1 /* -*- mode: C; c-basic-offset: 3; -*- */ 2 3 /*---------------------------------------------------------------*/ 4 /*--- begin guest_s390_toIR.c ---*/ 5 /*---------------------------------------------------------------*/ 6 7 /* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright IBM Corp. 2010-2015 12 13 This program is free software; you can redistribute it and/or 14 modify it under the terms of the GNU General Public License as 15 published by the Free Software Foundation; either version 2 of the 16 License, or (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, but 19 WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 02110-1301, USA. 27 28 The GNU General Public License is contained in the file COPYING. 29 */ 30 31 /* Contributed by Florian Krohm and Christian Borntraeger */ 32 33 /* Translates s390 code to IR. */ 34 35 #include "libvex_basictypes.h" 36 #include "libvex_ir.h" 37 #include "libvex_emnote.h" 38 #include "libvex_s390x_common.h" 39 #include "main_util.h" /* vassert */ 40 #include "main_globals.h" /* vex_traceflags */ 41 #include "guest_generic_bb_to_IR.h" /* DisResult */ 42 #include "guest_s390_defs.h" /* prototypes for this file's functions */ 43 #include "s390_disasm.h" 44 #include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */ 45 #include "host_s390_defs.h" /* s390_host_has_xyzzy */ 46 47 48 /*------------------------------------------------------------*/ 49 /*--- Forward declarations ---*/ 50 /*------------------------------------------------------------*/ 51 static UInt s390_decode_and_irgen(const UChar *, UInt, DisResult *); 52 static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp); 53 static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp); 54 55 56 /*------------------------------------------------------------*/ 57 /*--- Globals ---*/ 58 /*------------------------------------------------------------*/ 59 60 /* The IRSB* into which we're generating code. */ 61 static IRSB *irsb; 62 63 /* The guest address for the instruction currently being 64 translated. */ 65 static Addr64 guest_IA_curr_instr; 66 67 /* The guest address for the instruction following the current instruction. */ 68 static Addr64 guest_IA_next_instr; 69 70 /* Result of disassembly step. */ 71 static DisResult *dis_res; 72 73 /* Resteer function and callback data */ 74 static Bool (*resteer_fn)(void *, Addr); 75 static void *resteer_data; 76 77 /* Whether to print diagnostics for illegal instructions. */ 78 static Bool sigill_diag; 79 80 /* The last seen execute target instruction */ 81 ULong last_execute_target; 82 83 /* The possible outcomes of a decoding operation */ 84 typedef enum { 85 S390_DECODE_OK, 86 S390_DECODE_UNKNOWN_INSN, 87 S390_DECODE_UNIMPLEMENTED_INSN, 88 S390_DECODE_UNKNOWN_SPECIAL_INSN, 89 S390_DECODE_ERROR 90 } s390_decode_t; 91 92 93 /*------------------------------------------------------------*/ 94 /*--- Helpers for constructing IR. ---*/ 95 /*------------------------------------------------------------*/ 96 97 /* Add a statement to the current irsb. */ 98 static __inline__ void 99 stmt(IRStmt *st) 100 { 101 addStmtToIRSB(irsb, st); 102 } 103 104 /* Allocate a new temporary of the given type. */ 105 static __inline__ IRTemp 106 newTemp(IRType type) 107 { 108 vassert(isPlausibleIRType(type)); 109 110 return newIRTemp(irsb->tyenv, type); 111 } 112 113 /* Create an expression node for a temporary */ 114 static __inline__ IRExpr * 115 mkexpr(IRTemp tmp) 116 { 117 return IRExpr_RdTmp(tmp); 118 } 119 120 /* Generate an expression node for an address. */ 121 static __inline__ IRExpr * 122 mkaddr_expr(Addr64 addr) 123 { 124 return IRExpr_Const(IRConst_U64(addr)); 125 } 126 127 /* Add a statement that assigns to a temporary */ 128 static __inline__ void 129 assign(IRTemp dst, IRExpr *expr) 130 { 131 stmt(IRStmt_WrTmp(dst, expr)); 132 } 133 134 /* Write an address into the guest_IA */ 135 static __inline__ void 136 put_IA(IRExpr *address) 137 { 138 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address)); 139 } 140 141 /* Create a temporary of the given type and assign the expression to it */ 142 static __inline__ IRTemp 143 mktemp(IRType type, IRExpr *expr) 144 { 145 IRTemp temp = newTemp(type); 146 147 assign(temp, expr); 148 149 return temp; 150 } 151 152 /* Create a unary expression */ 153 static __inline__ IRExpr * 154 unop(IROp kind, IRExpr *op) 155 { 156 return IRExpr_Unop(kind, op); 157 } 158 159 /* Create a binary expression */ 160 static __inline__ IRExpr * 161 binop(IROp kind, IRExpr *op1, IRExpr *op2) 162 { 163 return IRExpr_Binop(kind, op1, op2); 164 } 165 166 /* Create a ternary expression */ 167 static __inline__ IRExpr * 168 triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3) 169 { 170 return IRExpr_Triop(kind, op1, op2, op3); 171 } 172 173 /* Create a quaternary expression */ 174 static __inline__ IRExpr * 175 qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4) 176 { 177 return IRExpr_Qop(kind, op1, op2, op3, op4); 178 } 179 180 /* Create an expression node for an 8-bit integer constant */ 181 static __inline__ IRExpr * 182 mkU8(UInt value) 183 { 184 vassert(value < 256); 185 186 return IRExpr_Const(IRConst_U8((UChar)value)); 187 } 188 189 /* Create an expression node for a 16-bit integer constant */ 190 static __inline__ IRExpr * 191 mkU16(UInt value) 192 { 193 vassert(value < 65536); 194 195 return IRExpr_Const(IRConst_U16((UShort)value)); 196 } 197 198 /* Create an expression node for a 32-bit integer constant */ 199 static __inline__ IRExpr * 200 mkU32(UInt value) 201 { 202 return IRExpr_Const(IRConst_U32(value)); 203 } 204 205 /* Create an expression node for a 64-bit integer constant */ 206 static __inline__ IRExpr * 207 mkU64(ULong value) 208 { 209 return IRExpr_Const(IRConst_U64(value)); 210 } 211 212 /* Create an expression node for a 32-bit floating point constant 213 whose value is given by a bit pattern. */ 214 static __inline__ IRExpr * 215 mkF32i(UInt value) 216 { 217 return IRExpr_Const(IRConst_F32i(value)); 218 } 219 220 /* Create an expression node for a 32-bit floating point constant 221 whose value is given by a bit pattern. */ 222 static __inline__ IRExpr * 223 mkF64i(ULong value) 224 { 225 return IRExpr_Const(IRConst_F64i(value)); 226 } 227 228 /* Little helper function for my sanity. ITE = if-then-else */ 229 static IRExpr * 230 mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse) 231 { 232 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1); 233 234 return IRExpr_ITE(condition, iftrue, iffalse); 235 } 236 237 /* Add a statement that stores DATA at ADDR. This is a big-endian machine. */ 238 static __inline__ void 239 store(IRExpr *addr, IRExpr *data) 240 { 241 stmt(IRStmt_Store(Iend_BE, addr, data)); 242 } 243 244 /* Create an expression that loads a TYPE sized value from ADDR. 245 This is a big-endian machine. */ 246 static __inline__ IRExpr * 247 load(IRType type, IRExpr *addr) 248 { 249 return IRExpr_Load(Iend_BE, type, addr); 250 } 251 252 /* Function call */ 253 static void 254 call_function(IRExpr *callee_address) 255 { 256 put_IA(callee_address); 257 258 dis_res->whatNext = Dis_StopHere; 259 dis_res->jk_StopHere = Ijk_Call; 260 } 261 262 /* Function call with known target. */ 263 static void 264 call_function_and_chase(Addr64 callee_address) 265 { 266 if (resteer_fn(resteer_data, callee_address)) { 267 dis_res->whatNext = Dis_ResteerU; 268 dis_res->continueAt = callee_address; 269 } else { 270 put_IA(mkaddr_expr(callee_address)); 271 272 dis_res->whatNext = Dis_StopHere; 273 dis_res->jk_StopHere = Ijk_Call; 274 } 275 } 276 277 /* Function return sequence */ 278 static void 279 return_from_function(IRExpr *return_address) 280 { 281 put_IA(return_address); 282 283 dis_res->whatNext = Dis_StopHere; 284 dis_res->jk_StopHere = Ijk_Ret; 285 } 286 287 /* A conditional branch whose target is not known at instrumentation time. 288 289 if (condition) goto computed_target; 290 291 Needs to be represented as: 292 293 if (! condition) goto next_instruction; 294 goto computed_target; 295 */ 296 static void 297 if_condition_goto_computed(IRExpr *condition, IRExpr *target) 298 { 299 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1); 300 301 condition = unop(Iop_Not1, condition); 302 303 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr), 304 S390X_GUEST_OFFSET(guest_IA))); 305 306 put_IA(target); 307 308 dis_res->whatNext = Dis_StopHere; 309 dis_res->jk_StopHere = Ijk_Boring; 310 } 311 312 /* A conditional branch whose target is known at instrumentation time. */ 313 static void 314 if_condition_goto(IRExpr *condition, Addr64 target) 315 { 316 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1); 317 318 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target), 319 S390X_GUEST_OFFSET(guest_IA))); 320 321 put_IA(mkaddr_expr(guest_IA_next_instr)); 322 323 dis_res->whatNext = Dis_StopHere; 324 dis_res->jk_StopHere = Ijk_Boring; 325 } 326 327 /* An unconditional branch. Target may or may not be known at instrumentation 328 time. */ 329 static void 330 always_goto(IRExpr *target) 331 { 332 put_IA(target); 333 334 dis_res->whatNext = Dis_StopHere; 335 dis_res->jk_StopHere = Ijk_Boring; 336 } 337 338 339 /* An unconditional branch to a known target. */ 340 static void 341 always_goto_and_chase(Addr64 target) 342 { 343 if (resteer_fn(resteer_data, target)) { 344 /* Follow into the target */ 345 dis_res->whatNext = Dis_ResteerU; 346 dis_res->continueAt = target; 347 } else { 348 put_IA(mkaddr_expr(target)); 349 350 dis_res->whatNext = Dis_StopHere; 351 dis_res->jk_StopHere = Ijk_Boring; 352 } 353 } 354 355 /* A system call */ 356 static void 357 system_call(IRExpr *sysno) 358 { 359 /* Store the system call number in the pseudo register. */ 360 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno)); 361 362 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */ 363 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL), 364 mkU64(guest_IA_curr_instr))); 365 366 put_IA(mkaddr_expr(guest_IA_next_instr)); 367 368 /* It's important that all ArchRegs carry their up-to-date value 369 at this point. So we declare an end-of-block here, which 370 forces any TempRegs caching ArchRegs to be flushed. */ 371 dis_res->whatNext = Dis_StopHere; 372 dis_res->jk_StopHere = Ijk_Sys_syscall; 373 } 374 375 /* A side exit that branches back to the current insn if CONDITION is 376 true. Does not set DisResult. */ 377 static void 378 iterate_if(IRExpr *condition) 379 { 380 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1); 381 382 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr), 383 S390X_GUEST_OFFSET(guest_IA))); 384 } 385 386 /* A side exit that branches back to the current insn. 387 Does not set DisResult. */ 388 static __inline__ void 389 iterate(void) 390 { 391 iterate_if(IRExpr_Const(IRConst_U1(True))); 392 } 393 394 /* A side exit that branches back to the insn immediately following the 395 current insn if CONDITION is true. Does not set DisResult. */ 396 static void 397 next_insn_if(IRExpr *condition) 398 { 399 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1); 400 401 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr), 402 S390X_GUEST_OFFSET(guest_IA))); 403 } 404 405 /* Convenience function to restart the current insn */ 406 static void 407 restart_if(IRExpr *condition) 408 { 409 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1); 410 411 stmt(IRStmt_Exit(condition, Ijk_InvalICache, 412 IRConst_U64(guest_IA_curr_instr), 413 S390X_GUEST_OFFSET(guest_IA))); 414 } 415 416 /* Convenience function to yield to thread scheduler */ 417 static void 418 yield_if(IRExpr *condition) 419 { 420 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr), 421 S390X_GUEST_OFFSET(guest_IA))); 422 } 423 424 static __inline__ IRExpr *get_fpr_dw0(UInt); 425 static __inline__ void put_fpr_dw0(UInt, IRExpr *); 426 static __inline__ IRExpr *get_dpr_dw0(UInt); 427 static __inline__ void put_dpr_dw0(UInt, IRExpr *); 428 429 /* Read a floating point register pair and combine their contents into a 430 128-bit value */ 431 static IRExpr * 432 get_fpr_pair(UInt archreg) 433 { 434 IRExpr *high = get_fpr_dw0(archreg); 435 IRExpr *low = get_fpr_dw0(archreg + 2); 436 437 return binop(Iop_F64HLtoF128, high, low); 438 } 439 440 /* Write a 128-bit floating point value into a register pair. */ 441 static void 442 put_fpr_pair(UInt archreg, IRExpr *expr) 443 { 444 IRExpr *high = unop(Iop_F128HItoF64, expr); 445 IRExpr *low = unop(Iop_F128LOtoF64, expr); 446 447 put_fpr_dw0(archreg, high); 448 put_fpr_dw0(archreg + 2, low); 449 } 450 451 /* Read a floating point register pair cointaining DFP value 452 and combine their contents into a 128-bit value */ 453 454 static IRExpr * 455 get_dpr_pair(UInt archreg) 456 { 457 IRExpr *high = get_dpr_dw0(archreg); 458 IRExpr *low = get_dpr_dw0(archreg + 2); 459 460 return binop(Iop_D64HLtoD128, high, low); 461 } 462 463 /* Write a 128-bit decimal floating point value into a register pair. */ 464 static void 465 put_dpr_pair(UInt archreg, IRExpr *expr) 466 { 467 IRExpr *high = unop(Iop_D128HItoD64, expr); 468 IRExpr *low = unop(Iop_D128LOtoD64, expr); 469 470 put_dpr_dw0(archreg, high); 471 put_dpr_dw0(archreg + 2, low); 472 } 473 474 /* Terminate the current IRSB with an emulation failure. */ 475 static void 476 emulation_failure_with_expr(IRExpr *emfailure) 477 { 478 vassert(typeOfIRExpr(irsb->tyenv, emfailure) == Ity_I32); 479 480 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emfailure)); 481 dis_res->whatNext = Dis_StopHere; 482 dis_res->jk_StopHere = Ijk_EmFail; 483 } 484 485 static void 486 emulation_failure(VexEmNote fail_kind) 487 { 488 emulation_failure_with_expr(mkU32(fail_kind)); 489 } 490 491 /* Terminate the current IRSB with an emulation warning. */ 492 static void 493 emulation_warning_with_expr(IRExpr *emwarning) 494 { 495 vassert(typeOfIRExpr(irsb->tyenv, emwarning) == Ity_I32); 496 497 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emwarning)); 498 dis_res->whatNext = Dis_StopHere; 499 dis_res->jk_StopHere = Ijk_EmWarn; 500 } 501 502 static void 503 emulation_warning(VexEmNote warn_kind) 504 { 505 emulation_warning_with_expr(mkU32(warn_kind)); 506 } 507 508 /*------------------------------------------------------------*/ 509 /*--- IR Debugging aids. ---*/ 510 /*------------------------------------------------------------*/ 511 #if 0 512 513 static ULong 514 s390_do_print(HChar *text, ULong value) 515 { 516 vex_printf("%s %llu\n", text, value); 517 return 0; 518 } 519 520 static void 521 s390_print(HChar *text, IRExpr *value) 522 { 523 IRDirty *d; 524 525 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print, 526 mkIRExprVec_2(mkU64((ULong)text), value)); 527 stmt(IRStmt_Dirty(d)); 528 } 529 #endif 530 531 532 /*------------------------------------------------------------*/ 533 /*--- Build the flags thunk. ---*/ 534 /*------------------------------------------------------------*/ 535 536 /* Completely fill the flags thunk. We're always filling all fields. 537 Apparently, that is better for redundant PUT elimination. */ 538 static void 539 s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep) 540 { 541 UInt op_off, dep1_off, dep2_off, ndep_off; 542 543 op_off = S390X_GUEST_OFFSET(guest_CC_OP); 544 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1); 545 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2); 546 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP); 547 548 stmt(IRStmt_Put(op_off, op)); 549 stmt(IRStmt_Put(dep1_off, dep1)); 550 stmt(IRStmt_Put(dep2_off, dep2)); 551 stmt(IRStmt_Put(ndep_off, ndep)); 552 } 553 554 555 /* Create an expression for V and widen the result to 64 bit. */ 556 static IRExpr * 557 s390_cc_widen(IRTemp v, Bool sign_extend) 558 { 559 IRExpr *expr; 560 561 expr = mkexpr(v); 562 563 switch (typeOfIRTemp(irsb->tyenv, v)) { 564 case Ity_I64: 565 break; 566 case Ity_I32: 567 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr); 568 break; 569 case Ity_I16: 570 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr); 571 break; 572 case Ity_I8: 573 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr); 574 break; 575 default: 576 vpanic("s390_cc_widen"); 577 } 578 579 return expr; 580 } 581 582 static void 583 s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend) 584 { 585 IRExpr *op, *dep1, *dep2, *ndep; 586 587 op = mkU64(opc); 588 dep1 = s390_cc_widen(d1, sign_extend); 589 dep2 = mkU64(0); 590 ndep = mkU64(0); 591 592 s390_cc_thunk_fill(op, dep1, dep2, ndep); 593 } 594 595 596 static void 597 s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend) 598 { 599 IRExpr *op, *dep1, *dep2, *ndep; 600 601 op = mkU64(opc); 602 dep1 = s390_cc_widen(d1, sign_extend); 603 dep2 = s390_cc_widen(d2, sign_extend); 604 ndep = mkU64(0); 605 606 s390_cc_thunk_fill(op, dep1, dep2, ndep); 607 } 608 609 610 /* memcheck believes that the NDEP field in the flags thunk is always 611 defined. But for some flag computations (e.g. add with carry) that is 612 just not true. We therefore need to convey to memcheck that the value 613 of the ndep field does matter and therefore we make the DEP2 field 614 depend on it: 615 616 DEP2 = original_DEP2 ^ NDEP 617 618 In s390_calculate_cc we exploit that (a^b)^b == a 619 I.e. we xor the DEP2 value with the NDEP value to recover the 620 original_DEP2 value. */ 621 static void 622 s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend) 623 { 624 IRExpr *op, *dep1, *dep2, *ndep, *dep2x; 625 626 op = mkU64(opc); 627 dep1 = s390_cc_widen(d1, sign_extend); 628 dep2 = s390_cc_widen(d2, sign_extend); 629 ndep = s390_cc_widen(nd, sign_extend); 630 631 dep2x = binop(Iop_Xor64, dep2, ndep); 632 633 s390_cc_thunk_fill(op, dep1, dep2x, ndep); 634 } 635 636 637 /* Write one floating point value into the flags thunk */ 638 static void 639 s390_cc_thunk_put1f(UInt opc, IRTemp d1) 640 { 641 IRExpr *op, *dep1, *dep2, *ndep; 642 643 /* Make the CC_DEP1 slot appear completely defined. 644 Otherwise, assigning a 32-bit value will cause memcheck 645 to trigger an undefinedness error. 646 */ 647 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) { 648 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1); 649 stmt(IRStmt_Put(dep1_off, mkU64(0))); 650 } 651 op = mkU64(opc); 652 dep1 = mkexpr(d1); 653 dep2 = mkU64(0); 654 ndep = mkU64(0); 655 656 s390_cc_thunk_fill(op, dep1, dep2, ndep); 657 } 658 659 660 /* Write a floating point value and an integer into the flags thunk. The 661 integer value is zero-extended first. */ 662 static void 663 s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2) 664 { 665 IRExpr *op, *dep1, *dep2, *ndep; 666 667 /* Make the CC_DEP1 slot appear completely defined. 668 Otherwise, assigning a 32-bit value will cause memcheck 669 to trigger an undefinedness error. 670 */ 671 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) { 672 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1); 673 stmt(IRStmt_Put(dep1_off, mkU64(0))); 674 } 675 op = mkU64(opc); 676 dep1 = mkexpr(d1); 677 dep2 = s390_cc_widen(d2, False); 678 ndep = mkU64(0); 679 680 s390_cc_thunk_fill(op, dep1, dep2, ndep); 681 } 682 683 684 /* Write a 128-bit floating point value into the flags thunk. This is 685 done by splitting the value into two 64-bits values. */ 686 static void 687 s390_cc_thunk_put1f128(UInt opc, IRTemp d1) 688 { 689 IRExpr *op, *hi, *lo, *ndep; 690 691 op = mkU64(opc); 692 hi = unop(Iop_F128HItoF64, mkexpr(d1)); 693 lo = unop(Iop_F128LOtoF64, mkexpr(d1)); 694 ndep = mkU64(0); 695 696 s390_cc_thunk_fill(op, hi, lo, ndep); 697 } 698 699 700 /* Write a 128-bit floating point value and an integer into the flags thunk. 701 The integer value is zero-extended first. */ 702 static void 703 s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd) 704 { 705 IRExpr *op, *hi, *lo, *lox, *ndep; 706 707 op = mkU64(opc); 708 hi = unop(Iop_F128HItoF64, mkexpr(d1)); 709 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1))); 710 ndep = s390_cc_widen(nd, False); 711 712 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */ 713 714 s390_cc_thunk_fill(op, hi, lox, ndep); 715 } 716 717 718 /* Write a 128-bit decimal floating point value into the flags thunk. 719 This is done by splitting the value into two 64-bits values. */ 720 static void 721 s390_cc_thunk_put1d128(UInt opc, IRTemp d1) 722 { 723 IRExpr *op, *hi, *lo, *ndep; 724 725 op = mkU64(opc); 726 hi = unop(Iop_D128HItoD64, mkexpr(d1)); 727 lo = unop(Iop_D128LOtoD64, mkexpr(d1)); 728 ndep = mkU64(0); 729 730 s390_cc_thunk_fill(op, hi, lo, ndep); 731 } 732 733 734 /* Write a 128-bit decimal floating point value and an integer into the flags 735 thunk. The integer value is zero-extended first. */ 736 static void 737 s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd) 738 { 739 IRExpr *op, *hi, *lo, *lox, *ndep; 740 741 op = mkU64(opc); 742 hi = unop(Iop_D128HItoD64, mkexpr(d1)); 743 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1))); 744 ndep = s390_cc_widen(nd, False); 745 746 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */ 747 748 s390_cc_thunk_fill(op, hi, lox, ndep); 749 } 750 751 752 static void 753 s390_cc_set(UInt val) 754 { 755 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), 756 mkU64(val), mkU64(0), mkU64(0)); 757 } 758 759 /* Build IR to calculate the condition code from flags thunk. 760 Returns an expression of type Ity_I32 */ 761 static IRExpr * 762 s390_call_calculate_cc(void) 763 { 764 IRExpr **args, *call, *op, *dep1, *dep2, *ndep; 765 766 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64); 767 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64); 768 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64); 769 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64); 770 771 args = mkIRExprVec_4(op, dep1, dep2, ndep); 772 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/, 773 "s390_calculate_cc", &s390_calculate_cc, args); 774 775 /* Exclude OP and NDEP from definedness checking. We're only 776 interested in DEP1 and DEP2. */ 777 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3); 778 779 return call; 780 } 781 782 /* Build IR to calculate the internal condition code for a "compare and branch" 783 insn. Returns an expression of type Ity_I32 */ 784 static IRExpr * 785 s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2) 786 { 787 IRExpr **args, *call, *op, *dep1, *dep2, *mask; 788 789 switch (opc) { 790 case S390_CC_OP_SIGNED_COMPARE: 791 dep1 = s390_cc_widen(op1, True); 792 dep2 = s390_cc_widen(op2, True); 793 break; 794 795 case S390_CC_OP_UNSIGNED_COMPARE: 796 dep1 = s390_cc_widen(op1, False); 797 dep2 = s390_cc_widen(op2, False); 798 break; 799 800 default: 801 vpanic("s390_call_calculate_icc"); 802 } 803 804 mask = mkU64(m); 805 op = mkU64(opc); 806 807 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */); 808 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/, 809 "s390_calculate_cond", &s390_calculate_cond, args); 810 811 /* Exclude the requested condition, OP and NDEP from definedness 812 checking. We're only interested in DEP1 and DEP2. */ 813 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4); 814 815 return call; 816 } 817 818 /* Build IR to calculate the condition code from flags thunk. 819 Returns an expression of type Ity_I32 */ 820 static IRExpr * 821 s390_call_calculate_cond(UInt m) 822 { 823 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask; 824 825 mask = mkU64(m); 826 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64); 827 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64); 828 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64); 829 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64); 830 831 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep); 832 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/, 833 "s390_calculate_cond", &s390_calculate_cond, args); 834 835 /* Exclude the requested condition, OP and NDEP from definedness 836 checking. We're only interested in DEP1 and DEP2. */ 837 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4); 838 839 return call; 840 } 841 842 #define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False) 843 #define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True) 844 #define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1) 845 #define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False) 846 #define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True) 847 #define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2) 848 #define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \ 849 s390_cc_thunk_put3(op,dep1,dep2,ndep,False) 850 #define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \ 851 s390_cc_thunk_put3(op,dep1,dep2,ndep,True) 852 853 854 855 856 /*------------------------------------------------------------*/ 857 /*--- Guest register access ---*/ 858 /*------------------------------------------------------------*/ 859 860 861 /*------------------------------------------------------------*/ 862 /*--- ar registers ---*/ 863 /*------------------------------------------------------------*/ 864 865 /* Return the guest state offset of a ar register. */ 866 static UInt 867 ar_offset(UInt archreg) 868 { 869 static const UInt offset[16] = { 870 S390X_GUEST_OFFSET(guest_a0), 871 S390X_GUEST_OFFSET(guest_a1), 872 S390X_GUEST_OFFSET(guest_a2), 873 S390X_GUEST_OFFSET(guest_a3), 874 S390X_GUEST_OFFSET(guest_a4), 875 S390X_GUEST_OFFSET(guest_a5), 876 S390X_GUEST_OFFSET(guest_a6), 877 S390X_GUEST_OFFSET(guest_a7), 878 S390X_GUEST_OFFSET(guest_a8), 879 S390X_GUEST_OFFSET(guest_a9), 880 S390X_GUEST_OFFSET(guest_a10), 881 S390X_GUEST_OFFSET(guest_a11), 882 S390X_GUEST_OFFSET(guest_a12), 883 S390X_GUEST_OFFSET(guest_a13), 884 S390X_GUEST_OFFSET(guest_a14), 885 S390X_GUEST_OFFSET(guest_a15), 886 }; 887 888 vassert(archreg < 16); 889 890 return offset[archreg]; 891 } 892 893 894 /* Return the guest state offset of word #0 of a ar register. */ 895 static __inline__ UInt 896 ar_w0_offset(UInt archreg) 897 { 898 return ar_offset(archreg) + 0; 899 } 900 901 /* Write word #0 of a ar to the guest state. */ 902 static __inline__ void 903 put_ar_w0(UInt archreg, IRExpr *expr) 904 { 905 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32); 906 907 stmt(IRStmt_Put(ar_w0_offset(archreg), expr)); 908 } 909 910 /* Read word #0 of a ar register. */ 911 static __inline__ IRExpr * 912 get_ar_w0(UInt archreg) 913 { 914 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32); 915 } 916 917 918 /*------------------------------------------------------------*/ 919 /*--- fpr registers ---*/ 920 /*------------------------------------------------------------*/ 921 922 /* Return the guest state offset of a fpr register. */ 923 static UInt 924 fpr_offset(UInt archreg) 925 { 926 static const UInt offset[16] = { 927 S390X_GUEST_OFFSET(guest_f0), 928 S390X_GUEST_OFFSET(guest_f1), 929 S390X_GUEST_OFFSET(guest_f2), 930 S390X_GUEST_OFFSET(guest_f3), 931 S390X_GUEST_OFFSET(guest_f4), 932 S390X_GUEST_OFFSET(guest_f5), 933 S390X_GUEST_OFFSET(guest_f6), 934 S390X_GUEST_OFFSET(guest_f7), 935 S390X_GUEST_OFFSET(guest_f8), 936 S390X_GUEST_OFFSET(guest_f9), 937 S390X_GUEST_OFFSET(guest_f10), 938 S390X_GUEST_OFFSET(guest_f11), 939 S390X_GUEST_OFFSET(guest_f12), 940 S390X_GUEST_OFFSET(guest_f13), 941 S390X_GUEST_OFFSET(guest_f14), 942 S390X_GUEST_OFFSET(guest_f15), 943 }; 944 945 vassert(archreg < 16); 946 947 return offset[archreg]; 948 } 949 950 951 /* Return the guest state offset of word #0 of a fpr register. */ 952 static __inline__ UInt 953 fpr_w0_offset(UInt archreg) 954 { 955 return fpr_offset(archreg) + 0; 956 } 957 958 /* Write word #0 of a fpr to the guest state. */ 959 static __inline__ void 960 put_fpr_w0(UInt archreg, IRExpr *expr) 961 { 962 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32); 963 964 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr)); 965 } 966 967 /* Read word #0 of a fpr register. */ 968 static __inline__ IRExpr * 969 get_fpr_w0(UInt archreg) 970 { 971 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32); 972 } 973 974 /* Return the guest state offset of double word #0 of a fpr register. */ 975 static __inline__ UInt 976 fpr_dw0_offset(UInt archreg) 977 { 978 return fpr_offset(archreg) + 0; 979 } 980 981 /* Write double word #0 of a fpr to the guest state. */ 982 static __inline__ void 983 put_fpr_dw0(UInt archreg, IRExpr *expr) 984 { 985 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64); 986 987 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr)); 988 } 989 990 /* Read double word #0 of a fpr register. */ 991 static __inline__ IRExpr * 992 get_fpr_dw0(UInt archreg) 993 { 994 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64); 995 } 996 997 /* Write word #0 of a dpr to the guest state. */ 998 static __inline__ void 999 put_dpr_w0(UInt archreg, IRExpr *expr) 1000 { 1001 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32); 1002 1003 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr)); 1004 } 1005 1006 /* Read word #0 of a dpr register. */ 1007 static __inline__ IRExpr * 1008 get_dpr_w0(UInt archreg) 1009 { 1010 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32); 1011 } 1012 1013 /* Write double word #0 of a fpr containg DFP value to the guest state. */ 1014 static __inline__ void 1015 put_dpr_dw0(UInt archreg, IRExpr *expr) 1016 { 1017 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64); 1018 1019 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr)); 1020 } 1021 1022 /* Read double word #0 of a fpr register containing DFP value. */ 1023 static __inline__ IRExpr * 1024 get_dpr_dw0(UInt archreg) 1025 { 1026 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64); 1027 } 1028 1029 /*------------------------------------------------------------*/ 1030 /*--- gpr registers ---*/ 1031 /*------------------------------------------------------------*/ 1032 1033 /* Return the guest state offset of a gpr register. */ 1034 static UInt 1035 gpr_offset(UInt archreg) 1036 { 1037 static const UInt offset[16] = { 1038 S390X_GUEST_OFFSET(guest_r0), 1039 S390X_GUEST_OFFSET(guest_r1), 1040 S390X_GUEST_OFFSET(guest_r2), 1041 S390X_GUEST_OFFSET(guest_r3), 1042 S390X_GUEST_OFFSET(guest_r4), 1043 S390X_GUEST_OFFSET(guest_r5), 1044 S390X_GUEST_OFFSET(guest_r6), 1045 S390X_GUEST_OFFSET(guest_r7), 1046 S390X_GUEST_OFFSET(guest_r8), 1047 S390X_GUEST_OFFSET(guest_r9), 1048 S390X_GUEST_OFFSET(guest_r10), 1049 S390X_GUEST_OFFSET(guest_r11), 1050 S390X_GUEST_OFFSET(guest_r12), 1051 S390X_GUEST_OFFSET(guest_r13), 1052 S390X_GUEST_OFFSET(guest_r14), 1053 S390X_GUEST_OFFSET(guest_r15), 1054 }; 1055 1056 vassert(archreg < 16); 1057 1058 return offset[archreg]; 1059 } 1060 1061 1062 /* Return the guest state offset of word #0 of a gpr register. */ 1063 static __inline__ UInt 1064 gpr_w0_offset(UInt archreg) 1065 { 1066 return gpr_offset(archreg) + 0; 1067 } 1068 1069 /* Write word #0 of a gpr to the guest state. */ 1070 static __inline__ void 1071 put_gpr_w0(UInt archreg, IRExpr *expr) 1072 { 1073 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32); 1074 1075 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr)); 1076 } 1077 1078 /* Read word #0 of a gpr register. */ 1079 static __inline__ IRExpr * 1080 get_gpr_w0(UInt archreg) 1081 { 1082 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32); 1083 } 1084 1085 /* Return the guest state offset of double word #0 of a gpr register. */ 1086 static __inline__ UInt 1087 gpr_dw0_offset(UInt archreg) 1088 { 1089 return gpr_offset(archreg) + 0; 1090 } 1091 1092 /* Write double word #0 of a gpr to the guest state. */ 1093 static __inline__ void 1094 put_gpr_dw0(UInt archreg, IRExpr *expr) 1095 { 1096 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64); 1097 1098 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr)); 1099 } 1100 1101 /* Read double word #0 of a gpr register. */ 1102 static __inline__ IRExpr * 1103 get_gpr_dw0(UInt archreg) 1104 { 1105 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64); 1106 } 1107 1108 /* Return the guest state offset of half word #1 of a gpr register. */ 1109 static __inline__ UInt 1110 gpr_hw1_offset(UInt archreg) 1111 { 1112 return gpr_offset(archreg) + 2; 1113 } 1114 1115 /* Write half word #1 of a gpr to the guest state. */ 1116 static __inline__ void 1117 put_gpr_hw1(UInt archreg, IRExpr *expr) 1118 { 1119 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16); 1120 1121 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr)); 1122 } 1123 1124 /* Read half word #1 of a gpr register. */ 1125 static __inline__ IRExpr * 1126 get_gpr_hw1(UInt archreg) 1127 { 1128 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16); 1129 } 1130 1131 /* Return the guest state offset of byte #6 of a gpr register. */ 1132 static __inline__ UInt 1133 gpr_b6_offset(UInt archreg) 1134 { 1135 return gpr_offset(archreg) + 6; 1136 } 1137 1138 /* Write byte #6 of a gpr to the guest state. */ 1139 static __inline__ void 1140 put_gpr_b6(UInt archreg, IRExpr *expr) 1141 { 1142 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8); 1143 1144 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr)); 1145 } 1146 1147 /* Read byte #6 of a gpr register. */ 1148 static __inline__ IRExpr * 1149 get_gpr_b6(UInt archreg) 1150 { 1151 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8); 1152 } 1153 1154 /* Return the guest state offset of byte #3 of a gpr register. */ 1155 static __inline__ UInt 1156 gpr_b3_offset(UInt archreg) 1157 { 1158 return gpr_offset(archreg) + 3; 1159 } 1160 1161 /* Write byte #3 of a gpr to the guest state. */ 1162 static __inline__ void 1163 put_gpr_b3(UInt archreg, IRExpr *expr) 1164 { 1165 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8); 1166 1167 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr)); 1168 } 1169 1170 /* Read byte #3 of a gpr register. */ 1171 static __inline__ IRExpr * 1172 get_gpr_b3(UInt archreg) 1173 { 1174 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8); 1175 } 1176 1177 /* Return the guest state offset of byte #0 of a gpr register. */ 1178 static __inline__ UInt 1179 gpr_b0_offset(UInt archreg) 1180 { 1181 return gpr_offset(archreg) + 0; 1182 } 1183 1184 /* Write byte #0 of a gpr to the guest state. */ 1185 static __inline__ void 1186 put_gpr_b0(UInt archreg, IRExpr *expr) 1187 { 1188 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8); 1189 1190 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr)); 1191 } 1192 1193 /* Read byte #0 of a gpr register. */ 1194 static __inline__ IRExpr * 1195 get_gpr_b0(UInt archreg) 1196 { 1197 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8); 1198 } 1199 1200 /* Return the guest state offset of word #1 of a gpr register. */ 1201 static __inline__ UInt 1202 gpr_w1_offset(UInt archreg) 1203 { 1204 return gpr_offset(archreg) + 4; 1205 } 1206 1207 /* Write word #1 of a gpr to the guest state. */ 1208 static __inline__ void 1209 put_gpr_w1(UInt archreg, IRExpr *expr) 1210 { 1211 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32); 1212 1213 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr)); 1214 } 1215 1216 /* Read word #1 of a gpr register. */ 1217 static __inline__ IRExpr * 1218 get_gpr_w1(UInt archreg) 1219 { 1220 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32); 1221 } 1222 1223 /* Return the guest state offset of half word #3 of a gpr register. */ 1224 static __inline__ UInt 1225 gpr_hw3_offset(UInt archreg) 1226 { 1227 return gpr_offset(archreg) + 6; 1228 } 1229 1230 /* Write half word #3 of a gpr to the guest state. */ 1231 static __inline__ void 1232 put_gpr_hw3(UInt archreg, IRExpr *expr) 1233 { 1234 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16); 1235 1236 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr)); 1237 } 1238 1239 /* Read half word #3 of a gpr register. */ 1240 static __inline__ IRExpr * 1241 get_gpr_hw3(UInt archreg) 1242 { 1243 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16); 1244 } 1245 1246 /* Return the guest state offset of byte #7 of a gpr register. */ 1247 static __inline__ UInt 1248 gpr_b7_offset(UInt archreg) 1249 { 1250 return gpr_offset(archreg) + 7; 1251 } 1252 1253 /* Write byte #7 of a gpr to the guest state. */ 1254 static __inline__ void 1255 put_gpr_b7(UInt archreg, IRExpr *expr) 1256 { 1257 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8); 1258 1259 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr)); 1260 } 1261 1262 /* Read byte #7 of a gpr register. */ 1263 static __inline__ IRExpr * 1264 get_gpr_b7(UInt archreg) 1265 { 1266 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8); 1267 } 1268 1269 /* Return the guest state offset of half word #0 of a gpr register. */ 1270 static __inline__ UInt 1271 gpr_hw0_offset(UInt archreg) 1272 { 1273 return gpr_offset(archreg) + 0; 1274 } 1275 1276 /* Write half word #0 of a gpr to the guest state. */ 1277 static __inline__ void 1278 put_gpr_hw0(UInt archreg, IRExpr *expr) 1279 { 1280 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16); 1281 1282 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr)); 1283 } 1284 1285 /* Read half word #0 of a gpr register. */ 1286 static __inline__ IRExpr * 1287 get_gpr_hw0(UInt archreg) 1288 { 1289 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16); 1290 } 1291 1292 /* Return the guest state offset of byte #4 of a gpr register. */ 1293 static __inline__ UInt 1294 gpr_b4_offset(UInt archreg) 1295 { 1296 return gpr_offset(archreg) + 4; 1297 } 1298 1299 /* Write byte #4 of a gpr to the guest state. */ 1300 static __inline__ void 1301 put_gpr_b4(UInt archreg, IRExpr *expr) 1302 { 1303 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8); 1304 1305 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr)); 1306 } 1307 1308 /* Read byte #4 of a gpr register. */ 1309 static __inline__ IRExpr * 1310 get_gpr_b4(UInt archreg) 1311 { 1312 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8); 1313 } 1314 1315 /* Return the guest state offset of byte #1 of a gpr register. */ 1316 static __inline__ UInt 1317 gpr_b1_offset(UInt archreg) 1318 { 1319 return gpr_offset(archreg) + 1; 1320 } 1321 1322 /* Write byte #1 of a gpr to the guest state. */ 1323 static __inline__ void 1324 put_gpr_b1(UInt archreg, IRExpr *expr) 1325 { 1326 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8); 1327 1328 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr)); 1329 } 1330 1331 /* Read byte #1 of a gpr register. */ 1332 static __inline__ IRExpr * 1333 get_gpr_b1(UInt archreg) 1334 { 1335 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8); 1336 } 1337 1338 /* Return the guest state offset of half word #2 of a gpr register. */ 1339 static __inline__ UInt 1340 gpr_hw2_offset(UInt archreg) 1341 { 1342 return gpr_offset(archreg) + 4; 1343 } 1344 1345 /* Write half word #2 of a gpr to the guest state. */ 1346 static __inline__ void 1347 put_gpr_hw2(UInt archreg, IRExpr *expr) 1348 { 1349 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16); 1350 1351 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr)); 1352 } 1353 1354 /* Read half word #2 of a gpr register. */ 1355 static __inline__ IRExpr * 1356 get_gpr_hw2(UInt archreg) 1357 { 1358 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16); 1359 } 1360 1361 /* Return the guest state offset of byte #5 of a gpr register. */ 1362 static __inline__ UInt 1363 gpr_b5_offset(UInt archreg) 1364 { 1365 return gpr_offset(archreg) + 5; 1366 } 1367 1368 /* Write byte #5 of a gpr to the guest state. */ 1369 static __inline__ void 1370 put_gpr_b5(UInt archreg, IRExpr *expr) 1371 { 1372 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8); 1373 1374 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr)); 1375 } 1376 1377 /* Read byte #5 of a gpr register. */ 1378 static __inline__ IRExpr * 1379 get_gpr_b5(UInt archreg) 1380 { 1381 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8); 1382 } 1383 1384 /* Return the guest state offset of byte #2 of a gpr register. */ 1385 static __inline__ UInt 1386 gpr_b2_offset(UInt archreg) 1387 { 1388 return gpr_offset(archreg) + 2; 1389 } 1390 1391 /* Write byte #2 of a gpr to the guest state. */ 1392 static __inline__ void 1393 put_gpr_b2(UInt archreg, IRExpr *expr) 1394 { 1395 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8); 1396 1397 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr)); 1398 } 1399 1400 /* Read byte #2 of a gpr register. */ 1401 static __inline__ IRExpr * 1402 get_gpr_b2(UInt archreg) 1403 { 1404 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8); 1405 } 1406 1407 /* Return the guest state offset of the counter register. */ 1408 static UInt 1409 counter_offset(void) 1410 { 1411 return S390X_GUEST_OFFSET(guest_counter); 1412 } 1413 1414 /* Return the guest state offset of double word #0 of the counter register. */ 1415 static __inline__ UInt 1416 counter_dw0_offset(void) 1417 { 1418 return counter_offset() + 0; 1419 } 1420 1421 /* Write double word #0 of the counter to the guest state. */ 1422 static __inline__ void 1423 put_counter_dw0(IRExpr *expr) 1424 { 1425 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64); 1426 1427 stmt(IRStmt_Put(counter_dw0_offset(), expr)); 1428 } 1429 1430 /* Read double word #0 of the counter register. */ 1431 static __inline__ IRExpr * 1432 get_counter_dw0(void) 1433 { 1434 return IRExpr_Get(counter_dw0_offset(), Ity_I64); 1435 } 1436 1437 /* Return the guest state offset of word #0 of the counter register. */ 1438 static __inline__ UInt 1439 counter_w0_offset(void) 1440 { 1441 return counter_offset() + 0; 1442 } 1443 1444 /* Return the guest state offset of word #1 of the counter register. */ 1445 static __inline__ UInt 1446 counter_w1_offset(void) 1447 { 1448 return counter_offset() + 4; 1449 } 1450 1451 /* Write word #0 of the counter to the guest state. */ 1452 static __inline__ void 1453 put_counter_w0(IRExpr *expr) 1454 { 1455 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32); 1456 1457 stmt(IRStmt_Put(counter_w0_offset(), expr)); 1458 } 1459 1460 /* Read word #0 of the counter register. */ 1461 static __inline__ IRExpr * 1462 get_counter_w0(void) 1463 { 1464 return IRExpr_Get(counter_w0_offset(), Ity_I32); 1465 } 1466 1467 /* Write word #1 of the counter to the guest state. */ 1468 static __inline__ void 1469 put_counter_w1(IRExpr *expr) 1470 { 1471 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32); 1472 1473 stmt(IRStmt_Put(counter_w1_offset(), expr)); 1474 } 1475 1476 /* Read word #1 of the counter register. */ 1477 static __inline__ IRExpr * 1478 get_counter_w1(void) 1479 { 1480 return IRExpr_Get(counter_w1_offset(), Ity_I32); 1481 } 1482 1483 /* Return the guest state offset of the fpc register. */ 1484 static UInt 1485 fpc_offset(void) 1486 { 1487 return S390X_GUEST_OFFSET(guest_fpc); 1488 } 1489 1490 /* Return the guest state offset of word #0 of the fpc register. */ 1491 static __inline__ UInt 1492 fpc_w0_offset(void) 1493 { 1494 return fpc_offset() + 0; 1495 } 1496 1497 /* Write word #0 of the fpc to the guest state. */ 1498 static __inline__ void 1499 put_fpc_w0(IRExpr *expr) 1500 { 1501 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32); 1502 1503 stmt(IRStmt_Put(fpc_w0_offset(), expr)); 1504 } 1505 1506 /* Read word #0 of the fpc register. */ 1507 static __inline__ IRExpr * 1508 get_fpc_w0(void) 1509 { 1510 return IRExpr_Get(fpc_w0_offset(), Ity_I32); 1511 } 1512 1513 1514 /*------------------------------------------------------------*/ 1515 /*--- Rounding modes ---*/ 1516 /*------------------------------------------------------------*/ 1517 1518 /* Extract the bfp rounding mode from the guest FPC reg and encode it as an 1519 IRRoundingMode: 1520 1521 rounding mode | s390 | IR 1522 ------------------------- 1523 to nearest | 00 | 00 1524 to zero | 01 | 11 1525 to +infinity | 10 | 10 1526 to -infinity | 11 | 01 1527 1528 So: IR = (4 - s390) & 3 1529 */ 1530 static IRExpr * 1531 get_bfp_rounding_mode_from_fpc(void) 1532 { 1533 IRTemp fpc_bits = newTemp(Ity_I32); 1534 1535 /* For z196 and later the bfp rounding mode is stored in bits [29:31]. 1536 Prior to that bits [30:31] contained the bfp rounding mode with 1537 bit 29 being unused and having a value of 0. So we can always 1538 extract the least significant 3 bits. */ 1539 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7))); 1540 1541 /* fixs390: 1542 1543 1544 if (! s390_host_has_fpext && rounding_mode > 3) { 1545 emulation warning @ runtime and 1546 set fpc to round nearest 1547 } 1548 */ 1549 1550 /* For now silently adjust an unsupported rounding mode to "nearest" */ 1551 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)), 1552 mkexpr(fpc_bits), 1553 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN)); 1554 1555 // rm_IR = (4 - rm_s390) & 3; 1556 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3)); 1557 } 1558 1559 /* Encode the s390 rounding mode as it appears in the m3 field of certain 1560 instructions to VEX's IRRoundingMode. Rounding modes that cannot be 1561 represented in VEX are converted to Irrm_NEAREST. The rationale is, that 1562 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard 1563 considers the default rounding mode (4.3.3). */ 1564 static IRTemp 1565 encode_bfp_rounding_mode(UChar mode) 1566 { 1567 IRExpr *rm; 1568 1569 switch (mode) { 1570 case S390_BFP_ROUND_PER_FPC: 1571 rm = get_bfp_rounding_mode_from_fpc(); 1572 break; 1573 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */ 1574 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */ 1575 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break; 1576 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break; 1577 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break; 1578 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break; 1579 default: 1580 vpanic("encode_bfp_rounding_mode"); 1581 } 1582 1583 return mktemp(Ity_I32, rm); 1584 } 1585 1586 /* Extract the DFP rounding mode from the guest FPC reg and encode it as an 1587 IRRoundingMode: 1588 1589 rounding mode | s390 | IR 1590 ------------------------------------------------ 1591 to nearest, ties to even | 000 | 000 1592 to zero | 001 | 011 1593 to +infinity | 010 | 010 1594 to -infinity | 011 | 001 1595 to nearest, ties away from 0 | 100 | 100 1596 to nearest, ties toward 0 | 101 | 111 1597 to away from 0 | 110 | 110 1598 to prepare for shorter precision | 111 | 101 1599 1600 So: IR = (s390 ^ ((s390 << 1) & 2)) 1601 */ 1602 static IRExpr * 1603 get_dfp_rounding_mode_from_fpc(void) 1604 { 1605 IRTemp fpc_bits = newTemp(Ity_I32); 1606 1607 /* The dfp rounding mode is stored in bits [25:27]. 1608 extract the bits at 25:27 and right shift 4 times. */ 1609 assign(fpc_bits, binop(Iop_Shr32, 1610 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)), 1611 mkU8(4))); 1612 1613 IRExpr *rm_s390 = mkexpr(fpc_bits); 1614 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2)); 1615 1616 return binop(Iop_Xor32, rm_s390, 1617 binop( Iop_And32, 1618 binop(Iop_Shl32, rm_s390, mkU8(1)), 1619 mkU32(2))); 1620 } 1621 1622 /* Encode the s390 rounding mode as it appears in the m3 field of certain 1623 instructions to VEX's IRRoundingMode. */ 1624 static IRTemp 1625 encode_dfp_rounding_mode(UChar mode) 1626 { 1627 IRExpr *rm; 1628 1629 switch (mode) { 1630 case S390_DFP_ROUND_PER_FPC_0: 1631 case S390_DFP_ROUND_PER_FPC_2: 1632 rm = get_dfp_rounding_mode_from_fpc(); break; 1633 case S390_DFP_ROUND_NEAREST_EVEN_4: 1634 case S390_DFP_ROUND_NEAREST_EVEN_8: 1635 rm = mkU32(Irrm_NEAREST); break; 1636 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1: 1637 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12: 1638 rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break; 1639 case S390_DFP_ROUND_PREPARE_SHORT_3: 1640 case S390_DFP_ROUND_PREPARE_SHORT_15: 1641 rm = mkU32(Irrm_PREPARE_SHORTER); break; 1642 case S390_DFP_ROUND_ZERO_5: 1643 case S390_DFP_ROUND_ZERO_9: 1644 rm = mkU32(Irrm_ZERO ); break; 1645 case S390_DFP_ROUND_POSINF_6: 1646 case S390_DFP_ROUND_POSINF_10: 1647 rm = mkU32(Irrm_PosINF); break; 1648 case S390_DFP_ROUND_NEGINF_7: 1649 case S390_DFP_ROUND_NEGINF_11: 1650 rm = mkU32(Irrm_NegINF); break; 1651 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0: 1652 rm = mkU32(Irrm_NEAREST_TIE_TOWARD_0); break; 1653 case S390_DFP_ROUND_AWAY_0: 1654 rm = mkU32(Irrm_AWAY_FROM_ZERO); break; 1655 default: 1656 vpanic("encode_dfp_rounding_mode"); 1657 } 1658 1659 return mktemp(Ity_I32, rm); 1660 } 1661 1662 1663 /*------------------------------------------------------------*/ 1664 /*--- Condition code helpers ---*/ 1665 /*------------------------------------------------------------*/ 1666 1667 /* The result of a Iop_CmpFxx operation is a condition code. It is 1668 encoded using the values defined in type IRCmpFxxResult. 1669 Before we can store the condition code into the guest state (or do 1670 anything else with it for that matter) we need to convert it to 1671 the encoding that s390 uses. This is what this function does. 1672 1673 s390 VEX b6 b2 b0 cc.1 cc.0 1674 0 0x40 EQ 1 0 0 0 0 1675 1 0x01 LT 0 0 1 0 1 1676 2 0x00 GT 0 0 0 1 0 1677 3 0x45 Unordered 1 1 1 1 1 1678 1679 The following bits from the VEX encoding are interesting: 1680 b0, b2, b6 with b0 being the LSB. We observe: 1681 1682 cc.0 = b0; 1683 cc.1 = b2 | (~b0 & ~b6) 1684 1685 with cc being the s390 condition code. 1686 */ 1687 static IRExpr * 1688 convert_vex_bfpcc_to_s390(IRTemp vex_cc) 1689 { 1690 IRTemp cc0 = newTemp(Ity_I32); 1691 IRTemp cc1 = newTemp(Ity_I32); 1692 IRTemp b0 = newTemp(Ity_I32); 1693 IRTemp b2 = newTemp(Ity_I32); 1694 IRTemp b6 = newTemp(Ity_I32); 1695 1696 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1))); 1697 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)), 1698 mkU32(1))); 1699 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)), 1700 mkU32(1))); 1701 1702 assign(cc0, mkexpr(b0)); 1703 assign(cc1, binop(Iop_Or32, mkexpr(b2), 1704 binop(Iop_And32, 1705 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */ 1706 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */ 1707 ))); 1708 1709 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1))); 1710 } 1711 1712 1713 /* The result of a Iop_CmpDxx operation is a condition code. It is 1714 encoded using the values defined in type IRCmpDxxResult. 1715 Before we can store the condition code into the guest state (or do 1716 anything else with it for that matter) we need to convert it to 1717 the encoding that s390 uses. This is what this function does. */ 1718 static IRExpr * 1719 convert_vex_dfpcc_to_s390(IRTemp vex_cc) 1720 { 1721 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the 1722 same. currently. */ 1723 return convert_vex_bfpcc_to_s390(vex_cc); 1724 } 1725 1726 1727 /*------------------------------------------------------------*/ 1728 /*--- Build IR for formats ---*/ 1729 /*------------------------------------------------------------*/ 1730 static void 1731 s390_format_I(const HChar *(*irgen)(UChar i), 1732 UChar i) 1733 { 1734 const HChar *mnm = irgen(i); 1735 1736 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1737 s390_disasm(ENC2(MNM, UINT), mnm, i); 1738 } 1739 1740 static void 1741 s390_format_E(const HChar *(*irgen)(void)) 1742 { 1743 const HChar *mnm = irgen(); 1744 1745 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1746 s390_disasm(ENC1(MNM), mnm); 1747 } 1748 1749 static void 1750 s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2), 1751 UChar r1, UShort i2) 1752 { 1753 irgen(r1, i2); 1754 } 1755 1756 static void 1757 s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2), 1758 UChar r1, UShort i2) 1759 { 1760 const HChar *mnm = irgen(r1, i2); 1761 1762 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1763 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2); 1764 } 1765 1766 static void 1767 s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2), 1768 UChar r1, UShort i2) 1769 { 1770 const HChar *mnm = irgen(r1, i2); 1771 1772 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1773 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2); 1774 } 1775 1776 static void 1777 s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2), 1778 UChar r1, UShort i2) 1779 { 1780 const HChar *mnm = irgen(r1, i2); 1781 1782 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1783 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2); 1784 } 1785 1786 static void 1787 s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2), 1788 UChar r1, UChar r3, UShort i2) 1789 { 1790 const HChar *mnm = irgen(r1, r3, i2); 1791 1792 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1793 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2); 1794 } 1795 1796 static void 1797 s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2), 1798 UChar r1, UChar r3, UShort i2) 1799 { 1800 const HChar *mnm = irgen(r1, r3, i2); 1801 1802 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1803 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2); 1804 } 1805 1806 static void 1807 s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3, 1808 UChar i4, UChar i5), 1809 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5) 1810 { 1811 const HChar *mnm = irgen(r1, r2, i3, i4, i5); 1812 1813 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1814 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4, 1815 i5); 1816 } 1817 1818 static void 1819 s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4, 1820 UChar m3), 1821 UChar r1, UChar r2, UShort i4, UChar m3) 1822 { 1823 const HChar *mnm = irgen(r1, r2, i4, m3); 1824 1825 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1826 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1, 1827 r2, m3, (Int)(Short)i4); 1828 } 1829 1830 static void 1831 s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4, 1832 UChar i2), 1833 UChar r1, UChar m3, UShort i4, UChar i2) 1834 { 1835 const HChar *mnm = irgen(r1, m3, i4, i2); 1836 1837 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1838 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, 1839 r1, i2, m3, (Int)(Short)i4); 1840 } 1841 1842 static void 1843 s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4, 1844 UChar i2), 1845 UChar r1, UChar m3, UShort i4, UChar i2) 1846 { 1847 const HChar *mnm = irgen(r1, m3, i4, i2); 1848 1849 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1850 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1, 1851 (Int)(Char)i2, m3, (Int)(Short)i4); 1852 } 1853 1854 static void 1855 s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2), 1856 UChar r1, UInt i2) 1857 { 1858 irgen(r1, i2); 1859 } 1860 1861 static void 1862 s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2), 1863 UChar r1, UInt i2) 1864 { 1865 const HChar *mnm = irgen(r1, i2); 1866 1867 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1868 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2); 1869 } 1870 1871 static void 1872 s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2), 1873 UChar r1, UInt i2) 1874 { 1875 const HChar *mnm = irgen(r1, i2); 1876 1877 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1878 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2); 1879 } 1880 1881 static void 1882 s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2), 1883 UChar r1, UInt i2) 1884 { 1885 const HChar *mnm = irgen(r1, i2); 1886 1887 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1888 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2); 1889 } 1890 1891 static void 1892 s390_format_RIL_UP(const HChar *(*irgen)(void), 1893 UChar r1, UInt i2) 1894 { 1895 const HChar *mnm = irgen(); 1896 1897 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1898 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2); 1899 } 1900 1901 static void 1902 s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2, 1903 IRTemp op4addr), 1904 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2) 1905 { 1906 const HChar *mnm; 1907 IRTemp op4addr = newTemp(Ity_I64); 1908 1909 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) : 1910 mkU64(0))); 1911 1912 mnm = irgen(r1, m3, i2, op4addr); 1913 1914 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1915 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1, 1916 (Int)(Char)i2, m3, d4, 0, b4); 1917 } 1918 1919 static void 1920 s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2, 1921 IRTemp op4addr), 1922 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2) 1923 { 1924 const HChar *mnm; 1925 IRTemp op4addr = newTemp(Ity_I64); 1926 1927 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) : 1928 mkU64(0))); 1929 1930 mnm = irgen(r1, m3, i2, op4addr); 1931 1932 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1933 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1, 1934 i2, m3, d4, 0, b4); 1935 } 1936 1937 static void 1938 s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2), 1939 UChar r1, UChar r2) 1940 { 1941 irgen(r1, r2); 1942 } 1943 1944 static void 1945 s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2), 1946 UChar r1, UChar r2) 1947 { 1948 const HChar *mnm = irgen(r1, r2); 1949 1950 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1951 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2); 1952 } 1953 1954 static void 1955 s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2), 1956 UChar r1, UChar r2) 1957 { 1958 const HChar *mnm = irgen(r1, r2); 1959 1960 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1961 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2); 1962 } 1963 1964 static void 1965 s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2), 1966 UChar r1, UChar r2) 1967 { 1968 irgen(r1, r2); 1969 } 1970 1971 static void 1972 s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2), 1973 UChar r1, UChar r2) 1974 { 1975 const HChar *mnm = irgen(r1, r2); 1976 1977 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1978 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2); 1979 } 1980 1981 static void 1982 s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2), 1983 UChar r1, UChar r2) 1984 { 1985 const HChar *mnm = irgen(r1, r2); 1986 1987 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1988 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2); 1989 } 1990 1991 static void 1992 s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar), 1993 UChar r1, UChar r2) 1994 { 1995 const HChar *mnm = irgen(r1, r2); 1996 1997 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 1998 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2); 1999 } 2000 2001 static void 2002 s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2), 2003 UChar r1, UChar r2) 2004 { 2005 const HChar *mnm = irgen(r1, r2); 2006 2007 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2008 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2); 2009 } 2010 2011 static void 2012 s390_format_RRE_R0(const HChar *(*irgen)(UChar r1), 2013 UChar r1) 2014 { 2015 const HChar *mnm = irgen(r1); 2016 2017 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2018 s390_disasm(ENC2(MNM, GPR), mnm, r1); 2019 } 2020 2021 static void 2022 s390_format_RRE_F0(const HChar *(*irgen)(UChar r1), 2023 UChar r1) 2024 { 2025 const HChar *mnm = irgen(r1); 2026 2027 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2028 s390_disasm(ENC2(MNM, FPR), mnm, r1); 2029 } 2030 2031 static void 2032 s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2), 2033 UChar m3, UChar r1, UChar r2) 2034 { 2035 const HChar *mnm = irgen(m3, r1, r2); 2036 2037 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2038 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3); 2039 } 2040 2041 static void 2042 s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar), 2043 UChar r1, UChar r3, UChar r2) 2044 { 2045 const HChar *mnm = irgen(r1, r3, r2); 2046 2047 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2048 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2); 2049 } 2050 2051 static void 2052 s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar), 2053 UChar r3, UChar r1, UChar r2) 2054 { 2055 const HChar *mnm = irgen(r3, r1, r2); 2056 2057 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2058 s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2); 2059 } 2060 2061 static void 2062 s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1, 2063 UChar r2), 2064 UChar m3, UChar m4, UChar r1, UChar r2) 2065 { 2066 const HChar *mnm = irgen(m3, m4, r1, r2); 2067 2068 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2069 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4); 2070 } 2071 2072 static void 2073 s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2), 2074 UChar m4, UChar r1, UChar r2) 2075 { 2076 const HChar *mnm = irgen(m4, r1, r2); 2077 2078 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2079 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4); 2080 } 2081 2082 static void 2083 s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1, 2084 UChar r2), 2085 UChar m3, UChar m4, UChar r1, UChar r2) 2086 { 2087 const HChar *mnm = irgen(m3, m4, r1, r2); 2088 2089 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2090 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4); 2091 } 2092 2093 static void 2094 s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1, 2095 UChar r2), 2096 UChar m3, UChar m4, UChar r1, UChar r2) 2097 { 2098 const HChar *mnm = irgen(m3, m4, r1, r2); 2099 2100 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2101 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4); 2102 } 2103 2104 2105 static void 2106 s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2), 2107 UChar m3, UChar r1, UChar r2, Int xmnm_kind) 2108 { 2109 irgen(m3, r1, r2); 2110 2111 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2112 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2); 2113 } 2114 2115 static void 2116 s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar), 2117 UChar r3, UChar r1, UChar r2) 2118 { 2119 const HChar *mnm = irgen(r3, r1, r2); 2120 2121 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2122 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2); 2123 } 2124 2125 static void 2126 s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar), 2127 UChar r3, UChar m4, UChar r1, UChar r2) 2128 { 2129 const HChar *mnm = irgen(r3, m4, r1, r2); 2130 2131 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2132 s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4); 2133 } 2134 2135 static void 2136 s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar), 2137 UChar r3, UChar m4, UChar r1, UChar r2) 2138 { 2139 const HChar *mnm = irgen(r3, m4, r1, r2); 2140 2141 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2142 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4); 2143 } 2144 2145 static void 2146 s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar), 2147 UChar r3, UChar m4, UChar r1, UChar r2) 2148 { 2149 const HChar *mnm = irgen(r3, m4, r1, r2); 2150 2151 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2152 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4); 2153 } 2154 2155 static void 2156 s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2), 2157 UChar r3, UChar r1, UChar r2) 2158 { 2159 const HChar *mnm = irgen(r3, r1, r2); 2160 2161 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2162 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3); 2163 } 2164 2165 static void 2166 s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3, 2167 IRTemp op4addr), 2168 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3) 2169 { 2170 const HChar *mnm; 2171 IRTemp op4addr = newTemp(Ity_I64); 2172 2173 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) : 2174 mkU64(0))); 2175 2176 mnm = irgen(r1, r2, m3, op4addr); 2177 2178 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2179 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1, 2180 r2, m3, d4, 0, b4); 2181 } 2182 2183 static void 2184 s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr), 2185 UChar r1, UChar b2, UShort d2) 2186 { 2187 const HChar *mnm; 2188 IRTemp op2addr = newTemp(Ity_I64); 2189 2190 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : 2191 mkU64(0))); 2192 2193 mnm = irgen(r1, op2addr); 2194 2195 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2196 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2); 2197 } 2198 2199 static void 2200 s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr), 2201 UChar r1, UChar r3, UChar b2, UShort d2) 2202 { 2203 const HChar *mnm; 2204 IRTemp op2addr = newTemp(Ity_I64); 2205 2206 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : 2207 mkU64(0))); 2208 2209 mnm = irgen(r1, r3, op2addr); 2210 2211 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2212 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2); 2213 } 2214 2215 static void 2216 s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr), 2217 UChar r1, UChar r3, UChar b2, UShort d2) 2218 { 2219 const HChar *mnm; 2220 IRTemp op2addr = newTemp(Ity_I64); 2221 2222 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : 2223 mkU64(0))); 2224 2225 mnm = irgen(r1, r3, op2addr); 2226 2227 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2228 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2); 2229 } 2230 2231 static void 2232 s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp), 2233 UChar r1, UChar r3, UChar b2, UShort d2) 2234 { 2235 const HChar *mnm; 2236 IRTemp op2addr = newTemp(Ity_I64); 2237 2238 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : 2239 mkU64(0))); 2240 2241 mnm = irgen(r1, r3, op2addr); 2242 2243 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2244 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2); 2245 } 2246 2247 static void 2248 s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2), 2249 UChar r1, UChar r3, UShort i2) 2250 { 2251 const HChar *mnm = irgen(r1, r3, i2); 2252 2253 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2254 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2); 2255 } 2256 2257 static void 2258 s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr), 2259 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) 2260 { 2261 const HChar *mnm; 2262 IRTemp op2addr = newTemp(Ity_I64); 2263 IRTemp d2 = newTemp(Ity_I64); 2264 2265 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); 2266 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) : 2267 mkU64(0))); 2268 2269 mnm = irgen(r1, r3, op2addr); 2270 2271 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2272 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2); 2273 } 2274 2275 static void 2276 s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp), 2277 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) 2278 { 2279 const HChar *mnm; 2280 IRTemp op2addr = newTemp(Ity_I64); 2281 IRTemp d2 = newTemp(Ity_I64); 2282 2283 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); 2284 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) : 2285 mkU64(0))); 2286 2287 mnm = irgen(r1, r3, op2addr); 2288 2289 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2290 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2); 2291 } 2292 2293 static void 2294 s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr), 2295 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2) 2296 { 2297 const HChar *mnm; 2298 IRTemp op2addr = newTemp(Ity_I64); 2299 IRTemp d2 = newTemp(Ity_I64); 2300 2301 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); 2302 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) : 2303 mkU64(0))); 2304 2305 mnm = irgen(r1, r3, op2addr); 2306 2307 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2308 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2); 2309 } 2310 2311 static void 2312 s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr), 2313 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2, 2314 Int xmnm_kind) 2315 { 2316 IRTemp op2addr = newTemp(Ity_I64); 2317 IRTemp d2 = newTemp(Ity_I64); 2318 2319 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0))); 2320 2321 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); 2322 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) : 2323 mkU64(0))); 2324 2325 irgen(r1, op2addr); 2326 2327 vassert(dis_res->whatNext == Dis_Continue); 2328 2329 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2330 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2); 2331 } 2332 2333 static void 2334 s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2, 2335 IRTemp op2addr), 2336 UChar r1, UChar x2, UChar b2, UShort d2) 2337 { 2338 IRTemp op2addr = newTemp(Ity_I64); 2339 2340 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), 2341 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : 2342 mkU64(0))); 2343 2344 irgen(r1, x2, b2, d2, op2addr); 2345 } 2346 2347 static void 2348 s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr), 2349 UChar r1, UChar x2, UChar b2, UShort d2) 2350 { 2351 const HChar *mnm; 2352 IRTemp op2addr = newTemp(Ity_I64); 2353 2354 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), 2355 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : 2356 mkU64(0))); 2357 2358 mnm = irgen(r1, op2addr); 2359 2360 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2361 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2); 2362 } 2363 2364 static void 2365 s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr), 2366 UChar r1, UChar x2, UChar b2, UShort d2) 2367 { 2368 const HChar *mnm; 2369 IRTemp op2addr = newTemp(Ity_I64); 2370 2371 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), 2372 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : 2373 mkU64(0))); 2374 2375 mnm = irgen(r1, op2addr); 2376 2377 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2378 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2); 2379 } 2380 2381 static void 2382 s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr), 2383 UChar r1, UChar x2, UChar b2, UShort d2) 2384 { 2385 const HChar *mnm; 2386 IRTemp op2addr = newTemp(Ity_I64); 2387 2388 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), 2389 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : 2390 mkU64(0))); 2391 2392 mnm = irgen(r1, op2addr); 2393 2394 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2395 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2); 2396 } 2397 2398 static void 2399 s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar), 2400 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1) 2401 { 2402 const HChar *mnm; 2403 IRTemp op2addr = newTemp(Ity_I64); 2404 2405 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2), 2406 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : 2407 mkU64(0))); 2408 2409 mnm = irgen(r3, op2addr, r1); 2410 2411 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2412 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2); 2413 } 2414 2415 static void 2416 s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr), 2417 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) 2418 { 2419 const HChar *mnm; 2420 IRTemp op2addr = newTemp(Ity_I64); 2421 IRTemp d2 = newTemp(Ity_I64); 2422 2423 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); 2424 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2), 2425 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : 2426 mkU64(0))); 2427 2428 mnm = irgen(r1, op2addr); 2429 2430 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2431 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2); 2432 } 2433 2434 static void 2435 s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr), 2436 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) 2437 { 2438 const HChar *mnm; 2439 IRTemp op2addr = newTemp(Ity_I64); 2440 IRTemp d2 = newTemp(Ity_I64); 2441 2442 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); 2443 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2), 2444 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : 2445 mkU64(0))); 2446 2447 mnm = irgen(r1, op2addr); 2448 2449 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2450 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2); 2451 } 2452 2453 static void 2454 s390_format_RXY_URRD(const HChar *(*irgen)(void), 2455 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) 2456 { 2457 const HChar *mnm; 2458 IRTemp op2addr = newTemp(Ity_I64); 2459 IRTemp d2 = newTemp(Ity_I64); 2460 2461 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2))); 2462 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2), 2463 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) : 2464 mkU64(0))); 2465 2466 mnm = irgen(); 2467 2468 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2469 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2); 2470 } 2471 2472 static void 2473 s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr), 2474 UChar b2, UShort d2) 2475 { 2476 const HChar *mnm; 2477 IRTemp op2addr = newTemp(Ity_I64); 2478 2479 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : 2480 mkU64(0))); 2481 2482 mnm = irgen(op2addr); 2483 2484 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2485 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2); 2486 } 2487 2488 static void 2489 s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr), 2490 UChar i2, UChar b1, UShort d1) 2491 { 2492 const HChar *mnm; 2493 IRTemp op1addr = newTemp(Ity_I64); 2494 2495 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) : 2496 mkU64(0))); 2497 2498 mnm = irgen(i2, op1addr); 2499 2500 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2501 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2); 2502 } 2503 2504 static void 2505 s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr), 2506 UChar i2, UChar b1, UShort dl1, UChar dh1) 2507 { 2508 const HChar *mnm; 2509 IRTemp op1addr = newTemp(Ity_I64); 2510 IRTemp d1 = newTemp(Ity_I64); 2511 2512 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1))); 2513 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) : 2514 mkU64(0))); 2515 2516 mnm = irgen(i2, op1addr); 2517 2518 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2519 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2); 2520 } 2521 2522 static void 2523 s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr), 2524 UChar i2, UChar b1, UShort dl1, UChar dh1) 2525 { 2526 const HChar *mnm; 2527 IRTemp op1addr = newTemp(Ity_I64); 2528 IRTemp d1 = newTemp(Ity_I64); 2529 2530 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1))); 2531 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) : 2532 mkU64(0))); 2533 2534 mnm = irgen(i2, op1addr); 2535 2536 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2537 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2); 2538 } 2539 2540 static void 2541 s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp), 2542 UChar l, UChar b1, UShort d1, UChar b2, UShort d2) 2543 { 2544 const HChar *mnm; 2545 IRTemp op1addr = newTemp(Ity_I64); 2546 IRTemp op2addr = newTemp(Ity_I64); 2547 2548 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) : 2549 mkU64(0))); 2550 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : 2551 mkU64(0))); 2552 2553 mnm = irgen(l, op1addr, op2addr); 2554 2555 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2556 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2); 2557 } 2558 2559 static void 2560 s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr), 2561 UChar b1, UShort d1, UShort i2) 2562 { 2563 const HChar *mnm; 2564 IRTemp op1addr = newTemp(Ity_I64); 2565 2566 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) : 2567 mkU64(0))); 2568 2569 mnm = irgen(i2, op1addr); 2570 2571 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2572 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2); 2573 } 2574 2575 static void 2576 s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr), 2577 UChar b1, UShort d1, UShort i2) 2578 { 2579 const HChar *mnm; 2580 IRTemp op1addr = newTemp(Ity_I64); 2581 2582 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) : 2583 mkU64(0))); 2584 2585 mnm = irgen(i2, op1addr); 2586 2587 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 2588 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2); 2589 } 2590 2591 2592 2593 /*------------------------------------------------------------*/ 2594 /*--- Build IR for opcodes ---*/ 2595 /*------------------------------------------------------------*/ 2596 2597 static const HChar * 2598 s390_irgen_AR(UChar r1, UChar r2) 2599 { 2600 IRTemp op1 = newTemp(Ity_I32); 2601 IRTemp op2 = newTemp(Ity_I32); 2602 IRTemp result = newTemp(Ity_I32); 2603 2604 assign(op1, get_gpr_w1(r1)); 2605 assign(op2, get_gpr_w1(r2)); 2606 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); 2607 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2); 2608 put_gpr_w1(r1, mkexpr(result)); 2609 2610 return "ar"; 2611 } 2612 2613 static const HChar * 2614 s390_irgen_AGR(UChar r1, UChar r2) 2615 { 2616 IRTemp op1 = newTemp(Ity_I64); 2617 IRTemp op2 = newTemp(Ity_I64); 2618 IRTemp result = newTemp(Ity_I64); 2619 2620 assign(op1, get_gpr_dw0(r1)); 2621 assign(op2, get_gpr_dw0(r2)); 2622 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); 2623 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2); 2624 put_gpr_dw0(r1, mkexpr(result)); 2625 2626 return "agr"; 2627 } 2628 2629 static const HChar * 2630 s390_irgen_AGFR(UChar r1, UChar r2) 2631 { 2632 IRTemp op1 = newTemp(Ity_I64); 2633 IRTemp op2 = newTemp(Ity_I64); 2634 IRTemp result = newTemp(Ity_I64); 2635 2636 assign(op1, get_gpr_dw0(r1)); 2637 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2))); 2638 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); 2639 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2); 2640 put_gpr_dw0(r1, mkexpr(result)); 2641 2642 return "agfr"; 2643 } 2644 2645 static const HChar * 2646 s390_irgen_ARK(UChar r3, UChar r1, UChar r2) 2647 { 2648 IRTemp op2 = newTemp(Ity_I32); 2649 IRTemp op3 = newTemp(Ity_I32); 2650 IRTemp result = newTemp(Ity_I32); 2651 2652 assign(op2, get_gpr_w1(r2)); 2653 assign(op3, get_gpr_w1(r3)); 2654 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3))); 2655 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3); 2656 put_gpr_w1(r1, mkexpr(result)); 2657 2658 return "ark"; 2659 } 2660 2661 static const HChar * 2662 s390_irgen_AGRK(UChar r3, UChar r1, UChar r2) 2663 { 2664 IRTemp op2 = newTemp(Ity_I64); 2665 IRTemp op3 = newTemp(Ity_I64); 2666 IRTemp result = newTemp(Ity_I64); 2667 2668 assign(op2, get_gpr_dw0(r2)); 2669 assign(op3, get_gpr_dw0(r3)); 2670 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3))); 2671 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3); 2672 put_gpr_dw0(r1, mkexpr(result)); 2673 2674 return "agrk"; 2675 } 2676 2677 static const HChar * 2678 s390_irgen_A(UChar r1, IRTemp op2addr) 2679 { 2680 IRTemp op1 = newTemp(Ity_I32); 2681 IRTemp op2 = newTemp(Ity_I32); 2682 IRTemp result = newTemp(Ity_I32); 2683 2684 assign(op1, get_gpr_w1(r1)); 2685 assign(op2, load(Ity_I32, mkexpr(op2addr))); 2686 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); 2687 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2); 2688 put_gpr_w1(r1, mkexpr(result)); 2689 2690 return "a"; 2691 } 2692 2693 static const HChar * 2694 s390_irgen_AY(UChar r1, IRTemp op2addr) 2695 { 2696 IRTemp op1 = newTemp(Ity_I32); 2697 IRTemp op2 = newTemp(Ity_I32); 2698 IRTemp result = newTemp(Ity_I32); 2699 2700 assign(op1, get_gpr_w1(r1)); 2701 assign(op2, load(Ity_I32, mkexpr(op2addr))); 2702 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); 2703 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2); 2704 put_gpr_w1(r1, mkexpr(result)); 2705 2706 return "ay"; 2707 } 2708 2709 static const HChar * 2710 s390_irgen_AG(UChar r1, IRTemp op2addr) 2711 { 2712 IRTemp op1 = newTemp(Ity_I64); 2713 IRTemp op2 = newTemp(Ity_I64); 2714 IRTemp result = newTemp(Ity_I64); 2715 2716 assign(op1, get_gpr_dw0(r1)); 2717 assign(op2, load(Ity_I64, mkexpr(op2addr))); 2718 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); 2719 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2); 2720 put_gpr_dw0(r1, mkexpr(result)); 2721 2722 return "ag"; 2723 } 2724 2725 static const HChar * 2726 s390_irgen_AGF(UChar r1, IRTemp op2addr) 2727 { 2728 IRTemp op1 = newTemp(Ity_I64); 2729 IRTemp op2 = newTemp(Ity_I64); 2730 IRTemp result = newTemp(Ity_I64); 2731 2732 assign(op1, get_gpr_dw0(r1)); 2733 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr)))); 2734 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); 2735 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2); 2736 put_gpr_dw0(r1, mkexpr(result)); 2737 2738 return "agf"; 2739 } 2740 2741 static const HChar * 2742 s390_irgen_AFI(UChar r1, UInt i2) 2743 { 2744 IRTemp op1 = newTemp(Ity_I32); 2745 Int op2; 2746 IRTemp result = newTemp(Ity_I32); 2747 2748 assign(op1, get_gpr_w1(r1)); 2749 op2 = (Int)i2; 2750 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2))); 2751 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32, 2752 mkU32((UInt)op2))); 2753 put_gpr_w1(r1, mkexpr(result)); 2754 2755 return "afi"; 2756 } 2757 2758 static const HChar * 2759 s390_irgen_AGFI(UChar r1, UInt i2) 2760 { 2761 IRTemp op1 = newTemp(Ity_I64); 2762 Long op2; 2763 IRTemp result = newTemp(Ity_I64); 2764 2765 assign(op1, get_gpr_dw0(r1)); 2766 op2 = (Long)(Int)i2; 2767 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2))); 2768 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64, 2769 mkU64((ULong)op2))); 2770 put_gpr_dw0(r1, mkexpr(result)); 2771 2772 return "agfi"; 2773 } 2774 2775 static const HChar * 2776 s390_irgen_AHIK(UChar r1, UChar r3, UShort i2) 2777 { 2778 Int op2; 2779 IRTemp op3 = newTemp(Ity_I32); 2780 IRTemp result = newTemp(Ity_I32); 2781 2782 op2 = (Int)(Short)i2; 2783 assign(op3, get_gpr_w1(r3)); 2784 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3))); 2785 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt) 2786 op2)), op3); 2787 put_gpr_w1(r1, mkexpr(result)); 2788 2789 return "ahik"; 2790 } 2791 2792 static const HChar * 2793 s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2) 2794 { 2795 Long op2; 2796 IRTemp op3 = newTemp(Ity_I64); 2797 IRTemp result = newTemp(Ity_I64); 2798 2799 op2 = (Long)(Short)i2; 2800 assign(op3, get_gpr_dw0(r3)); 2801 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3))); 2802 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong) 2803 op2)), op3); 2804 put_gpr_dw0(r1, mkexpr(result)); 2805 2806 return "aghik"; 2807 } 2808 2809 static const HChar * 2810 s390_irgen_ASI(UChar i2, IRTemp op1addr) 2811 { 2812 IRTemp op1 = newTemp(Ity_I32); 2813 Int op2; 2814 IRTemp result = newTemp(Ity_I32); 2815 2816 assign(op1, load(Ity_I32, mkexpr(op1addr))); 2817 op2 = (Int)(Char)i2; 2818 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2))); 2819 store(mkexpr(op1addr), mkexpr(result)); 2820 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32, 2821 mkU32((UInt)op2))); 2822 2823 return "asi"; 2824 } 2825 2826 static const HChar * 2827 s390_irgen_AGSI(UChar i2, IRTemp op1addr) 2828 { 2829 IRTemp op1 = newTemp(Ity_I64); 2830 Long op2; 2831 IRTemp result = newTemp(Ity_I64); 2832 2833 assign(op1, load(Ity_I64, mkexpr(op1addr))); 2834 op2 = (Long)(Char)i2; 2835 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2))); 2836 store(mkexpr(op1addr), mkexpr(result)); 2837 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64, 2838 mkU64((ULong)op2))); 2839 2840 return "agsi"; 2841 } 2842 2843 static const HChar * 2844 s390_irgen_AH(UChar r1, IRTemp op2addr) 2845 { 2846 IRTemp op1 = newTemp(Ity_I32); 2847 IRTemp op2 = newTemp(Ity_I32); 2848 IRTemp result = newTemp(Ity_I32); 2849 2850 assign(op1, get_gpr_w1(r1)); 2851 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr)))); 2852 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); 2853 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2); 2854 put_gpr_w1(r1, mkexpr(result)); 2855 2856 return "ah"; 2857 } 2858 2859 static const HChar * 2860 s390_irgen_AHY(UChar r1, IRTemp op2addr) 2861 { 2862 IRTemp op1 = newTemp(Ity_I32); 2863 IRTemp op2 = newTemp(Ity_I32); 2864 IRTemp result = newTemp(Ity_I32); 2865 2866 assign(op1, get_gpr_w1(r1)); 2867 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr)))); 2868 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); 2869 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2); 2870 put_gpr_w1(r1, mkexpr(result)); 2871 2872 return "ahy"; 2873 } 2874 2875 static const HChar * 2876 s390_irgen_AHI(UChar r1, UShort i2) 2877 { 2878 IRTemp op1 = newTemp(Ity_I32); 2879 Int op2; 2880 IRTemp result = newTemp(Ity_I32); 2881 2882 assign(op1, get_gpr_w1(r1)); 2883 op2 = (Int)(Short)i2; 2884 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2))); 2885 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32, 2886 mkU32((UInt)op2))); 2887 put_gpr_w1(r1, mkexpr(result)); 2888 2889 return "ahi"; 2890 } 2891 2892 static const HChar * 2893 s390_irgen_AGHI(UChar r1, UShort i2) 2894 { 2895 IRTemp op1 = newTemp(Ity_I64); 2896 Long op2; 2897 IRTemp result = newTemp(Ity_I64); 2898 2899 assign(op1, get_gpr_dw0(r1)); 2900 op2 = (Long)(Short)i2; 2901 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2))); 2902 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64, 2903 mkU64((ULong)op2))); 2904 put_gpr_dw0(r1, mkexpr(result)); 2905 2906 return "aghi"; 2907 } 2908 2909 static const HChar * 2910 s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2) 2911 { 2912 IRTemp op2 = newTemp(Ity_I32); 2913 IRTemp op3 = newTemp(Ity_I32); 2914 IRTemp result = newTemp(Ity_I32); 2915 2916 assign(op2, get_gpr_w0(r2)); 2917 assign(op3, get_gpr_w0(r3)); 2918 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3))); 2919 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3); 2920 put_gpr_w0(r1, mkexpr(result)); 2921 2922 return "ahhhr"; 2923 } 2924 2925 static const HChar * 2926 s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2) 2927 { 2928 IRTemp op2 = newTemp(Ity_I32); 2929 IRTemp op3 = newTemp(Ity_I32); 2930 IRTemp result = newTemp(Ity_I32); 2931 2932 assign(op2, get_gpr_w0(r2)); 2933 assign(op3, get_gpr_w1(r3)); 2934 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3))); 2935 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3); 2936 put_gpr_w0(r1, mkexpr(result)); 2937 2938 return "ahhlr"; 2939 } 2940 2941 static const HChar * 2942 s390_irgen_AIH(UChar r1, UInt i2) 2943 { 2944 IRTemp op1 = newTemp(Ity_I32); 2945 Int op2; 2946 IRTemp result = newTemp(Ity_I32); 2947 2948 assign(op1, get_gpr_w0(r1)); 2949 op2 = (Int)i2; 2950 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2))); 2951 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32, 2952 mkU32((UInt)op2))); 2953 put_gpr_w0(r1, mkexpr(result)); 2954 2955 return "aih"; 2956 } 2957 2958 static const HChar * 2959 s390_irgen_ALR(UChar r1, UChar r2) 2960 { 2961 IRTemp op1 = newTemp(Ity_I32); 2962 IRTemp op2 = newTemp(Ity_I32); 2963 IRTemp result = newTemp(Ity_I32); 2964 2965 assign(op1, get_gpr_w1(r1)); 2966 assign(op2, get_gpr_w1(r2)); 2967 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); 2968 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2); 2969 put_gpr_w1(r1, mkexpr(result)); 2970 2971 return "alr"; 2972 } 2973 2974 static const HChar * 2975 s390_irgen_ALGR(UChar r1, UChar r2) 2976 { 2977 IRTemp op1 = newTemp(Ity_I64); 2978 IRTemp op2 = newTemp(Ity_I64); 2979 IRTemp result = newTemp(Ity_I64); 2980 2981 assign(op1, get_gpr_dw0(r1)); 2982 assign(op2, get_gpr_dw0(r2)); 2983 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); 2984 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2); 2985 put_gpr_dw0(r1, mkexpr(result)); 2986 2987 return "algr"; 2988 } 2989 2990 static const HChar * 2991 s390_irgen_ALGFR(UChar r1, UChar r2) 2992 { 2993 IRTemp op1 = newTemp(Ity_I64); 2994 IRTemp op2 = newTemp(Ity_I64); 2995 IRTemp result = newTemp(Ity_I64); 2996 2997 assign(op1, get_gpr_dw0(r1)); 2998 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2))); 2999 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); 3000 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2); 3001 put_gpr_dw0(r1, mkexpr(result)); 3002 3003 return "algfr"; 3004 } 3005 3006 static const HChar * 3007 s390_irgen_ALRK(UChar r3, UChar r1, UChar r2) 3008 { 3009 IRTemp op2 = newTemp(Ity_I32); 3010 IRTemp op3 = newTemp(Ity_I32); 3011 IRTemp result = newTemp(Ity_I32); 3012 3013 assign(op2, get_gpr_w1(r2)); 3014 assign(op3, get_gpr_w1(r3)); 3015 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3))); 3016 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3); 3017 put_gpr_w1(r1, mkexpr(result)); 3018 3019 return "alrk"; 3020 } 3021 3022 static const HChar * 3023 s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2) 3024 { 3025 IRTemp op2 = newTemp(Ity_I64); 3026 IRTemp op3 = newTemp(Ity_I64); 3027 IRTemp result = newTemp(Ity_I64); 3028 3029 assign(op2, get_gpr_dw0(r2)); 3030 assign(op3, get_gpr_dw0(r3)); 3031 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3))); 3032 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3); 3033 put_gpr_dw0(r1, mkexpr(result)); 3034 3035 return "algrk"; 3036 } 3037 3038 static const HChar * 3039 s390_irgen_AL(UChar r1, IRTemp op2addr) 3040 { 3041 IRTemp op1 = newTemp(Ity_I32); 3042 IRTemp op2 = newTemp(Ity_I32); 3043 IRTemp result = newTemp(Ity_I32); 3044 3045 assign(op1, get_gpr_w1(r1)); 3046 assign(op2, load(Ity_I32, mkexpr(op2addr))); 3047 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); 3048 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2); 3049 put_gpr_w1(r1, mkexpr(result)); 3050 3051 return "al"; 3052 } 3053 3054 static const HChar * 3055 s390_irgen_ALY(UChar r1, IRTemp op2addr) 3056 { 3057 IRTemp op1 = newTemp(Ity_I32); 3058 IRTemp op2 = newTemp(Ity_I32); 3059 IRTemp result = newTemp(Ity_I32); 3060 3061 assign(op1, get_gpr_w1(r1)); 3062 assign(op2, load(Ity_I32, mkexpr(op2addr))); 3063 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2))); 3064 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2); 3065 put_gpr_w1(r1, mkexpr(result)); 3066 3067 return "aly"; 3068 } 3069 3070 static const HChar * 3071 s390_irgen_ALG(UChar r1, IRTemp op2addr) 3072 { 3073 IRTemp op1 = newTemp(Ity_I64); 3074 IRTemp op2 = newTemp(Ity_I64); 3075 IRTemp result = newTemp(Ity_I64); 3076 3077 assign(op1, get_gpr_dw0(r1)); 3078 assign(op2, load(Ity_I64, mkexpr(op2addr))); 3079 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); 3080 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2); 3081 put_gpr_dw0(r1, mkexpr(result)); 3082 3083 return "alg"; 3084 } 3085 3086 static const HChar * 3087 s390_irgen_ALGF(UChar r1, IRTemp op2addr) 3088 { 3089 IRTemp op1 = newTemp(Ity_I64); 3090 IRTemp op2 = newTemp(Ity_I64); 3091 IRTemp result = newTemp(Ity_I64); 3092 3093 assign(op1, get_gpr_dw0(r1)); 3094 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr)))); 3095 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); 3096 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2); 3097 put_gpr_dw0(r1, mkexpr(result)); 3098 3099 return "algf"; 3100 } 3101 3102 static const HChar * 3103 s390_irgen_ALFI(UChar r1, UInt i2) 3104 { 3105 IRTemp op1 = newTemp(Ity_I32); 3106 UInt op2; 3107 IRTemp result = newTemp(Ity_I32); 3108 3109 assign(op1, get_gpr_w1(r1)); 3110 op2 = i2; 3111 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2))); 3112 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32, 3113 mkU32(op2))); 3114 put_gpr_w1(r1, mkexpr(result)); 3115 3116 return "alfi"; 3117 } 3118 3119 static const HChar * 3120 s390_irgen_ALGFI(UChar r1, UInt i2) 3121 { 3122 IRTemp op1 = newTemp(Ity_I64); 3123 ULong op2; 3124 IRTemp result = newTemp(Ity_I64); 3125 3126 assign(op1, get_gpr_dw0(r1)); 3127 op2 = (ULong)i2; 3128 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2))); 3129 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64, 3130 mkU64(op2))); 3131 put_gpr_dw0(r1, mkexpr(result)); 3132 3133 return "algfi"; 3134 } 3135 3136 static const HChar * 3137 s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2) 3138 { 3139 IRTemp op2 = newTemp(Ity_I32); 3140 IRTemp op3 = newTemp(Ity_I32); 3141 IRTemp result = newTemp(Ity_I32); 3142 3143 assign(op2, get_gpr_w0(r2)); 3144 assign(op3, get_gpr_w0(r3)); 3145 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3))); 3146 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3); 3147 put_gpr_w0(r1, mkexpr(result)); 3148 3149 return "alhhhr"; 3150 } 3151 3152 static const HChar * 3153 s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2) 3154 { 3155 IRTemp op2 = newTemp(Ity_I32); 3156 IRTemp op3 = newTemp(Ity_I32); 3157 IRTemp result = newTemp(Ity_I32); 3158 3159 assign(op2, get_gpr_w0(r2)); 3160 assign(op3, get_gpr_w1(r3)); 3161 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3))); 3162 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3); 3163 put_gpr_w0(r1, mkexpr(result)); 3164 3165 return "alhhlr"; 3166 } 3167 3168 static const HChar * 3169 s390_irgen_ALCR(UChar r1, UChar r2) 3170 { 3171 IRTemp op1 = newTemp(Ity_I32); 3172 IRTemp op2 = newTemp(Ity_I32); 3173 IRTemp result = newTemp(Ity_I32); 3174 IRTemp carry_in = newTemp(Ity_I32); 3175 3176 assign(op1, get_gpr_w1(r1)); 3177 assign(op2, get_gpr_w1(r2)); 3178 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1))); 3179 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)), 3180 mkexpr(carry_in))); 3181 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in); 3182 put_gpr_w1(r1, mkexpr(result)); 3183 3184 return "alcr"; 3185 } 3186 3187 static const HChar * 3188 s390_irgen_ALCGR(UChar r1, UChar r2) 3189 { 3190 IRTemp op1 = newTemp(Ity_I64); 3191 IRTemp op2 = newTemp(Ity_I64); 3192 IRTemp result = newTemp(Ity_I64); 3193 IRTemp carry_in = newTemp(Ity_I64); 3194 3195 assign(op1, get_gpr_dw0(r1)); 3196 assign(op2, get_gpr_dw0(r2)); 3197 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(), 3198 mkU8(1)))); 3199 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)), 3200 mkexpr(carry_in))); 3201 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in); 3202 put_gpr_dw0(r1, mkexpr(result)); 3203 3204 return "alcgr"; 3205 } 3206 3207 static const HChar * 3208 s390_irgen_ALC(UChar r1, IRTemp op2addr) 3209 { 3210 IRTemp op1 = newTemp(Ity_I32); 3211 IRTemp op2 = newTemp(Ity_I32); 3212 IRTemp result = newTemp(Ity_I32); 3213 IRTemp carry_in = newTemp(Ity_I32); 3214 3215 assign(op1, get_gpr_w1(r1)); 3216 assign(op2, load(Ity_I32, mkexpr(op2addr))); 3217 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1))); 3218 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)), 3219 mkexpr(carry_in))); 3220 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in); 3221 put_gpr_w1(r1, mkexpr(result)); 3222 3223 return "alc"; 3224 } 3225 3226 static const HChar * 3227 s390_irgen_ALCG(UChar r1, IRTemp op2addr) 3228 { 3229 IRTemp op1 = newTemp(Ity_I64); 3230 IRTemp op2 = newTemp(Ity_I64); 3231 IRTemp result = newTemp(Ity_I64); 3232 IRTemp carry_in = newTemp(Ity_I64); 3233 3234 assign(op1, get_gpr_dw0(r1)); 3235 assign(op2, load(Ity_I64, mkexpr(op2addr))); 3236 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(), 3237 mkU8(1)))); 3238 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)), 3239 mkexpr(carry_in))); 3240 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in); 3241 put_gpr_dw0(r1, mkexpr(result)); 3242 3243 return "alcg"; 3244 } 3245 3246 static const HChar * 3247 s390_irgen_ALSI(UChar i2, IRTemp op1addr) 3248 { 3249 IRTemp op1 = newTemp(Ity_I32); 3250 UInt op2; 3251 IRTemp result = newTemp(Ity_I32); 3252 3253 assign(op1, load(Ity_I32, mkexpr(op1addr))); 3254 op2 = (UInt)(Int)(Char)i2; 3255 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2))); 3256 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32, 3257 mkU32(op2))); 3258 store(mkexpr(op1addr), mkexpr(result)); 3259 3260 return "alsi"; 3261 } 3262 3263 static const HChar * 3264 s390_irgen_ALGSI(UChar i2, IRTemp op1addr) 3265 { 3266 IRTemp op1 = newTemp(Ity_I64); 3267 ULong op2; 3268 IRTemp result = newTemp(Ity_I64); 3269 3270 assign(op1, load(Ity_I64, mkexpr(op1addr))); 3271 op2 = (ULong)(Long)(Char)i2; 3272 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2))); 3273 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64, 3274 mkU64(op2))); 3275 store(mkexpr(op1addr), mkexpr(result)); 3276 3277 return "algsi"; 3278 } 3279 3280 static const HChar * 3281 s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2) 3282 { 3283 UInt op2; 3284 IRTemp op3 = newTemp(Ity_I32); 3285 IRTemp result = newTemp(Ity_I32); 3286 3287 op2 = (UInt)(Int)(Short)i2; 3288 assign(op3, get_gpr_w1(r3)); 3289 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3))); 3290 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)), 3291 op3); 3292 put_gpr_w1(r1, mkexpr(result)); 3293 3294 return "alhsik"; 3295 } 3296 3297 static const HChar * 3298 s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2) 3299 { 3300 ULong op2; 3301 IRTemp op3 = newTemp(Ity_I64); 3302 IRTemp result = newTemp(Ity_I64); 3303 3304 op2 = (ULong)(Long)(Short)i2; 3305 assign(op3, get_gpr_dw0(r3)); 3306 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3))); 3307 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)), 3308 op3); 3309 put_gpr_dw0(r1, mkexpr(result)); 3310 3311 return "alghsik"; 3312 } 3313 3314 static const HChar * 3315 s390_irgen_ALSIH(UChar r1, UInt i2) 3316 { 3317 IRTemp op1 = newTemp(Ity_I32); 3318 UInt op2; 3319 IRTemp result = newTemp(Ity_I32); 3320 3321 assign(op1, get_gpr_w0(r1)); 3322 op2 = i2; 3323 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2))); 3324 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32, 3325 mkU32(op2))); 3326 put_gpr_w0(r1, mkexpr(result)); 3327 3328 return "alsih"; 3329 } 3330 3331 static const HChar * 3332 s390_irgen_ALSIHN(UChar r1, UInt i2) 3333 { 3334 IRTemp op1 = newTemp(Ity_I32); 3335 UInt op2; 3336 IRTemp result = newTemp(Ity_I32); 3337 3338 assign(op1, get_gpr_w0(r1)); 3339 op2 = i2; 3340 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2))); 3341 put_gpr_w0(r1, mkexpr(result)); 3342 3343 return "alsihn"; 3344 } 3345 3346 static const HChar * 3347 s390_irgen_NR(UChar r1, UChar r2) 3348 { 3349 IRTemp op1 = newTemp(Ity_I32); 3350 IRTemp op2 = newTemp(Ity_I32); 3351 IRTemp result = newTemp(Ity_I32); 3352 3353 assign(op1, get_gpr_w1(r1)); 3354 assign(op2, get_gpr_w1(r2)); 3355 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2))); 3356 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3357 put_gpr_w1(r1, mkexpr(result)); 3358 3359 return "nr"; 3360 } 3361 3362 static const HChar * 3363 s390_irgen_NGR(UChar r1, UChar r2) 3364 { 3365 IRTemp op1 = newTemp(Ity_I64); 3366 IRTemp op2 = newTemp(Ity_I64); 3367 IRTemp result = newTemp(Ity_I64); 3368 3369 assign(op1, get_gpr_dw0(r1)); 3370 assign(op2, get_gpr_dw0(r2)); 3371 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2))); 3372 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3373 put_gpr_dw0(r1, mkexpr(result)); 3374 3375 return "ngr"; 3376 } 3377 3378 static const HChar * 3379 s390_irgen_NRK(UChar r3, UChar r1, UChar r2) 3380 { 3381 IRTemp op2 = newTemp(Ity_I32); 3382 IRTemp op3 = newTemp(Ity_I32); 3383 IRTemp result = newTemp(Ity_I32); 3384 3385 assign(op2, get_gpr_w1(r2)); 3386 assign(op3, get_gpr_w1(r3)); 3387 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3))); 3388 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3389 put_gpr_w1(r1, mkexpr(result)); 3390 3391 return "nrk"; 3392 } 3393 3394 static const HChar * 3395 s390_irgen_NGRK(UChar r3, UChar r1, UChar r2) 3396 { 3397 IRTemp op2 = newTemp(Ity_I64); 3398 IRTemp op3 = newTemp(Ity_I64); 3399 IRTemp result = newTemp(Ity_I64); 3400 3401 assign(op2, get_gpr_dw0(r2)); 3402 assign(op3, get_gpr_dw0(r3)); 3403 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3))); 3404 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3405 put_gpr_dw0(r1, mkexpr(result)); 3406 3407 return "ngrk"; 3408 } 3409 3410 static const HChar * 3411 s390_irgen_N(UChar r1, IRTemp op2addr) 3412 { 3413 IRTemp op1 = newTemp(Ity_I32); 3414 IRTemp op2 = newTemp(Ity_I32); 3415 IRTemp result = newTemp(Ity_I32); 3416 3417 assign(op1, get_gpr_w1(r1)); 3418 assign(op2, load(Ity_I32, mkexpr(op2addr))); 3419 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2))); 3420 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3421 put_gpr_w1(r1, mkexpr(result)); 3422 3423 return "n"; 3424 } 3425 3426 static const HChar * 3427 s390_irgen_NY(UChar r1, IRTemp op2addr) 3428 { 3429 IRTemp op1 = newTemp(Ity_I32); 3430 IRTemp op2 = newTemp(Ity_I32); 3431 IRTemp result = newTemp(Ity_I32); 3432 3433 assign(op1, get_gpr_w1(r1)); 3434 assign(op2, load(Ity_I32, mkexpr(op2addr))); 3435 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2))); 3436 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3437 put_gpr_w1(r1, mkexpr(result)); 3438 3439 return "ny"; 3440 } 3441 3442 static const HChar * 3443 s390_irgen_NG(UChar r1, IRTemp op2addr) 3444 { 3445 IRTemp op1 = newTemp(Ity_I64); 3446 IRTemp op2 = newTemp(Ity_I64); 3447 IRTemp result = newTemp(Ity_I64); 3448 3449 assign(op1, get_gpr_dw0(r1)); 3450 assign(op2, load(Ity_I64, mkexpr(op2addr))); 3451 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2))); 3452 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3453 put_gpr_dw0(r1, mkexpr(result)); 3454 3455 return "ng"; 3456 } 3457 3458 static const HChar * 3459 s390_irgen_NI(UChar i2, IRTemp op1addr) 3460 { 3461 IRTemp op1 = newTemp(Ity_I8); 3462 UChar op2; 3463 IRTemp result = newTemp(Ity_I8); 3464 3465 assign(op1, load(Ity_I8, mkexpr(op1addr))); 3466 op2 = i2; 3467 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2))); 3468 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3469 store(mkexpr(op1addr), mkexpr(result)); 3470 3471 return "ni"; 3472 } 3473 3474 static const HChar * 3475 s390_irgen_NIY(UChar i2, IRTemp op1addr) 3476 { 3477 IRTemp op1 = newTemp(Ity_I8); 3478 UChar op2; 3479 IRTemp result = newTemp(Ity_I8); 3480 3481 assign(op1, load(Ity_I8, mkexpr(op1addr))); 3482 op2 = i2; 3483 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2))); 3484 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3485 store(mkexpr(op1addr), mkexpr(result)); 3486 3487 return "niy"; 3488 } 3489 3490 static const HChar * 3491 s390_irgen_NIHF(UChar r1, UInt i2) 3492 { 3493 IRTemp op1 = newTemp(Ity_I32); 3494 UInt op2; 3495 IRTemp result = newTemp(Ity_I32); 3496 3497 assign(op1, get_gpr_w0(r1)); 3498 op2 = i2; 3499 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2))); 3500 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3501 put_gpr_w0(r1, mkexpr(result)); 3502 3503 return "nihf"; 3504 } 3505 3506 static const HChar * 3507 s390_irgen_NIHH(UChar r1, UShort i2) 3508 { 3509 IRTemp op1 = newTemp(Ity_I16); 3510 UShort op2; 3511 IRTemp result = newTemp(Ity_I16); 3512 3513 assign(op1, get_gpr_hw0(r1)); 3514 op2 = i2; 3515 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2))); 3516 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3517 put_gpr_hw0(r1, mkexpr(result)); 3518 3519 return "nihh"; 3520 } 3521 3522 static const HChar * 3523 s390_irgen_NIHL(UChar r1, UShort i2) 3524 { 3525 IRTemp op1 = newTemp(Ity_I16); 3526 UShort op2; 3527 IRTemp result = newTemp(Ity_I16); 3528 3529 assign(op1, get_gpr_hw1(r1)); 3530 op2 = i2; 3531 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2))); 3532 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3533 put_gpr_hw1(r1, mkexpr(result)); 3534 3535 return "nihl"; 3536 } 3537 3538 static const HChar * 3539 s390_irgen_NILF(UChar r1, UInt i2) 3540 { 3541 IRTemp op1 = newTemp(Ity_I32); 3542 UInt op2; 3543 IRTemp result = newTemp(Ity_I32); 3544 3545 assign(op1, get_gpr_w1(r1)); 3546 op2 = i2; 3547 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2))); 3548 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3549 put_gpr_w1(r1, mkexpr(result)); 3550 3551 return "nilf"; 3552 } 3553 3554 static const HChar * 3555 s390_irgen_NILH(UChar r1, UShort i2) 3556 { 3557 IRTemp op1 = newTemp(Ity_I16); 3558 UShort op2; 3559 IRTemp result = newTemp(Ity_I16); 3560 3561 assign(op1, get_gpr_hw2(r1)); 3562 op2 = i2; 3563 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2))); 3564 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3565 put_gpr_hw2(r1, mkexpr(result)); 3566 3567 return "nilh"; 3568 } 3569 3570 static const HChar * 3571 s390_irgen_NILL(UChar r1, UShort i2) 3572 { 3573 IRTemp op1 = newTemp(Ity_I16); 3574 UShort op2; 3575 IRTemp result = newTemp(Ity_I16); 3576 3577 assign(op1, get_gpr_hw3(r1)); 3578 op2 = i2; 3579 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2))); 3580 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 3581 put_gpr_hw3(r1, mkexpr(result)); 3582 3583 return "nill"; 3584 } 3585 3586 static const HChar * 3587 s390_irgen_BASR(UChar r1, UChar r2) 3588 { 3589 IRTemp target = newTemp(Ity_I64); 3590 3591 if (r2 == 0) { 3592 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL)); 3593 } else { 3594 if (r1 != r2) { 3595 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL)); 3596 call_function(get_gpr_dw0(r2)); 3597 } else { 3598 assign(target, get_gpr_dw0(r2)); 3599 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL)); 3600 call_function(mkexpr(target)); 3601 } 3602 } 3603 3604 return "basr"; 3605 } 3606 3607 static const HChar * 3608 s390_irgen_BAS(UChar r1, IRTemp op2addr) 3609 { 3610 IRTemp target = newTemp(Ity_I64); 3611 3612 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL)); 3613 assign(target, mkexpr(op2addr)); 3614 call_function(mkexpr(target)); 3615 3616 return "bas"; 3617 } 3618 3619 static const HChar * 3620 s390_irgen_BCR(UChar r1, UChar r2) 3621 { 3622 IRTemp cond = newTemp(Ity_I32); 3623 3624 if (r2 == 0 && (r1 >= 14)) { /* serialization */ 3625 stmt(IRStmt_MBE(Imbe_Fence)); 3626 } 3627 3628 if ((r2 == 0) || (r1 == 0)) { 3629 } else { 3630 if (r1 == 15) { 3631 return_from_function(get_gpr_dw0(r2)); 3632 } else { 3633 assign(cond, s390_call_calculate_cond(r1)); 3634 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 3635 get_gpr_dw0(r2)); 3636 } 3637 } 3638 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 3639 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2); 3640 3641 return "bcr"; 3642 } 3643 3644 static const HChar * 3645 s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr) 3646 { 3647 IRTemp cond = newTemp(Ity_I32); 3648 3649 if (r1 == 0) { 3650 } else { 3651 if (r1 == 15) { 3652 always_goto(mkexpr(op2addr)); 3653 } else { 3654 assign(cond, s390_call_calculate_cond(r1)); 3655 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 3656 mkexpr(op2addr)); 3657 } 3658 } 3659 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 3660 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2); 3661 3662 return "bc"; 3663 } 3664 3665 static const HChar * 3666 s390_irgen_BCTR(UChar r1, UChar r2) 3667 { 3668 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1))); 3669 if (r2 != 0) { 3670 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)), 3671 get_gpr_dw0(r2)); 3672 } 3673 3674 return "bctr"; 3675 } 3676 3677 static const HChar * 3678 s390_irgen_BCTGR(UChar r1, UChar r2) 3679 { 3680 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1))); 3681 if (r2 != 0) { 3682 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)), 3683 get_gpr_dw0(r2)); 3684 } 3685 3686 return "bctgr"; 3687 } 3688 3689 static const HChar * 3690 s390_irgen_BCT(UChar r1, IRTemp op2addr) 3691 { 3692 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1))); 3693 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)), 3694 mkexpr(op2addr)); 3695 3696 return "bct"; 3697 } 3698 3699 static const HChar * 3700 s390_irgen_BCTG(UChar r1, IRTemp op2addr) 3701 { 3702 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1))); 3703 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)), 3704 mkexpr(op2addr)); 3705 3706 return "bctg"; 3707 } 3708 3709 static const HChar * 3710 s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr) 3711 { 3712 IRTemp value = newTemp(Ity_I32); 3713 3714 assign(value, get_gpr_w1(r3 | 1)); 3715 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3))); 3716 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value), 3717 get_gpr_w1(r1)), mkexpr(op2addr)); 3718 3719 return "bxh"; 3720 } 3721 3722 static const HChar * 3723 s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr) 3724 { 3725 IRTemp value = newTemp(Ity_I64); 3726 3727 assign(value, get_gpr_dw0(r3 | 1)); 3728 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3))); 3729 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value), 3730 get_gpr_dw0(r1)), mkexpr(op2addr)); 3731 3732 return "bxhg"; 3733 } 3734 3735 static const HChar * 3736 s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr) 3737 { 3738 IRTemp value = newTemp(Ity_I32); 3739 3740 assign(value, get_gpr_w1(r3 | 1)); 3741 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3))); 3742 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1), 3743 mkexpr(value)), mkexpr(op2addr)); 3744 3745 return "bxle"; 3746 } 3747 3748 static const HChar * 3749 s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr) 3750 { 3751 IRTemp value = newTemp(Ity_I64); 3752 3753 assign(value, get_gpr_dw0(r3 | 1)); 3754 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3))); 3755 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1), 3756 mkexpr(value)), mkexpr(op2addr)); 3757 3758 return "bxleg"; 3759 } 3760 3761 static const HChar * 3762 s390_irgen_BRAS(UChar r1, UShort i2) 3763 { 3764 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL)); 3765 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); 3766 3767 return "bras"; 3768 } 3769 3770 static const HChar * 3771 s390_irgen_BRASL(UChar r1, UInt i2) 3772 { 3773 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL)); 3774 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)); 3775 3776 return "brasl"; 3777 } 3778 3779 static const HChar * 3780 s390_irgen_BRC(UChar r1, UShort i2) 3781 { 3782 IRTemp cond = newTemp(Ity_I32); 3783 3784 if (r1 == 0) { 3785 } else { 3786 if (r1 == 15) { 3787 always_goto_and_chase( 3788 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); 3789 } else { 3790 assign(cond, s390_call_calculate_cond(r1)); 3791 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 3792 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); 3793 3794 } 3795 } 3796 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 3797 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2); 3798 3799 return "brc"; 3800 } 3801 3802 static const HChar * 3803 s390_irgen_BRCL(UChar r1, UInt i2) 3804 { 3805 IRTemp cond = newTemp(Ity_I32); 3806 3807 if (r1 == 0) { 3808 } else { 3809 if (r1 == 15) { 3810 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)); 3811 } else { 3812 assign(cond, s390_call_calculate_cond(r1)); 3813 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 3814 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)); 3815 } 3816 } 3817 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 3818 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2); 3819 3820 return "brcl"; 3821 } 3822 3823 static const HChar * 3824 s390_irgen_BRCT(UChar r1, UShort i2) 3825 { 3826 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1))); 3827 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)), 3828 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); 3829 3830 return "brct"; 3831 } 3832 3833 static const HChar * 3834 s390_irgen_BRCTG(UChar r1, UShort i2) 3835 { 3836 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1))); 3837 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)), 3838 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); 3839 3840 return "brctg"; 3841 } 3842 3843 static const HChar * 3844 s390_irgen_BRXH(UChar r1, UChar r3, UShort i2) 3845 { 3846 IRTemp value = newTemp(Ity_I32); 3847 3848 assign(value, get_gpr_w1(r3 | 1)); 3849 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3))); 3850 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)), 3851 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); 3852 3853 return "brxh"; 3854 } 3855 3856 static const HChar * 3857 s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2) 3858 { 3859 IRTemp value = newTemp(Ity_I64); 3860 3861 assign(value, get_gpr_dw0(r3 | 1)); 3862 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3))); 3863 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)), 3864 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); 3865 3866 return "brxhg"; 3867 } 3868 3869 static const HChar * 3870 s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2) 3871 { 3872 IRTemp value = newTemp(Ity_I32); 3873 3874 assign(value, get_gpr_w1(r3 | 1)); 3875 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3))); 3876 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)), 3877 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); 3878 3879 return "brxle"; 3880 } 3881 3882 static const HChar * 3883 s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2) 3884 { 3885 IRTemp value = newTemp(Ity_I64); 3886 3887 assign(value, get_gpr_dw0(r3 | 1)); 3888 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3))); 3889 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)), 3890 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); 3891 3892 return "brxlg"; 3893 } 3894 3895 static const HChar * 3896 s390_irgen_CR(UChar r1, UChar r2) 3897 { 3898 IRTemp op1 = newTemp(Ity_I32); 3899 IRTemp op2 = newTemp(Ity_I32); 3900 3901 assign(op1, get_gpr_w1(r1)); 3902 assign(op2, get_gpr_w1(r2)); 3903 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 3904 3905 return "cr"; 3906 } 3907 3908 static const HChar * 3909 s390_irgen_CGR(UChar r1, UChar r2) 3910 { 3911 IRTemp op1 = newTemp(Ity_I64); 3912 IRTemp op2 = newTemp(Ity_I64); 3913 3914 assign(op1, get_gpr_dw0(r1)); 3915 assign(op2, get_gpr_dw0(r2)); 3916 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 3917 3918 return "cgr"; 3919 } 3920 3921 static const HChar * 3922 s390_irgen_CGFR(UChar r1, UChar r2) 3923 { 3924 IRTemp op1 = newTemp(Ity_I64); 3925 IRTemp op2 = newTemp(Ity_I64); 3926 3927 assign(op1, get_gpr_dw0(r1)); 3928 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2))); 3929 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 3930 3931 return "cgfr"; 3932 } 3933 3934 static const HChar * 3935 s390_irgen_C(UChar r1, IRTemp op2addr) 3936 { 3937 IRTemp op1 = newTemp(Ity_I32); 3938 IRTemp op2 = newTemp(Ity_I32); 3939 3940 assign(op1, get_gpr_w1(r1)); 3941 assign(op2, load(Ity_I32, mkexpr(op2addr))); 3942 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 3943 3944 return "c"; 3945 } 3946 3947 static const HChar * 3948 s390_irgen_CY(UChar r1, IRTemp op2addr) 3949 { 3950 IRTemp op1 = newTemp(Ity_I32); 3951 IRTemp op2 = newTemp(Ity_I32); 3952 3953 assign(op1, get_gpr_w1(r1)); 3954 assign(op2, load(Ity_I32, mkexpr(op2addr))); 3955 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 3956 3957 return "cy"; 3958 } 3959 3960 static const HChar * 3961 s390_irgen_CG(UChar r1, IRTemp op2addr) 3962 { 3963 IRTemp op1 = newTemp(Ity_I64); 3964 IRTemp op2 = newTemp(Ity_I64); 3965 3966 assign(op1, get_gpr_dw0(r1)); 3967 assign(op2, load(Ity_I64, mkexpr(op2addr))); 3968 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 3969 3970 return "cg"; 3971 } 3972 3973 static const HChar * 3974 s390_irgen_CGF(UChar r1, IRTemp op2addr) 3975 { 3976 IRTemp op1 = newTemp(Ity_I64); 3977 IRTemp op2 = newTemp(Ity_I64); 3978 3979 assign(op1, get_gpr_dw0(r1)); 3980 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr)))); 3981 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 3982 3983 return "cgf"; 3984 } 3985 3986 static const HChar * 3987 s390_irgen_CFI(UChar r1, UInt i2) 3988 { 3989 IRTemp op1 = newTemp(Ity_I32); 3990 Int op2; 3991 3992 assign(op1, get_gpr_w1(r1)); 3993 op2 = (Int)i2; 3994 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32, 3995 mkU32((UInt)op2))); 3996 3997 return "cfi"; 3998 } 3999 4000 static const HChar * 4001 s390_irgen_CGFI(UChar r1, UInt i2) 4002 { 4003 IRTemp op1 = newTemp(Ity_I64); 4004 Long op2; 4005 4006 assign(op1, get_gpr_dw0(r1)); 4007 op2 = (Long)(Int)i2; 4008 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64, 4009 mkU64((ULong)op2))); 4010 4011 return "cgfi"; 4012 } 4013 4014 static const HChar * 4015 s390_irgen_CRL(UChar r1, UInt i2) 4016 { 4017 IRTemp op1 = newTemp(Ity_I32); 4018 IRTemp op2 = newTemp(Ity_I32); 4019 4020 assign(op1, get_gpr_w1(r1)); 4021 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int) 4022 i2 << 1)))); 4023 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 4024 4025 return "crl"; 4026 } 4027 4028 static const HChar * 4029 s390_irgen_CGRL(UChar r1, UInt i2) 4030 { 4031 IRTemp op1 = newTemp(Ity_I64); 4032 IRTemp op2 = newTemp(Ity_I64); 4033 4034 assign(op1, get_gpr_dw0(r1)); 4035 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int) 4036 i2 << 1)))); 4037 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 4038 4039 return "cgrl"; 4040 } 4041 4042 static const HChar * 4043 s390_irgen_CGFRL(UChar r1, UInt i2) 4044 { 4045 IRTemp op1 = newTemp(Ity_I64); 4046 IRTemp op2 = newTemp(Ity_I64); 4047 4048 assign(op1, get_gpr_dw0(r1)); 4049 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr + 4050 ((ULong)(Long)(Int)i2 << 1))))); 4051 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 4052 4053 return "cgfrl"; 4054 } 4055 4056 static const HChar * 4057 s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr) 4058 { 4059 IRTemp op1 = newTemp(Ity_I32); 4060 IRTemp op2 = newTemp(Ity_I32); 4061 IRTemp cond = newTemp(Ity_I32); 4062 4063 if (m3 == 0) { 4064 } else { 4065 if (m3 == 14) { 4066 always_goto(mkexpr(op4addr)); 4067 } else { 4068 assign(op1, get_gpr_w1(r1)); 4069 assign(op2, get_gpr_w1(r2)); 4070 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, 4071 op1, op2)); 4072 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), 4073 mkU32(0)), mkexpr(op4addr)); 4074 } 4075 } 4076 4077 return "crb"; 4078 } 4079 4080 static const HChar * 4081 s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr) 4082 { 4083 IRTemp op1 = newTemp(Ity_I64); 4084 IRTemp op2 = newTemp(Ity_I64); 4085 IRTemp cond = newTemp(Ity_I32); 4086 4087 if (m3 == 0) { 4088 } else { 4089 if (m3 == 14) { 4090 always_goto(mkexpr(op4addr)); 4091 } else { 4092 assign(op1, get_gpr_dw0(r1)); 4093 assign(op2, get_gpr_dw0(r2)); 4094 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, 4095 op1, op2)); 4096 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), 4097 mkU32(0)), mkexpr(op4addr)); 4098 } 4099 } 4100 4101 return "cgrb"; 4102 } 4103 4104 static const HChar * 4105 s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3) 4106 { 4107 IRTemp op1 = newTemp(Ity_I32); 4108 IRTemp op2 = newTemp(Ity_I32); 4109 IRTemp cond = newTemp(Ity_I32); 4110 4111 if (m3 == 0) { 4112 } else { 4113 if (m3 == 14) { 4114 always_goto_and_chase( 4115 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4116 } else { 4117 assign(op1, get_gpr_w1(r1)); 4118 assign(op2, get_gpr_w1(r2)); 4119 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, 4120 op1, op2)); 4121 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 4122 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4123 4124 } 4125 } 4126 4127 return "crj"; 4128 } 4129 4130 static const HChar * 4131 s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3) 4132 { 4133 IRTemp op1 = newTemp(Ity_I64); 4134 IRTemp op2 = newTemp(Ity_I64); 4135 IRTemp cond = newTemp(Ity_I32); 4136 4137 if (m3 == 0) { 4138 } else { 4139 if (m3 == 14) { 4140 always_goto_and_chase( 4141 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4142 } else { 4143 assign(op1, get_gpr_dw0(r1)); 4144 assign(op2, get_gpr_dw0(r2)); 4145 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, 4146 op1, op2)); 4147 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 4148 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4149 4150 } 4151 } 4152 4153 return "cgrj"; 4154 } 4155 4156 static const HChar * 4157 s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr) 4158 { 4159 IRTemp op1 = newTemp(Ity_I32); 4160 Int op2; 4161 IRTemp cond = newTemp(Ity_I32); 4162 4163 if (m3 == 0) { 4164 } else { 4165 if (m3 == 14) { 4166 always_goto(mkexpr(op4addr)); 4167 } else { 4168 assign(op1, get_gpr_w1(r1)); 4169 op2 = (Int)(Char)i2; 4170 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1, 4171 mktemp(Ity_I32, mkU32((UInt)op2)))); 4172 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 4173 mkexpr(op4addr)); 4174 } 4175 } 4176 4177 return "cib"; 4178 } 4179 4180 static const HChar * 4181 s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr) 4182 { 4183 IRTemp op1 = newTemp(Ity_I64); 4184 Long op2; 4185 IRTemp cond = newTemp(Ity_I32); 4186 4187 if (m3 == 0) { 4188 } else { 4189 if (m3 == 14) { 4190 always_goto(mkexpr(op4addr)); 4191 } else { 4192 assign(op1, get_gpr_dw0(r1)); 4193 op2 = (Long)(Char)i2; 4194 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1, 4195 mktemp(Ity_I64, mkU64((ULong)op2)))); 4196 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 4197 mkexpr(op4addr)); 4198 } 4199 } 4200 4201 return "cgib"; 4202 } 4203 4204 static const HChar * 4205 s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2) 4206 { 4207 IRTemp op1 = newTemp(Ity_I32); 4208 Int op2; 4209 IRTemp cond = newTemp(Ity_I32); 4210 4211 if (m3 == 0) { 4212 } else { 4213 if (m3 == 14) { 4214 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4215 } else { 4216 assign(op1, get_gpr_w1(r1)); 4217 op2 = (Int)(Char)i2; 4218 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1, 4219 mktemp(Ity_I32, mkU32((UInt)op2)))); 4220 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 4221 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4222 4223 } 4224 } 4225 4226 return "cij"; 4227 } 4228 4229 static const HChar * 4230 s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2) 4231 { 4232 IRTemp op1 = newTemp(Ity_I64); 4233 Long op2; 4234 IRTemp cond = newTemp(Ity_I32); 4235 4236 if (m3 == 0) { 4237 } else { 4238 if (m3 == 14) { 4239 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4240 } else { 4241 assign(op1, get_gpr_dw0(r1)); 4242 op2 = (Long)(Char)i2; 4243 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1, 4244 mktemp(Ity_I64, mkU64((ULong)op2)))); 4245 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 4246 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4247 4248 } 4249 } 4250 4251 return "cgij"; 4252 } 4253 4254 static const HChar * 4255 s390_irgen_CH(UChar r1, IRTemp op2addr) 4256 { 4257 IRTemp op1 = newTemp(Ity_I32); 4258 IRTemp op2 = newTemp(Ity_I32); 4259 4260 assign(op1, get_gpr_w1(r1)); 4261 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr)))); 4262 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 4263 4264 return "ch"; 4265 } 4266 4267 static const HChar * 4268 s390_irgen_CHY(UChar r1, IRTemp op2addr) 4269 { 4270 IRTemp op1 = newTemp(Ity_I32); 4271 IRTemp op2 = newTemp(Ity_I32); 4272 4273 assign(op1, get_gpr_w1(r1)); 4274 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr)))); 4275 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 4276 4277 return "chy"; 4278 } 4279 4280 static const HChar * 4281 s390_irgen_CGH(UChar r1, IRTemp op2addr) 4282 { 4283 IRTemp op1 = newTemp(Ity_I64); 4284 IRTemp op2 = newTemp(Ity_I64); 4285 4286 assign(op1, get_gpr_dw0(r1)); 4287 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr)))); 4288 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 4289 4290 return "cgh"; 4291 } 4292 4293 static const HChar * 4294 s390_irgen_CHI(UChar r1, UShort i2) 4295 { 4296 IRTemp op1 = newTemp(Ity_I32); 4297 Int op2; 4298 4299 assign(op1, get_gpr_w1(r1)); 4300 op2 = (Int)(Short)i2; 4301 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32, 4302 mkU32((UInt)op2))); 4303 4304 return "chi"; 4305 } 4306 4307 static const HChar * 4308 s390_irgen_CGHI(UChar r1, UShort i2) 4309 { 4310 IRTemp op1 = newTemp(Ity_I64); 4311 Long op2; 4312 4313 assign(op1, get_gpr_dw0(r1)); 4314 op2 = (Long)(Short)i2; 4315 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64, 4316 mkU64((ULong)op2))); 4317 4318 return "cghi"; 4319 } 4320 4321 static const HChar * 4322 s390_irgen_CHHSI(UShort i2, IRTemp op1addr) 4323 { 4324 IRTemp op1 = newTemp(Ity_I16); 4325 Short op2; 4326 4327 assign(op1, load(Ity_I16, mkexpr(op1addr))); 4328 op2 = (Short)i2; 4329 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16, 4330 mkU16((UShort)op2))); 4331 4332 return "chhsi"; 4333 } 4334 4335 static const HChar * 4336 s390_irgen_CHSI(UShort i2, IRTemp op1addr) 4337 { 4338 IRTemp op1 = newTemp(Ity_I32); 4339 Int op2; 4340 4341 assign(op1, load(Ity_I32, mkexpr(op1addr))); 4342 op2 = (Int)(Short)i2; 4343 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32, 4344 mkU32((UInt)op2))); 4345 4346 return "chsi"; 4347 } 4348 4349 static const HChar * 4350 s390_irgen_CGHSI(UShort i2, IRTemp op1addr) 4351 { 4352 IRTemp op1 = newTemp(Ity_I64); 4353 Long op2; 4354 4355 assign(op1, load(Ity_I64, mkexpr(op1addr))); 4356 op2 = (Long)(Short)i2; 4357 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64, 4358 mkU64((ULong)op2))); 4359 4360 return "cghsi"; 4361 } 4362 4363 static const HChar * 4364 s390_irgen_CHRL(UChar r1, UInt i2) 4365 { 4366 IRTemp op1 = newTemp(Ity_I32); 4367 IRTemp op2 = newTemp(Ity_I32); 4368 4369 assign(op1, get_gpr_w1(r1)); 4370 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr + 4371 ((ULong)(Long)(Int)i2 << 1))))); 4372 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 4373 4374 return "chrl"; 4375 } 4376 4377 static const HChar * 4378 s390_irgen_CGHRL(UChar r1, UInt i2) 4379 { 4380 IRTemp op1 = newTemp(Ity_I64); 4381 IRTemp op2 = newTemp(Ity_I64); 4382 4383 assign(op1, get_gpr_dw0(r1)); 4384 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr + 4385 ((ULong)(Long)(Int)i2 << 1))))); 4386 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 4387 4388 return "cghrl"; 4389 } 4390 4391 static const HChar * 4392 s390_irgen_CHHR(UChar r1, UChar r2) 4393 { 4394 IRTemp op1 = newTemp(Ity_I32); 4395 IRTemp op2 = newTemp(Ity_I32); 4396 4397 assign(op1, get_gpr_w0(r1)); 4398 assign(op2, get_gpr_w0(r2)); 4399 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 4400 4401 return "chhr"; 4402 } 4403 4404 static const HChar * 4405 s390_irgen_CHLR(UChar r1, UChar r2) 4406 { 4407 IRTemp op1 = newTemp(Ity_I32); 4408 IRTemp op2 = newTemp(Ity_I32); 4409 4410 assign(op1, get_gpr_w0(r1)); 4411 assign(op2, get_gpr_w1(r2)); 4412 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 4413 4414 return "chlr"; 4415 } 4416 4417 static const HChar * 4418 s390_irgen_CHF(UChar r1, IRTemp op2addr) 4419 { 4420 IRTemp op1 = newTemp(Ity_I32); 4421 IRTemp op2 = newTemp(Ity_I32); 4422 4423 assign(op1, get_gpr_w0(r1)); 4424 assign(op2, load(Ity_I32, mkexpr(op2addr))); 4425 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); 4426 4427 return "chf"; 4428 } 4429 4430 static const HChar * 4431 s390_irgen_CIH(UChar r1, UInt i2) 4432 { 4433 IRTemp op1 = newTemp(Ity_I32); 4434 Int op2; 4435 4436 assign(op1, get_gpr_w0(r1)); 4437 op2 = (Int)i2; 4438 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32, 4439 mkU32((UInt)op2))); 4440 4441 return "cih"; 4442 } 4443 4444 static const HChar * 4445 s390_irgen_CLR(UChar r1, UChar r2) 4446 { 4447 IRTemp op1 = newTemp(Ity_I32); 4448 IRTemp op2 = newTemp(Ity_I32); 4449 4450 assign(op1, get_gpr_w1(r1)); 4451 assign(op2, get_gpr_w1(r2)); 4452 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 4453 4454 return "clr"; 4455 } 4456 4457 static const HChar * 4458 s390_irgen_CLGR(UChar r1, UChar r2) 4459 { 4460 IRTemp op1 = newTemp(Ity_I64); 4461 IRTemp op2 = newTemp(Ity_I64); 4462 4463 assign(op1, get_gpr_dw0(r1)); 4464 assign(op2, get_gpr_dw0(r2)); 4465 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 4466 4467 return "clgr"; 4468 } 4469 4470 static const HChar * 4471 s390_irgen_CLGFR(UChar r1, UChar r2) 4472 { 4473 IRTemp op1 = newTemp(Ity_I64); 4474 IRTemp op2 = newTemp(Ity_I64); 4475 4476 assign(op1, get_gpr_dw0(r1)); 4477 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2))); 4478 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 4479 4480 return "clgfr"; 4481 } 4482 4483 static const HChar * 4484 s390_irgen_CL(UChar r1, IRTemp op2addr) 4485 { 4486 IRTemp op1 = newTemp(Ity_I32); 4487 IRTemp op2 = newTemp(Ity_I32); 4488 4489 assign(op1, get_gpr_w1(r1)); 4490 assign(op2, load(Ity_I32, mkexpr(op2addr))); 4491 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 4492 4493 return "cl"; 4494 } 4495 4496 static const HChar * 4497 s390_irgen_CLY(UChar r1, IRTemp op2addr) 4498 { 4499 IRTemp op1 = newTemp(Ity_I32); 4500 IRTemp op2 = newTemp(Ity_I32); 4501 4502 assign(op1, get_gpr_w1(r1)); 4503 assign(op2, load(Ity_I32, mkexpr(op2addr))); 4504 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 4505 4506 return "cly"; 4507 } 4508 4509 static const HChar * 4510 s390_irgen_CLG(UChar r1, IRTemp op2addr) 4511 { 4512 IRTemp op1 = newTemp(Ity_I64); 4513 IRTemp op2 = newTemp(Ity_I64); 4514 4515 assign(op1, get_gpr_dw0(r1)); 4516 assign(op2, load(Ity_I64, mkexpr(op2addr))); 4517 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 4518 4519 return "clg"; 4520 } 4521 4522 static const HChar * 4523 s390_irgen_CLGF(UChar r1, IRTemp op2addr) 4524 { 4525 IRTemp op1 = newTemp(Ity_I64); 4526 IRTemp op2 = newTemp(Ity_I64); 4527 4528 assign(op1, get_gpr_dw0(r1)); 4529 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr)))); 4530 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 4531 4532 return "clgf"; 4533 } 4534 4535 static const HChar * 4536 s390_irgen_CLFI(UChar r1, UInt i2) 4537 { 4538 IRTemp op1 = newTemp(Ity_I32); 4539 UInt op2; 4540 4541 assign(op1, get_gpr_w1(r1)); 4542 op2 = i2; 4543 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32, 4544 mkU32(op2))); 4545 4546 return "clfi"; 4547 } 4548 4549 static const HChar * 4550 s390_irgen_CLGFI(UChar r1, UInt i2) 4551 { 4552 IRTemp op1 = newTemp(Ity_I64); 4553 ULong op2; 4554 4555 assign(op1, get_gpr_dw0(r1)); 4556 op2 = (ULong)i2; 4557 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64, 4558 mkU64(op2))); 4559 4560 return "clgfi"; 4561 } 4562 4563 static const HChar * 4564 s390_irgen_CLI(UChar i2, IRTemp op1addr) 4565 { 4566 IRTemp op1 = newTemp(Ity_I8); 4567 UChar op2; 4568 4569 assign(op1, load(Ity_I8, mkexpr(op1addr))); 4570 op2 = i2; 4571 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8, 4572 mkU8(op2))); 4573 4574 return "cli"; 4575 } 4576 4577 static const HChar * 4578 s390_irgen_CLIY(UChar i2, IRTemp op1addr) 4579 { 4580 IRTemp op1 = newTemp(Ity_I8); 4581 UChar op2; 4582 4583 assign(op1, load(Ity_I8, mkexpr(op1addr))); 4584 op2 = i2; 4585 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8, 4586 mkU8(op2))); 4587 4588 return "cliy"; 4589 } 4590 4591 static const HChar * 4592 s390_irgen_CLFHSI(UShort i2, IRTemp op1addr) 4593 { 4594 IRTemp op1 = newTemp(Ity_I32); 4595 UInt op2; 4596 4597 assign(op1, load(Ity_I32, mkexpr(op1addr))); 4598 op2 = (UInt)i2; 4599 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32, 4600 mkU32(op2))); 4601 4602 return "clfhsi"; 4603 } 4604 4605 static const HChar * 4606 s390_irgen_CLGHSI(UShort i2, IRTemp op1addr) 4607 { 4608 IRTemp op1 = newTemp(Ity_I64); 4609 ULong op2; 4610 4611 assign(op1, load(Ity_I64, mkexpr(op1addr))); 4612 op2 = (ULong)i2; 4613 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64, 4614 mkU64(op2))); 4615 4616 return "clghsi"; 4617 } 4618 4619 static const HChar * 4620 s390_irgen_CLHHSI(UShort i2, IRTemp op1addr) 4621 { 4622 IRTemp op1 = newTemp(Ity_I16); 4623 UShort op2; 4624 4625 assign(op1, load(Ity_I16, mkexpr(op1addr))); 4626 op2 = i2; 4627 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16, 4628 mkU16(op2))); 4629 4630 return "clhhsi"; 4631 } 4632 4633 static const HChar * 4634 s390_irgen_CLRL(UChar r1, UInt i2) 4635 { 4636 IRTemp op1 = newTemp(Ity_I32); 4637 IRTemp op2 = newTemp(Ity_I32); 4638 4639 assign(op1, get_gpr_w1(r1)); 4640 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int) 4641 i2 << 1)))); 4642 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 4643 4644 return "clrl"; 4645 } 4646 4647 static const HChar * 4648 s390_irgen_CLGRL(UChar r1, UInt i2) 4649 { 4650 IRTemp op1 = newTemp(Ity_I64); 4651 IRTemp op2 = newTemp(Ity_I64); 4652 4653 assign(op1, get_gpr_dw0(r1)); 4654 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int) 4655 i2 << 1)))); 4656 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 4657 4658 return "clgrl"; 4659 } 4660 4661 static const HChar * 4662 s390_irgen_CLGFRL(UChar r1, UInt i2) 4663 { 4664 IRTemp op1 = newTemp(Ity_I64); 4665 IRTemp op2 = newTemp(Ity_I64); 4666 4667 assign(op1, get_gpr_dw0(r1)); 4668 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr + 4669 ((ULong)(Long)(Int)i2 << 1))))); 4670 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 4671 4672 return "clgfrl"; 4673 } 4674 4675 static const HChar * 4676 s390_irgen_CLHRL(UChar r1, UInt i2) 4677 { 4678 IRTemp op1 = newTemp(Ity_I32); 4679 IRTemp op2 = newTemp(Ity_I32); 4680 4681 assign(op1, get_gpr_w1(r1)); 4682 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr + 4683 ((ULong)(Long)(Int)i2 << 1))))); 4684 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 4685 4686 return "clhrl"; 4687 } 4688 4689 static const HChar * 4690 s390_irgen_CLGHRL(UChar r1, UInt i2) 4691 { 4692 IRTemp op1 = newTemp(Ity_I64); 4693 IRTemp op2 = newTemp(Ity_I64); 4694 4695 assign(op1, get_gpr_dw0(r1)); 4696 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr + 4697 ((ULong)(Long)(Int)i2 << 1))))); 4698 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 4699 4700 return "clghrl"; 4701 } 4702 4703 static const HChar * 4704 s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr) 4705 { 4706 IRTemp op1 = newTemp(Ity_I32); 4707 IRTemp op2 = newTemp(Ity_I32); 4708 IRTemp cond = newTemp(Ity_I32); 4709 4710 if (m3 == 0) { 4711 } else { 4712 if (m3 == 14) { 4713 always_goto(mkexpr(op4addr)); 4714 } else { 4715 assign(op1, get_gpr_w1(r1)); 4716 assign(op2, get_gpr_w1(r2)); 4717 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, 4718 op1, op2)); 4719 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 4720 mkexpr(op4addr)); 4721 } 4722 } 4723 4724 return "clrb"; 4725 } 4726 4727 static const HChar * 4728 s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr) 4729 { 4730 IRTemp op1 = newTemp(Ity_I64); 4731 IRTemp op2 = newTemp(Ity_I64); 4732 IRTemp cond = newTemp(Ity_I32); 4733 4734 if (m3 == 0) { 4735 } else { 4736 if (m3 == 14) { 4737 always_goto(mkexpr(op4addr)); 4738 } else { 4739 assign(op1, get_gpr_dw0(r1)); 4740 assign(op2, get_gpr_dw0(r2)); 4741 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, 4742 op1, op2)); 4743 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 4744 mkexpr(op4addr)); 4745 } 4746 } 4747 4748 return "clgrb"; 4749 } 4750 4751 static const HChar * 4752 s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3) 4753 { 4754 IRTemp op1 = newTemp(Ity_I32); 4755 IRTemp op2 = newTemp(Ity_I32); 4756 IRTemp cond = newTemp(Ity_I32); 4757 4758 if (m3 == 0) { 4759 } else { 4760 if (m3 == 14) { 4761 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4762 } else { 4763 assign(op1, get_gpr_w1(r1)); 4764 assign(op2, get_gpr_w1(r2)); 4765 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, 4766 op1, op2)); 4767 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 4768 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4769 4770 } 4771 } 4772 4773 return "clrj"; 4774 } 4775 4776 static const HChar * 4777 s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3) 4778 { 4779 IRTemp op1 = newTemp(Ity_I64); 4780 IRTemp op2 = newTemp(Ity_I64); 4781 IRTemp cond = newTemp(Ity_I32); 4782 4783 if (m3 == 0) { 4784 } else { 4785 if (m3 == 14) { 4786 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4787 } else { 4788 assign(op1, get_gpr_dw0(r1)); 4789 assign(op2, get_gpr_dw0(r2)); 4790 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, 4791 op1, op2)); 4792 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 4793 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4794 4795 } 4796 } 4797 4798 return "clgrj"; 4799 } 4800 4801 static const HChar * 4802 s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr) 4803 { 4804 IRTemp op1 = newTemp(Ity_I32); 4805 UInt op2; 4806 IRTemp cond = newTemp(Ity_I32); 4807 4808 if (m3 == 0) { 4809 } else { 4810 if (m3 == 14) { 4811 always_goto(mkexpr(op4addr)); 4812 } else { 4813 assign(op1, get_gpr_w1(r1)); 4814 op2 = (UInt)i2; 4815 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1, 4816 mktemp(Ity_I32, mkU32(op2)))); 4817 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 4818 mkexpr(op4addr)); 4819 } 4820 } 4821 4822 return "clib"; 4823 } 4824 4825 static const HChar * 4826 s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr) 4827 { 4828 IRTemp op1 = newTemp(Ity_I64); 4829 ULong op2; 4830 IRTemp cond = newTemp(Ity_I32); 4831 4832 if (m3 == 0) { 4833 } else { 4834 if (m3 == 14) { 4835 always_goto(mkexpr(op4addr)); 4836 } else { 4837 assign(op1, get_gpr_dw0(r1)); 4838 op2 = (ULong)i2; 4839 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1, 4840 mktemp(Ity_I64, mkU64(op2)))); 4841 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 4842 mkexpr(op4addr)); 4843 } 4844 } 4845 4846 return "clgib"; 4847 } 4848 4849 static const HChar * 4850 s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2) 4851 { 4852 IRTemp op1 = newTemp(Ity_I32); 4853 UInt op2; 4854 IRTemp cond = newTemp(Ity_I32); 4855 4856 if (m3 == 0) { 4857 } else { 4858 if (m3 == 14) { 4859 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4860 } else { 4861 assign(op1, get_gpr_w1(r1)); 4862 op2 = (UInt)i2; 4863 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1, 4864 mktemp(Ity_I32, mkU32(op2)))); 4865 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 4866 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4867 4868 } 4869 } 4870 4871 return "clij"; 4872 } 4873 4874 static const HChar * 4875 s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2) 4876 { 4877 IRTemp op1 = newTemp(Ity_I64); 4878 ULong op2; 4879 IRTemp cond = newTemp(Ity_I32); 4880 4881 if (m3 == 0) { 4882 } else { 4883 if (m3 == 14) { 4884 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4885 } else { 4886 assign(op1, get_gpr_dw0(r1)); 4887 op2 = (ULong)i2; 4888 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1, 4889 mktemp(Ity_I64, mkU64(op2)))); 4890 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), 4891 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); 4892 4893 } 4894 } 4895 4896 return "clgij"; 4897 } 4898 4899 static const HChar * 4900 s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr) 4901 { 4902 IRTemp op1 = newTemp(Ity_I32); 4903 IRTemp op2 = newTemp(Ity_I32); 4904 IRTemp b0 = newTemp(Ity_I32); 4905 IRTemp b1 = newTemp(Ity_I32); 4906 IRTemp b2 = newTemp(Ity_I32); 4907 IRTemp b3 = newTemp(Ity_I32); 4908 IRTemp c0 = newTemp(Ity_I32); 4909 IRTemp c1 = newTemp(Ity_I32); 4910 IRTemp c2 = newTemp(Ity_I32); 4911 IRTemp c3 = newTemp(Ity_I32); 4912 UChar n; 4913 4914 n = 0; 4915 if ((r3 & 8) != 0) { 4916 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1))); 4917 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr)))); 4918 n = n + 1; 4919 } else { 4920 assign(b0, mkU32(0)); 4921 assign(c0, mkU32(0)); 4922 } 4923 if ((r3 & 4) != 0) { 4924 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1))); 4925 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), 4926 mkU64(n))))); 4927 n = n + 1; 4928 } else { 4929 assign(b1, mkU32(0)); 4930 assign(c1, mkU32(0)); 4931 } 4932 if ((r3 & 2) != 0) { 4933 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1))); 4934 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), 4935 mkU64(n))))); 4936 n = n + 1; 4937 } else { 4938 assign(b2, mkU32(0)); 4939 assign(c2, mkU32(0)); 4940 } 4941 if ((r3 & 1) != 0) { 4942 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1))); 4943 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), 4944 mkU64(n))))); 4945 n = n + 1; 4946 } else { 4947 assign(b3, mkU32(0)); 4948 assign(c3, mkU32(0)); 4949 } 4950 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32, 4951 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))), 4952 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3))); 4953 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32, 4954 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))), 4955 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3))); 4956 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 4957 4958 return "clm"; 4959 } 4960 4961 static const HChar * 4962 s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr) 4963 { 4964 IRTemp op1 = newTemp(Ity_I32); 4965 IRTemp op2 = newTemp(Ity_I32); 4966 IRTemp b0 = newTemp(Ity_I32); 4967 IRTemp b1 = newTemp(Ity_I32); 4968 IRTemp b2 = newTemp(Ity_I32); 4969 IRTemp b3 = newTemp(Ity_I32); 4970 IRTemp c0 = newTemp(Ity_I32); 4971 IRTemp c1 = newTemp(Ity_I32); 4972 IRTemp c2 = newTemp(Ity_I32); 4973 IRTemp c3 = newTemp(Ity_I32); 4974 UChar n; 4975 4976 n = 0; 4977 if ((r3 & 8) != 0) { 4978 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1))); 4979 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr)))); 4980 n = n + 1; 4981 } else { 4982 assign(b0, mkU32(0)); 4983 assign(c0, mkU32(0)); 4984 } 4985 if ((r3 & 4) != 0) { 4986 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1))); 4987 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), 4988 mkU64(n))))); 4989 n = n + 1; 4990 } else { 4991 assign(b1, mkU32(0)); 4992 assign(c1, mkU32(0)); 4993 } 4994 if ((r3 & 2) != 0) { 4995 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1))); 4996 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), 4997 mkU64(n))))); 4998 n = n + 1; 4999 } else { 5000 assign(b2, mkU32(0)); 5001 assign(c2, mkU32(0)); 5002 } 5003 if ((r3 & 1) != 0) { 5004 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1))); 5005 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), 5006 mkU64(n))))); 5007 n = n + 1; 5008 } else { 5009 assign(b3, mkU32(0)); 5010 assign(c3, mkU32(0)); 5011 } 5012 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32, 5013 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))), 5014 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3))); 5015 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32, 5016 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))), 5017 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3))); 5018 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 5019 5020 return "clmy"; 5021 } 5022 5023 static const HChar * 5024 s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr) 5025 { 5026 IRTemp op1 = newTemp(Ity_I32); 5027 IRTemp op2 = newTemp(Ity_I32); 5028 IRTemp b0 = newTemp(Ity_I32); 5029 IRTemp b1 = newTemp(Ity_I32); 5030 IRTemp b2 = newTemp(Ity_I32); 5031 IRTemp b3 = newTemp(Ity_I32); 5032 IRTemp c0 = newTemp(Ity_I32); 5033 IRTemp c1 = newTemp(Ity_I32); 5034 IRTemp c2 = newTemp(Ity_I32); 5035 IRTemp c3 = newTemp(Ity_I32); 5036 UChar n; 5037 5038 n = 0; 5039 if ((r3 & 8) != 0) { 5040 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1))); 5041 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr)))); 5042 n = n + 1; 5043 } else { 5044 assign(b0, mkU32(0)); 5045 assign(c0, mkU32(0)); 5046 } 5047 if ((r3 & 4) != 0) { 5048 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1))); 5049 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), 5050 mkU64(n))))); 5051 n = n + 1; 5052 } else { 5053 assign(b1, mkU32(0)); 5054 assign(c1, mkU32(0)); 5055 } 5056 if ((r3 & 2) != 0) { 5057 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1))); 5058 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), 5059 mkU64(n))))); 5060 n = n + 1; 5061 } else { 5062 assign(b2, mkU32(0)); 5063 assign(c2, mkU32(0)); 5064 } 5065 if ((r3 & 1) != 0) { 5066 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1))); 5067 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), 5068 mkU64(n))))); 5069 n = n + 1; 5070 } else { 5071 assign(b3, mkU32(0)); 5072 assign(c3, mkU32(0)); 5073 } 5074 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32, 5075 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))), 5076 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3))); 5077 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32, 5078 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))), 5079 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3))); 5080 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 5081 5082 return "clmh"; 5083 } 5084 5085 static const HChar * 5086 s390_irgen_CLHHR(UChar r1, UChar r2) 5087 { 5088 IRTemp op1 = newTemp(Ity_I32); 5089 IRTemp op2 = newTemp(Ity_I32); 5090 5091 assign(op1, get_gpr_w0(r1)); 5092 assign(op2, get_gpr_w0(r2)); 5093 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 5094 5095 return "clhhr"; 5096 } 5097 5098 static const HChar * 5099 s390_irgen_CLHLR(UChar r1, UChar r2) 5100 { 5101 IRTemp op1 = newTemp(Ity_I32); 5102 IRTemp op2 = newTemp(Ity_I32); 5103 5104 assign(op1, get_gpr_w0(r1)); 5105 assign(op2, get_gpr_w1(r2)); 5106 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 5107 5108 return "clhlr"; 5109 } 5110 5111 static const HChar * 5112 s390_irgen_CLHF(UChar r1, IRTemp op2addr) 5113 { 5114 IRTemp op1 = newTemp(Ity_I32); 5115 IRTemp op2 = newTemp(Ity_I32); 5116 5117 assign(op1, get_gpr_w0(r1)); 5118 assign(op2, load(Ity_I32, mkexpr(op2addr))); 5119 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); 5120 5121 return "clhf"; 5122 } 5123 5124 static const HChar * 5125 s390_irgen_CLIH(UChar r1, UInt i2) 5126 { 5127 IRTemp op1 = newTemp(Ity_I32); 5128 UInt op2; 5129 5130 assign(op1, get_gpr_w0(r1)); 5131 op2 = i2; 5132 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32, 5133 mkU32(op2))); 5134 5135 return "clih"; 5136 } 5137 5138 static const HChar * 5139 s390_irgen_CPYA(UChar r1, UChar r2) 5140 { 5141 put_ar_w0(r1, get_ar_w0(r2)); 5142 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 5143 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2); 5144 5145 return "cpya"; 5146 } 5147 5148 static const HChar * 5149 s390_irgen_XR(UChar r1, UChar r2) 5150 { 5151 IRTemp op1 = newTemp(Ity_I32); 5152 IRTemp op2 = newTemp(Ity_I32); 5153 IRTemp result = newTemp(Ity_I32); 5154 5155 if (r1 == r2) { 5156 assign(result, mkU32(0)); 5157 } else { 5158 assign(op1, get_gpr_w1(r1)); 5159 assign(op2, get_gpr_w1(r2)); 5160 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2))); 5161 } 5162 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 5163 put_gpr_w1(r1, mkexpr(result)); 5164 5165 return "xr"; 5166 } 5167 5168 static const HChar * 5169 s390_irgen_XGR(UChar r1, UChar r2) 5170 { 5171 IRTemp op1 = newTemp(Ity_I64); 5172 IRTemp op2 = newTemp(Ity_I64); 5173 IRTemp result = newTemp(Ity_I64); 5174 5175 if (r1 == r2) { 5176 assign(result, mkU64(0)); 5177 } else { 5178 assign(op1, get_gpr_dw0(r1)); 5179 assign(op2, get_gpr_dw0(r2)); 5180 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2))); 5181 } 5182 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 5183 put_gpr_dw0(r1, mkexpr(result)); 5184 5185 return "xgr"; 5186 } 5187 5188 static const HChar * 5189 s390_irgen_XRK(UChar r3, UChar r1, UChar r2) 5190 { 5191 IRTemp op2 = newTemp(Ity_I32); 5192 IRTemp op3 = newTemp(Ity_I32); 5193 IRTemp result = newTemp(Ity_I32); 5194 5195 assign(op2, get_gpr_w1(r2)); 5196 assign(op3, get_gpr_w1(r3)); 5197 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3))); 5198 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 5199 put_gpr_w1(r1, mkexpr(result)); 5200 5201 return "xrk"; 5202 } 5203 5204 static const HChar * 5205 s390_irgen_XGRK(UChar r3, UChar r1, UChar r2) 5206 { 5207 IRTemp op2 = newTemp(Ity_I64); 5208 IRTemp op3 = newTemp(Ity_I64); 5209 IRTemp result = newTemp(Ity_I64); 5210 5211 assign(op2, get_gpr_dw0(r2)); 5212 assign(op3, get_gpr_dw0(r3)); 5213 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3))); 5214 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 5215 put_gpr_dw0(r1, mkexpr(result)); 5216 5217 return "xgrk"; 5218 } 5219 5220 static const HChar * 5221 s390_irgen_X(UChar r1, IRTemp op2addr) 5222 { 5223 IRTemp op1 = newTemp(Ity_I32); 5224 IRTemp op2 = newTemp(Ity_I32); 5225 IRTemp result = newTemp(Ity_I32); 5226 5227 assign(op1, get_gpr_w1(r1)); 5228 assign(op2, load(Ity_I32, mkexpr(op2addr))); 5229 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2))); 5230 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 5231 put_gpr_w1(r1, mkexpr(result)); 5232 5233 return "x"; 5234 } 5235 5236 static const HChar * 5237 s390_irgen_XY(UChar r1, IRTemp op2addr) 5238 { 5239 IRTemp op1 = newTemp(Ity_I32); 5240 IRTemp op2 = newTemp(Ity_I32); 5241 IRTemp result = newTemp(Ity_I32); 5242 5243 assign(op1, get_gpr_w1(r1)); 5244 assign(op2, load(Ity_I32, mkexpr(op2addr))); 5245 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2))); 5246 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 5247 put_gpr_w1(r1, mkexpr(result)); 5248 5249 return "xy"; 5250 } 5251 5252 static const HChar * 5253 s390_irgen_XG(UChar r1, IRTemp op2addr) 5254 { 5255 IRTemp op1 = newTemp(Ity_I64); 5256 IRTemp op2 = newTemp(Ity_I64); 5257 IRTemp result = newTemp(Ity_I64); 5258 5259 assign(op1, get_gpr_dw0(r1)); 5260 assign(op2, load(Ity_I64, mkexpr(op2addr))); 5261 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2))); 5262 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 5263 put_gpr_dw0(r1, mkexpr(result)); 5264 5265 return "xg"; 5266 } 5267 5268 static const HChar * 5269 s390_irgen_XI(UChar i2, IRTemp op1addr) 5270 { 5271 IRTemp op1 = newTemp(Ity_I8); 5272 UChar op2; 5273 IRTemp result = newTemp(Ity_I8); 5274 5275 assign(op1, load(Ity_I8, mkexpr(op1addr))); 5276 op2 = i2; 5277 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2))); 5278 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 5279 store(mkexpr(op1addr), mkexpr(result)); 5280 5281 return "xi"; 5282 } 5283 5284 static const HChar * 5285 s390_irgen_XIY(UChar i2, IRTemp op1addr) 5286 { 5287 IRTemp op1 = newTemp(Ity_I8); 5288 UChar op2; 5289 IRTemp result = newTemp(Ity_I8); 5290 5291 assign(op1, load(Ity_I8, mkexpr(op1addr))); 5292 op2 = i2; 5293 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2))); 5294 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 5295 store(mkexpr(op1addr), mkexpr(result)); 5296 5297 return "xiy"; 5298 } 5299 5300 static const HChar * 5301 s390_irgen_XIHF(UChar r1, UInt i2) 5302 { 5303 IRTemp op1 = newTemp(Ity_I32); 5304 UInt op2; 5305 IRTemp result = newTemp(Ity_I32); 5306 5307 assign(op1, get_gpr_w0(r1)); 5308 op2 = i2; 5309 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2))); 5310 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 5311 put_gpr_w0(r1, mkexpr(result)); 5312 5313 return "xihf"; 5314 } 5315 5316 static const HChar * 5317 s390_irgen_XILF(UChar r1, UInt i2) 5318 { 5319 IRTemp op1 = newTemp(Ity_I32); 5320 UInt op2; 5321 IRTemp result = newTemp(Ity_I32); 5322 5323 assign(op1, get_gpr_w1(r1)); 5324 op2 = i2; 5325 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2))); 5326 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 5327 put_gpr_w1(r1, mkexpr(result)); 5328 5329 return "xilf"; 5330 } 5331 5332 static const HChar * 5333 s390_irgen_EAR(UChar r1, UChar r2) 5334 { 5335 put_gpr_w1(r1, get_ar_w0(r2)); 5336 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) 5337 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2); 5338 5339 return "ear"; 5340 } 5341 5342 static const HChar * 5343 s390_irgen_IC(UChar r1, IRTemp op2addr) 5344 { 5345 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr))); 5346 5347 return "ic"; 5348 } 5349 5350 static const HChar * 5351 s390_irgen_ICY(UChar r1, IRTemp op2addr) 5352 { 5353 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr))); 5354 5355 return "icy"; 5356 } 5357 5358 static const HChar * 5359 s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr) 5360 { 5361 UChar n; 5362 IRTemp result = newTemp(Ity_I32); 5363 UInt mask; 5364 5365 n = 0; 5366 mask = (UInt)r3; 5367 if ((mask & 8) != 0) { 5368 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr))); 5369 n = n + 1; 5370 } 5371 if ((mask & 4) != 0) { 5372 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n)))); 5373 5374 n = n + 1; 5375 } 5376 if ((mask & 2) != 0) { 5377 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n)))); 5378 5379 n = n + 1; 5380 } 5381 if ((mask & 1) != 0) { 5382 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n)))); 5383 5384 n = n + 1; 5385 } 5386 assign(result, get_gpr_w1(r1)); 5387 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32, 5388 mkU32(mask))); 5389 5390 return "icm"; 5391 } 5392 5393 static const HChar * 5394 s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr) 5395 { 5396 UChar n; 5397 IRTemp result = newTemp(Ity_I32); 5398 UInt mask; 5399 5400 n = 0; 5401 mask = (UInt)r3; 5402 if ((mask & 8) != 0) { 5403 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr))); 5404 n = n + 1; 5405 } 5406 if ((mask & 4) != 0) { 5407 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n)))); 5408 5409 n = n + 1; 5410 } 5411 if ((mask & 2) != 0) { 5412 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n)))); 5413 5414 n = n + 1; 5415 } 5416 if ((mask & 1) != 0) { 5417 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n)))); 5418 5419 n = n + 1; 5420 } 5421 assign(result, get_gpr_w1(r1)); 5422 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32, 5423 mkU32(mask))); 5424 5425 return "icmy"; 5426 } 5427 5428 static const HChar * 5429 s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr) 5430 { 5431 UChar n; 5432 IRTemp result = newTemp(Ity_I32); 5433 UInt mask; 5434 5435 n = 0; 5436 mask = (UInt)r3; 5437 if ((mask & 8) != 0) { 5438 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr))); 5439 n = n + 1; 5440 } 5441 if ((mask & 4) != 0) { 5442 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n)))); 5443 5444 n = n + 1; 5445 } 5446 if ((mask & 2) != 0) { 5447 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n)))); 5448 5449 n = n + 1; 5450 } 5451 if ((mask & 1) != 0) { 5452 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n)))); 5453 5454 n = n + 1; 5455 } 5456 assign(result, get_gpr_w0(r1)); 5457 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32, 5458 mkU32(mask))); 5459 5460 return "icmh"; 5461 } 5462 5463 static const HChar * 5464 s390_irgen_IIHF(UChar r1, UInt i2) 5465 { 5466 put_gpr_w0(r1, mkU32(i2)); 5467 5468 return "iihf"; 5469 } 5470 5471 static const HChar * 5472 s390_irgen_IIHH(UChar r1, UShort i2) 5473 { 5474 put_gpr_hw0(r1, mkU16(i2)); 5475 5476 return "iihh"; 5477 } 5478 5479 static const HChar * 5480 s390_irgen_IIHL(UChar r1, UShort i2) 5481 { 5482 put_gpr_hw1(r1, mkU16(i2)); 5483 5484 return "iihl"; 5485 } 5486 5487 static const HChar * 5488 s390_irgen_IILF(UChar r1, UInt i2) 5489 { 5490 put_gpr_w1(r1, mkU32(i2)); 5491 5492 return "iilf"; 5493 } 5494 5495 static const HChar * 5496 s390_irgen_IILH(UChar r1, UShort i2) 5497 { 5498 put_gpr_hw2(r1, mkU16(i2)); 5499 5500 return "iilh"; 5501 } 5502 5503 static const HChar * 5504 s390_irgen_IILL(UChar r1, UShort i2) 5505 { 5506 put_gpr_hw3(r1, mkU16(i2)); 5507 5508 return "iill"; 5509 } 5510 5511 static const HChar * 5512 s390_irgen_LR(UChar r1, UChar r2) 5513 { 5514 put_gpr_w1(r1, get_gpr_w1(r2)); 5515 5516 return "lr"; 5517 } 5518 5519 static const HChar * 5520 s390_irgen_LGR(UChar r1, UChar r2) 5521 { 5522 put_gpr_dw0(r1, get_gpr_dw0(r2)); 5523 5524 return "lgr"; 5525 } 5526 5527 static const HChar * 5528 s390_irgen_LGFR(UChar r1, UChar r2) 5529 { 5530 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2))); 5531 5532 return "lgfr"; 5533 } 5534 5535 static const HChar * 5536 s390_irgen_L(UChar r1, IRTemp op2addr) 5537 { 5538 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr))); 5539 5540 return "l"; 5541 } 5542 5543 static const HChar * 5544 s390_irgen_LY(UChar r1, IRTemp op2addr) 5545 { 5546 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr))); 5547 5548 return "ly"; 5549 } 5550 5551 static const HChar * 5552 s390_irgen_LG(UChar r1, IRTemp op2addr) 5553 { 5554 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr))); 5555 5556 return "lg"; 5557 } 5558 5559 static const HChar * 5560 s390_irgen_LGF(UChar r1, IRTemp op2addr) 5561 { 5562 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr)))); 5563 5564 return "lgf"; 5565 } 5566 5567 static const HChar * 5568 s390_irgen_LGFI(UChar r1, UInt i2) 5569 { 5570 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2)); 5571 5572 return "lgfi"; 5573 } 5574 5575 static const HChar * 5576 s390_irgen_LRL(UChar r1, UInt i2) 5577 { 5578 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int) 5579 i2 << 1)))); 5580 5581 return "lrl"; 5582 } 5583 5584 static const HChar * 5585 s390_irgen_LGRL(UChar r1, UInt i2) 5586 { 5587 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int) 5588 i2 << 1)))); 5589 5590 return "lgrl"; 5591 } 5592 5593 static const HChar * 5594 s390_irgen_LGFRL(UChar r1, UInt i2) 5595 { 5596 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr + 5597 ((ULong)(Long)(Int)i2 << 1))))); 5598 5599 return "lgfrl"; 5600 } 5601 5602 static const HChar * 5603 s390_irgen_LA(UChar r1, IRTemp op2addr) 5604 { 5605 put_gpr_dw0(r1, mkexpr(op2addr)); 5606 5607 return "la"; 5608 } 5609 5610 static const HChar * 5611 s390_irgen_LAY(UChar r1, IRTemp op2addr) 5612 { 5613 put_gpr_dw0(r1, mkexpr(op2addr)); 5614 5615 return "lay"; 5616 } 5617 5618 static const HChar * 5619 s390_irgen_LAE(UChar r1, IRTemp op2addr) 5620 { 5621 put_gpr_dw0(r1, mkexpr(op2addr)); 5622 5623 return "lae"; 5624 } 5625 5626 static const HChar * 5627 s390_irgen_LAEY(UChar r1, IRTemp op2addr) 5628 { 5629 put_gpr_dw0(r1, mkexpr(op2addr)); 5630 5631 return "laey"; 5632 } 5633 5634 static const HChar * 5635 s390_irgen_LARL(UChar r1, UInt i2) 5636 { 5637 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1))); 5638 5639 return "larl"; 5640 } 5641 5642 /* The IR representation of LAA and friends is an approximation of what 5643 happens natively. Essentially a loop containing a compare-and-swap is 5644 constructed which will iterate until the CAS succeeds. As a consequence, 5645 instrumenters may see more memory accesses than happen natively. See also 5646 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */ 5647 static void 5648 s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed) 5649 { 5650 IRCAS *cas; 5651 IRTemp old_mem = newTemp(Ity_I32); 5652 IRTemp op2 = newTemp(Ity_I32); 5653 IRTemp op3 = newTemp(Ity_I32); 5654 IRTemp result = newTemp(Ity_I32); 5655 5656 assign(op2, load(Ity_I32, mkexpr(op2addr))); 5657 assign(op3, get_gpr_w1(r3)); 5658 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3))); 5659 5660 /* Place the addition of second operand and third operand at the 5661 second-operand location everytime */ 5662 cas = mkIRCAS(IRTemp_INVALID, old_mem, 5663 Iend_BE, mkexpr(op2addr), 5664 NULL, mkexpr(op2), /* expected value */ 5665 NULL, mkexpr(result) /* new value */); 5666 stmt(IRStmt_CAS(cas)); 5667 5668 /* Set CC according to 32-bit addition */ 5669 if (is_signed) { 5670 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3); 5671 } else { 5672 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3); 5673 } 5674 5675 /* If old_mem contains the expected value, then the CAS succeeded. 5676 Otherwise, it did not */ 5677 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2))); 5678 put_gpr_w1(r1, mkexpr(old_mem)); 5679 } 5680 5681 static void 5682 s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed) 5683 { 5684 IRCAS *cas; 5685 IRTemp old_mem = newTemp(Ity_I64); 5686 IRTemp op2 = newTemp(Ity_I64); 5687 IRTemp op3 = newTemp(Ity_I64); 5688 IRTemp result = newTemp(Ity_I64); 5689 5690 assign(op2, load(Ity_I64, mkexpr(op2addr))); 5691 assign(op3, get_gpr_dw0(r3)); 5692 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3))); 5693 5694 /* Place the addition of second operand and third operand at the 5695 second-operand location everytime */ 5696 cas = mkIRCAS(IRTemp_INVALID, old_mem, 5697 Iend_BE, mkexpr(op2addr), 5698 NULL, mkexpr(op2), /* expected value */ 5699 NULL, mkexpr(result) /* new value */); 5700 stmt(IRStmt_CAS(cas)); 5701 5702 /* Set CC according to 64-bit addition */ 5703 if (is_signed) { 5704 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3); 5705 } else { 5706 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3); 5707 } 5708 5709 /* If old_mem contains the expected value, then the CAS succeeded. 5710 Otherwise, it did not */ 5711 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2))); 5712 put_gpr_dw0(r1, mkexpr(old_mem)); 5713 } 5714 5715 static void 5716 s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op) 5717 { 5718 IRCAS *cas; 5719 IRTemp old_mem = newTemp(Ity_I32); 5720 IRTemp op2 = newTemp(Ity_I32); 5721 IRTemp op3 = newTemp(Ity_I32); 5722 IRTemp result = newTemp(Ity_I32); 5723 5724 assign(op2, load(Ity_I32, mkexpr(op2addr))); 5725 assign(op3, get_gpr_w1(r3)); 5726 assign(result, binop(op, mkexpr(op2), mkexpr(op3))); 5727 5728 /* Place the addition of second operand and third operand at the 5729 second-operand location everytime */ 5730 cas = mkIRCAS(IRTemp_INVALID, old_mem, 5731 Iend_BE, mkexpr(op2addr), 5732 NULL, mkexpr(op2), /* expected value */ 5733 NULL, mkexpr(result) /* new value */); 5734 stmt(IRStmt_CAS(cas)); 5735 5736 /* Set CC according to bitwise operation */ 5737 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 5738 5739 /* If old_mem contains the expected value, then the CAS succeeded. 5740 Otherwise, it did not */ 5741 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2))); 5742 put_gpr_w1(r1, mkexpr(old_mem)); 5743 } 5744 5745 static void 5746 s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op) 5747 { 5748 IRCAS *cas; 5749 IRTemp old_mem = newTemp(Ity_I64); 5750 IRTemp op2 = newTemp(Ity_I64); 5751 IRTemp op3 = newTemp(Ity_I64); 5752 IRTemp result = newTemp(Ity_I64); 5753 5754 assign(op2, load(Ity_I64, mkexpr(op2addr))); 5755 assign(op3, get_gpr_dw0(r3)); 5756 assign(result, binop(op, mkexpr(op2), mkexpr(op3))); 5757 5758 /* Place the addition of second operand and third operand at the 5759 second-operand location everytime */ 5760 cas = mkIRCAS(IRTemp_INVALID, old_mem, 5761 Iend_BE, mkexpr(op2addr), 5762 NULL, mkexpr(op2), /* expected value */ 5763 NULL, mkexpr(result) /* new value */); 5764 stmt(IRStmt_CAS(cas)); 5765 5766 /* Set CC according to bitwise operation */ 5767 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result); 5768 5769 /* If old_mem contains the expected value, then the CAS succeeded. 5770 Otherwise, it did not */ 5771 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2))); 5772 put_gpr_dw0(r1, mkexpr(old_mem)); 5773 } 5774 5775 static const HChar * 5776 s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr) 5777 { 5778 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */); 5779 5780 return "laa"; 5781 } 5782 5783 static const HChar * 5784 s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr) 5785 { 5786 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */); 5787 5788 return "laag"; 5789 } 5790 5791 static const HChar * 5792 s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr) 5793 { 5794 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */); 5795 5796 return "laal"; 5797 } 5798 5799 static const HChar * 5800 s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr) 5801 { 5802 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */); 5803 5804 return "laalg"; 5805 } 5806 5807 static const HChar * 5808 s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr) 5809 { 5810 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32); 5811 5812 return "lan"; 5813 } 5814 5815 static const HChar * 5816 s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr) 5817 { 5818 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64); 5819 5820 return "lang"; 5821 } 5822 5823 static const HChar * 5824 s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr) 5825 { 5826 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32); 5827 5828 return "lax"; 5829 } 5830 5831 static const HChar * 5832 s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr) 5833 { 5834 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64); 5835 5836 return "laxg"; 5837 } 5838 5839 static const HChar * 5840 s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr) 5841 { 5842 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32); 5843 5844 return "lao"; 5845 } 5846 5847 static const HChar * 5848 s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr) 5849 { 5850 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64); 5851 5852 return "laog"; 5853 } 5854 5855 static const HChar * 5856 s390_irgen_LTR(UChar r1, UChar r2) 5857 { 5858 IRTemp op2 = newTemp(Ity_I32); 5859 5860 assign(op2, get_gpr_w1(r2)); 5861 put_gpr_w1(r1, mkexpr(op2)); 5862 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2); 5863 5864 return "ltr"; 5865 } 5866 5867 static const HChar * 5868 s390_irgen_LTGR(UChar r1, UChar r2) 5869 { 5870 IRTemp op2 = newTemp(Ity_I64); 5871 5872 assign(op2, get_gpr_dw0(r2)); 5873 put_gpr_dw0(r1, mkexpr(op2)); 5874 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2); 5875 5876 return "ltgr"; 5877 } 5878 5879 static const HChar * 5880 s390_irgen_LTGFR(UChar r1, UChar r2) 5881 { 5882 IRTemp op2 = newTemp(Ity_I64); 5883 5884 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2))); 5885 put_gpr_dw0(r1, mkexpr(op2)); 5886 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2); 5887 5888 return "ltgfr"; 5889 } 5890 5891 static const HChar * 5892 s390_irgen_LT(UChar r1, IRTemp op2addr) 5893 { 5894 IRTemp op2 = newTemp(Ity_I32); 5895 5896 assign(op2, load(Ity_I32, mkexpr(op2addr))); 5897 put_gpr_w1(r1, mkexpr(op2)); 5898 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2); 5899 5900 return "lt"; 5901 } 5902 5903 static const HChar * 5904 s390_irgen_LTG(UChar r1, IRTemp op2addr) 5905 { 5906 IRTemp op2 = newTemp(Ity_I64); 5907 5908 assign(op2, load(Ity_I64, mkexpr(op2addr))); 5909 put_gpr_dw0(r1, mkexpr(op2)); 5910 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2); 5911 5912 return "ltg"; 5913 } 5914 5915 static const HChar * 5916 s390_irgen_LTGF(UChar r1, IRTemp op2addr) 5917 { 5918 IRTemp op2 = newTemp(Ity_I64); 5919 5920 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr)))); 5921 put_gpr_dw0(r1, mkexpr(op2)); 5922 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2); 5923 5924 return "ltgf"; 5925 } 5926 5927 static const HChar * 5928 s390_irgen_LBR(UChar r1, UChar r2) 5929 { 5930 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2))); 5931 5932 return "lbr"; 5933 } 5934 5935 static const HChar * 5936 s390_irgen_LGBR(UChar r1, UChar r2) 5937 { 5938 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2))); 5939 5940 return "lgbr"; 5941 } 5942 5943 static const HChar * 5944 s390_irgen_LB(UChar r1, IRTemp op2addr) 5945 { 5946 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr)))); 5947 5948 return "lb"; 5949 } 5950 5951 static const HChar * 5952 s390_irgen_LGB(UChar r1, IRTemp op2addr) 5953 { 5954 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr)))); 5955 5956 return "lgb"; 5957 } 5958 5959 static const HChar * 5960 s390_irgen_LBH(UChar r1, IRTemp op2addr) 5961 { 5962 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr)))); 5963 5964 return "lbh"; 5965 } 5966 5967 static const HChar * 5968 s390_irgen_LCR(UChar r1, UChar r2) 5969 { 5970 Int op1; 5971 IRTemp op2 = newTemp(Ity_I32); 5972 IRTemp result = newTemp(Ity_I32); 5973 5974 op1 = 0; 5975 assign(op2, get_gpr_w1(r2)); 5976 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2))); 5977 put_gpr_w1(r1, mkexpr(result)); 5978 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt) 5979 op1)), op2); 5980 5981 return "lcr"; 5982 } 5983 5984 static const HChar * 5985 s390_irgen_LCGR(UChar r1, UChar r2) 5986 { 5987 Long op1; 5988 IRTemp op2 = newTemp(Ity_I64); 5989 IRTemp result = newTemp(Ity_I64); 5990 5991 op1 = 0ULL; 5992 assign(op2, get_gpr_dw0(r2)); 5993 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2))); 5994 put_gpr_dw0(r1, mkexpr(result)); 5995 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong) 5996 op1)), op2); 5997 5998 return "lcgr"; 5999 } 6000 6001 static const HChar * 6002 s390_irgen_LCGFR(UChar r1, UChar r2) 6003 { 6004 Long op1; 6005 IRTemp op2 = newTemp(Ity_I64); 6006 IRTemp result = newTemp(Ity_I64); 6007 6008 op1 = 0ULL; 6009 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2))); 6010 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2))); 6011 put_gpr_dw0(r1, mkexpr(result)); 6012 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong) 6013 op1)), op2); 6014 6015 return "lcgfr"; 6016 } 6017 6018 static const HChar * 6019 s390_irgen_LHR(UChar r1, UChar r2) 6020 { 6021 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2))); 6022 6023 return "lhr"; 6024 } 6025 6026 static const HChar * 6027 s390_irgen_LGHR(UChar r1, UChar r2) 6028 { 6029 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2))); 6030 6031 return "lghr"; 6032 } 6033 6034 static const HChar * 6035 s390_irgen_LH(UChar r1, IRTemp op2addr) 6036 { 6037 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr)))); 6038 6039 return "lh"; 6040 } 6041 6042 static const HChar * 6043 s390_irgen_LHY(UChar r1, IRTemp op2addr) 6044 { 6045 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr)))); 6046 6047 return "lhy"; 6048 } 6049 6050 static const HChar * 6051 s390_irgen_LGH(UChar r1, IRTemp op2addr) 6052 { 6053 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr)))); 6054 6055 return "lgh"; 6056 } 6057 6058 static const HChar * 6059 s390_irgen_LHI(UChar r1, UShort i2) 6060 { 6061 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2)); 6062 6063 return "lhi"; 6064 } 6065 6066 static const HChar * 6067 s390_irgen_LGHI(UChar r1, UShort i2) 6068 { 6069 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2)); 6070 6071 return "lghi"; 6072 } 6073 6074 static const HChar * 6075 s390_irgen_LHRL(UChar r1, UInt i2) 6076 { 6077 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr + 6078 ((ULong)(Long)(Int)i2 << 1))))); 6079 6080 return "lhrl"; 6081 } 6082 6083 static const HChar * 6084 s390_irgen_LGHRL(UChar r1, UInt i2) 6085 { 6086 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr + 6087 ((ULong)(Long)(Int)i2 << 1))))); 6088 6089 return "lghrl"; 6090 } 6091 6092 static const HChar * 6093 s390_irgen_LHH(UChar r1, IRTemp op2addr) 6094 { 6095 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr)))); 6096 6097 return "lhh"; 6098 } 6099 6100 static const HChar * 6101 s390_irgen_LFH(UChar r1, IRTemp op2addr) 6102 { 6103 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr))); 6104 6105 return "lfh"; 6106 } 6107 6108 static const HChar * 6109 s390_irgen_LLGFR(UChar r1, UChar r2) 6110 { 6111 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2))); 6112 6113 return "llgfr"; 6114 } 6115 6116 static const HChar * 6117 s390_irgen_LLGF(UChar r1, IRTemp op2addr) 6118 { 6119 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr)))); 6120 6121 return "llgf"; 6122 } 6123 6124 static const HChar * 6125 s390_irgen_LLGFRL(UChar r1, UInt i2) 6126 { 6127 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr + 6128 ((ULong)(Long)(Int)i2 << 1))))); 6129 6130 return "llgfrl"; 6131 } 6132 6133 static const HChar * 6134 s390_irgen_LLCR(UChar r1, UChar r2) 6135 { 6136 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2))); 6137 6138 return "llcr"; 6139 } 6140 6141 static const HChar * 6142 s390_irgen_LLGCR(UChar r1, UChar r2) 6143 { 6144 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2))); 6145 6146 return "llgcr"; 6147 } 6148 6149 static const HChar * 6150 s390_irgen_LLC(UChar r1, IRTemp op2addr) 6151 { 6152 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr)))); 6153 6154 return "llc"; 6155 } 6156 6157 static const HChar * 6158 s390_irgen_LLGC(UChar r1, IRTemp op2addr) 6159 { 6160 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr)))); 6161 6162 return "llgc"; 6163 } 6164 6165 static const HChar * 6166 s390_irgen_LLCH(UChar r1, IRTemp op2addr) 6167 { 6168 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr)))); 6169 6170 return "llch"; 6171 } 6172 6173 static const HChar * 6174 s390_irgen_LLHR(UChar r1, UChar r2) 6175 { 6176 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2))); 6177 6178 return "llhr"; 6179 } 6180 6181 static const HChar * 6182 s390_irgen_LLGHR(UChar r1, UChar r2) 6183 { 6184 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2))); 6185 6186 return "llghr"; 6187 } 6188 6189 static const HChar * 6190 s390_irgen_LLH(UChar r1, IRTemp op2addr) 6191 { 6192 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr)))); 6193 6194 return "llh"; 6195 } 6196 6197 static const HChar * 6198 s390_irgen_LLGH(UChar r1, IRTemp op2addr) 6199 { 6200 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr)))); 6201 6202 return "llgh"; 6203 } 6204 6205 static const HChar * 6206 s390_irgen_LLHRL(UChar r1, UInt i2) 6207 { 6208 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr + 6209 ((ULong)(Long)(Int)i2 << 1))))); 6210 6211 return "llhrl"; 6212 } 6213 6214 static const HChar * 6215 s390_irgen_LLGHRL(UChar r1, UInt i2) 6216 { 6217 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr + 6218 ((ULong)(Long)(Int)i2 << 1))))); 6219 6220 return "llghrl"; 6221 } 6222 6223 static const HChar * 6224 s390_irgen_LLHH(UChar r1, IRTemp op2addr) 6225 { 6226 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr)))); 6227 6228 return "llhh"; 6229 } 6230 6231 static const HChar * 6232 s390_irgen_LLIHF(UChar r1, UInt i2) 6233 { 6234 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32)); 6235 6236 return "llihf"; 6237 } 6238 6239 static const HChar * 6240 s390_irgen_LLIHH(UChar r1, UShort i2) 6241 { 6242 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48)); 6243 6244 return "llihh"; 6245 } 6246 6247 static const HChar * 6248 s390_irgen_LLIHL(UChar r1, UShort i2) 6249 { 6250 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32)); 6251 6252 return "llihl"; 6253 } 6254 6255 static const HChar * 6256 s390_irgen_LLILF(UChar r1, UInt i2) 6257 { 6258 put_gpr_dw0(r1, mkU64(i2)); 6259 6260 return "llilf"; 6261 } 6262 6263 static const HChar * 6264 s390_irgen_LLILH(UChar r1, UShort i2) 6265 { 6266 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16)); 6267 6268 return "llilh"; 6269 } 6270 6271 static const HChar * 6272 s390_irgen_LLILL(UChar r1, UShort i2) 6273 { 6274 put_gpr_dw0(r1, mkU64(i2)); 6275 6276 return "llill"; 6277 } 6278 6279 static const HChar * 6280 s390_irgen_LLGTR(UChar r1, UChar r2) 6281 { 6282 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2), 6283 mkU32(2147483647)))); 6284 6285 return "llgtr"; 6286 } 6287 6288 static const HChar * 6289 s390_irgen_LLGT(UChar r1, IRTemp op2addr) 6290 { 6291 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32, 6292 mkexpr(op2addr)), mkU32(2147483647)))); 6293 6294 return "llgt"; 6295 } 6296 6297 static const HChar * 6298 s390_irgen_LNR(UChar r1, UChar r2) 6299 { 6300 IRTemp op2 = newTemp(Ity_I32); 6301 IRTemp result = newTemp(Ity_I32); 6302 6303 assign(op2, get_gpr_w1(r2)); 6304 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2), 6305 binop(Iop_Sub32, mkU32(0), mkexpr(op2)))); 6306 put_gpr_w1(r1, mkexpr(result)); 6307 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result); 6308 6309 return "lnr"; 6310 } 6311 6312 static const HChar * 6313 s390_irgen_LNGR(UChar r1, UChar r2) 6314 { 6315 IRTemp op2 = newTemp(Ity_I64); 6316 IRTemp result = newTemp(Ity_I64); 6317 6318 assign(op2, get_gpr_dw0(r2)); 6319 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2), 6320 binop(Iop_Sub64, mkU64(0), mkexpr(op2)))); 6321 put_gpr_dw0(r1, mkexpr(result)); 6322 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result); 6323 6324 return "lngr"; 6325 } 6326 6327 static const HChar * 6328 s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused))) 6329 { 6330 IRTemp op2 = newTemp(Ity_I64); 6331 IRTemp result = newTemp(Ity_I64); 6332 6333 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1))); 6334 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2), 6335 binop(Iop_Sub64, mkU64(0), mkexpr(op2)))); 6336 put_gpr_dw0(r1, mkexpr(result)); 6337 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result); 6338 6339 return "lngfr"; 6340 } 6341 6342 static const HChar * 6343 s390_irgen_LOCR(UChar m3, UChar r1, UChar r2) 6344 { 6345 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0))); 6346 put_gpr_w1(r1, get_gpr_w1(r2)); 6347 6348 return "locr"; 6349 } 6350 6351 static const HChar * 6352 s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2) 6353 { 6354 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0))); 6355 put_gpr_dw0(r1, get_gpr_dw0(r2)); 6356 6357 return "locgr"; 6358 } 6359 6360 static const HChar * 6361 s390_irgen_LOC(UChar r1, IRTemp op2addr) 6362 { 6363 /* condition is checked in format handler */ 6364 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr))); 6365 6366 return "loc"; 6367 } 6368 6369 static const HChar * 6370 s390_irgen_LOCG(UChar r1, IRTemp op2addr) 6371 { 6372 /* condition is checked in format handler */ 6373 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr))); 6374 6375 return "locg"; 6376 } 6377 6378 static const HChar * 6379 s390_irgen_LPQ(UChar r1, IRTemp op2addr) 6380 { 6381 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr))); 6382 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8)) 6383 )); 6384 6385 return "lpq"; 6386 } 6387 6388 static const HChar * 6389 s390_irgen_LPR(UChar r1, UChar r2) 6390 { 6391 IRTemp op2 = newTemp(Ity_I32); 6392 IRTemp result = newTemp(Ity_I32); 6393 6394 assign(op2, get_gpr_w1(r2)); 6395 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)), 6396 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2))); 6397 put_gpr_w1(r1, mkexpr(result)); 6398 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2); 6399 6400 return "lpr"; 6401 } 6402 6403 static const HChar * 6404 s390_irgen_LPGR(UChar r1, UChar r2) 6405 { 6406 IRTemp op2 = newTemp(Ity_I64); 6407 IRTemp result = newTemp(Ity_I64); 6408 6409 assign(op2, get_gpr_dw0(r2)); 6410 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)), 6411 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2))); 6412 put_gpr_dw0(r1, mkexpr(result)); 6413 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2); 6414 6415 return "lpgr"; 6416 } 6417 6418 static const HChar * 6419 s390_irgen_LPGFR(UChar r1, UChar r2) 6420 { 6421 IRTemp op2 = newTemp(Ity_I64); 6422 IRTemp result = newTemp(Ity_I64); 6423 6424 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2))); 6425 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)), 6426 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2))); 6427 put_gpr_dw0(r1, mkexpr(result)); 6428 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2); 6429 6430 return "lpgfr"; 6431 } 6432 6433 static const HChar * 6434 s390_irgen_LRVR(UChar r1, UChar r2) 6435 { 6436 IRTemp b0 = newTemp(Ity_I8); 6437 IRTemp b1 = newTemp(Ity_I8); 6438 IRTemp b2 = newTemp(Ity_I8); 6439 IRTemp b3 = newTemp(Ity_I8); 6440 6441 assign(b3, get_gpr_b7(r2)); 6442 assign(b2, get_gpr_b6(r2)); 6443 assign(b1, get_gpr_b5(r2)); 6444 assign(b0, get_gpr_b4(r2)); 6445 put_gpr_b4(r1, mkexpr(b3)); 6446 put_gpr_b5(r1, mkexpr(b2)); 6447 put_gpr_b6(r1, mkexpr(b1)); 6448 put_gpr_b7(r1, mkexpr(b0)); 6449 6450 return "lrvr"; 6451 } 6452 6453 static const HChar * 6454 s390_irgen_LRVGR(UChar r1, UChar r2) 6455 { 6456 IRTemp b0 = newTemp(Ity_I8); 6457 IRTemp b1 = newTemp(Ity_I8); 6458 IRTemp b2 = newTemp(Ity_I8); 6459 IRTemp b3 = newTemp(Ity_I8); 6460 IRTemp b4 = newTemp(Ity_I8); 6461 IRTemp b5 = newTemp(Ity_I8); 6462 IRTemp b6 = newTemp(Ity_I8); 6463 IRTemp b7 = newTemp(Ity_I8); 6464 6465 assign(b7, get_gpr_b7(r2)); 6466 assign(b6, get_gpr_b6(r2)); 6467 assign(b5, get_gpr_b5(r2)); 6468 assign(b4, get_gpr_b4(r2)); 6469 assign(b3, get_gpr_b3(r2)); 6470 assign(b2, get_gpr_b2(r2)); 6471 assign(b1, get_gpr_b1(r2)); 6472 assign(b0, get_gpr_b0(r2)); 6473 put_gpr_b0(r1, mkexpr(b7)); 6474 put_gpr_b1(r1, mkexpr(b6)); 6475 put_gpr_b2(r1, mkexpr(b5)); 6476 put_gpr_b3(r1, mkexpr(b4)); 6477 put_gpr_b4(r1, mkexpr(b3)); 6478 put_gpr_b5(r1, mkexpr(b2)); 6479 put_gpr_b6(r1, mkexpr(b1)); 6480 put_gpr_b7(r1, mkexpr(b0)); 6481 6482 return "lrvgr"; 6483 } 6484 6485 static const HChar * 6486 s390_irgen_LRVH(UChar r1, IRTemp op2addr) 6487 { 6488 IRTemp op2 = newTemp(Ity_I16); 6489 6490 assign(op2, load(Ity_I16, mkexpr(op2addr))); 6491 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2))); 6492 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2))); 6493 6494 return "lrvh"; 6495 } 6496 6497 static const HChar * 6498 s390_irgen_LRV(UChar r1, IRTemp op2addr) 6499 { 6500 IRTemp op2 = newTemp(Ity_I32); 6501 6502 assign(op2, load(Ity_I32, mkexpr(op2addr))); 6503 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255)))); 6504 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2), 6505 mkU8(8)), mkU32(255)))); 6506 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2), 6507 mkU8(16)), mkU32(255)))); 6508 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2), 6509 mkU8(24)), mkU32(255)))); 6510 6511 return "lrv"; 6512 } 6513 6514 static const HChar * 6515 s390_irgen_LRVG(UChar r1, IRTemp op2addr) 6516 { 6517 IRTemp op2 = newTemp(Ity_I64); 6518 6519 assign(op2, load(Ity_I64, mkexpr(op2addr))); 6520 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255)))); 6521 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2), 6522 mkU8(8)), mkU64(255)))); 6523 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2), 6524 mkU8(16)), mkU64(255)))); 6525 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2), 6526 mkU8(24)), mkU64(255)))); 6527 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2), 6528 mkU8(32)), mkU64(255)))); 6529 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2), 6530 mkU8(40)), mkU64(255)))); 6531 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2), 6532 mkU8(48)), mkU64(255)))); 6533 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2), 6534 mkU8(56)), mkU64(255)))); 6535 6536 return "lrvg"; 6537 } 6538 6539 static const HChar * 6540 s390_irgen_MVHHI(UShort i2, IRTemp op1addr) 6541 { 6542 store(mkexpr(op1addr), mkU16(i2)); 6543 6544 return "mvhhi"; 6545 } 6546 6547 static const HChar * 6548 s390_irgen_MVHI(UShort i2, IRTemp op1addr) 6549 { 6550 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2)); 6551 6552 return "mvhi"; 6553 } 6554 6555 static const HChar * 6556 s390_irgen_MVGHI(UShort i2, IRTemp op1addr) 6557 { 6558 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2)); 6559 6560 return "mvghi"; 6561 } 6562 6563 static const HChar * 6564 s390_irgen_MVI(UChar i2, IRTemp op1addr) 6565 { 6566 store(mkexpr(op1addr), mkU8(i2)); 6567 6568 return "mvi"; 6569 } 6570 6571 static const HChar * 6572 s390_irgen_MVIY(UChar i2, IRTemp op1addr) 6573 { 6574 store(mkexpr(op1addr), mkU8(i2)); 6575 6576 return "mviy"; 6577 } 6578 6579 static const HChar * 6580 s390_irgen_MR(UChar r1, UChar r2) 6581 { 6582 IRTemp op1 = newTemp(Ity_I32); 6583 IRTemp op2 = newTemp(Ity_I32); 6584 IRTemp result = newTemp(Ity_I64); 6585 6586 assign(op1, get_gpr_w1(r1 + 1)); 6587 assign(op2, get_gpr_w1(r2)); 6588 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2))); 6589 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); 6590 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); 6591 6592 return "mr"; 6593 } 6594 6595 static const HChar * 6596 s390_irgen_M(UChar r1, IRTemp op2addr) 6597 { 6598 IRTemp op1 = newTemp(Ity_I32); 6599 IRTemp op2 = newTemp(Ity_I32); 6600 IRTemp result = newTemp(Ity_I64); 6601 6602 assign(op1, get_gpr_w1(r1 + 1)); 6603 assign(op2, load(Ity_I32, mkexpr(op2addr))); 6604 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2))); 6605 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); 6606 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); 6607 6608 return "m"; 6609 } 6610 6611 static const HChar * 6612 s390_irgen_MFY(UChar r1, IRTemp op2addr) 6613 { 6614 IRTemp op1 = newTemp(Ity_I32); 6615 IRTemp op2 = newTemp(Ity_I32); 6616 IRTemp result = newTemp(Ity_I64); 6617 6618 assign(op1, get_gpr_w1(r1 + 1)); 6619 assign(op2, load(Ity_I32, mkexpr(op2addr))); 6620 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2))); 6621 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); 6622 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); 6623 6624 return "mfy"; 6625 } 6626 6627 static const HChar * 6628 s390_irgen_MH(UChar r1, IRTemp op2addr) 6629 { 6630 IRTemp op1 = newTemp(Ity_I32); 6631 IRTemp op2 = newTemp(Ity_I16); 6632 IRTemp result = newTemp(Ity_I64); 6633 6634 assign(op1, get_gpr_w1(r1)); 6635 assign(op2, load(Ity_I16, mkexpr(op2addr))); 6636 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2)) 6637 )); 6638 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result))); 6639 6640 return "mh"; 6641 } 6642 6643 static const HChar * 6644 s390_irgen_MHY(UChar r1, IRTemp op2addr) 6645 { 6646 IRTemp op1 = newTemp(Ity_I32); 6647 IRTemp op2 = newTemp(Ity_I16); 6648 IRTemp result = newTemp(Ity_I64); 6649 6650 assign(op1, get_gpr_w1(r1)); 6651 assign(op2, load(Ity_I16, mkexpr(op2addr))); 6652 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2)) 6653 )); 6654 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result))); 6655 6656 return "mhy"; 6657 } 6658 6659 static const HChar * 6660 s390_irgen_MHI(UChar r1, UShort i2) 6661 { 6662 IRTemp op1 = newTemp(Ity_I32); 6663 Short op2; 6664 IRTemp result = newTemp(Ity_I64); 6665 6666 assign(op1, get_gpr_w1(r1)); 6667 op2 = (Short)i2; 6668 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, 6669 mkU16((UShort)op2)))); 6670 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result))); 6671 6672 return "mhi"; 6673 } 6674 6675 static const HChar * 6676 s390_irgen_MGHI(UChar r1, UShort i2) 6677 { 6678 IRTemp op1 = newTemp(Ity_I64); 6679 Short op2; 6680 IRTemp result = newTemp(Ity_I128); 6681 6682 assign(op1, get_gpr_dw0(r1)); 6683 op2 = (Short)i2; 6684 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64, 6685 mkU16((UShort)op2)))); 6686 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result))); 6687 6688 return "mghi"; 6689 } 6690 6691 static const HChar * 6692 s390_irgen_MLR(UChar r1, UChar r2) 6693 { 6694 IRTemp op1 = newTemp(Ity_I32); 6695 IRTemp op2 = newTemp(Ity_I32); 6696 IRTemp result = newTemp(Ity_I64); 6697 6698 assign(op1, get_gpr_w1(r1 + 1)); 6699 assign(op2, get_gpr_w1(r2)); 6700 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2))); 6701 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); 6702 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); 6703 6704 return "mlr"; 6705 } 6706 6707 static const HChar * 6708 s390_irgen_MLGR(UChar r1, UChar r2) 6709 { 6710 IRTemp op1 = newTemp(Ity_I64); 6711 IRTemp op2 = newTemp(Ity_I64); 6712 IRTemp result = newTemp(Ity_I128); 6713 6714 assign(op1, get_gpr_dw0(r1 + 1)); 6715 assign(op2, get_gpr_dw0(r2)); 6716 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2))); 6717 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); 6718 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); 6719 6720 return "mlgr"; 6721 } 6722 6723 static const HChar * 6724 s390_irgen_ML(UChar r1, IRTemp op2addr) 6725 { 6726 IRTemp op1 = newTemp(Ity_I32); 6727 IRTemp op2 = newTemp(Ity_I32); 6728 IRTemp result = newTemp(Ity_I64); 6729 6730 assign(op1, get_gpr_w1(r1 + 1)); 6731 assign(op2, load(Ity_I32, mkexpr(op2addr))); 6732 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2))); 6733 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); 6734 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); 6735