1 2 /*---------------------------------------------------------------*/ 3 /*--- begin host_mips_defs.h ---*/ 4 /*---------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2010-2017 RT-RK 11 mips-valgrind (at) rt-rk.com 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., 59 Temple Place, Suite 330, Boston, MA 26 02111-1307, USA. 27 28 The GNU General Public License is contained in the file COPYING. 29 */ 30 31 #ifndef __VEX_HOST_MIPS_DEFS_H 32 #define __VEX_HOST_MIPS_DEFS_H 33 34 #include "libvex_basictypes.h" 35 #include "libvex.h" /* VexArch */ 36 #include "host_generic_regs.h" /* HReg */ 37 38 39 /* --------- Registers. --------- */ 40 41 #define ST_IN static inline 42 43 #define GPR(_mode64, _enc, _ix64, _ix32) \ 44 mkHReg(False, (_mode64) ? HRcInt64 : HRcInt32, \ 45 (_enc), (_mode64) ? (_ix64) : (_ix32)) 46 47 #define FR(_mode64, _enc, _ix64, _ix32) \ 48 mkHReg(False, (_mode64) ? HRcFlt64 : HRcFlt32, \ 49 (_enc), (_mode64) ? (_ix64) : (_ix32)) 50 51 #define DR(_mode64, _enc, _ix64, _ix32) \ 52 mkHReg(False, HRcFlt64, \ 53 (_enc), (_mode64) ? (_ix64) : (_ix32)) 54 55 ST_IN HReg hregMIPS_GPR16 ( Bool mode64 ) { return GPR(mode64, 16, 0, 0); } 56 ST_IN HReg hregMIPS_GPR17 ( Bool mode64 ) { return GPR(mode64, 17, 1, 1); } 57 ST_IN HReg hregMIPS_GPR18 ( Bool mode64 ) { return GPR(mode64, 18, 2, 2); } 58 ST_IN HReg hregMIPS_GPR19 ( Bool mode64 ) { return GPR(mode64, 19, 3, 3); } 59 ST_IN HReg hregMIPS_GPR20 ( Bool mode64 ) { return GPR(mode64, 20, 4, 4); } 60 ST_IN HReg hregMIPS_GPR21 ( Bool mode64 ) { return GPR(mode64, 21, 5, 5); } 61 ST_IN HReg hregMIPS_GPR22 ( Bool mode64 ) { return GPR(mode64, 22, 6, 6); } 62 63 ST_IN HReg hregMIPS_GPR12 ( Bool mode64 ) { return GPR(mode64, 12, 7, 7); } 64 ST_IN HReg hregMIPS_GPR13 ( Bool mode64 ) { return GPR(mode64, 13, 8, 8); } 65 ST_IN HReg hregMIPS_GPR14 ( Bool mode64 ) { return GPR(mode64, 14, 9, 9); } 66 ST_IN HReg hregMIPS_GPR15 ( Bool mode64 ) { return GPR(mode64, 15, 10, 10); } 67 ST_IN HReg hregMIPS_GPR24 ( Bool mode64 ) { return GPR(mode64, 24, 11, 11); } 68 69 ST_IN HReg hregMIPS_F16 ( Bool mode64 ) { return FR (mode64, 16, 12, 12); } 70 ST_IN HReg hregMIPS_F18 ( Bool mode64 ) { return FR (mode64, 18, 13, 13); } 71 ST_IN HReg hregMIPS_F20 ( Bool mode64 ) { return FR (mode64, 20, 14, 14); } 72 ST_IN HReg hregMIPS_F22 ( Bool mode64 ) { return FR (mode64, 22, 15, 15); } 73 ST_IN HReg hregMIPS_F24 ( Bool mode64 ) { return FR (mode64, 24, 16, 16); } 74 ST_IN HReg hregMIPS_F26 ( Bool mode64 ) { return FR (mode64, 26, 17, 17); } 75 ST_IN HReg hregMIPS_F28 ( Bool mode64 ) { return FR (mode64, 28, 18, 18); } 76 ST_IN HReg hregMIPS_F30 ( Bool mode64 ) { return FR (mode64, 30, 19, 19); } 77 78 // DRs are only allocatable in 32-bit mode, so the 64-bit index numbering 79 // doesn't advance here. 80 ST_IN HReg hregMIPS_D0 ( Bool mode64 ) { vassert(!mode64); 81 return DR (mode64, 0, 0, 20); } 82 ST_IN HReg hregMIPS_D1 ( Bool mode64 ) { vassert(!mode64); 83 return DR (mode64, 2, 0, 21); } 84 ST_IN HReg hregMIPS_D2 ( Bool mode64 ) { vassert(!mode64); 85 return DR (mode64, 4, 0, 22); } 86 ST_IN HReg hregMIPS_D3 ( Bool mode64 ) { vassert(!mode64); 87 return DR (mode64, 6, 0, 23); } 88 ST_IN HReg hregMIPS_D4 ( Bool mode64 ) { vassert(!mode64); 89 return DR (mode64, 8, 0, 24); } 90 ST_IN HReg hregMIPS_D5 ( Bool mode64 ) { vassert(!mode64); 91 return DR (mode64, 10, 0, 25); } 92 ST_IN HReg hregMIPS_D6 ( Bool mode64 ) { vassert(!mode64); 93 return DR (mode64, 12, 0, 26); } 94 ST_IN HReg hregMIPS_D7 ( Bool mode64 ) { vassert(!mode64); 95 return DR (mode64, 14, 0, 27); } 96 97 ST_IN HReg hregMIPS_HI ( Bool mode64 ) { return FR (mode64, 33, 20, 28); } 98 ST_IN HReg hregMIPS_LO ( Bool mode64 ) { return FR (mode64, 34, 21, 29); } 99 100 ST_IN HReg hregMIPS_GPR0 ( Bool mode64 ) { return GPR(mode64, 0, 22, 30); } 101 ST_IN HReg hregMIPS_GPR1 ( Bool mode64 ) { return GPR(mode64, 1, 23, 31); } 102 ST_IN HReg hregMIPS_GPR2 ( Bool mode64 ) { return GPR(mode64, 2, 24, 32); } 103 ST_IN HReg hregMIPS_GPR3 ( Bool mode64 ) { return GPR(mode64, 3, 25, 33); } 104 ST_IN HReg hregMIPS_GPR4 ( Bool mode64 ) { return GPR(mode64, 4, 26, 34); } 105 ST_IN HReg hregMIPS_GPR5 ( Bool mode64 ) { return GPR(mode64, 5, 27, 35); } 106 ST_IN HReg hregMIPS_GPR6 ( Bool mode64 ) { return GPR(mode64, 6, 28, 36); } 107 ST_IN HReg hregMIPS_GPR7 ( Bool mode64 ) { return GPR(mode64, 7, 29, 37); } 108 ST_IN HReg hregMIPS_GPR8 ( Bool mode64 ) { return GPR(mode64, 8, 30, 38); } 109 ST_IN HReg hregMIPS_GPR9 ( Bool mode64 ) { return GPR(mode64, 9, 31, 39); } 110 ST_IN HReg hregMIPS_GPR10 ( Bool mode64 ) { return GPR(mode64, 10, 32, 40); } 111 ST_IN HReg hregMIPS_GPR11 ( Bool mode64 ) { return GPR(mode64, 11, 33, 41); } 112 ST_IN HReg hregMIPS_GPR23 ( Bool mode64 ) { return GPR(mode64, 23, 34, 42); } 113 ST_IN HReg hregMIPS_GPR25 ( Bool mode64 ) { return GPR(mode64, 25, 35, 43); } 114 ST_IN HReg hregMIPS_GPR29 ( Bool mode64 ) { return GPR(mode64, 29, 36, 44); } 115 ST_IN HReg hregMIPS_GPR31 ( Bool mode64 ) { return GPR(mode64, 31, 37, 45); } 116 117 #undef ST_IN 118 #undef GPR 119 #undef FR 120 #undef DR 121 122 #define GuestStatePointer(_mode64) hregMIPS_GPR23(_mode64) 123 #define StackFramePointer(_mode64) hregMIPS_GPR30(_mode64) 124 #define StackPointer(_mode64) hregMIPS_GPR29(_mode64) 125 126 /* guest_COND offset */ 127 #define COND_OFFSET(_mode64) ((_mode64) ? 588 : 448) 128 129 /* Num registers used for function calls */ 130 #if defined(VGP_mips32_linux) 131 /* a0, a1, a2, a3 */ 132 # define MIPS_N_REGPARMS 4 133 #else 134 /* a0, a1, a2, a3, a4, a5, a6, a7 */ 135 # define MIPS_N_REGPARMS 8 136 #endif 137 138 extern void ppHRegMIPS ( HReg, Bool ); 139 140 141 /* --------- Condition codes, Intel encoding. --------- */ 142 typedef enum { 143 MIPScc_EQ = 0, /* equal */ 144 MIPScc_NE = 1, /* not equal */ 145 146 MIPScc_HS = 2, /* >=u (higher or same) */ 147 MIPScc_LO = 3, /* <u (lower) */ 148 149 MIPScc_MI = 4, /* minus (negative) */ 150 MIPScc_PL = 5, /* plus (zero or +ve) */ 151 152 MIPScc_VS = 6, /* overflow */ 153 MIPScc_VC = 7, /* no overflow */ 154 155 MIPScc_HI = 8, /* >u (higher) */ 156 MIPScc_LS = 9, /* <=u (lower or same) */ 157 158 MIPScc_GE = 10, /* >=s (signed greater or equal) */ 159 MIPScc_LT = 11, /* <s (signed less than) */ 160 161 MIPScc_GT = 12, /* >s (signed greater) */ 162 MIPScc_LE = 13, /* <=s (signed less or equal) */ 163 164 MIPScc_AL = 14, /* always (unconditional) */ 165 MIPScc_NV = 15 /* never (unconditional): */ 166 } MIPSCondCode; 167 168 extern const HChar *showMIPSCondCode(MIPSCondCode); 169 170 /* --------- Memory address expressions (amodes). --------- */ 171 typedef enum { 172 Mam_IR, /* Immediate (signed 16-bit) + Reg */ 173 Mam_RR /* Reg1 + Reg2 */ 174 } MIPSAModeTag; 175 176 typedef struct { 177 MIPSAModeTag tag; 178 union { 179 struct { 180 HReg base; 181 Int index; 182 } IR; 183 struct { 184 HReg base; 185 HReg index; 186 } RR; 187 } Mam; 188 } MIPSAMode; 189 190 extern MIPSAMode *MIPSAMode_IR(Int, HReg); 191 extern MIPSAMode *MIPSAMode_RR(HReg, HReg); 192 193 extern MIPSAMode *dopyMIPSAMode(MIPSAMode *); 194 extern MIPSAMode *nextMIPSAModeFloat(MIPSAMode *); 195 extern MIPSAMode *nextMIPSAModeInt(MIPSAMode *); 196 197 extern void ppMIPSAMode(MIPSAMode *, Bool); 198 199 /* --------- Operand, which can be a reg or a u16/s16. --------- */ 200 /* ("RH" == "Register or Halfword immediate") */ 201 typedef enum { 202 Mrh_Imm, 203 Mrh_Reg 204 } MIPSRHTag; 205 206 typedef struct { 207 MIPSRHTag tag; 208 union { 209 struct { 210 Bool syned; 211 UShort imm16; 212 } Imm; 213 struct { 214 HReg reg; 215 } Reg; 216 } Mrh; 217 } MIPSRH; 218 219 extern void ppMIPSRH(MIPSRH *, Bool); 220 221 extern MIPSRH *MIPSRH_Imm(Bool, UShort); 222 extern MIPSRH *MIPSRH_Reg(HReg); 223 224 /* --------- Instructions. --------- */ 225 226 /*Tags for operations*/ 227 228 /* --------- */ 229 typedef enum { 230 Mun_CLO, 231 Mun_CLZ, 232 Mun_DCLO, 233 Mun_DCLZ, 234 Mun_NOP, 235 } MIPSUnaryOp; 236 237 extern const HChar *showMIPSUnaryOp(MIPSUnaryOp); 238 /* --------- */ 239 240 /* --------- */ 241 242 typedef enum { 243 Malu_INVALID, 244 Malu_ADD, Malu_SUB, 245 Malu_AND, Malu_OR, Malu_NOR, Malu_XOR, 246 Malu_DADD, Malu_DSUB, 247 Malu_SLT 248 } MIPSAluOp; 249 250 extern const HChar *showMIPSAluOp(MIPSAluOp, 251 Bool /* is the 2nd operand an immediate? */ ); 252 253 /* --------- */ 254 typedef enum { 255 Mshft_INVALID, 256 Mshft_SLL, Mshft_SRL, 257 Mshft_SRA 258 } MIPSShftOp; 259 260 extern const HChar *showMIPSShftOp(MIPSShftOp, 261 Bool /* is the 2nd operand an immediate? */ , 262 Bool /* is this a 32bit or 64bit op? */ ); 263 264 /* --------- */ 265 typedef enum { 266 Macc_ADD, 267 Macc_SUB 268 } MIPSMaccOp; 269 270 extern const HChar *showMIPSMaccOp(MIPSMaccOp, Bool); 271 /* --------- */ 272 273 /* ----- Instruction tags ----- */ 274 typedef enum { 275 Min_LI, /* load word (32/64-bit) immediate (fake insn) */ 276 Min_Alu, /* word add/sub/and/or/xor/nor/others? */ 277 Min_Shft, /* word sll/srl/sra */ 278 Min_Unary, /* clo, clz, nop, neg */ 279 280 Min_Cmp, /* word compare (fake insn) */ 281 282 Min_Mul, /* widening/non-widening multiply */ 283 Min_Div, /* div */ 284 285 Min_Call, /* call to address in register */ 286 287 /* The following 5 insns are mandated by translation chaining */ 288 Min_XDirect, /* direct transfer to GA */ 289 Min_XIndir, /* indirect transfer to GA */ 290 Min_XAssisted, /* assisted transfer to GA */ 291 Min_EvCheck, /* Event check */ 292 Min_ProfInc, /* 64-bit profile counter increment */ 293 294 Min_RdWrLR, /* Read/Write Link Register */ 295 Min_Mthi, /* Move to HI from GP register */ 296 Min_Mtlo, /* Move to LO from GP register */ 297 Min_Mfhi, /* Move from HI to GP register */ 298 Min_Mflo, /* Move from LO to GP register */ 299 Min_Macc, /* Multiply and accumulate */ 300 301 Min_Load, /* zero-extending load a 8|16|32 bit value from mem */ 302 Min_Store, /* store a 8|16|32 bit value to mem */ 303 Min_Cas, /* compare and swap */ 304 Min_LoadL, /* mips Load Linked Word - LL */ 305 Min_StoreC, /* mips Store Conditional Word - SC */ 306 307 Min_FpUnary, /* FP unary op */ 308 Min_FpBinary, /* FP binary op */ 309 Min_FpTernary, /* FP ternary op */ 310 Min_FpConvert, /* FP conversion op */ 311 Min_FpMulAcc, /* FP multipy-accumulate style op */ 312 Min_FpLdSt, /* FP load/store */ 313 Min_FpSTFIW, /* stfiwx */ 314 Min_FpRSP, /* FP round IEEE754 double to IEEE754 single */ 315 Min_FpCftI, /* fcfid/fctid/fctiw */ 316 Min_FpCMov, /* FP floating point conditional move */ 317 Min_MtFCSR, /* set FCSR register */ 318 Min_MfFCSR, /* get FCSR register */ 319 Min_FpCompare, /* FP compare, generating value into int reg */ 320 321 Min_FpGpMove, /* Move from/to fpr to/from gpr */ 322 Min_MoveCond /* Move Conditional */ 323 } MIPSInstrTag; 324 325 /* --------- */ 326 typedef enum { 327 Mfp_INVALID, 328 329 /* Ternary */ 330 Mfp_MADDD, Mfp_MSUBD, 331 Mfp_MADDS, Mfp_MSUBS, 332 333 /* Binary */ 334 Mfp_ADDD, Mfp_SUBD, Mfp_MULD, Mfp_DIVD, 335 Mfp_ADDS, Mfp_SUBS, Mfp_MULS, Mfp_DIVS, 336 337 /* Unary */ 338 Mfp_SQRTS, Mfp_SQRTD, 339 Mfp_ABSS, Mfp_ABSD, Mfp_NEGS, Mfp_NEGD, Mfp_MOVS, Mfp_MOVD, 340 341 /* FP convert */ 342 Mfp_CVTSD, Mfp_CVTSW, Mfp_CVTWD, 343 Mfp_CVTWS, Mfp_CVTDL, Mfp_CVTSL, Mfp_CVTLS, Mfp_CVTLD, Mfp_TRULS, Mfp_TRULD, 344 Mfp_TRUWS, Mfp_TRUWD, Mfp_FLOORWS, Mfp_FLOORWD, Mfp_ROUNDWS, Mfp_ROUNDWD, 345 Mfp_CVTDW, Mfp_CEILWS, Mfp_CEILWD, Mfp_CEILLS, Mfp_CEILLD, Mfp_CVTDS, 346 Mfp_ROUNDLD, Mfp_FLOORLD, 347 348 /* FP compare */ 349 Mfp_CMP_UN, Mfp_CMP_EQ, Mfp_CMP_LT, Mfp_CMP_NGT 350 351 } MIPSFpOp; 352 353 extern const HChar *showMIPSFpOp(MIPSFpOp); 354 355 /* Move from/to fpr to/from gpr */ 356 typedef enum { 357 MFpGpMove_mfc1, /* Move Word From Floating Point - MIPS32 */ 358 MFpGpMove_dmfc1, /* Doubleword Move from Floating Point - MIPS64 */ 359 MFpGpMove_mtc1, /* Move Word to Floating Point - MIPS32 */ 360 MFpGpMove_dmtc1 /* Doubleword Move to Floating Point - MIPS64 */ 361 } MIPSFpGpMoveOp; 362 363 extern const HChar *showMIPSFpGpMoveOp ( MIPSFpGpMoveOp ); 364 365 /* Move Conditional */ 366 typedef enum { 367 MFpMoveCond_movns, /* FP Move Conditional on Not Zero - MIPS32 */ 368 MFpMoveCond_movnd, 369 MMoveCond_movn /* Move Conditional on Not Zero */ 370 } MIPSMoveCondOp; 371 372 extern const HChar *showMIPSMoveCondOp ( MIPSMoveCondOp ); 373 374 /*--------- Structure for instructions ----------*/ 375 /* Destinations are on the LEFT (first operand) */ 376 377 typedef struct { 378 MIPSInstrTag tag; 379 union { 380 /* Get a 32/64-bit literal into a register. 381 May turn into a number of real insns. */ 382 struct { 383 HReg dst; 384 ULong imm; 385 } LI; 386 /* Integer add/sub/and/or/xor. Limitations: 387 - For add, the immediate, if it exists, is a signed 16. 388 - For sub, the immediate, if it exists, is a signed 16 389 which may not be -32768, since no such instruction 390 exists, and so we have to emit addi with +32768, but 391 that is not possible. 392 - For and/or/xor, the immediate, if it exists, 393 is an unsigned 16. 394 */ 395 struct { 396 MIPSAluOp op; 397 HReg dst; 398 HReg srcL; 399 MIPSRH *srcR; 400 } Alu; 401 /* Integer shl/shr/sar. 402 Limitations: the immediate, if it exists, 403 is a signed 5-bit value between 1 and 31 inclusive. 404 */ 405 struct { 406 MIPSShftOp op; 407 Bool sz32; /* mode64 has both 32 and 64bit shft */ 408 HReg dst; 409 HReg srcL; 410 MIPSRH *srcR; 411 } Shft; 412 /* Clz, Clo, nop */ 413 struct { 414 MIPSUnaryOp op; 415 HReg dst; 416 HReg src; 417 } Unary; 418 /* Word compare. Fake instruction, used for basic block ending */ 419 struct { 420 Bool syned; 421 Bool sz32; 422 HReg dst; 423 HReg srcL; 424 HReg srcR; 425 426 MIPSCondCode cond; 427 } Cmp; 428 struct { 429 Bool widening; /* True => widening, False => non-widening */ 430 Bool syned; /* signed/unsigned - meaningless if widenind = False */ 431 Bool sz32; 432 HReg dst; 433 HReg srcL; 434 HReg srcR; 435 } Mul; 436 struct { 437 Bool syned; /* signed/unsigned - meaningless if widenind = False */ 438 Bool sz32; 439 HReg srcL; 440 HReg srcR; 441 } Div; 442 /* Pseudo-insn. Call target (an absolute address), on given 443 condition (which could be Mcc_ALWAYS). argiregs indicates 444 which of $4 .. $7 (mips32) or $4 .. $11 (mips64) 445 carries argument values for this call, 446 using a bit mask (1<<N is set if $N holds an arg, for N in 447 $4 .. $7 or $4 .. $11 inclusive). 448 If cond is != Mcc_ALWAYS, src is checked. 449 Otherwise, unconditional call */ 450 struct { 451 MIPSCondCode cond; 452 Addr64 target; 453 UInt argiregs; 454 HReg src; 455 RetLoc rloc; /* where the return value will be */ 456 } Call; 457 /* Update the guest EIP value, then exit requesting to chain 458 to it. May be conditional. Urr, use of Addr32 implicitly 459 assumes that wordsize(guest) == wordsize(host). */ 460 struct { 461 Addr64 dstGA; /* next guest address */ 462 MIPSAMode* amPC; /* amode in guest state for PC */ 463 MIPSCondCode cond; /* can be MIPScc_AL */ 464 Bool toFastEP; /* chain to the slow or fast point? */ 465 } XDirect; 466 /* Boring transfer to a guest address not known at JIT time. 467 Not chainable. May be conditional. */ 468 struct { 469 HReg dstGA; 470 MIPSAMode* amPC; 471 MIPSCondCode cond; /* can be MIPScc_AL */ 472 } XIndir; 473 /* Assisted transfer to a guest address, most general case. 474 Not chainable. May be conditional. */ 475 struct { 476 HReg dstGA; 477 MIPSAMode* amPC; 478 MIPSCondCode cond; /* can be MIPScc_AL */ 479 IRJumpKind jk; 480 } XAssisted; 481 /* Zero extending loads. Dst size is host word size */ 482 struct { 483 UChar sz; /* 1|2|4|8 */ 484 HReg dst; 485 MIPSAMode *src; 486 } Load; 487 /* 64/32/16/8 bit stores */ 488 struct { 489 UChar sz; /* 1|2|4|8 */ 490 MIPSAMode *dst; 491 HReg src; 492 } Store; 493 struct { 494 UChar sz; /* 4|8 */ 495 HReg dst; 496 MIPSAMode *src; 497 } LoadL; 498 struct { 499 UChar sz; /* 4|8 */ 500 HReg old; 501 HReg addr; 502 HReg expd; 503 HReg data; 504 } Cas; 505 struct { 506 UChar sz; /* 4|8 */ 507 MIPSAMode *dst; 508 HReg src; 509 } StoreC; 510 /* Move from HI/LO register to GP register. */ 511 struct { 512 HReg dst; 513 } MfHL; 514 515 /* Move to HI/LO register from GP register. */ 516 struct { 517 HReg src; 518 } MtHL; 519 520 /* Read/Write Link Register */ 521 struct { 522 Bool wrLR; 523 HReg gpr; 524 } RdWrLR; 525 526 /* MIPS Multiply and accumulate instructions. */ 527 struct { 528 MIPSMaccOp op; 529 Bool syned; 530 531 HReg srcL; 532 HReg srcR; 533 } Macc; 534 535 /* MIPS Floating point */ 536 struct { 537 MIPSFpOp op; 538 HReg dst; 539 HReg src; 540 } FpUnary; 541 struct { 542 MIPSFpOp op; 543 HReg dst; 544 HReg srcL; 545 HReg srcR; 546 } FpBinary; 547 struct { 548 MIPSFpOp op; 549 HReg dst; 550 HReg src1; 551 HReg src2; 552 HReg src3; 553 } FpTernary; 554 struct { 555 MIPSFpOp op; 556 HReg dst; 557 HReg srcML; 558 HReg srcMR; 559 HReg srcAcc; 560 } FpMulAcc; 561 struct { 562 Bool isLoad; 563 UChar sz; /* only 4 (IEEE single) or 8 (IEEE double) */ 564 HReg reg; 565 MIPSAMode *addr; 566 } FpLdSt; 567 568 struct { 569 MIPSFpOp op; 570 HReg dst; 571 HReg src; 572 } FpConvert; 573 struct { 574 MIPSFpOp op; 575 HReg dst; 576 HReg srcL; 577 HReg srcR; 578 UChar cond1; 579 } FpCompare; 580 /* Move from GP register to FCSR register. */ 581 struct { 582 HReg src; 583 } MtFCSR; 584 /* Move from FCSR register to GP register. */ 585 struct { 586 HReg dst; 587 } MfFCSR; 588 struct { 589 MIPSAMode* amCounter; 590 MIPSAMode* amFailAddr; 591 } EvCheck; 592 struct { 593 /* No fields. The address of the counter to inc is 594 installed later, post-translation, by patching it in, 595 as it is not known at translation time. */ 596 } ProfInc; 597 598 /* Move from/to fpr to/from gpr */ 599 struct { 600 MIPSFpGpMoveOp op; 601 HReg dst; 602 HReg src; 603 } FpGpMove; 604 struct { 605 MIPSMoveCondOp op; 606 HReg dst; 607 HReg src; 608 HReg cond; 609 } MoveCond; 610 611 } Min; 612 } MIPSInstr; 613 614 extern MIPSInstr *MIPSInstr_LI(HReg, ULong); 615 extern MIPSInstr *MIPSInstr_Alu(MIPSAluOp, HReg, HReg, MIPSRH *); 616 extern MIPSInstr *MIPSInstr_Shft(MIPSShftOp, Bool sz32, HReg, HReg, MIPSRH *); 617 extern MIPSInstr *MIPSInstr_Unary(MIPSUnaryOp op, HReg dst, HReg src); 618 extern MIPSInstr *MIPSInstr_Cmp(Bool, Bool, HReg, HReg, HReg, MIPSCondCode); 619 620 extern MIPSInstr *MIPSInstr_Mul(Bool syned, Bool hi32, Bool sz32, HReg, 621 HReg, HReg); 622 extern MIPSInstr *MIPSInstr_Div(Bool syned, Bool sz32, HReg, HReg); 623 extern MIPSInstr *MIPSInstr_Madd(Bool, HReg, HReg); 624 extern MIPSInstr *MIPSInstr_Msub(Bool, HReg, HReg); 625 626 extern MIPSInstr *MIPSInstr_Load(UChar sz, HReg dst, MIPSAMode * src, 627 Bool mode64); 628 extern MIPSInstr *MIPSInstr_Store(UChar sz, MIPSAMode * dst, HReg src, 629 Bool mode64); 630 631 extern MIPSInstr *MIPSInstr_LoadL(UChar sz, HReg dst, MIPSAMode * src, 632 Bool mode64); 633 extern MIPSInstr *MIPSInstr_StoreC(UChar sz, MIPSAMode * dst, HReg src, 634 Bool mode64); 635 extern MIPSInstr *MIPSInstr_Cas(UChar sz, HReg old, HReg addr, 636 HReg expd, HReg data, Bool mode64); 637 638 extern MIPSInstr *MIPSInstr_Call ( MIPSCondCode, Addr64, UInt, HReg, RetLoc ); 639 extern MIPSInstr *MIPSInstr_CallAlways ( MIPSCondCode, Addr64, UInt, RetLoc ); 640 641 extern MIPSInstr *MIPSInstr_XDirect ( Addr64 dstGA, MIPSAMode* amPC, 642 MIPSCondCode cond, Bool toFastEP ); 643 extern MIPSInstr *MIPSInstr_XIndir(HReg dstGA, MIPSAMode* amPC, 644 MIPSCondCode cond); 645 extern MIPSInstr *MIPSInstr_XAssisted(HReg dstGA, MIPSAMode* amPC, 646 MIPSCondCode cond, IRJumpKind jk); 647 648 extern MIPSInstr *MIPSInstr_FpUnary(MIPSFpOp op, HReg dst, HReg src); 649 extern MIPSInstr *MIPSInstr_FpBinary(MIPSFpOp op, HReg dst, HReg srcL, 650 HReg srcR); 651 extern MIPSInstr *MIPSInstr_FpTernary ( MIPSFpOp op, HReg dst, HReg src1, 652 HReg src2, HReg src3 ); 653 extern MIPSInstr *MIPSInstr_FpConvert(MIPSFpOp op, HReg dst, HReg src); 654 extern MIPSInstr *MIPSInstr_FpCompare(MIPSFpOp op, HReg dst, HReg srcL, 655 HReg srcR); 656 extern MIPSInstr *MIPSInstr_FpMulAcc(MIPSFpOp op, HReg dst, HReg srcML, 657 HReg srcMR, HReg srcAcc); 658 extern MIPSInstr *MIPSInstr_FpLdSt(Bool isLoad, UChar sz, HReg, MIPSAMode *); 659 extern MIPSInstr *MIPSInstr_FpSTFIW(HReg addr, HReg data); 660 extern MIPSInstr *MIPSInstr_FpRSP(HReg dst, HReg src); 661 extern MIPSInstr *MIPSInstr_FpCftI(Bool fromI, Bool int32, HReg dst, HReg src); 662 extern MIPSInstr *MIPSInstr_FpCMov(MIPSCondCode, HReg dst, HReg src); 663 extern MIPSInstr *MIPSInstr_MtFCSR(HReg src); 664 extern MIPSInstr *MIPSInstr_MfFCSR(HReg dst); 665 extern MIPSInstr *MIPSInstr_FpCmp(HReg dst, HReg srcL, HReg srcR); 666 667 extern MIPSInstr *MIPSInstr_Mfhi(HReg dst); 668 extern MIPSInstr *MIPSInstr_Mflo(HReg dst); 669 extern MIPSInstr *MIPSInstr_Mthi(HReg src); 670 extern MIPSInstr *MIPSInstr_Mtlo(HReg src); 671 672 extern MIPSInstr *MIPSInstr_RdWrLR(Bool wrLR, HReg gpr); 673 674 extern MIPSInstr *MIPSInstr_MoveCond ( MIPSMoveCondOp op, HReg dst, 675 HReg src, HReg cond ); 676 677 extern MIPSInstr *MIPSInstr_FpGpMove ( MIPSFpGpMoveOp op, HReg dst, HReg src ); 678 679 extern MIPSInstr *MIPSInstr_EvCheck(MIPSAMode* amCounter, 680 MIPSAMode* amFailAddr ); 681 extern MIPSInstr *MIPSInstr_ProfInc( void ); 682 683 extern void ppMIPSInstr(const MIPSInstr *, Bool mode64); 684 685 /* Some functions that insulate the register allocator from details 686 of the underlying instruction set. */ 687 extern void getRegUsage_MIPSInstr (HRegUsage *, const MIPSInstr *, Bool); 688 extern void mapRegs_MIPSInstr (HRegRemap *, MIPSInstr *, Bool mode64); 689 extern Bool isMove_MIPSInstr (const MIPSInstr *, HReg *, HReg *); 690 extern Int emit_MIPSInstr (/*MB_MOD*/Bool* is_profInc, 691 UChar* buf, Int nbuf, const MIPSInstr* i, 692 Bool mode64, 693 VexEndness endness_host, 694 const void* disp_cp_chain_me_to_slowEP, 695 const void* disp_cp_chain_me_to_fastEP, 696 const void* disp_cp_xindir, 697 const void* disp_cp_xassisted ); 698 699 extern void genSpill_MIPS ( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2, 700 HReg rreg, Int offset, Bool); 701 extern void genReload_MIPS( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2, 702 HReg rreg, Int offset, Bool); 703 704 extern const RRegUniverse* getRRegUniverse_MIPS ( Bool mode64 ); 705 706 extern HInstrArray *iselSB_MIPS ( const IRSB*, 707 VexArch, 708 const VexArchInfo*, 709 const VexAbiInfo*, 710 Int offs_Host_EvC_Counter, 711 Int offs_Host_EvC_FailAddr, 712 Bool chainingAllowed, 713 Bool addProfInc, 714 Addr max_ga ); 715 716 /* How big is an event check? This is kind of a kludge because it 717 depends on the offsets of host_EvC_FAILADDR and host_EvC_COUNTER, 718 and so assumes that they are both <= 128, and so can use the short 719 offset encoding. This is all checked with assertions, so in the 720 worst case we will merely assert at startup. */ 721 extern Int evCheckSzB_MIPS (void); 722 723 /* Perform a chaining and unchaining of an XDirect jump. */ 724 extern VexInvalRange chainXDirect_MIPS ( VexEndness endness_host, 725 void* place_to_chain, 726 const void* disp_cp_chain_me_EXPECTED, 727 const void* place_to_jump_to, 728 Bool mode64 ); 729 730 extern VexInvalRange unchainXDirect_MIPS ( VexEndness endness_host, 731 void* place_to_unchain, 732 const void* place_to_jump_to_EXPECTED, 733 const void* disp_cp_chain_me, 734 Bool mode64 ); 735 736 /* Patch the counter location into an existing ProfInc point. */ 737 extern VexInvalRange patchProfInc_MIPS ( VexEndness endness_host, 738 void* place_to_patch, 739 const ULong* location_of_counter, 740 Bool mode64 ); 741 742 #endif /* ndef __VEX_HOST_MIPS_DEFS_H */ 743 744 /*---------------------------------------------------------------*/ 745 /*--- end host-mips_defs.h ---*/ 746 /*---------------------------------------------------------------*/ 747