tcg-s390: Integrate endianness into TCGMemOp
Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
parent
a5a04f2830
commit
b8dd88b85c
|
@ -1273,11 +1273,6 @@ static void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
|
||||||
static void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp opc, TCGReg data,
|
static void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp opc, TCGReg data,
|
||||||
TCGReg base, TCGReg index, int disp)
|
TCGReg base, TCGReg index, int disp)
|
||||||
{
|
{
|
||||||
#ifdef TARGET_WORDS_BIGENDIAN
|
|
||||||
const int bswap = 0;
|
|
||||||
#else
|
|
||||||
const int bswap = 1;
|
|
||||||
#endif
|
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
case MO_UB:
|
case MO_UB:
|
||||||
tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
|
tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
|
||||||
|
@ -1285,49 +1280,50 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp opc, TCGReg data,
|
||||||
case MO_SB:
|
case MO_SB:
|
||||||
tcg_out_insn(s, RXY, LGB, data, base, index, disp);
|
tcg_out_insn(s, RXY, LGB, data, base, index, disp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MO_UW | MO_BSWAP:
|
||||||
|
/* swapped unsigned halfword load with upper bits zeroed */
|
||||||
|
tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
|
||||||
|
tgen_ext16u(s, TCG_TYPE_I64, data, data);
|
||||||
|
break;
|
||||||
case MO_UW:
|
case MO_UW:
|
||||||
if (bswap) {
|
tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
|
||||||
/* swapped unsigned halfword load with upper bits zeroed */
|
break;
|
||||||
tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
|
|
||||||
tgen_ext16u(s, TCG_TYPE_I64, data, data);
|
case MO_SW | MO_BSWAP:
|
||||||
} else {
|
/* swapped sign-extended halfword load */
|
||||||
tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
|
tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
|
||||||
}
|
tgen_ext16s(s, TCG_TYPE_I64, data, data);
|
||||||
break;
|
break;
|
||||||
case MO_SW:
|
case MO_SW:
|
||||||
if (bswap) {
|
tcg_out_insn(s, RXY, LGH, data, base, index, disp);
|
||||||
/* swapped sign-extended halfword load */
|
break;
|
||||||
tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
|
|
||||||
tgen_ext16s(s, TCG_TYPE_I64, data, data);
|
case MO_UL | MO_BSWAP:
|
||||||
} else {
|
/* swapped unsigned int load with upper bits zeroed */
|
||||||
tcg_out_insn(s, RXY, LGH, data, base, index, disp);
|
tcg_out_insn(s, RXY, LRV, data, base, index, disp);
|
||||||
}
|
tgen_ext32u(s, data, data);
|
||||||
break;
|
break;
|
||||||
case MO_UL:
|
case MO_UL:
|
||||||
if (bswap) {
|
tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
|
||||||
/* swapped unsigned int load with upper bits zeroed */
|
break;
|
||||||
tcg_out_insn(s, RXY, LRV, data, base, index, disp);
|
|
||||||
tgen_ext32u(s, data, data);
|
case MO_SL | MO_BSWAP:
|
||||||
} else {
|
/* swapped sign-extended int load */
|
||||||
tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
|
tcg_out_insn(s, RXY, LRV, data, base, index, disp);
|
||||||
}
|
tgen_ext32s(s, data, data);
|
||||||
break;
|
break;
|
||||||
case MO_SL:
|
case MO_SL:
|
||||||
if (bswap) {
|
tcg_out_insn(s, RXY, LGF, data, base, index, disp);
|
||||||
/* swapped sign-extended int load */
|
break;
|
||||||
tcg_out_insn(s, RXY, LRV, data, base, index, disp);
|
|
||||||
tgen_ext32s(s, data, data);
|
case MO_Q | MO_BSWAP:
|
||||||
} else {
|
tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
|
||||||
tcg_out_insn(s, RXY, LGF, data, base, index, disp);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case MO_Q:
|
case MO_Q:
|
||||||
if (bswap) {
|
tcg_out_insn(s, RXY, LG, data, base, index, disp);
|
||||||
tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
|
|
||||||
} else {
|
|
||||||
tcg_out_insn(s, RXY, LG, data, base, index, disp);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
tcg_abort();
|
tcg_abort();
|
||||||
}
|
}
|
||||||
|
@ -1336,11 +1332,6 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp opc, TCGReg data,
|
||||||
static void tcg_out_qemu_st_direct(TCGContext *s, TCGMemOp opc, TCGReg data,
|
static void tcg_out_qemu_st_direct(TCGContext *s, TCGMemOp opc, TCGReg data,
|
||||||
TCGReg base, TCGReg index, int disp)
|
TCGReg base, TCGReg index, int disp)
|
||||||
{
|
{
|
||||||
#ifdef TARGET_WORDS_BIGENDIAN
|
|
||||||
const int bswap = 0;
|
|
||||||
#else
|
|
||||||
const int bswap = 1;
|
|
||||||
#endif
|
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
case MO_UB:
|
case MO_UB:
|
||||||
if (disp >= 0 && disp < 0x1000) {
|
if (disp >= 0 && disp < 0x1000) {
|
||||||
|
@ -1349,31 +1340,36 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGMemOp opc, TCGReg data,
|
||||||
tcg_out_insn(s, RXY, STCY, data, base, index, disp);
|
tcg_out_insn(s, RXY, STCY, data, base, index, disp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MO_UW | MO_BSWAP:
|
||||||
|
tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
|
||||||
|
break;
|
||||||
case MO_UW:
|
case MO_UW:
|
||||||
if (bswap) {
|
if (disp >= 0 && disp < 0x1000) {
|
||||||
tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
|
|
||||||
} else if (disp >= 0 && disp < 0x1000) {
|
|
||||||
tcg_out_insn(s, RX, STH, data, base, index, disp);
|
tcg_out_insn(s, RX, STH, data, base, index, disp);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_insn(s, RXY, STHY, data, base, index, disp);
|
tcg_out_insn(s, RXY, STHY, data, base, index, disp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MO_UL | MO_BSWAP:
|
||||||
|
tcg_out_insn(s, RXY, STRV, data, base, index, disp);
|
||||||
|
break;
|
||||||
case MO_UL:
|
case MO_UL:
|
||||||
if (bswap) {
|
if (disp >= 0 && disp < 0x1000) {
|
||||||
tcg_out_insn(s, RXY, STRV, data, base, index, disp);
|
|
||||||
} else if (disp >= 0 && disp < 0x1000) {
|
|
||||||
tcg_out_insn(s, RX, ST, data, base, index, disp);
|
tcg_out_insn(s, RX, ST, data, base, index, disp);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_insn(s, RXY, STY, data, base, index, disp);
|
tcg_out_insn(s, RXY, STY, data, base, index, disp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MO_Q:
|
|
||||||
if (bswap) {
|
case MO_Q | MO_BSWAP:
|
||||||
tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
|
tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
|
||||||
} else {
|
|
||||||
tcg_out_insn(s, RXY, STG, data, base, index, disp);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
case MO_Q:
|
||||||
|
tcg_out_insn(s, RXY, STG, data, base, index, disp);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
tcg_abort();
|
tcg_abort();
|
||||||
}
|
}
|
||||||
|
@ -1457,7 +1453,7 @@ static TCGReg tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
|
||||||
tcg_out_call(s, qemu_ld_helpers[s_bits]);
|
tcg_out_call(s, qemu_ld_helpers[s_bits]);
|
||||||
|
|
||||||
/* sign extension */
|
/* sign extension */
|
||||||
switch (opc) {
|
switch (opc & MO_SSIZE) {
|
||||||
case MO_SB:
|
case MO_SB:
|
||||||
tgen_ext8s(s, TCG_TYPE_I64, data_reg, TCG_REG_R2);
|
tgen_ext8s(s, TCG_TYPE_I64, data_reg, TCG_REG_R2);
|
||||||
break;
|
break;
|
||||||
|
@ -1808,30 +1804,30 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
tcg_out_qemu_ld(s, args, MO_SB);
|
tcg_out_qemu_ld(s, args, MO_SB);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld16u:
|
case INDEX_op_qemu_ld16u:
|
||||||
tcg_out_qemu_ld(s, args, MO_UW);
|
tcg_out_qemu_ld(s, args, MO_TEUW);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld16s:
|
case INDEX_op_qemu_ld16s:
|
||||||
tcg_out_qemu_ld(s, args, MO_SW);
|
tcg_out_qemu_ld(s, args, MO_TESW);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld32:
|
case INDEX_op_qemu_ld32:
|
||||||
/* ??? Technically we can use a non-extending instruction. */
|
/* ??? Technically we can use a non-extending instruction. */
|
||||||
tcg_out_qemu_ld(s, args, MO_UL);
|
tcg_out_qemu_ld(s, args, MO_TEUL);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld64:
|
case INDEX_op_qemu_ld64:
|
||||||
tcg_out_qemu_ld(s, args, MO_Q);
|
tcg_out_qemu_ld(s, args, MO_TEQ);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_st8:
|
case INDEX_op_qemu_st8:
|
||||||
tcg_out_qemu_st(s, args, MO_UB);
|
tcg_out_qemu_st(s, args, MO_UB);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st16:
|
case INDEX_op_qemu_st16:
|
||||||
tcg_out_qemu_st(s, args, MO_UW);
|
tcg_out_qemu_st(s, args, MO_TEUW);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st32:
|
case INDEX_op_qemu_st32:
|
||||||
tcg_out_qemu_st(s, args, MO_UL);
|
tcg_out_qemu_st(s, args, MO_TEUL);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_st64:
|
case INDEX_op_qemu_st64:
|
||||||
tcg_out_qemu_st(s, args, MO_Q);
|
tcg_out_qemu_st(s, args, MO_TEQ);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_ld16s_i64:
|
case INDEX_op_ld16s_i64:
|
||||||
|
@ -2028,10 +2024,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_qemu_ld32u:
|
case INDEX_op_qemu_ld32u:
|
||||||
tcg_out_qemu_ld(s, args, MO_UL);
|
tcg_out_qemu_ld(s, args, MO_TEUL);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_qemu_ld32s:
|
case INDEX_op_qemu_ld32s:
|
||||||
tcg_out_qemu_ld(s, args, MO_SL);
|
tcg_out_qemu_ld(s, args, MO_TESL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
OP_32_64(deposit):
|
OP_32_64(deposit):
|
||||||
|
|
Loading…
Reference in a new issue