[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 50/62] tcg-s390: Conditionalize 8 and 16 bit extensi
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 50/62] tcg-s390: Conditionalize 8 and 16 bit extensions. |
Date: |
Thu, 27 May 2010 13:46:32 -0700 |
These instructions are part of the extended-immediate facility.
Signed-off-by: Richard Henderson <address@hidden>
---
tcg/s390/tcg-target.c | 115 ++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 90 insertions(+), 25 deletions(-)
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index 491de07..8a7c9ae 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -156,11 +156,9 @@ typedef enum S390Opcode {
RXY_LGF = 0xe314,
RXY_LGH = 0xe315,
RXY_LHY = 0xe378,
- RXY_LLC = 0xe394,
RXY_LLGC = 0xe390,
RXY_LLGF = 0xe316,
RXY_LLGH = 0xe391,
- RXY_LLH = 0xe395,
RXY_LMG = 0xeb04,
RXY_LRV = 0xe31e,
RXY_LRVG = 0xe30f,
@@ -653,24 +651,84 @@ static void tcg_out_ld_abs(TCGContext *s, TCGType type,
TCGReg dest, void *abs)
tcg_out_ld(s, type, dest, dest, addr & 0xffff);
}
-static inline void tgen_ext8s(TCGContext *s, TCGReg dest, TCGReg src)
+static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
{
- tcg_out_insn(s, RRE, LGBR, dest, src);
+ if (facilities & FACILITY_EXT_IMM) {
+ tcg_out_insn(s, RRE, LGBR, dest, src);
+ return;
+ }
+
+ if (type == TCG_TYPE_I32) {
+ if (dest == src) {
+ tcg_out_sh32(s, RS_SLL, dest, SH32_REG_NONE, 24);
+ } else {
+ tcg_out_sh64(s, RSY_SLLG, dest, src, SH64_REG_NONE, 24);
+ }
+ tcg_out_sh32(s, RS_SRA, dest, SH32_REG_NONE, 24);
+ } else {
+ tcg_out_sh64(s, RSY_SLLG, dest, src, SH64_REG_NONE, 56);
+ tcg_out_sh64(s, RSY_SRAG, dest, dest, SH64_REG_NONE, 56);
+ }
}
-static inline void tgen_ext8u(TCGContext *s, TCGReg dest, TCGReg src)
+static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
{
- tcg_out_insn(s, RRE, LLGCR, dest, src);
+ if (facilities & FACILITY_EXT_IMM) {
+ tcg_out_insn(s, RRE, LLGCR, dest, src);
+ return;
+ }
+
+ if (dest == src) {
+ tcg_out_movi(s, type, TCG_TMP0, 0xff);
+ src = TCG_TMP0;
+ } else {
+ tcg_out_movi(s, type, dest, 0xff);
+ }
+ if (type == TCG_TYPE_I32) {
+ tcg_out_insn(s, RR, NR, dest, src);
+ } else {
+ tcg_out_insn(s, RRE, NGR, dest, src);
+ }
}
-static inline void tgen_ext16s(TCGContext *s, TCGReg dest, TCGReg src)
+static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
{
- tcg_out_insn(s, RRE, LGHR, dest, src);
+ if (facilities & FACILITY_EXT_IMM) {
+ tcg_out_insn(s, RRE, LGHR, dest, src);
+ return;
+ }
+
+ if (type == TCG_TYPE_I32) {
+ if (dest == src) {
+ tcg_out_sh32(s, RS_SLL, dest, SH32_REG_NONE, 16);
+ } else {
+ tcg_out_sh64(s, RSY_SLLG, dest, src, SH64_REG_NONE, 16);
+ }
+ tcg_out_sh32(s, RS_SRA, dest, SH32_REG_NONE, 24);
+ } else {
+ tcg_out_sh64(s, RSY_SLLG, dest, src, SH64_REG_NONE, 48);
+ tcg_out_sh64(s, RSY_SRAG, dest, dest, SH64_REG_NONE, 48);
+ }
}
-static inline void tgen_ext16u(TCGContext *s, TCGReg dest, TCGReg src)
+static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
{
- tcg_out_insn(s, RRE, LLGHR, dest, src);
+ if (facilities & FACILITY_EXT_IMM) {
+ tcg_out_insn(s, RRE, LLGHR, dest, src);
+ return;
+ }
+
+ if (dest == src) {
+ tcg_out_movi(s, type, TCG_TMP0, 0xffff);
+ src = TCG_TMP0;
+ } else {
+ tcg_out_movi(s, type, dest, 0xffff);
+ }
+ if (type == TCG_TYPE_I32) {
+ tcg_out_insn(s, RR, NR, dest, src);
+ } else {
+ tcg_out_insn(s, RRE, NGR, dest, src);
+ }
}
static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
@@ -972,7 +1030,7 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, int opc,
TCGReg data,
if (bswap) {
/* swapped unsigned halfword load with upper bits zeroed */
tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
- tgen_ext16u(s, data, data);
+ tgen_ext16u(s, TCG_TYPE_I64, data, data);
} else {
tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
}
@@ -981,7 +1039,7 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, int opc,
TCGReg data,
if (bswap) {
/* swapped sign-extended halfword load */
tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
- tgen_ext16s(s, data, data);
+ tgen_ext16s(s, TCG_TYPE_I64, data, data);
} else {
tcg_out_insn(s, RXY, LGH, data, base, index, disp);
}
@@ -1117,10 +1175,10 @@ static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg
data_reg,
/* sign extension */
switch (opc) {
case LD_INT8:
- tgen_ext8s(s, data_reg, arg0);
+ tgen_ext8s(s, TCG_TYPE_I64, data_reg, arg0);
break;
case LD_INT16:
- tgen_ext16s(s, data_reg, arg0);
+ tgen_ext16s(s, TCG_TYPE_I64, data_reg, arg0);
break;
case LD_INT32:
tgen_ext32s(s, data_reg, arg0);
@@ -1264,23 +1322,22 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode
opc,
break;
case INDEX_op_ld8u_i32:
- tcg_out_ldst(s, 0, RXY_LLC, args[0], args[1], args[2]);
- break;
case INDEX_op_ld8u_i64:
+ /* ??? LLC (RXY format) is only present with the extended-immediate
+ facility, whereas LLGC is always present. */
tcg_out_ldst(s, 0, RXY_LLGC, args[0], args[1], args[2]);
break;
case INDEX_op_ld8s_i32:
- tcg_out_ldst(s, 0, RXY_LB, args[0], args[1], args[2]);
- break;
case INDEX_op_ld8s_i64:
+ /* ??? LB is no smaller than LGB, so no point to using it. */
tcg_out_ldst(s, 0, RXY_LGB, args[0], args[1], args[2]);
break;
case INDEX_op_ld16u_i32:
- tcg_out_ldst(s, 0, RXY_LLH, args[0], args[1], args[2]);
- break;
case INDEX_op_ld16u_i64:
+ /* ??? LLH (RXY format) is only present with the extended-immediate
+ facility, whereas LLGH is always present. */
tcg_out_ldst(s, 0, RXY_LLGH, args[0], args[1], args[2]);
break;
@@ -1517,24 +1574,32 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode
opc,
break;
case INDEX_op_ext8s_i32:
+ tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
+ break;
case INDEX_op_ext8s_i64:
- tgen_ext8s(s, args[0], args[1]);
+ tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
break;
case INDEX_op_ext16s_i32:
+ tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
+ break;
case INDEX_op_ext16s_i64:
- tgen_ext16s(s, args[0], args[1]);
+ tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
break;
case INDEX_op_ext32s_i64:
tgen_ext32s(s, args[0], args[1]);
break;
case INDEX_op_ext8u_i32:
+ tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
+ break;
case INDEX_op_ext8u_i64:
- tgen_ext8u(s, args[0], args[1]);
+ tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
break;
case INDEX_op_ext16u_i32:
+ tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
+ break;
case INDEX_op_ext16u_i64:
- tgen_ext16u(s, args[0], args[1]);
+ tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
break;
case INDEX_op_ext32u_i64:
tgen_ext32u(s, args[0], args[1]);
@@ -1545,7 +1610,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode
opc,
/* The TCG bswap definition requires bits 0-47 already be zero.
Thus we don't need the G-type insns to implement bswap16_i64. */
tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
- tcg_out_insn(s, RS, SRL, args[0], 0, SH32_REG_NONE, 16);
+ tcg_out_sh32(s, RS_SRL, args[0], SH32_REG_NONE, 16);
break;
case INDEX_op_bswap32_i32:
case INDEX_op_bswap32_i64:
--
1.7.0.1
- [Qemu-devel] [PATCH 36/62] tcg-s390: Icache flush is a no-op., (continued)
- [Qemu-devel] [PATCH 36/62] tcg-s390: Icache flush is a no-op., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 40/62] tcg-s390: Tidy goto_tb., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 41/62] tcg-s390: Allocate the code_gen_buffer near the main program., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 42/62] tcg-s390: Rearrange qemu_ld/st to avoid register copy., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 44/62] tcg-s390: Tidy user qemu_ld/st., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 45/62] tcg-s390: Implement GUEST_BASE., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 43/62] tcg-s390: Tidy tcg_prepare_qemu_ldst., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 47/62] tcg-s390: Conditionalize general-instruction-extension insns., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 48/62] tcg-s390: Conditionalize ADD IMMEDIATE instructions., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 46/62] tcg-s390: Query instruction extensions that are installed., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 50/62] tcg-s390: Conditionalize 8 and 16 bit extensions.,
Richard Henderson <=
- [Qemu-devel] [PATCH 49/62] tcg-s390: Conditionalize LOAD IMMEDIATE instructions., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 51/62] tcg-s390: Conditionalize AND IMMEDIATE instructions., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 52/62] tcg-s390: Conditionalize OR IMMEDIATE instructions., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 53/62] tcg-s390: Conditionalize XOR IMMEDIATE instructions., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 54/62] tcg-s390: Do not require the extended-immediate facility., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 55/62] tcg-s390: Use 16-bit branches for forward jumps., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 56/62] tcg-s390: Use the LOAD AND TEST instruction for compares., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 57/62] tcg-s390: Use the COMPARE IMMEDIATE instrucions for compares., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 58/62] tcg-s390: Use COMPARE AND BRANCH instructions., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 61/62] tcg-s390: Enable compile in 32-bit mode., Richard Henderson, 2010/05/27