Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / src / emit-x86.h
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 /*
33  * emit-x86.h - x86 & AMD64 code generators
34  * $Id: emit-x86.h,v 1.32 2008/09/11 20:14:14 mlam Exp $
35  */
36
37 #ifndef _EMIT_X86_H
38 #define _EMIT_X86_H
39
40 #include "common/h/headers.h"
41 #include "dyninstAPI/src/instPoint.h"
42 #include "dyninstAPI/src/arch-x86.h"
43 #include "dyninstAPI/src/baseTramp.h"
44
45 #include "dyninstAPI/src/emitter.h"
46 class codeGen;
47 class registerSpace;
48
49 class registerSlot;
50
51 // Emitter moved to emitter.h - useful on other platforms as well
52
53 // 32-bit class declared here since its implementation is in both inst-x86.C and emit-x86.C
54 class EmitterIA32 : public Emitter {
55
56 public:
57     virtual ~EmitterIA32() {};
58     static const int mt_offset;
59     codeBufIndex_t emitIf(Register expr_reg, Register target, RegControl rc, codeGen &gen);
60     void emitOp(unsigned opcode, Register dest, Register src1, Register src2, codeGen &gen);
61     void emitRelOp(unsigned op, Register dest, Register src1, Register src2, codeGen &gen);
62     void emitDiv(Register dest, Register src1, Register src2, codeGen &gen);
63     void emitOpImm(unsigned opcode1, unsigned opcode2, Register dest, Register src1, RegValue src2imm,
64                            codeGen &gen);
65     void emitRelOpImm(unsigned op, Register dest, Register src1, RegValue src2imm, codeGen &gen);
66     void emitTimesImm(Register dest, Register src1, RegValue src1imm, codeGen &gen);
67     void emitDivImm(Register dest, Register src1, RegValue src1imm, codeGen &gen);
68     void emitLoad(Register dest, Address addr, int size, codeGen &gen);
69     void emitLoadConst(Register dest, Address imm, codeGen &gen);
70     void emitLoadIndir(Register dest, Register addr_reg, int size, codeGen &gen);
71     bool emitLoadRelative(Register dest, Address offset, Register base, codeGen &gen);
72     bool emitLoadRelative(registerSlot* /*dest*/, Address /*offset*/, registerSlot* /*base*/, codeGen &/*gen*/) { assert(0); return true; }
73     void emitLoadShared(opCode op, Register dest, const image_variable *var, bool is_local,int size, codeGen &gen, Address offset);
74     void emitLoadFrameAddr(Register dest, Address offset, codeGen &gen);
75     void emitLoadOrigFrameRelative(Register dest, Address offset, codeGen &gen);
76     void emitLoadOrigRegRelative(Register dest, Address offset, Register base, codeGen &gen, bool store);
77     void emitLoadOrigRegister(Address register_num, Register dest, codeGen &gen);
78
79     void emitStoreOrigRegister(Address register_num, Register dest, codeGen &gen);
80
81     void emitStore(Address addr, Register src, int size, codeGen &gen);
82     void emitStoreIndir(Register addr_reg, Register src, int size, codeGen &gen);
83     void emitStoreFrameRelative(Address offset, Register src, Register scratch, int size, codeGen &gen);
84
85     void emitStoreRelative(Register source, Address offset, Register base, codeGen &gen);
86     void emitStoreRelative(registerSlot* /*source*/, Address /*offset*/, registerSlot* /*base*/, codeGen &/*gen*/) { assert(0); }
87
88     void emitStoreShared(Register source, const image_variable *var, bool is_local,int size, codeGen &gen);
89
90     bool clobberAllFuncCall(registerSpace *rs,int_function *callee);
91     void setFPSaveOrNot(const int * liveFPReg,bool saveOrNot);
92     // We can overload this for the stat/dyn case
93     virtual Register emitCall(opCode op, codeGen &gen,
94                               const pdvector<AstNodePtr> &operands,
95                               bool noCost, int_function *callee);
96     int emitCallParams(codeGen &gen, 
97                        const pdvector<AstNodePtr> &operands,
98                        int_function *target, 
99                        pdvector<Register> &extra_saves,
100                        bool noCost);
101     bool emitCallCleanup(codeGen &gen, int_function *target, 
102                          int frame_size, pdvector<Register> &extra_saves);
103     void emitGetRetVal(Register dest, bool addr_of, codeGen &gen);
104     void emitGetParam(Register dest, Register param_num, instPointType_t pt_type, bool addr_of, codeGen &gen);
105     void emitFuncJump(int_function *f, instPointType_t ptType, codeGen &gen);
106     void emitASload(int ra, int rb, int sc, long imm, Register dest, codeGen &gen);
107     void emitCSload(int ra, int rb, int sc, long imm, Register dest, codeGen &gen);
108     void emitPushFlags(codeGen &gen);
109     void emitRestoreFlags(codeGen &gen, unsigned offset);
110     void emitRestoreFlagsFromStackSlot(codeGen &gen);
111     bool emitBTSaves(baseTramp* bt, baseTrampInstance *, codeGen &gen);
112     bool emitBTRestores(baseTramp* bt, baseTrampInstance *bti, codeGen &gen);
113     void emitLoadEffectiveAddress(Register base, Register index, unsigned int scale, int disp,
114                                   Register dest, codeGen &gen);
115     void emitStoreImm(Address addr, int imm, codeGen &gen, bool noCost);
116     void emitAddSignedImm(Address addr, int imm, codeGen &gen, bool noCost);
117     int Register_DWARFtoMachineEnc(int n);
118     bool emitPush(codeGen &gen, Register pushee);
119     bool emitPop(codeGen &gen, Register popee);
120
121     bool emitAdjustStackPointer(int index, codeGen &gen);
122
123     bool emitMoveRegToReg(Register src, Register dest, codeGen &gen);
124     bool emitMoveRegToReg(registerSlot* /*src*/, registerSlot* /*dest*/, codeGen& /*gen*/) { assert(0); return true; }
125
126
127  protected:
128     virtual bool emitCallInstruction(codeGen &gen, int_function *target, Register ret) = 0;
129
130 };
131
132 class EmitterIA32Dyn : public EmitterIA32 {
133  public:
134     ~EmitterIA32Dyn() {};
135     
136  protected:
137     bool emitCallInstruction(codeGen &gen, int_function *target, Register ret);
138 };
139
140 class EmitterIA32Stat : public EmitterIA32 {
141  public:
142
143     ~EmitterIA32Stat() {};
144     
145  protected:
146     bool emitCallInstruction(codeGen &gen, int_function *target, Register ret);
147 };
148
149 extern EmitterIA32Dyn emitterIA32Dyn;
150 extern EmitterIA32Stat emitterIA32Stat;
151
152
153 // some useful 64-bit codegen functions
154 void emitMovRegToReg64(Register dest, Register src, bool is_64, codeGen &gen);
155 void emitMovPCRMToReg64(Register dest, int offset, int size, codeGen &gen);
156 void emitMovImmToReg64(Register dest, long imm, bool is_64, codeGen &gen);
157 void emitLEA64(Register base, Register index, unsigned int scale, int disp, Register dest, bool is_64, codeGen &gen);
158 void emitPushReg64(Register src, codeGen &gen);
159 void emitPopReg64(Register dest, codeGen &gen);
160 void emitMovImmToRM64(Register base, int disp, int imm, codeGen &gen);
161 void emitAddMem64(Address addr, int imm, codeGen &gen);
162 void emitAddRM64(Address addr, int imm, codeGen &gen);
163
164 #if defined(arch_x86_64)
165 class EmitterAMD64 : public Emitter {
166
167 public:
168     virtual ~EmitterAMD64() {};
169     static const int mt_offset;
170     codeBufIndex_t emitIf(Register expr_reg, Register target, RegControl rc, codeGen &gen);
171     void emitOp(unsigned op, Register dest, Register src1, Register src2, codeGen &gen);
172     void emitRelOp(unsigned op, Register dest, Register src1, Register src2, codeGen &gen);
173     void emitDiv(Register dest, Register src1, Register src2, codeGen &gen);
174     void emitOpImm(unsigned opcode1, unsigned opcode2, Register dest, Register src1, RegValue src2imm,
175                            codeGen &gen);
176     void emitRelOpImm(unsigned op, Register dest, Register src1, RegValue src2imm, codeGen &gen);
177     void emitTimesImm(Register dest, Register src1, RegValue src1imm, codeGen &gen);
178     void emitDivImm(Register dest, Register src1, RegValue src1imm, codeGen &gen);
179     void emitLoad(Register dest, Address addr, int size, codeGen &gen);
180     void emitLoadConst(Register dest, Address imm, codeGen &gen);
181     void emitLoadIndir(Register dest, Register addr_reg, int size, codeGen &gen);
182     bool emitLoadRelative(Register dest, Address offset, Register base, codeGen &gen);
183     bool emitLoadRelative(registerSlot *dest, Address offset, registerSlot *base, codeGen &gen);
184     void emitLoadFrameAddr(Register dest, Address offset, codeGen &gen);
185
186     void emitLoadOrigFrameRelative(Register dest, Address offset, codeGen &gen);
187     void emitLoadOrigRegRelative(Register dest, Address offset, Register base, codeGen &gen, bool store);
188     void emitLoadOrigRegister(Address register_num, Register dest, codeGen &gen);
189     void emitLoadShared(opCode op, Register dest, const image_variable *var, bool is_local,int size, codeGen &gen, Address offset);
190
191     void emitStoreOrigRegister(Address register_num, Register dest, codeGen &gen);
192
193     void emitStore(Address addr, Register src, int size, codeGen &gen);
194     void emitStoreIndir(Register addr_reg, Register src, int size, codeGen &gen);
195     void emitStoreFrameRelative(Address offset, Register src, Register scratch, int size, codeGen &gen);
196     void emitStoreRelative(Register source, Address offset, Register base, codeGen &gen);
197
198     void emitStoreRelative(registerSlot *source, Address offset, registerSlot *base, codeGen &gen);
199     void emitStoreShared(Register source, const image_variable *var, bool is_local,int size, codeGen &gen);
200
201     bool clobberAllFuncCall(registerSpace *rs, int_function *callee);
202     void setFPSaveOrNot(const int * liveFPReg,bool saveOrNot);
203     // See comment on 32-bit emitCall
204     virtual Register emitCall(opCode op, codeGen &gen,
205                               const pdvector<AstNodePtr> &operands,
206                               bool noCost, int_function *callee);
207     void emitGetRetVal(Register dest, bool addr_of, codeGen &gen);
208     void emitGetParam(Register dest, Register param_num, instPointType_t pt_type, bool addr_of, codeGen &gen);
209     void emitFuncJump(int_function *f, instPointType_t ptType, codeGen &gen);
210     void emitASload(int ra, int rb, int sc, long imm, Register dest, codeGen &gen);
211     void emitCSload(int ra, int rb, int sc, long imm, Register dest, codeGen &gen);
212     void emitPushFlags(codeGen &gen);
213     void emitRestoreFlags(codeGen &gen, unsigned offset);
214     void emitRestoreFlagsFromStackSlot(codeGen &gen);
215     bool emitBTSaves(baseTramp* bt, baseTrampInstance *, codeGen &gen);
216     bool emitBTRestores(baseTramp* bt, baseTrampInstance *bti, codeGen &gen);
217     void emitStoreImm(Address addr, int imm, codeGen &gen, bool noCost);
218     void emitAddSignedImm(Address addr, int imm, codeGen &gen, bool noCost);
219     /* The DWARF register numbering does not correspond to the architecture's
220        register encoding for 64-bit target binaries *only*. This method
221        maps the number that DWARF reports for a register to the actual
222        register number. */
223     int Register_DWARFtoMachineEnc(int n);
224     bool emitPush(codeGen &gen, Register pushee);
225     bool emitPop(codeGen &gen, Register popee);
226
227     bool emitAdjustStackPointer(int index, codeGen &gen);
228
229     bool emitMoveRegToReg(Register src, Register dest, codeGen &gen);
230     bool emitMoveRegToReg(registerSlot *src, registerSlot *dest, codeGen &gen);
231
232  protected:
233     virtual bool emitCallInstruction(codeGen &gen, int_function *target, Register ret) = 0;
234
235 };
236
237 class EmitterAMD64Dyn : public EmitterAMD64 {
238  public:
239     ~EmitterAMD64Dyn() {}
240
241     bool emitCallInstruction(codeGen &gen, int_function *target, Register ret);
242 };
243
244 class EmitterAMD64Stat : public EmitterAMD64 {
245  public:
246     ~EmitterAMD64Stat() {};
247     
248     bool emitCallInstruction(codeGen &gen, int_function *target, Register ret);
249 };
250
251 extern EmitterAMD64Dyn emitterAMD64Dyn;
252 extern EmitterAMD64Stat emitterAMD64Stat;
253
254 /* useful functions for inter-library function/variable references
255  * (used in the binary rewriter) */
256 Address getInterModuleFuncAddr(int_function *func, codeGen& gen);
257 Address getInterModuleVarAddr(const image_variable *var, codeGen& gen);
258
259 #endif
260
261 #endif