mirror of
https://github.com/qemu/qemu.git
synced 2025-08-14 03:15:54 +00:00
tcg: Remove last traces of TCG_TARGET_NEED_POOL_LABELS
tcg: Cleanups after disallowing 64-on-32 tcg: Introduce constraint for zero register tcg: Remove TCG_TARGET_HAS_{br,set}cond2 from riscv and loongarch64 tcg/i386: Use tcg_{high,unsigned}_cond in tcg_out_brcond2 linux-user: Move TARGET_SA_RESTORER out of generic/signal.h linux-user: Fix alignment when unmapping excess reservation target/sparc: Fix register selection for all F*TOx and FxTO* instructions target/sparc: Fix gdbstub incorrectly handling registers f32-f62 target/sparc: fake UltraSPARC T1 PCR and PIC registers -----BEGIN PGP SIGNATURE----- iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAme0tZ8dHHJpY2hhcmQu aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+u+AgAi47VyMpkM8HvlvrV 6NGYD5FANLAF+Axl42GCTZEsisLN8b+KNWnM3QIxtE/ryxVY+OBpn/JpMRN96MJH jcbsbnadJxJEUktCi1Ny/9vZGKh/wfT45OdJ7Ej+J5J/5EIuDsJQEPlR5U4QVv7H I574hNttTibj12lYs0lbo0hESIISL+ALNw+smBNYEQ5zZTAPl3utP96NiQ/w3lyK qtybkljYXQRjOtUM7iNH2x6mwrBrPfbTDFubD0lLJGBTRQg2Q2Z5QVSsP4OY5gMp L9NPEQPs35GXA8c0GcAWwhO6kAcEbvkcUEL+jhfalb5BWhVWBgmTqCqYXr5RvuG2 flSRwg== =BWCN -----END PGP SIGNATURE----- Merge tag 'pull-tcg-20250215-3' of https://gitlab.com/rth7680/qemu into staging tcg: Remove last traces of TCG_TARGET_NEED_POOL_LABELS tcg: Cleanups after disallowing 64-on-32 tcg: Introduce constraint for zero register tcg: Remove TCG_TARGET_HAS_{br,set}cond2 from riscv and loongarch64 tcg/i386: Use tcg_{high,unsigned}_cond in tcg_out_brcond2 linux-user: Move TARGET_SA_RESTORER out of generic/signal.h linux-user: Fix alignment when unmapping excess reservation target/sparc: Fix register selection for all F*TOx and FxTO* instructions target/sparc: Fix gdbstub incorrectly handling registers f32-f62 target/sparc: fake UltraSPARC T1 PCR and PIC registers # -----BEGIN PGP SIGNATURE----- # # iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAme0tZ8dHHJpY2hhcmQu # aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+u+AgAi47VyMpkM8HvlvrV # 6NGYD5FANLAF+Axl42GCTZEsisLN8b+KNWnM3QIxtE/ryxVY+OBpn/JpMRN96MJH # jcbsbnadJxJEUktCi1Ny/9vZGKh/wfT45OdJ7Ej+J5J/5EIuDsJQEPlR5U4QVv7H # I574hNttTibj12lYs0lbo0hESIISL+ALNw+smBNYEQ5zZTAPl3utP96NiQ/w3lyK # qtybkljYXQRjOtUM7iNH2x6mwrBrPfbTDFubD0lLJGBTRQg2Q2Z5QVSsP4OY5gMp # L9NPEQPs35GXA8c0GcAWwhO6kAcEbvkcUEL+jhfalb5BWhVWBgmTqCqYXr5RvuG2 # flSRwg== # =BWCN # -----END PGP SIGNATURE----- # gpg: Signature made Wed 19 Feb 2025 00:30:23 HKT # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full] # Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A 05C0 64DF 38E8 AF7E 215F * tag 'pull-tcg-20250215-3' of https://gitlab.com/rth7680/qemu: (28 commits) tcg: Remove TCG_TARGET_HAS_{br,set}cond2 from riscv and loongarch64 tcg/i386: Use tcg_{high,unsigned}_cond in tcg_out_brcond2 target/sparc: fake UltraSPARC T1 PCR and PIC registers target/sparc: Fix gdbstub incorrectly handling registers f32-f62 target/sparc: Fix register selection for all F*TOx and FxTO* instructions linux-user: Move TARGET_SA_RESTORER out of generic/signal.h elfload: Fix alignment when unmapping excess reservation tcg/sparc64: Use 'z' constraint tcg/riscv: Use 'z' constraint tcg/mips: Use 'z' constraint tcg/loongarch64: Use 'z' constraint tcg/aarch64: Use 'z' constraint tcg: Introduce the 'z' constraint for a hardware zero register include/exec: Use uintptr_t in CPUTLBEntry include/exec: Change vaddr to uintptr_t target/mips: Use VADDR_PRIx for logging pc_next target/loongarch: Use VADDR_PRIx for logging pc_next accel/tcg: Fix tlb_set_page_with_attrs, tlb_set_page plugins: Fix qemu_plugin_read_memory_vaddr parameters tcg: Replace addr{lo,hi}_reg with addr_reg in TCGLabelQemuLdst ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
40efe733e1
@ -47,7 +47,6 @@
|
|||||||
#include "qemu/plugin-memory.h"
|
#include "qemu/plugin-memory.h"
|
||||||
#endif
|
#endif
|
||||||
#include "tcg/tcg-ldst.h"
|
#include "tcg/tcg-ldst.h"
|
||||||
#include "tcg/oversized-guest.h"
|
|
||||||
|
|
||||||
/* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */
|
/* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */
|
||||||
/* #define DEBUG_TLB */
|
/* #define DEBUG_TLB */
|
||||||
@ -105,26 +104,15 @@ static inline uint64_t tlb_read_idx(const CPUTLBEntry *entry,
|
|||||||
{
|
{
|
||||||
/* Do not rearrange the CPUTLBEntry structure members. */
|
/* Do not rearrange the CPUTLBEntry structure members. */
|
||||||
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_read) !=
|
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_read) !=
|
||||||
MMU_DATA_LOAD * sizeof(uint64_t));
|
MMU_DATA_LOAD * sizeof(uintptr_t));
|
||||||
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_write) !=
|
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_write) !=
|
||||||
MMU_DATA_STORE * sizeof(uint64_t));
|
MMU_DATA_STORE * sizeof(uintptr_t));
|
||||||
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_code) !=
|
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_code) !=
|
||||||
MMU_INST_FETCH * sizeof(uint64_t));
|
MMU_INST_FETCH * sizeof(uintptr_t));
|
||||||
|
|
||||||
#if TARGET_LONG_BITS == 32
|
const uintptr_t *ptr = &entry->addr_idx[access_type];
|
||||||
/* Use qatomic_read, in case of addr_write; only care about low bits. */
|
|
||||||
const uint32_t *ptr = (uint32_t *)&entry->addr_idx[access_type];
|
|
||||||
ptr += HOST_BIG_ENDIAN;
|
|
||||||
return qatomic_read(ptr);
|
|
||||||
#else
|
|
||||||
const uint64_t *ptr = &entry->addr_idx[access_type];
|
|
||||||
# if TCG_OVERSIZED_GUEST
|
|
||||||
return *ptr;
|
|
||||||
# else
|
|
||||||
/* ofs might correspond to .addr_write, so use qatomic_read */
|
/* ofs might correspond to .addr_write, so use qatomic_read */
|
||||||
return qatomic_read(ptr);
|
return qatomic_read(ptr);
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t tlb_addr_write(const CPUTLBEntry *entry)
|
static inline uint64_t tlb_addr_write(const CPUTLBEntry *entry)
|
||||||
@ -904,16 +892,8 @@ static void tlb_reset_dirty_range_locked(CPUTLBEntry *tlb_entry,
|
|||||||
addr &= TARGET_PAGE_MASK;
|
addr &= TARGET_PAGE_MASK;
|
||||||
addr += tlb_entry->addend;
|
addr += tlb_entry->addend;
|
||||||
if ((addr - start) < length) {
|
if ((addr - start) < length) {
|
||||||
#if TARGET_LONG_BITS == 32
|
|
||||||
uint32_t *ptr_write = (uint32_t *)&tlb_entry->addr_write;
|
|
||||||
ptr_write += HOST_BIG_ENDIAN;
|
|
||||||
qatomic_set(ptr_write, *ptr_write | TLB_NOTDIRTY);
|
|
||||||
#elif TCG_OVERSIZED_GUEST
|
|
||||||
tlb_entry->addr_write |= TLB_NOTDIRTY;
|
|
||||||
#else
|
|
||||||
qatomic_set(&tlb_entry->addr_write,
|
qatomic_set(&tlb_entry->addr_write,
|
||||||
tlb_entry->addr_write | TLB_NOTDIRTY);
|
tlb_entry->addr_write | TLB_NOTDIRTY);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1200,7 +1180,7 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx,
|
|||||||
|
|
||||||
void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr,
|
void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr,
|
||||||
hwaddr paddr, MemTxAttrs attrs, int prot,
|
hwaddr paddr, MemTxAttrs attrs, int prot,
|
||||||
int mmu_idx, uint64_t size)
|
int mmu_idx, vaddr size)
|
||||||
{
|
{
|
||||||
CPUTLBEntryFull full = {
|
CPUTLBEntryFull full = {
|
||||||
.phys_addr = paddr,
|
.phys_addr = paddr,
|
||||||
@ -1215,7 +1195,7 @@ void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr,
|
|||||||
|
|
||||||
void tlb_set_page(CPUState *cpu, vaddr addr,
|
void tlb_set_page(CPUState *cpu, vaddr addr,
|
||||||
hwaddr paddr, int prot,
|
hwaddr paddr, int prot,
|
||||||
int mmu_idx, uint64_t size)
|
int mmu_idx, vaddr size)
|
||||||
{
|
{
|
||||||
tlb_set_page_with_attrs(cpu, addr, paddr, MEMTXATTRS_UNSPECIFIED,
|
tlb_set_page_with_attrs(cpu, addr, paddr, MEMTXATTRS_UNSPECIFIED,
|
||||||
prot, mmu_idx, size);
|
prot, mmu_idx, size);
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include "exec/replay-core.h"
|
#include "exec/replay-core.h"
|
||||||
#include "system/cpu-timers.h"
|
#include "system/cpu-timers.h"
|
||||||
#include "tcg/startup.h"
|
#include "tcg/startup.h"
|
||||||
#include "tcg/oversized-guest.h"
|
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/accel.h"
|
#include "qemu/accel.h"
|
||||||
@ -41,6 +40,8 @@
|
|||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
#endif
|
#endif
|
||||||
#include "internal-common.h"
|
#include "internal-common.h"
|
||||||
|
#include "cpu-param.h"
|
||||||
|
|
||||||
|
|
||||||
struct TCGState {
|
struct TCGState {
|
||||||
AccelState parent_obj;
|
AccelState parent_obj;
|
||||||
@ -72,7 +73,7 @@ DECLARE_INSTANCE_CHECKER(TCGState, TCG_STATE,
|
|||||||
|
|
||||||
static bool default_mttcg_enabled(void)
|
static bool default_mttcg_enabled(void)
|
||||||
{
|
{
|
||||||
if (icount_enabled() || TCG_OVERSIZED_GUEST) {
|
if (icount_enabled()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#ifdef TARGET_SUPPORTS_MTTCG
|
#ifdef TARGET_SUPPORTS_MTTCG
|
||||||
@ -145,9 +146,7 @@ static void tcg_set_thread(Object *obj, const char *value, Error **errp)
|
|||||||
TCGState *s = TCG_STATE(obj);
|
TCGState *s = TCG_STATE(obj);
|
||||||
|
|
||||||
if (strcmp(value, "multi") == 0) {
|
if (strcmp(value, "multi") == 0) {
|
||||||
if (TCG_OVERSIZED_GUEST) {
|
if (icount_enabled()) {
|
||||||
error_setg(errp, "No MTTCG when guest word size > hosts");
|
|
||||||
} else if (icount_enabled()) {
|
|
||||||
error_setg(errp, "No MTTCG when icount is enabled");
|
error_setg(errp, "No MTTCG when icount is enabled");
|
||||||
} else {
|
} else {
|
||||||
#ifndef TARGET_SUPPORTS_MTTCG
|
#ifndef TARGET_SUPPORTS_MTTCG
|
||||||
|
@ -37,7 +37,6 @@ if:
|
|||||||
|
|
||||||
* forced by --accel tcg,thread=single
|
* forced by --accel tcg,thread=single
|
||||||
* enabling --icount mode
|
* enabling --icount mode
|
||||||
* 64 bit guests on 32 bit hosts (TCG_OVERSIZED_GUEST)
|
|
||||||
|
|
||||||
In the general case of running translated code there should be no
|
In the general case of running translated code there should be no
|
||||||
inter-vCPU dependencies and all vCPUs should be able to run at full
|
inter-vCPU dependencies and all vCPUs should be able to run at full
|
||||||
|
@ -927,7 +927,9 @@ operation uses a constant input constraint which does not allow all
|
|||||||
constants, it must also accept registers in order to have a fallback.
|
constants, it must also accept registers in order to have a fallback.
|
||||||
The constraint '``i``' is defined generically to accept any constant.
|
The constraint '``i``' is defined generically to accept any constant.
|
||||||
The constraint '``r``' is not defined generically, but is consistently
|
The constraint '``r``' is not defined generically, but is consistently
|
||||||
used by each backend to indicate all registers.
|
used by each backend to indicate all registers. If ``TCG_REG_ZERO``
|
||||||
|
is defined by the backend, the constraint '``z``' is defined generically
|
||||||
|
to map constant 0 to the hardware zero register.
|
||||||
|
|
||||||
The movi_i32 and movi_i64 operations must accept any constants.
|
The movi_i32 and movi_i64 operations must accept any constants.
|
||||||
|
|
||||||
|
@ -19,14 +19,14 @@
|
|||||||
#ifndef EXEC_TLB_COMMON_H
|
#ifndef EXEC_TLB_COMMON_H
|
||||||
#define EXEC_TLB_COMMON_H 1
|
#define EXEC_TLB_COMMON_H 1
|
||||||
|
|
||||||
#define CPU_TLB_ENTRY_BITS 5
|
#define CPU_TLB_ENTRY_BITS (HOST_LONG_BITS == 32 ? 4 : 5)
|
||||||
|
|
||||||
/* Minimalized TLB entry for use by TCG fast path. */
|
/* Minimalized TLB entry for use by TCG fast path. */
|
||||||
typedef union CPUTLBEntry {
|
typedef union CPUTLBEntry {
|
||||||
struct {
|
struct {
|
||||||
uint64_t addr_read;
|
uintptr_t addr_read;
|
||||||
uint64_t addr_write;
|
uintptr_t addr_write;
|
||||||
uint64_t addr_code;
|
uintptr_t addr_code;
|
||||||
/*
|
/*
|
||||||
* Addend to virtual address to get host address. IO accesses
|
* Addend to virtual address to get host address. IO accesses
|
||||||
* use the corresponding iotlb value.
|
* use the corresponding iotlb value.
|
||||||
@ -37,7 +37,7 @@ typedef union CPUTLBEntry {
|
|||||||
* Padding to get a power of two size, as well as index
|
* Padding to get a power of two size, as well as index
|
||||||
* access to addr_{read,write,code}.
|
* access to addr_{read,write,code}.
|
||||||
*/
|
*/
|
||||||
uint64_t addr_idx[(1 << CPU_TLB_ENTRY_BITS) / sizeof(uint64_t)];
|
uintptr_t addr_idx[(1 << CPU_TLB_ENTRY_BITS) / sizeof(uintptr_t)];
|
||||||
} CPUTLBEntry;
|
} CPUTLBEntry;
|
||||||
|
|
||||||
QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
|
QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
|
||||||
|
@ -6,13 +6,15 @@
|
|||||||
/**
|
/**
|
||||||
* vaddr:
|
* vaddr:
|
||||||
* Type wide enough to contain any #target_ulong virtual address.
|
* Type wide enough to contain any #target_ulong virtual address.
|
||||||
|
* We do not support 64-bit guest on 32-host and detect at configure time.
|
||||||
|
* Therefore, a host pointer width will always fit a guest pointer.
|
||||||
*/
|
*/
|
||||||
typedef uint64_t vaddr;
|
typedef uintptr_t vaddr;
|
||||||
#define VADDR_PRId PRId64
|
#define VADDR_PRId PRIdPTR
|
||||||
#define VADDR_PRIu PRIu64
|
#define VADDR_PRIu PRIuPTR
|
||||||
#define VADDR_PRIo PRIo64
|
#define VADDR_PRIo PRIoPTR
|
||||||
#define VADDR_PRIx PRIx64
|
#define VADDR_PRIx PRIxPTR
|
||||||
#define VADDR_PRIX PRIX64
|
#define VADDR_PRIX PRIXPTR
|
||||||
#define VADDR_MAX UINT64_MAX
|
#define VADDR_MAX UINTPTR_MAX
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -56,25 +56,13 @@
|
|||||||
*/
|
*/
|
||||||
#define signal_barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST)
|
#define signal_barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST)
|
||||||
|
|
||||||
/* Sanity check that the size of an atomic operation isn't "overly large".
|
/*
|
||||||
|
* Sanity check that the size of an atomic operation isn't "overly large".
|
||||||
* Despite the fact that e.g. i686 has 64-bit atomic operations, we do not
|
* Despite the fact that e.g. i686 has 64-bit atomic operations, we do not
|
||||||
* want to use them because we ought not need them, and this lets us do a
|
* want to use them because we ought not need them, and this lets us do a
|
||||||
* bit of sanity checking that other 32-bit hosts might build.
|
* bit of sanity checking that other 32-bit hosts might build.
|
||||||
*
|
|
||||||
* That said, we have a problem on 64-bit ILP32 hosts in that in order to
|
|
||||||
* sync with TCG_OVERSIZED_GUEST, this must match TCG_TARGET_REG_BITS.
|
|
||||||
* We'd prefer not want to pull in everything else TCG related, so handle
|
|
||||||
* those few cases by hand.
|
|
||||||
*
|
|
||||||
* Note that x32 is fully detected with __x86_64__ + _ILP32, and that for
|
|
||||||
* Sparc we always force the use of sparcv9 in configure. MIPS n32 (ILP32) &
|
|
||||||
* n64 (LP64) ABIs are both detected using __mips64.
|
|
||||||
*/
|
*/
|
||||||
#if defined(__x86_64__) || defined(__sparc__) || defined(__mips64)
|
#define ATOMIC_REG_SIZE sizeof(void *)
|
||||||
# define ATOMIC_REG_SIZE 8
|
|
||||||
#else
|
|
||||||
# define ATOMIC_REG_SIZE sizeof(void *)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Weak atomic operations prevent the compiler moving other
|
/* Weak atomic operations prevent the compiler moving other
|
||||||
* loads/stores past the atomic operation load/store. However there is
|
* loads/stores past the atomic operation load/store. However there is
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: MIT */
|
|
||||||
/*
|
|
||||||
* Define TCG_OVERSIZED_GUEST
|
|
||||||
* Copyright (c) 2008 Fabrice Bellard
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EXEC_TCG_OVERSIZED_GUEST_H
|
|
||||||
#define EXEC_TCG_OVERSIZED_GUEST_H
|
|
||||||
|
|
||||||
#include "tcg-target-reg-bits.h"
|
|
||||||
#include "cpu-param.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Oversized TCG guests make things like MTTCG hard
|
|
||||||
* as we can't use atomics for cputlb updates.
|
|
||||||
*/
|
|
||||||
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
|
|
||||||
#define TCG_OVERSIZED_GUEST 1
|
|
||||||
#else
|
|
||||||
#define TCG_OVERSIZED_GUEST 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -188,36 +188,22 @@ DEF(goto_ptr, 0, 1, 0, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
|
|||||||
DEF(plugin_cb, 0, 0, 1, TCG_OPF_NOT_PRESENT)
|
DEF(plugin_cb, 0, 0, 1, TCG_OPF_NOT_PRESENT)
|
||||||
DEF(plugin_mem_cb, 0, 1, 1, TCG_OPF_NOT_PRESENT)
|
DEF(plugin_mem_cb, 0, 1, 1, TCG_OPF_NOT_PRESENT)
|
||||||
|
|
||||||
/* Replicate ld/st ops for 32 and 64-bit guest addresses. */
|
DEF(qemu_ld_i32, 1, 1, 1,
|
||||||
DEF(qemu_ld_a32_i32, 1, 1, 1,
|
|
||||||
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||||
DEF(qemu_st_a32_i32, 0, 1 + 1, 1,
|
DEF(qemu_st_i32, 0, 1 + 1, 1,
|
||||||
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||||
DEF(qemu_ld_a32_i64, DATA64_ARGS, 1, 1,
|
DEF(qemu_ld_i64, DATA64_ARGS, 1, 1,
|
||||||
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||||
DEF(qemu_st_a32_i64, 0, DATA64_ARGS + 1, 1,
|
DEF(qemu_st_i64, 0, DATA64_ARGS + 1, 1,
|
||||||
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
|
||||||
|
|
||||||
DEF(qemu_ld_a64_i32, 1, DATA64_ARGS, 1,
|
|
||||||
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
|
||||||
DEF(qemu_st_a64_i32, 0, 1 + DATA64_ARGS, 1,
|
|
||||||
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
|
||||||
DEF(qemu_ld_a64_i64, DATA64_ARGS, DATA64_ARGS, 1,
|
|
||||||
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
|
||||||
DEF(qemu_st_a64_i64, 0, DATA64_ARGS + DATA64_ARGS, 1,
|
|
||||||
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||||
|
|
||||||
/* Only used by i386 to cope with stupid register constraints. */
|
/* Only used by i386 to cope with stupid register constraints. */
|
||||||
DEF(qemu_st8_a32_i32, 0, 1 + 1, 1,
|
DEF(qemu_st8_i32, 0, 1 + 1, 1,
|
||||||
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
|
||||||
DEF(qemu_st8_a64_i32, 0, 1 + DATA64_ARGS, 1,
|
|
||||||
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||||
|
|
||||||
/* Only for 64-bit hosts at the moment. */
|
/* Only for 64-bit hosts at the moment. */
|
||||||
DEF(qemu_ld_a32_i128, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
DEF(qemu_ld_i128, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||||
DEF(qemu_ld_a64_i128, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
DEF(qemu_st_i128, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||||
DEF(qemu_st_a32_i128, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
|
||||||
DEF(qemu_st_a64_i128, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
|
||||||
|
|
||||||
/* Host vector support. */
|
/* Host vector support. */
|
||||||
|
|
||||||
|
@ -713,7 +713,8 @@ void tb_target_set_jmp_target(const TranslationBlock *, int,
|
|||||||
|
|
||||||
void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
|
void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
|
||||||
|
|
||||||
#define TCG_CT_CONST 1 /* any constant of register size */
|
#define TCG_CT_CONST 1 /* any constant of register size */
|
||||||
|
#define TCG_CT_REG_ZERO 2 /* zero, in TCG_REG_ZERO */
|
||||||
|
|
||||||
typedef struct TCGArgConstraint {
|
typedef struct TCGArgConstraint {
|
||||||
unsigned ct : 16;
|
unsigned ct : 16;
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "../generic/signal.h"
|
#include "../generic/signal.h"
|
||||||
|
|
||||||
|
#define TARGET_SA_RESTORER 0x04000000
|
||||||
|
|
||||||
#define TARGET_SEGV_MTEAERR 8 /* Asynchronous ARM MTE error */
|
#define TARGET_SEGV_MTEAERR 8 /* Asynchronous ARM MTE error */
|
||||||
#define TARGET_SEGV_MTESERR 9 /* Synchronous ARM MTE exception */
|
#define TARGET_SEGV_MTESERR 9 /* Synchronous ARM MTE exception */
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "../generic/signal.h"
|
#include "../generic/signal.h"
|
||||||
|
|
||||||
|
#define TARGET_SA_RESTORER 0x04000000
|
||||||
|
|
||||||
#define TARGET_ARCH_HAS_SETUP_FRAME
|
#define TARGET_ARCH_HAS_SETUP_FRAME
|
||||||
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
||||||
|
|
||||||
|
@ -3351,8 +3351,8 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
|||||||
|
|
||||||
if (align_size != reserve_size) {
|
if (align_size != reserve_size) {
|
||||||
abi_ulong align_addr = ROUND_UP(load_addr, align);
|
abi_ulong align_addr = ROUND_UP(load_addr, align);
|
||||||
abi_ulong align_end = align_addr + reserve_size;
|
abi_ulong align_end = TARGET_PAGE_ALIGN(align_addr + reserve_size);
|
||||||
abi_ulong load_end = load_addr + align_size;
|
abi_ulong load_end = TARGET_PAGE_ALIGN(load_addr + align_size);
|
||||||
|
|
||||||
if (align_addr != load_addr) {
|
if (align_addr != load_addr) {
|
||||||
target_munmap(load_addr, align_addr - load_addr);
|
target_munmap(load_addr, align_addr - load_addr);
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#define TARGET_SA_RESTART 0x10000000
|
#define TARGET_SA_RESTART 0x10000000
|
||||||
#define TARGET_SA_NODEFER 0x40000000
|
#define TARGET_SA_NODEFER 0x40000000
|
||||||
#define TARGET_SA_RESETHAND 0x80000000
|
#define TARGET_SA_RESETHAND 0x80000000
|
||||||
#define TARGET_SA_RESTORER 0x04000000
|
|
||||||
|
|
||||||
#define TARGET_SIGHUP 1
|
#define TARGET_SIGHUP 1
|
||||||
#define TARGET_SIGINT 2
|
#define TARGET_SIGINT 2
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "../generic/signal.h"
|
#include "../generic/signal.h"
|
||||||
|
|
||||||
|
#define TARGET_SA_RESTORER 0x04000000
|
||||||
|
|
||||||
#define TARGET_ARCH_HAS_SETUP_FRAME
|
#define TARGET_ARCH_HAS_SETUP_FRAME
|
||||||
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "../generic/signal.h"
|
#include "../generic/signal.h"
|
||||||
|
|
||||||
|
#define TARGET_ARCH_HAS_SA_RESTORER 1
|
||||||
#define TARGET_ARCH_HAS_SETUP_FRAME
|
#define TARGET_ARCH_HAS_SETUP_FRAME
|
||||||
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "../generic/signal.h"
|
#include "../generic/signal.h"
|
||||||
|
|
||||||
|
#define TARGET_SA_RESTORER 0x04000000
|
||||||
|
|
||||||
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
||||||
|
|
||||||
#endif /* MICROBLAZE_TARGET_SIGNAL_H */
|
#endif /* MICROBLAZE_TARGET_SIGNAL_H */
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "../generic/signal.h"
|
#include "../generic/signal.h"
|
||||||
|
|
||||||
|
#define TARGET_SA_RESTORER 0x04000000
|
||||||
|
|
||||||
#if !defined(TARGET_PPC64)
|
#if !defined(TARGET_PPC64)
|
||||||
#define TARGET_ARCH_HAS_SETUP_FRAME
|
#define TARGET_ARCH_HAS_SETUP_FRAME
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "../generic/signal.h"
|
#include "../generic/signal.h"
|
||||||
|
|
||||||
|
#define TARGET_SA_RESTORER 0x04000000
|
||||||
|
|
||||||
#define TARGET_ARCH_HAS_SETUP_FRAME
|
#define TARGET_ARCH_HAS_SETUP_FRAME
|
||||||
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "../generic/signal.h"
|
#include "../generic/signal.h"
|
||||||
|
|
||||||
|
#define TARGET_SA_RESTORER 0x04000000
|
||||||
|
|
||||||
#define TARGET_ARCH_HAS_SETUP_FRAME
|
#define TARGET_ARCH_HAS_SETUP_FRAME
|
||||||
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "../generic/signal.h"
|
#include "../generic/signal.h"
|
||||||
|
|
||||||
|
#define TARGET_SA_RESTORER 0x04000000
|
||||||
|
|
||||||
/* For x86_64, use of SA_RESTORER is mandatory. */
|
/* For x86_64, use of SA_RESTORER is mandatory. */
|
||||||
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
|
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "../generic/signal.h"
|
#include "../generic/signal.h"
|
||||||
|
|
||||||
|
#define TARGET_SA_RESTORER 0x04000000
|
||||||
|
|
||||||
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -561,7 +561,7 @@ GArray *qemu_plugin_get_registers(void)
|
|||||||
return create_register_handles(regs);
|
return create_register_handles(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool qemu_plugin_read_memory_vaddr(vaddr addr, GByteArray *data, size_t len)
|
bool qemu_plugin_read_memory_vaddr(uint64_t addr, GByteArray *data, size_t len)
|
||||||
{
|
{
|
||||||
g_assert(current_cpu);
|
g_assert(current_cpu);
|
||||||
|
|
||||||
|
@ -16,9 +16,6 @@
|
|||||||
#include "internals.h"
|
#include "internals.h"
|
||||||
#include "cpu-features.h"
|
#include "cpu-features.h"
|
||||||
#include "idau.h"
|
#include "idau.h"
|
||||||
#ifdef CONFIG_TCG
|
|
||||||
# include "tcg/oversized-guest.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct S1Translate {
|
typedef struct S1Translate {
|
||||||
/*
|
/*
|
||||||
@ -840,7 +837,6 @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
|
|||||||
ptw->out_rw = true;
|
ptw->out_rw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ATOMIC64
|
|
||||||
if (ptw->out_be) {
|
if (ptw->out_be) {
|
||||||
old_val = cpu_to_be64(old_val);
|
old_val = cpu_to_be64(old_val);
|
||||||
new_val = cpu_to_be64(new_val);
|
new_val = cpu_to_be64(new_val);
|
||||||
@ -852,36 +848,6 @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
|
|||||||
cur_val = qatomic_cmpxchg__nocheck((uint64_t *)host, old_val, new_val);
|
cur_val = qatomic_cmpxchg__nocheck((uint64_t *)host, old_val, new_val);
|
||||||
cur_val = le64_to_cpu(cur_val);
|
cur_val = le64_to_cpu(cur_val);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* We can't support the full 64-bit atomic cmpxchg on the host.
|
|
||||||
* Because this is only used for FEAT_HAFDBS, which is only for AA64,
|
|
||||||
* we know that TCG_OVERSIZED_GUEST is set, which means that we are
|
|
||||||
* running in round-robin mode and could only race with dma i/o.
|
|
||||||
*/
|
|
||||||
#if !TCG_OVERSIZED_GUEST
|
|
||||||
# error "Unexpected configuration"
|
|
||||||
#endif
|
|
||||||
bool locked = bql_locked();
|
|
||||||
if (!locked) {
|
|
||||||
bql_lock();
|
|
||||||
}
|
|
||||||
if (ptw->out_be) {
|
|
||||||
cur_val = ldq_be_p(host);
|
|
||||||
if (cur_val == old_val) {
|
|
||||||
stq_be_p(host, new_val);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cur_val = ldq_le_p(host);
|
|
||||||
if (cur_val == old_val) {
|
|
||||||
stq_le_p(host, new_val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!locked) {
|
|
||||||
bql_unlock();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return cur_val;
|
return cur_val;
|
||||||
#else
|
#else
|
||||||
/* AArch32 does not have FEAT_HADFS; non-TCG guests only use debug-mode. */
|
/* AArch32 does not have FEAT_HADFS; non-TCG guests only use debug-mode. */
|
||||||
|
@ -56,7 +56,7 @@ static bool gen_am(DisasContext *ctx, arg_rrr *a,
|
|||||||
if (a->rd != 0 && (a->rj == a->rd || a->rk == a->rd)) {
|
if (a->rd != 0 && (a->rj == a->rd || a->rk == a->rd)) {
|
||||||
qemu_log_mask(LOG_GUEST_ERROR,
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
"Warning: source register overlaps destination register"
|
"Warning: source register overlaps destination register"
|
||||||
"in atomic insn at pc=0x" TARGET_FMT_lx "\n",
|
"in atomic insn at pc=0x%" VADDR_PRIx "\n",
|
||||||
ctx->base.pc_next - 4);
|
ctx->base.pc_next - 4);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -289,7 +289,7 @@ static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
|
|||||||
|
|
||||||
if (!decode(ctx, ctx->opcode)) {
|
if (!decode(ctx, ctx->opcode)) {
|
||||||
qemu_log_mask(LOG_UNIMP, "Error: unknown opcode. "
|
qemu_log_mask(LOG_UNIMP, "Error: unknown opcode. "
|
||||||
TARGET_FMT_lx ": 0x%x\n",
|
"0x%" VADDR_PRIx ": 0x%x\n",
|
||||||
ctx->base.pc_next, ctx->opcode);
|
ctx->base.pc_next, ctx->opcode);
|
||||||
generate_exception(ctx, EXCCODE_INE);
|
generate_exception(ctx, EXCCODE_INE);
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@ static bool trans_BBIT(DisasContext *ctx, arg_BBIT *a)
|
|||||||
TCGv p;
|
TCGv p;
|
||||||
|
|
||||||
if (ctx->hflags & MIPS_HFLAG_BMASK) {
|
if (ctx->hflags & MIPS_HFLAG_BMASK) {
|
||||||
LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
|
LOG_DISAS("Branch in delay / forbidden slot at PC 0x%" VADDR_PRIx "\n",
|
||||||
TARGET_FMT_lx "\n", ctx->base.pc_next);
|
ctx->base.pc_next);
|
||||||
generate_exception_end(ctx, EXCP_RI);
|
generate_exception_end(ctx, EXCP_RI);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
#include "system/cpu-timers.h"
|
#include "system/cpu-timers.h"
|
||||||
#include "cpu_bits.h"
|
#include "cpu_bits.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "tcg/oversized-guest.h"
|
|
||||||
#include "pmp.h"
|
#include "pmp.h"
|
||||||
|
|
||||||
int riscv_env_mmu_index(CPURISCVState *env, bool ifetch)
|
int riscv_env_mmu_index(CPURISCVState *env, bool ifetch)
|
||||||
@ -1167,9 +1166,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
|
|||||||
hwaddr pte_addr;
|
hwaddr pte_addr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#if !TCG_OVERSIZED_GUEST
|
restart:
|
||||||
restart:
|
|
||||||
#endif
|
|
||||||
for (i = 0; i < levels; i++, ptshift -= ptidxbits) {
|
for (i = 0; i < levels; i++, ptshift -= ptidxbits) {
|
||||||
target_ulong idx;
|
target_ulong idx;
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
@ -1388,13 +1385,6 @@ restart:
|
|||||||
false, MEMTXATTRS_UNSPECIFIED);
|
false, MEMTXATTRS_UNSPECIFIED);
|
||||||
if (memory_region_is_ram(mr)) {
|
if (memory_region_is_ram(mr)) {
|
||||||
target_ulong *pte_pa = qemu_map_ram_ptr(mr->ram_block, addr1);
|
target_ulong *pte_pa = qemu_map_ram_ptr(mr->ram_block, addr1);
|
||||||
#if TCG_OVERSIZED_GUEST
|
|
||||||
/*
|
|
||||||
* MTTCG is not enabled on oversized TCG guests so
|
|
||||||
* page table updates do not need to be atomic
|
|
||||||
*/
|
|
||||||
*pte_pa = pte = updated_pte;
|
|
||||||
#else
|
|
||||||
target_ulong old_pte;
|
target_ulong old_pte;
|
||||||
if (riscv_cpu_sxl(env) == MXL_RV32) {
|
if (riscv_cpu_sxl(env) == MXL_RV32) {
|
||||||
old_pte = qatomic_cmpxchg((uint32_t *)pte_pa, pte, updated_pte);
|
old_pte = qatomic_cmpxchg((uint32_t *)pte_pa, pte, updated_pte);
|
||||||
@ -1405,7 +1395,6 @@ restart:
|
|||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
pte = updated_pte;
|
pte = updated_pte;
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Misconfigured PTE in ROM (AD bits are not preset) or
|
* Misconfigured PTE in ROM (AD bits are not preset) or
|
||||||
|
@ -79,8 +79,13 @@ int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (n < 80) {
|
if (n < 80) {
|
||||||
/* f32-f62 (double width, even numbers only) */
|
/* f32-f62 (16 double width registers, even register numbers only)
|
||||||
return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll);
|
* n == 64: f32 : env->fpr[16]
|
||||||
|
* n == 65: f34 : env->fpr[17]
|
||||||
|
* etc...
|
||||||
|
* n == 79: f62 : env->fpr[31]
|
||||||
|
*/
|
||||||
|
return gdb_get_reg64(mem_buf, env->fpr[(n - 64) + 16].ll);
|
||||||
}
|
}
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 80:
|
case 80:
|
||||||
@ -173,8 +178,13 @@ int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
|||||||
}
|
}
|
||||||
return 4;
|
return 4;
|
||||||
} else if (n < 80) {
|
} else if (n < 80) {
|
||||||
/* f32-f62 (double width, even numbers only) */
|
/* f32-f62 (16 double width registers, even register numbers only)
|
||||||
env->fpr[(n - 32) / 2].ll = tmp;
|
* n == 64: f32 : env->fpr[16]
|
||||||
|
* n == 65: f34 : env->fpr[17]
|
||||||
|
* etc...
|
||||||
|
* n == 79: f62 : env->fpr[31]
|
||||||
|
*/
|
||||||
|
env->fpr[(n - 64) + 16].ll = tmp;
|
||||||
} else {
|
} else {
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 80:
|
case 80:
|
||||||
|
@ -96,7 +96,10 @@ CALL 01 i:s30
|
|||||||
RDTICK 10 rd:5 101000 00100 0 0000000000000
|
RDTICK 10 rd:5 101000 00100 0 0000000000000
|
||||||
RDPC 10 rd:5 101000 00101 0 0000000000000
|
RDPC 10 rd:5 101000 00101 0 0000000000000
|
||||||
RDFPRS 10 rd:5 101000 00110 0 0000000000000
|
RDFPRS 10 rd:5 101000 00110 0 0000000000000
|
||||||
RDASR17 10 rd:5 101000 10001 0 0000000000000
|
{
|
||||||
|
RDASR17 10 rd:5 101000 10001 0 0000000000000
|
||||||
|
RDPIC 10 rd:5 101000 10001 0 0000000000000
|
||||||
|
}
|
||||||
RDGSR 10 rd:5 101000 10011 0 0000000000000
|
RDGSR 10 rd:5 101000 10011 0 0000000000000
|
||||||
RDSOFTINT 10 rd:5 101000 10110 0 0000000000000
|
RDSOFTINT 10 rd:5 101000 10110 0 0000000000000
|
||||||
RDTICK_CMPR 10 rd:5 101000 10111 0 0000000000000
|
RDTICK_CMPR 10 rd:5 101000 10111 0 0000000000000
|
||||||
@ -114,6 +117,8 @@ CALL 01 i:s30
|
|||||||
WRCCR 10 00010 110000 ..... . ............. @n_r_ri
|
WRCCR 10 00010 110000 ..... . ............. @n_r_ri
|
||||||
WRASI 10 00011 110000 ..... . ............. @n_r_ri
|
WRASI 10 00011 110000 ..... . ............. @n_r_ri
|
||||||
WRFPRS 10 00110 110000 ..... . ............. @n_r_ri
|
WRFPRS 10 00110 110000 ..... . ............. @n_r_ri
|
||||||
|
WRPCR 10 10000 110000 01000 0 0000000000000
|
||||||
|
WRPIC 10 10001 110000 01000 0 0000000000000
|
||||||
{
|
{
|
||||||
WRGSR 10 10011 110000 ..... . ............. @n_r_ri
|
WRGSR 10 10011 110000 ..... . ............. @n_r_ri
|
||||||
WRPOWERDOWN 10 10011 110000 ..... . ............. @n_r_ri
|
WRPOWERDOWN 10 10011 110000 ..... . ............. @n_r_ri
|
||||||
@ -321,12 +326,12 @@ FdMULq 10 ..... 110100 ..... 0 0110 1110 ..... @q_d_d
|
|||||||
FNHADDs 10 ..... 110100 ..... 0 0111 0001 ..... @r_r_r
|
FNHADDs 10 ..... 110100 ..... 0 0111 0001 ..... @r_r_r
|
||||||
FNHADDd 10 ..... 110100 ..... 0 0111 0010 ..... @d_d_d
|
FNHADDd 10 ..... 110100 ..... 0 0111 0010 ..... @d_d_d
|
||||||
FNsMULd 10 ..... 110100 ..... 0 0111 1001 ..... @d_r_r
|
FNsMULd 10 ..... 110100 ..... 0 0111 1001 ..... @d_r_r
|
||||||
FsTOx 10 ..... 110100 00000 0 1000 0001 ..... @r_r2
|
FsTOx 10 ..... 110100 00000 0 1000 0001 ..... @d_r2
|
||||||
FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_d2
|
FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @d_d2
|
||||||
FqTOx 10 ..... 110100 00000 0 1000 0011 ..... @r_q2
|
FqTOx 10 ..... 110100 00000 0 1000 0011 ..... @d_q2
|
||||||
FxTOs 10 ..... 110100 00000 0 1000 0100 ..... @r_r2
|
FxTOs 10 ..... 110100 00000 0 1000 0100 ..... @r_d2
|
||||||
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @d_r2
|
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @d_d2
|
||||||
FxTOq 10 ..... 110100 00000 0 1000 1100 ..... @q_r2
|
FxTOq 10 ..... 110100 00000 0 1000 1100 ..... @q_d2
|
||||||
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
|
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
|
||||||
FdTOs 10 ..... 110100 00000 0 1100 0110 ..... @r_d2
|
FdTOs 10 ..... 110100 00000 0 1100 0110 ..... @r_d2
|
||||||
FqTOs 10 ..... 110100 00000 0 1100 0111 ..... @r_q2
|
FqTOs 10 ..... 110100 00000 0 1100 0111 ..... @r_q2
|
||||||
|
@ -2882,6 +2882,14 @@ static TCGv do_rd_leon3_config(DisasContext *dc, TCGv dst)
|
|||||||
|
|
||||||
TRANS(RDASR17, ASR17, do_rd_special, true, a->rd, do_rd_leon3_config)
|
TRANS(RDASR17, ASR17, do_rd_special, true, a->rd, do_rd_leon3_config)
|
||||||
|
|
||||||
|
static TCGv do_rdpic(DisasContext *dc, TCGv dst)
|
||||||
|
{
|
||||||
|
return tcg_constant_tl(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRANS(RDPIC, HYPV, do_rd_special, supervisor(dc), a->rd, do_rdpic)
|
||||||
|
|
||||||
|
|
||||||
static TCGv do_rdccr(DisasContext *dc, TCGv dst)
|
static TCGv do_rdccr(DisasContext *dc, TCGv dst)
|
||||||
{
|
{
|
||||||
gen_helper_rdccr(dst, tcg_env);
|
gen_helper_rdccr(dst, tcg_env);
|
||||||
@ -3315,6 +3323,17 @@ static void do_wrfprs(DisasContext *dc, TCGv src)
|
|||||||
|
|
||||||
TRANS(WRFPRS, 64, do_wr_special, a, true, do_wrfprs)
|
TRANS(WRFPRS, 64, do_wr_special, a, true, do_wrfprs)
|
||||||
|
|
||||||
|
static bool do_priv_nop(DisasContext *dc, bool priv)
|
||||||
|
{
|
||||||
|
if (!priv) {
|
||||||
|
return raise_priv(dc);
|
||||||
|
}
|
||||||
|
return advance_pc(dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRANS(WRPCR, HYPV, do_priv_nop, supervisor(dc))
|
||||||
|
TRANS(WRPIC, HYPV, do_priv_nop, supervisor(dc))
|
||||||
|
|
||||||
static void do_wrgsr(DisasContext *dc, TCGv src)
|
static void do_wrgsr(DisasContext *dc, TCGv src)
|
||||||
{
|
{
|
||||||
gen_trap_ifnofpu(dc);
|
gen_trap_ifnofpu(dc);
|
||||||
|
@ -11,27 +11,27 @@
|
|||||||
*/
|
*/
|
||||||
C_O0_I1(r)
|
C_O0_I1(r)
|
||||||
C_O0_I2(r, rC)
|
C_O0_I2(r, rC)
|
||||||
C_O0_I2(rZ, r)
|
C_O0_I2(rz, r)
|
||||||
C_O0_I2(w, r)
|
C_O0_I2(w, r)
|
||||||
C_O0_I3(rZ, rZ, r)
|
C_O0_I3(rz, rz, r)
|
||||||
C_O1_I1(r, r)
|
C_O1_I1(r, r)
|
||||||
C_O1_I1(w, r)
|
C_O1_I1(w, r)
|
||||||
C_O1_I1(w, w)
|
C_O1_I1(w, w)
|
||||||
C_O1_I1(w, wr)
|
C_O1_I1(w, wr)
|
||||||
C_O1_I2(r, 0, rZ)
|
C_O1_I2(r, 0, rz)
|
||||||
C_O1_I2(r, r, r)
|
C_O1_I2(r, r, r)
|
||||||
C_O1_I2(r, r, rA)
|
C_O1_I2(r, r, rA)
|
||||||
C_O1_I2(r, r, rAL)
|
C_O1_I2(r, r, rAL)
|
||||||
C_O1_I2(r, r, rC)
|
C_O1_I2(r, r, rC)
|
||||||
C_O1_I2(r, r, ri)
|
C_O1_I2(r, r, ri)
|
||||||
C_O1_I2(r, r, rL)
|
C_O1_I2(r, r, rL)
|
||||||
C_O1_I2(r, rZ, rZ)
|
C_O1_I2(r, rz, rz)
|
||||||
C_O1_I2(w, 0, w)
|
C_O1_I2(w, 0, w)
|
||||||
C_O1_I2(w, w, w)
|
C_O1_I2(w, w, w)
|
||||||
C_O1_I2(w, w, wN)
|
C_O1_I2(w, w, wN)
|
||||||
C_O1_I2(w, w, wO)
|
C_O1_I2(w, w, wO)
|
||||||
C_O1_I2(w, w, wZ)
|
C_O1_I2(w, w, wZ)
|
||||||
C_O1_I3(w, w, w, w)
|
C_O1_I3(w, w, w, w)
|
||||||
C_O1_I4(r, r, rC, rZ, rZ)
|
C_O1_I4(r, r, rC, rz, rz)
|
||||||
C_O2_I1(r, r, r)
|
C_O2_I1(r, r, r)
|
||||||
C_O2_I4(r, r, rZ, rZ, rA, rMZ)
|
C_O2_I4(r, r, rz, rz, rA, rMZ)
|
||||||
|
@ -1775,7 +1775,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addr_reg;
|
ldst->addr_reg = addr_reg;
|
||||||
|
|
||||||
mask_type = (s->page_bits + s->tlb_dyn_max_bits > 32
|
mask_type = (s->page_bits + s->tlb_dyn_max_bits > 32
|
||||||
? TCG_TYPE_I64 : TCG_TYPE_I32);
|
? TCG_TYPE_I64 : TCG_TYPE_I32);
|
||||||
@ -1837,7 +1837,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
|
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addr_reg;
|
ldst->addr_reg = addr_reg;
|
||||||
|
|
||||||
/* tst addr, #mask */
|
/* tst addr, #mask */
|
||||||
tcg_out_logicali(s, I3404_ANDSI, 0, TCG_REG_XZR, addr_reg, a_mask);
|
tcg_out_logicali(s, I3404_ANDSI, 0, TCG_REG_XZR, addr_reg, a_mask);
|
||||||
@ -2125,10 +2125,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
|
|||||||
TCGArg a2 = args[2];
|
TCGArg a2 = args[2];
|
||||||
int c2 = const_args[2];
|
int c2 = const_args[2];
|
||||||
|
|
||||||
/* Some operands are defined with "rZ" constraint, a register or
|
|
||||||
the zero register. These need not actually test args[I] == 0. */
|
|
||||||
#define REG0(I) (const_args[I] ? TCG_REG_XZR : (TCGReg)args[I])
|
|
||||||
|
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
case INDEX_op_goto_ptr:
|
case INDEX_op_goto_ptr:
|
||||||
tcg_out_insn(s, 3207, BR, a0);
|
tcg_out_insn(s, 3207, BR, a0);
|
||||||
@ -2171,18 +2167,18 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
|
|||||||
|
|
||||||
case INDEX_op_st8_i32:
|
case INDEX_op_st8_i32:
|
||||||
case INDEX_op_st8_i64:
|
case INDEX_op_st8_i64:
|
||||||
tcg_out_ldst(s, I3312_STRB, REG0(0), a1, a2, 0);
|
tcg_out_ldst(s, I3312_STRB, a0, a1, a2, 0);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_st16_i32:
|
case INDEX_op_st16_i32:
|
||||||
case INDEX_op_st16_i64:
|
case INDEX_op_st16_i64:
|
||||||
tcg_out_ldst(s, I3312_STRH, REG0(0), a1, a2, 1);
|
tcg_out_ldst(s, I3312_STRH, a0, a1, a2, 1);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_st_i32:
|
case INDEX_op_st_i32:
|
||||||
case INDEX_op_st32_i64:
|
case INDEX_op_st32_i64:
|
||||||
tcg_out_ldst(s, I3312_STRW, REG0(0), a1, a2, 2);
|
tcg_out_ldst(s, I3312_STRW, a0, a1, a2, 2);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_st_i64:
|
case INDEX_op_st_i64:
|
||||||
tcg_out_ldst(s, I3312_STRX, REG0(0), a1, a2, 3);
|
tcg_out_ldst(s, I3312_STRX, a0, a1, a2, 3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_add_i32:
|
case INDEX_op_add_i32:
|
||||||
@ -2395,28 +2391,22 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
|
|||||||
/* FALLTHRU */
|
/* FALLTHRU */
|
||||||
case INDEX_op_movcond_i64:
|
case INDEX_op_movcond_i64:
|
||||||
tcg_out_cmp(s, ext, args[5], a1, a2, c2);
|
tcg_out_cmp(s, ext, args[5], a1, a2, c2);
|
||||||
tcg_out_insn(s, 3506, CSEL, ext, a0, REG0(3), REG0(4), args[5]);
|
tcg_out_insn(s, 3506, CSEL, ext, a0, args[3], args[4], args[5]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
tcg_out_qemu_ld(s, a0, a1, a2, ext);
|
tcg_out_qemu_ld(s, a0, a1, a2, ext);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st_i64:
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
tcg_out_qemu_st(s, a0, a1, a2, ext);
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
tcg_out_qemu_st(s, REG0(0), a1, a2, ext);
|
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a32_i128:
|
case INDEX_op_qemu_ld_i128:
|
||||||
case INDEX_op_qemu_ld_a64_i128:
|
|
||||||
tcg_out_qemu_ldst_i128(s, a0, a1, a2, args[3], true);
|
tcg_out_qemu_ldst_i128(s, a0, a1, a2, args[3], true);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i128:
|
case INDEX_op_qemu_st_i128:
|
||||||
case INDEX_op_qemu_st_a64_i128:
|
tcg_out_qemu_ldst_i128(s, a0, a1, a2, args[3], false);
|
||||||
tcg_out_qemu_ldst_i128(s, REG0(0), REG0(1), a2, args[3], false);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_bswap64_i64:
|
case INDEX_op_bswap64_i64:
|
||||||
@ -2445,7 +2435,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
|
|||||||
|
|
||||||
case INDEX_op_deposit_i64:
|
case INDEX_op_deposit_i64:
|
||||||
case INDEX_op_deposit_i32:
|
case INDEX_op_deposit_i32:
|
||||||
tcg_out_dep(s, ext, a0, REG0(2), args[3], args[4]);
|
tcg_out_dep(s, ext, a0, a2, args[3], args[4]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_extract_i64:
|
case INDEX_op_extract_i64:
|
||||||
@ -2465,25 +2455,25 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
|
|||||||
|
|
||||||
case INDEX_op_extract2_i64:
|
case INDEX_op_extract2_i64:
|
||||||
case INDEX_op_extract2_i32:
|
case INDEX_op_extract2_i32:
|
||||||
tcg_out_extr(s, ext, a0, REG0(2), REG0(1), args[3]);
|
tcg_out_extr(s, ext, a0, a2, a1, args[3]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_add2_i32:
|
case INDEX_op_add2_i32:
|
||||||
tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, REG0(2), REG0(3),
|
tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, a2, args[3],
|
||||||
(int32_t)args[4], args[5], const_args[4],
|
(int32_t)args[4], args[5], const_args[4],
|
||||||
const_args[5], false);
|
const_args[5], false);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_add2_i64:
|
case INDEX_op_add2_i64:
|
||||||
tcg_out_addsub2(s, TCG_TYPE_I64, a0, a1, REG0(2), REG0(3), args[4],
|
tcg_out_addsub2(s, TCG_TYPE_I64, a0, a1, a2, args[3], args[4],
|
||||||
args[5], const_args[4], const_args[5], false);
|
args[5], const_args[4], const_args[5], false);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_sub2_i32:
|
case INDEX_op_sub2_i32:
|
||||||
tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, REG0(2), REG0(3),
|
tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, a2, args[3],
|
||||||
(int32_t)args[4], args[5], const_args[4],
|
(int32_t)args[4], args[5], const_args[4],
|
||||||
const_args[5], true);
|
const_args[5], true);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_sub2_i64:
|
case INDEX_op_sub2_i64:
|
||||||
tcg_out_addsub2(s, TCG_TYPE_I64, a0, a1, REG0(2), REG0(3), args[4],
|
tcg_out_addsub2(s, TCG_TYPE_I64, a0, a1, a2, args[3], args[4],
|
||||||
args[5], const_args[4], const_args[5], true);
|
args[5], const_args[4], const_args[5], true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2519,8 +2509,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
|
|||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef REG0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
|
static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
|
||||||
@ -3016,7 +3004,7 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_st16_i64:
|
case INDEX_op_st16_i64:
|
||||||
case INDEX_op_st32_i64:
|
case INDEX_op_st32_i64:
|
||||||
case INDEX_op_st_i64:
|
case INDEX_op_st_i64:
|
||||||
return C_O0_I2(rZ, r);
|
return C_O0_I2(rz, r);
|
||||||
|
|
||||||
case INDEX_op_add_i32:
|
case INDEX_op_add_i32:
|
||||||
case INDEX_op_add_i64:
|
case INDEX_op_add_i64:
|
||||||
@ -3082,38 +3070,32 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
|
|
||||||
case INDEX_op_movcond_i32:
|
case INDEX_op_movcond_i32:
|
||||||
case INDEX_op_movcond_i64:
|
case INDEX_op_movcond_i64:
|
||||||
return C_O1_I4(r, r, rC, rZ, rZ);
|
return C_O1_I4(r, r, rC, rz, rz);
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
return C_O1_I1(r, r);
|
return C_O1_I1(r, r);
|
||||||
case INDEX_op_qemu_ld_a32_i128:
|
case INDEX_op_qemu_ld_i128:
|
||||||
case INDEX_op_qemu_ld_a64_i128:
|
|
||||||
return C_O2_I1(r, r, r);
|
return C_O2_I1(r, r, r);
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st_i64:
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
return C_O0_I2(rz, r);
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
case INDEX_op_qemu_st_i128:
|
||||||
return C_O0_I2(rZ, r);
|
return C_O0_I3(rz, rz, r);
|
||||||
case INDEX_op_qemu_st_a32_i128:
|
|
||||||
case INDEX_op_qemu_st_a64_i128:
|
|
||||||
return C_O0_I3(rZ, rZ, r);
|
|
||||||
|
|
||||||
case INDEX_op_deposit_i32:
|
case INDEX_op_deposit_i32:
|
||||||
case INDEX_op_deposit_i64:
|
case INDEX_op_deposit_i64:
|
||||||
return C_O1_I2(r, 0, rZ);
|
return C_O1_I2(r, 0, rz);
|
||||||
|
|
||||||
case INDEX_op_extract2_i32:
|
case INDEX_op_extract2_i32:
|
||||||
case INDEX_op_extract2_i64:
|
case INDEX_op_extract2_i64:
|
||||||
return C_O1_I2(r, rZ, rZ);
|
return C_O1_I2(r, rz, rz);
|
||||||
|
|
||||||
case INDEX_op_add2_i32:
|
case INDEX_op_add2_i32:
|
||||||
case INDEX_op_add2_i64:
|
case INDEX_op_add2_i64:
|
||||||
case INDEX_op_sub2_i32:
|
case INDEX_op_sub2_i32:
|
||||||
case INDEX_op_sub2_i64:
|
case INDEX_op_sub2_i64:
|
||||||
return C_O2_I4(r, r, rZ, rZ, rA, rMZ);
|
return C_O2_I4(r, r, rz, rz, rA, rMZ);
|
||||||
|
|
||||||
case INDEX_op_add_vec:
|
case INDEX_op_add_vec:
|
||||||
case INDEX_op_sub_vec:
|
case INDEX_op_sub_vec:
|
||||||
|
@ -45,6 +45,8 @@ typedef enum {
|
|||||||
TCG_AREG0 = TCG_REG_X19,
|
TCG_AREG0 = TCG_REG_X19,
|
||||||
} TCGReg;
|
} TCGReg;
|
||||||
|
|
||||||
|
#define TCG_REG_ZERO TCG_REG_XZR
|
||||||
|
|
||||||
#define TCG_TARGET_NB_REGS 64
|
#define TCG_TARGET_NB_REGS 64
|
||||||
|
|
||||||
#endif /* AARCH64_TCG_TARGET_H */
|
#endif /* AARCH64_TCG_TARGET_H */
|
||||||
|
@ -676,14 +676,8 @@ static void tcg_out_ldrd_r(TCGContext *s, ARMCond cond, TCGReg rt,
|
|||||||
tcg_out_memop_r(s, cond, INSN_LDRD_REG, rt, rn, rm, 1, 1, 0);
|
tcg_out_memop_r(s, cond, INSN_LDRD_REG, rt, rn, rm, 1, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused))
|
static void tcg_out_strd_8(TCGContext *s, ARMCond cond, TCGReg rt,
|
||||||
tcg_out_ldrd_rwb(TCGContext *s, ARMCond cond, TCGReg rt, TCGReg rn, TCGReg rm)
|
TCGReg rn, int imm8)
|
||||||
{
|
|
||||||
tcg_out_memop_r(s, cond, INSN_LDRD_REG, rt, rn, rm, 1, 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused))
|
|
||||||
tcg_out_strd_8(TCGContext *s, ARMCond cond, TCGReg rt, TCGReg rn, int imm8)
|
|
||||||
{
|
{
|
||||||
tcg_out_memop_8(s, cond, INSN_STRD_IMM, rt, rn, imm8, 1, 0);
|
tcg_out_memop_8(s, cond, INSN_STRD_IMM, rt, rn, imm8, 1, 0);
|
||||||
}
|
}
|
||||||
@ -1455,8 +1449,7 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
|
|||||||
#define MIN_TLB_MASK_TABLE_OFS -256
|
#define MIN_TLB_MASK_TABLE_OFS -256
|
||||||
|
|
||||||
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
||||||
TCGReg addrlo, TCGReg addrhi,
|
TCGReg addr, MemOpIdx oi, bool is_ld)
|
||||||
MemOpIdx oi, bool is_ld)
|
|
||||||
{
|
{
|
||||||
TCGLabelQemuLdst *ldst = NULL;
|
TCGLabelQemuLdst *ldst = NULL;
|
||||||
MemOp opc = get_memop(oi);
|
MemOp opc = get_memop(oi);
|
||||||
@ -1465,14 +1458,14 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
if (tcg_use_softmmu) {
|
if (tcg_use_softmmu) {
|
||||||
*h = (HostAddress){
|
*h = (HostAddress){
|
||||||
.cond = COND_AL,
|
.cond = COND_AL,
|
||||||
.base = addrlo,
|
.base = addr,
|
||||||
.index = TCG_REG_R1,
|
.index = TCG_REG_R1,
|
||||||
.index_scratch = true,
|
.index_scratch = true,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
*h = (HostAddress){
|
*h = (HostAddress){
|
||||||
.cond = COND_AL,
|
.cond = COND_AL,
|
||||||
.base = addrlo,
|
.base = addr,
|
||||||
.index = guest_base ? TCG_REG_GUEST_BASE : -1,
|
.index = guest_base ? TCG_REG_GUEST_BASE : -1,
|
||||||
.index_scratch = false,
|
.index_scratch = false,
|
||||||
};
|
};
|
||||||
@ -1492,8 +1485,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addrlo;
|
ldst->addr_reg = addr;
|
||||||
ldst->addrhi_reg = addrhi;
|
|
||||||
|
|
||||||
/* Load cpu->neg.tlb.f[mmu_idx].{mask,table} into {r0,r1}. */
|
/* Load cpu->neg.tlb.f[mmu_idx].{mask,table} into {r0,r1}. */
|
||||||
QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, mask) != 0);
|
QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, mask) != 0);
|
||||||
@ -1501,30 +1493,19 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
tcg_out_ldrd_8(s, COND_AL, TCG_REG_R0, TCG_AREG0, fast_off);
|
tcg_out_ldrd_8(s, COND_AL, TCG_REG_R0, TCG_AREG0, fast_off);
|
||||||
|
|
||||||
/* Extract the tlb index from the address into R0. */
|
/* Extract the tlb index from the address into R0. */
|
||||||
tcg_out_dat_reg(s, COND_AL, ARITH_AND, TCG_REG_R0, TCG_REG_R0, addrlo,
|
tcg_out_dat_reg(s, COND_AL, ARITH_AND, TCG_REG_R0, TCG_REG_R0, addr,
|
||||||
SHIFT_IMM_LSR(s->page_bits - CPU_TLB_ENTRY_BITS));
|
SHIFT_IMM_LSR(s->page_bits - CPU_TLB_ENTRY_BITS));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add the tlb_table pointer, creating the CPUTLBEntry address in R1.
|
* Add the tlb_table pointer, creating the CPUTLBEntry address in R1.
|
||||||
* Load the tlb comparator into R2/R3 and the fast path addend into R1.
|
* Load the tlb comparator into R2 and the fast path addend into R1.
|
||||||
*/
|
*/
|
||||||
QEMU_BUILD_BUG_ON(HOST_BIG_ENDIAN);
|
|
||||||
if (cmp_off == 0) {
|
if (cmp_off == 0) {
|
||||||
if (s->addr_type == TCG_TYPE_I32) {
|
tcg_out_ld32_rwb(s, COND_AL, TCG_REG_R2, TCG_REG_R1, TCG_REG_R0);
|
||||||
tcg_out_ld32_rwb(s, COND_AL, TCG_REG_R2,
|
|
||||||
TCG_REG_R1, TCG_REG_R0);
|
|
||||||
} else {
|
|
||||||
tcg_out_ldrd_rwb(s, COND_AL, TCG_REG_R2,
|
|
||||||
TCG_REG_R1, TCG_REG_R0);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
tcg_out_dat_reg(s, COND_AL, ARITH_ADD,
|
tcg_out_dat_reg(s, COND_AL, ARITH_ADD,
|
||||||
TCG_REG_R1, TCG_REG_R1, TCG_REG_R0, 0);
|
TCG_REG_R1, TCG_REG_R1, TCG_REG_R0, 0);
|
||||||
if (s->addr_type == TCG_TYPE_I32) {
|
tcg_out_ld32_12(s, COND_AL, TCG_REG_R2, TCG_REG_R1, cmp_off);
|
||||||
tcg_out_ld32_12(s, COND_AL, TCG_REG_R2, TCG_REG_R1, cmp_off);
|
|
||||||
} else {
|
|
||||||
tcg_out_ldrd_8(s, COND_AL, TCG_REG_R2, TCG_REG_R1, cmp_off);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the tlb addend. */
|
/* Load the tlb addend. */
|
||||||
@ -1543,11 +1524,11 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
* This leaves the least significant alignment bits unchanged, and of
|
* This leaves the least significant alignment bits unchanged, and of
|
||||||
* course must be zero.
|
* course must be zero.
|
||||||
*/
|
*/
|
||||||
t_addr = addrlo;
|
t_addr = addr;
|
||||||
if (a_mask < s_mask) {
|
if (a_mask < s_mask) {
|
||||||
t_addr = TCG_REG_R0;
|
t_addr = TCG_REG_R0;
|
||||||
tcg_out_dat_imm(s, COND_AL, ARITH_ADD, t_addr,
|
tcg_out_dat_imm(s, COND_AL, ARITH_ADD, t_addr,
|
||||||
addrlo, s_mask - a_mask);
|
addr, s_mask - a_mask);
|
||||||
}
|
}
|
||||||
if (use_armv7_instructions && s->page_bits <= 16) {
|
if (use_armv7_instructions && s->page_bits <= 16) {
|
||||||
tcg_out_movi32(s, COND_AL, TCG_REG_TMP, ~(s->page_mask | a_mask));
|
tcg_out_movi32(s, COND_AL, TCG_REG_TMP, ~(s->page_mask | a_mask));
|
||||||
@ -1558,7 +1539,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
} else {
|
} else {
|
||||||
if (a_mask) {
|
if (a_mask) {
|
||||||
tcg_debug_assert(a_mask <= 0xff);
|
tcg_debug_assert(a_mask <= 0xff);
|
||||||
tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, addrlo, a_mask);
|
tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, addr, a_mask);
|
||||||
}
|
}
|
||||||
tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_TMP, 0, t_addr,
|
tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_TMP, 0, t_addr,
|
||||||
SHIFT_IMM_LSR(s->page_bits));
|
SHIFT_IMM_LSR(s->page_bits));
|
||||||
@ -1566,21 +1547,16 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
0, TCG_REG_R2, TCG_REG_TMP,
|
0, TCG_REG_R2, TCG_REG_TMP,
|
||||||
SHIFT_IMM_LSL(s->page_bits));
|
SHIFT_IMM_LSL(s->page_bits));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->addr_type != TCG_TYPE_I32) {
|
|
||||||
tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0, TCG_REG_R3, addrhi, 0);
|
|
||||||
}
|
|
||||||
} else if (a_mask) {
|
} else if (a_mask) {
|
||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addrlo;
|
ldst->addr_reg = addr;
|
||||||
ldst->addrhi_reg = addrhi;
|
|
||||||
|
|
||||||
/* We are expecting alignment to max out at 7 */
|
/* We are expecting alignment to max out at 7 */
|
||||||
tcg_debug_assert(a_mask <= 0xff);
|
tcg_debug_assert(a_mask <= 0xff);
|
||||||
/* tst addr, #mask */
|
/* tst addr, #mask */
|
||||||
tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, addrlo, a_mask);
|
tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, addr, a_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ldst;
|
return ldst;
|
||||||
@ -1678,14 +1654,13 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg datalo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
||||||
TCGReg addrlo, TCGReg addrhi,
|
TCGReg addr, MemOpIdx oi, TCGType data_type)
|
||||||
MemOpIdx oi, TCGType data_type)
|
|
||||||
{
|
{
|
||||||
MemOp opc = get_memop(oi);
|
MemOp opc = get_memop(oi);
|
||||||
TCGLabelQemuLdst *ldst;
|
TCGLabelQemuLdst *ldst;
|
||||||
HostAddress h;
|
HostAddress h;
|
||||||
|
|
||||||
ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, true);
|
ldst = prepare_host_addr(s, &h, addr, oi, true);
|
||||||
if (ldst) {
|
if (ldst) {
|
||||||
ldst->type = data_type;
|
ldst->type = data_type;
|
||||||
ldst->datalo_reg = datalo;
|
ldst->datalo_reg = datalo;
|
||||||
@ -1764,14 +1739,13 @@ static void tcg_out_qemu_st_direct(TCGContext *s, MemOp opc, TCGReg datalo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_qemu_st(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
static void tcg_out_qemu_st(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
||||||
TCGReg addrlo, TCGReg addrhi,
|
TCGReg addr, MemOpIdx oi, TCGType data_type)
|
||||||
MemOpIdx oi, TCGType data_type)
|
|
||||||
{
|
{
|
||||||
MemOp opc = get_memop(oi);
|
MemOp opc = get_memop(oi);
|
||||||
TCGLabelQemuLdst *ldst;
|
TCGLabelQemuLdst *ldst;
|
||||||
HostAddress h;
|
HostAddress h;
|
||||||
|
|
||||||
ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, false);
|
ldst = prepare_host_addr(s, &h, addr, oi, false);
|
||||||
if (ldst) {
|
if (ldst) {
|
||||||
ldst->type = data_type;
|
ldst->type = data_type;
|
||||||
ldst->datalo_reg = datalo;
|
ldst->datalo_reg = datalo;
|
||||||
@ -2071,36 +2045,18 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||||||
ARITH_MOV, args[0], 0, 0);
|
ARITH_MOV, args[0], 0, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
tcg_out_qemu_ld(s, args[0], -1, args[1], -1, args[2], TCG_TYPE_I32);
|
tcg_out_qemu_ld(s, args[0], -1, args[1], args[2], TCG_TYPE_I32);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
tcg_out_qemu_ld(s, args[0], -1, args[1], args[2],
|
tcg_out_qemu_ld(s, args[0], args[1], args[2], args[3], TCG_TYPE_I64);
|
||||||
args[3], TCG_TYPE_I32);
|
|
||||||
break;
|
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
|
||||||
tcg_out_qemu_ld(s, args[0], args[1], args[2], -1,
|
|
||||||
args[3], TCG_TYPE_I64);
|
|
||||||
break;
|
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
tcg_out_qemu_ld(s, args[0], args[1], args[2], args[3],
|
|
||||||
args[4], TCG_TYPE_I64);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
tcg_out_qemu_st(s, args[0], -1, args[1], -1, args[2], TCG_TYPE_I32);
|
tcg_out_qemu_st(s, args[0], -1, args[1], args[2], TCG_TYPE_I32);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st_i64:
|
||||||
tcg_out_qemu_st(s, args[0], -1, args[1], args[2],
|
tcg_out_qemu_st(s, args[0], args[1], args[2], args[3], TCG_TYPE_I64);
|
||||||
args[3], TCG_TYPE_I32);
|
|
||||||
break;
|
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
|
||||||
tcg_out_qemu_st(s, args[0], args[1], args[2], -1,
|
|
||||||
args[3], TCG_TYPE_I64);
|
|
||||||
break;
|
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
tcg_out_qemu_st(s, args[0], args[1], args[2], args[3],
|
|
||||||
args[4], TCG_TYPE_I64);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_bswap16_i32:
|
case INDEX_op_bswap16_i32:
|
||||||
@ -2243,22 +2199,14 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_setcond2_i32:
|
case INDEX_op_setcond2_i32:
|
||||||
return C_O1_I4(r, r, r, rI, rI);
|
return C_O1_I4(r, r, r, rI, rI);
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
return C_O1_I1(r, q);
|
return C_O1_I1(r, q);
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
return C_O1_I2(r, q, q);
|
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
|
||||||
return C_O2_I1(e, p, q);
|
return C_O2_I1(e, p, q);
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
case INDEX_op_qemu_st_i32:
|
||||||
return C_O2_I2(e, p, q, q);
|
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
|
||||||
return C_O0_I2(q, q);
|
return C_O0_I2(q, q);
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st_i64:
|
||||||
return C_O0_I3(q, q, q);
|
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
|
||||||
return C_O0_I3(Q, p, q);
|
return C_O0_I3(Q, p, q);
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
return C_O0_I4(Q, p, q, q);
|
|
||||||
|
|
||||||
case INDEX_op_st_vec:
|
case INDEX_op_st_vec:
|
||||||
return C_O0_I2(w, r);
|
return C_O0_I2(w, r);
|
||||||
|
@ -1658,6 +1658,7 @@ static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
|
|||||||
tcg_out_brcond(s, 0, cond, args[1], args[3], const_args[3],
|
tcg_out_brcond(s, 0, cond, args[1], args[3], const_args[3],
|
||||||
label_this, small);
|
label_this, small);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TCG_COND_NE:
|
case TCG_COND_NE:
|
||||||
case TCG_COND_TSTNE:
|
case TCG_COND_TSTNE:
|
||||||
tcg_out_brcond(s, 0, cond, args[0], args[2], const_args[2],
|
tcg_out_brcond(s, 0, cond, args[0], args[2], const_args[2],
|
||||||
@ -1665,64 +1666,14 @@ static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
|
|||||||
tcg_out_brcond(s, 0, cond, args[1], args[3], const_args[3],
|
tcg_out_brcond(s, 0, cond, args[1], args[3], const_args[3],
|
||||||
label_this, small);
|
label_this, small);
|
||||||
break;
|
break;
|
||||||
case TCG_COND_LT:
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_LT, args[1], args[3], const_args[3],
|
|
||||||
label_this, small);
|
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_LTU, args[0], args[2], const_args[2],
|
|
||||||
label_this, small);
|
|
||||||
break;
|
|
||||||
case TCG_COND_LE:
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_LT, args[1], args[3], const_args[3],
|
|
||||||
label_this, small);
|
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_LEU, args[0], args[2], const_args[2],
|
|
||||||
label_this, small);
|
|
||||||
break;
|
|
||||||
case TCG_COND_GT:
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_GT, args[1], args[3], const_args[3],
|
|
||||||
label_this, small);
|
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_GTU, args[0], args[2], const_args[2],
|
|
||||||
label_this, small);
|
|
||||||
break;
|
|
||||||
case TCG_COND_GE:
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_GT, args[1], args[3], const_args[3],
|
|
||||||
label_this, small);
|
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_GEU, args[0], args[2], const_args[2],
|
|
||||||
label_this, small);
|
|
||||||
break;
|
|
||||||
case TCG_COND_LTU:
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_LTU, args[1], args[3], const_args[3],
|
|
||||||
label_this, small);
|
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_LTU, args[0], args[2], const_args[2],
|
|
||||||
label_this, small);
|
|
||||||
break;
|
|
||||||
case TCG_COND_LEU:
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_LTU, args[1], args[3], const_args[3],
|
|
||||||
label_this, small);
|
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_LEU, args[0], args[2], const_args[2],
|
|
||||||
label_this, small);
|
|
||||||
break;
|
|
||||||
case TCG_COND_GTU:
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_GTU, args[1], args[3], const_args[3],
|
|
||||||
label_this, small);
|
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_GTU, args[0], args[2], const_args[2],
|
|
||||||
label_this, small);
|
|
||||||
break;
|
|
||||||
case TCG_COND_GEU:
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_GTU, args[1], args[3], const_args[3],
|
|
||||||
label_this, small);
|
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
|
||||||
tcg_out_brcond(s, 0, TCG_COND_GEU, args[0], args[2], const_args[2],
|
|
||||||
label_this, small);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
tcg_out_brcond(s, 0, tcg_high_cond(cond), args[1],
|
||||||
|
args[3], const_args[3], label_this, small);
|
||||||
|
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
||||||
|
tcg_out_brcond(s, 0, tcg_unsigned_cond(cond), args[0],
|
||||||
|
args[2], const_args[2], label_this, small);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
tcg_out_label(s, label_next);
|
tcg_out_label(s, label_next);
|
||||||
}
|
}
|
||||||
@ -2169,8 +2120,7 @@ static inline int setup_guest_base_seg(void)
|
|||||||
* is required and fill in @h with the host address for the fast path.
|
* is required and fill in @h with the host address for the fast path.
|
||||||
*/
|
*/
|
||||||
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
||||||
TCGReg addrlo, TCGReg addrhi,
|
TCGReg addr, MemOpIdx oi, bool is_ld)
|
||||||
MemOpIdx oi, bool is_ld)
|
|
||||||
{
|
{
|
||||||
TCGLabelQemuLdst *ldst = NULL;
|
TCGLabelQemuLdst *ldst = NULL;
|
||||||
MemOp opc = get_memop(oi);
|
MemOp opc = get_memop(oi);
|
||||||
@ -2184,7 +2134,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
} else {
|
} else {
|
||||||
*h = x86_guest_base;
|
*h = x86_guest_base;
|
||||||
}
|
}
|
||||||
h->base = addrlo;
|
h->base = addr;
|
||||||
h->aa = atom_and_align_for_opc(s, opc, MO_ATOM_IFALIGN, s_bits == MO_128);
|
h->aa = atom_and_align_for_opc(s, opc, MO_ATOM_IFALIGN, s_bits == MO_128);
|
||||||
a_mask = (1 << h->aa.align) - 1;
|
a_mask = (1 << h->aa.align) - 1;
|
||||||
|
|
||||||
@ -2202,8 +2152,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addrlo;
|
ldst->addr_reg = addr;
|
||||||
ldst->addrhi_reg = addrhi;
|
|
||||||
|
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
if (TCG_TARGET_REG_BITS == 64) {
|
||||||
ttype = s->addr_type;
|
ttype = s->addr_type;
|
||||||
@ -2217,7 +2166,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tcg_out_mov(s, tlbtype, TCG_REG_L0, addrlo);
|
tcg_out_mov(s, tlbtype, TCG_REG_L0, addr);
|
||||||
tcg_out_shifti(s, SHIFT_SHR + tlbrexw, TCG_REG_L0,
|
tcg_out_shifti(s, SHIFT_SHR + tlbrexw, TCG_REG_L0,
|
||||||
s->page_bits - CPU_TLB_ENTRY_BITS);
|
s->page_bits - CPU_TLB_ENTRY_BITS);
|
||||||
|
|
||||||
@ -2233,10 +2182,10 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
* check that we don't cross pages for the complete access.
|
* check that we don't cross pages for the complete access.
|
||||||
*/
|
*/
|
||||||
if (a_mask >= s_mask) {
|
if (a_mask >= s_mask) {
|
||||||
tcg_out_mov(s, ttype, TCG_REG_L1, addrlo);
|
tcg_out_mov(s, ttype, TCG_REG_L1, addr);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_modrm_offset(s, OPC_LEA + trexw, TCG_REG_L1,
|
tcg_out_modrm_offset(s, OPC_LEA + trexw, TCG_REG_L1,
|
||||||
addrlo, s_mask - a_mask);
|
addr, s_mask - a_mask);
|
||||||
}
|
}
|
||||||
tlb_mask = s->page_mask | a_mask;
|
tlb_mask = s->page_mask | a_mask;
|
||||||
tgen_arithi(s, ARITH_AND + trexw, TCG_REG_L1, tlb_mask, 0);
|
tgen_arithi(s, ARITH_AND + trexw, TCG_REG_L1, tlb_mask, 0);
|
||||||
@ -2250,17 +2199,6 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
ldst->label_ptr[0] = s->code_ptr;
|
ldst->label_ptr[0] = s->code_ptr;
|
||||||
s->code_ptr += 4;
|
s->code_ptr += 4;
|
||||||
|
|
||||||
if (TCG_TARGET_REG_BITS == 32 && s->addr_type == TCG_TYPE_I64) {
|
|
||||||
/* cmp 4(TCG_REG_L0), addrhi */
|
|
||||||
tcg_out_modrm_offset(s, OPC_CMP_GvEv, addrhi,
|
|
||||||
TCG_REG_L0, cmp_ofs + 4);
|
|
||||||
|
|
||||||
/* jne slow_path */
|
|
||||||
tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0);
|
|
||||||
ldst->label_ptr[1] = s->code_ptr;
|
|
||||||
s->code_ptr += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TLB Hit. */
|
/* TLB Hit. */
|
||||||
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_L0, TCG_REG_L0,
|
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_L0, TCG_REG_L0,
|
||||||
offsetof(CPUTLBEntry, addend));
|
offsetof(CPUTLBEntry, addend));
|
||||||
@ -2270,11 +2208,10 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addrlo;
|
ldst->addr_reg = addr;
|
||||||
ldst->addrhi_reg = addrhi;
|
|
||||||
|
|
||||||
/* jne slow_path */
|
/* jne slow_path */
|
||||||
jcc = tcg_out_cmp(s, TCG_COND_TSTNE, addrlo, a_mask, true, false);
|
jcc = tcg_out_cmp(s, TCG_COND_TSTNE, addr, a_mask, true, false);
|
||||||
tcg_out_opc(s, OPC_JCC_long + jcc, 0, 0, 0);
|
tcg_out_opc(s, OPC_JCC_long + jcc, 0, 0, 0);
|
||||||
ldst->label_ptr[0] = s->code_ptr;
|
ldst->label_ptr[0] = s->code_ptr;
|
||||||
s->code_ptr += 4;
|
s->code_ptr += 4;
|
||||||
@ -2446,13 +2383,12 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
||||||
TCGReg addrlo, TCGReg addrhi,
|
TCGReg addr, MemOpIdx oi, TCGType data_type)
|
||||||
MemOpIdx oi, TCGType data_type)
|
|
||||||
{
|
{
|
||||||
TCGLabelQemuLdst *ldst;
|
TCGLabelQemuLdst *ldst;
|
||||||
HostAddress h;
|
HostAddress h;
|
||||||
|
|
||||||
ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, true);
|
ldst = prepare_host_addr(s, &h, addr, oi, true);
|
||||||
tcg_out_qemu_ld_direct(s, datalo, datahi, h, data_type, get_memop(oi));
|
tcg_out_qemu_ld_direct(s, datalo, datahi, h, data_type, get_memop(oi));
|
||||||
|
|
||||||
if (ldst) {
|
if (ldst) {
|
||||||
@ -2574,13 +2510,12 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_qemu_st(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
static void tcg_out_qemu_st(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
||||||
TCGReg addrlo, TCGReg addrhi,
|
TCGReg addr, MemOpIdx oi, TCGType data_type)
|
||||||
MemOpIdx oi, TCGType data_type)
|
|
||||||
{
|
{
|
||||||
TCGLabelQemuLdst *ldst;
|
TCGLabelQemuLdst *ldst;
|
||||||
HostAddress h;
|
HostAddress h;
|
||||||
|
|
||||||
ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, false);
|
ldst = prepare_host_addr(s, &h, addr, oi, false);
|
||||||
tcg_out_qemu_st_direct(s, datalo, datahi, h, get_memop(oi));
|
tcg_out_qemu_st_direct(s, datalo, datahi, h, get_memop(oi));
|
||||||
|
|
||||||
if (ldst) {
|
if (ldst) {
|
||||||
@ -2879,64 +2814,35 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||||||
tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, a0);
|
tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, a0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
if (TCG_TARGET_REG_BITS == 32) {
|
tcg_out_qemu_ld(s, a0, -1, a1, a2, TCG_TYPE_I32);
|
||||||
tcg_out_qemu_ld(s, a0, -1, a1, a2, args[3], TCG_TYPE_I32);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* fall through */
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
|
||||||
tcg_out_qemu_ld(s, a0, -1, a1, -1, a2, TCG_TYPE_I32);
|
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
case INDEX_op_qemu_ld_i64:
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
if (TCG_TARGET_REG_BITS == 64) {
|
||||||
tcg_out_qemu_ld(s, a0, -1, a1, -1, a2, TCG_TYPE_I64);
|
tcg_out_qemu_ld(s, a0, -1, a1, a2, TCG_TYPE_I64);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_qemu_ld(s, a0, a1, a2, -1, args[3], TCG_TYPE_I64);
|
tcg_out_qemu_ld(s, a0, a1, a2, args[3], TCG_TYPE_I64);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
case INDEX_op_qemu_ld_i128:
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
|
||||||
tcg_out_qemu_ld(s, a0, -1, a1, -1, a2, TCG_TYPE_I64);
|
|
||||||
} else {
|
|
||||||
tcg_out_qemu_ld(s, a0, a1, a2, args[3], args[4], TCG_TYPE_I64);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case INDEX_op_qemu_ld_a32_i128:
|
|
||||||
case INDEX_op_qemu_ld_a64_i128:
|
|
||||||
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
||||||
tcg_out_qemu_ld(s, a0, a1, a2, -1, args[3], TCG_TYPE_I128);
|
tcg_out_qemu_ld(s, a0, a1, a2, args[3], TCG_TYPE_I128);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
case INDEX_op_qemu_st8_a64_i32:
|
case INDEX_op_qemu_st8_i32:
|
||||||
if (TCG_TARGET_REG_BITS == 32) {
|
tcg_out_qemu_st(s, a0, -1, a1, a2, TCG_TYPE_I32);
|
||||||
tcg_out_qemu_st(s, a0, -1, a1, a2, args[3], TCG_TYPE_I32);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* fall through */
|
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
|
||||||
case INDEX_op_qemu_st8_a32_i32:
|
|
||||||
tcg_out_qemu_st(s, a0, -1, a1, -1, a2, TCG_TYPE_I32);
|
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
case INDEX_op_qemu_st_i64:
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
if (TCG_TARGET_REG_BITS == 64) {
|
||||||
tcg_out_qemu_st(s, a0, -1, a1, -1, a2, TCG_TYPE_I64);
|
tcg_out_qemu_st(s, a0, -1, a1, a2, TCG_TYPE_I64);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_qemu_st(s, a0, a1, a2, -1, args[3], TCG_TYPE_I64);
|
tcg_out_qemu_st(s, a0, a1, a2, args[3], TCG_TYPE_I64);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
case INDEX_op_qemu_st_i128:
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
|
||||||
tcg_out_qemu_st(s, a0, -1, a1, -1, a2, TCG_TYPE_I64);
|
|
||||||
} else {
|
|
||||||
tcg_out_qemu_st(s, a0, a1, a2, args[3], args[4], TCG_TYPE_I64);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case INDEX_op_qemu_st_a32_i128:
|
|
||||||
case INDEX_op_qemu_st_a64_i128:
|
|
||||||
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
||||||
tcg_out_qemu_st(s, a0, a1, a2, -1, args[3], TCG_TYPE_I128);
|
tcg_out_qemu_st(s, a0, a1, a2, args[3], TCG_TYPE_I128);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
OP_32_64(mulu2):
|
OP_32_64(mulu2):
|
||||||
@ -3824,36 +3730,24 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_clz_i64:
|
case INDEX_op_clz_i64:
|
||||||
return have_lzcnt ? C_N1_I2(r, r, rW) : C_N1_I2(r, r, r);
|
return have_lzcnt ? C_N1_I2(r, r, rW) : C_N1_I2(r, r, r);
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
return C_O1_I1(r, L);
|
return C_O1_I1(r, L);
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, L) : C_O1_I2(r, L, L);
|
|
||||||
|
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
return C_O0_I2(L, L);
|
return C_O0_I2(L, L);
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st8_i32:
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(L, L) : C_O0_I3(L, L, L);
|
|
||||||
case INDEX_op_qemu_st8_a32_i32:
|
|
||||||
return C_O0_I2(s, L);
|
return C_O0_I2(s, L);
|
||||||
case INDEX_op_qemu_st8_a64_i32:
|
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(s, L) : C_O0_I3(s, L, L);
|
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
case INDEX_op_qemu_ld_i64:
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, L) : C_O2_I1(r, r, L);
|
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, L) : C_O2_I1(r, r, L);
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, L) : C_O2_I2(r, r, L, L);
|
|
||||||
|
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
case INDEX_op_qemu_st_i64:
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(L, L) : C_O0_I3(L, L, L);
|
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(L, L) : C_O0_I3(L, L, L);
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(L, L) : C_O0_I4(L, L, L, L);
|
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i128:
|
case INDEX_op_qemu_ld_i128:
|
||||||
case INDEX_op_qemu_ld_a64_i128:
|
|
||||||
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
||||||
return C_O2_I1(r, r, L);
|
return C_O2_I1(r, r, L);
|
||||||
case INDEX_op_qemu_st_a32_i128:
|
case INDEX_op_qemu_st_i128:
|
||||||
case INDEX_op_qemu_st_a64_i128:
|
|
||||||
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
||||||
return C_O0_I3(L, L, L);
|
return C_O0_I3(L, L, L);
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
* tcg-target-con-str.h; the constraint combination is inclusive or.
|
* tcg-target-con-str.h; the constraint combination is inclusive or.
|
||||||
*/
|
*/
|
||||||
C_O0_I1(r)
|
C_O0_I1(r)
|
||||||
C_O0_I2(rZ, r)
|
C_O0_I2(rz, r)
|
||||||
C_O0_I2(rZ, rZ)
|
C_O0_I2(rz, rz)
|
||||||
C_O0_I2(w, r)
|
C_O0_I2(w, r)
|
||||||
C_O0_I3(r, r, r)
|
C_O0_I3(r, r, r)
|
||||||
C_O1_I1(r, r)
|
C_O1_I1(r, r)
|
||||||
@ -28,14 +28,13 @@ C_O1_I2(r, r, rI)
|
|||||||
C_O1_I2(r, r, rJ)
|
C_O1_I2(r, r, rJ)
|
||||||
C_O1_I2(r, r, rU)
|
C_O1_I2(r, r, rU)
|
||||||
C_O1_I2(r, r, rW)
|
C_O1_I2(r, r, rW)
|
||||||
C_O1_I2(r, r, rZ)
|
C_O1_I2(r, 0, rz)
|
||||||
C_O1_I2(r, 0, rZ)
|
C_O1_I2(r, rz, ri)
|
||||||
C_O1_I2(r, rZ, ri)
|
C_O1_I2(r, rz, rJ)
|
||||||
C_O1_I2(r, rZ, rJ)
|
C_O1_I2(r, rz, rz)
|
||||||
C_O1_I2(r, rZ, rZ)
|
|
||||||
C_O1_I2(w, w, w)
|
C_O1_I2(w, w, w)
|
||||||
C_O1_I2(w, w, wM)
|
C_O1_I2(w, w, wM)
|
||||||
C_O1_I2(w, w, wA)
|
C_O1_I2(w, w, wA)
|
||||||
C_O1_I3(w, w, w, w)
|
C_O1_I3(w, w, w, w)
|
||||||
C_O1_I4(r, rZ, rJ, rZ, rZ)
|
C_O1_I4(r, rz, rJ, rz, rz)
|
||||||
C_N2_I1(r, r, r)
|
C_N2_I1(r, r, r)
|
||||||
|
@ -23,7 +23,6 @@ REGS('w', ALL_VECTOR_REGS)
|
|||||||
CONST('I', TCG_CT_CONST_S12)
|
CONST('I', TCG_CT_CONST_S12)
|
||||||
CONST('J', TCG_CT_CONST_S32)
|
CONST('J', TCG_CT_CONST_S32)
|
||||||
CONST('U', TCG_CT_CONST_U12)
|
CONST('U', TCG_CT_CONST_U12)
|
||||||
CONST('Z', TCG_CT_CONST_ZERO)
|
|
||||||
CONST('C', TCG_CT_CONST_C12)
|
CONST('C', TCG_CT_CONST_C12)
|
||||||
CONST('W', TCG_CT_CONST_WSZ)
|
CONST('W', TCG_CT_CONST_WSZ)
|
||||||
CONST('M', TCG_CT_CONST_VCMP)
|
CONST('M', TCG_CT_CONST_VCMP)
|
||||||
|
@ -37,8 +37,6 @@
|
|||||||
#define TCG_TARGET_HAS_clz_i32 1
|
#define TCG_TARGET_HAS_clz_i32 1
|
||||||
#define TCG_TARGET_HAS_ctz_i32 1
|
#define TCG_TARGET_HAS_ctz_i32 1
|
||||||
#define TCG_TARGET_HAS_ctpop_i32 0
|
#define TCG_TARGET_HAS_ctpop_i32 0
|
||||||
#define TCG_TARGET_HAS_brcond2 0
|
|
||||||
#define TCG_TARGET_HAS_setcond2 0
|
|
||||||
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
||||||
|
|
||||||
/* 64-bit operations */
|
/* 64-bit operations */
|
||||||
|
@ -173,14 +173,13 @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
|
|||||||
|
|
||||||
#define TCG_GUEST_BASE_REG TCG_REG_S1
|
#define TCG_GUEST_BASE_REG TCG_REG_S1
|
||||||
|
|
||||||
#define TCG_CT_CONST_ZERO 0x100
|
#define TCG_CT_CONST_S12 0x100
|
||||||
#define TCG_CT_CONST_S12 0x200
|
#define TCG_CT_CONST_S32 0x200
|
||||||
#define TCG_CT_CONST_S32 0x400
|
#define TCG_CT_CONST_U12 0x400
|
||||||
#define TCG_CT_CONST_U12 0x800
|
#define TCG_CT_CONST_C12 0x800
|
||||||
#define TCG_CT_CONST_C12 0x1000
|
#define TCG_CT_CONST_WSZ 0x1000
|
||||||
#define TCG_CT_CONST_WSZ 0x2000
|
#define TCG_CT_CONST_VCMP 0x2000
|
||||||
#define TCG_CT_CONST_VCMP 0x4000
|
#define TCG_CT_CONST_VADD 0x4000
|
||||||
#define TCG_CT_CONST_VADD 0x8000
|
|
||||||
|
|
||||||
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
|
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
|
||||||
#define ALL_VECTOR_REGS MAKE_64BIT_MASK(32, 32)
|
#define ALL_VECTOR_REGS MAKE_64BIT_MASK(32, 32)
|
||||||
@ -197,9 +196,6 @@ static bool tcg_target_const_match(int64_t val, int ct,
|
|||||||
if (ct & TCG_CT_CONST) {
|
if (ct & TCG_CT_CONST) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
|
if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1010,7 +1006,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addr_reg;
|
ldst->addr_reg = addr_reg;
|
||||||
|
|
||||||
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_AREG0, mask_ofs);
|
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_AREG0, mask_ofs);
|
||||||
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, table_ofs);
|
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, table_ofs);
|
||||||
@ -1055,7 +1051,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
|
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addr_reg;
|
ldst->addr_reg = addr_reg;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Without micro-architecture details, we don't know which of
|
* Without micro-architecture details, we don't know which of
|
||||||
@ -1675,28 +1671,22 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||||||
tcg_out_ldst(s, OPC_ST_D, a0, a1, a2);
|
tcg_out_ldst(s, OPC_ST_D, a0, a1, a2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
|
||||||
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
|
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I64);
|
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I64);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a32_i128:
|
case INDEX_op_qemu_ld_i128:
|
||||||
case INDEX_op_qemu_ld_a64_i128:
|
|
||||||
tcg_out_qemu_ldst_i128(s, a0, a1, a2, a3, true);
|
tcg_out_qemu_ldst_i128(s, a0, a1, a2, a3, true);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
|
||||||
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I32);
|
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I32);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
case INDEX_op_qemu_st_i64:
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I64);
|
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I64);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i128:
|
case INDEX_op_qemu_st_i128:
|
||||||
case INDEX_op_qemu_st_a64_i128:
|
|
||||||
tcg_out_qemu_ldst_i128(s, a0, a1, a2, a3, false);
|
tcg_out_qemu_ldst_i128(s, a0, a1, a2, a3, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2233,23 +2223,19 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_st32_i64:
|
case INDEX_op_st32_i64:
|
||||||
case INDEX_op_st_i32:
|
case INDEX_op_st_i32:
|
||||||
case INDEX_op_st_i64:
|
case INDEX_op_st_i64:
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st_i64:
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
return C_O0_I2(rz, r);
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
return C_O0_I2(rZ, r);
|
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i128:
|
case INDEX_op_qemu_ld_i128:
|
||||||
case INDEX_op_qemu_ld_a64_i128:
|
|
||||||
return C_N2_I1(r, r, r);
|
return C_N2_I1(r, r, r);
|
||||||
|
|
||||||
case INDEX_op_qemu_st_a32_i128:
|
case INDEX_op_qemu_st_i128:
|
||||||
case INDEX_op_qemu_st_a64_i128:
|
|
||||||
return C_O0_I3(r, r, r);
|
return C_O0_I3(r, r, r);
|
||||||
|
|
||||||
case INDEX_op_brcond_i32:
|
case INDEX_op_brcond_i32:
|
||||||
case INDEX_op_brcond_i64:
|
case INDEX_op_brcond_i64:
|
||||||
return C_O0_I2(rZ, rZ);
|
return C_O0_I2(rz, rz);
|
||||||
|
|
||||||
case INDEX_op_ext8s_i32:
|
case INDEX_op_ext8s_i32:
|
||||||
case INDEX_op_ext8s_i64:
|
case INDEX_op_ext8s_i64:
|
||||||
@ -2290,10 +2276,8 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_ld32u_i64:
|
case INDEX_op_ld32u_i64:
|
||||||
case INDEX_op_ld_i32:
|
case INDEX_op_ld_i32:
|
||||||
case INDEX_op_ld_i64:
|
case INDEX_op_ld_i64:
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
return C_O1_I1(r, r);
|
return C_O1_I1(r, r);
|
||||||
|
|
||||||
case INDEX_op_andc_i32:
|
case INDEX_op_andc_i32:
|
||||||
@ -2344,14 +2328,14 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_deposit_i32:
|
case INDEX_op_deposit_i32:
|
||||||
case INDEX_op_deposit_i64:
|
case INDEX_op_deposit_i64:
|
||||||
/* Must deposit into the same register as input */
|
/* Must deposit into the same register as input */
|
||||||
return C_O1_I2(r, 0, rZ);
|
return C_O1_I2(r, 0, rz);
|
||||||
|
|
||||||
case INDEX_op_sub_i32:
|
case INDEX_op_sub_i32:
|
||||||
case INDEX_op_setcond_i32:
|
case INDEX_op_setcond_i32:
|
||||||
return C_O1_I2(r, rZ, ri);
|
return C_O1_I2(r, rz, ri);
|
||||||
case INDEX_op_sub_i64:
|
case INDEX_op_sub_i64:
|
||||||
case INDEX_op_setcond_i64:
|
case INDEX_op_setcond_i64:
|
||||||
return C_O1_I2(r, rZ, rJ);
|
return C_O1_I2(r, rz, rJ);
|
||||||
|
|
||||||
case INDEX_op_mul_i32:
|
case INDEX_op_mul_i32:
|
||||||
case INDEX_op_mul_i64:
|
case INDEX_op_mul_i64:
|
||||||
@ -2367,11 +2351,11 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_rem_i64:
|
case INDEX_op_rem_i64:
|
||||||
case INDEX_op_remu_i32:
|
case INDEX_op_remu_i32:
|
||||||
case INDEX_op_remu_i64:
|
case INDEX_op_remu_i64:
|
||||||
return C_O1_I2(r, rZ, rZ);
|
return C_O1_I2(r, rz, rz);
|
||||||
|
|
||||||
case INDEX_op_movcond_i32:
|
case INDEX_op_movcond_i32:
|
||||||
case INDEX_op_movcond_i64:
|
case INDEX_op_movcond_i64:
|
||||||
return C_O1_I4(r, rZ, rJ, rZ, rZ);
|
return C_O1_I4(r, rz, rJ, rz, rz);
|
||||||
|
|
||||||
case INDEX_op_ld_vec:
|
case INDEX_op_ld_vec:
|
||||||
case INDEX_op_dupm_vec:
|
case INDEX_op_dupm_vec:
|
||||||
|
@ -85,4 +85,6 @@ typedef enum {
|
|||||||
TCG_VEC_TMP0 = TCG_REG_V23,
|
TCG_VEC_TMP0 = TCG_REG_V23,
|
||||||
} TCGReg;
|
} TCGReg;
|
||||||
|
|
||||||
|
#define TCG_REG_ZERO TCG_REG_ZERO
|
||||||
|
|
||||||
#endif /* LOONGARCH_TCG_TARGET_H */
|
#endif /* LOONGARCH_TCG_TARGET_H */
|
||||||
|
@ -10,24 +10,24 @@
|
|||||||
* tcg-target-con-str.h; the constraint combination is inclusive or.
|
* tcg-target-con-str.h; the constraint combination is inclusive or.
|
||||||
*/
|
*/
|
||||||
C_O0_I1(r)
|
C_O0_I1(r)
|
||||||
C_O0_I2(rZ, r)
|
C_O0_I2(rz, r)
|
||||||
C_O0_I2(rZ, rZ)
|
C_O0_I2(rz, rz)
|
||||||
C_O0_I3(rZ, r, r)
|
C_O0_I3(rz, r, r)
|
||||||
C_O0_I3(rZ, rZ, r)
|
C_O0_I3(rz, rz, r)
|
||||||
C_O0_I4(rZ, rZ, rZ, rZ)
|
C_O0_I4(rz, rz, rz, rz)
|
||||||
C_O0_I4(rZ, rZ, r, r)
|
C_O0_I4(rz, rz, r, r)
|
||||||
C_O1_I1(r, r)
|
C_O1_I1(r, r)
|
||||||
C_O1_I2(r, 0, rZ)
|
C_O1_I2(r, 0, rz)
|
||||||
C_O1_I2(r, r, r)
|
C_O1_I2(r, r, r)
|
||||||
C_O1_I2(r, r, ri)
|
C_O1_I2(r, r, ri)
|
||||||
C_O1_I2(r, r, rI)
|
C_O1_I2(r, r, rI)
|
||||||
C_O1_I2(r, r, rIK)
|
C_O1_I2(r, r, rIK)
|
||||||
C_O1_I2(r, r, rJ)
|
C_O1_I2(r, r, rJ)
|
||||||
C_O1_I2(r, r, rWZ)
|
C_O1_I2(r, r, rzW)
|
||||||
C_O1_I2(r, rZ, rN)
|
C_O1_I2(r, rz, rN)
|
||||||
C_O1_I2(r, rZ, rZ)
|
C_O1_I2(r, rz, rz)
|
||||||
C_O1_I4(r, rZ, rZ, rZ, 0)
|
C_O1_I4(r, rz, rz, rz, 0)
|
||||||
C_O1_I4(r, rZ, rZ, rZ, rZ)
|
C_O1_I4(r, rz, rz, rz, rz)
|
||||||
C_O2_I1(r, r, r)
|
C_O2_I1(r, r, r)
|
||||||
C_O2_I2(r, r, r, r)
|
C_O2_I2(r, r, r, r)
|
||||||
C_O2_I4(r, r, rZ, rZ, rN, rN)
|
C_O2_I4(r, r, rz, rz, rN, rN)
|
||||||
|
@ -19,4 +19,3 @@ CONST('J', TCG_CT_CONST_S16)
|
|||||||
CONST('K', TCG_CT_CONST_P2M1)
|
CONST('K', TCG_CT_CONST_P2M1)
|
||||||
CONST('N', TCG_CT_CONST_N16)
|
CONST('N', TCG_CT_CONST_N16)
|
||||||
CONST('W', TCG_CT_CONST_WSZ)
|
CONST('W', TCG_CT_CONST_WSZ)
|
||||||
CONST('Z', TCG_CT_CONST_ZERO)
|
|
||||||
|
@ -184,12 +184,11 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
|
|||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TCG_CT_CONST_ZERO 0x100
|
#define TCG_CT_CONST_U16 0x100 /* Unsigned 16-bit: 0 - 0xffff. */
|
||||||
#define TCG_CT_CONST_U16 0x200 /* Unsigned 16-bit: 0 - 0xffff. */
|
#define TCG_CT_CONST_S16 0x200 /* Signed 16-bit: -32768 - 32767 */
|
||||||
#define TCG_CT_CONST_S16 0x400 /* Signed 16-bit: -32768 - 32767 */
|
#define TCG_CT_CONST_P2M1 0x400 /* Power of 2 minus 1. */
|
||||||
#define TCG_CT_CONST_P2M1 0x800 /* Power of 2 minus 1. */
|
#define TCG_CT_CONST_N16 0x800 /* "Negatable" 16-bit: -32767 - 32767 */
|
||||||
#define TCG_CT_CONST_N16 0x1000 /* "Negatable" 16-bit: -32767 - 32767 */
|
#define TCG_CT_CONST_WSZ 0x1000 /* word size */
|
||||||
#define TCG_CT_CONST_WSZ 0x2000 /* word size */
|
|
||||||
|
|
||||||
#define ALL_GENERAL_REGS 0xffffffffu
|
#define ALL_GENERAL_REGS 0xffffffffu
|
||||||
|
|
||||||
@ -204,8 +203,6 @@ static bool tcg_target_const_match(int64_t val, int ct,
|
|||||||
{
|
{
|
||||||
if (ct & TCG_CT_CONST) {
|
if (ct & TCG_CT_CONST) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
|
|
||||||
return 1;
|
|
||||||
} else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
|
} else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
|
} else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
|
||||||
@ -1217,8 +1214,7 @@ bool tcg_target_has_memory_bswap(MemOp memop)
|
|||||||
* is required and fill in @h with the host address for the fast path.
|
* is required and fill in @h with the host address for the fast path.
|
||||||
*/
|
*/
|
||||||
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
||||||
TCGReg addrlo, TCGReg addrhi,
|
TCGReg addr, MemOpIdx oi, bool is_ld)
|
||||||
MemOpIdx oi, bool is_ld)
|
|
||||||
{
|
{
|
||||||
TCGType addr_type = s->addr_type;
|
TCGType addr_type = s->addr_type;
|
||||||
TCGLabelQemuLdst *ldst = NULL;
|
TCGLabelQemuLdst *ldst = NULL;
|
||||||
@ -1245,8 +1241,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addrlo;
|
ldst->addr_reg = addr;
|
||||||
ldst->addrhi_reg = addrhi;
|
|
||||||
|
|
||||||
/* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
|
/* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
|
||||||
tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_AREG0, mask_off);
|
tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_AREG0, mask_off);
|
||||||
@ -1254,29 +1249,26 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
|
|
||||||
/* Extract the TLB index from the address into TMP3. */
|
/* Extract the TLB index from the address into TMP3. */
|
||||||
if (TCG_TARGET_REG_BITS == 32 || addr_type == TCG_TYPE_I32) {
|
if (TCG_TARGET_REG_BITS == 32 || addr_type == TCG_TYPE_I32) {
|
||||||
tcg_out_opc_sa(s, OPC_SRL, TCG_TMP3, addrlo,
|
tcg_out_opc_sa(s, OPC_SRL, TCG_TMP3, addr,
|
||||||
s->page_bits - CPU_TLB_ENTRY_BITS);
|
s->page_bits - CPU_TLB_ENTRY_BITS);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_dsrl(s, TCG_TMP3, addrlo,
|
tcg_out_dsrl(s, TCG_TMP3, addr, s->page_bits - CPU_TLB_ENTRY_BITS);
|
||||||
s->page_bits - CPU_TLB_ENTRY_BITS);
|
|
||||||
}
|
}
|
||||||
tcg_out_opc_reg(s, OPC_AND, TCG_TMP3, TCG_TMP3, TCG_TMP0);
|
tcg_out_opc_reg(s, OPC_AND, TCG_TMP3, TCG_TMP3, TCG_TMP0);
|
||||||
|
|
||||||
/* Add the tlb_table pointer, creating the CPUTLBEntry address. */
|
/* Add the tlb_table pointer, creating the CPUTLBEntry address. */
|
||||||
tcg_out_opc_reg(s, ALIAS_PADD, TCG_TMP3, TCG_TMP3, TCG_TMP1);
|
tcg_out_opc_reg(s, ALIAS_PADD, TCG_TMP3, TCG_TMP3, TCG_TMP1);
|
||||||
|
|
||||||
if (TCG_TARGET_REG_BITS == 32 || addr_type == TCG_TYPE_I32) {
|
/* Load the tlb comparator. */
|
||||||
/* Load the (low half) tlb comparator. */
|
if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
|
||||||
tcg_out_ld(s, TCG_TYPE_I32, TCG_TMP0, TCG_TMP3,
|
tcg_out_ld(s, TCG_TYPE_I32, TCG_TMP0, TCG_TMP3,
|
||||||
cmp_off + HOST_BIG_ENDIAN * 4);
|
cmp_off + HOST_BIG_ENDIAN * 4);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_ld(s, TCG_TYPE_I64, TCG_TMP0, TCG_TMP3, cmp_off);
|
tcg_out_ld(s, TCG_TYPE_REG, TCG_TMP0, TCG_TMP3, cmp_off);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TCG_TARGET_REG_BITS == 64 || addr_type == TCG_TYPE_I32) {
|
/* Load the tlb addend for the fast path. */
|
||||||
/* Load the tlb addend for the fast path. */
|
tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP3, TCG_TMP3, add_off);
|
||||||
tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP3, TCG_TMP3, add_off);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mask the page bits, keeping the alignment bits to compare against.
|
* Mask the page bits, keeping the alignment bits to compare against.
|
||||||
@ -1288,48 +1280,35 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
tcg_out_opc_imm(s, (TCG_TARGET_REG_BITS == 32
|
tcg_out_opc_imm(s, (TCG_TARGET_REG_BITS == 32
|
||||||
|| addr_type == TCG_TYPE_I32
|
|| addr_type == TCG_TYPE_I32
|
||||||
? OPC_ADDIU : OPC_DADDIU),
|
? OPC_ADDIU : OPC_DADDIU),
|
||||||
TCG_TMP2, addrlo, s_mask - a_mask);
|
TCG_TMP2, addr, s_mask - a_mask);
|
||||||
tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, TCG_TMP2);
|
tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, TCG_TMP2);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, addrlo);
|
tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zero extend a 32-bit guest address for a 64-bit host. */
|
/* Zero extend a 32-bit guest address for a 64-bit host. */
|
||||||
if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
|
if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
|
||||||
tcg_out_ext32u(s, TCG_TMP2, addrlo);
|
tcg_out_ext32u(s, TCG_TMP2, addr);
|
||||||
addrlo = TCG_TMP2;
|
addr = TCG_TMP2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ldst->label_ptr[0] = s->code_ptr;
|
ldst->label_ptr[0] = s->code_ptr;
|
||||||
tcg_out_opc_br(s, OPC_BNE, TCG_TMP1, TCG_TMP0);
|
tcg_out_opc_br(s, OPC_BNE, TCG_TMP1, TCG_TMP0);
|
||||||
|
|
||||||
/* Load and test the high half tlb comparator. */
|
|
||||||
if (TCG_TARGET_REG_BITS == 32 && addr_type != TCG_TYPE_I32) {
|
|
||||||
/* delay slot */
|
|
||||||
tcg_out_ldst(s, OPC_LW, TCG_TMP0, TCG_TMP3, cmp_off + HI_OFF);
|
|
||||||
|
|
||||||
/* Load the tlb addend for the fast path. */
|
|
||||||
tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP3, TCG_TMP3, add_off);
|
|
||||||
|
|
||||||
ldst->label_ptr[1] = s->code_ptr;
|
|
||||||
tcg_out_opc_br(s, OPC_BNE, addrhi, TCG_TMP0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* delay slot */
|
/* delay slot */
|
||||||
base = TCG_TMP3;
|
base = TCG_TMP3;
|
||||||
tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_TMP3, addrlo);
|
tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_TMP3, addr);
|
||||||
} else {
|
} else {
|
||||||
if (a_mask && (use_mips32r6_instructions || a_bits != s_bits)) {
|
if (a_mask && (use_mips32r6_instructions || a_bits != s_bits)) {
|
||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
|
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addrlo;
|
ldst->addr_reg = addr;
|
||||||
ldst->addrhi_reg = addrhi;
|
|
||||||
|
|
||||||
/* We are expecting a_bits to max out at 7, much lower than ANDI. */
|
/* We are expecting a_bits to max out at 7, much lower than ANDI. */
|
||||||
tcg_debug_assert(a_bits < 16);
|
tcg_debug_assert(a_bits < 16);
|
||||||
tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, addrlo, a_mask);
|
tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, addr, a_mask);
|
||||||
|
|
||||||
ldst->label_ptr[0] = s->code_ptr;
|
ldst->label_ptr[0] = s->code_ptr;
|
||||||
if (use_mips32r6_instructions) {
|
if (use_mips32r6_instructions) {
|
||||||
@ -1340,7 +1319,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
base = addrlo;
|
base = addr;
|
||||||
if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
|
if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
|
||||||
tcg_out_ext32u(s, TCG_REG_A0, base);
|
tcg_out_ext32u(s, TCG_REG_A0, base);
|
||||||
base = TCG_REG_A0;
|
base = TCG_REG_A0;
|
||||||
@ -1460,14 +1439,13 @@ static void tcg_out_qemu_ld_unalign(TCGContext *s, TCGReg lo, TCGReg hi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
||||||
TCGReg addrlo, TCGReg addrhi,
|
TCGReg addr, MemOpIdx oi, TCGType data_type)
|
||||||
MemOpIdx oi, TCGType data_type)
|
|
||||||
{
|
{
|
||||||
MemOp opc = get_memop(oi);
|
MemOp opc = get_memop(oi);
|
||||||
TCGLabelQemuLdst *ldst;
|
TCGLabelQemuLdst *ldst;
|
||||||
HostAddress h;
|
HostAddress h;
|
||||||
|
|
||||||
ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, true);
|
ldst = prepare_host_addr(s, &h, addr, oi, true);
|
||||||
|
|
||||||
if (use_mips32r6_instructions || h.aa.align >= (opc & MO_SIZE)) {
|
if (use_mips32r6_instructions || h.aa.align >= (opc & MO_SIZE)) {
|
||||||
tcg_out_qemu_ld_direct(s, datalo, datahi, h.base, opc, data_type);
|
tcg_out_qemu_ld_direct(s, datalo, datahi, h.base, opc, data_type);
|
||||||
@ -1547,14 +1525,13 @@ static void tcg_out_qemu_st_unalign(TCGContext *s, TCGReg lo, TCGReg hi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_qemu_st(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
static void tcg_out_qemu_st(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
||||||
TCGReg addrlo, TCGReg addrhi,
|
TCGReg addr, MemOpIdx oi, TCGType data_type)
|
||||||
MemOpIdx oi, TCGType data_type)
|
|
||||||
{
|
{
|
||||||
MemOp opc = get_memop(oi);
|
MemOp opc = get_memop(oi);
|
||||||
TCGLabelQemuLdst *ldst;
|
TCGLabelQemuLdst *ldst;
|
||||||
HostAddress h;
|
HostAddress h;
|
||||||
|
|
||||||
ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, false);
|
ldst = prepare_host_addr(s, &h, addr, oi, false);
|
||||||
|
|
||||||
if (use_mips32r6_instructions || h.aa.align >= (opc & MO_SIZE)) {
|
if (use_mips32r6_instructions || h.aa.align >= (opc & MO_SIZE)) {
|
||||||
tcg_out_qemu_st_direct(s, datalo, datahi, h.base, opc);
|
tcg_out_qemu_st_direct(s, datalo, datahi, h.base, opc);
|
||||||
@ -1686,11 +1663,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||||||
TCGArg a0, a1, a2;
|
TCGArg a0, a1, a2;
|
||||||
int c2;
|
int c2;
|
||||||
|
|
||||||
/*
|
|
||||||
* Note that many operands use the constraint set "rZ".
|
|
||||||
* We make use of the fact that 0 is the ZERO register,
|
|
||||||
* and hence such cases need not check for const_args.
|
|
||||||
*/
|
|
||||||
a0 = args[0];
|
a0 = args[0];
|
||||||
a1 = args[1];
|
a1 = args[1];
|
||||||
a2 = args[2];
|
a2 = args[2];
|
||||||
@ -2095,51 +2067,25 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||||||
tcg_out_setcond2(s, args[5], a0, a1, a2, args[3], args[4]);
|
tcg_out_setcond2(s, args[5], a0, a1, a2, args[3], args[4]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
if (TCG_TARGET_REG_BITS == 32) {
|
tcg_out_qemu_ld(s, a0, 0, a1, a2, TCG_TYPE_I32);
|
||||||
tcg_out_qemu_ld(s, a0, 0, a1, a2, args[3], TCG_TYPE_I32);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* fall through */
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
|
||||||
tcg_out_qemu_ld(s, a0, 0, a1, 0, a2, TCG_TYPE_I32);
|
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
case INDEX_op_qemu_ld_i64:
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
if (TCG_TARGET_REG_BITS == 64) {
|
||||||
tcg_out_qemu_ld(s, a0, 0, a1, 0, a2, TCG_TYPE_I64);
|
tcg_out_qemu_ld(s, a0, 0, a1, a2, TCG_TYPE_I64);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_qemu_ld(s, a0, a1, a2, 0, args[3], TCG_TYPE_I64);
|
tcg_out_qemu_ld(s, a0, a1, a2, args[3], TCG_TYPE_I64);
|
||||||
}
|
|
||||||
break;
|
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
|
||||||
tcg_out_qemu_ld(s, a0, 0, a1, 0, a2, TCG_TYPE_I64);
|
|
||||||
} else {
|
|
||||||
tcg_out_qemu_ld(s, a0, a1, a2, args[3], args[4], TCG_TYPE_I64);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
if (TCG_TARGET_REG_BITS == 32) {
|
tcg_out_qemu_st(s, a0, 0, a1, a2, TCG_TYPE_I32);
|
||||||
tcg_out_qemu_st(s, a0, 0, a1, a2, args[3], TCG_TYPE_I32);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* fall through */
|
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
|
||||||
tcg_out_qemu_st(s, a0, 0, a1, 0, a2, TCG_TYPE_I32);
|
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
case INDEX_op_qemu_st_i64:
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
if (TCG_TARGET_REG_BITS == 64) {
|
||||||
tcg_out_qemu_st(s, a0, 0, a1, 0, a2, TCG_TYPE_I64);
|
tcg_out_qemu_st(s, a0, 0, a1, a2, TCG_TYPE_I64);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_qemu_st(s, a0, a1, a2, 0, args[3], TCG_TYPE_I64);
|
tcg_out_qemu_st(s, a0, a1, a2, args[3], TCG_TYPE_I64);
|
||||||
}
|
|
||||||
break;
|
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
|
||||||
tcg_out_qemu_st(s, a0, 0, a1, 0, a2, TCG_TYPE_I64);
|
|
||||||
} else {
|
|
||||||
tcg_out_qemu_st(s, a0, a1, a2, args[3], args[4], TCG_TYPE_I64);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2227,14 +2173,14 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_st16_i64:
|
case INDEX_op_st16_i64:
|
||||||
case INDEX_op_st32_i64:
|
case INDEX_op_st32_i64:
|
||||||
case INDEX_op_st_i64:
|
case INDEX_op_st_i64:
|
||||||
return C_O0_I2(rZ, r);
|
return C_O0_I2(rz, r);
|
||||||
|
|
||||||
case INDEX_op_add_i32:
|
case INDEX_op_add_i32:
|
||||||
case INDEX_op_add_i64:
|
case INDEX_op_add_i64:
|
||||||
return C_O1_I2(r, r, rJ);
|
return C_O1_I2(r, r, rJ);
|
||||||
case INDEX_op_sub_i32:
|
case INDEX_op_sub_i32:
|
||||||
case INDEX_op_sub_i64:
|
case INDEX_op_sub_i64:
|
||||||
return C_O1_I2(r, rZ, rN);
|
return C_O1_I2(r, rz, rN);
|
||||||
case INDEX_op_mul_i32:
|
case INDEX_op_mul_i32:
|
||||||
case INDEX_op_mulsh_i32:
|
case INDEX_op_mulsh_i32:
|
||||||
case INDEX_op_muluh_i32:
|
case INDEX_op_muluh_i32:
|
||||||
@ -2253,7 +2199,7 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_remu_i64:
|
case INDEX_op_remu_i64:
|
||||||
case INDEX_op_nor_i64:
|
case INDEX_op_nor_i64:
|
||||||
case INDEX_op_setcond_i64:
|
case INDEX_op_setcond_i64:
|
||||||
return C_O1_I2(r, rZ, rZ);
|
return C_O1_I2(r, rz, rz);
|
||||||
case INDEX_op_muls2_i32:
|
case INDEX_op_muls2_i32:
|
||||||
case INDEX_op_mulu2_i32:
|
case INDEX_op_mulu2_i32:
|
||||||
case INDEX_op_muls2_i64:
|
case INDEX_op_muls2_i64:
|
||||||
@ -2280,44 +2226,35 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
return C_O1_I2(r, r, ri);
|
return C_O1_I2(r, r, ri);
|
||||||
case INDEX_op_clz_i32:
|
case INDEX_op_clz_i32:
|
||||||
case INDEX_op_clz_i64:
|
case INDEX_op_clz_i64:
|
||||||
return C_O1_I2(r, r, rWZ);
|
return C_O1_I2(r, r, rzW);
|
||||||
|
|
||||||
case INDEX_op_deposit_i32:
|
case INDEX_op_deposit_i32:
|
||||||
case INDEX_op_deposit_i64:
|
case INDEX_op_deposit_i64:
|
||||||
return C_O1_I2(r, 0, rZ);
|
return C_O1_I2(r, 0, rz);
|
||||||
case INDEX_op_brcond_i32:
|
case INDEX_op_brcond_i32:
|
||||||
case INDEX_op_brcond_i64:
|
case INDEX_op_brcond_i64:
|
||||||
return C_O0_I2(rZ, rZ);
|
return C_O0_I2(rz, rz);
|
||||||
case INDEX_op_movcond_i32:
|
case INDEX_op_movcond_i32:
|
||||||
case INDEX_op_movcond_i64:
|
case INDEX_op_movcond_i64:
|
||||||
return (use_mips32r6_instructions
|
return (use_mips32r6_instructions
|
||||||
? C_O1_I4(r, rZ, rZ, rZ, rZ)
|
? C_O1_I4(r, rz, rz, rz, rz)
|
||||||
: C_O1_I4(r, rZ, rZ, rZ, 0));
|
: C_O1_I4(r, rz, rz, rz, 0));
|
||||||
case INDEX_op_add2_i32:
|
case INDEX_op_add2_i32:
|
||||||
case INDEX_op_sub2_i32:
|
case INDEX_op_sub2_i32:
|
||||||
return C_O2_I4(r, r, rZ, rZ, rN, rN);
|
return C_O2_I4(r, r, rz, rz, rN, rN);
|
||||||
case INDEX_op_setcond2_i32:
|
case INDEX_op_setcond2_i32:
|
||||||
return C_O1_I4(r, rZ, rZ, rZ, rZ);
|
return C_O1_I4(r, rz, rz, rz, rz);
|
||||||
case INDEX_op_brcond2_i32:
|
case INDEX_op_brcond2_i32:
|
||||||
return C_O0_I4(rZ, rZ, rZ, rZ);
|
return C_O0_I4(rz, rz, rz, rz);
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
return C_O1_I1(r, r);
|
return C_O1_I1(r, r);
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O1_I2(r, r, r);
|
return C_O0_I2(rz, r);
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
return C_O0_I2(rZ, r);
|
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(rZ, r) : C_O0_I3(rZ, r, r);
|
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I1(r, r, r);
|
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I1(r, r, r);
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
case INDEX_op_qemu_st_i64:
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I2(r, r, r, r);
|
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(rz, r) : C_O0_I3(rz, rz, r);
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(rZ, r) : C_O0_I3(rZ, rZ, r);
|
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
return (TCG_TARGET_REG_BITS == 64 ? C_O0_I2(rZ, r)
|
|
||||||
: C_O0_I4(rZ, rZ, r, r));
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return C_NotImplemented;
|
return C_NotImplemented;
|
||||||
|
@ -70,4 +70,6 @@ typedef enum {
|
|||||||
TCG_AREG0 = TCG_REG_S8,
|
TCG_AREG0 = TCG_REG_S8,
|
||||||
} TCGReg;
|
} TCGReg;
|
||||||
|
|
||||||
|
#define TCG_REG_ZERO TCG_REG_ZERO
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3011,29 +3011,22 @@ void tcg_optimize(TCGContext *s)
|
|||||||
CASE_OP_32_64_VEC(orc):
|
CASE_OP_32_64_VEC(orc):
|
||||||
done = fold_orc(&ctx, op);
|
done = fold_orc(&ctx, op);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
|
||||||
done = fold_qemu_ld_1reg(&ctx, op);
|
done = fold_qemu_ld_1reg(&ctx, op);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
if (TCG_TARGET_REG_BITS == 64) {
|
||||||
done = fold_qemu_ld_1reg(&ctx, op);
|
done = fold_qemu_ld_1reg(&ctx, op);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
QEMU_FALLTHROUGH;
|
QEMU_FALLTHROUGH;
|
||||||
case INDEX_op_qemu_ld_a32_i128:
|
case INDEX_op_qemu_ld_i128:
|
||||||
case INDEX_op_qemu_ld_a64_i128:
|
|
||||||
done = fold_qemu_ld_2reg(&ctx, op);
|
done = fold_qemu_ld_2reg(&ctx, op);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st8_a32_i32:
|
case INDEX_op_qemu_st8_i32:
|
||||||
case INDEX_op_qemu_st8_a64_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i64:
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st_i128:
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
case INDEX_op_qemu_st_a32_i128:
|
|
||||||
case INDEX_op_qemu_st_a64_i128:
|
|
||||||
done = fold_qemu_st(&ctx, op);
|
done = fold_qemu_st(&ctx, op);
|
||||||
break;
|
break;
|
||||||
CASE_OP_32_64(rem):
|
CASE_OP_32_64(rem):
|
||||||
|
@ -2438,8 +2438,7 @@ bool tcg_target_has_memory_bswap(MemOp memop)
|
|||||||
* is required and fill in @h with the host address for the fast path.
|
* is required and fill in @h with the host address for the fast path.
|
||||||
*/
|
*/
|
||||||
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
||||||
TCGReg addrlo, TCGReg addrhi,
|
TCGReg addr, MemOpIdx oi, bool is_ld)
|
||||||
MemOpIdx oi, bool is_ld)
|
|
||||||
{
|
{
|
||||||
TCGType addr_type = s->addr_type;
|
TCGType addr_type = s->addr_type;
|
||||||
TCGLabelQemuLdst *ldst = NULL;
|
TCGLabelQemuLdst *ldst = NULL;
|
||||||
@ -2474,8 +2473,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addrlo;
|
ldst->addr_reg = addr;
|
||||||
ldst->addrhi_reg = addrhi;
|
|
||||||
|
|
||||||
/* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
|
/* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
|
||||||
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, mask_off);
|
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, mask_off);
|
||||||
@ -2483,36 +2481,25 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
|
|
||||||
/* Extract the page index, shifted into place for tlb index. */
|
/* Extract the page index, shifted into place for tlb index. */
|
||||||
if (TCG_TARGET_REG_BITS == 32) {
|
if (TCG_TARGET_REG_BITS == 32) {
|
||||||
tcg_out_shri32(s, TCG_REG_R0, addrlo,
|
tcg_out_shri32(s, TCG_REG_R0, addr,
|
||||||
s->page_bits - CPU_TLB_ENTRY_BITS);
|
s->page_bits - CPU_TLB_ENTRY_BITS);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_shri64(s, TCG_REG_R0, addrlo,
|
tcg_out_shri64(s, TCG_REG_R0, addr,
|
||||||
s->page_bits - CPU_TLB_ENTRY_BITS);
|
s->page_bits - CPU_TLB_ENTRY_BITS);
|
||||||
}
|
}
|
||||||
tcg_out32(s, AND | SAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_R0));
|
tcg_out32(s, AND | SAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_R0));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load the (low part) TLB comparator into TMP2.
|
* Load the TLB comparator into TMP2.
|
||||||
* For 64-bit host, always load the entire 64-bit slot for simplicity.
|
* For 64-bit host, always load the entire 64-bit slot for simplicity.
|
||||||
* We will ignore the high bits with tcg_out_cmp(..., addr_type).
|
* We will ignore the high bits with tcg_out_cmp(..., addr_type).
|
||||||
*/
|
*/
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
if (cmp_off == 0) {
|
||||||
if (cmp_off == 0) {
|
tcg_out32(s, (TCG_TARGET_REG_BITS == 64 ? LDUX : LWZUX)
|
||||||
tcg_out32(s, LDUX | TAB(TCG_REG_TMP2,
|
| TAB(TCG_REG_TMP2, TCG_REG_TMP1, TCG_REG_TMP2));
|
||||||
TCG_REG_TMP1, TCG_REG_TMP2));
|
|
||||||
} else {
|
|
||||||
tcg_out32(s, ADD | TAB(TCG_REG_TMP1,
|
|
||||||
TCG_REG_TMP1, TCG_REG_TMP2));
|
|
||||||
tcg_out_ld(s, TCG_TYPE_I64, TCG_REG_TMP2,
|
|
||||||
TCG_REG_TMP1, cmp_off);
|
|
||||||
}
|
|
||||||
} else if (cmp_off == 0 && !HOST_BIG_ENDIAN) {
|
|
||||||
tcg_out32(s, LWZUX | TAB(TCG_REG_TMP2,
|
|
||||||
TCG_REG_TMP1, TCG_REG_TMP2));
|
|
||||||
} else {
|
} else {
|
||||||
tcg_out32(s, ADD | TAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_TMP2));
|
tcg_out32(s, ADD | TAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_TMP2));
|
||||||
tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP2, TCG_REG_TMP1,
|
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_REG_TMP1, cmp_off);
|
||||||
cmp_off + 4 * HOST_BIG_ENDIAN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2534,10 +2521,10 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
if (a_bits < s_bits) {
|
if (a_bits < s_bits) {
|
||||||
a_bits = s_bits;
|
a_bits = s_bits;
|
||||||
}
|
}
|
||||||
tcg_out_rlw(s, RLWINM, TCG_REG_R0, addrlo, 0,
|
tcg_out_rlw(s, RLWINM, TCG_REG_R0, addr, 0,
|
||||||
(32 - a_bits) & 31, 31 - s->page_bits);
|
(32 - a_bits) & 31, 31 - s->page_bits);
|
||||||
} else {
|
} else {
|
||||||
TCGReg t = addrlo;
|
TCGReg t = addr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the access is unaligned, we need to make sure we fail if we
|
* If the access is unaligned, we need to make sure we fail if we
|
||||||
@ -2566,30 +2553,8 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TCG_TARGET_REG_BITS == 32 && addr_type != TCG_TYPE_I32) {
|
/* Full comparison into cr0. */
|
||||||
/* Low part comparison into cr7. */
|
tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP2, 0, 0, addr_type);
|
||||||
tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP2,
|
|
||||||
0, 7, TCG_TYPE_I32);
|
|
||||||
|
|
||||||
/* Load the high part TLB comparator into TMP2. */
|
|
||||||
tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP2, TCG_REG_TMP1,
|
|
||||||
cmp_off + 4 * !HOST_BIG_ENDIAN);
|
|
||||||
|
|
||||||
/* Load addend, deferred for this case. */
|
|
||||||
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_REG_TMP1,
|
|
||||||
offsetof(CPUTLBEntry, addend));
|
|
||||||
|
|
||||||
/* High part comparison into cr6. */
|
|
||||||
tcg_out_cmp(s, TCG_COND_EQ, addrhi, TCG_REG_TMP2,
|
|
||||||
0, 6, TCG_TYPE_I32);
|
|
||||||
|
|
||||||
/* Combine comparisons into cr0. */
|
|
||||||
tcg_out32(s, CRAND | BT(0, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
|
|
||||||
} else {
|
|
||||||
/* Full comparison into cr0. */
|
|
||||||
tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP2,
|
|
||||||
0, 0, addr_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load a pointer into the current opcode w/conditional branch-link. */
|
/* Load a pointer into the current opcode w/conditional branch-link. */
|
||||||
ldst->label_ptr[0] = s->code_ptr;
|
ldst->label_ptr[0] = s->code_ptr;
|
||||||
@ -2601,12 +2566,11 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addrlo;
|
ldst->addr_reg = addr;
|
||||||
ldst->addrhi_reg = addrhi;
|
|
||||||
|
|
||||||
/* We are expecting a_bits to max out at 7, much lower than ANDI. */
|
/* We are expecting a_bits to max out at 7, much lower than ANDI. */
|
||||||
tcg_debug_assert(a_bits < 16);
|
tcg_debug_assert(a_bits < 16);
|
||||||
tcg_out32(s, ANDI | SAI(addrlo, TCG_REG_R0, (1 << a_bits) - 1));
|
tcg_out32(s, ANDI | SAI(addr, TCG_REG_R0, (1 << a_bits) - 1));
|
||||||
|
|
||||||
ldst->label_ptr[0] = s->code_ptr;
|
ldst->label_ptr[0] = s->code_ptr;
|
||||||
tcg_out32(s, BC | BI(0, CR_EQ) | BO_COND_FALSE | LK);
|
tcg_out32(s, BC | BI(0, CR_EQ) | BO_COND_FALSE | LK);
|
||||||
@ -2617,24 +2581,23 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
|
|
||||||
if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
|
if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
|
||||||
/* Zero-extend the guest address for use in the host address. */
|
/* Zero-extend the guest address for use in the host address. */
|
||||||
tcg_out_ext32u(s, TCG_REG_TMP2, addrlo);
|
tcg_out_ext32u(s, TCG_REG_TMP2, addr);
|
||||||
h->index = TCG_REG_TMP2;
|
h->index = TCG_REG_TMP2;
|
||||||
} else {
|
} else {
|
||||||
h->index = addrlo;
|
h->index = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ldst;
|
return ldst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
||||||
TCGReg addrlo, TCGReg addrhi,
|
TCGReg addr, MemOpIdx oi, TCGType data_type)
|
||||||
MemOpIdx oi, TCGType data_type)
|
|
||||||
{
|
{
|
||||||
MemOp opc = get_memop(oi);
|
MemOp opc = get_memop(oi);
|
||||||
TCGLabelQemuLdst *ldst;
|
TCGLabelQemuLdst *ldst;
|
||||||
HostAddress h;
|
HostAddress h;
|
||||||
|
|
||||||
ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, true);
|
ldst = prepare_host_addr(s, &h, addr, oi, true);
|
||||||
|
|
||||||
if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
|
if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
|
||||||
if (opc & MO_BSWAP) {
|
if (opc & MO_BSWAP) {
|
||||||
@ -2678,14 +2641,13 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_qemu_st(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
static void tcg_out_qemu_st(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
||||||
TCGReg addrlo, TCGReg addrhi,
|
TCGReg addr, MemOpIdx oi, TCGType data_type)
|
||||||
MemOpIdx oi, TCGType data_type)
|
|
||||||
{
|
{
|
||||||
MemOp opc = get_memop(oi);
|
MemOp opc = get_memop(oi);
|
||||||
TCGLabelQemuLdst *ldst;
|
TCGLabelQemuLdst *ldst;
|
||||||
HostAddress h;
|
HostAddress h;
|
||||||
|
|
||||||
ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, false);
|
ldst = prepare_host_addr(s, &h, addr, oi, false);
|
||||||
|
|
||||||
if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
|
if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
|
||||||
if (opc & MO_BSWAP) {
|
if (opc & MO_BSWAP) {
|
||||||
@ -2729,7 +2691,7 @@ static void tcg_out_qemu_ldst_i128(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
|||||||
uint32_t insn;
|
uint32_t insn;
|
||||||
TCGReg index;
|
TCGReg index;
|
||||||
|
|
||||||
ldst = prepare_host_addr(s, &h, addr_reg, -1, oi, is_ld);
|
ldst = prepare_host_addr(s, &h, addr_reg, oi, is_ld);
|
||||||
|
|
||||||
/* Compose the final address, as LQ/STQ have no indexing. */
|
/* Compose the final address, as LQ/STQ have no indexing. */
|
||||||
index = h.index;
|
index = h.index;
|
||||||
@ -3308,70 +3270,34 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||||||
tcg_out32(s, MODUD | TAB(args[0], args[1], args[2]));
|
tcg_out32(s, MODUD | TAB(args[0], args[1], args[2]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
if (TCG_TARGET_REG_BITS == 32) {
|
tcg_out_qemu_ld(s, args[0], -1, args[1], args[2], TCG_TYPE_I32);
|
||||||
tcg_out_qemu_ld(s, args[0], -1, args[1], args[2],
|
|
||||||
args[3], TCG_TYPE_I32);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* fall through */
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
|
||||||
tcg_out_qemu_ld(s, args[0], -1, args[1], -1, args[2], TCG_TYPE_I32);
|
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
case INDEX_op_qemu_ld_i64:
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
if (TCG_TARGET_REG_BITS == 64) {
|
||||||
tcg_out_qemu_ld(s, args[0], -1, args[1], -1,
|
tcg_out_qemu_ld(s, args[0], -1, args[1], args[2], TCG_TYPE_I64);
|
||||||
args[2], TCG_TYPE_I64);
|
|
||||||
} else {
|
} else {
|
||||||
tcg_out_qemu_ld(s, args[0], args[1], args[2], -1,
|
tcg_out_qemu_ld(s, args[0], args[1], args[2],
|
||||||
args[3], TCG_TYPE_I64);
|
args[3], TCG_TYPE_I64);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
case INDEX_op_qemu_ld_i128:
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
|
||||||
tcg_out_qemu_ld(s, args[0], -1, args[1], -1,
|
|
||||||
args[2], TCG_TYPE_I64);
|
|
||||||
} else {
|
|
||||||
tcg_out_qemu_ld(s, args[0], args[1], args[2], args[3],
|
|
||||||
args[4], TCG_TYPE_I64);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case INDEX_op_qemu_ld_a32_i128:
|
|
||||||
case INDEX_op_qemu_ld_a64_i128:
|
|
||||||
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
||||||
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], true);
|
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
if (TCG_TARGET_REG_BITS == 32) {
|
tcg_out_qemu_st(s, args[0], -1, args[1], args[2], TCG_TYPE_I32);
|
||||||
tcg_out_qemu_st(s, args[0], -1, args[1], args[2],
|
|
||||||
args[3], TCG_TYPE_I32);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* fall through */
|
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
|
||||||
tcg_out_qemu_st(s, args[0], -1, args[1], -1, args[2], TCG_TYPE_I32);
|
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
case INDEX_op_qemu_st_i64:
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
if (TCG_TARGET_REG_BITS == 64) {
|
||||||
tcg_out_qemu_st(s, args[0], -1, args[1], -1,
|
tcg_out_qemu_st(s, args[0], -1, args[1], args[2], TCG_TYPE_I64);
|
||||||
args[2], TCG_TYPE_I64);
|
|
||||||
} else {
|
} else {
|
||||||
tcg_out_qemu_st(s, args[0], args[1], args[2], -1,
|
tcg_out_qemu_st(s, args[0], args[1], args[2],
|
||||||
args[3], TCG_TYPE_I64);
|
args[3], TCG_TYPE_I64);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
case INDEX_op_qemu_st_i128:
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
|
||||||
tcg_out_qemu_st(s, args[0], -1, args[1], -1,
|
|
||||||
args[2], TCG_TYPE_I64);
|
|
||||||
} else {
|
|
||||||
tcg_out_qemu_st(s, args[0], args[1], args[2], args[3],
|
|
||||||
args[4], TCG_TYPE_I64);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case INDEX_op_qemu_st_a32_i128:
|
|
||||||
case INDEX_op_qemu_st_a64_i128:
|
|
||||||
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
||||||
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], false);
|
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], false);
|
||||||
break;
|
break;
|
||||||
@ -4306,29 +4232,19 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_sub2_i32:
|
case INDEX_op_sub2_i32:
|
||||||
return C_O2_I4(r, r, rI, rZM, r, r);
|
return C_O2_I4(r, r, rI, rZM, r, r);
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
return C_O1_I1(r, r);
|
return C_O1_I1(r, r);
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O1_I2(r, r, r);
|
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I1(r, r, r);
|
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I1(r, r, r);
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I2(r, r, r, r);
|
|
||||||
|
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
return C_O0_I2(r, r);
|
return C_O0_I2(r, r);
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st_i64:
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I3(r, r, r);
|
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I3(r, r, r);
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I3(r, r, r);
|
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I4(r, r, r, r);
|
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i128:
|
case INDEX_op_qemu_ld_i128:
|
||||||
case INDEX_op_qemu_ld_a64_i128:
|
|
||||||
return C_N1O1_I1(o, m, r);
|
return C_N1O1_I1(o, m, r);
|
||||||
case INDEX_op_qemu_st_a32_i128:
|
case INDEX_op_qemu_st_i128:
|
||||||
case INDEX_op_qemu_st_a64_i128:
|
|
||||||
return C_O0_I3(o, m, r);
|
return C_O0_I3(o, m, r);
|
||||||
|
|
||||||
case INDEX_op_add_vec:
|
case INDEX_op_add_vec:
|
||||||
|
@ -10,17 +10,17 @@
|
|||||||
* tcg-target-con-str.h; the constraint combination is inclusive or.
|
* tcg-target-con-str.h; the constraint combination is inclusive or.
|
||||||
*/
|
*/
|
||||||
C_O0_I1(r)
|
C_O0_I1(r)
|
||||||
C_O0_I2(rZ, r)
|
C_O0_I2(rz, r)
|
||||||
C_O0_I2(rZ, rZ)
|
C_O0_I2(rz, rz)
|
||||||
C_O1_I1(r, r)
|
C_O1_I1(r, r)
|
||||||
C_O1_I2(r, r, ri)
|
C_O1_I2(r, r, ri)
|
||||||
C_O1_I2(r, r, rI)
|
C_O1_I2(r, r, rI)
|
||||||
C_O1_I2(r, r, rJ)
|
C_O1_I2(r, r, rJ)
|
||||||
C_O1_I2(r, rZ, rN)
|
C_O1_I2(r, rz, rN)
|
||||||
C_O1_I2(r, rZ, rZ)
|
C_O1_I2(r, rz, rz)
|
||||||
C_N1_I2(r, r, rM)
|
C_N1_I2(r, r, rM)
|
||||||
C_O1_I4(r, r, rI, rM, rM)
|
C_O1_I4(r, r, rI, rM, rM)
|
||||||
C_O2_I4(r, r, rZ, rZ, rM, rM)
|
C_O2_I4(r, r, rz, rz, rM, rM)
|
||||||
C_O0_I2(v, r)
|
C_O0_I2(v, r)
|
||||||
C_O1_I1(v, r)
|
C_O1_I1(v, r)
|
||||||
C_O1_I1(v, v)
|
C_O1_I1(v, v)
|
||||||
|
@ -21,4 +21,3 @@ CONST('K', TCG_CT_CONST_S5)
|
|||||||
CONST('L', TCG_CT_CONST_CMP_VI)
|
CONST('L', TCG_CT_CONST_CMP_VI)
|
||||||
CONST('N', TCG_CT_CONST_N12)
|
CONST('N', TCG_CT_CONST_N12)
|
||||||
CONST('M', TCG_CT_CONST_M12)
|
CONST('M', TCG_CT_CONST_M12)
|
||||||
CONST('Z', TCG_CT_CONST_ZERO)
|
|
||||||
|
@ -37,8 +37,6 @@
|
|||||||
#define TCG_TARGET_HAS_clz_i32 (cpuinfo & CPUINFO_ZBB)
|
#define TCG_TARGET_HAS_clz_i32 (cpuinfo & CPUINFO_ZBB)
|
||||||
#define TCG_TARGET_HAS_ctz_i32 (cpuinfo & CPUINFO_ZBB)
|
#define TCG_TARGET_HAS_ctz_i32 (cpuinfo & CPUINFO_ZBB)
|
||||||
#define TCG_TARGET_HAS_ctpop_i32 (cpuinfo & CPUINFO_ZBB)
|
#define TCG_TARGET_HAS_ctpop_i32 (cpuinfo & CPUINFO_ZBB)
|
||||||
#define TCG_TARGET_HAS_brcond2 1
|
|
||||||
#define TCG_TARGET_HAS_setcond2 1
|
|
||||||
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
||||||
|
|
||||||
#define TCG_TARGET_HAS_negsetcond_i64 1
|
#define TCG_TARGET_HAS_negsetcond_i64 1
|
||||||
|
@ -112,13 +112,12 @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
|
|||||||
return TCG_REG_A0 + slot;
|
return TCG_REG_A0 + slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TCG_CT_CONST_ZERO 0x100
|
#define TCG_CT_CONST_S12 0x100
|
||||||
#define TCG_CT_CONST_S12 0x200
|
#define TCG_CT_CONST_N12 0x200
|
||||||
#define TCG_CT_CONST_N12 0x400
|
#define TCG_CT_CONST_M12 0x400
|
||||||
#define TCG_CT_CONST_M12 0x800
|
#define TCG_CT_CONST_J12 0x800
|
||||||
#define TCG_CT_CONST_J12 0x1000
|
#define TCG_CT_CONST_S5 0x1000
|
||||||
#define TCG_CT_CONST_S5 0x2000
|
#define TCG_CT_CONST_CMP_VI 0x2000
|
||||||
#define TCG_CT_CONST_CMP_VI 0x4000
|
|
||||||
|
|
||||||
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
|
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
|
||||||
#define ALL_VECTOR_REGS MAKE_64BIT_MASK(32, 32)
|
#define ALL_VECTOR_REGS MAKE_64BIT_MASK(32, 32)
|
||||||
@ -391,9 +390,6 @@ static bool tcg_target_const_match(int64_t val, int ct,
|
|||||||
if (ct & TCG_CT_CONST) {
|
if (ct & TCG_CT_CONST) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (type >= TCG_TYPE_V64) {
|
if (type >= TCG_TYPE_V64) {
|
||||||
/* Val is replicated by VECE; extract the highest element. */
|
/* Val is replicated by VECE; extract the highest element. */
|
||||||
val >>= (-8 << vece) & 63;
|
val >>= (-8 << vece) & 63;
|
||||||
@ -1727,7 +1723,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
|
|||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addr_reg;
|
ldst->addr_reg = addr_reg;
|
||||||
|
|
||||||
init_setting_vtype(s);
|
init_setting_vtype(s);
|
||||||
|
|
||||||
@ -1790,7 +1786,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
|
|||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addr_reg;
|
ldst->addr_reg = addr_reg;
|
||||||
|
|
||||||
init_setting_vtype(s);
|
init_setting_vtype(s);
|
||||||
|
|
||||||
@ -2309,20 +2305,16 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||||||
args[3], const_args[3], args[4], const_args[4]);
|
args[3], const_args[3], args[4], const_args[4]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
|
||||||
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
|
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I64);
|
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I64);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
|
||||||
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I32);
|
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I32);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
case INDEX_op_qemu_st_i64:
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I64);
|
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I64);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2685,7 +2677,7 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_st16_i64:
|
case INDEX_op_st16_i64:
|
||||||
case INDEX_op_st32_i64:
|
case INDEX_op_st32_i64:
|
||||||
case INDEX_op_st_i64:
|
case INDEX_op_st_i64:
|
||||||
return C_O0_I2(rZ, r);
|
return C_O0_I2(rz, r);
|
||||||
|
|
||||||
case INDEX_op_add_i32:
|
case INDEX_op_add_i32:
|
||||||
case INDEX_op_and_i32:
|
case INDEX_op_and_i32:
|
||||||
@ -2711,7 +2703,7 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
|
|
||||||
case INDEX_op_sub_i32:
|
case INDEX_op_sub_i32:
|
||||||
case INDEX_op_sub_i64:
|
case INDEX_op_sub_i64:
|
||||||
return C_O1_I2(r, rZ, rN);
|
return C_O1_I2(r, rz, rN);
|
||||||
|
|
||||||
case INDEX_op_mul_i32:
|
case INDEX_op_mul_i32:
|
||||||
case INDEX_op_mulsh_i32:
|
case INDEX_op_mulsh_i32:
|
||||||
@ -2727,7 +2719,7 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_divu_i64:
|
case INDEX_op_divu_i64:
|
||||||
case INDEX_op_rem_i64:
|
case INDEX_op_rem_i64:
|
||||||
case INDEX_op_remu_i64:
|
case INDEX_op_remu_i64:
|
||||||
return C_O1_I2(r, rZ, rZ);
|
return C_O1_I2(r, rz, rz);
|
||||||
|
|
||||||
case INDEX_op_shl_i32:
|
case INDEX_op_shl_i32:
|
||||||
case INDEX_op_shr_i32:
|
case INDEX_op_shr_i32:
|
||||||
@ -2749,7 +2741,7 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
|
|
||||||
case INDEX_op_brcond_i32:
|
case INDEX_op_brcond_i32:
|
||||||
case INDEX_op_brcond_i64:
|
case INDEX_op_brcond_i64:
|
||||||
return C_O0_I2(rZ, rZ);
|
return C_O0_I2(rz, rz);
|
||||||
|
|
||||||
case INDEX_op_movcond_i32:
|
case INDEX_op_movcond_i32:
|
||||||
case INDEX_op_movcond_i64:
|
case INDEX_op_movcond_i64:
|
||||||
@ -2759,18 +2751,14 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_add2_i64:
|
case INDEX_op_add2_i64:
|
||||||
case INDEX_op_sub2_i32:
|
case INDEX_op_sub2_i32:
|
||||||
case INDEX_op_sub2_i64:
|
case INDEX_op_sub2_i64:
|
||||||
return C_O2_I4(r, r, rZ, rZ, rM, rM);
|
return C_O2_I4(r, r, rz, rz, rM, rM);
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
return C_O1_I1(r, r);
|
return C_O1_I1(r, r);
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st_i64:
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
return C_O0_I2(rz, r);
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
return C_O0_I2(rZ, r);
|
|
||||||
|
|
||||||
case INDEX_op_st_vec:
|
case INDEX_op_st_vec:
|
||||||
return C_O0_I2(v, r);
|
return C_O0_I2(v, r);
|
||||||
|
@ -57,4 +57,6 @@ typedef enum {
|
|||||||
TCG_REG_TMP2 = TCG_REG_T4,
|
TCG_REG_TMP2 = TCG_REG_T4,
|
||||||
} TCGReg;
|
} TCGReg;
|
||||||
|
|
||||||
|
#define TCG_REG_ZERO TCG_REG_ZERO
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1920,7 +1920,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addr_reg;
|
ldst->addr_reg = addr_reg;
|
||||||
|
|
||||||
tcg_out_sh64(s, RSY_SRLG, TCG_TMP0, addr_reg, TCG_REG_NONE,
|
tcg_out_sh64(s, RSY_SRLG, TCG_TMP0, addr_reg, TCG_REG_NONE,
|
||||||
s->page_bits - CPU_TLB_ENTRY_BITS);
|
s->page_bits - CPU_TLB_ENTRY_BITS);
|
||||||
@ -1974,7 +1974,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addr_reg;
|
ldst->addr_reg = addr_reg;
|
||||||
|
|
||||||
tcg_debug_assert(a_mask <= 0xffff);
|
tcg_debug_assert(a_mask <= 0xffff);
|
||||||
tcg_out_insn(s, RI, TMLL, addr_reg, a_mask);
|
tcg_out_insn(s, RI, TMLL, addr_reg, a_mask);
|
||||||
@ -2455,28 +2455,22 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||||||
args[2], const_args[2], args[3], const_args[3], args[4]);
|
args[2], const_args[2], args[3], const_args[3], args[4]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
|
||||||
tcg_out_qemu_ld(s, args[0], args[1], args[2], TCG_TYPE_I32);
|
tcg_out_qemu_ld(s, args[0], args[1], args[2], TCG_TYPE_I32);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
tcg_out_qemu_ld(s, args[0], args[1], args[2], TCG_TYPE_I64);
|
tcg_out_qemu_ld(s, args[0], args[1], args[2], TCG_TYPE_I64);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
|
||||||
tcg_out_qemu_st(s, args[0], args[1], args[2], TCG_TYPE_I32);
|
tcg_out_qemu_st(s, args[0], args[1], args[2], TCG_TYPE_I32);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
case INDEX_op_qemu_st_i64:
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
tcg_out_qemu_st(s, args[0], args[1], args[2], TCG_TYPE_I64);
|
tcg_out_qemu_st(s, args[0], args[1], args[2], TCG_TYPE_I64);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a32_i128:
|
case INDEX_op_qemu_ld_i128:
|
||||||
case INDEX_op_qemu_ld_a64_i128:
|
|
||||||
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], true);
|
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], true);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i128:
|
case INDEX_op_qemu_st_i128:
|
||||||
case INDEX_op_qemu_st_a64_i128:
|
|
||||||
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], false);
|
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3366,21 +3360,15 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_ctpop_i64:
|
case INDEX_op_ctpop_i64:
|
||||||
return C_O1_I1(r, r);
|
return C_O1_I1(r, r);
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
return C_O1_I1(r, r);
|
return C_O1_I1(r, r);
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
case INDEX_op_qemu_st_i64:
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
case INDEX_op_qemu_st_i32:
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
|
||||||
return C_O0_I2(r, r);
|
return C_O0_I2(r, r);
|
||||||
case INDEX_op_qemu_ld_a32_i128:
|
case INDEX_op_qemu_ld_i128:
|
||||||
case INDEX_op_qemu_ld_a64_i128:
|
|
||||||
return C_O2_I1(o, m, r);
|
return C_O2_I1(o, m, r);
|
||||||
case INDEX_op_qemu_st_a32_i128:
|
case INDEX_op_qemu_st_i128:
|
||||||
case INDEX_op_qemu_st_a64_i128:
|
|
||||||
return C_O0_I3(o, m, r);
|
return C_O0_I3(o, m, r);
|
||||||
|
|
||||||
case INDEX_op_deposit_i32:
|
case INDEX_op_deposit_i32:
|
||||||
|
@ -10,11 +10,11 @@
|
|||||||
* tcg-target-con-str.h; the constraint combination is inclusive or.
|
* tcg-target-con-str.h; the constraint combination is inclusive or.
|
||||||
*/
|
*/
|
||||||
C_O0_I1(r)
|
C_O0_I1(r)
|
||||||
C_O0_I2(rZ, r)
|
C_O0_I2(rz, r)
|
||||||
C_O0_I2(rZ, rJ)
|
C_O0_I2(rz, rJ)
|
||||||
C_O1_I1(r, r)
|
C_O1_I1(r, r)
|
||||||
C_O1_I2(r, r, r)
|
C_O1_I2(r, r, r)
|
||||||
C_O1_I2(r, rZ, rJ)
|
C_O1_I2(r, rz, rJ)
|
||||||
C_O1_I4(r, rZ, rJ, rI, 0)
|
C_O1_I4(r, rz, rJ, rI, 0)
|
||||||
C_O2_I2(r, r, rZ, rJ)
|
C_O2_I2(r, r, rz, rJ)
|
||||||
C_O2_I4(r, r, rZ, rZ, rJ, rJ)
|
C_O2_I4(r, r, rz, rz, rJ, rJ)
|
||||||
|
@ -16,4 +16,3 @@ REGS('r', ALL_GENERAL_REGS)
|
|||||||
*/
|
*/
|
||||||
CONST('I', TCG_CT_CONST_S11)
|
CONST('I', TCG_CT_CONST_S11)
|
||||||
CONST('J', TCG_CT_CONST_S13)
|
CONST('J', TCG_CT_CONST_S13)
|
||||||
CONST('Z', TCG_CT_CONST_ZERO)
|
|
||||||
|
@ -76,7 +76,6 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
|
|||||||
|
|
||||||
#define TCG_CT_CONST_S11 0x100
|
#define TCG_CT_CONST_S11 0x100
|
||||||
#define TCG_CT_CONST_S13 0x200
|
#define TCG_CT_CONST_S13 0x200
|
||||||
#define TCG_CT_CONST_ZERO 0x400
|
|
||||||
|
|
||||||
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
|
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
|
||||||
|
|
||||||
@ -340,9 +339,7 @@ static bool tcg_target_const_match(int64_t val, int ct,
|
|||||||
val = (int32_t)val;
|
val = (int32_t)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
|
if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) {
|
||||||
return 1;
|
|
||||||
} else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) {
|
|
||||||
return 1;
|
return 1;
|
||||||
} else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13)) {
|
} else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13)) {
|
||||||
return 1;
|
return 1;
|
||||||
@ -1127,7 +1124,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addr_reg;
|
ldst->addr_reg = addr_reg;
|
||||||
ldst->label_ptr[0] = s->code_ptr;
|
ldst->label_ptr[0] = s->code_ptr;
|
||||||
|
|
||||||
/* bne,pn %[xi]cc, label0 */
|
/* bne,pn %[xi]cc, label0 */
|
||||||
@ -1147,7 +1144,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
ldst = new_ldst_label(s);
|
ldst = new_ldst_label(s);
|
||||||
ldst->is_ld = is_ld;
|
ldst->is_ld = is_ld;
|
||||||
ldst->oi = oi;
|
ldst->oi = oi;
|
||||||
ldst->addrlo_reg = addr_reg;
|
ldst->addr_reg = addr_reg;
|
||||||
ldst->label_ptr[0] = s->code_ptr;
|
ldst->label_ptr[0] = s->code_ptr;
|
||||||
|
|
||||||
/* bne,pn %icc, label0 */
|
/* bne,pn %icc, label0 */
|
||||||
@ -1426,20 +1423,16 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||||||
tcg_out_arithi(s, a1, a0, 32, SHIFT_SRLX);
|
tcg_out_arithi(s, a1, a0, 32, SHIFT_SRLX);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
|
||||||
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
|
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I64);
|
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I64);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
|
||||||
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I32);
|
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I32);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
case INDEX_op_qemu_st_i64:
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I64);
|
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I64);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1570,10 +1563,8 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_extu_i32_i64:
|
case INDEX_op_extu_i32_i64:
|
||||||
case INDEX_op_extract_i64:
|
case INDEX_op_extract_i64:
|
||||||
case INDEX_op_sextract_i64:
|
case INDEX_op_sextract_i64:
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
return C_O1_I1(r, r);
|
return C_O1_I1(r, r);
|
||||||
|
|
||||||
case INDEX_op_st8_i32:
|
case INDEX_op_st8_i32:
|
||||||
@ -1583,11 +1574,9 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_st_i32:
|
case INDEX_op_st_i32:
|
||||||
case INDEX_op_st32_i64:
|
case INDEX_op_st32_i64:
|
||||||
case INDEX_op_st_i64:
|
case INDEX_op_st_i64:
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st_i64:
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
return C_O0_I2(rz, r);
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
return C_O0_I2(rZ, r);
|
|
||||||
|
|
||||||
case INDEX_op_add_i32:
|
case INDEX_op_add_i32:
|
||||||
case INDEX_op_add_i64:
|
case INDEX_op_add_i64:
|
||||||
@ -1619,22 +1608,22 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_setcond_i64:
|
case INDEX_op_setcond_i64:
|
||||||
case INDEX_op_negsetcond_i32:
|
case INDEX_op_negsetcond_i32:
|
||||||
case INDEX_op_negsetcond_i64:
|
case INDEX_op_negsetcond_i64:
|
||||||
return C_O1_I2(r, rZ, rJ);
|
return C_O1_I2(r, rz, rJ);
|
||||||
|
|
||||||
case INDEX_op_brcond_i32:
|
case INDEX_op_brcond_i32:
|
||||||
case INDEX_op_brcond_i64:
|
case INDEX_op_brcond_i64:
|
||||||
return C_O0_I2(rZ, rJ);
|
return C_O0_I2(rz, rJ);
|
||||||
case INDEX_op_movcond_i32:
|
case INDEX_op_movcond_i32:
|
||||||
case INDEX_op_movcond_i64:
|
case INDEX_op_movcond_i64:
|
||||||
return C_O1_I4(r, rZ, rJ, rI, 0);
|
return C_O1_I4(r, rz, rJ, rI, 0);
|
||||||
case INDEX_op_add2_i32:
|
case INDEX_op_add2_i32:
|
||||||
case INDEX_op_add2_i64:
|
case INDEX_op_add2_i64:
|
||||||
case INDEX_op_sub2_i32:
|
case INDEX_op_sub2_i32:
|
||||||
case INDEX_op_sub2_i64:
|
case INDEX_op_sub2_i64:
|
||||||
return C_O2_I4(r, r, rZ, rZ, rJ, rJ);
|
return C_O2_I4(r, r, rz, rz, rJ, rJ);
|
||||||
case INDEX_op_mulu2_i32:
|
case INDEX_op_mulu2_i32:
|
||||||
case INDEX_op_muls2_i32:
|
case INDEX_op_muls2_i32:
|
||||||
return C_O2_I2(r, r, rZ, rJ);
|
return C_O2_I2(r, r, rz, rJ);
|
||||||
case INDEX_op_muluh_i64:
|
case INDEX_op_muluh_i64:
|
||||||
return C_O1_I2(r, r, r);
|
return C_O1_I2(r, r, r);
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ typedef enum {
|
|||||||
TCG_REG_I7,
|
TCG_REG_I7,
|
||||||
} TCGReg;
|
} TCGReg;
|
||||||
|
|
||||||
#define TCG_AREG0 TCG_REG_I0
|
#define TCG_AREG0 TCG_REG_I0
|
||||||
|
#define TCG_REG_ZERO TCG_REG_G0
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -91,25 +91,10 @@ static MemOp tcg_canonicalize_memop(MemOp op, bool is64, bool st)
|
|||||||
static void gen_ldst(TCGOpcode opc, TCGType type, TCGTemp *vl, TCGTemp *vh,
|
static void gen_ldst(TCGOpcode opc, TCGType type, TCGTemp *vl, TCGTemp *vh,
|
||||||
TCGTemp *addr, MemOpIdx oi)
|
TCGTemp *addr, MemOpIdx oi)
|
||||||
{
|
{
|
||||||
if (TCG_TARGET_REG_BITS == 64 || tcg_ctx->addr_type == TCG_TYPE_I32) {
|
if (vh) {
|
||||||
if (vh) {
|
tcg_gen_op4(opc, type, temp_arg(vl), temp_arg(vh), temp_arg(addr), oi);
|
||||||
tcg_gen_op4(opc, type, temp_arg(vl), temp_arg(vh),
|
|
||||||
temp_arg(addr), oi);
|
|
||||||
} else {
|
|
||||||
tcg_gen_op3(opc, type, temp_arg(vl), temp_arg(addr), oi);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* See TCGV_LOW/HIGH. */
|
tcg_gen_op3(opc, type, temp_arg(vl), temp_arg(addr), oi);
|
||||||
TCGTemp *al = addr + HOST_BIG_ENDIAN;
|
|
||||||
TCGTemp *ah = addr + !HOST_BIG_ENDIAN;
|
|
||||||
|
|
||||||
if (vh) {
|
|
||||||
tcg_gen_op5(opc, type, temp_arg(vl), temp_arg(vh),
|
|
||||||
temp_arg(al), temp_arg(ah), oi);
|
|
||||||
} else {
|
|
||||||
tcg_gen_op4(opc, type, temp_arg(vl),
|
|
||||||
temp_arg(al), temp_arg(ah), oi);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +217,6 @@ static void tcg_gen_qemu_ld_i32_int(TCGv_i32 val, TCGTemp *addr,
|
|||||||
MemOp orig_memop;
|
MemOp orig_memop;
|
||||||
MemOpIdx orig_oi, oi;
|
MemOpIdx orig_oi, oi;
|
||||||
TCGv_i64 copy_addr;
|
TCGv_i64 copy_addr;
|
||||||
TCGOpcode opc;
|
|
||||||
|
|
||||||
tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
|
tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
|
||||||
orig_memop = memop = tcg_canonicalize_memop(memop, 0, 0);
|
orig_memop = memop = tcg_canonicalize_memop(memop, 0, 0);
|
||||||
@ -248,12 +232,8 @@ static void tcg_gen_qemu_ld_i32_int(TCGv_i32 val, TCGTemp *addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
copy_addr = plugin_maybe_preserve_addr(addr);
|
copy_addr = plugin_maybe_preserve_addr(addr);
|
||||||
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
|
gen_ldst(INDEX_op_qemu_ld_i32, TCG_TYPE_I32,
|
||||||
opc = INDEX_op_qemu_ld_a32_i32;
|
tcgv_i32_temp(val), NULL, addr, oi);
|
||||||
} else {
|
|
||||||
opc = INDEX_op_qemu_ld_a64_i32;
|
|
||||||
}
|
|
||||||
gen_ldst(opc, TCG_TYPE_I32, tcgv_i32_temp(val), NULL, addr, oi);
|
|
||||||
plugin_gen_mem_callbacks_i32(val, copy_addr, addr, orig_oi,
|
plugin_gen_mem_callbacks_i32(val, copy_addr, addr, orig_oi,
|
||||||
QEMU_PLUGIN_MEM_R);
|
QEMU_PLUGIN_MEM_R);
|
||||||
|
|
||||||
@ -310,17 +290,9 @@ static void tcg_gen_qemu_st_i32_int(TCGv_i32 val, TCGTemp *addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (TCG_TARGET_HAS_qemu_st8_i32 && (memop & MO_SIZE) == MO_8) {
|
if (TCG_TARGET_HAS_qemu_st8_i32 && (memop & MO_SIZE) == MO_8) {
|
||||||
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
|
opc = INDEX_op_qemu_st8_i32;
|
||||||
opc = INDEX_op_qemu_st8_a32_i32;
|
|
||||||
} else {
|
|
||||||
opc = INDEX_op_qemu_st8_a64_i32;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
|
opc = INDEX_op_qemu_st_i32;
|
||||||
opc = INDEX_op_qemu_st_a32_i32;
|
|
||||||
} else {
|
|
||||||
opc = INDEX_op_qemu_st_a64_i32;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
gen_ldst(opc, TCG_TYPE_I32, tcgv_i32_temp(val), NULL, addr, oi);
|
gen_ldst(opc, TCG_TYPE_I32, tcgv_i32_temp(val), NULL, addr, oi);
|
||||||
plugin_gen_mem_callbacks_i32(val, NULL, addr, orig_oi, QEMU_PLUGIN_MEM_W);
|
plugin_gen_mem_callbacks_i32(val, NULL, addr, orig_oi, QEMU_PLUGIN_MEM_W);
|
||||||
@ -344,7 +316,6 @@ static void tcg_gen_qemu_ld_i64_int(TCGv_i64 val, TCGTemp *addr,
|
|||||||
MemOp orig_memop;
|
MemOp orig_memop;
|
||||||
MemOpIdx orig_oi, oi;
|
MemOpIdx orig_oi, oi;
|
||||||
TCGv_i64 copy_addr;
|
TCGv_i64 copy_addr;
|
||||||
TCGOpcode opc;
|
|
||||||
|
|
||||||
if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
|
if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
|
||||||
tcg_gen_qemu_ld_i32_int(TCGV_LOW(val), addr, idx, memop);
|
tcg_gen_qemu_ld_i32_int(TCGV_LOW(val), addr, idx, memop);
|
||||||
@ -370,12 +341,7 @@ static void tcg_gen_qemu_ld_i64_int(TCGv_i64 val, TCGTemp *addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
copy_addr = plugin_maybe_preserve_addr(addr);
|
copy_addr = plugin_maybe_preserve_addr(addr);
|
||||||
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
|
gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, oi);
|
||||||
opc = INDEX_op_qemu_ld_a32_i64;
|
|
||||||
} else {
|
|
||||||
opc = INDEX_op_qemu_ld_a64_i64;
|
|
||||||
}
|
|
||||||
gen_ldst_i64(opc, val, addr, oi);
|
|
||||||
plugin_gen_mem_callbacks_i64(val, copy_addr, addr, orig_oi,
|
plugin_gen_mem_callbacks_i64(val, copy_addr, addr, orig_oi,
|
||||||
QEMU_PLUGIN_MEM_R);
|
QEMU_PLUGIN_MEM_R);
|
||||||
|
|
||||||
@ -412,7 +378,6 @@ static void tcg_gen_qemu_st_i64_int(TCGv_i64 val, TCGTemp *addr,
|
|||||||
{
|
{
|
||||||
TCGv_i64 swap = NULL;
|
TCGv_i64 swap = NULL;
|
||||||
MemOpIdx orig_oi, oi;
|
MemOpIdx orig_oi, oi;
|
||||||
TCGOpcode opc;
|
|
||||||
|
|
||||||
if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
|
if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
|
||||||
tcg_gen_qemu_st_i32_int(TCGV_LOW(val), addr, idx, memop);
|
tcg_gen_qemu_st_i32_int(TCGV_LOW(val), addr, idx, memop);
|
||||||
@ -443,12 +408,7 @@ static void tcg_gen_qemu_st_i64_int(TCGv_i64 val, TCGTemp *addr,
|
|||||||
oi = make_memop_idx(memop, idx);
|
oi = make_memop_idx(memop, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
|
gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, oi);
|
||||||
opc = INDEX_op_qemu_st_a32_i64;
|
|
||||||
} else {
|
|
||||||
opc = INDEX_op_qemu_st_a64_i64;
|
|
||||||
}
|
|
||||||
gen_ldst_i64(opc, val, addr, oi);
|
|
||||||
plugin_gen_mem_callbacks_i64(val, NULL, addr, orig_oi, QEMU_PLUGIN_MEM_W);
|
plugin_gen_mem_callbacks_i64(val, NULL, addr, orig_oi, QEMU_PLUGIN_MEM_W);
|
||||||
|
|
||||||
if (swap) {
|
if (swap) {
|
||||||
@ -560,7 +520,6 @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr,
|
|||||||
{
|
{
|
||||||
MemOpIdx orig_oi;
|
MemOpIdx orig_oi;
|
||||||
TCGv_i64 ext_addr = NULL;
|
TCGv_i64 ext_addr = NULL;
|
||||||
TCGOpcode opc;
|
|
||||||
|
|
||||||
check_max_alignment(memop_alignment_bits(memop));
|
check_max_alignment(memop_alignment_bits(memop));
|
||||||
tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
|
tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
|
||||||
@ -588,12 +547,7 @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr,
|
|||||||
hi = TCGV128_HIGH(val);
|
hi = TCGV128_HIGH(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
|
gen_ldst(INDEX_op_qemu_ld_i128, TCG_TYPE_I128, tcgv_i64_temp(lo),
|
||||||
opc = INDEX_op_qemu_ld_a32_i128;
|
|
||||||
} else {
|
|
||||||
opc = INDEX_op_qemu_ld_a64_i128;
|
|
||||||
}
|
|
||||||
gen_ldst(opc, TCG_TYPE_I128, tcgv_i64_temp(lo),
|
|
||||||
tcgv_i64_temp(hi), addr, oi);
|
tcgv_i64_temp(hi), addr, oi);
|
||||||
|
|
||||||
if (need_bswap) {
|
if (need_bswap) {
|
||||||
@ -609,12 +563,6 @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr,
|
|||||||
canonicalize_memop_i128_as_i64(mop, memop);
|
canonicalize_memop_i128_as_i64(mop, memop);
|
||||||
need_bswap = (mop[0] ^ memop) & MO_BSWAP;
|
need_bswap = (mop[0] ^ memop) & MO_BSWAP;
|
||||||
|
|
||||||
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
|
|
||||||
opc = INDEX_op_qemu_ld_a32_i64;
|
|
||||||
} else {
|
|
||||||
opc = INDEX_op_qemu_ld_a64_i64;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since there are no global TCGv_i128, there is no visible state
|
* Since there are no global TCGv_i128, there is no visible state
|
||||||
* changed if the second load faults. Load directly into the two
|
* changed if the second load faults. Load directly into the two
|
||||||
@ -628,7 +576,8 @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr,
|
|||||||
y = TCGV128_LOW(val);
|
y = TCGV128_LOW(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_ldst_i64(opc, x, addr, make_memop_idx(mop[0], idx));
|
gen_ldst_i64(INDEX_op_qemu_ld_i64, x, addr,
|
||||||
|
make_memop_idx(mop[0], idx));
|
||||||
|
|
||||||
if (need_bswap) {
|
if (need_bswap) {
|
||||||
tcg_gen_bswap64_i64(x, x);
|
tcg_gen_bswap64_i64(x, x);
|
||||||
@ -644,7 +593,8 @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr,
|
|||||||
addr_p8 = tcgv_i64_temp(t);
|
addr_p8 = tcgv_i64_temp(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_ldst_i64(opc, y, addr_p8, make_memop_idx(mop[1], idx));
|
gen_ldst_i64(INDEX_op_qemu_ld_i64, y, addr_p8,
|
||||||
|
make_memop_idx(mop[1], idx));
|
||||||
tcg_temp_free_internal(addr_p8);
|
tcg_temp_free_internal(addr_p8);
|
||||||
|
|
||||||
if (need_bswap) {
|
if (need_bswap) {
|
||||||
@ -678,7 +628,6 @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
|
|||||||
{
|
{
|
||||||
MemOpIdx orig_oi;
|
MemOpIdx orig_oi;
|
||||||
TCGv_i64 ext_addr = NULL;
|
TCGv_i64 ext_addr = NULL;
|
||||||
TCGOpcode opc;
|
|
||||||
|
|
||||||
check_max_alignment(memop_alignment_bits(memop));
|
check_max_alignment(memop_alignment_bits(memop));
|
||||||
tcg_gen_req_mo(TCG_MO_ST_LD | TCG_MO_ST_ST);
|
tcg_gen_req_mo(TCG_MO_ST_LD | TCG_MO_ST_ST);
|
||||||
@ -709,13 +658,8 @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
|
|||||||
hi = TCGV128_HIGH(val);
|
hi = TCGV128_HIGH(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
|
gen_ldst(INDEX_op_qemu_st_i128, TCG_TYPE_I128,
|
||||||
opc = INDEX_op_qemu_st_a32_i128;
|
tcgv_i64_temp(lo), tcgv_i64_temp(hi), addr, oi);
|
||||||
} else {
|
|
||||||
opc = INDEX_op_qemu_st_a64_i128;
|
|
||||||
}
|
|
||||||
gen_ldst(opc, TCG_TYPE_I128, tcgv_i64_temp(lo),
|
|
||||||
tcgv_i64_temp(hi), addr, oi);
|
|
||||||
|
|
||||||
if (need_bswap) {
|
if (need_bswap) {
|
||||||
tcg_temp_free_i64(lo);
|
tcg_temp_free_i64(lo);
|
||||||
@ -728,12 +672,6 @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
|
|||||||
|
|
||||||
canonicalize_memop_i128_as_i64(mop, memop);
|
canonicalize_memop_i128_as_i64(mop, memop);
|
||||||
|
|
||||||
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
|
|
||||||
opc = INDEX_op_qemu_st_a32_i64;
|
|
||||||
} else {
|
|
||||||
opc = INDEX_op_qemu_st_a64_i64;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((memop & MO_BSWAP) == MO_LE) {
|
if ((memop & MO_BSWAP) == MO_LE) {
|
||||||
x = TCGV128_LOW(val);
|
x = TCGV128_LOW(val);
|
||||||
y = TCGV128_HIGH(val);
|
y = TCGV128_HIGH(val);
|
||||||
@ -748,7 +686,8 @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
|
|||||||
x = b;
|
x = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_ldst_i64(opc, x, addr, make_memop_idx(mop[0], idx));
|
gen_ldst_i64(INDEX_op_qemu_st_i64, x, addr,
|
||||||
|
make_memop_idx(mop[0], idx));
|
||||||
|
|
||||||
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
|
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
|
||||||
TCGv_i32 t = tcg_temp_ebb_new_i32();
|
TCGv_i32 t = tcg_temp_ebb_new_i32();
|
||||||
@ -762,10 +701,12 @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
|
|||||||
|
|
||||||
if (b) {
|
if (b) {
|
||||||
tcg_gen_bswap64_i64(b, y);
|
tcg_gen_bswap64_i64(b, y);
|
||||||
gen_ldst_i64(opc, b, addr_p8, make_memop_idx(mop[1], idx));
|
gen_ldst_i64(INDEX_op_qemu_st_i64, b, addr_p8,
|
||||||
|
make_memop_idx(mop[1], idx));
|
||||||
tcg_temp_free_i64(b);
|
tcg_temp_free_i64(b);
|
||||||
} else {
|
} else {
|
||||||
gen_ldst_i64(opc, y, addr_p8, make_memop_idx(mop[1], idx));
|
gen_ldst_i64(INDEX_op_qemu_st_i64, y, addr_p8,
|
||||||
|
make_memop_idx(mop[1], idx));
|
||||||
}
|
}
|
||||||
tcg_temp_free_internal(addr_p8);
|
tcg_temp_free_internal(addr_p8);
|
||||||
} else {
|
} else {
|
||||||
|
97
tcg/tcg.c
97
tcg/tcg.c
@ -100,8 +100,7 @@ struct TCGLabelQemuLdst {
|
|||||||
bool is_ld; /* qemu_ld: true, qemu_st: false */
|
bool is_ld; /* qemu_ld: true, qemu_st: false */
|
||||||
MemOpIdx oi;
|
MemOpIdx oi;
|
||||||
TCGType type; /* result type of a load */
|
TCGType type; /* result type of a load */
|
||||||
TCGReg addrlo_reg; /* reg index for low word of guest virtual addr */
|
TCGReg addr_reg; /* reg index for guest virtual addr */
|
||||||
TCGReg addrhi_reg; /* reg index for high word of guest virtual addr */
|
|
||||||
TCGReg datalo_reg; /* reg index for low word to be loaded or stored */
|
TCGReg datalo_reg; /* reg index for low word to be loaded or stored */
|
||||||
TCGReg datahi_reg; /* reg index for high word to be loaded or stored */
|
TCGReg datahi_reg; /* reg index for high word to be loaded or stored */
|
||||||
const tcg_insn_unit *raddr; /* addr of the next IR of qemu_ld/st IR */
|
const tcg_insn_unit *raddr; /* addr of the next IR of qemu_ld/st IR */
|
||||||
@ -1598,21 +1597,17 @@ void tcg_prologue_init(void)
|
|||||||
tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(s->code_ptr);
|
tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(s->code_ptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TCG_TARGET_NEED_POOL_LABELS
|
|
||||||
s->pool_labels = NULL;
|
s->pool_labels = NULL;
|
||||||
#endif
|
|
||||||
|
|
||||||
qemu_thread_jit_write();
|
qemu_thread_jit_write();
|
||||||
/* Generate the prologue. */
|
/* Generate the prologue. */
|
||||||
tcg_target_qemu_prologue(s);
|
tcg_target_qemu_prologue(s);
|
||||||
|
|
||||||
#ifdef TCG_TARGET_NEED_POOL_LABELS
|
|
||||||
/* Allow the prologue to put e.g. guest_base into a pool entry. */
|
/* Allow the prologue to put e.g. guest_base into a pool entry. */
|
||||||
{
|
{
|
||||||
int result = tcg_out_pool_finalize(s);
|
int result = tcg_out_pool_finalize(s);
|
||||||
tcg_debug_assert(result == 0);
|
tcg_debug_assert(result == 0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
prologue_size = tcg_current_code_size(s);
|
prologue_size = tcg_current_code_size(s);
|
||||||
perf_report_prologue(s->code_gen_ptr, prologue_size);
|
perf_report_prologue(s->code_gen_ptr, prologue_size);
|
||||||
@ -1694,9 +1689,7 @@ void tcg_func_start(TCGContext *s)
|
|||||||
s->emit_before_op = NULL;
|
s->emit_before_op = NULL;
|
||||||
QSIMPLEQ_INIT(&s->labels);
|
QSIMPLEQ_INIT(&s->labels);
|
||||||
|
|
||||||
tcg_debug_assert(s->addr_type == TCG_TYPE_I32 ||
|
tcg_debug_assert(s->addr_type <= TCG_TYPE_REG);
|
||||||
s->addr_type == TCG_TYPE_I64);
|
|
||||||
|
|
||||||
tcg_debug_assert(s->insn_start_words > 0);
|
tcg_debug_assert(s->insn_start_words > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2153,24 +2146,17 @@ bool tcg_op_supported(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_exit_tb:
|
case INDEX_op_exit_tb:
|
||||||
case INDEX_op_goto_tb:
|
case INDEX_op_goto_tb:
|
||||||
case INDEX_op_goto_ptr:
|
case INDEX_op_goto_ptr:
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st_i64:
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case INDEX_op_qemu_st8_a32_i32:
|
case INDEX_op_qemu_st8_i32:
|
||||||
case INDEX_op_qemu_st8_a64_i32:
|
|
||||||
return TCG_TARGET_HAS_qemu_st8_i32;
|
return TCG_TARGET_HAS_qemu_st8_i32;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i128:
|
case INDEX_op_qemu_ld_i128:
|
||||||
case INDEX_op_qemu_ld_a64_i128:
|
case INDEX_op_qemu_st_i128:
|
||||||
case INDEX_op_qemu_st_a32_i128:
|
|
||||||
case INDEX_op_qemu_st_a64_i128:
|
|
||||||
return TCG_TARGET_HAS_qemu_ldst_i128;
|
return TCG_TARGET_HAS_qemu_ldst_i128;
|
||||||
|
|
||||||
case INDEX_op_mov_i32:
|
case INDEX_op_mov_i32:
|
||||||
@ -2868,20 +2854,13 @@ void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs)
|
|||||||
}
|
}
|
||||||
i = 1;
|
i = 1;
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st8_i32:
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_st8_a32_i32:
|
case INDEX_op_qemu_st_i64:
|
||||||
case INDEX_op_qemu_st8_a64_i32:
|
case INDEX_op_qemu_ld_i128:
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
case INDEX_op_qemu_st_i128:
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
case INDEX_op_qemu_ld_a32_i128:
|
|
||||||
case INDEX_op_qemu_ld_a64_i128:
|
|
||||||
case INDEX_op_qemu_st_a32_i128:
|
|
||||||
case INDEX_op_qemu_st_a64_i128:
|
|
||||||
{
|
{
|
||||||
const char *s_al, *s_op, *s_at;
|
const char *s_al, *s_op, *s_at;
|
||||||
MemOpIdx oi = op->args[k++];
|
MemOpIdx oi = op->args[k++];
|
||||||
@ -3244,6 +3223,11 @@ static void process_constraint_sets(void)
|
|||||||
case 'i':
|
case 'i':
|
||||||
args_ct[i].ct |= TCG_CT_CONST;
|
args_ct[i].ct |= TCG_CT_CONST;
|
||||||
break;
|
break;
|
||||||
|
#ifdef TCG_REG_ZERO
|
||||||
|
case 'z':
|
||||||
|
args_ct[i].ct |= TCG_CT_REG_ZERO;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Include all of the target-specific constraints. */
|
/* Include all of the target-specific constraints. */
|
||||||
|
|
||||||
@ -5095,13 +5079,23 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
|
|||||||
arg_ct = &args_ct[i];
|
arg_ct = &args_ct[i];
|
||||||
ts = arg_temp(arg);
|
ts = arg_temp(arg);
|
||||||
|
|
||||||
if (ts->val_type == TEMP_VAL_CONST
|
if (ts->val_type == TEMP_VAL_CONST) {
|
||||||
&& tcg_target_const_match(ts->val, arg_ct->ct, ts->type,
|
#ifdef TCG_REG_ZERO
|
||||||
op_cond, TCGOP_VECE(op))) {
|
if (ts->val == 0 && (arg_ct->ct & TCG_CT_REG_ZERO)) {
|
||||||
/* constant is OK for instruction */
|
/* Hardware zero register: indicate register via non-const. */
|
||||||
const_args[i] = 1;
|
const_args[i] = 0;
|
||||||
new_args[i] = ts->val;
|
new_args[i] = TCG_REG_ZERO;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (tcg_target_const_match(ts->val, arg_ct->ct, ts->type,
|
||||||
|
op_cond, TCGOP_VECE(op))) {
|
||||||
|
/* constant is OK for instruction */
|
||||||
|
const_args[i] = 1;
|
||||||
|
new_args[i] = ts->val;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = ts->reg;
|
reg = ts->reg;
|
||||||
@ -6081,7 +6075,7 @@ static void tcg_out_ld_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
|
|||||||
*/
|
*/
|
||||||
tcg_out_helper_add_mov(mov, loc + HOST_BIG_ENDIAN,
|
tcg_out_helper_add_mov(mov, loc + HOST_BIG_ENDIAN,
|
||||||
TCG_TYPE_I32, TCG_TYPE_I32,
|
TCG_TYPE_I32, TCG_TYPE_I32,
|
||||||
ldst->addrlo_reg, -1);
|
ldst->addr_reg, -1);
|
||||||
tcg_out_helper_load_slots(s, 1, mov, parm);
|
tcg_out_helper_load_slots(s, 1, mov, parm);
|
||||||
|
|
||||||
tcg_out_helper_load_imm(s, loc[!HOST_BIG_ENDIAN].arg_slot,
|
tcg_out_helper_load_imm(s, loc[!HOST_BIG_ENDIAN].arg_slot,
|
||||||
@ -6089,7 +6083,7 @@ static void tcg_out_ld_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
|
|||||||
next_arg += 2;
|
next_arg += 2;
|
||||||
} else {
|
} else {
|
||||||
nmov = tcg_out_helper_add_mov(mov, loc, TCG_TYPE_I64, s->addr_type,
|
nmov = tcg_out_helper_add_mov(mov, loc, TCG_TYPE_I64, s->addr_type,
|
||||||
ldst->addrlo_reg, ldst->addrhi_reg);
|
ldst->addr_reg, -1);
|
||||||
tcg_out_helper_load_slots(s, nmov, mov, parm);
|
tcg_out_helper_load_slots(s, nmov, mov, parm);
|
||||||
next_arg += nmov;
|
next_arg += nmov;
|
||||||
}
|
}
|
||||||
@ -6246,21 +6240,22 @@ static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
|
|||||||
|
|
||||||
/* Handle addr argument. */
|
/* Handle addr argument. */
|
||||||
loc = &info->in[next_arg];
|
loc = &info->in[next_arg];
|
||||||
if (TCG_TARGET_REG_BITS == 32 && s->addr_type == TCG_TYPE_I32) {
|
tcg_debug_assert(s->addr_type <= TCG_TYPE_REG);
|
||||||
|
if (TCG_TARGET_REG_BITS == 32) {
|
||||||
/*
|
/*
|
||||||
* 32-bit host with 32-bit guest: zero-extend the guest address
|
* 32-bit host (and thus 32-bit guest): zero-extend the guest address
|
||||||
* to 64-bits for the helper by storing the low part. Later,
|
* to 64-bits for the helper by storing the low part. Later,
|
||||||
* after we have processed the register inputs, we will load a
|
* after we have processed the register inputs, we will load a
|
||||||
* zero for the high part.
|
* zero for the high part.
|
||||||
*/
|
*/
|
||||||
tcg_out_helper_add_mov(mov, loc + HOST_BIG_ENDIAN,
|
tcg_out_helper_add_mov(mov, loc + HOST_BIG_ENDIAN,
|
||||||
TCG_TYPE_I32, TCG_TYPE_I32,
|
TCG_TYPE_I32, TCG_TYPE_I32,
|
||||||
ldst->addrlo_reg, -1);
|
ldst->addr_reg, -1);
|
||||||
next_arg += 2;
|
next_arg += 2;
|
||||||
nmov += 1;
|
nmov += 1;
|
||||||
} else {
|
} else {
|
||||||
n = tcg_out_helper_add_mov(mov, loc, TCG_TYPE_I64, s->addr_type,
|
n = tcg_out_helper_add_mov(mov, loc, TCG_TYPE_I64, s->addr_type,
|
||||||
ldst->addrlo_reg, ldst->addrhi_reg);
|
ldst->addr_reg, -1);
|
||||||
next_arg += n;
|
next_arg += n;
|
||||||
nmov += n;
|
nmov += n;
|
||||||
}
|
}
|
||||||
@ -6308,7 +6303,7 @@ static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
|
|||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TCG_TARGET_REG_BITS == 32 && s->addr_type == TCG_TYPE_I32) {
|
if (TCG_TARGET_REG_BITS == 32) {
|
||||||
/* Zero extend the address by loading a zero for the high part. */
|
/* Zero extend the address by loading a zero for the high part. */
|
||||||
loc = &info->in[1 + !HOST_BIG_ENDIAN];
|
loc = &info->in[1 + !HOST_BIG_ENDIAN];
|
||||||
tcg_out_helper_load_imm(s, loc->arg_slot, TCG_TYPE_I32, 0, parm);
|
tcg_out_helper_load_imm(s, loc->arg_slot, TCG_TYPE_I32, 0, parm);
|
||||||
|
119
tcg/tci.c
119
tcg/tci.c
@ -154,16 +154,6 @@ static void tci_args_rrrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
|
|||||||
*i4 = extract32(insn, 26, 6);
|
*i4 = extract32(insn, 26, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tci_args_rrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
|
|
||||||
TCGReg *r2, TCGReg *r3, TCGReg *r4)
|
|
||||||
{
|
|
||||||
*r0 = extract32(insn, 8, 4);
|
|
||||||
*r1 = extract32(insn, 12, 4);
|
|
||||||
*r2 = extract32(insn, 16, 4);
|
|
||||||
*r3 = extract32(insn, 20, 4);
|
|
||||||
*r4 = extract32(insn, 24, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tci_args_rrrr(uint32_t insn,
|
static void tci_args_rrrr(uint32_t insn,
|
||||||
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
|
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
|
||||||
{
|
{
|
||||||
@ -912,43 +902,21 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
|||||||
tb_ptr = ptr;
|
tb_ptr = ptr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
tci_args_rrm(insn, &r0, &r1, &oi);
|
tci_args_rrm(insn, &r0, &r1, &oi);
|
||||||
taddr = (uint32_t)regs[r1];
|
taddr = regs[r1];
|
||||||
goto do_ld_i32;
|
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
|
||||||
tci_args_rrm(insn, &r0, &r1, &oi);
|
|
||||||
taddr = regs[r1];
|
|
||||||
} else {
|
|
||||||
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
|
|
||||||
taddr = tci_uint64(regs[r2], regs[r1]);
|
|
||||||
oi = regs[r3];
|
|
||||||
}
|
|
||||||
do_ld_i32:
|
|
||||||
regs[r0] = tci_qemu_ld(env, taddr, oi, tb_ptr);
|
regs[r0] = tci_qemu_ld(env, taddr, oi, tb_ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
case INDEX_op_qemu_ld_i64:
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
|
||||||
tci_args_rrm(insn, &r0, &r1, &oi);
|
|
||||||
taddr = (uint32_t)regs[r1];
|
|
||||||
} else {
|
|
||||||
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
|
|
||||||
taddr = (uint32_t)regs[r2];
|
|
||||||
oi = regs[r3];
|
|
||||||
}
|
|
||||||
goto do_ld_i64;
|
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
if (TCG_TARGET_REG_BITS == 64) {
|
||||||
tci_args_rrm(insn, &r0, &r1, &oi);
|
tci_args_rrm(insn, &r0, &r1, &oi);
|
||||||
taddr = regs[r1];
|
taddr = regs[r1];
|
||||||
} else {
|
} else {
|
||||||
tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
|
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
|
||||||
taddr = tci_uint64(regs[r3], regs[r2]);
|
taddr = regs[r2];
|
||||||
oi = regs[r4];
|
oi = regs[r3];
|
||||||
}
|
}
|
||||||
do_ld_i64:
|
|
||||||
tmp64 = tci_qemu_ld(env, taddr, oi, tb_ptr);
|
tmp64 = tci_qemu_ld(env, taddr, oi, tb_ptr);
|
||||||
if (TCG_TARGET_REG_BITS == 32) {
|
if (TCG_TARGET_REG_BITS == 32) {
|
||||||
tci_write_reg64(regs, r1, r0, tmp64);
|
tci_write_reg64(regs, r1, r0, tmp64);
|
||||||
@ -957,47 +925,23 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i32:
|
||||||
tci_args_rrm(insn, &r0, &r1, &oi);
|
tci_args_rrm(insn, &r0, &r1, &oi);
|
||||||
taddr = (uint32_t)regs[r1];
|
taddr = regs[r1];
|
||||||
goto do_st_i32;
|
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
|
||||||
tci_args_rrm(insn, &r0, &r1, &oi);
|
|
||||||
taddr = regs[r1];
|
|
||||||
} else {
|
|
||||||
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
|
|
||||||
taddr = tci_uint64(regs[r2], regs[r1]);
|
|
||||||
oi = regs[r3];
|
|
||||||
}
|
|
||||||
do_st_i32:
|
|
||||||
tci_qemu_st(env, taddr, regs[r0], oi, tb_ptr);
|
tci_qemu_st(env, taddr, regs[r0], oi, tb_ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
case INDEX_op_qemu_st_i64:
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
|
||||||
tci_args_rrm(insn, &r0, &r1, &oi);
|
|
||||||
tmp64 = regs[r0];
|
|
||||||
taddr = (uint32_t)regs[r1];
|
|
||||||
} else {
|
|
||||||
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
|
|
||||||
tmp64 = tci_uint64(regs[r1], regs[r0]);
|
|
||||||
taddr = (uint32_t)regs[r2];
|
|
||||||
oi = regs[r3];
|
|
||||||
}
|
|
||||||
goto do_st_i64;
|
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
if (TCG_TARGET_REG_BITS == 64) {
|
||||||
tci_args_rrm(insn, &r0, &r1, &oi);
|
tci_args_rrm(insn, &r0, &r1, &oi);
|
||||||
tmp64 = regs[r0];
|
tmp64 = regs[r0];
|
||||||
taddr = regs[r1];
|
taddr = regs[r1];
|
||||||
} else {
|
} else {
|
||||||
tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
|
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
|
||||||
tmp64 = tci_uint64(regs[r1], regs[r0]);
|
tmp64 = tci_uint64(regs[r1], regs[r0]);
|
||||||
taddr = tci_uint64(regs[r3], regs[r2]);
|
taddr = regs[r2];
|
||||||
oi = regs[r4];
|
oi = regs[r3];
|
||||||
}
|
}
|
||||||
do_st_i64:
|
|
||||||
tci_qemu_st(env, taddr, tmp64, oi, tb_ptr);
|
tci_qemu_st(env, taddr, tmp64, oi, tb_ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1269,42 +1213,21 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
|
|||||||
str_r(r3), str_r(r4), str_r(r5));
|
str_r(r3), str_r(r4), str_r(r5));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i64:
|
||||||
len = 1 + 1;
|
if (TCG_TARGET_REG_BITS == 32) {
|
||||||
goto do_qemu_ldst;
|
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
|
||||||
len = 1 + DIV_ROUND_UP(64, TCG_TARGET_REG_BITS);
|
|
||||||
goto do_qemu_ldst;
|
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
len = 2 * DIV_ROUND_UP(64, TCG_TARGET_REG_BITS);
|
|
||||||
goto do_qemu_ldst;
|
|
||||||
do_qemu_ldst:
|
|
||||||
switch (len) {
|
|
||||||
case 2:
|
|
||||||
tci_args_rrm(insn, &r0, &r1, &oi);
|
|
||||||
info->fprintf_func(info->stream, "%-12s %s, %s, %x",
|
|
||||||
op_name, str_r(r0), str_r(r1), oi);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
|
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
|
||||||
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
|
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
|
||||||
op_name, str_r(r0), str_r(r1),
|
op_name, str_r(r0), str_r(r1),
|
||||||
str_r(r2), str_r(r3));
|
str_r(r2), str_r(r3));
|
||||||
break;
|
break;
|
||||||
case 4:
|
|
||||||
tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
|
|
||||||
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s",
|
|
||||||
op_name, str_r(r0), str_r(r1),
|
|
||||||
str_r(r2), str_r(r3), str_r(r4));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_assert_not_reached();
|
|
||||||
}
|
}
|
||||||
|
/* fall through */
|
||||||
|
case INDEX_op_qemu_ld_i32:
|
||||||
|
case INDEX_op_qemu_st_i32:
|
||||||
|
tci_args_rrm(insn, &r0, &r1, &oi);
|
||||||
|
info->fprintf_func(info->stream, "%-12s %s, %s, %x",
|
||||||
|
op_name, str_r(r0), str_r(r1), oi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -169,22 +169,14 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||||||
case INDEX_op_setcond2_i32:
|
case INDEX_op_setcond2_i32:
|
||||||
return C_O1_I4(r, r, r, r, r);
|
return C_O1_I4(r, r, r, r, r);
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i32:
|
||||||
return C_O1_I1(r, r);
|
return C_O1_I1(r, r);
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O1_I2(r, r, r);
|
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I1(r, r, r);
|
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I1(r, r, r);
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
case INDEX_op_qemu_st_i32:
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I2(r, r, r, r);
|
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
|
||||||
return C_O0_I2(r, r);
|
return C_O0_I2(r, r);
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
case INDEX_op_qemu_st_i64:
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I3(r, r, r);
|
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I3(r, r, r);
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I3(r, r, r);
|
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
|
||||||
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I4(r, r, r, r);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return C_NotImplemented;
|
return C_NotImplemented;
|
||||||
@ -422,20 +414,6 @@ static void tcg_out_op_rrrbb(TCGContext *s, TCGOpcode op, TCGReg r0,
|
|||||||
tcg_out32(s, insn);
|
tcg_out32(s, insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_op_rrrrr(TCGContext *s, TCGOpcode op, TCGReg r0,
|
|
||||||
TCGReg r1, TCGReg r2, TCGReg r3, TCGReg r4)
|
|
||||||
{
|
|
||||||
tcg_insn_unit insn = 0;
|
|
||||||
|
|
||||||
insn = deposit32(insn, 0, 8, op);
|
|
||||||
insn = deposit32(insn, 8, 4, r0);
|
|
||||||
insn = deposit32(insn, 12, 4, r1);
|
|
||||||
insn = deposit32(insn, 16, 4, r2);
|
|
||||||
insn = deposit32(insn, 20, 4, r3);
|
|
||||||
insn = deposit32(insn, 24, 4, r4);
|
|
||||||
tcg_out32(s, insn);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op,
|
static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op,
|
||||||
TCGReg r0, TCGReg r1, TCGReg r2, TCGReg r3)
|
TCGReg r0, TCGReg r1, TCGReg r2, TCGReg r3)
|
||||||
{
|
{
|
||||||
@ -833,29 +811,21 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||||||
tcg_out_op_rrrr(s, opc, args[0], args[1], args[2], args[3]);
|
tcg_out_op_rrrr(s, opc, args[0], args[1], args[2], args[3]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld_a32_i32:
|
case INDEX_op_qemu_ld_i64:
|
||||||
case INDEX_op_qemu_st_a32_i32:
|
case INDEX_op_qemu_st_i64:
|
||||||
tcg_out_op_rrm(s, opc, args[0], args[1], args[2]);
|
if (TCG_TARGET_REG_BITS == 32) {
|
||||||
break;
|
|
||||||
case INDEX_op_qemu_ld_a64_i32:
|
|
||||||
case INDEX_op_qemu_st_a64_i32:
|
|
||||||
case INDEX_op_qemu_ld_a32_i64:
|
|
||||||
case INDEX_op_qemu_st_a32_i64:
|
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
|
||||||
tcg_out_op_rrm(s, opc, args[0], args[1], args[2]);
|
|
||||||
} else {
|
|
||||||
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, args[3]);
|
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, args[3]);
|
||||||
tcg_out_op_rrrr(s, opc, args[0], args[1], args[2], TCG_REG_TMP);
|
tcg_out_op_rrrr(s, opc, args[0], args[1], args[2], TCG_REG_TMP);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
/* fall through */
|
||||||
case INDEX_op_qemu_ld_a64_i64:
|
case INDEX_op_qemu_ld_i32:
|
||||||
case INDEX_op_qemu_st_a64_i64:
|
case INDEX_op_qemu_st_i32:
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
if (TCG_TARGET_REG_BITS == 64 && s->addr_type == TCG_TYPE_I32) {
|
||||||
tcg_out_op_rrm(s, opc, args[0], args[1], args[2]);
|
tcg_out_ext32u(s, TCG_REG_TMP, args[1]);
|
||||||
|
tcg_out_op_rrm(s, opc, args[0], TCG_REG_TMP, args[2]);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, args[4]);
|
tcg_out_op_rrm(s, opc, args[0], args[1], args[2]);
|
||||||
tcg_out_op_rrrrr(s, opc, args[0], args[1],
|
|
||||||
args[2], args[3], TCG_REG_TMP);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -72,6 +72,5 @@ typedef enum {
|
|||||||
} TCGReg;
|
} TCGReg;
|
||||||
|
|
||||||
#define HAVE_TCG_QEMU_TB_EXEC
|
#define HAVE_TCG_QEMU_TB_EXEC
|
||||||
#define TCG_TARGET_NEED_POOL_LABELS
|
|
||||||
|
|
||||||
#endif /* TCG_TARGET_H */
|
#endif /* TCG_TARGET_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user