summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp
diff options
context:
space:
mode:
authorVenkatraman Govindaraju <venkatra@cs.wisc.edu>2013-11-24 20:23:25 +0000
committerVenkatraman Govindaraju <venkatra@cs.wisc.edu>2013-11-24 20:23:25 +0000
commit1116868a0da41326eca5ecf8c9c7eb655effcac2 (patch)
tree5980d14c68e627659d6a33098f01cb0736db2095 /llvm/lib/Target/Sparc/SparcRegisterInfo.cpp
parent9c338504e587cbdba54c3ab279d553d7eec81265 (diff)
downloadbcm5719-llvm-1116868a0da41326eca5ecf8c9c7eb655effcac2.tar.gz
bcm5719-llvm-1116868a0da41326eca5ecf8c9c7eb655effcac2.zip
[Sparc] Emit large negative adjustments to SP/FP with sethi+xor instead of sethi+or. This generates correct code for both sparc32 and sparc64.
llvm-svn: 195576
Diffstat (limited to 'llvm/lib/Target/Sparc/SparcRegisterInfo.cpp')
-rw-r--r--llvm/lib/Target/Sparc/SparcRegisterInfo.cpp41
1 files changed, 34 insertions, 7 deletions
diff --git a/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp b/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp
index 9442d03c129..c98613aa120 100644
--- a/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp
+++ b/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp
@@ -105,19 +105,46 @@ static void replaceFI(MachineFunction &MF,
// encode it.
MI.getOperand(FIOperandNum).ChangeToRegister(FramePtr, false);
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
- } else {
- // Otherwise, emit a G1 = SETHI %hi(offset). FIXME: it would be better to
- // scavenge a register here instead of reserving G1 all of the time.
- const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
- unsigned OffHi = (unsigned)Offset >> 10U;
- BuildMI(*MI.getParent(), II, dl, TII.get(SP::SETHIi), SP::G1).addImm(OffHi);
+ return;
+ }
+
+ const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
+
+ // FIXME: it would be better to scavenge a register here instead of
+ // reserving G1 all of the time.
+ if (Offset >= 0) {
+ // Emit nonnegaive immediates with sethi + or.
+ // sethi %hi(Offset), %g1
+ // add %g1, %fp, %g1
+ // Insert G1+%lo(offset) into the user.
+ BuildMI(*MI.getParent(), II, dl, TII.get(SP::SETHIi), SP::G1)
+ .addImm(HI22(Offset));
+
+
// Emit G1 = G1 + I6
BuildMI(*MI.getParent(), II, dl, TII.get(SP::ADDrr), SP::G1).addReg(SP::G1)
.addReg(FramePtr);
// Insert: G1+%lo(offset) into the user.
MI.getOperand(FIOperandNum).ChangeToRegister(SP::G1, false);
- MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset & ((1 << 10)-1));
+ MI.getOperand(FIOperandNum + 1).ChangeToImmediate(LO10(Offset));
+ return;
}
+
+ // Emit Negative numbers with sethi + xor
+ // sethi %hix(Offset), %g1
+ // xor %g1, %lox(offset), %g1
+ // add %g1, %fp, %g1
+ // Insert: G1 + 0 into the user.
+ BuildMI(*MI.getParent(), II, dl, TII.get(SP::SETHIi), SP::G1)
+ .addImm(HIX22(Offset));
+ BuildMI(*MI.getParent(), II, dl, TII.get(SP::XORri), SP::G1)
+ .addReg(SP::G1).addImm(LOX10(Offset));
+
+ BuildMI(*MI.getParent(), II, dl, TII.get(SP::ADDrr), SP::G1).addReg(SP::G1)
+ .addReg(FramePtr);
+ // Insert: G1+%lo(offset) into the user.
+ MI.getOperand(FIOperandNum).ChangeToRegister(SP::G1, false);
+ MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
}
OpenPOWER on IntegriCloud