}
+static UChar *
+s390_emit_LA(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
+{
+ return emit_RX(p, 0x41000000, r1, x2, b2, d2);
+}
+
+
+static UChar *
+s390_emit_LAY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
+{
+ return emit_RXY(p, 0xe30000000071ULL, r1, x2, b2, dl2, dh2);
+}
+
+
static UChar *
s390_emit_LG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
{
op = "v-signx";
break;
+ case S390_LOAD_ADDRESS:
+ op = "v-laddr";
+ break;
+
case S390_NEGATE:
op = "v-neg";
break;
case S390_SIGN_EXTEND_16: return s390_widen_emit(buf, insn, 2, 1);
case S390_SIGN_EXTEND_32: return s390_widen_emit(buf, insn, 4, 1);
- case S390_NEGATE: return s390_negate_emit(buf, insn);
+ case S390_LOAD_ADDRESS: {
+ vassert(insn->variant.unop.src.tag == S390_OPND_AMODE);
+ UChar dst = hregNumber(insn->variant.unop.dst);
+ s390_amode* am = insn->variant.unop.src.variant.am;
+ UChar x = hregNumber(am->x);
+ UChar b = hregNumber(am->b);
+ switch (am->tag) {
+ case S390_AMODE_B12:
+ case S390_AMODE_BX12:
+ return s390_emit_LA(buf, dst, x, b, am->d);
+ case S390_AMODE_B20:
+ case S390_AMODE_BX20:
+ return s390_emit_LAY(buf, dst, x, b, DISP20(am->d));
+ }
+ vpanic("s390_insn_unop_emit -- load address");
+ }
+ case S390_NEGATE:
+ return s390_negate_emit(buf, insn);
case S390_POPCNT: return s390_popcnt_emit(buf, insn);
case S390_VEC_FILL: {
vassert(insn->variant.unop.src.tag == S390_OPND_IMMEDIATE);
}
}
+ /* Is this a match for "load address"? */
+ if (expr->Iex.Binop.op == Iop_Add64) {
+ ULong disp = arg2->Iex.Const.con->Ico.U64;
+ if (arg2->tag == Iex_Const && ulong_fits_signed_20bit(disp)) {
+ h1 = s390_isel_int_expr(env, arg1);
+ opnd.tag = S390_OPND_AMODE;
+ if (ulong_fits_unsigned_12bit(disp)) {
+ opnd.variant.am = s390_amode_b12(disp, h1);
+ } else {
+ opnd.variant.am = s390_amode_b20((Int)disp, h1);
+ }
+ addInstr(env, s390_insn_unop(size, S390_LOAD_ADDRESS, res, opnd));
+ return res;
+ }
+ }
+
h1 = s390_isel_int_expr(env, arg1); /* Process 1st operand */
op2 = s390_isel_int_expr_RMI(env, arg2); /* Process 2nd operand */