tcg: Disambiguate qemu_ld32u with 32-bit and 64-bit outputs.
Some targets (e.g. Alpha and MIPS64) need to keep 32-bit operands sign-extended in 64-bit registers (regardless of the "real" sign of the operand). For that, we need to be able to distinguish between a 32-bit load with a 32-bit result and a 32-bit load with a given extension to a 64-bit result. This distinction already exists for the ld* loads, but not the qemu_ld* loads. Reserve qemu_ld32u for 64-bit outputs and introduce qemu_ld32 for 32-bit outputs. Adjust all code generators to match. Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
32d98fbd10
commit
86feb1c860
10
tcg/README
10
tcg/README
@ -378,13 +378,17 @@ instructions.
|
||||
qemu_ld8s t0, t1, flags
|
||||
qemu_ld16u t0, t1, flags
|
||||
qemu_ld16s t0, t1, flags
|
||||
qemu_ld32 t0, t1, flags
|
||||
qemu_ld32u t0, t1, flags
|
||||
qemu_ld32s t0, t1, flags
|
||||
qemu_ld64 t0, t1, flags
|
||||
|
||||
Load data at the QEMU CPU address t1 into t0. t1 has the QEMU CPU
|
||||
address type. 'flags' contains the QEMU memory index (selects user or
|
||||
kernel access) for example.
|
||||
Load data at the QEMU CPU address t1 into t0. t1 has the QEMU CPU address
|
||||
type. 'flags' contains the QEMU memory index (selects user or kernel access)
|
||||
for example.
|
||||
|
||||
Note that "qemu_ld32" implies a 32-bit result, while "qemu_ld32u" and
|
||||
"qemu_ld32s" imply a 64-bit result appropriately extended from 32 bits.
|
||||
|
||||
* qemu_st8 t0, t1, flags
|
||||
qemu_st16 t0, t1, flags
|
||||
|
@ -1488,7 +1488,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||
case INDEX_op_qemu_ld16s:
|
||||
tcg_out_qemu_ld(s, COND_AL, args, 1 | 4);
|
||||
break;
|
||||
case INDEX_op_qemu_ld32u:
|
||||
case INDEX_op_qemu_ld32:
|
||||
tcg_out_qemu_ld(s, COND_AL, args, 2);
|
||||
break;
|
||||
case INDEX_op_qemu_ld64:
|
||||
@ -1597,7 +1597,7 @@ static const TCGTargetOpDef arm_op_defs[] = {
|
||||
{ INDEX_op_qemu_ld8s, { "r", "x", "X" } },
|
||||
{ INDEX_op_qemu_ld16u, { "r", "x", "X" } },
|
||||
{ INDEX_op_qemu_ld16s, { "r", "x", "X" } },
|
||||
{ INDEX_op_qemu_ld32u, { "r", "x", "X" } },
|
||||
{ INDEX_op_qemu_ld32, { "r", "x", "X" } },
|
||||
{ INDEX_op_qemu_ld64, { "d", "r", "x", "X" } },
|
||||
|
||||
{ INDEX_op_qemu_st8, { "x", "x", "X" } },
|
||||
|
@ -863,7 +863,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
case INDEX_op_qemu_ld16s:
|
||||
tcg_out_qemu_ld(s, args, 1 | 4);
|
||||
break;
|
||||
case INDEX_op_qemu_ld32u:
|
||||
case INDEX_op_qemu_ld32:
|
||||
tcg_out_qemu_ld(s, args, 2);
|
||||
break;
|
||||
|
||||
@ -923,7 +923,7 @@ static const TCGTargetOpDef hppa_op_defs[] = {
|
||||
{ INDEX_op_qemu_ld8s, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld16u, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld16s, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32u, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld64, { "r", "r", "L" } },
|
||||
|
||||
{ INDEX_op_qemu_st8, { "L", "L" } },
|
||||
@ -935,7 +935,7 @@ static const TCGTargetOpDef hppa_op_defs[] = {
|
||||
{ INDEX_op_qemu_ld8s, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld16u, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld16s, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld32u, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld32, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
|
||||
|
||||
{ INDEX_op_qemu_st8, { "L", "L", "L" } },
|
||||
|
@ -1197,7 +1197,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||
case INDEX_op_qemu_ld16s:
|
||||
tcg_out_qemu_ld(s, args, 1 | 4);
|
||||
break;
|
||||
case INDEX_op_qemu_ld32u:
|
||||
case INDEX_op_qemu_ld32:
|
||||
tcg_out_qemu_ld(s, args, 2);
|
||||
break;
|
||||
case INDEX_op_qemu_ld64:
|
||||
@ -1281,7 +1281,7 @@ static const TCGTargetOpDef x86_op_defs[] = {
|
||||
{ INDEX_op_qemu_ld8s, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld16u, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld16s, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32u, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld64, { "r", "r", "L" } },
|
||||
|
||||
{ INDEX_op_qemu_st8, { "cb", "L" } },
|
||||
@ -1293,7 +1293,7 @@ static const TCGTargetOpDef x86_op_defs[] = {
|
||||
{ INDEX_op_qemu_ld8s, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld16u, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld16s, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld32u, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld32, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
|
||||
|
||||
{ INDEX_op_qemu_st8, { "cb", "L", "L" } },
|
||||
|
@ -1298,7 +1298,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||
case INDEX_op_qemu_ld16s:
|
||||
tcg_out_qemu_ld(s, args, 1 | 4);
|
||||
break;
|
||||
case INDEX_op_qemu_ld32u:
|
||||
case INDEX_op_qemu_ld32:
|
||||
tcg_out_qemu_ld(s, args, 2);
|
||||
break;
|
||||
case INDEX_op_qemu_ld64:
|
||||
@ -1371,7 +1371,7 @@ static const TCGTargetOpDef mips_op_defs[] = {
|
||||
{ INDEX_op_qemu_ld8s, { "L", "lZ" } },
|
||||
{ INDEX_op_qemu_ld16u, { "L", "lZ" } },
|
||||
{ INDEX_op_qemu_ld16s, { "L", "lZ" } },
|
||||
{ INDEX_op_qemu_ld32u, { "L", "lZ" } },
|
||||
{ INDEX_op_qemu_ld32, { "L", "lZ" } },
|
||||
{ INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
|
||||
|
||||
{ INDEX_op_qemu_st8, { "SZ", "SZ" } },
|
||||
@ -1383,7 +1383,7 @@ static const TCGTargetOpDef mips_op_defs[] = {
|
||||
{ INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
|
||||
{ INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
|
||||
{ INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
|
||||
{ INDEX_op_qemu_ld32u, { "L", "lZ", "lZ" } },
|
||||
{ INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
|
||||
{ INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
|
||||
|
||||
{ INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
|
||||
|
@ -1661,7 +1661,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
case INDEX_op_qemu_ld16s:
|
||||
tcg_out_qemu_ld(s, args, 1 | 4);
|
||||
break;
|
||||
case INDEX_op_qemu_ld32u:
|
||||
case INDEX_op_qemu_ld32:
|
||||
tcg_out_qemu_ld(s, args, 2);
|
||||
break;
|
||||
case INDEX_op_qemu_ld64:
|
||||
@ -1775,7 +1775,7 @@ static const TCGTargetOpDef ppc_op_defs[] = {
|
||||
{ INDEX_op_qemu_ld8s, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld16u, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld16s, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32u, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld64, { "r", "r", "L" } },
|
||||
|
||||
{ INDEX_op_qemu_st8, { "K", "K" } },
|
||||
@ -1787,7 +1787,7 @@ static const TCGTargetOpDef ppc_op_defs[] = {
|
||||
{ INDEX_op_qemu_ld8s, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld16u, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld16s, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld32u, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld32, { "r", "L", "L" } },
|
||||
{ INDEX_op_qemu_ld64, { "r", "L", "L", "L" } },
|
||||
|
||||
{ INDEX_op_qemu_st8, { "K", "K", "K" } },
|
||||
|
@ -1520,6 +1520,7 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
case INDEX_op_qemu_ld16s:
|
||||
tcg_out_qemu_ld (s, args, 1 | 4);
|
||||
break;
|
||||
case INDEX_op_qemu_ld32:
|
||||
case INDEX_op_qemu_ld32u:
|
||||
tcg_out_qemu_ld (s, args, 2);
|
||||
break;
|
||||
@ -1648,6 +1649,7 @@ static const TCGTargetOpDef ppc_op_defs[] = {
|
||||
{ INDEX_op_qemu_ld8s, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld16u, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld16s, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32u, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32s, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld64, { "r", "L" } },
|
||||
|
@ -1324,7 +1324,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
case INDEX_op_qemu_ld16s:
|
||||
tcg_out_qemu_ld(s, args, 1 | 4);
|
||||
break;
|
||||
case INDEX_op_qemu_ld32:
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
case INDEX_op_qemu_ld32u:
|
||||
#endif
|
||||
tcg_out_qemu_ld(s, args, 2);
|
||||
break;
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
@ -1480,8 +1483,9 @@ static const TCGTargetOpDef sparc_op_defs[] = {
|
||||
{ INDEX_op_qemu_ld8s, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld16u, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld16s, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32u, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32, { "r", "L" } },
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
{ INDEX_op_qemu_ld32u, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32s, { "r", "L" } },
|
||||
#endif
|
||||
|
||||
|
@ -2075,9 +2075,9 @@ static inline void tcg_gen_qemu_ld16s(TCGv ret, TCGv addr, int mem_index)
|
||||
static inline void tcg_gen_qemu_ld32u(TCGv ret, TCGv addr, int mem_index)
|
||||
{
|
||||
#if TARGET_LONG_BITS == 32
|
||||
tcg_gen_op3i_i32(INDEX_op_qemu_ld32u, ret, addr, mem_index);
|
||||
tcg_gen_op3i_i32(INDEX_op_qemu_ld32, ret, addr, mem_index);
|
||||
#else
|
||||
tcg_gen_op4i_i32(INDEX_op_qemu_ld32u, TCGV_LOW(ret), TCGV_LOW(addr),
|
||||
tcg_gen_op4i_i32(INDEX_op_qemu_ld32, TCGV_LOW(ret), TCGV_LOW(addr),
|
||||
TCGV_HIGH(addr), mem_index);
|
||||
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
|
||||
#endif
|
||||
@ -2086,9 +2086,9 @@ static inline void tcg_gen_qemu_ld32u(TCGv ret, TCGv addr, int mem_index)
|
||||
static inline void tcg_gen_qemu_ld32s(TCGv ret, TCGv addr, int mem_index)
|
||||
{
|
||||
#if TARGET_LONG_BITS == 32
|
||||
tcg_gen_op3i_i32(INDEX_op_qemu_ld32u, ret, addr, mem_index);
|
||||
tcg_gen_op3i_i32(INDEX_op_qemu_ld32, ret, addr, mem_index);
|
||||
#else
|
||||
tcg_gen_op4i_i32(INDEX_op_qemu_ld32u, TCGV_LOW(ret), TCGV_LOW(addr),
|
||||
tcg_gen_op4i_i32(INDEX_op_qemu_ld32, TCGV_LOW(ret), TCGV_LOW(addr),
|
||||
TCGV_HIGH(addr), mem_index);
|
||||
tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
|
||||
#endif
|
||||
|
@ -251,9 +251,9 @@ DEF2(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
DEF2(qemu_ld16s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
#endif
|
||||
#if TARGET_LONG_BITS == 32
|
||||
DEF2(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
DEF2(qemu_ld32, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
#else
|
||||
DEF2(qemu_ld32u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
DEF2(qemu_ld32, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
#endif
|
||||
#if TARGET_LONG_BITS == 32
|
||||
DEF2(qemu_ld64, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
@ -288,6 +288,7 @@ DEF2(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
DEF2(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
DEF2(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
DEF2(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
DEF2(qemu_ld32, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
DEF2(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
DEF2(qemu_ld32s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
DEF2(qemu_ld64, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
|
||||
|
@ -1238,6 +1238,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
case INDEX_op_qemu_ld16s:
|
||||
tcg_out_qemu_ld(s, args, 1 | 4);
|
||||
break;
|
||||
case INDEX_op_qemu_ld32:
|
||||
case INDEX_op_qemu_ld32u:
|
||||
tcg_out_qemu_ld(s, args, 2);
|
||||
break;
|
||||
@ -1412,6 +1413,7 @@ static const TCGTargetOpDef x86_64_op_defs[] = {
|
||||
{ INDEX_op_qemu_ld8s, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld16u, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld16s, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32u, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld32s, { "r", "L" } },
|
||||
{ INDEX_op_qemu_ld64, { "r", "L" } },
|
||||
|
Loading…
Reference in New Issue
Block a user