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
33extern UInt arm_hwcaps;
34
35
36/* --------- Registers. --------- */
37
38/* The usual HReg abstraction.
39   There are 16 general purpose regs.
40*/
41
42extern void ppHRegARM ( HReg );
43
44extern HReg hregARM_R0  ( void );
45extern HReg hregARM_R1  ( void );
46extern HReg hregARM_R2  ( void );
47extern HReg hregARM_R3  ( void );
48extern HReg hregARM_R4  ( void );
49extern HReg hregARM_R5  ( void );
50extern HReg hregARM_R6  ( void );
51extern HReg hregARM_R7  ( void );
52extern HReg hregARM_R8  ( void );
53extern HReg hregARM_R9  ( void );
54extern HReg hregARM_R10 ( void );
55extern HReg hregARM_R11 ( void );
56extern HReg hregARM_R12 ( void );
57extern HReg hregARM_R13 ( void );
58extern HReg hregARM_R14 ( void );
59extern HReg hregARM_R15 ( void );
60extern HReg hregARM_D8  ( void );
61extern HReg hregARM_D9  ( void );
62extern HReg hregARM_D10 ( void );
63extern HReg hregARM_D11 ( void );
64extern HReg hregARM_D12 ( void );
65extern HReg hregARM_S26 ( void );
66extern HReg hregARM_S27 ( void );
67extern HReg hregARM_S28 ( void );
68extern HReg hregARM_S29 ( void );
69extern HReg hregARM_S30 ( void );
70extern HReg hregARM_Q8  ( void );
71extern HReg hregARM_Q9  ( void );
72extern HReg hregARM_Q10 ( void );
73extern HReg hregARM_Q11 ( void );
74extern HReg hregARM_Q12 ( void );
75extern HReg hregARM_Q13 ( void );
76extern HReg hregARM_Q14 ( void );
77extern 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
85typedef
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
113extern HChar* showARMCondCode ( ARMCondCode );
114
115
116
117/* --------- Memory address expressions (amodes). --------- */
118
119/* --- Addressing Mode 1 --- */
120typedef
121   enum {
122      ARMam1_RI=1,   /* reg +/- imm12 */
123      ARMam1_RRS     /* reg1 + (reg2 << 0, 1 2 or 3) */
124   }
125   ARMAMode1Tag;
126
127typedef
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
144extern ARMAMode1* ARMAMode1_RI  ( HReg reg, Int simm13 );
145extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift );
146
147extern void ppARMAMode1 ( ARMAMode1* );
148
149
150/* --- Addressing Mode 2 --- */
151typedef
152   enum {
153      ARMam2_RI=3,   /* reg +/- imm8 */
154      ARMam2_RR      /* reg1 + reg2 */
155   }
156   ARMAMode2Tag;
157
158typedef
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
174extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 );
175extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index );
176
177extern 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. */
183typedef
184   struct {
185      HReg reg;
186      Int  simm11; /* -1020, -1016 .. 1016, 1020 */
187   }
188   ARMAModeV;
189
190extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 );
191
192extern void ppARMAModeV ( ARMAModeV* );
193
194/* --- Addressing Mode suitable for Neon --- */
195typedef
196   enum {
197      ARMamN_R=5,
198      ARMamN_RR
199      /* ... */
200   }
201   ARMAModeNTag;
202
203typedef
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
219extern ARMAModeN* mkARMAModeN_RR ( HReg, HReg );
220extern ARMAModeN* mkARMAModeN_R ( HReg );
221extern 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
227typedef
228   enum {
229      ARMri84_I84=7,   /* imm8 `ror` (2 * imm4) */
230      ARMri84_R        /* reg */
231   }
232   ARMRI84Tag;
233
234typedef
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
249extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 );
250extern ARMRI84* ARMRI84_R   ( HReg );
251
252extern void ppARMRI84 ( ARMRI84* );
253
254
255/* --------- Reg or imm5 operands --------- */
256typedef
257   enum {
258      ARMri5_I5=9,   /* imm5, 1 .. 31 only (no zero!) */
259      ARMri5_R       /* reg */
260   }
261   ARMRI5Tag;
262
263typedef
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
277extern ARMRI5* ARMRI5_I5 ( UInt imm5 );
278extern ARMRI5* ARMRI5_R  ( HReg );
279
280extern void ppARMRI5 ( ARMRI5* );
281
282/* -------- Neon Immediate operand -------- */
283
284/* imm8 = abcdefgh, B = NOT(b);
285
286type | 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
301Type 10 is:
302   (-1)^S * 2^exp * mantissa
303where S = a, exp = UInt(B:c:d) - 3, mantissa = (16 + UInt(e:f:g:h)) / 16
304*/
305
306typedef
307   struct {
308      UInt type;
309      UInt imm8;
310   }
311   ARMNImm;
312
313extern ARMNImm* ARMNImm_TI ( UInt type, UInt imm8 );
314extern ULong ARMNImm_to_Imm64 ( ARMNImm* );
315extern ARMNImm* Imm64_to_ARMNImm ( ULong );
316
317extern void ppARMNImm ( ARMNImm* );
318
319/* ------ Neon Register or Scalar Operand ------ */
320
321typedef
322   enum {
323      ARMNRS_Reg=11,
324      ARMNRS_Scalar
325   }
326   ARMNRS_tag;
327
328typedef
329   struct {
330      ARMNRS_tag tag;
331      HReg reg;
332      UInt index;
333   }
334   ARMNRS;
335
336extern ARMNRS* mkARMNRS(ARMNRS_tag, HReg reg, UInt index);
337extern void ppARMNRS ( ARMNRS* );
338
339/* --------- Instructions. --------- */
340
341/* --------- */
342typedef
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
357extern HChar* showARMAluOp ( ARMAluOp op );
358
359
360typedef
361   enum {
362      ARMsh_SHL=40,
363      ARMsh_SHR,
364      ARMsh_SAR
365   }
366   ARMShiftOp;
367
368extern HChar* showARMShiftOp ( ARMShiftOp op );
369
370
371typedef
372   enum {
373      ARMun_NEG=50,
374      ARMun_NOT,
375      ARMun_CLZ
376   }
377   ARMUnaryOp;
378
379extern HChar* showARMUnaryOp ( ARMUnaryOp op );
380
381
382typedef
383   enum {
384      ARMmul_PLAIN=60,
385      ARMmul_ZX,
386      ARMmul_SX
387   }
388   ARMMulOp;
389
390extern HChar* showARMMulOp ( ARMMulOp op );
391
392
393typedef
394   enum {
395      ARMvfp_ADD=70,
396      ARMvfp_SUB,
397      ARMvfp_MUL,
398      ARMvfp_DIV
399   }
400   ARMVfpOp;
401
402extern HChar* showARMVfpOp ( ARMVfpOp op );
403
404
405typedef
406   enum {
407      ARMvfpu_COPY=80,
408      ARMvfpu_NEG,
409      ARMvfpu_ABS,
410      ARMvfpu_SQRT
411   }
412   ARMVfpUnaryOp;
413
414extern HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
415
416typedef
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
471typedef
472   enum {
473      ARMneon_VSHL=150,
474      ARMneon_VSAL, /* Yah, not SAR but SAL */
475      ARMneon_VQSHL,
476      ARMneon_VQSAL
477   }
478   ARMNeonShiftOp;
479
480typedef
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
525typedef
526   enum {
527      ARMneon_SETELEM=200,
528      ARMneon_GETELEMU,
529      ARMneon_GETELEMS,
530      ARMneon_VDUP,
531   }
532   ARMNeonUnOpS;
533
534typedef
535   enum {
536      ARMneon_TRN=210,
537      ARMneon_ZIP,
538      ARMneon_UZP
539      /* ... */
540   }
541   ARMNeonDualOp;
542
543extern HChar* showARMNeonBinOp ( ARMNeonBinOp op );
544extern HChar* showARMNeonUnOp ( ARMNeonUnOp op );
545extern HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
546extern HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
547extern HChar* showARMNeonDualOp ( ARMNeonDualOp op );
548extern HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
549extern HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
550extern HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
551extern HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
552extern HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
553
554typedef
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
615typedef
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
913extern ARMInstr* ARMInstr_Alu      ( ARMAluOp, HReg, HReg, ARMRI84* );
914extern ARMInstr* ARMInstr_Shift    ( ARMShiftOp, HReg, HReg, ARMRI5* );
915extern ARMInstr* ARMInstr_Unary    ( ARMUnaryOp, HReg, HReg );
916extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
917extern ARMInstr* ARMInstr_Mov      ( HReg, ARMRI84* );
918extern ARMInstr* ARMInstr_Imm32    ( HReg, UInt );
919extern ARMInstr* ARMInstr_LdSt32   ( Bool isLoad, HReg, ARMAMode1* );
920extern ARMInstr* ARMInstr_LdSt16   ( Bool isLoad, Bool signedLoad,
921                                     HReg, ARMAMode2* );
922extern ARMInstr* ARMInstr_LdSt8U   ( Bool isLoad, HReg, ARMAMode1* );
923extern ARMInstr* ARMInstr_Ld8S     ( HReg, ARMAMode2* );
924extern ARMInstr* ARMInstr_Goto     ( IRJumpKind, ARMCondCode, HReg gnext );
925extern ARMInstr* ARMInstr_CMov     ( ARMCondCode, HReg dst, ARMRI84* src );
926extern ARMInstr* ARMInstr_Call     ( ARMCondCode, HWord, Int nArgRegs );
927extern ARMInstr* ARMInstr_Mul      ( ARMMulOp op );
928extern ARMInstr* ARMInstr_LdrEX    ( Int szB );
929extern ARMInstr* ARMInstr_StrEX    ( Int szB );
930extern ARMInstr* ARMInstr_VLdStD   ( Bool isLoad, HReg, ARMAModeV* );
931extern ARMInstr* ARMInstr_VLdStS   ( Bool isLoad, HReg, ARMAModeV* );
932extern ARMInstr* ARMInstr_VAluD    ( ARMVfpOp op, HReg, HReg, HReg );
933extern ARMInstr* ARMInstr_VAluS    ( ARMVfpOp op, HReg, HReg, HReg );
934extern ARMInstr* ARMInstr_VUnaryD  ( ARMVfpUnaryOp, HReg dst, HReg src );
935extern ARMInstr* ARMInstr_VUnaryS  ( ARMVfpUnaryOp, HReg dst, HReg src );
936extern ARMInstr* ARMInstr_VCmpD    ( HReg argL, HReg argR );
937extern ARMInstr* ARMInstr_VCMovD   ( ARMCondCode, HReg dst, HReg src );
938extern ARMInstr* ARMInstr_VCMovS   ( ARMCondCode, HReg dst, HReg src );
939extern ARMInstr* ARMInstr_VCvtSD   ( Bool sToD, HReg dst, HReg src );
940extern ARMInstr* ARMInstr_VXferD   ( Bool toD, HReg dD, HReg rHi, HReg rLo );
941extern ARMInstr* ARMInstr_VXferS   ( Bool toS, HReg fD, HReg rLo );
942extern ARMInstr* ARMInstr_VCvtID   ( Bool iToD, Bool syned,
943                                     HReg dst, HReg src );
944extern ARMInstr* ARMInstr_FPSCR    ( Bool toFPSCR, HReg iReg );
945extern ARMInstr* ARMInstr_MFence   ( void );
946extern ARMInstr* ARMInstr_CLREX    ( void );
947extern ARMInstr* ARMInstr_NLdStQ   ( Bool isLoad, HReg, ARMAModeN* );
948extern ARMInstr* ARMInstr_NLdStD   ( Bool isLoad, HReg, ARMAModeN* );
949extern ARMInstr* ARMInstr_NUnary   ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
950extern ARMInstr* ARMInstr_NUnaryS  ( ARMNeonUnOpS, ARMNRS*, ARMNRS*,
951                                     UInt, Bool );
952extern ARMInstr* ARMInstr_NDual    ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
953extern ARMInstr* ARMInstr_NBinary  ( ARMNeonBinOp, HReg, HReg, HReg,
954                                     UInt, Bool );
955extern ARMInstr* ARMInstr_NShift   ( ARMNeonShiftOp, HReg, HReg, HReg,
956                                     UInt, Bool );
957extern ARMInstr* ARMInstr_NeonImm  ( HReg, ARMNImm* );
958extern ARMInstr* ARMInstr_NCMovQ   ( ARMCondCode, HReg, HReg );
959extern ARMInstr* ARMInstr_Add32    ( HReg rD, HReg rN, UInt imm32 );
960
961extern void ppARMInstr ( ARMInstr* );
962
963
964/* Some functions that insulate the register allocator from details
965   of the underlying instruction set. */
966extern void getRegUsage_ARMInstr ( HRegUsage*, ARMInstr*, Bool );
967extern void mapRegs_ARMInstr     ( HRegRemap*, ARMInstr*, Bool );
968extern Bool isMove_ARMInstr      ( ARMInstr*, HReg*, HReg* );
969extern Int  emit_ARMInstr        ( UChar* buf, Int nbuf, ARMInstr*,
970                                   Bool,
971                                   void* dispatch_unassisted,
972                                   void* dispatch_assisted );
973
974extern void genSpill_ARM  ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
975                            HReg rreg, Int offset, Bool );
976extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
977                            HReg rreg, Int offset, Bool );
978
979extern void getAllocableRegs_ARM ( Int*, HReg** );
980extern 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