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:
Stefan Hajnoczi 2025-02-19 08:36:45 +08:00
commit 40efe733e1
62 changed files with 550 additions and 1162 deletions

View File

@ -47,7 +47,6 @@
#include "qemu/plugin-memory.h"
#endif
#include "tcg/tcg-ldst.h"
#include "tcg/oversized-guest.h"
/* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */
/* #define DEBUG_TLB */
@ -105,26 +104,15 @@ static inline uint64_t tlb_read_idx(const CPUTLBEntry *entry,
{
/* Do not rearrange the CPUTLBEntry structure members. */
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) !=
MMU_DATA_STORE * sizeof(uint64_t));
MMU_DATA_STORE * sizeof(uintptr_t));
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
/* 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
const uintptr_t *ptr = &entry->addr_idx[access_type];
/* ofs might correspond to .addr_write, so use qatomic_read */
return qatomic_read(ptr);
# endif
#endif
}
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 += tlb_entry->addend;
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,
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,
hwaddr paddr, MemTxAttrs attrs, int prot,
int mmu_idx, uint64_t size)
int mmu_idx, vaddr size)
{
CPUTLBEntryFull full = {
.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,
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,
prot, mmu_idx, size);

View File

@ -28,7 +28,6 @@
#include "exec/replay-core.h"
#include "system/cpu-timers.h"
#include "tcg/startup.h"
#include "tcg/oversized-guest.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/accel.h"
@ -41,6 +40,8 @@
#include "hw/boards.h"
#endif
#include "internal-common.h"
#include "cpu-param.h"
struct TCGState {
AccelState parent_obj;
@ -72,7 +73,7 @@ DECLARE_INSTANCE_CHECKER(TCGState, TCG_STATE,
static bool default_mttcg_enabled(void)
{
if (icount_enabled() || TCG_OVERSIZED_GUEST) {
if (icount_enabled()) {
return false;
}
#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);
if (strcmp(value, "multi") == 0) {
if (TCG_OVERSIZED_GUEST) {
error_setg(errp, "No MTTCG when guest word size > hosts");
} else if (icount_enabled()) {
if (icount_enabled()) {
error_setg(errp, "No MTTCG when icount is enabled");
} else {
#ifndef TARGET_SUPPORTS_MTTCG

View File

@ -37,7 +37,6 @@ if:
* forced by --accel tcg,thread=single
* 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
inter-vCPU dependencies and all vCPUs should be able to run at full

View File

@ -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.
The constraint '``i``' is defined generically to accept any constant.
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.

View File

@ -19,14 +19,14 @@
#ifndef EXEC_TLB_COMMON_H
#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. */
typedef union CPUTLBEntry {
struct {
uint64_t addr_read;
uint64_t addr_write;
uint64_t addr_code;
uintptr_t addr_read;
uintptr_t addr_write;
uintptr_t addr_code;
/*
* Addend to virtual address to get host address. IO accesses
* use the corresponding iotlb value.
@ -37,7 +37,7 @@ typedef union CPUTLBEntry {
* Padding to get a power of two size, as well as index
* 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;
QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));

View File

@ -6,13 +6,15 @@
/**
* vaddr:
* 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;
#define VADDR_PRId PRId64
#define VADDR_PRIu PRIu64
#define VADDR_PRIo PRIo64
#define VADDR_PRIx PRIx64
#define VADDR_PRIX PRIX64
#define VADDR_MAX UINT64_MAX
typedef uintptr_t vaddr;
#define VADDR_PRId PRIdPTR
#define VADDR_PRIu PRIuPTR
#define VADDR_PRIo PRIoPTR
#define VADDR_PRIx PRIxPTR
#define VADDR_PRIX PRIXPTR
#define VADDR_MAX UINTPTR_MAX
#endif

View File

@ -56,25 +56,13 @@
*/
#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
* 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.
*
* 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 8
#else
# define ATOMIC_REG_SIZE sizeof(void *)
#endif
#define ATOMIC_REG_SIZE sizeof(void *)
/* Weak atomic operations prevent the compiler moving other
* loads/stores past the atomic operation load/store. However there is

View File

@ -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

View File

@ -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_mem_cb, 0, 1, 1, TCG_OPF_NOT_PRESENT)
/* Replicate ld/st ops for 32 and 64-bit guest addresses. */
DEF(qemu_ld_a32_i32, 1, 1, 1,
DEF(qemu_ld_i32, 1, 1, 1,
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)
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)
DEF(qemu_st_a32_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,
DEF(qemu_st_i64, 0, DATA64_ARGS + 1, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
/* Only used by i386 to cope with stupid register constraints. */
DEF(qemu_st8_a32_i32, 0, 1 + 1, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
DEF(qemu_st8_a64_i32, 0, 1 + DATA64_ARGS, 1,
DEF(qemu_st8_i32, 0, 1 + 1, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
/* 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_a64_i128, 2, 1, 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)
DEF(qemu_ld_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)
/* Host vector support. */

View File

@ -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);
#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 {
unsigned ct : 16;

View File

@ -3,6 +3,8 @@
#include "../generic/signal.h"
#define TARGET_SA_RESTORER 0x04000000
#define TARGET_SEGV_MTEAERR 8 /* Asynchronous ARM MTE error */
#define TARGET_SEGV_MTESERR 9 /* Synchronous ARM MTE exception */

View File

@ -3,6 +3,8 @@
#include "../generic/signal.h"
#define TARGET_SA_RESTORER 0x04000000
#define TARGET_ARCH_HAS_SETUP_FRAME
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1

View File

@ -3351,8 +3351,8 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
if (align_size != reserve_size) {
abi_ulong align_addr = ROUND_UP(load_addr, align);
abi_ulong align_end = align_addr + reserve_size;
abi_ulong load_end = load_addr + align_size;
abi_ulong align_end = TARGET_PAGE_ALIGN(align_addr + reserve_size);
abi_ulong load_end = TARGET_PAGE_ALIGN(load_addr + align_size);
if (align_addr != load_addr) {
target_munmap(load_addr, align_addr - load_addr);

View File

@ -15,7 +15,6 @@
#define TARGET_SA_RESTART 0x10000000
#define TARGET_SA_NODEFER 0x40000000
#define TARGET_SA_RESETHAND 0x80000000
#define TARGET_SA_RESTORER 0x04000000
#define TARGET_SIGHUP 1
#define TARGET_SIGINT 2

View File

@ -3,6 +3,8 @@
#include "../generic/signal.h"
#define TARGET_SA_RESTORER 0x04000000
#define TARGET_ARCH_HAS_SETUP_FRAME
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1

View File

@ -3,6 +3,7 @@
#include "../generic/signal.h"
#define TARGET_ARCH_HAS_SA_RESTORER 1
#define TARGET_ARCH_HAS_SETUP_FRAME
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1

View File

@ -3,6 +3,8 @@
#include "../generic/signal.h"
#define TARGET_SA_RESTORER 0x04000000
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
#endif /* MICROBLAZE_TARGET_SIGNAL_H */

View File

@ -3,6 +3,8 @@
#include "../generic/signal.h"
#define TARGET_SA_RESTORER 0x04000000
#if !defined(TARGET_PPC64)
#define TARGET_ARCH_HAS_SETUP_FRAME
#endif

View File

@ -3,6 +3,8 @@
#include "../generic/signal.h"
#define TARGET_SA_RESTORER 0x04000000
#define TARGET_ARCH_HAS_SETUP_FRAME
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1

View File

@ -3,6 +3,8 @@
#include "../generic/signal.h"
#define TARGET_SA_RESTORER 0x04000000
#define TARGET_ARCH_HAS_SETUP_FRAME
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1

View File

@ -3,6 +3,8 @@
#include "../generic/signal.h"
#define TARGET_SA_RESTORER 0x04000000
/* For x86_64, use of SA_RESTORER is mandatory. */
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0

View File

@ -3,6 +3,8 @@
#include "../generic/signal.h"
#define TARGET_SA_RESTORER 0x04000000
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
#endif

View File

@ -561,7 +561,7 @@ GArray *qemu_plugin_get_registers(void)
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);

View File

@ -16,9 +16,6 @@
#include "internals.h"
#include "cpu-features.h"
#include "idau.h"
#ifdef CONFIG_TCG
# include "tcg/oversized-guest.h"
#endif
typedef struct S1Translate {
/*
@ -840,7 +837,6 @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
ptw->out_rw = true;
}
#ifdef CONFIG_ATOMIC64
if (ptw->out_be) {
old_val = cpu_to_be64(old_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 = 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;
#else
/* AArch32 does not have FEAT_HADFS; non-TCG guests only use debug-mode. */

View File

@ -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)) {
qemu_log_mask(LOG_GUEST_ERROR,
"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);
return false;
}

View File

@ -289,7 +289,7 @@ static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
if (!decode(ctx, ctx->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);
generate_exception(ctx, EXCCODE_INE);
}

View File

@ -18,8 +18,8 @@ static bool trans_BBIT(DisasContext *ctx, arg_BBIT *a)
TCGv p;
if (ctx->hflags & MIPS_HFLAG_BMASK) {
LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
TARGET_FMT_lx "\n", ctx->base.pc_next);
LOG_DISAS("Branch in delay / forbidden slot at PC 0x%" VADDR_PRIx "\n",
ctx->base.pc_next);
generate_exception_end(ctx, EXCP_RI);
return true;
}

View File

@ -32,7 +32,6 @@
#include "system/cpu-timers.h"
#include "cpu_bits.h"
#include "debug.h"
#include "tcg/oversized-guest.h"
#include "pmp.h"
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;
int i;
#if !TCG_OVERSIZED_GUEST
restart:
#endif
restart:
for (i = 0; i < levels; i++, ptshift -= ptidxbits) {
target_ulong idx;
if (i == 0) {
@ -1388,13 +1385,6 @@ restart:
false, MEMTXATTRS_UNSPECIFIED);
if (memory_region_is_ram(mr)) {
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;
if (riscv_cpu_sxl(env) == MXL_RV32) {
old_pte = qatomic_cmpxchg((uint32_t *)pte_pa, pte, updated_pte);
@ -1405,7 +1395,6 @@ restart:
goto restart;
}
pte = updated_pte;
#endif
} else {
/*
* Misconfigured PTE in ROM (AD bits are not preset) or

View File

@ -79,8 +79,13 @@ int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
}
}
if (n < 80) {
/* f32-f62 (double width, even numbers only) */
return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll);
/* f32-f62 (16 double width registers, even register numbers only)
* 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) {
case 80:
@ -173,8 +178,13 @@ int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
}
return 4;
} else if (n < 80) {
/* f32-f62 (double width, even numbers only) */
env->fpr[(n - 32) / 2].ll = tmp;
/* f32-f62 (16 double width registers, even register numbers only)
* 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 {
switch (n) {
case 80:

View File

@ -96,7 +96,10 @@ CALL 01 i:s30
RDTICK 10 rd:5 101000 00100 0 0000000000000
RDPC 10 rd:5 101000 00101 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
RDSOFTINT 10 rd:5 101000 10110 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
WRASI 10 00011 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
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
FNHADDd 10 ..... 110100 ..... 0 0111 0010 ..... @d_d_d
FNsMULd 10 ..... 110100 ..... 0 0111 1001 ..... @d_r_r
FsTOx 10 ..... 110100 00000 0 1000 0001 ..... @r_r2
FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_d2
FqTOx 10 ..... 110100 00000 0 1000 0011 ..... @r_q2
FxTOs 10 ..... 110100 00000 0 1000 0100 ..... @r_r2
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @d_r2
FxTOq 10 ..... 110100 00000 0 1000 1100 ..... @q_r2
FsTOx 10 ..... 110100 00000 0 1000 0001 ..... @d_r2
FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @d_d2
FqTOx 10 ..... 110100 00000 0 1000 0011 ..... @d_q2
FxTOs 10 ..... 110100 00000 0 1000 0100 ..... @r_d2
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @d_d2
FxTOq 10 ..... 110100 00000 0 1000 1100 ..... @q_d2
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
FdTOs 10 ..... 110100 00000 0 1100 0110 ..... @r_d2
FqTOs 10 ..... 110100 00000 0 1100 0111 ..... @r_q2

View File

@ -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)
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)
{
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)
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)
{
gen_trap_ifnofpu(dc);

View File

@ -11,27 +11,27 @@
*/
C_O0_I1(r)
C_O0_I2(r, rC)
C_O0_I2(rZ, r)
C_O0_I2(rz, 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(w, r)
C_O1_I1(w, w)
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, rA)
C_O1_I2(r, r, rAL)
C_O1_I2(r, r, rC)
C_O1_I2(r, r, ri)
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, w, w)
C_O1_I2(w, w, wN)
C_O1_I2(w, w, wO)
C_O1_I2(w, w, wZ)
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_I4(r, r, rZ, rZ, rA, rMZ)
C_O2_I4(r, r, rz, rz, rA, rMZ)

View File

@ -1775,7 +1775,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
ldst = new_ldst_label(s);
ldst->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addr_reg;
ldst->addr_reg = addr_reg;
mask_type = (s->page_bits + s->tlb_dyn_max_bits > 32
? 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->oi = oi;
ldst->addrlo_reg = addr_reg;
ldst->addr_reg = addr_reg;
/* tst addr, #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];
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) {
case INDEX_op_goto_ptr:
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_i64:
tcg_out_ldst(s, I3312_STRB, REG0(0), a1, a2, 0);
tcg_out_ldst(s, I3312_STRB, a0, a1, a2, 0);
break;
case INDEX_op_st16_i32:
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;
case INDEX_op_st_i32:
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;
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;
case INDEX_op_add_i32:
@ -2395,28 +2391,22 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
/* FALLTHRU */
case INDEX_op_movcond_i64:
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;
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_ld_a64_i32:
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_a64_i64:
case INDEX_op_qemu_ld_i32:
case INDEX_op_qemu_ld_i64:
tcg_out_qemu_ld(s, a0, a1, a2, ext);
break;
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_a64_i32:
case INDEX_op_qemu_st_a32_i64:
case INDEX_op_qemu_st_a64_i64:
tcg_out_qemu_st(s, REG0(0), a1, a2, ext);
case INDEX_op_qemu_st_i32:
case INDEX_op_qemu_st_i64:
tcg_out_qemu_st(s, a0, a1, a2, ext);
break;
case INDEX_op_qemu_ld_a32_i128:
case INDEX_op_qemu_ld_a64_i128:
case INDEX_op_qemu_ld_i128:
tcg_out_qemu_ldst_i128(s, a0, a1, a2, args[3], true);
break;
case INDEX_op_qemu_st_a32_i128:
case INDEX_op_qemu_st_a64_i128:
tcg_out_qemu_ldst_i128(s, REG0(0), REG0(1), a2, args[3], false);
case INDEX_op_qemu_st_i128:
tcg_out_qemu_ldst_i128(s, a0, a1, a2, args[3], false);
break;
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_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;
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_i32:
tcg_out_extr(s, ext, a0, REG0(2), REG0(1), args[3]);
tcg_out_extr(s, ext, a0, a2, a1, args[3]);
break;
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],
const_args[5], false);
break;
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);
break;
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],
const_args[5], true);
break;
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);
break;
@ -2519,8 +2509,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
default:
g_assert_not_reached();
}
#undef REG0
}
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_st32_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_i64:
@ -3082,38 +3070,32 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_movcond_i32:
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_a64_i32:
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_a64_i64:
case INDEX_op_qemu_ld_i32:
case INDEX_op_qemu_ld_i64:
return C_O1_I1(r, r);
case INDEX_op_qemu_ld_a32_i128:
case INDEX_op_qemu_ld_a64_i128:
case INDEX_op_qemu_ld_i128:
return C_O2_I1(r, r, r);
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_a64_i32:
case INDEX_op_qemu_st_a32_i64:
case INDEX_op_qemu_st_a64_i64:
return C_O0_I2(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_qemu_st_i32:
case INDEX_op_qemu_st_i64:
return C_O0_I2(rz, r);
case INDEX_op_qemu_st_i128:
return C_O0_I3(rz, rz, r);
case INDEX_op_deposit_i32:
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_i64:
return C_O1_I2(r, rZ, rZ);
return C_O1_I2(r, rz, rz);
case INDEX_op_add2_i32:
case INDEX_op_add2_i64:
case INDEX_op_sub2_i32:
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_sub_vec:

View File

@ -45,6 +45,8 @@ typedef enum {
TCG_AREG0 = TCG_REG_X19,
} TCGReg;
#define TCG_REG_ZERO TCG_REG_XZR
#define TCG_TARGET_NB_REGS 64
#endif /* AARCH64_TCG_TARGET_H */

View File

@ -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);
}
static void __attribute__((unused))
tcg_out_ldrd_rwb(TCGContext *s, ARMCond cond, TCGReg rt, TCGReg rn, TCGReg rm)
{
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)
static void 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);
}
@ -1455,8 +1449,7 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
#define MIN_TLB_MASK_TABLE_OFS -256
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
TCGReg addrlo, TCGReg addrhi,
MemOpIdx oi, bool is_ld)
TCGReg addr, MemOpIdx oi, bool is_ld)
{
TCGLabelQemuLdst *ldst = NULL;
MemOp opc = get_memop(oi);
@ -1465,14 +1458,14 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
if (tcg_use_softmmu) {
*h = (HostAddress){
.cond = COND_AL,
.base = addrlo,
.base = addr,
.index = TCG_REG_R1,
.index_scratch = true,
};
} else {
*h = (HostAddress){
.cond = COND_AL,
.base = addrlo,
.base = addr,
.index = guest_base ? TCG_REG_GUEST_BASE : -1,
.index_scratch = false,
};
@ -1492,8 +1485,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
ldst = new_ldst_label(s);
ldst->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addrlo;
ldst->addrhi_reg = addrhi;
ldst->addr_reg = addr;
/* Load cpu->neg.tlb.f[mmu_idx].{mask,table} into {r0,r1}. */
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);
/* 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));
/*
* 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 (s->addr_type == TCG_TYPE_I32) {
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);
}
tcg_out_ld32_rwb(s, COND_AL, TCG_REG_R2, TCG_REG_R1, TCG_REG_R0);
} else {
tcg_out_dat_reg(s, COND_AL, ARITH_ADD,
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);
} else {
tcg_out_ldrd_8(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);
}
/* 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
* course must be zero.
*/
t_addr = addrlo;
t_addr = addr;
if (a_mask < s_mask) {
t_addr = TCG_REG_R0;
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) {
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 {
if (a_mask) {
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,
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,
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) {
ldst = new_ldst_label(s);
ldst->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addrlo;
ldst->addrhi_reg = addrhi;
ldst->addr_reg = addr;
/* We are expecting alignment to max out at 7 */
tcg_debug_assert(a_mask <= 0xff);
/* 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;
@ -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,
TCGReg addrlo, TCGReg addrhi,
MemOpIdx oi, TCGType data_type)
TCGReg addr, MemOpIdx oi, TCGType data_type)
{
MemOp opc = get_memop(oi);
TCGLabelQemuLdst *ldst;
HostAddress h;
ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, true);
ldst = prepare_host_addr(s, &h, addr, oi, true);
if (ldst) {
ldst->type = data_type;
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,
TCGReg addrlo, TCGReg addrhi,
MemOpIdx oi, TCGType data_type)
TCGReg addr, MemOpIdx oi, TCGType data_type)
{
MemOp opc = get_memop(oi);
TCGLabelQemuLdst *ldst;
HostAddress h;
ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, false);
ldst = prepare_host_addr(s, &h, addr, oi, false);
if (ldst) {
ldst->type = data_type;
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);
break;
case INDEX_op_qemu_ld_a32_i32:
tcg_out_qemu_ld(s, args[0], -1, args[1], -1, args[2], TCG_TYPE_I32);
case INDEX_op_qemu_ld_i32:
tcg_out_qemu_ld(s, args[0], -1, args[1], args[2], TCG_TYPE_I32);
break;
case INDEX_op_qemu_ld_a64_i32:
tcg_out_qemu_ld(s, args[0], -1, args[1], args[2],
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);
case INDEX_op_qemu_ld_i64:
tcg_out_qemu_ld(s, args[0], args[1], args[2], args[3], TCG_TYPE_I64);
break;
case INDEX_op_qemu_st_a32_i32:
tcg_out_qemu_st(s, args[0], -1, args[1], -1, args[2], TCG_TYPE_I32);
case INDEX_op_qemu_st_i32:
tcg_out_qemu_st(s, args[0], -1, args[1], args[2], TCG_TYPE_I32);
break;
case INDEX_op_qemu_st_a64_i32:
tcg_out_qemu_st(s, args[0], -1, args[1], args[2],
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);
case INDEX_op_qemu_st_i64:
tcg_out_qemu_st(s, args[0], args[1], args[2], args[3], TCG_TYPE_I64);
break;
case INDEX_op_bswap16_i32:
@ -2243,22 +2199,14 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_setcond2_i32:
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);
case INDEX_op_qemu_ld_a64_i32:
return C_O1_I2(r, q, q);
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_i64:
return C_O2_I1(e, p, q);
case INDEX_op_qemu_ld_a64_i64:
return C_O2_I2(e, p, q, q);
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_i32:
return C_O0_I2(q, q);
case INDEX_op_qemu_st_a64_i32:
return C_O0_I3(q, q, q);
case INDEX_op_qemu_st_a32_i64:
case INDEX_op_qemu_st_i64:
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:
return C_O0_I2(w, r);

View File

@ -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],
label_this, small);
break;
case TCG_COND_NE:
case TCG_COND_TSTNE:
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],
label_this, small);
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:
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);
}
@ -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.
*/
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
TCGReg addrlo, TCGReg addrhi,
MemOpIdx oi, bool is_ld)
TCGReg addr, MemOpIdx oi, bool is_ld)
{
TCGLabelQemuLdst *ldst = NULL;
MemOp opc = get_memop(oi);
@ -2184,7 +2134,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
} else {
*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);
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->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addrlo;
ldst->addrhi_reg = addrhi;
ldst->addr_reg = addr;
if (TCG_TARGET_REG_BITS == 64) {
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,
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.
*/
if (a_mask >= s_mask) {
tcg_out_mov(s, ttype, TCG_REG_L1, addrlo);
tcg_out_mov(s, ttype, TCG_REG_L1, addr);
} else {
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;
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;
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. */
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_L0, TCG_REG_L0,
offsetof(CPUTLBEntry, addend));
@ -2270,11 +2208,10 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
ldst = new_ldst_label(s);
ldst->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addrlo;
ldst->addrhi_reg = addrhi;
ldst->addr_reg = addr;
/* 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);
ldst->label_ptr[0] = s->code_ptr;
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,
TCGReg addrlo, TCGReg addrhi,
MemOpIdx oi, TCGType data_type)
TCGReg addr, MemOpIdx oi, TCGType data_type)
{
TCGLabelQemuLdst *ldst;
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));
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,
TCGReg addrlo, TCGReg addrhi,
MemOpIdx oi, TCGType data_type)
TCGReg addr, MemOpIdx oi, TCGType data_type)
{
TCGLabelQemuLdst *ldst;
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));
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);
break;
case INDEX_op_qemu_ld_a64_i32:
if (TCG_TARGET_REG_BITS == 32) {
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);
case INDEX_op_qemu_ld_i32:
tcg_out_qemu_ld(s, a0, -1, a1, a2, TCG_TYPE_I32);
break;
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_i64:
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 {
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;
case INDEX_op_qemu_ld_a64_i64:
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:
case INDEX_op_qemu_ld_i128:
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;
case INDEX_op_qemu_st_a64_i32:
case INDEX_op_qemu_st8_a64_i32:
if (TCG_TARGET_REG_BITS == 32) {
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);
case INDEX_op_qemu_st_i32:
case INDEX_op_qemu_st8_i32:
tcg_out_qemu_st(s, a0, -1, a1, a2, TCG_TYPE_I32);
break;
case INDEX_op_qemu_st_a32_i64:
case INDEX_op_qemu_st_i64:
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 {
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;
case INDEX_op_qemu_st_a64_i64:
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:
case INDEX_op_qemu_st_i128:
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;
OP_32_64(mulu2):
@ -3824,36 +3730,24 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_clz_i64:
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);
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);
case INDEX_op_qemu_st_a64_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:
case INDEX_op_qemu_st8_i32:
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);
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);
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_a64_i128:
case INDEX_op_qemu_ld_i128:
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
return C_O2_I1(r, r, L);
case INDEX_op_qemu_st_a32_i128:
case INDEX_op_qemu_st_a64_i128:
case INDEX_op_qemu_st_i128:
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
return C_O0_I3(L, L, L);

View File

@ -15,8 +15,8 @@
* tcg-target-con-str.h; the constraint combination is inclusive or.
*/
C_O0_I1(r)
C_O0_I2(rZ, r)
C_O0_I2(rZ, rZ)
C_O0_I2(rz, r)
C_O0_I2(rz, rz)
C_O0_I2(w, r)
C_O0_I3(r, 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, rU)
C_O1_I2(r, r, rW)
C_O1_I2(r, r, rZ)
C_O1_I2(r, 0, rZ)
C_O1_I2(r, rZ, ri)
C_O1_I2(r, rZ, rJ)
C_O1_I2(r, rZ, rZ)
C_O1_I2(r, 0, rz)
C_O1_I2(r, rz, ri)
C_O1_I2(r, rz, rJ)
C_O1_I2(r, rz, rz)
C_O1_I2(w, w, w)
C_O1_I2(w, w, wM)
C_O1_I2(w, w, wA)
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)

View File

@ -23,7 +23,6 @@ REGS('w', ALL_VECTOR_REGS)
CONST('I', TCG_CT_CONST_S12)
CONST('J', TCG_CT_CONST_S32)
CONST('U', TCG_CT_CONST_U12)
CONST('Z', TCG_CT_CONST_ZERO)
CONST('C', TCG_CT_CONST_C12)
CONST('W', TCG_CT_CONST_WSZ)
CONST('M', TCG_CT_CONST_VCMP)

View File

@ -37,8 +37,6 @@
#define TCG_TARGET_HAS_clz_i32 1
#define TCG_TARGET_HAS_ctz_i32 1
#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
/* 64-bit operations */

View File

@ -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_CT_CONST_ZERO 0x100
#define TCG_CT_CONST_S12 0x200
#define TCG_CT_CONST_S32 0x400
#define TCG_CT_CONST_U12 0x800
#define TCG_CT_CONST_C12 0x1000
#define TCG_CT_CONST_WSZ 0x2000
#define TCG_CT_CONST_VCMP 0x4000
#define TCG_CT_CONST_VADD 0x8000
#define TCG_CT_CONST_S12 0x100
#define TCG_CT_CONST_S32 0x200
#define TCG_CT_CONST_U12 0x400
#define TCG_CT_CONST_C12 0x800
#define TCG_CT_CONST_WSZ 0x1000
#define TCG_CT_CONST_VCMP 0x2000
#define TCG_CT_CONST_VADD 0x4000
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 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) {
return true;
}
if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
return true;
}
if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
return true;
}
@ -1010,7 +1006,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
ldst = new_ldst_label(s);
ldst->is_ld = is_ld;
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_TMP1, TCG_AREG0, table_ofs);
@ -1055,7 +1051,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
ldst->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addr_reg;
ldst->addr_reg = addr_reg;
/*
* 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);
break;
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_ld_a64_i32:
case INDEX_op_qemu_ld_i32:
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
break;
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_a64_i64:
case INDEX_op_qemu_ld_i64:
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I64);
break;
case INDEX_op_qemu_ld_a32_i128:
case INDEX_op_qemu_ld_a64_i128:
case INDEX_op_qemu_ld_i128:
tcg_out_qemu_ldst_i128(s, a0, a1, a2, a3, true);
break;
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_a64_i32:
case INDEX_op_qemu_st_i32:
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I32);
break;
case INDEX_op_qemu_st_a32_i64:
case INDEX_op_qemu_st_a64_i64:
case INDEX_op_qemu_st_i64:
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I64);
break;
case INDEX_op_qemu_st_a32_i128:
case INDEX_op_qemu_st_a64_i128:
case INDEX_op_qemu_st_i128:
tcg_out_qemu_ldst_i128(s, a0, a1, a2, a3, false);
break;
@ -2233,23 +2223,19 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_st32_i64:
case INDEX_op_st_i32:
case INDEX_op_st_i64:
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_a64_i32:
case INDEX_op_qemu_st_a32_i64:
case INDEX_op_qemu_st_a64_i64:
return C_O0_I2(rZ, r);
case INDEX_op_qemu_st_i32:
case INDEX_op_qemu_st_i64:
return C_O0_I2(rz, r);
case INDEX_op_qemu_ld_a32_i128:
case INDEX_op_qemu_ld_a64_i128:
case INDEX_op_qemu_ld_i128:
return C_N2_I1(r, r, r);
case INDEX_op_qemu_st_a32_i128:
case INDEX_op_qemu_st_a64_i128:
case INDEX_op_qemu_st_i128:
return C_O0_I3(r, r, r);
case INDEX_op_brcond_i32:
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_i64:
@ -2290,10 +2276,8 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_ld32u_i64:
case INDEX_op_ld_i32:
case INDEX_op_ld_i64:
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_ld_a64_i32:
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_a64_i64:
case INDEX_op_qemu_ld_i32:
case INDEX_op_qemu_ld_i64:
return C_O1_I1(r, r);
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_i64:
/* 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_setcond_i32:
return C_O1_I2(r, rZ, ri);
return C_O1_I2(r, rz, ri);
case INDEX_op_sub_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_i64:
@ -2367,11 +2351,11 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_rem_i64:
case INDEX_op_remu_i32:
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_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_dupm_vec:

View File

@ -85,4 +85,6 @@ typedef enum {
TCG_VEC_TMP0 = TCG_REG_V23,
} TCGReg;
#define TCG_REG_ZERO TCG_REG_ZERO
#endif /* LOONGARCH_TCG_TARGET_H */

View File

@ -10,24 +10,24 @@
* tcg-target-con-str.h; the constraint combination is inclusive or.
*/
C_O0_I1(r)
C_O0_I2(rZ, r)
C_O0_I2(rZ, rZ)
C_O0_I3(rZ, r, r)
C_O0_I3(rZ, rZ, r)
C_O0_I4(rZ, rZ, rZ, rZ)
C_O0_I4(rZ, rZ, r, r)
C_O0_I2(rz, r)
C_O0_I2(rz, rz)
C_O0_I3(rz, r, r)
C_O0_I3(rz, rz, r)
C_O0_I4(rz, rz, rz, rz)
C_O0_I4(rz, rz, 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, ri)
C_O1_I2(r, r, rI)
C_O1_I2(r, r, rIK)
C_O1_I2(r, r, rJ)
C_O1_I2(r, r, rWZ)
C_O1_I2(r, rZ, rN)
C_O1_I2(r, rZ, rZ)
C_O1_I4(r, rZ, rZ, rZ, 0)
C_O1_I4(r, rZ, rZ, rZ, rZ)
C_O1_I2(r, r, rzW)
C_O1_I2(r, rz, rN)
C_O1_I2(r, rz, rz)
C_O1_I4(r, rz, rz, rz, 0)
C_O1_I4(r, rz, rz, rz, rz)
C_O2_I1(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)

View File

@ -19,4 +19,3 @@ CONST('J', TCG_CT_CONST_S16)
CONST('K', TCG_CT_CONST_P2M1)
CONST('N', TCG_CT_CONST_N16)
CONST('W', TCG_CT_CONST_WSZ)
CONST('Z', TCG_CT_CONST_ZERO)

View File

@ -184,12 +184,11 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
g_assert_not_reached();
}
#define TCG_CT_CONST_ZERO 0x100
#define TCG_CT_CONST_U16 0x200 /* Unsigned 16-bit: 0 - 0xffff. */
#define TCG_CT_CONST_S16 0x400 /* Signed 16-bit: -32768 - 32767 */
#define TCG_CT_CONST_P2M1 0x800 /* Power of 2 minus 1. */
#define TCG_CT_CONST_N16 0x1000 /* "Negatable" 16-bit: -32767 - 32767 */
#define TCG_CT_CONST_WSZ 0x2000 /* word size */
#define TCG_CT_CONST_U16 0x100 /* Unsigned 16-bit: 0 - 0xffff. */
#define TCG_CT_CONST_S16 0x200 /* Signed 16-bit: -32768 - 32767 */
#define TCG_CT_CONST_P2M1 0x400 /* Power of 2 minus 1. */
#define TCG_CT_CONST_N16 0x800 /* "Negatable" 16-bit: -32767 - 32767 */
#define TCG_CT_CONST_WSZ 0x1000 /* word size */
#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) {
return 1;
} else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
return 1;
} else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
return 1;
} 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.
*/
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
TCGReg addrlo, TCGReg addrhi,
MemOpIdx oi, bool is_ld)
TCGReg addr, MemOpIdx oi, bool is_ld)
{
TCGType addr_type = s->addr_type;
TCGLabelQemuLdst *ldst = NULL;
@ -1245,8 +1241,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
ldst = new_ldst_label(s);
ldst->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addrlo;
ldst->addrhi_reg = addrhi;
ldst->addr_reg = addr;
/* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
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. */
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);
} else {
tcg_out_dsrl(s, TCG_TMP3, addrlo,
s->page_bits - CPU_TLB_ENTRY_BITS);
tcg_out_dsrl(s, TCG_TMP3, addr, s->page_bits - CPU_TLB_ENTRY_BITS);
}
tcg_out_opc_reg(s, OPC_AND, TCG_TMP3, TCG_TMP3, TCG_TMP0);
/* Add the tlb_table pointer, creating the CPUTLBEntry address. */
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 (low half) tlb comparator. */
/* Load the tlb comparator. */
if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
tcg_out_ld(s, TCG_TYPE_I32, TCG_TMP0, TCG_TMP3,
cmp_off + HOST_BIG_ENDIAN * 4);
} 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. */
tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP3, TCG_TMP3, add_off);
}
/* Load the tlb addend for the fast path. */
tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP3, TCG_TMP3, add_off);
/*
* 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
|| addr_type == TCG_TYPE_I32
? 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);
} 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. */
if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
tcg_out_ext32u(s, TCG_TMP2, addrlo);
addrlo = TCG_TMP2;
tcg_out_ext32u(s, TCG_TMP2, addr);
addr = TCG_TMP2;
}
ldst->label_ptr[0] = s->code_ptr;
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 */
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 {
if (a_mask && (use_mips32r6_instructions || a_bits != s_bits)) {
ldst = new_ldst_label(s);
ldst->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addrlo;
ldst->addrhi_reg = addrhi;
ldst->addr_reg = addr;
/* We are expecting a_bits to max out at 7, much lower than ANDI. */
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;
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) {
tcg_out_ext32u(s, TCG_REG_A0, base);
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,
TCGReg addrlo, TCGReg addrhi,
MemOpIdx oi, TCGType data_type)
TCGReg addr, MemOpIdx oi, TCGType data_type)
{
MemOp opc = get_memop(oi);
TCGLabelQemuLdst *ldst;
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)) {
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,
TCGReg addrlo, TCGReg addrhi,
MemOpIdx oi, TCGType data_type)
TCGReg addr, MemOpIdx oi, TCGType data_type)
{
MemOp opc = get_memop(oi);
TCGLabelQemuLdst *ldst;
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)) {
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;
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];
a1 = args[1];
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]);
break;
case INDEX_op_qemu_ld_a64_i32:
if (TCG_TARGET_REG_BITS == 32) {
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);
case INDEX_op_qemu_ld_i32:
tcg_out_qemu_ld(s, a0, 0, a1, a2, TCG_TYPE_I32);
break;
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_i64:
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 {
tcg_out_qemu_ld(s, a0, a1, a2, 0, 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);
tcg_out_qemu_ld(s, a0, a1, a2, args[3], TCG_TYPE_I64);
}
break;
case INDEX_op_qemu_st_a64_i32:
if (TCG_TARGET_REG_BITS == 32) {
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);
case INDEX_op_qemu_st_i32:
tcg_out_qemu_st(s, a0, 0, a1, a2, TCG_TYPE_I32);
break;
case INDEX_op_qemu_st_a32_i64:
case INDEX_op_qemu_st_i64:
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 {
tcg_out_qemu_st(s, a0, a1, a2, 0, 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);
tcg_out_qemu_st(s, a0, a1, a2, args[3], TCG_TYPE_I64);
}
break;
@ -2227,14 +2173,14 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_st16_i64:
case INDEX_op_st32_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_i64:
return C_O1_I2(r, r, rJ);
case INDEX_op_sub_i32:
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_mulsh_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_nor_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_mulu2_i32:
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);
case INDEX_op_clz_i32:
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_i64:
return C_O1_I2(r, 0, rZ);
return C_O1_I2(r, 0, rz);
case INDEX_op_brcond_i32:
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_i64:
return (use_mips32r6_instructions
? C_O1_I4(r, rZ, rZ, rZ, rZ)
: C_O1_I4(r, rZ, rZ, rZ, 0));
? C_O1_I4(r, rz, rz, rz, rz)
: C_O1_I4(r, rz, rz, rz, 0));
case INDEX_op_add2_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:
return C_O1_I4(r, rZ, rZ, rZ, rZ);
return C_O1_I4(r, rz, rz, rz, rz);
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);
case INDEX_op_qemu_ld_a64_i32:
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O1_I2(r, r, r);
case INDEX_op_qemu_st_a32_i32:
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:
case INDEX_op_qemu_st_i32:
return C_O0_I2(rz, r);
case INDEX_op_qemu_ld_i64:
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_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));
case INDEX_op_qemu_st_i64:
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(rz, r) : C_O0_I3(rz, rz, r);
default:
return C_NotImplemented;

View File

@ -70,4 +70,6 @@ typedef enum {
TCG_AREG0 = TCG_REG_S8,
} TCGReg;
#define TCG_REG_ZERO TCG_REG_ZERO
#endif

View File

@ -3011,29 +3011,22 @@ void tcg_optimize(TCGContext *s)
CASE_OP_32_64_VEC(orc):
done = fold_orc(&ctx, op);
break;
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_ld_a64_i32:
case INDEX_op_qemu_ld_i32:
done = fold_qemu_ld_1reg(&ctx, op);
break;
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_a64_i64:
case INDEX_op_qemu_ld_i64:
if (TCG_TARGET_REG_BITS == 64) {
done = fold_qemu_ld_1reg(&ctx, op);
break;
}
QEMU_FALLTHROUGH;
case INDEX_op_qemu_ld_a32_i128:
case INDEX_op_qemu_ld_a64_i128:
case INDEX_op_qemu_ld_i128:
done = fold_qemu_ld_2reg(&ctx, op);
break;
case INDEX_op_qemu_st8_a32_i32:
case INDEX_op_qemu_st8_a64_i32:
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_a64_i32:
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:
case INDEX_op_qemu_st8_i32:
case INDEX_op_qemu_st_i32:
case INDEX_op_qemu_st_i64:
case INDEX_op_qemu_st_i128:
done = fold_qemu_st(&ctx, op);
break;
CASE_OP_32_64(rem):

View File

@ -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.
*/
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
TCGReg addrlo, TCGReg addrhi,
MemOpIdx oi, bool is_ld)
TCGReg addr, MemOpIdx oi, bool is_ld)
{
TCGType addr_type = s->addr_type;
TCGLabelQemuLdst *ldst = NULL;
@ -2474,8 +2473,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
ldst = new_ldst_label(s);
ldst->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addrlo;
ldst->addrhi_reg = addrhi;
ldst->addr_reg = addr;
/* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
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. */
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);
} else {
tcg_out_shri64(s, TCG_REG_R0, addrlo,
tcg_out_shri64(s, TCG_REG_R0, addr,
s->page_bits - CPU_TLB_ENTRY_BITS);
}
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.
* We will ignore the high bits with tcg_out_cmp(..., addr_type).
*/
if (TCG_TARGET_REG_BITS == 64) {
if (cmp_off == 0) {
tcg_out32(s, LDUX | TAB(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));
if (cmp_off == 0) {
tcg_out32(s, (TCG_TARGET_REG_BITS == 64 ? LDUX : LWZUX)
| TAB(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_I32, TCG_REG_TMP2, TCG_REG_TMP1,
cmp_off + 4 * HOST_BIG_ENDIAN);
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_REG_TMP1, cmp_off);
}
/*
@ -2534,10 +2521,10 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
if (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);
} else {
TCGReg t = addrlo;
TCGReg t = addr;
/*
* 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) {
/* Low part comparison into cr7. */
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);
}
/* 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. */
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->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addrlo;
ldst->addrhi_reg = addrhi;
ldst->addr_reg = addr;
/* We are expecting a_bits to max out at 7, much lower than ANDI. */
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;
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) {
/* 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;
} else {
h->index = addrlo;
h->index = addr;
}
return ldst;
}
static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
TCGReg addrlo, TCGReg addrhi,
MemOpIdx oi, TCGType data_type)
TCGReg addr, MemOpIdx oi, TCGType data_type)
{
MemOp opc = get_memop(oi);
TCGLabelQemuLdst *ldst;
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 (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,
TCGReg addrlo, TCGReg addrhi,
MemOpIdx oi, TCGType data_type)
TCGReg addr, MemOpIdx oi, TCGType data_type)
{
MemOp opc = get_memop(oi);
TCGLabelQemuLdst *ldst;
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 (opc & MO_BSWAP) {
@ -2729,7 +2691,7 @@ static void tcg_out_qemu_ldst_i128(TCGContext *s, TCGReg datalo, TCGReg datahi,
uint32_t insn;
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. */
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]));
break;
case INDEX_op_qemu_ld_a64_i32:
if (TCG_TARGET_REG_BITS == 32) {
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);
case INDEX_op_qemu_ld_i32:
tcg_out_qemu_ld(s, args[0], -1, args[1], args[2], TCG_TYPE_I32);
break;
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_i64:
if (TCG_TARGET_REG_BITS == 64) {
tcg_out_qemu_ld(s, args[0], -1, args[1], -1,
args[2], TCG_TYPE_I64);
tcg_out_qemu_ld(s, args[0], -1, args[1], args[2], TCG_TYPE_I64);
} 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);
}
break;
case INDEX_op_qemu_ld_a64_i64:
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:
case INDEX_op_qemu_ld_i128:
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], true);
break;
case INDEX_op_qemu_st_a64_i32:
if (TCG_TARGET_REG_BITS == 32) {
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);
case INDEX_op_qemu_st_i32:
tcg_out_qemu_st(s, args[0], -1, args[1], args[2], TCG_TYPE_I32);
break;
case INDEX_op_qemu_st_a32_i64:
case INDEX_op_qemu_st_i64:
if (TCG_TARGET_REG_BITS == 64) {
tcg_out_qemu_st(s, args[0], -1, args[1], -1,
args[2], TCG_TYPE_I64);
tcg_out_qemu_st(s, args[0], -1, args[1], args[2], TCG_TYPE_I64);
} 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);
}
break;
case INDEX_op_qemu_st_a64_i64:
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:
case INDEX_op_qemu_st_i128:
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], false);
break;
@ -4306,29 +4232,19 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_sub2_i32:
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);
case INDEX_op_qemu_ld_a64_i32:
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O1_I2(r, r, r);
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_i64:
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);
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);
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_a64_i128:
case INDEX_op_qemu_ld_i128:
return C_N1O1_I1(o, m, r);
case INDEX_op_qemu_st_a32_i128:
case INDEX_op_qemu_st_a64_i128:
case INDEX_op_qemu_st_i128:
return C_O0_I3(o, m, r);
case INDEX_op_add_vec:

View File

@ -10,17 +10,17 @@
* tcg-target-con-str.h; the constraint combination is inclusive or.
*/
C_O0_I1(r)
C_O0_I2(rZ, r)
C_O0_I2(rZ, rZ)
C_O0_I2(rz, r)
C_O0_I2(rz, rz)
C_O1_I1(r, r)
C_O1_I2(r, r, ri)
C_O1_I2(r, r, rI)
C_O1_I2(r, r, rJ)
C_O1_I2(r, rZ, rN)
C_O1_I2(r, rZ, rZ)
C_O1_I2(r, rz, rN)
C_O1_I2(r, rz, rz)
C_N1_I2(r, r, 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_O1_I1(v, r)
C_O1_I1(v, v)

View File

@ -21,4 +21,3 @@ CONST('K', TCG_CT_CONST_S5)
CONST('L', TCG_CT_CONST_CMP_VI)
CONST('N', TCG_CT_CONST_N12)
CONST('M', TCG_CT_CONST_M12)
CONST('Z', TCG_CT_CONST_ZERO)

View File

@ -37,8 +37,6 @@
#define TCG_TARGET_HAS_clz_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_brcond2 1
#define TCG_TARGET_HAS_setcond2 1
#define TCG_TARGET_HAS_qemu_st8_i32 0
#define TCG_TARGET_HAS_negsetcond_i64 1

View File

@ -112,13 +112,12 @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
return TCG_REG_A0 + slot;
}
#define TCG_CT_CONST_ZERO 0x100
#define TCG_CT_CONST_S12 0x200
#define TCG_CT_CONST_N12 0x400
#define TCG_CT_CONST_M12 0x800
#define TCG_CT_CONST_J12 0x1000
#define TCG_CT_CONST_S5 0x2000
#define TCG_CT_CONST_CMP_VI 0x4000
#define TCG_CT_CONST_S12 0x100
#define TCG_CT_CONST_N12 0x200
#define TCG_CT_CONST_M12 0x400
#define TCG_CT_CONST_J12 0x800
#define TCG_CT_CONST_S5 0x1000
#define TCG_CT_CONST_CMP_VI 0x2000
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 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) {
return 1;
}
if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
return 1;
}
if (type >= TCG_TYPE_V64) {
/* Val is replicated by VECE; extract the highest element. */
val >>= (-8 << vece) & 63;
@ -1727,7 +1723,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
ldst = new_ldst_label(s);
ldst->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addr_reg;
ldst->addr_reg = addr_reg;
init_setting_vtype(s);
@ -1790,7 +1786,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
ldst = new_ldst_label(s);
ldst->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addr_reg;
ldst->addr_reg = addr_reg;
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]);
break;
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_ld_a64_i32:
case INDEX_op_qemu_ld_i32:
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
break;
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_a64_i64:
case INDEX_op_qemu_ld_i64:
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I64);
break;
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_a64_i32:
case INDEX_op_qemu_st_i32:
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I32);
break;
case INDEX_op_qemu_st_a32_i64:
case INDEX_op_qemu_st_a64_i64:
case INDEX_op_qemu_st_i64:
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I64);
break;
@ -2685,7 +2677,7 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_st16_i64:
case INDEX_op_st32_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_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_i64:
return C_O1_I2(r, rZ, rN);
return C_O1_I2(r, rz, rN);
case INDEX_op_mul_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_rem_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_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_i64:
return C_O0_I2(rZ, rZ);
return C_O0_I2(rz, rz);
case INDEX_op_movcond_i32:
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_sub2_i32:
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_a64_i32:
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_a64_i64:
case INDEX_op_qemu_ld_i32:
case INDEX_op_qemu_ld_i64:
return C_O1_I1(r, r);
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_a64_i32:
case INDEX_op_qemu_st_a32_i64:
case INDEX_op_qemu_st_a64_i64:
return C_O0_I2(rZ, r);
case INDEX_op_qemu_st_i32:
case INDEX_op_qemu_st_i64:
return C_O0_I2(rz, r);
case INDEX_op_st_vec:
return C_O0_I2(v, r);

View File

@ -57,4 +57,6 @@ typedef enum {
TCG_REG_TMP2 = TCG_REG_T4,
} TCGReg;
#define TCG_REG_ZERO TCG_REG_ZERO
#endif

View File

@ -1920,7 +1920,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
ldst = new_ldst_label(s);
ldst->is_ld = is_ld;
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,
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->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addr_reg;
ldst->addr_reg = addr_reg;
tcg_debug_assert(a_mask <= 0xffff);
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]);
break;
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_ld_a64_i32:
case INDEX_op_qemu_ld_i32:
tcg_out_qemu_ld(s, args[0], args[1], args[2], TCG_TYPE_I32);
break;
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_a64_i64:
case INDEX_op_qemu_ld_i64:
tcg_out_qemu_ld(s, args[0], args[1], args[2], TCG_TYPE_I64);
break;
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_a64_i32:
case INDEX_op_qemu_st_i32:
tcg_out_qemu_st(s, args[0], args[1], args[2], TCG_TYPE_I32);
break;
case INDEX_op_qemu_st_a32_i64:
case INDEX_op_qemu_st_a64_i64:
case INDEX_op_qemu_st_i64:
tcg_out_qemu_st(s, args[0], args[1], args[2], TCG_TYPE_I64);
break;
case INDEX_op_qemu_ld_a32_i128:
case INDEX_op_qemu_ld_a64_i128:
case INDEX_op_qemu_ld_i128:
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], true);
break;
case INDEX_op_qemu_st_a32_i128:
case INDEX_op_qemu_st_a64_i128:
case INDEX_op_qemu_st_i128:
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], false);
break;
@ -3366,21 +3360,15 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_ctpop_i64:
return C_O1_I1(r, r);
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_ld_a64_i32:
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_a64_i64:
case INDEX_op_qemu_ld_i32:
case INDEX_op_qemu_ld_i64:
return C_O1_I1(r, r);
case INDEX_op_qemu_st_a32_i64:
case INDEX_op_qemu_st_a64_i64:
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_a64_i32:
case INDEX_op_qemu_st_i64:
case INDEX_op_qemu_st_i32:
return C_O0_I2(r, r);
case INDEX_op_qemu_ld_a32_i128:
case INDEX_op_qemu_ld_a64_i128:
case INDEX_op_qemu_ld_i128:
return C_O2_I1(o, m, r);
case INDEX_op_qemu_st_a32_i128:
case INDEX_op_qemu_st_a64_i128:
case INDEX_op_qemu_st_i128:
return C_O0_I3(o, m, r);
case INDEX_op_deposit_i32:

View File

@ -10,11 +10,11 @@
* tcg-target-con-str.h; the constraint combination is inclusive or.
*/
C_O0_I1(r)
C_O0_I2(rZ, r)
C_O0_I2(rZ, rJ)
C_O0_I2(rz, r)
C_O0_I2(rz, rJ)
C_O1_I1(r, r)
C_O1_I2(r, r, r)
C_O1_I2(r, rZ, rJ)
C_O1_I4(r, rZ, rJ, rI, 0)
C_O2_I2(r, r, rZ, rJ)
C_O2_I4(r, r, rZ, rZ, rJ, rJ)
C_O1_I2(r, rz, rJ)
C_O1_I4(r, rz, rJ, rI, 0)
C_O2_I2(r, r, rz, rJ)
C_O2_I4(r, r, rz, rz, rJ, rJ)

View File

@ -16,4 +16,3 @@ REGS('r', ALL_GENERAL_REGS)
*/
CONST('I', TCG_CT_CONST_S11)
CONST('J', TCG_CT_CONST_S13)
CONST('Z', TCG_CT_CONST_ZERO)

View File

@ -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_S13 0x200
#define TCG_CT_CONST_ZERO 0x400
#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;
}
if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
return 1;
} else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) {
if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) {
return 1;
} else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13)) {
return 1;
@ -1127,7 +1124,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
ldst = new_ldst_label(s);
ldst->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addr_reg;
ldst->addr_reg = addr_reg;
ldst->label_ptr[0] = s->code_ptr;
/* bne,pn %[xi]cc, label0 */
@ -1147,7 +1144,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
ldst = new_ldst_label(s);
ldst->is_ld = is_ld;
ldst->oi = oi;
ldst->addrlo_reg = addr_reg;
ldst->addr_reg = addr_reg;
ldst->label_ptr[0] = s->code_ptr;
/* 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);
break;
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_ld_a64_i32:
case INDEX_op_qemu_ld_i32:
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
break;
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_a64_i64:
case INDEX_op_qemu_ld_i64:
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I64);
break;
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_a64_i32:
case INDEX_op_qemu_st_i32:
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I32);
break;
case INDEX_op_qemu_st_a32_i64:
case INDEX_op_qemu_st_a64_i64:
case INDEX_op_qemu_st_i64:
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I64);
break;
@ -1570,10 +1563,8 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_extu_i32_i64:
case INDEX_op_extract_i64:
case INDEX_op_sextract_i64:
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_ld_a64_i32:
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_a64_i64:
case INDEX_op_qemu_ld_i32:
case INDEX_op_qemu_ld_i64:
return C_O1_I1(r, r);
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_st32_i64:
case INDEX_op_st_i64:
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_a64_i32:
case INDEX_op_qemu_st_a32_i64:
case INDEX_op_qemu_st_a64_i64:
return C_O0_I2(rZ, r);
case INDEX_op_qemu_st_i32:
case INDEX_op_qemu_st_i64:
return C_O0_I2(rz, r);
case INDEX_op_add_i32:
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_negsetcond_i32:
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_i64:
return C_O0_I2(rZ, rJ);
return C_O0_I2(rz, rJ);
case INDEX_op_movcond_i32:
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_i64:
case INDEX_op_sub2_i32:
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_muls2_i32:
return C_O2_I2(r, r, rZ, rJ);
return C_O2_I2(r, r, rz, rJ);
case INDEX_op_muluh_i64:
return C_O1_I2(r, r, r);

View File

@ -64,6 +64,7 @@ typedef enum {
TCG_REG_I7,
} TCGReg;
#define TCG_AREG0 TCG_REG_I0
#define TCG_AREG0 TCG_REG_I0
#define TCG_REG_ZERO TCG_REG_G0
#endif

View File

@ -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,
TCGTemp *addr, MemOpIdx oi)
{
if (TCG_TARGET_REG_BITS == 64 || tcg_ctx->addr_type == TCG_TYPE_I32) {
if (vh) {
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);
}
if (vh) {
tcg_gen_op4(opc, type, temp_arg(vl), temp_arg(vh), temp_arg(addr), oi);
} else {
/* See TCGV_LOW/HIGH. */
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);
}
tcg_gen_op3(opc, type, temp_arg(vl), temp_arg(addr), oi);
}
}
@ -232,7 +217,6 @@ static void tcg_gen_qemu_ld_i32_int(TCGv_i32 val, TCGTemp *addr,
MemOp orig_memop;
MemOpIdx orig_oi, oi;
TCGv_i64 copy_addr;
TCGOpcode opc;
tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
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);
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
opc = INDEX_op_qemu_ld_a32_i32;
} else {
opc = INDEX_op_qemu_ld_a64_i32;
}
gen_ldst(opc, TCG_TYPE_I32, tcgv_i32_temp(val), NULL, addr, oi);
gen_ldst(INDEX_op_qemu_ld_i32, TCG_TYPE_I32,
tcgv_i32_temp(val), NULL, addr, oi);
plugin_gen_mem_callbacks_i32(val, copy_addr, addr, orig_oi,
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_ctx->addr_type == TCG_TYPE_I32) {
opc = INDEX_op_qemu_st8_a32_i32;
} else {
opc = INDEX_op_qemu_st8_a64_i32;
}
opc = INDEX_op_qemu_st8_i32;
} else {
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
opc = INDEX_op_qemu_st_a32_i32;
} else {
opc = INDEX_op_qemu_st_a64_i32;
}
opc = INDEX_op_qemu_st_i32;
}
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);
@ -344,7 +316,6 @@ static void tcg_gen_qemu_ld_i64_int(TCGv_i64 val, TCGTemp *addr,
MemOp orig_memop;
MemOpIdx orig_oi, oi;
TCGv_i64 copy_addr;
TCGOpcode opc;
if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
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);
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
opc = INDEX_op_qemu_ld_a32_i64;
} else {
opc = INDEX_op_qemu_ld_a64_i64;
}
gen_ldst_i64(opc, val, addr, oi);
gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, oi);
plugin_gen_mem_callbacks_i64(val, copy_addr, addr, orig_oi,
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;
MemOpIdx orig_oi, oi;
TCGOpcode opc;
if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
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);
}
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
opc = INDEX_op_qemu_st_a32_i64;
} else {
opc = INDEX_op_qemu_st_a64_i64;
}
gen_ldst_i64(opc, val, addr, oi);
gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, oi);
plugin_gen_mem_callbacks_i64(val, NULL, addr, orig_oi, QEMU_PLUGIN_MEM_W);
if (swap) {
@ -560,7 +520,6 @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr,
{
MemOpIdx orig_oi;
TCGv_i64 ext_addr = NULL;
TCGOpcode opc;
check_max_alignment(memop_alignment_bits(memop));
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);
}
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
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),
gen_ldst(INDEX_op_qemu_ld_i128, TCG_TYPE_I128, tcgv_i64_temp(lo),
tcgv_i64_temp(hi), addr, oi);
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);
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
* 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);
}
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) {
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);
}
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);
if (need_bswap) {
@ -678,7 +628,6 @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
{
MemOpIdx orig_oi;
TCGv_i64 ext_addr = NULL;
TCGOpcode opc;
check_max_alignment(memop_alignment_bits(memop));
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);
}
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
opc = INDEX_op_qemu_st_a32_i128;
} else {
opc = INDEX_op_qemu_st_a64_i128;
}
gen_ldst(opc, TCG_TYPE_I128, tcgv_i64_temp(lo),
tcgv_i64_temp(hi), addr, oi);
gen_ldst(INDEX_op_qemu_st_i128, TCG_TYPE_I128,
tcgv_i64_temp(lo), tcgv_i64_temp(hi), addr, oi);
if (need_bswap) {
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);
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) {
x = TCGV128_LOW(val);
y = TCGV128_HIGH(val);
@ -748,7 +686,8 @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
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) {
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) {
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);
} 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);
} else {

View File

@ -100,8 +100,7 @@ struct TCGLabelQemuLdst {
bool is_ld; /* qemu_ld: true, qemu_st: false */
MemOpIdx oi;
TCGType type; /* result type of a load */
TCGReg addrlo_reg; /* reg index for low word of guest virtual addr */
TCGReg addrhi_reg; /* reg index for high word of guest virtual addr */
TCGReg addr_reg; /* reg index for guest virtual addr */
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 */
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);
#endif
#ifdef TCG_TARGET_NEED_POOL_LABELS
s->pool_labels = NULL;
#endif
qemu_thread_jit_write();
/* Generate the prologue. */
tcg_target_qemu_prologue(s);
#ifdef TCG_TARGET_NEED_POOL_LABELS
/* Allow the prologue to put e.g. guest_base into a pool entry. */
{
int result = tcg_out_pool_finalize(s);
tcg_debug_assert(result == 0);
}
#endif
prologue_size = tcg_current_code_size(s);
perf_report_prologue(s->code_gen_ptr, prologue_size);
@ -1694,9 +1689,7 @@ void tcg_func_start(TCGContext *s)
s->emit_before_op = NULL;
QSIMPLEQ_INIT(&s->labels);
tcg_debug_assert(s->addr_type == TCG_TYPE_I32 ||
s->addr_type == TCG_TYPE_I64);
tcg_debug_assert(s->addr_type <= TCG_TYPE_REG);
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_goto_tb:
case INDEX_op_goto_ptr:
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_ld_a64_i32:
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_a64_i32:
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:
case INDEX_op_qemu_ld_i32:
case INDEX_op_qemu_st_i32:
case INDEX_op_qemu_ld_i64:
case INDEX_op_qemu_st_i64:
return true;
case INDEX_op_qemu_st8_a32_i32:
case INDEX_op_qemu_st8_a64_i32:
case INDEX_op_qemu_st8_i32:
return TCG_TARGET_HAS_qemu_st8_i32;
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:
case INDEX_op_qemu_ld_i128:
case INDEX_op_qemu_st_i128:
return TCG_TARGET_HAS_qemu_ldst_i128;
case INDEX_op_mov_i32:
@ -2868,20 +2854,13 @@ void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs)
}
i = 1;
break;
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_ld_a64_i32:
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_a64_i32:
case INDEX_op_qemu_st8_a32_i32:
case INDEX_op_qemu_st8_a64_i32:
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:
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:
case INDEX_op_qemu_ld_i32:
case INDEX_op_qemu_st_i32:
case INDEX_op_qemu_st8_i32:
case INDEX_op_qemu_ld_i64:
case INDEX_op_qemu_st_i64:
case INDEX_op_qemu_ld_i128:
case INDEX_op_qemu_st_i128:
{
const char *s_al, *s_op, *s_at;
MemOpIdx oi = op->args[k++];
@ -3244,6 +3223,11 @@ static void process_constraint_sets(void)
case 'i':
args_ct[i].ct |= TCG_CT_CONST;
break;
#ifdef TCG_REG_ZERO
case 'z':
args_ct[i].ct |= TCG_CT_REG_ZERO;
break;
#endif
/* 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];
ts = arg_temp(arg);
if (ts->val_type == TEMP_VAL_CONST
&& 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;
if (ts->val_type == TEMP_VAL_CONST) {
#ifdef TCG_REG_ZERO
if (ts->val == 0 && (arg_ct->ct & TCG_CT_REG_ZERO)) {
/* Hardware zero register: indicate register via non-const. */
const_args[i] = 0;
new_args[i] = TCG_REG_ZERO;
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;
@ -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_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_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;
} else {
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);
next_arg += nmov;
}
@ -6246,21 +6240,22 @@ static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
/* Handle addr argument. */
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,
* after we have processed the register inputs, we will load a
* zero for the high part.
*/
tcg_out_helper_add_mov(mov, loc + HOST_BIG_ENDIAN,
TCG_TYPE_I32, TCG_TYPE_I32,
ldst->addrlo_reg, -1);
ldst->addr_reg, -1);
next_arg += 2;
nmov += 1;
} else {
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;
nmov += n;
}
@ -6308,7 +6303,7 @@ static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
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. */
loc = &info->in[1 + !HOST_BIG_ENDIAN];
tcg_out_helper_load_imm(s, loc->arg_slot, TCG_TYPE_I32, 0, parm);

119
tcg/tci.c
View File

@ -154,16 +154,6 @@ static void tci_args_rrrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
*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,
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;
break;
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_ld_i32:
tci_args_rrm(insn, &r0, &r1, &oi);
taddr = (uint32_t)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:
taddr = regs[r1];
regs[r0] = tci_qemu_ld(env, taddr, oi, tb_ptr);
break;
case INDEX_op_qemu_ld_a32_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:
case INDEX_op_qemu_ld_i64:
if (TCG_TARGET_REG_BITS == 64) {
tci_args_rrm(insn, &r0, &r1, &oi);
taddr = regs[r1];
} else {
tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
taddr = tci_uint64(regs[r3], regs[r2]);
oi = regs[r4];
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
taddr = regs[r2];
oi = regs[r3];
}
do_ld_i64:
tmp64 = tci_qemu_ld(env, taddr, oi, tb_ptr);
if (TCG_TARGET_REG_BITS == 32) {
tci_write_reg64(regs, r1, r0, tmp64);
@ -957,47 +925,23 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
}
break;
case INDEX_op_qemu_st_a32_i32:
case INDEX_op_qemu_st_i32:
tci_args_rrm(insn, &r0, &r1, &oi);
taddr = (uint32_t)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:
taddr = regs[r1];
tci_qemu_st(env, taddr, regs[r0], oi, tb_ptr);
break;
case INDEX_op_qemu_st_a32_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:
case INDEX_op_qemu_st_i64:
if (TCG_TARGET_REG_BITS == 64) {
tci_args_rrm(insn, &r0, &r1, &oi);
tmp64 = regs[r0];
taddr = regs[r1];
} 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]);
taddr = tci_uint64(regs[r3], regs[r2]);
oi = regs[r4];
taddr = regs[r2];
oi = regs[r3];
}
do_st_i64:
tci_qemu_st(env, taddr, tmp64, oi, tb_ptr);
break;
@ -1269,42 +1213,21 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
str_r(r3), str_r(r4), str_r(r5));
break;
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_st_a32_i32:
len = 1 + 1;
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:
case INDEX_op_qemu_ld_i64:
case INDEX_op_qemu_st_i64:
if (TCG_TARGET_REG_BITS == 32) {
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
op_name, str_r(r0), str_r(r1),
str_r(r2), str_r(r3));
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;
case 0:

View File

@ -169,22 +169,14 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_setcond2_i32:
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);
case INDEX_op_qemu_ld_a64_i32:
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O1_I2(r, r, r);
case INDEX_op_qemu_ld_a32_i64:
case INDEX_op_qemu_ld_i64:
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);
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);
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:
return C_NotImplemented;
@ -422,20 +414,6 @@ static void tcg_out_op_rrrbb(TCGContext *s, TCGOpcode op, TCGReg r0,
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,
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]);
break;
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_st_a32_i32:
tcg_out_op_rrm(s, opc, args[0], args[1], args[2]);
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 {
case INDEX_op_qemu_ld_i64:
case INDEX_op_qemu_st_i64:
if (TCG_TARGET_REG_BITS == 32) {
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);
break;
}
break;
case INDEX_op_qemu_ld_a64_i64:
case INDEX_op_qemu_st_a64_i64:
if (TCG_TARGET_REG_BITS == 64) {
tcg_out_op_rrm(s, opc, args[0], args[1], args[2]);
/* fall through */
case INDEX_op_qemu_ld_i32:
case INDEX_op_qemu_st_i32:
if (TCG_TARGET_REG_BITS == 64 && s->addr_type == TCG_TYPE_I32) {
tcg_out_ext32u(s, TCG_REG_TMP, args[1]);
tcg_out_op_rrm(s, opc, args[0], TCG_REG_TMP, args[2]);
} else {
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, args[4]);
tcg_out_op_rrrrr(s, opc, args[0], args[1],
args[2], args[3], TCG_REG_TMP);
tcg_out_op_rrm(s, opc, args[0], args[1], args[2]);
}
break;

View File

@ -72,6 +72,5 @@ typedef enum {
} TCGReg;
#define HAVE_TCG_QEMU_TB_EXEC
#define TCG_TARGET_NEED_POOL_LABELS
#endif /* TCG_TARGET_H */