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