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