]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/host_arm_defs.h
bc3831228e0ab5064bcb538a479c296b4a9830e1
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / VEX / priv / host_arm_defs.h
1
2 /*---------------------------------------------------------------*/
3 /*--- begin                                   host_arm_defs.h ---*/
4 /*---------------------------------------------------------------*/
5
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9
10    Copyright (C) 2004-2010 OpenWorks LLP
11       info@open-works.net
12
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26    02110-1301, USA.
27
28    The GNU General Public License is contained in the file COPYING.
29 */
30
31 #ifndef __VEX_HOST_ARM_DEFS_H
32 #define __VEX_HOST_ARM_DEFS_H
33
34
35 /* --------- Registers. --------- */
36
37 /* The usual HReg abstraction.
38    There are 16 general purpose regs.
39 */
40
41 extern void ppHRegARM ( HReg );
42
43 extern HReg hregARM_R0  ( void );
44 extern HReg hregARM_R1  ( void );
45 extern HReg hregARM_R2  ( void );
46 extern HReg hregARM_R3  ( void );
47 extern HReg hregARM_R4  ( void );
48 extern HReg hregARM_R5  ( void );
49 extern HReg hregARM_R6  ( void );
50 extern HReg hregARM_R7  ( void );
51 extern HReg hregARM_R8  ( void );
52 extern HReg hregARM_R9  ( void );
53 extern HReg hregARM_R10 ( void );
54 extern HReg hregARM_R11 ( void );
55 extern HReg hregARM_R12 ( void );
56 extern HReg hregARM_R13 ( void );
57 extern HReg hregARM_R14 ( void );
58 extern HReg hregARM_R15 ( void );
59 extern HReg hregARM_D8  ( void );
60 extern HReg hregARM_D9  ( void );
61 extern HReg hregARM_D10 ( void );
62 extern HReg hregARM_D11 ( void );
63 extern HReg hregARM_D12 ( void );
64 extern HReg hregARM_S26 ( void );
65 extern HReg hregARM_S27 ( void );
66 extern HReg hregARM_S28 ( void );
67 extern HReg hregARM_S29 ( void );
68 extern HReg hregARM_S30 ( void );
69
70 /* Number of registers used arg passing in function calls */
71 #define ARM_N_ARGREGS 4   /* r0, r1, r2, r3 */
72
73
74 /* --------- Condition codes. --------- */
75
76 typedef
77    enum {
78       ARMcc_EQ  = 0,  /* equal                          : Z=1 */
79       ARMcc_NE  = 1,  /* not equal                      : Z=0 */
80
81       ARMcc_HS  = 2,  /* >=u (higher or same)           : C=1 */
82       ARMcc_LO  = 3,  /* <u  (lower)                    : C=0 */
83
84       ARMcc_MI  = 4,  /* minus (negative)               : N=1 */
85       ARMcc_PL  = 5,  /* plus (zero or +ve)             : N=0 */
86
87       ARMcc_VS  = 6,  /* overflow                       : V=1 */
88       ARMcc_VC  = 7,  /* no overflow                    : V=0 */
89
90       ARMcc_HI  = 8,  /* >u   (higher)                  : C=1 && Z=0 */
91       ARMcc_LS  = 9,  /* <=u  (lower or same)           : C=0 || Z=1 */
92
93       ARMcc_GE  = 10, /* >=s (signed greater or equal)  : N=V */
94       ARMcc_LT  = 11, /* <s  (signed less than)         : N!=V */
95
96       ARMcc_GT  = 12, /* >s  (signed greater)           : Z=0 && N=V */
97       ARMcc_LE  = 13, /* <=s (signed less or equal)     : Z=1 || N!=V */
98
99       ARMcc_AL  = 14, /* always (unconditional) */
100       ARMcc_NV  = 15  /* never (basically undefined meaning), deprecated */
101    }
102    ARMCondCode;
103
104 extern HChar* showARMCondCode ( ARMCondCode );
105
106
107
108 /* --------- Memory address expressions (amodes). --------- */
109
110 /* --- Addressing Mode 1 --- */
111 typedef
112    enum {
113       ARMam1_RI=1,   /* reg +/- imm12 */
114       ARMam1_RRS     /* reg1 + (reg2 << 0, 1 2 or 3) */
115    }
116    ARMAMode1Tag;
117
118 typedef
119    struct {
120       ARMAMode1Tag tag;
121       union {
122          struct {
123             HReg reg;
124             Int  simm13; /* -4095 .. +4095 */
125          } RI;
126          struct {
127             HReg base;
128             HReg index;
129             UInt shift; /* 0, 1 2 or 3 */
130          } RRS;
131       } ARMam1;
132    }
133    ARMAMode1;
134
135 extern ARMAMode1* ARMAMode1_RI  ( HReg reg, Int simm13 );
136 extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift );
137
138 extern void ppARMAMode1 ( ARMAMode1* );
139
140
141 /* --- Addressing Mode 2 --- */
142 typedef
143    enum {
144       ARMam2_RI=3,   /* reg +/- imm8 */
145       ARMam2_RR      /* reg1 + reg2 */
146    }
147    ARMAMode2Tag;
148
149 typedef
150    struct {
151       ARMAMode2Tag tag;
152       union {
153          struct {
154             HReg reg;
155             Int  simm9; /* -255 .. 255 */
156          } RI;
157          struct {
158             HReg base;
159             HReg index;
160          } RR;
161       } ARMam2;
162    }
163    ARMAMode2;
164
165 extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 );
166 extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index );
167
168 extern void ppARMAMode2 ( ARMAMode2* );
169
170
171 /* --- Addressing Mode suitable for VFP --- */
172 /* The simm11 is encoded as 8 bits + 1 sign bit,
173    so can only be 0 % 4. */
174 typedef
175    struct {
176       HReg reg;
177       Int  simm11; /* -1020, -1016 .. 1016, 1020 */
178    }
179    ARMAModeV;
180
181 extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 );
182
183 extern void ppARMAModeV ( ARMAModeV* );
184
185
186 /* --------- Reg or imm-8x4 operands --------- */
187 /* a.k.a (a very restricted form of) Shifter Operand,
188    in the ARM parlance. */
189
190 typedef
191    enum {
192       ARMri84_I84=5,   /* imm8 `ror` (2 * imm4) */
193       ARMri84_R        /* reg */
194    }
195    ARMRI84Tag;
196
197 typedef
198    struct {
199       ARMRI84Tag tag;
200       union {
201          struct {
202             UShort imm8;
203             UShort imm4;
204          } I84;
205          struct {
206             HReg reg;
207          } R;
208       } ARMri84;
209    }
210    ARMRI84;
211
212 extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 );
213 extern ARMRI84* ARMRI84_R   ( HReg );
214
215 extern void ppARMRI84 ( ARMRI84* );
216
217
218 /* --------- Reg or imm5 operands --------- */
219 typedef
220    enum {
221       ARMri5_I5=7,   /* imm5, 1 .. 31 only (no zero!) */
222       ARMri5_R       /* reg */
223    }
224    ARMRI5Tag;
225
226 typedef
227    struct {
228       ARMRI5Tag tag;
229       union {
230          struct {
231             UInt imm5;
232          } I5;
233          struct {
234             HReg reg;
235          } R;
236       } ARMri5;
237    }
238    ARMRI5;
239
240 extern ARMRI5* ARMRI5_I5 ( UInt imm5 );
241 extern ARMRI5* ARMRI5_R  ( HReg );
242
243 extern void ppARMRI5 ( ARMRI5* );
244
245
246 /* --------- Instructions. --------- */
247
248 /* --------- */
249 typedef
250    enum {
251       ARMalu_ADD=10,   /* plain 32-bit add */
252       ARMalu_ADDS,     /* 32-bit add, and set the flags */
253       ARMalu_ADC,      /* 32-bit add with carry */
254       ARMalu_SUB,      /* plain 32-bit subtract */
255       ARMalu_SUBS,     /* 32-bit subtract, and set the flags */
256       ARMalu_SBC,      /* 32-bit subtract with carry */
257       ARMalu_AND,
258       ARMalu_BIC,
259       ARMalu_OR,
260       ARMalu_XOR
261    }
262    ARMAluOp;
263
264 extern HChar* showARMAluOp ( ARMAluOp op );
265
266
267 typedef
268    enum {
269       ARMsh_SHL=20,
270       ARMsh_SHR,
271       ARMsh_SAR
272    }
273    ARMShiftOp;
274
275 extern HChar* showARMShiftOp ( ARMShiftOp op );
276
277
278 typedef
279    enum {
280       ARMun_NEG=30,
281       ARMun_NOT,
282       ARMun_CLZ
283    }
284    ARMUnaryOp;
285
286 extern HChar* showARMUnaryOp ( ARMUnaryOp op );
287
288
289 typedef
290    enum {
291       ARMmul_PLAIN=40,
292       ARMmul_ZX,
293       ARMmul_SX
294    }
295    ARMMulOp;
296
297 extern HChar* showARMMulOp ( ARMMulOp op );
298
299
300 typedef
301    enum {
302       ARMvfp_ADD=50,
303       ARMvfp_SUB,
304       ARMvfp_MUL,
305       ARMvfp_DIV
306    }
307    ARMVfpOp;
308
309 extern HChar* showARMVfpOp ( ARMVfpOp op );
310
311
312 typedef
313    enum {
314       ARMvfpu_COPY=60,
315       ARMvfpu_NEG,
316       ARMvfpu_ABS,
317       ARMvfpu_SQRT
318    }
319    ARMVfpUnaryOp;
320
321 extern HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
322
323
324 typedef
325    enum {
326       /* baseline */
327       ARMin_Alu=70,
328       ARMin_Shift,
329       ARMin_Unary,
330       ARMin_CmpOrTst,
331       ARMin_Mov,
332       ARMin_Imm32,
333       ARMin_LdSt32,
334       ARMin_LdSt16,
335       ARMin_LdSt8U,
336       ARMin_Ld8S,
337       ARMin_Goto,
338       ARMin_CMov,
339       ARMin_Call,
340       ARMin_Mul,
341       ARMin_LdrEX,
342       ARMin_StrEX,
343       /* vfp */
344       ARMin_VLdStD,
345       ARMin_VLdStS,
346       ARMin_VAluD,
347       ARMin_VAluS,
348       ARMin_VUnaryD,
349       ARMin_VUnaryS,
350       ARMin_VCmpD,
351       ARMin_VCMovD,
352       ARMin_VCMovS,
353       ARMin_VCvtSD,
354       ARMin_VXferD,
355       ARMin_VXferS,
356       ARMin_VCvtID,
357       ARMin_FPSCR,
358       ARMin_MFence
359    }
360    ARMInstrTag;
361
362 /* Destinations are on the LEFT (first operand) */
363
364 typedef
365    struct {
366       ARMInstrTag tag;
367       union {
368          /* ADD/SUB/AND/OR/XOR, vanilla ALU op */
369          struct {
370             ARMAluOp op;
371             HReg     dst;
372             HReg     argL;
373             ARMRI84* argR;
374          } Alu;
375          /* SHL/SHR/SAR, 2nd arg is reg or imm */
376          struct {
377             ARMShiftOp op;
378             HReg       dst;
379             HReg       argL;
380             ARMRI5*    argR;
381          } Shift;
382          /* NOT/NEG/CLZ */
383          struct {
384             ARMUnaryOp op;
385             HReg       dst;
386             HReg       src;
387          } Unary;
388          /* CMP/TST; subtract/and, discard result, set NZCV */
389          struct {
390             Bool     isCmp;
391             HReg     argL;
392             ARMRI84* argR;
393          } CmpOrTst;
394          /* MOV dst, src -- reg-reg (or reg-imm8x4) move */
395          struct {
396             HReg     dst;
397             ARMRI84* src;
398          } Mov;
399          /* Pseudo-insn; make a 32-bit immediate */
400          struct {
401             HReg dst;
402             UInt imm32;
403          } Imm32;
404          /* 32-bit load or store */
405          struct {
406             Bool       isLoad;
407             HReg       rD;
408             ARMAMode1* amode;
409          } LdSt32;
410          /* 16-bit load or store */
411          struct {
412             Bool       isLoad;
413             Bool       signedLoad;
414             HReg       rD;
415             ARMAMode2* amode;
416          } LdSt16;
417          /* 8-bit (unsigned) load or store */
418          struct {
419             Bool       isLoad;
420             HReg       rD;
421             ARMAMode1* amode;
422          } LdSt8U;
423          /* 8-bit signed load */
424          struct {
425             HReg       rD;
426             ARMAMode2* amode;
427          } Ld8S;
428          /* Pseudo-insn.  Go to guest address gnext, on given
429             condition, which could be ARMcc_AL. */
430          struct {
431             IRJumpKind  jk;
432             ARMCondCode cond;
433             HReg        gnext;
434          } Goto;
435          /* Mov src to dst on the given condition, which may not
436             be ARMcc_AL. */
437          struct {
438             ARMCondCode cond;
439             HReg        dst;
440             ARMRI84*    src;
441          } CMov;
442          /* Pseudo-insn.  Call target (an absolute address), on given
443             condition (which could be ARMcc_AL). */
444          struct {
445             ARMCondCode cond;
446             HWord       target;
447             Int         nArgRegs; /* # regs carrying args: 0 .. 4 */
448          } Call;
449          /* (PLAIN) 32 *  32 -> 32:  r0    = r2 * r3
450             (ZX)    32 *u 32 -> 64:  r1:r0 = r2 *u r3
451             (SX)    32 *s 32 -> 64:  r1:r0 = r2 *s r3
452             Why hardwired registers?  Because the ARM ARM specifies
453             (eg for straight MUL) the result (Rd) and the left arg (Rm)
454             may not be the same register.  That's not a constraint we
455             can enforce in the register allocator (without mucho extra
456             complexity).  Hence hardwire it.  At least using caller-saves
457             registers, which are less likely to be in use. */
458          struct {
459             ARMMulOp op;
460          } Mul;
461          /* LDREX{,H,B} r0, [r1]
462             Again, hardwired registers since this is not performance
463             critical, and there are possibly constraints on the
464             registers that we can't express in the register allocator.*/
465          struct {
466             Int  szB; /* currently only 4 is allowed */
467          } LdrEX;
468          /* STREX{,H,B} r0, r1, [r2]
469             r0 = SC( [r2] = r1 )
470             Ditto comment re fixed registers. */
471          struct {
472             Int  szB; /* currently only 4 is allowed */
473          } StrEX;
474          /* VFP INSTRUCTIONS */
475          /* 64-bit Fp load/store */
476          struct {
477             Bool       isLoad;
478             HReg       dD;
479             ARMAModeV* amode;
480          } VLdStD;
481          /* 32-bit Fp load/store */
482          struct {
483             Bool       isLoad;
484             HReg       fD;
485             ARMAModeV* amode;
486          } VLdStS;
487          /* 64-bit FP binary arithmetic */
488          struct {
489             ARMVfpOp op;
490             HReg     dst;
491             HReg     argL;
492             HReg     argR;
493          } VAluD;
494          /* 32-bit FP binary arithmetic */
495          struct {
496             ARMVfpOp op;
497             HReg     dst;
498             HReg     argL;
499             HReg     argR;
500          } VAluS;
501          /* 64-bit FP unary, also reg-reg move */
502          struct {
503             ARMVfpUnaryOp op;
504             HReg          dst;
505             HReg          src;
506          } VUnaryD;
507          /* 32-bit FP unary, also reg-reg move */
508          struct {
509             ARMVfpUnaryOp op;
510             HReg          dst;
511             HReg          src;
512          } VUnaryS;
513          /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */
514          struct {
515             HReg argL;
516             HReg argR;
517          } VCmpD;
518          /* 64-bit FP mov src to dst on the given condition, which may
519             not be ARMcc_AL. */
520          struct {
521             ARMCondCode cond;
522             HReg        dst;
523             HReg        src;
524          } VCMovD;
525          /* 32-bit FP mov src to dst on the given condition, which may
526             not be ARMcc_AL. */
527          struct {
528             ARMCondCode cond;
529             HReg        dst;
530             HReg        src;
531          } VCMovS;
532          /* Convert between 32-bit and 64-bit FP values (both ways).
533             (FCVTSD, FCVTDS) */
534          struct {
535             Bool sToD; /* True: F32->F64.  False: F64->F32 */
536             HReg dst;
537             HReg src;
538          } VCvtSD;
539          /* Transfer a VFP D reg to/from two integer registers (VMOV) */
540          struct {
541             Bool toD;
542             HReg dD;
543             HReg rHi;
544             HReg rLo;
545          } VXferD;
546          /* Transfer a VFP S reg to/from an integer register (VMOV) */
547          struct {
548             Bool toS;
549             HReg fD;
550             HReg rLo;
551          } VXferS;
552          /* Convert between 32-bit ints and 64-bit FP values (both ways
553             and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
554          struct {
555             Bool iToD; /* True: I32->F64.  False: F64->I32 */
556             Bool syned; /* True: I32 is signed.  False: I32 is unsigned */
557             HReg dst;
558             HReg src;
559          } VCvtID;
560          /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
561          struct {
562             Bool toFPSCR;
563             HReg iReg;
564          } FPSCR;
565          /* Mem fence.  An insn which fences all loads and stores as
566             much as possible before continuing.  On ARM we emit the
567             sequence
568                mcr 15,0,r0,c7,c10,4 (DSB)
569                mcr 15,0,r0,c7,c10,5 (DMB)
570                mcr 15,0,r0,c7,c5,4 (ISB)
571             which is probably total overkill, but better safe than
572             sorry.
573          */
574          struct {
575          } MFence;
576
577       } ARMin;
578    }
579    ARMInstr;
580
581
582 extern ARMInstr* ARMInstr_Alu      ( ARMAluOp, HReg, HReg, ARMRI84* );
583 extern ARMInstr* ARMInstr_Shift    ( ARMShiftOp, HReg, HReg, ARMRI5* );
584 extern ARMInstr* ARMInstr_Unary    ( ARMUnaryOp, HReg, HReg );
585 extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
586 extern ARMInstr* ARMInstr_Mov      ( HReg, ARMRI84* );
587 extern ARMInstr* ARMInstr_Imm32    ( HReg, UInt );
588 extern ARMInstr* ARMInstr_LdSt32   ( Bool isLoad, HReg, ARMAMode1* );
589 extern ARMInstr* ARMInstr_LdSt16   ( Bool isLoad, Bool signedLoad,
590                                      HReg, ARMAMode2* );
591 extern ARMInstr* ARMInstr_LdSt8U   ( Bool isLoad, HReg, ARMAMode1* );
592 extern ARMInstr* ARMInstr_Ld8S     ( HReg, ARMAMode2* );
593 extern ARMInstr* ARMInstr_Goto     ( IRJumpKind, ARMCondCode, HReg gnext );
594 extern ARMInstr* ARMInstr_CMov     ( ARMCondCode, HReg dst, ARMRI84* src );
595 extern ARMInstr* ARMInstr_Call     ( ARMCondCode, HWord, Int nArgRegs );
596 extern ARMInstr* ARMInstr_Mul      ( ARMMulOp op );
597 extern ARMInstr* ARMInstr_LdrEX    ( Int szB );
598 extern ARMInstr* ARMInstr_StrEX    ( Int szB );
599 extern ARMInstr* ARMInstr_VLdStD   ( Bool isLoad, HReg, ARMAModeV* );
600 extern ARMInstr* ARMInstr_VLdStS   ( Bool isLoad, HReg, ARMAModeV* );
601 extern ARMInstr* ARMInstr_VAluD    ( ARMVfpOp op, HReg, HReg, HReg );
602 extern ARMInstr* ARMInstr_VAluS    ( ARMVfpOp op, HReg, HReg, HReg );
603 extern ARMInstr* ARMInstr_VUnaryD  ( ARMVfpUnaryOp, HReg dst, HReg src );
604 extern ARMInstr* ARMInstr_VUnaryS  ( ARMVfpUnaryOp, HReg dst, HReg src );
605 extern ARMInstr* ARMInstr_VCmpD    ( HReg argL, HReg argR );
606 extern ARMInstr* ARMInstr_VCMovD   ( ARMCondCode, HReg dst, HReg src );
607 extern ARMInstr* ARMInstr_VCMovS   ( ARMCondCode, HReg dst, HReg src );
608 extern ARMInstr* ARMInstr_VCvtSD   ( Bool sToD, HReg dst, HReg src );
609 extern ARMInstr* ARMInstr_VXferD   ( Bool toD, HReg dD, HReg rHi, HReg rLo );
610 extern ARMInstr* ARMInstr_VXferS   ( Bool toS, HReg fD, HReg rLo );
611 extern ARMInstr* ARMInstr_VCvtID   ( Bool iToD, Bool syned,
612                                      HReg dst, HReg src );
613 extern ARMInstr* ARMInstr_FPSCR    ( Bool toFPSCR, HReg iReg );
614 extern ARMInstr* ARMInstr_MFence   ( void );
615
616 extern void ppARMInstr ( ARMInstr* );
617
618
619 /* Some functions that insulate the register allocator from details
620    of the underlying instruction set. */
621 extern void getRegUsage_ARMInstr ( HRegUsage*, ARMInstr*, Bool );
622 extern void mapRegs_ARMInstr     ( HRegRemap*, ARMInstr*, Bool );
623 extern Bool isMove_ARMInstr      ( ARMInstr*, HReg*, HReg* );
624 extern Int  emit_ARMInstr        ( UChar* buf, Int nbuf, ARMInstr*, 
625                                    Bool, void* dispatch );
626
627 extern void genSpill_ARM  ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
628                             HReg rreg, Int offset, Bool );
629 extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
630                             HReg rreg, Int offset, Bool );
631
632 extern void getAllocableRegs_ARM ( Int*, HReg** );
633 extern HInstrArray* iselSB_ARM   ( IRSB*, VexArch,
634                                    VexArchInfo*, VexAbiInfo* );
635
636 #endif /* ndef __VEX_HOST_ARM_DEFS_H */
637
638 /*---------------------------------------------------------------*/
639 /*--- end                                     host_arm_defs.h ---*/
640 /*---------------------------------------------------------------*/