X86InstrBuilder.h revision d74ea2bbd8bb630331f35ead42d385249bd42af8
1//===-- X86InstrBuilder.h - Functions to aid building x86 insts -*- C++ -*-===// 2// 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//===----------------------------------------------------------------------===// 9// 10// This file exposes functions that may be used with BuildMI from the 11// MachineInstrBuilder.h file to handle X86'isms in a clean way. 12// 13// The BuildMem function may be used with the BuildMI function to add entire 14// memory references in a single, typed, function call. X86 memory references 15// can be very complex expressions (described in the README), so wrapping them 16// up behind an easier to use interface makes sense. Descriptions of the 17// functions are included below. 18// 19// For reference, the order of operands for memory references is: 20// (Operand), Base, Scale, Index, Displacement. 21// 22//===----------------------------------------------------------------------===// 23 24#ifndef X86INSTRBUILDER_H 25#define X86INSTRBUILDER_H 26 27#include "llvm/CodeGen/MachineInstrBuilder.h" 28 29namespace llvm { 30 31/// X86AddressMode - This struct holds a generalized full x86 address mode. 32/// The base register can be a frame index, which will eventually be replaced 33/// with BP or SP and Disp being offsetted accordingly. The displacement may 34/// also include the offset of a global value. 35struct X86AddressMode { 36 enum { 37 RegBase, 38 FrameIndexBase 39 } BaseType; 40 41 union { 42 unsigned Reg; 43 int FrameIndex; 44 } Base; 45 46 unsigned Scale; 47 unsigned IndexReg; 48 unsigned Disp; 49 GlobalValue *GV; 50 51 X86AddressMode() : BaseType(RegBase), Scale(1), IndexReg(0), Disp(0), GV(0) { 52 Base.Reg = 0; 53 } 54}; 55 56/// addDirectMem - This function is used to add a direct memory reference to the 57/// current instruction -- that is, a dereference of an address in a register, 58/// with no scale, index or displacement. An example is: DWORD PTR [EAX]. 59/// 60inline const MachineInstrBuilder &addDirectMem(const MachineInstrBuilder &MIB, 61 unsigned Reg) { 62 // Because memory references are always represented with four 63 // values, this adds: Reg, [1, NoReg, 0] to the instruction. 64 return MIB.addReg(Reg).addImm(1).addReg(0).addImm(0); 65} 66 67 68/// addRegOffset - This function is used to add a memory reference of the form 69/// [Reg + Offset], i.e., one with no scale or index, but with a 70/// displacement. An example is: DWORD PTR [EAX + 4]. 71/// 72inline const MachineInstrBuilder &addRegOffset(const MachineInstrBuilder &MIB, 73 unsigned Reg, int Offset) { 74 return MIB.addReg(Reg).addImm(1).addReg(0).addImm(Offset); 75} 76 77/// addRegReg - This function is used to add a memory reference of the form: 78/// [Reg + Reg]. 79inline const MachineInstrBuilder &addRegReg(const MachineInstrBuilder &MIB, 80 unsigned Reg1, unsigned Reg2) { 81 return MIB.addReg(Reg1).addImm(1).addReg(Reg2).addImm(0); 82} 83 84inline const MachineInstrBuilder &addFullAddress(const MachineInstrBuilder &MIB, 85 const X86AddressMode &AM) { 86 assert (AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8); 87 88 if (AM.BaseType == X86AddressMode::RegBase) 89 MIB.addReg(AM.Base.Reg); 90 else if (AM.BaseType == X86AddressMode::FrameIndexBase) 91 MIB.addFrameIndex(AM.Base.FrameIndex); 92 else 93 assert (0); 94 MIB.addImm(AM.Scale).addReg(AM.IndexReg); 95 if (AM.GV) 96 return MIB.addGlobalAddress(AM.GV, AM.Disp); 97 else 98 return MIB.addImm(AM.Disp); 99} 100 101/// addFrameReference - This function is used to add a reference to the base of 102/// an abstract object on the stack frame of the current function. This 103/// reference has base register as the FrameIndex offset until it is resolved. 104/// This allows a constant offset to be specified as well... 105/// 106inline const MachineInstrBuilder & 107addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset = 0) { 108 return MIB.addFrameIndex(FI).addImm(1).addReg(0).addImm(Offset); 109} 110 111/// addConstantPoolReference - This function is used to add a reference to the 112/// base of a constant value spilled to the per-function constant pool. The 113/// reference has base register ConstantPoolIndex offset which is retained until 114/// either machine code emission or assembly output. This allows an optional 115/// offset to be added as well. 116/// 117inline const MachineInstrBuilder & 118addConstantPoolReference(const MachineInstrBuilder &MIB, unsigned CPI, 119 int Offset = 0) { 120 return MIB.addConstantPoolIndex(CPI).addImm(1).addReg(0).addImm(Offset); 121} 122 123} // End llvm namespace 124 125#endif 126