LLVM API Documentation
00001 //===- X86RegisterInfo.cpp - X86 Register Information -----------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the X86 implementation of the MRegisterInfo class. This 00011 // file is responsible for the frame pointer elimination optimization on X86. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "X86.h" 00016 #include "X86RegisterInfo.h" 00017 #include "X86Subtarget.h" 00018 #include "X86InstrBuilder.h" 00019 #include "X86MachineFunctionInfo.h" 00020 #include "X86TargetMachine.h" 00021 #include "llvm/Constants.h" 00022 #include "llvm/Type.h" 00023 #include "llvm/Function.h" 00024 #include "llvm/CodeGen/ValueTypes.h" 00025 #include "llvm/CodeGen/MachineInstrBuilder.h" 00026 #include "llvm/CodeGen/MachineFunction.h" 00027 #include "llvm/CodeGen/MachineFrameInfo.h" 00028 #include "llvm/CodeGen/MachineLocation.h" 00029 #include "llvm/Target/TargetFrameInfo.h" 00030 #include "llvm/Target/TargetMachine.h" 00031 #include "llvm/Target/TargetOptions.h" 00032 #include "llvm/Support/CommandLine.h" 00033 #include "llvm/ADT/STLExtras.h" 00034 #include <iostream> 00035 00036 using namespace llvm; 00037 00038 namespace { 00039 cl::opt<bool> 00040 NoFusing("disable-spill-fusing", 00041 cl::desc("Disable fusing of spill code into instructions")); 00042 cl::opt<bool> 00043 PrintFailedFusing("print-failed-fuse-candidates", 00044 cl::desc("Print instructions that the allocator wants to" 00045 " fuse, but the X86 backend currently can't"), 00046 cl::Hidden); 00047 } 00048 00049 X86RegisterInfo::X86RegisterInfo() 00050 : X86GenRegisterInfo(X86::ADJCALLSTACKDOWN, X86::ADJCALLSTACKUP) {} 00051 00052 void X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 00053 MachineBasicBlock::iterator MI, 00054 unsigned SrcReg, int FrameIdx, 00055 const TargetRegisterClass *RC) const { 00056 unsigned Opc; 00057 if (RC == &X86::GR32RegClass) { 00058 Opc = X86::MOV32mr; 00059 } else if (RC == &X86::GR16RegClass) { 00060 Opc = X86::MOV16mr; 00061 } else if (RC == &X86::GR8RegClass) { 00062 Opc = X86::MOV8mr; 00063 } else if (RC == &X86::GR32_RegClass) { 00064 Opc = X86::MOV32_mr; 00065 } else if (RC == &X86::GR16_RegClass) { 00066 Opc = X86::MOV16_mr; 00067 } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) { 00068 Opc = X86::FpST64m; 00069 } else if (RC == &X86::FR32RegClass) { 00070 Opc = X86::MOVSSmr; 00071 } else if (RC == &X86::FR64RegClass) { 00072 Opc = X86::MOVSDmr; 00073 } else if (RC == &X86::VR128RegClass) { 00074 Opc = X86::MOVAPSmr; 00075 } else { 00076 assert(0 && "Unknown regclass"); 00077 abort(); 00078 } 00079 addFrameReference(BuildMI(MBB, MI, Opc, 5), FrameIdx).addReg(SrcReg); 00080 } 00081 00082 void X86RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 00083 MachineBasicBlock::iterator MI, 00084 unsigned DestReg, int FrameIdx, 00085 const TargetRegisterClass *RC) const{ 00086 unsigned Opc; 00087 if (RC == &X86::GR32RegClass) { 00088 Opc = X86::MOV32rm; 00089 } else if (RC == &X86::GR16RegClass) { 00090 Opc = X86::MOV16rm; 00091 } else if (RC == &X86::GR8RegClass) { 00092 Opc = X86::MOV8rm; 00093 } else if (RC == &X86::GR32_RegClass) { 00094 Opc = X86::MOV32_rm; 00095 } else if (RC == &X86::GR16_RegClass) { 00096 Opc = X86::MOV16_rm; 00097 } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) { 00098 Opc = X86::FpLD64m; 00099 } else if (RC == &X86::FR32RegClass) { 00100 Opc = X86::MOVSSrm; 00101 } else if (RC == &X86::FR64RegClass) { 00102 Opc = X86::MOVSDrm; 00103 } else if (RC == &X86::VR128RegClass) { 00104 Opc = X86::MOVAPSrm; 00105 } else { 00106 assert(0 && "Unknown regclass"); 00107 abort(); 00108 } 00109 addFrameReference(BuildMI(MBB, MI, Opc, 4, DestReg), FrameIdx); 00110 } 00111 00112 void X86RegisterInfo::copyRegToReg(MachineBasicBlock &MBB, 00113 MachineBasicBlock::iterator MI, 00114 unsigned DestReg, unsigned SrcReg, 00115 const TargetRegisterClass *RC) const { 00116 unsigned Opc; 00117 if (RC == &X86::GR32RegClass) { 00118 Opc = X86::MOV32rr; 00119 } else if (RC == &X86::GR16RegClass) { 00120 Opc = X86::MOV16rr; 00121 } else if (RC == &X86::GR8RegClass) { 00122 Opc = X86::MOV8rr; 00123 } else if (RC == &X86::GR32_RegClass) { 00124 Opc = X86::MOV32_rr; 00125 } else if (RC == &X86::GR16_RegClass) { 00126 Opc = X86::MOV16_rr; 00127 } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) { 00128 Opc = X86::FpMOV; 00129 } else if (RC == &X86::FR32RegClass) { 00130 Opc = X86::FsMOVAPSrr; 00131 } else if (RC == &X86::FR64RegClass) { 00132 Opc = X86::FsMOVAPDrr; 00133 } else if (RC == &X86::VR128RegClass) { 00134 Opc = X86::MOVAPSrr; 00135 } else { 00136 assert(0 && "Unknown regclass"); 00137 abort(); 00138 } 00139 BuildMI(MBB, MI, Opc, 1, DestReg).addReg(SrcReg); 00140 } 00141 00142 00143 static MachineInstr *MakeMInst(unsigned Opcode, unsigned FrameIndex, 00144 MachineInstr *MI) { 00145 return addFrameReference(BuildMI(Opcode, 4), FrameIndex); 00146 } 00147 00148 static MachineInstr *MakeMRInst(unsigned Opcode, unsigned FrameIndex, 00149 MachineInstr *MI) { 00150 return addFrameReference(BuildMI(Opcode, 5), FrameIndex) 00151 .addReg(MI->getOperand(1).getReg()); 00152 } 00153 00154 static MachineInstr *MakeMRIInst(unsigned Opcode, unsigned FrameIndex, 00155 MachineInstr *MI) { 00156 return addFrameReference(BuildMI(Opcode, 6), FrameIndex) 00157 .addReg(MI->getOperand(1).getReg()) 00158 .addImm(MI->getOperand(2).getImmedValue()); 00159 } 00160 00161 static MachineInstr *MakeMIInst(unsigned Opcode, unsigned FrameIndex, 00162 MachineInstr *MI) { 00163 if (MI->getOperand(1).isImmediate()) 00164 return addFrameReference(BuildMI(Opcode, 5), FrameIndex) 00165 .addImm(MI->getOperand(1).getImmedValue()); 00166 else if (MI->getOperand(1).isGlobalAddress()) 00167 return addFrameReference(BuildMI(Opcode, 5), FrameIndex) 00168 .addGlobalAddress(MI->getOperand(1).getGlobal(), 00169 MI->getOperand(1).getOffset()); 00170 else if (MI->getOperand(1).isJumpTableIndex()) 00171 return addFrameReference(BuildMI(Opcode, 5), FrameIndex) 00172 .addJumpTableIndex(MI->getOperand(1).getJumpTableIndex()); 00173 assert(0 && "Unknown operand for MakeMI!"); 00174 return 0; 00175 } 00176 00177 static MachineInstr *MakeM0Inst(unsigned Opcode, unsigned FrameIndex, 00178 MachineInstr *MI) { 00179 return addFrameReference(BuildMI(Opcode, 5), FrameIndex).addImm(0); 00180 } 00181 00182 static MachineInstr *MakeRMInst(unsigned Opcode, unsigned FrameIndex, 00183 MachineInstr *MI) { 00184 const MachineOperand& op = MI->getOperand(0); 00185 return addFrameReference(BuildMI(Opcode, 5, op.getReg(), op.getUseType()), 00186 FrameIndex); 00187 } 00188 00189 static MachineInstr *MakeRMIInst(unsigned Opcode, unsigned FrameIndex, 00190 MachineInstr *MI) { 00191 const MachineOperand& op = MI->getOperand(0); 00192 return addFrameReference(BuildMI(Opcode, 6, op.getReg(), op.getUseType()), 00193 FrameIndex).addImm(MI->getOperand(2).getImmedValue()); 00194 } 00195 00196 00197 //===----------------------------------------------------------------------===// 00198 // Efficient Lookup Table Support 00199 //===----------------------------------------------------------------------===// 00200 00201 namespace { 00202 /// TableEntry - Maps the 'from' opcode to a fused form of the 'to' opcode. 00203 /// 00204 struct TableEntry { 00205 unsigned from; // Original opcode. 00206 unsigned to; // New opcode. 00207 unsigned make; // Form of make required to produce the 00208 // new instruction. 00209 00210 // less operators used by STL search. 00211 bool operator<(const TableEntry &TE) const { return from < TE.from; } 00212 friend bool operator<(const TableEntry &TE, unsigned V) { 00213 return TE.from < V; 00214 } 00215 friend bool operator<(unsigned V, const TableEntry &TE) { 00216 return V < TE.from; 00217 } 00218 }; 00219 } 00220 00221 /// TableIsSorted - Return true if the table is in 'from' opcode order. 00222 /// 00223 static bool TableIsSorted(const TableEntry *Table, unsigned NumEntries) { 00224 for (unsigned i = 1; i != NumEntries; ++i) 00225 if (!(Table[i-1] < Table[i])) { 00226 std::cerr << "Entries out of order " << Table[i-1].from 00227 << " " << Table[i].from << "\n"; 00228 return false; 00229 } 00230 return true; 00231 } 00232 00233 /// TableLookup - Return the table entry matching the specified opcode. 00234 /// Otherwise return NULL. 00235 static const TableEntry *TableLookup(const TableEntry *Table, unsigned N, 00236 unsigned Opcode) { 00237 const TableEntry *I = std::lower_bound(Table, Table+N, Opcode); 00238 if (I != Table+N && I->from == Opcode) 00239 return I; 00240 return NULL; 00241 } 00242 00243 #define ARRAY_SIZE(TABLE) \ 00244 (sizeof(TABLE)/sizeof(TABLE[0])) 00245 00246 #ifdef NDEBUG 00247 #define ASSERT_SORTED(TABLE) 00248 #else 00249 #define ASSERT_SORTED(TABLE) \ 00250 { static bool TABLE##Checked = false; \ 00251 if (!TABLE##Checked) { \ 00252 assert(TableIsSorted(TABLE, ARRAY_SIZE(TABLE)) && \ 00253 "All lookup tables must be sorted for efficient access!"); \ 00254 TABLE##Checked = true; \ 00255 } \ 00256 } 00257 #endif 00258 00259 00260 MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr* MI, 00261 unsigned i, 00262 int FrameIndex) const { 00263 // Check switch flag 00264 if (NoFusing) return NULL; 00265 00266 // Selection of instruction makes 00267 enum { 00268 makeM0Inst, 00269 makeMIInst, 00270 makeMInst, 00271 makeMRIInst, 00272 makeMRInst, 00273 makeRMIInst, 00274 makeRMInst 00275 }; 00276 00277 // Table (and size) to search 00278 const TableEntry *OpcodeTablePtr = NULL; 00279 unsigned OpcodeTableSize = 0; 00280 00281 if (i == 0) { // If operand 0 00282 static const TableEntry OpcodeTable[] = { 00283 { X86::ADC32ri, X86::ADC32mi, makeMIInst }, 00284 { X86::ADC32ri8, X86::ADC32mi8, makeMIInst }, 00285 { X86::ADC32rr, X86::ADC32mr, makeMRInst }, 00286 { X86::ADD16ri, X86::ADD16mi, makeMIInst }, 00287 { X86::ADD16ri8, X86::ADD16mi8, makeMIInst }, 00288 { X86::ADD16rr, X86::ADD16mr, makeMRInst }, 00289 { X86::ADD32ri, X86::ADD32mi, makeMIInst }, 00290 { X86::ADD32ri8, X86::ADD32mi8, makeMIInst }, 00291 { X86::ADD32rr, X86::ADD32mr, makeMRInst }, 00292 { X86::ADD8ri, X86::ADD8mi, makeMIInst }, 00293 { X86::ADD8rr, X86::ADD8mr, makeMRInst }, 00294 { X86::AND16ri, X86::AND16mi, makeMIInst }, 00295 { X86::AND16ri8, X86::AND16mi8, makeMIInst }, 00296 { X86::AND16rr, X86::AND16mr, makeMRInst }, 00297 { X86::AND32ri, X86::AND32mi, makeMIInst }, 00298 { X86::AND32ri8, X86::AND32mi8, makeMIInst }, 00299 { X86::AND32rr, X86::AND32mr, makeMRInst }, 00300 { X86::AND8ri, X86::AND8mi, makeMIInst }, 00301 { X86::AND8rr, X86::AND8mr, makeMRInst }, 00302 { X86::DEC16r, X86::DEC16m, makeMInst }, 00303 { X86::DEC32r, X86::DEC32m, makeMInst }, 00304 { X86::DEC8r, X86::DEC8m, makeMInst }, 00305 { X86::DIV16r, X86::DIV16m, makeMInst }, 00306 { X86::DIV32r, X86::DIV32m, makeMInst }, 00307 { X86::DIV8r, X86::DIV8m, makeMInst }, 00308 { X86::FsMOVAPDrr, X86::MOVSDmr, makeMRInst }, 00309 { X86::FsMOVAPSrr, X86::MOVSSmr, makeMRInst }, 00310 { X86::IDIV16r, X86::IDIV16m, makeMInst }, 00311 { X86::IDIV32r, X86::IDIV32m, makeMInst }, 00312 { X86::IDIV8r, X86::IDIV8m, makeMInst }, 00313 { X86::IMUL16r, X86::IMUL16m, makeMInst }, 00314 { X86::IMUL32r, X86::IMUL32m, makeMInst }, 00315 { X86::IMUL8r, X86::IMUL8m, makeMInst }, 00316 { X86::INC16r, X86::INC16m, makeMInst }, 00317 { X86::INC32r, X86::INC32m, makeMInst }, 00318 { X86::INC8r, X86::INC8m, makeMInst }, 00319 { X86::MOV16r0, X86::MOV16mi, makeM0Inst }, 00320 { X86::MOV16ri, X86::MOV16mi, makeMIInst }, 00321 { X86::MOV16rr, X86::MOV16mr, makeMRInst }, 00322 { X86::MOV32r0, X86::MOV32mi, makeM0Inst }, 00323 { X86::MOV32ri, X86::MOV32mi, makeMIInst }, 00324 { X86::MOV32rr, X86::MOV32mr, makeMRInst }, 00325 { X86::MOV8r0, X86::MOV8mi, makeM0Inst }, 00326 { X86::MOV8ri, X86::MOV8mi, makeMIInst }, 00327 { X86::MOV8rr, X86::MOV8mr, makeMRInst }, 00328 { X86::MOVAPDrr, X86::MOVAPDmr, makeMRInst }, 00329 { X86::MOVAPSrr, X86::MOVAPSmr, makeMRInst }, 00330 { X86::MOVPDI2DIrr, X86::MOVPDI2DImr, makeMRInst }, 00331 { X86::MOVPS2SSrr, X86::MOVPS2SSmr, makeMRInst }, 00332 { X86::MOVSDrr, X86::MOVSDmr, makeMRInst }, 00333 { X86::MOVSSrr, X86::MOVSSmr, makeMRInst }, 00334 { X86::MOVUPDrr, X86::MOVUPDmr, makeMRInst }, 00335 { X86::MOVUPSrr, X86::MOVUPSmr, makeMRInst }, 00336 { X86::MUL16r, X86::MUL16m, makeMInst }, 00337 { X86::MUL32r, X86::MUL32m, makeMInst }, 00338 { X86::MUL8r, X86::MUL8m, makeMInst }, 00339 { X86::NEG16r, X86::NEG16m, makeMInst }, 00340 { X86::NEG32r, X86::NEG32m, makeMInst }, 00341 { X86::NEG8r, X86::NEG8m, makeMInst }, 00342 { X86::NOT16r, X86::NOT16m, makeMInst }, 00343 { X86::NOT32r, X86::NOT32m, makeMInst }, 00344 { X86::NOT8r, X86::NOT8m, makeMInst }, 00345 { X86::OR16ri, X86::OR16mi, makeMIInst }, 00346 { X86::OR16ri8, X86::OR16mi8, makeMIInst }, 00347 { X86::OR16rr, X86::OR16mr, makeMRInst }, 00348 { X86::OR32ri, X86::OR32mi, makeMIInst }, 00349 { X86::OR32ri8, X86::OR32mi8, makeMIInst }, 00350 { X86::OR32rr, X86::OR32mr, makeMRInst }, 00351 { X86::OR8ri, X86::OR8mi, makeMIInst }, 00352 { X86::OR8rr, X86::OR8mr, makeMRInst }, 00353 { X86::ROL16r1, X86::ROL16m1, makeMInst }, 00354 { X86::ROL16rCL, X86::ROL16mCL, makeMInst }, 00355 { X86::ROL16ri, X86::ROL16mi, makeMIInst }, 00356 { X86::ROL32r1, X86::ROL32m1, makeMInst }, 00357 { X86::ROL32rCL, X86::ROL32mCL, makeMInst }, 00358 { X86::ROL32ri, X86::ROL32mi, makeMIInst }, 00359 { X86::ROL8r1, X86::ROL8m1, makeMInst }, 00360 { X86::ROL8rCL, X86::ROL8mCL, makeMInst }, 00361 { X86::ROL8ri, X86::ROL8mi, makeMIInst }, 00362 { X86::ROR16r1, X86::ROR16m1, makeMInst }, 00363 { X86::ROR16rCL, X86::ROR16mCL, makeMInst }, 00364 { X86::ROR16ri, X86::ROR16mi, makeMIInst }, 00365 { X86::ROR32r1, X86::ROR32m1, makeMInst }, 00366 { X86::ROR32rCL, X86::ROR32mCL, makeMInst }, 00367 { X86::ROR32ri, X86::ROR32mi, makeMIInst }, 00368 { X86::ROR8r1, X86::ROR8m1, makeMInst }, 00369 { X86::ROR8rCL, X86::ROR8mCL, makeMInst }, 00370 { X86::ROR8ri, X86::ROR8mi, makeMIInst }, 00371 { X86::SAR16r1, X86::SAR16m1, makeMInst }, 00372 { X86::SAR16rCL, X86::SAR16mCL, makeMInst }, 00373 { X86::SAR16ri, X86::SAR16mi, makeMIInst }, 00374 { X86::SAR32r1, X86::SAR32m1, makeMInst }, 00375 { X86::SAR32rCL, X86::SAR32mCL, makeMInst }, 00376 { X86::SAR32ri, X86::SAR32mi, makeMIInst }, 00377 { X86::SAR8r1, X86::SAR8m1, makeMInst }, 00378 { X86::SAR8rCL, X86::SAR8mCL, makeMInst }, 00379 { X86::SAR8ri, X86::SAR8mi, makeMIInst }, 00380 { X86::SBB32ri, X86::SBB32mi, makeMIInst }, 00381 { X86::SBB32ri8, X86::SBB32mi8, makeMIInst }, 00382 { X86::SBB32rr, X86::SBB32mr, makeMRInst }, 00383 { X86::SETAEr, X86::SETAEm, makeMInst }, 00384 { X86::SETAr, X86::SETAm, makeMInst }, 00385 { X86::SETBEr, X86::SETBEm, makeMInst }, 00386 { X86::SETBr, X86::SETBm, makeMInst }, 00387 { X86::SETEr, X86::SETEm, makeMInst }, 00388 { X86::SETGEr, X86::SETGEm, makeMInst }, 00389 { X86::SETGr, X86::SETGm, makeMInst }, 00390 { X86::SETLEr, X86::SETLEm, makeMInst }, 00391 { X86::SETLr, X86::SETLm, makeMInst }, 00392 { X86::SETNEr, X86::SETNEm, makeMInst }, 00393 { X86::SETNPr, X86::SETNPm, makeMInst }, 00394 { X86::SETNSr, X86::SETNSm, makeMInst }, 00395 { X86::SETPr, X86::SETPm, makeMInst }, 00396 { X86::SETSr, X86::SETSm, makeMInst }, 00397 { X86::SHL16r1, X86::SHL16m1, makeMInst }, 00398 { X86::SHL16rCL, X86::SHL16mCL, makeMInst }, 00399 { X86::SHL16ri, X86::SHL16mi, makeMIInst }, 00400 { X86::SHL32r1, X86::SHL32m1, makeMInst }, 00401 { X86::SHL32rCL, X86::SHL32mCL, makeMInst }, 00402 { X86::SHL32ri, X86::SHL32mi, makeMIInst }, 00403 { X86::SHL8r1, X86::SHL8m1, makeMInst }, 00404 { X86::SHL8rCL, X86::SHL8mCL, makeMInst }, 00405 { X86::SHL8ri, X86::SHL8mi, makeMIInst }, 00406 { X86::SHLD16rrCL, X86::SHLD16mrCL, makeMRInst }, 00407 { X86::SHLD16rri8, X86::SHLD16mri8, makeMRIInst }, 00408 { X86::SHLD32rrCL, X86::SHLD32mrCL, makeMRInst }, 00409 { X86::SHLD32rri8, X86::SHLD32mri8, makeMRIInst }, 00410 { X86::SHR16r1, X86::SHR16m1, makeMInst }, 00411 { X86::SHR16rCL, X86::SHR16mCL, makeMInst }, 00412 { X86::SHR16ri, X86::SHR16mi, makeMIInst }, 00413 { X86::SHR32r1, X86::SHR32m1, makeMInst }, 00414 { X86::SHR32rCL, X86::SHR32mCL, makeMInst }, 00415 { X86::SHR32ri, X86::SHR32mi, makeMIInst }, 00416 { X86::SHR8r1, X86::SHR8m1, makeMInst }, 00417 { X86::SHR8rCL, X86::SHR8mCL, makeMInst }, 00418 { X86::SHR8ri, X86::SHR8mi, makeMIInst }, 00419 { X86::SHRD16rrCL, X86::SHRD16mrCL, makeMRInst }, 00420 { X86::SHRD16rri8, X86::SHRD16mri8, makeMRIInst }, 00421 { X86::SHRD32rrCL, X86::SHRD32mrCL, makeMRInst }, 00422 { X86::SHRD32rri8, X86::SHRD32mri8, makeMRIInst }, 00423 { X86::SUB16ri, X86::SUB16mi, makeMIInst }, 00424 { X86::SUB16ri8, X86::SUB16mi8, makeMIInst }, 00425 { X86::SUB16rr, X86::SUB16mr, makeMRInst }, 00426 { X86::SUB32ri, X86::SUB32mi, makeMIInst }, 00427 { X86::SUB32ri8, X86::SUB32mi8, makeMIInst }, 00428 { X86::SUB32rr, X86::SUB32mr, makeMRInst }, 00429 { X86::SUB8ri, X86::SUB8mi, makeMIInst }, 00430 { X86::SUB8rr, X86::SUB8mr, makeMRInst }, 00431 { X86::XCHG16rr, X86::XCHG16mr, makeMRInst }, 00432 { X86::XCHG32rr, X86::XCHG32mr, makeMRInst }, 00433 { X86::XCHG8rr, X86::XCHG8mr, makeMRInst }, 00434 { X86::XOR16ri, X86::XOR16mi, makeMIInst }, 00435 { X86::XOR16ri8, X86::XOR16mi8, makeMIInst }, 00436 { X86::XOR16rr, X86::XOR16mr, makeMRInst }, 00437 { X86::XOR32ri, X86::XOR32mi, makeMIInst }, 00438 { X86::XOR32ri8, X86::XOR32mi8, makeMIInst }, 00439 { X86::XOR32rr, X86::XOR32mr, makeMRInst }, 00440 { X86::XOR8ri, X86::XOR8mi, makeMIInst }, 00441 { X86::XOR8rr, X86::XOR8mr, makeMRInst } 00442 }; 00443 ASSERT_SORTED(OpcodeTable); 00444 OpcodeTablePtr = OpcodeTable; 00445 OpcodeTableSize = ARRAY_SIZE(OpcodeTable); 00446 } else if (i == 1) { 00447 static const TableEntry OpcodeTable[] = { 00448 { X86::ADC32rr, X86::ADC32rm, makeRMInst }, 00449 { X86::ADD16rr, X86::ADD16rm, makeRMInst }, 00450 { X86::ADD32rr, X86::ADD32rm, makeRMInst }, 00451 { X86::ADD8rr, X86::ADD8rm, makeRMInst }, 00452 { X86::ADDPDrr, X86::ADDPDrm, makeRMInst }, 00453 { X86::ADDPSrr, X86::ADDPSrm, makeRMInst }, 00454 { X86::ADDSDrr, X86::ADDSDrm, makeRMInst }, 00455 { X86::ADDSSrr, X86::ADDSSrm, makeRMInst }, 00456 { X86::ADDSUBPDrr, X86::ADDSUBPDrm, makeRMInst }, 00457 { X86::ADDSUBPSrr, X86::ADDSUBPSrm, makeRMInst }, 00458 { X86::AND16rr, X86::AND16rm, makeRMInst }, 00459 { X86::AND32rr, X86::AND32rm, makeRMInst }, 00460 { X86::AND8rr, X86::AND8rm, makeRMInst }, 00461 { X86::ANDNPDrr, X86::ANDNPDrm, makeRMInst }, 00462 { X86::ANDNPSrr, X86::ANDNPSrm, makeRMInst }, 00463 { X86::ANDPDrr, X86::ANDPDrm, makeRMInst }, 00464 { X86::ANDPSrr, X86::ANDPSrm, makeRMInst }, 00465 { X86::CMOVA16rr, X86::CMOVA16rm, makeRMInst }, 00466 { X86::CMOVA32rr, X86::CMOVA32rm, makeRMInst }, 00467 { X86::CMOVAE16rr, X86::CMOVAE16rm, makeRMInst }, 00468 { X86::CMOVAE32rr, X86::CMOVAE32rm, makeRMInst }, 00469 { X86::CMOVB16rr, X86::CMOVB16rm, makeRMInst }, 00470 { X86::CMOVB32rr, X86::CMOVB32rm, makeRMInst }, 00471 { X86::CMOVBE16rr, X86::CMOVBE16rm, makeRMInst }, 00472 { X86::CMOVBE32rr, X86::CMOVBE32rm, makeRMInst }, 00473 { X86::CMOVE16rr, X86::CMOVE16rm, makeRMInst }, 00474 { X86::CMOVE32rr, X86::CMOVE32rm, makeRMInst }, 00475 { X86::CMOVG16rr, X86::CMOVG16rm, makeRMInst }, 00476 { X86::CMOVG32rr, X86::CMOVG32rm, makeRMInst }, 00477 { X86::CMOVGE16rr, X86::CMOVGE16rm, makeRMInst }, 00478 { X86::CMOVGE32rr, X86::CMOVGE32rm, makeRMInst }, 00479 { X86::CMOVL16rr, X86::CMOVL16rm, makeRMInst }, 00480 { X86::CMOVL32rr, X86::CMOVL32rm, makeRMInst }, 00481 { X86::CMOVLE16rr, X86::CMOVLE16rm, makeRMInst }, 00482 { X86::CMOVLE32rr, X86::CMOVLE32rm, makeRMInst }, 00483 { X86::CMOVNE16rr, X86::CMOVNE16rm, makeRMInst }, 00484 { X86::CMOVNE32rr, X86::CMOVNE32rm, makeRMInst }, 00485 { X86::CMOVNP16rr, X86::CMOVNP16rm, makeRMInst }, 00486 { X86::CMOVNP32rr, X86::CMOVNP32rm, makeRMInst }, 00487 { X86::CMOVNS16rr, X86::CMOVNS16rm, makeRMInst }, 00488 { X86::CMOVNS32rr, X86::CMOVNS32rm, makeRMInst }, 00489 { X86::CMOVP16rr, X86::CMOVP16rm, makeRMInst }, 00490 { X86::CMOVP32rr, X86::CMOVP32rm, makeRMInst }, 00491 { X86::CMOVS16rr, X86::CMOVS16rm, makeRMInst }, 00492 { X86::CMOVS32rr, X86::CMOVS32rm, makeRMInst }, 00493 { X86::CMP16ri, X86::CMP16mi, makeMIInst }, 00494 { X86::CMP16ri8, X86::CMP16mi8, makeMIInst }, 00495 { X86::CMP16rr, X86::CMP16rm, makeRMInst }, 00496 { X86::CMP32ri, X86::CMP32mi, makeMIInst }, 00497 { X86::CMP32ri8, X86::CMP32mi8, makeRMInst }, 00498 { X86::CMP32rr, X86::CMP32rm, makeRMInst }, 00499 { X86::CMP8ri, X86::CMP8mi, makeRMInst }, 00500 { X86::CMP8rr, X86::CMP8rm, makeRMInst }, 00501 { X86::CMPPDrri, X86::CMPPDrmi, makeRMIInst }, 00502 { X86::CMPPSrri, X86::CMPPSrmi, makeRMIInst }, 00503 { X86::CMPSDrr, X86::CMPSDrm, makeRMInst }, 00504 { X86::CMPSSrr, X86::CMPSSrm, makeRMInst }, 00505 { X86::CVTSD2SSrr, X86::CVTSD2SSrm, makeRMInst }, 00506 { X86::CVTSI2SDrr, X86::CVTSI2SDrm, makeRMInst }, 00507 { X86::CVTSI2SSrr, X86::CVTSI2SSrm, makeRMInst }, 00508 { X86::CVTSS2SDrr, X86::CVTSS2SDrm, makeRMInst }, 00509 { X86::CVTTSD2SIrr, X86::CVTTSD2SIrm, makeRMInst }, 00510 { X86::CVTTSS2SIrr, X86::CVTTSS2SIrm, makeRMInst }, 00511 { X86::DIVPDrr, X86::DIVPDrm, makeRMInst }, 00512 { X86::DIVPSrr, X86::DIVPSrm, makeRMInst }, 00513 { X86::DIVSDrr, X86::DIVSDrm, makeRMInst }, 00514 { X86::DIVSSrr, X86::DIVSSrm, makeRMInst }, 00515 { X86::FsMOVAPDrr, X86::MOVSDrm, makeRMInst }, 00516 { X86::FsMOVAPSrr, X86::MOVSSrm, makeRMInst }, 00517 { X86::HADDPDrr, X86::HADDPDrm, makeRMInst }, 00518 { X86::HADDPSrr, X86::HADDPSrm, makeRMInst }, 00519 { X86::HSUBPDrr, X86::HSUBPDrm, makeRMInst }, 00520 { X86::HSUBPSrr, X86::HSUBPSrm, makeRMInst }, 00521 { X86::IMUL16rr, X86::IMUL16rm, makeRMInst }, 00522 { X86::IMUL16rri, X86::IMUL16rmi, makeRMIInst }, 00523 { X86::IMUL16rri8, X86::IMUL16rmi8, makeRMIInst }, 00524 { X86::IMUL32rr, X86::IMUL32rm, makeRMInst }, 00525 { X86::IMUL32rri, X86::IMUL32rmi, makeRMIInst }, 00526 { X86::IMUL32rri8, X86::IMUL32rmi8, makeRMIInst }, 00527 { X86::Int_CMPSDrr, X86::Int_CMPSDrm, makeRMInst }, 00528 { X86::Int_CMPSSrr, X86::Int_CMPSSrm, makeRMInst }, 00529 { X86::Int_COMISDrr, X86::Int_COMISDrm, makeRMInst }, 00530 { X86::Int_COMISSrr, X86::Int_COMISSrm, makeRMInst }, 00531 { X86::Int_CVTDQ2PDrr, X86::Int_CVTDQ2PDrm, makeRMInst }, 00532 { X86::Int_CVTDQ2PSrr, X86::Int_CVTDQ2PSrm, makeRMInst }, 00533 { X86::Int_CVTPD2DQrr, X86::Int_CVTPD2DQrm, makeRMInst }, 00534 { X86::Int_CVTPD2PSrr, X86::Int_CVTPD2PSrm, makeRMInst }, 00535 { X86::Int_CVTPS2DQrr, X86::Int_CVTPS2DQrm, makeRMInst }, 00536 { X86::Int_CVTPS2PDrr, X86::Int_CVTPS2PDrm, makeRMInst }, 00537 { X86::Int_CVTSD2SIrr, X86::Int_CVTSD2SIrm, makeRMInst }, 00538 { X86::Int_CVTSD2SSrr, X86::Int_CVTSD2SSrm, makeRMInst }, 00539 { X86::Int_CVTSI2SDrr, X86::Int_CVTSI2SDrm, makeRMInst }, 00540 { X86::Int_CVTSI2SSrr, X86::Int_CVTSI2SSrm, makeRMInst }, 00541 { X86::Int_CVTSS2SDrr, X86::Int_CVTSS2SDrm, makeRMInst }, 00542 { X86::Int_CVTSS2SIrr, X86::Int_CVTSS2SIrm, makeRMInst }, 00543 { X86::Int_CVTTPD2DQrr, X86::Int_CVTTPD2DQrm, makeRMInst }, 00544 { X86::Int_CVTTPS2DQrr, X86::Int_CVTTPS2DQrm, makeRMInst }, 00545 { X86::Int_CVTTSD2SIrr, X86::Int_CVTTSD2SIrm, makeRMInst }, 00546 { X86::Int_CVTTSS2SIrr, X86::Int_CVTTSS2SIrm, makeRMInst }, 00547 { X86::Int_UCOMISDrr, X86::Int_UCOMISDrm, makeRMInst }, 00548 { X86::Int_UCOMISSrr, X86::Int_UCOMISSrm, makeRMInst }, 00549 { X86::MAXPDrr, X86::MAXPDrm, makeRMInst }, 00550 { X86::MAXPSrr, X86::MAXPSrm, makeRMInst }, 00551 { X86::MINPDrr, X86::MINPDrm, makeRMInst }, 00552 { X86::MINPSrr, X86::MINPSrm, makeRMInst }, 00553 { X86::MOV16rr, X86::MOV16rm, makeRMInst }, 00554 { X86::MOV32rr, X86::MOV32rm, makeRMInst }, 00555 { X86::MOV8rr, X86::MOV8rm, makeRMInst }, 00556 { X86::MOVAPDrr, X86::MOVAPDrm, makeRMInst }, 00557 { X86::MOVAPSrr, X86::MOVAPSrm, makeRMInst }, 00558 { X86::MOVDDUPrr, X86::MOVDDUPrm, makeRMInst }, 00559 { X86::MOVDI2PDIrr, X86::MOVDI2PDIrm, makeRMInst }, 00560 { X86::MOVQI2PQIrr, X86::MOVQI2PQIrm, makeRMInst }, 00561 { X86::MOVSD2PDrr, X86::MOVSD2PDrm, makeRMInst }, 00562 { X86::MOVSDrr, X86::MOVSDrm, makeRMInst }, 00563 { X86::MOVSHDUPrr, X86::MOVSHDUPrm, makeRMInst }, 00564 { X86::MOVSLDUPrr, X86::MOVSLDUPrm, makeRMInst }, 00565 { X86::MOVSS2PSrr, X86::MOVSS2PSrm, makeRMInst }, 00566 { X86::MOVSSrr, X86::MOVSSrm, makeRMInst }, 00567 { X86::MOVSX16rr8, X86::MOVSX16rm8, makeRMInst }, 00568 { X86::MOVSX32rr16, X86::MOVSX32rm16, makeRMInst }, 00569 { X86::MOVSX32rr8, X86::MOVSX32rm8, makeRMInst }, 00570 { X86::MOVUPDrr, X86::MOVUPDrm, makeRMInst }, 00571 { X86::MOVUPSrr, X86::MOVUPSrm, makeRMInst }, 00572 { X86::MOVZX16rr8, X86::MOVZX16rm8, makeRMInst }, 00573 { X86::MOVZX32rr16, X86::MOVZX32rm16, makeRMInst }, 00574 { X86::MOVZX32rr8, X86::MOVZX32rm8, makeRMInst }, 00575 { X86::MULPDrr, X86::MULPDrm, makeRMInst }, 00576 { X86::MULPSrr, X86::MULPSrm, makeRMInst }, 00577 { X86::MULSDrr, X86::MULSDrm, makeRMInst }, 00578 { X86::MULSSrr, X86::MULSSrm, makeRMInst }, 00579 { X86::OR16rr, X86::OR16rm, makeRMInst }, 00580 { X86::OR32rr, X86::OR32rm, makeRMInst }, 00581 { X86::OR8rr, X86::OR8rm, makeRMInst }, 00582 { X86::ORPDrr, X86::ORPDrm, makeRMInst }, 00583 { X86::ORPSrr, X86::ORPSrm, makeRMInst }, 00584 { X86::PACKSSDWrr, X86::PACKSSDWrm, makeRMInst }, 00585 { X86::PACKSSWBrr, X86::PACKSSWBrm, makeRMInst }, 00586 { X86::PACKUSWBrr, X86::PACKUSWBrm, makeRMInst }, 00587 { X86::PADDBrr, X86::PADDBrm, makeRMInst }, 00588 { X86::PADDDrr, X86::PADDDrm, makeRMInst }, 00589 { X86::PADDSBrr, X86::PADDSBrm, makeRMInst }, 00590 { X86::PADDSWrr, X86::PADDSWrm, makeRMInst }, 00591 { X86::PADDWrr, X86::PADDWrm, makeRMInst }, 00592 { X86::PANDNrr, X86::PANDNrm, makeRMInst }, 00593 { X86::PANDrr, X86::PANDrm, makeRMInst }, 00594 { X86::PAVGBrr, X86::PAVGBrm, makeRMInst }, 00595 { X86::PAVGWrr, X86::PAVGWrm, makeRMInst }, 00596 { X86::PCMPEQBrr, X86::PCMPEQBrm, makeRMInst }, 00597 { X86::PCMPEQDrr, X86::PCMPEQDrm, makeRMInst }, 00598 { X86::PCMPEQWrr, X86::PCMPEQWrm, makeRMInst }, 00599 { X86::PCMPGTBrr, X86::PCMPGTBrm, makeRMInst }, 00600 { X86::PCMPGTDrr, X86::PCMPGTDrm, makeRMInst }, 00601 { X86::PCMPGTWrr, X86::PCMPGTWrm, makeRMInst }, 00602 { X86::PINSRWrri, X86::PINSRWrmi, makeRMIInst }, 00603 { X86::PMADDWDrr, X86::PMADDWDrm, makeRMInst }, 00604 { X86::PMAXSWrr, X86::PMAXSWrm, makeRMInst }, 00605 { X86::PMAXUBrr, X86::PMAXUBrm, makeRMInst }, 00606 { X86::PMINSWrr, X86::PMINSWrm, makeRMInst }, 00607 { X86::PMINUBrr, X86::PMINUBrm, makeRMInst }, 00608 { X86::PMULHUWrr, X86::PMULHUWrm, makeRMInst }, 00609 { X86::PMULHWrr, X86::PMULHWrm, makeRMInst }, 00610 { X86::PMULLWrr, X86::PMULLWrm, makeRMInst }, 00611 { X86::PMULUDQrr, X86::PMULUDQrm, makeRMInst }, 00612 { X86::PORrr, X86::PORrm, makeRMInst }, 00613 { X86::PSADBWrr, X86::PSADBWrm, makeRMInst }, 00614 { X86::PSHUFDri, X86::PSHUFDmi, makeRMIInst }, 00615 { X86::PSHUFHWri, X86::PSHUFHWmi, makeRMIInst }, 00616 { X86::PSHUFLWri, X86::PSHUFLWmi, makeRMIInst }, 00617 { X86::PSLLDrr, X86::PSLLDrm, makeRMInst }, 00618 { X86::PSLLQrr, X86::PSLLQrm, makeRMInst }, 00619 { X86::PSLLWrr, X86::PSLLWrm, makeRMInst }, 00620 { X86::PSRADrr, X86::PSRADrm, makeRMInst }, 00621 { X86::PSRAWrr, X86::PSRAWrm, makeRMInst }, 00622 { X86::PSRLDrr, X86::PSRLDrm, makeRMInst }, 00623 { X86::PSRLQrr, X86::PSRLQrm, makeRMInst }, 00624 { X86::PSRLWrr, X86::PSRLWrm, makeRMInst }, 00625 { X86::PSUBBrr, X86::PSUBBrm, makeRMInst }, 00626 { X86::PSUBDrr, X86::PSUBDrm, makeRMInst }, 00627 { X86::PSUBSBrr, X86::PSUBSBrm, makeRMInst }, 00628 { X86::PSUBSWrr, X86::PSUBSWrm, makeRMInst }, 00629 { X86::PSUBWrr, X86::PSUBWrm, makeRMInst }, 00630 { X86::PUNPCKHBWrr, X86::PUNPCKHBWrm, makeRMInst }, 00631 { X86::PUNPCKHDQrr, X86::PUNPCKHDQrm, makeRMInst }, 00632 { X86::PUNPCKHQDQrr, X86::PUNPCKHQDQrm, makeRMInst }, 00633 { X86::PUNPCKHWDrr, X86::PUNPCKHWDrm, makeRMInst }, 00634 { X86::PUNPCKLBWrr, X86::PUNPCKLBWrm, makeRMInst }, 00635 { X86::PUNPCKLDQrr, X86::PUNPCKLDQrm, makeRMInst }, 00636 { X86::PUNPCKLQDQrr, X86::PUNPCKLQDQrm, makeRMInst }, 00637 { X86::PUNPCKLWDrr, X86::PUNPCKLWDrm, makeRMInst }, 00638 { X86::PXORrr, X86::PXORrm, makeRMInst }, 00639 { X86::RCPPSr, X86::RCPPSm, makeRMInst }, 00640 { X86::RSQRTPSr, X86::RSQRTPSm, makeRMInst }, 00641 { X86::SBB32rr, X86::SBB32rm, makeRMInst }, 00642 { X86::SHUFPDrri, X86::SHUFPDrmi, makeRMIInst }, 00643 { X86::SHUFPSrri, X86::SHUFPSrmi, makeRMIInst }, 00644 { X86::SQRTPDr, X86::SQRTPDm, makeRMInst }, 00645 { X86::SQRTPSr, X86::SQRTPSm, makeRMInst }, 00646 { X86::SQRTSDr, X86::SQRTSDm, makeRMInst }, 00647 { X86::SQRTSSr, X86::SQRTSSm, makeRMInst }, 00648 { X86::SUB16rr, X86::SUB16rm, makeRMInst }, 00649 { X86::SUB32rr, X86::SUB32rm, makeRMInst }, 00650 { X86::SUB8rr, X86::SUB8rm, makeRMInst }, 00651 { X86::SUBPDrr, X86::SUBPDrm, makeRMInst }, 00652 { X86::SUBPSrr, X86::SUBPSrm, makeRMInst }, 00653 { X86::SUBSDrr, X86::SUBSDrm, makeRMInst }, 00654 { X86::SUBSSrr, X86::SUBSSrm, makeRMInst }, 00655 { X86::TEST16ri, X86::TEST16mi, makeMIInst }, 00656 { X86::TEST16rr, X86::TEST16rm, makeRMInst }, 00657 { X86::TEST32ri, X86::TEST32mi, makeMIInst }, 00658 { X86::TEST32rr, X86::TEST32rm, makeRMInst }, 00659 { X86::TEST8ri, X86::TEST8mi, makeMIInst }, 00660 { X86::TEST8rr, X86::TEST8rm, makeRMInst }, 00661 { X86::UCOMISDrr, X86::UCOMISDrm, makeRMInst }, 00662 { X86::UCOMISSrr, X86::UCOMISSrm, makeRMInst }, 00663 { X86::UNPCKHPDrr, X86::UNPCKHPDrm, makeRMInst }, 00664 { X86::UNPCKHPSrr, X86::UNPCKHPSrm, makeRMInst }, 00665 { X86::UNPCKLPDrr, X86::UNPCKLPDrm, makeRMInst }, 00666 { X86::UNPCKLPSrr, X86::UNPCKLPSrm, makeRMInst }, 00667 { X86::XCHG16rr, X86::XCHG16rm, makeRMInst }, 00668 { X86::XCHG32rr, X86::XCHG32rm, makeRMInst }, 00669 { X86::XCHG8rr, X86::XCHG8rm, makeRMInst }, 00670 { X86::XOR16rr, X86::XOR16rm, makeRMInst }, 00671 { X86::XOR32rr, X86::XOR32rm, makeRMInst }, 00672 { X86::XOR8rr, X86::XOR8rm, makeRMInst }, 00673 { X86::XORPDrr, X86::XORPDrm, makeRMInst }, 00674 { X86::XORPSrr, X86::XORPSrm, makeRMInst } 00675 }; 00676 ASSERT_SORTED(OpcodeTable); 00677 OpcodeTablePtr = OpcodeTable; 00678 OpcodeTableSize = ARRAY_SIZE(OpcodeTable); 00679 } 00680 00681 // If table selected 00682 if (OpcodeTablePtr) { 00683 // Opcode to fuse 00684 unsigned fromOpcode = MI->getOpcode(); 00685 // Lookup fromOpcode in table 00686 const TableEntry *entry = TableLookup(OpcodeTablePtr, OpcodeTableSize, 00687 fromOpcode); 00688 00689 // If opcode found in table 00690 if (entry) { 00691 // Fused opcode 00692 unsigned toOpcode = entry->to; 00693 00694 // Make new instruction 00695 switch (entry->make) { 00696 case makeM0Inst: return MakeM0Inst(toOpcode, FrameIndex, MI); 00697 case makeMIInst: return MakeMIInst(toOpcode, FrameIndex, MI); 00698 case makeMInst: return MakeMInst(toOpcode, FrameIndex, MI); 00699 case makeMRIInst: return MakeMRIInst(toOpcode, FrameIndex, MI); 00700 case makeMRInst: return MakeMRInst(toOpcode, FrameIndex, MI); 00701 case makeRMIInst: return MakeRMIInst(toOpcode, FrameIndex, MI); 00702 case makeRMInst: return MakeRMInst(toOpcode, FrameIndex, MI); 00703 default: assert(0 && "Unknown instruction make"); 00704 } 00705 } 00706 } 00707 00708 // No fusion 00709 if (PrintFailedFusing) 00710 std::cerr << "We failed to fuse (" 00711 << ((i == 1) ? "r" : "s") << "): " << *MI; 00712 return NULL; 00713 } 00714 00715 00716 const unsigned *X86RegisterInfo::getCalleeSaveRegs() const { 00717 static const unsigned CalleeSaveRegs[] = { 00718 X86::ESI, X86::EDI, X86::EBX, X86::EBP, 0 00719 }; 00720 return CalleeSaveRegs; 00721 } 00722 00723 const TargetRegisterClass* const* 00724 X86RegisterInfo::getCalleeSaveRegClasses() const { 00725 static const TargetRegisterClass * const CalleeSaveRegClasses[] = { 00726 &X86::GR32RegClass, &X86::GR32RegClass, 00727 &X86::GR32RegClass, &X86::GR32RegClass, 0 00728 }; 00729 return CalleeSaveRegClasses; 00730 } 00731 00732 //===----------------------------------------------------------------------===// 00733 // Stack Frame Processing methods 00734 //===----------------------------------------------------------------------===// 00735 00736 // hasFP - Return true if the specified function should have a dedicated frame 00737 // pointer register. This is true if the function has variable sized allocas or 00738 // if frame pointer elimination is disabled. 00739 // 00740 static bool hasFP(MachineFunction &MF) { 00741 return (NoFramePointerElim || 00742 MF.getFrameInfo()->hasVarSizedObjects() || 00743 MF.getInfo<X86FunctionInfo>()->getForceFramePointer()); 00744 } 00745 00746 void X86RegisterInfo:: 00747 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 00748 MachineBasicBlock::iterator I) const { 00749 if (hasFP(MF)) { 00750 // If we have a frame pointer, turn the adjcallstackup instruction into a 00751 // 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP, 00752 // <amt>' 00753 MachineInstr *Old = I; 00754 unsigned Amount = Old->getOperand(0).getImmedValue(); 00755 if (Amount != 0) { 00756 // We need to keep the stack aligned properly. To do this, we round the 00757 // amount of space needed for the outgoing arguments up to the next 00758 // alignment boundary. 00759 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 00760 Amount = (Amount+Align-1)/Align*Align; 00761 00762 MachineInstr *New = 0; 00763 if (Old->getOpcode() == X86::ADJCALLSTACKDOWN) { 00764 New=BuildMI(X86::SUB32ri, 1, X86::ESP, MachineOperand::UseAndDef) 00765 .addImm(Amount); 00766 } else { 00767 assert(Old->getOpcode() == X86::ADJCALLSTACKUP); 00768 // factor out the amount the callee already popped. 00769 unsigned CalleeAmt = Old->getOperand(1).getImmedValue(); 00770 Amount -= CalleeAmt; 00771 if (Amount) { 00772 unsigned Opc = Amount < 128 ? X86::ADD32ri8 : X86::ADD32ri; 00773 New = BuildMI(Opc, 1, X86::ESP, 00774 MachineOperand::UseAndDef).addImm(Amount); 00775 } 00776 } 00777 00778 // Replace the pseudo instruction with a new instruction... 00779 if (New) MBB.insert(I, New); 00780 } 00781 } else if (I->getOpcode() == X86::ADJCALLSTACKUP) { 00782 // If we are performing frame pointer elimination and if the callee pops 00783 // something off the stack pointer, add it back. We do this until we have 00784 // more advanced stack pointer tracking ability. 00785 if (unsigned CalleeAmt = I->getOperand(1).getImmedValue()) { 00786 unsigned Opc = CalleeAmt < 128 ? X86::SUB32ri8 : X86::SUB32ri; 00787 MachineInstr *New = 00788 BuildMI(Opc, 1, X86::ESP, 00789 MachineOperand::UseAndDef).addImm(CalleeAmt); 00790 MBB.insert(I, New); 00791 } 00792 } 00793 00794 MBB.erase(I); 00795 } 00796 00797 void X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{ 00798 unsigned i = 0; 00799 MachineInstr &MI = *II; 00800 MachineFunction &MF = *MI.getParent()->getParent(); 00801 while (!MI.getOperand(i).isFrameIndex()) { 00802 ++i; 00803 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 00804 } 00805 00806 int FrameIndex = MI.getOperand(i).getFrameIndex(); 00807 00808 // This must be part of a four operand memory reference. Replace the 00809 // FrameIndex with base register with EBP. Add add an offset to the offset. 00810 MI.getOperand(i).ChangeToRegister(hasFP(MF) ? X86::EBP : X86::ESP); 00811 00812 // Now add the frame object offset to the offset from EBP. 00813 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 00814 MI.getOperand(i+3).getImmedValue()+4; 00815 00816 if (!hasFP(MF)) 00817 Offset += MF.getFrameInfo()->getStackSize(); 00818 else 00819 Offset += 4; // Skip the saved EBP 00820 00821 MI.getOperand(i+3).ChangeToImmediate(Offset); 00822 } 00823 00824 void 00825 X86RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) const{ 00826 if (hasFP(MF)) { 00827 // Create a frame entry for the EBP register that must be saved. 00828 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, -8); 00829 assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() && 00830 "Slot for EBP register must be last in order to be found!"); 00831 } 00832 } 00833 00834 void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { 00835 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 00836 MachineBasicBlock::iterator MBBI = MBB.begin(); 00837 MachineFrameInfo *MFI = MF.getFrameInfo(); 00838 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 00839 const Function* Fn = MF.getFunction(); 00840 const X86Subtarget* Subtarget = &MF.getTarget().getSubtarget<X86Subtarget>(); 00841 MachineInstr *MI; 00842 00843 // Get the number of bytes to allocate from the FrameInfo 00844 unsigned NumBytes = MFI->getStackSize(); 00845 if (MFI->hasCalls() || MF.getFrameInfo()->hasVarSizedObjects()) { 00846 // When we have no frame pointer, we reserve argument space for call sites 00847 // in the function immediately on entry to the current function. This 00848 // eliminates the need for add/sub ESP brackets around call sites. 00849 // 00850 if (!hasFP(MF)) 00851 NumBytes += MFI->getMaxCallFrameSize(); 00852 00853 // Round the size to a multiple of the alignment (don't forget the 4 byte 00854 // offset though). 00855 NumBytes = ((NumBytes+4)+Align-1)/Align*Align - 4; 00856 } 00857 00858 // Update frame info to pretend that this is part of the stack... 00859 MFI->setStackSize(NumBytes); 00860 00861 if (NumBytes) { // adjust stack pointer: ESP -= numbytes 00862 if (NumBytes >= 4096 && Subtarget->TargetType == X86Subtarget::isCygwin) { 00863 // Function prologue calls _alloca to probe the stack when allocating 00864 // more than 4k bytes in one go. Touching the stack at 4K increments is 00865 // necessary to ensure that the guard pages used by the OS virtual memory 00866 // manager are allocated in correct sequence. 00867 MI = BuildMI(X86::MOV32ri, 2, X86::EAX).addImm(NumBytes); 00868 MBB.insert(MBBI, MI); 00869 MI = BuildMI(X86::CALLpcrel32, 1).addExternalSymbol("_alloca"); 00870 MBB.insert(MBBI, MI); 00871 } else { 00872 unsigned Opc = NumBytes < 128 ? X86::SUB32ri8 : X86::SUB32ri; 00873 MI = BuildMI(Opc, 1, X86::ESP,MachineOperand::UseAndDef).addImm(NumBytes); 00874 MBB.insert(MBBI, MI); 00875 } 00876 } 00877 00878 if (hasFP(MF)) { 00879 // Get the offset of the stack slot for the EBP register... which is 00880 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. 00881 int EBPOffset = MFI->getObjectOffset(MFI->getObjectIndexBegin())+4; 00882 00883 // Save EBP into the appropriate stack slot... 00884 MI = addRegOffset(BuildMI(X86::MOV32mr, 5), // mov [ESP-<offset>], EBP 00885 X86::ESP, EBPOffset+NumBytes).addReg(X86::EBP); 00886 MBB.insert(MBBI, MI); 00887 00888 // Update EBP with the new base value... 00889 if (NumBytes == 4) // mov EBP, ESP 00890 MI = BuildMI(X86::MOV32rr, 2, X86::EBP).addReg(X86::ESP); 00891 else // lea EBP, [ESP+StackSize] 00892 MI = addRegOffset(BuildMI(X86::LEA32r, 5, X86::EBP), X86::ESP,NumBytes-4); 00893 00894 MBB.insert(MBBI, MI); 00895 } 00896 00897 // If it's main() on Cygwin\Mingw32 we should align stack as well 00898 if (Fn->hasExternalLinkage() && Fn->getName() == "main" && 00899 Subtarget->TargetType == X86Subtarget::isCygwin) { 00900 MI = BuildMI(X86::AND32ri, 2, X86::ESP).addImm(-Align); 00901 MBB.insert(MBBI, MI); 00902 00903 // Probe the stack 00904 MI = BuildMI(X86::MOV32ri, 2, X86::EAX).addImm(Align); 00905 MBB.insert(MBBI, MI); 00906 MI = BuildMI(X86::CALLpcrel32, 1).addExternalSymbol("_alloca"); 00907 MBB.insert(MBBI, MI); 00908 } 00909 } 00910 00911 void X86RegisterInfo::emitEpilogue(MachineFunction &MF, 00912 MachineBasicBlock &MBB) const { 00913 const MachineFrameInfo *MFI = MF.getFrameInfo(); 00914 MachineBasicBlock::iterator MBBI = prior(MBB.end()); 00915 00916 switch (MBBI->getOpcode()) { 00917 case X86::RET: 00918 case X86::RETI: 00919 case X86::TAILJMPd: 00920 case X86::TAILJMPr: 00921 case X86::TAILJMPm: break; // These are ok 00922 default: 00923 assert(0 && "Can only insert epilog into returning blocks"); 00924 } 00925 00926 if (hasFP(MF)) { 00927 // Get the offset of the stack slot for the EBP register... which is 00928 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. 00929 int EBPOffset = MFI->getObjectOffset(MFI->getObjectIndexEnd()-1)+4; 00930 00931 // mov ESP, EBP 00932 BuildMI(MBB, MBBI, X86::MOV32rr, 1,X86::ESP).addReg(X86::EBP); 00933 00934 // pop EBP 00935 BuildMI(MBB, MBBI, X86::POP32r, 0, X86::EBP); 00936 } else { 00937 // Get the number of bytes allocated from the FrameInfo... 00938 unsigned NumBytes = MFI->getStackSize(); 00939 00940 if (NumBytes) { // adjust stack pointer back: ESP += numbytes 00941 // If there is an ADD32ri or SUB32ri of ESP immediately before this 00942 // instruction, merge the two instructions. 00943 if (MBBI != MBB.begin()) { 00944 MachineBasicBlock::iterator PI = prior(MBBI); 00945 if ((PI->getOpcode() == X86::ADD32ri || 00946 PI->getOpcode() == X86::ADD32ri8) && 00947 PI->getOperand(0).getReg() == X86::ESP) { 00948 NumBytes += PI->getOperand(1).getImmedValue(); 00949 MBB.erase(PI); 00950 } else if ((PI->getOpcode() == X86::SUB32ri || 00951 PI->getOpcode() == X86::SUB32ri8) && 00952 PI->getOperand(0).getReg() == X86::ESP) { 00953 NumBytes -= PI->getOperand(1).getImmedValue(); 00954 MBB.erase(PI); 00955 } else if (PI->getOpcode() == X86::ADJSTACKPTRri) { 00956 NumBytes += PI->getOperand(1).getImmedValue(); 00957 MBB.erase(PI); 00958 } 00959 } 00960 00961 if (NumBytes > 0) { 00962 unsigned Opc = NumBytes < 128 ? X86::ADD32ri8 : X86::ADD32ri; 00963 BuildMI(MBB, MBBI, Opc, 2) 00964 .addReg(X86::ESP, MachineOperand::UseAndDef).addImm(NumBytes); 00965 } else if ((int)NumBytes < 0) { 00966 unsigned Opc = -NumBytes < 128 ? X86::SUB32ri8 : X86::SUB32ri; 00967 BuildMI(MBB, MBBI, Opc, 2) 00968 .addReg(X86::ESP, MachineOperand::UseAndDef).addImm(-NumBytes); 00969 } 00970 } 00971 } 00972 } 00973 00974 unsigned X86RegisterInfo::getRARegister() const { 00975 return X86::ST0; // use a non-register register 00976 } 00977 00978 unsigned X86RegisterInfo::getFrameRegister(MachineFunction &MF) const { 00979 return hasFP(MF) ? X86::EBP : X86::ESP; 00980 } 00981 00982 namespace llvm { 00983 unsigned getX86SubSuperRegister(unsigned Reg, MVT::ValueType VT, bool High) { 00984 switch (VT) { 00985 default: return Reg; 00986 case MVT::i8: 00987 if (High) { 00988 switch (Reg) { 00989 default: return Reg; 00990 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: 00991 return X86::AH; 00992 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: 00993 return X86::DH; 00994 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: 00995 return X86::CH; 00996 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: 00997 return X86::BH; 00998 } 00999 } else { 01000 switch (Reg) { 01001 default: return Reg; 01002 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: 01003 return X86::AL; 01004 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: 01005 return X86::DL; 01006 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: 01007 return X86::CL; 01008 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: 01009 return X86::BL; 01010 } 01011 } 01012 case MVT::i16: 01013 switch (Reg) { 01014 default: return Reg; 01015 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: 01016 return X86::AX; 01017 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: 01018 return X86::DX; 01019 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: 01020 return X86::CX; 01021 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: 01022 return X86::BX; 01023 case X86::ESI: 01024 return X86::SI; 01025 case X86::EDI: 01026 return X86::DI; 01027 case X86::EBP: 01028 return X86::BP; 01029 case X86::ESP: 01030 return X86::SP; 01031 } 01032 case MVT::i32: 01033 switch (Reg) { 01034 default: return true; 01035 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: 01036 return X86::EAX; 01037 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: 01038 return X86::EDX; 01039 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: 01040 return X86::ECX; 01041 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: 01042 return X86::EBX; 01043 case X86::SI: 01044 return X86::ESI; 01045 case X86::DI: 01046 return X86::EDI; 01047 case X86::BP: 01048 return X86::EBP; 01049 case X86::SP: 01050 return X86::ESP; 01051 } 01052 } 01053 01054 return Reg; 01055 } 01056 } 01057 01058 #include "X86GenRegisterInfo.inc" 01059