initial dyninstAPI commit for code coverage
[dyninst.git] / dyninstAPI / src / arch-sparc.h
1 /*
2  * Copyright (c) 1996 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  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: arch-sparc.h,v 1.27 2001/09/07 21:15:07 tikir Exp $
43
44 #if !defined(sparc_sun_sunos4_1_3) && !defined(sparc_sun_solaris2_4)
45 #error "invalid architecture-os inclusion"
46 #endif
47
48 #ifndef _ARCH_SPARC_H
49 #define _ARCH_SPARC_H
50
51 /*
52  * Define sparc instruction information.
53  *
54  */
55 struct fmt1 {
56     unsigned op:2;
57     signed disp30:30;
58 };
59
60 struct fmt2 {
61     unsigned op:2;
62     unsigned anneal:1;
63     unsigned cond:4;
64     unsigned op2:3;
65     signed disp22:22;
66 };
67
68 struct fmt2a {
69     unsigned op:2;
70     unsigned rd:5;
71     unsigned op2:3;
72     signed imm22:22;
73 };
74
75 struct fmt3 {
76     unsigned op:2;
77     unsigned rd:5;
78     unsigned op3:6;
79     unsigned rs1:5;
80     unsigned i:1;
81     unsigned unused:8;
82     unsigned rs2:5;
83 };
84
85 struct fmt3ix {
86     unsigned op:2;
87     unsigned rd:5;
88     unsigned op3:6;
89     unsigned rs1:5;
90     unsigned i:1;
91     unsigned x:1;
92     unsigned unused:7;
93     unsigned rs2:5;
94 };
95
96 struct fmt3i {
97     unsigned op:2;
98     unsigned rd:5;
99     unsigned op3:6;
100     unsigned rs1:5;
101     unsigned i:1;
102     signed simm13:13;
103 };
104
105 union instructUnion {
106     struct fmt1 call;
107     struct fmt2 branch;
108     struct fmt2a sethi;
109     struct fmt3 rest;
110     struct fmt3i resti;
111     struct fmt3ix restix;
112     unsigned int raw;
113 };
114
115 typedef union instructUnion instruction;
116
117
118 /*
119  * Define the operation codes
120  *
121  */
122 #define SetCC           16
123 #define ADDop3          0
124 #define ADDop3cc        16
125 #define ANDop3          1
126 #define ANDop3cc        17
127 #define ANDNop3cc       21
128 #define ORop3           2
129 #define SUBop3          4
130 #define SUBop3cc        SetCC|SUBop3
131 #define SMULop3         11
132 #define SDIVop3         15
133 #define WRYop3          48      //SDIV needs to set Y register to 0
134 #define RDYop3          40
135 #define XNORop3         SetCC|7
136 #define SAVEop3         60
137 #define RESTOREop3      61
138 #define JMPLop3         56
139
140 #define SLLop3          37
141 #define SLLop           2
142 #define SRLop3          38
143 #define SRLop           2
144
145 #define FP_OP3_LOW      0x20
146 #define LDFop3          0x20
147 #define LDFSRop3        0x21
148 #define LDDFop3         0x23
149 #define STFop3          0x24
150 #define STFSRop3        0x25
151 #define STDFQop3        0x26
152 #define STDFop3         0x27
153 #define FP_OP3_HIGH     0x27
154
155 #define FP_OP2_FPop1    0x34
156 #define FP_OP2_FPop2    0x35
157
158 /* op = 11 */
159 #define LDSTop  3
160 #define STop    3
161 #define LDop3   0
162 #define STop3   4
163 #define LDDop3  3
164 #define STDop3  7
165 #define SWAPop  3
166 #define SWAPop3 15 
167
168 #define FLUSHWop3 43
169
170 /* mask bits for various parts of the instruction format */
171 #define OPmask          0xc0000000
172 #define OP2mask         0x01c00000
173 #define OP3mask         0x01f80000
174 #define RDmask          0x3e000000
175
176 #define DISP30mask      0x3fffffff
177
178 /* op = 01 -- mask for and match for call instruction */
179 #define CALLop          1
180 #define CALLmask        OPmask
181 #define CALLmatch       0x40000000
182
183 /* (op==10) && (op3 == 111000) 
184  */
185 #define RESTop          2
186 #define JMPLmask        (OPmask|OP3mask)
187 #define JMPLmatch       0x81c00000
188
189 #define FMT2op          0
190 #define LOADop          3
191
192 /*
193  * added this on 8/18 (jkh) to tell a jmpl from a call indirect.
194  *
195  */
196 #define CALLImask       (OPmask|RDmask|OP3mask)
197 #define CALLImatch      0x9fc00000
198
199 /* (op=10) && (op3==111001) trap instructions */
200 #define TRAPmask        (OPmask|OP3mask)
201 #define TRAPmatch       0x81d00000
202
203 /* (op == 00) && (op2 ^ 2) mask for conditional branching instructions */
204 #define BICCop2         2
205
206 #define BEcond          1
207 #define BLEcond         2
208 #define BLTcond         3
209 #define BGTcond        10
210 #define BGEcond        11
211 #define BAcond          8
212 #define BNEcond         9
213
214 #define BRNCHmask       (OPmask|OP2mask)
215 #define BRNCHmatch      0x1<<23
216
217 #define FBRNCHmask      (OPmask|OP2mask)
218 #define FBRNCHmatch     0x3<<23
219
220 /* really jmpl %i7+8,%g0 */
221 /* changed this to jmpl %i7+??,%g0 since g++ sometimes returns +0xc not +0x8 
222  * jkh - 7/12/93
223  */
224 #define RETmask         0xfffff000
225 #define RETmatch        0x81c7e000
226
227 /* retl - leaf return really jmpl %o7+8,%g0 */
228 /* changed this to jmpl %i7+??,%g0 since g++ sometimes returns +0xc not +0x8
229  * jkh - 7/12/93
230  */
231 #define RETLmask        0xfffff000
232 #define RETLmatch       0x81c3e000
233
234
235 #define SAVEmask        (OPmask|OP3mask)
236 #define SAVEmatch       0x81e00000
237
238 #define RESTOREmask     (OPmask|OP3mask)
239 #define RESTOREmatch    0x81e80000
240
241 /* noop insn */
242 #define NOOPop2         4
243 #define SETHIop2        4
244
245 /* If these bits are non-zero an op2 instruction is a non-annuled branch */
246 #define ANNUL_BIT       0x40000000
247
248 #define BREAK_POINT_INSN 0x91d02001   /* ta 1 */
249 #define SPILL_REGISTERS_INSN 0x91d02003 /*ta 3*/
250
251
252 inline bool isInsnType(const instruction i,
253                        const unsigned mask,
254                        const unsigned match) {
255   return ((i.raw & mask) == match);
256 }
257
258 /*
259    Return boolean value specifying whether instruction is NOP....
260  */
261 inline bool isNopInsn(const instruction i) {
262     if (i.sethi.op == 0 && i.sethi.op2 == 0x4) {
263         return true;
264     }
265     return false;
266 }
267
268 inline bool isCallInsn(const instruction i) {
269   return (isInsnType(i, CALLmask, CALLmatch) ||
270           isInsnType(i, CALLImask, CALLImatch));
271 }
272
273 //  is instruction i a "true" call?
274 //  2 types of call insn in sparc:
275 //    true call - call to fixed address (really pc rel addr, but disass will show
276 //     fixed addr - for your convenience)....
277 //    jmpl (jump & link) - call to register | register + const |
278 //       register + register, and stick return address in some 
279 //       register.  If dest register is 07, a disassembler should
280 //       show a "call" insn.
281 inline bool isTrueCallInsn(const instruction i) {
282     return (i.call.op == 0x1);
283 }
284
285 inline bool isJmplCallInsn(const instruction i) {
286     // condition for jmpl insn
287     if (i.resti.op == 0x2 && i.resti.op3 == 0x38) {
288         // condition for dest register == 07
289         if (i.resti.rd == 15) {
290             return true;
291         }
292     }
293     return false;
294 }
295
296 inline bool isJmplInsn(const instruction i){
297   if (i.resti.op == 0x2 && i.resti.op3 == 0x38)
298     return true;
299   return false;
300 }
301
302 inline bool isCondBranch(const instruction i){
303      if (i.branch.op == 0 && (i.branch.op2 == 2 || i.branch.op2 == 6)) {
304          if ((i.branch.cond != 0) && (i.branch.cond != 8))  
305              return true;
306      }
307      return false;
308 }
309
310 inline bool IS_DELAYED_INST(const instruction insn) {
311   return (insn.call.op == CALLop ||
312           isInsnType(insn, JMPLmask, JMPLmatch) ||
313           isInsnType(insn, FBRNCHmask, FBRNCHmatch) ||
314           isInsnType(insn, BRNCHmask, BRNCHmatch));
315 }
316
317 /* catch small ints that are invalid instructions */
318 /*
319  * insn.call.op checks for CALL or Format 3 insns
320  * op2 == {2,4,6,7} checks for valid format 2 instructions.
321  *    See SPARC Arch manual v8 p. 44.
322  *
323  */
324 inline bool IS_VALID_INSN(const instruction insn) {
325   return ((insn.call.op) || ((insn.branch.op2 == 2) ||
326                              (insn.branch.op2 == 4) ||
327                              (insn.branch.op2 == 6) ||
328                              (insn.branch.op2 == 7)));
329 }
330
331 /* addresses on sparc are aligned to word boundaries */
332 inline bool isAligned(const Address addr) { return !(addr & 0x3); }
333
334 int get_disp(instruction *insn);
335 int set_disp(bool setDisp, instruction *insn, int newOffset, bool outOfFunc);
336 int sizeOfMachineInsn(instruction *insn);
337 int addressOfMachineInsn(instruction *insn);
338
339 #define region_lo(x) ( (x > (0x1 << 23))? (x-(0x1 << 23)):0x0 )
340 #define region_hi(x) ( (x > (-1UL - (1<<23))) ? -1UL : (x + (0x1 << 23)))
341
342 class InsnRegister {
343 public:
344         enum RegisterType {GlobalIntReg=0,FloatReg,CoProcReg,SpecialReg,None};
345
346         InsnRegister();
347         InsnRegister(char isD,RegisterType rt,unsigned short rn);
348         void setWordCount(char isD);
349         void setType(RegisterType rt);
350         void setNumber(short rn);
351         bool is_o7();
352         void print();
353
354 private:
355         char wordCount;
356         RegisterType regType;
357         short regNumber;
358 };
359
360 void get_register_operands(const instruction&,
361                            InsnRegister*,InsnRegister*,InsnRegister*);
362
363 #endif