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-2013 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_VXferD,
595      ARMin_VXferS,
596      ARMin_VCvtID,
597      ARMin_FPSCR,
598      ARMin_MFence,
599      ARMin_CLREX,
600      /* Neon */
601      ARMin_NLdStQ,
602      ARMin_NLdStD,
603      ARMin_NUnary,
604      ARMin_NUnaryS,
605      ARMin_NDual,
606      ARMin_NBinary,
607      ARMin_NBinaryS,
608      ARMin_NShift,
609      ARMin_NShl64, // special case 64-bit shift of Dreg by immediate
610      ARMin_NeonImm,
611      ARMin_NCMovQ,
612      /* This is not a NEON instruction. Actually there is no corresponding
613         instruction in ARM instruction set at all. We need this one to
614         generate spill/reload of 128-bit registers since current register
615         allocator demands them to consist of no more than two instructions.
616         We will split this instruction into 2 or 3 ARM instructions on the
617         emiting phase.
618         NOTE: source and destination registers should be different! */
619      ARMin_Add32,
620      ARMin_EvCheck,     /* Event check */
621      ARMin_ProfInc      /* 64-bit profile counter increment */
622   }
623   ARMInstrTag;
624
625/* Destinations are on the LEFT (first operand) */
626
627typedef
628   struct {
629      ARMInstrTag tag;
630      union {
631         /* ADD/SUB/AND/OR/XOR, vanilla ALU op */
632         struct {
633            ARMAluOp op;
634            HReg     dst;
635            HReg     argL;
636            ARMRI84* argR;
637         } Alu;
638         /* SHL/SHR/SAR, 2nd arg is reg or imm */
639         struct {
640            ARMShiftOp op;
641            HReg       dst;
642            HReg       argL;
643            ARMRI5*    argR;
644         } Shift;
645         /* NOT/NEG/CLZ */
646         struct {
647            ARMUnaryOp op;
648            HReg       dst;
649            HReg       src;
650         } Unary;
651         /* CMP/TST; subtract/and, discard result, set NZCV */
652         struct {
653            Bool     isCmp;
654            HReg     argL;
655            ARMRI84* argR;
656         } CmpOrTst;
657         /* MOV dst, src -- reg-reg (or reg-imm8x4) move */
658         struct {
659            HReg     dst;
660            ARMRI84* src;
661         } Mov;
662         /* Pseudo-insn; make a 32-bit immediate */
663         struct {
664            HReg dst;
665            UInt imm32;
666         } Imm32;
667         /* 32-bit load or store, may be conditional */
668         struct {
669            ARMCondCode cc; /* ARMcc_NV is not allowed */
670            Bool        isLoad;
671            HReg        rD;
672            ARMAMode1*  amode;
673         } LdSt32;
674         /* 16-bit load or store, may be conditional */
675         struct {
676            ARMCondCode cc; /* ARMcc_NV is not allowed */
677            Bool        isLoad;
678            Bool        signedLoad;
679            HReg        rD;
680            ARMAMode2*  amode;
681         } LdSt16;
682         /* 8-bit (unsigned) load or store, may be conditional */
683         struct {
684            ARMCondCode cc; /* ARMcc_NV is not allowed */
685            Bool        isLoad;
686            HReg        rD;
687            ARMAMode1*  amode;
688         } LdSt8U;
689         /* 8-bit signed load, may be conditional */
690         struct {
691            ARMCondCode cc; /* ARMcc_NV is not allowed */
692            HReg        rD;
693            ARMAMode2*  amode;
694         } Ld8S;
695         /* Update the guest R15T value, then exit requesting to chain
696            to it.  May be conditional.  Urr, use of Addr32 implicitly
697            assumes that wordsize(guest) == wordsize(host). */
698         struct {
699            Addr32      dstGA;    /* next guest address */
700            ARMAMode1*  amR15T;   /* amode in guest state for R15T */
701            ARMCondCode cond;     /* can be ARMcc_AL */
702            Bool        toFastEP; /* chain to the slow or fast point? */
703         } XDirect;
704         /* Boring transfer to a guest address not known at JIT time.
705            Not chainable.  May be conditional. */
706         struct {
707            HReg        dstGA;
708            ARMAMode1*  amR15T;
709            ARMCondCode cond; /* can be ARMcc_AL */
710         } XIndir;
711         /* Assisted transfer to a guest address, most general case.
712            Not chainable.  May be conditional. */
713         struct {
714            HReg        dstGA;
715            ARMAMode1*  amR15T;
716            ARMCondCode cond; /* can be ARMcc_AL */
717            IRJumpKind  jk;
718         } XAssisted;
719         /* Mov src to dst on the given condition, which may not
720            be ARMcc_AL. */
721         struct {
722            ARMCondCode cond;
723            HReg        dst;
724            ARMRI84*    src;
725         } CMov;
726         /* Pseudo-insn.  Call target (an absolute address), on given
727            condition (which could be ARMcc_AL). */
728         struct {
729            ARMCondCode cond;
730            Addr32      target;
731            Int         nArgRegs; /* # regs carrying args: 0 .. 4 */
732            RetLoc      rloc;     /* where the return value will be */
733         } Call;
734         /* (PLAIN) 32 *  32 -> 32:  r0    = r2 * r3
735            (ZX)    32 *u 32 -> 64:  r1:r0 = r2 *u r3
736            (SX)    32 *s 32 -> 64:  r1:r0 = r2 *s r3
737            Why hardwired registers?  Because the ARM ARM specifies
738            (eg for straight MUL) the result (Rd) and the left arg (Rm)
739            may not be the same register.  That's not a constraint we
740            can enforce in the register allocator (without mucho extra
741            complexity).  Hence hardwire it.  At least using caller-saves
742            registers, which are less likely to be in use. */
743         struct {
744            ARMMulOp op;
745         } Mul;
746         /* LDREX{,H,B} r2, [r4]  and
747            LDREXD r2, r3, [r4]   (on LE hosts, transferred value is r3:r2)
748            Again, hardwired registers since this is not performance
749            critical, and there are possibly constraints on the
750            registers that we can't express in the register allocator.*/
751         struct {
752            Int  szB; /* 1, 2, 4 or 8 */
753         } LdrEX;
754         /* STREX{,H,B} r0, r2, [r4]  and
755            STREXD r0, r2, r3, [r4]   (on LE hosts, transferred value is r3:r2)
756            r0 = SC( [r4] = r2 )      (8, 16, 32 bit transfers)
757            r0 = SC( [r4] = r3:r2)    (64 bit transfers)
758            Ditto comment re fixed registers. */
759         struct {
760            Int  szB; /* 1, 2, 4 or 8 */
761         } StrEX;
762         /* VFP INSTRUCTIONS */
763         /* 64-bit Fp load/store */
764         struct {
765            Bool       isLoad;
766            HReg       dD;
767            ARMAModeV* amode;
768         } VLdStD;
769         /* 32-bit Fp load/store */
770         struct {
771            Bool       isLoad;
772            HReg       fD;
773            ARMAModeV* amode;
774         } VLdStS;
775         /* 64-bit FP binary arithmetic */
776         struct {
777            ARMVfpOp op;
778            HReg     dst;
779            HReg     argL;
780            HReg     argR;
781         } VAluD;
782         /* 32-bit FP binary arithmetic */
783         struct {
784            ARMVfpOp op;
785            HReg     dst;
786            HReg     argL;
787            HReg     argR;
788         } VAluS;
789         /* 64-bit FP unary, also reg-reg move */
790         struct {
791            ARMVfpUnaryOp op;
792            HReg          dst;
793            HReg          src;
794         } VUnaryD;
795         /* 32-bit FP unary, also reg-reg move */
796         struct {
797            ARMVfpUnaryOp op;
798            HReg          dst;
799            HReg          src;
800         } VUnaryS;
801         /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */
802         struct {
803            HReg argL;
804            HReg argR;
805         } VCmpD;
806         /* 64-bit FP mov src to dst on the given condition, which may
807            not be ARMcc_AL. */
808         struct {
809            ARMCondCode cond;
810            HReg        dst;
811            HReg        src;
812         } VCMovD;
813         /* 32-bit FP mov src to dst on the given condition, which may
814            not be ARMcc_AL. */
815         struct {
816            ARMCondCode cond;
817            HReg        dst;
818            HReg        src;
819         } VCMovS;
820         /* Convert between 32-bit and 64-bit FP values (both ways).
821            (FCVTSD, FCVTDS) */
822         struct {
823            Bool sToD; /* True: F32->F64.  False: F64->F32 */
824            HReg dst;
825            HReg src;
826         } VCvtSD;
827         /* Transfer a VFP D reg to/from two integer registers (VMOV) */
828         struct {
829            Bool toD;
830            HReg dD;
831            HReg rHi;
832            HReg rLo;
833         } VXferD;
834         /* Transfer a VFP S reg to/from an integer register (VMOV) */
835         struct {
836            Bool toS;
837            HReg fD;
838            HReg rLo;
839         } VXferS;
840         /* Convert between 32-bit ints and 64-bit FP values (both ways
841            and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
842         struct {
843            Bool iToD; /* True: I32->F64.  False: F64->I32 */
844            Bool syned; /* True: I32 is signed.  False: I32 is unsigned */
845            HReg dst;
846            HReg src;
847         } VCvtID;
848         /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
849         struct {
850            Bool toFPSCR;
851            HReg iReg;
852         } FPSCR;
853         /* Mem fence.  An insn which fences all loads and stores as
854            much as possible before continuing.  On ARM we emit the
855            sequence
856               mcr 15,0,r0,c7,c10,4 (DSB)
857               mcr 15,0,r0,c7,c10,5 (DMB)
858               mcr 15,0,r0,c7,c5,4 (ISB)
859            which is probably total overkill, but better safe than
860            sorry.
861         */
862         struct {
863         } MFence;
864         /* A CLREX instruction. */
865         struct {
866         } CLREX;
867         /* Neon data processing instruction: 3 registers of the same
868            length */
869         struct {
870            ARMNeonBinOp op;
871            HReg dst;
872            HReg argL;
873            HReg argR;
874            UInt size;
875            Bool Q;
876         } NBinary;
877         struct {
878            ARMNeonBinOp op;
879            ARMNRS* dst;
880            ARMNRS* argL;
881            ARMNRS* argR;
882            UInt size;
883            Bool Q;
884         } NBinaryS;
885         struct {
886            ARMNeonShiftOp op;
887            HReg dst;
888            HReg argL;
889            HReg argR;
890            UInt size;
891            Bool Q;
892         } NShift;
893         struct {
894            HReg dst;
895            HReg src;
896            UInt amt; /* 1..63 only */
897         } NShl64;
898         struct {
899            Bool isLoad;
900            HReg dQ;
901            ARMAModeN *amode;
902         } NLdStQ;
903         struct {
904            Bool isLoad;
905            HReg dD;
906            ARMAModeN *amode;
907         } NLdStD;
908         struct {
909            ARMNeonUnOpS op;
910            ARMNRS*  dst;
911            ARMNRS*  src;
912            UInt size;
913            Bool Q;
914         } NUnaryS;
915         struct {
916            ARMNeonUnOp op;
917            HReg  dst;
918            HReg  src;
919            UInt size;
920            Bool Q;
921         } NUnary;
922         /* Takes two arguments and modifies them both. */
923         struct {
924            ARMNeonDualOp op;
925            HReg  arg1;
926            HReg  arg2;
927            UInt size;
928            Bool Q;
929         } NDual;
930         struct {
931            HReg dst;
932            ARMNImm* imm;
933         } NeonImm;
934         /* 128-bit Neon move src to dst on the given condition, which
935            may not be ARMcc_AL. */
936         struct {
937            ARMCondCode cond;
938            HReg        dst;
939            HReg        src;
940         } NCMovQ;
941         struct {
942            /* Note: rD != rN */
943            HReg rD;
944            HReg rN;
945            UInt imm32;
946         } Add32;
947         struct {
948            ARMAMode1* amCounter;
949            ARMAMode1* amFailAddr;
950         } EvCheck;
951         struct {
952            /* No fields.  The address of the counter to inc is
953               installed later, post-translation, by patching it in,
954               as it is not known at translation time. */
955         } ProfInc;
956      } ARMin;
957   }
958   ARMInstr;
959
960
961extern ARMInstr* ARMInstr_Alu      ( ARMAluOp, HReg, HReg, ARMRI84* );
962extern ARMInstr* ARMInstr_Shift    ( ARMShiftOp, HReg, HReg, ARMRI5* );
963extern ARMInstr* ARMInstr_Unary    ( ARMUnaryOp, HReg, HReg );
964extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
965extern ARMInstr* ARMInstr_Mov      ( HReg, ARMRI84* );
966extern ARMInstr* ARMInstr_Imm32    ( HReg, UInt );
967extern ARMInstr* ARMInstr_LdSt32   ( ARMCondCode,
968                                     Bool isLoad, HReg, ARMAMode1* );
969extern ARMInstr* ARMInstr_LdSt16   ( ARMCondCode,
970                                     Bool isLoad, Bool signedLoad,
971                                     HReg, ARMAMode2* );
972extern ARMInstr* ARMInstr_LdSt8U   ( ARMCondCode,
973                                     Bool isLoad, HReg, ARMAMode1* );
974extern ARMInstr* ARMInstr_Ld8S     ( ARMCondCode, HReg, ARMAMode2* );
975extern ARMInstr* ARMInstr_XDirect  ( Addr32 dstGA, ARMAMode1* amR15T,
976                                     ARMCondCode cond, Bool toFastEP );
977extern ARMInstr* ARMInstr_XIndir   ( HReg dstGA, ARMAMode1* amR15T,
978                                     ARMCondCode cond );
979extern ARMInstr* ARMInstr_XAssisted ( HReg dstGA, ARMAMode1* amR15T,
980                                      ARMCondCode cond, IRJumpKind jk );
981extern ARMInstr* ARMInstr_CMov     ( ARMCondCode, HReg dst, ARMRI84* src );
982extern ARMInstr* ARMInstr_Call     ( ARMCondCode, Addr32, Int nArgRegs,
983                                     RetLoc rloc );
984extern ARMInstr* ARMInstr_Mul      ( ARMMulOp op );
985extern ARMInstr* ARMInstr_LdrEX    ( Int szB );
986extern ARMInstr* ARMInstr_StrEX    ( Int szB );
987extern ARMInstr* ARMInstr_VLdStD   ( Bool isLoad, HReg, ARMAModeV* );
988extern ARMInstr* ARMInstr_VLdStS   ( Bool isLoad, HReg, ARMAModeV* );
989extern ARMInstr* ARMInstr_VAluD    ( ARMVfpOp op, HReg, HReg, HReg );
990extern ARMInstr* ARMInstr_VAluS    ( ARMVfpOp op, HReg, HReg, HReg );
991extern ARMInstr* ARMInstr_VUnaryD  ( ARMVfpUnaryOp, HReg dst, HReg src );
992extern ARMInstr* ARMInstr_VUnaryS  ( ARMVfpUnaryOp, HReg dst, HReg src );
993extern ARMInstr* ARMInstr_VCmpD    ( HReg argL, HReg argR );
994extern ARMInstr* ARMInstr_VCMovD   ( ARMCondCode, HReg dst, HReg src );
995extern ARMInstr* ARMInstr_VCMovS   ( ARMCondCode, HReg dst, HReg src );
996extern ARMInstr* ARMInstr_VCvtSD   ( Bool sToD, HReg dst, HReg src );
997extern ARMInstr* ARMInstr_VXferD   ( Bool toD, HReg dD, HReg rHi, HReg rLo );
998extern ARMInstr* ARMInstr_VXferS   ( Bool toS, HReg fD, HReg rLo );
999extern ARMInstr* ARMInstr_VCvtID   ( Bool iToD, Bool syned,
1000                                     HReg dst, HReg src );
1001extern ARMInstr* ARMInstr_FPSCR    ( Bool toFPSCR, HReg iReg );
1002extern ARMInstr* ARMInstr_MFence   ( void );
1003extern ARMInstr* ARMInstr_CLREX    ( void );
1004extern ARMInstr* ARMInstr_NLdStQ   ( Bool isLoad, HReg, ARMAModeN* );
1005extern ARMInstr* ARMInstr_NLdStD   ( Bool isLoad, HReg, ARMAModeN* );
1006extern ARMInstr* ARMInstr_NUnary   ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
1007extern ARMInstr* ARMInstr_NUnaryS  ( ARMNeonUnOpS, ARMNRS*, ARMNRS*,
1008                                     UInt, Bool );
1009extern ARMInstr* ARMInstr_NDual    ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
1010extern ARMInstr* ARMInstr_NBinary  ( ARMNeonBinOp, HReg, HReg, HReg,
1011                                     UInt, Bool );
1012extern ARMInstr* ARMInstr_NShift   ( ARMNeonShiftOp, HReg, HReg, HReg,
1013                                     UInt, Bool );
1014extern ARMInstr* ARMInstr_NShl64   ( HReg, HReg, UInt );
1015extern ARMInstr* ARMInstr_NeonImm  ( HReg, ARMNImm* );
1016extern ARMInstr* ARMInstr_NCMovQ   ( ARMCondCode, HReg, HReg );
1017extern ARMInstr* ARMInstr_Add32    ( HReg rD, HReg rN, UInt imm32 );
1018extern ARMInstr* ARMInstr_EvCheck  ( ARMAMode1* amCounter,
1019                                     ARMAMode1* amFailAddr );
1020extern ARMInstr* ARMInstr_ProfInc  ( void );
1021
1022extern void ppARMInstr ( const ARMInstr* );
1023
1024
1025/* Some functions that insulate the register allocator from details
1026   of the underlying instruction set. */
1027extern void getRegUsage_ARMInstr ( HRegUsage*, const ARMInstr*, Bool );
1028extern void mapRegs_ARMInstr     ( HRegRemap*, ARMInstr*, Bool );
1029extern Bool isMove_ARMInstr      ( const ARMInstr*, HReg*, HReg* );
1030extern Int  emit_ARMInstr        ( /*MB_MOD*/Bool* is_profInc,
1031                                   UChar* buf, Int nbuf, const ARMInstr* i,
1032                                   Bool mode64,
1033                                   VexEndness endness_host,
1034                                   const void* disp_cp_chain_me_to_slowEP,
1035                                   const void* disp_cp_chain_me_to_fastEP,
1036                                   const void* disp_cp_xindir,
1037                                   const void* disp_cp_xassisted );
1038
1039extern void genSpill_ARM  ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1040                            HReg rreg, Int offset, Bool );
1041extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1042                            HReg rreg, Int offset, Bool );
1043
1044extern const RRegUniverse* getRRegUniverse_ARM ( void );
1045
1046extern HInstrArray* iselSB_ARM   ( const IRSB*,
1047                                   VexArch,
1048                                   const VexArchInfo*,
1049                                   const VexAbiInfo*,
1050                                   Int offs_Host_EvC_Counter,
1051                                   Int offs_Host_EvC_FailAddr,
1052                                   Bool chainingAllowed,
1053                                   Bool addProfInc,
1054                                   Addr max_ga );
1055
1056/* How big is an event check?  This is kind of a kludge because it
1057   depends on the offsets of host_EvC_FAILADDR and
1058   host_EvC_COUNTER. */
1059extern Int evCheckSzB_ARM (void);
1060
1061/* Perform a chaining and unchaining of an XDirect jump. */
1062extern VexInvalRange chainXDirect_ARM ( VexEndness endness_host,
1063                                        void* place_to_chain,
1064                                        const void* disp_cp_chain_me_EXPECTED,
1065                                        const void* place_to_jump_to );
1066
1067extern VexInvalRange unchainXDirect_ARM ( VexEndness endness_host,
1068                                          void* place_to_unchain,
1069                                          const void* place_to_jump_to_EXPECTED,
1070                                          const void* disp_cp_chain_me );
1071
1072/* Patch the counter location into an existing ProfInc point. */
1073extern VexInvalRange patchProfInc_ARM ( VexEndness endness_host,
1074                                        void*  place_to_patch,
1075                                        const ULong* location_of_counter );
1076
1077
1078#endif /* ndef __VEX_HOST_ARM_DEFS_H */
1079
1080/*---------------------------------------------------------------*/
1081/*--- end                                     host_arm_defs.h ---*/
1082/*---------------------------------------------------------------*/
1083