]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/host_arm_defs.h
update
[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 extern UInt arm_hwcaps;
35
36
37 /* --------- Registers. --------- */
38
39 /* The usual HReg abstraction.
40    There are 16 general purpose regs.
41 */
42
43 extern void ppHRegARM ( HReg );
44
45 extern HReg hregARM_R0  ( void );
46 extern HReg hregARM_R1  ( void );
47 extern HReg hregARM_R2  ( void );
48 extern HReg hregARM_R3  ( void );
49 extern HReg hregARM_R4  ( void );
50 extern HReg hregARM_R5  ( void );
51 extern HReg hregARM_R6  ( void );
52 extern HReg hregARM_R7  ( void );
53 extern HReg hregARM_R8  ( void );
54 extern HReg hregARM_R9  ( void );
55 extern HReg hregARM_R10 ( void );
56 extern HReg hregARM_R11 ( void );
57 extern HReg hregARM_R12 ( void );
58 extern HReg hregARM_R13 ( void );
59 extern HReg hregARM_R14 ( void );
60 extern HReg hregARM_R15 ( void );
61 extern HReg hregARM_D8  ( void );
62 extern HReg hregARM_D9  ( void );
63 extern HReg hregARM_D10 ( void );
64 extern HReg hregARM_D11 ( void );
65 extern HReg hregARM_D12 ( void );
66 extern HReg hregARM_S26 ( void );
67 extern HReg hregARM_S27 ( void );
68 extern HReg hregARM_S28 ( void );
69 extern HReg hregARM_S29 ( void );
70 extern HReg hregARM_S30 ( void );
71 extern HReg hregARM_Q8  ( void );
72 extern HReg hregARM_Q9  ( void );
73 extern HReg hregARM_Q10 ( void );
74 extern HReg hregARM_Q11 ( void );
75 extern HReg hregARM_Q12 ( void );
76 extern HReg hregARM_Q13 ( void );
77 extern HReg hregARM_Q14 ( void );
78 extern HReg hregARM_Q15 ( void );
79
80 /* Number of registers used arg passing in function calls */
81 #define ARM_N_ARGREGS 4   /* r0, r1, r2, r3 */
82
83
84 /* --------- Condition codes. --------- */
85
86 typedef
87    enum {
88       ARMcc_EQ  = 0,  /* equal                          : Z=1 */
89       ARMcc_NE  = 1,  /* not equal                      : Z=0 */
90
91       ARMcc_HS  = 2,  /* >=u (higher or same)           : C=1 */
92       ARMcc_LO  = 3,  /* <u  (lower)                    : C=0 */
93
94       ARMcc_MI  = 4,  /* minus (negative)               : N=1 */
95       ARMcc_PL  = 5,  /* plus (zero or +ve)             : N=0 */
96
97       ARMcc_VS  = 6,  /* overflow                       : V=1 */
98       ARMcc_VC  = 7,  /* no overflow                    : V=0 */
99
100       ARMcc_HI  = 8,  /* >u   (higher)                  : C=1 && Z=0 */
101       ARMcc_LS  = 9,  /* <=u  (lower or same)           : C=0 || Z=1 */
102
103       ARMcc_GE  = 10, /* >=s (signed greater or equal)  : N=V */
104       ARMcc_LT  = 11, /* <s  (signed less than)         : N!=V */
105
106       ARMcc_GT  = 12, /* >s  (signed greater)           : Z=0 && N=V */
107       ARMcc_LE  = 13, /* <=s (signed less or equal)     : Z=1 || N!=V */
108
109       ARMcc_AL  = 14, /* always (unconditional) */
110       ARMcc_NV  = 15  /* never (basically undefined meaning), deprecated */
111    }
112    ARMCondCode;
113
114 extern HChar* showARMCondCode ( ARMCondCode );
115
116
117
118 /* --------- Memory address expressions (amodes). --------- */
119
120 /* --- Addressing Mode 1 --- */
121 typedef
122    enum {
123       ARMam1_RI=1,   /* reg +/- imm12 */
124       ARMam1_RRS     /* reg1 + (reg2 << 0, 1 2 or 3) */
125    }
126    ARMAMode1Tag;
127
128 typedef
129    struct {
130       ARMAMode1Tag tag;
131       union {
132          struct {
133             HReg reg;
134             Int  simm13; /* -4095 .. +4095 */
135          } RI;
136          struct {
137             HReg base;
138             HReg index;
139             UInt shift; /* 0, 1 2 or 3 */
140          } RRS;
141       } ARMam1;
142    }
143    ARMAMode1;
144
145 extern ARMAMode1* ARMAMode1_RI  ( HReg reg, Int simm13 );
146 extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift );
147
148 extern void ppARMAMode1 ( ARMAMode1* );
149
150
151 /* --- Addressing Mode 2 --- */
152 typedef
153    enum {
154       ARMam2_RI=3,   /* reg +/- imm8 */
155       ARMam2_RR      /* reg1 + reg2 */
156    }
157    ARMAMode2Tag;
158
159 typedef
160    struct {
161       ARMAMode2Tag tag;
162       union {
163          struct {
164             HReg reg;
165             Int  simm9; /* -255 .. 255 */
166          } RI;
167          struct {
168             HReg base;
169             HReg index;
170          } RR;
171       } ARMam2;
172    }
173    ARMAMode2;
174
175 extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 );
176 extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index );
177
178 extern void ppARMAMode2 ( ARMAMode2* );
179
180
181 /* --- Addressing Mode suitable for VFP --- */
182 /* The simm11 is encoded as 8 bits + 1 sign bit,
183    so can only be 0 % 4. */
184 typedef
185    struct {
186       HReg reg;
187       Int  simm11; /* -1020, -1016 .. 1016, 1020 */
188    }
189    ARMAModeV;
190
191 extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 );
192
193 extern void ppARMAModeV ( ARMAModeV* );
194
195 /* --- Addressing Mode suitable for Neon --- */
196 typedef
197    enum {
198       ARMamN_R=5,
199       ARMamN_RR
200       /* ... */
201    }
202    ARMAModeNTag;
203
204 typedef
205    struct {
206       ARMAModeNTag tag;
207       union {
208          struct {
209             HReg rN;
210             HReg rM;
211          } RR;
212          struct {
213             HReg rN;
214          } R;
215          /* ... */
216       } ARMamN;
217    }
218    ARMAModeN;
219
220 extern ARMAModeN* mkARMAModeN_RR ( HReg, HReg );
221 extern ARMAModeN* mkARMAModeN_R ( HReg );
222 extern void ppARMAModeN ( ARMAModeN* );
223
224 /* --------- Reg or imm-8x4 operands --------- */
225 /* a.k.a (a very restricted form of) Shifter Operand,
226    in the ARM parlance. */
227
228 typedef
229    enum {
230       ARMri84_I84=7,   /* imm8 `ror` (2 * imm4) */
231       ARMri84_R        /* reg */
232    }
233    ARMRI84Tag;
234
235 typedef
236    struct {
237       ARMRI84Tag tag;
238       union {
239          struct {
240             UShort imm8;
241             UShort imm4;
242          } I84;
243          struct {
244             HReg reg;
245          } R;
246       } ARMri84;
247    }
248    ARMRI84;
249
250 extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 );
251 extern ARMRI84* ARMRI84_R   ( HReg );
252
253 extern void ppARMRI84 ( ARMRI84* );
254
255
256 /* --------- Reg or imm5 operands --------- */
257 typedef
258    enum {
259       ARMri5_I5=9,   /* imm5, 1 .. 31 only (no zero!) */
260       ARMri5_R       /* reg */
261    }
262    ARMRI5Tag;
263
264 typedef
265    struct {
266       ARMRI5Tag tag;
267       union {
268          struct {
269             UInt imm5;
270          } I5;
271          struct {
272             HReg reg;
273          } R;
274       } ARMri5;
275    }
276    ARMRI5;
277
278 extern ARMRI5* ARMRI5_I5 ( UInt imm5 );
279 extern ARMRI5* ARMRI5_R  ( HReg );
280
281 extern void ppARMRI5 ( ARMRI5* );
282
283 /* -------- Neon Immediate operand -------- */
284
285 /* imm8 = abcdefgh, B = NOT(b);
286
287 type | value (64bit binary)
288 -----+-------------------------------------------------------------------------
289    0 | 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh
290    1 | 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000
291    2 | 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000
292    3 | abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000
293    4 | 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh
294    5 | abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000
295    6 | abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh
296    7 | 00000000 00000000 abcdefgh 11111111 00000000 00000000 abcdefgh 11111111
297    8 | 00000000 abcdefgh 11111111 11111111 00000000 abcdefgh 11111111 11111111
298    9 | aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
299   10 | aBbbbbbc defgh000 00000000 00000000 aBbbbbbc defgh000 00000000 00000000
300 -----+-------------------------------------------------------------------------
301
302 Type 10 is:
303    (-1)^S * 2^exp * mantissa
304 where S = a, exp = UInt(B:c:d) - 3, mantissa = (16 + UInt(e:f:g:h)) / 16
305 */
306
307 typedef
308    struct {
309       UInt type;
310       UInt imm8;
311    }
312    ARMNImm;
313
314 extern ARMNImm* ARMNImm_TI ( UInt type, UInt imm8 );
315 extern ULong ARMNImm_to_Imm64 ( ARMNImm* );
316 extern ARMNImm* Imm64_to_ARMNImm ( ULong );
317
318 extern void ppARMNImm ( ARMNImm* );
319
320 /* ------ Neon Register or Scalar Operand ------ */
321
322 typedef
323    enum {
324       ARMNRS_Reg=11,
325       ARMNRS_Scalar
326    }
327    ARMNRS_tag;
328
329 typedef
330    struct {
331       ARMNRS_tag tag;
332       HReg reg;
333       UInt index;
334    }
335    ARMNRS;
336
337 extern ARMNRS* mkARMNRS(ARMNRS_tag, HReg reg, UInt index);
338 extern void ppARMNRS ( ARMNRS* );
339
340 /* --------- Instructions. --------- */
341
342 /* --------- */
343 typedef
344    enum {
345       ARMalu_ADD=20,   /* plain 32-bit add */
346       ARMalu_ADDS,     /* 32-bit add, and set the flags */
347       ARMalu_ADC,      /* 32-bit add with carry */
348       ARMalu_SUB,      /* plain 32-bit subtract */
349       ARMalu_SUBS,     /* 32-bit subtract, and set the flags */
350       ARMalu_SBC,      /* 32-bit subtract with carry */
351       ARMalu_AND,
352       ARMalu_BIC,
353       ARMalu_OR,
354       ARMalu_XOR
355    }
356    ARMAluOp;
357
358 extern HChar* showARMAluOp ( ARMAluOp op );
359
360
361 typedef
362    enum {
363       ARMsh_SHL=40,
364       ARMsh_SHR,
365       ARMsh_SAR
366    }
367    ARMShiftOp;
368
369 extern HChar* showARMShiftOp ( ARMShiftOp op );
370
371
372 typedef
373    enum {
374       ARMun_NEG=50,
375       ARMun_NOT,
376       ARMun_CLZ
377    }
378    ARMUnaryOp;
379
380 extern HChar* showARMUnaryOp ( ARMUnaryOp op );
381
382
383 typedef
384    enum {
385       ARMmul_PLAIN=60,
386       ARMmul_ZX,
387       ARMmul_SX
388    }
389    ARMMulOp;
390
391 extern HChar* showARMMulOp ( ARMMulOp op );
392
393
394 typedef
395    enum {
396       ARMvfp_ADD=70,
397       ARMvfp_SUB,
398       ARMvfp_MUL,
399       ARMvfp_DIV
400    }
401    ARMVfpOp;
402
403 extern HChar* showARMVfpOp ( ARMVfpOp op );
404
405
406 typedef
407    enum {
408       ARMvfpu_COPY=80,
409       ARMvfpu_NEG,
410       ARMvfpu_ABS,
411       ARMvfpu_SQRT
412    }
413    ARMVfpUnaryOp;
414
415 extern HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
416
417 typedef
418    enum {
419       ARMneon_VAND=90,
420       ARMneon_VORR,
421       ARMneon_VXOR,
422       ARMneon_VADD,
423       ARMneon_VADDFP,
424       ARMneon_VRHADDS,
425       ARMneon_VRHADDU,
426       ARMneon_VPADDFP,
427       ARMneon_VABDFP,
428       ARMneon_VSUB,
429       ARMneon_VSUBFP,
430       ARMneon_VMAXU,
431       ARMneon_VMAXS,
432       ARMneon_VMAXF,
433       ARMneon_VMINU,
434       ARMneon_VMINS,
435       ARMneon_VMINF,
436       ARMneon_VQADDU,
437       ARMneon_VQADDS,
438       ARMneon_VQSUBU,
439       ARMneon_VQSUBS,
440       ARMneon_VCGTU,
441       ARMneon_VCGTS,
442       ARMneon_VCGEU,
443       ARMneon_VCGES,
444       ARMneon_VCGTF,
445       ARMneon_VCGEF,
446       ARMneon_VCEQ,
447       ARMneon_VCEQF,
448       ARMneon_VEXT,
449       ARMneon_VMUL,
450       ARMneon_VMULFP,
451       ARMneon_VMULLU,
452       ARMneon_VMULLS,
453       ARMneon_VMULP,
454       ARMneon_VMULLP,
455       ARMneon_VQDMULH,
456       ARMneon_VQRDMULH,
457       ARMneon_VPADD,
458       ARMneon_VPMINU,
459       ARMneon_VPMINS,
460       ARMneon_VPMINF,
461       ARMneon_VPMAXU,
462       ARMneon_VPMAXS,
463       ARMneon_VPMAXF,
464       ARMneon_VTBL,
465       ARMneon_VQDMULL,
466       ARMneon_VRECPS,
467       ARMneon_VRSQRTS,
468       /* ... */
469    }
470    ARMNeonBinOp;
471
472 typedef
473    enum {
474       ARMneon_VSHL=150,
475       ARMneon_VSAL, /* Yah, not SAR but SAL */
476       ARMneon_VQSHL,
477       ARMneon_VQSAL
478    }
479    ARMNeonShiftOp;
480
481 typedef
482    enum {
483       ARMneon_COPY=160,
484       ARMneon_COPYLU,
485       ARMneon_COPYLS,
486       ARMneon_COPYN,
487       ARMneon_COPYQNSS,
488       ARMneon_COPYQNUS,
489       ARMneon_COPYQNUU,
490       ARMneon_NOT,
491       ARMneon_EQZ,
492       ARMneon_DUP,
493       ARMneon_PADDLS,
494       ARMneon_PADDLU,
495       ARMneon_CNT,
496       ARMneon_CLZ,
497       ARMneon_CLS,
498       ARMneon_VCVTxFPxINT,
499       ARMneon_VQSHLNSS,
500       ARMneon_VQSHLNUU,
501       ARMneon_VQSHLNUS,
502       ARMneon_VCVTFtoU,
503       ARMneon_VCVTFtoS,
504       ARMneon_VCVTUtoF,
505       ARMneon_VCVTStoF,
506       ARMneon_VCVTFtoFixedU,
507       ARMneon_VCVTFtoFixedS,
508       ARMneon_VCVTFixedUtoF,
509       ARMneon_VCVTFixedStoF,
510       ARMneon_VCVTF16toF32,
511       ARMneon_VCVTF32toF16,
512       ARMneon_REV16,
513       ARMneon_REV32,
514       ARMneon_REV64,
515       ARMneon_ABS,
516       ARMneon_VNEGF,
517       ARMneon_VRECIP,
518       ARMneon_VRECIPF,
519       ARMneon_VABSFP,
520       ARMneon_VRSQRTEFP,
521       ARMneon_VRSQRTE
522       /* ... */
523    }
524    ARMNeonUnOp;
525
526 typedef
527    enum {
528       ARMneon_SETELEM=200,
529       ARMneon_GETELEMU,
530       ARMneon_GETELEMS,
531       ARMneon_VDUP,
532    }
533    ARMNeonUnOpS;
534
535 typedef
536    enum {
537       ARMneon_TRN=210,
538       ARMneon_ZIP,
539       ARMneon_UZP
540       /* ... */
541    }
542    ARMNeonDualOp;
543
544 extern HChar* showARMNeonBinOp ( ARMNeonBinOp op );
545 extern HChar* showARMNeonUnOp ( ARMNeonUnOp op );
546 extern HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
547 extern HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
548 extern HChar* showARMNeonDualOp ( ARMNeonDualOp op );
549 extern HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
550 extern HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
551 extern HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
552 extern HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
553 extern HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
554
555 typedef
556    enum {
557       /* baseline */
558       ARMin_Alu=220,
559       ARMin_Shift,
560       ARMin_Unary,
561       ARMin_CmpOrTst,
562       ARMin_Mov,
563       ARMin_Imm32,
564       ARMin_LdSt32,
565       ARMin_LdSt16,
566       ARMin_LdSt8U,
567       ARMin_Ld8S,
568       ARMin_Goto,
569       ARMin_CMov,
570       ARMin_Call,
571       ARMin_Mul,
572       ARMin_LdrEX,
573       ARMin_StrEX,
574       /* vfp */
575       ARMin_VLdStD,
576       ARMin_VLdStS,
577       ARMin_VAluD,
578       ARMin_VAluS,
579       ARMin_VUnaryD,
580       ARMin_VUnaryS,
581       ARMin_VCmpD,
582       ARMin_VCMovD,
583       ARMin_VCMovS,
584       ARMin_VCvtSD,
585       ARMin_VXferD,
586       ARMin_VXferS,
587       ARMin_VCvtID,
588       ARMin_FPSCR,
589       ARMin_MFence,
590       /* Neon */
591       ARMin_NLdStQ,
592       ARMin_NLdStD,
593       ARMin_NUnary,
594       ARMin_NUnaryS,
595       ARMin_NDual,
596       ARMin_NBinary,
597       ARMin_NBinaryS,
598       ARMin_NShift,
599       ARMin_NeonImm,
600       ARMin_NCMovQ,
601       /* This is not a NEON instruction. Actually there is no corresponding
602          instruction in ARM instruction set at all. We need this one to
603          generate spill/reload of 128-bit registers since current register
604          allocator demands them to consist of no more than two instructions.
605          We will split this instruction into 2 or 3 ARM instructions on the
606          emiting phase.
607
608          NOTE: source and destination registers should be different! */
609       ARMin_Add32
610    }
611    ARMInstrTag;
612
613 /* Destinations are on the LEFT (first operand) */
614
615 typedef
616    struct {
617       ARMInstrTag tag;
618       union {
619          /* ADD/SUB/AND/OR/XOR, vanilla ALU op */
620          struct {
621             ARMAluOp op;
622             HReg     dst;
623             HReg     argL;
624             ARMRI84* argR;
625          } Alu;
626          /* SHL/SHR/SAR, 2nd arg is reg or imm */
627          struct {
628             ARMShiftOp op;
629             HReg       dst;
630             HReg       argL;
631             ARMRI5*    argR;
632          } Shift;
633          /* NOT/NEG/CLZ */
634          struct {
635             ARMUnaryOp op;
636             HReg       dst;
637             HReg       src;
638          } Unary;
639          /* CMP/TST; subtract/and, discard result, set NZCV */
640          struct {
641             Bool     isCmp;
642             HReg     argL;
643             ARMRI84* argR;
644          } CmpOrTst;
645          /* MOV dst, src -- reg-reg (or reg-imm8x4) move */
646          struct {
647             HReg     dst;
648             ARMRI84* src;
649          } Mov;
650          /* Pseudo-insn; make a 32-bit immediate */
651          struct {
652             HReg dst;
653             UInt imm32;
654          } Imm32;
655          /* 32-bit load or store */
656          struct {
657             Bool       isLoad;
658             HReg       rD;
659             ARMAMode1* amode;
660          } LdSt32;
661          /* 16-bit load or store */
662          struct {
663             Bool       isLoad;
664             Bool       signedLoad;
665             HReg       rD;
666             ARMAMode2* amode;
667          } LdSt16;
668          /* 8-bit (unsigned) load or store */
669          struct {
670             Bool       isLoad;
671             HReg       rD;
672             ARMAMode1* amode;
673          } LdSt8U;
674          /* 8-bit signed load */
675          struct {
676             HReg       rD;
677             ARMAMode2* amode;
678          } Ld8S;
679          /* Pseudo-insn.  Go to guest address gnext, on given
680             condition, which could be ARMcc_AL. */
681          struct {
682             IRJumpKind  jk;
683             ARMCondCode cond;
684             HReg        gnext;
685          } Goto;
686          /* Mov src to dst on the given condition, which may not
687             be ARMcc_AL. */
688          struct {
689             ARMCondCode cond;
690             HReg        dst;
691             ARMRI84*    src;
692          } CMov;
693          /* Pseudo-insn.  Call target (an absolute address), on given
694             condition (which could be ARMcc_AL). */
695          struct {
696             ARMCondCode cond;
697             HWord       target;
698             Int         nArgRegs; /* # regs carrying args: 0 .. 4 */
699          } Call;
700          /* (PLAIN) 32 *  32 -> 32:  r0    = r2 * r3
701             (ZX)    32 *u 32 -> 64:  r1:r0 = r2 *u r3
702             (SX)    32 *s 32 -> 64:  r1:r0 = r2 *s r3
703             Why hardwired registers?  Because the ARM ARM specifies
704             (eg for straight MUL) the result (Rd) and the left arg (Rm)
705             may not be the same register.  That's not a constraint we
706             can enforce in the register allocator (without mucho extra
707             complexity).  Hence hardwire it.  At least using caller-saves
708             registers, which are less likely to be in use. */
709          struct {
710             ARMMulOp op;
711          } Mul;
712          /* LDREX{,H,B} r0, [r1]
713             Again, hardwired registers since this is not performance
714             critical, and there are possibly constraints on the
715             registers that we can't express in the register allocator.*/
716          struct {
717             Int  szB; /* currently only 4 is allowed */
718          } LdrEX;
719          /* STREX{,H,B} r0, r1, [r2]
720             r0 = SC( [r2] = r1 )
721             Ditto comment re fixed registers. */
722          struct {
723             Int  szB; /* currently only 4 is allowed */
724          } StrEX;
725          /* VFP INSTRUCTIONS */
726          /* 64-bit Fp load/store */
727          struct {
728             Bool       isLoad;
729             HReg       dD;
730             ARMAModeV* amode;
731          } VLdStD;
732          /* 32-bit Fp load/store */
733          struct {
734             Bool       isLoad;
735             HReg       fD;
736             ARMAModeV* amode;
737          } VLdStS;
738          /* 64-bit FP binary arithmetic */
739          struct {
740             ARMVfpOp op;
741             HReg     dst;
742             HReg     argL;
743             HReg     argR;
744          } VAluD;
745          /* 32-bit FP binary arithmetic */
746          struct {
747             ARMVfpOp op;
748             HReg     dst;
749             HReg     argL;
750             HReg     argR;
751          } VAluS;
752          /* 64-bit FP unary, also reg-reg move */
753          struct {
754             ARMVfpUnaryOp op;
755             HReg          dst;
756             HReg          src;
757          } VUnaryD;
758          /* 32-bit FP unary, also reg-reg move */
759          struct {
760             ARMVfpUnaryOp op;
761             HReg          dst;
762             HReg          src;
763          } VUnaryS;
764          /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */
765          struct {
766             HReg argL;
767             HReg argR;
768          } VCmpD;
769          /* 64-bit FP mov src to dst on the given condition, which may
770             not be ARMcc_AL. */
771          struct {
772             ARMCondCode cond;
773             HReg        dst;
774             HReg        src;
775          } VCMovD;
776          /* 32-bit FP mov src to dst on the given condition, which may
777             not be ARMcc_AL. */
778          struct {
779             ARMCondCode cond;
780             HReg        dst;
781             HReg        src;
782          } VCMovS;
783          /* Convert between 32-bit and 64-bit FP values (both ways).
784             (FCVTSD, FCVTDS) */
785          struct {
786             Bool sToD; /* True: F32->F64.  False: F64->F32 */
787             HReg dst;
788             HReg src;
789          } VCvtSD;
790          /* Transfer a VFP D reg to/from two integer registers (VMOV) */
791          struct {
792             Bool toD;
793             HReg dD;
794             HReg rHi;
795             HReg rLo;
796          } VXferD;
797          /* Transfer a VFP S reg to/from an integer register (VMOV) */
798          struct {
799             Bool toS;
800             HReg fD;
801             HReg rLo;
802          } VXferS;
803          /* Convert between 32-bit ints and 64-bit FP values (both ways
804             and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
805          struct {
806             Bool iToD; /* True: I32->F64.  False: F64->I32 */
807             Bool syned; /* True: I32 is signed.  False: I32 is unsigned */
808             HReg dst;
809             HReg src;
810          } VCvtID;
811          /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
812          struct {
813             Bool toFPSCR;
814             HReg iReg;
815          } FPSCR;
816          /* Mem fence.  An insn which fences all loads and stores as
817             much as possible before continuing.  On ARM we emit the
818             sequence
819                mcr 15,0,r0,c7,c10,4 (DSB)
820                mcr 15,0,r0,c7,c10,5 (DMB)
821                mcr 15,0,r0,c7,c5,4 (ISB)
822             which is probably total overkill, but better safe than
823             sorry.
824          */
825          struct {
826          } MFence;
827          /* Neon data processing instruction: 3 registers of the same
828             length */
829          struct {
830             ARMNeonBinOp op;
831             HReg dst;
832             HReg argL;
833             HReg argR;
834             UInt size;
835             Bool Q;
836          } NBinary;
837          struct {
838             ARMNeonBinOp op;
839             ARMNRS* dst;
840             ARMNRS* argL;
841             ARMNRS* argR;
842             UInt size;
843             Bool Q;
844          } NBinaryS;
845          struct {
846             ARMNeonShiftOp op;
847             HReg dst;
848             HReg argL;
849             HReg argR;
850             UInt size;
851             Bool Q;
852          } NShift;
853          struct {
854             Bool isLoad;
855             HReg dQ;
856             ARMAModeN *amode;
857          } NLdStQ;
858          struct {
859             Bool isLoad;
860             HReg dD;
861             ARMAModeN *amode;
862          } NLdStD;
863          struct {
864             ARMNeonUnOpS op;
865             ARMNRS*  dst;
866             ARMNRS*  src;
867             UInt size;
868             Bool Q;
869          } NUnaryS;
870          struct {
871             ARMNeonUnOp op;
872             HReg  dst;
873             HReg  src;
874             UInt size;
875             Bool Q;
876          } NUnary;
877          /* Takes two arguments and modifies them both. */
878          struct {
879             ARMNeonDualOp op;
880             HReg  arg1;
881             HReg  arg2;
882             UInt size;
883             Bool Q;
884          } NDual;
885          struct {
886             HReg dst;
887             ARMNImm* imm;
888          } NeonImm;
889          /* 128-bit Neon move src to dst on the given condition, which
890             may not be ARMcc_AL. */
891          struct {
892             ARMCondCode cond;
893             HReg        dst;
894             HReg        src;
895          } NCMovQ;
896          struct {
897             /* Note: rD != rN */
898             HReg rD;
899             HReg rN;
900             UInt imm32;
901          } Add32;
902       } ARMin;
903    }
904    ARMInstr;
905
906
907 extern ARMInstr* ARMInstr_Alu      ( ARMAluOp, HReg, HReg, ARMRI84* );
908 extern ARMInstr* ARMInstr_Shift    ( ARMShiftOp, HReg, HReg, ARMRI5* );
909 extern ARMInstr* ARMInstr_Unary    ( ARMUnaryOp, HReg, HReg );
910 extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
911 extern ARMInstr* ARMInstr_Mov      ( HReg, ARMRI84* );
912 extern ARMInstr* ARMInstr_Imm32    ( HReg, UInt );
913 extern ARMInstr* ARMInstr_LdSt32   ( Bool isLoad, HReg, ARMAMode1* );
914 extern ARMInstr* ARMInstr_LdSt16   ( Bool isLoad, Bool signedLoad,
915                                      HReg, ARMAMode2* );
916 extern ARMInstr* ARMInstr_LdSt8U   ( Bool isLoad, HReg, ARMAMode1* );
917 extern ARMInstr* ARMInstr_Ld8S     ( HReg, ARMAMode2* );
918 extern ARMInstr* ARMInstr_Goto     ( IRJumpKind, ARMCondCode, HReg gnext );
919 extern ARMInstr* ARMInstr_CMov     ( ARMCondCode, HReg dst, ARMRI84* src );
920 extern ARMInstr* ARMInstr_Call     ( ARMCondCode, HWord, Int nArgRegs );
921 extern ARMInstr* ARMInstr_Mul      ( ARMMulOp op );
922 extern ARMInstr* ARMInstr_LdrEX    ( Int szB );
923 extern ARMInstr* ARMInstr_StrEX    ( Int szB );
924 extern ARMInstr* ARMInstr_VLdStD   ( Bool isLoad, HReg, ARMAModeV* );
925 extern ARMInstr* ARMInstr_VLdStS   ( Bool isLoad, HReg, ARMAModeV* );
926 extern ARMInstr* ARMInstr_VAluD    ( ARMVfpOp op, HReg, HReg, HReg );
927 extern ARMInstr* ARMInstr_VAluS    ( ARMVfpOp op, HReg, HReg, HReg );
928 extern ARMInstr* ARMInstr_VUnaryD  ( ARMVfpUnaryOp, HReg dst, HReg src );
929 extern ARMInstr* ARMInstr_VUnaryS  ( ARMVfpUnaryOp, HReg dst, HReg src );
930 extern ARMInstr* ARMInstr_VCmpD    ( HReg argL, HReg argR );
931 extern ARMInstr* ARMInstr_VCMovD   ( ARMCondCode, HReg dst, HReg src );
932 extern ARMInstr* ARMInstr_VCMovS   ( ARMCondCode, HReg dst, HReg src );
933 extern ARMInstr* ARMInstr_VCvtSD   ( Bool sToD, HReg dst, HReg src );
934 extern ARMInstr* ARMInstr_VXferD   ( Bool toD, HReg dD, HReg rHi, HReg rLo );
935 extern ARMInstr* ARMInstr_VXferS   ( Bool toS, HReg fD, HReg rLo );
936 extern ARMInstr* ARMInstr_VCvtID   ( Bool iToD, Bool syned,
937                                      HReg dst, HReg src );
938 extern ARMInstr* ARMInstr_FPSCR    ( Bool toFPSCR, HReg iReg );
939 extern ARMInstr* ARMInstr_MFence   ( void );
940 extern ARMInstr* ARMInstr_NLdStQ   ( Bool isLoad, HReg, ARMAModeN* );
941 extern ARMInstr* ARMInstr_NLdStD   ( Bool isLoad, HReg, ARMAModeN* );
942 extern ARMInstr* ARMInstr_NUnary   ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
943 extern ARMInstr* ARMInstr_NUnaryS  ( ARMNeonUnOpS, ARMNRS*, ARMNRS*,
944                                      UInt, Bool );
945 extern ARMInstr* ARMInstr_NDual    ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
946 extern ARMInstr* ARMInstr_NBinary  ( ARMNeonBinOp, HReg, HReg, HReg,
947                                      UInt, Bool );
948 extern ARMInstr* ARMInstr_NShift   ( ARMNeonShiftOp, HReg, HReg, HReg,
949                                      UInt, Bool );
950 extern ARMInstr* ARMInstr_NeonImm  ( HReg, ARMNImm* );
951 extern ARMInstr* ARMInstr_NCMovQ   ( ARMCondCode, HReg, HReg );
952 extern ARMInstr* ARMInstr_Add32    ( HReg rD, HReg rN, UInt imm32 );
953
954 extern void ppARMInstr ( ARMInstr* );
955
956
957 /* Some functions that insulate the register allocator from details
958    of the underlying instruction set. */
959 extern void getRegUsage_ARMInstr ( HRegUsage*, ARMInstr*, Bool );
960 extern void mapRegs_ARMInstr     ( HRegRemap*, ARMInstr*, Bool );
961 extern Bool isMove_ARMInstr      ( ARMInstr*, HReg*, HReg* );
962 extern Int  emit_ARMInstr        ( UChar* buf, Int nbuf, ARMInstr*, 
963                                    Bool, void* dispatch );
964
965 extern void genSpill_ARM  ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
966                             HReg rreg, Int offset, Bool );
967 extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
968                             HReg rreg, Int offset, Bool );
969
970 extern void getAllocableRegs_ARM ( Int*, HReg** );
971 extern HInstrArray* iselSB_ARM   ( IRSB*, VexArch,
972                                    VexArchInfo*, VexAbiInfo* );
973
974 #endif /* ndef __VEX_HOST_ARM_DEFS_H */
975
976 /*---------------------------------------------------------------*/
977 /*--- end                                     host_arm_defs.h ---*/
978 /*---------------------------------------------------------------*/