[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 9/9] tcg-sparc: Define TCG_TARGET_INSN_UNIT_SIZE
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH v2 9/9] tcg-sparc: Define TCG_TARGET_INSN_UNIT_SIZE |
Date: |
Tue, 1 Apr 2014 13:53:34 -0700 |
And use tcg pointer differencing functions as appropriate.
Signed-off-by: Richard Henderson <address@hidden>
---
tcg/sparc/tcg-target.c | 138 ++++++++++++++++++++++---------------------------
tcg/sparc/tcg-target.h | 2 +-
2 files changed, 64 insertions(+), 76 deletions(-)
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 152335c..d4c97e1 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -253,37 +253,32 @@ static inline int check_fit_i32(uint32_t val, unsigned
int bits)
return ((val << (32 - bits)) >> (32 - bits)) == val;
}
-static void patch_reloc(uint8_t *code_ptr, int type,
+static void patch_reloc(tcg_insn_unit *code_ptr, int type,
intptr_t value, intptr_t addend)
{
uint32_t insn;
- value += addend;
+
+ /* Note that we always use 0 for addend in calls to tcg_out_reloc. */
+ value = tcg_ptr_byte_diff((tcg_insn_unit *)value, code_ptr);
+
switch (type) {
- case R_SPARC_32:
- if (value != (uint32_t)value) {
- tcg_abort();
- }
- *(uint32_t *)code_ptr = value;
- break;
case R_SPARC_WDISP16:
- value -= (intptr_t)code_ptr;
if (!check_fit_tl(value >> 2, 16)) {
tcg_abort();
}
- insn = *(uint32_t *)code_ptr;
+ insn = *code_ptr;
insn &= ~INSN_OFF16(-1);
insn |= INSN_OFF16(value);
- *(uint32_t *)code_ptr = insn;
+ *code_ptr = insn;
break;
case R_SPARC_WDISP19:
- value -= (intptr_t)code_ptr;
if (!check_fit_tl(value >> 2, 19)) {
tcg_abort();
}
- insn = *(uint32_t *)code_ptr;
+ insn = *code_ptr;
insn &= ~INSN_OFF19(-1);
insn |= INSN_OFF19(value);
- *(uint32_t *)code_ptr = insn;
+ *code_ptr = insn;
break;
default:
tcg_abort();
@@ -544,10 +539,10 @@ static void tcg_out_bpcc(TCGContext *s, int scond, int
flags, int label)
int off19;
if (l->has_value) {
- off19 = INSN_OFF19(l->u.value - (unsigned long)s->code_ptr);
+ off19 = INSN_OFF19(tcg_pcrel_diff(s, l->u.value_ptr));
} else {
/* Make sure to preserve destinations during retranslation. */
- off19 = *(uint32_t *)s->code_ptr & INSN_OFF19(-1);
+ off19 = *s->code_ptr & INSN_OFF19(-1);
tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, label, 0);
}
tcg_out_bpcc0(s, scond, flags, off19);
@@ -592,10 +587,10 @@ static void tcg_out_brcond_i64(TCGContext *s, TCGCond
cond, TCGArg arg1,
int off16;
if (l->has_value) {
- off16 = INSN_OFF16(l->u.value - (unsigned long)s->code_ptr);
+ off16 = INSN_OFF16(tcg_pcrel_diff(s, l->u.value_ptr));
} else {
/* Make sure to preserve destinations during retranslation. */
- off16 = *(uint32_t *)s->code_ptr & INSN_OFF16(-1);
+ off16 = *s->code_ptr & INSN_OFF16(-1);
tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP16, label, 0);
}
tcg_out32(s, INSN_OP(0) | INSN_OP2(3) | BPR_PT | INSN_RS1(arg1)
@@ -794,62 +789,60 @@ static void tcg_out_addsub2(TCGContext *s, TCGArg rl,
TCGArg rh,
tcg_out_mov(s, TCG_TYPE_I32, rl, tmp);
}
-static inline void tcg_out_calli(TCGContext *s, uintptr_t dest)
+static inline void tcg_out_calli(TCGContext *s, void *dest)
{
- intptr_t disp = dest - (uintptr_t)s->code_ptr;
+ ptrdiff_t disp = tcg_pcrel_diff(s, dest);
if (disp == (int32_t)disp) {
tcg_out32(s, CALL | (uint32_t)disp >> 2);
} else {
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, dest & ~0xfff);
- tcg_out_arithi(s, TCG_REG_O7, TCG_REG_T1, dest & 0xfff, JMPL);
+ uintptr_t desti = (uintptr_t)dest;
+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, desti & ~0xfff);
+ tcg_out_arithi(s, TCG_REG_O7, TCG_REG_T1, desti & 0xfff, JMPL);
}
}
#ifdef CONFIG_SOFTMMU
-static uintptr_t qemu_ld_trampoline[16];
-static uintptr_t qemu_st_trampoline[16];
+static tcg_insn_unit *qemu_ld_trampoline[16];
+static tcg_insn_unit *qemu_st_trampoline[16];
static void build_trampolines(TCGContext *s)
{
- static uintptr_t const qemu_ld_helpers[16] = {
- [MO_UB] = (uintptr_t)helper_ret_ldub_mmu,
- [MO_SB] = (uintptr_t)helper_ret_ldsb_mmu,
- [MO_LEUW] = (uintptr_t)helper_le_lduw_mmu,
- [MO_LESW] = (uintptr_t)helper_le_ldsw_mmu,
- [MO_LEUL] = (uintptr_t)helper_le_ldul_mmu,
- [MO_LEQ] = (uintptr_t)helper_le_ldq_mmu,
- [MO_BEUW] = (uintptr_t)helper_be_lduw_mmu,
- [MO_BESW] = (uintptr_t)helper_be_ldsw_mmu,
- [MO_BEUL] = (uintptr_t)helper_be_ldul_mmu,
- [MO_BEQ] = (uintptr_t)helper_be_ldq_mmu,
+ static void * const qemu_ld_helpers[16] = {
+ [MO_UB] = helper_ret_ldub_mmu,
+ [MO_SB] = helper_ret_ldsb_mmu,
+ [MO_LEUW] = helper_le_lduw_mmu,
+ [MO_LESW] = helper_le_ldsw_mmu,
+ [MO_LEUL] = helper_le_ldul_mmu,
+ [MO_LEQ] = helper_le_ldq_mmu,
+ [MO_BEUW] = helper_be_lduw_mmu,
+ [MO_BESW] = helper_be_ldsw_mmu,
+ [MO_BEUL] = helper_be_ldul_mmu,
+ [MO_BEQ] = helper_be_ldq_mmu,
};
- static uintptr_t const qemu_st_helpers[16] = {
- [MO_UB] = (uintptr_t)helper_ret_stb_mmu,
- [MO_LEUW] = (uintptr_t)helper_le_stw_mmu,
- [MO_LEUL] = (uintptr_t)helper_le_stl_mmu,
- [MO_LEQ] = (uintptr_t)helper_le_stq_mmu,
- [MO_BEUW] = (uintptr_t)helper_be_stw_mmu,
- [MO_BEUL] = (uintptr_t)helper_be_stl_mmu,
- [MO_BEQ] = (uintptr_t)helper_be_stq_mmu,
+ static void * const qemu_st_helpers[16] = {
+ [MO_UB] = helper_ret_stb_mmu,
+ [MO_LEUW] = helper_le_stw_mmu,
+ [MO_LEUL] = helper_le_stl_mmu,
+ [MO_LEQ] = helper_le_stq_mmu,
+ [MO_BEUW] = helper_be_stw_mmu,
+ [MO_BEUL] = helper_be_stl_mmu,
+ [MO_BEQ] = helper_be_stq_mmu,
};
int i;
TCGReg ra;
- uintptr_t tramp;
for (i = 0; i < 16; ++i) {
- if (qemu_ld_helpers[i] == 0) {
+ if (qemu_ld_helpers[i] == NULL) {
continue;
}
/* May as well align the trampoline. */
- tramp = (uintptr_t)s->code_ptr;
- while (tramp & 15) {
+ while ((uintptr_t)s->code_ptr & 15) {
tcg_out_nop(s);
- tramp += 4;
}
- qemu_ld_trampoline[i] = tramp;
+ qemu_ld_trampoline[i] = s->code_ptr;
/* Find the retaddr argument register. */
ra = TCG_REG_O3 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS);
@@ -864,17 +857,15 @@ static void build_trampolines(TCGContext *s)
}
for (i = 0; i < 16; ++i) {
- if (qemu_st_helpers[i] == 0) {
+ if (qemu_st_helpers[i] == NULL) {
continue;
}
/* May as well align the trampoline. */
- tramp = (uintptr_t)s->code_ptr;
- while (tramp & 15) {
+ while ((uintptr_t)s->code_ptr & 15) {
tcg_out_nop(s);
- tramp += 4;
}
- qemu_st_trampoline[i] = tramp;
+ qemu_st_trampoline[i] = s->code_ptr;
/* Find the retaddr argument. For 32-bit, this may be past the
last argument register, and need passing on the stack. */
@@ -1044,9 +1035,9 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg
*args, bool is64)
TCGMemOp memop, s_bits;
#if defined(CONFIG_SOFTMMU)
TCGReg addrz, param;
- uintptr_t func;
+ void *func;
int memi;
- uint32_t *label_ptr[2];
+ tcg_insn_unit *label_ptr[2];
#endif
datalo = *args++;
@@ -1065,7 +1056,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg
*args, bool is64)
int reg64;
/* bne,pn %[xi]cc, label0 */
- label_ptr[0] = (uint32_t *)s->code_ptr;
+ label_ptr[0] = s->code_ptr;
tcg_out_bpcc0(s, COND_NE, BPCC_PN
| (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
tcg_out_nop(s);
@@ -1082,7 +1073,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg
*args, bool is64)
}
/* b,a,pt label1 */
- label_ptr[1] = (uint32_t *)s->code_ptr;
+ label_ptr[1] = s->code_ptr;
tcg_out_bpcc0(s, COND_A, BPCC_A | BPCC_PT, 0);
} else {
/* The fast path is exactly one insn. Thus we can perform the
@@ -1091,7 +1082,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg
*args, bool is64)
/* beq,a,pt %[xi]cc, label0 */
label_ptr[0] = NULL;
- label_ptr[1] = (uint32_t *)s->code_ptr;
+ label_ptr[1] = s->code_ptr;
tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
| (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
/* delay slot */
@@ -1101,8 +1092,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg
*args, bool is64)
/* TLB Miss. */
if (label_ptr[0]) {
- *label_ptr[0] |= INSN_OFF19((unsigned long)s->code_ptr -
- (unsigned long)label_ptr[0]);
+ ptrdiff_t disp = tcg_ptr_byte_diff(s->code_ptr, label_ptr[0]);
+ *label_ptr[0] |= INSN_OFF19(disp);
}
param = TCG_REG_O1;
@@ -1118,7 +1109,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg
*args, bool is64)
} else {
func = qemu_ld_trampoline[memop];
}
- assert(func != 0);
+ assert(func != NULL);
tcg_out_calli(s, func);
/* delay slot */
tcg_out_movi(s, TCG_TYPE_I32, param, memi);
@@ -1140,8 +1131,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg
*args, bool is64)
break;
}
- *label_ptr[1] |= INSN_OFF19((unsigned long)s->code_ptr -
- (unsigned long)label_ptr[1]);
+ *label_ptr[1] |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr[1]));
#else
if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
tcg_out_arithi(s, TCG_REG_T1, addrlo, 0, SHIFT_SRL);
@@ -1172,9 +1162,9 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg
*args, bool is64)
TCGMemOp memop, s_bits;
#if defined(CONFIG_SOFTMMU)
TCGReg addrz, datafull, param;
- uintptr_t func;
+ void *func;
int memi;
- uint32_t *label_ptr;
+ tcg_insn_unit *label_ptr;
#endif
datalo = *args++;
@@ -1201,7 +1191,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg
*args, bool is64)
/* The fast path is exactly one insn. Thus we can perform the entire
TLB Hit in the (annulled) delay slot of the branch over TLB Miss. */
/* beq,a,pt %[xi]cc, label0 */
- label_ptr = (uint32_t *)s->code_ptr;
+ label_ptr = s->code_ptr;
tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
| (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
/* delay slot */
@@ -1220,13 +1210,12 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg
*args, bool is64)
tcg_out_mov(s, TCG_TYPE_REG, param++, datalo);
func = qemu_st_trampoline[memop];
- assert(func != 0);
+ assert(func != NULL);
tcg_out_calli(s, func);
/* delay slot */
tcg_out_movi(s, TCG_TYPE_REG, param, memi);
- *label_ptr |= INSN_OFF19((unsigned long)s->code_ptr -
- (unsigned long)label_ptr);
+ *label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
#else
if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
tcg_out_arithi(s, TCG_REG_T1, addrlo, 0, SHIFT_SRL);
@@ -1259,21 +1248,20 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode
opc, const TCGArg *args,
case INDEX_op_goto_tb:
if (s->tb_jmp_offset) {
/* direct jump method */
- uint32_t old_insn = *(uint32_t *)s->code_ptr;
- s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
+ s->tb_jmp_offset[args[0]] = tcg_current_code_size(s);
/* Make sure to preserve links during retranslation. */
- tcg_out32(s, CALL | (old_insn & ~INSN_OP(-1)));
+ tcg_out32(s, CALL | (*s->code_ptr & ~INSN_OP(-1)));
} else {
/* indirect jump method */
tcg_out_ld_ptr(s, TCG_REG_T1, (uintptr_t)(s->tb_next + args[0]));
tcg_out_arithi(s, TCG_REG_G0, TCG_REG_T1, 0, JMPL);
}
tcg_out_nop(s);
- s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
+ s->tb_next_offset[args[0]] = tcg_current_code_size(s);
break;
case INDEX_op_call:
if (const_args[0]) {
- tcg_out_calli(s, args[0]);
+ tcg_out_calli(s, (void *)(uintptr_t)args[0]);
} else {
tcg_out_arithi(s, TCG_REG_O7, args[0], 0, JMPL);
}
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index 3abf1b4..da5a0ef 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -33,7 +33,7 @@
#endif
#define TCG_TARGET_WORDS_BIGENDIAN
-
+#define TCG_TARGET_INSN_UNIT_SIZE 4
#define TCG_TARGET_NB_REGS 32
typedef enum {
--
1.9.0
- [Qemu-devel] [PATCH v2 1/9] exec-all.h: Use stl_p to avoid undefined behaviour patching x86 jumps, (continued)
- [Qemu-devel] [PATCH v2 1/9] exec-all.h: Use stl_p to avoid undefined behaviour patching x86 jumps, Richard Henderson, 2014/04/01
- [Qemu-devel] [PATCH v2 2/9] tcg: Avoid stores to unaligned addresses, Richard Henderson, 2014/04/01
- [Qemu-devel] [PATCH v2 3/9] tcg: Avoid undefined behaviour patching code at unaligned addresses, Richard Henderson, 2014/04/01
- [Qemu-devel] [PATCH v2 4/9] tcg: Introduce byte pointer arithmetic helpers, Richard Henderson, 2014/04/01
- [Qemu-devel] [PATCH v2 5/9] tcg: Define tcg_insn_unit for code pointers, Richard Henderson, 2014/04/01
- [Qemu-devel] [PATCH v2 6/9] tcg-i386: Define TCG_TARGET_INSN_UNIT_SIZE, Richard Henderson, 2014/04/01
- [Qemu-devel] [PATCH v2 7/9] tcg-ppc64: Define TCG_TARGET_INSN_UNIT_SIZE, Richard Henderson, 2014/04/01
- [Qemu-devel] [PATCH v2 8/9] tcg-ppc: Define TCG_TARGET_INSN_UNIT_SIZE, Richard Henderson, 2014/04/01
- [Qemu-devel] [PATCH v2 9/9] tcg-sparc: Define TCG_TARGET_INSN_UNIT_SIZE,
Richard Henderson <=
- Re: [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr, Peter Maydell, 2014/04/01