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: what is the host's endianness? This has to do with float vs 53 double register accesses on VFP, but it's complex and not properly 54 thought out. */ 55 static VexEndness host_endness; 56 57 /* Pointer to the guest code area. */ 58 static const 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(const 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(const 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 /* Cavium Specific instructions. */ 778 if (opcode == 0x32 || opcode == 0x3A || opcode == 0x36 || opcode == 0x3E) { 779 /* BBIT0, BBIT1, BBIT032, BBIT132 */ 780 return True; 781 } 782 783 return False; 784 } 785 786 static Bool is_Branch_or_Jump_and_Link(const UChar * addr) 787 { 788 UInt cins = getUInt(addr); 789 790 UInt opcode = get_opcode(cins); 791 UInt rt = get_rt(cins); 792 UInt function = get_function(cins); 793 794 /* jal */ 795 if (opcode == 0x02) { 796 return True; 797 } 798 799 /* bgezal */ 800 if (opcode == 0x01 && rt == 0x11) { 801 return True; 802 } 803 804 /* bltzal */ 805 if (opcode == 0x01 && rt == 0x10) { 806 return True; 807 } 808 809 /* jalr */ 810 if (opcode == 0x00 && function == 0x09) { 811 return True; 812 } 813 814 return False; 815 } 816 817 static Bool branch_or_link_likely(const UChar * addr) 818 { 819 UInt cins = getUInt(addr); 820 UInt opcode = get_opcode(cins); 821 UInt rt = get_rt(cins); 822 823 /* bgtzl, blezl, bnel, beql */ 824 if (opcode == 0x17 || opcode == 0x16 || opcode == 0x15 || opcode == 0x14) 825 return True; 826 827 /* bgezl */ 828 if (opcode == 0x01 && rt == 0x03) 829 return True; 830 831 /* bgezall */ 832 if (opcode == 0x01 && rt == 0x13) 833 return True; 834 835 /* bltzall */ 836 if (opcode == 0x01 && rt == 0x12) 837 return True; 838 839 /* bltzl */ 840 if (opcode == 0x01 && rt == 0x02) 841 return True; 842 843 return False; 844 } 845 846 /*------------------------------------------------------------*/ 847 /*--- Helper bits and pieces for creating IR fragments. ---*/ 848 /*------------------------------------------------------------*/ 849 850 static IRExpr *mkU8(UInt i) 851 { 852 vassert(i < 256); 853 return IRExpr_Const(IRConst_U8((UChar) i)); 854 } 855 856 /* Create an expression node for a 16-bit integer constant. */ 857 static IRExpr *mkU16(UInt i) 858 { 859 return IRExpr_Const(IRConst_U16(i)); 860 } 861 862 /* Create an expression node for a 32-bit integer constant. */ 863 static IRExpr *mkU32(UInt i) 864 { 865 return IRExpr_Const(IRConst_U32(i)); 866 } 867 868 /* Create an expression node for a 64-bit integer constant. */ 869 static IRExpr *mkU64(ULong i) 870 { 871 return IRExpr_Const(IRConst_U64(i)); 872 } 873 874 static IRExpr *mkexpr(IRTemp tmp) 875 { 876 return IRExpr_RdTmp(tmp); 877 } 878 879 static IRExpr *unop(IROp op, IRExpr * a) 880 { 881 return IRExpr_Unop(op, a); 882 } 883 884 static IRExpr *binop(IROp op, IRExpr * a1, IRExpr * a2) 885 { 886 return IRExpr_Binop(op, a1, a2); 887 } 888 889 static IRExpr *triop(IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3) 890 { 891 return IRExpr_Triop(op, a1, a2, a3); 892 } 893 894 static IRExpr *qop ( IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3, 895 IRExpr * a4 ) 896 { 897 return IRExpr_Qop(op, a1, a2, a3, a4); 898 } 899 900 static IRExpr *load(IRType ty, IRExpr * addr) 901 { 902 IRExpr *load1 = NULL; 903 #if defined (_MIPSEL) 904 load1 = IRExpr_Load(Iend_LE, ty, addr); 905 #elif defined (_MIPSEB) 906 load1 = IRExpr_Load(Iend_BE, ty, addr); 907 #endif 908 return load1; 909 } 910 911 /* Add a statement to the list held by "irsb". */ 912 static void stmt(IRStmt * st) 913 { 914 addStmtToIRSB(irsb, st); 915 } 916 917 static void assign(IRTemp dst, IRExpr * e) 918 { 919 stmt(IRStmt_WrTmp(dst, e)); 920 } 921 922 static void store(IRExpr * addr, IRExpr * data) 923 { 924 #if defined (_MIPSEL) 925 stmt(IRStmt_Store(Iend_LE, addr, data)); 926 #elif defined (_MIPSEB) 927 stmt(IRStmt_Store(Iend_BE, addr, data)); 928 #endif 929 } 930 931 /* Generate a new temporary of the given type. */ 932 static IRTemp newTemp(IRType ty) 933 { 934 vassert(isPlausibleIRType(ty)); 935 return newIRTemp(irsb->tyenv, ty); 936 } 937 938 /* Generate an expression for SRC rotated right by ROT. */ 939 static IRExpr *genROR32(IRExpr * src, Int rot) 940 { 941 vassert(rot >= 0 && rot < 32); 942 if (rot == 0) 943 return src; 944 return binop(Iop_Or32, binop(Iop_Shl32, src, mkU8(32 - rot)), 945 binop(Iop_Shr32, src, mkU8(rot))); 946 } 947 948 static IRExpr *genRORV32(IRExpr * src, IRExpr * rs) 949 { 950 IRTemp t0 = newTemp(Ity_I8); 951 IRTemp t1 = newTemp(Ity_I8); 952 953 assign(t0, unop(Iop_32to8, binop(Iop_And32, rs, mkU32(0x0000001F)))); 954 assign(t1, binop(Iop_Sub8, mkU8(32), mkexpr(t0))); 955 return binop(Iop_Or32, binop(Iop_Shl32, src, mkexpr(t1)), 956 binop(Iop_Shr32, src, mkexpr(t0))); 957 } 958 959 static UShort extend_s_10to16(UInt x) 960 { 961 return (UShort) ((((Int) x) << 22) >> 22); 962 } 963 964 static ULong extend_s_10to32(UInt x) 965 { 966 return (ULong)((((Long) x) << 22) >> 22); 967 } 968 969 static ULong extend_s_10to64(UInt x) 970 { 971 return (ULong)((((Long) x) << 54) >> 54); 972 } 973 974 static UInt extend_s_16to32(UInt x) 975 { 976 return (UInt) ((((Int) x) << 16) >> 16); 977 } 978 979 static UInt extend_s_18to32(UInt x) 980 { 981 return (UInt) ((((Int) x) << 14) >> 14); 982 } 983 984 static ULong extend_s_16to64 ( UInt x ) 985 { 986 return (ULong) ((((Long) x) << 48) >> 48); 987 } 988 989 static ULong extend_s_18to64 ( UInt x ) 990 { 991 return (ULong) ((((Long) x) << 46) >> 46); 992 } 993 994 static ULong extend_s_32to64 ( UInt x ) 995 { 996 return (ULong) ((((Long) x) << 32) >> 32); 997 } 998 999 static void jmp_lit32 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr32 d32 ) 1000 { 1001 vassert(dres->whatNext == Dis_Continue); 1002 vassert(dres->len == 0); 1003 vassert(dres->continueAt == 0); 1004 vassert(dres->jk_StopHere == Ijk_INVALID); 1005 dres->whatNext = Dis_StopHere; 1006 dres->jk_StopHere = kind; 1007 stmt( IRStmt_Put( OFFB_PC, mkU32(d32) ) ); 1008 } 1009 1010 static void jmp_lit64 ( /*MOD*/ DisResult* dres, IRJumpKind kind, Addr64 d64 ) 1011 { 1012 vassert(dres->whatNext == Dis_Continue); 1013 vassert(dres->len == 0); 1014 vassert(dres->continueAt == 0); 1015 vassert(dres->jk_StopHere == Ijk_INVALID); 1016 dres->whatNext = Dis_StopHere; 1017 dres->jk_StopHere = kind; 1018 stmt(IRStmt_Put(OFFB_PC, mkU64(d64))); 1019 } 1020 1021 /* Get value from accumulator (helper function for MIPS32 DSP ASE instructions). 1022 This function should be called before any other operation if widening 1023 multiplications are used. */ 1024 static IRExpr *getAcc(UInt acNo) 1025 { 1026 vassert(!mode64); 1027 vassert(acNo <= 3); 1028 return IRExpr_Get(accumulatorGuestRegOffset(acNo), Ity_I64); 1029 } 1030 1031 /* Get value from DSPControl register (helper function for MIPS32 DSP ASE 1032 instructions). */ 1033 static IRExpr *getDSPControl(void) 1034 { 1035 vassert(!mode64); 1036 return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_DSPControl), Ity_I32); 1037 } 1038 1039 /* Put value to DSPControl register. Expression e is written to DSPControl as 1040 is. If only certain bits of DSPControl need to be changed, it should be done 1041 before calling putDSPControl(). It could be done by reading DSPControl and 1042 ORing it with appropriate mask. */ 1043 static void putDSPControl(IRExpr * e) 1044 { 1045 vassert(!mode64); 1046 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_DSPControl), e)); 1047 } 1048 1049 /* Fetch a byte from the guest insn stream. */ 1050 static UChar getIByte(Int delta) 1051 { 1052 return guest_code[delta]; 1053 } 1054 1055 static IRExpr *getIReg(UInt iregNo) 1056 { 1057 if (0 == iregNo) { 1058 return mode64 ? mkU64(0x0) : mkU32(0x0); 1059 } else { 1060 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1061 vassert(iregNo < 32); 1062 return IRExpr_Get(integerGuestRegOffset(iregNo), ty); 1063 } 1064 } 1065 1066 static IRExpr *getHI(void) 1067 { 1068 if (mode64) 1069 return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_HI), Ity_I64); 1070 else 1071 return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_HI), Ity_I32); 1072 } 1073 1074 static IRExpr *getLO(void) 1075 { 1076 if (mode64) 1077 return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LO), Ity_I64); 1078 else 1079 return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LO), Ity_I32); 1080 } 1081 1082 static IRExpr *getFCSR(void) 1083 { 1084 if (mode64) 1085 return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_FCSR), Ity_I32); 1086 else 1087 return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_FCSR), Ity_I32); 1088 } 1089 1090 /* Get byte from register reg, byte pos from 0 to 3 (or 7 for MIPS64) . */ 1091 static IRExpr *getByteFromReg(UInt reg, UInt byte_pos) 1092 { 1093 UInt pos = byte_pos * 8; 1094 if (mode64) 1095 return unop(Iop_64to8, binop(Iop_And64, 1096 binop(Iop_Shr64, getIReg(reg), mkU8(pos)), 1097 mkU64(0xFF))); 1098 else 1099 return unop(Iop_32to8, binop(Iop_And32, 1100 binop(Iop_Shr32, getIReg(reg), mkU8(pos)), 1101 mkU32(0xFF))); 1102 } 1103 1104 static void putFCSR(IRExpr * e) 1105 { 1106 if (mode64) 1107 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_FCSR), e)); 1108 else 1109 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_FCSR), e)); 1110 } 1111 1112 /* fs - fpu source register number. 1113 inst - fpu instruction that needs to be executed. 1114 sz32 - size of source register. 1115 opN - number of operads: 1116 1 - unary operation. 1117 2 - binary operation. */ 1118 static void calculateFCSR(UInt fs, UInt ft, UInt inst, Bool sz32, UInt opN) 1119 { 1120 IRDirty *d; 1121 IRTemp fcsr = newTemp(Ity_I32); 1122 /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper. */ 1123 if (fp_mode64) 1124 d = unsafeIRDirty_1_N(fcsr, 0, 1125 "mips_dirtyhelper_calculate_FCSR_fp64", 1126 &mips_dirtyhelper_calculate_FCSR_fp64, 1127 mkIRExprVec_4(IRExpr_BBPTR(), 1128 mkU32(fs), 1129 mkU32(ft), 1130 mkU32(inst))); 1131 else 1132 d = unsafeIRDirty_1_N(fcsr, 0, 1133 "mips_dirtyhelper_calculate_FCSR_fp32", 1134 &mips_dirtyhelper_calculate_FCSR_fp32, 1135 mkIRExprVec_4(IRExpr_BBPTR(), 1136 mkU32(fs), 1137 mkU32(ft), 1138 mkU32(inst))); 1139 1140 if (opN == 1) { /* Unary operation. */ 1141 /* Declare we're reading guest state. */ 1142 if (sz32 || fp_mode64) 1143 d->nFxState = 2; 1144 else 1145 d->nFxState = 3; 1146 vex_bzero(&d->fxState, sizeof(d->fxState)); 1147 1148 d->fxState[0].fx = Ifx_Read; /* read */ 1149 if (mode64) 1150 d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR); 1151 else 1152 d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR); 1153 d->fxState[0].size = sizeof(UInt); 1154 d->fxState[1].fx = Ifx_Read; /* read */ 1155 d->fxState[1].offset = floatGuestRegOffset(fs); 1156 d->fxState[1].size = sizeof(ULong); 1157 1158 if (!(sz32 || fp_mode64)) { 1159 d->fxState[2].fx = Ifx_Read; /* read */ 1160 d->fxState[2].offset = floatGuestRegOffset(fs+1); 1161 d->fxState[2].size = sizeof(ULong); 1162 } 1163 } else if (opN == 2) { /* Binary operation. */ 1164 /* Declare we're reading guest state. */ 1165 if (sz32 || fp_mode64) 1166 d->nFxState = 3; 1167 else 1168 d->nFxState = 5; 1169 vex_bzero(&d->fxState, sizeof(d->fxState)); 1170 1171 d->fxState[0].fx = Ifx_Read; /* read */ 1172 if (mode64) 1173 d->fxState[0].offset = offsetof(VexGuestMIPS64State, guest_FCSR); 1174 else 1175 d->fxState[0].offset = offsetof(VexGuestMIPS32State, guest_FCSR); 1176 d->fxState[0].size = sizeof(UInt); 1177 d->fxState[1].fx = Ifx_Read; /* read */ 1178 d->fxState[1].offset = floatGuestRegOffset(fs); 1179 d->fxState[1].size = sizeof(ULong); 1180 d->fxState[2].fx = Ifx_Read; /* read */ 1181 d->fxState[2].offset = floatGuestRegOffset(ft); 1182 d->fxState[2].size = sizeof(ULong); 1183 1184 if (!(sz32 || fp_mode64)) { 1185 d->fxState[3].fx = Ifx_Read; /* read */ 1186 d->fxState[3].offset = floatGuestRegOffset(fs+1); 1187 d->fxState[3].size = sizeof(ULong); 1188 d->fxState[4].fx = Ifx_Read; /* read */ 1189 d->fxState[4].offset = floatGuestRegOffset(ft+1); 1190 d->fxState[4].size = sizeof(ULong); 1191 } 1192 } 1193 1194 stmt(IRStmt_Dirty(d)); 1195 1196 putFCSR(mkexpr(fcsr)); 1197 } 1198 1199 static IRExpr *getULR(void) 1200 { 1201 if (mode64) 1202 return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_ULR), Ity_I64); 1203 else 1204 return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_ULR), Ity_I32); 1205 } 1206 1207 static void putIReg(UInt archreg, IRExpr * e) 1208 { 1209 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1210 vassert(archreg < 32); 1211 vassert(typeOfIRExpr(irsb->tyenv, e) == ty); 1212 if (archreg != 0) 1213 stmt(IRStmt_Put(integerGuestRegOffset(archreg), e)); 1214 } 1215 1216 static IRExpr *mkNarrowTo32(IRType ty, IRExpr * src) 1217 { 1218 vassert(ty == Ity_I32 || ty == Ity_I64); 1219 return ty == Ity_I64 ? unop(Iop_64to32, src) : src; 1220 } 1221 1222 static void putLO(IRExpr * e) 1223 { 1224 if (mode64) { 1225 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LO), e)); 1226 } else { 1227 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LO), e)); 1228 /* Add value to lower 32 bits of ac0 to maintain compatibility between 1229 regular MIPS32 instruction set and MIPS DSP ASE. Keep higher 32bits 1230 unchanged. */ 1231 IRTemp t_lo = newTemp(Ity_I32); 1232 IRTemp t_hi = newTemp(Ity_I32); 1233 assign(t_lo, e); 1234 assign(t_hi, unop(Iop_64HIto32, getAcc(0))); 1235 stmt(IRStmt_Put(accumulatorGuestRegOffset(0), 1236 binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo)))); 1237 } 1238 } 1239 1240 static void putHI(IRExpr * e) 1241 { 1242 if (mode64) { 1243 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_HI), e)); 1244 } else { 1245 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_HI), e)); 1246 /* Add value to higher 32 bits of ac0 to maintain compatibility between 1247 regular MIPS32 instruction set and MIPS DSP ASE. Keep lower 32bits 1248 unchanged. */ 1249 IRTemp t_lo = newTemp(Ity_I32); 1250 IRTemp t_hi = newTemp(Ity_I32); 1251 assign(t_hi, e); 1252 assign(t_lo, unop(Iop_64to32, getAcc(0))); 1253 stmt(IRStmt_Put(accumulatorGuestRegOffset(0), 1254 binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo)))); 1255 } 1256 } 1257 1258 /* Put value to accumulator(helper function for MIPS32 DSP ASE instructions). */ 1259 static void putAcc(UInt acNo, IRExpr * e) 1260 { 1261 vassert(!mode64); 1262 vassert(acNo <= 3); 1263 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I64); 1264 stmt(IRStmt_Put(accumulatorGuestRegOffset(acNo), e)); 1265 /* If acNo = 0, split value to HI and LO regs in order to maintain compatibility 1266 between MIPS32 and MIPS DSP ASE insn sets. */ 1267 if (0 == acNo) { 1268 putLO(unop(Iop_64to32, e)); 1269 putHI(unop(Iop_64HIto32, e)); 1270 } 1271 } 1272 1273 static IRExpr *mkNarrowTo8 ( IRType ty, IRExpr * src ) 1274 { 1275 vassert(ty == Ity_I32 || ty == Ity_I64); 1276 return ty == Ity_I64 ? unop(Iop_64to8, src) : unop(Iop_32to8, src); 1277 } 1278 1279 static void putPC(IRExpr * e) 1280 { 1281 stmt(IRStmt_Put(OFFB_PC, e)); 1282 } 1283 1284 static IRExpr *mkWidenFrom32(IRType ty, IRExpr * src, Bool sined) 1285 { 1286 vassert(ty == Ity_I32 || ty == Ity_I64); 1287 if (ty == Ity_I32) 1288 return src; 1289 return (sined) ? unop(Iop_32Sto64, src) : unop(Iop_32Uto64, src); 1290 } 1291 1292 /* Narrow 8/16/32 bit int expr to 8/16/32. Clearly only some 1293 of these combinations make sense. */ 1294 static IRExpr *narrowTo(IRType dst_ty, IRExpr * e) 1295 { 1296 IRType src_ty = typeOfIRExpr(irsb->tyenv, e); 1297 if (src_ty == dst_ty) 1298 return e; 1299 if (src_ty == Ity_I32 && dst_ty == Ity_I16) 1300 return unop(Iop_32to16, e); 1301 if (src_ty == Ity_I32 && dst_ty == Ity_I8) 1302 return unop(Iop_32to8, e); 1303 if (src_ty == Ity_I64 && dst_ty == Ity_I8) { 1304 vassert(mode64); 1305 return unop(Iop_64to8, e); 1306 } 1307 if (src_ty == Ity_I64 && dst_ty == Ity_I16) { 1308 vassert(mode64); 1309 return unop(Iop_64to16, e); 1310 } 1311 vpanic("narrowTo(mips)"); 1312 return 0; 1313 } 1314 1315 static IRExpr *getLoFromF64(IRType ty, IRExpr * src) 1316 { 1317 vassert(ty == Ity_F32 || ty == Ity_F64); 1318 if (ty == Ity_F64) { 1319 IRTemp t0, t1; 1320 t0 = newTemp(Ity_I64); 1321 t1 = newTemp(Ity_I32); 1322 assign(t0, unop(Iop_ReinterpF64asI64, src)); 1323 assign(t1, unop(Iop_64to32, mkexpr(t0))); 1324 return unop(Iop_ReinterpI32asF32, mkexpr(t1)); 1325 } else 1326 return src; 1327 } 1328 1329 static IRExpr *mkWidenFromF32(IRType ty, IRExpr * src) 1330 { 1331 vassert(ty == Ity_F32 || ty == Ity_F64); 1332 if (ty == Ity_F64) { 1333 IRTemp t0 = newTemp(Ity_I32); 1334 IRTemp t1 = newTemp(Ity_I64); 1335 assign(t0, unop(Iop_ReinterpF32asI32, src)); 1336 assign(t1, binop(Iop_32HLto64, mkU32(0x0), mkexpr(t0))); 1337 return unop(Iop_ReinterpI64asF64, mkexpr(t1)); 1338 } else 1339 return src; 1340 } 1341 1342 static IRExpr *dis_branch_likely(IRExpr * guard, UInt imm) 1343 { 1344 ULong branch_offset; 1345 IRTemp t0; 1346 1347 /* PC = PC + (SignExtend(signed_immed_24) << 2) 1348 An 18-bit signed offset (the 16-bit offset field shifted left 2 bits) 1349 is added to the address of the instruction following 1350 the branch (not the branch itself), in the branch delay slot, to form 1351 a PC-relative effective target address. */ 1352 if (mode64) 1353 branch_offset = extend_s_18to64(imm << 2); 1354 else 1355 branch_offset = extend_s_18to32(imm << 2); 1356 1357 t0 = newTemp(Ity_I1); 1358 assign(t0, guard); 1359 1360 if (mode64) 1361 stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring, 1362 IRConst_U64(guest_PC_curr_instr + 8), OFFB_PC)); 1363 else 1364 stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring, 1365 IRConst_U32(guest_PC_curr_instr + 8), OFFB_PC)); 1366 1367 irsb->jumpkind = Ijk_Boring; 1368 1369 if (mode64) 1370 return mkU64(guest_PC_curr_instr + 4 + branch_offset); 1371 else 1372 return mkU32(guest_PC_curr_instr + 4 + branch_offset); 1373 } 1374 1375 static void dis_branch(Bool link, IRExpr * guard, UInt imm, IRStmt ** set) 1376 { 1377 ULong branch_offset; 1378 IRTemp t0; 1379 1380 if (link) { /* LR (GPR31) = addr of the 2nd instr after branch instr */ 1381 if (mode64) 1382 putIReg(31, mkU64(guest_PC_curr_instr + 8)); 1383 else 1384 putIReg(31, mkU32(guest_PC_curr_instr + 8)); 1385 } 1386 1387 /* PC = PC + (SignExtend(signed_immed_24) << 2) 1388 An 18-bit signed offset (the 16-bit offset field shifted left 2 bits) 1389 is added to the address of the instruction following 1390 the branch (not the branch itself), in the branch delay slot, to form 1391 a PC-relative effective target address. */ 1392 1393 if (mode64) 1394 branch_offset = extend_s_18to64(imm << 2); 1395 else 1396 branch_offset = extend_s_18to32(imm << 2); 1397 1398 t0 = newTemp(Ity_I1); 1399 assign(t0, guard); 1400 if (mode64) 1401 *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring, 1402 IRConst_U64(guest_PC_curr_instr + 4 + branch_offset), 1403 OFFB_PC); 1404 else 1405 *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring, 1406 IRConst_U32(guest_PC_curr_instr + 4 + 1407 (UInt) branch_offset), OFFB_PC); 1408 } 1409 1410 static IRExpr *getFReg(UInt fregNo) 1411 { 1412 vassert(fregNo < 32); 1413 IRType ty = fp_mode64 ? Ity_F64 : Ity_F32; 1414 return IRExpr_Get(floatGuestRegOffset(fregNo), ty); 1415 } 1416 1417 static IRExpr *getDReg(UInt dregNo) 1418 { 1419 vassert(dregNo < 32); 1420 if (fp_mode64) { 1421 return IRExpr_Get(floatGuestRegOffset(dregNo), Ity_F64); 1422 } else { 1423 /* Read a floating point register pair and combine their contents into a 1424 64-bit value */ 1425 IRTemp t0 = newTemp(Ity_F32); 1426 IRTemp t1 = newTemp(Ity_F32); 1427 IRTemp t2 = newTemp(Ity_F64); 1428 IRTemp t3 = newTemp(Ity_I32); 1429 IRTemp t4 = newTemp(Ity_I32); 1430 IRTemp t5 = newTemp(Ity_I64); 1431 1432 assign(t0, getFReg(dregNo)); 1433 assign(t1, getFReg(dregNo + 1)); 1434 1435 assign(t3, unop(Iop_ReinterpF32asI32, mkexpr(t0))); 1436 assign(t4, unop(Iop_ReinterpF32asI32, mkexpr(t1))); 1437 assign(t5, binop(Iop_32HLto64, mkexpr(t4), mkexpr(t3))); 1438 assign(t2, unop(Iop_ReinterpI64asF64, mkexpr(t5))); 1439 1440 return mkexpr(t2); 1441 } 1442 } 1443 1444 static void putFReg(UInt dregNo, IRExpr * e) 1445 { 1446 vassert(dregNo < 32); 1447 IRType ty = fp_mode64 ? Ity_F64 : Ity_F32; 1448 vassert(typeOfIRExpr(irsb->tyenv, e) == ty); 1449 stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e)); 1450 } 1451 1452 static void putDReg(UInt dregNo, IRExpr * e) 1453 { 1454 if (fp_mode64) { 1455 vassert(dregNo < 32); 1456 IRType ty = Ity_F64; 1457 vassert(typeOfIRExpr(irsb->tyenv, e) == ty); 1458 stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e)); 1459 } else { 1460 vassert(dregNo < 32); 1461 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F64); 1462 IRTemp t1 = newTemp(Ity_F64); 1463 IRTemp t4 = newTemp(Ity_I32); 1464 IRTemp t5 = newTemp(Ity_I32); 1465 IRTemp t6 = newTemp(Ity_I64); 1466 assign(t1, e); 1467 assign(t6, unop(Iop_ReinterpF64asI64, mkexpr(t1))); 1468 assign(t4, unop(Iop_64HIto32, mkexpr(t6))); /* hi */ 1469 assign(t5, unop(Iop_64to32, mkexpr(t6))); /* lo */ 1470 putFReg(dregNo, unop(Iop_ReinterpI32asF32, mkexpr(t5))); 1471 putFReg(dregNo + 1, unop(Iop_ReinterpI32asF32, mkexpr(t4))); 1472 } 1473 } 1474 1475 static void setFPUCondCode(IRExpr * e, UInt cc) 1476 { 1477 if (cc == 0) { 1478 putFCSR(binop(Iop_And32, getFCSR(), mkU32(0xFF7FFFFF))); 1479 putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(23)))); 1480 } else { 1481 putFCSR(binop(Iop_And32, getFCSR(), unop(Iop_Not32, 1482 binop(Iop_Shl32, mkU32(0x01000000), mkU8(cc))))); 1483 putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(24 + cc)))); 1484 } 1485 } 1486 1487 static IRExpr* get_IR_roundingmode ( void ) 1488 { 1489 /* 1490 rounding mode | MIPS | IR 1491 ------------------------ 1492 to nearest | 00 | 00 1493 to zero | 01 | 11 1494 to +infinity | 10 | 10 1495 to -infinity | 11 | 01 1496 */ 1497 IRTemp rm_MIPS = newTemp(Ity_I32); 1498 /* Last two bits in FCSR are rounding mode. */ 1499 1500 if (mode64) 1501 assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS64State, 1502 guest_FCSR), Ity_I32), mkU32(3))); 1503 else 1504 assign(rm_MIPS, binop(Iop_And32, IRExpr_Get(offsetof(VexGuestMIPS32State, 1505 guest_FCSR), Ity_I32), mkU32(3))); 1506 1507 /* rm_IR = XOR( rm_MIPS32, (rm_MIPS32 << 1) & 2) */ 1508 1509 return binop(Iop_Xor32, mkexpr(rm_MIPS), binop(Iop_And32, 1510 binop(Iop_Shl32, mkexpr(rm_MIPS), mkU8(1)), mkU32(2))); 1511 } 1512 1513 /* sz, ULong -> IRExpr */ 1514 static IRExpr *mkSzImm ( IRType ty, ULong imm64 ) 1515 { 1516 vassert(ty == Ity_I32 || ty == Ity_I64); 1517 return ty == Ity_I64 ? mkU64(imm64) : mkU32((UInt) imm64); 1518 } 1519 1520 static IRConst *mkSzConst ( IRType ty, ULong imm64 ) 1521 { 1522 vassert(ty == Ity_I32 || ty == Ity_I64); 1523 return (ty == Ity_I64 ? IRConst_U64(imm64) : IRConst_U32((UInt) imm64)); 1524 } 1525 1526 /* Make sure we get valid 32 and 64bit addresses */ 1527 static Addr64 mkSzAddr ( IRType ty, Addr64 addr ) 1528 { 1529 vassert(ty == Ity_I32 || ty == Ity_I64); 1530 return (ty == Ity_I64 ? (Addr64) addr : 1531 (Addr64) extend_s_32to64(toUInt(addr))); 1532 } 1533 1534 /* Shift and Rotate instructions for MIPS64 */ 1535 static Bool dis_instr_shrt ( UInt theInstr ) 1536 { 1537 UInt opc2 = get_function(theInstr); 1538 UChar regRs = get_rs(theInstr); 1539 UChar regRt = get_rt(theInstr); 1540 UChar regRd = get_rd(theInstr); 1541 UChar uImmsa = get_sa(theInstr); 1542 Long sImmsa = extend_s_16to64(uImmsa); 1543 IRType ty = mode64 ? Ity_I64 : Ity_I32; 1544 IRTemp tmp = newTemp(ty); 1545 IRTemp tmpOr = newTemp(ty); 1546 IRTemp tmpRt = newTemp(ty); 1547 IRTemp tmpRs = newTemp(ty); 1548 IRTemp tmpRd = newTemp(ty); 1549 1550 assign(tmpRs, getIReg(regRs)); 1551 assign(tmpRt, getIReg(regRt)); 1552 1553 switch (opc2) { 1554 case 0x3A: 1555 if ((regRs & 0x01) == 0) { 1556 /* Doubleword Shift Right Logical - DSRL; MIPS64 */ 1557 DIP("dsrl r%u, r%u, %d", regRd, regRt, (Int)sImmsa); 1558 assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa))); 1559 putIReg(regRd, mkexpr(tmpRd)); 1560 } else if ((regRs & 0x01) == 1) { 1561 /* Doubleword Rotate Right - DROTR; MIPS64r2 */ 1562 vassert(mode64); 1563 DIP("drotr r%u, r%u, %d", regRd, regRt, (Int)sImmsa); 1564 IRTemp tmpL = newTemp(ty); 1565 IRTemp tmpR = newTemp(ty); 1566 assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa))); 1567 assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(63 - uImmsa))); 1568 assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1))); 1569 assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR))); 1570 putIReg(regRd, mkexpr(tmpRd)); 1571 } else 1572 return False; 1573 break; 1574 1575 case 0x3E: 1576 if ((regRs & 0x01) == 0) { 1577 /* Doubleword Shift Right Logical Plus 32 - DSRL32; MIPS64 */ 1578 DIP("dsrl32 r%u, r%u, %d", regRd, regRt, (Int)(sImmsa + 32)); 1579 assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32))); 1580 putIReg(regRd, mkexpr(tmpRd)); 1581 } else if ((regRs & 0x01) == 1) { 1582 /* Doubleword Rotate Right Plus 32 - DROTR32; MIPS64r2 */ 1583 DIP("drotr32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa); 1584 vassert(mode64); 1585 IRTemp tmpL = newTemp(ty); 1586 IRTemp tmpR = newTemp(ty); 1587 /* (tmpRt >> sa) | (tmpRt << (64 - sa)) */ 1588 assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(uImmsa + 32))); 1589 assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), 1590 mkU8(63 - (uImmsa + 32)))); 1591 assign(tmpL, binop(Iop_Shl64, mkexpr(tmp), mkU8(1))); 1592 assign(tmpRd, binop(Iop_Or64, mkexpr(tmpL), mkexpr(tmpR))); 1593 putIReg(regRd, mkexpr(tmpRd)); 1594 } else 1595 return False; 1596 break; 1597 1598 case 0x16: 1599 if ((uImmsa & 0x01) == 0) { 1600 /* Doubleword Shift Right Logical Variable - DSRLV; MIPS64 */ 1601 DIP("dsrlv r%u, r%u, r%u", regRd, regRt, regRs); 1602 IRTemp tmpRs8 = newTemp(Ity_I8); 1603 /* s = tmpRs[5..0] */ 1604 assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkU64(63))); 1605 assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp))); 1606 assign(tmpRd, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8))); 1607 putIReg(regRd, mkexpr(tmpRd)); 1608 } else if ((uImmsa & 0x01) == 1) { 1609 /* Doubleword Rotate Right Variable - DROTRV; MIPS64r2 */ 1610 DIP("drotrv r%u, r%u, r%u", regRd, regRt, regRs); 1611 IRTemp tmpL = newTemp(ty); 1612 IRTemp tmpR = newTemp(ty); 1613 IRTemp tmpRs8 = newTemp(Ity_I8); 1614 IRTemp tmpLs8 = newTemp(Ity_I8); 1615 IRTemp tmp64 = newTemp(ty); 1616 /* s = tmpRs[5...0] 1617 m = 64 - s 1618 (tmpRt << s) | (tmpRt >> m) */ 1619 1620 assign(tmp64, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63))); 1621 assign(tmp, binop(Iop_Sub64, mkU64(63), mkexpr(tmp64))); 1622 1623 assign(tmpLs8, mkNarrowTo8(ty, mkexpr(tmp))); 1624 assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp64))); 1625 1626 assign(tmpR, binop(Iop_Shr64, mkexpr(tmpRt), mkexpr(tmpRs8))); 1627 assign(tmpL, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpLs8))); 1628 assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpL), mkU8(1))); 1629 assign(tmpOr, binop(Iop_Or64, mkexpr(tmpRd), mkexpr(tmpR))); 1630 1631 putIReg(regRd, mkexpr(tmpOr)); 1632 } else 1633 return False; 1634 break; 1635 1636 case 0x38: /* Doubleword Shift Left Logical - DSLL; MIPS64 */ 1637 DIP("dsll r%u, r%u, %d", regRd, regRt, (Int)sImmsa); 1638 vassert(mode64); 1639 assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa))); 1640 putIReg(regRd, mkexpr(tmpRd)); 1641 break; 1642 1643 case 0x3C: /* Doubleword Shift Left Logical Plus 32 - DSLL32; MIPS64 */ 1644 DIP("dsll32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa); 1645 assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(uImmsa + 32))); 1646 putIReg(regRd, mkexpr(tmpRd)); 1647 break; 1648 1649 case 0x14: { /* Doubleword Shift Left Logical Variable - DSLLV; MIPS64 */ 1650 DIP("dsllv r%u, r%u, r%u", regRd, regRt, regRs); 1651 IRTemp tmpRs8 = newTemp(Ity_I8); 1652 1653 assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63))); 1654 assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp))); 1655 assign(tmpRd, binop(Iop_Shl64, mkexpr(tmpRt), mkexpr(tmpRs8))); 1656 putIReg(regRd, mkexpr(tmpRd)); 1657 break; 1658 } 1659 1660 case 0x3B: /* Doubleword Shift Right Arithmetic - DSRA; MIPS64 */ 1661 DIP("dsra r%u, r%u, %d", regRd, regRt, (Int)sImmsa); 1662 assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa))); 1663 putIReg(regRd, mkexpr(tmpRd)); 1664 break; 1665 1666 case 0x3F: /* Doubleword Shift Right Arithmetic Plus 32 - DSRA32; 1667 MIPS64 */ 1668 DIP("dsra32 r%u, r%u, %d", regRd, regRt, (Int)sImmsa); 1669 assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkU8(uImmsa + 32))); 1670 putIReg(regRd, mkexpr(tmpRd)); 1671 break; 1672 1673 case 0x17: { /* Doubleword Shift Right Arithmetic Variable - DSRAV; 1674 MIPS64 */ 1675 DIP("dsrav r%u, r%u, r%u", regRd, regRt, regRs); 1676 IRTemp tmpRs8 = newTemp(Ity_I8); 1677 assign(tmp, binop(Iop_And64, mkexpr(tmpRs), mkSzImm(ty, 63))); 1678 assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp))); 1679 assign(tmpRd, binop(Iop_Sar64, mkexpr(tmpRt), mkexpr(tmpRs8))); 1680 putIReg(regRd, mkexpr(tmpRd)); 1681 break; 1682 1683 } 1684 1685 default: 1686 return False; 1687 1688 } 1689 return True; 1690 } 1691 1692 static IROp mkSzOp ( IRType ty, IROp op8 ) 1693 { 1694 Int adj; 1695 vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I64); 1696 vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 || op8 == Iop_Mul8 1697 || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8 1698 || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8 1699 || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 || op8 == Iop_Not8); 1700 adj = ty == Ity_I8 ? 0 : (ty == Ity_I16 ? 1 : (ty == Ity_I32 ? 2 : 3)); 1701 return adj + op8; 1702 } 1703 1704 /*********************************************************/ 1705 /*--- Floating Point Compare ---*/ 1706 /*********************************************************/ 1707 /* Function that returns a string that represent mips cond 1708 mnemonic for the input code. */ 1709 static const HChar* showCondCode(UInt code) { 1710 const HChar* ret; 1711 switch (code) { 1712 case 0: ret = "f"; break; 1713 case 1: ret = "un"; break; 1714 case 2: ret = "eq"; break; 1715 case 3: ret = "ueq"; break; 1716 case 4: ret = "olt"; break; 1717 case 5: ret = "ult"; break; 1718 case 6: ret = "ole"; break; 1719 case 7: ret = "ule"; break; 1720 case 8: ret = "sf"; break; 1721 case 9: ret = "ngle"; break; 1722 case 10: ret = "seq"; break; 1723 case 11: ret = "ngl"; break; 1724 case 12: ret = "lt"; break; 1725 case 13: ret = "nge"; break; 1726 case 14: ret = "le"; break; 1727 case 15: ret = "ngt"; break; 1728 default: vpanic("showCondCode"); break; 1729 } 1730 return ret; 1731 } 1732 1733 static Bool dis_instr_CCondFmt ( UInt cins ) 1734 { 1735 IRTemp t0, t1, t2, t3, tmp5, tmp6; 1736 IRTemp ccIR = newTemp(Ity_I32); 1737 IRTemp ccMIPS = newTemp(Ity_I32); 1738 UInt FC = get_FC(cins); 1739 UInt fmt = get_fmt(cins); 1740 UInt fs = get_fs(cins); 1741 UInt ft = get_ft(cins); 1742 UInt cond = get_cond(cins); 1743 1744 if (FC == 0x3) { /* C.cond.fmt */ 1745 UInt fpc_cc = get_fpc_cc(cins); 1746 switch (fmt) { 1747 case 0x10: { /* C.cond.S */ 1748 DIP("c.%s.s %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft); 1749 if (fp_mode64) { 1750 t0 = newTemp(Ity_I32); 1751 t1 = newTemp(Ity_I32); 1752 t2 = newTemp(Ity_I32); 1753 t3 = newTemp(Ity_I32); 1754 1755 tmp5 = newTemp(Ity_F64); 1756 tmp6 = newTemp(Ity_F64); 1757 1758 assign(tmp5, unop(Iop_F32toF64, getLoFromF64(Ity_F64, 1759 getFReg(fs)))); 1760 assign(tmp6, unop(Iop_F32toF64, getLoFromF64(Ity_F64, 1761 getFReg(ft)))); 1762 1763 assign(ccIR, binop(Iop_CmpF64, mkexpr(tmp5), mkexpr(tmp6))); 1764 putHI(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32, 1765 mkexpr(ccIR), True)); 1766 /* Map compare result from IR to MIPS 1767 FP cmp result | MIPS | IR 1768 -------------------------- 1769 UN | 0x1 | 0x45 1770 EQ | 0x2 | 0x40 1771 GT | 0x4 | 0x00 1772 LT | 0x8 | 0x01 1773 */ 1774 1775 /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */ 1776 assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8, 1777 binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32, 1778 binop(Iop_Shr32, mkexpr(ccIR),mkU8(5))),mkU32(2)), 1779 binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR), 1780 binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))), 1781 mkU32(1)))))); 1782 putLO(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32, 1783 mkexpr(ccMIPS), True)); 1784 1785 /* UN */ 1786 assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1))); 1787 /* EQ */ 1788 assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS), 1789 mkU8(0x1)), mkU32(0x1))); 1790 /* NGT */ 1791 assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32, 1792 mkexpr(ccMIPS), mkU8(0x2))),mkU32(0x1))); 1793 /* LT */ 1794 assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS), 1795 mkU8(0x3)), mkU32(0x1))); 1796 switch (cond) { 1797 case 0x0: 1798 setFPUCondCode(mkU32(0), fpc_cc); 1799 break; 1800 case 0x1: 1801 setFPUCondCode(mkexpr(t0), fpc_cc); 1802 break; 1803 case 0x2: 1804 setFPUCondCode(mkexpr(t1), fpc_cc); 1805 break; 1806 case 0x3: 1807 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)), 1808 fpc_cc); 1809 break; 1810 case 0x4: 1811 setFPUCondCode(mkexpr(t3), fpc_cc); 1812 break; 1813 case 0x5: 1814 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)), 1815 fpc_cc); 1816 break; 1817 case 0x6: 1818 setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)), 1819 fpc_cc); 1820 break; 1821 case 0x7: 1822 setFPUCondCode(mkexpr(t2), fpc_cc); 1823 break; 1824 case 0x8: 1825 setFPUCondCode(mkU32(0), fpc_cc); 1826 break; 1827 case 0x9: 1828 setFPUCondCode(mkexpr(t0), fpc_cc); 1829 break; 1830 case 0xA: 1831 setFPUCondCode(mkexpr(t1), fpc_cc); 1832 break; 1833 case 0xB: 1834 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)), 1835 fpc_cc); 1836 break; 1837 case 0xC: 1838 setFPUCondCode(mkexpr(t3), fpc_cc); 1839 break; 1840 case 0xD: 1841 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)), 1842 fpc_cc); 1843 break; 1844 case 0xE: 1845 setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)), 1846 fpc_cc); 1847 break; 1848 case 0xF: 1849 setFPUCondCode(mkexpr(t2), fpc_cc); 1850 break; 1851 1852 default: 1853 return False; 1854 } 1855 1856 } else { 1857 t0 = newTemp(Ity_I32); 1858 t1 = newTemp(Ity_I32); 1859 t2 = newTemp(Ity_I32); 1860 t3 = newTemp(Ity_I32); 1861 1862 assign(ccIR, binop(Iop_CmpF64, unop(Iop_F32toF64, getFReg(fs)), 1863 unop(Iop_F32toF64, getFReg(ft)))); 1864 /* Map compare result from IR to MIPS 1865 FP cmp result | MIPS | IR 1866 -------------------------- 1867 UN | 0x1 | 0x45 1868 EQ | 0x2 | 0x40 1869 GT | 0x4 | 0x00 1870 LT | 0x8 | 0x01 1871 */ 1872 1873 /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */ 1874 assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8, 1875 binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32, 1876 binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))), 1877 mkU32(2)), binop(Iop_And32, 1878 binop(Iop_Xor32, mkexpr(ccIR), 1879 binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))), 1880 mkU32(1)))))); 1881 /* UN */ 1882 assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1))); 1883 /* EQ */ 1884 assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS), 1885 mkU8(0x1)), mkU32(0x1))); 1886 /* NGT */ 1887 assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32, 1888 mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1))); 1889 /* LT */ 1890 assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS), 1891 mkU8(0x3)), mkU32(0x1))); 1892 1893 switch (cond) { 1894 case 0x0: 1895 setFPUCondCode(mkU32(0), fpc_cc); 1896 break; 1897 case 0x1: 1898 setFPUCondCode(mkexpr(t0), fpc_cc); 1899 break; 1900 case 0x2: 1901 setFPUCondCode(mkexpr(t1), fpc_cc); 1902 break; 1903 case 0x3: 1904 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)), 1905 fpc_cc); 1906 break; 1907 case 0x4: 1908 setFPUCondCode(mkexpr(t3), fpc_cc); 1909 break; 1910 case 0x5: 1911 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)), 1912 fpc_cc); 1913 break; 1914 case 0x6: 1915 setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)), 1916 fpc_cc); 1917 break; 1918 case 0x7: 1919 setFPUCondCode(mkexpr(t2), fpc_cc); 1920 break; 1921 case 0x8: 1922 setFPUCondCode(mkU32(0), fpc_cc); 1923 break; 1924 case 0x9: 1925 setFPUCondCode(mkexpr(t0), fpc_cc); 1926 break; 1927 case 0xA: 1928 setFPUCondCode(mkexpr(t1), fpc_cc); 1929 break; 1930 case 0xB: 1931 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)), 1932 fpc_cc); 1933 break; 1934 case 0xC: 1935 setFPUCondCode(mkexpr(t3), fpc_cc); 1936 break; 1937 case 0xD: 1938 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)), 1939 fpc_cc); 1940 break; 1941 case 0xE: 1942 setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)), 1943 fpc_cc); 1944 break; 1945 case 0xF: 1946 setFPUCondCode(mkexpr(t2), fpc_cc); 1947 break; 1948 1949 default: 1950 return False; 1951 } 1952 } 1953 } 1954 break; 1955 1956 case 0x11: { /* C.cond.D */ 1957 DIP("c.%s.d %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft); 1958 t0 = newTemp(Ity_I32); 1959 t1 = newTemp(Ity_I32); 1960 t2 = newTemp(Ity_I32); 1961 t3 = newTemp(Ity_I32); 1962 assign(ccIR, binop(Iop_CmpF64, getDReg(fs), getDReg(ft))); 1963 /* Map compare result from IR to MIPS 1964 FP cmp result | MIPS | IR 1965 -------------------------- 1966 UN | 0x1 | 0x45 1967 EQ | 0x2 | 0x40 1968 GT | 0x4 | 0x00 1969 LT | 0x8 | 0x01 1970 */ 1971 1972 /* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */ 1973 assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8, 1974 binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32, 1975 binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))), mkU32(2)), 1976 binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR), 1977 binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))), 1978 mkU32(1)))))); 1979 1980 /* UN */ 1981 assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1))); 1982 /* EQ */ 1983 assign(t1, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS), 1984 mkU8(0x1)), mkU32(0x1))); 1985 /* NGT */ 1986 assign(t2, binop(Iop_And32, unop(Iop_Not32, binop(Iop_Shr32, 1987 mkexpr(ccMIPS), mkU8(0x2))), mkU32(0x1))); 1988 /* LT */ 1989 assign(t3, binop(Iop_And32, binop(Iop_Shr32, mkexpr(ccMIPS), 1990 mkU8(0x3)), mkU32(0x1))); 1991 1992 switch (cond) { 1993 case 0x0: 1994 setFPUCondCode(mkU32(0), fpc_cc); 1995 break; 1996 case 0x1: 1997 setFPUCondCode(mkexpr(t0), fpc_cc); 1998 break; 1999 case 0x2: 2000 setFPUCondCode(mkexpr(t1), fpc_cc); 2001 break; 2002 case 0x3: 2003 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)), 2004 fpc_cc); 2005 break; 2006 case 0x4: 2007 setFPUCondCode(mkexpr(t3), fpc_cc); 2008 break; 2009 case 0x5: 2010 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)), 2011 fpc_cc); 2012 break; 2013 case 0x6: 2014 setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)), 2015 fpc_cc); 2016 break; 2017 case 0x7: 2018 setFPUCondCode(mkexpr(t2), fpc_cc); 2019 break; 2020 case 0x8: 2021 setFPUCondCode(mkU32(0), fpc_cc); 2022 break; 2023 case 0x9: 2024 setFPUCondCode(mkexpr(t0), fpc_cc); 2025 break; 2026 case 0xA: 2027 setFPUCondCode(mkexpr(t1), fpc_cc); 2028 break; 2029 case 0xB: 2030 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t1)), 2031 fpc_cc); 2032 break; 2033 case 0xC: 2034 setFPUCondCode(mkexpr(t3), fpc_cc); 2035 break; 2036 case 0xD: 2037 setFPUCondCode(binop(Iop_Or32, mkexpr(t0), mkexpr(t3)), 2038 fpc_cc); 2039 break; 2040 case 0xE: 2041 setFPUCondCode(binop(Iop_Or32, mkexpr(t3), mkexpr(t1)), 2042 fpc_cc); 2043 break; 2044 case 0xF: 2045 setFPUCondCode(mkexpr(t2), fpc_cc); 2046 break; 2047 default: 2048 return False; 2049 } 2050 } 2051 break; 2052 2053 default: 2054 return False; 2055 } 2056 } else { 2057 return False; 2058 } 2059 2060 return True; 2061 } 2062 2063 /*********************************************************/ 2064 /*--- Branch Instructions for mips64 ---*/ 2065 /*********************************************************/ 2066 static Bool dis_instr_branch ( UInt theInstr, DisResult * dres, 2067 Bool(*resteerOkFn) (void *, Addr), 2068 void *callback_opaque, IRStmt ** set ) 2069 { 2070 UInt jmpKind = 0; 2071 UChar opc1 = get_opcode(theInstr); 2072 UChar regRs = get_rs(theInstr); 2073 UChar regRt = get_rt(theInstr); 2074 UInt offset = get_imm(theInstr); 2075 Long sOffset = extend_s_16to64(offset); 2076 IRType ty = mode64 ? Ity_I64 : Ity_I32; 2077 IROp opSlt = mode64 ? Iop_CmpLT64S : Iop_CmpLT32S; 2078 2079 IRTemp tmp = newTemp(ty); 2080 IRTemp tmpRs = newTemp(ty); 2081 IRTemp tmpRt = newTemp(ty); 2082 IRTemp tmpLt = newTemp(ty); 2083 IRTemp tmpReg0 = newTemp(ty); 2084 2085 UChar regLnk = 31; /* reg 31 is link reg in MIPS */ 2086 Addr64 addrTgt = 0; 2087 Addr64 cia = guest_PC_curr_instr; 2088 2089 IRExpr *eConst0 = mkSzImm(ty, (UInt) 0); 2090 IRExpr *eNia = mkSzImm(ty, cia + 8); 2091 IRExpr *eCond = NULL; 2092 2093 assign(tmpRs, getIReg(regRs)); 2094 assign(tmpRt, getIReg(regRt)); 2095 assign(tmpReg0, getIReg(0)); 2096 2097 eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpReg0), mkexpr(tmpReg0)); 2098 2099 switch (opc1) { 2100 case 0x01: 2101 switch (regRt) { 2102 case 0x00: { /* BLTZ rs, offset */ 2103 addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2)); 2104 IRTemp tmpLtRes = newTemp(Ity_I1); 2105 2106 assign(tmp, eConst0); 2107 assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp))); 2108 assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) : 2109 unop(Iop_1Uto32, mkexpr(tmpLtRes))); 2110 2111 eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpLt), 2112 mkexpr(tmpReg0)); 2113 2114 jmpKind = Ijk_Boring; 2115 break; 2116 } 2117 2118 case 0x01: { /* BGEZ rs, offset */ 2119 IRTemp tmpLtRes = newTemp(Ity_I1); 2120 addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2)); 2121 2122 assign(tmp, eConst0); 2123 assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp))); 2124 assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) : 2125 unop(Iop_1Uto32, mkexpr(tmpLtRes))); 2126 eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt), 2127 mkexpr(tmpReg0)); 2128 2129 jmpKind = Ijk_Boring; 2130 break; 2131 } 2132 2133 case 0x11: { /* BGEZAL rs, offset */ 2134 addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2)); 2135 putIReg(regLnk, eNia); 2136 IRTemp tmpLtRes = newTemp(Ity_I1); 2137 2138 assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), eConst0)); 2139 assign(tmpLt, mode64 ? unop(Iop_1Uto64, mkexpr(tmpLtRes)) : 2140 unop(Iop_1Uto32, mkexpr(tmpLtRes))); 2141 2142 eCond = binop(mkSzOp(ty, Iop_CmpEQ8), mkexpr(tmpLt), 2143 mkexpr(tmpReg0)); 2144 2145 jmpKind = Ijk_Call; 2146 break; 2147 } 2148 2149 case 0x10: { /* BLTZAL rs, offset */ 2150 IRTemp tmpLtRes = newTemp(Ity_I1); 2151 IRTemp tmpRes = newTemp(ty); 2152 2153 addrTgt = mkSzAddr(ty, cia + 4 + (sOffset << 2)); 2154 putIReg(regLnk, eNia); 2155 2156 assign(tmp, eConst0); 2157 assign(tmpLtRes, binop(opSlt, mkexpr(tmpRs), mkexpr(tmp))); 2158 assign(tmpRes, mode64 ? unop(Iop_1Uto64, 2159 mkexpr(tmpLtRes)) : unop(Iop_1Uto32, mkexpr(tmpLtRes))); 2160 eCond = binop(mkSzOp(ty, Iop_CmpNE8), mkexpr(tmpRes), 2161 mkexpr(tmpReg0)); 2162 2163 jmpKind = Ijk_Call; 2164 break; 2165 } 2166 2167 } 2168 break; 2169 default: 2170 return False; 2171 } 2172 *set = IRStmt_Exit(eCond, jmpKind, mkSzConst(ty, addrTgt), OFFB_PC); 2173 return True; 2174 } 2175 2176 /*********************************************************/ 2177 /*--- Cavium Specific Instructions ---*/ 2178 /*********************************************************/ 2179 2180 /* Convenience function to yield to thread scheduler */ 2181 static void jump_back(IRExpr *condition) 2182 { 2183 stmt( IRStmt_Exit(condition, 2184 Ijk_Yield, 2185 IRConst_U64( guest_PC_curr_instr ), 2186 OFFB_PC) ); 2187 } 2188 2189 /* Based on s390_irgen_load_and_add32. */ 2190 static void mips_irgen_load_and_add32(IRTemp op1addr, IRTemp new_val, 2191 UChar rd, Bool putIntoRd) 2192 { 2193 IRCAS *cas; 2194 IRTemp old_mem = newTemp(Ity_I32); 2195 IRTemp expd = newTemp(Ity_I32); 2196 2197 assign(expd, load(Ity_I32, mkexpr(op1addr))); 2198 2199 cas = mkIRCAS(IRTemp_INVALID, old_mem, 2200 Iend_LE, mkexpr(op1addr), 2201 NULL, mkexpr(expd), /* expected value */ 2202 NULL, mkexpr(new_val) /* new value */); 2203 stmt(IRStmt_CAS(cas)); 2204 2205 /* If old_mem contains the expected value, then the CAS succeeded. 2206 Otherwise, it did not */ 2207 jump_back(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(expd))); 2208 if (putIntoRd) 2209 putIReg(rd, mkWidenFrom32(Ity_I64, mkexpr(old_mem), True)); 2210 } 2211 2212 /* Based on s390_irgen_load_and_add64. */ 2213 static void mips_irgen_load_and_add64(IRTemp op1addr, IRTemp new_val, 2214 UChar rd, Bool putIntoRd) 2215 { 2216 IRCAS *cas; 2217 IRTemp old_mem = newTemp(Ity_I64); 2218 IRTemp expd = newTemp(Ity_I64); 2219 2220 assign(expd, load(Ity_I64, mkexpr(op1addr))); 2221 2222 cas = mkIRCAS(IRTemp_INVALID, old_mem, 2223 Iend_LE, mkexpr(op1addr), 2224 NULL, mkexpr(expd), /* expected value */ 2225 NULL, mkexpr(new_val) /* new value */); 2226 stmt(IRStmt_CAS(cas)); 2227 2228 /* If old_mem contains the expected value, then the CAS succeeded. 2229 Otherwise, it did not */ 2230 jump_back(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(expd))); 2231 if (putIntoRd) 2232 putIReg(rd, mkexpr(old_mem)); 2233 } 2234 2235 static Bool dis_instr_CVM ( UInt theInstr ) 2236 { 2237 UChar opc2 = get_function(theInstr); 2238 UChar opc1 = get_opcode(theInstr); 2239 UChar regRs = get_rs(theInstr); 2240 UChar regRt = get_rt(theInstr); 2241 UChar regRd = get_rd(theInstr); 2242 /* MIPS trap instructions extract code from theInstr[15:6]. 2243 Cavium OCTEON instructions SNEI, SEQI extract immediate operands 2244 from the same bit field [15:6]. */ 2245 UInt imm = get_code(theInstr); 2246 UChar lenM1 = get_msb(theInstr); 2247 UChar p = get_lsb(theInstr); 2248 IRType ty = mode64? Ity_I64 : Ity_I32; 2249 IRTemp tmp = newTemp(ty); 2250 IRTemp tmpRs = newTemp(ty); 2251 IRTemp tmpRt = newTemp(ty); 2252 IRTemp t1 = newTemp(ty); 2253 UInt size; 2254 assign(tmpRs, getIReg(regRs)); 2255 2256 switch(opc1) { 2257 case 0x1C: { 2258 switch(opc2) { 2259 case 0x03: { /* DMUL rd, rs, rt */ 2260 DIP("dmul r%d, r%d, r%d", regRd, regRs, regRt); 2261 IRTemp t0 = newTemp(Ity_I128); 2262 assign(t0, binop(Iop_MullU64, getIReg(regRs), getIReg(regRt))); 2263 putIReg(regRd, unop(Iop_128to64, mkexpr(t0))); 2264 break; 2265 } 2266 2267 case 0x18: { /* Store Atomic Add Word - SAA; Cavium OCTEON */ 2268 DIP("saa r%u, (r%u)", regRt, regRs); 2269 IRTemp addr = newTemp(Ity_I64); 2270 IRTemp new = newTemp(Ity_I32); 2271 assign (addr, getIReg(regRs)); 2272 assign(new, binop(Iop_Add32, 2273 load(Ity_I32, mkexpr(addr)), 2274 mkNarrowTo32(ty, getIReg(regRt)))); 2275 mips_irgen_load_and_add32(addr, new, 0, False); 2276 break; 2277 } 2278 2279 /* Store Atomic Add Doubleword - SAAD; Cavium OCTEON */ 2280 case 0x19: { 2281 DIP( "saad r%u, (r%u)", regRt, regRs); 2282 IRTemp addr = newTemp(Ity_I64); 2283 IRTemp new = newTemp(Ity_I64); 2284 assign (addr, getIReg(regRs)); 2285 assign(new, binop(Iop_Add64, 2286 load(Ity_I64, mkexpr(addr)), 2287 getIReg(regRt))); 2288 mips_irgen_load_and_add64(addr, new, 0, False); 2289 break; 2290 } 2291 2292 /* LAI, LAID, LAD, LADD, LAS, LASD, 2293 LAC, LACD, LAA, LAAD, LAW, LAWD */ 2294 case 0x1f: { 2295 UInt opc3 = get_sa(theInstr); 2296 IRTemp addr = newTemp(Ity_I64); 2297 switch (opc3) { 2298 /* Load Atomic Increment Word - LAI; Cavium OCTEON2 */ 2299 case 0x02: { 2300 DIP("lai r%u,(r%u)\n", regRd, regRs); 2301 IRTemp new = newTemp(Ity_I32); 2302 assign(addr, getIReg(regRs)); 2303 assign(new, binop(Iop_Add32, 2304 load(Ity_I32, mkexpr(addr)), 2305 mkU32(1))); 2306 mips_irgen_load_and_add32(addr, new, regRd, True); 2307 break; 2308 } 2309 /* Load Atomic Increment Doubleword - LAID; Cavium OCTEON2 */ 2310 case 0x03: { 2311 DIP("laid r%u,(r%u)\n", regRd, regRs); 2312 IRTemp new = newTemp(Ity_I64); 2313 assign(addr, getIReg(regRs)); 2314 assign(new, binop(Iop_Add64, 2315 load(Ity_I64, mkexpr(addr)), 2316 mkU64(1))); 2317 mips_irgen_load_and_add64(addr, new, regRd, True); 2318 break; 2319 } 2320 /* Load Atomic Decrement Word - LAD; Cavium OCTEON2 */ 2321 case 0x06: { 2322 DIP("lad r%u,(r%u)\n", regRd, regRs); 2323 IRTemp new = newTemp(Ity_I32); 2324 assign(addr, getIReg(regRs)); 2325 assign(new, binop(Iop_Sub32, 2326 load(Ity_I32, mkexpr(addr)), 2327 mkU32(1))); 2328 mips_irgen_load_and_add32(addr, new, regRd, True); 2329 break; 2330 } 2331 /* Load Atomic Decrement Doubleword - LADD; Cavium OCTEON2 */ 2332 case 0x07: { 2333 DIP("ladd r%u,(r%u)\n", regRd, regRs); 2334 IRTemp new = newTemp(Ity_I64); 2335 assign (addr, getIReg(regRs)); 2336 assign(new, binop(Iop_Sub64, 2337 load(Ity_I64, mkexpr(addr)), 2338 mkU64(1))); 2339 mips_irgen_load_and_add64(addr, new, regRd, True); 2340 break; 2341 } 2342 /* Load Atomic Set Word - LAS; Cavium OCTEON2 */ 2343 case 0x0a: { 2344 DIP("las r%u,(r%u)\n", regRd, regRs); 2345 IRTemp new = newTemp(Ity_I32); 2346 assign(addr, getIReg(regRs)); 2347 assign(new, mkU32(0xffffffff)); 2348 mips_irgen_load_and_add32(addr, new, regRd, True); 2349 break; 2350 } 2351 /* Load Atomic Set Doubleword - LASD; Cavium OCTEON2 */ 2352 case 0x0b: { 2353 DIP("lasd r%u,(r%u)\n", regRd, regRs); 2354 IRTemp new = newTemp(Ity_I64); 2355 assign (addr, getIReg(regRs)); 2356 assign(new, mkU64(0xffffffffffffffffULL)); 2357 mips_irgen_load_and_add64(addr, new, regRd, True); 2358 break; 2359 } 2360 /* Load Atomic Clear Word - LAC; Cavium OCTEON2 */ 2361 case 0x0e: { 2362 DIP("lac r%u,(r%u)\n", regRd, regRs); 2363 IRTemp new = newTemp(Ity_I32); 2364 assign (addr, getIReg(regRs)); 2365 assign(new, mkU32(0)); 2366 mips_irgen_load_and_add32(addr, new, regRd, True); 2367 break; 2368 } 2369 /* Load Atomic Clear Doubleword - LACD; Cavium OCTEON2 */ 2370 case 0x0f: { 2371 DIP("lacd r%u,(r%u)\n", regRd, regRs); 2372 IRTemp new = newTemp(Ity_I64); 2373 assign(addr, getIReg(regRs)); 2374 assign(new, mkU64(0)); 2375 mips_irgen_load_and_add64(addr, new, regRd, True); 2376 break; 2377 } 2378 /* Load Atomic Add Word - LAA; Cavium OCTEON2 */ 2379 case 0x12: { 2380 DIP("laa r%u,(r%u),r%u\n", regRd, regRs, regRt); 2381 IRTemp new = newTemp(Ity_I32); 2382 assign(addr, getIReg(regRs)); 2383 assign(new, binop(Iop_Add32, 2384 load(Ity_I32, mkexpr(addr)), 2385 mkNarrowTo32(ty, getIReg(regRt)))); 2386 mips_irgen_load_and_add32(addr, new, regRd, True); 2387 break; 2388 } 2389 /* Load Atomic Add Doubleword - LAAD; Cavium OCTEON2 */ 2390 case 0x13: { 2391 DIP("laad r%u,(r%u),r%u\n", regRd, regRs, regRt); 2392 IRTemp new = newTemp(Ity_I64); 2393 assign (addr, getIReg(regRs)); 2394 assign(new, binop(Iop_Add64, 2395 load(Ity_I64, mkexpr(addr)), 2396 getIReg(regRt))); 2397 mips_irgen_load_and_add64(addr, new, regRd, True); 2398 break; 2399 } 2400 /* Load Atomic Swap Word - LAW; Cavium OCTEON2 */ 2401 case 0x16: { 2402 DIP("law r%u,(r%u)\n", regRd, regRs); 2403 IRTemp new = newTemp(Ity_I32); 2404 assign(addr, getIReg(regRs)); 2405 assign(new, mkNarrowTo32(ty, getIReg(regRt))); 2406 mips_irgen_load_and_add32(addr, new, regRd, True); 2407 break; 2408 } 2409 /* Load Atomic Swap Doubleword - LAWD; Cavium OCTEON2 */ 2410 case 0x17: { 2411 DIP("lawd r%u,(r%u)\n", regRd, regRs); 2412 IRTemp new = newTemp(Ity_I64); 2413 assign(addr, getIReg(regRs)); 2414 assign(new, getIReg(regRt)); 2415 mips_irgen_load_and_add64(addr, new, regRd, True); 2416 break; 2417 } 2418 default: 2419 vex_printf("Unknown laxx instruction, opc3=0x%x\n", opc3); 2420 vex_printf("Instruction=0x%08x\n", theInstr); 2421 return False; 2422 } 2423 break; 2424 } 2425 2426 /* Unsigned Byte Add - BADDU rd, rs, rt; Cavium OCTEON */ 2427 case 0x28: { 2428 DIP("BADDU r%d, r%d, r%d", regRs, regRt, regRd); 2429 IRTemp t0 = newTemp(Ity_I8); 2430 2431 assign(t0, binop(Iop_Add8, 2432 mkNarrowTo8(ty, getIReg(regRs)), 2433 mkNarrowTo8(ty, getIReg(regRt)))); 2434 2435 if (mode64) 2436 putIReg(regRd, binop(mkSzOp(ty, Iop_And8), 2437 unop(Iop_8Uto64, mkexpr(t0)), 2438 mkSzImm(ty, 0xFF))); 2439 else 2440 putIReg(regRd, binop(mkSzOp(ty, Iop_And8), 2441 unop(Iop_8Uto32, mkexpr(t0)), 2442 mkSzImm(ty, 0xFF))); 2443 break; 2444 } 2445 2446 case 0x2c: { /* Count Ones in a Word - POP; Cavium OCTEON */ 2447 int i, shift[5]; 2448 IRTemp mask[5]; 2449 IRTemp old = newTemp(ty); 2450 IRTemp nyu = IRTemp_INVALID; 2451 assign(old, getIReg(regRs)); 2452 DIP("pop r%d, r%d", regRd, regRs); 2453 2454 for (i = 0; i < 5; i++) { 2455 mask[i] = newTemp(ty); 2456 shift[i] = 1 << i; 2457 } 2458 if(mode64) { 2459 assign(mask[0], mkU64(0x0000000055555555)); 2460 assign(mask[1], mkU64(0x0000000033333333)); 2461 assign(mask[2], mkU64(0x000000000F0F0F0F)); 2462 assign(mask[3], mkU64(0x0000000000FF00FF)); 2463 assign(mask[4], mkU64(0x000000000000FFFF)); 2464 2465 for (i = 0; i < 5; i++) { 2466 nyu = newTemp(ty); 2467 assign(nyu, 2468 binop(Iop_Add64, 2469 binop(Iop_And64, 2470 mkexpr(old), mkexpr(mask[i])), 2471 binop(Iop_And64, 2472 binop(Iop_Shr64, 2473 mkexpr(old), mkU8(shift[i])), 2474 mkexpr(mask[i])))); 2475 old = nyu; 2476 } 2477 } else { 2478 assign(mask[0], mkU32(0x55555555)); 2479 assign(mask[1], mkU32(0x33333333)); 2480 assign(mask[2], mkU32(0x0F0F0F0F)); 2481 assign(mask[3], mkU32(0x00FF00FF)); 2482 assign(mask[4], mkU32(0x0000FFFF)); 2483 assign(old, getIReg(regRs)); 2484 2485 for (i = 0; i < 5; i++) { 2486 nyu = newTemp(ty); 2487 assign(nyu, 2488 binop(Iop_Add32, 2489 binop(Iop_And32, 2490 mkexpr(old), mkexpr(mask[i])), 2491 binop(Iop_And32, 2492 binop(Iop_Shr32, 2493 mkexpr(old), mkU8(shift[i])), 2494 mkexpr(mask[i])))); 2495 old = nyu; 2496 } 2497 } 2498 putIReg(regRd, mkexpr(nyu)); 2499 break; 2500 } 2501 2502 /* Count Ones in a Doubleword - DPOP; Cavium OCTEON */ 2503 case 0x2d: { 2504 int i, shift[6]; 2505 IRTemp mask[6]; 2506 IRTemp old = newTemp(ty); 2507 IRTemp nyu = IRTemp_INVALID; 2508 DIP("dpop r%d, r%d", regRd, regRs); 2509 2510 for (i = 0; i < 6; i++) { 2511 mask[i] = newTemp(ty); 2512 shift[i] = 1 << i; 2513 } 2514 vassert(mode64); /*Caution! Only for Mode 64*/ 2515 assign(mask[0], mkU64(0x5555555555555555ULL)); 2516 assign(mask[1], mkU64(0x3333333333333333ULL)); 2517 assign(mask[2], mkU64(0x0F0F0F0F0F0F0F0FULL)); 2518 assign(mask[3], mkU64(0x00FF00FF00FF00FFULL)); 2519 assign(mask[4], mkU64(0x0000FFFF0000FFFFULL)); 2520 assign(mask[5], mkU64(0x00000000FFFFFFFFULL)); 2521 assign(old, getIReg(regRs)); 2522 for (i = 0; i < 6; i++) { 2523 nyu = newTemp(Ity_I64); 2524 assign(nyu, 2525 binop(Iop_Add64, 2526 binop(Iop_And64, 2527 mkexpr(old), mkexpr(mask[i])), 2528 binop(Iop_And64, 2529 binop(Iop_Shr64, 2530 mkexpr(old), mkU8(shift[i])), 2531 mkexpr(mask[i])))); 2532 old = nyu; 2533 } 2534 putIReg(regRd, mkexpr(nyu)); 2535 break; 2536 } 2537 2538 case 0x32: /* 5. CINS rd, rs, p, lenm1 */ 2539 DIP("cins r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1); 2540 assign ( tmp , binop(Iop_Shl64, mkexpr(tmpRs), 2541 mkU8(64-( lenM1+1 )))); 2542 assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ), 2543 mkU8(64-(p+lenM1+1)))); 2544 putIReg( regRt, mkexpr(tmpRt)); 2545 break; 2546 2547 case 0x33: /* 6. CINS32 rd, rs, p+32, lenm1 */ 2548 DIP("cins32 r%u, r%u, %d, %d\n", regRt, regRs, p+32, lenM1); 2549 assign ( tmp , binop(Iop_Shl64, mkexpr(tmpRs), 2550 mkU8(64-( lenM1+1 )))); 2551 assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ), 2552 mkU8(32-(p+lenM1+1)))); 2553 putIReg( regRt, mkexpr(tmpRt)); 2554 break; 2555 2556 case 0x3A: /* 3. EXTS rt, rs, p len */ 2557 DIP("exts r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1); 2558 size = lenM1 + 1; /* lenm1+1 */ 2559 UChar lsAmt = 64 - (p + size); /* p+lenm1+1 */ 2560 UChar rsAmt = 64 - size; /* lenm1+1 */ 2561 tmp = newTemp(Ity_I64); 2562 assign(tmp, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt))); 2563 putIReg(regRt, binop(Iop_Sar64, mkexpr(tmp), mkU8(rsAmt))); 2564 break; 2565 2566 case 0x3B: /* 4. EXTS32 rt, rs, p len */ 2567 DIP("exts32 r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1); 2568 assign ( tmp , binop(Iop_Shl64, mkexpr(tmpRs), 2569 mkU8(32-(p+lenM1+1)))); 2570 assign ( tmpRt, binop(Iop_Sar64, mkexpr(tmp), 2571 mkU8(64-(lenM1+1))) ); 2572 putIReg( regRt, mkexpr(tmpRt)); 2573 break; 2574 2575 case 0x2B: /* 20. SNE rd, rs, rt */ 2576 DIP("sne r%d, r%d, r%d", regRd,regRs, regRt); 2577 if (mode64) 2578 putIReg(regRd, unop(Iop_1Uto64, binop(Iop_CmpNE64, 2579 getIReg(regRs), 2580 getIReg(regRt)))); 2581 else 2582 putIReg(regRd,unop(Iop_1Uto32, binop(Iop_CmpNE32, 2583 getIReg(regRs), 2584 getIReg(regRt)))); 2585 break; 2586 2587 case 0x2A: /* Set Equals - SEQ; Cavium OCTEON */ 2588 DIP("seq r%d, r%d, %d", regRd, regRs, regRt); 2589 if (mode64) 2590 putIReg(regRd, unop(Iop_1Uto64, 2591 binop(Iop_CmpEQ64, getIReg(regRs), 2592 getIReg(regRt)))); 2593 else 2594 putIReg(regRd, unop(Iop_1Uto32, 2595 binop(Iop_CmpEQ32, getIReg(regRs), 2596 getIReg(regRt)))); 2597 break; 2598 2599 case 0x2E: /* Set Equals Immediate - SEQI; Cavium OCTEON */ 2600 DIP("seqi r%d, r%d, %d", regRt, regRs, imm); 2601 if (mode64) 2602 putIReg(regRt, unop(Iop_1Uto64, 2603 binop(Iop_CmpEQ64, getIReg(regRs), 2604 mkU64(extend_s_10to64(imm))))); 2605 else 2606 putIReg(regRt, unop(Iop_1Uto32, 2607 binop(Iop_CmpEQ32, getIReg(regRs), 2608 mkU32(extend_s_10to32(imm))))); 2609 break; 2610 2611 case 0x2F: /* Set Not Equals Immediate - SNEI; Cavium OCTEON */ 2612 DIP("snei r%d, r%d, %d", regRt, regRs, imm); 2613 if (mode64) 2614 putIReg(regRt, unop(Iop_1Uto64, 2615 binop(Iop_CmpNE64, 2616 getIReg(regRs), 2617 mkU64(extend_s_10to64(imm))))); 2618 else 2619 putIReg(regRt, unop(Iop_1Uto32, 2620 binop(Iop_CmpNE32, 2621 getIReg(regRs), 2622 mkU32(extend_s_10to32(imm))))); 2623 break; 2624 2625 default: 2626 return False; 2627 } 2628 break; 2629 } /* opc1 0x1C ends here*/ 2630 case 0x1F: { 2631 switch(opc2) { 2632 case 0x0A: { // lx - Load indexed instructions 2633 switch (get_sa(theInstr)) { 2634 case 0x00: { // LWX rd, index(base) 2635 DIP("lwx r%d, r%d(r%d)", regRd, regRt, regRs); 2636 LOADX_STORE_PATTERN; 2637 putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), 2638 True)); 2639 break; 2640 } 2641 case 0x08: { // LDX rd, index(base) 2642 DIP("ldx r%d, r%d(r%d)", regRd, regRt, regRs); 2643 vassert(mode64); /* Currently Implemented only for n64 */ 2644 LOADX_STORE_PATTERN; 2645 putIReg(regRd, load(Ity_I64, mkexpr(t1))); 2646 break; 2647 } 2648 case 0x06: { // LBUX rd, index(base) 2649 DIP("lbux r%d, r%d(r%d)", regRd, regRt, regRs); 2650 LOADX_STORE_PATTERN; 2651 if (mode64) 2652 putIReg(regRd, unop(Iop_8Uto64, load(Ity_I8, 2653 mkexpr(t1)))); 2654 else 2655 putIReg(regRd, unop(Iop_8Uto32, load(Ity_I8, 2656 mkexpr(t1)))); 2657 break; 2658 } 2659 case 0x10: { // LWUX rd, index(base) (Cavium OCTEON) 2660 DIP("lwux r%d, r%d(r%d)", regRd, regRt, regRs); 2661 LOADX_STORE_PATTERN; /* same for both 32 and 64 modes*/ 2662 putIReg(regRd, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), 2663 False)); 2664 break; 2665 } 2666 case 0x14: { // LHUX rd, index(base) (Cavium OCTEON) 2667 DIP("lhux r%d, r%d(r%d)", regRd, regRt, regRs); 2668 LOADX_STORE_PATTERN; 2669 if (mode64) 2670 putIReg(regRd, 2671 unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1)))); 2672 else 2673 putIReg(regRd, 2674 unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1)))); 2675 break; 2676 } 2677 case 0x16: { // LBX rd, index(base) (Cavium OCTEON) 2678 DIP("lbx r%d, r%d(r%d)", regRd, regRs, regRt); 2679 LOADX_STORE_PATTERN; 2680 if (mode64) 2681 putIReg(regRd, 2682 unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1)))); 2683 else 2684 putIReg(regRd, 2685 unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1)))); 2686 break; 2687 } 2688 default: 2689 vex_printf("\nUnhandled LX instruction opc3 = %x\n", 2690 get_sa(theInstr)); 2691 return False; 2692 } 2693 break; 2694 } 2695 } /* opc1 = 0x1F & opc2 = 0xA (LX) ends here*/ 2696 break; 2697 } /* opc1 = 0x1F ends here*/ 2698 default: 2699 return False; 2700 } /* main opc1 switch ends here */ 2701 return True; 2702 } 2703 2704 /*------------------------------------------------------------*/ 2705 /*--- Disassemble a single DSP ASE instruction ---*/ 2706 /*------------------------------------------------------------*/ 2707 2708 static UInt disDSPInstr_MIPS_WRK ( UInt cins ) 2709 { 2710 IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, 2711 t15, t16, t17; 2712 UInt opcode, rs, rt, rd, sa, function, ac, ac_mfhilo, rddsp_mask, 2713 wrdsp_mask, dsp_imm, shift; 2714 2715 opcode = get_opcode(cins); 2716 rs = get_rs(cins); 2717 rt = get_rt(cins); 2718 rd = get_rd(cins); 2719 sa = get_sa(cins); 2720 function = get_function(cins); 2721 ac = get_acNo(cins); 2722 ac_mfhilo = get_acNo_mfhilo(cins); 2723 rddsp_mask = get_rddspMask(cins); 2724 wrdsp_mask = get_wrdspMask(cins); 2725 dsp_imm = get_dspImm(cins); 2726 shift = get_shift(cins); 2727 2728 switch (opcode) { 2729 case 0x00: { /* Special */ 2730 switch (function) { 2731 case 0x10: { /* MFHI */ 2732 DIP("mfhi ac%d r%d", ac_mfhilo, rd); 2733 putIReg(rd, unop(Iop_64HIto32, getAcc(ac_mfhilo))); 2734 break; 2735 } 2736 2737 case 0x11: { /* MTHI */ 2738 DIP("mthi ac%d r%d", ac, rs); 2739 t1 = newTemp(Ity_I32); 2740 assign(t1, unop(Iop_64to32, getAcc(ac))); 2741 putAcc(ac, binop(Iop_32HLto64, getIReg(rs), mkexpr(t1))); 2742 break; 2743 } 2744 2745 case 0x12: { /* MFLO */ 2746 DIP("mflo ac%d r%d", ac_mfhilo, rd); 2747 putIReg(rd, unop(Iop_64to32, getAcc(ac_mfhilo))); 2748 break; 2749 } 2750 2751 case 0x13: { /* MTLO */ 2752 DIP("mtlo ac%d r%d", ac, rs); 2753 t1 = newTemp(Ity_I32); 2754 assign(t1, unop(Iop_64HIto32, getAcc(ac))); 2755 putAcc(ac, binop(Iop_32HLto64, mkexpr(t1), getIReg(rs))); 2756 break; 2757 } 2758 2759 case 0x18: { /* MULT */ 2760 DIP("mult ac%d r%d, r%d", ac, rs, rt); 2761 t1 = newTemp(Ity_I64); 2762 assign(t1, binop(Iop_MullS32, mkNarrowTo32(Ity_I32, getIReg(rs)), 2763 mkNarrowTo32(Ity_I32, getIReg(rt)))); 2764 putAcc(ac, mkexpr(t1)); 2765 break; 2766 } 2767 2768 case 0x19: { /* MULTU */ 2769 DIP("multu ac%d r%d, r%d", ac, rs, rt); 2770 t1 = newTemp(Ity_I64); 2771 assign(t1, binop(Iop_MullU32, mkNarrowTo32(Ity_I32, getIReg(rs)), 2772 mkNarrowTo32(Ity_I32, 2773 getIReg(rt)))); 2774 putAcc(ac, mkexpr(t1)); 2775 break; 2776 } 2777 } 2778 break; 2779 } 2780 case 0x1C: { /* Special2 */ 2781 switch (function) { 2782 case 0x00: { /* MADD */ 2783 DIP("madd ac%d, r%d, r%d", ac, rs, rt); 2784 t1 = newTemp(Ity_I64); 2785 t2 = newTemp(Ity_I64); 2786 t3 = newTemp(Ity_I64); 2787 2788 assign(t1, getAcc(ac)); 2789 assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt))); 2790 assign(t3, binop(Iop_Add64, mkexpr(t1), mkexpr(t2))); 2791 2792 putAcc(ac, mkexpr(t3)); 2793 break; 2794 } 2795 case 0x01: { /* MADDU */ 2796 DIP("maddu ac%d r%d, r%d", ac, rs, rt); 2797 t1 = newTemp(Ity_I64); 2798 t2 = newTemp(Ity_I64); 2799 t3 = newTemp(Ity_I64); 2800 2801 assign(t1, getAcc(ac)); 2802 assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt))); 2803 assign(t3, binop(Iop_Add64, mkexpr(t2), mkexpr(t1))); 2804 2805 putAcc(ac, mkexpr(t3)); 2806 break; 2807 } 2808 case 0x04: { /* MSUB */ 2809 DIP("msub ac%d r%d, r%d", ac, rs, rt); 2810 t1 = newTemp(Ity_I64); 2811 t2 = newTemp(Ity_I64); 2812 t3 = newTemp(Ity_I64); 2813 2814 assign(t1, getAcc(ac)); 2815 assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt))); 2816 assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2))); 2817 2818 putAcc(ac, mkexpr(t3)); 2819 break; 2820 } 2821 case 0x05: { /* MSUBU */ 2822 DIP("msubu ac%d r%d, r%d", ac, rs, rt); 2823 t1 = newTemp(Ity_I64); 2824 t2 = newTemp(Ity_I64); 2825 t3 = newTemp(Ity_I64); 2826 2827 assign(t1, getAcc(ac)); 2828 assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt))); 2829 assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2))); 2830 2831 putAcc(ac, mkexpr(t3)); 2832 break; 2833 } 2834 } 2835 break; 2836 } 2837 case 0x1F: { /* Special3 */ 2838 switch (function) { 2839 case 0x12: { /* ABSQ_S.PH */ 2840 switch (sa) { 2841 case 0x1: { /* ABSQ_S.QB */ 2842 DIP("absq_s.qb r%d, r%d", rd, rt); 2843 vassert(!mode64); 2844 t0 = newTemp(Ity_I8); 2845 t1 = newTemp(Ity_I1); 2846 t2 = newTemp(Ity_I1); 2847 t3 = newTemp(Ity_I8); 2848 t4 = newTemp(Ity_I8); 2849 t5 = newTemp(Ity_I1); 2850 t6 = newTemp(Ity_I1); 2851 t7 = newTemp(Ity_I8); 2852 t8 = newTemp(Ity_I8); 2853 t9 = newTemp(Ity_I1); 2854 t10 = newTemp(Ity_I1); 2855 t11 = newTemp(Ity_I8); 2856 t12 = newTemp(Ity_I8); 2857 t13 = newTemp(Ity_I1); 2858 t14 = newTemp(Ity_I1); 2859 t15 = newTemp(Ity_I8); 2860 t16 = newTemp(Ity_I32); 2861 t17 = newTemp(Ity_I32); 2862 2863 /* Absolute value of the rightmost byte (bits 7-0). */ 2864 /* t0 - rightmost byte. */ 2865 assign(t0, unop(Iop_16to8, unop(Iop_32to16, getIReg(rt)))); 2866 /* t1 holds 1 if t0 is equal to 0x80, or 0 otherwise. */ 2867 assign(t1, binop(Iop_CmpEQ32, 2868 unop(Iop_8Uto32, mkexpr(t0)), 2869 mkU32(0x00000080))); 2870 /* t2 holds 1 if value in t0 is negative, 0 otherwise. */ 2871 assign(t2, unop(Iop_32to1, 2872 binop(Iop_Shr32, 2873 binop(Iop_And32, 2874 getIReg(rt), 2875 mkU32(0x00000080)), 2876 mkU8(0x7)))); 2877 /* t3 holds abs(t0). */ 2878 assign(t3, IRExpr_ITE(mkexpr(t1), 2879 mkU8(0x7F), 2880 IRExpr_ITE(mkexpr(t2), 2881 binop(Iop_Add8, 2882 unop(Iop_Not8, 2883 mkexpr(t0)), 2884 mkU8(0x1)), 2885 mkexpr(t0)))); 2886 2887 /* Absolute value of bits 15-8. */ 2888 /* t4 - input byte. */ 2889 assign(t4, 2890 unop(Iop_16HIto8, unop(Iop_32to16, getIReg(rt)))); 2891 /* t5 holds 1 if t4 is equal to 0x80, or 0 otherwise. */ 2892 assign(t5, binop(Iop_CmpEQ32, 2893 unop(Iop_8Uto32, mkexpr(t4)), 2894 mkU32(0x00000080))); 2895 /* t6 holds 1 if value in t4 is negative, 0 otherwise. */ 2896 assign(t6, unop(Iop_32to1, 2897 binop(Iop_Shr32, 2898 binop(Iop_And32, 2899 getIReg(rt), 2900 mkU32(0x00008000)), 2901 mkU8(15)))); 2902 /* t3 holds abs(t4). */ 2903 assign(t7, IRExpr_ITE(mkexpr(t5), 2904 mkU8(0x7F), 2905 IRExpr_ITE(mkexpr(t6), 2906 binop(Iop_Add8, 2907 unop(Iop_Not8, 2908 mkexpr(t4)), 2909 mkU8(0x1)), 2910 mkexpr(t4)))); 2911 2912 /* Absolute value of bits 23-15. */ 2913 /* t8 - input byte. */ 2914 assign(t8, 2915 unop(Iop_16to8, unop(Iop_32HIto16, getIReg(rt)))); 2916 /* t9 holds 1 if t8 is equal to 0x80, or 0 otherwise. */ 2917 assign(t9, binop(Iop_CmpEQ32, 2918 unop(Iop_8Uto32, mkexpr(t8)), 2919 mkU32(0x00000080))); 2920 /* t6 holds 1 if value in t8 is negative, 0 otherwise. */ 2921 assign(t10, unop(Iop_32to1, 2922 binop(Iop_Shr32, 2923 binop(Iop_And32, 2924 getIReg(rt), 2925 mkU32(0x00800000)), 2926 mkU8(23)))); 2927 /* t3 holds abs(t8). */ 2928 assign(t11, IRExpr_ITE(mkexpr(t9), 2929 mkU8(0x7F), 2930 IRExpr_ITE(mkexpr(t10), 2931 binop(Iop_Add8, 2932 unop(Iop_Not8, 2933 mkexpr(t8)), 2934 mkU8(0x1)), 2935 mkexpr(t8)))); 2936 2937 /* Absolute value of bits 31-24. */ 2938 /* t12 - input byte. */ 2939 assign(t12, 2940 unop(Iop_16HIto8, unop(Iop_32HIto16, getIReg(rt)))); 2941 /* t13 holds 1 if t12 is equal to 0x80, or 0 otherwise. */ 2942 assign(t13, binop(Iop_CmpEQ32, 2943 unop(Iop_8Uto32, mkexpr(t12)), 2944 mkU32(0x00000080))); 2945 /* t14 holds 1 if value in t12 is negative, 0 otherwise. */ 2946 assign(t14, unop(Iop_32to1, 2947 binop(Iop_Shr32, 2948 binop(Iop_And32, 2949 getIReg(rt), 2950 mkU32(0x80000000)), 2951 mkU8(31)))); 2952 /* t15 holds abs(t12). */ 2953 assign(t15, IRExpr_ITE(mkexpr(t13), 2954 mkU8(0x7F), 2955 IRExpr_ITE(mkexpr(t14), 2956 binop(Iop_Add8, 2957 unop(Iop_Not8, 2958 mkexpr(t12)), 2959 mkU8(0x1)), 2960 mkexpr(t12)))); 2961 2962 /* t16 holds !0 if any of input bytes is 0x80 or 0 2963 otherwise. */ 2964 assign(t16, 2965 binop(Iop_Or32, 2966 binop(Iop_Or32, 2967 binop(Iop_Or32, 2968 unop(Iop_1Sto32, mkexpr(t13)), 2969 unop(Iop_1Sto32, mkexpr(t9))), 2970 unop(Iop_1Sto32, mkexpr(t5))), 2971 unop(Iop_1Sto32, mkexpr(t1)))); 2972 2973 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 2974 mkexpr(t16), 2975 mkU32(0x0)), 2976 getDSPControl(), 2977 binop(Iop_Or32, 2978 getDSPControl(), 2979 mkU32(0x00100000)))); 2980 2981 /* t17 = t15|t11|t7|t3 */ 2982 assign(t17, 2983 binop(Iop_16HLto32, 2984 binop(Iop_8HLto16, mkexpr(t15), mkexpr(t11)), 2985 binop(Iop_8HLto16, mkexpr(t7), mkexpr(t3)))); 2986 2987 putIReg(rd, mkexpr(t17)); 2988 break; 2989 } 2990 case 0x2: { /* REPL.QB */ 2991 DIP("repl.qb r%d, %d", rd, dsp_imm); 2992 vassert(!mode64); 2993 2994 putIReg(rd, mkU32((dsp_imm << 24) | (dsp_imm << 16) | 2995 (dsp_imm << 8) | (dsp_imm))); 2996 break; 2997 } 2998 case 0x3: { /* REPLV.QB */ 2999 DIP("replv.qb r%d, r%d", rd, rt); 3000 vassert(!mode64); 3001 t0 = newTemp(Ity_I8); 3002 3003 assign(t0, unop(Iop_32to8, 3004 binop(Iop_And32, getIReg(rt), mkU32(0xff)))); 3005 putIReg(rd, 3006 binop(Iop_16HLto32, 3007 binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0)), 3008 binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0)))); 3009 break; 3010 } 3011 case 0x4: { /* PRECEQU.PH.QBL */ 3012 DIP("precequ.ph.qbl r%d, r%d", rd, rt); 3013 vassert(!mode64); 3014 3015 putIReg(rd, binop(Iop_Or32, 3016 binop(Iop_Shr32, 3017 binop(Iop_And32, 3018 getIReg(rt), 3019 mkU32(0xff000000)), 3020 mkU8(1)), 3021 binop(Iop_Shr32, 3022 binop(Iop_And32, 3023 getIReg(rt), 3024 mkU32(0x00ff0000)), 3025 mkU8(9)))); 3026 break; 3027 } 3028 case 0x5: { /* PRECEQU.PH.QBR */ 3029 DIP("precequ.ph.qbr r%d, r%d", rd, rt); 3030 vassert(!mode64); 3031 3032 putIReg(rd, binop(Iop_Or32, 3033 binop(Iop_Shl32, 3034 binop(Iop_And32, 3035 getIReg(rt), 3036 mkU32(0x0000ff00)), 3037 mkU8(15)), 3038 binop(Iop_Shl32, 3039 binop(Iop_And32, 3040 getIReg(rt), 3041 mkU32(0x000000ff)), 3042 mkU8(7)))); 3043 break; 3044 } 3045 case 0x6: { /* PRECEQU.PH.QBLA */ 3046 DIP("precequ.ph.qbla r%d, r%d", rd, rt); 3047 vassert(!mode64); 3048 3049 putIReg(rd, binop(Iop_Or32, 3050 binop(Iop_Shr32, 3051 binop(Iop_And32, 3052 getIReg(rt), 3053 mkU32(0xff000000)), 3054 mkU8(1)), 3055 binop(Iop_Shr32, 3056 binop(Iop_And32, 3057 getIReg(rt), 3058 mkU32(0x0000ff00)), 3059 mkU8(1)))); 3060 break; 3061 } 3062 case 0x7: { /* PRECEQU.PH.QBRA */ 3063 DIP("precequ.ph.qbra r%d, r%d", rd, rt); 3064 vassert(!mode64); 3065 3066 putIReg(rd, binop(Iop_Or32, 3067 binop(Iop_Shl32, 3068 binop(Iop_And32, 3069 getIReg(rt), 3070 mkU32(0x00ff0000)), 3071 mkU8(7)), 3072 binop(Iop_Shl32, 3073 binop(Iop_And32, 3074 getIReg(rt), 3075 mkU32(0x000000ff)), 3076 mkU8(7)))); 3077 break; 3078 } 3079 case 0x9: { /* ABSQ_S.PH */ 3080 DIP("absq_s.ph r%d, r%d", rd, rt); 3081 vassert(!mode64); 3082 t0 = newTemp(Ity_I16); 3083 t1 = newTemp(Ity_I1); 3084 t2 = newTemp(Ity_I1); 3085 t3 = newTemp(Ity_I16); 3086 t4 = newTemp(Ity_I16); 3087 t5 = newTemp(Ity_I1); 3088 t6 = newTemp(Ity_I1); 3089 t7 = newTemp(Ity_I16); 3090 t8 = newTemp(Ity_I32); 3091 t9 = newTemp(Ity_I32); 3092 3093 /* t0 holds lower 16 bits of value in rt. */ 3094 assign(t0, unop(Iop_32to16, getIReg(rt))); 3095 /* t1 holds 1 if t0 is equal to 0x8000. */ 3096 assign(t1, binop(Iop_CmpEQ32, 3097 unop(Iop_16Uto32, mkexpr(t0)), 3098 mkU32(0x00008000))); 3099 /* t2 holds 1 if value in t0 is negative, 0 otherwise. */ 3100 assign(t2, unop(Iop_32to1, 3101 binop(Iop_Shr32, 3102 binop(Iop_And32, 3103 getIReg(rt), 3104 mkU32(0x00008000)), 3105 mkU8(15)))); 3106 /* t3 holds abs(t0). */ 3107 assign(t3, IRExpr_ITE(mkexpr(t1), 3108 mkU16(0x7FFF), 3109 IRExpr_ITE(mkexpr(t2), 3110 binop(Iop_Add16, 3111 unop(Iop_Not16, 3112 mkexpr(t0)), 3113 mkU16(0x1)), 3114 mkexpr(t0)))); 3115 3116 /* t4 holds lower 16 bits of value in rt. */ 3117 assign(t4, unop(Iop_32HIto16, getIReg(rt))); 3118 /* t5 holds 1 if t4 is equal to 0x8000. */ 3119 assign(t5, binop(Iop_CmpEQ32, 3120 unop(Iop_16Uto32, mkexpr(t4)), 3121 mkU32(0x00008000))); 3122 /* t6 holds 1 if value in t4 is negative, 0 otherwise. */ 3123 assign(t6, unop(Iop_32to1, 3124 binop(Iop_Shr32, 3125 binop(Iop_And32, 3126 getIReg(rt), 3127 mkU32(0x80000000)), 3128 mkU8(31)))); 3129 /* t7 holds abs(t4). */ 3130 assign(t7, IRExpr_ITE(mkexpr(t5), 3131 mkU16(0x7FFF), 3132 IRExpr_ITE(mkexpr(t6), 3133 binop(Iop_Add16, 3134 unop(Iop_Not16, 3135 mkexpr(t4)), 3136 mkU16(0x1)), 3137 mkexpr(t4)))); 3138 /* If any of the two input halfwords is equal 0x8000, 3139 set bit 20 in DSPControl register. */ 3140 assign(t8, binop(Iop_Or32, 3141 unop(Iop_1Sto32, mkexpr(t5)), 3142 unop(Iop_1Sto32, mkexpr(t1)))); 3143 3144 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 3145 mkexpr(t8), 3146 mkU32(0x0)), 3147 getDSPControl(), 3148 binop(Iop_Or32, 3149 getDSPControl(), 3150 mkU32(0x00100000)))); 3151 3152 /* t9 = t7|t3 */ 3153 assign(t9, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3))); 3154 3155 putIReg(rd, mkexpr(t9)); 3156 break; 3157 } 3158 case 0xA: { /* REPL.PH */ 3159 DIP("repl.ph r%d, %d", rd, dsp_imm); 3160 vassert(!mode64); 3161 UShort immediate = extend_s_10to16(dsp_imm); 3162 3163 putIReg(rd, mkU32(immediate << 16 | immediate)); 3164 break; 3165 } 3166 case 0xB: { /* REPLV.PH */ 3167 DIP("replv.ph r%d, r%d", rd, rt); 3168 vassert(!mode64); 3169 3170 putIReg(rd, binop(Iop_16HLto32, 3171 unop(Iop_32to16, getIReg(rt)), 3172 unop(Iop_32to16, getIReg(rt)))); 3173 break; 3174 } 3175 case 0xC: { /* PRECEQ.W.PHL */ 3176 DIP("preceq.w.phl r%d, r%d", rd, rt); 3177 vassert(!mode64); 3178 putIReg(rd, binop(Iop_And32, 3179 getIReg(rt), 3180 mkU32(0xffff0000))); 3181 break; 3182 } 3183 case 0xD: { /* PRECEQ.W.PHR */ 3184 DIP("preceq.w.phr r%d, r%d", rd, rt); 3185 vassert(!mode64); 3186 putIReg(rd, binop(Iop_16HLto32, 3187 unop(Iop_32to16, getIReg(rt)), 3188 mkU16(0x0))); 3189 break; 3190 } 3191 case 0x11: { /* ABSQ_S.W */ 3192 DIP("absq_s.w r%d, r%d", rd, rt); 3193 vassert(!mode64); 3194 t0 = newTemp(Ity_I1); 3195 t1 = newTemp(Ity_I1); 3196 t2 = newTemp(Ity_I32); 3197 3198 assign(t0, 3199 binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000))); 3200 3201 putDSPControl(IRExpr_ITE(mkexpr(t0), 3202 binop(Iop_Or32, 3203 getDSPControl(), 3204 mkU32(0x00100000)), 3205 getDSPControl())); 3206 3207 assign(t1, binop(Iop_CmpLT32S, getIReg(rt), mkU32(0x0))); 3208 3209 assign(t2, IRExpr_ITE(mkexpr(t0), 3210 mkU32(0x7FFFFFFF), 3211 IRExpr_ITE(mkexpr(t1), 3212 binop(Iop_Add32, 3213 unop(Iop_Not32, 3214 getIReg(rt)), 3215 mkU32(0x1)), 3216 getIReg(rt)))); 3217 putIReg(rd, mkexpr(t2)); 3218 break; 3219 } 3220 case 0x1B: { /* BITREV */ 3221 DIP("bitrev r%d, r%d", rd, rt); 3222 vassert(!mode64); 3223 /* 32bit reversal as seen on Bit Twiddling Hacks site 3224 http://graphics.stanford.edu/~seander/bithacks.html 3225 section ReverseParallel */ 3226 t1 = newTemp(Ity_I32); 3227 t2 = newTemp(Ity_I32); 3228 t3 = newTemp(Ity_I32); 3229 t4 = newTemp(Ity_I32); 3230 t5 = newTemp(Ity_I32); 3231 3232 assign(t1, binop(Iop_Or32, 3233 binop(Iop_Shr32, 3234 binop(Iop_And32, 3235 getIReg(rt), 3236 mkU32(0xaaaaaaaa)), 3237 mkU8(0x1)), 3238 binop(Iop_Shl32, 3239 binop(Iop_And32, 3240 getIReg(rt), 3241 mkU32(0x55555555)), 3242 mkU8(0x1)))); 3243 assign(t2, binop(Iop_Or32, 3244 binop(Iop_Shr32, 3245 binop(Iop_And32, 3246 mkexpr(t1), 3247 mkU32(0xcccccccc)), 3248 mkU8(0x2)), 3249 binop(Iop_Shl32, 3250 binop(Iop_And32, 3251 mkexpr(t1), 3252 mkU32(0x33333333)), 3253 mkU8(0x2)))); 3254 assign(t3, binop(Iop_Or32, 3255 binop(Iop_Shr32, 3256 binop(Iop_And32, 3257 mkexpr(t2), 3258 mkU32(0xf0f0f0f0)), 3259 mkU8(0x4)), 3260 binop(Iop_Shl32, 3261 binop(Iop_And32, 3262 mkexpr(t2), 3263 mkU32(0x0f0f0f0f)), 3264 mkU8(0x4)))); 3265 assign(t4, binop(Iop_Or32, 3266 binop(Iop_Shr32, 3267 binop(Iop_And32, 3268 mkexpr(t3), 3269 mkU32(0xff00ff00)), 3270 mkU8(0x8)), 3271 binop(Iop_Shl32, 3272 binop(Iop_And32, 3273 mkexpr(t3), 3274 mkU32(0x00ff00ff)), 3275 mkU8(0x8)))); 3276 assign(t5, binop(Iop_Or32, 3277 binop(Iop_Shr32, 3278 mkexpr(t4), 3279 mkU8(0x10)), 3280 binop(Iop_Shl32, 3281 mkexpr(t4), 3282 mkU8(0x10)))); 3283 putIReg(rd, binop(Iop_Shr32, 3284 mkexpr(t5), 3285 mkU8(16))); 3286 break; 3287 } 3288 case 0x1C: { /* PRECEU.PH.QBL */ 3289 DIP("preceu.ph.qbl r%d, r%d", rd, rt); 3290 vassert(!mode64); 3291 3292 putIReg(rd, binop(Iop_Or32, 3293 binop(Iop_Shr32, 3294 binop(Iop_And32, 3295 getIReg(rt), 3296 mkU32(0xff000000)), 3297 mkU8(8)), 3298 binop(Iop_Shr32, 3299 binop(Iop_And32, 3300 getIReg(rt), 3301 mkU32(0x00ff0000)), 3302 mkU8(16)))); 3303 break; 3304 } 3305 case 0x1E: { /* PRECEU.PH.QBLA */ 3306 DIP("preceu.ph.qbla r%d, r%d", rd, rt); 3307 vassert(!mode64); 3308 3309 putIReg(rd, binop(Iop_Or32, 3310 binop(Iop_Shr32, 3311 binop(Iop_And32, 3312 getIReg(rt), 3313 mkU32(0xff000000)), 3314 mkU8(8)), 3315 binop(Iop_Shr32, 3316 binop(Iop_And32, 3317 getIReg(rt), 3318 mkU32(0x0000ff00)), 3319 mkU8(8)))); 3320 break; 3321 } 3322 case 0x1D: { /* PRECEU.PH.QBR */ 3323 DIP("preceu.ph.qbr r%d, r%d", rd, rt); 3324 vassert(!mode64); 3325 3326 putIReg(rd, binop(Iop_Or32, 3327 binop(Iop_Shl32, 3328 binop(Iop_And32, 3329 getIReg(rt), 3330 mkU32(0x0000ff00)), 3331 mkU8(8)), 3332 binop(Iop_And32, 3333 getIReg(rt), 3334 mkU32(0x000000ff)))); 3335 break; 3336 } 3337 case 0x1F: { /* PRECEU.PH.QBRA */ 3338 DIP("preceu.ph.qbra r%d, r%d", rd, rt); 3339 vassert(!mode64); 3340 3341 putIReg(rd, binop(Iop_Or32, 3342 binop(Iop_And32, 3343 getIReg(rt), 3344 mkU32(0x00ff0000)), 3345 binop(Iop_And32, 3346 getIReg(rt), 3347 mkU32(0x000000ff)))); 3348 break; 3349 } 3350 default: 3351 return -1; 3352 } 3353 break; /* end of ABSQ_S.PH */ 3354 } 3355 case 0x38: { /* EXTR.W */ 3356 switch(sa) { 3357 case 0x0: { /* EXTR.W */ 3358 DIP("extr.w r%d, ac%d, %d", rt, ac, rs); 3359 vassert(!mode64); 3360 t0 = newTemp(Ity_I64); 3361 t1 = newTemp(Ity_I64); 3362 t2 = newTemp(Ity_I32); 3363 t3 = newTemp(Ity_I1); 3364 t4 = newTemp(Ity_I1); 3365 t5 = newTemp(Ity_I1); 3366 t6 = newTemp(Ity_I1); 3367 t7 = newTemp(Ity_I32); 3368 t8 = newTemp(Ity_I64); 3369 t9 = newTemp(Ity_I64); 3370 t10 = newTemp(Ity_I1); 3371 t11 = newTemp(Ity_I1); 3372 t12 = newTemp(Ity_I1); 3373 t13 = newTemp(Ity_I1); 3374 t14 = newTemp(Ity_I32); 3375 3376 assign(t0, getAcc(ac)); 3377 if (0 == rs) { 3378 assign(t1, mkexpr(t0)); 3379 } else { 3380 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs))); 3381 } 3382 /* Check if bits 63..31 of the result in t1 aren't 0. */ 3383 assign(t3, binop(Iop_CmpNE32, 3384 unop(Iop_64HIto32, 3385 mkexpr(t1)), 3386 mkU32(0))); 3387 assign(t4, binop(Iop_CmpNE32, 3388 binop(Iop_And32, 3389 unop(Iop_64to32, 3390 mkexpr(t1)), 3391 mkU32(0x80000000)), 3392 mkU32(0))); 3393 /* Check if bits 63..31 of the result in t1 aren't 3394 0x1ffffffff. */ 3395 assign(t5, binop(Iop_CmpNE32, 3396 unop(Iop_64HIto32, 3397 mkexpr(t1)), 3398 mkU32(0xffffffff))); 3399 assign(t6, binop(Iop_CmpNE32, 3400 binop(Iop_And32, 3401 unop(Iop_64to32, 3402 mkexpr(t1)), 3403 mkU32(0x80000000)), 3404 mkU32(0x80000000))); 3405 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP 3406 control register. */ 3407 assign(t7, binop(Iop_And32, 3408 binop(Iop_Or32, 3409 unop(Iop_1Sto32, mkexpr(t3)), 3410 unop(Iop_1Sto32, mkexpr(t4))), 3411 binop(Iop_Or32, 3412 unop(Iop_1Sto32, mkexpr(t5)), 3413 unop(Iop_1Sto32, mkexpr(t6))))); 3414 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3415 mkexpr(t7), 3416 mkU32(0)), 3417 binop(Iop_Or32, 3418 getDSPControl(), 3419 mkU32(0x00800000)), 3420 getDSPControl())); 3421 3422 /* If the last discarded bit is 1, there would be carry 3423 when rounding, otherwise there wouldn't. We use that 3424 fact and just add the value of the last discarded bit 3425 to the least sifgnificant bit of the shifted value 3426 from acc. */ 3427 if (0 == rs) { 3428 assign(t8, mkU64(0x0ULL)); 3429 } else { 3430 assign(t8, binop(Iop_And64, 3431 binop(Iop_Shr64, 3432 mkexpr(t0), 3433 mkU8(rs-1)), 3434 mkU64(0x1ULL))); 3435 } 3436 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8))); 3437 3438 /* Repeat previous steps for the rounded value. */ 3439 assign(t10, binop(Iop_CmpNE32, 3440 unop(Iop_64HIto32, 3441 mkexpr(t9)), 3442 mkU32(0))); 3443 assign(t11, binop(Iop_CmpNE32, 3444 binop(Iop_And32, 3445 unop(Iop_64to32, 3446 mkexpr(t9)), 3447 mkU32(0x80000000)), 3448 mkU32(0))); 3449 3450 assign(t12, binop(Iop_CmpNE32, 3451 unop(Iop_64HIto32, 3452 mkexpr(t9)), 3453 mkU32(0xffffffff))); 3454 assign(t13, binop(Iop_CmpNE32, 3455 binop(Iop_And32, 3456 unop(Iop_64to32, 3457 mkexpr(t9)), 3458 mkU32(0x80000000)), 3459 mkU32(0x80000000))); 3460 3461 assign(t14, binop(Iop_And32, 3462 binop(Iop_Or32, 3463 unop(Iop_1Sto32, mkexpr(t10)), 3464 unop(Iop_1Sto32, mkexpr(t11))), 3465 binop(Iop_Or32, 3466 unop(Iop_1Sto32, mkexpr(t12)), 3467 unop(Iop_1Sto32, mkexpr(t13))))); 3468 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3469 mkexpr(t14), 3470 mkU32(0)), 3471 binop(Iop_Or32, 3472 getDSPControl(), 3473 mkU32(0x00800000)), 3474 getDSPControl())); 3475 if (0 == rs) { 3476 putIReg(rt, unop(Iop_64to32, mkexpr(t0))); 3477 } else { 3478 putIReg(rt, unop(Iop_64to32, mkexpr(t1))); 3479 } 3480 break; 3481 } 3482 case 0x1: { /* EXTRV.W */ 3483 DIP("extrv.w r%d, ac%d, r%d", rt, ac, rs); 3484 vassert(!mode64); 3485 t0 = newTemp(Ity_I64); 3486 t1 = newTemp(Ity_I64); 3487 t2 = newTemp(Ity_I32); 3488 t3 = newTemp(Ity_I1); 3489 t4 = newTemp(Ity_I1); 3490 t5 = newTemp(Ity_I1); 3491 t6 = newTemp(Ity_I1); 3492 t7 = newTemp(Ity_I32); 3493 t8 = newTemp(Ity_I64); 3494 t9 = newTemp(Ity_I64); 3495 t10 = newTemp(Ity_I1); 3496 t11 = newTemp(Ity_I1); 3497 t12 = newTemp(Ity_I1); 3498 t13 = newTemp(Ity_I1); 3499 t14 = newTemp(Ity_I32); 3500 t15 = newTemp(Ity_I8); 3501 3502 assign(t15, unop(Iop_32to8, 3503 binop(Iop_And32, 3504 getIReg(rs), 3505 mkU32(0x1f)))); 3506 assign(t0, getAcc(ac)); 3507 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15))); 3508 putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32, 3509 unop(Iop_8Uto32, 3510 mkexpr(t15)), 3511 mkU32(0)), 3512 unop(Iop_64to32, mkexpr(t0)), 3513 unop(Iop_64to32, mkexpr(t1)))); 3514 3515 /* Check if bits 63..31 of the result in t1 aren't 0. */ 3516 assign(t3, binop(Iop_CmpNE32, 3517 unop(Iop_64HIto32, 3518 mkexpr(t1)), 3519 mkU32(0))); 3520 assign(t4, binop(Iop_CmpNE32, 3521 binop(Iop_And32, 3522 unop(Iop_64to32, 3523 mkexpr(t1)), 3524 mkU32(0x80000000)), 3525 mkU32(0))); 3526 /* Check if bits 63..31 of the result in t1 aren't 3527 0x1ffffffff. */ 3528 assign(t5, binop(Iop_CmpNE32, 3529 unop(Iop_64HIto32, 3530 mkexpr(t1)), 3531 mkU32(0xffffffff))); 3532 assign(t6, binop(Iop_CmpNE32, 3533 binop(Iop_And32, 3534 unop(Iop_64to32, 3535 mkexpr(t1)), 3536 mkU32(0x80000000)), 3537 mkU32(0x80000000))); 3538 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP 3539 control register. */ 3540 assign(t7, binop(Iop_And32, 3541 binop(Iop_Or32, 3542 unop(Iop_1Sto32, mkexpr(t3)), 3543 unop(Iop_1Sto32, mkexpr(t4))), 3544 binop(Iop_Or32, 3545 unop(Iop_1Sto32, mkexpr(t5)), 3546 unop(Iop_1Sto32, mkexpr(t6))))); 3547 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3548 mkexpr(t7), 3549 mkU32(0)), 3550 binop(Iop_Or32, 3551 getDSPControl(), 3552 mkU32(0x00800000)), 3553 getDSPControl())); 3554 3555 /* If the last discarded bit is 1, there would be carry 3556 when rounding, otherwise there wouldn't. We use that 3557 fact and just add the value of the last discarded bit 3558 to the least sifgnificant bit of the shifted value 3559 from acc. */ 3560 assign(t8, 3561 IRExpr_ITE(binop(Iop_CmpEQ32, 3562 unop(Iop_8Uto32, 3563 mkexpr(t15)), 3564 mkU32(0)), 3565 mkU64(0x0ULL), 3566 binop(Iop_And64, 3567 binop(Iop_Shr64, 3568 mkexpr(t0), 3569 unop(Iop_32to8, 3570 binop(Iop_Sub32, 3571 unop(Iop_8Uto32, 3572 mkexpr(t15)), 3573 mkU32(1)))), 3574 mkU64(0x1ULL)))); 3575 3576 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8))); 3577 3578 /* Repeat previous steps for the rounded value. */ 3579 assign(t10, binop(Iop_CmpNE32, 3580 unop(Iop_64HIto32, 3581 mkexpr(t9)), 3582 mkU32(0))); 3583 assign(t11, binop(Iop_CmpNE32, 3584 binop(Iop_And32, 3585 unop(Iop_64to32, 3586 mkexpr(t9)), 3587 mkU32(0x80000000)), 3588 mkU32(0))); 3589 3590 assign(t12, binop(Iop_CmpNE32, 3591 unop(Iop_64HIto32, 3592 mkexpr(t9)), 3593 mkU32(0xffffffff))); 3594 assign(t13, binop(Iop_CmpNE32, 3595 binop(Iop_And32, 3596 unop(Iop_64to32, 3597 mkexpr(t9)), 3598 mkU32(0x80000000)), 3599 mkU32(0x80000000))); 3600 3601 assign(t14, binop(Iop_And32, 3602 binop(Iop_Or32, 3603 unop(Iop_1Sto32, mkexpr(t10)), 3604 unop(Iop_1Sto32, mkexpr(t11))), 3605 binop(Iop_Or32, 3606 unop(Iop_1Sto32, mkexpr(t12)), 3607 unop(Iop_1Sto32, mkexpr(t13))))); 3608 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3609 mkexpr(t14), 3610 mkU32(0)), 3611 binop(Iop_Or32, 3612 getDSPControl(), 3613 mkU32(0x00800000)), 3614 getDSPControl())); 3615 break; 3616 } 3617 case 0x2: { /* EXTP */ 3618 DIP("extp r%d, ac%d, %d", rt, ac, rs); 3619 vassert(!mode64); 3620 t0 = newTemp(Ity_I64); 3621 t1 = newTemp(Ity_I32); 3622 t2 = newTemp(Ity_I1); 3623 t3 = newTemp(Ity_I1); 3624 t4 = newTemp(Ity_I8); 3625 t5 = newTemp(Ity_I64); 3626 t6 = newTemp(Ity_I64); 3627 t7 = newTemp(Ity_I32); 3628 3629 assign(t0, getAcc(ac)); 3630 /* Extract pos field of DSPControl register. */ 3631 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f))); 3632 3633 /* Check if (pos - size) >= 0 [size <= pos] 3634 if (pos < size) 3635 put 1 to EFI field of DSPControl register 3636 else 3637 extract bits from acc and put 0 to EFI field of 3638 DSPCtrl */ 3639 assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs))); 3640 3641 putDSPControl(IRExpr_ITE(mkexpr(t2), 3642 binop(Iop_Or32, 3643 binop(Iop_And32, 3644 getDSPControl(), 3645 mkU32(0xffffbfff)), 3646 mkU32(0x4000)), 3647 binop(Iop_And32, 3648 getDSPControl(), 3649 mkU32(0xffffbfff)))); 3650 3651 /* If pos <= 31, shift right the value from the acc 3652 (pos-size) times and take (size+1) bits from the least 3653 significant positions. Otherwise, shift left the value 3654 (63-pos) times, take (size+1) bits from the most 3655 significant positions and shift right (31-size) times.*/ 3656 assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31))); 3657 3658 assign(t4, 3659 IRExpr_ITE(mkexpr(t3), 3660 unop(Iop_32to8, 3661 binop(Iop_Sub32, 3662 mkexpr(t1), mkU32(rs))), 3663 unop(Iop_32to8, 3664 binop(Iop_Sub32, 3665 mkU32(63), mkexpr(t1))))); 3666 3667 assign(t5, IRExpr_ITE(mkexpr(t3), 3668 binop(Iop_Shr64, 3669 mkexpr(t0), mkexpr(t4)), 3670 binop(Iop_Shl64, 3671 mkexpr(t0), mkexpr(t4)))); 3672 3673 /* t6 holds a mask for bit extraction */ 3674 assign(t6, 3675 IRExpr_ITE(mkexpr(t3), 3676 unop(Iop_Not64, 3677 binop(Iop_Shl64, 3678 mkU64(0xffffffffffffffffULL), 3679 mkU8(rs+1))), 3680 unop(Iop_Not64, 3681 binop(Iop_Shr64, 3682 mkU64(0xffffffffffffffffULL), 3683 mkU8(rs+1))))); 3684 3685 assign(t7, IRExpr_ITE(mkexpr(t3), 3686 unop(Iop_64to32, 3687 binop(Iop_And64, 3688 mkexpr(t5), 3689 mkexpr(t6))), 3690 binop(Iop_Shr32, 3691 unop(Iop_64HIto32, 3692 binop(Iop_And64, 3693 mkexpr(t5), 3694 mkexpr(t6))), 3695 mkU8(31-rs)))); 3696 3697 putIReg(rt, mkexpr(t7)); 3698 break; 3699 } 3700 case 0x3: { /* EXTPV */ 3701 DIP("extpv r%d, ac%d, r%d", rt, ac, rs); 3702 vassert(!mode64); 3703 t0 = newTemp(Ity_I64); 3704 t1 = newTemp(Ity_I32); 3705 t2 = newTemp(Ity_I1); 3706 t3 = newTemp(Ity_I1); 3707 t4 = newTemp(Ity_I8); 3708 t5 = newTemp(Ity_I64); 3709 t6 = newTemp(Ity_I64); 3710 t7 = newTemp(Ity_I32); 3711 t8 = newTemp(Ity_I32); 3712 3713 assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f))); 3714 assign(t0, getAcc(ac)); 3715 /* Extract pos field of DSPControl register. */ 3716 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f))); 3717 3718 /* Check if (pos - size) >= 0 [size <= pos] 3719 if (pos < size) 3720 put 1 to EFI field of DSPControl register 3721 else 3722 extract bits from acc and put 0 to EFI field of 3723 DSPCtrl */ 3724 assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8))); 3725 3726 putDSPControl(IRExpr_ITE(mkexpr(t2), 3727 binop(Iop_Or32, 3728 binop(Iop_And32, 3729 getDSPControl(), 3730 mkU32(0xffffbfff)), 3731 mkU32(0x4000)), 3732 binop(Iop_And32, 3733 getDSPControl(), 3734 mkU32(0xffffbfff)))); 3735 3736 /* If pos <= 31, shift right the value from the acc 3737 (pos-size) times and take (size+1) bits from the least 3738 significant positions. Otherwise, shift left the value 3739 (63-pos) times, take (size+1) bits from the most 3740 significant positions and shift right (31-size) 3741 times. */ 3742 assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31))); 3743 3744 assign(t4, 3745 IRExpr_ITE(mkexpr(t3), 3746 unop(Iop_32to8, 3747 binop(Iop_Sub32, 3748 mkexpr(t1), mkexpr(t8))), 3749 unop(Iop_32to8, 3750 binop(Iop_Sub32, 3751 mkU32(63), mkexpr(t1))))); 3752 3753 assign(t5, IRExpr_ITE(mkexpr(t3), 3754 binop(Iop_Shr64, 3755 mkexpr(t0), mkexpr(t4)), 3756 binop(Iop_Shl64, 3757 mkexpr(t0), mkexpr(t4)))); 3758 3759 /* t6 holds a mask for bit extraction. */ 3760 assign(t6, 3761 IRExpr_ITE(mkexpr(t3), 3762 unop(Iop_Not64, 3763 binop(Iop_Shl64, 3764 mkU64(0xffffffffffffffffULL), 3765 unop(Iop_32to8, 3766 binop(Iop_Add32, 3767 mkexpr(t8), 3768 mkU32(1))))), 3769 unop(Iop_Not64, 3770 binop(Iop_Shr64, 3771 mkU64(0xffffffffffffffffULL), 3772 unop(Iop_32to8, 3773 binop(Iop_Add32, 3774 mkexpr(t8), 3775 mkU32(1))))))); 3776 3777 assign(t7, IRExpr_ITE(mkexpr(t3), 3778 unop(Iop_64to32, 3779 binop(Iop_And64, 3780 mkexpr(t5), 3781 mkexpr(t6))), 3782 binop(Iop_Shr32, 3783 unop(Iop_64HIto32, 3784 binop(Iop_And64, 3785 mkexpr(t5), 3786 mkexpr(t6))), 3787 unop(Iop_32to8, 3788 binop(Iop_Sub32, 3789 mkU32(31), 3790 mkexpr(t8)))))); 3791 3792 putIReg(rt, mkexpr(t7)); 3793 break; 3794 } 3795 case 0x4: { /* EXTR_R.W */ 3796 DIP("extr_r.w r%d, ac%d, %d", rt, ac, rs); 3797 vassert(!mode64); 3798 t0 = newTemp(Ity_I64); 3799 t1 = newTemp(Ity_I64); 3800 t2 = newTemp(Ity_I32); 3801 t3 = newTemp(Ity_I1); 3802 t4 = newTemp(Ity_I1); 3803 t5 = newTemp(Ity_I1); 3804 t6 = newTemp(Ity_I1); 3805 t7 = newTemp(Ity_I32); 3806 t8 = newTemp(Ity_I64); 3807 t9 = newTemp(Ity_I64); 3808 t10 = newTemp(Ity_I1); 3809 t11 = newTemp(Ity_I1); 3810 t12 = newTemp(Ity_I1); 3811 t13 = newTemp(Ity_I1); 3812 t14 = newTemp(Ity_I32); 3813 t15 = newTemp(Ity_I64); 3814 t16 = newTemp(Ity_I1); 3815 3816 assign(t0, getAcc(ac)); 3817 assign(t16, binop(Iop_CmpEQ32, 3818 mkU32(rs), 3819 mkU32(0))); 3820 assign(t1, IRExpr_ITE(mkexpr(t16), 3821 mkexpr(t0), 3822 binop(Iop_Sar64, 3823 mkexpr(t0), 3824 mkU8(rs)))); 3825 /* If the last discarded bit is 1, there would be carry 3826 when rounding, otherwise there wouldn't. We use that 3827 fact and just add the value of the last discarded bit 3828 to the least significant bit of the shifted value 3829 from acc. */ 3830 assign(t15, binop(Iop_Shr64, 3831 mkexpr(t0), 3832 unop(Iop_32to8, 3833 binop(Iop_Sub32, 3834 binop(Iop_And32, 3835 mkU32(rs), 3836 mkU32(0x1f)), 3837 mkU32(1))))); 3838 3839 assign(t8, 3840 IRExpr_ITE(mkexpr(t16), 3841 mkU64(0x0ULL), 3842 binop(Iop_And64, 3843 mkexpr(t15), 3844 mkU64(0x0000000000000001ULL)))); 3845 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8))); 3846 putIReg(rt, unop(Iop_64to32, mkexpr(t9))); 3847 3848 /* Check if bits 63..31 of the result in t1 aren't 0. */ 3849 assign(t3, binop(Iop_CmpNE32, 3850 unop(Iop_64HIto32, 3851 mkexpr(t1)), 3852 mkU32(0))); 3853 assign(t4, binop(Iop_CmpNE32, 3854 binop(Iop_And32, 3855 unop(Iop_64to32, 3856 mkexpr(t1)), 3857 mkU32(0x80000000)), 3858 mkU32(0))); 3859 3860 /* Check if bits 63..31 of the result in t1 aren't 3861 0x1ffffffff. */ 3862 assign(t5, binop(Iop_CmpNE32, 3863 unop(Iop_64HIto32, 3864 mkexpr(t1)), 3865 mkU32(0xffffffff))); 3866 assign(t6, binop(Iop_CmpNE32, 3867 binop(Iop_And32, 3868 unop(Iop_64to32, 3869 mkexpr(t1)), 3870 mkU32(0x80000000)), 3871 mkU32(0x80000000))); 3872 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP 3873 control register. */ 3874 assign(t7, binop(Iop_And32, 3875 binop(Iop_Or32, 3876 unop(Iop_1Sto32, mkexpr(t3)), 3877 unop(Iop_1Sto32, mkexpr(t4))), 3878 binop(Iop_Or32, 3879 unop(Iop_1Sto32, mkexpr(t5)), 3880 unop(Iop_1Sto32, mkexpr(t6))))); 3881 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3882 mkexpr(t7), 3883 mkU32(0)), 3884 binop(Iop_Or32, 3885 getDSPControl(), 3886 mkU32(0x00800000)), 3887 getDSPControl())); 3888 3889 /* Repeat previous steps for the rounded value. */ 3890 assign(t10, binop(Iop_CmpNE32, 3891 unop(Iop_64HIto32, 3892 mkexpr(t9)), 3893 mkU32(0))); 3894 assign(t11, binop(Iop_CmpNE32, 3895 binop(Iop_And32, 3896 unop(Iop_64to32, 3897 mkexpr(t9)), 3898 mkU32(0x80000000)), 3899 mkU32(0))); 3900 3901 assign(t12, binop(Iop_CmpNE32, 3902 unop(Iop_64HIto32, 3903 mkexpr(t9)), 3904 mkU32(0xffffffff))); 3905 assign(t13, binop(Iop_CmpNE32, 3906 binop(Iop_And32, 3907 unop(Iop_64to32, 3908 mkexpr(t9)), 3909 mkU32(0x80000000)), 3910 mkU32(0x80000000))); 3911 3912 assign(t14, binop(Iop_And32, 3913 binop(Iop_Or32, 3914 unop(Iop_1Sto32, mkexpr(t10)), 3915 unop(Iop_1Sto32, mkexpr(t11))), 3916 binop(Iop_Or32, 3917 unop(Iop_1Sto32, mkexpr(t12)), 3918 unop(Iop_1Sto32, mkexpr(t13))))); 3919 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3920 mkexpr(t14), 3921 mkU32(0)), 3922 binop(Iop_Or32, 3923 getDSPControl(), 3924 mkU32(0x00800000)), 3925 getDSPControl())); 3926 break; 3927 } 3928 case 0x5: { /* EXTRV_R.W */ 3929 DIP("extrv_r.w r%d, ac%d, r%d", rt, ac, rs); 3930 vassert(!mode64); 3931 t0 = newTemp(Ity_I64); 3932 t1 = newTemp(Ity_I64); 3933 t2 = newTemp(Ity_I32); 3934 t3 = newTemp(Ity_I1); 3935 t4 = newTemp(Ity_I1); 3936 t5 = newTemp(Ity_I1); 3937 t6 = newTemp(Ity_I1); 3938 t7 = newTemp(Ity_I32); 3939 t8 = newTemp(Ity_I64); 3940 t9 = newTemp(Ity_I64); 3941 t10 = newTemp(Ity_I1); 3942 t11 = newTemp(Ity_I1); 3943 t12 = newTemp(Ity_I1); 3944 t13 = newTemp(Ity_I1); 3945 t14 = newTemp(Ity_I32); 3946 t15 = newTemp(Ity_I8); 3947 3948 assign(t15, unop(Iop_32to8, 3949 binop(Iop_And32, 3950 getIReg(rs), 3951 mkU32(0x1f)))); 3952 assign(t0, getAcc(ac)); 3953 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15))); 3954 3955 /* Check if bits 63..31 of the result in t1 aren't 0. */ 3956 assign(t3, binop(Iop_CmpNE32, 3957 unop(Iop_64HIto32, 3958 mkexpr(t1)), 3959 mkU32(0))); 3960 assign(t4, binop(Iop_CmpNE32, 3961 binop(Iop_And32, 3962 unop(Iop_64to32, 3963 mkexpr(t1)), 3964 mkU32(0x80000000)), 3965 mkU32(0))); 3966 /* Check if bits 63..31 of the result in t1 aren't 3967 0x1ffffffff. */ 3968 assign(t5, binop(Iop_CmpNE32, 3969 unop(Iop_64HIto32, 3970 mkexpr(t1)), 3971 mkU32(0xffffffff))); 3972 assign(t6, binop(Iop_CmpNE32, 3973 binop(Iop_And32, 3974 unop(Iop_64to32, 3975 mkexpr(t1)), 3976 mkU32(0x80000000)), 3977 mkU32(0x80000000))); 3978 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP 3979 control register. */ 3980 assign(t7, binop(Iop_And32, 3981 binop(Iop_Or32, 3982 unop(Iop_1Sto32, mkexpr(t3)), 3983 unop(Iop_1Sto32, mkexpr(t4))), 3984 binop(Iop_Or32, 3985 unop(Iop_1Sto32, mkexpr(t5)), 3986 unop(Iop_1Sto32, mkexpr(t6))))); 3987 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 3988 mkexpr(t7), 3989 mkU32(0)), 3990 binop(Iop_Or32, 3991 getDSPControl(), 3992 mkU32(0x00800000)), 3993 getDSPControl())); 3994 3995 /* If the last discarded bit is 1, there would be carry 3996 when rounding, otherwise there wouldn't. We use that 3997 fact and just add the value of the last discarded bit 3998 to the least sifgnificant bit of the shifted value 3999 from acc. */ 4000 assign(t8, 4001 IRExpr_ITE(binop(Iop_CmpEQ32, 4002 unop(Iop_8Uto32, 4003 mkexpr(t15)), 4004 mkU32(0)), 4005 mkU64(0x0ULL), 4006 binop(Iop_And64, 4007 binop(Iop_Shr64, 4008 mkexpr(t0), 4009 unop(Iop_32to8, 4010 binop(Iop_Sub32, 4011 unop(Iop_8Uto32, 4012 mkexpr(t15)), 4013 mkU32(1)))), 4014 mkU64(0x1ULL)))); 4015 4016 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8))); 4017 /* Put rounded value in destination register. */ 4018 putIReg(rt, unop(Iop_64to32, mkexpr(t9))); 4019 4020 /* Repeat previous steps for the rounded value. */ 4021 assign(t10, binop(Iop_CmpNE32, 4022 unop(Iop_64HIto32, 4023 mkexpr(t9)), 4024 mkU32(0))); 4025 assign(t11, binop(Iop_CmpNE32, 4026 binop(Iop_And32, 4027 unop(Iop_64to32, 4028 mkexpr(t9)), 4029 mkU32(0x80000000)), 4030 mkU32(0))); 4031 4032 assign(t12, binop(Iop_CmpNE32, 4033 unop(Iop_64HIto32, 4034 mkexpr(t9)), 4035 mkU32(0xffffffff))); 4036 assign(t13, binop(Iop_CmpNE32, 4037 binop(Iop_And32, 4038 unop(Iop_64to32, 4039 mkexpr(t9)), 4040 mkU32(0x80000000)), 4041 mkU32(0x80000000))); 4042 4043 assign(t14, binop(Iop_And32, 4044 binop(Iop_Or32, 4045 unop(Iop_1Sto32, mkexpr(t10)), 4046 unop(Iop_1Sto32, mkexpr(t11))), 4047 binop(Iop_Or32, 4048 unop(Iop_1Sto32, mkexpr(t12)), 4049 unop(Iop_1Sto32, mkexpr(t13))))); 4050 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4051 mkexpr(t14), 4052 mkU32(0)), 4053 binop(Iop_Or32, 4054 getDSPControl(), 4055 mkU32(0x00800000)), 4056 getDSPControl())); 4057 break; 4058 } 4059 case 0x6: { /* EXTR_RS.W */ 4060 DIP("extr_rs.w r%d, ac%d, %d", rt, ac, rs); 4061 vassert(!mode64); 4062 t0 = newTemp(Ity_I64); 4063 t1 = newTemp(Ity_I64); 4064 t2 = newTemp(Ity_I32); 4065 t3 = newTemp(Ity_I1); 4066 t4 = newTemp(Ity_I1); 4067 t5 = newTemp(Ity_I1); 4068 t6 = newTemp(Ity_I1); 4069 t7 = newTemp(Ity_I32); 4070 t8 = newTemp(Ity_I64); 4071 t9 = newTemp(Ity_I64); 4072 t10 = newTemp(Ity_I1); 4073 t11 = newTemp(Ity_I1); 4074 t12 = newTemp(Ity_I1); 4075 t13 = newTemp(Ity_I1); 4076 t14 = newTemp(Ity_I32); 4077 t16 = newTemp(Ity_I32); 4078 4079 assign(t0, getAcc(ac)); 4080 if (0 == rs) { 4081 assign(t1, mkexpr(t0)); 4082 } else { 4083 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs))); 4084 } 4085 4086 /* Check if bits 63..31 of the result in t1 aren't 0. */ 4087 assign(t3, binop(Iop_CmpNE32, 4088 unop(Iop_64HIto32, 4089 mkexpr(t1)), 4090 mkU32(0))); 4091 assign(t4, binop(Iop_CmpNE32, 4092 binop(Iop_And32, 4093 unop(Iop_64to32, 4094 mkexpr(t1)), 4095 mkU32(0x80000000)), 4096 mkU32(0))); 4097 /* Check if bits 63..31 of the result in t1 aren't 4098 0x1ffffffff. */ 4099 assign(t5, binop(Iop_CmpNE32, 4100 unop(Iop_64HIto32, 4101 mkexpr(t1)), 4102 mkU32(0xffffffff))); 4103 assign(t6, binop(Iop_CmpNE32, 4104 binop(Iop_And32, 4105 unop(Iop_64to32, 4106 mkexpr(t1)), 4107 mkU32(0x80000000)), 4108 mkU32(0x80000000))); 4109 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP 4110 control register. */ 4111 assign(t7, binop(Iop_And32, 4112 binop(Iop_Or32, 4113 unop(Iop_1Sto32, mkexpr(t3)), 4114 unop(Iop_1Sto32, mkexpr(t4))), 4115 binop(Iop_Or32, 4116 unop(Iop_1Sto32, mkexpr(t5)), 4117 unop(Iop_1Sto32, mkexpr(t6))))); 4118 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4119 mkexpr(t7), 4120 mkU32(0)), 4121 binop(Iop_Or32, 4122 getDSPControl(), 4123 mkU32(0x00800000)), 4124 getDSPControl())); 4125 4126 /* If the last discarded bit is 1, there would be carry 4127 when rounding, otherwise there wouldn't. We use that 4128 fact and just add the value of the last discarded bit 4129 to the least sifgnificant bit of the shifted value 4130 from acc. */ 4131 if (0 == rs) { 4132 assign(t8, mkU64(0x0ULL)); 4133 } else { 4134 assign(t8, binop(Iop_And64, 4135 binop(Iop_Shr64, 4136 mkexpr(t0), 4137 mkU8(rs-1)), 4138 mkU64(0x1ULL))); 4139 } 4140 4141 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8))); 4142 4143 /* Repeat previous steps for the rounded value. */ 4144 assign(t10, binop(Iop_CmpNE32, 4145 unop(Iop_64HIto32, 4146 mkexpr(t9)), 4147 mkU32(0))); 4148 assign(t11, binop(Iop_CmpNE32, 4149 binop(Iop_And32, 4150 unop(Iop_64to32, 4151 mkexpr(t9)), 4152 mkU32(0x80000000)), 4153 mkU32(0))); 4154 4155 assign(t12, binop(Iop_CmpNE32, 4156 unop(Iop_64HIto32, 4157 mkexpr(t9)), 4158 mkU32(0xffffffff))); 4159 assign(t13, binop(Iop_CmpNE32, 4160 binop(Iop_And32, 4161 unop(Iop_64to32, 4162 mkexpr(t9)), 4163 mkU32(0x80000000)), 4164 mkU32(0x80000000))); 4165 4166 assign(t14, binop(Iop_And32, 4167 binop(Iop_Or32, 4168 unop(Iop_1Sto32, mkexpr(t10)), 4169 unop(Iop_1Sto32, mkexpr(t11))), 4170 binop(Iop_Or32, 4171 unop(Iop_1Sto32, mkexpr(t12)), 4172 unop(Iop_1Sto32, mkexpr(t13))))); 4173 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4174 mkexpr(t14), 4175 mkU32(0)), 4176 binop(Iop_Or32, 4177 getDSPControl(), 4178 mkU32(0x00800000)), 4179 getDSPControl())); 4180 4181 assign(t16, binop(Iop_And32, 4182 unop(Iop_64HIto32, 4183 mkexpr(t9)), 4184 mkU32(0x80000000))); 4185 putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32, 4186 mkexpr(t14), 4187 mkU32(0)), 4188 IRExpr_ITE(binop(Iop_CmpEQ32, 4189 mkexpr(t16), 4190 mkU32(0)), 4191 mkU32(0x7fffffff), 4192 mkU32(0x80000000)), 4193 unop(Iop_64to32, mkexpr(t9)))); 4194 break; 4195 } 4196 case 0x7: { /* EXTRV_RS.W */ 4197 DIP("extrv_rs.w r%d, ac%d, r%d", rt, ac, rs); 4198 vassert(!mode64); 4199 t0 = newTemp(Ity_I64); 4200 t1 = newTemp(Ity_I64); 4201 t2 = newTemp(Ity_I32); 4202 t3 = newTemp(Ity_I1); 4203 t4 = newTemp(Ity_I1); 4204 t5 = newTemp(Ity_I1); 4205 t6 = newTemp(Ity_I1); 4206 t7 = newTemp(Ity_I32); 4207 t8 = newTemp(Ity_I64); 4208 t9 = newTemp(Ity_I64); 4209 t10 = newTemp(Ity_I1); 4210 t11 = newTemp(Ity_I1); 4211 t12 = newTemp(Ity_I1); 4212 t13 = newTemp(Ity_I1); 4213 t14 = newTemp(Ity_I32); 4214 t15 = newTemp(Ity_I32); 4215 t16 = newTemp(Ity_I32); 4216 t17 = newTemp(Ity_I1); 4217 4218 assign(t15, binop(Iop_And32, 4219 getIReg(rs), 4220 mkU32(0x1f))); 4221 assign(t17, binop(Iop_CmpEQ32, 4222 mkexpr(t15), 4223 mkU32(0))); 4224 assign(t0, getAcc(ac)); 4225 assign(t1, IRExpr_ITE(mkexpr(t17), 4226 mkexpr(t0), 4227 binop(Iop_Sar64, 4228 mkexpr(t0), 4229 unop(Iop_32to8, 4230 mkexpr(t15))))); 4231 4232 /* Check if bits 63..31 of the result in t1 aren't 0. */ 4233 assign(t3, binop(Iop_CmpNE32, 4234 unop(Iop_64HIto32, 4235 mkexpr(t1)), 4236 mkU32(0))); 4237 assign(t4, binop(Iop_CmpNE32, 4238 binop(Iop_And32, 4239 unop(Iop_64to32, 4240 mkexpr(t1)), 4241 mkU32(0x80000000)), 4242 mkU32(0))); 4243 /* Check if bits 63..31 of the result in t1 aren't 4244 0x1ffffffff. */ 4245 assign(t5, binop(Iop_CmpNE32, 4246 unop(Iop_64HIto32, 4247 mkexpr(t1)), 4248 mkU32(0xffffffff))); 4249 assign(t6, binop(Iop_CmpNE32, 4250 binop(Iop_And32, 4251 unop(Iop_64to32, 4252 mkexpr(t1)), 4253 mkU32(0x80000000)), 4254 mkU32(0x80000000))); 4255 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP 4256 control register. */ 4257 assign(t7, binop(Iop_And32, 4258 binop(Iop_Or32, 4259 unop(Iop_1Sto32, mkexpr(t3)), 4260 unop(Iop_1Sto32, mkexpr(t4))), 4261 binop(Iop_Or32, 4262 unop(Iop_1Sto32, mkexpr(t5)), 4263 unop(Iop_1Sto32, mkexpr(t6))))); 4264 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4265 mkexpr(t7), 4266 mkU32(0)), 4267 binop(Iop_Or32, 4268 getDSPControl(), 4269 mkU32(0x00800000)), 4270 getDSPControl())); 4271 4272 /* If the last discarded bit is 1, there would be carry 4273 when rounding, otherwise there wouldn't. We use that 4274 fact and just add the value of the last discarded bit 4275 to the least sifgnificant bit of the shifted value 4276 from acc. */ 4277 assign(t8, 4278 IRExpr_ITE(mkexpr(t17), 4279 mkU64(0x0ULL), 4280 binop(Iop_And64, 4281 binop(Iop_Shr64, 4282 mkexpr(t0), 4283 unop(Iop_32to8, 4284 binop(Iop_Sub32, 4285 mkexpr(t15), 4286 mkU32(1)))), 4287 mkU64(0x1ULL)))); 4288 4289 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8))); 4290 4291 /* Repeat previous steps for the rounded value. */ 4292 assign(t10, binop(Iop_CmpNE32, 4293 unop(Iop_64HIto32, 4294 mkexpr(t9)), 4295 mkU32(0))); 4296 assign(t11, binop(Iop_CmpNE32, 4297 binop(Iop_And32, 4298 unop(Iop_64to32, 4299 mkexpr(t9)), 4300 mkU32(0x80000000)), 4301 mkU32(0))); 4302 4303 assign(t12, binop(Iop_CmpNE32, 4304 unop(Iop_64HIto32, 4305 mkexpr(t9)), 4306 mkU32(0xffffffff))); 4307 assign(t13, binop(Iop_CmpNE32, 4308 binop(Iop_And32, 4309 unop(Iop_64to32, 4310 mkexpr(t9)), 4311 mkU32(0x80000000)), 4312 mkU32(0x80000000))); 4313 4314 assign(t14, binop(Iop_And32, 4315 binop(Iop_Or32, 4316 unop(Iop_1Sto32, mkexpr(t10)), 4317 unop(Iop_1Sto32, mkexpr(t11))), 4318 binop(Iop_Or32, 4319 unop(Iop_1Sto32, mkexpr(t12)), 4320 unop(Iop_1Sto32, mkexpr(t13))))); 4321 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4322 mkexpr(t14), 4323 mkU32(0)), 4324 binop(Iop_Or32, 4325 getDSPControl(), 4326 mkU32(0x00800000)), 4327 getDSPControl())); 4328 4329 assign(t16, binop(Iop_And32, 4330 unop(Iop_64HIto32, 4331 mkexpr(t9)), 4332 mkU32(0x80000000))); 4333 putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32, 4334 mkexpr(t14), 4335 mkU32(0)), 4336 IRExpr_ITE(binop(Iop_CmpEQ32, 4337 mkexpr(t16), 4338 mkU32(0)), 4339 mkU32(0x7fffffff), 4340 mkU32(0x80000000)), 4341 unop(Iop_64to32, mkexpr(t9)))); 4342 break; 4343 } 4344 case 0xA: { /* EXTPDP */ 4345 DIP("extpdp r%d, ac%d, %d", rt, ac, rs); 4346 vassert(!mode64); 4347 t0 = newTemp(Ity_I64); 4348 t1 = newTemp(Ity_I32); 4349 t2 = newTemp(Ity_I1); 4350 t3 = newTemp(Ity_I1); 4351 t4 = newTemp(Ity_I8); 4352 t5 = newTemp(Ity_I64); 4353 t6 = newTemp(Ity_I64); 4354 t7 = newTemp(Ity_I32); 4355 t8 = newTemp(Ity_I32); 4356 4357 assign(t0, getAcc(ac)); 4358 /* Extract pos field of DSPControl register. */ 4359 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f))); 4360 4361 /* Check if (pos - size) >= 0 [size <= pos] 4362 if (pos < size) 4363 put 1 to EFI field of DSPControl register 4364 else 4365 extract bits from acc and put 0 to EFI field of 4366 DSPCtrl */ 4367 assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs))); 4368 4369 assign(t8, binop(Iop_Or32, 4370 binop(Iop_And32, 4371 getDSPControl(), 4372 mkU32(0xffffbfc0)), 4373 binop(Iop_And32, 4374 binop(Iop_Sub32, 4375 binop(Iop_And32, 4376 getDSPControl(), 4377 mkU32(0x3f)), 4378 mkU32(rs+1)), 4379 mkU32(0x3f)))); 4380 putDSPControl(IRExpr_ITE(mkexpr(t2), 4381 binop(Iop_Or32, 4382 binop(Iop_And32, 4383 getDSPControl(), 4384 mkU32(0xffffbfff)), 4385 mkU32(0x4000)), 4386 mkexpr(t8))); 4387 4388 /* If pos <= 31, shift right the value from the acc 4389 (pos-size) times and take (size+1) bits from the least 4390 significant positions. Otherwise, shift left the value 4391 (63-pos) times, take (size+1) bits from the most 4392 significant positions and shift right (31-size) times. 4393 */ 4394 assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31))); 4395 4396 assign(t4, 4397 IRExpr_ITE(mkexpr(t3), 4398 unop(Iop_32to8, 4399 binop(Iop_Sub32, 4400 mkexpr(t1), mkU32(rs))), 4401 unop(Iop_32to8, 4402 binop(Iop_Sub32, 4403 mkU32(63), mkexpr(t1))))); 4404 4405 assign(t5, IRExpr_ITE(mkexpr(t3), 4406 binop(Iop_Shr64, 4407 mkexpr(t0), mkexpr(t4)), 4408 binop(Iop_Shl64, 4409 mkexpr(t0), mkexpr(t4)))); 4410 4411 /* t6 holds a mask for bit extraction. */ 4412 assign(t6, 4413 IRExpr_ITE(mkexpr(t3), 4414 unop(Iop_Not64, 4415 binop(Iop_Shl64, 4416 mkU64(0xffffffffffffffffULL), 4417 mkU8(rs+1))), 4418 unop(Iop_Not64, 4419 binop(Iop_Shr64, 4420 mkU64(0xffffffffffffffffULL), 4421 mkU8(rs+1))))); 4422 4423 assign(t7, IRExpr_ITE(mkexpr(t3), 4424 unop(Iop_64to32, 4425 binop(Iop_And64, 4426 mkexpr(t5), 4427 mkexpr(t6))), 4428 binop(Iop_Shr32, 4429 unop(Iop_64HIto32, 4430 binop(Iop_And64, 4431 mkexpr(t5), 4432 mkexpr(t6))), 4433 mkU8(31-rs)))); 4434 4435 putIReg(rt, mkexpr(t7)); 4436 break; 4437 } 4438 case 0xB: { /* EXTPDPV */ 4439 DIP("extpdpv r%d, ac%d, r%d", rt, ac, rs); 4440 vassert(!mode64); 4441 t0 = newTemp(Ity_I64); 4442 t1 = newTemp(Ity_I32); 4443 t2 = newTemp(Ity_I1); 4444 t3 = newTemp(Ity_I1); 4445 t4 = newTemp(Ity_I8); 4446 t5 = newTemp(Ity_I64); 4447 t6 = newTemp(Ity_I64); 4448 t7 = newTemp(Ity_I32); 4449 t8 = newTemp(Ity_I32); 4450 t9 = newTemp(Ity_I32); 4451 4452 assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f))); 4453 assign(t0, getAcc(ac)); 4454 /* Extract pos field of DSPControl register. */ 4455 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f))); 4456 4457 /* Check if (pos - size) >= 0 [size <= pos] 4458 if (pos < size) 4459 put 1 to EFI field of DSPControl register 4460 else 4461 extract bits from acc and put 0 to EFI field of 4462 DSPCtrl */ 4463 assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8))); 4464 4465 assign(t9, binop(Iop_Or32, 4466 binop(Iop_And32, 4467 getDSPControl(), 4468 mkU32(0xffffbfc0)), 4469 binop(Iop_And32, 4470 binop(Iop_Sub32, 4471 binop(Iop_And32, 4472 getDSPControl(), 4473 mkU32(0x3f)), 4474 binop(Iop_Add32, 4475 mkexpr(t8), 4476 mkU32(0x1))), 4477 mkU32(0x3f)))); 4478 putDSPControl(IRExpr_ITE(mkexpr(t2), 4479 binop(Iop_Or32, 4480 binop(Iop_And32, 4481 getDSPControl(), 4482 mkU32(0xffffbfff)), 4483 mkU32(0x4000)), 4484 mkexpr(t9))); 4485 4486 /* If pos <= 31, shift right the value from the acc 4487 (pos-size) times and take (size+1) bits from the least 4488 significant positions. Otherwise, shift left the value 4489 (63-pos) times, take (size+1) bits from the most 4490 significant positions and shift right (31-size) times. 4491 */ 4492 assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31))); 4493 4494 assign(t4, 4495 IRExpr_ITE(mkexpr(t3), 4496 unop(Iop_32to8, 4497 binop(Iop_Sub32, 4498 mkexpr(t1), mkexpr(t8))), 4499 unop(Iop_32to8, 4500 binop(Iop_Sub32, 4501 mkU32(63), mkexpr(t1))))); 4502 4503 assign(t5, IRExpr_ITE(mkexpr(t3), 4504 binop(Iop_Shr64, 4505 mkexpr(t0), mkexpr(t4)), 4506 binop(Iop_Shl64, 4507 mkexpr(t0), mkexpr(t4)))); 4508 4509 /* t6 holds a mask for bit extraction. */ 4510 assign(t6, 4511 IRExpr_ITE(mkexpr(t3), 4512 unop(Iop_Not64, 4513 binop(Iop_Shl64, 4514 mkU64(0xffffffffffffffffULL), 4515 unop(Iop_32to8, 4516 binop(Iop_Add32, 4517 mkexpr(t8), 4518 mkU32(1))))), 4519 unop(Iop_Not64, 4520 binop(Iop_Shr64, 4521 mkU64(0xffffffffffffffffULL), 4522 unop(Iop_32to8, 4523 binop(Iop_Add32, 4524 mkexpr(t8), 4525 mkU32(1))))))); 4526 4527 assign(t7, IRExpr_ITE(mkexpr(t3), 4528 unop(Iop_64to32, 4529 binop(Iop_And64, 4530 mkexpr(t5), 4531 mkexpr(t6))), 4532 binop(Iop_Shr32, 4533 unop(Iop_64HIto32, 4534 binop(Iop_And64, 4535 mkexpr(t5), 4536 mkexpr(t6))), 4537 unop(Iop_32to8, 4538 binop(Iop_Sub32, 4539 mkU32(31), 4540 mkexpr(t8)))))); 4541 4542 putIReg(rt, mkexpr(t7)); 4543 break; 4544 } 4545 case 0xE: { /* EXTR_S.H */ 4546 DIP("extr_s.h r%d, ac%d, %d", rt, ac, rs); 4547 vassert(!mode64); 4548 t0 = newTemp(Ity_I64); 4549 t1 = newTemp(Ity_I64); 4550 t2 = newTemp(Ity_I32); 4551 t3 = newTemp(Ity_I64); 4552 t4 = newTemp(Ity_I32); 4553 t5 = newTemp(Ity_I32); 4554 t6 = newTemp(Ity_I64); 4555 t7 = newTemp(Ity_I32); 4556 t9 = newTemp(Ity_I32); 4557 4558 assign(t0, getAcc(ac)); 4559 4560 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs))); 4561 4562 assign(t2, binop(Iop_Or32, 4563 getDSPControl(), mkU32(0x00800000))); 4564 4565 assign(t9, binop(Iop_And32, 4566 unop(Iop_64to32, 4567 mkexpr(t1)), 4568 mkU32(0x80000000))); 4569 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4570 mkexpr(t9), 4571 binop(Iop_And32, 4572 unop(Iop_64HIto32, 4573 mkexpr(t0)), 4574 mkU32(0x80000000))), 4575 mkexpr(t2), 4576 getDSPControl())); 4577 4578 /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0) 4579 1. subtract 0x7fff from t1 4580 2. if the resulting number is positive (sign bit = 0) 4581 and any of the other bits is 1, the value is > 0. */ 4582 assign(t3, binop(Iop_Sub64, 4583 mkexpr(t1), 4584 mkU64(0x0000000000007fffULL))); 4585 assign(t4, binop(Iop_And32, 4586 binop(Iop_Or32, 4587 unop(Iop_1Sto32, 4588 binop(Iop_CmpNE32, 4589 mkU32(0), 4590 binop(Iop_And32, 4591 unop(Iop_64HIto32, 4592 mkexpr(t3)), 4593 mkU32(0x7fffffff)))), 4594 unop(Iop_1Sto32, 4595 binop(Iop_CmpNE32, 4596 mkU32(0), 4597 unop(Iop_64to32, 4598 mkexpr(t3))))), 4599 unop(Iop_1Sto32, 4600 binop(Iop_CmpEQ32, 4601 binop(Iop_And32, 4602 unop(Iop_64HIto32, 4603 mkexpr(t3)), 4604 mkU32(0x80000000)), 4605 mkU32(0))))); 4606 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4607 mkU32(0), 4608 mkexpr(t4)), 4609 binop(Iop_Or32, 4610 getDSPControl(), 4611 mkU32(0x00800000)), 4612 getDSPControl())); 4613 /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0 4614 1. subtract t1 from 0xffffffffffff8000 4615 2. if the resulting number is positive (sign bit = 0) 4616 and any of the other bits is 1, the value is > 0 */ 4617 assign(t6, binop(Iop_Sub64, 4618 mkU64(0xffffffffffff8000ULL), 4619 mkexpr(t1))); 4620 assign(t7, binop(Iop_And32, 4621 binop(Iop_Or32, 4622 unop(Iop_1Sto32, 4623 binop(Iop_CmpNE32, 4624 mkU32(0), 4625 binop(Iop_And32, 4626 unop(Iop_64HIto32, 4627 mkexpr(t6)), 4628 mkU32(0x7fffffff)))), 4629 unop(Iop_1Sto32, 4630 binop(Iop_CmpNE32, 4631 mkU32(0), 4632 unop(Iop_64to32, 4633 mkexpr(t6))))), 4634 unop(Iop_1Sto32, 4635 binop(Iop_CmpEQ32, 4636 binop(Iop_And32, 4637 unop(Iop_64HIto32, 4638 mkexpr(t6)), 4639 mkU32(0x80000000)), 4640 mkU32(0))))); 4641 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4642 mkU32(0), 4643 mkexpr(t7)), 4644 binop(Iop_Or32, 4645 getDSPControl(), 4646 mkU32(0x00800000)), 4647 getDSPControl())); 4648 putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32, 4649 mkU32(0), 4650 mkexpr(t4)), 4651 mkU32(0x00007fff), 4652 IRExpr_ITE(binop(Iop_CmpNE32, 4653 mkU32(0), 4654 mkexpr(t7)), 4655 mkU32(0xffff8000), 4656 unop(Iop_64to32, 4657 mkexpr(t1))))); 4658 break; 4659 } 4660 case 0xF: { /* EXTRV_S.H */ 4661 DIP("extrv_s.h r%d, ac%d, %d", rt, ac, rs); 4662 vassert(!mode64); 4663 t0 = newTemp(Ity_I64); 4664 t1 = newTemp(Ity_I64); 4665 t2 = newTemp(Ity_I32); 4666 t3 = newTemp(Ity_I64); 4667 t4 = newTemp(Ity_I32); 4668 t5 = newTemp(Ity_I32); 4669 t6 = newTemp(Ity_I64); 4670 t7 = newTemp(Ity_I32); 4671 t9 = newTemp(Ity_I32); 4672 4673 assign(t0, getAcc(ac)); 4674 4675 assign(t1, binop(Iop_Sar64, 4676 mkexpr(t0), 4677 unop(Iop_32to8, 4678 binop(Iop_And32, 4679 getIReg(rs), 4680 mkU32(0x1f))))); 4681 4682 assign(t2, binop(Iop_Or32, 4683 getDSPControl(), mkU32(0x00800000))); 4684 4685 assign(t9, binop(Iop_And32, 4686 unop(Iop_64to32, 4687 mkexpr(t1)), 4688 mkU32(0x80000000))); 4689 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4690 mkexpr(t9), 4691 binop(Iop_And32, 4692 unop(Iop_64HIto32, 4693 mkexpr(t0)), 4694 mkU32(0x80000000))), 4695 mkexpr(t2), 4696 getDSPControl())); 4697 4698 /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0) 4699 1. subtract 0x7fff from t1 4700 2. if the resulting number is positive (sign bit = 0) 4701 and any of the other bits is 1, the value is > 0. */ 4702 assign(t3, binop(Iop_Sub64, 4703 mkexpr(t1), 4704 mkU64(0x0000000000007fffULL))); 4705 assign(t4, binop(Iop_And32, 4706 binop(Iop_Or32, 4707 unop(Iop_1Sto32, 4708 binop(Iop_CmpNE32, 4709 mkU32(0), 4710 binop(Iop_And32, 4711 unop(Iop_64HIto32, 4712 mkexpr(t3)), 4713 mkU32(0x7fffffff)))), 4714 unop(Iop_1Sto32, 4715 binop(Iop_CmpNE32, 4716 mkU32(0), 4717 unop(Iop_64to32, 4718 mkexpr(t3))))), 4719 unop(Iop_1Sto32, 4720 binop(Iop_CmpEQ32, 4721 binop(Iop_And32, 4722 unop(Iop_64HIto32, 4723 mkexpr(t3)), 4724 mkU32(0x80000000)), 4725 mkU32(0))))); 4726 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4727 mkU32(0), 4728 mkexpr(t4)), 4729 binop(Iop_Or32, 4730 getDSPControl(), 4731 mkU32(0x00800000)), 4732 getDSPControl())); 4733 /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0 4734 1. subtract t1 from 0xffffffffffff8000 4735 2. if the resulting number is positive (sign bit = 0) 4736 and any of the other bits is 1, the value is > 0 */ 4737 assign(t6, binop(Iop_Sub64, 4738 mkU64(0xffffffffffff8000ULL), 4739 mkexpr(t1))); 4740 assign(t7, binop(Iop_And32, 4741 binop(Iop_Or32, 4742 unop(Iop_1Sto32, 4743 binop(Iop_CmpNE32, 4744 mkU32(0), 4745 binop(Iop_And32, 4746 unop(Iop_64HIto32, 4747 mkexpr(t6)), 4748 mkU32(0x7fffffff)))), 4749 unop(Iop_1Sto32, 4750 binop(Iop_CmpNE32, 4751 mkU32(0), 4752 unop(Iop_64to32, 4753 mkexpr(t6))))), 4754 unop(Iop_1Sto32, 4755 binop(Iop_CmpEQ32, 4756 binop(Iop_And32, 4757 unop(Iop_64HIto32, 4758 mkexpr(t6)), 4759 mkU32(0x80000000)), 4760 mkU32(0))))); 4761 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 4762 mkU32(0), 4763 mkexpr(t7)), 4764 binop(Iop_Or32, 4765 getDSPControl(), 4766 mkU32(0x00800000)), 4767 getDSPControl())); 4768 putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32, 4769 mkU32(0), 4770 mkexpr(t4)), 4771 mkU32(0x00007fff), 4772 IRExpr_ITE(binop(Iop_CmpNE32, 4773 mkU32(0), 4774 mkexpr(t7)), 4775 mkU32(0xffff8000), 4776 unop(Iop_64to32, 4777 mkexpr(t1))))); 4778 break; 4779 } 4780 case 0x12: { /* RDDSP*/ 4781 DIP("rddsp r%d, mask 0x%x", rd, rddsp_mask); 4782 vassert(!mode64); 4783 4784 putIReg(rd, mkU32(0x0)); 4785 4786 if ((rddsp_mask & 0x1) == 0x1) { 4787 /* Read pos field (bits 5-0) of DSPControl register. */ 4788 putIReg(rd, binop(Iop_Or32, 4789 getIReg(rd), 4790 binop(Iop_And32, 4791 getDSPControl(), 4792 mkU32(0x0000003F)))); 4793 } 4794 4795 if ((rddsp_mask & 0x2) == 0x2) { 4796 /* Read scount field (bits 12-7) of DSPControl 4797 register. */ 4798 putIReg(rd, binop(Iop_Or32, 4799 getIReg(rd), 4800 binop(Iop_And32, 4801 getDSPControl(), 4802 mkU32(0x00001F80)))); 4803 } 4804 4805 if ((rddsp_mask & 0x4) == 0x4) { 4806 /* Read C field (bit 13) of DSPControl register. */ 4807 putIReg(rd, binop(Iop_Or32, 4808 getIReg(rd), 4809 binop(Iop_And32, 4810 getDSPControl(), 4811 mkU32(0x00002000)))); 4812 } 4813 4814 if ((rddsp_mask & 0x8) == 0x8) { 4815 /* Read outflag field (bit s 23-16) of DSPControl 4816 register. */ 4817 putIReg(rd, binop(Iop_Or32, 4818 getIReg(rd), 4819 binop(Iop_And32, 4820 getDSPControl(), 4821 mkU32(0x00FF0000)))); 4822 } 4823 4824 if ((rddsp_mask & 0x10) == 0x10) { 4825 /* Read ccond field (bits 31-24) of DSPControl 4826 register. */ 4827 putIReg(rd, binop(Iop_Or32, 4828 getIReg(rd), 4829 binop(Iop_And32, 4830 getDSPControl(), 4831 mkU32(0xFF000000)))); 4832 } 4833 4834 if ((rddsp_mask & 0x20) == 0x20) { 4835 /* Read EFI field (bit 14) of DSPControl register. */ 4836 putIReg(rd, binop(Iop_Or32, 4837 getIReg(rd), 4838 binop(Iop_And32, 4839 getDSPControl(), 4840 mkU32(0x00004000)))); 4841 } 4842 4843 if ((rddsp_mask & 0x3f) == 0x3f) { 4844 /* Read all fields of DSPControl register. */ 4845 putIReg(rd, getDSPControl()); 4846 } 4847 break; 4848 } 4849 case 0x13: { /* WRDSP */ 4850 DIP("wrdsp r%d, mask 0x%x", rs, wrdsp_mask); 4851 vassert(!mode64); 4852 4853 if ((wrdsp_mask & 0x3f) == 0x3f) { 4854 /* If mips64 put all fields of rs, except bit 15 and bit 4855 6, to DSPControl register, otherwise put all except 4856 bits 15, 6 and bits 31..28. */ 4857 putDSPControl(mode64 ? 4858 binop(Iop_And32, 4859 getIReg(rs), 4860 mkU32(0xffff7fbf)) : 4861 binop(Iop_And32, 4862 getIReg(rs), 4863 mkU32(0x0fff7fbf))); 4864 } else { 4865 if ((wrdsp_mask & 0x1) == 0x1) { 4866 /* Put bits 5-0 of rs to DSPControl register pos 4867 field. */ 4868 putDSPControl(binop(Iop_Or32, 4869 binop(Iop_And32, 4870 getDSPControl(), 4871 mkU32(0xFFFF7F40)), 4872 binop(Iop_And32, 4873 getIReg(rs), 4874 mkU32(0x0000003F)))); 4875 } 4876 4877 if ((wrdsp_mask & 0x2) == 0x2) { 4878 /* Put bits 12-7 of rs to DSPControl scount field. */ 4879 putDSPControl(binop(Iop_Or32, 4880 binop(Iop_And32, 4881 getDSPControl(), 4882 mkU32(0xFFFFE03F)), 4883 binop(Iop_And32, 4884 getIReg(rs), 4885 mkU32(0x00001F80)))); 4886 } 4887 4888 if ((wrdsp_mask & 0x4) == 0x4) { 4889 /* Put bit 13 of rs to DSPControl register C 4890 field. */ 4891 putDSPControl(binop(Iop_Or32, 4892 binop(Iop_And32, 4893 getDSPControl(), 4894 mkU32(0xFFFF5FBF)), 4895 binop(Iop_And32, 4896 getIReg(rs), 4897 mkU32(0x00002000)))); 4898 } 4899 4900 if ((wrdsp_mask & 0x8) == 0x8) { 4901 /* Put bits 23-16 of rs to DSPControl reg outflag 4902 field. */ 4903 putDSPControl(binop(Iop_Or32, 4904 binop(Iop_And32, 4905 getDSPControl(), 4906 mkU32(0xFF007FBF)), 4907 binop(Iop_And32, 4908 getIReg(rs), 4909 mkU32(0x00FF0000)))); 4910 } 4911 4912 if ((wrdsp_mask & 0x10) == 0x10) { 4913 /* Put bits 31-24 of rs to DSPControl reg ccond 4914 field. */ 4915 putDSPControl(binop(Iop_Or32, 4916 binop(Iop_And32, 4917 getDSPControl(), 4918 mkU32(0x00FF7FBF)), 4919 binop(Iop_And32, 4920 getIReg(rs), 4921 mode64 ? mkU32(0xFF000000) 4922 : mkU32(0x0F000000)) 4923 ) 4924 ); 4925 } 4926 4927 if ((wrdsp_mask & 0x20) == 0x20) { 4928 /* Put bit 14 of rs to DSPControl register EFI 4929 field. */ 4930 putDSPControl(binop(Iop_Or32, 4931 binop(Iop_And32, 4932 getDSPControl(), 4933 mkU32(0xFFFF3FBF)), 4934 binop(Iop_And32, 4935 getIReg(rs), 4936 mkU32(0x00004000)))); 4937 } 4938 } 4939 break; 4940 } 4941 case 0x1A: { /* SHILO */ 4942 DIP("shilo ac%d, %d", ac, shift); 4943 vassert(!mode64); 4944 t0 = newTemp(Ity_I64); 4945 t1 = newTemp(Ity_I64); 4946 4947 assign(t0, getAcc(ac)); 4948 4949 putAcc(ac, mkexpr(t0)); 4950 4951 if (0x20 == (shift & 0x3f)) { 4952 putAcc(ac, binop(Iop_32HLto64, 4953 unop(Iop_64to32, mkexpr(t0)), 4954 mkU32(0x0))); 4955 } else if (0x20 == (shift & 0x20)) { 4956 assign(t1, binop(Iop_Shl64, 4957 mkexpr(t0), 4958 unop(Iop_32to8, 4959 binop(Iop_Add32, 4960 unop(Iop_Not32, 4961 mkU32(shift)), 4962 mkU32(0x1))))); 4963 4964 putAcc(ac, mkexpr(t1)); 4965 } else { 4966 assign(t1, binop(Iop_Shr64, mkexpr(t0), mkU8(shift))); 4967 4968 putAcc(ac, mkexpr(t1)); 4969 } 4970 break; 4971 } 4972 case 0x1B: { /* SHILOV */ 4973 DIP("shilov ac%d, r%d", ac, rs); 4974 vassert(!mode64); 4975 t0 = newTemp(Ity_I64); 4976 t1 = newTemp(Ity_I32); 4977 t2 = newTemp(Ity_I1); 4978 t3 = newTemp(Ity_I64); 4979 t4 = newTemp(Ity_I64); 4980 4981 assign(t0, getAcc(ac)); 4982 assign(t1, binop(Iop_And32, getIReg(rs), mkU32(0x3f))); 4983 assign(t2, binop(Iop_CmpEQ32, mkexpr(t1), mkU32(0x20))); 4984 assign(t3, binop(Iop_Shl64, 4985 mkexpr(t0), 4986 unop(Iop_32to8, 4987 binop(Iop_Add32, 4988 unop(Iop_Not32, 4989 mkexpr(t1)), 4990 mkU32(0x1))))); 4991 assign(t4, binop(Iop_Shr64, 4992 mkexpr(t0), 4993 unop(Iop_32to8, 4994 mkexpr(t1)))); 4995 4996 putAcc(ac, 4997 IRExpr_ITE(mkexpr(t2), 4998 binop(Iop_32HLto64, 4999 unop(Iop_64to32, mkexpr(t0)), 5000 mkU32(0x0)), 5001 IRExpr_ITE(binop(Iop_CmpEQ32, 5002 binop(Iop_And32, 5003 mkexpr(t1), 5004 mkU32(0x20)), 5005 mkU32(0x20)), 5006 mkexpr(t3), 5007 mkexpr(t4)))); 5008 break; 5009 } 5010 case 0x1F: { /* MTHLIP */ 5011 DIP("mthlip r%d, ac%d", rs, ac); 5012 vassert(!mode64); 5013 t0 = newTemp(Ity_I64); 5014 t1 = newTemp(Ity_I32); 5015 t2 = newTemp(Ity_I32); 5016 t3 = newTemp(Ity_I1); 5017 5018 assign(t0, getAcc(ac)); 5019 putAcc(ac, binop(Iop_32HLto64, 5020 unop(Iop_64to32, mkexpr(t0)), 5021 getIReg(rs))); 5022 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f))); 5023 putDSPControl(IRExpr_ITE(binop(Iop_CmpLE32U, 5024 mkU32(32), 5025 mkexpr(t1)), 5026 binop(Iop_Or32, 5027 binop(Iop_Sub32, 5028 mkexpr(t1), 5029 mkU32(32)), 5030 binop(Iop_And32, 5031 getDSPControl(), 5032 mkU32(0xffffffc0))), 5033 binop(Iop_Or32, 5034 binop(Iop_Add32, 5035 mkexpr(t1), 5036 mkU32(32)), 5037 binop(Iop_And32, 5038 getDSPControl(), 5039 mkU32(0xffffffc0))))); 5040 break; 5041 } 5042 default: 5043 return -1; 5044 } 5045 break; /* end of EXTR.W */ 5046 } 5047 case 0xA: { /* LX */ 5048 switch(sa) { 5049 case 0x0: { /* LWX */ 5050 DIP("lwx r%d, r%d(r%d)", rd, rt, rs); 5051 vassert(!mode64); 5052 t0 = newTemp(Ity_I32); 5053 5054 assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs))); 5055 5056 putIReg(rd, load(Ity_I32, mkexpr(t0))); 5057 break; 5058 } 5059 case 0x4: { /* LHX */ 5060 DIP("lhx r%d, r%d(r%d)", rd, rt, rs); 5061 vassert(!mode64); 5062 t0 = newTemp(Ity_I32); 5063 5064 assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs))); 5065 5066 putIReg(rd, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t0)))); 5067 break; 5068 } 5069 case 0x6: { /* LBUX */ 5070 DIP("lbux r%d, r%d(r%d)", rd, rt, rs); 5071 vassert(!mode64); 5072 t0 = newTemp(Ity_I32); 5073 5074 assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs))); 5075 5076 putIReg(rd, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t0)))); 5077 break; 5078 } 5079 default: 5080 return -1; 5081 } 5082 break; /* end of LX */ 5083 } 5084 case 0xC: { /* INSV */ 5085 switch(sa) { 5086 case 0x0: { /* INSV */ 5087 DIP("insv r%d, r%d", rt, rs); 5088 vassert(!mode64); 5089 5090 t0 = newTemp(Ity_I32); 5091 t1 = newTemp(Ity_I32); 5092 t2 = newTemp(Ity_I8); 5093 t3 = newTemp(Ity_I8); 5094 t4 = newTemp(Ity_I32); 5095 t5 = newTemp(Ity_I1); 5096 t6 = newTemp(Ity_I32); 5097 t7 = newTemp(Ity_I32); 5098 t8 = newTemp(Ity_I32); 5099 t9 = newTemp(Ity_I32); 5100 5101 /* t0 <- pos field of DSPControl register. */ 5102 assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f))); 5103 /* t1 <- scount field of DSPControl register. */ 5104 assign(t1, binop(Iop_Shr32, 5105 binop(Iop_And32, 5106 getDSPControl(), 5107 mkU32(0x1f80)), 5108 mkU8(7))); 5109 5110 assign(t2, unop(Iop_32to8, 5111 binop(Iop_Add32, 5112 mkexpr(t1), 5113 mkexpr(t0)))); 5114 5115 /* 32-(pos+size) most significant bits of rt. */ 5116 assign(t6, binop(Iop_Shl32, 5117 binop(Iop_Shr32, 5118 getIReg(rt), 5119 mkexpr(t2)), 5120 mkexpr(t2))); 5121 5122 assign(t3, unop(Iop_32to8, 5123 binop(Iop_Sub32, 5124 mkU32(32), 5125 mkexpr(t0)))); 5126 /* Pos least significant bits of rt. */ 5127 assign(t7, binop(Iop_Shr32, 5128 binop(Iop_Shl32, 5129 getIReg(rt), 5130 mkexpr(t3)), 5131 mkexpr(t3))); 5132 5133 /* Size least significant bits of rs, 5134 shifted to appropriate position. */ 5135 assign(t8, binop(Iop_Shl32, 5136 binop(Iop_And32, 5137 getIReg(rs), 5138 unop(Iop_Not32, 5139 binop(Iop_Shl32, 5140 mkU32(0xffffffff), 5141 unop(Iop_32to8, 5142 mkexpr(t1))))), 5143 unop(Iop_32to8, 5144 mkexpr(t0)))); 5145 5146 putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32, 5147 mkexpr(t0), 5148 mkU32(0)), 5149 IRExpr_ITE(binop(Iop_CmpEQ32, 5150 mkexpr(t1), 5151 mkU32(32)), 5152 getIReg(rs), 5153 binop(Iop_Or32, 5154 mkexpr(t6), 5155 mkexpr(t8))), 5156 IRExpr_ITE(binop(Iop_CmpEQ32, 5157 unop(Iop_8Uto32, 5158 mkexpr(t2)), 5159 mkU32(32)), 5160 binop(Iop_Or32, 5161 mkexpr(t7), 5162 mkexpr(t8)), 5163 binop(Iop_Or32, 5164 binop(Iop_Or32, 5165 mkexpr(t6), 5166 mkexpr(t7)), 5167 mkexpr(t8))))); 5168 break; 5169 } 5170 default: 5171 return -1; 5172 } 5173 break; /* enf of INSV */ 5174 } 5175 case 0x10: { /* ADDU.QB */ 5176 switch(sa) { 5177 case 0x00: { /* ADDU.QB */ 5178 DIP("addu.qb r%d, r%d, r%d", rd, rs, rt); 5179 vassert(!mode64); 5180 t0 = newTemp(Ity_I32); 5181 t1 = newTemp(Ity_I1); 5182 t2 = newTemp(Ity_I32); 5183 t3 = newTemp(Ity_I1); 5184 t4 = newTemp(Ity_I32); 5185 t5 = newTemp(Ity_I1); 5186 t6 = newTemp(Ity_I32); 5187 t7 = newTemp(Ity_I1); 5188 t8 = newTemp(Ity_I32); 5189 5190 /* Add rightmost bytes of rs and rt. */ 5191 assign(t0, 5192 binop(Iop_Add32, 5193 unop(Iop_8Uto32, 5194 unop(Iop_16to8, 5195 unop(Iop_32to16, getIReg(rs)))), 5196 unop(Iop_8Uto32, 5197 unop(Iop_16to8, 5198 unop(Iop_32to16, getIReg(rt)))))); 5199 /* t1 will be 1 if there is overflow, 0 otherwise. */ 5200 assign(t1, binop(Iop_CmpEQ32, 5201 binop(Iop_And32, 5202 mkexpr(t0), 5203 mkU32(0x00000100)), 5204 mkU32(0x00000100))); 5205 5206 /* Add bits 15-8 of rs and rt. */ 5207 assign(t2, 5208 binop(Iop_Add32, 5209 unop(Iop_8Uto32, 5210 unop(Iop_16HIto8, 5211 unop(Iop_32to16, getIReg(rs)))), 5212 unop(Iop_8Uto32, 5213 unop(Iop_16HIto8, 5214 unop(Iop_32to16, getIReg(rt)))))); 5215 /* t3 will be 1 if there is overflow, 0 otherwise. */ 5216 assign(t3, binop(Iop_CmpEQ32, 5217 binop(Iop_And32, 5218 mkexpr(t2), 5219 mkU32(0x00000100)), 5220 mkU32(0x00000100))); 5221 5222 /* Add bits 15-8 of rs and rt. */ 5223 assign(t4, 5224 binop(Iop_Add32, 5225 unop(Iop_8Uto32, 5226 unop(Iop_16to8, 5227 unop(Iop_32HIto16, getIReg(rs)))), 5228 unop(Iop_8Uto32, 5229 unop(Iop_16to8, 5230 unop(Iop_32HIto16, getIReg(rt)))))); 5231 /* t5 will be 1 if there is overflow, 0 otherwise. */ 5232 assign(t5, binop(Iop_CmpEQ32, 5233 binop(Iop_And32, 5234 mkexpr(t4), 5235 mkU32(0x00000100)), 5236 mkU32(0x00000100))); 5237 5238 /* Add bits 15-8 of rs and rt. */ 5239 assign(t6, 5240 binop(Iop_Add32, 5241 unop(Iop_8Uto32, 5242 unop(Iop_16HIto8, 5243 unop(Iop_32HIto16, getIReg(rs)))), 5244 unop(Iop_8Uto32, 5245 unop(Iop_16HIto8, 5246 unop(Iop_32HIto16, getIReg(rt)))))); 5247 /* t7 will be 1 if there is overflow, 0 otherwise. */ 5248 assign(t7, binop(Iop_CmpEQ32, 5249 binop(Iop_And32, 5250 mkexpr(t6), 5251 mkU32(0x00000100)), 5252 mkU32(0x00000100))); 5253 5254 assign(t8, 5255 binop(Iop_Or32, 5256 binop(Iop_Or32, 5257 binop(Iop_Or32, 5258 unop(Iop_1Sto32, mkexpr(t7)), 5259 unop(Iop_1Sto32, mkexpr(t5))), 5260 unop(Iop_1Sto32, mkexpr(t3))), 5261 unop(Iop_1Sto32, mkexpr(t1)))); 5262 5263 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 5264 mkexpr(t8), 5265 mkU32(0x0)), 5266 getDSPControl(), 5267 binop(Iop_Or32, 5268 getDSPControl(), 5269 mkU32(0x00100000)))); 5270 5271 putIReg(rd, binop(Iop_16HLto32, 5272 binop(Iop_8HLto16, 5273 unop(Iop_32to8, mkexpr(t6)), 5274 unop(Iop_32to8, mkexpr(t4))), 5275 binop(Iop_8HLto16, 5276 unop(Iop_32to8, mkexpr(t2)), 5277 unop(Iop_32to8, mkexpr(t0))))); 5278 break; 5279 } 5280 case 0x1: { /* SUBU.QB */ 5281 DIP("subu.qb r%d, r%d, r%d", rd, rs, rt); 5282 vassert(!mode64); 5283 t0 = newTemp(Ity_I32); 5284 t1 = newTemp(Ity_I1); 5285 t2 = newTemp(Ity_I32); 5286 t3 = newTemp(Ity_I1); 5287 t4 = newTemp(Ity_I32); 5288 t5 = newTemp(Ity_I1); 5289 t6 = newTemp(Ity_I32); 5290 t7 = newTemp(Ity_I1); 5291 t8 = newTemp(Ity_I32); 5292 5293 /* Subtract rightmost bytes of rs and rt. */ 5294 assign(t0, 5295 binop(Iop_Sub32, 5296 unop(Iop_8Uto32, 5297 unop(Iop_16to8, 5298 unop(Iop_32to16, getIReg(rs)))), 5299 unop(Iop_8Uto32, 5300 unop(Iop_16to8, 5301 unop(Iop_32to16, getIReg(rt)))))); 5302 /* t1 will be 1 if there is overflow, 0 otherwise. */ 5303 assign(t1, binop(Iop_CmpEQ32, 5304 binop(Iop_And32, 5305 mkexpr(t0), 5306 mkU32(0x00000100)), 5307 mkU32(0x00000100))); 5308 5309 /* Subtract bits 15-8 of rs and rt. */ 5310 assign(t2, 5311 binop(Iop_Sub32, 5312 unop(Iop_8Uto32, 5313 unop(Iop_16HIto8, 5314 unop(Iop_32to16, getIReg(rs)))), 5315 unop(Iop_8Uto32, 5316 unop(Iop_16HIto8, 5317 unop(Iop_32to16, getIReg(rt)))))); 5318 /* t3 will be 1 if there is overflow, 0 otherwise. */ 5319 assign(t3, binop(Iop_CmpEQ32, 5320 binop(Iop_And32, 5321 mkexpr(t2), 5322 mkU32(0x00000100)), 5323 mkU32(0x00000100))); 5324 5325 /* Subtract bits 15-8 of rs and rt. */ 5326 assign(t4, 5327 binop(Iop_Sub32, 5328 unop(Iop_8Uto32, 5329 unop(Iop_16to8, 5330 unop(Iop_32HIto16, getIReg(rs)))), 5331 unop(Iop_8Uto32, 5332 unop(Iop_16to8, 5333 unop(Iop_32HIto16, getIReg(rt)))))); 5334 /* t5 will be 1 if there is overflow, 0 otherwise. */ 5335 assign(t5, binop(Iop_CmpEQ32, 5336 binop(Iop_And32, 5337 mkexpr(t4), 5338 mkU32(0x00000100)), 5339 mkU32(0x00000100))); 5340 5341 /* Subtract bits 15-8 of rs and rt. */ 5342 assign(t6, 5343 binop(Iop_Sub32, 5344 unop(Iop_8Uto32, 5345 unop(Iop_16HIto8, 5346 unop(Iop_32HIto16, getIReg(rs)))), 5347 unop(Iop_8Uto32, 5348 unop(Iop_16HIto8, 5349 unop(Iop_32HIto16, getIReg(rt)))))); 5350 /* t7 will be 1 if there is overflow, 0 otherwise. */ 5351 assign(t7, binop(Iop_CmpEQ32, 5352 binop(Iop_And32, 5353 mkexpr(t6), 5354 mkU32(0x00000100)), 5355 mkU32(0x00000100))); 5356 5357 assign(t8, binop(Iop_Or32, 5358 binop(Iop_Or32, 5359 binop(Iop_Or32, 5360 unop(Iop_1Sto32, mkexpr(t7)), 5361 unop(Iop_1Sto32, mkexpr(t5))), 5362 unop(Iop_1Sto32, mkexpr(t3))), 5363 unop(Iop_1Sto32, mkexpr(t1)))); 5364 5365 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 5366 mkexpr(t8), 5367 mkU32(0x0)), 5368 getDSPControl(), 5369 binop(Iop_Or32, 5370 getDSPControl(), 5371 mkU32(0x00100000)))); 5372 5373 putIReg(rd, binop(Iop_16HLto32, 5374 binop(Iop_8HLto16, 5375 unop(Iop_32to8, mkexpr(t6)), 5376 unop(Iop_32to8, mkexpr(t4))), 5377 binop(Iop_8HLto16, 5378 unop(Iop_32to8, mkexpr(t2)), 5379 unop(Iop_32to8, mkexpr(t0))))); 5380 break; 5381 } 5382 case 0x04: { /* ADDU_S.QB */ 5383 DIP("addu_s.qb r%d, r%d, r%d", rd, rs, rt); 5384 vassert(!mode64); 5385 t0 = newTemp(Ity_I32); 5386 t1 = newTemp(Ity_I1); 5387 t2 = newTemp(Ity_I8); 5388 t3 = newTemp(Ity_I32); 5389 t4 = newTemp(Ity_I1); 5390 t5 = newTemp(Ity_I8); 5391 t6 = newTemp(Ity_I32); 5392 t7 = newTemp(Ity_I1); 5393 t8 = newTemp(Ity_I8); 5394 t9 = newTemp(Ity_I32); 5395 t10 = newTemp(Ity_I1); 5396 t11 = newTemp(Ity_I8); 5397 t12 = newTemp(Ity_I32); 5398 5399 /* Add rightmost bytes of rs and rt. */ 5400 assign(t0, 5401 binop(Iop_Add32, 5402 unop(Iop_8Uto32, 5403 unop(Iop_16to8, 5404 unop(Iop_32to16, getIReg(rs)))), 5405 unop(Iop_8Uto32, 5406 unop(Iop_16to8, 5407 unop(Iop_32to16, getIReg(rt)))))); 5408 /* t1 will be 1 if there is overflow, 0 otherwise. */ 5409 assign(t1, binop(Iop_CmpEQ32, 5410 binop(Iop_And32, 5411 mkexpr(t0), 5412 mkU32(0x00000100)), 5413 mkU32(0x00000100))); 5414 /* Saturate if necessary. */ 5415 assign(t2, IRExpr_ITE(mkexpr(t1), 5416 mkU8(0xff), 5417 unop(Iop_32to8, mkexpr(t0)))); 5418 5419 /* Add bits 15-8 of rs and rt. */ 5420 assign(t3, 5421 binop(Iop_Add32, 5422 unop(Iop_8Uto32, 5423 unop(Iop_16HIto8, 5424 unop(Iop_32to16, getIReg(rs)))), 5425 unop(Iop_8Uto32, 5426 unop(Iop_16HIto8, 5427 unop(Iop_32to16, getIReg(rt)))))); 5428 /* t4 will be 1 if there is overflow, 0 otherwise. */ 5429 assign(t4, binop(Iop_CmpEQ32, 5430 binop(Iop_And32, 5431 mkexpr(t3), 5432 mkU32(0x00000100)), 5433 mkU32(0x00000100))); 5434 /* Saturate if necessary. */ 5435 assign(t5, IRExpr_ITE(mkexpr(t4), 5436 mkU8(0xff), 5437 unop(Iop_32to8, mkexpr(t3)))); 5438 5439 /* Add bits 15-8 of rs and rt. */ 5440 assign(t6, 5441 binop(Iop_Add32, 5442 unop(Iop_8Uto32, 5443 unop(Iop_16to8, 5444 unop(Iop_32HIto16, getIReg(rs)))), 5445 unop(Iop_8Uto32, 5446 unop(Iop_16to8, 5447 unop(Iop_32HIto16, getIReg(rt)))))); 5448 /* t7 will be 1 if there is overflow, 0 otherwise. */ 5449 assign(t7, binop(Iop_CmpEQ32, 5450 binop(Iop_And32, 5451 mkexpr(t6), 5452 mkU32(0x00000100)), 5453 mkU32(0x00000100))); 5454 /* Saturate if necessary. */ 5455 assign(t8, IRExpr_ITE(mkexpr(t7), 5456 mkU8(0xff), 5457 unop(Iop_32to8, mkexpr(t6)))); 5458 5459 /* Add bits 15-8 of rs and rt. */ 5460 assign(t9, 5461 binop(Iop_Add32, 5462 unop(Iop_8Uto32, 5463 unop(Iop_16HIto8, 5464 unop(Iop_32HIto16, getIReg(rs)))), 5465 unop(Iop_8Uto32, 5466 unop(Iop_16HIto8, 5467 unop(Iop_32HIto16, getIReg(rt)))))); 5468 /* t10 will be 1 if there is overflow, 0 otherwise. */ 5469 assign(t10, binop(Iop_CmpEQ32, 5470 binop(Iop_And32, 5471 mkexpr(t9), 5472 mkU32(0x00000100)), 5473 mkU32(0x00000100))); 5474 /* Saturate if necessary. */ 5475 assign(t11, IRExpr_ITE(mkexpr(t10), 5476 mkU8(0xff), 5477 unop(Iop_32to8, mkexpr(t9)))); 5478 5479 assign(t12, 5480 binop(Iop_Or32, 5481 binop(Iop_Or32, 5482 binop(Iop_Or32, 5483 unop(Iop_1Sto32, mkexpr(t10)), 5484 unop(Iop_1Sto32, mkexpr(t7))), 5485 unop(Iop_1Sto32, mkexpr(t4))), 5486 unop(Iop_1Sto32, mkexpr(t1)))); 5487 5488 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 5489 mkexpr(t12), 5490 mkU32(0x0)), 5491 getDSPControl(), 5492 binop(Iop_Or32, 5493 getDSPControl(), 5494 mkU32(0x00100000)))); 5495 5496 putIReg(rd, 5497 binop(Iop_16HLto32, 5498 binop(Iop_8HLto16, mkexpr(t11), mkexpr(t8)), 5499 binop(Iop_8HLto16, mkexpr(t5), mkexpr(t2)))); 5500 break; 5501 } 5502 case 0x05: { /* SUBU_S.QB */ 5503 DIP("subu_s.qb r%d, r%d, r%d", rd, rs, rt); 5504 vassert(!mode64); 5505 t1 = newTemp(Ity_I32); 5506 t2 = newTemp(Ity_I1); 5507 t3 = newTemp(Ity_I1); 5508 t4 = newTemp(Ity_I1); 5509 t5 = newTemp(Ity_I1); 5510 t6 = newTemp(Ity_I32); 5511 t7 = newTemp(Ity_I32); 5512 t8 = newTemp(Ity_I32); 5513 t9 = newTemp(Ity_I32); 5514 5515 /* Use C function to easily calculate the result 5516 and write it in the register more conveniently 5517 Underflow is checked using step by step subtraction. */ 5518 assign(t1, binop(Iop_QSub8Ux4, getIReg(rs), getIReg(rt))); 5519 5520 /* Subtract each byte of rs and rt. */ 5521 assign(t6, 5522 binop(Iop_Sub32, 5523 unop(Iop_8Uto32, 5524 unop(Iop_16to8, 5525 unop(Iop_32to16, getIReg(rs)))), 5526 unop(Iop_8Uto32, 5527 unop(Iop_16to8, 5528 unop(Iop_32to16, getIReg(rt)))))); 5529 assign(t7, 5530 binop(Iop_Sub32, 5531 unop(Iop_8Uto32, 5532 unop(Iop_16HIto8, 5533 unop(Iop_32to16, getIReg(rs)))), 5534 unop(Iop_8Uto32, 5535 unop(Iop_16HIto8, 5536 unop(Iop_32to16, getIReg(rt)))))); 5537 assign(t8, 5538 binop(Iop_Sub32, 5539 unop(Iop_8Uto32, 5540 unop(Iop_16to8, 5541 unop(Iop_32HIto16, getIReg(rs)))), 5542 unop(Iop_8Uto32, 5543 unop(Iop_16to8, 5544 unop(Iop_32HIto16, getIReg(rt)))))); 5545 assign(t9, 5546 binop(Iop_Sub32, 5547 unop(Iop_8Uto32, 5548 unop(Iop_16HIto8, 5549 unop(Iop_32HIto16, getIReg(rs)))), 5550 unop(Iop_8Uto32, 5551 unop(Iop_16HIto8, 5552 unop(Iop_32HIto16, getIReg(rt)))))); 5553 5554 /* Put 1 to bit 20 in DSPControl if there is underflow 5555 in either byte. */ 5556 assign(t2, binop(Iop_CmpEQ32, 5557 binop(Iop_And32, 5558 mkexpr(t6), 5559 mkU32(0x00000100)), 5560 mkU32(0x00000100))); 5561 putDSPControl(IRExpr_ITE(mkexpr(t2), 5562 binop(Iop_Or32, 5563 getDSPControl(), 5564 mkU32(0x00100000)), 5565 getDSPControl())); 5566 assign(t3, binop(Iop_CmpEQ32, 5567 binop(Iop_And32, 5568 mkexpr(t7), 5569 mkU32(0x00000100)), 5570 mkU32(0x00000100))); 5571 putDSPControl(IRExpr_ITE(mkexpr(t3), 5572 binop(Iop_Or32, 5573 getDSPControl(), 5574 mkU32(0x00100000)), 5575 getDSPControl())); 5576 assign(t4, binop(Iop_CmpEQ32, 5577 binop(Iop_And32, 5578 mkexpr(t8), 5579 mkU32(0x00000100)), 5580 mkU32(0x00000100))); 5581 putDSPControl(IRExpr_ITE(mkexpr(t4), 5582 binop(Iop_Or32, 5583 getDSPControl(), 5584 mkU32(0x00100000)), 5585 getDSPControl())); 5586 assign(t5, binop(Iop_CmpEQ32, 5587 binop(Iop_And32, 5588 mkexpr(t9), 5589 mkU32(0x00000100)), 5590 mkU32(0x00000100))); 5591 putDSPControl(IRExpr_ITE(mkexpr(t5), 5592 binop(Iop_Or32, 5593 getDSPControl(), 5594 mkU32(0x00100000)), 5595 getDSPControl())); 5596 putIReg(rd, mkexpr(t1)); 5597 break; 5598 } 5599 case 0x6: { /* MULEU_S.PH.QBL */ 5600 DIP("muleu_s.ph.qbl r%d, r%d, r%d", rd, rs, rt); 5601 vassert(!mode64); 5602 t0 = newTemp(Ity_I32); 5603 t1 = newTemp(Ity_I32); 5604 t2 = newTemp(Ity_I1); 5605 t3 = newTemp(Ity_I1); 5606 5607 assign(t0, 5608 unop(Iop_64to32, 5609 binop(Iop_MullU32, 5610 unop(Iop_8Uto32, 5611 unop(Iop_16HIto8, 5612 unop(Iop_32HIto16, 5613 getIReg(rs)))), 5614 unop(Iop_16Uto32, 5615 unop(Iop_32HIto16, getIReg(rt)))))); 5616 assign(t1, 5617 unop(Iop_64to32, 5618 binop(Iop_MullU32, 5619 unop(Iop_8Uto32, 5620 unop(Iop_16to8, 5621 unop(Iop_32HIto16, 5622 getIReg(rs)))), 5623 unop(Iop_16Uto32, 5624 unop(Iop_32to16, getIReg(rt)))))); 5625 5626 assign(t2, binop(Iop_CmpNE32, 5627 mkU32(0x0), 5628 binop(Iop_And32, 5629 mkexpr(t0), 5630 mkU32(0x03ff0000)))); 5631 assign(t3, binop(Iop_CmpNE32, 5632 mkU32(0x0), 5633 binop(Iop_And32, 5634 mkexpr(t1), 5635 mkU32(0x03ff0000)))); 5636 putDSPControl(IRExpr_ITE(mkexpr(t2), 5637 binop(Iop_Or32, 5638 getDSPControl(), 5639 mkU32(0x200000)), 5640 IRExpr_ITE(mkexpr(t3), 5641 binop(Iop_Or32, 5642 getDSPControl(), 5643 mkU32(0x200000)), 5644 getDSPControl()))); 5645 putIReg(rd, 5646 binop(Iop_16HLto32, 5647 IRExpr_ITE(mkexpr(t2), 5648 mkU16(0xffff), 5649 unop(Iop_32to16, mkexpr(t0))), 5650 IRExpr_ITE(mkexpr(t3), 5651 mkU16(0xffff), 5652 unop(Iop_32to16, mkexpr(t1))))); 5653 break; 5654 } 5655 case 0x7: { /* MULEU_S.PH.QBR */ 5656 DIP("muleu_s.ph.qbr r%d, r%d, r%d", rd, rs, rt); 5657 vassert(!mode64); 5658 t0 = newTemp(Ity_I32); 5659 t1 = newTemp(Ity_I32); 5660 t2 = newTemp(Ity_I1); 5661 t3 = newTemp(Ity_I1); 5662 5663 assign(t0, unop(Iop_64to32, 5664 binop(Iop_MullU32, 5665 unop(Iop_8Uto32, 5666 unop(Iop_16HIto8, 5667 unop(Iop_32to16, 5668 getIReg(rs)))), 5669 unop(Iop_16Uto32, 5670 unop(Iop_32HIto16, 5671 getIReg(rt)))))); 5672 assign(t1, unop(Iop_64to32, 5673 binop(Iop_MullU32, 5674 unop(Iop_8Uto32, 5675 unop(Iop_16to8, 5676 unop(Iop_32to16, 5677 getIReg(rs)))), 5678 unop(Iop_16Uto32, 5679 unop(Iop_32to16, 5680 getIReg(rt)))))); 5681 5682 assign(t2, binop(Iop_CmpNE32, 5683 mkU32(0x0), 5684 binop(Iop_And32, 5685 mkexpr(t0), 5686 mkU32(0x03ff0000)))); 5687 assign(t3, binop(Iop_CmpNE32, 5688 mkU32(0x0), 5689 binop(Iop_And32, 5690 mkexpr(t1), 5691 mkU32(0x03ff0000)))); 5692 putDSPControl(IRExpr_ITE(mkexpr(t2), 5693 binop(Iop_Or32, 5694 getDSPControl(), 5695 mkU32(0x200000)), 5696 IRExpr_ITE(mkexpr(t3), 5697 binop(Iop_Or32, 5698 getDSPControl(), 5699 mkU32(0x200000)), 5700 getDSPControl()))); 5701 putIReg(rd, binop(Iop_16HLto32, 5702 IRExpr_ITE(mkexpr(t2), 5703 mkU16(0xffff), 5704 unop(Iop_32to16, 5705 mkexpr(t0))), 5706 IRExpr_ITE(mkexpr(t3), 5707 mkU16(0xffff), 5708 unop(Iop_32to16, 5709 mkexpr(t1))))); 5710 break; 5711 } 5712 case 0x08: { /* ADDU.PH */ 5713 DIP("addu.ph r%d, r%d, r%d", rd, rs, rt); 5714 vassert(!mode64); 5715 t0 = newTemp(Ity_I32); 5716 t1 = newTemp(Ity_I1); 5717 t2 = newTemp(Ity_I32); 5718 t3 = newTemp(Ity_I1); 5719 5720 /* Add lower halves. */ 5721 assign(t0, binop(Iop_Add32, 5722 unop(Iop_16Uto32, 5723 unop(Iop_32to16, getIReg(rs))), 5724 unop(Iop_16Uto32, 5725 unop(Iop_32to16, getIReg(rt))))); 5726 5727 /* Detect overflow. */ 5728 assign(t1, binop(Iop_CmpLT32U, 5729 unop(Iop_16Uto32, 5730 unop(Iop_32to16, mkexpr(t0))), 5731 unop(Iop_16Uto32, 5732 unop(Iop_32to16, getIReg(rs))))); 5733 5734 putDSPControl(IRExpr_ITE(mkexpr(t1), 5735 binop(Iop_Or32, 5736 getDSPControl(), 5737 mkU32(0x00100000)), 5738 getDSPControl())); 5739 5740 /* Add higher halves. */ 5741 assign(t2, binop(Iop_Add32, 5742 unop(Iop_16Uto32, 5743 unop(Iop_32HIto16, getIReg(rs))), 5744 unop(Iop_16Uto32, 5745 unop(Iop_32HIto16, getIReg(rt))))); 5746 5747 /* Detect overflow. */ 5748 assign(t3, binop(Iop_CmpLT32U, 5749 unop(Iop_16Uto32, 5750 unop(Iop_32to16, mkexpr(t2))), 5751 unop(Iop_16Uto32, 5752 unop(Iop_32HIto16, 5753 getIReg(rs))))); 5754 5755 putDSPControl(IRExpr_ITE(mkexpr(t3), 5756 binop(Iop_Or32, 5757 getDSPControl(), 5758 mkU32(0x00100000)), 5759 getDSPControl())); 5760 5761 putIReg(rd, binop(Iop_16HLto32, 5762 unop(Iop_32to16, mkexpr(t2)), 5763 unop(Iop_32to16, mkexpr(t0)))); 5764 break; 5765 } 5766 case 0x9: { /* SUBU.PH */ 5767 DIP("subu.ph r%d, r%d, r%d", rd, rs, rt); 5768 vassert(!mode64); 5769 t0 = newTemp(Ity_I32); 5770 t1 = newTemp(Ity_I1); 5771 t2 = newTemp(Ity_I32); 5772 t3 = newTemp(Ity_I1); 5773 5774 /* Substract lower halves. */ 5775 assign(t0, binop(Iop_Sub32, 5776 unop(Iop_16Uto32, 5777 unop(Iop_32to16, getIReg(rs))), 5778 unop(Iop_16Uto32, 5779 unop(Iop_32to16, getIReg(rt))))); 5780 5781 /* Detect underflow. */ 5782 assign(t1, binop(Iop_CmpNE32, 5783 binop(Iop_And32, 5784 mkexpr(t0), 5785 mkU32(0x00010000)), 5786 mkU32(0x0))); 5787 5788 putDSPControl(IRExpr_ITE(mkexpr(t1), 5789 binop(Iop_Or32, 5790 getDSPControl(), 5791 mkU32(0x00100000)), 5792 getDSPControl())); 5793 5794 /* Subtract higher halves. */ 5795 assign(t2, binop(Iop_Sub32, 5796 unop(Iop_16Uto32, 5797 unop(Iop_32HIto16, getIReg(rs))), 5798 unop(Iop_16Uto32, 5799 unop(Iop_32HIto16, getIReg(rt))))); 5800 5801 /* Detect underflow. */ 5802 assign(t3, binop(Iop_CmpNE32, 5803 binop(Iop_And32, 5804 mkexpr(t2), 5805 mkU32(0x00010000)), 5806 mkU32(0x0))); 5807 5808 putDSPControl(IRExpr_ITE(mkexpr(t3), 5809 binop(Iop_Or32, 5810 getDSPControl(), 5811 mkU32(0x00100000)), 5812 getDSPControl())); 5813 5814 putIReg(rd, binop(Iop_16HLto32, 5815 unop(Iop_32to16, mkexpr(t2)), 5816 unop(Iop_32to16, mkexpr(t0)))); 5817 break; 5818 } 5819 case 0xA: { /* ADDQ.PH */ 5820 DIP("addq.ph r%d, r%d, r%d", rd, rs, rt); 5821 vassert(!mode64); 5822 t0 = newTemp(Ity_I32); 5823 t1 = newTemp(Ity_I1); 5824 t2 = newTemp(Ity_I32); 5825 t3 = newTemp(Ity_I1); 5826 t6 = newTemp(Ity_I32); 5827 t7 = newTemp(Ity_I32); 5828 5829 /* Add lower halves. */ 5830 assign(t0, binop(Iop_Add32, 5831 unop(Iop_16Sto32, 5832 unop(Iop_32to16, getIReg(rs))), 5833 unop(Iop_16Sto32, 5834 unop(Iop_32to16, getIReg(rt))))); 5835 5836 /* Bit 16 of the result. */ 5837 assign(t6, binop(Iop_And32, 5838 unop(Iop_16Uto32, 5839 unop(Iop_32HIto16, mkexpr(t0))), 5840 mkU32(0x1))); 5841 /* Detect overflow. */ 5842 assign(t1, binop(Iop_CmpNE32, 5843 binop(Iop_Shr32, 5844 binop(Iop_And32, 5845 mkexpr(t0), 5846 mkU32(0x8000)), 5847 mkU8(15)), 5848 mkexpr(t6))); 5849 5850 putDSPControl(IRExpr_ITE(mkexpr(t1), 5851 binop(Iop_Or32, 5852 getDSPControl(), 5853 mkU32(0x00100000)), 5854 getDSPControl())); 5855 5856 /* Add higher halves. */ 5857 assign(t2, binop(Iop_Add32, 5858 unop(Iop_16Sto32, 5859 unop(Iop_32HIto16, getIReg(rs))), 5860 unop(Iop_16Sto32, 5861 unop(Iop_32HIto16, getIReg(rt))))); 5862 5863 /* Bit 16 of the result. */ 5864 assign(t7, binop(Iop_And32, 5865 unop(Iop_16Uto32, 5866 unop(Iop_32HIto16, mkexpr(t2))), 5867 mkU32(0x1))); 5868 /* Detect overflow. */ 5869 assign(t3, binop(Iop_CmpNE32, 5870 binop(Iop_Shr32, 5871 binop(Iop_And32, 5872 mkexpr(t2), 5873 mkU32(0x00008000)), 5874 mkU8(15)), 5875 mkexpr(t7))); 5876 5877 putDSPControl(IRExpr_ITE(mkexpr(t3), 5878 binop(Iop_Or32, 5879 getDSPControl(), 5880 mkU32(0x00100000)), 5881 getDSPControl())); 5882 5883 putIReg(rd, binop(Iop_16HLto32, 5884 unop(Iop_32to16, mkexpr(t2)), 5885 unop(Iop_32to16, mkexpr(t0)))); 5886 break; 5887 } 5888 case 0xB: { /* SUBQ.PH */ 5889 DIP("subq.ph r%d, r%d, r%d", rd, rs, rt); 5890 vassert(!mode64); 5891 t0 = newTemp(Ity_I32); 5892 t1 = newTemp(Ity_I1); 5893 t2 = newTemp(Ity_I32); 5894 t3 = newTemp(Ity_I1); 5895 t6 = newTemp(Ity_I32); 5896 t7 = newTemp(Ity_I32); 5897 5898 /* Subtract lower halves. */ 5899 assign(t0, binop(Iop_Sub32, 5900 unop(Iop_16Sto32, 5901 unop(Iop_32to16, getIReg(rs))), 5902 unop(Iop_16Sto32, 5903 unop(Iop_32to16, getIReg(rt))))); 5904 5905 /* Bit 16 of the result. */ 5906 assign(t6, binop(Iop_And32, 5907 unop(Iop_16Uto32, 5908 unop(Iop_32HIto16, mkexpr(t0))), 5909 mkU32(0x1))); 5910 /* Compare the signs of input value and the result. */ 5911 assign(t1, binop(Iop_CmpNE32, 5912 binop(Iop_Shr32, 5913 binop(Iop_And32, 5914 mkexpr(t0), 5915 mkU32(0x8000)), 5916 mkU8(15)), 5917 mkexpr(t6))); 5918 5919 putDSPControl(IRExpr_ITE(mkexpr(t1), 5920 binop(Iop_Or32, 5921 getDSPControl(), 5922 mkU32(0x00100000)), 5923 getDSPControl())); 5924 5925 /* Subtract higher halves. */ 5926 assign(t2, binop(Iop_Sub32, 5927 unop(Iop_16Sto32, 5928 unop(Iop_32HIto16, getIReg(rs))), 5929 unop(Iop_16Sto32, 5930 unop(Iop_32HIto16, getIReg(rt))))); 5931 5932 /* Bit 16 of the result. */ 5933 assign(t7, binop(Iop_And32, 5934 unop(Iop_16Uto32, 5935 unop(Iop_32HIto16, mkexpr(t2))), 5936 mkU32(0x1))); 5937 /* Compare the signs of input value and the result. */ 5938 assign(t3, binop(Iop_CmpNE32, 5939 binop(Iop_Shr32, 5940 binop(Iop_And32, 5941 mkexpr(t2), 5942 mkU32(0x00008000)), 5943 mkU8(15)), 5944 mkexpr(t7))); 5945 5946 putDSPControl(IRExpr_ITE(mkexpr(t3), 5947 binop(Iop_Or32, 5948 getDSPControl(), 5949 mkU32(0x00100000)), 5950 getDSPControl())); 5951 5952 putIReg(rd, binop(Iop_16HLto32, 5953 unop(Iop_32to16, mkexpr(t2)), 5954 unop(Iop_32to16, mkexpr(t0)))); 5955 break; 5956 } 5957 case 0xC: { /* ADDU_S.PH */ 5958 DIP("addu_s.ph r%d, r%d, r%d", rd, rs, rt); 5959 vassert(!mode64); 5960 t0 = newTemp(Ity_I32); 5961 t1 = newTemp(Ity_I1); 5962 t2 = newTemp(Ity_I32); 5963 t3 = newTemp(Ity_I1); 5964 5965 /* Add lower halves. */ 5966 assign(t0, binop(Iop_Add32, 5967 unop(Iop_16Uto32, 5968 unop(Iop_32to16, getIReg(rs))), 5969 unop(Iop_16Uto32, 5970 unop(Iop_32to16, getIReg(rt))))); 5971 5972 /* Detect overflow. */ 5973 assign(t1, binop(Iop_CmpLT32U, 5974 unop(Iop_16Uto32, 5975 unop(Iop_32to16, mkexpr(t0))), 5976 unop(Iop_16Uto32, 5977 unop(Iop_32to16, getIReg(rs))))); 5978 5979 putDSPControl(IRExpr_ITE(mkexpr(t1), 5980 binop(Iop_Or32, 5981 getDSPControl(), 5982 mkU32(0x00100000)), 5983 getDSPControl())); 5984 5985 /* Add higher halves. */ 5986 assign(t2, binop(Iop_Add32, 5987 unop(Iop_16Uto32, 5988 unop(Iop_32HIto16, getIReg(rs))), 5989 unop(Iop_16Uto32, 5990 unop(Iop_32HIto16, getIReg(rt))))); 5991 5992 /* Detect overflow. */ 5993 assign(t3, binop(Iop_CmpLT32U, 5994 unop(Iop_16Uto32, 5995 unop(Iop_32to16, mkexpr(t2))), 5996 unop(Iop_16Uto32, 5997 unop(Iop_32HIto16, getIReg(rs))))); 5998 5999 putDSPControl(IRExpr_ITE(mkexpr(t3), 6000 binop(Iop_Or32, 6001 getDSPControl(), 6002 mkU32(0x00100000)), 6003 getDSPControl())); 6004 6005 putIReg(rd, binop(Iop_16HLto32, 6006 IRExpr_ITE(mkexpr(t3), 6007 mkU16(0xffff), 6008 unop(Iop_32to16, 6009 mkexpr(t2))), 6010 IRExpr_ITE(mkexpr(t1), 6011 mkU16(0xffff), 6012 unop(Iop_32to16, 6013 mkexpr(t0))))); 6014 break; 6015 } 6016 case 0xD: { /* SUBU_S.PH */ 6017 DIP("subu_s.ph r%d, r%d, r%d", rd, rs, rt); 6018 vassert(!mode64); 6019 t0 = newTemp(Ity_I32); 6020 t1 = newTemp(Ity_I1); 6021 t2 = newTemp(Ity_I32); 6022 t3 = newTemp(Ity_I1); 6023 6024 /* Subtract lower halves. */ 6025 assign(t0, binop(Iop_Sub32, 6026 unop(Iop_16Uto32, 6027 unop(Iop_32to16, getIReg(rs))), 6028 unop(Iop_16Uto32, 6029 unop(Iop_32to16, getIReg(rt))))); 6030 6031 /* Detect underflow. */ 6032 assign(t1, binop(Iop_CmpNE32, 6033 binop(Iop_And32, 6034 mkexpr(t0), mkU32(0x00010000)), 6035 mkU32(0x0))); 6036 6037 putDSPControl(IRExpr_ITE(mkexpr(t1), 6038 binop(Iop_Or32, 6039 getDSPControl(), 6040 mkU32(0x00100000)), 6041 getDSPControl())); 6042 6043 /* Subtract higher halves. */ 6044 assign(t2, binop(Iop_Sub32, 6045 unop(Iop_16Uto32, 6046 unop(Iop_32HIto16, getIReg(rs))), 6047 unop(Iop_16Uto32, 6048 unop(Iop_32HIto16, getIReg(rt))))); 6049 6050 /* Detect underflow. */ 6051 assign(t3, binop(Iop_CmpNE32, 6052 binop(Iop_And32, 6053 mkexpr(t2), mkU32(0x00010000)), 6054 mkU32(0x0))); 6055 6056 putDSPControl(IRExpr_ITE(mkexpr(t3), 6057 binop(Iop_Or32, 6058 getDSPControl(), 6059 mkU32(0x00100000)), 6060 getDSPControl())); 6061 6062 putIReg(rd, 6063 binop(Iop_16HLto32, 6064 IRExpr_ITE(mkexpr(t3), 6065 mkU16(0x0000), 6066 unop(Iop_32to16, mkexpr(t2))), 6067 IRExpr_ITE(mkexpr(t1), 6068 mkU16(0x0000), 6069 unop(Iop_32to16, mkexpr(t0))))); 6070 break; 6071 } 6072 case 0xE: { /* ADDQ_S.PH */ 6073 DIP("addq_s.ph r%d r%d, r%d", rd, rs, rt); 6074 vassert(!mode64); 6075 t0 = newTemp(Ity_I32); 6076 t1 = newTemp(Ity_I1); 6077 t2 = newTemp(Ity_I32); 6078 t3 = newTemp(Ity_I1); 6079 t4 = newTemp(Ity_I16); 6080 t5 = newTemp(Ity_I16); 6081 t6 = newTemp(Ity_I32); 6082 t7 = newTemp(Ity_I32); 6083 6084 /* Add lower halves. */ 6085 assign(t0, binop(Iop_Add32, 6086 unop(Iop_16Sto32, 6087 unop(Iop_32to16, getIReg(rs))), 6088 unop(Iop_16Sto32, 6089 unop(Iop_32to16, getIReg(rt))))); 6090 6091 /* Bit 16 of the result. */ 6092 assign(t6, binop(Iop_And32, 6093 unop(Iop_16Uto32, 6094 unop(Iop_32HIto16, mkexpr(t0))), 6095 mkU32(0x1))); 6096 /* Detect overflow. */ 6097 assign(t1, binop(Iop_CmpNE32, 6098 binop(Iop_Shr32, 6099 binop(Iop_And32, 6100 mkexpr(t0), 6101 mkU32(0x8000)), 6102 mkU8(15)), 6103 mkexpr(t6))); 6104 6105 putDSPControl(IRExpr_ITE(mkexpr(t1), 6106 binop(Iop_Or32, 6107 getDSPControl(), 6108 mkU32(0x00100000)), 6109 getDSPControl())); 6110 /* Saturate if needed. */ 6111 assign(t4, IRExpr_ITE(mkexpr(t1), 6112 IRExpr_ITE(binop(Iop_CmpEQ32, 6113 mkexpr(t6), 6114 mkU32(0x0)), 6115 mkU16(0x7fff), 6116 mkU16(0x8000)), 6117 unop(Iop_32to16, mkexpr(t0)))); 6118 6119 /* Add higher halves. */ 6120 assign(t2, binop(Iop_Add32, 6121 unop(Iop_16Sto32, 6122 unop(Iop_32HIto16, getIReg(rs))), 6123 unop(Iop_16Sto32, 6124 unop(Iop_32HIto16, getIReg(rt))))); 6125 6126 /* Bit 16 of the result. */ 6127 assign(t7, binop(Iop_And32, 6128 unop(Iop_16Uto32, 6129 unop(Iop_32HIto16, mkexpr(t2))), 6130 mkU32(0x1))); 6131 /* Detect overflow. */ 6132 assign(t3, binop(Iop_CmpNE32, 6133 binop(Iop_Shr32, 6134 binop(Iop_And32, 6135 mkexpr(t2), 6136 mkU32(0x00008000)), 6137 mkU8(15)), 6138 mkexpr(t7))); 6139 6140 putDSPControl(IRExpr_ITE(mkexpr(t3), 6141 binop(Iop_Or32, 6142 getDSPControl(), 6143 mkU32(0x00100000)), 6144 getDSPControl())); 6145 /* Saturate if needed. */ 6146 assign(t5, IRExpr_ITE(mkexpr(t3), 6147 IRExpr_ITE(binop(Iop_CmpEQ32, 6148 mkexpr(t7), 6149 mkU32(0x0)), 6150 mkU16(0x7fff), 6151 mkU16(0x8000)), 6152 unop(Iop_32to16, mkexpr(t2)))); 6153 6154 putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4))); 6155 break; 6156 } 6157 case 0xF: { /* SUBQ_S.PH */ 6158 DIP("subq_s.ph r%d r%d, r%d", rd, rs, rt); 6159 vassert(!mode64); 6160 t0 = newTemp(Ity_I32); 6161 t1 = newTemp(Ity_I1); 6162 t2 = newTemp(Ity_I32); 6163 t3 = newTemp(Ity_I1); 6164 t4 = newTemp(Ity_I16); 6165 t5 = newTemp(Ity_I16); 6166 t6 = newTemp(Ity_I32); 6167 t7 = newTemp(Ity_I32); 6168 6169 /* Subtract lower halves. */ 6170 assign(t0, binop(Iop_Sub32, 6171 unop(Iop_16Sto32, 6172 unop(Iop_32to16, getIReg(rs))), 6173 unop(Iop_16Sto32, 6174 unop(Iop_32to16, getIReg(rt))))); 6175 6176 /* Bit 16 of the result. */ 6177 assign(t6, binop(Iop_And32, 6178 unop(Iop_16Uto32, 6179 unop(Iop_32HIto16, mkexpr(t0))), 6180 mkU32(0x1))); 6181 /* Detect overflow or underflow. */ 6182 assign(t1, binop(Iop_CmpNE32, 6183 binop(Iop_Shr32, 6184 binop(Iop_And32, 6185 mkexpr(t0), 6186 mkU32(0x8000)), 6187 mkU8(15)), 6188 mkexpr(t6))); 6189 6190 putDSPControl(IRExpr_ITE(mkexpr(t1), 6191 binop(Iop_Or32, 6192 getDSPControl(), 6193 mkU32(0x00100000)), 6194 getDSPControl())); 6195 /* Saturate if needed. */ 6196 assign(t4, IRExpr_ITE(mkexpr(t1), 6197 IRExpr_ITE(binop(Iop_CmpEQ32, 6198 mkexpr(t6), 6199 mkU32(0x0)), 6200 mkU16(0x7fff), 6201 mkU16(0x8000)), 6202 unop(Iop_32to16, mkexpr(t0)))); 6203 6204 /* Subtract higher halves. */ 6205 assign(t2, binop(Iop_Sub32, 6206 unop(Iop_16Sto32, 6207 unop(Iop_32HIto16, getIReg(rs))), 6208 unop(Iop_16Sto32, 6209 unop(Iop_32HIto16, getIReg(rt))))); 6210 6211 /* Bit 16 of the result. */ 6212 assign(t7, binop(Iop_And32, 6213 unop(Iop_16Uto32, 6214 unop(Iop_32HIto16, mkexpr(t2))), 6215 mkU32(0x1))); 6216 /* Detect overflow or underflow. */ 6217 assign(t3, binop(Iop_CmpNE32, 6218 binop(Iop_Shr32, 6219 binop(Iop_And32, 6220 mkexpr(t2), 6221 mkU32(0x00008000)), 6222 mkU8(15)), 6223 mkexpr(t7))); 6224 6225 putDSPControl(IRExpr_ITE(mkexpr(t3), 6226 binop(Iop_Or32, 6227 getDSPControl(), 6228 mkU32(0x00100000)), 6229 getDSPControl())); 6230 /* Saturate if needed. */ 6231 assign(t5, IRExpr_ITE(mkexpr(t3), 6232 IRExpr_ITE(binop(Iop_CmpEQ32, 6233 mkexpr(t7), 6234 mkU32(0x0)), 6235 mkU16(0x7fff), 6236 mkU16(0x8000)), 6237 unop(Iop_32to16, mkexpr(t2)))); 6238 6239 putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4))); 6240 break; 6241 } 6242 case 0x10: { /* ADDSC */ 6243 DIP("addsc r%d, r%d, r%d", rd, rs, rt); 6244 vassert(!mode64); 6245 t0 = newTemp(Ity_I64); 6246 t1 = newTemp(Ity_I1); 6247 6248 /* The carry bit result out of the addition operation is 6249 written to bit 13(the c field) of the DSPControl reg. */ 6250 assign(t0, binop(Iop_Add64, 6251 unop(Iop_32Uto64, getIReg(rs)), 6252 unop(Iop_32Uto64, getIReg(rt)))); 6253 6254 assign(t1, binop(Iop_CmpEQ32, 6255 binop(Iop_And32, 6256 unop(Iop_64HIto32, mkexpr(t0)), 6257 mkU32(0x1)), 6258 mkU32(0x1))); 6259 putDSPControl(IRExpr_ITE(mkexpr(t1), 6260 binop(Iop_Or32, 6261 getDSPControl(), 6262 mkU32(0x2000)), 6263 binop(Iop_And32, 6264 getDSPControl(), 6265 mkU32(0xffffdfff)))); 6266 6267 putIReg(rd, unop(Iop_64to32, mkexpr(t0))); 6268 break; 6269 } 6270 case 0x11: { /* ADDWC */ 6271 DIP("addwc r%d, r%d, r%d", rd, rs, rt); 6272 vassert(!mode64); 6273 t0 = newTemp(Ity_I32); 6274 t1 = newTemp(Ity_I64); 6275 t2 = newTemp(Ity_I32); 6276 t3 = newTemp(Ity_I32); 6277 t4 = newTemp(Ity_I1); 6278 6279 /* Get carry bit from DSPControl register. */ 6280 assign(t0, binop(Iop_Shr32, 6281 binop(Iop_And32, 6282 getDSPControl(), 6283 mkU32(0x2000)), 6284 mkU8(0xd))); 6285 assign(t1, binop(Iop_Add64, 6286 unop(Iop_32Sto64, getIReg(rs)), 6287 unop(Iop_32Sto64, 6288 binop(Iop_Add32, 6289 getIReg(rt), 6290 mkexpr(t0))))); 6291 6292 /* Extract bits 32 and 31. */ 6293 assign(t2, binop(Iop_And32, 6294 unop(Iop_64HIto32, mkexpr(t1)), 6295 mkU32(0x1))); 6296 assign(t3, binop(Iop_Shr32, 6297 binop(Iop_And32, 6298 unop(Iop_64to32, mkexpr(t1)), 6299 mkU32(0x80000000)), 6300 mkU8(31))); 6301 assign(t4, binop(Iop_CmpNE32, mkexpr(t2), mkexpr(t3))); 6302 6303 putDSPControl(IRExpr_ITE(mkexpr(t4), 6304 binop(Iop_Or32, 6305 getDSPControl(), 6306 mkU32(0x00100000)), 6307 getDSPControl())); 6308 putIReg(rd, unop(Iop_64to32, mkexpr(t1))); 6309 break; 6310 } 6311 case 0x12: { /* MODSUB */ 6312 DIP("modsub r%d, r%d, r%d", rd, rs, rt); 6313 vassert(!mode64); 6314 t0 = newTemp(Ity_I32); 6315 t1 = newTemp(Ity_I32); 6316 t2 = newTemp(Ity_I32); 6317 6318 /* decr_7..0 */ 6319 assign(t0, 6320 unop(Iop_8Uto32, 6321 unop(Iop_16to8, 6322 unop(Iop_32to16, getIReg(rt))))); 6323 6324 /* lastindex_15..0 */ 6325 assign(t1, 6326 unop(Iop_16Uto32, 6327 binop(Iop_8HLto16, 6328 unop(Iop_16to8, 6329 unop(Iop_32HIto16, getIReg(rt))), 6330 unop(Iop_16HIto8, 6331 unop(Iop_32to16, getIReg(rt)))))); 6332 /* temp_15..0 */ 6333 assign(t2, 6334 IRExpr_ITE(binop(Iop_CmpEQ32, 6335 getIReg(rs), 6336 mkU32(0x00000000)), 6337 mkexpr(t1), 6338 binop(Iop_Sub32, 6339 getIReg(rs), mkexpr(t0)))); 6340 putIReg(rd, mkexpr(t2)); 6341 break; 6342 } 6343 case 0x14: { /* RADDU.W.QB */ 6344 DIP("raddu.w.qb r%d, r%d", rd, rs); 6345 vassert(!mode64); 6346 putIReg(rd, binop(Iop_Add32, 6347 binop(Iop_Add32, 6348 unop(Iop_8Uto32, 6349 unop(Iop_16to8, 6350 unop(Iop_32to16, 6351 getIReg(rs)))), 6352 unop(Iop_8Uto32, 6353 unop(Iop_16HIto8, 6354 unop(Iop_32to16, 6355 getIReg(rs))))), 6356 binop(Iop_Add32, 6357 unop(Iop_8Uto32, 6358 unop(Iop_16to8, 6359 unop(Iop_32HIto16, 6360 getIReg(rs)))), 6361 unop(Iop_8Uto32, 6362 unop(Iop_16HIto8, 6363 unop(Iop_32HIto16, 6364 getIReg(rs))))))); 6365 break; 6366 } 6367 case 0x16: { /* ADDQ_S.W */ 6368 DIP("addq_s.w r%d, r%d, r%d", rd, rs, rt); 6369 vassert(!mode64); 6370 t0 = newTemp(Ity_I64); 6371 t1 = newTemp(Ity_I1); 6372 t2 = newTemp(Ity_I32); 6373 t3 = newTemp(Ity_I32); 6374 6375 assign(t0, binop(Iop_Add64, 6376 unop(Iop_32Sto64, getIReg(rs)), 6377 unop(Iop_32Sto64, getIReg(rt)))); 6378 6379 assign(t3, binop(Iop_And32, 6380 unop(Iop_64HIto32, mkexpr(t0)), 6381 mkU32(0x1))); 6382 assign(t1, binop(Iop_CmpNE32, 6383 binop(Iop_Shr32, 6384 binop(Iop_And32, 6385 unop(Iop_64to32, mkexpr(t0)), 6386 mkU32(0x80000000)), 6387 mkU8(31)), 6388 mkexpr(t3))); 6389 6390 putDSPControl(IRExpr_ITE(mkexpr(t1), 6391 binop(Iop_Or32, 6392 getDSPControl(), 6393 mkU32(0x00100000)), 6394 getDSPControl())); 6395 6396 putIReg(rd, IRExpr_ITE(mkexpr(t1), 6397 IRExpr_ITE(binop(Iop_CmpEQ32, 6398 mkexpr(t3), 6399 mkU32(0x0)), 6400 mkU32(0x7fffffff), 6401 mkU32(0x80000000)), 6402 unop(Iop_64to32, mkexpr(t0)))); 6403 break; 6404 } 6405 case 0x17: { /* SUBQ_S.W */ 6406 DIP("subq_s.w r%d, r%d, r%d", rd, rs, rt); 6407 vassert(!mode64); 6408 t0 = newTemp(Ity_I64); 6409 t1 = newTemp(Ity_I1); 6410 t2 = newTemp(Ity_I32); 6411 t3 = newTemp(Ity_I32); 6412 6413 assign(t0, binop(Iop_Sub64, 6414 unop(Iop_32Sto64, getIReg(rs)), 6415 unop(Iop_32Sto64, getIReg(rt)))); 6416 6417 assign(t3, binop(Iop_And32, 6418 unop(Iop_64HIto32, mkexpr(t0)), 6419 mkU32(0x1))); 6420 assign(t1, binop(Iop_CmpNE32, 6421 binop(Iop_Shr32, 6422 binop(Iop_And32, 6423 unop(Iop_64to32, mkexpr(t0)), 6424 mkU32(0x80000000)), 6425 mkU8(31)), 6426 mkexpr(t3))); 6427 6428 putDSPControl(IRExpr_ITE(mkexpr(t1), 6429 binop(Iop_Or32, 6430 getDSPControl(), 6431 mkU32(0x00100000)), 6432 getDSPControl())); 6433 6434 putIReg(rd, IRExpr_ITE(mkexpr(t1), 6435 IRExpr_ITE(binop(Iop_CmpEQ32, 6436 mkexpr(t3), 6437 mkU32(0x0)), 6438 mkU32(0x7fffffff), 6439 mkU32(0x80000000)), 6440 unop(Iop_64to32, mkexpr(t0)))); 6441 break; 6442 } 6443 case 0x1C: { /* MULEQ_S.W.PHL */ 6444 DIP("muleq_s.w.phl r%d, r%d, r%d", rd, rs, rt); 6445 vassert(!mode64); 6446 t0 = newTemp(Ity_I32); 6447 t1 = newTemp(Ity_I1); 6448 t2 = newTemp(Ity_I1); 6449 t3 = newTemp(Ity_I32); 6450 6451 assign(t0, 6452 binop(Iop_Shl32, 6453 binop(Iop_Mul32, 6454 unop(Iop_16Sto32, 6455 unop(Iop_32HIto16, getIReg(rt))), 6456 unop(Iop_16Sto32, 6457 unop(Iop_32HIto16, getIReg(rs)))), 6458 mkU8(0x1))); 6459 assign(t1, binop(Iop_CmpEQ32, 6460 binop(Iop_And32, 6461 getIReg(rt), 6462 mkU32(0xffff0000)), 6463 mkU32(0x80000000))); 6464 assign(t2, binop(Iop_CmpEQ32, 6465 binop(Iop_And32, 6466 getIReg(rs), 6467 mkU32(0xffff0000)), 6468 mkU32(0x80000000))); 6469 assign(t3, IRExpr_ITE(mkexpr(t1), 6470 IRExpr_ITE(mkexpr(t2), 6471 binop(Iop_Or32, 6472 getDSPControl(), 6473 mkU32(0x00200000)), 6474 getDSPControl()), 6475 getDSPControl())); 6476 putDSPControl(mkexpr(t3)); 6477 6478 putIReg(rd, IRExpr_ITE(mkexpr(t1), 6479 IRExpr_ITE(mkexpr(t2), 6480 mkU32(0x7fffffff), 6481 mkexpr(t0)), 6482 mkexpr(t0))); 6483 break; 6484 } 6485 case 0x1D: { /* MULEQ_S.W.PHR */ 6486 DIP("muleq_s.w.phr r%d, r%d, r%d", rd, rs, rt); 6487 vassert(!mode64); 6488 t0 = newTemp(Ity_I32); 6489 t1 = newTemp(Ity_I1); 6490 t2 = newTemp(Ity_I1); 6491 6492 assign(t0, 6493 binop(Iop_Shl32, 6494 binop(Iop_Mul32, 6495 unop(Iop_16Sto32, 6496 unop(Iop_32to16, getIReg(rt))), 6497 unop(Iop_16Sto32, 6498 unop(Iop_32to16, getIReg(rs)))), 6499 mkU8(0x1))); 6500 assign(t1, binop(Iop_CmpEQ32, 6501 binop(Iop_And32, 6502 getIReg(rt), 6503 mkU32(0xffff)), 6504 mkU32(0x8000))); 6505 assign(t2, binop(Iop_CmpEQ32, 6506 binop(Iop_And32, 6507 getIReg(rs), 6508 mkU32(0xffff)), 6509 mkU32(0x8000))); 6510 putDSPControl(IRExpr_ITE(mkexpr(t1), 6511 IRExpr_ITE(mkexpr(t2), 6512 binop(Iop_Or32, 6513 getDSPControl(), 6514 mkU32(0x00200000) 6515 ), 6516 getDSPControl()), 6517 getDSPControl())); 6518 putIReg(rd, IRExpr_ITE(mkexpr(t1), 6519 IRExpr_ITE(mkexpr(t2), 6520 mkU32(0x7fffffff), 6521 mkexpr(t0)), 6522 mkexpr(t0))); 6523 break; 6524 } 6525 case 0x1E: { /* MULQ_S.PH */ 6526 DIP("mulq_s.ph r%d, r%d, r%d", rd, rs, rt); 6527 vassert(!mode64); 6528 t0 = newTemp(Ity_I32); 6529 t1 = newTemp(Ity_I32); 6530 t2 = newTemp(Ity_I16); 6531 t3 = newTemp(Ity_I16); 6532 t5 = newTemp(Ity_I32); 6533 t6 = newTemp(Ity_I32); 6534 t7 = newTemp(Ity_I32); 6535 t8 = newTemp(Ity_I32); 6536 6537 assign(t5, 6538 unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rs)))); 6539 assign(t6, 6540 unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt)))); 6541 6542 assign(t7, 6543 unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rs)))); 6544 assign(t8, 6545 unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rt)))); 6546 6547 assign(t0, binop(Iop_And32, 6548 unop(Iop_1Sto32, 6549 binop(Iop_CmpEQ32, 6550 binop(Iop_And32, 6551 mkexpr(t5), 6552 mkU32(0xffff)), 6553 mkU32(0x8000))), 6554 unop(Iop_1Sto32, 6555 binop(Iop_CmpEQ32, 6556 binop(Iop_And32, 6557 mkexpr(t6), 6558 mkU32(0xffff)), 6559 mkU32(0x8000))))); 6560 assign(t1, binop(Iop_And32, 6561 unop(Iop_1Sto32, 6562 binop(Iop_CmpEQ32, 6563 binop(Iop_And32, 6564 mkexpr(t7), 6565 mkU32(0xffff)), 6566 mkU32(0x8000))), 6567 unop(Iop_1Sto32, 6568 binop(Iop_CmpEQ32, 6569 binop(Iop_And32, 6570 mkexpr(t8), 6571 mkU32(0xffff)), 6572 mkU32(0x8000))))); 6573 6574 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 6575 binop(Iop_Or32, 6576 mkexpr(t0), 6577 mkexpr(t1)), 6578 mkU32(0x0)), 6579 getDSPControl(), 6580 binop(Iop_Or32, 6581 getDSPControl(), 6582 mkU32(0x200000)))); 6583 6584 assign(t2, unop(Iop_32HIto16, 6585 binop(Iop_Shl32, 6586 unop(Iop_64to32, 6587 binop(Iop_MullS32, 6588 mkexpr(t7), 6589 mkexpr(t8))), 6590 mkU8(0x1)))); 6591 assign(t3, unop(Iop_32HIto16, 6592 binop(Iop_Shl32, 6593 unop(Iop_64to32, 6594 binop(Iop_MullS32, 6595 mkexpr(t5), 6596 mkexpr(t6))), 6597 mkU8(0x1)))); 6598 putIReg(rd, binop(Iop_16HLto32, 6599 IRExpr_ITE(binop(Iop_CmpEQ32, 6600 mkexpr(t1), 6601 mkU32(0x0)), 6602 mkexpr(t2), 6603 mkU16(0x7fff)), 6604 IRExpr_ITE(binop(Iop_CmpEQ32, 6605 mkexpr(t0), 6606 mkU32(0x0)), 6607 mkexpr(t3), 6608 mkU16(0x7fff)))); 6609 break; 6610 } 6611 case 0x1F: { /* MULQ_RS.PH */ 6612 DIP("mulq_rs.ph r%d, r%d, r%d", rd, rs, rt); 6613 vassert(!mode64); 6614 t0 = newTemp(Ity_I32); 6615 t1 = newTemp(Ity_I1); 6616 t2 = newTemp(Ity_I1); 6617 t3 = newTemp(Ity_I16); 6618 t4 = newTemp(Ity_I32); 6619 t5 = newTemp(Ity_I1); 6620 t6 = newTemp(Ity_I1); 6621 t7 = newTemp(Ity_I16); 6622 6623 /* Multiply and round lower halfwords. */ 6624 assign(t0, binop(Iop_Add32, 6625 binop(Iop_Shl32, 6626 binop(Iop_Mul32, 6627 unop(Iop_16Sto32, 6628 unop(Iop_32to16, 6629 getIReg(rt))), 6630 unop(Iop_16Sto32, 6631 unop(Iop_32to16, 6632 getIReg(rs)))), 6633 mkU8(0x1)), 6634 mkU32(0x00008000))); 6635 assign(t1, binop(Iop_CmpEQ32, 6636 binop(Iop_And32, 6637 getIReg(rt), mkU32(0xffff)), 6638 mkU32(0x8000))); 6639 assign(t2, binop(Iop_CmpEQ32, 6640 binop(Iop_And32, 6641 getIReg(rs), mkU32(0xffff)), 6642 mkU32(0x8000))); 6643 putDSPControl(IRExpr_ITE(mkexpr(t1), 6644 IRExpr_ITE(mkexpr(t2), 6645 binop(Iop_Or32, 6646 getDSPControl(), 6647 mkU32(0x00200000) 6648 ), 6649 getDSPControl()), 6650 getDSPControl())); 6651 assign(t3, IRExpr_ITE(mkexpr(t1), 6652 IRExpr_ITE(mkexpr(t2), 6653 mkU16(0x7fff), 6654 unop(Iop_32HIto16, 6655 mkexpr(t0))), 6656 unop(Iop_32HIto16, mkexpr(t0)))); 6657 6658 /* Multiply and round higher halfwords. */ 6659 assign(t4, binop(Iop_Add32, 6660 binop(Iop_Shl32, 6661 binop(Iop_Mul32, 6662 unop(Iop_16Sto32, 6663 unop(Iop_32HIto16, 6664 getIReg(rt))), 6665 unop(Iop_16Sto32, 6666 unop(Iop_32HIto16, 6667 getIReg(rs)))), 6668 mkU8(0x1)), 6669 mkU32(0x00008000))); 6670 assign(t5, binop(Iop_CmpEQ32, 6671 binop(Iop_And32, 6672 getIReg(rt), 6673 mkU32(0xffff0000)), 6674 mkU32(0x80000000))); 6675 assign(t6, binop(Iop_CmpEQ32, 6676 binop(Iop_And32, 6677 getIReg(rs), 6678 mkU32(0xffff0000)), 6679 mkU32(0x80000000))); 6680 putDSPControl(IRExpr_ITE(mkexpr(t5), 6681 IRExpr_ITE(mkexpr(t6), 6682 binop(Iop_Or32, 6683 getDSPControl(), 6684 mkU32(0x00200000)), 6685 getDSPControl()), 6686 getDSPControl())); 6687 assign(t7, IRExpr_ITE(mkexpr(t5), 6688 IRExpr_ITE(mkexpr(t6), 6689 mkU16(0x7fff), 6690 unop(Iop_32HIto16, 6691 mkexpr(t4))), 6692 unop(Iop_32HIto16, mkexpr(t4)))); 6693 6694 putIReg(rd, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3))); 6695 break; 6696 } 6697 default: 6698 return -1; 6699 } 6700 break; /* end of ADDU.QB */ 6701 } 6702 case 0x11: { /* CMPU.EQ.QB */ 6703 switch(sa) { 6704 case 0x0: { /* CMPU.EQ.QB */ 6705 DIP("cmpu.eq.qb r%d, r%d", rs, rt); 6706 vassert(!mode64); 6707 t1 = newTemp(Ity_I1); 6708 t2 = newTemp(Ity_I1); 6709 t3 = newTemp(Ity_I1); 6710 t4 = newTemp(Ity_I1); 6711 6712 assign(t1, 6713 binop(Iop_CmpEQ32, 6714 binop(Iop_And32, getIReg(rs), mkU32(0xff)), 6715 binop(Iop_And32, getIReg(rt), mkU32(0xff)))); 6716 putDSPControl(IRExpr_ITE(mkexpr(t1), 6717 binop(Iop_Or32, 6718 getDSPControl(), 6719 mkU32(0x01000000)), 6720 binop(Iop_And32, 6721 getDSPControl(), 6722 mkU32(0xfeffffff)))); 6723 6724 assign(t2, binop(Iop_CmpEQ32, 6725 unop(Iop_8Uto32, 6726 unop(Iop_16HIto8, 6727 unop(Iop_32to16, 6728 getIReg(rs)))), 6729 unop(Iop_8Uto32, 6730 unop(Iop_16HIto8, 6731 unop(Iop_32to16, 6732 getIReg(rt)))))); 6733 putDSPControl(IRExpr_ITE(mkexpr(t2), 6734 binop(Iop_Or32, 6735 getDSPControl(), 6736 mkU32(0x02000000)), 6737 binop(Iop_And32, 6738 getDSPControl(), 6739 mkU32(0xfdffffff)))); 6740 6741 assign(t3, binop(Iop_CmpEQ32, 6742 unop(Iop_8Uto32, 6743 unop(Iop_16to8, 6744 unop(Iop_32HIto16, 6745 getIReg(rs)))), 6746 unop(Iop_8Uto32, 6747 unop(Iop_16to8, 6748 unop(Iop_32HIto16, 6749 getIReg(rt)))))); 6750 putDSPControl(IRExpr_ITE(mkexpr(t3), 6751 binop(Iop_Or32, 6752 getDSPControl(), 6753 mkU32(0x04000000)), 6754 binop(Iop_And32, 6755 getDSPControl(), 6756 mkU32(0xfbffffff)))); 6757 6758 assign(t4, binop(Iop_CmpEQ32, 6759 unop(Iop_8Uto32, 6760 unop(Iop_16HIto8, 6761 unop(Iop_32HIto16, 6762 getIReg(rs)))), 6763 unop(Iop_8Uto32, 6764 unop(Iop_16HIto8, 6765 unop(Iop_32HIto16, 6766 getIReg(rt)))))); 6767 putDSPControl(IRExpr_ITE(mkexpr(t4), 6768 binop(Iop_Or32, 6769 getDSPControl(), 6770 mkU32(0x08000000)), 6771 binop(Iop_And32, 6772 getDSPControl(), 6773 mkU32(0xf7ffffff)))); 6774 break; 6775 } 6776 case 0x1: { /* CMPU.LT.QB */ 6777 DIP("cmpu.lt.qb r%d, r%d", rs, rt); 6778 vassert(!mode64); 6779 t1 = newTemp(Ity_I1); 6780 t2 = newTemp(Ity_I1); 6781 t3 = newTemp(Ity_I1); 6782 t4 = newTemp(Ity_I1); 6783 6784 assign(t1, binop(Iop_CmpLT32U, 6785 unop(Iop_8Uto32, 6786 unop(Iop_16to8, 6787 unop(Iop_32to16, 6788 getIReg(rs)))), 6789 unop(Iop_8Uto32, 6790 unop(Iop_16to8, 6791 unop(Iop_32to16, 6792 getIReg(rt)))))); 6793 putDSPControl(IRExpr_ITE(mkexpr(t1), 6794 binop(Iop_Or32, 6795 getDSPControl(), 6796 mkU32(0x01000000)), 6797 binop(Iop_And32, 6798 getDSPControl(), 6799 mkU32(0xfeffffff)))); 6800 6801 assign(t2, binop(Iop_CmpLT32U, 6802 unop(Iop_8Uto32, 6803 unop(Iop_16HIto8, 6804 unop(Iop_32to16, 6805 getIReg(rs)))), 6806 unop(Iop_8Uto32, 6807 unop(Iop_16HIto8, 6808 unop(Iop_32to16, 6809 getIReg(rt)))))); 6810 putDSPControl(IRExpr_ITE(mkexpr(t2), 6811 binop(Iop_Or32, 6812 getDSPControl(), 6813 mkU32(0x02000000)), 6814 binop(Iop_And32, 6815 getDSPControl(), 6816 mkU32(0xfdffffff)))); 6817 6818 assign(t3, binop(Iop_CmpLT32U, 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 putDSPControl(IRExpr_ITE(mkexpr(t3), 6828 binop(Iop_Or32, 6829 getDSPControl(), 6830 mkU32(0x04000000)), 6831 binop(Iop_And32, 6832 getDSPControl(), 6833 mkU32(0xfbffffff)))); 6834 6835 assign(t4, binop(Iop_CmpLT32U, 6836 unop(Iop_8Uto32, 6837 unop(Iop_16HIto8, 6838 unop(Iop_32HIto16, 6839 getIReg(rs)))), 6840 unop(Iop_8Uto32, 6841 unop(Iop_16HIto8, 6842 unop(Iop_32HIto16, 6843 getIReg(rt)))))); 6844 putDSPControl(IRExpr_ITE(mkexpr(t4), 6845 binop(Iop_Or32, 6846 getDSPControl(), 6847 mkU32(0x08000000)), 6848 binop(Iop_And32, 6849 getDSPControl(), 6850 mkU32(0xf7ffffff)))); 6851 break; 6852 } 6853 case 0x2: { /* CMPU.LE.QB */ 6854 DIP("cmpu.le.qb r%d, r%d", rs, rt); 6855 vassert(!mode64); 6856 t1 = newTemp(Ity_I1); 6857 t2 = newTemp(Ity_I1); 6858 t3 = newTemp(Ity_I1); 6859 t4 = newTemp(Ity_I1); 6860 6861 assign(t1, binop(Iop_CmpLE32U, 6862 unop(Iop_8Uto32, 6863 unop(Iop_16to8, 6864 unop(Iop_32to16, 6865 getIReg(rs)))), 6866 unop(Iop_8Uto32, 6867 unop(Iop_16to8, 6868 unop(Iop_32to16, 6869 getIReg(rt)))))); 6870 putDSPControl(IRExpr_ITE(mkexpr(t1), 6871 binop(Iop_Or32, 6872 getDSPControl(), 6873 mkU32(0x01000000)), 6874 binop(Iop_And32, 6875 getDSPControl(), 6876 mkU32(0xfeffffff)))); 6877 6878 assign(t2, binop(Iop_CmpLE32U, 6879 unop(Iop_8Uto32, 6880 unop(Iop_16HIto8, 6881 unop(Iop_32to16, 6882 getIReg(rs)))), 6883 unop(Iop_8Uto32, 6884 unop(Iop_16HIto8, 6885 unop(Iop_32to16, 6886 getIReg(rt)))))); 6887 putDSPControl(IRExpr_ITE(mkexpr(t2), 6888 binop(Iop_Or32, 6889 getDSPControl(), 6890 mkU32(0x02000000)), 6891 binop(Iop_And32, 6892 getDSPControl(), 6893 mkU32(0xfdffffff)))); 6894 6895 assign(t3, binop(Iop_CmpLE32U, 6896 unop(Iop_8Uto32, 6897 unop(Iop_16to8, 6898 unop(Iop_32HIto16, 6899 getIReg(rs)))), 6900 unop(Iop_8Uto32, 6901 unop(Iop_16to8, 6902 unop(Iop_32HIto16, 6903 getIReg(rt)))))); 6904 putDSPControl(IRExpr_ITE(mkexpr(t3), 6905 binop(Iop_Or32, 6906 getDSPControl(), 6907 mkU32(0x04000000)), 6908 binop(Iop_And32, 6909 getDSPControl(), 6910 mkU32(0xfbffffff)))); 6911 6912 assign(t4, binop(Iop_CmpLE32U, 6913 unop(Iop_8Uto32, 6914 unop(Iop_16HIto8, 6915 unop(Iop_32HIto16, 6916 getIReg(rs)))), 6917 unop(Iop_8Uto32, 6918 unop(Iop_16HIto8, 6919 unop(Iop_32HIto16, 6920 getIReg(rt)))))); 6921 putDSPControl(IRExpr_ITE(mkexpr(t4), 6922 binop(Iop_Or32, 6923 getDSPControl(), 6924 mkU32(0x08000000)), 6925 binop(Iop_And32, 6926 getDSPControl(), 6927 mkU32(0xf7ffffff)))); 6928 break; 6929 } 6930 case 0x3: { /* PICK.QB */ 6931 DIP("pick.qb r%d, r%d, r%d", rd, rs, rt); 6932 vassert(!mode64); 6933 t0 = newTemp(Ity_I32); 6934 t1 = newTemp(Ity_I8); 6935 t2 = newTemp(Ity_I8); 6936 t3 = newTemp(Ity_I8); 6937 t4 = newTemp(Ity_I8); 6938 6939 assign(t0, getDSPControl()); 6940 assign(t1, IRExpr_ITE(binop(Iop_CmpNE32, 6941 binop(Iop_And32, 6942 mkexpr(t0), 6943 mkU32(0x01000000)), 6944 mkU32(0x0)), 6945 unop(Iop_16to8, 6946 unop(Iop_32to16, 6947 getIReg(rs))), 6948 unop(Iop_16to8, 6949 unop(Iop_32to16, 6950 getIReg(rt))))); 6951 assign(t2, IRExpr_ITE(binop(Iop_CmpNE32, 6952 binop(Iop_And32, 6953 mkexpr(t0), 6954 mkU32(0x02000000)), 6955 mkU32(0x0)), 6956 unop(Iop_16HIto8, 6957 unop(Iop_32to16, getIReg(rs))), 6958 unop(Iop_16HIto8, 6959 unop(Iop_32to16, 6960 getIReg(rt))))); 6961 assign(t3, IRExpr_ITE(binop(Iop_CmpNE32, 6962 binop(Iop_And32, 6963 mkexpr(t0), 6964 mkU32(0x04000000)), 6965 mkU32(0x0)), 6966 unop(Iop_16to8, 6967 unop(Iop_32HIto16, 6968 getIReg(rs))), 6969 unop(Iop_16to8, 6970 unop(Iop_32HIto16, 6971 getIReg(rt))))); 6972 assign(t4, IRExpr_ITE(binop(Iop_CmpNE32, 6973 binop(Iop_And32, 6974 mkexpr(t0), 6975 mkU32(0x08000000)), 6976 mkU32(0x0)), 6977 unop(Iop_16HIto8, 6978 unop(Iop_32HIto16, 6979 getIReg(rs))), 6980 unop(Iop_16HIto8, 6981 unop(Iop_32HIto16, 6982 getIReg(rt))))); 6983 putIReg(rd, 6984 binop(Iop_16HLto32, 6985 binop(Iop_8HLto16, mkexpr(t4), mkexpr(t3)), 6986 binop(Iop_8HLto16, mkexpr(t2), mkexpr(t1)))); 6987 break; 6988 } 6989 case 0x4: { /* CMPGU.EQ.QB */ 6990 DIP("cmpgu.eq.qb r%d, r%d, r%d", rd, rs, rt); 6991 vassert(!mode64); 6992 t1 = newTemp(Ity_I1); 6993 t2 = newTemp(Ity_I1); 6994 t3 = newTemp(Ity_I1); 6995 t4 = newTemp(Ity_I1); 6996 t5 = newTemp(Ity_I32); 6997 t6 = newTemp(Ity_I32); 6998 t7 = newTemp(Ity_I32); 6999 t8 = newTemp(Ity_I32); 7000 7001 assign(t1, binop(Iop_CmpEQ32, 7002 unop(Iop_8Uto32, 7003 unop(Iop_16to8, 7004 unop(Iop_32to16, getIReg(rs)))), 7005 unop(Iop_8Uto32, 7006 unop(Iop_16to8, 7007 unop(Iop_32to16, 7008 getIReg(rt)))))); 7009 assign(t5, IRExpr_ITE(mkexpr(t1), 7010 mkU32(0x00000001), mkU32(0))); 7011 7012 assign(t2, binop(Iop_CmpEQ32, 7013 unop(Iop_8Uto32, 7014 unop(Iop_16HIto8, 7015 unop(Iop_32to16, getIReg(rs)))), 7016 unop(Iop_8Uto32, 7017 unop(Iop_16HIto8, 7018 unop(Iop_32to16, 7019 getIReg(rt)))))); 7020 assign(t6, IRExpr_ITE(mkexpr(t2), 7021 mkU32(0x00000002), mkU32(0))); 7022 7023 assign(t3, binop(Iop_CmpEQ32, 7024 unop(Iop_8Uto32, 7025 unop(Iop_16to8, 7026 unop(Iop_32HIto16, 7027 getIReg(rs)))), 7028 unop(Iop_8Uto32, 7029 unop(Iop_16to8, 7030 unop(Iop_32HIto16, 7031 getIReg(rt)))))); 7032 assign(t7, IRExpr_ITE(mkexpr(t3), 7033 mkU32(0x00000004), mkU32(0))); 7034 7035 assign(t4, binop(Iop_CmpEQ32, 7036 unop(Iop_8Uto32, 7037 unop(Iop_16HIto8, 7038 unop(Iop_32HIto16, 7039 getIReg(rs)))), 7040 unop(Iop_8Uto32, 7041 unop(Iop_16HIto8, 7042 unop(Iop_32HIto16, 7043 getIReg(rt)))))); 7044 assign(t8, IRExpr_ITE(mkexpr(t4), 7045 mkU32(0x00000008), mkU32(0))); 7046 7047 putIReg(rd, binop(Iop_Or32, 7048 binop(Iop_Or32, 7049 binop(Iop_Or32, 7050 mkexpr(t5), mkexpr(t6)), 7051 mkexpr(t7)), 7052 mkexpr(t8))); 7053 break; 7054 } 7055 case 0x5: { /* CMPGU.LT.QB */ 7056 DIP("cmpgu.lt.qb r%d, r%d, r%d", rd, rs, rt); 7057 vassert(!mode64); 7058 t1 = newTemp(Ity_I1); 7059 t2 = newTemp(Ity_I1); 7060 t3 = newTemp(Ity_I1); 7061 t4 = newTemp(Ity_I1); 7062 t5 = newTemp(Ity_I32); 7063 t6 = newTemp(Ity_I32); 7064 t7 = newTemp(Ity_I32); 7065 t8 = newTemp(Ity_I32); 7066 7067 assign(t1, binop(Iop_CmpLT32U, 7068 unop(Iop_8Uto32, 7069 unop(Iop_16to8, 7070 unop(Iop_32to16, getIReg(rs)))), 7071 unop(Iop_8Uto32, 7072 unop(Iop_16to8, 7073 unop(Iop_32to16, 7074 getIReg(rt)))))); 7075 assign(t5, IRExpr_ITE(mkexpr(t1), 7076 mkU32(0x00000001), mkU32(0))); 7077 7078 assign(t2, binop(Iop_CmpLT32U, 7079 unop(Iop_8Uto32, 7080 unop(Iop_16HIto8, 7081 unop(Iop_32to16, getIReg(rs)))), 7082 unop(Iop_8Uto32, 7083 unop(Iop_16HIto8, 7084 unop(Iop_32to16, 7085 getIReg(rt)))))); 7086 assign(t6, IRExpr_ITE(mkexpr(t2), 7087 mkU32(0x00000002), mkU32(0))); 7088 7089 assign(t3, binop(Iop_CmpLT32U, 7090 unop(Iop_8Uto32, 7091 unop(Iop_16to8, 7092 unop(Iop_32HIto16, 7093 getIReg(rs)))), 7094 unop(Iop_8Uto32, 7095 unop(Iop_16to8, 7096 unop(Iop_32HIto16, 7097 getIReg(rt)))))); 7098 assign(t7, IRExpr_ITE(mkexpr(t3), 7099 mkU32(0x00000004), mkU32(0))); 7100 7101 assign(t4, binop(Iop_CmpLT32U, 7102 unop(Iop_8Uto32, 7103 unop(Iop_16HIto8, 7104 unop(Iop_32HIto16, 7105 getIReg(rs)))), 7106 unop(Iop_8Uto32, 7107 unop(Iop_16HIto8, 7108 unop(Iop_32HIto16, 7109 getIReg(rt)))))); 7110 assign(t8, IRExpr_ITE(mkexpr(t4), 7111 mkU32(0x00000008), mkU32(0))); 7112 putIReg(rd, binop(Iop_Or32, 7113 binop(Iop_Or32, 7114 binop(Iop_Or32, 7115 mkexpr(t5), mkexpr(t6)), 7116 mkexpr(t7)), 7117 mkexpr(t8))); 7118 break; 7119 } 7120 case 0x6: { /* CMPGU.LE.QB */ 7121 DIP("cmpgu.le.qb r%d, r%d, r%d", rd, rs, rt); 7122 vassert(!mode64); 7123 t1 = newTemp(Ity_I1); 7124 t2 = newTemp(Ity_I1); 7125 t3 = newTemp(Ity_I1); 7126 t4 = newTemp(Ity_I1); 7127 t5 = newTemp(Ity_I32); 7128 t6 = newTemp(Ity_I32); 7129 t7 = newTemp(Ity_I32); 7130 t8 = newTemp(Ity_I32); 7131 7132 assign(t1, binop(Iop_CmpLE32U, 7133 unop(Iop_8Uto32, 7134 unop(Iop_16to8, 7135 unop(Iop_32to16, getIReg(rs)))), 7136 unop(Iop_8Uto32, 7137 unop(Iop_16to8, 7138 unop(Iop_32to16, 7139 getIReg(rt)))))); 7140 assign(t5, IRExpr_ITE(mkexpr(t1), 7141 mkU32(0x00000001), mkU32(0))); 7142 7143 assign(t2, binop(Iop_CmpLE32U, 7144 unop(Iop_8Uto32, 7145 unop(Iop_16HIto8, 7146 unop(Iop_32to16, getIReg(rs)))), 7147 unop(Iop_8Uto32, 7148 unop(Iop_16HIto8, 7149 unop(Iop_32to16, 7150 getIReg(rt)))))); 7151 assign(t6, IRExpr_ITE(mkexpr(t2), 7152 mkU32(0x00000002), mkU32(0))); 7153 7154 assign(t3, binop(Iop_CmpLE32U, 7155 unop(Iop_8Uto32, 7156 unop(Iop_16to8, 7157 unop(Iop_32HIto16, 7158 getIReg(rs)))), 7159 unop(Iop_8Uto32, 7160 unop(Iop_16to8, 7161 unop(Iop_32HIto16, 7162 getIReg(rt)))))); 7163 assign(t7, IRExpr_ITE(mkexpr(t3), 7164 mkU32(0x00000004), mkU32(0))); 7165 7166 assign(t4, binop(Iop_CmpLE32U, 7167 unop(Iop_8Uto32, 7168 unop(Iop_16HIto8, 7169 unop(Iop_32HIto16, 7170 getIReg(rs)))), 7171 unop(Iop_8Uto32, 7172 unop(Iop_16HIto8, 7173 unop(Iop_32HIto16, 7174 getIReg(rt)))))); 7175 assign(t8, IRExpr_ITE(mkexpr(t4), 7176 mkU32(0x00000008), mkU32(0))); 7177 putIReg(rd, binop(Iop_Or32, 7178 binop(Iop_Or32, 7179 binop(Iop_Or32, 7180 mkexpr(t5), mkexpr(t6)), 7181 mkexpr(t7)), 7182 mkexpr(t8))); 7183 break; 7184 } 7185 case 0x8: { /* CMP.EQ.PH */ 7186 DIP("cmp.eq.ph r%d, r%d", rs, rt); 7187 vassert(!mode64); 7188 t1 = newTemp(Ity_I1); 7189 t2 = newTemp(Ity_I1); 7190 7191 assign(t1, binop(Iop_CmpEQ16, 7192 unop(Iop_32to16, getIReg(rs)), 7193 unop(Iop_32to16, getIReg(rt)))); 7194 putDSPControl(IRExpr_ITE(mkexpr(t1), 7195 binop(Iop_Or32, 7196 getDSPControl(), 7197 mkU32(0x01000000)), 7198 binop(Iop_And32, 7199 getDSPControl(), 7200 mkU32(0xfeffffff)))); 7201 assign(t2, binop(Iop_CmpEQ16, 7202 unop(Iop_32HIto16, getIReg(rs)), 7203 unop(Iop_32HIto16, getIReg(rt)))); 7204 putDSPControl(IRExpr_ITE(mkexpr(t2), 7205 binop(Iop_Or32, 7206 getDSPControl(), 7207 mkU32(0x02000000)), 7208 binop(Iop_And32, 7209 getDSPControl(), 7210 mkU32(0xfdffffff)))); 7211 break; 7212 } 7213 case 0x9: { /* CMP.LT.PH */ 7214 DIP("cmp.lt.ph r%d, r%d", rs, rt); 7215 vassert(!mode64); 7216 t1 = newTemp(Ity_I1); 7217 t2 = newTemp(Ity_I1); 7218 7219 assign(t1, binop(Iop_CmpLT32S, 7220 unop(Iop_16Sto32, 7221 unop(Iop_32to16, getIReg(rs))), 7222 unop(Iop_16Sto32, 7223 unop(Iop_32to16, getIReg(rt))))); 7224 putDSPControl(IRExpr_ITE(mkexpr(t1), 7225 binop(Iop_Or32, 7226 getDSPControl(), 7227 mkU32(0x01000000)), 7228 binop(Iop_And32, 7229 getDSPControl(), 7230 mkU32(0xfeffffff)))); 7231 7232 assign(t2, binop(Iop_CmpLT32S, 7233 unop(Iop_16Sto32, 7234 unop(Iop_32HIto16, getIReg(rs))), 7235 unop(Iop_16Sto32, 7236 unop(Iop_32HIto16, getIReg(rt))))); 7237 putDSPControl(IRExpr_ITE(mkexpr(t2), 7238 binop(Iop_Or32, 7239 getDSPControl(), 7240 mkU32(0x02000000)), 7241 binop(Iop_And32, 7242 getDSPControl(), 7243 mkU32(0xfdffffff)))); 7244 break; 7245 } 7246 case 0xA: { /* CMP.LE.PH */ 7247 DIP("cmp.le.ph r%d, r%d", rs, rt); 7248 vassert(!mode64); 7249 t1 = newTemp(Ity_I1); 7250 t2 = newTemp(Ity_I1); 7251 7252 assign(t1, binop(Iop_CmpLE32S, 7253 unop(Iop_16Sto32, 7254 unop(Iop_32to16, getIReg(rs))), 7255 unop(Iop_16Sto32, 7256 unop(Iop_32to16, getIReg(rt))))); 7257 putDSPControl(IRExpr_ITE(mkexpr(t1), 7258 binop(Iop_Or32, 7259 getDSPControl(), 7260 mkU32(0x01000000)), 7261 binop(Iop_And32, 7262 getDSPControl(), 7263 mkU32(0xfeffffff)))); 7264 7265 assign(t2, binop(Iop_CmpLE32S, 7266 unop(Iop_16Sto32, 7267 unop(Iop_32HIto16, getIReg(rs))), 7268 unop(Iop_16Sto32, 7269 unop(Iop_32HIto16, getIReg(rt))))); 7270 putDSPControl(IRExpr_ITE(mkexpr(t2), 7271 binop(Iop_Or32, 7272 getDSPControl(), 7273 mkU32(0x02000000)), 7274 binop(Iop_And32, 7275 getDSPControl(), 7276 mkU32(0xfdffffff)))); 7277 break; 7278 } 7279 case 0xB: { /* PICK.PH */ 7280 DIP("pick.qb r%d, r%d, r%d", rd, rs, rt); 7281 vassert(!mode64); 7282 t0 = newTemp(Ity_I32); 7283 t1 = newTemp(Ity_I16); 7284 t2 = newTemp(Ity_I16); 7285 7286 assign(t0, getDSPControl()); 7287 7288 assign(t1, IRExpr_ITE(binop(Iop_CmpNE32, 7289 binop(Iop_And32, 7290 mkexpr(t0), 7291 mkU32(0x01000000)), 7292 mkU32(0x0)), 7293 unop(Iop_32to16, getIReg(rs)), 7294 unop(Iop_32to16, getIReg(rt)))); 7295 7296 assign(t2, IRExpr_ITE(binop(Iop_CmpNE32, 7297 binop(Iop_And32, 7298 mkexpr(t0), 7299 mkU32(0x02000000)), 7300 mkU32(0x0)), 7301 unop(Iop_32HIto16, getIReg(rs)), 7302 unop(Iop_32HIto16, getIReg(rt)))); 7303 7304 putIReg(rd, binop(Iop_16HLto32, mkexpr(t2), mkexpr(t1))); 7305 break; 7306 } 7307 case 0xC: { /* PRECRQ.QB.PH */ 7308 DIP("precrq.qb.ph r%d, r%d, %d", rd, rs, rt); 7309 vassert(!mode64); 7310 putIReg(rd, 7311 binop(Iop_16HLto32, 7312 binop(Iop_8HLto16, 7313 unop(Iop_16HIto8, 7314 unop(Iop_32HIto16, getIReg(rs))), 7315 unop(Iop_16HIto8, 7316 unop(Iop_32to16, getIReg(rs)))), 7317 binop(Iop_8HLto16, 7318 unop(Iop_16HIto8, 7319 unop(Iop_32HIto16, getIReg(rt))), 7320 unop(Iop_16HIto8, 7321 unop(Iop_32to16, getIReg(rt)))))); 7322 break; 7323 } 7324 case 0xD: { /* PRECR.QB.PH */ 7325 DIP("precr.qb.ph r%d, r%d, r%d", rd, rs, rt); 7326 vassert(!mode64); 7327 7328 putIReg(rd, 7329 binop(Iop_16HLto32, 7330 binop(Iop_8HLto16, 7331 unop(Iop_16to8, 7332 unop(Iop_32HIto16, getIReg(rs))), 7333 unop(Iop_16to8, 7334 unop(Iop_32to16, getIReg(rs)))), 7335 binop(Iop_8HLto16, 7336 unop(Iop_16to8, 7337 unop(Iop_32HIto16, getIReg(rt))), 7338 unop(Iop_16to8, 7339 unop(Iop_32to16, getIReg(rt)))))); 7340 break; 7341 } 7342 case 0xF: { /* PRECRQU_S.QB.PH */ 7343 DIP("precrqu_s.qb.ph r%d, r%d, %d", rd, rs, rt); 7344 vassert(!mode64); 7345 t0 = newTemp(Ity_I8); 7346 t1 = newTemp(Ity_I8); 7347 t2 = newTemp(Ity_I8); 7348 t3 = newTemp(Ity_I8); 7349 t4 = newTemp(Ity_I8); 7350 t5 = newTemp(Ity_I32); 7351 t6 = newTemp(Ity_I1); 7352 t7 = newTemp(Ity_I8); 7353 t8 = newTemp(Ity_I1); 7354 t9 = newTemp(Ity_I32); 7355 t10 = newTemp(Ity_I8); 7356 t11 = newTemp(Ity_I1); 7357 t12 = newTemp(Ity_I32); 7358 t13 = newTemp(Ity_I8); 7359 t14 = newTemp(Ity_I1); 7360 t15 = newTemp(Ity_I32); 7361 7362 assign(t4, IRExpr_ITE(binop(Iop_CmpLT32U, 7363 mkU32(0x7f80), 7364 binop(Iop_And32, 7365 unop(Iop_16Uto32, 7366 unop(Iop_32to16, 7367 getIReg(rs))), 7368 mkU32(0x7fff))), 7369 mkU8(0xff), 7370 unop(Iop_16HIto8, 7371 unop(Iop_32to16, 7372 binop(Iop_Shl32, 7373 getIReg(rs), 7374 mkU8(1)))))); 7375 assign(t0, IRExpr_ITE(binop(Iop_CmpEQ32, 7376 binop(Iop_And32, 7377 unop(Iop_16Uto32, 7378 unop(Iop_32to16, 7379 getIReg(rs))), 7380 mkU32(0x00008000)), 7381 mkU32(0x0)), 7382 mkexpr(t4), 7383 mkU8(0x0))); 7384 assign(t5, binop(Iop_And32, 7385 unop(Iop_16Uto32, 7386 unop(Iop_32to16, 7387 getIReg(rs))), 7388 mkU32(0x00008000))); 7389 assign(t6, binop(Iop_CmpLT32U, 7390 mkU32(0x7f80), 7391 binop(Iop_And32, 7392 unop(Iop_16Uto32, 7393 unop(Iop_32to16, 7394 getIReg(rs))), 7395 mkU32(0x7fff)))); 7396 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 7397 mkexpr(t5), 7398 mkU32(0x0)), 7399 IRExpr_ITE(mkexpr(t6), 7400 binop(Iop_Or32, 7401 getDSPControl(), 7402 mkU32(0x00400000) 7403 ), 7404 getDSPControl()), 7405 binop(Iop_Or32, 7406 getDSPControl(), 7407 mkU32(0x00400000)))); 7408 7409 assign(t7, IRExpr_ITE(binop(Iop_CmpLT32U, 7410 mkU32(0x7f80), 7411 binop(Iop_And32, 7412 unop(Iop_16Uto32, 7413 unop(Iop_32HIto16, 7414 getIReg(rs))), 7415 mkU32(0x7fff))), 7416 mkU8(0xff), 7417 unop(Iop_16HIto8, 7418 unop(Iop_32HIto16, 7419 binop(Iop_Shl32, 7420 getIReg(rs), 7421 mkU8(1)))))); 7422 assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32, 7423 binop(Iop_And32, 7424 unop(Iop_16Uto32, 7425 unop(Iop_32HIto16, 7426 getIReg(rs))), 7427 mkU32(0x00008000)), 7428 mkU32(0x0)), 7429 mkexpr(t7), 7430 mkU8(0x0))); 7431 assign(t8, binop(Iop_CmpEQ32, 7432 binop(Iop_And32, 7433 unop(Iop_16Uto32, 7434 unop(Iop_32HIto16, 7435 getIReg(rs))), 7436 mkU32(0x00008000)), 7437 mkU32(0x0))); 7438 assign(t9, IRExpr_ITE(binop(Iop_CmpLT32U, 7439 mkU32(0x7f80), 7440 binop(Iop_And32, 7441 unop(Iop_16Uto32, 7442 unop(Iop_32HIto16, 7443 getIReg(rs))), 7444 mkU32(0x7fff))), 7445 binop(Iop_Or32, 7446 getDSPControl(), 7447 mkU32(0x00400000)), 7448 getDSPControl())); 7449 putDSPControl(IRExpr_ITE(mkexpr(t8), 7450 mkexpr(t9), 7451 binop(Iop_Or32, 7452 getDSPControl(), 7453 mkU32(0x00400000)))); 7454 7455 assign(t10, IRExpr_ITE(binop(Iop_CmpLT32U, 7456 mkU32(0x7f80), 7457 binop(Iop_And32, 7458 unop(Iop_16Uto32, 7459 unop(Iop_32to16, 7460 getIReg(rt))), 7461 mkU32(0x7fff))), 7462 mkU8(0xff), 7463 unop(Iop_16HIto8, 7464 unop(Iop_32to16, 7465 binop(Iop_Shl32, 7466 getIReg(rt), 7467 mkU8(1)))))); 7468 assign(t2, IRExpr_ITE(binop(Iop_CmpEQ32, 7469 binop(Iop_And32, 7470 unop(Iop_16Uto32, 7471 unop(Iop_32to16, 7472 getIReg(rt))), 7473 mkU32(0x00008000)), 7474 mkU32(0x0)), 7475 mkexpr(t10), 7476 mkU8(0x0))); 7477 assign(t11, binop(Iop_CmpEQ32, 7478 binop(Iop_And32, 7479 unop(Iop_16Uto32, 7480 unop(Iop_32to16, 7481 getIReg(rt))), 7482 mkU32(0x00008000)), 7483 mkU32(0x0))); 7484 assign(t12, IRExpr_ITE(binop(Iop_CmpLT32U, 7485 mkU32(0x7f80), 7486 binop(Iop_And32, 7487 unop(Iop_16Uto32, 7488 unop(Iop_32to16, 7489 getIReg(rt))), 7490 mkU32(0x7fff))), 7491 binop(Iop_Or32, 7492 getDSPControl(), 7493 mkU32(0x00400000)), 7494 getDSPControl())); 7495 putDSPControl(IRExpr_ITE(mkexpr(t11), 7496 mkexpr(t12), 7497 binop(Iop_Or32, 7498 getDSPControl(), 7499 mkU32(0x00400000)))); 7500 7501 assign(t13, IRExpr_ITE(binop(Iop_CmpLT32U, 7502 mkU32(0x7f80), 7503 binop(Iop_And32, 7504 unop(Iop_16Uto32, 7505 unop(Iop_32HIto16, 7506 getIReg(rt))), 7507 mkU32(0x7fff))), 7508 mkU8(0xff), 7509 unop(Iop_16HIto8, 7510 unop(Iop_32HIto16, 7511 binop(Iop_Shl32, 7512 getIReg(rt), 7513 mkU8(1)))))); 7514 assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32, 7515 binop(Iop_And32, 7516 unop(Iop_16Uto32, 7517 unop(Iop_32HIto16, 7518 getIReg(rt))), 7519 mkU32(0x00008000)), 7520 mkU32(0x0)), 7521 mkexpr(t13), 7522 mkU8(0x0))); 7523 assign(t14, binop(Iop_CmpEQ32, 7524 binop(Iop_And32, 7525 unop(Iop_16Uto32, 7526 unop(Iop_32HIto16, 7527 getIReg(rt))), 7528 mkU32(0x00008000)), 7529 mkU32(0x0))); 7530 assign(t15, IRExpr_ITE(binop(Iop_CmpLT32U, 7531 mkU32(0x7f80), 7532 binop(Iop_And32, 7533 unop(Iop_16Uto32, 7534 unop(Iop_32HIto16, 7535 getIReg(rt))), 7536 mkU32(0x7fff))), 7537 binop(Iop_Or32, 7538 getDSPControl(), 7539 mkU32(0x00400000)), 7540 getDSPControl())); 7541 putDSPControl(IRExpr_ITE(mkexpr(t14), 7542 mkexpr(t15), 7543 binop(Iop_Or32, 7544 getDSPControl(), 7545 mkU32(0x00400000)))); 7546 7547 putIReg(rd, binop(Iop_16HLto32, 7548 binop(Iop_8HLto16, 7549 mkexpr(t1), mkexpr(t0)), 7550 binop(Iop_8HLto16, 7551 mkexpr(t3), mkexpr(t2)))); 7552 break; 7553 } 7554 case 0x14: { /* PRECRQ.PH.W */ 7555 DIP("precrq.ph.w r%d, r%d, %d", rd, rs, rt); 7556 vassert(!mode64); 7557 putIReg(rd, binop(Iop_16HLto32, 7558 unop(Iop_32HIto16, getIReg(rs)), 7559 unop(Iop_32HIto16, getIReg(rt)))); 7560 break; 7561 } 7562 case 0x15: { /* PRECRQ_RS.PH.W */ 7563 DIP("precrq_rs.ph.w r%d, r%d, %d", rd, rs, rt); 7564 vassert(!mode64); 7565 t0 = newTemp(Ity_I64); 7566 t1 = newTemp(Ity_I1); 7567 t2 = newTemp(Ity_I32); 7568 t3 = newTemp(Ity_I64); 7569 t4 = newTemp(Ity_I1); 7570 t5 = newTemp(Ity_I32); 7571 7572 assign(t0, binop(Iop_Add64, 7573 binop(Iop_32HLto64, 7574 binop(Iop_Shr32, 7575 binop(Iop_And32, 7576 getIReg(rs), 7577 mkU32(0x80000000)), 7578 mkU8(31)), 7579 getIReg(rs)), 7580 mkU64(0x0000000000008000ULL))); 7581 assign(t1, binop(Iop_CmpNE32, 7582 binop(Iop_And32, 7583 unop(Iop_64HIto32, mkexpr(t0)), 7584 mkU32(0x1)), 7585 binop(Iop_And32, 7586 binop(Iop_Shr32, 7587 unop(Iop_64to32, mkexpr(t0)), 7588 mkU8(31)), 7589 mkU32(0x1)))); 7590 assign(t2, IRExpr_ITE(mkexpr(t1), 7591 mkU32(0x7fffffff), 7592 unop(Iop_64to32, mkexpr(t0)))); 7593 putDSPControl(IRExpr_ITE(mkexpr(t1), 7594 binop(Iop_Or32, 7595 getDSPControl(), 7596 mkU32(0x400000)), 7597 getDSPControl())); 7598 assign(t3, binop(Iop_Add64, 7599 binop(Iop_32HLto64, 7600 binop(Iop_Shr32, 7601 binop(Iop_And32, 7602 getIReg(rt), 7603 mkU32(0x80000000)), 7604 mkU8(31)), 7605 getIReg(rt)), 7606 mkU64(0x0000000000008000ULL))); 7607 assign(t4, binop(Iop_CmpNE32, 7608 binop(Iop_And32, 7609 unop(Iop_64HIto32, mkexpr(t3)), 7610 mkU32(0x1)), 7611 binop(Iop_And32, 7612 binop(Iop_Shr32, 7613 unop(Iop_64to32, mkexpr(t3)), 7614 mkU8(31)), 7615 mkU32(0x1)))); 7616 assign(t5, IRExpr_ITE(mkexpr(t4), 7617 mkU32(0x7fffffff), 7618 unop(Iop_64to32, mkexpr(t3)))); 7619 putDSPControl(IRExpr_ITE(mkexpr(t4), 7620 binop(Iop_Or32, 7621 getDSPControl(), 7622 mkU32(0x400000)), 7623 getDSPControl())); 7624 putIReg(rd, binop(Iop_16HLto32, 7625 unop(Iop_32HIto16, mkexpr(t2)), 7626 unop(Iop_32HIto16, mkexpr(t5)))); 7627 break; 7628 } 7629 case 0x1E: { /* PRECR_SRA.PH.W */ 7630 DIP("precr_sra.ph.w r%d, r%d, %d", rt, rs, rd); 7631 vassert(!mode64); 7632 7633 if (0 == rd) { 7634 putIReg(rt, binop(Iop_16HLto32, 7635 unop(Iop_32to16, getIReg(rt)), 7636 unop(Iop_32to16, getIReg(rs)))); 7637 } else { 7638 putIReg(rt, binop(Iop_16HLto32, 7639 unop(Iop_32to16, binop(Iop_Sar32, 7640 getIReg(rt), 7641 mkU8(rd))), 7642 unop(Iop_32to16, binop(Iop_Sar32, 7643 getIReg(rs), 7644 mkU8(rd))))); 7645 } 7646 break; 7647 } 7648 case 0x1F: { /* PRECR_SRA_R.PH.W */ 7649 DIP("precr_sra_r.ph.w r%d, r%d, %d", rt, rs, rd); 7650 vassert(!mode64); 7651 7652 t0 = newTemp(Ity_I32); 7653 t1 = newTemp(Ity_I32); 7654 7655 if (0 == rd) { 7656 putIReg(rt, binop(Iop_16HLto32, 7657 unop(Iop_32to16, getIReg(rt)), 7658 unop(Iop_32to16, getIReg(rs)))); 7659 } else { 7660 assign(t0, binop(Iop_Shr32, 7661 binop(Iop_Add32, 7662 binop(Iop_Sar32, 7663 getIReg(rt), 7664 mkU8(rd-1)), 7665 mkU32(0x1)), 7666 mkU8(0x1))); 7667 assign(t1, binop(Iop_Shr32, 7668 binop(Iop_Add32, 7669 binop(Iop_Sar32, 7670 getIReg(rs), 7671 mkU8(rd-1)), 7672 mkU32(0x1)), 7673 mkU8(0x1))); 7674 putIReg(rt, binop(Iop_16HLto32, 7675 unop(Iop_32to16, mkexpr(t0)), 7676 unop(Iop_32to16, mkexpr(t1)))); 7677 }; 7678 break; 7679 } 7680 case 0xE: { /* PACKRL.PH */ 7681 DIP("packrl.ph r%d, r%d, r%d", rd, rs, rt); 7682 vassert(!mode64); 7683 7684 putIReg(rd, binop(Iop_16HLto32, 7685 unop(Iop_32to16, getIReg(rs)), 7686 unop(Iop_32HIto16, getIReg(rt)))); 7687 break; 7688 } 7689 case 0x18: { /* CMPGDU.EQ.QB */ 7690 DIP("cmpgdu.eq.qb r%d, r%d, r%d", rd, rs, rt); 7691 vassert(!mode64); 7692 t1 = newTemp(Ity_I1); 7693 t2 = newTemp(Ity_I1); 7694 t3 = newTemp(Ity_I1); 7695 t4 = newTemp(Ity_I1); 7696 t5 = newTemp(Ity_I32); 7697 t6 = newTemp(Ity_I32); 7698 t7 = newTemp(Ity_I32); 7699 t8 = newTemp(Ity_I32); 7700 7701 assign(t1, 7702 binop(Iop_CmpEQ32, 7703 unop(Iop_8Uto32, 7704 unop(Iop_16to8, 7705 unop(Iop_32to16, getIReg(rs)))), 7706 unop(Iop_8Uto32, 7707 unop(Iop_16to8, 7708 unop(Iop_32to16, getIReg(rt)))))); 7709 assign(t5, IRExpr_ITE(mkexpr(t1), 7710 mkU32(0x00000001), mkU32(0))); 7711 putDSPControl(IRExpr_ITE(mkexpr(t1), 7712 binop(Iop_Or32, 7713 getDSPControl(), 7714 mkU32(0x01000000)), 7715 binop(Iop_And32, 7716 getDSPControl(), 7717 mkU32(0xfeffffff)))); 7718 7719 assign(t2, binop(Iop_CmpEQ32, 7720 unop(Iop_8Uto32, 7721 unop(Iop_16HIto8, 7722 unop(Iop_32to16, getIReg(rs)))), 7723 unop(Iop_8Uto32, 7724 unop(Iop_16HIto8, 7725 unop(Iop_32to16, 7726 getIReg(rt)))))); 7727 assign(t6, IRExpr_ITE(mkexpr(t2), 7728 mkU32(0x00000002), mkU32(0))); 7729 putDSPControl(IRExpr_ITE(mkexpr(t2), 7730 binop(Iop_Or32, 7731 getDSPControl(), 7732 mkU32(0x02000000)), 7733 binop(Iop_And32, 7734 getDSPControl(), 7735 mkU32(0xfdffffff)))); 7736 7737 assign(t3, binop(Iop_CmpEQ32, 7738 unop(Iop_8Uto32, 7739 unop(Iop_16to8, 7740 unop(Iop_32HIto16, 7741 getIReg(rs)))), 7742 unop(Iop_8Uto32, 7743 unop(Iop_16to8, 7744 unop(Iop_32HIto16, 7745 getIReg(rt)))))); 7746 assign(t7, IRExpr_ITE(mkexpr(t3), 7747 mkU32(0x00000004), mkU32(0))); 7748 putDSPControl(IRExpr_ITE(mkexpr(t3), 7749 binop(Iop_Or32, 7750 getDSPControl(), 7751 mkU32(0x04000000)), 7752 binop(Iop_And32, 7753 getDSPControl(), 7754 mkU32(0xfbffffff)))); 7755 7756 assign(t4, binop(Iop_CmpEQ32, 7757 unop(Iop_8Uto32, 7758 unop(Iop_16HIto8, 7759 unop(Iop_32HIto16, 7760 getIReg(rs)))), 7761 unop(Iop_8Uto32, 7762 unop(Iop_16HIto8, 7763 unop(Iop_32HIto16, 7764 getIReg(rt)))))); 7765 assign(t8, IRExpr_ITE(mkexpr(t4), 7766 mkU32(0x00000008), mkU32(0))); 7767 putDSPControl(IRExpr_ITE(mkexpr(t4), 7768 binop(Iop_Or32, 7769 getDSPControl(), 7770 mkU32(0x08000000)), 7771 binop(Iop_And32, 7772 getDSPControl(), 7773 mkU32(0xf7ffffff)))); 7774 7775 putIReg(rd, binop(Iop_Or32, 7776 binop(Iop_Or32, 7777 binop(Iop_Or32, 7778 mkexpr(t5), mkexpr(t6)), 7779 mkexpr(t7)), 7780 mkexpr(t8))); 7781 break; 7782 } 7783 case 0x19: { /* CMPGDU.LT.QB */ 7784 DIP("cmpgdu.lt.qb r%d, r%d, r%d", rd, rs, rt); 7785 vassert(!mode64); 7786 t1 = newTemp(Ity_I1); 7787 t2 = newTemp(Ity_I1); 7788 t3 = newTemp(Ity_I1); 7789 t4 = newTemp(Ity_I1); 7790 t5 = newTemp(Ity_I32); 7791 t6 = newTemp(Ity_I32); 7792 t7 = newTemp(Ity_I32); 7793 t8 = newTemp(Ity_I32); 7794 7795 assign(t1, binop(Iop_CmpLT32U, 7796 unop(Iop_8Uto32, 7797 unop(Iop_16to8, 7798 unop(Iop_32to16, getIReg(rs)))), 7799 unop(Iop_8Uto32, 7800 unop(Iop_16to8, 7801 unop(Iop_32to16, 7802 getIReg(rt)))))); 7803 assign(t5, IRExpr_ITE(mkexpr(t1), 7804 mkU32(0x00000001), mkU32(0))); 7805 putDSPControl(IRExpr_ITE(mkexpr(t1), 7806 binop(Iop_Or32, 7807 getDSPControl(), 7808 mkU32(0x01000000)), 7809 binop(Iop_And32, 7810 getDSPControl(), 7811 mkU32(0xfeffffff)))); 7812 7813 assign(t2, binop(Iop_CmpLT32U, 7814 unop(Iop_8Uto32, 7815 unop(Iop_16HIto8, 7816 unop(Iop_32to16, getIReg(rs)))), 7817 unop(Iop_8Uto32, 7818 unop(Iop_16HIto8, 7819 unop(Iop_32to16, 7820 getIReg(rt)))))); 7821 assign(t6, IRExpr_ITE(mkexpr(t2), 7822 mkU32(0x00000002), mkU32(0))); 7823 putDSPControl(IRExpr_ITE(mkexpr(t2), 7824 binop(Iop_Or32, 7825 getDSPControl(), 7826 mkU32(0x02000000)), 7827 binop(Iop_And32, 7828 getDSPControl(), 7829 mkU32(0xfdffffff)))); 7830 7831 assign(t3, binop(Iop_CmpLT32U, 7832 unop(Iop_8Uto32, 7833 unop(Iop_16to8, 7834 unop(Iop_32HIto16, 7835 getIReg(rs)))), 7836 unop(Iop_8Uto32, 7837 unop(Iop_16to8, 7838 unop(Iop_32HIto16, 7839 getIReg(rt)))))); 7840 assign(t7, IRExpr_ITE(mkexpr(t3), 7841 mkU32(0x00000004), mkU32(0))); 7842 putDSPControl(IRExpr_ITE(mkexpr(t3), 7843 binop(Iop_Or32, 7844 getDSPControl(), 7845 mkU32(0x04000000)), 7846 binop(Iop_And32, 7847 getDSPControl(), 7848 mkU32(0xfbffffff)))); 7849 7850 assign(t4, binop(Iop_CmpLT32U, 7851 unop(Iop_8Uto32, 7852 unop(Iop_16HIto8, 7853 unop(Iop_32HIto16, 7854 getIReg(rs)))), 7855 unop(Iop_8Uto32, 7856 unop(Iop_16HIto8, 7857 unop(Iop_32HIto16, 7858 getIReg(rt)))))); 7859 assign(t8, IRExpr_ITE(mkexpr(t4), 7860 mkU32(0x00000008), mkU32(0))); 7861 putDSPControl(IRExpr_ITE(mkexpr(t4), 7862 binop(Iop_Or32, 7863 getDSPControl(), 7864 mkU32(0x08000000)), 7865 binop(Iop_And32, 7866 getDSPControl(), 7867 mkU32(0xf7ffffff)))); 7868 7869 putIReg(rd, binop(Iop_Or32, 7870 binop(Iop_Or32, 7871 binop(Iop_Or32, 7872 mkexpr(t5), mkexpr(t6)), 7873 mkexpr(t7)), 7874 mkexpr(t8))); 7875 break; 7876 } 7877 case 0x1A: { /* CMPGDU.LE.QB */ 7878 DIP("cmpgdu.le.qb r%d, r%d, r%d", rd, rs, rt); 7879 vassert(!mode64); 7880 t1 = newTemp(Ity_I1); 7881 t2 = newTemp(Ity_I1); 7882 t3 = newTemp(Ity_I1); 7883 t4 = newTemp(Ity_I1); 7884 t5 = newTemp(Ity_I32); 7885 t6 = newTemp(Ity_I32); 7886 t7 = newTemp(Ity_I32); 7887 t8 = newTemp(Ity_I32); 7888 7889 assign(t1, binop(Iop_CmpLE32U, 7890 unop(Iop_8Uto32, 7891 unop(Iop_16to8, 7892 unop(Iop_32to16, getIReg(rs)))), 7893 unop(Iop_8Uto32, 7894 unop(Iop_16to8, 7895 unop(Iop_32to16, 7896 getIReg(rt)))))); 7897 assign(t5, IRExpr_ITE(mkexpr(t1), 7898 mkU32(0x00000001), 7899 mkU32(0))); 7900 putDSPControl(IRExpr_ITE(mkexpr(t1), 7901 binop(Iop_Or32, 7902 getDSPControl(), 7903 mkU32(0x01000000)), 7904 binop(Iop_And32, 7905 getDSPControl(), 7906 mkU32(0xfeffffff)))); 7907 7908 assign(t2, binop(Iop_CmpLE32U, 7909 unop(Iop_8Uto32, 7910 unop(Iop_16HIto8, 7911 unop(Iop_32to16, getIReg(rs)))), 7912 unop(Iop_8Uto32, 7913 unop(Iop_16HIto8, 7914 unop(Iop_32to16, 7915 getIReg(rt)))))); 7916 assign(t6, IRExpr_ITE(mkexpr(t2), 7917 mkU32(0x00000002), mkU32(0))); 7918 putDSPControl(IRExpr_ITE(mkexpr(t2), 7919 binop(Iop_Or32, 7920 getDSPControl(), 7921 mkU32(0x02000000)), 7922 binop(Iop_And32, 7923 getDSPControl(), 7924 mkU32(0xfdffffff)))); 7925 7926 assign(t3, binop(Iop_CmpLE32U, 7927 unop(Iop_8Uto32, 7928 unop(Iop_16to8, 7929 unop(Iop_32HIto16, 7930 getIReg(rs)))), 7931 unop(Iop_8Uto32, 7932 unop(Iop_16to8, 7933 unop(Iop_32HIto16, 7934 getIReg(rt)))))); 7935 assign(t7, IRExpr_ITE(mkexpr(t3), 7936 mkU32(0x00000004), mkU32(0))); 7937 putDSPControl(IRExpr_ITE(mkexpr(t3), 7938 binop(Iop_Or32, 7939 getDSPControl(), 7940 mkU32(0x04000000)), 7941 binop(Iop_And32, 7942 getDSPControl(), 7943 mkU32(0xfbffffff)))); 7944 7945 assign(t4, binop(Iop_CmpLE32U, 7946 unop(Iop_8Uto32, 7947 unop(Iop_16HIto8, 7948 unop(Iop_32HIto16, 7949 getIReg(rs)))), 7950 unop(Iop_8Uto32, 7951 unop(Iop_16HIto8, 7952 unop(Iop_32HIto16, 7953 getIReg(rt)))))); 7954 assign(t8, IRExpr_ITE(mkexpr(t4), 7955 mkU32(0x00000008), mkU32(0))); 7956 putDSPControl(IRExpr_ITE(mkexpr(t4), 7957 binop(Iop_Or32, 7958 getDSPControl(), 7959 mkU32(0x08000000)), 7960 binop(Iop_And32, 7961 getDSPControl(), 7962 mkU32(0xf7ffffff)))); 7963 7964 putIReg(rd, binop(Iop_Or32, 7965 binop(Iop_Or32, 7966 binop(Iop_Or32, 7967 mkexpr(t5), mkexpr(t6)), 7968 mkexpr(t7)), 7969 mkexpr(t8))); 7970 break; 7971 } 7972 default: 7973 return -1; 7974 } 7975 break; /* end of CMPU.EQ.QB */ 7976 } 7977 case 0x13: { /* SHLL.QB */ 7978 switch(sa) { 7979 case 0x0: { /* SHLL.QB */ 7980 DIP("shll.qb r%d, r%d, %d", rd, rt, rs); 7981 vassert(!mode64); 7982 t0 = newTemp(Ity_I32); 7983 t1 = newTemp(Ity_I1); 7984 t2 = newTemp(Ity_I1); 7985 t3 = newTemp(Ity_I32); 7986 t4 = newTemp(Ity_I1); 7987 t5 = newTemp(Ity_I1); 7988 t6 = newTemp(Ity_I32); 7989 t7 = newTemp(Ity_I1); 7990 t8 = newTemp(Ity_I1); 7991 t9 = newTemp(Ity_I1); 7992 t10 = newTemp(Ity_I1); 7993 7994 if (0 == rs) { 7995 putIReg(rd, getIReg(rt)); 7996 } else { 7997 /* Shift bits 7..0 and 23..16. */ 7998 assign(t0, binop(Iop_Shl32, 7999 binop(Iop_And32, 8000 getIReg(rt), 8001 mkU32(0x00ff00ff)), 8002 mkU8(rs))); 8003 assign(t1, binop(Iop_CmpNE32, 8004 binop(Iop_And32, 8005 mkexpr(t0), 8006 mkU32(0xff000000)), 8007 mkU32(0x00000000))); 8008 assign(t2, binop(Iop_CmpNE32, 8009 binop(Iop_And32, 8010 mkexpr(t0), 8011 mkU32(0xff000000)), 8012 mkU32(0xff000000))); 8013 assign(t7, binop(Iop_CmpNE32, 8014 binop(Iop_And32, 8015 mkexpr(t0), 8016 mkU32(0x0000ff00)), 8017 mkU32(0x00000000))); 8018 assign(t8, binop(Iop_CmpNE32, 8019 binop(Iop_And32, 8020 mkexpr(t0), 8021 mkU32(0x0000ff00)), 8022 mkU32(0x000ff00))); 8023 /* Shift bits 15..8 and 31..24. */ 8024 assign(t3, binop(Iop_Shl32, 8025 binop(Iop_Shr32, 8026 binop(Iop_And32, 8027 getIReg(rt), 8028 mkU32(0xff00ff00)), 8029 mkU8(8)), 8030 mkU8(rs))); 8031 assign(t4, binop(Iop_CmpNE32, 8032 binop(Iop_And32, 8033 mkexpr(t3), 8034 mkU32(0xff000000)), 8035 mkU32(0x00000000))); 8036 assign(t5, binop(Iop_CmpNE32, 8037 binop(Iop_And32, 8038 mkexpr(t3), 8039 mkU32(0xff000000)), 8040 mkU32(0xff000000))); 8041 assign(t9, binop(Iop_CmpNE32, 8042 binop(Iop_And32, 8043 mkexpr(t3), 8044 mkU32(0x0000ff00)), 8045 mkU32(0x00000000))); 8046 assign(t10, binop(Iop_CmpNE32, 8047 binop(Iop_And32, 8048 mkexpr(t3), 8049 mkU32(0x0000ff00)), 8050 mkU32(0x0000ff00))); 8051 8052 assign(t6, binop(Iop_Or32, 8053 binop(Iop_Or32, 8054 binop(Iop_And32, 8055 unop(Iop_1Uto32, 8056 mkexpr(t1)), 8057 unop(Iop_1Uto32, 8058 mkexpr(t2))), 8059 binop(Iop_And32, 8060 unop(Iop_1Uto32, 8061 mkexpr(t7)), 8062 unop(Iop_1Uto32, 8063 mkexpr(t8)))), 8064 binop(Iop_Or32, 8065 binop(Iop_And32, 8066 unop(Iop_1Uto32, 8067 mkexpr(t4)), 8068 unop(Iop_1Uto32, 8069 mkexpr(t5))), 8070 binop(Iop_And32, 8071 unop(Iop_1Uto32, 8072 mkexpr(t9)), 8073 unop(Iop_1Uto32, 8074 mkexpr(t10)))))); 8075 8076 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 8077 mkexpr(t6), 8078 mkU32(0x0)), 8079 binop(Iop_Or32, 8080 getDSPControl(), 8081 mkU32(0x400000)), 8082 getDSPControl())); 8083 putIReg(rd, binop(Iop_Or32, 8084 binop(Iop_Shl32, 8085 binop(Iop_And32, 8086 mkexpr(t3), 8087 mkU32(0x00ff00ff)), 8088 mkU8(8)), 8089 binop(Iop_And32, 8090 mkexpr(t0), 8091 mkU32(0x00ff00ff)))); 8092 } 8093 break; 8094 } 8095 case 0x3: { /* SHRL.QB */ 8096 DIP("shrl.qb r%d, r%d, %d", rd, rt, rs); 8097 vassert(!mode64); 8098 t0 = newTemp(Ity_I32); 8099 t1 = newTemp(Ity_I8); 8100 t2 = newTemp(Ity_I32); 8101 t3 = newTemp(Ity_I8); 8102 t4 = newTemp(Ity_I32); 8103 t5 = newTemp(Ity_I8); 8104 t6 = newTemp(Ity_I32); 8105 t7 = newTemp(Ity_I8); 8106 t9 = newTemp(Ity_I32); 8107 8108 assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7))); 8109 assign(t0, unop(Iop_8Uto32, 8110 unop(Iop_16to8, 8111 unop(Iop_32to16, getIReg(rt))))); 8112 assign(t1, unop(Iop_32to8, 8113 binop(Iop_Shr32, 8114 mkexpr(t0), 8115 unop(Iop_32to8, mkexpr(t9))))); 8116 8117 assign(t2, unop(Iop_8Uto32, 8118 unop(Iop_16HIto8, 8119 unop(Iop_32to16, getIReg(rt))))); 8120 assign(t3, unop(Iop_32to8, 8121 binop(Iop_Shr32, 8122 mkexpr(t2), 8123 unop(Iop_32to8, mkexpr(t9))))); 8124 8125 assign(t4, unop(Iop_8Uto32, 8126 unop(Iop_16to8, 8127 unop(Iop_32HIto16, getIReg(rt))))); 8128 assign(t5, unop(Iop_32to8, 8129 binop(Iop_Shr32, 8130 mkexpr(t4), 8131 unop(Iop_32to8, mkexpr(t9))))); 8132 8133 assign(t6, unop(Iop_8Uto32, 8134 unop(Iop_16HIto8, 8135 unop(Iop_32HIto16, getIReg(rt))))); 8136 assign(t7, unop(Iop_32to8, 8137 binop(Iop_Shr32, 8138 mkexpr(t6), 8139 unop(Iop_32to8, mkexpr(t9))))); 8140 putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32, 8141 mkexpr(t9), 8142 mkU32(0x0)), 8143 getIReg(rt), 8144 binop(Iop_16HLto32, 8145 binop(Iop_8HLto16, 8146 mkexpr(t7), 8147 mkexpr(t5)), 8148 binop(Iop_8HLto16, 8149 mkexpr(t3), 8150 mkexpr(t1))))); 8151 break; 8152 } 8153 case 0x2: { /* SHLLV.QB */ 8154 DIP("shllv.qb r%d, r%d, r%d", rd, rt, rs); 8155 vassert(!mode64); 8156 t0 = newTemp(Ity_I32); 8157 t1 = newTemp(Ity_I1); 8158 t2 = newTemp(Ity_I1); 8159 t3 = newTemp(Ity_I32); 8160 t4 = newTemp(Ity_I1); 8161 t5 = newTemp(Ity_I1); 8162 t6 = newTemp(Ity_I32); 8163 t7 = newTemp(Ity_I1); 8164 t8 = newTemp(Ity_I1); 8165 t9 = newTemp(Ity_I1); 8166 t10 = newTemp(Ity_I1); 8167 t11 = newTemp(Ity_I8); 8168 8169 assign(t11, unop(Iop_32to8, 8170 binop(Iop_And32, 8171 getIReg(rs), 8172 mkU32(0x7)))); 8173 /* Shift bits 7..0 and 23..16. */ 8174 assign(t0, binop(Iop_Shl32, 8175 binop(Iop_And32, 8176 getIReg(rt), 8177 mkU32(0x00ff00ff)), 8178 mkexpr(t11))); 8179 assign(t1, binop(Iop_CmpNE32, 8180 binop(Iop_And32, 8181 mkexpr(t0), 8182 mkU32(0xff000000)), 8183 mkU32(0x00000000))); 8184 assign(t2, binop(Iop_CmpNE32, 8185 binop(Iop_And32, 8186 mkexpr(t0), 8187 mkU32(0xff000000)), 8188 mkU32(0xff000000))); 8189 assign(t7, binop(Iop_CmpNE32, 8190 binop(Iop_And32, 8191 mkexpr(t0), 8192 mkU32(0x0000ff00)), 8193 mkU32(0x00000000))); 8194 assign(t8, binop(Iop_CmpNE32, 8195 binop(Iop_And32, 8196 mkexpr(t0), 8197 mkU32(0x0000ff00)), 8198 mkU32(0x000ff00))); 8199 /* Shift bits 15..8 and 31..24. */ 8200 assign(t3, binop(Iop_Shl32, 8201 binop(Iop_Shr32, 8202 binop(Iop_And32, 8203 getIReg(rt), 8204 mkU32(0xff00ff00)), 8205 mkU8(8)), 8206 mkexpr(t11))); 8207 assign(t4, binop(Iop_CmpNE32, 8208 binop(Iop_And32, 8209 mkexpr(t3), 8210 mkU32(0xff000000)), 8211 mkU32(0x00000000))); 8212 assign(t5, binop(Iop_CmpNE32, 8213 binop(Iop_And32, 8214 mkexpr(t3), 8215 mkU32(0xff000000)), 8216 mkU32(0xff000000))); 8217 assign(t9, binop(Iop_CmpNE32, 8218 binop(Iop_And32, 8219 mkexpr(t3), 8220 mkU32(0x0000ff00)), 8221 mkU32(0x00000000))); 8222 assign(t10, binop(Iop_CmpNE32, 8223 binop(Iop_And32, 8224 mkexpr(t3), 8225 mkU32(0x0000ff00)), 8226 mkU32(0x0000ff00))); 8227 8228 assign(t6, binop(Iop_Or32, 8229 binop(Iop_Or32, 8230 binop(Iop_And32, 8231 unop(Iop_1Uto32, 8232 mkexpr(t1)), 8233 unop(Iop_1Uto32, 8234 mkexpr(t2))), 8235 binop(Iop_And32, 8236 unop(Iop_1Uto32, 8237 mkexpr(t7)), 8238 unop(Iop_1Uto32, 8239 mkexpr(t8)))), 8240 binop(Iop_Or32, 8241 binop(Iop_And32, 8242 unop(Iop_1Uto32, 8243 mkexpr(t4)), 8244 unop(Iop_1Uto32, 8245 mkexpr(t5))), 8246 binop(Iop_And32, 8247 unop(Iop_1Uto32, 8248 mkexpr(t9)), 8249 unop(Iop_1Uto32, 8250 mkexpr(t10)))))); 8251 8252 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 8253 mkexpr(t6), 8254 mkU32(0x0)), 8255 binop(Iop_Or32, 8256 getDSPControl(), 8257 mkU32(0x400000)), 8258 getDSPControl())); 8259 putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32, 8260 unop(Iop_8Uto32, mkexpr(t11)), 8261 mkU32(0)), 8262 getIReg(rt), 8263 binop(Iop_Or32, 8264 binop(Iop_Shl32, 8265 binop(Iop_And32, 8266 mkexpr(t3), 8267 mkU32(0xff00ff)), 8268 mkU8(8)), 8269 binop(Iop_And32, 8270 mkexpr(t0), 8271 mkU32(0x00ff00ff))))); 8272 break; 8273 } 8274 case 0x1: { /* SHRLV.QB */ 8275 DIP("shrlv.qb r%d, r%d, r%d", rd, rt, rs); 8276 vassert(!mode64); 8277 t0 = newTemp(Ity_I8); 8278 t1 = newTemp(Ity_I8); 8279 t2 = newTemp(Ity_I8); 8280 t3 = newTemp(Ity_I8); 8281 8282 assign(t0, unop(Iop_32to8, 8283 binop(Iop_Shr32, 8284 unop(Iop_8Uto32, 8285 unop(Iop_32to8, getIReg(rt))), 8286 mkU8(rs)))); 8287 assign(t1, unop(Iop_32to8, 8288 binop(Iop_Shr32, 8289 unop(Iop_8Uto32, 8290 unop(Iop_16HIto8, 8291 unop(Iop_32to16, 8292 getIReg(rt)))), 8293 mkU8(rs)))); 8294 assign(t2, unop(Iop_32to8, 8295 binop(Iop_Shr32, 8296 unop(Iop_8Uto32, 8297 unop(Iop_16to8, 8298 unop(Iop_32HIto16, 8299 getIReg(rt)))), 8300 mkU8(rs)))); 8301 assign(t3, unop(Iop_32to8, 8302 binop(Iop_Shr32, 8303 unop(Iop_8Uto32, 8304 unop(Iop_16HIto8, 8305 unop(Iop_32HIto16, 8306 getIReg(rt)))), 8307 mkU8(rs)))); 8308 putIReg(rd, 8309 binop(Iop_16HLto32, 8310 binop(Iop_8HLto16, mkexpr(t3), mkexpr(t2)), 8311 binop(Iop_8HLto16, mkexpr(t1), mkexpr(t0)))); 8312 break; 8313 } 8314 case 0x4: { /* SHRA.QB */ 8315 DIP("shra.qb r%d, r%d, %d", rd, rt, rs); 8316 vassert(!mode64); 8317 t0 = newTemp(Ity_I32); 8318 t1 = newTemp(Ity_I32); 8319 t2 = newTemp(Ity_I32); 8320 t3 = newTemp(Ity_I32); 8321 t4 = newTemp(Ity_I32); 8322 t5 = newTemp(Ity_I32); 8323 t6 = newTemp(Ity_I32); 8324 t7 = newTemp(Ity_I32); 8325 t8 = newTemp(Ity_I32); 8326 t9 = newTemp(Ity_I32); 8327 t10 = newTemp(Ity_I32); 8328 t11 = newTemp(Ity_I32); 8329 8330 /* ========== GPR[rt]_31..24 ========== */ 8331 assign(t1, 8332 unop(Iop_8Uto32, 8333 unop(Iop_16HIto8, 8334 unop(Iop_32HIto16, getIReg(rt))))); 8335 assign(t2, 8336 binop(Iop_Shr32, mkexpr(t1), mkU8(rs))); 8337 /* tempD_7..0 */ 8338 assign(t0, 8339 binop(Iop_Or32, 8340 mkexpr(t2), 8341 binop(Iop_Shl32, 8342 IRExpr_ITE(binop(Iop_CmpEQ32, 8343 binop(Iop_And32, 8344 mkexpr(t1), 8345 mkU32(0x00000080) 8346 ), 8347 mkU32(0x00000080)), 8348 mkU32(0xFFFFFFFF), 8349 mkU32(0x00000000)), 8350 binop(Iop_Sub8, mkU8(0x8), mkU8(rs))))); 8351 8352 /* ========== GPR[rt]_23..16 ========== */ 8353 assign(t4, 8354 unop(Iop_8Uto32, 8355 unop(Iop_16to8, 8356 unop(Iop_32HIto16, getIReg(rt))))); 8357 assign(t5, binop(Iop_Shr32, mkexpr(t4), mkU8(rs))); 8358 /* tempC_7..0 */ 8359 assign(t3, 8360 binop(Iop_Or32, 8361 mkexpr(t5), 8362 binop(Iop_Shl32, 8363 IRExpr_ITE(binop(Iop_CmpEQ32, 8364 binop(Iop_And32, 8365 mkexpr(t4), 8366 mkU32(0x00000080) 8367 ), 8368 mkU32(0x00000080)), 8369 mkU32(0xFFFFFFFF), 8370 mkU32(0x00000000)), 8371 binop(Iop_Sub8, mkU8(0x8), mkU8(rs))))); 8372 8373 /* ========== GPR[rt]_15..8 ========== */ 8374 assign(t7, 8375 unop(Iop_8Uto32, 8376 unop(Iop_16HIto8, 8377 unop(Iop_32to16, getIReg(rt))))); 8378 assign(t8, binop(Iop_Shr32, mkexpr(t7), mkU8(rs))); 8379 /* tempB_7..0 */ 8380 assign(t6, 8381 binop(Iop_Or32, 8382 mkexpr(t8), 8383 binop(Iop_Shl32, 8384 IRExpr_ITE(binop(Iop_CmpEQ32, 8385 binop(Iop_And32, 8386 mkexpr(t7), 8387 mkU32(0x00000080) 8388 ), 8389 mkU32(0x00000080)), 8390 mkU32(0xFFFFFFFF), 8391 mkU32(0x00000000)), 8392 binop(Iop_Sub8, mkU8(0x8), mkU8(rs))))); 8393 8394 /* ========== GPR[rt]_7..0 ========== */ 8395 assign(t10, 8396 unop(Iop_8Uto32, 8397 unop(Iop_16to8, 8398 unop(Iop_32to16, getIReg(rt))))); 8399 assign(t11, binop(Iop_Shr32, mkexpr(t10), mkU8(rs))); 8400 /* tempB_7..0 */ 8401 assign(t9, 8402 binop(Iop_Or32, 8403 mkexpr(t11), 8404 binop(Iop_Shl32, 8405 IRExpr_ITE(binop(Iop_CmpEQ32, 8406 binop(Iop_And32, 8407 mkexpr(t10), 8408 mkU32(0x00000080) 8409 ), 8410 mkU32(0x00000080)), 8411 mkU32(0xFFFFFFFF), 8412 mkU32(0x00000000)), 8413 binop(Iop_Sub8, mkU8(0x8), mkU8(rs))))); 8414 8415 putIReg(rd, 8416 binop(Iop_16HLto32, 8417 binop(Iop_8HLto16, 8418 unop(Iop_32to8, mkexpr(t0)), 8419 unop(Iop_32to8, mkexpr(t3))), 8420 binop(Iop_8HLto16, 8421 unop(Iop_32to8, mkexpr(t6)), 8422 unop(Iop_32to8, mkexpr(t9))))); 8423 break; 8424 } 8425 case 0x5: { /* SHRA_R.QB */ 8426 DIP("shra_r.qb r%d, r%d, %d", rd, rt, rs); 8427 vassert(!mode64); 8428 t0 = newTemp(Ity_I32); 8429 t1 = newTemp(Ity_I8); 8430 t2 = newTemp(Ity_I32); 8431 t3 = newTemp(Ity_I8); 8432 t4 = newTemp(Ity_I32); 8433 t5 = newTemp(Ity_I8); 8434 t6 = newTemp(Ity_I32); 8435 t7 = newTemp(Ity_I8); 8436 8437 if (0 == rs) { 8438 putIReg(rd, getIReg(rt)); 8439 } else { 8440 assign(t0, unop(Iop_8Sto32, 8441 unop(Iop_16to8, 8442 unop(Iop_32to16, getIReg(rt))))); 8443 assign(t1, unop(Iop_32to8, 8444 binop(Iop_Sar32, 8445 binop(Iop_Add32, 8446 mkexpr(t0), 8447 binop(Iop_Shl32, 8448 mkU32(0x1), 8449 mkU8(rs-1))), 8450 mkU8(rs)))); 8451 8452 assign(t2, unop(Iop_8Sto32, 8453 unop(Iop_16HIto8, 8454 unop(Iop_32to16, getIReg(rt))))); 8455 assign(t3, unop(Iop_32to8, 8456 binop(Iop_Sar32, 8457 binop(Iop_Add32, 8458 mkexpr(t2), 8459 binop(Iop_Shl32, 8460 mkU32(0x1), 8461 mkU8(rs-1))), 8462 mkU8(rs)))); 8463 8464 assign(t4, unop(Iop_8Sto32, 8465 unop(Iop_16to8, 8466 unop(Iop_32HIto16, getIReg(rt))))); 8467 assign(t5, unop(Iop_32to8, 8468 binop(Iop_Sar32, 8469 binop(Iop_Add32, 8470 mkexpr(t4), 8471 binop(Iop_Shl32, 8472 mkU32(0x1), 8473 mkU8(rs-1))), 8474 mkU8(rs)))); 8475 8476 assign(t6, unop(Iop_8Sto32, 8477 unop(Iop_16HIto8, 8478 unop(Iop_32HIto16, getIReg(rt))))); 8479 assign(t7, unop(Iop_32to8, 8480 binop(Iop_Sar32, 8481 binop(Iop_Add32, 8482 mkexpr(t6), 8483 binop(Iop_Shl32, 8484 mkU32(0x1), 8485 mkU8(rs-1))), 8486 mkU8(rs)))); 8487 putIReg(rd, binop(Iop_16HLto32, 8488 binop(Iop_8HLto16, 8489 mkexpr(t7), mkexpr(t5)), 8490 binop(Iop_8HLto16, 8491 mkexpr(t3), mkexpr(t1)))); 8492 } 8493 break; 8494 } 8495 case 0x6: { /* SHRAV.QB */ 8496 DIP("shrav.qb r%d, r%d, %d", rd, rt, rs); 8497 vassert(!mode64); 8498 8499 t0 = newTemp(Ity_I32); 8500 t1 = newTemp(Ity_I32); 8501 t2 = newTemp(Ity_I32); 8502 8503 t3 = newTemp(Ity_I32); 8504 t4 = newTemp(Ity_I32); 8505 t5 = newTemp(Ity_I32); 8506 8507 t6 = newTemp(Ity_I32); 8508 t7 = newTemp(Ity_I32); 8509 t8 = newTemp(Ity_I32); 8510 8511 t9 = newTemp(Ity_I32); 8512 t10 = newTemp(Ity_I32); 8513 t11 = newTemp(Ity_I32); 8514 8515 /* ========== GPR[rt]_31..24 ========== */ 8516 assign(t1, 8517 unop(Iop_8Uto32, 8518 unop(Iop_16HIto8, 8519 unop(Iop_32HIto16, getIReg(rt))))); 8520 assign(t2, 8521 binop(Iop_Shr32, 8522 mkexpr(t1), 8523 unop(Iop_32to8, binop(Iop_And32, 8524 getIReg(rs), 8525 mkU32(0x7))))); 8526 /* tempD_7..0 */ 8527 assign(t0, 8528 binop(Iop_Or32, 8529 mkexpr(t2), 8530 binop(Iop_Shl32, 8531 IRExpr_ITE(binop(Iop_CmpEQ32, 8532 binop(Iop_And32, 8533 mkexpr(t1), 8534 mkU32(0x00000080) 8535 ), 8536 mkU32(0x00000080)), 8537 mkU32(0xFFFFFFFF), 8538 mkU32(0x00000000)), 8539 binop(Iop_Sub8, 8540 mkU8(0x8), 8541 unop(Iop_32to8, binop(Iop_And32, 8542 getIReg(rs), 8543 mkU32(0x7))) 8544 )))); 8545 8546 /* ========== GPR[rt]_23..16 ========== */ 8547 assign(t4, 8548 unop(Iop_8Uto32, 8549 unop(Iop_16to8, 8550 unop(Iop_32HIto16, getIReg(rt))))); 8551 assign(t5, 8552 binop(Iop_Shr32, 8553 mkexpr(t4), 8554 unop(Iop_32to8, binop(Iop_And32, 8555 getIReg(rs), 8556 mkU32(0x7))))); 8557 /* tempC_7..0 */ 8558 assign(t3, 8559 binop(Iop_Or32, 8560 mkexpr(t5), 8561 binop(Iop_Shl32, 8562 IRExpr_ITE(binop(Iop_CmpEQ32, 8563 binop(Iop_And32, 8564 mkexpr(t4), 8565 mkU32(0x00000080) 8566 ), 8567 mkU32(0x00000080)), 8568 mkU32(0xFFFFFFFF), 8569 mkU32(0x00000000)), 8570 binop(Iop_Sub8, 8571 mkU8(0x8), 8572 unop(Iop_32to8, binop(Iop_And32, 8573 getIReg(rs), 8574 mkU32(0x7))) 8575 )))); 8576 8577 /* ========== GPR[rt]_15..8 ========== */ 8578 assign(t7, 8579 unop(Iop_8Uto32, 8580 unop(Iop_16HIto8, 8581 unop(Iop_32to16, getIReg(rt))))); 8582 assign(t8, 8583 binop(Iop_Shr32, 8584 mkexpr(t7), 8585 unop(Iop_32to8, binop(Iop_And32, 8586 getIReg(rs), 8587 mkU32(0x7))))); 8588 /* tempB_7..0 */ 8589 assign(t6, 8590 binop(Iop_Or32, 8591 mkexpr(t8), 8592 binop(Iop_Shl32, 8593 IRExpr_ITE(binop(Iop_CmpEQ32, 8594 binop(Iop_And32, 8595 mkexpr(t7), 8596 mkU32(0x00000080) 8597 ), 8598 mkU32(0x00000080)), 8599 mkU32(0xFFFFFFFF), 8600 mkU32(0x00000000)), 8601 binop(Iop_Sub8, 8602 mkU8(0x8), 8603 unop(Iop_32to8, binop(Iop_And32, 8604 getIReg(rs), 8605 mkU32(0x7))) 8606 )))); 8607 8608 /* ========== GPR[rt]_7..0 ========== */ 8609 assign(t10, 8610 unop(Iop_8Uto32, 8611 unop(Iop_16to8, 8612 unop(Iop_32to16, getIReg(rt))))); 8613 assign(t11, 8614 binop(Iop_Shr32, 8615 mkexpr(t10), 8616 unop(Iop_32to8, binop(Iop_And32, 8617 getIReg(rs), 8618 mkU32(0x7))))); 8619 /* tempB_7..0 */ 8620 assign(t9, 8621 binop(Iop_Or32, 8622 mkexpr(t11), 8623 binop(Iop_Shl32, 8624 IRExpr_ITE(binop(Iop_CmpEQ32, 8625 binop(Iop_And32, 8626 mkexpr(t10), 8627 mkU32(0x00000080) 8628 ), 8629 mkU32(0x00000080)), 8630 mkU32(0xFFFFFFFF), 8631 mkU32(0x00000000)), 8632 binop(Iop_Sub8, 8633 mkU8(0x8), 8634 unop(Iop_32to8, binop(Iop_And32, 8635 getIReg(rs), 8636 mkU32(0x7))) 8637 )))); 8638 8639 putIReg(rd, 8640 binop(Iop_16HLto32, 8641 binop(Iop_8HLto16, 8642 unop(Iop_32to8, 8643 IRExpr_ITE(binop(Iop_CmpEQ32, 8644 binop(Iop_And32, 8645 mkU32(rs), 8646 mkU32(0x7) 8647 ), 8648 mkU32(0x0)), 8649 mkexpr(t1), 8650 mkexpr(t0))), 8651 unop(Iop_32to8, 8652 IRExpr_ITE(binop(Iop_CmpEQ32, 8653 binop(Iop_And32, 8654 mkU32(rs), 8655 mkU32(0x7) 8656 ), 8657 mkU32(0x0)), 8658 mkexpr(t2), 8659 mkexpr(t3)))), 8660 binop(Iop_8HLto16, 8661 unop(Iop_32to8, 8662 IRExpr_ITE(binop(Iop_CmpEQ32, 8663 binop(Iop_And32, 8664 mkU32(rs), 8665 mkU32(0x7) 8666 ), 8667 mkU32(0x0)), 8668 mkexpr(t5), 8669 mkexpr(t6))), 8670 unop(Iop_32to8, 8671 IRExpr_ITE(binop(Iop_CmpEQ32, 8672 binop(Iop_And32, 8673 mkU32(rs), 8674 mkU32(0x7) 8675 ), 8676 mkU32(0x0)), 8677 mkexpr(t8), 8678 mkexpr(t9)))))); 8679 break; 8680 } 8681 case 0x7: { /* SHRAV_R.QB */ 8682 DIP("shrav_r.qb r%d, r%d, r%d", rd, rt, rs); 8683 vassert(!mode64); 8684 t0 = newTemp(Ity_I32); 8685 t1 = newTemp(Ity_I8); 8686 t2 = newTemp(Ity_I32); 8687 t3 = newTemp(Ity_I8); 8688 t4 = newTemp(Ity_I32); 8689 t5 = newTemp(Ity_I8); 8690 t6 = newTemp(Ity_I32); 8691 t7 = newTemp(Ity_I8); 8692 t8 = newTemp(Ity_I8); 8693 t9 = newTemp(Ity_I32); 8694 8695 assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7))); 8696 assign(t8, unop(Iop_32to8, 8697 binop(Iop_Sub32, mkexpr(t9), mkU32(0x1)))); 8698 assign(t0, unop(Iop_8Sto32, 8699 unop(Iop_16to8, 8700 unop(Iop_32to16, getIReg(rt))))); 8701 assign(t1, unop(Iop_32to8, 8702 binop(Iop_Sar32, 8703 binop(Iop_Add32, 8704 mkexpr(t0), 8705 binop(Iop_Shl32, 8706 mkU32(0x1), 8707 mkexpr(t8))), 8708 unop(Iop_32to8, 8709 mkexpr(t9))))); 8710 8711 assign(t2, unop(Iop_8Sto32, 8712 unop(Iop_16HIto8, 8713 unop(Iop_32to16, getIReg(rt))))); 8714 assign(t3, unop(Iop_32to8, 8715 binop(Iop_Sar32, 8716 binop(Iop_Add32, 8717 mkexpr(t2), 8718 binop(Iop_Shl32, 8719 mkU32(0x1), 8720 mkexpr(t8))), 8721 unop(Iop_32to8, mkexpr(t9))))); 8722 8723 assign(t4, unop(Iop_8Sto32, 8724 unop(Iop_16to8, 8725 unop(Iop_32HIto16, getIReg(rt))))); 8726 assign(t5, unop(Iop_32to8, 8727 binop(Iop_Sar32, 8728 binop(Iop_Add32, 8729 mkexpr(t4), 8730 binop(Iop_Shl32, 8731 mkU32(0x1), 8732 mkexpr(t8))), 8733 unop(Iop_32to8, mkexpr(t9))))); 8734 8735 assign(t6, unop(Iop_8Sto32, 8736 unop(Iop_16HIto8, 8737 unop(Iop_32HIto16, getIReg(rt))))); 8738 assign(t7, unop(Iop_32to8, 8739 binop(Iop_Sar32, 8740 binop(Iop_Add32, 8741 mkexpr(t6), 8742 binop(Iop_Shl32, 8743 mkU32(0x1), 8744 mkexpr(t8))), 8745 unop(Iop_32to8, mkexpr(t9))))); 8746 putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32, 8747 mkexpr(t9), 8748 mkU32(0x0)), 8749 getIReg(rt), 8750 binop(Iop_16HLto32, 8751 binop(Iop_8HLto16, 8752 mkexpr(t7), 8753 mkexpr(t5)), 8754 binop(Iop_8HLto16, 8755 mkexpr(t3), 8756 mkexpr(t1))))); 8757 break; 8758 } 8759 case 0x8: { /* SHLL.PH */ 8760 DIP("shll.ph r%d, r%d, %d", rd, rt, rs); 8761 vassert(!mode64); 8762 t0 = newTemp(Ity_I32); 8763 t1 = newTemp(Ity_I32); 8764 t2 = newTemp(Ity_I32); 8765 t3 = newTemp(Ity_I32); 8766 t4 = newTemp(Ity_I32); 8767 t5 = newTemp(Ity_I32); 8768 t6 = newTemp(Ity_I32); 8769 t7 = newTemp(Ity_I32); 8770 8771 if (0 == rs) { 8772 putIReg(rd, getIReg(rt)); 8773 } else { 8774 /* Shift lower 16 bits. */ 8775 assign(t0, binop(Iop_Shl32, 8776 unop(Iop_16Sto32, 8777 unop(Iop_32to16, getIReg(rt))), 8778 mkU8(rs))); 8779 8780 assign(t1, unop(Iop_1Uto32, 8781 binop(Iop_CmpNE32, 8782 binop(Iop_Sar32, 8783 mkexpr(t0), 8784 mkU8(16)), 8785 mkU32(0)))); 8786 assign(t2, unop(Iop_1Uto32, 8787 binop(Iop_CmpNE32, 8788 binop(Iop_Sar32, 8789 mkexpr(t0), 8790 mkU8(16)), 8791 mkU32(0xffffffff)))); 8792 assign(t3, binop(Iop_And32, 8793 mkexpr(t1), 8794 mkexpr(t2))); 8795 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8796 mkexpr(t3), 8797 mkU32(0x1)), 8798 binop(Iop_Or32, 8799 getDSPControl(), 8800 mkU32(0x400000)), 8801 getDSPControl())); 8802 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8803 binop(Iop_And32, 8804 getIReg(rt), 8805 mkU32(0x00008000)), 8806 binop(Iop_And32, 8807 mkexpr(t0), 8808 mkU32(0x00008000)) 8809 ), 8810 getDSPControl(), 8811 binop(Iop_Or32, 8812 getDSPControl(), 8813 mkU32(0x400000)))); 8814 /* Shift higher 16 bits. */ 8815 assign(t4, binop(Iop_Shl32, 8816 unop(Iop_16Sto32, 8817 unop(Iop_32HIto16, getIReg(rt))), 8818 mkU8(rs))); 8819 8820 assign(t5, unop(Iop_1Uto32, 8821 binop(Iop_CmpNE32, 8822 binop(Iop_Sar32, 8823 mkexpr(t4), 8824 mkU8(16)), 8825 mkU32(0)))); 8826 assign(t6, unop(Iop_1Uto32, 8827 binop(Iop_CmpNE32, 8828 binop(Iop_Sar32, 8829 mkexpr(t4), 8830 mkU8(16)), 8831 mkU32(0xffffffff)))); 8832 assign(t7, binop(Iop_And32, 8833 mkexpr(t5), 8834 mkexpr(t6))); 8835 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8836 mkexpr(t7), 8837 mkU32(0x1)), 8838 binop(Iop_Or32, 8839 getDSPControl(), 8840 mkU32(0x400000)), 8841 getDSPControl())); 8842 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8843 mkexpr(t7), 8844 mkU32(0x1)), 8845 binop(Iop_Or32, 8846 getDSPControl(), 8847 mkU32(0x400000)), 8848 getDSPControl())); 8849 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 8850 binop(Iop_And32, 8851 getIReg(rt), 8852 mkU32(0x80000000)), 8853 binop(Iop_Shl32, 8854 binop(Iop_And32, 8855 mkexpr(t4), 8856 mkU32(0x00008000)), 8857 mkU8(16)) 8858 ), 8859 getDSPControl(), 8860 binop(Iop_Or32, 8861 getDSPControl(), 8862 mkU32(0x400000)))); 8863 putIReg(rd, binop(Iop_16HLto32, 8864 unop(Iop_32to16, mkexpr(t4)), 8865 unop(Iop_32to16, mkexpr(t0)))); 8866 } 8867 break; 8868 } 8869 case 0x9: { /* SHRA.PH */ 8870 DIP("shra.ph r%d, r%d, %d", rd, rt, rs); 8871 vassert(!mode64); 8872 t0 = newTemp(Ity_I32); 8873 t1 = newTemp(Ity_I32); 8874 if (0 == rs) { 8875 putIReg(rd, getIReg(rt)); 8876 } else { 8877 assign(t0, binop(Iop_Sar32, 8878 unop(Iop_16Sto32, 8879 unop(Iop_32to16, getIReg(rt))), 8880 mkU8(rs))); 8881 assign(t1, binop(Iop_Sar32, 8882 unop(Iop_16Sto32, 8883 unop(Iop_32HIto16, getIReg(rt))), 8884 mkU8(rs))); 8885 putIReg(rd, binop(Iop_16HLto32, 8886 unop(Iop_32to16, mkexpr(t1)), 8887 unop(Iop_32to16, mkexpr(t0)))); 8888 } 8889 break; 8890 } 8891 case 0xA: { /* SHLLV.PH */ 8892 DIP("shllv.ph r%d, r%d, r%d", rd, rt, rs); 8893 vassert(!mode64); 8894 t0 = newTemp(Ity_I32); 8895 t2 = newTemp(Ity_I32); 8896 t3 = newTemp(Ity_I1); 8897 t4 = newTemp(Ity_I1); 8898 t5 = newTemp(Ity_I32); 8899 t6 = newTemp(Ity_I32); 8900 t7 = newTemp(Ity_I1); 8901 t8 = newTemp(Ity_I1); 8902 t9 = newTemp(Ity_I32); 8903 t10 = newTemp(Ity_I32); 8904 t11 = newTemp(Ity_I32); 8905 t12 = newTemp(Ity_I1); 8906 t13 = newTemp(Ity_I1); 8907 8908 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f))); 8909 8910 /* Shift lower 16 bits. */ 8911 assign(t2, binop(Iop_Shl32, 8912 unop(Iop_16Sto32, 8913 unop(Iop_32to16, getIReg(rt))), 8914 unop(Iop_32to8, mkexpr(t0)))); 8915 8916 assign(t3, binop(Iop_CmpNE32, 8917 unop(Iop_16Sto32, 8918 unop(Iop_32HIto16, mkexpr(t2))), 8919 mkU32(0x00000000))); 8920 assign(t4, binop(Iop_CmpNE32, 8921 unop(Iop_16Sto32, 8922 unop(Iop_32HIto16, mkexpr(t2))), 8923 mkU32(0xffffffff))); 8924 assign(t10, binop(Iop_And32, 8925 unop(Iop_1Sto32, mkexpr(t3)), 8926 unop(Iop_1Sto32, mkexpr(t4)))); 8927 assign(t5, binop(Iop_Shr32, 8928 binop(Iop_And32, 8929 getIReg(rt), 8930 mkU32(0x00008000)), 8931 mkU8(15))); 8932 assign(t12, binop(Iop_CmpEQ32, 8933 mkexpr(t5), 8934 binop(Iop_Shr32, 8935 binop(Iop_And32, 8936 mkexpr(t2), 8937 mkU32(0x00008000)), 8938 mkU8(15)))); 8939 8940 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 8941 mkexpr(t10), 8942 mkU32(0x0)), 8943 binop(Iop_Or32, 8944 getDSPControl(), 8945 mkU32(0x400000)), 8946 IRExpr_ITE(mkexpr(t12), 8947 getDSPControl(), 8948 binop(Iop_Or32, 8949 getDSPControl(), 8950 mkU32(0x400000))) 8951 )); 8952 /* Shift higher 16 bits. */ 8953 assign(t6, binop(Iop_Shl32, 8954 unop(Iop_16Sto32, 8955 unop(Iop_32HIto16, getIReg(rt))), 8956 unop(Iop_32to8, mkexpr(t0)))); 8957 8958 assign(t7, binop(Iop_CmpNE32, 8959 unop(Iop_16Sto32, 8960 unop(Iop_32HIto16, mkexpr(t6))), 8961 mkU32(0x00000000))); 8962 assign(t8, binop(Iop_CmpNE32, 8963 unop(Iop_16Sto32, 8964 unop(Iop_32HIto16, mkexpr(t6))), 8965 mkU32(0xffffffff))); 8966 assign(t11, binop(Iop_And32, 8967 unop(Iop_1Sto32, mkexpr(t7)), 8968 unop(Iop_1Sto32, mkexpr(t8)))); 8969 8970 assign(t9, binop(Iop_Shr32, 8971 binop(Iop_And32, 8972 getIReg(rt), 8973 mkU32(0x80000000)), 8974 mkU8(31))); 8975 assign(t13, binop(Iop_CmpEQ32, 8976 mkexpr(t9), 8977 binop(Iop_Shr32, 8978 binop(Iop_And32, 8979 mkexpr(t6), 8980 mkU32(0x00008000)), 8981 mkU8(15)))); 8982 8983 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 8984 mkexpr(t11), 8985 mkU32(0x0)), 8986 binop(Iop_Or32, 8987 getDSPControl(), 8988 mkU32(0x400000)), 8989 IRExpr_ITE(mkexpr(t13), 8990 getDSPControl(), 8991 binop(Iop_Or32, 8992 getDSPControl(), 8993 mkU32(0x400000))) 8994 )); 8995 8996 putIReg(rd, binop(Iop_16HLto32, 8997 unop(Iop_32to16, mkexpr(t6)), 8998 unop(Iop_32to16, mkexpr(t2)))); 8999 break; 9000 } 9001 case 0xB: { /* SHRAV.PH */ 9002 DIP("shrav.ph r%d, r%d, r%d", rd, rt, rs); 9003 vassert(!mode64); 9004 t0 = newTemp(Ity_I32); 9005 t1 = newTemp(Ity_I1); 9006 t2 = newTemp(Ity_I32); 9007 t3 = newTemp(Ity_I32); 9008 9009 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f))); 9010 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0))); 9011 assign(t2, binop(Iop_Sar32, 9012 unop(Iop_16Sto32, 9013 unop(Iop_32to16, getIReg(rt))), 9014 unop(Iop_32to8, mkexpr(t0)))); 9015 assign(t3, binop(Iop_Sar32, 9016 unop(Iop_16Sto32, 9017 unop(Iop_32HIto16, getIReg(rt))), 9018 unop(Iop_32to8, mkexpr(t0)))); 9019 putIReg(rd, 9020 binop(Iop_16HLto32, 9021 IRExpr_ITE(mkexpr(t1), 9022 unop(Iop_32HIto16, getIReg(rt)), 9023 unop(Iop_32to16, mkexpr(t3))), 9024 IRExpr_ITE(mkexpr(t1), 9025 unop(Iop_32to16, getIReg(rt)), 9026 unop(Iop_32to16, mkexpr(t2))))); 9027 break; 9028 } 9029 case 0xC: { /* SHLL_S.PH */ 9030 DIP("shll_s.ph r%d, r%d, %d", rd, rt, rs); 9031 vassert(!mode64); 9032 t0 = newTemp(Ity_I32); 9033 t1 = newTemp(Ity_I32); 9034 t2 = newTemp(Ity_I32); 9035 t3 = newTemp(Ity_I32); 9036 t4 = newTemp(Ity_I32); 9037 t5 = newTemp(Ity_I32); 9038 t6 = newTemp(Ity_I32); 9039 t7 = newTemp(Ity_I32); 9040 t8 = newTemp(Ity_I32); 9041 t9 = newTemp(Ity_I32); 9042 t10 = newTemp(Ity_I32); 9043 t11 = newTemp(Ity_I32); 9044 t12 = newTemp(Ity_I32); 9045 t13 = newTemp(Ity_I32); 9046 t14 = newTemp(Ity_I32); 9047 9048 if (0 == rs) { 9049 putIReg(rd, getIReg(rt)); 9050 } else { 9051 /* Shift lower 16 bits. */ 9052 assign(t0, binop(Iop_Shl32, 9053 unop(Iop_16Sto32, 9054 unop(Iop_32to16, getIReg(rt))), 9055 mkU8(rs))); 9056 9057 assign(t1, unop(Iop_1Uto32, 9058 binop(Iop_CmpNE32, 9059 binop(Iop_Sar32, 9060 mkexpr(t0), 9061 mkU8(16)), 9062 mkU32(0)))); 9063 assign(t2, unop(Iop_1Uto32, 9064 binop(Iop_CmpNE32, 9065 binop(Iop_Sar32, 9066 mkexpr(t0), 9067 mkU8(16)), 9068 mkU32(0xffffffff)))); 9069 assign(t3, binop(Iop_And32, 9070 mkexpr(t1), 9071 mkexpr(t2))); 9072 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 9073 mkexpr(t3), 9074 mkU32(0x1)), 9075 binop(Iop_Or32, 9076 getDSPControl(), 9077 mkU32(0x400000)), 9078 getDSPControl())); 9079 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 9080 binop(Iop_And32, 9081 getIReg(rt), 9082 mkU32(0x00008000)), 9083 binop(Iop_And32, 9084 mkexpr(t0), 9085 mkU32(0x00008000)) 9086 ), 9087 getDSPControl(), 9088 binop(Iop_Or32, 9089 getDSPControl(), 9090 mkU32(0x400000)))); 9091 assign(t8, 9092 IRExpr_ITE(binop(Iop_CmpEQ32, 9093 mkexpr(t3), 9094 mkU32(0x1)), 9095 IRExpr_ITE(binop(Iop_CmpEQ32, 9096 binop(Iop_And32, 9097 getIReg(rt), 9098 mkU32(0x8000)), 9099 mkU32(0)), 9100 mkU32(0x00007fff), 9101 mkU32(0x00008000)), 9102 binop(Iop_And32, 9103 mkexpr(t0), 9104 mkU32(0x0000ffff)))); 9105 assign(t10, 9106 IRExpr_ITE(binop(Iop_CmpEQ32, 9107 binop(Iop_And32, 9108 getIReg(rt), 9109 mkU32(0x00008000)), 9110 binop(Iop_And32, 9111 mkexpr(t0), 9112 mkU32(0x00008000))), 9113 mkexpr(t8), 9114 IRExpr_ITE(binop(Iop_CmpEQ32, 9115 binop(Iop_And32, 9116 getIReg(rt), 9117 mkU32(0x8000)), 9118 mkU32(0)), 9119 mkU32(0x00007fff), 9120 mkU32(0x00008000)))); 9121 /* Shift higher 16 bits. */ 9122 assign(t4, binop(Iop_Shl32, 9123 unop(Iop_16Sto32, 9124 unop(Iop_32HIto16, getIReg(rt))), 9125 mkU8(rs))); 9126 9127 assign(t5, unop(Iop_1Uto32, 9128 binop(Iop_CmpNE32, 9129 binop(Iop_Sar32, 9130 mkexpr(t4), 9131 mkU8(16)), 9132 mkU32(0)))); 9133 assign(t6, unop(Iop_1Uto32, 9134 binop(Iop_CmpNE32, 9135 binop(Iop_Sar32, 9136 mkexpr(t4), 9137 mkU8(16)), 9138 mkU32(0xffffffff)))); 9139 assign(t7, binop(Iop_And32, 9140 mkexpr(t5), 9141 mkexpr(t6))); 9142 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 9143 mkexpr(t7), 9144 mkU32(0x1)), 9145 binop(Iop_Or32, 9146 getDSPControl(), 9147 mkU32(0x400000)), 9148 getDSPControl())); 9149 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 9150 mkexpr(t7), 9151 mkU32(0x1)), 9152 binop(Iop_Or32, 9153 getDSPControl(), 9154 mkU32(0x400000)), 9155 getDSPControl())); 9156 assign(t12, binop(Iop_Shl32, 9157 binop(Iop_And32, 9158 mkexpr(t4), 9159 mkU32(0x8000)), 9160 mkU8(16))); 9161 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 9162 binop(Iop_And32, 9163 getIReg(rt), 9164 mkU32(0x80000000)), 9165 mkexpr(t12)), 9166 getDSPControl(), 9167 binop(Iop_Or32, 9168 getDSPControl(), 9169 mkU32(0x400000)))); 9170 assign(t13, IRExpr_ITE(binop(Iop_CmpEQ32, 9171 binop(Iop_And32, 9172 getIReg(rt), 9173 mkU32(0x80000000)), 9174 mkU32(0)), 9175 mkU32(0x7fff0000), 9176 mkU32(0x80000000))); 9177 assign(t9, 9178 IRExpr_ITE(binop(Iop_CmpEQ32, 9179 mkexpr(t7), 9180 mkU32(0x1)), 9181 mkexpr(t13), 9182 binop(Iop_Shl32, 9183 binop(Iop_And32, 9184 mkexpr(t4), 9185 mkU32(0x0000ffff)), 9186 mkU8(16)))); 9187 assign(t14, IRExpr_ITE(binop(Iop_CmpEQ32, 9188 binop(Iop_And32, 9189 getIReg(rt), 9190 mkU32(0x80000000)), 9191 mkU32(0)), 9192 mkU32(0x7fff0000), 9193 mkU32(0x80000000))); 9194 assign(t11, 9195 IRExpr_ITE(binop(Iop_CmpEQ32, 9196 binop(Iop_And32, 9197 getIReg(rt), 9198 mkU32(0x80000000)), 9199 binop(Iop_Shl32, 9200 binop(Iop_And32, 9201 mkexpr(t4), 9202 mkU32(0x00008000)), 9203 mkU8(16))), 9204 mkexpr(t9), 9205 mkexpr(t14))); 9206 putIReg(rd, binop(Iop_Or32, 9207 mkexpr(t10), 9208 mkexpr(t11))); 9209 } 9210 break; 9211 } 9212 case 0xD: { /* SHRA_R.PH */ 9213 DIP("shra.ph r%d, r%d, %d", rd, rt, rs); 9214 vassert(!mode64); 9215 t0 = newTemp(Ity_I32); 9216 t1 = newTemp(Ity_I32); 9217 if (0 == rs) { 9218 putIReg(rd, getIReg(rt)); 9219 } else { 9220 assign(t0, binop(Iop_Sar32, 9221 binop(Iop_Add32, 9222 unop(Iop_16Sto32, 9223 unop(Iop_32to16, 9224 getIReg(rt))), 9225 binop(Iop_Shl32, 9226 mkU32(0x1), 9227 mkU8(rs-1))), 9228 mkU8(rs))); 9229 assign(t1, binop(Iop_Sar32, 9230 binop(Iop_Add32, 9231 unop(Iop_16Sto32, 9232 unop(Iop_32HIto16, 9233 getIReg(rt))), 9234 binop(Iop_Shl32, 9235 mkU32(0x1), 9236 mkU8(rs-1))), 9237 mkU8(rs))); 9238 putIReg(rd, binop(Iop_16HLto32, 9239 unop(Iop_32to16, mkexpr(t1)), 9240 unop(Iop_32to16, mkexpr(t0)))); 9241 } 9242 break; 9243 } 9244 case 0xE: { /* SHLLV_S.PH */ 9245 DIP("shllv_s.ph r%d, r%d, r%d", rd, rt, rs); 9246 vassert(!mode64); 9247 t0 = newTemp(Ity_I32); 9248 t2 = newTemp(Ity_I32); 9249 t3 = newTemp(Ity_I1); 9250 t4 = newTemp(Ity_I1); 9251 t5 = newTemp(Ity_I32); 9252 t6 = newTemp(Ity_I32); 9253 t7 = newTemp(Ity_I1); 9254 t8 = newTemp(Ity_I1); 9255 t9 = newTemp(Ity_I32); 9256 t10 = newTemp(Ity_I32); 9257 t11 = newTemp(Ity_I32); 9258 t12 = newTemp(Ity_I1); 9259 t13 = newTemp(Ity_I1); 9260 t14 = newTemp(Ity_I16); 9261 t15 = newTemp(Ity_I16); 9262 t16 = newTemp(Ity_I16); 9263 t17 = newTemp(Ity_I16); 9264 9265 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f))); 9266 9267 /* Shift lower 16 bits. */ 9268 assign(t2, binop(Iop_Shl32, 9269 unop(Iop_16Sto32, 9270 unop(Iop_32to16, getIReg(rt))), 9271 unop(Iop_32to8, mkexpr(t0)))); 9272 9273 assign(t3, binop(Iop_CmpNE32, 9274 unop(Iop_16Sto32, 9275 unop(Iop_32HIto16, mkexpr(t2))), 9276 mkU32(0x00000000))); 9277 assign(t4, binop(Iop_CmpNE32, 9278 unop(Iop_16Sto32, 9279 unop(Iop_32HIto16, mkexpr(t2))), 9280 mkU32(0xffffffff))); 9281 assign(t10, binop(Iop_And32, 9282 unop(Iop_1Sto32, mkexpr(t3)), 9283 unop(Iop_1Sto32, mkexpr(t4)))); 9284 assign(t5, binop(Iop_Shr32, 9285 binop(Iop_And32, 9286 getIReg(rt), 9287 mkU32(0x00008000)), 9288 mkU8(15))); 9289 assign(t12, binop(Iop_CmpEQ32, 9290 mkexpr(t5), 9291 binop(Iop_Shr32, 9292 binop(Iop_And32, 9293 mkexpr(t2), 9294 mkU32(0x00008000)), 9295 mkU8(15)))); 9296 9297 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 9298 mkexpr(t10), 9299 mkU32(0x0)), 9300 binop(Iop_Or32, 9301 getDSPControl(), 9302 mkU32(0x400000)), 9303 IRExpr_ITE(mkexpr(t12), 9304 getDSPControl(), 9305 binop(Iop_Or32, 9306 getDSPControl(), 9307 mkU32(0x400000))) 9308 )); 9309 assign(t14, IRExpr_ITE(binop(Iop_CmpNE32, 9310 mkexpr(t5), 9311 mkU32(0x0)), 9312 mkU16(0x8000), 9313 mkU16(0x7fff))); 9314 assign(t15, IRExpr_ITE(binop(Iop_CmpNE32, 9315 mkexpr(t10), 9316 mkU32(0x0)), 9317 mkexpr(t14), 9318 IRExpr_ITE(mkexpr(t12), 9319 unop(Iop_32to16, 9320 mkexpr(t2)), 9321 mkexpr(t14)))); 9322 /* Shift higher 16 bits. */ 9323 assign(t6, binop(Iop_Shl32, 9324 unop(Iop_16Sto32, 9325 unop(Iop_32HIto16, getIReg(rt))), 9326 unop(Iop_32to8, mkexpr(t0)))); 9327 9328 assign(t7, binop(Iop_CmpNE32, 9329 unop(Iop_16Sto32, 9330 unop(Iop_32HIto16, mkexpr(t6))), 9331 mkU32(0x00000000))); 9332 assign(t8, binop(Iop_CmpNE32, 9333 unop(Iop_16Sto32, 9334 unop(Iop_32HIto16, mkexpr(t6))), 9335 mkU32(0xffffffff))); 9336 assign(t11, binop(Iop_And32, 9337 unop(Iop_1Sto32, mkexpr(t7)), 9338 unop(Iop_1Sto32, mkexpr(t8)))); 9339 9340 assign(t9, binop(Iop_Shr32, 9341 binop(Iop_And32, 9342 getIReg(rt), 9343 mkU32(0x80000000)), 9344 mkU8(31))); 9345 assign(t13, binop(Iop_CmpEQ32, 9346 mkexpr(t9), 9347 binop(Iop_Shr32, 9348 binop(Iop_And32, 9349 mkexpr(t6), 9350 mkU32(0x00008000)), 9351 mkU8(15)))); 9352 9353 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 9354 mkexpr(t11), 9355 mkU32(0x0)), 9356 binop(Iop_Or32, 9357 getDSPControl(), 9358 mkU32(0x400000)), 9359 IRExpr_ITE(mkexpr(t13), 9360 getDSPControl(), 9361 binop(Iop_Or32, 9362 getDSPControl(), 9363 mkU32(0x400000))) 9364 )); 9365 9366 assign(t16, IRExpr_ITE(binop(Iop_CmpNE32, 9367 mkexpr(t9), 9368 mkU32(0x0)), 9369 mkU16(0x8000), 9370 mkU16(0x7fff))); 9371 assign(t17, IRExpr_ITE(binop(Iop_CmpNE32, 9372 mkexpr(t11), 9373 mkU32(0x0)), 9374 mkexpr(t16), 9375 IRExpr_ITE(mkexpr(t13), 9376 unop(Iop_32to16, 9377 mkexpr(t6)), 9378 mkexpr(t16)))); 9379 9380 putIReg(rd, binop(Iop_16HLto32, mkexpr(t17), mkexpr(t15))); 9381 break; 9382 } 9383 case 0xF: { /* SHRAV_R.PH */ 9384 DIP("shrav_r.ph r%d, r%d, r%d", rd, rt, rs); 9385 vassert(!mode64); 9386 t0 = newTemp(Ity_I32); 9387 t1 = newTemp(Ity_I1); 9388 t2 = newTemp(Ity_I8); 9389 t3 = newTemp(Ity_I32); 9390 t4 = newTemp(Ity_I32); 9391 9392 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f))); 9393 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0))); 9394 assign(t2, unop(Iop_32to8, 9395 binop(Iop_Sub32, mkexpr(t0), mkU32(1)))); 9396 9397 assign(t3, binop(Iop_Sar32, 9398 binop(Iop_Add32, 9399 unop(Iop_16Sto32, 9400 unop(Iop_32to16, getIReg(rt))), 9401 binop(Iop_Shl32, 9402 mkU32(0x1), 9403 mkexpr(t2))), 9404 unop(Iop_32to8, mkexpr(t0)))); 9405 assign(t4, binop(Iop_Sar32, 9406 binop(Iop_Add32, 9407 unop(Iop_16Sto32, 9408 unop(Iop_32HIto16, 9409 getIReg(rt))), 9410 binop(Iop_Shl32, 9411 mkU32(0x1), 9412 mkexpr(t2))), 9413 unop(Iop_32to8, mkexpr(t0)))); 9414 9415 putIReg(rd, binop(Iop_16HLto32, 9416 IRExpr_ITE(mkexpr(t1), 9417 unop(Iop_32HIto16, 9418 getIReg(rt)), 9419 unop(Iop_32to16, 9420 mkexpr(t4))), 9421 IRExpr_ITE(mkexpr(t1), 9422 unop(Iop_32to16, getIReg(rt)), 9423 unop(Iop_32to16, 9424 mkexpr(t3))))); 9425 break; 9426 } 9427 case 0x14: { /* SHLL_S.W */ 9428 DIP("shll_s.w r%d, r%d, %d", rd, rt, rs); 9429 vassert(!mode64); 9430 t0 = newTemp(Ity_I32); 9431 t1 = newTemp(Ity_I32); 9432 t2 = newTemp(Ity_I32); 9433 t3 = newTemp(Ity_I32); 9434 t4 = newTemp(Ity_I32); 9435 t5 = newTemp(Ity_I32); 9436 9437 if (0 == rs) { 9438 putIReg(rd, getIReg(rt)); 9439 } else { 9440 /* t0-bits that will be discarded, sign extended to 9441 32bits. */ 9442 assign(t0, binop(Iop_Sar32, 9443 binop(Iop_And32, 9444 getIReg(rt), 9445 binop(Iop_Sar32, 9446 mkU32(0x80000000), 9447 mkU8(rs-1))), 9448 mkU8(32-rs))); 9449 9450 assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32, 9451 binop(Iop_And32, 9452 getIReg(rt), 9453 mkU32(0x80000000)), 9454 mkU32(0x0)), 9455 mkU32(0x7fffffff), 9456 mkU32(0x80000000))); 9457 9458 assign(t2, binop(Iop_Shl32, getIReg(rt), mkU8(rs))); 9459 assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32, 9460 binop(Iop_And32, 9461 getIReg(rt), 9462 mkU32(0x80000000)), 9463 binop(Iop_And32, 9464 mkexpr(t2), 9465 mkU32(0x80000000))), 9466 mkexpr(t2), 9467 mkexpr(t1))); 9468 9469 assign(t4, IRExpr_ITE(binop(Iop_CmpNE32, 9470 mkexpr(t0), 9471 mkU32(0x0)), 9472 IRExpr_ITE(binop(Iop_CmpNE32, 9473 mkexpr(t0), 9474 mkU32(0xffffffff) 9475 ), 9476 mkexpr(t1), 9477 mkexpr(t3)), 9478 mkexpr(t3))); 9479 assign(t5, IRExpr_ITE(binop(Iop_CmpNE32, 9480 mkexpr(t0), 9481 mkU32(0xffffffff)), 9482 binop(Iop_Or32, 9483 getDSPControl(), 9484 mkU32(0x400000)), 9485 getDSPControl())); 9486 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 9487 mkexpr(t0), 9488 mkU32(0x0)), 9489 mkexpr(t5), 9490 getDSPControl())); 9491 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 9492 binop(Iop_And32, 9493 getIReg(rt), 9494 mkU32(0x80000000)), 9495 binop(Iop_And32, 9496 mkexpr(t2), 9497 mkU32(0x80000000)) 9498 ), 9499 getDSPControl(), 9500 binop(Iop_Or32, 9501 getDSPControl(), 9502 mkU32(0x400000)))); 9503 putIReg(rd, mkexpr(t4)); 9504 } 9505 break; 9506 } 9507 case 0x15: { /* SHRA_R.W */ 9508 DIP("shra_r.w r%d, r%d, %d", rd, rt, rs); 9509 vassert(!mode64); 9510 if (0 == rs) { 9511 putIReg(rd, getIReg(rt)); 9512 } else { 9513 putIReg(rd, binop(Iop_Add32, 9514 binop(Iop_Sar32, 9515 getIReg(rt), mkU8(rs)), 9516 binop(Iop_Shr32, 9517 binop(Iop_And32, 9518 getIReg(rt), 9519 binop(Iop_Shl32, 9520 mkU32(0x1), 9521 mkU8(rs-1))), 9522 mkU8(rs-1)))); 9523 } 9524 break; 9525 } 9526 case 0x16: { /* SHLLV_S.W */ 9527 DIP("shllv_s.w r%d, r%d, r%d", rd, rt, rs); 9528 vassert(!mode64); 9529 t0 = newTemp(Ity_I32); 9530 t1 = newTemp(Ity_I1); 9531 t2 = newTemp(Ity_I32); 9532 t3 = newTemp(Ity_I64); 9533 t4 = newTemp(Ity_I1); 9534 t5 = newTemp(Ity_I1); 9535 t6 = newTemp(Ity_I32); 9536 t7 = newTemp(Ity_I1); 9537 t8 = newTemp(Ity_I32); 9538 9539 /* Check if shift amount is zero. */ 9540 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f))); 9541 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0))); 9542 9543 /* t2 = sign of the input value. */ 9544 assign(t2, binop(Iop_Shr32, 9545 binop(Iop_And32, 9546 getIReg(rt), 9547 mkU32(0x80000000)), 9548 mkU8(31))); 9549 /* Shift left input value and check for overflow. */ 9550 assign(t3, binop(Iop_Shl64, 9551 unop(Iop_32Sto64, getIReg(rt)), 9552 unop(Iop_32to8, mkexpr(t0)))); 9553 assign(t4, binop(Iop_CmpNE32, 9554 unop(Iop_64HIto32, mkexpr(t3)), 9555 mkU32(0x00000000))); 9556 assign(t5, binop(Iop_CmpNE32, 9557 unop(Iop_64HIto32, mkexpr(t3)), 9558 mkU32(0xffffffff))); 9559 assign(t6, binop(Iop_And32, 9560 unop(Iop_1Uto32, mkexpr(t4)), 9561 unop(Iop_1Uto32, mkexpr(t5)))); 9562 assign(t7, binop(Iop_CmpEQ32, 9563 binop(Iop_Shr32, 9564 binop(Iop_And32, 9565 getIReg(rt), 9566 mkU32(0x80000000)), 9567 mkU8(31)), 9568 binop(Iop_Shr32, 9569 binop(Iop_And32, 9570 unop(Iop_64to32, mkexpr(t3)), 9571 mkU32(0x80000000)), 9572 mkU8(31)))); 9573 9574 putDSPControl(IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)), 9575 binop(Iop_Or32, 9576 getDSPControl(), 9577 mkU32(0x400000)), 9578 IRExpr_ITE(mkexpr(t7), 9579 getDSPControl(), 9580 binop(Iop_Or32, 9581 getDSPControl(), 9582 mkU32(0x400000))) 9583 )); 9584 9585 assign(t8, IRExpr_ITE(unop(Iop_32to1, 9586 mkexpr(t2)), 9587 mkU32(0x80000000), 9588 mkU32(0x7fffffff))); 9589 putIReg(rd, IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)), 9590 IRExpr_ITE(unop(Iop_32to1, 9591 mkexpr(t2)), 9592 mkU32(0x80000000), 9593 mkU32(0x7fffffff)), 9594 IRExpr_ITE(mkexpr(t7), 9595 unop(Iop_64to32, 9596 mkexpr(t3)), 9597 mkexpr(t8)))); 9598 break; 9599 } 9600 case 0x17: { /* SHRAV_R.W */ 9601 DIP("shrav_r.w r%d, r%d, r%d", rd, rt, rs); 9602 vassert(!mode64); 9603 t0 = newTemp(Ity_I32); 9604 t1 = newTemp(Ity_I1); 9605 t2 = newTemp(Ity_I8); 9606 t3 = newTemp(Ity_I32); 9607 9608 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f))); 9609 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0))); 9610 assign(t2, unop(Iop_32to8, 9611 binop(Iop_Sub32, mkexpr(t0), mkU32(1)))); 9612 9613 putIReg(rd, IRExpr_ITE(mkexpr(t1), 9614 getIReg(rt), 9615 binop(Iop_Sar32, 9616 binop(Iop_Add32, 9617 binop(Iop_Sar32, 9618 getIReg(rt), 9619 mkexpr(t2)), 9620 mkU32(0x1)), 9621 mkU8(1)))); 9622 break; 9623 } 9624 case 0x19: { /* SHRL.PH */ 9625 DIP("shrl.ph r%d, r%d, %d", rd, rt, rs); 9626 vassert(!mode64); 9627 t0 = newTemp(Ity_I32); 9628 t1 = newTemp(Ity_I32); 9629 assign(t0, binop(Iop_Shr32, 9630 unop(Iop_16Uto32, 9631 unop(Iop_32to16, getIReg(rt))), 9632 mkU8(rs))); 9633 assign(t1, binop(Iop_Shr32, 9634 unop(Iop_16Uto32, 9635 unop(Iop_32HIto16, getIReg(rt))), 9636 mkU8(rs))); 9637 putIReg(rd, binop(Iop_16HLto32, 9638 unop(Iop_32to16, mkexpr(t1)), 9639 unop(Iop_32to16, mkexpr(t0)))); 9640 break; 9641 } 9642 case 0x1B: { /* SHRLV.PH */ 9643 DIP("shrlv.ph r%d, r%d, r%d", rd, rt, rs); 9644 vassert(!mode64); 9645 t0 = newTemp(Ity_I32); 9646 t1 = newTemp(Ity_I1); 9647 t2 = newTemp(Ity_I32); 9648 t3 = newTemp(Ity_I32); 9649 t4 = newTemp(Ity_I16); 9650 t5 = newTemp(Ity_I16); 9651 9652 /* Get shift amount from lower 5 bits of rs 9653 and check if it is zero. */ 9654 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f))); 9655 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0))); 9656 9657 assign(t2, binop(Iop_Shr32, 9658 unop(Iop_16Uto32, 9659 unop(Iop_32to16, getIReg(rt))), 9660 unop(Iop_32to8, mkexpr(t0)))); 9661 assign(t3, binop(Iop_Shr32, 9662 unop(Iop_16Uto32, 9663 unop(Iop_32HIto16, getIReg(rt))), 9664 unop(Iop_32to8, mkexpr(t0)))); 9665 9666 assign(t4, IRExpr_ITE(mkexpr(t1), 9667 unop(Iop_32HIto16, getIReg(rt)), 9668 unop(Iop_32to16, mkexpr(t3)))); 9669 assign(t5, IRExpr_ITE(mkexpr(t1), 9670 unop(Iop_32to16, getIReg(rt)), 9671 unop(Iop_32to16, mkexpr(t2)))); 9672 putIReg(rd, binop(Iop_16HLto32, mkexpr(t4), mkexpr(t5))); 9673 break; 9674 } 9675 default: 9676 return -1; 9677 } 9678 break; /* end of SHLL.QB */ 9679 } 9680 case 0x18: { /* ADDUH.QB/MUL.PH */ 9681 switch(sa) { 9682 case 0x00: { /* ADDUH.QB */ 9683 DIP("adduh.qb r%d, r%d, r%d", rd, rs, rt); 9684 vassert(!mode64); 9685 t0 = newTemp(Ity_I32); 9686 9687 assign(t0, binop(Iop_HAdd8Ux4, getIReg(rs), getIReg(rt))); 9688 9689 putIReg(rd, mkexpr(t0)); 9690 break; 9691 } 9692 case 0x1: { /* SUBUH.QB */ 9693 DIP("subuh.qb r%d, r%d, r%d", rd, rs, rt); 9694 vassert(!mode64); 9695 t0 = newTemp(Ity_I32); 9696 9697 assign(t0, binop(Iop_HSub8Ux4, getIReg(rs), getIReg(rt))); 9698 9699 putIReg(rd, mkexpr(t0)); 9700 break; 9701 } 9702 case 0x02: { /* ADDUH_R.QB */ 9703 DIP("adduh_r.qb r%d, r%d, r%d", rd, rs, rt); 9704 vassert(!mode64); 9705 t0 = newTemp(Ity_I32); 9706 t1 = newTemp(Ity_I32); 9707 t2 = newTemp(Ity_I8); 9708 t3 = newTemp(Ity_I32); 9709 t4 = newTemp(Ity_I32); 9710 t5 = newTemp(Ity_I8); 9711 t6 = newTemp(Ity_I32); 9712 t7 = newTemp(Ity_I32); 9713 t8 = newTemp(Ity_I8); 9714 t9 = newTemp(Ity_I32); 9715 t10 = newTemp(Ity_I32); 9716 t11 = newTemp(Ity_I8); 9717 9718 /* Extract input bytes, add values, add 1 and half the 9719 result. */ 9720 assign(t0, unop(Iop_8Uto32, 9721 unop(Iop_16to8, 9722 unop(Iop_32to16, getIReg(rs))))); 9723 assign(t1, unop(Iop_8Uto32, 9724 unop(Iop_16to8, 9725 unop(Iop_32to16, getIReg(rt))))); 9726 assign(t2, unop(Iop_16to8, 9727 unop(Iop_32to16, 9728 binop(Iop_Shr32, 9729 binop(Iop_Add32, 9730 binop(Iop_Add32, 9731 mkexpr(t0), 9732 mkexpr(t1)), 9733 mkU32(0x00000001)), 9734 mkU8(0x01))))); 9735 9736 assign(t3, unop(Iop_8Uto32, 9737 unop(Iop_16HIto8, 9738 unop(Iop_32to16, getIReg(rs))))); 9739 assign(t4, unop(Iop_8Uto32, 9740 unop(Iop_16HIto8, 9741 unop(Iop_32to16, getIReg(rt))))); 9742 assign(t5, unop(Iop_16to8, 9743 unop(Iop_32to16, 9744 binop(Iop_Shr32, 9745 binop(Iop_Add32, 9746 binop(Iop_Add32, 9747 mkexpr(t3), 9748 mkexpr(t4)), 9749 mkU32(0x00000001)), 9750 mkU8(0x01))))); 9751 9752 assign(t6, unop(Iop_8Uto32, 9753 unop(Iop_16to8, 9754 unop(Iop_32HIto16, getIReg(rs))))); 9755 assign(t7, unop(Iop_8Uto32, 9756 unop(Iop_16to8, 9757 unop(Iop_32HIto16, getIReg(rt))))); 9758 assign(t8, unop(Iop_16to8, 9759 unop(Iop_32to16, 9760 binop(Iop_Shr32, 9761 binop(Iop_Add32, 9762 binop(Iop_Add32, 9763 mkexpr(t7), 9764 mkexpr(t6)), 9765 mkU32(0x00000001)), 9766 mkU8(0x01))))); 9767 9768 assign(t9, unop(Iop_8Uto32, 9769 unop(Iop_16HIto8, 9770 unop(Iop_32HIto16, getIReg(rs))))); 9771 assign(t10, unop(Iop_8Uto32, 9772 unop(Iop_16HIto8, 9773 unop(Iop_32HIto16, getIReg(rt))))); 9774 assign(t11, unop(Iop_16to8, 9775 unop(Iop_32to16, 9776 binop(Iop_Shr32, 9777 binop(Iop_Add32, 9778 binop(Iop_Add32, 9779 mkexpr(t9), 9780 mkexpr(t10)), 9781 mkU32(0x00000001)), 9782 mkU8(0x01))))); 9783 9784 putIReg(rd, binop(Iop_16HLto32, 9785 binop(Iop_8HLto16, 9786 mkexpr(t11), mkexpr(t8)), 9787 binop(Iop_8HLto16, 9788 mkexpr(t5), mkexpr(t2)))); 9789 break; 9790 } 9791 case 0x3: { /* SUBUH_R.QB */ 9792 DIP("subuh_r.qb r%d, r%d, r%d", rd, rs, rt); 9793 vassert(!mode64); 9794 t1 = newTemp(Ity_I32); 9795 t2 = newTemp(Ity_I32); 9796 t3 = newTemp(Ity_I32); 9797 t4 = newTemp(Ity_I32); 9798 t5 = newTemp(Ity_I32); 9799 t6 = newTemp(Ity_I32); 9800 t7 = newTemp(Ity_I32); 9801 t8 = newTemp(Ity_I32); 9802 t9 = newTemp(Ity_I8); 9803 t10 = newTemp(Ity_I8); 9804 t11 = newTemp(Ity_I8); 9805 t12 = newTemp(Ity_I8); 9806 9807 /* Extract each byte of rs and rt. */ 9808 assign(t1, unop(Iop_8Uto32, 9809 unop(Iop_16to8, 9810 unop(Iop_32to16, getIReg(rs))))); 9811 assign(t2, unop(Iop_8Uto32, 9812 unop(Iop_16HIto8, 9813 unop(Iop_32to16, getIReg(rs))))); 9814 assign(t3, unop(Iop_8Uto32, 9815 unop(Iop_16to8, 9816 unop(Iop_32HIto16, getIReg(rs))))); 9817 assign(t4, unop(Iop_8Uto32, 9818 unop(Iop_16HIto8, 9819 unop(Iop_32HIto16, getIReg(rs))))); 9820 9821 assign(t5, unop(Iop_8Uto32, 9822 unop(Iop_16to8, 9823 unop(Iop_32to16, getIReg(rt))))); 9824 assign(t6, unop(Iop_8Uto32, 9825 unop(Iop_16HIto8, 9826 unop(Iop_32to16, getIReg(rt))))); 9827 assign(t7, unop(Iop_8Uto32, 9828 unop(Iop_16to8, 9829 unop(Iop_32HIto16, getIReg(rt))))); 9830 assign(t8, unop(Iop_8Uto32, 9831 unop(Iop_16HIto8, 9832 unop(Iop_32HIto16, getIReg(rt))))); 9833 9834 /* Add 1 to each resulting byte and half the results. */ 9835 assign(t9, unop(Iop_16to8, 9836 unop(Iop_32to16, 9837 binop(Iop_Shr32, 9838 binop(Iop_Add32, 9839 binop(Iop_Sub32, 9840 mkexpr(t1), 9841 mkexpr(t5)), 9842 mkU32(0x00000001)), 9843 mkU8(0x01))))); 9844 assign(t10, unop(Iop_16to8, 9845 unop(Iop_32to16, 9846 binop(Iop_Shr32, 9847 binop(Iop_Add32, 9848 binop(Iop_Sub32, 9849 mkexpr(t2), 9850 mkexpr(t6)), 9851 mkU32(0x00000001)), 9852 mkU8(0x01))))); 9853 assign(t11, unop(Iop_16to8, 9854 unop(Iop_32to16, 9855 binop(Iop_Shr32, 9856 binop(Iop_Add32, 9857 binop(Iop_Sub32, 9858 mkexpr(t3), 9859 mkexpr(t7)), 9860 mkU32(0x00000001)), 9861 mkU8(0x01))))); 9862 assign(t12, unop(Iop_16to8, 9863 unop(Iop_32to16, 9864 binop(Iop_Shr32, 9865 binop(Iop_Add32, 9866 binop(Iop_Sub32, 9867 mkexpr(t4), 9868 mkexpr(t8)), 9869 mkU32(0x00000001)), 9870 mkU8(0x01))))); 9871 9872 putIReg(rd, binop(Iop_16HLto32, 9873 binop(Iop_8HLto16, 9874 mkexpr(t12), mkexpr(t11)), 9875 binop(Iop_8HLto16, 9876 mkexpr(t10), mkexpr(t9)))); 9877 break; 9878 } 9879 case 0x8: { /* ADDQH.PH */ 9880 DIP("addqh.ph r%d, r%d, r%d", rd, rs, rt); 9881 vassert(!mode64); 9882 t0 = newTemp(Ity_I32); 9883 t1 = newTemp(Ity_I16); 9884 t2 = newTemp(Ity_I32); 9885 t3 = newTemp(Ity_I16); 9886 9887 /* Add lower halfs of rs and rt 9888 and right shift the result by 1. */ 9889 assign(t0, binop(Iop_Add32, 9890 unop(Iop_16Sto32, 9891 unop(Iop_32to16, getIReg(rs))), 9892 unop(Iop_16Sto32, 9893 unop(Iop_32to16, getIReg(rt))))); 9894 assign(t1, unop(Iop_32to16, 9895 binop(Iop_Shr32, 9896 binop(Iop_And32, 9897 mkexpr(t0), 9898 mkU32(0x0001fffe)), 9899 mkU8(0x1)))); 9900 /* Add higher halfs of rs and rt 9901 and right shift the result by 1. */ 9902 assign(t2, binop(Iop_Add32, 9903 unop(Iop_16Sto32, 9904 unop(Iop_32HIto16, getIReg(rs))), 9905 unop(Iop_16Sto32, 9906 unop(Iop_32HIto16, getIReg(rt))))); 9907 assign(t3, unop(Iop_32to16, 9908 binop(Iop_Shr32, 9909 binop(Iop_And32, 9910 mkexpr(t2), 9911 mkU32(0x0001fffe)), 9912 mkU8(0x1)))); 9913 putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1))); 9914 break; 9915 } 9916 case 0x9: { /* SUBQH.PH */ 9917 DIP("subqh.ph r%d, r%d, r%d", rd, rs, rt); 9918 vassert(!mode64); 9919 9920 putIReg(rd, binop(Iop_HSub16Sx2, 9921 getIReg(rs), getIReg(rt))); 9922 break; 9923 } 9924 case 0xA: {/* ADDQH_R.PH */ 9925 DIP("addqh_r.ph r%d, r%d, r%d", rd, rs, rt); 9926 vassert(!mode64); 9927 t0 = newTemp(Ity_I32); 9928 t1 = newTemp(Ity_I16); 9929 t2 = newTemp(Ity_I32); 9930 t3 = newTemp(Ity_I16); 9931 9932 /* Add lower halfs of rs and rt, add 1 9933 and right shift the result by 1. */ 9934 assign(t0, binop(Iop_Add32, 9935 unop(Iop_16Sto32, 9936 unop(Iop_32to16, getIReg(rs))), 9937 unop(Iop_16Sto32, 9938 unop(Iop_32to16, getIReg(rt))))); 9939 assign(t1, unop(Iop_32to16, 9940 binop(Iop_Shr32, 9941 binop(Iop_And32, 9942 binop(Iop_Add32, 9943 mkexpr(t0), 9944 mkU32(0x1)), 9945 mkU32(0x0001fffe)), 9946 mkU8(0x1)))); 9947 /* Add higher halfs of rs and rt, add 1 9948 and right shift the result by 1. */ 9949 assign(t2, binop(Iop_Add32, 9950 unop(Iop_16Sto32, 9951 unop(Iop_32HIto16, getIReg(rs))), 9952 unop(Iop_16Sto32, 9953 unop(Iop_32HIto16, getIReg(rt))))); 9954 assign(t3, unop(Iop_32to16, 9955 binop(Iop_Shr32, 9956 binop(Iop_And32, 9957 binop(Iop_Add32, 9958 mkexpr(t2), 9959 mkU32(0x1)), 9960 mkU32(0x0001fffe)), 9961 mkU8(0x1)))); 9962 9963 putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1))); 9964 break; 9965 } 9966 case 0xB: { /* SUBQH_R.PH */ 9967 DIP("subqh_r.ph r%d, r%d, r%d", rd, rs, rt); 9968 vassert(!mode64); 9969 t0 = newTemp(Ity_I32); 9970 t1 = newTemp(Ity_I16); 9971 t2 = newTemp(Ity_I32); 9972 t3 = newTemp(Ity_I16); 9973 9974 /* Sub lower halfs of rs and rt, add 1 9975 and right shift the result by 1. */ 9976 assign(t0, binop(Iop_Sub32, 9977 unop(Iop_16Sto32, 9978 unop(Iop_32to16, getIReg(rs))), 9979 unop(Iop_16Sto32, 9980 unop(Iop_32to16, getIReg(rt))))); 9981 assign(t1, unop(Iop_32to16, 9982 binop(Iop_Shr32, 9983 binop(Iop_And32, 9984 binop(Iop_Add32, 9985 mkexpr(t0), 9986 mkU32(0x1)), 9987 mkU32(0x0001fffe)), 9988 mkU8(0x1)))); 9989 /* Sub higher halfs of rs and rt, add 1 9990 and right shift the result by 1. */ 9991 assign(t2, binop(Iop_Sub32, 9992 unop(Iop_16Sto32, 9993 unop(Iop_32HIto16, getIReg(rs))), 9994 unop(Iop_16Sto32, 9995 unop(Iop_32HIto16, getIReg(rt))))); 9996 assign(t3, unop(Iop_32to16, 9997 binop(Iop_Shr32, 9998 binop(Iop_And32, 9999 binop(Iop_Add32, 10000 mkexpr(t2), 10001 mkU32(0x1)), 10002 mkU32(0x0001fffe)), 10003 mkU8(0x1)))); 10004 10005 putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1))); 10006 break; 10007 } 10008 case 0xC: { /* MUL.PH */ 10009 DIP("mul.ph r%d, r%d, r%d", rd, rs, rt); 10010 vassert(!mode64); 10011 t0 = newTemp(Ity_I32); 10012 t1 = newTemp(Ity_I32); 10013 t2 = newTemp(Ity_I32); 10014 10015 assign(t0, 10016 binop(Iop_Mul32, 10017 unop(Iop_16Sto32, 10018 unop(Iop_32HIto16, getIReg(rs))), 10019 unop(Iop_16Sto32, 10020 unop(Iop_32HIto16, getIReg(rt))))); 10021 /* DSP Control flag. */ 10022 putDSPControl(IRExpr_ITE(unop(Iop_Not1, 10023 binop(Iop_CmpLE32S, 10024 mkexpr(t0), 10025 mkU32(0x7FFF))), 10026 binop(Iop_Or32, 10027 getDSPControl(), 10028 mkU32(0x00200000)), 10029 IRExpr_ITE(binop(Iop_CmpLT32S, 10030 mkexpr(t0), 10031 mkU32(0xFFFF8000) 10032 ), 10033 binop(Iop_Or32, 10034 getDSPControl(), 10035 mkU32(0x00200000) 10036 ), 10037 getDSPControl()))); 10038 10039 assign(t1, 10040 binop(Iop_Mul32, 10041 unop(Iop_16Sto32, 10042 unop(Iop_32to16, getIReg(rs))), 10043 unop(Iop_16Sto32, 10044 unop(Iop_32to16, getIReg(rt))))); 10045 /* DSP Control flag. */ 10046 putDSPControl(IRExpr_ITE(unop(Iop_Not1, 10047 binop(Iop_CmpLE32S, 10048 mkexpr(t1), 10049 mkU32(0x7FFF))), 10050 binop(Iop_Or32, 10051 getDSPControl(), 10052 mkU32(0x00200000)), 10053 IRExpr_ITE(binop(Iop_CmpLT32S, 10054 mkexpr(t1), 10055 mkU32(0xFFFF8000) 10056 ), 10057 binop(Iop_Or32, 10058 getDSPControl(), 10059 mkU32(0x00200000) 10060 ), 10061 getDSPControl()))); 10062 10063 assign(t2, binop(Iop_16HLto32, 10064 unop(Iop_32to16, mkexpr(t0)), 10065 unop(Iop_32to16, mkexpr(t1)))); 10066 putIReg(rd, mkexpr(t2)); 10067 break; 10068 } 10069 case 0xE: { /* MUL_S.PH */ 10070 DIP("mul_s.ph r%d r%d, r%d", rd, rs, rt); 10071 vassert(!mode64); 10072 10073 t0 = newTemp(Ity_I32); 10074 t1 = newTemp(Ity_I32); 10075 t2 = newTemp(Ity_I32); 10076 t3 = newTemp(Ity_I32); 10077 t4 = newTemp(Ity_I32); 10078 10079 /* t0 - signed intermediate result. */ 10080 assign(t0, 10081 binop(Iop_Mul32, 10082 unop(Iop_16Sto32, 10083 unop(Iop_32HIto16, getIReg(rs))), 10084 unop(Iop_16Sto32, 10085 unop(Iop_32HIto16, getIReg(rt))))); 10086 10087 assign(t1, 10088 IRExpr_ITE(unop(Iop_Not1, 10089 binop(Iop_CmpLE32S, 10090 mkexpr(t0), 10091 mkU32(0x7FFF))), 10092 mkU32(0x00007FFF), 10093 IRExpr_ITE(binop(Iop_CmpLT32S, 10094 mkexpr(t0), 10095 mkU32(0xFFFF8000)), 10096 mkU32(0xFFFF8000), 10097 mkexpr(t0)))); 10098 10099 /* DSP Control flag. */ 10100 putDSPControl(IRExpr_ITE(unop(Iop_Not1, 10101 binop(Iop_CmpLE32S, 10102 mkexpr(t0), 10103 mkU32(0x7FFF))), 10104 binop(Iop_Or32, 10105 getDSPControl(), 10106 mkU32(0x00200000)), 10107 IRExpr_ITE(binop(Iop_CmpLT32S, 10108 mkexpr(t0), 10109 mkU32(0xFFFF8000) 10110 ), 10111 binop(Iop_Or32, 10112 getDSPControl(), 10113 mkU32(0x00200000) 10114 ), 10115 getDSPControl()))); 10116 10117 /* t2 - signed intermediate result. */ 10118 assign(t2, binop(Iop_Mul32, 10119 unop(Iop_16Sto32, 10120 unop(Iop_32to16, getIReg(rs))), 10121 unop(Iop_16Sto32, 10122 unop(Iop_32to16, getIReg(rt))))); 10123 10124 assign(t3, IRExpr_ITE(unop(Iop_Not1, 10125 binop(Iop_CmpLE32S, 10126 mkexpr(t2), 10127 mkU32(0x7FFF))), 10128 mkU32(0x00007FFF), 10129 IRExpr_ITE(binop(Iop_CmpLT32S, 10130 mkexpr(t2), 10131 mkU32(0xFFFF8000)), 10132 mkU32(0xFFFF8000), 10133 mkexpr(t2)))); 10134 10135 /* DSP Control flag. */ 10136 putDSPControl(IRExpr_ITE(unop(Iop_Not1, 10137 binop(Iop_CmpLE32S, 10138 mkexpr(t2), 10139 mkU32(0x7FFF))), 10140 binop(Iop_Or32, 10141 getDSPControl(), 10142 mkU32(0x00200000)), 10143 IRExpr_ITE(binop(Iop_CmpLT32S, 10144 mkexpr(t2), 10145 mkU32(0xFFFF8000) 10146 ), 10147 binop(Iop_Or32, 10148 getDSPControl(), 10149 mkU32(0x00200000) 10150 ), 10151 getDSPControl()))); 10152 10153 assign(t4, binop(Iop_16HLto32, 10154 unop(Iop_32to16, mkexpr(t1)), 10155 unop(Iop_32to16, mkexpr(t3)))); 10156 putIReg(rd, mkexpr(t4)); 10157 break; 10158 } 10159 case 0x10: { /* ADDQH.W */ 10160 DIP("addqh.w r%d, r%d, r%d", rd, rs, rt); 10161 vassert(!mode64); 10162 t0 = newTemp(Ity_I64); 10163 t1 = newTemp(Ity_I64); 10164 10165 assign(t0, binop(Iop_Add64, 10166 unop(Iop_32Sto64, getIReg(rs)), 10167 unop(Iop_32Sto64, getIReg(rt)))); 10168 assign(t1, binop(Iop_And64, 10169 mkexpr(t0), 10170 mkU64(0x00000001fffffffeULL))); 10171 putIReg(rd, unop(Iop_64to32, 10172 binop(Iop_Shr64, mkexpr(t1), mkU8(0x1)))); 10173 break; 10174 } 10175 case 0x11: { /* SUBQH.W */ 10176 DIP("subqh.w r%d, r%d, r%d", rd, rs, rt); 10177 vassert(!mode64); 10178 t0 = newTemp(Ity_I64); 10179 t1 = newTemp(Ity_I64); 10180 10181 assign(t0, binop(Iop_Sub64, 10182 unop(Iop_32Sto64, getIReg(rs)), 10183 unop(Iop_32Sto64, getIReg(rt)))); 10184 assign(t1, binop(Iop_And64, 10185 mkexpr(t0), 10186 mkU64(0x00000001fffffffeULL))); 10187 putIReg(rd, unop(Iop_64to32, 10188 binop(Iop_Shr64, mkexpr(t1), mkU8(0x1)))); 10189 break; 10190 } 10191 case 0x12: { /* ADDQH_R.W */ 10192 DIP("addqh_r.w r%d, r%d, r%d", rd, rs, rt); 10193 vassert(!mode64); 10194 t0 = newTemp(Ity_I64); 10195 t1 = newTemp(Ity_I64); 10196 t2 = newTemp(Ity_I64); 10197 10198 assign(t0, binop(Iop_Add64, 10199 unop(Iop_32Sto64, getIReg(rs)), 10200 unop(Iop_32Sto64, getIReg(rt)))); 10201 assign(t1, binop(Iop_Add64, 10202 mkexpr(t0), 10203 mkU64(0x0000000000000001ULL))); 10204 assign(t2, binop(Iop_And64, 10205 mkexpr(t1), 10206 mkU64(0x00000001fffffffeULL))); 10207 putIReg(rd, unop(Iop_64to32, 10208 binop(Iop_Shr64, mkexpr(t2), mkU8(0x1)))); 10209 break; 10210 } 10211 case 0x13: { /* SUBQH_R.W */ 10212 DIP("subqh_r.w r%d, r%d, r%d", rd, rs, rt); 10213 vassert(!mode64); 10214 t0 = newTemp(Ity_I64); 10215 t1 = newTemp(Ity_I64); 10216 t2 = newTemp(Ity_I64); 10217 10218 assign(t0, binop(Iop_Sub64, 10219 unop(Iop_32Sto64, getIReg(rs)), 10220 unop(Iop_32Sto64, getIReg(rt)))); 10221 assign(t1, binop(Iop_Add64, 10222 mkexpr(t0), 10223 mkU64(0x0000000000000001ULL))); 10224 assign(t2, binop(Iop_And64, 10225 mkexpr(t1), 10226 mkU64(0x00000001fffffffeULL))); 10227 putIReg(rd, unop(Iop_64to32, 10228 binop(Iop_Shr64, mkexpr(t2), mkU8(0x1)))); 10229 break; 10230 } 10231 case 0x16: { /* MULQ_S.W */ 10232 DIP("mulq_s.w r%d, r%d, r%d", rd, rs, rt); 10233 vassert(!mode64); 10234 t0 = newTemp(Ity_I64); 10235 t1 = newTemp(Ity_I1); 10236 t2 = newTemp(Ity_I1); 10237 10238 assign(t0, binop(Iop_Shl64, 10239 binop(Iop_MullS32, 10240 getIReg(rt), getIReg(rs)), 10241 mkU8(0x1))); 10242 assign(t1, binop(Iop_CmpEQ32, 10243 getIReg(rt), mkU32(0x80000000))); 10244 assign(t2, binop(Iop_CmpEQ32, 10245 getIReg(rs), mkU32(0x80000000))); 10246 10247 putDSPControl(IRExpr_ITE(mkexpr(t1), 10248 IRExpr_ITE(mkexpr(t2), 10249 binop(Iop_Or32, 10250 getDSPControl(), 10251 mkU32(0x00200000) 10252 ), 10253 getDSPControl()), 10254 getDSPControl())); 10255 putIReg(rd, IRExpr_ITE(mkexpr(t1), 10256 IRExpr_ITE(mkexpr(t2), 10257 mkU32(0x7fffffff), 10258 unop(Iop_64HIto32, 10259 mkexpr(t0))), 10260 unop(Iop_64HIto32, mkexpr(t0)))); 10261 break; 10262 } 10263 case 0x17: { /* MULQ_RS.W */ 10264 DIP("mulq_rs.w r%d, r%d, r%d", rd, rs, rt); 10265 vassert(!mode64); 10266 t0 = newTemp(Ity_I64); 10267 t1 = newTemp(Ity_I1); 10268 t2 = newTemp(Ity_I1); 10269 10270 assign(t0, binop(Iop_Add64, 10271 binop(Iop_Shl64, 10272 binop(Iop_MullS32, 10273 getIReg(rt), 10274 getIReg(rs)), 10275 mkU8(0x1)), 10276 mkU64(0x0000000080000000ULL))); 10277 assign(t1, 10278 binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000))); 10279 assign(t2, 10280 binop(Iop_CmpEQ32, getIReg(rs), mkU32(0x80000000))); 10281 putDSPControl(IRExpr_ITE(mkexpr(t1), 10282 IRExpr_ITE(mkexpr(t2), 10283 binop(Iop_Or32, 10284 getDSPControl(), 10285 mkU32(0x00200000) 10286 ), 10287 getDSPControl()), 10288 getDSPControl())); 10289 putIReg(rd, IRExpr_ITE(mkexpr(t1), 10290 IRExpr_ITE(mkexpr(t2), 10291 mkU32(0x7fffffff), 10292 unop(Iop_64HIto32, 10293 mkexpr(t0))), 10294 unop(Iop_64HIto32, mkexpr(t0)))); 10295 break; 10296 } 10297 default: 10298 return -1; 10299 } 10300 break; /* end of ADDUH.QB/MUL.PH */ 10301 } 10302 case 0x30: { /* DPAQ.W.PH */ 10303 switch(sa) { 10304 case 0x0: { /* DPA.W.PH */ 10305 DIP("dpa.w.ph ac%d, r%d, r%d", ac, rs, rt); 10306 vassert(!mode64); 10307 10308 t0 = newTemp(Ity_I64); 10309 t1 = newTemp(Ity_I64); 10310 t2 = newTemp(Ity_I64); 10311 10312 assign(t0, 10313 unop(Iop_32Sto64, 10314 binop(Iop_Mul32, 10315 unop(Iop_16Sto32, 10316 unop(Iop_32HIto16, getIReg(rs))), 10317 unop(Iop_16Sto32, 10318 unop(Iop_32HIto16, getIReg(rt)))))); 10319 assign(t1, 10320 unop(Iop_32Sto64, 10321 binop(Iop_Mul32, 10322 unop(Iop_16Sto32, 10323 unop(Iop_32to16, getIReg(rs))), 10324 unop(Iop_16Sto32, 10325 unop(Iop_32to16, getIReg(rt)))))); 10326 assign(t2, 10327 binop(Iop_Add64, 10328 getAcc(ac), 10329 binop(Iop_Add64, mkexpr(t0), mkexpr(t1)))); 10330 putAcc(ac, mkexpr(t2)); 10331 break; 10332 } 10333 case 0x1: { /* DPS.W.PH */ 10334 DIP("dps.w.ph ac%d, r%d, r%d", ac, rs, rt); 10335 vassert(!mode64); 10336 10337 t0 = newTemp(Ity_I64); 10338 t1 = newTemp(Ity_I64); 10339 t2 = newTemp(Ity_I64); 10340 10341 assign(t0, 10342 unop(Iop_32Sto64, 10343 binop(Iop_Mul32, 10344 unop(Iop_16Sto32, 10345 unop(Iop_32HIto16, getIReg(rs))), 10346 unop(Iop_16Sto32, 10347 unop(Iop_32HIto16, getIReg(rt)))))); 10348 assign(t1, 10349 unop(Iop_32Sto64, 10350 binop(Iop_Mul32, 10351 unop(Iop_16Sto32, 10352 unop(Iop_32to16, getIReg(rs))), 10353 unop(Iop_16Sto32, 10354 unop(Iop_32to16, getIReg(rt)))))); 10355 assign(t2, 10356 binop(Iop_Sub64, 10357 getAcc(ac), 10358 binop(Iop_Add64, mkexpr(t0), mkexpr(t1)))); 10359 putAcc(ac, mkexpr(t2)); 10360 break; 10361 } 10362 case 0x2: { /* MULSA.W.PH */ 10363 DIP("mulsa.w.ph ac%d, r%d, r%d", ac, rs, rt); 10364 vassert(!mode64); 10365 t0 = newTemp(Ity_I32); 10366 t1 = newTemp(Ity_I32); 10367 t2 = newTemp(Ity_I32); 10368 t3 = newTemp(Ity_I1); 10369 t4 = newTemp(Ity_I64); 10370 10371 assign(t4, getAcc(ac)); 10372 assign(t0, binop(Iop_Mul32, 10373 unop(Iop_16Sto32, 10374 unop(Iop_32to16, getIReg(rt))), 10375 unop(Iop_16Sto32, 10376 unop(Iop_32to16, getIReg(rs))))); 10377 assign(t1, binop(Iop_Mul32, 10378 unop(Iop_16Sto32, 10379 unop(Iop_32HIto16, getIReg(rt))), 10380 unop(Iop_16Sto32, 10381 unop(Iop_32HIto16, getIReg(rs))))); 10382 assign(t2, binop(Iop_Sub32, mkexpr(t1), mkexpr(t0))); 10383 putAcc(ac, binop(Iop_Add64, 10384 mkexpr(t4), 10385 unop(Iop_32Sto64, mkexpr(t2)))); 10386 break; 10387 } 10388 case 0x3: { /* DPAU.H.QBL */ 10389 DIP("dpau.h.qbl ac%d, r%d, r%d", ac, rs, rt); 10390 vassert(!mode64); 10391 t0 = newTemp(Ity_I32); 10392 t1 = newTemp(Ity_I32); 10393 t2 = newTemp(Ity_I64); 10394 t3 = newTemp(Ity_I64); 10395 10396 assign(t0, 10397 binop(Iop_Mul32, 10398 unop(Iop_8Uto32, 10399 unop(Iop_16HIto8, 10400 unop(Iop_32HIto16, getIReg(rs)))), 10401 unop(Iop_8Uto32, 10402 unop(Iop_16HIto8, 10403 unop(Iop_32HIto16, getIReg(rt)))))); 10404 assign(t1, 10405 binop(Iop_Mul32, 10406 unop(Iop_8Uto32, 10407 unop(Iop_16to8, 10408 unop(Iop_32HIto16, getIReg(rs)))), 10409 unop(Iop_8Uto32, 10410 unop(Iop_16to8, 10411 unop(Iop_32HIto16, getIReg(rt)))))); 10412 assign(t2, 10413 unop(Iop_32Uto64, 10414 binop(Iop_Add32, 10415 mkexpr(t0), 10416 mkexpr(t1)))); 10417 assign(t3, 10418 binop(Iop_Add64, getAcc(ac), mkexpr(t2))); 10419 putAcc(ac, mkexpr(t3)); 10420 break; 10421 } 10422 case 0x4: { /* DPAQ_S.W.PH */ 10423 DIP("dpaq_s.w.ph ac%d, r%d, r%d", ac, rs, rt); 10424 vassert(!mode64); 10425 t0 = newTemp(Ity_I64); 10426 t1 = newTemp(Ity_I64); 10427 t2 = newTemp(Ity_I1); 10428 t3 = newTemp(Ity_I1); 10429 t4 = newTemp(Ity_I64); 10430 t5 = newTemp(Ity_I64); 10431 t6 = newTemp(Ity_I1); 10432 t7 = newTemp(Ity_I1); 10433 t8 = newTemp(Ity_I64); 10434 t9 = newTemp(Ity_I64); 10435 10436 assign(t0, getAcc(ac)); 10437 10438 assign(t1, binop(Iop_Shl64, 10439 binop(Iop_MullS32, 10440 unop(Iop_16Sto32, 10441 unop(Iop_32HIto16, 10442 getIReg(rs))), 10443 unop(Iop_16Sto32, 10444 unop(Iop_32HIto16, 10445 getIReg(rt)))), 10446 mkU8(0x1))); 10447 assign(t2, binop(Iop_CmpEQ32, 10448 unop(Iop_16Uto32, 10449 unop(Iop_32HIto16, getIReg(rs))), 10450 mkU32(0x00008000))); 10451 assign(t3, binop(Iop_CmpEQ32, 10452 unop(Iop_16Uto32, 10453 unop(Iop_32HIto16, getIReg(rt))), 10454 mkU32(0x00008000))); 10455 assign(t4, 10456 IRExpr_ITE(mkexpr(t2), 10457 IRExpr_ITE(mkexpr(t3), 10458 mkU64(0x000000007fffffffULL), 10459 mkexpr(t1)), 10460 mkexpr(t1))); 10461 10462 putDSPControl(IRExpr_ITE(mkexpr(t2), 10463 IRExpr_ITE(mkexpr(t3), 10464 binop(Iop_Or32, 10465 getDSPControl(), 10466 binop(Iop_Shl32, 10467 mkU32(0x1), 10468 mkU8(ac+16) 10469 ) 10470 ), 10471 getDSPControl()), 10472 getDSPControl())); 10473 10474 assign(t5, binop(Iop_Shl64, 10475 binop(Iop_MullS32, 10476 unop(Iop_16Sto32, 10477 unop(Iop_32to16, getIReg(rs))), 10478 unop(Iop_16Sto32, 10479 unop(Iop_32to16, getIReg(rt))) 10480 ), 10481 mkU8(0x1))); 10482 assign(t6, binop(Iop_CmpEQ32, 10483 unop(Iop_16Uto32, 10484 unop(Iop_32to16, getIReg(rs))), 10485 mkU32(0x00008000))); 10486 assign(t7, binop(Iop_CmpEQ32, 10487 unop(Iop_16Uto32, 10488 unop(Iop_32to16, getIReg(rt))), 10489 mkU32(0x00008000))); 10490 assign(t8, 10491 IRExpr_ITE(mkexpr(t6), 10492 IRExpr_ITE(mkexpr(t7), 10493 mkU64(0x000000007fffffffULL), 10494 mkexpr(t5)), 10495 mkexpr(t5))); 10496 10497 putDSPControl(IRExpr_ITE(mkexpr(t6), 10498 IRExpr_ITE(mkexpr(t7), 10499 binop(Iop_Or32, 10500 getDSPControl(), 10501 binop(Iop_Shl32, 10502 mkU32(0x1), 10503 mkU8(ac+16) 10504 ) 10505 ), 10506 getDSPControl()), 10507 getDSPControl())); 10508 10509 assign(t9, binop(Iop_Add64, 10510 binop(Iop_Add64, mkexpr(t4), mkexpr(t8)), 10511 mkexpr(t0))); 10512 putAcc(ac, mkexpr(t9)); 10513 break; 10514 } 10515 case 0x5: { /* DPSQ_S.W.PH */ 10516 DIP("dpsq_s.w.ph ac%d r%d, r%d", ac, rs, rt); 10517 vassert(!mode64); 10518 t0 = newTemp(Ity_I64); 10519 t1 = newTemp(Ity_I64); 10520 t2 = newTemp(Ity_I1); 10521 t3 = newTemp(Ity_I1); 10522 t4 = newTemp(Ity_I64); 10523 t5 = newTemp(Ity_I64); 10524 t6 = newTemp(Ity_I1); 10525 t7 = newTemp(Ity_I1); 10526 t8 = newTemp(Ity_I64); 10527 t9 = newTemp(Ity_I64); 10528 10529 assign(t0, getAcc(ac)); 10530 10531 assign(t1, binop(Iop_Shl64, 10532 binop(Iop_MullS32, 10533 unop(Iop_16Sto32, 10534 unop(Iop_32HIto16, 10535 getIReg(rs))), 10536 unop(Iop_16Sto32, 10537 unop(Iop_32HIto16, 10538 getIReg(rt)))), 10539 mkU8(0x1))); 10540 assign(t2, binop(Iop_CmpEQ32, 10541 unop(Iop_16Uto32, 10542 unop(Iop_32HIto16, getIReg(rs))), 10543 mkU32(0x00008000))); 10544 assign(t3, binop(Iop_CmpEQ32, 10545 unop(Iop_16Uto32, 10546 unop(Iop_32HIto16, getIReg(rt))), 10547 mkU32(0x00008000))); 10548 assign(t4, 10549 IRExpr_ITE(mkexpr(t2), 10550 IRExpr_ITE(mkexpr(t3), 10551 mkU64(0x000000007fffffffULL), 10552 mkexpr(t1)), 10553 mkexpr(t1))); 10554 10555 putDSPControl(IRExpr_ITE(mkexpr(t2), 10556 IRExpr_ITE(mkexpr(t3), 10557 binop(Iop_Or32, 10558 getDSPControl(), 10559 binop(Iop_Shl32, 10560 mkU32(0x1), 10561 mkU8(ac+16) 10562 ) 10563 ), 10564 getDSPControl()), 10565 getDSPControl())); 10566 10567 assign(t5, 10568 binop(Iop_Shl64, 10569 binop(Iop_MullS32, 10570 unop(Iop_16Sto32, 10571 unop(Iop_32to16, getIReg(rs))), 10572 unop(Iop_16Sto32, 10573 unop(Iop_32to16, getIReg(rt)))), 10574 mkU8(0x1))); 10575 assign(t6, binop(Iop_CmpEQ32, 10576 unop(Iop_16Uto32, 10577 unop(Iop_32to16, getIReg(rs))), 10578 mkU32(0x00008000))); 10579 assign(t7, binop(Iop_CmpEQ32, 10580 unop(Iop_16Uto32, 10581 unop(Iop_32to16, getIReg(rt))), 10582 mkU32(0x00008000))); 10583 assign(t8, 10584 IRExpr_ITE(mkexpr(t6), 10585 IRExpr_ITE(mkexpr(t7), 10586 mkU64(0x000000007fffffffULL), 10587 mkexpr(t5)), 10588 mkexpr(t5))); 10589 10590 putDSPControl(IRExpr_ITE(mkexpr(t6), 10591 IRExpr_ITE(mkexpr(t7), 10592 binop(Iop_Or32, 10593 getDSPControl(), 10594 binop(Iop_Shl32, 10595 mkU32(0x1), 10596 mkU8(ac+16) 10597 ) 10598 ), 10599 getDSPControl()), 10600 getDSPControl())); 10601 10602 assign(t9, 10603 binop(Iop_Sub64, 10604 mkexpr(t0), 10605 binop(Iop_Add64, mkexpr(t4), mkexpr(t8)))); 10606 putAcc(ac, mkexpr(t9)); 10607 break; 10608 } 10609 case 0x6: { /* MULSAQ_S.W.PH */ 10610 DIP("mulsaq_s.w.ph ac%d r%d, r%d", ac, rs, rt); 10611 vassert(!mode64); 10612 10613 t0 = newTemp(Ity_I32); 10614 t1 = newTemp(Ity_I32); 10615 t2 = newTemp(Ity_I32); 10616 t3 = newTemp(Ity_I32); 10617 t4 = newTemp(Ity_I32); 10618 t5 = newTemp(Ity_I32); 10619 t6 = newTemp(Ity_I64); 10620 t7 = newTemp(Ity_I64); 10621 t8 = newTemp(Ity_I32); 10622 t9 = newTemp(Ity_I32); 10623 10624 assign(t0, unop(Iop_16Sto32, 10625 unop(Iop_32HIto16, getIReg(rs)))); 10626 assign(t1, unop(Iop_16Sto32, 10627 unop(Iop_32HIto16, getIReg(rt)))); 10628 10629 assign(t8, binop(Iop_And32, 10630 unop(Iop_1Sto32, 10631 binop(Iop_CmpEQ32, 10632 unop(Iop_16Uto32, 10633 unop(Iop_32HIto16, 10634 getIReg(rs))), 10635 mkU32(0x8000))), 10636 unop(Iop_1Sto32, 10637 binop(Iop_CmpEQ32, 10638 unop(Iop_16Uto32, 10639 unop(Iop_32HIto16, 10640 getIReg(rt))), 10641 mkU32(0x8000))))); 10642 /* DSPControl_outflag:16+acc <- 1 */ 10643 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 10644 mkexpr(t8), 10645 mkU32(0x0)), 10646 binop(Iop_Or32, 10647 getDSPControl(), 10648 binop(Iop_Shl32, 10649 mkU32(0x00010000), 10650 mkU8(ac))), 10651 getDSPControl())); 10652 10653 /* tempB_31..0 */ 10654 assign(t2, 10655 IRExpr_ITE(binop(Iop_CmpNE32, 10656 mkexpr(t8), mkU32(0x0)), 10657 mkU32(0x7FFFFFFF), 10658 binop(Iop_Shl32, 10659 binop(Iop_Mul32, 10660 mkexpr(t0), mkexpr(t1)), 10661 mkU8(1)))); 10662 10663 assign(t3, unop(Iop_16Sto32, 10664 unop(Iop_32to16, getIReg(rs)))); 10665 assign(t4, unop(Iop_16Sto32, 10666 unop(Iop_32to16, getIReg(rt)))); 10667 10668 assign(t9, binop(Iop_And32, 10669 unop(Iop_1Sto32, 10670 binop(Iop_CmpEQ32, 10671 unop(Iop_16Uto32, 10672 unop(Iop_32to16, 10673 getIReg(rs))), 10674 mkU32(0x8000))), 10675 unop(Iop_1Sto32, 10676 binop(Iop_CmpEQ32, 10677 unop(Iop_16Uto32, 10678 unop(Iop_32to16, 10679 getIReg(rt))), 10680 mkU32(0x8000))))); 10681 /* DSPControl_outflag:16+acc <- 1 */ 10682 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 10683 mkexpr(t9), 10684 mkU32(0x0)), 10685 binop(Iop_Or32, 10686 getDSPControl(), 10687 binop(Iop_Shl32, 10688 mkU32(0x00010000), 10689 mkU8(ac))), 10690 getDSPControl())); 10691 /* tempA_31..0 */ 10692 assign(t5, 10693 IRExpr_ITE(binop(Iop_CmpNE32, 10694 mkexpr(t9), 10695 mkU32(0x0)), 10696 mkU32(0x7FFFFFFF), 10697 binop(Iop_Shl32, 10698 binop(Iop_Mul32, 10699 mkexpr(t3), 10700 mkexpr(t4)), 10701 mkU8(1)))); 10702 /* dotp_63..0 */ 10703 assign(t6, 10704 binop(Iop_Sub64, 10705 unop(Iop_32Sto64, mkexpr(t2)), 10706 unop(Iop_32Sto64, mkexpr(t5)))); 10707 /* tempC_63..0 */ 10708 assign(t7, binop(Iop_Add64, getAcc(ac), mkexpr(t6))); 10709 10710 putAcc(ac, mkexpr(t7)); 10711 break; 10712 } 10713 case 0x7: { /* DPAU.H.QBR */ 10714 DIP("dpau.h.qbr ac%d, r%d, r%d", ac, rs, rt); 10715 vassert(!mode64); 10716 t0 = newTemp(Ity_I32); 10717 t1 = newTemp(Ity_I32); 10718 t2 = newTemp(Ity_I64); 10719 t3 = newTemp(Ity_I64); 10720 10721 assign(t0, 10722 binop(Iop_Mul32, 10723 unop(Iop_8Uto32, 10724 unop(Iop_16HIto8, 10725 unop(Iop_32to16, getIReg(rs)))), 10726 unop(Iop_8Uto32, 10727 unop(Iop_16HIto8, 10728 unop(Iop_32to16, getIReg(rt)))))); 10729 assign(t1, 10730 binop(Iop_Mul32, 10731 unop(Iop_8Uto32, 10732 unop(Iop_16to8, 10733 unop(Iop_32to16, getIReg(rs)))), 10734 unop(Iop_8Uto32, 10735 unop(Iop_16to8, 10736 unop(Iop_32to16, getIReg(rt)))))); 10737 assign(t2, unop(Iop_32Uto64, 10738 binop(Iop_Add32, mkexpr(t0), mkexpr(t1)))); 10739 assign(t3, binop(Iop_Add64, getAcc(ac), mkexpr(t2))); 10740 putAcc(ac, mkexpr(t3)); 10741 break; 10742 } 10743 case 0x8: { /* DPAX.W.PH */ 10744 DIP("dpax.w.ph ac%d, r%d, r%d", ac, rs, rt); 10745 vassert(!mode64); 10746 t0 = newTemp(Ity_I64); 10747 t1 = newTemp(Ity_I64); 10748 t2 = newTemp(Ity_I64); 10749 10750 assign(t0, 10751 unop(Iop_32Sto64, 10752 binop(Iop_Mul32, 10753 unop(Iop_16Sto32, 10754 unop(Iop_32HIto16, getIReg(rs))), 10755 unop(Iop_16Sto32, 10756 unop(Iop_32to16, getIReg(rt)))))); 10757 assign(t1, 10758 unop(Iop_32Sto64, 10759 binop(Iop_Mul32, 10760 unop(Iop_16Sto32, 10761 unop(Iop_32to16, getIReg(rs))), 10762 unop(Iop_16Sto32, 10763 unop(Iop_32HIto16, getIReg(rt)))))); 10764 assign(t2, 10765 binop(Iop_Add64, 10766 getAcc(ac), 10767 binop(Iop_Add64, mkexpr(t0), mkexpr(t1)))); 10768 putAcc(ac, mkexpr(t2)); 10769 break; 10770 } 10771 case 0x9: { /* DPSX.W.PH */ 10772 DIP("dpsx.w.ph ac%d r%d, r%d", ac, rs, rt); 10773 vassert(!mode64); 10774 10775 t0 = newTemp(Ity_I64); 10776 t1 = newTemp(Ity_I64); 10777 t2 = newTemp(Ity_I64); 10778 10779 assign(t0, 10780 unop(Iop_32Sto64, 10781 binop(Iop_Mul32, 10782 unop(Iop_16Sto32, 10783 unop(Iop_32HIto16, getIReg(rs))), 10784 unop(Iop_16Sto32, 10785 unop(Iop_32to16, getIReg(rt)))))); 10786 assign(t1, 10787 unop(Iop_32Sto64, 10788 binop(Iop_Mul32, 10789 unop(Iop_16Sto32, 10790 unop(Iop_32to16, getIReg(rs))), 10791 unop(Iop_16Sto32, 10792 unop(Iop_32HIto16, getIReg(rt)))))); 10793 assign(t2, 10794 binop(Iop_Sub64, 10795 getAcc(ac), 10796 binop(Iop_Add64, mkexpr(t0), mkexpr(t1)))); 10797 putAcc(ac, mkexpr(t2)); 10798 break; 10799 } 10800 case 0xB: { /* DPSU.H.QBL */ 10801 DIP("dpsu.h.qbl ac%d, r%d, r%d", ac, rs, rt); 10802 vassert(!mode64); 10803 10804 t0 = newTemp(Ity_I32); 10805 t1 = newTemp(Ity_I32); 10806 t2 = newTemp(Ity_I64); 10807 t3 = newTemp(Ity_I64); 10808 10809 assign(t0, 10810 binop(Iop_Mul32, 10811 unop(Iop_8Uto32, 10812 unop(Iop_16HIto8, 10813 unop(Iop_32HIto16, getIReg(rs)))), 10814 unop(Iop_8Uto32, 10815 unop(Iop_16HIto8, 10816 unop(Iop_32HIto16, getIReg(rt)))))); 10817 assign(t1, 10818 binop(Iop_Mul32, 10819 unop(Iop_8Uto32, 10820 unop(Iop_16to8, 10821 unop(Iop_32HIto16, getIReg(rs)))), 10822 unop(Iop_8Uto32, 10823 unop(Iop_16to8, 10824 unop(Iop_32HIto16, getIReg(rt)))))); 10825 assign(t2, 10826 unop(Iop_32Uto64, 10827 binop(Iop_Add32, mkexpr(t0), mkexpr(t1)))); 10828 assign(t3, 10829 binop(Iop_Sub64, getAcc(ac), mkexpr(t2))); 10830 putAcc(ac, mkexpr(t3)); 10831 break; 10832 } 10833 case 0xC: { /* DPAQ_SA.L.W */ 10834 DIP("dpaq_sa.l.w ac%d, r%d, r%d", ac, rs, rt); 10835 vassert(!mode64); 10836 t0 = newTemp(Ity_I64); 10837 t1 = newTemp(Ity_I64); 10838 t2 = newTemp(Ity_I1); 10839 t3 = newTemp(Ity_I1); 10840 t4 = newTemp(Ity_I64); 10841 t5 = newTemp(Ity_I64); 10842 t6 = newTemp(Ity_I64); 10843 t7 = newTemp(Ity_I64); 10844 t8 = newTemp(Ity_I1); 10845 t9 = newTemp(Ity_I1); 10846 10847 assign(t0, getAcc(ac)); 10848 10849 assign(t1, binop(Iop_Shl64, 10850 binop(Iop_MullS32, 10851 getIReg(rs), getIReg(rt)), 10852 mkU8(0x1))); 10853 10854 assign(t2, binop(Iop_CmpEQ32, 10855 getIReg(rs), 10856 mkU32(0x80000000))); 10857 assign(t3, binop(Iop_CmpEQ32, 10858 getIReg(rt), 10859 mkU32(0x80000000))); 10860 10861 assign(t4, 10862 IRExpr_ITE(mkexpr(t2), 10863 IRExpr_ITE(mkexpr(t3), 10864 mkU64(0x7fffffffffffffffULL), 10865 mkexpr(t1)), 10866 mkexpr(t1))); 10867 10868 putDSPControl(IRExpr_ITE(mkexpr(t2), 10869 IRExpr_ITE(mkexpr(t3), 10870 binop(Iop_Or32, 10871 getDSPControl(), 10872 binop(Iop_Shl32, 10873 mkU32(0x1), 10874 mkU8(ac+16) 10875 ) 10876 ), 10877 getDSPControl()), 10878 getDSPControl())); 10879 10880 assign(t5, binop(Iop_Add64, 10881 unop(Iop_32Uto64, 10882 unop(Iop_64to32, mkexpr(t0))), 10883 unop(Iop_32Uto64, 10884 unop(Iop_64to32, mkexpr(t4))))); 10885 assign(t6, 10886 binop(Iop_Add64, 10887 binop(Iop_Add64, 10888 unop(Iop_32Sto64, 10889 unop(Iop_64HIto32, mkexpr(t0))), 10890 unop(Iop_32Sto64, 10891 unop(Iop_64HIto32, mkexpr(t4)))), 10892 unop(Iop_32Uto64, 10893 binop(Iop_And32, 10894 unop(Iop_64HIto32, mkexpr(t5)), 10895 mkU32(0x1))))); 10896 assign(t7, binop(Iop_32HLto64, 10897 unop(Iop_64to32, mkexpr(t6)), 10898 unop(Iop_64to32, mkexpr(t5)))); 10899 assign(t8, binop(Iop_CmpEQ32, 10900 binop(Iop_Shr32, 10901 binop(Iop_And32, 10902 unop(Iop_64to32, mkexpr(t6)), 10903 mkU32(0x80000000)), 10904 mkU8(31)), 10905 binop(Iop_And32, 10906 unop(Iop_64HIto32, mkexpr(t6)), 10907 mkU32(0x00000001)))); 10908 assign(t9, binop(Iop_CmpEQ32, 10909 binop(Iop_And32, 10910 unop(Iop_64HIto32, 10911 mkexpr(t6)), 10912 mkU32(0x00000001)), 10913 mkU32(0x1))); 10914 putDSPControl(IRExpr_ITE(mkexpr(t8), 10915 getDSPControl(), 10916 binop(Iop_Or32, 10917 getDSPControl(), 10918 binop(Iop_Shl32, 10919 mkU32(0x1), 10920 mkU8(ac+16))))); 10921 putAcc(ac, 10922 IRExpr_ITE(mkexpr(t8), 10923 mkexpr(t7), 10924 IRExpr_ITE(mkexpr(t9), 10925 mkU64(0x8000000000000000ULL), 10926 mkU64(0x7fffffffffffffffULL))) 10927 ); 10928 break; 10929 } 10930 case 0xD: { /* DPSQ_SA.L.W */ 10931 DIP("dpsq_sa.l.w ac%d, r%d, r%d", ac, rs, rt); 10932 vassert(!mode64); 10933 t0 = newTemp(Ity_I64); 10934 t1 = newTemp(Ity_I64); 10935 t2 = newTemp(Ity_I1); 10936 t3 = newTemp(Ity_I1); 10937 t4 = newTemp(Ity_I64); 10938 t5 = newTemp(Ity_I64); 10939 t6 = newTemp(Ity_I64); 10940 t7 = newTemp(Ity_I64); 10941 t8 = newTemp(Ity_I1); 10942 t9 = newTemp(Ity_I1); 10943 10944 assign(t0, getAcc(ac)); 10945 10946 assign(t1, binop(Iop_Shl64, 10947 binop(Iop_MullS32, 10948 getIReg(rs), getIReg(rt)), 10949 mkU8(0x1))); 10950 10951 assign(t2, binop(Iop_CmpEQ32, 10952 getIReg(rs), 10953 mkU32(0x80000000))); 10954 assign(t3, binop(Iop_CmpEQ32, 10955 getIReg(rt), 10956 mkU32(0x80000000))); 10957 10958 assign(t4, 10959 IRExpr_ITE(mkexpr(t2), 10960 IRExpr_ITE(mkexpr(t3), 10961 mkU64(0x7fffffffffffffffULL), 10962 mkexpr(t1)), 10963 mkexpr(t1))); 10964 10965 putDSPControl(IRExpr_ITE(mkexpr(t2), 10966 IRExpr_ITE(mkexpr(t3), 10967 binop(Iop_Or32, 10968 getDSPControl(), 10969 binop(Iop_Shl32, 10970 mkU32(0x1), 10971 mkU8(ac+16) 10972 ) 10973 ), 10974 getDSPControl()), 10975 getDSPControl())); 10976 10977 assign(t5, binop(Iop_Sub64, 10978 unop(Iop_32Uto64, 10979 unop(Iop_64to32, mkexpr(t0))), 10980 unop(Iop_32Uto64, 10981 unop(Iop_64to32, mkexpr(t4))))); 10982 assign(t6, binop(Iop_Sub64, 10983 binop(Iop_Add64, 10984 unop(Iop_32Sto64, 10985 unop(Iop_64HIto32, mkexpr(t0)) 10986 ), 10987 unop(Iop_32Sto64, 10988 unop(Iop_1Sto32, 10989 binop(Iop_CmpLT32U, 10990 unop(Iop_64to32, 10991 mkexpr(t0)), 10992 unop(Iop_64to32, 10993 mkexpr(t4)))))), 10994 unop(Iop_32Sto64, 10995 unop(Iop_64HIto32, mkexpr(t4))))); 10996 assign(t7, binop(Iop_32HLto64, 10997 unop(Iop_64to32, mkexpr(t6)), 10998 unop(Iop_64to32, mkexpr(t5)))); 10999 assign(t8, binop(Iop_CmpEQ32, 11000 binop(Iop_Shr32, 11001 binop(Iop_And32, 11002 unop(Iop_64to32, mkexpr(t6)), 11003 mkU32(0x80000000)), 11004 mkU8(31)), 11005 binop(Iop_And32, 11006 unop(Iop_64HIto32, mkexpr(t6)), 11007 mkU32(0x00000001)))); 11008 assign(t9, binop(Iop_CmpEQ32, 11009 binop(Iop_And32, 11010 unop(Iop_64HIto32, mkexpr(t6)), 11011 mkU32(0x00000001)), 11012 mkU32(0x1))); 11013 putDSPControl(IRExpr_ITE(mkexpr(t8), 11014 getDSPControl(), 11015 binop(Iop_Or32, 11016 getDSPControl(), 11017 binop(Iop_Shl32, 11018 mkU32(0x1), 11019 mkU8(ac+16))))); 11020 putAcc(ac, 11021 IRExpr_ITE(mkexpr(t8), 11022 mkexpr(t7), 11023 IRExpr_ITE(mkexpr(t9), 11024 mkU64(0x8000000000000000ULL), 11025 mkU64(0x7fffffffffffffffULL))) 11026 ); 11027 break; 11028 } 11029 case 0xF: { /* DPSU.H.QBR */ 11030 DIP("dpsu.h.qbr ac%d r%d, r%d", ac, rs, rt); 11031 vassert(!mode64); 11032 11033 t0 = newTemp(Ity_I32); 11034 t1 = newTemp(Ity_I32); 11035 t2 = newTemp(Ity_I64); 11036 t3 = newTemp(Ity_I64); 11037 11038 assign(t0, 11039 binop(Iop_Mul32, 11040 unop(Iop_8Uto32, 11041 unop(Iop_16HIto8, 11042 unop(Iop_32to16, getIReg(rs)))), 11043 unop(Iop_8Uto32, 11044 unop(Iop_16HIto8, 11045 unop(Iop_32to16, getIReg(rt)))))); 11046 assign(t1, 11047 binop(Iop_Mul32, 11048 unop(Iop_8Uto32, 11049 unop(Iop_16to8, 11050 unop(Iop_32to16, getIReg(rs)))), 11051 unop(Iop_8Uto32, 11052 unop(Iop_16to8, 11053 unop(Iop_32to16, getIReg(rt)))))); 11054 assign(t2, unop(Iop_32Uto64, 11055 binop(Iop_Add32, mkexpr(t0), mkexpr(t1)))); 11056 assign(t3, binop(Iop_Sub64, getAcc(ac), mkexpr(t2))); 11057 putAcc(ac, mkexpr(t3)); 11058 11059 break; 11060 } 11061 case 0x10: { /* MAQ_SA.W.PHL */ 11062 DIP("maq_sa.w.phl ac%d, r%d, r%d", ac, rs, rt); 11063 vassert(!mode64); 11064 t0 = newTemp(Ity_I64); 11065 t1 = newTemp(Ity_I64); 11066 t2 = newTemp(Ity_I1); 11067 t3 = newTemp(Ity_I1); 11068 t4 = newTemp(Ity_I64); 11069 t5 = newTemp(Ity_I64); 11070 t6 = newTemp(Ity_I1); 11071 t7 = newTemp(Ity_I64); 11072 11073 assign(t0, getAcc(ac)); 11074 assign(t1, unop(Iop_32Sto64, 11075 binop(Iop_Shl32, 11076 binop(Iop_Mul32, 11077 unop(Iop_16Sto32, 11078 unop(Iop_32HIto16, 11079 getIReg(rs))), 11080 unop(Iop_16Sto32, 11081 unop(Iop_32HIto16, 11082 getIReg(rt)))), 11083 mkU8(0x1)))); 11084 11085 /* If both input arguments are equal 0x8000, saturate 11086 intermediate product and write to DSPControl register. 11087 */ 11088 assign(t2, binop(Iop_CmpEQ32, 11089 unop(Iop_16Uto32, 11090 unop(Iop_32HIto16, getIReg(rs))), 11091 mkU32(0x00008000))); 11092 assign(t3, binop(Iop_CmpEQ32, 11093 unop(Iop_16Uto32, 11094 unop(Iop_32HIto16, getIReg(rt))), 11095 mkU32(0x00008000))); 11096 11097 assign(t4, 11098 IRExpr_ITE(mkexpr(t2), 11099 IRExpr_ITE(mkexpr(t3), 11100 mkU64(0x000000007fffffffULL), 11101 mkexpr(t1)), 11102 mkexpr(t1))); 11103 11104 putDSPControl(IRExpr_ITE(mkexpr(t2), 11105 IRExpr_ITE(mkexpr(t3), 11106 binop(Iop_Or32, 11107 getDSPControl(), 11108 binop(Iop_Shl32, 11109 mkU32(0x1), 11110 mkU8(ac+16) 11111 ) 11112 ), 11113 getDSPControl()), 11114 getDSPControl())); 11115 /* Add intermediate product and value in the 11116 accumulator. */ 11117 assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4))); 11118 11119 /* Compare bits 31 and 32 of the value in t5. */ 11120 assign(t6, binop(Iop_CmpEQ32, 11121 binop(Iop_Shr32, 11122 binop(Iop_And32, 11123 unop(Iop_64to32, mkexpr(t5)), 11124 mkU32(0x80000000)), 11125 mkU8(31)), 11126 binop(Iop_And32, 11127 unop(Iop_64HIto32, mkexpr(t5)), 11128 mkU32(1)))); 11129 putDSPControl(IRExpr_ITE(mkexpr(t6), 11130 getDSPControl(), 11131 binop(Iop_Or32, 11132 getDSPControl(), 11133 binop(Iop_Shl32, 11134 mkU32(0x1), 11135 mkU8(ac+16))))); 11136 assign(t7, 11137 IRExpr_ITE(mkexpr(t6), 11138 mkexpr(t5), 11139 IRExpr_ITE(binop(Iop_CmpEQ32, 11140 binop(Iop_And32, 11141 unop(Iop_64HIto32, 11142 mkexpr(t5)), 11143 mkU32(1)), 11144 mkU32(0x0)), 11145 mkU64(0x000000007fffffffULL), 11146 mkU64(0xffffffff80000000ULL))) 11147 ); 11148 putAcc(ac, mkexpr(t7)); 11149 break; 11150 } 11151 case 0x12: { /* MAQ_SA.W.PHR */ 11152 DIP("maq_sa.w.phr ac%d, r%d, r%d", ac, rs, rt); 11153 vassert(!mode64); 11154 t0 = newTemp(Ity_I64); 11155 t1 = newTemp(Ity_I64); 11156 t2 = newTemp(Ity_I1); 11157 t3 = newTemp(Ity_I1); 11158 t4 = newTemp(Ity_I64); 11159 t5 = newTemp(Ity_I64); 11160 t6 = newTemp(Ity_I1); 11161 t7 = newTemp(Ity_I64); 11162 11163 assign(t0, getAcc(ac)); 11164 assign(t1, unop(Iop_32Sto64, 11165 binop(Iop_Shl32, 11166 binop(Iop_Mul32, 11167 unop(Iop_16Sto32, 11168 unop(Iop_32to16, 11169 getIReg(rs))), 11170 unop(Iop_16Sto32, 11171 unop(Iop_32to16, 11172 getIReg(rt)))), 11173 mkU8(0x1)))); 11174 11175 /* If both input arguments are equal 0x8000, saturate 11176 intermediate product and write to DSPControl 11177 register. */ 11178 assign(t2, binop(Iop_CmpEQ32, 11179 unop(Iop_16Uto32, 11180 unop(Iop_32to16, getIReg(rs))), 11181 mkU32(0x00008000))); 11182 assign(t3, binop(Iop_CmpEQ32, 11183 unop(Iop_16Uto32, 11184 unop(Iop_32to16, getIReg(rt))), 11185 mkU32(0x00008000))); 11186 11187 assign(t4, 11188 IRExpr_ITE(mkexpr(t2), 11189 IRExpr_ITE(mkexpr(t3), 11190 mkU64(0x000000007fffffffULL), 11191 mkexpr(t1)), 11192 mkexpr(t1))); 11193 11194 putDSPControl(IRExpr_ITE(mkexpr(t2), 11195 IRExpr_ITE(mkexpr(t3), 11196 binop(Iop_Or32, 11197 getDSPControl(), 11198 binop(Iop_Shl32, 11199 mkU32(0x1), 11200 mkU8(ac+16) 11201 ) 11202 ), 11203 getDSPControl()), 11204 getDSPControl())); 11205 /* Add intermediate product and value in the 11206 accumulator. */ 11207 assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4))); 11208 11209 /* Compare bits 31 and 32 of the value in t5. */ 11210 assign(t6, binop(Iop_CmpEQ32, 11211 binop(Iop_Shr32, 11212 binop(Iop_And32, 11213 unop(Iop_64to32, mkexpr(t5)), 11214 mkU32(0x80000000)), 11215 mkU8(31)), 11216 binop(Iop_And32, 11217 unop(Iop_64HIto32, mkexpr(t5)), 11218 mkU32(1)))); 11219 putDSPControl(IRExpr_ITE(mkexpr(t6), 11220 getDSPControl(), 11221 binop(Iop_Or32, 11222 getDSPControl(), 11223 binop(Iop_Shl32, 11224 mkU32(0x1), 11225 mkU8(ac+16))))); 11226 assign(t7, 11227 IRExpr_ITE(mkexpr(t6), 11228 mkexpr(t5), 11229 IRExpr_ITE(binop(Iop_CmpEQ32, 11230 binop(Iop_And32, 11231 unop(Iop_64HIto32, 11232 mkexpr(t5)), 11233 mkU32(1)), 11234 mkU32(0x0)), 11235 mkU64(0x000000007fffffffULL), 11236 mkU64(0xffffffff80000000ULL))) 11237 ); 11238 putAcc(ac, mkexpr(t7)); 11239 break; 11240 } 11241 case 0x14: { /* MAQ_S.W.PHL */ 11242 DIP("maq_s.w.phl ac%d, r%d, r%d", ac, rs, rt); 11243 vassert(!mode64); 11244 t0 = newTemp(Ity_I32); 11245 t1 = newTemp(Ity_I32); 11246 t2 = newTemp(Ity_I32); 11247 t3 = newTemp(Ity_I1); 11248 t4 = newTemp(Ity_I32); 11249 t5 = newTemp(Ity_I64); 11250 11251 assign(t5, getAcc(ac)); 11252 11253 assign(t0, unop(Iop_16Sto32, 11254 unop(Iop_32HIto16, getIReg(rs)))); 11255 assign(t1, unop(Iop_16Sto32, 11256 unop(Iop_32HIto16, getIReg(rt)))); 11257 11258 assign(t2, binop(Iop_And32, 11259 unop(Iop_1Sto32, 11260 binop(Iop_CmpEQ32, 11261 binop(Iop_And32, 11262 mkexpr(t0), 11263 mkU32(0xffff)), 11264 mkU32(0x8000))), 11265 unop(Iop_1Sto32, 11266 binop(Iop_CmpEQ32, 11267 binop(Iop_And32, 11268 mkexpr(t1), 11269 mkU32(0xffff)), 11270 mkU32(0x8000))))); 11271 11272 assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0))); 11273 11274 putDSPControl(IRExpr_ITE(mkexpr(t3), 11275 getDSPControl(), 11276 binop(Iop_Or32, 11277 getDSPControl(), 11278 binop(Iop_Shl32, 11279 mkU32(0x1), 11280 mkU8(ac+16))))); 11281 11282 assign(t4, unop(Iop_64to32, 11283 binop(Iop_MullS32, 11284 mkexpr(t0), mkexpr(t1)))); 11285 putAcc(ac, IRExpr_ITE(mkexpr(t3), 11286 binop(Iop_Add64, 11287 unop(Iop_32Sto64, 11288 binop(Iop_Shl32, 11289 mkexpr(t4), 11290 mkU8(0x1))), 11291 mkexpr(t5)), 11292 binop(Iop_Add64, 11293 mkexpr(t5), 11294 unop(Iop_32Sto64, 11295 mkU32(0x7fffffff))))); 11296 break; 11297 } 11298 case 0x16: { /* MAQ_S.W.PHR */ 11299 DIP("maq_s.w.phr ac%d, r%d, r%d", ac, rs, rt); 11300 vassert(!mode64); 11301 t0 = newTemp(Ity_I32); 11302 t1 = newTemp(Ity_I32); 11303 t2 = newTemp(Ity_I32); 11304 t3 = newTemp(Ity_I1); 11305 t4 = newTemp(Ity_I32); 11306 t5 = newTemp(Ity_I64); 11307 11308 assign(t5, getAcc(ac)); 11309 11310 assign(t0, unop(Iop_16Sto32, 11311 unop(Iop_32to16, getIReg(rs)))); 11312 assign(t1, unop(Iop_16Sto32, 11313 unop(Iop_32to16, getIReg(rt)))); 11314 11315 assign(t2, binop(Iop_And32, 11316 unop(Iop_1Sto32, 11317 binop(Iop_CmpEQ32, 11318 binop(Iop_And32, 11319 mkexpr(t0), 11320 mkU32(0xffff)), 11321 mkU32(0x8000))), 11322 unop(Iop_1Sto32, 11323 binop(Iop_CmpEQ32, 11324 binop(Iop_And32, 11325 mkexpr(t1), 11326 mkU32(0xffff)), 11327 mkU32(0x8000))))); 11328 11329 assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0))); 11330 11331 putDSPControl(IRExpr_ITE(mkexpr(t3), 11332 getDSPControl(), 11333 binop(Iop_Or32, 11334 getDSPControl(), 11335 binop(Iop_Shl32, 11336 mkU32(0x1), 11337 mkU8(ac+16))))); 11338 11339 assign(t4, unop(Iop_64to32, 11340 binop(Iop_MullS32, 11341 mkexpr(t0), mkexpr(t1)))); 11342 putAcc(ac, IRExpr_ITE(mkexpr(t3), 11343 binop(Iop_Add64, 11344 unop(Iop_32Sto64, 11345 binop(Iop_Shl32, 11346 mkexpr(t4), 11347 mkU8(0x1))), 11348 mkexpr(t5)), 11349 binop(Iop_Add64, 11350 mkexpr(t5), 11351 unop(Iop_32Sto64, 11352 mkU32(0x7fffffff))))); 11353 break; 11354 } 11355 case 0x18: { /* DPAQX_S.W.PH */ 11356 DIP("dpaqx_s.w.ph ac%d, r%d, r%d", ac, rs, rt); 11357 vassert(!mode64); 11358 t0 = newTemp(Ity_I64); 11359 t1 = newTemp(Ity_I64); 11360 t2 = newTemp(Ity_I1); 11361 t3 = newTemp(Ity_I1); 11362 t4 = newTemp(Ity_I64); 11363 t5 = newTemp(Ity_I64); 11364 t6 = newTemp(Ity_I1); 11365 t7 = newTemp(Ity_I1); 11366 t8 = newTemp(Ity_I64); 11367 t9 = newTemp(Ity_I64); 11368 11369 assign(t0, getAcc(ac)); 11370 11371 assign(t1, binop(Iop_Shl64, 11372 binop(Iop_MullS32, 11373 unop(Iop_16Sto32, 11374 unop(Iop_32HIto16, 11375 getIReg(rs))), 11376 unop(Iop_16Sto32, 11377 unop(Iop_32to16, 11378 getIReg(rt)))), 11379 mkU8(0x1))); 11380 assign(t2, binop(Iop_CmpEQ32, 11381 unop(Iop_16Uto32, 11382 unop(Iop_32HIto16, getIReg(rs))), 11383 mkU32(0x00008000))); 11384 assign(t3, binop(Iop_CmpEQ32, 11385 unop(Iop_16Uto32, 11386 unop(Iop_32to16, getIReg(rt))), 11387 mkU32(0x00008000))); 11388 assign(t4, 11389 IRExpr_ITE(mkexpr(t2), 11390 IRExpr_ITE(mkexpr(t3), 11391 mkU64(0x000000007fffffffULL), 11392 mkexpr(t1)), 11393 mkexpr(t1))); 11394 11395 putDSPControl(IRExpr_ITE(mkexpr(t2), 11396 IRExpr_ITE(mkexpr(t3), 11397 binop(Iop_Or32, 11398 getDSPControl(), 11399 binop(Iop_Shl32, 11400 mkU32(0x1), 11401 mkU8(ac+16))), 11402 getDSPControl()), 11403 getDSPControl())); 11404 11405 assign(t5, binop(Iop_Shl64, 11406 binop(Iop_MullS32, 11407 unop(Iop_16Sto32, 11408 unop(Iop_32to16, 11409 getIReg(rs))), 11410 unop(Iop_16Sto32, 11411 unop(Iop_32HIto16, 11412 getIReg(rt)))), 11413 mkU8(0x1))); 11414 assign(t6, binop(Iop_CmpEQ32, 11415 unop(Iop_16Uto32, 11416 unop(Iop_32to16, getIReg(rs))), 11417 mkU32(0x00008000))); 11418 assign(t7, binop(Iop_CmpEQ32, 11419 unop(Iop_16Uto32, 11420 unop(Iop_32HIto16, getIReg(rt))), 11421 mkU32(0x00008000))); 11422 assign(t8, 11423 IRExpr_ITE(mkexpr(t6), 11424 IRExpr_ITE(mkexpr(t7), 11425 mkU64(0x000000007fffffffULL), 11426 mkexpr(t5)), 11427 mkexpr(t5))); 11428 11429 putDSPControl(IRExpr_ITE(mkexpr(t6), 11430 IRExpr_ITE(mkexpr(t7), 11431 binop(Iop_Or32, 11432 getDSPControl(), 11433 binop(Iop_Shl32, 11434 mkU32(0x1), 11435 mkU8(ac+16) 11436 ) 11437 ), 11438 getDSPControl()), 11439 getDSPControl())); 11440 11441 assign(t9, binop(Iop_Add64, 11442 binop(Iop_Add64, mkexpr(t4), mkexpr(t8)), 11443 mkexpr(t0))); 11444 putAcc(ac, mkexpr(t9)); 11445 break; 11446 } 11447 case 0x19: { /* DPSQX_S.W.PH */ 11448 DIP("dpsqx_s.w.ph ac%d, r%d, r%d", ac, rs, rt); 11449 vassert(!mode64); 11450 t0 = newTemp(Ity_I64); 11451 t1 = newTemp(Ity_I64); 11452 t2 = newTemp(Ity_I1); 11453 t3 = newTemp(Ity_I1); 11454 t4 = newTemp(Ity_I64); 11455 t5 = newTemp(Ity_I64); 11456 t6 = newTemp(Ity_I1); 11457 t7 = newTemp(Ity_I1); 11458 t8 = newTemp(Ity_I64); 11459 t9 = newTemp(Ity_I64); 11460 11461 assign(t0, getAcc(ac)); 11462 11463 assign(t1, binop(Iop_Shl64, 11464 binop(Iop_MullS32, 11465 unop(Iop_16Sto32, 11466 unop(Iop_32HIto16, 11467 getIReg(rs))), 11468 unop(Iop_16Sto32, 11469 unop(Iop_32to16, 11470 getIReg(rt)))), 11471 mkU8(0x1))); 11472 assign(t2, binop(Iop_CmpEQ32, 11473 unop(Iop_16Uto32, 11474 unop(Iop_32HIto16, getIReg(rs))), 11475 mkU32(0x00008000))); 11476 assign(t3, binop(Iop_CmpEQ32, 11477 unop(Iop_16Uto32, 11478 unop(Iop_32to16, getIReg(rt))), 11479 mkU32(0x00008000))); 11480 assign(t4, 11481 IRExpr_ITE(mkexpr(t2), 11482 IRExpr_ITE(mkexpr(t3), 11483 mkU64(0x000000007fffffffULL), 11484 mkexpr(t1)), 11485 mkexpr(t1))); 11486 11487 putDSPControl(IRExpr_ITE(mkexpr(t2), 11488 IRExpr_ITE(mkexpr(t3), 11489 binop(Iop_Or32, 11490 getDSPControl(), 11491 binop(Iop_Shl32, 11492 mkU32(0x1), 11493 mkU8(ac+16) 11494 ) 11495 ), 11496 getDSPControl()), 11497 getDSPControl())); 11498 11499 assign(t5, binop(Iop_Shl64, 11500 binop(Iop_MullS32, 11501 unop(Iop_16Sto32, 11502 unop(Iop_32to16, 11503 getIReg(rs))), 11504 unop(Iop_16Sto32, 11505 unop(Iop_32HIto16, 11506 getIReg(rt)))), 11507 mkU8(0x1))); 11508 assign(t6, binop(Iop_CmpEQ32, 11509 unop(Iop_16Uto32, 11510 unop(Iop_32to16, getIReg(rs))), 11511 mkU32(0x00008000))); 11512 assign(t7, binop(Iop_CmpEQ32, 11513 unop(Iop_16Uto32, 11514 unop(Iop_32HIto16, getIReg(rt))), 11515 mkU32(0x00008000))); 11516 assign(t8, 11517 IRExpr_ITE(mkexpr(t6), 11518 IRExpr_ITE(mkexpr(t7), 11519 mkU64(0x000000007fffffffULL), 11520 mkexpr(t5)), 11521 mkexpr(t5))); 11522 11523 putDSPControl(IRExpr_ITE(mkexpr(t6), 11524 IRExpr_ITE(mkexpr(t7), 11525 binop(Iop_Or32, 11526 getDSPControl(), 11527 binop(Iop_Shl32, 11528 mkU32(0x1), 11529 mkU8(ac+16) 11530 ) 11531 ), 11532 getDSPControl()), 11533 getDSPControl())); 11534 11535 assign(t9, binop(Iop_Sub64, 11536 mkexpr(t0), 11537 binop(Iop_Add64, mkexpr(t4), mkexpr(t8)))); 11538 putAcc(ac, mkexpr(t9)); 11539 break; 11540 } 11541 case 0x1A: { /* DPAQX_SA.W.PH */ 11542 DIP("dpaqx_sa.w.ph ac%d, r%d, r%d", ac, rs, rt); 11543 vassert(!mode64); 11544 t0 = newTemp(Ity_I64); 11545 t1 = newTemp(Ity_I64); 11546 t2 = newTemp(Ity_I1); 11547 t3 = newTemp(Ity_I1); 11548 t4 = newTemp(Ity_I64); 11549 t5 = newTemp(Ity_I64); 11550 t6 = newTemp(Ity_I1); 11551 t7 = newTemp(Ity_I1); 11552 t8 = newTemp(Ity_I64); 11553 t9 = newTemp(Ity_I64); 11554 t10 = newTemp(Ity_I32); 11555 11556 assign(t0, getAcc(ac)); 11557 /* Calculate the first cross dot product and saturate if 11558 needed. */ 11559 assign(t1, unop(Iop_32Sto64, 11560 binop(Iop_Shl32, 11561 binop(Iop_Mul32, 11562 unop(Iop_16Sto32, 11563 unop(Iop_32HIto16, 11564 getIReg(rs))), 11565 unop(Iop_16Sto32, 11566 unop(Iop_32to16, 11567 getIReg(rt)))), 11568 mkU8(0x1)))); 11569 11570 /* If both input arguments are equal 0x8000, saturate 11571 intermediate product and write to DSPControl 11572 register. */ 11573 assign(t2, binop(Iop_CmpEQ32, 11574 unop(Iop_16Uto32, 11575 unop(Iop_32HIto16, getIReg(rs))), 11576 mkU32(0x00008000))); 11577 assign(t3, binop(Iop_CmpEQ32, 11578 unop(Iop_16Uto32, 11579 unop(Iop_32to16, getIReg(rt))), 11580 mkU32(0x00008000))); 11581 11582 assign(t4, IRExpr_ITE(binop(Iop_CmpNE32, 11583 binop(Iop_And32, 11584 unop(Iop_1Sto32, 11585 mkexpr(t2)), 11586 unop(Iop_1Sto32, 11587 mkexpr(t3))), 11588 mkU32(0)), 11589 mkU64(0x000000007fffffffULL), 11590 mkexpr(t1))); 11591 11592 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 11593 binop(Iop_And32, 11594 unop(Iop_1Sto32, 11595 mkexpr(t2)), 11596 unop(Iop_1Sto32, 11597 mkexpr(t3))), 11598 mkU32(0)), 11599 binop(Iop_Or32, 11600 getDSPControl(), 11601 binop(Iop_Shl32, 11602 mkU32(0x1), 11603 mkU8(ac+16))), 11604 getDSPControl())); 11605 /* Calculate second cross dot product and saturate if 11606 needed. */ 11607 assign(t5, unop(Iop_32Sto64, 11608 binop(Iop_Shl32, 11609 binop(Iop_Mul32, 11610 unop(Iop_16Sto32, 11611 unop(Iop_32to16, 11612 getIReg(rs))), 11613 unop(Iop_16Sto32, 11614 unop(Iop_32HIto16, 11615 getIReg(rt)))), 11616 mkU8(0x1)))); 11617 11618 /* If both input arguments are equal 0x8000, saturate 11619 intermediate product and write to DSPControl 11620 register. */ 11621 assign(t6, binop(Iop_CmpEQ32, 11622 unop(Iop_16Uto32, 11623 unop(Iop_32to16, getIReg(rs))), 11624 mkU32(0x00008000))); 11625 assign(t7, binop(Iop_CmpEQ32, 11626 unop(Iop_16Uto32, 11627 unop(Iop_32HIto16, getIReg(rt))), 11628 mkU32(0x00008000))); 11629 11630 assign(t8, IRExpr_ITE(binop(Iop_CmpNE32, 11631 binop(Iop_And32, 11632 unop(Iop_1Sto32, 11633 mkexpr(t6)), 11634 unop(Iop_1Sto32, 11635 mkexpr(t7))), 11636 mkU32(0)), 11637 mkU64(0x000000007fffffffULL), 11638 mkexpr(t5))); 11639 11640 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 11641 binop(Iop_And32, 11642 unop(Iop_1Sto32, 11643 mkexpr(t6)), 11644 unop(Iop_1Sto32, 11645 mkexpr(t7))), 11646 mkU32(0)), 11647 binop(Iop_Or32, 11648 getDSPControl(), 11649 binop(Iop_Shl32, 11650 mkU32(0x1), 11651 mkU8(ac+16))), 11652 getDSPControl())); 11653 /* Subtract intermediate products from value in the 11654 accumulator. */ 11655 assign(t9, 11656 binop(Iop_Add64, 11657 mkexpr(t0), 11658 binop(Iop_Add64, mkexpr(t8), mkexpr(t4)))); 11659 11660 putAcc(ac, 11661 IRExpr_ITE(binop(Iop_CmpEQ32, 11662 binop(Iop_And32, 11663 unop(Iop_64HIto32, 11664 mkexpr(t9)), 11665 mkU32(0x80000000)), 11666 mkU32(0x0)), 11667 IRExpr_ITE(binop(Iop_CmpNE32, 11668 unop(Iop_64HIto32, 11669 binop(Iop_Shl64, 11670 mkexpr(t9), 11671 mkU8(1))), 11672 mkU32(0x0)), 11673 mkU64(0x000000007fffffffULL), 11674 mkexpr(t9)), 11675 IRExpr_ITE(binop(Iop_CmpNE32, 11676 unop(Iop_64HIto32, 11677 binop(Iop_Shl64, 11678 mkexpr(t9), 11679 mkU8(1))), 11680 mkU32(0xffffffff)), 11681 mkU64(0xffffffff80000000ULL), 11682 mkexpr(t9)))); 11683 assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32, 11684 unop(Iop_64to32, 11685 mkexpr(t9)), 11686 unop(Iop_64to32, 11687 getAcc(ac))), 11688 getDSPControl(), 11689 binop(Iop_Or32, 11690 getDSPControl(), 11691 binop(Iop_Shl32, 11692 mkU32(0x1), 11693 mkU8(ac+16))))); 11694 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 11695 unop(Iop_64HIto32, 11696 mkexpr(t9)), 11697 unop(Iop_64HIto32, 11698 getAcc(ac))), 11699 mkexpr(t10), 11700 binop(Iop_Or32, 11701 getDSPControl(), 11702 binop(Iop_Shl32, 11703 mkU32(0x1), 11704 mkU8(ac+16))))); 11705 break; 11706 } 11707 case 0x1B: { /* DPSQX_SA.W.PH */ 11708 DIP("dpsqx_sa.w.ph ac%d, r%d, r%d", ac, rs, rt); 11709 vassert(!mode64); 11710 t0 = newTemp(Ity_I64); 11711 t1 = newTemp(Ity_I64); 11712 t2 = newTemp(Ity_I1); 11713 t3 = newTemp(Ity_I1); 11714 t4 = newTemp(Ity_I64); 11715 t5 = newTemp(Ity_I64); 11716 t6 = newTemp(Ity_I1); 11717 t7 = newTemp(Ity_I1); 11718 t8 = newTemp(Ity_I64); 11719 t9 = newTemp(Ity_I64); 11720 t10 = newTemp(Ity_I32); 11721 11722 assign(t0, getAcc(ac)); 11723 /* Calculate the first cross dot product and saturate if 11724 needed. */ 11725 assign(t1, unop(Iop_32Sto64, 11726 binop(Iop_Shl32, 11727 binop(Iop_Mul32, 11728 unop(Iop_16Sto32, 11729 unop(Iop_32HIto16, 11730 getIReg(rs))), 11731 unop(Iop_16Sto32, 11732 unop(Iop_32to16, 11733 getIReg(rt)))), 11734 mkU8(0x1)))); 11735 11736 /* If both input arguments are equal 0x8000, saturate 11737 intermediate product and write to DSPControl 11738 register. */ 11739 assign(t2, binop(Iop_CmpEQ32, 11740 unop(Iop_16Uto32, 11741 unop(Iop_32HIto16, getIReg(rs))), 11742 mkU32(0x00008000))); 11743 assign(t3, binop(Iop_CmpEQ32, 11744 unop(Iop_16Uto32, 11745 unop(Iop_32to16, getIReg(rt))), 11746 mkU32(0x00008000))); 11747 11748 assign(t4, IRExpr_ITE(binop(Iop_CmpNE32, 11749 binop(Iop_And32, 11750 unop(Iop_1Sto32, 11751 mkexpr(t2)), 11752 unop(Iop_1Sto32, 11753 mkexpr(t3))), 11754 mkU32(0)), 11755 mkU64(0x000000007fffffffULL), 11756 mkexpr(t1))); 11757 11758 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 11759 binop(Iop_And32, 11760 unop(Iop_1Sto32, 11761 mkexpr(t2)), 11762 unop(Iop_1Sto32, 11763 mkexpr(t3))), 11764 mkU32(0)), 11765 binop(Iop_Or32, 11766 getDSPControl(), 11767 binop(Iop_Shl32, 11768 mkU32(0x1), 11769 mkU8(ac+16))), 11770 getDSPControl())); 11771 /* Calculate second cross dot product and saturate if 11772 needed. */ 11773 assign(t5, unop(Iop_32Sto64, 11774 binop(Iop_Shl32, 11775 binop(Iop_Mul32, 11776 unop(Iop_16Sto32, 11777 unop(Iop_32to16, 11778 getIReg(rs))), 11779 unop(Iop_16Sto32, 11780 unop(Iop_32HIto16, 11781 getIReg(rt)))), 11782 mkU8(0x1)))); 11783 11784 /* If both input arguments are equal 0x8000, saturate 11785 intermediate product and write to DSPControl 11786 register. */ 11787 assign(t6, binop(Iop_CmpEQ32, 11788 unop(Iop_16Uto32, 11789 unop(Iop_32to16, getIReg(rs))), 11790 mkU32(0x00008000))); 11791 assign(t7, binop(Iop_CmpEQ32, 11792 unop(Iop_16Uto32, 11793 unop(Iop_32HIto16, getIReg(rt))), 11794 mkU32(0x00008000))); 11795 11796 assign(t8, IRExpr_ITE(binop(Iop_CmpNE32, 11797 binop(Iop_And32, 11798 unop(Iop_1Sto32, 11799 mkexpr(t6)), 11800 unop(Iop_1Sto32, 11801 mkexpr(t7))), 11802 mkU32(0)), 11803 mkU64(0x000000007fffffffULL), 11804 mkexpr(t5))); 11805 11806 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32, 11807 binop(Iop_And32, 11808 unop(Iop_1Sto32, 11809 mkexpr(t6)), 11810 unop(Iop_1Sto32, 11811 mkexpr(t7))), 11812 mkU32(0)), 11813 binop(Iop_Or32, 11814 getDSPControl(), 11815 binop(Iop_Shl32, 11816 mkU32(0x1), 11817 mkU8(ac+16))), 11818 getDSPControl())); 11819 /* Subtract intermediate products from value in the 11820 accumulator. */ 11821 assign(t9, 11822 binop(Iop_Sub64, 11823 mkexpr(t0), 11824 binop(Iop_Add64, mkexpr(t8), mkexpr(t4)))); 11825 11826 putAcc(ac, 11827 IRExpr_ITE(binop(Iop_CmpEQ32, 11828 binop(Iop_And32, 11829 unop(Iop_64HIto32, 11830 mkexpr(t9)), 11831 mkU32(0x80000000)), 11832 mkU32(0x0)), 11833 IRExpr_ITE(binop(Iop_CmpNE32, 11834 unop(Iop_64HIto32, 11835 binop(Iop_Shl64, 11836 mkexpr(t9), 11837 mkU8(1))), 11838 mkU32(0x0)), 11839 mkU64(0x000000007fffffffULL), 11840 mkexpr(t9)), 11841 IRExpr_ITE(binop(Iop_CmpNE32, 11842 unop(Iop_64HIto32, 11843 binop(Iop_Shl64, 11844 mkexpr(t9), 11845 mkU8(1))), 11846 mkU32(0xffffffff)), 11847 mkU64(0xffffffff80000000ULL), 11848 mkexpr(t9)))); 11849 assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32, 11850 unop(Iop_64to32, 11851 mkexpr(t9)), 11852 unop(Iop_64to32, 11853 getAcc(ac))), 11854 getDSPControl(), 11855 binop(Iop_Or32, 11856 getDSPControl(), 11857 binop(Iop_Shl32, 11858 mkU32(0x1), 11859 mkU8(ac+16))))); 11860 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32, 11861 unop(Iop_64HIto32, 11862 mkexpr(t9)), 11863 unop(Iop_64HIto32, 11864 getAcc(ac))), 11865 mkexpr(t10), 11866 binop(Iop_Or32, 11867 getDSPControl(), 11868 binop(Iop_Shl32, 11869 mkU32(0x1), 11870 mkU8(ac+16))))); 11871 break; 11872 } 11873 default: 11874 return -1; 11875 } 11876 break; /* end of DPAQ.W.PH */ 11877 } 11878 case 0x31: { /* APPEND */ 11879 switch(sa) { 11880 case 0x0: { /* APPEND */ 11881 DIP("append r%d, r%d, %d", rt, rs, rd); 11882 vassert(!mode64); 11883 t1 = newTemp(Ity_I32); 11884 t2 = newTemp(Ity_I32); 11885 t3 = newTemp(Ity_I32); 11886 11887 assign(t1, binop(Iop_Shl32, getIReg(rt), mkU8(rd))); 11888 11889 if (31 == rd) { 11890 putIReg(rt, binop(Iop_Or32, 11891 mkexpr(t1), 11892 binop(Iop_And32, 11893 getIReg(rs), 11894 mkU32(0x7fffffff)))); 11895 } else if (1 == rd) { 11896 putIReg(rt, 11897 binop(Iop_Or32, 11898 mkexpr(t1), 11899 binop(Iop_And32, 11900 getIReg(rs), mkU32(0x1)))); 11901 } else { 11902 assign(t2, 11903 unop(Iop_Not32, 11904 binop(Iop_Shl32, 11905 mkU32(0xffffffff), mkU8(rd)))); 11906 11907 putIReg(rt, binop(Iop_Or32, 11908 mkexpr(t1), 11909 binop(Iop_And32, 11910 getIReg(rs), mkexpr(t2)))); 11911 } 11912 break; 11913 } 11914 case 0x1: { /* PREPEND */ 11915 DIP("prepend r%d, r%d, %d", rt, rs, rd); 11916 vassert(!mode64); 11917 t1 = newTemp(Ity_I32); 11918 t2 = newTemp(Ity_I32); 11919 t3 = newTemp(Ity_I32); 11920 11921 if (0 != rd) { 11922 assign(t1, binop(Iop_Shr32, getIReg(rt), mkU8(rd))); 11923 11924 if (31 == rd) { 11925 putIReg(rt, binop(Iop_Or32, 11926 mkexpr(t1), 11927 binop(Iop_Shl32, 11928 binop(Iop_And32, 11929 getIReg(rs), 11930 mkU32(0x7fffffff)), 11931 mkU8(1)))); 11932 } else if (1 == rd) { 11933 putIReg(rt, binop(Iop_Or32, 11934 mkexpr(t1), 11935 binop(Iop_Shl32, 11936 binop(Iop_And32, 11937 getIReg(rs), 11938 mkU32(0x1)), 11939 mkU8(31)))); 11940 } else { 11941 assign(t2, binop(Iop_Add32, mkU32(rd), mkU32(0x1))); 11942 11943 assign(t3, unop(Iop_Not32, 11944 binop(Iop_Shl32, 11945 mkU32(0xffffffff), 11946 unop(Iop_32to8, mkexpr(t2))))); 11947 11948 putIReg(rt, binop(Iop_Or32, 11949 mkexpr(t1), 11950 binop(Iop_Shl32, 11951 binop(Iop_And32, 11952 getIReg(rs), 11953 mkexpr(t3)), 11954 mkU8(32-rd)))); 11955 } 11956 } 11957 break; 11958 } 11959 case 0x10: { /* BALIGN */ 11960 DIP("balign r%d, r%d, %d", rt, rs, rd); 11961 vassert(!mode64); 11962 t1 = newTemp(Ity_I32); 11963 t2 = newTemp(Ity_I32); 11964 t3 = newTemp(Ity_I32); 11965 11966 if ((2 != rd) && (0 != rd)) { 11967 assign(t1, binop(Iop_Shl32, 11968 binop(Iop_And32, 11969 mkU32(rd), mkU32(0x3)), 11970 mkU8(0x3))); 11971 assign(t2, binop(Iop_Shl32, 11972 getIReg(rt), 11973 unop(Iop_32to8, mkexpr(t1)))); 11974 assign(t3, binop(Iop_Shr32, 11975 getIReg(rs), 11976 unop(Iop_32to8, 11977 binop(Iop_Shl32, 11978 binop(Iop_Sub32, 11979 mkU32(0x4), 11980 binop(Iop_And32, 11981 mkU32(rd), 11982 mkU32(0x3))), 11983 mkU8(0x3))))); 11984 putIReg(rt, binop(Iop_Or32, mkexpr(t2), mkexpr(t3))); 11985 } 11986 break; 11987 } 11988 default: 11989 return -1; 11990 } 11991 break; /* end of APPEND */ 11992 } 11993 default: 11994 return -1; 11995 } 11996 break; 11997 } 11998 default: 11999 return -1; 12000 } 12001 return 0; 12002 } 12003 12004 /*------------------------------------------------------------*/ 12005 /*--- Disassemble a single instruction ---*/ 12006 /*------------------------------------------------------------*/ 12007 12008 /* Disassemble a single instruction into IR. The instruction is 12009 located in host memory at guest_instr, and has guest IP of 12010 guest_PC_curr_instr, which will have been set before the call 12011 here. */ 12012 12013 static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, 12014 Addr), 12015 Bool resteerCisOk, 12016 void* callback_opaque, 12017 Long delta64, 12018 const VexArchInfo* archinfo, 12019 const VexAbiInfo* abiinfo, 12020 Bool sigill_diag ) 12021 { 12022 IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7; 12023 12024 UInt opcode, cins, rs, rt, rd, sa, ft, fs, fd, fmt, tf, nd, function, 12025 trap_code, imm, instr_index, p, msb, lsb, size, rot, sel; 12026 /* Additional variables for instruction fields in DSP ASE insructions */ 12027 UInt ac; 12028 12029 DisResult dres; 12030 12031 static IRExpr *lastn = NULL; /* last jump addr */ 12032 static IRStmt *bstmt = NULL; /* branch (Exit) stmt */ 12033 12034 /* The running delta */ 12035 Int delta = (Int) delta64; 12036 12037 /* Holds eip at the start of the insn, so that we can print 12038 consistent error messages for unimplemented insns. */ 12039 Int delta_start = delta; 12040 12041 /* Are we in a delay slot ? */ 12042 Bool delay_slot_branch, likely_delay_slot, delay_slot_jump; 12043 12044 /* Set result defaults. */ 12045 dres.whatNext = Dis_Continue; 12046 dres.len = 0; 12047 dres.continueAt = 0; 12048 dres.jk_StopHere = Ijk_INVALID; 12049 12050 delay_slot_branch = likely_delay_slot = delay_slot_jump = False; 12051 12052 const UChar *code = guest_code + delta; 12053 cins = getUInt(code); 12054 DIP("\t0x%lx:\t0x%08x\t", (long)guest_PC_curr_instr, cins); 12055 12056 if (delta != 0) { 12057 if (branch_or_jump(guest_code + delta - 4)) { 12058 if (lastn == NULL && bstmt == NULL) { 12059 vassert(0); 12060 } else { 12061 dres.whatNext = Dis_StopHere; 12062 if (lastn != NULL) { 12063 delay_slot_jump = True; 12064 } else if (bstmt != NULL) { 12065 delay_slot_branch = True; 12066 } 12067 } 12068 } 12069 12070 if (branch_or_link_likely(guest_code + delta - 4)) { 12071 likely_delay_slot = True; 12072 } 12073 } 12074 12075 /* Spot "Special" instructions (see comment at top of file). */ 12076 { 12077 /* Spot the 16-byte preamble: 12078 ****mips32**** 12079 "srl $0, $0, 13 12080 "srl $0, $0, 29 12081 "srl $0, $0, 3 12082 "srl $0, $0, 19 12083 12084 ****mips64**** 12085 dsll $0, $0, 3 12086 dsll $0, $0, 13 12087 dsll $0, $0, 29 12088 dsll $0, $0, 19 */ 12089 12090 UInt word1 = mode64 ? 0xF8 : 0x342; 12091 UInt word2 = mode64 ? 0x378 : 0x742; 12092 UInt word3 = mode64 ? 0x778 : 0xC2; 12093 UInt word4 = mode64 ? 0x4F8 : 0x4C2; 12094 if (getUInt(code + 0) == word1 && getUInt(code + 4) == word2 && 12095 getUInt(code + 8) == word3 && getUInt(code + 12) == word4) { 12096 /* Got a "Special" instruction preamble. Which one is it? */ 12097 if (getUInt(code + 16) == 0x01ad6825 /* or $13, $13, $13 */ ) { 12098 /* $11 = client_request ( $12 ) */ 12099 DIP("$11 = client_request ( $12 )"); 12100 if (mode64) 12101 putPC(mkU64(guest_PC_curr_instr + 20)); 12102 else 12103 putPC(mkU32(guest_PC_curr_instr + 20)); 12104 dres.jk_StopHere = Ijk_ClientReq; 12105 dres.whatNext = Dis_StopHere; 12106 12107 goto decode_success; 12108 } else if (getUInt(code + 16) == 0x01ce7025 /* or $14, $14, $14 */ ) { 12109 /* $11 = guest_NRADDR */ 12110 DIP("$11 = guest_NRADDR"); 12111 dres.len = 20; 12112 delta += 20; 12113 if (mode64) 12114 putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS64State, 12115 guest_NRADDR), Ity_I64)); 12116 else 12117 putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS32State, 12118 guest_NRADDR), Ity_I32)); 12119 goto decode_success; 12120 } else if (getUInt(code + 16) == 0x01ef7825 /* or $15, $15, $15 */ ) { 12121 /* branch-and-link-to-noredir $25 */ 12122 DIP("branch-and-link-to-noredir $25"); 12123 if (mode64) 12124 putIReg(31, mkU64(guest_PC_curr_instr + 20)); 12125 else 12126 putIReg(31, mkU32(guest_PC_curr_instr + 20)); 12127 putPC(getIReg(25)); 12128 dres.jk_StopHere = Ijk_NoRedir; 12129 dres.whatNext = Dis_StopHere; 12130 goto decode_success; 12131 } else if (getUInt(code + 16) == 0x016b5825 /* or $11,$11,$11 */ ) { 12132 /* IR injection */ 12133 DIP("IR injection"); 12134 #if defined (_MIPSEL) 12135 vex_inject_ir(irsb, Iend_LE); 12136 #elif defined (_MIPSEB) 12137 vex_inject_ir(irsb, Iend_BE); 12138 #endif 12139 if (mode64) { 12140 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMSTART), 12141 mkU64(guest_PC_curr_instr))); 12142 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_CMLEN), 12143 mkU64(20))); 12144 12145 putPC(mkU64(guest_PC_curr_instr + 20)); 12146 } else { 12147 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMSTART), 12148 mkU32(guest_PC_curr_instr))); 12149 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_CMLEN), 12150 mkU32(20))); 12151 12152 putPC(mkU32(guest_PC_curr_instr + 20)); 12153 } 12154 dres.whatNext = Dis_StopHere; 12155 dres.jk_StopHere = Ijk_InvalICache; 12156 dres.len = 20; 12157 delta += 20; 12158 goto decode_success; 12159 } 12160 12161 /* We don't know what it is. Set opc1/opc2 so decode_failure 12162 can print the insn following the Special-insn preamble. */ 12163 delta += 16; 12164 goto decode_failure; 12165 /*NOTREACHED*/} 12166 } 12167 12168 opcode = get_opcode(cins); 12169 imm = get_imm(cins); 12170 rs = get_rs(cins); 12171 rt = get_rt(cins); 12172 rd = get_rd(cins); 12173 sa = get_sa(cins); 12174 fs = get_fs(cins); 12175 fd = get_fd(cins); 12176 ft = get_ft(cins); 12177 tf = get_tf(cins); 12178 nd = get_nd(cins); 12179 sel = get_sel(cins); 12180 fmt = get_fmt(cins); 12181 instr_index = get_instr_index(cins); 12182 trap_code = get_code(cins); 12183 function = get_function(cins); 12184 IRType ty = mode64 ? Ity_I64 : Ity_I32; 12185 IRType tyF = fp_mode64 ? Ity_F64 : Ity_F32; 12186 12187 ac = get_acNo(cins); 12188 12189 switch (opcode) { 12190 12191 case 0x03: /* JAL */ 12192 DIP("jal 0x%x", instr_index); 12193 if (mode64) { 12194 putIReg(31, mkU64(guest_PC_curr_instr + 8)); 12195 t0 = newTemp(ty); 12196 assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) | 12197 (instr_index << 2))); 12198 } else { 12199 putIReg(31, mkU32(guest_PC_curr_instr + 8)); 12200 t0 = newTemp(ty); 12201 assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) | 12202 (instr_index << 2))); 12203 } 12204 lastn = mkexpr(t0); 12205 break; 12206 case 0x02: /* J */ 12207 DIP("j 0x%x", instr_index); 12208 t0 = newTemp(ty); 12209 if (mode64) 12210 assign(t0, mkU64((guest_PC_curr_instr & 0xFFFFFFFFF0000000ULL) | 12211 (instr_index << 2))); 12212 else 12213 assign(t0, mkU32((guest_PC_curr_instr & 0xF0000000) | 12214 (instr_index << 2))); 12215 lastn = mkexpr(t0); 12216 break; 12217 12218 case 0x11: { /* COP1 */ 12219 if (fmt == 0x3 && fd == 0 && function == 0) { /* MFHC1 */ 12220 DIP("mfhc1 r%d, f%d", rt, fs); 12221 if (fp_mode64) { 12222 t0 = newTemp(Ity_I64); 12223 t1 = newTemp(Ity_I32); 12224 assign(t0, unop(Iop_ReinterpF64asI64, getDReg(fs))); 12225 assign(t1, unop(Iop_64HIto32, mkexpr(t0))); 12226 putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True)); 12227 } else { 12228 ILLEGAL_INSTRUCTON; 12229 } 12230 break; 12231 } else if (fmt == 0x7 && fd == 0 && function == 0) { /* MTHC1 */ 12232 DIP("mthc1 r%d, f%d", rt, fs); 12233 if (fp_mode64) { 12234 t0 = newTemp(Ity_I64); 12235 assign(t0, binop(Iop_32HLto64, getIReg(rt), 12236 unop(Iop_ReinterpF32asI32, 12237 getLoFromF64(Ity_F64 /* 32FPR mode. */, 12238 getDReg(fs))))); 12239 putDReg(fs, unop(Iop_ReinterpI64asF64, mkexpr(t0))); 12240 } else { 12241 ILLEGAL_INSTRUCTON; 12242 } 12243 break; 12244 } else if (fmt == 0x8) { /* BC */ 12245 /* FcConditionalCode(bc1_cc) */ 12246 UInt bc1_cc = get_bc1_cc(cins); 12247 t1 = newTemp(Ity_I1); 12248 t2 = newTemp(Ity_I32); 12249 t3 = newTemp(Ity_I1); 12250 12251 assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(bc1_cc))); 12252 assign(t2, IRExpr_ITE(mkexpr(t1), 12253 binop(Iop_And32, 12254 binop(Iop_Shr32, getFCSR(), mkU8(23)), 12255 mkU32(0x1)), 12256 binop(Iop_And32, 12257 binop(Iop_Shr32, getFCSR(), 12258 mkU8(24 + bc1_cc)), 12259 mkU32(0x1)))); 12260 12261 if (tf == 1 && nd == 0) { 12262 /* branch on true */ 12263 DIP("bc1t %d, %d", bc1_cc, imm); 12264 assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2))); 12265 dis_branch(False, mkexpr(t3), imm, &bstmt); 12266 break; 12267 } else if (tf == 0 && nd == 0) { 12268 /* branch on false */ 12269 DIP("bc1f %d, %d", bc1_cc, imm); 12270 assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2))); 12271 dis_branch(False, mkexpr(t3), imm, &bstmt); 12272 break; 12273 } else if (nd == 1 && tf == 0) { 12274 DIP("bc1fl %d, %d", bc1_cc, imm); 12275 lastn = dis_branch_likely(binop(Iop_CmpNE32, mkexpr(t2), 12276 mkU32(0x0)), imm); 12277 break; 12278 } else if (nd == 1 && tf == 1) { 12279 DIP("bc1tl %d, %d", bc1_cc, imm); 12280 lastn = dis_branch_likely(binop(Iop_CmpEQ32, mkexpr(t2), 12281 mkU32(0x0)), imm); 12282 break; 12283 } else 12284 goto decode_failure; 12285 } else { 12286 switch (function) { 12287 case 0x4: { /* SQRT.fmt */ 12288 switch (fmt) { 12289 case 0x10: { /* S */ 12290 IRExpr *rm = get_IR_roundingmode(); 12291 putFReg(fd, mkWidenFromF32(tyF, binop(Iop_SqrtF32, rm, 12292 getLoFromF64(tyF, getFReg(fs))))); 12293 break; 12294 } 12295 case 0x11: { /* D */ 12296 IRExpr *rm = get_IR_roundingmode(); 12297 putDReg(fd, binop(Iop_SqrtF64, rm, getDReg(fs))); 12298 break; 12299 } 12300 default: 12301 goto decode_failure; 12302 } 12303 } 12304 break; 12305 case 0x5: /* abs.fmt */ 12306 switch (fmt) { 12307 case 0x10: /* S */ 12308 DIP("abs.s f%d, f%d", fd, fs); 12309 putFReg(fd, mkWidenFromF32(tyF, unop(Iop_AbsF32, 12310 getLoFromF64(tyF, getFReg(fs))))); 12311 break; 12312 case 0x11: /* D */ 12313 DIP("abs.d f%d, f%d", fd, fs); 12314 putDReg(fd, unop(Iop_AbsF64, getDReg(fs))); 12315 break; 12316 default: 12317 goto decode_failure; 12318 } 12319 break; /* case 0x5 */ 12320 12321 case 0x02: /* MUL.fmt */ 12322 switch (fmt) { 12323 case 0x11: { /* D */ 12324 DIP("mul.d f%d, f%d, f%d", fd, fs, ft); 12325 IRExpr *rm = get_IR_roundingmode(); 12326 putDReg(fd, triop(Iop_MulF64, rm, getDReg(fs), 12327 getDReg(ft))); 12328 break; 12329 } 12330 case 0x10: { /* S */ 12331 DIP("mul.s f%d, f%d, f%d", fd, fs, ft); 12332 IRExpr *rm = get_IR_roundingmode(); 12333 putFReg(fd, mkWidenFromF32(tyF, triop(Iop_MulF32, rm, 12334 getLoFromF64(tyF, getFReg(fs)), 12335 getLoFromF64(tyF, getFReg(ft))))); 12336 break; 12337 } 12338 default: 12339 goto decode_failure; 12340 } 12341 break; /* MUL.fmt */ 12342 12343 case 0x03: /* DIV.fmt */ 12344 switch (fmt) { 12345 case 0x11: { /* D */ 12346 DIP("div.d f%d, f%d, f%d", fd, fs, ft); 12347 IRExpr *rm = get_IR_roundingmode(); 12348 putDReg(fd, triop(Iop_DivF64, rm, getDReg(fs), 12349 getDReg(ft))); 12350 break; 12351 } 12352 case 0x10: { /* S */ 12353 DIP("div.s f%d, f%d, f%d", fd, fs, ft); 12354 calculateFCSR(fs, ft, DIVS, False, 2); 12355 IRExpr *rm = get_IR_roundingmode(); 12356 putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm, 12357 getLoFromF64(tyF, getFReg(fs)), 12358 getLoFromF64(tyF, getFReg(ft))))); 12359 break; 12360 } 12361 default: 12362 goto decode_failure; 12363 } 12364 break; /* DIV.fmt */ 12365 12366 case 0x01: /* SUB.fmt */ 12367 switch (fmt) { 12368 case 0x11: { /* D */ 12369 DIP("sub.d f%d, f%d, f%d", fd, fs, ft); 12370 calculateFCSR(fs, ft, SUBD, False, 2); 12371 IRExpr *rm = get_IR_roundingmode(); 12372 putDReg(fd, triop(Iop_SubF64, rm, getDReg(fs), 12373 getDReg(ft))); 12374 break; 12375 } 12376 case 0x10: { /* S */ 12377 DIP("sub.s f%d, f%d, f%d", fd, fs, ft); 12378 calculateFCSR(fs, ft, SUBS, True, 2); 12379 IRExpr *rm = get_IR_roundingmode(); 12380 putFReg(fd, mkWidenFromF32(tyF, triop(Iop_SubF32, rm, 12381 getLoFromF64(tyF, getFReg(fs)), 12382 getLoFromF64(tyF, getFReg(ft))))); 12383 break; 12384 } 12385 default: 12386 goto decode_failure; 12387 } 12388 break; /* SUB.fmt */ 12389 12390 case 0x06: /* MOV.fmt */ 12391 switch (fmt) { 12392 case 0x11: /* D */ 12393 DIP("mov.d f%d, f%d", fd, fs); 12394 if (fp_mode64) { 12395 putDReg(fd, getDReg(fs)); 12396 } else { 12397 putFReg(fd, getFReg(fs)); 12398 putFReg(fd + 1, getFReg(fs + 1)); 12399 } 12400 break; 12401 case 0x10: /* S */ 12402 DIP("mov.s f%d, f%d", fd, fs); 12403 putFReg(fd, getFReg(fs)); 12404 break; 12405 default: 12406 goto decode_failure; 12407 } 12408 break; /* MOV.fmt */ 12409 12410 case 0x7: /* neg.fmt */ 12411 switch (fmt) { 12412 case 0x10: /* S */ 12413 DIP("neg.s f%d, f%d", fd, fs); 12414 putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, 12415 getLoFromF64(tyF, getFReg(fs))))); 12416 break; 12417 case 0x11: /* D */ 12418 DIP("neg.d f%d, f%d", fd, fs); 12419 putDReg(fd, unop(Iop_NegF64, getDReg(fs))); 12420 break; 12421 default: 12422 goto decode_failure; 12423 } 12424 break; /* case 0x7 */ 12425 12426 case 0x08: /* ROUND.L.fmt */ 12427 switch (fmt) { 12428 case 0x10: /* S */ 12429 DIP("round.l.s f%d, f%d", fd, fs); 12430 if (fp_mode64) { 12431 calculateFCSR(fs, 0, ROUNDLS, True, 1); 12432 t0 = newTemp(Ity_I64); 12433 12434 assign(t0, binop(Iop_F32toI64S, mkU32(0x0), 12435 getLoFromF64(Ity_F64, getFReg(fs)))); 12436 12437 putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); 12438 } else { 12439 ILLEGAL_INSTRUCTON; 12440 } 12441 break; 12442 case 0x11: /* D */ 12443 DIP("round.l.d f%d, f%d", fd, fs); 12444 if (fp_mode64) { 12445 calculateFCSR(fs, 0, ROUNDLD, False, 1); 12446 putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x0), 12447 getDReg(fs))); 12448 } else { 12449 ILLEGAL_INSTRUCTON; 12450 } 12451 break; 12452 default: 12453 goto decode_failure; 12454 12455 } 12456 break; /* ROUND.L.fmt */ 12457 12458 case 0x09: /* TRUNC.L.fmt */ 12459 switch (fmt) { 12460 case 0x10: /* S */ 12461 DIP("trunc.l.s f%d, f%d", fd, fs); 12462 if (fp_mode64) { 12463 calculateFCSR(fs, 0, TRUNCLS, True, 1); 12464 t0 = newTemp(Ity_I64); 12465 assign(t0, binop(Iop_F32toI64S, mkU32(0x3), 12466 getLoFromF64(Ity_F64, getFReg(fs)))); 12467 12468 putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); 12469 } else { 12470 ILLEGAL_INSTRUCTON; 12471 } 12472 break; 12473 case 0x11: /* D */ 12474 DIP("trunc.l.d f%d, f%d", fd, fs); 12475 if (fp_mode64) { 12476 calculateFCSR(fs, 0, TRUNCLD, False, 1); 12477 putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x3), 12478 getDReg(fs))); 12479 } else { 12480 ILLEGAL_INSTRUCTON; 12481 } 12482 break; 12483 default: 12484 goto decode_failure; 12485 } 12486 break; /* TRUNC.L.fmt */ 12487 12488 case 0x15: /* RECIP.fmt */ 12489 switch (fmt) { 12490 case 0x10: { /* S */ 12491 DIP("recip.s f%d, f%d", fd, fs); 12492 IRExpr *rm = get_IR_roundingmode(); 12493 putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, 12494 rm, unop(Iop_ReinterpI32asF32, 12495 mkU32(ONE_SINGLE)), getLoFromF64(tyF, 12496 getFReg(fs))))); 12497 break; 12498 } 12499 case 0x11: { /* D */ 12500 DIP("recip.d f%d, f%d", fd, fs); 12501 IRExpr *rm = get_IR_roundingmode(); 12502 /* putDReg(fd, 1.0/getDreg(fs)); */ 12503 putDReg(fd, triop(Iop_DivF64, rm, 12504 unop(Iop_ReinterpI64asF64, 12505 mkU64(ONE_DOUBLE)), getDReg(fs))); 12506 break; 12507 } 12508 default: 12509 goto decode_failure; 12510 12511 } 12512 break; /* case 0x15 */ 12513 12514 case 0x13: /* MOVN.fmt */ 12515 switch (fmt) { 12516 case 0x10: /* S */ 12517 DIP("movn.s f%d, f%d, r%d", fd, fs, rt); 12518 t1 = newTemp(Ity_F64); 12519 t2 = newTemp(Ity_F64); 12520 t3 = newTemp(Ity_I1); 12521 t4 = newTemp(Ity_F64); 12522 if (mode64) { 12523 assign(t1, getFReg(fs)); 12524 assign(t2, getFReg(fd)); 12525 assign(t3, binop(Iop_CmpNE64, mkU64(0), getIReg(rt))); 12526 } else { 12527 if (fp_mode64) { 12528 assign(t1, getFReg(fs)); 12529 assign(t2, getFReg(fd)); 12530 assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt))); 12531 } else { 12532 assign(t1, unop(Iop_F32toF64, getFReg(fs))); 12533 assign(t2, unop(Iop_F32toF64, getFReg(fd))); 12534 assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt))); 12535 } 12536 } 12537 12538 assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t1), mkexpr(t2))); 12539 if (fp_mode64) { 12540 IRTemp f = newTemp(Ity_F64); 12541 IRTemp fd_hi = newTemp(Ity_I32); 12542 t5 = newTemp(Ity_I64); 12543 assign(f, getFReg(fd)); 12544 assign(fd_hi, unop(Iop_64HIto32, unop(Iop_ReinterpF64asI64, 12545 mkexpr(f)))); 12546 12547 assign(t5, mkWidenFrom32(Ity_I64, unop(Iop_64to32, 12548 unop(Iop_ReinterpF64asI64, mkexpr(t4))), True)); 12549 12550 putFReg(fd, unop (Iop_ReinterpI64asF64, mkexpr(t5))); 12551 } else 12552 putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(), 12553 mkexpr(t4))); 12554 break; 12555 case 0x11: /* D */ 12556 DIP("movn.d f%d, f%d, r%d", fd, fs, rt); 12557 12558 t3 = newTemp(Ity_I1); 12559 t4 = newTemp(Ity_F64); 12560 12561 if (mode64) 12562 assign(t3, binop(Iop_CmpNE64, mkU64(0), getIReg(rt))); 12563 else 12564 assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt))); 12565 12566 putDReg(fd, IRExpr_ITE(mkexpr(t3), getDReg(fs), getDReg(fd))); 12567 break; 12568 default: 12569 goto decode_failure; 12570 } 12571 break; /* MOVN.fmt */ 12572 12573 case 0x12: /* MOVZ.fmt */ 12574 switch (fmt) { 12575 case 0x10: /* S */ 12576 DIP("movz.s f%d, f%d, r%d", fd, fs, rt); 12577 12578 t1 = newTemp(Ity_F64); 12579 t2 = newTemp(Ity_F64); 12580 t3 = newTemp(Ity_I1); 12581 t4 = newTemp(Ity_F64); 12582 if (fp_mode64) { 12583 assign(t1, getFReg(fs)); 12584 assign(t2, getFReg(fd)); 12585 if (mode64) 12586 assign(t3, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt))); 12587 else 12588 assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt))); 12589 } else { 12590 assign(t1, unop(Iop_F32toF64, getFReg(fs))); 12591 assign(t2, unop(Iop_F32toF64, getFReg(fd))); 12592 assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt))); 12593 } 12594 assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t1), mkexpr(t2))); 12595 12596 if (fp_mode64) { 12597 IRTemp f = newTemp(Ity_F64); 12598 IRTemp fd_hi = newTemp(Ity_I32); 12599 t7 = newTemp(Ity_I64); 12600 assign(f, getFReg(fd)); 12601 assign(fd_hi, unop(Iop_64HIto32, 12602 unop(Iop_ReinterpF64asI64, mkexpr(f)))); 12603 assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32, 12604 unop(Iop_ReinterpF64asI64, mkexpr(t4))), True)); 12605 12606 putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7))); 12607 } else 12608 putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(), 12609 mkexpr(t4))); 12610 12611 break; 12612 case 0x11: /* D */ 12613 DIP("movz.d f%d, f%d, r%d", fd, fs, rt); 12614 t3 = newTemp(Ity_I1); 12615 t4 = newTemp(Ity_F64); 12616 if (mode64) 12617 assign(t3, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt))); 12618 else 12619 assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt))); 12620 12621 putDReg(fd, IRExpr_ITE(mkexpr(t3), getDReg(fs), getDReg(fd))); 12622 break; 12623 default: 12624 goto decode_failure; 12625 } 12626 break; /* MOVZ.fmt */ 12627 12628 case 0x11: /* MOVT.fmt */ 12629 if (tf == 1) { 12630 UInt mov_cc = get_mov_cc(cins); 12631 switch (fmt) { /* MOVCF = 010001 */ 12632 case 0x11: /* D */ 12633 DIP("movt.d f%d, f%d, %d", fd, fs, mov_cc); 12634 t1 = newTemp(Ity_I1); 12635 t2 = newTemp(Ity_I32); 12636 t3 = newTemp(Ity_I1); 12637 t4 = newTemp(Ity_F64); 12638 12639 assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc))); 12640 assign(t2, IRExpr_ITE(mkexpr(t1), 12641 binop(Iop_And32, 12642 binop(Iop_Shr32, getFCSR(), 12643 mkU8(23)), 12644 mkU32(0x1)), 12645 binop(Iop_And32, 12646 binop(Iop_Shr32, getFCSR(), 12647 mkU8(24 + mov_cc)), 12648 mkU32(0x1)) 12649 )); 12650 12651 assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2))); 12652 assign(t4, IRExpr_ITE(mkexpr(t3), 12653 getDReg(fs), getDReg(fd))); 12654 putDReg(fd, mkexpr(t4)); 12655 break; 12656 case 0x10: /* S */ 12657 DIP("movt.s f%d, f%d, %d", fd, fs, mov_cc); 12658 t1 = newTemp(Ity_I1); 12659 t2 = newTemp(Ity_I32); 12660 t3 = newTemp(Ity_I1); 12661 t4 = newTemp(Ity_F64); 12662 t5 = newTemp(Ity_F64); 12663 t6 = newTemp(Ity_F64); 12664 t7 = newTemp(Ity_I64); 12665 12666 if (fp_mode64) { 12667 assign(t5, getFReg(fs)); 12668 assign(t6, getFReg(fd)); 12669 } else { 12670 assign(t5, unop(Iop_F32toF64, getFReg(fs))); 12671 assign(t6, unop(Iop_F32toF64, getFReg(fd))); 12672 } 12673 12674 assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc))); 12675 assign(t2, IRExpr_ITE(mkexpr(t1), 12676 binop(Iop_And32, 12677 binop(Iop_Shr32, getFCSR(), 12678 mkU8(23)), 12679 mkU32(0x1)), 12680 binop(Iop_And32, 12681 binop(Iop_Shr32, getFCSR(), 12682 mkU8(24 + mov_cc)), 12683 mkU32(0x1)) 12684 )); 12685 12686 assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2))); 12687 assign(t4, IRExpr_ITE(mkexpr(t3), 12688 mkexpr(t5), mkexpr(t6))); 12689 12690 if (fp_mode64) { 12691 IRTemp f = newTemp(Ity_F64); 12692 IRTemp fd_hi = newTemp(Ity_I32); 12693 assign(f, getFReg(fd)); 12694 assign(fd_hi, unop(Iop_64HIto32, 12695 unop(Iop_ReinterpF64asI64, mkexpr(f)))); 12696 assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32, 12697 unop(Iop_ReinterpF64asI64, mkexpr(t4))), 12698 True)); 12699 12700 putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7))); 12701 } else 12702 putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(), 12703 mkexpr(t4))); 12704 break; 12705 default: 12706 goto decode_failure; 12707 } 12708 } else if (tf == 0) /* movf.fmt */ 12709 { 12710 UInt mov_cc = get_mov_cc(cins); 12711 switch (fmt) /* MOVCF = 010001 */ 12712 { 12713 case 0x11: /* D */ 12714 DIP("movf.d f%d, f%d, %d", fd, fs, mov_cc); 12715 t1 = newTemp(Ity_I1); 12716 t2 = newTemp(Ity_I32); 12717 t3 = newTemp(Ity_I1); 12718 t4 = newTemp(Ity_F64); 12719 12720 assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc))); 12721 assign(t2, IRExpr_ITE(mkexpr(t1), 12722 binop(Iop_And32, 12723 binop(Iop_Shr32, getFCSR(), 12724 mkU8(23)), 12725 mkU32(0x1)), 12726 binop(Iop_And32, 12727 binop(Iop_Shr32, getFCSR(), 12728 mkU8(24 + mov_cc)), 12729 mkU32(0x1)) 12730 )); 12731 12732 assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2))); 12733 assign(t4, IRExpr_ITE(mkexpr(t3), 12734 getDReg(fs), getDReg(fd))); 12735 putDReg(fd, mkexpr(t4)); 12736 break; 12737 case 0x10: /* S */ 12738 DIP("movf.s f%d, f%d, %d", fd, fs, mov_cc); 12739 t1 = newTemp(Ity_I1); 12740 t2 = newTemp(Ity_I32); 12741 t3 = newTemp(Ity_I1); 12742 t4 = newTemp(Ity_F64); 12743 t5 = newTemp(Ity_F64); 12744 t6 = newTemp(Ity_F64); 12745 12746 if (fp_mode64) { 12747 assign(t5, getFReg(fs)); 12748 assign(t6, getFReg(fd)); 12749 } else { 12750 assign(t5, unop(Iop_F32toF64, getFReg(fs))); 12751 assign(t6, unop(Iop_F32toF64, getFReg(fd))); 12752 } 12753 12754 assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc))); 12755 assign(t2, IRExpr_ITE(mkexpr(t1), 12756 binop(Iop_And32, 12757 binop(Iop_Shr32, getFCSR(), 12758 mkU8(23)), 12759 mkU32(0x1)), 12760 binop(Iop_And32, 12761 binop(Iop_Shr32, getFCSR(), 12762 mkU8(24 + mov_cc)), 12763 mkU32(0x1)) 12764 )); 12765 12766 assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2))); 12767 assign(t4, IRExpr_ITE(mkexpr(t3), 12768 mkexpr(t5), mkexpr(t6))); 12769 12770 if (fp_mode64) { 12771 IRTemp f = newTemp(Ity_F64); 12772 IRTemp fd_hi = newTemp(Ity_I32); 12773 t7 = newTemp(Ity_I64); 12774 assign(f, getFReg(fd)); 12775 assign(fd_hi, unop(Iop_64HIto32, 12776 unop(Iop_ReinterpF64asI64, mkexpr(f)))); 12777 assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32, 12778 unop(Iop_ReinterpF64asI64, mkexpr(t4))), 12779 True)); 12780 12781 putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7))); 12782 } else 12783 putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(), 12784 mkexpr(t4))); 12785 break; 12786 default: 12787 goto decode_failure; 12788 } 12789 } 12790 12791 break; /* MOVT.fmt */ 12792 12793 case 0x0: /* add.fmt */ 12794 switch (fmt) { 12795 case 0x10: { /* S */ 12796 DIP("add.s f%d, f%d, f%d", fd, fs, ft); 12797 calculateFCSR(fs, ft, ADDS, True, 2); 12798 IRExpr *rm = get_IR_roundingmode(); 12799 putFReg(fd, mkWidenFromF32(tyF, triop(Iop_AddF32, rm, 12800 getLoFromF64(tyF, getFReg(fs)), 12801 getLoFromF64(tyF, getFReg(ft))))); 12802 break; 12803 } 12804 case 0x11: { /* D */ 12805 DIP("add.d f%d, f%d, f%d", fd, fs, ft); 12806 calculateFCSR(fs, ft, ADDD, False, 2); 12807 IRExpr *rm = get_IR_roundingmode(); 12808 putDReg(fd, triop(Iop_AddF64, rm, getDReg(fs), getDReg(ft))); 12809 break; 12810 } 12811 12812 case 0x4: /* MTC1 (Move Word to Floating Point) */ 12813 DIP("mtc1 r%d, f%d", rt, fs); 12814 if (fp_mode64) { 12815 t0 = newTemp(Ity_I32); 12816 t1 = newTemp(Ity_F32); 12817 assign(t0, mkNarrowTo32(ty, getIReg(rt))); 12818 assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0))); 12819 12820 putFReg(fs, mkWidenFromF32(tyF, mkexpr(t1))); 12821 } else 12822 putFReg(fs, unop(Iop_ReinterpI32asF32, getIReg(rt))); 12823 break; 12824 12825 case 0x5: /* Doubleword Move to Floating Point DMTC1; MIPS64 */ 12826 DIP("dmtc1 r%d, f%d", rt, fs); 12827 vassert(mode64); 12828 putFReg(fs, unop(Iop_ReinterpI64asF64, getIReg(rt))); 12829 break; 12830 12831 case 0x0: /* MFC1 */ 12832 DIP("mfc1 r%d, f%d", rt, fs); 12833 if (fp_mode64) { 12834 t0 = newTemp(Ity_I64); 12835 t1 = newTemp(Ity_I32); 12836 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12837 assign(t1, unop(Iop_64to32, mkexpr(t0))); 12838 putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True)); 12839 } else 12840 putIReg(rt, unop(Iop_ReinterpF32asI32, getFReg(fs))); 12841 break; 12842 12843 case 0x1: /* Doubleword Move from Floating Point DMFC1; 12844 MIPS64 */ 12845 DIP("dmfc1 r%d, f%d", rt, fs); 12846 putIReg(rt, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12847 break; 12848 12849 case 0x6: /* CTC1 */ 12850 DIP("ctc1 r%d, f%d", rt, fs); 12851 t0 = newTemp(Ity_I32); 12852 t1 = newTemp(Ity_I32); 12853 t2 = newTemp(Ity_I32); 12854 t3 = newTemp(Ity_I32); 12855 t4 = newTemp(Ity_I32); 12856 t5 = newTemp(Ity_I32); 12857 t6 = newTemp(Ity_I32); 12858 assign(t0, mkNarrowTo32(ty, getIReg(rt))); 12859 if (fs == 25) { /* FCCR */ 12860 assign(t1, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0), 12861 mkU32(0x000000FE)), mkU8(24))); 12862 assign(t2, binop(Iop_And32, mkexpr(t0), 12863 mkU32(0x01000000))); 12864 assign(t3, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0), 12865 mkU32(0x00000001)), mkU8(23))); 12866 assign(t4, binop(Iop_And32, mkexpr(t0), 12867 mkU32(0x007FFFFF))); 12868 putFCSR(binop(Iop_Or32, binop(Iop_Or32, mkexpr(t1), 12869 mkexpr(t2)), binop(Iop_Or32, mkexpr(t3), 12870 mkexpr(t4)))); 12871 } else if (fs == 26) { /* FEXR */ 12872 assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFFFC0000))); 12873 assign(t2, binop(Iop_And32, mkexpr(t0), 12874 mkU32(0x0003F000))); 12875 assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00000F80))); 12876 assign(t4, binop(Iop_And32, mkexpr(t0), 12877 mkU32(0x0000007C))); 12878 assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x00000003))); 12879 putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, 12880 mkexpr(t1), mkexpr(t2)), binop(Iop_Or32, 12881 mkexpr(t3), mkexpr(t4))), mkexpr(t5))); 12882 } else if (fs == 28) { 12883 assign(t1, binop(Iop_And32, getFCSR(), mkU32(0xFE000000))); 12884 assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkexpr(t0), 12885 mkU32(0x00000002)), mkU8(22))); 12886 assign(t3, binop(Iop_And32, getFCSR(), mkU32(0x00FFF000))); 12887 assign(t4, binop(Iop_And32, mkexpr(t0), 12888 mkU32(0x00000F80))); 12889 assign(t5, binop(Iop_And32, getFCSR(), mkU32(0x0000007C))); 12890 assign(t6, binop(Iop_And32, mkexpr(t0), 12891 mkU32(0x00000003))); 12892 putFCSR(binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, 12893 mkexpr(t1), mkexpr(t2)), binop(Iop_Or32, 12894 mkexpr(t3), mkexpr(t4))), binop(Iop_Or32, 12895 mkexpr(t5), mkexpr(t6)))); 12896 } else if (fs == 31) { 12897 putFCSR(mkexpr(t0)); 12898 } 12899 break; 12900 case 0x2: /* CFC1 */ 12901 DIP("cfc1 r%d, f%d", rt, fs); 12902 t0 = newTemp(Ity_I32); 12903 t1 = newTemp(Ity_I32); 12904 t2 = newTemp(Ity_I32); 12905 t3 = newTemp(Ity_I32); 12906 t4 = newTemp(Ity_I32); 12907 t5 = newTemp(Ity_I32); 12908 t6 = newTemp(Ity_I32); 12909 assign(t0, getFCSR()); 12910 if (fs == 0) { 12911 putIReg(rt, mkWidenFrom32(ty, 12912 IRExpr_Get(offsetof(VexGuestMIPS32State, 12913 guest_FIR), 12914 Ity_I32), 12915 False)); 12916 } else if (fs == 25) { 12917 assign(t1, mkU32(0x000000FF)); 12918 assign(t2, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0), 12919 mkU32(0xFE000000)), mkU8(25))); 12920 assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0), 12921 mkU32(0x00800000)), mkU8(23))); 12922 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, 12923 binop(Iop_Or32, mkexpr(t1), mkexpr(t2)), 12924 mkexpr(t3)), False)); 12925 } else if (fs == 26) { 12926 assign(t1, mkU32(0xFFFFF07C)); 12927 assign(t2, binop(Iop_And32, mkexpr(t0), 12928 mkU32(0x0003F000))); 12929 assign(t3, binop(Iop_And32, mkexpr(t0), 12930 mkU32(0x0000007C))); 12931 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, 12932 binop(Iop_Or32, mkexpr(t1), mkexpr(t2)), 12933 mkexpr(t3)), False)); 12934 } else if (fs == 28) { 12935 assign(t1, mkU32(0x00000F87)); 12936 assign(t2, binop(Iop_And32, mkexpr(t0), 12937 mkU32(0x00000F83))); 12938 assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkexpr(t0), 12939 mkU32(0x01000000)), mkU8(22))); 12940 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, 12941 binop(Iop_Or32, mkexpr(t1), mkexpr(t2)), 12942 mkexpr(t3)), False)); 12943 } else if (fs == 31) { 12944 putIReg(rt, mkWidenFrom32(ty, getFCSR(), False)); 12945 } 12946 break; 12947 default: 12948 goto decode_failure; 12949 } 12950 break; 12951 12952 case 0x21: /* CVT.D */ 12953 switch (fmt) { 12954 case 0x10: /* S */ 12955 DIP("cvt.d.s f%d, f%d", fd, fs); 12956 calculateFCSR(fs, 0, CVTDS, True, 1); 12957 if (fp_mode64) { 12958 t0 = newTemp(Ity_I64); 12959 t1 = newTemp(Ity_I32); 12960 t3 = newTemp(Ity_F32); 12961 t4 = newTemp(Ity_F32); 12962 /* get lo half of FPR */ 12963 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12964 12965 assign(t1, unop(Iop_64to32, mkexpr(t0))); 12966 12967 assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1))); 12968 12969 putFReg(fd, unop(Iop_F32toF64, mkexpr(t3))); 12970 } else 12971 putDReg(fd, unop(Iop_F32toF64, getFReg(fs))); 12972 break; 12973 12974 case 0x14: 12975 DIP("cvt.d.w %d, %d", fd, fs); 12976 calculateFCSR(fs, 0, CVTDW, True, 1); 12977 if (fp_mode64) { 12978 t0 = newTemp(Ity_I64); 12979 t1 = newTemp(Ity_I32); 12980 t3 = newTemp(Ity_F32); 12981 t4 = newTemp(Ity_F32); 12982 /* get lo half of FPR */ 12983 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 12984 12985 assign(t1, unop(Iop_64to32, mkexpr(t0))); 12986 putDReg(fd,unop(Iop_I32StoF64, mkexpr(t1))); 12987 break; 12988 } else { 12989 t0 = newTemp(Ity_I32); 12990 assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs))); 12991 putDReg(fd, unop(Iop_I32StoF64, mkexpr(t0))); 12992 break; 12993 } 12994 12995 case 0x15: { /* L */ 12996 if (fp_mode64) { 12997 DIP("cvt.d.l %d, %d", fd, fs); 12998 calculateFCSR(fs, 0, CVTDL, False, 1); 12999 t0 = newTemp(Ity_I64); 13000 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 13001 13002 putFReg(fd, binop(Iop_I64StoF64, 13003 get_IR_roundingmode(), mkexpr(t0))); 13004 break; 13005 } else 13006 goto decode_failure; 13007 } 13008 default: 13009 goto decode_failure; 13010 } 13011 break; /* CVT.D */ 13012 13013 case 0x20: /* cvt.s */ 13014 switch (fmt) { 13015 case 0x14: /* W */ 13016 DIP("cvt.s.w %d, %d", fd, fs); 13017 calculateFCSR(fs, 0, CVTSW, True, 1); 13018 if (fp_mode64) { 13019 t0 = newTemp(Ity_I64); 13020 t1 = newTemp(Ity_I32); 13021 t3 = newTemp(Ity_F32); 13022 t4 = newTemp(Ity_F32); 13023 /* get lo half of FPR */ 13024 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 13025 13026 assign(t1, unop(Iop_64to32, mkexpr(t0))); 13027 putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I32StoF32, 13028 get_IR_roundingmode(), mkexpr(t1)))); 13029 } else { 13030 t0 = newTemp(Ity_I32); 13031 assign(t0, unop(Iop_ReinterpF32asI32, getFReg(fs))); 13032 putFReg(fd, binop(Iop_I32StoF32, get_IR_roundingmode(), 13033 mkexpr(t0))); 13034 } 13035 break; 13036 13037 case 0x11: /* D */ 13038 DIP("cvt.s.d %d, %d", fd, fs); 13039 calculateFCSR(fs, 0, CVTSD, False, 1); 13040 t0 = newTemp(Ity_F32); 13041 assign(t0, binop(Iop_F64toF32, get_IR_roundingmode(), 13042 getDReg(fs))); 13043 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t0))); 13044 break; 13045 13046 case 0x15: /* L */ 13047 DIP("cvt.s.l %d, %d", fd, fs); 13048 calculateFCSR(fs, 0, CVTSL, False, 1); 13049 t0 = newTemp(Ity_I64); 13050 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 13051 13052 putFReg(fd, mkWidenFromF32(tyF, binop(Iop_I64StoF32, 13053 get_IR_roundingmode(), mkexpr(t0)))); 13054 break; 13055 13056 default: 13057 goto decode_failure; 13058 } 13059 break; /* cvt.s */ 13060 13061 case 0x24: /* cvt.w */ 13062 switch (fmt) { 13063 case 0x10: /* S */ 13064 DIP("cvt.w.s %d, %d", fd, fs); 13065 calculateFCSR(fs, 0, CVTWS, True, 1); 13066 putFReg(fd, 13067 mkWidenFromF32(tyF, 13068 binop(Iop_RoundF32toInt, 13069 get_IR_roundingmode(), 13070 getLoFromF64(tyF, getFReg(fs)))) 13071 ); 13072 break; 13073 13074 case 0x11: 13075 DIP("cvt.w.d %d, %d", fd, fs); 13076 calculateFCSR(fs, 0, CVTWD, False, 1); 13077 t0 = newTemp(Ity_I32); 13078 t1 = newTemp(Ity_F32); 13079 assign(t0, binop(Iop_F64toI32S, get_IR_roundingmode(), 13080 getDReg(fs))); 13081 assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0))); 13082 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1))); 13083 break; 13084 13085 default: 13086 goto decode_failure; 13087 13088 } 13089 break; 13090 13091 case 0x25: /* cvt.l */ 13092 switch (fmt) { 13093 case 0x10: /* S */ 13094 DIP("cvt.l.s %d, %d", fd, fs); 13095 if (fp_mode64) { 13096 calculateFCSR(fs, 0, CVTLS, True, 1); 13097 t0 = newTemp(Ity_I64); 13098 13099 assign(t0, binop(Iop_F32toI64S, get_IR_roundingmode(), 13100 getLoFromF64(tyF, getFReg(fs)))); 13101 13102 putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); 13103 } else { 13104 ILLEGAL_INSTRUCTON; 13105 } 13106 break; 13107 13108 case 0x11: { /* D */ 13109 DIP("cvt.l.d %d, %d", fd, fs); 13110 if (fp_mode64) { 13111 calculateFCSR(fs, 0, CVTLD, False, 1); 13112 putDReg(fd, binop(Iop_RoundF64toInt, 13113 get_IR_roundingmode(), getDReg(fs))); 13114 } else { 13115 ILLEGAL_INSTRUCTON; 13116 } 13117 break; 13118 } 13119 13120 default: 13121 goto decode_failure; 13122 } 13123 break; 13124 13125 case 0x0B: /* FLOOR.L.fmt */ 13126 switch (fmt) { 13127 case 0x10: /* S */ 13128 DIP("floor.l.s %d, %d", fd, fs); 13129 if (fp_mode64) { 13130 calculateFCSR(fs, 0, FLOORLS, True, 1); 13131 t0 = newTemp(Ity_I64); 13132 13133 assign(t0, binop(Iop_F32toI64S, mkU32(0x1), 13134 getLoFromF64(tyF, getFReg(fs)))); 13135 13136 putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); 13137 } else { 13138 ILLEGAL_INSTRUCTON; 13139 } 13140 break; 13141 13142 case 0x11: /* D */ 13143 DIP("floor.l.d %d, %d", fd, fs); 13144 if (fp_mode64) { 13145 calculateFCSR(fs, 0, FLOORLD, False, 1); 13146 putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x1), 13147 getDReg(fs))); 13148 } else { 13149 ILLEGAL_INSTRUCTON; 13150 } 13151 break; 13152 default: 13153 goto decode_failure; 13154 } 13155 break; 13156 13157 case 0x0C: /* ROUND.W.fmt */ 13158 switch (fmt) { 13159 case 0x10: /* S */ 13160 DIP("round.w.s f%d, f%d", fd, fs); 13161 calculateFCSR(fs, 0, ROUNDWS, True, 1); 13162 if (fp_mode64) { 13163 t0 = newTemp(Ity_I64); 13164 t1 = newTemp(Ity_I32); 13165 t3 = newTemp(Ity_F32); 13166 t4 = newTemp(Ity_F32); 13167 /* get lo half of FPR */ 13168 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 13169 13170 assign(t1, unop(Iop_64to32, mkexpr(t0))); 13171 13172 assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1))); 13173 13174 assign(t4, binop(Iop_RoundF32toInt, mkU32(0x0), 13175 mkexpr(t3))); 13176 13177 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4))); 13178 } else 13179 putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x0), 13180 getFReg(fs))); 13181 break; 13182 13183 case 0x11: /* D */ 13184 DIP("round.w.d f%d, f%d", fd, fs); 13185 calculateFCSR(fs, 0, ROUNDWD, False, 1); 13186 if (fp_mode64) { 13187 t0 = newTemp(Ity_I32); 13188 assign(t0, binop(Iop_F64toI32S, mkU32(0x0), 13189 getDReg(fs))); 13190 putFReg(fd, mkWidenFromF32(tyF, 13191 unop(Iop_ReinterpI32asF32, mkexpr(t0)))); 13192 } else { 13193 t0 = newTemp(Ity_I32); 13194 13195 assign(t0, binop(Iop_F64toI32S, mkU32(0x0), 13196 getDReg(fs))); 13197 13198 putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0))); 13199 } 13200 break; 13201 default: 13202 goto decode_failure; 13203 13204 } 13205 break; /* ROUND.W.fmt */ 13206 13207 case 0x0F: /* FLOOR.W.fmt */ 13208 switch (fmt) { 13209 case 0x10: /* S */ 13210 DIP("floor.w.s f%d, f%d", fd, fs); 13211 calculateFCSR(fs, 0, FLOORWS, True, 1); 13212 if (fp_mode64) { 13213 t0 = newTemp(Ity_I64); 13214 t1 = newTemp(Ity_I32); 13215 t3 = newTemp(Ity_F32); 13216 t4 = newTemp(Ity_F32); 13217 /* get lo half of FPR */ 13218 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 13219 13220 assign(t1, unop(Iop_64to32, mkexpr(t0))); 13221 13222 assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1))); 13223 13224 assign(t4, binop(Iop_RoundF32toInt, mkU32(0x1), 13225 mkexpr(t3))); 13226 13227 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4))); 13228 } else 13229 putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x1), 13230 getFReg(fs))); 13231 break; 13232 13233 case 0x11: /* D */ 13234 DIP("floor.w.d f%d, f%d", fd, fs); 13235 calculateFCSR(fs, 0, FLOORWD, False, 1); 13236 if (fp_mode64) { 13237 t0 = newTemp(Ity_I32); 13238 assign(t0, binop(Iop_F64toI32S, mkU32(0x1), 13239 getDReg(fs))); 13240 putFReg(fd, mkWidenFromF32(tyF, 13241 unop(Iop_ReinterpI32asF32, mkexpr(t0)))); 13242 break; 13243 } else { 13244 t0 = newTemp(Ity_I32); 13245 13246 assign(t0, binop(Iop_F64toI32S, mkU32(0x1), 13247 getDReg(fs))); 13248 13249 putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0))); 13250 break; 13251 } 13252 default: 13253 goto decode_failure; 13254 13255 } 13256 break; /* FLOOR.W.fmt */ 13257 13258 case 0x0D: /* TRUNC.W */ 13259 switch (fmt) { 13260 case 0x10: /* S */ 13261 DIP("trunc.w.s %d, %d", fd, fs); 13262 calculateFCSR(fs, 0, TRUNCWS, True, 1); 13263 if (fp_mode64) { 13264 t0 = newTemp(Ity_I64); 13265 t1 = newTemp(Ity_I32); 13266 t3 = newTemp(Ity_F32); 13267 t4 = newTemp(Ity_F32); 13268 /* get lo half of FPR */ 13269 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 13270 13271 assign(t1, unop(Iop_64to32, mkexpr(t0))); 13272 13273 assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1))); 13274 13275 assign(t4, binop(Iop_RoundF32toInt, mkU32(0x3), 13276 mkexpr(t3))); 13277 13278 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4))); 13279 } else 13280 putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x3), 13281 getFReg(fs))); 13282 break; 13283 case 0x11: /* D */ 13284 DIP("trunc.w.d %d, %d", fd, fs); 13285 calculateFCSR(fs, 0, TRUNCWD, False, 1); 13286 if (fp_mode64) { 13287 t0 = newTemp(Ity_I32); 13288 13289 assign(t0, binop(Iop_F64toI32S, mkU32(0x3), 13290 getFReg(fs))); 13291 13292 putFReg(fd, mkWidenFromF32(tyF, 13293 unop(Iop_ReinterpI32asF32, mkexpr(t0)))); 13294 } else { 13295 t0 = newTemp(Ity_I32); 13296 13297 assign(t0, binop(Iop_F64toI32S, mkU32(0x3), 13298 getDReg(fs))); 13299 13300 putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0))); 13301 } 13302 break; 13303 default: 13304 goto decode_failure; 13305 13306 } 13307 break; 13308 13309 case 0x0E: /* CEIL.W.fmt */ 13310 switch (fmt) { 13311 case 0x10: /* S */ 13312 DIP("ceil.w.s %d, %d", fd, fs); 13313 calculateFCSR(fs, 0, CEILWS, True, 1); 13314 if (fp_mode64) { 13315 t0 = newTemp(Ity_I64); 13316 t1 = newTemp(Ity_I32); 13317 t3 = newTemp(Ity_F32); 13318 t4 = newTemp(Ity_F32); 13319 /* get lo half of FPR */ 13320 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); 13321 13322 assign(t1, unop(Iop_64to32, mkexpr(t0))); 13323 13324 assign(t3, unop(Iop_ReinterpI32asF32, mkexpr(t1))); 13325 13326 assign(t4, binop(Iop_RoundF32toInt, mkU32(0x2), 13327 mkexpr(t3))); 13328 13329 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t4))); 13330 } else 13331 putFReg(fd, binop(Iop_RoundF32toInt, mkU32(0x2), 13332 getFReg(fs))); 13333 break; 13334 13335 case 0x11: /* D */ 13336 DIP("ceil.w.d %d, %d", fd, fs); 13337 calculateFCSR(fs, 0, CEILWD, False, 1); 13338 if (!fp_mode64) { 13339 t0 = newTemp(Ity_I32); 13340 assign(t0, binop(Iop_F64toI32S, mkU32(0x2), 13341 getDReg(fs))); 13342 putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0))); 13343 } else { 13344 t0 = newTemp(Ity_I32); 13345 assign(t0, binop(Iop_F64toI32S, mkU32(0x2), 13346 getDReg(fs))); 13347 putFReg(fd, mkWidenFromF32(tyF, 13348 unop(Iop_ReinterpI32asF32, mkexpr(t0)))); 13349 } 13350 break; 13351 default: 13352 goto decode_failure; 13353 13354 } 13355 break; 13356 13357 case 0x0A: /* CEIL.L.fmt */ 13358 switch (fmt) { 13359 case 0x10: /* S */ 13360 DIP("ceil.l.s %d, %d", fd, fs); 13361 if (fp_mode64) { 13362 calculateFCSR(fs, 0, CEILLS, True, 1); 13363 t0 = newTemp(Ity_I64); 13364 13365 assign(t0, binop(Iop_F32toI64S, mkU32(0x2), 13366 getLoFromF64(tyF, getFReg(fs)))); 13367 13368 putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); 13369 } else { 13370 ILLEGAL_INSTRUCTON; 13371 } 13372 break; 13373 13374 case 0x11: /* D */ 13375 DIP("ceil.l.d %d, %d", fd, fs); 13376 if (fp_mode64) { 13377 calculateFCSR(fs, 0, CEILLD, False, 1); 13378 putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x2), 13379 getDReg(fs))); 13380 } else { 13381 ILLEGAL_INSTRUCTON; 13382 } 13383 break; 13384 13385 default: 13386 goto decode_failure; 13387 13388 } 13389 break; 13390 13391 case 0x16: /* RSQRT.fmt */ 13392 switch (fmt) { 13393 case 0x10: { /* S */ 13394 DIP("rsqrt.s %d, %d", fd, fs); 13395 IRExpr *rm = get_IR_roundingmode(); 13396 putFReg(fd, mkWidenFromF32(tyF, triop(Iop_DivF32, rm, 13397 unop(Iop_ReinterpI32asF32, mkU32(ONE_SINGLE)), 13398 binop(Iop_SqrtF32, rm, getLoFromF64(tyF, 13399 getFReg(fs)))))); 13400 break; 13401 } 13402 case 0x11: { /* D */ 13403 DIP("rsqrt.d %d, %d", fd, fs); 13404 IRExpr *rm = get_IR_roundingmode(); 13405 putDReg(fd, triop(Iop_DivF64, rm, 13406 unop(Iop_ReinterpI64asF64, 13407 mkU64(ONE_DOUBLE)), 13408 binop(Iop_SqrtF64, rm, getDReg(fs)))); 13409 break; 13410 } 13411 default: 13412 goto decode_failure; 13413 13414 } 13415 break; 13416 13417 default: 13418 if (dis_instr_CCondFmt(cins)) 13419 break; 13420 goto decode_failure; 13421 13422 } 13423 13424 } 13425 } 13426 break; /* COP1 */ 13427 case 0x10: /* COP0 */ 13428 if (rs == 0) { /* MFC0 */ 13429 DIP("mfc0 r%d, r%d, %d", rt, rd, sel); 13430 IRTemp val = newTemp(Ity_I32); 13431 IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(), mkU32(rd), mkU32(sel)); 13432 IRDirty *d = unsafeIRDirty_1_N(val, 13433 0, 13434 "mips32_dirtyhelper_mfc0", 13435 &mips32_dirtyhelper_mfc0, 13436 args); 13437 stmt(IRStmt_Dirty(d)); 13438 putIReg(rt, mkexpr(val)); 13439 } else if (rs == 1) { 13440 /* Doubleword Move from Coprocessor 0 - DMFC0; MIPS64 */ 13441 DIP("dmfc0 r%d, r%d, %d", rt, rd, sel); 13442 IRTemp val = newTemp(Ity_I64); 13443 IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(), mkU64(rd), mkU64(sel)); 13444 IRDirty *d = unsafeIRDirty_1_N(val, 13445 0, 13446 "mips64_dirtyhelper_dmfc0", 13447 &mips64_dirtyhelper_dmfc0, 13448 args); 13449 stmt(IRStmt_Dirty(d)); 13450 putDReg(rt, mkexpr(val)); 13451 } else 13452 goto decode_failure; 13453 break; 13454 13455 case 0x31: /* LWC1 */ 13456 /* Load Word to Floating Point - LWC1 (MIPS32) */ 13457 DIP("lwc1 f%d, %d(r%d)", ft, imm, rs); 13458 if (fp_mode64) { 13459 t1 = newTemp(Ity_F32); 13460 t2 = newTemp(Ity_I64); 13461 if (mode64) { 13462 t0 = newTemp(Ity_I64); 13463 /* new LO */ 13464 assign(t0, binop(Iop_Add64, getIReg(rs), 13465 mkU64(extend_s_16to64(imm)))); 13466 } else { 13467 t0 = newTemp(Ity_I32); 13468 /* new LO */ 13469 assign(t0, binop(Iop_Add32, getIReg(rs), 13470 mkU32(extend_s_16to32(imm)))); 13471 } 13472 assign(t1, load(Ity_F32, mkexpr(t0))); 13473 assign(t2, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32, 13474 mkexpr(t1)), True)); 13475 putDReg(ft, unop(Iop_ReinterpI64asF64, mkexpr(t2))); 13476 } else { 13477 t0 = newTemp(Ity_I32); 13478 assign(t0, binop(Iop_Add32, getIReg(rs), 13479 mkU32(extend_s_16to32(imm)))); 13480 putFReg(ft, load(Ity_F32, mkexpr(t0))); 13481 } 13482 break; 13483 13484 case 0x39: /* SWC1 */ 13485 DIP("swc1 f%d, %d(r%d)", ft, imm, rs); 13486 if (fp_mode64) { 13487 t0 = newTemp(Ity_I64); 13488 t2 = newTemp(Ity_I32); 13489 LOAD_STORE_PATTERN; 13490 assign(t0, unop(Iop_ReinterpF64asI64, getFReg(ft))); 13491 assign(t2, unop(Iop_64to32, mkexpr(t0))); 13492 store(mkexpr(t1), unop(Iop_ReinterpI32asF32, mkexpr(t2))); 13493 } else { 13494 LOAD_STORE_PATTERN; 13495 store(mkexpr(t1), getFReg(ft)); 13496 } 13497 break; 13498 13499 case 0x33: /* PREF */ 13500 DIP("pref"); 13501 break; 13502 13503 case 0x35: 13504 /* Load Doubleword to Floating Point - LDC1 (MIPS32) */ 13505 DIP("ldc1 f%d, %d(%d)", rt, imm, rs); 13506 LOAD_STORE_PATTERN; 13507 putDReg(ft, load(Ity_F64, mkexpr(t1))); 13508 break; 13509 13510 case 0x3D: 13511 /* Store Doubleword from Floating Point - SDC1 */ 13512 DIP("sdc1 f%d, %d(%d)", ft, imm, rs); 13513 LOAD_STORE_PATTERN; 13514 store(mkexpr(t1), getDReg(ft)); 13515 break; 13516 13517 case 0x23: /* LW */ 13518 DIP("lw r%d, %d(r%d)", rt, imm, rs); 13519 LOAD_STORE_PATTERN; 13520 putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), True)); 13521 break; 13522 13523 case 0x20: /* LB */ 13524 DIP("lb r%d, %d(r%d)", rt, imm, rs); 13525 LOAD_STORE_PATTERN; 13526 if (mode64) 13527 putIReg(rt, unop(Iop_8Sto64, load(Ity_I8, mkexpr(t1)))); 13528 else 13529 putIReg(rt, unop(Iop_8Sto32, load(Ity_I8, mkexpr(t1)))); 13530 break; 13531 13532 case 0x24: /* LBU */ 13533 DIP("lbu r%d, %d(r%d)", rt, imm, rs); 13534 LOAD_STORE_PATTERN; 13535 if (mode64) 13536 putIReg(rt, unop(Iop_8Uto64, load(Ity_I8, mkexpr(t1)))); 13537 else 13538 putIReg(rt, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t1)))); 13539 break; 13540 13541 case 0x21: /* LH */ 13542 DIP("lh r%d, %d(r%d)", rt, imm, rs); 13543 LOAD_STORE_PATTERN; 13544 if (mode64) 13545 putIReg(rt, unop(Iop_16Sto64, load(Ity_I16, mkexpr(t1)))); 13546 else 13547 putIReg(rt, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t1)))); 13548 break; 13549 13550 case 0x25: /* LHU */ 13551 DIP("lhu r%d, %d(r%d)", rt, imm, rs); 13552 LOAD_STORE_PATTERN; 13553 if (mode64) 13554 putIReg(rt, unop(Iop_16Uto64, load(Ity_I16, mkexpr(t1)))); 13555 else 13556 putIReg(rt, unop(Iop_16Uto32, load(Ity_I16, mkexpr(t1)))); 13557 break; 13558 13559 case 0x0F: /* LUI */ 13560 p = (imm << 16); 13561 DIP("lui r%d, imm: 0x%x", rt, imm); 13562 if (mode64) 13563 putIReg(rt, mkU64(extend_s_32to64(p))); 13564 else 13565 putIReg(rt, mkU32(p)); 13566 break; 13567 13568 case 0x13: /* COP1X */ 13569 switch (function) { 13570 case 0x0: { /* LWXC1 */ 13571 /* Load Word Indexed to Floating Point - LWXC1 (MIPS32r2) */ 13572 DIP("lwxc1 f%d, r%d(r%d)", fd, rt, rs); 13573 if (fp_mode64) { 13574 t0 = newTemp(Ity_I64); 13575 t1 = newTemp(Ity_I32); 13576 t3 = newTemp(Ity_F32); 13577 t4 = newTemp(Ity_I64); 13578 13579 t2 = newTemp(ty); 13580 /* new LO */ 13581 assign(t2, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs), 13582 getIReg(rt))); 13583 assign(t3, load(Ity_F32, mkexpr(t2))); 13584 13585 assign(t4, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32, 13586 mkexpr(t3)), True)); 13587 13588 putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t4))); 13589 } else { 13590 t0 = newTemp(Ity_I32); 13591 assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt))); 13592 putFReg(fd, load(Ity_F32, mkexpr(t0))); 13593 } 13594 break; 13595 } 13596 13597 case 0x1: { /* LDXC1 */ 13598 /* Load Doubleword Indexed to Floating Point 13599 LDXC1 (MIPS32r2 and MIPS64) */ 13600 if (fp_mode64) { 13601 DIP("ldxc1 f%d, r%d(r%d)", fd, rt, rs); 13602 t0 = newTemp(ty); 13603 assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs), 13604 getIReg(rt))); 13605 putFReg(fd, load(Ity_F64, mkexpr(t0))); 13606 break; 13607 } else { 13608 t0 = newTemp(Ity_I32); 13609 assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt))); 13610 13611 t1 = newTemp(Ity_I32); 13612 assign(t1, binop(Iop_Add32, mkexpr(t0), mkU32(4))); 13613 13614 #if defined (_MIPSEL) 13615 putFReg(fd, load(Ity_F32, mkexpr(t0))); 13616 putFReg(fd + 1, load(Ity_F32, mkexpr(t1))); 13617 #elif defined (_MIPSEB) 13618 putFReg(fd + 1, load(Ity_F32, mkexpr(t0))); 13619 putFReg(fd, load(Ity_F32, mkexpr(t1))); 13620 #endif 13621 break; 13622 } 13623 } 13624 13625 case 0x5: /* Load Doubleword Indexed Unaligned to Floating Point - LUXC1; 13626 MIPS32r2 */ 13627 DIP("luxc1 f%d, r%d(r%d)", fd, rt, rs); 13628 t0 = newTemp(Ity_I64); 13629 t1 = newTemp(Ity_I64); 13630 assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt))); 13631 assign(t1, binop(Iop_And64, mkexpr(t0), 13632 mkU64(0xfffffffffffffff8ULL))); 13633 putFReg(fd, load(Ity_F64, mkexpr(t1))); 13634 break; 13635 13636 case 0x8: { /* Store Word Indexed from Floating Point - SWXC1 */ 13637 DIP("swxc1 f%d, r%d(r%d)", ft, rt, rs); 13638 if (fp_mode64) { 13639 t0 = newTemp(ty); 13640 assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs), 13641 getIReg(rt))); 13642 store(mkexpr(t0), getLoFromF64(tyF, getFReg(fs))); 13643 13644 } else { 13645 t0 = newTemp(Ity_I32); 13646 assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt))); 13647 13648 store(mkexpr(t0), getFReg(fs)); 13649 } 13650 break; 13651 } 13652 case 0x9: { /* Store Doubleword Indexed from Floating Point - SDXC1 */ 13653 DIP("sdc1 f%d, %d(%d)", ft, imm, rs); 13654 if (fp_mode64) { 13655 t0 = newTemp(ty); 13656 assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs), 13657 getIReg(rt))); 13658 store(mkexpr(t0), getFReg(fs)); 13659 } else { 13660 t0 = newTemp(Ity_I32); 13661 assign(t0, binop(Iop_Add32, getIReg(rs), getIReg(rt))); 13662 13663 t1 = newTemp(Ity_I32); 13664 assign(t1, binop(Iop_Add32, mkexpr(t0), mkU32(4))); 13665 13666 #if defined (_MIPSEL) 13667 store(mkexpr(t0), getFReg(fs)); 13668 store(mkexpr(t1), getFReg(fs + 1)); 13669 #elif defined (_MIPSEB) 13670 store(mkexpr(t0), getFReg(fs + 1)); 13671 store(mkexpr(t1), getFReg(fs)); 13672 #endif 13673 } 13674 break; 13675 } 13676 case 0xD: /* Store Doubleword Indexed Unaligned from Floating Point - 13677 SUXC1; MIPS64 MIPS32r2 */ 13678 DIP("suxc1 f%d, r%d(r%d)", fd, rt, rs); 13679 t0 = newTemp(Ity_I64); 13680 t1 = newTemp(Ity_I64); 13681 assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt))); 13682 assign(t1, binop(Iop_And64, mkexpr(t0), mkU64(0xfffffffffffffff8ULL))); 13683 store(mkexpr(t1), getFReg(fs)); 13684 break; 13685 13686 case 0x0F: { 13687 DIP("prefx"); 13688 break; 13689 } 13690 case 0x20: { /* MADD.S */ 13691 DIP("madd.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13692 IRExpr *rm = get_IR_roundingmode(); 13693 t1 = newTemp(Ity_F32); 13694 assign(t1, qop(Iop_MAddF32, rm, 13695 getLoFromF64(tyF, getFReg(fmt)), 13696 getLoFromF64(tyF, getFReg(fs)), 13697 getLoFromF64(tyF, getFReg(ft)))); 13698 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1))); 13699 break; /* MADD.S */ 13700 } 13701 case 0x21: { /* MADD.D */ 13702 DIP("madd.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13703 IRExpr *rm = get_IR_roundingmode(); 13704 putDReg(fd, qop(Iop_MAddF64, rm, getDReg(fmt), getDReg(fs), 13705 getDReg(ft))); 13706 break; /* MADD.D */ 13707 } 13708 case 0x28: { /* MSUB.S */ 13709 DIP("msub.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13710 IRExpr *rm = get_IR_roundingmode(); 13711 t1 = newTemp(Ity_F32); 13712 assign(t1, qop(Iop_MSubF32, rm, 13713 getLoFromF64(tyF, getFReg(fmt)), 13714 getLoFromF64(tyF, getFReg(fs)), 13715 getLoFromF64(tyF, getFReg(ft)))); 13716 putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1))); 13717 break; /* MSUB.S */ 13718 } 13719 case 0x29: { /* MSUB.D */ 13720 DIP("msub.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13721 IRExpr *rm = get_IR_roundingmode(); 13722 putDReg(fd, qop(Iop_MSubF64, rm, getDReg(fmt), getDReg(fs), 13723 getDReg(ft))); 13724 break; /* MSUB.D */ 13725 } 13726 case 0x30: { /* NMADD.S */ 13727 DIP("nmadd.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13728 IRExpr *rm = get_IR_roundingmode(); 13729 t1 = newTemp(Ity_F32); 13730 assign(t1, qop(Iop_MAddF32, rm, 13731 getLoFromF64(tyF, getFReg(fmt)), 13732 getLoFromF64(tyF, getFReg(fs)), 13733 getLoFromF64(tyF, getFReg(ft)))); 13734 13735 putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1)))); 13736 break; /* NMADD.S */ 13737 } 13738 case 0x31: { /* NMADD.D */ 13739 DIP("nmadd.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13740 IRExpr *rm = get_IR_roundingmode(); 13741 t1 = newTemp(Ity_F64); 13742 assign(t1, qop(Iop_MAddF64, rm, getDReg(fmt), getDReg(fs), 13743 getDReg(ft))); 13744 putDReg(fd, unop(Iop_NegF64, mkexpr(t1))); 13745 break; /* NMADD.D */ 13746 } 13747 case 0x38: { /* NMSUBB.S */ 13748 DIP("nmsub.s f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13749 IRExpr *rm = get_IR_roundingmode(); 13750 t1 = newTemp(Ity_F32); 13751 assign(t1, qop(Iop_MSubF32, rm, 13752 getLoFromF64(tyF, getFReg(fmt)), 13753 getLoFromF64(tyF, getFReg(fs)), 13754 getLoFromF64(tyF, getFReg(ft)))); 13755 13756 putFReg(fd, mkWidenFromF32(tyF, unop(Iop_NegF32, mkexpr(t1)))); 13757 break; /* NMSUBB.S */ 13758 } 13759 case 0x39: { /* NMSUBB.D */ 13760 DIP("nmsub.d f%d, f%d, f%d, f%d", fd, fmt, fs, ft); 13761 IRExpr *rm = get_IR_roundingmode(); 13762 t1 = newTemp(Ity_F64); 13763 assign(t1, qop(Iop_MSubF64, rm, getDReg(fmt), getDReg(fs), 13764 getDReg(ft))); 13765 putDReg(fd, unop(Iop_NegF64, mkexpr(t1))); 13766 break; /* NMSUBB.D */ 13767 } 13768 13769 default: 13770 goto decode_failure; 13771 } 13772 break; 13773 13774 case 0x22: /* LWL */ 13775 DIP("lwl r%d, %d(r%d)", rt, imm, rs); 13776 if (mode64) { 13777 /* t1 = addr */ 13778 t1 = newTemp(Ity_I64); 13779 #if defined (_MIPSEL) 13780 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 13781 /* t2 = word addr */ 13782 /* t4 = addr mod 4 */ 13783 LWX_SWX_PATTERN64; 13784 13785 /* t3 = word content - shifted */ 13786 t3 = newTemp(Ity_I32); 13787 assign(t3, binop(Iop_Shl32, mkNarrowTo32(ty, load(Ity_I64, 13788 mkexpr(t2))), narrowTo(Ity_I8, binop(Iop_Shl32, 13789 binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)), mkU8(3))))); 13790 13791 /* rt content - adjusted */ 13792 t5 = newTemp(Ity_I32); 13793 assign(t5, binop(Iop_And32, 13794 mkNarrowTo32(ty, getIReg(rt)), 13795 binop(Iop_Shr32, 13796 mkU32(0x00FFFFFF), 13797 narrowTo(Ity_I8, binop(Iop_Mul32, 13798 mkU32(0x08), 13799 mkexpr(t4)))))); 13800 13801 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5), 13802 mkexpr(t3)), True)); 13803 #elif defined (_MIPSEB) 13804 assign(t1, binop(Iop_Xor64, mkU64(0x3), 13805 binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm))))); 13806 /* t2 = word addr */ 13807 /* t4 = addr mod 4 */ 13808 LWX_SWX_PATTERN64; 13809 13810 /* t3 = word content - shifted */ 13811 t3 = newTemp(Ity_I32); 13812 assign(t3, binop(Iop_Shl32, unop(Iop_64HIto32, load(Ity_I64, 13813 mkexpr(t2))), narrowTo(Ity_I8, binop(Iop_Shl32, 13814 binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)), mkU8(3))))); 13815 13816 /* rt content - adjusted */ 13817 t5 = newTemp(Ity_I32); 13818 assign(t5, binop(Iop_And32, 13819 mkNarrowTo32(ty, getIReg(rt)), 13820 binop(Iop_Shr32, 13821 mkU32(0x00FFFFFF), 13822 narrowTo(Ity_I8, binop(Iop_Mul32, 13823 mkU32(0x08), 13824 mkexpr(t4)))))); 13825 13826 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5), 13827 mkexpr(t3)), True)); 13828 #endif 13829 } else { 13830 /* t1 = addr */ 13831 t1 = newTemp(Ity_I32); 13832 #if defined (_MIPSEL) 13833 assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm)))); 13834 #elif defined (_MIPSEB) 13835 assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs), 13836 mkU32(extend_s_16to32(imm))))); 13837 #endif 13838 13839 /* t2 = word addr */ 13840 /* t4 = addr mod 4 */ 13841 LWX_SWX_PATTERN; 13842 13843 /* t3 = word content - shifted */ 13844 t3 = newTemp(Ity_I32); 13845 assign(t3, binop(Iop_Shl32, load(Ity_I32, mkexpr(t2)), narrowTo(Ity_I8, 13846 binop(Iop_Shl32, binop(Iop_Sub32, mkU32(0x03), mkexpr(t4)), 13847 mkU8(3))))); 13848 13849 /* rt content - adjusted */ 13850 t5 = newTemp(Ity_I32); 13851 assign(t5, binop(Iop_And32, 13852 getIReg(rt), 13853 binop(Iop_Shr32, 13854 mkU32(0x00FFFFFF), 13855 narrowTo(Ity_I8, binop(Iop_Mul32, 13856 mkU32(0x08), 13857 mkexpr(t4)))))); 13858 13859 putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3))); 13860 } 13861 break; 13862 13863 case 0x26: /* LWR */ 13864 DIP("lwr r%d, %d(r%d)", rt, imm, rs); 13865 if (mode64) { 13866 /* t1 = addr */ 13867 t1 = newTemp(Ity_I64); 13868 #if defined (_MIPSEL) 13869 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 13870 /* t2 = word addr */ 13871 /* t4 = addr mod 8 */ 13872 LWX_SWX_PATTERN64; 13873 13874 /* t3 = word content - shifted */ 13875 t3 = newTemp(Ity_I32); 13876 assign(t3, binop(Iop_Shr32, mkNarrowTo32(ty, load(Ity_I64,mkexpr(t2))), 13877 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(3))))); 13878 13879 /* rt content - adjusted */ 13880 t5 = newTemp(Ity_I32); 13881 assign(t5, binop(Iop_And32, mkNarrowTo32(ty, getIReg(rt)), 13882 unop(Iop_Not32, binop(Iop_Shr32, mkU32(0xFFFFFFFF), 13883 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(0x3))))))); 13884 13885 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5), 13886 mkexpr(t3)), True)); 13887 #elif defined (_MIPSEB) 13888 assign(t1, binop(Iop_Xor64, mkU64(0x3), binop(Iop_Add64, getIReg(rs), 13889 mkU64(extend_s_16to64(imm))))); 13890 /* t2 = word addr */ 13891 /* t4 = addr mod 4 */ 13892 LWX_SWX_PATTERN64; 13893 13894 /* t3 = word content - shifted */ 13895 t3 = newTemp(Ity_I32); 13896 assign(t3, binop(Iop_Shr32, unop(Iop_64HIto32, load(Ity_I64,mkexpr(t2))), 13897 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(3))))); 13898 13899 /* rt content - adjusted */ 13900 t5 = newTemp(Ity_I32); 13901 assign(t5, binop(Iop_And32, mkNarrowTo32(ty, getIReg(rt)), 13902 unop(Iop_Not32, binop(Iop_Shr32, mkU32(0xFFFFFFFF), 13903 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), mkU8(0x3))))))); 13904 13905 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t5), 13906 mkexpr(t3)), True)); 13907 #endif 13908 13909 } else { 13910 /* t1 = addr */ 13911 t1 = newTemp(Ity_I32); 13912 #if defined (_MIPSEL) 13913 assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm)))); 13914 #elif defined (_MIPSEB) 13915 assign(t1, binop(Iop_Xor32, mkU32(0x3), binop(Iop_Add32, getIReg(rs), 13916 mkU32(extend_s_16to32(imm))))); 13917 #endif 13918 13919 /* t2 = word addr */ 13920 /* t4 = addr mod 4 */ 13921 LWX_SWX_PATTERN; 13922 13923 /* t3 = word content - shifted */ 13924 t3 = newTemp(Ity_I32); 13925 assign(t3, binop(Iop_Shr32, load(Ity_I32, mkexpr(t2)), 13926 narrowTo(Ity_I8, binop(Iop_Shl32, mkexpr(t4), 13927 mkU8(3))))); 13928 13929 /* rt content - adjusted */ 13930 t5 = newTemp(Ity_I32); 13931 assign(t5, binop(Iop_And32, getIReg(rt), unop(Iop_Not32, 13932 binop(Iop_Shr32, mkU32(0xFFFFFFFF), narrowTo(Ity_I8, 13933 binop(Iop_Shl32, mkexpr(t4), mkU8(0x3))))))); 13934 13935 putIReg(rt, binop(Iop_Or32, mkexpr(t5), mkexpr(t3))); 13936 } 13937 break; 13938 13939 case 0x2B: /* SW */ 13940 DIP("sw r%d, %d(r%d)", rt, imm, rs); 13941 LOAD_STORE_PATTERN; 13942 store(mkexpr(t1), mkNarrowTo32(ty, getIReg(rt))); 13943 break; 13944 13945 case 0x2C: { /* SDL rt, offset(base) MIPS64 */ 13946 DIP("sdl r%u, %d(r%u)", rt, (Int) imm, rs); 13947 vassert(mode64); 13948 IRTemp A_byte = newTemp(Ity_I8); 13949 IRTemp B_byte = newTemp(Ity_I8); 13950 IRTemp C_byte = newTemp(Ity_I8); 13951 IRTemp D_byte = newTemp(Ity_I8); 13952 IRTemp E_byte = newTemp(Ity_I8); 13953 IRTemp F_byte = newTemp(Ity_I8); 13954 IRTemp G_byte = newTemp(Ity_I8); 13955 IRTemp H_byte = newTemp(Ity_I8); 13956 IRTemp B_pos = newTemp(Ity_I64); 13957 IRTemp C_pos = newTemp(Ity_I64); 13958 IRTemp D_pos = newTemp(Ity_I64); 13959 IRTemp E_pos = newTemp(Ity_I64); 13960 IRTemp F_pos = newTemp(Ity_I64); 13961 IRTemp G_pos = newTemp(Ity_I64); 13962 13963 /* H byte */ 13964 assign(H_byte, getByteFromReg(rt, 0)); 13965 /* G byte */ 13966 assign(G_byte, getByteFromReg(rt, 1)); 13967 /* F byte */ 13968 assign(F_byte, getByteFromReg(rt, 2)); 13969 /* E byte */ 13970 assign(E_byte, getByteFromReg(rt, 3)); 13971 /* D byte */ 13972 assign(D_byte, getByteFromReg(rt, 4)); 13973 /* C byte */ 13974 assign(C_byte, getByteFromReg(rt, 5)); 13975 /* B byte */ 13976 assign(B_byte, getByteFromReg(rt, 6)); 13977 /* A byte */ 13978 assign(A_byte, getByteFromReg(rt, 7)); 13979 13980 /* t1 = addr */ 13981 t1 = newTemp(Ity_I64); 13982 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 13983 13984 /* t2 = word addr */ 13985 t2 = newTemp(Ity_I64); 13986 assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL))); 13987 13988 /* t3 = addr mod 7 */ 13989 t3 = newTemp(Ity_I64); 13990 assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7))); 13991 13992 #if defined (_MIPSEL) 13993 /* Calculate X_byte position. */ 13994 assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x1)), 13995 mkU64(0x0), 13996 mkU64(0x1))); 13997 13998 assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x2)), 13999 mkU64(0x0), 14000 mkU64(0x2))); 14001 14002 assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)), 14003 mkU64(0x0), 14004 mkU64(0x3))); 14005 14006 assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)), 14007 mkU64(0x0), 14008 mkU64(0x4))); 14009 14010 assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)), 14011 mkU64(0x0), 14012 mkU64(0x5))); 14013 14014 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)), 14015 mkU64(0x1), 14016 mkU64(0x0))); 14017 14018 /* Store X_byte on the right place. */ 14019 store(mkexpr(t2), mkexpr(H_byte)); 14020 store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte)); 14021 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 14022 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte)); 14023 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte)); 14024 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte)); 14025 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte)); 14026 store(mkexpr(t1), mkexpr(A_byte)); 14027 14028 #else /* _MIPSEB */ 14029 /* Calculate X_byte position. */ 14030 assign(B_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)), 14031 mkU64(0x0), 14032 mkU64(0x1))); 14033 14034 assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x6)), 14035 mkU64(0x2), 14036 mkU64(0x0))); 14037 14038 assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x5)), 14039 mkU64(0x3), 14040 mkU64(0x0))); 14041 14042 assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x4)), 14043 mkU64(0x4), 14044 mkU64(0x0))); 14045 14046 assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkexpr(t3), mkU64(0x3)), 14047 mkU64(0x5), 14048 mkU64(0x0))); 14049 14050 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)), 14051 mkU64(0x6), 14052 mkU64(0x7))); 14053 14054 /* Store X_byte on the right place. */ 14055 store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(H_byte)); 14056 store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte)); 14057 store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 14058 store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte)); 14059 store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte)); 14060 store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte)); 14061 store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte)); 14062 store(mkexpr(t1), mkexpr(A_byte)); 14063 #endif 14064 14065 break; 14066 } 14067 14068 case 0x2D: { 14069 /* SDR rt, offset(base) - MIPS64 */ 14070 vassert(mode64); 14071 DIP("sdr r%u, %d(r%u)", rt, imm, rs); 14072 IRTemp A_byte = newTemp(Ity_I8); 14073 IRTemp B_byte = newTemp(Ity_I8); 14074 IRTemp C_byte = newTemp(Ity_I8); 14075 IRTemp D_byte = newTemp(Ity_I8); 14076 IRTemp E_byte = newTemp(Ity_I8); 14077 IRTemp F_byte = newTemp(Ity_I8); 14078 IRTemp G_byte = newTemp(Ity_I8); 14079 IRTemp H_byte = newTemp(Ity_I8); 14080 IRTemp B_pos = newTemp(Ity_I64); 14081 IRTemp C_pos = newTemp(Ity_I64); 14082 IRTemp D_pos = newTemp(Ity_I64); 14083 IRTemp E_pos = newTemp(Ity_I64); 14084 IRTemp F_pos = newTemp(Ity_I64); 14085 IRTemp G_pos = newTemp(Ity_I64); 14086 14087 /* H byte */ 14088 assign(H_byte, getByteFromReg(rt, 0)); 14089 /* G byte */ 14090 assign(G_byte, getByteFromReg(rt, 1)); 14091 /* F byte */ 14092 assign(F_byte, getByteFromReg(rt, 2)); 14093 /* E byte */ 14094 assign(E_byte, getByteFromReg(rt, 3)); 14095 /* D byte */ 14096 assign(D_byte, getByteFromReg(rt, 4)); 14097 /* C byte */ 14098 assign(C_byte, getByteFromReg(rt, 5)); 14099 /* B byte */ 14100 assign(B_byte, getByteFromReg(rt, 6)); 14101 /* A byte */ 14102 assign(A_byte, getByteFromReg(rt, 7)); 14103 14104 /* t1 = addr */ 14105 t1 = newTemp(Ity_I64); 14106 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 14107 14108 /* t2 = word addr */ 14109 t2 = newTemp(Ity_I64); 14110 assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL))); 14111 14112 /* t3 = addr mod 7 */ 14113 t3 = newTemp(Ity_I64); 14114 assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x7))); 14115 14116 #if defined (_MIPSEL) 14117 /* Calculate X_byte position. */ 14118 assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)), 14119 mkU64(0x0), 14120 mkU64(0x6))); 14121 14122 assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)), 14123 mkU64(0x0), 14124 mkU64(0x5))); 14125 14126 assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)), 14127 mkU64(0x0), 14128 mkU64(0x4))); 14129 14130 assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)), 14131 mkU64(0x0), 14132 mkU64(0x3))); 14133 14134 assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)), 14135 mkU64(0x0), 14136 mkU64(0x2))); 14137 14138 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x7)), 14139 mkU64(0x0), 14140 mkU64(0x1))); 14141 14142 /* Store X_byte on the right place. */ 14143 store(binop(Iop_Add64, mkexpr(t2), mkU64(0x7)), mkexpr(A_byte)); 14144 store(binop(Iop_Add64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte)); 14145 store(binop(Iop_Add64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte)); 14146 store(binop(Iop_Add64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte)); 14147 store(binop(Iop_Add64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte)); 14148 store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 14149 store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte)); 14150 store(mkexpr(t1), mkexpr(H_byte)); 14151 14152 #else /* _MIPSEB */ 14153 /* Calculate X_byte position. */ 14154 assign(B_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x5), mkexpr(t3)), 14155 mkU64(0x6), 14156 mkU64(0x0))); 14157 14158 assign(C_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x4), mkexpr(t3)), 14159 mkU64(0x5), 14160 mkU64(0x0))); 14161 14162 assign(D_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x3), mkexpr(t3)), 14163 mkU64(0x4), 14164 mkU64(0x0))); 14165 14166 assign(E_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x2), mkexpr(t3)), 14167 mkU64(0x3), 14168 mkU64(0x0))); 14169 14170 assign(F_pos, IRExpr_ITE(binop(Iop_CmpLT64U, mkU64(0x1), mkexpr(t3)), 14171 mkU64(0x2), 14172 mkU64(0x0))); 14173 14174 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)), 14175 mkU64(0x0), 14176 mkU64(0x1))); 14177 14178 /* Store X_byte on the right place. */ 14179 store(mkexpr(t2), mkexpr(A_byte)); 14180 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(B_pos)), mkexpr(B_byte)); 14181 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(C_pos)), mkexpr(C_byte)); 14182 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(D_pos)), mkexpr(D_byte)); 14183 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(E_pos)), mkexpr(E_byte)); 14184 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 14185 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte)); 14186 store(mkexpr(t1), mkexpr(H_byte)); 14187 #endif 14188 break; 14189 } 14190 14191 case 0x28: /* SB */ 14192 DIP("sb r%d, %d(r%d)", rt, imm, rs); 14193 LOAD_STORE_PATTERN; 14194 store(mkexpr(t1), narrowTo(Ity_I8, getIReg(rt))); 14195 break; 14196 14197 case 0x29: /* SH */ 14198 DIP("sh r%d, %d(r%d)", rt, imm, rs); 14199 LOAD_STORE_PATTERN; 14200 store(mkexpr(t1), narrowTo(Ity_I16, getIReg(rt))); 14201 break; 14202 14203 case 0x2A: /* SWL */ 14204 DIP("swl r%d, %d(r%d)", rt, imm, rs); 14205 if (mode64) { 14206 IRTemp E_byte = newTemp(Ity_I8); 14207 IRTemp F_byte = newTemp(Ity_I8); 14208 IRTemp G_byte = newTemp(Ity_I8); 14209 IRTemp H_byte = newTemp(Ity_I8); 14210 IRTemp F_pos = newTemp(Ity_I64); 14211 IRTemp G_pos = newTemp(Ity_I64); 14212 14213 /* H byte */ 14214 assign(H_byte, getByteFromReg(rt, 0)); 14215 /* G byte */ 14216 assign(G_byte, getByteFromReg(rt, 1)); 14217 /* F byte */ 14218 assign(F_byte, getByteFromReg(rt, 2)); 14219 /* E byte */ 14220 assign(E_byte, getByteFromReg(rt, 3)); 14221 14222 /* t1 = addr */ 14223 t1 = newTemp(Ity_I64); 14224 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 14225 14226 /* t2 = word addr */ 14227 t2 = newTemp(Ity_I64); 14228 assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL))); 14229 14230 /* t3 = addr mod 4 */ 14231 t3 = newTemp(Ity_I64); 14232 assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3))); 14233 14234 #if defined (_MIPSEL) 14235 /* Calculate X_byte position. */ 14236 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)), 14237 mkU64(0x0), 14238 mkU64(0x1))); 14239 14240 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)), 14241 mkU64(0x1), 14242 mkU64(0x0))); 14243 14244 /* Store X_byte on the right place. */ 14245 store(mkexpr(t2), mkexpr(H_byte)); 14246 store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte)); 14247 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 14248 store(mkexpr(t1), mkexpr(E_byte)); 14249 14250 #else /* _MIPSEB */ 14251 /* Calculate X_byte position. */ 14252 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)), 14253 mkU64(0x0), 14254 mkU64(0x1))); 14255 14256 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)), 14257 mkU64(0x2), 14258 mkU64(0x3))); 14259 14260 store(binop(Iop_Add64, mkexpr(t2), mkU64(3)), mkexpr(H_byte)); 14261 store(binop(Iop_Add64, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte)); 14262 store(binop(Iop_Add64, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 14263 store(mkexpr(t1), mkexpr(E_byte)); 14264 14265 #endif 14266 } else { 14267 IRTemp E_byte = newTemp(Ity_I8); 14268 IRTemp F_byte = newTemp(Ity_I8); 14269 IRTemp G_byte = newTemp(Ity_I8); 14270 IRTemp H_byte = newTemp(Ity_I8); 14271 IRTemp F_pos = newTemp(Ity_I32); 14272 IRTemp G_pos = newTemp(Ity_I32); 14273 14274 /* H byte */ 14275 assign(H_byte, getByteFromReg(rt, 0)); 14276 /* G byte */ 14277 assign(G_byte, getByteFromReg(rt, 1)); 14278 /* F byte */ 14279 assign(F_byte, getByteFromReg(rt, 2)); 14280 /* E byte */ 14281 assign(E_byte, getByteFromReg(rt, 3)); 14282 14283 /* t1 = addr */ 14284 t1 = newTemp(Ity_I32); 14285 assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm)))); 14286 14287 /* t2 = word addr */ 14288 t2 = newTemp(Ity_I32); 14289 assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL))); 14290 14291 /* t3 = addr mod 4 */ 14292 t3 = newTemp(Ity_I32); 14293 assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3))); 14294 14295 #if defined (_MIPSEL) 14296 /* Calculate X_byte position. */ 14297 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)), 14298 mkU32(0x0), 14299 mkU32(0x1))); 14300 14301 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)), 14302 mkU32(0x1), 14303 mkU32(0x0))); 14304 14305 /* Store X_byte on the right place. */ 14306 store(mkexpr(t2), mkexpr(H_byte)); 14307 store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte)); 14308 store(binop(Iop_Sub32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 14309 store(mkexpr(t1), mkexpr(E_byte)); 14310 14311 #else /* _MIPSEB */ 14312 /* Calculate X_byte position. */ 14313 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)), 14314 mkU32(0x0), 14315 mkU32(0x1))); 14316 14317 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)), 14318 mkU32(0x2), 14319 mkU32(0x3))); 14320 14321 store(binop(Iop_Add32, mkexpr(t2), mkU32(3)), mkexpr(H_byte)); 14322 store(binop(Iop_Add32, mkexpr(t2), mkexpr(G_pos)), mkexpr(G_byte)); 14323 store(binop(Iop_Add32, mkexpr(t1), mkexpr(F_pos)), mkexpr(F_byte)); 14324 store(mkexpr(t1), mkexpr(E_byte)); 14325 14326 #endif 14327 } 14328 break; 14329 14330 case 0x2E: /* SWR */ 14331 DIP("swr r%d, %d(r%d)", rt, imm, rs); 14332 if (mode64) { 14333 IRTemp E_byte = newTemp(Ity_I8); 14334 IRTemp F_byte = newTemp(Ity_I8); 14335 IRTemp G_byte = newTemp(Ity_I8); 14336 IRTemp H_byte = newTemp(Ity_I8); 14337 IRTemp F_pos = newTemp(Ity_I64); 14338 IRTemp G_pos = newTemp(Ity_I64); 14339 14340 /* H byte */ 14341 assign(H_byte, getByteFromReg(rt, 0)); 14342 /* G byte */ 14343 assign(G_byte, getByteFromReg(rt, 1)); 14344 /* F byte */ 14345 assign(F_byte, getByteFromReg(rt, 2)); 14346 /* E byte */ 14347 assign(E_byte, getByteFromReg(rt, 3)); 14348 14349 /* t1 = addr */ 14350 t1 = newTemp(Ity_I64); 14351 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 14352 14353 /* t2 = word addr */ 14354 t2 = newTemp(Ity_I64); 14355 assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFFCULL))); 14356 14357 /* t3 = addr mod 4 */ 14358 t3 = newTemp(Ity_I64); 14359 assign(t3, binop(Iop_And64, mkexpr(t1), mkU64(0x3))); 14360 14361 #if defined (_MIPSEL) 14362 /* Calculate X_byte position. */ 14363 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)), 14364 mkU64(0x2), 14365 mkU64(0x3))); 14366 14367 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)), 14368 mkU64(0x0), 14369 mkU64(0x1))); 14370 14371 /* Store X_byte on the right place. */ 14372 store(binop(Iop_Add64, mkexpr(t2), mkU64(0x3)), mkexpr(E_byte)); 14373 store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte)); 14374 store(binop(Iop_Add64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte)); 14375 store(mkexpr(t1), mkexpr(H_byte)); 14376 14377 #else /* _MIPSEB */ 14378 /* Calculate X_byte position. */ 14379 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x3)), 14380 mkU64(0x1), 14381 mkU64(0x0))); 14382 14383 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ64, mkexpr(t3), mkU64(0x0)), 14384 mkU64(0x0), 14385 mkU64(0x1))); 14386 14387 /* Store X_byte on the right place. */ 14388 store(mkexpr(t2), mkexpr(E_byte)); 14389 store(binop(Iop_Add64, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte)); 14390 store(binop(Iop_Sub64, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte)); 14391 store(mkexpr(t1), mkexpr(H_byte)); 14392 #endif 14393 } else { 14394 IRTemp E_byte = newTemp(Ity_I8); 14395 IRTemp F_byte = newTemp(Ity_I8); 14396 IRTemp G_byte = newTemp(Ity_I8); 14397 IRTemp H_byte = newTemp(Ity_I8); 14398 IRTemp F_pos = newTemp(Ity_I32); 14399 IRTemp G_pos = newTemp(Ity_I32); 14400 14401 /* H byte */ 14402 assign(H_byte, getByteFromReg(rt, 0)); 14403 /* G byte */ 14404 assign(G_byte, getByteFromReg(rt, 1)); 14405 /* F byte */ 14406 assign(F_byte, getByteFromReg(rt, 2)); 14407 /* E byte */ 14408 assign(E_byte, getByteFromReg(rt, 3)); 14409 14410 /* t1 = addr */ 14411 t1 = newTemp(Ity_I32); 14412 assign(t1, binop(Iop_Add32, getIReg(rs), mkU32(extend_s_16to32(imm)))); 14413 14414 /* t2 = word addr */ 14415 t2 = newTemp(Ity_I32); 14416 assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFCULL))); 14417 14418 /* t3 = addr mod 4 */ 14419 t3 = newTemp(Ity_I32); 14420 assign(t3, binop(Iop_And32, mkexpr(t1), mkU32(0x3))); 14421 14422 #if defined (_MIPSEL) 14423 /* Calculate X_byte position. */ 14424 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)), 14425 mkU32(0x2), 14426 mkU32(0x3))); 14427 14428 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)), 14429 mkU32(0x0), 14430 mkU32(0x1))); 14431 14432 /* Store X_byte on the right place. */ 14433 store(binop(Iop_Add32, mkexpr(t2), mkU32(0x3)), mkexpr(E_byte)); 14434 store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte)); 14435 store(binop(Iop_Add32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte)); 14436 store(mkexpr(t1), mkexpr(H_byte)); 14437 14438 #else /* _MIPSEB */ 14439 /* Calculate X_byte position. */ 14440 assign(F_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x3)), 14441 mkU32(0x1), 14442 mkU32(0x0))); 14443 14444 assign(G_pos, IRExpr_ITE(binop(Iop_CmpEQ32, mkexpr(t3), mkU32(0x0)), 14445 mkU32(0x0), 14446 mkU32(0x1))); 14447 14448 /* Store X_byte on the right place. */ 14449 store(mkexpr(t2), mkexpr(E_byte)); 14450 store(binop(Iop_Add32, mkexpr(t2), mkexpr(F_pos)), mkexpr(F_byte)); 14451 store(binop(Iop_Sub32, mkexpr(t1), mkexpr(G_pos)), mkexpr(G_byte)); 14452 store(mkexpr(t1), mkexpr(H_byte)); 14453 #endif 14454 } 14455 break; 14456 14457 case 0x1C: /* Special2 */ 14458 switch (function) { 14459 /* Cavium Specific instructions */ 14460 case 0x03: case 0x32: case 0x33: /* DMUL, CINS , CINS32 */ 14461 case 0x3A: case 0x3B: case 0x2B: /* EXT, EXT32, SNE */ 14462 /* CVM Compare Instructions */ 14463 case 0x2A: case 0x2E: case 0x2F: /* SEQ, SEQI, SNEI */ 14464 /* CPU Load, Store, Memory, and Control Instructions */ 14465 case 0x18: case 0x19: /* SAA, SAAD */ 14466 case 0x1F: /* LAA, LAAD, LAI, LAID */ 14467 case 0x28: case 0x2C: case 0x2D: /* BADDU, POP, DPOP */ 14468 if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) { 14469 if (dis_instr_CVM(cins)) 14470 break; 14471 goto decode_failure; 14472 } else { 14473 goto decode_failure; 14474 } 14475 break; 14476 14477 case 0x02: { /* MUL */ 14478 DIP("mul r%d, r%d, r%d", rd, rs, rt); 14479 if (mode64) { 14480 IRTemp tmpRs32 = newTemp(Ity_I32); 14481 IRTemp tmpRt32 = newTemp(Ity_I32); 14482 IRTemp tmpRes = newTemp(Ity_I32); 14483 14484 assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); 14485 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 14486 assign(tmpRes, binop(Iop_Mul32, 14487 mkexpr(tmpRs32), mkexpr(tmpRt32))); 14488 putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpRes), True)); 14489 } else 14490 putIReg(rd, binop(Iop_Mul32, getIReg(rs), getIReg(rt))); 14491 break; 14492 } 14493 14494 case 0x00: { /* MADD */ 14495 if (mode64) { 14496 DIP("madd r%d, r%d", rs, rt); 14497 t1 = newTemp(Ity_I32); 14498 t2 = newTemp(Ity_I32); 14499 t3 = newTemp(Ity_I64); 14500 t4 = newTemp(Ity_I64); 14501 t5 = newTemp(Ity_I64); 14502 t6 = newTemp(Ity_I32); 14503 14504 assign(t1, mkNarrowTo32(ty, getHI())); 14505 assign(t2, mkNarrowTo32(ty, getLO())); 14506 14507 assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)), 14508 mkNarrowTo32(ty, getIReg(rt)))); 14509 14510 assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2))); 14511 assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4))); 14512 14513 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True)); 14514 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True)); 14515 } else { 14516 if ( (1 <= ac) && ( 3 >= ac) ) { 14517 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 14518 /* If DSP is present -> DSP ASE MADD */ 14519 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 14520 if (0 != retVal ) { 14521 goto decode_failure_dsp; 14522 } 14523 break; 14524 } else { 14525 goto decode_failure_dsp; 14526 } 14527 } else { 14528 DIP("madd r%d, r%d", rs, rt); 14529 t1 = newTemp(Ity_I32); 14530 t2 = newTemp(Ity_I32); 14531 t3 = newTemp(Ity_I64); 14532 t4 = newTemp(Ity_I32); 14533 t5 = newTemp(Ity_I32); 14534 t6 = newTemp(Ity_I32); 14535 14536 assign(t1, getHI()); 14537 assign(t2, getLO()); 14538 14539 assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt))); 14540 14541 assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32, 14542 mkexpr(t3)))); 14543 14544 assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4), 14545 unop(Iop_64to32, mkexpr(t3))))); 14546 assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1))); 14547 14548 putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32, 14549 mkexpr(t3)))); 14550 putLO(mkexpr(t4)); 14551 break; 14552 } 14553 } 14554 break; 14555 } 14556 14557 case 0x01: { /* MADDU */ 14558 if (mode64) { 14559 DIP("maddu r%d, r%d", rs, rt); 14560 t1 = newTemp(Ity_I32); 14561 t2 = newTemp(Ity_I32); 14562 t3 = newTemp(Ity_I64); 14563 t4 = newTemp(Ity_I64); 14564 t5 = newTemp(Ity_I64); 14565 t6 = newTemp(Ity_I32); 14566 14567 assign(t1, mkNarrowTo32(ty, getHI())); 14568 assign(t2, mkNarrowTo32(ty, getLO())); 14569 14570 assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)), 14571 mkNarrowTo32(ty, getIReg(rt)))); 14572 14573 assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2))); 14574 assign(t5, binop(Iop_Add64, mkexpr(t3), mkexpr(t4))); 14575 14576 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True)); 14577 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True)); 14578 } else { 14579 if ( (1 <= ac) && ( 3 >= ac) ) { 14580 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 14581 /* If DSP is present -> DSP ASE MADDU */ 14582 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 14583 if (0 != retVal ) { 14584 goto decode_failure_dsp; 14585 } 14586 break; 14587 } else { 14588 goto decode_failure_dsp; 14589 } 14590 } else { 14591 DIP("maddu r%d, r%d", rs, rt); 14592 t1 = newTemp(Ity_I32); 14593 t2 = newTemp(Ity_I32); 14594 t3 = newTemp(Ity_I64); 14595 t4 = newTemp(Ity_I32); 14596 t5 = newTemp(Ity_I32); 14597 t6 = newTemp(Ity_I32); 14598 14599 assign(t1, getHI()); 14600 assign(t2, getLO()); 14601 14602 assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt))); 14603 14604 assign(t4, binop(Iop_Add32, mkexpr(t2), unop(Iop_64to32, 14605 mkexpr(t3)))); 14606 assign(t5, unop(Iop_1Uto32, binop(Iop_CmpLT32U, mkexpr(t4), 14607 unop(Iop_64to32, mkexpr(t3))))); 14608 assign(t6, binop(Iop_Add32, mkexpr(t5), mkexpr(t1))); 14609 14610 putHI(binop(Iop_Add32, mkexpr(t6), unop(Iop_64HIto32, 14611 mkexpr(t3)))); 14612 putLO(mkexpr(t4)); 14613 break; 14614 } 14615 } 14616 break; 14617 } 14618 14619 case 0x04: { /* MSUB */ 14620 if (mode64) { 14621 DIP("msub r%d, r%d", rs, rt); 14622 t1 = newTemp(Ity_I32); 14623 t2 = newTemp(Ity_I32); 14624 t3 = newTemp(Ity_I64); 14625 t4 = newTemp(Ity_I64); 14626 t5 = newTemp(Ity_I64); 14627 t6 = newTemp(Ity_I32); 14628 14629 assign(t1, mkNarrowTo32(ty, getHI())); 14630 assign(t2, mkNarrowTo32(ty, getLO())); 14631 14632 assign(t3, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)), 14633 mkNarrowTo32(ty, getIReg(rt)))); 14634 14635 assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2))); 14636 assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3))); 14637 14638 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True)); 14639 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True)); 14640 } else { 14641 if ( (1 <= ac) && ( 3 >= ac) ) { 14642 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 14643 /* If DSP is present -> DSP ASE MSUB */ 14644 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 14645 if (0 != retVal ) { 14646 goto decode_failure_dsp; 14647 } 14648 break; 14649 } else { 14650 goto decode_failure_dsp; 14651 } 14652 } else { 14653 DIP("msub r%d, r%d", rs, rt); 14654 t1 = newTemp(Ity_I32); 14655 t2 = newTemp(Ity_I32); 14656 t3 = newTemp(Ity_I64); 14657 t4 = newTemp(Ity_I32); 14658 t5 = newTemp(Ity_I1); 14659 t6 = newTemp(Ity_I32); 14660 14661 assign(t1, getHI()); 14662 assign(t2, getLO()); 14663 14664 assign(t3, binop(Iop_MullS32, getIReg(rs), getIReg(rt))); 14665 assign(t4, unop(Iop_64to32, mkexpr(t3))); /* new lo */ 14666 14667 /* if lo<lo(mul) hi = hi - 1 */ 14668 assign(t5, binop(Iop_CmpLT32U, 14669 mkexpr(t2), 14670 mkexpr(t4))); 14671 14672 assign(t6, IRExpr_ITE(mkexpr(t5), 14673 binop(Iop_Sub32, mkexpr(t1), mkU32(0x1)), 14674 mkexpr(t1))); 14675 14676 putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32, 14677 mkexpr(t3)))); 14678 putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4))); 14679 break; 14680 } 14681 } 14682 break; 14683 } 14684 14685 case 0x05: { /* MSUBU */ 14686 if (mode64) { 14687 DIP("msubu r%d, r%d", rs, rt); 14688 t1 = newTemp(Ity_I32); 14689 t2 = newTemp(Ity_I32); 14690 t3 = newTemp(Ity_I64); 14691 t4 = newTemp(Ity_I64); 14692 t5 = newTemp(Ity_I64); 14693 t6 = newTemp(Ity_I32); 14694 14695 assign(t1, mkNarrowTo32(ty, getHI())); 14696 assign(t2, mkNarrowTo32(ty, getLO())); 14697 14698 assign(t3, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)), 14699 mkNarrowTo32(ty, getIReg(rt)))); 14700 14701 assign(t4, binop(Iop_32HLto64, mkexpr(t1), mkexpr(t2))); 14702 assign(t5, binop(Iop_Sub64, mkexpr(t4), mkexpr(t3))); 14703 14704 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t5)), True)); 14705 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t5)), True)); 14706 } else { 14707 if ( (1 <= ac) && ( 3 >= ac) ) { 14708 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 14709 /* If DSP is present -> DSP ASE MSUBU */ 14710 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 14711 if (0 != retVal ) { 14712 goto decode_failure_dsp; 14713 } 14714 break; 14715 } else { 14716 goto decode_failure_dsp; 14717 } 14718 } else { 14719 DIP("msubu r%d, r%d", rs, rt); 14720 t1 = newTemp(Ity_I32); 14721 t2 = newTemp(Ity_I32); 14722 t3 = newTemp(Ity_I64); 14723 t4 = newTemp(Ity_I32); 14724 t5 = newTemp(Ity_I1); 14725 t6 = newTemp(Ity_I32); 14726 14727 assign(t1, getHI()); 14728 assign(t2, getLO()); 14729 14730 assign(t3, binop(Iop_MullU32, getIReg(rs), getIReg(rt))); 14731 assign(t4, unop(Iop_64to32, mkexpr(t3))); /* new lo */ 14732 14733 /* if lo<lo(mul) hi = hi - 1 */ 14734 assign(t5, binop(Iop_CmpLT32U, 14735 mkexpr(t2), 14736 mkexpr(t4))); 14737 14738 assign(t6, IRExpr_ITE(mkexpr(t5), 14739 binop(Iop_Sub32, 14740 mkexpr(t1), 14741 mkU32(0x1)), 14742 mkexpr(t1))); 14743 14744 putHI(binop(Iop_Sub32, mkexpr(t6), unop(Iop_64HIto32, 14745 mkexpr(t3)))); 14746 putLO(binop(Iop_Sub32, mkexpr(t2), mkexpr(t4))); 14747 break; 14748 } 14749 } 14750 break; 14751 } 14752 14753 case 0x6: /* dmul MIPS64 - Netlogic */ 14754 DIP("dmul r%u, r%u, r%u", rd, rs, rt); 14755 t0 = newTemp(Ity_I128); 14756 14757 assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt))); 14758 14759 putIReg(rd, unop(Iop_128to64, mkexpr(t0))); 14760 break; 14761 14762 case 0x10: /* LDADDW - Swap Word - Netlogic */ 14763 DIP("ldaddw r%u, r%u", rt, rs); 14764 t0 = newTemp(Ity_I32); 14765 t1 = newTemp(Ity_I32); 14766 t2 = newTemp(Ity_I32); 14767 t3 = newTemp(Ity_I64); 14768 t4 = newTemp(Ity_I32); 14769 t5 = newTemp(Ity_I32); 14770 t6 = newTemp(Ity_I32); 14771 14772 /* v = GPR[rt] */ 14773 assign(t0, mkNarrowTo32(ty, getIReg(rt))); 14774 14775 /* GPR[rt] = memory[base]; */ 14776 assign(t1, load(Ity_I32, getIReg(rs))); 14777 putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True)); 14778 14779 /* memory[base] = memory[base] + v; */ 14780 store(getIReg(rs), binop(Iop_Add32, mkexpr(t0), mkexpr(t1))); 14781 break; 14782 14783 case 0x12: /* LDADDD - Swap Word - Netlogic */ 14784 DIP("ldaddw r%u, r%u", rt, rs); 14785 t0 = newTemp(Ity_I64); 14786 t1 = newTemp(Ity_I64); 14787 14788 /* v = GPR[rt] */ 14789 assign(t0, getIReg(rt)); 14790 14791 /* GPR[rt] = memory[base]; */ 14792 assign(t1, load(Ity_I64, getIReg(rs))); 14793 putIReg(rt, mkexpr(t1)); 14794 14795 /* memory[base] = memory[base] + v; */ 14796 store(getIReg(rs), binop(Iop_Add64, mkexpr(t0), mkexpr(t1))); 14797 break; 14798 14799 case 0x14: /* SWAPW - Swap Word - Netlogic */ 14800 DIP("swapw r%u, r%u", rt, rs); 14801 t0 = newTemp(Ity_I32); 14802 t1 = newTemp(Ity_I32); 14803 assign(t0, mkNarrowTo32(ty, getIReg(rt))); 14804 assign(t1, load(Ity_I32, getIReg(rs))); 14805 putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True)); 14806 store(getIReg(rs), mkexpr(t0)); 14807 break; 14808 14809 case 0x16: /* SWAPD - Swap Double - Netlogic */ 14810 DIP("swapw r%u, r%u", rt, rs); 14811 t0 = newTemp(Ity_I64); 14812 t1 = newTemp(Ity_I64); 14813 assign(t0, getIReg(rt)); 14814 assign(t1, load(Ity_I64, getIReg(rs))); 14815 putIReg(rt, mkexpr(t1)); 14816 store(getIReg(rs), mkexpr(t0)); 14817 break; 14818 14819 case 0x20: { /* CLZ */ 14820 DIP("clz r%d, r%d", rd, rs); 14821 if (mode64) { 14822 IRTemp tmpClz32 = newTemp(Ity_I32); 14823 IRTemp tmpRs32 = newTemp(Ity_I32); 14824 14825 assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); 14826 assign(tmpClz32, unop(Iop_Clz32, mkexpr(tmpRs32))); 14827 putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClz32), True)); 14828 } else { 14829 t1 = newTemp(Ity_I1); 14830 assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0))); 14831 putIReg(rd, IRExpr_ITE(mkexpr(t1), 14832 mkU32(0x00000020), 14833 unop(Iop_Clz32, getIReg(rs)))); 14834 } 14835 break; 14836 } 14837 14838 case 0x21: { /* CLO */ 14839 DIP("clo r%d, r%d", rd, rs); 14840 if (mode64) { 14841 IRTemp tmpClo32 = newTemp(Ity_I32); 14842 IRTemp tmpRs32 = newTemp(Ity_I32); 14843 assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); 14844 14845 t1 = newTemp(Ity_I1); 14846 assign(t1, binop(Iop_CmpEQ32, mkexpr(tmpRs32), mkU32(0xffffffff))); 14847 assign(tmpClo32, IRExpr_ITE(mkexpr(t1), 14848 mkU32(0x00000020), 14849 unop(Iop_Clz32, unop(Iop_Not32, mkexpr(tmpRs32))))); 14850 14851 putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpClo32), True)); 14852 break; 14853 } else { 14854 t1 = newTemp(Ity_I1); 14855 assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0xffffffff))); 14856 putIReg(rd, IRExpr_ITE(mkexpr(t1), 14857 mkU32(0x00000020), 14858 unop(Iop_Clz32, 14859 unop(Iop_Not32, getIReg(rs))))); 14860 break; 14861 } 14862 } 14863 14864 case 0x24: /* Count Leading Zeros in Doubleword - DCLZ; MIPS64 */ 14865 DIP("dclz r%d, r%d", rd, rs); 14866 t1 = newTemp(Ity_I1); 14867 assign(t1, binop(Iop_CmpEQ64, getIReg(rs), mkU64(0))); 14868 putIReg(rd, IRExpr_ITE(mkexpr(t1), 14869 mkU64(0x00000040), 14870 unop(Iop_Clz64, getIReg(rs)))); 14871 break; 14872 14873 case 0x25: /* Count Leading Ones in Doubleword - DCLO; MIPS64 */ 14874 DIP("dclo r%d, r%d", rd, rs); 14875 t1 = newTemp(Ity_I1); 14876 assign(t1, binop(Iop_CmpEQ64, getIReg(rs), 14877 mkU64(0xffffffffffffffffULL))); 14878 putIReg(rd, IRExpr_ITE(mkexpr(t1), 14879 mkU64(0x40), 14880 unop(Iop_Clz64, unop(Iop_Not64, 14881 getIReg(rs))))); 14882 break; 14883 14884 default: 14885 goto decode_failure; 14886 } 14887 break; 14888 14889 case 0x1F: /* Special3 */ 14890 switch (function) { 14891 case 0x01: { 14892 /* Doubleword Extract Bit Field - DEXTM; MIPS64r2 */ 14893 msb = get_msb(cins); 14894 lsb = get_lsb(cins); 14895 size = msb + 1; 14896 UInt srcPos = lsb; 14897 UInt dstSz = msb + 33; 14898 t1 = newTemp(Ity_I64); 14899 DIP("dextm r%u, r%u, %d, %d", rt, rs, lsb, msb + 1); 14900 14901 UChar lsAmt = 64 - (srcPos + dstSz); /* left shift amount; */ 14902 UChar rsAmt = 64 - dstSz; /* right shift amount; */ 14903 14904 assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt))); 14905 putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt))); 14906 14907 break; 14908 } 14909 case 0x02: { 14910 /* Doubleword Extract Bit Field Upper - DEXTU; MIPS64r2 */ 14911 msb = get_msb(cins); 14912 lsb = get_lsb(cins); 14913 size = msb + 1; 14914 UInt srcPos = lsb + 32; 14915 UInt dstSz = msb + 1; 14916 DIP("dextu r%u, r%u, %d, %d", rt, rs, srcPos, dstSz); 14917 t1 = newTemp(Ity_I64); 14918 14919 vassert(srcPos >= 32 && srcPos < 64); 14920 vassert(dstSz > 0 && dstSz <= 32); 14921 vassert((srcPos + dstSz) > 32 && (srcPos + dstSz) <= 64); 14922 14923 UChar lsAmt = 64 - (srcPos + dstSz); /* left shift amount; */ 14924 UChar rsAmt = 64 - dstSz; /* right shift amount; */ 14925 14926 assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt))); 14927 putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt))); 14928 break; 14929 } 14930 case 0x05: { 14931 /* Doubleword Insert Bit Field Middle - DINSM; MIPS64r2 */ 14932 msb = get_msb(cins); 14933 lsb = get_lsb(cins); 14934 size = msb + 1; 14935 UInt dstPos = lsb; 14936 UInt srcSz = msb - lsb + 33; 14937 t1 = newTemp(ty); 14938 t2 = newTemp(ty); 14939 t3 = newTemp(ty); 14940 t4 = newTemp(ty); 14941 IRTemp tmpT1 = newTemp(ty); 14942 IRTemp tmpT2 = newTemp(ty); 14943 IRTemp tmpT3 = newTemp(ty); 14944 IRTemp tmpT4 = newTemp(ty); 14945 IRTemp tmpT5 = newTemp(ty); 14946 IRTemp tmpT6 = newTemp(ty); 14947 IRTemp tmpT7 = newTemp(ty); 14948 IRTemp tmpRs = newTemp(ty); 14949 IRTemp tmpRt = newTemp(ty); 14950 IRTemp tmpRd = newTemp(ty); 14951 14952 assign(tmpRs, getIReg(rs)); 14953 assign(tmpRt, getIReg(rt)); 14954 DIP("dinsm r%u, r%u, %d, %d", rt, rs, lsb, msb); 14955 14956 UChar lsAmt = dstPos + srcSz - 1; /* left shift amount; */ 14957 UChar rsAmt = dstPos + srcSz - 1; /* right shift amount; */ 14958 14959 assign(t1, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt))); 14960 assign(tmpT1, binop(Iop_Shr64, mkexpr(t1), mkU8(1))); 14961 assign(t2, binop(Iop_Shl64, mkexpr(tmpT1), mkU8(lsAmt))); 14962 assign(tmpT2, binop(Iop_Shl64, mkexpr(t2), mkU8(1))); 14963 14964 lsAmt = 63 - dstPos; /* left shift amount; */ 14965 rsAmt = 63 - dstPos; /* right shift amount; */ 14966 14967 assign(t3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt))); 14968 assign(tmpT3, binop(Iop_Shl64, mkexpr(t3), mkU8(1))); 14969 assign(t4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt))); 14970 assign(tmpT4, binop(Iop_Shr64, mkexpr(t4), mkU8(1))); 14971 14972 /* extract size from src register */ 14973 lsAmt = 64 - srcSz; /* left shift amount; */ 14974 rsAmt = 64 - (lsb + srcSz); /* right shift amount; */ 14975 14976 assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt))); 14977 assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(rsAmt))); 14978 14979 assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT4))); 14980 assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT7))); 14981 putIReg(rt, mkexpr(tmpRd)); 14982 break; 14983 } 14984 case 0x06: { 14985 /* Doubleword Insert Bit Field Upper - DINSU; MIPS64r2 */ 14986 msb = get_msb(cins); 14987 lsb = get_lsb(cins); 14988 size = msb + 1; 14989 UInt dstPos = lsb + 32; 14990 UInt srcSz = msb - lsb + 1; 14991 IRTemp tmpT1 = newTemp(ty); 14992 IRTemp tmpT2 = newTemp(ty); 14993 IRTemp tmpT3 = newTemp(ty); 14994 IRTemp tmpT4 = newTemp(ty); 14995 IRTemp tmpT5 = newTemp(ty); 14996 IRTemp tmpT6 = newTemp(ty); 14997 IRTemp tmpT7 = newTemp(ty); 14998 IRTemp tmpT8 = newTemp(ty); 14999 IRTemp tmpT9 = newTemp(ty); 15000 IRTemp tmpRs = newTemp(ty); 15001 IRTemp tmpRt = newTemp(ty); 15002 IRTemp tmpRd = newTemp(ty); 15003 15004 assign(tmpRs, getIReg(rs)); 15005 assign(tmpRt, getIReg(rt)); 15006 DIP("dinsu r%u, r%u, %d, %d", rt, rs, lsb, msb); 15007 15008 UChar lsAmt = 64 - srcSz; /* left shift amount; */ 15009 UChar rsAmt = 64 - (dstPos + srcSz); /* right shift amount; */ 15010 assign(tmpT1, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt))); 15011 assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt))); 15012 15013 lsAmt = 64 - dstPos; /* left shift amount; */ 15014 rsAmt = 64 - dstPos; /* right shift amount; */ 15015 assign(tmpT3, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt))); 15016 assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(rsAmt))); 15017 15018 lsAmt = dstPos; /* left shift amount; */ 15019 rsAmt = srcSz; /* right shift amount; */ 15020 assign(tmpT5, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt))); 15021 assign(tmpT6, binop(Iop_Shr64, mkexpr(tmpT5), mkU8(lsAmt))); 15022 15023 assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpT6), mkU8(rsAmt))); 15024 assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(lsAmt))); 15025 15026 assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT4))); 15027 assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT9))); 15028 putIReg(rt, mkexpr(tmpRd)); 15029 break; 15030 } 15031 case 0x07: { 15032 /* Doubleword Insert Bit Field - DINS; MIPS64r2 */ 15033 IRTemp tmp1 = newTemp(ty); 15034 IRTemp tmpT1 = newTemp(ty); 15035 IRTemp tmpT2 = newTemp(ty); 15036 IRTemp tmpT3 = newTemp(ty); 15037 IRTemp tmpT4 = newTemp(ty); 15038 IRTemp tmpT5 = newTemp(ty); 15039 IRTemp tmpT6 = newTemp(ty); 15040 IRTemp tmpT7 = newTemp(ty); 15041 IRTemp tmpT8 = newTemp(ty); 15042 IRTemp tmpT9 = newTemp(ty); 15043 IRTemp tmp = newTemp(ty); 15044 IRTemp tmpRs = newTemp(ty); 15045 IRTemp tmpRt = newTemp(ty); 15046 IRTemp tmpRd = newTemp(ty); 15047 15048 assign(tmpRs, getIReg(rs)); 15049 assign(tmpRt, getIReg(rt)); 15050 15051 msb = get_msb(cins); 15052 lsb = get_lsb(cins); 15053 size = msb + 1; 15054 DIP("dins r%u, r%u, %d, %d", rt, rs, lsb, 15055 msb - lsb + 1); 15056 UChar lsAmt = 63 - lsb; /* left shift amount; */ 15057 UChar rsAmt = 63 - lsb; /* right shift amount; */ 15058 assign(tmp, binop(Iop_Shl64, mkexpr(tmpRt), mkU8(lsAmt))); 15059 assign(tmpT1, binop(Iop_Shl64, mkexpr(tmp), mkU8(1))); 15060 assign(tmp1, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(rsAmt))); 15061 assign(tmpT2, binop(Iop_Shr64, mkexpr(tmp1), mkU8(1))); 15062 15063 lsAmt = msb; /* left shift amount; */ 15064 rsAmt = 1; /*right shift amount; */ 15065 assign(tmpT3, binop(Iop_Shr64, mkexpr(tmpRt), mkU8(rsAmt))); 15066 assign(tmpT4, binop(Iop_Shr64, mkexpr(tmpT3), mkU8(lsAmt))); 15067 assign(tmpT5, binop(Iop_Shl64, mkexpr(tmpT4), mkU8(rsAmt))); 15068 assign(tmpT6, binop(Iop_Shl64, mkexpr(tmpT5), mkU8(lsAmt))); 15069 15070 lsAmt = 64 - (msb - lsb + 1); /* left shift amount; */ 15071 rsAmt = 64 - (msb + 1); /* right shift amount; */ 15072 assign(tmpT7, binop(Iop_Shl64, mkexpr(tmpRs), mkU8(lsAmt))); 15073 assign(tmpT8, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(rsAmt))); 15074 15075 assign(tmpT9, binop(Iop_Or64, mkexpr(tmpT2), mkexpr(tmpT8))); 15076 assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT6), mkexpr(tmpT9))); 15077 putIReg(rt, mkexpr(tmpRd)); 15078 break; 15079 } 15080 case 0x24: /* DBSHFL */ 15081 lsb = get_lsb(cins); 15082 IRTemp tmpRs = newTemp(ty); 15083 IRTemp tmpRt = newTemp(ty); 15084 IRTemp tmpRd = newTemp(ty); 15085 assign(tmpRs, getIReg(rs)); 15086 assign(tmpRt, getIReg(rt)); 15087 switch (lsb) { 15088 case 0x02: { /* DSBH */ 15089 DIP("dsbh r%u, r%u", rd, rt); 15090 IRTemp tmpT1 = newTemp(ty); 15091 IRTemp tmpT2 = newTemp(ty); 15092 IRTemp tmpT3 = newTemp(ty); 15093 IRTemp tmpT4 = newTemp(ty); 15094 IRTemp tmpT5 = newTemp(Ity_I64); 15095 IRTemp tmpT6 = newTemp(ty); 15096 assign(tmpT5, mkU64(0xFF00FF00FF00FF00ULL)); 15097 assign(tmpT6, mkU64(0x00FF00FF00FF00FFULL)); 15098 assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5))); 15099 assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(8))); 15100 assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6))); 15101 assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(8))); 15102 assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2))); 15103 putIReg(rd, mkexpr(tmpRd)); 15104 break; 15105 } 15106 case 0x05: { /* DSHD */ 15107 DIP("dshd r%u, r%u\n", rd, rt); 15108 IRTemp tmpT1 = newTemp(ty); 15109 IRTemp tmpT2 = newTemp(ty); 15110 IRTemp tmpT3 = newTemp(ty); 15111 IRTemp tmpT4 = newTemp(ty); 15112 IRTemp tmpT5 = newTemp(Ity_I64); 15113 IRTemp tmpT6 = newTemp(ty); 15114 IRTemp tmpT7 = newTemp(ty); 15115 IRTemp tmpT8 = newTemp(ty); 15116 IRTemp tmpT9 = newTemp(ty); 15117 assign(tmpT5, mkU64(0xFFFF0000FFFF0000ULL)); 15118 assign(tmpT6, mkU64(0x0000FFFF0000FFFFULL)); 15119 assign(tmpT1, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT5))); 15120 assign(tmpT2, binop(Iop_Shr64, mkexpr(tmpT1), mkU8(16))); 15121 assign(tmpT3, binop(Iop_And64, mkexpr(tmpRt), mkexpr(tmpT6))); 15122 assign(tmpT4, binop(Iop_Shl64, mkexpr(tmpT3), mkU8(16))); 15123 assign(tmpT7, binop(Iop_Or64, mkexpr(tmpT4), mkexpr(tmpT2))); 15124 assign(tmpT8, binop(Iop_Shl64, mkexpr(tmpT7), mkU8(32))); 15125 assign(tmpT9, binop(Iop_Shr64, mkexpr(tmpT7), mkU8(32))); 15126 assign(tmpRd, binop(Iop_Or64, mkexpr(tmpT8), mkexpr(tmpT9))); 15127 putIReg(rd, mkexpr(tmpRd)); 15128 break; 15129 } 15130 default: 15131 vex_printf("\nop6o10 = %d", lsb); 15132 goto decode_failure;; 15133 } 15134 break; 15135 case 0x3B: { /* RDHWR */ 15136 DIP("rdhwr r%d, r%d", rt, rd); 15137 if (rd == 29) { 15138 putIReg(rt, getULR()); 15139 #if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2)) 15140 } else if (rd == 1) { 15141 if (mode64) { 15142 IRTemp val = newTemp(Ity_I64); 15143 IRExpr** args = mkIRExprVec_2 (mkU64(rt), mkU64(rd)); 15144 IRDirty *d = unsafeIRDirty_1_N(val, 15145 0, 15146 "mips64_dirtyhelper_rdhwr", 15147 &mips64_dirtyhelper_rdhwr, 15148 args); 15149 stmt(IRStmt_Dirty(d)); 15150 putIReg(rt, mkexpr(val)); 15151 } else { 15152 IRTemp val = newTemp(Ity_I32); 15153 IRExpr** args = mkIRExprVec_2 (mkU32(rt), mkU32(rd)); 15154 IRDirty *d = unsafeIRDirty_1_N(val, 15155 0, 15156 "mips32_dirtyhelper_rdhwr", 15157 &mips32_dirtyhelper_rdhwr, 15158 args); 15159 stmt(IRStmt_Dirty(d)); 15160 putIReg(rt, mkexpr(val)); 15161 } 15162 #endif 15163 } else 15164 goto decode_failure; 15165 break; 15166 } 15167 case 0x04: /* INS */ 15168 msb = get_msb(cins); 15169 lsb = get_lsb(cins); 15170 size = msb - lsb + 1; 15171 DIP("ins size:%d msb:%d lsb:%d", size, msb, lsb); 15172 15173 vassert(lsb + size <= 32); 15174 vassert(lsb + size > 0); 15175 15176 /* put size bits from rs at the pos in temporary */ 15177 t0 = newTemp(Ity_I32); 15178 t3 = newTemp(Ity_I32); 15179 /* shift left for 32 - size to clear leading bits and get zeros 15180 at the end */ 15181 assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)), 15182 mkU8(32 - size))); 15183 /* now set it at pos */ 15184 t1 = newTemp(Ity_I32); 15185 assign(t1, binop(Iop_Shr32, mkexpr(t0), mkU8(32 - size - lsb))); 15186 15187 if (lsb > 0) { 15188 t2 = newTemp(Ity_I32); 15189 /* clear everything but lower pos bits from rt */ 15190 assign(t2, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rt)), 15191 mkU8(32 - lsb))); 15192 assign(t3, binop(Iop_Shr32, mkexpr(t2), mkU8(32 - lsb))); 15193 } else 15194 assign(t3, mkU32(0)); 15195 15196 if (msb < 31) { 15197 t4 = newTemp(Ity_I32); 15198 /* clear everything but upper msb + 1 bits from rt */ 15199 assign(t4, binop(Iop_Shr32, mkNarrowTo32(ty, getIReg(rt)), 15200 mkU8(msb + 1))); 15201 t5 = newTemp(Ity_I32); 15202 assign(t5, binop(Iop_Shl32, mkexpr(t4), mkU8(msb + 1))); 15203 15204 /* now combine these registers */ 15205 if (lsb > 0) { 15206 t6 = newTemp(Ity_I32); 15207 assign(t6, binop(Iop_Or32, mkexpr(t5), mkexpr(t1))); 15208 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t6), 15209 mkexpr(t3)), True)); 15210 } else { 15211 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1), 15212 mkexpr(t5)), True)); 15213 } 15214 } else { 15215 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Or32, mkexpr(t1), 15216 mkexpr(t3)), True)); 15217 } 15218 break; 15219 15220 case 0x00: /* EXT */ 15221 msb = get_msb(cins); 15222 lsb = get_lsb(cins); 15223 size = msb + 1; 15224 DIP("ext size:%d msb:%d lsb:%d", size, msb, lsb); 15225 vassert(lsb + size <= 32); 15226 vassert(lsb + size > 0); 15227 /* put size bits from rs at the top of in temporary */ 15228 if (lsb + size < 32) { 15229 t0 = newTemp(Ity_I32); 15230 assign(t0, binop(Iop_Shl32, mkNarrowTo32(ty, getIReg(rs)), 15231 mkU8(32 - lsb - size))); 15232 15233 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32, mkexpr(t0), 15234 mkU8(32 - size)), True)); 15235 } else { 15236 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Shr32, 15237 mkNarrowTo32(ty, getIReg(rs)), 15238 mkU8(32 - size)), True)); 15239 } 15240 break; 15241 15242 case 0x03: /* Doubleword Extract Bit Field - DEXT; MIPS64r2 */ 15243 msb = get_msb(cins); 15244 lsb = get_lsb(cins); 15245 size = msb + 1; 15246 DIP("dext r%u, r%u, %d, %d", rt, rs, lsb, msb + 1); 15247 t1 = newTemp(Ity_I64); 15248 vassert(lsb >= 0 && lsb < 32); 15249 vassert(size > 0 && size <= 32); 15250 vassert((lsb + size) > 0 && (lsb + size) <= 63); 15251 15252 UChar lsAmt = 63 - (lsb + msb); /* left shift amount; */ 15253 UChar rsAmt = 63 - msb; /* right shift amount; */ 15254 15255 assign(t1, binop(Iop_Shl64, getIReg(rs), mkU8(lsAmt))); 15256 putIReg(rt, binop(Iop_Shr64, mkexpr(t1), mkU8(rsAmt))); 15257 15258 break; 15259 15260 case 0x20: /* BSHFL */ 15261 switch (sa) { 15262 case 0x02: /* WSBH */ 15263 DIP("wsbh r%d, r%d", rd, rt); 15264 t0 = newTemp(Ity_I32); 15265 t1 = newTemp(Ity_I32); 15266 t2 = newTemp(Ity_I32); 15267 t3 = newTemp(Ity_I32); 15268 assign(t0, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty, 15269 getIReg(rt)), mkU32(0x00FF0000)), 15270 mkU8(0x8))); 15271 assign(t1, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty, 15272 getIReg(rt)), mkU32(0xFF000000)), mkU8(0x8))); 15273 assign(t2, binop(Iop_Shl32, binop(Iop_And32, mkNarrowTo32(ty, 15274 getIReg(rt)), mkU32(0x000000FF)), mkU8(0x8))); 15275 assign(t3, binop(Iop_Shr32, binop(Iop_And32, mkNarrowTo32(ty, 15276 getIReg(rt)), mkU32(0x0000FF00)), mkU8(0x8))); 15277 putIReg(rd, mkWidenFrom32(ty, binop(Iop_Or32, binop(Iop_Or32, 15278 mkexpr(t0), mkexpr(t1)), 15279 binop(Iop_Or32, mkexpr(t2), 15280 mkexpr(t3))), True)); 15281 break; 15282 15283 case 0x10: /* SEB */ 15284 DIP("seb r%d, r%d", rd, rt); 15285 if (mode64) 15286 putIReg(rd, unop(Iop_8Sto64, unop(Iop_64to8, getIReg(rt)))); 15287 else 15288 putIReg(rd, unop(Iop_8Sto32, unop(Iop_32to8, getIReg(rt)))); 15289 break; 15290 15291 case 0x18: /* SEH */ 15292 DIP("seh r%d, r%d", rd, rt); 15293 if (mode64) 15294 putIReg(rd, unop(Iop_16Sto64, unop(Iop_64to16, getIReg(rt)))); 15295 else 15296 putIReg(rd, unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt)))); 15297 break; 15298 15299 default: 15300 goto decode_failure; 15301 15302 } 15303 break; /* BSHFL */ 15304 15305 /* --- MIPS32(r2) DSP ASE(r2) / Cavium Specfic (LX) instructions --- */ 15306 case 0xA: /* LX */ 15307 if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) { 15308 if (dis_instr_CVM(cins)) 15309 break; 15310 goto decode_failure; 15311 } 15312 case 0xC: /* INSV */ 15313 case 0x38: { /* EXTR.W */ 15314 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15315 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15316 if (0 != retVal ) { 15317 goto decode_failure_dsp; 15318 } 15319 break; 15320 } else { 15321 goto decode_failure_dsp; 15322 } 15323 break; 15324 } 15325 case 0x10: { /* ADDU.QB */ 15326 switch(sa) { 15327 case 0xC: /* SUBU_S.PH */ 15328 case 0xD: /* ADDU_S.PH */ 15329 case 0x1E: { /* MULQ_S.PH */ 15330 if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) { 15331 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15332 if (0 != retVal ) { 15333 goto decode_failure_dsp; 15334 } 15335 break; 15336 } else { 15337 goto decode_failure_dsp; 15338 } 15339 break; 15340 } 15341 default: { 15342 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15343 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15344 if (0 != retVal ) { 15345 goto decode_failure_dsp; 15346 } 15347 break; 15348 } else { 15349 goto decode_failure_dsp; 15350 } 15351 break; 15352 } 15353 } 15354 break; 15355 } 15356 case 0x11: { /* CMPU.EQ.QB */ 15357 switch(sa) { 15358 case 0x18: /* CMPGDU.EQ.QB */ 15359 case 0x19: /* CMPGDU.LT.QB */ 15360 case 0x1A: /* CMPGDU.LE.QB */ 15361 case 0x0D: /* PRECR.QB.PH */ 15362 case 0x1E: /* PRECR_SRA.PH.W */ 15363 case 0x1F: { /* PRECR_SRA_R.PH.W */ 15364 if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) { 15365 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15366 if (0 != retVal ) { 15367 goto decode_failure_dsp; 15368 } 15369 break; 15370 } else { 15371 goto decode_failure_dsp; 15372 } 15373 break; 15374 } 15375 default: { 15376 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15377 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15378 if (0 != retVal ) { 15379 goto decode_failure_dsp; 15380 } 15381 break; 15382 } else { 15383 goto decode_failure_dsp; 15384 } 15385 break; 15386 } 15387 } 15388 break; 15389 } 15390 case 0x12: { /* ABSQ_S.PH */ 15391 switch(sa){ 15392 case 0x1: { /* ABSQ_S.QB */ 15393 if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) { 15394 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15395 if (0 != retVal ) { 15396 goto decode_failure_dsp; 15397 } 15398 break; 15399 } else { 15400 goto decode_failure_dsp; 15401 } 15402 break; 15403 } 15404 default: { 15405 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15406 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15407 if (0 != retVal ) { 15408 goto decode_failure_dsp; 15409 } 15410 break; 15411 } else { 15412 goto decode_failure_dsp; 15413 } 15414 break; 15415 } 15416 } 15417 break; 15418 } 15419 case 0x13: { /* SHLL.QB */ 15420 switch(sa) { 15421 case 0x04: /* SHRA.QB */ 15422 case 0x05: /* SHRA_R.QB */ 15423 case 0x06: /* SHRAV.QB */ 15424 case 0x07: /* SHRAV_R.QB */ 15425 case 0x19: /* SHLR.PH */ 15426 case 0x1B: { /* SHLRV.PH */ 15427 if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) { 15428 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15429 if (0 != retVal ) { 15430 goto decode_failure_dsp; 15431 } 15432 break; 15433 } else { 15434 goto decode_failure_dsp; 15435 } 15436 break; 15437 } 15438 default: { 15439 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15440 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15441 if (0 != retVal ) { 15442 goto decode_failure_dsp; 15443 } 15444 break; 15445 } else { 15446 goto decode_failure_dsp; 15447 } 15448 break; 15449 } 15450 } 15451 break; 15452 } 15453 case 0x30: { /* DPAQ.W.PH */ 15454 switch(sa) { 15455 case 0x0: /* DPA.W.PH */ 15456 case 0x18: /* DPAQX_S.W.PH */ 15457 case 0x1A: /* DPAQX_SA.W.PH */ 15458 case 0x8: /* DPAX.W.PH */ 15459 case 0x1: /* DPS.W.PH */ 15460 case 0x19: /* DPSQX_S.W.PH */ 15461 case 0x1B: /* DPSQX_SA.W.PH */ 15462 case 0x9: /* DPSX.W.PH */ 15463 case 0x2: { /* MULSA.W.PH */ 15464 if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) { 15465 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15466 if (0 != retVal ) { 15467 goto decode_failure_dsp; 15468 } 15469 break; 15470 } else { 15471 goto decode_failure_dsp; 15472 } 15473 break; 15474 } 15475 default: { 15476 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15477 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15478 if (0 != retVal ) { 15479 goto decode_failure_dsp; 15480 } 15481 break; 15482 } else { 15483 goto decode_failure_dsp; 15484 } 15485 break; 15486 } 15487 } 15488 break; 15489 } 15490 case 0x18: /* ADDUH.QB/MUL.PH */ 15491 case 0x31: { /* APPEND */ 15492 if (VEX_MIPS_PROC_DSP2(archinfo->hwcaps)) { 15493 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15494 if (0 != retVal ) { 15495 goto decode_failure_dsp; 15496 } 15497 break; 15498 } else { 15499 goto decode_failure_dsp; 15500 } 15501 } 15502 default: 15503 goto decode_failure; 15504 15505 } 15506 break; /* Special3 */ 15507 15508 case 0x3B: 15509 if (0x3B == function && 15510 (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_BROADCOM)) { 15511 /*RDHWR*/ 15512 DIP("rdhwr r%d, r%d", rt, rd); 15513 if (rd == 29) { 15514 putIReg(rt, getULR()); 15515 } else 15516 goto decode_failure; 15517 break; 15518 } else { 15519 goto decode_failure; 15520 } 15521 15522 case 0x00: /* Special */ 15523 15524 switch (function) { 15525 case 0x1: { 15526 UInt mov_cc = get_mov_cc(cins); 15527 if (tf == 0) { /* MOVF */ 15528 DIP("movf r%d, r%d, %d", rd, rs, mov_cc); 15529 t1 = newTemp(Ity_I1); 15530 t2 = newTemp(Ity_I32); 15531 t3 = newTemp(Ity_I1); 15532 15533 assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc))); 15534 assign(t2, IRExpr_ITE(mkexpr(t1), 15535 binop(Iop_And32, 15536 binop(Iop_Shr32, getFCSR(), 15537 mkU8(23)), 15538 mkU32(0x1)), 15539 binop(Iop_And32, 15540 binop(Iop_Shr32, getFCSR(), 15541 mkU8(24 + mov_cc)), 15542 mkU32(0x1)) 15543 )); 15544 assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2))); 15545 putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd))); 15546 } else if (tf == 1) { /* MOVT */ 15547 DIP("movt r%d, r%d, %d", rd, rs, mov_cc); 15548 t1 = newTemp(Ity_I1); 15549 t2 = newTemp(Ity_I32); 15550 t3 = newTemp(Ity_I1); 15551 15552 assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(mov_cc))); 15553 assign(t2, IRExpr_ITE(mkexpr(t1), 15554 binop(Iop_And32, 15555 binop(Iop_Shr32, getFCSR(), 15556 mkU8(23)), 15557 mkU32(0x1)), 15558 binop(Iop_And32, 15559 binop(Iop_Shr32, getFCSR(), 15560 mkU8(24 + mov_cc)), 15561 mkU32(0x1)) 15562 )); 15563 assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2))); 15564 putIReg(rd, IRExpr_ITE(mkexpr(t3), getIReg(rs), getIReg(rd))); 15565 } 15566 break; 15567 } 15568 case 0x0A: { /* MOVZ */ 15569 DIP("movz r%d, r%d, r%d", rd, rs, rt); 15570 t1 = newTemp(ty); 15571 t2 = newTemp(ty); 15572 if (mode64) { 15573 assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64, 15574 getIReg(rt), mkU64(0x0))))); 15575 assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64, 15576 getIReg(rt), mkU64(0x0))))); 15577 putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs), 15578 mkexpr(t1)), binop(Iop_And64, getIReg(rd),mkexpr(t2)))); 15579 } else { 15580 assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt), 15581 mkU32(0x0)))); 15582 assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt), 15583 mkU32(0x0)))); 15584 putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs), 15585 mkexpr(t1)), binop(Iop_And32, getIReg(rd), 15586 mkexpr(t2)))); 15587 } 15588 break; 15589 } 15590 15591 case 0x0B: { /* MOVN */ 15592 DIP("movn r%d, r%d, r%d", rd, rs, rt); 15593 t1 = newTemp(ty); 15594 t2 = newTemp(ty); 15595 if (mode64) { 15596 assign(t1, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpEQ64, 15597 getIReg(rt), mkU64(0x0))))); 15598 assign(t2, unop(Iop_32Sto64, unop(Iop_1Sto32, binop(Iop_CmpNE64, 15599 getIReg(rt), mkU64(0x0))))); 15600 putIReg(rd, binop(Iop_Add64, binop(Iop_And64, getIReg(rs), 15601 mkexpr(t2)), binop(Iop_And64, getIReg(rd), 15602 mkexpr(t1)))); 15603 } else { 15604 assign(t1, unop(Iop_1Sto32, binop(Iop_CmpEQ32, getIReg(rt), 15605 mkU32(0x0)))); 15606 assign(t2, unop(Iop_1Sto32, binop(Iop_CmpNE32, getIReg(rt), 15607 mkU32(0x0)))); 15608 putIReg(rd, binop(Iop_Add32, binop(Iop_And32, getIReg(rs), 15609 mkexpr(t2)), binop(Iop_And32, getIReg(rd), 15610 mkexpr(t1)))); 15611 } 15612 break; 15613 } 15614 15615 case 0x18: { /* MULT */ 15616 if ( (1 <= ac) && ( 3 >= ac) ) { 15617 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15618 /* If DSP is present -> DSP ASE MULT */ 15619 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15620 if (0 != retVal ) { 15621 goto decode_failure_dsp; 15622 } 15623 break; 15624 } else { 15625 goto decode_failure_dsp; 15626 } 15627 } else { 15628 DIP("mult r%d, r%d", rs, rt); 15629 t2 = newTemp(Ity_I64); 15630 15631 assign(t2, binop(Iop_MullS32, mkNarrowTo32(ty, getIReg(rs)), 15632 mkNarrowTo32(ty, getIReg(rt)))); 15633 15634 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True)); 15635 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True)); 15636 break; 15637 } 15638 } 15639 case 0x19: { /* MULTU */ 15640 if ( (1 <= ac) && ( 3 >= ac) ) { 15641 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15642 /* If DSP is present -> DSP ASE MULTU */ 15643 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15644 if (0 != retVal ) { 15645 goto decode_failure_dsp; 15646 } 15647 break; 15648 } else { 15649 goto decode_failure_dsp; 15650 } 15651 } else { 15652 DIP("multu r%d, r%d", rs, rt); 15653 t2 = newTemp(Ity_I64); 15654 15655 assign(t2, binop(Iop_MullU32, mkNarrowTo32(ty, getIReg(rs)), 15656 mkNarrowTo32(ty, getIReg(rt)))); 15657 15658 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True)); 15659 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True)); 15660 break; 15661 } 15662 } 15663 case 0x20: { /* ADD */ 15664 DIP("add r%d, r%d, r%d", rd, rs, rt); 15665 IRTemp tmpRs32 = newTemp(Ity_I32); 15666 IRTemp tmpRt32 = newTemp(Ity_I32); 15667 15668 assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); 15669 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 15670 15671 t0 = newTemp(Ity_I32); 15672 t1 = newTemp(Ity_I32); 15673 t2 = newTemp(Ity_I32); 15674 t3 = newTemp(Ity_I32); 15675 t4 = newTemp(Ity_I32); 15676 /* dst = src0 + src1 15677 if (sign(src0 ) != sign(src1 )) 15678 goto no overflow; 15679 if (sign(dst) == sign(src0 )) 15680 goto no overflow; 15681 we have overflow! */ 15682 15683 assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(tmpRt32))); 15684 assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(tmpRt32))); 15685 assign(t2, unop(Iop_1Uto32, 15686 binop(Iop_CmpEQ32, 15687 binop(Iop_And32, mkexpr(t1), mkU32(0x80000000)), 15688 mkU32(0x80000000)))); 15689 15690 assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32))); 15691 assign(t4, unop(Iop_1Uto32, 15692 binop(Iop_CmpNE32, 15693 binop(Iop_And32, mkexpr(t3), mkU32(0x80000000)), 15694 mkU32(0x80000000)))); 15695 15696 stmt(IRStmt_Exit(binop(Iop_CmpEQ32, 15697 binop(Iop_Or32, mkexpr(t2), mkexpr(t4)), 15698 mkU32(0)), 15699 Ijk_SigFPE_IntOvf, 15700 mode64 ? IRConst_U64(guest_PC_curr_instr + 4) : 15701 IRConst_U32(guest_PC_curr_instr + 4), 15702 OFFB_PC)); 15703 15704 putIReg(rd, mkWidenFrom32(ty, mkexpr(t0), True)); 15705 break; 15706 } 15707 case 0x1A: /* DIV */ 15708 DIP("div r%d, r%d", rs, rt); 15709 if (mode64) { 15710 t2 = newTemp(Ity_I64); 15711 15712 assign(t2, binop(Iop_DivModS64to32, 15713 getIReg(rs), mkNarrowTo32(ty, getIReg(rt)))); 15714 15715 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True)); 15716 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True)); 15717 } else { 15718 t1 = newTemp(Ity_I64); 15719 t2 = newTemp(Ity_I64); 15720 15721 assign(t1, unop(Iop_32Sto64, getIReg(rs))); 15722 assign(t2, binop(Iop_DivModS64to32, mkexpr(t1), getIReg(rt))); 15723 15724 putHI(unop(Iop_64HIto32, mkexpr(t2))); 15725 putLO(unop(Iop_64to32, mkexpr(t2))); 15726 } 15727 break; 15728 15729 case 0x1B: /* DIVU */ 15730 DIP("divu r%d, r%d", rs, rt); 15731 if (mode64) { 15732 t2 = newTemp(Ity_I64); 15733 15734 assign(t2, binop(Iop_DivModU64to32, 15735 getIReg(rs), mkNarrowTo32(ty, getIReg(rt)))); 15736 15737 putHI(mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(t2)), True)); 15738 putLO(mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(t2)), True)); 15739 } else { 15740 t1 = newTemp(Ity_I64); 15741 t2 = newTemp(Ity_I64); 15742 assign(t1, unop(Iop_32Uto64, getIReg(rs))); 15743 assign(t2, binop(Iop_DivModU64to32, mkexpr(t1), getIReg(rt))); 15744 putHI(unop(Iop_64HIto32, mkexpr(t2))); 15745 putLO(unop(Iop_64to32, mkexpr(t2))); 15746 } 15747 break; 15748 15749 case 0x1C: /* Doubleword Multiply - DMULT; MIPS64 */ 15750 DIP("dmult r%u, r%u", rs, rt); 15751 t0 = newTemp(Ity_I128); 15752 15753 assign(t0, binop(Iop_MullS64, getIReg(rs), getIReg(rt))); 15754 15755 putHI(unop(Iop_128HIto64, mkexpr(t0))); 15756 putLO(unop(Iop_128to64, mkexpr(t0))); 15757 break; 15758 15759 case 0x1D: /* Doubleword Multiply Unsigned - DMULTU; MIPS64 */ 15760 DIP("dmultu r%u, r%u", rs, rt); 15761 t0 = newTemp(Ity_I128); 15762 15763 assign(t0, binop(Iop_MullU64, getIReg(rs), getIReg(rt))); 15764 15765 putHI(unop(Iop_128HIto64, mkexpr(t0))); 15766 putLO(unop(Iop_128to64, mkexpr(t0))); 15767 break; 15768 15769 case 0x1E: /* Doubleword Divide DDIV; MIPS64 */ 15770 DIP("ddiv r%u, r%u", rs, rt); 15771 t1 = newTemp(Ity_I128); 15772 15773 assign(t1, binop(Iop_DivModS64to64, getIReg(rs), getIReg(rt))); 15774 15775 putHI(unop(Iop_128HIto64, mkexpr(t1))); 15776 putLO(unop(Iop_128to64, mkexpr(t1))); 15777 break; 15778 15779 case 0x1F: /* Doubleword Divide Unsigned DDIVU; MIPS64 check this */ 15780 DIP("ddivu r%u, r%u", rs, rt); 15781 t1 = newTemp(Ity_I128); 15782 t2 = newTemp(Ity_I128); 15783 15784 assign(t1, binop(Iop_64HLto128, mkU64(0), getIReg(rs))); 15785 15786 assign(t2, binop(Iop_DivModU128to64, mkexpr(t1), getIReg(rt))); 15787 15788 putHI(unop(Iop_128HIto64, mkexpr(t2))); 15789 putLO(unop(Iop_128to64, mkexpr(t2))); 15790 break; 15791 15792 case 0x10: { /* MFHI */ 15793 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15794 /* If DSP is present -> DSP ASE MFHI */ 15795 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15796 if (0 != retVal ) { 15797 goto decode_failure; 15798 } 15799 break; 15800 } else { 15801 DIP("mfhi r%d", rd); 15802 putIReg(rd, getHI()); 15803 break; 15804 } 15805 } 15806 15807 case 0x11: { /* MTHI */ 15808 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15809 /* If DSP is present -> DSP ASE MTHI */ 15810 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15811 if (0 != retVal ) { 15812 goto decode_failure; 15813 } 15814 break; 15815 } else { 15816 DIP("mthi r%d", rs); 15817 putHI(getIReg(rs)); 15818 break; 15819 } 15820 } 15821 15822 case 0x12: { /* MFLO */ 15823 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15824 /* If DSP is present -> DSP ASE MFLO */ 15825 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15826 if (0 != retVal ) { 15827 goto decode_failure; 15828 } 15829 break; 15830 } else { 15831 DIP("mflo r%d", rd); 15832 putIReg(rd, getLO()); 15833 break; 15834 } 15835 } 15836 15837 case 0x13: { /* MTLO */ 15838 if (VEX_MIPS_PROC_DSP(archinfo->hwcaps)) { 15839 /* If DSP is present -> DSP ASE MTLO */ 15840 UInt retVal = disDSPInstr_MIPS_WRK ( cins ); 15841 if (0 != retVal ) { 15842 goto decode_failure; 15843 } 15844 break; 15845 } else { 15846 DIP("mtlo r%d", rs); 15847 putLO(getIReg(rs)); 15848 break; 15849 } 15850 } 15851 15852 case 0x21: /* ADDU */ 15853 DIP("addu r%d, r%d, r%d", rd, rs, rt); 15854 if (mode64) { 15855 ALU_PATTERN64(Iop_Add32); 15856 } else { 15857 ALU_PATTERN(Iop_Add32); 15858 } 15859 break; 15860 15861 case 0x22: { /* SUB */ 15862 DIP("sub r%d, r%d, r%d", rd, rs, rt); 15863 IRTemp tmpRs32 = newTemp(Ity_I32); 15864 IRTemp tmpRt32 = newTemp(Ity_I32); 15865 15866 assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); 15867 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 15868 t0 = newTemp(Ity_I32); 15869 t1 = newTemp(Ity_I32); 15870 t2 = newTemp(Ity_I32); 15871 t3 = newTemp(Ity_I32); 15872 t4 = newTemp(Ity_I32); 15873 t5 = newTemp(Ity_I32); 15874 /* dst = src0 + (-1 * src1) 15875 if(sign(src0 ) != sign((-1 * src1) )) 15876 goto no overflow; 15877 if(sign(dst) == sign(src0 )) 15878 goto no overflow; 15879 we have overflow! */ 15880 15881 assign(t5, binop(Iop_Mul32, mkexpr(tmpRt32), mkU32(-1))); 15882 assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), mkexpr(t5))); 15883 assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), mkexpr(t5))); 15884 assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32, 15885 mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000)))); 15886 15887 assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32))); 15888 assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32, 15889 mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000)))); 15890 15891 stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2), 15892 mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf, 15893 mode64 ? IRConst_U64(guest_PC_curr_instr + 4) : 15894 IRConst_U32(guest_PC_curr_instr + 4), 15895 OFFB_PC)); 15896 15897 putIReg(rd, mkWidenFrom32(ty, mkexpr(t0), True)); 15898 break; 15899 } 15900 case 0x23: /* SUBU */ 15901 DIP("subu r%d, r%d, r%d", rd, rs, rt); 15902 if (mode64) { 15903 ALU_PATTERN64(Iop_Sub32); 15904 } else { 15905 ALU_PATTERN(Iop_Sub32); 15906 } 15907 break; 15908 15909 case 0x24: /* AND */ 15910 DIP("and r%d, r%d, r%d", rd, rs, rt); 15911 if (mode64) { 15912 ALU_PATTERN(Iop_And64); 15913 } else { 15914 ALU_PATTERN(Iop_And32); 15915 } 15916 break; 15917 15918 case 0x25: /* OR */ 15919 DIP("or r%d, r%d, r%d", rd, rs, rt); 15920 if (mode64) { 15921 ALU_PATTERN(Iop_Or64); 15922 } else { 15923 ALU_PATTERN(Iop_Or32); 15924 } 15925 break; 15926 15927 case 0x26: /* XOR */ 15928 DIP("xor r%d, r%d, r%d", rd, rs, rt); 15929 if (mode64) { 15930 ALU_PATTERN(Iop_Xor64); 15931 } else { 15932 ALU_PATTERN(Iop_Xor32); 15933 } 15934 break; 15935 15936 case 0x27: /* NOR */ 15937 DIP("nor r%d, r%d, r%d", rd, rs, rt); 15938 if (mode64) 15939 putIReg(rd, unop(Iop_Not64, binop(Iop_Or64, getIReg(rs), 15940 getIReg(rt)))); 15941 else 15942 putIReg(rd, unop(Iop_Not32, binop(Iop_Or32, getIReg(rs), 15943 getIReg(rt)))); 15944 break; 15945 15946 case 0x08: /* JR */ 15947 DIP("jr r%d", rs); 15948 t0 = newTemp(ty); 15949 assign(t0, getIReg(rs)); 15950 lastn = mkexpr(t0); 15951 break; 15952 15953 case 0x09: /* JALR */ 15954 DIP("jalr r%d r%d", rd, rs); 15955 if (mode64) { 15956 putIReg(rd, mkU64(guest_PC_curr_instr + 8)); 15957 t0 = newTemp(Ity_I64); 15958 assign(t0, getIReg(rs)); 15959 lastn = mkexpr(t0); 15960 } else { 15961 putIReg(rd, mkU32(guest_PC_curr_instr + 8)); 15962 t0 = newTemp(Ity_I32); 15963 assign(t0, getIReg(rs)); 15964 lastn = mkexpr(t0); 15965 } 15966 break; 15967 15968 case 0x0C: /* SYSCALL */ 15969 DIP("syscall"); 15970 if (mode64) 15971 putPC(mkU64(guest_PC_curr_instr + 4)); 15972 else 15973 putPC(mkU32(guest_PC_curr_instr + 4)); 15974 dres.jk_StopHere = Ijk_Sys_syscall; 15975 dres.whatNext = Dis_StopHere; 15976 break; 15977 15978 case 0x2A: /* SLT */ 15979 DIP("slt r%d, r%d, r%d", rd, rs, rt); 15980 if (mode64) 15981 putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs), 15982 getIReg(rt)))); 15983 else 15984 putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs), 15985 getIReg(rt)))); 15986 break; 15987 15988 case 0x2B: /* SLTU */ 15989 DIP("sltu r%d, r%d, r%d", rd, rs, rt); 15990 if (mode64) 15991 putIReg(rd, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs), 15992 getIReg(rt)))); 15993 else 15994 putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs), 15995 getIReg(rt)))); 15996 break; 15997 15998 case 0x00: { /* SLL */ 15999 DIP("sll r%d, r%d, %d", rd, rt, sa); 16000 IRTemp tmpRt32 = newTemp(Ity_I32); 16001 IRTemp tmpSh32 = newTemp(Ity_I32); 16002 IRTemp tmpRd = newTemp(Ity_I64); 16003 if (mode64) { 16004 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 16005 assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkU8(sa))); 16006 assign(tmpRd, mkWidenFrom32(ty, mkexpr(tmpSh32), True)); 16007 putIReg(rd, mkexpr(tmpRd)); 16008 } else 16009 SXX_PATTERN(Iop_Shl32); 16010 break; 16011 } 16012 16013 case 0x04: { /* SLLV */ 16014 DIP("sllv r%d, r%d, r%d", rd, rt, rs); 16015 if (mode64) { 16016 IRTemp tmpRs8 = newTemp(Ity_I8); 16017 IRTemp tmpRt32 = newTemp(Ity_I32); 16018 IRTemp tmpSh32 = newTemp(Ity_I32); 16019 IRTemp tmp = newTemp(ty); 16020 assign(tmp, binop(mkSzOp(ty, Iop_And8), getIReg(rs), 16021 mkSzImm(ty, 31))); 16022 assign(tmpRs8, mkNarrowTo8(ty, mkexpr(tmp))); 16023 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 16024 assign(tmpSh32, binop(Iop_Shl32, mkexpr(tmpRt32), mkexpr(tmpRs8))); 16025 putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True)); 16026 } else { 16027 SXXV_PATTERN(Iop_Shl32); 16028 } 16029 break; 16030 } 16031 16032 case 0x03: /* SRA */ 16033 DIP("sra r%d, r%d, %d", rd, rt, sa); 16034 if (mode64) { 16035 IRTemp tmpRt32 = newTemp(Ity_I32); 16036 IRTemp tmpSh32 = newTemp(Ity_I32); 16037 16038 t1 = newTemp(Ity_I64); 16039 t2 = newTemp(Ity_I64); 16040 t3 = newTemp(Ity_I64); 16041 16042 assign(t1, binop(Iop_And64, getIReg(rt), /* hi */ 16043 mkU64(0xFFFFFFFF00000000ULL))); 16044 16045 assign(t2, binop(Iop_Sar64, mkexpr(t1), mkU8(sa))); 16046 16047 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 16048 assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkU8(sa))); 16049 16050 putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True)); 16051 } else { 16052 SXX_PATTERN(Iop_Sar32); 16053 } 16054 break; 16055 16056 case 0x07: /* SRAV */ 16057 DIP("srav r%d, r%d, r%d", rd, rt, rs); 16058 if (mode64) { 16059 IRTemp tmpRt32 = newTemp(Ity_I32); 16060 IRTemp tmpSh32 = newTemp(Ity_I32); 16061 16062 t1 = newTemp(Ity_I64); 16063 t2 = newTemp(Ity_I64); 16064 t3 = newTemp(Ity_I64); 16065 t4 = newTemp(Ity_I8); 16066 16067 assign(t4, unop(Iop_32to8, binop(Iop_And32, 16068 mkNarrowTo32(ty, getIReg(rs)), mkU32(0x0000001F)))); 16069 16070 assign(t1, binop(Iop_And64, getIReg(rt), /* hi */ 16071 mkU64(0xFFFFFFFF00000000ULL))); 16072 16073 assign(t2, binop(Iop_Sar64, mkexpr(t1), mkexpr(t4))); 16074 16075 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 16076 assign(tmpSh32, binop(Iop_Sar32, mkexpr(tmpRt32), mkexpr(t4))); 16077 16078 putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True)); 16079 } else { 16080 SXXV_PATTERN(Iop_Sar32); 16081 } 16082 break; 16083 16084 case 0x02: { /* SRL */ 16085 rot = get_rot(cins); 16086 if (rot) { 16087 DIP("rotr r%d, r%d, %d", rd, rt, sa); 16088 putIReg(rd, mkWidenFrom32(ty, genROR32(mkNarrowTo32(ty, 16089 getIReg(rt)), sa), True)); 16090 } else { 16091 DIP("srl r%d, r%d, %d", rd, rt, sa); 16092 if (mode64) { 16093 IRTemp tmpSh32 = newTemp(Ity_I32); 16094 IRTemp tmpRt32 = newTemp(Ity_I32); 16095 16096 assign(tmpRt32, mkNarrowTo32(ty, getIReg(rt))); 16097 assign(tmpSh32, binop(Iop_Shr32, mkexpr(tmpRt32), mkU8(sa))); 16098 putIReg(rd, mkWidenFrom32(ty, mkexpr(tmpSh32), True)); 16099 } else { 16100 SXX_PATTERN(Iop_Shr32); 16101 } 16102 } 16103 break; 16104 } 16105 16106 case 0x06: { 16107 rot = get_rotv(cins); 16108 if (rot) { 16109 DIP("rotrv r%d, r%d, r%d", rd, rt, rs); 16110 putIReg(rd, mkWidenFrom32(ty, genRORV32(mkNarrowTo32(ty, 16111 getIReg(rt)), mkNarrowTo32(ty, getIReg(rs))), True)); 16112 break; 16113 } else { /* SRLV */ 16114 DIP("srlv r%d, r%d, r%d", rd, rt, rs); 16115 if (mode64) { 16116 SXXV_PATTERN64(Iop_Shr32); 16117 } else { 16118 SXXV_PATTERN(Iop_Shr32); 16119 } 16120 break; 16121 } 16122 } 16123 16124 case 0x0D: /* BREAK */ 16125 DIP("break 0x%x", trap_code); 16126 if (mode64) 16127 jmp_lit64(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4)); 16128 else 16129 jmp_lit32(&dres, Ijk_SigTRAP, (guest_PC_curr_instr + 4)); 16130 vassert(dres.whatNext == Dis_StopHere); 16131 break; 16132 16133 case 0x30: { /* TGE */ 16134 DIP("tge r%d, r%d %d", rs, rt, trap_code); 16135 if (mode64) { 16136 if (trap_code == 7) 16137 stmt (IRStmt_Exit (unop (Iop_Not1, 16138 binop (Iop_CmpLT64S, 16139 getIReg (rs), 16140 getIReg (rt))), 16141 Ijk_SigFPE_IntDiv, 16142 IRConst_U64(guest_PC_curr_instr + 4), 16143 OFFB_PC)); 16144 else if (trap_code == 6) 16145 stmt (IRStmt_Exit (unop (Iop_Not1, 16146 binop (Iop_CmpLT64S, 16147 getIReg (rs), 16148 getIReg (rt))), 16149 Ijk_SigFPE_IntOvf, 16150 IRConst_U64(guest_PC_curr_instr + 4), 16151 OFFB_PC)); 16152 else 16153 stmt (IRStmt_Exit (unop (Iop_Not1, 16154 binop (Iop_CmpLT64S, 16155 getIReg (rs), 16156 getIReg (rt))), 16157 Ijk_SigTRAP, 16158 IRConst_U64(guest_PC_curr_instr + 4), 16159 OFFB_PC)); 16160 } else { 16161 if (trap_code == 7) 16162 stmt (IRStmt_Exit (unop (Iop_Not1, 16163 binop (Iop_CmpLT32S, 16164 getIReg (rs), 16165 getIReg (rt))), 16166 Ijk_SigFPE_IntDiv, 16167 IRConst_U32(guest_PC_curr_instr + 4), 16168 OFFB_PC)); 16169 else if (trap_code == 6) 16170 stmt (IRStmt_Exit (unop (Iop_Not1, 16171 binop (Iop_CmpLT32S, 16172 getIReg (rs), 16173 getIReg (rt))), 16174 Ijk_SigFPE_IntOvf, 16175 IRConst_U32(guest_PC_curr_instr + 4), 16176 OFFB_PC)); 16177 else 16178 stmt (IRStmt_Exit (unop (Iop_Not1, 16179 binop (Iop_CmpLT32S, 16180 getIReg (rs), 16181 getIReg (rt))), 16182 Ijk_SigTRAP, 16183 IRConst_U32(guest_PC_curr_instr + 4), 16184 OFFB_PC)); 16185 } 16186 break; 16187 } 16188 case 0x31: { /* TGEU */ 16189 DIP("tgeu r%d, r%d %d", rs, rt, trap_code); 16190 if (mode64) { 16191 if (trap_code == 7) 16192 stmt (IRStmt_Exit (unop (Iop_Not1, 16193 binop (Iop_CmpLT64U, 16194 getIReg (rs), 16195 getIReg (rt))), 16196 Ijk_SigFPE_IntDiv, 16197 IRConst_U64(guest_PC_curr_instr + 4), 16198 OFFB_PC)); 16199 else if (trap_code == 6) 16200 stmt (IRStmt_Exit (unop (Iop_Not1, 16201 binop (Iop_CmpLT64U, 16202 getIReg (rs), 16203 getIReg (rt))), 16204 Ijk_SigFPE_IntOvf, 16205 IRConst_U64(guest_PC_curr_instr + 4), 16206 OFFB_PC)); 16207 else 16208 stmt (IRStmt_Exit (unop (Iop_Not1, 16209 binop (Iop_CmpLT64U, 16210 getIReg (rs), 16211 getIReg (rt))), 16212 Ijk_SigTRAP, 16213 IRConst_U64(guest_PC_curr_instr + 4), 16214 OFFB_PC)); 16215 } else { 16216 if (trap_code == 7) 16217 stmt (IRStmt_Exit (unop (Iop_Not1, 16218 binop (Iop_CmpLT32U, 16219 getIReg (rs), 16220 getIReg (rt))), 16221 Ijk_SigFPE_IntDiv, 16222 IRConst_U32(guest_PC_curr_instr + 4), 16223 OFFB_PC)); 16224 else if (trap_code == 6) 16225 stmt (IRStmt_Exit (unop (Iop_Not1, 16226 binop (Iop_CmpLT32U, 16227 getIReg (rs), 16228 getIReg (rt))), 16229 Ijk_SigFPE_IntOvf, 16230 IRConst_U32(guest_PC_curr_instr + 4), 16231 OFFB_PC)); 16232 else 16233 stmt (IRStmt_Exit (unop (Iop_Not1, 16234 binop (Iop_CmpLT32U, 16235 getIReg (rs), 16236 getIReg (rt))), 16237 Ijk_SigTRAP, 16238 IRConst_U32(guest_PC_curr_instr + 4), 16239 OFFB_PC)); 16240 } 16241 break; 16242 } 16243 case 0x32: { /* TLT */ 16244 DIP("tlt r%d, r%d %d", rs, rt, trap_code); 16245 if (mode64) { 16246 if (trap_code == 7) 16247 stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs), 16248 getIReg(rt)), Ijk_SigFPE_IntDiv, 16249 IRConst_U64(guest_PC_curr_instr + 4), 16250 OFFB_PC)); 16251 else if (trap_code == 6) 16252 stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs), 16253 getIReg(rt)), Ijk_SigFPE_IntOvf, 16254 IRConst_U64(guest_PC_curr_instr + 4), 16255 OFFB_PC)); 16256 else 16257 stmt(IRStmt_Exit(binop(Iop_CmpLT64S, getIReg(rs), 16258 getIReg(rt)), Ijk_SigTRAP, 16259 IRConst_U64(guest_PC_curr_instr + 4), 16260 OFFB_PC)); 16261 } else { 16262 if (trap_code == 7) 16263 stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs), 16264 getIReg(rt)), Ijk_SigFPE_IntDiv, 16265 IRConst_U32(guest_PC_curr_instr + 4), 16266 OFFB_PC)); 16267 else if (trap_code == 6) 16268 stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs), 16269 getIReg(rt)), Ijk_SigFPE_IntOvf, 16270 IRConst_U32(guest_PC_curr_instr + 4), 16271 OFFB_PC)); 16272 else 16273 stmt(IRStmt_Exit(binop(Iop_CmpLT32S, getIReg(rs), 16274 getIReg(rt)), Ijk_SigTRAP, 16275 IRConst_U32(guest_PC_curr_instr + 4), 16276 OFFB_PC)); 16277 } 16278 break; 16279 } 16280 case 0x33: { /* TLTU */ 16281 DIP("tltu r%d, r%d %d", rs, rt, trap_code); 16282 if (mode64) { 16283 if (trap_code == 7) 16284 stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs), 16285 getIReg(rt)), Ijk_SigFPE_IntDiv, 16286 IRConst_U64(guest_PC_curr_instr + 4), 16287 OFFB_PC)); 16288 else if (trap_code == 6) 16289 stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs), 16290 getIReg(rt)), Ijk_SigFPE_IntOvf, 16291 IRConst_U64(guest_PC_curr_instr + 4), 16292 OFFB_PC)); 16293 else 16294 stmt(IRStmt_Exit(binop(Iop_CmpLT64U, getIReg(rs), 16295 getIReg(rt)), Ijk_SigTRAP, 16296 IRConst_U64(guest_PC_curr_instr + 4), 16297 OFFB_PC)); 16298 } else { 16299 if (trap_code == 7) 16300 stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs), 16301 getIReg(rt)), Ijk_SigFPE_IntDiv, 16302 IRConst_U32(guest_PC_curr_instr + 4), 16303 OFFB_PC)); 16304 else if (trap_code == 6) 16305 stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs), 16306 getIReg(rt)), Ijk_SigFPE_IntOvf, 16307 IRConst_U32(guest_PC_curr_instr + 4), 16308 OFFB_PC)); 16309 else 16310 stmt(IRStmt_Exit(binop(Iop_CmpLT32U, getIReg(rs), 16311 getIReg (rt)), Ijk_SigTRAP, 16312 IRConst_U32(guest_PC_curr_instr + 4), 16313 OFFB_PC)); 16314 } 16315 break; 16316 } 16317 case 0x34: { /* TEQ */ 16318 DIP("teq r%d, r%d, %d", rs, rt, trap_code); 16319 if (mode64) { 16320 if (trap_code == 7) 16321 stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs), 16322 getIReg(rt)), Ijk_SigFPE_IntDiv, 16323 IRConst_U64(guest_PC_curr_instr + 4), 16324 OFFB_PC)); 16325 else if (trap_code == 6) 16326 stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs), 16327 getIReg(rt)), Ijk_SigFPE_IntOvf, 16328 IRConst_U64(guest_PC_curr_instr + 4), 16329 OFFB_PC)); 16330 else 16331 stmt(IRStmt_Exit(binop(Iop_CmpEQ64, getIReg(rs), 16332 getIReg(rt)), Ijk_SigTRAP, 16333 IRConst_U64(guest_PC_curr_instr + 4), 16334 OFFB_PC)); 16335 } else { 16336 if (trap_code == 7) 16337 stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs), 16338 getIReg(rt)), Ijk_SigFPE_IntDiv, 16339 IRConst_U32(guest_PC_curr_instr + 4), 16340 OFFB_PC)); 16341 else if (trap_code == 6) 16342 stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs), 16343 getIReg(rt)), Ijk_SigFPE_IntOvf, 16344 IRConst_U32(guest_PC_curr_instr + 4), 16345 OFFB_PC)); 16346 else 16347 stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs), 16348 getIReg(rt)), Ijk_SigTRAP, 16349 IRConst_U32(guest_PC_curr_instr + 4), 16350 OFFB_PC)); 16351 } 16352 break; 16353 } 16354 case 0x36: { /* TNE */ 16355 DIP("tne r%d, r%d %d", rs, rt, trap_code); 16356 if (mode64) { 16357 if (trap_code == 7) 16358 stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs), 16359 getIReg(rt)), Ijk_SigFPE_IntDiv, 16360 IRConst_U64(guest_PC_curr_instr + 4), 16361 OFFB_PC)); 16362 else if (trap_code == 6) 16363 stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs), 16364 getIReg(rt)), Ijk_SigFPE_IntOvf, 16365 IRConst_U64(guest_PC_curr_instr + 4), 16366 OFFB_PC)); 16367 else 16368 stmt(IRStmt_Exit(binop(Iop_CmpNE64, getIReg(rs), 16369 getIReg(rt)), Ijk_SigTRAP, 16370 IRConst_U64(guest_PC_curr_instr + 4), 16371 OFFB_PC)); 16372 } else { 16373 if (trap_code == 7) 16374 stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs), 16375 getIReg(rt)), Ijk_SigFPE_IntDiv, 16376 IRConst_U32(guest_PC_curr_instr + 4), 16377 OFFB_PC)); 16378 else if (trap_code == 6) 16379 stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs), 16380 getIReg(rt)), Ijk_SigFPE_IntOvf, 16381 IRConst_U32(guest_PC_curr_instr + 4), 16382 OFFB_PC)); 16383 else 16384 stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs), 16385 getIReg(rt)), Ijk_SigTRAP, 16386 IRConst_U32(guest_PC_curr_instr + 4), 16387 OFFB_PC)); 16388 } 16389 break; 16390 } 16391 case 0x14: 16392 case 0x16: 16393 case 0x17: /* DSLLV, DROTRV:DSRLV, DSRAV */ 16394 case 0x38: 16395 case 0x3A: 16396 case 0x3B: /* DSLL, DROTL:DSRL, DSRA */ 16397 case 0x3C: 16398 case 0x3E: 16399 case 0x3F: /* DSLL32, DROTR32:DSRL32, DSRA32 */ 16400 if (dis_instr_shrt(cins)) 16401 break; 16402 goto decode_failure; 16403 16404 case 0x0F: /* SYNC */ 16405 DIP("sync 0x%x", sel); 16406 /* Just ignore it. */ 16407 break; 16408 16409 case 0x2C: { /* Doubleword Add - DADD; MIPS64 */ 16410 DIP("dadd r%d, r%d, r%d", rd, rs, rt); 16411 IRTemp tmpRs64 = newTemp(Ity_I64); 16412 IRTemp tmpRt64 = newTemp(Ity_I64); 16413 16414 assign(tmpRs64, getIReg(rs)); 16415 assign(tmpRt64, getIReg(rt)); 16416 16417 t0 = newTemp(Ity_I64); 16418 t1 = newTemp(Ity_I64); 16419 t2 = newTemp(Ity_I64); 16420 t3 = newTemp(Ity_I64); 16421 t4 = newTemp(Ity_I64); 16422 /* dst = src0 + src1 16423 if(sign(src0 ) != sign(src1 )) 16424 goto no overflow; 16425 if(sign(dst) == sign(src0 )) 16426 goto no overflow; 16427 we have overflow! */ 16428 16429 assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(tmpRt64))); 16430 assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(tmpRt64))); 16431 assign(t2, unop(Iop_1Uto64, 16432 binop(Iop_CmpEQ64, 16433 binop(Iop_And64, mkexpr(t1), 16434 mkU64(0x8000000000000000ULL)), 16435 mkU64(0x8000000000000000ULL)))); 16436 16437 assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64))); 16438 assign(t4, unop(Iop_1Uto64, 16439 binop(Iop_CmpNE64, 16440 binop(Iop_And64, mkexpr(t3), 16441 mkU64(0x8000000000000000ULL)), 16442 mkU64(0x8000000000000000ULL)))); 16443 16444 stmt(IRStmt_Exit(binop(Iop_CmpEQ64, 16445 binop(Iop_Or64, mkexpr(t2), mkexpr(t4)), 16446 mkU64(0)), 16447 Ijk_SigFPE_IntOvf, 16448 IRConst_U64(guest_PC_curr_instr + 4), 16449 OFFB_PC)); 16450 16451 putIReg(rd, mkexpr(t0)); 16452 break; 16453 } 16454 16455 case 0x2D: /* Doubleword Add Unsigned - DADDU; MIPS64 */ 16456 DIP("daddu r%d, r%d, r%d", rd, rs, rt); 16457 ALU_PATTERN(Iop_Add64); 16458 break; 16459 16460 case 0x2E: { /* Doubleword Subtract - DSUB; MIPS64 */ 16461 DIP("dsub r%u, r%u, r%u", rd, rs, rt); 16462 IRTemp tmpRs64 = newTemp(Ity_I64); 16463 IRTemp tmpRt64 = newTemp(Ity_I64); 16464 16465 assign(tmpRs64, getIReg(rs)); 16466 assign(tmpRt64, getIReg(rt)); 16467 t0 = newTemp(Ity_I64); 16468 t1 = newTemp(Ity_I64); 16469 t2 = newTemp(Ity_I64); 16470 t3 = newTemp(Ity_I64); 16471 t4 = newTemp(Ity_I64); 16472 t5 = newTemp(Ity_I64); 16473 /* dst = src0 + (-1 * src1) 16474 if(sign(src0 ) != sign((-1 * src1) )) 16475 goto no overflow; 16476 if(sign(dst) == sign(src0 )) 16477 goto no overflow; 16478 we have overflow! */ 16479 16480 assign(t5, binop(Iop_Mul64, 16481 mkexpr(tmpRt64), 16482 mkU64(0xffffffffffffffffULL))); 16483 assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), mkexpr(t5))); 16484 assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), mkexpr(t5))); 16485 assign(t2, unop(Iop_1Sto64, 16486 binop(Iop_CmpEQ64, 16487 binop(Iop_And64, 16488 mkexpr(t1), 16489 mkU64(0x8000000000000000ULL)), 16490 mkU64(0x8000000000000000ULL)))); 16491 16492 assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64))); 16493 assign(t4, unop(Iop_1Sto64, 16494 binop(Iop_CmpNE64, 16495 binop(Iop_And64, 16496 mkexpr(t3), 16497 mkU64(0x8000000000000000ULL)), 16498 mkU64(0x8000000000000000ULL)))); 16499 16500 stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2), 16501 mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf, 16502 IRConst_U64(guest_PC_curr_instr + 4), 16503 OFFB_PC)); 16504 16505 putIReg(rd, binop(Iop_Sub64, getIReg(rs), getIReg(rt))); 16506 break; 16507 } 16508 16509 case 0x2F: /* Doubleword Subtract Unsigned - DSUBU; MIPS64 */ 16510 DIP("dsub r%u, r%u,r%u", rd, rt, rt); 16511 ALU_PATTERN(Iop_Sub64); 16512 break; 16513 16514 default: 16515 goto decode_failure; 16516 } 16517 break; 16518 16519 case 0x01: /* Regimm */ 16520 16521 switch (rt) { 16522 case 0x00: /* BLTZ */ 16523 DIP("bltz r%d, %d", rs, imm); 16524 if (mode64) { 16525 if (!dis_instr_branch(cins, &dres, resteerOkFn, 16526 callback_opaque, &bstmt)) 16527 goto decode_failure; 16528 } else 16529 dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs), 16530 mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt); 16531 break; 16532 16533 case 0x01: /* BGEZ */ 16534 DIP("bgez r%d, %d", rs, imm); 16535 if (mode64) { 16536 if (!dis_instr_branch(cins, &dres, resteerOkFn, 16537 callback_opaque, &bstmt)) 16538 goto decode_failure; 16539 } else 16540 dis_branch(False, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs), 16541 mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt); 16542 break; 16543 16544 case 0x02: /* BLTZL */ 16545 DIP("bltzl r%d, %d", rs, imm); 16546 lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32, 16547 binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs), 16548 mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)), 16549 mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)), 16550 imm); 16551 break; 16552 16553 case 0x03: /* BGEZL */ 16554 DIP("bgezl r%d, %d", rs, imm); 16555 lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32, 16556 binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs), 16557 mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)), 16558 mode64 ? mkU64(0x0) : mkU32(0x0)), imm); 16559 break; 16560 16561 case 0x10: /* BLTZAL */ 16562 DIP("bltzal r%d, %d", rs, imm); 16563 if (mode64) { 16564 if (!dis_instr_branch(cins, &dres, resteerOkFn, 16565 callback_opaque, &bstmt)) 16566 goto decode_failure; 16567 } else 16568 dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs), 16569 mkU32(0x80000000)), mkU32(0x80000000)), imm, &bstmt); 16570 break; 16571 16572 case 0x12: /* BLTZALL */ 16573 DIP("bltzall r%d, %d", rs, imm); 16574 putIReg(31, mode64 ? mkU64(guest_PC_curr_instr + 8) : 16575 mkU32(guest_PC_curr_instr + 8)); 16576 lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32, 16577 binop(mode64 ? Iop_And64 : Iop_And32, getIReg(rs), 16578 mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)), 16579 mode64 ? mkU64(0x8000000000000000ULL) : mkU32(0x80000000)), 16580 imm); 16581 break; 16582 16583 case 0x11: /* BGEZAL */ 16584 DIP("bgezal r%d, %d", rs, imm); 16585 if (mode64) { 16586 if (!dis_instr_branch(cins, &dres, resteerOkFn, 16587 callback_opaque, &bstmt)) 16588 goto decode_failure; 16589 } else 16590 dis_branch(True, binop(Iop_CmpEQ32, binop(Iop_And32, getIReg(rs), 16591 mkU32(0x80000000)), mkU32(0x0)), imm, &bstmt); 16592 break; 16593 16594 case 0x13: /* BGEZALL */ 16595 DIP("bgezall r%d, %d", rs, imm); 16596 if (mode64) { 16597 putIReg(31, mkU64(guest_PC_curr_instr + 8)); 16598 lastn = dis_branch_likely(binop(Iop_CmpNE64, 16599 binop(Iop_And64, 16600 getIReg(rs), 16601 mkU64(0x8000000000000000ULL)), 16602 mkU64(0x0)), 16603 imm); 16604 } else { 16605 putIReg(31, mkU32(guest_PC_curr_instr + 8)); 16606 lastn = dis_branch_likely(binop(Iop_CmpNE32, binop(Iop_And32, 16607 getIReg(rs), mkU32(0x80000000)), 16608 mkU32(0x0)), imm); 16609 } 16610 break; 16611 16612 case 0x08: /* TGEI */ 16613 DIP("tgei r%d, %d %d", rs, imm, trap_code); 16614 if (mode64) { 16615 stmt (IRStmt_Exit (unop (Iop_Not1, 16616 binop (Iop_CmpLT64S, 16617 getIReg (rs), 16618 mkU64 (extend_s_16to64 (imm)))), 16619 Ijk_SigTRAP, 16620 IRConst_U64(guest_PC_curr_instr + 4), 16621 OFFB_PC)); 16622 } else { 16623 stmt (IRStmt_Exit (unop (Iop_Not1, 16624 binop (Iop_CmpLT32S, 16625 getIReg (rs), 16626 mkU32 (extend_s_16to32 (imm)))), 16627 Ijk_SigTRAP, 16628 IRConst_U32(guest_PC_curr_instr + 4), 16629 OFFB_PC)); 16630 } 16631 break; 16632 16633 case 0x09: { /* TGEIU */ 16634 DIP("tgeiu r%d, %d %d", rs, imm, trap_code); 16635 if (mode64) { 16636 stmt (IRStmt_Exit (unop (Iop_Not1, 16637 binop (Iop_CmpLT64U, 16638 getIReg (rs), 16639 mkU64 (extend_s_16to64 (imm)))), 16640 Ijk_SigTRAP, 16641 IRConst_U64(guest_PC_curr_instr + 4), 16642 OFFB_PC)); 16643 } else { 16644 stmt (IRStmt_Exit (unop (Iop_Not1, 16645 binop (Iop_CmpLT32U, 16646 getIReg (rs), 16647 mkU32 (extend_s_16to32 (imm)))), 16648 Ijk_SigTRAP, 16649 IRConst_U32(guest_PC_curr_instr + 4), 16650 OFFB_PC)); 16651 } 16652 break; 16653 } 16654 case 0x0A: { /* TLTI */ 16655 DIP("tlti r%d, %d %d", rs, imm, trap_code); 16656 if (mode64) { 16657 stmt (IRStmt_Exit (binop (Iop_CmpLT64S, getIReg (rs), 16658 mkU64 (extend_s_16to64 (imm))), 16659 Ijk_SigTRAP, 16660 IRConst_U64(guest_PC_curr_instr + 4), 16661 OFFB_PC)); 16662 } else { 16663 stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rs), 16664 mkU32 (extend_s_16to32 (imm))), 16665 Ijk_SigTRAP, 16666 IRConst_U32(guest_PC_curr_instr + 4), 16667 OFFB_PC)); 16668 } 16669 break; 16670 } 16671 case 0x0B: { /* TLTIU */ 16672 DIP("tltiu r%d, %d %d", rs, imm, trap_code); 16673 if (mode64) { 16674 stmt (IRStmt_Exit (binop (Iop_CmpLT64U, getIReg (rs), 16675 mkU64 (extend_s_16to64 (imm))), 16676 Ijk_SigTRAP, 16677 IRConst_U64(guest_PC_curr_instr + 4), 16678 OFFB_PC)); 16679 } else { 16680 stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rs), 16681 mkU32 (extend_s_16to32 (imm))), 16682 Ijk_SigTRAP, 16683 IRConst_U32(guest_PC_curr_instr + 4), 16684 OFFB_PC)); 16685 } 16686 break; 16687 } 16688 case 0x0C: { /* TEQI */ 16689 DIP("teqi r%d, %d %d", rs, imm, trap_code); 16690 if (mode64) { 16691 stmt (IRStmt_Exit (binop (Iop_CmpEQ64, getIReg (rs), 16692 mkU64 (extend_s_16to64 (imm))), 16693 Ijk_SigTRAP, 16694 IRConst_U64(guest_PC_curr_instr + 4), 16695 OFFB_PC)); 16696 } else { 16697 stmt (IRStmt_Exit (binop (Iop_CmpEQ32, getIReg (rs), 16698 mkU32 (extend_s_16to32 (imm))), 16699 Ijk_SigTRAP, 16700 IRConst_U32(guest_PC_curr_instr + 4), 16701 OFFB_PC)); 16702 } 16703 break; 16704 } 16705 case 0x0E: { /* TNEI */ 16706 DIP("tnei r%d, %d %d", rs, imm, trap_code); 16707 if (mode64) { 16708 stmt (IRStmt_Exit (binop (Iop_CmpNE64, getIReg (rs), 16709 mkU64 (extend_s_16to64 (imm))), 16710 Ijk_SigTRAP, 16711 IRConst_U64(guest_PC_curr_instr + 4), 16712 OFFB_PC)); 16713 } else { 16714 stmt (IRStmt_Exit (binop (Iop_CmpNE32, getIReg (rs), 16715 mkU32 (extend_s_16to32 (imm))), 16716 Ijk_SigTRAP, 16717 IRConst_U32(guest_PC_curr_instr + 4), 16718 OFFB_PC)); 16719 } 16720 break; 16721 } 16722 case 0x1C: { /* BPOSGE32 */ 16723 DIP("bposge32 %d", imm); 16724 vassert(!mode64); 16725 t0 = newTemp(Ity_I32); 16726 /* Get pos field from DSPControl register. */ 16727 assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f))); 16728 dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLT32U, mkexpr(t0), 16729 mkU32(32))), imm, &bstmt); 16730 } 16731 case 0x1F: 16732 /* SYNCI */ 16733 /* Just ignore it */ 16734 break; 16735 16736 default: 16737 goto decode_failure; 16738 } 16739 break; 16740 16741 case 0x04: 16742 DIP("beq r%d, r%d, %d", rs, rt, imm); 16743 if (mode64) 16744 dis_branch(False, binop(Iop_CmpEQ64, getIReg(rs), getIReg(rt)), 16745 imm, &bstmt); 16746 else 16747 dis_branch(False, binop(Iop_CmpEQ32, getIReg(rs), getIReg(rt)), 16748 imm, &bstmt); 16749 break; 16750 16751 case 0x14: 16752 DIP("beql r%d, r%d, %d", rs, rt, imm); 16753 lastn = dis_branch_likely(binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32, 16754 getIReg(rs), getIReg(rt)), imm); 16755 break; 16756 16757 case 0x05: 16758 DIP("bne r%d, r%d, %d", rs, rt, imm); 16759 if (mode64) 16760 dis_branch(False, binop(Iop_CmpNE64, getIReg(rs), getIReg(rt)), 16761 imm, &bstmt); 16762 else 16763 dis_branch(False, binop(Iop_CmpNE32, getIReg(rs), getIReg(rt)), 16764 imm, &bstmt); 16765 break; 16766 16767 case 0x15: 16768 DIP("bnel r%d, r%d, %d", rs, rt, imm); 16769 lastn = dis_branch_likely(binop(mode64 ? Iop_CmpEQ64 : Iop_CmpEQ32, 16770 getIReg(rs), getIReg(rt)), imm); 16771 break; 16772 16773 case 0x07: /* BGTZ */ 16774 DIP("bgtz r%d, %d", rs, imm); 16775 if (mode64) 16776 dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE64S, getIReg(rs), 16777 mkU64(0x00))), imm, &bstmt); 16778 else 16779 dis_branch(False, unop(Iop_Not1, binop(Iop_CmpLE32S, getIReg(rs), 16780 mkU32(0x00))), imm, &bstmt); 16781 break; 16782 16783 case 0x17: /* BGTZL */ 16784 DIP("bgtzl r%d, %d", rs, imm); 16785 if (mode64) 16786 lastn = dis_branch_likely(binop(Iop_CmpLE64S, getIReg(rs), 16787 mkU64(0x00)), imm); 16788 else 16789 lastn = dis_branch_likely(binop(Iop_CmpLE32S, getIReg(rs), 16790 mkU32(0x00)), imm); 16791 break; 16792 16793 case 0x06: /* BLEZ */ 16794 DIP("blez r%d, %d", rs, imm); 16795 if (mode64) 16796 dis_branch(False, binop(Iop_CmpLE64S, getIReg(rs), mkU64(0x0)), 16797 imm, &bstmt); 16798 else 16799 dis_branch(False,binop(Iop_CmpLE32S, getIReg(rs), mkU32(0x0)), imm, 16800 &bstmt); 16801 break; 16802 16803 case 0x16: /* BLEZL */ 16804 DIP("blezl r%d, %d", rs, imm); 16805 lastn = dis_branch_likely(unop(Iop_Not1, (binop(mode64 ? Iop_CmpLE64S : 16806 Iop_CmpLE32S, getIReg(rs), mode64 ? 16807 mkU64(0x0) : mkU32(0x0)))), imm); 16808 break; 16809 16810 case 0x08: { /* ADDI */ 16811 DIP("addi r%d, r%d, %d", rt, rs, imm); 16812 IRTemp tmpRs32 = newTemp(Ity_I32); 16813 assign(tmpRs32, mkNarrowTo32(ty, getIReg(rs))); 16814 16815 t0 = newTemp(Ity_I32); 16816 t1 = newTemp(Ity_I32); 16817 t2 = newTemp(Ity_I32); 16818 t3 = newTemp(Ity_I32); 16819 t4 = newTemp(Ity_I32); 16820 /* dst = src0 + sign(imm) 16821 if(sign(src0 ) != sign(imm )) 16822 goto no overflow; 16823 if(sign(dst) == sign(src0 )) 16824 goto no overflow; 16825 we have overflow! */ 16826 16827 assign(t0, binop(Iop_Add32, mkexpr(tmpRs32), 16828 mkU32(extend_s_16to32(imm)))); 16829 assign(t1, binop(Iop_Xor32, mkexpr(tmpRs32), 16830 mkU32(extend_s_16to32(imm)))); 16831 assign(t2, unop(Iop_1Sto32, binop(Iop_CmpEQ32, binop(Iop_And32, 16832 mkexpr(t1), mkU32(0x80000000)), mkU32(0x80000000)))); 16833 16834 assign(t3, binop(Iop_Xor32, mkexpr(t0), mkexpr(tmpRs32))); 16835 assign(t4, unop(Iop_1Sto32, binop(Iop_CmpNE32, binop(Iop_And32, 16836 mkexpr(t3), mkU32(0x80000000)), mkU32(0x80000000)))); 16837 16838 stmt(IRStmt_Exit(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(t2), 16839 mkexpr(t4)), mkU32(0)), Ijk_SigFPE_IntOvf, 16840 mode64 ? IRConst_U64(guest_PC_curr_instr + 4) : 16841 IRConst_U32(guest_PC_curr_instr + 4), 16842 OFFB_PC)); 16843 16844 putIReg(rt, mkWidenFrom32(ty, mkexpr(t0), True)); 16845 break; 16846 } 16847 case 0x09: /* ADDIU */ 16848 DIP("addiu r%d, r%d, %d", rt, rs, imm); 16849 if (mode64) { 16850 putIReg(rt, mkWidenFrom32(ty, binop(Iop_Add32, 16851 mkNarrowTo32(ty, getIReg(rs)),mkU32(extend_s_16to32(imm))), 16852 True)); 16853 } else 16854 putIReg(rt, binop(Iop_Add32, getIReg(rs),mkU32(extend_s_16to32(imm)))); 16855 break; 16856 16857 case 0x0C: /* ANDI */ 16858 DIP("andi r%d, r%d, %d", rt, rs, imm); 16859 if (mode64) { 16860 ALUI_PATTERN64(Iop_And64); 16861 } else { 16862 ALUI_PATTERN(Iop_And32); 16863 } 16864 break; 16865 16866 case 0x0E: /* XORI */ 16867 DIP("xori r%d, r%d, %d", rt, rs, imm); 16868 if (mode64) { 16869 ALUI_PATTERN64(Iop_Xor64); 16870 } else { 16871 ALUI_PATTERN(Iop_Xor32); 16872 } 16873 break; 16874 16875 case 0x0D: /* ORI */ 16876 DIP("ori r%d, r%d, %d", rt, rs, imm); 16877 if (mode64) { 16878 ALUI_PATTERN64(Iop_Or64); 16879 } else { 16880 ALUI_PATTERN(Iop_Or32); 16881 } 16882 break; 16883 16884 case 0x0A: /* SLTI */ 16885 DIP("slti r%d, r%d, %d", rt, rs, imm); 16886 if (mode64) 16887 putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64S, getIReg(rs), 16888 mkU64(extend_s_16to64(imm))))); 16889 else 16890 putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs), 16891 mkU32(extend_s_16to32(imm))))); 16892 break; 16893 16894 case 0x0B: /* SLTIU */ 16895 DIP("sltiu r%d, r%d, %d", rt, rs, imm); 16896 if (mode64) 16897 putIReg(rt, unop(Iop_1Uto64, binop(Iop_CmpLT64U, getIReg(rs), 16898 mkU64(extend_s_16to64(imm))))); 16899 else 16900 putIReg(rt, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs), 16901 mkU32(extend_s_16to32(imm))))); 16902 break; 16903 16904 case 0x18: { /* Doubleword Add Immidiate - DADD; MIPS64 */ 16905 DIP("daddi r%d, r%d, %d", rt, rs, imm); 16906 IRTemp tmpRs64 = newTemp(Ity_I64); 16907 assign(tmpRs64, getIReg(rs)); 16908 16909 t0 = newTemp(Ity_I64); 16910 t1 = newTemp(Ity_I64); 16911 t2 = newTemp(Ity_I64); 16912 t3 = newTemp(Ity_I64); 16913 t4 = newTemp(Ity_I64); 16914 /* dst = src0 + sign(imm) 16915 if(sign(src0 ) != sign(imm )) 16916 goto no overflow; 16917 if(sign(dst) == sign(src0 )) 16918 goto no overflow; 16919 we have overflow! */ 16920 16921 assign(t0, binop(Iop_Add64, mkexpr(tmpRs64), 16922 mkU64(extend_s_16to64(imm)))); 16923 assign(t1, binop(Iop_Xor64, mkexpr(tmpRs64), 16924 mkU64(extend_s_16to64(imm)))); 16925 assign(t2, unop(Iop_1Sto64, binop(Iop_CmpEQ64, binop(Iop_And64, 16926 mkexpr(t1), mkU64(0x8000000000000000ULL)), 16927 mkU64(0x8000000000000000ULL)))); 16928 16929 assign(t3, binop(Iop_Xor64, mkexpr(t0), mkexpr(tmpRs64))); 16930 assign(t4, unop(Iop_1Sto64, binop(Iop_CmpNE64, binop(Iop_And64, 16931 mkexpr(t3), mkU64(0x8000000000000000ULL)), 16932 mkU64(0x8000000000000000ULL)))); 16933 16934 stmt(IRStmt_Exit(binop(Iop_CmpEQ64, binop(Iop_Or64, mkexpr(t2), 16935 mkexpr(t4)), mkU64(0)), Ijk_SigFPE_IntOvf, 16936 IRConst_U64(guest_PC_curr_instr + 4), 16937 OFFB_PC)); 16938 16939 putIReg(rt, mkexpr(t0)); 16940 break; 16941 } 16942 16943 case 0x19: /* Doubleword Add Immidiate Unsigned - DADDIU; MIPS64 */ 16944 DIP("daddiu r%d, r%d, %d", rt, rs, imm); 16945 putIReg(rt, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 16946 break; 16947 16948 case 0x1A: { 16949 /* Load Doubleword Left - LDL; MIPS64 */ 16950 vassert(mode64); 16951 DIP("ldl r%u, %d(r%u)", rt, imm, rs); 16952 /* t1 = addr */ 16953 #if defined (_MIPSEL) 16954 t1 = newTemp(Ity_I64); 16955 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 16956 #elif defined (_MIPSEB) 16957 t1 = newTemp(Ity_I64); 16958 assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs), 16959 mkU64(extend_s_16to64(imm))))); 16960 #endif 16961 /* t2 = word addr */ 16962 /* t4 = addr mod 8 */ 16963 LWX_SWX_PATTERN64_1; 16964 16965 /* t3 = word content - shifted */ 16966 t3 = newTemp(Ity_I64); 16967 assign(t3, binop(Iop_Shl64, load(Ity_I64, mkexpr(t2)), 16968 narrowTo(Ity_I8, binop(Iop_Shl64, binop(Iop_Sub64, mkU64(0x07), 16969 mkexpr(t4)), mkU8(3))))); 16970 16971 /* rt content - adjusted */ 16972 t5 = newTemp(Ity_I64); 16973 t6 = newTemp(Ity_I64); 16974 t7 = newTemp(Ity_I64); 16975 16976 assign(t5, binop(Iop_Mul64, mkexpr(t4), mkU64(0x8))); 16977 16978 assign(t6, binop(Iop_Shr64, mkU64(0x00FFFFFFFFFFFFFFULL), 16979 narrowTo(Ity_I8, mkexpr(t5)))); 16980 16981 assign(t7, binop(Iop_And64, getIReg(rt), mkexpr(t6))); 16982 16983 putIReg(rt, binop(Iop_Or64, mkexpr(t7), mkexpr(t3))); 16984 break; 16985 } 16986 16987 case 0x1B: { 16988 /* Load Doubleword Right - LDR; MIPS64 */ 16989 vassert(mode64); 16990 DIP("ldr r%u,%d(r%u)", rt, imm, rs); 16991 /* t1 = addr */ 16992 #if defined (_MIPSEL) 16993 t1 = newTemp(Ity_I64); 16994 assign(t1, binop(Iop_Add64, getIReg(rs), mkU64(extend_s_16to64(imm)))); 16995 #elif defined (_MIPSEB) 16996 t1 = newTemp(Ity_I64); 16997 assign(t1, binop(Iop_Xor64, mkU64(0x7), binop(Iop_Add64, getIReg(rs), 16998 mkU64(extend_s_16to64(imm))))); 16999 #endif 17000 /* t2 = word addr */ 17001 /* t4 = addr mod 8 */ 17002 LWX_SWX_PATTERN64_1; 17003 17004 /* t3 = word content - shifted */ 17005 t3 = newTemp(Ity_I64); 17006 assign(t3, binop(Iop_Shr64, load(Ity_I64, mkexpr(t2)), 17007 narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(3))))); 17008 17009 /* rt content - adjusted */ 17010 t5 = newTemp(Ity_I64); 17011 assign(t5, binop(Iop_And64, getIReg(rt), unop(Iop_Not64, 17012 binop(Iop_Shr64, mkU64(0xFFFFFFFFFFFFFFFFULL), 17013 narrowTo(Ity_I8, binop(Iop_Shl64, mkexpr(t4), mkU8(0x3))))))); 17014 17015 putIReg(rt, binop(Iop_Or64, mkexpr(t5), mkexpr(t3))); 17016 break; 17017 } 17018 17019 case 0x27: /* Load Word unsigned - LWU; MIPS64 */ 17020 DIP("lwu r%u,%d(r%u)", rt, imm, rs); 17021 LOAD_STORE_PATTERN; 17022 17023 putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), False)); 17024 break; 17025 17026 case 0x30: /* LL / LWC0 */ 17027 DIP("ll r%d, %d(r%d)", rt, imm, rs); 17028 LOAD_STORE_PATTERN; 17029 17030 t2 = newTemp(Ity_I32); 17031 #if defined (_MIPSEL) 17032 stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ )); 17033 #elif defined (_MIPSEB) 17034 stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ )); 17035 #endif 17036 if (mode64) 17037 putIReg(rt, unop(Iop_32Sto64, mkexpr(t2))); 17038 else 17039 putIReg(rt, mkexpr(t2)); 17040 break; 17041 17042 case 0x34: /* Load Linked Doubleword - LLD; MIPS64 */ 17043 DIP("lld r%d, %d(r%d)", rt, imm, rs); 17044 LOAD_STORE_PATTERN; 17045 17046 t2 = newTemp(Ity_I64); 17047 #if defined (_MIPSEL) 17048 stmt(IRStmt_LLSC 17049 (Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ )); 17050 #elif defined (_MIPSEB) 17051 stmt(IRStmt_LLSC 17052 (Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ )); 17053 #endif 17054 17055 putIReg(rt, mkexpr(t2)); 17056 break; 17057 17058 case 0x38: /* SC / SWC0 */ 17059 DIP("sc r%d, %d(r%d)", rt, imm, rs); 17060 LOAD_STORE_PATTERN; 17061 17062 t2 = newTemp(Ity_I1); 17063 #if defined (_MIPSEL) 17064 stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt)))); 17065 #elif defined (_MIPSEB) 17066 stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt)))); 17067 #endif 17068 17069 putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32, mkexpr(t2))); 17070 break; 17071 17072 case 0x3C: /* Store Conditional Doubleword - SCD; MIPS64 */ 17073 DIP("sdc r%d, %d(r%d)", rt, imm, rs); 17074 LOAD_STORE_PATTERN; 17075 17076 t2 = newTemp(Ity_I1); 17077 #if defined (_MIPSEL) 17078 stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), getIReg(rt))); 17079 #elif defined (_MIPSEB) 17080 stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), getIReg(rt))); 17081 #endif 17082 17083 putIReg(rt, unop(Iop_1Uto64, mkexpr(t2))); 17084 break; 17085 17086 case 0x37: /* Load Doubleword - LD; MIPS64 */ 17087 DIP("ld r%u, %d(r%u)", rt, imm, rs); 17088 LOAD_STORE_PATTERN; 17089 putIReg(rt, load(Ity_I64, mkexpr(t1))); 17090 break; 17091 17092 case 0x3F: /* Store Doubleword - SD; MIPS64 */ 17093 DIP("sd r%u, %d(r%u)", rt, imm, rs); 17094 LOAD_STORE_PATTERN; 17095 store(mkexpr(t1), getIReg(rt)); 17096 break; 17097 17098 case 0x32: /* Branch on Bit Clear - BBIT0; Cavium OCTEON */ 17099 /* Cavium Specific instructions. */ 17100 if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) { 17101 DIP("bbit0 r%d, 0x%x, %x", rs, rt, imm); 17102 t0 = newTemp(Ity_I32); 17103 t1 = newTemp(Ity_I32); 17104 assign(t0, mkU32(0x1)); 17105 assign(t1, binop(Iop_Shl32, mkexpr(t0), mkU8(rt))); 17106 dis_branch(False, binop(Iop_CmpEQ32, 17107 binop(Iop_And32, 17108 mkexpr(t1), 17109 mkNarrowTo32(ty, getIReg(rs))), 17110 mkU32(0x0)), 17111 imm, &bstmt); 17112 break; 17113 } else { 17114 goto decode_failure; 17115 } 17116 17117 case 0x36: /* Branch on Bit Clear Plus 32 - BBIT032; Cavium OCTEON */ 17118 /* Cavium Specific instructions. */ 17119 if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) { 17120 DIP("bbit032 r%d, 0x%x, %x", rs, rt, imm); 17121 t0 = newTemp(Ity_I64); 17122 t1 = newTemp(Ity_I8); /* Shift. */ 17123 t2 = newTemp(Ity_I64); 17124 assign(t0, mkU64(0x1)); 17125 assign(t1, binop(Iop_Add8, mkU8(rt), mkU8(32))); 17126 assign(t2, binop(Iop_Shl64, mkexpr(t0), mkexpr(t1))); 17127 dis_branch(False, binop(Iop_CmpEQ64, 17128 binop(Iop_And64, 17129 mkexpr(t2), 17130 getIReg(rs)), 17131 mkU64(0x0)), 17132 imm, &bstmt); 17133 break; 17134 } else { 17135 goto decode_failure; 17136 } 17137 17138 case 0x3A: /* Branch on Bit Set - BBIT1; Cavium OCTEON */ 17139 /* Cavium Specific instructions. */ 17140 if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) { 17141 DIP("bbit1 r%d, 0x%x, %x", rs, rt, imm); 17142 t0 = newTemp(Ity_I32); 17143 t1 = newTemp(Ity_I32); 17144 assign(t0, mkU32(0x1)); 17145 assign(t1, binop(Iop_Shl32, mkexpr(t0), mkU8(rt))); 17146 dis_branch(False, binop(Iop_CmpNE32, 17147 binop(Iop_And32, 17148 mkexpr(t1), 17149 mkNarrowTo32(ty, getIReg(rs))), 17150 mkU32(0x0)), 17151 imm, &bstmt); 17152 break; 17153 } else { 17154 goto decode_failure; 17155 } 17156 17157 case 0x3E: /* Branch on Bit Set Plus 32 - BBIT132; Cavium OCTEON */ 17158 /* Cavium Specific instructions. */ 17159 if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) { 17160 DIP("bbit132 r%d, 0x%x, %x", rs, rt, imm); 17161 t0 = newTemp(Ity_I64); 17162 t1 = newTemp(Ity_I8); /* Shift. */ 17163 t2 = newTemp(Ity_I64); 17164 assign(t0, mkU64(0x1)); 17165 assign(t1, binop(Iop_Add8, mkU8(rt), mkU8(32))); 17166 assign(t2, binop(Iop_Shl64, mkexpr(t0), mkexpr(t1))); 17167 dis_branch(False, binop(Iop_CmpNE64, 17168 binop(Iop_And64, 17169 mkexpr(t2), 17170 getIReg(rs)), 17171 mkU64(0x0)), 17172 imm, &bstmt); 17173 break; 17174 } else { 17175 goto decode_failure; 17176 } 17177 17178 default: 17179 goto decode_failure; 17180 17181 decode_failure_dsp: 17182 vex_printf("Error occured while trying to decode MIPS32 DSP " 17183 "instruction.\nYour platform probably doesn't support " 17184 "MIPS32 DSP ASE.\n"); 17185 decode_failure: 17186 /* All decode failures end up here. */ 17187 if (sigill_diag) 17188 vex_printf("vex mips->IR: unhandled instruction bytes: " 17189 "0x%x 0x%x 0x%x 0x%x\n", 17190 (Int) getIByte(delta_start + 0), 17191 (Int) getIByte(delta_start + 1), 17192 (Int) getIByte(delta_start + 2), 17193 (Int) getIByte(delta_start + 3)); 17194 17195 /* Tell the dispatcher that this insn cannot be decoded, and so has 17196 not been executed, and (is currently) the next to be executed. 17197 EIP should be up-to-date since it made so at the start bnezof each 17198 insn, but nevertheless be paranoid and update it again right 17199 now. */ 17200 if (mode64) { 17201 stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_PC), 17202 mkU64(guest_PC_curr_instr))); 17203 jmp_lit64(&dres, Ijk_NoDecode, guest_PC_curr_instr); 17204 } else { 17205 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_PC), 17206 mkU32(guest_PC_curr_instr))); 17207 jmp_lit32(&dres, Ijk_NoDecode, guest_PC_curr_instr); 17208 } 17209 dres.whatNext = Dis_StopHere; 17210 dres.len = 0; 17211 return dres; 17212 } /* switch (opc) for the main (primary) opcode switch. */ 17213 17214 /* All MIPS insn have 4 bytes */ 17215 17216 if (delay_slot_branch) { 17217 delay_slot_branch = False; 17218 stmt(bstmt); 17219 bstmt = NULL; 17220 if (mode64) 17221 putPC(mkU64(guest_PC_curr_instr + 4)); 17222 else 17223 putPC(mkU32(guest_PC_curr_instr + 4)); 17224 dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ? 17225 Ijk_Call : Ijk_Boring; 17226 } 17227 17228 if (likely_delay_slot) { 17229 dres.jk_StopHere = Ijk_Boring; 17230 dres.whatNext = Dis_StopHere; 17231 putPC(lastn); 17232 lastn = NULL; 17233 } 17234 if (delay_slot_jump) { 17235 putPC(lastn); 17236 lastn = NULL; 17237 dres.jk_StopHere = is_Branch_or_Jump_and_Link(guest_code + delta - 4) ? 17238 Ijk_Call : Ijk_Boring; 17239 } 17240 17241 decode_success: 17242 /* All decode successes end up here. */ 17243 switch (dres.whatNext) { 17244 case Dis_Continue: 17245 if (mode64) 17246 putPC(mkU64(guest_PC_curr_instr + 4)); 17247 else 17248 putPC(mkU32(guest_PC_curr_instr + 4)); 17249 break; 17250 case Dis_ResteerU: 17251 case Dis_ResteerC: 17252 putPC(mkU32(dres.continueAt)); 17253 break; 17254 case Dis_StopHere: 17255 break; 17256 default: 17257 vassert(0); 17258 break; 17259 } 17260 17261 /* On MIPS we need to check if the last instruction in block is branch or 17262 jump. */ 17263 if (((vex_control.guest_max_insns - 1) == (delta + 4) / 4) 17264 && (dres.whatNext != Dis_StopHere)) 17265 if (branch_or_jump(guest_code + delta + 4)) { 17266 dres.whatNext = Dis_StopHere; 17267 dres.jk_StopHere = Ijk_Boring; 17268 if (mode64) 17269 putPC(mkU64(guest_PC_curr_instr + 4)); 17270 else 17271 putPC(mkU32(guest_PC_curr_instr + 4)); 17272 } 17273 dres.len = 4; 17274 17275 DIP("\n"); 17276 17277 return dres; 17278 17279 } 17280 17281 /*------------------------------------------------------------*/ 17282 /*--- Top-level fn ---*/ 17283 /*------------------------------------------------------------*/ 17284 17285 /* Disassemble a single instruction into IR. The instruction 17286 is located in host memory at &guest_code[delta]. */ 17287 DisResult disInstr_MIPS( IRSB* irsb_IN, 17288 Bool (*resteerOkFn) ( void *, Addr ), 17289 Bool resteerCisOk, 17290 void* callback_opaque, 17291 const UChar* guest_code_IN, 17292 Long delta, 17293 Addr guest_IP, 17294 VexArch guest_arch, 17295 const VexArchInfo* archinfo, 17296 const VexAbiInfo* abiinfo, 17297 VexEndness host_endness_IN, 17298 Bool sigill_diag_IN ) 17299 { 17300 DisResult dres; 17301 /* Set globals (see top of this file) */ 17302 vassert(guest_arch == VexArchMIPS32 || guest_arch == VexArchMIPS64); 17303 17304 mode64 = guest_arch != VexArchMIPS32; 17305 #if (__mips_fpr==64) 17306 fp_mode64 = ((VEX_MIPS_REV(archinfo->hwcaps) == VEX_PRID_CPU_32FPR) 17307 || guest_arch == VexArchMIPS64); 17308 #endif 17309 17310 guest_code = guest_code_IN; 17311 irsb = irsb_IN; 17312 host_endness = host_endness_IN; 17313 #if defined(VGP_mips32_linux) 17314 guest_PC_curr_instr = (Addr32)guest_IP; 17315 #elif defined(VGP_mips64_linux) 17316 guest_PC_curr_instr = (Addr64)guest_IP; 17317 #endif 17318 17319 dres = disInstr_MIPS_WRK(resteerOkFn, resteerCisOk, callback_opaque, 17320 delta, archinfo, abiinfo, sigill_diag_IN); 17321 17322 return dres; 17323 } 17324 17325 /*--------------------------------------------------------------------*/ 17326 /*--- end guest_mips_toIR.c ---*/ 17327 /*--------------------------------------------------------------------*/ 17328