提交 b8dd88b8 编写于 作者: R Richard Henderson

tcg-s390: Integrate endianness into TCGMemOp

Signed-off-by: NRichard Henderson <rth@twiddle.net>
上级 a5a04f28
...@@ -1273,11 +1273,6 @@ static void tcg_out_call(TCGContext *s, tcg_insn_unit *dest) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 | MO_BSWAP:
tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
break;
case MO_Q: case MO_Q:
if (bswap) { tcg_out_insn(s, RXY, STG, 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;
default: default:
tcg_abort(); tcg_abort();
} }
...@@ -1457,7 +1453,7 @@ static TCGReg tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg, ...@@ -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, ...@@ -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, ...@@ -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):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册