blob: 3031762288d9c6b75fbdf72989c45acd618079dd [file] [log] [blame]
Misha Brukmancf2b9ac2002-11-22 22:43:47 +00001//===- X86RegisterInfo.cpp - X86 Register Information -----------*- C++ -*-===//
John Criswellb576c942003-10-20 19:43:21 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Chris Lattner72614082002-10-25 22:55:53 +00009//
Chris Lattner3c1c03d2002-12-28 20:32:28 +000010// This file contains the X86 implementation of the MRegisterInfo class. This
11// file is responsible for the frame pointer elimination optimization on X86.
Chris Lattner72614082002-10-25 22:55:53 +000012//
13//===----------------------------------------------------------------------===//
14
Misha Brukmanb83b2862002-11-20 18:59:43 +000015#include "X86.h"
Chris Lattner72614082002-10-25 22:55:53 +000016#include "X86RegisterInfo.h"
Misha Brukmancf2b9ac2002-11-22 22:43:47 +000017#include "X86InstrBuilder.h"
Misha Brukmanb83b2862002-11-20 18:59:43 +000018#include "llvm/Constants.h"
19#include "llvm/Type.h"
Chris Lattnerc8c377d2003-07-29 05:14:16 +000020#include "llvm/CodeGen/ValueTypes.h"
Misha Brukmanb83b2862002-11-20 18:59:43 +000021#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner198ab642002-12-15 20:06:35 +000022#include "llvm/CodeGen/MachineFunction.h"
Chris Lattneraa09b752002-12-28 21:08:28 +000023#include "llvm/CodeGen/MachineFrameInfo.h"
Chris Lattnerf158da22003-01-16 02:20:12 +000024#include "llvm/Target/TargetMachine.h"
25#include "llvm/Target/TargetFrameInfo.h"
Chris Lattner3c1c03d2002-12-28 20:32:28 +000026#include "Support/CommandLine.h"
27
Brian Gaeked0fde302003-11-11 22:41:34 +000028namespace llvm {
29
Chris Lattner3c1c03d2002-12-28 20:32:28 +000030namespace {
31 cl::opt<bool>
Chris Lattnerddd5b412003-02-26 20:00:41 +000032 NoFPElim("disable-fp-elim",
Chris Lattner3c1c03d2002-12-28 20:32:28 +000033 cl::desc("Disable frame pointer elimination optimization"));
34}
Chris Lattner72614082002-10-25 22:55:53 +000035
Chris Lattner7ad3e062003-08-03 15:48:14 +000036X86RegisterInfo::X86RegisterInfo()
37 : X86GenRegisterInfo(X86::ADJCALLSTACKDOWN, X86::ADJCALLSTACKUP) {}
38
Chris Lattner8e581792002-12-25 05:07:09 +000039static unsigned getIdx(const TargetRegisterClass *RC) {
Chris Lattner3c1c03d2002-12-28 20:32:28 +000040 switch (RC->getSize()) {
Chris Lattner6eaa4692002-12-20 04:13:28 +000041 default: assert(0 && "Invalid data size!");
Chris Lattner8e581792002-12-25 05:07:09 +000042 case 1: return 0;
43 case 2: return 1;
44 case 4: return 2;
45 case 10: return 3;
Misha Brukman87e369d2002-12-13 12:00:06 +000046 }
47}
48
Alkis Evlogimenose668dab2003-11-04 22:57:09 +000049int X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
Alkis Evlogimenos024126e2004-02-12 08:11:04 +000050 MachineBasicBlock::iterator MI,
Alkis Evlogimenose668dab2003-11-04 22:57:09 +000051 unsigned SrcReg, int FrameIdx,
52 const TargetRegisterClass *RC) const {
Chris Lattner8e581792002-12-25 05:07:09 +000053 static const unsigned Opcode[] =
54 { X86::MOVrm8, X86::MOVrm16, X86::MOVrm32, X86::FSTPr80 };
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +000055 MachineInstr *I = addFrameReference(BuildMI(Opcode[getIdx(RC)], 5),
Chris Lattner3c1c03d2002-12-28 20:32:28 +000056 FrameIdx).addReg(SrcReg);
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +000057 MBB.insert(MI, I);
Alkis Evlogimenose668dab2003-11-04 22:57:09 +000058 return 1;
Misha Brukmanb83b2862002-11-20 18:59:43 +000059}
60
Alkis Evlogimenose668dab2003-11-04 22:57:09 +000061int X86RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
Alkis Evlogimenos024126e2004-02-12 08:11:04 +000062 MachineBasicBlock::iterator MI,
Alkis Evlogimenose668dab2003-11-04 22:57:09 +000063 unsigned DestReg, int FrameIdx,
64 const TargetRegisterClass *RC) const{
Chris Lattner8e581792002-12-25 05:07:09 +000065 static const unsigned Opcode[] =
66 { X86::MOVmr8, X86::MOVmr16, X86::MOVmr32, X86::FLDr80 };
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +000067 unsigned OC = Opcode[getIdx(RC)];
68 MBB.insert(MI, addFrameReference(BuildMI(OC, 4, DestReg), FrameIdx));
Alkis Evlogimenose668dab2003-11-04 22:57:09 +000069 return 1;
Misha Brukmanb83b2862002-11-20 18:59:43 +000070}
71
Alkis Evlogimenose668dab2003-11-04 22:57:09 +000072int X86RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
Alkis Evlogimenos024126e2004-02-12 08:11:04 +000073 MachineBasicBlock::iterator MI,
Alkis Evlogimenose668dab2003-11-04 22:57:09 +000074 unsigned DestReg, unsigned SrcReg,
75 const TargetRegisterClass *RC) const {
Chris Lattner8e581792002-12-25 05:07:09 +000076 static const unsigned Opcode[] =
77 { X86::MOVrr8, X86::MOVrr16, X86::MOVrr32, X86::FpMOV };
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +000078 MBB.insert(MI, BuildMI(Opcode[getIdx(RC)],1,DestReg).addReg(SrcReg));
Alkis Evlogimenose668dab2003-11-04 22:57:09 +000079 return 1;
Misha Brukman2b46e8e2002-12-13 09:54:12 +000080}
81
Chris Lattner3c1c03d2002-12-28 20:32:28 +000082//===----------------------------------------------------------------------===//
83// Stack Frame Processing methods
84//===----------------------------------------------------------------------===//
85
86// hasFP - Return true if the specified function should have a dedicated frame
87// pointer register. This is true if the function has variable sized allocas or
88// if frame pointer elimination is disabled.
89//
90static bool hasFP(MachineFunction &MF) {
91 return NoFPElim || MF.getFrameInfo()->hasVarSizedObjects();
Misha Brukman03c6faf2002-12-03 23:11:21 +000092}
Misha Brukman2adb3952002-12-04 23:57:03 +000093
Alkis Evlogimenose668dab2003-11-04 22:57:09 +000094int X86RegisterInfo::eliminateCallFramePseudoInstr(MachineFunction &MF,
95 MachineBasicBlock &MBB,
Alkis Evlogimenos024126e2004-02-12 08:11:04 +000096 MachineBasicBlock::iterator I) const {
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +000097 MachineInstr *New = 0, *Old = I;
Chris Lattner3c1c03d2002-12-28 20:32:28 +000098 if (hasFP(MF)) {
99 // If we have a frame pointer, turn the adjcallstackup instruction into a
100 // 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP,
101 // <amt>'
102 unsigned Amount = Old->getOperand(0).getImmedValue();
103 if (Amount != 0) {
Chris Lattnerf158da22003-01-16 02:20:12 +0000104 // We need to keep the stack aligned properly. To do this, we round the
105 // amount of space needed for the outgoing arguments up to the next
106 // alignment boundary.
107 unsigned Align = MF.getTarget().getFrameInfo().getStackAlignment();
108 Amount = (Amount+Align-1)/Align*Align;
109
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000110 if (Old->getOpcode() == X86::ADJCALLSTACKDOWN) {
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000111 New=BuildMI(X86::SUBri32, 1, X86::ESP, MOTy::UseAndDef).addZImm(Amount);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000112 } else {
113 assert(Old->getOpcode() == X86::ADJCALLSTACKUP);
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000114 New=BuildMI(X86::ADDri32, 1, X86::ESP, MOTy::UseAndDef).addZImm(Amount);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000115 }
116 }
117 }
118
Alkis Evlogimenose668dab2003-11-04 22:57:09 +0000119 if (New) {
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000120 // Replace the pseudo instruction with a new instruction...
121 MBB.insert(MBB.erase(I), New);
Alkis Evlogimenose668dab2003-11-04 22:57:09 +0000122 return 0;
123 } else {
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000124 MBB.erase(I);
Alkis Evlogimenose668dab2003-11-04 22:57:09 +0000125 return -1;
126 }
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000127}
128
Alkis Evlogimenose668dab2003-11-04 22:57:09 +0000129int X86RegisterInfo::eliminateFrameIndex(MachineFunction &MF,
Alkis Evlogimenos024126e2004-02-12 08:11:04 +0000130 MachineBasicBlock::iterator II) const {
Chris Lattnerd264bec2003-01-13 00:50:33 +0000131 unsigned i = 0;
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000132 MachineInstr &MI = *II;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000133 while (!MI.getOperand(i).isFrameIndex()) {
134 ++i;
135 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
136 }
137
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000138 int FrameIndex = MI.getOperand(i).getFrameIndex();
Chris Lattnerd264bec2003-01-13 00:50:33 +0000139
140 // This must be part of a four operand memory reference. Replace the
141 // FrameIndex with base register with EBP. Add add an offset to the offset.
142 MI.SetMachineOperandReg(i, hasFP(MF) ? X86::EBP : X86::ESP);
143
144 // Now add the frame object offset to the offset from EBP.
145 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
Chris Lattnereafa4232003-01-15 22:57:35 +0000146 MI.getOperand(i+3).getImmedValue()+4;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000147
Chris Lattnerd5b7c472003-10-14 18:52:41 +0000148 if (!hasFP(MF))
149 Offset += MF.getFrameInfo()->getStackSize();
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000150
Chris Lattnerd264bec2003-01-13 00:50:33 +0000151 MI.SetMachineOperandConst(i+3, MachineOperand::MO_SignExtendedImmed, Offset);
Alkis Evlogimenose668dab2003-11-04 22:57:09 +0000152 return 0;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000153}
154
Alkis Evlogimenose668dab2003-11-04 22:57:09 +0000155int X86RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF)
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000156 const {
157 if (hasFP(MF)) {
158 // Create a frame entry for the EBP register that must be saved.
159 int FrameIdx = MF.getFrameInfo()->CreateStackObject(4, 4);
160 assert(FrameIdx == MF.getFrameInfo()->getObjectIndexEnd()-1 &&
161 "Slot for EBP register must be last in order to be found!");
162 }
Alkis Evlogimenose668dab2003-11-04 22:57:09 +0000163 return 0;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000164}
165
Alkis Evlogimenose668dab2003-11-04 22:57:09 +0000166int X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
Chris Lattner198ab642002-12-15 20:06:35 +0000167 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
168 MachineBasicBlock::iterator MBBI = MBB.begin();
Chris Lattnereafa4232003-01-15 22:57:35 +0000169 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000170 MachineInstr *MI;
Misha Brukman2adb3952002-12-04 23:57:03 +0000171
Alkis Evlogimenose668dab2003-11-04 22:57:09 +0000172 unsigned oldSize = MBB.size();
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000173 // Get the number of bytes to allocate from the FrameInfo
Chris Lattneraa09b752002-12-28 21:08:28 +0000174 unsigned NumBytes = MFI->getStackSize();
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000175 if (hasFP(MF)) {
176 // Get the offset of the stack slot for the EBP register... which is
177 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
Chris Lattnereafa4232003-01-15 22:57:35 +0000178 int EBPOffset = MFI->getObjectOffset(MFI->getObjectIndexEnd()-1)+4;
Chris Lattner3bbe7cc2002-12-17 03:15:26 +0000179
Chris Lattnerc2b81f62003-10-14 19:09:05 +0000180 if (NumBytes) { // adjust stack pointer: ESP -= numbytes
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000181 MI= BuildMI(X86::SUBri32, 1, X86::ESP, MOTy::UseAndDef).addZImm(NumBytes);
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000182 MBB.insert(MBBI, MI);
Chris Lattnerc2b81f62003-10-14 19:09:05 +0000183 }
184
185 // Save EBP into the appropriate stack slot...
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000186 MI = addRegOffset(BuildMI(X86::MOVrm32, 5), // mov [ESP-<offset>], EBP
Chris Lattnerc2b81f62003-10-14 19:09:05 +0000187 X86::ESP, EBPOffset+NumBytes).addReg(X86::EBP);
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000188 MBB.insert(MBBI, MI);
Chris Lattnerc2b81f62003-10-14 19:09:05 +0000189
190 // Update EBP with the new base value...
191 if (NumBytes == 0) // mov EBP, ESP
192 MI = BuildMI(X86::MOVrr32, 2, X86::EBP).addReg(X86::ESP);
193 else // lea EBP, [ESP+StackSize]
194 MI = addRegOffset(BuildMI(X86::LEAr32, 5, X86::EBP), X86::ESP, NumBytes);
195
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000196 MBB.insert(MBBI, MI);
Chris Lattnerc2b81f62003-10-14 19:09:05 +0000197
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000198 } else {
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000199 // When we have no frame pointer, we reserve argument space for call sites
200 // in the function immediately on entry to the current function. This
201 // eliminates the need for add/sub ESP brackets around call sites.
202 //
Chris Lattneraa09b752002-12-28 21:08:28 +0000203 NumBytes += MFI->getMaxCallFrameSize();
Chris Lattnereafa4232003-01-15 22:57:35 +0000204
Chris Lattnerf158da22003-01-16 02:20:12 +0000205 // Round the size to a multiple of the alignment (don't forget the 4 byte
206 // offset though).
207 unsigned Align = MF.getTarget().getFrameInfo().getStackAlignment();
208 NumBytes = ((NumBytes+4)+Align-1)/Align*Align - 4;
209
Chris Lattnereafa4232003-01-15 22:57:35 +0000210 // Update frame info to pretend that this is part of the stack...
211 MFI->setStackSize(NumBytes);
Misha Brukman2adb3952002-12-04 23:57:03 +0000212
Chris Lattnerc2b81f62003-10-14 19:09:05 +0000213 if (NumBytes) {
214 // adjust stack pointer: ESP -= numbytes
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000215 MI= BuildMI(X86::SUBri32, 1, X86::ESP, MOTy::UseAndDef).addZImm(NumBytes);
Chris Lattnerc2b81f62003-10-14 19:09:05 +0000216 MBB.insert(MBBI, MI);
217 }
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000218 }
Alkis Evlogimenose668dab2003-11-04 22:57:09 +0000219 return MBB.size() - oldSize;
Misha Brukman2adb3952002-12-04 23:57:03 +0000220}
221
Alkis Evlogimenose668dab2003-11-04 22:57:09 +0000222int X86RegisterInfo::emitEpilogue(MachineFunction &MF,
223 MachineBasicBlock &MBB) const {
224 unsigned oldSize = MBB.size();
Chris Lattneraa09b752002-12-28 21:08:28 +0000225 const MachineFrameInfo *MFI = MF.getFrameInfo();
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000226 MachineBasicBlock::iterator MBBI = MBB.end(); --MBBI;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000227 MachineInstr *MI;
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000228 assert(MBBI->getOpcode() == X86::RET &&
Chris Lattner198ab642002-12-15 20:06:35 +0000229 "Can only insert epilog into returning blocks");
Misha Brukman2adb3952002-12-04 23:57:03 +0000230
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000231 if (hasFP(MF)) {
232 // Get the offset of the stack slot for the EBP register... which is
233 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
Chris Lattnereafa4232003-01-15 22:57:35 +0000234 int EBPOffset = MFI->getObjectOffset(MFI->getObjectIndexEnd()-1)+4;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000235
236 // mov ESP, EBP
237 MI = BuildMI(X86::MOVrr32, 1,X86::ESP).addReg(X86::EBP);
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000238 MBB.insert(MBBI, MI);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000239
240 // mov EBP, [ESP-<offset>]
241 MI = addRegOffset(BuildMI(X86::MOVmr32, 5, X86::EBP), X86::ESP, EBPOffset);
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000242 MBB.insert(MBBI, MI);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000243 } else {
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000244 // Get the number of bytes allocated from the FrameInfo...
Chris Lattneraa09b752002-12-28 21:08:28 +0000245 unsigned NumBytes = MFI->getStackSize();
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000246
247 if (NumBytes) { // adjust stack pointer back: ESP += numbytes
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000248 MI =BuildMI(X86::ADDri32, 1, X86::ESP, MOTy::UseAndDef).addZImm(NumBytes);
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000249 MBB.insert(MBBI, MI);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000250 }
251 }
Alkis Evlogimenose668dab2003-11-04 22:57:09 +0000252 return MBB.size() - oldSize;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000253}
254
Brian Gaeked0fde302003-11-11 22:41:34 +0000255} // End llvm namespace
256
Chris Lattner7ad3e062003-08-03 15:48:14 +0000257#include "X86GenRegisterInfo.inc"
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000258
Brian Gaeked0fde302003-11-11 22:41:34 +0000259namespace llvm {
260
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000261const TargetRegisterClass*
262X86RegisterInfo::getRegClassForType(const Type* Ty) const {
263 switch (Ty->getPrimitiveID()) {
Chris Lattnerd264bec2003-01-13 00:50:33 +0000264 case Type::LongTyID:
265 case Type::ULongTyID: assert(0 && "Long values can't fit in registers!");
266 default: assert(0 && "Invalid type to getClass!");
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000267 case Type::BoolTyID:
268 case Type::SByteTyID:
Chris Lattner6770aed2003-08-04 20:58:29 +0000269 case Type::UByteTyID: return &R8Instance;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000270 case Type::ShortTyID:
Chris Lattner6770aed2003-08-04 20:58:29 +0000271 case Type::UShortTyID: return &R16Instance;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000272 case Type::IntTyID:
273 case Type::UIntTyID:
Chris Lattner6770aed2003-08-04 20:58:29 +0000274 case Type::PointerTyID: return &R32Instance;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000275
276 case Type::FloatTyID:
Chris Lattner6770aed2003-08-04 20:58:29 +0000277 case Type::DoubleTyID: return &RFPInstance;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000278 }
Misha Brukman2adb3952002-12-04 23:57:03 +0000279}
Brian Gaeked0fde302003-11-11 22:41:34 +0000280
281} // End llvm namespace