diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp index 40d757b645a..54cf29229d7 100644 --- a/lib/Target/X86/InstSelectSimple.cpp +++ b/lib/Target/X86/InstSelectSimple.cpp @@ -159,23 +159,24 @@ namespace { } else if (Argument *A = dyn_cast(V)) { // Find the position of the argument in the argument list. const Function *f = F->getFunction (); - int counter = 0, argPosition = -1; + // The function's arguments look like this: + // [EBP] -- copy of old EBP + // [EBP + 4] -- return address + // [EBP + 8] -- first argument (leftmost lexically) + // So we want to start with counter = 2. + int counter = 2, argPosition = -1; for (Function::const_aiterator ai = f->abegin (), ae = f->aend (); ai != ae; ++ai) { - ++counter; if (&(*ai) == A) { argPosition = counter; + break; // Only need to find it once. ;-) } + ++counter; } assert (argPosition != -1 && "Argument not found in current function's argument list"); // Load it out of the stack frame at EBP + 4*argPosition. - // (First, load Reg with argPosition, then load Reg with DWORD - // PTR [EBP + 4*Reg].) - BuildMI (BB, X86::MOVir32, 1, Reg).addZImm (argPosition); - BuildMI (BB, X86::MOVmr32, 4, - Reg).addReg (X86::EBP).addZImm (4).addReg (Reg).addSImm (0); - // std::cerr << "ERROR: Arguments not implemented in SimpleInstSel\n"; + addRegOffset (BuildMI (BB, X86::MOVmr32, 4, Reg), X86::EBP, 4*argPosition); } return Reg; diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index 40d757b645a..54cf29229d7 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.cpp @@ -159,23 +159,24 @@ namespace { } else if (Argument *A = dyn_cast(V)) { // Find the position of the argument in the argument list. const Function *f = F->getFunction (); - int counter = 0, argPosition = -1; + // The function's arguments look like this: + // [EBP] -- copy of old EBP + // [EBP + 4] -- return address + // [EBP + 8] -- first argument (leftmost lexically) + // So we want to start with counter = 2. + int counter = 2, argPosition = -1; for (Function::const_aiterator ai = f->abegin (), ae = f->aend (); ai != ae; ++ai) { - ++counter; if (&(*ai) == A) { argPosition = counter; + break; // Only need to find it once. ;-) } + ++counter; } assert (argPosition != -1 && "Argument not found in current function's argument list"); // Load it out of the stack frame at EBP + 4*argPosition. - // (First, load Reg with argPosition, then load Reg with DWORD - // PTR [EBP + 4*Reg].) - BuildMI (BB, X86::MOVir32, 1, Reg).addZImm (argPosition); - BuildMI (BB, X86::MOVmr32, 4, - Reg).addReg (X86::EBP).addZImm (4).addReg (Reg).addSImm (0); - // std::cerr << "ERROR: Arguments not implemented in SimpleInstSel\n"; + addRegOffset (BuildMI (BB, X86::MOVmr32, 4, Reg), X86::EBP, 4*argPosition); } return Reg; diff --git a/lib/Target/X86/X86InstrBuilder.h b/lib/Target/X86/X86InstrBuilder.h index 2558a96c04e..af3b5221673 100644 --- a/lib/Target/X86/X86InstrBuilder.h +++ b/lib/Target/X86/X86InstrBuilder.h @@ -9,6 +9,9 @@ // up behind an easier to use interface makes sense. Descriptions of the // functions are included below. // +// For reference, the order of operands for memory references is: +// (Operand), Base, Scale, Index, Displacement. +// //===----------------------------------------------------------------------===// #ifndef X86INSTRBUILDER_H @@ -17,18 +20,19 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" /// addDirectMem - This function is used to add a direct memory reference to the -/// current instruction. Because memory references are always represented with -/// four values, this adds: Reg, [1, NoReg, 0] to the instruction -/// +/// current instruction -- that is, a dereference of an address in a register, with +/// no scale, index or displacement. An example is: DWORD PTR [EAX]. inline const MachineInstrBuilder &addDirectMem(const MachineInstrBuilder &MIB, unsigned Reg) { + // Because memory references are always represented with four + // values, this adds: Reg, [1, NoReg, 0] to the instruction. return MIB.addReg(Reg).addZImm(1).addMReg(0).addSImm(0); } -/// addRegOffset - -/// -/// +/// addRegOffset - This function is used to add a memory reference of +/// the form [Reg + Offset], i.e., one with no scale or index, but +/// with a displacement. An example is: DWORD PTR [EAX + 4]. inline const MachineInstrBuilder &addRegOffset(const MachineInstrBuilder &MIB, unsigned Reg, unsigned Offset) { return MIB.addReg(Reg).addZImm(1).addMReg(0).addSImm(Offset); diff --git a/test/ExecutionEngine/test-loadstore.ll b/test/ExecutionEngine/test-loadstore.ll index 936aa5f7443..f301e66be5a 100644 --- a/test/ExecutionEngine/test-loadstore.ll +++ b/test/ExecutionEngine/test-loadstore.ll @@ -11,10 +11,10 @@ void %test(sbyte* %P, short* %P, int* %P) { ret void } -void %main() { +int %main() { %A = alloca sbyte %B = alloca short %C = alloca int call void %test(sbyte* %A, short* %B, int* %C) - ret void + ret int 0 }