[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 58/62] tcg-s390: Use COMPARE AND BRANCH instructions
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 58/62] tcg-s390: Use COMPARE AND BRANCH instructions. |
Date: |
Thu, 27 May 2010 13:46:40 -0700 |
These instructions are available with the general-instructions-extension
facility. Use them if available.
Signed-off-by: Richard Henderson <address@hidden>
---
tcg/s390/tcg-target.c | 102 +++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 95 insertions(+), 7 deletions(-)
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index 5af8bc9..4e3fb8b 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -114,6 +114,15 @@ typedef enum S390Opcode {
RI_OILH = 0xa50a,
RI_OILL = 0xa50b,
+ RIE_CGIJ = 0xec7c,
+ RIE_CGRJ = 0xec64,
+ RIE_CIJ = 0xec7e,
+ RIE_CLGRJ = 0xec65,
+ RIE_CLIJ = 0xec7f,
+ RIE_CLGIJ = 0xec7d,
+ RIE_CLRJ = 0xec77,
+ RIE_CRJ = 0xec76,
+
RRE_AGR = 0xb908,
RRE_CGR = 0xb920,
RRE_CLGR = 0xb921,
@@ -1100,6 +1109,7 @@ static void tgen64_xori(TCGContext *s, TCGReg dest,
tcg_target_ulong val)
static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
TCGArg c2, int c2const)
{
+ _Bool is_unsigned = (c > TCG_COND_GT);
if (c2const) {
if (c2 == 0) {
if (type == TCG_TYPE_I32) {
@@ -1109,15 +1119,13 @@ static int tgen_cmp(TCGContext *s, TCGType type,
TCGCond c, TCGReg r1,
}
return tcg_cond_to_ltr_cond[c];
} else {
- if (c > TCG_COND_GT) {
- /* unsigned */
+ if (is_unsigned) {
if (type == TCG_TYPE_I32) {
tcg_out_insn(s, RIL, CLFI, r1, c2);
} else {
tcg_out_insn(s, RIL, CLGFI, r1, c2);
}
} else {
- /* signed */
if (type == TCG_TYPE_I32) {
tcg_out_insn(s, RIL, CFI, r1, c2);
} else {
@@ -1126,15 +1134,13 @@ static int tgen_cmp(TCGContext *s, TCGType type,
TCGCond c, TCGReg r1,
}
}
} else {
- if (c > TCG_COND_GT) {
- /* unsigned */
+ if (is_unsigned) {
if (type == TCG_TYPE_I32) {
tcg_out_insn(s, RR, CLR, r1, c2);
} else {
tcg_out_insn(s, RRE, CLGR, r1, c2);
}
} else {
- /* signed */
if (type == TCG_TYPE_I32) {
tcg_out_insn(s, RR, CR, r1, c2);
} else {
@@ -1185,10 +1191,92 @@ static void tgen_branch(TCGContext *s, int cc, int
labelno)
}
}
+static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
+ TCGReg r1, TCGReg r2, int labelno)
+{
+ TCGLabel* l = &s->labels[labelno];
+ tcg_target_long off;
+
+ if (l->has_value) {
+ off = (l->u.value - (tcg_target_long)s->code_ptr) >> 1;
+ } else {
+ /* We need to keep the offset unchanged for retranslation. */
+ off = ((int16_t *)s->code_ptr)[1];
+ tcg_out_reloc(s, s->code_ptr + 2, R_390_PC16DBL, labelno, -2);
+ }
+
+ tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
+ tcg_out16(s, off);
+ tcg_out16(s, cc << 12 | (opc & 0xff));
+}
+
+static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
+ TCGReg r1, int i2, int labelno)
+{
+ TCGLabel* l = &s->labels[labelno];
+ tcg_target_long off;
+
+ if (l->has_value) {
+ off = (l->u.value - (tcg_target_long)s->code_ptr) >> 1;
+ } else {
+ /* We need to keep the offset unchanged for retranslation. */
+ off = ((int16_t *)s->code_ptr)[1];
+ tcg_out_reloc(s, s->code_ptr + 2, R_390_PC16DBL, labelno, -2);
+ }
+
+ tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
+ tcg_out16(s, off);
+ tcg_out16(s, (i2 << 8) | (opc & 0xff));
+}
+
static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
TCGReg r1, TCGArg c2, int c2const, int labelno)
{
- int cc = tgen_cmp(s, type, c, r1, c2, c2const);
+ int cc;
+
+ if (facilities & FACILITY_GEN_INST_EXT) {
+ _Bool is_unsigned = (c > TCG_COND_GT);
+ _Bool in_range;
+ S390Opcode opc;
+
+ cc = tcg_cond_to_s390_cond[c];
+
+ if (!c2const) {
+ opc = (type == TCG_TYPE_I32
+ ? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
+ : (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
+ tgen_compare_branch(s, opc, cc, r1, c2, labelno);
+ return;
+ }
+
+ /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
+ If the immediate we've been given does not fit that range, we'll
+ fall back to separate compare and branch instructions using the
+ larger comparison range afforded by COMPARE IMMEDIATE. */
+ if (type == TCG_TYPE_I32) {
+ if (is_unsigned) {
+ opc = RIE_CLIJ;
+ in_range = (uint32_t)c2 == (uint8_t)c2;
+ } else {
+ opc = RIE_CIJ;
+ in_range = (int32_t)c2 == (int8_t)c2;
+ }
+ } else {
+ if (is_unsigned) {
+ opc = RIE_CLGIJ;
+ in_range = (uint64_t)c2 == (uint8_t)c2;
+ } else {
+ opc = RIE_CGIJ;
+ in_range = (int64_t)c2 == (int8_t)c2;
+ }
+ }
+ if (in_range) {
+ tgen_compare_imm_branch(s, opc, cc, r1, c2, labelno);
+ return;
+ }
+ }
+
+ cc = tgen_cmp(s, type, c, r1, c2, c2const);
tgen_branch(s, cc, labelno);
}
--
1.7.0.1
- [Qemu-devel] [PATCH 46/62] tcg-s390: Query instruction extensions that are installed., (continued)
- [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, 2010/05/27
- [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 <=
- [Qemu-devel] [PATCH 61/62] tcg-s390: Enable compile in 32-bit mode., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 59/62] tcg-s390: Generalize load/store support., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 60/62] tcg-s390: Fix TLB comparison width., Richard Henderson, 2010/05/27
- [Qemu-devel] [PATCH 62/62] tcg: Optionally sign-extend 32-bit arguments for 64-bit host., Richard Henderson, 2010/05/27
- Re: [Qemu-devel] [PATCH 00/62] s390x tcg target, Blue Swirl, 2010/05/27