1 2 /*---------------------------------------------------------------*/ 3 /*--- begin host_arm_defs.h ---*/ 4 /*---------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2004-2010 OpenWorks LLP 11 info@open-works.net 12 13 This program is free software; you can redistribute it and/or 14 modify it under the terms of the GNU General Public License as 15 published by the Free Software Foundation; either version 2 of the 16 License, or (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, but 19 WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 02110-1301, USA. 27 28 The GNU General Public License is contained in the file COPYING. 29 */ 30 31 #ifndef __VEX_HOST_ARM_DEFS_H 32 #define __VEX_HOST_ARM_DEFS_H 33 34 extern UInt arm_hwcaps; 35 36 37 /* --------- Registers. --------- */ 38 39 /* The usual HReg abstraction. 40 There are 16 general purpose regs. 41 */ 42 43 extern void ppHRegARM ( HReg ); 44 45 extern HReg hregARM_R0 ( void ); 46 extern HReg hregARM_R1 ( void ); 47 extern HReg hregARM_R2 ( void ); 48 extern HReg hregARM_R3 ( void ); 49 extern HReg hregARM_R4 ( void ); 50 extern HReg hregARM_R5 ( void ); 51 extern HReg hregARM_R6 ( void ); 52 extern HReg hregARM_R7 ( void ); 53 extern HReg hregARM_R8 ( void ); 54 extern HReg hregARM_R9 ( void ); 55 extern HReg hregARM_R10 ( void ); 56 extern HReg hregARM_R11 ( void ); 57 extern HReg hregARM_R12 ( void ); 58 extern HReg hregARM_R13 ( void ); 59 extern HReg hregARM_R14 ( void ); 60 extern HReg hregARM_R15 ( void ); 61 extern HReg hregARM_D8 ( void ); 62 extern HReg hregARM_D9 ( void ); 63 extern HReg hregARM_D10 ( void ); 64 extern HReg hregARM_D11 ( void ); 65 extern HReg hregARM_D12 ( void ); 66 extern HReg hregARM_S26 ( void ); 67 extern HReg hregARM_S27 ( void ); 68 extern HReg hregARM_S28 ( void ); 69 extern HReg hregARM_S29 ( void ); 70 extern HReg hregARM_S30 ( void ); 71 extern HReg hregARM_Q8 ( void ); 72 extern HReg hregARM_Q9 ( void ); 73 extern HReg hregARM_Q10 ( void ); 74 extern HReg hregARM_Q11 ( void ); 75 extern HReg hregARM_Q12 ( void ); 76 extern HReg hregARM_Q13 ( void ); 77 extern HReg hregARM_Q14 ( void ); 78 extern HReg hregARM_Q15 ( void ); 79 80 /* Number of registers used arg passing in function calls */ 81 #define ARM_N_ARGREGS 4 /* r0, r1, r2, r3 */ 82 83 84 /* --------- Condition codes. --------- */ 85 86 typedef 87 enum { 88 ARMcc_EQ = 0, /* equal : Z=1 */ 89 ARMcc_NE = 1, /* not equal : Z=0 */ 90 91 ARMcc_HS = 2, /* >=u (higher or same) : C=1 */ 92 ARMcc_LO = 3, /* <u (lower) : C=0 */ 93 94 ARMcc_MI = 4, /* minus (negative) : N=1 */ 95 ARMcc_PL = 5, /* plus (zero or +ve) : N=0 */ 96 97 ARMcc_VS = 6, /* overflow : V=1 */ 98 ARMcc_VC = 7, /* no overflow : V=0 */ 99 100 ARMcc_HI = 8, /* >u (higher) : C=1 && Z=0 */ 101 ARMcc_LS = 9, /* <=u (lower or same) : C=0 || Z=1 */ 102 103 ARMcc_GE = 10, /* >=s (signed greater or equal) : N=V */ 104 ARMcc_LT = 11, /* <s (signed less than) : N!=V */ 105 106 ARMcc_GT = 12, /* >s (signed greater) : Z=0 && N=V */ 107 ARMcc_LE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */ 108 109 ARMcc_AL = 14, /* always (unconditional) */ 110 ARMcc_NV = 15 /* never (basically undefined meaning), deprecated */ 111 } 112 ARMCondCode; 113 114 extern HChar* showARMCondCode ( ARMCondCode ); 115 116 117 118 /* --------- Memory address expressions (amodes). --------- */ 119 120 /* --- Addressing Mode 1 --- */ 121 typedef 122 enum { 123 ARMam1_RI=1, /* reg +/- imm12 */ 124 ARMam1_RRS /* reg1 + (reg2 << 0, 1 2 or 3) */ 125 } 126 ARMAMode1Tag; 127 128 typedef 129 struct { 130 ARMAMode1Tag tag; 131 union { 132 struct { 133 HReg reg; 134 Int simm13; /* -4095 .. +4095 */ 135 } RI; 136 struct { 137 HReg base; 138 HReg index; 139 UInt shift; /* 0, 1 2 or 3 */ 140 } RRS; 141 } ARMam1; 142 } 143 ARMAMode1; 144 145 extern ARMAMode1* ARMAMode1_RI ( HReg reg, Int simm13 ); 146 extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift ); 147 148 extern void ppARMAMode1 ( ARMAMode1* ); 149 150 151 /* --- Addressing Mode 2 --- */ 152 typedef 153 enum { 154 ARMam2_RI=3, /* reg +/- imm8 */ 155 ARMam2_RR /* reg1 + reg2 */ 156 } 157 ARMAMode2Tag; 158 159 typedef 160 struct { 161 ARMAMode2Tag tag; 162 union { 163 struct { 164 HReg reg; 165 Int simm9; /* -255 .. 255 */ 166 } RI; 167 struct { 168 HReg base; 169 HReg index; 170 } RR; 171 } ARMam2; 172 } 173 ARMAMode2; 174 175 extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 ); 176 extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index ); 177 178 extern void ppARMAMode2 ( ARMAMode2* ); 179 180 181 /* --- Addressing Mode suitable for VFP --- */ 182 /* The simm11 is encoded as 8 bits + 1 sign bit, 183 so can only be 0 % 4. */ 184 typedef 185 struct { 186 HReg reg; 187 Int simm11; /* -1020, -1016 .. 1016, 1020 */ 188 } 189 ARMAModeV; 190 191 extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 ); 192 193 extern void ppARMAModeV ( ARMAModeV* ); 194 195 /* --- Addressing Mode suitable for Neon --- */ 196 typedef 197 enum { 198 ARMamN_R=5, 199 ARMamN_RR 200 /* ... */ 201 } 202 ARMAModeNTag; 203 204 typedef 205 struct { 206 ARMAModeNTag tag; 207 union { 208 struct { 209 HReg rN; 210 HReg rM; 211 } RR; 212 struct { 213 HReg rN; 214 } R; 215 /* ... */ 216 } ARMamN; 217 } 218 ARMAModeN; 219 220 extern ARMAModeN* mkARMAModeN_RR ( HReg, HReg ); 221 extern ARMAModeN* mkARMAModeN_R ( HReg ); 222 extern void ppARMAModeN ( ARMAModeN* ); 223 224 /* --------- Reg or imm-8x4 operands --------- */ 225 /* a.k.a (a very restricted form of) Shifter Operand, 226 in the ARM parlance. */ 227 228 typedef 229 enum { 230 ARMri84_I84=7, /* imm8 `ror` (2 * imm4) */ 231 ARMri84_R /* reg */ 232 } 233 ARMRI84Tag; 234 235 typedef 236 struct { 237 ARMRI84Tag tag; 238 union { 239 struct { 240 UShort imm8; 241 UShort imm4; 242 } I84; 243 struct { 244 HReg reg; 245 } R; 246 } ARMri84; 247 } 248 ARMRI84; 249 250 extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 ); 251 extern ARMRI84* ARMRI84_R ( HReg ); 252 253 extern void ppARMRI84 ( ARMRI84* ); 254 255 256 /* --------- Reg or imm5 operands --------- */ 257 typedef 258 enum { 259 ARMri5_I5=9, /* imm5, 1 .. 31 only (no zero!) */ 260 ARMri5_R /* reg */ 261 } 262 ARMRI5Tag; 263 264 typedef 265 struct { 266 ARMRI5Tag tag; 267 union { 268 struct { 269 UInt imm5; 270 } I5; 271 struct { 272 HReg reg; 273 } R; 274 } ARMri5; 275 } 276 ARMRI5; 277 278 extern ARMRI5* ARMRI5_I5 ( UInt imm5 ); 279 extern ARMRI5* ARMRI5_R ( HReg ); 280 281 extern void ppARMRI5 ( ARMRI5* ); 282 283 /* -------- Neon Immediate operand -------- */ 284 285 /* imm8 = abcdefgh, B = NOT(b); 286 287 type | value (64bit binary) 288 -----+------------------------------------------------------------------------- 289 0 | 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 290 1 | 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 291 2 | 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000 292 3 | abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000 293 4 | 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 294 5 | abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 295 6 | abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh 296 7 | 00000000 00000000 abcdefgh 11111111 00000000 00000000 abcdefgh 11111111 297 8 | 00000000 abcdefgh 11111111 11111111 00000000 abcdefgh 11111111 11111111 298 9 | aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 299 10 | aBbbbbbc defgh000 00000000 00000000 aBbbbbbc defgh000 00000000 00000000 300 -----+------------------------------------------------------------------------- 301 302 Type 10 is: 303 (-1)^S * 2^exp * mantissa 304 where S = a, exp = UInt(B:c:d) - 3, mantissa = (16 + UInt(e:f:g:h)) / 16 305 */ 306 307 typedef 308 struct { 309 UInt type; 310 UInt imm8; 311 } 312 ARMNImm; 313 314 extern ARMNImm* ARMNImm_TI ( UInt type, UInt imm8 ); 315 extern ULong ARMNImm_to_Imm64 ( ARMNImm* ); 316 extern ARMNImm* Imm64_to_ARMNImm ( ULong ); 317 318 extern void ppARMNImm ( ARMNImm* ); 319 320 /* ------ Neon Register or Scalar Operand ------ */ 321 322 typedef 323 enum { 324 ARMNRS_Reg=11, 325 ARMNRS_Scalar 326 } 327 ARMNRS_tag; 328 329 typedef 330 struct { 331 ARMNRS_tag tag; 332 HReg reg; 333 UInt index; 334 } 335 ARMNRS; 336 337 extern ARMNRS* mkARMNRS(ARMNRS_tag, HReg reg, UInt index); 338 extern void ppARMNRS ( ARMNRS* ); 339 340 /* --------- Instructions. --------- */ 341 342 /* --------- */ 343 typedef 344 enum { 345 ARMalu_ADD=20, /* plain 32-bit add */ 346 ARMalu_ADDS, /* 32-bit add, and set the flags */ 347 ARMalu_ADC, /* 32-bit add with carry */ 348 ARMalu_SUB, /* plain 32-bit subtract */ 349 ARMalu_SUBS, /* 32-bit subtract, and set the flags */ 350 ARMalu_SBC, /* 32-bit subtract with carry */ 351 ARMalu_AND, 352 ARMalu_BIC, 353 ARMalu_OR, 354 ARMalu_XOR 355 } 356 ARMAluOp; 357 358 extern HChar* showARMAluOp ( ARMAluOp op ); 359 360 361 typedef 362 enum { 363 ARMsh_SHL=40, 364 ARMsh_SHR, 365 ARMsh_SAR 366 } 367 ARMShiftOp; 368 369 extern HChar* showARMShiftOp ( ARMShiftOp op ); 370 371 372 typedef 373 enum { 374 ARMun_NEG=50, 375 ARMun_NOT, 376 ARMun_CLZ 377 } 378 ARMUnaryOp; 379 380 extern HChar* showARMUnaryOp ( ARMUnaryOp op ); 381 382 383 typedef 384 enum { 385 ARMmul_PLAIN=60, 386 ARMmul_ZX, 387 ARMmul_SX 388 } 389 ARMMulOp; 390 391 extern HChar* showARMMulOp ( ARMMulOp op ); 392 393 394 typedef 395 enum { 396 ARMvfp_ADD=70, 397 ARMvfp_SUB, 398 ARMvfp_MUL, 399 ARMvfp_DIV 400 } 401 ARMVfpOp; 402 403 extern HChar* showARMVfpOp ( ARMVfpOp op ); 404 405 406 typedef 407 enum { 408 ARMvfpu_COPY=80, 409 ARMvfpu_NEG, 410 ARMvfpu_ABS, 411 ARMvfpu_SQRT 412 } 413 ARMVfpUnaryOp; 414 415 extern HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op ); 416 417 typedef 418 enum { 419 ARMneon_VAND=90, 420 ARMneon_VORR, 421 ARMneon_VXOR, 422 ARMneon_VADD, 423 ARMneon_VADDFP, 424 ARMneon_VRHADDS, 425 ARMneon_VRHADDU, 426 ARMneon_VPADDFP, 427 ARMneon_VABDFP, 428 ARMneon_VSUB, 429 ARMneon_VSUBFP, 430 ARMneon_VMAXU, 431 ARMneon_VMAXS, 432 ARMneon_VMAXF, 433 ARMneon_VMINU, 434 ARMneon_VMINS, 435 ARMneon_VMINF, 436 ARMneon_VQADDU, 437 ARMneon_VQADDS, 438 ARMneon_VQSUBU, 439 ARMneon_VQSUBS, 440 ARMneon_VCGTU, 441 ARMneon_VCGTS, 442 ARMneon_VCGEU, 443 ARMneon_VCGES, 444 ARMneon_VCGTF, 445 ARMneon_VCGEF, 446 ARMneon_VCEQ, 447 ARMneon_VCEQF, 448 ARMneon_VEXT, 449 ARMneon_VMUL, 450 ARMneon_VMULFP, 451 ARMneon_VMULLU, 452 ARMneon_VMULLS, 453 ARMneon_VMULP, 454 ARMneon_VMULLP, 455 ARMneon_VQDMULH, 456 ARMneon_VQRDMULH, 457 ARMneon_VPADD, 458 ARMneon_VPMINU, 459 ARMneon_VPMINS, 460 ARMneon_VPMINF, 461 ARMneon_VPMAXU, 462 ARMneon_VPMAXS, 463 ARMneon_VPMAXF, 464 ARMneon_VTBL, 465 ARMneon_VQDMULL, 466 ARMneon_VRECPS, 467 ARMneon_VRSQRTS, 468 /* ... */ 469 } 470 ARMNeonBinOp; 471 472 typedef 473 enum { 474 ARMneon_VSHL=150, 475 ARMneon_VSAL, /* Yah, not SAR but SAL */ 476 ARMneon_VQSHL, 477 ARMneon_VQSAL 478 } 479 ARMNeonShiftOp; 480 481 typedef 482 enum { 483 ARMneon_COPY=160, 484 ARMneon_COPYLU, 485 ARMneon_COPYLS, 486 ARMneon_COPYN, 487 ARMneon_COPYQNSS, 488 ARMneon_COPYQNUS, 489 ARMneon_COPYQNUU, 490 ARMneon_NOT, 491 ARMneon_EQZ, 492 ARMneon_DUP, 493 ARMneon_PADDLS, 494 ARMneon_PADDLU, 495 ARMneon_CNT, 496 ARMneon_CLZ, 497 ARMneon_CLS, 498 ARMneon_VCVTxFPxINT, 499 ARMneon_VQSHLNSS, 500 ARMneon_VQSHLNUU, 501 ARMneon_VQSHLNUS, 502 ARMneon_VCVTFtoU, 503 ARMneon_VCVTFtoS, 504 ARMneon_VCVTUtoF, 505 ARMneon_VCVTStoF, 506 ARMneon_VCVTFtoFixedU, 507 ARMneon_VCVTFtoFixedS, 508 ARMneon_VCVTFixedUtoF, 509 ARMneon_VCVTFixedStoF, 510 ARMneon_VCVTF16toF32, 511 ARMneon_VCVTF32toF16, 512 ARMneon_REV16, 513 ARMneon_REV32, 514 ARMneon_REV64, 515 ARMneon_ABS, 516 ARMneon_VNEGF, 517 ARMneon_VRECIP, 518 ARMneon_VRECIPF, 519 ARMneon_VABSFP, 520 ARMneon_VRSQRTEFP, 521 ARMneon_VRSQRTE 522 /* ... */ 523 } 524 ARMNeonUnOp; 525 526 typedef 527 enum { 528 ARMneon_SETELEM=200, 529 ARMneon_GETELEMU, 530 ARMneon_GETELEMS, 531 ARMneon_VDUP, 532 } 533 ARMNeonUnOpS; 534 535 typedef 536 enum { 537 ARMneon_TRN=210, 538 ARMneon_ZIP, 539 ARMneon_UZP 540 /* ... */ 541 } 542 ARMNeonDualOp; 543 544 extern HChar* showARMNeonBinOp ( ARMNeonBinOp op ); 545 extern HChar* showARMNeonUnOp ( ARMNeonUnOp op ); 546 extern HChar* showARMNeonUnOpS ( ARMNeonUnOpS op ); 547 extern HChar* showARMNeonShiftOp ( ARMNeonShiftOp op ); 548 extern HChar* showARMNeonDualOp ( ARMNeonDualOp op ); 549 extern HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op ); 550 extern HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op ); 551 extern HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op ); 552 extern HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op ); 553 extern HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op ); 554 555 typedef 556 enum { 557 /* baseline */ 558 ARMin_Alu=220, 559 ARMin_Shift, 560 ARMin_Unary, 561 ARMin_CmpOrTst, 562 ARMin_Mov, 563 ARMin_Imm32, 564 ARMin_LdSt32, 565 ARMin_LdSt16, 566 ARMin_LdSt8U, 567 ARMin_Ld8S, 568 ARMin_Goto, 569 ARMin_CMov, 570 ARMin_Call, 571 ARMin_Mul, 572 ARMin_LdrEX, 573 ARMin_StrEX, 574 /* vfp */ 575 ARMin_VLdStD, 576 ARMin_VLdStS, 577 ARMin_VAluD, 578 ARMin_VAluS, 579 ARMin_VUnaryD, 580 ARMin_VUnaryS, 581 ARMin_VCmpD, 582 ARMin_VCMovD, 583 ARMin_VCMovS, 584 ARMin_VCvtSD, 585 ARMin_VXferD, 586 ARMin_VXferS, 587 ARMin_VCvtID, 588 ARMin_FPSCR, 589 ARMin_MFence, 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} r0, [r1] 713 Again, hardwired registers since this is not performance 714 critical, and there are possibly constraints on the 715 registers that we can't express in the register allocator.*/ 716 struct { 717 Int szB; /* currently only 4 is allowed */ 718 } LdrEX; 719 /* STREX{,H,B} r0, r1, [r2] 720 r0 = SC( [r2] = r1 ) 721 Ditto comment re fixed registers. */ 722 struct { 723 Int szB; /* currently only 4 is allowed */ 724 } StrEX; 725 /* VFP INSTRUCTIONS */ 726 /* 64-bit Fp load/store */ 727 struct { 728 Bool isLoad; 729 HReg dD; 730 ARMAModeV* amode; 731 } VLdStD; 732 /* 32-bit Fp load/store */ 733 struct { 734 Bool isLoad; 735 HReg fD; 736 ARMAModeV* amode; 737 } VLdStS; 738 /* 64-bit FP binary arithmetic */ 739 struct { 740 ARMVfpOp op; 741 HReg dst; 742 HReg argL; 743 HReg argR; 744 } VAluD; 745 /* 32-bit FP binary arithmetic */ 746 struct { 747 ARMVfpOp op; 748 HReg dst; 749 HReg argL; 750 HReg argR; 751 } VAluS; 752 /* 64-bit FP unary, also reg-reg move */ 753 struct { 754 ARMVfpUnaryOp op; 755 HReg dst; 756 HReg src; 757 } VUnaryD; 758 /* 32-bit FP unary, also reg-reg move */ 759 struct { 760 ARMVfpUnaryOp op; 761 HReg dst; 762 HReg src; 763 } VUnaryS; 764 /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */ 765 struct { 766 HReg argL; 767 HReg argR; 768 } VCmpD; 769 /* 64-bit FP mov src to dst on the given condition, which may 770 not be ARMcc_AL. */ 771 struct { 772 ARMCondCode cond; 773 HReg dst; 774 HReg src; 775 } VCMovD; 776 /* 32-bit FP mov src to dst on the given condition, which may 777 not be ARMcc_AL. */ 778 struct { 779 ARMCondCode cond; 780 HReg dst; 781 HReg src; 782 } VCMovS; 783 /* Convert between 32-bit and 64-bit FP values (both ways). 784 (FCVTSD, FCVTDS) */ 785 struct { 786 Bool sToD; /* True: F32->F64. False: F64->F32 */ 787 HReg dst; 788 HReg src; 789 } VCvtSD; 790 /* Transfer a VFP D reg to/from two integer registers (VMOV) */ 791 struct { 792 Bool toD; 793 HReg dD; 794 HReg rHi; 795 HReg rLo; 796 } VXferD; 797 /* Transfer a VFP S reg to/from an integer register (VMOV) */ 798 struct { 799 Bool toS; 800 HReg fD; 801 HReg rLo; 802 } VXferS; 803 /* Convert between 32-bit ints and 64-bit FP values (both ways 804 and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */ 805 struct { 806 Bool iToD; /* True: I32->F64. False: F64->I32 */ 807 Bool syned; /* True: I32 is signed. False: I32 is unsigned */ 808 HReg dst; 809 HReg src; 810 } VCvtID; 811 /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */ 812 struct { 813 Bool toFPSCR; 814 HReg iReg; 815 } FPSCR; 816 /* Mem fence. An insn which fences all loads and stores as 817 much as possible before continuing. On ARM we emit the 818 sequence 819 mcr 15,0,r0,c7,c10,4 (DSB) 820 mcr 15,0,r0,c7,c10,5 (DMB) 821 mcr 15,0,r0,c7,c5,4 (ISB) 822 which is probably total overkill, but better safe than 823 sorry. 824 */ 825 struct { 826 } MFence; 827 /* Neon data processing instruction: 3 registers of the same 828 length */ 829 struct { 830 ARMNeonBinOp op; 831 HReg dst; 832 HReg argL; 833 HReg argR; 834 UInt size; 835 Bool Q; 836 } NBinary; 837 struct { 838 ARMNeonBinOp op; 839 ARMNRS* dst; 840 ARMNRS* argL; 841 ARMNRS* argR; 842 UInt size; 843 Bool Q; 844 } NBinaryS; 845 struct { 846 ARMNeonShiftOp op; 847 HReg dst; 848 HReg argL; 849 HReg argR; 850 UInt size; 851 Bool Q; 852 } NShift; 853 struct { 854 Bool isLoad; 855 HReg dQ; 856 ARMAModeN *amode; 857 } NLdStQ; 858 struct { 859 Bool isLoad; 860 HReg dD; 861 ARMAModeN *amode; 862 } NLdStD; 863 struct { 864 ARMNeonUnOpS op; 865 ARMNRS* dst; 866 ARMNRS* src; 867 UInt size; 868 Bool Q; 869 } NUnaryS; 870 struct { 871 ARMNeonUnOp op; 872 HReg dst; 873 HReg src; 874 UInt size; 875 Bool Q; 876 } NUnary; 877 /* Takes two arguments and modifies them both. */ 878 struct { 879 ARMNeonDualOp op; 880 HReg arg1; 881 HReg arg2; 882 UInt size; 883 Bool Q; 884 } NDual; 885 struct { 886 HReg dst; 887 ARMNImm* imm; 888 } NeonImm; 889 /* 128-bit Neon move src to dst on the given condition, which 890 may not be ARMcc_AL. */ 891 struct { 892 ARMCondCode cond; 893 HReg dst; 894 HReg src; 895 } NCMovQ; 896 struct { 897 /* Note: rD != rN */ 898 HReg rD; 899 HReg rN; 900 UInt imm32; 901 } Add32; 902 } ARMin; 903 } 904 ARMInstr; 905 906 907 extern ARMInstr* ARMInstr_Alu ( ARMAluOp, HReg, HReg, ARMRI84* ); 908 extern ARMInstr* ARMInstr_Shift ( ARMShiftOp, HReg, HReg, ARMRI5* ); 909 extern ARMInstr* ARMInstr_Unary ( ARMUnaryOp, HReg, HReg ); 910 extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* ); 911 extern ARMInstr* ARMInstr_Mov ( HReg, ARMRI84* ); 912 extern ARMInstr* ARMInstr_Imm32 ( HReg, UInt ); 913 extern ARMInstr* ARMInstr_LdSt32 ( Bool isLoad, HReg, ARMAMode1* ); 914 extern ARMInstr* ARMInstr_LdSt16 ( Bool isLoad, Bool signedLoad, 915 HReg, ARMAMode2* ); 916 extern ARMInstr* ARMInstr_LdSt8U ( Bool isLoad, HReg, ARMAMode1* ); 917 extern ARMInstr* ARMInstr_Ld8S ( HReg, ARMAMode2* ); 918 extern ARMInstr* ARMInstr_Goto ( IRJumpKind, ARMCondCode, HReg gnext ); 919 extern ARMInstr* ARMInstr_CMov ( ARMCondCode, HReg dst, ARMRI84* src ); 920 extern ARMInstr* ARMInstr_Call ( ARMCondCode, HWord, Int nArgRegs ); 921 extern ARMInstr* ARMInstr_Mul ( ARMMulOp op ); 922 extern ARMInstr* ARMInstr_LdrEX ( Int szB ); 923 extern ARMInstr* ARMInstr_StrEX ( Int szB ); 924 extern ARMInstr* ARMInstr_VLdStD ( Bool isLoad, HReg, ARMAModeV* ); 925 extern ARMInstr* ARMInstr_VLdStS ( Bool isLoad, HReg, ARMAModeV* ); 926 extern ARMInstr* ARMInstr_VAluD ( ARMVfpOp op, HReg, HReg, HReg ); 927 extern ARMInstr* ARMInstr_VAluS ( ARMVfpOp op, HReg, HReg, HReg ); 928 extern ARMInstr* ARMInstr_VUnaryD ( ARMVfpUnaryOp, HReg dst, HReg src ); 929 extern ARMInstr* ARMInstr_VUnaryS ( ARMVfpUnaryOp, HReg dst, HReg src ); 930 extern ARMInstr* ARMInstr_VCmpD ( HReg argL, HReg argR ); 931 extern ARMInstr* ARMInstr_VCMovD ( ARMCondCode, HReg dst, HReg src ); 932 extern ARMInstr* ARMInstr_VCMovS ( ARMCondCode, HReg dst, HReg src ); 933 extern ARMInstr* ARMInstr_VCvtSD ( Bool sToD, HReg dst, HReg src ); 934 extern ARMInstr* ARMInstr_VXferD ( Bool toD, HReg dD, HReg rHi, HReg rLo ); 935 extern ARMInstr* ARMInstr_VXferS ( Bool toS, HReg fD, HReg rLo ); 936 extern ARMInstr* ARMInstr_VCvtID ( Bool iToD, Bool syned, 937 HReg dst, HReg src ); 938 extern ARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg ); 939 extern ARMInstr* ARMInstr_MFence ( void ); 940 extern ARMInstr* ARMInstr_NLdStQ ( Bool isLoad, HReg, ARMAModeN* ); 941 extern ARMInstr* ARMInstr_NLdStD ( Bool isLoad, HReg, ARMAModeN* ); 942 extern ARMInstr* ARMInstr_NUnary ( ARMNeonUnOp, HReg, HReg, UInt, Bool ); 943 extern ARMInstr* ARMInstr_NUnaryS ( ARMNeonUnOp, ARMNRS*, ARMNRS*, 944 UInt, Bool ); 945 extern ARMInstr* ARMInstr_NDual ( ARMNeonDualOp, HReg, HReg, UInt, Bool ); 946 extern ARMInstr* ARMInstr_NBinary ( ARMNeonBinOp, HReg, HReg, HReg, 947 UInt, Bool ); 948 extern ARMInstr* ARMInstr_NShift ( ARMNeonShiftOp, HReg, HReg, HReg, 949 UInt, Bool ); 950 extern ARMInstr* ARMInstr_NeonImm ( HReg, ARMNImm* ); 951 extern ARMInstr* ARMInstr_NCMovQ ( ARMCondCode, HReg, HReg ); 952 extern ARMInstr* ARMInstr_Add32 ( HReg rD, HReg rN, UInt imm32 ); 953 954 extern void ppARMInstr ( ARMInstr* ); 955 956 957 /* Some functions that insulate the register allocator from details 958 of the underlying instruction set. */ 959 extern void getRegUsage_ARMInstr ( HRegUsage*, ARMInstr*, Bool ); 960 extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr*, Bool ); 961 extern Bool isMove_ARMInstr ( ARMInstr*, HReg*, HReg* ); 962 extern Int emit_ARMInstr ( UChar* buf, Int nbuf, ARMInstr*, 963 Bool, void* dispatch ); 964 965 extern void genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2, 966 HReg rreg, Int offset, Bool ); 967 extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2, 968 HReg rreg, Int offset, Bool ); 969 970 extern void getAllocableRegs_ARM ( Int*, HReg** ); 971 extern HInstrArray* iselSB_ARM ( IRSB*, VexArch, 972 VexArchInfo*, VexAbiInfo* ); 973 974 #endif /* ndef __VEX_HOST_ARM_DEFS_H */ 975 976 /*---------------------------------------------------------------*/ 977 /*--- end host_arm_defs.h ---*/ 978 /*---------------------------------------------------------------*/ 979