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