stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
}
-/* Add a dummy put to the guest_IA to satisfy an assert in bb_to_IR
- that wants the last statement in an IRSB to be a put to the guest_IA.
- Mostly used for insns that use the "counter" pseudo guest reg. */
-static __inline__ void
-dummy_put_IA(void)
-{
- put_IA(IRExpr_Get(S390X_GUEST_OFFSET(guest_IA), Ity_I64));
-}
-
/* Create a temporary of the given type and assign the expression to it */
static __inline__ IRTemp
mktemp(IRType type, IRExpr *expr)
dis_res->jk_StopHere = Ijk_Sys_syscall;
}
+/* A side exit that branches back to the current insn if CONDITION is
+ true. Does not set DisResult. */
+static void
+iterate_if(IRExpr *condition)
+{
+ vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
+
+ stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
+ S390X_GUEST_OFFSET(guest_IA)));
+}
+
+/* A side exit that branches back to the current insn.
+ Does not set DisResult. */
+static __inline__ void
+iterate(void)
+{
+ iterate_if(IRExpr_Const(IRConst_U1(True)));
+}
+
+/* A side exit that branches back to the insn immediately following the
+ current insn if CONDITION is true. Does not set DisResult. */
+static void
+next_insn_if(IRExpr *condition)
+{
+ vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
+
+ stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
+ S390X_GUEST_OFFSET(guest_IA)));
+}
+
+/* Convenience function to restart the current insn */
+static void
+restart_if(IRExpr *condition)
+{
+ vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
+
+ stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
+ S390X_GUEST_OFFSET(guest_IA)));
+}
+
+/* Convenience function to yield to thread scheduler */
+static void
+yield_if(IRExpr *condition)
+{
+ stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
+ S390X_GUEST_OFFSET(guest_IA)));
+}
+
/* Encode the s390 rounding mode as it appears in the m3/m4 fields of certain
instructions to VEX's IRRoundingMode. */
static IRRoundingMode
IRTemp op2addr = newTemp(Ity_I64);
IRTemp d2 = newTemp(Ity_I64);
- if_condition_goto(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
+
assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
mkU64(0)));
irgen(r1, op2addr);
- dummy_put_IA();
+
+ vassert(dis_res->whatNext == Dis_Continue);
if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
static HChar *
s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
{
- if_condition_goto(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
put_gpr_w1(r1, get_gpr_w1(r2));
- dummy_put_IA();
return "locr";
}
static HChar *
s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
{
- if_condition_goto(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
put_gpr_dw0(r1, get_gpr_dw0(r2));
- dummy_put_IA();
return "locgr";
}
assign(len, mkU64(length));
s390_irgen_CLC_EX(len, start1, start2);
- dummy_put_IA();
return "clc";
}
/* len1 == 0 and len2 == 0? Exit */
s390_cc_set(0);
- if_condition_goto(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
- mkexpr(len2)), mkU32(0)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
+ mkexpr(len2)), mkU32(0)));
/* Because mkite evaluates both the then-clause and the else-clause
we cannot load directly from addr1 here. If len1 is 0, then adddr1
s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
/* Fields differ ? */
- if_condition_goto(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
/* Update len1 and addr1, unless len1 == 0. */
put_gpr_dw0(r1,
binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
- always_goto_and_chase(guest_IA_curr_instr);
+ iterate();
return "clcl";
}
/* len1 == 0 and len3 == 0? Exit */
s390_cc_set(0);
- if_condition_goto(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
- mkexpr(len3)), mkU64(0)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
+ mkexpr(len3)), mkU64(0)));
/* A mux requires both ways to be possible. This is a way to prevent clcle
from reading from addr1 if it should read from the pad. Since the pad
s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
/* Both fields differ ? */
- if_condition_goto(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
/* If a length in 0 we must not change this length and the address */
put_gpr_dw0(r1,
mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
- always_goto_and_chase(guest_IA_curr_instr);
+ iterate();
return "clcle";
}
False);
/* Both fields differ ? */
- if_condition_goto(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
/* Check for end of field */
put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
- if_condition_goto(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)),
- guest_IA_curr_instr);
+ iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
put_counter_dw0(mkU64(0));
}
/* Check for end of field */
put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
- if_condition_goto(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)),
- guest_IA_curr_instr);
+ iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
put_counter_dw0(mkU64(0));
}
store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
- if_condition_goto(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)),
- guest_IA_curr_instr);
+ iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
put_counter_dw0(mkU64(0));
}
static void
s390_irgen_EX_SS(UChar r, IRTemp addr2,
-void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2), int lensize)
+ void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
+ int lensize)
{
struct SS {
unsigned int op : 8;
stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
mkU64(guest_IA_curr_instr)));
stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
- stmt(IRStmt_Exit(mkexpr(cond), Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
- S390X_GUEST_OFFSET(guest_IA)));
+ restart_if(mkexpr(cond));
ss.bytes = last_execute_target;
assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
irgen(len, start1, start2);
- dummy_put_IA();
last_execute_target = 0;
}
stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
mkU64(guest_IA_curr_instr)));
stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
- stmt(IRStmt_Exit(IRExpr_Const(IRConst_U1(True)), Ijk_TInval,
- IRConst_U64(guest_IA_curr_instr),
- S390X_GUEST_OFFSET(guest_IA)));
+ restart_if(IRExpr_Const(IRConst_U1(True)));
+
/* we know that this will be invalidated */
put_IA(mkaddr_expr(guest_IA_next_instr));
dis_res->whatNext = Dis_StopHere;
/* and restart */
stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
- stmt(IRStmt_Exit(mkexpr(cond), Ijk_TInval,
- IRConst_U64(guest_IA_curr_instr),
- S390X_GUEST_OFFSET(guest_IA)));
+ restart_if(mkexpr(cond));
/* Now comes the actual translation */
bytes = (UChar *) &last_execute_target;
vex_printf(" which was executed by\n");
/* dont make useless translations in the next execute */
last_execute_target = 0;
- dummy_put_IA();
}
}
return "ex";
// start = next? CC=2 and out r1 and r2 unchanged
s390_cc_set(2);
put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
- if_condition_goto(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
assign(byte, load(Ity_I8, mkexpr(address)));
assign(delim, get_gpr_b7(0));
// byte = delim? CC=1, R1=address
s390_cc_set(1);
put_gpr_dw0(r1, mkexpr(address));
- if_condition_goto(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
// else: all equal, no end yet, loop
put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
put_gpr_dw0(r1, mkexpr(next));
put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
- always_goto_and_chase(guest_IA_curr_instr);
+ iterate();
return "srst";
}
s390_cc_set(0);
put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
- if_condition_goto(binop(Iop_CmpEQ8, mkU8(0),
- binop(Iop_Or8,
- binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
- binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
+ binop(Iop_Or8,
+ binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
+ binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
put_gpr_dw0(r1, mkexpr(address1));
put_gpr_dw0(r2, mkexpr(address2));
// End found in string1
s390_cc_set(1);
- if_condition_goto(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
// End found in string2
s390_cc_set(2);
- if_condition_goto(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
// string1 < string2
s390_cc_set(1);
- if_condition_goto(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
- unop(Iop_8Uto32, mkexpr(byte2))),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
+ unop(Iop_8Uto32, mkexpr(byte2))));
// string2 < string1
s390_cc_set(2);
- if_condition_goto(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
- unop(Iop_8Uto32, mkexpr(byte1))),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
+ unop(Iop_8Uto32, mkexpr(byte1))));
// else: all equal, no end yet, loop
put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
- always_goto_and_chase(guest_IA_curr_instr);
+ iterate();
return "clst";
}
/* Check for end of field */
put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
- if_condition_goto(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)),
- guest_IA_curr_instr);
+ iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
False);
put_counter_dw0(mkU64(0));
assign(len, mkU32(length));
s390_irgen_xonc(Iop_Xor8, len, start1, start2);
- dummy_put_IA();
return "xc";
}
/* Check for end of field */
put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
- if_condition_goto(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)),
- guest_IA_curr_instr);
+ iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
/* Reset counter */
put_counter_dw0(mkU64(0));
}
s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
- dummy_put_IA();
if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
assign(len, mkU32(length));
s390_irgen_xonc(Iop_And8, len, start1, start2);
- dummy_put_IA();
return "nc";
}
assign(len, mkU32(length));
s390_irgen_xonc(Iop_Or8, len, start1, start2);
- dummy_put_IA();
return "oc";
}
assign(len, mkU64(length));
s390_irgen_MVC_EX(len, start1, start2);
- dummy_put_IA();
return "mvc";
}
/* len1 == 0 ? */
s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
- if_condition_goto(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
/* Check for destructive overlap:
addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
binop(Iop_Add64, mkexpr(addr2),
unop(Iop_32Uto64, mkexpr(len2))))));
- if_condition_goto(binop(Iop_CmpEQ32,
- binop(Iop_And32,
- binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
- mkexpr(cond3)),
- mkU32(1)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
+ mkexpr(cond3)),
+ mkU32(1)));
/* See s390_irgen_CLCL for explanation why we cannot load directly
and need two steps. */
binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
- if_condition_goto(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)),
- guest_IA_curr_instr);
+ iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
return "mvcl";
}
// len1 == 0 ?
s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
- if_condition_goto(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
/* This is a hack to prevent mvcle from reading from addr3 if it
should read from the pad. Since the pad has no address, just
mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
- if_condition_goto(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)),
- guest_IA_curr_instr);
+ iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
return "mvcle";
}
// We use unlimited as cpu-determined number
put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
- if_condition_goto(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)),
- guest_IA_curr_instr);
+ iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
// and always set cc=1 at the end + update r1
s390_cc_set(1);
put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
put_counter_dw0(mkU64(0));
- dummy_put_IA();
return "mvst";
}
Otherwise, store the old_value from memory in r1 and yield. */
assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
- stmt(IRStmt_Exit(mkexpr(nequal), Ijk_Yield,
- IRConst_U64(guest_IA_next_instr),
- S390X_GUEST_OFFSET(guest_IA)));
+ yield_if(mkexpr(nequal));
}
static HChar *
Otherwise, store the old_value from memory in r1 and yield. */
assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
- stmt(IRStmt_Exit(mkexpr(nequal), Ijk_Yield,
- IRConst_U64(guest_IA_next_instr),
- S390X_GUEST_OFFSET(guest_IA)));
+ yield_if(mkexpr(nequal));
return "csg";
}
assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
- stmt(IRStmt_Exit(mkexpr(nequal), Ijk_Yield,
- IRConst_U64(guest_IA_next_instr),
- S390X_GUEST_OFFSET(guest_IA)));
+ yield_if(mkexpr(nequal));
}
static HChar *
assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
- stmt(IRStmt_Exit(mkexpr(nequal), Ijk_Yield,
- IRConst_U64(guest_IA_next_instr),
- S390X_GUEST_OFFSET(guest_IA)));
+ yield_if(mkexpr(nequal));
+
return "cdsg";
}
s390_cc_set(0);
/* If length is zero, there is no need to calculate the checksum */
- if_condition_goto(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
/* Assiging the increment variable to adjust address and length
later on. */
put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
- if_condition_goto(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)),
- guest_IA_curr_instr);
+ iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
return "cksm";
}
/* End of source string? We're done; proceed to next insn */
s390_cc_set(0);
- if_condition_goto(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
/* Load character from source string, index translation table and
store translated character in op1. */
if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
s390_cc_set(1);
- if_condition_goto(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
}
store(get_gpr_dw0(r1), mkexpr(op1));
put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
- always_goto_and_chase(guest_IA_curr_instr);
+ iterate();
return "troo";
}
/* End of source string? We're done; proceed to next insn */
s390_cc_set(0);
- if_condition_goto(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
/* Load character from source string, index translation table and
store translated character in op1. */
if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
s390_cc_set(1);
- if_condition_goto(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
}
store(get_gpr_dw0(r1), mkexpr(op1));
put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
- always_goto_and_chase(guest_IA_curr_instr);
+ iterate();
return "trto";
}
/* End of source string? We're done; proceed to next insn */
s390_cc_set(0);
- if_condition_goto(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
/* Load character from source string, index translation table and
store translated character in op1. */
if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
s390_cc_set(1);
- if_condition_goto(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
}
store(get_gpr_dw0(r1), mkexpr(op1));
put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
- always_goto_and_chase(guest_IA_curr_instr);
+ iterate();
return "trot";
}
/* End of source string? We're done; proceed to next insn */
s390_cc_set(0);
- if_condition_goto(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
/* Load character from source string, index translation table and
store translated character in op1. */
if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
s390_cc_set(1);
- if_condition_goto(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
}
store(get_gpr_dw0(r1), mkexpr(op1));
put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
- always_goto_and_chase(guest_IA_curr_instr);
+ iterate();
return "trtt";
}
assign(len, mkU64(length));
s390_irgen_TR_EX(len, start1, start2);
- dummy_put_IA();
return "tr";
}
/* End of source string? We're done; proceed to next insn */
s390_cc_set(0);
- if_condition_goto(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
/* Load character from source string and compare with test byte */
assign(op, load(Ity_I8, mkexpr(src_addr)));
s390_cc_set(1);
- if_condition_goto(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
mkexpr(tab_addr)));
put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
- always_goto_and_chase(guest_IA_curr_instr);
+ iterate();
return "tre";
}
there are less than 2 bytes left, then the 2nd operand is exhausted
and we're done here. cc = 0 */
s390_cc_set(0);
- if_condition_goto(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
/* There are at least two bytes there. Read them. */
IRTemp srcval = newTemp(Ity_I32);
IRExpr *not_enough_bytes =
mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
- if_condition_goto(binop(Iop_CmpEQ32,
- binop(Iop_And32, mkexpr(is_high_surrogate),
- not_enough_bytes),
- mkU32(1)), guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ32,
+ binop(Iop_And32, mkexpr(is_high_surrogate),
+ not_enough_bytes), mkU32(1)));
/* The 2nd operand is not exhausted. If the first 2 bytes are a high
surrogate, read the next two bytes (low surrogate). */
binop(Iop_And64, mkexpr(retval), mkU64(0xff));
s390_cc_set(2);
- if_condition_goto(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
}
/* Now test whether the 1st operand is exhausted */
binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
mkU64(0xff)));
s390_cc_set(1);
- if_condition_goto(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
/* Extract the bytes to be stored at addr1 */
IRTemp data = newTemp(Ity_I64);
put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
- /* Iterate */
- always_goto_and_chase(guest_IA_curr_instr);
+ iterate();
return "cu21";
}
there are less than 2 bytes left, then the 2nd operand is exhausted
and we're done here. cc = 0 */
s390_cc_set(0);
- if_condition_goto(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
/* There are at least two bytes there. Read them. */
IRTemp srcval = newTemp(Ity_I32);
IRExpr *not_enough_bytes =
mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
- if_condition_goto(binop(Iop_CmpEQ32,
- binop(Iop_And32, mkexpr(is_high_surrogate),
- not_enough_bytes),
- mkU32(1)), guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ32,
+ binop(Iop_And32, mkexpr(is_high_surrogate),
+ not_enough_bytes),
+ mkU32(1)));
/* The 2nd operand is not exhausted. If the first 2 bytes are a high
surrogate, read the next two bytes (low surrogate). */
binop(Iop_And64, mkexpr(retval), mkU64(0xff));
s390_cc_set(2);
- if_condition_goto(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
}
/* Now test whether the 1st operand is exhausted */
s390_cc_set(1);
- if_condition_goto(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)),
- guest_IA_next_instr);
+ next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
/* Extract the bytes to be stored at addr1 */
IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
- /* Iterate */
- always_goto_and_chase(guest_IA_curr_instr);
+ iterate();
return "cu24";
}