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.inc.c"
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 /* Several places within the instruction set 0 means "no register"
46 rather than TCG_REG_R0. */
47 #define TCG_REG_NONE 0
49 /* A scratch register that may be be used throughout the backend. */
50 #define TCG_TMP0 TCG_REG_R1
52 /* A scratch register that holds a pointer to the beginning of the TB.
53 We don't need this when we have pc-relative loads with the general
54 instructions extension facility. */
55 #define TCG_REG_TB TCG_REG_R12
56 #define USE_REG_TB (!(s390_facilities & FACILITY_GEN_INST_EXT))
58 #ifndef CONFIG_SOFTMMU
59 #define TCG_GUEST_BASE_REG TCG_REG_R13
62 /* All of the following instructions are prefixed with their instruction
63 format, and are defined as 8- or 16-bit quantities, even when the two
64 halves of the 16-bit quantity may appear 32 bits apart in the insn.
65 This makes it easy to copy the values from the tables in Appendix B. */
66 typedef enum S390Opcode
{
256 #ifdef CONFIG_DEBUG_TCG
257 static const char * const tcg_target_reg_names
[TCG_TARGET_NB_REGS
] = {
258 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
259 "%r8", "%r9", "%r10" "%r11" "%r12" "%r13" "%r14" "%r15"
263 /* Since R6 is a potential argument register, choose it last of the
264 call-saved registers. Likewise prefer the call-clobbered registers
265 in reverse order to maximize the chance of avoiding the arguments. */
266 static const int tcg_target_reg_alloc_order
[] = {
267 /* Call saved registers. */
276 /* Call clobbered registers. */
280 /* Argument registers, in reverse order of allocation. */
287 static const int tcg_target_call_iarg_regs
[] = {
295 static const int tcg_target_call_oarg_regs
[] = {
303 #define S390_CC_NE (S390_CC_LT | S390_CC_GT)
304 #define S390_CC_LE (S390_CC_LT | S390_CC_EQ)
305 #define S390_CC_GE (S390_CC_GT | S390_CC_EQ)
306 #define S390_CC_NEVER 0
307 #define S390_CC_ALWAYS 15
309 /* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
310 static const uint8_t tcg_cond_to_s390_cond
[] = {
311 [TCG_COND_EQ
] = S390_CC_EQ
,
312 [TCG_COND_NE
] = S390_CC_NE
,
313 [TCG_COND_LT
] = S390_CC_LT
,
314 [TCG_COND_LE
] = S390_CC_LE
,
315 [TCG_COND_GT
] = S390_CC_GT
,
316 [TCG_COND_GE
] = S390_CC_GE
,
317 [TCG_COND_LTU
] = S390_CC_LT
,
318 [TCG_COND_LEU
] = S390_CC_LE
,
319 [TCG_COND_GTU
] = S390_CC_GT
,
320 [TCG_COND_GEU
] = S390_CC_GE
,
323 /* Condition codes that result from a LOAD AND TEST. Here, we have no
324 unsigned instruction variation, however since the test is vs zero we
325 can re-map the outcomes appropriately. */
326 static const uint8_t tcg_cond_to_ltr_cond
[] = {
327 [TCG_COND_EQ
] = S390_CC_EQ
,
328 [TCG_COND_NE
] = S390_CC_NE
,
329 [TCG_COND_LT
] = S390_CC_LT
,
330 [TCG_COND_LE
] = S390_CC_LE
,
331 [TCG_COND_GT
] = S390_CC_GT
,
332 [TCG_COND_GE
] = S390_CC_GE
,
333 [TCG_COND_LTU
] = S390_CC_NEVER
,
334 [TCG_COND_LEU
] = S390_CC_EQ
,
335 [TCG_COND_GTU
] = S390_CC_NE
,
336 [TCG_COND_GEU
] = S390_CC_ALWAYS
,
339 #ifdef CONFIG_SOFTMMU
340 static void * const qemu_ld_helpers
[16] = {
341 [MO_UB
] = helper_ret_ldub_mmu
,
342 [MO_SB
] = helper_ret_ldsb_mmu
,
343 [MO_LEUW
] = helper_le_lduw_mmu
,
344 [MO_LESW
] = helper_le_ldsw_mmu
,
345 [MO_LEUL
] = helper_le_ldul_mmu
,
346 [MO_LESL
] = helper_le_ldsl_mmu
,
347 [MO_LEQ
] = helper_le_ldq_mmu
,
348 [MO_BEUW
] = helper_be_lduw_mmu
,
349 [MO_BESW
] = helper_be_ldsw_mmu
,
350 [MO_BEUL
] = helper_be_ldul_mmu
,
351 [MO_BESL
] = helper_be_ldsl_mmu
,
352 [MO_BEQ
] = helper_be_ldq_mmu
,
355 static void * const qemu_st_helpers
[16] = {
356 [MO_UB
] = helper_ret_stb_mmu
,
357 [MO_LEUW
] = helper_le_stw_mmu
,
358 [MO_LEUL
] = helper_le_stl_mmu
,
359 [MO_LEQ
] = helper_le_stq_mmu
,
360 [MO_BEUW
] = helper_be_stw_mmu
,
361 [MO_BEUL
] = helper_be_stl_mmu
,
362 [MO_BEQ
] = helper_be_stq_mmu
,
366 static tcg_insn_unit
*tb_ret_addr
;
367 uint64_t s390_facilities
;
369 static bool patch_reloc(tcg_insn_unit
*code_ptr
, int type
,
370 intptr_t value
, intptr_t addend
)
376 pcrel2
= (tcg_insn_unit
*)value
- code_ptr
;
380 assert(pcrel2
== (int16_t)pcrel2
);
381 tcg_patch16(code_ptr
, pcrel2
);
384 assert(pcrel2
== (int32_t)pcrel2
);
385 tcg_patch32(code_ptr
, pcrel2
);
388 assert(value
== sextract64(value
, 0, 20));
389 old
= *(uint32_t *)code_ptr
& 0xf00000ff;
390 old
|= ((value
& 0xfff) << 16) | ((value
& 0xff000) >> 4);
391 tcg_patch32(code_ptr
, old
);
394 g_assert_not_reached();
399 /* parse target specific constraints */
400 static const char *target_parse_constraint(TCGArgConstraint
*ct
,
401 const char *ct_str
, TCGType type
)
404 case 'r': /* all registers */
405 ct
->ct
|= TCG_CT_REG
;
408 case 'L': /* qemu_ld/st constraint */
409 ct
->ct
|= TCG_CT_REG
;
411 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_R2
);
412 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_R3
);
413 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_R4
);
415 case 'a': /* force R2 for division */
416 ct
->ct
|= TCG_CT_REG
;
418 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_R2
);
420 case 'b': /* force R3 for division */
421 ct
->ct
|= TCG_CT_REG
;
423 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_R3
);
426 ct
->ct
|= TCG_CT_CONST_S33
;
429 ct
->ct
|= TCG_CT_CONST_S16
;
432 ct
->ct
|= TCG_CT_CONST_S32
;
435 ct
->ct
|= TCG_CT_CONST_ZERO
;
443 /* Test if a constant matches the constraint. */
444 static int tcg_target_const_match(tcg_target_long val
, TCGType type
,
445 const TCGArgConstraint
*arg_ct
)
449 if (ct
& TCG_CT_CONST
) {
453 if (type
== TCG_TYPE_I32
) {
457 /* The following are mutually exclusive. */
458 if (ct
& TCG_CT_CONST_S16
) {
459 return val
== (int16_t)val
;
460 } else if (ct
& TCG_CT_CONST_S32
) {
461 return val
== (int32_t)val
;
462 } else if (ct
& TCG_CT_CONST_S33
) {
463 return val
>= -0xffffffffll
&& val
<= 0xffffffffll
;
464 } else if (ct
& TCG_CT_CONST_ZERO
) {
471 /* Emit instructions according to the given instruction format. */
473 static void tcg_out_insn_RR(TCGContext
*s
, S390Opcode op
, TCGReg r1
, TCGReg r2
)
475 tcg_out16(s
, (op
<< 8) | (r1
<< 4) | r2
);
478 static void tcg_out_insn_RRE(TCGContext
*s
, S390Opcode op
,
479 TCGReg r1
, TCGReg r2
)
481 tcg_out32(s
, (op
<< 16) | (r1
<< 4) | r2
);
484 static void tcg_out_insn_RRF(TCGContext
*s
, S390Opcode op
,
485 TCGReg r1
, TCGReg r2
, int m3
)
487 tcg_out32(s
, (op
<< 16) | (m3
<< 12) | (r1
<< 4) | r2
);
490 static void tcg_out_insn_RI(TCGContext
*s
, S390Opcode op
, TCGReg r1
, int i2
)
492 tcg_out32(s
, (op
<< 16) | (r1
<< 20) | (i2
& 0xffff));
495 static void tcg_out_insn_RIE(TCGContext
*s
, S390Opcode op
, TCGReg r1
,
498 tcg_out16(s
, (op
& 0xff00) | (r1
<< 4) | m3
);
499 tcg_out32(s
, (i2
<< 16) | (op
& 0xff));
502 static void tcg_out_insn_RIL(TCGContext
*s
, S390Opcode op
, TCGReg r1
, int i2
)
504 tcg_out16(s
, op
| (r1
<< 4));
508 static void tcg_out_insn_RS(TCGContext
*s
, S390Opcode op
, TCGReg r1
,
509 TCGReg b2
, TCGReg r3
, int disp
)
511 tcg_out32(s
, (op
<< 24) | (r1
<< 20) | (r3
<< 16) | (b2
<< 12)
515 static void tcg_out_insn_RSY(TCGContext
*s
, S390Opcode op
, TCGReg r1
,
516 TCGReg b2
, TCGReg r3
, int disp
)
518 tcg_out16(s
, (op
& 0xff00) | (r1
<< 4) | r3
);
519 tcg_out32(s
, (op
& 0xff) | (b2
<< 28)
520 | ((disp
& 0xfff) << 16) | ((disp
& 0xff000) >> 4));
523 #define tcg_out_insn_RX tcg_out_insn_RS
524 #define tcg_out_insn_RXY tcg_out_insn_RSY
526 /* Emit an opcode with "type-checking" of the format. */
527 #define tcg_out_insn(S, FMT, OP, ...) \
528 glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
531 /* emit 64-bit shifts */
532 static void tcg_out_sh64(TCGContext
* s
, S390Opcode op
, TCGReg dest
,
533 TCGReg src
, TCGReg sh_reg
, int sh_imm
)
535 tcg_out_insn_RSY(s
, op
, dest
, sh_reg
, src
, sh_imm
);
538 /* emit 32-bit shifts */
539 static void tcg_out_sh32(TCGContext
* s
, S390Opcode op
, TCGReg dest
,
540 TCGReg sh_reg
, int sh_imm
)
542 tcg_out_insn_RS(s
, op
, dest
, sh_reg
, 0, sh_imm
);
545 static void tcg_out_mov(TCGContext
*s
, TCGType type
, TCGReg dst
, TCGReg src
)
548 if (type
== TCG_TYPE_I32
) {
549 tcg_out_insn(s
, RR
, LR
, dst
, src
);
551 tcg_out_insn(s
, RRE
, LGR
, dst
, src
);
556 static const S390Opcode lli_insns
[4] = {
557 RI_LLILL
, RI_LLILH
, RI_LLIHL
, RI_LLIHH
560 static bool maybe_out_small_movi(TCGContext
*s
, TCGType type
,
561 TCGReg ret
, tcg_target_long sval
)
563 tcg_target_ulong uval
= sval
;
566 if (type
== TCG_TYPE_I32
) {
567 uval
= (uint32_t)sval
;
568 sval
= (int32_t)sval
;
571 /* Try all 32-bit insns that can load it in one go. */
572 if (sval
>= -0x8000 && sval
< 0x8000) {
573 tcg_out_insn(s
, RI
, LGHI
, ret
, sval
);
577 for (i
= 0; i
< 4; i
++) {
578 tcg_target_long mask
= 0xffffull
<< i
*16;
579 if ((uval
& mask
) == uval
) {
580 tcg_out_insn_RI(s
, lli_insns
[i
], ret
, uval
>> i
*16);
588 /* load a register with an immediate value */
589 static void tcg_out_movi_int(TCGContext
*s
, TCGType type
, TCGReg ret
,
590 tcg_target_long sval
, bool in_prologue
)
592 tcg_target_ulong uval
;
594 /* Try all 32-bit insns that can load it in one go. */
595 if (maybe_out_small_movi(s
, type
, ret
, sval
)) {
600 if (type
== TCG_TYPE_I32
) {
601 uval
= (uint32_t)sval
;
602 sval
= (int32_t)sval
;
605 /* Try all 48-bit insns that can load it in one go. */
606 if (s390_facilities
& FACILITY_EXT_IMM
) {
607 if (sval
== (int32_t)sval
) {
608 tcg_out_insn(s
, RIL
, LGFI
, ret
, sval
);
611 if (uval
<= 0xffffffff) {
612 tcg_out_insn(s
, RIL
, LLILF
, ret
, uval
);
615 if ((uval
& 0xffffffff) == 0) {
616 tcg_out_insn(s
, RIL
, LLIHF
, ret
, uval
>> 32);
621 /* Try for PC-relative address load. For odd addresses,
622 attempt to use an offset from the start of the TB. */
623 if ((sval
& 1) == 0) {
624 ptrdiff_t off
= tcg_pcrel_diff(s
, (void *)sval
) >> 1;
625 if (off
== (int32_t)off
) {
626 tcg_out_insn(s
, RIL
, LARL
, ret
, off
);
629 } else if (USE_REG_TB
&& !in_prologue
) {
630 ptrdiff_t off
= sval
- (uintptr_t)s
->code_gen_ptr
;
631 if (off
== sextract64(off
, 0, 20)) {
632 /* This is certain to be an address within TB, and therefore
633 OFF will be negative; don't try RX_LA. */
634 tcg_out_insn(s
, RXY
, LAY
, ret
, TCG_REG_TB
, TCG_REG_NONE
, off
);
639 /* A 32-bit unsigned value can be loaded in 2 insns. And given
640 that LLILL, LLIHL, LLILF above did not succeed, we know that
641 both insns are required. */
642 if (uval
<= 0xffffffff) {
643 tcg_out_insn(s
, RI
, LLILL
, ret
, uval
);
644 tcg_out_insn(s
, RI
, IILH
, ret
, uval
>> 16);
648 /* Otherwise, stuff it in the constant pool. */
649 if (s390_facilities
& FACILITY_GEN_INST_EXT
) {
650 tcg_out_insn(s
, RIL
, LGRL
, ret
, 0);
651 new_pool_label(s
, sval
, R_390_PC32DBL
, s
->code_ptr
- 2, 2);
652 } else if (USE_REG_TB
&& !in_prologue
) {
653 tcg_out_insn(s
, RXY
, LG
, ret
, TCG_REG_TB
, TCG_REG_NONE
, 0);
654 new_pool_label(s
, sval
, R_390_20
, s
->code_ptr
- 2,
655 -(intptr_t)s
->code_gen_ptr
);
657 TCGReg base
= ret
? ret
: TCG_TMP0
;
658 tcg_out_insn(s
, RIL
, LARL
, base
, 0);
659 new_pool_label(s
, sval
, R_390_PC32DBL
, s
->code_ptr
- 2, 2);
660 tcg_out_insn(s
, RXY
, LG
, ret
, base
, TCG_REG_NONE
, 0);
664 static void tcg_out_movi(TCGContext
*s
, TCGType type
,
665 TCGReg ret
, tcg_target_long sval
)
667 tcg_out_movi_int(s
, type
, ret
, sval
, false);
670 /* Emit a load/store type instruction. Inputs are:
671 DATA: The register to be loaded or stored.
672 BASE+OFS: The effective address.
673 OPC_RX: If the operation has an RX format opcode (e.g. STC), otherwise 0.
674 OPC_RXY: The RXY format opcode for the operation (e.g. STCY). */
676 static void tcg_out_mem(TCGContext
*s
, S390Opcode opc_rx
, S390Opcode opc_rxy
,
677 TCGReg data
, TCGReg base
, TCGReg index
,
680 if (ofs
< -0x80000 || ofs
>= 0x80000) {
681 /* Combine the low 20 bits of the offset with the actual load insn;
682 the high 44 bits must come from an immediate load. */
683 tcg_target_long low
= ((ofs
& 0xfffff) ^ 0x80000) - 0x80000;
684 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_TMP0
, ofs
- low
);
687 /* If we were already given an index register, add it in. */
688 if (index
!= TCG_REG_NONE
) {
689 tcg_out_insn(s
, RRE
, AGR
, TCG_TMP0
, index
);
694 if (opc_rx
&& ofs
>= 0 && ofs
< 0x1000) {
695 tcg_out_insn_RX(s
, opc_rx
, data
, base
, index
, ofs
);
697 tcg_out_insn_RXY(s
, opc_rxy
, data
, base
, index
, ofs
);
702 /* load data without address translation or endianness conversion */
703 static inline void tcg_out_ld(TCGContext
*s
, TCGType type
, TCGReg data
,
704 TCGReg base
, intptr_t ofs
)
706 if (type
== TCG_TYPE_I32
) {
707 tcg_out_mem(s
, RX_L
, RXY_LY
, data
, base
, TCG_REG_NONE
, ofs
);
709 tcg_out_mem(s
, 0, RXY_LG
, data
, base
, TCG_REG_NONE
, ofs
);
713 static inline void tcg_out_st(TCGContext
*s
, TCGType type
, TCGReg data
,
714 TCGReg base
, intptr_t ofs
)
716 if (type
== TCG_TYPE_I32
) {
717 tcg_out_mem(s
, RX_ST
, RXY_STY
, data
, base
, TCG_REG_NONE
, ofs
);
719 tcg_out_mem(s
, 0, RXY_STG
, data
, base
, TCG_REG_NONE
, ofs
);
723 static inline bool tcg_out_sti(TCGContext
*s
, TCGType type
, TCGArg val
,
724 TCGReg base
, intptr_t ofs
)
729 /* load data from an absolute host address */
730 static void tcg_out_ld_abs(TCGContext
*s
, TCGType type
, TCGReg dest
, void *abs
)
732 intptr_t addr
= (intptr_t)abs
;
734 if ((s390_facilities
& FACILITY_GEN_INST_EXT
) && !(addr
& 1)) {
735 ptrdiff_t disp
= tcg_pcrel_diff(s
, abs
) >> 1;
736 if (disp
== (int32_t)disp
) {
737 if (type
== TCG_TYPE_I32
) {
738 tcg_out_insn(s
, RIL
, LRL
, dest
, disp
);
740 tcg_out_insn(s
, RIL
, LGRL
, dest
, disp
);
746 ptrdiff_t disp
= abs
- (void *)s
->code_gen_ptr
;
747 if (disp
== sextract64(disp
, 0, 20)) {
748 tcg_out_ld(s
, type
, dest
, TCG_REG_TB
, disp
);
753 tcg_out_movi(s
, TCG_TYPE_PTR
, dest
, addr
& ~0xffff);
754 tcg_out_ld(s
, type
, dest
, dest
, addr
& 0xffff);
757 static inline void tcg_out_risbg(TCGContext
*s
, TCGReg dest
, TCGReg src
,
758 int msb
, int lsb
, int ofs
, int z
)
761 tcg_out16(s
, (RIE_RISBG
& 0xff00) | (dest
<< 4) | src
);
762 tcg_out16(s
, (msb
<< 8) | (z
<< 7) | lsb
);
763 tcg_out16(s
, (ofs
<< 8) | (RIE_RISBG
& 0xff));
766 static void tgen_ext8s(TCGContext
*s
, TCGType type
, TCGReg dest
, TCGReg src
)
768 if (s390_facilities
& FACILITY_EXT_IMM
) {
769 tcg_out_insn(s
, RRE
, LGBR
, dest
, src
);
773 if (type
== TCG_TYPE_I32
) {
775 tcg_out_sh32(s
, RS_SLL
, dest
, TCG_REG_NONE
, 24);
777 tcg_out_sh64(s
, RSY_SLLG
, dest
, src
, TCG_REG_NONE
, 24);
779 tcg_out_sh32(s
, RS_SRA
, dest
, TCG_REG_NONE
, 24);
781 tcg_out_sh64(s
, RSY_SLLG
, dest
, src
, TCG_REG_NONE
, 56);
782 tcg_out_sh64(s
, RSY_SRAG
, dest
, dest
, TCG_REG_NONE
, 56);
786 static void tgen_ext8u(TCGContext
*s
, TCGType type
, TCGReg dest
, TCGReg src
)
788 if (s390_facilities
& FACILITY_EXT_IMM
) {
789 tcg_out_insn(s
, RRE
, LLGCR
, dest
, src
);
794 tcg_out_movi(s
, type
, TCG_TMP0
, 0xff);
797 tcg_out_movi(s
, type
, dest
, 0xff);
799 if (type
== TCG_TYPE_I32
) {
800 tcg_out_insn(s
, RR
, NR
, dest
, src
);
802 tcg_out_insn(s
, RRE
, NGR
, dest
, src
);
806 static void tgen_ext16s(TCGContext
*s
, TCGType type
, TCGReg dest
, TCGReg src
)
808 if (s390_facilities
& FACILITY_EXT_IMM
) {
809 tcg_out_insn(s
, RRE
, LGHR
, dest
, src
);
813 if (type
== TCG_TYPE_I32
) {
815 tcg_out_sh32(s
, RS_SLL
, dest
, TCG_REG_NONE
, 16);
817 tcg_out_sh64(s
, RSY_SLLG
, dest
, src
, TCG_REG_NONE
, 16);
819 tcg_out_sh32(s
, RS_SRA
, dest
, TCG_REG_NONE
, 16);
821 tcg_out_sh64(s
, RSY_SLLG
, dest
, src
, TCG_REG_NONE
, 48);
822 tcg_out_sh64(s
, RSY_SRAG
, dest
, dest
, TCG_REG_NONE
, 48);
826 static void tgen_ext16u(TCGContext
*s
, TCGType type
, TCGReg dest
, TCGReg src
)
828 if (s390_facilities
& FACILITY_EXT_IMM
) {
829 tcg_out_insn(s
, RRE
, LLGHR
, dest
, src
);
834 tcg_out_movi(s
, type
, TCG_TMP0
, 0xffff);
837 tcg_out_movi(s
, type
, dest
, 0xffff);
839 if (type
== TCG_TYPE_I32
) {
840 tcg_out_insn(s
, RR
, NR
, dest
, src
);
842 tcg_out_insn(s
, RRE
, NGR
, dest
, src
);
846 static inline void tgen_ext32s(TCGContext
*s
, TCGReg dest
, TCGReg src
)
848 tcg_out_insn(s
, RRE
, LGFR
, dest
, src
);
851 static inline void tgen_ext32u(TCGContext
*s
, TCGReg dest
, TCGReg src
)
853 tcg_out_insn(s
, RRE
, LLGFR
, dest
, src
);
856 /* Accept bit patterns like these:
861 Copied from gcc sources. */
862 static inline bool risbg_mask(uint64_t c
)
865 /* We don't change the number of transitions by inverting,
866 so make sure we start with the LSB zero. */
870 /* Reject all zeros or all ones. */
874 /* Find the first transition. */
876 /* Invert to look for a second transition. */
878 /* Erase the first transition. */
880 /* Find the second transition, if any. */
882 /* Match if all the bits are 1's, or if c is zero. */
886 static void tgen_andi_risbg(TCGContext
*s
, TCGReg out
, TCGReg in
, uint64_t val
)
889 if ((val
& 0x8000000000000001ull
) == 0x8000000000000001ull
) {
890 /* Achieve wraparound by swapping msb and lsb. */
891 msb
= 64 - ctz64(~val
);
892 lsb
= clz64(~val
) - 1;
895 lsb
= 63 - ctz64(val
);
897 tcg_out_risbg(s
, out
, in
, msb
, lsb
, 0, 1);
900 static void tgen_andi(TCGContext
*s
, TCGType type
, TCGReg dest
, uint64_t val
)
902 static const S390Opcode ni_insns
[4] = {
903 RI_NILL
, RI_NILH
, RI_NIHL
, RI_NIHH
905 static const S390Opcode nif_insns
[2] = {
908 uint64_t valid
= (type
== TCG_TYPE_I32
? 0xffffffffull
: -1ull);
911 /* Look for the zero-extensions. */
912 if ((val
& valid
) == 0xffffffff) {
913 tgen_ext32u(s
, dest
, dest
);
916 if (s390_facilities
& FACILITY_EXT_IMM
) {
917 if ((val
& valid
) == 0xff) {
918 tgen_ext8u(s
, TCG_TYPE_I64
, dest
, dest
);
921 if ((val
& valid
) == 0xffff) {
922 tgen_ext16u(s
, TCG_TYPE_I64
, dest
, dest
);
927 /* Try all 32-bit insns that can perform it in one go. */
928 for (i
= 0; i
< 4; i
++) {
929 tcg_target_ulong mask
= ~(0xffffull
<< i
*16);
930 if (((val
| ~valid
) & mask
) == mask
) {
931 tcg_out_insn_RI(s
, ni_insns
[i
], dest
, val
>> i
*16);
936 /* Try all 48-bit insns that can perform it in one go. */
937 if (s390_facilities
& FACILITY_EXT_IMM
) {
938 for (i
= 0; i
< 2; i
++) {
939 tcg_target_ulong mask
= ~(0xffffffffull
<< i
*32);
940 if (((val
| ~valid
) & mask
) == mask
) {
941 tcg_out_insn_RIL(s
, nif_insns
[i
], dest
, val
>> i
*32);
946 if ((s390_facilities
& FACILITY_GEN_INST_EXT
) && risbg_mask(val
)) {
947 tgen_andi_risbg(s
, dest
, dest
, val
);
951 /* Use the constant pool if USE_REG_TB, but not for small constants. */
953 if (!maybe_out_small_movi(s
, type
, TCG_TMP0
, val
)) {
954 tcg_out_insn(s
, RXY
, NG
, dest
, TCG_REG_TB
, TCG_REG_NONE
, 0);
955 new_pool_label(s
, val
& valid
, R_390_20
, s
->code_ptr
- 2,
956 -(intptr_t)s
->code_gen_ptr
);
960 tcg_out_movi(s
, type
, TCG_TMP0
, val
);
962 if (type
== TCG_TYPE_I32
) {
963 tcg_out_insn(s
, RR
, NR
, dest
, TCG_TMP0
);
965 tcg_out_insn(s
, RRE
, NGR
, dest
, TCG_TMP0
);
969 static void tgen_ori(TCGContext
*s
, TCGType type
, TCGReg dest
, uint64_t val
)
971 static const S390Opcode oi_insns
[4] = {
972 RI_OILL
, RI_OILH
, RI_OIHL
, RI_OIHH
974 static const S390Opcode oif_insns
[2] = {
980 /* Look for no-op. */
981 if (unlikely(val
== 0)) {
985 /* Try all 32-bit insns that can perform it in one go. */
986 for (i
= 0; i
< 4; i
++) {
987 tcg_target_ulong mask
= (0xffffull
<< i
*16);
988 if ((val
& mask
) != 0 && (val
& ~mask
) == 0) {
989 tcg_out_insn_RI(s
, oi_insns
[i
], dest
, val
>> i
*16);
994 /* Try all 48-bit insns that can perform it in one go. */
995 if (s390_facilities
& FACILITY_EXT_IMM
) {
996 for (i
= 0; i
< 2; i
++) {
997 tcg_target_ulong mask
= (0xffffffffull
<< i
*32);
998 if ((val
& mask
) != 0 && (val
& ~mask
) == 0) {
999 tcg_out_insn_RIL(s
, oif_insns
[i
], dest
, val
>> i
*32);
1005 /* Use the constant pool if USE_REG_TB, but not for small constants. */
1006 if (maybe_out_small_movi(s
, type
, TCG_TMP0
, val
)) {
1007 if (type
== TCG_TYPE_I32
) {
1008 tcg_out_insn(s
, RR
, OR
, dest
, TCG_TMP0
);
1010 tcg_out_insn(s
, RRE
, OGR
, dest
, TCG_TMP0
);
1012 } else if (USE_REG_TB
) {
1013 tcg_out_insn(s
, RXY
, OG
, dest
, TCG_REG_TB
, TCG_REG_NONE
, 0);
1014 new_pool_label(s
, val
, R_390_20
, s
->code_ptr
- 2,
1015 -(intptr_t)s
->code_gen_ptr
);
1017 /* Perform the OR via sequential modifications to the high and
1018 low parts. Do this via recursion to handle 16-bit vs 32-bit
1019 masks in each half. */
1020 tcg_debug_assert(s390_facilities
& FACILITY_EXT_IMM
);
1021 tgen_ori(s
, type
, dest
, val
& 0x00000000ffffffffull
);
1022 tgen_ori(s
, type
, dest
, val
& 0xffffffff00000000ull
);
1026 static void tgen_xori(TCGContext
*s
, TCGType type
, TCGReg dest
, uint64_t val
)
1028 /* Try all 48-bit insns that can perform it in one go. */
1029 if (s390_facilities
& FACILITY_EXT_IMM
) {
1030 if ((val
& 0xffffffff00000000ull
) == 0) {
1031 tcg_out_insn(s
, RIL
, XILF
, dest
, val
);
1034 if ((val
& 0x00000000ffffffffull
) == 0) {
1035 tcg_out_insn(s
, RIL
, XIHF
, dest
, val
>> 32);
1040 /* Use the constant pool if USE_REG_TB, but not for small constants. */
1041 if (maybe_out_small_movi(s
, type
, TCG_TMP0
, val
)) {
1042 if (type
== TCG_TYPE_I32
) {
1043 tcg_out_insn(s
, RR
, XR
, dest
, TCG_TMP0
);
1045 tcg_out_insn(s
, RRE
, XGR
, dest
, TCG_TMP0
);
1047 } else if (USE_REG_TB
) {
1048 tcg_out_insn(s
, RXY
, XG
, dest
, TCG_REG_TB
, TCG_REG_NONE
, 0);
1049 new_pool_label(s
, val
, R_390_20
, s
->code_ptr
- 2,
1050 -(intptr_t)s
->code_gen_ptr
);
1052 /* Perform the xor by parts. */
1053 tcg_debug_assert(s390_facilities
& FACILITY_EXT_IMM
);
1054 if (val
& 0xffffffff) {
1055 tcg_out_insn(s
, RIL
, XILF
, dest
, val
);
1057 if (val
> 0xffffffff) {
1058 tcg_out_insn(s
, RIL
, XIHF
, dest
, val
>> 32);
1063 static int tgen_cmp(TCGContext
*s
, TCGType type
, TCGCond c
, TCGReg r1
,
1064 TCGArg c2
, bool c2const
, bool need_carry
)
1066 bool is_unsigned
= is_unsigned_cond(c
);
1071 if (!(is_unsigned
&& need_carry
)) {
1072 if (type
== TCG_TYPE_I32
) {
1073 tcg_out_insn(s
, RR
, LTR
, r1
, r1
);
1075 tcg_out_insn(s
, RRE
, LTGR
, r1
, r1
);
1077 return tcg_cond_to_ltr_cond
[c
];
1081 if (!is_unsigned
&& c2
== (int16_t)c2
) {
1082 op
= (type
== TCG_TYPE_I32
? RI_CHI
: RI_CGHI
);
1083 tcg_out_insn_RI(s
, op
, r1
, c2
);
1087 if (s390_facilities
& FACILITY_EXT_IMM
) {
1088 if (type
== TCG_TYPE_I32
) {
1089 op
= (is_unsigned
? RIL_CLFI
: RIL_CFI
);
1090 tcg_out_insn_RIL(s
, op
, r1
, c2
);
1092 } else if (c2
== (is_unsigned
? (uint32_t)c2
: (int32_t)c2
)) {
1093 op
= (is_unsigned
? RIL_CLGFI
: RIL_CGFI
);
1094 tcg_out_insn_RIL(s
, op
, r1
, c2
);
1099 /* Use the constant pool, but not for small constants. */
1100 if (maybe_out_small_movi(s
, type
, TCG_TMP0
, c2
)) {
1102 /* fall through to reg-reg */
1103 } else if (USE_REG_TB
) {
1104 if (type
== TCG_TYPE_I32
) {
1105 op
= (is_unsigned
? RXY_CLY
: RXY_CY
);
1106 tcg_out_insn_RXY(s
, op
, r1
, TCG_REG_TB
, TCG_REG_NONE
, 0);
1107 new_pool_label(s
, (uint32_t)c2
, R_390_20
, s
->code_ptr
- 2,
1108 4 - (intptr_t)s
->code_gen_ptr
);
1110 op
= (is_unsigned
? RXY_CLG
: RXY_CG
);
1111 tcg_out_insn_RXY(s
, op
, r1
, TCG_REG_TB
, TCG_REG_NONE
, 0);
1112 new_pool_label(s
, c2
, R_390_20
, s
->code_ptr
- 2,
1113 -(intptr_t)s
->code_gen_ptr
);
1117 if (type
== TCG_TYPE_I32
) {
1118 op
= (is_unsigned
? RIL_CLRL
: RIL_CRL
);
1119 tcg_out_insn_RIL(s
, op
, r1
, 0);
1120 new_pool_label(s
, (uint32_t)c2
, R_390_PC32DBL
,
1121 s
->code_ptr
- 2, 2 + 4);
1123 op
= (is_unsigned
? RIL_CLGRL
: RIL_CGRL
);
1124 tcg_out_insn_RIL(s
, op
, r1
, 0);
1125 new_pool_label(s
, c2
, R_390_PC32DBL
, s
->code_ptr
- 2, 2);
1131 if (type
== TCG_TYPE_I32
) {
1132 op
= (is_unsigned
? RR_CLR
: RR_CR
);
1133 tcg_out_insn_RR(s
, op
, r1
, c2
);
1135 op
= (is_unsigned
? RRE_CLGR
: RRE_CGR
);
1136 tcg_out_insn_RRE(s
, op
, r1
, c2
);
1140 return tcg_cond_to_s390_cond
[c
];
1143 static void tgen_setcond(TCGContext
*s
, TCGType type
, TCGCond cond
,
1144 TCGReg dest
, TCGReg c1
, TCGArg c2
, int c2const
)
1149 /* With LOC2, we can always emit the minimum 3 insns. */
1150 if (s390_facilities
& FACILITY_LOAD_ON_COND2
) {
1151 /* Emit: d = 0, d = (cc ? 1 : d). */
1152 cc
= tgen_cmp(s
, type
, cond
, c1
, c2
, c2const
, false);
1153 tcg_out_movi(s
, TCG_TYPE_I64
, dest
, 0);
1154 tcg_out_insn(s
, RIE
, LOCGHI
, dest
, 1, cc
);
1158 have_loc
= (s390_facilities
& FACILITY_LOAD_ON_COND
) != 0;
1160 /* For HAVE_LOC, only the paths through GTU/GT/LEU/LE are smaller. */
1164 /* X != 0 is X > 0. */
1165 if (c2const
&& c2
== 0) {
1166 cond
= TCG_COND_GTU
;
1174 /* The result of a compare has CC=2 for GT and CC=3 unused.
1175 ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */
1176 tgen_cmp(s
, type
, cond
, c1
, c2
, c2const
, true);
1177 tcg_out_movi(s
, type
, dest
, 0);
1178 tcg_out_insn(s
, RRE
, ALCGR
, dest
, dest
);
1182 /* X == 0 is X <= 0. */
1183 if (c2const
&& c2
== 0) {
1184 cond
= TCG_COND_LEU
;
1192 /* As above, but we're looking for borrow, or !carry.
1193 The second insn computes d - d - borrow, or -1 for true
1194 and 0 for false. So we must mask to 1 bit afterward. */
1195 tgen_cmp(s
, type
, cond
, c1
, c2
, c2const
, true);
1196 tcg_out_insn(s
, RRE
, SLBGR
, dest
, dest
);
1197 tgen_andi(s
, type
, dest
, 1);
1204 /* Swap operands so that we can use LEU/GTU/GT/LE. */
1209 tcg_out_movi(s
, type
, TCG_TMP0
, c2
);
1218 cond
= tcg_swap_cond(cond
);
1222 g_assert_not_reached();
1225 cc
= tgen_cmp(s
, type
, cond
, c1
, c2
, c2const
, false);
1227 /* Emit: d = 0, t = 1, d = (cc ? t : d). */
1228 tcg_out_movi(s
, TCG_TYPE_I64
, dest
, 0);
1229 tcg_out_movi(s
, TCG_TYPE_I64
, TCG_TMP0
, 1);
1230 tcg_out_insn(s
, RRF
, LOCGR
, dest
, TCG_TMP0
, cc
);
1232 /* Emit: d = 1; if (cc) goto over; d = 0; over: */
1233 tcg_out_movi(s
, type
, dest
, 1);
1234 tcg_out_insn(s
, RI
, BRC
, cc
, (4 + 4) >> 1);
1235 tcg_out_movi(s
, type
, dest
, 0);
1239 static void tgen_movcond(TCGContext
*s
, TCGType type
, TCGCond c
, TCGReg dest
,
1240 TCGReg c1
, TCGArg c2
, int c2const
,
1241 TCGArg v3
, int v3const
)
1244 if (s390_facilities
& FACILITY_LOAD_ON_COND
) {
1245 cc
= tgen_cmp(s
, type
, c
, c1
, c2
, c2const
, false);
1247 tcg_out_insn(s
, RIE
, LOCGHI
, dest
, v3
, cc
);
1249 tcg_out_insn(s
, RRF
, LOCGR
, dest
, v3
, cc
);
1252 c
= tcg_invert_cond(c
);
1253 cc
= tgen_cmp(s
, type
, c
, c1
, c2
, c2const
, false);
1255 /* Emit: if (cc) goto over; dest = r3; over: */
1256 tcg_out_insn(s
, RI
, BRC
, cc
, (4 + 4) >> 1);
1257 tcg_out_insn(s
, RRE
, LGR
, dest
, v3
);
1261 static void tgen_clz(TCGContext
*s
, TCGReg dest
, TCGReg a1
,
1262 TCGArg a2
, int a2const
)
1264 /* Since this sets both R and R+1, we have no choice but to store the
1265 result into R0, allowing R1 == TCG_TMP0 to be clobbered as well. */
1266 QEMU_BUILD_BUG_ON(TCG_TMP0
!= TCG_REG_R1
);
1267 tcg_out_insn(s
, RRE
, FLOGR
, TCG_REG_R0
, a1
);
1269 if (a2const
&& a2
== 64) {
1270 tcg_out_mov(s
, TCG_TYPE_I64
, dest
, TCG_REG_R0
);
1273 tcg_out_movi(s
, TCG_TYPE_I64
, dest
, a2
);
1275 tcg_out_mov(s
, TCG_TYPE_I64
, dest
, a2
);
1277 if (s390_facilities
& FACILITY_LOAD_ON_COND
) {
1278 /* Emit: if (one bit found) dest = r0. */
1279 tcg_out_insn(s
, RRF
, LOCGR
, dest
, TCG_REG_R0
, 2);
1281 /* Emit: if (no one bit found) goto over; dest = r0; over: */
1282 tcg_out_insn(s
, RI
, BRC
, 8, (4 + 4) >> 1);
1283 tcg_out_insn(s
, RRE
, LGR
, dest
, TCG_REG_R0
);
1288 static void tgen_deposit(TCGContext
*s
, TCGReg dest
, TCGReg src
,
1289 int ofs
, int len
, int z
)
1291 int lsb
= (63 - ofs
);
1292 int msb
= lsb
- (len
- 1);
1293 tcg_out_risbg(s
, dest
, src
, msb
, lsb
, ofs
, z
);
1296 static void tgen_extract(TCGContext
*s
, TCGReg dest
, TCGReg src
,
1299 tcg_out_risbg(s
, dest
, src
, 64 - len
, 63, 64 - ofs
, 1);
1302 static void tgen_gotoi(TCGContext
*s
, int cc
, tcg_insn_unit
*dest
)
1304 ptrdiff_t off
= dest
- s
->code_ptr
;
1305 if (off
== (int16_t)off
) {
1306 tcg_out_insn(s
, RI
, BRC
, cc
, off
);
1307 } else if (off
== (int32_t)off
) {
1308 tcg_out_insn(s
, RIL
, BRCL
, cc
, off
);
1310 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_TMP0
, (uintptr_t)dest
);
1311 tcg_out_insn(s
, RR
, BCR
, cc
, TCG_TMP0
);
1315 static void tgen_branch(TCGContext
*s
, int cc
, TCGLabel
*l
)
1318 tgen_gotoi(s
, cc
, l
->u
.value_ptr
);
1319 } else if (USE_LONG_BRANCHES
) {
1320 tcg_out16(s
, RIL_BRCL
| (cc
<< 4));
1321 tcg_out_reloc(s
, s
->code_ptr
, R_390_PC32DBL
, l
, 2);
1324 tcg_out16(s
, RI_BRC
| (cc
<< 4));
1325 tcg_out_reloc(s
, s
->code_ptr
, R_390_PC16DBL
, l
, 2);
1330 static void tgen_compare_branch(TCGContext
*s
, S390Opcode opc
, int cc
,
1331 TCGReg r1
, TCGReg r2
, TCGLabel
*l
)
1336 off
= l
->u
.value_ptr
- s
->code_ptr
;
1338 tcg_out_reloc(s
, s
->code_ptr
+ 1, R_390_PC16DBL
, l
, 2);
1341 tcg_out16(s
, (opc
& 0xff00) | (r1
<< 4) | r2
);
1343 tcg_out16(s
, cc
<< 12 | (opc
& 0xff));
1346 static void tgen_compare_imm_branch(TCGContext
*s
, S390Opcode opc
, int cc
,
1347 TCGReg r1
, int i2
, TCGLabel
*l
)
1349 tcg_target_long off
= 0;
1352 off
= l
->u
.value_ptr
- s
->code_ptr
;
1354 tcg_out_reloc(s
, s
->code_ptr
+ 1, R_390_PC16DBL
, l
, 2);
1357 tcg_out16(s
, (opc
& 0xff00) | (r1
<< 4) | cc
);
1359 tcg_out16(s
, (i2
<< 8) | (opc
& 0xff));
1362 static void tgen_brcond(TCGContext
*s
, TCGType type
, TCGCond c
,
1363 TCGReg r1
, TCGArg c2
, int c2const
, TCGLabel
*l
)
1367 if (s390_facilities
& FACILITY_GEN_INST_EXT
) {
1368 bool is_unsigned
= is_unsigned_cond(c
);
1372 cc
= tcg_cond_to_s390_cond
[c
];
1375 opc
= (type
== TCG_TYPE_I32
1376 ? (is_unsigned
? RIE_CLRJ
: RIE_CRJ
)
1377 : (is_unsigned
? RIE_CLGRJ
: RIE_CGRJ
));
1378 tgen_compare_branch(s
, opc
, cc
, r1
, c2
, l
);
1382 /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1383 If the immediate we've been given does not fit that range, we'll
1384 fall back to separate compare and branch instructions using the
1385 larger comparison range afforded by COMPARE IMMEDIATE. */
1386 if (type
== TCG_TYPE_I32
) {
1389 in_range
= (uint32_t)c2
== (uint8_t)c2
;
1392 in_range
= (int32_t)c2
== (int8_t)c2
;
1397 in_range
= (uint64_t)c2
== (uint8_t)c2
;
1400 in_range
= (int64_t)c2
== (int8_t)c2
;
1404 tgen_compare_imm_branch(s
, opc
, cc
, r1
, c2
, l
);
1409 cc
= tgen_cmp(s
, type
, c
, r1
, c2
, c2const
, false);
1410 tgen_branch(s
, cc
, l
);
1413 static void tcg_out_call(TCGContext
*s
, tcg_insn_unit
*dest
)
1415 ptrdiff_t off
= dest
- s
->code_ptr
;
1416 if (off
== (int32_t)off
) {
1417 tcg_out_insn(s
, RIL
, BRASL
, TCG_REG_R14
, off
);
1419 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_TMP0
, (uintptr_t)dest
);
1420 tcg_out_insn(s
, RR
, BASR
, TCG_REG_R14
, TCG_TMP0
);
1424 static void tcg_out_qemu_ld_direct(TCGContext
*s
, TCGMemOp opc
, TCGReg data
,
1425 TCGReg base
, TCGReg index
, int disp
)
1427 switch (opc
& (MO_SSIZE
| MO_BSWAP
)) {
1429 tcg_out_insn(s
, RXY
, LLGC
, data
, base
, index
, disp
);
1432 tcg_out_insn(s
, RXY
, LGB
, data
, base
, index
, disp
);
1435 case MO_UW
| MO_BSWAP
:
1436 /* swapped unsigned halfword load with upper bits zeroed */
1437 tcg_out_insn(s
, RXY
, LRVH
, data
, base
, index
, disp
);
1438 tgen_ext16u(s
, TCG_TYPE_I64
, data
, data
);
1441 tcg_out_insn(s
, RXY
, LLGH
, data
, base
, index
, disp
);
1444 case MO_SW
| MO_BSWAP
:
1445 /* swapped sign-extended halfword load */
1446 tcg_out_insn(s
, RXY
, LRVH
, data
, base
, index
, disp
);
1447 tgen_ext16s(s
, TCG_TYPE_I64
, data
, data
);
1450 tcg_out_insn(s
, RXY
, LGH
, data
, base
, index
, disp
);
1453 case MO_UL
| MO_BSWAP
:
1454 /* swapped unsigned int load with upper bits zeroed */
1455 tcg_out_insn(s
, RXY
, LRV
, data
, base
, index
, disp
);
1456 tgen_ext32u(s
, data
, data
);
1459 tcg_out_insn(s
, RXY
, LLGF
, data
, base
, index
, disp
);
1462 case MO_SL
| MO_BSWAP
:
1463 /* swapped sign-extended int load */
1464 tcg_out_insn(s
, RXY
, LRV
, data
, base
, index
, disp
);
1465 tgen_ext32s(s
, data
, data
);
1468 tcg_out_insn(s
, RXY
, LGF
, data
, base
, index
, disp
);
1471 case MO_Q
| MO_BSWAP
:
1472 tcg_out_insn(s
, RXY
, LRVG
, data
, base
, index
, disp
);
1475 tcg_out_insn(s
, RXY
, LG
, data
, base
, index
, disp
);
1483 static void tcg_out_qemu_st_direct(TCGContext
*s
, TCGMemOp opc
, TCGReg data
,
1484 TCGReg base
, TCGReg index
, int disp
)
1486 switch (opc
& (MO_SIZE
| MO_BSWAP
)) {
1488 if (disp
>= 0 && disp
< 0x1000) {
1489 tcg_out_insn(s
, RX
, STC
, data
, base
, index
, disp
);
1491 tcg_out_insn(s
, RXY
, STCY
, data
, base
, index
, disp
);
1495 case MO_UW
| MO_BSWAP
:
1496 tcg_out_insn(s
, RXY
, STRVH
, data
, base
, index
, disp
);
1499 if (disp
>= 0 && disp
< 0x1000) {
1500 tcg_out_insn(s
, RX
, STH
, data
, base
, index
, disp
);
1502 tcg_out_insn(s
, RXY
, STHY
, data
, base
, index
, disp
);
1506 case MO_UL
| MO_BSWAP
:
1507 tcg_out_insn(s
, RXY
, STRV
, data
, base
, index
, disp
);
1510 if (disp
>= 0 && disp
< 0x1000) {
1511 tcg_out_insn(s
, RX
, ST
, data
, base
, index
, disp
);
1513 tcg_out_insn(s
, RXY
, STY
, data
, base
, index
, disp
);
1517 case MO_Q
| MO_BSWAP
:
1518 tcg_out_insn(s
, RXY
, STRVG
, data
, base
, index
, disp
);
1521 tcg_out_insn(s
, RXY
, STG
, data
, base
, index
, disp
);
1529 #if defined(CONFIG_SOFTMMU)
1530 #include "tcg-ldst.inc.c"
1532 /* We're expecting to use a 20-bit signed offset on the tlb memory ops.
1533 Using the offset of the second entry in the last tlb table ensures
1534 that we can index all of the elements of the first entry. */
1535 QEMU_BUILD_BUG_ON(offsetof(CPUArchState
, tlb_table
[NB_MMU_MODES
- 1][1])
1538 /* Load and compare a TLB entry, leaving the flags set. Loads the TLB
1539 addend into R2. Returns a register with the santitized guest address. */
1540 static TCGReg
tcg_out_tlb_read(TCGContext
* s
, TCGReg addr_reg
, TCGMemOp opc
,
1541 int mem_index
, bool is_ld
)
1543 unsigned s_bits
= opc
& MO_SIZE
;
1544 unsigned a_bits
= get_alignment_bits(opc
);
1545 unsigned s_mask
= (1 << s_bits
) - 1;
1546 unsigned a_mask
= (1 << a_bits
) - 1;
1550 /* For aligned accesses, we check the first byte and include the alignment
1551 bits within the address. For unaligned access, we check that we don't
1552 cross pages using the address of the last byte of the access. */
1553 a_off
= (a_bits
>= s_bits
? 0 : s_mask
- a_mask
);
1554 tlb_mask
= (uint64_t)TARGET_PAGE_MASK
| a_mask
;
1556 if (s390_facilities
& FACILITY_GEN_INST_EXT
) {
1557 tcg_out_risbg(s
, TCG_REG_R2
, addr_reg
,
1558 64 - CPU_TLB_BITS
- CPU_TLB_ENTRY_BITS
,
1559 63 - CPU_TLB_ENTRY_BITS
,
1560 64 + CPU_TLB_ENTRY_BITS
- TARGET_PAGE_BITS
, 1);
1562 tcg_out_insn(s
, RX
, LA
, TCG_REG_R3
, addr_reg
, TCG_REG_NONE
, a_off
);
1563 tgen_andi(s
, TCG_TYPE_TL
, TCG_REG_R3
, tlb_mask
);
1565 tgen_andi_risbg(s
, TCG_REG_R3
, addr_reg
, tlb_mask
);
1568 tcg_out_sh64(s
, RSY_SRLG
, TCG_REG_R2
, addr_reg
, TCG_REG_NONE
,
1569 TARGET_PAGE_BITS
- CPU_TLB_ENTRY_BITS
);
1570 tcg_out_insn(s
, RX
, LA
, TCG_REG_R3
, addr_reg
, TCG_REG_NONE
, a_off
);
1571 tgen_andi(s
, TCG_TYPE_I64
, TCG_REG_R2
,
1572 (CPU_TLB_SIZE
- 1) << CPU_TLB_ENTRY_BITS
);
1573 tgen_andi(s
, TCG_TYPE_TL
, TCG_REG_R3
, tlb_mask
);
1577 ofs
= offsetof(CPUArchState
, tlb_table
[mem_index
][0].addr_read
);
1579 ofs
= offsetof(CPUArchState
, tlb_table
[mem_index
][0].addr_write
);
1581 if (TARGET_LONG_BITS
== 32) {
1582 tcg_out_mem(s
, RX_C
, RXY_CY
, TCG_REG_R3
, TCG_REG_R2
, TCG_AREG0
, ofs
);
1584 tcg_out_mem(s
, 0, RXY_CG
, TCG_REG_R3
, TCG_REG_R2
, TCG_AREG0
, ofs
);
1587 ofs
= offsetof(CPUArchState
, tlb_table
[mem_index
][0].addend
);
1588 tcg_out_mem(s
, 0, RXY_LG
, TCG_REG_R2
, TCG_REG_R2
, TCG_AREG0
, ofs
);
1590 if (TARGET_LONG_BITS
== 32) {
1591 tgen_ext32u(s
, TCG_REG_R3
, addr_reg
);
1597 static void add_qemu_ldst_label(TCGContext
*s
, bool is_ld
, TCGMemOpIdx oi
,
1598 TCGReg data
, TCGReg addr
,
1599 tcg_insn_unit
*raddr
, tcg_insn_unit
*label_ptr
)
1601 TCGLabelQemuLdst
*label
= new_ldst_label(s
);
1603 label
->is_ld
= is_ld
;
1605 label
->datalo_reg
= data
;
1606 label
->addrlo_reg
= addr
;
1607 label
->raddr
= raddr
;
1608 label
->label_ptr
[0] = label_ptr
;
1611 static void tcg_out_qemu_ld_slow_path(TCGContext
*s
, TCGLabelQemuLdst
*lb
)
1613 TCGReg addr_reg
= lb
->addrlo_reg
;
1614 TCGReg data_reg
= lb
->datalo_reg
;
1615 TCGMemOpIdx oi
= lb
->oi
;
1616 TCGMemOp opc
= get_memop(oi
);
1618 patch_reloc(lb
->label_ptr
[0], R_390_PC16DBL
, (intptr_t)s
->code_ptr
, 2);
1620 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_REG_R2
, TCG_AREG0
);
1621 if (TARGET_LONG_BITS
== 64) {
1622 tcg_out_mov(s
, TCG_TYPE_I64
, TCG_REG_R3
, addr_reg
);
1624 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_R4
, oi
);
1625 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R5
, (uintptr_t)lb
->raddr
);
1626 tcg_out_call(s
, qemu_ld_helpers
[opc
& (MO_BSWAP
| MO_SSIZE
)]);
1627 tcg_out_mov(s
, TCG_TYPE_I64
, data_reg
, TCG_REG_R2
);
1629 tgen_gotoi(s
, S390_CC_ALWAYS
, lb
->raddr
);
1632 static void tcg_out_qemu_st_slow_path(TCGContext
*s
, TCGLabelQemuLdst
*lb
)
1634 TCGReg addr_reg
= lb
->addrlo_reg
;
1635 TCGReg data_reg
= lb
->datalo_reg
;
1636 TCGMemOpIdx oi
= lb
->oi
;
1637 TCGMemOp opc
= get_memop(oi
);
1639 patch_reloc(lb
->label_ptr
[0], R_390_PC16DBL
, (intptr_t)s
->code_ptr
, 2);
1641 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_REG_R2
, TCG_AREG0
);
1642 if (TARGET_LONG_BITS
== 64) {
1643 tcg_out_mov(s
, TCG_TYPE_I64
, TCG_REG_R3
, addr_reg
);
1645 switch (opc
& MO_SIZE
) {
1647 tgen_ext8u(s
, TCG_TYPE_I64
, TCG_REG_R4
, data_reg
);
1650 tgen_ext16u(s
, TCG_TYPE_I64
, TCG_REG_R4
, data_reg
);
1653 tgen_ext32u(s
, TCG_REG_R4
, data_reg
);
1656 tcg_out_mov(s
, TCG_TYPE_I64
, TCG_REG_R4
, data_reg
);
1661 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_R5
, oi
);
1662 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R6
, (uintptr_t)lb
->raddr
);
1663 tcg_out_call(s
, qemu_st_helpers
[opc
& (MO_BSWAP
| MO_SIZE
)]);
1665 tgen_gotoi(s
, S390_CC_ALWAYS
, lb
->raddr
);
1668 static void tcg_prepare_user_ldst(TCGContext
*s
, TCGReg
*addr_reg
,
1669 TCGReg
*index_reg
, tcg_target_long
*disp
)
1671 if (TARGET_LONG_BITS
== 32) {
1672 tgen_ext32u(s
, TCG_TMP0
, *addr_reg
);
1673 *addr_reg
= TCG_TMP0
;
1675 if (guest_base
< 0x80000) {
1676 *index_reg
= TCG_REG_NONE
;
1679 *index_reg
= TCG_GUEST_BASE_REG
;
1683 #endif /* CONFIG_SOFTMMU */
1685 static void tcg_out_qemu_ld(TCGContext
* s
, TCGReg data_reg
, TCGReg addr_reg
,
1688 TCGMemOp opc
= get_memop(oi
);
1689 #ifdef CONFIG_SOFTMMU
1690 unsigned mem_index
= get_mmuidx(oi
);
1691 tcg_insn_unit
*label_ptr
;
1694 base_reg
= tcg_out_tlb_read(s
, addr_reg
, opc
, mem_index
, 1);
1696 tcg_out16(s
, RI_BRC
| (S390_CC_NE
<< 4));
1697 label_ptr
= s
->code_ptr
;
1700 tcg_out_qemu_ld_direct(s
, opc
, data_reg
, base_reg
, TCG_REG_R2
, 0);
1702 add_qemu_ldst_label(s
, 1, oi
, data_reg
, addr_reg
, s
->code_ptr
, label_ptr
);
1705 tcg_target_long disp
;
1707 tcg_prepare_user_ldst(s
, &addr_reg
, &index_reg
, &disp
);
1708 tcg_out_qemu_ld_direct(s
, opc
, data_reg
, addr_reg
, index_reg
, disp
);
1712 static void tcg_out_qemu_st(TCGContext
* s
, TCGReg data_reg
, TCGReg addr_reg
,
1715 TCGMemOp opc
= get_memop(oi
);
1716 #ifdef CONFIG_SOFTMMU
1717 unsigned mem_index
= get_mmuidx(oi
);
1718 tcg_insn_unit
*label_ptr
;
1721 base_reg
= tcg_out_tlb_read(s
, addr_reg
, opc
, mem_index
, 0);
1723 tcg_out16(s
, RI_BRC
| (S390_CC_NE
<< 4));
1724 label_ptr
= s
->code_ptr
;
1727 tcg_out_qemu_st_direct(s
, opc
, data_reg
, base_reg
, TCG_REG_R2
, 0);
1729 add_qemu_ldst_label(s
, 0, oi
, data_reg
, addr_reg
, s
->code_ptr
, label_ptr
);
1732 tcg_target_long disp
;
1734 tcg_prepare_user_ldst(s
, &addr_reg
, &index_reg
, &disp
);
1735 tcg_out_qemu_st_direct(s
, opc
, data_reg
, addr_reg
, index_reg
, disp
);
1739 # define OP_32_64(x) \
1740 case glue(glue(INDEX_op_,x),_i32): \
1741 case glue(glue(INDEX_op_,x),_i64)
1743 static inline void tcg_out_op(TCGContext
*s
, TCGOpcode opc
,
1744 const TCGArg
*args
, const int *const_args
)
1750 case INDEX_op_exit_tb
:
1751 /* Reuse the zeroing that exists for goto_ptr. */
1754 tgen_gotoi(s
, S390_CC_ALWAYS
, s
->code_gen_epilogue
);
1756 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R2
, a0
);
1757 tgen_gotoi(s
, S390_CC_ALWAYS
, tb_ret_addr
);
1761 case INDEX_op_goto_tb
:
1763 if (s
->tb_jmp_insn_offset
) {
1764 /* branch displacement must be aligned for atomic patching;
1765 * see if we need to add extra nop before branch
1767 if (!QEMU_PTR_IS_ALIGNED(s
->code_ptr
+ 1, 4)) {
1770 tcg_debug_assert(!USE_REG_TB
);
1771 tcg_out16(s
, RIL_BRCL
| (S390_CC_ALWAYS
<< 4));
1772 s
->tb_jmp_insn_offset
[a0
] = tcg_current_code_size(s
);
1775 /* load address stored at s->tb_jmp_target_addr + a0 */
1776 tcg_out_ld_abs(s
, TCG_TYPE_PTR
, TCG_REG_TB
,
1777 s
->tb_jmp_target_addr
+ a0
);
1779 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, TCG_REG_TB
);
1781 set_jmp_reset_offset(s
, a0
);
1783 /* For the unlinked path of goto_tb, we need to reset
1784 TCG_REG_TB to the beginning of this TB. */
1786 int ofs
= -tcg_current_code_size(s
);
1787 assert(ofs
== (int16_t)ofs
);
1788 tcg_out_insn(s
, RI
, AGHI
, TCG_REG_TB
, ofs
);
1792 case INDEX_op_goto_ptr
:
1795 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_REG_TB
, a0
);
1797 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, a0
);
1801 /* ??? LLC (RXY format) is only present with the extended-immediate
1802 facility, whereas LLGC is always present. */
1803 tcg_out_mem(s
, 0, RXY_LLGC
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1807 /* ??? LB is no smaller than LGB, so no point to using it. */
1808 tcg_out_mem(s
, 0, RXY_LGB
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1812 /* ??? LLH (RXY format) is only present with the extended-immediate
1813 facility, whereas LLGH is always present. */
1814 tcg_out_mem(s
, 0, RXY_LLGH
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1817 case INDEX_op_ld16s_i32
:
1818 tcg_out_mem(s
, RX_LH
, RXY_LHY
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1821 case INDEX_op_ld_i32
:
1822 tcg_out_ld(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1826 tcg_out_mem(s
, RX_STC
, RXY_STCY
, args
[0], args
[1],
1827 TCG_REG_NONE
, args
[2]);
1831 tcg_out_mem(s
, RX_STH
, RXY_STHY
, args
[0], args
[1],
1832 TCG_REG_NONE
, args
[2]);
1835 case INDEX_op_st_i32
:
1836 tcg_out_st(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1839 case INDEX_op_add_i32
:
1840 a0
= args
[0], a1
= args
[1], a2
= (int32_t)args
[2];
1841 if (const_args
[2]) {
1844 if (a2
== (int16_t)a2
) {
1845 tcg_out_insn(s
, RI
, AHI
, a0
, a2
);
1848 if (s390_facilities
& FACILITY_EXT_IMM
) {
1849 tcg_out_insn(s
, RIL
, AFI
, a0
, a2
);
1853 tcg_out_mem(s
, RX_LA
, RXY_LAY
, a0
, a1
, TCG_REG_NONE
, a2
);
1854 } else if (a0
== a1
) {
1855 tcg_out_insn(s
, RR
, AR
, a0
, a2
);
1857 tcg_out_insn(s
, RX
, LA
, a0
, a1
, a2
, 0);
1860 case INDEX_op_sub_i32
:
1861 a0
= args
[0], a1
= args
[1], a2
= (int32_t)args
[2];
1862 if (const_args
[2]) {
1865 } else if (a0
== a1
) {
1866 tcg_out_insn(s
, RR
, SR
, a0
, a2
);
1868 tcg_out_insn(s
, RRF
, SRK
, a0
, a1
, a2
);
1872 case INDEX_op_and_i32
:
1873 a0
= args
[0], a1
= args
[1], a2
= (uint32_t)args
[2];
1874 if (const_args
[2]) {
1875 tcg_out_mov(s
, TCG_TYPE_I32
, a0
, a1
);
1876 tgen_andi(s
, TCG_TYPE_I32
, a0
, a2
);
1877 } else if (a0
== a1
) {
1878 tcg_out_insn(s
, RR
, NR
, a0
, a2
);
1880 tcg_out_insn(s
, RRF
, NRK
, a0
, a1
, a2
);
1883 case INDEX_op_or_i32
:
1884 a0
= args
[0], a1
= args
[1], a2
= (uint32_t)args
[2];
1885 if (const_args
[2]) {
1886 tcg_out_mov(s
, TCG_TYPE_I32
, a0
, a1
);
1887 tgen_ori(s
, TCG_TYPE_I32
, a0
, a2
);
1888 } else if (a0
== a1
) {
1889 tcg_out_insn(s
, RR
, OR
, a0
, a2
);
1891 tcg_out_insn(s
, RRF
, ORK
, a0
, a1
, a2
);
1894 case INDEX_op_xor_i32
:
1895 a0
= args
[0], a1
= args
[1], a2
= (uint32_t)args
[2];
1896 if (const_args
[2]) {
1897 tcg_out_mov(s
, TCG_TYPE_I32
, a0
, a1
);
1898 tgen_xori(s
, TCG_TYPE_I32
, a0
, a2
);
1899 } else if (a0
== a1
) {
1900 tcg_out_insn(s
, RR
, XR
, args
[0], args
[2]);
1902 tcg_out_insn(s
, RRF
, XRK
, a0
, a1
, a2
);
1906 case INDEX_op_neg_i32
:
1907 tcg_out_insn(s
, RR
, LCR
, args
[0], args
[1]);
1910 case INDEX_op_mul_i32
:
1911 if (const_args
[2]) {
1912 if ((int32_t)args
[2] == (int16_t)args
[2]) {
1913 tcg_out_insn(s
, RI
, MHI
, args
[0], args
[2]);
1915 tcg_out_insn(s
, RIL
, MSFI
, args
[0], args
[2]);
1918 tcg_out_insn(s
, RRE
, MSR
, args
[0], args
[2]);
1922 case INDEX_op_div2_i32
:
1923 tcg_out_insn(s
, RR
, DR
, TCG_REG_R2
, args
[4]);
1925 case INDEX_op_divu2_i32
:
1926 tcg_out_insn(s
, RRE
, DLR
, TCG_REG_R2
, args
[4]);
1929 case INDEX_op_shl_i32
:
1933 a0
= args
[0], a1
= args
[1], a2
= (int32_t)args
[2];
1935 if (const_args
[2]) {
1936 tcg_out_sh32(s
, op
, a0
, TCG_REG_NONE
, a2
);
1938 tcg_out_sh32(s
, op
, a0
, a2
, 0);
1941 /* Using tcg_out_sh64 here for the format; it is a 32-bit shift. */
1942 if (const_args
[2]) {
1943 tcg_out_sh64(s
, op2
, a0
, a1
, TCG_REG_NONE
, a2
);
1945 tcg_out_sh64(s
, op2
, a0
, a1
, a2
, 0);
1949 case INDEX_op_shr_i32
:
1953 case INDEX_op_sar_i32
:
1958 case INDEX_op_rotl_i32
:
1959 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1960 if (const_args
[2]) {
1961 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1963 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], args
[2], 0);
1966 case INDEX_op_rotr_i32
:
1967 if (const_args
[2]) {
1968 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1],
1969 TCG_REG_NONE
, (32 - args
[2]) & 31);
1971 tcg_out_insn(s
, RR
, LCR
, TCG_TMP0
, args
[2]);
1972 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], TCG_TMP0
, 0);
1976 case INDEX_op_ext8s_i32
:
1977 tgen_ext8s(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1979 case INDEX_op_ext16s_i32
:
1980 tgen_ext16s(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1982 case INDEX_op_ext8u_i32
:
1983 tgen_ext8u(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1985 case INDEX_op_ext16u_i32
:
1986 tgen_ext16u(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1990 /* The TCG bswap definition requires bits 0-47 already be zero.
1991 Thus we don't need the G-type insns to implement bswap16_i64. */
1992 tcg_out_insn(s
, RRE
, LRVR
, args
[0], args
[1]);
1993 tcg_out_sh32(s
, RS_SRL
, args
[0], TCG_REG_NONE
, 16);
1996 tcg_out_insn(s
, RRE
, LRVR
, args
[0], args
[1]);
1999 case INDEX_op_add2_i32
:
2000 if (const_args
[4]) {
2001 tcg_out_insn(s
, RIL
, ALFI
, args
[0], args
[4]);
2003 tcg_out_insn(s
, RR
, ALR
, args
[0], args
[4]);
2005 tcg_out_insn(s
, RRE
, ALCR
, args
[1], args
[5]);
2007 case INDEX_op_sub2_i32
:
2008 if (const_args
[4]) {
2009 tcg_out_insn(s
, RIL
, SLFI
, args
[0], args
[4]);
2011 tcg_out_insn(s
, RR
, SLR
, args
[0], args
[4]);
2013 tcg_out_insn(s
, RRE
, SLBR
, args
[1], args
[5]);
2017 tgen_branch(s
, S390_CC_ALWAYS
, arg_label(args
[0]));
2020 case INDEX_op_brcond_i32
:
2021 tgen_brcond(s
, TCG_TYPE_I32
, args
[2], args
[0],
2022 args
[1], const_args
[1], arg_label(args
[3]));
2024 case INDEX_op_setcond_i32
:
2025 tgen_setcond(s
, TCG_TYPE_I32
, args
[3], args
[0], args
[1],
2026 args
[2], const_args
[2]);
2028 case INDEX_op_movcond_i32
:
2029 tgen_movcond(s
, TCG_TYPE_I32
, args
[5], args
[0], args
[1],
2030 args
[2], const_args
[2], args
[3], const_args
[3]);
2033 case INDEX_op_qemu_ld_i32
:
2034 /* ??? Technically we can use a non-extending instruction. */
2035 case INDEX_op_qemu_ld_i64
:
2036 tcg_out_qemu_ld(s
, args
[0], args
[1], args
[2]);
2038 case INDEX_op_qemu_st_i32
:
2039 case INDEX_op_qemu_st_i64
:
2040 tcg_out_qemu_st(s
, args
[0], args
[1], args
[2]);
2043 case INDEX_op_ld16s_i64
:
2044 tcg_out_mem(s
, 0, RXY_LGH
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
2046 case INDEX_op_ld32u_i64
:
2047 tcg_out_mem(s
, 0, RXY_LLGF
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
2049 case INDEX_op_ld32s_i64
:
2050 tcg_out_mem(s
, 0, RXY_LGF
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
2052 case INDEX_op_ld_i64
:
2053 tcg_out_ld(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
2056 case INDEX_op_st32_i64
:
2057 tcg_out_st(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
2059 case INDEX_op_st_i64
:
2060 tcg_out_st(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
2063 case INDEX_op_add_i64
:
2064 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2065 if (const_args
[2]) {
2068 if (a2
== (int16_t)a2
) {
2069 tcg_out_insn(s
, RI
, AGHI
, a0
, a2
);
2072 if (s390_facilities
& FACILITY_EXT_IMM
) {
2073 if (a2
== (int32_t)a2
) {
2074 tcg_out_insn(s
, RIL
, AGFI
, a0
, a2
);
2076 } else if (a2
== (uint32_t)a2
) {
2077 tcg_out_insn(s
, RIL
, ALGFI
, a0
, a2
);
2079 } else if (-a2
== (uint32_t)-a2
) {
2080 tcg_out_insn(s
, RIL
, SLGFI
, a0
, -a2
);
2085 tcg_out_mem(s
, RX_LA
, RXY_LAY
, a0
, a1
, TCG_REG_NONE
, a2
);
2086 } else if (a0
== a1
) {
2087 tcg_out_insn(s
, RRE
, AGR
, a0
, a2
);
2089 tcg_out_insn(s
, RX
, LA
, a0
, a1
, a2
, 0);
2092 case INDEX_op_sub_i64
:
2093 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2094 if (const_args
[2]) {
2097 } else if (a0
== a1
) {
2098 tcg_out_insn(s
, RRE
, SGR
, a0
, a2
);
2100 tcg_out_insn(s
, RRF
, SGRK
, a0
, a1
, a2
);
2104 case INDEX_op_and_i64
:
2105 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2106 if (const_args
[2]) {
2107 tcg_out_mov(s
, TCG_TYPE_I64
, a0
, a1
);
2108 tgen_andi(s
, TCG_TYPE_I64
, args
[0], args
[2]);
2109 } else if (a0
== a1
) {
2110 tcg_out_insn(s
, RRE
, NGR
, args
[0], args
[2]);
2112 tcg_out_insn(s
, RRF
, NGRK
, a0
, a1
, a2
);
2115 case INDEX_op_or_i64
:
2116 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2117 if (const_args
[2]) {
2118 tcg_out_mov(s
, TCG_TYPE_I64
, a0
, a1
);
2119 tgen_ori(s
, TCG_TYPE_I64
, a0
, a2
);
2120 } else if (a0
== a1
) {
2121 tcg_out_insn(s
, RRE
, OGR
, a0
, a2
);
2123 tcg_out_insn(s
, RRF
, OGRK
, a0
, a1
, a2
);
2126 case INDEX_op_xor_i64
:
2127 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2128 if (const_args
[2]) {
2129 tcg_out_mov(s
, TCG_TYPE_I64
, a0
, a1
);
2130 tgen_xori(s
, TCG_TYPE_I64
, a0
, a2
);
2131 } else if (a0
== a1
) {
2132 tcg_out_insn(s
, RRE
, XGR
, a0
, a2
);
2134 tcg_out_insn(s
, RRF
, XGRK
, a0
, a1
, a2
);
2138 case INDEX_op_neg_i64
:
2139 tcg_out_insn(s
, RRE
, LCGR
, args
[0], args
[1]);
2141 case INDEX_op_bswap64_i64
:
2142 tcg_out_insn(s
, RRE
, LRVGR
, args
[0], args
[1]);
2145 case INDEX_op_mul_i64
:
2146 if (const_args
[2]) {
2147 if (args
[2] == (int16_t)args
[2]) {
2148 tcg_out_insn(s
, RI
, MGHI
, args
[0], args
[2]);
2150 tcg_out_insn(s
, RIL
, MSGFI
, args
[0], args
[2]);
2153 tcg_out_insn(s
, RRE
, MSGR
, args
[0], args
[2]);
2157 case INDEX_op_div2_i64
:
2158 /* ??? We get an unnecessary sign-extension of the dividend
2159 into R3 with this definition, but as we do in fact always
2160 produce both quotient and remainder using INDEX_op_div_i64
2161 instead requires jumping through even more hoops. */
2162 tcg_out_insn(s
, RRE
, DSGR
, TCG_REG_R2
, args
[4]);
2164 case INDEX_op_divu2_i64
:
2165 tcg_out_insn(s
, RRE
, DLGR
, TCG_REG_R2
, args
[4]);
2167 case INDEX_op_mulu2_i64
:
2168 tcg_out_insn(s
, RRE
, MLGR
, TCG_REG_R2
, args
[3]);
2171 case INDEX_op_shl_i64
:
2174 if (const_args
[2]) {
2175 tcg_out_sh64(s
, op
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
2177 tcg_out_sh64(s
, op
, args
[0], args
[1], args
[2], 0);
2180 case INDEX_op_shr_i64
:
2183 case INDEX_op_sar_i64
:
2187 case INDEX_op_rotl_i64
:
2188 if (const_args
[2]) {
2189 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1],
2190 TCG_REG_NONE
, args
[2]);
2192 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1], args
[2], 0);
2195 case INDEX_op_rotr_i64
:
2196 if (const_args
[2]) {
2197 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1],
2198 TCG_REG_NONE
, (64 - args
[2]) & 63);
2200 /* We can use the smaller 32-bit negate because only the
2201 low 6 bits are examined for the rotate. */
2202 tcg_out_insn(s
, RR
, LCR
, TCG_TMP0
, args
[2]);
2203 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1], TCG_TMP0
, 0);
2207 case INDEX_op_ext8s_i64
:
2208 tgen_ext8s(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2210 case INDEX_op_ext16s_i64
:
2211 tgen_ext16s(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2213 case INDEX_op_ext_i32_i64
:
2214 case INDEX_op_ext32s_i64
:
2215 tgen_ext32s(s
, args
[0], args
[1]);
2217 case INDEX_op_ext8u_i64
:
2218 tgen_ext8u(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2220 case INDEX_op_ext16u_i64
:
2221 tgen_ext16u(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2223 case INDEX_op_extu_i32_i64
:
2224 case INDEX_op_ext32u_i64
:
2225 tgen_ext32u(s
, args
[0], args
[1]);
2228 case INDEX_op_add2_i64
:
2229 if (const_args
[4]) {
2230 if ((int64_t)args
[4] >= 0) {
2231 tcg_out_insn(s
, RIL
, ALGFI
, args
[0], args
[4]);
2233 tcg_out_insn(s
, RIL
, SLGFI
, args
[0], -args
[4]);
2236 tcg_out_insn(s
, RRE
, ALGR
, args
[0], args
[4]);
2238 tcg_out_insn(s
, RRE
, ALCGR
, args
[1], args
[5]);
2240 case INDEX_op_sub2_i64
:
2241 if (const_args
[4]) {
2242 if ((int64_t)args
[4] >= 0) {
2243 tcg_out_insn(s
, RIL
, SLGFI
, args
[0], args
[4]);
2245 tcg_out_insn(s
, RIL
, ALGFI
, args
[0], -args
[4]);
2248 tcg_out_insn(s
, RRE
, SLGR
, args
[0], args
[4]);
2250 tcg_out_insn(s
, RRE
, SLBGR
, args
[1], args
[5]);
2253 case INDEX_op_brcond_i64
:
2254 tgen_brcond(s
, TCG_TYPE_I64
, args
[2], args
[0],
2255 args
[1], const_args
[1], arg_label(args
[3]));
2257 case INDEX_op_setcond_i64
:
2258 tgen_setcond(s
, TCG_TYPE_I64
, args
[3], args
[0], args
[1],
2259 args
[2], const_args
[2]);
2261 case INDEX_op_movcond_i64
:
2262 tgen_movcond(s
, TCG_TYPE_I64
, args
[5], args
[0], args
[1],
2263 args
[2], const_args
[2], args
[3], const_args
[3]);
2267 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2268 if (const_args
[1]) {
2269 tgen_deposit(s
, a0
, a2
, args
[3], args
[4], 1);
2271 /* Since we can't support "0Z" as a constraint, we allow a1 in
2272 any register. Fix things up as if a matching constraint. */
2274 TCGType type
= (opc
== INDEX_op_deposit_i64
);
2276 tcg_out_mov(s
, type
, TCG_TMP0
, a2
);
2279 tcg_out_mov(s
, type
, a0
, a1
);
2281 tgen_deposit(s
, a0
, a2
, args
[3], args
[4], 0);
2286 tgen_extract(s
, args
[0], args
[1], args
[2], args
[3]);
2289 case INDEX_op_clz_i64
:
2290 tgen_clz(s
, args
[0], args
[1], args
[2], const_args
[2]);
2294 /* The host memory model is quite strong, we simply need to
2295 serialize the instruction stream. */
2296 if (args
[0] & TCG_MO_ST_LD
) {
2297 tcg_out_insn(s
, RR
, BCR
,
2298 s390_facilities
& FACILITY_FAST_BCR_SER
? 14 : 15, 0);
2302 case INDEX_op_mov_i32
: /* Always emitted via tcg_out_mov. */
2303 case INDEX_op_mov_i64
:
2304 case INDEX_op_movi_i32
: /* Always emitted via tcg_out_movi. */
2305 case INDEX_op_movi_i64
:
2306 case INDEX_op_call
: /* Always emitted via tcg_out_call. */
2312 static const TCGTargetOpDef
*tcg_target_op_def(TCGOpcode op
)
2314 static const TCGTargetOpDef r
= { .args_ct_str
= { "r" } };
2315 static const TCGTargetOpDef r_r
= { .args_ct_str
= { "r", "r" } };
2316 static const TCGTargetOpDef r_L
= { .args_ct_str
= { "r", "L" } };
2317 static const TCGTargetOpDef L_L
= { .args_ct_str
= { "L", "L" } };
2318 static const TCGTargetOpDef r_ri
= { .args_ct_str
= { "r", "ri" } };
2319 static const TCGTargetOpDef r_r_ri
= { .args_ct_str
= { "r", "r", "ri" } };
2320 static const TCGTargetOpDef r_0_ri
= { .args_ct_str
= { "r", "0", "ri" } };
2321 static const TCGTargetOpDef r_0_rI
= { .args_ct_str
= { "r", "0", "rI" } };
2322 static const TCGTargetOpDef r_0_rJ
= { .args_ct_str
= { "r", "0", "rJ" } };
2323 static const TCGTargetOpDef a2_r
2324 = { .args_ct_str
= { "r", "r", "0", "1", "r", "r" } };
2325 static const TCGTargetOpDef a2_ri
2326 = { .args_ct_str
= { "r", "r", "0", "1", "ri", "r" } };
2327 static const TCGTargetOpDef a2_rA
2328 = { .args_ct_str
= { "r", "r", "0", "1", "rA", "r" } };
2331 case INDEX_op_goto_ptr
:
2334 case INDEX_op_ld8u_i32
:
2335 case INDEX_op_ld8u_i64
:
2336 case INDEX_op_ld8s_i32
:
2337 case INDEX_op_ld8s_i64
:
2338 case INDEX_op_ld16u_i32
:
2339 case INDEX_op_ld16u_i64
:
2340 case INDEX_op_ld16s_i32
:
2341 case INDEX_op_ld16s_i64
:
2342 case INDEX_op_ld_i32
:
2343 case INDEX_op_ld32u_i64
:
2344 case INDEX_op_ld32s_i64
:
2345 case INDEX_op_ld_i64
:
2346 case INDEX_op_st8_i32
:
2347 case INDEX_op_st8_i64
:
2348 case INDEX_op_st16_i32
:
2349 case INDEX_op_st16_i64
:
2350 case INDEX_op_st_i32
:
2351 case INDEX_op_st32_i64
:
2352 case INDEX_op_st_i64
:
2355 case INDEX_op_add_i32
:
2356 case INDEX_op_add_i64
:
2358 case INDEX_op_sub_i32
:
2359 case INDEX_op_sub_i64
:
2360 case INDEX_op_and_i32
:
2361 case INDEX_op_and_i64
:
2362 case INDEX_op_or_i32
:
2363 case INDEX_op_or_i64
:
2364 case INDEX_op_xor_i32
:
2365 case INDEX_op_xor_i64
:
2366 return (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_ri
: &r_0_ri
);
2368 case INDEX_op_mul_i32
:
2369 /* If we have the general-instruction-extensions, then we have
2370 MULTIPLY SINGLE IMMEDIATE with a signed 32-bit, otherwise we
2371 have only MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
2372 return (s390_facilities
& FACILITY_GEN_INST_EXT
? &r_0_ri
: &r_0_rI
);
2373 case INDEX_op_mul_i64
:
2374 return (s390_facilities
& FACILITY_GEN_INST_EXT
? &r_0_rJ
: &r_0_rI
);
2376 case INDEX_op_shl_i32
:
2377 case INDEX_op_shr_i32
:
2378 case INDEX_op_sar_i32
:
2379 return (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_ri
: &r_0_ri
);
2381 case INDEX_op_shl_i64
:
2382 case INDEX_op_shr_i64
:
2383 case INDEX_op_sar_i64
:
2386 case INDEX_op_rotl_i32
:
2387 case INDEX_op_rotl_i64
:
2388 case INDEX_op_rotr_i32
:
2389 case INDEX_op_rotr_i64
:
2392 case INDEX_op_brcond_i32
:
2393 case INDEX_op_brcond_i64
:
2396 case INDEX_op_bswap16_i32
:
2397 case INDEX_op_bswap16_i64
:
2398 case INDEX_op_bswap32_i32
:
2399 case INDEX_op_bswap32_i64
:
2400 case INDEX_op_bswap64_i64
:
2401 case INDEX_op_neg_i32
:
2402 case INDEX_op_neg_i64
:
2403 case INDEX_op_ext8s_i32
:
2404 case INDEX_op_ext8s_i64
:
2405 case INDEX_op_ext8u_i32
:
2406 case INDEX_op_ext8u_i64
:
2407 case INDEX_op_ext16s_i32
:
2408 case INDEX_op_ext16s_i64
:
2409 case INDEX_op_ext16u_i32
:
2410 case INDEX_op_ext16u_i64
:
2411 case INDEX_op_ext32s_i64
:
2412 case INDEX_op_ext32u_i64
:
2413 case INDEX_op_ext_i32_i64
:
2414 case INDEX_op_extu_i32_i64
:
2415 case INDEX_op_extract_i32
:
2416 case INDEX_op_extract_i64
:
2419 case INDEX_op_clz_i64
:
2420 case INDEX_op_setcond_i32
:
2421 case INDEX_op_setcond_i64
:
2424 case INDEX_op_qemu_ld_i32
:
2425 case INDEX_op_qemu_ld_i64
:
2427 case INDEX_op_qemu_st_i64
:
2428 case INDEX_op_qemu_st_i32
:
2431 case INDEX_op_deposit_i32
:
2432 case INDEX_op_deposit_i64
:
2434 static const TCGTargetOpDef dep
2435 = { .args_ct_str
= { "r", "rZ", "r" } };
2438 case INDEX_op_movcond_i32
:
2439 case INDEX_op_movcond_i64
:
2441 static const TCGTargetOpDef movc
2442 = { .args_ct_str
= { "r", "r", "ri", "r", "0" } };
2443 static const TCGTargetOpDef movc_l
2444 = { .args_ct_str
= { "r", "r", "ri", "rI", "0" } };
2445 return (s390_facilities
& FACILITY_LOAD_ON_COND2
? &movc_l
: &movc
);
2447 case INDEX_op_div2_i32
:
2448 case INDEX_op_div2_i64
:
2449 case INDEX_op_divu2_i32
:
2450 case INDEX_op_divu2_i64
:
2452 static const TCGTargetOpDef div2
2453 = { .args_ct_str
= { "b", "a", "0", "1", "r" } };
2456 case INDEX_op_mulu2_i64
:
2458 static const TCGTargetOpDef mul2
2459 = { .args_ct_str
= { "b", "a", "0", "r" } };
2463 case INDEX_op_add2_i32
:
2464 case INDEX_op_sub2_i32
:
2465 return (s390_facilities
& FACILITY_EXT_IMM
? &a2_ri
: &a2_r
);
2466 case INDEX_op_add2_i64
:
2467 case INDEX_op_sub2_i64
:
2468 return (s390_facilities
& FACILITY_EXT_IMM
? &a2_rA
: &a2_r
);
2476 static void query_s390_facilities(void)
2478 unsigned long hwcap
= qemu_getauxval(AT_HWCAP
);
2480 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
2481 is present on all 64-bit systems, but let's check for it anyway. */
2482 if (hwcap
& HWCAP_S390_STFLE
) {
2483 register int r0
__asm__("0");
2484 register void *r1
__asm__("1");
2487 r1
= &s390_facilities
;
2488 asm volatile(".word 0xb2b0,0x1000"
2489 : "=r"(r0
) : "0"(0), "r"(r1
) : "memory", "cc");
2493 static void tcg_target_init(TCGContext
*s
)
2495 query_s390_facilities();
2497 tcg_target_available_regs
[TCG_TYPE_I32
] = 0xffff;
2498 tcg_target_available_regs
[TCG_TYPE_I64
] = 0xffff;
2500 tcg_target_call_clobber_regs
= 0;
2501 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R0
);
2502 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R1
);
2503 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R2
);
2504 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R3
);
2505 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R4
);
2506 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R5
);
2507 /* The r6 register is technically call-saved, but it's also a parameter
2508 register, so it can get killed by setup for the qemu_st helper. */
2509 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R6
);
2510 /* The return register can be considered call-clobbered. */
2511 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R14
);
2513 s
->reserved_regs
= 0;
2514 tcg_regset_set_reg(s
->reserved_regs
, TCG_TMP0
);
2515 /* XXX many insns can't be used with R0, so we better avoid it for now */
2516 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_R0
);
2517 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_CALL_STACK
);
2519 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_TB
);
2523 #define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
2524 + TCG_STATIC_CALL_ARGS_SIZE \
2525 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
2527 static void tcg_target_qemu_prologue(TCGContext
*s
)
2529 /* stmg %r6,%r15,48(%r15) (save registers) */
2530 tcg_out_insn(s
, RXY
, STMG
, TCG_REG_R6
, TCG_REG_R15
, TCG_REG_R15
, 48);
2532 /* aghi %r15,-frame_size */
2533 tcg_out_insn(s
, RI
, AGHI
, TCG_REG_R15
, -FRAME_SIZE
);
2535 tcg_set_frame(s
, TCG_REG_CALL_STACK
,
2536 TCG_STATIC_CALL_ARGS_SIZE
+ TCG_TARGET_CALL_STACK_OFFSET
,
2537 CPU_TEMP_BUF_NLONGS
* sizeof(long));
2539 #ifndef CONFIG_SOFTMMU
2540 if (guest_base
>= 0x80000) {
2541 tcg_out_movi_int(s
, TCG_TYPE_PTR
, TCG_GUEST_BASE_REG
, guest_base
, true);
2542 tcg_regset_set_reg(s
->reserved_regs
, TCG_GUEST_BASE_REG
);
2546 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_AREG0
, tcg_target_call_iarg_regs
[0]);
2548 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_REG_TB
,
2549 tcg_target_call_iarg_regs
[1]);
2552 /* br %r3 (go to TB) */
2553 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, tcg_target_call_iarg_regs
[1]);
2556 * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2557 * and fall through to the rest of the epilogue.
2559 s
->code_gen_epilogue
= s
->code_ptr
;
2560 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R2
, 0);
2563 tb_ret_addr
= s
->code_ptr
;
2565 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2566 tcg_out_insn(s
, RXY
, LMG
, TCG_REG_R6
, TCG_REG_R15
, TCG_REG_R15
,
2569 /* br %r14 (return) */
2570 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, TCG_REG_R14
);
2573 static void tcg_out_nop_fill(tcg_insn_unit
*p
, int count
)
2575 memset(p
, 0x07, count
* sizeof(tcg_insn_unit
));
2580 uint8_t fde_def_cfa
[4];
2581 uint8_t fde_reg_ofs
[18];
2584 /* We're expecting a 2 byte uleb128 encoded value. */
2585 QEMU_BUILD_BUG_ON(FRAME_SIZE
>= (1 << 14));
2587 #define ELF_HOST_MACHINE EM_S390
2589 static const DebugFrame debug_frame
= {
2590 .h
.cie
.len
= sizeof(DebugFrameCIE
)-4, /* length after .len member */
2593 .h
.cie
.code_align
= 1,
2594 .h
.cie
.data_align
= 8, /* sleb128 8 */
2595 .h
.cie
.return_column
= TCG_REG_R14
,
2597 /* Total FDE size does not include the "len" member. */
2598 .h
.fde
.len
= sizeof(DebugFrame
) - offsetof(DebugFrame
, h
.fde
.cie_offset
),
2601 12, TCG_REG_CALL_STACK
, /* DW_CFA_def_cfa %r15, ... */
2602 (FRAME_SIZE
& 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2606 0x86, 6, /* DW_CFA_offset, %r6, 48 */
2607 0x87, 7, /* DW_CFA_offset, %r7, 56 */
2608 0x88, 8, /* DW_CFA_offset, %r8, 64 */
2609 0x89, 9, /* DW_CFA_offset, %r92, 72 */
2610 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
2611 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
2612 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
2613 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
2614 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
2618 void tcg_register_jit(void *buf
, size_t buf_size
)
2620 tcg_register_jit_int(buf
, buf_size
, &debug_frame
, sizeof(debug_frame
));