[llvm-commits] [llvm] r43032 - in /llvm/trunk: lib/Target/PowerPC/PPCRegisterInfo.cpp test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll
Chris Lattner
sabre at nondot.org
Tue Oct 16 11:00:19 PDT 2007
Author: lattner
Date: Tue Oct 16 13:00:18 2007
New Revision: 43032
URL: http://llvm.org/viewvc/llvm-project?rev=43032&view=rev
Log:
Fix a bug handling frame references in ppc inline asm when the frame offset
doesn't fit into 16 bits.
Added:
llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll
Modified:
llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp
Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=43032&r1=43031&r2=43032&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Tue Oct 16 13:00:18 2007
@@ -722,18 +722,19 @@
MachineFrameInfo *MFI = MF.getFrameInfo();
// Find out which operand is the frame index.
- unsigned i = 0;
- while (!MI.getOperand(i).isFrameIndex()) {
- ++i;
- assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
+ unsigned FIOperandNo = 0;
+ while (!MI.getOperand(FIOperandNo).isFrameIndex()) {
+ ++FIOperandNo;
+ assert(FIOperandNo != MI.getNumOperands() &&
+ "Instr doesn't have FrameIndex operand!");
}
// Take into account whether it's an add or mem instruction
- unsigned OffIdx = (i == 2) ? 1 : 2;
+ unsigned OffsetOperandNo = (FIOperandNo == 2) ? 1 : 2;
if (MI.getOpcode() == TargetInstrInfo::INLINEASM)
- OffIdx = i-1;
+ OffsetOperandNo = FIOperandNo-1;
// Get the frame index.
- int FrameIndex = MI.getOperand(i).getFrameIndex();
+ int FrameIndex = MI.getOperand(FIOperandNo).getFrameIndex();
// Get the frame pointer save index. Users of this index are primarily
// DYNALLOC instructions.
@@ -750,7 +751,8 @@
}
// Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP).
- MI.getOperand(i).ChangeToRegister(hasFP(MF) ? PPC::R31 : PPC::R1, false);
+ MI.getOperand(FIOperandNo).ChangeToRegister(hasFP(MF) ? PPC::R31 : PPC::R1,
+ false);
// Figure out if the offset in the instruction is shifted right two bits. This
// is true for instructions like "STD", which the machine implicitly adds two
@@ -767,37 +769,44 @@
// Now add the frame object offset to the offset from r1.
int Offset = MFI->getObjectOffset(FrameIndex);
-
if (!isIXAddr)
- Offset += MI.getOperand(OffIdx).getImmedValue();
+ Offset += MI.getOperand(OffsetOperandNo).getImmedValue();
else
- Offset += MI.getOperand(OffIdx).getImmedValue() << 2;
+ Offset += MI.getOperand(OffsetOperandNo).getImmedValue() << 2;
// If we're not using a Frame Pointer that has been set to the value of the
// SP before having the stack size subtracted from it, then add the stack size
// to Offset to get the correct offset.
Offset += MFI->getStackSize();
- if (!isInt16(Offset)) {
+ if (isInt16(Offset)) {
+ if (isIXAddr) {
+ assert((Offset & 3) == 0 && "Invalid frame offset!");
+ Offset >>= 2; // The actual encoded value has the low two bits zero.
+ }
+ MI.getOperand(OffsetOperandNo).ChangeToImmediate(Offset);
+ } else {
// Insert a set of r0 with the full offset value before the ld, st, or add
BuildMI(MBB, II, TII.get(PPC::LIS), PPC::R0).addImm(Offset >> 16);
BuildMI(MBB, II, TII.get(PPC::ORI), PPC::R0).addReg(PPC::R0).addImm(Offset);
- // convert into indexed form of the instruction
+ // Convert into indexed form of the instruction
// sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0
// addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
- assert(ImmToIdxMap.count(OpC) &&
- "No indexed form of load or store available!");
- unsigned NewOpcode = ImmToIdxMap.find(OpC)->second;
- MI.setInstrDescriptor(TII.get(NewOpcode));
- MI.getOperand(1).ChangeToRegister(MI.getOperand(i).getReg(), false);
- MI.getOperand(2).ChangeToRegister(PPC::R0, false);
- } else {
- if (isIXAddr) {
- assert((Offset & 3) == 0 && "Invalid frame offset!");
- Offset >>= 2; // The actual encoded value has the low two bits zero.
+ unsigned OperandBase;
+ if (OpC != TargetInstrInfo::INLINEASM) {
+ assert(ImmToIdxMap.count(OpC) &&
+ "No indexed form of load or store available!");
+ unsigned NewOpcode = ImmToIdxMap.find(OpC)->second;
+ MI.setInstrDescriptor(TII.get(NewOpcode));
+ OperandBase = 1;
+ } else {
+ OperandBase = OffsetOperandNo;
}
- MI.getOperand(OffIdx).ChangeToImmediate(Offset);
+
+ unsigned StackReg = MI.getOperand(FIOperandNo).getReg();
+ MI.getOperand(OperandBase).ChangeToRegister(StackReg, false);
+ MI.getOperand(OperandBase+1).ChangeToRegister(PPC::R0, false);
}
}
Added: llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll?rev=43032&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll Tue Oct 16 13:00:18 2007
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | llc -march=ppc32
+; rdar://5538377
+
+ %struct.disk_unsigned = type { i32 }
+ %struct._StorePageMax = type { %struct.disk_unsigned, %struct.disk_unsigned, [65536 x i8] }
+
+define i32 @test() {
+entry:
+ %data = alloca i32 ; <i32*> [#uses=1]
+ %compressedPage = alloca %struct._StorePageMax ; <%struct._StorePageMax*> [#uses=0]
+ %tmp107 = call i32 asm "lwbrx $0, $2, $1", "=r,r,bO,*m"( i8* null, i32 0, i32* %data ) ; <i32> [#uses=0]
+ unreachable
+}
+
More information about the llvm-commits
mailing list