}
+static UChar *
+s390_emit_TM(UChar *p, UChar i2, UChar b1, UShort d1)
+{
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+ s390_disasm(ENC3(MNM, UDXB, INT), "tm", d1, 0, b1, i2);
+
+ return emit_SI(p, 0x91000000, i2, b1, d1);
+}
+
+
+static UChar *
+s390_emit_TMY(UChar *p, UChar i2, UChar b1, UShort dl1, UChar dh1)
+{
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+ s390_disasm(ENC3(MNM, SDXB, INT), "tmy", dh1, dl1, 0, b1, (Int)(Char)i2);
+
+ return emit_SIY(p, 0xeb0000000051ULL, i2, b1, dl1, dh1);
+}
+
+
+static UChar *
+s390_emit_TMLL(UChar *p, UChar r1, UShort i2)
+{
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+ s390_disasm(ENC3(MNM, GPR, UINT), "tmll", r1, i2);
+
+ return emit_RI(p, 0xa7010000, r1, i2);
+}
+
+
static UChar *
s390_emit_BASR(UChar *p, UChar r1, UChar r2)
{
{
s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
- vassert(size == 4 || size == 8);
+ vassert(size == 1 || size == 2 || size == 4 || size == 8);
insn->tag = S390_INSN_TEST;
insn->size = size;
}
-/* Only 4-byte and 8-byte operands are handled. 1-byte and 2-byte
- comparisons will have been converted to 4-byte comparisons in
- s390_isel_cc and should not occur here. */
+/* Test operand for zero. */
static UChar *
s390_insn_test_emit(UChar *buf, const s390_insn *insn)
{
UInt reg = hregNumber(opnd.variant.reg);
switch (insn->size) {
+ case 1:
+ return s390_emit_TMLL(buf, reg, 0xff);
+
+ case 2:
+ return s390_emit_TMLL(buf, reg, 0xffff);
+
case 4:
return s390_emit_LTR(buf, reg, reg);
Int d = am->d;
switch (insn->size) {
+ case 1:
+ switch (am->tag) {
+ case S390_AMODE_B12:
+ return s390_emit_TM(buf, 0xff, b, d);
+ case S390_AMODE_B20:
+ return s390_emit_TMY(buf, 0xff, b, DISP20(d));
+ default:
+ buf = s390_emit_LB(buf, R0, x, b, DISP20(d));
+ return s390_emit_TMLL(buf, R0, 0xff);
+ }
+
+ case 2:
+ switch (am->tag) {
+ case S390_AMODE_B12:
+ buf = s390_emit_LH(buf, R0, x, b, d);
+ return s390_emit_TMLL(buf, R0, 0xffff);
+ default:
+ buf = s390_emit_LHY(buf, R0, x, b, DISP20(d));
+ return s390_emit_TMLL(buf, R0, 0xffff);
+ }
+
case 4:
return s390_emit_LTw(buf, R0, x, b, DISP20(d));
}
case S390_OPND_IMMEDIATE: {
- ULong value = opnd.variant.imm;
-
- switch (insn->size) {
- case 4:
- buf = s390_emit_load_32imm(buf, R0, value);
- return s390_emit_LTR(buf, R0, R0);
-
- case 8:
- buf = s390_emit_load_64imm(buf, R0, value);
- return s390_emit_LTGR(buf, R0, R0);
-
- default:
- goto fail;
- }
+ if (opnd.variant.imm == 0)
+ return s390_emit_CR(buf, R0, R0);
+ else
+ return s390_emit_OILL(buf, R0, 1);
}
default: