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