2 * Tiny Code Generator for QEMU
4 * Copyright (c) 2009 Ulrich Hecht <uli@suse.de>
5 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
6 * Copyright (c) 2010 Richard Henderson <rth@twiddle.net>
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 /* We only support generating code for 64-bit mode. */
28 #if TCG_TARGET_REG_BITS != 64
29 #error "unsupported code generation mode"
32 #include "../tcg-pool.c.inc"
35 /* ??? The translation blocks produced by TCG are generally small enough to
36 be entirely reachable with a 16-bit displacement. Leaving the option for
37 a 32-bit displacement here Just In Case. */
38 #define USE_LONG_BRANCHES 0
40 #define TCG_CT_CONST_S16 0x100
41 #define TCG_CT_CONST_S32 0x200
42 #define TCG_CT_CONST_S33 0x400
43 #define TCG_CT_CONST_ZERO 0x800
45 #define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 16)
47 * For softmmu, we need to avoid conflicts with the first 3
48 * argument registers to perform the tlb lookup, and to call
49 * the helper function.
52 #define SOFTMMU_RESERVE_REGS MAKE_64BIT_MASK(TCG_REG_R2, 3)
54 #define SOFTMMU_RESERVE_REGS 0
58 /* Several places within the instruction set 0 means "no register"
59 rather than TCG_REG_R0. */
60 #define TCG_REG_NONE 0
62 /* A scratch register that may be be used throughout the backend. */
63 #define TCG_TMP0 TCG_REG_R1
65 /* A scratch register that holds a pointer to the beginning of the TB.
66 We don't need this when we have pc-relative loads with the general
67 instructions extension facility. */
68 #define TCG_REG_TB TCG_REG_R12
69 #define USE_REG_TB (!(s390_facilities & FACILITY_GEN_INST_EXT))
71 #ifndef CONFIG_SOFTMMU
72 #define TCG_GUEST_BASE_REG TCG_REG_R13
75 /* All of the following instructions are prefixed with their instruction
76 format, and are defined as 8- or 16-bit quantities, even when the two
77 halves of the 16-bit quantity may appear 32 bits apart in the insn.
78 This makes it easy to copy the values from the tables in Appendix B. */
79 typedef enum S390Opcode {
269 #ifdef CONFIG_DEBUG_TCG
270 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
271 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
272 "%r8", "%r9", "%r10" "%r11" "%r12" "%r13" "%r14" "%r15"
276 /* Since R6 is a potential argument register, choose it last of the
277 call-saved registers. Likewise prefer the call-clobbered registers
278 in reverse order to maximize the chance of avoiding the arguments. */
279 static const int tcg_target_reg_alloc_order[] = {
280 /* Call saved registers. */
289 /* Call clobbered registers. */
293 /* Argument registers, in reverse order of allocation. */
300 static const int tcg_target_call_iarg_regs[] = {
308 static const int tcg_target_call_oarg_regs[] = {
316 #define S390_CC_NE (S390_CC_LT | S390_CC_GT)
317 #define S390_CC_LE (S390_CC_LT | S390_CC_EQ)
318 #define S390_CC_GE (S390_CC_GT | S390_CC_EQ)
319 #define S390_CC_NEVER 0
320 #define S390_CC_ALWAYS 15
322 /* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
323 static const uint8_t tcg_cond_to_s390_cond[] = {
324 [TCG_COND_EQ] = S390_CC_EQ,
325 [TCG_COND_NE] = S390_CC_NE,
326 [TCG_COND_LT] = S390_CC_LT,
327 [TCG_COND_LE] = S390_CC_LE,
328 [TCG_COND_GT] = S390_CC_GT,
329 [TCG_COND_GE] = S390_CC_GE,
330 [TCG_COND_LTU] = S390_CC_LT,
331 [TCG_COND_LEU] = S390_CC_LE,
332 [TCG_COND_GTU] = S390_CC_GT,
333 [TCG_COND_GEU] = S390_CC_GE,
336 /* Condition codes that result from a LOAD AND TEST. Here, we have no
337 unsigned instruction variation, however since the test is vs zero we
338 can re-map the outcomes appropriately. */
339 static const uint8_t tcg_cond_to_ltr_cond[] = {
340 [TCG_COND_EQ] = S390_CC_EQ,
341 [TCG_COND_NE] = S390_CC_NE,
342 [TCG_COND_LT] = S390_CC_LT,
343 [TCG_COND_LE] = S390_CC_LE,
344 [TCG_COND_GT] = S390_CC_GT,
345 [TCG_COND_GE] = S390_CC_GE,
346 [TCG_COND_LTU] = S390_CC_NEVER,
347 [TCG_COND_LEU] = S390_CC_EQ,
348 [TCG_COND_GTU] = S390_CC_NE,
349 [TCG_COND_GEU] = S390_CC_ALWAYS,
352 #ifdef CONFIG_SOFTMMU
353 static void * const qemu_ld_helpers[16] = {
354 [MO_UB] = helper_ret_ldub_mmu,
355 [MO_SB] = helper_ret_ldsb_mmu,
356 [MO_LEUW] = helper_le_lduw_mmu,
357 [MO_LESW] = helper_le_ldsw_mmu,
358 [MO_LEUL] = helper_le_ldul_mmu,
359 [MO_LESL] = helper_le_ldsl_mmu,
360 [MO_LEQ] = helper_le_ldq_mmu,
361 [MO_BEUW] = helper_be_lduw_mmu,
362 [MO_BESW] = helper_be_ldsw_mmu,
363 [MO_BEUL] = helper_be_ldul_mmu,
364 [MO_BESL] = helper_be_ldsl_mmu,
365 [MO_BEQ] = helper_be_ldq_mmu,
368 static void * const qemu_st_helpers[16] = {
369 [MO_UB] = helper_ret_stb_mmu,
370 [MO_LEUW] = helper_le_stw_mmu,
371 [MO_LEUL] = helper_le_stl_mmu,
372 [MO_LEQ] = helper_le_stq_mmu,
373 [MO_BEUW] = helper_be_stw_mmu,
374 [MO_BEUL] = helper_be_stl_mmu,
375 [MO_BEQ] = helper_be_stq_mmu,
379 static const tcg_insn_unit *tb_ret_addr;
380 uint64_t s390_facilities;
382 static bool patch_reloc(tcg_insn_unit *src_rw, int type,
383 intptr_t value, intptr_t addend)
385 const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
390 pcrel2 = (tcg_insn_unit *)value - src_rx;
394 if (pcrel2 == (int16_t)pcrel2) {
395 tcg_patch16(src_rw, pcrel2);
400 if (pcrel2 == (int32_t)pcrel2) {
401 tcg_patch32(src_rw, pcrel2);
406 if (value == sextract64(value, 0, 20)) {
407 old = *(uint32_t *)src_rw & 0xf00000ff;
408 old |= ((value & 0xfff) << 16) | ((value & 0xff000) >> 4);
409 tcg_patch32(src_rw, old);
414 g_assert_not_reached();
419 /* Test if a constant matches the constraint. */
420 static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
422 if (ct & TCG_CT_CONST) {
426 if (type == TCG_TYPE_I32) {
430 /* The following are mutually exclusive. */
431 if (ct & TCG_CT_CONST_S16) {
432 return val == (int16_t)val;
433 } else if (ct & TCG_CT_CONST_S32) {
434 return val == (int32_t)val;
435 } else if (ct & TCG_CT_CONST_S33) {
436 return val >= -0xffffffffll && val <= 0xffffffffll;
437 } else if (ct & TCG_CT_CONST_ZERO) {
444 /* Emit instructions according to the given instruction format. */
446 static void tcg_out_insn_RR(TCGContext *s, S390Opcode op, TCGReg r1, TCGReg r2)
448 tcg_out16(s, (op << 8) | (r1 << 4) | r2);
451 static void tcg_out_insn_RRE(TCGContext *s, S390Opcode op,
452 TCGReg r1, TCGReg r2)
454 tcg_out32(s, (op << 16) | (r1 << 4) | r2);
457 static void tcg_out_insn_RRF(TCGContext *s, S390Opcode op,
458 TCGReg r1, TCGReg r2, int m3)
460 tcg_out32(s, (op << 16) | (m3 << 12) | (r1 << 4) | r2);
463 static void tcg_out_insn_RI(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
465 tcg_out32(s, (op << 16) | (r1 << 20) | (i2 & 0xffff));
468 static void tcg_out_insn_RIE(TCGContext *s, S390Opcode op, TCGReg r1,
471 tcg_out16(s, (op & 0xff00) | (r1 << 4) | m3);
472 tcg_out32(s, (i2 << 16) | (op & 0xff));
475 static void tcg_out_insn_RIL(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
477 tcg_out16(s, op | (r1 << 4));
481 static void tcg_out_insn_RS(TCGContext *s, S390Opcode op, TCGReg r1,
482 TCGReg b2, TCGReg r3, int disp)
484 tcg_out32(s, (op << 24) | (r1 << 20) | (r3 << 16) | (b2 << 12)
488 static void tcg_out_insn_RSY(TCGContext *s, S390Opcode op, TCGReg r1,
489 TCGReg b2, TCGReg r3, int disp)
491 tcg_out16(s, (op & 0xff00) | (r1 << 4) | r3);
492 tcg_out32(s, (op & 0xff) | (b2 << 28)
493 | ((disp & 0xfff) << 16) | ((disp & 0xff000) >> 4));
496 #define tcg_out_insn_RX tcg_out_insn_RS
497 #define tcg_out_insn_RXY tcg_out_insn_RSY
499 /* Emit an opcode with "type-checking" of the format. */
500 #define tcg_out_insn(S, FMT, OP, ...) \
501 glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
504 /* emit 64-bit shifts */
505 static void tcg_out_sh64(TCGContext* s, S390Opcode op, TCGReg dest,
506 TCGReg src, TCGReg sh_reg, int sh_imm)
508 tcg_out_insn_RSY(s, op, dest, sh_reg, src, sh_imm);
511 /* emit 32-bit shifts */
512 static void tcg_out_sh32(TCGContext* s, S390Opcode op, TCGReg dest,
513 TCGReg sh_reg, int sh_imm)
515 tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
518 static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
521 if (type == TCG_TYPE_I32) {
522 tcg_out_insn(s, RR, LR, dst, src);
524 tcg_out_insn(s, RRE, LGR, dst, src);
530 static const S390Opcode lli_insns[4] = {
531 RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
534 static bool maybe_out_small_movi(TCGContext *s, TCGType type,
535 TCGReg ret, tcg_target_long sval)
537 tcg_target_ulong uval = sval;
540 if (type == TCG_TYPE_I32) {
541 uval = (uint32_t)sval;
542 sval = (int32_t)sval;
545 /* Try all 32-bit insns that can load it in one go. */
546 if (sval >= -0x8000 && sval < 0x8000) {
547 tcg_out_insn(s, RI, LGHI, ret, sval);
551 for (i = 0; i < 4; i++) {
552 tcg_target_long mask = 0xffffull << i*16;
553 if ((uval & mask) == uval) {
554 tcg_out_insn_RI(s, lli_insns[i], ret, uval >> i*16);
562 /* load a register with an immediate value */
563 static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
564 tcg_target_long sval, bool in_prologue)
566 tcg_target_ulong uval;
568 /* Try all 32-bit insns that can load it in one go. */
569 if (maybe_out_small_movi(s, type, ret, sval)) {
574 if (type == TCG_TYPE_I32) {
575 uval = (uint32_t)sval;
576 sval = (int32_t)sval;
579 /* Try all 48-bit insns that can load it in one go. */
580 if (s390_facilities & FACILITY_EXT_IMM) {
581 if (sval == (int32_t)sval) {
582 tcg_out_insn(s, RIL, LGFI, ret, sval);
585 if (uval <= 0xffffffff) {
586 tcg_out_insn(s, RIL, LLILF, ret, uval);
589 if ((uval & 0xffffffff) == 0) {
590 tcg_out_insn(s, RIL, LLIHF, ret, uval >> 32);
595 /* Try for PC-relative address load. For odd addresses,
596 attempt to use an offset from the start of the TB. */
597 if ((sval & 1) == 0) {
598 ptrdiff_t off = tcg_pcrel_diff(s, (void *)sval) >> 1;
599 if (off == (int32_t)off) {
600 tcg_out_insn(s, RIL, LARL, ret, off);
603 } else if (USE_REG_TB && !in_prologue) {
604 ptrdiff_t off = tcg_tbrel_diff(s, (void *)sval);
605 if (off == sextract64(off, 0, 20)) {
606 /* This is certain to be an address within TB, and therefore
607 OFF will be negative; don't try RX_LA. */
608 tcg_out_insn(s, RXY, LAY, ret, TCG_REG_TB, TCG_REG_NONE, off);
613 /* A 32-bit unsigned value can be loaded in 2 insns. And given
614 that LLILL, LLIHL, LLILF above did not succeed, we know that
615 both insns are required. */
616 if (uval <= 0xffffffff) {
617 tcg_out_insn(s, RI, LLILL, ret, uval);
618 tcg_out_insn(s, RI, IILH, ret, uval >> 16);
622 /* Otherwise, stuff it in the constant pool. */
623 if (s390_facilities & FACILITY_GEN_INST_EXT) {
624 tcg_out_insn(s, RIL, LGRL, ret, 0);
625 new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
626 } else if (USE_REG_TB && !in_prologue) {
627 tcg_out_insn(s, RXY, LG, ret, TCG_REG_TB, TCG_REG_NONE, 0);
628 new_pool_label(s, sval, R_390_20, s->code_ptr - 2,
629 tcg_tbrel_diff(s, NULL));
631 TCGReg base = ret ? ret : TCG_TMP0;
632 tcg_out_insn(s, RIL, LARL, base, 0);
633 new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
634 tcg_out_insn(s, RXY, LG, ret, base, TCG_REG_NONE, 0);
638 static void tcg_out_movi(TCGContext *s, TCGType type,
639 TCGReg ret, tcg_target_long sval)
641 tcg_out_movi_int(s, type, ret, sval, false);
644 /* Emit a load/store type instruction. Inputs are:
645 DATA: The register to be loaded or stored.
646 BASE+OFS: The effective address.
647 OPC_RX: If the operation has an RX format opcode (e.g. STC), otherwise 0.
648 OPC_RXY: The RXY format opcode for the operation (e.g. STCY). */
650 static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
651 TCGReg data, TCGReg base, TCGReg index,
654 if (ofs < -0x80000 || ofs >= 0x80000) {
655 /* Combine the low 20 bits of the offset with the actual load insn;
656 the high 44 bits must come from an immediate load. */
657 tcg_target_long low = ((ofs & 0xfffff) ^ 0x80000) - 0x80000;
658 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - low);
661 /* If we were already given an index register, add it in. */
662 if (index != TCG_REG_NONE) {
663 tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
668 if (opc_rx && ofs >= 0 && ofs < 0x1000) {
669 tcg_out_insn_RX(s, opc_rx, data, base, index, ofs);
671 tcg_out_insn_RXY(s, opc_rxy, data, base, index, ofs);
676 /* load data without address translation or endianness conversion */
677 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
678 TCGReg base, intptr_t ofs)
680 if (type == TCG_TYPE_I32) {
681 tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs);
683 tcg_out_mem(s, 0, RXY_LG, data, base, TCG_REG_NONE, ofs);
687 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
688 TCGReg base, intptr_t ofs)
690 if (type == TCG_TYPE_I32) {
691 tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs);
693 tcg_out_mem(s, 0, RXY_STG, data, base, TCG_REG_NONE, ofs);
697 static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
698 TCGReg base, intptr_t ofs)
703 /* load data from an absolute host address */
704 static void tcg_out_ld_abs(TCGContext *s, TCGType type,
705 TCGReg dest, const void *abs)
707 intptr_t addr = (intptr_t)abs;
709 if ((s390_facilities & FACILITY_GEN_INST_EXT) && !(addr & 1)) {
710 ptrdiff_t disp = tcg_pcrel_diff(s, abs) >> 1;
711 if (disp == (int32_t)disp) {
712 if (type == TCG_TYPE_I32) {
713 tcg_out_insn(s, RIL, LRL, dest, disp);
715 tcg_out_insn(s, RIL, LGRL, dest, disp);
721 ptrdiff_t disp = tcg_tbrel_diff(s, abs);
722 if (disp == sextract64(disp, 0, 20)) {
723 tcg_out_ld(s, type, dest, TCG_REG_TB, disp);
728 tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
729 tcg_out_ld(s, type, dest, dest, addr & 0xffff);
732 static inline void tcg_out_risbg(TCGContext *s, TCGReg dest, TCGReg src,
733 int msb, int lsb, int ofs, int z)
736 tcg_out16(s, (RIE_RISBG & 0xff00) | (dest << 4) | src);
737 tcg_out16(s, (msb << 8) | (z << 7) | lsb);
738 tcg_out16(s, (ofs << 8) | (RIE_RISBG & 0xff));
741 static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
743 if (s390_facilities & FACILITY_EXT_IMM) {
744 tcg_out_insn(s, RRE, LGBR, dest, src);
748 if (type == TCG_TYPE_I32) {
750 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 24);
752 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 24);
754 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 24);
756 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 56);
757 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 56);
761 static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
763 if (s390_facilities & FACILITY_EXT_IMM) {
764 tcg_out_insn(s, RRE, LLGCR, dest, src);
769 tcg_out_movi(s, type, TCG_TMP0, 0xff);
772 tcg_out_movi(s, type, dest, 0xff);
774 if (type == TCG_TYPE_I32) {
775 tcg_out_insn(s, RR, NR, dest, src);
777 tcg_out_insn(s, RRE, NGR, dest, src);
781 static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
783 if (s390_facilities & FACILITY_EXT_IMM) {
784 tcg_out_insn(s, RRE, LGHR, dest, src);
788 if (type == TCG_TYPE_I32) {
790 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 16);
792 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 16);
794 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 16);
796 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 48);
797 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 48);
801 static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
803 if (s390_facilities & FACILITY_EXT_IMM) {
804 tcg_out_insn(s, RRE, LLGHR, dest, src);
809 tcg_out_movi(s, type, TCG_TMP0, 0xffff);
812 tcg_out_movi(s, type, dest, 0xffff);
814 if (type == TCG_TYPE_I32) {
815 tcg_out_insn(s, RR, NR, dest, src);
817 tcg_out_insn(s, RRE, NGR, dest, src);
821 static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
823 tcg_out_insn(s, RRE, LGFR, dest, src);
826 static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
828 tcg_out_insn(s, RRE, LLGFR, dest, src);
831 /* Accept bit patterns like these:
836 Copied from gcc sources. */
837 static inline bool risbg_mask(uint64_t c)
840 /* We don't change the number of transitions by inverting,
841 so make sure we start with the LSB zero. */
845 /* Reject all zeros or all ones. */
849 /* Find the first transition. */
851 /* Invert to look for a second transition. */
853 /* Erase the first transition. */
855 /* Find the second transition, if any. */
857 /* Match if all the bits are 1's, or if c is zero. */
861 static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val)
864 if ((val & 0x8000000000000001ull) == 0x8000000000000001ull) {
865 /* Achieve wraparound by swapping msb and lsb. */
866 msb = 64 - ctz64(~val);
867 lsb = clz64(~val) - 1;
870 lsb = 63 - ctz64(val);
872 tcg_out_risbg(s, out, in, msb, lsb, 0, 1);
875 static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
877 static const S390Opcode ni_insns[4] = {
878 RI_NILL, RI_NILH, RI_NIHL, RI_NIHH
880 static const S390Opcode nif_insns[2] = {
883 uint64_t valid = (type == TCG_TYPE_I32 ? 0xffffffffull : -1ull);
886 /* Look for the zero-extensions. */
887 if ((val & valid) == 0xffffffff) {
888 tgen_ext32u(s, dest, dest);
891 if (s390_facilities & FACILITY_EXT_IMM) {
892 if ((val & valid) == 0xff) {
893 tgen_ext8u(s, TCG_TYPE_I64, dest, dest);
896 if ((val & valid) == 0xffff) {
897 tgen_ext16u(s, TCG_TYPE_I64, dest, dest);
902 /* Try all 32-bit insns that can perform it in one go. */
903 for (i = 0; i < 4; i++) {
904 tcg_target_ulong mask = ~(0xffffull << i*16);
905 if (((val | ~valid) & mask) == mask) {
906 tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
911 /* Try all 48-bit insns that can perform it in one go. */
912 if (s390_facilities & FACILITY_EXT_IMM) {
913 for (i = 0; i < 2; i++) {
914 tcg_target_ulong mask = ~(0xffffffffull << i*32);
915 if (((val | ~valid) & mask) == mask) {
916 tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
921 if ((s390_facilities & FACILITY_GEN_INST_EXT) && risbg_mask(val)) {
922 tgen_andi_risbg(s, dest, dest, val);
926 /* Use the constant pool if USE_REG_TB, but not for small constants. */
928 if (!maybe_out_small_movi(s, type, TCG_TMP0, val)) {
929 tcg_out_insn(s, RXY, NG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
930 new_pool_label(s, val & valid, R_390_20, s->code_ptr - 2,
931 tcg_tbrel_diff(s, NULL));
935 tcg_out_movi(s, type, TCG_TMP0, val);
937 if (type == TCG_TYPE_I32) {
938 tcg_out_insn(s, RR, NR, dest, TCG_TMP0);
940 tcg_out_insn(s, RRE, NGR, dest, TCG_TMP0);
944 static void tgen_ori(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
946 static const S390Opcode oi_insns[4] = {
947 RI_OILL, RI_OILH, RI_OIHL, RI_OIHH
949 static const S390Opcode oif_insns[2] = {
955 /* Look for no-op. */
956 if (unlikely(val == 0)) {
960 /* Try all 32-bit insns that can perform it in one go. */
961 for (i = 0; i < 4; i++) {
962 tcg_target_ulong mask = (0xffffull << i*16);
963 if ((val & mask) != 0 && (val & ~mask) == 0) {
964 tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
969 /* Try all 48-bit insns that can perform it in one go. */
970 if (s390_facilities & FACILITY_EXT_IMM) {
971 for (i = 0; i < 2; i++) {
972 tcg_target_ulong mask = (0xffffffffull << i*32);
973 if ((val & mask) != 0 && (val & ~mask) == 0) {
974 tcg_out_insn_RIL(s, oif_insns[i], dest, val >> i*32);
980 /* Use the constant pool if USE_REG_TB, but not for small constants. */
981 if (maybe_out_small_movi(s, type, TCG_TMP0, val)) {
982 if (type == TCG_TYPE_I32) {
983 tcg_out_insn(s, RR, OR, dest, TCG_TMP0);
985 tcg_out_insn(s, RRE, OGR, dest, TCG_TMP0);
987 } else if (USE_REG_TB) {
988 tcg_out_insn(s, RXY, OG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
989 new_pool_label(s, val, R_390_20, s->code_ptr - 2,
990 tcg_tbrel_diff(s, NULL));
992 /* Perform the OR via sequential modifications to the high and
993 low parts. Do this via recursion to handle 16-bit vs 32-bit
994 masks in each half. */
995 tcg_debug_assert(s390_facilities & FACILITY_EXT_IMM);
996 tgen_ori(s, type, dest, val & 0x00000000ffffffffull);
997 tgen_ori(s, type, dest, val & 0xffffffff00000000ull);
1001 static void tgen_xori(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
1003 /* Try all 48-bit insns that can perform it in one go. */
1004 if (s390_facilities & FACILITY_EXT_IMM) {
1005 if ((val & 0xffffffff00000000ull) == 0) {
1006 tcg_out_insn(s, RIL, XILF, dest, val);
1009 if ((val & 0x00000000ffffffffull) == 0) {
1010 tcg_out_insn(s, RIL, XIHF, dest, val >> 32);
1015 /* Use the constant pool if USE_REG_TB, but not for small constants. */
1016 if (maybe_out_small_movi(s, type, TCG_TMP0, val)) {
1017 if (type == TCG_TYPE_I32) {
1018 tcg_out_insn(s, RR, XR, dest, TCG_TMP0);
1020 tcg_out_insn(s, RRE, XGR, dest, TCG_TMP0);
1022 } else if (USE_REG_TB) {
1023 tcg_out_insn(s, RXY, XG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
1024 new_pool_label(s, val, R_390_20, s->code_ptr - 2,
1025 tcg_tbrel_diff(s, NULL));
1027 /* Perform the xor by parts. */
1028 tcg_debug_assert(s390_facilities & FACILITY_EXT_IMM);
1029 if (val & 0xffffffff) {
1030 tcg_out_insn(s, RIL, XILF, dest, val);
1032 if (val > 0xffffffff) {
1033 tcg_out_insn(s, RIL, XIHF, dest, val >> 32);
1038 static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
1039 TCGArg c2, bool c2const, bool need_carry)
1041 bool is_unsigned = is_unsigned_cond(c);
1046 if (!(is_unsigned && need_carry)) {
1047 if (type == TCG_TYPE_I32) {
1048 tcg_out_insn(s, RR, LTR, r1, r1);
1050 tcg_out_insn(s, RRE, LTGR, r1, r1);
1052 return tcg_cond_to_ltr_cond[c];
1056 if (!is_unsigned && c2 == (int16_t)c2) {
1057 op = (type == TCG_TYPE_I32 ? RI_CHI : RI_CGHI);
1058 tcg_out_insn_RI(s, op, r1, c2);
1062 if (s390_facilities & FACILITY_EXT_IMM) {
1063 if (type == TCG_TYPE_I32) {
1064 op = (is_unsigned ? RIL_CLFI : RIL_CFI);
1065 tcg_out_insn_RIL(s, op, r1, c2);
1067 } else if (c2 == (is_unsigned ? (TCGArg)(uint32_t)c2 : (TCGArg)(int32_t)c2)) {
1068 op = (is_unsigned ? RIL_CLGFI : RIL_CGFI);
1069 tcg_out_insn_RIL(s, op, r1, c2);
1074 /* Use the constant pool, but not for small constants. */
1075 if (maybe_out_small_movi(s, type, TCG_TMP0, c2)) {
1077 /* fall through to reg-reg */
1078 } else if (USE_REG_TB) {
1079 if (type == TCG_TYPE_I32) {
1080 op = (is_unsigned ? RXY_CLY : RXY_CY);
1081 tcg_out_insn_RXY(s, op, r1, TCG_REG_TB, TCG_REG_NONE, 0);
1082 new_pool_label(s, (uint32_t)c2, R_390_20, s->code_ptr - 2,
1083 4 - tcg_tbrel_diff(s, NULL));
1085 op = (is_unsigned ? RXY_CLG : RXY_CG);
1086 tcg_out_insn_RXY(s, op, r1, TCG_REG_TB, TCG_REG_NONE, 0);
1087 new_pool_label(s, c2, R_390_20, s->code_ptr - 2,
1088 tcg_tbrel_diff(s, NULL));
1092 if (type == TCG_TYPE_I32) {
1093 op = (is_unsigned ? RIL_CLRL : RIL_CRL);
1094 tcg_out_insn_RIL(s, op, r1, 0);
1095 new_pool_label(s, (uint32_t)c2, R_390_PC32DBL,
1096 s->code_ptr - 2, 2 + 4);
1098 op = (is_unsigned ? RIL_CLGRL : RIL_CGRL);
1099 tcg_out_insn_RIL(s, op, r1, 0);
1100 new_pool_label(s, c2, R_390_PC32DBL, s->code_ptr - 2, 2);
1106 if (type == TCG_TYPE_I32) {
1107 op = (is_unsigned ? RR_CLR : RR_CR);
1108 tcg_out_insn_RR(s, op, r1, c2);
1110 op = (is_unsigned ? RRE_CLGR : RRE_CGR);
1111 tcg_out_insn_RRE(s, op, r1, c2);
1115 return tcg_cond_to_s390_cond[c];
1118 static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
1119 TCGReg dest, TCGReg c1, TCGArg c2, int c2const)
1124 /* With LOC2, we can always emit the minimum 3 insns. */
1125 if (s390_facilities & FACILITY_LOAD_ON_COND2) {
1126 /* Emit: d = 0, d = (cc ? 1 : d). */
1127 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1128 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1129 tcg_out_insn(s, RIE, LOCGHI, dest, 1, cc);
1133 have_loc = (s390_facilities & FACILITY_LOAD_ON_COND) != 0;
1135 /* For HAVE_LOC, only the paths through GTU/GT/LEU/LE are smaller. */
1139 /* X != 0 is X > 0. */
1140 if (c2const && c2 == 0) {
1141 cond = TCG_COND_GTU;
1149 /* The result of a compare has CC=2 for GT and CC=3 unused.
1150 ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */
1151 tgen_cmp(s, type, cond, c1, c2, c2const, true);
1152 tcg_out_movi(s, type, dest, 0);
1153 tcg_out_insn(s, RRE, ALCGR, dest, dest);
1157 /* X == 0 is X <= 0. */
1158 if (c2const && c2 == 0) {
1159 cond = TCG_COND_LEU;
1167 /* As above, but we're looking for borrow, or !carry.
1168 The second insn computes d - d - borrow, or -1 for true
1169 and 0 for false. So we must mask to 1 bit afterward. */
1170 tgen_cmp(s, type, cond, c1, c2, c2const, true);
1171 tcg_out_insn(s, RRE, SLBGR, dest, dest);
1172 tgen_andi(s, type, dest, 1);
1179 /* Swap operands so that we can use LEU/GTU/GT/LE. */
1184 tcg_out_movi(s, type, TCG_TMP0, c2);
1193 cond = tcg_swap_cond(cond);
1197 g_assert_not_reached();
1200 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1202 /* Emit: d = 0, t = 1, d = (cc ? t : d). */
1203 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1204 tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 1);
1205 tcg_out_insn(s, RRF, LOCGR, dest, TCG_TMP0, cc);
1207 /* Emit: d = 1; if (cc) goto over; d = 0; over: */
1208 tcg_out_movi(s, type, dest, 1);
1209 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1210 tcg_out_movi(s, type, dest, 0);
1214 static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest,
1215 TCGReg c1, TCGArg c2, int c2const,
1216 TCGArg v3, int v3const)
1219 if (s390_facilities & FACILITY_LOAD_ON_COND) {
1220 cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1222 tcg_out_insn(s, RIE, LOCGHI, dest, v3, cc);
1224 tcg_out_insn(s, RRF, LOCGR, dest, v3, cc);
1227 c = tcg_invert_cond(c);
1228 cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1230 /* Emit: if (cc) goto over; dest = r3; over: */
1231 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1232 tcg_out_insn(s, RRE, LGR, dest, v3);
1236 static void tgen_clz(TCGContext *s, TCGReg dest, TCGReg a1,
1237 TCGArg a2, int a2const)
1239 /* Since this sets both R and R+1, we have no choice but to store the
1240 result into R0, allowing R1 == TCG_TMP0 to be clobbered as well. */
1241 QEMU_BUILD_BUG_ON(TCG_TMP0 != TCG_REG_R1);
1242 tcg_out_insn(s, RRE, FLOGR, TCG_REG_R0, a1);
1244 if (a2const && a2 == 64) {
1245 tcg_out_mov(s, TCG_TYPE_I64, dest, TCG_REG_R0);
1248 tcg_out_movi(s, TCG_TYPE_I64, dest, a2);
1250 tcg_out_mov(s, TCG_TYPE_I64, dest, a2);
1252 if (s390_facilities & FACILITY_LOAD_ON_COND) {
1253 /* Emit: if (one bit found) dest = r0. */
1254 tcg_out_insn(s, RRF, LOCGR, dest, TCG_REG_R0, 2);
1256 /* Emit: if (no one bit found) goto over; dest = r0; over: */
1257 tcg_out_insn(s, RI, BRC, 8, (4 + 4) >> 1);
1258 tcg_out_insn(s, RRE, LGR, dest, TCG_REG_R0);
1263 static void tgen_deposit(TCGContext *s, TCGReg dest, TCGReg src,
1264 int ofs, int len, int z)
1266 int lsb = (63 - ofs);
1267 int msb = lsb - (len - 1);
1268 tcg_out_risbg(s, dest, src, msb, lsb, ofs, z);
1271 static void tgen_extract(TCGContext *s, TCGReg dest, TCGReg src,
1274 tcg_out_risbg(s, dest, src, 64 - len, 63, 64 - ofs, 1);
1277 static void tgen_gotoi(TCGContext *s, int cc, const tcg_insn_unit *dest)
1279 ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
1280 if (off == (int16_t)off) {
1281 tcg_out_insn(s, RI, BRC, cc, off);
1282 } else if (off == (int32_t)off) {
1283 tcg_out_insn(s, RIL, BRCL, cc, off);
1285 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1286 tcg_out_insn(s, RR, BCR, cc, TCG_TMP0);
1290 static void tgen_branch(TCGContext *s, int cc, TCGLabel *l)
1293 tgen_gotoi(s, cc, l->u.value_ptr);
1294 } else if (USE_LONG_BRANCHES) {
1295 tcg_out16(s, RIL_BRCL | (cc << 4));
1296 tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, l, 2);
1299 tcg_out16(s, RI_BRC | (cc << 4));
1300 tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, l, 2);
1305 static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
1306 TCGReg r1, TCGReg r2, TCGLabel *l)
1308 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
1309 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
1311 tcg_out16(s, cc << 12 | (opc & 0xff));
1314 static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
1315 TCGReg r1, int i2, TCGLabel *l)
1317 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
1318 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
1320 tcg_out16(s, (i2 << 8) | (opc & 0xff));
1323 static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
1324 TCGReg r1, TCGArg c2, int c2const, TCGLabel *l)
1328 if (s390_facilities & FACILITY_GEN_INST_EXT) {
1329 bool is_unsigned = is_unsigned_cond(c);
1333 cc = tcg_cond_to_s390_cond[c];
1336 opc = (type == TCG_TYPE_I32
1337 ? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
1338 : (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
1339 tgen_compare_branch(s, opc, cc, r1, c2, l);
1343 /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1344 If the immediate we've been given does not fit that range, we'll
1345 fall back to separate compare and branch instructions using the
1346 larger comparison range afforded by COMPARE IMMEDIATE. */
1347 if (type == TCG_TYPE_I32) {
1350 in_range = (uint32_t)c2 == (uint8_t)c2;
1353 in_range = (int32_t)c2 == (int8_t)c2;
1358 in_range = (uint64_t)c2 == (uint8_t)c2;
1361 in_range = (int64_t)c2 == (int8_t)c2;
1365 tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
1370 cc = tgen_cmp(s, type, c, r1, c2, c2const, false);
1371 tgen_branch(s, cc, l);
1374 static void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest)
1376 ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
1377 if (off == (int32_t)off) {
1378 tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
1380 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1381 tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_TMP0);
1385 static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data,
1386 TCGReg base, TCGReg index, int disp)
1388 switch (opc & (MO_SSIZE | MO_BSWAP)) {
1390 tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
1393 tcg_out_insn(s, RXY, LGB, data, base, index, disp);
1396 case MO_UW | MO_BSWAP:
1397 /* swapped unsigned halfword load with upper bits zeroed */
1398 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1399 tgen_ext16u(s, TCG_TYPE_I64, data, data);
1402 tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
1405 case MO_SW | MO_BSWAP:
1406 /* swapped sign-extended halfword load */
1407 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1408 tgen_ext16s(s, TCG_TYPE_I64, data, data);
1411 tcg_out_insn(s, RXY, LGH, data, base, index, disp);
1414 case MO_UL | MO_BSWAP:
1415 /* swapped unsigned int load with upper bits zeroed */
1416 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1417 tgen_ext32u(s, data, data);
1420 tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
1423 case MO_SL | MO_BSWAP:
1424 /* swapped sign-extended int load */
1425 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1426 tgen_ext32s(s, data, data);
1429 tcg_out_insn(s, RXY, LGF, data, base, index, disp);
1432 case MO_Q | MO_BSWAP:
1433 tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
1436 tcg_out_insn(s, RXY, LG, data, base, index, disp);
1444 static void tcg_out_qemu_st_direct(TCGContext *s, MemOp opc, TCGReg data,
1445 TCGReg base, TCGReg index, int disp)
1447 switch (opc & (MO_SIZE | MO_BSWAP)) {
1449 if (disp >= 0 && disp < 0x1000) {
1450 tcg_out_insn(s, RX, STC, data, base, index, disp);
1452 tcg_out_insn(s, RXY, STCY, data, base, index, disp);
1456 case MO_UW | MO_BSWAP:
1457 tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
1460 if (disp >= 0 && disp < 0x1000) {
1461 tcg_out_insn(s, RX, STH, data, base, index, disp);
1463 tcg_out_insn(s, RXY, STHY, data, base, index, disp);
1467 case MO_UL | MO_BSWAP:
1468 tcg_out_insn(s, RXY, STRV, data, base, index, disp);
1471 if (disp >= 0 && disp < 0x1000) {
1472 tcg_out_insn(s, RX, ST, data, base, index, disp);
1474 tcg_out_insn(s, RXY, STY, data, base, index, disp);
1478 case MO_Q | MO_BSWAP:
1479 tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
1482 tcg_out_insn(s, RXY, STG, data, base, index, disp);
1490 #if defined(CONFIG_SOFTMMU)
1491 #include "../tcg-ldst.c.inc"
1493 /* We're expecting to use a 20-bit negative offset on the tlb memory ops. */
1494 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
1495 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 19));
1497 /* Load and compare a TLB entry, leaving the flags set. Loads the TLB
1498 addend into R2. Returns a register with the santitized guest address. */
1499 static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, MemOp opc,
1500 int mem_index, bool is_ld)
1502 unsigned s_bits = opc & MO_SIZE;
1503 unsigned a_bits = get_alignment_bits(opc);
1504 unsigned s_mask = (1 << s_bits) - 1;
1505 unsigned a_mask = (1 << a_bits) - 1;
1506 int fast_off = TLB_MASK_TABLE_OFS(mem_index);
1507 int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
1508 int table_off = fast_off + offsetof(CPUTLBDescFast, table);
1512 tcg_out_sh64(s, RSY_SRLG, TCG_REG_R2, addr_reg, TCG_REG_NONE,
1513 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1514 tcg_out_insn(s, RXY, NG, TCG_REG_R2, TCG_AREG0, TCG_REG_NONE, mask_off);
1515 tcg_out_insn(s, RXY, AG, TCG_REG_R2, TCG_AREG0, TCG_REG_NONE, table_off);
1517 /* For aligned accesses, we check the first byte and include the alignment
1518 bits within the address. For unaligned access, we check that we don't
1519 cross pages using the address of the last byte of the access. */
1520 a_off = (a_bits >= s_bits ? 0 : s_mask - a_mask);
1521 tlb_mask = (uint64_t)TARGET_PAGE_MASK | a_mask;
1522 if ((s390_facilities & FACILITY_GEN_INST_EXT) && a_off == 0) {
1523 tgen_andi_risbg(s, TCG_REG_R3, addr_reg, tlb_mask);
1525 tcg_out_insn(s, RX, LA, TCG_REG_R3, addr_reg, TCG_REG_NONE, a_off);
1526 tgen_andi(s, TCG_TYPE_TL, TCG_REG_R3, tlb_mask);
1530 ofs = offsetof(CPUTLBEntry, addr_read);
1532 ofs = offsetof(CPUTLBEntry, addr_write);
1534 if (TARGET_LONG_BITS == 32) {
1535 tcg_out_insn(s, RX, C, TCG_REG_R3, TCG_REG_R2, TCG_REG_NONE, ofs);
1537 tcg_out_insn(s, RXY, CG, TCG_REG_R3, TCG_REG_R2, TCG_REG_NONE, ofs);
1540 tcg_out_insn(s, RXY, LG, TCG_REG_R2, TCG_REG_R2, TCG_REG_NONE,
1541 offsetof(CPUTLBEntry, addend));
1543 if (TARGET_LONG_BITS == 32) {
1544 tgen_ext32u(s, TCG_REG_R3, addr_reg);
1550 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
1551 TCGReg data, TCGReg addr,
1552 tcg_insn_unit *raddr, tcg_insn_unit *label_ptr)
1554 TCGLabelQemuLdst *label = new_ldst_label(s);
1556 label->is_ld = is_ld;
1558 label->datalo_reg = data;
1559 label->addrlo_reg = addr;
1560 label->raddr = tcg_splitwx_to_rx(raddr);
1561 label->label_ptr[0] = label_ptr;
1564 static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1566 TCGReg addr_reg = lb->addrlo_reg;
1567 TCGReg data_reg = lb->datalo_reg;
1568 TCGMemOpIdx oi = lb->oi;
1569 MemOp opc = get_memop(oi);
1571 if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
1572 (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
1576 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1577 if (TARGET_LONG_BITS == 64) {
1578 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
1580 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, oi);
1581 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R5, (uintptr_t)lb->raddr);
1582 tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)]);
1583 tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_R2);
1585 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1589 static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1591 TCGReg addr_reg = lb->addrlo_reg;
1592 TCGReg data_reg = lb->datalo_reg;
1593 TCGMemOpIdx oi = lb->oi;
1594 MemOp opc = get_memop(oi);
1596 if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
1597 (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
1601 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1602 if (TARGET_LONG_BITS == 64) {
1603 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
1605 switch (opc & MO_SIZE) {
1607 tgen_ext8u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1610 tgen_ext16u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1613 tgen_ext32u(s, TCG_REG_R4, data_reg);
1616 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1621 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, oi);
1622 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R6, (uintptr_t)lb->raddr);
1623 tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1625 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1629 static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
1630 TCGReg *index_reg, tcg_target_long *disp)
1632 if (TARGET_LONG_BITS == 32) {
1633 tgen_ext32u(s, TCG_TMP0, *addr_reg);
1634 *addr_reg = TCG_TMP0;
1636 if (guest_base < 0x80000) {
1637 *index_reg = TCG_REG_NONE;
1640 *index_reg = TCG_GUEST_BASE_REG;
1644 #endif /* CONFIG_SOFTMMU */
1646 static void tcg_out_qemu_ld(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
1649 MemOp opc = get_memop(oi);
1650 #ifdef CONFIG_SOFTMMU
1651 unsigned mem_index = get_mmuidx(oi);
1652 tcg_insn_unit *label_ptr;
1655 base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 1);
1657 tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
1658 label_ptr = s->code_ptr;
1661 tcg_out_qemu_ld_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
1663 add_qemu_ldst_label(s, 1, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
1666 tcg_target_long disp;
1668 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1669 tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1673 static void tcg_out_qemu_st(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
1676 MemOp opc = get_memop(oi);
1677 #ifdef CONFIG_SOFTMMU
1678 unsigned mem_index = get_mmuidx(oi);
1679 tcg_insn_unit *label_ptr;
1682 base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 0);
1684 tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
1685 label_ptr = s->code_ptr;
1688 tcg_out_qemu_st_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
1690 add_qemu_ldst_label(s, 0, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
1693 tcg_target_long disp;
1695 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1696 tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1700 # define OP_32_64(x) \
1701 case glue(glue(INDEX_op_,x),_i32): \
1702 case glue(glue(INDEX_op_,x),_i64)
1704 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1705 const TCGArg args[TCG_MAX_OP_ARGS],
1706 const int const_args[TCG_MAX_OP_ARGS])
1712 case INDEX_op_exit_tb:
1713 /* Reuse the zeroing that exists for goto_ptr. */
1716 tgen_gotoi(s, S390_CC_ALWAYS, tcg_code_gen_epilogue);
1718 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, a0);
1719 tgen_gotoi(s, S390_CC_ALWAYS, tb_ret_addr);
1723 case INDEX_op_goto_tb:
1725 if (s->tb_jmp_insn_offset) {
1727 * branch displacement must be aligned for atomic patching;
1728 * see if we need to add extra nop before branch
1730 if (!QEMU_PTR_IS_ALIGNED(s->code_ptr + 1, 4)) {
1733 tcg_debug_assert(!USE_REG_TB);
1734 tcg_out16(s, RIL_BRCL | (S390_CC_ALWAYS << 4));
1735 s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
1738 /* load address stored at s->tb_jmp_target_addr + a0 */
1739 tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_REG_TB,
1740 tcg_splitwx_to_rx(s->tb_jmp_target_addr + a0));
1742 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_TB);
1744 set_jmp_reset_offset(s, a0);
1746 /* For the unlinked path of goto_tb, we need to reset
1747 TCG_REG_TB to the beginning of this TB. */
1749 int ofs = -tcg_current_code_size(s);
1750 /* All TB are restricted to 64KiB by unwind info. */
1751 tcg_debug_assert(ofs == sextract64(ofs, 0, 20));
1752 tcg_out_insn(s, RXY, LAY, TCG_REG_TB,
1753 TCG_REG_TB, TCG_REG_NONE, ofs);
1757 case INDEX_op_goto_ptr:
1760 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, a0);
1762 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, a0);
1766 /* ??? LLC (RXY format) is only present with the extended-immediate
1767 facility, whereas LLGC is always present. */
1768 tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
1772 /* ??? LB is no smaller than LGB, so no point to using it. */
1773 tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
1777 /* ??? LLH (RXY format) is only present with the extended-immediate
1778 facility, whereas LLGH is always present. */
1779 tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
1782 case INDEX_op_ld16s_i32:
1783 tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
1786 case INDEX_op_ld_i32:
1787 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1791 tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
1792 TCG_REG_NONE, args[2]);
1796 tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
1797 TCG_REG_NONE, args[2]);
1800 case INDEX_op_st_i32:
1801 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1804 case INDEX_op_add_i32:
1805 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1806 if (const_args[2]) {
1809 if (a2 == (int16_t)a2) {
1810 tcg_out_insn(s, RI, AHI, a0, a2);
1813 if (s390_facilities & FACILITY_EXT_IMM) {
1814 tcg_out_insn(s, RIL, AFI, a0, a2);
1818 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
1819 } else if (a0 == a1) {
1820 tcg_out_insn(s, RR, AR, a0, a2);
1822 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
1825 case INDEX_op_sub_i32:
1826 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1827 if (const_args[2]) {
1830 } else if (a0 == a1) {
1831 tcg_out_insn(s, RR, SR, a0, a2);
1833 tcg_out_insn(s, RRF, SRK, a0, a1, a2);
1837 case INDEX_op_and_i32:
1838 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1839 if (const_args[2]) {
1840 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1841 tgen_andi(s, TCG_TYPE_I32, a0, a2);
1842 } else if (a0 == a1) {
1843 tcg_out_insn(s, RR, NR, a0, a2);
1845 tcg_out_insn(s, RRF, NRK, a0, a1, a2);
1848 case INDEX_op_or_i32:
1849 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1850 if (const_args[2]) {
1851 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1852 tgen_ori(s, TCG_TYPE_I32, a0, a2);
1853 } else if (a0 == a1) {
1854 tcg_out_insn(s, RR, OR, a0, a2);
1856 tcg_out_insn(s, RRF, ORK, a0, a1, a2);
1859 case INDEX_op_xor_i32:
1860 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1861 if (const_args[2]) {
1862 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1863 tgen_xori(s, TCG_TYPE_I32, a0, a2);
1864 } else if (a0 == a1) {
1865 tcg_out_insn(s, RR, XR, args[0], args[2]);
1867 tcg_out_insn(s, RRF, XRK, a0, a1, a2);
1871 case INDEX_op_neg_i32:
1872 tcg_out_insn(s, RR, LCR, args[0], args[1]);
1875 case INDEX_op_mul_i32:
1876 if (const_args[2]) {
1877 if ((int32_t)args[2] == (int16_t)args[2]) {
1878 tcg_out_insn(s, RI, MHI, args[0], args[2]);
1880 tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
1883 tcg_out_insn(s, RRE, MSR, args[0], args[2]);
1887 case INDEX_op_div2_i32:
1888 tcg_out_insn(s, RR, DR, TCG_REG_R2, args[4]);
1890 case INDEX_op_divu2_i32:
1891 tcg_out_insn(s, RRE, DLR, TCG_REG_R2, args[4]);
1894 case INDEX_op_shl_i32:
1898 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1900 if (const_args[2]) {
1901 tcg_out_sh32(s, op, a0, TCG_REG_NONE, a2);
1903 tcg_out_sh32(s, op, a0, a2, 0);
1906 /* Using tcg_out_sh64 here for the format; it is a 32-bit shift. */
1907 if (const_args[2]) {
1908 tcg_out_sh64(s, op2, a0, a1, TCG_REG_NONE, a2);
1910 tcg_out_sh64(s, op2, a0, a1, a2, 0);
1914 case INDEX_op_shr_i32:
1918 case INDEX_op_sar_i32:
1923 case INDEX_op_rotl_i32:
1924 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1925 if (const_args[2]) {
1926 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
1928 tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
1931 case INDEX_op_rotr_i32:
1932 if (const_args[2]) {
1933 tcg_out_sh64(s, RSY_RLL, args[0], args[1],
1934 TCG_REG_NONE, (32 - args[2]) & 31);
1936 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
1937 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
1941 case INDEX_op_ext8s_i32:
1942 tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
1944 case INDEX_op_ext16s_i32:
1945 tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
1947 case INDEX_op_ext8u_i32:
1948 tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
1950 case INDEX_op_ext16u_i32:
1951 tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
1954 case INDEX_op_bswap16_i32:
1955 a0 = args[0], a1 = args[1], a2 = args[2];
1956 tcg_out_insn(s, RRE, LRVR, a0, a1);
1957 if (a2 & TCG_BSWAP_OS) {
1958 tcg_out_sh32(s, RS_SRA, a0, TCG_REG_NONE, 16);
1960 tcg_out_sh32(s, RS_SRL, a0, TCG_REG_NONE, 16);
1963 case INDEX_op_bswap16_i64:
1964 a0 = args[0], a1 = args[1], a2 = args[2];
1965 tcg_out_insn(s, RRE, LRVGR, a0, a1);
1966 if (a2 & TCG_BSWAP_OS) {
1967 tcg_out_sh64(s, RSY_SRAG, a0, a0, TCG_REG_NONE, 48);
1969 tcg_out_sh64(s, RSY_SRLG, a0, a0, TCG_REG_NONE, 48);
1973 case INDEX_op_bswap32_i32:
1974 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1976 case INDEX_op_bswap32_i64:
1977 a0 = args[0], a1 = args[1], a2 = args[2];
1978 tcg_out_insn(s, RRE, LRVR, a0, a1);
1979 if (a2 & TCG_BSWAP_OS) {
1980 tgen_ext32s(s, a0, a0);
1981 } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) {
1982 tgen_ext32u(s, a0, a0);
1986 case INDEX_op_add2_i32:
1987 if (const_args[4]) {
1988 tcg_out_insn(s, RIL, ALFI, args[0], args[4]);
1990 tcg_out_insn(s, RR, ALR, args[0], args[4]);
1992 tcg_out_insn(s, RRE, ALCR, args[1], args[5]);
1994 case INDEX_op_sub2_i32:
1995 if (const_args[4]) {
1996 tcg_out_insn(s, RIL, SLFI, args[0], args[4]);
1998 tcg_out_insn(s, RR, SLR, args[0], args[4]);
2000 tcg_out_insn(s, RRE, SLBR, args[1], args[5]);
2004 tgen_branch(s, S390_CC_ALWAYS, arg_label(args[0]));
2007 case INDEX_op_brcond_i32:
2008 tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
2009 args[1], const_args[1], arg_label(args[3]));
2011 case INDEX_op_setcond_i32:
2012 tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
2013 args[2], const_args[2]);
2015 case INDEX_op_movcond_i32:
2016 tgen_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1],
2017 args[2], const_args[2], args[3], const_args[3]);
2020 case INDEX_op_qemu_ld_i32:
2021 /* ??? Technically we can use a non-extending instruction. */
2022 case INDEX_op_qemu_ld_i64:
2023 tcg_out_qemu_ld(s, args[0], args[1], args[2]);
2025 case INDEX_op_qemu_st_i32:
2026 case INDEX_op_qemu_st_i64:
2027 tcg_out_qemu_st(s, args[0], args[1], args[2]);
2030 case INDEX_op_ld16s_i64:
2031 tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
2033 case INDEX_op_ld32u_i64:
2034 tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
2036 case INDEX_op_ld32s_i64:
2037 tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
2039 case INDEX_op_ld_i64:
2040 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2043 case INDEX_op_st32_i64:
2044 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
2046 case INDEX_op_st_i64:
2047 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2050 case INDEX_op_add_i64:
2051 a0 = args[0], a1 = args[1], a2 = args[2];
2052 if (const_args[2]) {
2055 if (a2 == (int16_t)a2) {
2056 tcg_out_insn(s, RI, AGHI, a0, a2);
2059 if (s390_facilities & FACILITY_EXT_IMM) {
2060 if (a2 == (int32_t)a2) {
2061 tcg_out_insn(s, RIL, AGFI, a0, a2);
2063 } else if (a2 == (uint32_t)a2) {
2064 tcg_out_insn(s, RIL, ALGFI, a0, a2);
2066 } else if (-a2 == (uint32_t)-a2) {
2067 tcg_out_insn(s, RIL, SLGFI, a0, -a2);
2072 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
2073 } else if (a0 == a1) {
2074 tcg_out_insn(s, RRE, AGR, a0, a2);
2076 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
2079 case INDEX_op_sub_i64:
2080 a0 = args[0], a1 = args[1], a2 = args[2];
2081 if (const_args[2]) {
2084 } else if (a0 == a1) {
2085 tcg_out_insn(s, RRE, SGR, a0, a2);
2087 tcg_out_insn(s, RRF, SGRK, a0, a1, a2);
2091 case INDEX_op_and_i64:
2092 a0 = args[0], a1 = args[1], a2 = args[2];
2093 if (const_args[2]) {
2094 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2095 tgen_andi(s, TCG_TYPE_I64, args[0], args[2]);
2096 } else if (a0 == a1) {
2097 tcg_out_insn(s, RRE, NGR, args[0], args[2]);
2099 tcg_out_insn(s, RRF, NGRK, a0, a1, a2);
2102 case INDEX_op_or_i64:
2103 a0 = args[0], a1 = args[1], a2 = args[2];
2104 if (const_args[2]) {
2105 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2106 tgen_ori(s, TCG_TYPE_I64, a0, a2);
2107 } else if (a0 == a1) {
2108 tcg_out_insn(s, RRE, OGR, a0, a2);
2110 tcg_out_insn(s, RRF, OGRK, a0, a1, a2);
2113 case INDEX_op_xor_i64:
2114 a0 = args[0], a1 = args[1], a2 = args[2];
2115 if (const_args[2]) {
2116 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2117 tgen_xori(s, TCG_TYPE_I64, a0, a2);
2118 } else if (a0 == a1) {
2119 tcg_out_insn(s, RRE, XGR, a0, a2);
2121 tcg_out_insn(s, RRF, XGRK, a0, a1, a2);
2125 case INDEX_op_neg_i64:
2126 tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
2128 case INDEX_op_bswap64_i64:
2129 tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
2132 case INDEX_op_mul_i64:
2133 if (const_args[2]) {
2134 if (args[2] == (int16_t)args[2]) {
2135 tcg_out_insn(s, RI, MGHI, args[0], args[2]);
2137 tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
2140 tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
2144 case INDEX_op_div2_i64:
2145 /* ??? We get an unnecessary sign-extension of the dividend
2146 into R3 with this definition, but as we do in fact always
2147 produce both quotient and remainder using INDEX_op_div_i64
2148 instead requires jumping through even more hoops. */
2149 tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
2151 case INDEX_op_divu2_i64:
2152 tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
2154 case INDEX_op_mulu2_i64:
2155 tcg_out_insn(s, RRE, MLGR, TCG_REG_R2, args[3]);
2158 case INDEX_op_shl_i64:
2161 if (const_args[2]) {
2162 tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
2164 tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
2167 case INDEX_op_shr_i64:
2170 case INDEX_op_sar_i64:
2174 case INDEX_op_rotl_i64:
2175 if (const_args[2]) {
2176 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2177 TCG_REG_NONE, args[2]);
2179 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
2182 case INDEX_op_rotr_i64:
2183 if (const_args[2]) {
2184 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2185 TCG_REG_NONE, (64 - args[2]) & 63);
2187 /* We can use the smaller 32-bit negate because only the
2188 low 6 bits are examined for the rotate. */
2189 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2190 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
2194 case INDEX_op_ext8s_i64:
2195 tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
2197 case INDEX_op_ext16s_i64:
2198 tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
2200 case INDEX_op_ext_i32_i64:
2201 case INDEX_op_ext32s_i64:
2202 tgen_ext32s(s, args[0], args[1]);
2204 case INDEX_op_ext8u_i64:
2205 tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
2207 case INDEX_op_ext16u_i64:
2208 tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
2210 case INDEX_op_extu_i32_i64:
2211 case INDEX_op_ext32u_i64:
2212 tgen_ext32u(s, args[0], args[1]);
2215 case INDEX_op_add2_i64:
2216 if (const_args[4]) {
2217 if ((int64_t)args[4] >= 0) {
2218 tcg_out_insn(s, RIL, ALGFI, args[0], args[4]);
2220 tcg_out_insn(s, RIL, SLGFI, args[0], -args[4]);
2223 tcg_out_insn(s, RRE, ALGR, args[0], args[4]);
2225 tcg_out_insn(s, RRE, ALCGR, args[1], args[5]);
2227 case INDEX_op_sub2_i64:
2228 if (const_args[4]) {
2229 if ((int64_t)args[4] >= 0) {
2230 tcg_out_insn(s, RIL, SLGFI, args[0], args[4]);
2232 tcg_out_insn(s, RIL, ALGFI, args[0], -args[4]);
2235 tcg_out_insn(s, RRE, SLGR, args[0], args[4]);
2237 tcg_out_insn(s, RRE, SLBGR, args[1], args[5]);
2240 case INDEX_op_brcond_i64:
2241 tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
2242 args[1], const_args[1], arg_label(args[3]));
2244 case INDEX_op_setcond_i64:
2245 tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2246 args[2], const_args[2]);
2248 case INDEX_op_movcond_i64:
2249 tgen_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1],
2250 args[2], const_args[2], args[3], const_args[3]);
2254 a0 = args[0], a1 = args[1], a2 = args[2];
2255 if (const_args[1]) {
2256 tgen_deposit(s, a0, a2, args[3], args[4], 1);
2258 /* Since we can't support "0Z" as a constraint, we allow a1 in
2259 any register. Fix things up as if a matching constraint. */
2261 TCGType type = (opc == INDEX_op_deposit_i64);
2263 tcg_out_mov(s, type, TCG_TMP0, a2);
2266 tcg_out_mov(s, type, a0, a1);
2268 tgen_deposit(s, a0, a2, args[3], args[4], 0);
2273 tgen_extract(s, args[0], args[1], args[2], args[3]);
2276 case INDEX_op_clz_i64:
2277 tgen_clz(s, args[0], args[1], args[2], const_args[2]);
2281 /* The host memory model is quite strong, we simply need to
2282 serialize the instruction stream. */
2283 if (args[0] & TCG_MO_ST_LD) {
2284 tcg_out_insn(s, RR, BCR,
2285 s390_facilities & FACILITY_FAST_BCR_SER ? 14 : 15, 0);
2289 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
2290 case INDEX_op_mov_i64:
2291 case INDEX_op_call: /* Always emitted via tcg_out_call. */
2297 static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
2300 case INDEX_op_goto_ptr:
2303 case INDEX_op_ld8u_i32:
2304 case INDEX_op_ld8u_i64:
2305 case INDEX_op_ld8s_i32:
2306 case INDEX_op_ld8s_i64:
2307 case INDEX_op_ld16u_i32:
2308 case INDEX_op_ld16u_i64:
2309 case INDEX_op_ld16s_i32:
2310 case INDEX_op_ld16s_i64:
2311 case INDEX_op_ld_i32:
2312 case INDEX_op_ld32u_i64:
2313 case INDEX_op_ld32s_i64:
2314 case INDEX_op_ld_i64:
2315 return C_O1_I1(r, r);
2317 case INDEX_op_st8_i32:
2318 case INDEX_op_st8_i64:
2319 case INDEX_op_st16_i32:
2320 case INDEX_op_st16_i64:
2321 case INDEX_op_st_i32:
2322 case INDEX_op_st32_i64:
2323 case INDEX_op_st_i64:
2324 return C_O0_I2(r, r);
2326 case INDEX_op_add_i32:
2327 case INDEX_op_add_i64:
2328 case INDEX_op_shl_i64:
2329 case INDEX_op_shr_i64:
2330 case INDEX_op_sar_i64:
2331 case INDEX_op_rotl_i32:
2332 case INDEX_op_rotl_i64:
2333 case INDEX_op_rotr_i32:
2334 case INDEX_op_rotr_i64:
2335 case INDEX_op_clz_i64:
2336 case INDEX_op_setcond_i32:
2337 case INDEX_op_setcond_i64:
2338 return C_O1_I2(r, r, ri);
2340 case INDEX_op_sub_i32:
2341 case INDEX_op_sub_i64:
2342 case INDEX_op_and_i32:
2343 case INDEX_op_and_i64:
2344 case INDEX_op_or_i32:
2345 case INDEX_op_or_i64:
2346 case INDEX_op_xor_i32:
2347 case INDEX_op_xor_i64:
2348 return (s390_facilities & FACILITY_DISTINCT_OPS
2350 : C_O1_I2(r, 0, ri));
2352 case INDEX_op_mul_i32:
2353 /* If we have the general-instruction-extensions, then we have
2354 MULTIPLY SINGLE IMMEDIATE with a signed 32-bit, otherwise we
2355 have only MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
2356 return (s390_facilities & FACILITY_GEN_INST_EXT
2358 : C_O1_I2(r, 0, rI));
2360 case INDEX_op_mul_i64:
2361 return (s390_facilities & FACILITY_GEN_INST_EXT
2363 : C_O1_I2(r, 0, rI));
2365 case INDEX_op_shl_i32:
2366 case INDEX_op_shr_i32:
2367 case INDEX_op_sar_i32:
2368 return (s390_facilities & FACILITY_DISTINCT_OPS
2370 : C_O1_I2(r, 0, ri));
2372 case INDEX_op_brcond_i32:
2373 case INDEX_op_brcond_i64:
2374 return C_O0_I2(r, ri);
2376 case INDEX_op_bswap16_i32:
2377 case INDEX_op_bswap16_i64:
2378 case INDEX_op_bswap32_i32:
2379 case INDEX_op_bswap32_i64:
2380 case INDEX_op_bswap64_i64:
2381 case INDEX_op_neg_i32:
2382 case INDEX_op_neg_i64:
2383 case INDEX_op_ext8s_i32:
2384 case INDEX_op_ext8s_i64:
2385 case INDEX_op_ext8u_i32:
2386 case INDEX_op_ext8u_i64:
2387 case INDEX_op_ext16s_i32:
2388 case INDEX_op_ext16s_i64:
2389 case INDEX_op_ext16u_i32:
2390 case INDEX_op_ext16u_i64:
2391 case INDEX_op_ext32s_i64:
2392 case INDEX_op_ext32u_i64:
2393 case INDEX_op_ext_i32_i64:
2394 case INDEX_op_extu_i32_i64:
2395 case INDEX_op_extract_i32:
2396 case INDEX_op_extract_i64:
2397 return C_O1_I1(r, r);
2399 case INDEX_op_qemu_ld_i32:
2400 case INDEX_op_qemu_ld_i64:
2401 return C_O1_I1(r, L);
2402 case INDEX_op_qemu_st_i64:
2403 case INDEX_op_qemu_st_i32:
2404 return C_O0_I2(L, L);
2406 case INDEX_op_deposit_i32:
2407 case INDEX_op_deposit_i64:
2408 return C_O1_I2(r, rZ, r);
2410 case INDEX_op_movcond_i32:
2411 case INDEX_op_movcond_i64:
2412 return (s390_facilities & FACILITY_LOAD_ON_COND2
2413 ? C_O1_I4(r, r, ri, rI, 0)
2414 : C_O1_I4(r, r, ri, r, 0));
2416 case INDEX_op_div2_i32:
2417 case INDEX_op_div2_i64:
2418 case INDEX_op_divu2_i32:
2419 case INDEX_op_divu2_i64:
2420 return C_O2_I3(b, a, 0, 1, r);
2422 case INDEX_op_mulu2_i64:
2423 return C_O2_I2(b, a, 0, r);
2425 case INDEX_op_add2_i32:
2426 case INDEX_op_sub2_i32:
2427 return (s390_facilities & FACILITY_EXT_IMM
2428 ? C_O2_I4(r, r, 0, 1, ri, r)
2429 : C_O2_I4(r, r, 0, 1, r, r));
2431 case INDEX_op_add2_i64:
2432 case INDEX_op_sub2_i64:
2433 return (s390_facilities & FACILITY_EXT_IMM
2434 ? C_O2_I4(r, r, 0, 1, rA, r)
2435 : C_O2_I4(r, r, 0, 1, r, r));
2438 g_assert_not_reached();
2442 static void query_s390_facilities(void)
2444 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2446 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
2447 is present on all 64-bit systems, but let's check for it anyway. */
2448 if (hwcap & HWCAP_S390_STFLE) {
2449 register int r0 __asm__("0");
2450 register void *r1 __asm__("1");
2453 r1 = &s390_facilities;
2454 asm volatile(".word 0xb2b0,0x1000"
2455 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
2459 static void tcg_target_init(TCGContext *s)
2461 query_s390_facilities();
2463 tcg_target_available_regs[TCG_TYPE_I32] = 0xffff;
2464 tcg_target_available_regs[TCG_TYPE_I64] = 0xffff;
2466 tcg_target_call_clobber_regs = 0;
2467 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2468 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
2469 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2470 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2471 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
2472 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
2473 /* The r6 register is technically call-saved, but it's also a parameter
2474 register, so it can get killed by setup for the qemu_st helper. */
2475 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6);
2476 /* The return register can be considered call-clobbered. */
2477 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2479 s->reserved_regs = 0;
2480 tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
2481 /* XXX many insns can't be used with R0, so we better avoid it for now */
2482 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
2483 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2485 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB);
2489 #define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
2490 + TCG_STATIC_CALL_ARGS_SIZE \
2491 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
2493 static void tcg_target_qemu_prologue(TCGContext *s)
2495 /* stmg %r6,%r15,48(%r15) (save registers) */
2496 tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
2498 /* aghi %r15,-frame_size */
2499 tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -FRAME_SIZE);
2501 tcg_set_frame(s, TCG_REG_CALL_STACK,
2502 TCG_STATIC_CALL_ARGS_SIZE + TCG_TARGET_CALL_STACK_OFFSET,
2503 CPU_TEMP_BUF_NLONGS * sizeof(long));
2505 #ifndef CONFIG_SOFTMMU
2506 if (guest_base >= 0x80000) {
2507 tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base, true);
2508 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2512 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2514 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB,
2515 tcg_target_call_iarg_regs[1]);
2518 /* br %r3 (go to TB) */
2519 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
2522 * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2523 * and fall through to the rest of the epilogue.
2525 tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
2526 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, 0);
2529 tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
2531 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2532 tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15,
2535 /* br %r14 (return) */
2536 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
2539 static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
2541 memset(p, 0x07, count * sizeof(tcg_insn_unit));
2546 uint8_t fde_def_cfa[4];
2547 uint8_t fde_reg_ofs[18];
2550 /* We're expecting a 2 byte uleb128 encoded value. */
2551 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2553 #define ELF_HOST_MACHINE EM_S390
2555 static const DebugFrame debug_frame = {
2556 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2559 .h.cie.code_align = 1,
2560 .h.cie.data_align = 8, /* sleb128 8 */
2561 .h.cie.return_column = TCG_REG_R14,
2563 /* Total FDE size does not include the "len" member. */
2564 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
2567 12, TCG_REG_CALL_STACK, /* DW_CFA_def_cfa %r15, ... */
2568 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2572 0x86, 6, /* DW_CFA_offset, %r6, 48 */
2573 0x87, 7, /* DW_CFA_offset, %r7, 56 */
2574 0x88, 8, /* DW_CFA_offset, %r8, 64 */
2575 0x89, 9, /* DW_CFA_offset, %r92, 72 */
2576 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
2577 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
2578 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
2579 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
2580 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
2584 void tcg_register_jit(const void *buf, size_t buf_size)
2586 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));