1 /* 2 * S/390 translation 3 * 4 * Copyright (c) 2009 Ulrich Hecht 5 * Copyright (c) 2010 Alexander Graf 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 /* #define DEBUG_INLINE_BRANCHES */ 22 #define S390X_DEBUG_DISAS 23 /* #define S390X_DEBUG_DISAS_VERBOSE */ 24 25 #ifdef S390X_DEBUG_DISAS_VERBOSE 26 # define LOG_DISAS(...) qemu_log(__VA_ARGS__) 27 #else 28 # define LOG_DISAS(...) do { } while (0) 29 #endif 30 31 #include "qemu/osdep.h" 32 #include "cpu.h" 33 #include "s390x-internal.h" 34 #include "disas/disas.h" 35 #include "exec/exec-all.h" 36 #include "tcg/tcg-op.h" 37 #include "tcg/tcg-op-gvec.h" 38 #include "qemu/log.h" 39 #include "qemu/host-utils.h" 40 #include "exec/cpu_ldst.h" 41 #include "exec/gen-icount.h" 42 #include "exec/helper-proto.h" 43 #include "exec/helper-gen.h" 44 45 #include "exec/translator.h" 46 #include "exec/log.h" 47 #include "qemu/atomic128.h" 48 49 50 /* Information that (most) every instruction needs to manipulate. */ 51 typedef struct DisasContext DisasContext; 52 typedef struct DisasInsn DisasInsn; 53 typedef struct DisasFields DisasFields; 54 55 /* 56 * Define a structure to hold the decoded fields. We'll store each inside 57 * an array indexed by an enum. In order to conserve memory, we'll arrange 58 * for fields that do not exist at the same time to overlap, thus the "C" 59 * for compact. For checking purposes there is an "O" for original index 60 * as well that will be applied to availability bitmaps. 61 */ 62 63 enum DisasFieldIndexO { 64 FLD_O_r1, 65 FLD_O_r2, 66 FLD_O_r3, 67 FLD_O_m1, 68 FLD_O_m3, 69 FLD_O_m4, 70 FLD_O_m5, 71 FLD_O_m6, 72 FLD_O_b1, 73 FLD_O_b2, 74 FLD_O_b4, 75 FLD_O_d1, 76 FLD_O_d2, 77 FLD_O_d4, 78 FLD_O_x2, 79 FLD_O_l1, 80 FLD_O_l2, 81 FLD_O_i1, 82 FLD_O_i2, 83 FLD_O_i3, 84 FLD_O_i4, 85 FLD_O_i5, 86 FLD_O_v1, 87 FLD_O_v2, 88 FLD_O_v3, 89 FLD_O_v4, 90 }; 91 92 enum DisasFieldIndexC { 93 FLD_C_r1 = 0, 94 FLD_C_m1 = 0, 95 FLD_C_b1 = 0, 96 FLD_C_i1 = 0, 97 FLD_C_v1 = 0, 98 99 FLD_C_r2 = 1, 100 FLD_C_b2 = 1, 101 FLD_C_i2 = 1, 102 103 FLD_C_r3 = 2, 104 FLD_C_m3 = 2, 105 FLD_C_i3 = 2, 106 FLD_C_v3 = 2, 107 108 FLD_C_m4 = 3, 109 FLD_C_b4 = 3, 110 FLD_C_i4 = 3, 111 FLD_C_l1 = 3, 112 FLD_C_v4 = 3, 113 114 FLD_C_i5 = 4, 115 FLD_C_d1 = 4, 116 FLD_C_m5 = 4, 117 118 FLD_C_d2 = 5, 119 FLD_C_m6 = 5, 120 121 FLD_C_d4 = 6, 122 FLD_C_x2 = 6, 123 FLD_C_l2 = 6, 124 FLD_C_v2 = 6, 125 126 NUM_C_FIELD = 7 127 }; 128 129 struct DisasFields { 130 uint64_t raw_insn; 131 unsigned op:8; 132 unsigned op2:8; 133 unsigned presentC:16; 134 unsigned int presentO; 135 int c[NUM_C_FIELD]; 136 }; 137 138 struct DisasContext { 139 DisasContextBase base; 140 const DisasInsn *insn; 141 DisasFields fields; 142 uint64_t ex_value; 143 /* 144 * During translate_one(), pc_tmp is used to determine the instruction 145 * to be executed after base.pc_next - e.g. next sequential instruction 146 * or a branch target. 147 */ 148 uint64_t pc_tmp; 149 uint32_t ilen; 150 enum cc_op cc_op; 151 bool do_debug; 152 }; 153 154 /* Information carried about a condition to be evaluated. */ 155 typedef struct { 156 TCGCond cond:8; 157 bool is_64; 158 bool g1; 159 bool g2; 160 union { 161 struct { TCGv_i64 a, b; } s64; 162 struct { TCGv_i32 a, b; } s32; 163 } u; 164 } DisasCompare; 165 166 #ifdef DEBUG_INLINE_BRANCHES 167 static uint64_t inline_branch_hit[CC_OP_MAX]; 168 static uint64_t inline_branch_miss[CC_OP_MAX]; 169 #endif 170 171 static void pc_to_link_info(TCGv_i64 out, DisasContext *s, uint64_t pc) 172 { 173 TCGv_i64 tmp; 174 175 if (s->base.tb->flags & FLAG_MASK_32) { 176 if (s->base.tb->flags & FLAG_MASK_64) { 177 tcg_gen_movi_i64(out, pc); 178 return; 179 } 180 pc |= 0x80000000; 181 } 182 assert(!(s->base.tb->flags & FLAG_MASK_64)); 183 tmp = tcg_const_i64(pc); 184 tcg_gen_deposit_i64(out, out, tmp, 0, 32); 185 tcg_temp_free_i64(tmp); 186 } 187 188 static TCGv_i64 psw_addr; 189 static TCGv_i64 psw_mask; 190 static TCGv_i64 gbea; 191 192 static TCGv_i32 cc_op; 193 static TCGv_i64 cc_src; 194 static TCGv_i64 cc_dst; 195 static TCGv_i64 cc_vr; 196 197 static char cpu_reg_names[16][4]; 198 static TCGv_i64 regs[16]; 199 200 void s390x_translate_init(void) 201 { 202 int i; 203 204 psw_addr = tcg_global_mem_new_i64(cpu_env, 205 offsetof(CPUS390XState, psw.addr), 206 "psw_addr"); 207 psw_mask = tcg_global_mem_new_i64(cpu_env, 208 offsetof(CPUS390XState, psw.mask), 209 "psw_mask"); 210 gbea = tcg_global_mem_new_i64(cpu_env, 211 offsetof(CPUS390XState, gbea), 212 "gbea"); 213 214 cc_op = tcg_global_mem_new_i32(cpu_env, offsetof(CPUS390XState, cc_op), 215 "cc_op"); 216 cc_src = tcg_global_mem_new_i64(cpu_env, offsetof(CPUS390XState, cc_src), 217 "cc_src"); 218 cc_dst = tcg_global_mem_new_i64(cpu_env, offsetof(CPUS390XState, cc_dst), 219 "cc_dst"); 220 cc_vr = tcg_global_mem_new_i64(cpu_env, offsetof(CPUS390XState, cc_vr), 221 "cc_vr"); 222 223 for (i = 0; i < 16; i++) { 224 snprintf(cpu_reg_names[i], sizeof(cpu_reg_names[0]), "r%d", i); 225 regs[i] = tcg_global_mem_new(cpu_env, 226 offsetof(CPUS390XState, regs[i]), 227 cpu_reg_names[i]); 228 } 229 } 230 231 static inline int vec_full_reg_offset(uint8_t reg) 232 { 233 g_assert(reg < 32); 234 return offsetof(CPUS390XState, vregs[reg][0]); 235 } 236 237 static inline int vec_reg_offset(uint8_t reg, uint8_t enr, MemOp es) 238 { 239 /* Convert element size (es) - e.g. MO_8 - to bytes */ 240 const uint8_t bytes = 1 << es; 241 int offs = enr * bytes; 242 243 /* 244 * vregs[n][0] is the lowest 8 byte and vregs[n][1] the highest 8 byte 245 * of the 16 byte vector, on both, little and big endian systems. 246 * 247 * Big Endian (target/possible host) 248 * B: [ 0][ 1][ 2][ 3][ 4][ 5][ 6][ 7] - [ 8][ 9][10][11][12][13][14][15] 249 * HW: [ 0][ 1][ 2][ 3] - [ 4][ 5][ 6][ 7] 250 * W: [ 0][ 1] - [ 2][ 3] 251 * DW: [ 0] - [ 1] 252 * 253 * Little Endian (possible host) 254 * B: [ 7][ 6][ 5][ 4][ 3][ 2][ 1][ 0] - [15][14][13][12][11][10][ 9][ 8] 255 * HW: [ 3][ 2][ 1][ 0] - [ 7][ 6][ 5][ 4] 256 * W: [ 1][ 0] - [ 3][ 2] 257 * DW: [ 0] - [ 1] 258 * 259 * For 16 byte elements, the two 8 byte halves will not form a host 260 * int128 if the host is little endian, since they're in the wrong order. 261 * Some operations (e.g. xor) do not care. For operations like addition, 262 * the two 8 byte elements have to be loaded separately. Let's force all 263 * 16 byte operations to handle it in a special way. 264 */ 265 g_assert(es <= MO_64); 266 #ifndef HOST_WORDS_BIGENDIAN 267 offs ^= (8 - bytes); 268 #endif 269 return offs + vec_full_reg_offset(reg); 270 } 271 272 static inline int freg64_offset(uint8_t reg) 273 { 274 g_assert(reg < 16); 275 return vec_reg_offset(reg, 0, MO_64); 276 } 277 278 static inline int freg32_offset(uint8_t reg) 279 { 280 g_assert(reg < 16); 281 return vec_reg_offset(reg, 0, MO_32); 282 } 283 284 static TCGv_i64 load_reg(int reg) 285 { 286 TCGv_i64 r = tcg_temp_new_i64(); 287 tcg_gen_mov_i64(r, regs[reg]); 288 return r; 289 } 290 291 static TCGv_i64 load_freg(int reg) 292 { 293 TCGv_i64 r = tcg_temp_new_i64(); 294 295 tcg_gen_ld_i64(r, cpu_env, freg64_offset(reg)); 296 return r; 297 } 298 299 static TCGv_i64 load_freg32_i64(int reg) 300 { 301 TCGv_i64 r = tcg_temp_new_i64(); 302 303 tcg_gen_ld32u_i64(r, cpu_env, freg32_offset(reg)); 304 return r; 305 } 306 307 static void store_reg(int reg, TCGv_i64 v) 308 { 309 tcg_gen_mov_i64(regs[reg], v); 310 } 311 312 static void store_freg(int reg, TCGv_i64 v) 313 { 314 tcg_gen_st_i64(v, cpu_env, freg64_offset(reg)); 315 } 316 317 static void store_reg32_i64(int reg, TCGv_i64 v) 318 { 319 /* 32 bit register writes keep the upper half */ 320 tcg_gen_deposit_i64(regs[reg], regs[reg], v, 0, 32); 321 } 322 323 static void store_reg32h_i64(int reg, TCGv_i64 v) 324 { 325 tcg_gen_deposit_i64(regs[reg], regs[reg], v, 32, 32); 326 } 327 328 static void store_freg32_i64(int reg, TCGv_i64 v) 329 { 330 tcg_gen_st32_i64(v, cpu_env, freg32_offset(reg)); 331 } 332 333 static void return_low128(TCGv_i64 dest) 334 { 335 tcg_gen_ld_i64(dest, cpu_env, offsetof(CPUS390XState, retxl)); 336 } 337 338 static void update_psw_addr(DisasContext *s) 339 { 340 /* psw.addr */ 341 tcg_gen_movi_i64(psw_addr, s->base.pc_next); 342 } 343 344 static void per_branch(DisasContext *s, bool to_next) 345 { 346 #ifndef CONFIG_USER_ONLY 347 tcg_gen_movi_i64(gbea, s->base.pc_next); 348 349 if (s->base.tb->flags & FLAG_MASK_PER) { 350 TCGv_i64 next_pc = to_next ? tcg_const_i64(s->pc_tmp) : psw_addr; 351 gen_helper_per_branch(cpu_env, gbea, next_pc); 352 if (to_next) { 353 tcg_temp_free_i64(next_pc); 354 } 355 } 356 #endif 357 } 358 359 static void per_branch_cond(DisasContext *s, TCGCond cond, 360 TCGv_i64 arg1, TCGv_i64 arg2) 361 { 362 #ifndef CONFIG_USER_ONLY 363 if (s->base.tb->flags & FLAG_MASK_PER) { 364 TCGLabel *lab = gen_new_label(); 365 tcg_gen_brcond_i64(tcg_invert_cond(cond), arg1, arg2, lab); 366 367 tcg_gen_movi_i64(gbea, s->base.pc_next); 368 gen_helper_per_branch(cpu_env, gbea, psw_addr); 369 370 gen_set_label(lab); 371 } else { 372 TCGv_i64 pc = tcg_const_i64(s->base.pc_next); 373 tcg_gen_movcond_i64(cond, gbea, arg1, arg2, gbea, pc); 374 tcg_temp_free_i64(pc); 375 } 376 #endif 377 } 378 379 static void per_breaking_event(DisasContext *s) 380 { 381 tcg_gen_movi_i64(gbea, s->base.pc_next); 382 } 383 384 static void update_cc_op(DisasContext *s) 385 { 386 if (s->cc_op != CC_OP_DYNAMIC && s->cc_op != CC_OP_STATIC) { 387 tcg_gen_movi_i32(cc_op, s->cc_op); 388 } 389 } 390 391 static inline uint64_t ld_code2(CPUS390XState *env, uint64_t pc) 392 { 393 return (uint64_t)cpu_lduw_code(env, pc); 394 } 395 396 static inline uint64_t ld_code4(CPUS390XState *env, uint64_t pc) 397 { 398 return (uint64_t)(uint32_t)cpu_ldl_code(env, pc); 399 } 400 401 static int get_mem_index(DisasContext *s) 402 { 403 #ifdef CONFIG_USER_ONLY 404 return MMU_USER_IDX; 405 #else 406 if (!(s->base.tb->flags & FLAG_MASK_DAT)) { 407 return MMU_REAL_IDX; 408 } 409 410 switch (s->base.tb->flags & FLAG_MASK_ASC) { 411 case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT: 412 return MMU_PRIMARY_IDX; 413 case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT: 414 return MMU_SECONDARY_IDX; 415 case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT: 416 return MMU_HOME_IDX; 417 default: 418 tcg_abort(); 419 break; 420 } 421 #endif 422 } 423 424 static void gen_exception(int excp) 425 { 426 TCGv_i32 tmp = tcg_const_i32(excp); 427 gen_helper_exception(cpu_env, tmp); 428 tcg_temp_free_i32(tmp); 429 } 430 431 static void gen_program_exception(DisasContext *s, int code) 432 { 433 TCGv_i32 tmp; 434 435 /* Remember what pgm exeption this was. */ 436 tmp = tcg_const_i32(code); 437 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUS390XState, int_pgm_code)); 438 tcg_temp_free_i32(tmp); 439 440 tmp = tcg_const_i32(s->ilen); 441 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUS390XState, int_pgm_ilen)); 442 tcg_temp_free_i32(tmp); 443 444 /* update the psw */ 445 update_psw_addr(s); 446 447 /* Save off cc. */ 448 update_cc_op(s); 449 450 /* Trigger exception. */ 451 gen_exception(EXCP_PGM); 452 } 453 454 static inline void gen_illegal_opcode(DisasContext *s) 455 { 456 gen_program_exception(s, PGM_OPERATION); 457 } 458 459 static inline void gen_data_exception(uint8_t dxc) 460 { 461 TCGv_i32 tmp = tcg_const_i32(dxc); 462 gen_helper_data_exception(cpu_env, tmp); 463 tcg_temp_free_i32(tmp); 464 } 465 466 static inline void gen_trap(DisasContext *s) 467 { 468 /* Set DXC to 0xff */ 469 gen_data_exception(0xff); 470 } 471 472 static void gen_addi_and_wrap_i64(DisasContext *s, TCGv_i64 dst, TCGv_i64 src, 473 int64_t imm) 474 { 475 tcg_gen_addi_i64(dst, src, imm); 476 if (!(s->base.tb->flags & FLAG_MASK_64)) { 477 if (s->base.tb->flags & FLAG_MASK_32) { 478 tcg_gen_andi_i64(dst, dst, 0x7fffffff); 479 } else { 480 tcg_gen_andi_i64(dst, dst, 0x00ffffff); 481 } 482 } 483 } 484 485 static TCGv_i64 get_address(DisasContext *s, int x2, int b2, int d2) 486 { 487 TCGv_i64 tmp = tcg_temp_new_i64(); 488 489 /* 490 * Note that d2 is limited to 20 bits, signed. If we crop negative 491 * displacements early we create larger immedate addends. 492 */ 493 if (b2 && x2) { 494 tcg_gen_add_i64(tmp, regs[b2], regs[x2]); 495 gen_addi_and_wrap_i64(s, tmp, tmp, d2); 496 } else if (b2) { 497 gen_addi_and_wrap_i64(s, tmp, regs[b2], d2); 498 } else if (x2) { 499 gen_addi_and_wrap_i64(s, tmp, regs[x2], d2); 500 } else if (!(s->base.tb->flags & FLAG_MASK_64)) { 501 if (s->base.tb->flags & FLAG_MASK_32) { 502 tcg_gen_movi_i64(tmp, d2 & 0x7fffffff); 503 } else { 504 tcg_gen_movi_i64(tmp, d2 & 0x00ffffff); 505 } 506 } else { 507 tcg_gen_movi_i64(tmp, d2); 508 } 509 510 return tmp; 511 } 512 513 static inline bool live_cc_data(DisasContext *s) 514 { 515 return (s->cc_op != CC_OP_DYNAMIC 516 && s->cc_op != CC_OP_STATIC 517 && s->cc_op > 3); 518 } 519 520 static inline void gen_op_movi_cc(DisasContext *s, uint32_t val) 521 { 522 if (live_cc_data(s)) { 523 tcg_gen_discard_i64(cc_src); 524 tcg_gen_discard_i64(cc_dst); 525 tcg_gen_discard_i64(cc_vr); 526 } 527 s->cc_op = CC_OP_CONST0 + val; 528 } 529 530 static void gen_op_update1_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 dst) 531 { 532 if (live_cc_data(s)) { 533 tcg_gen_discard_i64(cc_src); 534 tcg_gen_discard_i64(cc_vr); 535 } 536 tcg_gen_mov_i64(cc_dst, dst); 537 s->cc_op = op; 538 } 539 540 static void gen_op_update2_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src, 541 TCGv_i64 dst) 542 { 543 if (live_cc_data(s)) { 544 tcg_gen_discard_i64(cc_vr); 545 } 546 tcg_gen_mov_i64(cc_src, src); 547 tcg_gen_mov_i64(cc_dst, dst); 548 s->cc_op = op; 549 } 550 551 static void gen_op_update3_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src, 552 TCGv_i64 dst, TCGv_i64 vr) 553 { 554 tcg_gen_mov_i64(cc_src, src); 555 tcg_gen_mov_i64(cc_dst, dst); 556 tcg_gen_mov_i64(cc_vr, vr); 557 s->cc_op = op; 558 } 559 560 static void set_cc_nz_u64(DisasContext *s, TCGv_i64 val) 561 { 562 gen_op_update1_cc_i64(s, CC_OP_NZ, val); 563 } 564 565 /* CC value is in env->cc_op */ 566 static void set_cc_static(DisasContext *s) 567 { 568 if (live_cc_data(s)) { 569 tcg_gen_discard_i64(cc_src); 570 tcg_gen_discard_i64(cc_dst); 571 tcg_gen_discard_i64(cc_vr); 572 } 573 s->cc_op = CC_OP_STATIC; 574 } 575 576 /* calculates cc into cc_op */ 577 static void gen_op_calc_cc(DisasContext *s) 578 { 579 TCGv_i32 local_cc_op = NULL; 580 TCGv_i64 dummy = NULL; 581 582 switch (s->cc_op) { 583 default: 584 dummy = tcg_const_i64(0); 585 /* FALLTHRU */ 586 case CC_OP_ADD_64: 587 case CC_OP_SUB_64: 588 case CC_OP_ADD_32: 589 case CC_OP_SUB_32: 590 local_cc_op = tcg_const_i32(s->cc_op); 591 break; 592 case CC_OP_CONST0: 593 case CC_OP_CONST1: 594 case CC_OP_CONST2: 595 case CC_OP_CONST3: 596 case CC_OP_STATIC: 597 case CC_OP_DYNAMIC: 598 break; 599 } 600 601 switch (s->cc_op) { 602 case CC_OP_CONST0: 603 case CC_OP_CONST1: 604 case CC_OP_CONST2: 605 case CC_OP_CONST3: 606 /* s->cc_op is the cc value */ 607 tcg_gen_movi_i32(cc_op, s->cc_op - CC_OP_CONST0); 608 break; 609 case CC_OP_STATIC: 610 /* env->cc_op already is the cc value */ 611 break; 612 case CC_OP_NZ: 613 case CC_OP_ABS_64: 614 case CC_OP_NABS_64: 615 case CC_OP_ABS_32: 616 case CC_OP_NABS_32: 617 case CC_OP_LTGT0_32: 618 case CC_OP_LTGT0_64: 619 case CC_OP_COMP_32: 620 case CC_OP_COMP_64: 621 case CC_OP_NZ_F32: 622 case CC_OP_NZ_F64: 623 case CC_OP_FLOGR: 624 case CC_OP_LCBB: 625 case CC_OP_MULS_32: 626 /* 1 argument */ 627 gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, dummy, cc_dst, dummy); 628 break; 629 case CC_OP_ADDU: 630 case CC_OP_ICM: 631 case CC_OP_LTGT_32: 632 case CC_OP_LTGT_64: 633 case CC_OP_LTUGTU_32: 634 case CC_OP_LTUGTU_64: 635 case CC_OP_TM_32: 636 case CC_OP_TM_64: 637 case CC_OP_SLA_32: 638 case CC_OP_SLA_64: 639 case CC_OP_SUBU: 640 case CC_OP_NZ_F128: 641 case CC_OP_VC: 642 case CC_OP_MULS_64: 643 /* 2 arguments */ 644 gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, dummy); 645 break; 646 case CC_OP_ADD_64: 647 case CC_OP_SUB_64: 648 case CC_OP_ADD_32: 649 case CC_OP_SUB_32: 650 /* 3 arguments */ 651 gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, cc_vr); 652 break; 653 case CC_OP_DYNAMIC: 654 /* unknown operation - assume 3 arguments and cc_op in env */ 655 gen_helper_calc_cc(cc_op, cpu_env, cc_op, cc_src, cc_dst, cc_vr); 656 break; 657 default: 658 tcg_abort(); 659 } 660 661 if (local_cc_op) { 662 tcg_temp_free_i32(local_cc_op); 663 } 664 if (dummy) { 665 tcg_temp_free_i64(dummy); 666 } 667 668 /* We now have cc in cc_op as constant */ 669 set_cc_static(s); 670 } 671 672 static bool use_goto_tb(DisasContext *s, uint64_t dest) 673 { 674 if (unlikely(s->base.tb->flags & FLAG_MASK_PER)) { 675 return false; 676 } 677 return translator_use_goto_tb(&s->base, dest); 678 } 679 680 static void account_noninline_branch(DisasContext *s, int cc_op) 681 { 682 #ifdef DEBUG_INLINE_BRANCHES 683 inline_branch_miss[cc_op]++; 684 #endif 685 } 686 687 static void account_inline_branch(DisasContext *s, int cc_op) 688 { 689 #ifdef DEBUG_INLINE_BRANCHES 690 inline_branch_hit[cc_op]++; 691 #endif 692 } 693 694 /* Table of mask values to comparison codes, given a comparison as input. 695 For such, CC=3 should not be possible. */ 696 static const TCGCond ltgt_cond[16] = { 697 TCG_COND_NEVER, TCG_COND_NEVER, /* | | | x */ 698 TCG_COND_GT, TCG_COND_GT, /* | | GT | x */ 699 TCG_COND_LT, TCG_COND_LT, /* | LT | | x */ 700 TCG_COND_NE, TCG_COND_NE, /* | LT | GT | x */ 701 TCG_COND_EQ, TCG_COND_EQ, /* EQ | | | x */ 702 TCG_COND_GE, TCG_COND_GE, /* EQ | | GT | x */ 703 TCG_COND_LE, TCG_COND_LE, /* EQ | LT | | x */ 704 TCG_COND_ALWAYS, TCG_COND_ALWAYS, /* EQ | LT | GT | x */ 705 }; 706 707 /* Table of mask values to comparison codes, given a logic op as input. 708 For such, only CC=0 and CC=1 should be possible. */ 709 static const TCGCond nz_cond[16] = { 710 TCG_COND_NEVER, TCG_COND_NEVER, /* | | x | x */ 711 TCG_COND_NEVER, TCG_COND_NEVER, 712 TCG_COND_NE, TCG_COND_NE, /* | NE | x | x */ 713 TCG_COND_NE, TCG_COND_NE, 714 TCG_COND_EQ, TCG_COND_EQ, /* EQ | | x | x */ 715 TCG_COND_EQ, TCG_COND_EQ, 716 TCG_COND_ALWAYS, TCG_COND_ALWAYS, /* EQ | NE | x | x */ 717 TCG_COND_ALWAYS, TCG_COND_ALWAYS, 718 }; 719 720 /* Interpret MASK in terms of S->CC_OP, and fill in C with all the 721 details required to generate a TCG comparison. */ 722 static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask) 723 { 724 TCGCond cond; 725 enum cc_op old_cc_op = s->cc_op; 726 727 if (mask == 15 || mask == 0) { 728 c->cond = (mask ? TCG_COND_ALWAYS : TCG_COND_NEVER); 729 c->u.s32.a = cc_op; 730 c->u.s32.b = cc_op; 731 c->g1 = c->g2 = true; 732 c->is_64 = false; 733 return; 734 } 735 736 /* Find the TCG condition for the mask + cc op. */ 737 switch (old_cc_op) { 738 case CC_OP_LTGT0_32: 739 case CC_OP_LTGT0_64: 740 case CC_OP_LTGT_32: 741 case CC_OP_LTGT_64: 742 cond = ltgt_cond[mask]; 743 if (cond == TCG_COND_NEVER) { 744 goto do_dynamic; 745 } 746 account_inline_branch(s, old_cc_op); 747 break; 748 749 case CC_OP_LTUGTU_32: 750 case CC_OP_LTUGTU_64: 751 cond = tcg_unsigned_cond(ltgt_cond[mask]); 752 if (cond == TCG_COND_NEVER) { 753 goto do_dynamic; 754 } 755 account_inline_branch(s, old_cc_op); 756 break; 757 758 case CC_OP_NZ: 759 cond = nz_cond[mask]; 760 if (cond == TCG_COND_NEVER) { 761 goto do_dynamic; 762 } 763 account_inline_branch(s, old_cc_op); 764 break; 765 766 case CC_OP_TM_32: 767 case CC_OP_TM_64: 768 switch (mask) { 769 case 8: 770 cond = TCG_COND_EQ; 771 break; 772 case 4 | 2 | 1: 773 cond = TCG_COND_NE; 774 break; 775 default: 776 goto do_dynamic; 777 } 778 account_inline_branch(s, old_cc_op); 779 break; 780 781 case CC_OP_ICM: 782 switch (mask) { 783 case 8: 784 cond = TCG_COND_EQ; 785 break; 786 case 4 | 2 | 1: 787 case 4 | 2: 788 cond = TCG_COND_NE; 789 break; 790 default: 791 goto do_dynamic; 792 } 793 account_inline_branch(s, old_cc_op); 794 break; 795 796 case CC_OP_FLOGR: 797 switch (mask & 0xa) { 798 case 8: /* src == 0 -> no one bit found */ 799 cond = TCG_COND_EQ; 800 break; 801 case 2: /* src != 0 -> one bit found */ 802 cond = TCG_COND_NE; 803 break; 804 default: 805 goto do_dynamic; 806 } 807 account_inline_branch(s, old_cc_op); 808 break; 809 810 case CC_OP_ADDU: 811 case CC_OP_SUBU: 812 switch (mask) { 813 case 8 | 2: /* result == 0 */ 814 cond = TCG_COND_EQ; 815 break; 816 case 4 | 1: /* result != 0 */ 817 cond = TCG_COND_NE; 818 break; 819 case 8 | 4: /* !carry (borrow) */ 820 cond = old_cc_op == CC_OP_ADDU ? TCG_COND_EQ : TCG_COND_NE; 821 break; 822 case 2 | 1: /* carry (!borrow) */ 823 cond = old_cc_op == CC_OP_ADDU ? TCG_COND_NE : TCG_COND_EQ; 824 break; 825 default: 826 goto do_dynamic; 827 } 828 account_inline_branch(s, old_cc_op); 829 break; 830 831 default: 832 do_dynamic: 833 /* Calculate cc value. */ 834 gen_op_calc_cc(s); 835 /* FALLTHRU */ 836 837 case CC_OP_STATIC: 838 /* Jump based on CC. We'll load up the real cond below; 839 the assignment here merely avoids a compiler warning. */ 840 account_noninline_branch(s, old_cc_op); 841 old_cc_op = CC_OP_STATIC; 842 cond = TCG_COND_NEVER; 843 break; 844 } 845 846 /* Load up the arguments of the comparison. */ 847 c->is_64 = true; 848 c->g1 = c->g2 = false; 849 switch (old_cc_op) { 850 case CC_OP_LTGT0_32: 851 c->is_64 = false; 852 c->u.s32.a = tcg_temp_new_i32(); 853 tcg_gen_extrl_i64_i32(c->u.s32.a, cc_dst); 854 c->u.s32.b = tcg_const_i32(0); 855 break; 856 case CC_OP_LTGT_32: 857 case CC_OP_LTUGTU_32: 858 c->is_64 = false; 859 c->u.s32.a = tcg_temp_new_i32(); 860 tcg_gen_extrl_i64_i32(c->u.s32.a, cc_src); 861 c->u.s32.b = tcg_temp_new_i32(); 862 tcg_gen_extrl_i64_i32(c->u.s32.b, cc_dst); 863 break; 864 865 case CC_OP_LTGT0_64: 866 case CC_OP_NZ: 867 case CC_OP_FLOGR: 868 c->u.s64.a = cc_dst; 869 c->u.s64.b = tcg_const_i64(0); 870 c->g1 = true; 871 break; 872 case CC_OP_LTGT_64: 873 case CC_OP_LTUGTU_64: 874 c->u.s64.a = cc_src; 875 c->u.s64.b = cc_dst; 876 c->g1 = c->g2 = true; 877 break; 878 879 case CC_OP_TM_32: 880 case CC_OP_TM_64: 881 case CC_OP_ICM: 882 c->u.s64.a = tcg_temp_new_i64(); 883 c->u.s64.b = tcg_const_i64(0); 884 tcg_gen_and_i64(c->u.s64.a, cc_src, cc_dst); 885 break; 886 887 case CC_OP_ADDU: 888 case CC_OP_SUBU: 889 c->is_64 = true; 890 c->u.s64.b = tcg_const_i64(0); 891 c->g1 = true; 892 switch (mask) { 893 case 8 | 2: 894 case 4 | 1: /* result */ 895 c->u.s64.a = cc_dst; 896 break; 897 case 8 | 4: 898 case 2 | 1: /* carry */ 899 c->u.s64.a = cc_src; 900 break; 901 default: 902 g_assert_not_reached(); 903 } 904 break; 905 906 case CC_OP_STATIC: 907 c->is_64 = false; 908 c->u.s32.a = cc_op; 909 c->g1 = true; 910 switch (mask) { 911 case 0x8 | 0x4 | 0x2: /* cc != 3 */ 912 cond = TCG_COND_NE; 913 c->u.s32.b = tcg_const_i32(3); 914 break; 915 case 0x8 | 0x4 | 0x1: /* cc != 2 */ 916 cond = TCG_COND_NE; 917 c->u.s32.b = tcg_const_i32(2); 918 break; 919 case 0x8 | 0x2 | 0x1: /* cc != 1 */ 920 cond = TCG_COND_NE; 921 c->u.s32.b = tcg_const_i32(1); 922 break; 923 case 0x8 | 0x2: /* cc == 0 || cc == 2 => (cc & 1) == 0 */ 924 cond = TCG_COND_EQ; 925 c->g1 = false; 926 c->u.s32.a = tcg_temp_new_i32(); 927 c->u.s32.b = tcg_const_i32(0); 928 tcg_gen_andi_i32(c->u.s32.a, cc_op, 1); 929 break; 930 case 0x8 | 0x4: /* cc < 2 */ 931 cond = TCG_COND_LTU; 932 c->u.s32.b = tcg_const_i32(2); 933 break; 934 case 0x8: /* cc == 0 */ 935 cond = TCG_COND_EQ; 936 c->u.s32.b = tcg_const_i32(0); 937 break; 938 case 0x4 | 0x2 | 0x1: /* cc != 0 */ 939 cond = TCG_COND_NE; 940 c->u.s32.b = tcg_const_i32(0); 941 break; 942 case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */ 943 cond = TCG_COND_NE; 944 c->g1 = false; 945 c->u.s32.a = tcg_temp_new_i32(); 946 c->u.s32.b = tcg_const_i32(0); 947 tcg_gen_andi_i32(c->u.s32.a, cc_op, 1); 948 break; 949 case 0x4: /* cc == 1 */ 950 cond = TCG_COND_EQ; 951 c->u.s32.b = tcg_const_i32(1); 952 break; 953 case 0x2 | 0x1: /* cc > 1 */ 954 cond = TCG_COND_GTU; 955 c->u.s32.b = tcg_const_i32(1); 956 break; 957 case 0x2: /* cc == 2 */ 958 cond = TCG_COND_EQ; 959 c->u.s32.b = tcg_const_i32(2); 960 break; 961 case 0x1: /* cc == 3 */ 962 cond = TCG_COND_EQ; 963 c->u.s32.b = tcg_const_i32(3); 964 break; 965 default: 966 /* CC is masked by something else: (8 >> cc) & mask. */ 967 cond = TCG_COND_NE; 968 c->g1 = false; 969 c->u.s32.a = tcg_const_i32(8); 970 c->u.s32.b = tcg_const_i32(0); 971 tcg_gen_shr_i32(c->u.s32.a, c->u.s32.a, cc_op); 972 tcg_gen_andi_i32(c->u.s32.a, c->u.s32.a, mask); 973 break; 974 } 975 break; 976 977 default: 978 abort(); 979 } 980 c->cond = cond; 981 } 982 983 static void free_compare(DisasCompare *c) 984 { 985 if (!c->g1) { 986 if (c->is_64) { 987 tcg_temp_free_i64(c->u.s64.a); 988 } else { 989 tcg_temp_free_i32(c->u.s32.a); 990 } 991 } 992 if (!c->g2) { 993 if (c->is_64) { 994 tcg_temp_free_i64(c->u.s64.b); 995 } else { 996 tcg_temp_free_i32(c->u.s32.b); 997 } 998 } 999 } 1000 1001 /* ====================================================================== */ 1002 /* Define the insn format enumeration. */ 1003 #define F0(N) FMT_##N, 1004 #define F1(N, X1) F0(N) 1005 #define F2(N, X1, X2) F0(N) 1006 #define F3(N, X1, X2, X3) F0(N) 1007 #define F4(N, X1, X2, X3, X4) F0(N) 1008 #define F5(N, X1, X2, X3, X4, X5) F0(N) 1009 #define F6(N, X1, X2, X3, X4, X5, X6) F0(N) 1010 1011 typedef enum { 1012 #include "insn-format.def" 1013 } DisasFormat; 1014 1015 #undef F0 1016 #undef F1 1017 #undef F2 1018 #undef F3 1019 #undef F4 1020 #undef F5 1021 #undef F6 1022 1023 /* This is the way fields are to be accessed out of DisasFields. */ 1024 #define have_field(S, F) have_field1((S), FLD_O_##F) 1025 #define get_field(S, F) get_field1((S), FLD_O_##F, FLD_C_##F) 1026 1027 static bool have_field1(const DisasContext *s, enum DisasFieldIndexO c) 1028 { 1029 return (s->fields.presentO >> c) & 1; 1030 } 1031 1032 static int get_field1(const DisasContext *s, enum DisasFieldIndexO o, 1033 enum DisasFieldIndexC c) 1034 { 1035 assert(have_field1(s, o)); 1036 return s->fields.c[c]; 1037 } 1038 1039 /* Describe the layout of each field in each format. */ 1040 typedef struct DisasField { 1041 unsigned int beg:8; 1042 unsigned int size:8; 1043 unsigned int type:2; 1044 unsigned int indexC:6; 1045 enum DisasFieldIndexO indexO:8; 1046 } DisasField; 1047 1048 typedef struct DisasFormatInfo { 1049 DisasField op[NUM_C_FIELD]; 1050 } DisasFormatInfo; 1051 1052 #define R(N, B) { B, 4, 0, FLD_C_r##N, FLD_O_r##N } 1053 #define M(N, B) { B, 4, 0, FLD_C_m##N, FLD_O_m##N } 1054 #define V(N, B) { B, 4, 3, FLD_C_v##N, FLD_O_v##N } 1055 #define BD(N, BB, BD) { BB, 4, 0, FLD_C_b##N, FLD_O_b##N }, \ 1056 { BD, 12, 0, FLD_C_d##N, FLD_O_d##N } 1057 #define BXD(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \ 1058 { 12, 4, 0, FLD_C_x##N, FLD_O_x##N }, \ 1059 { 20, 12, 0, FLD_C_d##N, FLD_O_d##N } 1060 #define BDL(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \ 1061 { 20, 20, 2, FLD_C_d##N, FLD_O_d##N } 1062 #define BXDL(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \ 1063 { 12, 4, 0, FLD_C_x##N, FLD_O_x##N }, \ 1064 { 20, 20, 2, FLD_C_d##N, FLD_O_d##N } 1065 #define I(N, B, S) { B, S, 1, FLD_C_i##N, FLD_O_i##N } 1066 #define L(N, B, S) { B, S, 0, FLD_C_l##N, FLD_O_l##N } 1067 1068 #define F0(N) { { } }, 1069 #define F1(N, X1) { { X1 } }, 1070 #define F2(N, X1, X2) { { X1, X2 } }, 1071 #define F3(N, X1, X2, X3) { { X1, X2, X3 } }, 1072 #define F4(N, X1, X2, X3, X4) { { X1, X2, X3, X4 } }, 1073 #define F5(N, X1, X2, X3, X4, X5) { { X1, X2, X3, X4, X5 } }, 1074 #define F6(N, X1, X2, X3, X4, X5, X6) { { X1, X2, X3, X4, X5, X6 } }, 1075 1076 static const DisasFormatInfo format_info[] = { 1077 #include "insn-format.def" 1078 }; 1079 1080 #undef F0 1081 #undef F1 1082 #undef F2 1083 #undef F3 1084 #undef F4 1085 #undef F5 1086 #undef F6 1087 #undef R 1088 #undef M 1089 #undef V 1090 #undef BD 1091 #undef BXD 1092 #undef BDL 1093 #undef BXDL 1094 #undef I 1095 #undef L 1096 1097 /* Generally, we'll extract operands into this structures, operate upon 1098 them, and store them back. See the "in1", "in2", "prep", "wout" sets 1099 of routines below for more details. */ 1100 typedef struct { 1101 bool g_out, g_out2, g_in1, g_in2; 1102 TCGv_i64 out, out2, in1, in2; 1103 TCGv_i64 addr1; 1104 } DisasOps; 1105 1106 /* Instructions can place constraints on their operands, raising specification 1107 exceptions if they are violated. To make this easy to automate, each "in1", 1108 "in2", "prep", "wout" helper will have a SPEC_<name> define that equals one 1109 of the following, or 0. To make this easy to document, we'll put the 1110 SPEC_<name> defines next to <name>. */ 1111 1112 #define SPEC_r1_even 1 1113 #define SPEC_r2_even 2 1114 #define SPEC_r3_even 4 1115 #define SPEC_r1_f128 8 1116 #define SPEC_r2_f128 16 1117 1118 /* Return values from translate_one, indicating the state of the TB. */ 1119 1120 /* We are not using a goto_tb (for whatever reason), but have updated 1121 the PC (for whatever reason), so there's no need to do it again on 1122 exiting the TB. */ 1123 #define DISAS_PC_UPDATED DISAS_TARGET_0 1124 1125 /* We have emitted one or more goto_tb. No fixup required. */ 1126 #define DISAS_GOTO_TB DISAS_TARGET_1 1127 1128 /* We have updated the PC and CC values. */ 1129 #define DISAS_PC_CC_UPDATED DISAS_TARGET_2 1130 1131 /* We are exiting the TB, but have neither emitted a goto_tb, nor 1132 updated the PC for the next instruction to be executed. */ 1133 #define DISAS_PC_STALE DISAS_TARGET_3 1134 1135 /* We are exiting the TB to the main loop. */ 1136 #define DISAS_PC_STALE_NOCHAIN DISAS_TARGET_4 1137 1138 1139 /* Instruction flags */ 1140 #define IF_AFP1 0x0001 /* r1 is a fp reg for HFP/FPS instructions */ 1141 #define IF_AFP2 0x0002 /* r2 is a fp reg for HFP/FPS instructions */ 1142 #define IF_AFP3 0x0004 /* r3 is a fp reg for HFP/FPS instructions */ 1143 #define IF_BFP 0x0008 /* binary floating point instruction */ 1144 #define IF_DFP 0x0010 /* decimal floating point instruction */ 1145 #define IF_PRIV 0x0020 /* privileged instruction */ 1146 #define IF_VEC 0x0040 /* vector instruction */ 1147 #define IF_IO 0x0080 /* input/output instruction */ 1148 1149 struct DisasInsn { 1150 unsigned opc:16; 1151 unsigned flags:16; 1152 DisasFormat fmt:8; 1153 unsigned fac:8; 1154 unsigned spec:8; 1155 1156 const char *name; 1157 1158 /* Pre-process arguments before HELP_OP. */ 1159 void (*help_in1)(DisasContext *, DisasOps *); 1160 void (*help_in2)(DisasContext *, DisasOps *); 1161 void (*help_prep)(DisasContext *, DisasOps *); 1162 1163 /* 1164 * Post-process output after HELP_OP. 1165 * Note that these are not called if HELP_OP returns DISAS_NORETURN. 1166 */ 1167 void (*help_wout)(DisasContext *, DisasOps *); 1168 void (*help_cout)(DisasContext *, DisasOps *); 1169 1170 /* Implement the operation itself. */ 1171 DisasJumpType (*help_op)(DisasContext *, DisasOps *); 1172 1173 uint64_t data; 1174 }; 1175 1176 /* ====================================================================== */ 1177 /* Miscellaneous helpers, used by several operations. */ 1178 1179 static void help_l2_shift(DisasContext *s, DisasOps *o, int mask) 1180 { 1181 int b2 = get_field(s, b2); 1182 int d2 = get_field(s, d2); 1183 1184 if (b2 == 0) { 1185 o->in2 = tcg_const_i64(d2 & mask); 1186 } else { 1187 o->in2 = get_address(s, 0, b2, d2); 1188 tcg_gen_andi_i64(o->in2, o->in2, mask); 1189 } 1190 } 1191 1192 static DisasJumpType help_goto_direct(DisasContext *s, uint64_t dest) 1193 { 1194 if (dest == s->pc_tmp) { 1195 per_branch(s, true); 1196 return DISAS_NEXT; 1197 } 1198 if (use_goto_tb(s, dest)) { 1199 update_cc_op(s); 1200 per_breaking_event(s); 1201 tcg_gen_goto_tb(0); 1202 tcg_gen_movi_i64(psw_addr, dest); 1203 tcg_gen_exit_tb(s->base.tb, 0); 1204 return DISAS_GOTO_TB; 1205 } else { 1206 tcg_gen_movi_i64(psw_addr, dest); 1207 per_branch(s, false); 1208 return DISAS_PC_UPDATED; 1209 } 1210 } 1211 1212 static DisasJumpType help_branch(DisasContext *s, DisasCompare *c, 1213 bool is_imm, int imm, TCGv_i64 cdest) 1214 { 1215 DisasJumpType ret; 1216 uint64_t dest = s->base.pc_next + 2 * imm; 1217 TCGLabel *lab; 1218 1219 /* Take care of the special cases first. */ 1220 if (c->cond == TCG_COND_NEVER) { 1221 ret = DISAS_NEXT; 1222 goto egress; 1223 } 1224 if (is_imm) { 1225 if (dest == s->pc_tmp) { 1226 /* Branch to next. */ 1227 per_branch(s, true); 1228 ret = DISAS_NEXT; 1229 goto egress; 1230 } 1231 if (c->cond == TCG_COND_ALWAYS) { 1232 ret = help_goto_direct(s, dest); 1233 goto egress; 1234 } 1235 } else { 1236 if (!cdest) { 1237 /* E.g. bcr %r0 -> no branch. */ 1238 ret = DISAS_NEXT; 1239 goto egress; 1240 } 1241 if (c->cond == TCG_COND_ALWAYS) { 1242 tcg_gen_mov_i64(psw_addr, cdest); 1243 per_branch(s, false); 1244 ret = DISAS_PC_UPDATED; 1245 goto egress; 1246 } 1247 } 1248 1249 if (use_goto_tb(s, s->pc_tmp)) { 1250 if (is_imm && use_goto_tb(s, dest)) { 1251 /* Both exits can use goto_tb. */ 1252 update_cc_op(s); 1253 1254 lab = gen_new_label(); 1255 if (c->is_64) { 1256 tcg_gen_brcond_i64(c->cond, c->u.s64.a, c->u.s64.b, lab); 1257 } else { 1258 tcg_gen_brcond_i32(c->cond, c->u.s32.a, c->u.s32.b, lab); 1259 } 1260 1261 /* Branch not taken. */ 1262 tcg_gen_goto_tb(0); 1263 tcg_gen_movi_i64(psw_addr, s->pc_tmp); 1264 tcg_gen_exit_tb(s->base.tb, 0); 1265 1266 /* Branch taken. */ 1267 gen_set_label(lab); 1268 per_breaking_event(s); 1269 tcg_gen_goto_tb(1); 1270 tcg_gen_movi_i64(psw_addr, dest); 1271 tcg_gen_exit_tb(s->base.tb, 1); 1272 1273 ret = DISAS_GOTO_TB; 1274 } else { 1275 /* Fallthru can use goto_tb, but taken branch cannot. */ 1276 /* Store taken branch destination before the brcond. This 1277 avoids having to allocate a new local temp to hold it. 1278 We'll overwrite this in the not taken case anyway. */ 1279 if (!is_imm) { 1280 tcg_gen_mov_i64(psw_addr, cdest); 1281 } 1282 1283 lab = gen_new_label(); 1284 if (c->is_64) { 1285 tcg_gen_brcond_i64(c->cond, c->u.s64.a, c->u.s64.b, lab); 1286 } else { 1287 tcg_gen_brcond_i32(c->cond, c->u.s32.a, c->u.s32.b, lab); 1288 } 1289 1290 /* Branch not taken. */ 1291 update_cc_op(s); 1292 tcg_gen_goto_tb(0); 1293 tcg_gen_movi_i64(psw_addr, s->pc_tmp); 1294 tcg_gen_exit_tb(s->base.tb, 0); 1295 1296 gen_set_label(lab); 1297 if (is_imm) { 1298 tcg_gen_movi_i64(psw_addr, dest); 1299 } 1300 per_breaking_event(s); 1301 ret = DISAS_PC_UPDATED; 1302 } 1303 } else { 1304 /* Fallthru cannot use goto_tb. This by itself is vanishingly rare. 1305 Most commonly we're single-stepping or some other condition that 1306 disables all use of goto_tb. Just update the PC and exit. */ 1307 1308 TCGv_i64 next = tcg_const_i64(s->pc_tmp); 1309 if (is_imm) { 1310 cdest = tcg_const_i64(dest); 1311 } 1312 1313 if (c->is_64) { 1314 tcg_gen_movcond_i64(c->cond, psw_addr, c->u.s64.a, c->u.s64.b, 1315 cdest, next); 1316 per_branch_cond(s, c->cond, c->u.s64.a, c->u.s64.b); 1317 } else { 1318 TCGv_i32 t0 = tcg_temp_new_i32(); 1319 TCGv_i64 t1 = tcg_temp_new_i64(); 1320 TCGv_i64 z = tcg_const_i64(0); 1321 tcg_gen_setcond_i32(c->cond, t0, c->u.s32.a, c->u.s32.b); 1322 tcg_gen_extu_i32_i64(t1, t0); 1323 tcg_temp_free_i32(t0); 1324 tcg_gen_movcond_i64(TCG_COND_NE, psw_addr, t1, z, cdest, next); 1325 per_branch_cond(s, TCG_COND_NE, t1, z); 1326 tcg_temp_free_i64(t1); 1327 tcg_temp_free_i64(z); 1328 } 1329 1330 if (is_imm) { 1331 tcg_temp_free_i64(cdest); 1332 } 1333 tcg_temp_free_i64(next); 1334 1335 ret = DISAS_PC_UPDATED; 1336 } 1337 1338 egress: 1339 free_compare(c); 1340 return ret; 1341 } 1342 1343 /* ====================================================================== */ 1344 /* The operations. These perform the bulk of the work for any insn, 1345 usually after the operands have been loaded and output initialized. */ 1346 1347 static DisasJumpType op_abs(DisasContext *s, DisasOps *o) 1348 { 1349 tcg_gen_abs_i64(o->out, o->in2); 1350 return DISAS_NEXT; 1351 } 1352 1353 static DisasJumpType op_absf32(DisasContext *s, DisasOps *o) 1354 { 1355 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffull); 1356 return DISAS_NEXT; 1357 } 1358 1359 static DisasJumpType op_absf64(DisasContext *s, DisasOps *o) 1360 { 1361 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffffffffffull); 1362 return DISAS_NEXT; 1363 } 1364 1365 static DisasJumpType op_absf128(DisasContext *s, DisasOps *o) 1366 { 1367 tcg_gen_andi_i64(o->out, o->in1, 0x7fffffffffffffffull); 1368 tcg_gen_mov_i64(o->out2, o->in2); 1369 return DISAS_NEXT; 1370 } 1371 1372 static DisasJumpType op_add(DisasContext *s, DisasOps *o) 1373 { 1374 tcg_gen_add_i64(o->out, o->in1, o->in2); 1375 return DISAS_NEXT; 1376 } 1377 1378 static DisasJumpType op_addu64(DisasContext *s, DisasOps *o) 1379 { 1380 tcg_gen_movi_i64(cc_src, 0); 1381 tcg_gen_add2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src); 1382 return DISAS_NEXT; 1383 } 1384 1385 /* Compute carry into cc_src. */ 1386 static void compute_carry(DisasContext *s) 1387 { 1388 switch (s->cc_op) { 1389 case CC_OP_ADDU: 1390 /* The carry value is already in cc_src (1,0). */ 1391 break; 1392 case CC_OP_SUBU: 1393 tcg_gen_addi_i64(cc_src, cc_src, 1); 1394 break; 1395 default: 1396 gen_op_calc_cc(s); 1397 /* fall through */ 1398 case CC_OP_STATIC: 1399 /* The carry flag is the msb of CC; compute into cc_src. */ 1400 tcg_gen_extu_i32_i64(cc_src, cc_op); 1401 tcg_gen_shri_i64(cc_src, cc_src, 1); 1402 break; 1403 } 1404 } 1405 1406 static DisasJumpType op_addc32(DisasContext *s, DisasOps *o) 1407 { 1408 compute_carry(s); 1409 tcg_gen_add_i64(o->out, o->in1, o->in2); 1410 tcg_gen_add_i64(o->out, o->out, cc_src); 1411 return DISAS_NEXT; 1412 } 1413 1414 static DisasJumpType op_addc64(DisasContext *s, DisasOps *o) 1415 { 1416 compute_carry(s); 1417 1418 TCGv_i64 zero = tcg_const_i64(0); 1419 tcg_gen_add2_i64(o->out, cc_src, o->in1, zero, cc_src, zero); 1420 tcg_gen_add2_i64(o->out, cc_src, o->out, cc_src, o->in2, zero); 1421 tcg_temp_free_i64(zero); 1422 1423 return DISAS_NEXT; 1424 } 1425 1426 static DisasJumpType op_asi(DisasContext *s, DisasOps *o) 1427 { 1428 bool non_atomic = !s390_has_feat(S390_FEAT_STFLE_45); 1429 1430 o->in1 = tcg_temp_new_i64(); 1431 if (non_atomic) { 1432 tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data); 1433 } else { 1434 /* Perform the atomic addition in memory. */ 1435 tcg_gen_atomic_fetch_add_i64(o->in1, o->addr1, o->in2, get_mem_index(s), 1436 s->insn->data); 1437 } 1438 1439 /* Recompute also for atomic case: needed for setting CC. */ 1440 tcg_gen_add_i64(o->out, o->in1, o->in2); 1441 1442 if (non_atomic) { 1443 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data); 1444 } 1445 return DISAS_NEXT; 1446 } 1447 1448 static DisasJumpType op_asiu64(DisasContext *s, DisasOps *o) 1449 { 1450 bool non_atomic = !s390_has_feat(S390_FEAT_STFLE_45); 1451 1452 o->in1 = tcg_temp_new_i64(); 1453 if (non_atomic) { 1454 tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data); 1455 } else { 1456 /* Perform the atomic addition in memory. */ 1457 tcg_gen_atomic_fetch_add_i64(o->in1, o->addr1, o->in2, get_mem_index(s), 1458 s->insn->data); 1459 } 1460 1461 /* Recompute also for atomic case: needed for setting CC. */ 1462 tcg_gen_movi_i64(cc_src, 0); 1463 tcg_gen_add2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src); 1464 1465 if (non_atomic) { 1466 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data); 1467 } 1468 return DISAS_NEXT; 1469 } 1470 1471 static DisasJumpType op_aeb(DisasContext *s, DisasOps *o) 1472 { 1473 gen_helper_aeb(o->out, cpu_env, o->in1, o->in2); 1474 return DISAS_NEXT; 1475 } 1476 1477 static DisasJumpType op_adb(DisasContext *s, DisasOps *o) 1478 { 1479 gen_helper_adb(o->out, cpu_env, o->in1, o->in2); 1480 return DISAS_NEXT; 1481 } 1482 1483 static DisasJumpType op_axb(DisasContext *s, DisasOps *o) 1484 { 1485 gen_helper_axb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2); 1486 return_low128(o->out2); 1487 return DISAS_NEXT; 1488 } 1489 1490 static DisasJumpType op_and(DisasContext *s, DisasOps *o) 1491 { 1492 tcg_gen_and_i64(o->out, o->in1, o->in2); 1493 return DISAS_NEXT; 1494 } 1495 1496 static DisasJumpType op_andi(DisasContext *s, DisasOps *o) 1497 { 1498 int shift = s->insn->data & 0xff; 1499 int size = s->insn->data >> 8; 1500 uint64_t mask = ((1ull << size) - 1) << shift; 1501 1502 assert(!o->g_in2); 1503 tcg_gen_shli_i64(o->in2, o->in2, shift); 1504 tcg_gen_ori_i64(o->in2, o->in2, ~mask); 1505 tcg_gen_and_i64(o->out, o->in1, o->in2); 1506 1507 /* Produce the CC from only the bits manipulated. */ 1508 tcg_gen_andi_i64(cc_dst, o->out, mask); 1509 set_cc_nz_u64(s, cc_dst); 1510 return DISAS_NEXT; 1511 } 1512 1513 static DisasJumpType op_ni(DisasContext *s, DisasOps *o) 1514 { 1515 o->in1 = tcg_temp_new_i64(); 1516 1517 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) { 1518 tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data); 1519 } else { 1520 /* Perform the atomic operation in memory. */ 1521 tcg_gen_atomic_fetch_and_i64(o->in1, o->addr1, o->in2, get_mem_index(s), 1522 s->insn->data); 1523 } 1524 1525 /* Recompute also for atomic case: needed for setting CC. */ 1526 tcg_gen_and_i64(o->out, o->in1, o->in2); 1527 1528 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) { 1529 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data); 1530 } 1531 return DISAS_NEXT; 1532 } 1533 1534 static DisasJumpType op_bas(DisasContext *s, DisasOps *o) 1535 { 1536 pc_to_link_info(o->out, s, s->pc_tmp); 1537 if (o->in2) { 1538 tcg_gen_mov_i64(psw_addr, o->in2); 1539 per_branch(s, false); 1540 return DISAS_PC_UPDATED; 1541 } else { 1542 return DISAS_NEXT; 1543 } 1544 } 1545 1546 static void save_link_info(DisasContext *s, DisasOps *o) 1547 { 1548 TCGv_i64 t; 1549 1550 if (s->base.tb->flags & (FLAG_MASK_32 | FLAG_MASK_64)) { 1551 pc_to_link_info(o->out, s, s->pc_tmp); 1552 return; 1553 } 1554 gen_op_calc_cc(s); 1555 tcg_gen_andi_i64(o->out, o->out, 0xffffffff00000000ull); 1556 tcg_gen_ori_i64(o->out, o->out, ((s->ilen / 2) << 30) | s->pc_tmp); 1557 t = tcg_temp_new_i64(); 1558 tcg_gen_shri_i64(t, psw_mask, 16); 1559 tcg_gen_andi_i64(t, t, 0x0f000000); 1560 tcg_gen_or_i64(o->out, o->out, t); 1561 tcg_gen_extu_i32_i64(t, cc_op); 1562 tcg_gen_shli_i64(t, t, 28); 1563 tcg_gen_or_i64(o->out, o->out, t); 1564 tcg_temp_free_i64(t); 1565 } 1566 1567 static DisasJumpType op_bal(DisasContext *s, DisasOps *o) 1568 { 1569 save_link_info(s, o); 1570 if (o->in2) { 1571 tcg_gen_mov_i64(psw_addr, o->in2); 1572 per_branch(s, false); 1573 return DISAS_PC_UPDATED; 1574 } else { 1575 return DISAS_NEXT; 1576 } 1577 } 1578 1579 static DisasJumpType op_basi(DisasContext *s, DisasOps *o) 1580 { 1581 pc_to_link_info(o->out, s, s->pc_tmp); 1582 return help_goto_direct(s, s->base.pc_next + 2 * get_field(s, i2)); 1583 } 1584 1585 static DisasJumpType op_bc(DisasContext *s, DisasOps *o) 1586 { 1587 int m1 = get_field(s, m1); 1588 bool is_imm = have_field(s, i2); 1589 int imm = is_imm ? get_field(s, i2) : 0; 1590 DisasCompare c; 1591 1592 /* BCR with R2 = 0 causes no branching */ 1593 if (have_field(s, r2) && get_field(s, r2) == 0) { 1594 if (m1 == 14) { 1595 /* Perform serialization */ 1596 /* FIXME: check for fast-BCR-serialization facility */ 1597 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); 1598 } 1599 if (m1 == 15) { 1600 /* Perform serialization */ 1601 /* FIXME: perform checkpoint-synchronisation */ 1602 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); 1603 } 1604 return DISAS_NEXT; 1605 } 1606 1607 disas_jcc(s, &c, m1); 1608 return help_branch(s, &c, is_imm, imm, o->in2); 1609 } 1610 1611 static DisasJumpType op_bct32(DisasContext *s, DisasOps *o) 1612 { 1613 int r1 = get_field(s, r1); 1614 bool is_imm = have_field(s, i2); 1615 int imm = is_imm ? get_field(s, i2) : 0; 1616 DisasCompare c; 1617 TCGv_i64 t; 1618 1619 c.cond = TCG_COND_NE; 1620 c.is_64 = false; 1621 c.g1 = false; 1622 c.g2 = false; 1623 1624 t = tcg_temp_new_i64(); 1625 tcg_gen_subi_i64(t, regs[r1], 1); 1626 store_reg32_i64(r1, t); 1627 c.u.s32.a = tcg_temp_new_i32(); 1628 c.u.s32.b = tcg_const_i32(0); 1629 tcg_gen_extrl_i64_i32(c.u.s32.a, t); 1630 tcg_temp_free_i64(t); 1631 1632 return help_branch(s, &c, is_imm, imm, o->in2); 1633 } 1634 1635 static DisasJumpType op_bcth(DisasContext *s, DisasOps *o) 1636 { 1637 int r1 = get_field(s, r1); 1638 int imm = get_field(s, i2); 1639 DisasCompare c; 1640 TCGv_i64 t; 1641 1642 c.cond = TCG_COND_NE; 1643 c.is_64 = false; 1644 c.g1 = false; 1645 c.g2 = false; 1646 1647 t = tcg_temp_new_i64(); 1648 tcg_gen_shri_i64(t, regs[r1], 32); 1649 tcg_gen_subi_i64(t, t, 1); 1650 store_reg32h_i64(r1, t); 1651 c.u.s32.a = tcg_temp_new_i32(); 1652 c.u.s32.b = tcg_const_i32(0); 1653 tcg_gen_extrl_i64_i32(c.u.s32.a, t); 1654 tcg_temp_free_i64(t); 1655 1656 return help_branch(s, &c, 1, imm, o->in2); 1657 } 1658 1659 static DisasJumpType op_bct64(DisasContext *s, DisasOps *o) 1660 { 1661 int r1 = get_field(s, r1); 1662 bool is_imm = have_field(s, i2); 1663 int imm = is_imm ? get_field(s, i2) : 0; 1664 DisasCompare c; 1665 1666 c.cond = TCG_COND_NE; 1667 c.is_64 = true; 1668 c.g1 = true; 1669 c.g2 = false; 1670 1671 tcg_gen_subi_i64(regs[r1], regs[r1], 1); 1672 c.u.s64.a = regs[r1]; 1673 c.u.s64.b = tcg_const_i64(0); 1674 1675 return help_branch(s, &c, is_imm, imm, o->in2); 1676 } 1677 1678 static DisasJumpType op_bx32(DisasContext *s, DisasOps *o) 1679 { 1680 int r1 = get_field(s, r1); 1681 int r3 = get_field(s, r3); 1682 bool is_imm = have_field(s, i2); 1683 int imm = is_imm ? get_field(s, i2) : 0; 1684 DisasCompare c; 1685 TCGv_i64 t; 1686 1687 c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT); 1688 c.is_64 = false; 1689 c.g1 = false; 1690 c.g2 = false; 1691 1692 t = tcg_temp_new_i64(); 1693 tcg_gen_add_i64(t, regs[r1], regs[r3]); 1694 c.u.s32.a = tcg_temp_new_i32(); 1695 c.u.s32.b = tcg_temp_new_i32(); 1696 tcg_gen_extrl_i64_i32(c.u.s32.a, t); 1697 tcg_gen_extrl_i64_i32(c.u.s32.b, regs[r3 | 1]); 1698 store_reg32_i64(r1, t); 1699 tcg_temp_free_i64(t); 1700 1701 return help_branch(s, &c, is_imm, imm, o->in2); 1702 } 1703 1704 static DisasJumpType op_bx64(DisasContext *s, DisasOps *o) 1705 { 1706 int r1 = get_field(s, r1); 1707 int r3 = get_field(s, r3); 1708 bool is_imm = have_field(s, i2); 1709 int imm = is_imm ? get_field(s, i2) : 0; 1710 DisasCompare c; 1711 1712 c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT); 1713 c.is_64 = true; 1714 1715 if (r1 == (r3 | 1)) { 1716 c.u.s64.b = load_reg(r3 | 1); 1717 c.g2 = false; 1718 } else { 1719 c.u.s64.b = regs[r3 | 1]; 1720 c.g2 = true; 1721 } 1722 1723 tcg_gen_add_i64(regs[r1], regs[r1], regs[r3]); 1724 c.u.s64.a = regs[r1]; 1725 c.g1 = true; 1726 1727 return help_branch(s, &c, is_imm, imm, o->in2); 1728 } 1729 1730 static DisasJumpType op_cj(DisasContext *s, DisasOps *o) 1731 { 1732 int imm, m3 = get_field(s, m3); 1733 bool is_imm; 1734 DisasCompare c; 1735 1736 c.cond = ltgt_cond[m3]; 1737 if (s->insn->data) { 1738 c.cond = tcg_unsigned_cond(c.cond); 1739 } 1740 c.is_64 = c.g1 = c.g2 = true; 1741 c.u.s64.a = o->in1; 1742 c.u.s64.b = o->in2; 1743 1744 is_imm = have_field(s, i4); 1745 if (is_imm) { 1746 imm = get_field(s, i4); 1747 } else { 1748 imm = 0; 1749 o->out = get_address(s, 0, get_field(s, b4), 1750 get_field(s, d4)); 1751 } 1752 1753 return help_branch(s, &c, is_imm, imm, o->out); 1754 } 1755 1756 static DisasJumpType op_ceb(DisasContext *s, DisasOps *o) 1757 { 1758 gen_helper_ceb(cc_op, cpu_env, o->in1, o->in2); 1759 set_cc_static(s); 1760 return DISAS_NEXT; 1761 } 1762 1763 static DisasJumpType op_cdb(DisasContext *s, DisasOps *o) 1764 { 1765 gen_helper_cdb(cc_op, cpu_env, o->in1, o->in2); 1766 set_cc_static(s); 1767 return DISAS_NEXT; 1768 } 1769 1770 static DisasJumpType op_cxb(DisasContext *s, DisasOps *o) 1771 { 1772 gen_helper_cxb(cc_op, cpu_env, o->out, o->out2, o->in1, o->in2); 1773 set_cc_static(s); 1774 return DISAS_NEXT; 1775 } 1776 1777 static TCGv_i32 fpinst_extract_m34(DisasContext *s, bool m3_with_fpe, 1778 bool m4_with_fpe) 1779 { 1780 const bool fpe = s390_has_feat(S390_FEAT_FLOATING_POINT_EXT); 1781 uint8_t m3 = get_field(s, m3); 1782 uint8_t m4 = get_field(s, m4); 1783 1784 /* m3 field was introduced with FPE */ 1785 if (!fpe && m3_with_fpe) { 1786 m3 = 0; 1787 } 1788 /* m4 field was introduced with FPE */ 1789 if (!fpe && m4_with_fpe) { 1790 m4 = 0; 1791 } 1792 1793 /* Check for valid rounding modes. Mode 3 was introduced later. */ 1794 if (m3 == 2 || m3 > 7 || (!fpe && m3 == 3)) { 1795 gen_program_exception(s, PGM_SPECIFICATION); 1796 return NULL; 1797 } 1798 1799 return tcg_const_i32(deposit32(m3, 4, 4, m4)); 1800 } 1801 1802 static DisasJumpType op_cfeb(DisasContext *s, DisasOps *o) 1803 { 1804 TCGv_i32 m34 = fpinst_extract_m34(s, false, true); 1805 1806 if (!m34) { 1807 return DISAS_NORETURN; 1808 } 1809 gen_helper_cfeb(o->out, cpu_env, o->in2, m34); 1810 tcg_temp_free_i32(m34); 1811 set_cc_static(s); 1812 return DISAS_NEXT; 1813 } 1814 1815 static DisasJumpType op_cfdb(DisasContext *s, DisasOps *o) 1816 { 1817 TCGv_i32 m34 = fpinst_extract_m34(s, false, true); 1818 1819 if (!m34) { 1820 return DISAS_NORETURN; 1821 } 1822 gen_helper_cfdb(o->out, cpu_env, o->in2, m34); 1823 tcg_temp_free_i32(m34); 1824 set_cc_static(s); 1825 return DISAS_NEXT; 1826 } 1827 1828 static DisasJumpType op_cfxb(DisasContext *s, DisasOps *o) 1829 { 1830 TCGv_i32 m34 = fpinst_extract_m34(s, false, true); 1831 1832 if (!m34) { 1833 return DISAS_NORETURN; 1834 } 1835 gen_helper_cfxb(o->out, cpu_env, o->in1, o->in2, m34); 1836 tcg_temp_free_i32(m34); 1837 set_cc_static(s); 1838 return DISAS_NEXT; 1839 } 1840 1841 static DisasJumpType op_cgeb(DisasContext *s, DisasOps *o) 1842 { 1843 TCGv_i32 m34 = fpinst_extract_m34(s, false, true); 1844 1845 if (!m34) { 1846 return DISAS_NORETURN; 1847 } 1848 gen_helper_cgeb(o->out, cpu_env, o->in2, m34); 1849 tcg_temp_free_i32(m34); 1850 set_cc_static(s); 1851 return DISAS_NEXT; 1852 } 1853 1854 static DisasJumpType op_cgdb(DisasContext *s, DisasOps *o) 1855 { 1856 TCGv_i32 m34 = fpinst_extract_m34(s, false, true); 1857 1858 if (!m34) { 1859 return DISAS_NORETURN; 1860 } 1861 gen_helper_cgdb(o->out, cpu_env, o->in2, m34); 1862 tcg_temp_free_i32(m34); 1863 set_cc_static(s); 1864 return DISAS_NEXT; 1865 } 1866 1867 static DisasJumpType op_cgxb(DisasContext *s, DisasOps *o) 1868 { 1869 TCGv_i32 m34 = fpinst_extract_m34(s, false, true); 1870 1871 if (!m34) { 1872 return DISAS_NORETURN; 1873 } 1874 gen_helper_cgxb(o->out, cpu_env, o->in1, o->in2, m34); 1875 tcg_temp_free_i32(m34); 1876 set_cc_static(s); 1877 return DISAS_NEXT; 1878 } 1879 1880 static DisasJumpType op_clfeb(DisasContext *s, DisasOps *o) 1881 { 1882 TCGv_i32 m34 = fpinst_extract_m34(s, false, false); 1883 1884 if (!m34) { 1885 return DISAS_NORETURN; 1886 } 1887 gen_helper_clfeb(o->out, cpu_env, o->in2, m34); 1888 tcg_temp_free_i32(m34); 1889 set_cc_static(s); 1890 return DISAS_NEXT; 1891 } 1892 1893 static DisasJumpType op_clfdb(DisasContext *s, DisasOps *o) 1894 { 1895 TCGv_i32 m34 = fpinst_extract_m34(s, false, false); 1896 1897 if (!m34) { 1898 return DISAS_NORETURN; 1899 } 1900 gen_helper_clfdb(o->out, cpu_env, o->in2, m34); 1901 tcg_temp_free_i32(m34); 1902 set_cc_static(s); 1903 return DISAS_NEXT; 1904 } 1905 1906 static DisasJumpType op_clfxb(DisasContext *s, DisasOps *o) 1907 { 1908 TCGv_i32 m34 = fpinst_extract_m34(s, false, false); 1909 1910 if (!m34) { 1911 return DISAS_NORETURN; 1912 } 1913 gen_helper_clfxb(o->out, cpu_env, o->in1, o->in2, m34); 1914 tcg_temp_free_i32(m34); 1915 set_cc_static(s); 1916 return DISAS_NEXT; 1917 } 1918 1919 static DisasJumpType op_clgeb(DisasContext *s, DisasOps *o) 1920 { 1921 TCGv_i32 m34 = fpinst_extract_m34(s, false, false); 1922 1923 if (!m34) { 1924 return DISAS_NORETURN; 1925 } 1926 gen_helper_clgeb(o->out, cpu_env, o->in2, m34); 1927 tcg_temp_free_i32(m34); 1928 set_cc_static(s); 1929 return DISAS_NEXT; 1930 } 1931 1932 static DisasJumpType op_clgdb(DisasContext *s, DisasOps *o) 1933 { 1934 TCGv_i32 m34 = fpinst_extract_m34(s, false, false); 1935 1936 if (!m34) { 1937 return DISAS_NORETURN; 1938 } 1939 gen_helper_clgdb(o->out, cpu_env, o->in2, m34); 1940 tcg_temp_free_i32(m34); 1941 set_cc_static(s); 1942 return DISAS_NEXT; 1943 } 1944 1945 static DisasJumpType op_clgxb(DisasContext *s, DisasOps *o) 1946 { 1947 TCGv_i32 m34 = fpinst_extract_m34(s, false, false); 1948 1949 if (!m34) { 1950 return DISAS_NORETURN; 1951 } 1952 gen_helper_clgxb(o->out, cpu_env, o->in1, o->in2, m34); 1953 tcg_temp_free_i32(m34); 1954 set_cc_static(s); 1955 return DISAS_NEXT; 1956 } 1957 1958 static DisasJumpType op_cegb(DisasContext *s, DisasOps *o) 1959 { 1960 TCGv_i32 m34 = fpinst_extract_m34(s, true, true); 1961 1962 if (!m34) { 1963 return DISAS_NORETURN; 1964 } 1965 gen_helper_cegb(o->out, cpu_env, o->in2, m34); 1966 tcg_temp_free_i32(m34); 1967 return DISAS_NEXT; 1968 } 1969 1970 static DisasJumpType op_cdgb(DisasContext *s, DisasOps *o) 1971 { 1972 TCGv_i32 m34 = fpinst_extract_m34(s, true, true); 1973 1974 if (!m34) { 1975 return DISAS_NORETURN; 1976 } 1977 gen_helper_cdgb(o->out, cpu_env, o->in2, m34); 1978 tcg_temp_free_i32(m34); 1979 return DISAS_NEXT; 1980 } 1981 1982 static DisasJumpType op_cxgb(DisasContext *s, DisasOps *o) 1983 { 1984 TCGv_i32 m34 = fpinst_extract_m34(s, true, true); 1985 1986 if (!m34) { 1987 return DISAS_NORETURN; 1988 } 1989 gen_helper_cxgb(o->out, cpu_env, o->in2, m34); 1990 tcg_temp_free_i32(m34); 1991 return_low128(o->out2); 1992 return DISAS_NEXT; 1993 } 1994 1995 static DisasJumpType op_celgb(DisasContext *s, DisasOps *o) 1996 { 1997 TCGv_i32 m34 = fpinst_extract_m34(s, false, false); 1998 1999 if (!m34) { 2000 return DISAS_NORETURN; 2001 } 2002 gen_helper_celgb(o->out, cpu_env, o->in2, m34); 2003 tcg_temp_free_i32(m34); 2004 return DISAS_NEXT; 2005 } 2006 2007 static DisasJumpType op_cdlgb(DisasContext *s, DisasOps *o) 2008 { 2009 TCGv_i32 m34 = fpinst_extract_m34(s, false, false); 2010 2011 if (!m34) { 2012 return DISAS_NORETURN; 2013 } 2014 gen_helper_cdlgb(o->out, cpu_env, o->in2, m34); 2015 tcg_temp_free_i32(m34); 2016 return DISAS_NEXT; 2017 } 2018 2019 static DisasJumpType op_cxlgb(DisasContext *s, DisasOps *o) 2020 { 2021 TCGv_i32 m34 = fpinst_extract_m34(s, false, false); 2022 2023 if (!m34) { 2024 return DISAS_NORETURN; 2025 } 2026 gen_helper_cxlgb(o->out, cpu_env, o->in2, m34); 2027 tcg_temp_free_i32(m34); 2028 return_low128(o->out2); 2029 return DISAS_NEXT; 2030 } 2031 2032 static DisasJumpType op_cksm(DisasContext *s, DisasOps *o) 2033 { 2034 int r2 = get_field(s, r2); 2035 TCGv_i64 len = tcg_temp_new_i64(); 2036 2037 gen_helper_cksm(len, cpu_env, o->in1, o->in2, regs[r2 + 1]); 2038 set_cc_static(s); 2039 return_low128(o->out); 2040 2041 tcg_gen_add_i64(regs[r2], regs[r2], len); 2042 tcg_gen_sub_i64(regs[r2 + 1], regs[r2 + 1], len); 2043 tcg_temp_free_i64(len); 2044 2045 return DISAS_NEXT; 2046 } 2047 2048 static DisasJumpType op_clc(DisasContext *s, DisasOps *o) 2049 { 2050 int l = get_field(s, l1); 2051 TCGv_i32 vl; 2052 2053 switch (l + 1) { 2054 case 1: 2055 tcg_gen_qemu_ld8u(cc_src, o->addr1, get_mem_index(s)); 2056 tcg_gen_qemu_ld8u(cc_dst, o->in2, get_mem_index(s)); 2057 break; 2058 case 2: 2059 tcg_gen_qemu_ld16u(cc_src, o->addr1, get_mem_index(s)); 2060 tcg_gen_qemu_ld16u(cc_dst, o->in2, get_mem_index(s)); 2061 break; 2062 case 4: 2063 tcg_gen_qemu_ld32u(cc_src, o->addr1, get_mem_index(s)); 2064 tcg_gen_qemu_ld32u(cc_dst, o->in2, get_mem_index(s)); 2065 break; 2066 case 8: 2067 tcg_gen_qemu_ld64(cc_src, o->addr1, get_mem_index(s)); 2068 tcg_gen_qemu_ld64(cc_dst, o->in2, get_mem_index(s)); 2069 break; 2070 default: 2071 vl = tcg_const_i32(l); 2072 gen_helper_clc(cc_op, cpu_env, vl, o->addr1, o->in2); 2073 tcg_temp_free_i32(vl); 2074 set_cc_static(s); 2075 return DISAS_NEXT; 2076 } 2077 gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, cc_src, cc_dst); 2078 return DISAS_NEXT; 2079 } 2080 2081 static DisasJumpType op_clcl(DisasContext *s, DisasOps *o) 2082 { 2083 int r1 = get_field(s, r1); 2084 int r2 = get_field(s, r2); 2085 TCGv_i32 t1, t2; 2086 2087 /* r1 and r2 must be even. */ 2088 if (r1 & 1 || r2 & 1) { 2089 gen_program_exception(s, PGM_SPECIFICATION); 2090 return DISAS_NORETURN; 2091 } 2092 2093 t1 = tcg_const_i32(r1); 2094 t2 = tcg_const_i32(r2); 2095 gen_helper_clcl(cc_op, cpu_env, t1, t2); 2096 tcg_temp_free_i32(t1); 2097 tcg_temp_free_i32(t2); 2098 set_cc_static(s); 2099 return DISAS_NEXT; 2100 } 2101 2102 static DisasJumpType op_clcle(DisasContext *s, DisasOps *o) 2103 { 2104 int r1 = get_field(s, r1); 2105 int r3 = get_field(s, r3); 2106 TCGv_i32 t1, t3; 2107 2108 /* r1 and r3 must be even. */ 2109 if (r1 & 1 || r3 & 1) { 2110 gen_program_exception(s, PGM_SPECIFICATION); 2111 return DISAS_NORETURN; 2112 } 2113 2114 t1 = tcg_const_i32(r1); 2115 t3 = tcg_const_i32(r3); 2116 gen_helper_clcle(cc_op, cpu_env, t1, o->in2, t3); 2117 tcg_temp_free_i32(t1); 2118 tcg_temp_free_i32(t3); 2119 set_cc_static(s); 2120 return DISAS_NEXT; 2121 } 2122 2123 static DisasJumpType op_clclu(DisasContext *s, DisasOps *o) 2124 { 2125 int r1 = get_field(s, r1); 2126 int r3 = get_field(s, r3); 2127 TCGv_i32 t1, t3; 2128 2129 /* r1 and r3 must be even. */ 2130 if (r1 & 1 || r3 & 1) { 2131 gen_program_exception(s, PGM_SPECIFICATION); 2132 return DISAS_NORETURN; 2133 } 2134 2135 t1 = tcg_const_i32(r1); 2136 t3 = tcg_const_i32(r3); 2137 gen_helper_clclu(cc_op, cpu_env, t1, o->in2, t3); 2138 tcg_temp_free_i32(t1); 2139 tcg_temp_free_i32(t3); 2140 set_cc_static(s); 2141 return DISAS_NEXT; 2142 } 2143 2144 static DisasJumpType op_clm(DisasContext *s, DisasOps *o) 2145 { 2146 TCGv_i32 m3 = tcg_const_i32(get_field(s, m3)); 2147 TCGv_i32 t1 = tcg_temp_new_i32(); 2148 tcg_gen_extrl_i64_i32(t1, o->in1); 2149 gen_helper_clm(cc_op, cpu_env, t1, m3, o->in2); 2150 set_cc_static(s); 2151 tcg_temp_free_i32(t1); 2152 tcg_temp_free_i32(m3); 2153 return DISAS_NEXT; 2154 } 2155 2156 static DisasJumpType op_clst(DisasContext *s, DisasOps *o) 2157 { 2158 gen_helper_clst(o->in1, cpu_env, regs[0], o->in1, o->in2); 2159 set_cc_static(s); 2160 return_low128(o->in2); 2161 return DISAS_NEXT; 2162 } 2163 2164 static DisasJumpType op_cps(DisasContext *s, DisasOps *o) 2165 { 2166 TCGv_i64 t = tcg_temp_new_i64(); 2167 tcg_gen_andi_i64(t, o->in1, 0x8000000000000000ull); 2168 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffffffffffull); 2169 tcg_gen_or_i64(o->out, o->out, t); 2170 tcg_temp_free_i64(t); 2171 return DISAS_NEXT; 2172 } 2173 2174 static DisasJumpType op_cs(DisasContext *s, DisasOps *o) 2175 { 2176 int d2 = get_field(s, d2); 2177 int b2 = get_field(s, b2); 2178 TCGv_i64 addr, cc; 2179 2180 /* Note that in1 = R3 (new value) and 2181 in2 = (zero-extended) R1 (expected value). */ 2182 2183 addr = get_address(s, 0, b2, d2); 2184 tcg_gen_atomic_cmpxchg_i64(o->out, addr, o->in2, o->in1, 2185 get_mem_index(s), s->insn->data | MO_ALIGN); 2186 tcg_temp_free_i64(addr); 2187 2188 /* Are the memory and expected values (un)equal? Note that this setcond 2189 produces the output CC value, thus the NE sense of the test. */ 2190 cc = tcg_temp_new_i64(); 2191 tcg_gen_setcond_i64(TCG_COND_NE, cc, o->in2, o->out); 2192 tcg_gen_extrl_i64_i32(cc_op, cc); 2193 tcg_temp_free_i64(cc); 2194 set_cc_static(s); 2195 2196 return DISAS_NEXT; 2197 } 2198 2199 static DisasJumpType op_cdsg(DisasContext *s, DisasOps *o) 2200 { 2201 int r1 = get_field(s, r1); 2202 int r3 = get_field(s, r3); 2203 int d2 = get_field(s, d2); 2204 int b2 = get_field(s, b2); 2205 DisasJumpType ret = DISAS_NEXT; 2206 TCGv_i64 addr; 2207 TCGv_i32 t_r1, t_r3; 2208 2209 /* Note that R1:R1+1 = expected value and R3:R3+1 = new value. */ 2210 addr = get_address(s, 0, b2, d2); 2211 t_r1 = tcg_const_i32(r1); 2212 t_r3 = tcg_const_i32(r3); 2213 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) { 2214 gen_helper_cdsg(cpu_env, addr, t_r1, t_r3); 2215 } else if (HAVE_CMPXCHG128) { 2216 gen_helper_cdsg_parallel(cpu_env, addr, t_r1, t_r3); 2217 } else { 2218 gen_helper_exit_atomic(cpu_env); 2219 ret = DISAS_NORETURN; 2220 } 2221 tcg_temp_free_i64(addr); 2222 tcg_temp_free_i32(t_r1); 2223 tcg_temp_free_i32(t_r3); 2224 2225 set_cc_static(s); 2226 return ret; 2227 } 2228 2229 static DisasJumpType op_csst(DisasContext *s, DisasOps *o) 2230 { 2231 int r3 = get_field(s, r3); 2232 TCGv_i32 t_r3 = tcg_const_i32(r3); 2233 2234 if (tb_cflags(s->base.tb) & CF_PARALLEL) { 2235 gen_helper_csst_parallel(cc_op, cpu_env, t_r3, o->addr1, o->in2); 2236 } else { 2237 gen_helper_csst(cc_op, cpu_env, t_r3, o->addr1, o->in2); 2238 } 2239 tcg_temp_free_i32(t_r3); 2240 2241 set_cc_static(s); 2242 return DISAS_NEXT; 2243 } 2244 2245 #ifndef CONFIG_USER_ONLY 2246 static DisasJumpType op_csp(DisasContext *s, DisasOps *o) 2247 { 2248 MemOp mop = s->insn->data; 2249 TCGv_i64 addr, old, cc; 2250 TCGLabel *lab = gen_new_label(); 2251 2252 /* Note that in1 = R1 (zero-extended expected value), 2253 out = R1 (original reg), out2 = R1+1 (new value). */ 2254 2255 addr = tcg_temp_new_i64(); 2256 old = tcg_temp_new_i64(); 2257 tcg_gen_andi_i64(addr, o->in2, -1ULL << (mop & MO_SIZE)); 2258 tcg_gen_atomic_cmpxchg_i64(old, addr, o->in1, o->out2, 2259 get_mem_index(s), mop | MO_ALIGN); 2260 tcg_temp_free_i64(addr); 2261 2262 /* Are the memory and expected values (un)equal? */ 2263 cc = tcg_temp_new_i64(); 2264 tcg_gen_setcond_i64(TCG_COND_NE, cc, o->in1, old); 2265 tcg_gen_extrl_i64_i32(cc_op, cc); 2266 2267 /* Write back the output now, so that it happens before the 2268 following branch, so that we don't need local temps. */ 2269 if ((mop & MO_SIZE) == MO_32) { 2270 tcg_gen_deposit_i64(o->out, o->out, old, 0, 32); 2271 } else { 2272 tcg_gen_mov_i64(o->out, old); 2273 } 2274 tcg_temp_free_i64(old); 2275 2276 /* If the comparison was equal, and the LSB of R2 was set, 2277 then we need to flush the TLB (for all cpus). */ 2278 tcg_gen_xori_i64(cc, cc, 1); 2279 tcg_gen_and_i64(cc, cc, o->in2); 2280 tcg_gen_brcondi_i64(TCG_COND_EQ, cc, 0, lab); 2281 tcg_temp_free_i64(cc); 2282 2283 gen_helper_purge(cpu_env); 2284 gen_set_label(lab); 2285 2286 return DISAS_NEXT; 2287 } 2288 #endif 2289 2290 static DisasJumpType op_cvd(DisasContext *s, DisasOps *o) 2291 { 2292 TCGv_i64 t1 = tcg_temp_new_i64(); 2293 TCGv_i32 t2 = tcg_temp_new_i32(); 2294 tcg_gen_extrl_i64_i32(t2, o->in1); 2295 gen_helper_cvd(t1, t2); 2296 tcg_temp_free_i32(t2); 2297 tcg_gen_qemu_st64(t1, o->in2, get_mem_index(s)); 2298 tcg_temp_free_i64(t1); 2299 return DISAS_NEXT; 2300 } 2301 2302 static DisasJumpType op_ct(DisasContext *s, DisasOps *o) 2303 { 2304 int m3 = get_field(s, m3); 2305 TCGLabel *lab = gen_new_label(); 2306 TCGCond c; 2307 2308 c = tcg_invert_cond(ltgt_cond[m3]); 2309 if (s->insn->data) { 2310 c = tcg_unsigned_cond(c); 2311 } 2312 tcg_gen_brcond_i64(c, o->in1, o->in2, lab); 2313 2314 /* Trap. */ 2315 gen_trap(s); 2316 2317 gen_set_label(lab); 2318 return DISAS_NEXT; 2319 } 2320 2321 static DisasJumpType op_cuXX(DisasContext *s, DisasOps *o) 2322 { 2323 int m3 = get_field(s, m3); 2324 int r1 = get_field(s, r1); 2325 int r2 = get_field(s, r2); 2326 TCGv_i32 tr1, tr2, chk; 2327 2328 /* R1 and R2 must both be even. */ 2329 if ((r1 | r2) & 1) { 2330 gen_program_exception(s, PGM_SPECIFICATION); 2331 return DISAS_NORETURN; 2332 } 2333 if (!s390_has_feat(S390_FEAT_ETF3_ENH)) { 2334 m3 = 0; 2335 } 2336 2337 tr1 = tcg_const_i32(r1); 2338 tr2 = tcg_const_i32(r2); 2339 chk = tcg_const_i32(m3); 2340 2341 switch (s->insn->data) { 2342 case 12: 2343 gen_helper_cu12(cc_op, cpu_env, tr1, tr2, chk); 2344 break; 2345 case 14: 2346 gen_helper_cu14(cc_op, cpu_env, tr1, tr2, chk); 2347 break; 2348 case 21: 2349 gen_helper_cu21(cc_op, cpu_env, tr1, tr2, chk); 2350 break; 2351 case 24: 2352 gen_helper_cu24(cc_op, cpu_env, tr1, tr2, chk); 2353 break; 2354 case 41: 2355 gen_helper_cu41(cc_op, cpu_env, tr1, tr2, chk); 2356 break; 2357 case 42: 2358 gen_helper_cu42(cc_op, cpu_env, tr1, tr2, chk); 2359 break; 2360 default: 2361 g_assert_not_reached(); 2362 } 2363 2364 tcg_temp_free_i32(tr1); 2365 tcg_temp_free_i32(tr2); 2366 tcg_temp_free_i32(chk); 2367 set_cc_static(s); 2368 return DISAS_NEXT; 2369 } 2370 2371 #ifndef CONFIG_USER_ONLY 2372 static DisasJumpType op_diag(DisasContext *s, DisasOps *o) 2373 { 2374 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 2375 TCGv_i32 r3 = tcg_const_i32(get_field(s, r3)); 2376 TCGv_i32 func_code = tcg_const_i32(get_field(s, i2)); 2377 2378 gen_helper_diag(cpu_env, r1, r3, func_code); 2379 2380 tcg_temp_free_i32(func_code); 2381 tcg_temp_free_i32(r3); 2382 tcg_temp_free_i32(r1); 2383 return DISAS_NEXT; 2384 } 2385 #endif 2386 2387 static DisasJumpType op_divs32(DisasContext *s, DisasOps *o) 2388 { 2389 gen_helper_divs32(o->out2, cpu_env, o->in1, o->in2); 2390 return_low128(o->out); 2391 return DISAS_NEXT; 2392 } 2393 2394 static DisasJumpType op_divu32(DisasContext *s, DisasOps *o) 2395 { 2396 gen_helper_divu32(o->out2, cpu_env, o->in1, o->in2); 2397 return_low128(o->out); 2398 return DISAS_NEXT; 2399 } 2400 2401 static DisasJumpType op_divs64(DisasContext *s, DisasOps *o) 2402 { 2403 gen_helper_divs64(o->out2, cpu_env, o->in1, o->in2); 2404 return_low128(o->out); 2405 return DISAS_NEXT; 2406 } 2407 2408 static DisasJumpType op_divu64(DisasContext *s, DisasOps *o) 2409 { 2410 gen_helper_divu64(o->out2, cpu_env, o->out, o->out2, o->in2); 2411 return_low128(o->out); 2412 return DISAS_NEXT; 2413 } 2414 2415 static DisasJumpType op_deb(DisasContext *s, DisasOps *o) 2416 { 2417 gen_helper_deb(o->out, cpu_env, o->in1, o->in2); 2418 return DISAS_NEXT; 2419 } 2420 2421 static DisasJumpType op_ddb(DisasContext *s, DisasOps *o) 2422 { 2423 gen_helper_ddb(o->out, cpu_env, o->in1, o->in2); 2424 return DISAS_NEXT; 2425 } 2426 2427 static DisasJumpType op_dxb(DisasContext *s, DisasOps *o) 2428 { 2429 gen_helper_dxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2); 2430 return_low128(o->out2); 2431 return DISAS_NEXT; 2432 } 2433 2434 static DisasJumpType op_ear(DisasContext *s, DisasOps *o) 2435 { 2436 int r2 = get_field(s, r2); 2437 tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, aregs[r2])); 2438 return DISAS_NEXT; 2439 } 2440 2441 static DisasJumpType op_ecag(DisasContext *s, DisasOps *o) 2442 { 2443 /* No cache information provided. */ 2444 tcg_gen_movi_i64(o->out, -1); 2445 return DISAS_NEXT; 2446 } 2447 2448 static DisasJumpType op_efpc(DisasContext *s, DisasOps *o) 2449 { 2450 tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, fpc)); 2451 return DISAS_NEXT; 2452 } 2453 2454 static DisasJumpType op_epsw(DisasContext *s, DisasOps *o) 2455 { 2456 int r1 = get_field(s, r1); 2457 int r2 = get_field(s, r2); 2458 TCGv_i64 t = tcg_temp_new_i64(); 2459 2460 /* Note the "subsequently" in the PoO, which implies a defined result 2461 if r1 == r2. Thus we cannot defer these writes to an output hook. */ 2462 tcg_gen_shri_i64(t, psw_mask, 32); 2463 store_reg32_i64(r1, t); 2464 if (r2 != 0) { 2465 store_reg32_i64(r2, psw_mask); 2466 } 2467 2468 tcg_temp_free_i64(t); 2469 return DISAS_NEXT; 2470 } 2471 2472 static DisasJumpType op_ex(DisasContext *s, DisasOps *o) 2473 { 2474 int r1 = get_field(s, r1); 2475 TCGv_i32 ilen; 2476 TCGv_i64 v1; 2477 2478 /* Nested EXECUTE is not allowed. */ 2479 if (unlikely(s->ex_value)) { 2480 gen_program_exception(s, PGM_EXECUTE); 2481 return DISAS_NORETURN; 2482 } 2483 2484 update_psw_addr(s); 2485 update_cc_op(s); 2486 2487 if (r1 == 0) { 2488 v1 = tcg_const_i64(0); 2489 } else { 2490 v1 = regs[r1]; 2491 } 2492 2493 ilen = tcg_const_i32(s->ilen); 2494 gen_helper_ex(cpu_env, ilen, v1, o->in2); 2495 tcg_temp_free_i32(ilen); 2496 2497 if (r1 == 0) { 2498 tcg_temp_free_i64(v1); 2499 } 2500 2501 return DISAS_PC_CC_UPDATED; 2502 } 2503 2504 static DisasJumpType op_fieb(DisasContext *s, DisasOps *o) 2505 { 2506 TCGv_i32 m34 = fpinst_extract_m34(s, false, true); 2507 2508 if (!m34) { 2509 return DISAS_NORETURN; 2510 } 2511 gen_helper_fieb(o->out, cpu_env, o->in2, m34); 2512 tcg_temp_free_i32(m34); 2513 return DISAS_NEXT; 2514 } 2515 2516 static DisasJumpType op_fidb(DisasContext *s, DisasOps *o) 2517 { 2518 TCGv_i32 m34 = fpinst_extract_m34(s, false, true); 2519 2520 if (!m34) { 2521 return DISAS_NORETURN; 2522 } 2523 gen_helper_fidb(o->out, cpu_env, o->in2, m34); 2524 tcg_temp_free_i32(m34); 2525 return DISAS_NEXT; 2526 } 2527 2528 static DisasJumpType op_fixb(DisasContext *s, DisasOps *o) 2529 { 2530 TCGv_i32 m34 = fpinst_extract_m34(s, false, true); 2531 2532 if (!m34) { 2533 return DISAS_NORETURN; 2534 } 2535 gen_helper_fixb(o->out, cpu_env, o->in1, o->in2, m34); 2536 return_low128(o->out2); 2537 tcg_temp_free_i32(m34); 2538 return DISAS_NEXT; 2539 } 2540 2541 static DisasJumpType op_flogr(DisasContext *s, DisasOps *o) 2542 { 2543 /* We'll use the original input for cc computation, since we get to 2544 compare that against 0, which ought to be better than comparing 2545 the real output against 64. It also lets cc_dst be a convenient 2546 temporary during our computation. */ 2547 gen_op_update1_cc_i64(s, CC_OP_FLOGR, o->in2); 2548 2549 /* R1 = IN ? CLZ(IN) : 64. */ 2550 tcg_gen_clzi_i64(o->out, o->in2, 64); 2551 2552 /* R1+1 = IN & ~(found bit). Note that we may attempt to shift this 2553 value by 64, which is undefined. But since the shift is 64 iff the 2554 input is zero, we still get the correct result after and'ing. */ 2555 tcg_gen_movi_i64(o->out2, 0x8000000000000000ull); 2556 tcg_gen_shr_i64(o->out2, o->out2, o->out); 2557 tcg_gen_andc_i64(o->out2, cc_dst, o->out2); 2558 return DISAS_NEXT; 2559 } 2560 2561 static DisasJumpType op_icm(DisasContext *s, DisasOps *o) 2562 { 2563 int m3 = get_field(s, m3); 2564 int pos, len, base = s->insn->data; 2565 TCGv_i64 tmp = tcg_temp_new_i64(); 2566 uint64_t ccm; 2567 2568 switch (m3) { 2569 case 0xf: 2570 /* Effectively a 32-bit load. */ 2571 tcg_gen_qemu_ld32u(tmp, o->in2, get_mem_index(s)); 2572 len = 32; 2573 goto one_insert; 2574 2575 case 0xc: 2576 case 0x6: 2577 case 0x3: 2578 /* Effectively a 16-bit load. */ 2579 tcg_gen_qemu_ld16u(tmp, o->in2, get_mem_index(s)); 2580 len = 16; 2581 goto one_insert; 2582 2583 case 0x8: 2584 case 0x4: 2585 case 0x2: 2586 case 0x1: 2587 /* Effectively an 8-bit load. */ 2588 tcg_gen_qemu_ld8u(tmp, o->in2, get_mem_index(s)); 2589 len = 8; 2590 goto one_insert; 2591 2592 one_insert: 2593 pos = base + ctz32(m3) * 8; 2594 tcg_gen_deposit_i64(o->out, o->out, tmp, pos, len); 2595 ccm = ((1ull << len) - 1) << pos; 2596 break; 2597 2598 default: 2599 /* This is going to be a sequence of loads and inserts. */ 2600 pos = base + 32 - 8; 2601 ccm = 0; 2602 while (m3) { 2603 if (m3 & 0x8) { 2604 tcg_gen_qemu_ld8u(tmp, o->in2, get_mem_index(s)); 2605 tcg_gen_addi_i64(o->in2, o->in2, 1); 2606 tcg_gen_deposit_i64(o->out, o->out, tmp, pos, 8); 2607 ccm |= 0xff << pos; 2608 } 2609 m3 = (m3 << 1) & 0xf; 2610 pos -= 8; 2611 } 2612 break; 2613 } 2614 2615 tcg_gen_movi_i64(tmp, ccm); 2616 gen_op_update2_cc_i64(s, CC_OP_ICM, tmp, o->out); 2617 tcg_temp_free_i64(tmp); 2618 return DISAS_NEXT; 2619 } 2620 2621 static DisasJumpType op_insi(DisasContext *s, DisasOps *o) 2622 { 2623 int shift = s->insn->data & 0xff; 2624 int size = s->insn->data >> 8; 2625 tcg_gen_deposit_i64(o->out, o->in1, o->in2, shift, size); 2626 return DISAS_NEXT; 2627 } 2628 2629 static DisasJumpType op_ipm(DisasContext *s, DisasOps *o) 2630 { 2631 TCGv_i64 t1, t2; 2632 2633 gen_op_calc_cc(s); 2634 t1 = tcg_temp_new_i64(); 2635 tcg_gen_extract_i64(t1, psw_mask, 40, 4); 2636 t2 = tcg_temp_new_i64(); 2637 tcg_gen_extu_i32_i64(t2, cc_op); 2638 tcg_gen_deposit_i64(t1, t1, t2, 4, 60); 2639 tcg_gen_deposit_i64(o->out, o->out, t1, 24, 8); 2640 tcg_temp_free_i64(t1); 2641 tcg_temp_free_i64(t2); 2642 return DISAS_NEXT; 2643 } 2644 2645 #ifndef CONFIG_USER_ONLY 2646 static DisasJumpType op_idte(DisasContext *s, DisasOps *o) 2647 { 2648 TCGv_i32 m4; 2649 2650 if (s390_has_feat(S390_FEAT_LOCAL_TLB_CLEARING)) { 2651 m4 = tcg_const_i32(get_field(s, m4)); 2652 } else { 2653 m4 = tcg_const_i32(0); 2654 } 2655 gen_helper_idte(cpu_env, o->in1, o->in2, m4); 2656 tcg_temp_free_i32(m4); 2657 return DISAS_NEXT; 2658 } 2659 2660 static DisasJumpType op_ipte(DisasContext *s, DisasOps *o) 2661 { 2662 TCGv_i32 m4; 2663 2664 if (s390_has_feat(S390_FEAT_LOCAL_TLB_CLEARING)) { 2665 m4 = tcg_const_i32(get_field(s, m4)); 2666 } else { 2667 m4 = tcg_const_i32(0); 2668 } 2669 gen_helper_ipte(cpu_env, o->in1, o->in2, m4); 2670 tcg_temp_free_i32(m4); 2671 return DISAS_NEXT; 2672 } 2673 2674 static DisasJumpType op_iske(DisasContext *s, DisasOps *o) 2675 { 2676 gen_helper_iske(o->out, cpu_env, o->in2); 2677 return DISAS_NEXT; 2678 } 2679 #endif 2680 2681 static DisasJumpType op_msa(DisasContext *s, DisasOps *o) 2682 { 2683 int r1 = have_field(s, r1) ? get_field(s, r1) : 0; 2684 int r2 = have_field(s, r2) ? get_field(s, r2) : 0; 2685 int r3 = have_field(s, r3) ? get_field(s, r3) : 0; 2686 TCGv_i32 t_r1, t_r2, t_r3, type; 2687 2688 switch (s->insn->data) { 2689 case S390_FEAT_TYPE_KMA: 2690 if (r3 == r1 || r3 == r2) { 2691 gen_program_exception(s, PGM_SPECIFICATION); 2692 return DISAS_NORETURN; 2693 } 2694 /* FALL THROUGH */ 2695 case S390_FEAT_TYPE_KMCTR: 2696 if (r3 & 1 || !r3) { 2697 gen_program_exception(s, PGM_SPECIFICATION); 2698 return DISAS_NORETURN; 2699 } 2700 /* FALL THROUGH */ 2701 case S390_FEAT_TYPE_PPNO: 2702 case S390_FEAT_TYPE_KMF: 2703 case S390_FEAT_TYPE_KMC: 2704 case S390_FEAT_TYPE_KMO: 2705 case S390_FEAT_TYPE_KM: 2706 if (r1 & 1 || !r1) { 2707 gen_program_exception(s, PGM_SPECIFICATION); 2708 return DISAS_NORETURN; 2709 } 2710 /* FALL THROUGH */ 2711 case S390_FEAT_TYPE_KMAC: 2712 case S390_FEAT_TYPE_KIMD: 2713 case S390_FEAT_TYPE_KLMD: 2714 if (r2 & 1 || !r2) { 2715 gen_program_exception(s, PGM_SPECIFICATION); 2716 return DISAS_NORETURN; 2717 } 2718 /* FALL THROUGH */ 2719 case S390_FEAT_TYPE_PCKMO: 2720 case S390_FEAT_TYPE_PCC: 2721 break; 2722 default: 2723 g_assert_not_reached(); 2724 }; 2725 2726 t_r1 = tcg_const_i32(r1); 2727 t_r2 = tcg_const_i32(r2); 2728 t_r3 = tcg_const_i32(r3); 2729 type = tcg_const_i32(s->insn->data); 2730 gen_helper_msa(cc_op, cpu_env, t_r1, t_r2, t_r3, type); 2731 set_cc_static(s); 2732 tcg_temp_free_i32(t_r1); 2733 tcg_temp_free_i32(t_r2); 2734 tcg_temp_free_i32(t_r3); 2735 tcg_temp_free_i32(type); 2736 return DISAS_NEXT; 2737 } 2738 2739 static DisasJumpType op_keb(DisasContext *s, DisasOps *o) 2740 { 2741 gen_helper_keb(cc_op, cpu_env, o->in1, o->in2); 2742 set_cc_static(s); 2743 return DISAS_NEXT; 2744 } 2745 2746 static DisasJumpType op_kdb(DisasContext *s, DisasOps *o) 2747 { 2748 gen_helper_kdb(cc_op, cpu_env, o->in1, o->in2); 2749 set_cc_static(s); 2750 return DISAS_NEXT; 2751 } 2752 2753 static DisasJumpType op_kxb(DisasContext *s, DisasOps *o) 2754 { 2755 gen_helper_kxb(cc_op, cpu_env, o->out, o->out2, o->in1, o->in2); 2756 set_cc_static(s); 2757 return DISAS_NEXT; 2758 } 2759 2760 static DisasJumpType op_laa(DisasContext *s, DisasOps *o) 2761 { 2762 /* The real output is indeed the original value in memory; 2763 recompute the addition for the computation of CC. */ 2764 tcg_gen_atomic_fetch_add_i64(o->in2, o->in2, o->in1, get_mem_index(s), 2765 s->insn->data | MO_ALIGN); 2766 /* However, we need to recompute the addition for setting CC. */ 2767 tcg_gen_add_i64(o->out, o->in1, o->in2); 2768 return DISAS_NEXT; 2769 } 2770 2771 static DisasJumpType op_lan(DisasContext *s, DisasOps *o) 2772 { 2773 /* The real output is indeed the original value in memory; 2774 recompute the addition for the computation of CC. */ 2775 tcg_gen_atomic_fetch_and_i64(o->in2, o->in2, o->in1, get_mem_index(s), 2776 s->insn->data | MO_ALIGN); 2777 /* However, we need to recompute the operation for setting CC. */ 2778 tcg_gen_and_i64(o->out, o->in1, o->in2); 2779 return DISAS_NEXT; 2780 } 2781 2782 static DisasJumpType op_lao(DisasContext *s, DisasOps *o) 2783 { 2784 /* The real output is indeed the original value in memory; 2785 recompute the addition for the computation of CC. */ 2786 tcg_gen_atomic_fetch_or_i64(o->in2, o->in2, o->in1, get_mem_index(s), 2787 s->insn->data | MO_ALIGN); 2788 /* However, we need to recompute the operation for setting CC. */ 2789 tcg_gen_or_i64(o->out, o->in1, o->in2); 2790 return DISAS_NEXT; 2791 } 2792 2793 static DisasJumpType op_lax(DisasContext *s, DisasOps *o) 2794 { 2795 /* The real output is indeed the original value in memory; 2796 recompute the addition for the computation of CC. */ 2797 tcg_gen_atomic_fetch_xor_i64(o->in2, o->in2, o->in1, get_mem_index(s), 2798 s->insn->data | MO_ALIGN); 2799 /* However, we need to recompute the operation for setting CC. */ 2800 tcg_gen_xor_i64(o->out, o->in1, o->in2); 2801 return DISAS_NEXT; 2802 } 2803 2804 static DisasJumpType op_ldeb(DisasContext *s, DisasOps *o) 2805 { 2806 gen_helper_ldeb(o->out, cpu_env, o->in2); 2807 return DISAS_NEXT; 2808 } 2809 2810 static DisasJumpType op_ledb(DisasContext *s, DisasOps *o) 2811 { 2812 TCGv_i32 m34 = fpinst_extract_m34(s, true, true); 2813 2814 if (!m34) { 2815 return DISAS_NORETURN; 2816 } 2817 gen_helper_ledb(o->out, cpu_env, o->in2, m34); 2818 tcg_temp_free_i32(m34); 2819 return DISAS_NEXT; 2820 } 2821 2822 static DisasJumpType op_ldxb(DisasContext *s, DisasOps *o) 2823 { 2824 TCGv_i32 m34 = fpinst_extract_m34(s, true, true); 2825 2826 if (!m34) { 2827 return DISAS_NORETURN; 2828 } 2829 gen_helper_ldxb(o->out, cpu_env, o->in1, o->in2, m34); 2830 tcg_temp_free_i32(m34); 2831 return DISAS_NEXT; 2832 } 2833 2834 static DisasJumpType op_lexb(DisasContext *s, DisasOps *o) 2835 { 2836 TCGv_i32 m34 = fpinst_extract_m34(s, true, true); 2837 2838 if (!m34) { 2839 return DISAS_NORETURN; 2840 } 2841 gen_helper_lexb(o->out, cpu_env, o->in1, o->in2, m34); 2842 tcg_temp_free_i32(m34); 2843 return DISAS_NEXT; 2844 } 2845 2846 static DisasJumpType op_lxdb(DisasContext *s, DisasOps *o) 2847 { 2848 gen_helper_lxdb(o->out, cpu_env, o->in2); 2849 return_low128(o->out2); 2850 return DISAS_NEXT; 2851 } 2852 2853 static DisasJumpType op_lxeb(DisasContext *s, DisasOps *o) 2854 { 2855 gen_helper_lxeb(o->out, cpu_env, o->in2); 2856 return_low128(o->out2); 2857 return DISAS_NEXT; 2858 } 2859 2860 static DisasJumpType op_lde(DisasContext *s, DisasOps *o) 2861 { 2862 tcg_gen_shli_i64(o->out, o->in2, 32); 2863 return DISAS_NEXT; 2864 } 2865 2866 static DisasJumpType op_llgt(DisasContext *s, DisasOps *o) 2867 { 2868 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffff); 2869 return DISAS_NEXT; 2870 } 2871 2872 static DisasJumpType op_ld8s(DisasContext *s, DisasOps *o) 2873 { 2874 tcg_gen_qemu_ld8s(o->out, o->in2, get_mem_index(s)); 2875 return DISAS_NEXT; 2876 } 2877 2878 static DisasJumpType op_ld8u(DisasContext *s, DisasOps *o) 2879 { 2880 tcg_gen_qemu_ld8u(o->out, o->in2, get_mem_index(s)); 2881 return DISAS_NEXT; 2882 } 2883 2884 static DisasJumpType op_ld16s(DisasContext *s, DisasOps *o) 2885 { 2886 tcg_gen_qemu_ld16s(o->out, o->in2, get_mem_index(s)); 2887 return DISAS_NEXT; 2888 } 2889 2890 static DisasJumpType op_ld16u(DisasContext *s, DisasOps *o) 2891 { 2892 tcg_gen_qemu_ld16u(o->out, o->in2, get_mem_index(s)); 2893 return DISAS_NEXT; 2894 } 2895 2896 static DisasJumpType op_ld32s(DisasContext *s, DisasOps *o) 2897 { 2898 tcg_gen_qemu_ld32s(o->out, o->in2, get_mem_index(s)); 2899 return DISAS_NEXT; 2900 } 2901 2902 static DisasJumpType op_ld32u(DisasContext *s, DisasOps *o) 2903 { 2904 tcg_gen_qemu_ld32u(o->out, o->in2, get_mem_index(s)); 2905 return DISAS_NEXT; 2906 } 2907 2908 static DisasJumpType op_ld64(DisasContext *s, DisasOps *o) 2909 { 2910 tcg_gen_qemu_ld64(o->out, o->in2, get_mem_index(s)); 2911 return DISAS_NEXT; 2912 } 2913 2914 static DisasJumpType op_lat(DisasContext *s, DisasOps *o) 2915 { 2916 TCGLabel *lab = gen_new_label(); 2917 store_reg32_i64(get_field(s, r1), o->in2); 2918 /* The value is stored even in case of trap. */ 2919 tcg_gen_brcondi_i64(TCG_COND_NE, o->in2, 0, lab); 2920 gen_trap(s); 2921 gen_set_label(lab); 2922 return DISAS_NEXT; 2923 } 2924 2925 static DisasJumpType op_lgat(DisasContext *s, DisasOps *o) 2926 { 2927 TCGLabel *lab = gen_new_label(); 2928 tcg_gen_qemu_ld64(o->out, o->in2, get_mem_index(s)); 2929 /* The value is stored even in case of trap. */ 2930 tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab); 2931 gen_trap(s); 2932 gen_set_label(lab); 2933 return DISAS_NEXT; 2934 } 2935 2936 static DisasJumpType op_lfhat(DisasContext *s, DisasOps *o) 2937 { 2938 TCGLabel *lab = gen_new_label(); 2939 store_reg32h_i64(get_field(s, r1), o->in2); 2940 /* The value is stored even in case of trap. */ 2941 tcg_gen_brcondi_i64(TCG_COND_NE, o->in2, 0, lab); 2942 gen_trap(s); 2943 gen_set_label(lab); 2944 return DISAS_NEXT; 2945 } 2946 2947 static DisasJumpType op_llgfat(DisasContext *s, DisasOps *o) 2948 { 2949 TCGLabel *lab = gen_new_label(); 2950 tcg_gen_qemu_ld32u(o->out, o->in2, get_mem_index(s)); 2951 /* The value is stored even in case of trap. */ 2952 tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab); 2953 gen_trap(s); 2954 gen_set_label(lab); 2955 return DISAS_NEXT; 2956 } 2957 2958 static DisasJumpType op_llgtat(DisasContext *s, DisasOps *o) 2959 { 2960 TCGLabel *lab = gen_new_label(); 2961 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffff); 2962 /* The value is stored even in case of trap. */ 2963 tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab); 2964 gen_trap(s); 2965 gen_set_label(lab); 2966 return DISAS_NEXT; 2967 } 2968 2969 static DisasJumpType op_loc(DisasContext *s, DisasOps *o) 2970 { 2971 DisasCompare c; 2972 2973 disas_jcc(s, &c, get_field(s, m3)); 2974 2975 if (c.is_64) { 2976 tcg_gen_movcond_i64(c.cond, o->out, c.u.s64.a, c.u.s64.b, 2977 o->in2, o->in1); 2978 free_compare(&c); 2979 } else { 2980 TCGv_i32 t32 = tcg_temp_new_i32(); 2981 TCGv_i64 t, z; 2982 2983 tcg_gen_setcond_i32(c.cond, t32, c.u.s32.a, c.u.s32.b); 2984 free_compare(&c); 2985 2986 t = tcg_temp_new_i64(); 2987 tcg_gen_extu_i32_i64(t, t32); 2988 tcg_temp_free_i32(t32); 2989 2990 z = tcg_const_i64(0); 2991 tcg_gen_movcond_i64(TCG_COND_NE, o->out, t, z, o->in2, o->in1); 2992 tcg_temp_free_i64(t); 2993 tcg_temp_free_i64(z); 2994 } 2995 2996 return DISAS_NEXT; 2997 } 2998 2999 #ifndef CONFIG_USER_ONLY 3000 static DisasJumpType op_lctl(DisasContext *s, DisasOps *o) 3001 { 3002 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 3003 TCGv_i32 r3 = tcg_const_i32(get_field(s, r3)); 3004 gen_helper_lctl(cpu_env, r1, o->in2, r3); 3005 tcg_temp_free_i32(r1); 3006 tcg_temp_free_i32(r3); 3007 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */ 3008 return DISAS_PC_STALE_NOCHAIN; 3009 } 3010 3011 static DisasJumpType op_lctlg(DisasContext *s, DisasOps *o) 3012 { 3013 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 3014 TCGv_i32 r3 = tcg_const_i32(get_field(s, r3)); 3015 gen_helper_lctlg(cpu_env, r1, o->in2, r3); 3016 tcg_temp_free_i32(r1); 3017 tcg_temp_free_i32(r3); 3018 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */ 3019 return DISAS_PC_STALE_NOCHAIN; 3020 } 3021 3022 static DisasJumpType op_lra(DisasContext *s, DisasOps *o) 3023 { 3024 gen_helper_lra(o->out, cpu_env, o->in2); 3025 set_cc_static(s); 3026 return DISAS_NEXT; 3027 } 3028 3029 static DisasJumpType op_lpp(DisasContext *s, DisasOps *o) 3030 { 3031 tcg_gen_st_i64(o->in2, cpu_env, offsetof(CPUS390XState, pp)); 3032 return DISAS_NEXT; 3033 } 3034 3035 static DisasJumpType op_lpsw(DisasContext *s, DisasOps *o) 3036 { 3037 TCGv_i64 t1, t2; 3038 3039 per_breaking_event(s); 3040 3041 t1 = tcg_temp_new_i64(); 3042 t2 = tcg_temp_new_i64(); 3043 tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), 3044 MO_TEUL | MO_ALIGN_8); 3045 tcg_gen_addi_i64(o->in2, o->in2, 4); 3046 tcg_gen_qemu_ld32u(t2, o->in2, get_mem_index(s)); 3047 /* Convert the 32-bit PSW_MASK into the 64-bit PSW_MASK. */ 3048 tcg_gen_shli_i64(t1, t1, 32); 3049 gen_helper_load_psw(cpu_env, t1, t2); 3050 tcg_temp_free_i64(t1); 3051 tcg_temp_free_i64(t2); 3052 return DISAS_NORETURN; 3053 } 3054 3055 static DisasJumpType op_lpswe(DisasContext *s, DisasOps *o) 3056 { 3057 TCGv_i64 t1, t2; 3058 3059 per_breaking_event(s); 3060 3061 t1 = tcg_temp_new_i64(); 3062 t2 = tcg_temp_new_i64(); 3063 tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), 3064 MO_TEQ | MO_ALIGN_8); 3065 tcg_gen_addi_i64(o->in2, o->in2, 8); 3066 tcg_gen_qemu_ld64(t2, o->in2, get_mem_index(s)); 3067 gen_helper_load_psw(cpu_env, t1, t2); 3068 tcg_temp_free_i64(t1); 3069 tcg_temp_free_i64(t2); 3070 return DISAS_NORETURN; 3071 } 3072 #endif 3073 3074 static DisasJumpType op_lam(DisasContext *s, DisasOps *o) 3075 { 3076 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 3077 TCGv_i32 r3 = tcg_const_i32(get_field(s, r3)); 3078 gen_helper_lam(cpu_env, r1, o->in2, r3); 3079 tcg_temp_free_i32(r1); 3080 tcg_temp_free_i32(r3); 3081 return DISAS_NEXT; 3082 } 3083 3084 static DisasJumpType op_lm32(DisasContext *s, DisasOps *o) 3085 { 3086 int r1 = get_field(s, r1); 3087 int r3 = get_field(s, r3); 3088 TCGv_i64 t1, t2; 3089 3090 /* Only one register to read. */ 3091 t1 = tcg_temp_new_i64(); 3092 if (unlikely(r1 == r3)) { 3093 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s)); 3094 store_reg32_i64(r1, t1); 3095 tcg_temp_free(t1); 3096 return DISAS_NEXT; 3097 } 3098 3099 /* First load the values of the first and last registers to trigger 3100 possible page faults. */ 3101 t2 = tcg_temp_new_i64(); 3102 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s)); 3103 tcg_gen_addi_i64(t2, o->in2, 4 * ((r3 - r1) & 15)); 3104 tcg_gen_qemu_ld32u(t2, t2, get_mem_index(s)); 3105 store_reg32_i64(r1, t1); 3106 store_reg32_i64(r3, t2); 3107 3108 /* Only two registers to read. */ 3109 if (((r1 + 1) & 15) == r3) { 3110 tcg_temp_free(t2); 3111 tcg_temp_free(t1); 3112 return DISAS_NEXT; 3113 } 3114 3115 /* Then load the remaining registers. Page fault can't occur. */ 3116 r3 = (r3 - 1) & 15; 3117 tcg_gen_movi_i64(t2, 4); 3118 while (r1 != r3) { 3119 r1 = (r1 + 1) & 15; 3120 tcg_gen_add_i64(o->in2, o->in2, t2); 3121 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s)); 3122 store_reg32_i64(r1, t1); 3123 } 3124 tcg_temp_free(t2); 3125 tcg_temp_free(t1); 3126 3127 return DISAS_NEXT; 3128 } 3129 3130 static DisasJumpType op_lmh(DisasContext *s, DisasOps *o) 3131 { 3132 int r1 = get_field(s, r1); 3133 int r3 = get_field(s, r3); 3134 TCGv_i64 t1, t2; 3135 3136 /* Only one register to read. */ 3137 t1 = tcg_temp_new_i64(); 3138 if (unlikely(r1 == r3)) { 3139 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s)); 3140 store_reg32h_i64(r1, t1); 3141 tcg_temp_free(t1); 3142 return DISAS_NEXT; 3143 } 3144 3145 /* First load the values of the first and last registers to trigger 3146 possible page faults. */ 3147 t2 = tcg_temp_new_i64(); 3148 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s)); 3149 tcg_gen_addi_i64(t2, o->in2, 4 * ((r3 - r1) & 15)); 3150 tcg_gen_qemu_ld32u(t2, t2, get_mem_index(s)); 3151 store_reg32h_i64(r1, t1); 3152 store_reg32h_i64(r3, t2); 3153 3154 /* Only two registers to read. */ 3155 if (((r1 + 1) & 15) == r3) { 3156 tcg_temp_free(t2); 3157 tcg_temp_free(t1); 3158 return DISAS_NEXT; 3159 } 3160 3161 /* Then load the remaining registers. Page fault can't occur. */ 3162 r3 = (r3 - 1) & 15; 3163 tcg_gen_movi_i64(t2, 4); 3164 while (r1 != r3) { 3165 r1 = (r1 + 1) & 15; 3166 tcg_gen_add_i64(o->in2, o->in2, t2); 3167 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s)); 3168 store_reg32h_i64(r1, t1); 3169 } 3170 tcg_temp_free(t2); 3171 tcg_temp_free(t1); 3172 3173 return DISAS_NEXT; 3174 } 3175 3176 static DisasJumpType op_lm64(DisasContext *s, DisasOps *o) 3177 { 3178 int r1 = get_field(s, r1); 3179 int r3 = get_field(s, r3); 3180 TCGv_i64 t1, t2; 3181 3182 /* Only one register to read. */ 3183 if (unlikely(r1 == r3)) { 3184 tcg_gen_qemu_ld64(regs[r1], o->in2, get_mem_index(s)); 3185 return DISAS_NEXT; 3186 } 3187 3188 /* First load the values of the first and last registers to trigger 3189 possible page faults. */ 3190 t1 = tcg_temp_new_i64(); 3191 t2 = tcg_temp_new_i64(); 3192 tcg_gen_qemu_ld64(t1, o->in2, get_mem_index(s)); 3193 tcg_gen_addi_i64(t2, o->in2, 8 * ((r3 - r1) & 15)); 3194 tcg_gen_qemu_ld64(regs[r3], t2, get_mem_index(s)); 3195 tcg_gen_mov_i64(regs[r1], t1); 3196 tcg_temp_free(t2); 3197 3198 /* Only two registers to read. */ 3199 if (((r1 + 1) & 15) == r3) { 3200 tcg_temp_free(t1); 3201 return DISAS_NEXT; 3202 } 3203 3204 /* Then load the remaining registers. Page fault can't occur. */ 3205 r3 = (r3 - 1) & 15; 3206 tcg_gen_movi_i64(t1, 8); 3207 while (r1 != r3) { 3208 r1 = (r1 + 1) & 15; 3209 tcg_gen_add_i64(o->in2, o->in2, t1); 3210 tcg_gen_qemu_ld64(regs[r1], o->in2, get_mem_index(s)); 3211 } 3212 tcg_temp_free(t1); 3213 3214 return DISAS_NEXT; 3215 } 3216 3217 static DisasJumpType op_lpd(DisasContext *s, DisasOps *o) 3218 { 3219 TCGv_i64 a1, a2; 3220 MemOp mop = s->insn->data; 3221 3222 /* In a parallel context, stop the world and single step. */ 3223 if (tb_cflags(s->base.tb) & CF_PARALLEL) { 3224 update_psw_addr(s); 3225 update_cc_op(s); 3226 gen_exception(EXCP_ATOMIC); 3227 return DISAS_NORETURN; 3228 } 3229 3230 /* In a serial context, perform the two loads ... */ 3231 a1 = get_address(s, 0, get_field(s, b1), get_field(s, d1)); 3232 a2 = get_address(s, 0, get_field(s, b2), get_field(s, d2)); 3233 tcg_gen_qemu_ld_i64(o->out, a1, get_mem_index(s), mop | MO_ALIGN); 3234 tcg_gen_qemu_ld_i64(o->out2, a2, get_mem_index(s), mop | MO_ALIGN); 3235 tcg_temp_free_i64(a1); 3236 tcg_temp_free_i64(a2); 3237 3238 /* ... and indicate that we performed them while interlocked. */ 3239 gen_op_movi_cc(s, 0); 3240 return DISAS_NEXT; 3241 } 3242 3243 static DisasJumpType op_lpq(DisasContext *s, DisasOps *o) 3244 { 3245 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) { 3246 gen_helper_lpq(o->out, cpu_env, o->in2); 3247 } else if (HAVE_ATOMIC128) { 3248 gen_helper_lpq_parallel(o->out, cpu_env, o->in2); 3249 } else { 3250 gen_helper_exit_atomic(cpu_env); 3251 return DISAS_NORETURN; 3252 } 3253 return_low128(o->out2); 3254 return DISAS_NEXT; 3255 } 3256 3257 #ifndef CONFIG_USER_ONLY 3258 static DisasJumpType op_lura(DisasContext *s, DisasOps *o) 3259 { 3260 tcg_gen_qemu_ld_tl(o->out, o->in2, MMU_REAL_IDX, s->insn->data); 3261 return DISAS_NEXT; 3262 } 3263 #endif 3264 3265 static DisasJumpType op_lzrb(DisasContext *s, DisasOps *o) 3266 { 3267 tcg_gen_andi_i64(o->out, o->in2, -256); 3268 return DISAS_NEXT; 3269 } 3270 3271 static DisasJumpType op_lcbb(DisasContext *s, DisasOps *o) 3272 { 3273 const int64_t block_size = (1ull << (get_field(s, m3) + 6)); 3274 3275 if (get_field(s, m3) > 6) { 3276 gen_program_exception(s, PGM_SPECIFICATION); 3277 return DISAS_NORETURN; 3278 } 3279 3280 tcg_gen_ori_i64(o->addr1, o->addr1, -block_size); 3281 tcg_gen_neg_i64(o->addr1, o->addr1); 3282 tcg_gen_movi_i64(o->out, 16); 3283 tcg_gen_umin_i64(o->out, o->out, o->addr1); 3284 gen_op_update1_cc_i64(s, CC_OP_LCBB, o->out); 3285 return DISAS_NEXT; 3286 } 3287 3288 static DisasJumpType op_mc(DisasContext *s, DisasOps *o) 3289 { 3290 #if !defined(CONFIG_USER_ONLY) 3291 TCGv_i32 i2; 3292 #endif 3293 const uint16_t monitor_class = get_field(s, i2); 3294 3295 if (monitor_class & 0xff00) { 3296 gen_program_exception(s, PGM_SPECIFICATION); 3297 return DISAS_NORETURN; 3298 } 3299 3300 #if !defined(CONFIG_USER_ONLY) 3301 i2 = tcg_const_i32(monitor_class); 3302 gen_helper_monitor_call(cpu_env, o->addr1, i2); 3303 tcg_temp_free_i32(i2); 3304 #endif 3305 /* Defaults to a NOP. */ 3306 return DISAS_NEXT; 3307 } 3308 3309 static DisasJumpType op_mov2(DisasContext *s, DisasOps *o) 3310 { 3311 o->out = o->in2; 3312 o->g_out = o->g_in2; 3313 o->in2 = NULL; 3314 o->g_in2 = false; 3315 return DISAS_NEXT; 3316 } 3317 3318 static DisasJumpType op_mov2e(DisasContext *s, DisasOps *o) 3319 { 3320 int b2 = get_field(s, b2); 3321 TCGv ar1 = tcg_temp_new_i64(); 3322 3323 o->out = o->in2; 3324 o->g_out = o->g_in2; 3325 o->in2 = NULL; 3326 o->g_in2 = false; 3327 3328 switch (s->base.tb->flags & FLAG_MASK_ASC) { 3329 case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT: 3330 tcg_gen_movi_i64(ar1, 0); 3331 break; 3332 case PSW_ASC_ACCREG >> FLAG_MASK_PSW_SHIFT: 3333 tcg_gen_movi_i64(ar1, 1); 3334 break; 3335 case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT: 3336 if (b2) { 3337 tcg_gen_ld32u_i64(ar1, cpu_env, offsetof(CPUS390XState, aregs[b2])); 3338 } else { 3339 tcg_gen_movi_i64(ar1, 0); 3340 } 3341 break; 3342 case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT: 3343 tcg_gen_movi_i64(ar1, 2); 3344 break; 3345 } 3346 3347 tcg_gen_st32_i64(ar1, cpu_env, offsetof(CPUS390XState, aregs[1])); 3348 tcg_temp_free_i64(ar1); 3349 3350 return DISAS_NEXT; 3351 } 3352 3353 static DisasJumpType op_movx(DisasContext *s, DisasOps *o) 3354 { 3355 o->out = o->in1; 3356 o->out2 = o->in2; 3357 o->g_out = o->g_in1; 3358 o->g_out2 = o->g_in2; 3359 o->in1 = NULL; 3360 o->in2 = NULL; 3361 o->g_in1 = o->g_in2 = false; 3362 return DISAS_NEXT; 3363 } 3364 3365 static DisasJumpType op_mvc(DisasContext *s, DisasOps *o) 3366 { 3367 TCGv_i32 l = tcg_const_i32(get_field(s, l1)); 3368 gen_helper_mvc(cpu_env, l, o->addr1, o->in2); 3369 tcg_temp_free_i32(l); 3370 return DISAS_NEXT; 3371 } 3372 3373 static DisasJumpType op_mvcin(DisasContext *s, DisasOps *o) 3374 { 3375 TCGv_i32 l = tcg_const_i32(get_field(s, l1)); 3376 gen_helper_mvcin(cpu_env, l, o->addr1, o->in2); 3377 tcg_temp_free_i32(l); 3378 return DISAS_NEXT; 3379 } 3380 3381 static DisasJumpType op_mvcl(DisasContext *s, DisasOps *o) 3382 { 3383 int r1 = get_field(s, r1); 3384 int r2 = get_field(s, r2); 3385 TCGv_i32 t1, t2; 3386 3387 /* r1 and r2 must be even. */ 3388 if (r1 & 1 || r2 & 1) { 3389 gen_program_exception(s, PGM_SPECIFICATION); 3390 return DISAS_NORETURN; 3391 } 3392 3393 t1 = tcg_const_i32(r1); 3394 t2 = tcg_const_i32(r2); 3395 gen_helper_mvcl(cc_op, cpu_env, t1, t2); 3396 tcg_temp_free_i32(t1); 3397 tcg_temp_free_i32(t2); 3398 set_cc_static(s); 3399 return DISAS_NEXT; 3400 } 3401 3402 static DisasJumpType op_mvcle(DisasContext *s, DisasOps *o) 3403 { 3404 int r1 = get_field(s, r1); 3405 int r3 = get_field(s, r3); 3406 TCGv_i32 t1, t3; 3407 3408 /* r1 and r3 must be even. */ 3409 if (r1 & 1 || r3 & 1) { 3410 gen_program_exception(s, PGM_SPECIFICATION); 3411 return DISAS_NORETURN; 3412 } 3413 3414 t1 = tcg_const_i32(r1); 3415 t3 = tcg_const_i32(r3); 3416 gen_helper_mvcle(cc_op, cpu_env, t1, o->in2, t3); 3417 tcg_temp_free_i32(t1); 3418 tcg_temp_free_i32(t3); 3419 set_cc_static(s); 3420 return DISAS_NEXT; 3421 } 3422 3423 static DisasJumpType op_mvclu(DisasContext *s, DisasOps *o) 3424 { 3425 int r1 = get_field(s, r1); 3426 int r3 = get_field(s, r3); 3427 TCGv_i32 t1, t3; 3428 3429 /* r1 and r3 must be even. */ 3430 if (r1 & 1 || r3 & 1) { 3431 gen_program_exception(s, PGM_SPECIFICATION); 3432 return DISAS_NORETURN; 3433 } 3434 3435 t1 = tcg_const_i32(r1); 3436 t3 = tcg_const_i32(r3); 3437 gen_helper_mvclu(cc_op, cpu_env, t1, o->in2, t3); 3438 tcg_temp_free_i32(t1); 3439 tcg_temp_free_i32(t3); 3440 set_cc_static(s); 3441 return DISAS_NEXT; 3442 } 3443 3444 static DisasJumpType op_mvcos(DisasContext *s, DisasOps *o) 3445 { 3446 int r3 = get_field(s, r3); 3447 gen_helper_mvcos(cc_op, cpu_env, o->addr1, o->in2, regs[r3]); 3448 set_cc_static(s); 3449 return DISAS_NEXT; 3450 } 3451 3452 #ifndef CONFIG_USER_ONLY 3453 static DisasJumpType op_mvcp(DisasContext *s, DisasOps *o) 3454 { 3455 int r1 = get_field(s, l1); 3456 gen_helper_mvcp(cc_op, cpu_env, regs[r1], o->addr1, o->in2); 3457 set_cc_static(s); 3458 return DISAS_NEXT; 3459 } 3460 3461 static DisasJumpType op_mvcs(DisasContext *s, DisasOps *o) 3462 { 3463 int r1 = get_field(s, l1); 3464 gen_helper_mvcs(cc_op, cpu_env, regs[r1], o->addr1, o->in2); 3465 set_cc_static(s); 3466 return DISAS_NEXT; 3467 } 3468 #endif 3469 3470 static DisasJumpType op_mvn(DisasContext *s, DisasOps *o) 3471 { 3472 TCGv_i32 l = tcg_const_i32(get_field(s, l1)); 3473 gen_helper_mvn(cpu_env, l, o->addr1, o->in2); 3474 tcg_temp_free_i32(l); 3475 return DISAS_NEXT; 3476 } 3477 3478 static DisasJumpType op_mvo(DisasContext *s, DisasOps *o) 3479 { 3480 TCGv_i32 l = tcg_const_i32(get_field(s, l1)); 3481 gen_helper_mvo(cpu_env, l, o->addr1, o->in2); 3482 tcg_temp_free_i32(l); 3483 return DISAS_NEXT; 3484 } 3485 3486 static DisasJumpType op_mvpg(DisasContext *s, DisasOps *o) 3487 { 3488 TCGv_i32 t1 = tcg_const_i32(get_field(s, r1)); 3489 TCGv_i32 t2 = tcg_const_i32(get_field(s, r2)); 3490 3491 gen_helper_mvpg(cc_op, cpu_env, regs[0], t1, t2); 3492 tcg_temp_free_i32(t1); 3493 tcg_temp_free_i32(t2); 3494 set_cc_static(s); 3495 return DISAS_NEXT; 3496 } 3497 3498 static DisasJumpType op_mvst(DisasContext *s, DisasOps *o) 3499 { 3500 TCGv_i32 t1 = tcg_const_i32(get_field(s, r1)); 3501 TCGv_i32 t2 = tcg_const_i32(get_field(s, r2)); 3502 3503 gen_helper_mvst(cc_op, cpu_env, t1, t2); 3504 tcg_temp_free_i32(t1); 3505 tcg_temp_free_i32(t2); 3506 set_cc_static(s); 3507 return DISAS_NEXT; 3508 } 3509 3510 static DisasJumpType op_mvz(DisasContext *s, DisasOps *o) 3511 { 3512 TCGv_i32 l = tcg_const_i32(get_field(s, l1)); 3513 gen_helper_mvz(cpu_env, l, o->addr1, o->in2); 3514 tcg_temp_free_i32(l); 3515 return DISAS_NEXT; 3516 } 3517 3518 static DisasJumpType op_mul(DisasContext *s, DisasOps *o) 3519 { 3520 tcg_gen_mul_i64(o->out, o->in1, o->in2); 3521 return DISAS_NEXT; 3522 } 3523 3524 static DisasJumpType op_mul128(DisasContext *s, DisasOps *o) 3525 { 3526 tcg_gen_mulu2_i64(o->out2, o->out, o->in1, o->in2); 3527 return DISAS_NEXT; 3528 } 3529 3530 static DisasJumpType op_muls128(DisasContext *s, DisasOps *o) 3531 { 3532 tcg_gen_muls2_i64(o->out2, o->out, o->in1, o->in2); 3533 return DISAS_NEXT; 3534 } 3535 3536 static DisasJumpType op_meeb(DisasContext *s, DisasOps *o) 3537 { 3538 gen_helper_meeb(o->out, cpu_env, o->in1, o->in2); 3539 return DISAS_NEXT; 3540 } 3541 3542 static DisasJumpType op_mdeb(DisasContext *s, DisasOps *o) 3543 { 3544 gen_helper_mdeb(o->out, cpu_env, o->in1, o->in2); 3545 return DISAS_NEXT; 3546 } 3547 3548 static DisasJumpType op_mdb(DisasContext *s, DisasOps *o) 3549 { 3550 gen_helper_mdb(o->out, cpu_env, o->in1, o->in2); 3551 return DISAS_NEXT; 3552 } 3553 3554 static DisasJumpType op_mxb(DisasContext *s, DisasOps *o) 3555 { 3556 gen_helper_mxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2); 3557 return_low128(o->out2); 3558 return DISAS_NEXT; 3559 } 3560 3561 static DisasJumpType op_mxdb(DisasContext *s, DisasOps *o) 3562 { 3563 gen_helper_mxdb(o->out, cpu_env, o->out, o->out2, o->in2); 3564 return_low128(o->out2); 3565 return DISAS_NEXT; 3566 } 3567 3568 static DisasJumpType op_maeb(DisasContext *s, DisasOps *o) 3569 { 3570 TCGv_i64 r3 = load_freg32_i64(get_field(s, r3)); 3571 gen_helper_maeb(o->out, cpu_env, o->in1, o->in2, r3); 3572 tcg_temp_free_i64(r3); 3573 return DISAS_NEXT; 3574 } 3575 3576 static DisasJumpType op_madb(DisasContext *s, DisasOps *o) 3577 { 3578 TCGv_i64 r3 = load_freg(get_field(s, r3)); 3579 gen_helper_madb(o->out, cpu_env, o->in1, o->in2, r3); 3580 tcg_temp_free_i64(r3); 3581 return DISAS_NEXT; 3582 } 3583 3584 static DisasJumpType op_mseb(DisasContext *s, DisasOps *o) 3585 { 3586 TCGv_i64 r3 = load_freg32_i64(get_field(s, r3)); 3587 gen_helper_mseb(o->out, cpu_env, o->in1, o->in2, r3); 3588 tcg_temp_free_i64(r3); 3589 return DISAS_NEXT; 3590 } 3591 3592 static DisasJumpType op_msdb(DisasContext *s, DisasOps *o) 3593 { 3594 TCGv_i64 r3 = load_freg(get_field(s, r3)); 3595 gen_helper_msdb(o->out, cpu_env, o->in1, o->in2, r3); 3596 tcg_temp_free_i64(r3); 3597 return DISAS_NEXT; 3598 } 3599 3600 static DisasJumpType op_nabs(DisasContext *s, DisasOps *o) 3601 { 3602 TCGv_i64 z, n; 3603 z = tcg_const_i64(0); 3604 n = tcg_temp_new_i64(); 3605 tcg_gen_neg_i64(n, o->in2); 3606 tcg_gen_movcond_i64(TCG_COND_GE, o->out, o->in2, z, n, o->in2); 3607 tcg_temp_free_i64(n); 3608 tcg_temp_free_i64(z); 3609 return DISAS_NEXT; 3610 } 3611 3612 static DisasJumpType op_nabsf32(DisasContext *s, DisasOps *o) 3613 { 3614 tcg_gen_ori_i64(o->out, o->in2, 0x80000000ull); 3615 return DISAS_NEXT; 3616 } 3617 3618 static DisasJumpType op_nabsf64(DisasContext *s, DisasOps *o) 3619 { 3620 tcg_gen_ori_i64(o->out, o->in2, 0x8000000000000000ull); 3621 return DISAS_NEXT; 3622 } 3623 3624 static DisasJumpType op_nabsf128(DisasContext *s, DisasOps *o) 3625 { 3626 tcg_gen_ori_i64(o->out, o->in1, 0x8000000000000000ull); 3627 tcg_gen_mov_i64(o->out2, o->in2); 3628 return DISAS_NEXT; 3629 } 3630 3631 static DisasJumpType op_nc(DisasContext *s, DisasOps *o) 3632 { 3633 TCGv_i32 l = tcg_const_i32(get_field(s, l1)); 3634 gen_helper_nc(cc_op, cpu_env, l, o->addr1, o->in2); 3635 tcg_temp_free_i32(l); 3636 set_cc_static(s); 3637 return DISAS_NEXT; 3638 } 3639 3640 static DisasJumpType op_neg(DisasContext *s, DisasOps *o) 3641 { 3642 tcg_gen_neg_i64(o->out, o->in2); 3643 return DISAS_NEXT; 3644 } 3645 3646 static DisasJumpType op_negf32(DisasContext *s, DisasOps *o) 3647 { 3648 tcg_gen_xori_i64(o->out, o->in2, 0x80000000ull); 3649 return DISAS_NEXT; 3650 } 3651 3652 static DisasJumpType op_negf64(DisasContext *s, DisasOps *o) 3653 { 3654 tcg_gen_xori_i64(o->out, o->in2, 0x8000000000000000ull); 3655 return DISAS_NEXT; 3656 } 3657 3658 static DisasJumpType op_negf128(DisasContext *s, DisasOps *o) 3659 { 3660 tcg_gen_xori_i64(o->out, o->in1, 0x8000000000000000ull); 3661 tcg_gen_mov_i64(o->out2, o->in2); 3662 return DISAS_NEXT; 3663 } 3664 3665 static DisasJumpType op_oc(DisasContext *s, DisasOps *o) 3666 { 3667 TCGv_i32 l = tcg_const_i32(get_field(s, l1)); 3668 gen_helper_oc(cc_op, cpu_env, l, o->addr1, o->in2); 3669 tcg_temp_free_i32(l); 3670 set_cc_static(s); 3671 return DISAS_NEXT; 3672 } 3673 3674 static DisasJumpType op_or(DisasContext *s, DisasOps *o) 3675 { 3676 tcg_gen_or_i64(o->out, o->in1, o->in2); 3677 return DISAS_NEXT; 3678 } 3679 3680 static DisasJumpType op_ori(DisasContext *s, DisasOps *o) 3681 { 3682 int shift = s->insn->data & 0xff; 3683 int size = s->insn->data >> 8; 3684 uint64_t mask = ((1ull << size) - 1) << shift; 3685 3686 assert(!o->g_in2); 3687 tcg_gen_shli_i64(o->in2, o->in2, shift); 3688 tcg_gen_or_i64(o->out, o->in1, o->in2); 3689 3690 /* Produce the CC from only the bits manipulated. */ 3691 tcg_gen_andi_i64(cc_dst, o->out, mask); 3692 set_cc_nz_u64(s, cc_dst); 3693 return DISAS_NEXT; 3694 } 3695 3696 static DisasJumpType op_oi(DisasContext *s, DisasOps *o) 3697 { 3698 o->in1 = tcg_temp_new_i64(); 3699 3700 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) { 3701 tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data); 3702 } else { 3703 /* Perform the atomic operation in memory. */ 3704 tcg_gen_atomic_fetch_or_i64(o->in1, o->addr1, o->in2, get_mem_index(s), 3705 s->insn->data); 3706 } 3707 3708 /* Recompute also for atomic case: needed for setting CC. */ 3709 tcg_gen_or_i64(o->out, o->in1, o->in2); 3710 3711 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) { 3712 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data); 3713 } 3714 return DISAS_NEXT; 3715 } 3716 3717 static DisasJumpType op_pack(DisasContext *s, DisasOps *o) 3718 { 3719 TCGv_i32 l = tcg_const_i32(get_field(s, l1)); 3720 gen_helper_pack(cpu_env, l, o->addr1, o->in2); 3721 tcg_temp_free_i32(l); 3722 return DISAS_NEXT; 3723 } 3724 3725 static DisasJumpType op_pka(DisasContext *s, DisasOps *o) 3726 { 3727 int l2 = get_field(s, l2) + 1; 3728 TCGv_i32 l; 3729 3730 /* The length must not exceed 32 bytes. */ 3731 if (l2 > 32) { 3732 gen_program_exception(s, PGM_SPECIFICATION); 3733 return DISAS_NORETURN; 3734 } 3735 l = tcg_const_i32(l2); 3736 gen_helper_pka(cpu_env, o->addr1, o->in2, l); 3737 tcg_temp_free_i32(l); 3738 return DISAS_NEXT; 3739 } 3740 3741 static DisasJumpType op_pku(DisasContext *s, DisasOps *o) 3742 { 3743 int l2 = get_field(s, l2) + 1; 3744 TCGv_i32 l; 3745 3746 /* The length must be even and should not exceed 64 bytes. */ 3747 if ((l2 & 1) || (l2 > 64)) { 3748 gen_program_exception(s, PGM_SPECIFICATION); 3749 return DISAS_NORETURN; 3750 } 3751 l = tcg_const_i32(l2); 3752 gen_helper_pku(cpu_env, o->addr1, o->in2, l); 3753 tcg_temp_free_i32(l); 3754 return DISAS_NEXT; 3755 } 3756 3757 static DisasJumpType op_popcnt(DisasContext *s, DisasOps *o) 3758 { 3759 gen_helper_popcnt(o->out, o->in2); 3760 return DISAS_NEXT; 3761 } 3762 3763 #ifndef CONFIG_USER_ONLY 3764 static DisasJumpType op_ptlb(DisasContext *s, DisasOps *o) 3765 { 3766 gen_helper_ptlb(cpu_env); 3767 return DISAS_NEXT; 3768 } 3769 #endif 3770 3771 static DisasJumpType op_risbg(DisasContext *s, DisasOps *o) 3772 { 3773 int i3 = get_field(s, i3); 3774 int i4 = get_field(s, i4); 3775 int i5 = get_field(s, i5); 3776 int do_zero = i4 & 0x80; 3777 uint64_t mask, imask, pmask; 3778 int pos, len, rot; 3779 3780 /* Adjust the arguments for the specific insn. */ 3781 switch (s->fields.op2) { 3782 case 0x55: /* risbg */ 3783 case 0x59: /* risbgn */ 3784 i3 &= 63; 3785 i4 &= 63; 3786 pmask = ~0; 3787 break; 3788 case 0x5d: /* risbhg */ 3789 i3 &= 31; 3790 i4 &= 31; 3791 pmask = 0xffffffff00000000ull; 3792 break; 3793 case 0x51: /* risblg */ 3794 i3 = (i3 & 31) + 32; 3795 i4 = (i4 & 31) + 32; 3796 pmask = 0x00000000ffffffffull; 3797 break; 3798 default: 3799 g_assert_not_reached(); 3800 } 3801 3802 /* MASK is the set of bits to be inserted from R2. */ 3803 if (i3 <= i4) { 3804 /* [0...i3---i4...63] */ 3805 mask = (-1ull >> i3) & (-1ull << (63 - i4)); 3806 } else { 3807 /* [0---i4...i3---63] */ 3808 mask = (-1ull >> i3) | (-1ull << (63 - i4)); 3809 } 3810 /* For RISBLG/RISBHG, the wrapping is limited to the high/low doubleword. */ 3811 mask &= pmask; 3812 3813 /* IMASK is the set of bits to be kept from R1. In the case of the high/low 3814 insns, we need to keep the other half of the register. */ 3815 imask = ~mask | ~pmask; 3816 if (do_zero) { 3817 imask = ~pmask; 3818 } 3819 3820 len = i4 - i3 + 1; 3821 pos = 63 - i4; 3822 rot = i5 & 63; 3823 3824 /* In some cases we can implement this with extract. */ 3825 if (imask == 0 && pos == 0 && len > 0 && len <= rot) { 3826 tcg_gen_extract_i64(o->out, o->in2, 64 - rot, len); 3827 return DISAS_NEXT; 3828 } 3829 3830 /* In some cases we can implement this with deposit. */ 3831 if (len > 0 && (imask == 0 || ~mask == imask)) { 3832 /* Note that we rotate the bits to be inserted to the lsb, not to 3833 the position as described in the PoO. */ 3834 rot = (rot - pos) & 63; 3835 } else { 3836 pos = -1; 3837 } 3838 3839 /* Rotate the input as necessary. */ 3840 tcg_gen_rotli_i64(o->in2, o->in2, rot); 3841 3842 /* Insert the selected bits into the output. */ 3843 if (pos >= 0) { 3844 if (imask == 0) { 3845 tcg_gen_deposit_z_i64(o->out, o->in2, pos, len); 3846 } else { 3847 tcg_gen_deposit_i64(o->out, o->out, o->in2, pos, len); 3848 } 3849 } else if (imask == 0) { 3850 tcg_gen_andi_i64(o->out, o->in2, mask); 3851 } else { 3852 tcg_gen_andi_i64(o->in2, o->in2, mask); 3853 tcg_gen_andi_i64(o->out, o->out, imask); 3854 tcg_gen_or_i64(o->out, o->out, o->in2); 3855 } 3856 return DISAS_NEXT; 3857 } 3858 3859 static DisasJumpType op_rosbg(DisasContext *s, DisasOps *o) 3860 { 3861 int i3 = get_field(s, i3); 3862 int i4 = get_field(s, i4); 3863 int i5 = get_field(s, i5); 3864 uint64_t mask; 3865 3866 /* If this is a test-only form, arrange to discard the result. */ 3867 if (i3 & 0x80) { 3868 o->out = tcg_temp_new_i64(); 3869 o->g_out = false; 3870 } 3871 3872 i3 &= 63; 3873 i4 &= 63; 3874 i5 &= 63; 3875 3876 /* MASK is the set of bits to be operated on from R2. 3877 Take care for I3/I4 wraparound. */ 3878 mask = ~0ull >> i3; 3879 if (i3 <= i4) { 3880 mask ^= ~0ull >> i4 >> 1; 3881 } else { 3882 mask |= ~(~0ull >> i4 >> 1); 3883 } 3884 3885 /* Rotate the input as necessary. */ 3886 tcg_gen_rotli_i64(o->in2, o->in2, i5); 3887 3888 /* Operate. */ 3889 switch (s->fields.op2) { 3890 case 0x54: /* AND */ 3891 tcg_gen_ori_i64(o->in2, o->in2, ~mask); 3892 tcg_gen_and_i64(o->out, o->out, o->in2); 3893 break; 3894 case 0x56: /* OR */ 3895 tcg_gen_andi_i64(o->in2, o->in2, mask); 3896 tcg_gen_or_i64(o->out, o->out, o->in2); 3897 break; 3898 case 0x57: /* XOR */ 3899 tcg_gen_andi_i64(o->in2, o->in2, mask); 3900 tcg_gen_xor_i64(o->out, o->out, o->in2); 3901 break; 3902 default: 3903 abort(); 3904 } 3905 3906 /* Set the CC. */ 3907 tcg_gen_andi_i64(cc_dst, o->out, mask); 3908 set_cc_nz_u64(s, cc_dst); 3909 return DISAS_NEXT; 3910 } 3911 3912 static DisasJumpType op_rev16(DisasContext *s, DisasOps *o) 3913 { 3914 tcg_gen_bswap16_i64(o->out, o->in2, TCG_BSWAP_IZ | TCG_BSWAP_OZ); 3915 return DISAS_NEXT; 3916 } 3917 3918 static DisasJumpType op_rev32(DisasContext *s, DisasOps *o) 3919 { 3920 tcg_gen_bswap32_i64(o->out, o->in2, TCG_BSWAP_IZ | TCG_BSWAP_OZ); 3921 return DISAS_NEXT; 3922 } 3923 3924 static DisasJumpType op_rev64(DisasContext *s, DisasOps *o) 3925 { 3926 tcg_gen_bswap64_i64(o->out, o->in2); 3927 return DISAS_NEXT; 3928 } 3929 3930 static DisasJumpType op_rll32(DisasContext *s, DisasOps *o) 3931 { 3932 TCGv_i32 t1 = tcg_temp_new_i32(); 3933 TCGv_i32 t2 = tcg_temp_new_i32(); 3934 TCGv_i32 to = tcg_temp_new_i32(); 3935 tcg_gen_extrl_i64_i32(t1, o->in1); 3936 tcg_gen_extrl_i64_i32(t2, o->in2); 3937 tcg_gen_rotl_i32(to, t1, t2); 3938 tcg_gen_extu_i32_i64(o->out, to); 3939 tcg_temp_free_i32(t1); 3940 tcg_temp_free_i32(t2); 3941 tcg_temp_free_i32(to); 3942 return DISAS_NEXT; 3943 } 3944 3945 static DisasJumpType op_rll64(DisasContext *s, DisasOps *o) 3946 { 3947 tcg_gen_rotl_i64(o->out, o->in1, o->in2); 3948 return DISAS_NEXT; 3949 } 3950 3951 #ifndef CONFIG_USER_ONLY 3952 static DisasJumpType op_rrbe(DisasContext *s, DisasOps *o) 3953 { 3954 gen_helper_rrbe(cc_op, cpu_env, o->in2); 3955 set_cc_static(s); 3956 return DISAS_NEXT; 3957 } 3958 3959 static DisasJumpType op_sacf(DisasContext *s, DisasOps *o) 3960 { 3961 gen_helper_sacf(cpu_env, o->in2); 3962 /* Addressing mode has changed, so end the block. */ 3963 return DISAS_PC_STALE; 3964 } 3965 #endif 3966 3967 static DisasJumpType op_sam(DisasContext *s, DisasOps *o) 3968 { 3969 int sam = s->insn->data; 3970 TCGv_i64 tsam; 3971 uint64_t mask; 3972 3973 switch (sam) { 3974 case 0: 3975 mask = 0xffffff; 3976 break; 3977 case 1: 3978 mask = 0x7fffffff; 3979 break; 3980 default: 3981 mask = -1; 3982 break; 3983 } 3984 3985 /* Bizarre but true, we check the address of the current insn for the 3986 specification exception, not the next to be executed. Thus the PoO 3987 documents that Bad Things Happen two bytes before the end. */ 3988 if (s->base.pc_next & ~mask) { 3989 gen_program_exception(s, PGM_SPECIFICATION); 3990 return DISAS_NORETURN; 3991 } 3992 s->pc_tmp &= mask; 3993 3994 tsam = tcg_const_i64(sam); 3995 tcg_gen_deposit_i64(psw_mask, psw_mask, tsam, 31, 2); 3996 tcg_temp_free_i64(tsam); 3997 3998 /* Always exit the TB, since we (may have) changed execution mode. */ 3999 return DISAS_PC_STALE; 4000 } 4001 4002 static DisasJumpType op_sar(DisasContext *s, DisasOps *o) 4003 { 4004 int r1 = get_field(s, r1); 4005 tcg_gen_st32_i64(o->in2, cpu_env, offsetof(CPUS390XState, aregs[r1])); 4006 return DISAS_NEXT; 4007 } 4008 4009 static DisasJumpType op_seb(DisasContext *s, DisasOps *o) 4010 { 4011 gen_helper_seb(o->out, cpu_env, o->in1, o->in2); 4012 return DISAS_NEXT; 4013 } 4014 4015 static DisasJumpType op_sdb(DisasContext *s, DisasOps *o) 4016 { 4017 gen_helper_sdb(o->out, cpu_env, o->in1, o->in2); 4018 return DISAS_NEXT; 4019 } 4020 4021 static DisasJumpType op_sxb(DisasContext *s, DisasOps *o) 4022 { 4023 gen_helper_sxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2); 4024 return_low128(o->out2); 4025 return DISAS_NEXT; 4026 } 4027 4028 static DisasJumpType op_sqeb(DisasContext *s, DisasOps *o) 4029 { 4030 gen_helper_sqeb(o->out, cpu_env, o->in2); 4031 return DISAS_NEXT; 4032 } 4033 4034 static DisasJumpType op_sqdb(DisasContext *s, DisasOps *o) 4035 { 4036 gen_helper_sqdb(o->out, cpu_env, o->in2); 4037 return DISAS_NEXT; 4038 } 4039 4040 static DisasJumpType op_sqxb(DisasContext *s, DisasOps *o) 4041 { 4042 gen_helper_sqxb(o->out, cpu_env, o->in1, o->in2); 4043 return_low128(o->out2); 4044 return DISAS_NEXT; 4045 } 4046 4047 #ifndef CONFIG_USER_ONLY 4048 static DisasJumpType op_servc(DisasContext *s, DisasOps *o) 4049 { 4050 gen_helper_servc(cc_op, cpu_env, o->in2, o->in1); 4051 set_cc_static(s); 4052 return DISAS_NEXT; 4053 } 4054 4055 static DisasJumpType op_sigp(DisasContext *s, DisasOps *o) 4056 { 4057 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 4058 TCGv_i32 r3 = tcg_const_i32(get_field(s, r3)); 4059 gen_helper_sigp(cc_op, cpu_env, o->in2, r1, r3); 4060 set_cc_static(s); 4061 tcg_temp_free_i32(r1); 4062 tcg_temp_free_i32(r3); 4063 return DISAS_NEXT; 4064 } 4065 #endif 4066 4067 static DisasJumpType op_soc(DisasContext *s, DisasOps *o) 4068 { 4069 DisasCompare c; 4070 TCGv_i64 a, h; 4071 TCGLabel *lab; 4072 int r1; 4073 4074 disas_jcc(s, &c, get_field(s, m3)); 4075 4076 /* We want to store when the condition is fulfilled, so branch 4077 out when it's not */ 4078 c.cond = tcg_invert_cond(c.cond); 4079 4080 lab = gen_new_label(); 4081 if (c.is_64) { 4082 tcg_gen_brcond_i64(c.cond, c.u.s64.a, c.u.s64.b, lab); 4083 } else { 4084 tcg_gen_brcond_i32(c.cond, c.u.s32.a, c.u.s32.b, lab); 4085 } 4086 free_compare(&c); 4087 4088 r1 = get_field(s, r1); 4089 a = get_address(s, 0, get_field(s, b2), get_field(s, d2)); 4090 switch (s->insn->data) { 4091 case 1: /* STOCG */ 4092 tcg_gen_qemu_st64(regs[r1], a, get_mem_index(s)); 4093 break; 4094 case 0: /* STOC */ 4095 tcg_gen_qemu_st32(regs[r1], a, get_mem_index(s)); 4096 break; 4097 case 2: /* STOCFH */ 4098 h = tcg_temp_new_i64(); 4099 tcg_gen_shri_i64(h, regs[r1], 32); 4100 tcg_gen_qemu_st32(h, a, get_mem_index(s)); 4101 tcg_temp_free_i64(h); 4102 break; 4103 default: 4104 g_assert_not_reached(); 4105 } 4106 tcg_temp_free_i64(a); 4107 4108 gen_set_label(lab); 4109 return DISAS_NEXT; 4110 } 4111 4112 static DisasJumpType op_sla(DisasContext *s, DisasOps *o) 4113 { 4114 uint64_t sign = 1ull << s->insn->data; 4115 enum cc_op cco = s->insn->data == 31 ? CC_OP_SLA_32 : CC_OP_SLA_64; 4116 gen_op_update2_cc_i64(s, cco, o->in1, o->in2); 4117 tcg_gen_shl_i64(o->out, o->in1, o->in2); 4118 /* The arithmetic left shift is curious in that it does not affect 4119 the sign bit. Copy that over from the source unchanged. */ 4120 tcg_gen_andi_i64(o->out, o->out, ~sign); 4121 tcg_gen_andi_i64(o->in1, o->in1, sign); 4122 tcg_gen_or_i64(o->out, o->out, o->in1); 4123 return DISAS_NEXT; 4124 } 4125 4126 static DisasJumpType op_sll(DisasContext *s, DisasOps *o) 4127 { 4128 tcg_gen_shl_i64(o->out, o->in1, o->in2); 4129 return DISAS_NEXT; 4130 } 4131 4132 static DisasJumpType op_sra(DisasContext *s, DisasOps *o) 4133 { 4134 tcg_gen_sar_i64(o->out, o->in1, o->in2); 4135 return DISAS_NEXT; 4136 } 4137 4138 static DisasJumpType op_srl(DisasContext *s, DisasOps *o) 4139 { 4140 tcg_gen_shr_i64(o->out, o->in1, o->in2); 4141 return DISAS_NEXT; 4142 } 4143 4144 static DisasJumpType op_sfpc(DisasContext *s, DisasOps *o) 4145 { 4146 gen_helper_sfpc(cpu_env, o->in2); 4147 return DISAS_NEXT; 4148 } 4149 4150 static DisasJumpType op_sfas(DisasContext *s, DisasOps *o) 4151 { 4152 gen_helper_sfas(cpu_env, o->in2); 4153 return DISAS_NEXT; 4154 } 4155 4156 static DisasJumpType op_srnm(DisasContext *s, DisasOps *o) 4157 { 4158 /* Bits other than 62 and 63 are ignored. Bit 29 is set to zero. */ 4159 tcg_gen_andi_i64(o->addr1, o->addr1, 0x3ull); 4160 gen_helper_srnm(cpu_env, o->addr1); 4161 return DISAS_NEXT; 4162 } 4163 4164 static DisasJumpType op_srnmb(DisasContext *s, DisasOps *o) 4165 { 4166 /* Bits 0-55 are are ignored. */ 4167 tcg_gen_andi_i64(o->addr1, o->addr1, 0xffull); 4168 gen_helper_srnm(cpu_env, o->addr1); 4169 return DISAS_NEXT; 4170 } 4171 4172 static DisasJumpType op_srnmt(DisasContext *s, DisasOps *o) 4173 { 4174 TCGv_i64 tmp = tcg_temp_new_i64(); 4175 4176 /* Bits other than 61-63 are ignored. */ 4177 tcg_gen_andi_i64(o->addr1, o->addr1, 0x7ull); 4178 4179 /* No need to call a helper, we don't implement dfp */ 4180 tcg_gen_ld32u_i64(tmp, cpu_env, offsetof(CPUS390XState, fpc)); 4181 tcg_gen_deposit_i64(tmp, tmp, o->addr1, 4, 3); 4182 tcg_gen_st32_i64(tmp, cpu_env, offsetof(CPUS390XState, fpc)); 4183 4184 tcg_temp_free_i64(tmp); 4185 return DISAS_NEXT; 4186 } 4187 4188 static DisasJumpType op_spm(DisasContext *s, DisasOps *o) 4189 { 4190 tcg_gen_extrl_i64_i32(cc_op, o->in1); 4191 tcg_gen_extract_i32(cc_op, cc_op, 28, 2); 4192 set_cc_static(s); 4193 4194 tcg_gen_shri_i64(o->in1, o->in1, 24); 4195 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in1, PSW_SHIFT_MASK_PM, 4); 4196 return DISAS_NEXT; 4197 } 4198 4199 static DisasJumpType op_ectg(DisasContext *s, DisasOps *o) 4200 { 4201 int b1 = get_field(s, b1); 4202 int d1 = get_field(s, d1); 4203 int b2 = get_field(s, b2); 4204 int d2 = get_field(s, d2); 4205 int r3 = get_field(s, r3); 4206 TCGv_i64 tmp = tcg_temp_new_i64(); 4207 4208 /* fetch all operands first */ 4209 o->in1 = tcg_temp_new_i64(); 4210 tcg_gen_addi_i64(o->in1, regs[b1], d1); 4211 o->in2 = tcg_temp_new_i64(); 4212 tcg_gen_addi_i64(o->in2, regs[b2], d2); 4213 o->addr1 = tcg_temp_new_i64(); 4214 gen_addi_and_wrap_i64(s, o->addr1, regs[r3], 0); 4215 4216 /* load the third operand into r3 before modifying anything */ 4217 tcg_gen_qemu_ld64(regs[r3], o->addr1, get_mem_index(s)); 4218 4219 /* subtract CPU timer from first operand and store in GR0 */ 4220 gen_helper_stpt(tmp, cpu_env); 4221 tcg_gen_sub_i64(regs[0], o->in1, tmp); 4222 4223 /* store second operand in GR1 */ 4224 tcg_gen_mov_i64(regs[1], o->in2); 4225 4226 tcg_temp_free_i64(tmp); 4227 return DISAS_NEXT; 4228 } 4229 4230 #ifndef CONFIG_USER_ONLY 4231 static DisasJumpType op_spka(DisasContext *s, DisasOps *o) 4232 { 4233 tcg_gen_shri_i64(o->in2, o->in2, 4); 4234 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, PSW_SHIFT_KEY, 4); 4235 return DISAS_NEXT; 4236 } 4237 4238 static DisasJumpType op_sske(DisasContext *s, DisasOps *o) 4239 { 4240 gen_helper_sske(cpu_env, o->in1, o->in2); 4241 return DISAS_NEXT; 4242 } 4243 4244 static DisasJumpType op_ssm(DisasContext *s, DisasOps *o) 4245 { 4246 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8); 4247 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */ 4248 return DISAS_PC_STALE_NOCHAIN; 4249 } 4250 4251 static DisasJumpType op_stap(DisasContext *s, DisasOps *o) 4252 { 4253 tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, core_id)); 4254 return DISAS_NEXT; 4255 } 4256 #endif 4257 4258 static DisasJumpType op_stck(DisasContext *s, DisasOps *o) 4259 { 4260 gen_helper_stck(o->out, cpu_env); 4261 /* ??? We don't implement clock states. */ 4262 gen_op_movi_cc(s, 0); 4263 return DISAS_NEXT; 4264 } 4265 4266 static DisasJumpType op_stcke(DisasContext *s, DisasOps *o) 4267 { 4268 TCGv_i64 c1 = tcg_temp_new_i64(); 4269 TCGv_i64 c2 = tcg_temp_new_i64(); 4270 TCGv_i64 todpr = tcg_temp_new_i64(); 4271 gen_helper_stck(c1, cpu_env); 4272 /* 16 bit value store in an uint32_t (only valid bits set) */ 4273 tcg_gen_ld32u_i64(todpr, cpu_env, offsetof(CPUS390XState, todpr)); 4274 /* Shift the 64-bit value into its place as a zero-extended 4275 104-bit value. Note that "bit positions 64-103 are always 4276 non-zero so that they compare differently to STCK"; we set 4277 the least significant bit to 1. */ 4278 tcg_gen_shli_i64(c2, c1, 56); 4279 tcg_gen_shri_i64(c1, c1, 8); 4280 tcg_gen_ori_i64(c2, c2, 0x10000); 4281 tcg_gen_or_i64(c2, c2, todpr); 4282 tcg_gen_qemu_st64(c1, o->in2, get_mem_index(s)); 4283 tcg_gen_addi_i64(o->in2, o->in2, 8); 4284 tcg_gen_qemu_st64(c2, o->in2, get_mem_index(s)); 4285 tcg_temp_free_i64(c1); 4286 tcg_temp_free_i64(c2); 4287 tcg_temp_free_i64(todpr); 4288 /* ??? We don't implement clock states. */ 4289 gen_op_movi_cc(s, 0); 4290 return DISAS_NEXT; 4291 } 4292 4293 #ifndef CONFIG_USER_ONLY 4294 static DisasJumpType op_sck(DisasContext *s, DisasOps *o) 4295 { 4296 tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), MO_TEQ | MO_ALIGN); 4297 gen_helper_sck(cc_op, cpu_env, o->in1); 4298 set_cc_static(s); 4299 return DISAS_NEXT; 4300 } 4301 4302 static DisasJumpType op_sckc(DisasContext *s, DisasOps *o) 4303 { 4304 gen_helper_sckc(cpu_env, o->in2); 4305 return DISAS_NEXT; 4306 } 4307 4308 static DisasJumpType op_sckpf(DisasContext *s, DisasOps *o) 4309 { 4310 gen_helper_sckpf(cpu_env, regs[0]); 4311 return DISAS_NEXT; 4312 } 4313 4314 static DisasJumpType op_stckc(DisasContext *s, DisasOps *o) 4315 { 4316 gen_helper_stckc(o->out, cpu_env); 4317 return DISAS_NEXT; 4318 } 4319 4320 static DisasJumpType op_stctg(DisasContext *s, DisasOps *o) 4321 { 4322 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 4323 TCGv_i32 r3 = tcg_const_i32(get_field(s, r3)); 4324 gen_helper_stctg(cpu_env, r1, o->in2, r3); 4325 tcg_temp_free_i32(r1); 4326 tcg_temp_free_i32(r3); 4327 return DISAS_NEXT; 4328 } 4329 4330 static DisasJumpType op_stctl(DisasContext *s, DisasOps *o) 4331 { 4332 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 4333 TCGv_i32 r3 = tcg_const_i32(get_field(s, r3)); 4334 gen_helper_stctl(cpu_env, r1, o->in2, r3); 4335 tcg_temp_free_i32(r1); 4336 tcg_temp_free_i32(r3); 4337 return DISAS_NEXT; 4338 } 4339 4340 static DisasJumpType op_stidp(DisasContext *s, DisasOps *o) 4341 { 4342 tcg_gen_ld_i64(o->out, cpu_env, offsetof(CPUS390XState, cpuid)); 4343 return DISAS_NEXT; 4344 } 4345 4346 static DisasJumpType op_spt(DisasContext *s, DisasOps *o) 4347 { 4348 gen_helper_spt(cpu_env, o->in2); 4349 return DISAS_NEXT; 4350 } 4351 4352 static DisasJumpType op_stfl(DisasContext *s, DisasOps *o) 4353 { 4354 gen_helper_stfl(cpu_env); 4355 return DISAS_NEXT; 4356 } 4357 4358 static DisasJumpType op_stpt(DisasContext *s, DisasOps *o) 4359 { 4360 gen_helper_stpt(o->out, cpu_env); 4361 return DISAS_NEXT; 4362 } 4363 4364 static DisasJumpType op_stsi(DisasContext *s, DisasOps *o) 4365 { 4366 gen_helper_stsi(cc_op, cpu_env, o->in2, regs[0], regs[1]); 4367 set_cc_static(s); 4368 return DISAS_NEXT; 4369 } 4370 4371 static DisasJumpType op_spx(DisasContext *s, DisasOps *o) 4372 { 4373 gen_helper_spx(cpu_env, o->in2); 4374 return DISAS_NEXT; 4375 } 4376 4377 static DisasJumpType op_xsch(DisasContext *s, DisasOps *o) 4378 { 4379 gen_helper_xsch(cpu_env, regs[1]); 4380 set_cc_static(s); 4381 return DISAS_NEXT; 4382 } 4383 4384 static DisasJumpType op_csch(DisasContext *s, DisasOps *o) 4385 { 4386 gen_helper_csch(cpu_env, regs[1]); 4387 set_cc_static(s); 4388 return DISAS_NEXT; 4389 } 4390 4391 static DisasJumpType op_hsch(DisasContext *s, DisasOps *o) 4392 { 4393 gen_helper_hsch(cpu_env, regs[1]); 4394 set_cc_static(s); 4395 return DISAS_NEXT; 4396 } 4397 4398 static DisasJumpType op_msch(DisasContext *s, DisasOps *o) 4399 { 4400 gen_helper_msch(cpu_env, regs[1], o->in2); 4401 set_cc_static(s); 4402 return DISAS_NEXT; 4403 } 4404 4405 static DisasJumpType op_rchp(DisasContext *s, DisasOps *o) 4406 { 4407 gen_helper_rchp(cpu_env, regs[1]); 4408 set_cc_static(s); 4409 return DISAS_NEXT; 4410 } 4411 4412 static DisasJumpType op_rsch(DisasContext *s, DisasOps *o) 4413 { 4414 gen_helper_rsch(cpu_env, regs[1]); 4415 set_cc_static(s); 4416 return DISAS_NEXT; 4417 } 4418 4419 static DisasJumpType op_sal(DisasContext *s, DisasOps *o) 4420 { 4421 gen_helper_sal(cpu_env, regs[1]); 4422 return DISAS_NEXT; 4423 } 4424 4425 static DisasJumpType op_schm(DisasContext *s, DisasOps *o) 4426 { 4427 gen_helper_schm(cpu_env, regs[1], regs[2], o->in2); 4428 return DISAS_NEXT; 4429 } 4430 4431 static DisasJumpType op_siga(DisasContext *s, DisasOps *o) 4432 { 4433 /* From KVM code: Not provided, set CC = 3 for subchannel not operational */ 4434 gen_op_movi_cc(s, 3); 4435 return DISAS_NEXT; 4436 } 4437 4438 static DisasJumpType op_stcps(DisasContext *s, DisasOps *o) 4439 { 4440 /* The instruction is suppressed if not provided. */ 4441 return DISAS_NEXT; 4442 } 4443 4444 static DisasJumpType op_ssch(DisasContext *s, DisasOps *o) 4445 { 4446 gen_helper_ssch(cpu_env, regs[1], o->in2); 4447 set_cc_static(s); 4448 return DISAS_NEXT; 4449 } 4450 4451 static DisasJumpType op_stsch(DisasContext *s, DisasOps *o) 4452 { 4453 gen_helper_stsch(cpu_env, regs[1], o->in2); 4454 set_cc_static(s); 4455 return DISAS_NEXT; 4456 } 4457 4458 static DisasJumpType op_stcrw(DisasContext *s, DisasOps *o) 4459 { 4460 gen_helper_stcrw(cpu_env, o->in2); 4461 set_cc_static(s); 4462 return DISAS_NEXT; 4463 } 4464 4465 static DisasJumpType op_tpi(DisasContext *s, DisasOps *o) 4466 { 4467 gen_helper_tpi(cc_op, cpu_env, o->addr1); 4468 set_cc_static(s); 4469 return DISAS_NEXT; 4470 } 4471 4472 static DisasJumpType op_tsch(DisasContext *s, DisasOps *o) 4473 { 4474 gen_helper_tsch(cpu_env, regs[1], o->in2); 4475 set_cc_static(s); 4476 return DISAS_NEXT; 4477 } 4478 4479 static DisasJumpType op_chsc(DisasContext *s, DisasOps *o) 4480 { 4481 gen_helper_chsc(cpu_env, o->in2); 4482 set_cc_static(s); 4483 return DISAS_NEXT; 4484 } 4485 4486 static DisasJumpType op_stpx(DisasContext *s, DisasOps *o) 4487 { 4488 tcg_gen_ld_i64(o->out, cpu_env, offsetof(CPUS390XState, psa)); 4489 tcg_gen_andi_i64(o->out, o->out, 0x7fffe000); 4490 return DISAS_NEXT; 4491 } 4492 4493 static DisasJumpType op_stnosm(DisasContext *s, DisasOps *o) 4494 { 4495 uint64_t i2 = get_field(s, i2); 4496 TCGv_i64 t; 4497 4498 /* It is important to do what the instruction name says: STORE THEN. 4499 If we let the output hook perform the store then if we fault and 4500 restart, we'll have the wrong SYSTEM MASK in place. */ 4501 t = tcg_temp_new_i64(); 4502 tcg_gen_shri_i64(t, psw_mask, 56); 4503 tcg_gen_qemu_st8(t, o->addr1, get_mem_index(s)); 4504 tcg_temp_free_i64(t); 4505 4506 if (s->fields.op == 0xac) { 4507 tcg_gen_andi_i64(psw_mask, psw_mask, 4508 (i2 << 56) | 0x00ffffffffffffffull); 4509 } else { 4510 tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56); 4511 } 4512 4513 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */ 4514 return DISAS_PC_STALE_NOCHAIN; 4515 } 4516 4517 static DisasJumpType op_stura(DisasContext *s, DisasOps *o) 4518 { 4519 tcg_gen_qemu_st_tl(o->in1, o->in2, MMU_REAL_IDX, s->insn->data); 4520 4521 if (s->base.tb->flags & FLAG_MASK_PER) { 4522 update_psw_addr(s); 4523 gen_helper_per_store_real(cpu_env); 4524 } 4525 return DISAS_NEXT; 4526 } 4527 #endif 4528 4529 static DisasJumpType op_stfle(DisasContext *s, DisasOps *o) 4530 { 4531 gen_helper_stfle(cc_op, cpu_env, o->in2); 4532 set_cc_static(s); 4533 return DISAS_NEXT; 4534 } 4535 4536 static DisasJumpType op_st8(DisasContext *s, DisasOps *o) 4537 { 4538 tcg_gen_qemu_st8(o->in1, o->in2, get_mem_index(s)); 4539 return DISAS_NEXT; 4540 } 4541 4542 static DisasJumpType op_st16(DisasContext *s, DisasOps *o) 4543 { 4544 tcg_gen_qemu_st16(o->in1, o->in2, get_mem_index(s)); 4545 return DISAS_NEXT; 4546 } 4547 4548 static DisasJumpType op_st32(DisasContext *s, DisasOps *o) 4549 { 4550 tcg_gen_qemu_st32(o->in1, o->in2, get_mem_index(s)); 4551 return DISAS_NEXT; 4552 } 4553 4554 static DisasJumpType op_st64(DisasContext *s, DisasOps *o) 4555 { 4556 tcg_gen_qemu_st64(o->in1, o->in2, get_mem_index(s)); 4557 return DISAS_NEXT; 4558 } 4559 4560 static DisasJumpType op_stam(DisasContext *s, DisasOps *o) 4561 { 4562 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 4563 TCGv_i32 r3 = tcg_const_i32(get_field(s, r3)); 4564 gen_helper_stam(cpu_env, r1, o->in2, r3); 4565 tcg_temp_free_i32(r1); 4566 tcg_temp_free_i32(r3); 4567 return DISAS_NEXT; 4568 } 4569 4570 static DisasJumpType op_stcm(DisasContext *s, DisasOps *o) 4571 { 4572 int m3 = get_field(s, m3); 4573 int pos, base = s->insn->data; 4574 TCGv_i64 tmp = tcg_temp_new_i64(); 4575 4576 pos = base + ctz32(m3) * 8; 4577 switch (m3) { 4578 case 0xf: 4579 /* Effectively a 32-bit store. */ 4580 tcg_gen_shri_i64(tmp, o->in1, pos); 4581 tcg_gen_qemu_st32(tmp, o->in2, get_mem_index(s)); 4582 break; 4583 4584 case 0xc: 4585 case 0x6: 4586 case 0x3: 4587 /* Effectively a 16-bit store. */ 4588 tcg_gen_shri_i64(tmp, o->in1, pos); 4589 tcg_gen_qemu_st16(tmp, o->in2, get_mem_index(s)); 4590 break; 4591 4592 case 0x8: 4593 case 0x4: 4594 case 0x2: 4595 case 0x1: 4596 /* Effectively an 8-bit store. */ 4597 tcg_gen_shri_i64(tmp, o->in1, pos); 4598 tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s)); 4599 break; 4600 4601 default: 4602 /* This is going to be a sequence of shifts and stores. */ 4603 pos = base + 32 - 8; 4604 while (m3) { 4605 if (m3 & 0x8) { 4606 tcg_gen_shri_i64(tmp, o->in1, pos); 4607 tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s)); 4608 tcg_gen_addi_i64(o->in2, o->in2, 1); 4609 } 4610 m3 = (m3 << 1) & 0xf; 4611 pos -= 8; 4612 } 4613 break; 4614 } 4615 tcg_temp_free_i64(tmp); 4616 return DISAS_NEXT; 4617 } 4618 4619 static DisasJumpType op_stm(DisasContext *s, DisasOps *o) 4620 { 4621 int r1 = get_field(s, r1); 4622 int r3 = get_field(s, r3); 4623 int size = s->insn->data; 4624 TCGv_i64 tsize = tcg_const_i64(size); 4625 4626 while (1) { 4627 if (size == 8) { 4628 tcg_gen_qemu_st64(regs[r1], o->in2, get_mem_index(s)); 4629 } else { 4630 tcg_gen_qemu_st32(regs[r1], o->in2, get_mem_index(s)); 4631 } 4632 if (r1 == r3) { 4633 break; 4634 } 4635 tcg_gen_add_i64(o->in2, o->in2, tsize); 4636 r1 = (r1 + 1) & 15; 4637 } 4638 4639 tcg_temp_free_i64(tsize); 4640 return DISAS_NEXT; 4641 } 4642 4643 static DisasJumpType op_stmh(DisasContext *s, DisasOps *o) 4644 { 4645 int r1 = get_field(s, r1); 4646 int r3 = get_field(s, r3); 4647 TCGv_i64 t = tcg_temp_new_i64(); 4648 TCGv_i64 t4 = tcg_const_i64(4); 4649 TCGv_i64 t32 = tcg_const_i64(32); 4650 4651 while (1) { 4652 tcg_gen_shl_i64(t, regs[r1], t32); 4653 tcg_gen_qemu_st32(t, o->in2, get_mem_index(s)); 4654 if (r1 == r3) { 4655 break; 4656 } 4657 tcg_gen_add_i64(o->in2, o->in2, t4); 4658 r1 = (r1 + 1) & 15; 4659 } 4660 4661 tcg_temp_free_i64(t); 4662 tcg_temp_free_i64(t4); 4663 tcg_temp_free_i64(t32); 4664 return DISAS_NEXT; 4665 } 4666 4667 static DisasJumpType op_stpq(DisasContext *s, DisasOps *o) 4668 { 4669 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) { 4670 gen_helper_stpq(cpu_env, o->in2, o->out2, o->out); 4671 } else if (HAVE_ATOMIC128) { 4672 gen_helper_stpq_parallel(cpu_env, o->in2, o->out2, o->out); 4673 } else { 4674 gen_helper_exit_atomic(cpu_env); 4675 return DISAS_NORETURN; 4676 } 4677 return DISAS_NEXT; 4678 } 4679 4680 static DisasJumpType op_srst(DisasContext *s, DisasOps *o) 4681 { 4682 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 4683 TCGv_i32 r2 = tcg_const_i32(get_field(s, r2)); 4684 4685 gen_helper_srst(cpu_env, r1, r2); 4686 4687 tcg_temp_free_i32(r1); 4688 tcg_temp_free_i32(r2); 4689 set_cc_static(s); 4690 return DISAS_NEXT; 4691 } 4692 4693 static DisasJumpType op_srstu(DisasContext *s, DisasOps *o) 4694 { 4695 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 4696 TCGv_i32 r2 = tcg_const_i32(get_field(s, r2)); 4697 4698 gen_helper_srstu(cpu_env, r1, r2); 4699 4700 tcg_temp_free_i32(r1); 4701 tcg_temp_free_i32(r2); 4702 set_cc_static(s); 4703 return DISAS_NEXT; 4704 } 4705 4706 static DisasJumpType op_sub(DisasContext *s, DisasOps *o) 4707 { 4708 tcg_gen_sub_i64(o->out, o->in1, o->in2); 4709 return DISAS_NEXT; 4710 } 4711 4712 static DisasJumpType op_subu64(DisasContext *s, DisasOps *o) 4713 { 4714 tcg_gen_movi_i64(cc_src, 0); 4715 tcg_gen_sub2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src); 4716 return DISAS_NEXT; 4717 } 4718 4719 /* Compute borrow (0, -1) into cc_src. */ 4720 static void compute_borrow(DisasContext *s) 4721 { 4722 switch (s->cc_op) { 4723 case CC_OP_SUBU: 4724 /* The borrow value is already in cc_src (0,-1). */ 4725 break; 4726 default: 4727 gen_op_calc_cc(s); 4728 /* fall through */ 4729 case CC_OP_STATIC: 4730 /* The carry flag is the msb of CC; compute into cc_src. */ 4731 tcg_gen_extu_i32_i64(cc_src, cc_op); 4732 tcg_gen_shri_i64(cc_src, cc_src, 1); 4733 /* fall through */ 4734 case CC_OP_ADDU: 4735 /* Convert carry (1,0) to borrow (0,-1). */ 4736 tcg_gen_subi_i64(cc_src, cc_src, 1); 4737 break; 4738 } 4739 } 4740 4741 static DisasJumpType op_subb32(DisasContext *s, DisasOps *o) 4742 { 4743 compute_borrow(s); 4744 4745 /* Borrow is {0, -1}, so add to subtract. */ 4746 tcg_gen_add_i64(o->out, o->in1, cc_src); 4747 tcg_gen_sub_i64(o->out, o->out, o->in2); 4748 return DISAS_NEXT; 4749 } 4750 4751 static DisasJumpType op_subb64(DisasContext *s, DisasOps *o) 4752 { 4753 compute_borrow(s); 4754 4755 /* 4756 * Borrow is {0, -1}, so add to subtract; replicate the 4757 * borrow input to produce 128-bit -1 for the addition. 4758 */ 4759 TCGv_i64 zero = tcg_const_i64(0); 4760 tcg_gen_add2_i64(o->out, cc_src, o->in1, zero, cc_src, cc_src); 4761 tcg_gen_sub2_i64(o->out, cc_src, o->out, cc_src, o->in2, zero); 4762 tcg_temp_free_i64(zero); 4763 4764 return DISAS_NEXT; 4765 } 4766 4767 static DisasJumpType op_svc(DisasContext *s, DisasOps *o) 4768 { 4769 TCGv_i32 t; 4770 4771 update_psw_addr(s); 4772 update_cc_op(s); 4773 4774 t = tcg_const_i32(get_field(s, i1) & 0xff); 4775 tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_code)); 4776 tcg_temp_free_i32(t); 4777 4778 t = tcg_const_i32(s->ilen); 4779 tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_ilen)); 4780 tcg_temp_free_i32(t); 4781 4782 gen_exception(EXCP_SVC); 4783 return DISAS_NORETURN; 4784 } 4785 4786 static DisasJumpType op_tam(DisasContext *s, DisasOps *o) 4787 { 4788 int cc = 0; 4789 4790 cc |= (s->base.tb->flags & FLAG_MASK_64) ? 2 : 0; 4791 cc |= (s->base.tb->flags & FLAG_MASK_32) ? 1 : 0; 4792 gen_op_movi_cc(s, cc); 4793 return DISAS_NEXT; 4794 } 4795 4796 static DisasJumpType op_tceb(DisasContext *s, DisasOps *o) 4797 { 4798 gen_helper_tceb(cc_op, cpu_env, o->in1, o->in2); 4799 set_cc_static(s); 4800 return DISAS_NEXT; 4801 } 4802 4803 static DisasJumpType op_tcdb(DisasContext *s, DisasOps *o) 4804 { 4805 gen_helper_tcdb(cc_op, cpu_env, o->in1, o->in2); 4806 set_cc_static(s); 4807 return DISAS_NEXT; 4808 } 4809 4810 static DisasJumpType op_tcxb(DisasContext *s, DisasOps *o) 4811 { 4812 gen_helper_tcxb(cc_op, cpu_env, o->out, o->out2, o->in2); 4813 set_cc_static(s); 4814 return DISAS_NEXT; 4815 } 4816 4817 #ifndef CONFIG_USER_ONLY 4818 4819 static DisasJumpType op_testblock(DisasContext *s, DisasOps *o) 4820 { 4821 gen_helper_testblock(cc_op, cpu_env, o->in2); 4822 set_cc_static(s); 4823 return DISAS_NEXT; 4824 } 4825 4826 static DisasJumpType op_tprot(DisasContext *s, DisasOps *o) 4827 { 4828 gen_helper_tprot(cc_op, cpu_env, o->addr1, o->in2); 4829 set_cc_static(s); 4830 return DISAS_NEXT; 4831 } 4832 4833 #endif 4834 4835 static DisasJumpType op_tp(DisasContext *s, DisasOps *o) 4836 { 4837 TCGv_i32 l1 = tcg_const_i32(get_field(s, l1) + 1); 4838 gen_helper_tp(cc_op, cpu_env, o->addr1, l1); 4839 tcg_temp_free_i32(l1); 4840 set_cc_static(s); 4841 return DISAS_NEXT; 4842 } 4843 4844 static DisasJumpType op_tr(DisasContext *s, DisasOps *o) 4845 { 4846 TCGv_i32 l = tcg_const_i32(get_field(s, l1)); 4847 gen_helper_tr(cpu_env, l, o->addr1, o->in2); 4848 tcg_temp_free_i32(l); 4849 set_cc_static(s); 4850 return DISAS_NEXT; 4851 } 4852 4853 static DisasJumpType op_tre(DisasContext *s, DisasOps *o) 4854 { 4855 gen_helper_tre(o->out, cpu_env, o->out, o->out2, o->in2); 4856 return_low128(o->out2); 4857 set_cc_static(s); 4858 return DISAS_NEXT; 4859 } 4860 4861 static DisasJumpType op_trt(DisasContext *s, DisasOps *o) 4862 { 4863 TCGv_i32 l = tcg_const_i32(get_field(s, l1)); 4864 gen_helper_trt(cc_op, cpu_env, l, o->addr1, o->in2); 4865 tcg_temp_free_i32(l); 4866 set_cc_static(s); 4867 return DISAS_NEXT; 4868 } 4869 4870 static DisasJumpType op_trtr(DisasContext *s, DisasOps *o) 4871 { 4872 TCGv_i32 l = tcg_const_i32(get_field(s, l1)); 4873 gen_helper_trtr(cc_op, cpu_env, l, o->addr1, o->in2); 4874 tcg_temp_free_i32(l); 4875 set_cc_static(s); 4876 return DISAS_NEXT; 4877 } 4878 4879 static DisasJumpType op_trXX(DisasContext *s, DisasOps *o) 4880 { 4881 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 4882 TCGv_i32 r2 = tcg_const_i32(get_field(s, r2)); 4883 TCGv_i32 sizes = tcg_const_i32(s->insn->opc & 3); 4884 TCGv_i32 tst = tcg_temp_new_i32(); 4885 int m3 = get_field(s, m3); 4886 4887 if (!s390_has_feat(S390_FEAT_ETF2_ENH)) { 4888 m3 = 0; 4889 } 4890 if (m3 & 1) { 4891 tcg_gen_movi_i32(tst, -1); 4892 } else { 4893 tcg_gen_extrl_i64_i32(tst, regs[0]); 4894 if (s->insn->opc & 3) { 4895 tcg_gen_ext8u_i32(tst, tst); 4896 } else { 4897 tcg_gen_ext16u_i32(tst, tst); 4898 } 4899 } 4900 gen_helper_trXX(cc_op, cpu_env, r1, r2, tst, sizes); 4901 4902 tcg_temp_free_i32(r1); 4903 tcg_temp_free_i32(r2); 4904 tcg_temp_free_i32(sizes); 4905 tcg_temp_free_i32(tst); 4906 set_cc_static(s); 4907 return DISAS_NEXT; 4908 } 4909 4910 static DisasJumpType op_ts(DisasContext *s, DisasOps *o) 4911 { 4912 TCGv_i32 t1 = tcg_const_i32(0xff); 4913 tcg_gen_atomic_xchg_i32(t1, o->in2, t1, get_mem_index(s), MO_UB); 4914 tcg_gen_extract_i32(cc_op, t1, 7, 1); 4915 tcg_temp_free_i32(t1); 4916 set_cc_static(s); 4917 return DISAS_NEXT; 4918 } 4919 4920 static DisasJumpType op_unpk(DisasContext *s, DisasOps *o) 4921 { 4922 TCGv_i32 l = tcg_const_i32(get_field(s, l1)); 4923 gen_helper_unpk(cpu_env, l, o->addr1, o->in2); 4924 tcg_temp_free_i32(l); 4925 return DISAS_NEXT; 4926 } 4927 4928 static DisasJumpType op_unpka(DisasContext *s, DisasOps *o) 4929 { 4930 int l1 = get_field(s, l1) + 1; 4931 TCGv_i32 l; 4932 4933 /* The length must not exceed 32 bytes. */ 4934 if (l1 > 32) { 4935 gen_program_exception(s, PGM_SPECIFICATION); 4936 return DISAS_NORETURN; 4937 } 4938 l = tcg_const_i32(l1); 4939 gen_helper_unpka(cc_op, cpu_env, o->addr1, l, o->in2); 4940 tcg_temp_free_i32(l); 4941 set_cc_static(s); 4942 return DISAS_NEXT; 4943 } 4944 4945 static DisasJumpType op_unpku(DisasContext *s, DisasOps *o) 4946 { 4947 int l1 = get_field(s, l1) + 1; 4948 TCGv_i32 l; 4949 4950 /* The length must be even and should not exceed 64 bytes. */ 4951 if ((l1 & 1) || (l1 > 64)) { 4952 gen_program_exception(s, PGM_SPECIFICATION); 4953 return DISAS_NORETURN; 4954 } 4955 l = tcg_const_i32(l1); 4956 gen_helper_unpku(cc_op, cpu_env, o->addr1, l, o->in2); 4957 tcg_temp_free_i32(l); 4958 set_cc_static(s); 4959 return DISAS_NEXT; 4960 } 4961 4962 4963 static DisasJumpType op_xc(DisasContext *s, DisasOps *o) 4964 { 4965 int d1 = get_field(s, d1); 4966 int d2 = get_field(s, d2); 4967 int b1 = get_field(s, b1); 4968 int b2 = get_field(s, b2); 4969 int l = get_field(s, l1); 4970 TCGv_i32 t32; 4971 4972 o->addr1 = get_address(s, 0, b1, d1); 4973 4974 /* If the addresses are identical, this is a store/memset of zero. */ 4975 if (b1 == b2 && d1 == d2 && (l + 1) <= 32) { 4976 o->in2 = tcg_const_i64(0); 4977 4978 l++; 4979 while (l >= 8) { 4980 tcg_gen_qemu_st64(o->in2, o->addr1, get_mem_index(s)); 4981 l -= 8; 4982 if (l > 0) { 4983 tcg_gen_addi_i64(o->addr1, o->addr1, 8); 4984 } 4985 } 4986 if (l >= 4) { 4987 tcg_gen_qemu_st32(o->in2, o->addr1, get_mem_index(s)); 4988 l -= 4; 4989 if (l > 0) { 4990 tcg_gen_addi_i64(o->addr1, o->addr1, 4); 4991 } 4992 } 4993 if (l >= 2) { 4994 tcg_gen_qemu_st16(o->in2, o->addr1, get_mem_index(s)); 4995 l -= 2; 4996 if (l > 0) { 4997 tcg_gen_addi_i64(o->addr1, o->addr1, 2); 4998 } 4999 } 5000 if (l) { 5001 tcg_gen_qemu_st8(o->in2, o->addr1, get_mem_index(s)); 5002 } 5003 gen_op_movi_cc(s, 0); 5004 return DISAS_NEXT; 5005 } 5006 5007 /* But in general we'll defer to a helper. */ 5008 o->in2 = get_address(s, 0, b2, d2); 5009 t32 = tcg_const_i32(l); 5010 gen_helper_xc(cc_op, cpu_env, t32, o->addr1, o->in2); 5011 tcg_temp_free_i32(t32); 5012 set_cc_static(s); 5013 return DISAS_NEXT; 5014 } 5015 5016 static DisasJumpType op_xor(DisasContext *s, DisasOps *o) 5017 { 5018 tcg_gen_xor_i64(o->out, o->in1, o->in2); 5019 return DISAS_NEXT; 5020 } 5021 5022 static DisasJumpType op_xori(DisasContext *s, DisasOps *o) 5023 { 5024 int shift = s->insn->data & 0xff; 5025 int size = s->insn->data >> 8; 5026 uint64_t mask = ((1ull << size) - 1) << shift; 5027 5028 assert(!o->g_in2); 5029 tcg_gen_shli_i64(o->in2, o->in2, shift); 5030 tcg_gen_xor_i64(o->out, o->in1, o->in2); 5031 5032 /* Produce the CC from only the bits manipulated. */ 5033 tcg_gen_andi_i64(cc_dst, o->out, mask); 5034 set_cc_nz_u64(s, cc_dst); 5035 return DISAS_NEXT; 5036 } 5037 5038 static DisasJumpType op_xi(DisasContext *s, DisasOps *o) 5039 { 5040 o->in1 = tcg_temp_new_i64(); 5041 5042 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) { 5043 tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data); 5044 } else { 5045 /* Perform the atomic operation in memory. */ 5046 tcg_gen_atomic_fetch_xor_i64(o->in1, o->addr1, o->in2, get_mem_index(s), 5047 s->insn->data); 5048 } 5049 5050 /* Recompute also for atomic case: needed for setting CC. */ 5051 tcg_gen_xor_i64(o->out, o->in1, o->in2); 5052 5053 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) { 5054 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data); 5055 } 5056 return DISAS_NEXT; 5057 } 5058 5059 static DisasJumpType op_zero(DisasContext *s, DisasOps *o) 5060 { 5061 o->out = tcg_const_i64(0); 5062 return DISAS_NEXT; 5063 } 5064 5065 static DisasJumpType op_zero2(DisasContext *s, DisasOps *o) 5066 { 5067 o->out = tcg_const_i64(0); 5068 o->out2 = o->out; 5069 o->g_out2 = true; 5070 return DISAS_NEXT; 5071 } 5072 5073 #ifndef CONFIG_USER_ONLY 5074 static DisasJumpType op_clp(DisasContext *s, DisasOps *o) 5075 { 5076 TCGv_i32 r2 = tcg_const_i32(get_field(s, r2)); 5077 5078 gen_helper_clp(cpu_env, r2); 5079 tcg_temp_free_i32(r2); 5080 set_cc_static(s); 5081 return DISAS_NEXT; 5082 } 5083 5084 static DisasJumpType op_pcilg(DisasContext *s, DisasOps *o) 5085 { 5086 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 5087 TCGv_i32 r2 = tcg_const_i32(get_field(s, r2)); 5088 5089 gen_helper_pcilg(cpu_env, r1, r2); 5090 tcg_temp_free_i32(r1); 5091 tcg_temp_free_i32(r2); 5092 set_cc_static(s); 5093 return DISAS_NEXT; 5094 } 5095 5096 static DisasJumpType op_pcistg(DisasContext *s, DisasOps *o) 5097 { 5098 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 5099 TCGv_i32 r2 = tcg_const_i32(get_field(s, r2)); 5100 5101 gen_helper_pcistg(cpu_env, r1, r2); 5102 tcg_temp_free_i32(r1); 5103 tcg_temp_free_i32(r2); 5104 set_cc_static(s); 5105 return DISAS_NEXT; 5106 } 5107 5108 static DisasJumpType op_stpcifc(DisasContext *s, DisasOps *o) 5109 { 5110 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 5111 TCGv_i32 ar = tcg_const_i32(get_field(s, b2)); 5112 5113 gen_helper_stpcifc(cpu_env, r1, o->addr1, ar); 5114 tcg_temp_free_i32(ar); 5115 tcg_temp_free_i32(r1); 5116 set_cc_static(s); 5117 return DISAS_NEXT; 5118 } 5119 5120 static DisasJumpType op_sic(DisasContext *s, DisasOps *o) 5121 { 5122 gen_helper_sic(cpu_env, o->in1, o->in2); 5123 return DISAS_NEXT; 5124 } 5125 5126 static DisasJumpType op_rpcit(DisasContext *s, DisasOps *o) 5127 { 5128 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 5129 TCGv_i32 r2 = tcg_const_i32(get_field(s, r2)); 5130 5131 gen_helper_rpcit(cpu_env, r1, r2); 5132 tcg_temp_free_i32(r1); 5133 tcg_temp_free_i32(r2); 5134 set_cc_static(s); 5135 return DISAS_NEXT; 5136 } 5137 5138 static DisasJumpType op_pcistb(DisasContext *s, DisasOps *o) 5139 { 5140 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 5141 TCGv_i32 r3 = tcg_const_i32(get_field(s, r3)); 5142 TCGv_i32 ar = tcg_const_i32(get_field(s, b2)); 5143 5144 gen_helper_pcistb(cpu_env, r1, r3, o->addr1, ar); 5145 tcg_temp_free_i32(ar); 5146 tcg_temp_free_i32(r1); 5147 tcg_temp_free_i32(r3); 5148 set_cc_static(s); 5149 return DISAS_NEXT; 5150 } 5151 5152 static DisasJumpType op_mpcifc(DisasContext *s, DisasOps *o) 5153 { 5154 TCGv_i32 r1 = tcg_const_i32(get_field(s, r1)); 5155 TCGv_i32 ar = tcg_const_i32(get_field(s, b2)); 5156 5157 gen_helper_mpcifc(cpu_env, r1, o->addr1, ar); 5158 tcg_temp_free_i32(ar); 5159 tcg_temp_free_i32(r1); 5160 set_cc_static(s); 5161 return DISAS_NEXT; 5162 } 5163 #endif 5164 5165 #include "translate_vx.c.inc" 5166 5167 /* ====================================================================== */ 5168 /* The "Cc OUTput" generators. Given the generated output (and in some cases 5169 the original inputs), update the various cc data structures in order to 5170 be able to compute the new condition code. */ 5171 5172 static void cout_abs32(DisasContext *s, DisasOps *o) 5173 { 5174 gen_op_update1_cc_i64(s, CC_OP_ABS_32, o->out); 5175 } 5176 5177 static void cout_abs64(DisasContext *s, DisasOps *o) 5178 { 5179 gen_op_update1_cc_i64(s, CC_OP_ABS_64, o->out); 5180 } 5181 5182 static void cout_adds32(DisasContext *s, DisasOps *o) 5183 { 5184 gen_op_update3_cc_i64(s, CC_OP_ADD_32, o->in1, o->in2, o->out); 5185 } 5186 5187 static void cout_adds64(DisasContext *s, DisasOps *o) 5188 { 5189 gen_op_update3_cc_i64(s, CC_OP_ADD_64, o->in1, o->in2, o->out); 5190 } 5191 5192 static void cout_addu32(DisasContext *s, DisasOps *o) 5193 { 5194 tcg_gen_shri_i64(cc_src, o->out, 32); 5195 tcg_gen_ext32u_i64(cc_dst, o->out); 5196 gen_op_update2_cc_i64(s, CC_OP_ADDU, cc_src, cc_dst); 5197 } 5198 5199 static void cout_addu64(DisasContext *s, DisasOps *o) 5200 { 5201 gen_op_update2_cc_i64(s, CC_OP_ADDU, cc_src, o->out); 5202 } 5203 5204 static void cout_cmps32(DisasContext *s, DisasOps *o) 5205 { 5206 gen_op_update2_cc_i64(s, CC_OP_LTGT_32, o->in1, o->in2); 5207 } 5208 5209 static void cout_cmps64(DisasContext *s, DisasOps *o) 5210 { 5211 gen_op_update2_cc_i64(s, CC_OP_LTGT_64, o->in1, o->in2); 5212 } 5213 5214 static void cout_cmpu32(DisasContext *s, DisasOps *o) 5215 { 5216 gen_op_update2_cc_i64(s, CC_OP_LTUGTU_32, o->in1, o->in2); 5217 } 5218 5219 static void cout_cmpu64(DisasContext *s, DisasOps *o) 5220 { 5221 gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, o->in1, o->in2); 5222 } 5223 5224 static void cout_f32(DisasContext *s, DisasOps *o) 5225 { 5226 gen_op_update1_cc_i64(s, CC_OP_NZ_F32, o->out); 5227 } 5228 5229 static void cout_f64(DisasContext *s, DisasOps *o) 5230 { 5231 gen_op_update1_cc_i64(s, CC_OP_NZ_F64, o->out); 5232 } 5233 5234 static void cout_f128(DisasContext *s, DisasOps *o) 5235 { 5236 gen_op_update2_cc_i64(s, CC_OP_NZ_F128, o->out, o->out2); 5237 } 5238 5239 static void cout_nabs32(DisasContext *s, DisasOps *o) 5240 { 5241 gen_op_update1_cc_i64(s, CC_OP_NABS_32, o->out); 5242 } 5243 5244 static void cout_nabs64(DisasContext *s, DisasOps *o) 5245 { 5246 gen_op_update1_cc_i64(s, CC_OP_NABS_64, o->out); 5247 } 5248 5249 static void cout_neg32(DisasContext *s, DisasOps *o) 5250 { 5251 gen_op_update1_cc_i64(s, CC_OP_COMP_32, o->out); 5252 } 5253 5254 static void cout_neg64(DisasContext *s, DisasOps *o) 5255 { 5256 gen_op_update1_cc_i64(s, CC_OP_COMP_64, o->out); 5257 } 5258 5259 static void cout_nz32(DisasContext *s, DisasOps *o) 5260 { 5261 tcg_gen_ext32u_i64(cc_dst, o->out); 5262 gen_op_update1_cc_i64(s, CC_OP_NZ, cc_dst); 5263 } 5264 5265 static void cout_nz64(DisasContext *s, DisasOps *o) 5266 { 5267 gen_op_update1_cc_i64(s, CC_OP_NZ, o->out); 5268 } 5269 5270 static void cout_s32(DisasContext *s, DisasOps *o) 5271 { 5272 gen_op_update1_cc_i64(s, CC_OP_LTGT0_32, o->out); 5273 } 5274 5275 static void cout_s64(DisasContext *s, DisasOps *o) 5276 { 5277 gen_op_update1_cc_i64(s, CC_OP_LTGT0_64, o->out); 5278 } 5279 5280 static void cout_subs32(DisasContext *s, DisasOps *o) 5281 { 5282 gen_op_update3_cc_i64(s, CC_OP_SUB_32, o->in1, o->in2, o->out); 5283 } 5284 5285 static void cout_subs64(DisasContext *s, DisasOps *o) 5286 { 5287 gen_op_update3_cc_i64(s, CC_OP_SUB_64, o->in1, o->in2, o->out); 5288 } 5289 5290 static void cout_subu32(DisasContext *s, DisasOps *o) 5291 { 5292 tcg_gen_sari_i64(cc_src, o->out, 32); 5293 tcg_gen_ext32u_i64(cc_dst, o->out); 5294 gen_op_update2_cc_i64(s, CC_OP_SUBU, cc_src, cc_dst); 5295 } 5296 5297 static void cout_subu64(DisasContext *s, DisasOps *o) 5298 { 5299 gen_op_update2_cc_i64(s, CC_OP_SUBU, cc_src, o->out); 5300 } 5301 5302 static void cout_tm32(DisasContext *s, DisasOps *o) 5303 { 5304 gen_op_update2_cc_i64(s, CC_OP_TM_32, o->in1, o->in2); 5305 } 5306 5307 static void cout_tm64(DisasContext *s, DisasOps *o) 5308 { 5309 gen_op_update2_cc_i64(s, CC_OP_TM_64, o->in1, o->in2); 5310 } 5311 5312 static void cout_muls32(DisasContext *s, DisasOps *o) 5313 { 5314 gen_op_update1_cc_i64(s, CC_OP_MULS_32, o->out); 5315 } 5316 5317 static void cout_muls64(DisasContext *s, DisasOps *o) 5318 { 5319 /* out contains "high" part, out2 contains "low" part of 128 bit result */ 5320 gen_op_update2_cc_i64(s, CC_OP_MULS_64, o->out, o->out2); 5321 } 5322 5323 /* ====================================================================== */ 5324 /* The "PREParation" generators. These initialize the DisasOps.OUT fields 5325 with the TCG register to which we will write. Used in combination with 5326 the "wout" generators, in some cases we need a new temporary, and in 5327 some cases we can write to a TCG global. */ 5328 5329 static void prep_new(DisasContext *s, DisasOps *o) 5330 { 5331 o->out = tcg_temp_new_i64(); 5332 } 5333 #define SPEC_prep_new 0 5334 5335 static void prep_new_P(DisasContext *s, DisasOps *o) 5336 { 5337 o->out = tcg_temp_new_i64(); 5338 o->out2 = tcg_temp_new_i64(); 5339 } 5340 #define SPEC_prep_new_P 0 5341 5342 static void prep_r1(DisasContext *s, DisasOps *o) 5343 { 5344 o->out = regs[get_field(s, r1)]; 5345 o->g_out = true; 5346 } 5347 #define SPEC_prep_r1 0 5348 5349 static void prep_r1_P(DisasContext *s, DisasOps *o) 5350 { 5351 int r1 = get_field(s, r1); 5352 o->out = regs[r1]; 5353 o->out2 = regs[r1 + 1]; 5354 o->g_out = o->g_out2 = true; 5355 } 5356 #define SPEC_prep_r1_P SPEC_r1_even 5357 5358 /* Whenever we need x1 in addition to other inputs, we'll load it to out/out2 */ 5359 static void prep_x1(DisasContext *s, DisasOps *o) 5360 { 5361 o->out = load_freg(get_field(s, r1)); 5362 o->out2 = load_freg(get_field(s, r1) + 2); 5363 } 5364 #define SPEC_prep_x1 SPEC_r1_f128 5365 5366 /* ====================================================================== */ 5367 /* The "Write OUTput" generators. These generally perform some non-trivial 5368 copy of data to TCG globals, or to main memory. The trivial cases are 5369 generally handled by having a "prep" generator install the TCG global 5370 as the destination of the operation. */ 5371 5372 static void wout_r1(DisasContext *s, DisasOps *o) 5373 { 5374 store_reg(get_field(s, r1), o->out); 5375 } 5376 #define SPEC_wout_r1 0 5377 5378 static void wout_out2_r1(DisasContext *s, DisasOps *o) 5379 { 5380 store_reg(get_field(s, r1), o->out2); 5381 } 5382 #define SPEC_wout_out2_r1 0 5383 5384 static void wout_r1_8(DisasContext *s, DisasOps *o) 5385 { 5386 int r1 = get_field(s, r1); 5387 tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 8); 5388 } 5389 #define SPEC_wout_r1_8 0 5390 5391 static void wout_r1_16(DisasContext *s, DisasOps *o) 5392 { 5393 int r1 = get_field(s, r1); 5394 tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 16); 5395 } 5396 #define SPEC_wout_r1_16 0 5397 5398 static void wout_r1_32(DisasContext *s, DisasOps *o) 5399 { 5400 store_reg32_i64(get_field(s, r1), o->out); 5401 } 5402 #define SPEC_wout_r1_32 0 5403 5404 static void wout_r1_32h(DisasContext *s, DisasOps *o) 5405 { 5406 store_reg32h_i64(get_field(s, r1), o->out); 5407 } 5408 #define SPEC_wout_r1_32h 0 5409 5410 static void wout_r1_P32(DisasContext *s, DisasOps *o) 5411 { 5412 int r1 = get_field(s, r1); 5413 store_reg32_i64(r1, o->out); 5414 store_reg32_i64(r1 + 1, o->out2); 5415 } 5416 #define SPEC_wout_r1_P32 SPEC_r1_even 5417 5418 static void wout_r1_D32(DisasContext *s, DisasOps *o) 5419 { 5420 int r1 = get_field(s, r1); 5421 store_reg32_i64(r1 + 1, o->out); 5422 tcg_gen_shri_i64(o->out, o->out, 32); 5423 store_reg32_i64(r1, o->out); 5424 } 5425 #define SPEC_wout_r1_D32 SPEC_r1_even 5426 5427 static void wout_r3_P32(DisasContext *s, DisasOps *o) 5428 { 5429 int r3 = get_field(s, r3); 5430 store_reg32_i64(r3, o->out); 5431 store_reg32_i64(r3 + 1, o->out2); 5432 } 5433 #define SPEC_wout_r3_P32 SPEC_r3_even 5434 5435 static void wout_r3_P64(DisasContext *s, DisasOps *o) 5436 { 5437 int r3 = get_field(s, r3); 5438 store_reg(r3, o->out); 5439 store_reg(r3 + 1, o->out2); 5440 } 5441 #define SPEC_wout_r3_P64 SPEC_r3_even 5442 5443 static void wout_e1(DisasContext *s, DisasOps *o) 5444 { 5445 store_freg32_i64(get_field(s, r1), o->out); 5446 } 5447 #define SPEC_wout_e1 0 5448 5449 static void wout_f1(DisasContext *s, DisasOps *o) 5450 { 5451 store_freg(get_field(s, r1), o->out); 5452 } 5453 #define SPEC_wout_f1 0 5454 5455 static void wout_x1(DisasContext *s, DisasOps *o) 5456 { 5457 int f1 = get_field(s, r1); 5458 store_freg(f1, o->out); 5459 store_freg(f1 + 2, o->out2); 5460 } 5461 #define SPEC_wout_x1 SPEC_r1_f128 5462 5463 static void wout_cond_r1r2_32(DisasContext *s, DisasOps *o) 5464 { 5465 if (get_field(s, r1) != get_field(s, r2)) { 5466 store_reg32_i64(get_field(s, r1), o->out); 5467 } 5468 } 5469 #define SPEC_wout_cond_r1r2_32 0 5470 5471 static void wout_cond_e1e2(DisasContext *s, DisasOps *o) 5472 { 5473 if (get_field(s, r1) != get_field(s, r2)) { 5474 store_freg32_i64(get_field(s, r1), o->out); 5475 } 5476 } 5477 #define SPEC_wout_cond_e1e2 0 5478 5479 static void wout_m1_8(DisasContext *s, DisasOps *o) 5480 { 5481 tcg_gen_qemu_st8(o->out, o->addr1, get_mem_index(s)); 5482 } 5483 #define SPEC_wout_m1_8 0 5484 5485 static void wout_m1_16(DisasContext *s, DisasOps *o) 5486 { 5487 tcg_gen_qemu_st16(o->out, o->addr1, get_mem_index(s)); 5488 } 5489 #define SPEC_wout_m1_16 0 5490 5491 #ifndef CONFIG_USER_ONLY 5492 static void wout_m1_16a(DisasContext *s, DisasOps *o) 5493 { 5494 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), MO_TEUW | MO_ALIGN); 5495 } 5496 #define SPEC_wout_m1_16a 0 5497 #endif 5498 5499 static void wout_m1_32(DisasContext *s, DisasOps *o) 5500 { 5501 tcg_gen_qemu_st32(o->out, o->addr1, get_mem_index(s)); 5502 } 5503 #define SPEC_wout_m1_32 0 5504 5505 #ifndef CONFIG_USER_ONLY 5506 static void wout_m1_32a(DisasContext *s, DisasOps *o) 5507 { 5508 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), MO_TEUL | MO_ALIGN); 5509 } 5510 #define SPEC_wout_m1_32a 0 5511 #endif 5512 5513 static void wout_m1_64(DisasContext *s, DisasOps *o) 5514 { 5515 tcg_gen_qemu_st64(o->out, o->addr1, get_mem_index(s)); 5516 } 5517 #define SPEC_wout_m1_64 0 5518 5519 #ifndef CONFIG_USER_ONLY 5520 static void wout_m1_64a(DisasContext *s, DisasOps *o) 5521 { 5522 tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), MO_TEQ | MO_ALIGN); 5523 } 5524 #define SPEC_wout_m1_64a 0 5525 #endif 5526 5527 static void wout_m2_32(DisasContext *s, DisasOps *o) 5528 { 5529 tcg_gen_qemu_st32(o->out, o->in2, get_mem_index(s)); 5530 } 5531 #define SPEC_wout_m2_32 0 5532 5533 static void wout_in2_r1(DisasContext *s, DisasOps *o) 5534 { 5535 store_reg(get_field(s, r1), o->in2); 5536 } 5537 #define SPEC_wout_in2_r1 0 5538 5539 static void wout_in2_r1_32(DisasContext *s, DisasOps *o) 5540 { 5541 store_reg32_i64(get_field(s, r1), o->in2); 5542 } 5543 #define SPEC_wout_in2_r1_32 0 5544 5545 /* ====================================================================== */ 5546 /* The "INput 1" generators. These load the first operand to an insn. */ 5547 5548 static void in1_r1(DisasContext *s, DisasOps *o) 5549 { 5550 o->in1 = load_reg(get_field(s, r1)); 5551 } 5552 #define SPEC_in1_r1 0 5553 5554 static void in1_r1_o(DisasContext *s, DisasOps *o) 5555 { 5556 o->in1 = regs[get_field(s, r1)]; 5557 o->g_in1 = true; 5558 } 5559 #define SPEC_in1_r1_o 0 5560 5561 static void in1_r1_32s(DisasContext *s, DisasOps *o) 5562 { 5563 o->in1 = tcg_temp_new_i64(); 5564 tcg_gen_ext32s_i64(o->in1, regs[get_field(s, r1)]); 5565 } 5566 #define SPEC_in1_r1_32s 0 5567 5568 static void in1_r1_32u(DisasContext *s, DisasOps *o) 5569 { 5570 o->in1 = tcg_temp_new_i64(); 5571 tcg_gen_ext32u_i64(o->in1, regs[get_field(s, r1)]); 5572 } 5573 #define SPEC_in1_r1_32u 0 5574 5575 static void in1_r1_sr32(DisasContext *s, DisasOps *o) 5576 { 5577 o->in1 = tcg_temp_new_i64(); 5578 tcg_gen_shri_i64(o->in1, regs[get_field(s, r1)], 32); 5579 } 5580 #define SPEC_in1_r1_sr32 0 5581 5582 static void in1_r1p1(DisasContext *s, DisasOps *o) 5583 { 5584 o->in1 = load_reg(get_field(s, r1) + 1); 5585 } 5586 #define SPEC_in1_r1p1 SPEC_r1_even 5587 5588 static void in1_r1p1_o(DisasContext *s, DisasOps *o) 5589 { 5590 o->in1 = regs[get_field(s, r1) + 1]; 5591 o->g_in1 = true; 5592 } 5593 #define SPEC_in1_r1p1_o SPEC_r1_even 5594 5595 static void in1_r1p1_32s(DisasContext *s, DisasOps *o) 5596 { 5597 o->in1 = tcg_temp_new_i64(); 5598 tcg_gen_ext32s_i64(o->in1, regs[get_field(s, r1) + 1]); 5599 } 5600 #define SPEC_in1_r1p1_32s SPEC_r1_even 5601 5602 static void in1_r1p1_32u(DisasContext *s, DisasOps *o) 5603 { 5604 o->in1 = tcg_temp_new_i64(); 5605 tcg_gen_ext32u_i64(o->in1, regs[get_field(s, r1) + 1]); 5606 } 5607 #define SPEC_in1_r1p1_32u SPEC_r1_even 5608 5609 static void in1_r1_D32(DisasContext *s, DisasOps *o) 5610 { 5611 int r1 = get_field(s, r1); 5612 o->in1 = tcg_temp_new_i64(); 5613 tcg_gen_concat32_i64(o->in1, regs[r1 + 1], regs[r1]); 5614 } 5615 #define SPEC_in1_r1_D32 SPEC_r1_even 5616 5617 static void in1_r2(DisasContext *s, DisasOps *o) 5618 { 5619 o->in1 = load_reg(get_field(s, r2)); 5620 } 5621 #define SPEC_in1_r2 0 5622 5623 static void in1_r2_sr32(DisasContext *s, DisasOps *o) 5624 { 5625 o->in1 = tcg_temp_new_i64(); 5626 tcg_gen_shri_i64(o->in1, regs[get_field(s, r2)], 32); 5627 } 5628 #define SPEC_in1_r2_sr32 0 5629 5630 static void in1_r2_32u(DisasContext *s, DisasOps *o) 5631 { 5632 o->in1 = tcg_temp_new_i64(); 5633 tcg_gen_ext32u_i64(o->in1, regs[get_field(s, r2)]); 5634 } 5635 #define SPEC_in1_r2_32u 0 5636 5637 static void in1_r3(DisasContext *s, DisasOps *o) 5638 { 5639 o->in1 = load_reg(get_field(s, r3)); 5640 } 5641 #define SPEC_in1_r3 0 5642 5643 static void in1_r3_o(DisasContext *s, DisasOps *o) 5644 { 5645 o->in1 = regs[get_field(s, r3)]; 5646 o->g_in1 = true; 5647 } 5648 #define SPEC_in1_r3_o 0 5649 5650 static void in1_r3_32s(DisasContext *s, DisasOps *o) 5651 { 5652 o->in1 = tcg_temp_new_i64(); 5653 tcg_gen_ext32s_i64(o->in1, regs[get_field(s, r3)]); 5654 } 5655 #define SPEC_in1_r3_32s 0 5656 5657 static void in1_r3_32u(DisasContext *s, DisasOps *o) 5658 { 5659 o->in1 = tcg_temp_new_i64(); 5660 tcg_gen_ext32u_i64(o->in1, regs[get_field(s, r3)]); 5661 } 5662 #define SPEC_in1_r3_32u 0 5663 5664 static void in1_r3_D32(DisasContext *s, DisasOps *o) 5665 { 5666 int r3 = get_field(s, r3); 5667 o->in1 = tcg_temp_new_i64(); 5668 tcg_gen_concat32_i64(o->in1, regs[r3 + 1], regs[r3]); 5669 } 5670 #define SPEC_in1_r3_D32 SPEC_r3_even 5671 5672 static void in1_e1(DisasContext *s, DisasOps *o) 5673 { 5674 o->in1 = load_freg32_i64(get_field(s, r1)); 5675 } 5676 #define SPEC_in1_e1 0 5677 5678 static void in1_f1(DisasContext *s, DisasOps *o) 5679 { 5680 o->in1 = load_freg(get_field(s, r1)); 5681 } 5682 #define SPEC_in1_f1 0 5683 5684 /* Load the high double word of an extended (128-bit) format FP number */ 5685 static void in1_x2h(DisasContext *s, DisasOps *o) 5686 { 5687 o->in1 = load_freg(get_field(s, r2)); 5688 } 5689 #define SPEC_in1_x2h SPEC_r2_f128 5690 5691 static void in1_f3(DisasContext *s, DisasOps *o) 5692 { 5693 o->in1 = load_freg(get_field(s, r3)); 5694 } 5695 #define SPEC_in1_f3 0 5696 5697 static void in1_la1(DisasContext *s, DisasOps *o) 5698 { 5699 o->addr1 = get_address(s, 0, get_field(s, b1), get_field(s, d1)); 5700 } 5701 #define SPEC_in1_la1 0 5702 5703 static void in1_la2(DisasContext *s, DisasOps *o) 5704 { 5705 int x2 = have_field(s, x2) ? get_field(s, x2) : 0; 5706 o->addr1 = get_address(s, x2, get_field(s, b2), get_field(s, d2)); 5707 } 5708 #define SPEC_in1_la2 0 5709 5710 static void in1_m1_8u(DisasContext *s, DisasOps *o) 5711 { 5712 in1_la1(s, o); 5713 o->in1 = tcg_temp_new_i64(); 5714 tcg_gen_qemu_ld8u(o->in1, o->addr1, get_mem_index(s)); 5715 } 5716 #define SPEC_in1_m1_8u 0 5717 5718 static void in1_m1_16s(DisasContext *s, DisasOps *o) 5719 { 5720 in1_la1(s, o); 5721 o->in1 = tcg_temp_new_i64(); 5722 tcg_gen_qemu_ld16s(o->in1, o->addr1, get_mem_index(s)); 5723 } 5724 #define SPEC_in1_m1_16s 0 5725 5726 static void in1_m1_16u(DisasContext *s, DisasOps *o) 5727 { 5728 in1_la1(s, o); 5729 o->in1 = tcg_temp_new_i64(); 5730 tcg_gen_qemu_ld16u(o->in1, o->addr1, get_mem_index(s)); 5731 } 5732 #define SPEC_in1_m1_16u 0 5733 5734 static void in1_m1_32s(DisasContext *s, DisasOps *o) 5735 { 5736 in1_la1(s, o); 5737 o->in1 = tcg_temp_new_i64(); 5738 tcg_gen_qemu_ld32s(o->in1, o->addr1, get_mem_index(s)); 5739 } 5740 #define SPEC_in1_m1_32s 0 5741 5742 static void in1_m1_32u(DisasContext *s, DisasOps *o) 5743 { 5744 in1_la1(s, o); 5745 o->in1 = tcg_temp_new_i64(); 5746 tcg_gen_qemu_ld32u(o->in1, o->addr1, get_mem_index(s)); 5747 } 5748 #define SPEC_in1_m1_32u 0 5749 5750 static void in1_m1_64(DisasContext *s, DisasOps *o) 5751 { 5752 in1_la1(s, o); 5753 o->in1 = tcg_temp_new_i64(); 5754 tcg_gen_qemu_ld64(o->in1, o->addr1, get_mem_index(s)); 5755 } 5756 #define SPEC_in1_m1_64 0 5757 5758 /* ====================================================================== */ 5759 /* The "INput 2" generators. These load the second operand to an insn. */ 5760 5761 static void in2_r1_o(DisasContext *s, DisasOps *o) 5762 { 5763 o->in2 = regs[get_field(s, r1)]; 5764 o->g_in2 = true; 5765 } 5766 #define SPEC_in2_r1_o 0 5767 5768 static void in2_r1_16u(DisasContext *s, DisasOps *o) 5769 { 5770 o->in2 = tcg_temp_new_i64(); 5771 tcg_gen_ext16u_i64(o->in2, regs[get_field(s, r1)]); 5772 } 5773 #define SPEC_in2_r1_16u 0 5774 5775 static void in2_r1_32u(DisasContext *s, DisasOps *o) 5776 { 5777 o->in2 = tcg_temp_new_i64(); 5778 tcg_gen_ext32u_i64(o->in2, regs[get_field(s, r1)]); 5779 } 5780 #define SPEC_in2_r1_32u 0 5781 5782 static void in2_r1_D32(DisasContext *s, DisasOps *o) 5783 { 5784 int r1 = get_field(s, r1); 5785 o->in2 = tcg_temp_new_i64(); 5786 tcg_gen_concat32_i64(o->in2, regs[r1 + 1], regs[r1]); 5787 } 5788 #define SPEC_in2_r1_D32 SPEC_r1_even 5789 5790 static void in2_r2(DisasContext *s, DisasOps *o) 5791 { 5792 o->in2 = load_reg(get_field(s, r2)); 5793 } 5794 #define SPEC_in2_r2 0 5795 5796 static void in2_r2_o(DisasContext *s, DisasOps *o) 5797 { 5798 o->in2 = regs[get_field(s, r2)]; 5799 o->g_in2 = true; 5800 } 5801 #define SPEC_in2_r2_o 0 5802 5803 static void in2_r2_nz(DisasContext *s, DisasOps *o) 5804 { 5805 int r2 = get_field(s, r2); 5806 if (r2 != 0) { 5807 o->in2 = load_reg(r2); 5808 } 5809 } 5810 #define SPEC_in2_r2_nz 0 5811 5812 static void in2_r2_8s(DisasContext *s, DisasOps *o) 5813 { 5814 o->in2 = tcg_temp_new_i64(); 5815 tcg_gen_ext8s_i64(o->in2, regs[get_field(s, r2)]); 5816 } 5817 #define SPEC_in2_r2_8s 0 5818 5819 static void in2_r2_8u(DisasContext *s, DisasOps *o) 5820 { 5821 o->in2 = tcg_temp_new_i64(); 5822 tcg_gen_ext8u_i64(o->in2, regs[get_field(s, r2)]); 5823 } 5824 #define SPEC_in2_r2_8u 0 5825 5826 static void in2_r2_16s(DisasContext *s, DisasOps *o) 5827 { 5828 o->in2 = tcg_temp_new_i64(); 5829 tcg_gen_ext16s_i64(o->in2, regs[get_field(s, r2)]); 5830 } 5831 #define SPEC_in2_r2_16s 0 5832 5833 static void in2_r2_16u(DisasContext *s, DisasOps *o) 5834 { 5835 o->in2 = tcg_temp_new_i64(); 5836 tcg_gen_ext16u_i64(o->in2, regs[get_field(s, r2)]); 5837 } 5838 #define SPEC_in2_r2_16u 0 5839 5840 static void in2_r3(DisasContext *s, DisasOps *o) 5841 { 5842 o->in2 = load_reg(get_field(s, r3)); 5843 } 5844 #define SPEC_in2_r3 0 5845 5846 static void in2_r3_sr32(DisasContext *s, DisasOps *o) 5847 { 5848 o->in2 = tcg_temp_new_i64(); 5849 tcg_gen_shri_i64(o->in2, regs[get_field(s, r3)], 32); 5850 } 5851 #define SPEC_in2_r3_sr32 0 5852 5853 static void in2_r3_32u(DisasContext *s, DisasOps *o) 5854 { 5855 o->in2 = tcg_temp_new_i64(); 5856 tcg_gen_ext32u_i64(o->in2, regs[get_field(s, r3)]); 5857 } 5858 #define SPEC_in2_r3_32u 0 5859 5860 static void in2_r2_32s(DisasContext *s, DisasOps *o) 5861 { 5862 o->in2 = tcg_temp_new_i64(); 5863 tcg_gen_ext32s_i64(o->in2, regs[get_field(s, r2)]); 5864 } 5865 #define SPEC_in2_r2_32s 0 5866 5867 static void in2_r2_32u(DisasContext *s, DisasOps *o) 5868 { 5869 o->in2 = tcg_temp_new_i64(); 5870 tcg_gen_ext32u_i64(o->in2, regs[get_field(s, r2)]); 5871 } 5872 #define SPEC_in2_r2_32u 0 5873 5874 static void in2_r2_sr32(DisasContext *s, DisasOps *o) 5875 { 5876 o->in2 = tcg_temp_new_i64(); 5877 tcg_gen_shri_i64(o->in2, regs[get_field(s, r2)], 32); 5878 } 5879 #define SPEC_in2_r2_sr32 0 5880 5881 static void in2_e2(DisasContext *s, DisasOps *o) 5882 { 5883 o->in2 = load_freg32_i64(get_field(s, r2)); 5884 } 5885 #define SPEC_in2_e2 0 5886 5887 static void in2_f2(DisasContext *s, DisasOps *o) 5888 { 5889 o->in2 = load_freg(get_field(s, r2)); 5890 } 5891 #define SPEC_in2_f2 0 5892 5893 /* Load the low double word of an extended (128-bit) format FP number */ 5894 static void in2_x2l(DisasContext *s, DisasOps *o) 5895 { 5896 o->in2 = load_freg(get_field(s, r2) + 2); 5897 } 5898 #define SPEC_in2_x2l SPEC_r2_f128 5899 5900 static void in2_ra2(DisasContext *s, DisasOps *o) 5901 { 5902 int r2 = get_field(s, r2); 5903 5904 /* Note: *don't* treat !r2 as 0, use the reg value. */ 5905 o->in2 = tcg_temp_new_i64(); 5906 gen_addi_and_wrap_i64(s, o->in2, regs[r2], 0); 5907 } 5908 #define SPEC_in2_ra2 0 5909 5910 static void in2_a2(DisasContext *s, DisasOps *o) 5911 { 5912 int x2 = have_field(s, x2) ? get_field(s, x2) : 0; 5913 o->in2 = get_address(s, x2, get_field(s, b2), get_field(s, d2)); 5914 } 5915 #define SPEC_in2_a2 0 5916 5917 static void in2_ri2(DisasContext *s, DisasOps *o) 5918 { 5919 o->in2 = tcg_const_i64(s->base.pc_next + (int64_t)get_field(s, i2) * 2); 5920 } 5921 #define SPEC_in2_ri2 0 5922 5923 static void in2_sh32(DisasContext *s, DisasOps *o) 5924 { 5925 help_l2_shift(s, o, 31); 5926 } 5927 #define SPEC_in2_sh32 0 5928 5929 static void in2_sh64(DisasContext *s, DisasOps *o) 5930 { 5931 help_l2_shift(s, o, 63); 5932 } 5933 #define SPEC_in2_sh64 0 5934 5935 static void in2_m2_8u(DisasContext *s, DisasOps *o) 5936 { 5937 in2_a2(s, o); 5938 tcg_gen_qemu_ld8u(o->in2, o->in2, get_mem_index(s)); 5939 } 5940 #define SPEC_in2_m2_8u 0 5941 5942 static void in2_m2_16s(DisasContext *s, DisasOps *o) 5943 { 5944 in2_a2(s, o); 5945 tcg_gen_qemu_ld16s(o->in2, o->in2, get_mem_index(s)); 5946 } 5947 #define SPEC_in2_m2_16s 0 5948 5949 static void in2_m2_16u(DisasContext *s, DisasOps *o) 5950 { 5951 in2_a2(s, o); 5952 tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s)); 5953 } 5954 #define SPEC_in2_m2_16u 0 5955 5956 static void in2_m2_32s(DisasContext *s, DisasOps *o) 5957 { 5958 in2_a2(s, o); 5959 tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s)); 5960 } 5961 #define SPEC_in2_m2_32s 0 5962 5963 static void in2_m2_32u(DisasContext *s, DisasOps *o) 5964 { 5965 in2_a2(s, o); 5966 tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s)); 5967 } 5968 #define SPEC_in2_m2_32u 0 5969 5970 #ifndef CONFIG_USER_ONLY 5971 static void in2_m2_32ua(DisasContext *s, DisasOps *o) 5972 { 5973 in2_a2(s, o); 5974 tcg_gen_qemu_ld_tl(o->in2, o->in2, get_mem_index(s), MO_TEUL | MO_ALIGN); 5975 } 5976 #define SPEC_in2_m2_32ua 0 5977 #endif 5978 5979 static void in2_m2_64(DisasContext *s, DisasOps *o) 5980 { 5981 in2_a2(s, o); 5982 tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s)); 5983 } 5984 #define SPEC_in2_m2_64 0 5985 5986 static void in2_m2_64w(DisasContext *s, DisasOps *o) 5987 { 5988 in2_a2(s, o); 5989 tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s)); 5990 gen_addi_and_wrap_i64(s, o->in2, o->in2, 0); 5991 } 5992 #define SPEC_in2_m2_64w 0 5993 5994 #ifndef CONFIG_USER_ONLY 5995 static void in2_m2_64a(DisasContext *s, DisasOps *o) 5996 { 5997 in2_a2(s, o); 5998 tcg_gen_qemu_ld_i64(o->in2, o->in2, get_mem_index(s), MO_TEQ | MO_ALIGN); 5999 } 6000 #define SPEC_in2_m2_64a 0 6001 #endif 6002 6003 static void in2_mri2_16u(DisasContext *s, DisasOps *o) 6004 { 6005 in2_ri2(s, o); 6006 tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s)); 6007 } 6008 #define SPEC_in2_mri2_16u 0 6009 6010 static void in2_mri2_32s(DisasContext *s, DisasOps *o) 6011 { 6012 in2_ri2(s, o); 6013 tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s)); 6014 } 6015 #define SPEC_in2_mri2_32s 0 6016 6017 static void in2_mri2_32u(DisasContext *s, DisasOps *o) 6018 { 6019 in2_ri2(s, o); 6020 tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s)); 6021 } 6022 #define SPEC_in2_mri2_32u 0 6023 6024 static void in2_mri2_64(DisasContext *s, DisasOps *o) 6025 { 6026 in2_ri2(s, o); 6027 tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s)); 6028 } 6029 #define SPEC_in2_mri2_64 0 6030 6031 static void in2_i2(DisasContext *s, DisasOps *o) 6032 { 6033 o->in2 = tcg_const_i64(get_field(s, i2)); 6034 } 6035 #define SPEC_in2_i2 0 6036 6037 static void in2_i2_8u(DisasContext *s, DisasOps *o) 6038 { 6039 o->in2 = tcg_const_i64((uint8_t)get_field(s, i2)); 6040 } 6041 #define SPEC_in2_i2_8u 0 6042 6043 static void in2_i2_16u(DisasContext *s, DisasOps *o) 6044 { 6045 o->in2 = tcg_const_i64((uint16_t)get_field(s, i2)); 6046 } 6047 #define SPEC_in2_i2_16u 0 6048 6049 static void in2_i2_32u(DisasContext *s, DisasOps *o) 6050 { 6051 o->in2 = tcg_const_i64((uint32_t)get_field(s, i2)); 6052 } 6053 #define SPEC_in2_i2_32u 0 6054 6055 static void in2_i2_16u_shl(DisasContext *s, DisasOps *o) 6056 { 6057 uint64_t i2 = (uint16_t)get_field(s, i2); 6058 o->in2 = tcg_const_i64(i2 << s->insn->data); 6059 } 6060 #define SPEC_in2_i2_16u_shl 0 6061 6062 static void in2_i2_32u_shl(DisasContext *s, DisasOps *o) 6063 { 6064 uint64_t i2 = (uint32_t)get_field(s, i2); 6065 o->in2 = tcg_const_i64(i2 << s->insn->data); 6066 } 6067 #define SPEC_in2_i2_32u_shl 0 6068 6069 #ifndef CONFIG_USER_ONLY 6070 static void in2_insn(DisasContext *s, DisasOps *o) 6071 { 6072 o->in2 = tcg_const_i64(s->fields.raw_insn); 6073 } 6074 #define SPEC_in2_insn 0 6075 #endif 6076 6077 /* ====================================================================== */ 6078 6079 /* Find opc within the table of insns. This is formulated as a switch 6080 statement so that (1) we get compile-time notice of cut-paste errors 6081 for duplicated opcodes, and (2) the compiler generates the binary 6082 search tree, rather than us having to post-process the table. */ 6083 6084 #define C(OPC, NM, FT, FC, I1, I2, P, W, OP, CC) \ 6085 E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, 0, 0) 6086 6087 #define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) \ 6088 E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, 0) 6089 6090 #define F(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, FL) \ 6091 E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, 0, FL) 6092 6093 #define E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, FL) insn_ ## NM, 6094 6095 enum DisasInsnEnum { 6096 #include "insn-data.def" 6097 }; 6098 6099 #undef E 6100 #define E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, FL) { \ 6101 .opc = OPC, \ 6102 .flags = FL, \ 6103 .fmt = FMT_##FT, \ 6104 .fac = FAC_##FC, \ 6105 .spec = SPEC_in1_##I1 | SPEC_in2_##I2 | SPEC_prep_##P | SPEC_wout_##W, \ 6106 .name = #NM, \ 6107 .help_in1 = in1_##I1, \ 6108 .help_in2 = in2_##I2, \ 6109 .help_prep = prep_##P, \ 6110 .help_wout = wout_##W, \ 6111 .help_cout = cout_##CC, \ 6112 .help_op = op_##OP, \ 6113 .data = D \ 6114 }, 6115 6116 /* Allow 0 to be used for NULL in the table below. */ 6117 #define in1_0 NULL 6118 #define in2_0 NULL 6119 #define prep_0 NULL 6120 #define wout_0 NULL 6121 #define cout_0 NULL 6122 #define op_0 NULL 6123 6124 #define SPEC_in1_0 0 6125 #define SPEC_in2_0 0 6126 #define SPEC_prep_0 0 6127 #define SPEC_wout_0 0 6128 6129 /* Give smaller names to the various facilities. */ 6130 #define FAC_Z S390_FEAT_ZARCH 6131 #define FAC_CASS S390_FEAT_COMPARE_AND_SWAP_AND_STORE 6132 #define FAC_DFP S390_FEAT_DFP 6133 #define FAC_DFPR S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* DFP-rounding */ 6134 #define FAC_DO S390_FEAT_STFLE_45 /* distinct-operands */ 6135 #define FAC_EE S390_FEAT_EXECUTE_EXT 6136 #define FAC_EI S390_FEAT_EXTENDED_IMMEDIATE 6137 #define FAC_FPE S390_FEAT_FLOATING_POINT_EXT 6138 #define FAC_FPSSH S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* FPS-sign-handling */ 6139 #define FAC_FPRGR S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* FPR-GR-transfer */ 6140 #define FAC_GIE S390_FEAT_GENERAL_INSTRUCTIONS_EXT 6141 #define FAC_HFP_MA S390_FEAT_HFP_MADDSUB 6142 #define FAC_HW S390_FEAT_STFLE_45 /* high-word */ 6143 #define FAC_IEEEE_SIM S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* IEEE-exception-simulation */ 6144 #define FAC_MIE S390_FEAT_STFLE_49 /* misc-instruction-extensions */ 6145 #define FAC_LAT S390_FEAT_STFLE_49 /* load-and-trap */ 6146 #define FAC_LOC S390_FEAT_STFLE_45 /* load/store on condition 1 */ 6147 #define FAC_LOC2 S390_FEAT_STFLE_53 /* load/store on condition 2 */ 6148 #define FAC_LD S390_FEAT_LONG_DISPLACEMENT 6149 #define FAC_PC S390_FEAT_STFLE_45 /* population count */ 6150 #define FAC_SCF S390_FEAT_STORE_CLOCK_FAST 6151 #define FAC_SFLE S390_FEAT_STFLE 6152 #define FAC_ILA S390_FEAT_STFLE_45 /* interlocked-access-facility 1 */ 6153 #define FAC_MVCOS S390_FEAT_MOVE_WITH_OPTIONAL_SPEC 6154 #define FAC_LPP S390_FEAT_SET_PROGRAM_PARAMETERS /* load-program-parameter */ 6155 #define FAC_DAT_ENH S390_FEAT_DAT_ENH 6156 #define FAC_E2 S390_FEAT_EXTENDED_TRANSLATION_2 6157 #define FAC_EH S390_FEAT_STFLE_49 /* execution-hint */ 6158 #define FAC_PPA S390_FEAT_STFLE_49 /* processor-assist */ 6159 #define FAC_LZRB S390_FEAT_STFLE_53 /* load-and-zero-rightmost-byte */ 6160 #define FAC_ETF3 S390_FEAT_EXTENDED_TRANSLATION_3 6161 #define FAC_MSA S390_FEAT_MSA /* message-security-assist facility */ 6162 #define FAC_MSA3 S390_FEAT_MSA_EXT_3 /* msa-extension-3 facility */ 6163 #define FAC_MSA4 S390_FEAT_MSA_EXT_4 /* msa-extension-4 facility */ 6164 #define FAC_MSA5 S390_FEAT_MSA_EXT_5 /* msa-extension-5 facility */ 6165 #define FAC_MSA8 S390_FEAT_MSA_EXT_8 /* msa-extension-8 facility */ 6166 #define FAC_ECT S390_FEAT_EXTRACT_CPU_TIME 6167 #define FAC_PCI S390_FEAT_ZPCI /* z/PCI facility */ 6168 #define FAC_AIS S390_FEAT_ADAPTER_INT_SUPPRESSION 6169 #define FAC_V S390_FEAT_VECTOR /* vector facility */ 6170 #define FAC_VE S390_FEAT_VECTOR_ENH /* vector enhancements facility 1 */ 6171 #define FAC_MIE2 S390_FEAT_MISC_INSTRUCTION_EXT2 /* miscellaneous-instruction-extensions facility 2 */ 6172 6173 static const DisasInsn insn_info[] = { 6174 #include "insn-data.def" 6175 }; 6176 6177 #undef E 6178 #define E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, FL) \ 6179 case OPC: return &insn_info[insn_ ## NM]; 6180 6181 static const DisasInsn *lookup_opc(uint16_t opc) 6182 { 6183 switch (opc) { 6184 #include "insn-data.def" 6185 default: 6186 return NULL; 6187 } 6188 } 6189 6190 #undef F 6191 #undef E 6192 #undef D 6193 #undef C 6194 6195 /* Extract a field from the insn. The INSN should be left-aligned in 6196 the uint64_t so that we can more easily utilize the big-bit-endian 6197 definitions we extract from the Principals of Operation. */ 6198 6199 static void extract_field(DisasFields *o, const DisasField *f, uint64_t insn) 6200 { 6201 uint32_t r, m; 6202 6203 if (f->size == 0) { 6204 return; 6205 } 6206 6207 /* Zero extract the field from the insn. */ 6208 r = (insn << f->beg) >> (64 - f->size); 6209 6210 /* Sign-extend, or un-swap the field as necessary. */ 6211 switch (f->type) { 6212 case 0: /* unsigned */ 6213 break; 6214 case 1: /* signed */ 6215 assert(f->size <= 32); 6216 m = 1u << (f->size - 1); 6217 r = (r ^ m) - m; 6218 break; 6219 case 2: /* dl+dh split, signed 20 bit. */ 6220 r = ((int8_t)r << 12) | (r >> 8); 6221 break; 6222 case 3: /* MSB stored in RXB */ 6223 g_assert(f->size == 4); 6224 switch (f->beg) { 6225 case 8: 6226 r |= extract64(insn, 63 - 36, 1) << 4; 6227 break; 6228 case 12: 6229 r |= extract64(insn, 63 - 37, 1) << 4; 6230 break; 6231 case 16: 6232 r |= extract64(insn, 63 - 38, 1) << 4; 6233 break; 6234 case 32: 6235 r |= extract64(insn, 63 - 39, 1) << 4; 6236 break; 6237 default: 6238 g_assert_not_reached(); 6239 } 6240 break; 6241 default: 6242 abort(); 6243 } 6244 6245 /* 6246 * Validate that the "compressed" encoding we selected above is valid. 6247 * I.e. we haven't made two different original fields overlap. 6248 */ 6249 assert(((o->presentC >> f->indexC) & 1) == 0); 6250 o->presentC |= 1 << f->indexC; 6251 o->presentO |= 1 << f->indexO; 6252 6253 o->c[f->indexC] = r; 6254 } 6255 6256 /* Lookup the insn at the current PC, extracting the operands into O and 6257 returning the info struct for the insn. Returns NULL for invalid insn. */ 6258 6259 static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s) 6260 { 6261 uint64_t insn, pc = s->base.pc_next; 6262 int op, op2, ilen; 6263 const DisasInsn *info; 6264 6265 if (unlikely(s->ex_value)) { 6266 /* Drop the EX data now, so that it's clear on exception paths. */ 6267 TCGv_i64 zero = tcg_const_i64(0); 6268 tcg_gen_st_i64(zero, cpu_env, offsetof(CPUS390XState, ex_value)); 6269 tcg_temp_free_i64(zero); 6270 6271 /* Extract the values saved by EXECUTE. */ 6272 insn = s->ex_value & 0xffffffffffff0000ull; 6273 ilen = s->ex_value & 0xf; 6274 op = insn >> 56; 6275 } else { 6276 insn = ld_code2(env, pc); 6277 op = (insn >> 8) & 0xff; 6278 ilen = get_ilen(op); 6279 switch (ilen) { 6280 case 2: 6281 insn = insn << 48; 6282 break; 6283 case 4: 6284 insn = ld_code4(env, pc) << 32; 6285 break; 6286 case 6: 6287 insn = (insn << 48) | (ld_code4(env, pc + 2) << 16); 6288 break; 6289 default: 6290 g_assert_not_reached(); 6291 } 6292 } 6293 s->pc_tmp = s->base.pc_next + ilen; 6294 s->ilen = ilen; 6295 6296 /* We can't actually determine the insn format until we've looked up 6297 the full insn opcode. Which we can't do without locating the 6298 secondary opcode. Assume by default that OP2 is at bit 40; for 6299 those smaller insns that don't actually have a secondary opcode 6300 this will correctly result in OP2 = 0. */ 6301 switch (op) { 6302 case 0x01: /* E */ 6303 case 0x80: /* S */ 6304 case 0x82: /* S */ 6305 case 0x93: /* S */ 6306 case 0xb2: /* S, RRF, RRE, IE */ 6307 case 0xb3: /* RRE, RRD, RRF */ 6308 case 0xb9: /* RRE, RRF */ 6309 case 0xe5: /* SSE, SIL */ 6310 op2 = (insn << 8) >> 56; 6311 break; 6312 case 0xa5: /* RI */ 6313 case 0xa7: /* RI */ 6314 case 0xc0: /* RIL */ 6315 case 0xc2: /* RIL */ 6316 case 0xc4: /* RIL */ 6317 case 0xc6: /* RIL */ 6318 case 0xc8: /* SSF */ 6319 case 0xcc: /* RIL */ 6320 op2 = (insn << 12) >> 60; 6321 break; 6322 case 0xc5: /* MII */ 6323 case 0xc7: /* SMI */ 6324 case 0xd0 ... 0xdf: /* SS */ 6325 case 0xe1: /* SS */ 6326 case 0xe2: /* SS */ 6327 case 0xe8: /* SS */ 6328 case 0xe9: /* SS */ 6329 case 0xea: /* SS */ 6330 case 0xee ... 0xf3: /* SS */ 6331 case 0xf8 ... 0xfd: /* SS */ 6332 op2 = 0; 6333 break; 6334 default: 6335 op2 = (insn << 40) >> 56; 6336 break; 6337 } 6338 6339 memset(&s->fields, 0, sizeof(s->fields)); 6340 s->fields.raw_insn = insn; 6341 s->fields.op = op; 6342 s->fields.op2 = op2; 6343 6344 /* Lookup the instruction. */ 6345 info = lookup_opc(op << 8 | op2); 6346 s->insn = info; 6347 6348 /* If we found it, extract the operands. */ 6349 if (info != NULL) { 6350 DisasFormat fmt = info->fmt; 6351 int i; 6352 6353 for (i = 0; i < NUM_C_FIELD; ++i) { 6354 extract_field(&s->fields, &format_info[fmt].op[i], insn); 6355 } 6356 } 6357 return info; 6358 } 6359 6360 static bool is_afp_reg(int reg) 6361 { 6362 return reg % 2 || reg > 6; 6363 } 6364 6365 static bool is_fp_pair(int reg) 6366 { 6367 /* 0,1,4,5,8,9,12,13: to exclude the others, check for single bit */ 6368 return !(reg & 0x2); 6369 } 6370 6371 static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s) 6372 { 6373 const DisasInsn *insn; 6374 DisasJumpType ret = DISAS_NEXT; 6375 DisasOps o = {}; 6376 bool icount = false; 6377 6378 /* Search for the insn in the table. */ 6379 insn = extract_insn(env, s); 6380 6381 /* Emit insn_start now that we know the ILEN. */ 6382 tcg_gen_insn_start(s->base.pc_next, s->cc_op, s->ilen); 6383 6384 /* Not found means unimplemented/illegal opcode. */ 6385 if (insn == NULL) { 6386 qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n", 6387 s->fields.op, s->fields.op2); 6388 gen_illegal_opcode(s); 6389 ret = DISAS_NORETURN; 6390 goto out; 6391 } 6392 6393 #ifndef CONFIG_USER_ONLY 6394 if (s->base.tb->flags & FLAG_MASK_PER) { 6395 TCGv_i64 addr = tcg_const_i64(s->base.pc_next); 6396 gen_helper_per_ifetch(cpu_env, addr); 6397 tcg_temp_free_i64(addr); 6398 } 6399 #endif 6400 6401 /* process flags */ 6402 if (insn->flags) { 6403 /* privileged instruction */ 6404 if ((s->base.tb->flags & FLAG_MASK_PSTATE) && (insn->flags & IF_PRIV)) { 6405 gen_program_exception(s, PGM_PRIVILEGED); 6406 ret = DISAS_NORETURN; 6407 goto out; 6408 } 6409 6410 /* if AFP is not enabled, instructions and registers are forbidden */ 6411 if (!(s->base.tb->flags & FLAG_MASK_AFP)) { 6412 uint8_t dxc = 0; 6413 6414 if ((insn->flags & IF_AFP1) && is_afp_reg(get_field(s, r1))) { 6415 dxc = 1; 6416 } 6417 if ((insn->flags & IF_AFP2) && is_afp_reg(get_field(s, r2))) { 6418 dxc = 1; 6419 } 6420 if ((insn->flags & IF_AFP3) && is_afp_reg(get_field(s, r3))) { 6421 dxc = 1; 6422 } 6423 if (insn->flags & IF_BFP) { 6424 dxc = 2; 6425 } 6426 if (insn->flags & IF_DFP) { 6427 dxc = 3; 6428 } 6429 if (insn->flags & IF_VEC) { 6430 dxc = 0xfe; 6431 } 6432 if (dxc) { 6433 gen_data_exception(dxc); 6434 ret = DISAS_NORETURN; 6435 goto out; 6436 } 6437 } 6438 6439 /* if vector instructions not enabled, executing them is forbidden */ 6440 if (insn->flags & IF_VEC) { 6441 if (!((s->base.tb->flags & FLAG_MASK_VECTOR))) { 6442 gen_data_exception(0xfe); 6443 ret = DISAS_NORETURN; 6444 goto out; 6445 } 6446 } 6447 6448 /* input/output is the special case for icount mode */ 6449 if (unlikely(insn->flags & IF_IO)) { 6450 icount = tb_cflags(s->base.tb) & CF_USE_ICOUNT; 6451 if (icount) { 6452 gen_io_start(); 6453 } 6454 } 6455 } 6456 6457 /* Check for insn specification exceptions. */ 6458 if (insn->spec) { 6459 if ((insn->spec & SPEC_r1_even && get_field(s, r1) & 1) || 6460 (insn->spec & SPEC_r2_even && get_field(s, r2) & 1) || 6461 (insn->spec & SPEC_r3_even && get_field(s, r3) & 1) || 6462 (insn->spec & SPEC_r1_f128 && !is_fp_pair(get_field(s, r1))) || 6463 (insn->spec & SPEC_r2_f128 && !is_fp_pair(get_field(s, r2)))) { 6464 gen_program_exception(s, PGM_SPECIFICATION); 6465 ret = DISAS_NORETURN; 6466 goto out; 6467 } 6468 } 6469 6470 /* Implement the instruction. */ 6471 if (insn->help_in1) { 6472 insn->help_in1(s, &o); 6473 } 6474 if (insn->help_in2) { 6475 insn->help_in2(s, &o); 6476 } 6477 if (insn->help_prep) { 6478 insn->help_prep(s, &o); 6479 } 6480 if (insn->help_op) { 6481 ret = insn->help_op(s, &o); 6482 } 6483 if (ret != DISAS_NORETURN) { 6484 if (insn->help_wout) { 6485 insn->help_wout(s, &o); 6486 } 6487 if (insn->help_cout) { 6488 insn->help_cout(s, &o); 6489 } 6490 } 6491 6492 /* Free any temporaries created by the helpers. */ 6493 if (o.out && !o.g_out) { 6494 tcg_temp_free_i64(o.out); 6495 } 6496 if (o.out2 && !o.g_out2) { 6497 tcg_temp_free_i64(o.out2); 6498 } 6499 if (o.in1 && !o.g_in1) { 6500 tcg_temp_free_i64(o.in1); 6501 } 6502 if (o.in2 && !o.g_in2) { 6503 tcg_temp_free_i64(o.in2); 6504 } 6505 if (o.addr1) { 6506 tcg_temp_free_i64(o.addr1); 6507 } 6508 6509 /* io should be the last instruction in tb when icount is enabled */ 6510 if (unlikely(icount && ret == DISAS_NEXT)) { 6511 ret = DISAS_PC_STALE; 6512 } 6513 6514 #ifndef CONFIG_USER_ONLY 6515 if (s->base.tb->flags & FLAG_MASK_PER) { 6516 /* An exception might be triggered, save PSW if not already done. */ 6517 if (ret == DISAS_NEXT || ret == DISAS_PC_STALE) { 6518 tcg_gen_movi_i64(psw_addr, s->pc_tmp); 6519 } 6520 6521 /* Call the helper to check for a possible PER exception. */ 6522 gen_helper_per_check_exception(cpu_env); 6523 } 6524 #endif 6525 6526 out: 6527 /* Advance to the next instruction. */ 6528 s->base.pc_next = s->pc_tmp; 6529 return ret; 6530 } 6531 6532 static void s390x_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 6533 { 6534 DisasContext *dc = container_of(dcbase, DisasContext, base); 6535 6536 /* 31-bit mode */ 6537 if (!(dc->base.tb->flags & FLAG_MASK_64)) { 6538 dc->base.pc_first &= 0x7fffffff; 6539 dc->base.pc_next = dc->base.pc_first; 6540 } 6541 6542 dc->cc_op = CC_OP_DYNAMIC; 6543 dc->ex_value = dc->base.tb->cs_base; 6544 dc->do_debug = dc->base.singlestep_enabled; 6545 } 6546 6547 static void s390x_tr_tb_start(DisasContextBase *db, CPUState *cs) 6548 { 6549 } 6550 6551 static void s390x_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 6552 { 6553 } 6554 6555 static bool s390x_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, 6556 const CPUBreakpoint *bp) 6557 { 6558 DisasContext *dc = container_of(dcbase, DisasContext, base); 6559 6560 /* 6561 * Emit an insn_start to accompany the breakpoint exception. 6562 * The ILEN value is a dummy, since this does not result in 6563 * an s390x exception, but an internal qemu exception which 6564 * brings us back to interact with the gdbstub. 6565 */ 6566 tcg_gen_insn_start(dc->base.pc_next, dc->cc_op, 2); 6567 6568 dc->base.is_jmp = DISAS_PC_STALE; 6569 dc->do_debug = true; 6570 /* The address covered by the breakpoint must be included in 6571 [tb->pc, tb->pc + tb->size) in order to for it to be 6572 properly cleared -- thus we increment the PC here so that 6573 the logic setting tb->size does the right thing. */ 6574 dc->base.pc_next += 2; 6575 return true; 6576 } 6577 6578 static void s390x_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 6579 { 6580 CPUS390XState *env = cs->env_ptr; 6581 DisasContext *dc = container_of(dcbase, DisasContext, base); 6582 6583 dc->base.is_jmp = translate_one(env, dc); 6584 if (dc->base.is_jmp == DISAS_NEXT) { 6585 uint64_t page_start; 6586 6587 page_start = dc->base.pc_first & TARGET_PAGE_MASK; 6588 if (dc->base.pc_next - page_start >= TARGET_PAGE_SIZE || dc->ex_value) { 6589 dc->base.is_jmp = DISAS_TOO_MANY; 6590 } 6591 } 6592 } 6593 6594 static void s390x_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 6595 { 6596 DisasContext *dc = container_of(dcbase, DisasContext, base); 6597 6598 switch (dc->base.is_jmp) { 6599 case DISAS_GOTO_TB: 6600 case DISAS_NORETURN: 6601 break; 6602 case DISAS_TOO_MANY: 6603 case DISAS_PC_STALE: 6604 case DISAS_PC_STALE_NOCHAIN: 6605 update_psw_addr(dc); 6606 /* FALLTHRU */ 6607 case DISAS_PC_UPDATED: 6608 /* Next TB starts off with CC_OP_DYNAMIC, so make sure the 6609 cc op type is in env */ 6610 update_cc_op(dc); 6611 /* FALLTHRU */ 6612 case DISAS_PC_CC_UPDATED: 6613 /* Exit the TB, either by raising a debug exception or by return. */ 6614 if (dc->do_debug) { 6615 gen_exception(EXCP_DEBUG); 6616 } else if ((dc->base.tb->flags & FLAG_MASK_PER) || 6617 dc->base.is_jmp == DISAS_PC_STALE_NOCHAIN) { 6618 tcg_gen_exit_tb(NULL, 0); 6619 } else { 6620 tcg_gen_lookup_and_goto_ptr(); 6621 } 6622 break; 6623 default: 6624 g_assert_not_reached(); 6625 } 6626 } 6627 6628 static void s390x_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs) 6629 { 6630 DisasContext *dc = container_of(dcbase, DisasContext, base); 6631 6632 if (unlikely(dc->ex_value)) { 6633 /* ??? Unfortunately log_target_disas can't use host memory. */ 6634 qemu_log("IN: EXECUTE %016" PRIx64, dc->ex_value); 6635 } else { 6636 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first)); 6637 log_target_disas(cs, dc->base.pc_first, dc->base.tb->size); 6638 } 6639 } 6640 6641 static const TranslatorOps s390x_tr_ops = { 6642 .init_disas_context = s390x_tr_init_disas_context, 6643 .tb_start = s390x_tr_tb_start, 6644 .insn_start = s390x_tr_insn_start, 6645 .breakpoint_check = s390x_tr_breakpoint_check, 6646 .translate_insn = s390x_tr_translate_insn, 6647 .tb_stop = s390x_tr_tb_stop, 6648 .disas_log = s390x_tr_disas_log, 6649 }; 6650 6651 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) 6652 { 6653 DisasContext dc; 6654 6655 translator_loop(&s390x_tr_ops, &dc.base, cs, tb, max_insns); 6656 } 6657 6658 void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb, 6659 target_ulong *data) 6660 { 6661 int cc_op = data[1]; 6662 6663 env->psw.addr = data[0]; 6664 6665 /* Update the CC opcode if it is not already up-to-date. */ 6666 if ((cc_op != CC_OP_DYNAMIC) && (cc_op != CC_OP_STATIC)) { 6667 env->cc_op = cc_op; 6668 } 6669 6670 /* Record ILEN. */ 6671 env->int_pgm_ilen = data[2]; 6672 } 6673