}
bool AArch64InstrInfo::isExynosResetFast(const MachineInstr &MI) const {
+ unsigned Reg, Imm, Shift;
+
switch (MI.getOpcode()) {
default:
return false;
+ // MOV Rd, SP
+ case AArch64::ADDWri:
+ case AArch64::ADDXri:
+ if (!MI.getOperand(1).isReg() || !MI.getOperand(2).isImm())
+ return false;
+
+ Reg = MI.getOperand(1).getReg();
+ Imm = MI.getOperand(2).getImm();
+ return ((Reg == AArch64::WSP || Reg == AArch64::SP) && Imm == 0);
+
+ // Literal
case AArch64::ADR:
case AArch64::ADRP:
-
- case AArch64::MOVNWi:
- case AArch64::MOVNXi:
- case AArch64::MOVZWi:
- case AArch64::MOVZXi:
return true;
+ // MOVI Vd, #0
case AArch64::MOVID:
- case AArch64::MOVIv2d_ns:
case AArch64::MOVIv8b_ns:
+ case AArch64::MOVIv2d_ns:
case AArch64::MOVIv16b_ns:
- return (MI.getOperand(1).getImm() == 0);
+ Imm = MI.getOperand(1).getImm();
+ return (Imm == 0);
+ // MOVI Vd, #0
case AArch64::MOVIv2i32:
- case AArch64::MOVIv4i32:
case AArch64::MOVIv4i16:
+ case AArch64::MOVIv4i32:
case AArch64::MOVIv8i16:
- return (MI.getOperand(1).getImm() == 0 &&
- MI.getOperand(2).getImm() == 0);
+ Imm = MI.getOperand(1).getImm();
+ Shift = MI.getOperand(2).getImm();
+ return (Imm == 0 && Shift == 0);
+
+ // MOV Rd, Imm
+ case AArch64::MOVNWi:
+ case AArch64::MOVNXi:
+
+ // MOV Rd, Imm
+ case AArch64::MOVZWi:
+ case AArch64::MOVZXi:
+ return true;
+
+ // MOV Rd, Imm
+ case AArch64::ORRWri:
+ case AArch64::ORRXri:
+ if (!MI.getOperand(1).isReg())
+ return false;
+
+ Reg = MI.getOperand(1).getReg();
+ Imm = MI.getOperand(2).getImm();
+ return ((Reg == AArch64::WZR || Reg == AArch64::XZR) && Imm == 0);
+
+ // MOV Rd, Rm
+ case AArch64::ORRWrs:
+ case AArch64::ORRXrs:
+ if (!MI.getOperand(1).isReg())
+ return false;
+
+ Reg = MI.getOperand(1).getReg();
+ Imm = MI.getOperand(3).getImm();
+ Shift = AArch64_AM::getShiftValue(Imm);
+ return ((Reg == AArch64::WZR || Reg == AArch64::XZR) && Shift == 0);
}
}
// Predicates.
def M3BranchLinkFastPred : SchedPredicate<[{MI->getOpcode() == AArch64::BLR &&
+ MI->getOperand(0).isReg() &&
MI->getOperand(0).getReg() != AArch64::LR}]>;
def M3ResetFastPred : SchedPredicate<[{TII->isExynosResetFast(*MI)}]>;
def M3ShiftLeftFastPred : SchedPredicate<[{TII->isExynosShiftLeftFast(*MI)}]>;
let NumMicroOps = 2; }
def M3WriteC1 : SchedWriteRes<[M3UnitC]> { let Latency = 1; }
def M3WriteC2 : SchedWriteRes<[M3UnitC]> { let Latency = 2; }
-def M3WriteAX : SchedWriteVariant<[SchedVar<M3ShiftLeftFastPred, [M3WriteA1]>,
+def M3WriteAX : SchedWriteVariant<[SchedVar<M3ResetFastPred, [M3WriteZ0]>,
+ SchedVar<M3ShiftLeftFastPred, [M3WriteA1]>,
SchedVar<NoSchedPred, [M3WriteAA]>]>;
def M3WriteB1 : SchedWriteRes<[M3UnitB]> { let Latency = 1; }
// Arithmetic and logical integer instructions.
def : InstRW<[M3WriteA1], (instrs COPY)>;
-def : InstRW<[M3WriteAX], (instregex "(ADD|AND|BIC|EON|EOR|ORN|ORR|SUB)S?[WX]r[sx](64)?$")>;
+def : InstRW<[M3WriteAX], (instregex "^(ADD|SUB)S?Xrx64")>;
+def : InstRW<[M3WriteAX], (instregex "^(ADD|AND|BIC|EON|EOR|ORN|ORR|SUB)[WX]r[sx]$")>;
+def : InstRW<[M3WriteAX], (instregex "^(ADD|BIC|SUB)S[WX]r[sx]$")>;
+def : InstRW<[M3WriteAX], (instregex "^(ADD|AND|EOR|ORR|SUB)[WX]ri")>;
// Move instructions.
def : InstRW<[M3WriteZ0], (instrs ADR, ADRP)>;