blob: 6fdf80024eee6fb13cc79013d2030e64283fc6f8 [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"
Alkis Evlogimenosf81af212004-02-14 01:18:34 +000027#include "Support/STLExtras.h"
Chris Lattner300d0ed2004-02-14 06:00:36 +000028using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000029
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
Chris Lattnerbb07ef92004-02-14 19:49:54 +000094void X86RegisterInfo::
95eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
96 MachineBasicBlock::iterator I) const {
Chris Lattner3c1c03d2002-12-28 20:32:28 +000097 if (hasFP(MF)) {
98 // If we have a frame pointer, turn the adjcallstackup instruction into a
99 // 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP,
100 // <amt>'
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000101 MachineInstr *Old = I;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000102 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 Lattnerbb07ef92004-02-14 19:49:54 +0000110 MachineInstr *New;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000111 if (Old->getOpcode() == X86::ADJCALLSTACKDOWN) {
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000112 New=BuildMI(X86::SUBri32, 1, X86::ESP, MOTy::UseAndDef).addZImm(Amount);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000113 } else {
114 assert(Old->getOpcode() == X86::ADJCALLSTACKUP);
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000115 New=BuildMI(X86::ADDri32, 1, X86::ESP, MOTy::UseAndDef).addZImm(Amount);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000116 }
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000117
118 // Replace the pseudo instruction with a new instruction...
119 MBB.insert(I, New);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000120 }
121 }
122
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000123 MBB.erase(I);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000124}
125
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000126void X86RegisterInfo::eliminateFrameIndex(MachineFunction &MF,
Alkis Evlogimenos024126e2004-02-12 08:11:04 +0000127 MachineBasicBlock::iterator II) const {
Chris Lattnerd264bec2003-01-13 00:50:33 +0000128 unsigned i = 0;
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000129 MachineInstr &MI = *II;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000130 while (!MI.getOperand(i).isFrameIndex()) {
131 ++i;
132 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
133 }
134
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000135 int FrameIndex = MI.getOperand(i).getFrameIndex();
Chris Lattnerd264bec2003-01-13 00:50:33 +0000136
137 // This must be part of a four operand memory reference. Replace the
138 // FrameIndex with base register with EBP. Add add an offset to the offset.
139 MI.SetMachineOperandReg(i, hasFP(MF) ? X86::EBP : X86::ESP);
140
141 // Now add the frame object offset to the offset from EBP.
142 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
Chris Lattnereafa4232003-01-15 22:57:35 +0000143 MI.getOperand(i+3).getImmedValue()+4;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000144
Chris Lattnerd5b7c472003-10-14 18:52:41 +0000145 if (!hasFP(MF))
146 Offset += MF.getFrameInfo()->getStackSize();
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000147
Chris Lattnerd264bec2003-01-13 00:50:33 +0000148 MI.SetMachineOperandConst(i+3, MachineOperand::MO_SignExtendedImmed, Offset);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000149}
150
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000151void
152X86RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) const{
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000153 if (hasFP(MF)) {
154 // Create a frame entry for the EBP register that must be saved.
155 int FrameIdx = MF.getFrameInfo()->CreateStackObject(4, 4);
156 assert(FrameIdx == MF.getFrameInfo()->getObjectIndexEnd()-1 &&
157 "Slot for EBP register must be last in order to be found!");
158 }
159}
160
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000161void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
Chris Lattner198ab642002-12-15 20:06:35 +0000162 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
163 MachineBasicBlock::iterator MBBI = MBB.begin();
Chris Lattnereafa4232003-01-15 22:57:35 +0000164 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000165 MachineInstr *MI;
Misha Brukman2adb3952002-12-04 23:57:03 +0000166
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000167 // Get the number of bytes to allocate from the FrameInfo
Chris Lattneraa09b752002-12-28 21:08:28 +0000168 unsigned NumBytes = MFI->getStackSize();
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000169 if (hasFP(MF)) {
170 // Get the offset of the stack slot for the EBP register... which is
171 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
Chris Lattnereafa4232003-01-15 22:57:35 +0000172 int EBPOffset = MFI->getObjectOffset(MFI->getObjectIndexEnd()-1)+4;
Chris Lattner3bbe7cc2002-12-17 03:15:26 +0000173
Chris Lattnerc2b81f62003-10-14 19:09:05 +0000174 if (NumBytes) { // adjust stack pointer: ESP -= numbytes
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000175 MI= BuildMI(X86::SUBri32, 1, X86::ESP, MOTy::UseAndDef).addZImm(NumBytes);
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000176 MBB.insert(MBBI, MI);
Chris Lattnerc2b81f62003-10-14 19:09:05 +0000177 }
178
179 // Save EBP into the appropriate stack slot...
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000180 MI = addRegOffset(BuildMI(X86::MOVrm32, 5), // mov [ESP-<offset>], EBP
Chris Lattnerc2b81f62003-10-14 19:09:05 +0000181 X86::ESP, EBPOffset+NumBytes).addReg(X86::EBP);
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000182 MBB.insert(MBBI, MI);
Chris Lattnerc2b81f62003-10-14 19:09:05 +0000183
184 // Update EBP with the new base value...
185 if (NumBytes == 0) // mov EBP, ESP
186 MI = BuildMI(X86::MOVrr32, 2, X86::EBP).addReg(X86::ESP);
187 else // lea EBP, [ESP+StackSize]
188 MI = addRegOffset(BuildMI(X86::LEAr32, 5, X86::EBP), X86::ESP, NumBytes);
189
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000190 MBB.insert(MBBI, MI);
Chris Lattnerc2b81f62003-10-14 19:09:05 +0000191
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000192 } else {
Chris Lattnere9dd84e2004-02-14 20:11:07 +0000193 if (MFI->hasCalls()) {
194 // When we have no frame pointer, we reserve argument space for call sites
195 // in the function immediately on entry to the current function. This
196 // eliminates the need for add/sub ESP brackets around call sites.
197 //
198 NumBytes += MFI->getMaxCallFrameSize();
199
200 // Round the size to a multiple of the alignment (don't forget the 4 byte
201 // offset though).
202 unsigned Align = MF.getTarget().getFrameInfo().getStackAlignment();
203 NumBytes = ((NumBytes+4)+Align-1)/Align*Align - 4;
204 }
Chris Lattnerf158da22003-01-16 02:20:12 +0000205
Chris Lattnereafa4232003-01-15 22:57:35 +0000206 // Update frame info to pretend that this is part of the stack...
207 MFI->setStackSize(NumBytes);
Misha Brukman2adb3952002-12-04 23:57:03 +0000208
Chris Lattnerc2b81f62003-10-14 19:09:05 +0000209 if (NumBytes) {
210 // adjust stack pointer: ESP -= numbytes
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000211 MI= BuildMI(X86::SUBri32, 1, X86::ESP, MOTy::UseAndDef).addZImm(NumBytes);
Chris Lattnerc2b81f62003-10-14 19:09:05 +0000212 MBB.insert(MBBI, MI);
213 }
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000214 }
Misha Brukman2adb3952002-12-04 23:57:03 +0000215}
216
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000217void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
218 MachineBasicBlock &MBB) const {
Chris Lattneraa09b752002-12-28 21:08:28 +0000219 const MachineFrameInfo *MFI = MF.getFrameInfo();
Alkis Evlogimenosf81af212004-02-14 01:18:34 +0000220 MachineBasicBlock::iterator MBBI = prior(MBB.end());
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000221 MachineInstr *MI;
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000222 assert(MBBI->getOpcode() == X86::RET &&
Chris Lattner198ab642002-12-15 20:06:35 +0000223 "Can only insert epilog into returning blocks");
Misha Brukman2adb3952002-12-04 23:57:03 +0000224
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000225 if (hasFP(MF)) {
226 // Get the offset of the stack slot for the EBP register... which is
227 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
Chris Lattnereafa4232003-01-15 22:57:35 +0000228 int EBPOffset = MFI->getObjectOffset(MFI->getObjectIndexEnd()-1)+4;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000229
230 // mov ESP, EBP
231 MI = BuildMI(X86::MOVrr32, 1,X86::ESP).addReg(X86::EBP);
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000232 MBB.insert(MBBI, MI);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000233
234 // mov EBP, [ESP-<offset>]
235 MI = addRegOffset(BuildMI(X86::MOVmr32, 5, X86::EBP), X86::ESP, EBPOffset);
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000236 MBB.insert(MBBI, MI);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000237 } else {
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000238 // Get the number of bytes allocated from the FrameInfo...
Chris Lattneraa09b752002-12-28 21:08:28 +0000239 unsigned NumBytes = MFI->getStackSize();
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000240
241 if (NumBytes) { // adjust stack pointer back: ESP += numbytes
Alkis Evlogimenos14be6402004-02-04 22:17:40 +0000242 MI =BuildMI(X86::ADDri32, 1, X86::ESP, MOTy::UseAndDef).addZImm(NumBytes);
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000243 MBB.insert(MBBI, MI);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000244 }
245 }
246}
247
Chris Lattner7ad3e062003-08-03 15:48:14 +0000248#include "X86GenRegisterInfo.inc"
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000249
250const TargetRegisterClass*
251X86RegisterInfo::getRegClassForType(const Type* Ty) const {
252 switch (Ty->getPrimitiveID()) {
Chris Lattnerd264bec2003-01-13 00:50:33 +0000253 case Type::LongTyID:
254 case Type::ULongTyID: assert(0 && "Long values can't fit in registers!");
255 default: assert(0 && "Invalid type to getClass!");
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000256 case Type::BoolTyID:
257 case Type::SByteTyID:
Chris Lattner6770aed2003-08-04 20:58:29 +0000258 case Type::UByteTyID: return &R8Instance;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000259 case Type::ShortTyID:
Chris Lattner6770aed2003-08-04 20:58:29 +0000260 case Type::UShortTyID: return &R16Instance;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000261 case Type::IntTyID:
262 case Type::UIntTyID:
Chris Lattner6770aed2003-08-04 20:58:29 +0000263 case Type::PointerTyID: return &R32Instance;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000264
265 case Type::FloatTyID:
Chris Lattner6770aed2003-08-04 20:58:29 +0000266 case Type::DoubleTyID: return &RFPInstance;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000267 }
Misha Brukman2adb3952002-12-04 23:57:03 +0000268}