diff --git a/lib/Target/AArch64/AArch64InstrInfo.cpp b/lib/Target/AArch64/AArch64InstrInfo.cpp index ecb550b7899..b4231d6ff05 100644 --- a/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -741,31 +741,73 @@ bool AArch64InstrInfo::isAsCheapAsAMove(const MachineInstr &MI) const { } 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: + return true; + // MOVI Vd, #0 + case AArch64::MOVID: + case AArch64::MOVIv8b_ns: + case AArch64::MOVIv2d_ns: + case AArch64::MOVIv16b_ns: + Imm = MI.getOperand(1).getImm(); + return (Imm == 0); + + // MOVI Vd, #0 + case AArch64::MOVIv2i32: + case AArch64::MOVIv4i16: + case AArch64::MOVIv4i32: + case AArch64::MOVIv8i16: + 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; - case AArch64::MOVID: - case AArch64::MOVIv2d_ns: - case AArch64::MOVIv8b_ns: - case AArch64::MOVIv16b_ns: - return (MI.getOperand(1).getImm() == 0); + // MOV Rd, Imm + case AArch64::ORRWri: + case AArch64::ORRXri: + if (!MI.getOperand(1).isReg()) + return false; - case AArch64::MOVIv2i32: - case AArch64::MOVIv4i32: - case AArch64::MOVIv4i16: - case AArch64::MOVIv8i16: - return (MI.getOperand(1).getImm() == 0 && - MI.getOperand(2).getImm() == 0); + 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); } } diff --git a/lib/Target/AArch64/AArch64SchedExynosM3.td b/lib/Target/AArch64/AArch64SchedExynosM3.td index 6fe545d80ca..2ee8be3b684 100644 --- a/lib/Target/AArch64/AArch64SchedExynosM3.td +++ b/lib/Target/AArch64/AArch64SchedExynosM3.td @@ -107,6 +107,7 @@ def M3UnitNSHF : ProcResGroup<[M3UnitNSHF0, // 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)}]>; @@ -132,7 +133,8 @@ def M3WriteAD : SchedWriteRes<[M3UnitALU, let NumMicroOps = 2; } def M3WriteC1 : SchedWriteRes<[M3UnitC]> { let Latency = 1; } def M3WriteC2 : SchedWriteRes<[M3UnitC]> { let Latency = 2; } -def M3WriteAX : SchedWriteVariant<[SchedVar, +def M3WriteAX : SchedWriteVariant<[SchedVar, + SchedVar, SchedVar]>; def M3WriteB1 : SchedWriteRes<[M3UnitB]> { let Latency = 1; } @@ -486,7 +488,10 @@ def : InstRW<[M3WriteAD], (instregex "^TBN?Z[WX]")>; // 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)>;