Commit 86feb1c8 authored by Richard Henderson's avatar Richard Henderson Committed by Aurelien Jarno
Browse files

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: default avatarRichard Henderson <rth@twiddle.net>
Signed-off-by: default avatarAurelien Jarno <aurelien@aurel32.net>
parent 32d98fbd
......@@ -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" } },
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment