aboutsummaryrefslogtreecommitdiff
path: root/tcg/i386
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-05-16 20:07:20 -0700
committerRichard Henderson <richard.henderson@linaro.org>2023-05-16 20:07:20 -0700
commitfecccfcc542370caedbfc09fe9963d128f5e73a0 (patch)
tree78d60fe5833e95d65d2344981ea4ea0ddeaa1386 /tcg/i386
parent0700ceb3939f08619d7f323209597ef62b489514 (diff)
tcg: Split INDEX_op_qemu_{ld,st}* for guest address size
For 32-bit hosts, we cannot simply rely on TCGContext.addr_bits, as we need one or two host registers to represent the guest address. Create the new opcodes and update all users. Since we have not yet eliminated TARGET_LONG_BITS, only one of the two opcodes will ever be used, so we can get away with treating them the same in the backends. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg/i386')
-rw-r--r--tcg/i386/tcg-target.c.inc85
1 files changed, 52 insertions, 33 deletions
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
index 3b8528e332..d8fd38d9e7 100644
--- a/tcg/i386/tcg-target.c.inc
+++ b/tcg/i386/tcg-target.c.inc
@@ -2475,35 +2475,51 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, a0);
break;
- case INDEX_op_qemu_ld_i32:
- if (TCG_TARGET_REG_BITS >= TARGET_LONG_BITS) {
- tcg_out_qemu_ld(s, a0, -1, a1, -1, a2, TCG_TYPE_I32);
- } else {
+ 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);
break;
- case INDEX_op_qemu_ld_i64:
+ case INDEX_op_qemu_ld_a32_i64:
if (TCG_TARGET_REG_BITS == 64) {
tcg_out_qemu_ld(s, a0, -1, a1, -1, a2, TCG_TYPE_I64);
- } else if (TARGET_LONG_BITS == 32) {
+ } else {
tcg_out_qemu_ld(s, a0, a1, a2, -1, 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_st_i32:
- case INDEX_op_qemu_st8_i32:
- if (TCG_TARGET_REG_BITS >= TARGET_LONG_BITS) {
- tcg_out_qemu_st(s, a0, -1, a1, -1, a2, TCG_TYPE_I32);
- } else {
+
+ 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);
break;
- case INDEX_op_qemu_st_i64:
+ case INDEX_op_qemu_st_a32_i64:
if (TCG_TARGET_REG_BITS == 64) {
tcg_out_qemu_st(s, a0, -1, a1, -1, a2, TCG_TYPE_I64);
- } else if (TARGET_LONG_BITS == 32) {
+ } else {
tcg_out_qemu_st(s, a0, a1, a2, -1, 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);
}
@@ -3181,26 +3197,29 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
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_i32:
- return (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
- ? C_O1_I1(r, L) : C_O1_I2(r, L, L));
-
- case INDEX_op_qemu_st_i32:
- return (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
- ? C_O0_I2(L, L) : C_O0_I3(L, L, L));
- case INDEX_op_qemu_st8_i32:
- return (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
- ? C_O0_I2(s, L) : C_O0_I3(s, L, L));
-
- case INDEX_op_qemu_ld_i64:
- return (TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, L)
- : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? C_O2_I1(r, r, L)
- : C_O2_I2(r, r, L, L));
-
- case INDEX_op_qemu_st_i64:
- return (TCG_TARGET_REG_BITS == 64 ? C_O0_I2(L, L)
- : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? C_O0_I3(L, L, L)
- : C_O0_I4(L, L, L, L));
+ case INDEX_op_qemu_ld_a32_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:
+ 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:
+ 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:
+ 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:
+ 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_brcond2_i32:
return C_O0_I4(r, r, ri, ri);