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-2011 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 extern UInt arm_hwcaps; 34 35 36 /* --------- Registers. --------- */ 37 38 /* The usual HReg abstraction. 39 There are 16 general purpose regs. 40 */ 41 42 extern void ppHRegARM ( HReg ); 43 44 extern HReg hregARM_R0 ( void ); 45 extern HReg hregARM_R1 ( void ); 46 extern HReg hregARM_R2 ( void ); 47 extern HReg hregARM_R3 ( void ); 48 extern HReg hregARM_R4 ( void ); 49 extern HReg hregARM_R5 ( void ); 50 extern HReg hregARM_R6 ( void ); 51 extern HReg hregARM_R7 ( void ); 52 extern HReg hregARM_R8 ( void ); 53 extern HReg hregARM_R9 ( void ); 54 extern HReg hregARM_R10 ( void ); 55 extern HReg hregARM_R11 ( void ); 56 extern HReg hregARM_R12 ( void ); 57 extern HReg hregARM_R13 ( void ); 58 extern HReg hregARM_R14 ( void ); 59 extern HReg hregARM_R15 ( void ); 60 extern HReg hregARM_D8 ( void ); 61 extern HReg hregARM_D9 ( void ); 62 extern HReg hregARM_D10 ( void ); 63 extern HReg hregARM_D11 ( void ); 64 extern HReg hregARM_D12 ( void ); 65 extern HReg hregARM_S26 ( void ); 66 extern HReg hregARM_S27 ( void ); 67 extern HReg hregARM_S28 ( void ); 68 extern HReg hregARM_S29 ( void ); 69 extern HReg hregARM_S30 ( void ); 70 extern HReg hregARM_Q8 ( void ); 71 extern HReg hregARM_Q9 ( void ); 72 extern HReg hregARM_Q10 ( void ); 73 extern HReg hregARM_Q11 ( void ); 74 extern HReg hregARM_Q12 ( void ); 75 extern HReg hregARM_Q13 ( void ); 76 extern HReg hregARM_Q14 ( void ); 77 extern 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 85 typedef 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 113 extern HChar* showARMCondCode ( ARMCondCode ); 114 115 116 117 /* --------- Memory address expressions (amodes). --------- */ 118 119 /* --- Addressing Mode 1 --- */ 120 typedef 121 enum { 122 ARMam1_RI=1, /* reg +/- imm12 */ 123 ARMam1_RRS /* reg1 + (reg2 << 0, 1 2 or 3) */ 124 } 125 ARMAMode1Tag; 126 127 typedef 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 144 extern ARMAMode1* ARMAMode1_RI ( HReg reg, Int simm13 ); 145 extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift ); 146 147 extern void ppARMAMode1 ( ARMAMode1* ); 148 149 150 /* --- Addressing Mode 2 --- */ 151 typedef 152 enum { 153 ARMam2_RI=3, /* reg +/- imm8 */ 154 ARMam2_RR /* reg1 + reg2 */ 155 } 156 ARMAMode2Tag; 157 158 typedef 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 174 extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 ); 175 extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index ); 176 177 extern 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. */ 183 typedef 184 struct { 185 HReg reg; 186 Int simm11; /* -1020, -1016 .. 1016, 1020 */ 187 } 188 ARMAModeV; 189 190 extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 ); 191 192 extern void ppARMAModeV ( ARMAModeV* ); 193 194 /* --- Addressing Mode suitable for Neon --- */ 195 typedef 196 enum { 197 ARMamN_R=5, 198 ARMamN_RR 199 /* ... */ 200 } 201 ARMAModeNTag; 202 203 typedef 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 219 extern ARMAModeN* mkARMAModeN_RR ( HReg, HReg ); 220 extern ARMAModeN* mkARMAModeN_R ( HReg ); 221 extern 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 227 typedef 228 enum { 229 ARMri84_I84=7, /* imm8 `ror` (2 * imm4) */ 230 ARMri84_R /* reg */ 231 } 232 ARMRI84Tag; 233 234 typedef 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 249 extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 ); 250 extern ARMRI84* ARMRI84_R ( HReg ); 251 252 extern void ppARMRI84 ( ARMRI84* ); 253 254 255 /* --------- Reg or imm5 operands --------- */ 256 typedef 257 enum { 258 ARMri5_I5=9, /* imm5, 1 .. 31 only (no zero!) */ 259 ARMri5_R /* reg */ 260 } 261 ARMRI5Tag; 262 263 typedef 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 277 extern ARMRI5* ARMRI5_I5 ( UInt imm5 ); 278 extern ARMRI5* ARMRI5_R ( HReg ); 279 280 extern void ppARMRI5 ( ARMRI5* ); 281 282 /* -------- Neon Immediate operand -------- */ 283 284 /* imm8 = abcdefgh, B = NOT(b); 285 286 type | 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 301 Type 10 is: 302 (-1)^S * 2^exp * mantissa 303 where S = a, exp = UInt(B:c:d) - 3, mantissa = (16 + UInt(e:f:g:h)) / 16 304 */ 305 306 typedef 307 struct { 308 UInt type; 309 UInt imm8; 310 } 311 ARMNImm; 312 313 extern ARMNImm* ARMNImm_TI ( UInt type, UInt imm8 ); 314 extern ULong ARMNImm_to_Imm64 ( ARMNImm* ); 315 extern ARMNImm* Imm64_to_ARMNImm ( ULong ); 316 317 extern void ppARMNImm ( ARMNImm* ); 318 319 /* ------ Neon Register or Scalar Operand ------ */ 320 321 typedef 322 enum { 323 ARMNRS_Reg=11, 324 ARMNRS_Scalar 325 } 326 ARMNRS_tag; 327 328 typedef 329 struct { 330 ARMNRS_tag tag; 331 HReg reg; 332 UInt index; 333 } 334 ARMNRS; 335 336 extern ARMNRS* mkARMNRS(ARMNRS_tag, HReg reg, UInt index); 337 extern void ppARMNRS ( ARMNRS* ); 338 339 /* --------- Instructions. --------- */ 340 341 /* --------- */ 342 typedef 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 357 extern HChar* showARMAluOp ( ARMAluOp op ); 358 359 360 typedef 361 enum { 362 ARMsh_SHL=40, 363 ARMsh_SHR, 364 ARMsh_SAR 365 } 366 ARMShiftOp; 367 368 extern HChar* showARMShiftOp ( ARMShiftOp op ); 369 370 371 typedef 372 enum { 373 ARMun_NEG=50, 374 ARMun_NOT, 375 ARMun_CLZ 376 } 377 ARMUnaryOp; 378 379 extern HChar* showARMUnaryOp ( ARMUnaryOp op ); 380 381 382 typedef 383 enum { 384 ARMmul_PLAIN=60, 385 ARMmul_ZX, 386 ARMmul_SX 387 } 388 ARMMulOp; 389 390 extern HChar* showARMMulOp ( ARMMulOp op ); 391 392 393 typedef 394 enum { 395 ARMvfp_ADD=70, 396 ARMvfp_SUB, 397 ARMvfp_MUL, 398 ARMvfp_DIV 399 } 400 ARMVfpOp; 401 402 extern HChar* showARMVfpOp ( ARMVfpOp op ); 403 404 405 typedef 406 enum { 407 ARMvfpu_COPY=80, 408 ARMvfpu_NEG, 409 ARMvfpu_ABS, 410 ARMvfpu_SQRT 411 } 412 ARMVfpUnaryOp; 413 414 extern HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op ); 415 416 typedef 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 471 typedef 472 enum { 473 ARMneon_VSHL=150, 474 ARMneon_VSAL, /* Yah, not SAR but SAL */ 475 ARMneon_VQSHL, 476 ARMneon_VQSAL 477 } 478 ARMNeonShiftOp; 479 480 typedef 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 525 typedef 526 enum { 527 ARMneon_SETELEM=200, 528 ARMneon_GETELEMU, 529 ARMneon_GETELEMS, 530 ARMneon_VDUP, 531 } 532 ARMNeonUnOpS; 533 534 typedef 535 enum { 536 ARMneon_TRN=210, 537 ARMneon_ZIP, 538 ARMneon_UZP 539 /* ... */ 540 } 541 ARMNeonDualOp; 542 543 extern HChar* showARMNeonBinOp ( ARMNeonBinOp op ); 544 extern HChar* showARMNeonUnOp ( ARMNeonUnOp op ); 545 extern HChar* showARMNeonUnOpS ( ARMNeonUnOpS op ); 546 extern HChar* showARMNeonShiftOp ( ARMNeonShiftOp op ); 547 extern HChar* showARMNeonDualOp ( ARMNeonDualOp op ); 548 extern HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op ); 549 extern HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op ); 550 extern HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op ); 551 extern HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op ); 552 extern HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op ); 553 554 typedef 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_Goto, 568 ARMin_CMov, 569 ARMin_Call, 570 ARMin_Mul, 571 ARMin_LdrEX, 572 ARMin_StrEX, 573 /* vfp */ 574 ARMin_VLdStD, 575 ARMin_VLdStS, 576 ARMin_VAluD, 577 ARMin_VAluS, 578 ARMin_VUnaryD, 579 ARMin_VUnaryS, 580 ARMin_VCmpD, 581 ARMin_VCMovD, 582 ARMin_VCMovS, 583 ARMin_VCvtSD, 584 ARMin_VXferD, 585 ARMin_VXferS, 586 ARMin_VCvtID, 587 ARMin_FPSCR, 588 ARMin_MFence, 589 ARMin_CLREX, 590 /* Neon */ 591 ARMin_NLdStQ, 592 ARMin_NLdStD, 593 ARMin_NUnary, 594 ARMin_NUnaryS, 595 ARMin_NDual, 596 ARMin_NBinary, 597 ARMin_NBinaryS, 598 ARMin_NShift, 599 ARMin_NeonImm, 600 ARMin_NCMovQ, 601 /* This is not a NEON instruction. Actually there is no corresponding 602 instruction in ARM instruction set at all. We need this one to 603 generate spill/reload of 128-bit registers since current register 604 allocator demands them to consist of no more than two instructions. 605 We will split this instruction into 2 or 3 ARM instructions on the 606 emiting phase. 607 608 NOTE: source and destination registers should be different! */ 609 ARMin_Add32 610 } 611 ARMInstrTag; 612 613 /* Destinations are on the LEFT (first operand) */ 614 615 typedef 616 struct { 617 ARMInstrTag tag; 618 union { 619 /* ADD/SUB/AND/OR/XOR, vanilla ALU op */ 620 struct { 621 ARMAluOp op; 622 HReg dst; 623 HReg argL; 624 ARMRI84* argR; 625 } Alu; 626 /* SHL/SHR/SAR, 2nd arg is reg or imm */ 627 struct { 628 ARMShiftOp op; 629 HReg dst; 630 HReg argL; 631 ARMRI5* argR; 632 } Shift; 633 /* NOT/NEG/CLZ */ 634 struct { 635 ARMUnaryOp op; 636 HReg dst; 637 HReg src; 638 } Unary; 639 /* CMP/TST; subtract/and, discard result, set NZCV */ 640 struct { 641 Bool isCmp; 642 HReg argL; 643 ARMRI84* argR; 644 } CmpOrTst; 645 /* MOV dst, src -- reg-reg (or reg-imm8x4) move */ 646 struct { 647 HReg dst; 648 ARMRI84* src; 649 } Mov; 650 /* Pseudo-insn; make a 32-bit immediate */ 651 struct { 652 HReg dst; 653 UInt imm32; 654 } Imm32; 655 /* 32-bit load or store */ 656 struct { 657 Bool isLoad; 658 HReg rD; 659 ARMAMode1* amode; 660 } LdSt32; 661 /* 16-bit load or store */ 662 struct { 663 Bool isLoad; 664 Bool signedLoad; 665 HReg rD; 666 ARMAMode2* amode; 667 } LdSt16; 668 /* 8-bit (unsigned) load or store */ 669 struct { 670 Bool isLoad; 671 HReg rD; 672 ARMAMode1* amode; 673 } LdSt8U; 674 /* 8-bit signed load */ 675 struct { 676 HReg rD; 677 ARMAMode2* amode; 678 } Ld8S; 679 /* Pseudo-insn. Go to guest address gnext, on given 680 condition, which could be ARMcc_AL. */ 681 struct { 682 IRJumpKind jk; 683 ARMCondCode cond; 684 HReg gnext; 685 } Goto; 686 /* Mov src to dst on the given condition, which may not 687 be ARMcc_AL. */ 688 struct { 689 ARMCondCode cond; 690 HReg dst; 691 ARMRI84* src; 692 } CMov; 693 /* Pseudo-insn. Call target (an absolute address), on given 694 condition (which could be ARMcc_AL). */ 695 struct { 696 ARMCondCode cond; 697 HWord target; 698 Int nArgRegs; /* # regs carrying args: 0 .. 4 */ 699 } Call; 700 /* (PLAIN) 32 * 32 -> 32: r0 = r2 * r3 701 (ZX) 32 *u 32 -> 64: r1:r0 = r2 *u r3 702 (SX) 32 *s 32 -> 64: r1:r0 = r2 *s r3 703 Why hardwired registers? Because the ARM ARM specifies 704 (eg for straight MUL) the result (Rd) and the left arg (Rm) 705 may not be the same register. That's not a constraint we 706 can enforce in the register allocator (without mucho extra 707 complexity). Hence hardwire it. At least using caller-saves 708 registers, which are less likely to be in use. */ 709 struct { 710 ARMMulOp op; 711 } Mul; 712 /* LDREX{,H,B} r2, [r4] and 713 LDREXD r2, r3, [r4] (on LE hosts, transferred value is r3:r2) 714 Again, hardwired registers since this is not performance 715 critical, and there are possibly constraints on the 716 registers that we can't express in the register allocator.*/ 717 struct { 718 Int szB; /* 1, 2, 4 or 8 */ 719 } LdrEX; 720 /* STREX{,H,B} r0, r2, [r4] and 721 STREXD r0, r2, r3, [r4] (on LE hosts, transferred value is r3:r2) 722 r0 = SC( [r4] = r2 ) (8, 16, 32 bit transfers) 723 r0 = SC( [r4] = r3:r2) (64 bit transfers) 724 Ditto comment re fixed registers. */ 725 struct { 726 Int szB; /* 1, 2, 4 or 8 */ 727 } StrEX; 728 /* VFP INSTRUCTIONS */ 729 /* 64-bit Fp load/store */ 730 struct { 731 Bool isLoad; 732 HReg dD; 733 ARMAModeV* amode; 734 } VLdStD; 735 /* 32-bit Fp load/store */ 736 struct { 737 Bool isLoad; 738 HReg fD; 739 ARMAModeV* amode; 740 } VLdStS; 741 /* 64-bit FP binary arithmetic */ 742 struct { 743 ARMVfpOp op; 744 HReg dst; 745 HReg argL; 746 HReg argR; 747 } VAluD; 748 /* 32-bit FP binary arithmetic */ 749 struct { 750 ARMVfpOp op; 751 HReg dst; 752 HReg argL; 753 HReg argR; 754 } VAluS; 755 /* 64-bit FP unary, also reg-reg move */ 756 struct { 757 ARMVfpUnaryOp op; 758 HReg dst; 759 HReg src; 760 } VUnaryD; 761 /* 32-bit FP unary, also reg-reg move */ 762 struct { 763 ARMVfpUnaryOp op; 764 HReg dst; 765 HReg src; 766 } VUnaryS; 767 /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */ 768 struct { 769 HReg argL; 770 HReg argR; 771 } VCmpD; 772 /* 64-bit FP mov src to dst on the given condition, which may 773 not be ARMcc_AL. */ 774 struct { 775 ARMCondCode cond; 776 HReg dst; 777 HReg src; 778 } VCMovD; 779 /* 32-bit FP mov src to dst on the given condition, which may 780 not be ARMcc_AL. */ 781 struct { 782 ARMCondCode cond; 783 HReg dst; 784 HReg src; 785 } VCMovS; 786 /* Convert between 32-bit and 64-bit FP values (both ways). 787 (FCVTSD, FCVTDS) */ 788 struct { 789 Bool sToD; /* True: F32->F64. False: F64->F32 */ 790 HReg dst; 791 HReg src; 792 } VCvtSD; 793 /* Transfer a VFP D reg to/from two integer registers (VMOV) */ 794 struct { 795 Bool toD; 796 HReg dD; 797 HReg rHi; 798 HReg rLo; 799 } VXferD; 800 /* Transfer a VFP S reg to/from an integer register (VMOV) */ 801 struct { 802 Bool toS; 803 HReg fD; 804 HReg rLo; 805 } VXferS; 806 /* Convert between 32-bit ints and 64-bit FP values (both ways 807 and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */ 808 struct { 809 Bool iToD; /* True: I32->F64. False: F64->I32 */ 810 Bool syned; /* True: I32 is signed. False: I32 is unsigned */ 811 HReg dst; 812 HReg src; 813 } VCvtID; 814 /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */ 815 struct { 816 Bool toFPSCR; 817 HReg iReg; 818 } FPSCR; 819 /* Mem fence. An insn which fences all loads and stores as 820 much as possible before continuing. On ARM we emit the 821 sequence 822 mcr 15,0,r0,c7,c10,4 (DSB) 823 mcr 15,0,r0,c7,c10,5 (DMB) 824 mcr 15,0,r0,c7,c5,4 (ISB) 825 which is probably total overkill, but better safe than 826 sorry. 827 */ 828 struct { 829 } MFence; 830 /* A CLREX instruction. */ 831 struct { 832 } CLREX; 833 /* Neon data processing instruction: 3 registers of the same 834 length */ 835 struct { 836 ARMNeonBinOp op; 837 HReg dst; 838 HReg argL; 839 HReg argR; 840 UInt size; 841 Bool Q; 842 } NBinary; 843 struct { 844 ARMNeonBinOp op; 845 ARMNRS* dst; 846 ARMNRS* argL; 847 ARMNRS* argR; 848 UInt size; 849 Bool Q; 850 } NBinaryS; 851 struct { 852 ARMNeonShiftOp op; 853 HReg dst; 854 HReg argL; 855 HReg argR; 856 UInt size; 857 Bool Q; 858 } NShift; 859 struct { 860 Bool isLoad; 861 HReg dQ; 862 ARMAModeN *amode; 863 } NLdStQ; 864 struct { 865 Bool isLoad; 866 HReg dD; 867 ARMAModeN *amode; 868 } NLdStD; 869 struct { 870 ARMNeonUnOpS op; 871 ARMNRS* dst; 872 ARMNRS* src; 873 UInt size; 874 Bool Q; 875 } NUnaryS; 876 struct { 877 ARMNeonUnOp op; 878 HReg dst; 879 HReg src; 880 UInt size; 881 Bool Q; 882 } NUnary; 883 /* Takes two arguments and modifies them both. */ 884 struct { 885 ARMNeonDualOp op; 886 HReg arg1; 887 HReg arg2; 888 UInt size; 889 Bool Q; 890 } NDual; 891 struct { 892 HReg dst; 893 ARMNImm* imm; 894 } NeonImm; 895 /* 128-bit Neon move src to dst on the given condition, which 896 may not be ARMcc_AL. */ 897 struct { 898 ARMCondCode cond; 899 HReg dst; 900 HReg src; 901 } NCMovQ; 902 struct { 903 /* Note: rD != rN */ 904 HReg rD; 905 HReg rN; 906 UInt imm32; 907 } Add32; 908 } ARMin; 909 } 910 ARMInstr; 911 912 913 extern ARMInstr* ARMInstr_Alu ( ARMAluOp, HReg, HReg, ARMRI84* ); 914 extern ARMInstr* ARMInstr_Shift ( ARMShiftOp, HReg, HReg, ARMRI5* ); 915 extern ARMInstr* ARMInstr_Unary ( ARMUnaryOp, HReg, HReg ); 916 extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* ); 917 extern ARMInstr* ARMInstr_Mov ( HReg, ARMRI84* ); 918 extern ARMInstr* ARMInstr_Imm32 ( HReg, UInt ); 919 extern ARMInstr* ARMInstr_LdSt32 ( Bool isLoad, HReg, ARMAMode1* ); 920 extern ARMInstr* ARMInstr_LdSt16 ( Bool isLoad, Bool signedLoad, 921 HReg, ARMAMode2* ); 922 extern ARMInstr* ARMInstr_LdSt8U ( Bool isLoad, HReg, ARMAMode1* ); 923 extern ARMInstr* ARMInstr_Ld8S ( HReg, ARMAMode2* ); 924 extern ARMInstr* ARMInstr_Goto ( IRJumpKind, ARMCondCode, HReg gnext ); 925 extern ARMInstr* ARMInstr_CMov ( ARMCondCode, HReg dst, ARMRI84* src ); 926 extern ARMInstr* ARMInstr_Call ( ARMCondCode, HWord, Int nArgRegs ); 927 extern ARMInstr* ARMInstr_Mul ( ARMMulOp op ); 928 extern ARMInstr* ARMInstr_LdrEX ( Int szB ); 929 extern ARMInstr* ARMInstr_StrEX ( Int szB ); 930 extern ARMInstr* ARMInstr_VLdStD ( Bool isLoad, HReg, ARMAModeV* ); 931 extern ARMInstr* ARMInstr_VLdStS ( Bool isLoad, HReg, ARMAModeV* ); 932 extern ARMInstr* ARMInstr_VAluD ( ARMVfpOp op, HReg, HReg, HReg ); 933 extern ARMInstr* ARMInstr_VAluS ( ARMVfpOp op, HReg, HReg, HReg ); 934 extern ARMInstr* ARMInstr_VUnaryD ( ARMVfpUnaryOp, HReg dst, HReg src ); 935 extern ARMInstr* ARMInstr_VUnaryS ( ARMVfpUnaryOp, HReg dst, HReg src ); 936 extern ARMInstr* ARMInstr_VCmpD ( HReg argL, HReg argR ); 937 extern ARMInstr* ARMInstr_VCMovD ( ARMCondCode, HReg dst, HReg src ); 938 extern ARMInstr* ARMInstr_VCMovS ( ARMCondCode, HReg dst, HReg src ); 939 extern ARMInstr* ARMInstr_VCvtSD ( Bool sToD, HReg dst, HReg src ); 940 extern ARMInstr* ARMInstr_VXferD ( Bool toD, HReg dD, HReg rHi, HReg rLo ); 941 extern ARMInstr* ARMInstr_VXferS ( Bool toS, HReg fD, HReg rLo ); 942 extern ARMInstr* ARMInstr_VCvtID ( Bool iToD, Bool syned, 943 HReg dst, HReg src ); 944 extern ARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg ); 945 extern ARMInstr* ARMInstr_MFence ( void ); 946 extern ARMInstr* ARMInstr_CLREX ( void ); 947 extern ARMInstr* ARMInstr_NLdStQ ( Bool isLoad, HReg, ARMAModeN* ); 948 extern ARMInstr* ARMInstr_NLdStD ( Bool isLoad, HReg, ARMAModeN* ); 949 extern ARMInstr* ARMInstr_NUnary ( ARMNeonUnOp, HReg, HReg, UInt, Bool ); 950 extern ARMInstr* ARMInstr_NUnaryS ( ARMNeonUnOpS, ARMNRS*, ARMNRS*, 951 UInt, Bool ); 952 extern ARMInstr* ARMInstr_NDual ( ARMNeonDualOp, HReg, HReg, UInt, Bool ); 953 extern ARMInstr* ARMInstr_NBinary ( ARMNeonBinOp, HReg, HReg, HReg, 954 UInt, Bool ); 955 extern ARMInstr* ARMInstr_NShift ( ARMNeonShiftOp, HReg, HReg, HReg, 956 UInt, Bool ); 957 extern ARMInstr* ARMInstr_NeonImm ( HReg, ARMNImm* ); 958 extern ARMInstr* ARMInstr_NCMovQ ( ARMCondCode, HReg, HReg ); 959 extern ARMInstr* ARMInstr_Add32 ( HReg rD, HReg rN, UInt imm32 ); 960 961 extern void ppARMInstr ( ARMInstr* ); 962 963 964 /* Some functions that insulate the register allocator from details 965 of the underlying instruction set. */ 966 extern void getRegUsage_ARMInstr ( HRegUsage*, ARMInstr*, Bool ); 967 extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr*, Bool ); 968 extern Bool isMove_ARMInstr ( ARMInstr*, HReg*, HReg* ); 969 extern Int emit_ARMInstr ( UChar* buf, Int nbuf, ARMInstr*, 970 Bool, 971 void* dispatch_unassisted, 972 void* dispatch_assisted ); 973 974 extern void genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2, 975 HReg rreg, Int offset, Bool ); 976 extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2, 977 HReg rreg, Int offset, Bool ); 978 979 extern void getAllocableRegs_ARM ( Int*, HReg** ); 980 extern HInstrArray* iselSB_ARM ( IRSB*, VexArch, 981 VexArchInfo*, VexAbiInfo* ); 982 983 #endif /* ndef __VEX_HOST_ARM_DEFS_H */ 984 985 /*---------------------------------------------------------------*/ 986 /*--- end host_arm_defs.h ---*/ 987 /*---------------------------------------------------------------*/ 988