~ubuntu-branches/ubuntu/quantal/llvm-3.1/quantal

« back to all changes in this revision

Viewing changes to lib/Target/X86/X86InstrBuilder.h

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2012-03-29 19:09:51 UTC
  • Revision ID: package-import@ubuntu.com-20120329190951-aq83ivog4cg8bxun
Tags: upstream-3.1~svn153643
ImportĀ upstreamĀ versionĀ 3.1~svn153643

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===-- X86InstrBuilder.h - Functions to aid building x86 insts -*- C++ -*-===//
 
2
//
 
3
//                     The LLVM Compiler Infrastructure
 
4
//
 
5
// This file is distributed under the University of Illinois Open Source
 
6
// 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/MachineFrameInfo.h"
 
28
#include "llvm/CodeGen/MachineInstrBuilder.h"
 
29
#include "llvm/CodeGen/MachineMemOperand.h"
 
30
 
 
31
namespace llvm {
 
32
 
 
33
/// X86AddressMode - This struct holds a generalized full x86 address mode.
 
34
/// The base register can be a frame index, which will eventually be replaced
 
35
/// with BP or SP and Disp being offsetted accordingly.  The displacement may
 
36
/// also include the offset of a global value.
 
37
struct X86AddressMode {
 
38
  enum {
 
39
    RegBase,
 
40
    FrameIndexBase
 
41
  } BaseType;
 
42
 
 
43
  union {
 
44
    unsigned Reg;
 
45
    int FrameIndex;
 
46
  } Base;
 
47
 
 
48
  unsigned Scale;
 
49
  unsigned IndexReg;
 
50
  int Disp;
 
51
  const GlobalValue *GV;
 
52
  unsigned GVOpFlags;
 
53
 
 
54
  X86AddressMode()
 
55
    : BaseType(RegBase), Scale(1), IndexReg(0), Disp(0), GV(0), GVOpFlags(0) {
 
56
    Base.Reg = 0;
 
57
  }
 
58
  
 
59
  
 
60
  void getFullAddress(SmallVectorImpl<MachineOperand> &MO) {
 
61
    assert(Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8);
 
62
    
 
63
    if (BaseType == X86AddressMode::RegBase)
 
64
      MO.push_back(MachineOperand::CreateReg(Base.Reg, false, false,
 
65
                                             false, false, false, 0, false));
 
66
    else {
 
67
      assert(BaseType == X86AddressMode::FrameIndexBase);
 
68
      MO.push_back(MachineOperand::CreateFI(Base.FrameIndex));
 
69
    }
 
70
    
 
71
    MO.push_back(MachineOperand::CreateImm(Scale));
 
72
    MO.push_back(MachineOperand::CreateReg(IndexReg, false, false,
 
73
                                           false, false, false, 0, false));
 
74
    
 
75
    if (GV)
 
76
      MO.push_back(MachineOperand::CreateGA(GV, Disp, GVOpFlags));
 
77
    else
 
78
      MO.push_back(MachineOperand::CreateImm(Disp));
 
79
    
 
80
    MO.push_back(MachineOperand::CreateReg(0, false, false,
 
81
                                           false, false, false, 0, false));
 
82
  }
 
83
};
 
84
 
 
85
/// addDirectMem - This function is used to add a direct memory reference to the
 
86
/// current instruction -- that is, a dereference of an address in a register,
 
87
/// with no scale, index or displacement. An example is: DWORD PTR [EAX].
 
88
///
 
89
static inline const MachineInstrBuilder &
 
90
addDirectMem(const MachineInstrBuilder &MIB, unsigned Reg) {
 
91
  // Because memory references are always represented with five
 
92
  // values, this adds: Reg, 1, NoReg, 0, NoReg to the instruction.
 
93
  return MIB.addReg(Reg).addImm(1).addReg(0).addImm(0).addReg(0);
 
94
}
 
95
 
 
96
 
 
97
static inline const MachineInstrBuilder &
 
98
addOffset(const MachineInstrBuilder &MIB, int Offset) {
 
99
  return MIB.addImm(1).addReg(0).addImm(Offset).addReg(0);
 
100
}
 
101
 
 
102
/// addRegOffset - This function is used to add a memory reference of the form
 
103
/// [Reg + Offset], i.e., one with no scale or index, but with a
 
104
/// displacement. An example is: DWORD PTR [EAX + 4].
 
105
///
 
106
static inline const MachineInstrBuilder &
 
107
addRegOffset(const MachineInstrBuilder &MIB,
 
108
             unsigned Reg, bool isKill, int Offset) {
 
109
  return addOffset(MIB.addReg(Reg, getKillRegState(isKill)), Offset);
 
110
}
 
111
 
 
112
/// addRegReg - This function is used to add a memory reference of the form:
 
113
/// [Reg + Reg].
 
114
static inline const MachineInstrBuilder &addRegReg(const MachineInstrBuilder &MIB,
 
115
                                            unsigned Reg1, bool isKill1,
 
116
                                            unsigned Reg2, bool isKill2) {
 
117
  return MIB.addReg(Reg1, getKillRegState(isKill1)).addImm(1)
 
118
    .addReg(Reg2, getKillRegState(isKill2)).addImm(0).addReg(0);
 
119
}
 
120
 
 
121
static inline const MachineInstrBuilder &
 
122
addFullAddress(const MachineInstrBuilder &MIB,
 
123
               const X86AddressMode &AM) {
 
124
  assert(AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8);
 
125
  
 
126
  if (AM.BaseType == X86AddressMode::RegBase)
 
127
    MIB.addReg(AM.Base.Reg);
 
128
  else {
 
129
    assert(AM.BaseType == X86AddressMode::FrameIndexBase);
 
130
    MIB.addFrameIndex(AM.Base.FrameIndex);
 
131
  }
 
132
 
 
133
  MIB.addImm(AM.Scale).addReg(AM.IndexReg);
 
134
  if (AM.GV)
 
135
    MIB.addGlobalAddress(AM.GV, AM.Disp, AM.GVOpFlags);
 
136
  else
 
137
    MIB.addImm(AM.Disp);
 
138
    
 
139
  return MIB.addReg(0);
 
140
}
 
141
 
 
142
/// addFrameReference - This function is used to add a reference to the base of
 
143
/// an abstract object on the stack frame of the current function.  This
 
144
/// reference has base register as the FrameIndex offset until it is resolved.
 
145
/// This allows a constant offset to be specified as well...
 
146
///
 
147
static inline const MachineInstrBuilder &
 
148
addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset = 0) {
 
149
  MachineInstr *MI = MIB;
 
150
  MachineFunction &MF = *MI->getParent()->getParent();
 
151
  MachineFrameInfo &MFI = *MF.getFrameInfo();
 
152
  const MCInstrDesc &MCID = MI->getDesc();
 
153
  unsigned Flags = 0;
 
154
  if (MCID.mayLoad())
 
155
    Flags |= MachineMemOperand::MOLoad;
 
156
  if (MCID.mayStore())
 
157
    Flags |= MachineMemOperand::MOStore;
 
158
  MachineMemOperand *MMO =
 
159
    MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI, Offset),
 
160
                            Flags, MFI.getObjectSize(FI),
 
161
                            MFI.getObjectAlignment(FI));
 
162
  return addOffset(MIB.addFrameIndex(FI), Offset)
 
163
            .addMemOperand(MMO);
 
164
}
 
165
 
 
166
/// addConstantPoolReference - This function is used to add a reference to the
 
167
/// base of a constant value spilled to the per-function constant pool.  The
 
168
/// reference uses the abstract ConstantPoolIndex which is retained until
 
169
/// either machine code emission or assembly output. In PIC mode on x86-32,
 
170
/// the GlobalBaseReg parameter can be used to make this a
 
171
/// GlobalBaseReg-relative reference.
 
172
///
 
173
static inline const MachineInstrBuilder &
 
174
addConstantPoolReference(const MachineInstrBuilder &MIB, unsigned CPI,
 
175
                         unsigned GlobalBaseReg, unsigned char OpFlags) {
 
176
  //FIXME: factor this
 
177
  return MIB.addReg(GlobalBaseReg).addImm(1).addReg(0)
 
178
    .addConstantPoolIndex(CPI, 0, OpFlags).addReg(0);
 
179
}
 
180
 
 
181
} // End llvm namespace
 
182
 
 
183
#endif