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-2015 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