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