1 2 /*--------------------------------------------------------------------*/ 3 /*--- begin guest_mips_toIR.c ---*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2010-2013 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 /* Translates MIPS code to IR. */ 32 33 #include "libvex_basictypes.h" 34 #include "libvex_ir.h" 35 #include "libvex.h" 36 #include "libvex_guest_mips32.h" 37 #include "libvex_guest_mips64.h" 38 39 #include "main_util.h" 40 #include "main_globals.h" 41 #include "guest_generic_bb_to_IR.h" 42 #include "guest_mips_defs.h" 43 44 /*------------------------------------------------------------*/ 45 /*--- Globals ---*/ 46 /*------------------------------------------------------------*/ 47 48 /* These are set at the start of the translation of a instruction, so 49 that we don't have to pass them around endlessly. CONST means does 50 not change during translation of the instruction. */ 51 52 /* CONST: is the host bigendian? This has to do with float vs double 53 register accesses on VFP, but it's complex and not properly thought 54 out. */ 55 static Bool host_is_bigendian; 56 57 /* Pointer to the guest code area. */ 58 static UChar *guest_code; 59 60 /* CONST: The guest address for the instruction currently being 61 translated. */ 62 #if defined(VGP_mips32_linux) 63 static Addr32 guest_PC_curr_instr; 64 #else 65 static Addr64 guest_PC_curr_instr; 66 #endif 67 68 /* MOD: The IRSB* into which we're generating code. */ 69 static IRSB *irsb; 70 71 /* Is our guest binary 32 or 64bit? Set at each call to 72 disInstr_MIPS below. */ 73 static Bool mode64 = False; 74 75 /* CPU has FPU and 32 dbl. prec. FP registers. */ 76 static Bool fp_mode64 = False; 77 78 /* Define 1.0 in single and double precision. */ 79 #define ONE_SINGLE 0x3F800000 80 #define ONE_DOUBLE 0x3FF0000000000000ULL 81 82 /*------------------------------------------------------------*/ 83 /*--- Debugging output ---*/ 84 /*------------------------------------------------------------*/ 85 86 #define DIP(format, args...) \ 87 if (vex_traceflags & VEX_TRACE_FE) \ 88 vex_printf(format, ## args) 89 90 /*------------------------------------------------------------*/ 91 /*--- Helper bits and pieces for deconstructing the ---*/ 92 /*--- mips insn stream. ---*/ 93 /*------------------------------------------------------------*/ 94 95 /* ---------------- Integer registers ---------------- */ 96 97 static UInt integerGuestRegOffset(UInt iregNo) 98 { 99 /* Do we care about endianness here? We do if sub-parts of integer 100 registers are accessed, but I don't think that ever happens on 101 MIPS. */ 102 UInt ret; 103 if (!mode64) 104 switch (iregNo) { 105 case 0: 106 ret = offsetof(VexGuestMIPS32State, guest_r0); break; 107 case 1: 108 ret = offsetof(VexGuestMIPS32State, guest_r1); break; 109 case 2: 110 ret = offsetof(VexGuestMIPS32State, guest_r2); break; 111 case 3: 112 ret = offsetof(VexGuestMIPS32State, guest_r3); break; 113 case 4: 114 ret = offsetof(VexGuestMIPS32State, guest_r4); break; 115 case 5: 116 ret = offsetof(VexGuestMIPS32State, guest_r5); break; 117 case 6: 118 ret = offsetof(VexGuestMIPS32State, guest_r6); break; 119 case 7: 120 ret = offsetof(VexGuestMIPS32State, guest_r7); break; 121 case 8: 122 ret = offsetof(VexGuestMIPS32State, guest_r8); break; 123 case 9: 124 ret = offsetof(VexGuestMIPS32State, guest_r9); break; 125 case 10: 126 ret = offsetof(VexGuestMIPS32State, guest_r10); break; 127 case 11: 128 ret = offsetof(VexGuestMIPS32State, guest_r11); break; 129 case 12: 130 ret = offsetof(VexGuestMIPS32State, guest_r12); break; 131 case 13: 132 ret = offsetof(VexGuestMIPS32State, guest_r13); break; 133 case 14: 134 ret = offsetof(VexGuestMIPS32State, guest_r14); break; 135 case 15: 136 ret = offsetof(VexGuestMIPS32State, guest_r15); break; 137 case 16: 138 ret = offsetof(VexGuestMIPS32State, guest_r16); break; 139 case 17: 140 ret = offsetof(VexGuestMIPS32State, guest_r17); break; 141 case 18: 142 ret = offsetof(VexGuestMIPS32State, guest_r18); break; 143 case 19: 144 ret = offsetof(VexGuestMIPS32State, guest_r19); break; 145 case 20: 146 ret = offsetof(VexGuestMIPS32State, guest_r20); break; 147 case 21: 148 ret = offsetof(VexGuestMIPS32State, guest_r21); break; 149 case 22: 150 ret = offsetof(VexGuestMIPS32State, guest_r22); break; 151 case 23: 152 ret = offsetof(VexGuestMIPS32State, guest_r23); break; 153 case 24: 154 ret = offsetof(VexGuestMIPS32State, guest_r24); break; 155 case 25: 156 ret = offsetof(VexGuestMIPS32State, guest_r25); break; 157 case 26: 158 ret = offsetof(VexGuestMIPS32State, guest_r26); break; 159 case 27: 160 ret = offsetof(VexGuestMIPS32State, guest_r27); break; 161 case 28: 162 ret = offsetof(VexGuestMIPS32State, guest_r28); break; 163 case 29: 164 ret = offsetof(VexGuestMIPS32State, guest_r29); break; 165 case 30: 166 ret = offsetof(VexGuestMIPS32State, guest_r30); break; 167 case 31: 168 ret = offsetof(VexGuestMIPS32State, guest_r31); break; 169 default: 170 vassert(0); 171 break; 172 } 173 else 174 switch (iregNo) { 175 case 0: 176 ret = offsetof(VexGuestMIPS64State, guest_r0); break; 177 case 1: 178 ret = offsetof(VexGuestMIPS64State, guest_r1); break; 179 case 2: 180 ret = offsetof(VexGuestMIPS64State, guest_r2); break; 181 case 3: 182 ret = offsetof(VexGuestMIPS64State, guest_r3); break; 183 case 4: 184 ret = offsetof(VexGuestMIPS64State, guest_r4); break; 185 case 5: 186 ret = offsetof(VexGuestMIPS64State, guest_r5); break; 187 case 6: 188 ret = offsetof(VexGuestMIPS64State, guest_r6); break; 189 case 7: 190 ret = offsetof(VexGuestMIPS64State, guest_r7); break; 191 case 8: 192 ret = offsetof(VexGuestMIPS64State, guest_r8); break; 193 case 9: 194 ret = offsetof(VexGuestMIPS64State, guest_r9); break; 195 case 10: 196 ret = offsetof(VexGuestMIPS64State, guest_r10); break; 197 case 11: 198 ret = offsetof(VexGuestMIPS64State, guest_r11); break; 199 case 12: 200 ret = offsetof(VexGuestMIPS64State, guest_r12); break; 201 case 13: 202 ret = offsetof(VexGuestMIPS64State, guest_r13); break; 203 case 14: 204 ret = offsetof(VexGuestMIPS64State, guest_r14); break; 205 case 15: 206 ret = offsetof(VexGuestMIPS64State, guest_r15); break; 207 case 16: 208 ret = offsetof(VexGuestMIPS64State, guest_r16); break; 209 case 17: 210 ret = offsetof(VexGuestMIPS64State, guest_r17); break; 211 case 18: 212 ret = offsetof(VexGuestMIPS64State, guest_r18); break; 213 case 19: 214 ret = offsetof(VexGuestMIPS64State, guest_r19); break; 215 case 20: 216 ret = offsetof(VexGuestMIPS64State, guest_r20); break; 217 case 21: 218 ret = offsetof(VexGuestMIPS64State, guest_r21); break; 219 case 22: 220 ret = offsetof(VexGuestMIPS64State, guest_r22); break; 221 case 23: 222 ret = offsetof(VexGuestMIPS64State, guest_r23); break; 223 case 24: 224 ret = offsetof(VexGuestMIPS64State, guest_r24); break; 225 case 25: 226 ret = offsetof(VexGuestMIPS64State, guest_r25); break; 227 case 26: 228 ret = offsetof(VexGuestMIPS64State, guest_r26); break; 229 case 27: 230 ret = offsetof(VexGuestMIPS64State, guest_r27); break; 231 case 28: 232 ret = offsetof(VexGuestMIPS64State, guest_r28); break; 233 case 29: 234 ret = offsetof(VexGuestMIPS64State, guest_r29); break; 235 case 30: 236 ret = offsetof(VexGuestMIPS64State, guest_r30); break; 237 case 31: 238 ret = offsetof(VexGuestMIPS64State, guest_r31); break; 239 default: 240 vassert(0); 241 break; 242 } 243 return ret; 244 } 245 246 #if defined(VGP_mips32_linux) 247 #define OFFB_PC offsetof(VexGuestMIPS32State, guest_PC) 248 #else 249 #define OFFB_PC offsetof(VexGuestMIPS64State, guest_PC) 250 #endif 251 252 /* ---------------- Floating point registers ---------------- */ 253 254 static UInt floatGuestRegOffset(UInt fregNo) 255 { 256 vassert(fregNo < 32); 257 UInt ret; 258 if (!mode64) 259 switch (fregNo) { 260 case 0: 261 ret = offsetof(VexGuestMIPS32State, guest_f0); break; 262 case 1: 263 ret = offsetof(VexGuestMIPS32State, guest_f1); break; 264 case 2: 265 ret = offsetof(VexGuestMIPS32State, guest_f2); break; 266 case 3: 267 ret = offsetof(VexGuestMIPS32State, guest_f3); break; 268 case 4: 269 ret = offsetof(VexGuestMIPS32State, guest_f4); break; 270 case 5: 271 ret = offsetof(VexGuestMIPS32State, guest_f5); break; 272 case 6: 273 ret = offsetof(VexGuestMIPS32State, guest_f6); break; 274 case 7: 275 ret = offsetof(VexGuestMIPS32State, guest_f7); break; 276 case 8: 277 ret = offsetof(VexGuestMIPS32State, guest_f8); break; 278 case 9: 279 ret = offsetof(VexGuestMIPS32State, guest_f9); break; 280 case 10: 281 ret = offsetof(VexGuestMIPS32State, guest_f10); break; 282 case 11: 283 ret = offsetof(VexGuestMIPS32State, guest_f11); break; 284 case 12: 285 ret = offsetof(VexGuestMIPS32State, guest_f12); break; 286 case 13: 287 ret = offsetof(VexGuestMIPS32State, guest_f13); break; 288 case 14: 289 ret = offsetof(VexGuestMIPS32State, guest_f14); break; 290 case 15: 291 ret = offsetof(VexGuestMIPS32State, guest_f15); break; 292 case 16: 293 ret = offsetof(VexGuestMIPS32State, guest_f16); break; 294 case 17: 295 ret = offsetof(VexGuestMIPS32State, guest_f17); break; 296 case 18: 297 ret = offsetof(VexGuestMIPS32State, guest_f18); break; 298 case 19: 299 ret = offsetof(VexGuestMIPS32State, guest_f19); break; 300 case 20: 301 ret = offsetof(VexGuestMIPS32State, guest_f20); break; 302 case 21: 303 ret = offsetof(VexGuestMIPS32State, guest_f21); break; 304 case 22: 305 ret = offsetof(VexGuestMIPS32State, guest_f22); break; 306 case 23: 307 ret = offsetof(VexGuestMIPS32State, guest_f23); break; 308 case 24: 309 ret = offsetof(VexGuestMIPS32State, guest_f24); break; 310 case 25: 311 ret = offsetof(VexGuestMIPS32State, guest_f25); break; 312 case 26: 313 ret = offsetof(VexGuestMIPS32State, guest_f26); break; 314 case 27: 315 ret = offsetof(VexGuestMIPS32State, guest_f27); break; 316 case 28: 317 ret = offsetof(VexGuestMIPS32State, guest_f28); break; 318 case 29: 319 ret = offsetof(VexGuestMIPS32State, guest_f29); break; 320 case 30: 321 ret = offsetof(VexGuestMIPS32State, guest_f30); break; 322 case 31: 323 ret = offsetof(VexGuestMIPS32State, guest_f31); break; 324 default: 325 vassert(0); 326 break; 327 } 328 else 329 switch (fregNo) { 330 case 0: 331 ret = offsetof(VexGuestMIPS64State, guest_f0); break; 332 case 1: 333 ret = offsetof(VexGuestMIPS64State, guest_f1); break; 334 case 2: 335 ret = offsetof(VexGuestMIPS64State, guest_f2); break; 336 case 3: 337 ret = offsetof(VexGuestMIPS64State, guest_f3); break; 338 case 4: 339 ret = offsetof(VexGuestMIPS64State, guest_f4); break; 340 case 5: 341 ret = offsetof(VexGuestMIPS64State, guest_f5); break; 342 case 6: 343 ret = offsetof(VexGuestMIPS64State, guest_f6); break; 344 case 7: 345 ret = offsetof(VexGuestMIPS64State, guest_f7); break; 346 case 8: 347 ret = offsetof(VexGuestMIPS64State, guest_f8); break; 348 case 9: 349 ret = offsetof(VexGuestMIPS64State, guest_f9); break; 350 case 10: 351 ret = offsetof(VexGuestMIPS64State, guest_f10); break; 352 case 11: 353 ret = offsetof(VexGuestMIPS64State, guest_f11); break; 354 case 12: 355 ret = offsetof(VexGuestMIPS64State, guest_f12); break; 356 case 13: 357 ret = offsetof(VexGuestMIPS64State, guest_f13); break; 358 case 14: 359 ret = offsetof(VexGuestMIPS64State, guest_f14); break; 360 case 15: 361 ret = offsetof(VexGuestMIPS64State, guest_f15); break; 362 case 16: 363 ret = offsetof(VexGuestMIPS64State, guest_f16); break; 364 case 17: 365 ret = offsetof(VexGuestMIPS64State, guest_f17); break; 366 case 18: 367 ret = offsetof(VexGuestMIPS64State, guest_f18); break; 368 case 19: 369 ret = offsetof(VexGuestMIPS64State, guest_f19); break; 370 case 20: 371 ret = offsetof(VexGuestMIPS64State, guest_f20); break; 372 case 21: 373 ret = offsetof(VexGuestMIPS64State, guest_f21); break; 374 case 22: 375 ret = offsetof(VexGuestMIPS64State, guest_f22); break; 376 case 23: 377 ret = offsetof(VexGuestMIPS64State, guest_f23); break; 378 case 24: 379 ret = offsetof(VexGuestMIPS64State, guest_f24); break; 380 case 25: 381 ret = offsetof(VexGuestMIPS64State, guest_f25); break; 382 case 26: 383 ret = offsetof(VexGuestMIPS64State, guest_f26); break; 384 case 27: 385 ret = offsetof(VexGuestMIPS64State, guest_f27); break; 386 case 28: 387 ret = offsetof(VexGuestMIPS64State, guest_f28); break; 388 case 29: 389 ret = offsetof(VexGuestMIPS64State, guest_f29); break; 390 case 30: 391 ret = offsetof(VexGuestMIPS64State, guest_f30); break; 392 case 31: 393 ret = offsetof(VexGuestMIPS64State, guest_f31); break; 394 default: 395 vassert(0); 396 break; 397 } 398 return ret; 399 } 400 401 /* ---------------- MIPS32 DSP ASE(r2) accumulators ---------------- */ 402 403 static UInt accumulatorGuestRegOffset(UInt acNo) 404 { 405 vassert(!mode64); 406 vassert(acNo <= 3); 407 UInt ret; 408 switch (acNo) { 409 case 0: 410 ret = offsetof(VexGuestMIPS32State, guest_ac0); break; 411 case 1: 412 ret = offsetof(VexGuestMIPS32State, guest_ac1); break; 413 case 2: 414 ret = offsetof(VexGuestMIPS32State, guest_ac2); break; 415 case 3: 416 ret = offsetof(VexGuestMIPS32State, guest_ac3); break; 417 default: 418 vassert(0); 419 break; 420 } 421 return ret; 422 } 423 424 /* Do a endian load of a 32-bit word, regardless of the endianness of the 425 underlying host. */ 426 static inline UInt getUInt(UChar * p) 427 { 428 UInt w = 0; 429 #if defined (_MIPSEL) 430 w = (w << 8) | p[3]; 431 w = (w << 8) | p[2]; 432 w = (w << 8) | p[1]; 433 w = (w << 8) | p[0]; 434 #elif defined (_MIPSEB) 435 w = (w << 8) | p[0]; 436 w = (w << 8) | p[1]; 437 w = (w << 8) | p[2]; 438 w = (w << 8) | p[3]; 439 #endif 440 return w; 441 } 442 443 #define BITS2(_b1,_b0) \ 444 (((_b1) << 1) | (_b0)) 445 446 #define BITS3(_b2,_b1,_b0) \ 447 (((_b2) << 2) | ((_b1) << 1) | (_b0)) 448 449 #define BITS4(_b3,_b2,_b1,_b0) \ 450 (((_b3) << 3) | ((_b2) << 2) | ((_b1) << 1) | (_b0)) 451 452 #define BITS5(_b4,_b3,_b2,_b1,_b0) \ 453 (((_b4) << 4) | BITS4((_b3),(_b2),(_b1),(_b0))) 454 455 #define BITS6(_b5,_b4,_b3,_b2,_b1,_b0) \ 456 ((BITS2((_b5),(_b4)) << 4) \ 457 | BITS4((_b3),(_b2),(_b1),(_b0))) 458 459 #define BITS8(_b7,_b6,_b5,_b4,_b3,_b2,_b1,_b0) \ 460 ((BITS4((_b7),(_b6),(_b5),(_b4)) << 4) \ 461 | BITS4((_b3),(_b2),(_b1),(_b0))) 462 463 #define LOAD_STORE_PATTERN \ 464 t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \ 465 if(!mode64) \ 466 assign(t1, binop(Iop_Add32, getIReg(rs), \ 467 mkU32(extend_s_16to32(imm)))); \ 468 else \ 469 assign(t1, binop(Iop_Add64, getIReg(rs), \ 470 mkU64(extend_s_16to64(imm)))); \ 471 472 #define LOADX_STORE_PATTERN \ 473 t1 = newTemp(mode64 ? Ity_I64 : Ity_I32); \ 474 if(!mode64) \ 475 assign(t1, binop(Iop_Add32, getIReg(regRs), getIReg(regRt))); \ 476 else \ 477 assign(t1, binop(Iop_Add64, getIReg(regRs), getIReg(regRt))); 478 479 #define LWX_SWX_PATTERN64 \ 480 t2 = newTemp(Ity_I64); \ 481 assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL))); \ 482 t4 = newTemp(Ity_I32); \ 483 assign(t4, mkNarrowTo32( ty, binop(Iop_And64, \ 484 mkexpr(t1), mkU64(0x3)))); 485 486 #define LWX_SWX_PATTERN64_1 \ 487 t2 = newTemp(Ity_I64); \ 488 assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL))); \ 489 t4 = newTemp(Ity_I64); \ 490 assign(t4, binop(Iop_And64, mkexpr(t1), mkU64(0x7))); 491 492 #define LWX_SWX_PATTERN \ 493 t2 = newTemp(Ity_I32); \ 494 assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFC))); \ 495 t4 = newTemp(Ity_I32); \ 496 assign(t4, binop(Iop_And32, mkexpr(t1), mkU32(0x00000003))) 497 498 #define SXXV_PATTERN(op) \ 499 putIReg(rd, binop(op, \ 500 getIReg(rt), \ 501 unop(Iop_32to8, \ 502 binop(Iop_And32, \ 503 getIReg(rs), \ 504 mkU32(0x0000001F) \ 505 ) \ 506 ) \ 507 ) \ 508 ) 509 510 #define SXXV_PATTERN64(op) \ 511 putIReg(rd, mkWidenFrom32(ty, binop(op, \ 512 mkNarrowTo32(ty, getIReg(rt)), \ 513 unop(Iop_32to8, \ 514 binop(Iop_And32, \ 515 mkNarrowTo32(ty, getIReg(rs)), \ 516 mkU32(0x0000001F) \ 517 ) \ 518 ) \ 519 ), True \ 520 )) 521 522 #define SXX_PATTERN(op) \ 523 putIReg(rd, binop(op, getIReg(rt), mkU8(sa))); 524 525 #define ALU_PATTERN(op) \ 526 putIReg(rd, binop(op, getIReg(rs), getIReg(rt))); 527 528 #define ALUI_PATTERN(op) \ 529 putIReg(rt, binop(op, getIReg(rs), mkU32(imm))); 530 531 #define ALUI_PATTERN64(op) \ 532 putIReg(rt, binop(op, getIReg(rs), mkU64(imm))); 533 534 #define ALU_PATTERN64(op) \ 535 putIReg(rd, mkWidenFrom32(ty, binop(op, \ 536 mkNarrowTo32(ty, getIReg(rs)), \ 537 mkNarrowTo32(ty, getIReg(rt))), True)); 538 539 #define FP_CONDITIONAL_CODE \ 540 t3 = newTemp(Ity_I32); \ 541 assign(t3, binop(Iop_And32, \ 542 IRExpr_ITE( binop(Iop_CmpEQ32, mkU32(cc), mkU32(0)), \ 543 binop(Iop_Shr32, getFCSR(), mkU8(23)), \ 544 binop(Iop_Shr32, getFCSR(), mkU8(24+cc))), \ 545 mkU32(0x1))); 546 547 #define ILLEGAL_INSTRUCTON \ 548 putPC(mkU32(guest_PC_curr_instr + 4)); \ 549 dres.jk_StopHere = Ijk_SigILL; \ 550 dres.whatNext = Dis_StopHere; 551 552 /*------------------------------------------------------------*/ 553 /*--- Field helpers ---*/ 554 /*------------------------------------------------------------*/ 555 556 static UInt get_opcode(UInt mipsins) 557 { 558 return (0xFC000000 & mipsins) >> 26; 559 } 560 561 static UInt get_rs(UInt mipsins) 562 { 563 return (0x03E00000 & mipsins) >> 21; 564 } 565 566 static UInt get_rt(UInt mipsins) 567 { 568 return (0x001F0000 & mipsins) >> 16; 569 } 570 571 static UInt get_imm(UInt mipsins) 572 { 573 return (0x0000FFFF & mipsins); 574 } 575 576 static UInt get_instr_index(UInt mipsins) 577 { 578 return (0x03FFFFFF & mipsins); 579 } 580 581 static UInt get_rd(UInt mipsins) 582 { 583 return (0x0000F800 & mipsins) >> 11; 584 } 585 586 static UInt get_sa(UInt mipsins) 587 { 588 return (0x000007C0 & mipsins) >> 6; 589 } 590 591 static UInt get_function(UInt mipsins) 592 { 593 return (0x0000003F & mipsins); 594 } 595 596 static UInt get_ft(UInt mipsins) 597 { 598 return (0x001F0000 & mipsins) >> 16; 599 } 600 601 static UInt get_fs(UInt mipsins) 602 { 603 return (0x0000F800 & mipsins) >> 11; 604 } 605 606 static UInt get_fd(UInt mipsins) 607 { 608 return (0x000007C0 & mipsins) >> 6; 609 } 610 611 static UInt get_mov_cc(UInt mipsins) 612 { 613 return (0x001C0000 & mipsins) >> 18; 614 } 615 616 static UInt get_bc1_cc(UInt mipsins) 617 { 618 return (0x001C0000 & mipsins) >> 18; 619 } 620 621 static UInt get_fpc_cc(UInt mipsins) 622 { 623 return (0x00000700 & mipsins) >> 8; 624 } 625 626 static UInt get_tf(UInt mipsins) 627 { 628 return (0x00010000 & mipsins) >> 16; 629 } 630 631 static UInt get_nd(UInt mipsins) 632 { 633 return (0x00020000 & mipsins) >> 17; 634 } 635 636 static UInt get_fmt(UInt mipsins) 637 { 638 return (0x03E00000 & mipsins) >> 21; 639 } 640 641 static UInt get_FC(UInt mipsins) 642 { 643 return (0x000000F0 & mipsins) >> 4; 644 } 645 646 static UInt get_cond(UInt mipsins) 647 { 648 return (0x0000000F & mipsins); 649 } 650 651 /* for break & syscall */ 652 static UInt get_code(UInt mipsins) 653 { 654 return (0xFFC0 & mipsins) >> 6; 655 } 656 657 static UInt get_lsb(UInt mipsins) 658 { 659 return (0x7C0 & mipsins) >> 6; 660 } 661 662 static UInt get_msb(UInt mipsins) 663 { 664 return (0x0000F800 & mipsins) >> 11; 665 } 666 667 static UInt get_rot(UInt mipsins) 668 { 669 return (0x00200000 & mipsins) >> 21; 670 } 671 672 static UInt get_rotv(UInt mipsins) 673 { 674 return (0x00000040 & mipsins) >> 6; 675 } 676 677 static UInt get_sel(UInt mipsins) 678 { 679 return (0x00000007 & mipsins); 680 } 681 682 /* Get acc number for all MIPS32 DSP ASE(r2) instructions that use them, 683 except for MFHI and MFLO. */ 684 static UInt get_acNo(UInt mipsins) 685 { 686 return (0x00001800 & mipsins) >> 11; 687 } 688 689 /* Get accumulator number for MIPS32 DSP ASEr2 MFHI and MFLO instructions. */ 690 static UInt get_acNo_mfhilo(UInt mipsins) 691 { 692 return (0x00600000 & mipsins) >> 21; 693 } 694 695 /* Get mask field (helper function for wrdsp instruction). */ 696 static UInt get_wrdspMask(UInt mipsins) 697 { 698 return (0x001ff800 & mipsins) >> 11; 699 } 700 701 /* Get mask field (helper function for rddsp instruction). */ 702 static UInt get_rddspMask(UInt mipsins) 703 { 704 return (0x03ff0000 & mipsins) >> 16; 705 } 706 707 /* Get shift field (helper function for DSP ASE instructions). */ 708 static UInt get_shift(UInt mipsins) 709 { 710 return (0x03f00000 & mipsins) >> 20; 711 } 712 713 /* Get immediate field for DSP ASE instructions. */ 714 static UInt get_dspImm(UInt mipsins) 715 { 716 return (0x03ff0000 & mipsins) >> 16; 717 } 718 719 static Bool branch_or_jump(UChar * addr) 720 { 721 UInt fmt; 722 UInt cins = getUInt(addr); 723 724 UInt opcode = get_opcode(cins); 725 UInt rt = get_rt(cins); 726 UInt function = get_function(cins); 727 728 /* bgtz, blez, bne, beq, jal */ 729 if (opcode == 0x07 || opcode == 0x06 || opcode == 0x05 || opcode == 0x04 730 || opcode == 0x03 || opcode == 0x02) { 731 return True; 732 } 733 734 /* bgez */ 735 if (opcode == 0x01 && rt == 0x01) { 736 return True; 737 } 738 739 /* bgezal */ 740 if (opcode == 0x01 && rt == 0x11) { 741 return True; 742 } 743 744 /* bltzal */ 745 if (opcode == 0x01 && rt == 0x10) { 746 return True; 747 } 748 749 /* bltz */ 750 if (opcode == 0x01 && rt == 0x00) { 751 return True; 752 } 753 754 /* jalr */ 755 if (opcode == 0x00 && function == 0x09) { 756 return True; 757 } 758 759 /* jr */ 760 if (opcode == 0x00 && function == 0x08) { 761 return True; 762 } 763 764 if (opcode == 0x11) { 765 /*bc1f & bc1t */ 766 fmt = get_fmt(cins); 767 if (fmt == 0x08) { 768 return True; 769 } 770 } 771 772 /* bposge32 */ 773 if (opcode == 0x01 && rt == 0x1c) { 774 return True; 775 } 776 777 return False; 778 } 779 780 static Bool is_Branch_or_Jump_and_Link(UChar * addr) 781 { 782 UInt cins = getUInt(addr); 783 784 UInt opcode = get_opcode(cins); 785 UInt rt = get_rt(cins); 786 UInt function = get_function(cins); 787 788 /* jal */ 789 if (opcode == 0x02) { 790 return True; 791 } 792 793 /* bgezal */ 794 if (opcode == 0x01 && rt == 0x11) { 795 return True; 796 } 797 798 /* bltzal */ 799 if (opcode == 0x01 && rt == 0x10) { 800 return True; 801 } 802 803 /* jalr */ 804 if (opcode == 0x00 && function == 0x09) { 805 return True; 806 } 807 808 return False; 809 } 810 811 static Bool branch_or_link_likely(UChar * addr) 812 { 813 UInt cins = getUInt(addr); 814 UInt opcode = get_opcode(cins); 815 UInt rt = get_rt(cins); 816 817 /* bgtzl, blezl, bnel, beql */ 818 if (opcode == 0x17 || opcode == 0x16 || opcode == 0x15 || opcode == 0x14) 819 return True; 820 821 /* bgezl */ 822 if (opcode == 0x01 && rt == 0x03) 823 return True; 824 825 /* bgezall */ 826 if (opcode == 0x01 && rt == 0x13) 827 return True; 828 829 /* bltzall */ 830 if (opcode == 0x01 && rt == 0x12) 831 return True; 832 833 /* bltzl */ 834 if (opcode == 0x01 && rt == 0x02) 835 return True; 836 837 return False; 838 } 839 840 /*------------------------------------------------------------*/ 841 /*--- Helper bits and pieces for creating IR fragments. ---*/ 842 /*------------------------------------------------------------*/ 843 844 static IRExpr *mkU8(UInt i) 845 { 846 vassert(i < 256); 847 return IRExpr_Const(IRConst_U8((UChar) i)); 848 } 849 850 /* Create an expression node for a 16-bit integer constant. */ 851 static IRExpr *mkU16(UInt i) 852 { 853 return IRExpr_Const(IRConst_U16(i)); 854 } 855 856 /* Create an expression node for a 32-bit integer constant. */ 857 static IRExpr *mkU32(UInt i) 858 { 859 return IRExpr_Const(IRConst_U32(i)); 860 } 861 862 /* Create an expression node for a 64-bit integer constant. */ 863 static IRExpr *mkU64(ULong i) 864 { 865 return IRExpr_Const(IRConst_U64(i)); 866 } 867 868 static IRExpr *mkexpr(IRTemp tmp) 869 { 870 return IRExpr_RdTmp(tmp); 871 } 872 873 static IRExpr *unop(IROp op, IRExpr * a) 874 { 875 return IRExpr_Unop(op, a); 876 } 877 878 static IRExpr *binop(IROp op, IRExpr * a1, IRExpr * a2) 879 { 880 return IRExpr_Binop(op, a1, a2); 881 } 882 883 static IRExpr *triop(IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3) 884 { 885 return IRExpr_Triop(op, a1, a2, a3); 886 } 887 888 static IRExpr *qop ( IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3, 889 IRExpr * a4 ) 890 { 891 return IRExpr_Qop(op, a1, a2, a3, a4); 892 } 893 894 static IRExpr *load(IRType ty, IRExpr * addr) 895 { 896 IRExpr *load1 = NULL; 897 #if defined (_MIPSEL) 898 load1 = IRExpr_Load(Iend_LE, ty, addr); 899 #elif defined (_MIPSEB) 900 load1 = IRExpr_Load(Iend_BE, ty, addr); 901 #endif 902 return load1; 903 } 904 905 /* Add a statement to the list held by "irsb". */ 906 static void stmt(IRStmt * st) 907 { 908 addStmtToIRSB(irsb, st); 909 } 910 911 static void assign(IRTemp dst, IRExpr * e) 912 { 913 stmt(IRStmt_WrTmp(dst, e)); 914 } 915 916 static void store(IRExpr * addr, IRExpr * data) 917 { 918 #if defined (_MIPSEL) 919 stmt(IRStmt_Store(Iend_LE, addr, data)); 920 #elif defined (_MIPSEB) 921 stmt(IRStmt_Store(Iend_BE, addr, data)); 922 #endif 923 } 924 925 /* Generate a new temporary of the given type. */ 926 static IRTemp newTemp(IRType ty) 927 { 928 vassert(isPlausibleIRType(ty)); 929 return newIRTemp(irsb->tyenv, ty); 930 } 931 932 /* Generate an expression for SRC rotated right by ROT. */ 933 static IRExpr *genROR32(IRExpr * src, Int rot) 934 { 935 vassert(rot >= 0 && rot < 32); 936 if (rot == 0) 937 return src; 938 return binop(Iop_Or32, binop(Iop_Shl32, src, mkU8(32 - rot)), 939 binop(Iop_Shr32, src, mkU8(rot))); 940 } 941 942 static IRExpr *genRORV32(IRExpr * src, IRExpr * rs) 943 { 944 IRTemp t0 = newTemp(Ity_I8); 945 IRTemp t1 = newTemp(Ity_I8); 946 947 assign(t0, unop(Iop_32to8, binop(Iop_And32, rs, mkU32(0x0000001F)))); 948 assign(t1, binop(Iop_Sub8, mkU8(32), mkexpr(t0))); 949 return binop(Iop_Or32, binop(Iop_Shl32, src, mkexpr(t1)), 950 binop(Iop_Shr32, src, mkexpr(t0))); 951 } 952 953 static UShort extend_s_10to16(UInt x) 954 { 955 return (UShort) ((((Int) x) << 22) >> 22); 956 } 957 958 static ULong extend_s_10to32(UInt x) 959 { 960 return (ULong)((((Long) x) << 22) >> 22); 961 } 962 963 static ULong extend_s_10to64(UInt x) 964 { 965 return (ULong)((((Long) x) << 54) >> 54); 966 } 967 968 static UInt extend_s_16to32(UInt x) 969 { 970 return (UInt) ((((Int) x) << 16) >> 16); 971 } 972 973 static UInt extend_s_18to32(UInt x) 974 { 975 return (UInt) ((((Int) x) << 14) >> 14); 976 } 977 978 static ULong extend_s_16to64 ( UInt x ) 979 { 980 return (ULong) ((((Long) x) << 48) >> 48); 981 } 982 983 static ULong extend_s_18to64 ( UInt x ) 984 { 985 return (ULong) ((((Long) x) << 46) >> 46); 986 } 987 988 static ULong extend_s_32to64 ( UInt x ) 989 { 990 return (ULong) ((((Long) x) << 32) >> 32); 991 } 992 993 static void jmp_lit32 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr32 d32 ) 994 { 995 vassert(dres->whatNext == Dis_Continue); 996 vassert(dres->len == 0); 997 vassert(dres->continueAt == 0); 998 vassert(dres->jk_StopHere == Ijk_INVALID); 999 dres->whatNext = Dis_StopHere; 1000 dres->jk_StopHere = kind; 1001 stmt( IRStmt_Put( OFFB_PC, mkU32(d32) ) ); 1002 } 1003 1004 static void jmp_lit64 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr64 d64 ) 1005 { 1006 vassert(dres->whatNext == Dis_Continue); 1007 vassert(dres->len == 0); 1008 vassert(dres->continueAt == 0); 1009 vassert(dres->jk_StopHere == Ijk_INVALID); 1010 dres->whatNext = Dis_StopHere; 1011 dres->jk_StopHere = kind; 1012 stmt(IRStmt_Put(OFFB_PC, mkU64(d64))); 1013 } 1014 1015 /* Get value from accumulator (helper function for MIPS32 DSP ASE instructions). 1016 This function should be called before any other operation if widening 1017 multiplications are used. */ 1018 static IRExpr *getAcc(UInt acNo) 1019 { 1020 vassert(!mode64); 1021 vassert(acNo <= 3); 1022 return IRExpr_Get(accumulatorGuestRegOffset(acNo), Ity_I64); 1023 } 1024 1025 /* Get value from DSPControl register (helper function for MIPS32 DSP ASE 1026 instructions). */ 1027 static IRExpr *getDSPControl(void) 1028 { 1029 vassert(!mode64); 1030 return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_DSPControl), Ity_I32); 1031 } 1032 1033 /* Put value to DSPControl register. Expression e is written to DSPControl as 1034 is. If only certain bits of DSPControl need to be changed, it should be done 1035 before calling putDSPControl(). It could be done by reading DSPControl and 1036 ORing it with appropriate mask. */ 1037 static void putDSPControl(IRExpr * e) 1038 { 1039 vassert(!mode64); 1040 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_DSPControl), e)); 1041 } 1042 1043 /* Fetch a byte from the guest insn stream. */ 1044 static UChar getIByte(Int delta) 1045 { 1046 return guest_code[delta]; 1047 } 1048 1049 static IRExpr *getIReg(UInt iregNo) 1050 { 1051 if (0 == iregNo) { 1052 return mode64 ? mkU64(0x0) : mkU32(0x0); 1053 } else { 1054 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1055 vassert(iregNo < 32); 1056 return IRExpr_Get(integerGuestRegOffset(iregNo), ty); 1057 } 1058 } 1059 1060 static IRExpr *getHI(void) 1061 { 1062 if (mode64) 1063 return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_HI), Ity_I64); 1064 else 1065 return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_HI), Ity_I32); 1066 } 1067 1068 static IRExpr *getLO(void) 1069 { 1070 if (mode64) 1071 return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LO), Ity_I64); 1072 else 1073 return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LO), Ity_I32); 1074 } 1075 1076 static IRExpr *getFCSR(void) 1077 { 1078 if (mode64) 1079 return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_FCSR), Ity_I32); 1080 else 1081 return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_FCSR), Ity_I32); 1082 } 1083 1084 /* Get byte from register reg, byte pos from 0 to 3 (or 7 for MIPS64) . */ 1085 static IRExpr *getByteFromReg(UInt reg, UInt byte_pos) 1086 { 1087 UInt pos = byte_pos * 8; 1088 if (mode64) 1089 return unop(Iop_64to8, binop(Iop_And64, 1090 binop(Iop_Shr64, getIReg(reg), mkU8(pos)), 1091 mkU64(0xFF))); 1092 else 1093 return unop(Iop_32to8, binop(Iop_And32, 1094 binop(Iop_Shr32, getIReg(reg), mkU8(pos)), 1095 mkU32(0xFF))); 1096 } 1097 1098 static void putFCSR(IRExpr * e) 1099 { 1100 if (mode64) 1101 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_FCSR), e)); 1102 else 1103 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_FCSR), e)); 1104 } 1105 1106 /* fs - fpu source register number. 1107 inst - fpu instruction that needs to be executed. 1108 sz32 - size of source register. 1109 opN - number of operads: 1110 1 - unary operation. 1111 2 - binary operation. */ 1112 static void calculateFCSR(UInt fs, UInt ft, UInt inst, Bool sz32, UInt opN) 1113 { 1114 IRDirty *d; 1115 IRTemp fcsr = newTemp(Ity_I32); 1116 /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper. */ 1117 if (fp_mode64) 1118 d = unsafeIRDirty_1_N(fcsr, 0, 1119 "mips_dirtyhelper_calculate_FCSR_fp64", 1120 &mips_dirtyhelper_calculate_FCSR_fp64, 1121 mkIRExprVec_4(IRExpr_BBPTR(), 1122 mkU32(fs), 1123 mkU32(ft), 1124 mkU32(inst))); 1125 else 1126 d = unsafeIRDirty_1_N(fcsr, 0, 1127 "mips_dirtyhelper_calculate_FCSR_fp32", 1128 &mips_dirtyhelper_calculate_FCSR_fp32, 1129 mkIRExprVec_4(IRExpr_BBPTR(), 1130 mkU32(fs), 1131 mkU32(ft), 1132 mkU32(inst))); 1133 1134 if (opN == 1) { /* Unary operation. */ 1135 /* Declare we're reading guest state. */ 1136 if (sz32 || fp_mode64) 1137 d->nFxState = 2; 1138 else 1139 d->nFxState = 3; 1140 vex_bzero(&d->fxState, sizeof(d->fxState)); 1141 1142 d->fxState[0].fx = Ifx_Read; /* read */ 1143 if (mode64) 1144 d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR); 1145 else 1146 d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR); 1147 d->fxState[0].size = sizeof(UInt); 1148 d->fxState[1].fx = Ifx_Read; /* read */ 1149 d->fxState[1].offset = floatGuestRegOffset(fs); 1150 d->fxState[1].size = sizeof(ULong); 1151 1152 if (!(sz32 || fp_mode64)) { 1153 d->fxState[2].fx = Ifx_Read; /* read */ 1154 d->fxState[2].offset = floatGuestRegOffset(fs+1); 1155 d->fxState[2].size = sizeof(ULong); 1156 } 1157 } else if (opN == 2) { /* Binary operation. */ 1158 /* Declare we're reading guest state. */ 1159 if (sz32 || fp_mode64) 1160 d->nFxState = 3; 1161 else 1162 d->nFxState = 5; 1163 vex_bzero(&d->fxState, sizeof(d->fxState)); 1164 1165 d->fxState[0].fx = Ifx_Read; /* read */ 1166 if (mode64) 1167 d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR); 1168 else 1169 d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR); 1170 d->fxState[0].size = sizeof(UInt); 1171 d->fxState[1].fx = Ifx_Read; /* read */ 1172 d->fxState[1].offset = floatGuestRegOffset(fs); 1173 d->fxState[1].size = sizeof(ULong); 1174 d->fxState[2].fx = Ifx_Read; /* read */ 1175 d->fxState[2].offset = floatGuestRegOffset(ft); 1176 d->fxState[2].size = sizeof(ULong); 1177 1178 if (!(sz32 || fp_mode64)) { 1179 d->fxState[3].fx = Ifx_Read; /* read */ 1180 d->fxState[3].offset = floatGuestRegOffset(fs+1); 1181 d->fxState[3].size = sizeof(ULong); 1182 d->fxState[4].fx = Ifx_Read; /* read */ 1183 d->fxState[4].offset = floatGuestRegOffset(ft+1); 1184 d->fxState[4].size = sizeof(ULong); 1185 } 1186 } 1187 1188 stmt(IRStmt_Dirty(d)); 1189 1190 putFCSR(mkexpr(fcsr)); 1191 } 1192 1193 static IRExpr *getULR(void) 1194 { 1195 if (mode64) 1196 return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_ULR), Ity_I64); 1197 else 1198 return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_ULR), Ity_I32); 1199 } 1200 1201 static void putIReg(UInt archreg, IRExpr * e) 1202 { 1203 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1204 vassert(archreg < 32); 1205 vassert(typeOfIRExpr(irsb->tyenv, e) == ty); 1206 if (archreg != 0) 1207 stmt(IRStmt_Put(integerGuestRegOffset(archreg), e)); 1208 } 1209 1210 static IRExpr *mkNarrowTo32(IRType ty, IRExpr * src) 1211 { 1212 vassert(ty == Ity_I32 || ty == Ity_I64); 1213 return ty == Ity_I64 ? unop(Iop_64to32, src) : src; 1214 } 1215 1216 static void putLO(IRExpr * e) 1217 { 1218 if (mode64) { 1219 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LO), e)); 1220 } else { 1221 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LO), e)); 1222 /* Add value to lower 32 bits of ac0 to maintain compatibility between 1223 regular MIPS32 instruction set and MIPS DSP ASE. Keep higher 32bits 1224 unchanged. */ 1225 IRTemp t_lo = newTemp(Ity_I32); 1226 IRTemp t_hi = newTemp(Ity_I32); 1227 assign(t_lo, e); 1228 assign(t_hi, unop(Iop_64HIto32, getAcc(0))); 1229 stmt(IRStmt_Put(accumulatorGuestRegOffset(0), 1230 binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo)))); 1231 } 1232 } 1233 1234 static void putHI(IRExpr * e) 1235 { 1236 if (mode64) { 1237 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_HI), e)); 1238 } else { 1239 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_HI), e)); 1240 /* Add value to higher 32 bits of ac0 to maintain compatibility between 1241 regular MIPS32 instruction set and MIPS DSP ASE. Keep lower 32bits 1242 unchanged. */ 1243 IRTemp t_lo = newTemp(Ity_I32); 1244 IRTemp t_hi = newTemp(Ity_I32); 1245 assign(t_hi, e); 1246 assign(t_lo, unop(Iop_64to32, getAcc(0))); 1247 stmt(IRStmt_Put(accumulatorGuestRegOffset(0), 1248 binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo)))); 1249 } 1250 } 1251 1252 /* Put value to accumulator(helper function for MIPS32 DSP ASE instructions). */ 1253 static void putAcc(UInt acNo, IRExpr * e) 1254 { 1255 vassert(!mode64); 1256 vassert(acNo <= 3); 1257 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I64); 1258 stmt(IRStmt_Put(accumulatorGuestRegOffset(acNo), e)); 1259 /* If acNo = 0, split value to HI and LO regs in order to maintain compatibility 1260 between MIPS32 and MIPS DSP ASE insn sets. */ 1261 if (0 == acNo) { 1262 putLO(unop(Iop_64to32, e)); 1263 putHI(unop(Iop_64HIto32, e)); 1264 } 1265 } 1266 1267 static IRExpr *mkNarrowTo8 ( IRType ty, IRExpr * src ) 1268 { 1269 vassert(ty == Ity_I32 || ty == Ity_I64); 1270 return ty == Ity_I64 ? unop(Iop_64to8, src) : unop(Iop_32to8, src); 1271 } 1272 1273 static void putPC(IRExpr * e) 1274 { 1275 stmt(IRStmt_Put(OFFB_PC, e)); 1276 } 1277 1278 static IRExpr *mkWidenFrom32(IRType ty, IRExpr * src, Bool sined) 1279 { 1280 vassert(ty == Ity_I32 || ty == Ity_I64); 1281 if (ty == Ity_I32) 1282 return src; 1283 return (sined) ? unop(Iop_32Sto64, src) : unop(Iop_32Uto64, src); 1284 } 1285 1286 /* Narrow 8/16/32 bit int expr to 8/16/32. Clearly only some 1287 of these combinations make sense. */ 1288 static IRExpr *narrowTo(IRType dst_ty, IRExpr * e) 1289 { 1290 IRType src_ty = typeOfIRExpr(irsb->tyenv, e); 1291 if (src_ty == dst_ty) 1292 return e; 1293 if (src_ty == Ity_I32 && dst_ty == Ity_I16) 1294 return unop(Iop_32to16, e); 1295 if (src_ty == Ity_I32 && dst_ty == Ity_I8) 1296 return unop(Iop_32to8, e); 1297 if (src_ty == Ity_I64 && dst_ty == Ity_I8) { 1298 vassert(mode64); 1299 return unop(Iop_64to8, e); 1300 } 1301 if (src_ty == Ity_I64 && dst_ty == Ity_I16) { 1302 vassert(mode64); 1303 return unop(Iop_64to16, e); 1304 } 1305 vpanic("narrowTo(mips)"); 1306 return 0; 1307 } 1308 1309 static IRExpr *getLoFromF64(IRType ty, IRExpr * src) 1310 { 1311 vassert(ty == Ity_F32 || ty == Ity_F64); 1312 if (ty == Ity_F64) { 1313 IRTemp t0, t1; 1314 t0 = newTemp(Ity_I64); 1315 t1 = newTemp(Ity_I32); 1316 assign(t0, unop(Iop_ReinterpF64asI64, src)); 1317 assign(t1, unop(Iop_64to32, mkexpr(t0))); 1318 return unop(Iop_ReinterpI32asF32, mkexpr(t1)); 1319 } else 1320 return src; 1321 } 1322 1323 static IRExpr *mkWidenFromF32(IRType ty, IRExpr * src) 1324 { 1325 vassert(ty == Ity_F32 || ty == Ity_F64); 1326 if (ty == Ity_F64) { 1327 IRTemp t0 = newTemp(Ity_I32); 1328 IRTemp t1 = newTemp(Ity_I64); 1329 assign(t0, unop(Iop_ReinterpF32asI32, src)); 1330 assign(t1, binop(Iop_32HLto64, mkU32(0x0), mkexpr(t0))); 1331 return unop(Iop_ReinterpI64asF64, mkexpr(t1)); 1332 } else 1333 return src; 1334 } 1335 1336 static IRExpr *dis_branch_likely(IRExpr * guard, UInt imm) 1337 { 1338 ULong branch_offset; 1339 IRTemp t0; 1340 1341 /* PC = PC + (SignExtend(signed_immed_24) << 2) 1342 An 18-bit signed offset (the 16-bit offset field shifted left 2 bits) 1343 is added to the address of the instruction following 1344 the branch (not the branch itself), in the branch delay slot, to form 1345 a PC-relative effective target address. */ 1346 if (mode64) 1347 branch_offset = extend_s_18to64(imm << 2); 1348 else 1349 branch_offset = extend_s_18to32(imm << 2); 1350 1351 t0 = newTemp(Ity_I1); 1352 assign(t0, guard); 1353 1354 if (mode64) 1355 stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring, 1356 IRConst_U64(guest_PC_curr_instr + 8), OFFB_PC)); 1357 else 1358 stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring, 1359 IRConst_U32(guest_PC_curr_instr + 8), OFFB_PC)); 1360 1361 irsb->jumpkind = Ijk_Boring; 1362 1363 if (mode64) 1364 return mkU64(guest_PC_curr_instr + 4 + branch_offset); 1365 else 1366 return mkU32(guest_PC_curr_instr + 4 + branch_offset); 1367 } 1368 1369 static void dis_branch(Bool link, IRExpr * guard, UInt imm, IRStmt ** set) 1370 { 1371 ULong branch_offset; 1372 IRTemp t0; 1373 1374 if (link) { /* LR (GPR31) = addr of the 2nd instr after branch instr */ 1375 if (mode64) 1376 putIReg(31, mkU64(guest_PC_curr_instr + 8)); 1377 else 1378 putIReg(31, mkU32(guest_PC_curr_instr + 8)); 1379 } 1380 1381 /* PC = PC + (SignExtend(signed_immed_24) << 2) 1382 An 18-bit signed offset (the 16-bit offset field shifted left 2 bits) 1383 is added to the address of the instruction following 1384 the branch (not the branch itself), in the branch delay slot, to form 1385 a PC-relative effective target address. */ 1386 1387 if (mode64) 1388 branch_offset = extend_s_18to64(imm << 2); 1389 else 1390 branch_offset = extend_s_18to32(imm << 2); 1391 1392 t0 = newTemp(Ity_I1); 1393 assign(t0, guard); 1394 if (mode64) 1395 *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring, 1396 IRConst_U64(guest_PC_curr_instr + 4 + branch_offset), 1397 OFFB_PC); 1398 else 1399 *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring, 1400 IRConst_U32(guest_PC_curr_instr + 4 + 1401 (UInt) branch_offset), OFFB_PC); 1402 } 1403 1404 static IRExpr *getFReg(UInt fregNo) 1405 { 1406 vassert(fregNo < 32); 1407 IRType ty = fp_mode64 ? Ity_F64 : Ity_F32; 1408 return IRExpr_Get(floatGuestRegOffset(fregNo), ty); 1409 } 1410 1411 static IRExpr *getDReg(UInt dregNo) 1412 { 1413 vassert(dregNo < 32); 1414 if (fp_mode64) { 1415 return IRExpr_Get(floatGuestRegOffset(dregNo), Ity_F64); 1416 } else { 1417 /* Read a floating point register pair and combine their contents into a 1418 64-bit value */ 1419 IRTemp t0 = newTemp(Ity_F32); 1420 IRTemp t1 = newTemp(Ity_F32); 1421 IRTemp t2 = newTemp(Ity_F64); 1422 IRTemp t3 = newTemp(Ity_I32); 1423 IRTemp t4 = newTemp(Ity_I32); 1424 IRTemp t5 = newTemp(Ity_I64); 1425 1426 assign(t0, getFReg(dregNo)); 1427 assign(t1, getFReg(dregNo + 1)); 1428 1429 assign(t3, unop(Iop_ReinterpF32asI32, mkexpr(t0))); 1430 assign(t4, unop(Iop_ReinterpF32asI32, mkexpr(t1))); 1431 assign(t5, binop(Iop_32HLto64, mkexpr(t4), mkexpr(t3))); 1432 assign(t2, unop(Iop_ReinterpI64asF64, mkexpr(t5))); 1433 1434 return mkexpr(t2); 1435 } 1436 } 1437 1438 static void putFReg(UInt dregNo, IRExpr * e) 1439 { 1440 vassert(dregNo < 32); 1441 IRType ty = fp_mode64 ? Ity_F64 : Ity_F32; 1442 vassert(typeOfIRExpr(irsb->tyenv, e) == ty); 1443 stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e)); 1444 } 1445 1446 static void putDReg(UInt dregNo, IRExpr * e) 1447 { 1448 if (fp_mode64) { 1449 vassert(dregNo < 32); 1450 IRType ty = Ity_F64; 1451 vassert(typeOfIRExpr(irsb->tyenv, e) == ty); 1452 stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e)); 1453 } else { 1454 vassert(dregNo < 32); 1455 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F64); 1456 IRTemp t1 = newTemp(Ity_F64); 1457 IRTemp t4 = newTemp(Ity_I32); 1458 IRTemp t5 = newTemp(Ity_I32); 1459 IRTemp t6 = newTemp(Ity_I64); 1460 assign(t1, e); 1461 assign(t6, unop(Iop_ReinterpF64asI64, mkexpr(t1))); 1462 assign(t4, unop(Iop_64HIto32, mkexpr(t6))); /* hi */ 1463 assign(t5, unop(Iop_64to32, mkexpr(t6))); /* lo */ 1464 putFReg(dregNo, unop(Iop_ReinterpI32asF32, mkexpr(t5))); 1465 putFReg(dregNo + 1, unop(Iop_ReinterpI32asF32, mkexpr(t4))); 1466 } 1467 } 1468 1469 static void setFPUCondCode(IRExpr * e, UInt cc) 1470 { 1471 if (cc == 0) { 1472 putFCSR(binop(Iop_And32, getFCSR(), mkU32(0xFF7FFFFF))); 1473 putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(23)))); 1474 } else { 1475 putFCSR(binop(Iop_And32, getFCSR(), unop(Iop_Not32, 1476 binop(Iop_Shl32, mkU32(0x01000000), mkU8(cc))))); 1477 putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(24 + cc)))); 1478 } 1479 } 1480 1481 static IRExpr* get_IR_roundingmode ( void ) 1482 { 1483 /* 1484 rounding mode | MIPS | IR 1485 ------------------------ 1486 to nearest | 00 | 00 1487 to zero | 01 | 11 1488 to +infinity | 10 | 10 1489 to -infinity | 11 | 01 1490 */ 1491 IRTemp rm_MIPS = newTemp(Ity_I32); 1492 /* Last two bits in FCSR are rounding mode. */ 1493 1494 if (mode64) 1495 assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS64State, 1496 guest_FCSR), Ity_I32), mkU32(3))); 1497 else 1498 assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS32State, 1499 guest_FCSR), Ity_I32), mkU32(3))); 1500 1501 /* rm_IR = XOR( rm_MIPS32, (rm_MIPS32 << 1) & 2) */ 1502 1503 return binop(Iop_Xor32, mkexpr(rm_MIPS), binop(Iop_And32, 1504 binop(Iop_Shl32, mkexpr(rm_MIPS), mkU8(1)), mkU32(2))); 1505 } 1506 1507 /* sz, ULong -> IRExpr */ 1508 static IRExpr *mkSzImm ( IRType ty, ULong imm64 ) 1509 { 1510 vassert(ty == Ity_I32 || ty == Ity_I64); 1511 return ty == Ity_I64 ? mkU64(imm64) : mkU32((UInt) imm64); 1512 } 1513 1514 static IRConst *mkSzConst ( IRType ty, ULong imm64 ) 1515 { 1516 vassert(ty == Ity_I32 || ty == Ity_I64); 1517 return (ty == Ity_I64 ? IRConst_U64(imm64) : IRConst_U32((UInt) imm64)); 1518 } 1519 1520 /* Make sure we get valid 32 and 64bit addresses */ 1521 static Addr64 mkSzAddr ( IRType ty, Addr64 addr ) 1522 { 1523 vassert(ty == Ity_I32 || ty == Ity_I64); 1524 return (ty == Ity_I64 ? (Addr64) addr : 1525 (Addr64) extend_s_32to64(toUInt(addr))); 1526 } 1527 1528 /* Shift and Rotate instructions for MIPS64 */ 1529 static Bool dis_instr_shrt ( UInt theInstr ) 1530 { 1531 UInt opc2 = get_function(theInstr); 1532 UChar regRs = get_rs(theInstr); 1533 UChar regRt = get_rt(theInstr); 1534 UChar regRd = get_rd(theInstr); 1535 UChar uImmsa = get_sa(theInstr); 1536 Long sImmsa = extend_s_16to64(uImmsa); 1537 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1538 IRTemp tmp = newTemp(ty); 1539 IRTemp tmpOr = newTemp(ty); 1540 IRTemp tmpRt = newTemp(ty); 1541 IRTemp tmpRs = newTemp(ty); 1542 IRTemp tmpRd = newTemp(ty); 1543 1544 assign(tmpRs, getIReg(regRs)); 1545 assign(tmpRt, getIReg(regRt)); 1546 1547 switch (opc2) { 1548 case 0x3A: 1549 if ((regRs & 0x01) == 0) { 1550 /* Doubleword Shift Right Logical - DSRL; MIPS64 */ 1551 DIP("dsrl r%u, r%u, %d", regRd, regRt, (Int)sImmsa); 1552 assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa))); 1553 putIReg(regRd, mkexpr(tmpRd)); 1554 } else if ((regRs & 0x01) == 1) { 1555 /* Doubleword Rotate Right - DROTR; MIPS64r2 */ 1556 vassert(mode64); 1557 DIP("drotr r%u, r%u, %d", regRd, regRt, (Int)sImmsa); 1558 IRTemp tmpL = newTemp(ty); 1559 IRTemp tmpR = newTemp(ty); 1560 assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa))); 1561 assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(63 - uImmsa))); 1562 assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1))); 1563 assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR))); 1564 putIReg(regRd, mkexpr(tmpRd)); 1565 } else 1566 return False; 1567 break; 1568 1569 case 0x3E: 1570 if ((regRs & 0x01) == 0) { 1571 /* Doubleword Shift Right Logical Plus 32 - DSRL32; MIPS64 */ 1572 DIP("dsrl32 r%u, r%u, %d", regRd, regRt, (Int)(sImmsa + 32)); 1573 assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32))); 1574 putIReg(regRd, mkexpr(tmpRd)); 1575 } else if ((regRs & 0x01) == 1) { 1576 /* Doubleword Rotate Right Plus 32 - DROTR32; MIPS64r2 */ 1577 DIP("drotr32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa); 1578 vassert(mode64); 1579 IRTemp tmpL = newTemp(ty); 1580 IRTemp tmpR = newTemp(ty); 1581 /* (tmpRt >> sa) | (tmpRt << (64 - sa)) */ 1582 assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32))); 1583 assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), 1584 mkU8(63 - (uImmsa + 32)))); 1585 assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1))); 1586 assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR))); 1587 putIReg(regRd, mkexpr(tmpRd)); 1588 } else 1589 return False; 1590 break; 1591 1592 case 0x16: 1593 if ((uImmsa & 0x01) == 0) { 1594 /* Doubleword Shift Right Logical Variable - DSRLV; MIPS64 */ 1595 DIP("dsrlv r%u, r%u, r%u", regRd, regRt, regRs); 1596 IRTemp tmpRs8 = newTemp(Ity_I8); 1597 /* s = tmpRs[5..0] */ 1598 assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkU64(63))); 1599 assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp))); 1600 assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8))); 1601 putIReg(regRd, mkexpr(tmpRd)); 1602 } else if ((uImmsa & 0x01) == 1) { 1603 /* Doubleword Rotate Right Variable - DROTRV; MIPS64r2 */ 1604 DIP("drotrv r%u, r%u, r%u", regRd, regRt, regRs); 1605 IRTemp tmpL = newTemp(ty); 1606 IRTemp tmpR = newTemp(ty); 1607 IRTemp tmpRs8 = newTemp(Ity_I8); 1608 IRTemp tmpLs8 = newTemp(Ity_I8); 1609 IRTemp tmp64 = newTemp(ty); 1610 /* s = tmpRs[5...0] 1611 m = 64 - s 1612 (tmpRt << s) | (tmpRt >> m) */ 1613 1614 assign(tmp64, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63))); 1615 assign(tmp, binop(Iop_Sub64, mkU64(63), mkexpr(tmp64))); 1616 1617 assign(tmpLs8, mkNarrowTo8(ty, mkexpr(tmp))); 1618 assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp64))); 1619 1620 assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8))); 1621 assign(tmpL, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpLs8))); 1622 assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpL), mkU8(1))); 1623 assign(tmpOr, binop(Iop_Or64, mkexpr(tmpRd), mkexpr(tmpR))); 1624 1625 putIReg(regRd, mkexpr(tmpOr)); 1626 } else 1627 return False; 1628 break; 1629 1630 case 0x38: /* Doubleword Shift Left Logical - DSLL; MIPS64 */ 1631 DIP("dsll r%u, r%u, %d", regRd, regRt, (Int)sImmsa); 1632 vassert(mode64); 1633 assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa))); 1634 putIReg(regRd, mkexpr(tmpRd)); 1635 break; 1636 1637 case 0x3C: /* Doubleword Shift Left Logical Plus 32 - DSLL32; MIPS64 */ 1638 DIP("dsll32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa); 1639 assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa + 32))); 1640 putIReg(regRd, mkexpr(tmpRd)); 1641 break; 1642 1643 case 0x14: { /* Doubleword Shift Left Logical Variable - DSLLV; MIPS64 */ 1644 DIP("dsllv r%u, r%u, r%u", regRd, regRt, regRs); 1645 IRTemp tmpRs8 = newTemp(Ity_I8); 1646 1647 assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63))); 1648 assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp))); 1649 assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpRs8))); 1650 putIReg(regRd, mkexpr(tmpRd)); 1651 break; 1652 } 1653 1654 case 0x3B: /* Doubleword Shift Right Arithmetic - DSRA; MIPS64 */ 1655 DIP("dsra r%u, r%u, %d", regRd, regRt, (Int)sImmsa); 1656 assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa))); 1657 putIReg(regRd, mkexpr(tmpRd)); 1658 break; 1659 1660 case 0x3F: /* Doubleword Shift Right Arithmetic Plus 32 - DSRA32; 1661 MIPS64 */ 1662 DIP("dsra32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa); 1663 assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa + 32))); 1664 putIReg(regRd, mkexpr(tmpRd)); 1665 break; 1666 1667 case 0x17: { /* Doubleword Shift Right Arithmetic Variable - DSRAV; 1668 MIPS64 */ 1669 DIP("dsrav r%u, r%u, r%u", regRd, regRt, regRs); 1670 IRTemp tmpRs8 = newTemp(Ity_I8); 1671 assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63))); 1672 assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp))); 1673 assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkexpr(tmpRs8))); 1674 putIReg(regRd, mkexpr(tmpRd)); 1675 break; 1676 1677 } 1678 1679 default: 1680 return False; 1681 1682 } 1683 return True; 1684 } 1685 1686 static IROp mkSzOp ( IRType ty, IROp op8 ) 1687 { 1688 Int adj; 1689 vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I64); 1690 vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 || op8 == Iop_Mul8 1691 || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8 1692 || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8 1693 || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 || op8 == Iop_Not8); 1694 adj = ty == Ity_I8 ? 0 : (ty == Ity_I16 ? 1 : (ty == Ity_I32 ? 2 : 3)); 1695 return adj + op8; 1696 } 1697 1698 /*********************************************************/ 1699 /*--- Floating Point Compare ---*/ 1700 /*********************************************************/ 1701 /* Function that returns a string that represent mips cond 1702 mnemonic for the input code. */ 1703 static const HChar* showCondCode(UInt code) { 1704 const HChar* ret; 1705 switch (code) { 1706 case 0: ret = "f"; break; 1707 case 1: ret = "un"; break; 1708 case 2: ret = "eq"; break; 1709 case 3: ret = "ueq"; break; 1710 case 4: ret = "olt"; break; 1711 case 5: ret = "ult"; break; 1712 case 6: ret = "ole"; break; 1713 case 7: ret = "ule"; break; 1714 case 8: ret = "sf"; break; 1715 case 9: ret = "ngle"; break; 1716 case 10: ret = "seq"; break; 1717 case 11: ret = "ngl"; break; 1718 case 12: ret = "lt"; break; 1719 case 13: ret = "nge"; break; 1720 case 14: ret = "le"; break; 1721 case 15: ret = "ngt"; break; 1722 default: vpanic("showCondCode"); break; 1723 } 1724 return ret; 1725 } 1726 1727 static Bool dis_instr_CCondFmt ( UInt cins ) 1728 { 1729 IRTemp t0, t1, t2, t3, tmp5, tmp6; 1730 IRTemp ccIR = newTemp(Ity_I32); 1731 IRTemp ccMIPS = newTemp(Ity_I32); 1732 UInt FC = get_FC(cins); 1733 UInt fmt = get_fmt(cins); 1734 UInt fs = get_fs(cins); 1735 UInt ft = get_ft(cins); 1736 UInt cond = get_cond(cins); 1737 1738 if (FC == 0x3) { /* C.cond.fmt */ 1739 UInt fpc_cc = get_fpc_cc(cins); 1740 switch (fmt) { 1741 case 0x10: { /* C.cond.S */ 1742 DIP("c.%s.s %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft); 1743 if (fp_mode64) { 1744 t0 = newTemp(Ity_I32); 1745 t1 = newTemp(Ity_I32); 1746 t2 = newTemp(Ity_I32); 1747 t3 = newTemp(Ity_I32); 1748 1749 tmp5 = newTemp(Ity_F64); 1750 tmp6 = newTemp(Ity_F64); 1751 1752 assign(tmp5, unop(Iop_F32toF64, getLoFromF64(Ity_F64, 1753 getFReg(fs)))); 1754 assign(tmp6, unop(Iop_F32toF64, getLoFromF64(Ity_F64, 1755 getFReg(ft)))); 1756 1757 assign(ccIR, binop(Iop_CmpF64, mkexpr(tmp5), mkexpr(tmp6))); 1758 putHI(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32, 1759 mkexpr(ccIR), True)); 1760 /* Map compare result from IR to MIPS 1761 FP cmp result | MIPS | IR 1762 -------------------------- 1763 UN | 0x1 | 0x45 1764 EQ | 0x2 | 0x40 1765 GT | 0x4 | 0x00 1766 LT | 0x8 | 0x01 1767 */ 1768 1769 /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */ 1770 assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8, 1771 binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32, 1772 binop(Iop_Shr32, mkexpr(ccIR),mkU8(5))),mkU32(2)), 1773 binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR), 1774 binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))), 1775 mkU32(1)))))); 1776 putLO(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32, 1777 mkexpr(ccMIPS), True)); 1778 1779 /* UN */ 1780 assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1))); 1781 /* EQ */ 1782 assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS), 1783 mkU8(0x1)), mkU32(0x1))); 1784 /* NGT */ 1785 assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32, 1786 mkexpr(ccMIPS), mkU8(0x2))),mkU32(0x1))); 1787 /* LT */ 1788 assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS), 1789 mkU8(0x3)), mkU32(0x1))); 1790 switch (cond) { 1791 case 0x0: 1792 setFPUCondCode(mkU32(0), fpc_cc); 1793 break; 1794 case 0x1: 1795 setFPUCondCode(mkexpr(t0), fpc_cc); 1796 break; 1797 case 0x2: 1798 setFPUCondCode(mkexpr(t1), fpc_cc); 1799 break; 1800 case 0x3: 1801 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)), 1802 fpc_cc); 1803 break; 1804 case 0x4: 1805 setFPUCondCode(mkexpr(t3), fpc_cc); 1806 break; 1807 case 0x5: 1808 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)), 1809 fpc_cc); 1810 break; 1811 case 0x6: 1812 setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)), 1813 fpc_cc); 1814 break; 1815 case 0x7: 1816 setFPUCondCode(mkexpr(t2), fpc_cc); 1817 break; 1818 case 0x8: 1819 setFPUCondCode(mkU32(0), fpc_cc); 1820 break; 1821 case 0x9: 1822 setFPUCondCode(mkexpr(t0), fpc_cc); 1823 break; 1824 case 0xA: 1825 setFPUCondCode(mkexpr(t1), fpc_cc); 1826 break; 1827 case 0xB: 1828 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)), 1829 fpc_cc); 1830 break; 1831 case 0xC: 1832 setFPUCondCode(mkexpr(t3), fpc_cc); 1833 break; 1834 case 0xD: 1835 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)), 1836 fpc_cc); 1837 break; 1838 case 0xE: 1839 setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)), 1840 fpc_cc); 1841 break; 1842 case 0xF: 1843 setFPUCondCode(mkexpr(t2), fpc_cc); 1844 break; 1845 1846 default: 1847 return False; 1848 } 1849 1850 } else { 1851 t0 = newTemp(Ity_I32); 1852 t1 = newTemp(Ity_I32); 1853 t2 = newTemp(Ity_I32); 1854 t3 = newTemp(Ity_I32); 1855 1856 assign(ccIR, binop(Iop_CmpF64, unop(Iop_F32toF64, getFReg(fs)), 1857 unop(Iop_F32toF64, getFReg(ft)))); 1858 /* Map compare result from IR to MIPS 1859 FP cmp result | MIPS | IR 1860 -------------------------- 1861 UN | 0x1 | 0x45 1862 EQ | 0x2 | 0x40 1863 GT | 0x4 | 0x00 1864 LT | 0x8 | 0x01 1865 */ 1866 1867 /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */ 1868 assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8, 1869 binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32, 1870 binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))), 1871 mkU32(2)), binop(Iop_And32, 1872 binop(Iop_Xor32, mkexpr(ccIR), 1873 binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))), 1874 mkU32(1)))))); 1875 /* UN */ 1876 assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1))); 1877 /* EQ */ 1878 assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS), 1879 mkU8(0x1)), mkU32(0x1))); 1880 /* NGT */ 1881 assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32, 1882 mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1))); 1883 /* LT */ 1884 assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS), 1885 mkU8(0x3)), mkU32(0x1))); 1886 1887 switch (cond) { 1888 case 0x0: 1889 setFPUCondCode(mkU32(0), fpc_cc); 1890 break; 1891 case 0x1: 1892 setFPUCondCode(mkexpr(t0), fpc_cc); 1893 break; 1894 case 0x2: 1895 setFPUCondCode(mkexpr(t1), fpc_cc); 1896 break; 1897 case 0x3: 1898 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)), 1899 fpc_cc); 1900 break; 1901 case 0x4: 1902 setFPUCondCode(mkexpr(t3), fpc_cc); 1903 break; 1904 case 0x5: 1905 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)), 1906 fpc_cc); 1907 break; 1908 case 0x6: 1909 setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)), 1910 fpc_cc); 1911 break; 1912 case 0x7: 1913 setFPUCondCode(mkexpr(t2), fpc_cc); 1914 break; 1915 case 0x8: 1916 setFPUCondCode(mkU32(0), fpc_cc); 1917 break; 1918 case 0x9: 1919 setFPUCondCode(mkexpr(t0), fpc_cc); 1920 break; 1921 case 0xA: 1922 setFPUCondCode(mkexpr(t1), fpc_cc); 1923 break; 1924 case 0xB: 1925 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)), 1926 fpc_cc); 1927 break; 1928 case 0xC: 1929 setFPUCondCode(mkexpr(t3), fpc_cc); 1930 break; 1931 case 0xD: 1932 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)), 1933 fpc_cc); 1934 break; 1935 case 0xE: 1936 setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)), 1937 fpc_cc); 1938 break; 1939 case 0xF: 1940 setFPUCondCode(mkexpr(t2), fpc_cc); 1941 break; 1942 1943 default: 1944 return False; 1945 } 1946 } 1947 } 1948 break; 1949 1950 case 0x11: { /* C.cond.D */ 1951 DIP("c.%s.d %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft); 1952 t0 = newTemp(Ity_I32); 1953 t1 = newTemp(Ity_I32); 1954 t2 = newTemp(Ity_I32); 1955 t3 = newTemp(Ity_I32); 1956 assign(ccIR, binop(Iop_CmpF64, getDReg(fs), getDReg(ft))); 1957 /* Map compare result from IR to MIPS 1958 FP cmp result | MIPS | IR 1959 -------------------------- 1960 UN | 0x1 | 0x45 1961 EQ | 0x2 | 0x40 1962 GT | 0x4 | 0x00 1963 LT | 0x8 | 0x01 1964 */ 1965 1966 /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */ 1967 assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8, 1968 binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32, 1969 binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))), mkU32(2)), 1970 binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR), 1971 binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))), 1972 mkU32(1)))))); 1973 1974 /* UN */ 1975 assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1))); 1976 /* EQ */ 1977 assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS), 1978 mkU8(0x1)), mkU32(0x1))); 1979 /* NGT */ 1980 assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32, 1981 mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1))); 1982 /* LT */ 1983 assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS), 1984 mkU8(0x3)), mkU32(0x1))); 1985 1986 switch (cond) { 1987 case 0x0: 1988 setFPUCondCode(mkU32(0), fpc_cc); 1989 break; 1990 case 0x1: 1991 setFPUCondCode(mkexpr(t0), fpc_cc); 1992 break; 1993 case 0x2: 1994 setFPUCondCode(mkexpr(t1), fpc_cc); 1995 break; 1996 case 0x3: 1997 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)), 1998 fpc_cc); 1999 break; 2000 case 0x4: 2001 setFPUCondCode(mkexpr(t3), fpc_cc); 2002 break; 2003 case 0x5: 2004 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)), 2005 fpc_cc); 2006 break; 2007 case 0x6: 2008 setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)), 2009 fpc_cc); 2010 break; 2011 case 0x7: 2012 setFPUCondCode(mkexpr(t2), fpc_cc); 2013 break; 2014 case 0x8: 2015 setFPUCondCode(mkU32(0), fpc_cc); 2016 break; 2017 case 0x9: 2018 setFPUCondCode(mkexpr(t0), fpc_cc); 2019 break; 2020 case 0xA: 2021 setFPUCondCode(mkexpr(t1), fpc_cc); 2022 break; 2023 case 0xB: 2024 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)), 2025 fpc_cc); 2026 break; 2027 case 0xC: 2028 setFPUCondCode(mkexpr(t3), fpc_cc); 2029 break; 2030 case 0xD: 2031 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)), 2032 fpc_cc); 2033 break; 2034 case 0xE: 2035 setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)), 2036 fpc_cc); 2037 break; 2038 case 0xF: 2039 setFPUCondCode(mkexpr(t2), fpc_cc); 2040 break; 2041 default: 2042 return False; 2043 } 2044 } 2045 break; 2046 2047 default: 2048 return False; 2049 } 2050 } else { 2051 return False; 2052 } 2053 2054 return True; 2055 } 2056 2057 /*********************************************************/ 2058 /*--- Branch Instructions for mips64 ---*/ 2059 /*********************************************************/ 2060 static Bool dis_instr_branch ( UInt theInstr, DisResult * dres, 2061 Bool(*resteerOkFn) (void *, Addr64), 2062 void *callback_opaque, IRStmt ** set ) 2063 { 2064 UInt jmpKind = 0; 2065 UChar opc1 = get_opcode(theInstr); 2066 UChar regRs = get_rs(theInstr); 2067 UChar regRt = get_rt(theInstr); 2068 UInt offset = get_imm(theInstr); 2069 Long sOffset = extend_s_16to64(offset); 2070 IRType ty = mode64 ? Ity_I64 : Ity_I32; 2071 IROp opSlt = mode64 ? Iop_CmpLT64S : Iop_CmpLT32S; 2072 2073 IRTemp tmp = newTemp(ty); 2074 IRTemp tmpRs = newTemp(ty); 2075 IRTemp tmpRt = newTemp(ty); 2076 IRTemp tmpLt = newTemp(ty); 2077 IRTemp tmpReg0 = newTemp(ty); 2078 2079 UChar regLnk = 31; /* reg 31 is link reg in MIPS */ 2080 Addr64 addrTgt = 0; 2081 Addr64 cia = guest_PC_curr_instr; 2082 2083 IRExpr *eConst0 = mkSzImm(ty, (UInt) 0); 2084 IRExpr *eNia = mkSzImm(ty, cia + 8); 2085 IRExpr *eCond = NULL; 2086 2087 assign(tmpRs, getIReg(regRs)); 2088 assign(tmpRt, getIReg(regRt)); 2089 assign(tmpReg0, getIReg(0)); 2090 2091 eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpReg0), mkexpr(tmpReg0)); 2092 2093 switch (opc1) { 2094 case 0x01: 2095 switch (regRt) { 2096 case 0x00: { /* BLTZ rs, offset */ 2097 addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2)); 2098 IRTemp tmpLtRes = newTemp(Ity_I1); 2099 2100 assign(tmp, eConst0); 2101 assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp))); 2102 assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) : 2103 unop(Iop_1Uto32, mkexpr(tmpLtRes))); 2104 2105 eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpLt), 2106 mkexpr(tmpReg0)); 2107 2108 jmpKind = Ijk_Call; 2109 break; 2110 } 2111 2112 case 0x01: { /* BGEZ rs, offset */ 2113 IRTemp tmpLtRes = newTemp(Ity_I1); 2114 addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2)); 2115 2116 assign(tmp, eConst0); 2117 assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp))); 2118 assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) : 2119 unop(Iop_1Uto32, mkexpr(tmpLtRes))); 2120 eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt), 2121 mkexpr(tmpReg0)); 2122 2123 jmpKind = Ijk_Call; 2124 break; 2125 } 2126 2127 case 0x11: { /* BGEZAL rs, offset */ 2128 addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2)); 2129 putIReg(regLnk, eNia); 2130 IRTemp tmpLtRes = newTemp(Ity_I1); 2131 2132 assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), eConst0)); 2133 assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) : 2134 unop(Iop_1Uto32, mkexpr(tmpLtRes))); 2135 2136 eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt), 2137 mkexpr(tmpReg0)); 2138 2139 jmpKind = Ijk_Call; 2140 break; 2141 } 2142 2143 case 0x10: { /* BLTZAL rs, offset */ 2144 IRTemp tmpLtRes = newTemp(Ity_I1); 2145 IRTemp tmpRes = newTemp(ty); 2146 2147 addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2)); 2148 putIReg(regLnk, eNia); 2149 2150 assign(tmp, eConst0); 2151 assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp))); 2152 assign(tmpRes, mode64 ? unop(Iop_1Uto64, 2153 mkexpr(tmpLtRes)) : unop(Iop_1Uto32, mkexpr(tmpLtRes))); 2154 eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpRes), 2155 mkexpr(tmpReg0)); 2156 2157 jmpKind = Ijk_Call; 2158 break; 2159 } 2160 2161 } 2162 break; 2163 default: 2164 return False; 2165 } 2166 *set = IRStmt_Exit(eCond, jmpKind, mkSzConst(ty, addrTgt), OFFB_PC); 2167 return True; 2168 } 2169 2170 /*********************************************************/ 2171 /*--- Cavium Specific Instructions ---*/ 2172 /*********************************************************/ 2173 static Bool dis_instr_CVM ( UInt theInstr ) 2174 { 2175 UChar opc2 = get_function(theInstr); 2176 UChar opc1 = get_opcode(theInstr); 2177 UChar regRs = get_rs(theInstr); 2178 UChar regRt = get_rt(theInstr); 2179 UChar regRd = get_rd(theInstr); 2180 UInt imm = get_imm(theInstr); 2181 UChar lenM1 = get_msb(theInstr); 2182 UChar p = get_lsb(theInstr); 2183 IRType ty = mode64? Ity_I64 : Ity_I32; 2184 IRTemp tmp = newTemp(ty); 2185 IRTemp tmpRs = newTemp(ty); 2186 IRTemp tmpRt = newTemp(ty); 2187 IRTemp t1 = newTemp(ty); 2188 UInt size; 2189 assign(tmpRs, getIReg(regRs)); 2190 2191 switch(opc1){ 2192 case 0x1C: { 2193 switch(opc2) { 2194 case 0x03: { /* DMUL rd, rs, rt */ 2195 DIP("dmul r%d, r%d, r%d", regRd, regRs, regRt); 2196 IRType t0 = newTemp(Ity_I128); 2197 assign(t0, binop(Iop_MullU64, getIReg(regRs), getIReg(regRt))); 2198 putIReg(regRd, unop(Iop_128to64, mkexpr(t0))); 2199 break; 2200 } 2201 2202 case 0x32: /* 5. CINS rd, rs, p, lenm1 */ 2203 DIP("cins r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1); 2204 assign ( tmp , binop(Iop_Shl64, mkexpr(tmpRs), 2205 mkU8(64-( lenM1+1 )))); 2206 assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ), 2207 mkU8(64-(p+lenM1+1)))); 2208 putIReg( regRt, mkexpr(tmpRt)); 2209 break; 2210 2211 case 0x33: /* 6. CINS32 rd, rs, p+32, lenm1 */ 2212 DIP("cins32 r%u, r%u, %d, %d\n", regRt, regRs, p+32, lenM1); 2213 assign ( tmp , binop(Iop_Shl64, mkexpr(tmpRs), 2214 mkU8(64-( lenM1+1 )))); 2215 assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ), 2216 mkU8(32-(p+lenM1+1)))); 2217 putIReg( regRt, mkexpr(tmpRt)); 2218 break; 2219 2220 case 0x3A: /* 3. EXTS rt, rs, p len */ 2221 DIP("exts r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1); 2222 size = lenM1 + 1; /* lenm1+1 */ 2223 UChar lsAmt = 64 - (p + size); /* p+lenm1+1 */ 2224 UChar rsAmt = 64 - size; /* lenm1+1 */ 2225 tmp = newTemp(Ity_I64); 2226 assign(tmp, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt))); 2227 putIReg(regRt, binop(Iop_Sar64, mkexpr(tmp), mkU8(rsAmt))); 2228 break; 2229 2230 case 0x3B: /* 4. EXTS32 rt, rs, p len */ 2231 DIP("exts32 r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1); 2232 assign ( tmp , binop(Iop_Shl64, mkexpr(tmpRs), 2233 mkU8(32-(p+lenM1+1)))); 2234 assign ( tmpRt, binop(Iop_Sar64, mkexpr(tmp), 2235 mkU8(64-(lenM1+1))) ); 2236 putIReg( regRt, mkexpr(tmpRt)); 2237 break; 2238 2239 case 0x2B: /* 20. SNE rd, rs, rt */ 2240 DIP("sne r%d, r%d, r%d", regRd,regRs, regRt); 2241 if (mode64) 2242 putIReg(regRd, unop(Iop_1Uto64, binop(Iop_CmpNE64, 2243 getIReg(regRs), 2244 getIReg(regRt)))); 2245 else 2246 putIReg(regRd,unop(Iop_1Uto32, binop(Iop_CmpNE32, 2247 getIReg(regRs), 2248 getIReg(regRt)))); 2249 break; 2250 2251 case 0x2A: /* Set Equals - SEQ; Cavium OCTEON */ 2252 DIP("seq r%d, r%d, %d", regRd, regRs, regRt); 2253 if (mode64) 2254 putIReg(regRd, unop(Iop_1Uto64, 2255 binop(Iop_CmpEQ64, getIReg(regRs), 2256 getIReg(regRt)))); 2257 else 2258 putIReg(regRd, unop(Iop_1Uto32, 2259 binop(Iop_CmpEQ32, getIReg(regRs), 2260 getIReg(regRt)))); 2261 break; 2262 2263 case 0x2E: /* Set Equals Immediate - SEQI; Cavium OCTEON */ 2264 DIP("seqi r%d, r%d, %d", regRt, regRs, imm); 2265 if (mode64) 2266 putIReg(regRt, unop(Iop_1Uto64, 2267 binop(Iop_CmpEQ64, getIReg(regRs), 2268 mkU64(extend_s_10to64(imm))))); 2269 else 2270 putIReg(regRt, unop(Iop_1Uto32, 2271 binop(Iop_CmpEQ32, getIReg(regRs), 2272 mkU32(extend_s_10to32(imm))))); 2273 break; 2274 2275 case 0x2F: /* Set Not Equals Immediate - SNEI; Cavium OCTEON */ 2276 DIP("snei r%d, r%d, %d", regRt, regRs, imm); 2277 if (mode64) 2278 putIReg(regRt, unop(Iop_1Uto64, 2279 binop(Iop_CmpNE64, 2280 getIReg(regRs), 2281 mkU64(extend_s_10to64(imm))))); 2282 else 2283 putIReg(regRt, unop(Iop_1Uto32, 2284 binop(Iop_CmpNE32, 2285 getIReg(regRs), 2286 mkU32(extend_s_10to32(imm))))); 2287 break; 2288 2289 default: 2290 return False; 2291 } 2292 break; 2293 } /* opc1 0x1C ends here*/ 2294 case 0x1F:{ 2295 switch(opc2) { 2296 case 0x0A: { // lx - Load indexed instructions 2297 switch (get_sa(theInstr)) { 2298 case 0x00: { // LWX rd, index(base) 2299 DIP("lwx r%d, r%d(r%d)", regRd, regRt, regRs); 2300 LOADX_STORE_PATTERN; 2301 putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), 2302 True)); 2303 break; 2304 } 2305 case 0x08: { // LDX rd, index(base) 2306 DIP("ldx r%d, r%d(r%d)", regRd, regRt, regRs); 2307 vassert(mode64); /* Currently Implemented only for n64 */ 2308 LOADX_STORE_PATTERN; 2309 putIReg(regRd, load(Ity_I64, mkexpr(t1))); 2310 break; 2311 } 2312 case 0x06: { // LBUX rd, index(base) 2313 DIP("lbux r%d, r%d(r%d)", regRd, regRt, regRs); 2314 LOADX_STORE_PATTERN; 2315 if (mode64) 2316 putIReg(regRd, unop(Iop_8Uto64, load(Ity_I8, 2317 mkexpr(t1)))); 2318 else 2319 putIReg(regRd, unop(Iop_8Uto32, load(Ity_I8, 2320 mkexpr(t1)))); 2321 break; 2322 } 2323 case 0x10: { // LWUX rd, index(base) (Cavium OCTEON) 2324 DIP("lwux r%d, r%d(r%d)", regRd, regRt, regRs); 2325 LOADX_STORE_PATTERN; /* same for both 32 and 64 modes*/ 2326 putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), 2327 False)); 2328 break; 2329 } 2330 case 0x14: { // LHUX rd, index(base) (Cavium OCTEON) 2331 DIP("lhux r%d, r%d(r%d)", regRd, regRt, regRs); 2332 LOADX_STORE_PATTERN; 2333 if (mode64) 2334 putIReg(regRd, 2335 unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1)))); 2336 else 2337 putIReg(regRd, 2338 unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1)))); 2339 break; 2340 } 2341 case 0x16: { // LBX rd, index(base) (Cavium OCTEON) 2342 DIP("lbx r%d, r%d(r%d)", regRd, regRs, regRt); 2343 LOADX_STORE_PATTERN; 2344 if (mode64) 2345 putIReg(regRd, 2346 unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1)))); 2347 else 2348 putIReg(regRd, 2349 unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1)))); 2350 break; 2351 } 2352 default: 2353 vex_printf("\nUnhandled LX instruction opc3 = %x\n", 2354 get_sa(theInstr)); 2355 return False; 2356 } 2357 break; 2358 } 2359 } /* opc1 = 0x1F & opc2 = 0xA (LX) ends here*/ 2360 break; 2361 } /* opc1 = 0x1F ends here*/ 2362 default: 2363 return False; 2364 } /* main opc1 switch ends here */ 2365 return True; 2366 } 2367 2368 /*------------------------------------------------------------*/ 2369 /*--- Disassemble a single DSP ASE instruction ---*/ 2370 /*------------------------------------------------------------*/ 2371 2372 static UInt disDSPInstr_MIPS_WRK ( UInt cins ) 2373 { 2374 IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, 2375 t15, t16, t17; 2376 UInt opcode, rs, rt, rd, sa, function, ac, ac_mfhilo, rddsp_mask, 2377 wrdsp_mask, dsp_imm, shift; 2378 2379 opcode = get_opcode(cins); 2380 rs = get_rs(cins); 2381 rt = get_rt(cins); 2382 rd = get_rd(cins); 2383 sa = get_sa(cins); 2384 function = get_function(cins); 2385 ac = get_acNo(cins); 2386 ac_mfhilo = get_acNo_mfhilo(cins); 2387 rddsp_mask = get_rddspMask(cins); 2388 wrdsp_mask = get_wrdspMask(cins); 2389 dsp_imm = get_dspImm(cins); 2390 shift = get_shift(cins); 2391 2392 switch (opcode) { 2393 case 0x00: { /* Special */ 2394 switch (function) { 2395 case 0x10: { /* MFHI */ 2396 DIP("mfhi ac%d r%d", ac_mfhilo, rd); 2397 putIReg(rd, unop(Iop_64HIto32, getAcc(ac_mfhilo))); 2398 break; 2399 } 2400 2401 case 0x11: { /* MTHI */ 2402 DIP("mthi ac%d r%d", ac, rs); 2403 t1 = newTemp(Ity_I32); 2404 assign(t1, unop(Iop_64to32, getAcc(ac))); 2405 putAcc(ac, binop(Iop_32HLto64, getIReg(rs), mkexpr(t1))); 2406 break; 2407 } 2408 2409 case 0x12: { /* MFLO */ 2410 DIP("mflo ac%d r%d", ac_mfhilo, rd); 2411 putIReg(rd, unop(Iop_64to32, getAcc(ac_mfhilo))); 2412 break; 2413 } 2414 2415 case 0x13: { /* MTLO */ 2416 DIP("mtlo ac%d r%d", ac, rs); 2417 t1 = newTemp(Ity_I32); 2418 assign(t1, unop(Iop_64HIto32, getAcc(ac))); 2419 putAcc(ac, binop(Iop_32HLto64, mkexpr(t1), getIReg(rs))); 2420 break; 2421 } 2422 2423 case 0x18: { /* MULT */ 2424 DIP("mult ac%d r%d, r%d", ac, rs, rt); 2425 t1 = newTemp(Ity_I64); 2426 assign(t1, binop(Iop_MullS32, mkNarrowTo32(Ity_I32, getIReg(rs)), 2427 mkNarrowTo32(Ity_I32, getIReg(rt)))); 2428 putAcc(ac, mkexpr(t1)); 2429 break; 2430 } 2431 2432 case 0x19: { /* MULTU */ 2433 DIP("multu ac%d r%d, r%d", ac, rs, rt); 2434 t1 = newTemp(Ity_I64); 2435 assign(t1, binop(Iop_MullU32, mkNarrowTo32(Ity_I32, getIReg(rs)), 2436 mkNarrowTo32(Ity_I32, 2437 getIReg(rt)))); 2438 putAcc(ac, mkexpr(t1)); 2439 break; 2440 } 2441 } 2442 break; 2443 } 2444 case 0x1C: { /* Special2 */ 2445 switch (function) { 2446 case 0x00: { /* MADD */ 2447 DIP("madd ac%d, r%d, r%d", ac, rs, rt); 2448 t1 = newTemp(Ity_I64); 2449 t2 = newTemp(Ity_I64); 2450 t3 = newTemp(Ity_I64); 2451 2452 assign(t1, getAcc(ac)); 2453 assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt))); 2454 assign(t3, binop(Iop_Add64, mkexpr(t1), mkexpr(t2))); 2455 2456 putAcc(ac, mkexpr(t3)); 2457 break; 2458 } 2459 case 0x01: { /* MADDU */ 2460 DIP("maddu ac%d r%d, r%d", ac, rs, rt); 2461 t1 = newTemp(Ity_I64); 2462 t2 = newTemp(Ity_I64); 2463 t3 = newTemp(Ity_I64); 2464 2465 assign(t1, getAcc(ac)); 2466 assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt))); 2467 assign(t3, binop(Iop_Add64, mkexpr(t2), mkexpr(t1))); 2468 2469 putAcc(ac, mkexpr(t3)); 2470 break; 2471 } 2472 case 0x04: { /* MSUB */ 2473 DIP("msub ac%d r%d, r%d", ac, rs, rt); 2474 t1 = newTemp(Ity_I64); 2475 t2 = newTemp(Ity_I64); 2476 t3 = newTemp(Ity_I64); 2477 2478 assign(t1, getAcc(ac)); 2479 assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt))); 2480 assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2))); 2481 2482 putAcc(ac, mkexpr(t3)); 2483 break; 2484 } 2485 case 0x05: { /* MSUBU */ 2486 DIP("msubu ac%d r%d, r%d", ac, rs, rt); 2487 t1 = newTemp(Ity_I64); 2488 t2 = newTemp(Ity_I64); 2489 t3 = newTemp(Ity_I64); 2490 2491 assign(t1, getAcc(ac)); 2492 assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt))); 2493 assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2))); 2494 2495 putAcc(ac, mkexpr(t3)); 2496 break; 2497 } 2498 } 2499 break; 2500 } 2501 case 0x1F: { /* Special3 */ 2502 switch (function) { 2503 case 0x12: { /* ABSQ_S.PH */ 2504 switch (sa) { 2505 case 0x1: { /* ABSQ_S.QB */ 2506 DIP("absq_s.qb r%d, r%d", rd, rt); 2507 vassert(!mode64); 2508 t0 = newTemp(Ity_I8); 2509 t1 = newTemp(Ity_I1); 2510 t2 = newTemp(Ity_I1); 2511 t3 = newTemp(Ity_I8); 2512 t4 = newTemp(Ity_I8); 2513 t5 = newTemp(Ity_I1); 2514 t6 = newTemp(Ity_I1); 2515 t7 = newTemp(Ity_I8); 2516 t8 = newTemp(Ity_I8); 2517 t9 = newTemp(Ity_I1); 2518 t10 = newTemp(Ity_I1); 2519 t11 = newTemp(Ity_I8); 2520 t12 = newTemp(Ity_I8); 2521 t13 = newTemp(Ity_I1); 2522 t14 = newTemp(Ity_I1); 2523 t15 = newTemp(Ity_I8); 2524 t16 = newTemp(Ity_I32); 2525 t17 = newTemp(Ity_I32); 2526 2527 /* Absolute value of the rightmost byte (bits 7-0). */ 2528 /* t0 - rightmost byte. */ 2529 assign(t0, unop(Iop_16to8, unop(Iop_32to16, getIReg(rt)))); 2530 /* t1 holds 1 if t0 is equal to 0x80, or 0 otherwise. */ 2531 assign(t1, binop(Iop_CmpEQ32, 2532 unop(Iop_8Uto32, mkexpr(t0)), 2533 mkU32(0x00000080))); 2534 /* t2 holds 1 if value in t0 is negative, 0 otherwise. */ 2535 assign(t2, unop(Iop_32to1, 2536 binop(Iop_Shr32, 2537 binop(Iop_And32, 2538 getIReg(rt), 2539 mkU32(0x00000080)), 2540 mkU8(0x7)))); 2541 /* t3 holds abs(t0). */ 2542 assign(t3, IRExpr_ITE(mkexpr(t1), 2543 mkU8(0x7F), 2544 IRExpr_ITE(mkexpr(t2), 2545 binop(Iop_Add8, 2546 unop(Iop_Not8, 2547 mkexpr(t0)), 2548 mkU8(0x1)), 2549 mkexpr(t0)))); 2550 2551 /* Absolute value of bits 15-8. */ 2552 /* t4 - input byte. */ 2553 assign(t4, 2554 unop(Iop_16HIto8, unop(Iop_32to16, getIReg(rt)))); 2555 /* t5 holds 1 if t4 is equal to 0x80, or 0 otherwise. */ 2556 assign(t5, binop(Iop_CmpEQ32, 2557 unop(Iop_8Uto32, mkexpr(t4)), 2558 mkU32(0x00000080))); 2559 /* t6 holds 1 if value in t4 is negative, 0 otherwise. */ 2560 assign(t6, unop(Iop_32to1, 2561 binop(Iop_Shr32, 2562 binop(Iop_And32, 2563 getIReg(rt), 2564 mkU32(0x00008000)), 2565 mkU8(15)))); 2566 /* t3 holds abs(t4). */ 2567 assign(t7, IRExpr_ITE(mkexpr(t5), 2568 mkU8(0x7F), 2569 IRExpr_ITE(mkexpr(t6), 2570 binop(Iop_Add8, 2571 unop(Iop_Not8, 2572 mkexpr(t4)), 2573 mkU8(0x1)), 2574 mkexpr(t4)))); 2575 2576 /* Absolute value of bits 23-15. */ 2577 /* t8 - input byte. */ 2578 assign(t8, 2579 unop(Iop_16to8, unop(Iop_32HIto16, getIReg(rt)))); 2580 /* t9 holds 1 if t8 is equal to 0x80, or 0 otherwise. */ 2581 assign(t9, binop(Iop_CmpEQ32, 2582 unop(Iop_8Uto32, mkexpr(t8)), 2583 mkU32(0x00000080))); 2584 /* t6 holds 1 if value in t8 is negative, 0 otherwise. */ 2585 assign(t10, unop(Iop_32to1, 2586 binop(Iop_Shr32, 2587 binop(Iop_And32, 2588 getIReg(rt), 2589 mkU32(0x00800000)), 2590 mkU8(23)))); 2591 /* t3 holds abs(t8). */ 2592 assign(t11, IRExpr_ITE(mkexpr(t9), 2593 mkU8(0x7F), 2594 IRExpr_ITE(mkexpr(t10), 2595 binop(Iop_Add8, 2596 unop(Iop_Not8, 2597 mkexpr(t8)), 2598 mkU8(0x1)), 2599 mkexpr(t8)))); 2600 2601 /* Absolute value of bits 31-24. */ 2602 /* t12 - input byte. */ 2603 assign(t12, 2604 unop(Iop_16HIto8, unop(Iop_32HIto16, getIReg(rt)))); 2605 /* t13 holds 1 if t12 is equal to 0x80, or 0 otherwise. */ 2606 assign(t13, binop(Iop_CmpEQ32, 2607 unop(Iop_8Uto32, mkexpr(t12)), 2608 mkU32(0x00000080))); 2609 /* t14 holds 1 if value in t12 is negative, 0 otherwise. */ 2610 assign(t14, unop(Iop_32to1, 2611 binop(Iop_Shr32, 2612 binop(Iop_And32, 2613 getIReg(rt), 2614 mkU32(0x80000000)), 2615 mkU8(31)))); 2616 /* t15 holds abs(t12). */ 2617 assign(t15, IRExpr_ITE(mkexpr(t13), 2618 mkU8(0x7F), 2619 IRExpr_ITE(mkexpr(t14), 2620 binop(Iop_Add8, 2621 unop(Iop_Not8, 2622 mkexpr(t12)), 2623 mkU8(0x1)), 2624 mkexpr(t12)))); 2625 2626 /* t16 holds !0 if any of input bytes is 0x80 or 0 2627 otherwise. */ 2628 assign(t16, 2629 binop(Iop_Or32, 2630 binop(Iop_Or32, 2631 binop(Iop_Or32, 2632 unop(Iop_1Sto32, mkexpr(t13)), 2633 unop(Iop_1Sto32, mkexpr(t9))), 2634 unop(Iop_1Sto32, mkexpr(t5))), 2635 unop(Iop_1Sto32, mkexpr(t1)))); 2636 2637 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 2638 mkexpr(t16), 2639 mkU32(0x0)), 2640 getDSPControl(), 2641 binop(Iop_Or32, 2642 getDSPControl(), 2643 mkU32(0x00100000)))); 2644 2645 /* t17 = t15|t11|t7|t3 */ 2646 assign(t17, 2647 binop(Iop_16HLto32, 2648 binop(Iop_8HLto16, mkexpr(t15), mkexpr(t11)), 2649 binop(Iop_8HLto16, mkexpr(t7), mkexpr(t3)))); 2650 2651 putIReg(rd, mkexpr(t17)); 2652 break; 2653 } 2654 case 0x2: { /* REPL.QB */ 2655 DIP("repl.qb r%d, %d", rd, dsp_imm); 2656 vassert(!mode64); 2657 2658 putIReg(rd, mkU32((dsp_imm << 24) | (dsp_imm << 16) | 2659 (dsp_imm << 8) | (dsp_imm))); 2660 break; 2661 } 2662 case 0x3: { /* REPLV.QB */ 2663 DIP("replv.qb r%d, r%d", rd, rt); 2664 vassert(!mode64); 2665 t0 = newTemp(Ity_I8); 2666 2667 assign(t0, unop(Iop_32to8, 2668 binop(Iop_And32, getIReg(rt), mkU32(0xff)))); 2669 putIReg(rd, 2670 binop(Iop_16HLto32, 2671 binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0)), 2672 binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0)))); 2673 break; 2674 } 2675 case 0x4: { /* PRECEQU.PH.QBL */ 2676 DIP("precequ.ph.qbl r%d, r%d", rd, rt); 2677 vassert(!mode64); 2678 2679 putIReg(rd, binop(Iop_Or32, 2680 binop(Iop_Shr32, 2681 binop(Iop_And32, 2682 getIReg(rt), 2683 mkU32(0xff000000)), 2684 mkU8(1)), 2685 binop(Iop_Shr32, 2686 binop(Iop_And32, 2687 getIReg(rt), 2688 mkU32(0x00ff0000)), 2689 mkU8(9)))); 2690 break; 2691 } 2692 case 0x5: { /* PRECEQU.PH.QBR */ 2693 DIP("precequ.ph.qbr r%d, r%d", rd, rt); 2694 vassert(!mode64); 2695 2696 putIReg(rd, binop(Iop_Or32, 2697 binop(Iop_Shl32, 2698 binop(Iop_And32, 2699 getIReg(rt), 2700 mkU32(0x0000ff00)), 2701 mkU8(15)), 2702 binop(Iop_Shl32, 2703 binop(Iop_And32, 2704 getIReg(rt), 2705 mkU32(0x000000ff)), 2706 mkU8(7)))); 2707 break; 2708 } 2709 case 0x6: { /* PRECEQU.PH.QBLA */ 2710 DIP("precequ.ph.qbla r%d, r%d", rd, rt); 2711 vassert(!mode64); 2712 2713 putIReg(rd, binop(Iop_Or32, 2714 binop(Iop_Shr32, 2715 binop(Iop_And32, 2716 getIReg(rt), 2717 mkU32(0xff000000)), 2718 mkU8(1)), 2719 binop(Iop_Shr32, 2720 binop(Iop_And32, 2721 getIReg(rt), 2722 mkU32(0x0000ff00)), 2723 mkU8(1)))); 2724 break; 2725 } 2726 case 0x7: { /* PRECEQU.PH.QBRA */ 2727 DIP("precequ.ph.qbra r%d, r%d", rd, rt); 2728 vassert(!mode64); 2729 2730 putIReg(rd, binop(Iop_Or32, 2731 binop(Iop_Shl32, 2732 binop(Iop_And32, 2733 getIReg(rt), 2734 mkU32(0x00ff0000)), 2735 mkU8(7)), 2736 binop(Iop_Shl32, 2737 binop(Iop_And32, 2738 getIReg(rt), 2739 mkU32(0x000000ff)), 2740 mkU8(7)))); 2741 break; 2742 } 2743 case 0x9: { /* ABSQ_S.PH */ 2744 DIP("absq_s.ph r%d, r%d", rd, rt); 2745 vassert(!mode64); 2746 t0 = newTemp(Ity_I16); 2747 t1 = newTemp(Ity_I1); 2748 t2 = newTemp(Ity_I1); 2749 t3 = newTemp(Ity_I16); 2750 t4 = newTemp(Ity_I16); 2751 t5 = newTemp(Ity_I1); 2752 t6 = newTemp(Ity_I1); 2753 t7 = newTemp(Ity_I16); 2754 t8 = newTemp(Ity_I32); 2755 t9 = newTemp(Ity_I32); 2756 2757 /* t0 holds lower 16 bits of value in rt. */ 2758 assign(t0, unop(Iop_32to16, getIReg(rt))); 2759 /* t1 holds 1 if t0 is equal to 0x8000. */ 2760 assign(t1, binop(Iop_CmpEQ32, 2761 unop(Iop_16Uto32, mkexpr(t0)), 2762 mkU32(0x00008000))); 2763 /* t2 holds 1 if value in t0 is negative, 0 otherwise. */ 2764 assign(t2, unop(Iop_32to1, 2765 binop(Iop_Shr32, 2766 binop(Iop_And32, 2767 getIReg(rt), 2768 mkU32(0x00008000)), 2769 mkU8(15)))); 2770 /* t3 holds abs(t0). */ 2771 assign(t3, IRExpr_ITE(mkexpr(t1), 2772 mkU16(0x7FFF), 2773 IRExpr_ITE(mkexpr(t2), 2774 binop(Iop_Add16, 2775 unop(Iop_Not16, 2776 mkexpr(t0)), 2777 mkU16(0x1)), 2778 mkexpr(t0)))); 2779 2780 /* t4 holds lower 16 bits of value in rt. */ 2781 assign(t4, unop(Iop_32HIto16, getIReg(rt))); 2782 /* t5 holds 1 if t4 is equal to 0x8000. */ 2783 assign(t5, binop(Iop_CmpEQ32, 2784 unop(Iop_16Uto32, mkexpr(t4)), 2785 mkU32(0x00008000))); 2786 /* t6 holds 1 if value in t4 is negative, 0 otherwise. */ 2787 assign(t6, unop(Iop_32to1, 2788 binop(Iop_Shr32, 2789 binop(Iop_And32, 2790 getIReg(rt), 2791 mkU32(0x80000000)), 2792 mkU8(31)))); 2793 /* t7 holds abs(t4). */ 2794 assign(t7, IRExpr_ITE(mkexpr(t5), 2795 mkU16(0x7FFF), 2796 IRExpr_ITE(mkexpr(t6), 2797 binop(Iop_Add16, 2798 unop(Iop_Not16, 2799 mkexpr(t4)), 2800 mkU16(0x1)), 2801 mkexpr(t4)))); 2802 /* If any of the two input halfwords is equal 0x8000, 2803 set bit 20 in DSPControl register. */ 2804 assign(t8, binop(Iop_Or32, 2805 unop(Iop_1Sto32, mkexpr(t5)), 2806 unop(Iop_1Sto32, mkexpr(t1)))); 2807 2808 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 2809 mkexpr(t8), 2810 mkU32(0x0)), 2811 getDSPControl(), 2812 binop(Iop_Or32, 2813 getDSPControl(), 2814 mkU32(0x00100000)))); 2815 2816 /* t9 = t7|t3 */ 2817 assign(t9, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3))); 2818 2819 putIReg(rd, mkexpr(t9)); 2820 break; 2821 } 2822 case 0xA: { /* REPL.PH */ 2823 DIP("repl.ph r%d, %d", rd, dsp_imm); 2824 vassert(!mode64); 2825 UShort immediate = extend_s_10to16(dsp_imm); 2826 2827 putIReg(rd, mkU32(immediate << 16 | immediate)); 2828 break; 2829 } 2830 case 0xB: { /* REPLV.PH */ 2831 DIP("replv.ph r%d, r%d", rd, rt); 2832 vassert(!mode64); 2833 2834 putIReg(rd, binop(Iop_16HLto32, 2835 unop(Iop_32to16, getIReg(rt)), 2836 unop(Iop_32to16, getIReg(rt)))); 2837 break; 2838 } 2839 case 0xC: { /* PRECEQ.W.PHL */ 2840 DIP("preceq.w.phl r%d, r%d", rd, rt); 2841 vassert(!mode64); 2842 putIReg(rd, binop(Iop_And32, 2843 getIReg(rt), 2844 mkU32(0xffff0000))); 2845 break; 2846 } 2847 case 0xD: { /* PRECEQ.W.PHR */ 2848 DIP("preceq.w.phr r%d, r%d", rd, rt); 2849 vassert(!mode64); 2850 putIReg(rd, binop(Iop_16HLto32, 2851 unop(Iop_32to16, getIReg(rt)), 2852 mkU16(0x0))); 2853 break; 2854 } 2855 case 0x11: { /* ABSQ_S.W */ 2856 DIP("absq_s.w r%d, r%d", rd, rt); 2857 vassert(!mode64); 2858 t0 = newTemp(Ity_I1); 2859 t1 = newTemp(Ity_I1); 2860 t2 = newTemp(Ity_I32); 2861 2862 assign(t0, 2863 binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000))); 2864 2865 putDSPControl(IRExpr_ITE(mkexpr(t0), 2866 binop(Iop_Or32, 2867 getDSPControl(), 2868 mkU32(0x00100000)), 2869 getDSPControl())); 2870 2871 assign(t1, binop(Iop_CmpLT32S, getIReg(rt), mkU32(0x0))); 2872 2873 assign(t2, IRExpr_ITE(mkexpr(t0), 2874 mkU32(0x7FFFFFFF), 2875 IRExpr_ITE(mkexpr(t1), 2876 binop(Iop_Add32, 2877 unop(Iop_Not32, 2878 getIReg(rt)), 2879 mkU32(0x1)), 2880 getIReg(rt)))); 2881 putIReg(rd, mkexpr(t2)); 2882 break; 2883 } 2884 case 0x1B: { /* BITREV */ 2885 DIP("bitrev r%d, r%d", rd, rt); 2886 vassert(!mode64); 2887 /* 32bit reversal as seen on Bit Twiddling Hacks site 2888 http://graphics.stanford.edu/~seander/bithacks.html 2889 section ReverseParallel */ 2890 t1 = newTemp(Ity_I32); 2891 t2 = newTemp(Ity_I32); 2892 t3 = newTemp(Ity_I32); 2893 t4 = newTemp(Ity_I32); 2894 t5 = newTemp(Ity_I32); 2895 2896 assign(t1, binop(Iop_Or32, 2897 binop(Iop_Shr32, 2898 binop(Iop_And32, 2899 getIReg(rt), 2900 mkU32(0xaaaaaaaa)), 2901 mkU8(0x1)), 2902 binop(Iop_Shl32, 2903 binop(Iop_And32, 2904 getIReg(rt), 2905 mkU32(0x55555555)), 2906 mkU8(0x1)))); 2907 assign(t2, binop(Iop_Or32, 2908 binop(Iop_Shr32, 2909 binop(Iop_And32, 2910 mkexpr(t1), 2911 mkU32(0xcccccccc)), 2912 mkU8(0x2)), 2913 binop(Iop_Shl32, 2914 binop(Iop_And32, 2915 mkexpr(t1), 2916 mkU32(0x33333333)), 2917 mkU8(0x2)))); 2918 assign(t3, binop(Iop_Or32, 2919 binop(Iop_Shr32, 2920 binop(Iop_And32, 2921 mkexpr(t2), 2922 mkU32(0xf0f0f0f0)), 2923 mkU8(0x4)), 2924 binop(Iop_Shl32, 2925 binop(Iop_And32, 2926 mkexpr(t2), 2927 mkU32(0x0f0f0f0f)), 2928 mkU8(0x4)))); 2929 assign(t4, binop(Iop_Or32, 2930 binop(Iop_Shr32, 2931 binop(Iop_And32, 2932 mkexpr(t3), 2933 mkU32(0xff00ff00)), 2934 mkU8(0x8)), 2935 binop(Iop_Shl32, 2936 binop(Iop_And32, 2937 mkexpr(t3), 2938 mkU32(0x00ff00ff)), 2939 mkU8(0x8)))); 2940 assign(t5, binop(Iop_Or32, 2941 binop(Iop_Shr32, 2942 mkexpr(t4), 2943 mkU8(0x10)), 2944 binop(Iop_Shl32, 2945 mkexpr(t4), 2946 mkU8(0x10)))); 2947 putIReg(rd, binop(Iop_Shr32, 2948 mkexpr(t5), 2949 mkU8(16))); 2950 break; 2951 } 2952 case 0x1C: { /* PRECEU.PH.QBL */ 2953 DIP("preceu.ph.qbl r%d, r%d", rd, rt); 2954 vassert(!mode64); 2955 2956 putIReg(rd, binop(Iop_Or32, 2957 binop(Iop_Shr32, 2958 binop(Iop_And32, 2959 getIReg(rt), 2960 mkU32(0xff000000)), 2961 mkU8(8)), 2962 binop(Iop_Shr32, 2963 binop(Iop_And32, 2964 getIReg(rt), 2965 mkU32(0x00ff0000)), 2966 mkU8(16)))); 2967 break; 2968 } 2969 case 0x1E: { /* PRECEU.PH.QBLA */ 2970 DIP("preceu.ph.qbla r%d, r%d", rd, rt); 2971 vassert(!mode64); 2972 2973 putIReg(rd, binop(Iop_Or32, 2974 binop(Iop_Shr32, 2975 binop(Iop_And32, 2976 getIReg(rt), 2977 mkU32(0xff000000)), 2978 mkU8(8)), 2979 binop(Iop_Shr32, 2980 binop(Iop_And32, 2981 getIReg(rt), 2982 mkU32(0x0000ff00)), 2983 mkU8(8)))); 2984 break; 2985 } 2986 case 0x1D: { /* PRECEU.PH.QBR */ 2987 DIP("preceu.ph.qbr r%d, r%d", rd, rt); 2988 vassert(!mode64); 2989 2990 putIReg(rd, binop(Iop_Or32, 2991 binop(Iop_Shl32, 2992 binop(Iop_And32, 2993 getIReg(rt), 2994 mkU32(0x0000ff00)), 2995 mkU8(8)), 2996 binop(Iop_And32, 2997 getIReg(rt), 2998 mkU32(0x000000ff)))); 2999 break; 3000 } 3001 case 0x1F: { /* PRECEU.PH.QBRA */ 3002 DIP("preceu.ph.qbra r%d, r%d", rd, rt); 3003 vassert(!mode64); 3004 3005 putIReg(rd, binop(Iop_Or32, 3006 binop(Iop_And32, 3007 getIReg(rt), 3008 mkU32(0x00ff0000)), 3009 binop(Iop_And32, 3010 getIReg(rt), 3011 mkU32(0x000000ff)))); 3012 break; 3013 } 3014 default: 3015 return -1; 3016 } 3017 break; /* end of ABSQ_S.PH */ 3018 } 3019 case 0x38: { /* EXTR.W */ 3020 switch(sa) { 3021 case 0x0: { /* EXTR.W */ 3022 DIP("extr.w r%d, ac%d, %d", rt, ac, rs); 3023 vassert(!mode64); 3024 t0 = newTemp(Ity_I64); 3025 t1 = newTemp(Ity_I64); 3026 t2 = newTemp(Ity_I32); 3027 t3 = newTemp(Ity_I1); 3028 t4 = newTemp(Ity_I1); 3029 t5 = newTemp(Ity_I1); 3030 t6 = newTemp(Ity_I1); 3031 t7 = newTemp(Ity_I32); 3032 t8 = newTemp(Ity_I64); 3033 t9 = newTemp(Ity_I64); 3034 t10 = newTemp(Ity_I1); 3035 t11 = newTemp(Ity_I1); 3036 t12 = newTemp(Ity_I1); 3037 t13 = newTemp(Ity_I1); 3038 t14 = newTemp(Ity_I32); 3039 3040 assign(t0, getAcc(ac)); 3041 if (0 == rs) { 3042 assign(t1, mkexpr(t0)); 3043 } else { 3044 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs))); 3045 } 3046 /* Check if bits 63..31 of the result in t1 aren't 0. */ 3047 assign(t3, binop(Iop_CmpNE32, 3048 unop(Iop_64HIto32, 3049 mkexpr(t1)), 3050 mkU32(0))); 3051 assign(t4, binop(Iop_CmpNE32, 3052 binop(Iop_And32, 3053 unop(Iop_64to32, 3054 mkexpr(t1)), 3055 mkU32(0x80000000)), 3056 mkU32(0))); 3057 /* Check if bits 63..31 of the result in t1 aren't 3058 0x1ffffffff. */ 3059 assign(t5, binop(Iop_CmpNE32, 3060 unop(Iop_64HIto32, 3061 mkexpr(t1)), 3062 mkU32(0xffffffff))); 3063 assign(t6, binop(Iop_CmpNE32, 3064 binop(Iop_And32, 3065 unop(Iop_64to32, 3066 mkexpr(t1)), 3067 mkU32(0x80000000)), 3068 mkU32(0x80000000))); 3069 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP 3070 control register. */ 3071 assign(t7, binop(Iop_And32, 3072 binop(Iop_Or32, 3073 unop(Iop_1Sto32, mkexpr(t3)), 3074 unop(Iop_1Sto32, mkexpr(t4))), 3075 binop(Iop_Or32, 3076 unop(Iop_1Sto32, mkexpr(t5)), 3077 unop(Iop_1Sto32, mkexpr(t6))))); 3078 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3079 mkexpr(t7), 3080 mkU32(0)), 3081 binop(Iop_Or32, 3082 getDSPControl(), 3083 mkU32(0x00800000)), 3084 getDSPControl())); 3085 3086 /* If the last discarded bit is 1, there would be carry 3087 when rounding, otherwise there wouldn't. We use that 3088 fact and just add the value of the last discarded bit 3089 to the least sifgnificant bit of the shifted value 3090 from acc. */ 3091 if (0 == rs) { 3092 assign(t8, mkU64(0x0ULL)); 3093 } else { 3094 assign(t8, binop(Iop_And64, 3095 binop(Iop_Shr64, 3096 mkexpr(t0), 3097 mkU8(rs-1)), 3098 mkU64(0x1ULL))); 3099 } 3100 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8))); 3101 3102 /* Repeat previous steps for the rounded value. */ 3103 assign(t10, binop(Iop_CmpNE32, 3104 unop(Iop_64HIto32, 3105 mkexpr(t9)), 3106 mkU32(0))); 3107 assign(t11, binop(Iop_CmpNE32, 3108 binop(Iop_And32, 3109 unop(Iop_64to32, 3110 mkexpr(t9)), 3111 mkU32(0x80000000)), 3112 mkU32(0))); 3113 3114 assign(t12, binop(Iop_CmpNE32, 3115 unop(Iop_64HIto32, 3116 mkexpr(t9)), 3117 mkU32(0xffffffff))); 3118 assign(t13, binop(Iop_CmpNE32, 3119 binop(Iop_And32, 3120 unop(Iop_64to32, 3121 mkexpr(t9)), 3122 mkU32(0x80000000)), 3123 mkU32(0x80000000))); 3124 3125 assign(t14, binop(Iop_And32, 3126 binop(Iop_Or32, 3127 unop(Iop_1Sto32, mkexpr(t10)), 3128 unop(Iop_1Sto32, mkexpr(t11))), 3129 binop(Iop_Or32, 3130 unop(Iop_1Sto32, mkexpr(t12)), 3131 unop(Iop_1Sto32, mkexpr(t13))))); 3132 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3133 mkexpr(t14), 3134 mkU32(0)), 3135 binop(Iop_Or32, 3136 getDSPControl(), 3137 mkU32(0x00800000)), 3138 getDSPControl())); 3139 if (0 == rs) { 3140 putIReg(rt, unop(Iop_64to32, mkexpr(t0))); 3141 } else { 3142 putIReg(rt, unop(Iop_64to32, mkexpr(t1))); 3143 } 3144 break; 3145 } 3146 case 0x1: { /* EXTRV.W */ 3147 DIP("extrv.w r%d, ac%d, r%d", rt, ac, rs); 3148 vassert(!mode64); 3149 t0 = newTemp(Ity_I64); 3150 t1 = newTemp(Ity_I64); 3151 t2 = newTemp(Ity_I32); 3152 t3 = newTemp(Ity_I1); 3153 t4 = newTemp(Ity_I1); 3154 t5 = newTemp(Ity_I1); 3155 t6 = newTemp(Ity_I1); 3156 t7 = newTemp(Ity_I32); 3157 t8 = newTemp(Ity_I64); 3158 t9 = newTemp(Ity_I64); 3159 t10 = newTemp(Ity_I1); 3160 t11 = newTemp(Ity_I1); 3161 t12 = newTemp(Ity_I1); 3162 t13 = newTemp(Ity_I1); 3163 t14 = newTemp(Ity_I32); 3164 t15 = newTemp(Ity_I8); 3165 3166 assign(t15, unop(Iop_32to8, 3167 binop(Iop_And32, 3168 getIReg(rs), 3169 mkU32(0x1f)))); 3170 assign(t0, getAcc(ac)); 3171 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15))); 3172 putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32, 3173 unop(Iop_8Uto32, 3174 mkexpr(t15)), 3175 mkU32(0)), 3176 unop(Iop_64to32, mkexpr(t0)), 3177 unop(Iop_64to32, mkexpr(t1)))); 3178 3179 /* Check if bits 63..31 of the result in t1 aren't 0. */ 3180 assign(t3, binop(Iop_CmpNE32, 3181 unop(Iop_64HIto32, 3182 mkexpr(t1)), 3183 mkU32(0))); 3184 assign(t4, binop(Iop_CmpNE32, 3185 binop(Iop_And32, 3186 unop(Iop_64to32, 3187 mkexpr(t1)), 3188 mkU32(0x80000000)), 3189 mkU32(0))); 3190 /* Check if bits 63..31 of the result in t1 aren't 3191 0x1ffffffff. */ 3192 assign(t5, binop(Iop_CmpNE32, 3193 unop(Iop_64HIto32, 3194 mkexpr(t1)), 3195 mkU32(0xffffffff))); 3196 assign(t6, binop(Iop_CmpNE32, 3197 binop(Iop_And32, 3198 unop(Iop_64to32, 3199 mkexpr(t1)), 3200 mkU32(0x80000000)), 3201 mkU32(0x80000000))); 3202 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP 3203 control register. */ 3204 assign(t7, binop(Iop_And32, 3205 binop(Iop_Or32, 3206 unop(Iop_1Sto32, mkexpr(t3)), 3207 unop(Iop_1Sto32, mkexpr(t4))), 3208 binop(Iop_Or32, 3209 unop(Iop_1Sto32, mkexpr(t5)), 3210 unop(Iop_1Sto32, mkexpr(t6))))); 3211 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3212 mkexpr(t7), 3213 mkU32(0)), 3214 binop(Iop_Or32, 3215 getDSPControl(), 3216 mkU32(0x00800000)), 3217 getDSPControl())); 3218 3219 /* If the last discarded bit is 1, there would be carry 3220 when rounding, otherwise there wouldn't. We use that 3221 fact and just add the value of the last discarded bit 3222 to the least sifgnificant bit of the shifted value 3223 from acc. */ 3224 assign(t8, 3225 IRExpr_ITE(binop(Iop_CmpEQ32, 3226 unop(Iop_8Uto32, 3227 mkexpr(t15)), 3228 mkU32(0)), 3229 mkU64(0x0ULL), 3230 binop(Iop_And64, 3231 binop(Iop_Shr64, 3232 mkexpr(t0), 3233 unop(Iop_32to8, 3234 binop(Iop_Sub32, 3235 unop(Iop_8Uto32, 3236 mkexpr(t15)), 3237 mkU32(1)))), 3238 mkU64(0x1ULL)))); 3239 3240 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8))); 3241 3242 /* Repeat previous steps for the rounded value. */ 3243 assign(t10, binop(Iop_CmpNE32, 3244 unop(Iop_64HIto32, 3245 mkexpr(t9)), 3246 mkU32(0))); 3247 assign(t11, binop(Iop_CmpNE32, 3248 binop(Iop_And32, 3249 unop(Iop_64to32, 3250 mkexpr(t9)), 3251 mkU32(0x80000000)), 3252 mkU32(0))); 3253 3254 assign(t12, binop(Iop_CmpNE32, 3255 unop(Iop_64HIto32, 3256 mkexpr(t9)), 3257 mkU32(0xffffffff))); 3258 assign(t13, binop(Iop_CmpNE32, 3259 binop(Iop_And32, 3260 unop(Iop_64to32, 3261 mkexpr(t9)), 3262 mkU32(0x80000000)), 3263 mkU32(0x80000000))); 3264 3265 assign(t14, binop(Iop_And32, 3266 binop(Iop_Or32, 3267 unop(Iop_1Sto32, mkexpr(t10)), 3268 unop(Iop_1Sto32, mkexpr(t11))), 3269 binop(Iop_Or32, 3270 unop(Iop_1Sto32, mkexpr(t12)), 3271 unop(Iop_1Sto32, mkexpr(t13))))); 3272 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3273 mkexpr(t14), 3274 mkU32(0)), 3275 binop(Iop_Or32, 3276 getDSPControl(), 3277 mkU32(0x00800000)), 3278 getDSPControl())); 3279 break; 3280 } 3281 case 0x2: { /* EXTP */ 3282 DIP("extp r%d, ac%d, %d", rt, ac, rs); 3283 vassert(!mode64); 3284 t0 = newTemp(Ity_I64); 3285 t1 = newTemp(Ity_I32); 3286 t2 = newTemp(Ity_I1); 3287 t3 = newTemp(Ity_I1); 3288 t4 = newTemp(Ity_I8); 3289 t5 = newTemp(Ity_I64); 3290 t6 = newTemp(Ity_I64); 3291 t7 = newTemp(Ity_I32); 3292 3293 assign(t0, getAcc(ac)); 3294 /* Extract pos field of DSPControl register. */ 3295 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f))); 3296 3297 /* Check if (pos - size) >= 0 [size <= pos] 3298 if (pos < size) 3299 put 1 to EFI field of DSPControl register 3300 else 3301 extract bits from acc and put 0 to EFI field of 3302 DSPCtrl */ 3303 assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs))); 3304 3305 putDSPControl(IRExpr_ITE(mkexpr(t2), 3306 binop(Iop_Or32, 3307 binop(Iop_And32, 3308 getDSPControl(), 3309 mkU32(0xffffbfff)), 3310 mkU32(0x4000)), 3311 binop(Iop_And32, 3312 getDSPControl(), 3313 mkU32(0xffffbfff)))); 3314 3315 /* If pos <= 31, shift right the value from the acc 3316 (pos-size) times and take (size+1) bits from the least 3317 significant positions. Otherwise, shift left the value 3318 (63-pos) times, take (size+1) bits from the most 3319 significant positions and shift right (31-size) times.*/ 3320 assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31))); 3321 3322 assign(t4, 3323 IRExpr_ITE(mkexpr(t3), 3324 unop(Iop_32to8, 3325 binop(Iop_Sub32, 3326 mkexpr(t1), mkU32(rs))), 3327 unop(Iop_32to8, 3328 binop(Iop_Sub32, 3329 mkU32(63), mkexpr(t1))))); 3330 3331 assign(t5, IRExpr_ITE(mkexpr(t3), 3332 binop(Iop_Shr64, 3333 mkexpr(t0), mkexpr(t4)), 3334 binop(Iop_Shl64, 3335 mkexpr(t0), mkexpr(t4)))); 3336 3337 /* t6 holds a mask for bit extraction */ 3338 assign(t6, 3339 IRExpr_ITE(mkexpr(t3), 3340 unop(Iop_Not64, 3341 binop(Iop_Shl64, 3342 mkU64(0xffffffffffffffffULL), 3343 mkU8(rs+1))), 3344 unop(Iop_Not64, 3345 binop(Iop_Shr64, 3346 mkU64(0xffffffffffffffffULL), 3347 mkU8(rs+1))))); 3348 3349 assign(t7, IRExpr_ITE(mkexpr(t3), 3350 unop(Iop_64to32, 3351 binop(Iop_And64, 3352 mkexpr(t5), 3353 mkexpr(t6))), 3354 binop(Iop_Shr32, 3355 unop(Iop_64HIto32, 3356 binop(Iop_And64, 3357 mkexpr(t5), 3358 mkexpr(t6))), 3359 mkU8(31-rs)))); 3360 3361 putIReg(rt, mkexpr(t7)); 3362 break; 3363 } 3364 case 0x3: { /* EXTPV */ 3365 DIP("extpv r%d, ac%d, r%d", rt, ac, rs); 3366 vassert(!mode64); 3367 t0 = newTemp(Ity_I64); 3368 t1 = newTemp(Ity_I32); 3369 t2 = newTemp(Ity_I1); 3370 t3 = newTemp(Ity_I1); 3371 t4 = newTemp(Ity_I8); 3372 t5 = newTemp(Ity_I64); 3373 t6 = newTemp(Ity_I64); 3374 t7 = newTemp(Ity_I32); 3375 t8 = newTemp(Ity_I32); 3376 3377 assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f))); 3378 assign(t0, getAcc(ac)); 3379 /* Extract pos field of DSPControl register. */ 3380 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f))); 3381 3382 /* Check if (pos - size) >= 0 [size <= pos] 3383 if (pos < size) 3384 put 1 to EFI field of DSPControl register 3385 else 3386 extract bits from acc and put 0 to EFI field of 3387 DSPCtrl */ 3388 assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8))); 3389 3390 putDSPControl(IRExpr_ITE(mkexpr(t2), 3391 binop(Iop_Or32, 3392 binop(Iop_And32, 3393 getDSPControl(), 3394 mkU32(0xffffbfff)), 3395 mkU32(0x4000)), 3396 binop(Iop_And32, 3397 getDSPControl(), 3398 mkU32(0xffffbfff)))); 3399 3400 /* If pos <= 31, shift right the value from the acc 3401 (pos-size) times and take (size+1) bits from the least 3402 significant positions. Otherwise, shift left the value 3403 (63-pos) times, take (size+1) bits from the most 3404 significant positions and shift right (31-size) 3405 times. */ 3406 assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31))); 3407 3408 assign(t4, 3409 IRExpr_ITE(mkexpr(t3), 3410 unop(Iop_32to8, 3411 binop(Iop_Sub32, 3412 mkexpr(t1), mkexpr(t8))), 3413 unop(Iop_32to8, 3414 binop(Iop_Sub32, 3415 mkU32(63), mkexpr(t1))))); 3416 3417 assign(t5, IRExpr_ITE(mkexpr(t3), 3418 binop(Iop_Shr64, 3419 mkexpr(t0), mkexpr(t4)), 3420 binop(Iop_Shl64, 3421 mkexpr(t0), mkexpr(t4)))); 3422 3423 /* t6 holds a mask for bit extraction. */ 3424 assign(t6, 3425 IRExpr_ITE(mkexpr(t3), 3426 unop(Iop_Not64, 3427 binop(Iop_Shl64, 3428 mkU64(0xffffffffffffffffULL), 3429 unop(Iop_32to8, 3430 binop(Iop_Add32, 3431 mkexpr(t8), 3432 mkU32(1))))), 3433 unop(Iop_Not64, 3434 binop(Iop_Shr64, 3435 mkU64(0xffffffffffffffffULL), 3436 unop(Iop_32to8, 3437 binop(Iop_Add32, 3438 mkexpr(t8), 3439 mkU32(1))))))); 3440 3441 assign(t7, IRExpr_ITE(mkexpr(t3), 3442 unop(Iop_64to32, 3443 binop(Iop_And64, 3444 mkexpr(t5), 3445 mkexpr(t6))), 3446 binop(Iop_Shr32, 3447 unop(Iop_64HIto32, 3448 binop(Iop_And64, 3449 mkexpr(t5), 3450 mkexpr(t6))), 3451 unop(Iop_32to8, 3452 binop(Iop_Sub32, 3453 mkU32(31), 3454 mkexpr(t8)))))); 3455 3456 putIReg(rt, mkexpr(t7)); 3457 break; 3458 } 3459 case 0x4: { /* EXTR_R.W */ 3460 DIP("extr_r.w r%d, ac%d, %d", rt, ac, rs); 3461 vassert(!mode64); 3462 t0 = newTemp(Ity_I64); 3463 t1 = newTemp(Ity_I64); 3464 t2 = newTemp(Ity_I32); 3465 t3 = newTemp(Ity_I1); 3466 t4 = newTemp(Ity_I1); 3467 t5 = newTemp(Ity_I1); 3468 t6 = newTemp(Ity_I1); 3469 t7 = newTemp(Ity_I32); 3470 t8 = newTemp(Ity_I64); 3471 t9 = newTemp(Ity_I64); 3472 t10 = newTemp(Ity_I1); 3473 t11 = newTemp(Ity_I1); 3474 t12 = newTemp(Ity_I1); 3475 t13 = newTemp(Ity_I1); 3476 t14 = newTemp(Ity_I32); 3477 t15 = newTemp(Ity_I64); 3478 t16 = newTemp(Ity_I1); 3479 3480 assign(t0, getAcc(ac)); 3481 assign(t16, binop(Iop_CmpEQ32, 3482 mkU32(rs), 3483 mkU32(0))); 3484 assign(t1, IRExpr_ITE(mkexpr(t16), 3485 mkexpr(t0), 3486 binop(Iop_Sar64, 3487 mkexpr(t0), 3488 mkU8(rs)))); 3489 /* If the last discarded bit is 1, there would be carry 3490 when rounding, otherwise there wouldn't. We use that 3491 fact and just add the value of the last discarded bit 3492 to the least significant bit of the shifted value 3493 from acc. */ 3494 assign(t15, binop(Iop_Shr64, 3495 mkexpr(t0), 3496 unop(Iop_32to8, 3497 binop(Iop_Sub32, 3498 binop(Iop_And32, 3499 mkU32(rs), 3500 mkU32(0x1f)), 3501 mkU32(1))))); 3502 3503 assign(t8, 3504 IRExpr_ITE(mkexpr(t16), 3505 mkU64(0x0ULL), 3506 binop(Iop_And64, 3507 mkexpr(t15), 3508 mkU64(0x0000000000000001ULL)))); 3509 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8))); 3510 putIReg(rt, unop(Iop_64to32, mkexpr(t9))); 3511 3512 /* Check if bits 63..31 of the result in t1 aren't 0. */ 3513 assign(t3, binop(Iop_CmpNE32, 3514 unop(Iop_64HIto32, 3515 mkexpr(t1)), 3516 mkU32(0))); 3517 assign(t4, binop(Iop_CmpNE32, 3518 binop(Iop_And32, 3519 unop(Iop_64to32, 3520 mkexpr(t1)), 3521 mkU32(0x80000000)), 3522 mkU32(0))); 3523 3524 /* Check if bits 63..31 of the result in t1 aren't 3525 0x1ffffffff. */ 3526 assign(t5, binop(Iop_CmpNE32, 3527 unop(Iop_64HIto32, 3528 mkexpr(t1)), 3529 mkU32(0xffffffff))); 3530 assign(t6, binop(Iop_CmpNE32, 3531 binop(Iop_And32, 3532 unop(Iop_64to32, 3533 mkexpr(t1)), 3534 mkU32(0x80000000)), 3535 mkU32(0x80000000))); 3536 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP 3537 control register. */ 3538 assign(t7, binop(Iop_And32, 3539 binop(Iop_Or32, 3540 unop(Iop_1Sto32, mkexpr(t3)), 3541 unop(Iop_1Sto32, mkexpr(t4))), 3542 binop(Iop_Or32, 3543 unop(Iop_1Sto32, mkexpr(t5)), 3544 unop(Iop_1Sto32, mkexpr(t6))))); 3545 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3546 mkexpr(t7), 3547 mkU32(0)), 3548 binop(Iop_Or32, 3549 getDSPControl(), 3550 mkU32(0x00800000)), 3551 getDSPControl())); 3552 3553 /* Repeat previous steps for the rounded value. */ 3554 assign(t10, binop(Iop_CmpNE32, 3555 unop(Iop_64HIto32, 3556 mkexpr(t9)), 3557 mkU32(0))); 3558 assign(t11, binop(Iop_CmpNE32, 3559 binop(Iop_And32, 3560 unop(Iop_64to32, 3561 mkexpr(t9)), 3562 mkU32(0x80000000)), 3563 mkU32(0))); 3564 3565 assign(t12, binop(Iop_CmpNE32, 3566 unop(Iop_64HIto32, 3567 mkexpr(t9)), 3568 mkU32(0xffffffff))); 3569 assign(t13, binop(Iop_CmpNE32, 3570 binop(Iop_And32, 3571 unop(Iop_64to32, 3572 mkexpr(t9)), 3573 mkU32(0x80000000)), 3574 mkU32(0x80000000))); 3575 3576 assign(t14, binop(Iop_And32, 3577 binop(Iop_Or32, 3578 unop(Iop_1Sto32, mkexpr(t10)), 3579 unop(Iop_1Sto32, mkexpr(t11))), 3580 binop(Iop_Or32, 3581 unop(Iop_1Sto32, mkexpr(t12)), 3582 unop(Iop_1Sto32, mkexpr(t13))))); 3583 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3584 mkexpr(t14), 3585 mkU32(0)), 3586 binop(Iop_Or32, 3587 getDSPControl(), 3588 mkU32(0x00800000)), 3589 getDSPControl())); 3590 break; 3591 } 3592 case 0x5: { /* EXTRV_R.W */ 3593 DIP("extrv_r.w r%d, ac%d, r%d", rt, ac, rs); 3594 vassert(!mode64); 3595 t0 = newTemp(Ity_I64); 3596 t1 = newTemp(Ity_I64); 3597 t2 = newTemp(Ity_I32); 3598 t3 = newTemp(Ity_I1); 3599 t4 = newTemp(Ity_I1); 3600 t5 = newTemp(Ity_I1); 3601 t6 = newTemp(Ity_I1); 3602 t7 = newTemp(Ity_I32); 3603 t8 = newTemp(Ity_I64); 3604 t9 = newTemp(Ity_I64); 3605 t10 = newTemp(Ity_I1); 3606 t11 = newTemp(Ity_I1); 3607 t12 = newTemp(Ity_I1); 3608 t13 = newTemp(Ity_I1); 3609 t14 = newTemp(Ity_I32); 3610 t15 = newTemp(Ity_I8); 3611 3612 assign(t15, unop(Iop_32to8, 3613 binop(Iop_And32, 3614 getIReg(rs), 3615 mkU32(0x1f)))); 3616 assign(t0, getAcc(ac)); 3617 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15))); 3618 3619 /* Check if bits 63..31 of the result in t1 aren't 0. */ 3620 assign(t3, binop(Iop_CmpNE32, 3621 unop(Iop_64HIto32, 3622 mkexpr(t1)), 3623 mkU32(0))); 3624 assign(t4, binop(Iop_CmpNE32, 3625 binop(Iop_And32, 3626 unop(Iop_64to32, 3627 mkexpr(t1)), 3628 mkU32(0x80000000)), 3629 mkU32(0))); 3630 /* Check if bits 63..31 of the result in t1 aren't 3631 0x1ffffffff. */ 3632 assign(t5, binop(Iop_CmpNE32, 3633 unop(Iop_64HIto32, 3634 mkexpr(t1)), 3635 mkU32(0xffffffff))); 3636 assign(t6, binop(Iop_CmpNE32, 3637 binop(Iop_And32, 3638 unop(Iop_64to32, 3639 mkexpr(t1)), 3640 mkU32(0x80000000)), 3641 mkU32(0x80000000))); 3642 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP 3643 control register. */ 3644 assign(t7, binop(Iop_And32, 3645 binop(Iop_Or32, 3646 unop(Iop_1Sto32, mkexpr(t3)), 3647 unop(Iop_1Sto32, mkexpr(t4))), 3648 binop(Iop_Or32, 3649 unop(Iop_1Sto32, mkexpr(t5)), 3650 unop(Iop_1Sto32, mkexpr(t6))))); 3651 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3652 mkexpr(t7), 3653 mkU32(0)), 3654 binop(Iop_Or32, 3655 getDSPControl(), 3656 mkU32(0x00800000)), 3657 getDSPControl())); 3658 3659 /* If the last discarded bit is 1, there would be carry 3660 when rounding, otherwise there wouldn't. We use that 3661 fact and just add the value of the last discarded bit 3662 to the least sifgnificant bit of the shifted value 3663 from acc. */ 3664 assign(t8, 3665 IRExpr_ITE(binop(Iop_CmpEQ32, 3666 unop(Iop_8Uto32, 3667 mkexpr(t15)), 3668 mkU32(0)), 3669 mkU64(0x0ULL), 3670 binop(Iop_And64, 3671 binop(Iop_Shr64, 3672 mkexpr(t0), 3673 unop(Iop_32to8, 3674 binop(Iop_Sub32, 3675 unop(Iop_8Uto32, 3676 mkexpr(t15)), 3677 mkU32(1)))), 3678 mkU64(0x1ULL)))); 3679 3680 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8))); 3681 /* Put rounded value in destination register. */ 3682 putIReg(rt, unop(Iop_64to32, mkexpr(t9))); 3683 3684 /* Repeat previous steps for the rounded value. */ 3685 assign(t10, binop(Iop_CmpNE32, 3686 unop(Iop_64HIto32, 3687 mkexpr(t9)), 3688 mkU32(0))); 3689 assign(t11, binop(Iop_CmpNE32, 3690 binop(Iop_And32, 3691 unop(Iop_64to32, 3692 mkexpr(t9)), 3693 mkU32(0x80000000)), 3694 mkU32(0))); 3695 3696 assign(t12, binop(Iop_CmpNE32, 3697 unop(Iop_64HIto32, 3698 mkexpr(t9)), 3699 mkU32(0xffffffff))); 3700 assign(t13, binop(Iop_CmpNE32, 3701 binop(Iop_And32, 3702 unop(Iop_64to32, 3703 mkexpr(t9)), 3704 mkU32(0x80000000)), 3705 mkU32(0x80000000))); 3706 3707 assign(t14, binop(Iop_And32, 3708 binop(Iop_Or32, 3709 unop(Iop_1Sto32, mkexpr(t10)), 3710 unop(Iop_1Sto32, mkexpr(t11))), 3711 binop(Iop_Or32, 3712 unop(Iop_1Sto32, mkexpr(t12)), 3713 unop(Iop_1Sto32, mkexpr(t13))))); 3714 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3715 mkexpr(t14), 3716 mkU32(0)), 3717 binop(Iop_Or32, 3718 getDSPControl(), 3719 mkU32(0x00800000)), 3720 getDSPControl())); 3721 break; 3722 } 3723 case 0x6: { /* EXTR_RS.W */ 3724 DIP("extr_rs.w r%d, ac%d, %d", rt, ac, rs); 3725 vassert(!mode64); 3726 t0 = newTemp(Ity_I64); 3727 t1 = newTemp(Ity_I64); 3728 t2 = newTemp(Ity_I32); 3729 t3 = newTemp(Ity_I1); 3730 t4 = newTemp(Ity_I1); 3731 t5 = newTemp(Ity_I1); 3732 t6 = newTemp(Ity_I1); 3733 t7 = newTemp(Ity_I32); 3734 t8 = newTemp(Ity_I64); 3735 t9 = newTemp(Ity_I64); 3736 t10 = newTemp(Ity_I1); 3737 t11 = newTemp(Ity_I1); 3738 t12 = newTemp(Ity_I1); 3739 t13 = newTemp(Ity_I1); 3740 t14 = newTemp(Ity_I32); 3741 t16 = newTemp(Ity_I32); 3742 3743 assign(t0, getAcc(ac)); 3744 if (0 == rs) { 3745 assign(t1, mkexpr(t0)); 3746 } else { 3747 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs))); 3748 } 3749 3750 /* Check if bits 63..31 of the result in t1 aren't 0. */ 3751 assign(t3, binop(Iop_CmpNE32, 3752 unop(Iop_64HIto32, 3753 mkexpr(t1)), 3754 mkU32(0))); 3755 assign(t4, binop(Iop_CmpNE32, 3756 binop(Iop_And32, 3757 unop(Iop_64to32, 3758 mkexpr(t1)), 3759 mkU32(0x80000000)), 3760 mkU32(0))); 3761 /* Check if bits 63..31 of the result in t1 aren't 3762 0x1ffffffff. */ 3763 assign(t5, binop(Iop_CmpNE32, 3764 unop(Iop_64HIto32, 3765 mkexpr(t1)), 3766 mkU32(0xffffffff))); 3767 assign(t6, binop(Iop_CmpNE32, 3768 binop(Iop_And32, 3769 unop(Iop_64to32, 3770 mkexpr(t1)), 3771 mkU32(0x80000000)), 3772 mkU32(0x80000000))); 3773 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP 3774 control register. */ 3775 assign(t7, binop(Iop_And32, 3776 binop(Iop_Or32, 3777 unop(Iop_1Sto32, mkexpr(t3)), 3778 unop(Iop_1Sto32, mkexpr(t4))), 3779 binop(Iop_Or32, 3780 unop(Iop_1Sto32, mkexpr(t5)), 3781 unop(Iop_1Sto32, mkexpr(t6))))); 3782 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3783 mkexpr(t7), 3784 mkU32(0)), 3785 binop(Iop_Or32, 3786 getDSPControl(), 3787 mkU32(0x00800000)), 3788 getDSPControl())); 3789 3790 /* If the last discarded bit is 1, there would be carry 3791 when rounding, otherwise there wouldn't. We use that 3792 fact and just add the value of the last discarded bit 3793 to the least sifgnificant bit of the shifted value 3794 from acc. */ 3795 if (0 == rs) { 3796 assign(t8, mkU64(0x0ULL)); 3797 } else { 3798 assign(t8, binop(Iop_And64, 3799 binop(Iop_Shr64, 3800 mkexpr(t0), 3801 mkU8(rs-1)), 3802 mkU64(0x1ULL))); 3803 } 3804 3805 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8))); 3806 3807 /* Repeat previous steps for the rounded value. */ 3808 assign(t10, binop(Iop_CmpNE32, 3809 unop(Iop_64HIto32, 3810 mkexpr(t9)), 3811 mkU32(0))); 3812 assign(t11, binop(Iop_CmpNE32, 3813 binop(Iop_And32, 3814 unop(Iop_64to32, 3815 mkexpr(t9)), 3816 mkU32(0x80000000)), 3817 mkU32(0))); 3818 3819 assign(t12, binop(Iop_CmpNE32, 3820 unop(Iop_64HIto32, 3821 mkexpr(t9)), 3822 mkU32(0xffffffff))); 3823 assign(t13, binop(Iop_CmpNE32, 3824 binop(Iop_And32, 3825 unop(Iop_64to32, 3826 mkexpr(t9)), 3827 mkU32(0x80000000)), 3828 mkU32(0x80000000))); 3829 3830 assign(t14, binop(Iop_And32, 3831 binop(Iop_Or32, 3832 unop(Iop_1Sto32, mkexpr(t10)), 3833 unop(Iop_1Sto32, mkexpr(t11))), 3834 binop(Iop_Or32, 3835 unop(Iop_1Sto32, mkexpr(t12)), 3836 unop(Iop_1Sto32, mkexpr(t13))))); 3837 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3838 mkexpr(t14), 3839 mkU32(0)), 3840 binop(Iop_Or32, 3841 getDSPControl(), 3842 mkU32(0x00800000)), 3843 getDSPControl())); 3844 3845 assign(t16, binop(Iop_And32, 3846 unop(Iop_64HIto32, 3847 mkexpr(t9)), 3848 mkU32(0x80000000))); 3849 putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32, 3850 mkexpr(t14), 3851 mkU32(0)), 3852 IRExpr_ITE(binop(Iop_CmpEQ32, 3853 mkexpr(t16), 3854 mkU32(0)), 3855 mkU32(0x7fffffff), 3856 mkU32(0x80000000)), 3857 unop(Iop_64to32, mkexpr(t9)))); 3858 break; 3859 } 3860 case 0x7: { /* EXTRV_RS.W */ 3861 DIP("extrv_rs.w r%d, ac%d, r%d", rt, ac, rs); 3862 vassert(!mode64); 3863 t0 = newTemp(Ity_I64); 3864 t1 = newTemp(Ity_I64); 3865 t2 = newTemp(Ity_I32); 3866 t3 = newTemp(Ity_I1); 3867 t4 = newTemp(Ity_I1); 3868 t5 = newTemp(Ity_I1); 3869 t6 = newTemp(Ity_I1); 3870 t7 = newTemp(Ity_I32); 3871 t8 = newTemp(Ity_I64); 3872 t9 = newTemp(Ity_I64); 3873 t10 = newTemp(Ity_I1); 3874 t11 = newTemp(Ity_I1); 3875 t12 = newTemp(Ity_I1); 3876 t13 = newTemp(Ity_I1); 3877 t14 = newTemp(Ity_I32); 3878 t15 = newTemp(Ity_I32); 3879 t16 = newTemp(Ity_I32); 3880 t17 = newTemp(Ity_I1); 3881 3882 assign(t15, binop(Iop_And32, 3883 getIReg(rs), 3884 mkU32(0x1f))); 3885 assign(t17, binop(Iop_CmpEQ32, 3886 mkexpr(t15), 3887 mkU32(0))); 3888 assign(t0, getAcc(ac)); 3889 assign(t1, IRExpr_ITE(mkexpr(t17), 3890 mkexpr(t0), 3891 binop(Iop_Sar64, 3892 mkexpr(t0), 3893 unop(Iop_32to8, 3894 mkexpr(t15))))); 3895 3896 /* Check if bits 63..31 of the result in t1 aren't 0. */ 3897 assign(t3, binop(Iop_CmpNE32, 3898 unop(Iop_64HIto32, 3899 mkexpr(t1)), 3900 mkU32(0))); 3901 assign(t4, binop(Iop_CmpNE32, 3902 binop(Iop_And32, 3903 unop(Iop_64to32, 3904 mkexpr(t1)), 3905 mkU32(0x80000000)), 3906 mkU32(0))); 3907 /* Check if bits 63..31 of the result in t1 aren't 3908 0x1ffffffff. */ 3909 assign(t5, binop(Iop_CmpNE32, 3910 unop(Iop_64HIto32, 3911 mkexpr(t1)), 3912 mkU32(0xffffffff))); 3913 assign(t6, binop(Iop_CmpNE32, 3914 binop(Iop_And32, 3915 unop(Iop_64to32, 3916 mkexpr(t1)), 3917 mkU32(0x80000000)), 3918 mkU32(0x80000000))); 3919 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP 3920 control register. */ 3921 assign(t7, binop(Iop_And32, 3922 binop(Iop_Or32, 3923 unop(Iop_1Sto32, mkexpr(t3)), 3924 unop(Iop_1Sto32, mkexpr(t4))), 3925 binop(Iop_Or32, 3926 unop(Iop_1Sto32, mkexpr(t5)), 3927 unop(Iop_1Sto32, mkexpr(t6))))); 3928 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3929 mkexpr(t7), 3930 mkU32(0)), 3931 binop(Iop_Or32, 3932 getDSPControl(), 3933 mkU32(0x00800000)), 3934 getDSPControl())); 3935 3936 /* If the last discarded bit is 1, there would be carry 3937 when rounding, otherwise there wouldn't. We use that 3938 fact and just add the value of the last discarded bit 3939 to the least sifgnificant bit of the shifted value 3940 from acc. */ 3941 assign(t8, 3942 IRExpr_ITE(mkexpr(t17), 3943 mkU64(0x0ULL), 3944 binop(Iop_And64, 3945 binop(Iop_Shr64, 3946 mkexpr(t0), 3947 unop(Iop_32to8, 3948 binop(Iop_Sub32, 3949 mkexpr(t15), 3950 mkU32(1)))), 3951 mkU64(0x1ULL)))); 3952 3953 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8))); 3954 3955 /* Repeat previous steps for the rounded value. */ 3956 assign(t10, binop(Iop_CmpNE32, 3957 unop(Iop_64HIto32, 3958 mkexpr(t9)), 3959 mkU32(0))); 3960 assign(t11, binop(Iop_CmpNE32, 3961 binop(Iop_And32, 3962 unop(Iop_64to32, 3963 mkexpr(t9)), 3964 mkU32(0x80000000)), 3965 mkU32(0))); 3966 3967 assign(t12, binop(Iop_CmpNE32, 3968 unop(Iop_64HIto32, 3969 mkexpr(t9)), 3970 mkU32(0xffffffff))); 3971 assign(t13, binop(Iop_CmpNE32, 3972 binop(Iop_And32, 3973 unop(Iop_64to32, 3974 mkexpr(t9)), 3975 mkU32(0x80000000)), 3976 mkU32(0x80000000))); 3977 3978 assign(t14, binop(Iop_And32, 3979 binop(Iop_Or32, 3980 unop(Iop_1Sto32, mkexpr(t10)), 3981 unop(Iop_1Sto32, mkexpr(t11))), 3982 binop(Iop_Or32, 3983 unop(Iop_1Sto32, mkexpr(t12)), 3984 unop(Iop_1Sto32, mkexpr(t13))))); 3985 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3986 mkexpr(t14), 3987 mkU32(0)), 3988 binop(Iop_Or32, 3989 getDSPControl(), 3990 mkU32(0x00800000)), 3991 getDSPControl())); 3992 3993 assign(t16, binop(Iop_And32, 3994 unop(Iop_64HIto32, 3995 mkexpr(t9)), 3996 mkU32(0x80000000))); 3997 putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32, 3998 mkexpr(t14), 3999 mkU32(0)), 4000 IRExpr_ITE(binop(Iop_CmpEQ32, 4001 mkexpr(t16), 4002 mkU32(0)), 4003 mkU32(0x7fffffff), 4004 mkU32(0x80000000)), 4005 unop(Iop_64to32, mkexpr(t9)))); 4006 break; 4007 } 4008 case 0xA: { /* EXTPDP */ 4009 DIP("extpdp r%d, ac%d, %d", rt, ac, rs); 4010 vassert(!mode64); 4011 t0 = newTemp(Ity_I64); 4012 t1 = newTemp(Ity_I32); 4013 t2 = newTemp(Ity_I1); 4014 t3 = newTemp(Ity_I1); 4015 t4 = newTemp(Ity_I8); 4016 t5 = newTemp(Ity_I64); 4017 t6 = newTemp(Ity_I64); 4018 t7 = newTemp(Ity_I32); 4019 t8 = newTemp(Ity_I32); 4020 4021 assign(t0, getAcc(ac)); 4022 /* Extract pos field of DSPControl register. */ 4023 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f))); 4024 4025 /* Check if (pos - size) >= 0 [size <= pos] 4026 if (pos < size) 4027 put 1 to EFI field of DSPControl register 4028 else 4029 extract bits from acc and put 0 to EFI field of 4030 DSPCtrl */ 4031 assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs))); 4032 4033 assign(t8, binop(Iop_Or32, 4034 binop(Iop_And32, 4035 getDSPControl(), 4036 mkU32(0xffffbfc0)), 4037 binop(Iop_And32, 4038 binop(Iop_Sub32, 4039 binop(Iop_And32, 4040 getDSPControl(), 4041 mkU32(0x3f)), 4042 mkU32(rs+1)), 4043 mkU32(0x3f)))); 4044 putDSPControl(IRExpr_ITE(mkexpr(t2), 4045 binop(Iop_Or32, 4046 binop(Iop_And32, 4047 getDSPControl(), 4048 mkU32(0xffffbfff)), 4049 mkU32(0x4000)), 4050 mkexpr(t8))); 4051 4052 /* If pos <= 31, shift right the value from the acc 4053 (pos-size) times and take (size+1) bits from the least 4054 significant positions. Otherwise, shift left the value 4055 (63-pos) times, take (size+1) bits from the most 4056 significant positions and shift right (31-size) times. 4057 */ 4058 assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31))); 4059 4060 assign(t4, 4061 IRExpr_ITE(mkexpr(t3), 4062 unop(Iop_32to8, 4063 binop(Iop_Sub32, 4064 mkexpr(t1), mkU32(rs))), 4065 unop(Iop_32to8, 4066 binop(Iop_Sub32, 4067 mkU32(63), mkexpr(t1))))); 4068 4069 assign(t5, IRExpr_ITE(mkexpr(t3), 4070 binop(Iop_Shr64, 4071 mkexpr(t0), mkexpr(t4)), 4072 binop(Iop_Shl64, 4073 mkexpr(t0), mkexpr(t4)))); 4074 4075 /* t6 holds a mask for bit extraction. */ 4076 assign(t6, 4077 IRExpr_ITE(mkexpr(t3), 4078 unop(Iop_Not64, 4079 binop(Iop_Shl64, 4080 mkU64(0xffffffffffffffffULL), 4081 mkU8(rs+1))), 4082 unop(Iop_Not64, 4083 binop(Iop_Shr64, 4084 mkU64(0xffffffffffffffffULL), 4085 mkU8(rs+1))))); 4086 4087 assign(t7, IRExpr_ITE(mkexpr(t3), 4088 unop(Iop_64to32, 4089 binop(Iop_And64, 4090 mkexpr(t5), 4091 mkexpr(t6))), 4092 binop(Iop_Shr32, 4093 unop(Iop_64HIto32, 4094 binop(Iop_And64, 4095 mkexpr(t5), 4096 mkexpr(t6))), 4097 mkU8(31-rs)))); 4098 4099 putIReg(rt, mkexpr(t7)); 4100 break; 4101 } 4102 case 0xB: { /* EXTPDPV */ 4103 DIP("extpdpv r%d, ac%d, r%d", rt, ac, rs); 4104 vassert(!mode64); 4105 t0 = newTemp(Ity_I64); 4106 t1 = newTemp(Ity_I32); 4107 t2 = newTemp(Ity_I1); 4108 t3 = newTemp(Ity_I1); 4109 t4 = newTemp(Ity_I8); 4110 t5 = newTemp(Ity_I64); 4111 t6 = newTemp(Ity_I64); 4112 t7 = newTemp(Ity_I32); 4113 t8 = newTemp(Ity_I32); 4114 t9 = newTemp(Ity_I32); 4115 4116 assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f))); 4117 assign(t0, getAcc(ac)); 4118 /* Extract pos field of DSPControl register. */ 4119 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f))); 4120 4121 /* Check if (pos - size) >= 0 [size <= pos] 4122 if (pos < size) 4123 put 1 to EFI field of DSPControl register 4124 else 4125 extract bits from acc and put 0 to EFI field of 4126 DSPCtrl */ 4127 assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8))); 4128 4129 assign(t9, binop(Iop_Or32, 4130 binop(Iop_And32, 4131 getDSPControl(), 4132 mkU32(0xffffbfc0)), 4133 binop(Iop_And32, 4134 binop(Iop_Sub32, 4135 binop(Iop_And32, 4136 getDSPControl(), 4137 mkU32(0x3f)), 4138 binop(Iop_Add32, 4139 mkexpr(t8), 4140 mkU32(0x1))), 4141 mkU32(0x3f)))); 4142 putDSPControl(IRExpr_ITE(mkexpr(t2), 4143 binop(Iop_Or32, 4144 binop(Iop_And32, 4145 getDSPControl(), 4146 mkU32(0xffffbfff)), 4147 mkU32(0x4000)), 4148 mkexpr(t9))); 4149 4150 /* If pos <= 31, shift right the value from the acc 4151 (pos-size) times and take (size+1) bits from the least 4152 significant positions. Otherwise, shift left the value 4153 (63-pos) times, take (size+1) bits from the most 4154 significant positions and shift right (31-size) times. 4155 */ 4156 assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31))); 4157 4158 assign(t4, 4159 IRExpr_ITE(mkexpr(t3), 4160 unop(Iop_32to8, 4161 binop(Iop_Sub32, 4162 mkexpr(t1), mkexpr(t8))), 4163 unop(Iop_32to8, 4164 binop(Iop_Sub32, 4165 mkU32(63), mkexpr(t1))))); 4166 4167 assign(t5, IRExpr_ITE(mkexpr(t3), 4168 binop(Iop_Shr64, 4169 mkexpr(t0), mkexpr(t4)), 4170 binop(Iop_Shl64, 4171 mkexpr(t0), mkexpr(t4)))); 4172 4173 /* t6 holds a mask for bit extraction. */ 4174 assign(t6, 4175 IRExpr_ITE(mkexpr(t3), 4176 unop(Iop_Not64, 4177 binop(Iop_Shl64, 4178 mkU64(0xffffffffffffffffULL), 4179 unop(Iop_32to8, 4180 binop(Iop_Add32, 4181 mkexpr(t8), 4182 mkU32(1))))), 4183 unop(Iop_Not64, 4184 binop(Iop_Shr64, 4185 mkU64(0xffffffffffffffffULL), 4186 unop(Iop_32to8, 4187 binop(Iop_Add32, 4188 mkexpr(t8), 4189 mkU32(1))))))); 4190 4191 assign(t7, IRExpr_ITE(mkexpr(t3), 4192 unop(Iop_64to32, 4193 binop(Iop_And64, 4194 mkexpr(t5), 4195 mkexpr(t6))), 4196 binop(Iop_Shr32, 4197 unop(Iop_64HIto32, 4198 binop(Iop_And64, 4199 mkexpr(t5), 4200 mkexpr(t6))), 4201 unop(Iop_32to8, 4202 binop(Iop_Sub32, 4203 mkU32(31), 4204 mkexpr(t8)))))); 4205 4206 putIReg(rt, mkexpr(t7)); 4207 break; 4208 } 4209 case 0xE: { /* EXTR_S.H */ 4210 DIP("extr_s.h r%d, ac%d, %d", rt, ac, rs); 4211 vassert(!mode64); 4212 t0 = newTemp(Ity_I64); 4213 t1 = newTemp(Ity_I64); 4214 t2 = newTemp(Ity_I32); 4215 t3 = newTemp(Ity_I64); 4216 t4 = newTemp(Ity_I32); 4217 t5 = newTemp(Ity_I32); 4218 t6 = newTemp(Ity_I64); 4219 t7 = newTemp(Ity_I32); 4220 t9 = newTemp(Ity_I32); 4221 4222 assign(t0, getAcc(ac)); 4223 4224 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs))); 4225 4226 assign(t2, binop(Iop_Or32, 4227 getDSPControl(), mkU32(0x00800000))); 4228 4229 assign(t9, binop(Iop_And32, 4230 unop(Iop_64to32, 4231 mkexpr(t1)), 4232 mkU32(0x80000000))); 4233 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4234 mkexpr(t9), 4235 binop(Iop_And32, 4236 unop(Iop_64HIto32, 4237 mkexpr(t0)), 4238 mkU32(0x80000000))), 4239 mkexpr(t2), 4240 getDSPControl())); 4241 4242 /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0) 4243 1. subtract 0x7fff from t1 4244 2. if the resulting number is positive (sign bit = 0) 4245 and any of the other bits is 1, the value is > 0. */ 4246 assign(t3, binop(Iop_Sub64, 4247 mkexpr(t1), 4248 mkU64(0x0000000000007fffULL))); 4249 assign(t4, binop(Iop_And32, 4250 binop(Iop_Or32, 4251 unop(Iop_1Sto32, 4252 binop(Iop_CmpNE32, 4253 mkU32(0), 4254 binop(Iop_And32, 4255 unop(Iop_64HIto32, 4256 mkexpr(t3)), 4257 mkU32(0x7fffffff)))), 4258 unop(Iop_1Sto32, 4259 binop(Iop_CmpNE32, 4260 mkU32(0), 4261 unop(Iop_64to32, 4262 mkexpr(t3))))), 4263 unop(Iop_1Sto32, 4264 binop(Iop_CmpEQ32, 4265 binop(Iop_And32, 4266 unop(Iop_64HIto32, 4267 mkexpr(t3)), 4268 mkU32(0x80000000)), 4269 mkU32(0))))); 4270 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4271 mkU32(0), 4272 mkexpr(t4)), 4273 binop(Iop_Or32, 4274 getDSPControl(), 4275 mkU32(0x00800000)), 4276 getDSPControl())); 4277 /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0 4278 1. subtract t1 from 0xffffffffffff8000 4279 2. if the resulting number is positive (sign bit = 0) 4280 and any of the other bits is 1, the value is > 0 */ 4281 assign(t6, binop(Iop_Sub64, 4282 mkU64(0xffffffffffff8000ULL), 4283 mkexpr(t1))); 4284 assign(t7, binop(Iop_And32, 4285 binop(Iop_Or32, 4286 unop(Iop_1Sto32, 4287 binop(Iop_CmpNE32, 4288 mkU32(0), 4289 binop(Iop_And32, 4290 unop(Iop_64HIto32, 4291 mkexpr(t6)), 4292 mkU32(0x7fffffff)))), 4293 unop(Iop_1Sto32, 4294 binop(Iop_CmpNE32, 4295 mkU32(0), 4296 unop(Iop_64to32, 4297 mkexpr(t6))))), 4298 unop(Iop_1Sto32, 4299 binop(Iop_CmpEQ32, 4300 binop(Iop_And32, 4301 unop(Iop_64HIto32, 4302 mkexpr(t6)), 4303 mkU32(0x80000000)), 4304 mkU32(0))))); 4305 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4306 mkU32(0), 4307 mkexpr(t7)), 4308 binop(Iop_Or32, 4309 getDSPControl(), 4310 mkU32(0x00800000)), 4311 getDSPControl())); 4312 putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32, 4313 mkU32(0), 4314 mkexpr(t4)), 4315 mkU32(0x00007fff), 4316 IRExpr_ITE(binop(Iop_CmpNE32, 4317 mkU32(0), 4318 mkexpr(t7)), 4319 mkU32(0xffff8000), 4320 unop(Iop_64to32, 4321 mkexpr(t1))))); 4322 break; 4323 } 4324 case 0xF: { /* EXTRV_S.H */ 4325 DIP("extrv_s.h r%d, ac%d, %d", rt, ac, rs); 4326 vassert(!mode64); 4327 t0 = newTemp(Ity_I64); 4328 t1 = newTemp(Ity_I64); 4329 t2 = newTemp(Ity_I32); 4330 t3 = newTemp(Ity_I64); 4331 t4 = newTemp(Ity_I32); 4332 t5 = newTemp(Ity_I32); 4333 t6 = newTemp(Ity_I64); 4334 t7 = newTemp(Ity_I32); 4335 t9 = newTemp(Ity_I32); 4336 4337 assign(t0, getAcc(ac)); 4338 4339 assign(t1, binop(Iop_Sar64, 4340 mkexpr(t0), 4341 unop(Iop_32to8, 4342 binop(Iop_And32, 4343 getIReg(rs), 4344 mkU32(0x1f))))); 4345 4346 assign(t2, binop(Iop_Or32, 4347 getDSPControl(), mkU32(0x00800000))); 4348 4349 assign(t9, binop(Iop_And32, 4350 unop(Iop_64to32, 4351 mkexpr(t1)), 4352 mkU32(0x80000000))); 4353 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4354 mkexpr(t9), 4355 binop(Iop_And32, 4356 unop(Iop_64HIto32, 4357 mkexpr(t0)), 4358 mkU32(0x80000000))), 4359 mkexpr(t2), 4360 getDSPControl())); 4361 4362 /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0) 4363 1. subtract 0x7fff from t1 4364 2. if the resulting number is positive (sign bit = 0) 4365 and any of the other bits is 1, the value is > 0. */ 4366 assign(t3, binop(Iop_Sub64, 4367 mkexpr(t1), 4368 mkU64(0x0000000000007fffULL))); 4369 assign(t4, binop(Iop_And32, 4370 binop(Iop_Or32, 4371 unop(Iop_1Sto32, 4372 binop(Iop_CmpNE32, 4373 mkU32(0), 4374 binop(Iop_And32, 4375 unop(Iop_64HIto32, 4376 mkexpr(t3)), 4377 mkU32(0x7fffffff)))), 4378 unop(Iop_1Sto32, 4379 binop(Iop_CmpNE32, 4380 mkU32(0), 4381 unop(Iop_64to32, 4382 mkexpr(t3))))), 4383 unop(Iop_1Sto32, 4384 binop(Iop_CmpEQ32, 4385 binop(Iop_And32, 4386 unop(Iop_64HIto32, 4387 mkexpr(t3)), 4388 mkU32(0x80000000)), 4389 mkU32(0))))); 4390 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4391 mkU32(0), 4392 mkexpr(t4)), 4393 binop(Iop_Or32, 4394 getDSPControl(), 4395 mkU32(0x00800000)), 4396 getDSPControl())); 4397 /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0 4398 1. subtract t1 from 0xffffffffffff8000 4399 2. if the resulting number is positive (sign bit = 0) 4400 and any of the other bits is 1, the value is > 0 */ 4401 assign(t6, binop(Iop_Sub64, 4402 mkU64(0xffffffffffff8000ULL), 4403 mkexpr(t1))); 4404 assign(t7, binop(Iop_And32, 4405 binop(Iop_Or32, 4406 unop(Iop_1Sto32, 4407 binop(Iop_CmpNE32, 4408 mkU32(0), 4409 binop(Iop_And32, 4410 unop(Iop_64HIto32, 4411 mkexpr(t6)), 4412 mkU32(0x7fffffff)))), 4413 unop(Iop_1Sto32, 4414 binop(Iop_CmpNE32, 4415 mkU32(0), 4416 unop(Iop_64to32, 4417 mkexpr(t6))))), 4418 unop(Iop_1Sto32, 4419 binop(Iop_CmpEQ32, 4420 binop(Iop_And32, 4421 unop(Iop_64HIto32, 4422 mkexpr(t6)), 4423 mkU32(0x80000000)), 4424 mkU32(0))))); 4425 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4426 mkU32(0), 4427 mkexpr(t7)), 4428 binop(Iop_Or32, 4429 getDSPControl(), 4430 mkU32(0x00800000)), 4431 getDSPControl())); 4432 putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32, 4433 mkU32(0), 4434 mkexpr(t4)), 4435 mkU32(0x00007fff), 4436 IRExpr_ITE(binop(Iop_CmpNE32, 4437 mkU32(0), 4438 mkexpr(t7)), 4439 mkU32(0xffff8000), 4440 unop(Iop_64to32, 4441 mkexpr(t1))))); 4442 break; 4443 } 4444 case 0x12: { /* RDDSP*/ 4445 DIP("rddsp r%d, mask 0x%x", rd, rddsp_mask); 4446 vassert(!mode64); 4447 4448 putIReg(rd, mkU32(0x0)); 4449 4450 if ((rddsp_mask & 0x1) == 0x1) { 4451 /* Read pos field (bits 5-0) of DSPControl register. */ 4452 putIReg(rd, binop(Iop_Or32, 4453 getIReg(rd), 4454 binop(Iop_And32, 4455 getDSPControl(), 4456 mkU32(0x0000003F)))); 4457 } 4458 4459 if ((rddsp_mask & 0x2) == 0x2) { 4460 /* Read scount field (bits 12-7) of DSPControl 4461 register. */ 4462 putIReg(rd, binop(Iop_Or32, 4463 getIReg(rd), 4464 binop(Iop_And32, 4465 getDSPControl(), 4466 mkU32(0x00001F80)))); 4467 } 4468 4469 if ((rddsp_mask & 0x4) == 0x4) { 4470 /* Read C field (bit 13) of DSPControl register. */ 4471 putIReg(rd, binop(Iop_Or32, 4472 getIReg(rd), 4473 binop(Iop_And32, 4474 getDSPControl(), 4475 mkU32(0x00002000)))); 4476 } 4477 4478 if ((rddsp_mask & 0x8) == 0x8) { 4479 /* Read outflag field (bit s 23-16) of DSPControl 4480 register. */ 4481 putIReg(rd, binop(Iop_Or32, 4482 getIReg(rd), 4483 binop(Iop_And32, 4484 getDSPControl(), 4485 mkU32(0x00FF0000)))); 4486 } 4487 4488 if ((rddsp_mask & 0x10) == 0x10) { 4489 /* Read ccond field (bits 31-24) of DSPControl 4490 register. */ 4491 putIReg(rd, binop(Iop_Or32, 4492 getIReg(rd), 4493 binop(Iop_And32, 4494 getDSPControl(), 4495 mkU32(0xFF000000)))); 4496 } 4497 4498 if ((rddsp_mask & 0x20) == 0x20) { 4499 /* Read EFI field (bit 14) of DSPControl register. */ 4500 putIReg(rd, binop(Iop_Or32, 4501 getIReg(rd), 4502 binop(Iop_And32, 4503 getDSPControl(), 4504 mkU32(0x00004000)))); 4505 } 4506 4507 if ((rddsp_mask & 0x3f) == 0x3f) { 4508 /* Read all fields of DSPControl register. */ 4509 putIReg(rd, getDSPControl()); 4510 } 4511 break; 4512 } 4513 case 0x13: { /* WRDSP */ 4514 DIP("wrdsp r%d, mask 0x%x", rs, wrdsp_mask); 4515 vassert(!mode64); 4516 4517 if ((wrdsp_mask & 0x3f) == 0x3f) { 4518 /* If mips64 put all fields of rs, except bit 15 and bit 4519 6, to DSPControl register, otherwise put all except 4520 bits 15, 6 and bits 31..28. */ 4521 putDSPControl(mode64 ? 4522 binop(Iop_And32, 4523 getIReg(rs), 4524 mkU32(0xffff7fbf)) : 4525 binop(Iop_And32, 4526 getIReg(rs), 4527 mkU32(0x0fff7fbf))); 4528 } else { 4529 if ((wrdsp_mask & 0x1) == 0x1) { 4530 /* Put bits 5-0 of rs to DSPControl register pos 4531 field. */ 4532 putDSPControl(binop(Iop_Or32, 4533 binop(Iop_And32, 4534 getDSPControl(), 4535 mkU32(0xFFFF7F40)), 4536 binop(Iop_And32, 4537 getIReg(rs), 4538 mkU32(0x0000003F)))); 4539 } 4540 4541 if ((wrdsp_mask & 0x2) == 0x2) { 4542 /* Put bits 12-7 of rs to DSPControl scount field. */ 4543 putDSPControl(binop(Iop_Or32, 4544 binop(Iop_And32, 4545 getDSPControl(), 4546 mkU32(0xFFFFE03F)), 4547 binop(Iop_And32, 4548 getIReg(rs), 4549 mkU32(0x00001F80)))); 4550 } 4551 4552 if ((wrdsp_mask & 0x4) == 0x4) { 4553 /* Put bit 13 of rs to DSPControl register C 4554 field. */ 4555 putDSPControl(binop(Iop_Or32, 4556 binop(Iop_And32, 4557 getDSPControl(), 4558 mkU32(0xFFFF5FBF)), 4559 binop(Iop_And32, 4560 getIReg(rs), 4561 mkU32(0x00002000)))); 4562 } 4563 4564 if ((wrdsp_mask & 0x8) == 0x8) { 4565 /* Put bits 23-16 of rs to DSPControl reg outflag 4566 field. */ 4567 putDSPControl(binop(Iop_Or32, 4568 binop(Iop_And32, 4569 getDSPControl(), 4570 mkU32(0xFF007FBF)), 4571 binop(Iop_And32, 4572 getIReg(rs), 4573 mkU32(0x00FF0000)))); 4574 } 4575 4576 if ((wrdsp_mask & 0x10) == 0x10) { 4577 /* Put bits 31-24 of rs to DSPControl reg ccond 4578 field. */ 4579 putDSPControl(binop(Iop_Or32, 4580 binop(Iop_And32, 4581 getDSPControl(), 4582 mkU32(0x00FF7FBF)), 4583 binop(Iop_And32, 4584 getIReg(rs), 4585 mode64 ? mkU32(0xFF000000) 4586 : mkU32(0x0F000000)) 4587 ) 4588 ); 4589 } 4590 4591 if ((wrdsp_mask & 0x20) == 0x20) { 4592 /* Put bit 14 of rs to DSPControl register EFI 4593 field. */ 4594 putDSPControl(binop(Iop_Or32, 4595 binop(Iop_And32, 4596 getDSPControl(), 4597 mkU32(0xFFFF3FBF)), 4598 binop(Iop_And32, 4599 getIReg(rs), 4600 mkU32(0x00004000)))); 4601 } 4602 } 4603 break; 4604 } 4605 case 0x1A: { /* SHILO */ 4606 DIP("shilo ac%d, %d", ac, shift); 4607 vassert(!mode64); 4608 t0 = newTemp(Ity_I64); 4609 t1 = newTemp(Ity_I64); 4610 4611 assign(t0, getAcc(ac)); 4612 4613 putAcc(ac, mkexpr(t0)); 4614 4615 if (0x20 == (shift & 0x3f)) { 4616 putAcc(ac, binop(Iop_32HLto64, 4617 unop(Iop_64to32, mkexpr(t0)), 4618 mkU32(0x0))); 4619 } else if (0x20 == (shift & 0x20)) { 4620 assign(t1, binop(Iop_Shl64, 4621 mkexpr(t0), 4622 unop(Iop_32to8, 4623 binop(Iop_Add32, 4624 unop(Iop_Not32, 4625 mkU32(shift)), 4626 mkU32(0x1))))); 4627 4628 putAcc(ac, mkexpr(t1)); 4629 } else { 4630 assign(t1, binop(Iop_Shr64, mkexpr(t0), mkU8(shift))); 4631 4632 putAcc(ac, mkexpr(t1)); 4633 } 4634 break; 4635 } 4636 case 0x1B: { /* SHILOV */ 4637 DIP("shilov ac%d, r%d", ac, rs); 4638 vassert(!mode64); 4639 t0 = newTemp(Ity_I64); 4640 t1 = newTemp(Ity_I32); 4641 t2 = newTemp(Ity_I1); 4642 t3 = newTemp(Ity_I64); 4643 t4 = newTemp(Ity_I64); 4644 4645 assign(t0, getAcc(ac)); 4646 assign(t1, binop(Iop_And32, getIReg(rs), mkU32(0x3f))); 4647 assign(t2, binop(Iop_CmpEQ32, mkexpr(t1), mkU32(0x20))); 4648 assign(t3, binop(Iop_Shl64, 4649 mkexpr(t0), 4650 unop(Iop_32to8, 4651 binop(Iop_Add32, 4652 unop(Iop_Not32, 4653 mkexpr(t1)), 4654 mkU32(0x1))))); 4655 assign(t4, binop(Iop_Shr64, 4656 mkexpr(t0), 4657 unop(Iop_32to8, 4658 mkexpr(t1)))); 4659 4660 putAcc(ac, 4661 IRExpr_ITE(mkexpr(t2), 4662 binop(Iop_32HLto64, 4663 unop(Iop_64to32, mkexpr(t0)), 4664 mkU32(0x0)), 4665 IRExpr_ITE(binop(Iop_CmpEQ32, 4666 binop(Iop_And32, 4667 mkexpr(t1), 4668 mkU32(0x20)), 4669 mkU32(0x20)), 4670 mkexpr(t3), 4671 mkexpr(t4)))); 4672 break; 4673 } 4674 case 0x1F: { /* MTHLIP */ 4675 DIP("mthlip r%d, ac%d", rs, ac); 4676 vassert(!mode64); 4677 t0 = newTemp(Ity_I64); 4678 t1 = newTemp(Ity_I32); 4679 t2 = newTemp(Ity_I32); 4680 t3 = newTemp(Ity_I1); 4681 4682 assign(t0, getAcc(ac)); 4683 putAcc(ac, binop(Iop_32HLto64, 4684 unop(Iop_64to32, mkexpr(t0)), 4685 getIReg(rs))); 4686 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f))); 4687 putDSPControl(IRExpr_ITE(binop(Iop_CmpLE32U, 4688 mkU32(32), 4689 mkexpr(t1)), 4690 binop(Iop_Or32, 4691 binop(Iop_Sub32, 4692 mkexpr(t1), 4693 mkU32(32)), 4694 binop(Iop_And32, 4695 getDSPControl(), 4696 mkU32(0xffffffc0))), 4697 binop(Iop_Or32, 4698 binop(Iop_Add32, 4699 mkexpr(t1), 4700 mkU32(32)), 4701 binop(Iop_And32, 4702 getDSPControl(), 4703 mkU32(0xffffffc0))))); 4704 break; 4705 } 4706 default: 4707 return -1; 4708 } 4709 break; /* end of EXTR.W */ 4710 } 4711 case 0xA: { /* LX */ 4712 switch(sa) { 4713 case 0x0: { /* LWX */ 4714 DIP("lwx r%d, r%d(r%d)", rd, rt, rs); 4715 vassert(!mode64); 4716 t0 = newTemp(Ity_I32); 4717 4718 assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs))); 4719 4720 putIReg(rd, load(Ity_I32, mkexpr(t0))); 4721 break; 4722 } 4723 case 0x4: { /* LHX */ 4724 DIP("lhx r%d, r%d(r%d)", rd, rt, rs); 4725 vassert(!mode64); 4726 t0 = newTemp(Ity_I32); 4727 4728 assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs))); 4729 4730 putIReg(rd, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t0)))); 4731 break; 4732 } 4733 case 0x6: { /* LBUX */ 4734 DIP("lbux r%d, r%d(r%d)", rd, rt, rs); 4735 vassert(!mode64); 4736 t0 = newTemp(Ity_I32); 4737 4738 assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs))); 4739 4740 putIReg(rd, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t0)))); 4741 break; 4742 } 4743 default: 4744 return -1; 4745 } 4746 break; /* end of LX */ 4747 } 4748 case 0xC: { /* INSV */ 4749 switch(sa) { 4750 case 0x0: { /* INSV */ 4751 DIP("insv r%d, r%d", rt, rs); 4752 vassert(!mode64); 4753 4754 t0 = newTemp(Ity_I32); 4755 t1 = newTemp(Ity_I32); 4756 t2 = newTemp(Ity_I8); 4757 t3 = newTemp(Ity_I8); 4758 t4 = newTemp(Ity_I32); 4759 t5 = newTemp(Ity_I1); 4760 t6 = newTemp(Ity_I32); 4761 t7 = newTemp(Ity_I32); 4762 t8 = newTemp(Ity_I32); 4763 t9 = newTemp(Ity_I32); 4764 4765 /* t0 <- pos field of DSPControl register. */ 4766 assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f))); 4767 /* t1 <- scount field of DSPControl register. */ 4768 assign(t1, binop(Iop_Shr32, 4769 binop(Iop_And32, 4770 getDSPControl(), 4771 mkU32(0x1f80)), 4772 mkU8(7))); 4773 4774 assign(t2, unop(Iop_32to8, 4775 binop(Iop_Add32, 4776 mkexpr(t1), 4777 mkexpr(t0)))); 4778 4779 /* 32-(pos+size) most significant bits of rt. */ 4780 assign(t6, binop(Iop_Shl32, 4781 binop(Iop_Shr32, 4782 getIReg(rt), 4783 mkexpr(t2)), 4784 mkexpr(t2))); 4785 4786 assign(t3, unop(Iop_32to8, 4787 binop(Iop_Sub32, 4788 mkU32(32), 4789 mkexpr(t0)))); 4790 /* Pos least significant bits of rt. */ 4791 assign(t7, binop(Iop_Shr32, 4792 binop(Iop_Shl32, 4793 getIReg(rt), 4794 mkexpr(t3)), 4795 mkexpr(t3))); 4796 4797 /* Size least significant bits of rs, 4798 shifted to appropriate position. */ 4799 assign(t8, binop(Iop_Shl32, 4800 binop(Iop_And32, 4801 getIReg(rs), 4802 unop(Iop_Not32, 4803 binop(Iop_Shl32, 4804 mkU32(0xffffffff), 4805 unop(Iop_32to8, 4806 mkexpr(t1))))), 4807 unop(Iop_32to8, 4808 mkexpr(t0)))); 4809 4810 putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32, 4811 mkexpr(t0), 4812 mkU32(0)), 4813 IRExpr_ITE(binop(Iop_CmpEQ32, 4814 mkexpr(t1), 4815 mkU32(32)), 4816 getIReg(rs), 4817 binop(Iop_Or32, 4818 mkexpr(t6), 4819 mkexpr(t8))), 4820 IRExpr_ITE(binop(Iop_CmpEQ32, 4821 unop(Iop_8Uto32, 4822 mkexpr(t2)), 4823 mkU32(32)), 4824 binop(Iop_Or32, 4825 mkexpr(t7), 4826 mkexpr(t8)), 4827 binop(Iop_Or32, 4828 binop(Iop_Or32, 4829 mkexpr(t6), 4830 mkexpr(t7)), 4831 mkexpr(t8))))); 4832 break; 4833 } 4834 default: 4835 return -1; 4836 } 4837 break; /* enf of INSV */ 4838 } 4839 case 0x10: { /* ADDU.QB */ 4840 switch(sa) { 4841 case 0x00: { /* ADDU.QB */ 4842 DIP("addu.qb r%d, r%d, r%d", rd, rs, rt); 4843 vassert(!mode64); 4844 t0 = newTemp(Ity_I32); 4845 t1 = newTemp(Ity_I1); 4846 t2 = newTemp(Ity_I32); 4847 t3 = newTemp(Ity_I1); 4848 t4 = newTemp(Ity_I32); 4849 t5 = newTemp(Ity_I1); 4850 t6 = newTemp(Ity_I32); 4851 t7 = newTemp(Ity_I1); 4852 t8 = newTemp(Ity_I32); 4853 4854 /* Add rightmost bytes of rs and rt. */ 4855 assign(t0, 4856 binop(Iop_Add32, 4857 unop(Iop_8Uto32, 4858 unop(Iop_16to8, 4859 unop(Iop_32to16, getIReg(rs)))), 4860 unop(Iop_8Uto32, 4861 unop(Iop_16to8, 4862 unop(Iop_32to16, getIReg(rt)))))); 4863 /* t1 will be 1 if there is overflow, 0 otherwise. */ 4864 assign(t1, binop(Iop_CmpEQ32, 4865 binop(Iop_And32, 4866 mkexpr(t0), 4867 mkU32(0x00000100)), 4868 mkU32(0x00000100))); 4869 4870 /* Add bits 15-8 of rs and rt. */ 4871 assign(t2, 4872 binop(Iop_Add32, 4873 unop(Iop_8Uto32, 4874 unop(Iop_16HIto8, 4875 unop(Iop_32to16, getIReg(rs)))), 4876 unop(Iop_8Uto32, 4877 unop(Iop_16HIto8, 4878 unop(Iop_32to16, getIReg(rt)))))); 4879 /* t3 will be 1 if there is overflow, 0 otherwise. */ 4880 assign(t3, binop(Iop_CmpEQ32, 4881 binop(Iop_And32, 4882 mkexpr(t2), 4883 mkU32(0x00000100)), 4884 mkU32(0x00000100))); 4885 4886 /* Add bits 15-8 of rs and rt. */ 4887 assign(t4, 4888 binop(Iop_Add32, 4889 unop(Iop_8Uto32, 4890 unop(Iop_16to8, 4891 unop(Iop_32HIto16, getIReg(rs)))), 4892 unop(Iop_8Uto32, 4893 unop(Iop_16to8, 4894 unop(Iop_32HIto16, getIReg(rt)))))); 4895 /* t5 will be 1 if there is overflow, 0 otherwise. */ 4896 assign(t5, binop(Iop_CmpEQ32, 4897 binop(Iop_And32, 4898 mkexpr(t4), 4899 mkU32(0x00000100)), 4900 mkU32(0x00000100))); 4901 4902 /* Add bits 15-8 of rs and rt. */ 4903 assign(t6, 4904 binop(Iop_Add32, 4905 unop(Iop_8Uto32, 4906 unop(Iop_16HIto8, 4907 unop(Iop_32HIto16, getIReg(rs)))), 4908 unop(Iop_8Uto32, 4909 unop(Iop_16HIto8, 4910 unop(Iop_32HIto16, getIReg(rt)))))); 4911 /* t7 will be 1 if there is overflow, 0 otherwise. */ 4912 assign(t7, binop(Iop_CmpEQ32, 4913 binop(Iop_And32, 4914 mkexpr(t6), 4915 mkU32(0x00000100)), 4916 mkU32(0x00000100))); 4917 4918 assign(t8, 4919 binop(Iop_Or32, 4920 binop(Iop_Or32, 4921 binop(Iop_Or32, 4922 unop(Iop_1Sto32, mkexpr(t7)), 4923 unop(Iop_1Sto32, mkexpr(t5))), 4924 unop(Iop_1Sto32, mkexpr(t3))), 4925 unop(Iop_1Sto32, mkexpr(t1)))); 4926 4927 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 4928 mkexpr(t8), 4929 mkU32(0x0)), 4930 getDSPControl(), 4931 binop(Iop_Or32, 4932 getDSPControl(), 4933 mkU32(0x00100000)))); 4934 4935 putIReg(rd, binop(Iop_16HLto32, 4936 binop(Iop_8HLto16, 4937 unop(Iop_32to8, mkexpr(t6)), 4938 unop(Iop_32to8, mkexpr(t4))), 4939 binop(Iop_8HLto16, 4940 unop(Iop_32to8, mkexpr(t2)), 4941 unop(Iop_32to8, mkexpr(t0))))); 4942 break; 4943 } 4944 case 0x1: { /* SUBU.QB */ 4945 DIP("subu.qb r%d, r%d, r%d", rd, rs, rt); 4946 vassert(!mode64); 4947 t0 = newTemp(Ity_I32); 4948 t1 = newTemp(Ity_I1); 4949 t2 = newTemp(Ity_I32); 4950 t3 = newTemp(Ity_I1); 4951 t4 = newTemp(Ity_I32); 4952 t5 = newTemp(Ity_I1); 4953 t6 = newTemp(Ity_I32); 4954 t7 = newTemp(Ity_I1); 4955 t8 = newTemp(Ity_I32); 4956 4957 /* Subtract rightmost bytes of rs and rt. */ 4958 assign(t0, 4959 binop(Iop_Sub32, 4960 unop(Iop_8Uto32, 4961 unop(Iop_16to8, 4962 unop(Iop_32to16, getIReg(rs)))), 4963 unop(Iop_8Uto32, 4964 unop(Iop_16to8, 4965 unop(Iop_32to16, getIReg(rt)))))); 4966 /* t1 will be 1 if there is overflow, 0 otherwise. */ 4967 assign(t1, binop(Iop_CmpEQ32, 4968 binop(Iop_And32, 4969 mkexpr(t0), 4970 mkU32(0x00000100)), 4971 mkU32(0x00000100))); 4972 4973 /* Subtract bits 15-8 of rs and rt. */ 4974 assign(t2, 4975 binop(Iop_Sub32, 4976 unop(Iop_8Uto32, 4977 unop(Iop_16HIto8, 4978 unop(Iop_32to16, getIReg(rs)))), 4979 unop(Iop_8Uto32, 4980 unop(Iop_16HIto8, 4981 unop(Iop_32to16, getIReg(rt)))))); 4982 /* t3 will be 1 if there is overflow, 0 otherwise. */ 4983 assign(t3, binop(Iop_CmpEQ32, 4984 binop(Iop_And32, 4985 mkexpr(t2), 4986 mkU32(0x00000100)), 4987 mkU32(0x00000100))); 4988 4989 /* Subtract bits 15-8 of rs and rt. */ 4990 assign(t4, 4991 binop(Iop_Sub32, 4992 unop(Iop_8Uto32, 4993 unop(Iop_16to8, 4994 unop(Iop_32HIto16, getIReg(rs)))), 4995 unop(Iop_8Uto32, 4996 unop(Iop_16to8, 4997 unop(Iop_32HIto16, getIReg(rt)))))); 4998 /* t5 will be 1 if there is overflow, 0 otherwise. */ 4999 assign(t5, binop(Iop_CmpEQ32, 5000 binop(Iop_And32, 5001 mkexpr(t4), 5002 mkU32(0x00000100)), 5003 mkU32(0x00000100))); 5004 5005 /* Subtract bits 15-8 of rs and rt. */ 5006 assign(t6, 5007 binop(Iop_Sub32, 5008 unop(Iop_8Uto32, 5009 unop(Iop_16HIto8, 5010 unop(Iop_32HIto16, getIReg(rs)))), 5011 unop(Iop_8Uto32, 5012 unop(Iop_16HIto8, 5013 unop(Iop_32HIto16, getIReg(rt)))))); 5014 /* t7 will be 1 if there is overflow, 0 otherwise. */ 5015 assign(t7, binop(Iop_CmpEQ32, 5016 binop(Iop_And32, 5017 mkexpr(t6), 5018 mkU32(0x00000100)), 5019 mkU32(0x00000100))); 5020 5021 assign(t8, binop(Iop_Or32, 5022 binop(Iop_Or32, 5023 binop(Iop_Or32, 5024 unop(Iop_1Sto32, mkexpr(t7)), 5025 unop(Iop_1Sto32, mkexpr(t5))), 5026 unop(Iop_1Sto32, mkexpr(t3))), 5027 unop(Iop_1Sto32, mkexpr(t1)))); 5028 5029 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 5030 mkexpr(t8), 5031 mkU32(0x0)), 5032 getDSPControl(), 5033 binop(Iop_Or32, 5034 getDSPControl(), 5035 mkU32(0x00100000)))); 5036 5037 putIReg(rd, binop(Iop_16HLto32, 5038 binop(Iop_8HLto16, 5039 unop(Iop_32to8, mkexpr(t6)), 5040 unop(Iop_32to8, mkexpr(t4))), 5041 binop(Iop_8HLto16, 5042 unop(Iop_32to8, mkexpr(t2)), 5043 unop(Iop_32to8, mkexpr(t0))))); 5044 break; 5045 } 5046 case 0x04: { /* ADDU_S.QB */ 5047 DIP("addu_s.qb r%d, r%d, r%d", rd, rs, rt); 5048 vassert(!mode64); 5049 t0 = newTemp(Ity_I32); 5050 t1 = newTemp(Ity_I1); 5051 t2 = newTemp(Ity_I8); 5052 t3 = newTemp(Ity_I32); 5053 t4 = newTemp(Ity_I1); 5054 t5 = newTemp(Ity_I8); 5055 t6 = newTemp(Ity_I32); 5056 t7 = newTemp(Ity_I1); 5057 t8 = newTemp(Ity_I8); 5058 t9 = newTemp(Ity_I32); 5059 t10 = newTemp(Ity_I1); 5060 t11 = newTemp(Ity_I8); 5061 t12 = newTemp(Ity_I32); 5062 5063 /* Add rightmost bytes of rs and rt. */ 5064 assign(t0, 5065 binop(Iop_Add32, 5066 unop(Iop_8Uto32, 5067 unop(Iop_16to8, 5068 unop(Iop_32to16, getIReg(rs)))), 5069 unop(Iop_8Uto32, 5070 unop(Iop_16to8, 5071 unop(Iop_32to16, getIReg(rt)))))); 5072 /* t1 will be 1 if there is overflow, 0 otherwise. */ 5073 assign(t1, binop(Iop_CmpEQ32, 5074 binop(Iop_And32, 5075 mkexpr(t0), 5076 mkU32(0x00000100)), 5077 mkU32(0x00000100))); 5078 /* Saturate if necessary. */ 5079 assign(t2, IRExpr_ITE(mkexpr(t1), 5080 mkU8(0xff), 5081 unop(Iop_32to8, mkexpr(t0)))); 5082 5083 /* Add bits 15-8 of rs and rt. */ 5084 assign(t3, 5085 binop(Iop_Add32, 5086 unop(Iop_8Uto32, 5087 unop(Iop_16HIto8, 5088 unop(Iop_32to16, getIReg(rs)))), 5089 unop(Iop_8Uto32, 5090 unop(Iop_16HIto8, 5091 unop(Iop_32to16, getIReg(rt)))))); 5092 /* t4 will be 1 if there is overflow, 0 otherwise. */ 5093 assign(t4, binop(Iop_CmpEQ32, 5094 binop(Iop_And32, 5095 mkexpr(t3), 5096 mkU32(0x00000100)), 5097 mkU32(0x00000100))); 5098 /* Saturate if necessary. */ 5099 assign(t5, IRExpr_ITE(mkexpr(t4), 5100 mkU8(0xff), 5101 unop(Iop_32to8, mkexpr(t3)))); 5102 5103 /* Add bits 15-8 of rs and rt. */ 5104 assign(t6, 5105 binop(Iop_Add32, 5106 unop(Iop_8Uto32, 5107 unop(Iop_16to8, 5108 unop(Iop_32HIto16, getIReg(rs)))), 5109 unop(Iop_8Uto32, 5110 unop(Iop_16to8, 5111 unop(Iop_32HIto16, getIReg(rt)))))); 5112 /* t7 will be 1 if there is overflow, 0 otherwise. */ 5113 assign(t7, binop(Iop_CmpEQ32, 5114 binop(Iop_And32, 5115 mkexpr(t6), 5116 mkU32(0x00000100)), 5117 mkU32(0x00000100))); 5118 /* Saturate if necessary. */ 5119 assign(t8, IRExpr_ITE(mkexpr(t7), 5120 mkU8(0xff), 5121 unop(Iop_32to8, mkexpr(t6)))); 5122 5123 /* Add bits 15-8 of rs and rt. */ 5124 assign(t9, 5125 binop(Iop_Add32, 5126 unop(Iop_8Uto32, 5127 unop(Iop_16HIto8, 5128 unop(Iop_32HIto16, getIReg(rs)))), 5129 unop(Iop_8Uto32, 5130 unop(Iop_16HIto8, 5131 unop(Iop_32HIto16, getIReg(rt)))))); 5132 /* t10 will be 1 if there is overflow, 0 otherwise. */ 5133 assign(t10, binop(Iop_CmpEQ32, 5134 binop(Iop_And32, 5135 mkexpr(t9), 5136 mkU32(0x00000100)), 5137 mkU32(0x00000100))); 5138 /* Saturate if necessary. */ 5139 assign(t11, IRExpr_ITE(mkexpr(t10), 5140 mkU8(0xff), 5141 unop(Iop_32to8, mkexpr(t9)))); 5142 5143 assign(t12, 5144 binop(Iop_Or32, 5145 binop(Iop_Or32, 5146 binop(Iop_Or32, 5147 unop(Iop_1Sto32, mkexpr(t10)), 5148 unop(Iop_1Sto32, mkexpr(t7))), 5149 unop(Iop_1Sto32, mkexpr(t4))), 5150 unop(Iop_1Sto32, mkexpr(t1)))); 5151 5152 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 5153 mkexpr(t12), 5154 mkU32(0x0)), 5155 getDSPControl(), 5156 binop(Iop_Or32, 5157 getDSPControl(), 5158 mkU32(0x00100000)))); 5159 5160 putIReg(rd, 5161 binop(Iop_16HLto32, 5162 binop(Iop_8HLto16, mkexpr(t11), mkexpr(t8)), 5163 binop(Iop_8HLto16, mkexpr(t5), mkexpr(t2)))); 5164 break; 5165 } 5166 case 0x05: { /* SUBU_S.QB */ 5167 DIP("subu_s.qb r%d, r%d, r%d", rd, rs, rt); 5168 vassert(!mode64); 5169 t1 = newTemp(Ity_I32); 5170 t2 = newTemp(Ity_I1); 5171 t3 = newTemp(Ity_I1); 5172 t4 = newTemp(Ity_I1); 5173 t5 = newTemp(Ity_I1); 5174 t6 = newTemp(Ity_I32); 5175 t7 = newTemp(Ity_I32); 5176 t8 = newTemp(Ity_I32); 5177 t9 = newTemp(Ity_I32); 5178 5179 /* Use C function to easily calculate the result 5180 and write it in the register more conveniently 5181 Underflow is checked using step by step subtraction. */ 5182 assign(t1, binop(Iop_QSub8Ux4, getIReg(rs), getIReg(rt))); 5183 5184 /* Subtract each byte of rs and rt. */ 5185 assign(t6, 5186 binop(Iop_Sub32, 5187 unop(Iop_8Uto32, 5188 unop(Iop_16to8, 5189 unop(Iop_32to16, getIReg(rs)))), 5190 unop(Iop_8Uto32, 5191 unop(Iop_16to8, 5192 unop(Iop_32to16, getIReg(rt)))))); 5193 assign(t7, 5194 binop(Iop_Sub32, 5195 unop(Iop_8Uto32, 5196 unop(Iop_16HIto8, 5197 unop(Iop_32to16, getIReg(rs)))), 5198 unop(Iop_8Uto32, 5199 unop(Iop_16HIto8, 5200 unop(Iop_32to16, getIReg(rt)))))); 5201 assign(t8, 5202 binop(Iop_Sub32, 5203 unop(Iop_8Uto32, 5204 unop(Iop_16to8, 5205 unop(Iop_32HIto16, getIReg(rs)))), 5206 unop(Iop_8Uto32, 5207 unop(Iop_16to8, 5208 unop(Iop_32HIto16, getIReg(rt)))))); 5209 assign(t9, 5210 binop(Iop_Sub32, 5211 unop(Iop_8Uto32, 5212 unop(Iop_16HIto8, 5213 unop(Iop_32HIto16, getIReg(rs)))), 5214 unop(Iop_8Uto32, 5215 unop(Iop_16HIto8, 5216 unop(Iop_32HIto16, getIReg(rt)))))); 5217 5218 /* Put 1 to bit 20 in DSPControl if there is underflow 5219 in either byte. */ 5220 assign(t2, binop(Iop_CmpEQ32, 5221 binop(Iop_And32, 5222 mkexpr(t6), 5223 mkU32(0x00000100)), 5224 mkU32(0x00000100))); 5225 putDSPControl(IRExpr_ITE(mkexpr(t2), 5226 binop(Iop_Or32, 5227 getDSPControl(), 5228 mkU32(0x00100000)), 5229 getDSPControl())); 5230 assign(t3, binop(Iop_CmpEQ32, 5231 binop(Iop_And32, 5232 mkexpr(t7), 5233 mkU32(0x00000100)), 5234 mkU32(0x00000100))); 5235 putDSPControl(IRExpr_ITE(mkexpr(t3), 5236 binop(Iop_Or32, 5237 getDSPControl(), 5238 mkU32(0x00100000)), 5239 getDSPControl())); 5240 assign(t4, binop(Iop_CmpEQ32, 5241 binop(Iop_And32, 5242 mkexpr(t8), 5243 mkU32(0x00000100)), 5244 mkU32(0x00000100))); 5245 putDSPControl(IRExpr_ITE(mkexpr(t4), 5246 binop(Iop_Or32, 5247 getDSPControl(), 5248 mkU32(0x00100000)), 5249 getDSPControl())); 5250 assign(t5, binop(Iop_CmpEQ32, 5251 binop(Iop_And32, 5252 mkexpr(t9), 5253 mkU32(0x00000100)), 5254 mkU32(0x00000100))); 5255 putDSPControl(IRExpr_ITE(mkexpr(t5), 5256 binop(Iop_Or32, 5257 getDSPControl(), 5258 mkU32(0x00100000)), 5259 getDSPControl())); 5260 putIReg(rd, mkexpr(t1)); 5261 break; 5262 } 5263 case 0x6: { /* MULEU_S.PH.QBL */ 5264 DIP("muleu_s.ph.qbl r%d, r%d, r%d", rd, rs, rt); 5265 vassert(!mode64); 5266 t0 = newTemp(Ity_I32); 5267 t1 = newTemp(Ity_I32); 5268 t2 = newTemp(Ity_I1); 5269 t3 = newTemp(Ity_I1); 5270 5271 assign(t0, 5272 unop(Iop_64to32, 5273 binop(Iop_MullU32, 5274 unop(Iop_8Uto32, 5275 unop(Iop_16HIto8, 5276 unop(Iop_32HIto16, 5277 getIReg(rs)))), 5278 unop(Iop_16Uto32, 5279 unop(Iop_32HIto16, getIReg(rt)))))); 5280 assign(t1, 5281 unop(Iop_64to32, 5282 binop(Iop_MullU32, 5283 unop(Iop_8Uto32, 5284 unop(Iop_16to8, 5285 unop(Iop_32HIto16, 5286 getIReg(rs)))), 5287 unop(Iop_16Uto32, 5288 unop(Iop_32to16, getIReg(rt)))))); 5289 5290 assign(t2, binop(Iop_CmpNE32, 5291 mkU32(0x0), 5292 binop(Iop_And32, 5293 mkexpr(t0), 5294 mkU32(0x03ff0000)))); 5295 assign(t3, binop(Iop_CmpNE32, 5296 mkU32(0x0), 5297 binop(Iop_And32, 5298 mkexpr(t1), 5299 mkU32(0x03ff0000)))); 5300 putDSPControl(IRExpr_ITE(mkexpr(t2), 5301 binop(Iop_Or32, 5302 getDSPControl(), 5303 mkU32(0x200000)), 5304 IRExpr_ITE(mkexpr(t3), 5305 binop(Iop_Or32, 5306 getDSPControl(), 5307 mkU32(0x200000)), 5308 getDSPControl()))); 5309 putIReg(rd, 5310 binop(Iop_16HLto32, 5311 IRExpr_ITE(mkexpr(t2), 5312 mkU16(0xffff), 5313 unop(Iop_32to16, mkexpr(t0))), 5314 IRExpr_ITE(mkexpr(t3), 5315 mkU16(0xffff), 5316 unop(Iop_32to16, mkexpr(t1))))); 5317 break; 5318 } 5319 case 0x7: { /* MULEU_S.PH.QBR */ 5320 DIP("muleu_s.ph.qbr r%d, r%d, r%d", rd, rs, rt); 5321 vassert(!mode64); 5322 t0 = newTemp(Ity_I32); 5323 t1 = newTemp(Ity_I32); 5324 t2 = newTemp(Ity_I1); 5325 t3 = newTemp(Ity_I1); 5326 5327 assign(t0, unop(Iop_64to32, 5328 binop(Iop_MullU32, 5329 unop(Iop_8Uto32, 5330 unop(Iop_16HIto8, 5331 unop(Iop_32to16, 5332 getIReg(rs)))), 5333 unop(Iop_16Uto32, 5334 unop(Iop_32HIto16, 5335 getIReg(rt)))))); 5336 assign(t1, unop(Iop_64to32, 5337 binop(Iop_MullU32, 5338 unop(Iop_8Uto32, 5339 unop(Iop_16to8, 5340 unop(Iop_32to16, 5341 getIReg(rs)))), 5342 unop(Iop_16Uto32, 5343 unop(Iop_32to16, 5344 getIReg(rt)))))); 5345 5346 assign(t2, binop(Iop_CmpNE32, 5347 mkU32(0x0), 5348 binop(Iop_And32, 5349 mkexpr(t0), 5350 mkU32(0x03ff0000)))); 5351 assign(t3, binop(Iop_CmpNE32, 5352 mkU32(0x0), 5353 binop(Iop_And32, 5354 mkexpr(t1), 5355 mkU32(0x03ff0000)))); 5356 putDSPControl(IRExpr_ITE(mkexpr(t2), 5357 binop(Iop_Or32, 5358 getDSPControl(), 5359 mkU32(0x200000)), 5360 IRExpr_ITE(mkexpr(t3), 5361 binop(Iop_Or32, 5362 getDSPControl(), 5363 mkU32(0x200000)), 5364 getDSPControl()))); 5365 putIReg(rd, binop(Iop_16HLto32, 5366 IRExpr_ITE(mkexpr(t2), 5367 mkU16(0xffff), 5368 unop(Iop_32to16, 5369 mkexpr(t0))), 5370 IRExpr_ITE(mkexpr(t3), 5371 mkU16(0xffff), 5372 unop(Iop_32to16, 5373 mkexpr(t1))))); 5374 break; 5375 } 5376 case 0x08: { /* ADDU.PH */ 5377 DIP("addu.ph r%d, r%d, r%d", rd, rs, rt); 5378 vassert(!mode64); 5379 t0 = newTemp(Ity_I32); 5380 t1 = newTemp(Ity_I1); 5381 t2 = newTemp(Ity_I32); 5382 t3 = newTemp(Ity_I1); 5383 5384 /* Add lower halves. */ 5385 assign(t0, binop(Iop_Add32, 5386 unop(Iop_16Uto32, 5387 unop(Iop_32to16, getIReg(rs))), 5388 unop(Iop_16Uto32, 5389 unop(Iop_32to16, getIReg(rt))))); 5390 5391 /* Detect overflow. */ 5392 assign(t1, binop(Iop_CmpLT32U, 5393 unop(Iop_16Uto32, 5394 unop(Iop_32to16, mkexpr(t0))), 5395 unop(Iop_16Uto32, 5396 unop(Iop_32to16, getIReg(rs))))); 5397 5398 putDSPControl(IRExpr_ITE(mkexpr(t1), 5399 binop(Iop_Or32, 5400 getDSPControl(), 5401 mkU32(0x00100000)), 5402 getDSPControl())); 5403 5404 /* Add higher halves. */ 5405 assign(t2, binop(Iop_Add32, 5406 unop(Iop_16Uto32, 5407 unop(Iop_32HIto16, getIReg(rs))), 5408 unop(Iop_16Uto32, 5409 unop(Iop_32HIto16, getIReg(rt))))); 5410 5411 /* Detect overflow. */ 5412 assign(t3, binop(Iop_CmpLT32U, 5413 unop(Iop_16Uto32, 5414 unop(Iop_32to16, mkexpr(t2))), 5415 unop(Iop_16Uto32, 5416 unop(Iop_32HIto16, 5417 getIReg(rs))))); 5418 5419 putDSPControl(IRExpr_ITE(mkexpr(t3), 5420 binop(Iop_Or32, 5421 getDSPControl(), 5422 mkU32(0x00100000)), 5423 getDSPControl())); 5424 5425 putIReg(rd, binop(Iop_16HLto32, 5426 unop(Iop_32to16, mkexpr(t2)), 5427 unop(Iop_32to16, mkexpr(t0)))); 5428 break; 5429 } 5430 case 0x9: { /* SUBU.PH */ 5431 DIP("subu.ph r%d, r%d, r%d", rd, rs, rt); 5432 vassert(!mode64); 5433 t0 = newTemp(Ity_I32); 5434 t1 = newTemp(Ity_I1); 5435 t2 = newTemp(Ity_I32); 5436 t3 = newTemp(Ity_I1); 5437 5438 /* Substract lower halves. */ 5439 assign(t0, binop(Iop_Sub32, 5440 unop(Iop_16Uto32, 5441 unop(Iop_32to16, getIReg(rs))), 5442 unop(Iop_16Uto32, 5443 unop(Iop_32to16, getIReg(rt))))); 5444 5445 /* Detect underflow. */ 5446 assign(t1, binop(Iop_CmpNE32, 5447 binop(Iop_And32, 5448 mkexpr(t0), 5449 mkU32(0x00010000)), 5450 mkU32(0x0))); 5451 5452 putDSPControl(IRExpr_ITE(mkexpr(t1), 5453 binop(Iop_Or32, 5454 getDSPControl(), 5455 mkU32(0x00100000)), 5456 getDSPControl())); 5457 5458 /* Subtract higher halves. */ 5459 assign(t2, binop(Iop_Sub32, 5460 unop(Iop_16Uto32, 5461 unop(Iop_32HIto16, getIReg(rs))), 5462 unop(Iop_16Uto32, 5463 unop(Iop_32HIto16, getIReg(rt))))); 5464 5465 /* Detect underflow. */ 5466 assign(t3, binop(Iop_CmpNE32, 5467 binop(Iop_And32, 5468 mkexpr(t2), 5469 mkU32(0x00010000)), 5470 mkU32(0x0))); 5471 5472 putDSPControl(IRExpr_ITE(mkexpr(t3), 5473 binop(Iop_Or32, 5474 getDSPControl(), 5475 mkU32(0x00100000)), 5476 getDSPControl())); 5477 5478 putIReg(rd, binop(Iop_16HLto32, 5479 unop(Iop_32to16, mkexpr(t2)), 5480 unop(Iop_32to16, mkexpr(t0)))); 5481 break; 5482 } 5483 case 0xA: { /* ADDQ.PH */ 5484 DIP("addq.ph r%d, r%d, r%d", rd, rs, rt); 5485 vassert(!mode64); 5486 t0 = newTemp(Ity_I32); 5487 t1 = newTemp(Ity_I1); 5488 t2 = newTemp(Ity_I32); 5489 t3 = newTemp(Ity_I1); 5490 t6 = newTemp(Ity_I32); 5491 t7 = newTemp(Ity_I32); 5492 5493 /* Add lower halves. */ 5494 assign(t0, binop(Iop_Add32, 5495 unop(Iop_16Sto32, 5496 unop(Iop_32to16, getIReg(rs))), 5497 unop(Iop_16Sto32, 5498 unop(Iop_32to16, getIReg(rt))))); 5499 5500 /* Bit 16 of the result. */ 5501 assign(t6, binop(Iop_And32, 5502 unop(Iop_16Uto32, 5503 unop(Iop_32HIto16, mkexpr(t0))), 5504 mkU32(0x1))); 5505 /* Detect overflow. */ 5506 assign(t1, binop(Iop_CmpNE32, 5507 binop(Iop_Shr32, 5508 binop(Iop_And32, 5509 mkexpr(t0), 5510 mkU32(0x8000)), 5511 mkU8(15)), 5512 mkexpr(t6))); 5513 5514 putDSPControl(IRExpr_ITE(mkexpr(t1), 5515 binop(Iop_Or32, 5516 getDSPControl(), 5517 mkU32(0x00100000)), 5518 getDSPControl())); 5519 5520 /* Add higher halves. */ 5521 assign(t2, binop(Iop_Add32, 5522 unop(Iop_16Sto32, 5523 unop(Iop_32HIto16, getIReg(rs))), 5524 unop(Iop_16Sto32, 5525 unop(Iop_32HIto16, getIReg(rt))))); 5526 5527 /* Bit 16 of the result. */ 5528 assign(t7, binop(Iop_And32, 5529 unop(Iop_16Uto32, 5530 unop(Iop_32HIto16, mkexpr(t2))), 5531 mkU32(0x1))); 5532 /* Detect overflow. */ 5533 assign(t3, binop(Iop_CmpNE32, 5534 binop(Iop_Shr32, 5535 binop(Iop_And32, 5536 mkexpr(t2), 5537 mkU32(0x00008000)), 5538 mkU8(15)), 5539 mkexpr(t7))); 5540 5541 putDSPControl(IRExpr_ITE(mkexpr(t3), 5542 binop(Iop_Or32, 5543 getDSPControl(), 5544 mkU32(0x00100000)), 5545 getDSPControl())); 5546 5547 putIReg(rd, binop(Iop_16HLto32, 5548 unop(Iop_32to16, mkexpr(t2)), 5549 unop(Iop_32to16, mkexpr(t0)))); 5550 break; 5551 } 5552 case 0xB: { /* SUBQ.PH */ 5553 DIP("subq.ph r%d, r%d, r%d", rd, rs, rt); 5554 vassert(!mode64); 5555 t0 = newTemp(Ity_I32); 5556 t1 = newTemp(Ity_I1); 5557 t2 = newTemp(Ity_I32); 5558 t3 = newTemp(Ity_I1); 5559 t6 = newTemp(Ity_I32); 5560 t7 = newTemp(Ity_I32); 5561 5562 /* Subtract lower halves. */ 5563 assign(t0, binop(Iop_Sub32, 5564 unop(Iop_16Sto32, 5565 unop(Iop_32to16, getIReg(rs))), 5566 unop(Iop_16Sto32, 5567 unop(Iop_32to16, getIReg(rt))))); 5568 5569 /* Bit 16 of the result. */ 5570 assign(t6, binop(Iop_And32, 5571 unop(Iop_16Uto32, 5572 unop(Iop_32HIto16, mkexpr(t0))), 5573 mkU32(0x1))); 5574 /* Compare the signs of input value and the result. */ 5575 assign(t1, binop(Iop_CmpNE32, 5576 binop(Iop_Shr32, 5577 binop(Iop_And32, 5578 mkexpr(t0), 5579 mkU32(0x8000)), 5580 mkU8(15)), 5581 mkexpr(t6))); 5582 5583 putDSPControl(IRExpr_ITE(mkexpr(t1), 5584 binop(Iop_Or32, 5585 getDSPControl(), 5586 mkU32(0x00100000)), 5587 getDSPControl())); 5588 5589 /* Subtract higher halves. */ 5590 assign(t2, binop(Iop_Sub32, 5591 unop(Iop_16Sto32, 5592 unop(Iop_32HIto16, getIReg(rs))), 5593 unop(Iop_16Sto32, 5594 unop(Iop_32HIto16, getIReg(rt))))); 5595 5596 /* Bit 16 of the result. */ 5597 assign(t7, binop(Iop_And32, 5598 unop(Iop_16Uto32, 5599 unop(Iop_32HIto16, mkexpr(t2))), 5600 mkU32(0x1))); 5601 /* Compare the signs of input value and the result. */ 5602 assign(t3, binop(Iop_CmpNE32, 5603 binop(Iop_Shr32, 5604 binop(Iop_And32, 5605 mkexpr(t2), 5606 mkU32(0x00008000)), 5607 mkU8(15)), 5608 mkexpr(t7))); 5609 5610 putDSPControl(IRExpr_ITE(mkexpr(t3), 5611 binop(Iop_Or32, 5612 getDSPControl(), 5613 mkU32(0x00100000)), 5614 getDSPControl())); 5615 5616 putIReg(rd, binop(Iop_16HLto32, 5617 unop(Iop_32to16, mkexpr(t2)), 5618 unop(Iop_32to16, mkexpr(t0)))); 5619 break; 5620 } 5621 case 0xC: { /* ADDU_S.PH */ 5622 DIP("addu_s.ph r%d, r%d, r%d", rd, rs, rt); 5623 vassert(!mode64); 5624 t0 = newTemp(Ity_I32); 5625 t1 = newTemp(Ity_I1); 5626 t2 = newTemp(Ity_I32); 5627 t3 = newTemp(Ity_I1); 5628 5629 /* Add lower halves. */ 5630 assign(t0, binop(Iop_Add32, 5631 unop(Iop_16Uto32, 5632 unop(Iop_32to16, getIReg(rs))), 5633 unop(Iop_16Uto32, 5634 unop(Iop_32to16, getIReg(rt))))); 5635 5636 /* Detect overflow. */ 5637 assign(t1, binop(Iop_CmpLT32U, 5638 unop(Iop_16Uto32, 5639 unop(Iop_32to16, mkexpr(t0))), 5640 unop(Iop_16Uto32, 5641 unop(Iop_32to16, getIReg(rs))))); 5642 5643 putDSPControl(IRExpr_ITE(mkexpr(t1), 5644 binop(Iop_Or32, 5645 getDSPControl(), 5646 mkU32(0x00100000)), 5647 getDSPControl())); 5648 5649 /* Add higher halves. */ 5650 assign(t2, binop(Iop_Add32, 5651 unop(Iop_16Uto32, 5652 unop(Iop_32HIto16, getIReg(rs))), 5653 unop(Iop_16Uto32, 5654 unop(Iop_32HIto16, getIReg(rt))))); 5655 5656 /* Detect overflow. */ 5657 assign(t3, binop(Iop_CmpLT32U, 5658 unop(Iop_16Uto32, 5659 unop(Iop_32to16, mkexpr(t2))), 5660 unop(Iop_16Uto32, 5661 unop(Iop_32HIto16, getIReg(rs))))); 5662 5663 putDSPControl(IRExpr_ITE(mkexpr(t3), 5664 binop(Iop_Or32, 5665 getDSPControl(), 5666 mkU32(0x00100000)), 5667 getDSPControl())); 5668 5669 putIReg(rd, binop(Iop_16HLto32, 5670 IRExpr_ITE(mkexpr(t3), 5671 mkU16(0xffff), 5672 unop(Iop_32to16, 5673 mkexpr(t2))), 5674 IRExpr_ITE(mkexpr(t1), 5675 mkU16(0xffff), 5676 unop(Iop_32to16, 5677 mkexpr(t0))))); 5678 break; 5679 } 5680 case 0xD: { /* SUBU_S.PH */ 5681 DIP("subu_s.ph r%d, r%d, r%d", rd, rs, rt); 5682 vassert(!mode64); 5683 t0 = newTemp(Ity_I32); 5684 t1 = newTemp(Ity_I1); 5685 t2 = newTemp(Ity_I32); 5686 t3 = newTemp(Ity_I1); 5687 5688 /* Subtract lower halves. */ 5689 assign(t0, binop(Iop_Sub32, 5690 unop(Iop_16Uto32, 5691 unop(Iop_32to16, getIReg(rs))), 5692 unop(Iop_16Uto32, 5693 unop(Iop_32to16, getIReg(rt))))); 5694 5695 /* Detect underflow. */ 5696 assign(t1, binop(Iop_CmpNE32, 5697 binop(Iop_And32, 5698 mkexpr(t0), mkU32(0x00010000)), 5699 mkU32(0x0))); 5700 5701 putDSPControl(IRExpr_ITE(mkexpr(t1), 5702 binop(Iop_Or32, 5703 getDSPControl(), 5704 mkU32(0x00100000)), 5705 getDSPControl())); 5706 5707 /* Subtract higher halves. */ 5708 assign(t2, binop(Iop_Sub32, 5709 unop(Iop_16Uto32, 5710 unop(Iop_32HIto16, getIReg(rs))), 5711 unop(Iop_16Uto32, 5712 unop(Iop_32HIto16, getIReg(rt))))); 5713 5714 /* Detect underflow. */ 5715 assign(t3, binop(Iop_CmpNE32, 5716 binop(Iop_And32, 5717 mkexpr(t2), mkU32(0x00010000)), 5718 mkU32(0x0))); 5719 5720 putDSPControl(IRExpr_ITE(mkexpr(t3), 5721 binop(Iop_Or32, 5722 getDSPControl(), 5723 mkU32(0x00100000)), 5724 getDSPControl())); 5725 5726 putIReg(rd, 5727 binop(Iop_16HLto32, 5728 IRExpr_ITE(mkexpr(t3), 5729 mkU16(0x0000), 5730 unop(Iop_32to16, mkexpr(t2))), 5731 IRExpr_ITE(mkexpr(t1), 5732 mkU16(0x0000), 5733 unop(Iop_32to16, mkexpr(t0))))); 5734 break; 5735 } 5736 case 0xE: { /* ADDQ_S.PH */ 5737 DIP("addq_s.ph r%d r%d, r%d", rd, rs, rt); 5738 vassert(!mode64); 5739 t0 = newTemp(Ity_I32); 5740 t1 = newTemp(Ity_I1); 5741 t2 = newTemp(Ity_I32); 5742 t3 = newTemp(Ity_I1); 5743 t4 = newTemp(Ity_I16); 5744 t5 = newTemp(Ity_I16); 5745 t6 = newTemp(Ity_I32); 5746 t7 = newTemp(Ity_I32); 5747 5748 /* Add lower halves. */ 5749 assign(t0, binop(Iop_Add32, 5750 unop(Iop_16Sto32, 5751 unop(Iop_32to16, getIReg(rs))), 5752 unop(Iop_16Sto32, 5753 unop(Iop_32to16, getIReg(rt))))); 5754 5755 /* Bit 16 of the result. */ 5756 assign(t6, binop(Iop_And32, 5757 unop(Iop_16Uto32, 5758 unop(Iop_32HIto16, mkexpr(t0))), 5759 mkU32(0x1))); 5760 /* Detect overflow. */ 5761 assign(t1, binop(Iop_CmpNE32, 5762 binop(Iop_Shr32, 5763 binop(Iop_And32, 5764 mkexpr(t0), 5765 mkU32(0x8000)), 5766 mkU8(15)), 5767 mkexpr(t6))); 5768 5769 putDSPControl(IRExpr_ITE(mkexpr(t1), 5770 binop(Iop_Or32, 5771 getDSPControl(), 5772 mkU32(0x00100000)), 5773 getDSPControl())); 5774 /* Saturate if needed. */ 5775 assign(t4, IRExpr_ITE(mkexpr(t1), 5776 IRExpr_ITE(binop(Iop_CmpEQ32, 5777 mkexpr(t6), 5778 mkU32(0x0)), 5779 mkU16(0x7fff), 5780 mkU16(0x8000)), 5781 unop(Iop_32to16, mkexpr(t0)))); 5782 5783 /* Add higher halves. */ 5784 assign(t2, binop(Iop_Add32, 5785 unop(Iop_16Sto32, 5786 unop(Iop_32HIto16, getIReg(rs))), 5787 unop(Iop_16Sto32, 5788 unop(Iop_32HIto16, getIReg(rt))))); 5789 5790 /* Bit 16 of the result. */ 5791 assign(t7, binop(Iop_And32, 5792 unop(Iop_16Uto32, 5793 unop(Iop_32HIto16, mkexpr(t2))), 5794 mkU32(0x1))); 5795 /* Detect overflow. */ 5796 assign(t3, binop(Iop_CmpNE32, 5797 binop(Iop_Shr32, 5798 binop(Iop_And32, 5799 mkexpr(t2), 5800 mkU32(0x00008000)), 5801 mkU8(15)), 5802 mkexpr(t7))); 5803 5804 putDSPControl(IRExpr_ITE(mkexpr(t3), 5805 binop(Iop_Or32, 5806 getDSPControl(), 5807 mkU32(0x00100000)), 5808 getDSPControl())); 5809 /* Saturate if needed. */ 5810 assign(t5, IRExpr_ITE(mkexpr(t3), 5811 IRExpr_ITE(binop(Iop_CmpEQ32, 5812 mkexpr(t7), 5813 mkU32(0x0)), 5814 mkU16(0x7fff), 5815 mkU16(0x8000)), 5816 unop(Iop_32to16, mkexpr(t2)))); 5817 5818 putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4))); 5819 break; 5820 } 5821 case 0xF: { /* SUBQ_S.PH */ 5822 DIP("subq_s.ph r%d r%d, r%d", rd, rs, rt); 5823 vassert(!mode64); 5824 t0 = newTemp(Ity_I32); 5825 t1 = newTemp(Ity_I1); 5826 t2 = newTemp(Ity_I32); 5827 t3 = newTemp(Ity_I1); 5828 t4 = newTemp(Ity_I16); 5829 t5 = newTemp(Ity_I16); 5830 t6 = newTemp(Ity_I32); 5831 t7 = newTemp(Ity_I32); 5832 5833 /* Subtract lower halves. */ 5834 assign(t0, binop(Iop_Sub32, 5835 unop(Iop_16Sto32, 5836 unop(Iop_32to16, getIReg(rs))), 5837 unop(Iop_16Sto32, 5838 unop(Iop_32to16, getIReg(rt))))); 5839 5840 /* Bit 16 of the result. */ 5841 assign(t6, binop(Iop_And32, 5842 unop(Iop_16Uto32, 5843 unop(Iop_32HIto16, mkexpr(t0))), 5844 mkU32(0x1))); 5845 /* Detect overflow or underflow. */ 5846 assign(t1, binop(Iop_CmpNE32, 5847 binop(Iop_Shr32, 5848 binop(Iop_And32, 5849 mkexpr(t0), 5850 mkU32(0x8000)), 5851 mkU8(15)), 5852 mkexpr(t6))); 5853 5854 putDSPControl(IRExpr_ITE(mkexpr(t1), 5855 binop(Iop_Or32, 5856 getDSPControl(), 5857 mkU32(0x00100000)), 5858 getDSPControl())); 5859 /* Saturate if needed. */ 5860 assign(t4, IRExpr_ITE(mkexpr(t1), 5861 IRExpr_ITE(binop(Iop_CmpEQ32, 5862 mkexpr(t6), 5863 mkU32(0x0)), 5864 mkU16(0x7fff), 5865 mkU16(0x8000)), 5866 unop(Iop_32to16, mkexpr(t0)))); 5867 5868 /* Subtract higher halves. */ 5869 assign(t2, binop(Iop_Sub32, 5870 unop(Iop_16Sto32, 5871 unop(Iop_32HIto16, getIReg(rs))), 5872 unop(Iop_16Sto32, 5873 unop(Iop_32HIto16, getIReg(rt))))); 5874 5875 /* Bit 16 of the result. */ 5876 assign(t7, binop(Iop_And32, 5877 unop(Iop_16Uto32, 5878 unop(Iop_32HIto16, mkexpr(t2))), 5879 mkU32(0x1))); 5880 /* Detect overflow or underflow. */ 5881 assign(t3, binop(Iop_CmpNE32, 5882 binop(Iop_Shr32, 5883 binop(Iop_And32, 5884 mkexpr(t2), 5885 mkU32(0x00008000)), 5886 mkU8(15)), 5887 mkexpr(t7))); 5888 5889 putDSPControl(IRExpr_ITE(mkexpr(t3), 5890 binop(Iop_Or32, 5891 getDSPControl(), 5892 mkU32(0x00100000)), 5893 getDSPControl())); 5894 /* Saturate if needed. */ 5895 assign(t5, IRExpr_ITE(mkexpr(t3), 5896 IRExpr_ITE(binop(Iop_CmpEQ32, 5897 mkexpr(t7), 5898 mkU32(0x0)), 5899 mkU16(0x7fff), 5900 mkU16(0x8000)), 5901 unop(Iop_32to16, mkexpr(t2)))); 5902 5903 putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4))); 5904 break; 5905 } 5906 case 0x10: { /* ADDSC */ 5907 DIP("addsc r%d, r%d, r%d", rd, rs, rt); 5908 vassert(!mode64); 5909 t0 = newTemp(Ity_I64); 5910 t1 = newTemp(Ity_I1); 5911 5912 /* The carry bit result out of the addition operation is 5913 written to bit 13(the c field) of the DSPControl reg. */ 5914 assign(t0, binop(Iop_Add64, 5915 unop(Iop_32Uto64, getIReg(rs)), 5916 unop(Iop_32Uto64, getIReg(rt)))); 5917 5918 assign(t1, binop(Iop_CmpEQ32, 5919 binop(Iop_And32, 5920 unop(Iop_64HIto32, mkexpr(t0)), 5921 mkU32(0x1)), 5922 mkU32(0x1))); 5923 putDSPControl(IRExpr_ITE(mkexpr(t1), 5924 binop(Iop_Or32, 5925 getDSPControl(), 5926 mkU32(0x2000)), 5927 binop(Iop_And32, 5928 getDSPControl(), 5929 mkU32(0xffffdfff)))); 5930 5931 putIReg(rd, unop(Iop_64to32, mkexpr(t0))); 5932 break; 5933 } 5934 case 0x11: { /* ADDWC */ 5935 DIP("addwc r%d, r%d, r%d", rd, rs, rt); 5936 vassert(!mode64); 5937 t0 = newTemp(Ity_I32); 5938 t1 = newTemp(Ity_I64); 5939 t2 = newTemp(Ity_I32); 5940 t3 = newTemp(Ity_I32); 5941 t4 = newTemp(Ity_I1); 5942 5943 /* Get carry bit from DSPControl register. */ 5944 assign(t0, binop(Iop_Shr32, 5945 binop(Iop_And32, 5946 getDSPControl(), 5947 mkU32(0x2000)), 5948 mkU8(0xd))); 5949 assign(t1, binop(Iop_Add64, 5950 unop(Iop_32Sto64, getIReg(rs)), 5951 unop(Iop_32Sto64, 5952 binop(Iop_Add32, 5953 getIReg(rt), 5954 mkexpr(t0))))); 5955 5956 /* Extract bits 32 and 31. */ 5957 assign(t2, binop(Iop_And32, 5958 unop(Iop_64HIto32, mkexpr(t1)), 5959 mkU32(0x1))); 5960 assign(t3, binop(Iop_Shr32, 5961 binop(Iop_And32, 5962 unop(Iop_64to32, mkexpr(t1)), 5963 mkU32(0x80000000)), 5964 mkU8(31))); 5965 assign(t4, binop(Iop_CmpNE32, mkexpr(t2), mkexpr(t3))); 5966 5967 putDSPControl(IRExpr_ITE(mkexpr(t4), 5968 binop(Iop_Or32, 5969 getDSPControl(), 5970 mkU32(0x00100000)), 5971 getDSPControl())); 5972 putIReg(rd, unop(Iop_64to32, mkexpr(t1))); 5973 break; 5974 } 5975 case 0x12: { /* MODSUB */ 5976 DIP("modsub r%d, r%d, r%d", rd, rs, rt); 5977 vassert(!mode64); 5978 t0 = newTemp(Ity_I32); 5979 t1 = newTemp(Ity_I32); 5980 t2 = newTemp(Ity_I32); 5981 5982 /* decr_7..0 */ 5983 assign(t0, 5984 unop(Iop_8Uto32, 5985 unop(Iop_16to8, 5986 unop(Iop_32to16, getIReg(rt))))); 5987 5988 /* lastindex_15..0 */ 5989 assign(t1, 5990 unop(Iop_16Uto32, 5991 binop(Iop_8HLto16, 5992 unop(Iop_16to8, 5993 unop(Iop_32HIto16, getIReg(rt))), 5994 unop(Iop_16HIto8, 5995 unop(Iop_32to16, getIReg(rt)))))); 5996 /* temp_15..0 */ 5997 assign(t2, 5998 IRExpr_ITE(binop(Iop_CmpEQ32, 5999 getIReg(rs), 6000 mkU32(0x00000000)), 6001 mkexpr(t1), 6002 binop(Iop_Sub32, 6003 getIReg(rs), mkexpr(t0)))); 6004 putIReg(rd, mkexpr(t2)); 6005 break; 6006 } 6007 case 0x14: { /* RADDU.W.QB */ 6008 DIP("raddu.w.qb r%d, r%d", rd, rs); 6009 vassert(!mode64); 6010 putIReg(rd, binop(Iop_Add32, 6011 binop(Iop_Add32, 6012 unop(Iop_8Uto32, 6013 unop(Iop_16to8, 6014 unop(Iop_32to16, 6015 getIReg(rs)))), 6016 unop(Iop_8Uto32, 6017 unop(Iop_16HIto8, 6018 unop(Iop_32to16, 6019 getIReg(rs))))), 6020 binop(Iop_Add32, 6021 unop(Iop_8Uto32, 6022 unop(Iop_16to8, 6023 unop(Iop_32HIto16, 6024 getIReg(rs)))), 6025 unop(Iop_8Uto32, 6026 unop(Iop_16HIto8, 6027 unop(Iop_32HIto16, 6028 getIReg(rs))))))); 6029 break; 6030 } 6031 case 0x16: { /* ADDQ_S.W */ 6032 DIP("addq_s.w r%d, r%d, r%d", rd, rs, rt); 6033 vassert(!mode64); 6034 t0 = newTemp(Ity_I64); 6035 t1 = newTemp(Ity_I1); 6036 t2 = newTemp(Ity_I32); 6037 t3 = newTemp(Ity_I32); 6038 6039 assign(t0, binop(Iop_Add64, 6040 unop(Iop_32Sto64, getIReg(rs)), 6041 unop(Iop_32Sto64, getIReg(rt)))); 6042 6043 assign(t3, binop(Iop_And32, 6044 unop(Iop_64HIto32, mkexpr(t0)), 6045 mkU32(0x1))); 6046 assign(t1, binop(Iop_CmpNE32, 6047 binop(Iop_Shr32, 6048 binop(Iop_And32, 6049 unop(Iop_64to32, mkexpr(t0)), 6050 mkU32(0x80000000)), 6051 mkU8(31)), 6052 mkexpr(t3))); 6053 6054 putDSPControl(IRExpr_ITE(mkexpr(t1), 6055 binop(Iop_Or32, 6056 getDSPControl(), 6057 mkU32(0x00100000)), 6058 getDSPControl())); 6059 6060 putIReg(rd, IRExpr_ITE(mkexpr(t1), 6061 IRExpr_ITE(binop(Iop_CmpEQ32, 6062 mkexpr(t3), 6063 mkU32(0x0)), 6064 mkU32(0x7fffffff), 6065 mkU32(0x80000000)), 6066 unop(Iop_64to32, mkexpr(t0)))); 6067 break; 6068 } 6069 case 0x17: { /* SUBQ_S.W */ 6070 DIP("subq_s.w r%d, r%d, r%d", rd, rs, rt); 6071 vassert(!mode64); 6072 t0 = newTemp(Ity_I64); 6073 t1 = newTemp(Ity_I1); 6074 t2 = newTemp(Ity_I32); 6075 t3 = newTemp(Ity_I32); 6076 6077 assign(t0, binop(Iop_Sub64, 6078 unop(Iop_32Sto64, getIReg(rs)), 6079 unop(Iop_32Sto64, getIReg(rt)))); 6080 6081 assign(t3, binop(Iop_And32, 6082 unop(Iop_64HIto32, mkexpr(t0)), 6083 mkU32(0x1))); 6084 assign(t1, binop(Iop_CmpNE32, 6085 binop(Iop_Shr32, 6086 binop(Iop_And32, 6087 unop(Iop_64to32, mkexpr(t0)), 6088 mkU32(0x80000000)), 6089 mkU8(31)), 6090 mkexpr(t3))); 6091 6092 putDSPControl(IRExpr_ITE(mkexpr(t1), 6093 binop(Iop_Or32, 6094 getDSPControl(), 6095 mkU32(0x00100000)), 6096 getDSPControl())); 6097 6098 putIReg(rd, IRExpr_ITE(mkexpr(t1), 6099 IRExpr_ITE(binop(Iop_CmpEQ32, 6100 mkexpr(t3), 6101 mkU32(0x0)), 6102 mkU32(0x7fffffff), 6103 mkU32(0x80000000)), 6104 unop(Iop_64to32, mkexpr(t0)))); 6105 break; 6106 } 6107 case 0x1C: { /* MULEQ_S.W.PHL */ 6108 DIP("muleq_s.w.phl r%d, r%d, r%d", rd, rs, rt); 6109 vassert(!mode64); 6110 t0 = newTemp(Ity_I32); 6111 t1 = newTemp(Ity_I1); 6112 t2 = newTemp(Ity_I1); 6113 t3 = newTemp(Ity_I32); 6114 6115 assign(t0, 6116 binop(Iop_Shl32, 6117 binop(Iop_Mul32, 6118 unop(Iop_16Sto32, 6119 unop(Iop_32HIto16, getIReg(rt))), 6120 unop(Iop_16Sto32, 6121 unop(Iop_32HIto16, getIReg(rs)))), 6122 mkU8(0x1))); 6123 assign(t1, binop(Iop_CmpEQ32, 6124 binop(Iop_And32, 6125 getIReg(rt), 6126 mkU32(0xffff0000)), 6127 mkU32(0x80000000))); 6128 assign(t2, binop(Iop_CmpEQ32, 6129 binop(Iop_And32, 6130 getIReg(rs), 6131 mkU32(0xffff0000)), 6132 mkU32(0x80000000))); 6133 assign(t3, IRExpr_ITE(mkexpr(t1), 6134 IRExpr_ITE(mkexpr(t2), 6135 binop(Iop_Or32, 6136 getDSPControl(), 6137 mkU32(0x00200000)), 6138 getDSPControl()), 6139 getDSPControl())); 6140 putDSPControl(mkexpr(t3)); 6141 6142 putIReg(rd, IRExpr_ITE(mkexpr(t1), 6143 IRExpr_ITE(mkexpr(t2), 6144 mkU32(0x7fffffff), 6145 mkexpr(t0)), 6146 mkexpr(t0))); 6147 break; 6148 } 6149 case 0x1D: { /* MULEQ_S.W.PHR */ 6150 DIP("muleq_s.w.phr r%d, r%d, r%d", rd, rs, rt); 6151 vassert(!mode64); 6152 t0 = newTemp(Ity_I32); 6153 t1 = newTemp(Ity_I1); 6154 t2 = newTemp(Ity_I1); 6155 6156 assign(t0, 6157 binop(Iop_Shl32, 6158 binop(Iop_Mul32, 6159 unop(Iop_16Sto32, 6160 unop(Iop_32to16, getIReg(rt))), 6161 unop(Iop_16Sto32, 6162 unop(Iop_32to16, getIReg(rs)))), 6163 mkU8(0x1))); 6164 assign(t1, binop(Iop_CmpEQ32, 6165 binop(Iop_And32, 6166 getIReg(rt), 6167 mkU32(0xffff)), 6168 mkU32(0x8000))); 6169 assign(t2, binop(Iop_CmpEQ32, 6170 binop(Iop_And32, 6171 getIReg(rs), 6172 mkU32(0xffff)), 6173 mkU32(0x8000))); 6174 putDSPControl(IRExpr_ITE(mkexpr(t1), 6175 IRExpr_ITE(mkexpr(t2), 6176 binop(Iop_Or32, 6177 getDSPControl(), 6178 mkU32(0x00200000) 6179 ), 6180 getDSPControl()), 6181 getDSPControl())); 6182 putIReg(rd, IRExpr_ITE(mkexpr(t1), 6183 IRExpr_ITE(mkexpr(t2), 6184 mkU32(0x7fffffff), 6185 mkexpr(t0)), 6186 mkexpr(t0))); 6187 break; 6188 } 6189 case 0x1E: { /* MULQ_S.PH */ 6190 DIP("mulq_s.ph r%d, r%d, r%d", rd, rs, rt); 6191 vassert(!mode64); 6192 t0 = newTemp(Ity_I32); 6193 t1 = newTemp(Ity_I32); 6194 t2 = newTemp(Ity_I16); 6195 t3 = newTemp(Ity_I16); 6196 t5 = newTemp(Ity_I32); 6197 t6 = newTemp(Ity_I32); 6198 t7 = newTemp(Ity_I32); 6199 t8 = newTemp(Ity_I32); 6200 6201 assign(t5, 6202 unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rs)))); 6203 assign(t6, 6204 unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt)))); 6205 6206 assign(t7, 6207 unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rs)))); 6208 assign(t8, 6209 unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rt)))); 6210 6211 assign(t0, binop(Iop_And32, 6212 unop(Iop_1Sto32, 6213 binop(Iop_CmpEQ32, 6214 binop(Iop_And32, 6215 mkexpr(t5), 6216 mkU32(0xffff)), 6217 mkU32(0x8000))), 6218 unop(Iop_1Sto32, 6219 binop(Iop_CmpEQ32, 6220 binop(Iop_And32, 6221 mkexpr(t6), 6222 mkU32(0xffff)), 6223 mkU32(0x8000))))); 6224 assign(t1, binop(Iop_And32, 6225 unop(Iop_1Sto32, 6226 binop(Iop_CmpEQ32, 6227 binop(Iop_And32, 6228 mkexpr(t7), 6229 mkU32(0xffff)), 6230 mkU32(0x8000))), 6231 unop(Iop_1Sto32, 6232 binop(Iop_CmpEQ32, 6233 binop(Iop_And32, 6234 mkexpr(t8), 6235 mkU32(0xffff)), 6236 mkU32(0x8000))))); 6237 6238 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 6239 binop(Iop_Or32, 6240 mkexpr(t0), 6241 mkexpr(t1)), 6242 mkU32(0x0)), 6243 getDSPControl(), 6244 binop(Iop_Or32, 6245 getDSPControl(), 6246 mkU32(0x200000)))); 6247 6248 assign(t2, unop(Iop_32HIto16, 6249 binop(Iop_Shl32, 6250 unop(Iop_64to32, 6251 binop(Iop_MullS32, 6252 mkexpr(t7), 6253 mkexpr(t8))), 6254 mkU8(0x1)))); 6255 assign(t3, unop(Iop_32HIto16, 6256 binop(Iop_Shl32, 6257 unop(Iop_64to32, 6258 binop(Iop_MullS32, 6259 mkexpr(t5), 6260 mkexpr(t6))), 6261 mkU8(0x1)))); 6262 putIReg(rd, binop(Iop_16HLto32, 6263 IRExpr_ITE(binop(Iop_CmpEQ32, 6264 mkexpr(t1), 6265 mkU32(0x0)), 6266 mkexpr(t2), 6267 mkU16(0x7fff)), 6268 IRExpr_ITE(binop(Iop_CmpEQ32, 6269 mkexpr(t0), 6270 mkU32(0x0)), 6271 mkexpr(t3), 6272 mkU16(0x7fff)))); 6273 break; 6274 } 6275 case 0x1F: { /* MULQ_RS.PH */ 6276 DIP("mulq_rs.ph r%d, r%d, r%d", rd, rs, rt); 6277 vassert(!mode64); 6278 t0 = newTemp(Ity_I32); 6279 t1 = newTemp(Ity_I1); 6280 t2 = newTemp(Ity_I1); 6281 t3 = newTemp(Ity_I16); 6282 t4 = newTemp(Ity_I32); 6283 t5 = newTemp(Ity_I1); 6284 t6 = newTemp(Ity_I1); 6285 t7 = newTemp(Ity_I16); 6286 6287 /* Multiply and round lower halfwords. */ 6288 assign(t0, binop(Iop_Add32, 6289 binop(Iop_Shl32, 6290 binop(Iop_Mul32, 6291 unop(Iop_16Sto32, 6292 unop(Iop_32to16, 6293 getIReg(rt))), 6294 unop(Iop_16Sto32, 6295 unop(Iop_32to16, 6296 getIReg(rs)))), 6297 mkU8(0x1)), 6298 mkU32(0x00008000))); 6299 assign(t1, binop(Iop_CmpEQ32, 6300 binop(Iop_And32, 6301 getIReg(rt), mkU32(0xffff)), 6302 mkU32(0x8000))); 6303 assign(t2, binop(Iop_CmpEQ32, 6304 binop(Iop_And32, 6305 getIReg(rs), mkU32(0xffff)), 6306 mkU32(0x8000))); 6307 putDSPControl(IRExpr_ITE(mkexpr(t1), 6308 IRExpr_ITE(mkexpr(t2), 6309 binop(Iop_Or32, 6310 getDSPControl(), 6311 mkU32(0x00200000) 6312 ), 6313 getDSPControl()), 6314 getDSPControl())); 6315 assign(t3, IRExpr_ITE(mkexpr(t1), 6316 IRExpr_ITE(mkexpr(t2), 6317 mkU16(0x7fff), 6318 unop(Iop_32HIto16, 6319 mkexpr(t0))), 6320 unop(Iop_32HIto16, mkexpr(t0)))); 6321 6322 /* Multiply and round higher halfwords. */ 6323 assign(t4, binop(Iop_Add32, 6324 binop(Iop_Shl32, 6325 binop(Iop_Mul32, 6326 unop(Iop_16Sto32, 6327 unop(Iop_32HIto16, 6328 getIReg(rt))), 6329 unop(Iop_16Sto32, 6330 unop(Iop_32HIto16, 6331 getIReg(rs)))), 6332 mkU8(0x1)), 6333 mkU32(0x00008000))); 6334 assign(t5, binop(Iop_CmpEQ32, 6335 binop(Iop_And32, 6336 getIReg(rt), 6337 mkU32(0xffff0000)), 6338 mkU32(0x80000000))); 6339 assign(t6, binop(Iop_CmpEQ32, 6340 binop(Iop_And32, 6341 getIReg(rs), 6342 mkU32(0xffff0000)), 6343 mkU32(0x80000000))); 6344 putDSPControl(IRExpr_ITE(mkexpr(t5), 6345 IRExpr_ITE(mkexpr(t6), 6346 binop(Iop_Or32, 6347 getDSPControl(), 6348 mkU32(0x00200000)), 6349 getDSPControl()), 6350 getDSPControl())); 6351 assign(t7, IRExpr_ITE(mkexpr(t5), 6352 IRExpr_ITE(mkexpr(t6), 6353 mkU16(0x7fff), 6354 unop(Iop_32HIto16, 6355 mkexpr(t4))), 6356 unop(Iop_32HIto16, mkexpr(t4)))); 6357 6358 putIReg(rd, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3))); 6359 break; 6360 } 6361 default: 6362 return -1; 6363 } 6364 break; /* end of ADDU.QB */ 6365 } 6366 case 0x11: { /* CMPU.EQ.QB */ 6367 switch(sa) { 6368 case 0x0: { /* CMPU.EQ.QB */ 6369 DIP("cmpu.eq.qb r%d, r%d", rs, rt); 6370 vassert(!mode64); 6371 t1 = newTemp(Ity_I1); 6372 t2 = newTemp(Ity_I1); 6373 t3 = newTemp(Ity_I1); 6374 t4 = newTemp(Ity_I1); 6375 6376 assign(t1, 6377 binop(Iop_CmpEQ32, 6378 binop(Iop_And32, getIReg(rs), mkU32(0xff)), 6379 binop(Iop_And32, getIReg(rt), mkU32(0xff)))); 6380 putDSPControl(IRExpr_ITE(mkexpr(t1), 6381 binop(Iop_Or32, 6382 getDSPControl(), 6383 mkU32(0x01000000)), 6384 binop(Iop_And32, 6385 getDSPControl(), 6386 mkU32(0xfeffffff)))); 6387 6388 assign(t2, binop(Iop_CmpEQ32, 6389 unop(Iop_8Uto32, 6390 unop(Iop_16HIto8, 6391 unop(Iop_32to16, 6392 getIReg(rs)))), 6393 unop(Iop_8Uto32, 6394 unop(Iop_16HIto8, 6395 unop(Iop_32to16, 6396 getIReg(rt)))))); 6397 putDSPControl(IRExpr_ITE(mkexpr(t2), 6398 binop(Iop_Or32, 6399 getDSPControl(), 6400 mkU32(0x02000000)), 6401 binop(Iop_And32, 6402 getDSPControl(), 6403 mkU32(0xfdffffff)))); 6404 6405 assign(t3, binop(Iop_CmpEQ32, 6406 unop(Iop_8Uto32, 6407 unop(Iop_16to8, 6408 unop(Iop_32HIto16, 6409 getIReg(rs)))), 6410 unop(Iop_8Uto32, 6411 unop(Iop_16to8, 6412 unop(Iop_32HIto16, 6413 getIReg(rt)))))); 6414 putDSPControl(IRExpr_ITE(mkexpr(t3), 6415 binop(Iop_Or32, 6416 getDSPControl(), 6417 mkU32(0x04000000)), 6418 binop(Iop_And32, 6419 getDSPControl(), 6420 mkU32(0xfbffffff)))); 6421 6422 assign(t4, binop(Iop_CmpEQ32, 6423 unop(Iop_8Uto32, 6424 unop(Iop_16HIto8, 6425 unop(Iop_32HIto16, 6426 getIReg(rs)))), 6427 unop(Iop_8Uto32, 6428 unop(Iop_16HIto8, 6429 unop(Iop_32HIto16, 6430 getIReg(rt)))))); 6431 putDSPControl(IRExpr_ITE(mkexpr(t4), 6432 binop(Iop_Or32, 6433 getDSPControl(), 6434 mkU32(0x08000000)), 6435 binop(Iop_And32, 6436 getDSPControl(), 6437 mkU32(0xf7ffffff)))); 6438 break; 6439 } 6440 case 0x1: { /* CMPU.LT.QB */ 6441 DIP("cmpu.lt.qb r%d, r%d", rs, rt); 6442 vassert(!mode64); 6443 t1 = newTemp(Ity_I1); 6444 t2 = newTemp(Ity_I1); 6445 t3 = newTemp(Ity_I1); 6446 t4 = newTemp(Ity_I1); 6447 6448 assign(t1, binop(Iop_CmpLT32U, 6449 unop(Iop_8Uto32, 6450 unop(Iop_16to8, 6451 unop(Iop_32to16, 6452 getIReg(rs)))), 6453 unop(Iop_8Uto32, 6454 unop(Iop_16to8, 6455 unop(Iop_32to16, 6456 getIReg(rt)))))); 6457 putDSPControl(IRExpr_ITE(mkexpr(t1), 6458 binop(Iop_Or32, 6459 getDSPControl(), 6460 mkU32(0x01000000)), 6461 binop(Iop_And32, 6462 getDSPControl(), 6463 mkU32(0xfeffffff)))); 6464 6465 assign(t2, binop(Iop_CmpLT32U, 6466 unop(Iop_8Uto32, 6467 unop(Iop_16HIto8, 6468 unop(Iop_32to16, 6469 getIReg(rs)))), 6470 unop(Iop_8Uto32, 6471 unop(Iop_16HIto8, 6472 unop(Iop_32to16, 6473 getIReg(rt)))))); 6474 putDSPControl(IRExpr_ITE(mkexpr(t2), 6475 binop(Iop_Or32, 6476 getDSPControl(), 6477 mkU32(0x02000000)), 6478 binop(Iop_And32, 6479 getDSPControl(), 6480 mkU32(0xfdffffff)))); 6481 6482 assign(t3, binop(Iop_CmpLT32U, 6483 unop(Iop_8Uto32, 6484 unop(Iop_16to8, 6485 unop(Iop_32HIto16, 6486 getIReg(rs)))), 6487 unop(Iop_8Uto32, 6488 unop(Iop_16to8, 6489 unop(Iop_32HIto16, 6490 getIReg(rt)))))); 6491 putDSPControl(IRExpr_ITE(mkexpr(t3), 6492 binop(Iop_Or32, 6493 getDSPControl(), 6494 mkU32(0x04000000)), 6495 binop(Iop_And32, 6496 getDSPControl(), 6497 mkU32(0xfbffffff)))); 6498 6499 assign(t4, binop(Iop_CmpLT32U, 6500 unop(Iop_8Uto32, 6501 unop(Iop_16HIto8, 6502 unop(Iop_32HIto16, 6503 getIReg(rs)))), 6504 unop(Iop_8Uto32, 6505 unop(Iop_16HIto8, 6506 unop(Iop_32HIto16, 6507 getIReg(rt)))))); 6508 putDSPControl(IRExpr_ITE(mkexpr(t4), 6509 binop(Iop_Or32, 6510 getDSPControl(), 6511 mkU32(0x08000000)), 6512 binop(Iop_And32, 6513 getDSPControl(), 6514 mkU32(0xf7ffffff)))); 6515 break; 6516 } 6517 case 0x2: { /* CMPU.LE.QB */ 6518 DIP("cmpu.le.qb r%d, r%d", rs, rt); 6519 vassert(!mode64); 6520 t1 = newTemp(Ity_I1); 6521 t2 = newTemp(Ity_I1); 6522 t3 = newTemp(Ity_I1); 6523 t4 = newTemp(Ity_I1); 6524 6525 assign(t1, binop(Iop_CmpLE32U, 6526 unop(Iop_8Uto32, 6527 unop(Iop_16to8, 6528 unop(Iop_32to16, 6529 getIReg(rs)))), 6530 unop(Iop_8Uto32, 6531 unop(Iop_16to8, 6532 unop(Iop_32to16, 6533 getIReg(rt)))))); 6534 putDSPControl(IRExpr_ITE(mkexpr(t1), 6535 binop(Iop_Or32, 6536 getDSPControl(), 6537 mkU32(0x01000000)), 6538 binop(Iop_And32, 6539 getDSPControl(), 6540 mkU32(0xfeffffff)))); 6541 6542 assign(t2, binop(Iop_CmpLE32U, 6543 unop(Iop_8Uto32, 6544 unop(Iop_16HIto8, 6545 unop(Iop_32to16, 6546 getIReg(rs)))), 6547 unop(Iop_8Uto32, 6548 unop(Iop_16HIto8, 6549 unop(Iop_32to16, 6550 getIReg(rt)))))); 6551 putDSPControl(IRExpr_ITE(mkexpr(t2), 6552 binop(Iop_Or32, 6553 getDSPControl(), 6554 mkU32(0x02000000)), 6555 binop(Iop_And32, 6556 getDSPControl(), 6557 mkU32(0xfdffffff)))); 6558 6559 assign(t3, binop(Iop_CmpLE32U, 6560 unop(Iop_8Uto32, 6561 unop(Iop_16to8, 6562 unop(Iop_32HIto16, 6563 getIReg(rs)))), 6564 unop(Iop_8Uto32, 6565 unop(Iop_16to8, 6566 unop(Iop_32HIto16, 6567 getIReg(rt)))))); 6568 putDSPControl(IRExpr_ITE(mkexpr(t3), 6569 binop(Iop_Or32, 6570 getDSPControl(), 6571 mkU32(0x04000000)), 6572 binop(Iop_And32, 6573 getDSPControl(), 6574 mkU32(0xfbffffff)))); 6575 6576 assign(t4, binop(Iop_CmpLE32U, 6577 unop(Iop_8Uto32, 6578 unop(Iop_16HIto8, 6579 unop(Iop_32HIto16, 6580 getIReg(rs)))), 6581 unop(Iop_8Uto32, 6582 unop(Iop_16HIto8, 6583 unop(Iop_32HIto16, 6584 getIReg(rt)))))); 6585 putDSPControl(IRExpr_ITE(mkexpr(t4), 6586 binop(Iop_Or32, 6587 getDSPControl(), 6588 mkU32(0x08000000)), 6589 binop(Iop_And32, 6590 getDSPControl(), 6591 mkU32(0xf7ffffff)))); 6592 break; 6593 } 6594 case 0x3: { /* PICK.QB */ 6595 DIP("pick.qb r%d, r%d, r%d", rd, rs, rt); 6596 vassert(!mode64); 6597 t0 = newTemp(Ity_I32); 6598 t1 = newTemp(Ity_I8); 6599 t2 = newTemp(Ity_I8); 6600 t3 = newTemp(Ity_I8); 6601 t4 = newTemp(Ity_I8); 6602 6603 assign(t0, getDSPControl()); 6604 assign(t1, IRExpr_ITE(binop(Iop_CmpNE32, 6605 binop(Iop_And32, 6606 mkexpr(t0), 6607 mkU32(0x01000000)), 6608 mkU32(0x0)), 6609 unop(Iop_16to8, 6610 unop(Iop_32to16, 6611 getIReg(rs))), 6612 unop(Iop_16to8, 6613 unop(Iop_32to16, 6614 getIReg(rt))))); 6615 assign(t2, IRExpr_ITE(binop(Iop_CmpNE32, 6616 binop(Iop_And32, 6617 mkexpr(t0), 6618 mkU32(0x02000000)), 6619 mkU32(0x0)), 6620 unop(Iop_16HIto8, 6621 unop(Iop_32to16, getIReg(rs))), 6622 unop(Iop_16HIto8, 6623 unop(Iop_32to16, 6624 getIReg(rt))))); 6625 assign(t3, IRExpr_ITE(binop(Iop_CmpNE32, 6626 binop(Iop_And32, 6627 mkexpr(t0), 6628 mkU32(0x04000000)), 6629 mkU32(0x0)), 6630 unop(Iop_16to8, 6631 unop(Iop_32HIto16, 6632 getIReg(rs))), 6633 unop(Iop_16to8, 6634 unop(Iop_32HIto16, 6635 getIReg(rt))))); 6636 assign(t4, IRExpr_ITE(binop(Iop_CmpNE32, 6637 binop(Iop_And32, 6638 mkexpr(t0), 6639 mkU32(0x08000000)), 6640 mkU32(0x0)), 6641 unop(Iop_16HIto8, 6642 unop(Iop_32HIto16, 6643 getIReg(rs))), 6644 unop(Iop_16HIto8, 6645 unop(Iop_32HIto16, 6646 getIReg(rt))))); 6647 putIReg(rd, 6648 binop(Iop_16HLto32, 6649 binop(Iop_8HLto16, mkexpr(t4), mkexpr(t3)), 6650 binop(Iop_8HLto16, mkexpr(t2), mkexpr(t1)))); 6651 break; 6652 } 6653 case 0x4: { /* CMPGU.EQ.QB */ 6654 DIP("cmpgu.eq.qb r%d, r%d, r%d", rd, rs, rt); 6655 vassert(!mode64); 6656 t1 = newTemp(Ity_I1); 6657 t2 = newTemp(Ity_I1); 6658 t3 = newTemp(Ity_I1); 6659 t4 = newTemp(Ity_I1); 6660 t5 = newTemp(Ity_I32); 6661 t6 = newTemp(Ity_I32); 6662 t7 = newTemp(Ity_I32); 6663 t8 = newTemp(Ity_I32); 6664 6665 assign(t1, binop(Iop_CmpEQ32, 6666 unop(Iop_8Uto32, 6667 unop(Iop_16to8, 6668 unop(Iop_32to16, getIReg(rs)))), 6669 unop(Iop_8Uto32, 6670 unop(Iop_16to8, 6671 unop(Iop_32to16, 6672 getIReg(rt)))))); 6673 assign(t5, IRExpr_ITE(mkexpr(t1), 6674 mkU32(0x00000001), mkU32(0))); 6675 6676 assign(t2, binop(Iop_CmpEQ32, 6677 unop(Iop_8Uto32, 6678 unop(Iop_16HIto8, 6679 unop(Iop_32to16, getIReg(rs)))), 6680 unop(Iop_8Uto32, 6681 unop(Iop_16HIto8, 6682 unop(Iop_32to16, 6683 getIReg(rt)))))); 6684 assign(t6, IRExpr_ITE(mkexpr(t2), 6685 mkU32(0x00000002), mkU32(0))); 6686 6687 assign(t3, binop(Iop_CmpEQ32, 6688 unop(Iop_8Uto32, 6689 unop(Iop_16to8, 6690 unop(Iop_32HIto16, 6691 getIReg(rs)))), 6692 unop(Iop_8Uto32, 6693 unop(Iop_16to8, 6694 unop(Iop_32HIto16, 6695 getIReg(rt)))))); 6696 assign(t7, IRExpr_ITE(mkexpr(t3), 6697 mkU32(0x00000004), mkU32(0))); 6698 6699 assign(t4, binop(Iop_CmpEQ32, 6700 unop(Iop_8Uto32, 6701 unop(Iop_16HIto8, 6702 unop(Iop_32HIto16, 6703 getIReg(rs)))), 6704 unop(Iop_8Uto32, 6705 unop(Iop_16HIto8, 6706 unop(Iop_32HIto16, 6707 getIReg(rt)))))); 6708 assign(t8, IRExpr_ITE(mkexpr(t4), 6709 mkU32(0x00000008), mkU32(0))); 6710 6711 putIReg(rd, binop(Iop_Or32, 6712 binop(Iop_Or32, 6713 binop(Iop_Or32, 6714 mkexpr(t5), mkexpr(t6)), 6715 mkexpr(t7)), 6716 mkexpr(t8))); 6717 break; 6718 } 6719 case 0x5: { /* CMPGU.LT.QB */ 6720 DIP("cmpgu.lt.qb r%d, r%d, r%d", rd, rs, rt); 6721 vassert(!mode64); 6722 t1 = newTemp(Ity_I1); 6723 t2 = newTemp(Ity_I1); 6724 t3 = newTemp(Ity_I1); 6725 t4 = newTemp(Ity_I1); 6726 t5 = newTemp(Ity_I32); 6727 t6 = newTemp(Ity_I32); 6728 t7 = newTemp(Ity_I32); 6729 t8 = newTemp(Ity_I32); 6730 6731 assign(t1, binop(Iop_CmpLT32U, 6732 unop(Iop_8Uto32, 6733 unop(Iop_16to8, 6734 unop(Iop_32to16, getIReg(rs)))), 6735 unop(Iop_8Uto32, 6736 unop(Iop_16to8, 6737 unop(Iop_32to16, 6738 getIReg(rt)))))); 6739 assign(t5, IRExpr_ITE(mkexpr(t1), 6740 mkU32(0x00000001), mkU32(0))); 6741 6742 assign(t2, binop(Iop_CmpLT32U, 6743 unop(Iop_8Uto32, 6744 unop(Iop_16HIto8, 6745 unop(Iop_32to16, getIReg(rs)))), 6746 unop(Iop_8Uto32, 6747 unop(Iop_16HIto8, 6748 unop(Iop_32to16, 6749 getIReg(rt)))))); 6750 assign(t6, IRExpr_ITE(mkexpr(t2), 6751 mkU32(0x00000002), mkU32(0))); 6752 6753 assign(t3, binop(Iop_CmpLT32U, 6754 unop(Iop_8Uto32, 6755 unop(Iop_16to8, 6756 unop(Iop_32HIto16, 6757 getIReg(rs)))), 6758 unop(Iop_8Uto32, 6759 unop(Iop_16to8, 6760 unop(Iop_32HIto16, 6761 getIReg(rt)))))); 6762 assign(t7, IRExpr_ITE(mkexpr(t3), 6763 mkU32(0x00000004), mkU32(0))); 6764 6765 assign(t4, binop(Iop_CmpLT32U, 6766 unop(Iop_8Uto32, 6767 unop(Iop_16HIto8, 6768 unop(Iop_32HIto16, 6769 getIReg(rs)))), 6770 unop(Iop_8Uto32, 6771 unop(Iop_16HIto8, 6772 unop(Iop_32HIto16, 6773 getIReg(rt)))))); 6774 assign(t8, IRExpr_ITE(mkexpr(t4), 6775 mkU32(0x00000008), mkU32(0))); 6776 putIReg(rd, binop(Iop_Or32, 6777 binop(Iop_Or32, 6778 binop(Iop_Or32, 6779 mkexpr(t5), mkexpr(t6)), 6780 mkexpr(t7)), 6781 mkexpr(t8))); 6782 break; 6783 } 6784 case 0x6: { /* CMPGU.LE.QB */ 6785 DIP("cmpgu.le.qb r%d, r%d, r%d", rd, rs, rt); 6786 vassert(!mode64); 6787 t1 = newTemp(Ity_I1); 6788 t2 = newTemp(Ity_I1); 6789 t3 = newTemp(Ity_I1); 6790 t4 = newTemp(Ity_I1); 6791 t5 = newTemp(Ity_I32); 6792 t6 = newTemp(Ity_I32); 6793 t7 = newTemp(Ity_I32); 6794 t8 = newTemp(Ity_I32); 6795 6796 assign(t1, binop(Iop_CmpLE32U, 6797 unop(Iop_8Uto32, 6798 unop(Iop_16to8, 6799 unop(Iop_32to16, getIReg(rs)))), 6800 unop(Iop_8Uto32, 6801 unop(Iop_16to8, 6802 unop(Iop_32to16, 6803 getIReg(rt)))))); 6804 assign(t5, IRExpr_ITE(mkexpr(t1), 6805 mkU32(0x00000001), mkU32(0))); 6806 6807 assign(t2, binop(Iop_CmpLE32U, 6808 unop(Iop_8Uto32, 6809 unop(Iop_16HIto8, 6810 unop(Iop_32to16, getIReg(rs)))), 6811 unop(Iop_8Uto32, 6812 unop(Iop_16HIto8, 6813 unop(Iop_32to16, 6814 getIReg(rt)))))); 6815 assign(t6, IRExpr_ITE(mkexpr(t2), 6816 mkU32(0x00000002), mkU32(0))); 6817 6818 assign(t3, binop(Iop_CmpLE32U, 6819 unop(Iop_8Uto32, 6820 unop(Iop_16to8, 6821 unop(Iop_32HIto16, 6822 getIReg(rs)))), 6823 unop(Iop_8Uto32, 6824 unop(Iop_16to8, 6825 unop(Iop_32HIto16, 6826 getIReg(rt)))))); 6827 assign(t7, IRExpr_ITE(mkexpr(t3), 6828 mkU32(0x00000004), mkU32(0))); 6829 6830 assign(t4, binop(Iop_CmpLE32U, 6831 unop(Iop_8Uto32, 6832 unop(Iop_16HIto8, 6833 unop(Iop_32HIto16, 6834 getIReg(rs)))), 6835 unop(Iop_8Uto32, 6836 unop(Iop_16HIto8, 6837 unop(Iop_32HIto16, 6838 getIReg(rt)))))); 6839 assign(t8, IRExpr_ITE(mkexpr(t4), 6840 mkU32(0x00000008), mkU32(0))); 6841 putIReg(rd, binop(Iop_Or32, 6842 binop(Iop_Or32, 6843 binop(Iop_Or32, 6844 mkexpr(t5), mkexpr(t6)), 6845 mkexpr(t7)), 6846 mkexpr(t8))); 6847 break; 6848 } 6849 case 0x8: { /* CMP.EQ.PH */ 6850 DIP("cmp.eq.ph r%d, r%d", rs, rt); 6851 vassert(!mode64); 6852 t1 = newTemp(Ity_I1); 6853 t2 = newTemp(Ity_I1); 6854 6855 assign(t1, binop(Iop_CmpEQ16, 6856 unop(Iop_32to16, getIReg(rs)), 6857 unop(Iop_32to16, getIReg(rt)))); 6858 putDSPControl(IRExpr_ITE(mkexpr(t1), 6859 binop(Iop_Or32, 6860 getDSPControl(), 6861 mkU32(0x01000000)), 6862 binop(Iop_And32, 6863 getDSPControl(), 6864 mkU32(0xfeffffff)))); 6865 assign(t2, binop(Iop_CmpEQ16, 6866 unop(Iop_32HIto16, getIReg(rs)), 6867 unop(Iop_32HIto16, getIReg(rt)))); 6868 putDSPControl(IRExpr_ITE(mkexpr(t2), 6869 binop(Iop_Or32, 6870 getDSPControl(), 6871 mkU32(0x02000000)), 6872 binop(Iop_And32, 6873 getDSPControl(), 6874 mkU32(0xfdffffff)))); 6875 break; 6876 } 6877 case 0x9: { /* CMP.LT.PH */ 6878 DIP("cmp.lt.ph r%d, r%d", rs, rt); 6879 vassert(!mode64); 6880 t1 = newTemp(Ity_I1); 6881 t2 = newTemp(Ity_I1); 6882 6883 assign(t1, binop(Iop_CmpLT32S, 6884 unop(Iop_16Sto32, 6885 unop(Iop_32to16, getIReg(rs))), 6886 unop(Iop_16Sto32, 6887 unop(Iop_32to16, getIReg(rt))))); 6888 putDSPControl(IRExpr_ITE(mkexpr(t1), 6889 binop(Iop_Or32, 6890 getDSPControl(), 6891 mkU32(0x01000000)), 6892 binop(Iop_And32, 6893 getDSPControl(), 6894 mkU32(0xfeffffff)))); 6895 6896 assign(t2, binop(Iop_CmpLT32S, 6897 unop(Iop_16Sto32, 6898 unop(Iop_32HIto16, getIReg(rs))), 6899 unop(Iop_16Sto32, 6900 unop(Iop_32HIto16, getIReg(rt))))); 6901 putDSPControl(IRExpr_ITE(mkexpr(t2), 6902 binop(Iop_Or32, 6903 getDSPControl(), 6904 mkU32(0x02000000)), 6905 binop(Iop_And32, 6906 getDSPControl(), 6907 mkU32(0xfdffffff)))); 6908 break; 6909 } 6910 case 0xA: { /* CMP.LE.PH */ 6911 DIP("cmp.le.ph r%d, r%d", rs, rt); 6912 vassert(!mode64); 6913 t1 = newTemp(Ity_I1); 6914 t2 = newTemp(Ity_I1); 6915 6916 assign(t1, binop(Iop_CmpLE32S, 6917 unop(Iop_16Sto32, 6918 unop(Iop_32to16, getIReg(rs))), 6919 unop(Iop_16Sto32, 6920 unop(Iop_32to16, getIReg(rt))))); 6921 putDSPControl(IRExpr_ITE(mkexpr(t1), 6922 binop(Iop_Or32, 6923 getDSPControl(), 6924 mkU32(0x01000000)), 6925 binop(Iop_And32, 6926 getDSPControl(), 6927 mkU32(0xfeffffff)))); 6928 6929 assign(t2, binop(Iop_CmpLE32S, 6930 unop(Iop_16Sto32, 6931 unop(Iop_32HIto16, getIReg(rs))), 6932 unop(Iop_16Sto32, 6933 unop(Iop_32HIto16, getIReg(rt))))); 6934 putDSPControl(IRExpr_ITE(mkexpr(t2), 6935 binop(Iop_Or32, 6936 getDSPControl(), 6937 mkU32(0x02000000)), 6938 binop(Iop_And32, 6939 getDSPControl(), 6940 mkU32(0xfdffffff)))); 6941 break; 6942 } 6943 case 0xB: { /* PICK.PH */ 6944 DIP("pick.qb r%d, r%d, r%d", rd, rs, rt); 6945 vassert(!mode64); 6946 t0 = newTemp(Ity_I32); 6947 t1 = newTemp(Ity_I16); 6948 t2 = newTemp(Ity_I16); 6949 6950 assign(t0, getDSPControl()); 6951 6952 assign(t1, IRExpr_ITE(binop(Iop_CmpNE32, 6953 binop(Iop_And32, 6954 mkexpr(t0), 6955 mkU32(0x01000000)), 6956 mkU32(0x0)), 6957 unop(Iop_32to16, getIReg(rs)), 6958 unop(Iop_32to16, getIReg(rt)))); 6959 6960 assign(t2, IRExpr_ITE(binop(Iop_CmpNE32, 6961 binop(Iop_And32, 6962 mkexpr(t0), 6963 mkU32(0x02000000)), 6964 mkU32(0x0)), 6965 unop(Iop_32HIto16, getIReg(rs)), 6966 unop(Iop_32HIto16, getIReg(rt)))); 6967 6968 putIReg(rd, binop(Iop_16HLto32, mkexpr(t2), mkexpr(t1))); 6969 break; 6970 } 6971 case 0xC: { /* PRECRQ.QB.PH */ 6972 DIP("precrq.qb.ph r%d, r%d, %d", rd, rs, rt); 6973 vassert(!mode64); 6974 putIReg(rd, 6975 binop(Iop_16HLto32, 6976 binop(Iop_8HLto16, 6977 unop(Iop_16HIto8, 6978 unop(Iop_32HIto16, getIReg(rs))), 6979 unop(Iop_16HIto8, 6980 unop(Iop_32to16, getIReg(rs)))), 6981 binop(Iop_8HLto16, 6982 unop(Iop_16HIto8, 6983 unop(Iop_32HIto16, getIReg(rt))), 6984 unop(Iop_16HIto8, 6985 unop(Iop_32to16, getIReg(rt)))))); 6986 break; 6987 } 6988 case 0xD: { /* PRECR.QB.PH */ 6989 DIP("precr.qb.ph r%d, r%d, r%d", rd, rs, rt); 6990 vassert(!mode64); 6991 6992 putIReg(rd, 6993 binop(Iop_16HLto32, 6994 binop(Iop_8HLto16, 6995 unop(Iop_16to8, 6996 unop(Iop_32HIto16, getIReg(rs))), 6997 unop(Iop_16to8, 6998 unop(Iop_32to16, getIReg(rs)))), 6999 binop(Iop_8HLto16, 7000 unop(Iop_16to8, 7001 unop(Iop_32HIto16, getIReg(rt))), 7002 unop(Iop_16to8, 7003 unop(Iop_32to16, getIReg(rt)))))); 7004 break; 7005 } 7006 case 0xF: { /* PRECRQU_S.QB.PH */ 7007 DIP("precrqu_s.qb.ph r%d, r%d, %d", rd, rs, rt); 7008 vassert(!mode64); 7009 t0 = newTemp(Ity_I8); 7010 t1 = newTemp(Ity_I8); 7011 t2 = newTemp(Ity_I8); 7012 t3 = newTemp(Ity_I8); 7013 t4 = newTemp(Ity_I8); 7014 t5 = newTemp(Ity_I32); 7015 t6 = newTemp(Ity_I1); 7016 t7 = newTemp(Ity_I8); 7017 t8 = newTemp(Ity_I1); 7018 t9 = newTemp(Ity_I32); 7019 t10 = newTemp(Ity_I8); 7020 t11 = newTemp(Ity_I1); 7021 t12 = newTemp(Ity_I32); 7022 t13 = newTemp(Ity_I8); 7023 t14 = newTemp(Ity_I1); 7024 t15 = newTemp(Ity_I32); 7025 7026 assign(t4, IRExpr_ITE(binop(Iop_CmpLT32U, 7027 mkU32(0x7f80), 7028 binop(Iop_And32, 7029 unop(Iop_16Uto32, 7030 unop(Iop_32to16, 7031 getIReg(rs))), 7032 mkU32(0x7fff))), 7033 mkU8(0xff), 7034 unop(Iop_16HIto8, 7035 unop(Iop_32to16, 7036 binop(Iop_Shl32, 7037 getIReg(rs), 7038 mkU8(1)))))); 7039 assign(t0, IRExpr_ITE(binop(Iop_CmpEQ32, 7040 binop(Iop_And32, 7041 unop(Iop_16Uto32, 7042 unop(Iop_32to16, 7043 getIReg(rs))), 7044 mkU32(0x00008000)), 7045 mkU32(0x0)), 7046 mkexpr(t4), 7047 mkU8(0x0))); 7048 assign(t5, binop(Iop_And32, 7049 unop(Iop_16Uto32, 7050 unop(Iop_32to16, 7051 getIReg(rs))), 7052 mkU32(0x00008000))); 7053 assign(t6, binop(Iop_CmpLT32U, 7054 mkU32(0x7f80), 7055 binop(Iop_And32, 7056 unop(Iop_16Uto32, 7057 unop(Iop_32to16, 7058 getIReg(rs))), 7059 mkU32(0x7fff)))); 7060 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 7061 mkexpr(t5), 7062 mkU32(0x0)), 7063 IRExpr_ITE(mkexpr(t6), 7064 binop(Iop_Or32, 7065 getDSPControl(), 7066 mkU32(0x00400000) 7067 ), 7068 getDSPControl()), 7069 binop(Iop_Or32, 7070 getDSPControl(), 7071 mkU32(0x00400000)))); 7072 7073 assign(t7, IRExpr_ITE(binop(Iop_CmpLT32U, 7074 mkU32(0x7f80), 7075 binop(Iop_And32, 7076 unop(Iop_16Uto32, 7077 unop(Iop_32HIto16, 7078 getIReg(rs))), 7079 mkU32(0x7fff))), 7080 mkU8(0xff), 7081 unop(Iop_16HIto8, 7082 unop(Iop_32HIto16, 7083 binop(Iop_Shl32, 7084 getIReg(rs), 7085 mkU8(1)))))); 7086 assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32, 7087 binop(Iop_And32, 7088 unop(Iop_16Uto32, 7089 unop(Iop_32HIto16, 7090 getIReg(rs))), 7091 mkU32(0x00008000)), 7092 mkU32(0x0)), 7093 mkexpr(t7), 7094 mkU8(0x0))); 7095 assign(t8, binop(Iop_CmpEQ32, 7096 binop(Iop_And32, 7097 unop(Iop_16Uto32, 7098 unop(Iop_32HIto16, 7099 getIReg(rs))), 7100 mkU32(0x00008000)), 7101 mkU32(0x0))); 7102 assign(t9, IRExpr_ITE(binop(Iop_CmpLT32U, 7103 mkU32(0x7f80), 7104 binop(Iop_And32, 7105 unop(Iop_16Uto32, 7106 unop(Iop_32HIto16, 7107 getIReg(rs))), 7108 mkU32(0x7fff))), 7109 binop(Iop_Or32, 7110 getDSPControl(), 7111 mkU32(0x00400000)), 7112 getDSPControl())); 7113 putDSPControl(IRExpr_ITE(mkexpr(t8), 7114 mkexpr(t9), 7115 binop(Iop_Or32, 7116 getDSPControl(), 7117 mkU32(0x00400000)))); 7118 7119 assign(t10, IRExpr_ITE(binop(Iop_CmpLT32U, 7120 mkU32(0x7f80), 7121 binop(Iop_And32, 7122 unop(Iop_16Uto32, 7123 unop(Iop_32to16, 7124 getIReg(rt))), 7125 mkU32(0x7fff))), 7126 mkU8(0xff), 7127 unop(Iop_16HIto8, 7128 unop(Iop_32to16, 7129 binop(Iop_Shl32, 7130 getIReg(rt), 7131 mkU8(1)))))); 7132 assign(t2, IRExpr_ITE(binop(Iop_CmpEQ32, 7133 binop(Iop_And32, 7134 unop(Iop_16Uto32, 7135 unop(Iop_32to16, 7136 getIReg(rt))), 7137 mkU32(0x00008000)), 7138 mkU32(0x0)), 7139 mkexpr(t10), 7140 mkU8(0x0))); 7141 assign(t11, binop(Iop_CmpEQ32, 7142 binop(Iop_And32, 7143 unop(Iop_16Uto32, 7144 unop(Iop_32to16, 7145 getIReg(rt))), 7146 mkU32(0x00008000)), 7147 mkU32(0x0))); 7148 assign(t12, IRExpr_ITE(binop(Iop_CmpLT32U, 7149 mkU32(0x7f80), 7150 binop(Iop_And32, 7151 unop(Iop_16Uto32, 7152 unop(Iop_32to16, 7153 getIReg(rt))), 7154 mkU32(0x7fff))), 7155 binop(Iop_Or32, 7156 getDSPControl(), 7157 mkU32(0x00400000)), 7158 getDSPControl())); 7159 putDSPControl(IRExpr_ITE(mkexpr(t11), 7160 mkexpr(t12), 7161 binop(Iop_Or32, 7162 getDSPControl(), 7163 mkU32(0x00400000)))); 7164 7165 assign(t13, IRExpr_ITE(binop(Iop_CmpLT32U, 7166 mkU32(0x7f80), 7167 binop(Iop_And32, 7168 unop(Iop_16Uto32, 7169 unop(Iop_32HIto16, 7170 getIReg(rt))), 7171 mkU32(0x7fff))), 7172 mkU8(0xff), 7173 unop(Iop_16HIto8, 7174 unop(Iop_32HIto16, 7175 binop(Iop_Shl32, 7176 getIReg(rt), 7177 mkU8(1)))))); 7178 assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32, 7179 binop(Iop_And32, 7180 unop(Iop_16Uto32, 7181 unop(Iop_32HIto16, 7182 getIReg(rt))), 7183 mkU32(0x00008000)), 7184 mkU32(0x0)), 7185 mkexpr(t13), 7186 mkU8(0x0))); 7187 assign(t14, binop(Iop_CmpEQ32, 7188 binop(Iop_And32, 7189 unop(Iop_16Uto32, 7190 unop(Iop_32HIto16, 7191 getIReg(rt))), 7192 mkU32(0x00008000)), 7193 mkU32(0x0))); 7194 assign(t15, IRExpr_ITE(binop(Iop_CmpLT32U, 7195 mkU32(0x7f80), 7196 binop(Iop_And32, 7197 unop(Iop_16Uto32, 7198 unop(Iop_32HIto16, 7199 getIReg(rt))), 7200 mkU32(0x7fff))), 7201 binop(Iop_Or32, 7202 getDSPControl(), 7203 mkU32(0x00400000)), 7204 getDSPControl())); 7205 putDSPControl(IRExpr_ITE(mkexpr(t14), 7206 mkexpr(t15), 7207 binop(Iop_Or32, 7208 getDSPControl(), 7209 mkU32(0x00400000)))); 7210 7211 putIReg(rd, binop(Iop_16HLto32, 7212 binop(Iop_8HLto16, 7213 mkexpr(t1), mkexpr(t0)), 7214 binop(Iop_8HLto16, 7215 mkexpr(t3), mkexpr(t2)))); 7216 break; 7217 } 7218 case 0x14: { /* PRECRQ.PH.W */ 7219 DIP("precrq.ph.w r%d, r%d, %d", rd, rs, rt); 7220 vassert(!mode64); 7221 putIReg(rd, binop(Iop_16HLto32, 7222 unop(Iop_32HIto16, getIReg(rs)), 7223 unop(Iop_32HIto16, getIReg(rt)))); 7224 break; 7225 } 7226 case 0x15: { /* PRECRQ_RS.PH.W */ 7227 DIP("precrq_rs.ph.w r%d, r%d, %d", rd, rs, rt); 7228 vassert(!mode64); 7229 t0 = newTemp(Ity_I64); 7230 t1 = newTemp(Ity_I1); 7231 t2 = newTemp(Ity_I32); 7232 t3 = newTemp(Ity_I64); 7233 t4 = newTemp(Ity_I1); 7234 t5 = newTemp(Ity_I32); 7235 7236 assign(t0, binop(Iop_Add64, 7237 binop(Iop_32HLto64, 7238 binop(Iop_Shr32, 7239 binop(Iop_And32, 7240 getIReg(rs), 7241 mkU32(0x80000000)), 7242 mkU8(31)), 7243 getIReg(rs)), 7244 mkU64(0x0000000000008000ULL))); 7245 assign(t1, binop(Iop_CmpNE32, 7246 binop(Iop_And32, 7247 unop(Iop_64HIto32, mkexpr(t0)), 7248 mkU32(0x1)), 7249 binop(Iop_And32, 7250 binop(Iop_Shr32, 7251 unop(Iop_64to32, mkexpr(t0)), 7252 mkU8(31)), 7253 mkU32(0x1)))); 7254 assign(t2, IRExpr_ITE(mkexpr(t1), 7255 mkU32(0x7fffffff), 7256 unop(Iop_64to32, mkexpr(t0)))); 7257 putDSPControl(IRExpr_ITE(mkexpr(t1), 7258 binop(Iop_Or32, 7259 getDSPControl(), 7260 mkU32(0x400000)), 7261 getDSPControl())); 7262 assign(t3, binop(Iop_Add64, 7263 binop(Iop_32HLto64, 7264 binop(Iop_Shr32, 7265 binop(Iop_And32, 7266 getIReg(rt), 7267 mkU32(0x80000000)), 7268 mkU8(31)), 7269 getIReg(rt)), 7270 mkU64(0x0000000000008000ULL))); 7271 assign(t4, binop(Iop_CmpNE32, 7272 binop(Iop_And32, 7273 unop(Iop_64HIto32, mkexpr(t3)), 7274 mkU32(0x1)), 7275 binop(Iop_And32, 7276 binop(Iop_Shr32, 7277 unop(Iop_64to32, mkexpr(t3)), 7278 mkU8(31)), 7279 mkU32(0x1)))); 7280 assign(t5, IRExpr_ITE(mkexpr(t4), 7281 mkU32(0x7fffffff), 7282 unop(Iop_64to32, mkexpr(t3)))); 7283 putDSPControl(IRExpr_ITE(mkexpr(t4), 7284 binop(Iop_Or32, 7285 getDSPControl(), 7286 mkU32(0x400000)), 7287 getDSPControl())); 7288 putIReg(rd, binop(Iop_16HLto32, 7289 unop(Iop_32HIto16, mkexpr(t2)), 7290 unop(Iop_32HIto16, mkexpr(t5)))); 7291 break; 7292 } 7293 case 0x1E: { /* PRECR_SRA.PH.W */ 7294 DIP("precr_sra.ph.w r%d, r%d, %d", rt, rs, rd); 7295 vassert(!mode64); 7296 7297 if (0 == rd) { 7298 putIReg(rt, binop(Iop_16HLto32, 7299 unop(Iop_32to16, getIReg(rt)), 7300 unop(Iop_32to16, getIReg(rs)))); 7301 } else { 7302 putIReg(rt, binop(Iop_16HLto32, 7303 unop(Iop_32to16, binop(Iop_Sar32, 7304 getIReg(rt), 7305 mkU8(rd))), 7306 unop(Iop_32to16, binop(Iop_Sar32, 7307 getIReg(rs), 7308 mkU8(rd))))); 7309 } 7310 break; 7311 } 7312 case 0x1F: { /* PRECR_SRA_R.PH.W */ 7313 DIP("precr_sra_r.ph.w r%d, r%d, %d", rt, rs, rd); 7314 vassert(!mode64); 7315 7316 t0 = newTemp(Ity_I32); 7317 t1 = newTemp(Ity_I32); 7318 7319 if (0 == rd) { 7320 putIReg(rt, binop(Iop_16HLto32, 7321 unop(Iop_32to16, getIReg(rt)), 7322 unop(Iop_32to16, getIReg(rs)))); 7323 } else { 7324 assign(t0, binop(Iop_Shr32, 7325 binop(Iop_Add32, 7326 binop(Iop_Sar32, 7327 getIReg(rt), 7328 mkU8(rd-1)), 7329 mkU32(0x1)), 7330 mkU8(0x1))); 7331 assign(t1, binop(Iop_Shr32, 7332 binop(Iop_Add32, 7333 binop(Iop_Sar32, 7334 getIReg(rs), 7335 mkU8(rd-1)), 7336 mkU32(0x1)), 7337 mkU8(0x1))); 7338 putIReg(rt, binop(Iop_16HLto32, 7339 unop(Iop_32to16, mkexpr(t0)), 7340 unop(Iop_32to16, mkexpr(t1)))); 7341 }; 7342 break; 7343 } 7344 case 0xE: { /* PACKRL.PH */ 7345 DIP("packrl.ph r%d, r%d, r%d", rd, rs, rt); 7346 vassert(!mode64); 7347 7348 putIReg(rd, binop(Iop_16HLto32, 7349 unop(Iop_32to16, getIReg(rs)), 7350 unop(Iop_32HIto16, getIReg(rt)))); 7351 break; 7352 } 7353 case 0x18: { /* CMPGDU.EQ.QB */ 7354 DIP("cmpgdu.eq.qb r%d, r%d, r%d", rd, rs, rt); 7355 vassert(!mode64); 7356 t1 = newTemp(Ity_I1); 7357 t2 = newTemp(Ity_I1); 7358 t3 = newTemp(Ity_I1); 7359 t4 = newTemp(Ity_I1); 7360 t5 = newTemp(Ity_I32); 7361 t6 = newTemp(Ity_I32); 7362 t7 = newTemp(Ity_I32); 7363 t8 = newTemp(Ity_I32); 7364 7365 assign(t1, 7366 binop(Iop_CmpEQ32, 7367 unop(Iop_8Uto32, 7368 unop(Iop_16to8, 7369 unop(Iop_32to16, getIReg(rs)))), 7370 unop(Iop_8Uto32, 7371 unop(Iop_16to8, 7372 unop(Iop_32to16, getIReg(rt)))))); 7373 assign(t5, IRExpr_ITE(mkexpr(t1), 7374 mkU32(0x00000001), mkU32(0))); 7375 putDSPControl(IRExpr_ITE(mkexpr(t1), 7376 binop(Iop_Or32, 7377 getDSPControl(), 7378 mkU32(0x01000000)), 7379 binop(Iop_And32, 7380 getDSPControl(), 7381 mkU32(0xfeffffff)))); 7382 7383 assign(t2, binop(Iop_CmpEQ32, 7384 unop(Iop_8Uto32, 7385 unop(Iop_16HIto8, 7386 unop(Iop_32to16, getIReg(rs)))), 7387 unop(Iop_8Uto32, 7388 unop(Iop_16HIto8, 7389 unop(Iop_32to16, 7390 getIReg(rt)))))); 7391 assign(t6, IRExpr_ITE(mkexpr(t2), 7392 mkU32(0x00000002), mkU32(0))); 7393 putDSPControl(IRExpr_ITE(mkexpr(t2), 7394 binop(Iop_Or32, 7395 getDSPControl(), 7396 mkU32(0x02000000)), 7397 binop(Iop_And32, 7398 getDSPControl(), 7399 mkU32(0xfdffffff)))); 7400 7401 assign(t3, binop(Iop_CmpEQ32, 7402 unop(Iop_8Uto32, 7403 unop(Iop_16to8, 7404 unop(Iop_32HIto16, 7405 getIReg(rs)))), 7406 unop(Iop_8Uto32, 7407 unop(Iop_16to8, 7408 unop(Iop_32HIto16, 7409 getIReg(rt)))))); 7410 assign(t7, IRExpr_ITE(mkexpr(t3), 7411 mkU32(0x00000004), mkU32(0))); 7412 putDSPControl(IRExpr_ITE(mkexpr(t3), 7413 binop(Iop_Or32, 7414 getDSPControl(), 7415 mkU32(0x04000000)), 7416 binop(Iop_And32, 7417 getDSPControl(), 7418 mkU32(0xfbffffff)))); 7419 7420 assign(t4, binop(Iop_CmpEQ32, 7421 unop(Iop_8Uto32, 7422 unop(Iop_16HIto8, 7423 unop(Iop_32HIto16, 7424 getIReg(rs)))), 7425 unop(Iop_8Uto32, 7426 unop(Iop_16HIto8, 7427 unop(Iop_32HIto16, 7428 getIReg(rt)))))); 7429 assign(t8, IRExpr_ITE(mkexpr(t4), 7430 mkU32(0x00000008), mkU32(0))); 7431 putDSPControl(IRExpr_ITE(mkexpr(t4), 7432 binop(Iop_Or32, 7433 getDSPControl(), 7434 mkU32(0x08000000)), 7435 binop(Iop_And32, 7436 getDSPControl(), 7437 mkU32(0xf7ffffff)))); 7438 7439 putIReg(rd, binop(Iop_Or32, 7440 binop(Iop_Or32, 7441 binop(Iop_Or32, 7442 mkexpr(t5), mkexpr(t6)), 7443 mkexpr(t7)), 7444 mkexpr(t8))); 7445 break; 7446 } 7447 case 0x19: { /* CMPGDU.LT.QB */ 7448 DIP("cmpgdu.lt.qb r%d, r%d, r%d", rd, rs, rt); 7449 vassert(!mode64); 7450 t1 = newTemp(Ity_I1); 7451 t2 = newTemp(Ity_I1); 7452 t3 = newTemp(Ity_I1); 7453 t4 = newTemp(Ity_I1); 7454 t5 = newTemp(Ity_I32); 7455 t6 = newTemp(Ity_I32); 7456 t7 = newTemp(Ity_I32); 7457 t8 = newTemp(Ity_I32); 7458 7459 assign(t1, binop(Iop_CmpLT32U, 7460 unop(Iop_8Uto32, 7461 unop(Iop_16to8, 7462 unop(Iop_32to16, getIReg(rs)))), 7463 unop(Iop_8Uto32, 7464 unop(Iop_16to8, 7465 unop(Iop_32to16, 7466 getIReg(rt)))))); 7467 assign(t5, IRExpr_ITE(mkexpr(t1), 7468 mkU32(0x00000001), mkU32(0))); 7469 putDSPControl(IRExpr_ITE(mkexpr(t1), 7470 binop(Iop_Or32, 7471 getDSPControl(), 7472 mkU32(0x01000000)), 7473 binop(Iop_And32, 7474 getDSPControl(), 7475 mkU32(0xfeffffff)))); 7476 7477 assign(t2, binop(Iop_CmpLT32U, 7478 unop(Iop_8Uto32, 7479 unop(Iop_16HIto8, 7480 unop(Iop_32to16, getIReg(rs)))), 7481 unop(Iop_8Uto32, 7482 unop(Iop_16HIto8, 7483 unop(Iop_32to16, 7484 getIReg(rt)))))); 7485 assign(t6, IRExpr_ITE(mkexpr(t2), 7486 mkU32(0x00000002), mkU32(0))); 7487 putDSPControl(IRExpr_ITE(mkexpr(t2), 7488 binop(Iop_Or32, 7489 getDSPControl(), 7490 mkU32(0x02000000)), 7491 binop(Iop_And32, 7492 getDSPControl(), 7493 mkU32(0xfdffffff)))); 7494 7495 assign(t3, binop(Iop_CmpLT32U, 7496 unop(Iop_8Uto32, 7497 unop(Iop_16to8, 7498 unop(Iop_32HIto16, 7499 getIReg(rs)))), 7500 unop(Iop_8Uto32, 7501 unop(Iop_16to8, 7502 unop(Iop_32HIto16, 7503 getIReg(rt)))))); 7504 assign(t7, IRExpr_ITE(mkexpr(t3), 7505 mkU32(0x00000004), mkU32(0))); 7506 putDSPControl(IRExpr_ITE(mkexpr(t3), 7507 binop(Iop_Or32, 7508 getDSPControl(), 7509 mkU32(0x04000000)), 7510 binop(Iop_And32, 7511 getDSPControl(), 7512 mkU32(0xfbffffff)))); 7513 7514 assign(t4, binop(Iop_CmpLT32U, 7515 unop(Iop_8Uto32, 7516 unop(Iop_16HIto8, 7517 unop(Iop_32HIto16, 7518 getIReg(rs)))), 7519 unop(Iop_8Uto32, 7520 unop(Iop_16HIto8, 7521 unop(Iop_32HIto16, 7522 getIReg(rt)))))); 7523 assign(t8, IRExpr_ITE(mkexpr(t4), 7524 mkU32(0x00000008), mkU32(0))); 7525 putDSPControl(IRExpr_ITE(mkexpr(t4), 7526 binop(Iop_Or32, 7527 getDSPControl(), 7528 mkU32(0x08000000)), 7529 binop(Iop_And32, 7530 getDSPControl(), 7531 mkU32(0xf7ffffff)))); 7532 7533 putIReg(rd, binop(Iop_Or32, 7534 binop(Iop_Or32, 7535 binop(Iop_Or32, 7536 mkexpr(t5), mkexpr(t6)), 7537 mkexpr(t7)), 7538 mkexpr(t8))); 7539 break; 7540 } 7541 case 0x1A: { /* CMPGDU.LE.QB */ 7542 DIP("cmpgdu.le.qb r%d, r%d, r%d", rd, rs, rt); 7543 vassert(!mode64); 7544 t1 = newTemp(Ity_I1); 7545 t2 = newTemp(Ity_I1); 7546 t3 = newTemp(Ity_I1); 7547 t4 = newTemp(Ity_I1); 7548 t5 = newTemp(Ity_I32); 7549 t6 = newTemp(Ity_I32); 7550 t7 = newTemp(Ity_I32); 7551 t8 = newTemp(Ity_I32); 7552 7553 assign(t1, binop(Iop_CmpLE32U, 7554 unop(Iop_8Uto32, 7555 unop(Iop_16to8, 7556 unop(Iop_32to16, getIReg(rs)))), 7557 unop(Iop_8Uto32, 7558 unop(Iop_16to8, 7559 unop(Iop_32to16, 7560 getIReg(rt)))))); 7561 assign(t5, IRExpr_ITE(mkexpr(t1), 7562 mkU32(0x00000001), 7563 mkU32(0))); 7564 putDSPControl(IRExpr_ITE(mkexpr(t1), 7565 binop(Iop_Or32, 7566 getDSPControl(), 7567 mkU32(0x01000000)), 7568 binop(Iop_And32, 7569 getDSPControl(), 7570 mkU32(0xfeffffff)))); 7571 7572 assign(t2, binop(Iop_CmpLE32U, 7573 unop(Iop_8Uto32, 7574 unop(Iop_16HIto8, 7575 unop(Iop_32to16, getIReg(rs)))), 7576 unop(Iop_8Uto32, 7577 unop(Iop_16HIto8, 7578 unop(Iop_32to16, 7579 getIReg(rt)))))); 7580 assign(t6, IRExpr_ITE(mkexpr(t2), 7581 mkU32(0x00000002), mkU32(0))); 7582 putDSPControl(IRExpr_ITE(mkexpr(t2), 7583 binop(Iop_Or32, 7584 getDSPControl(), 7585 mkU32(0x02000000)), 7586 binop(Iop_And32, 7587 getDSPControl(), 7588 mkU32(0xfdffffff)))); 7589 7590 assign(t3, binop(Iop_CmpLE32U, 7591 unop(Iop_8Uto32, 7592 unop(Iop_16to8, 7593 unop(Iop_32HIto16, 7594 getIReg(rs)))), 7595 unop(Iop_8Uto32, 7596 unop(Iop_16to8, 7597 unop(Iop_32HIto16, 7598 getIReg(rt)))))); 7599 assign(t7, IRExpr_ITE(mkexpr(t3), 7600 mkU32(0x00000004), mkU32(0))); 7601 putDSPControl(IRExpr_ITE(mkexpr(t3), 7602 binop(Iop_Or32, 7603 getDSPControl(), 7604 mkU32(0x04000000)), 7605 binop(Iop_And32, 7606 getDSPControl(), 7607 mkU32(0xfbffffff)))); 7608 7609 assign(t4, binop(Iop_CmpLE32U, 7610 unop(Iop_8Uto32, 7611 unop(Iop_16HIto8, 7612 unop(Iop_32HIto16, 7613 getIReg(rs)))), 7614 unop(Iop_8Uto32, 7615 unop(Iop_16HIto8, 7616 unop(Iop_32HIto16, 7617 getIReg(rt)))))); 7618 assign(t8, IRExpr_ITE(mkexpr(t4), 7619 mkU32(0x00000008), mkU32(0))); 7620 putDSPControl(IRExpr_ITE(mkexpr(t4), 7621 binop(Iop_Or32, 7622 getDSPControl(), 7623 mkU32(0x08000000)), 7624 binop(Iop_And32, 7625 getDSPControl(), 7626 mkU32(0xf7ffffff)))); 7627 7628 putIReg(rd, binop(Iop_Or32, 7629 binop(Iop_Or32, 7630 binop(Iop_Or32, 7631 mkexpr(t5), mkexpr(t6)), 7632 mkexpr(t7)), 7633 mkexpr(t8))); 7634 break; 7635 } 7636 default: 7637 return -1; 7638 } 7639 break; /* end of CMPU.EQ.QB */ 7640 } 7641 case 0x13: { /* SHLL.QB */ 7642 switch(sa) { 7643 case 0x0: { /* SHLL.QB */ 7644 DIP("shll.qb r%d, r%d, %d", rd, rt, rs); 7645 vassert(!mode64); 7646 t0 = newTemp(Ity_I32); 7647 t1 = newTemp(Ity_I1); 7648 t2 = newTemp(Ity_I1); 7649 t3 = newTemp(Ity_I32); 7650 t4 = newTemp(Ity_I1); 7651 t5 = newTemp(Ity_I1); 7652 t6 = newTemp(Ity_I32); 7653 t7 = newTemp(Ity_I1); 7654 t8 = newTemp(Ity_I1); 7655 t9 = newTemp(Ity_I1); 7656 t10 = newTemp(Ity_I1); 7657 7658 if (0 == rs) { 7659 putIReg(rd, getIReg(rt)); 7660 } else { 7661 /* Shift bits 7..0 and 23..16. */ 7662 assign(t0, binop(Iop_Shl32, 7663 binop(Iop_And32, 7664 getIReg(rt), 7665 mkU32(0x00ff00ff)), 7666 mkU8(rs))); 7667 assign(t1, binop(Iop_CmpNE32, 7668 binop(Iop_And32, 7669 mkexpr(t0), 7670 mkU32(0xff000000)), 7671 mkU32(0x00000000))); 7672 assign(t2, binop(Iop_CmpNE32, 7673 binop(Iop_And32, 7674 mkexpr(t0), 7675 mkU32(0xff000000)), 7676 mkU32(0xff000000))); 7677 assign(t7, binop(Iop_CmpNE32, 7678 binop(Iop_And32, 7679 mkexpr(t0), 7680 mkU32(0x0000ff00)), 7681 mkU32(0x00000000))); 7682 assign(t8, binop(Iop_CmpNE32, 7683 binop(Iop_And32, 7684 mkexpr(t0), 7685 mkU32(0x0000ff00)), 7686 mkU32(0x000ff00))); 7687 /* Shift bits 15..8 and 31..24. */ 7688 assign(t3, binop(Iop_Shl32, 7689 binop(Iop_Shr32, 7690 binop(Iop_And32, 7691 getIReg(rt), 7692 mkU32(0xff00ff00)), 7693 mkU8(8)), 7694 mkU8(rs))); 7695 assign(t4, binop(Iop_CmpNE32, 7696 binop(Iop_And32, 7697 mkexpr(t3), 7698 mkU32(0xff000000)), 7699 mkU32(0x00000000))); 7700 assign(t5, binop(Iop_CmpNE32, 7701 binop(Iop_And32, 7702 mkexpr(t3), 7703 mkU32(0xff000000)), 7704 mkU32(0xff000000))); 7705 assign(t9, binop(Iop_CmpNE32, 7706 binop(Iop_And32, 7707 mkexpr(t3), 7708 mkU32(0x0000ff00)), 7709 mkU32(0x00000000))); 7710 assign(t10, binop(Iop_CmpNE32, 7711 binop(Iop_And32, 7712 mkexpr(t3), 7713 mkU32(0x0000ff00)), 7714 mkU32(0x0000ff00))); 7715 7716 assign(t6, binop(Iop_Or32, 7717 binop(Iop_Or32, 7718 binop(Iop_And32, 7719 unop(Iop_1Uto32, 7720 mkexpr(t1)), 7721 unop(Iop_1Uto32, 7722 mkexpr(t2))), 7723 binop(Iop_And32, 7724 unop(Iop_1Uto32, 7725 mkexpr(t7)), 7726 unop(Iop_1Uto32, 7727 mkexpr(t8)))), 7728 binop(Iop_Or32, 7729 binop(Iop_And32, 7730 unop(Iop_1Uto32, 7731 mkexpr(t4)), 7732 unop(Iop_1Uto32, 7733 mkexpr(t5))), 7734 binop(Iop_And32, 7735 unop(Iop_1Uto32, 7736 mkexpr(t9)), 7737 unop(Iop_1Uto32, 7738 mkexpr(t10)))))); 7739 7740 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 7741 mkexpr(t6), 7742 mkU32(0x0)), 7743 binop(Iop_Or32, 7744 getDSPControl(), 7745 mkU32(0x400000)), 7746 getDSPControl())); 7747 putIReg(rd, binop(Iop_Or32, 7748 binop(Iop_Shl32, 7749 binop(Iop_And32, 7750 mkexpr(t3), 7751 mkU32(0x00ff00ff)), 7752 mkU8(8)), 7753 binop(Iop_And32, 7754 mkexpr(t0), 7755 mkU32(0x00ff00ff)))); 7756 } 7757 break; 7758 } 7759 case 0x3: { /* SHRL.QB */ 7760 DIP("shrl.qb r%d, r%d, %d", rd, rt, rs); 7761 vassert(!mode64); 7762 t0 = newTemp(Ity_I32); 7763 t1 = newTemp(Ity_I8); 7764 t2 = newTemp(Ity_I32); 7765 t3 = newTemp(Ity_I8); 7766 t4 = newTemp(Ity_I32); 7767 t5 = newTemp(Ity_I8); 7768 t6 = newTemp(Ity_I32); 7769 t7 = newTemp(Ity_I8); 7770 t9 = newTemp(Ity_I32); 7771 7772 assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7))); 7773 assign(t0, unop(Iop_8Uto32, 7774 unop(Iop_16to8, 7775 unop(Iop_32to16, getIReg(rt))))); 7776 assign(t1, unop(Iop_32to8, 7777 binop(Iop_Shr32, 7778 mkexpr(t0), 7779 unop(Iop_32to8, mkexpr(t9))))); 7780 7781 assign(t2, unop(Iop_8Uto32, 7782 unop(Iop_16HIto8, 7783 unop(Iop_32to16, getIReg(rt))))); 7784 assign(t3, unop(Iop_32to8, 7785 binop(Iop_Shr32, 7786 mkexpr(t2), 7787 unop(Iop_32to8, mkexpr(t9))))); 7788 7789 assign(t4, unop(Iop_8Uto32, 7790 unop(Iop_16to8, 7791 unop(Iop_32HIto16, getIReg(rt))))); 7792 assign(t5, unop(Iop_32to8, 7793 binop(Iop_Shr32, 7794 mkexpr(t4), 7795 unop(Iop_32to8, mkexpr(t9))))); 7796 7797 assign(t6, unop(Iop_8Uto32, 7798 unop(Iop_16HIto8, 7799 unop(Iop_32HIto16, getIReg(rt))))); 7800 assign(t7, unop(Iop_32to8, 7801 binop(Iop_Shr32, 7802 mkexpr(t6), 7803 unop(Iop_32to8, mkexpr(t9))))); 7804 putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32, 7805 mkexpr(t9), 7806 mkU32(0x0)), 7807 getIReg(rt), 7808 binop(Iop_16HLto32, 7809 binop(Iop_8HLto16, 7810 mkexpr(t7), 7811 mkexpr(t5)), 7812 binop(Iop_8HLto16, 7813 mkexpr(t3), 7814 mkexpr(t1))))); 7815 break; 7816 } 7817 case 0x2: { /* SHLLV.QB */ 7818 DIP("shllv.qb r%d, r%d, r%d", rd, rt, rs); 7819 vassert(!mode64); 7820 t0 = newTemp(Ity_I32); 7821 t1 = newTemp(Ity_I1); 7822 t2 = newTemp(Ity_I1); 7823 t3 = newTemp(Ity_I32); 7824 t4 = newTemp(Ity_I1); 7825 t5 = newTemp(Ity_I1); 7826 t6 = newTemp(Ity_I32); 7827 t7 = newTemp(Ity_I1); 7828 t8 = newTemp(Ity_I1); 7829 t9 = newTemp(Ity_I1); 7830 t10 = newTemp(Ity_I1); 7831 t11 = newTemp(Ity_I8); 7832 7833 assign(t11, unop(Iop_32to8, 7834 binop(Iop_And32, 7835 getIReg(rs), 7836 mkU32(0x7)))); 7837 /* Shift bits 7..0 and 23..16. */ 7838 assign(t0, binop(Iop_Shl32, 7839 binop(Iop_And32, 7840 getIReg(rt), 7841 mkU32(0x00ff00ff)), 7842 mkexpr(t11))); 7843 assign(t1, binop(Iop_CmpNE32, 7844 binop(Iop_And32, 7845 mkexpr(t0), 7846 mkU32(0xff000000)), 7847 mkU32(0x00000000))); 7848 assign(t2, binop(Iop_CmpNE32, 7849 binop(Iop_And32, 7850 mkexpr(t0), 7851 mkU32(0xff000000)), 7852 mkU32(0xff000000))); 7853 assign(t7, binop(Iop_CmpNE32, 7854 binop(Iop_And32, 7855 mkexpr(t0), 7856 mkU32(0x0000ff00)), 7857 mkU32(0x00000000))); 7858 assign(t8, binop(Iop_CmpNE32, 7859 binop(Iop_And32, 7860 mkexpr(t0), 7861 mkU32(0x0000ff00)), 7862 mkU32(0x000ff00))); 7863 /* Shift bits 15..8 and 31..24. */ 7864 assign(t3, binop(Iop_Shl32, 7865 binop(Iop_Shr32, 7866 binop(Iop_And32, 7867 getIReg(rt), 7868 mkU32(0xff00ff00)), 7869 mkU8(8)), 7870 mkexpr(t11))); 7871 assign(t4, binop(Iop_CmpNE32, 7872 binop(Iop_And32, 7873 mkexpr(t3), 7874 mkU32(0xff000000)), 7875 mkU32(0x00000000))); 7876 assign(t5, binop(Iop_CmpNE32, 7877 binop(Iop_And32, 7878 mkexpr(t3), 7879 mkU32(0xff000000)), 7880 mkU32(0xff000000))); 7881 assign(t9, binop(Iop_CmpNE32, 7882 binop(Iop_And32, 7883 mkexpr(t3), 7884 mkU32(0x0000ff00)), 7885 mkU32(0x00000000))); 7886 assign(t10, binop(Iop_CmpNE32, 7887 binop(Iop_And32, 7888 mkexpr(t3), 7889 mkU32(0x0000ff00)), 7890 mkU32(0x0000ff00))); 7891 7892 assign(t6, binop(Iop_Or32, 7893 binop(Iop_Or32, 7894 binop(Iop_And32, 7895 unop(Iop_1Uto32, 7896 mkexpr(t1)), 7897 unop(Iop_1Uto32, 7898 mkexpr(t2))), 7899 binop(Iop_And32, 7900 unop(Iop_1Uto32, 7901 mkexpr(t7)), 7902 unop(Iop_1Uto32, 7903 mkexpr(t8)))), 7904 binop(Iop_Or32, 7905 binop(Iop_And32, 7906 unop(Iop_1Uto32, 7907 mkexpr(t4)), 7908 unop(Iop_1Uto32, 7909 mkexpr(t5))), 7910 binop(Iop_And32, 7911 unop(Iop_1Uto32, 7912 mkexpr(t9)), 7913 unop(Iop_1Uto32, 7914 mkexpr(t10)))))); 7915 7916 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 7917 mkexpr(t6), 7918 mkU32(0x0)), 7919 binop(Iop_Or32, 7920 getDSPControl(), 7921 mkU32(0x400000)), 7922 getDSPControl())); 7923 putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32, 7924 unop(Iop_8Uto32, mkexpr(t11)), 7925 mkU32(0)), 7926 getIReg(rt), 7927 binop(Iop_Or32, 7928 binop(Iop_Shl32, 7929 binop(Iop_And32, 7930 mkexpr(t3), 7931 mkU32(0xff00ff)), 7932 mkU8(8)), 7933 binop(Iop_And32, 7934 mkexpr(t0), 7935 mkU32(0x00ff00ff))))); 7936 break; 7937 } 7938 case 0x1: { /* SHRLV.QB */ 7939 DIP("shrlv.qb r%d, r%d, r%d", rd, rt, rs); 7940 vassert(!mode64); 7941 t0 = newTemp(Ity_I8); 7942 t1 = newTemp(Ity_I8); 7943 t2 = newTemp(Ity_I8); 7944 t3 = newTemp(Ity_I8); 7945 7946 assign(t0, unop(Iop_32to8, 7947 binop(Iop_Shr32, 7948 unop(Iop_8Uto32, 7949 unop(Iop_32to8, getIReg(rt))), 7950 mkU8(rs)))); 7951 assign(t1, unop(Iop_32to8, 7952 binop(Iop_Shr32, 7953 unop(Iop_8Uto32, 7954 unop(Iop_16HIto8, 7955 unop(Iop_32to16, 7956 getIReg(rt)))), 7957 mkU8(rs)))); 7958 assign(t2, unop(Iop_32to8, 7959 binop(Iop_Shr32, 7960 unop(Iop_8Uto32, 7961 unop(Iop_16to8, 7962 unop(Iop_32HIto16, 7963 getIReg(rt)))), 7964 mkU8(rs)))); 7965 assign(t3, unop(Iop_32to8, 7966 binop(Iop_Shr32, 7967 unop(Iop_8Uto32, 7968 unop(Iop_16HIto8, 7969 unop(Iop_32HIto16, 7970 getIReg(rt)))), 7971 mkU8(rs)))); 7972 putIReg(rd, 7973 binop(Iop_16HLto32, 7974 binop(Iop_8HLto16, mkexpr(t3), mkexpr(t2)), 7975 binop(Iop_8HLto16, mkexpr(t1), mkexpr(t0)))); 7976 break; 7977 } 7978 case 0x4: { /* SHRA.QB */ 7979 DIP("shra.qb r%d, r%d, %d", rd, rt, rs); 7980 vassert(!mode64); 7981 t0 = newTemp(Ity_I32); 7982 t1 = newTemp(Ity_I32); 7983 t2 = newTemp(Ity_I32); 7984 t3 = newTemp(Ity_I32); 7985 t4 = newTemp(Ity_I32); 7986 t5 = newTemp(Ity_I32); 7987 t6 = newTemp(Ity_I32); 7988 t7 = newTemp(Ity_I32); 7989 t8 = newTemp(Ity_I32); 7990 t9 = newTemp(Ity_I32); 7991 t10 = newTemp(Ity_I32); 7992 t11 = newTemp(Ity_I32); 7993 7994 /* ========== GPR[rt]_31..24 ========== */ 7995 assign(t1, 7996 unop(Iop_8Uto32, 7997 unop(Iop_16HIto8, 7998 unop(Iop_32HIto16, getIReg(rt))))); 7999 assign(t2, 8000 binop(Iop_Shr32, mkexpr(t1), mkU8(rs))); 8001 /* tempD_7..0 */ 8002 assign(t0, 8003 binop(Iop_Or32, 8004 mkexpr(t2), 8005 binop(Iop_Shl32, 8006 IRExpr_ITE(binop(Iop_CmpEQ32, 8007 binop(Iop_And32, 8008 mkexpr(t1), 8009 mkU32(0x00000080) 8010 ), 8011 mkU32(0x00000080)), 8012 mkU32(0xFFFFFFFF), 8013 mkU32(0x00000000)), 8014 binop(Iop_Sub8, mkU8(0x8), mkU8(rs))))); 8015 8016 /* ========== GPR[rt]_23..16 ========== */ 8017 assign(t4, 8018 unop(Iop_8Uto32, 8019 unop(Iop_16to8, 8020 unop(Iop_32HIto16, getIReg(rt))))); 8021 assign(t5, binop(Iop_Shr32, mkexpr(t4), mkU8(rs))); 8022 /* tempC_7..0 */ 8023 assign(t3, 8024 binop(Iop_Or32, 8025 mkexpr(t5), 8026 binop(Iop_Shl32, 8027 IRExpr_ITE(binop(Iop_CmpEQ32, 8028 binop(Iop_And32, 8029 mkexpr(t4), 8030 mkU32(0x00000080) 8031 ), 8032 mkU32(0x00000080)), 8033 mkU32(0xFFFFFFFF), 8034 mkU32(0x00000000)), 8035 binop(Iop_Sub8, mkU8(0x8), mkU8(rs))))); 8036 8037 /* ========== GPR[rt]_15..8 ========== */ 8038 assign(t7, 8039 unop(Iop_8Uto32, 8040 unop(Iop_16HIto8, 8041 unop(Iop_32to16, getIReg(rt))))); 8042 assign(t8, binop(Iop_Shr32, mkexpr(t7), mkU8(rs))); 8043 /* tempB_7..0 */ 8044 assign(t6, 8045 binop(Iop_Or32, 8046 mkexpr(t8), 8047 binop(Iop_Shl32, 8048 IRExpr_ITE(binop(Iop_CmpEQ32, 8049 binop(Iop_And32, 8050 mkexpr(t7), 8051 mkU32(0x00000080) 8052 ), 8053 mkU32(0x00000080)), 8054 mkU32(0xFFFFFFFF), 8055 mkU32(0x00000000)), 8056 binop(Iop_Sub8, mkU8(0x8), mkU8(rs))))); 8057 8058 /* ========== GPR[rt]_7..0 ========== */ 8059 assign(t10, 8060 unop(Iop_8Uto32, 8061 unop(Iop_16to8, 8062 unop(Iop_32to16, getIReg(rt))))); 8063 assign(t11, binop(Iop_Shr32, mkexpr(t10), mkU8(rs))); 8064 /* tempB_7..0 */ 8065 assign(t9, 8066 binop(Iop_Or32, 8067 mkexpr(t11), 8068 binop(Iop_Shl32, 8069 IRExpr_ITE(binop(Iop_CmpEQ32, 8070 binop(Iop_And32, 8071 mkexpr(t10), 8072 mkU32(0x00000080) 8073 ), 8074 mkU32(0x00000080)), 8075 mkU32(0xFFFFFFFF), 8076 mkU32(0x00000000)), 8077 binop(Iop_Sub8, mkU8(0x8), mkU8(rs))))); 8078 8079 putIReg(rd, 8080 binop(Iop_16HLto32, 8081 binop(Iop_8HLto16, 8082 unop(Iop_32to8, mkexpr(t0)), 8083 unop(Iop_32to8, mkexpr(t3))), 8084 binop(Iop_8HLto16, 8085 unop(Iop_32to8, mkexpr(t6)), 8086 unop(Iop_32to8, mkexpr(t9))))); 8087 break; 8088 } 8089 case 0x5: { /* SHRA_R.QB */ 8090 DIP("shra_r.qb r%d, r%d, %d", rd, rt, rs); 8091 vassert(!mode64); 8092 t0 = newTemp(Ity_I32); 8093 t1 = newTemp(Ity_I8); 8094 t2 = newTemp(Ity_I32); 8095 t3 = newTemp(Ity_I8); 8096 t4 = newTemp(Ity_I32); 8097 t5 = newTemp(Ity_I8); 8098 t6 = newTemp(Ity_I32); 8099 t7 = newTemp(Ity_I8); 8100 8101 if (0 == rs) { 8102 putIReg(rd, getIReg(rt)); 8103 } else { 8104 assign(t0, unop(Iop_8Sto32, 8105 unop(Iop_16to8, 8106 unop(Iop_32to16, getIReg(rt))))); 8107 assign(t1, unop(Iop_32to8, 8108 binop(Iop_Sar32, 8109 binop(Iop_Add32, 8110 mkexpr(t0), 8111 binop(Iop_Shl32, 8112 mkU32(0x1), 8113 mkU8(rs-1))), 8114 mkU8(rs)))); 8115 8116 assign(t2, unop(Iop_8Sto32, 8117 unop(Iop_16HIto8, 8118 unop(Iop_32to16, getIReg(rt))))); 8119 assign(t3, unop(Iop_32to8, 8120 binop(Iop_Sar32, 8121 binop(Iop_Add32, 8122 mkexpr(t2), 8123 binop(Iop_Shl32, 8124 mkU32(0x1), 8125 mkU8(rs-1))), 8126 mkU8(rs)))); 8127 8128 assign(t4, unop(Iop_8Sto32, 8129 unop(Iop_16to8, 8130 unop(Iop_32HIto16, getIReg(rt))))); 8131 assign(t5, unop(Iop_32to8, 8132 binop(Iop_Sar32, 8133 binop(Iop_Add32, 8134 mkexpr(t4), 8135 binop(Iop_Shl32, 8136 mkU32(0x1), 8137 mkU8(rs-1))), 8138 mkU8(rs)))); 8139 8140 assign(t6, unop(Iop_8Sto32, 8141 unop(Iop_16HIto8, 8142 unop(Iop_32HIto16, getIReg(rt))))); 8143 assign(t7, unop(Iop_32to8, 8144 binop(Iop_Sar32, 8145 binop(Iop_Add32, 8146 mkexpr(t6), 8147 binop(Iop_Shl32, 8148 mkU32(0x1), 8149 mkU8(rs-1))), 8150 mkU8(rs)))); 8151 putIReg(rd, binop(Iop_16HLto32, 8152 binop(Iop_8HLto16, 8153 mkexpr(t7), mkexpr(t5)), 8154 binop(Iop_8HLto16, 8155 mkexpr(t3), mkexpr(t1)))); 8156 } 8157 break; 8158 } 8159 case 0x6: { /* SHRAV.QB */ 8160 DIP("shrav.qb r%d, r%d, %d", rd, rt, rs); 8161 vassert(!mode64); 8162 8163 t0 = newTemp(Ity_I32); 8164 t1 = newTemp(Ity_I32); 8165 t2 = newTemp(Ity_I32); 8166 8167 t3 = newTemp(Ity_I32); 8168 t4 = newTemp(Ity_I32); 8169 t5 = newTemp(Ity_I32); 8170 8171 t6 = newTemp(Ity_I32); 8172 t7 = newTemp(Ity_I32); 8173 t8 = newTemp(Ity_I32); 8174 8175 t9 = newTemp(Ity_I32); 8176 t10 = newTemp(Ity_I32); 8177 t11 = newTemp(Ity_I32); 8178 8179 /* ========== GPR[rt]_31..24 ========== */ 8180 assign(t1, 8181 unop(Iop_8Uto32, 8182 unop(Iop_16HIto8, 8183 unop(Iop_32HIto16, getIReg(rt))))); 8184 assign(t2, 8185 binop(Iop_Shr32, 8186 mkexpr(t1), 8187 unop(Iop_32to8, binop(Iop_And32, 8188 getIReg(rs), 8189 mkU32(0x7))))); 8190 /* tempD_7..0 */ 8191 assign(t0, 8192 binop(Iop_Or32, 8193 mkexpr(t2), 8194 binop(Iop_Shl32, 8195 IRExpr_ITE(binop(Iop_CmpEQ32, 8196 binop(Iop_And32, 8197 mkexpr(t1), 8198 mkU32(0x00000080) 8199 ), 8200 mkU32(0x00000080)), 8201 mkU32(0xFFFFFFFF), 8202 mkU32(0x00000000)), 8203 binop(Iop_Sub8, 8204 mkU8(0x8), 8205 unop(Iop_32to8, binop(Iop_And32, 8206 getIReg(rs), 8207 mkU32(0x7))) 8208 )))); 8209 8210 /* ========== GPR[rt]_23..16 ========== */ 8211 assign(t4, 8212 unop(Iop_8Uto32, 8213 unop(Iop_16to8, 8214 unop(Iop_32HIto16, getIReg(rt))))); 8215 assign(t5, 8216 binop(Iop_Shr32, 8217 mkexpr(t4), 8218 unop(Iop_32to8, binop(Iop_And32, 8219 getIReg(rs), 8220 mkU32(0x7))))); 8221 /* tempC_7..0 */ 8222 assign(t3, 8223 binop(Iop_Or32, 8224 mkexpr(t5), 8225 binop(Iop_Shl32, 8226 IRExpr_ITE(binop(Iop_CmpEQ32, 8227 binop(Iop_And32, 8228 mkexpr(t4), 8229 mkU32(0x00000080) 8230 ), 8231 mkU32(0x00000080)), 8232 mkU32(0xFFFFFFFF), 8233 mkU32(0x00000000)), 8234 binop(Iop_Sub8, 8235 mkU8(0x8), 8236 unop(Iop_32to8, binop(Iop_And32, 8237 getIReg(rs), 8238 mkU32(0x7))) 8239 )))); 8240 8241 /* ========== GPR[rt]_15..8 ========== */ 8242 assign(t7, 8243 unop(Iop_8Uto32, 8244 unop(Iop_16HIto8, 8245 unop(Iop_32to16, getIReg(rt))))); 8246 assign(t8, 8247 binop(Iop_Shr32, 8248 mkexpr(t7), 8249 unop(Iop_32to8, binop(Iop_And32, 8250 getIReg(rs), 8251 mkU32(0x7))))); 8252 /* tempB_7..0 */ 8253 assign(t6, 8254 binop(Iop_Or32, 8255 mkexpr(t8), 8256 binop(Iop_Shl32, 8257 IRExpr_ITE(binop(Iop_CmpEQ32, 8258 binop(Iop_And32, 8259 mkexpr(t7), 8260 mkU32(0x00000080) 8261 ), 8262 mkU32(0x00000080)), 8263 mkU32(0xFFFFFFFF), 8264 mkU32(0x00000000)), 8265 binop(Iop_Sub8, 8266 mkU8(0x8), 8267 unop(Iop_32to8, binop(Iop_And32, 8268 getIReg(rs), 8269 mkU32(0x7))) 8270 )))); 8271 8272 /* ========== GPR[rt]_7..0 ========== */ 8273 assign(t10, 8274 unop(Iop_8Uto32, 8275 unop(Iop_16to8, 8276 unop(Iop_32to16, getIReg(rt))))); 8277 assign(t11, 8278 binop(Iop_Shr32, 8279 mkexpr(t10), 8280 unop(Iop_32to8, binop(Iop_And32, 8281 getIReg(rs), 8282 mkU32(0x7))))); 8283 /* tempB_7..0 */ 8284 assign(t9, 8285 binop(Iop_Or32, 8286 mkexpr(t11), 8287 binop(Iop_Shl32, 8288 IRExpr_ITE(binop(Iop_CmpEQ32, 8289 binop(Iop_And32, 8290 mkexpr(t10), 8291 mkU32(0x00000080) 8292 ), 8293 mkU32(0x00000080)), 8294 mkU32(0xFFFFFFFF), 8295 mkU32(0x00000000)), 8296 binop(Iop_Sub8, 8297 mkU8(0x8), 8298 unop(Iop_32to8, binop(Iop_And32, 8299 getIReg(rs), 8300 mkU32(0x7))) 8301 )))); 8302 8303 putIReg(rd, 8304 binop(Iop_16HLto32, 8305 binop(Iop_8HLto16, 8306 unop(Iop_32to8, 8307 IRExpr_ITE(binop(Iop_CmpEQ32, 8308 binop(Iop_And32, 8309 mkU32(rs), 8310 mkU32(0x7) 8311 ), 8312 mkU32(0x0)), 8313 mkexpr(t1), 8314 mkexpr(t0))), 8315 unop(Iop_32to8, 8316 IRExpr_ITE(binop(Iop_CmpEQ32, 8317 binop(Iop_And32, 8318 mkU32(rs), 8319 mkU32(0x7) 8320 ), 8321 mkU32(0x0)), 8322 mkexpr(t2), 8323 mkexpr(t3)))), 8324 binop(Iop_8HLto16, 8325 unop(Iop_32to8, 8326 IRExpr_ITE(binop(Iop_CmpEQ32, 8327 binop(Iop_And32, 8328 mkU32(rs), 8329 mkU32(0x7) 8330 ), 8331 mkU32(0x0)), 8332 mkexpr(t5), 8333 mkexpr(t6))), 8334 unop(Iop_32to8, 8335 IRExpr_ITE(binop(Iop_CmpEQ32, 8336 binop(Iop_And32, 8337 mkU32(rs), 8338 mkU32(0x7) 8339 ), 8340 mkU32(0x0)), 8341 mkexpr(t8), 8342 mkexpr(t9)))))); 8343 break; 8344 } 8345 case 0x7: { /* SHRAV_R.QB */ 8346 DIP("shrav_r.qb r%d, r%d, r%d", rd, rt, rs); 8347 vassert(!mode64); 8348 t0 = newTemp(Ity_I32); 8349 t1 = newTemp(Ity_I8); 8350 t2 = newTemp(Ity_I32); 8351 t3 = newTemp(Ity_I8); 8352 t4 = newTemp(Ity_I32); 8353 t5 = newTemp(Ity_I8); 8354 t6 = newTemp(Ity_I32); 8355 t7 = newTemp(Ity_I8); 8356 t8 = newTemp(Ity_I8); 8357 t9 = newTemp(Ity_I32); 8358 8359 assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7))); 8360 assign(t8, unop(Iop_32to8, 8361 binop(Iop_Sub32, mkexpr(t9), mkU32(0x1)))); 8362 assign(t0, unop(Iop_8Sto32, 8363 unop(Iop_16to8, 8364 unop(Iop_32to16, getIReg(rt))))); 8365 assign(t1, unop(Iop_32to8, 8366 binop(Iop_Sar32, 8367 binop(Iop_Add32, 8368 mkexpr(t0), 8369 binop(Iop_Shl32, 8370 mkU32(0x1), 8371 mkexpr(t8))), 8372 unop(Iop_32to8, 8373 mkexpr(t9))))); 8374 8375 assign(t2, unop(Iop_8Sto32, 8376 unop(Iop_16HIto8, 8377 unop(Iop_32to16, getIReg(rt))))); 8378 assign(t3, unop(Iop_32to8, 8379 binop(Iop_Sar32, 8380 binop(Iop_Add32, 8381 mkexpr(t2), 8382 binop(Iop_Shl32, 8383 mkU32(0x1), 8384 mkexpr(t8))), 8385 unop(Iop_32to8, mkexpr(t9))))); 8386 8387 assign(t4, unop(Iop_8Sto32, 8388 unop(Iop_16to8, 8389 unop(Iop_32HIto16, getIReg(rt))))); 8390 assign(t5, unop(Iop_32to8, 8391 binop(Iop_Sar32, 8392 binop(Iop_Add32, 8393 mkexpr(t4), 8394 binop(Iop_Shl32, 8395 mkU32(0x1), 8396 mkexpr(t8))), 8397 unop(Iop_32to8, mkexpr(t9))))); 8398 8399 assign(t6, unop(Iop_8Sto32, 8400 unop(Iop_16HIto8, 8401 unop(Iop_32HIto16, getIReg(rt))))); 8402 assign(t7, unop(Iop_32to8, 8403 binop(Iop_Sar32, 8404 binop(Iop_Add32, 8405 mkexpr(t6), 8406 binop(Iop_Shl32, 8407 mkU32(0x1), 8408 mkexpr(t8))), 8409 unop(Iop_32to8, mkexpr(t9))))); 8410 putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32, 8411 mkexpr(t9), 8412 mkU32(0x0)), 8413 getIReg(rt), 8414 binop(Iop_16HLto32, 8415 binop(Iop_8HLto16, 8416 mkexpr(t7), 8417 mkexpr(t5)), 8418 binop(Iop_8HLto16, 8419 mkexpr(t3), 8420 mkexpr(t1))))); 8421 break; 8422 } 8423 case 0x8: { /* SHLL.PH */ 8424 DIP("shll.ph r%d, r%d, %d", rd, rt, rs); 8425 vassert(!mode64); 8426 t0 = newTemp(Ity_I32); 8427 t1 = newTemp(Ity_I32); 8428 t2 = newTemp(Ity_I32); 8429 t3 = newTemp(Ity_I32); 8430 t4 = newTemp(Ity_I32); 8431 t5 = newTemp(Ity_I32); 8432 t6 = newTemp(Ity_I32); 8433 t7 = newTemp(Ity_I32); 8434 8435 if (0 == rs) { 8436 putIReg(rd, getIReg(rt)); 8437 } else { 8438 /* Shift lower 16 bits. */ 8439 assign(t0, binop(Iop_Shl32, 8440 unop(Iop_16Sto32, 8441 unop(Iop_32to16, getIReg(rt))), 8442 mkU8(rs))); 8443 8444 assign(t1, unop(Iop_1Uto32, 8445 binop(Iop_CmpNE32, 8446 binop(Iop_Sar32, 8447 mkexpr(t0), 8448 mkU8(16)), 8449 mkU32(0)))); 8450 assign(t2, unop(Iop_1Uto32, 8451 binop(Iop_CmpNE32, 8452 binop(Iop_Sar32, 8453 mkexpr(t0), 8454 mkU8(16)), 8455 mkU32(0xffffffff)))); 8456 assign(t3, binop(Iop_And32, 8457 mkexpr(t1), 8458 mkexpr(t2))); 8459 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8460 mkexpr(t3), 8461 mkU32(0x1)), 8462 binop(Iop_Or32, 8463 getDSPControl(), 8464 mkU32(0x400000)), 8465 getDSPControl())); 8466 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8467 binop(Iop_And32, 8468 getIReg(rt), 8469 mkU32(0x00008000)), 8470 binop(Iop_And32, 8471 mkexpr(t0), 8472 mkU32(0x00008000)) 8473 ), 8474 getDSPControl(), 8475 binop(Iop_Or32, 8476 getDSPControl(), 8477 mkU32(0x400000)))); 8478 /* Shift higher 16 bits. */ 8479 assign(t4, binop(Iop_Shl32, 8480 unop(Iop_16Sto32, 8481 unop(Iop_32HIto16, getIReg(rt))), 8482 mkU8(rs))); 8483 8484 assign(t5, unop(Iop_1Uto32, 8485 binop(Iop_CmpNE32, 8486 binop(Iop_Sar32, 8487 mkexpr(t4), 8488 mkU8(16)), 8489 mkU32(0)))); 8490 assign(t6, unop(Iop_1Uto32, 8491 binop(Iop_CmpNE32, 8492 binop(Iop_Sar32, 8493 mkexpr(t4), 8494 mkU8(16)), 8495 mkU32(0xffffffff)))); 8496 assign(t7, binop(Iop_And32, 8497 mkexpr(t5), 8498 mkexpr(t6))); 8499 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8500 mkexpr(t7), 8501 mkU32(0x1)), 8502 binop(Iop_Or32, 8503 getDSPControl(), 8504 mkU32(0x400000)), 8505 getDSPControl())); 8506 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8507 mkexpr(t7), 8508 mkU32(0x1)), 8509 binop(Iop_Or32, 8510 getDSPControl(), 8511 mkU32(0x400000)), 8512 getDSPControl())); 8513 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8514 binop(Iop_And32, 8515 getIReg(rt), 8516 mkU32(0x80000000)), 8517 binop(Iop_Shl32, 8518 binop(Iop_And32, 8519 mkexpr(t4), 8520 mkU32(0x00008000)), 8521 mkU8(16)) 8522 ), 8523 getDSPControl(), 8524 binop(Iop_Or32, 8525 getDSPControl(), 8526 mkU32(0x400000)))); 8527 putIReg(rd, binop(Iop_16HLto32, 8528 unop(Iop_32to16, mkexpr(t4)), 8529 unop(Iop_32to16, mkexpr(t0)))); 8530 } 8531 break; 8532 } 8533 case 0x9: { /* SHRA.PH */ 8534 DIP("shra.ph r%d, r%d, %d", rd, rt, rs); 8535 vassert(!mode64); 8536 t0 = newTemp(Ity_I32); 8537 t1 = newTemp(Ity_I32); 8538 if (0 == rs) { 8539 putIReg(rd, getIReg(rt)); 8540 } else { 8541 assign(t0, binop(Iop_Sar32, 8542 unop(Iop_16Sto32, 8543 unop(Iop_32to16, getIReg(rt))), 8544 mkU8(rs))); 8545 assign(t1, binop(Iop_Sar32, 8546 unop(Iop_16Sto32, 8547 unop(Iop_32HIto16, getIReg(rt))), 8548 mkU8(rs))); 8549 putIReg(rd, binop(Iop_16HLto32, 8550 unop(Iop_32to16, mkexpr(t1)), 8551 unop(Iop_32to16, mkexpr(t0)))); 8552 } 8553 break; 8554 } 8555 case 0xA: { /* SHLLV.PH */ 8556 DIP("shllv.ph r%d, r%d, r%d", rd, rt, rs); 8557 vassert(!mode64); 8558 t0 = newTemp(Ity_I32); 8559 t2 = newTemp(Ity_I32); 8560 t3 = newTemp(Ity_I1); 8561 t4 = newTemp(Ity_I1); 8562 t5 = newTemp(Ity_I32); 8563 t6 = newTemp(Ity_I32); 8564 t7 = newTemp(Ity_I1); 8565 t8 = newTemp(Ity_I1); 8566 t9 = newTemp(Ity_I32); 8567 t10 = newTemp(Ity_I32); 8568 t11 = newTemp(Ity_I32); 8569 t12 = newTemp(Ity_I1); 8570 t13 = newTemp(Ity_I1); 8571 8572 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f))); 8573 8574 /* Shift lower 16 bits. */ 8575 assign(t2, binop(Iop_Shl32, 8576 unop(Iop_16Sto32, 8577 unop(Iop_32to16, getIReg(rt))), 8578 unop(Iop_32to8, mkexpr(t0)))); 8579 8580 assign(t3, binop(Iop_CmpNE32, 8581 unop(Iop_16Sto32, 8582 unop(Iop_32HIto16, mkexpr(t2))), 8583 mkU32(0x00000000))); 8584 assign(t4, binop(Iop_CmpNE32, 8585 unop(Iop_16Sto32, 8586 unop(Iop_32HIto16, mkexpr(t2))), 8587 mkU32(0xffffffff))); 8588 assign(t10, binop(Iop_And32, 8589 unop(Iop_1Sto32, mkexpr(t3)), 8590 unop(Iop_1Sto32, mkexpr(t4)))); 8591 assign(t5, binop(Iop_Shr32, 8592 binop(Iop_And32, 8593 getIReg(rt), 8594 mkU32(0x00008000)), 8595 mkU8(15))); 8596 assign(t12, binop(Iop_CmpEQ32, 8597 mkexpr(t5), 8598 binop(Iop_Shr32, 8599 binop(Iop_And32, 8600 mkexpr(t2), 8601 mkU32(0x00008000)), 8602 mkU8(15)))); 8603 8604 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 8605 mkexpr(t10), 8606 mkU32(0x0)), 8607 binop(Iop_Or32, 8608 getDSPControl(), 8609 mkU32(0x400000)), 8610 IRExpr_ITE(mkexpr(t12), 8611 getDSPControl(), 8612 binop(Iop_Or32, 8613 getDSPControl(), 8614 mkU32(0x400000))) 8615 )); 8616 /* Shift higher 16 bits. */ 8617 assign(t6, binop(Iop_Shl32, 8618 unop(Iop_16Sto32, 8619 unop(Iop_32HIto16, getIReg(rt))), 8620 unop(Iop_32to8, mkexpr(t0)))); 8621 8622 assign(t7, binop(Iop_CmpNE32, 8623 unop(Iop_16Sto32, 8624 unop(Iop_32HIto16, mkexpr(t6))), 8625 mkU32(0x00000000))); 8626 assign(t8, binop(Iop_CmpNE32, 8627 unop(Iop_16Sto32, 8628 unop(Iop_32HIto16, mkexpr(t6))), 8629 mkU32(0xffffffff))); 8630 assign(t11, binop(Iop_And32, 8631 unop(Iop_1Sto32, mkexpr(t7)), 8632 unop(Iop_1Sto32, mkexpr(t8)))); 8633 8634 assign(t9, binop(Iop_Shr32, 8635 binop(Iop_And32, 8636 getIReg(rt), 8637 mkU32(0x80000000)), 8638 mkU8(31))); 8639 assign(t13, binop(Iop_CmpEQ32, 8640 mkexpr(t9), 8641 binop(Iop_Shr32, 8642 binop(Iop_And32, 8643 mkexpr(t6), 8644 mkU32(0x00008000)), 8645 mkU8(15)))); 8646 8647 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 8648 mkexpr(t11), 8649 mkU32(0x0)), 8650 binop(Iop_Or32, 8651 getDSPControl(), 8652 mkU32(0x400000)), 8653 IRExpr_ITE(mkexpr(t13), 8654 getDSPControl(), 8655 binop(Iop_Or32, 8656 getDSPControl(), 8657 mkU32(0x400000))) 8658 )); 8659 8660 putIReg(rd, binop(Iop_16HLto32, 8661 unop(Iop_32to16, mkexpr(t6)), 8662 unop(Iop_32to16, mkexpr(t2)))); 8663 break; 8664 } 8665 case 0xB: { /* SHRAV.PH */ 8666 DIP("shrav.ph r%d, r%d, r%d", rd, rt, rs); 8667 vassert(!mode64); 8668 t0 = newTemp(Ity_I32); 8669 t1 = newTemp(Ity_I1); 8670 t2 = newTemp(Ity_I32); 8671 t3 = newTemp(Ity_I32); 8672 8673 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f))); 8674 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0))); 8675 assign(t2, binop(Iop_Sar32, 8676 unop(Iop_16Sto32, 8677 unop(Iop_32to16, getIReg(rt))), 8678 unop(Iop_32to8, mkexpr(t0)))); 8679 assign(t3, binop(Iop_Sar32, 8680 unop(Iop_16Sto32, 8681 unop(Iop_32HIto16, getIReg(rt))), 8682 unop(Iop_32to8, mkexpr(t0)))); 8683 putIReg(rd, 8684 binop(Iop_16HLto32, 8685 IRExpr_ITE(mkexpr(t1), 8686 unop(Iop_32HIto16, getIReg(rt)), 8687 unop(Iop_32to16, mkexpr(t3))), 8688 IRExpr_ITE(mkexpr(t1), 8689 unop(Iop_32to16, getIReg(rt)), 8690 unop(Iop_32to16, mkexpr(t2))))); 8691 break; 8692 } 8693 case 0xC: { /* SHLL_S.PH */ 8694 DIP("shll_s.ph r%d, r%d, %d", rd, rt, rs); 8695 vassert(!mode64); 8696 t0 = newTemp(Ity_I32); 8697 t1 = newTemp(Ity_I32); 8698 t2 = newTemp(Ity_I32); 8699 t3 = newTemp(Ity_I32); 8700 t4 = newTemp(Ity_I32); 8701 t5 = newTemp(Ity_I32); 8702 t6 = newTemp(Ity_I32); 8703 t7 = newTemp(Ity_I32); 8704 t8 = newTemp(Ity_I32); 8705 t9 = newTemp(Ity_I32); 8706 t10 = newTemp(Ity_I32); 8707 t11 = newTemp(Ity_I32); 8708 t12 = newTemp(Ity_I32); 8709 t13 = newTemp(Ity_I32); 8710 t14 = newTemp(Ity_I32); 8711 8712 if (0 == rs) { 8713 putIReg(rd, getIReg(rt)); 8714 } else { 8715 /* Shift lower 16 bits. */ 8716 assign(t0, binop(Iop_Shl32, 8717 unop(Iop_16Sto32, 8718 unop(Iop_32to16, getIReg(rt))), 8719 mkU8(rs))); 8720 8721 assign(t1, unop(Iop_1Uto32, 8722 binop(Iop_CmpNE32, 8723 binop(Iop_Sar32, 8724 mkexpr(t0), 8725 mkU8(16)), 8726 mkU32(0)))); 8727 assign(t2, unop(Iop_1Uto32, 8728 binop(Iop_CmpNE32, 8729 binop(Iop_Sar32, 8730 mkexpr(t0), 8731 mkU8(16)), 8732 mkU32(0xffffffff)))); 8733 assign(t3, binop(Iop_And32, 8734 mkexpr(t1), 8735 mkexpr(t2))); 8736 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8737 mkexpr(t3), 8738 mkU32(0x1)), 8739 binop(Iop_Or32, 8740 getDSPControl(), 8741 mkU32(0x400000)), 8742 getDSPControl())); 8743 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8744 binop(Iop_And32, 8745 getIReg(rt), 8746 mkU32(0x00008000)), 8747 binop(Iop_And32, 8748 mkexpr(t0), 8749 mkU32(0x00008000)) 8750 ), 8751 getDSPControl(), 8752 binop(Iop_Or32, 8753 getDSPControl(), 8754 mkU32(0x400000)))); 8755 assign(t8, 8756 IRExpr_ITE(binop(Iop_CmpEQ32, 8757 mkexpr(t3), 8758 mkU32(0x1)), 8759 IRExpr_ITE(binop(Iop_CmpEQ32, 8760 binop(Iop_And32, 8761 getIReg(rt), 8762 mkU32(0x8000)), 8763 mkU32(0)), 8764 mkU32(0x00007fff), 8765 mkU32(0x00008000)), 8766 binop(Iop_And32, 8767 mkexpr(t0), 8768 mkU32(0x0000ffff)))); 8769 assign(t10, 8770 IRExpr_ITE(binop(Iop_CmpEQ32, 8771 binop(Iop_And32, 8772 getIReg(rt), 8773 mkU32(0x00008000)), 8774 binop(Iop_And32, 8775 mkexpr(t0), 8776 mkU32(0x00008000))), 8777 mkexpr(t8), 8778 IRExpr_ITE(binop(Iop_CmpEQ32, 8779 binop(Iop_And32, 8780 getIReg(rt), 8781 mkU32(0x8000)), 8782 mkU32(0)), 8783 mkU32(0x00007fff), 8784 mkU32(0x00008000)))); 8785 /* Shift higher 16 bits. */ 8786 assign(t4, binop(Iop_Shl32, 8787 unop(Iop_16Sto32, 8788 unop(Iop_32HIto16, getIReg(rt))), 8789 mkU8(rs))); 8790 8791 assign(t5, unop(Iop_1Uto32, 8792 binop(Iop_CmpNE32, 8793 binop(Iop_Sar32, 8794 mkexpr(t4), 8795 mkU8(16)), 8796 mkU32(0)))); 8797 assign(t6, unop(Iop_1Uto32, 8798 binop(Iop_CmpNE32, 8799 binop(Iop_Sar32, 8800 mkexpr(t4), 8801 mkU8(16)), 8802 mkU32(0xffffffff)))); 8803 assign(t7, binop(Iop_And32, 8804 mkexpr(t5), 8805 mkexpr(t6))); 8806 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8807 mkexpr(t7), 8808 mkU32(0x1)), 8809 binop(Iop_Or32, 8810 getDSPControl(), 8811 mkU32(0x400000)), 8812 getDSPControl())); 8813 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8814 mkexpr(t7), 8815 mkU32(0x1)), 8816 binop(Iop_Or32, 8817 getDSPControl(), 8818 mkU32(0x400000)), 8819 getDSPControl())); 8820 assign(t12, binop(Iop_Shl32, 8821 binop(Iop_And32, 8822 mkexpr(t4), 8823 mkU32(0x8000)), 8824 mkU8(16))); 8825 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8826 binop(Iop_And32, 8827 getIReg(rt), 8828 mkU32(0x80000000)), 8829 mkexpr(t12)), 8830 getDSPControl(), 8831 binop(Iop_Or32, 8832 getDSPControl(), 8833 mkU32(0x400000)))); 8834 assign(t13, IRExpr_ITE(binop(Iop_CmpEQ32, 8835 binop(Iop_And32, 8836 getIReg(rt), 8837 mkU32(0x80000000)), 8838 mkU32(0)), 8839 mkU32(0x7fff0000), 8840 mkU32(0x80000000))); 8841 assign(t9, 8842 IRExpr_ITE(binop(Iop_CmpEQ32, 8843 mkexpr(t7), 8844 mkU32(0x1)), 8845 mkexpr(t13), 8846 binop(Iop_Shl32, 8847 binop(Iop_And32, 8848 mkexpr(t4), 8849 mkU32(0x0000ffff)), 8850 mkU8(16)))); 8851 assign(t14, IRExpr_ITE(binop(Iop_CmpEQ32, 8852 binop(Iop_And32, 8853 getIReg(rt), 8854 mkU32(0x80000000)), 8855 mkU32(0)), 8856 mkU32(0x7fff0000), 8857 mkU32(0x80000000))); 8858 assign(t11, 8859 IRExpr_ITE(binop(Iop_CmpEQ32, 8860 binop(Iop_And32, 8861 getIReg(rt), 8862 mkU32(0x80000000)), 8863 binop(Iop_Shl32, 8864 binop(Iop_And32, 8865 mkexpr(t4), 8866 mkU32(0x00008000)), 8867 mkU8(16))), 8868 mkexpr(t9), 8869 mkexpr(t14))); 8870 putIReg(rd, binop(Iop_Or32, 8871 mkexpr(t10), 8872 mkexpr(t11))); 8873 } 8874 break; 8875 } 8876 case 0xD: { /* SHRA_R.PH */ 8877 DIP("shra.ph r%d, r%d, %d", rd, rt, rs); 8878 vassert(!mode64); 8879 t0 = newTemp(Ity_I32); 8880 t1 = newTemp(Ity_I32); 8881 if (0 == rs) { 8882 putIReg(rd, getIReg(rt)); 8883 } else { 8884 assign(t0, binop(Iop_Sar32, 8885 binop(Iop_Add32, 8886 unop(Iop_16Sto32, 8887 unop(Iop_32to16, 8888 getIReg(rt))), 8889 binop(Iop_Shl32, 8890 mkU32(0x1), 8891 mkU8(rs-1))), 8892 mkU8(rs))); 8893 assign(t1, binop(Iop_Sar32, 8894 binop(Iop_Add32, 8895 unop(Iop_16Sto32, 8896 unop(Iop_32HIto16, 8897 getIReg(rt))), 8898 binop(Iop_Shl32, 8899 mkU32(0x1), 8900 mkU8(rs-1))), 8901 mkU8(rs))); 8902 putIReg(rd, binop(Iop_16HLto32, 8903 unop(Iop_32to16, mkexpr(t1)), 8904 unop(Iop_32to16, mkexpr(t0)))); 8905 } 8906 break; 8907 } 8908 case 0xE: { /* SHLLV_S.PH */ 8909 DIP("shllv_s.ph r%d, r%d, r%d", rd, rt, rs); 8910 vassert(!mode64); 8911 t0 = newTemp(Ity_I32); 8912 t2 = newTemp(Ity_I32); 8913 t3 = newTemp(Ity_I1); 8914 t4 = newTemp(Ity_I1); 8915 t5 = newTemp(Ity_I32); 8916 t6 = newTemp(Ity_I32); 8917 t7 = newTemp(Ity_I1); 8918 t8 = newTemp(Ity_I1); 8919 t9 = newTemp(Ity_I32); 8920 t10 = newTemp(Ity_I32); 8921 t11 = newTemp(Ity_I32); 8922 t12 = newTemp(Ity_I1); 8923 t13 = newTemp(Ity_I1); 8924 t14 = newTemp(Ity_I16); 8925 t15 = newTemp(Ity_I16); 8926 t16 = newTemp(Ity_I16); 8927 t17 = newTemp(Ity_I16); 8928 8929 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f))); 8930 8931 /* Shift lower 16 bits. */ 8932 assign(t2, binop(Iop_Shl32, 8933 unop(Iop_16Sto32, 8934 unop(Iop_32to16, getIReg(rt))), 8935 unop(Iop_32to8, mkexpr(t0)))); 8936 8937 assign(t3, binop(Iop_CmpNE32, 8938 unop(Iop_16Sto32, 8939 unop(Iop_32HIto16, mkexpr(t2))), 8940 mkU32(0x00000000))); 8941 assign(t4, binop(Iop_CmpNE32, 8942 unop(Iop_16Sto32, 8943 unop(Iop_32HIto16, mkexpr(t2))), 8944 mkU32(0xffffffff))); 8945 assign(t10, binop(Iop_And32, 8946 unop(Iop_1Sto32, mkexpr(t3)), 8947 unop(Iop_1Sto32, mkexpr(t4)))); 8948 assign(t5, binop(Iop_Shr32, 8949 binop(Iop_And32, 8950 getIReg(rt), 8951 mkU32(0x00008000)), 8952 mkU8(15))); 8953 assign(t12, binop(Iop_CmpEQ32, 8954 mkexpr(t5), 8955 binop(Iop_Shr32, 8956 binop(Iop_And32, 8957 mkexpr(t2), 8958 mkU32(0x00008000)), 8959 mkU8(15)))); 8960 8961 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 8962 mkexpr(t10), 8963 mkU32(0x0)), 8964 binop(Iop_Or32, 8965 getDSPControl(), 8966 mkU32(0x400000)), 8967 IRExpr_ITE(mkexpr(t12), 8968 getDSPControl(), 8969 binop(Iop_Or32, 8970 getDSPControl(), 8971 mkU32(0x400000))) 8972 )); 8973 assign(t14, IRExpr_ITE(binop(Iop_CmpNE32, 8974 mkexpr(t5), 8975 mkU32(0x0)), 8976 mkU16(0x8000), 8977 mkU16(0x7fff))); 8978 assign(t15, IRExpr_ITE(binop(Iop_CmpNE32, 8979 mkexpr(t10), 8980 mkU32(0x0)), 8981 mkexpr(t14), 8982 IRExpr_ITE(mkexpr(t12), 8983 unop(Iop_32to16, 8984 mkexpr(t2)), 8985 mkexpr(t14)))); 8986 /* Shift higher 16 bits. */ 8987 assign(t6, binop(Iop_Shl32, 8988 unop(Iop_16Sto32, 8989 unop(Iop_32HIto16, getIReg(rt))), 8990 unop(Iop_32to8, mkexpr(t0)))); 8991 8992 assign(t7, binop(Iop_CmpNE32, 8993 unop(Iop_16Sto32, 8994 unop(Iop_32HIto16, mkexpr(t6))), 8995 mkU32(0x00000000))); 8996 assign(t8, binop(Iop_CmpNE32, 8997 unop(Iop_16Sto32, 8998 unop(Iop_32HIto16, mkexpr(t6))), 8999 mkU32(0xffffffff))); 9000 assign(t11, binop(Iop_And32, 9001 unop(Iop_1Sto32, mkexpr(t7)), 9002 unop(Iop_1Sto32, mkexpr(t8)))); 9003 9004 assign(t9, binop(Iop_Shr32, 9005 binop(Iop_And32, 9006 getIReg(rt), 9007 mkU32(0x80000000)), 9008 mkU8(31))); 9009 assign(t13, binop(Iop_CmpEQ32, 9010 mkexpr(t9), 9011 binop(Iop_Shr32, 9012 binop(Iop_And32, 9013 mkexpr(t6), 9014 mkU32(0x00008000)), 9015 mkU8(15)))); 9016 9017 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 9018 mkexpr(t11), 9019 mkU32(0x0)), 9020 binop(Iop_Or32, 9021 getDSPControl(), 9022 mkU32(0x400000)), 9023 IRExpr_ITE(mkexpr(t13), 9024 getDSPControl(), 9025 binop(Iop_Or32, 9026 getDSPControl(), 9027 mkU32(0x400000))) 9028 )); 9029 9030 assign(t16, IRExpr_ITE(binop(Iop_CmpNE32, 9031 mkexpr(t9), 9032 mkU32(0x0)), 9033 mkU16(0x8000), 9034 mkU16(0x7fff))); 9035 assign(t17, IRExpr_ITE(binop(Iop_CmpNE32, 9036 mkexpr(t11), 9037 mkU32(0x0)), 9038 mkexpr(t16), 9039 IRExpr_ITE(mkexpr(t13), 9040 unop(Iop_32to16, 9041 mkexpr(t6)), 9042 mkexpr(t16)))); 9043 9044 putIReg(rd, binop(Iop_16HLto32, mkexpr(t17), mkexpr(t15))); 9045 break; 9046 } 9047 case 0xF: { /* SHRAV_R.PH */ 9048 DIP("shrav_r.ph r%d, r%d, r%d", rd, rt, rs); 9049 vassert(!mode64); 9050 t0 = newTemp(Ity_I32); 9051 t1 = newTemp(Ity_I1); 9052 t2 = newTemp(Ity_I8); 9053 t3 = newTemp(Ity_I32); 9054 t4 = newTemp(Ity_I32); 9055 9056 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f))); 9057 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0))); 9058 assign(t2, unop(Iop_32to8, 9059 binop(Iop_Sub32, mkexpr(t0), mkU32(1)))); 9060 9061 assign(t3, binop(Iop_Sar32, 9062 binop(Iop_Add32, 9063 unop(Iop_16Sto32, 9064 unop(Iop_32to16, getIReg(rt))), 9065 binop(Iop_Shl32, 9066 mkU32(0x1), 9067 mkexpr(t2))), 9068 unop(Iop_32to8, mkexpr(t0)))); 9069 assign(t4, binop(Iop_Sar32, 9070 binop(Iop_Add32, 9071 unop(Iop_16Sto32, 9072 unop(Iop_32HIto16, 9073 getIReg(rt))), 9074 binop(Iop_Shl32, 9075 mkU32(0x1), 9076 mkexpr(t2))), 9077 unop(Iop_32to8, mkexpr(t0)))); 9078 9079 putIReg(rd, binop(Iop_16HLto32, 9080 IRExpr_ITE(mkexpr(t1), 9081 unop(Iop_32HIto16, 9082 getIReg(rt)), 9083 unop(Iop_32to16, 9084 mkexpr(t4))), 9085 IRExpr_ITE(mkexpr(t1), 9086 unop(Iop_32to16, getIReg(rt)), 9087 unop(Iop_32to16, 9088 mkexpr(t3))))); 9089 break; 9090 } 9091 case 0x14: { /* SHLL_S.W */ 9092 DIP("shll_s.w r%d, r%d, %d", rd, rt, rs); 9093 vassert(!mode64); 9094 t0 = newTemp(Ity_I32); 9095 t1 = newTemp(Ity_I32); 9096 t2 = newTemp(Ity_I32); 9097 t3 = newTemp(Ity_I32); 9098 t4 = newTemp(Ity_I32); 9099 t5 = newTemp(Ity_I32); 9100 9101 if (0 == rs) { 9102 putIReg(rd, getIReg(rt)); 9103 } else { 9104 /* t0-bits that will be discarded, sign extended to 9105 32bits. */ 9106 assign(t0, binop(Iop_Sar32, 9107 binop(Iop_And32, 9108 getIReg(rt), 9109 binop(Iop_Sar32, 9110 mkU32(0x80000000), 9111 mkU8(rs-1))), 9112 mkU8(32-rs))); 9113 9114 assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32, 9115 binop(Iop_And32, 9116 getIReg(rt), 9117 mkU32(0x80000000)), 9118 mkU32(0x0)), 9119 mkU32(0x7fffffff), 9120 mkU32(0x80000000))); 9121 9122 assign(t2, binop(Iop_Shl32, getIReg(rt), mkU8(rs))); 9123 assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32, 9124 binop(Iop_And32, 9125 getIReg(rt), 9126 mkU32(0x80000000)), 9127 binop(Iop_And32, 9128 mkexpr(t2), 9129 mkU32(0x80000000))), 9130 mkexpr(t2), 9131 mkexpr(t1))); 9132 9133 assign(t4, IRExpr_ITE(binop(Iop_CmpNE32, 9134 mkexpr(t0), 9135 mkU32(0x0)), 9136 IRExpr_ITE(binop(Iop_CmpNE32, 9137 mkexpr(t0), 9138 mkU32(0xffffffff) 9139 ), 9140 mkexpr(t1), 9141 mkexpr(t3)), 9142 mkexpr(t3))); 9143 assign(t5, IRExpr_ITE(binop(Iop_CmpNE32, 9144 mkexpr(t0), 9145 mkU32(0xffffffff)), 9146 binop(Iop_Or32, 9147 getDSPControl(), 9148 mkU32(0x400000)), 9149 getDSPControl())); 9150 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 9151 mkexpr(t0), 9152 mkU32(0x0)), 9153 mkexpr(t5), 9154 getDSPControl())); 9155 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 9156 binop(Iop_And32, 9157 getIReg(rt), 9158 mkU32(0x80000000)), 9159 binop(Iop_And32, 9160 mkexpr(t2), 9161 mkU32(0x80000000)) 9162 ), 9163 getDSPControl(), 9164 binop(Iop_Or32, 9165 getDSPControl(), 9166 mkU32(0x400000)))); 9167 putIReg(rd, mkexpr(t4)); 9168 } 9169 break; 9170 } 9171 case 0x15: { /* SHRA_R.W */ 9172 DIP("shra_r.w r%d, r%d, %d", rd, rt, rs); 9173 vassert(!mode64); 9174 if (0 == rs) { 9175 putIReg(rd, getIReg(rt)); 9176 } else { 9177 putIReg(rd, binop(Iop_Add32, 9178 binop(Iop_Sar32, 9179 getIReg(rt), mkU8(rs)), 9180 binop(Iop_Shr32, 9181 binop(Iop_And32, 9182 getIReg(rt), 9183 binop(Iop_Shl32, 9184 mkU32(0x1), 9185 mkU8(rs-1))), 9186 mkU8(rs-1)))); 9187 } 9188 break; 9189 } 9190 case 0x16: { /* SHLLV_S.W */ 9191 DIP("shllv_s.w r%d, r%d, r%d", rd, rt, rs); 9192 vassert(!mode64); 9193 t0 = newTemp(Ity_I32); 9194 t1 = newTemp(Ity_I1); 9195 t2 = newTemp(Ity_I32); 9196 t3 = newTemp(Ity_I64); 9197 t4 = newTemp(Ity_I1); 9198 t5 = newTemp(Ity_I1); 9199 t6 = newTemp(Ity_I32); 9200 t7 = newTemp(Ity_I1); 9201 t8 = newTemp(Ity_I32); 9202 9203 /* Check if shift amount is zero. */ 9204 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f))); 9205 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0))); 9206 9207 /* t2 = sign of the input value. */ 9208 assign(t2, binop(Iop_Shr32, 9209 binop(Iop_And32, 9210 getIReg(rt), 9211 mkU32(0x80000000)), 9212 mkU8(31))); 9213 /* Shift left input value and check for overflow. */ 9214 assign(t3, binop(Iop_Shl64, 9215 unop(Iop_32Sto64, getIReg(rt)), 9216 unop(Iop_32to8, mkexpr(t0)))); 9217 assign(t4, binop(Iop_CmpNE32, 9218 unop(Iop_64HIto32, mkexpr(t3)), 9219 mkU32(0x00000000))); 9220 assign(t5, binop(Iop_CmpNE32, 9221 unop(Iop_64HIto32, mkexpr(t3)), 9222 mkU32(0xffffffff))); 9223 assign(t6, binop(Iop_And32, 9224 unop(Iop_1Uto32, mkexpr(t4)), 9225 unop(Iop_1Uto32, mkexpr(t5)))); 9226 assign(t7, binop(Iop_CmpEQ32, 9227 binop(Iop_Shr32, 9228 binop(Iop_And32, 9229 getIReg(rt), 9230 mkU32(0x80000000)), 9231 mkU8(31)), 9232 binop(Iop_Shr32, 9233 binop(Iop_And32, 9234 unop(Iop_64to32, mkexpr(t3)), 9235 mkU32(0x80000000)), 9236 mkU8(31)))); 9237 9238 putDSPControl(IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)), 9239 binop(Iop_Or32, 9240 getDSPControl(), 9241 mkU32(0x400000)), 9242 IRExpr_ITE(mkexpr(t7), 9243 getDSPControl(), 9244 binop(Iop_Or32, 9245 getDSPControl(), 9246 mkU32(0x400000))) 9247 )); 9248 9249 assign(t8, IRExpr_ITE(unop(Iop_32to1, 9250 mkexpr(t2)), 9251 mkU32(0x80000000), 9252 mkU32(0x7fffffff))); 9253 putIReg(rd, IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)), 9254 IRExpr_ITE(unop(Iop_32to1, 9255 mkexpr(t2)), 9256 mkU32(0x80000000), 9257 mkU32(0x7fffffff)), 9258 IRExpr_ITE(mkexpr(t7), 9259 unop(Iop_64to32, 9260 mkexpr(t3)), 9261 mkexpr(t8)))); 9262 break; 9263 } 9264 case 0x17: { /* SHRAV_R.W */ 9265 DIP("shrav_r.w r%d, r%d, r%d", rd, rt, rs); 9266 vassert(!mode64); 9267 t0 = newTemp(Ity_I32); 9268 t1 = newTemp(Ity_I1); 9269 t2 = newTemp(Ity_I8); 9270 t3 = newTemp(Ity_I32); 9271 9272 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f))); 9273 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0))); 9274 assign(t2, unop(Iop_32to8, 9275 binop(Iop_Sub32, mkexpr(t0), mkU32(1)))); 9276 9277 putIReg(rd, IRExpr_ITE(mkexpr(t1), 9278 getIReg(rt), 9279 binop(Iop_Sar32, 9280 binop(Iop_Add32, 9281 binop(Iop_Sar32, 9282 getIReg(rt), 9283 mkexpr(t2)), 9284 mkU32(0x1)), 9285 mkU8(1)))); 9286 break; 9287 } 9288 case 0x19: { /* SHRL.PH */ 9289 DIP("shrl.ph r%d, r%d, %d", rd, rt, rs); 9290 vassert(!mode64); 9291 t0 = newTemp(Ity_I32); 9292 t1 = newTemp(Ity_I32); 9293 assign(t0, binop(Iop_Shr32, 9294 unop(Iop_16Uto32, 9295 unop(Iop_32to16, getIReg(rt))), 9296 mkU8(rs))); 9297 assign(t1, binop(Iop_Shr32, 9298 unop(Iop_16Uto32, 9299 unop(Iop_32HIto16, getIReg(rt))), 9300 mkU8(rs))); 9301 putIReg(rd, binop(Iop_16HLto32, 9302 unop(Iop_32to16, mkexpr(t1)), 9303 unop(Iop_32to16, mkexpr(t0)))); 9304 break; 9305 } 9306 case 0x1B: { /* SHRLV.PH */ 9307 DIP("shrlv.ph r%d, r%d, r%d", rd, rt, rs); 9308 vassert(!mode64); 9309 t0 = newTemp(Ity_I32); 9310 t1 = newTemp(Ity_I1); 9311 t2 = newTemp(Ity_I32); 9312 t3 = newTemp(Ity_I32); 9313 t4 = newTemp(Ity_I16); 9314 t5 = newTemp(Ity_I16); 9315 9316 /* Get shift amount from lower 5 bits of rs 9317 and check if it is zero. */ 9318 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f))); 9319 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0))); 9320 9321 assign(t2, binop(Iop_Shr32, 9322 unop(Iop_16Uto32, 9323 unop(Iop_32to16, getIReg(rt))), 9324 unop(Iop_32to8, mkexpr(t0)))); 9325 assign(t3, binop(Iop_Shr32, 9326 unop(Iop_16Uto32, 9327 unop(Iop_32HIto16, getIReg(rt))), 9328 unop(Iop_32to8, mkexpr(t0)))); 9329 9330 assign(t4, IRExpr_ITE(mkexpr(t1), 9331 unop(Iop_32HIto16, getIReg(rt)), 9332 unop(Iop_32to16, mkexpr(t3)))); 9333 assign(t5, IRExpr_ITE(mkexpr(t1), 9334 unop(Iop_32to16, getIReg(rt)), 9335 unop(Iop_32to16, mkexpr(t2)))); 9336 putIReg(rd, binop(Iop_16HLto32, mkexpr(t4), mkexpr(t5))); 9337 break; 9338 } 9339 default: 9340 return -1; 9341 } 9342 break; /* end of SHLL.QB */ 9343 } 9344 case 0x18: { /* ADDUH.QB/MUL.PH */ 9345 switch(sa) { 9346 case 0x00: { /* ADDUH.QB */ 9347 DIP("adduh.qb r%d, r%d, r%d", rd, rs, rt); 9348 vassert(!mode64); 9349 t0 = newTemp(Ity_I32); 9350 9351 assign(t0, binop(Iop_HAdd8Ux4, getIReg(rs), getIReg(rt))); 9352 9353 putIReg(rd, mkexpr(t0)); 9354 break; 9355 } 9356 case 0x1: { /* SUBUH.QB */ 9357 DIP("subuh.qb r%d, r%d, r%d", rd, rs, rt); 9358 vassert(!mode64); 9359 t0 = newTemp(Ity_I32); 9360 9361 assign(t0, binop(Iop_HSub8Ux4, getIReg(rs), getIReg(rt))); 9362 9363 putIReg(rd, mkexpr(t0)); 9364 break; 9365 } 9366 case 0x02: { /* ADDUH_R.QB */ 9367 DIP("adduh_r.qb r%d, r%d, r%d", rd, rs, rt); 9368 vassert(!mode64); 9369 t0 = newTemp(Ity_I32); 9370 t1 = newTemp(Ity_I32); 9371 t2 = newTemp(Ity_I8); 9372 t3 = newTemp(Ity_I32); 9373 t4 = newTemp(Ity_I32); 9374 t5 = newTemp(Ity_I8); 9375 t6 = newTemp(Ity_I32); 9376 t7 = newTemp(Ity_I32); 9377 t8 = newTemp(Ity_I8); 9378 t9 = newTemp(Ity_I32); 9379 t10 = newTemp(Ity_I32); 9380 t11 = newTemp(Ity_I8); 9381 9382 /* Extract input bytes, add values, add 1 and half the 9383 result. */ 9384 assign(t0, unop(Iop_8Uto32, 9385 unop(Iop_16to8, 9386 unop(Iop_32to16, getIReg(rs))))); 9387 assign(t1, unop(Iop_8Uto32, 9388 unop(Iop_16to8, 9389 unop(Iop_32to16, getIReg(rt))))); 9390 assign(t2, unop(Iop_16to8, 9391 unop(Iop_32to16, 9392 binop(Iop_Shr32, 9393 binop(Iop_Add32, 9394 binop(Iop_Add32, 9395 mkexpr(t0), 9396 mkexpr(t1)), 9397 mkU32(0x00000001)), 9398 mkU8(0x01))))); 9399 9400 assign(t3, unop(Iop_8Uto32, 9401 unop(Iop_16HIto8, 9402 unop(Iop_32to16, getIReg(rs))))); 9403 assign(t4, unop(Iop_8Uto32, 9404 unop(Iop_16HIto8, 9405 unop(Iop_32to16, getIReg(rt))))); 9406 assign(t5, unop(Iop_16to8, 9407 unop(Iop_32to16, 9408 binop(Iop_Shr32, 9409 binop(Iop_Add32, 9410 binop(Iop_Add32, 9411 mkexpr(t3), 9412 mkexpr(t4)), 9413 mkU32(0x00000001)), 9414 mkU8(0x01))))); 9415 9416 assign(t6, unop(Iop_8Uto32, 9417 unop(Iop_16to8, 9418 unop(Iop_32HIto16, getIReg(rs))))); 9419 assign(t7, unop(Iop_8Uto32, 9420 unop(Iop_16to8, 9421 unop(Iop_32HIto16, getIReg(rt))))); 9422 assign(t8, unop(Iop_16to8, 9423 unop(Iop_32to16, 9424 binop(Iop_Shr32, 9425 binop(Iop_Add32, 9426 binop(Iop_Add32, 9427 mkexpr(t7), 9428 mkexpr(t6)), 9429 mkU32(0x00000001)), 9430 mkU8(0x01))))); 9431 9432 assign(t9, unop(Iop_8Uto32, 9433 unop(Iop_16HIto8, 9434 unop(Iop_32HIto16, getIReg(rs))))); 9435 assign(t10, unop(Iop_8Uto32, 9436 unop(Iop_16HIto8, 9437 unop(Iop_32HIto16, getIReg(rt))))); 9438 assign(t11, unop(Iop_16to8, 9439 unop(Iop_32to16, 9440 binop(Iop_Shr32, 9441 binop(Iop_Add32, 9442 binop(Iop_Add32, 9443 mkexpr(t9), 9444 mkexpr(t10)), 9445 mkU32(0x00000001)), 9446 mkU8(0x01))))); 9447 9448 putIReg(rd, binop(Iop_16HLto32, 9449 binop(Iop_8HLto16, 9450 mkexpr(t11), mkexpr(t8)), 9451 binop(Iop_8HLto16, 9452 mkexpr(t5), mkexpr(t2)))); 9453 break; 9454 } 9455 case 0x3: { /* SUBUH_R.QB */ 9456 DIP("subuh_r.qb r%d, r%d, r%d", rd, rs, rt); 9457 vassert(!mode64); 9458 t1 = newTemp(Ity_I32); 9459 t2 = newTemp(Ity_I32); 9460 t3 = newTemp(Ity_I32); 9461 t4 = newTemp(Ity_I32); 9462 t5 = newTemp(Ity_I32); 9463 t6 = newTemp(Ity_I32); 9464 t7 = newTemp(Ity_I32); 9465 t8 = newTemp(Ity_I32); 9466 t9 = newTemp(Ity_I8); 9467 t10 = newTemp(Ity_I8); 9468 t11 = newTemp(Ity_I8); 9469 t12 = newTemp(Ity_I8); 9470 9471 /* Extract each byte of rs and rt. */ 9472 assign(t1, unop(Iop_8Uto32, 9473 unop(Iop_16to8, 9474 unop(Iop_32to16, getIReg(rs))))); 9475 assign(t2, unop(Iop_8Uto32, 9476 unop(Iop_16HIto8, 9477 unop(Iop_32to16, getIReg(rs))))); 9478 assign(t3, unop(Iop_8Uto32, 9479 unop(Iop_16to8, 9480 unop(Iop_32HIto16, getIReg(rs))))); 9481 assign(t4, unop(Iop_8Uto32, 9482 unop(Iop_16HIto8, 9483 unop(Iop_32HIto16, getIReg(rs))))); 9484 9485 assign(t5, unop(Iop_8Uto32, 9486 unop(Iop_16to8, 9487 unop(Iop_32to16, getIReg(rt))))); 9488 assign(t6, unop(Iop_8Uto32, 9489 unop(Iop_16HIto8, 9490 unop(Iop_32to16, getIReg(rt))))); 9491 assign(t7, unop(Iop_8Uto32, 9492 unop(Iop_16to8, 9493 unop(Iop_32HIto16, getIReg(rt))))); 9494 assign(t8, unop(Iop_8Uto32, 9495 unop(Iop_16HIto8, 9496 unop(Iop_32HIto16, getIReg(rt))))); 9497 9498 /* Add 1 to each resulting byte and half the results. */ 9499 assign(t9, unop(Iop_16to8, 9500 unop(Iop_32to16, 9501 binop(Iop_Shr32, 9502 binop(Iop_Add32, 9503 binop(Iop_Sub32, 9504 mkexpr(t1), 9505 mkexpr(t5)), 9506 mkU32(0x00000001)), 9507 mkU8(0x01))))); 9508 assign(t10, unop(Iop_16to8, 9509 unop(Iop_32to16, 9510 binop(Iop_Shr32, 9511 binop(Iop_Add32, 9512 binop(Iop_Sub32, 9513 mkexpr(t2), 9514 mkexpr(t6)), 9515 mkU32(0x00000001)), 9516 mkU8(0x01))))); 9517 assign(t11, unop(Iop_16to8, 9518 unop(Iop_32to16, 9519 binop(Iop_Shr32, 9520 binop(Iop_Add32, 9521 binop(Iop_Sub32, 9522 mkexpr(t3), 9523 mkexpr(t7)), 9524 mkU32(0x00000001)), 9525 mkU8(0x01))))); 9526 assign(t12, unop(Iop_16to8, 9527 unop(Iop_32to16, 9528 binop(Iop_Shr32, 9529 binop(Iop_Add32, 9530 binop(Iop_Sub32, 9531 mkexpr(t4), 9532 mkexpr(t8)), 9533 mkU32(0x00000001)), 9534 mkU8(0x01))))); 9535 9536 putIReg(rd, binop(Iop_16HLto32, 9537 binop(Iop_8HLto16, 9538 mkexpr(t12), mkexpr(t11)), 9539 binop(Iop_8HLto16, 9540 mkexpr(t10), mkexpr(t9)))); 9541 break; 9542 } 9543 case 0x8: { /* ADDQH.PH */ 9544 DIP("addqh.ph r%d, r%d, r%d", rd, rs, rt); 9545 vassert(!mode64); 9546 t0 = newTemp(Ity_I32); 9547 t1 = newTemp(Ity_I16); 9548 t2 = newTemp(Ity_I32); 9549 t3 = newTemp(Ity_I16); 9550 9551 /* Add lower halfs of rs and rt 9552 and right shift the result by 1. */ 9553 assign(t0, binop(Iop_Add32, 9554 unop(Iop_16Sto32, 9555 unop(Iop_32to16, getIReg(rs))), 9556 unop(Iop_16Sto32, 9557 unop(Iop_32to16, getIReg(rt))))); 9558 assign(t1, unop(Iop_32to16, 9559 binop(Iop_Shr32, 9560 binop(Iop_And32, 9561 mkexpr(t0), 9562 mkU32(0x0001fffe)), 9563 mkU8(0x1)))); 9564 /* Add higher halfs of rs and rt 9565 and right shift the result by 1. */ 9566 assign(t2, binop(Iop_Add32, 9567 unop(Iop_16Sto32, 9568 unop(Iop_32HIto16, getIReg(rs))), 9569 unop(Iop_16Sto32, 9570 unop(Iop_32HIto16, getIReg(rt))))); 9571 assign(t3, unop(Iop_32to16, 9572 binop(Iop_Shr32, 9573 binop(Iop_And32, 9574 mkexpr(t2), 9575 mkU32(0x0001fffe)), 9576 mkU8(0x1)))); 9577 putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1))); 9578 break; 9579 } 9580 case 0x9: { /* SUBQH.PH */ 9581 DIP("subqh.ph r%d, r%d, r%d", rd, rs, rt); 9582 vassert(!mode64); 9583 9584 putIReg(rd, binop(Iop_HSub16Sx2, 9585 getIReg(rs), getIReg(rt))); 9586 break; 9587 } 9588 case 0xA: {/* ADDQH_R.PH */ 9589 DIP("addqh_r.ph r%d, r%d, r%d", rd, rs, rt); 9590 vassert(!mode64); 9591 t0 = newTemp(Ity_I32); 9592 t1 = newTemp(Ity_I16); 9593 t2 = newTemp(Ity_I32); 9594 t3 = newTemp(Ity_I16); 9595 9596 /* Add lower halfs of rs and rt, add 1 9597 and right shift the result by 1. */ 9598 assign(t0, binop(Iop_Add32, 9599 unop(Iop_16Sto32, 9600 unop(Iop_32to16, getIReg(rs))), 9601 unop(Iop_16Sto32, 9602 unop(Iop_32to16, getIReg(rt))))); 9603 assign(t1, unop(Iop_32to16, 9604 binop(Iop_Shr32, 9605 binop(Iop_And32, 9606 binop(Iop_Add32, 9607 mkexpr(t0), 9608 mkU32(0x1)), 9609 mkU32(0x0001fffe)), 9610 mkU8(0x1)))); 9611 /* Add higher halfs of rs and rt, add 1 9612 and right shift the result by 1. */ 9613 assign(t2, binop(Iop_Add32, 9614 unop(Iop_16Sto32, 9615 unop(Iop_32HIto16, getIReg(rs))), 9616 unop(Iop_16Sto32, 9617 unop(Iop_32HIto16, getIReg(rt))))); 9618 assign(t3, unop(Iop_32to16, 9619 binop(Iop_Shr32, 9620 binop(Iop_And32, 9621 binop(Iop_Add32, 9622 mkexpr(t2), 9623 mkU32(0x1)), 9624 mkU32(0x0001fffe)), 9625 mkU8(0x1)))); 9626 9627 putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1))); 9628 break; 9629 } 9630 case 0xB: { /* SUBQH_R.PH */ 9631 DIP("subqh_r.ph r%d, r%d, r%d", rd, rs, rt); 9632 vassert(!mode64); 9633 t0 = newTemp(Ity_I32); 9634 t1 = newTemp(Ity_I16); 9635 t2 = newTemp(Ity_I32); 9636 t3 = newTemp(Ity_I16); 9637 9638 /* Sub lower halfs of rs and rt, add 1 9639 and right shift the result by 1. */ 9640 assign(t0, binop(Iop_Sub32, 9641 unop(Iop_16Sto32, 9642 unop(Iop_32to16, getIReg(rs))), 9643 unop(Iop_16Sto32, 9644 unop(Iop_32to16, getIReg(rt))))); 9645 assign(t1, unop(Iop_32to16, 9646 binop(Iop_Shr32, 9647 binop(Iop_And32, 9648 binop(Iop_Add32, 9649 mkexpr(t0), 9650 mkU32(0x1)), 9651 mkU32(0x0001fffe)), 9652 mkU8(0x1)))); 9653 /* Sub higher halfs of rs and rt, add 1 9654 and right shift the result by 1. */ 9655 assign(t2, binop(Iop_Sub32, 9656 unop(Iop_16Sto32, 9657 unop(Iop_32HIto16, getIReg(rs))), 9658 unop(Iop_16Sto32, 9659 unop(Iop_32HIto16, getIReg(rt))))); 9660 assign(t3, unop(Iop_32to16, 9661 binop(Iop_Shr32, 9662 binop(Iop_And32, 9663 binop(Iop_Add32, 9664 mkexpr(t2), 9665 mkU32(0x1)), 9666 mkU32(0x0001fffe)), 9667 mkU8(0x1)))); 9668 9669 putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1))); 9670 break; 9671 } 9672 case 0xC: { /* MUL.PH */ 9673 DIP("mul.ph r%d, r%d, r%d", rd, rs, rt); 9674 vassert(!mode64); 9675 t0 = newTemp(Ity_I32); 9676 t1 = newTemp(Ity_I32); 9677 t2 = newTemp(Ity_I32); 9678 9679 assign(t0, 9680 binop(Iop_Mul32, 9681 unop(Iop_16Sto32, 9682 unop(Iop_32HIto16, getIReg(rs))), 9683 unop(Iop_16Sto32, 9684 unop(Iop_32HIto16, getIReg(rt))))); 9685 /* DSP Control flag. */ 9686 putDSPControl(IRExpr_ITE(unop(Iop_Not1, 9687 binop(Iop_CmpLE32S, 9688 mkexpr(t0), 9689 mkU32(0x7FFF))), 9690 binop(Iop_Or32, 9691 getDSPControl(), 9692 mkU32(0x00200000)), 9693 IRExpr_ITE(binop(Iop_CmpLT32S, 9694 mkexpr(t0), 9695 mkU32(0xFFFF8000) 9696 ), 9697 binop(Iop_Or32, 9698 getDSPControl(), 9699 mkU32(0x00200000) 9700 ), 9701 getDSPControl()))); 9702 9703 assign(t1, 9704 binop(Iop_Mul32, 9705 unop(Iop_16Sto32, 9706 unop(Iop_32to16, getIReg(rs))), 9707 unop(Iop_16Sto32, 9708 unop(Iop_32to16, getIReg(rt))))); 9709 /* DSP Control flag. */ 9710 putDSPControl(IRExpr_ITE(unop(Iop_Not1, 9711 binop(Iop_CmpLE32S, 9712 mkexpr(t1), 9713 mkU32(0x7FFF))), 9714 binop(Iop_Or32, 9715 getDSPControl(), 9716 mkU32(0x00200000)), 9717 IRExpr_ITE(binop(Iop_CmpLT32S, 9718 mkexpr(t1), 9719 mkU32(0xFFFF8000) 9720 ), 9721 binop(Iop_Or32, 9722 getDSPControl(), 9723 mkU32(0x00200000) 9724 ), 9725 getDSPControl()))); 9726 9727 assign(t2, binop(Iop_16HLto32, 9728 unop(Iop_32to16, mkexpr(t0)), 9729 unop(Iop_32to16, mkexpr(t1)))); 9730 putIReg(rd, mkexpr(t2)); 9731 break; 9732 } 9733 case 0xE: { /* MUL_S.PH */ 9734 DIP("mul_s.ph r%d r%d, r%d", rd, rs, rt); 9735 vassert(!mode64); 9736 9737 t0 = newTemp(Ity_I32); 9738 t1 = newTemp(Ity_I32); 9739 t2 = newTemp(Ity_I32); 9740 t3 = newTemp(Ity_I32); 9741 t4 = newTemp(Ity_I32); 9742 9743 /* t0 - signed intermediate result. */ 9744 assign(t0, 9745 binop(Iop_Mul32, 9746 unop(Iop_16Sto32, 9747 unop(Iop_32HIto16, getIReg(rs))), 9748 unop(Iop_16Sto32, 9749 unop(Iop_32HIto16, getIReg(rt))))); 9750 9751 assign(t1, 9752 IRExpr_ITE(unop(Iop_Not1, 9753 binop(Iop_CmpLE32S, 9754 mkexpr(t0), 9755 mkU32(0x7FFF))), 9756 mkU32(0x00007FFF), 9757 IRExpr_ITE(binop(Iop_CmpLT32S, 9758 mkexpr(t0), 9759 mkU32(0xFFFF8000)), 9760 mkU32(0xFFFF8000), 9761 mkexpr(t0)))); 9762 9763 /* DSP Control flag. */ 9764 putDSPControl(IRExpr_ITE(unop(Iop_Not1, 9765 binop(Iop_CmpLE32S, 9766 mkexpr(t0), 9767 mkU32(0x7FFF))), 9768 binop(Iop_Or32, 9769 getDSPControl(), 9770 mkU32(0x00200000)), 9771 IRExpr_ITE(binop(Iop_CmpLT32S, 9772 mkexpr(t0), 9773 mkU32(0xFFFF8000) 9774 ), 9775 binop(Iop_Or32, 9776 getDSPControl(), 9777 mkU32(0x00200000) 9778 ), 9779 getDSPControl()))); 9780 9781 /* t2 - signed intermediate result. */ 9782 assign(t2, binop(Iop_Mul32, 9783 unop(Iop_16Sto32, 9784 unop(Iop_32to16, getIReg(rs))), 9785 unop(Iop_16Sto32, 9786 unop(Iop_32to16, getIReg(rt))))); 9787 9788 assign(t3, IRExpr_ITE(unop(Iop_Not1, 9789 binop(Iop_CmpLE32S, 9790 mkexpr(t2), 9791 mkU32(0x7FFF))), 9792 mkU32(0x00007FFF), 9793 IRExpr_ITE(binop(Iop_CmpLT32S, 9794 mkexpr(t2), 9795 mkU32(0xFFFF8000)), 9796 mkU32(0xFFFF8000), 9797 mkexpr(t2)))); 9798 9799 /* DSP Control flag. */ 9800 putDSPControl(IRExpr_ITE(unop(Iop_Not1, 9801 binop(Iop_CmpLE32S, 9802 mkexpr(t2), 9803 mkU32(0x7FFF))), 9804 binop(Iop_Or32, 9805 getDSPControl(), 9806 mkU32(0x00200000)), 9807 IRExpr_ITE(binop(Iop_CmpLT32S, 9808 mkexpr(t2), 9809 mkU32(0xFFFF8000) 9810 ), 9811 binop(Iop_Or32, 9812 getDSPControl(), 9813 mkU32(0x00200000) 9814 ), 9815 getDSPControl()))); 9816 9817 assign(t4, binop(Iop_16HLto32, 9818 unop(Iop_32to16, mkexpr(t1)), 9819 unop(Iop_32to16, mkexpr(t3)))); 9820 putIReg(rd, mkexpr(t4)); 9821 break; 9822 } 9823 case 0x10: { /* ADDQH.W */ 9824 DIP("addqh.w r%d, r%d, r%d", rd, rs, rt); 9825 vassert(!mode64); 9826 t0 = newTemp(Ity_I64); 9827 t1 = newTemp(Ity_I64); 9828 9829 assign(t0, binop(Iop_Add64, 9830 unop(Iop_32Sto64, getIReg(rs)), 9831 unop(Iop_32Sto64, getIReg(rt)))); 9832 assign(t1, binop(Iop_And64, 9833 mkexpr(t0), 9834 mkU64(0x00000001fffffffeULL))); 9835 putIReg(rd, unop(Iop_64to32, 9836 binop(Iop_Shr64, mkexpr(t1), mkU8(0x1)))); 9837 break; 9838 } 9839 case 0x11: { /* SUBQH.W */ 9840 DIP("subqh.w r%d, r%d, r%d", rd, rs, rt); 9841 vassert(!mode64); 9842 t0 = newTemp(Ity_I64); 9843 t1 = newTemp(Ity_I64); 9844 9845 assign(t0, binop(Iop_Sub64, 9846 unop(Iop_32Sto64, getIReg(rs)), 9847 unop(Iop_32Sto64, getIReg(rt)))); 9848 assign(t1, binop(Iop_And64, 9849 mkexpr(t0), 9850 mkU64(0x00000001fffffffeULL))); 9851 putIReg(rd, unop(Iop_64to32, 9852 binop(Iop_Shr64, mkexpr(t1), mkU8(0x1)))); 9853 break; 9854 } 9855 case 0x12: { /* ADDQH_R.W */ 9856 DIP("addqh_r.w r%d, r%d, r%d", rd, rs, rt); 9857 vassert(!mode64); 9858 t0 = newTemp(Ity_I64); 9859 t1 = newTemp(Ity_I64); 9860 t2 = newTemp(Ity_I64); 9861 9862 assign(t0, binop(Iop_Add64, 9863 unop(Iop_32Sto64, getIReg(rs)), 9864 unop(Iop_32Sto64, getIReg(rt)))); 9865 assign(t1, binop(Iop_Add64, 9866 mkexpr(t0), 9867 mkU64(0x0000000000000001ULL))); 9868 assign(t2, binop(Iop_And64, 9869 mkexpr(t1), 9870 mkU64(0x00000001fffffffeULL))); 9871 putIReg(rd, unop(Iop_64to32, 9872 binop(Iop_Shr64, mkexpr(t2), mkU8(0x1)))); 9873 break; 9874 } 9875 case 0x13: { /* SUBQH_R.W */ 9876 DIP("subqh_r.w r%d, r%d, r%d", rd, rs, rt); 9877 vassert(!mode64); 9878 t0 = newTemp(Ity_I64); 9879 t1 = newTemp(Ity_I64); 9880 t2 = newTemp(Ity_I64); 9881 9882 assign(t0, binop(Iop_Sub64, 9883 unop(Iop_32Sto64, getIReg(rs)), 9884 unop(Iop_32Sto64, getIReg(rt)))); 9885 assign(t1, binop(Iop_Add64, 9886 mkexpr(t0), 9887 mkU64(0x0000000000000001ULL))); 9888 assign(t2, binop(Iop_And64, 9889 mkexpr(t1), 9890 mkU64(0x00000001fffffffeULL))); 9891 putIReg(rd, unop(Iop_64to32, 9892 binop(Iop_Shr64, mkexpr(t2), mkU8(0x1)))); 9893 break; 9894 } 9895 case 0x16: { /* MULQ_S.W */ 9896 DIP("mulq_s.w r%d, r%d, r%d", rd, rs, rt); 9897 vassert(!mode64); 9898 t0 = newTemp(Ity_I64); 9899 t1 = newTemp(Ity_I1); 9900 t2 = newTemp(Ity_I1); 9901 9902 assign(t0, binop(Iop_Shl64, 9903 binop(Iop_MullS32, 9904 getIReg(rt), getIReg(rs)), 9905 mkU8(0x1))); 9906 assign(t1, binop(Iop_CmpEQ32, 9907 getIReg(rt), mkU32(0x80000000))); 9908 assign(t2, binop(Iop_CmpEQ32, 9909 getIReg(rs), mkU32(0x80000000))); 9910 9911 putDSPControl(IRExpr_ITE(mkexpr(t1), 9912 IRExpr_ITE(mkexpr(t2), 9913 binop(Iop_Or32, 9914 getDSPControl(), 9915 mkU32(0x00200000) 9916 ), 9917 getDSPControl()), 9918 getDSPControl())); 9919 putIReg(rd, IRExpr_ITE(mkexpr(t1), 9920 IRExpr_ITE(mkexpr(t2), 9921 mkU32(0x7fffffff), 9922 unop(Iop_64HIto32, 9923 mkexpr(t0))), 9924 unop(Iop_64HIto32, mkexpr(t0)))); 9925 break; 9926 } 9927 case 0x17: { /* MULQ_RS.W */ 9928 DIP("mulq_rs.w r%d, r%d, r%d", rd, rs, rt); 9929 vassert(!mode64); 9930 t0 = newTemp(Ity_I64); 9931 t1 = newTemp(Ity_I1); 9932 t2 = newTemp(Ity_I1); 9933 9934 assign(t0, binop(Iop_Add64, 9935 binop(Iop_Shl64, 9936 binop(Iop_MullS32, 9937 getIReg(rt), 9938 getIReg(rs)), 9939 mkU8(0x1)), 9940 mkU64(0x0000000080000000ULL))); 9941 assign(t1, 9942 binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000))); 9943 assign(t2, 9944 binop(Iop_CmpEQ32, getIReg(rs), mkU32(0x80000000))); 9945 putDSPControl(IRExpr_ITE(mkexpr(t1), 9946 IRExpr_ITE(mkexpr(t2), 9947 binop(Iop_Or32, 9948 getDSPControl(), 9949 mkU32(0x00200000) 9950 ), 9951 getDSPControl()), 9952 getDSPControl())); 9953 putIReg(rd, IRExpr_ITE(mkexpr(t1), 9954 IRExpr_ITE(mkexpr(t2), 9955 mkU32(0x7fffffff), 9956 unop(Iop_64HIto32, 9957 mkexpr(t0))), 9958 unop(Iop_64HIto32, mkexpr(t0)))); 9959 break; 9960 } 9961 default: 9962 return -1; 9963 } 9964 break; /* end of ADDUH.QB/MUL.PH */ 9965 } 9966 case 0x30: { /* DPAQ.W.PH */ 9967 switch(sa) { 9968 case 0x0: { /* DPA.W.PH */ 9969 DIP("dpa.w.ph ac%d, r%d, r%d", ac, rs, rt); 9970 vassert(!mode64); 9971 9972 t0 = newTemp(Ity_I64); 9973 t1 = newTemp(Ity_I64); 9974 t2 = newTemp(Ity_I64); 9975 9976 assign(t0, 9977 unop(Iop_32Sto64, 9978 binop(Iop_Mul32, 9979 unop(Iop_16Sto32, 9980 unop(Iop_32HIto16, getIReg(rs))), 9981 unop(Iop_16Sto32, 9982 unop(Iop_32HIto16, getIReg(rt)))))); 9983 assign(t1, 9984 unop(Iop_32Sto64, 9985 binop(Iop_Mul32, 9986 unop(Iop_16Sto32, 9987 unop(Iop_32to16, getIReg(rs))), 9988 unop(Iop_16Sto32, 9989 unop(Iop_32to16, getIReg(rt)))))); 9990 assign(t2, 9991 binop(Iop_Add64, 9992 getAcc(ac), 9993 binop(Iop_Add64, mkexpr(t0), mkexpr(t1)))); 9994 putAcc(ac, mkexpr(t2)); 9995 break; 9996 } 9997 case 0x1: { /* DPS.W.PH */ 9998 DIP("dps.w.ph ac%d, r%d, r%d", ac, rs, rt); 9999 vassert(!mode64); 10000 10001 t0 = newTemp(Ity_I64); 10002 t1 = newTemp(Ity_I64); 10003 t2 = newTemp(Ity_I64); 10004 10005 assign(t0, 10006 unop(Iop_32Sto64, 10007 binop(Iop_Mul32, 10008 unop(Iop_16Sto32, 10009 unop(Iop_32HIto16, getIReg(rs))), 10010 unop(Iop_16Sto32, 10011 unop(Iop_32HIto16, getIReg(rt)))))); 10012 assign(t1, 10013 unop(Iop_32Sto64, 10014 binop(Iop_Mul32, 10015 unop(Iop_16Sto32, 10016 unop(Iop_32to16, getIReg(rs))), 10017 unop(Iop_16Sto32, 10018 unop(Iop_32to16, getIReg(rt)))))); 10019 assign(t2, 10020 binop(Iop_Sub64, 10021 getAcc(ac), 10022 binop(Iop_Add64, mkexpr(t0), mkexpr(t1)))); 10023 putAcc(ac, mkexpr(t2)); 10024 break; 10025 } 10026 case 0x2: { /* MULSA.W.PH */ 10027 DIP("mulsa.w.ph ac%d, r%d, r%d", ac, rs, rt); 10028 vassert(!mode64); 10029 t0 = newTemp(Ity_I32); 10030 t1 = newTemp(Ity_I32); 10031 t2 = newTemp(Ity_I32); 10032 t3 = newTemp(Ity_I1); 10033 t4 = newTemp(Ity_I64); 10034 10035 assign(t4, getAcc(ac)); 10036 assign(t0, binop(Iop_Mul32, 10037 unop(Iop_16Sto32, 10038 unop(Iop_32to16, getIReg(rt))), 10039 unop(Iop_16Sto32, 10040 unop(Iop_32to16, getIReg(rs))))); 10041 assign(t1, binop(Iop_Mul32, 10042 unop(Iop_16Sto32, 10043 unop(Iop_32HIto16, getIReg(rt))), 10044 unop(Iop_16Sto32, 10045 unop(Iop_32HIto16, getIReg(rs))))); 10046 assign(t2, binop(Iop_Sub32, mkexpr(t1), mkexpr(t0))); 10047 putAcc(ac, binop(Iop_Add64, 10048 mkexpr(t4), 10049 unop(Iop_32Sto64, mkexpr(t2)))); 10050 break; 10051 } 10052 case 0x3: { /* DPAU.H.QBL */ 10053 DIP("dpau.h.qbl ac%d, r%d, r%d", ac, rs, rt); 10054 vassert(!mode64); 10055 t0 = newTemp(Ity_I32); 10056 t1 = newTemp(Ity_I32); 10057 t2 = newTemp(Ity_I64); 10058 t3 = newTemp(Ity_I64); 10059 10060 assign(t0, 10061 binop(Iop_Mul32, 10062 unop(Iop_8Uto32, 10063 unop(Iop_16HIto8, 10064 unop(Iop_32HIto16, getIReg(rs)))), 10065 unop(Iop_8Uto32, 10066 unop(Iop_16HIto8, 10067 unop(Iop_32HIto16, getIReg(rt)))))); 10068 assign(t1, 10069 binop(Iop_Mul32, 10070 unop(Iop_8Uto32, 10071 unop(Iop_16to8, 10072 unop(Iop_32HIto16, getIReg(rs)))), 10073 unop(Iop_8Uto32, 10074 unop(Iop_16to8, 10075 unop(Iop_32HIto16, getIReg(rt)))))); 10076 assign(t2, 10077 unop(Iop_32Uto64, 10078 binop(Iop_Add32, 10079 mkexpr(t0), 10080 mkexpr(t1)))); 10081 assign(t3, 10082 binop(Iop_Add64, getAcc(ac), mkexpr(t2))); 10083 putAcc(ac, mkexpr(t3)); 10084 break; 10085 } 10086 case 0x4: { /* DPAQ_S.W.PH */ 10087 DIP("dpaq_s.w.ph ac%d, r%d, r%d", ac, rs, rt); 10088 vassert(!mode64); 10089 t0 = newTemp(Ity_I64); 10090 t1 = newTemp(Ity_I64); 10091 t2 = newTemp(Ity_I1); 10092 t3 = newTemp(Ity_I1); 10093 t4 = newTemp(Ity_I64); 10094 t5 = newTemp(Ity_I64); 10095 t6 = newTemp(Ity_I1); 10096 t7 = newTemp(Ity_I1); 10097 t8 = newTemp(Ity_I64); 10098 t9 = newTemp(Ity_I64); 10099 10100 assign(t0, getAcc(ac)); 10101 10102 assign(t1, binop(Iop_Shl64, 10103 binop(Iop_MullS32, 10104 unop(Iop_16Sto32, 10105 unop(Iop_32HIto16, 10106 getIReg(rs))), 10107 unop(Iop_16Sto32, 10108 unop(Iop_32HIto16, 10109 getIReg(rt)))), 10110 mkU8(0x1))); 10111 assign(t2, binop(Iop_CmpEQ32, 10112 unop(Iop_16Uto32, 10113 unop(Iop_32HIto16, getIReg(rs))), 10114 mkU32(0x00008000))); 10115 assign(t3, binop(Iop_CmpEQ32, 10116 unop(Iop_16Uto32, 10117 unop(Iop_32HIto16, getIReg(rt))), 10118 mkU32(0x00008000))); 10119 assign(t4, 10120 IRExpr_ITE(mkexpr(t2), 10121 IRExpr_ITE(mkexpr(t3), 10122 mkU64(0x000000007fffffffULL), 10123 mkexpr(t1)), 10124 mkexpr(t1))); 10125 10126 putDSPControl(IRExpr_ITE(mkexpr(t2), 10127 IRExpr_ITE(mkexpr(t3), 10128 binop(Iop_Or32, 10129 getDSPControl(), 10130 binop(Iop_Shl32, 10131 mkU32(0x1), 10132 mkU8(ac+16) 10133 ) 10134 ), 10135 getDSPControl()), 10136 getDSPControl())); 10137 10138 assign(t5, binop(Iop_Shl64, 10139 binop(Iop_MullS32, 10140 unop(Iop_16Sto32, 10141 unop(Iop_32to16, getIReg(rs))), 10142 unop(Iop_16Sto32, 10143 unop(Iop_32to16, getIReg(rt))) 10144 ), 10145 mkU8(0x1))); 10146 assign(t6, binop(Iop_CmpEQ32, 10147 unop(Iop_16Uto32, 10148 unop(Iop_32to16, getIReg(rs))), 10149 mkU32(0x00008000))); 10150 assign(t7, binop(Iop_CmpEQ32, 10151 unop(Iop_16Uto32, 10152 unop(Iop_32to16, getIReg(rt))), 10153 mkU32(0x00008000))); 10154 assign(t8, 10155 IRExpr_ITE(mkexpr(t6), 10156 IRExpr_ITE(mkexpr(t7), 10157 mkU64(0x000000007fffffffULL), 10158 mkexpr(t5)), 10159 mkexpr(t5))); 10160 10161 putDSPControl(IRExpr_ITE(mkexpr(t6), 10162 IRExpr_ITE(mkexpr(t7), 10163 binop(Iop_Or32, 10164 getDSPControl(), 10165 binop(Iop_Shl32, 10166 mkU32(0x1), 10167 mkU8(ac+16) 10168 ) 10169 ), 10170 getDSPControl()), 10171 getDSPControl())); 10172 10173 assign(t9, binop(Iop_Add64, 10174 binop(Iop_Add64, mkexpr(t4), mkexpr(t8)), 10175 mkexpr(t0))); 10176 putAcc(ac, mkexpr(t9)); 10177 break; 10178 } 10179 case 0x5: { /* DPSQ_S.W.PH */ 10180 DIP("dpsq_s.w.ph ac%d r%d, r%d", ac, rs, rt); 10181 vassert(!mode64); 10182 t0 = newTemp(Ity_I64); 10183 t1 = newTemp(Ity_I64); 10184 t2 = newTemp(Ity_I1); 10185 t3 = newTemp(Ity_I1); 10186 t4 = newTemp(Ity_I64); 10187 t5 = newTemp(Ity_I64); 10188 t6 = newTemp(Ity_I1); 10189 t7 = newTemp(Ity_I1); 10190 t8 = newTemp(Ity_I64); 10191 t9 = newTemp(Ity_I64); 10192 10193 assign(t0, getAcc(ac)); 10194 10195 assign(t1, binop(Iop_Shl64, 10196 binop(Iop_MullS32, 10197 unop(Iop_16Sto32, 10198 unop(Iop_32HIto16, 10199 getIReg(rs))), 10200 unop(Iop_16Sto32, 10201 unop(Iop_32HIto16, 10202 getIReg(rt)))), 10203 mkU8(0x1))); 10204 assign(t2, binop(Iop_CmpEQ32, 10205 unop(Iop_16Uto32, 10206 unop(Iop_32HIto16, getIReg(rs))), 10207 mkU32(0x00008000))); 10208 assign(t3, binop(Iop_CmpEQ32, 10209 unop(Iop_16Uto32, 10210 unop(Iop_32HIto16, getIReg(rt))), 10211 mkU32(0x00008000))); 10212 assign(t4, 10213 IRExpr_ITE(mkexpr(t2), 10214 IRExpr_ITE(mkexpr(t3), 10215 mkU64(0x000000007fffffffULL), 10216 mkexpr(t1)), 10217 mkexpr(t1))); 10218 10219 putDSPControl(IRExpr_ITE(mkexpr(t2), 10220 IRExpr_ITE(mkexpr(t3), 10221 binop(Iop_Or32, 10222 getDSPControl(), 10223 binop(Iop_Shl32, 10224 mkU32(0x1), 10225 mkU8(ac+16) 10226 ) 10227 ), 10228 getDSPControl()), 10229 getDSPControl())); 10230 10231 assign(t5, 10232 binop(Iop_Shl64, 10233 binop(Iop_MullS32, 10234 unop(Iop_16Sto32, 10235 unop(Iop_32to16, getIReg(rs))), 10236 unop(Iop_16Sto32, 10237 unop(Iop_32to16, getIReg(rt)))), 10238 mkU8(0x1))); 10239 assign(t6, binop(Iop_CmpEQ32, 10240 unop(Iop_16Uto32, 10241 unop(Iop_32to16, getIReg(rs))), 10242 mkU32(0x00008000))); 10243 assign(t7, binop(Iop_CmpEQ32, 10244 unop(Iop_16Uto32, 10245 unop(Iop_32to16, getIReg(rt))), 10246 mkU32(0x00008000))); 10247 assign(t8, 10248 IRExpr_ITE(mkexpr(t6), 10249 IRExpr_ITE(mkexpr(t7), 10250 mkU64(0x000000007fffffffULL), 10251 mkexpr(t5)), 10252 mkexpr(t5))); 10253 10254 putDSPControl(IRExpr_ITE(mkexpr(t6), 10255 IRExpr_ITE(mkexpr(t7), 10256 binop(Iop_Or32, 10257 getDSPControl(), 10258 binop(Iop_Shl32, 10259 mkU32(0x1), 10260 mkU8(ac+16) 10261 ) 10262 ), 10263 getDSPControl()), 10264 getDSPControl())); 10265 10266 assign(t9, 10267 binop(Iop_Sub64, 10268 mkexpr(t0), 10269 binop(Iop_Add64, mkexpr(t4), mkexpr(t8)))); 10270 putAcc(ac, mkexpr(t9)); 10271 break; 10272 } 10273 case 0x6: { /* MULSAQ_S.W.PH */ 10274 DIP("mulsaq_s.w.ph ac%d r%d, r%d", ac, rs, rt); 10275 vassert(!mode64); 10276 10277 t0 = newTemp(Ity_I32); 10278 t1 = newTemp(Ity_I32); 10279 t2 = newTemp(Ity_I32); 10280 t3 = newTemp(Ity_I32); 10281 t4 = newTemp(Ity_I32); 10282 t5 = newTemp(Ity_I32); 10283 t6 = newTemp(Ity_I64); 10284 t7 = newTemp(Ity_I64); 10285 t8 = newTemp(Ity_I32); 10286 t9 = newTemp(Ity_I32); 10287 10288 assign(t0, unop(Iop_16Sto32, 10289 unop(Iop_32HIto16, getIReg(rs)))); 10290 assign(t1, unop(Iop_16Sto32, 10291 unop(Iop_32HIto16, getIReg(rt)))); 10292 10293 assign(t8, binop(Iop_And32, 10294 unop(Iop_1Sto32, 10295 binop(Iop_CmpEQ32, 10296 unop(Iop_16Uto32, 10297 unop(Iop_32HIto16, 10298 getIReg(rs))), 10299 mkU32(0x8000))), 10300 unop(Iop_1Sto32, 10301 binop(Iop_CmpEQ32, 10302 unop(Iop_16Uto32, 10303 unop(Iop_32HIto16, 10304 getIReg(rt))), 10305 mkU32(0x8000))))); 10306 /* DSPControl_outflag:16+acc <- 1 */ 10307 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 10308 mkexpr(t8), 10309 mkU32(0x0)), 10310 binop(Iop_Or32, 10311 getDSPControl(), 10312 binop(Iop_Shl32, 10313 mkU32(0x00010000), 10314 mkU8(ac))), 10315 getDSPControl())); 10316 10317 /* tempB_31..0 */ 10318 assign(t2, 10319 IRExpr_ITE(binop(Iop_CmpNE32, 10320 mkexpr(t8), mkU32(0x0)), 10321 mkU32(0x7FFFFFFF), 10322 binop(Iop_Shl32, 10323 binop(Iop_Mul32, 10324 mkexpr(t0), mkexpr(t1)), 10325 mkU8(1)))); 10326 10327 assign(t3, unop(Iop_16Sto32, 10328 unop(Iop_32to16, getIReg(rs)))); 10329 assign(t4, unop(Iop_16Sto32, 10330 unop(Iop_32to16, getIReg(rt)))); 10331 10332 assign(t9, binop(Iop_And32, 10333 unop(Iop_1Sto32, 10334 binop(Iop_CmpEQ32, 10335 unop(Iop_16Uto32, 10336 unop(Iop_32to16, 10337 getIReg(rs))), 10338 mkU32(0x8000))), 10339 unop(Iop_1Sto32, 10340 binop(Iop_CmpEQ32, 10341 unop(Iop_16Uto32, 10342 unop(Iop_32to16, 10343 getIReg(rt))), 10344 mkU32(0x8000))))); 10345 /* DSPControl_outflag:16+acc <- 1 */ 10346 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 10347 mkexpr(t9), 10348 mkU32(0x0)), 10349 binop(Iop_Or32, 10350 getDSPControl(), 10351 binop(Iop_Shl32, 10352 mkU32(0x00010000), 10353 mkU8(ac))), 10354 getDSPControl())); 10355 /* tempA_31..0 */ 10356 assign(t5, 10357 IRExpr_ITE(binop(Iop_CmpNE32, 10358 mkexpr(t9), 10359 mkU32(0x0)), 10360 mkU32(0x7FFFFFFF), 10361 binop(Iop_Shl32, 10362 binop(Iop_Mul32, 10363 mkexpr(t3), 10364 mkexpr(t4)), 10365 mkU8(1)))); 10366 /* dotp_63..0 */ 10367 assign(t6, 10368 binop(Iop_Sub64, 10369 unop(Iop_32Sto64, mkexpr(t2)), 10370 unop(Iop_32Sto64, mkexpr(t5)))); 10371 /* tempC_63..0 */ 10372 assign(t7, binop(Iop_Add64, getAcc(ac), mkexpr(t6))); 10373 10374 putAcc(ac, mkexpr(t7)); 10375 break; 10376 } 10377 case 0x7: { /* DPAU.H.QBR */ 10378 DIP("dpau.h.qbr ac%d, r%d, r%d", ac, rs, rt); 10379 vassert(!mode64); 10380 t0 = newTemp(Ity_I32); 10381 t1 = newTemp(Ity_I32); 10382 t2 = newTemp(Ity_I64); 10383 t3 = newTemp(Ity_I64); 10384 10385 assign(t0, 10386 binop(Iop_Mul32, 10387 unop(Iop_8Uto32, 10388 unop(Iop_16HIto8, 10389 unop(Iop_32to16, getIReg(rs)))), 10390 unop(Iop_8Uto32, 10391 unop(Iop_16HIto8, 10392 unop(Iop_32to16, getIReg(rt)))))); 10393 assign(t1, 10394 binop(Iop_Mul32, 10395 unop(Iop_8Uto32, 10396 unop(Iop_16to8, 10397 unop(Iop_32to16, getIReg(rs)))), 10398 unop(Iop_8Uto32, 10399 unop(Iop_16to8, 10400 unop(Iop_32to16, getIReg(rt)))))); 10401 assign(t2, unop(Iop_32Uto64, 10402 binop(Iop_Add32, mkexpr(t0), mkexpr(t1)))); 10403 assign(t3, binop(Iop_Add64, getAcc(ac), mkexpr(t2))); 10404 putAcc(ac, mkexpr(t3)); 10405 break; 10406 } 10407 case 0x8: { /* DPAX.W.PH */ 10408 DIP("dpax.w.ph ac%d, r%d, r%d", ac, rs, rt); 10409 vassert(!mode64); 10410 t0 = newTemp(Ity_I64); 10411 t1 = newTemp(Ity_I64); 10412 t2 = newTemp(Ity_I64); 10413 10414 assign(t0, 10415 unop(Iop_32Sto64, 10416 binop(Iop_Mul32, 10417 unop(Iop_16Sto32, 10418 unop(Iop_32HIto16, getIReg(rs))), 10419 unop(Iop_16Sto32, 10420 unop(Iop_32to16, getIReg(rt)))))); 10421 assign(t1, 10422 unop(Iop_32Sto64, 10423 binop(Iop_Mul32, 10424 unop(Iop_16Sto32, 10425 unop(Iop_32to16, getIReg(rs))), 10426 unop(Iop_16Sto32, 10427 unop(Iop_32HIto16, getIReg(rt)))))); 10428 assign(t2, 10429 binop(Iop_Add64, 10430 getAcc(ac), 10431 binop(Iop_Add64, mkexpr(t0), mkexpr(t1)))); 10432 putAcc(ac, mkexpr(t2)); 10433 break; 10434 } 10435 case 0x9: { /* DPSX.W.PH */ 10436 DIP("dpsx.w.ph ac%d r%d, r%d", ac, rs, rt); 10437 vassert(!mode64); 10438 10439 t0 = newTemp(Ity_I64); 10440 t1 = newTemp(Ity_I64); 10441 t2 = newTemp(Ity_I64); 10442 10443 assign(t0, 10444 unop(Iop_32Sto64, 10445 binop(Iop_Mul32, 10446 unop(Iop_16Sto32, 10447 unop(Iop_32HIto16, getIReg(rs))), 10448 unop(Iop_16Sto32, 10449 unop(Iop_32to16, getIReg(rt)))))); 10450 assign(t1, 10451 unop(Iop_32Sto64, 10452 binop(Iop_Mul32, 10453 unop(Iop_16Sto32, 10454 unop(Iop_32to16, getIReg(rs))), 10455 unop(Iop_16Sto32, 10456 unop(Iop_32HIto16, getIReg(rt)))))); 10457 assign(t2, 10458 binop(Iop_Sub64, 10459 getAcc(ac), 10460 binop(Iop_Add64, mkexpr(t0), mkexpr(t1)))); 10461 putAcc(ac, mkexpr(t2)); 10462 break; 10463 } 10464 case 0xB: { /* DPSU.H.QBL */ 10465 DIP("dpsu.h.qbl ac%d, r%d, r%d", ac, rs, rt); 10466 vassert(!mode64); 10467 10468 t0 = newTemp(Ity_I32); 10469 t1 = newTemp(Ity_I32); 10470 t2 = newTemp(Ity_I64); 10471 t3 = newTemp(Ity_I64); 10472 10473 assign(t0, 10474 binop(Iop_Mul32, 10475 unop(Iop_8Uto32, 10476 unop(Iop_16HIto8, 10477 unop(Iop_32HIto16, getIReg(rs)))), 10478 unop(Iop_8Uto32, 10479 unop(Iop_16HIto8, 10480 unop(Iop_32HIto16, getIReg(rt)))))); 10481 assign(t1, 10482 binop(Iop_Mul32, 10483 unop(Iop_8Uto32, 10484 unop(Iop_16to8, 10485 unop(Iop_32HIto16, getIReg(rs)))), 10486 unop(Iop_8Uto32, 10487 unop(Iop_16to8, 10488 unop(Iop_32HIto16, getIReg(rt)))))); 10489 assign(t2, 10490 unop(Iop_32Uto64, 10491 binop(Iop_Add32, mkexpr(t0), mkexpr(t1)))); 10492 assign(t3, 10493 binop(Iop_Sub64, getAcc(ac), mkexpr(t2))); 10494 putAcc(ac, mkexpr(t3)); 10495 break; 10496 } 10497 case 0xC: { /* DPAQ_SA.L.W */ 10498 DIP("dpaq_sa.l.w ac%d, r%d, r%d", ac, rs, rt); 10499 vassert(!mode64); 10500 t0 = newTemp(Ity_I64); 10501 t1 = newTemp(Ity_I64); 10502 t2 = newTemp(Ity_I1); 10503 t3 = newTemp(Ity_I1); 10504 t4 = newTemp(Ity_I64); 10505 t5 = newTemp(Ity_I64); 10506 t6 = newTemp(Ity_I64); 10507 t7 = newTemp(Ity_I64); 10508 t8 = newTemp(Ity_I1); 10509 t9 = newTemp(Ity_I1); 10510 10511 assign(t0, getAcc(ac)); 10512 10513 assign(t1, binop(Iop_Shl64, 10514 binop(Iop_MullS32, 10515 getIReg(rs), getIReg(rt)), 10516 mkU8(0x1))); 10517 10518 assign(t2, binop(Iop_CmpEQ32, 10519 getIReg(rs), 10520 mkU32(0x80000000))); 10521 assign(t3, binop(Iop_CmpEQ32, 10522 getIReg(rt), 10523 mkU32(0x80000000))); 10524 10525 assign(t4, 10526 IRExpr_ITE(mkexpr(t2), 10527 IRExpr_ITE(mkexpr(t3), 10528 mkU64(0x7fffffffffffffffULL), 10529 mkexpr(t1)), 10530 mkexpr(t1))); 10531 10532 putDSPControl(IRExpr_ITE(mkexpr(t2), 10533 IRExpr_ITE(mkexpr(t3), 10534 binop(Iop_Or32, 10535 getDSPControl(), 10536 binop(Iop_Shl32, 10537 mkU32(0x1), 10538 mkU8(ac+16) 10539 ) 10540 ), 10541 getDSPControl()), 10542 getDSPControl())); 10543 10544 assign(t5, binop(Iop_Add64, 10545 unop(Iop_32Uto64, 10546 unop(Iop_64to32, mkexpr(t0))), 10547 unop(Iop_32Uto64, 10548 unop(Iop_64to32, mkexpr(t4))))); 10549 assign(t6, 10550 binop(Iop_Add64, 10551 binop(Iop_Add64, 10552 unop(Iop_32Sto64, 10553 unop(Iop_64HIto32, mkexpr(t0))), 10554 unop(Iop_32Sto64, 10555 unop(Iop_64HIto32, mkexpr(t4)))), 10556 unop(Iop_32Uto64, 10557 binop(Iop_And32, 10558 unop(Iop_64HIto32, mkexpr(t5)), 10559 mkU32(0x1))))); 10560 assign(t7, binop(Iop_32HLto64, 10561 unop(Iop_64to32, mkexpr(t6)), 10562 unop(Iop_64to32, mkexpr(t5)))); 10563 assign(t8, binop(Iop_CmpEQ32, 10564 binop(Iop_Shr32, 10565 binop(Iop_And32, 10566 unop(Iop_64to32, mkexpr(t6)), 10567 mkU32(0x80000000)), 10568 mkU8(31)), 10569 binop(Iop_And32, 10570 unop(Iop_64HIto32, mkexpr(t6)), 10571 mkU32(0x00000001)))); 10572 assign(t9, binop(Iop_CmpEQ32, 10573 binop(Iop_And32, 10574 unop(Iop_64HIto32, 10575 mkexpr(t6)), 10576 mkU32(0x00000001)), 10577 mkU32(0x1))); 10578 putDSPControl(IRExpr_ITE(mkexpr(t8), 10579 getDSPControl(), 10580 binop(Iop_Or32, 10581 getDSPControl(), 10582 binop(Iop_Shl32, 10583 mkU32(0x1), 10584 mkU8(ac+16))))); 10585 putAcc(ac, 10586 IRExpr_ITE(mkexpr(t8), 10587 mkexpr(t7), 10588 IRExpr_ITE(mkexpr(t9), 10589 mkU64(0x8000000000000000ULL), 10590 mkU64(0x7fffffffffffffffULL))) 10591 ); 10592 break; 10593 } 10594 case 0xD: { /* DPSQ_SA.L.W */ 10595 DIP("dpsq_sa.l.w ac%d, r%d, r%d", ac, rs, rt); 10596 vassert(!mode64); 10597 t0 = newTemp(Ity_I64); 10598 t1 = newTemp(Ity_I64); 10599 t2 = newTemp(Ity_I1); 10600 t3 = newTemp(Ity_I1); 10601 t4 = newTemp(Ity_I64); 10602 t5 = newTemp(Ity_I64); 10603 t6 = newTemp(Ity_I64); 10604 t7 = newTemp(Ity_I64); 10605 t8 = newTemp(Ity_I1); 10606 t9 = newTemp(Ity_I1); 10607 10608 assign(t0, getAcc(ac)); 10609 10610 assign(t1, binop(Iop_Shl64, 10611 binop(Iop_MullS32, 10612 getIReg(rs), getIReg(rt)), 10613 mkU8(0x1))); 10614 10615 assign(t2, binop(Iop_CmpEQ32, 10616 getIReg(rs), 10617 mkU32(0x80000000))); 10618 assign(t3, binop(Iop_CmpEQ32, 10619 getIReg(rt), 10620 mkU32(0x80000000))); 10621 10622 assign(t4, 10623 IRExpr_ITE(mkexpr(t2), 10624 IRExpr_ITE(mkexpr(t3), 10625 mkU64(0x7fffffffffffffffULL), 10626 mkexpr(t1)), 10627 mkexpr(t1))); 10628 10629 putDSPControl(IRExpr_ITE(mkexpr(t2), 10630 IRExpr_ITE(mkexpr(t3), 10631 binop(Iop_Or32, 10632 getDSPControl(), 10633 binop(Iop_Shl32, 10634 mkU32(0x1), 10635 mkU8(ac+16) 10636 ) 10637 ), 10638 getDSPControl()), 10639 getDSPControl())); 10640 10641 assign(t5, binop(Iop_Sub64, 10642 unop(Iop_32Uto64, 10643 unop(Iop_64to32, mkexpr(t0))), 10644 unop(Iop_32Uto64, 10645 unop(Iop_64to32, mkexpr(t4))))); 10646 assign(t6, binop(Iop_Sub64, 10647 binop(Iop_Add64, 10648 unop(Iop_32Sto64, 10649 unop(Iop_64HIto32, mkexpr(t0)) 10650 ), 10651 unop(Iop_32Sto64, 10652 unop(Iop_1Sto32, 10653 binop(Iop_CmpLT32U, 10654 unop(Iop_64to32, 10655 mkexpr(t0)), 10656 unop(Iop_64to32, 10657 mkexpr(t4)))))), 10658 unop(Iop_32Sto64, 10659 unop(Iop_64HIto32, mkexpr(t4))))); 10660 assign(t7, binop(Iop_32HLto64, 10661 unop(Iop_64to32, mkexpr(t6)), 10662 unop(Iop_64to32, mkexpr(t5)))); 10663 assign(t8, binop(Iop_CmpEQ32, 10664 binop(Iop_Shr32, 10665 binop(Iop_And32, 10666 unop(Iop_64to32, mkexpr(t6)), 10667 mkU32(0x80000000)), 10668 mkU8(31)), 10669 binop(Iop_And32, 10670 unop(Iop_64HIto32, mkexpr(t6)), 10671 mkU32(0x00000001)))); 10672 assign(t9, binop(Iop_CmpEQ32, 10673 binop(Iop_And32, 10674 unop(Iop_64HIto32, mkexpr(t6)), 10675 mkU32(0x00000001)), 10676 mkU32(0x1))); 10677 putDSPControl(IRExpr_ITE(mkexpr(t8), 10678 getDSPControl(), 10679 binop(Iop_Or32, 10680 getDSPControl(), 10681 binop(Iop_Shl32, 10682 mkU32(0x1), 10683 mkU8(ac+16))))); 10684 putAcc(ac, 10685 IRExpr_ITE(mkexpr(t8), 10686 mkexpr(t7), 10687 IRExpr_ITE(mkexpr(t9), 10688 mkU64(0x8000000000000000ULL), 10689 mkU64(0x7fffffffffffffffULL))) 10690 ); 10691 break; 10692 } 10693 case 0xF: { /* DPSU.H.QBR */ 10694 DIP("dpsu.h.qbr ac%d r%d, r%d", ac, rs, rt); 10695 vassert(!mode64); 10696 10697 t0 = newTemp(Ity_I32); 10698 t1 = newTemp(Ity_I32); 10699 t2 = newTemp(Ity_I64); 10700 t3 = newTemp(Ity_I64); 10701 10702 assign(t0, 10703 binop(Iop_Mul32, 10704 unop(Iop_8Uto32, 10705 unop(Iop_16HIto8, 10706 unop(Iop_32to16, getIReg(rs)))), 10707 unop(Iop_8Uto32, 10708 unop(Iop_16HIto8, 10709 unop(Iop_32to16, getIReg(rt)))))); 10710 assign(t1, 10711 binop(Iop_Mul32, 10712 unop(Iop_8Uto32, 10713 unop(Iop_16to8, 10714 unop(Iop_32to16, getIReg(rs)))), 10715 unop(Iop_8Uto32, 10716 unop(Iop_16to8, 10717 unop(Iop_32to16, getIReg(rt)))))); 10718 assign(t2, unop(Iop_32Uto64, 10719 binop(Iop_Add32, mkexpr(t0), mkexpr(t1)))); 10720 assign(t3, binop(Iop_Sub64, getAcc(ac), mkexpr(t2))); 10721 putAcc(ac, mkexpr(t3)); 10722 10723 break; 10724 } 10725 case 0x10: { /* MAQ_SA.W.PHL */ 10726 DIP("maq_sa.w.phl ac%d, r%d, r%d", ac, rs, rt); 10727 vassert(!mode64); 10728 t0 = newTemp(Ity_I64); 10729 t1 = newTemp(Ity_I64); 10730 t2 = newTemp(Ity_I1); 10731 t3 = newTemp(Ity_I1); 10732 t4 = newTemp(Ity_I64); 10733 t5 = newTemp(Ity_I64); 10734 t6 = newTemp(Ity_I1); 10735 t7 = newTemp(Ity_I64); 10736 10737 assign(t0, getAcc(ac)); 10738 assign(t1, unop(Iop_32Sto64, 10739 binop(Iop_Shl32, 10740 binop(Iop_Mul32, 10741 unop(Iop_16Sto32, 10742 unop(Iop_32HIto16, 10743 getIReg(rs))), 10744 unop(Iop_16Sto32, 10745 unop(Iop_32HIto16, 10746 getIReg(rt)))), 10747 mkU8(0x1)))); 10748 10749 /* If both input arguments are equal 0x8000, saturate 10750 intermediate product and write to DSPControl register. 10751 */ 10752 assign(t2, binop(Iop_CmpEQ32, 10753 unop(Iop_16Uto32, 10754 unop(Iop_32HIto16, getIReg(rs))), 10755 mkU32(0x00008000))); 10756 assign(t3, binop(Iop_CmpEQ32, 10757 unop(Iop_16Uto32, 10758 unop(Iop_32HIto16, getIReg(rt))), 10759 mkU32(0x00008000))); 10760 10761 assign(t4, 10762 IRExpr_ITE(mkexpr(t2), 10763 IRExpr_ITE(mkexpr(t3), 10764 mkU64(0x000000007fffffffULL), 10765 mkexpr(t1)), 10766 mkexpr(t1))); 10767 10768 putDSPControl(IRExpr_ITE(mkexpr(t2), 10769 IRExpr_ITE(mkexpr(t3), 10770 binop(Iop_Or32, 10771 getDSPControl(), 10772 binop(Iop_Shl32, 10773 mkU32(0x1), 10774 mkU8(ac+16) 10775 ) 10776 ), 10777 getDSPControl()), 10778 getDSPControl())); 10779 /* Add intermediate product and value in the 10780 accumulator. */ 10781 assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4))); 10782 10783 /* Compare bits 31 and 32 of the value in t5. */ 10784 assign(t6, binop(Iop_CmpEQ32, 10785 binop(Iop_Shr32, 10786 binop(Iop_And32, 10787 unop(Iop_64to32, mkexpr(t5)), 10788 mkU32(0x80000000)), 10789 mkU8(31)), 10790 binop(Iop_And32, 10791 unop(Iop_64HIto32, mkexpr(t5)), 10792 mkU32(1)))); 10793 putDSPControl(IRExpr_ITE(mkexpr(t6), 10794 getDSPControl(), 10795 binop(Iop_Or32, 10796 getDSPControl(), 10797 binop(Iop_Shl32, 10798 mkU32(0x1), 10799 mkU8(ac+16))))); 10800 assign(t7, 10801 IRExpr_ITE(mkexpr(t6), 10802 mkexpr(t5), 10803 IRExpr_ITE(binop(Iop_CmpEQ32, 10804 binop(Iop_And32, 10805 unop(Iop_64HIto32, 10806 mkexpr(t5)), 10807 mkU32(1)), 10808 mkU32(0x0)), 10809 mkU64(0x000000007fffffffULL), 10810 mkU64(0xffffffff80000000ULL))) 10811 ); 10812 putAcc(ac, mkexpr(t7)); 10813 break; 10814 } 10815 case 0x12: { /* MAQ_SA.W.PHR */ 10816 DIP("maq_sa.w.phr ac%d, r%d, r%d", ac, rs, rt); 10817 vassert(!mode64); 10818 t0 = newTemp(Ity_I64); 10819 t1 = newTemp(Ity_I64); 10820 t2 = newTemp(Ity_I1); 10821 t3 = newTemp(Ity_I1); 10822 t4 = newTemp(Ity_I64); 10823 t5 = newTemp(Ity_I64); 10824 t6 = newTemp(Ity_I1); 10825 t7 = newTemp(Ity_I64); 10826 10827 assign(t0, getAcc(ac)); 10828 assign(t1, unop(Iop_32Sto64, 10829 binop(Iop_Shl32, 10830 binop(Iop_Mul32, 10831 unop(Iop_16Sto32, 10832 unop(Iop_32to16, 10833 getIReg(rs))), 10834 unop(Iop_16Sto32, 10835 unop(Iop_32to16, 10836 getIReg(rt)))), 10837 mkU8(0x1)))); 10838 10839 /* If both input arguments are equal 0x8000, saturate 10840 intermediate product and write to DSPControl 10841 register. */ 10842 assign(t2, binop(Iop_CmpEQ32, 10843 unop(Iop_16Uto32, 10844 unop(Iop_32to16, getIReg(rs))), 10845 mkU32(0x00008000))); 10846 assign(t3, binop(Iop_CmpEQ32, 10847 unop(Iop_16Uto32, 10848 unop(Iop_32to16, getIReg(rt))), 10849 mkU32(0x00008000))); 10850 10851 assign(t4, 10852 IRExpr_ITE(mkexpr(t2), 10853 IRExpr_ITE(mkexpr(t3), 10854 mkU64(0x000000007fffffffULL), 10855 mkexpr(t1)), 10856 mkexpr(t1))); 10857 10858 putDSPControl(IRExpr_ITE(mkexpr(t2), 10859 IRExpr_ITE(mkexpr(t3), 10860 binop(Iop_Or32, 10861 getDSPControl(), 10862 binop(Iop_Shl32, 10863 mkU32(0x1), 10864 mkU8(ac+16) 10865 ) 10866 ), 10867 getDSPControl()), 10868 getDSPControl())); 10869 /* Add intermediate product and value in the 10870 accumulator. */ 10871 assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4))); 10872 10873 /* Compare bits 31 and 32 of the value in t5. */ 10874 assign(t6, binop(Iop_CmpEQ32, 10875 binop(Iop_Shr32, 10876 binop(Iop_And32, 10877 unop(Iop_64to32, mkexpr(t5)), 10878 mkU32(0x80000000)), 10879 mkU8(31)), 10880 binop(Iop_And32, 10881 unop(Iop_64HIto32, mkexpr(t5)), 10882 mkU32(1)))); 10883 putDSPControl(IRExpr_ITE(mkexpr(t6), 10884 getDSPControl(), 10885 binop(Iop_Or32, 10886 getDSPControl(), 10887 binop(Iop_Shl32, 10888 mkU32(0x1), 10889 mkU8(ac+16))))); 10890 assign(t7, 10891 IRExpr_ITE(mkexpr(t6), 10892 mkexpr(t5), 10893 IRExpr_ITE(binop(Iop_CmpEQ32, 10894 binop(Iop_And32, 10895 unop(Iop_64HIto32, 10896 mkexpr(t5)), 10897 mkU32(1)), 10898 mkU32(0x0)), 10899 mkU64(0x000000007fffffffULL), 10900 mkU64(0xffffffff80000000ULL))) 10901 ); 10902 putAcc(ac, mkexpr(t7)); 10903 break; 10904 } 10905 case 0x14: { /* MAQ_S.W.PHL */ 10906 DIP("maq_s.w.phl ac%d, r%d, r%d", ac, rs, rt); 10907 vassert(!mode64); 10908 t0 = newTemp(Ity_I32); 10909 t1 = newTemp(Ity_I32); 10910 t2 = newTemp(Ity_I32); 10911 t3 = newTemp(Ity_I1); 10912 t4 = newTemp(Ity_I32); 10913 t5 = newTemp(Ity_I64); 10914 10915 assign(t5, getAcc(ac)); 10916 10917 assign(t0, unop(Iop_16Sto32, 10918 unop(Iop_32HIto16, getIReg(rs)))); 10919 assign(t1, unop(Iop_16Sto32, 10920 unop(Iop_32HIto16, getIReg(rt)))); 10921 10922 assign(t2, binop(Iop_And32, 10923 unop(Iop_1Sto32, 10924 binop(Iop_CmpEQ32, 10925 binop(Iop_And32, 10926 mkexpr(t0), 10927 mkU32(0xffff)), 10928 mkU32(0x8000))), 10929 unop(Iop_1Sto32, 10930 binop(Iop_CmpEQ32, 10931 binop(Iop_And32, 10932 mkexpr(t1), 10933 mkU32(0xffff)), 10934 mkU32(0x8000))))); 10935 10936 assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0))); 10937 10938 putDSPControl(IRExpr_ITE(mkexpr(t3), 10939 getDSPControl(), 10940 binop(Iop_Or32, 10941 getDSPControl(), 10942 binop(Iop_Shl32, 10943 mkU32(0x1), 10944 mkU8(ac+16))))); 10945 10946 assign(t4, unop(Iop_64to32, 10947 binop(Iop_MullS32, 10948 mkexpr(t0), mkexpr(t1)))); 10949 putAcc(ac, IRExpr_ITE(mkexpr(t3), 10950 binop(Iop_Add64, 10951 unop(Iop_32Sto64, 10952 binop(Iop_Shl32, 10953 mkexpr(t4), 10954 mkU8(0x1))), 10955 mkexpr(t5)), 10956 binop(Iop_Add64, 10957 mkexpr(t5), 10958 unop(Iop_32Sto64, 10959 mkU32(0x7fffffff))))); 10960 break; 10961 } 10962 case 0x16: { /* MAQ_S.W.PHR */ 10963 DIP("maq_s.w.phr ac%d, r%d, r%d", ac, rs, rt); 10964 vassert(!mode64); 10965 t0 = newTemp(Ity_I32); 10966 t1 = newTemp(Ity_I32); 10967 t2 = newTemp(Ity_I32); 10968 t3 = newTemp(Ity_I1); 10969 t4 = newTemp(Ity_I32); 10970 t5 = newTemp(Ity_I64); 10971 10972 assign(t5, getAcc(ac)); 10973 10974 assign(t0, unop(Iop_16Sto32, 10975 unop(Iop_32to16, getIReg(rs)))); 10976 assign(t1, unop(Iop_16Sto32, 10977 unop(Iop_32to16, getIReg(rt)))); 10978 10979 assign(t2, binop(Iop_And32, 10980 unop(Iop_1Sto32, 10981 binop(Iop_CmpEQ32, 10982 binop(Iop_And32, 10983 mkexpr(t0), 10984 mkU32(0xffff)), 10985 mkU32(0x8000))), 10986 unop(Iop_1Sto32, 10987 binop(Iop_CmpEQ32, 10988 binop(Iop_And32, 10989 mkexpr(t1), 10990 mkU32(0xffff)), 10991 mkU32(0x8000))))); 10992 10993 assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0))); 10994 10995 putDSPControl(IRExpr_ITE(mkexpr(t3), 10996 getDSPControl(), 10997 binop(Iop_Or32, 10998 getDSPControl(), 10999 binop(Iop_Shl32, 11000 mkU32(0x1), 11001 mkU8(ac+16))))); 11002 11003 assign(t4, unop(Iop_64to32, 11004 binop(Iop_MullS32, 11005 mkexpr(t0), mkexpr(t1)))); 11006 putAcc(ac, IRExpr_ITE(mkexpr(t3), 11007 binop(Iop_Add64, 11008 unop(Iop_32Sto64, 11009 binop(Iop_Shl32, 11010 mkexpr(t4), 11011 mkU8(0x1))), 11012 mkexpr(t5)), 11013 binop(Iop_Add64, 11014 mkexpr(t5), 11015 unop(Iop_32Sto64, 11016 mkU32(0x7fffffff))))); 11017 break; 11018 } 11019 case 0x18: { /* DPAQX_S.W.PH */ 11020 DIP("dpaqx_s.w.ph ac%d, r%d, r%d", ac, rs, rt); 11021 vassert(!mode64); 11022 t0 = newTemp(Ity_I64); 11023 t1 = newTemp(Ity_I64); 11024 t2 = newTemp(Ity_I1); 11025 t3 = newTemp(Ity_I1); 11026 t4 = newTemp(Ity_I64); 11027 t5 = newTemp(Ity_I64); 11028 t6 = newTemp(Ity_I1); 11029 t7 = newTemp(Ity_I1); 11030 t8 = newTemp(Ity_I64); 11031 t9 = newTemp(Ity_I64); 11032 11033 assign(t0, getAcc(ac)); 11034 11035 assign(t1, binop(Iop_Shl64, 11036 binop(Iop_MullS32, 11037 unop(Iop_16Sto32, 11038 unop(Iop_32HIto16, 11039 getIReg(rs))), 11040 unop(Iop_16Sto32, 11041 unop(Iop_32to16, 11042 getIReg(rt)))), 11043 mkU8(0x1))); 11044 assign(t2, binop(Iop_CmpEQ32, 11045 unop(Iop_16Uto32, 11046 unop(Iop_32HIto16, getIReg(rs))), 11047 mkU32(0x00008000))); 11048 assign(t3, binop(Iop_CmpEQ32, 11049 unop(Iop_16Uto32, 11050 unop(Iop_32to16, getIReg(rt))), 11051 mkU32(0x00008000))); 11052 assign(t4, 11053 IRExpr_ITE(mkexpr(t2), 11054 IRExpr_ITE(mkexpr(t3), 11055 mkU64(0x000000007fffffffULL), 11056 mkexpr(t1)), 11057 mkexpr(t1))); 11058 11059 putDSPControl(IRExpr_ITE(mkexpr(t2), 11060 IRExpr_ITE(mkexpr(t3), 11061 binop(Iop_Or32, 11062 getDSPControl(), 11063 binop(Iop_Shl32, 11064 mkU32(0x1), 11065 mkU8(ac+16))), 11066 getDSPControl()), 11067 getDSPControl())); 11068 11069 assign(t5, binop(Iop_Shl64, 11070 binop(Iop_MullS32, 11071 unop(Iop_16Sto32, 11072 unop(Iop_32to16, 11073 getIReg(rs))), 11074 unop(Iop_16Sto32, 11075 unop(Iop_32HIto16, 11076 getIReg(rt)))), 11077 mkU8(0x1))); 11078 assign(t6, binop(Iop_CmpEQ32, 11079 unop(Iop_16Uto32, 11080 unop(Iop_32to16, getIReg(rs))), 11081 mkU32(0x00008000))); 11082 assign(t7, binop(Iop_CmpEQ32, 11083 unop(Iop_16Uto32, 11084 unop(Iop_32HIto16, getIReg(rt))), 11085 mkU32(0x00008000))); 11086 assign(t8, 11087 IRExpr_ITE(mkexpr(t6), 11088 IRExpr_ITE(mkexpr(t7), 11089 mkU64(0x000000007fffffffULL), 11090 mkexpr(t5)), 11091 mkexpr(t5))); 11092 11093 putDSPControl(IRExpr_ITE(mkexpr(t6), 11094 IRExpr_ITE(mkexpr(t7), 11095 binop(Iop_Or32, 11096 getDSPControl(), 11097 binop(Iop_Shl32, 11098 mkU32(0x1), 11099 mkU8(ac+16) 11100 ) 11101 ), 11102 getDSPControl()), 11103 getDSPControl())); 11104 11105 assign(t9, binop(Iop_Add64, 11106 binop(Iop_Add64, mkexpr(t4), mkexpr(t8)), 11107 mkexpr(t0))); 11108 putAcc(ac, mkexpr(t9)); 11109 break; 11110 } 11111 case 0x19: { /* DPSQX_S.W.PH */ 11112 DIP("dpsqx_s.w.ph ac%d, r%d, r%d", ac, rs, rt); 11113 vassert(!mode64); 11114 t0 = newTemp(Ity_I64); 11115 t1 = newTemp(Ity_I64); 11116 t2 = newTemp(Ity_I1); 11117 t3 = newTemp(Ity_I1); 11118 t4 = newTemp(Ity_I64); 11119 t5 = newTemp(Ity_I64); 11120 t6 = newTemp(Ity_I1); 11121 t7 = newTemp(Ity_I1); 11122 t8 = newTemp(Ity_I64); 11123 t9 = newTemp(Ity_I64); 11124 11125 assign(t0, getAcc(ac)); 11126 11127 assign(t1, binop(Iop_Shl64, 11128 binop(Iop_MullS32, 11129 unop(Iop_16Sto32, 11130 unop(Iop_32HIto16, 11131 getIReg(rs))), 11132 unop(Iop_16Sto32, 11133 unop(Iop_32to16, 11134 getIReg(rt)))), 11135 mkU8(0x1))); 11136 assign(t2, binop(Iop_CmpEQ32, 11137 unop(Iop_16Uto32, 11138 unop(Iop_32HIto16, getIReg(rs))), 11139 mkU32(0x00008000))); 11140 assign(t3, binop(Iop_CmpEQ32, 11141 unop(Iop_16Uto32, 11142 unop(Iop_32to16, getIReg(rt))), 11143 mkU32(0x00008000))); 11144 assign(t4, 11145 IRExpr_ITE(mkexpr(t2), 11146 IRExpr_ITE(mkexpr(t3), 11147 mkU64(0x000000007fffffffULL), 11148 mkexpr(t1)), 11149 mkexpr(t1))); 11150 11151 putDSPControl(IRExpr_ITE(mkexpr(t2), 11152 IRExpr_ITE(mkexpr(t3), 11153 binop(Iop_Or32, 11154 getDSPControl(), 11155 binop(Iop_Shl32, 11156 mkU32(0x1), 11157 mkU8(ac+16) 11158 ) 11159 ), 11160 getDSPControl()), 11161 getDSPControl())); 11162 11163 assign(t5, binop(Iop_Shl64, 11164 binop(Iop_MullS32, 11165 unop(Iop_16Sto32, 11166 unop(Iop_32to16, 11167 getIReg(rs))), 11168 unop(Iop_16Sto32, 11169 unop(Iop_32HIto16, 11170 getIReg(rt)))), 11171 mkU8(0x1))); 11172 assign(t6, binop(Iop_CmpEQ32, 11173 unop(Iop_16Uto32, 11174 unop(Iop_32to16, getIReg(rs))), 11175 mkU32(0x00008000))); 11176 assign(t7, binop(Iop_CmpEQ32, 11177 unop(Iop_16Uto32, 11178 unop(Iop_32HIto16, getIReg(rt))), 11179 mkU32(0x00008000))); 11180 assign(t8, 11181 IRExpr_ITE(mkexpr(t6), 11182 IRExpr_ITE(mkexpr(t7), 11183 mkU64(0x000000007fffffffULL), 11184 mkexpr(t5)), 11185 mkexpr(t5))); 11186 11187 putDSPControl(IRExpr_ITE(mkexpr(t6), 11188 IRExpr_ITE(mkexpr(t7), 11189 binop(Iop_Or32, 11190 getDSPControl(), 11191 binop(Iop_Shl32, 11192 mkU32(0x1), 11193 mkU8(ac+16) 11194 ) 11195 ), 11196 getDSPControl()), 11197 getDSPControl())); 11198 11199 assign(t9, binop(Iop_Sub64, 11200 mkexpr(t0), 11201 binop(Iop_Add64, mkexpr(t4), mkexpr(t8)))); 11202 putAcc(ac, mkexpr(t9)); 11203 break; 11204 } 11205 case 0x1A: { /* DPAQX_SA.W.PH */ 11206 DIP("dpaqx_sa.w.ph ac%d, r%d, r%d", ac, rs, rt); 11207 vassert(!mode64); 11208 t0 = newTemp(Ity_I64); 11209 t1 = newTemp(Ity_I64); 11210 t2 = newTemp(Ity_I1); 11211 t3 = newTemp(Ity_I1); 11212 t4 = newTemp(Ity_I64); 11213 t5 = newTemp(Ity_I64); 11214 t6 = newTemp(Ity_I1); 11215 t7 = newTemp(Ity_I1); 11216 t8 = newTemp(Ity_I64); 11217 t9 = newTemp(Ity_I64); 11218 t10 = newTemp(Ity_I32); 11219 11220 assign(t0, getAcc(ac)); 11221 /* Calculate the first cross dot product and saturate if 11222 needed. */ 11223 assign(t1, unop(Iop_32Sto64, 11224 binop(Iop_Shl32, 11225 binop(Iop_Mul32, 11226 unop(Iop_16Sto32, 11227 unop(Iop_32HIto16, 11228 getIReg(rs))), 11229 unop(Iop_16Sto32, 11230 unop(Iop_32to16, 11231 getIReg(rt)))), 11232 mkU8(0x1)))); 11233 11234 /* If both input arguments are equal 0x8000, saturate 11235 intermediate product and write to DSPControl 11236 register. */ 11237 assign(t2, binop(Iop_CmpEQ32, 11238 unop(Iop_16Uto32, 11239 unop(Iop_32HIto16, getIReg(rs))), 11240 mkU32(0x00008000))); 11241 assign(t3, binop(Iop_CmpEQ32, 11242 unop(Iop_16Uto32, 11243 unop(Iop_32to16, getIReg(rt))), 11244 mkU32(0x00008000))); 11245 11246 assign(t4, IRExpr_ITE(binop(Iop_CmpNE32, 11247 binop(Iop_And32, 11248 unop(Iop_1Sto32, 11249 mkexpr(t2)), 11250 unop(Iop_1Sto32, 11251 mkexpr(t3))), 11252 mkU32(0)), 11253 mkU64(0x000000007fffffffULL), 11254 mkexpr(t1))); 11255 11256 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 11257 binop(Iop_And32, 11258 unop(Iop_1Sto32, 11259 mkexpr(t2)), 11260 unop(Iop_1Sto32, 11261 mkexpr(t3))), 11262 mkU32(0)), 11263 binop(Iop_Or32, 11264 getDSPControl(), 11265 binop(Iop_Shl32, 11266 mkU32(0x1), 11267 mkU8(ac+16))), 11268 getDSPControl())); 11269 /* Calculate second cross dot product and saturate if 11270 needed. */ 11271 assign(t5, unop(Iop_32Sto64, 11272 binop(Iop_Shl32, 11273 binop(Iop_Mul32, 11274 unop(Iop_16Sto32, 11275 unop(Iop_32to16, 11276 getIReg(rs))), 11277 unop(Iop_16Sto32, 11278 unop(Iop_32HIto16, 11279 getIReg(rt)))), 11280 mkU8(0x1)))); 11281 11282 /* If both input arguments are equal 0x8000, saturate 11283 intermediate product and write to DSPControl 11284 register. */ 11285 assign(t6, binop(Iop_CmpEQ32, 11286 unop(Iop_16Uto32, 11287 unop(Iop_32to16, getIReg(rs))), 11288 mkU32(0x00008000))); 11289 assign(t7, binop(Iop_CmpEQ32, 11290 unop(Iop_16Uto32, 11291 unop(Iop_32HIto16, getIReg(rt))), 11292 mkU32(0x00008000))); 11293 11294 assign(t8, IRExpr_ITE(binop(Iop_CmpNE32, 11295 binop(Iop_And32, 11296 unop(Iop_1Sto32, 11297 mkexpr(t6)), 11298 unop(Iop_1Sto32, 11299 mkexpr(t7))), 11300 mkU32(0)), 11301 mkU64(0x000000007fffffffULL), 11302 mkexpr(t5))); 11303 11304 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 11305 binop(Iop_And32, 11306 unop(Iop_1Sto32, 11307 mkexpr(t6)), 11308 unop(Iop_1Sto32, 11309 mkexpr(t7))), 11310 mkU32(0)), 11311 binop(Iop_Or32, 11312 getDSPControl(), 11313 binop(Iop_Shl32, 11314 mkU32(0x1), 11315 mkU8(ac+16))), 11316 getDSPControl())); 11317 /* Subtract intermediate products from value in the 11318 accumulator. */ 11319 assign(t9, 11320 binop(Iop_Add64, 11321 mkexpr(t0), 11322 binop(Iop_Add64, mkexpr(t8), mkexpr(t4)))); 11323 11324 putAcc(ac, 11325 IRExpr_ITE(binop(Iop_CmpEQ32, 11326 binop(Iop_And32, 11327 unop(Iop_64HIto32, 11328 mkexpr(t9)), 11329 mkU32(0x80000000)), 11330 mkU32(0x0)), 11331 IRExpr_ITE(binop(Iop_CmpNE32, 11332 unop(Iop_64HIto32, 11333 binop(Iop_Shl64, 11334 mkexpr(t9), 11335 mkU8(1))), 11336 mkU32(0x0)), 11337 mkU64(0x000000007fffffffULL), 11338 mkexpr(t9)), 11339 IRExpr_ITE(binop(Iop_CmpNE32, 11340 unop(Iop_64HIto32, 11341 binop(Iop_Shl64, 11342 mkexpr(t9), 11343 mkU8(1))), 11344 mkU32(0xffffffff)), 11345 mkU64(0xffffffff80000000ULL), 11346 mkexpr(t9)))); 11347 assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32, 11348 unop(Iop_64to32, 11349 mkexpr(t9)), 11350 unop(Iop_64to32, 11351 getAcc(ac))), 11352 getDSPControl(), 11353 binop(Iop_Or32, 11354 getDSPControl(), 11355 binop(Iop_Shl32, 11356 mkU32(0x1), 11357 mkU8(ac+16))))); 11358 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 11359 unop(Iop_64HIto32, 11360 mkexpr(t9)), 11361 unop(Iop_64HIto32, 11362 getAcc(ac))), 11363 mkexpr(t10), 11364 binop(Iop_Or32, 11365 getDSPControl(), 11366 binop(Iop_Shl32, 11367 mkU32(0x1), 11368 mkU8(ac+16))))); 11369 break; 11370 } 11371 case 0x1B: { /* DPSQX_SA.W.PH */ 11372 DIP("dpsqx_sa.w.ph ac%d, r%d, r%d", ac, rs, rt); 11373 vassert(!mode64); 11374 t0 = newTemp(Ity_I64); 11375 t1 = newTemp(Ity_I64); 11376 t2 = newTemp(Ity_I1); 11377 t3 = newTemp(Ity_I1); 11378 t4 = newTemp(Ity_I64); 11379 t5 = newTemp(Ity_I64); 11380 t6 = newTemp(Ity_I1); 11381 t7 = newTemp(Ity_I1); 11382 t8 = newTemp(Ity_I64); 11383 t9 = newTemp(Ity_I64); 11384 t10 = newTemp(Ity_I32); 11385 11386 assign(t0, getAcc(ac)); 11387 /* Calculate the first cross dot product and saturate if 11388 needed. */ 11389 assign(t1, unop(Iop_32Sto64, 11390 binop(Iop_Shl32, 11391 binop(Iop_Mul32, 11392 unop(Iop_16Sto32, 11393 unop(Iop_32HIto16, 11394 getIReg(rs))), 11395 unop(Iop_16Sto32, 11396 unop(Iop_32to16, 11397 getIReg(rt)))), 11398 mkU8(0x1)))); 11399 11400 /* If both input arguments are equal 0x8000, saturate 11401 intermediate product and write to DSPControl 11402 register. */ 11403 assign(t2, binop(Iop_CmpEQ32, 11404 unop(Iop_16Uto32, 11405 unop(Iop_32HIto16, getIReg(rs))), 11406 mkU32(0x00008000))); 11407 assign(t3, binop(Iop_CmpEQ32, 11408 unop(Iop_16Uto32, 11409 unop(Iop_32to16, getIReg(rt))), 11410 mkU32(0x00008000))); 11411 11412 assign(t4, IRExpr_ITE(binop(Iop_CmpNE32, 11413 binop(Iop_And32, 11414 unop(Iop_1Sto32, 11415 mkexpr(t2)), 11416 unop(Iop_1Sto32, 11417 mkexpr(t3))), 11418 mkU32(0)), 11419 mkU64(0x000000007fffffffULL), 11420 mkexpr(t1))); 11421 11422 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 11423 binop(Iop_And32, 11424 unop(Iop_1Sto32, 11425 mkexpr(t2)), 11426 unop(Iop_1Sto32, 11427 mkexpr(t3))), 11428 mkU32(0)), 11429 binop(Iop_Or32, 11430 getDSPControl(), 11431 binop(Iop_Shl32, 11432 mkU32(0x1), 11433 mkU8(ac+16))), 11434 getDSPControl())); 11435 /* Calculate second cross dot product and saturate if 11436 needed. */ 11437 assign(t5, unop(Iop_32Sto64, 11438 binop(Iop_Shl32, 11439 binop(Iop_Mul32, 11440 unop(Iop_16Sto32, 11441 unop(Iop_32to16, 11442 getIReg(rs))), 11443 unop(Iop_16Sto32, 11444 unop(Iop_32HIto16, 11445 getIReg(rt)))), 11446 mkU8(0x1)))); 11447 11448 /* If both input arguments are equal 0x8000, saturate 11449 intermediate product and write to DSPControl 11450 register. */ 11451 assign(t6, binop(Iop_CmpEQ32, 11452 unop(Iop_16Uto32, 11453 unop(Iop_32to16, getIReg(rs))), 11454 mkU32(0x00008000))); 11455 assign(t7, binop(Iop_CmpEQ32, 11456 unop(Iop_16Uto32, 11457 unop(Iop_32HIto16, getIReg(rt))), 11458 mkU32(0x00008000))); 11459 11460 assign(t8, IRExpr_ITE(binop(Iop_CmpNE32, 11461 binop(Iop_And32, 11462 unop(Iop_1Sto32, 11463 mkexpr(t6)), 11464 unop(Iop_1Sto32, 11465 mkexpr(t7))), 11466 mkU32(0)), 11467 mkU64(0x000000007fffffffULL), 11468 mkexpr(t5))); 11469 11470 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 11471 binop(Iop_And32, 11472 unop(Iop_1Sto32, 11473 mkexpr(t6)), 11474 unop(Iop_1Sto32, 11475 mkexpr(t7))), 11476 mkU32(0)), 11477 binop(Iop_Or32, 11478 getDSPControl(), 11479 binop(Iop_Shl32, 11480 mkU32(0x1), 11481 mkU8(ac+16))), 11482 getDSPControl())); 11483 /* Subtract intermediate products from value in the 11484 accumulator. */ 11485 assign(t9, 11486 binop(Iop_Sub64, 11487 mkexpr(t0), 11488 binop(Iop_Add64, mkexpr(t8), mkexpr(t4)))); 11489 11490 putAcc(ac, 11491 IRExpr_ITE(binop(Iop_CmpEQ32, 11492 binop(Iop_And32, 11493 unop(Iop_64HIto32, 11494 mkexpr(t9)), 11495 mkU32(0x80000000)), 11496 mkU32(0x0)), 11497 IRExpr_ITE(binop(Iop_CmpNE32, 11498 unop(Iop_64HIto32, 11499 binop(Iop_Shl64, 11500 mkexpr(t9), 11501 mkU8(1))), 11502 mkU32(0x0)), 11503 mkU64(0x000000007fffffffULL), 11504 mkexpr(t9)), 11505 IRExpr_ITE(binop(Iop_CmpNE32, 11506 unop(Iop_64HIto32, 11507 binop(Iop_Shl64, 11508 mkexpr(t9), 11509 mkU8(1))), 11510 mkU32(0xffffffff)), 11511 mkU64(0xffffffff80000000ULL), 11512 mkexpr(t9)))); 11513 assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32, 11514 unop(Iop_64to32, 11515 mkexpr(t9)), 11516 unop(Iop_64to32, 11517 getAcc(ac))), 11518 getDSPControl(), 11519 binop(Iop_Or32, 11520 getDSPControl(), 11521 binop(Iop_Shl32, 11522 mkU32(0x1), 11523 mkU8(ac+16))))); 11524 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 11525 unop(Iop_64HIto32, 11526 mkexpr(t9)), 11527 unop(Iop_64HIto32, 11528 getAcc(ac))), 11529 mkexpr(t10), 11530 binop(Iop_Or32, 11531 getDSPControl(), 11532 binop(Iop_Shl32, 11533 mkU32(0x1), 11534 mkU8(ac+16))))); 11535 break; 11536 } 11537 default: 11538 return -1; 11539 } 11540 break; /* end of DPAQ.W.PH */ 11541 } 11542 case 0x31: { /* APPEND */ 11543 switch(sa) { 11544 case 0x0: { /* APPEND */ 11545 DIP("append r%d, r%d, %d", rt, rs, rd); 11546 vassert(!mode64); 11547 t1 = newTemp(Ity_I32); 11548 t2 = newTemp(Ity_I32); 11549 t3 = newTemp(Ity_I32); 11550 11551 assign(t1, binop(Iop_Shl32, getIReg(rt), mkU8(rd))); 11552 11553 if (31 == rd) { 11554 putIReg(rt, binop(Iop_Or32, 11555 mkexpr(t1), 11556 binop(Iop_And32, 11557 getIReg(rs), 11558 mkU32(0x7fffffff)))); 11559 } else if (1 == rd) { 11560 putIReg(rt, 11561 binop(Iop_Or32, 11562 mkexpr(t1), 11563 binop(Iop_And32, 11564 getIReg(rs), mkU32(0x1)))); 11565 } else { 11566 assign(t2, 11567 unop(Iop_Not32, 11568 binop(Iop_Shl32, 11569 mkU32(0xffffffff), mkU8(rd)))); 11570 11571 putIReg(rt, binop(Iop_Or32, 11572 mkexpr(t1), 11573 binop(Iop_And32, 11574 getIReg(rs), mkexpr(t2)))); 11575 } 11576 break; 11577 } 11578 case 0x1: { /* PREPEND */ 11579 DIP("prepend r%d, r%d, %d", rt, rs, rd); 11580 vassert(!mode64); 11581 t1 = newTemp(Ity_I32); 11582 t2 = newTemp(Ity_I32); 11583 t3 = newTemp(Ity_I32); 11584 11585 if (0 != rd) { 11586 assign(t1, binop(Iop_Shr32, getIReg(rt), mkU8(rd))); 11587 11588 if (31 == rd) { 11589 putIReg(rt, binop(Iop_Or32, 11590 mkexpr(t1), 11591 binop(Iop_Shl32, 11592 binop(Iop_And32, 11593 getIReg(rs), 11594 mkU32(0x7fffffff)), 11595 mkU8(1)))); 11596 } else if (1 == rd) { 11597 putIReg(rt, binop(Iop_Or32, 11598 mkexpr(t1), 11599 binop(Iop_Shl32, 11600 binop(Iop_And32, 11601 getIReg(rs), 11602 mkU32(0x1)), 11603 mkU8(31)))); 11604 } else { 11605 assign(t2, binop(Iop_Add32, mkU32(rd), mkU32(0x1))); 11606 11607 assign(t3, unop(Iop_Not32, 11608 binop(Iop_Shl32, 11609 mkU32(0xffffffff), 11610 unop(Iop_32to8, mkexpr(t2))))); 11611 11612 putIReg(rt, binop(Iop_Or32, 11613 mkexpr(t1), 11614 binop(Iop_Shl32, 11615 binop(Iop_And32, 11616 getIReg(rs), 11617 mkexpr(t3)), 11618 mkU8(32-rd)))); 11619 } 11620 } 11621 break; 11622 } 11623 case 0x10: { /* BALIGN */ 11624 DIP("balign r%d, r%d, %d", rt, rs, rd); 11625 vassert(!mode64); 11626 t1 = newTemp(Ity_I32); 11627 t2 = newTemp(Ity_I32); 11628 t3 = newTemp(Ity_I32); 11629 11630 if ((2 != rd) && (0 != rd)) { 11631 assign(t1, binop(Iop_Shl32, 11632 binop(Iop_And32, 11633 mkU32(rd), mkU32(0x3)), 11634 mkU8(0x3))); 11635 assign(t2, binop(Iop_Shl32, 11636 getIReg(rt), 11637 unop(Iop_32to8, mkexpr(t1)))); 11638 assign(t3, binop(Iop_Shr32, 11639 getIReg(rs), 11640 unop(Iop_32to8, 11641 binop(Iop_Shl32, 11642 binop(Iop_Sub32, 11643 mkU32(0x4), 11644 binop(Iop_And32, 11645 mkU32(rd), 11646 mkU32(0x3))), 11647 mkU8(0x3))))); 11648 putIReg(rt, binop(Iop_Or32, mkexpr(t2), mkexpr(t3))); 11649 } 11650 break; 11651 } 11652 default: 11653 return -1; 11654 } 11655 break; /* end of APPEND */ 11656 } 11657 default: 11658 return -1; 11659 } 11660 break; 11661 } 11662 default: 11663 return -1; 11664 } 11665 return 0; 11666 } 11667 11668 /*------------------------------------------------------------*/ 11669 /*--- Disassemble a single instruction ---*/ 11670 /*------------------------------------------------------------*/ 11671 11672 /* Disassemble a single instruction into IR. The instruction is 11673 located in host memory at guest_instr, and has guest IP of 11674 guest_PC_curr_instr, which will have been set before the call 11675 here. */ 11676 11677 static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, 11678 Addr64), 11679 Bool resteerCisOk, 11680 void* callback_opaque, 11681 Long delta64, 11682 VexArchInfo* archinfo, 11683 VexAbiInfo* abiinfo, 11684 Bool sigill_diag ) 11685 { 11686 IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7; 11687 11688 UInt opcode, cins, rs, rt, rd, sa, ft, fs, fd, fmt, tf, nd, function, 11689 trap_code, imm, instr_index, p, msb, lsb, size, rot, sel; 11690 /* Additional variables for instruction fields in DSP ASE insructions */ 11691 UInt ac; 11692 11693 DisResult dres; 11694 11695 static IRExpr *lastn = NULL; /* last jump addr */ 11696 static IRStmt *bstmt = NULL; /* branch (Exit) stmt */ 11697 11698 /* The running delta */ 11699 Int delta = (Int) delta64; 11700 11701 /* Holds eip at the start of the insn, so that we can print 11702 consistent error messages for unimplemented insns. */ 11703 Int delta_start = delta; 11704 11705 /* Are we in a delay slot ? */ 11706 Bool delay_slot_branch, likely_delay_slot, delay_slot_jump; 11707 11708 /* Set result defaults. */ 11709 dres.whatNext = Dis_Continue; 11710 dres.len = 0; 11711 dres.continueAt = 0; 11712 dres.jk_StopHere = Ijk_INVALID; 11713 11714 delay_slot_branch = likely_delay_slot = delay_slot_jump = False; 11715 11716 UChar *code = (UChar *) (guest_code + delta); 11717 cins = getUInt(code); 11718 DIP("\t0x%lx:\t0x%08x\t", (long)guest_PC_curr_instr, cins); 11719 11720 if (delta != 0) { 11721 if (branch_or_jump(guest_code + delta - 4)) { 11722 if (lastn == NULL && bstmt == NULL) { 11723 vassert(0); 11724 } else { 11725 dres.whatNext = Dis_StopHere; 11726 if (lastn != NULL) { 11727 delay_slot_jump = True; 11728 } else if (bstmt != NULL) { 11729 delay_slot_branch = True; 11730 } 11731 } 11732 } 11733 11734 if (branch_or_link_likely(guest_code + delta - 4)) { 11735 likely_delay_slot = True; 11736 } 11737 } 11738 11739 /* Spot "Special" instructions (see comment at top of file). */ 11740 { 11741 /* Spot the 16-byte preamble: 11742 ****mips32**** 11743 "srl $0, $0, 13 11744 "srl $0, $0, 29 11745 "srl $0, $0, 3 11746 "srl $0, $0, 19 11747 11748 ****mips64**** 11749 dsll $0, $0, 3 11750 dsll $0, $0, 13 11751 dsll $0, $0, 29 11752 dsll $0, $0, 19 */ 11753 11754 UInt word1 = mode64 ? 0xF8 : 0x342; 11755 UInt word2 = mode64 ? 0x378 : 0x742; 11756 UInt word3 = mode64 ? 0x778 : 0xC2; 11757 UInt word4 = mode64 ? 0x4F8 : 0x4C2; 11758 if (getUInt(code + 0) == word1 && getUInt(code + 4) == word2 && 11759 getUInt(code + 8) == word3 && getUInt(code + 12) == word4) { 11760 /* Got a "Special" instruction preamble. Which one is it? */ 11761 if (getUInt(code + 16) == 0x01ad6825 /* or $13, $13, $13 */ ) { 11762 /* $11 = client_request ( $12 ) */ 11763 DIP("$11 = client_request ( $12 )"); 11764 if (mode64) 11765 putPC(mkU64(guest_PC_curr_instr + 20)); 11766 else 11767 putPC(mkU32(guest_PC_curr_instr + 20)); 11768 dres.jk_StopHere = Ijk_ClientReq; 11769 dres.whatNext = Dis_StopHere; 11770 11771 goto decode_success; 11772 } else if (getUInt(code + 16) == 0x01ce7025 /* or $14, $14, $14 */ ) { 11773 /* $11 = guest_NRADDR */ 11774 DIP("$11 = guest_NRADDR"); 11775 dres.len = 20; 11776 delta += 20; 11777 if (mode64) 11778 putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS64State, 11779 guest_NRADDR), Ity_I64)); 11780 else 11781 putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS32State, 11782 guest_NRADDR), Ity_I32)); 11783 goto decode_success; 11784 } else if (getUInt(code + 16) == 0x01ef7825 /* or $15, $15, $15 */ ) { 11785 /* branch-and-link-to-noredir $25 */ 11786 DIP("branch-and-link-to-noredir $25"); 11787 if (mode64) 11788 putIReg(31, mkU64(guest_PC_curr_instr + 20)); 11789 else 11790 putIReg(31, mkU32(guest_PC_curr_instr + 20)); 11791 putPC(getIReg(25)); 11792 dres.jk_StopHere = Ijk_NoRedir; 11793 dres.whatNext = Dis_StopHere; 11794 goto decode_success; 11795 } else if (getUInt(code + 16) == 0x016b5825 /* or $11,$11,$11 */ ) { 11796 /* IR injection */ 11797 DIP("IR injection"); 11798 #if defined (_MIPSEL) 11799 vex_inject_ir(irsb, Iend_LE); 11800 #elif defined (_MIPSEB) 11801 vex_inject_ir(irsb, Iend_BE); 11802 #endif 11803 if (mode64) { 11804 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMSTART), 11805 mkU64(guest_PC_curr_instr))); 11806 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMLEN), 11807 mkU64(20))); 11808 11809 putPC(mkU64(guest_PC_curr_instr + 20)); 11810 } else { 11811 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMSTART), 11812 mkU32(guest_PC_curr_instr))); 11813 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMLEN), 11814 mkU32(20))); 11815 11816 putPC(mkU32(guest_PC_curr_instr + 20)); 11817 } 11818 dres.whatNext = Dis_StopHere; 11819 dres.jk_StopHere = Ijk_InvalICache; 11820 dres.len = 20; 11821 delta += 20; 11822 goto decode_success; 11823 } 11824 11825 /* We don't know what it is. Set opc1/opc2 so decode_failure 11826 can print the insn following the Special-insn preamble. */ 11827 delta += 16; 11828 goto decode_failure; 11829 /*NOTREACHED*/} 11830 } 11831 11832 opcode = get_opcode(cins); 11833 imm = get_imm(cins); 11834 rs = get_rs(cins); 11835 rt = get_rt(cins); 11836 rd = get_rd(cins); 11837 sa = get_sa(cins); 11838 fs = get_fs(cins); 11839 fd = get_fd(cins); 11840 ft = get_ft(cins); 11841 tf = get_tf(cins); 11842 nd = get_nd(cins); 11843 sel = get_sel(cins); 11844 fmt = get_fmt(cins); 11845 instr_index = get_instr_index(cins); 11846 trap_code = get_code(cins); 11847 function = get_function(cins); 11848 IRType ty = mode64 ? Ity_I64 : Ity_I32; 11849 IRType tyF = fp_mode64 ? Ity_F64 : Ity_F32; 11850 11851 ac = get_acNo(cins); 11852 11853 switch (opcode) { 11854 11855 case 0x03: /* JAL */ 11856 DIP("jal 0x%x", instr_index); 11857 if (mode64) { 11858 putIReg(31, mkU64(guest_PC_curr_instr + 8)); 11859 t0 = newTemp(ty); 11860 assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) | 11861 (instr_index << 2))); 11862 } else { 11863 putIReg(31, mkU32(guest_PC_curr_instr + 8)); 11864 t0 = newTemp(ty); 11865 assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) | 11866 (instr_index << 2))); 11867 } 11868 lastn = mkexpr(t0); 11869 break; 11870 case 0x02: /* J */ 11871 DIP("j 0x%x", instr_index); 11872 t0 = newTemp(ty); 11873 if (mode64) 11874 assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) | 11875 (instr_index << 2))); 11876 else 11877 assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) | 11878 (instr_index << 2))); 11879 lastn = mkexpr(t0); 11880 break; 11881 11882 case 0x11: { /* COP1 */ 11883 if (fmt == 0x3 && fd == 0 && function == 0) { /* MFHC1 */ 11884 DIP("mfhc1 r%d, f%d", rt, fs); 11885 if (fp_mode64) { 11886 t0 = newTemp(Ity_I64); 11887 t1 = newTemp(Ity_I32); 11888 assign(t0, unop(Iop_ReinterpF64asI64, getDReg(fs))); 11889 assign(t1, unop(Iop_64HIto32, mkexpr(t0))); 11890 putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True)); 11891 } else { 11892 ILLEGAL_INSTRUCTON; 11893 } 11894 break; 11895 } else if (fmt == 0x7 && fd == 0 && function == 0) { /* MTHC1 */ 11896 DIP("mthc1 r%d, f%d", rt, fs); 11897 if (fp_mode64) { 11898 t0 = newTemp(Ity_I64); 11899 assign(t0, binop(Iop_32HLto64, getIReg(rt), 11900 unop(Iop_ReinterpF32asI32, 11901 getLoFromF64(Ity_F64 /* 32FPR mode. */, 11902 getDReg(fs))))); 11903 putDReg(fs, unop(Iop_ReinterpI64asF64, mkexpr(t0))); 11904 } else { 11905 ILLEGAL_INSTRUCTON; 11906 } 11907 break; 11908 } else if (fmt == 0x8) { /* BC */ 11909 /* FcConditionalCode(bc1_cc) */ 11910 UInt bc1_cc = get_bc1_cc(cins); 11911 t1 = newTemp(Ity_I1); 11912 t2 = newTemp(Ity_I32); 11913 t3 = newTemp(Ity_I1); 11914 11915 assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(bc1_cc))); 11916 assign(t2, IRExpr_ITE(mkexpr(t1), 11917 binop(Iop_And32, 11918 binop(Iop_Shr32, getFCSR(), mkU8(23)), 11919 mkU32(0x1)), 11920 binop(Iop_And32, 11921 binop(Iop_Shr32, getFCSR(), 11922 mkU8(24 + bc1_cc)), 11923 mkU32(0x1)))); 11924 11925 if (tf == 1 && nd == 0) { 11926 /* branch on true */ 11927 DIP("bc1t %d, %d", bc1_cc, imm); 11928 assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2))); 11929 dis_branch(False, mkexpr(t3), imm, &bstmt); 11930 break; 11931 } else if (tf == 0 && nd == 0) { 11932 /* branch on false */ 11933 DIP("bc1f %d, %d", bc1_cc, imm); 11934 assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2))); 11935 dis_branch(False, mkexpr(t3), imm, &bstmt); 11936 break; 11937 } else if (nd == 1 && tf == 0) { 11938 DIP("bc1fl %d, %d", bc1_cc, imm); 11939 lastn = dis_branch_likely(binop(Iop_CmpNE32, mkexpr(t2), 11940 mkU32(0x0)), imm); 11941 break; 11942 } else if (nd == 1 && tf == 1) { 11943 DIP("bc1tl %d, %d", bc1_cc, imm); 11944 lastn = dis_branch_likely(binop(Iop_CmpEQ32, mkexpr(t2), 11945 mkU32(0x0)), imm); 11946 break; 11947 } else 11948 goto decode_failure; 11949 } else { 11950 switch (function) { 11951 case 0x4: { /* SQRT.fmt */ 11952 switch (fmt) { 11953 case 0x10: { /* S */ 11954 IRExpr *rm = get_IR_roundingmode(); 11955 putFReg(fd, mkWidenFromF32(tyF, binop(Iop_SqrtF32, rm, 11956 getLoFromF64(tyF, getFReg(fs))))); 11957 break; 11958 } 11959 case 0x11: { /* D */ 11960 IRExpr *rm = get_IR_roundingmode(); 11961 putDReg(fd, binop(Iop_SqrtF64, rm, getDReg(fs))); 11962 break; 11963 } 11964 default: 11965 goto decode_failure; 11966 } 11967 } 11968 break; 11969 case 0x5: /* abs.fmt */ 11970 switch (fmt) { 11971 case 0x10: /* S */ 11972 DIP("abs.s f%d, f%d", fd, fs); 11973 putFReg(fd, mkWidenFromF32(tyF, unop(Iop_AbsF32, 11974 getLoFromF64(tyF, getFReg(fs))))); 11975 break; 11976 case 0x11: /* D */ 11977 DIP("abs.d f%d, f%d", fd, fs); 11978 putDReg(fd, unop(Iop_AbsF64, getDReg(fs))); 11979 break; 11980 default: 11981 goto decode_failure; 11982 } 11983 break; /* case 0x5 */ 11984 11985 case 0x02: /* MUL.fmt */ 11986 switch (fmt) { 11987 case 0x11: { /* D */ 11988 DIP("mul.d f%d, f%d, f%d", fd, fs, ft); 11989 IRExpr *rm = get_IR_roundingmode(); 11990 putDReg(fd, triop(Iop_MulF64, rm, getDReg(fs), 11991 getDReg(ft))); 11992 break; 11993 } 11994 case 0x10: { /* S */ 11995 DIP("mul.s f%d, f%d, f%d", fd, fs, ft); 11996 IRExpr *rm = get_IR_roundingmode(); 11997 putFReg(fd, mkWidenFromF32(tyF, triop(Iop_MulF32, rm, 11998 getLoFromF64(tyF, getFReg(fs)), 11999 getLoFromF64(tyF, getFReg(ft))))); 12000 break; 12001 } 12002 default: 12003 goto decode_failure; 12004 } 12005 break; /* MUL.fmt */ 12006 12007 case 0x03: /* DIV.fmt */ 12008 switch (fmt) { 12009 case 0x11: { /* D */ 12010 DIP("div.d f%d, f%d, f%d", fd, fs, ft); 12011 IRExpr *rm = get_IR_roundingmode(); 12012 putDReg(fd, triop(Iop_DivF64, rm, getDReg(fs), 12013 getDReg(ft))); 12014 break; 12015 } 12016 case 0x10: { /* S */ 12017 DIP("div.s f%d, f%d, f%d", fd, fs, ft); 12018 calculateFCSR(fs, ft, DIVS, False, 2); 12019 IRExpr *rm = get_IR_roundingmode(); 12020 putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm, 12021 getLoFromF64(tyF, getFReg(fs)), 12022 getLoFromF64(tyF, getFReg(ft))))); 12023 break; 12024 } 12025 default: 12026 goto decode_failure; 12027 } 12028 break; /* DIV.fmt */ 12029 12030 case 0x01: /* SUB.fmt */ 12031 switch (fmt) { 12032 case 0x11: { /* D */ 12033 DIP("sub.d f%d, f%d, f%d", fd, fs, ft); 12034 calculateFCSR(fs, ft, SUBD, False, 2); 12035 IRExpr *rm = get_IR_roundingmode(); 12036 putDReg(fd, triop(Iop_SubF64, rm, getDReg(fs), 12037 getDReg(ft))); 12038 break; 12039 } 12040 case 0x10: { /* S */ 12041 DIP("sub.s f%d, f%d, f%d", fd, fs, ft); 12042 calculateFCSR(fs, ft, SUBS, True, 2); 12043 IRExpr *rm = get_IR_roundingmode(); 12044 putFReg(fd, mkWidenFromF32(tyF, triop(Iop_SubF32, rm, 12045 getLoFromF64(tyF, getFReg(fs)), 12046 getLoFromF64(tyF, getFReg(ft))))); 12047 break; 12048 } 12049 default: 12050 goto decode_failure; 12051 } 12052 break; /* SUB.fmt */ 12053 12054 case 0x06: /* MOV.fmt */ 12055 switch (fmt) { 12056 case 0x11: /* D */ 12057 DIP("mov.d f%d, f%d", fd, fs); 12058 if (fp_mode64) { 12059 putDReg(fd, getDReg(fs)); 12060 } else { 12061 putFReg(fd, getFReg(fs)); 12062 putFReg(fd + 1, getFReg(fs + 1)); 12063 } 12064 break; 12065 case 0x10: /* S */ 12066 DIP("mov.s f%d, f%d", fd, fs); 12067 putFReg(fd, getFReg(fs)); 12068 break; 12069 default: 12070 goto decode_failure; 12071 } 12072 break; /* MOV.fmt */ 12073 12074 case 0x7: /* neg.fmt */ 12075 switch (fmt) { 12076 case 0x10: /* S */ 12077 DIP("neg.s f%d, f%d", fd, fs); 12078 putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, 12079 getLoFromF64(tyF, getFReg(fs))))); 12080 break; 12081 case 0x11: /* D */ 12082 DIP("neg.d f%d, f%d", fd, fs); 12083 putDReg(fd, unop(Iop_NegF64, getDReg(fs))); 12084 break; 12085 default: 12086 goto decode_failure; 12087 } 12088 break; /* case 0x7 */ 12089 12090 case 0x08: /* ROUND.L.fmt */ 12091 switch (fmt) { 12092 case 0x10: /* S */ 12093 DIP("round.l.s f%d, f%d", fd, fs); 12094 if (fp_mode64) { 12095 calculateFCSR(fs, 0, ROUNDLS, True, 1); 12096 t0 = newTemp(Ity_I64); 12097 12098 assign(t0, binop(Iop_F32toI64S, mkU32(0x0), 12099 getLoFromF64(Ity_F64, getFReg(fs)))); 12100 12101 putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); 12102 } else { 12103 ILLEGAL_INSTRUCTON; 12104 } 12105 break; 12106 case 0x11: /* D */ 12107 DIP("round.l.d f%d, f%d", fd, fs); 12108 if (fp_mode64) { 12109 calculateFCSR(fs, 0, ROUNDLD, False, 1); 12110 putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x0), 12111 getDReg(fs))); 12112 } else { 12113 ILLEGAL_INSTRUCTON; 12114 } 12115 break; 12116 default: 12117 goto decode_failure; 12118 12119 } 12120 break; /* ROUND.L.fmt */ 12121 12122 case 0x09: /* TRUNC.L.fmt */ 12123 switch (fmt) { 12124 case 0x10: /* S */ 12125 DIP("trunc.l.s f%d, f%d", fd, fs); 12126 if (fp_mode64) { 12127 calculateFCSR(fs, 0, TRUNCLS, True, 1); 12128 t0 = newTemp(Ity_I64); 12129 assign(t0, binop(Iop_F32toI64S, mkU32(0x3), 12130 getLoFromF64(Ity_F64, getFReg(fs)))); 12131 12132 putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); 12133 } else { 12134 ILLEGAL_INSTRUCTON; 12135 } 12136 break; 12137 case 0x11: /* D */ 12138 DIP("trunc.l.d f%d, f%d", fd, fs); 12139 if (fp_mode64) { 12140 calculateFCSR(fs, 0, TRUNCLD, False, 1); 12141 putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x3), 12142 getDReg(fs))); 12143 } else { 12144 ILLEGAL_INSTRUCTON; 12145 } 12146 break; 12147 default: 12148 goto decode_failure; 12149 } 12150 break; /* TRUNC.L.fmt */ 12151 12152 case 0x15: /* RECIP.fmt */ 12153 switch (fmt) { 12154 case 0x10: { /* S */ 12155 DIP("recip.s f%d, f%d", fd, fs); 12156 IRExpr *rm = get_IR_roundingmode(); 12157 putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, 12158 rm, unop(Iop_ReinterpI32asF32, 12159 mkU32(ONE_SINGLE)), getLoFromF64(tyF, 12160 getFReg(fs))))); 12161 break; 12162 } 12163 case 0x11: { /* D */ 12164 DIP("recip.d f%d, f%d", fd, fs); 12165 IRExpr *rm = get_IR_roundingmode(); 12166 /* putDReg(fd, 1.0/getDreg(fs)); */ 12167 putDReg(fd, triop(Iop_DivF64, rm, 12168 unop(Iop_ReinterpI64asF64, 12169 mkU64(ONE_DOUBLE)), getDReg(fs))); 12170 break; 12171 } 12172 default: 12173 goto decode_failure; 12174 12175 } 12176 break; /* case 0x15 */ 12177 12178 case 0x13: /* MOVN.fmt */ 12179 switch (fmt) { 12180 case 0x10: /* S */ 12181 DIP("movn.s f%d, f%d, r%d", fd, fs, rt); 12182 t1 = newTemp(Ity_F64); 12183 t2 = newTemp(Ity_F64); 12184 t3 = newTemp(Ity_I1); 12185 t4 = newTemp(Ity_F64); 12186 if (mode64) { 12187 assign(t1, getFReg(fs)); 12188 assign(t2, getFReg(fd)); 12189 assign(t3, binop(Iop_CmpNE64, mkU64(0), getIReg(rt))); 12190 } else { 12191 if (fp_mode64) { 12192 assign(t1, getFReg(fs)); 12193 assign(t2, getFReg(fd)); 12194 assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt))); 12195 } else { 12196 assign(t1, unop(Iop_F32toF64, getFReg(fs))); 12197 assign(t2, unop(Iop_F32toF64, getFReg(fd))); 12198 assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt))); 12199 } 12200 } 12201 12202 assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t1), mkexpr(t2))); 12203 if (fp_mode64) { 12204 IRTemp f = newTemp(Ity_F64); 12205 IRTemp fd_hi = newTemp(Ity_I32); 12206 t5 = newTemp(Ity_I64); 12207 assign(f, getFReg(fd)); 12208 assign(fd_hi, unop(Iop_64HIto32, unop(Iop_ReinterpF64asI64, 12209 mkexpr(f)))); 12210 12211 assign(t5, mkWidenFrom32(Ity_I64, unop(Iop_64to32, 12212 unop(Iop_ReinterpF64asI64, mkexpr(t4))), True)); 12213 12214 putFReg(fd, unop (Iop_ReinterpI64asF64, mkexpr(t5))); 12215 } else 12216 putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(), 12217 mkexpr(t4))); 12218 break; 12219 case 0x11: /* D */ 12220 DIP("movn.d f%d, f%d, r%d", fd, fs, rt); 12221 12222 t3 = newTemp(Ity_I1); 12223 t4 = newTemp(Ity_F64); 12224 12225 if (mode64) 12226 assign(t3, binop(Iop_CmpNE64, mkU64(0), getIReg(rt))); 12227 else 12228 assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt))); 12229 12230 putDReg(fd, IRExpr_ITE(mkexpr(t3), getDReg(fs), getDReg(fd))); 12231 break; 12232 default: 12233 goto decode_failure; 12234 } 12235 break; /* MOVN.fmt */ 12236 12237 case 0x12: /* MOVZ.fmt */ 12238 switch (fmt) { 12239 case 0x10: /* S */ 12240 DIP("movz.s f%d, f%d, r%d", fd, fs, rt); 12241 12242 t1 = newTemp(Ity_F64); 12243 t2 = newTemp(Ity_F64); 12244 t3 = newTemp(Ity_I1); 12245 t4 = newTemp(Ity_F64); 12246 if (fp_mode64) { 12247 assign(t1, getFReg(fs)); 12248 assign(t2, getFReg(fd)); 12249 if (mode64) 12250 assign(t3, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt))); 12251 else 12252 assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt))); 12253 } else { 12254 assign(t1, unop(Iop_F32toF64, getFReg(fs))); 12255 assign(t2, unop(Iop_F32toF64, getFReg(fd))); 12256 assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt))); 12257 } 12258 assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t1), mkexpr(t2))); 12259 12260 if (fp_mode64) { 12261 IRTemp f = newTemp(Ity_F64); 12262 IRTemp fd_hi = newTemp(Ity_I32); 12263 t7 = newTemp(Ity_I64); 12264 assign(f, getFReg(fd)); 12265 assign(fd_hi, unop(Iop_64HIto32, 12266 unop(Iop_ReinterpF64asI64, mkexpr(f)))); 12267 assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32, 12268 unop(Iop_ReinterpF64asI64, mkexpr(t4))), True)); 12269 12270 putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7))); 12271 } else 12272 putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(), 12273 mkexpr(t4))); 12274 12275 break; 12276 case 0x11: /* D */ 12277 DIP("movz.d f%d, f%d, r%d", fd, fs, rt); 12278 t3 = newTemp(Ity_I1); 12279 t4 = newTemp(Ity_F64); 12280 if (mode64) 12281 assign(t3, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt))); 12282 else 12283 assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt))); 12284 12285 putDReg(fd, IRExpr_ITE(mkexpr(t3), getDReg(fs), getDReg(fd))); 12286 break; 12287 default: 12288 goto decode_failure; 12289 } 12290 break; /* MOVZ.fmt */ 12291 12292 case 0x11: /* MOVT.fmt */ 12293 if (tf == 1) { 12294 UInt mov_cc = get_mov_cc(cins); 12295 switch (fmt) { /* MOVCF = 010001 */ 12296 case 0x11: /* D */ 12297 DIP("movt.d f%d, f%d, %d", fd, fs, mov_cc); 12298 t1 = newTemp(Ity_I1); 12299 t2 = newTemp(Ity_I32); 12300 t3 = newTemp(Ity_I1); 12301 t4 = newTemp(Ity_F64); 12302 12303 assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc))); 12304 assign(t2, IRExpr_ITE(mkexpr(t1), 12305 binop(Iop_And32, 12306 binop(Iop_Shr32, getFCSR(), 12307 mkU8(23)), 12308 mkU32(0x1)), 12309 binop(Iop_And32, 12310 binop(Iop_Shr32, getFCSR(), 12311 mkU8(24 + mov_cc)), 12312 mkU32(0x1)) 12313 )); 12314 12315 assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2))); 12316 assign(t4, IRExpr_ITE(mkexpr(t3), 12317 getDReg(fs), getDReg(fd))); 12318 putDReg(fd, mkexpr(t4)); 12319 break; 12320 case 0x10: /* S */ 12321 DIP("movt.s f%d, f%d, %d", fd, fs, mov_cc); 12322 t1 = newTemp(Ity_I1); 12323 t2 = newTemp(Ity_I32); 12324 t3 = newTemp(Ity_I1); 12325 t4 = newTemp(Ity_F64); 12326 t5 = newTemp(Ity_F64); 12327 t6 = newTemp(Ity_F64); 12328 t7 = newTemp(Ity_I64); 12329 12330 if (fp_mode64) { 12331 assign(t5, getFReg(fs)); 12332 assign(t6, getFReg(fd)); 12333 } else { 12334 assign(t5, unop(Iop_F32toF64, getFReg(fs))); 12335 assign(t6, unop(Iop_F32toF64, getFReg(fd))); 12336 } 12337 12338 assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc))); 12339 assign(t2, IRExpr_ITE(mkexpr(t1), 12340 binop(Iop_And32, 12341 binop(Iop_Shr32, getFCSR(), 12342 mkU8(23)), 12343 mkU32(0x1)), 12344 binop(Iop_And32, 12345 binop(Iop_Shr32, getFCSR(), 12346 mkU8(24 + mov_cc)), 12347 mkU32(0x1)) 12348 )); 12349 12350 assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2))); 12351 assign(t4, IRExpr_ITE(mkexpr(t3), 12352 mkexpr(t5), mkexpr(t6))); 12353 12354 if (fp_mode64) { 12355 IRTemp f = newTemp(Ity_F64); 12356 IRTemp fd_hi = newTemp(Ity_I32); 12357 assign(f, getFReg(fd)); 12358 assign(fd_hi, unop(Iop_64HIto32, 12359 unop(Iop_ReinterpF64asI64, mkexpr(f)))); 12360 assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32, 12361 unop(Iop_ReinterpF64asI64, mkexpr(t4))), 12362 True)); 12363 12364 putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7))); 12365 } else 12366 putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(), 12367 mkexpr(t4))); 12368 break; 12369 default: 12370 goto decode_failure; 12371 } 12372 } else if (tf == 0) /* movf.fmt */ 12373 { 12374 UInt mov_cc = get_mov_cc(cins); 12375 switch (fmt) /* MOVCF = 010001 */ 12376 { 12377 case 0x11: /* D */ 12378 DIP("movf.d f%d, f%d, %d", fd, fs, mov_cc); 12379 t1 = newTemp(Ity_I1); 12380 t2 = newTemp(Ity_I32); 12381 t3 = newTemp(Ity_I1); 12382 t4 = newTemp(Ity_F64); 12383 12384 assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc))); 12385 assign(t2, IRExpr_ITE(mkexpr(t1), 12386 binop(Iop_And32, 12387 binop(Iop_Shr32, getFCSR(), 12388 mkU8(23)), 12389 mkU32(0x1)), 12390 binop(Iop_And32, 12391 binop(Iop_Shr32, getFCSR(), 12392 mkU8(24 + mov_cc)), 12393 mkU32(0x1)) 12394 )); 12395 12396 assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2))); 12397 assign(t4, IRExpr_ITE(mkexpr(t3), 12398 getDReg(fs), getDReg(fd))); 12399 putDReg(fd, mkexpr(t4)); 12400 break; 12401 case 0x10: /* S */ 12402 DIP("movf.s f%d, f%d, %d", fd, fs, mov_cc); 12403 t1 = newTemp(Ity_I1); 12404 t2 = newTemp(Ity_I32); 12405 t3 = newTemp(Ity_I1); 12406 t4 = newTemp(Ity_F64); 12407 t5 = newTemp(Ity_F64); 12408 t6 = newTemp(Ity_F64); 12409 12410 if (fp_mode64) { 12411 assign(t5, getFReg(fs)); 12412 assign(t6, getFReg(fd)); 12413 } else { 12414 assign(t5, unop(Iop_F32toF64, getFReg(fs))); 12415 assign(t6, unop(Iop_F32toF64, getFReg(fd))); 12416 } 12417 12418 assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc))); 12419 assign(t2, IRExpr_ITE(mkexpr(t1), 12420 binop(Iop_And32, 12421 binop(Iop_Shr32, getFCSR(), 12422 mkU8(23)), 12423 mkU32(0x1)), 12424 binop(Iop_And32, 12425 binop(Iop_Shr32, getFCSR(), 12426 mkU8(24 + mov_cc)), 12427 mkU32(0x1)) 12428 )); 12429 12430 assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2))); 12431 assign(t4, IRExpr_ITE(mkexpr(t3), 12432 mkexpr(t5), mkexpr(t6))); 12433 12434 if (fp_mode64) { 12435 IRTemp f = newTemp(Ity_F64); 12436 IRTemp fd_hi = newTemp(Ity_I32); 12437 t7 = newTemp(Ity_I64); 12438 assign(f, getFReg(fd)); 12439 assign(fd_hi, unop(Iop_64HIto32, 12440 unop(Iop_ReinterpF64asI64, mkexpr(f)))); 12441 assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32, 12442 unop(Iop_ReinterpF64asI64, mkexpr(t4))), 12443 True)); 12444 12445 putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7))); 12446 } else 12447 putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(), 12448 mkexpr(t4))); 12449 break; 12450 default: 12451 goto decode_failure; 12452 } 12453 } 12454 12455 break; /* MOVT.fmt */ 12456 12457 case 0x0: /* add.fmt */ 12458 switch (fmt) { 12459 case 0x10: { /* S */ 12460 DIP("add.s f%d, f%d, f%d", fd, fs, ft); 12461 calculateFCSR(fs, ft, ADDS, True, 2); 12462 IRExpr *rm = get_IR_roundingmode(); 12463 putFReg(fd, mkWidenFromF32(tyF, triop(Iop_AddF32, rm, 12464 getLoFromF64(tyF, getFReg(fs)), 12465 getLoFromF64(tyF, getFReg(ft))))); 12466 break; 12467 } 12468 case 0x11: { /* D */ 12469 DIP("add.d f%d, f%d, f%d", fd, fs, ft); 12470 calculateFCSR(fs, ft, ADDD, False, 2); 12471 IRExpr *rm = get_IR_roundingmode(); 12472 putDReg(fd, triop(Iop_AddF64, rm, getDReg(fs), getDReg(ft))); 12473 break; 12474 } 12475 12476 case 0x4: /* MTC1 (Move Word to Floating Point) */ 12477 DIP("mtc1 r%d, f%d", rt, fs); 12478 if (fp_mode64) { 12479 t0 = newTemp(Ity_I32); 12480 t1 = newTemp(Ity_F32); 12481 assign(t0, mkNarrowTo32(ty, getIReg(rt))); 12482 assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0))); 12483 12484 putFReg(fs, mkWidenFromF32(tyF, mkexpr(t1))); 12485 } else 12486 putFReg(fs, unop(Iop_ReinterpI32asF32, getIReg(rt))); 12487 break; 12488 12489 case 0x5: /* Doubleword Move to Floating Point DMTC1; MIPS64 */ 12490 DIP("dmtc1 r%d, f%d", rt, fs); 12491 vassert(mode64); 12492 putFReg(fs, unop(Iop_ReinterpI64asF64, getIReg(rt))); 12493 break; 12494 12495 case 0x0: /* MFC1 */ 12496 DIP("mfc1 r%d, f%d", rt, fs); 12497 if (fp_mode64) { 12498 t0 = newTemp(Ity_I64); 12499 t1 = newTemp(Ity_I32); 12500 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12501 assign(t1, unop(Iop_64to32, mkexpr(t0))); 12502 putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True)); 12503 } else 12504 putIReg(rt, unop(Iop_ReinterpF32asI32, getFReg(fs))); 12505 break; 12506 12507 case 0x1: /* Doubleword Move from Floating Point DMFC1; 12508 MIPS64 */ 12509 DIP("dmfc1 r%d, f%d", rt, fs); 12510 putIReg(rt, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12511 break; 12512 12513 case 0x6: /* CTC1 */ 12514 DIP("ctc1 r%d, f%d", rt, fs); 12515 t0 = newTemp(Ity_I32); 12516 t1 = newTemp(Ity_I32); 12517 t2 = newTemp(Ity_I32); 12518 t3 = newTemp(Ity_I32); 12519 t4 = newTemp(Ity_I32); 12520 t5 = newTemp(Ity_I32); 12521 t6 = newTemp(Ity_I32); 12522 assign(t0, mkNarrowTo32(ty, getIReg(rt))); 12523 if (fs == 25) { /* FCCR */ 12524 assign(t1, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0), 12525 mkU32(0x000000FE)), mkU8(24))); 12526 assign(t2, binop(Iop_And32, mkexpr(t0), 12527 mkU32(0x01000000))); 12528 assign(t3, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0), 12529 mkU32(0x00000001)), mkU8(23))); 12530 assign(t4, binop(Iop_And32, mkexpr(t0), 12531 mkU32(0x007FFFFF))); 12532 putFCSR(binop(Iop_Or32, binop(Iop_Or32, mkexpr(t1), 12533 mkexpr(t2)), binop(Iop_Or32, mkexpr(t3), 12534 mkexpr(t4)))); 12535 } else if (fs == 26) { /* FEXR */ 12536 assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFFFC0000))); 12537 assign(t2, binop(Iop_And32, mkexpr(t0), 12538 mkU32(0x0003F000))); 12539 assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00000F80))); 12540 assign(t4, binop(Iop_And32, mkexpr(t0), 12541 mkU32(0x0000007C))); 12542 assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x00000003))); 12543 putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, 12544 mkexpr(t1), mkexpr(t2)), binop(Iop_Or32, 12545 mkexpr(t3), mkexpr(t4))), mkexpr(t5))); 12546 } else if (fs == 28) { 12547 assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFE000000))); 12548 assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0), 12549 mkU32(0x00000002)), mkU8(22))); 12550 assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00FFF000))); 12551 assign(t4, binop(Iop_And32, mkexpr(t0), 12552 mkU32(0x00000F80))); 12553 assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x0000007C))); 12554 assign(t6, binop(Iop_And32, mkexpr(t0), 12555 mkU32(0x00000003))); 12556 putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, 12557 mkexpr(t1), mkexpr(t2)), binop(Iop_Or32, 12558 mkexpr(t3), mkexpr(t4))), binop(Iop_Or32, 12559 mkexpr(t5), mkexpr(t6)))); 12560 } else if (fs == 31) { 12561 putFCSR(mkexpr(t0)); 12562 } 12563 break; 12564 case 0x2: /* CFC1 */ 12565 DIP("cfc1 r%d, f%d", rt, fs); 12566 t0 = newTemp(Ity_I32); 12567 t1 = newTemp(Ity_I32); 12568 t2 = newTemp(Ity_I32); 12569 t3 = newTemp(Ity_I32); 12570 t4 = newTemp(Ity_I32); 12571 t5 = newTemp(Ity_I32); 12572 t6 = newTemp(Ity_I32); 12573 assign(t0, getFCSR()); 12574 if (fs == 0) { 12575 putIReg(rt, mkWidenFrom32(ty, 12576 IRExpr_Get(offsetof(VexGuestMIPS32State, 12577 guest_FIR), 12578 Ity_I32), 12579 False)); 12580 } else if (fs == 25) { 12581 assign(t1, mkU32(0x000000FF)); 12582 assign(t2, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0), 12583 mkU32(0xFE000000)), mkU8(25))); 12584 assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0), 12585 mkU32(0x00800000)), mkU8(23))); 12586 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, 12587 binop(Iop_Or32, mkexpr(t1), mkexpr(t2)), 12588 mkexpr(t3)), False)); 12589 } else if (fs == 26) { 12590 assign(t1, mkU32(0xFFFFF07C)); 12591 assign(t2, binop(Iop_And32, mkexpr(t0), 12592 mkU32(0x0003F000))); 12593 assign(t3, binop(Iop_And32, mkexpr(t0), 12594 mkU32(0x0000007C))); 12595 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, 12596 binop(Iop_Or32, mkexpr(t1), mkexpr(t2)), 12597 mkexpr(t3)), False)); 12598 } else if (fs == 28) { 12599 assign(t1, mkU32(0x00000F87)); 12600 assign(t2, binop(Iop_And32, mkexpr(t0), 12601 mkU32(0x00000F83))); 12602 assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0), 12603 mkU32(0x01000000)), mkU8(22))); 12604 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, 12605 binop(Iop_Or32, mkexpr(t1), mkexpr(t2)), 12606 mkexpr(t3)), False)); 12607 } else if (fs == 31) { 12608 putIReg(rt, mkWidenFrom32(ty, getFCSR(), False)); 12609 } 12610 break; 12611 default: 12612 goto decode_failure; 12613 } 12614 break; 12615 12616 case 0x21: /* CVT.D */ 12617 switch (fmt) { 12618 case 0x10: /* S */ 12619 DIP("cvt.d.s f%d, f%d", fd, fs); 12620 calculateFCSR(fs, 0, CVTDS, True, 1); 12621 if (fp_mode64) { 12622 t0 = newTemp(Ity_I64); 12623 t1 = newTemp(Ity_I32); 12624 t3 = newTemp(Ity_F32); 12625 t4 = newTemp(Ity_F32); 12626 /* get lo half of FPR */ 12627 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12628 12629 assign(t1, unop(Iop_64to32, mkexpr(t0))); 12630 12631 assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1))); 12632 12633 putFReg(fd, unop(Iop_F32toF64, mkexpr(t3))); 12634 } else 12635 putDReg(fd, unop(Iop_F32toF64, getFReg(fs))); 12636 break; 12637 12638 case 0x14: 12639 DIP("cvt.d.w %d, %d", fd, fs); 12640 calculateFCSR(fs, 0, CVTDW, True, 1); 12641 if (fp_mode64) { 12642 t0 = newTemp(Ity_I64); 12643 t1 = newTemp(Ity_I32); 12644 t3 = newTemp(Ity_F32); 12645 t4 = newTemp(Ity_F32); 12646 /* get lo half of FPR */ 12647 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12648 12649 assign(t1, unop(Iop_64to32, mkexpr(t0))); 12650 putDReg(fd,unop(Iop_I32StoF64, mkexpr(t1))); 12651 break; 12652 } else { 12653 t0 = newTemp(Ity_I32); 12654 assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs))); 12655 putDReg(fd, unop(Iop_I32StoF64, mkexpr(t0))); 12656 break; 12657 } 12658 12659 case 0x15: { /* L */ 12660 if (fp_mode64) { 12661 DIP("cvt.d.l %d, %d", fd, fs); 12662 calculateFCSR(fs, 0, CVTDL, False, 1); 12663 t0 = newTemp(Ity_I64); 12664 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12665 12666 putFReg(fd, binop(Iop_I64StoF64, 12667 get_IR_roundingmode(), mkexpr(t0))); 12668 break; 12669 } else 12670 goto decode_failure; 12671 } 12672 default: 12673 goto decode_failure; 12674 } 12675 break; /* CVT.D */ 12676 12677 case 0x20: /* cvt.s */ 12678 switch (fmt) { 12679 case 0x14: /* W */ 12680 DIP("cvt.s.w %d, %d", fd, fs); 12681 calculateFCSR(fs, 0, CVTSW, True, 1); 12682 if (fp_mode64) { 12683 t0 = newTemp(Ity_I64); 12684 t1 = newTemp(Ity_I32); 12685 t3 = newTemp(Ity_F32); 12686 t4 = newTemp(Ity_F32); 12687 /* get lo half of FPR */ 12688 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12689 12690 assign(t1, unop(Iop_64to32, mkexpr(t0))); 12691 putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I32StoF32, 12692 get_IR_roundingmode(), mkexpr(t1)))); 12693 } else { 12694 t0 = newTemp(Ity_I32); 12695 assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs))); 12696 putFReg(fd, binop(Iop_I32StoF32, get_IR_roundingmode(), 12697 mkexpr(t0))); 12698 } 12699 break; 12700 12701 case 0x11: /* D */ 12702 DIP("cvt.s.d %d, %d", fd, fs); 12703 calculateFCSR(fs, 0, CVTSD, False, 1); 12704 t0 = newTemp(Ity_F32); 12705 assign(t0, binop(Iop_F64toF32, get_IR_roundingmode(), 12706 getDReg(fs))); 12707 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t0))); 12708 break; 12709 12710 case 0x15: /* L */ 12711 DIP("cvt.s.l %d, %d", fd, fs); 12712 calculateFCSR(fs, 0, CVTSL, False, 1); 12713 t0 = newTemp(Ity_I64); 12714 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12715 12716 putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I64StoF32, 12717 get_IR_roundingmode(), mkexpr(t0)))); 12718 break; 12719 12720 default: 12721 goto decode_failure; 12722 } 12723 break; /* cvt.s */ 12724 12725 case 0x24: /* cvt.w */ 12726 switch (fmt) { 12727 case 0x10: /* S */ 12728 DIP("cvt.w.s %d, %d", fd, fs); 12729 calculateFCSR(fs, 0, CVTWS, True, 1); 12730 putFReg(fd, 12731 mkWidenFromF32(tyF, 12732 binop(Iop_RoundF32toInt, 12733 get_IR_roundingmode(), 12734 getLoFromF64(tyF, getFReg(fs)))) 12735 ); 12736 break; 12737 12738 case 0x11: 12739 DIP("cvt.w.d %d, %d", fd, fs); 12740 calculateFCSR(fs, 0, CVTWD, False, 1); 12741 t0 = newTemp(Ity_I32); 12742 t1 = newTemp(Ity_F32); 12743 assign(t0, binop(Iop_F64toI32S, get_IR_roundingmode(), 12744 getDReg(fs))); 12745 assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0))); 12746 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1))); 12747 break; 12748 12749 default: 12750 goto decode_failure; 12751 12752 } 12753 break; 12754 12755 case 0x25: /* cvt.l */ 12756 switch (fmt) { 12757 case 0x10: /* S */ 12758 DIP("cvt.l.s %d, %d", fd, fs); 12759 if (fp_mode64) { 12760 calculateFCSR(fs, 0, CVTLS, True, 1); 12761 t0 = newTemp(Ity_I64); 12762 12763 assign(t0, binop(Iop_F32toI64S, get_IR_roundingmode(), 12764 getLoFromF64(tyF, getFReg(fs)))); 12765 12766 putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); 12767 } else { 12768 ILLEGAL_INSTRUCTON; 12769 } 12770 break; 12771 12772 case 0x11: { /* D */ 12773 DIP("cvt.l.d %d, %d", fd, fs); 12774 if (fp_mode64) { 12775 calculateFCSR(fs, 0, CVTLD, False, 1); 12776 putDReg(fd, binop(Iop_RoundF64toInt, 12777 get_IR_roundingmode(), getDReg(fs))); 12778 } else { 12779 ILLEGAL_INSTRUCTON; 12780 } 12781 break; 12782 } 12783 12784 default: 12785 goto decode_failure; 12786 } 12787 break; 12788 12789 case 0x0B: /* FLOOR.L.fmt */ 12790 switch (fmt) { 12791 case 0x10: /* S */ 12792 DIP("floor.l.s %d, %d", fd, fs); 12793 if (fp_mode64) { 12794 calculateFCSR(fs, 0, FLOORLS, True, 1); 12795 t0 = newTemp(Ity_I64); 12796 12797 assign(t0, binop(Iop_F32toI64S, mkU32(0x1), 12798 getLoFromF64(tyF, getFReg(fs)))); 12799 12800 putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); 12801 } else { 12802 ILLEGAL_INSTRUCTON; 12803 } 12804 break; 12805 12806 case 0x11: /* D */ 12807 DIP("floor.l.d %d, %d", fd, fs); 12808 if (fp_mode64) { 12809 calculateFCSR(fs, 0, FLOORLD, False, 1); 12810 putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x1), 12811 getDReg(fs))); 12812 } else { 12813 ILLEGAL_INSTRUCTON; 12814 } 12815 break; 12816 default: 12817 goto decode_failure; 12818 } 12819 break; 12820 12821 case 0x0C: /* ROUND.W.fmt */ 12822 switch (fmt) { 12823 case 0x10: /* S */ 12824 DIP("round.w.s f%d, f%d", fd, fs); 12825 calculateFCSR(fs, 0, ROUNDWS, True, 1); 12826 if (fp_mode64) { 12827 t0 = newTemp(Ity_I64); 12828 t1 = newTemp(Ity_I32); 12829 t3 = newTemp(Ity_F32); 12830 t4 = newTemp(Ity_F32); 12831 /* get lo half of FPR */ 12832 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12833 12834 assign(t1, unop(Iop_64to32, mkexpr(t0))); 12835 12836 assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1))); 12837 12838 assign(t4, binop(Iop_RoundF32toInt, mkU32(0x0), 12839 mkexpr(t3))); 12840 12841 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4))); 12842 } else 12843 putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x0), 12844 getFReg(fs))); 12845 break; 12846 12847 case 0x11: /* D */ 12848 DIP("round.w.d f%d, f%d", fd, fs); 12849 calculateFCSR(fs, 0, ROUNDWD, False, 1); 12850 if (fp_mode64) { 12851 t0 = newTemp(Ity_I32); 12852 assign(t0, binop(Iop_F64toI32S, mkU32(0x0), 12853 getDReg(fs))); 12854 putFReg(fd, mkWidenFromF32(tyF, 12855 unop(Iop_ReinterpI32asF32, mkexpr(t0)))); 12856 } else { 12857 t0 = newTemp(Ity_I32); 12858 12859 assign(t0, binop(Iop_F64toI32S, mkU32(0x0), 12860 getDReg(fs))); 12861 12862 putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0))); 12863 } 12864 break; 12865 default: 12866 goto decode_failure; 12867 12868 } 12869 break; /* ROUND.W.fmt */ 12870 12871 case 0x0F: /* FLOOR.W.fmt */ 12872 switch (fmt) { 12873 case 0x10: /* S */ 12874 DIP("floor.w.s f%d, f%d", fd, fs); 12875 calculateFCSR(fs, 0, FLOORWS, True, 1); 12876 if (fp_mode64) { 12877 t0 = newTemp(Ity_I64); 12878 t1 = newTemp(Ity_I32); 12879 t3 = newTemp(Ity_F32); 12880 t4 = newTemp(Ity_F32); 12881 /* get lo half of FPR */ 12882 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12883 12884 assign(t1, unop(Iop_64to32, mkexpr(t0))); 12885 12886 assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1))); 12887 12888 assign(t4, binop(Iop_RoundF32toInt, mkU32(0x1), 12889 mkexpr(t3))); 12890 12891 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4))); 12892 } else 12893 putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x1), 12894 getFReg(fs))); 12895 break; 12896 12897 case 0x11: /* D */ 12898 DIP("floor.w.d f%d, f%d", fd, fs); 12899 calculateFCSR(fs, 0, FLOORWD, False, 1); 12900 if (fp_mode64) { 12901 t0 = newTemp(Ity_I32); 12902 assign(t0, binop(Iop_F64toI32S, mkU32(0x1), 12903 getDReg(fs))); 12904 putFReg(fd, mkWidenFromF32(tyF, 12905 unop(Iop_ReinterpI32asF32, mkexpr(t0)))); 12906 break; 12907 } else { 12908 t0 = newTemp(Ity_I32); 12909 12910 assign(t0, binop(Iop_F64toI32S, mkU32(0x1), 12911 getDReg(fs))); 12912 12913 putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0))); 12914 break; 12915 } 12916 default: 12917 goto decode_failure; 12918 12919 } 12920 break; /* FLOOR.W.fmt */ 12921 12922 case 0x0D: /* TRUNC.W */ 12923 switch (fmt) { 12924 case 0x10: /* S */ 12925 DIP("trunc.w.s %d, %d", fd, fs); 12926 calculateFCSR(fs, 0, TRUNCWS, True, 1); 12927 if (fp_mode64) { 12928 t0 = newTemp(Ity_I64); 12929 t1 = newTemp(Ity_I32); 12930 t3 = newTemp(Ity_F32); 12931 t4 = newTemp(Ity_F32); 12932 /* get lo half of FPR */ 12933 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12934 12935 assign(t1, unop(Iop_64to32, mkexpr(t0))); 12936 12937 assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1))); 12938 12939 assign(t4, binop(Iop_RoundF32toInt, mkU32(0x3), 12940 mkexpr(t3))); 12941 12942 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4))); 12943 } else 12944 putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x3), 12945 getFReg(fs))); 12946 break; 12947 case 0x11: /* D */ 12948 DIP("trunc.w.d %d, %d", fd, fs); 12949 calculateFCSR(fs, 0, TRUNCWD, False, 1); 12950 if (fp_mode64) { 12951 t0 = newTemp(Ity_I32); 12952 12953 assign(t0, binop(Iop_F64toI32S, mkU32(0x3), 12954 getFReg(fs))); 12955 12956 putFReg(fd, mkWidenFromF32(tyF, 12957 unop(Iop_ReinterpI32asF32, mkexpr(t0)))); 12958 } else { 12959 t0 = newTemp(Ity_I32); 12960 12961 assign(t0, binop(Iop_F64toI32S, mkU32(0x3), 12962 getDReg(fs))); 12963 12964 putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0))); 12965 } 12966 break; 12967 default: 12968 goto decode_failure; 12969 12970 } 12971 break; 12972 12973 case 0x0E: /* CEIL.W.fmt */ 12974 switch (fmt) { 12975 case 0x10: /* S */ 12976 DIP("ceil.w.s %d, %d", fd, fs); 12977 calculateFCSR(fs, 0, CEILWS, True, 1); 12978 if (fp_mode64) { 12979 t0 = newTemp(Ity_I64); 12980 t1 = newTemp(Ity_I32); 12981 t3 = newTemp(Ity_F32); 12982 t4 = newTemp(Ity_F32); 12983 /* get lo half of FPR */ 12984 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12985 12986 assign(t1, unop(Iop_64to32, mkexpr(t0))); 12987 12988 assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1))); 12989 12990 assign(t4, binop(Iop_RoundF32toInt, mkU32(0x2), 12991 mkexpr(t3))); 12992 12993 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4))); 12994 } else 12995 putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x2), 12996 getFReg(fs))); 12997 break; 12998 12999 case 0x11: /* D */ 13000 DIP("ceil.w.d %d, %d", fd, fs); 13001 calculateFCSR(fs, 0, CEILWD, False, 1); 13002 if (!fp_mode64) { 13003 t0 = newTemp(Ity_I32); 13004 assign(t0, binop(Iop_F64toI32S, mkU32(0x2), 13005 getDReg(fs))); 13006 putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0))); 13007 } else { 13008 t0 = newTemp(Ity_I32); 13009 assign(t0, binop(Iop_F64toI32S, mkU32(0x2), 13010 getDReg(fs))); 13011 putFReg(fd, mkWidenFromF32(tyF, 13012 unop(Iop_ReinterpI32asF32, mkexpr(t0)))); 13013 } 13014 break; 13015 default: 13016 goto decode_failure; 13017 13018 } 13019 break; 13020 13021 case 0x0A: /* CEIL.L.fmt */ 13022 switch (fmt) { 13023 case 0x10: /* S */ 13024 DIP("ceil.l.s %d, %d", fd, fs); 13025 if (fp_mode64) { 13026 calculateFCSR(fs, 0, CEILLS, True, 1); 13027 t0 = newTemp(Ity_I64); 13028 13029 assign(t0, binop(Iop_F32toI64S, mkU32(0x2), 13030 getLoFromF64(tyF, getFReg(fs)))); 13031 13032 putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); 13033 } else { 13034 ILLEGAL_INSTRUCTON; 13035 } 13036 break; 13037 13038 case 0x11: /* D */ 13039 DIP("ceil.l.d %d, %d", fd, fs); 13040 if (fp_mode64) { 13041 calculateFCSR(fs, 0, CEILLD, False, 1); 13042 putFReg(fd, binop(Iop_RoundF64toInt, mkU32(0x2), 13043 getFReg(fs))); 13044 } else { 13045 ILLEGAL_INSTRUCTON; 13046 } 13047 break; 13048 13049 default: 13050 goto decode_failure; 13051 13052 } 13053 break; 13054 13055 case 0x16: /* RSQRT.fmt */ 13056 switch (fmt) { 13057 case 0x10: { /* S */ 13058 DIP("rsqrt.s %d, %d", fd, fs); 13059 IRExpr *rm = get_IR_roundingmode(); 13060 putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm, 13061 unop(Iop_ReinterpI32asF32, mkU32(ONE_SINGLE)), 13062 binop(Iop_SqrtF32, rm, getLoFromF64(tyF, 13063 getFReg(fs)))))); 13064 break; 13065 } 13066 case 0x11: { /* D */ 13067 DIP("rsqrt.d %d, %d", fd, fs); 13068 IRExpr *rm = get_IR_roundingmode(); 13069 putDReg(fd, triop(Iop_DivF64, rm, 13070 unop(Iop_ReinterpI64asF64, 13071 mkU64(ONE_DOUBLE)), 13072 binop(Iop_SqrtF64, rm, getDReg(fs)))); 13073 break; 13074 } 13075 default: 13076 goto decode_failure; 13077 13078 } 13079 break; 13080 13081 default: 13082 if (dis_instr_CCondFmt(cins)) 13083 break; 13084 goto decode_failure; 13085 13086 } 13087 13088 } 13089 } 13090 break; /* COP1 */ 13091 case 0x10: /* COP0 */ 13092 if (rs == 0) { /* MFC0 */ 13093 DIP("mfc0 r%d, r%d, %d", rt, rd, sel); 13094 IRTemp val = newTemp(Ity_I32); 13095 IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(), mkU32(rd), mkU32(sel)); 13096 IRDirty *d = unsafeIRDirty_1_N(val, 13097 0, 13098 "mips32_dirtyhelper_mfc0", 13099 &mips32_dirtyhelper_mfc0, 13100 args); 13101 stmt(IRStmt_Dirty(d)); 13102 putIReg(rt, mkexpr(val)); 13103 } else if (rs == 1) { 13104 /* Doubleword Move from Coprocessor 0 - DMFC0; MIPS64 */ 13105 DIP("dmfc0 r%d, r%d, %d", rt, rd, sel); 13106 IRTemp val = newTemp(Ity_I64); 13107 IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(), mkU64(rd), mkU64(sel)); 13108 IRDirty *d = unsafeIRDirty_1_N(val, 13109 0, 13110 "mips64_dirtyhelper_dmfc0", 13111 &mips64_dirtyhelper_dmfc0, 13112 args); 13113 stmt(IRStmt_Dirty(d)); 13114 putDReg(rt, mkexpr(val)); 13115 } else 13116 goto decode_failure; 13117 break; 13118 13119 case 0x31: /* LWC1 */ 13120 /* Load Word to Floating Point - LWC1 (MIPS32) */ 13121 DIP("lwc1 f%d, %d(r%d)", ft, imm, rs); 13122 if (fp_mode64) { 13123 t1 = newTemp(Ity_F32); 13124 t2 = newTemp(Ity_I64); 13125 if (mode64) { 13126 t0 = newTemp(Ity_I64); 13127 /* new LO */ 13128 assign(t0, binop(Iop_Add64, getIReg(rs), 13129 mkU64(extend_s_16to64(imm)))); 13130 } else { 13131 t0 = newTemp(Ity_I32); 13132 /* new LO */ 13133 assign(t0, binop(Iop_Add32, getIReg(rs), 13134 mkU32(extend_s_16to32(imm)))); 13135 } 13136 assign(t1, load(Ity_F32, mkexpr(t0))); 13137 assign(t2, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32, 13138 mkexpr(t1)), True)); 13139 putDReg(ft, unop(Iop_ReinterpI64asF64, mkexpr(t2))); 13140 } else { 13141 t0 = newTemp(Ity_I32); 13142 assign(t0, binop(Iop_Add32, getIReg(rs), 13143 mkU32(extend_s_16to32(imm)))); 13144 putFReg(ft, load(Ity_F32, mkexpr(t0))); 13145 } 13146 break; 13147 13148 case 0x39: /* SWC1 */ 13149 DIP("swc1 f%d, %d(r%d)", ft, imm, rs); 13150 if (fp_mode64) { 13151 t0 = newTemp(Ity_I64); 13152 t2 = newTemp(Ity_I32); 13153 LOAD_STORE_PATTERN; 13154 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(ft))); 13155 assign(t2, unop(Iop_64to32, mkexpr(t0))); 13156 store(mkexpr(t1), unop(Iop_ReinterpI32asF32, mkexpr(t2))); 13157 } else { 13158 LOAD_STORE_PATTERN; 13159 store(mkexpr(t1), getFReg(ft)); 13160 } 13161 break; 13162 13163 case 0x33: /* PREF */ 13164 DIP("pref"); 13165 break; 13166 13167 case 0x35: 13168 /* Load Doubleword to Floating Point - LDC1 (MIPS32) */ 13169 DIP("ldc1 f%d, %d(%d)", rt, imm, rs); 13170 LOAD_STORE_PATTERN; 13171 putDReg(ft, load(Ity_F64, mkexpr(t1))); 13172 break; 13173 13174 case 0x3D: 13175 /* Store Doubleword from Floating Point - SDC1 */ 13176 DIP("sdc1 f%d, %d(%d)", ft, imm, rs); 13177 LOAD_STORE_PATTERN; 13178 store(mkexpr(t1), getDReg(ft)); 13179 break; 13180 13181 case 0x23: /* LW */ 13182 DIP("lw r%d, %d(r%d)", rt, imm, rs); 13183 LOAD_STORE_PATTERN; 13184 putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), True)); 13185 break; 13186 13187 case 0x20: /* LB */ 13188 DIP("lb r%d, %d(r%d)", rt, imm, rs); 13189 LOAD_STORE_PATTERN; 13190 if (mode64) 13191 putIReg(rt, unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1)))); 13192 else 13193 putIReg(rt, unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1)))); 13194 break; 13195 13196 case 0x24: /* LBU */ 13197 DIP("lbu r%d, %d(r%d)", rt, imm, rs); 13198 LOAD_STORE_PATTERN; 13199 if (mode64) 13200 putIReg(rt, unop(Iop_8Uto64, load(Ity_I8, mkexpr(t1)))); 13201 else 13202 putIReg(rt, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t1)))); 13203 break; 13204 13205 case 0x21: /* LH */ 13206 DIP("lh r%d, %d(r%d)", rt, imm, rs); 13207 LOAD_STORE_PATTERN; 13208 if (mode64) 13209 putIReg(rt, unop(Iop_16Sto64, load(Ity_I16, mkexpr(t1)))); 13210 else 13211 putIReg(rt, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t1)))); 13212 break; 13213 13214 case 0x25: /* LHU */ 13215 DIP("lhu r%d, %d(r%d)", rt, imm, rs); 13216 LOAD_STORE_PATTERN; 13217 if (mode64) 13218 putIReg(rt, unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1)))); 13219 else 13220 putIReg(rt, unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1)))); 13221 break; 13222 13223 case 0x0F: /* LUI */ 13224 p = (imm << 16); 13225 DIP("lui r%d, imm: 0x%x", rt, imm); 13226 if (mode64) 13227 putIReg(rt, mkU64(extend_s_32to64(p))); 13228 else 13229 putIReg(rt, mkU32(p)); 13230 break; 13231 13232 case 0x13: /* COP1X */ 13233 switch (function) { 13234 case 0x0: { /* LWXC1 */ 13235 /* Load Word Indexed to Floating Point - LWXC1 (MIPS32r2) */ 13236 DIP("lwxc1 f%d, r%d(r%d)", fd, rt, rs); 13237 if (fp_mode64) { 13238 t0 = newTemp(Ity_I64); 13239 t1 = newTemp(Ity_I32); 13240 t3 = newTemp(Ity_F32); 13241 t4 = newTemp(Ity_I64); 13242 13243 t2 = newTemp(ty); 13244 /* new LO */ 13245 assign(t2, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs), 13246 getIReg(rt))); 13247 assign(t3, load(Ity_F32, mkexpr(t2))); 13248 13249 assign(t4, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32, 13250 mkexpr(t3)), True)); 13251 13252 putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t4))); 13253 } else { 13254 t0 = newTemp(Ity_I32); 13255 assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt))); 13256 putFReg(fd, load(Ity_F32, mkexpr(t0))); 13257 } 13258 break; 13259 } 13260 13261 case 0x1: { /* LDXC1 */ 13262 /* Load Doubleword Indexed to Floating Point 13263 LDXC1 (MIPS32r2 and MIPS64) */ 13264 if (fp_mode64) { 13265 DIP("ldxc1 f%d, r%d(r%d)", fd, rt, rs); 13266 t0 = newTemp(ty); 13267 assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs), 13268 getIReg(rt))); 13269 putFReg(fd, load(Ity_F64, mkexpr(t0))); 13270 break; 13271 } else { 13272 t0 = newTemp(Ity_I32); 13273 assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt))); 13274 13275 t1 = newTemp(Ity_I32); 13276 assign(t1, binop(Iop_Add32, mkexpr(t0), mkU32(4))); 13277 13278 #if defined (_MIPSEL) 13279 putFReg(fd, load(Ity_F32, mkexpr(t0))); 13280 putFReg(fd + 1, load(Ity_F32, mkexpr(t1))); 13281 #elif defined (_MIPSEB) 13282 putFReg(fd + 1, load(Ity_F32, mkexpr(t0))); 13283 putFReg(fd, load(Ity_F32, mkexpr(t1))); 13284 #endif 13285 break; 13286 } 13287 } 13288 13289 case 0x5: /* Load Doubleword Indexed Unaligned to Floating Point - LUXC1; 13290 MIPS32r2 */ 13291 DIP("luxc1 f%d, r%d(r%d)", fd, rt, rs); 13292 t0 = newTemp(Ity_I64); 13293 t1 = newTemp(Ity_I64); 13294 assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt))); 13295 assign(t1, binop(Iop_And64, mkexpr(t0), 13296 mkU64(0xfffffffffffffff8ULL))); 13297 putFReg(fd, load(Ity_F64, mkexpr(t1))); 13298 break; 13299 13300 case 0x8: { /* Store Word Indexed from Floating Point - SWXC1 */ 13301 DIP("swxc1 f%d, r%d(r%d)", ft, rt, rs); 13302 if (fp_mode64) { 13303 t0 = newTemp(ty); 13304 assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs), 13305 getIReg(rt))); 13306 store(mkexpr(t0), getLoFromF64(tyF, getFReg(fs))); 13307 13308 } else { 13309 t0 = newTemp(Ity_I32); 13310 assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt))); 13311 13312 store(mkexpr(t0), getFReg(fs)); 13313 } 13314 break; 13315 } 13316 case 0x9: { /* Store Doubleword Indexed from Floating Point - SDXC1 */ 13317 DIP("sdc1 f%d, %d(%d)", ft, imm, rs); 13318 if (fp_mode64) { 13319 t0 = newTemp(ty); 13320 assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs), 13321 getIReg(rt))); 13322 store(mkexpr(t0), getFReg(fs)); 13323 } else { 13324 t0 = newTemp(Ity_I32); 13325 assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt))); 13326 13327 t1 = newTemp(Ity_I32); 13328 assign(t1, binop(Iop_Add32, mkexpr(t0), mkU32(4))); 13329 13330 #if defined (_MIPSEL) 13331 store(mkexpr(t0), getFReg(fs)); 13332 store(mkexpr(t1), getFReg(fs + 1)); 13333 #elif defined (_MIPSEB) 13334 store(mkexpr(t0), getFReg(fs + 1)); 13335 store(mkexpr(t1), getFReg(fs)); 13336 #endif 13337 } 13338 break; 13339 } 13340 case 0xD: /* Store Doubleword Indexed Unaligned from Floating Point - 13341 SUXC1; MIPS64 MIPS32r2 */ 13342 DIP("suxc1 f%d, r%d(r%d)", fd, rt, rs); 13343 t0 = newTemp(Ity_I64); 13344 t1 = newTemp(Ity_I64); 13345 assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt))); 13346 assign(t1, binop(Iop_And64, mkexpr(t0), mkU64(0xfffffffffffffff8ULL))); 13347 store(mkexpr(t1), getFReg(fs)); 13348 break; 13349 13350 case 0x0F: { 13351 DIP("prefx"); 13352 break; 13353 } 13354 case 0x20: { /* MADD.S */ 13355 DIP("madd.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13356 IRExpr *rm = get_IR_roundingmode(); 13357 t1 = newTemp(Ity_F32); 13358 assign(t1, qop(Iop_MAddF32, rm, 13359 getLoFromF64(tyF, getFReg(fmt)), 13360 getLoFromF64(tyF, getFReg(fs)), 13361 getLoFromF64(tyF, getFReg(ft)))); 13362 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1))); 13363 break; /* MADD.S */ 13364 } 13365 case 0x21: { /* MADD.D */ 13366 DIP("madd.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13367 IRExpr *rm = get_IR_roundingmode(); 13368 putDReg(fd, qop(Iop_MAddF64, rm, getDReg(fmt), getDReg(fs), 13369 getDReg(ft))); 13370 break; /* MADD.D */ 13371 } 13372 case 0x28: { /* MSUB.S */ 13373 DIP("msub.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13374 IRExpr *rm = get_IR_roundingmode(); 13375 t1 = newTemp(Ity_F32); 13376 assign(t1, qop(Iop_MSubF32, rm, 13377 getLoFromF64(tyF, getFReg(fmt)), 13378 getLoFromF64(tyF, getFReg(fs)), 13379 getLoFromF64(tyF, getFReg(ft)))); 13380 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1))); 13381 break; /* MSUB.S */ 13382 } 13383 case 0x29: { /* MSUB.D */ 13384 DIP("msub.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13385 IRExpr *rm = get_IR_roundingmode(); 13386 putDReg(fd, qop(Iop_MSubF64, rm, getDReg(fmt), getDReg(fs), 13387 getDReg(ft))); 13388 break; /* MSUB.D */ 13389 } 13390 case 0x30: { /* NMADD.S */ 13391 DIP("nmadd.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13392 IRExpr *rm = get_IR_roundingmode(); 13393 t1 = newTemp(Ity_F32); 13394 assign(t1, qop(Iop_MAddF32, rm, 13395 getLoFromF64(tyF, getFReg(fmt)), 13396 getLoFromF64(tyF, getFReg(fs)), 13397 getLoFromF64(tyF, getFReg(ft)))); 13398 13399 putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1)))); 13400 break; /* NMADD.S */ 13401 } 13402 case 0x31: { /* NMADD.D */ 13403 DIP("nmadd.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13404 IRExpr *rm = get_IR_roundingmode(); 13405 t1 = newTemp(Ity_F64); 13406 assign(t1, qop(Iop_MAddF64, rm, getDReg(fmt), getDReg(fs), 13407 getDReg(ft))); 13408 putDReg(fd, unop(Iop_NegF64, mkexpr(t1))); 13409 break; /* NMADD.D */ 13410 } 13411 case 0x38: { /* NMSUBB.S */ 13412 DIP("nmsub.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13413 IRExpr *rm = get_IR_roundingmode(); 13414 t1 = newTemp(Ity_F32); 13415 assign(t1, qop(Iop_MSubF32, rm, 13416 getLoFromF64(tyF, getFReg(fmt)), 13417 getLoFromF64(tyF, getFReg(fs)), 13418 getLoFromF64(tyF, getFReg(ft)))); 13419 13420 putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1)))); 13421 break; /* NMSUBB.S */ 13422 } 13423 case 0x39: { /* NMSUBB.D */ 13424 DIP("nmsub.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13425 IRExpr *rm = get_IR_roundingmode(); 13426 t1 = newTemp(Ity_F64); 13427 assign(t1, qop(Iop_MSubF64, rm, getDReg(fmt), getDReg(fs), 13428 getDReg(ft))); 13429 putDReg(fd, unop(Iop_NegF64, mkexpr(t1))); 13430 break; /* NMSUBB.D */ 13431 } 13432 13433 default: 13434 goto decode_failure; 13435 } 13436 break; 13437 13438 case 0x22: /* LWL */ 13439 DIP("lwl r%d, %d(r%d)", rt, imm, rs); 13440 if (mode64) { 13441 /* t1 = addr */ 13442 t1 = newTemp(Ity_I64); 13443 #if defined (_MIPSEL) 13444 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 13445 /* t2 = word addr */ 13446 /* t4 = addr mod 4 */ 13447 LWX_SWX_PATTERN64; 13448 13449 /* t3 = word content - shifted */ 13450 t3 = newTemp(Ity_I32); 13451 assign(t3, binop(Iop_Shl32, mkNarrowTo32(ty, load(Ity_I64, 13452 mkexpr(t2))), narrowTo(Ity_I8, binop(Iop_Shl32, 13453 binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)), mkU8(3))))); 13454 13455 /* rt content - adjusted */ 13456 t5 = newTemp(Ity_I32); 13457 assign(t5, binop(Iop_And32, 13458 mkNarrowTo32(ty, getIReg(rt)), 13459 binop(Iop_Shr32, 13460 mkU32(0x00FFFFFF), 13461 narrowTo(Ity_I8, binop(Iop_Mul32, 13462 mkU32(0x08), 13463 mkexpr(t4)))))); 13464 13465 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5), 13466 mkexpr(t3)), True)); 13467 #elif defined (_MIPSEB) 13468 assign(t1, binop(Iop_Xor64, mkU64(0x3), 13469 binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))))); 13470 /* t2 = word addr */ 13471 /* t4 = addr mod 4 */ 13472 LWX_SWX_PATTERN64; 13473 13474 /* t3 = word content - shifted */ 13475 t3 = newTemp(Ity_I32); 13476 assign(t3, binop(Iop_Shl32, unop(Iop_64HIto32, load(Ity_I64, 13477 mkexpr(t2))), narrowTo(Ity_I8, binop(Iop_Shl32, 13478 binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)), mkU8(3))))); 13479 13480 /* rt content - adjusted */ 13481 t5 = newTemp(Ity_I32); 13482 assign(t5, binop(Iop_And32, 13483 mkNarrowTo32(ty, getIReg(rt)), 13484 binop(Iop_Shr32, 13485 mkU32(0x00FFFFFF), 13486 narrowTo(Ity_I8, binop(Iop_Mul32, 13487 mkU32(0x08), 13488 mkexpr(t4)))))); 13489 13490 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5), 13491 mkexpr(t3)), True)); 13492 #endif 13493 } else { 13494 /* t1 = addr */ 13495 t1 = newTemp(Ity_I32); 13496 #if defined (_MIPSEL) 13497 assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm)))); 13498 #elif defined (_MIPSEB) 13499 assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs), 13500 mkU32(extend_s_16to32(imm))))); 13501 #endif 13502 13503 /* t2 = word addr */ 13504 /* t4 = addr mod 4 */ 13505 LWX_SWX_PATTERN; 13506 13507 /* t3 = word content - shifted */ 13508 t3 = newTemp(Ity_I32); 13509 assign(t3, binop(Iop_Shl32, load(Ity_I32, mkexpr(t2)), narrowTo(Ity_I8, 13510 binop(Iop_Shl32, binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)), 13511 mkU8(3))))); 13512 13513 /* rt content - adjusted */ 13514 t5 = newTemp(Ity_I32); 13515 assign(t5, binop(Iop_And32, 13516 getIReg(rt), 13517 binop(Iop_Shr32, 13518 mkU32(0x00FFFFFF), 13519 narrowTo(Ity_I8, binop(Iop_Mul32, 13520 mkU32(0x08), 13521 mkexpr(t4)))))); 13522 13523 putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3))); 13524 } 13525 break; 13526 13527 case 0x26: /* LWR */ 13528 DIP("lwr r%d, %d(r%d)", rt, imm, rs); 13529 if (mode64) { 13530 /* t1 = addr */ 13531 t1 = newTemp(Ity_I64); 13532 #if defined (_MIPSEL) 13533 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 13534 /* t2 = word addr */ 13535 /* t4 = addr mod 8 */ 13536 LWX_SWX_PATTERN64; 13537 13538 /* t3 = word content - shifted */ 13539 t3 = newTemp(Ity_I32); 13540 assign(t3, binop(Iop_Shr32, mkNarrowTo32(ty, load(Ity_I64,mkexpr(t2))), 13541 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(3))))); 13542 13543 /* rt content - adjusted */ 13544 t5 = newTemp(Ity_I32); 13545 assign(t5, binop(Iop_And32, mkNarrowTo32(ty, getIReg(rt)), 13546 unop(Iop_Not32, binop(Iop_Shr32, mkU32(0xFFFFFFFF), 13547 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(0x3))))))); 13548 13549 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5), 13550 mkexpr(t3)), True)); 13551 #elif defined (_MIPSEB) 13552 assign(t1, binop(Iop_Xor64, mkU64(0x3), binop(Iop_Add64, getIReg(rs), 13553 mkU64(extend_s_16to64(imm))))); 13554 /* t2 = word addr */ 13555 /* t4 = addr mod 4 */ 13556 LWX_SWX_PATTERN64; 13557 13558 /* t3 = word content - shifted */ 13559 t3 = newTemp(Ity_I32); 13560 assign(t3, binop(Iop_Shr32, unop(Iop_64HIto32, load(Ity_I64,mkexpr(t2))), 13561 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(3))))); 13562 13563 /* rt content - adjusted */ 13564 t5 = newTemp(Ity_I32); 13565 assign(t5, binop(Iop_And32, mkNarrowTo32(ty, getIReg(rt)), 13566 unop(Iop_Not32, binop(Iop_Shr32, mkU32(0xFFFFFFFF), 13567 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(0x3))))))); 13568 13569 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5), 13570 mkexpr(t3)), True)); 13571 #endif 13572 13573 } else { 13574 /* t1 = addr */ 13575 t1 = newTemp(Ity_I32); 13576 #if defined (_MIPSEL) 13577 assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm)))); 13578 #elif defined (_MIPSEB) 13579 assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs), 13580 mkU32(extend_s_16to32(imm))))); 13581 #endif 13582 13583 /* t2 = word addr */ 13584 /* t4 = addr mod 4 */ 13585 LWX_SWX_PATTERN; 13586 13587 /* t3 = word content - shifted */ 13588 t3 = newTemp(Ity_I32); 13589 assign(t3, binop(Iop_Shr32, load(Ity_I32, mkexpr(t2)), 13590 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), 13591 mkU8(3))))); 13592 13593 /* rt content - adjusted */ 13594 t5 = newTemp(Ity_I32); 13595 assign(t5, binop(Iop_And32, getIReg(rt), unop(Iop_Not32, 13596 binop(Iop_Shr32, mkU32(0xFFFFFFFF), narrowTo(Ity_I8, 13597 binop(Iop_Shl32, mkexpr(t4), mkU8(0x3))))))); 13598 13599 putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3))); 13600 } 13601 break; 13602 13603 case 0x2B: /* SW */ 13604 DIP("sw r%d, %d(r%d)", rt, imm, rs); 13605 LOAD_STORE_PATTERN; 13606 store(mkexpr(t1), mkNarrowTo32(ty, getIReg(rt))); 13607 break; 13608 13609 case 0x2C: { /* SDL rt, offset(base) MIPS64 */ 13610 DIP("sdl r%u, %d(r%u)", rt, (Int) imm, rs); 13611 vassert(mode64); 13612 IRTemp A_byte = newTemp(Ity_I8); 13613 IRTemp B_byte = newTemp(Ity_I8); 13614 IRTemp C_byte = newTemp(Ity_I8); 13615 IRTemp D_byte = newTemp(Ity_I8); 13616 IRTemp E_byte = newTemp(Ity_I8); 13617 IRTemp F_byte = newTemp(Ity_I8); 13618 IRTemp G_byte = newTemp(Ity_I8); 13619 IRTemp H_byte = newTemp(Ity_I8); 13620 IRTemp B_pos = newTemp(Ity_I64); 13621 IRTemp C_pos = newTemp(Ity_I64); 13622 IRTemp D_pos = newTemp(Ity_I64); 13623 IRTemp E_pos = newTemp(Ity_I64); 13624 IRTemp F_pos = newTemp(Ity_I64); 13625 IRTemp G_pos = newTemp(Ity_I64); 13626 13627 /* H byte */ 13628 assign(H_byte, getByteFromReg(rt, 0)); 13629 /* G byte */ 13630 assign(G_byte, getByteFromReg(rt, 1)); 13631 /* F byte */ 13632 assign(F_byte, getByteFromReg(rt, 2)); 13633 /* E byte */ 13634 assign(E_byte, getByteFromReg(rt, 3)); 13635 /* D byte */ 13636 assign(D_byte, getByteFromReg(rt, 4)); 13637 /* C byte */ 13638 assign(C_byte, getByteFromReg(rt, 5)); 13639 /* B byte */ 13640 assign(B_byte, getByteFromReg(rt, 6)); 13641 /* A byte */ 13642 assign(A_byte, getByteFromReg(rt, 7)); 13643 13644 /* t1 = addr */ 13645 t1 = newTemp(Ity_I64); 13646 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 13647 13648 /* t2 = word addr */ 13649 t2 = newTemp(Ity_I64); 13650 assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL))); 13651 13652 /* t3 = addr mod 7 */ 13653 t3 = newTemp(Ity_I64); 13654 assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7))); 13655 13656 #if defined (_MIPSEL) 13657 /* Calculate X_byte position. */ 13658 assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x1)), 13659 mkU64(0x0), 13660 mkU64(0x1))); 13661 13662 assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x2)), 13663 mkU64(0x0), 13664 mkU64(0x2))); 13665 13666 assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)), 13667 mkU64(0x0), 13668 mkU64(0x3))); 13669 13670 assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)), 13671 mkU64(0x0), 13672 mkU64(0x4))); 13673 13674 assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)), 13675 mkU64(0x0), 13676 mkU64(0x5))); 13677 13678 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)), 13679 mkU64(0x1), 13680 mkU64(0x0))); 13681 13682 /* Store X_byte on the right place. */ 13683 store(mkexpr(t2), mkexpr(H_byte)); 13684 store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte)); 13685 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 13686 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte)); 13687 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte)); 13688 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte)); 13689 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte)); 13690 store(mkexpr(t1), mkexpr(A_byte)); 13691 13692 #else /* _MIPSEB */ 13693 /* Calculate X_byte position. */ 13694 assign(B_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)), 13695 mkU64(0x0), 13696 mkU64(0x1))); 13697 13698 assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x6)), 13699 mkU64(0x2), 13700 mkU64(0x0))); 13701 13702 assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)), 13703 mkU64(0x3), 13704 mkU64(0x0))); 13705 13706 assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)), 13707 mkU64(0x4), 13708 mkU64(0x0))); 13709 13710 assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)), 13711 mkU64(0x5), 13712 mkU64(0x0))); 13713 13714 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)), 13715 mkU64(0x6), 13716 mkU64(0x7))); 13717 13718 /* Store X_byte on the right place. */ 13719 store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(H_byte)); 13720 store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte)); 13721 store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 13722 store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte)); 13723 store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte)); 13724 store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte)); 13725 store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte)); 13726 store(mkexpr(t1), mkexpr(A_byte)); 13727 #endif 13728 13729 break; 13730 } 13731 13732 case 0x2D: { 13733 /* SDR rt, offset(base) - MIPS64 */ 13734 vassert(mode64); 13735 DIP("sdr r%u, %d(r%u)", rt, imm, rs); 13736 IRTemp A_byte = newTemp(Ity_I8); 13737 IRTemp B_byte = newTemp(Ity_I8); 13738 IRTemp C_byte = newTemp(Ity_I8); 13739 IRTemp D_byte = newTemp(Ity_I8); 13740 IRTemp E_byte = newTemp(Ity_I8); 13741 IRTemp F_byte = newTemp(Ity_I8); 13742 IRTemp G_byte = newTemp(Ity_I8); 13743 IRTemp H_byte = newTemp(Ity_I8); 13744 IRTemp B_pos = newTemp(Ity_I64); 13745 IRTemp C_pos = newTemp(Ity_I64); 13746 IRTemp D_pos = newTemp(Ity_I64); 13747 IRTemp E_pos = newTemp(Ity_I64); 13748 IRTemp F_pos = newTemp(Ity_I64); 13749 IRTemp G_pos = newTemp(Ity_I64); 13750 13751 /* H byte */ 13752 assign(H_byte, getByteFromReg(rt, 0)); 13753 /* G byte */ 13754 assign(G_byte, getByteFromReg(rt, 1)); 13755 /* F byte */ 13756 assign(F_byte, getByteFromReg(rt, 2)); 13757 /* E byte */ 13758 assign(E_byte, getByteFromReg(rt, 3)); 13759 /* D byte */ 13760 assign(D_byte, getByteFromReg(rt, 4)); 13761 /* C byte */ 13762 assign(C_byte, getByteFromReg(rt, 5)); 13763 /* B byte */ 13764 assign(B_byte, getByteFromReg(rt, 6)); 13765 /* A byte */ 13766 assign(A_byte, getByteFromReg(rt, 7)); 13767 13768 /* t1 = addr */ 13769 t1 = newTemp(Ity_I64); 13770 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 13771 13772 /* t2 = word addr */ 13773 t2 = newTemp(Ity_I64); 13774 assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL))); 13775 13776 /* t3 = addr mod 7 */ 13777 t3 = newTemp(Ity_I64); 13778 assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7))); 13779 13780 #if defined (_MIPSEL) 13781 /* Calculate X_byte position. */ 13782 assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)), 13783 mkU64(0x0), 13784 mkU64(0x6))); 13785 13786 assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)), 13787 mkU64(0x0), 13788 mkU64(0x5))); 13789 13790 assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)), 13791 mkU64(0x0), 13792 mkU64(0x4))); 13793 13794 assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)), 13795 mkU64(0x0), 13796 mkU64(0x3))); 13797 13798 assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)), 13799 mkU64(0x0), 13800 mkU64(0x2))); 13801 13802 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)), 13803 mkU64(0x0), 13804 mkU64(0x1))); 13805 13806 /* Store X_byte on the right place. */ 13807 store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(A_byte)); 13808 store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte)); 13809 store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte)); 13810 store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte)); 13811 store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte)); 13812 store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 13813 store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte)); 13814 store(mkexpr(t1), mkexpr(H_byte)); 13815 13816 #else /* _MIPSEB */ 13817 /* Calculate X_byte position. */ 13818 assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)), 13819 mkU64(0x6), 13820 mkU64(0x0))); 13821 13822 assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)), 13823 mkU64(0x5), 13824 mkU64(0x0))); 13825 13826 assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)), 13827 mkU64(0x4), 13828 mkU64(0x0))); 13829 13830 assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)), 13831 mkU64(0x3), 13832 mkU64(0x0))); 13833 13834 assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)), 13835 mkU64(0x2), 13836 mkU64(0x0))); 13837 13838 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)), 13839 mkU64(0x0), 13840 mkU64(0x1))); 13841 13842 /* Store X_byte on the right place. */ 13843 store(mkexpr(t2), mkexpr(A_byte)); 13844 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte)); 13845 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte)); 13846 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte)); 13847 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte)); 13848 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 13849 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte)); 13850 store(mkexpr(t1), mkexpr(H_byte)); 13851 #endif 13852 break; 13853 } 13854 13855 case 0x28: /* SB */ 13856 DIP("sb r%d, %d(r%d)", rt, imm, rs); 13857 LOAD_STORE_PATTERN; 13858 store(mkexpr(t1), narrowTo(Ity_I8, getIReg(rt))); 13859 break; 13860 13861 case 0x29: /* SH */ 13862 DIP("sh r%d, %d(r%d)", rt, imm, rs); 13863 LOAD_STORE_PATTERN; 13864 store(mkexpr(t1), narrowTo(Ity_I16, getIReg(rt))); 13865 break; 13866 13867 case 0x2A: /* SWL */ 13868 DIP("swl r%d, %d(r%d)", rt, imm, rs); 13869 if (mode64) { 13870 IRTemp E_byte = newTemp(Ity_I8); 13871 IRTemp F_byte = newTemp(Ity_I8); 13872 IRTemp G_byte = newTemp(Ity_I8); 13873 IRTemp H_byte = newTemp(Ity_I8); 13874 IRTemp F_pos = newTemp(Ity_I64); 13875 IRTemp G_pos = newTemp(Ity_I64); 13876 13877 /* H byte */ 13878 assign(H_byte, getByteFromReg(rt, 0)); 13879 /* G byte */ 13880 assign(G_byte, getByteFromReg(rt, 1)); 13881 /* F byte */ 13882 assign(F_byte, getByteFromReg(rt, 2)); 13883 /* E byte */ 13884 assign(E_byte, getByteFromReg(rt, 3)); 13885 13886 /* t1 = addr */ 13887 t1 = newTemp(Ity_I64); 13888 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 13889 13890 /* t2 = word addr */ 13891 t2 = newTemp(Ity_I64); 13892 assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL))); 13893 13894 /* t3 = addr mod 4 */ 13895 t3 = newTemp(Ity_I64); 13896 assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3))); 13897 13898 #if defined (_MIPSEL) 13899 /* Calculate X_byte position. */ 13900 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)), 13901 mkU64(0x0), 13902 mkU64(0x1))); 13903 13904 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)), 13905 mkU64(0x1), 13906 mkU64(0x0))); 13907 13908 /* Store X_byte on the right place. */ 13909 store(mkexpr(t2), mkexpr(H_byte)); 13910 store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte)); 13911 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 13912 store(mkexpr(t1), mkexpr(E_byte)); 13913 13914 #else /* _MIPSEB */ 13915 /* Calculate X_byte position. */ 13916 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)), 13917 mkU64(0x0), 13918 mkU64(0x1))); 13919 13920 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)), 13921 mkU64(0x2), 13922 mkU64(0x3))); 13923 13924 store(binop(Iop_Add64, mkexpr(t2), mkU64(3)), mkexpr(H_byte)); 13925 store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte)); 13926 store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 13927 store(mkexpr(t1), mkexpr(E_byte)); 13928 13929 #endif 13930 } else { 13931 IRTemp E_byte = newTemp(Ity_I8); 13932 IRTemp F_byte = newTemp(Ity_I8); 13933 IRTemp G_byte = newTemp(Ity_I8); 13934 IRTemp H_byte = newTemp(Ity_I8); 13935 IRTemp F_pos = newTemp(Ity_I32); 13936 IRTemp G_pos = newTemp(Ity_I32); 13937 13938 /* H byte */ 13939 assign(H_byte, getByteFromReg(rt, 0)); 13940 /* G byte */ 13941 assign(G_byte, getByteFromReg(rt, 1)); 13942 /* F byte */ 13943 assign(F_byte, getByteFromReg(rt, 2)); 13944 /* E byte */ 13945 assign(E_byte, getByteFromReg(rt, 3)); 13946 13947 /* t1 = addr */ 13948 t1 = newTemp(Ity_I32); 13949 assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm)))); 13950 13951 /* t2 = word addr */ 13952 t2 = newTemp(Ity_I32); 13953 assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL))); 13954 13955 /* t3 = addr mod 4 */ 13956 t3 = newTemp(Ity_I32); 13957 assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3))); 13958 13959 #if defined (_MIPSEL) 13960 /* Calculate X_byte position. */ 13961 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)), 13962 mkU32(0x0), 13963 mkU32(0x1))); 13964 13965 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)), 13966 mkU32(0x1), 13967 mkU32(0x0))); 13968 13969 /* Store X_byte on the right place. */ 13970 store(mkexpr(t2), mkexpr(H_byte)); 13971 store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte)); 13972 store(binop(Iop_Sub32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 13973 store(mkexpr(t1), mkexpr(E_byte)); 13974 13975 #else /* _MIPSEB */ 13976 /* Calculate X_byte position. */ 13977 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)), 13978 mkU32(0x0), 13979 mkU32(0x1))); 13980 13981 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)), 13982 mkU32(0x2), 13983 mkU32(0x3))); 13984 13985 store(binop(Iop_Add32, mkexpr(t2), mkU32(3)), mkexpr(H_byte)); 13986 store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte)); 13987 store(binop(Iop_Add32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 13988 store(mkexpr(t1), mkexpr(E_byte)); 13989 13990 #endif 13991 } 13992 break; 13993 13994 case 0x2E: /* SWR */ 13995 DIP("swr r%d, %d(r%d)", rt, imm, rs); 13996 if (mode64) { 13997 IRTemp E_byte = newTemp(Ity_I8); 13998 IRTemp F_byte = newTemp(Ity_I8); 13999 IRTemp G_byte = newTemp(Ity_I8); 14000 IRTemp H_byte = newTemp(Ity_I8); 14001 IRTemp F_pos = newTemp(Ity_I64); 14002 IRTemp G_pos = newTemp(Ity_I64); 14003 14004 /* H byte */ 14005 assign(H_byte, getByteFromReg(rt, 0)); 14006 /* G byte */ 14007 assign(G_byte, getByteFromReg(rt, 1)); 14008 /* F byte */ 14009 assign(F_byte, getByteFromReg(rt, 2)); 14010 /* E byte */ 14011 assign(E_byte, getByteFromReg(rt, 3)); 14012 14013 /* t1 = addr */ 14014 t1 = newTemp(Ity_I64); 14015 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 14016 14017 /* t2 = word addr */ 14018 t2 = newTemp(Ity_I64); 14019 assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL))); 14020 14021 /* t3 = addr mod 4 */ 14022 t3 = newTemp(Ity_I64); 14023 assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3))); 14024 14025 #if defined (_MIPSEL) 14026 /* Calculate X_byte position. */ 14027 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)), 14028 mkU64(0x2), 14029 mkU64(0x3))); 14030 14031 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)), 14032 mkU64(0x0), 14033 mkU64(0x1))); 14034 14035 /* Store X_byte on the right place. */ 14036 store(binop(Iop_Add64, mkexpr(t2), mkU64(0x3)), mkexpr(E_byte)); 14037 store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte)); 14038 store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte)); 14039 store(mkexpr(t1), mkexpr(H_byte)); 14040 14041 #else /* _MIPSEB */ 14042 /* Calculate X_byte position. */ 14043 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)), 14044 mkU64(0x1), 14045 mkU64(0x0))); 14046 14047 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)), 14048 mkU64(0x0), 14049 mkU64(0x1))); 14050 14051 /* Store X_byte on the right place. */ 14052 store(mkexpr(t2), mkexpr(E_byte)); 14053 store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte)); 14054 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte)); 14055 store(mkexpr(t1), mkexpr(H_byte)); 14056 #endif 14057 } else { 14058 IRTemp E_byte = newTemp(Ity_I8); 14059 IRTemp F_byte = newTemp(Ity_I8); 14060 IRTemp G_byte = newTemp(Ity_I8); 14061 IRTemp H_byte = newTemp(Ity_I8); 14062 IRTemp F_pos = newTemp(Ity_I32); 14063 IRTemp G_pos = newTemp(Ity_I32); 14064 14065 /* H byte */ 14066 assign(H_byte, getByteFromReg(rt, 0)); 14067 /* G byte */ 14068 assign(G_byte, getByteFromReg(rt, 1)); 14069 /* F byte */ 14070 assign(F_byte, getByteFromReg(rt, 2)); 14071 /* E byte */ 14072 assign(E_byte, getByteFromReg(rt, 3)); 14073 14074 /* t1 = addr */ 14075 t1 = newTemp(Ity_I32); 14076 assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm)))); 14077 14078 /* t2 = word addr */ 14079 t2 = newTemp(Ity_I32); 14080 assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL))); 14081 14082 /* t3 = addr mod 4 */ 14083 t3 = newTemp(Ity_I32); 14084 assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3))); 14085 14086 #if defined (_MIPSEL) 14087 /* Calculate X_byte position. */ 14088 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)), 14089 mkU32(0x2), 14090 mkU32(0x3))); 14091 14092 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)), 14093 mkU32(0x0), 14094 mkU32(0x1))); 14095 14096 /* Store X_byte on the right place. */ 14097 store(binop(Iop_Add32, mkexpr(t2), mkU32(0x3)), mkexpr(E_byte)); 14098 store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte)); 14099 store(binop(Iop_Add32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte)); 14100 store(mkexpr(t1), mkexpr(H_byte)); 14101 14102 #else /* _MIPSEB */ 14103 /* Calculate X_byte position. */ 14104 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)), 14105 mkU32(0x1), 14106 mkU32(0x0))); 14107 14108 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)), 14109 mkU32(0x0), 14110 mkU32(0x1))); 14111 14112 /* Store X_byte on the right place. */ 14113 store(mkexpr(t2), mkexpr(E_byte)); 14114 store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte)); 14115 store(binop(Iop_Sub32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte)); 14116 store(mkexpr(t1), mkexpr(H_byte)); 14117 #endif 14118 } 14119 break; 14120 14121 case 0x1C: /* Special2 */ 14122 switch (function) { 14123 /* Cavium Specific instructions */ 14124 case 0x03: case 0x32: case 0x33: /* DMUL, CINS , CINS32 */ 14125 case 0x3A: case 0x3B: case 0x2B: /* EXT, EXT32, SNE */ 14126 /* CVM Compare Instructions */ 14127 case 0x2A: case 0x2E: case 0x2F: /* SEQ, SEQI, SNEI */ 14128 if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) { 14129 if (dis_instr_CVM(cins)) 14130 break; 14131 goto decode_failure; 14132 } else { 14133 goto decode_failure; 14134 } 14135 break; 14136 case 0x02: { /* MUL */ 14137 DIP("mul r%d, r%d, r%d", rd, rs, rt); 14138 if (mode64) { 14139 IRTemp tmpRs32 = newTemp(Ity_I32); 14140 IRTemp tmpRt32 = newTemp(Ity_I32); 14141 IRTemp tmpRes = newTemp(Ity_I32); 14142 14143 assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); 14144 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 14145 assign(tmpRes, binop(Iop_Mul32, mkexpr(tmpRs32), mkexpr(tmpRt32))); 14146 putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpRes), True)); 14147 } else 14148 putIReg(rd, binop(Iop_Mul32, getIReg(rs), getIReg(rt))); 14149 break; 14150 } 14151 14152 case 0x00: { /* MADD */ 14153 if (mode64) { 14154 DIP("madd r%d, r%d", rs, rt); 14155 t1 = newTemp(Ity_I32); 14156 t2 = newTemp(Ity_I32); 14157 t3 = newTemp(Ity_I64); 14158 t4 = newTemp(Ity_I64); 14159 t5 = newTemp(Ity_I64); 14160 t6 = newTemp(Ity_I32); 14161 14162 assign(t1, mkNarrowTo32(ty, getHI())); 14163 assign(t2, mkNarrowTo32(ty, getLO())); 14164 14165 assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)), 14166 mkNarrowTo32(ty, getIReg(rt)))); 14167 14168 assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2))); 14169 assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4))); 14170 14171 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True)); 14172 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True)); 14173 } else { 14174 if ( (1 <= ac) && ( 3 >= ac) ) { 14175 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 14176 /* If DSP is present -> DSP ASE MADD */ 14177 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 14178 if (0 != retVal ) { 14179 goto decode_failure_dsp; 14180 } 14181 break; 14182 } else { 14183 goto decode_failure_dsp; 14184 } 14185 } else { 14186 DIP("madd r%d, r%d", rs, rt); 14187 t1 = newTemp(Ity_I32); 14188 t2 = newTemp(Ity_I32); 14189 t3 = newTemp(Ity_I64); 14190 t4 = newTemp(Ity_I32); 14191 t5 = newTemp(Ity_I32); 14192 t6 = newTemp(Ity_I32); 14193 14194 assign(t1, getHI()); 14195 assign(t2, getLO()); 14196 14197 assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt))); 14198 14199 assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32, 14200 mkexpr(t3)))); 14201 14202 assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4), 14203 unop(Iop_64to32, mkexpr(t3))))); 14204 assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1))); 14205 14206 putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32, 14207 mkexpr(t3)))); 14208 putLO(mkexpr(t4)); 14209 break; 14210 } 14211 } 14212 break; 14213 } 14214 14215 case 0x01: { /* MADDU */ 14216 if (mode64) { 14217 DIP("maddu r%d, r%d", rs, rt); 14218 t1 = newTemp(Ity_I32); 14219 t2 = newTemp(Ity_I32); 14220 t3 = newTemp(Ity_I64); 14221 t4 = newTemp(Ity_I64); 14222 t5 = newTemp(Ity_I64); 14223 t6 = newTemp(Ity_I32); 14224 14225 assign(t1, mkNarrowTo32(ty, getHI())); 14226 assign(t2, mkNarrowTo32(ty, getLO())); 14227 14228 assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)), 14229 mkNarrowTo32(ty, getIReg(rt)))); 14230 14231 assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2))); 14232 assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4))); 14233 14234 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True)); 14235 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True)); 14236 } else { 14237 if ( (1 <= ac) && ( 3 >= ac) ) { 14238 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 14239 /* If DSP is present -> DSP ASE MADDU */ 14240 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 14241 if (0 != retVal ) { 14242 goto decode_failure_dsp; 14243 } 14244 break; 14245 } else { 14246 goto decode_failure_dsp; 14247 } 14248 } else { 14249 DIP("maddu r%d, r%d", rs, rt); 14250 t1 = newTemp(Ity_I32); 14251 t2 = newTemp(Ity_I32); 14252 t3 = newTemp(Ity_I64); 14253 t4 = newTemp(Ity_I32); 14254 t5 = newTemp(Ity_I32); 14255 t6 = newTemp(Ity_I32); 14256 14257 assign(t1, getHI()); 14258 assign(t2, getLO()); 14259 14260 assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt))); 14261 14262 assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32, 14263 mkexpr(t3)))); 14264 assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4), 14265 unop(Iop_64to32, mkexpr(t3))))); 14266 assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1))); 14267 14268 putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32, 14269 mkexpr(t3)))); 14270 putLO(mkexpr(t4)); 14271 break; 14272 } 14273 } 14274 break; 14275 } 14276 14277 case 0x04: { /* MSUB */ 14278 if (mode64) { 14279 DIP("msub r%d, r%d", rs, rt); 14280 t1 = newTemp(Ity_I32); 14281 t2 = newTemp(Ity_I32); 14282 t3 = newTemp(Ity_I64); 14283 t4 = newTemp(Ity_I64); 14284 t5 = newTemp(Ity_I64); 14285 t6 = newTemp(Ity_I32); 14286 14287 assign(t1, mkNarrowTo32(ty, getHI())); 14288 assign(t2, mkNarrowTo32(ty, getLO())); 14289 14290 assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)), 14291 mkNarrowTo32(ty, getIReg(rt)))); 14292 14293 assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2))); 14294 assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3))); 14295 14296 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True)); 14297 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True)); 14298 } else { 14299 if ( (1 <= ac) && ( 3 >= ac) ) { 14300 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 14301 /* If DSP is present -> DSP ASE MSUB */ 14302 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 14303 if (0 != retVal ) { 14304 goto decode_failure_dsp; 14305 } 14306 break; 14307 } else { 14308 goto decode_failure_dsp; 14309 } 14310 } else { 14311 DIP("msub r%d, r%d", rs, rt); 14312 t1 = newTemp(Ity_I32); 14313 t2 = newTemp(Ity_I32); 14314 t3 = newTemp(Ity_I64); 14315 t4 = newTemp(Ity_I32); 14316 t5 = newTemp(Ity_I1); 14317 t6 = newTemp(Ity_I32); 14318 14319 assign(t1, getHI()); 14320 assign(t2, getLO()); 14321 14322 assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt))); 14323 assign(t4, unop(Iop_64to32, mkexpr(t3))); /* new lo */ 14324 14325 /* if lo<lo(mul) hi = hi - 1 */ 14326 assign(t5, binop(Iop_CmpLT32U, 14327 mkexpr(t2), 14328 mkexpr(t4))); 14329 14330 assign(t6, IRExpr_ITE(mkexpr(t5), 14331 binop(Iop_Sub32, mkexpr(t1), mkU32(0x1)), 14332 mkexpr(t1))); 14333 14334 putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32, 14335 mkexpr(t3)))); 14336 putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4))); 14337 break; 14338 } 14339 } 14340 break; 14341 } 14342 14343 case 0x05: { /* MSUBU */ 14344 if (mode64) { 14345 DIP("msubu r%d, r%d", rs, rt); 14346 t1 = newTemp(Ity_I32); 14347 t2 = newTemp(Ity_I32); 14348 t3 = newTemp(Ity_I64); 14349 t4 = newTemp(Ity_I64); 14350 t5 = newTemp(Ity_I64); 14351 t6 = newTemp(Ity_I32); 14352 14353 assign(t1, mkNarrowTo32(ty, getHI())); 14354 assign(t2, mkNarrowTo32(ty, getLO())); 14355 14356 assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)), 14357 mkNarrowTo32(ty, getIReg(rt)))); 14358 14359 assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2))); 14360 assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3))); 14361 14362 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True)); 14363 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True)); 14364 } else { 14365 if ( (1 <= ac) && ( 3 >= ac) ) { 14366 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 14367 /* If DSP is present -> DSP ASE MSUBU */ 14368 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 14369 if (0 != retVal ) { 14370 goto decode_failure_dsp; 14371 } 14372 break; 14373 } else { 14374 goto decode_failure_dsp; 14375 } 14376 } else { 14377 DIP("msubu r%d, r%d", rs, rt); 14378 t1 = newTemp(Ity_I32); 14379 t2 = newTemp(Ity_I32); 14380 t3 = newTemp(Ity_I64); 14381 t4 = newTemp(Ity_I32); 14382 t5 = newTemp(Ity_I1); 14383 t6 = newTemp(Ity_I32); 14384 14385 assign(t1, getHI()); 14386 assign(t2, getLO()); 14387 14388 assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt))); 14389 assign(t4, unop(Iop_64to32, mkexpr(t3))); /* new lo */ 14390 14391 /* if lo<lo(mul) hi = hi - 1 */ 14392 assign(t5, binop(Iop_CmpLT32U, 14393 mkexpr(t2), 14394 mkexpr(t4))); 14395 14396 assign(t6, IRExpr_ITE(mkexpr(t5), 14397 binop(Iop_Sub32, 14398 mkexpr(t1), 14399 mkU32(0x1)), 14400 mkexpr(t1))); 14401 14402 putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32, 14403 mkexpr(t3)))); 14404 putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4))); 14405 break; 14406 } 14407 } 14408 break; 14409 } 14410 14411 case 0x6: /* dmul MIPS64 - Netlogic */ 14412 DIP("dmul r%u, r%u, r%u", rd, rs, rt); 14413 t0 = newTemp(Ity_I128); 14414 14415 assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt))); 14416 14417 putIReg(rd, unop(Iop_128to64, mkexpr(t0))); 14418 break; 14419 14420 case 0x10: /* LDADDW - Swap Word - Netlogic */ 14421 DIP("ldaddw r%u, r%u", rt, rs); 14422 t0 = newTemp(Ity_I32); 14423 t1 = newTemp(Ity_I32); 14424 t2 = newTemp(Ity_I32); 14425 t3 = newTemp(Ity_I64); 14426 t4 = newTemp(Ity_I32); 14427 t5 = newTemp(Ity_I32); 14428 t6 = newTemp(Ity_I32); 14429 14430 /* v = GPR[rt] */ 14431 assign(t0, mkNarrowTo32(ty, getIReg(rt))); 14432 14433 /* GPR[rt] = memory[base]; */ 14434 assign(t1, load(Ity_I32, getIReg(rs))); 14435 putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True)); 14436 14437 /* memory[base] = memory[base] + v; */ 14438 store(getIReg(rs), binop(Iop_Add32, mkexpr(t0), mkexpr(t1))); 14439 break; 14440 14441 case 0x12: /* LDADDD - Swap Word - Netlogic */ 14442 DIP("ldaddw r%u, r%u", rt, rs); 14443 t0 = newTemp(Ity_I64); 14444 t1 = newTemp(Ity_I64); 14445 14446 /* v = GPR[rt] */ 14447 assign(t0, getIReg(rt)); 14448 14449 /* GPR[rt] = memory[base]; */ 14450 assign(t1, load(Ity_I64, getIReg(rs))); 14451 putIReg(rt, mkexpr(t1)); 14452 14453 /* memory[base] = memory[base] + v; */ 14454 store(getIReg(rs), binop(Iop_Add64, mkexpr(t0), mkexpr(t1))); 14455 break; 14456 14457 case 0x14: /* SWAPW - Swap Word - Netlogic */ 14458 DIP("swapw r%u, r%u", rt, rs); 14459 t0 = newTemp(Ity_I32); 14460 t1 = newTemp(Ity_I32); 14461 assign(t0, mkNarrowTo32(ty, getIReg(rt))); 14462 assign(t1, load(Ity_I32, getIReg(rs))); 14463 putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True)); 14464 store(getIReg(rs), mkexpr(t0)); 14465 break; 14466 14467 case 0x16: /* SWAPD - Swap Double - Netlogic */ 14468 DIP("swapw r%u, r%u", rt, rs); 14469 t0 = newTemp(Ity_I64); 14470 t1 = newTemp(Ity_I64); 14471 assign(t0, getIReg(rt)); 14472 assign(t1, load(Ity_I64, getIReg(rs))); 14473 putIReg(rt, mkexpr(t1)); 14474 store(getIReg(rs), mkexpr(t0)); 14475 break; 14476 14477 case 0x20: { /* CLZ */ 14478 DIP("clz r%d, r%d", rd, rs); 14479 if (mode64) { 14480 IRTemp tmpClz32 = newTemp(Ity_I32); 14481 IRTemp tmpRs32 = newTemp(Ity_I32); 14482 14483 assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); 14484 assign(tmpClz32, unop(Iop_Clz32, mkexpr(tmpRs32))); 14485 putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClz32), True)); 14486 } else { 14487 t1 = newTemp(Ity_I1); 14488 assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0))); 14489 putIReg(rd, IRExpr_ITE(mkexpr(t1), 14490 mkU32(0x00000020), 14491 unop(Iop_Clz32, getIReg(rs)))); 14492 } 14493 break; 14494 } 14495 14496 case 0x21: { /* CLO */ 14497 DIP("clo r%d, r%d", rd, rs); 14498 if (mode64) { 14499 IRTemp tmpClo32 = newTemp(Ity_I32); 14500 IRTemp tmpRs32 = newTemp(Ity_I32); 14501 assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); 14502 14503 t1 = newTemp(Ity_I1); 14504 assign(t1, binop(Iop_CmpEQ32, mkexpr(tmpRs32), mkU32(0xffffffff))); 14505 assign(tmpClo32, IRExpr_ITE(mkexpr(t1), 14506 mkU32(0x00000020), 14507 unop(Iop_Clz32, unop(Iop_Not32, mkexpr(tmpRs32))))); 14508 14509 putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClo32), True)); 14510 break; 14511 } else { 14512 t1 = newTemp(Ity_I1); 14513 assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0xffffffff))); 14514 putIReg(rd, IRExpr_ITE(mkexpr(t1), 14515 mkU32(0x00000020), 14516 unop(Iop_Clz32, 14517 unop(Iop_Not32, getIReg(rs))))); 14518 break; 14519 } 14520 } 14521 14522 case 0x24: /* Count Leading Zeros in Doubleword - DCLZ; MIPS64 */ 14523 DIP("dclz r%d, r%d", rd, rs); 14524 t1 = newTemp(Ity_I1); 14525 assign(t1, binop(Iop_CmpEQ64, getIReg(rs), mkU64(0))); 14526 putIReg(rd, IRExpr_ITE(mkexpr(t1), 14527 mkU64(0x00000040), 14528 unop(Iop_Clz64, getIReg(rs)))); 14529 break; 14530 14531 case 0x25: /* Count Leading Ones in Doubleword - DCLO; MIPS64 */ 14532 DIP("dclo r%d, r%d", rd, rs); 14533 t1 = newTemp(Ity_I1); 14534 assign(t1, binop(Iop_CmpEQ64, getIReg(rs), 14535 mkU64(0xffffffffffffffffULL))); 14536 putIReg(rd, IRExpr_ITE(mkexpr(t1), 14537 mkU64(0x40), 14538 unop(Iop_Clz64, unop(Iop_Not64, 14539 getIReg(rs))))); 14540 break; 14541 14542 default: 14543 goto decode_failure; 14544 } 14545 break; 14546 14547 case 0x1F: /* Special3 */ 14548 switch (function) { 14549 case 0x01: { 14550 /* Doubleword Extract Bit Field - DEXTM; MIPS64r2 */ 14551 msb = get_msb(cins); 14552 lsb = get_lsb(cins); 14553 size = msb + 1; 14554 UInt srcPos = lsb; 14555 UInt dstSz = msb + 33; 14556 t1 = newTemp(Ity_I64); 14557 DIP("dextm r%u, r%u, %d, %d", rt, rs, lsb, msb + 1); 14558 14559 UChar lsAmt = 64 - (srcPos + dstSz); /* left shift amount; */ 14560 UChar rsAmt = 64 - dstSz; /* right shift amount; */ 14561 14562 assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt))); 14563 putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt))); 14564 14565 break; 14566 } 14567 case 0x02: { 14568 /* Doubleword Extract Bit Field Upper - DEXTU; MIPS64r2 */ 14569 msb = get_msb(cins); 14570 lsb = get_lsb(cins); 14571 size = msb + 1; 14572 UInt srcPos = lsb + 32; 14573 UInt dstSz = msb + 1; 14574 DIP("dextu r%u, r%u, %d, %d", rt, rs, srcPos, dstSz); 14575 t1 = newTemp(Ity_I64); 14576 14577 vassert(srcPos >= 32 && srcPos < 64); 14578 vassert(dstSz > 0 && dstSz <= 32); 14579 vassert((srcPos + dstSz) > 32 && (srcPos + dstSz) <= 64); 14580 14581 UChar lsAmt = 64 - (srcPos + dstSz); /* left shift amount; */ 14582 UChar rsAmt = 64 - dstSz; /* right shift amount; */ 14583 14584 assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt))); 14585 putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt))); 14586 break; 14587 } 14588 case 0x05: { 14589 /* Doubleword Insert Bit Field Middle - DINSM; MIPS64r2 */ 14590 msb = get_msb(cins); 14591 lsb = get_lsb(cins); 14592 size = msb + 1; 14593 UInt dstPos = lsb; 14594 UInt srcSz = msb - lsb + 33; 14595 t1 = newTemp(ty); 14596 t2 = newTemp(ty); 14597 t3 = newTemp(ty); 14598 t4 = newTemp(ty); 14599 IRTemp tmpT1 = newTemp(ty); 14600 IRTemp tmpT2 = newTemp(ty); 14601 IRTemp tmpT3 = newTemp(ty); 14602 IRTemp tmpT4 = newTemp(ty); 14603 IRTemp tmpT5 = newTemp(ty); 14604 IRTemp tmpT6 = newTemp(ty); 14605 IRTemp tmpT7 = newTemp(ty); 14606 IRTemp tmpRs = newTemp(ty); 14607 IRTemp tmpRt = newTemp(ty); 14608 IRTemp tmpRd = newTemp(ty); 14609 14610 assign(tmpRs, getIReg(rs)); 14611 assign(tmpRt, getIReg(rt)); 14612 DIP("dinsm r%u, r%u, %d, %d", rt, rs, lsb, msb); 14613 14614 UChar lsAmt = dstPos + srcSz - 1; /* left shift amount; */ 14615 UChar rsAmt = dstPos + srcSz - 1; /* right shift amount; */ 14616 14617 assign(t1, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt))); 14618 assign(tmpT1, binop(Iop_Shr64, mkexpr(t1), mkU8(1))); 14619 assign(t2, binop(Iop_Shl64, mkexpr(tmpT1), mkU8(lsAmt))); 14620 assign(tmpT2, binop(Iop_Shl64, mkexpr(t2), mkU8(1))); 14621 14622 lsAmt = 63 - dstPos; /* left shift amount; */ 14623 rsAmt = 63 - dstPos; /* right shift amount; */ 14624 14625 assign(t3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt))); 14626 assign(tmpT3, binop(Iop_Shl64, mkexpr(t3), mkU8(1))); 14627 assign(t4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt))); 14628 assign(tmpT4, binop(Iop_Shr64, mkexpr(t4), mkU8(1))); 14629 14630 /* extract size from src register */ 14631 lsAmt = 64 - srcSz; /* left shift amount; */ 14632 rsAmt = 64 - (lsb + srcSz); /* right shift amount; */ 14633 14634 assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt))); 14635 assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(rsAmt))); 14636 14637 assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT4))); 14638 assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT7))); 14639 putIReg(rt, mkexpr(tmpRd)); 14640 break; 14641 } 14642 case 0x06: { 14643 /* Doubleword Insert Bit Field Upper - DINSU; MIPS64r2 */ 14644 msb = get_msb(cins); 14645 lsb = get_lsb(cins); 14646 size = msb + 1; 14647 UInt dstPos = lsb + 32; 14648 UInt srcSz = msb - lsb + 1; 14649 IRTemp tmpT1 = newTemp(ty); 14650 IRTemp tmpT2 = newTemp(ty); 14651 IRTemp tmpT3 = newTemp(ty); 14652 IRTemp tmpT4 = newTemp(ty); 14653 IRTemp tmpT5 = newTemp(ty); 14654 IRTemp tmpT6 = newTemp(ty); 14655 IRTemp tmpT7 = newTemp(ty); 14656 IRTemp tmpT8 = newTemp(ty); 14657 IRTemp tmpT9 = newTemp(ty); 14658 IRTemp tmpRs = newTemp(ty); 14659 IRTemp tmpRt = newTemp(ty); 14660 IRTemp tmpRd = newTemp(ty); 14661 14662 assign(tmpRs, getIReg(rs)); 14663 assign(tmpRt, getIReg(rt)); 14664 DIP("dinsu r%u, r%u, %d, %d", rt, rs, lsb, msb); 14665 14666 UChar lsAmt = 64 - srcSz; /* left shift amount; */ 14667 UChar rsAmt = 64 - (dstPos + srcSz); /* right shift amount; */ 14668 assign(tmpT1, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt))); 14669 assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt))); 14670 14671 lsAmt = 64 - dstPos; /* left shift amount; */ 14672 rsAmt = 64 - dstPos; /* right shift amount; */ 14673 assign(tmpT3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt))); 14674 assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt))); 14675 14676 lsAmt = dstPos; /* left shift amount; */ 14677 rsAmt = srcSz; /* right shift amount; */ 14678 assign(tmpT5, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt))); 14679 assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(lsAmt))); 14680 14681 assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpT6), mkU8(rsAmt))); 14682 assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(lsAmt))); 14683 14684 assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT4))); 14685 assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT9))); 14686 putIReg(rt, mkexpr(tmpRd)); 14687 break; 14688 } 14689 case 0x07: { 14690 /* Doubleword Insert Bit Field - DINS; MIPS64r2 */ 14691 IRTemp tmp1 = newTemp(ty); 14692 IRTemp tmpT1 = newTemp(ty); 14693 IRTemp tmpT2 = newTemp(ty); 14694 IRTemp tmpT3 = newTemp(ty); 14695 IRTemp tmpT4 = newTemp(ty); 14696 IRTemp tmpT5 = newTemp(ty); 14697 IRTemp tmpT6 = newTemp(ty); 14698 IRTemp tmpT7 = newTemp(ty); 14699 IRTemp tmpT8 = newTemp(ty); 14700 IRTemp tmpT9 = newTemp(ty); 14701 IRTemp tmp = newTemp(ty); 14702 IRTemp tmpRs = newTemp(ty); 14703 IRTemp tmpRt = newTemp(ty); 14704 IRTemp tmpRd = newTemp(ty); 14705 14706 assign(tmpRs, getIReg(rs)); 14707 assign(tmpRt, getIReg(rt)); 14708 14709 msb = get_msb(cins); 14710 lsb = get_lsb(cins); 14711 size = msb + 1; 14712 DIP("dins r%u, r%u, %d, %d", rt, rs, lsb, 14713 msb - lsb + 1); 14714 UChar lsAmt = 63 - lsb; /* left shift amount; */ 14715 UChar rsAmt = 63 - lsb; /* right shift amount; */ 14716 assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt))); 14717 assign(tmpT1, binop(Iop_Shl64, mkexpr(tmp), mkU8(1))); 14718 assign(tmp1, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt))); 14719 assign(tmpT2, binop(Iop_Shr64, mkexpr(tmp1), mkU8(1))); 14720 14721 lsAmt = msb; /* left shift amount; */ 14722 rsAmt = 1; /*right shift amount; */ 14723 assign(tmpT3, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt))); 14724 assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(lsAmt))); 14725 assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpT4), mkU8(rsAmt))); 14726 assign(tmpT6, binop(Iop_Shl64, mkexpr(tmpT5), mkU8(lsAmt))); 14727 14728 lsAmt = 64 - (msb - lsb + 1); /* left shift amount; */ 14729 rsAmt = 64 - (msb + 1); /* right shift amount; */ 14730 assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt))); 14731 assign(tmpT8, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(rsAmt))); 14732 14733 assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT8))); 14734 assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT9))); 14735 putIReg(rt, mkexpr(tmpRd)); 14736 break; 14737 } 14738 case 0x24: /* DBSHFL */ 14739 lsb = get_lsb(cins); 14740 IRTemp tmpRs = newTemp(ty); 14741 IRTemp tmpRt = newTemp(ty); 14742 IRTemp tmpRd = newTemp(ty); 14743 assign(tmpRs, getIReg(rs)); 14744 assign(tmpRt, getIReg(rt)); 14745 switch (lsb) { 14746 case 0x02: { /* DSBH */ 14747 DIP("dsbh r%u, r%u", rd, rt); 14748 IRTemp tmpT1 = newTemp(ty); 14749 IRTemp tmpT2 = newTemp(ty); 14750 IRTemp tmpT3 = newTemp(ty); 14751 IRTemp tmpT4 = newTemp(ty); 14752 IRTemp tmpT5 = newTemp(Ity_I64); 14753 IRTemp tmpT6 = newTemp(ty); 14754 assign(tmpT5, mkU64(0xFF00FF00FF00FF00ULL)); 14755 assign(tmpT6, mkU64(0x00FF00FF00FF00FFULL)); 14756 assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5))); 14757 assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(8))); 14758 assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6))); 14759 assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(8))); 14760 assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2))); 14761 putIReg(rd, mkexpr(tmpRd)); 14762 break; 14763 } 14764 case 0x05: { /* DSHD */ 14765 DIP("dshd r%u, r%u\n", rd, rt); 14766 IRTemp tmpT1 = newTemp(ty); 14767 IRTemp tmpT2 = newTemp(ty); 14768 IRTemp tmpT3 = newTemp(ty); 14769 IRTemp tmpT4 = newTemp(ty); 14770 IRTemp tmpT5 = newTemp(Ity_I64); 14771 IRTemp tmpT6 = newTemp(ty); 14772 IRTemp tmpT7 = newTemp(ty); 14773 IRTemp tmpT8 = newTemp(ty); 14774 IRTemp tmpT9 = newTemp(ty); 14775 assign(tmpT5, mkU64(0xFFFF0000FFFF0000ULL)); 14776 assign(tmpT6, mkU64(0x0000FFFF0000FFFFULL)); 14777 assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5))); 14778 assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(16))); 14779 assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6))); 14780 assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(16))); 14781 assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2))); 14782 assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(32))); 14783 assign(tmpT9, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(32))); 14784 assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT9))); 14785 putIReg(rd, mkexpr(tmpRd)); 14786 break; 14787 } 14788 default: 14789 vex_printf("\nop6o10 = %d", lsb); 14790 goto decode_failure;; 14791 } 14792 break; 14793 case 0x3B: { /* RDHWR */ 14794 DIP("rdhwr r%d, r%d", rt, rd); 14795 if (rd == 29) { 14796 putIReg(rt, getULR()); 14797 #if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2)) 14798 } else if (rd == 1) { 14799 if (mode64) { 14800 IRTemp val = newTemp(Ity_I64); 14801 IRExpr** args = mkIRExprVec_2 (mkU64(rt), mkU64(rd)); 14802 IRDirty *d = unsafeIRDirty_1_N(val, 14803 0, 14804 "mips64_dirtyhelper_rdhwr", 14805 &mips64_dirtyhelper_rdhwr, 14806 args); 14807 stmt(IRStmt_Dirty(d)); 14808 putIReg(rt, mkexpr(val)); 14809 } else { 14810 IRTemp val = newTemp(Ity_I32); 14811 IRExpr** args = mkIRExprVec_2 (mkU32(rt), mkU32(rd)); 14812 IRDirty *d = unsafeIRDirty_1_N(val, 14813 0, 14814 "mips32_dirtyhelper_rdhwr", 14815 &mips32_dirtyhelper_rdhwr, 14816 args); 14817 stmt(IRStmt_Dirty(d)); 14818 putIReg(rt, mkexpr(val)); 14819 } 14820 #endif 14821 } else 14822 goto decode_failure; 14823 break; 14824 } 14825 case 0x04: /* INS */ 14826 msb = get_msb(cins); 14827 lsb = get_lsb(cins); 14828 size = msb - lsb + 1; 14829 DIP("ins size:%d msb:%d lsb:%d", size, msb, lsb); 14830 14831 vassert(lsb + size <= 32); 14832 vassert(lsb + size > 0); 14833 14834 /* put size bits from rs at the pos in temporary */ 14835 t0 = newTemp(Ity_I32); 14836 t3 = newTemp(Ity_I32); 14837 /* shift left for 32 - size to clear leading bits and get zeros 14838 at the end */ 14839 assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)), 14840 mkU8(32 - size))); 14841 /* now set it at pos */ 14842 t1 = newTemp(Ity_I32); 14843 assign(t1, binop(Iop_Shr32, mkexpr(t0), mkU8(32 - size - lsb))); 14844 14845 if (lsb > 0) { 14846 t2 = newTemp(Ity_I32); 14847 /* clear everything but lower pos bits from rt */ 14848 assign(t2, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rt)), 14849 mkU8(32 - lsb))); 14850 assign(t3, binop(Iop_Shr32, mkexpr(t2), mkU8(32 - lsb))); 14851 } else 14852 assign(t3, mkU32(0)); 14853 14854 if (msb < 31) { 14855 t4 = newTemp(Ity_I32); 14856 /* clear everything but upper msb + 1 bits from rt */ 14857 assign(t4, binop(Iop_Shr32, mkNarrowTo32(ty, getIReg(rt)), 14858 mkU8(msb + 1))); 14859 t5 = newTemp(Ity_I32); 14860 assign(t5, binop(Iop_Shl32, mkexpr(t4), mkU8(msb + 1))); 14861 14862 /* now combine these registers */ 14863 if (lsb > 0) { 14864 t6 = newTemp(Ity_I32); 14865 assign(t6, binop(Iop_Or32, mkexpr(t5), mkexpr(t1))); 14866 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t6), 14867 mkexpr(t3)), True)); 14868 } else { 14869 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1), 14870 mkexpr(t5)), True)); 14871 } 14872 } else { 14873 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1), 14874 mkexpr(t3)), True)); 14875 } 14876 break; 14877 14878 case 0x00: /* EXT */ 14879 msb = get_msb(cins); 14880 lsb = get_lsb(cins); 14881 size = msb + 1; 14882 DIP("ext size:%d msb:%d lsb:%d", size, msb, lsb); 14883 vassert(lsb + size <= 32); 14884 vassert(lsb + size > 0); 14885 /* put size bits from rs at the top of in temporary */ 14886 if (lsb + size < 32) { 14887 t0 = newTemp(Ity_I32); 14888 assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)), 14889 mkU8(32 - lsb - size))); 14890 14891 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32, mkexpr(t0), 14892 mkU8(32 - size)), True)); 14893 } else { 14894 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32, 14895 mkNarrowTo32(ty, getIReg(rs)), 14896 mkU8(32 - size)), True)); 14897 } 14898 break; 14899 14900 case 0x03: /* Doubleword Extract Bit Field - DEXT; MIPS64r2 */ 14901 msb = get_msb(cins); 14902 lsb = get_lsb(cins); 14903 size = msb + 1; 14904 DIP("dext r%u, r%u, %d, %d", rt, rs, lsb, msb + 1); 14905 t1 = newTemp(Ity_I64); 14906 vassert(lsb >= 0 && lsb < 32); 14907 vassert(size > 0 && size <= 32); 14908 vassert((lsb + size) > 0 && (lsb + size) <= 63); 14909 14910 UChar lsAmt = 63 - (lsb + msb); /* left shift amount; */ 14911 UChar rsAmt = 63 - msb; /* right shift amount; */ 14912 14913 assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt))); 14914 putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt))); 14915 14916 break; 14917 14918 case 0x20: /* BSHFL */ 14919 switch (sa) { 14920 case 0x02: /* WSBH */ 14921 DIP("wsbh r%d, r%d", rd, rt); 14922 t0 = newTemp(Ity_I32); 14923 t1 = newTemp(Ity_I32); 14924 t2 = newTemp(Ity_I32); 14925 t3 = newTemp(Ity_I32); 14926 assign(t0, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty, 14927 getIReg(rt)), mkU32(0x00FF0000)), 14928 mkU8(0x8))); 14929 assign(t1, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty, 14930 getIReg(rt)), mkU32(0xFF000000)), mkU8(0x8))); 14931 assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty, 14932 getIReg(rt)), mkU32(0x000000FF)), mkU8(0x8))); 14933 assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty, 14934 getIReg(rt)), mkU32(0x0000FF00)), mkU8(0x8))); 14935 putIReg(rd, mkWidenFrom32(ty, binop(Iop_Or32, binop(Iop_Or32, 14936 mkexpr(t0), mkexpr(t1)), 14937 binop(Iop_Or32, mkexpr(t2), 14938 mkexpr(t3))), True)); 14939 break; 14940 14941 case 0x10: /* SEB */ 14942 DIP("seb r%d, r%d", rd, rt); 14943 if (mode64) 14944 putIReg(rd, unop(Iop_8Sto64, unop(Iop_64to8, getIReg(rt)))); 14945 else 14946 putIReg(rd, unop(Iop_8Sto32, unop(Iop_32to8, getIReg(rt)))); 14947 break; 14948 14949 case 0x18: /* SEH */ 14950 DIP("seh r%d, r%d", rd, rt); 14951 if (mode64) 14952 putIReg(rd, unop(Iop_16Sto64, unop(Iop_64to16, getIReg(rt)))); 14953 else 14954 putIReg(rd, unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt)))); 14955 break; 14956 14957 default: 14958 goto decode_failure; 14959 14960 } 14961 break; /* BSHFL */ 14962 14963 /* --- MIPS32(r2) DSP ASE(r2) / Cavium Specfic (LX) instructions --- */ 14964 case 0xA: /* LX */ 14965 if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) { 14966 if (dis_instr_CVM(cins)) 14967 break; 14968 goto decode_failure; 14969 } 14970 case 0xC: /* INSV */ 14971 case 0x38: { /* EXTR.W */ 14972 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 14973 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 14974 if (0 != retVal ) { 14975 goto decode_failure_dsp; 14976 } 14977 break; 14978 } else { 14979 goto decode_failure_dsp; 14980 } 14981 break; 14982 } 14983 case 0x10: { /* ADDU.QB */ 14984 switch(sa) { 14985 case 0xC: /* SUBU_S.PH */ 14986 case 0xD: /* ADDU_S.PH */ 14987 case 0x1E: { /* MULQ_S.PH */ 14988 if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) { 14989 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 14990 if (0 != retVal ) { 14991 goto decode_failure_dsp; 14992 } 14993 break; 14994 } else { 14995 goto decode_failure_dsp; 14996 } 14997 break; 14998 } 14999 default: { 15000 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15001 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15002 if (0 != retVal ) { 15003 goto decode_failure_dsp; 15004 } 15005 break; 15006 } else { 15007 goto decode_failure_dsp; 15008 } 15009 break; 15010 } 15011 } 15012 break; 15013 } 15014 case 0x11: { /* CMPU.EQ.QB */ 15015 switch(sa) { 15016 case 0x18: /* CMPGDU.EQ.QB */ 15017 case 0x19: /* CMPGDU.LT.QB */ 15018 case 0x1A: /* CMPGDU.LE.QB */ 15019 case 0x0D: /* PRECR.QB.PH */ 15020 case 0x1E: /* PRECR_SRA.PH.W */ 15021 case 0x1F: { /* PRECR_SRA_R.PH.W */ 15022 if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) { 15023 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15024 if (0 != retVal ) { 15025 goto decode_failure_dsp; 15026 } 15027 break; 15028 } else { 15029 goto decode_failure_dsp; 15030 } 15031 break; 15032 } 15033 default: { 15034 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15035 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15036 if (0 != retVal ) { 15037 goto decode_failure_dsp; 15038 } 15039 break; 15040 } else { 15041 goto decode_failure_dsp; 15042 } 15043 break; 15044 } 15045 } 15046 break; 15047 } 15048 case 0x12: { /* ABSQ_S.PH */ 15049 switch(sa){ 15050 case 0x1: { /* ABSQ_S.QB */ 15051 if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) { 15052 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15053 if (0 != retVal ) { 15054 goto decode_failure_dsp; 15055 } 15056 break; 15057 } else { 15058 goto decode_failure_dsp; 15059 } 15060 break; 15061 } 15062 default: { 15063 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15064 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15065 if (0 != retVal ) { 15066 goto decode_failure_dsp; 15067 } 15068 break; 15069 } else { 15070 goto decode_failure_dsp; 15071 } 15072 break; 15073 } 15074 } 15075 break; 15076 } 15077 case 0x13: { /* SHLL.QB */ 15078 switch(sa) { 15079 case 0x04: /* SHRA.QB */ 15080 case 0x05: /* SHRA_R.QB */ 15081 case 0x06: /* SHRAV.QB */ 15082 case 0x07: /* SHRAV_R.QB */ 15083 case 0x19: /* SHLR.PH */ 15084 case 0x1B: { /* SHLRV.PH */ 15085 if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) { 15086 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15087 if (0 != retVal ) { 15088 goto decode_failure_dsp; 15089 } 15090 break; 15091 } else { 15092 goto decode_failure_dsp; 15093 } 15094 break; 15095 } 15096 default: { 15097 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15098 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15099 if (0 != retVal ) { 15100 goto decode_failure_dsp; 15101 } 15102 break; 15103 } else { 15104 goto decode_failure_dsp; 15105 } 15106 break; 15107 } 15108 } 15109 break; 15110 } 15111 case 0x30: { /* DPAQ.W.PH */ 15112 switch(sa) { 15113 case 0x0: /* DPA.W.PH */ 15114 case 0x18: /* DPAQX_S.W.PH */ 15115 case 0x1A: /* DPAQX_SA.W.PH */ 15116 case 0x8: /* DPAX.W.PH */ 15117 case 0x1: /* DPS.W.PH */ 15118 case 0x19: /* DPSQX_S.W.PH */ 15119 case 0x1B: /* DPSQX_SA.W.PH */ 15120 case 0x9: /* DPSX.W.PH */ 15121 case 0x2: { /* MULSA.W.PH */ 15122 if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) { 15123 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15124 if (0 != retVal ) { 15125 goto decode_failure_dsp; 15126 } 15127 break; 15128 } else { 15129 goto decode_failure_dsp; 15130 } 15131 break; 15132 } 15133 default: { 15134 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15135 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15136 if (0 != retVal ) { 15137 goto decode_failure_dsp; 15138 } 15139 break; 15140 } else { 15141 goto decode_failure_dsp; 15142 } 15143 break; 15144 } 15145 } 15146 break; 15147 } 15148 case 0x18: /* ADDUH.QB/MUL.PH */ 15149 case 0x31: { /* APPEND */ 15150 if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) { 15151 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15152 if (0 != retVal ) { 15153 goto decode_failure_dsp; 15154 } 15155 break; 15156 } else { 15157 goto decode_failure_dsp; 15158 } 15159 } 15160 default: 15161 goto decode_failure; 15162 15163 } 15164 break; /* Special3 */ 15165 15166 case 0x3B: 15167 if (0x3B == function && 15168 (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_BROADCOM)) { 15169 /*RDHWR*/ 15170 DIP("rdhwr r%d, r%d", rt, rd); 15171 if (rd == 29) { 15172 putIReg(rt, getULR()); 15173 } else 15174 goto decode_failure; 15175 break; 15176 } else { 15177 goto decode_failure; 15178 } 15179 15180 case 0x00: /* Special */ 15181 15182 switch (function) { 15183 case 0x1: { 15184 UInt mov_cc = get_mov_cc(cins); 15185 if (tf == 0) { /* MOVF */ 15186 DIP("movf r%d, r%d, %d", rd, rs, mov_cc); 15187 t1 = newTemp(Ity_I1); 15188 t2 = newTemp(Ity_I32); 15189 t3 = newTemp(Ity_I1); 15190 15191 assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc))); 15192 assign(t2, IRExpr_ITE(mkexpr(t1), 15193 binop(Iop_And32, 15194 binop(Iop_Shr32, getFCSR(), 15195 mkU8(23)), 15196 mkU32(0x1)), 15197 binop(Iop_And32, 15198 binop(Iop_Shr32, getFCSR(), 15199 mkU8(24 + mov_cc)), 15200 mkU32(0x1)) 15201 )); 15202 assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2))); 15203 putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd))); 15204 } else if (tf == 1) { /* MOVT */ 15205 DIP("movt r%d, r%d, %d", rd, rs, mov_cc); 15206 t1 = newTemp(Ity_I1); 15207 t2 = newTemp(Ity_I32); 15208 t3 = newTemp(Ity_I1); 15209 15210 assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc))); 15211 assign(t2, IRExpr_ITE(mkexpr(t1), 15212 binop(Iop_And32, 15213 binop(Iop_Shr32, getFCSR(), 15214 mkU8(23)), 15215 mkU32(0x1)), 15216 binop(Iop_And32, 15217 binop(Iop_Shr32, getFCSR(), 15218 mkU8(24 + mov_cc)), 15219 mkU32(0x1)) 15220 )); 15221 assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2))); 15222 putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd))); 15223 } 15224 break; 15225 } 15226 case 0x0A: { /* MOVZ */ 15227 DIP("movz r%d, r%d, r%d", rd, rs, rt); 15228 t1 = newTemp(ty); 15229 t2 = newTemp(ty); 15230 if (mode64) { 15231 assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64, 15232 getIReg(rt), mkU64(0x0))))); 15233 assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64, 15234 getIReg(rt), mkU64(0x0))))); 15235 putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs), 15236 mkexpr(t1)), binop(Iop_And64, getIReg(rd),mkexpr(t2)))); 15237 } else { 15238 assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt), 15239 mkU32(0x0)))); 15240 assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt), 15241 mkU32(0x0)))); 15242 putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs), 15243 mkexpr(t1)), binop(Iop_And32, getIReg(rd), 15244 mkexpr(t2)))); 15245 } 15246 break; 15247 } 15248 15249 case 0x0B: { /* MOVN */ 15250 DIP("movn r%d, r%d, r%d", rd, rs, rt); 15251 t1 = newTemp(ty); 15252 t2 = newTemp(ty); 15253 if (mode64) { 15254 assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64, 15255 getIReg(rt), mkU64(0x0))))); 15256 assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64, 15257 getIReg(rt), mkU64(0x0))))); 15258 putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs), 15259 mkexpr(t2)), binop(Iop_And64, getIReg(rd), 15260 mkexpr(t1)))); 15261 } else { 15262 assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt), 15263 mkU32(0x0)))); 15264 assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt), 15265 mkU32(0x0)))); 15266 putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs), 15267 mkexpr(t2)), binop(Iop_And32, getIReg(rd), 15268 mkexpr(t1)))); 15269 } 15270 break; 15271 } 15272 15273 case 0x18: { /* MULT */ 15274 if ( (1 <= ac) && ( 3 >= ac) ) { 15275 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15276 /* If DSP is present -> DSP ASE MULT */ 15277 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15278 if (0 != retVal ) { 15279 goto decode_failure_dsp; 15280 } 15281 break; 15282 } else { 15283 goto decode_failure_dsp; 15284 } 15285 } else { 15286 DIP("mult r%d, r%d", rs, rt); 15287 t2 = newTemp(Ity_I64); 15288 15289 assign(t2, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)), 15290 mkNarrowTo32(ty, getIReg(rt)))); 15291 15292 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True)); 15293 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True)); 15294 break; 15295 } 15296 } 15297 case 0x19: { /* MULTU */ 15298 if ( (1 <= ac) && ( 3 >= ac) ) { 15299 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15300 /* If DSP is present -> DSP ASE MULTU */ 15301 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15302 if (0 != retVal ) { 15303 goto decode_failure_dsp; 15304 } 15305 break; 15306 } else { 15307 goto decode_failure_dsp; 15308 } 15309 } else { 15310 DIP("multu r%d, r%d", rs, rt); 15311 t2 = newTemp(Ity_I64); 15312 15313 assign(t2, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)), 15314 mkNarrowTo32(ty, getIReg(rt)))); 15315 15316 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True)); 15317 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True)); 15318 break; 15319 } 15320 } 15321 case 0x20: { /* ADD */ 15322 DIP("add r%d, r%d, r%d", rd, rs, rt); 15323 IRTemp tmpRs32 = newTemp(Ity_I32); 15324 IRTemp tmpRt32 = newTemp(Ity_I32); 15325 15326 assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); 15327 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 15328 15329 t0 = newTemp(Ity_I32); 15330 t1 = newTemp(Ity_I32); 15331 t2 = newTemp(Ity_I32); 15332 t3 = newTemp(Ity_I32); 15333 t4 = newTemp(Ity_I32); 15334 /* dst = src0 + src1 15335 if (sign(src0 ) != sign(src1 )) 15336 goto no overflow; 15337 if (sign(dst) == sign(src0 )) 15338 goto no overflow; 15339 we have overflow! */ 15340 15341 assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(tmpRt32))); 15342 assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(tmpRt32))); 15343 assign(t2, unop(Iop_1Uto32, 15344 binop(Iop_CmpEQ32, 15345 binop(Iop_And32, mkexpr(t1), mkU32(0x80000000)), 15346 mkU32(0x80000000)))); 15347 15348 assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32))); 15349 assign(t4, unop(Iop_1Uto32, 15350 binop(Iop_CmpNE32, 15351 binop(Iop_And32, mkexpr(t3), mkU32(0x80000000)), 15352 mkU32(0x80000000)))); 15353 15354 stmt(IRStmt_Exit(binop(Iop_CmpEQ32, 15355 binop(Iop_Or32, mkexpr(t2), mkexpr(t4)), 15356 mkU32(0)), 15357 Ijk_SigFPE_IntOvf, 15358 mode64 ? IRConst_U64(guest_PC_curr_instr + 4) : 15359 IRConst_U32(guest_PC_curr_instr + 4), 15360 OFFB_PC)); 15361 15362 putIReg(rd, mkWidenFrom32(ty, mkexpr(t0), True)); 15363 break; 15364 } 15365 case 0x1A: /* DIV */ 15366 DIP("div r%d, r%d", rs, rt); 15367 if (mode64) { 15368 t2 = newTemp(Ity_I64); 15369 15370 assign(t2, binop(Iop_DivModS64to32, 15371 getIReg(rs), mkNarrowTo32(ty, getIReg(rt)))); 15372 15373 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True)); 15374 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True)); 15375 } else { 15376 t1 = newTemp(Ity_I64); 15377 t2 = newTemp(Ity_I64); 15378 15379 assign(t1, unop(Iop_32Sto64, getIReg(rs))); 15380 assign(t2, binop(Iop_DivModS64to32, mkexpr(t1), getIReg(rt))); 15381 15382 putHI(unop(Iop_64HIto32, mkexpr(t2))); 15383 putLO(unop(Iop_64to32, mkexpr(t2))); 15384 } 15385 break; 15386 15387 case 0x1B: /* DIVU */ 15388 DIP("divu r%d, r%d", rs, rt); 15389 if (mode64) { 15390 t2 = newTemp(Ity_I64); 15391 15392 assign(t2, binop(Iop_DivModU64to32, 15393 getIReg(rs), mkNarrowTo32(ty, getIReg(rt)))); 15394 15395 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True)); 15396 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True)); 15397 } else { 15398 t1 = newTemp(Ity_I64); 15399 t2 = newTemp(Ity_I64); 15400 assign(t1, unop(Iop_32Uto64, getIReg(rs))); 15401 assign(t2, binop(Iop_DivModU64to32, mkexpr(t1), getIReg(rt))); 15402 putHI(unop(Iop_64HIto32, mkexpr(t2))); 15403 putLO(unop(Iop_64to32, mkexpr(t2))); 15404 } 15405 break; 15406 15407 case 0x1C: /* Doubleword Multiply - DMULT; MIPS64 */ 15408 DIP("dmult r%u, r%u", rs, rt); 15409 t0 = newTemp(Ity_I128); 15410 15411 assign(t0, binop(Iop_MullS64, getIReg(rs), getIReg(rt))); 15412 15413 putHI(unop(Iop_128HIto64, mkexpr(t0))); 15414 putLO(unop(Iop_128to64, mkexpr(t0))); 15415 break; 15416 15417 case 0x1D: /* Doubleword Multiply Unsigned - DMULTU; MIPS64 */ 15418 DIP("dmultu r%u, r%u", rs, rt); 15419 t0 = newTemp(Ity_I128); 15420 15421 assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt))); 15422 15423 putHI(unop(Iop_128HIto64, mkexpr(t0))); 15424 putLO(unop(Iop_128to64, mkexpr(t0))); 15425 break; 15426 15427 case 0x1E: /* Doubleword Divide DDIV; MIPS64 */ 15428 DIP("ddiv r%u, r%u", rs, rt); 15429 t1 = newTemp(Ity_I128); 15430 15431 assign(t1, binop(Iop_DivModS64to64, getIReg(rs), getIReg(rt))); 15432 15433 putHI(unop(Iop_128HIto64, mkexpr(t1))); 15434 putLO(unop(Iop_128to64, mkexpr(t1))); 15435 break; 15436 15437 case 0x1F: /* Doubleword Divide Unsigned DDIVU; MIPS64 check this */ 15438 DIP("ddivu r%u, r%u", rs, rt); 15439 t1 = newTemp(Ity_I128); 15440 t2 = newTemp(Ity_I128); 15441 15442 assign(t1, binop(Iop_64HLto128, mkU64(0), getIReg(rs))); 15443 15444 assign(t2, binop(Iop_DivModU128to64, mkexpr(t1), getIReg(rt))); 15445 15446 putHI(unop(Iop_128HIto64, mkexpr(t2))); 15447 putLO(unop(Iop_128to64, mkexpr(t2))); 15448 break; 15449 15450 case 0x10: { /* MFHI */ 15451 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15452 /* If DSP is present -> DSP ASE MFHI */ 15453 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15454 if (0 != retVal ) { 15455 goto decode_failure; 15456 } 15457 break; 15458 } else { 15459 DIP("mfhi r%d", rd); 15460 putIReg(rd, getHI()); 15461 break; 15462 } 15463 } 15464 15465 case 0x11: { /* MTHI */ 15466 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15467 /* If DSP is present -> DSP ASE MTHI */ 15468 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15469 if (0 != retVal ) { 15470 goto decode_failure; 15471 } 15472 break; 15473 } else { 15474 DIP("mthi r%d", rs); 15475 putHI(getIReg(rs)); 15476 break; 15477 } 15478 } 15479 15480 case 0x12: { /* MFLO */ 15481 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15482 /* If DSP is present -> DSP ASE MFLO */ 15483 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15484 if (0 != retVal ) { 15485 goto decode_failure; 15486 } 15487 break; 15488 } else { 15489 DIP("mflo r%d", rd); 15490 putIReg(rd, getLO()); 15491 break; 15492 } 15493 } 15494 15495 case 0x13: { /* MTLO */ 15496 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15497 /* If DSP is present -> DSP ASE MTLO */ 15498 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15499 if (0 != retVal ) { 15500 goto decode_failure; 15501 } 15502 break; 15503 } else { 15504 DIP("mtlo r%d", rs); 15505 putLO(getIReg(rs)); 15506 break; 15507 } 15508 } 15509 15510 case 0x21: /* ADDU */ 15511 DIP("addu r%d, r%d, r%d", rd, rs, rt); 15512 if (mode64) { 15513 ALU_PATTERN64(Iop_Add32); 15514 } else { 15515 ALU_PATTERN(Iop_Add32); 15516 } 15517 break; 15518 15519 case 0x22: { /* SUB */ 15520 DIP("sub r%d, r%d, r%d", rd, rs, rt); 15521 IRTemp tmpRs32 = newTemp(Ity_I32); 15522 IRTemp tmpRt32 = newTemp(Ity_I32); 15523 15524 assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); 15525 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 15526 t0 = newTemp(Ity_I32); 15527 t1 = newTemp(Ity_I32); 15528 t2 = newTemp(Ity_I32); 15529 t3 = newTemp(Ity_I32); 15530 t4 = newTemp(Ity_I32); 15531 t5 = newTemp(Ity_I32); 15532 /* dst = src0 + (-1 * src1) 15533 if(sign(src0 ) != sign((-1 * src1) )) 15534 goto no overflow; 15535 if(sign(dst) == sign(src0 )) 15536 goto no overflow; 15537 we have overflow! */ 15538 15539 assign(t5, binop(Iop_Mul32, mkexpr(tmpRt32), mkU32(-1))); 15540 assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(t5))); 15541 assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(t5))); 15542 assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32, 15543 mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000)))); 15544 15545 assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32))); 15546 assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32, 15547 mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000)))); 15548 15549 stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2), 15550 mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf, 15551 mode64 ? IRConst_U64(guest_PC_curr_instr + 4) : 15552 IRConst_U32(guest_PC_curr_instr + 4), 15553 OFFB_PC)); 15554 15555 putIReg(rd, mkWidenFrom32(ty, mkexpr(t0), True)); 15556 break; 15557 } 15558 case 0x23: /* SUBU */ 15559 DIP("subu r%d, r%d, r%d", rd, rs, rt); 15560 if (mode64) { 15561 ALU_PATTERN64(Iop_Sub32); 15562 } else { 15563 ALU_PATTERN(Iop_Sub32); 15564 } 15565 break; 15566 15567 case 0x24: /* AND */ 15568 DIP("and r%d, r%d, r%d", rd, rs, rt); 15569 if (mode64) { 15570 ALU_PATTERN(Iop_And64); 15571 } else { 15572 ALU_PATTERN(Iop_And32); 15573 } 15574 break; 15575 15576 case 0x25: /* OR */ 15577 DIP("or r%d, r%d, r%d", rd, rs, rt); 15578 if (mode64) { 15579 ALU_PATTERN(Iop_Or64); 15580 } else { 15581 ALU_PATTERN(Iop_Or32); 15582 } 15583 break; 15584 15585 case 0x26: /* XOR */ 15586 DIP("xor r%d, r%d, r%d", rd, rs, rt); 15587 if (mode64) { 15588 ALU_PATTERN(Iop_Xor64); 15589 } else { 15590 ALU_PATTERN(Iop_Xor32); 15591 } 15592 break; 15593 15594 case 0x27: /* NOR */ 15595 DIP("nor r%d, r%d, r%d", rd, rs, rt); 15596 if (mode64) 15597 putIReg(rd, unop(Iop_Not64, binop(Iop_Or64, getIReg(rs), 15598 getIReg(rt)))); 15599 else 15600 putIReg(rd, unop(Iop_Not32, binop(Iop_Or32, getIReg(rs), 15601 getIReg(rt)))); 15602 break; 15603 15604 case 0x08: /* JR */ 15605 DIP("jr r%d", rs); 15606 t0 = newTemp(ty); 15607 assign(t0, getIReg(rs)); 15608 lastn = mkexpr(t0); 15609 break; 15610 15611 case 0x09: /* JALR */ 15612 DIP("jalr r%d r%d", rd, rs); 15613 if (mode64) { 15614 putIReg(rd, mkU64(guest_PC_curr_instr + 8)); 15615 t0 = newTemp(Ity_I64); 15616 assign(t0, getIReg(rs)); 15617 lastn = mkexpr(t0); 15618 } else { 15619 putIReg(rd, mkU32(guest_PC_curr_instr + 8)); 15620 t0 = newTemp(Ity_I32); 15621 assign(t0, getIReg(rs)); 15622 lastn = mkexpr(t0); 15623 } 15624 break; 15625 15626 case 0x0C: /* SYSCALL */ 15627 DIP("syscall"); 15628 if (mode64) 15629 putPC(mkU64(guest_PC_curr_instr + 4)); 15630 else 15631 putPC(mkU32(guest_PC_curr_instr + 4)); 15632 dres.jk_StopHere = Ijk_Sys_syscall; 15633 dres.whatNext = Dis_StopHere; 15634 break; 15635 15636 case 0x2A: /* SLT */ 15637 DIP("slt r%d, r%d, r%d", rd, rs, rt); 15638 if (mode64) 15639 putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs), 15640 getIReg(rt)))); 15641 else 15642 putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs), 15643 getIReg(rt)))); 15644 break; 15645 15646 case 0x2B: /* SLTU */ 15647 DIP("sltu r%d, r%d, r%d", rd, rs, rt); 15648 if (mode64) 15649 putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs), 15650 getIReg(rt)))); 15651 else 15652 putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs), 15653 getIReg(rt)))); 15654 break; 15655 15656 case 0x00: { /* SLL */ 15657 DIP("sll r%d, r%d, %d", rd, rt, sa); 15658 IRTemp tmpRt32 = newTemp(Ity_I32); 15659 IRTemp tmpSh32 = newTemp(Ity_I32); 15660 IRTemp tmpRd = newTemp(Ity_I64); 15661 if (mode64) { 15662 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 15663 assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkU8(sa))); 15664 assign(tmpRd, mkWidenFrom32(ty, mkexpr(tmpSh32), True)); 15665 putIReg(rd, mkexpr(tmpRd)); 15666 } else 15667 SXX_PATTERN(Iop_Shl32); 15668 break; 15669 } 15670 15671 case 0x04: { /* SLLV */ 15672 DIP("sllv r%d, r%d, r%d", rd, rt, rs); 15673 if (mode64) { 15674 IRTemp tmpRs8 = newTemp(Ity_I8); 15675 IRTemp tmpRt32 = newTemp(Ity_I32); 15676 IRTemp tmpSh32 = newTemp(Ity_I32); 15677 IRTemp tmp = newTemp(ty); 15678 assign(tmp, binop(mkSzOp(ty, Iop_And8), getIReg(rs), 15679 mkSzImm(ty, 31))); 15680 assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp))); 15681 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 15682 assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkexpr(tmpRs8))); 15683 putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True)); 15684 } else { 15685 SXXV_PATTERN(Iop_Shl32); 15686 } 15687 break; 15688 } 15689 15690 case 0x03: /* SRA */ 15691 DIP("sra r%d, r%d, %d", rd, rt, sa); 15692 if (mode64) { 15693 IRTemp tmpRt32 = newTemp(Ity_I32); 15694 IRTemp tmpSh32 = newTemp(Ity_I32); 15695 15696 t1 = newTemp(Ity_I64); 15697 t2 = newTemp(Ity_I64); 15698 t3 = newTemp(Ity_I64); 15699 15700 assign(t1, binop(Iop_And64, getIReg(rt), /* hi */ 15701 mkU64(0xFFFFFFFF00000000ULL))); 15702 15703 assign(t2, binop(Iop_Sar64, mkexpr(t1), mkU8(sa))); 15704 15705 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 15706 assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkU8(sa))); 15707 15708 putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True)); 15709 } else { 15710 SXX_PATTERN(Iop_Sar32); 15711 } 15712 break; 15713 15714 case 0x07: /* SRAV */ 15715 DIP("srav r%d, r%d, r%d", rd, rt, rs); 15716 if (mode64) { 15717 IRTemp tmpRt32 = newTemp(Ity_I32); 15718 IRTemp tmpSh32 = newTemp(Ity_I32); 15719 15720 t1 = newTemp(Ity_I64); 15721 t2 = newTemp(Ity_I64); 15722 t3 = newTemp(Ity_I64); 15723 t4 = newTemp(Ity_I8); 15724 15725 assign(t4, unop(Iop_32to8, binop(Iop_And32, 15726 mkNarrowTo32(ty, getIReg(rs)), mkU32(0x0000001F)))); 15727 15728 assign(t1, binop(Iop_And64, getIReg(rt), /* hi */ 15729 mkU64(0xFFFFFFFF00000000ULL))); 15730 15731 assign(t2, binop(Iop_Sar64, mkexpr(t1), mkexpr(t4))); 15732 15733 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 15734 assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkexpr(t4))); 15735 15736 putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True)); 15737 } else { 15738 SXXV_PATTERN(Iop_Sar32); 15739 } 15740 break; 15741 15742 case 0x02: { /* SRL */ 15743 rot = get_rot(cins); 15744 if (rot) { 15745 DIP("rotr r%d, r%d, %d", rd, rt, sa); 15746 putIReg(rd, mkWidenFrom32(ty, genROR32(mkNarrowTo32(ty, 15747 getIReg(rt)), sa), True)); 15748 } else { 15749 DIP("srl r%d, r%d, %d", rd, rt, sa); 15750 if (mode64) { 15751 IRTemp tmpSh32 = newTemp(Ity_I32); 15752 IRTemp tmpRt32 = newTemp(Ity_I32); 15753 15754 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 15755 assign(tmpSh32, binop(Iop_Shr32, mkexpr(tmpRt32), mkU8(sa))); 15756 putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True)); 15757 } else { 15758 SXX_PATTERN(Iop_Shr32); 15759 } 15760 } 15761 break; 15762 } 15763 15764 case 0x06: { 15765 rot = get_rotv(cins); 15766 if (rot) { 15767 DIP("rotrv r%d, r%d, r%d", rd, rt, rs); 15768 putIReg(rd, mkWidenFrom32(ty, genRORV32(mkNarrowTo32(ty, 15769 getIReg(rt)), mkNarrowTo32(ty, getIReg(rs))), True)); 15770 break; 15771 } else { /* SRLV */ 15772 DIP("srlv r%d, r%d, r%d", rd, rt, rs); 15773 if (mode64) { 15774 SXXV_PATTERN64(Iop_Shr32); 15775 } else { 15776 SXXV_PATTERN(Iop_Shr32); 15777 } 15778 break; 15779 } 15780 } 15781 15782 case 0x0D: /* BREAK */ 15783 DIP("break 0x%x", trap_code); 15784 if (mode64) 15785 jmp_lit64(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4)); 15786 else 15787 jmp_lit32(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4)); 15788 vassert(dres.whatNext == Dis_StopHere); 15789 break; 15790 15791 case 0x30: { /* TGE */ 15792 DIP("tge r%d, r%d %d", rs, rt, trap_code); 15793 if (mode64) { 15794 if (trap_code == 7) 15795 stmt (IRStmt_Exit (unop (Iop_Not1, 15796 binop (Iop_CmpLT64S, 15797 getIReg (rs), 15798 getIReg (rt))), 15799 Ijk_SigFPE_IntDiv, 15800 IRConst_U64(guest_PC_curr_instr + 4), 15801 OFFB_PC)); 15802 else if (trap_code == 6) 15803 stmt (IRStmt_Exit (unop (Iop_Not1, 15804 binop (Iop_CmpLT64S, 15805 getIReg (rs), 15806 getIReg (rt))), 15807 Ijk_SigFPE_IntOvf, 15808 IRConst_U64(guest_PC_curr_instr + 4), 15809 OFFB_PC)); 15810 else 15811 stmt (IRStmt_Exit (unop (Iop_Not1, 15812 binop (Iop_CmpLT64S, 15813 getIReg (rs), 15814 getIReg (rt))), 15815 Ijk_SigTRAP, 15816 IRConst_U64(guest_PC_curr_instr + 4), 15817 OFFB_PC)); 15818 } else { 15819 if (trap_code == 7) 15820 stmt (IRStmt_Exit (unop (Iop_Not1, 15821 binop (Iop_CmpLT32S, 15822 getIReg (rs), 15823 getIReg (rt))), 15824 Ijk_SigFPE_IntDiv, 15825 IRConst_U32(guest_PC_curr_instr + 4), 15826 OFFB_PC)); 15827 else if (trap_code == 6) 15828 stmt (IRStmt_Exit (unop (Iop_Not1, 15829 binop (Iop_CmpLT32S, 15830 getIReg (rs), 15831 getIReg (rt))), 15832 Ijk_SigFPE_IntOvf, 15833 IRConst_U32(guest_PC_curr_instr + 4), 15834 OFFB_PC)); 15835 else 15836 stmt (IRStmt_Exit (unop (Iop_Not1, 15837 binop (Iop_CmpLT32S, 15838 getIReg (rs), 15839 getIReg (rt))), 15840 Ijk_SigTRAP, 15841 IRConst_U32(guest_PC_curr_instr + 4), 15842 OFFB_PC)); 15843 } 15844 break; 15845 } 15846 case 0x31: { /* TGEU */ 15847 DIP("tgeu r%d, r%d %d", rs, rt, trap_code); 15848 if (mode64) { 15849 if (trap_code == 7) 15850 stmt (IRStmt_Exit (unop (Iop_Not1, 15851 binop (Iop_CmpLT64U, 15852 getIReg (rs), 15853 getIReg (rt))), 15854 Ijk_SigFPE_IntDiv, 15855 IRConst_U64(guest_PC_curr_instr + 4), 15856 OFFB_PC)); 15857 else if (trap_code == 6) 15858 stmt (IRStmt_Exit (unop (Iop_Not1, 15859 binop (Iop_CmpLT64U, 15860 getIReg (rs), 15861 getIReg (rt))), 15862 Ijk_SigFPE_IntOvf, 15863 IRConst_U64(guest_PC_curr_instr + 4), 15864 OFFB_PC)); 15865 else 15866 stmt (IRStmt_Exit (unop (Iop_Not1, 15867 binop (Iop_CmpLT64U, 15868 getIReg (rs), 15869 getIReg (rt))), 15870 Ijk_SigTRAP, 15871 IRConst_U64(guest_PC_curr_instr + 4), 15872 OFFB_PC)); 15873 } else { 15874 if (trap_code == 7) 15875 stmt (IRStmt_Exit (unop (Iop_Not1, 15876 binop (Iop_CmpLT32U, 15877 getIReg (rs), 15878 getIReg (rt))), 15879 Ijk_SigFPE_IntDiv, 15880 IRConst_U32(guest_PC_curr_instr + 4), 15881 OFFB_PC)); 15882 else if (trap_code == 6) 15883 stmt (IRStmt_Exit (unop (Iop_Not1, 15884 binop (Iop_CmpLT32U, 15885 getIReg (rs), 15886 getIReg (rt))), 15887 Ijk_SigFPE_IntOvf, 15888 IRConst_U32(guest_PC_curr_instr + 4), 15889 OFFB_PC)); 15890 else 15891 stmt (IRStmt_Exit (unop (Iop_Not1, 15892 binop (Iop_CmpLT32U, 15893 getIReg (rs), 15894 getIReg (rt))), 15895 Ijk_SigTRAP, 15896 IRConst_U32(guest_PC_curr_instr + 4), 15897 OFFB_PC)); 15898 } 15899 break; 15900 } 15901 case 0x32: { /* TLT */ 15902 DIP("tlt r%d, r%d %d", rs, rt, trap_code); 15903 if (mode64) { 15904 if (trap_code == 7) 15905 stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs), 15906 getIReg(rt)), Ijk_SigFPE_IntDiv, 15907 IRConst_U64(guest_PC_curr_instr + 4), 15908 OFFB_PC)); 15909 else if (trap_code == 6) 15910 stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs), 15911 getIReg(rt)), Ijk_SigFPE_IntOvf, 15912 IRConst_U64(guest_PC_curr_instr + 4), 15913 OFFB_PC)); 15914 else 15915 stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs), 15916 getIReg(rt)), Ijk_SigTRAP, 15917 IRConst_U64(guest_PC_curr_instr + 4), 15918 OFFB_PC)); 15919 } else { 15920 if (trap_code == 7) 15921 stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs), 15922 getIReg(rt)), Ijk_SigFPE_IntDiv, 15923 IRConst_U32(guest_PC_curr_instr + 4), 15924 OFFB_PC)); 15925 else if (trap_code == 6) 15926 stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs), 15927 getIReg(rt)), Ijk_SigFPE_IntOvf, 15928 IRConst_U32(guest_PC_curr_instr + 4), 15929 OFFB_PC)); 15930 else 15931 stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs), 15932 getIReg(rt)), Ijk_SigTRAP, 15933 IRConst_U32(guest_PC_curr_instr + 4), 15934 OFFB_PC)); 15935 } 15936 break; 15937 } 15938 case 0x33: { /* TLTU */ 15939 DIP("tltu r%d, r%d %d", rs, rt, trap_code); 15940 if (mode64) { 15941 if (trap_code == 7) 15942 stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs), 15943 getIReg(rt)), Ijk_SigFPE_IntDiv, 15944 IRConst_U64(guest_PC_curr_instr + 4), 15945 OFFB_PC)); 15946 else if (trap_code == 6) 15947 stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs), 15948 getIReg(rt)), Ijk_SigFPE_IntOvf, 15949 IRConst_U64(guest_PC_curr_instr + 4), 15950 OFFB_PC)); 15951 else 15952 stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs), 15953 getIReg(rt)), Ijk_SigTRAP, 15954 IRConst_U64(guest_PC_curr_instr + 4), 15955 OFFB_PC)); 15956 } else { 15957 if (trap_code == 7) 15958 stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs), 15959 getIReg(rt)), Ijk_SigFPE_IntDiv, 15960 IRConst_U32(guest_PC_curr_instr + 4), 15961 OFFB_PC)); 15962 else if (trap_code == 6) 15963 stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs), 15964 getIReg(rt)), Ijk_SigFPE_IntOvf, 15965 IRConst_U32(guest_PC_curr_instr + 4), 15966 OFFB_PC)); 15967 else 15968 stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs), 15969 getIReg (rt)), Ijk_SigTRAP, 15970 IRConst_U32(guest_PC_curr_instr + 4), 15971 OFFB_PC)); 15972 } 15973 break; 15974 } 15975 case 0x34: { /* TEQ */ 15976 DIP("teq r%d, r%d, %d", rs, rt, trap_code); 15977 if (mode64) { 15978 if (trap_code == 7) 15979 stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs), 15980 getIReg(rt)), Ijk_SigFPE_IntDiv, 15981 IRConst_U64(guest_PC_curr_instr + 4), 15982 OFFB_PC)); 15983 else if (trap_code == 6) 15984 stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs), 15985 getIReg(rt)), Ijk_SigFPE_IntOvf, 15986 IRConst_U64(guest_PC_curr_instr + 4), 15987 OFFB_PC)); 15988 else 15989 stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs), 15990 getIReg(rt)), Ijk_SigTRAP, 15991 IRConst_U64(guest_PC_curr_instr + 4), 15992 OFFB_PC)); 15993 } else { 15994 if (trap_code == 7) 15995 stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs), 15996 getIReg(rt)), Ijk_SigFPE_IntDiv, 15997 IRConst_U32(guest_PC_curr_instr + 4), 15998 OFFB_PC)); 15999 else if (trap_code == 6) 16000 stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs), 16001 getIReg(rt)), Ijk_SigFPE_IntOvf, 16002 IRConst_U32(guest_PC_curr_instr + 4), 16003 OFFB_PC)); 16004 else 16005 stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs), 16006 getIReg(rt)), Ijk_SigTRAP, 16007 IRConst_U32(guest_PC_curr_instr + 4), 16008 OFFB_PC)); 16009 } 16010 break; 16011 } 16012 case 0x36: { /* TNE */ 16013 DIP("tne r%d, r%d %d", rs, rt, trap_code); 16014 if (mode64) { 16015 if (trap_code == 7) 16016 stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs), 16017 getIReg(rt)), Ijk_SigFPE_IntDiv, 16018 IRConst_U64(guest_PC_curr_instr + 4), 16019 OFFB_PC)); 16020 else if (trap_code == 6) 16021 stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs), 16022 getIReg(rt)), Ijk_SigFPE_IntOvf, 16023 IRConst_U64(guest_PC_curr_instr + 4), 16024 OFFB_PC)); 16025 else 16026 stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs), 16027 getIReg(rt)), Ijk_SigTRAP, 16028 IRConst_U64(guest_PC_curr_instr + 4), 16029 OFFB_PC)); 16030 } else { 16031 if (trap_code == 7) 16032 stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs), 16033 getIReg(rt)), Ijk_SigFPE_IntDiv, 16034 IRConst_U32(guest_PC_curr_instr + 4), 16035 OFFB_PC)); 16036 else if (trap_code == 6) 16037 stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs), 16038 getIReg(rt)), Ijk_SigFPE_IntOvf, 16039 IRConst_U32(guest_PC_curr_instr + 4), 16040 OFFB_PC)); 16041 else 16042 stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs), 16043 getIReg(rt)), Ijk_SigTRAP, 16044 IRConst_U32(guest_PC_curr_instr + 4), 16045 OFFB_PC)); 16046 } 16047 break; 16048 } 16049 case 0x14: 16050 case 0x16: 16051 case 0x17: /* DSLLV, DROTRV:DSRLV, DSRAV */ 16052 case 0x38: 16053 case 0x3A: 16054 case 0x3B: /* DSLL, DROTL:DSRL, DSRA */ 16055 case 0x3C: 16056 case 0x3E: 16057 case 0x3F: /* DSLL32, DROTR32:DSRL32, DSRA32 */ 16058 if (dis_instr_shrt(cins)) 16059 break; 16060 goto decode_failure; 16061 16062 case 0x0F: /* SYNC */ 16063 DIP("sync 0x%x", sel); 16064 /* Just ignore it. */ 16065 break; 16066 16067 case 0x2C: { /* Doubleword Add - DADD; MIPS64 */ 16068 DIP("dadd r%d, r%d, r%d", rd, rs, rt); 16069 IRTemp tmpRs64 = newTemp(Ity_I64); 16070 IRTemp tmpRt64 = newTemp(Ity_I64); 16071 16072 assign(tmpRs64, getIReg(rs)); 16073 assign(tmpRt64, getIReg(rt)); 16074 16075 t0 = newTemp(Ity_I64); 16076 t1 = newTemp(Ity_I64); 16077 t2 = newTemp(Ity_I64); 16078 t3 = newTemp(Ity_I64); 16079 t4 = newTemp(Ity_I64); 16080 /* dst = src0 + src1 16081 if(sign(src0 ) != sign(src1 )) 16082 goto no overflow; 16083 if(sign(dst) == sign(src0 )) 16084 goto no overflow; 16085 we have overflow! */ 16086 16087 assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(tmpRt64))); 16088 assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(tmpRt64))); 16089 assign(t2, unop(Iop_1Uto64, 16090 binop(Iop_CmpEQ64, 16091 binop(Iop_And64, mkexpr(t1), 16092 mkU64(0x8000000000000000ULL)), 16093 mkU64(0x8000000000000000ULL)))); 16094 16095 assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64))); 16096 assign(t4, unop(Iop_1Uto64, 16097 binop(Iop_CmpNE64, 16098 binop(Iop_And64, mkexpr(t3), 16099 mkU64(0x8000000000000000ULL)), 16100 mkU64(0x8000000000000000ULL)))); 16101 16102 stmt(IRStmt_Exit(binop(Iop_CmpEQ64, 16103 binop(Iop_Or64, mkexpr(t2), mkexpr(t4)), 16104 mkU64(0)), 16105 Ijk_SigFPE_IntOvf, 16106 IRConst_U64(guest_PC_curr_instr + 4), 16107 OFFB_PC)); 16108 16109 putIReg(rd, mkexpr(t0)); 16110 break; 16111 } 16112 16113 case 0x2D: /* Doubleword Add Unsigned - DADDU; MIPS64 */ 16114 DIP("daddu r%d, r%d, r%d", rd, rs, rt); 16115 ALU_PATTERN(Iop_Add64); 16116 break; 16117 16118 case 0x2E: { /* Doubleword Subtract - DSUB; MIPS64 */ 16119 DIP("dsub r%u, r%u, r%u", rd, rs, rt); 16120 IRTemp tmpRs64 = newTemp(Ity_I64); 16121 IRTemp tmpRt64 = newTemp(Ity_I64); 16122 16123 assign(tmpRs64, getIReg(rs)); 16124 assign(tmpRt64, getIReg(rt)); 16125 t0 = newTemp(Ity_I64); 16126 t1 = newTemp(Ity_I64); 16127 t2 = newTemp(Ity_I64); 16128 t3 = newTemp(Ity_I64); 16129 t4 = newTemp(Ity_I64); 16130 t5 = newTemp(Ity_I64); 16131 /* dst = src0 + (-1 * src1) 16132 if(sign(src0 ) != sign((-1 * src1) )) 16133 goto no overflow; 16134 if(sign(dst) == sign(src0 )) 16135 goto no overflow; 16136 we have overflow! */ 16137 16138 assign(t5, binop(Iop_Mul64, 16139 mkexpr(tmpRt64), 16140 mkU64(0xffffffffffffffffULL))); 16141 assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(t5))); 16142 assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(t5))); 16143 assign(t2, unop(Iop_1Sto64, 16144 binop(Iop_CmpEQ64, 16145 binop(Iop_And64, 16146 mkexpr(t1), 16147 mkU64(0x8000000000000000ULL)), 16148 mkU64(0x8000000000000000ULL)))); 16149 16150 assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64))); 16151 assign(t4, unop(Iop_1Sto64, 16152 binop(Iop_CmpNE64, 16153 binop(Iop_And64, 16154 mkexpr(t3), 16155 mkU64(0x8000000000000000ULL)), 16156 mkU64(0x8000000000000000ULL)))); 16157 16158 stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2), 16159 mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf, 16160 IRConst_U64(guest_PC_curr_instr + 4), 16161 OFFB_PC)); 16162 16163 putIReg(rd, binop(Iop_Sub64, getIReg(rs), getIReg(rt))); 16164 break; 16165 } 16166 16167 case 0x2F: /* Doubleword Subtract Unsigned - DSUBU; MIPS64 */ 16168 DIP("dsub r%u, r%u,r%u", rd, rt, rt); 16169 ALU_PATTERN(Iop_Sub64); 16170 break; 16171 16172 default: 16173 goto decode_failure; 16174 } 16175 break; 16176 16177 case 0x01: /* Regimm */ 16178 16179 switch (rt) { 16180 case 0x00: /* BLTZ */ 16181 DIP("bltz r%d, %d", rs, imm); 16182 if (mode64) { 16183 if (!dis_instr_branch(cins, &dres, resteerOkFn, 16184 callback_opaque, &bstmt)) 16185 goto decode_failure; 16186 } else 16187 dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs), 16188 mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt); 16189 break; 16190 16191 case 0x01: /* BGEZ */ 16192 DIP("bgez r%d, %d", rs, imm); 16193 if (mode64) { 16194 if (!dis_instr_branch(cins, &dres, resteerOkFn, 16195 callback_opaque, &bstmt)) 16196 goto decode_failure; 16197 } else 16198 dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs), 16199 mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt); 16200 break; 16201 16202 case 0x02: /* BLTZL */ 16203 DIP("bltzl r%d, %d", rs, imm); 16204 lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32, 16205 binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs), 16206 mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)), 16207 mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)), 16208 imm); 16209 break; 16210 16211 case 0x03: /* BGEZL */ 16212 DIP("bgezl r%d, %d", rs, imm); 16213 lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32, 16214 binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs), 16215 mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)), 16216 mode64 ? mkU64(0x0) : mkU32(0x0)), imm); 16217 break; 16218 16219 case 0x10: /* BLTZAL */ 16220 DIP("bltzal r%d, %d", rs, imm); 16221 if (mode64) { 16222 if (!dis_instr_branch(cins, &dres, resteerOkFn, 16223 callback_opaque, &bstmt)) 16224 goto decode_failure; 16225 } else 16226 dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs), 16227 mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt); 16228 break; 16229 16230 case 0x12: /* BLTZALL */ 16231 DIP("bltzall r%d, %d", rs, imm); 16232 putIReg(31, mode64 ? mkU64(guest_PC_curr_instr + 8) : 16233 mkU32(guest_PC_curr_instr + 8)); 16234 lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32, 16235 binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs), 16236 mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)), 16237 mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)), 16238 imm); 16239 break; 16240 16241 case 0x11: /* BGEZAL */ 16242 DIP("bgezal r%d, %d", rs, imm); 16243 if (mode64) { 16244 if (!dis_instr_branch(cins, &dres, resteerOkFn, 16245 callback_opaque, &bstmt)) 16246 goto decode_failure; 16247 } else 16248 dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs), 16249 mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt); 16250 break; 16251 16252 case 0x13: /* BGEZALL */ 16253 DIP("bgezall r%d, %d", rs, imm); 16254 if (mode64) { 16255 putIReg(31, mkU64(guest_PC_curr_instr + 8)); 16256 lastn = dis_branch_likely(binop(Iop_CmpNE64, 16257 binop(Iop_And64, 16258 getIReg(rs), 16259 mkU64(0x8000000000000000ULL)), 16260 mkU64(0x0)), 16261 imm); 16262 } else { 16263 putIReg(31, mkU32(guest_PC_curr_instr + 8)); 16264 lastn = dis_branch_likely(binop(Iop_CmpNE32, binop(Iop_And32, 16265 getIReg(rs), mkU32(0x80000000)), 16266 mkU32(0x0)), imm); 16267 } 16268 break; 16269 16270 case 0x08: /* TGEI */ 16271 DIP("tgei r%d, %d %d", rs, imm, trap_code); 16272 if (mode64) { 16273 stmt (IRStmt_Exit (unop (Iop_Not1, 16274 binop (Iop_CmpLT64S, 16275 getIReg (rs), 16276 mkU64 (extend_s_16to64 (imm)))), 16277 Ijk_SigTRAP, 16278 IRConst_U64(guest_PC_curr_instr + 4), 16279 OFFB_PC)); 16280 } else { 16281 stmt (IRStmt_Exit (unop (Iop_Not1, 16282 binop (Iop_CmpLT32S, 16283 getIReg (rs), 16284 mkU32 (extend_s_16to32 (imm)))), 16285 Ijk_SigTRAP, 16286 IRConst_U32(guest_PC_curr_instr + 4), 16287 OFFB_PC)); 16288 } 16289 break; 16290 16291 case 0x09: { /* TGEIU */ 16292 DIP("tgeiu r%d, %d %d", rs, imm, trap_code); 16293 if (mode64) { 16294 stmt (IRStmt_Exit (unop (Iop_Not1, 16295 binop (Iop_CmpLT64U, 16296 getIReg (rs), 16297 mkU64 (extend_s_16to64 (imm)))), 16298 Ijk_SigTRAP, 16299 IRConst_U64(guest_PC_curr_instr + 4), 16300 OFFB_PC)); 16301 } else { 16302 stmt (IRStmt_Exit (unop (Iop_Not1, 16303 binop (Iop_CmpLT32U, 16304 getIReg (rs), 16305 mkU32 (extend_s_16to32 (imm)))), 16306 Ijk_SigTRAP, 16307 IRConst_U32(guest_PC_curr_instr + 4), 16308 OFFB_PC)); 16309 } 16310 break; 16311 } 16312 case 0x0A: { /* TLTI */ 16313 DIP("tlti r%d, %d %d", rs, imm, trap_code); 16314 if (mode64) { 16315 stmt (IRStmt_Exit (binop (Iop_CmpLT64S, getIReg (rs), 16316 mkU64 (extend_s_16to64 (imm))), 16317 Ijk_SigTRAP, 16318 IRConst_U64(guest_PC_curr_instr + 4), 16319 OFFB_PC)); 16320 } else { 16321 stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rs), 16322 mkU32 (extend_s_16to32 (imm))), 16323 Ijk_SigTRAP, 16324 IRConst_U32(guest_PC_curr_instr + 4), 16325 OFFB_PC)); 16326 } 16327 break; 16328 } 16329 case 0x0B: { /* TLTIU */ 16330 DIP("tltiu r%d, %d %d", rs, imm, trap_code); 16331 if (mode64) { 16332 stmt (IRStmt_Exit (binop (Iop_CmpLT64U, getIReg (rs), 16333 mkU64 (extend_s_16to64 (imm))), 16334 Ijk_SigTRAP, 16335 IRConst_U64(guest_PC_curr_instr + 4), 16336 OFFB_PC)); 16337 } else { 16338 stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rs), 16339 mkU32 (extend_s_16to32 (imm))), 16340 Ijk_SigTRAP, 16341 IRConst_U32(guest_PC_curr_instr + 4), 16342 OFFB_PC)); 16343 } 16344 break; 16345 } 16346 case 0x0C: { /* TEQI */ 16347 DIP("teqi r%d, %d %d", rs, imm, trap_code); 16348 if (mode64) { 16349 stmt (IRStmt_Exit (binop (Iop_CmpEQ64, getIReg (rs), 16350 mkU64 (extend_s_16to64 (imm))), 16351 Ijk_SigTRAP, 16352 IRConst_U64(guest_PC_curr_instr + 4), 16353 OFFB_PC)); 16354 } else { 16355 stmt (IRStmt_Exit (binop (Iop_CmpEQ32, getIReg (rs), 16356 mkU32 (extend_s_16to32 (imm))), 16357 Ijk_SigTRAP, 16358 IRConst_U32(guest_PC_curr_instr + 4), 16359 OFFB_PC)); 16360 } 16361 break; 16362 } 16363 case 0x0E: { /* TNEI */ 16364 DIP("tnei r%d, %d %d", rs, imm, trap_code); 16365 if (mode64) { 16366 stmt (IRStmt_Exit (binop (Iop_CmpNE64, getIReg (rs), 16367 mkU64 (extend_s_16to64 (imm))), 16368 Ijk_SigTRAP, 16369 IRConst_U64(guest_PC_curr_instr + 4), 16370 OFFB_PC)); 16371 } else { 16372 stmt (IRStmt_Exit (binop (Iop_CmpNE32, getIReg (rs), 16373 mkU32 (extend_s_16to32 (imm))), 16374 Ijk_SigTRAP, 16375 IRConst_U32(guest_PC_curr_instr + 4), 16376 OFFB_PC)); 16377 } 16378 break; 16379 } 16380 case 0x1C: { /* BPOSGE32 */ 16381 DIP("bposge32 %d", imm); 16382 vassert(!mode64); 16383 t0 = newTemp(Ity_I32); 16384 /* Get pos field from DSPControl register. */ 16385 assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f))); 16386 dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLT32U, mkexpr(t0), 16387 mkU32(32))), imm, &bstmt); 16388 } 16389 case 0x1F: 16390 /* SYNCI */ 16391 /* Just ignore it */ 16392 break; 16393 16394 default: 16395 goto decode_failure; 16396 } 16397 break; 16398 16399 case 0x04: 16400 DIP("beq r%d, r%d, %d", rs, rt, imm); 16401 if (mode64) 16402 dis_branch(False, binop(Iop_CmpEQ64, getIReg(rs), getIReg(rt)), 16403 imm, &bstmt); 16404 else 16405 dis_branch(False, binop(Iop_CmpEQ32, getIReg(rs), getIReg(rt)), 16406 imm, &bstmt); 16407 break; 16408 16409 case 0x14: 16410 DIP("beql r%d, r%d, %d", rs, rt, imm); 16411 lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32, 16412 getIReg(rs), getIReg(rt)), imm); 16413 break; 16414 16415 case 0x05: 16416 DIP("bne r%d, r%d, %d", rs, rt, imm); 16417 if (mode64) 16418 dis_branch(False, binop(Iop_CmpNE64, getIReg(rs), getIReg(rt)), 16419 imm, &bstmt); 16420 else 16421 dis_branch(False, binop(Iop_CmpNE32, getIReg(rs), getIReg(rt)), 16422 imm, &bstmt); 16423 break; 16424 16425 case 0x15: 16426 DIP("bnel r%d, r%d, %d", rs, rt, imm); 16427 lastn = dis_branch_likely(binop(mode64 ? Iop_CmpEQ64 : Iop_CmpEQ32, 16428 getIReg(rs), getIReg(rt)), imm); 16429 break; 16430 16431 case 0x07: /* BGTZ */ 16432 DIP("bgtz r%d, %d", rs, imm); 16433 if (mode64) 16434 dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE64S, getIReg(rs), 16435 mkU64(0x00))), imm, &bstmt); 16436 else 16437 dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE32S, getIReg(rs), 16438 mkU32(0x00))), imm, &bstmt); 16439 break; 16440 16441 case 0x17: /* BGTZL */ 16442 DIP("bgtzl r%d, %d", rs, imm); 16443 if (mode64) 16444 lastn = dis_branch_likely(binop(Iop_CmpLE64S, getIReg(rs), 16445 mkU64(0x00)), imm); 16446 else 16447 lastn = dis_branch_likely(binop(Iop_CmpLE32S, getIReg(rs), 16448 mkU32(0x00)), imm); 16449 break; 16450 16451 case 0x06: /* BLEZ */ 16452 DIP("blez r%d, %d", rs, imm); 16453 if (mode64) 16454 dis_branch(False, binop(Iop_CmpLE64S, getIReg(rs), mkU64(0x0)), 16455 imm, &bstmt); 16456 else 16457 dis_branch(False,binop(Iop_CmpLE32S, getIReg(rs), mkU32(0x0)), imm, 16458 &bstmt); 16459 break; 16460 16461 case 0x16: /* BLEZL */ 16462 DIP("blezl r%d, %d", rs, imm); 16463 lastn = dis_branch_likely(unop(Iop_Not1, (binop(mode64 ? Iop_CmpLE64S : 16464 Iop_CmpLE32S, getIReg(rs), mode64 ? 16465 mkU64(0x0) : mkU32(0x0)))), imm); 16466 break; 16467 16468 case 0x08: { /* ADDI */ 16469 DIP("addi r%d, r%d, %d", rt, rs, imm); 16470 IRTemp tmpRs32 = newTemp(Ity_I32); 16471 assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); 16472 16473 t0 = newTemp(Ity_I32); 16474 t1 = newTemp(Ity_I32); 16475 t2 = newTemp(Ity_I32); 16476 t3 = newTemp(Ity_I32); 16477 t4 = newTemp(Ity_I32); 16478 /* dst = src0 + sign(imm) 16479 if(sign(src0 ) != sign(imm )) 16480 goto no overflow; 16481 if(sign(dst) == sign(src0 )) 16482 goto no overflow; 16483 we have overflow! */ 16484 16485 assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), 16486 mkU32(extend_s_16to32(imm)))); 16487 assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), 16488 mkU32(extend_s_16to32(imm)))); 16489 assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32, 16490 mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000)))); 16491 16492 assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32))); 16493 assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32, 16494 mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000)))); 16495 16496 stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2), 16497 mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf, 16498 mode64 ? IRConst_U64(guest_PC_curr_instr + 4) : 16499 IRConst_U32(guest_PC_curr_instr + 4), 16500 OFFB_PC)); 16501 16502 putIReg(rt, mkWidenFrom32(ty, mkexpr(t0), True)); 16503 break; 16504 } 16505 case 0x09: /* ADDIU */ 16506 DIP("addiu r%d, r%d, %d", rt, rs, imm); 16507 if (mode64) { 16508 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Add32, 16509 mkNarrowTo32(ty, getIReg(rs)),mkU32(extend_s_16to32(imm))), 16510 True)); 16511 } else 16512 putIReg(rt, binop(Iop_Add32, getIReg(rs),mkU32(extend_s_16to32(imm)))); 16513 break; 16514 16515 case 0x0C: /* ANDI */ 16516 DIP("andi r%d, r%d, %d", rt, rs, imm); 16517 if (mode64) { 16518 ALUI_PATTERN64(Iop_And64); 16519 } else { 16520 ALUI_PATTERN(Iop_And32); 16521 } 16522 break; 16523 16524 case 0x0E: /* XORI */ 16525 DIP("xori r%d, r%d, %d", rt, rs, imm); 16526 if (mode64) { 16527 ALUI_PATTERN64(Iop_Xor64); 16528 } else { 16529 ALUI_PATTERN(Iop_Xor32); 16530 } 16531 break; 16532 16533 case 0x0D: /* ORI */ 16534 DIP("ori r%d, r%d, %d", rt, rs, imm); 16535 if (mode64) { 16536 ALUI_PATTERN64(Iop_Or64); 16537 } else { 16538 ALUI_PATTERN(Iop_Or32); 16539 } 16540 break; 16541 16542 case 0x0A: /* SLTI */ 16543 DIP("slti r%d, r%d, %d", rt, rs, imm); 16544 if (mode64) 16545 putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs), 16546 mkU64(extend_s_16to64(imm))))); 16547 else 16548 putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs), 16549 mkU32(extend_s_16to32(imm))))); 16550 break; 16551 16552 case 0x0B: /* SLTIU */ 16553 DIP("sltiu r%d, r%d, %d", rt, rs, imm); 16554 if (mode64) 16555 putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs), 16556 mkU64(extend_s_16to64(imm))))); 16557 else 16558 putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs), 16559 mkU32(extend_s_16to32(imm))))); 16560 break; 16561 16562 case 0x18: { /* Doubleword Add Immidiate - DADD; MIPS64 */ 16563 DIP("daddi r%d, r%d, %d", rt, rs, imm); 16564 IRTemp tmpRs64 = newTemp(Ity_I64); 16565 assign(tmpRs64, getIReg(rs)); 16566 16567 t0 = newTemp(Ity_I64); 16568 t1 = newTemp(Ity_I64); 16569 t2 = newTemp(Ity_I64); 16570 t3 = newTemp(Ity_I64); 16571 t4 = newTemp(Ity_I64); 16572 /* dst = src0 + sign(imm) 16573 if(sign(src0 ) != sign(imm )) 16574 goto no overflow; 16575 if(sign(dst) == sign(src0 )) 16576 goto no overflow; 16577 we have overflow! */ 16578 16579 assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), 16580 mkU64(extend_s_16to64(imm)))); 16581 assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), 16582 mkU64(extend_s_16to64(imm)))); 16583 assign(t2, unop(Iop_1Sto64, binop(Iop_CmpEQ64, binop(Iop_And64, 16584 mkexpr(t1), mkU64(0x8000000000000000ULL)), 16585 mkU64(0x8000000000000000ULL)))); 16586 16587 assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64))); 16588 assign(t4, unop(Iop_1Sto64, binop(Iop_CmpNE64, binop(Iop_And64, 16589 mkexpr(t3), mkU64(0x8000000000000000ULL)), 16590 mkU64(0x8000000000000000ULL)))); 16591 16592 stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2), 16593 mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf, 16594 IRConst_U64(guest_PC_curr_instr + 4), 16595 OFFB_PC)); 16596 16597 putIReg(rt, mkexpr(t0)); 16598 break; 16599 } 16600 16601 case 0x19: /* Doubleword Add Immidiate Unsigned - DADDIU; MIPS64 */ 16602 DIP("daddiu r%d, r%d, %d", rt, rs, imm); 16603 putIReg(rt, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 16604 break; 16605 16606 case 0x1A: { 16607 /* Load Doubleword Left - LDL; MIPS64 */ 16608 vassert(mode64); 16609 DIP("ldl r%u, %d(r%u)", rt, imm, rs); 16610 /* t1 = addr */ 16611 #if defined (_MIPSEL) 16612 t1 = newTemp(Ity_I64); 16613 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 16614 #elif defined (_MIPSEB) 16615 t1 = newTemp(Ity_I64); 16616 assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs), 16617 mkU64(extend_s_16to64(imm))))); 16618 #endif 16619 /* t2 = word addr */ 16620 /* t4 = addr mod 8 */ 16621 LWX_SWX_PATTERN64_1; 16622 16623 /* t3 = word content - shifted */ 16624 t3 = newTemp(Ity_I64); 16625 assign(t3, binop(Iop_Shl64, load(Ity_I64, mkexpr(t2)), 16626 narrowTo(Ity_I8, binop(Iop_Shl64, binop(Iop_Sub64, mkU64(0x07), 16627 mkexpr(t4)), mkU8(3))))); 16628 16629 /* rt content - adjusted */ 16630 t5 = newTemp(Ity_I64); 16631 t6 = newTemp(Ity_I64); 16632 t7 = newTemp(Ity_I64); 16633 16634 assign(t5, binop(Iop_Mul64, mkexpr(t4), mkU64(0x8))); 16635 16636 assign(t6, binop(Iop_Shr64, mkU64(0x00FFFFFFFFFFFFFFULL), 16637 narrowTo(Ity_I8, mkexpr(t5)))); 16638 16639 assign(t7, binop(Iop_And64, getIReg(rt), mkexpr(t6))); 16640 16641 putIReg(rt, binop(Iop_Or64, mkexpr(t7), mkexpr(t3))); 16642 break; 16643 } 16644 16645 case 0x1B: { 16646 /* Load Doubleword Right - LDR; MIPS64 */ 16647 vassert(mode64); 16648 DIP("ldr r%u,%d(r%u)", rt, imm, rs); 16649 /* t1 = addr */ 16650 #if defined (_MIPSEL) 16651 t1 = newTemp(Ity_I64); 16652 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 16653 #elif defined (_MIPSEB) 16654 t1 = newTemp(Ity_I64); 16655 assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs), 16656 mkU64(extend_s_16to64(imm))))); 16657 #endif 16658 /* t2 = word addr */ 16659 /* t4 = addr mod 8 */ 16660 LWX_SWX_PATTERN64_1; 16661 16662 /* t3 = word content - shifted */ 16663 t3 = newTemp(Ity_I64); 16664 assign(t3, binop(Iop_Shr64, load(Ity_I64, mkexpr(t2)), 16665 narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(3))))); 16666 16667 /* rt content - adjusted */ 16668 t5 = newTemp(Ity_I64); 16669 assign(t5, binop(Iop_And64, getIReg(rt), unop(Iop_Not64, 16670 binop(Iop_Shr64, mkU64(0xFFFFFFFFFFFFFFFFULL), 16671 narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(0x3))))))); 16672 16673 putIReg(rt, binop(Iop_Or64, mkexpr(t5), mkexpr(t3))); 16674 break; 16675 } 16676 16677 case 0x27: /* Load Word unsigned - LWU; MIPS64 */ 16678 DIP("lwu r%u,%d(r%u)", rt, imm, rs); 16679 LOAD_STORE_PATTERN; 16680 16681 putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), False)); 16682 break; 16683 16684 case 0x30: /* LL / LWC0 */ 16685 DIP("ll r%d, %d(r%d)", rt, imm, rs); 16686 LOAD_STORE_PATTERN; 16687 16688 t2 = newTemp(Ity_I32); 16689 #if defined (_MIPSEL) 16690 stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ )); 16691 #elif defined (_MIPSEB) 16692 stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ )); 16693 #endif 16694 if (mode64) 16695 putIReg(rt, unop(Iop_32Sto64, mkexpr(t2))); 16696 else 16697 putIReg(rt, mkexpr(t2)); 16698 break; 16699 16700 case 0x34: /* Load Linked Doubleword - LLD; MIPS64 */ 16701 DIP("lld r%d, %d(r%d)", rt, imm, rs); 16702 LOAD_STORE_PATTERN; 16703 16704 t2 = newTemp(Ity_I64); 16705 #if defined (_MIPSEL) 16706 stmt(IRStmt_LLSC 16707 (Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ )); 16708 #elif defined (_MIPSEB) 16709 stmt(IRStmt_LLSC 16710 (Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ )); 16711 #endif 16712 16713 putIReg(rt, mkexpr(t2)); 16714 break; 16715 16716 case 0x38: /* SC / SWC0 */ 16717 DIP("sc r%d, %d(r%d)", rt, imm, rs); 16718 LOAD_STORE_PATTERN; 16719 16720 t2 = newTemp(Ity_I1); 16721 #if defined (_MIPSEL) 16722 stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt)))); 16723 #elif defined (_MIPSEB) 16724 stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt)))); 16725 #endif 16726 16727 putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32, mkexpr(t2))); 16728 break; 16729 16730 case 0x3C: /* Store Conditional Doubleword - SCD; MIPS64 */ 16731 DIP("sdc r%d, %d(r%d)", rt, imm, rs); 16732 LOAD_STORE_PATTERN; 16733 16734 t2 = newTemp(Ity_I1); 16735 #if defined (_MIPSEL) 16736 stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), getIReg(rt))); 16737 #elif defined (_MIPSEB) 16738 stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), getIReg(rt))); 16739 #endif 16740 16741 putIReg(rt, unop(Iop_1Uto64, mkexpr(t2))); 16742 break; 16743 16744 case 0x37: /* Load Doubleword - LD; MIPS64 */ 16745 DIP("ld r%u, %d(r%u)", rt, imm, rs); 16746 LOAD_STORE_PATTERN; 16747 putIReg(rt, load(Ity_I64, mkexpr(t1))); 16748 break; 16749 16750 case 0x3F: /* Store Doubleword - SD; MIPS64 */ 16751 DIP("sd r%u, %d(r%u)", rt, imm, rs); 16752 LOAD_STORE_PATTERN; 16753 store(mkexpr(t1), getIReg(rt)); 16754 break; 16755 16756 decode_failure_dsp: 16757 vex_printf("Error occured while trying to decode MIPS32 DSP " 16758 "instruction.\nYour platform probably doesn't support " 16759 "MIPS32 DSP ASE.\n"); 16760 decode_failure: 16761 /* All decode failures end up here. */ 16762 if (sigill_diag) 16763 vex_printf("vex mips->IR: unhandled instruction bytes: " 16764 "0x%x 0x%x 0x%x 0x%x\n", 16765 (Int) getIByte(delta_start + 0), 16766 (Int) getIByte(delta_start + 1), 16767 (Int) getIByte(delta_start + 2), 16768 (Int) getIByte(delta_start + 3)); 16769 16770 /* Tell the dispatcher that this insn cannot be decoded, and so has 16771 not been executed, and (is currently) the next to be executed. 16772 EIP should be up-to-date since it made so at the start bnezof each 16773 insn, but nevertheless be paranoid and update it again right 16774 now. */ 16775 if (mode64) { 16776 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_PC), 16777 mkU64(guest_PC_curr_instr))); 16778 jmp_lit64(&dres, Ijk_NoDecode, guest_PC_curr_instr); 16779 } else { 16780 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_PC), 16781 mkU32(guest_PC_curr_instr))); 16782 jmp_lit32(&dres, Ijk_NoDecode, guest_PC_curr_instr); 16783 } 16784 dres.whatNext = Dis_StopHere; 16785 dres.len = 0; 16786 return dres; 16787 } /* switch (opc) for the main (primary) opcode switch. */ 16788 16789 /* All MIPS insn have 4 bytes */ 16790 16791 if (delay_slot_branch) { 16792 delay_slot_branch = False; 16793 stmt(bstmt); 16794 bstmt = NULL; 16795 if (mode64) 16796 putPC(mkU64(guest_PC_curr_instr + 4)); 16797 else 16798 putPC(mkU32(guest_PC_curr_instr + 4)); 16799 dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ? 16800 Ijk_Call : Ijk_Boring; 16801 } 16802 16803 if (likely_delay_slot) { 16804 dres.jk_StopHere = Ijk_Boring; 16805 dres.whatNext = Dis_StopHere; 16806 putPC(lastn); 16807 lastn = NULL; 16808 } 16809 if (delay_slot_jump) { 16810 putPC(lastn); 16811 lastn = NULL; 16812 dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ? 16813 Ijk_Call : Ijk_Boring; 16814 } 16815 16816 decode_success: 16817 /* All decode successes end up here. */ 16818 switch (dres.whatNext) { 16819 case Dis_Continue: 16820 if (mode64) 16821 putPC(mkU64(guest_PC_curr_instr + 4)); 16822 else 16823 putPC(mkU32(guest_PC_curr_instr + 4)); 16824 break; 16825 case Dis_ResteerU: 16826 case Dis_ResteerC: 16827 putPC(mkU32(dres.continueAt)); 16828 break; 16829 case Dis_StopHere: 16830 break; 16831 default: 16832 vassert(0); 16833 break; 16834 } 16835 16836 /* On MIPS we need to check if the last instruction in block is branch or 16837 jump. */ 16838 if (((vex_control.guest_max_insns - 1) == (delta + 4) / 4) 16839 && (dres.whatNext != Dis_StopHere)) 16840 if (branch_or_jump(guest_code + delta + 4)) { 16841 dres.whatNext = Dis_StopHere; 16842 dres.jk_StopHere = Ijk_Boring; 16843 if (mode64) 16844 putPC(mkU64(guest_PC_curr_instr + 4)); 16845 else 16846 putPC(mkU32(guest_PC_curr_instr + 4)); 16847 } 16848 dres.len = 4; 16849 16850 DIP("\n"); 16851 16852 return dres; 16853 16854 } 16855 16856 /*------------------------------------------------------------*/ 16857 /*--- Top-level fn ---*/ 16858 /*------------------------------------------------------------*/ 16859 16860 /* Disassemble a single instruction into IR. The instruction 16861 is located in host memory at &guest_code[delta]. */ 16862 DisResult disInstr_MIPS( IRSB* irsb_IN, 16863 Bool (*resteerOkFn) ( void *, Addr64 ), 16864 Bool resteerCisOk, 16865 void* callback_opaque, 16866 UChar* guest_code_IN, 16867 Long delta, 16868 Addr64 guest_IP, 16869 VexArch guest_arch, 16870 VexArchInfo* archinfo, 16871 VexAbiInfo* abiinfo, 16872 Bool host_bigendian_IN, 16873 Bool sigill_diag_IN ) 16874 { 16875 DisResult dres; 16876 /* Set globals (see top of this file) */ 16877 vassert(guest_arch == VexArchMIPS32 || guest_arch == VexArchMIPS64); 16878 16879 mode64 = guest_arch != VexArchMIPS32; 16880 #if (__mips_fpr==64) 16881 fp_mode64 = ((VEX_MIPS_REV(archinfo->hwcaps) == VEX_PRID_CPU_32FPR) 16882 || guest_arch == VexArchMIPS64); 16883 #endif 16884 16885 guest_code = guest_code_IN; 16886 irsb = irsb_IN; 16887 host_is_bigendian = host_bigendian_IN; 16888 #if defined(VGP_mips32_linux) 16889 guest_PC_curr_instr = (Addr32)guest_IP; 16890 #elif defined(VGP_mips64_linux) 16891 guest_PC_curr_instr = (Addr64)guest_IP; 16892 #endif 16893 16894 dres = disInstr_MIPS_WRK(resteerOkFn, resteerCisOk, callback_opaque, 16895 delta, archinfo, abiinfo, sigill_diag_IN); 16896 16897 return dres; 16898 } 16899 16900 /*--------------------------------------------------------------------*/ 16901 /*--- end guest_mips_toIR.c ---*/ 16902 /*--------------------------------------------------------------------*/ 16903