Skip to content

Commit

Permalink
[ARC] Better classify add/sub immediate instructions in frame lowering.
Browse files Browse the repository at this point in the history
Summary:
Some operations have multiple ARC instructions that are applicable.
For instance, "add r0, r0, 123" can be encoded as a "LImm" instruction
with a 32-bit immediate (8-bytes), or as a signed 12-bit immediate instruction
for the case where the source and destination register are the same (4-bytes).
The ARC assembler will choose the shortest encoding, but we should track
the correct instruction in the compiler.
This patch fixes the instruction used in some cases from ARCFrameLowering.

Subscribers: hiraditya, jdoerfert, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D59326

llvm-svn: 356179
  • Loading branch information
petecoup committed Mar 14, 2019
1 parent a80d9ce commit 225c0bd
Showing 1 changed file with 40 additions and 10 deletions.
50 changes: 40 additions & 10 deletions llvm/lib/Target/ARC/ARCFrameLowering.cpp
Expand Up @@ -64,6 +64,8 @@ static void generateStackAdjustment(MachineBasicBlock &MBB,
assert((AbsAmount % 4 == 0) && "Stack adjustments must be 4-byte aligned.");
if (isUInt<6>(AbsAmount))
AdjOp = Positive ? ARC::ADD_rru6 : ARC::SUB_rru6;
else if (isInt<12>(AbsAmount))
AdjOp = Positive ? ARC::ADD_rrs12 : ARC::SUB_rrs12;
else
AdjOp = Positive ? ARC::ADD_rrlimm : ARC::SUB_rrlimm;

Expand Down Expand Up @@ -133,8 +135,12 @@ void ARCFrameLowering::emitPrologue(MachineFunction &MF,
// Add in the varargs area here first.
LLVM_DEBUG(dbgs() << "Varargs\n");
unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex());
BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6))
.addReg(ARC::SP)
unsigned Opc = ARC::SUB_rrlimm;
if (isUInt<6>(VarArgsBytes))
Opc = ARC::SUB_rru6;
else if (isInt<12>(VarArgsBytes))
Opc = ARC::SUB_rrs12;
BuildMI(MBB, MBBI, dl, TII->get(Opc), ARC::SP)
.addReg(ARC::SP)
.addImm(VarArgsBytes);
}
Expand Down Expand Up @@ -246,7 +252,10 @@ void ARCFrameLowering::emitEpilogue(MachineFunction &MF,
// Then, replace the frame pointer by (new) [sp,StackSize-4].
// Then, move the stack pointer the rest of the way (sp = sp + StackSize).
if (hasFP(MF)) {
BuildMI(MBB, MBBI, DebugLoc(), TII->get(ARC::SUB_rru6), ARC::SP)
unsigned Opc = ARC::SUB_rrlimm;
if (isUInt<6>(StackSize))
Opc = ARC::SUB_rru6;
BuildMI(MBB, MBBI, DebugLoc(), TII->get(Opc), ARC::SP)
.addReg(ARC::FP)
.addImm(StackSize);
AmountAboveFunclet += 4;
Expand All @@ -270,19 +279,28 @@ void ARCFrameLowering::emitEpilogue(MachineFunction &MF,
}

// Move the stack pointer up to the point of the funclet.
if (StackSize - AmountAboveFunclet) {
BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
.addReg(ARC::SP)
if (unsigned MoveAmount = StackSize - AmountAboveFunclet) {
unsigned Opc = ARC::ADD_rrlimm;
if (isUInt<6>(MoveAmount))
Opc = ARC::ADD_rru6;
else if (isInt<12>(MoveAmount))
Opc = ARC::ADD_rrs12;
BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc), ARC::SP)
.addReg(ARC::SP)
.addImm(StackSize - AmountAboveFunclet);
}

if (StackSlotsUsedByFunclet) {
// This part of the adjustment will always be < 64 bytes.
BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::BL))
.addExternalSymbol(load_funclet_name[Last - ARC::R15])
.addReg(ARC::BLINK, RegState::Implicit | RegState::Kill);
BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
.addReg(ARC::SP)
unsigned Opc = ARC::ADD_rrlimm;
if (isUInt<6>(4 * StackSlotsUsedByFunclet))
Opc = ARC::ADD_rru6;
else if (isInt<12>(4 * StackSlotsUsedByFunclet))
Opc = ARC::ADD_rrs12;
BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc), ARC::SP)
.addReg(ARC::SP)
.addImm(4 * (StackSlotsUsedByFunclet));
}
Expand All @@ -304,7 +322,12 @@ void ARCFrameLowering::emitEpilogue(MachineFunction &MF,
// Add in the varargs area here first.
LLVM_DEBUG(dbgs() << "Varargs\n");
unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex());
BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
unsigned Opc = ARC::ADD_rrlimm;
if (isUInt<6>(VarArgsBytes))
Opc = ARC::ADD_rru6;
else if (isInt<12>(VarArgsBytes))
Opc = ARC::ADD_rrs12;
BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc))
.addReg(ARC::SP)
.addReg(ARC::SP)
.addImm(VarArgsBytes);
Expand Down Expand Up @@ -430,7 +453,14 @@ static void emitRegUpdate(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI, DebugLoc dl,
unsigned Reg, int NumBytes, bool IsAdd,
const ARCInstrInfo *TII) {
unsigned Opc = IsAdd ? ARC::ADD_rru6 : ARC::SUB_rru6;
unsigned Opc;
if (isUInt<6>(NumBytes))
Opc = IsAdd ? ARC::ADD_rru6 : ARC::SUB_rru6;
else if (isInt<12>(NumBytes))
Opc = IsAdd ? ARC::ADD_rrs12 : ARC::SUB_rrs12;
else
Opc = IsAdd ? ARC::ADD_rrlimm : ARC::SUB_rrlimm;

BuildMI(MBB, MBBI, dl, TII->get(Opc), Reg)
.addReg(Reg, RegState::Kill)
.addImm(NumBytes);
Expand Down

0 comments on commit 225c0bd

Please sign in to comment.