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]);
1955 /* The TCG bswap definition requires bits 0-47 already be zero.
1956 Thus we don't need the G-type insns to implement bswap16_i64. */
1957 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1958 tcg_out_sh32(s, RS_SRL, args[0], TCG_REG_NONE, 16);
1961 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1964 case INDEX_op_add2_i32:
1965 if (const_args[4]) {
1966 tcg_out_insn(s, RIL, ALFI, args[0], args[4]);
1968 tcg_out_insn(s, RR, ALR, args[0], args[4]);
1970 tcg_out_insn(s, RRE, ALCR, args[1], args[5]);
1972 case INDEX_op_sub2_i32:
1973 if (const_args[4]) {
1974 tcg_out_insn(s, RIL, SLFI, args[0], args[4]);
1976 tcg_out_insn(s, RR, SLR, args[0], args[4]);
1978 tcg_out_insn(s, RRE, SLBR, args[1], args[5]);
1982 tgen_branch(s, S390_CC_ALWAYS, arg_label(args[0]));
1985 case INDEX_op_brcond_i32:
1986 tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
1987 args[1], const_args[1], arg_label(args[3]));
1989 case INDEX_op_setcond_i32:
1990 tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
1991 args[2], const_args[2]);
1993 case INDEX_op_movcond_i32:
1994 tgen_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1],
1995 args[2], const_args[2], args[3], const_args[3]);
1998 case INDEX_op_qemu_ld_i32:
1999 /* ??? Technically we can use a non-extending instruction. */
2000 case INDEX_op_qemu_ld_i64:
2001 tcg_out_qemu_ld(s, args[0], args[1], args[2]);
2003 case INDEX_op_qemu_st_i32:
2004 case INDEX_op_qemu_st_i64:
2005 tcg_out_qemu_st(s, args[0], args[1], args[2]);
2008 case INDEX_op_ld16s_i64:
2009 tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
2011 case INDEX_op_ld32u_i64:
2012 tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
2014 case INDEX_op_ld32s_i64:
2015 tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
2017 case INDEX_op_ld_i64:
2018 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2021 case INDEX_op_st32_i64:
2022 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
2024 case INDEX_op_st_i64:
2025 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2028 case INDEX_op_add_i64:
2029 a0 = args[0], a1 = args[1], a2 = args[2];
2030 if (const_args[2]) {
2033 if (a2 == (int16_t)a2) {
2034 tcg_out_insn(s, RI, AGHI, a0, a2);
2037 if (s390_facilities & FACILITY_EXT_IMM) {
2038 if (a2 == (int32_t)a2) {
2039 tcg_out_insn(s, RIL, AGFI, a0, a2);
2041 } else if (a2 == (uint32_t)a2) {
2042 tcg_out_insn(s, RIL, ALGFI, a0, a2);
2044 } else if (-a2 == (uint32_t)-a2) {
2045 tcg_out_insn(s, RIL, SLGFI, a0, -a2);
2050 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
2051 } else if (a0 == a1) {
2052 tcg_out_insn(s, RRE, AGR, a0, a2);
2054 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
2057 case INDEX_op_sub_i64:
2058 a0 = args[0], a1 = args[1], a2 = args[2];
2059 if (const_args[2]) {
2062 } else if (a0 == a1) {
2063 tcg_out_insn(s, RRE, SGR, a0, a2);
2065 tcg_out_insn(s, RRF, SGRK, a0, a1, a2);
2069 case INDEX_op_and_i64:
2070 a0 = args[0], a1 = args[1], a2 = args[2];
2071 if (const_args[2]) {
2072 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2073 tgen_andi(s, TCG_TYPE_I64, args[0], args[2]);
2074 } else if (a0 == a1) {
2075 tcg_out_insn(s, RRE, NGR, args[0], args[2]);
2077 tcg_out_insn(s, RRF, NGRK, a0, a1, a2);
2080 case INDEX_op_or_i64:
2081 a0 = args[0], a1 = args[1], a2 = args[2];
2082 if (const_args[2]) {
2083 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2084 tgen_ori(s, TCG_TYPE_I64, a0, a2);
2085 } else if (a0 == a1) {
2086 tcg_out_insn(s, RRE, OGR, a0, a2);
2088 tcg_out_insn(s, RRF, OGRK, a0, a1, a2);
2091 case INDEX_op_xor_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_xori(s, TCG_TYPE_I64, a0, a2);
2096 } else if (a0 == a1) {
2097 tcg_out_insn(s, RRE, XGR, a0, a2);
2099 tcg_out_insn(s, RRF, XGRK, a0, a1, a2);
2103 case INDEX_op_neg_i64:
2104 tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
2106 case INDEX_op_bswap64_i64:
2107 tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
2110 case INDEX_op_mul_i64:
2111 if (const_args[2]) {
2112 if (args[2] == (int16_t)args[2]) {
2113 tcg_out_insn(s, RI, MGHI, args[0], args[2]);
2115 tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
2118 tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
2122 case INDEX_op_div2_i64:
2123 /* ??? We get an unnecessary sign-extension of the dividend
2124 into R3 with this definition, but as we do in fact always
2125 produce both quotient and remainder using INDEX_op_div_i64
2126 instead requires jumping through even more hoops. */
2127 tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
2129 case INDEX_op_divu2_i64:
2130 tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
2132 case INDEX_op_mulu2_i64:
2133 tcg_out_insn(s, RRE, MLGR, TCG_REG_R2, args[3]);
2136 case INDEX_op_shl_i64:
2139 if (const_args[2]) {
2140 tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
2142 tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
2145 case INDEX_op_shr_i64:
2148 case INDEX_op_sar_i64:
2152 case INDEX_op_rotl_i64:
2153 if (const_args[2]) {
2154 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2155 TCG_REG_NONE, args[2]);
2157 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
2160 case INDEX_op_rotr_i64:
2161 if (const_args[2]) {
2162 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2163 TCG_REG_NONE, (64 - args[2]) & 63);
2165 /* We can use the smaller 32-bit negate because only the
2166 low 6 bits are examined for the rotate. */
2167 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2168 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
2172 case INDEX_op_ext8s_i64:
2173 tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
2175 case INDEX_op_ext16s_i64:
2176 tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
2178 case INDEX_op_ext_i32_i64:
2179 case INDEX_op_ext32s_i64:
2180 tgen_ext32s(s, args[0], args[1]);
2182 case INDEX_op_ext8u_i64:
2183 tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
2185 case INDEX_op_ext16u_i64:
2186 tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
2188 case INDEX_op_extu_i32_i64:
2189 case INDEX_op_ext32u_i64:
2190 tgen_ext32u(s, args[0], args[1]);
2193 case INDEX_op_add2_i64:
2194 if (const_args[4]) {
2195 if ((int64_t)args[4] >= 0) {
2196 tcg_out_insn(s, RIL, ALGFI, args[0], args[4]);
2198 tcg_out_insn(s, RIL, SLGFI, args[0], -args[4]);
2201 tcg_out_insn(s, RRE, ALGR, args[0], args[4]);
2203 tcg_out_insn(s, RRE, ALCGR, args[1], args[5]);
2205 case INDEX_op_sub2_i64:
2206 if (const_args[4]) {
2207 if ((int64_t)args[4] >= 0) {
2208 tcg_out_insn(s, RIL, SLGFI, args[0], args[4]);
2210 tcg_out_insn(s, RIL, ALGFI, args[0], -args[4]);
2213 tcg_out_insn(s, RRE, SLGR, args[0], args[4]);
2215 tcg_out_insn(s, RRE, SLBGR, args[1], args[5]);
2218 case INDEX_op_brcond_i64:
2219 tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
2220 args[1], const_args[1], arg_label(args[3]));
2222 case INDEX_op_setcond_i64:
2223 tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2224 args[2], const_args[2]);
2226 case INDEX_op_movcond_i64:
2227 tgen_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1],
2228 args[2], const_args[2], args[3], const_args[3]);
2232 a0 = args[0], a1 = args[1], a2 = args[2];
2233 if (const_args[1]) {
2234 tgen_deposit(s, a0, a2, args[3], args[4], 1);
2236 /* Since we can't support "0Z" as a constraint, we allow a1 in
2237 any register. Fix things up as if a matching constraint. */
2239 TCGType type = (opc == INDEX_op_deposit_i64);
2241 tcg_out_mov(s, type, TCG_TMP0, a2);
2244 tcg_out_mov(s, type, a0, a1);
2246 tgen_deposit(s, a0, a2, args[3], args[4], 0);
2251 tgen_extract(s, args[0], args[1], args[2], args[3]);
2254 case INDEX_op_clz_i64:
2255 tgen_clz(s, args[0], args[1], args[2], const_args[2]);
2259 /* The host memory model is quite strong, we simply need to
2260 serialize the instruction stream. */
2261 if (args[0] & TCG_MO_ST_LD) {
2262 tcg_out_insn(s, RR, BCR,
2263 s390_facilities & FACILITY_FAST_BCR_SER ? 14 : 15, 0);
2267 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
2268 case INDEX_op_mov_i64:
2269 case INDEX_op_call: /* Always emitted via tcg_out_call. */
2275 static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
2278 case INDEX_op_goto_ptr:
2281 case INDEX_op_ld8u_i32:
2282 case INDEX_op_ld8u_i64:
2283 case INDEX_op_ld8s_i32:
2284 case INDEX_op_ld8s_i64:
2285 case INDEX_op_ld16u_i32:
2286 case INDEX_op_ld16u_i64:
2287 case INDEX_op_ld16s_i32:
2288 case INDEX_op_ld16s_i64:
2289 case INDEX_op_ld_i32:
2290 case INDEX_op_ld32u_i64:
2291 case INDEX_op_ld32s_i64:
2292 case INDEX_op_ld_i64:
2293 return C_O1_I1(r, r);
2295 case INDEX_op_st8_i32:
2296 case INDEX_op_st8_i64:
2297 case INDEX_op_st16_i32:
2298 case INDEX_op_st16_i64:
2299 case INDEX_op_st_i32:
2300 case INDEX_op_st32_i64:
2301 case INDEX_op_st_i64:
2302 return C_O0_I2(r, r);
2304 case INDEX_op_add_i32:
2305 case INDEX_op_add_i64:
2306 case INDEX_op_shl_i64:
2307 case INDEX_op_shr_i64:
2308 case INDEX_op_sar_i64:
2309 case INDEX_op_rotl_i32:
2310 case INDEX_op_rotl_i64:
2311 case INDEX_op_rotr_i32:
2312 case INDEX_op_rotr_i64:
2313 case INDEX_op_clz_i64:
2314 case INDEX_op_setcond_i32:
2315 case INDEX_op_setcond_i64:
2316 return C_O1_I2(r, r, ri);
2318 case INDEX_op_sub_i32:
2319 case INDEX_op_sub_i64:
2320 case INDEX_op_and_i32:
2321 case INDEX_op_and_i64:
2322 case INDEX_op_or_i32:
2323 case INDEX_op_or_i64:
2324 case INDEX_op_xor_i32:
2325 case INDEX_op_xor_i64:
2326 return (s390_facilities & FACILITY_DISTINCT_OPS
2328 : C_O1_I2(r, 0, ri));
2330 case INDEX_op_mul_i32:
2331 /* If we have the general-instruction-extensions, then we have
2332 MULTIPLY SINGLE IMMEDIATE with a signed 32-bit, otherwise we
2333 have only MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
2334 return (s390_facilities & FACILITY_GEN_INST_EXT
2336 : C_O1_I2(r, 0, rI));
2338 case INDEX_op_mul_i64:
2339 return (s390_facilities & FACILITY_GEN_INST_EXT
2341 : C_O1_I2(r, 0, rI));
2343 case INDEX_op_shl_i32:
2344 case INDEX_op_shr_i32:
2345 case INDEX_op_sar_i32:
2346 return (s390_facilities & FACILITY_DISTINCT_OPS
2348 : C_O1_I2(r, 0, ri));
2350 case INDEX_op_brcond_i32:
2351 case INDEX_op_brcond_i64:
2352 return C_O0_I2(r, ri);
2354 case INDEX_op_bswap16_i32:
2355 case INDEX_op_bswap16_i64:
2356 case INDEX_op_bswap32_i32:
2357 case INDEX_op_bswap32_i64:
2358 case INDEX_op_bswap64_i64:
2359 case INDEX_op_neg_i32:
2360 case INDEX_op_neg_i64:
2361 case INDEX_op_ext8s_i32:
2362 case INDEX_op_ext8s_i64:
2363 case INDEX_op_ext8u_i32:
2364 case INDEX_op_ext8u_i64:
2365 case INDEX_op_ext16s_i32:
2366 case INDEX_op_ext16s_i64:
2367 case INDEX_op_ext16u_i32:
2368 case INDEX_op_ext16u_i64:
2369 case INDEX_op_ext32s_i64:
2370 case INDEX_op_ext32u_i64:
2371 case INDEX_op_ext_i32_i64:
2372 case INDEX_op_extu_i32_i64:
2373 case INDEX_op_extract_i32:
2374 case INDEX_op_extract_i64:
2375 return C_O1_I1(r, r);
2377 case INDEX_op_qemu_ld_i32:
2378 case INDEX_op_qemu_ld_i64:
2379 return C_O1_I1(r, L);
2380 case INDEX_op_qemu_st_i64:
2381 case INDEX_op_qemu_st_i32:
2382 return C_O0_I2(L, L);
2384 case INDEX_op_deposit_i32:
2385 case INDEX_op_deposit_i64:
2386 return C_O1_I2(r, rZ, r);
2388 case INDEX_op_movcond_i32:
2389 case INDEX_op_movcond_i64:
2390 return (s390_facilities & FACILITY_LOAD_ON_COND2
2391 ? C_O1_I4(r, r, ri, rI, 0)
2392 : C_O1_I4(r, r, ri, r, 0));
2394 case INDEX_op_div2_i32:
2395 case INDEX_op_div2_i64:
2396 case INDEX_op_divu2_i32:
2397 case INDEX_op_divu2_i64:
2398 return C_O2_I3(b, a, 0, 1, r);
2400 case INDEX_op_mulu2_i64:
2401 return C_O2_I2(b, a, 0, r);
2403 case INDEX_op_add2_i32:
2404 case INDEX_op_sub2_i32:
2405 return (s390_facilities & FACILITY_EXT_IMM
2406 ? C_O2_I4(r, r, 0, 1, ri, r)
2407 : C_O2_I4(r, r, 0, 1, r, r));
2409 case INDEX_op_add2_i64:
2410 case INDEX_op_sub2_i64:
2411 return (s390_facilities & FACILITY_EXT_IMM
2412 ? C_O2_I4(r, r, 0, 1, rA, r)
2413 : C_O2_I4(r, r, 0, 1, r, r));
2416 g_assert_not_reached();
2420 static void query_s390_facilities(void)
2422 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2424 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
2425 is present on all 64-bit systems, but let's check for it anyway. */
2426 if (hwcap & HWCAP_S390_STFLE) {
2427 register int r0 __asm__("0");
2428 register void *r1 __asm__("1");
2431 r1 = &s390_facilities;
2432 asm volatile(".word 0xb2b0,0x1000"
2433 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
2437 static void tcg_target_init(TCGContext *s)
2439 query_s390_facilities();
2441 tcg_target_available_regs[TCG_TYPE_I32] = 0xffff;
2442 tcg_target_available_regs[TCG_TYPE_I64] = 0xffff;
2444 tcg_target_call_clobber_regs = 0;
2445 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2446 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
2447 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2448 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2449 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
2450 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
2451 /* The r6 register is technically call-saved, but it's also a parameter
2452 register, so it can get killed by setup for the qemu_st helper. */
2453 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6);
2454 /* The return register can be considered call-clobbered. */
2455 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2457 s->reserved_regs = 0;
2458 tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
2459 /* XXX many insns can't be used with R0, so we better avoid it for now */
2460 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
2461 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2463 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB);
2467 #define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
2468 + TCG_STATIC_CALL_ARGS_SIZE \
2469 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
2471 static void tcg_target_qemu_prologue(TCGContext *s)
2473 /* stmg %r6,%r15,48(%r15) (save registers) */
2474 tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
2476 /* aghi %r15,-frame_size */
2477 tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -FRAME_SIZE);
2479 tcg_set_frame(s, TCG_REG_CALL_STACK,
2480 TCG_STATIC_CALL_ARGS_SIZE + TCG_TARGET_CALL_STACK_OFFSET,
2481 CPU_TEMP_BUF_NLONGS * sizeof(long));
2483 #ifndef CONFIG_SOFTMMU
2484 if (guest_base >= 0x80000) {
2485 tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base, true);
2486 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2490 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2492 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB,
2493 tcg_target_call_iarg_regs[1]);
2496 /* br %r3 (go to TB) */
2497 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
2500 * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2501 * and fall through to the rest of the epilogue.
2503 tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
2504 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, 0);
2507 tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
2509 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2510 tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15,
2513 /* br %r14 (return) */
2514 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
2517 static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
2519 memset(p, 0x07, count * sizeof(tcg_insn_unit));
2524 uint8_t fde_def_cfa[4];
2525 uint8_t fde_reg_ofs[18];
2528 /* We're expecting a 2 byte uleb128 encoded value. */
2529 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2531 #define ELF_HOST_MACHINE EM_S390
2533 static const DebugFrame debug_frame = {
2534 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2537 .h.cie.code_align = 1,
2538 .h.cie.data_align = 8, /* sleb128 8 */
2539 .h.cie.return_column = TCG_REG_R14,
2541 /* Total FDE size does not include the "len" member. */
2542 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
2545 12, TCG_REG_CALL_STACK, /* DW_CFA_def_cfa %r15, ... */
2546 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2550 0x86, 6, /* DW_CFA_offset, %r6, 48 */
2551 0x87, 7, /* DW_CFA_offset, %r7, 56 */
2552 0x88, 8, /* DW_CFA_offset, %r8, 64 */
2553 0x89, 9, /* DW_CFA_offset, %r92, 72 */
2554 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
2555 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
2556 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
2557 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
2558 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
2562 void tcg_register_jit(const void *buf, size_t buf_size)
2564 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));