Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / src / arch-sparc.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 // $Id: arch-sparc.h,v 1.56 2008/11/03 15:19:24 jaw Exp $
33
34 #include "common/h/Vector.h"
35 // TUGRUL
36 #include "Annotatable.h"
37
38 #if !defined(arch_sparc)
39 #error "invalid architecture-os inclusion"
40 #endif
41
42 #ifndef _ARCH_SPARC_H
43 #define _ARCH_SPARC_H
44
45 // Code generation
46
47 typedef unsigned int codeBuf_t;
48 typedef unsigned codeBufIndex_t;
49
50 class AddressSpace;
51
52 /*
53  * Define sparc instruction information.
54  *
55  */
56 struct fmt1 {
57     unsigned op:2;
58     signed disp30:30;
59 };
60
61 struct fmt2 {
62     unsigned op:2;
63     unsigned anneal:1; // VG: must read anull I guess...
64     unsigned cond:4;
65     unsigned op2:3;
66     signed disp22:22;
67 };
68
69 struct fmt2a {
70     unsigned op:2;
71     unsigned rd:5;
72     unsigned op2:3;
73     signed imm22:22;
74 };
75
76 struct fmt3 {
77     unsigned op:2;
78     unsigned rd:5;
79     unsigned op3:6;
80     unsigned rs1:5;
81     unsigned i:1;
82     unsigned unused:8;
83     unsigned rs2:5;
84 };
85
86 struct fmt3ix {
87     unsigned op:2;
88     unsigned rd:5;
89     unsigned op3:6;
90     unsigned rs1:5;
91     unsigned i:1;
92     unsigned x:1;
93     unsigned unused:7;
94     unsigned rs2:5;
95 };
96
97 struct fmt3i {
98     unsigned op:2;
99     unsigned rd:5;
100     unsigned op3:6;
101     unsigned rs1:5;
102     unsigned i:1;
103     signed simm13:13;
104 };
105
106 typedef union {
107     struct fmt1 call;
108     struct fmt2 branch;
109     struct fmt2a sethi;
110     struct fmt3 rest;
111     struct fmt3i resti;
112     struct fmt3ix restix;
113     unsigned int raw;
114 } instructUnion;
115
116 /* Address space identifiers */
117 #define ASI_PRIMARY 0x80
118 #define ASI_PRIMARY_NOFAULT 0x82
119
120 /*
121  * Define the operation codes
122  *
123  */
124 #define SetCC           16
125 #define ADDop3          0
126 #define ADDop3cc        16
127 #define ANDop3          1
128 #define ANDop3cc        17
129 #define ANDNop3cc       21
130 #define ORop3           2
131 #define SUBop3          4
132 #define SUBop3cc        SetCC|SUBop3
133 #define SMULop3         11
134 #define SDIVop3         15
135 #define WRYop3          48      //SDIV needs to set Y register to 0
136 #define RDYop3          40
137 #define XNORop3         SetCC|7
138 #define SAVEop3         60
139 #define RESTOREop3      61
140 #define JMPLop3         56
141
142 #define SLLop3          37
143 #define SLLop           2
144 #define SRLop3          38
145 #define SRLop           2
146
147 #define FP_OP3_LOW      0x20
148 #define LDFop3          0x20
149 #define LDFSRop3        0x21
150 #define LDDFop3         0x23
151 #define STFop3          0x24
152 #define STFSRop3        0x25
153 #define STDFQop3        0x26
154 #define STDFop3         0x27
155 #define FP_OP3_HIGH     0x27
156
157 #define FP_OP2_FPop1    0x34
158 #define FP_OP2_FPop2    0x35
159
160 /* op = 11 */
161 #define LDSTop  3
162 #define STop    3
163 #define LDop3   0
164 #define STop3   4
165 #define LDDop3  3
166 #define STDop3  7
167 #define LDUBop3 1
168 #define LDSBop3 9
169 #define STBop3 5
170 #define LDUHop3 2
171 #define LDSHop3 10
172 #define STHop3 6
173 #define SWAPop  3
174 #define SWAPop3 15 
175
176 #define FLUSHWop3 43
177
178 /* illegal instructions */
179 #define ILLTRAPop 0
180 #define ILLTRAPop2 = 0
181
182 /* mask bits for various parts of the instruction format */
183 #define OPmask          0xc0000000
184 #define OP2mask         0x01c00000
185 #define OP3mask         0x01f80000
186 #define RDmask          0x3e000000
187
188 #define DISP30mask      0x3fffffff
189
190 /* op = 01 -- mask for and match for call instruction */
191 #define CALLop          1
192 #define CALLmask        OPmask
193 #define CALLmatch       0x40000000
194
195 /* (op==10) && (op3 == 111000) 
196  */
197 #define RESTop          2
198 #define JMPLmask        (OPmask|OP3mask)
199 #define JMPLmatch       0x81c00000
200
201 #define FMT2op          0
202 #define LOADop          3
203
204 /*
205  * added this on 8/18 (jkh) to tell a jmpl from a call indirect.
206  *
207  */
208 #define CALLImask       (OPmask|RDmask|OP3mask)
209 #define CALLImatch      0x9fc00000
210
211 /* (op=10) && (op3==111001) trap instructions */
212 #define TRAPmask        (OPmask|OP3mask)
213 #define TRAPmatch       0x81d00000
214
215 /* (op == 00) && (op2 ^ 2) mask for conditional branching instructions */
216 #define BICCop2         2
217
218 #define BEcond          1
219 #define BLEcond         2
220 #define BLTcond         3
221 #define BGTcond        10
222 #define BGEcond        11
223 #define BAcond          8
224 #define BNEcond         9
225
226 #define BRNCHmask       (OPmask|OP2mask)
227 #define BRNCHmatch      0x1<<23
228
229 #define FBRNCHmask      (OPmask|OP2mask)
230 #define FBRNCHmatch     0x3<<23
231
232 /* really jmpl %i7+8,%g0 */
233 /* changed this to jmpl %i7+??,%g0 since g++ sometimes returns +0xc not +0x8 
234  * jkh - 7/12/93
235  */
236 #define RETmask         0xfffff000
237 #define RETmatch        0x81c7e000
238
239 /* retl - leaf return really jmpl %o7+8,%g0 */
240 /* changed this to jmpl %i7+??,%g0 since g++ sometimes returns +0xc not +0x8
241  * jkh - 7/12/93
242  */
243 #define RETLmask        0xfffff000
244 #define RETLmatch       0x81c3e000
245
246
247 #define SAVEmask        (OPmask|OP3mask)
248 #define SAVEmatch       0x81e00000
249
250 #define RESTOREmask     (OPmask|OP3mask)
251 #define RESTOREmatch    0x81e80000
252
253 /* noop insn */
254 #define NOOPop2         4
255 #define SETHIop2        4
256
257 // VG(4/24/2002): This was wrong; fortunately, it was not used anywhere...
258 #define ANNUL_BIT       0x20000000
259
260 #define BREAK_POINT_INSN 0x91d02001   /* ta 1 */
261 #define SPILL_REGISTERS_INSN 0x91d02003 /*ta 3*/
262
263 #define region_lo(x) ( (x > (0x1 << 23))? (x-(0x1 << 23)):0x0 )
264 #define region_hi(x) ( (x > (-1UL - (1<<23))) ? -1UL : (x + (0x1 << 23)))
265
266 /*
267  *    The following definitions are used for readWriteRegisters method
268  */
269 #define WIN_SIZE 16
270 #define MAX_SETS 32
271 #define FLOAT_OFFSET 530 // must be greater than 528 which is the max. number of registers on sparc
272
273 #define SINGLE 1
274 #define DOUBLE 2
275 #define QUAD 4
276
277 /* although the real values of the following constants are not important, they have to be greater than
278  * FLOAT_OFFSET + 62
279  */
280 #define FCC0 600
281 #define FCC1 601
282 #define FCC2 602
283 #define FCC3 603
284 #define ICC 604
285 #define XCC 605
286 #define FSR 606
287 #define REG_Y_reg 610
288 #define REG_CCR 611
289 #define REG_ASI 612
290 #define REG_TICK 613
291 #define REG_PC_reg 614
292 #define REG_FPRS 615
293 #define REG_TPC 616
294 #define REG_TNPC 617
295 #define REG_TSTATE 618
296 #define REG_TT 619
297 //#define REG_TICK 620
298 #define REG_TBA 621
299 #define REG_PSTATE 622
300 #define REG_TL 623
301 #define REG_PIL 624
302 #define REG_CWP 625
303 #define REG_CANSAVE 626
304 #define REG_CANRESTORE 627
305 #define REG_CLEANWIN 628
306 #define REG_OTHERWIN 629
307 #define REG_WSTATE 630
308 #define REG_FQ 631
309 #define REG_VER 632
310
311 /* opcodes */
312 #define SETHIop2 4
313 #define BProp2 3
314 #define BPop2cc 1
315 #define Bop2icc 2
316 #define FBPop2fcc 5
317 #define FBop2fcc 6
318
319 #define ILLEGAL_0x19 0x19
320 #define ILLEGAL_0x1D 0x1D
321 #define ILLEGAL_0x29 0x29
322 #define ILLEGAL_0x33 0x33
323 #define ILLEGAL_0x3F 0x3F
324 #define ADDCop3 0x08
325 #define MULXop3 0x09
326 #define UMULop3 0x0A
327 #define SUBCop3 0x0C
328 #define UDIVXop3 0x0D
329 #define UDIVop3 0x0E
330 #define ORop3cc 0x12
331 #define XORop3cc 0x13
332 #define ORNop3cc 0x16
333 #define XNORop3cc 0x17
334 #define ADDCop3cc 0x18
335 #define UMULop3cc 0x1A
336 #define SMULop3cc 0x1B
337 #define SUBCop3cc 0x1C
338 #define UDIVop3cc 0x1E
339 #define SDIVop3cc 0x1F
340 #define TADDop3cc 0x20
341 #define TSUBop3cc 0x21
342 #define TADDop3ccTV 0x22
343 #define TSUBop3ccTV 0x23
344 #define MULSop3cc 0x24
345 #define RDPRop3 0x2A
346 #define MOVop3cc 0x2C
347 #define SDIVXop3 0x2D
348 #define POPCop3 0x2E
349 #define MOVrop3 0x2F
350 #define SAVED_RESTOREDop3 0x31
351 #define WRPRop3 0x32
352 #define IMPDEP1op3 0x36
353 #define IMPDEP2op3 0x37
354 #define RETURNop3 0x39
355 #define Tccop3 0X3A
356 #define FLUSHop3 0X3B
357 #define DONE_RETRYop3 0X3E
358
359 /* the following constants are used when opcode=2, op3=0x30 */
360 #define WRY 0
361 #define WRCCR 2
362 #define WRASI 3
363 #define WRFPRS 6
364 #define SIR 15
365
366 /* the following constants are used when opcode=2, op3=0x30 */
367 #define TPC 0
368 #define TNPC 1
369 #define TSTATE 2
370 #define TT 3
371 #define TICK_reg 4 // TICK is defined somewhere else
372 #define TBA 5
373 #define PSTATE 6
374 #define TL 7
375 #define PIL 8
376 #define CWP 9
377 #define CANSAVE 10
378 #define CANRESTORE 11
379 #define CLEANWIN 12
380 #define OTHERWIN 13
381 #define WSTATE 14
382
383 /* the following constants are used when opcode=2, op3=0x34 */
384 #define FMOVs 0x001
385 #define FMOVd 0x002
386 #define FMOVq 0x003
387 #define FNEGs 0x005
388 #define FNEGd 0x006
389 #define FNEGq 0x007
390 #define FABSs 0x009
391 #define FABSd 0x00A
392 #define FABSq 0x00B
393 #define FSQRTs 0x029
394 #define FSQRTd 0x02A
395 #define FSQRTq 0x02B
396 #define FsTOx 0x081
397 #define FdTOx 0x082
398 #define FqTOx 0x083
399 #define FxTOs 0x084
400 #define FxTOd 0x088
401 #define FxTOq 0x08C
402 #define FiTOs 0x0C4
403 #define FdTOs 0x0C6
404 #define FqTOs 0x0C7
405 #define FiTOd 0x0C8
406 #define FsTOd 0x0C9
407 #define FqTOd 0x0CB
408 #define FiTOq 0x0CC
409 #define FsTOq 0x0CD
410 #define FdTOq 0x0CE
411 #define FsTOi 0x0D1
412 #define FdTOi 0x0D2
413 #define FqTOi 0x0D3
414 #define FADDs 0x041
415 #define FADDd 0x042
416 #define FADDq 0x043
417 #define FSUBs 0x045
418 #define FSUBd 0x046
419 #define FSUBq 0x047
420 #define FMULs 0x049
421 #define FMULd 0x04A
422 #define FMULq 0x04B
423 #define FDIVs 0x04D
424 #define FDIVd 0x04E
425 #define FDIVq 0x04F
426 #define FsMULd 0x069
427 #define FdMULq 0x06E
428
429 /* the following constants are used when opcode=2, op3=0x35 */
430 #define FMOVsfcc0 0x001
431 #define FMOVdfcc0 0x002
432 #define FMOVqfcc0 0x003
433 #define FMOVRsZ 0x025
434 #define FMOVRdZ 0x026
435 #define FMOVRqZ 0x027
436 #define FMOVsfcc1 0x041
437 #define FMOVdfcc1 0x042
438 #define FMOVqfcc1 0x043
439 #define FMOVRsLEZ 0x045
440 #define FMOVRdLEZ 0x046
441 #define FMOVRqLEZ 0x047
442 #define FCMPs 0x051
443 #define FCMPd 0x052
444 #define FCMPq 0x053
445 #define FCMPEs 0x055
446 #define FCMPEd 0x056
447 #define FCMPEq 0x057
448 #define FMOVRsLZ 0x065
449 #define FMOVRdLZ 0x066
450 #define FMOVRqLZ 0x067
451 #define FMOVsfcc2 0x081
452 #define FMOVdfcc2 0x082
453 #define FMOVqfcc2 0x083
454 #define FMOVRsNZ 0x0A5
455 #define FMOVRdNZ 0x0A6
456 #define FMOVRqNZ 0x0A7
457 #define FMOVsfcc3 0x0C1
458 #define FMOVdfcc3 0x0C2
459 #define FMOVqfcc3 0x0C3
460 #define FMOVRsGZ 0x0C5
461 #define FMOVRdGZ 0x0C6
462 #define FMOVRqGZ 0x0C7
463 #define FMOVRsGEZ 0x0E5
464 #define FMOVRdGEZ 0x0E6
465 #define FMOVRqGEZ 0x0E7
466 #define FMOVsicc 0x101
467 #define FMOVdicc 0x102
468 #define FMOVqicc 0x103
469 #define FMOVsxcc 0x181
470 #define FMOVdxcc 0x182
471 #define FMOVqxcc 0x183
472
473 #define LDSWop3 0x08
474 #define LDXop3 0x0B
475 #define LDSTUBop3 0x0D
476 #define STXop3 0x0E
477 #define LDUWAop3 0x10
478 #define LDUBAop3 0x11
479 #define LDUHAop3 0x12
480 #define LDDAop3 0x13
481 #define STWAop3 0x14
482 #define STBAop3 0x15
483 #define STHAop3 0x16
484 #define STDAop3 0x17
485 #define LDSWAop3 0x18
486 #define LDSBAop3 0x19
487 #define LDSHAop3 0x1A
488 #define LDXAop3 0x1B
489 #define LDSTUBAop3 0x1D
490 #define STXAop3 0x1E
491 #define SWAPAop3 0x1F
492 #define LDQFop3 0x22
493 #define STQFop3 0x26
494 #define PREFETCHop3 0x2D
495 #define LDFAop3 0x30
496 #define LDQFAop3 0x32
497 #define LDDFAop3 0x33
498 #define STFAop3 0x34
499 #define STQFAop3 0x36
500 #define STDFAop3 0x37
501 #define CASAop3 0x3C
502 #define PREFETCHAop3 0x3D
503 #define CASXAop3 0x3E
504
505 #define SRAop3 0x27
506
507
508 /* End definitions for readWriteRegisters */
509
510 class InsnRegister {
511 public:
512         enum RegisterType { GlobalIntReg=0, FloatReg, CoProcReg, SpecialReg, NoneReg};
513
514         InsnRegister();
515         InsnRegister(char isD, RegisterType rt, short rn);
516         void setWordCount(char isD);
517         void setType(RegisterType rt);
518         void setNumber(short rn);
519         int getWordCount();
520         RegisterType getType();
521         int getNumber();
522         bool is_o7();
523         void print();
524
525 private:
526         char wordCount;
527         RegisterType regType;
528         short regNumber;
529 };
530
531 class codeGen;
532
533 #if 0
534 typedef struct {} register_read_set_a;
535 typedef struct {} register_write_set_a;
536 static AnnotationClass<std::vector<InsnRegister *> > RegisterReadSetAnno("RegisterReadSetAnno");
537 static AnnotationClass<std::vector<InsnRegister *> > RegisterWriteSetAnno("RegisterWriteSetAnno");
538 #endif
539 class InsnRegister;
540 class instruction : public AnnotatableSparse
541 {
542
543  private:
544     static instructUnion *insnPtr(codeGen &gen);
545     static instructUnion *ptrAndInc(codeGen &gen);
546  public:
547     instruction() {insn_.raw = 0;};
548     instruction(unsigned int raw) { insn_.raw = raw; }
549
550     instruction(const instruction &insn) :
551         AnnotatableSparse(),
552         insn_(insn.insn_) {};
553     instruction(instructUnion &insn) :
554         insn_(insn) {};
555     
556     instruction *copy() const;
557
558     void setInstruction(codeBuf_t *ptr, Address = 0);
559
560     static bool offsetWithinRangeOfBranchInsn(long off);
561     
562     static void generateTrap(codeGen &gen);
563     static void generateIllegal(codeGen &gen);
564
565     static void generateNOOP(codeGen &gen,
566                              unsigned size = 4);
567     static void generateBranch(codeGen &gen,
568                                int jump_off);
569     static void generateBranch(codeGen &gen,
570                                Address from,
571                                Address to);
572     static void generateInterFunctionBranch(codeGen &gen,
573                                             Address from,
574                                             Address to) {
575         return generateBranch(gen, from, to);
576     }
577
578
579     static void generateCall(codeGen &gen,
580                              Address fromAddr,
581                              Address toAddr);
582     static void generateJmpl(codeGen &gen,
583                              int rs1,
584                              int jump_off,
585                              int rd);
586     static void generateCondBranch(codeGen &gen,
587                                    int jump_off,
588                                    unsigned condition,
589                                    bool annul);
590     static void generateAnnulledBranch(codeGen &gen,
591                                        int jump_off);
592     static void generateSimple(codeGen &gen,
593                                int op,
594                                Register rs1,
595                                Register rs2,
596                                Register rd);
597     static void generateImm(codeGen &gen,
598                             int op,
599                             Register rs1,
600                             int immd,
601                             Register rd);
602     static void generateImmRelOp(codeGen &gen,
603                                int cond,
604                                Register rs1,
605                                int immd,
606                                  Register rd);
607     static void generateRelOp(codeGen &gen,
608                               int cond,
609                               Register rs1,
610                               Register rs2,
611                               Register rd);
612     static void generateSetHi(codeGen &gen,
613                               int src1,
614                               int dest);
615     static void generateStore(codeGen &gen,
616                               int rd,
617                               int rs1,
618                               int store_off);
619     static void generateLShift(codeGen &gen,
620                                int rs1,
621                                int shift,
622                                int rd);
623     static void generateRShift(codeGen &gen,
624                                int rs1,
625                                int shift,
626                                int rd);
627     static void generateLoad(codeGen &gen,
628                              int rs1,
629                              int load_off,
630                              int rd);
631     static void generateStoreD(codeGen &gen,
632                                int rd,
633                                int rs1,
634                                int shift);
635     static void generateLoadD(codeGen &gen,
636                                int rs1,
637                                int load_off,
638                                int rd);
639     static void generateLoadB(codeGen &gen,
640                               int rs1,
641                               int load_off,
642                               int rd);    
643     static void generateLoadH(codeGen &gen,
644                               int rs1,
645                               int load_off,
646                               int rd);
647     static void generateStoreFD(codeGen &gen,
648                                 int rd,
649                                 int rs1,
650                                 int shift);
651     static void generateLoadFD(codeGen &gen,
652                                int rs1,
653                                int load_off,
654                                int rd);
655     static void generateFlushw(codeGen &gen);
656     static void generateTrapRegisterSpill(codeGen &gen);
657   
658     void write(codeGen &gen);
659     void generate(codeGen &gen);
660
661     unsigned spaceToRelocate() const;
662     bool generate(codeGen &gen,
663                   AddressSpace *proc,
664                   Address origAddr,
665                   Address newAddr,
666                   patchTarget *fallthroughOverride = NULL,
667                   patchTarget *targetOverride = NULL);
668
669     bool generateMem(codeGen &gen,
670                      Address origAddr,
671                      Address newAddr,
672                      Register newLoadReg,
673                      Register newStoreReg);
674   bool getUsedRegs(pdvector<int> &regs);
675
676
677   // return the type of the instruction
678   unsigned type() const;
679
680   // return a pointer to the instruction
681   const unsigned char *ptr() const { return (const unsigned char *)&insn_; }
682
683   const unsigned int &raw() const { return insn_.raw; }
684   
685   const unsigned opcode() const;
686
687   // For external modification
688   instructUnion &operator* () { return insn_; }
689   const instructUnion &operator* () const { return insn_; }
690   
691   Address getTarget(Address insnAddr) const;
692   Address getOffset() const;
693
694   // And tell us how much space we'll need...
695   static unsigned jumpSize(Address from, Address to, unsigned addr_width);
696   static unsigned jumpSize(int disp, unsigned addr_width);
697   static unsigned maxJumpSize(unsigned addr_width);
698
699   static unsigned maxInterFunctionJumpSize(unsigned addr_width);
700
701
702   bool isInsnType(const unsigned mask,
703                   const unsigned match) const {
704       return ((insn_.raw & mask) == match);
705   }
706
707   bool isCall() const;
708
709   void get_register_operands();
710 #if 0
711   void get_register_operands(InsnRegister * reads,
712                              InsnRegister * writes);
713 #endif
714
715   //  is instruction i a "true" call?
716   //  2 types of call insn in sparc:
717   //    true call - call to fixed address (really pc rel addr, but disass will show
718   //     fixed addr - for your convenience)....
719   //    jmpl (jump & link) - call to register | register + const |
720   //       register + register, and stick return address in some 
721   //       register.  If dest register is 07, a disassembler should
722   //       show a "call" insn.
723   bool isTrueCallInsn() const {
724       return (insn_.call.op == 0x1);
725   }
726   
727   bool isJmplCallInsn() const {
728       // condition for jmpl insn
729       if (insn_.resti.op == 0x2 && insn_.resti.op3 == 0x38) {
730           // condition for dest register == 07
731           if (insn_.resti.rd == 15) {
732               return true;
733           }
734       }
735       return false;
736   }
737   
738   inline bool isJmplInsn() const{
739       if (insn_.resti.op == 0x2 && insn_.resti.op3 == 0x38)
740           return true;
741       return false;
742   }
743     
744   // VG(4/24/200): DCTI = delayed control-transfer instruction
745   // It was incomplete on v9, so here's a quick rewrite:
746   bool isDCTI() const {
747       return (insn_.call.op == 1 || // call
748               (insn_.branch.op == 0 && // branches (BPcc, Bicc, BPr, FBPfcc, FBfcc)
749                insn_.branch.op2 != 0 &&
750                insn_.branch.op2 != 4 &&
751                insn_.branch.op2 != 7) ||
752               (insn_.rest.op == 2 &&  // JMPL, RETURN
753                ((insn_.rest.op3 | 1) == 0x39))
754               );
755       /*   return (insn_.call.op == CALLop || */
756       /*          isInsnType(insn, JMPLmask, JMPLmatch) || */
757       /*          isInsnType(insn, FBRNCHmask, FBRNCHmatch) || */
758       /*          isInsnType(insn, BRNCHmask, BRNCHmatch)); */
759   }
760   
761   bool isAnnulled() const {
762       return insn_.branch.anneal == 1;
763   }
764   
765   // VG(4/24/200): UB = unconditional branch
766   inline bool isUB() const {
767       // Only Bicc(010), BPcc(001), FBfcc (110), FBPfcc(101) can be unconditional
768       if(insn_.branch.op==00 && ((insn_.branch.op2 & 3) == 1 ||
769                                  (insn_.branch.op2 & 3) == 2) &&
770          // 0x0=never; 0x8=always
771          (insn_.branch.cond == 0x0 || insn_.branch.cond == 0x8))
772           return true;
773       return false;
774   }
775   
776   // VG(4/24/200): UBA = unconditional branch anulled
777   bool isUBA() const {
778       return isUB() && isAnnulled();
779   }
780
781   bool isRestore() const {
782       return (insn_.rest.op == 2 && insn_.rest.op3 == RESTOREop3);
783   }
784
785   bool isMovToO7() const {
786       return (insn_.rest.op == 2 && insn_.rest.op3 == ORop3 &&
787               insn_.rest.rd == 15 && insn_.rest.rs1 == 0);
788   }
789   
790   /* catch small ints that are invalid instructions */
791   /*
792    * insn.call.op checks for CALL or Format 3 insns
793    * op2 == {2,4,6,7} checks for valid format 2 instructions.
794    *    See SPARC Arch manual v8 p. 44.
795    *
796    */
797   inline bool valid() const {
798       return ((insn_.call.op) || ((insn_.branch.op2 == 2) ||
799                                   (insn_.branch.op2 == 4) ||
800                                   (insn_.branch.op2 == 6) ||
801                                   (insn_.branch.op2 == 7)));
802   }
803   
804   /* addresses on sparc are aligned to word boundaries */
805   static bool isAligned(const Address addr) { return !(addr & 0x3); }
806   
807   int get_disp();
808   void set_disp(bool setDisp, int newOffset, bool outOfFunc);
809   static unsigned size();
810   
811   bool isUncondBranch() const;
812   bool isCondBranch() const;
813   
814   bool isNop() const {
815       if (insn_.sethi.op == 0 && insn_.sethi.op2 == 0x4) {
816           return true;
817       }
818       return false;
819   }
820
821   bool isIllegal() const {
822     if (insn_.sethi.op == 0 && insn_.sethi.op2 == 0) {
823         return true;
824     }
825     return false;
826   }
827   bool isCleaningRet() const { return false; }
828   
829  private:
830   instructUnion insn_;
831
832   
833 };
834
835 #endif