// micro-architecture target hook should be introduced here in future.
bool AArch64InstrInfo::isAsCheapAsAMove(const MachineInstr *MI) const {
if (!Subtarget.isCortexA57() && !Subtarget.isCortexA53() &&
- !Subtarget.isKryo())
+ !Subtarget.isExynosM1() && !Subtarget.isKryo())
return MI->isAsCheapAsAMove();
+ unsigned Imm;
+
switch (MI->getOpcode()) {
default:
return false;
case AArch64::ADDXri:
case AArch64::SUBWri:
case AArch64::SUBXri:
- return (MI->getOperand(3).getImm() == 0);
+ return (Subtarget.isExynosM1() ||
+ MI->getOperand(3).getImm() == 0);
+
+ // add/sub on register with shift
+ case AArch64::ADDWrs:
+ case AArch64::ADDXrs:
+ case AArch64::SUBWrs:
+ case AArch64::SUBXrs:
+ Imm = MI->getOperand(3).getImm();
+ return (Subtarget.isExynosM1() &&
+ AArch64_AM::getArithShiftValue(Imm) < 4);
// logical ops on immediate
case AArch64::ANDWri:
case AArch64::ORRWrr:
case AArch64::ORRXrr:
return true;
+
+ // logical ops on register with shift
+ case AArch64::ANDWrs:
+ case AArch64::ANDXrs:
+ case AArch64::BICWrs:
+ case AArch64::BICXrs:
+ case AArch64::EONWrs:
+ case AArch64::EONXrs:
+ case AArch64::EORWrs:
+ case AArch64::EORXrs:
+ case AArch64::ORNWrs:
+ case AArch64::ORNXrs:
+ case AArch64::ORRWrs:
+ case AArch64::ORRXrs:
+ Imm = MI->getOperand(3).getImm();
+ return (Subtarget.isExynosM1() &&
+ AArch64_AM::getShiftValue(Imm) < 4 &&
+ AArch64_AM::getShiftType(Imm) == AArch64_AM::LSL);
+
// If MOVi32imm or MOVi64imm can be expanded into ORRWri or
// ORRXri, it is as cheap as MOV
case AArch64::MOVi32imm: