{
assert(hasImmediateOperand);
- if (isRMW)
- {
- GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true);
-
- HWIntrinsicImmOpHelper helper(this, intrin.op3, node);
+ auto emitShift = [&](GenTree* op, regNumber reg) {
+ HWIntrinsicImmOpHelper helper(this, op, node);
for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd())
{
const int shiftAmount = helper.ImmValue();
- GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, op2Reg, shiftAmount, opt);
+ if (shiftAmount == 0)
+ {
+ // TODO: Use emitIns_Mov instead.
+ // We do not use it currently because it will still elide the 'mov'
+ // even if 'canSkip' is false. We cannot elide the 'mov' here.
+ GetEmitter()->emitIns_R_R_R(INS_mov, emitTypeSize(node), targetReg, reg, reg);
+ }
+ else
+ {
+ GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, reg, shiftAmount, opt);
+ }
}
+ };
+
+ if (isRMW)
+ {
+ GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true);
+ emitShift(intrin.op3, op2Reg);
}
else
{
- HWIntrinsicImmOpHelper helper(this, intrin.op2, node);
-
- for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd())
- {
- const int shiftAmount = helper.ImmValue();
-
- GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, op1Reg, shiftAmount, opt);
- }
+ emitShift(intrin.op2, op1Reg);
}
}
else