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 int tcg_target_const_match(tcg_target_long val, TCGType type,
421 const TCGArgConstraint *arg_ct)
425 if (ct & TCG_CT_CONST) {
429 if (type == TCG_TYPE_I32) {
433 /* The following are mutually exclusive. */
434 if (ct & TCG_CT_CONST_S16) {
435 return val == (int16_t)val;
436 } else if (ct & TCG_CT_CONST_S32) {
437 return val == (int32_t)val;
438 } else if (ct & TCG_CT_CONST_S33) {
439 return val >= -0xffffffffll && val <= 0xffffffffll;
440 } else if (ct & TCG_CT_CONST_ZERO) {
447 /* Emit instructions according to the given instruction format. */
449 static void tcg_out_insn_RR(TCGContext *s, S390Opcode op, TCGReg r1, TCGReg r2)
451 tcg_out16(s, (op << 8) | (r1 << 4) | r2);
454 static void tcg_out_insn_RRE(TCGContext *s, S390Opcode op,
455 TCGReg r1, TCGReg r2)
457 tcg_out32(s, (op << 16) | (r1 << 4) | r2);
460 static void tcg_out_insn_RRF(TCGContext *s, S390Opcode op,
461 TCGReg r1, TCGReg r2, int m3)
463 tcg_out32(s, (op << 16) | (m3 << 12) | (r1 << 4) | r2);
466 static void tcg_out_insn_RI(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
468 tcg_out32(s, (op << 16) | (r1 << 20) | (i2 & 0xffff));
471 static void tcg_out_insn_RIE(TCGContext *s, S390Opcode op, TCGReg r1,
474 tcg_out16(s, (op & 0xff00) | (r1 << 4) | m3);
475 tcg_out32(s, (i2 << 16) | (op & 0xff));
478 static void tcg_out_insn_RIL(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
480 tcg_out16(s, op | (r1 << 4));
484 static void tcg_out_insn_RS(TCGContext *s, S390Opcode op, TCGReg r1,
485 TCGReg b2, TCGReg r3, int disp)
487 tcg_out32(s, (op << 24) | (r1 << 20) | (r3 << 16) | (b2 << 12)
491 static void tcg_out_insn_RSY(TCGContext *s, S390Opcode op, TCGReg r1,
492 TCGReg b2, TCGReg r3, int disp)
494 tcg_out16(s, (op & 0xff00) | (r1 << 4) | r3);
495 tcg_out32(s, (op & 0xff) | (b2 << 28)
496 | ((disp & 0xfff) << 16) | ((disp & 0xff000) >> 4));
499 #define tcg_out_insn_RX tcg_out_insn_RS
500 #define tcg_out_insn_RXY tcg_out_insn_RSY
502 /* Emit an opcode with "type-checking" of the format. */
503 #define tcg_out_insn(S, FMT, OP, ...) \
504 glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
507 /* emit 64-bit shifts */
508 static void tcg_out_sh64(TCGContext* s, S390Opcode op, TCGReg dest,
509 TCGReg src, TCGReg sh_reg, int sh_imm)
511 tcg_out_insn_RSY(s, op, dest, sh_reg, src, sh_imm);
514 /* emit 32-bit shifts */
515 static void tcg_out_sh32(TCGContext* s, S390Opcode op, TCGReg dest,
516 TCGReg sh_reg, int sh_imm)
518 tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
521 static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
524 if (type == TCG_TYPE_I32) {
525 tcg_out_insn(s, RR, LR, dst, src);
527 tcg_out_insn(s, RRE, LGR, dst, src);
533 static const S390Opcode lli_insns[4] = {
534 RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
537 static bool maybe_out_small_movi(TCGContext *s, TCGType type,
538 TCGReg ret, tcg_target_long sval)
540 tcg_target_ulong uval = sval;
543 if (type == TCG_TYPE_I32) {
544 uval = (uint32_t)sval;
545 sval = (int32_t)sval;
548 /* Try all 32-bit insns that can load it in one go. */
549 if (sval >= -0x8000 && sval < 0x8000) {
550 tcg_out_insn(s, RI, LGHI, ret, sval);
554 for (i = 0; i < 4; i++) {
555 tcg_target_long mask = 0xffffull << i*16;
556 if ((uval & mask) == uval) {
557 tcg_out_insn_RI(s, lli_insns[i], ret, uval >> i*16);
565 /* load a register with an immediate value */
566 static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
567 tcg_target_long sval, bool in_prologue)
569 tcg_target_ulong uval;
571 /* Try all 32-bit insns that can load it in one go. */
572 if (maybe_out_small_movi(s, type, ret, sval)) {
577 if (type == TCG_TYPE_I32) {
578 uval = (uint32_t)sval;
579 sval = (int32_t)sval;
582 /* Try all 48-bit insns that can load it in one go. */
583 if (s390_facilities & FACILITY_EXT_IMM) {
584 if (sval == (int32_t)sval) {
585 tcg_out_insn(s, RIL, LGFI, ret, sval);
588 if (uval <= 0xffffffff) {
589 tcg_out_insn(s, RIL, LLILF, ret, uval);
592 if ((uval & 0xffffffff) == 0) {
593 tcg_out_insn(s, RIL, LLIHF, ret, uval >> 32);
598 /* Try for PC-relative address load. For odd addresses,
599 attempt to use an offset from the start of the TB. */
600 if ((sval & 1) == 0) {
601 ptrdiff_t off = tcg_pcrel_diff(s, (void *)sval) >> 1;
602 if (off == (int32_t)off) {
603 tcg_out_insn(s, RIL, LARL, ret, off);
606 } else if (USE_REG_TB && !in_prologue) {
607 ptrdiff_t off = tcg_tbrel_diff(s, (void *)sval);
608 if (off == sextract64(off, 0, 20)) {
609 /* This is certain to be an address within TB, and therefore
610 OFF will be negative; don't try RX_LA. */
611 tcg_out_insn(s, RXY, LAY, ret, TCG_REG_TB, TCG_REG_NONE, off);
616 /* A 32-bit unsigned value can be loaded in 2 insns. And given
617 that LLILL, LLIHL, LLILF above did not succeed, we know that
618 both insns are required. */
619 if (uval <= 0xffffffff) {
620 tcg_out_insn(s, RI, LLILL, ret, uval);
621 tcg_out_insn(s, RI, IILH, ret, uval >> 16);
625 /* Otherwise, stuff it in the constant pool. */
626 if (s390_facilities & FACILITY_GEN_INST_EXT) {
627 tcg_out_insn(s, RIL, LGRL, ret, 0);
628 new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
629 } else if (USE_REG_TB && !in_prologue) {
630 tcg_out_insn(s, RXY, LG, ret, TCG_REG_TB, TCG_REG_NONE, 0);
631 new_pool_label(s, sval, R_390_20, s->code_ptr - 2,
632 tcg_tbrel_diff(s, NULL));
634 TCGReg base = ret ? ret : TCG_TMP0;
635 tcg_out_insn(s, RIL, LARL, base, 0);
636 new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
637 tcg_out_insn(s, RXY, LG, ret, base, TCG_REG_NONE, 0);
641 static void tcg_out_movi(TCGContext *s, TCGType type,
642 TCGReg ret, tcg_target_long sval)
644 tcg_out_movi_int(s, type, ret, sval, false);
647 /* Emit a load/store type instruction. Inputs are:
648 DATA: The register to be loaded or stored.
649 BASE+OFS: The effective address.
650 OPC_RX: If the operation has an RX format opcode (e.g. STC), otherwise 0.
651 OPC_RXY: The RXY format opcode for the operation (e.g. STCY). */
653 static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
654 TCGReg data, TCGReg base, TCGReg index,
657 if (ofs < -0x80000 || ofs >= 0x80000) {
658 /* Combine the low 20 bits of the offset with the actual load insn;
659 the high 44 bits must come from an immediate load. */
660 tcg_target_long low = ((ofs & 0xfffff) ^ 0x80000) - 0x80000;
661 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - low);
664 /* If we were already given an index register, add it in. */
665 if (index != TCG_REG_NONE) {
666 tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
671 if (opc_rx && ofs >= 0 && ofs < 0x1000) {
672 tcg_out_insn_RX(s, opc_rx, data, base, index, ofs);
674 tcg_out_insn_RXY(s, opc_rxy, data, base, index, ofs);
679 /* load data without address translation or endianness conversion */
680 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
681 TCGReg base, intptr_t ofs)
683 if (type == TCG_TYPE_I32) {
684 tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs);
686 tcg_out_mem(s, 0, RXY_LG, data, base, TCG_REG_NONE, ofs);
690 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
691 TCGReg base, intptr_t ofs)
693 if (type == TCG_TYPE_I32) {
694 tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs);
696 tcg_out_mem(s, 0, RXY_STG, data, base, TCG_REG_NONE, ofs);
700 static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
701 TCGReg base, intptr_t ofs)
706 /* load data from an absolute host address */
707 static void tcg_out_ld_abs(TCGContext *s, TCGType type,
708 TCGReg dest, const void *abs)
710 intptr_t addr = (intptr_t)abs;
712 if ((s390_facilities & FACILITY_GEN_INST_EXT) && !(addr & 1)) {
713 ptrdiff_t disp = tcg_pcrel_diff(s, abs) >> 1;
714 if (disp == (int32_t)disp) {
715 if (type == TCG_TYPE_I32) {
716 tcg_out_insn(s, RIL, LRL, dest, disp);
718 tcg_out_insn(s, RIL, LGRL, dest, disp);
724 ptrdiff_t disp = tcg_tbrel_diff(s, abs);
725 if (disp == sextract64(disp, 0, 20)) {
726 tcg_out_ld(s, type, dest, TCG_REG_TB, disp);
731 tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
732 tcg_out_ld(s, type, dest, dest, addr & 0xffff);
735 static inline void tcg_out_risbg(TCGContext *s, TCGReg dest, TCGReg src,
736 int msb, int lsb, int ofs, int z)
739 tcg_out16(s, (RIE_RISBG & 0xff00) | (dest << 4) | src);
740 tcg_out16(s, (msb << 8) | (z << 7) | lsb);
741 tcg_out16(s, (ofs << 8) | (RIE_RISBG & 0xff));
744 static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
746 if (s390_facilities & FACILITY_EXT_IMM) {
747 tcg_out_insn(s, RRE, LGBR, dest, src);
751 if (type == TCG_TYPE_I32) {
753 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 24);
755 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 24);
757 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 24);
759 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 56);
760 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 56);
764 static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
766 if (s390_facilities & FACILITY_EXT_IMM) {
767 tcg_out_insn(s, RRE, LLGCR, dest, src);
772 tcg_out_movi(s, type, TCG_TMP0, 0xff);
775 tcg_out_movi(s, type, dest, 0xff);
777 if (type == TCG_TYPE_I32) {
778 tcg_out_insn(s, RR, NR, dest, src);
780 tcg_out_insn(s, RRE, NGR, dest, src);
784 static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
786 if (s390_facilities & FACILITY_EXT_IMM) {
787 tcg_out_insn(s, RRE, LGHR, dest, src);
791 if (type == TCG_TYPE_I32) {
793 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 16);
795 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 16);
797 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 16);
799 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 48);
800 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 48);
804 static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
806 if (s390_facilities & FACILITY_EXT_IMM) {
807 tcg_out_insn(s, RRE, LLGHR, dest, src);
812 tcg_out_movi(s, type, TCG_TMP0, 0xffff);
815 tcg_out_movi(s, type, dest, 0xffff);
817 if (type == TCG_TYPE_I32) {
818 tcg_out_insn(s, RR, NR, dest, src);
820 tcg_out_insn(s, RRE, NGR, dest, src);
824 static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
826 tcg_out_insn(s, RRE, LGFR, dest, src);
829 static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
831 tcg_out_insn(s, RRE, LLGFR, dest, src);
834 /* Accept bit patterns like these:
839 Copied from gcc sources. */
840 static inline bool risbg_mask(uint64_t c)
843 /* We don't change the number of transitions by inverting,
844 so make sure we start with the LSB zero. */
848 /* Reject all zeros or all ones. */
852 /* Find the first transition. */
854 /* Invert to look for a second transition. */
856 /* Erase the first transition. */
858 /* Find the second transition, if any. */
860 /* Match if all the bits are 1's, or if c is zero. */
864 static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val)
867 if ((val & 0x8000000000000001ull) == 0x8000000000000001ull) {
868 /* Achieve wraparound by swapping msb and lsb. */
869 msb = 64 - ctz64(~val);
870 lsb = clz64(~val) - 1;
873 lsb = 63 - ctz64(val);
875 tcg_out_risbg(s, out, in, msb, lsb, 0, 1);
878 static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
880 static const S390Opcode ni_insns[4] = {
881 RI_NILL, RI_NILH, RI_NIHL, RI_NIHH
883 static const S390Opcode nif_insns[2] = {
886 uint64_t valid = (type == TCG_TYPE_I32 ? 0xffffffffull : -1ull);
889 /* Look for the zero-extensions. */
890 if ((val & valid) == 0xffffffff) {
891 tgen_ext32u(s, dest, dest);
894 if (s390_facilities & FACILITY_EXT_IMM) {
895 if ((val & valid) == 0xff) {
896 tgen_ext8u(s, TCG_TYPE_I64, dest, dest);
899 if ((val & valid) == 0xffff) {
900 tgen_ext16u(s, TCG_TYPE_I64, dest, dest);
905 /* Try all 32-bit insns that can perform it in one go. */
906 for (i = 0; i < 4; i++) {
907 tcg_target_ulong mask = ~(0xffffull << i*16);
908 if (((val | ~valid) & mask) == mask) {
909 tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
914 /* Try all 48-bit insns that can perform it in one go. */
915 if (s390_facilities & FACILITY_EXT_IMM) {
916 for (i = 0; i < 2; i++) {
917 tcg_target_ulong mask = ~(0xffffffffull << i*32);
918 if (((val | ~valid) & mask) == mask) {
919 tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
924 if ((s390_facilities & FACILITY_GEN_INST_EXT) && risbg_mask(val)) {
925 tgen_andi_risbg(s, dest, dest, val);
929 /* Use the constant pool if USE_REG_TB, but not for small constants. */
931 if (!maybe_out_small_movi(s, type, TCG_TMP0, val)) {
932 tcg_out_insn(s, RXY, NG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
933 new_pool_label(s, val & valid, R_390_20, s->code_ptr - 2,
934 tcg_tbrel_diff(s, NULL));
938 tcg_out_movi(s, type, TCG_TMP0, val);
940 if (type == TCG_TYPE_I32) {
941 tcg_out_insn(s, RR, NR, dest, TCG_TMP0);
943 tcg_out_insn(s, RRE, NGR, dest, TCG_TMP0);
947 static void tgen_ori(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
949 static const S390Opcode oi_insns[4] = {
950 RI_OILL, RI_OILH, RI_OIHL, RI_OIHH
952 static const S390Opcode oif_insns[2] = {
958 /* Look for no-op. */
959 if (unlikely(val == 0)) {
963 /* Try all 32-bit insns that can perform it in one go. */
964 for (i = 0; i < 4; i++) {
965 tcg_target_ulong mask = (0xffffull << i*16);
966 if ((val & mask) != 0 && (val & ~mask) == 0) {
967 tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
972 /* Try all 48-bit insns that can perform it in one go. */
973 if (s390_facilities & FACILITY_EXT_IMM) {
974 for (i = 0; i < 2; i++) {
975 tcg_target_ulong mask = (0xffffffffull << i*32);
976 if ((val & mask) != 0 && (val & ~mask) == 0) {
977 tcg_out_insn_RIL(s, oif_insns[i], dest, val >> i*32);
983 /* Use the constant pool if USE_REG_TB, but not for small constants. */
984 if (maybe_out_small_movi(s, type, TCG_TMP0, val)) {
985 if (type == TCG_TYPE_I32) {
986 tcg_out_insn(s, RR, OR, dest, TCG_TMP0);
988 tcg_out_insn(s, RRE, OGR, dest, TCG_TMP0);
990 } else if (USE_REG_TB) {
991 tcg_out_insn(s, RXY, OG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
992 new_pool_label(s, val, R_390_20, s->code_ptr - 2,
993 tcg_tbrel_diff(s, NULL));
995 /* Perform the OR via sequential modifications to the high and
996 low parts. Do this via recursion to handle 16-bit vs 32-bit
997 masks in each half. */
998 tcg_debug_assert(s390_facilities & FACILITY_EXT_IMM);
999 tgen_ori(s, type, dest, val & 0x00000000ffffffffull);
1000 tgen_ori(s, type, dest, val & 0xffffffff00000000ull);
1004 static void tgen_xori(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
1006 /* Try all 48-bit insns that can perform it in one go. */
1007 if (s390_facilities & FACILITY_EXT_IMM) {
1008 if ((val & 0xffffffff00000000ull) == 0) {
1009 tcg_out_insn(s, RIL, XILF, dest, val);
1012 if ((val & 0x00000000ffffffffull) == 0) {
1013 tcg_out_insn(s, RIL, XIHF, dest, val >> 32);
1018 /* Use the constant pool if USE_REG_TB, but not for small constants. */
1019 if (maybe_out_small_movi(s, type, TCG_TMP0, val)) {
1020 if (type == TCG_TYPE_I32) {
1021 tcg_out_insn(s, RR, XR, dest, TCG_TMP0);
1023 tcg_out_insn(s, RRE, XGR, dest, TCG_TMP0);
1025 } else if (USE_REG_TB) {
1026 tcg_out_insn(s, RXY, XG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
1027 new_pool_label(s, val, R_390_20, s->code_ptr - 2,
1028 tcg_tbrel_diff(s, NULL));
1030 /* Perform the xor by parts. */
1031 tcg_debug_assert(s390_facilities & FACILITY_EXT_IMM);
1032 if (val & 0xffffffff) {
1033 tcg_out_insn(s, RIL, XILF, dest, val);
1035 if (val > 0xffffffff) {
1036 tcg_out_insn(s, RIL, XIHF, dest, val >> 32);
1041 static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
1042 TCGArg c2, bool c2const, bool need_carry)
1044 bool is_unsigned = is_unsigned_cond(c);
1049 if (!(is_unsigned && need_carry)) {
1050 if (type == TCG_TYPE_I32) {
1051 tcg_out_insn(s, RR, LTR, r1, r1);
1053 tcg_out_insn(s, RRE, LTGR, r1, r1);
1055 return tcg_cond_to_ltr_cond[c];
1059 if (!is_unsigned && c2 == (int16_t)c2) {
1060 op = (type == TCG_TYPE_I32 ? RI_CHI : RI_CGHI);
1061 tcg_out_insn_RI(s, op, r1, c2);
1065 if (s390_facilities & FACILITY_EXT_IMM) {
1066 if (type == TCG_TYPE_I32) {
1067 op = (is_unsigned ? RIL_CLFI : RIL_CFI);
1068 tcg_out_insn_RIL(s, op, r1, c2);
1070 } else if (c2 == (is_unsigned ? (TCGArg)(uint32_t)c2 : (TCGArg)(int32_t)c2)) {
1071 op = (is_unsigned ? RIL_CLGFI : RIL_CGFI);
1072 tcg_out_insn_RIL(s, op, r1, c2);
1077 /* Use the constant pool, but not for small constants. */
1078 if (maybe_out_small_movi(s, type, TCG_TMP0, c2)) {
1080 /* fall through to reg-reg */
1081 } else if (USE_REG_TB) {
1082 if (type == TCG_TYPE_I32) {
1083 op = (is_unsigned ? RXY_CLY : RXY_CY);
1084 tcg_out_insn_RXY(s, op, r1, TCG_REG_TB, TCG_REG_NONE, 0);
1085 new_pool_label(s, (uint32_t)c2, R_390_20, s->code_ptr - 2,
1086 4 - tcg_tbrel_diff(s, NULL));
1088 op = (is_unsigned ? RXY_CLG : RXY_CG);
1089 tcg_out_insn_RXY(s, op, r1, TCG_REG_TB, TCG_REG_NONE, 0);
1090 new_pool_label(s, c2, R_390_20, s->code_ptr - 2,
1091 tcg_tbrel_diff(s, NULL));
1095 if (type == TCG_TYPE_I32) {
1096 op = (is_unsigned ? RIL_CLRL : RIL_CRL);
1097 tcg_out_insn_RIL(s, op, r1, 0);
1098 new_pool_label(s, (uint32_t)c2, R_390_PC32DBL,
1099 s->code_ptr - 2, 2 + 4);
1101 op = (is_unsigned ? RIL_CLGRL : RIL_CGRL);
1102 tcg_out_insn_RIL(s, op, r1, 0);
1103 new_pool_label(s, c2, R_390_PC32DBL, s->code_ptr - 2, 2);
1109 if (type == TCG_TYPE_I32) {
1110 op = (is_unsigned ? RR_CLR : RR_CR);
1111 tcg_out_insn_RR(s, op, r1, c2);
1113 op = (is_unsigned ? RRE_CLGR : RRE_CGR);
1114 tcg_out_insn_RRE(s, op, r1, c2);
1118 return tcg_cond_to_s390_cond[c];
1121 static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
1122 TCGReg dest, TCGReg c1, TCGArg c2, int c2const)
1127 /* With LOC2, we can always emit the minimum 3 insns. */
1128 if (s390_facilities & FACILITY_LOAD_ON_COND2) {
1129 /* Emit: d = 0, d = (cc ? 1 : d). */
1130 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1131 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1132 tcg_out_insn(s, RIE, LOCGHI, dest, 1, cc);
1136 have_loc = (s390_facilities & FACILITY_LOAD_ON_COND) != 0;
1138 /* For HAVE_LOC, only the paths through GTU/GT/LEU/LE are smaller. */
1142 /* X != 0 is X > 0. */
1143 if (c2const && c2 == 0) {
1144 cond = TCG_COND_GTU;
1152 /* The result of a compare has CC=2 for GT and CC=3 unused.
1153 ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */
1154 tgen_cmp(s, type, cond, c1, c2, c2const, true);
1155 tcg_out_movi(s, type, dest, 0);
1156 tcg_out_insn(s, RRE, ALCGR, dest, dest);
1160 /* X == 0 is X <= 0. */
1161 if (c2const && c2 == 0) {
1162 cond = TCG_COND_LEU;
1170 /* As above, but we're looking for borrow, or !carry.
1171 The second insn computes d - d - borrow, or -1 for true
1172 and 0 for false. So we must mask to 1 bit afterward. */
1173 tgen_cmp(s, type, cond, c1, c2, c2const, true);
1174 tcg_out_insn(s, RRE, SLBGR, dest, dest);
1175 tgen_andi(s, type, dest, 1);
1182 /* Swap operands so that we can use LEU/GTU/GT/LE. */
1187 tcg_out_movi(s, type, TCG_TMP0, c2);
1196 cond = tcg_swap_cond(cond);
1200 g_assert_not_reached();
1203 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1205 /* Emit: d = 0, t = 1, d = (cc ? t : d). */
1206 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1207 tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 1);
1208 tcg_out_insn(s, RRF, LOCGR, dest, TCG_TMP0, cc);
1210 /* Emit: d = 1; if (cc) goto over; d = 0; over: */
1211 tcg_out_movi(s, type, dest, 1);
1212 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1213 tcg_out_movi(s, type, dest, 0);
1217 static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest,
1218 TCGReg c1, TCGArg c2, int c2const,
1219 TCGArg v3, int v3const)
1222 if (s390_facilities & FACILITY_LOAD_ON_COND) {
1223 cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1225 tcg_out_insn(s, RIE, LOCGHI, dest, v3, cc);
1227 tcg_out_insn(s, RRF, LOCGR, dest, v3, cc);
1230 c = tcg_invert_cond(c);
1231 cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1233 /* Emit: if (cc) goto over; dest = r3; over: */
1234 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1235 tcg_out_insn(s, RRE, LGR, dest, v3);
1239 static void tgen_clz(TCGContext *s, TCGReg dest, TCGReg a1,
1240 TCGArg a2, int a2const)
1242 /* Since this sets both R and R+1, we have no choice but to store the
1243 result into R0, allowing R1 == TCG_TMP0 to be clobbered as well. */
1244 QEMU_BUILD_BUG_ON(TCG_TMP0 != TCG_REG_R1);
1245 tcg_out_insn(s, RRE, FLOGR, TCG_REG_R0, a1);
1247 if (a2const && a2 == 64) {
1248 tcg_out_mov(s, TCG_TYPE_I64, dest, TCG_REG_R0);
1251 tcg_out_movi(s, TCG_TYPE_I64, dest, a2);
1253 tcg_out_mov(s, TCG_TYPE_I64, dest, a2);
1255 if (s390_facilities & FACILITY_LOAD_ON_COND) {
1256 /* Emit: if (one bit found) dest = r0. */
1257 tcg_out_insn(s, RRF, LOCGR, dest, TCG_REG_R0, 2);
1259 /* Emit: if (no one bit found) goto over; dest = r0; over: */
1260 tcg_out_insn(s, RI, BRC, 8, (4 + 4) >> 1);
1261 tcg_out_insn(s, RRE, LGR, dest, TCG_REG_R0);
1266 static void tgen_deposit(TCGContext *s, TCGReg dest, TCGReg src,
1267 int ofs, int len, int z)
1269 int lsb = (63 - ofs);
1270 int msb = lsb - (len - 1);
1271 tcg_out_risbg(s, dest, src, msb, lsb, ofs, z);
1274 static void tgen_extract(TCGContext *s, TCGReg dest, TCGReg src,
1277 tcg_out_risbg(s, dest, src, 64 - len, 63, 64 - ofs, 1);
1280 static void tgen_gotoi(TCGContext *s, int cc, const tcg_insn_unit *dest)
1282 ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
1283 if (off == (int16_t)off) {
1284 tcg_out_insn(s, RI, BRC, cc, off);
1285 } else if (off == (int32_t)off) {
1286 tcg_out_insn(s, RIL, BRCL, cc, off);
1288 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1289 tcg_out_insn(s, RR, BCR, cc, TCG_TMP0);
1293 static void tgen_branch(TCGContext *s, int cc, TCGLabel *l)
1296 tgen_gotoi(s, cc, l->u.value_ptr);
1297 } else if (USE_LONG_BRANCHES) {
1298 tcg_out16(s, RIL_BRCL | (cc << 4));
1299 tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, l, 2);
1302 tcg_out16(s, RI_BRC | (cc << 4));
1303 tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, l, 2);
1308 static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
1309 TCGReg r1, TCGReg r2, TCGLabel *l)
1311 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
1312 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
1314 tcg_out16(s, cc << 12 | (opc & 0xff));
1317 static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
1318 TCGReg r1, int i2, TCGLabel *l)
1320 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
1321 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
1323 tcg_out16(s, (i2 << 8) | (opc & 0xff));
1326 static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
1327 TCGReg r1, TCGArg c2, int c2const, TCGLabel *l)
1331 if (s390_facilities & FACILITY_GEN_INST_EXT) {
1332 bool is_unsigned = is_unsigned_cond(c);
1336 cc = tcg_cond_to_s390_cond[c];
1339 opc = (type == TCG_TYPE_I32
1340 ? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
1341 : (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
1342 tgen_compare_branch(s, opc, cc, r1, c2, l);
1346 /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1347 If the immediate we've been given does not fit that range, we'll
1348 fall back to separate compare and branch instructions using the
1349 larger comparison range afforded by COMPARE IMMEDIATE. */
1350 if (type == TCG_TYPE_I32) {
1353 in_range = (uint32_t)c2 == (uint8_t)c2;
1356 in_range = (int32_t)c2 == (int8_t)c2;
1361 in_range = (uint64_t)c2 == (uint8_t)c2;
1364 in_range = (int64_t)c2 == (int8_t)c2;
1368 tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
1373 cc = tgen_cmp(s, type, c, r1, c2, c2const, false);
1374 tgen_branch(s, cc, l);
1377 static void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest)
1379 ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
1380 if (off == (int32_t)off) {
1381 tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
1383 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1384 tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_TMP0);
1388 static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data,
1389 TCGReg base, TCGReg index, int disp)
1391 switch (opc & (MO_SSIZE | MO_BSWAP)) {
1393 tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
1396 tcg_out_insn(s, RXY, LGB, data, base, index, disp);
1399 case MO_UW | MO_BSWAP:
1400 /* swapped unsigned halfword load with upper bits zeroed */
1401 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1402 tgen_ext16u(s, TCG_TYPE_I64, data, data);
1405 tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
1408 case MO_SW | MO_BSWAP:
1409 /* swapped sign-extended halfword load */
1410 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1411 tgen_ext16s(s, TCG_TYPE_I64, data, data);
1414 tcg_out_insn(s, RXY, LGH, data, base, index, disp);
1417 case MO_UL | MO_BSWAP:
1418 /* swapped unsigned int load with upper bits zeroed */
1419 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1420 tgen_ext32u(s, data, data);
1423 tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
1426 case MO_SL | MO_BSWAP:
1427 /* swapped sign-extended int load */
1428 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1429 tgen_ext32s(s, data, data);
1432 tcg_out_insn(s, RXY, LGF, data, base, index, disp);
1435 case MO_Q | MO_BSWAP:
1436 tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
1439 tcg_out_insn(s, RXY, LG, data, base, index, disp);
1447 static void tcg_out_qemu_st_direct(TCGContext *s, MemOp opc, TCGReg data,
1448 TCGReg base, TCGReg index, int disp)
1450 switch (opc & (MO_SIZE | MO_BSWAP)) {
1452 if (disp >= 0 && disp < 0x1000) {
1453 tcg_out_insn(s, RX, STC, data, base, index, disp);
1455 tcg_out_insn(s, RXY, STCY, data, base, index, disp);
1459 case MO_UW | MO_BSWAP:
1460 tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
1463 if (disp >= 0 && disp < 0x1000) {
1464 tcg_out_insn(s, RX, STH, data, base, index, disp);
1466 tcg_out_insn(s, RXY, STHY, data, base, index, disp);
1470 case MO_UL | MO_BSWAP:
1471 tcg_out_insn(s, RXY, STRV, data, base, index, disp);
1474 if (disp >= 0 && disp < 0x1000) {
1475 tcg_out_insn(s, RX, ST, data, base, index, disp);
1477 tcg_out_insn(s, RXY, STY, data, base, index, disp);
1481 case MO_Q | MO_BSWAP:
1482 tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
1485 tcg_out_insn(s, RXY, STG, data, base, index, disp);
1493 #if defined(CONFIG_SOFTMMU)
1494 #include "../tcg-ldst.c.inc"
1496 /* We're expecting to use a 20-bit negative offset on the tlb memory ops. */
1497 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
1498 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 19));
1500 /* Load and compare a TLB entry, leaving the flags set. Loads the TLB
1501 addend into R2. Returns a register with the santitized guest address. */
1502 static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, MemOp opc,
1503 int mem_index, bool is_ld)
1505 unsigned s_bits = opc & MO_SIZE;
1506 unsigned a_bits = get_alignment_bits(opc);
1507 unsigned s_mask = (1 << s_bits) - 1;
1508 unsigned a_mask = (1 << a_bits) - 1;
1509 int fast_off = TLB_MASK_TABLE_OFS(mem_index);
1510 int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
1511 int table_off = fast_off + offsetof(CPUTLBDescFast, table);
1515 tcg_out_sh64(s, RSY_SRLG, TCG_REG_R2, addr_reg, TCG_REG_NONE,
1516 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1517 tcg_out_insn(s, RXY, NG, TCG_REG_R2, TCG_AREG0, TCG_REG_NONE, mask_off);
1518 tcg_out_insn(s, RXY, AG, TCG_REG_R2, TCG_AREG0, TCG_REG_NONE, table_off);
1520 /* For aligned accesses, we check the first byte and include the alignment
1521 bits within the address. For unaligned access, we check that we don't
1522 cross pages using the address of the last byte of the access. */
1523 a_off = (a_bits >= s_bits ? 0 : s_mask - a_mask);
1524 tlb_mask = (uint64_t)TARGET_PAGE_MASK | a_mask;
1525 if ((s390_facilities & FACILITY_GEN_INST_EXT) && a_off == 0) {
1526 tgen_andi_risbg(s, TCG_REG_R3, addr_reg, tlb_mask);
1528 tcg_out_insn(s, RX, LA, TCG_REG_R3, addr_reg, TCG_REG_NONE, a_off);
1529 tgen_andi(s, TCG_TYPE_TL, TCG_REG_R3, tlb_mask);
1533 ofs = offsetof(CPUTLBEntry, addr_read);
1535 ofs = offsetof(CPUTLBEntry, addr_write);
1537 if (TARGET_LONG_BITS == 32) {
1538 tcg_out_insn(s, RX, C, TCG_REG_R3, TCG_REG_R2, TCG_REG_NONE, ofs);
1540 tcg_out_insn(s, RXY, CG, TCG_REG_R3, TCG_REG_R2, TCG_REG_NONE, ofs);
1543 tcg_out_insn(s, RXY, LG, TCG_REG_R2, TCG_REG_R2, TCG_REG_NONE,
1544 offsetof(CPUTLBEntry, addend));
1546 if (TARGET_LONG_BITS == 32) {
1547 tgen_ext32u(s, TCG_REG_R3, addr_reg);
1553 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
1554 TCGReg data, TCGReg addr,
1555 tcg_insn_unit *raddr, tcg_insn_unit *label_ptr)
1557 TCGLabelQemuLdst *label = new_ldst_label(s);
1559 label->is_ld = is_ld;
1561 label->datalo_reg = data;
1562 label->addrlo_reg = addr;
1563 label->raddr = tcg_splitwx_to_rx(raddr);
1564 label->label_ptr[0] = label_ptr;
1567 static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1569 TCGReg addr_reg = lb->addrlo_reg;
1570 TCGReg data_reg = lb->datalo_reg;
1571 TCGMemOpIdx oi = lb->oi;
1572 MemOp opc = get_memop(oi);
1574 if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
1575 (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
1579 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1580 if (TARGET_LONG_BITS == 64) {
1581 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
1583 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, oi);
1584 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R5, (uintptr_t)lb->raddr);
1585 tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)]);
1586 tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_R2);
1588 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1592 static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1594 TCGReg addr_reg = lb->addrlo_reg;
1595 TCGReg data_reg = lb->datalo_reg;
1596 TCGMemOpIdx oi = lb->oi;
1597 MemOp opc = get_memop(oi);
1599 if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
1600 (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
1604 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1605 if (TARGET_LONG_BITS == 64) {
1606 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
1608 switch (opc & MO_SIZE) {
1610 tgen_ext8u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1613 tgen_ext16u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1616 tgen_ext32u(s, TCG_REG_R4, data_reg);
1619 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1624 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, oi);
1625 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R6, (uintptr_t)lb->raddr);
1626 tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1628 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1632 static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
1633 TCGReg *index_reg, tcg_target_long *disp)
1635 if (TARGET_LONG_BITS == 32) {
1636 tgen_ext32u(s, TCG_TMP0, *addr_reg);
1637 *addr_reg = TCG_TMP0;
1639 if (guest_base < 0x80000) {
1640 *index_reg = TCG_REG_NONE;
1643 *index_reg = TCG_GUEST_BASE_REG;
1647 #endif /* CONFIG_SOFTMMU */
1649 static void tcg_out_qemu_ld(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
1652 MemOp opc = get_memop(oi);
1653 #ifdef CONFIG_SOFTMMU
1654 unsigned mem_index = get_mmuidx(oi);
1655 tcg_insn_unit *label_ptr;
1658 base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 1);
1660 tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
1661 label_ptr = s->code_ptr;
1664 tcg_out_qemu_ld_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
1666 add_qemu_ldst_label(s, 1, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
1669 tcg_target_long disp;
1671 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1672 tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1676 static void tcg_out_qemu_st(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
1679 MemOp opc = get_memop(oi);
1680 #ifdef CONFIG_SOFTMMU
1681 unsigned mem_index = get_mmuidx(oi);
1682 tcg_insn_unit *label_ptr;
1685 base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 0);
1687 tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
1688 label_ptr = s->code_ptr;
1691 tcg_out_qemu_st_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
1693 add_qemu_ldst_label(s, 0, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
1696 tcg_target_long disp;
1698 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1699 tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1703 # define OP_32_64(x) \
1704 case glue(glue(INDEX_op_,x),_i32): \
1705 case glue(glue(INDEX_op_,x),_i64)
1707 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1708 const TCGArg args[TCG_MAX_OP_ARGS],
1709 const int const_args[TCG_MAX_OP_ARGS])
1715 case INDEX_op_exit_tb:
1716 /* Reuse the zeroing that exists for goto_ptr. */
1719 tgen_gotoi(s, S390_CC_ALWAYS, tcg_code_gen_epilogue);
1721 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, a0);
1722 tgen_gotoi(s, S390_CC_ALWAYS, tb_ret_addr);
1726 case INDEX_op_goto_tb:
1728 if (s->tb_jmp_insn_offset) {
1730 * branch displacement must be aligned for atomic patching;
1731 * see if we need to add extra nop before branch
1733 if (!QEMU_PTR_IS_ALIGNED(s->code_ptr + 1, 4)) {
1736 tcg_debug_assert(!USE_REG_TB);
1737 tcg_out16(s, RIL_BRCL | (S390_CC_ALWAYS << 4));
1738 s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
1741 /* load address stored at s->tb_jmp_target_addr + a0 */
1742 tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_REG_TB,
1743 tcg_splitwx_to_rx(s->tb_jmp_target_addr + a0));
1745 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_TB);
1747 set_jmp_reset_offset(s, a0);
1749 /* For the unlinked path of goto_tb, we need to reset
1750 TCG_REG_TB to the beginning of this TB. */
1752 int ofs = -tcg_current_code_size(s);
1753 /* All TB are restricted to 64KiB by unwind info. */
1754 tcg_debug_assert(ofs == sextract64(ofs, 0, 20));
1755 tcg_out_insn(s, RXY, LAY, TCG_REG_TB,
1756 TCG_REG_TB, TCG_REG_NONE, ofs);
1760 case INDEX_op_goto_ptr:
1763 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, a0);
1765 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, a0);
1769 /* ??? LLC (RXY format) is only present with the extended-immediate
1770 facility, whereas LLGC is always present. */
1771 tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
1775 /* ??? LB is no smaller than LGB, so no point to using it. */
1776 tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
1780 /* ??? LLH (RXY format) is only present with the extended-immediate
1781 facility, whereas LLGH is always present. */
1782 tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
1785 case INDEX_op_ld16s_i32:
1786 tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
1789 case INDEX_op_ld_i32:
1790 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1794 tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
1795 TCG_REG_NONE, args[2]);
1799 tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
1800 TCG_REG_NONE, args[2]);
1803 case INDEX_op_st_i32:
1804 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1807 case INDEX_op_add_i32:
1808 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1809 if (const_args[2]) {
1812 if (a2 == (int16_t)a2) {
1813 tcg_out_insn(s, RI, AHI, a0, a2);
1816 if (s390_facilities & FACILITY_EXT_IMM) {
1817 tcg_out_insn(s, RIL, AFI, a0, a2);
1821 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
1822 } else if (a0 == a1) {
1823 tcg_out_insn(s, RR, AR, a0, a2);
1825 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
1828 case INDEX_op_sub_i32:
1829 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1830 if (const_args[2]) {
1833 } else if (a0 == a1) {
1834 tcg_out_insn(s, RR, SR, a0, a2);
1836 tcg_out_insn(s, RRF, SRK, a0, a1, a2);
1840 case INDEX_op_and_i32:
1841 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1842 if (const_args[2]) {
1843 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1844 tgen_andi(s, TCG_TYPE_I32, a0, a2);
1845 } else if (a0 == a1) {
1846 tcg_out_insn(s, RR, NR, a0, a2);
1848 tcg_out_insn(s, RRF, NRK, a0, a1, a2);
1851 case INDEX_op_or_i32:
1852 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1853 if (const_args[2]) {
1854 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1855 tgen_ori(s, TCG_TYPE_I32, a0, a2);
1856 } else if (a0 == a1) {
1857 tcg_out_insn(s, RR, OR, a0, a2);
1859 tcg_out_insn(s, RRF, ORK, a0, a1, a2);
1862 case INDEX_op_xor_i32:
1863 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1864 if (const_args[2]) {
1865 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1866 tgen_xori(s, TCG_TYPE_I32, a0, a2);
1867 } else if (a0 == a1) {
1868 tcg_out_insn(s, RR, XR, args[0], args[2]);
1870 tcg_out_insn(s, RRF, XRK, a0, a1, a2);
1874 case INDEX_op_neg_i32:
1875 tcg_out_insn(s, RR, LCR, args[0], args[1]);
1878 case INDEX_op_mul_i32:
1879 if (const_args[2]) {
1880 if ((int32_t)args[2] == (int16_t)args[2]) {
1881 tcg_out_insn(s, RI, MHI, args[0], args[2]);
1883 tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
1886 tcg_out_insn(s, RRE, MSR, args[0], args[2]);
1890 case INDEX_op_div2_i32:
1891 tcg_out_insn(s, RR, DR, TCG_REG_R2, args[4]);
1893 case INDEX_op_divu2_i32:
1894 tcg_out_insn(s, RRE, DLR, TCG_REG_R2, args[4]);
1897 case INDEX_op_shl_i32:
1901 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1903 if (const_args[2]) {
1904 tcg_out_sh32(s, op, a0, TCG_REG_NONE, a2);
1906 tcg_out_sh32(s, op, a0, a2, 0);
1909 /* Using tcg_out_sh64 here for the format; it is a 32-bit shift. */
1910 if (const_args[2]) {
1911 tcg_out_sh64(s, op2, a0, a1, TCG_REG_NONE, a2);
1913 tcg_out_sh64(s, op2, a0, a1, a2, 0);
1917 case INDEX_op_shr_i32:
1921 case INDEX_op_sar_i32:
1926 case INDEX_op_rotl_i32:
1927 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1928 if (const_args[2]) {
1929 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
1931 tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
1934 case INDEX_op_rotr_i32:
1935 if (const_args[2]) {
1936 tcg_out_sh64(s, RSY_RLL, args[0], args[1],
1937 TCG_REG_NONE, (32 - args[2]) & 31);
1939 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
1940 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
1944 case INDEX_op_ext8s_i32:
1945 tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
1947 case INDEX_op_ext16s_i32:
1948 tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
1950 case INDEX_op_ext8u_i32:
1951 tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
1953 case INDEX_op_ext16u_i32:
1954 tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
1958 /* The TCG bswap definition requires bits 0-47 already be zero.
1959 Thus we don't need the G-type insns to implement bswap16_i64. */
1960 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1961 tcg_out_sh32(s, RS_SRL, args[0], TCG_REG_NONE, 16);
1964 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1967 case INDEX_op_add2_i32:
1968 if (const_args[4]) {
1969 tcg_out_insn(s, RIL, ALFI, args[0], args[4]);
1971 tcg_out_insn(s, RR, ALR, args[0], args[4]);
1973 tcg_out_insn(s, RRE, ALCR, args[1], args[5]);
1975 case INDEX_op_sub2_i32:
1976 if (const_args[4]) {
1977 tcg_out_insn(s, RIL, SLFI, args[0], args[4]);
1979 tcg_out_insn(s, RR, SLR, args[0], args[4]);
1981 tcg_out_insn(s, RRE, SLBR, args[1], args[5]);
1985 tgen_branch(s, S390_CC_ALWAYS, arg_label(args[0]));
1988 case INDEX_op_brcond_i32:
1989 tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
1990 args[1], const_args[1], arg_label(args[3]));
1992 case INDEX_op_setcond_i32:
1993 tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
1994 args[2], const_args[2]);
1996 case INDEX_op_movcond_i32:
1997 tgen_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1],
1998 args[2], const_args[2], args[3], const_args[3]);
2001 case INDEX_op_qemu_ld_i32:
2002 /* ??? Technically we can use a non-extending instruction. */
2003 case INDEX_op_qemu_ld_i64:
2004 tcg_out_qemu_ld(s, args[0], args[1], args[2]);
2006 case INDEX_op_qemu_st_i32:
2007 case INDEX_op_qemu_st_i64:
2008 tcg_out_qemu_st(s, args[0], args[1], args[2]);
2011 case INDEX_op_ld16s_i64:
2012 tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
2014 case INDEX_op_ld32u_i64:
2015 tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
2017 case INDEX_op_ld32s_i64:
2018 tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
2020 case INDEX_op_ld_i64:
2021 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2024 case INDEX_op_st32_i64:
2025 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
2027 case INDEX_op_st_i64:
2028 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2031 case INDEX_op_add_i64:
2032 a0 = args[0], a1 = args[1], a2 = args[2];
2033 if (const_args[2]) {
2036 if (a2 == (int16_t)a2) {
2037 tcg_out_insn(s, RI, AGHI, a0, a2);
2040 if (s390_facilities & FACILITY_EXT_IMM) {
2041 if (a2 == (int32_t)a2) {
2042 tcg_out_insn(s, RIL, AGFI, a0, a2);
2044 } else if (a2 == (uint32_t)a2) {
2045 tcg_out_insn(s, RIL, ALGFI, a0, a2);
2047 } else if (-a2 == (uint32_t)-a2) {
2048 tcg_out_insn(s, RIL, SLGFI, a0, -a2);
2053 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
2054 } else if (a0 == a1) {
2055 tcg_out_insn(s, RRE, AGR, a0, a2);
2057 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
2060 case INDEX_op_sub_i64:
2061 a0 = args[0], a1 = args[1], a2 = args[2];
2062 if (const_args[2]) {
2065 } else if (a0 == a1) {
2066 tcg_out_insn(s, RRE, SGR, a0, a2);
2068 tcg_out_insn(s, RRF, SGRK, a0, a1, a2);
2072 case INDEX_op_and_i64:
2073 a0 = args[0], a1 = args[1], a2 = args[2];
2074 if (const_args[2]) {
2075 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2076 tgen_andi(s, TCG_TYPE_I64, args[0], args[2]);
2077 } else if (a0 == a1) {
2078 tcg_out_insn(s, RRE, NGR, args[0], args[2]);
2080 tcg_out_insn(s, RRF, NGRK, a0, a1, a2);
2083 case INDEX_op_or_i64:
2084 a0 = args[0], a1 = args[1], a2 = args[2];
2085 if (const_args[2]) {
2086 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2087 tgen_ori(s, TCG_TYPE_I64, a0, a2);
2088 } else if (a0 == a1) {
2089 tcg_out_insn(s, RRE, OGR, a0, a2);
2091 tcg_out_insn(s, RRF, OGRK, a0, a1, a2);
2094 case INDEX_op_xor_i64:
2095 a0 = args[0], a1 = args[1], a2 = args[2];
2096 if (const_args[2]) {
2097 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2098 tgen_xori(s, TCG_TYPE_I64, a0, a2);
2099 } else if (a0 == a1) {
2100 tcg_out_insn(s, RRE, XGR, a0, a2);
2102 tcg_out_insn(s, RRF, XGRK, a0, a1, a2);
2106 case INDEX_op_neg_i64:
2107 tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
2109 case INDEX_op_bswap64_i64:
2110 tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
2113 case INDEX_op_mul_i64:
2114 if (const_args[2]) {
2115 if (args[2] == (int16_t)args[2]) {
2116 tcg_out_insn(s, RI, MGHI, args[0], args[2]);
2118 tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
2121 tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
2125 case INDEX_op_div2_i64:
2126 /* ??? We get an unnecessary sign-extension of the dividend
2127 into R3 with this definition, but as we do in fact always
2128 produce both quotient and remainder using INDEX_op_div_i64
2129 instead requires jumping through even more hoops. */
2130 tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
2132 case INDEX_op_divu2_i64:
2133 tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
2135 case INDEX_op_mulu2_i64:
2136 tcg_out_insn(s, RRE, MLGR, TCG_REG_R2, args[3]);
2139 case INDEX_op_shl_i64:
2142 if (const_args[2]) {
2143 tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
2145 tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
2148 case INDEX_op_shr_i64:
2151 case INDEX_op_sar_i64:
2155 case INDEX_op_rotl_i64:
2156 if (const_args[2]) {
2157 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2158 TCG_REG_NONE, args[2]);
2160 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
2163 case INDEX_op_rotr_i64:
2164 if (const_args[2]) {
2165 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2166 TCG_REG_NONE, (64 - args[2]) & 63);
2168 /* We can use the smaller 32-bit negate because only the
2169 low 6 bits are examined for the rotate. */
2170 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2171 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
2175 case INDEX_op_ext8s_i64:
2176 tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
2178 case INDEX_op_ext16s_i64:
2179 tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
2181 case INDEX_op_ext_i32_i64:
2182 case INDEX_op_ext32s_i64:
2183 tgen_ext32s(s, args[0], args[1]);
2185 case INDEX_op_ext8u_i64:
2186 tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
2188 case INDEX_op_ext16u_i64:
2189 tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
2191 case INDEX_op_extu_i32_i64:
2192 case INDEX_op_ext32u_i64:
2193 tgen_ext32u(s, args[0], args[1]);
2196 case INDEX_op_add2_i64:
2197 if (const_args[4]) {
2198 if ((int64_t)args[4] >= 0) {
2199 tcg_out_insn(s, RIL, ALGFI, args[0], args[4]);
2201 tcg_out_insn(s, RIL, SLGFI, args[0], -args[4]);
2204 tcg_out_insn(s, RRE, ALGR, args[0], args[4]);
2206 tcg_out_insn(s, RRE, ALCGR, args[1], args[5]);
2208 case INDEX_op_sub2_i64:
2209 if (const_args[4]) {
2210 if ((int64_t)args[4] >= 0) {
2211 tcg_out_insn(s, RIL, SLGFI, args[0], args[4]);
2213 tcg_out_insn(s, RIL, ALGFI, args[0], -args[4]);
2216 tcg_out_insn(s, RRE, SLGR, args[0], args[4]);
2218 tcg_out_insn(s, RRE, SLBGR, args[1], args[5]);
2221 case INDEX_op_brcond_i64:
2222 tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
2223 args[1], const_args[1], arg_label(args[3]));
2225 case INDEX_op_setcond_i64:
2226 tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2227 args[2], const_args[2]);
2229 case INDEX_op_movcond_i64:
2230 tgen_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1],
2231 args[2], const_args[2], args[3], const_args[3]);
2235 a0 = args[0], a1 = args[1], a2 = args[2];
2236 if (const_args[1]) {
2237 tgen_deposit(s, a0, a2, args[3], args[4], 1);
2239 /* Since we can't support "0Z" as a constraint, we allow a1 in
2240 any register. Fix things up as if a matching constraint. */
2242 TCGType type = (opc == INDEX_op_deposit_i64);
2244 tcg_out_mov(s, type, TCG_TMP0, a2);
2247 tcg_out_mov(s, type, a0, a1);
2249 tgen_deposit(s, a0, a2, args[3], args[4], 0);
2254 tgen_extract(s, args[0], args[1], args[2], args[3]);
2257 case INDEX_op_clz_i64:
2258 tgen_clz(s, args[0], args[1], args[2], const_args[2]);
2262 /* The host memory model is quite strong, we simply need to
2263 serialize the instruction stream. */
2264 if (args[0] & TCG_MO_ST_LD) {
2265 tcg_out_insn(s, RR, BCR,
2266 s390_facilities & FACILITY_FAST_BCR_SER ? 14 : 15, 0);
2270 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
2271 case INDEX_op_mov_i64:
2272 case INDEX_op_call: /* Always emitted via tcg_out_call. */
2278 static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
2281 case INDEX_op_goto_ptr:
2284 case INDEX_op_ld8u_i32:
2285 case INDEX_op_ld8u_i64:
2286 case INDEX_op_ld8s_i32:
2287 case INDEX_op_ld8s_i64:
2288 case INDEX_op_ld16u_i32:
2289 case INDEX_op_ld16u_i64:
2290 case INDEX_op_ld16s_i32:
2291 case INDEX_op_ld16s_i64:
2292 case INDEX_op_ld_i32:
2293 case INDEX_op_ld32u_i64:
2294 case INDEX_op_ld32s_i64:
2295 case INDEX_op_ld_i64:
2296 return C_O1_I1(r, r);
2298 case INDEX_op_st8_i32:
2299 case INDEX_op_st8_i64:
2300 case INDEX_op_st16_i32:
2301 case INDEX_op_st16_i64:
2302 case INDEX_op_st_i32:
2303 case INDEX_op_st32_i64:
2304 case INDEX_op_st_i64:
2305 return C_O0_I2(r, r);
2307 case INDEX_op_add_i32:
2308 case INDEX_op_add_i64:
2309 case INDEX_op_shl_i64:
2310 case INDEX_op_shr_i64:
2311 case INDEX_op_sar_i64:
2312 case INDEX_op_rotl_i32:
2313 case INDEX_op_rotl_i64:
2314 case INDEX_op_rotr_i32:
2315 case INDEX_op_rotr_i64:
2316 case INDEX_op_clz_i64:
2317 case INDEX_op_setcond_i32:
2318 case INDEX_op_setcond_i64:
2319 return C_O1_I2(r, r, ri);
2321 case INDEX_op_sub_i32:
2322 case INDEX_op_sub_i64:
2323 case INDEX_op_and_i32:
2324 case INDEX_op_and_i64:
2325 case INDEX_op_or_i32:
2326 case INDEX_op_or_i64:
2327 case INDEX_op_xor_i32:
2328 case INDEX_op_xor_i64:
2329 return (s390_facilities & FACILITY_DISTINCT_OPS
2331 : C_O1_I2(r, 0, ri));
2333 case INDEX_op_mul_i32:
2334 /* If we have the general-instruction-extensions, then we have
2335 MULTIPLY SINGLE IMMEDIATE with a signed 32-bit, otherwise we
2336 have only MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
2337 return (s390_facilities & FACILITY_GEN_INST_EXT
2339 : C_O1_I2(r, 0, rI));
2341 case INDEX_op_mul_i64:
2342 return (s390_facilities & FACILITY_GEN_INST_EXT
2344 : C_O1_I2(r, 0, rI));
2346 case INDEX_op_shl_i32:
2347 case INDEX_op_shr_i32:
2348 case INDEX_op_sar_i32:
2349 return (s390_facilities & FACILITY_DISTINCT_OPS
2351 : C_O1_I2(r, 0, ri));
2353 case INDEX_op_brcond_i32:
2354 case INDEX_op_brcond_i64:
2355 return C_O0_I2(r, ri);
2357 case INDEX_op_bswap16_i32:
2358 case INDEX_op_bswap16_i64:
2359 case INDEX_op_bswap32_i32:
2360 case INDEX_op_bswap32_i64:
2361 case INDEX_op_bswap64_i64:
2362 case INDEX_op_neg_i32:
2363 case INDEX_op_neg_i64:
2364 case INDEX_op_ext8s_i32:
2365 case INDEX_op_ext8s_i64:
2366 case INDEX_op_ext8u_i32:
2367 case INDEX_op_ext8u_i64:
2368 case INDEX_op_ext16s_i32:
2369 case INDEX_op_ext16s_i64:
2370 case INDEX_op_ext16u_i32:
2371 case INDEX_op_ext16u_i64:
2372 case INDEX_op_ext32s_i64:
2373 case INDEX_op_ext32u_i64:
2374 case INDEX_op_ext_i32_i64:
2375 case INDEX_op_extu_i32_i64:
2376 case INDEX_op_extract_i32:
2377 case INDEX_op_extract_i64:
2378 return C_O1_I1(r, r);
2380 case INDEX_op_qemu_ld_i32:
2381 case INDEX_op_qemu_ld_i64:
2382 return C_O1_I1(r, L);
2383 case INDEX_op_qemu_st_i64:
2384 case INDEX_op_qemu_st_i32:
2385 return C_O0_I2(L, L);
2387 case INDEX_op_deposit_i32:
2388 case INDEX_op_deposit_i64:
2389 return C_O1_I2(r, rZ, r);
2391 case INDEX_op_movcond_i32:
2392 case INDEX_op_movcond_i64:
2393 return (s390_facilities & FACILITY_LOAD_ON_COND2
2394 ? C_O1_I4(r, r, ri, rI, 0)
2395 : C_O1_I4(r, r, ri, r, 0));
2397 case INDEX_op_div2_i32:
2398 case INDEX_op_div2_i64:
2399 case INDEX_op_divu2_i32:
2400 case INDEX_op_divu2_i64:
2401 return C_O2_I3(b, a, 0, 1, r);
2403 case INDEX_op_mulu2_i64:
2404 return C_O2_I2(b, a, 0, r);
2406 case INDEX_op_add2_i32:
2407 case INDEX_op_sub2_i32:
2408 return (s390_facilities & FACILITY_EXT_IMM
2409 ? C_O2_I4(r, r, 0, 1, ri, r)
2410 : C_O2_I4(r, r, 0, 1, r, r));
2412 case INDEX_op_add2_i64:
2413 case INDEX_op_sub2_i64:
2414 return (s390_facilities & FACILITY_EXT_IMM
2415 ? C_O2_I4(r, r, 0, 1, rA, r)
2416 : C_O2_I4(r, r, 0, 1, r, r));
2419 g_assert_not_reached();
2423 static void query_s390_facilities(void)
2425 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2427 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
2428 is present on all 64-bit systems, but let's check for it anyway. */
2429 if (hwcap & HWCAP_S390_STFLE) {
2430 register int r0 __asm__("0");
2431 register void *r1 __asm__("1");
2434 r1 = &s390_facilities;
2435 asm volatile(".word 0xb2b0,0x1000"
2436 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
2440 static void tcg_target_init(TCGContext *s)
2442 query_s390_facilities();
2444 tcg_target_available_regs[TCG_TYPE_I32] = 0xffff;
2445 tcg_target_available_regs[TCG_TYPE_I64] = 0xffff;
2447 tcg_target_call_clobber_regs = 0;
2448 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2449 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
2450 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2451 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2452 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
2453 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
2454 /* The r6 register is technically call-saved, but it's also a parameter
2455 register, so it can get killed by setup for the qemu_st helper. */
2456 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6);
2457 /* The return register can be considered call-clobbered. */
2458 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2460 s->reserved_regs = 0;
2461 tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
2462 /* XXX many insns can't be used with R0, so we better avoid it for now */
2463 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
2464 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2466 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB);
2470 #define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
2471 + TCG_STATIC_CALL_ARGS_SIZE \
2472 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
2474 static void tcg_target_qemu_prologue(TCGContext *s)
2476 /* stmg %r6,%r15,48(%r15) (save registers) */
2477 tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
2479 /* aghi %r15,-frame_size */
2480 tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -FRAME_SIZE);
2482 tcg_set_frame(s, TCG_REG_CALL_STACK,
2483 TCG_STATIC_CALL_ARGS_SIZE + TCG_TARGET_CALL_STACK_OFFSET,
2484 CPU_TEMP_BUF_NLONGS * sizeof(long));
2486 #ifndef CONFIG_SOFTMMU
2487 if (guest_base >= 0x80000) {
2488 tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base, true);
2489 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2493 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2495 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB,
2496 tcg_target_call_iarg_regs[1]);
2499 /* br %r3 (go to TB) */
2500 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
2503 * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2504 * and fall through to the rest of the epilogue.
2506 tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
2507 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, 0);
2510 tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
2512 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2513 tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15,
2516 /* br %r14 (return) */
2517 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
2520 static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
2522 memset(p, 0x07, count * sizeof(tcg_insn_unit));
2527 uint8_t fde_def_cfa[4];
2528 uint8_t fde_reg_ofs[18];
2531 /* We're expecting a 2 byte uleb128 encoded value. */
2532 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2534 #define ELF_HOST_MACHINE EM_S390
2536 static const DebugFrame debug_frame = {
2537 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2540 .h.cie.code_align = 1,
2541 .h.cie.data_align = 8, /* sleb128 8 */
2542 .h.cie.return_column = TCG_REG_R14,
2544 /* Total FDE size does not include the "len" member. */
2545 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
2548 12, TCG_REG_CALL_STACK, /* DW_CFA_def_cfa %r15, ... */
2549 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2553 0x86, 6, /* DW_CFA_offset, %r6, 48 */
2554 0x87, 7, /* DW_CFA_offset, %r7, 56 */
2555 0x88, 8, /* DW_CFA_offset, %r8, 64 */
2556 0x89, 9, /* DW_CFA_offset, %r92, 72 */
2557 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
2558 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
2559 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
2560 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
2561 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
2565 void tcg_register_jit(const void *buf, size_t buf_size)
2567 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));