1 /* $Id: BPatch_memoryAccess_NP.h,v 1.11 2002/09/23 21:47:10 gaburici Exp $ */
3 #ifndef _MemoryAccess_h_
4 #define _MemoryAccess_h_
7 #include <BPatch_point.h>
9 /* Pseudoregisters definitions */
10 #define POWER_XER2531 9999
12 #define IA32_EMULATE 1000
13 #define IA32_ESCAS 1000
14 #define IA32_NESCAS 1001
15 #define IA32_ECMPS 1002
16 #define IA32_NECMPS 1003
18 #define IA32prefetchNTA 0
19 #define IA32prefetchT0 1
20 #define IA32prefetchT1 2
21 #define IA32prefetchT2 3
22 #define IA32AMDprefetch 100
23 #define IA32AMDprefetchw 101
26 /* This is believed to be machine independent, modulo register numbers of course */
27 struct BPATCH_DLL_EXPORT BPatch_addrSpec_NP
29 // the formula is regs[0] + 2 ^ scale * regs[1] + imm
32 int regs[2]; // registers: -1 means none, 0 is 1st, 1 is 2nd and so on
33 // some pseudoregisters may be used, see the documentation
36 BPatch_addrSpec_NP(int _imm, int _ra = -1, int _rb = -1, int _scale = 0)
37 : imm(_imm), scale(_scale)
43 BPatch_addrSpec_NP() : imm(0), scale(0)
49 int getImm() const { return imm; }
50 int getScale() const { return scale; }
51 int getReg(unsigned i) const { return regs[i]; }
53 bool equals(const BPatch_addrSpec_NP& ar) const
57 (scale == ar.scale) &&
58 (regs[0] == ar.regs[0]) &&
59 (regs[1] == ar.regs[1]);
63 #define BPatch_countSpec_NP BPatch_addrSpec_NP // right now it has the same form
65 class BPatch_memoryAccess;
66 extern void initOpCodeInfo();
69 class BPATCH_DLL_EXPORT BPatch_memoryAccess
71 friend class BPatch_function;
73 friend class InstrucIter;
76 // maximum number of memory accesses per instruction; platform dependent
77 #if defined(i386_unknown_nt4_0)
78 // Translation from C++ to VC++ 6.0
81 #if defined(i386_unknown_linux2_0)
82 static const unsigned int nmaxacc_NP = 2;
84 static const unsigned int nmaxacc_NP = 1;
88 // Utility function to filter out the points that don't have a 2nd memory access on x86
89 static BPatch_Vector<BPatch_point*>* filterPoints(const BPatch_Vector<BPatch_point*> &points,
94 bool isLoad[nmaxacc_NP];
95 bool isStore[nmaxacc_NP];
96 // VG(8/13/02): removed redundant isPrefetch fields; preFcn>=0 is the same thing
98 BPatch_addrSpec_NP start[nmaxacc_NP];
99 BPatch_countSpec_NP count[nmaxacc_NP];
100 int preFcn[nmaxacc_NP]; // prefetch function (-1 = none)
101 int condition[nmaxacc_NP]; // -1 means no condition, all other values are machine specific
102 // conditions, currently (8/13/02) the tttn field on x86
103 bool nonTemporal[nmaxacc_NP]; // non-temporal (cache non-polluting) write on x86
106 bool hasALoad() const { return nacc == 1 ? isLoad[0] : (isLoad[0] || isLoad[1]); }
107 bool hasAStore() const { return nacc == 1 ? isStore[0] : (isStore[0] || isStore[1]); }
108 bool hasAPrefetch() const { return preFcn[0] >= 0; }
109 int prefetchType(int which = 0) { return preFcn[which]; }
111 BPatch_addrSpec_NP getStartAddr(int which = 0) const { return start[which]; }
112 BPatch_countSpec_NP getByteCount(int which = 0) const { return count[which]; }
115 // initializes only the first access - general case
116 void set1st(bool _isLoad, bool _isStore,
117 int _imm_s, int _ra_s, int _rb_s, unsigned int _scale_s,
118 int _imm_c, int _ra_c, int _rb_c, unsigned int _scale_c,
119 int _preFcn, int _cond, bool _nt)
123 isStore[0] = _isStore;
124 start[0] = BPatch_addrSpec_NP(_imm_s, _ra_s, _rb_s, _scale_s);
125 count[0] = BPatch_countSpec_NP(_imm_c, _ra_c, _rb_c, _scale_c);
127 condition[0] = _cond;
128 nonTemporal[0] = _nt;
131 // initializes only the first access - no scale for count
132 void set1st(bool _isLoad, bool _isStore,
133 int _imm_s, int _ra_s, int _rb_s,
134 int _imm_c, int _ra_c = -1, int _rb_c = -1,
135 unsigned int _scale_s = 0, int _preFcn = -1,
136 int _cond = -1, bool _nt = false)
140 isStore[0] = _isStore;
141 start[0] = BPatch_addrSpec_NP(_imm_s, _ra_s, _rb_s, _scale_s);
142 count[0] = BPatch_countSpec_NP(_imm_c, _ra_c, _rb_c);
144 condition[0] = _cond;
145 nonTemporal[0] = _nt;
149 static BPatch_memoryAccess* const none;
151 static BPatch_memoryAccess* init_tables()
157 // initializes only the first access; #bytes is a constant
158 BPatch_memoryAccess(bool _isLoad, bool _isStore, unsigned int _bytes,
159 int _imm, int _ra, int _rb, unsigned int _scale = 0,
160 int _cond = -1, bool _nt = false)
162 set1st(_isLoad, _isStore, _imm, _ra, _rb, _bytes, -1, -1, _scale, -1, _cond, _nt);
165 // initializes only the first access; #bytes is an expression w/scale
166 BPatch_memoryAccess(bool _isLoad, bool _isStore,
167 int _imm_s, int _ra_s, int _rb_s, unsigned int _scale_s,
168 int _imm_c, int _ra_c, int _rb_c, unsigned int _scale_c,
169 int _cond, bool _nt, int _preFcn = -1)
171 set1st(_isLoad, _isStore,
172 _imm_s, _ra_s, _rb_s, _scale_s,
173 _imm_c, _ra_c, _rb_c, _scale_c,
174 _preFcn, _cond, _nt);
177 // initializes only the first access; #bytes is an expression
178 BPatch_memoryAccess(bool _isLoad, bool _isStore, bool _isPrefetch,
179 int _imm_s, int _ra_s, int _rb_s,
180 int _imm_c, int _ra_c, int _rb_c,
181 unsigned short _preFcn)
183 assert(_isPrefetch); // VG(8/13/02): historical reasons...
184 set1st(_isLoad, _isStore, _imm_s, _ra_s, _rb_s, _imm_c, _ra_c, _rb_c, 0, _preFcn);
187 // initializes only the first access; #bytes is an expression & not a prefetch
188 BPatch_memoryAccess(bool _isLoad, bool _isStore,
189 int _imm_s, int _ra_s, int _rb_s,
190 int _imm_c, int _ra_c, int _rb_c)
192 set1st(_isLoad, _isStore, _imm_s, _ra_s, _rb_s, _imm_c, _ra_c, _rb_c);
195 // sets 2nd access; #bytes is constant
196 void set2nd(bool _isLoad, bool _isStore, unsigned int _bytes,
197 int _imm, int _ra, int _rb, unsigned int _scale = 0)
203 isStore[1] = _isStore;
204 start[1] = BPatch_addrSpec_NP(_imm, _ra, _rb, _scale);
205 count[1] = BPatch_countSpec_NP(_bytes);
208 nonTemporal[1] = false;
211 // sets 2nd access; #bytes is an expression w/scale
212 void set2nd(bool _isLoad, bool _isStore,
213 int _imm_s, int _ra_s, int _rb_s, unsigned int _scale_s,
214 int _imm_c, int _ra_c, int _rb_c, unsigned int _scale_c,
221 isStore[1] = _isStore;
222 start[1] = BPatch_addrSpec_NP(_imm_s, _ra_s, _rb_s, _scale_s);
223 count[1] = BPatch_countSpec_NP(_imm_c, _ra_c, _rb_c, _scale_c);
225 condition[1] = _cond;
226 nonTemporal[1] = _nt;
230 // initializes both accesses; #bytes is a constant
231 BPatch_memoryAccess(bool _isLoad, bool _isStore, unsigned int _bytes,
232 int _imm, int _ra, int _rb, unsigned int _scale,
233 bool _isLoad2, bool _isStore2, unsigned int _bytes2,
234 int _imm2, int _ra2, int _rb2, unsigned int _scale2)
236 set1st(_isLoad, _isStore, _imm, _ra, _rb, _bytes, -1, -1, _scale);
237 set2nd(_isLoad2, _isStore2, _bytes2, _imm2, _ra2, _rb2, _scale2);
240 // initializes both accesses; #bytes is an expression & not a prefetch
241 BPatch_memoryAccess(bool _isLoad, bool _isStore,
242 int _imm_s, int _ra_s, int _rb_s, unsigned int _scale_s,
243 int _imm_c, int _ra_c, int _rb_c, unsigned int _scale_c,
244 bool _isLoad2, bool _isStore2,
245 int _imm2_s, int _ra2_s, int _rb2_s, unsigned int _scale2_s,
246 int _imm2_c, int _ra2_c, int _rb2_c, unsigned int _scale2_c)
248 set1st(_isLoad, _isStore,
249 _imm_s, _ra_s, _rb_s, _scale_s,
250 _imm_c, _ra_c, _rb_c, _scale_c,
252 set2nd(_isLoad2, _isStore2,
253 _imm2_s, _ra2_s, _rb2_s, _scale2_s,
254 _imm2_c, _ra2_c, _rb2_c, _scale2_c,
259 bool equals(const BPatch_memoryAccess* mp) const { return mp ? equals(*mp) : false; }
261 bool equals(const BPatch_memoryAccess& rp) const
263 bool res = nacc == rp.nacc;
268 for(unsigned int i=0; i<nacc; ++i) {
270 (isLoad[i] == rp.isLoad[i]) &&
271 (isStore[i] == rp.isStore[i]) &&
272 (start[i].equals(rp.start[i])) &&
273 (count[i].equals(rp.count[i])) &&
274 (preFcn[i] == rp.preFcn[i]) &&
275 (condition[i] == rp.condition[i]) &&
276 (nonTemporal[i] == rp.nonTemporal[i]);
284 unsigned int getNumberOfAccesses() const { return nacc; }
285 BPatch_addrSpec_NP getStartAddr_NP(int which = 0) const { return start[which]; }
286 BPatch_countSpec_NP getByteCount_NP(int which = 0) const { return count[which]; }
287 bool isALoad_NP(int which = 0) const { return isLoad[which]; }
288 bool isAStore_NP(int which = 0) const { return isStore[which]; }
289 bool isAPrefetch_NP(int which = 0) const { return preFcn[which] >= 0; }
290 bool isConditional_NP(int which = 0) const { return condition[which] >= 0; }
291 bool isNonTemporal_NP(int which = 0) const { return nonTemporal[which]; }
292 int prefetchType_NP(int which = 0) const { return preFcn[which]; }
293 int conditionCode_NP(int which = 0) const { return condition[which]; }