From 59227d5d45bb3c31dc2118011691c35b3c00879c Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 12 May 2015 11:51:44 -0700 Subject: tcg: Merge memop and mmu_idx parameters to qemu_ld/st At the tcg opcode level, not at the tcg-op.h generator level. This requires minor changes through all of the tcg backends, but none of the cpu translators. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c | 12 ++++++++---- tcg/arm/tcg-target.c | 12 ++++++++---- tcg/i386/tcg-target.c | 12 ++++++++---- tcg/ia64/tcg-target.c | 12 ++++++++---- tcg/mips/tcg-target.c | 12 ++++++++---- tcg/optimize.c | 3 ++- tcg/ppc/tcg-target.c | 12 ++++++++---- tcg/s390/tcg-target.c | 12 ++++++++---- tcg/sparc/tcg-target.c | 14 +++++++++----- tcg/tcg-op.c | 22 ++++++++++------------ tcg/tcg-opc.h | 8 ++++---- tcg/tcg.c | 16 +++++++++++----- tcg/tcg.h | 38 ++++++++++++++++++++++++++++++++++++++ tcg/tci/tcg-target.c | 6 ------ tci.c | 20 ++++++++++---------- 15 files changed, 140 insertions(+), 71 deletions(-) diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index 87dc245..23b8fda 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -1197,9 +1197,11 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGMemOp memop, } static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, - TCGMemOp memop, TCGType ext, int mem_index) + TCGMemOpIdx oi, TCGType ext) { + TCGMemOp memop = get_memop(oi); #ifdef CONFIG_SOFTMMU + unsigned mem_index = get_mmuidx(oi); TCGMemOp s_bits = memop & MO_SIZE; tcg_insn_unit *label_ptr; @@ -1214,9 +1216,11 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, } static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, - TCGMemOp memop, int mem_index) + TCGMemOpIdx oi) { + TCGMemOp memop = get_memop(oi); #ifdef CONFIG_SOFTMMU + unsigned mem_index = get_mmuidx(oi); TCGMemOp s_bits = memop & MO_SIZE; tcg_insn_unit *label_ptr; @@ -1515,11 +1519,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_qemu_ld_i32: case INDEX_op_qemu_ld_i64: - tcg_out_qemu_ld(s, a0, a1, a2, ext, args[3]); + tcg_out_qemu_ld(s, a0, a1, a2, ext); break; case INDEX_op_qemu_st_i32: case INDEX_op_qemu_st_i64: - tcg_out_qemu_st(s, REG0(0), a1, a2, args[3]); + tcg_out_qemu_st(s, REG0(0), a1, a2); break; case INDEX_op_bswap64_i64: diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index 01e6fbf..f3221e7 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -1463,6 +1463,7 @@ static inline void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp opc, static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64) { TCGReg addrlo, datalo, datahi, addrhi __attribute__((unused)); + TCGMemOpIdx oi; TCGMemOp opc; #ifdef CONFIG_SOFTMMU int mem_index; @@ -1474,10 +1475,11 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64) datahi = (is64 ? *args++ : 0); addrlo = *args++; addrhi = (TARGET_LONG_BITS == 64 ? *args++ : 0); - opc = *args++; + oi = *args++; + opc = get_memop(oi); #ifdef CONFIG_SOFTMMU - mem_index = *args; + mem_index = get_mmuidx(oi); addend = tcg_out_tlb_read(s, addrlo, addrhi, opc & MO_SIZE, mem_index, 1); /* This a conditional BL only to load a pointer within this opcode into LR @@ -1592,6 +1594,7 @@ static inline void tcg_out_qemu_st_direct(TCGContext *s, TCGMemOp opc, static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64) { TCGReg addrlo, datalo, datahi, addrhi __attribute__((unused)); + TCGMemOpIdx oi; TCGMemOp opc; #ifdef CONFIG_SOFTMMU int mem_index; @@ -1603,10 +1606,11 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64) datahi = (is64 ? *args++ : 0); addrlo = *args++; addrhi = (TARGET_LONG_BITS == 64 ? *args++ : 0); - opc = *args++; + oi = *args++; + opc = get_memop(oi); #ifdef CONFIG_SOFTMMU - mem_index = *args; + mem_index = get_mmuidx(oi); addend = tcg_out_tlb_read(s, addrlo, addrhi, opc & MO_SIZE, mem_index, 0); tcg_out_qemu_st_index(s, COND_EQ, opc, datalo, datahi, addrlo, addend); diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index ab63823..a458c8a 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -1531,6 +1531,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64) { TCGReg datalo, datahi, addrlo; TCGReg addrhi __attribute__((unused)); + TCGMemOpIdx oi; TCGMemOp opc; #if defined(CONFIG_SOFTMMU) int mem_index; @@ -1542,10 +1543,11 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64) datahi = (TCG_TARGET_REG_BITS == 32 && is64 ? *args++ : 0); addrlo = *args++; addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0); - opc = *args++; + oi = *args++; + opc = get_memop(oi); #if defined(CONFIG_SOFTMMU) - mem_index = *args++; + mem_index = get_mmuidx(oi); s_bits = opc & MO_SIZE; tcg_out_tlb_load(s, addrlo, addrhi, mem_index, s_bits, @@ -1662,6 +1664,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64) { TCGReg datalo, datahi, addrlo; TCGReg addrhi __attribute__((unused)); + TCGMemOpIdx oi; TCGMemOp opc; #if defined(CONFIG_SOFTMMU) int mem_index; @@ -1673,10 +1676,11 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64) datahi = (TCG_TARGET_REG_BITS == 32 && is64 ? *args++ : 0); addrlo = *args++; addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0); - opc = *args++; + oi = *args++; + opc = get_memop(oi); #if defined(CONFIG_SOFTMMU) - mem_index = *args++; + mem_index = get_mmuidx(oi); s_bits = opc & MO_SIZE; tcg_out_tlb_load(s, addrlo, addrhi, mem_index, s_bits, diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c index 25f207d..1920593 100644 --- a/tcg/ia64/tcg-target.c +++ b/tcg/ia64/tcg-target.c @@ -1634,14 +1634,16 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args) OPC_LD1_M1, OPC_LD2_M1, OPC_LD4_M1, OPC_LD8_M1 }; int addr_reg, data_reg, mem_index; + TCGMemOpIdx oi; TCGMemOp opc, s_bits; uint64_t fin1, fin2; tcg_insn_unit *label_ptr; data_reg = args[0]; addr_reg = args[1]; - opc = args[2]; - mem_index = args[3]; + oi = args[2]; + opc = get_memop(oi); + mem_index = get_mmuidx(oi); s_bits = opc & MO_SIZE; /* Read the TLB entry */ @@ -1696,13 +1698,15 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args) TCGReg addr_reg, data_reg; int mem_index; uint64_t pre1, pre2; + TCGMemOpIdx oi; TCGMemOp opc, s_bits; tcg_insn_unit *label_ptr; data_reg = args[0]; addr_reg = args[1]; - opc = args[2]; - mem_index = args[3]; + oi = args[2]; + opc = get_memop(oi); + mem_index = get_mmuidx(oi); s_bits = opc & MO_SIZE; /* Note that we always use LE helper functions, so the bswap insns diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index 5414b83..3f86182 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -1150,6 +1150,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64) { TCGReg addr_regl, addr_regh __attribute__((unused)); TCGReg data_regl, data_regh; + TCGMemOpIdx oi; TCGMemOp opc; #if defined(CONFIG_SOFTMMU) tcg_insn_unit *label_ptr[2]; @@ -1164,10 +1165,11 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64) data_regh = (is_64 ? *args++ : 0); addr_regl = *args++; addr_regh = (TARGET_LONG_BITS == 64 ? *args++ : 0); - opc = *args++; + oi = *args++; + opc = get_memop(oi); #if defined(CONFIG_SOFTMMU) - mem_index = *args; + mem_index = get_mmuidx(oi); s_bits = opc & MO_SIZE; tcg_out_tlb_load(s, base, addr_regl, addr_regh, mem_index, @@ -1279,6 +1281,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64) { TCGReg addr_regl, addr_regh __attribute__((unused)); TCGReg data_regl, data_regh, base; + TCGMemOpIdx oi; TCGMemOp opc; #if defined(CONFIG_SOFTMMU) tcg_insn_unit *label_ptr[2]; @@ -1290,10 +1293,11 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64) data_regh = (is_64 ? *args++ : 0); addr_regl = *args++; addr_regh = (TARGET_LONG_BITS == 64 ? *args++ : 0); - opc = *args++; + oi = *args++; + opc = get_memop(oi); #if defined(CONFIG_SOFTMMU) - mem_index = *args; + mem_index = get_mmuidx(oi); s_bits = opc & 3; /* Note that we eliminated the helper's address argument, diff --git a/tcg/optimize.c b/tcg/optimize.c index 37c1110..585f1ed 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -918,7 +918,8 @@ static void tcg_constant_folding(TCGContext *s) CASE_OP_32_64(qemu_ld): { - TCGMemOp mop = args[nb_oargs + nb_iargs]; + TCGMemOpIdx oi = args[nb_oargs + nb_iargs]; + TCGMemOp mop = get_memop(oi); if (!(mop & MO_SIGN)) { mask = (2ULL << ((8 << (mop & MO_SIZE)) - 1)) - 1; } diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 36fd314..b9d02c4 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -1575,6 +1575,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64) { TCGReg datalo, datahi, addrlo, rbase; TCGReg addrhi __attribute__((unused)); + TCGMemOpIdx oi; TCGMemOp opc, s_bits; #ifdef CONFIG_SOFTMMU int mem_index; @@ -1585,11 +1586,12 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64) datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0); addrlo = *args++; addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0); - opc = *args++; + oi = *args++; + opc = get_memop(oi); s_bits = opc & MO_SIZE; #ifdef CONFIG_SOFTMMU - mem_index = *args; + mem_index = get_mmuidx(oi); addrlo = tcg_out_tlb_read(s, s_bits, addrlo, addrhi, mem_index, true); /* Load a pointer into the current opcode w/conditional branch-link. */ @@ -1648,6 +1650,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64) { TCGReg datalo, datahi, addrlo, rbase; TCGReg addrhi __attribute__((unused)); + TCGMemOpIdx oi; TCGMemOp opc, s_bits; #ifdef CONFIG_SOFTMMU int mem_index; @@ -1658,11 +1661,12 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64) datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0); addrlo = *args++; addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0); - opc = *args++; + oi = *args++; + opc = get_memop(oi); s_bits = opc & MO_SIZE; #ifdef CONFIG_SOFTMMU - mem_index = *args; + mem_index = get_mmuidx(oi); addrlo = tcg_out_tlb_read(s, s_bits, addrlo, addrhi, mem_index, false); /* Load a pointer into the current opcode w/conditional branch-link. */ diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c index be984f5..10577ab 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c @@ -1632,9 +1632,11 @@ static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg, #endif /* CONFIG_SOFTMMU */ static void tcg_out_qemu_ld(TCGContext* s, TCGReg data_reg, TCGReg addr_reg, - TCGMemOp opc, int mem_index) + TCGMemOpIdx oi) { + TCGMemOp opc = get_memop(oi); #ifdef CONFIG_SOFTMMU + unsigned mem_index = get_mmuidx(oi); tcg_insn_unit *label_ptr; TCGReg base_reg; @@ -1657,9 +1659,11 @@ static void tcg_out_qemu_ld(TCGContext* s, TCGReg data_reg, TCGReg addr_reg, } static void tcg_out_qemu_st(TCGContext* s, TCGReg data_reg, TCGReg addr_reg, - TCGMemOp opc, int mem_index) + TCGMemOpIdx oi) { + TCGMemOp opc = get_memop(oi); #ifdef CONFIG_SOFTMMU + unsigned mem_index = get_mmuidx(oi); tcg_insn_unit *label_ptr; TCGReg base_reg; @@ -1920,11 +1924,11 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_qemu_ld_i32: /* ??? Technically we can use a non-extending instruction. */ case INDEX_op_qemu_ld_i64: - tcg_out_qemu_ld(s, args[0], args[1], args[2], args[3]); + tcg_out_qemu_ld(s, args[0], args[1], args[2]); break; case INDEX_op_qemu_st_i32: case INDEX_op_qemu_st_i64: - tcg_out_qemu_st(s, args[0], args[1], args[2], args[3]); + tcg_out_qemu_st(s, args[0], args[1], args[2]); break; case INDEX_op_ld16s_i64: diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index f9b616f..ccc3173 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -1070,9 +1070,11 @@ static const int qemu_st_opc[16] = { }; static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr, - TCGMemOp memop, int memi, bool is_64) + TCGMemOpIdx oi, bool is_64) { + TCGMemOp memop = get_memop(oi); #ifdef CONFIG_SOFTMMU + unsigned memi = get_mmuidx(oi); TCGMemOp s_bits = memop & MO_SIZE; TCGReg addrz, param; tcg_insn_unit *func; @@ -1150,9 +1152,11 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr, } static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr, - TCGMemOp memop, int memi) + TCGMemOpIdx oi) { + TCGMemOp memop = get_memop(oi); #ifdef CONFIG_SOFTMMU + unsigned memi = get_mmuidx(oi); TCGMemOp s_bits = memop & MO_SIZE; TCGReg addrz, param; tcg_insn_unit *func; @@ -1363,14 +1367,14 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, break; case INDEX_op_qemu_ld_i32: - tcg_out_qemu_ld(s, a0, a1, a2, args[3], false); + tcg_out_qemu_ld(s, a0, a1, a2, false); break; case INDEX_op_qemu_ld_i64: - tcg_out_qemu_ld(s, a0, a1, a2, args[3], true); + tcg_out_qemu_ld(s, a0, a1, a2, true); break; case INDEX_op_qemu_st_i32: case INDEX_op_qemu_st_i64: - tcg_out_qemu_st(s, a0, a1, a2, args[3]); + tcg_out_qemu_st(s, a0, a1, a2); break; case INDEX_op_ld32s_i64: diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index 2b6be75..45098c3 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -1873,15 +1873,14 @@ static inline TCGMemOp tcg_canonicalize_memop(TCGMemOp op, bool is64, bool st) static void gen_ldst_i32(TCGOpcode opc, TCGv_i32 val, TCGv addr, TCGMemOp memop, TCGArg idx) { + TCGMemOpIdx oi = make_memop_idx(memop, idx); #if TARGET_LONG_BITS == 32 - tcg_gen_op4ii_i32(opc, val, addr, memop, idx); + tcg_gen_op3i_i32(opc, val, addr, oi); #else if (TCG_TARGET_REG_BITS == 32) { - tcg_gen_op5ii_i32(opc, val, TCGV_LOW(addr), TCGV_HIGH(addr), - memop, idx); + tcg_gen_op4i_i32(opc, val, TCGV_LOW(addr), TCGV_HIGH(addr), oi); } else { - tcg_gen_op4(&tcg_ctx, opc, GET_TCGV_I32(val), GET_TCGV_I64(addr), - memop, idx); + tcg_gen_op3(&tcg_ctx, opc, GET_TCGV_I32(val), GET_TCGV_I64(addr), oi); } #endif } @@ -1889,20 +1888,19 @@ static void gen_ldst_i32(TCGOpcode opc, TCGv_i32 val, TCGv addr, static void gen_ldst_i64(TCGOpcode opc, TCGv_i64 val, TCGv addr, TCGMemOp memop, TCGArg idx) { + TCGMemOpIdx oi = make_memop_idx(memop, idx); #if TARGET_LONG_BITS == 32 if (TCG_TARGET_REG_BITS == 32) { - tcg_gen_op5ii_i32(opc, TCGV_LOW(val), TCGV_HIGH(val), - addr, memop, idx); + tcg_gen_op4i_i32(opc, TCGV_LOW(val), TCGV_HIGH(val), addr, oi); } else { - tcg_gen_op4(&tcg_ctx, opc, GET_TCGV_I64(val), GET_TCGV_I32(addr), - memop, idx); + tcg_gen_op3(&tcg_ctx, opc, GET_TCGV_I64(val), GET_TCGV_I32(addr), oi); } #else if (TCG_TARGET_REG_BITS == 32) { - tcg_gen_op6ii_i32(opc, TCGV_LOW(val), TCGV_HIGH(val), - TCGV_LOW(addr), TCGV_HIGH(addr), memop, idx); + tcg_gen_op5i_i32(opc, TCGV_LOW(val), TCGV_HIGH(val), + TCGV_LOW(addr), TCGV_HIGH(addr), oi); } else { - tcg_gen_op4ii_i64(opc, val, addr, memop, idx); + tcg_gen_op3i_i64(opc, val, addr, oi); } #endif } diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h index 42d0cfe..13ccb60 100644 --- a/tcg/tcg-opc.h +++ b/tcg/tcg-opc.h @@ -179,13 +179,13 @@ DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_END) #define TLADDR_ARGS (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? 1 : 2) #define DATA64_ARGS (TCG_TARGET_REG_BITS == 64 ? 1 : 2) -DEF(qemu_ld_i32, 1, TLADDR_ARGS, 2, +DEF(qemu_ld_i32, 1, TLADDR_ARGS, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS) -DEF(qemu_st_i32, 0, TLADDR_ARGS + 1, 2, +DEF(qemu_st_i32, 0, TLADDR_ARGS + 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS) -DEF(qemu_ld_i64, DATA64_ARGS, TLADDR_ARGS, 2, +DEF(qemu_ld_i64, DATA64_ARGS, TLADDR_ARGS, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT) -DEF(qemu_st_i64, 0, TLADDR_ARGS + DATA64_ARGS, 2, +DEF(qemu_st_i64, 0, TLADDR_ARGS + DATA64_ARGS, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT) #undef TLADDR_ARGS diff --git a/tcg/tcg.c b/tcg/tcg.c index f1558b7..8b43bbb 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1071,12 +1071,18 @@ void tcg_dump_ops(TCGContext *s) case INDEX_op_qemu_st_i32: case INDEX_op_qemu_ld_i64: case INDEX_op_qemu_st_i64: - if (args[k] < ARRAY_SIZE(ldst_name) && ldst_name[args[k]]) { - qemu_log(",%s", ldst_name[args[k++]]); - } else { - qemu_log(",$0x%" TCG_PRIlx, args[k++]); + { + TCGMemOpIdx oi = args[k++]; + TCGMemOp op = get_memop(oi); + unsigned ix = get_mmuidx(oi); + + if (op < ARRAY_SIZE(ldst_name) && ldst_name[op]) { + qemu_log(",%s,%u", ldst_name[op], ix); + } else { + qemu_log(",$0x%x,%u", op, ix); + } + i = 1; } - i = 1; break; default: i = 0; diff --git a/tcg/tcg.h b/tcg/tcg.h index fbb3daf..99d3f14 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -826,6 +826,44 @@ static inline size_t tcg_current_code_size(TCGContext *s) return tcg_ptr_byte_diff(s->code_ptr, s->code_buf); } +/* Combine the TCGMemOp and mmu_idx parameters into a single value. */ +typedef uint32_t TCGMemOpIdx; + +/** + * make_memop_idx + * @op: memory operation + * @idx: mmu index + * + * Encode these values into a single parameter. + */ +static inline TCGMemOpIdx make_memop_idx(TCGMemOp op, unsigned idx) +{ + tcg_debug_assert(idx <= 15); + return (op << 4) | idx; +} + +/** + * get_memop + * @oi: combined op/idx parameter + * + * Extract the memory operation from the combined value. + */ +static inline TCGMemOp get_memop(TCGMemOpIdx oi) +{ + return oi >> 4; +} + +/** + * get_mmuidx + * @oi: combined op/idx parameter + * + * Extract the mmu index from the combined value. + */ +static inline unsigned get_mmuidx(TCGMemOpIdx oi) +{ + return oi & 15; +} + /** * tcg_qemu_tb_exec: * @env: CPUArchState * for the CPU diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c index fb2339d..10affab 100644 --- a/tcg/tci/tcg-target.c +++ b/tcg/tci/tcg-target.c @@ -763,9 +763,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, tcg_out_r(s, *args++); } tcg_out_i(s, *args++); -#ifdef CONFIG_SOFTMMU - tcg_out_i(s, *args); -#endif break; case INDEX_op_qemu_ld_i64: tcg_out_r(s, *args++); @@ -777,9 +774,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, tcg_out_r(s, *args++); } tcg_out_i(s, *args++); -#ifdef CONFIG_SOFTMMU - tcg_out_i(s, *args); -#endif break; case INDEX_op_qemu_st_i32: tcg_out_r(s, *args++); diff --git a/tci.c b/tci.c index 28292b3..800ada8 100644 --- a/tci.c +++ b/tci.c @@ -420,7 +420,7 @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition) } #ifdef CONFIG_SOFTMMU -# define mmuidx tci_read_i(&tb_ptr) +# define mmuidx get_mmuidx(oi) # define qemu_ld_ub \ helper_ret_ldub_mmu(env, taddr, mmuidx, (uintptr_t)tb_ptr) # define qemu_ld_leuw \ @@ -496,7 +496,7 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) #if TCG_TARGET_REG_BITS == 32 uint64_t v64; #endif - TCGMemOp memop; + TCGMemOpIdx oi; #if defined(GETPC) tci_tb_ptr = (uintptr_t)tb_ptr; @@ -1107,8 +1107,8 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) case INDEX_op_qemu_ld_i32: t0 = *tb_ptr++; taddr = tci_read_ulong(&tb_ptr); - memop = tci_read_i(&tb_ptr); - switch (memop) { + oi = tci_read_i(&tb_ptr); + switch (get_memop(oi)) { case MO_UB: tmp32 = qemu_ld_ub; break; @@ -1144,8 +1144,8 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) t1 = *tb_ptr++; } taddr = tci_read_ulong(&tb_ptr); - memop = tci_read_i(&tb_ptr); - switch (memop) { + oi = tci_read_i(&tb_ptr); + switch (get_memop(oi)) { case MO_UB: tmp64 = qemu_ld_ub; break; @@ -1193,8 +1193,8 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) case INDEX_op_qemu_st_i32: t0 = tci_read_r(&tb_ptr); taddr = tci_read_ulong(&tb_ptr); - memop = tci_read_i(&tb_ptr); - switch (memop) { + oi = tci_read_i(&tb_ptr); + switch (get_memop(oi)) { case MO_UB: qemu_st_b(t0); break; @@ -1217,8 +1217,8 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) case INDEX_op_qemu_st_i64: tmp64 = tci_read_r64(&tb_ptr); taddr = tci_read_ulong(&tb_ptr); - memop = tci_read_i(&tb_ptr); - switch (memop) { + oi = tci_read_i(&tb_ptr); + switch (get_memop(oi)) { case MO_UB: qemu_st_b(tmp64); break; -- cgit v1.1 From 3972ef6f830d65e9bacbd31257abedc055fd6dc8 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 13 May 2015 09:10:33 -0700 Subject: tcg: Push merged memop+mmu_idx parameter to softmmu routines The extra information is not yet used but it is now available. This requires minor changes through all of the tcg backends. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson --- softmmu_template.h | 42 ++++++++++++++++++++++++------------------ target-arm/helper.c | 10 ++++++---- tcg/aarch64/tcg-target.c | 35 ++++++++++++++++++----------------- tcg/arm/tcg-target.c | 27 ++++++++++++++------------- tcg/i386/tcg-target.c | 37 ++++++++++++++++++------------------- tcg/ia64/tcg-target.c | 4 ++-- tcg/mips/tcg-target.c | 26 +++++++++++++------------- tcg/ppc/tcg-target.c | 26 +++++++++++++------------- tcg/s390/tcg-target.c | 23 +++++++++++------------ tcg/sparc/tcg-target.c | 6 +++--- tcg/tcg-be-ldst.h | 3 +-- tcg/tcg.h | 38 +++++++++++++++++++------------------- tci.c | 29 ++++++++++++++--------------- 13 files changed, 156 insertions(+), 150 deletions(-) diff --git a/softmmu_template.h b/softmmu_template.h index 16b0852..10820a5 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -168,9 +168,10 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env, #ifdef SOFTMMU_CODE_ACCESS static __attribute__((unused)) #endif -WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, - uintptr_t retaddr) +WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, + TCGMemOpIdx oi, uintptr_t retaddr) { + unsigned mmu_idx = get_mmuidx(oi); int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; uintptr_t haddr; @@ -226,8 +227,8 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, addr2 = addr1 + DATA_SIZE; /* Note the adjustment at the beginning of the function. Undo that for the recursion. */ - res1 = helper_le_ld_name(env, addr1, mmu_idx, retaddr + GETPC_ADJ); - res2 = helper_le_ld_name(env, addr2, mmu_idx, retaddr + GETPC_ADJ); + res1 = helper_le_ld_name(env, addr1, oi, retaddr + GETPC_ADJ); + res2 = helper_le_ld_name(env, addr2, oi, retaddr + GETPC_ADJ); shift = (addr & (DATA_SIZE - 1)) * 8; /* Little-endian combine. */ @@ -256,9 +257,10 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, #ifdef SOFTMMU_CODE_ACCESS static __attribute__((unused)) #endif -WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, - uintptr_t retaddr) +WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, + TCGMemOpIdx oi, uintptr_t retaddr) { + unsigned mmu_idx = get_mmuidx(oi); int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; uintptr_t haddr; @@ -314,8 +316,8 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, addr2 = addr1 + DATA_SIZE; /* Note the adjustment at the beginning of the function. Undo that for the recursion. */ - res1 = helper_be_ld_name(env, addr1, mmu_idx, retaddr + GETPC_ADJ); - res2 = helper_be_ld_name(env, addr2, mmu_idx, retaddr + GETPC_ADJ); + res1 = helper_be_ld_name(env, addr1, oi, retaddr + GETPC_ADJ); + res2 = helper_be_ld_name(env, addr2, oi, retaddr + GETPC_ADJ); shift = (addr & (DATA_SIZE - 1)) * 8; /* Big-endian combine. */ @@ -341,7 +343,8 @@ DATA_TYPE glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, int mmu_idx) { - return helper_te_ld_name (env, addr, mmu_idx, GETRA()); + TCGMemOpIdx oi = make_memop_idx(SHIFT, mmu_idx); + return helper_te_ld_name (env, addr, oi, GETRA()); } #ifndef SOFTMMU_CODE_ACCESS @@ -350,16 +353,16 @@ glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, avoid this for 64-bit data, or for 32-bit data on 32-bit host. */ #if DATA_SIZE * 8 < TCG_TARGET_REG_BITS WORD_TYPE helper_le_lds_name(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr) + TCGMemOpIdx oi, uintptr_t retaddr) { - return (SDATA_TYPE)helper_le_ld_name(env, addr, mmu_idx, retaddr); + return (SDATA_TYPE)helper_le_ld_name(env, addr, oi, retaddr); } # if DATA_SIZE > 1 WORD_TYPE helper_be_lds_name(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr) + TCGMemOpIdx oi, uintptr_t retaddr) { - return (SDATA_TYPE)helper_be_ld_name(env, addr, mmu_idx, retaddr); + return (SDATA_TYPE)helper_be_ld_name(env, addr, oi, retaddr); } # endif #endif @@ -386,8 +389,9 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env, } void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, - int mmu_idx, uintptr_t retaddr) + TCGMemOpIdx oi, uintptr_t retaddr) { + unsigned mmu_idx = get_mmuidx(oi); int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write; uintptr_t haddr; @@ -444,7 +448,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, /* Note the adjustment at the beginning of the function. Undo that for the recursion. */ glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8, - mmu_idx, retaddr + GETPC_ADJ); + oi, retaddr + GETPC_ADJ); } return; } @@ -467,8 +471,9 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, #if DATA_SIZE > 1 void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, - int mmu_idx, uintptr_t retaddr) + TCGMemOpIdx oi, uintptr_t retaddr) { + unsigned mmu_idx = get_mmuidx(oi); int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write; uintptr_t haddr; @@ -525,7 +530,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, /* Note the adjustment at the beginning of the function. Undo that for the recursion. */ glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8, - mmu_idx, retaddr + GETPC_ADJ); + oi, retaddr + GETPC_ADJ); } return; } @@ -547,7 +552,8 @@ void glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, DATA_TYPE val, int mmu_idx) { - helper_te_st_name(env, addr, val, mmu_idx, GETRA()); + TCGMemOpIdx oi = make_memop_idx(SHIFT, mmu_idx); + helper_te_st_name(env, addr, val, oi, GETRA()); } #endif /* !defined(SOFTMMU_CODE_ACCESS) */ diff --git a/target-arm/helper.c b/target-arm/helper.c index f8f8d76..2a68318 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -6013,13 +6013,15 @@ void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in) int maxidx = DIV_ROUND_UP(blocklen, TARGET_PAGE_SIZE); void *hostaddr[maxidx]; int try, i; + unsigned mmu_idx = cpu_mmu_index(env); + TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx); for (try = 0; try < 2; try++) { for (i = 0; i < maxidx; i++) { hostaddr[i] = tlb_vaddr_to_host(env, vaddr + TARGET_PAGE_SIZE * i, - 1, cpu_mmu_index(env)); + 1, mmu_idx); if (!hostaddr[i]) { break; } @@ -6040,12 +6042,12 @@ void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in) * this purpose use the actual register value passed to us * so that we get the fault address right. */ - helper_ret_stb_mmu(env, vaddr_in, 0, cpu_mmu_index(env), GETRA()); + helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETRA()); /* Now we can populate the other TLB entries, if any */ for (i = 0; i < maxidx; i++) { uint64_t va = vaddr + TARGET_PAGE_SIZE * i; if (va != (vaddr_in & TARGET_PAGE_MASK)) { - helper_ret_stb_mmu(env, va, 0, cpu_mmu_index(env), GETRA()); + helper_ret_stb_mmu(env, va, 0, oi, GETRA()); } } } @@ -6062,7 +6064,7 @@ void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in) * bounce buffer was in use */ for (i = 0; i < blocklen; i++) { - helper_ret_stb_mmu(env, vaddr + i, 0, cpu_mmu_index(env), GETRA()); + helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETRA()); } } #else diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index 23b8fda..b3be6f3 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -959,7 +959,7 @@ static inline void tcg_out_addsub2(TCGContext *s, int ext, TCGReg rl, #ifdef CONFIG_SOFTMMU /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr, - * int mmu_idx, uintptr_t ra) + * TCGMemOpIdx oi, uintptr_t ra) */ static void * const qemu_ld_helpers[16] = { [MO_UB] = helper_ret_ldub_mmu, @@ -972,7 +972,8 @@ static void * const qemu_ld_helpers[16] = { }; /* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr, - * uintxx_t val, int mmu_idx, uintptr_t ra) + * uintxx_t val, TCGMemOpIdx oi, + * uintptr_t ra) */ static void * const qemu_st_helpers[16] = { [MO_UB] = helper_ret_stb_mmu, @@ -993,14 +994,15 @@ static inline void tcg_out_adr(TCGContext *s, TCGReg rd, void *target) static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) { - TCGMemOp opc = lb->opc; + TCGMemOpIdx oi = lb->oi; + TCGMemOp opc = get_memop(oi); TCGMemOp size = opc & MO_SIZE; reloc_pc19(lb->label_ptr[0], s->code_ptr); - tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_X0, TCG_AREG0); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_X0, TCG_AREG0); tcg_out_mov(s, TARGET_LONG_BITS == 64, TCG_REG_X1, lb->addrlo_reg); - tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X2, lb->mem_index); + tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X2, oi); tcg_out_adr(s, TCG_REG_X3, lb->raddr); tcg_out_call(s, qemu_ld_helpers[opc & ~MO_SIGN]); if (opc & MO_SIGN) { @@ -1014,33 +1016,32 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) { - TCGMemOp opc = lb->opc; + TCGMemOpIdx oi = lb->oi; + TCGMemOp opc = get_memop(oi); TCGMemOp size = opc & MO_SIZE; reloc_pc19(lb->label_ptr[0], s->code_ptr); - tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_X0, TCG_AREG0); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_X0, TCG_AREG0); tcg_out_mov(s, TARGET_LONG_BITS == 64, TCG_REG_X1, lb->addrlo_reg); tcg_out_mov(s, size == MO_64, TCG_REG_X2, lb->datalo_reg); - tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X3, lb->mem_index); + tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X3, oi); tcg_out_adr(s, TCG_REG_X4, lb->raddr); tcg_out_call(s, qemu_st_helpers[opc]); tcg_out_goto(s, lb->raddr); } -static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc, +static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi, TCGType ext, TCGReg data_reg, TCGReg addr_reg, - int mem_index, tcg_insn_unit *raddr, - tcg_insn_unit *label_ptr) + tcg_insn_unit *raddr, tcg_insn_unit *label_ptr) { TCGLabelQemuLdst *label = new_ldst_label(s); label->is_ld = is_ld; - label->opc = opc; + label->oi = oi; label->type = ext; label->datalo_reg = data_reg; label->addrlo_reg = addr_reg; - label->mem_index = mem_index; label->raddr = raddr; label->label_ptr[0] = label_ptr; } @@ -1207,8 +1208,8 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, tcg_out_tlb_read(s, addr_reg, s_bits, &label_ptr, mem_index, 1); tcg_out_qemu_ld_direct(s, memop, ext, data_reg, addr_reg, TCG_REG_X1); - add_qemu_ldst_label(s, true, memop, ext, data_reg, addr_reg, - mem_index, s->code_ptr, label_ptr); + add_qemu_ldst_label(s, true, oi, ext, data_reg, addr_reg, + s->code_ptr, label_ptr); #else /* !CONFIG_SOFTMMU */ tcg_out_qemu_ld_direct(s, memop, ext, data_reg, addr_reg, GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR); @@ -1226,8 +1227,8 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, tcg_out_tlb_read(s, addr_reg, s_bits, &label_ptr, mem_index, 0); tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg, TCG_REG_X1); - add_qemu_ldst_label(s, false, memop, s_bits == MO_64, data_reg, addr_reg, - mem_index, s->code_ptr, label_ptr); + add_qemu_ldst_label(s, false, oi, s_bits == MO_64, data_reg, addr_reg, + s->code_ptr, label_ptr); #else /* !CONFIG_SOFTMMU */ tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg, GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR); diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index f3221e7..06a8064 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -1221,20 +1221,19 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addrlo, TCGReg addrhi, /* Record the context of a call to the out of line helper code for the slow path for a load or store, so that we can later generate the correct helper code. */ -static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc, +static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi, TCGReg datalo, TCGReg datahi, TCGReg addrlo, - TCGReg addrhi, int mem_index, - tcg_insn_unit *raddr, tcg_insn_unit *label_ptr) + TCGReg addrhi, tcg_insn_unit *raddr, + tcg_insn_unit *label_ptr) { TCGLabelQemuLdst *label = new_ldst_label(s); label->is_ld = is_ld; - label->opc = opc; + label->oi = oi; label->datalo_reg = datalo; label->datahi_reg = datahi; label->addrlo_reg = addrlo; label->addrhi_reg = addrhi; - label->mem_index = mem_index; label->raddr = raddr; label->label_ptr[0] = label_ptr; } @@ -1242,7 +1241,8 @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc, static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) { TCGReg argreg, datalo, datahi; - TCGMemOp opc = lb->opc; + TCGMemOpIdx oi = lb->oi; + TCGMemOp opc = get_memop(oi); void *func; reloc_pc24(lb->label_ptr[0], s->code_ptr); @@ -1253,7 +1253,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) } else { argreg = tcg_out_arg_reg32(s, argreg, lb->addrlo_reg); } - argreg = tcg_out_arg_imm32(s, argreg, lb->mem_index); + argreg = tcg_out_arg_imm32(s, argreg, oi); argreg = tcg_out_arg_reg32(s, argreg, TCG_REG_R14); /* For armv6 we can use the canonical unsigned helpers and minimize @@ -1302,7 +1302,8 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) { TCGReg argreg, datalo, datahi; - TCGMemOp opc = lb->opc; + TCGMemOpIdx oi = lb->oi; + TCGMemOp opc = get_memop(oi); reloc_pc24(lb->label_ptr[0], s->code_ptr); @@ -1332,7 +1333,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) break; } - argreg = tcg_out_arg_imm32(s, argreg, lb->mem_index); + argreg = tcg_out_arg_imm32(s, argreg, oi); argreg = tcg_out_arg_reg32(s, argreg, TCG_REG_R14); /* Tail-call to the helper, which will return to the fast path. */ @@ -1489,8 +1490,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64) tcg_out_qemu_ld_index(s, opc, datalo, datahi, addrlo, addend); - add_qemu_ldst_label(s, true, opc, datalo, datahi, addrlo, addrhi, - mem_index, s->code_ptr, label_ptr); + add_qemu_ldst_label(s, true, oi, datalo, datahi, addrlo, addrhi, + s->code_ptr, label_ptr); #else /* !CONFIG_SOFTMMU */ if (GUEST_BASE) { tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP, GUEST_BASE); @@ -1619,8 +1620,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64) label_ptr = s->code_ptr; tcg_out_bl_noaddr(s, COND_NE); - add_qemu_ldst_label(s, false, opc, datalo, datahi, addrlo, addrhi, - mem_index, s->code_ptr, label_ptr); + add_qemu_ldst_label(s, false, oi, datalo, datahi, addrlo, addrhi, + s->code_ptr, label_ptr); #else /* !CONFIG_SOFTMMU */ if (GUEST_BASE) { tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP, GUEST_BASE); diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index a458c8a..2e4bf52 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -1244,21 +1244,20 @@ static inline void tcg_out_tlb_load(TCGContext *s, TCGReg addrlo, TCGReg addrhi, * Record the context of a call to the out of line helper code for the slow path * for a load or store, so that we can later generate the correct helper code */ -static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc, +static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi, TCGReg datalo, TCGReg datahi, TCGReg addrlo, TCGReg addrhi, - int mem_index, tcg_insn_unit *raddr, + tcg_insn_unit *raddr, tcg_insn_unit **label_ptr) { TCGLabelQemuLdst *label = new_ldst_label(s); label->is_ld = is_ld; - label->opc = opc; + label->oi = oi; label->datalo_reg = datalo; label->datahi_reg = datahi; label->addrlo_reg = addrlo; label->addrhi_reg = addrhi; - label->mem_index = mem_index; label->raddr = raddr; label->label_ptr[0] = label_ptr[0]; if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) { @@ -1271,7 +1270,8 @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc, */ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) { - TCGMemOp opc = l->opc; + TCGMemOpIdx oi = l->oi; + TCGMemOp opc = get_memop(oi); TCGReg data_reg; tcg_insn_unit **label_ptr = &l->label_ptr[0]; @@ -1295,15 +1295,14 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) ofs += 4; } - tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, l->mem_index); + tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, oi); ofs += 4; - tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, (uintptr_t)l->raddr); + tcg_out_sti(s, TCG_TYPE_PTR, TCG_REG_ESP, ofs, (uintptr_t)l->raddr); } else { tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0); /* The second argument is already loaded with addrlo. */ - tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], - l->mem_index); + tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], oi); tcg_out_movi(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[3], (uintptr_t)l->raddr); } @@ -1354,7 +1353,8 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) */ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) { - TCGMemOp opc = l->opc; + TCGMemOpIdx oi = l->oi; + TCGMemOp opc = get_memop(oi); TCGMemOp s_bits = opc & MO_SIZE; tcg_insn_unit **label_ptr = &l->label_ptr[0]; TCGReg retaddr; @@ -1387,19 +1387,18 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) ofs += 4; } - tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, l->mem_index); + tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, oi); ofs += 4; retaddr = TCG_REG_EAX; - tcg_out_movi(s, TCG_TYPE_I32, retaddr, (uintptr_t)l->raddr); - tcg_out_st(s, TCG_TYPE_I32, retaddr, TCG_REG_ESP, ofs); + tcg_out_movi(s, TCG_TYPE_PTR, retaddr, (uintptr_t)l->raddr); + tcg_out_st(s, TCG_TYPE_PTR, retaddr, TCG_REG_ESP, ofs); } else { tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0); /* The second argument is already loaded with addrlo. */ tcg_out_mov(s, (s_bits == MO_64 ? TCG_TYPE_I64 : TCG_TYPE_I32), tcg_target_call_iarg_regs[2], l->datalo_reg); - tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3], - l->mem_index); + tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3], oi); if (ARRAY_SIZE(tcg_target_call_iarg_regs) > 4) { retaddr = tcg_target_call_iarg_regs[4]; @@ -1557,8 +1556,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64) tcg_out_qemu_ld_direct(s, datalo, datahi, TCG_REG_L1, 0, 0, opc); /* Record the current context of a load into ldst label */ - add_qemu_ldst_label(s, true, opc, datalo, datahi, addrlo, addrhi, - mem_index, s->code_ptr, label_ptr); + add_qemu_ldst_label(s, true, oi, datalo, datahi, addrlo, addrhi, + s->code_ptr, label_ptr); #else { int32_t offset = GUEST_BASE; @@ -1690,8 +1689,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64) tcg_out_qemu_st_direct(s, datalo, datahi, TCG_REG_L1, 0, 0, opc); /* Record the current context of a store into ldst label */ - add_qemu_ldst_label(s, false, opc, datalo, datahi, addrlo, addrhi, - mem_index, s->code_ptr, label_ptr); + add_qemu_ldst_label(s, false, oi, datalo, datahi, addrlo, addrhi, + s->code_ptr, label_ptr); #else { int32_t offset = GUEST_BASE; diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c index 1920593..81cb9f7 100644 --- a/tcg/ia64/tcg-target.c +++ b/tcg/ia64/tcg-target.c @@ -1671,7 +1671,7 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args) tcg_opc_mov_a(TCG_REG_P7, TCG_REG_R56, TCG_AREG0), tcg_opc_a1 (TCG_REG_P6, OPC_ADD_A1, TCG_REG_R2, TCG_REG_R2, TCG_REG_R57), - tcg_opc_movi_a(TCG_REG_P7, TCG_REG_R58, mem_index)); + tcg_opc_movi_a(TCG_REG_P7, TCG_REG_R58, oi)); label_ptr = s->code_ptr; tcg_out_bundle(s, miB, tcg_opc_m1 (TCG_REG_P6, opc_ld_m1[s_bits], @@ -1735,7 +1735,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args) tcg_opc_mov_a(TCG_REG_P7, TCG_REG_R56, TCG_AREG0), tcg_opc_a1 (TCG_REG_P6, OPC_ADD_A1, TCG_REG_R2, TCG_REG_R2, TCG_REG_R57), - tcg_opc_movi_a(TCG_REG_P7, TCG_REG_R59, mem_index)); + tcg_opc_movi_a(TCG_REG_P7, TCG_REG_R59, oi)); label_ptr = s->code_ptr; tcg_out_bundle(s, miB, tcg_opc_m4 (TCG_REG_P6, opc_st_m4[s_bits], diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index 3f86182..f64c89c 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -990,21 +990,19 @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg base, TCGReg addrl, tcg_out_opc_reg(s, OPC_ADDU, base, TCG_REG_A0, addrl); } -static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOp opc, +static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi, TCGReg datalo, TCGReg datahi, TCGReg addrlo, TCGReg addrhi, - int mem_index, void *raddr, - tcg_insn_unit *label_ptr[2]) + void *raddr, tcg_insn_unit *label_ptr[2]) { TCGLabelQemuLdst *label = new_ldst_label(s); label->is_ld = is_ld; - label->opc = opc; + label->oi = oi; label->datalo_reg = datalo; label->datahi_reg = datahi; label->addrlo_reg = addrlo; label->addrhi_reg = addrhi; - label->mem_index = mem_index; label->raddr = raddr; label->label_ptr[0] = label_ptr[0]; if (TARGET_LONG_BITS == 64) { @@ -1014,7 +1012,8 @@ static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOp opc, static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) { - TCGMemOp opc = l->opc; + TCGMemOpIdx oi = lb->oi; + TCGMemOp opc = get_memop(oi); TCGReg v0; int i; @@ -1030,7 +1029,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) } else { i = tcg_out_call_iarg_reg(s, i, l->addrlo_reg); } - i = tcg_out_call_iarg_imm(s, i, l->mem_index); + i = tcg_out_call_iarg_imm(s, i, oi); i = tcg_out_call_iarg_imm(s, i, (intptr_t)l->raddr); tcg_out_call_int(s, qemu_ld_helpers[opc], false); /* delay slot */ @@ -1056,7 +1055,8 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) { - TCGMemOp opc = l->opc; + TCGMemOpIdx oi = lb->oi; + TCGMemOp opc = get_memop(oi); TCGMemOp s_bits = opc & MO_SIZE; int i; @@ -1088,7 +1088,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) default: tcg_abort(); } - i = tcg_out_call_iarg_imm(s, i, l->mem_index); + i = tcg_out_call_iarg_imm(s, i, oi); /* Tail call to the store helper. Thus force the return address computation to take place in the return address register. */ @@ -1175,8 +1175,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64) tcg_out_tlb_load(s, base, addr_regl, addr_regh, mem_index, s_bits, label_ptr, 1); tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc); - add_qemu_ldst_label(s, 1, opc, data_regl, data_regh, addr_regl, addr_regh, - mem_index, s->code_ptr, label_ptr); + add_qemu_ldst_label(s, 1, oi, data_regl, data_regh, addr_regl, addr_regh, + s->code_ptr, label_ptr); #else if (GUEST_BASE == 0 && data_regl != addr_regl) { base = addr_regl; @@ -1306,8 +1306,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64) tcg_out_tlb_load(s, base, addr_regl, addr_regh, mem_index, s_bits, label_ptr, 0); tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc); - add_qemu_ldst_label(s, 0, opc, data_regl, data_regh, addr_regl, addr_regh, - mem_index, s->code_ptr, label_ptr); + add_qemu_ldst_label(s, 0, oi, data_regl, data_regh, addr_regl, addr_regh, + s->code_ptr, label_ptr); #else if (GUEST_BASE == 0) { base = addr_regl; diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index b9d02c4..d49c7d9 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -1451,28 +1451,27 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp s_bits, /* Record the context of a call to the out of line helper code for the slow path for a load or store, so that we can later generate the correct helper code. */ -static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc, +static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi, TCGReg datalo_reg, TCGReg datahi_reg, TCGReg addrlo_reg, TCGReg addrhi_reg, - int mem_index, tcg_insn_unit *raddr, - tcg_insn_unit *lptr) + tcg_insn_unit *raddr, tcg_insn_unit *lptr) { TCGLabelQemuLdst *label = new_ldst_label(s); label->is_ld = is_ld; - label->opc = opc; + label->oi = oi; label->datalo_reg = datalo_reg; label->datahi_reg = datahi_reg; label->addrlo_reg = addrlo_reg; label->addrhi_reg = addrhi_reg; - label->mem_index = mem_index; label->raddr = raddr; label->label_ptr[0] = lptr; } static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) { - TCGMemOp opc = lb->opc; + TCGMemOpIdx oi = lb->oi; + TCGMemOp opc = get_memop(oi); TCGReg hi, lo, arg = TCG_REG_R3; reloc_pc14(lb->label_ptr[0], s->code_ptr); @@ -1493,7 +1492,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) tcg_out_mov(s, TCG_TYPE_TL, arg++, lo); } - tcg_out_movi(s, TCG_TYPE_I32, arg++, lb->mem_index); + tcg_out_movi(s, TCG_TYPE_I32, arg++, oi); tcg_out32(s, MFSPR | RT(arg) | LR); tcg_out_call(s, qemu_ld_helpers[opc & ~MO_SIGN]); @@ -1515,7 +1514,8 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) { - TCGMemOp opc = lb->opc; + TCGMemOpIdx oi = lb->oi; + TCGMemOp opc = get_memop(oi); TCGMemOp s_bits = opc & MO_SIZE; TCGReg hi, lo, arg = TCG_REG_R3; @@ -1562,7 +1562,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) } } - tcg_out_movi(s, TCG_TYPE_I32, arg++, lb->mem_index); + tcg_out_movi(s, TCG_TYPE_I32, arg++, oi); tcg_out32(s, MFSPR | RT(arg) | LR); tcg_out_call(s, qemu_st_helpers[opc]); @@ -1641,8 +1641,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64) } #ifdef CONFIG_SOFTMMU - add_qemu_ldst_label(s, true, opc, datalo, datahi, addrlo, addrhi, - mem_index, s->code_ptr, label_ptr); + add_qemu_ldst_label(s, true, oi, datalo, datahi, addrlo, addrhi, + s->code_ptr, label_ptr); #endif } @@ -1708,8 +1708,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64) } #ifdef CONFIG_SOFTMMU - add_qemu_ldst_label(s, false, opc, datalo, datahi, addrlo, addrhi, - mem_index, s->code_ptr, label_ptr); + add_qemu_ldst_label(s, false, oi, datalo, datahi, addrlo, addrhi, + s->code_ptr, label_ptr); #endif } diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c index 10577ab..46dedc9 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c @@ -1544,17 +1544,16 @@ static TCGReg tcg_out_tlb_read(TCGContext* s, TCGReg addr_reg, TCGMemOp opc, return addr_reg; } -static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc, - TCGReg data, TCGReg addr, int mem_index, +static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi, + TCGReg data, TCGReg addr, tcg_insn_unit *raddr, tcg_insn_unit *label_ptr) { TCGLabelQemuLdst *label = new_ldst_label(s); label->is_ld = is_ld; - label->opc = opc; + label->oi = oi; label->datalo_reg = data; label->addrlo_reg = addr; - label->mem_index = mem_index; label->raddr = raddr; label->label_ptr[0] = label_ptr; } @@ -1563,7 +1562,8 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) { TCGReg addr_reg = lb->addrlo_reg; TCGReg data_reg = lb->datalo_reg; - TCGMemOp opc = lb->opc; + TCGMemOpIdx oi = lb->oi; + TCGMemOp opc = get_memop(oi); patch_reloc(lb->label_ptr[0], R_390_PC16DBL, (intptr_t)s->code_ptr, -2); @@ -1571,7 +1571,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) if (TARGET_LONG_BITS == 64) { tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg); } - tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, lb->mem_index); + tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, oi); tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R5, (uintptr_t)lb->raddr); tcg_out_call(s, qemu_ld_helpers[opc]); tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_R2); @@ -1583,7 +1583,8 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) { TCGReg addr_reg = lb->addrlo_reg; TCGReg data_reg = lb->datalo_reg; - TCGMemOp opc = lb->opc; + TCGMemOpIdx oi = lb->oi; + TCGMemOp opc = get_memop(oi); patch_reloc(lb->label_ptr[0], R_390_PC16DBL, (intptr_t)s->code_ptr, -2); @@ -1607,7 +1608,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) default: tcg_abort(); } - tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, lb->mem_index); + tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, oi); tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R6, (uintptr_t)lb->raddr); tcg_out_call(s, qemu_st_helpers[opc]); @@ -1647,8 +1648,7 @@ static void tcg_out_qemu_ld(TCGContext* s, TCGReg data_reg, TCGReg addr_reg, tcg_out_qemu_ld_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0); - add_qemu_ldst_label(s, 1, opc, data_reg, addr_reg, mem_index, - s->code_ptr, label_ptr); + add_qemu_ldst_label(s, 1, oi, data_reg, addr_reg, s->code_ptr, label_ptr); #else TCGReg index_reg; tcg_target_long disp; @@ -1674,8 +1674,7 @@ static void tcg_out_qemu_st(TCGContext* s, TCGReg data_reg, TCGReg addr_reg, tcg_out_qemu_st_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0); - add_qemu_ldst_label(s, 0, opc, data_reg, addr_reg, mem_index, - s->code_ptr, label_ptr); + add_qemu_ldst_label(s, 0, oi, data_reg, addr_reg, s->code_ptr, label_ptr); #else TCGReg index_reg; tcg_target_long disp; diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index ccc3173..c1794a3 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -915,7 +915,7 @@ static void build_trampolines(TCGContext *s) } else { ra += 1; } - /* Skip the mem_index argument. */ + /* Skip the oi argument. */ ra += 1; } @@ -1113,7 +1113,7 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr, assert(func != NULL); tcg_out_call_nodelay(s, func); /* delay slot */ - tcg_out_movi(s, TCG_TYPE_I32, param, memi); + tcg_out_movi(s, TCG_TYPE_I32, param, oi); /* Recall that all of the helpers return 64-bit results. Which complicates things for sparcv8plus. */ @@ -1192,7 +1192,7 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr, assert(func != NULL); tcg_out_call_nodelay(s, func); /* delay slot */ - tcg_out_movi(s, TCG_TYPE_REG, param, memi); + tcg_out_movi(s, TCG_TYPE_I32, param, oi); *label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr)); #else diff --git a/tcg/tcg-be-ldst.h b/tcg/tcg-be-ldst.h index 4a45102..40a2369 100644 --- a/tcg/tcg-be-ldst.h +++ b/tcg/tcg-be-ldst.h @@ -24,13 +24,12 @@ typedef struct TCGLabelQemuLdst { bool is_ld; /* qemu_ld: true, qemu_st: false */ - TCGMemOp opc; + TCGMemOpIdx 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 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 */ - int mem_index; /* soft MMU memory index */ tcg_insn_unit *raddr; /* gen code addr of the next IR of qemu_ld/st IR */ tcg_insn_unit *label_ptr[2]; /* label pointers to be updated */ struct TCGLabelQemuLdst *next; diff --git a/tcg/tcg.h b/tcg/tcg.h index 99d3f14..f9fb380 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -927,46 +927,46 @@ void tcg_register_jit(void *buf, size_t buf_size); #ifdef CONFIG_SOFTMMU /* Value zero-extended to tcg register size. */ tcg_target_ulong helper_ret_ldub_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); tcg_target_ulong helper_le_lduw_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); tcg_target_ulong helper_le_ldul_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); uint64_t helper_le_ldq_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); tcg_target_ulong helper_be_lduw_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); tcg_target_ulong helper_be_ldul_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); /* Value sign-extended to tcg register size. */ tcg_target_ulong helper_ret_ldsb_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); tcg_target_ulong helper_le_ldsw_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); tcg_target_ulong helper_le_ldsl_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); tcg_target_ulong helper_be_ldsw_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); tcg_target_ulong helper_be_ldsl_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); void helper_le_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); void helper_le_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); void helper_le_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); void helper_be_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val, - int mmu_idx, uintptr_t retaddr); + TCGMemOpIdx oi, uintptr_t retaddr); /* Temporary aliases until backends are converted. */ #ifdef TARGET_WORDS_BIGENDIAN diff --git a/tci.c b/tci.c index 800ada8..a14717d 100644 --- a/tci.c +++ b/tci.c @@ -420,35 +420,34 @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition) } #ifdef CONFIG_SOFTMMU -# define mmuidx get_mmuidx(oi) # define qemu_ld_ub \ - helper_ret_ldub_mmu(env, taddr, mmuidx, (uintptr_t)tb_ptr) + helper_ret_ldub_mmu(env, taddr, oi, (uintptr_t)tb_ptr) # define qemu_ld_leuw \ - helper_le_lduw_mmu(env, taddr, mmuidx, (uintptr_t)tb_ptr) + helper_le_lduw_mmu(env, taddr, oi, (uintptr_t)tb_ptr) # define qemu_ld_leul \ - helper_le_ldul_mmu(env, taddr, mmuidx, (uintptr_t)tb_ptr) + helper_le_ldul_mmu(env, taddr, oi, (uintptr_t)tb_ptr) # define qemu_ld_leq \ - helper_le_ldq_mmu(env, taddr, mmuidx, (uintptr_t)tb_ptr) + helper_le_ldq_mmu(env, taddr, oi, (uintptr_t)tb_ptr) # define qemu_ld_beuw \ - helper_be_lduw_mmu(env, taddr, mmuidx, (uintptr_t)tb_ptr) + helper_be_lduw_mmu(env, taddr, oi, (uintptr_t)tb_ptr) # define qemu_ld_beul \ - helper_be_ldul_mmu(env, taddr, mmuidx, (uintptr_t)tb_ptr) + helper_be_ldul_mmu(env, taddr, oi, (uintptr_t)tb_ptr) # define qemu_ld_beq \ - helper_be_ldq_mmu(env, taddr, mmuidx, (uintptr_t)tb_ptr) + helper_be_ldq_mmu(env, taddr, oi, (uintptr_t)tb_ptr) # define qemu_st_b(X) \ - helper_ret_stb_mmu(env, taddr, X, mmuidx, (uintptr_t)tb_ptr) + helper_ret_stb_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr) # define qemu_st_lew(X) \ - helper_le_stw_mmu(env, taddr, X, mmuidx, (uintptr_t)tb_ptr) + helper_le_stw_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr) # define qemu_st_lel(X) \ - helper_le_stl_mmu(env, taddr, X, mmuidx, (uintptr_t)tb_ptr) + helper_le_stl_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr) # define qemu_st_leq(X) \ - helper_le_stq_mmu(env, taddr, X, mmuidx, (uintptr_t)tb_ptr) + helper_le_stq_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr) # define qemu_st_bew(X) \ - helper_be_stw_mmu(env, taddr, X, mmuidx, (uintptr_t)tb_ptr) + helper_be_stw_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr) # define qemu_st_bel(X) \ - helper_be_stl_mmu(env, taddr, X, mmuidx, (uintptr_t)tb_ptr) + helper_be_stl_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr) # define qemu_st_beq(X) \ - helper_be_stq_mmu(env, taddr, X, mmuidx, (uintptr_t)tb_ptr) + helper_be_stq_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr) #else # define qemu_ld_ub ldub_p(g2h(taddr)) # define qemu_ld_leuw lduw_le_p(g2h(taddr)) -- cgit v1.1 From dfb36305626636e2e07e0c5acd3a002a5419399e Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 13 May 2015 11:25:20 -0700 Subject: tcg: Add MO_ALIGN, MO_UNALN These modifiers control, on a per-memory-op basis, whether unaligned memory accesses are allowed. The default setting reflects the target's definition of ALIGNED_ONLY. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson --- softmmu_template.h | 72 ++++++++++++++++++++++++------------------------------ tcg/tcg.h | 13 ++++++++++ 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/softmmu_template.h b/softmmu_template.h index 10820a5..39f571b 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -183,12 +183,11 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, /* If the TLB entry is for a different page, reload and try again. */ if ((addr & TARGET_PAGE_MASK) != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { -#ifdef ALIGNED_ONLY - if ((addr & (DATA_SIZE - 1)) != 0) { + if ((addr & (DATA_SIZE - 1)) != 0 + && (get_memop(oi) & MO_AMASK) == MO_ALIGN) { cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, mmu_idx, retaddr); } -#endif if (!VICTIM_TLB_HIT(ADDR_READ)) { tlb_fill(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, mmu_idx, retaddr); @@ -219,10 +218,10 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, DATA_TYPE res1, res2; unsigned shift; do_unaligned_access: -#ifdef ALIGNED_ONLY - cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, - mmu_idx, retaddr); -#endif + if ((get_memop(oi) & MO_AMASK) == MO_ALIGN) { + cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, + mmu_idx, retaddr); + } addr1 = addr & ~(DATA_SIZE - 1); addr2 = addr1 + DATA_SIZE; /* Note the adjustment at the beginning of the function. @@ -237,12 +236,11 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, } /* Handle aligned access or unaligned access in the same page. */ -#ifdef ALIGNED_ONLY - if ((addr & (DATA_SIZE - 1)) != 0) { + if ((addr & (DATA_SIZE - 1)) != 0 + && (get_memop(oi) & MO_AMASK) == MO_ALIGN) { cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, mmu_idx, retaddr); } -#endif haddr = addr + env->tlb_table[mmu_idx][index].addend; #if DATA_SIZE == 1 @@ -272,12 +270,11 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, /* If the TLB entry is for a different page, reload and try again. */ if ((addr & TARGET_PAGE_MASK) != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { -#ifdef ALIGNED_ONLY - if ((addr & (DATA_SIZE - 1)) != 0) { + if ((addr & (DATA_SIZE - 1)) != 0 + && (get_memop(oi) & MO_AMASK) == MO_ALIGN) { cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, mmu_idx, retaddr); } -#endif if (!VICTIM_TLB_HIT(ADDR_READ)) { tlb_fill(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, mmu_idx, retaddr); @@ -308,10 +305,10 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, DATA_TYPE res1, res2; unsigned shift; do_unaligned_access: -#ifdef ALIGNED_ONLY - cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, - mmu_idx, retaddr); -#endif + if ((get_memop(oi) & MO_AMASK) == MO_ALIGN) { + cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, + mmu_idx, retaddr); + } addr1 = addr & ~(DATA_SIZE - 1); addr2 = addr1 + DATA_SIZE; /* Note the adjustment at the beginning of the function. @@ -326,12 +323,11 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, } /* Handle aligned access or unaligned access in the same page. */ -#ifdef ALIGNED_ONLY - if ((addr & (DATA_SIZE - 1)) != 0) { + if ((addr & (DATA_SIZE - 1)) != 0 + && (get_memop(oi) & MO_AMASK) == MO_ALIGN) { cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, mmu_idx, retaddr); } -#endif haddr = addr + env->tlb_table[mmu_idx][index].addend; res = glue(glue(ld, LSUFFIX), _be_p)((uint8_t *)haddr); @@ -402,12 +398,11 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, /* If the TLB entry is for a different page, reload and try again. */ if ((addr & TARGET_PAGE_MASK) != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { -#ifdef ALIGNED_ONLY - if ((addr & (DATA_SIZE - 1)) != 0) { + if ((addr & (DATA_SIZE - 1)) != 0 + && (get_memop(oi) & MO_AMASK) == MO_ALIGN) { cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr); } -#endif if (!VICTIM_TLB_HIT(addr_write)) { tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr); } @@ -435,10 +430,10 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, >= TARGET_PAGE_SIZE)) { int i; do_unaligned_access: -#ifdef ALIGNED_ONLY - cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, - mmu_idx, retaddr); -#endif + if ((get_memop(oi) & MO_AMASK) == MO_ALIGN) { + cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, + mmu_idx, retaddr); + } /* XXX: not efficient, but simple */ /* Note: relies on the fact that tlb_fill() does not remove the * previous page from the TLB cache. */ @@ -454,12 +449,11 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, } /* Handle aligned access or unaligned access in the same page. */ -#ifdef ALIGNED_ONLY - if ((addr & (DATA_SIZE - 1)) != 0) { + if ((addr & (DATA_SIZE - 1)) != 0 + && (get_memop(oi) & MO_AMASK) == MO_ALIGN) { cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr); } -#endif haddr = addr + env->tlb_table[mmu_idx][index].addend; #if DATA_SIZE == 1 @@ -484,12 +478,11 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, /* If the TLB entry is for a different page, reload and try again. */ if ((addr & TARGET_PAGE_MASK) != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { -#ifdef ALIGNED_ONLY - if ((addr & (DATA_SIZE - 1)) != 0) { + if ((addr & (DATA_SIZE - 1)) != 0 + && (get_memop(oi) & MO_AMASK) == MO_ALIGN) { cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr); } -#endif if (!VICTIM_TLB_HIT(addr_write)) { tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr); } @@ -517,10 +510,10 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, >= TARGET_PAGE_SIZE)) { int i; do_unaligned_access: -#ifdef ALIGNED_ONLY - cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, - mmu_idx, retaddr); -#endif + if ((get_memop(oi) & MO_AMASK) == MO_ALIGN) { + cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, + mmu_idx, retaddr); + } /* XXX: not efficient, but simple */ /* Note: relies on the fact that tlb_fill() does not remove the * previous page from the TLB cache. */ @@ -536,12 +529,11 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, } /* Handle aligned access or unaligned access in the same page. */ -#ifdef ALIGNED_ONLY - if ((addr & (DATA_SIZE - 1)) != 0) { + if ((addr & (DATA_SIZE - 1)) != 0 + && (get_memop(oi) & MO_AMASK) == MO_ALIGN) { cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr); } -#endif haddr = addr + env->tlb_table[mmu_idx][index].addend; glue(glue(st, SUFFIX), _be_p)((uint8_t *)haddr, val); diff --git a/tcg/tcg.h b/tcg/tcg.h index f9fb380..8098f82 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -241,6 +241,19 @@ typedef enum TCGMemOp { MO_TE = MO_LE, #endif + /* MO_UNALN accesses are never checked for alignment. + MO_ALIGN accesses will result in a call to the CPU's + do_unaligned_access hook if the guest address is not aligned. + The default depends on whether the target CPU defines ALIGNED_ONLY. */ + MO_AMASK = 16, +#ifdef ALIGNED_ONLY + MO_ALIGN = 0, + MO_UNALN = MO_AMASK, +#else + MO_ALIGN = MO_AMASK, + MO_UNALN = 0, +#endif + /* Combinations of the above, for ease of use. */ MO_UB = MO_8, MO_UW = MO_16, -- cgit v1.1