aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Target/AVR/AVRISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/AVR/AVRISelLowering.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Target/AVR/AVRISelLowering.cpp129
1 files changed, 93 insertions, 36 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/AVR/AVRISelLowering.cpp b/contrib/llvm-project/llvm/lib/Target/AVR/AVRISelLowering.cpp
index bf9b32e1278e..3e7c2984655a 100644
--- a/contrib/llvm-project/llvm/lib/Target/AVR/AVRISelLowering.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/AVR/AVRISelLowering.cpp
@@ -334,6 +334,36 @@ SDValue AVRTargetLowering::LowerShifts(SDValue Op, SelectionDAG &DAG) const {
llvm_unreachable("Invalid shift opcode");
}
+ // Optimize int8 shifts.
+ if (VT.getSizeInBits() == 8) {
+ if (Op.getOpcode() == ISD::SHL && 4 <= ShiftAmount && ShiftAmount < 7) {
+ // Optimize LSL when 4 <= ShiftAmount <= 6.
+ Victim = DAG.getNode(AVRISD::SWAP, dl, VT, Victim);
+ Victim =
+ DAG.getNode(ISD::AND, dl, VT, Victim, DAG.getConstant(0xf0, dl, VT));
+ ShiftAmount -= 4;
+ } else if (Op.getOpcode() == ISD::SRL && 4 <= ShiftAmount &&
+ ShiftAmount < 7) {
+ // Optimize LSR when 4 <= ShiftAmount <= 6.
+ Victim = DAG.getNode(AVRISD::SWAP, dl, VT, Victim);
+ Victim =
+ DAG.getNode(ISD::AND, dl, VT, Victim, DAG.getConstant(0x0f, dl, VT));
+ ShiftAmount -= 4;
+ } else if (Op.getOpcode() == ISD::SHL && ShiftAmount == 7) {
+ // Optimize LSL when ShiftAmount == 7.
+ Victim = DAG.getNode(AVRISD::LSL7, dl, VT, Victim);
+ ShiftAmount = 0;
+ } else if (Op.getOpcode() == ISD::SRL && ShiftAmount == 7) {
+ // Optimize LSR when ShiftAmount == 7.
+ Victim = DAG.getNode(AVRISD::LSR7, dl, VT, Victim);
+ ShiftAmount = 0;
+ } else if (Op.getOpcode() == ISD::SRA && ShiftAmount == 7) {
+ // Optimize ASR when ShiftAmount == 7.
+ Victim = DAG.getNode(AVRISD::ASR7, dl, VT, Victim);
+ ShiftAmount = 0;
+ }
+ }
+
while (ShiftAmount--) {
Victim = DAG.getNode(Opc8, dl, VT, Victim);
}
@@ -437,6 +467,36 @@ static AVRCC::CondCodes intCCToAVRCC(ISD::CondCode CC) {
}
}
+/// Returns appropriate CP/CPI/CPC nodes code for the given 8/16-bit operands.
+SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS,
+ SelectionDAG &DAG, SDLoc DL) const {
+ assert((LHS.getSimpleValueType() == RHS.getSimpleValueType()) &&
+ "LHS and RHS have different types");
+ assert(((LHS.getSimpleValueType() == MVT::i16) ||
+ (LHS.getSimpleValueType() == MVT::i8)) && "invalid comparison type");
+
+ SDValue Cmp;
+
+ if (LHS.getSimpleValueType() == MVT::i16 && dyn_cast<ConstantSDNode>(RHS)) {
+ // Generate a CPI/CPC pair if RHS is a 16-bit constant.
+ SDValue LHSlo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS,
+ DAG.getIntPtrConstant(0, DL));
+ SDValue LHShi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS,
+ DAG.getIntPtrConstant(1, DL));
+ SDValue RHSlo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS,
+ DAG.getIntPtrConstant(0, DL));
+ SDValue RHShi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS,
+ DAG.getIntPtrConstant(1, DL));
+ Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHSlo, RHSlo);
+ Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHShi, RHShi, Cmp);
+ } else {
+ // Generate ordinary 16-bit comparison.
+ Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHS, RHS);
+ }
+
+ return Cmp;
+}
+
/// Returns appropriate AVR CMP/CMPC nodes and corresponding condition code for
/// the given operands.
SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
@@ -549,7 +609,7 @@ SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
DAG.getIntPtrConstant(1, DL));
Cmp = DAG.getNode(AVRISD::TST, DL, MVT::Glue, Top);
} else {
- Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHSlo, RHSlo);
+ Cmp = getAVRCmp(LHSlo, RHSlo, DAG, DL);
Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHShi, RHShi, Cmp);
}
} else if (VT == MVT::i64) {
@@ -587,7 +647,7 @@ SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
DAG.getIntPtrConstant(1, DL));
Cmp = DAG.getNode(AVRISD::TST, DL, MVT::Glue, Top);
} else {
- Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHS0, RHS0);
+ Cmp = getAVRCmp(LHS0, RHS0, DAG, DL);
Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHS1, RHS1, Cmp);
Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHS2, RHS2, Cmp);
Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHS3, RHS3, Cmp);
@@ -601,7 +661,7 @@ SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
: DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8,
LHS, DAG.getIntPtrConstant(1, DL)));
} else {
- Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHS, RHS);
+ Cmp = getAVRCmp(LHS, RHS, DAG, DL);
}
} else {
llvm_unreachable("Invalid comparison size");
@@ -676,7 +736,7 @@ SDValue AVRTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
SDValue FI = DAG.getFrameIndex(AFI->getVarArgsFrameIndex(), getPointerTy(DL));
return DAG.getStore(Op.getOperand(0), dl, FI, Op.getOperand(1),
- MachinePointerInfo(SV), 0);
+ MachinePointerInfo(SV));
}
SDValue AVRTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
@@ -1096,8 +1156,7 @@ SDValue AVRTargetLowering::LowerFormalArguments(
// from this parameter.
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DL));
InVals.push_back(DAG.getLoad(LocVT, dl, Chain, FIN,
- MachinePointerInfo::getFixedStack(MF, FI),
- 0));
+ MachinePointerInfo::getFixedStack(MF, FI)));
}
}
@@ -1230,8 +1289,7 @@ SDValue AVRTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
Chain =
DAG.getStore(Chain, DL, Arg, PtrOff,
- MachinePointerInfo::getStack(MF, VA.getLocMemOffset()),
- 0);
+ MachinePointerInfo::getStack(MF, VA.getLocMemOffset()));
}
}
@@ -1460,9 +1518,11 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI,
// Create loop block.
MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *CheckBB = F->CreateMachineBasicBlock(LLVM_BB);
MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB);
F->insert(I, LoopBB);
+ F->insert(I, CheckBB);
F->insert(I, RemBB);
// Update machine-CFG edges by transferring all successors of the current
@@ -1471,14 +1531,14 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI,
BB->end());
RemBB->transferSuccessorsAndUpdatePHIs(BB);
- // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB.
- BB->addSuccessor(LoopBB);
- BB->addSuccessor(RemBB);
- LoopBB->addSuccessor(RemBB);
- LoopBB->addSuccessor(LoopBB);
+ // Add edges BB => LoopBB => CheckBB => RemBB, CheckBB => LoopBB.
+ BB->addSuccessor(CheckBB);
+ LoopBB->addSuccessor(CheckBB);
+ CheckBB->addSuccessor(LoopBB);
+ CheckBB->addSuccessor(RemBB);
- Register ShiftAmtReg = RI.createVirtualRegister(&AVR::LD8RegClass);
- Register ShiftAmtReg2 = RI.createVirtualRegister(&AVR::LD8RegClass);
+ Register ShiftAmtReg = RI.createVirtualRegister(&AVR::GPR8RegClass);
+ Register ShiftAmtReg2 = RI.createVirtualRegister(&AVR::GPR8RegClass);
Register ShiftReg = RI.createVirtualRegister(RC);
Register ShiftReg2 = RI.createVirtualRegister(RC);
Register ShiftAmtSrcReg = MI.getOperand(2).getReg();
@@ -1486,44 +1546,41 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI,
Register DstReg = MI.getOperand(0).getReg();
// BB:
- // cpi N, 0
- // breq RemBB
- BuildMI(BB, dl, TII.get(AVR::CPIRdK)).addReg(ShiftAmtSrcReg).addImm(0);
- BuildMI(BB, dl, TII.get(AVR::BREQk)).addMBB(RemBB);
+ // rjmp CheckBB
+ BuildMI(BB, dl, TII.get(AVR::RJMPk)).addMBB(CheckBB);
// LoopBB:
- // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
- // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB]
// ShiftReg2 = shift ShiftReg
+ auto ShiftMI = BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2).addReg(ShiftReg);
+ if (HasRepeatedOperand)
+ ShiftMI.addReg(ShiftReg);
+
+ // CheckBB:
+ // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
+ // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB]
+ // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
// ShiftAmt2 = ShiftAmt - 1;
- BuildMI(LoopBB, dl, TII.get(AVR::PHI), ShiftReg)
+ // if (ShiftAmt2 >= 0) goto LoopBB;
+ BuildMI(CheckBB, dl, TII.get(AVR::PHI), ShiftReg)
.addReg(SrcReg)
.addMBB(BB)
.addReg(ShiftReg2)
.addMBB(LoopBB);
- BuildMI(LoopBB, dl, TII.get(AVR::PHI), ShiftAmtReg)
+ BuildMI(CheckBB, dl, TII.get(AVR::PHI), ShiftAmtReg)
.addReg(ShiftAmtSrcReg)
.addMBB(BB)
.addReg(ShiftAmtReg2)
.addMBB(LoopBB);
-
- auto ShiftMI = BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2).addReg(ShiftReg);
- if (HasRepeatedOperand)
- ShiftMI.addReg(ShiftReg);
-
- BuildMI(LoopBB, dl, TII.get(AVR::SUBIRdK), ShiftAmtReg2)
- .addReg(ShiftAmtReg)
- .addImm(1);
- BuildMI(LoopBB, dl, TII.get(AVR::BRNEk)).addMBB(LoopBB);
-
- // RemBB:
- // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
- BuildMI(*RemBB, RemBB->begin(), dl, TII.get(AVR::PHI), DstReg)
+ BuildMI(CheckBB, dl, TII.get(AVR::PHI), DstReg)
.addReg(SrcReg)
.addMBB(BB)
.addReg(ShiftReg2)
.addMBB(LoopBB);
+ BuildMI(CheckBB, dl, TII.get(AVR::DECRd), ShiftAmtReg2)
+ .addReg(ShiftAmtReg);
+ BuildMI(CheckBB, dl, TII.get(AVR::BRPLk)).addMBB(LoopBB);
+
MI.eraseFromParent(); // The pseudo instruction is gone now.
return RemBB;
}