/* 100 1101 0100 mm cond 00 nn dd = CSEL Xd, Xn, Xm, cond */
UInt dd = iregEnc(i->ARM64in.CSel.dst);
UInt nn = iregEnc(i->ARM64in.CSel.argL);
- UInt mm = iregEnc(i->ARM64in.CSel.argR);
+ UInt mm = iregEncOr31(i->ARM64in.CSel.argR); // Can be XZR
UInt cond = (UInt)i->ARM64in.CSel.cond;
- vassert(dd < 31 && nn < 31 && mm < 31 && cond < 16);
+ vassert(dd < 31 && nn < 31 && mm <= 31 && cond < 16);
*p++ = X_3_8_5_6_5_5(X100, X11010100, mm, cond << 2, nn, dd);
goto done;
}
case Iop_1Sto32:
case Iop_1Sto64: {
/* As with the iselStmt case for 'tmp:I1 = expr', we could
- do a lot better here if it ever became necessary. */
- HReg zero = newVRegI(env);
+ do a lot better here if it ever became necessary. (CSDEC?) */
+ HReg zero = hregARM64_XZR_XSP(); // XZR in this context
HReg one = newVRegI(env);
HReg dst = newVRegI(env);
- addInstr(env, ARM64Instr_Imm64(zero, 0));
addInstr(env, ARM64Instr_Imm64(one, 1));
ARM64CondCode cc = iselCondCode_C(env, e->Iex.Unop.arg);
addInstr(env, ARM64Instr_CSel(dst, one, zero, cc));
addInstr(env, ARM64Instr_Logic(dst, src, one, ARM64lo_AND));
} else {
/* CLONE-01 */
- HReg zero = newVRegI(env);
+ HReg zero = hregARM64_XZR_XSP(); // XZR in this context
HReg one = newVRegI(env);
- addInstr(env, ARM64Instr_Imm64(zero, 0));
addInstr(env, ARM64Instr_Imm64(one, 1));
ARM64CondCode cc = iselCondCode_C(env, e->Iex.Unop.arg);
addInstr(env, ARM64Instr_CSel(dst, one, zero, cc));
in that case. Also, could do this just with a single CINC
insn. */
/* CLONE-01 */
- HReg zero = newVRegI(env);
+ HReg zero = hregARM64_XZR_XSP(); // XZR in this context
HReg one = newVRegI(env);
HReg dst = lookupIRTemp(env, tmp);
- addInstr(env, ARM64Instr_Imm64(zero, 0));
addInstr(env, ARM64Instr_Imm64(one, 1));
ARM64CondCode cc = iselCondCode_C(env, stmt->Ist.WrTmp.data);
addInstr(env, ARM64Instr_CSel(dst, one, zero, cc));