]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390x: reconsider "long displacement" requirement. We currently
authorJulian Seward <jseward@acm.org>
Wed, 13 Apr 2011 15:38:17 +0000 (15:38 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 13 Apr 2011 15:38:17 +0000 (15:38 +0000)
require that the host supports accessing memory using long
displacement. On older machines e.g. z900 that is an expensive
operation, because it is millicoded. It would be a performance win to
relax that requirement.  (VEX side changes.)  See #268620.
(Florian Krohm, britzel@acm.org)

git-svn-id: svn://svn.valgrind.org/vex/trunk@2126

VEX/priv/host_s390_defs.c
VEX/priv/host_s390_defs.h
VEX/priv/host_s390_isel.c
VEX/priv/main_main.c
VEX/pub/libvex.h

index 3e0eaf79c5bb80379d18a69f75d5be51275686bd..17cc7377576445eeca88215cd229b08712a9efee 100644 (file)
@@ -265,8 +265,6 @@ s390_amode_for_guest_state(Int offset)
 {
    if (fits_unsigned_12bit(offset))
       return s390_amode_b12(offset, s390_hreg_guest_state_pointer());
-   if (fits_signed_20bit(offset))
-      return s390_amode_b20(offset, s390_hreg_guest_state_pointer());
 
    vpanic("invalid guest state offset");
 }
@@ -1142,6 +1140,8 @@ s390_emit_A(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_AY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "ay", r1, dh2, dl2, x2, b2);
 
@@ -1152,6 +1152,8 @@ s390_emit_AY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_AG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "ag", r1, dh2, dl2, x2, b2);
 
@@ -1162,6 +1164,8 @@ s390_emit_AG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_AFI(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, INT), "afi", r1, i2);
 
@@ -1172,6 +1176,8 @@ s390_emit_AFI(UChar *p, UChar r1, UInt i2)
 static UChar *
 s390_emit_AGFI(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, INT), "agfi", r1, i2);
 
@@ -1192,6 +1198,8 @@ s390_emit_AH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_AHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "ahy", r1, dh2, dl2, x2, b2);
 
@@ -1252,6 +1260,8 @@ s390_emit_N(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_NY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "ny", r1, dh2, dl2, x2, b2);
 
@@ -1262,6 +1272,8 @@ s390_emit_NY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_NG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "ng", r1, dh2, dl2, x2, b2);
 
@@ -1272,6 +1284,8 @@ s390_emit_NG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_NIHF(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, UINT), "nihf", r1, i2);
 
@@ -1282,6 +1296,8 @@ s390_emit_NIHF(UChar *p, UChar r1, UInt i2)
 static UChar *
 s390_emit_NILF(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, UINT), "nilf", r1, i2);
 
@@ -1362,6 +1378,8 @@ s390_emit_C(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_CY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "cy", r1, dh2, dl2, x2, b2);
 
@@ -1372,6 +1390,8 @@ s390_emit_CY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_CG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "cg", r1, dh2, dl2, x2, b2);
 
@@ -1382,6 +1402,8 @@ s390_emit_CG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_CFI(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, INT), "cfi", r1, i2);
 
@@ -1402,6 +1424,8 @@ s390_emit_CS(UChar *p, UChar r1, UChar r3, UChar b2, UShort d2)
 static UChar *
 s390_emit_CSY(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "csy", r1, r3, dh2, dl2, 0, b2);
 
@@ -1412,6 +1436,8 @@ s390_emit_CSY(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_CSG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "csg", r1, r3, dh2, dl2, 0, b2);
 
@@ -1452,6 +1478,8 @@ s390_emit_CL(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_CLY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "cly", r1, dh2, dl2, x2, b2);
 
@@ -1462,6 +1490,8 @@ s390_emit_CLY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_CLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "clg", r1, dh2, dl2, x2, b2);
 
@@ -1472,6 +1502,8 @@ s390_emit_CLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_CLFI(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, UINT), "clfi", r1, i2);
 
@@ -1522,6 +1554,8 @@ s390_emit_DLGR(UChar *p, UChar r1, UChar r2)
 static UChar *
 s390_emit_DL(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "dl", r1, dh2, dl2, x2, b2);
 
@@ -1532,6 +1566,8 @@ s390_emit_DL(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_DLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "dlg", r1, dh2, dl2, x2, b2);
 
@@ -1552,6 +1588,8 @@ s390_emit_DSGR(UChar *p, UChar r1, UChar r2)
 static UChar *
 s390_emit_DSG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "dsg", r1, dh2, dl2, x2, b2);
 
@@ -1592,6 +1630,8 @@ s390_emit_X(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_XY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "xy", r1, dh2, dl2, x2, b2);
 
@@ -1602,6 +1642,8 @@ s390_emit_XY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_XG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "xg", r1, dh2, dl2, x2, b2);
 
@@ -1612,6 +1654,8 @@ s390_emit_XG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_XIHF(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, UINT), "xihf", r1, i2);
 
@@ -1622,6 +1666,8 @@ s390_emit_XIHF(UChar *p, UChar r1, UInt i2)
 static UChar *
 s390_emit_XILF(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, UINT), "xilf", r1, i2);
 
@@ -1632,6 +1678,8 @@ s390_emit_XILF(UChar *p, UChar r1, UInt i2)
 static UChar *
 s390_emit_FLOGR(UChar *p, UChar r1, UChar r2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, GPR), "flogr", r1, r2);
 
@@ -1652,6 +1700,8 @@ s390_emit_IC(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_ICY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "icy", r1, dh2, dl2, x2, b2);
 
@@ -1662,6 +1712,8 @@ s390_emit_ICY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_IIHF(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, UINT), "iihf", r1, i2);
 
@@ -1692,6 +1744,8 @@ s390_emit_IIHL(UChar *p, UChar r1, UShort i2)
 static UChar *
 s390_emit_IILF(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, UINT), "iilf", r1, i2);
 
@@ -1772,6 +1826,8 @@ s390_emit_L(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_LY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "ly", r1, dh2, dl2, x2, b2);
 
@@ -1782,6 +1838,8 @@ s390_emit_LY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_LG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "lg", r1, dh2, dl2, x2, b2);
 
@@ -1792,6 +1850,8 @@ s390_emit_LG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_LGF(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "lgf", r1, dh2, dl2, x2, b2);
 
@@ -1802,6 +1862,8 @@ s390_emit_LGF(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_LGFI(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, INT), "lgfi", r1, i2);
 
@@ -1832,6 +1894,8 @@ s390_emit_LTGR(UChar *p, UChar r1, UChar r2)
 static UChar *
 s390_emit_LT(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "lt", r1, dh2, dl2, x2, b2);
 
@@ -1842,6 +1906,8 @@ s390_emit_LT(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_LTG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "ltg", r1, dh2, dl2, x2, b2);
 
@@ -1852,6 +1918,8 @@ s390_emit_LTG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_LBR(UChar *p, UChar r1, UChar r2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, GPR), "lbr", r1, r2);
 
@@ -1862,6 +1930,8 @@ s390_emit_LBR(UChar *p, UChar r1, UChar r2)
 static UChar *
 s390_emit_LGBR(UChar *p, UChar r1, UChar r2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, GPR), "lgbr", r1, r2);
 
@@ -1872,6 +1942,8 @@ s390_emit_LGBR(UChar *p, UChar r1, UChar r2)
 static UChar *
 s390_emit_LB(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "lb", r1, dh2, dl2, x2, b2);
 
@@ -1882,6 +1954,8 @@ s390_emit_LB(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_LGB(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "lgb", r1, dh2, dl2, x2, b2);
 
@@ -1912,6 +1986,8 @@ s390_emit_LCGR(UChar *p, UChar r1, UChar r2)
 static UChar *
 s390_emit_LHR(UChar *p, UChar r1, UChar r2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, GPR), "lhr", r1, r2);
 
@@ -1922,6 +1998,8 @@ s390_emit_LHR(UChar *p, UChar r1, UChar r2)
 static UChar *
 s390_emit_LGHR(UChar *p, UChar r1, UChar r2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, GPR), "lghr", r1, r2);
 
@@ -1942,6 +2020,8 @@ s390_emit_LH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_LHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "lhy", r1, dh2, dl2, x2, b2);
 
@@ -1952,6 +2032,8 @@ s390_emit_LHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_LGH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "lgh", r1, dh2, dl2, x2, b2);
 
@@ -1992,6 +2074,8 @@ s390_emit_LLGFR(UChar *p, UChar r1, UChar r2)
 static UChar *
 s390_emit_LLGF(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "llgf", r1, dh2, dl2, x2, b2);
 
@@ -2002,6 +2086,8 @@ s390_emit_LLGF(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_LLCR(UChar *p, UChar r1, UChar r2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, GPR), "llcr", r1, r2);
 
@@ -2012,6 +2098,8 @@ s390_emit_LLCR(UChar *p, UChar r1, UChar r2)
 static UChar *
 s390_emit_LLGCR(UChar *p, UChar r1, UChar r2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, GPR), "llgcr", r1, r2);
 
@@ -2022,6 +2110,8 @@ s390_emit_LLGCR(UChar *p, UChar r1, UChar r2)
 static UChar *
 s390_emit_LLC(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "llc", r1, dh2, dl2, x2, b2);
 
@@ -2032,6 +2122,8 @@ s390_emit_LLC(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_LLGC(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "llgc", r1, dh2, dl2, x2, b2);
 
@@ -2042,6 +2134,8 @@ s390_emit_LLGC(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_LLHR(UChar *p, UChar r1, UChar r2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, GPR), "llhr", r1, r2);
 
@@ -2052,6 +2146,8 @@ s390_emit_LLHR(UChar *p, UChar r1, UChar r2)
 static UChar *
 s390_emit_LLGHR(UChar *p, UChar r1, UChar r2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, GPR), "llghr", r1, r2);
 
@@ -2062,6 +2158,8 @@ s390_emit_LLGHR(UChar *p, UChar r1, UChar r2)
 static UChar *
 s390_emit_LLH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "llh", r1, dh2, dl2, x2, b2);
 
@@ -2072,6 +2170,8 @@ s390_emit_LLH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_LLGH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "llgh", r1, dh2, dl2, x2, b2);
 
@@ -2082,6 +2182,8 @@ s390_emit_LLGH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_LLILF(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, UINT), "llilf", r1, i2);
 
@@ -2132,6 +2234,8 @@ s390_emit_M(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_MFY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_gie);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "mfy", r1, dh2, dl2, x2, b2);
 
@@ -2152,6 +2256,8 @@ s390_emit_MH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_MHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_gie);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "mhy", r1, dh2, dl2, x2, b2);
 
@@ -2192,6 +2298,8 @@ s390_emit_MLGR(UChar *p, UChar r1, UChar r2)
 static UChar *
 s390_emit_ML(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "ml", r1, dh2, dl2, x2, b2);
 
@@ -2202,6 +2310,8 @@ s390_emit_ML(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_MLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "mlg", r1, dh2, dl2, x2, b2);
 
@@ -2242,6 +2352,8 @@ s390_emit_MS(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_MSY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "msy", r1, dh2, dl2, x2, b2);
 
@@ -2252,6 +2364,8 @@ s390_emit_MSY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_MSG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "msg", r1, dh2, dl2, x2, b2);
 
@@ -2262,6 +2376,8 @@ s390_emit_MSG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_MSFI(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_gie);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, INT), "msfi", r1, i2);
 
@@ -2272,6 +2388,8 @@ s390_emit_MSFI(UChar *p, UChar r1, UInt i2)
 static UChar *
 s390_emit_MSGFI(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_gie);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, INT), "msgfi", r1, i2);
 
@@ -2312,6 +2430,8 @@ s390_emit_O(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_OY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "oy", r1, dh2, dl2, x2, b2);
 
@@ -2322,6 +2442,8 @@ s390_emit_OY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_OG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "og", r1, dh2, dl2, x2, b2);
 
@@ -2332,6 +2454,8 @@ s390_emit_OG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_OIHF(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, UINT), "oihf", r1, i2);
 
@@ -2342,6 +2466,8 @@ s390_emit_OIHF(UChar *p, UChar r1, UInt i2)
 static UChar *
 s390_emit_OILF(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, UINT), "oilf", r1, i2);
 
@@ -2372,6 +2498,8 @@ s390_emit_SLL(UChar *p, UChar r1, UChar b2, UShort d2)
 static UChar *
 s390_emit_SLLG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "sllg", r1, r3, dh2, dl2, 0, b2);
 
@@ -2392,6 +2520,8 @@ s390_emit_SRA(UChar *p, UChar r1, UChar b2, UShort d2)
 static UChar *
 s390_emit_SRAG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "srag", r1, r3, dh2, dl2, 0, b2);
 
@@ -2412,6 +2542,8 @@ s390_emit_SRL(UChar *p, UChar r1, UChar b2, UShort d2)
 static UChar *
 s390_emit_SRLG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "srlg", r1, r3, dh2, dl2, 0, b2);
 
@@ -2432,6 +2564,8 @@ s390_emit_ST(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_STY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "sty", r1, dh2, dl2, x2, b2);
 
@@ -2442,6 +2576,8 @@ s390_emit_STY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_STG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "stg", r1, dh2, dl2, x2, b2);
 
@@ -2462,6 +2598,8 @@ s390_emit_STC(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_STCY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "stcy", r1, dh2, dl2, x2, b2);
 
@@ -2482,6 +2620,8 @@ s390_emit_STH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_STHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "sthy", r1, dh2, dl2, x2, b2);
 
@@ -2522,6 +2662,8 @@ s390_emit_S(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_SY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "sy", r1, dh2, dl2, x2, b2);
 
@@ -2532,6 +2674,8 @@ s390_emit_SY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_SG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "sg", r1, dh2, dl2, x2, b2);
 
@@ -2552,6 +2696,8 @@ s390_emit_SH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_SHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, SDXB), "shy", r1, dh2, dl2, x2, b2);
 
@@ -2562,6 +2708,8 @@ s390_emit_SHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_SLFI(UChar *p, UChar r1, UInt i2)
 {
+   vassert(s390_host_has_eimm);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, UINT), "slfi", r1, i2);
 
@@ -2612,6 +2760,8 @@ s390_emit_LD(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_LEY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, FPR, SDXB), "ley", r1, dh2, dl2, x2, b2);
 
@@ -2622,6 +2772,8 @@ s390_emit_LEY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_LDY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, FPR, SDXB), "ldy", r1, dh2, dl2, x2, b2);
 
@@ -2642,6 +2794,7 @@ s390_emit_LFPC(UChar *p, UChar b2, UShort d2)
 static UChar *
 s390_emit_LDGR(UChar *p, UChar r1, UChar r2)
 {
+   /* fixs390: PR 268619 */
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, FPR, GPR), "ldgr", r1, r2);
 
@@ -2652,6 +2805,7 @@ s390_emit_LDGR(UChar *p, UChar r1, UChar r2)
 static UChar *
 s390_emit_LGDR(UChar *p, UChar r1, UChar r2)
 {
+   /* fixs390: PR 268619 */
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, GPR, FPR), "lgdr", r1, r2);
 
@@ -2712,6 +2866,8 @@ s390_emit_STD(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 static UChar *
 s390_emit_STEY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, FPR, SDXB), "stey", r1, dh2, dl2, x2, b2);
 
@@ -2722,6 +2878,8 @@ s390_emit_STEY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 static UChar *
 s390_emit_STDY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 {
+   vassert(s390_host_has_ldisp);
+
    if (unlikely(vex_traceflags & VEX_TRACE_ASM))
       s390_disasm(ENC3(MNM, FPR, SDXB), "stdy", r1, dh2, dl2, x2, b2);
 
@@ -3423,6 +3581,22 @@ s390_emit_XILFw(UChar *p, UChar r1, UInt i2)
 }
 
 
+/* r1[32:63] = sign_extend(mem[op2addr][0:7]) */
+static UChar *
+s390_emit_LBw(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
+{
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
+   if (s390_host_has_ldisp) {
+      return s390_emit_LB(p, r1, x2, b2, dl2, dh2);
+   }
+
+   p = s390_emit_IC(p, r1, x2, b2, dl2);    /* r1[56:63] = mem[op2addr][0:7] */
+   p = s390_emit_SLL(p, r1, R0, 24);        /* r1 = r1 << 24  */
+   return s390_emit_SRA(p, r1, R0, 24);     /* r1 = r1 >>a 24 */
+}
+
+
 /*  r1[32:63] = sign_extend(r2[56:63]) */
 static UChar *
 s390_emit_LBRw(UChar *p, UChar r1, UChar r2)
@@ -3437,6 +3611,22 @@ s390_emit_LBRw(UChar *p, UChar r1, UChar r2)
 }
 
 
+/* r1[0:63] = sign_extend(mem[op2addr][0:7]) */
+static UChar *
+s390_emit_LGBw(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
+{
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
+   if (s390_host_has_ldisp) {
+      return s390_emit_LGB(p, r1, x2, b2, dl2, dh2);
+   }
+
+   p = s390_emit_IC(p, r1, x2, b2, dl2);             /* r1[56:63] = mem[op2addr][0:7] */
+   p = s390_emit_SLLG(p, r1, r1, R0, DISP20(56));    /* r1 = r1 << 56  */
+   return s390_emit_SRAG(p, r1, r1, R0, DISP20(56)); /* r1 = r1 >>a 56 */
+}
+
+
 /*  r1[0:63] = sign_extend(r2[56:63]) */
 static UChar *
 s390_emit_LGBRw(UChar *p, UChar r1, UChar r2)
@@ -4861,9 +5051,9 @@ s390_insn_move_emit(UChar *buf, const s390_insn *insn)
          return s390_emit_LDR(buf, dst, src);
    } else {
       if (dst_class == HRcFlt64 && src_class == HRcInt64)
-         return s390_emit_LDGR(buf, dst, src);
+         return s390_emit_LDGR(buf, dst, src);   /* fixs390: PR 268619 */
       if (dst_class == HRcInt64 && src_class == HRcFlt64)
-         return s390_emit_LGDR(buf, dst, src);
+         return s390_emit_LGDR(buf, dst, src);   /* fixs390: PR 268619 */
       /* A move between floating point registers and general purpose
          registers of different size should never occur and indicates
          an error elsewhere. */
@@ -4968,6 +5158,8 @@ s390_insn_alu_emit(UChar *buf, const s390_insn *insn)
 
       /* Shift operands are special here as there are no opcodes that
          allow a memory operand. So we first load the 2nd operand to R0. */
+
+      /* fixs390: NO. Using R0 as the base will ignore the register contents. */
       if (insn->variant.alu.tag == S390_ALU_LSH ||
           insn->variant.alu.tag == S390_ALU_RSH ||
           insn->variant.alu.tag == S390_ALU_RSHA) {
@@ -5245,6 +5437,11 @@ s390_insn_alu_emit(UChar *buf, const s390_insn *insn)
             buf = s390_emit_load_64imm(buf, R0, value);
             return s390_emit_XGR(buf, dst, R0);
 
+            /* No special considerations for long displacement here. Only the six
+               least significant bits of VALUE will be taken; all other bits are
+               ignored. So the DH2 bits are irrelevant and do not influence the
+               shift operation, independent of whether long-displacement is available
+               or not. */
          case S390_ALU_LSH:  return s390_emit_SLLG(buf, dst, dst, 0, DISP20(value));
          case S390_ALU_RSH:  return s390_emit_SRLG(buf, dst, dst, 0, DISP20(value));
          case S390_ALU_RSHA: return s390_emit_SRAG(buf, dst, dst, 0, DISP20(value));
@@ -5328,15 +5525,14 @@ s390_widen_emit(UChar *buf, const s390_insn *insn, UInt from_size,
       case 1:
          if (insn->size == 4 || insn->size == 2) {
             if (sign_extend)
-               return s390_emit_LB(buf, r1, x, b, DISP20(d));
+               return s390_emit_LBw(buf, r1, x, b, DISP20(d));
             else
                return s390_emit_LLCw(buf, r1, x, b, DISP20(d));
          }
          if (insn->size == 8) {
             if (sign_extend)
-               return s390_emit_LGB(buf, r1, x, b, DISP20(d));
+               return s390_emit_LGBw(buf, r1, x, b, DISP20(d));
             else
-               /* No wrapper required. Opcode exists as RXE and RXY */
                return s390_emit_LLGC(buf, r1, x, b, DISP20(d));
          }
          goto fail;
@@ -5358,7 +5554,6 @@ s390_widen_emit(UChar *buf, const s390_insn *insn, UInt from_size,
             goto fail;
          }
          if (insn->size == 8) {  /* 16 --> 64 */
-            /* No wrappers required. Opcodes exist as RXE and RXY */
             if (sign_extend)
                return s390_emit_LGH(buf, r1, x, b, DISP20(d));
             else
@@ -5368,7 +5563,6 @@ s390_widen_emit(UChar *buf, const s390_insn *insn, UInt from_size,
 
       case 4:
          if (insn->size == 8) {  /* 32 --> 64 */
-            /* No wrappers required. Opcodes exist as RXE and RXY */
             if (sign_extend)
                return s390_emit_LGF(buf, r1, x, b, DISP20(d));
             else
index 9781258c27a02ae343fd51782d817dba7362a89c..e409bd5b37e8bedf3da04a667f0673eec87d4f93 100644 (file)
@@ -483,6 +483,8 @@ HInstrArray *iselSB_S390   ( IRSB *, VexArch, VexArchInfo *, VexAbiInfo * );
 extern const VexArchInfo *s390_archinfo_host;
 
 /* Convenience macros to test installed facilities */
+#define s390_host_has_ldisp \
+                      (s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_LDISP))
 #define s390_host_has_eimm \
                       (s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_EIMM))
 #define s390_host_has_gie \
index 80e5759a54283077848a1db877b6dfaa0bfe5cad..beb03b3c3a59b750f0383d31551d698e8aecef3f 100644 (file)
@@ -227,7 +227,9 @@ s390_isel_amode_wrk(ISelEnv *env, IRExpr *expr)
          if (ulong_fits_unsigned_12bit(value)) {
             return s390_amode_b12((Int)value, s390_isel_int_expr(env, arg1));
          }
-         if (ulong_fits_signed_20bit(value)) {
+         /* If long-displacement is not available, do not construct B20 or
+            BX20 amodes because code generation cannot handle them. */
+         if (s390_host_has_ldisp && ulong_fits_signed_20bit(value)) {
             return s390_amode_b20((Int)value, s390_isel_int_expr(env, arg1));
          }
       }
@@ -2350,9 +2352,8 @@ iselSB_S390(IRSB *bb, VexArch arch_host, VexArchInfo *archinfo_host,
    /* KLUDGE: export archinfo_host. */
    s390_archinfo_host = archinfo_host;
 
-
    /* Do some sanity checks */
-   vassert((hwcaps_host & ~(VEX_HWCAPS_S390X_ALL)) == 0);
+   vassert((VEX_HWCAPS_S390X(hwcaps_host) & ~(VEX_HWCAPS_S390X_ALL)) == 0);
 
    /* Make up an initial environment to use. */
    env = LibVEX_Alloc(sizeof(ISelEnv));
index 4a4d2c93a7d4e671cd898e453b633d3dd6f1c89c..989bb6c130e6928dbc0e6e152679c88aed1c13d3 100644 (file)
@@ -934,6 +934,8 @@ static HChar* show_hwcaps_s390x ( UInt hwcaps )
    const UInt GE = VEX_HWCAPS_S390X_GIE;
    const UInt DF = VEX_HWCAPS_S390X_DFP;
 
+   hwcaps = VEX_HWCAPS_S390X(hwcaps);
+
    if (hwcaps == (LD))          return "s390x-ldisp";
    if (hwcaps == (LD|EI))       return "s390x-ldisp-eimm";
    if (hwcaps == (LD|GE))       return "s390x-ldisp-gie";
@@ -943,7 +945,7 @@ static HChar* show_hwcaps_s390x ( UInt hwcaps )
    if (hwcaps == (LD|GE|DF))    return "s390x-ldisp-gie-dfp";
    if (hwcaps == (LD|EI|GE|DF)) return "s390x-ldisp-eimm-gie-dfp";
 
-   return NULL;
+   return "s390-zarch";
 }
 
 /* ---- */
index 84a55a8368800a9f85467441d02f5c33642e2ce4..e7f94e1fc52bca0a1d85dde5cadb696a7a32c2ce 100644 (file)
@@ -94,18 +94,45 @@ typedef
 #define VEX_HWCAPS_PPC64_GX    (1<<14) /* Graphics extns
                                           (fres,frsqrte,fsel,stfiwx) */
 
-/* s390x: baseline capability is z/Architecture with long displacement */
-#define VEX_HWCAPS_S390X_LDISP (1<<13)  /* Long-displacement facility */
-#define VEX_HWCAPS_S390X_EIMM  (1<<14)  /* Extended-immediate facility */
-#define VEX_HWCAPS_S390X_GIE   (1<<15)  /* General-instruction-extension
-                                           facility */
-#define VEX_HWCAPS_S390X_DFP   (1<<16)  /* Decimal floating point facility */
+/* s390x: Hardware capability encoding
+
+   Bits    Information
+   [26:31] Machine model
+   [25]    Long displacement facility
+   [24]    Extended-immediate facility
+   [23]    General-instruction-extension facility
+   [22]    Decimal floating point facility
+   [0:21]  Currently unused; reserved for future use
+*/
+
+/* Model numbers must be assigned in chronological order.
+   They are used as array index. */
+#define VEX_S390X_MODEL_Z900     0
+#define VEX_S390X_MODEL_Z800     1
+#define VEX_S390X_MODEL_Z990     2
+#define VEX_S390X_MODEL_Z890     3
+#define VEX_S390X_MODEL_Z9_EC    4
+#define VEX_S390X_MODEL_Z9_BC    5
+#define VEX_S390X_MODEL_Z10_EC   6
+#define VEX_S390X_MODEL_Z10_BC   7
+#define VEX_S390X_MODEL_Z196     8
+#define VEX_S390X_MODEL_INVALID  9
+#define VEX_S390X_MODEL_MASK     0x3F
+
+#define VEX_HWCAPS_S390X_LDISP (1<<6)  /* Long-displacement facility */
+#define VEX_HWCAPS_S390X_EIMM  (1<<7)  /* Extended-immediate facility */
+#define VEX_HWCAPS_S390X_GIE   (1<<8)  /* General-instruction-extension facility */
+#define VEX_HWCAPS_S390X_DFP   (1<<9)  /* Decimal floating point facility */
+
 /* Special value representing all available s390x hwcaps */
 #define VEX_HWCAPS_S390X_ALL   (VEX_HWCAPS_S390X_LDISP | \
                                 VEX_HWCAPS_S390X_EIMM  | \
                                 VEX_HWCAPS_S390X_GIE   | \
                                 VEX_HWCAPS_S390X_DFP)
 
+#define VEX_HWCAPS_S390X(x)  ((x) & ~VEX_S390X_MODEL_MASK)
+#define VEX_S390X_MODEL(x)   ((x) &  VEX_S390X_MODEL_MASK)
+
 /* arm: baseline capability is ARMv4 */
 /* Bits 5:0 - architecture level (e.g. 5 for v5, 6 for v6 etc) */
 #define VEX_HWCAPS_ARM_VFP    (1<<6)  /* VFP extension */