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 #include "tcg-be-ldst.h"
29 /* We only support generating code for 64-bit mode. */
30 #if TCG_TARGET_REG_BITS != 64
31 #error "unsupported code generation mode"
36 /* ??? The translation blocks produced by TCG are generally small enough to
37 be entirely reachable with a 16-bit displacement. Leaving the option for
38 a 32-bit displacement here Just In Case. */
39 #define USE_LONG_BRANCHES 0
41 #define TCG_CT_CONST_MULI 0x100
42 #define TCG_CT_CONST_ORI 0x200
43 #define TCG_CT_CONST_XORI 0x400
44 #define TCG_CT_CONST_CMPI 0x800
45 #define TCG_CT_CONST_ADLI 0x1000
46 #define TCG_CT_CONST_ZERO 0x2000
48 /* Several places within the instruction set 0 means "no register"
49 rather than TCG_REG_R0. */
50 #define TCG_REG_NONE 0
52 /* A scratch register that may be be used throughout the backend. */
53 #define TCG_TMP0 TCG_REG_R1
55 #ifndef CONFIG_SOFTMMU
56 #define TCG_GUEST_BASE_REG TCG_REG_R13
59 /* All of the following instructions are prefixed with their instruction
60 format, and are defined as 8- or 16-bit quantities, even when the two
61 halves of the 16-bit quantity may appear 32 bits apart in the insn.
62 This makes it easy to copy the values from the tables in Appendix B. */
63 typedef enum S390Opcode
{
228 #ifdef CONFIG_DEBUG_TCG
229 static const char * const tcg_target_reg_names
[TCG_TARGET_NB_REGS
] = {
230 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
231 "%r8", "%r9", "%r10" "%r11" "%r12" "%r13" "%r14" "%r15"
235 /* Since R6 is a potential argument register, choose it last of the
236 call-saved registers. Likewise prefer the call-clobbered registers
237 in reverse order to maximize the chance of avoiding the arguments. */
238 static const int tcg_target_reg_alloc_order
[] = {
239 /* Call saved registers. */
248 /* Call clobbered registers. */
252 /* Argument registers, in reverse order of allocation. */
259 static const int tcg_target_call_iarg_regs
[] = {
267 static const int tcg_target_call_oarg_regs
[] = {
275 #define S390_CC_NE (S390_CC_LT | S390_CC_GT)
276 #define S390_CC_LE (S390_CC_LT | S390_CC_EQ)
277 #define S390_CC_GE (S390_CC_GT | S390_CC_EQ)
278 #define S390_CC_NEVER 0
279 #define S390_CC_ALWAYS 15
281 /* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
282 static const uint8_t tcg_cond_to_s390_cond
[] = {
283 [TCG_COND_EQ
] = S390_CC_EQ
,
284 [TCG_COND_NE
] = S390_CC_NE
,
285 [TCG_COND_LT
] = S390_CC_LT
,
286 [TCG_COND_LE
] = S390_CC_LE
,
287 [TCG_COND_GT
] = S390_CC_GT
,
288 [TCG_COND_GE
] = S390_CC_GE
,
289 [TCG_COND_LTU
] = S390_CC_LT
,
290 [TCG_COND_LEU
] = S390_CC_LE
,
291 [TCG_COND_GTU
] = S390_CC_GT
,
292 [TCG_COND_GEU
] = S390_CC_GE
,
295 /* Condition codes that result from a LOAD AND TEST. Here, we have no
296 unsigned instruction variation, however since the test is vs zero we
297 can re-map the outcomes appropriately. */
298 static const uint8_t tcg_cond_to_ltr_cond
[] = {
299 [TCG_COND_EQ
] = S390_CC_EQ
,
300 [TCG_COND_NE
] = S390_CC_NE
,
301 [TCG_COND_LT
] = S390_CC_LT
,
302 [TCG_COND_LE
] = S390_CC_LE
,
303 [TCG_COND_GT
] = S390_CC_GT
,
304 [TCG_COND_GE
] = S390_CC_GE
,
305 [TCG_COND_LTU
] = S390_CC_NEVER
,
306 [TCG_COND_LEU
] = S390_CC_EQ
,
307 [TCG_COND_GTU
] = S390_CC_NE
,
308 [TCG_COND_GEU
] = S390_CC_ALWAYS
,
311 #ifdef CONFIG_SOFTMMU
312 static void * const qemu_ld_helpers
[16] = {
313 [MO_UB
] = helper_ret_ldub_mmu
,
314 [MO_SB
] = helper_ret_ldsb_mmu
,
315 [MO_LEUW
] = helper_le_lduw_mmu
,
316 [MO_LESW
] = helper_le_ldsw_mmu
,
317 [MO_LEUL
] = helper_le_ldul_mmu
,
318 [MO_LESL
] = helper_le_ldsl_mmu
,
319 [MO_LEQ
] = helper_le_ldq_mmu
,
320 [MO_BEUW
] = helper_be_lduw_mmu
,
321 [MO_BESW
] = helper_be_ldsw_mmu
,
322 [MO_BEUL
] = helper_be_ldul_mmu
,
323 [MO_BESL
] = helper_be_ldsl_mmu
,
324 [MO_BEQ
] = helper_be_ldq_mmu
,
327 static void * const qemu_st_helpers
[16] = {
328 [MO_UB
] = helper_ret_stb_mmu
,
329 [MO_LEUW
] = helper_le_stw_mmu
,
330 [MO_LEUL
] = helper_le_stl_mmu
,
331 [MO_LEQ
] = helper_le_stq_mmu
,
332 [MO_BEUW
] = helper_be_stw_mmu
,
333 [MO_BEUL
] = helper_be_stl_mmu
,
334 [MO_BEQ
] = helper_be_stq_mmu
,
338 static tcg_insn_unit
*tb_ret_addr
;
339 uint64_t s390_facilities
;
341 static void patch_reloc(tcg_insn_unit
*code_ptr
, int type
,
342 intptr_t value
, intptr_t addend
)
344 intptr_t pcrel2
= (tcg_insn_unit
*)value
- (code_ptr
- 1);
345 tcg_debug_assert(addend
== -2);
349 tcg_debug_assert(pcrel2
== (int16_t)pcrel2
);
350 tcg_patch16(code_ptr
, pcrel2
);
353 tcg_debug_assert(pcrel2
== (int32_t)pcrel2
);
354 tcg_patch32(code_ptr
, pcrel2
);
362 /* parse target specific constraints */
363 static const char *target_parse_constraint(TCGArgConstraint
*ct
,
364 const char *ct_str
, TCGType type
)
367 case 'r': /* all registers */
368 ct
->ct
|= TCG_CT_REG
;
369 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
371 case 'L': /* qemu_ld/st constraint */
372 ct
->ct
|= TCG_CT_REG
;
373 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
374 tcg_regset_reset_reg (ct
->u
.regs
, TCG_REG_R2
);
375 tcg_regset_reset_reg (ct
->u
.regs
, TCG_REG_R3
);
376 tcg_regset_reset_reg (ct
->u
.regs
, TCG_REG_R4
);
378 case 'a': /* force R2 for division */
379 ct
->ct
|= TCG_CT_REG
;
380 tcg_regset_clear(ct
->u
.regs
);
381 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_R2
);
383 case 'b': /* force R3 for division */
384 ct
->ct
|= TCG_CT_REG
;
385 tcg_regset_clear(ct
->u
.regs
);
386 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_R3
);
389 ct
->ct
|= TCG_CT_CONST_ADLI
;
392 ct
->ct
|= TCG_CT_CONST_MULI
;
395 ct
->ct
|= TCG_CT_CONST_ORI
;
398 ct
->ct
|= TCG_CT_CONST_XORI
;
401 ct
->ct
|= TCG_CT_CONST_CMPI
;
404 ct
->ct
|= TCG_CT_CONST_ZERO
;
412 /* Immediates to be used with logical OR. This is an optimization only,
413 since a full 64-bit immediate OR can always be performed with 4 sequential
414 OI[LH][LH] instructions. What we're looking for is immediates that we
415 can load efficiently, and the immediate load plus the reg-reg OR is
416 smaller than the sequential OI's. */
418 static int tcg_match_ori(TCGType type
, tcg_target_long val
)
420 if (s390_facilities
& FACILITY_EXT_IMM
) {
421 if (type
== TCG_TYPE_I32
) {
422 /* All 32-bit ORs can be performed with 1 48-bit insn. */
427 /* Look for negative values. These are best to load with LGHI. */
429 if (val
== (int16_t)val
) {
432 if (s390_facilities
& FACILITY_EXT_IMM
) {
433 if (val
== (int32_t)val
) {
442 /* Immediates to be used with logical XOR. This is almost, but not quite,
443 only an optimization. XOR with immediate is only supported with the
444 extended-immediate facility. That said, there are a few patterns for
445 which it is better to load the value into a register first. */
447 static int tcg_match_xori(TCGType type
, tcg_target_long val
)
449 if ((s390_facilities
& FACILITY_EXT_IMM
) == 0) {
453 if (type
== TCG_TYPE_I32
) {
454 /* All 32-bit XORs can be performed with 1 48-bit insn. */
458 /* Look for negative values. These are best to load with LGHI. */
459 if (val
< 0 && val
== (int32_t)val
) {
466 /* Imediates to be used with comparisons. */
468 static int tcg_match_cmpi(TCGType type
, tcg_target_long val
)
470 if (s390_facilities
& FACILITY_EXT_IMM
) {
471 /* The COMPARE IMMEDIATE instruction is available. */
472 if (type
== TCG_TYPE_I32
) {
473 /* We have a 32-bit immediate and can compare against anything. */
476 /* ??? We have no insight here into whether the comparison is
477 signed or unsigned. The COMPARE IMMEDIATE insn uses a 32-bit
478 signed immediate, and the COMPARE LOGICAL IMMEDIATE insn uses
479 a 32-bit unsigned immediate. If we were to use the (semi)
480 obvious "val == (int32_t)val" we would be enabling unsigned
481 comparisons vs very large numbers. The only solution is to
482 take the intersection of the ranges. */
483 /* ??? Another possible solution is to simply lie and allow all
484 constants here and force the out-of-range values into a temp
485 register in tgen_cmp when we have knowledge of the actual
486 comparison code in use. */
487 return val
>= 0 && val
<= 0x7fffffff;
490 /* Only the LOAD AND TEST instruction is available. */
495 /* Immediates to be used with add2/sub2. */
497 static int tcg_match_add2i(TCGType type
, tcg_target_long val
)
499 if (s390_facilities
& FACILITY_EXT_IMM
) {
500 if (type
== TCG_TYPE_I32
) {
502 } else if (val
>= -0xffffffffll
&& val
<= 0xffffffffll
) {
509 /* Test if a constant matches the constraint. */
510 static int tcg_target_const_match(tcg_target_long val
, TCGType type
,
511 const TCGArgConstraint
*arg_ct
)
515 if (ct
& TCG_CT_CONST
) {
519 if (type
== TCG_TYPE_I32
) {
523 /* The following are mutually exclusive. */
524 if (ct
& TCG_CT_CONST_MULI
) {
525 /* Immediates that may be used with multiply. If we have the
526 general-instruction-extensions, then we have MULTIPLY SINGLE
527 IMMEDIATE with a signed 32-bit, otherwise we have only
528 MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
529 if (s390_facilities
& FACILITY_GEN_INST_EXT
) {
530 return val
== (int32_t)val
;
532 return val
== (int16_t)val
;
534 } else if (ct
& TCG_CT_CONST_ADLI
) {
535 return tcg_match_add2i(type
, val
);
536 } else if (ct
& TCG_CT_CONST_ORI
) {
537 return tcg_match_ori(type
, val
);
538 } else if (ct
& TCG_CT_CONST_XORI
) {
539 return tcg_match_xori(type
, val
);
540 } else if (ct
& TCG_CT_CONST_CMPI
) {
541 return tcg_match_cmpi(type
, val
);
542 } else if (ct
& TCG_CT_CONST_ZERO
) {
549 /* Emit instructions according to the given instruction format. */
551 static void tcg_out_insn_RR(TCGContext
*s
, S390Opcode op
, TCGReg r1
, TCGReg r2
)
553 tcg_out16(s
, (op
<< 8) | (r1
<< 4) | r2
);
556 static void tcg_out_insn_RRE(TCGContext
*s
, S390Opcode op
,
557 TCGReg r1
, TCGReg r2
)
559 tcg_out32(s
, (op
<< 16) | (r1
<< 4) | r2
);
562 static void tcg_out_insn_RRF(TCGContext
*s
, S390Opcode op
,
563 TCGReg r1
, TCGReg r2
, int m3
)
565 tcg_out32(s
, (op
<< 16) | (m3
<< 12) | (r1
<< 4) | r2
);
568 static void tcg_out_insn_RI(TCGContext
*s
, S390Opcode op
, TCGReg r1
, int i2
)
570 tcg_out32(s
, (op
<< 16) | (r1
<< 20) | (i2
& 0xffff));
573 static void tcg_out_insn_RIL(TCGContext
*s
, S390Opcode op
, TCGReg r1
, int i2
)
575 tcg_out16(s
, op
| (r1
<< 4));
579 static void tcg_out_insn_RS(TCGContext
*s
, S390Opcode op
, TCGReg r1
,
580 TCGReg b2
, TCGReg r3
, int disp
)
582 tcg_out32(s
, (op
<< 24) | (r1
<< 20) | (r3
<< 16) | (b2
<< 12)
586 static void tcg_out_insn_RSY(TCGContext
*s
, S390Opcode op
, TCGReg r1
,
587 TCGReg b2
, TCGReg r3
, int disp
)
589 tcg_out16(s
, (op
& 0xff00) | (r1
<< 4) | r3
);
590 tcg_out32(s
, (op
& 0xff) | (b2
<< 28)
591 | ((disp
& 0xfff) << 16) | ((disp
& 0xff000) >> 4));
594 #define tcg_out_insn_RX tcg_out_insn_RS
595 #define tcg_out_insn_RXY tcg_out_insn_RSY
597 /* Emit an opcode with "type-checking" of the format. */
598 #define tcg_out_insn(S, FMT, OP, ...) \
599 glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
602 /* emit 64-bit shifts */
603 static void tcg_out_sh64(TCGContext
* s
, S390Opcode op
, TCGReg dest
,
604 TCGReg src
, TCGReg sh_reg
, int sh_imm
)
606 tcg_out_insn_RSY(s
, op
, dest
, sh_reg
, src
, sh_imm
);
609 /* emit 32-bit shifts */
610 static void tcg_out_sh32(TCGContext
* s
, S390Opcode op
, TCGReg dest
,
611 TCGReg sh_reg
, int sh_imm
)
613 tcg_out_insn_RS(s
, op
, dest
, sh_reg
, 0, sh_imm
);
616 static void tcg_out_mov(TCGContext
*s
, TCGType type
, TCGReg dst
, TCGReg src
)
619 if (type
== TCG_TYPE_I32
) {
620 tcg_out_insn(s
, RR
, LR
, dst
, src
);
622 tcg_out_insn(s
, RRE
, LGR
, dst
, src
);
627 /* load a register with an immediate value */
628 static void tcg_out_movi(TCGContext
*s
, TCGType type
,
629 TCGReg ret
, tcg_target_long sval
)
631 static const S390Opcode lli_insns
[4] = {
632 RI_LLILL
, RI_LLILH
, RI_LLIHL
, RI_LLIHH
635 tcg_target_ulong uval
= sval
;
638 if (type
== TCG_TYPE_I32
) {
639 uval
= (uint32_t)sval
;
640 sval
= (int32_t)sval
;
643 /* Try all 32-bit insns that can load it in one go. */
644 if (sval
>= -0x8000 && sval
< 0x8000) {
645 tcg_out_insn(s
, RI
, LGHI
, ret
, sval
);
649 for (i
= 0; i
< 4; i
++) {
650 tcg_target_long mask
= 0xffffull
<< i
*16;
651 if ((uval
& mask
) == uval
) {
652 tcg_out_insn_RI(s
, lli_insns
[i
], ret
, uval
>> i
*16);
657 /* Try all 48-bit insns that can load it in one go. */
658 if (s390_facilities
& FACILITY_EXT_IMM
) {
659 if (sval
== (int32_t)sval
) {
660 tcg_out_insn(s
, RIL
, LGFI
, ret
, sval
);
663 if (uval
<= 0xffffffff) {
664 tcg_out_insn(s
, RIL
, LLILF
, ret
, uval
);
667 if ((uval
& 0xffffffff) == 0) {
668 tcg_out_insn(s
, RIL
, LLIHF
, ret
, uval
>> 31 >> 1);
673 /* Try for PC-relative address load. */
674 if ((sval
& 1) == 0) {
675 ptrdiff_t off
= tcg_pcrel_diff(s
, (void *)sval
) >> 1;
676 if (off
== (int32_t)off
) {
677 tcg_out_insn(s
, RIL
, LARL
, ret
, off
);
682 /* If extended immediates are not present, then we may have to issue
683 several instructions to load the low 32 bits. */
684 if (!(s390_facilities
& FACILITY_EXT_IMM
)) {
685 /* A 32-bit unsigned value can be loaded in 2 insns. And given
686 that the lli_insns loop above did not succeed, we know that
687 both insns are required. */
688 if (uval
<= 0xffffffff) {
689 tcg_out_insn(s
, RI
, LLILL
, ret
, uval
);
690 tcg_out_insn(s
, RI
, IILH
, ret
, uval
>> 16);
694 /* If all high bits are set, the value can be loaded in 2 or 3 insns.
695 We first want to make sure that all the high bits get set. With
696 luck the low 16-bits can be considered negative to perform that for
697 free, otherwise we load an explicit -1. */
698 if (sval
>> 31 >> 1 == -1) {
700 tcg_out_insn(s
, RI
, LGHI
, ret
, uval
);
702 tcg_out_insn(s
, RI
, LGHI
, ret
, -1);
703 tcg_out_insn(s
, RI
, IILL
, ret
, uval
);
705 tcg_out_insn(s
, RI
, IILH
, ret
, uval
>> 16);
710 /* If we get here, both the high and low parts have non-zero bits. */
712 /* Recurse to load the lower 32-bits. */
713 tcg_out_movi(s
, TCG_TYPE_I64
, ret
, uval
& 0xffffffff);
715 /* Insert data into the high 32-bits. */
716 uval
= uval
>> 31 >> 1;
717 if (s390_facilities
& FACILITY_EXT_IMM
) {
718 if (uval
< 0x10000) {
719 tcg_out_insn(s
, RI
, IIHL
, ret
, uval
);
720 } else if ((uval
& 0xffff) == 0) {
721 tcg_out_insn(s
, RI
, IIHH
, ret
, uval
>> 16);
723 tcg_out_insn(s
, RIL
, IIHF
, ret
, uval
);
727 tcg_out_insn(s
, RI
, IIHL
, ret
, uval
);
729 if (uval
& 0xffff0000) {
730 tcg_out_insn(s
, RI
, IIHH
, ret
, uval
>> 16);
736 /* Emit a load/store type instruction. Inputs are:
737 DATA: The register to be loaded or stored.
738 BASE+OFS: The effective address.
739 OPC_RX: If the operation has an RX format opcode (e.g. STC), otherwise 0.
740 OPC_RXY: The RXY format opcode for the operation (e.g. STCY). */
742 static void tcg_out_mem(TCGContext
*s
, S390Opcode opc_rx
, S390Opcode opc_rxy
,
743 TCGReg data
, TCGReg base
, TCGReg index
,
746 if (ofs
< -0x80000 || ofs
>= 0x80000) {
747 /* Combine the low 20 bits of the offset with the actual load insn;
748 the high 44 bits must come from an immediate load. */
749 tcg_target_long low
= ((ofs
& 0xfffff) ^ 0x80000) - 0x80000;
750 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_TMP0
, ofs
- low
);
753 /* If we were already given an index register, add it in. */
754 if (index
!= TCG_REG_NONE
) {
755 tcg_out_insn(s
, RRE
, AGR
, TCG_TMP0
, index
);
760 if (opc_rx
&& ofs
>= 0 && ofs
< 0x1000) {
761 tcg_out_insn_RX(s
, opc_rx
, data
, base
, index
, ofs
);
763 tcg_out_insn_RXY(s
, opc_rxy
, data
, base
, index
, ofs
);
768 /* load data without address translation or endianness conversion */
769 static inline void tcg_out_ld(TCGContext
*s
, TCGType type
, TCGReg data
,
770 TCGReg base
, intptr_t ofs
)
772 if (type
== TCG_TYPE_I32
) {
773 tcg_out_mem(s
, RX_L
, RXY_LY
, data
, base
, TCG_REG_NONE
, ofs
);
775 tcg_out_mem(s
, 0, RXY_LG
, data
, base
, TCG_REG_NONE
, ofs
);
779 static inline void tcg_out_st(TCGContext
*s
, TCGType type
, TCGReg data
,
780 TCGReg base
, intptr_t ofs
)
782 if (type
== TCG_TYPE_I32
) {
783 tcg_out_mem(s
, RX_ST
, RXY_STY
, data
, base
, TCG_REG_NONE
, ofs
);
785 tcg_out_mem(s
, 0, RXY_STG
, data
, base
, TCG_REG_NONE
, ofs
);
789 static inline bool tcg_out_sti(TCGContext
*s
, TCGType type
, TCGArg val
,
790 TCGReg base
, intptr_t ofs
)
795 /* load data from an absolute host address */
796 static void tcg_out_ld_abs(TCGContext
*s
, TCGType type
, TCGReg dest
, void *abs
)
798 intptr_t addr
= (intptr_t)abs
;
800 if ((s390_facilities
& FACILITY_GEN_INST_EXT
) && !(addr
& 1)) {
801 ptrdiff_t disp
= tcg_pcrel_diff(s
, abs
) >> 1;
802 if (disp
== (int32_t)disp
) {
803 if (type
== TCG_TYPE_I32
) {
804 tcg_out_insn(s
, RIL
, LRL
, dest
, disp
);
806 tcg_out_insn(s
, RIL
, LGRL
, dest
, disp
);
812 tcg_out_movi(s
, TCG_TYPE_PTR
, dest
, addr
& ~0xffff);
813 tcg_out_ld(s
, type
, dest
, dest
, addr
& 0xffff);
816 static inline void tcg_out_risbg(TCGContext
*s
, TCGReg dest
, TCGReg src
,
817 int msb
, int lsb
, int ofs
, int z
)
820 tcg_out16(s
, (RIE_RISBG
& 0xff00) | (dest
<< 4) | src
);
821 tcg_out16(s
, (msb
<< 8) | (z
<< 7) | lsb
);
822 tcg_out16(s
, (ofs
<< 8) | (RIE_RISBG
& 0xff));
825 static void tgen_ext8s(TCGContext
*s
, TCGType type
, TCGReg dest
, TCGReg src
)
827 if (s390_facilities
& FACILITY_EXT_IMM
) {
828 tcg_out_insn(s
, RRE
, LGBR
, dest
, src
);
832 if (type
== TCG_TYPE_I32
) {
834 tcg_out_sh32(s
, RS_SLL
, dest
, TCG_REG_NONE
, 24);
836 tcg_out_sh64(s
, RSY_SLLG
, dest
, src
, TCG_REG_NONE
, 24);
838 tcg_out_sh32(s
, RS_SRA
, dest
, TCG_REG_NONE
, 24);
840 tcg_out_sh64(s
, RSY_SLLG
, dest
, src
, TCG_REG_NONE
, 56);
841 tcg_out_sh64(s
, RSY_SRAG
, dest
, dest
, TCG_REG_NONE
, 56);
845 static void tgen_ext8u(TCGContext
*s
, TCGType type
, TCGReg dest
, TCGReg src
)
847 if (s390_facilities
& FACILITY_EXT_IMM
) {
848 tcg_out_insn(s
, RRE
, LLGCR
, dest
, src
);
853 tcg_out_movi(s
, type
, TCG_TMP0
, 0xff);
856 tcg_out_movi(s
, type
, dest
, 0xff);
858 if (type
== TCG_TYPE_I32
) {
859 tcg_out_insn(s
, RR
, NR
, dest
, src
);
861 tcg_out_insn(s
, RRE
, NGR
, dest
, src
);
865 static void tgen_ext16s(TCGContext
*s
, TCGType type
, TCGReg dest
, TCGReg src
)
867 if (s390_facilities
& FACILITY_EXT_IMM
) {
868 tcg_out_insn(s
, RRE
, LGHR
, dest
, src
);
872 if (type
== TCG_TYPE_I32
) {
874 tcg_out_sh32(s
, RS_SLL
, dest
, TCG_REG_NONE
, 16);
876 tcg_out_sh64(s
, RSY_SLLG
, dest
, src
, TCG_REG_NONE
, 16);
878 tcg_out_sh32(s
, RS_SRA
, dest
, TCG_REG_NONE
, 16);
880 tcg_out_sh64(s
, RSY_SLLG
, dest
, src
, TCG_REG_NONE
, 48);
881 tcg_out_sh64(s
, RSY_SRAG
, dest
, dest
, TCG_REG_NONE
, 48);
885 static void tgen_ext16u(TCGContext
*s
, TCGType type
, TCGReg dest
, TCGReg src
)
887 if (s390_facilities
& FACILITY_EXT_IMM
) {
888 tcg_out_insn(s
, RRE
, LLGHR
, dest
, src
);
893 tcg_out_movi(s
, type
, TCG_TMP0
, 0xffff);
896 tcg_out_movi(s
, type
, dest
, 0xffff);
898 if (type
== TCG_TYPE_I32
) {
899 tcg_out_insn(s
, RR
, NR
, dest
, src
);
901 tcg_out_insn(s
, RRE
, NGR
, dest
, src
);
905 static inline void tgen_ext32s(TCGContext
*s
, TCGReg dest
, TCGReg src
)
907 tcg_out_insn(s
, RRE
, LGFR
, dest
, src
);
910 static inline void tgen_ext32u(TCGContext
*s
, TCGReg dest
, TCGReg src
)
912 tcg_out_insn(s
, RRE
, LLGFR
, dest
, src
);
915 /* Accept bit patterns like these:
920 Copied from gcc sources. */
921 static inline bool risbg_mask(uint64_t c
)
924 /* We don't change the number of transitions by inverting,
925 so make sure we start with the LSB zero. */
929 /* Reject all zeros or all ones. */
933 /* Find the first transition. */
935 /* Invert to look for a second transition. */
937 /* Erase the first transition. */
939 /* Find the second transition, if any. */
941 /* Match if all the bits are 1's, or if c is zero. */
945 static void tgen_andi_risbg(TCGContext
*s
, TCGReg out
, TCGReg in
, uint64_t val
)
948 if ((val
& 0x8000000000000001ull
) == 0x8000000000000001ull
) {
949 /* Achieve wraparound by swapping msb and lsb. */
950 msb
= 64 - ctz64(~val
);
951 lsb
= clz64(~val
) - 1;
954 lsb
= 63 - ctz64(val
);
956 tcg_out_risbg(s
, out
, in
, msb
, lsb
, 0, 1);
959 static void tgen_andi(TCGContext
*s
, TCGType type
, TCGReg dest
, uint64_t val
)
961 static const S390Opcode ni_insns
[4] = {
962 RI_NILL
, RI_NILH
, RI_NIHL
, RI_NIHH
964 static const S390Opcode nif_insns
[2] = {
967 uint64_t valid
= (type
== TCG_TYPE_I32
? 0xffffffffull
: -1ull);
970 /* Look for the zero-extensions. */
971 if ((val
& valid
) == 0xffffffff) {
972 tgen_ext32u(s
, dest
, dest
);
975 if (s390_facilities
& FACILITY_EXT_IMM
) {
976 if ((val
& valid
) == 0xff) {
977 tgen_ext8u(s
, TCG_TYPE_I64
, dest
, dest
);
980 if ((val
& valid
) == 0xffff) {
981 tgen_ext16u(s
, TCG_TYPE_I64
, dest
, dest
);
986 /* Try all 32-bit insns that can perform it in one go. */
987 for (i
= 0; i
< 4; i
++) {
988 tcg_target_ulong mask
= ~(0xffffull
<< i
*16);
989 if (((val
| ~valid
) & mask
) == mask
) {
990 tcg_out_insn_RI(s
, ni_insns
[i
], dest
, val
>> i
*16);
995 /* Try all 48-bit insns that can perform it in one go. */
996 if (s390_facilities
& FACILITY_EXT_IMM
) {
997 for (i
= 0; i
< 2; i
++) {
998 tcg_target_ulong mask
= ~(0xffffffffull
<< i
*32);
999 if (((val
| ~valid
) & mask
) == mask
) {
1000 tcg_out_insn_RIL(s
, nif_insns
[i
], dest
, val
>> i
*32);
1005 if ((s390_facilities
& FACILITY_GEN_INST_EXT
) && risbg_mask(val
)) {
1006 tgen_andi_risbg(s
, dest
, dest
, val
);
1010 /* Fall back to loading the constant. */
1011 tcg_out_movi(s
, type
, TCG_TMP0
, val
);
1012 if (type
== TCG_TYPE_I32
) {
1013 tcg_out_insn(s
, RR
, NR
, dest
, TCG_TMP0
);
1015 tcg_out_insn(s
, RRE
, NGR
, dest
, TCG_TMP0
);
1019 static void tgen64_ori(TCGContext
*s
, TCGReg dest
, tcg_target_ulong val
)
1021 static const S390Opcode oi_insns
[4] = {
1022 RI_OILL
, RI_OILH
, RI_OIHL
, RI_OIHH
1024 static const S390Opcode nif_insns
[2] = {
1030 /* Look for no-op. */
1035 if (s390_facilities
& FACILITY_EXT_IMM
) {
1036 /* Try all 32-bit insns that can perform it in one go. */
1037 for (i
= 0; i
< 4; i
++) {
1038 tcg_target_ulong mask
= (0xffffull
<< i
*16);
1039 if ((val
& mask
) != 0 && (val
& ~mask
) == 0) {
1040 tcg_out_insn_RI(s
, oi_insns
[i
], dest
, val
>> i
*16);
1045 /* Try all 48-bit insns that can perform it in one go. */
1046 for (i
= 0; i
< 2; i
++) {
1047 tcg_target_ulong mask
= (0xffffffffull
<< i
*32);
1048 if ((val
& mask
) != 0 && (val
& ~mask
) == 0) {
1049 tcg_out_insn_RIL(s
, nif_insns
[i
], dest
, val
>> i
*32);
1054 /* Perform the OR via sequential modifications to the high and
1055 low parts. Do this via recursion to handle 16-bit vs 32-bit
1056 masks in each half. */
1057 tgen64_ori(s
, dest
, val
& 0x00000000ffffffffull
);
1058 tgen64_ori(s
, dest
, val
& 0xffffffff00000000ull
);
1060 /* With no extended-immediate facility, we don't need to be so
1061 clever. Just iterate over the insns and mask in the constant. */
1062 for (i
= 0; i
< 4; i
++) {
1063 tcg_target_ulong mask
= (0xffffull
<< i
*16);
1064 if ((val
& mask
) != 0) {
1065 tcg_out_insn_RI(s
, oi_insns
[i
], dest
, val
>> i
*16);
1071 static void tgen64_xori(TCGContext
*s
, TCGReg dest
, tcg_target_ulong val
)
1073 /* Perform the xor by parts. */
1074 if (val
& 0xffffffff) {
1075 tcg_out_insn(s
, RIL
, XILF
, dest
, val
);
1077 if (val
> 0xffffffff) {
1078 tcg_out_insn(s
, RIL
, XIHF
, dest
, val
>> 31 >> 1);
1082 static int tgen_cmp(TCGContext
*s
, TCGType type
, TCGCond c
, TCGReg r1
,
1083 TCGArg c2
, bool c2const
, bool need_carry
)
1085 bool is_unsigned
= is_unsigned_cond(c
);
1088 if (!(is_unsigned
&& need_carry
)) {
1089 if (type
== TCG_TYPE_I32
) {
1090 tcg_out_insn(s
, RR
, LTR
, r1
, r1
);
1092 tcg_out_insn(s
, RRE
, LTGR
, r1
, r1
);
1094 return tcg_cond_to_ltr_cond
[c
];
1096 /* If we only got here because of load-and-test,
1097 and we couldn't use that, then we need to load
1098 the constant into a register. */
1099 if (!(s390_facilities
& FACILITY_EXT_IMM
)) {
1101 tcg_out_movi(s
, type
, c2
, 0);
1106 if (type
== TCG_TYPE_I32
) {
1107 tcg_out_insn(s
, RIL
, CLFI
, r1
, c2
);
1109 tcg_out_insn(s
, RIL
, CLGFI
, r1
, c2
);
1112 if (type
== TCG_TYPE_I32
) {
1113 tcg_out_insn(s
, RIL
, CFI
, r1
, c2
);
1115 tcg_out_insn(s
, RIL
, CGFI
, r1
, c2
);
1121 if (type
== TCG_TYPE_I32
) {
1122 tcg_out_insn(s
, RR
, CLR
, r1
, c2
);
1124 tcg_out_insn(s
, RRE
, CLGR
, r1
, c2
);
1127 if (type
== TCG_TYPE_I32
) {
1128 tcg_out_insn(s
, RR
, CR
, r1
, c2
);
1130 tcg_out_insn(s
, RRE
, CGR
, r1
, c2
);
1134 return tcg_cond_to_s390_cond
[c
];
1137 static void tgen_setcond(TCGContext
*s
, TCGType type
, TCGCond cond
,
1138 TCGReg dest
, TCGReg c1
, TCGArg c2
, int c2const
)
1146 /* The result of a compare has CC=2 for GT and CC=3 unused.
1147 ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */
1148 tgen_cmp(s
, type
, cond
, c1
, c2
, c2const
, true);
1149 tcg_out_movi(s
, type
, dest
, 0);
1150 tcg_out_insn(s
, RRE
, ALCGR
, dest
, dest
);
1155 /* We need "real" carry semantics, so use SUBTRACT LOGICAL
1156 instead of COMPARE LOGICAL. This needs an extra move. */
1157 tcg_out_mov(s
, type
, TCG_TMP0
, c1
);
1159 tcg_out_movi(s
, TCG_TYPE_I64
, dest
, 0);
1160 if (type
== TCG_TYPE_I32
) {
1161 tcg_out_insn(s
, RIL
, SLFI
, TCG_TMP0
, c2
);
1163 tcg_out_insn(s
, RIL
, SLGFI
, TCG_TMP0
, c2
);
1166 if (type
== TCG_TYPE_I32
) {
1167 tcg_out_insn(s
, RR
, SLR
, TCG_TMP0
, c2
);
1169 tcg_out_insn(s
, RRE
, SLGR
, TCG_TMP0
, c2
);
1171 tcg_out_movi(s
, TCG_TYPE_I64
, dest
, 0);
1173 tcg_out_insn(s
, RRE
, ALCGR
, dest
, dest
);
1179 /* Swap operands so that we can use GEU/GTU/GT. */
1181 tcg_out_movi(s
, type
, TCG_TMP0
, c2
);
1190 if (cond
== TCG_COND_LEU
) {
1193 cond
= tcg_swap_cond(cond
);
1197 /* X != 0 is X > 0. */
1198 if (c2const
&& c2
== 0) {
1199 cond
= TCG_COND_GTU
;
1205 /* X == 0 is X <= 0 is 0 >= X. */
1206 if (c2const
&& c2
== 0) {
1207 tcg_out_movi(s
, TCG_TYPE_I64
, TCG_TMP0
, 0);
1219 cc
= tgen_cmp(s
, type
, cond
, c1
, c2
, c2const
, false);
1220 if (s390_facilities
& FACILITY_LOAD_ON_COND
) {
1221 /* Emit: d = 0, t = 1, d = (cc ? t : d). */
1222 tcg_out_movi(s
, TCG_TYPE_I64
, dest
, 0);
1223 tcg_out_movi(s
, TCG_TYPE_I64
, TCG_TMP0
, 1);
1224 tcg_out_insn(s
, RRF
, LOCGR
, dest
, TCG_TMP0
, cc
);
1226 /* Emit: d = 1; if (cc) goto over; d = 0; over: */
1227 tcg_out_movi(s
, type
, dest
, 1);
1228 tcg_out_insn(s
, RI
, BRC
, cc
, (4 + 4) >> 1);
1229 tcg_out_movi(s
, type
, dest
, 0);
1233 static void tgen_movcond(TCGContext
*s
, TCGType type
, TCGCond c
, TCGReg dest
,
1234 TCGReg c1
, TCGArg c2
, int c2const
, TCGReg r3
)
1237 if (s390_facilities
& FACILITY_LOAD_ON_COND
) {
1238 cc
= tgen_cmp(s
, type
, c
, c1
, c2
, c2const
, false);
1239 tcg_out_insn(s
, RRF
, LOCGR
, dest
, r3
, cc
);
1241 c
= tcg_invert_cond(c
);
1242 cc
= tgen_cmp(s
, type
, c
, c1
, c2
, c2const
, false);
1244 /* Emit: if (cc) goto over; dest = r3; over: */
1245 tcg_out_insn(s
, RI
, BRC
, cc
, (4 + 4) >> 1);
1246 tcg_out_insn(s
, RRE
, LGR
, dest
, r3
);
1250 static void tgen_clz(TCGContext
*s
, TCGReg dest
, TCGReg a1
,
1251 TCGArg a2
, int a2const
)
1253 /* Since this sets both R and R+1, we have no choice but to store the
1254 result into R0, allowing R1 == TCG_TMP0 to be clobbered as well. */
1255 QEMU_BUILD_BUG_ON(TCG_TMP0
!= TCG_REG_R1
);
1256 tcg_out_insn(s
, RRE
, FLOGR
, TCG_REG_R0
, a1
);
1258 if (a2const
&& a2
== 64) {
1259 tcg_out_mov(s
, TCG_TYPE_I64
, dest
, TCG_REG_R0
);
1262 tcg_out_movi(s
, TCG_TYPE_I64
, dest
, a2
);
1264 tcg_out_mov(s
, TCG_TYPE_I64
, dest
, a2
);
1266 if (s390_facilities
& FACILITY_LOAD_ON_COND
) {
1267 /* Emit: if (one bit found) dest = r0. */
1268 tcg_out_insn(s
, RRF
, LOCGR
, dest
, TCG_REG_R0
, 2);
1270 /* Emit: if (no one bit found) goto over; dest = r0; over: */
1271 tcg_out_insn(s
, RI
, BRC
, 8, (4 + 4) >> 1);
1272 tcg_out_insn(s
, RRE
, LGR
, dest
, TCG_REG_R0
);
1277 static void tgen_deposit(TCGContext
*s
, TCGReg dest
, TCGReg src
,
1278 int ofs
, int len
, int z
)
1280 int lsb
= (63 - ofs
);
1281 int msb
= lsb
- (len
- 1);
1282 tcg_out_risbg(s
, dest
, src
, msb
, lsb
, ofs
, z
);
1285 static void tgen_extract(TCGContext
*s
, TCGReg dest
, TCGReg src
,
1288 tcg_out_risbg(s
, dest
, src
, 64 - len
, 63, 64 - ofs
, 1);
1291 static void tgen_gotoi(TCGContext
*s
, int cc
, tcg_insn_unit
*dest
)
1293 ptrdiff_t off
= dest
- s
->code_ptr
;
1294 if (off
== (int16_t)off
) {
1295 tcg_out_insn(s
, RI
, BRC
, cc
, off
);
1296 } else if (off
== (int32_t)off
) {
1297 tcg_out_insn(s
, RIL
, BRCL
, cc
, off
);
1299 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_TMP0
, (uintptr_t)dest
);
1300 tcg_out_insn(s
, RR
, BCR
, cc
, TCG_TMP0
);
1304 static void tgen_branch(TCGContext
*s
, int cc
, TCGLabel
*l
)
1307 tgen_gotoi(s
, cc
, l
->u
.value_ptr
);
1308 } else if (USE_LONG_BRANCHES
) {
1309 tcg_out16(s
, RIL_BRCL
| (cc
<< 4));
1310 tcg_out_reloc(s
, s
->code_ptr
, R_390_PC32DBL
, l
, -2);
1313 tcg_out16(s
, RI_BRC
| (cc
<< 4));
1314 tcg_out_reloc(s
, s
->code_ptr
, R_390_PC16DBL
, l
, -2);
1319 static void tgen_compare_branch(TCGContext
*s
, S390Opcode opc
, int cc
,
1320 TCGReg r1
, TCGReg r2
, TCGLabel
*l
)
1325 off
= l
->u
.value_ptr
- s
->code_ptr
;
1327 /* We need to keep the offset unchanged for retranslation. */
1328 off
= s
->code_ptr
[1];
1329 tcg_out_reloc(s
, s
->code_ptr
+ 1, R_390_PC16DBL
, l
, -2);
1332 tcg_out16(s
, (opc
& 0xff00) | (r1
<< 4) | r2
);
1334 tcg_out16(s
, cc
<< 12 | (opc
& 0xff));
1337 static void tgen_compare_imm_branch(TCGContext
*s
, S390Opcode opc
, int cc
,
1338 TCGReg r1
, int i2
, TCGLabel
*l
)
1340 tcg_target_long off
;
1343 off
= l
->u
.value_ptr
- s
->code_ptr
;
1345 /* We need to keep the offset unchanged for retranslation. */
1346 off
= s
->code_ptr
[1];
1347 tcg_out_reloc(s
, s
->code_ptr
+ 1, R_390_PC16DBL
, l
, -2);
1350 tcg_out16(s
, (opc
& 0xff00) | (r1
<< 4) | cc
);
1352 tcg_out16(s
, (i2
<< 8) | (opc
& 0xff));
1355 static void tgen_brcond(TCGContext
*s
, TCGType type
, TCGCond c
,
1356 TCGReg r1
, TCGArg c2
, int c2const
, TCGLabel
*l
)
1360 if (s390_facilities
& FACILITY_GEN_INST_EXT
) {
1361 bool is_unsigned
= is_unsigned_cond(c
);
1365 cc
= tcg_cond_to_s390_cond
[c
];
1368 opc
= (type
== TCG_TYPE_I32
1369 ? (is_unsigned
? RIE_CLRJ
: RIE_CRJ
)
1370 : (is_unsigned
? RIE_CLGRJ
: RIE_CGRJ
));
1371 tgen_compare_branch(s
, opc
, cc
, r1
, c2
, l
);
1375 /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1376 If the immediate we've been given does not fit that range, we'll
1377 fall back to separate compare and branch instructions using the
1378 larger comparison range afforded by COMPARE IMMEDIATE. */
1379 if (type
== TCG_TYPE_I32
) {
1382 in_range
= (uint32_t)c2
== (uint8_t)c2
;
1385 in_range
= (int32_t)c2
== (int8_t)c2
;
1390 in_range
= (uint64_t)c2
== (uint8_t)c2
;
1393 in_range
= (int64_t)c2
== (int8_t)c2
;
1397 tgen_compare_imm_branch(s
, opc
, cc
, r1
, c2
, l
);
1402 cc
= tgen_cmp(s
, type
, c
, r1
, c2
, c2const
, false);
1403 tgen_branch(s
, cc
, l
);
1406 static void tcg_out_call(TCGContext
*s
, tcg_insn_unit
*dest
)
1408 ptrdiff_t off
= dest
- s
->code_ptr
;
1409 if (off
== (int32_t)off
) {
1410 tcg_out_insn(s
, RIL
, BRASL
, TCG_REG_R14
, off
);
1412 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_TMP0
, (uintptr_t)dest
);
1413 tcg_out_insn(s
, RR
, BASR
, TCG_REG_R14
, TCG_TMP0
);
1417 static void tcg_out_qemu_ld_direct(TCGContext
*s
, TCGMemOp opc
, TCGReg data
,
1418 TCGReg base
, TCGReg index
, int disp
)
1420 switch (opc
& (MO_SSIZE
| MO_BSWAP
)) {
1422 tcg_out_insn(s
, RXY
, LLGC
, data
, base
, index
, disp
);
1425 tcg_out_insn(s
, RXY
, LGB
, data
, base
, index
, disp
);
1428 case MO_UW
| MO_BSWAP
:
1429 /* swapped unsigned halfword load with upper bits zeroed */
1430 tcg_out_insn(s
, RXY
, LRVH
, data
, base
, index
, disp
);
1431 tgen_ext16u(s
, TCG_TYPE_I64
, data
, data
);
1434 tcg_out_insn(s
, RXY
, LLGH
, data
, base
, index
, disp
);
1437 case MO_SW
| MO_BSWAP
:
1438 /* swapped sign-extended halfword load */
1439 tcg_out_insn(s
, RXY
, LRVH
, data
, base
, index
, disp
);
1440 tgen_ext16s(s
, TCG_TYPE_I64
, data
, data
);
1443 tcg_out_insn(s
, RXY
, LGH
, data
, base
, index
, disp
);
1446 case MO_UL
| MO_BSWAP
:
1447 /* swapped unsigned int load with upper bits zeroed */
1448 tcg_out_insn(s
, RXY
, LRV
, data
, base
, index
, disp
);
1449 tgen_ext32u(s
, data
, data
);
1452 tcg_out_insn(s
, RXY
, LLGF
, data
, base
, index
, disp
);
1455 case MO_SL
| MO_BSWAP
:
1456 /* swapped sign-extended int load */
1457 tcg_out_insn(s
, RXY
, LRV
, data
, base
, index
, disp
);
1458 tgen_ext32s(s
, data
, data
);
1461 tcg_out_insn(s
, RXY
, LGF
, data
, base
, index
, disp
);
1464 case MO_Q
| MO_BSWAP
:
1465 tcg_out_insn(s
, RXY
, LRVG
, data
, base
, index
, disp
);
1468 tcg_out_insn(s
, RXY
, LG
, data
, base
, index
, disp
);
1476 static void tcg_out_qemu_st_direct(TCGContext
*s
, TCGMemOp opc
, TCGReg data
,
1477 TCGReg base
, TCGReg index
, int disp
)
1479 switch (opc
& (MO_SIZE
| MO_BSWAP
)) {
1481 if (disp
>= 0 && disp
< 0x1000) {
1482 tcg_out_insn(s
, RX
, STC
, data
, base
, index
, disp
);
1484 tcg_out_insn(s
, RXY
, STCY
, data
, base
, index
, disp
);
1488 case MO_UW
| MO_BSWAP
:
1489 tcg_out_insn(s
, RXY
, STRVH
, data
, base
, index
, disp
);
1492 if (disp
>= 0 && disp
< 0x1000) {
1493 tcg_out_insn(s
, RX
, STH
, data
, base
, index
, disp
);
1495 tcg_out_insn(s
, RXY
, STHY
, data
, base
, index
, disp
);
1499 case MO_UL
| MO_BSWAP
:
1500 tcg_out_insn(s
, RXY
, STRV
, data
, base
, index
, disp
);
1503 if (disp
>= 0 && disp
< 0x1000) {
1504 tcg_out_insn(s
, RX
, ST
, data
, base
, index
, disp
);
1506 tcg_out_insn(s
, RXY
, STY
, data
, base
, index
, disp
);
1510 case MO_Q
| MO_BSWAP
:
1511 tcg_out_insn(s
, RXY
, STRVG
, data
, base
, index
, disp
);
1514 tcg_out_insn(s
, RXY
, STG
, data
, base
, index
, disp
);
1522 #if defined(CONFIG_SOFTMMU)
1523 /* We're expecting to use a 20-bit signed offset on the tlb memory ops.
1524 Using the offset of the second entry in the last tlb table ensures
1525 that we can index all of the elements of the first entry. */
1526 QEMU_BUILD_BUG_ON(offsetof(CPUArchState
, tlb_table
[NB_MMU_MODES
- 1][1])
1529 /* Load and compare a TLB entry, leaving the flags set. Loads the TLB
1530 addend into R2. Returns a register with the santitized guest address. */
1531 static TCGReg
tcg_out_tlb_read(TCGContext
* s
, TCGReg addr_reg
, TCGMemOp opc
,
1532 int mem_index
, bool is_ld
)
1534 unsigned s_bits
= opc
& MO_SIZE
;
1535 unsigned a_bits
= get_alignment_bits(opc
);
1536 unsigned s_mask
= (1 << s_bits
) - 1;
1537 unsigned a_mask
= (1 << a_bits
) - 1;
1541 /* For aligned accesses, we check the first byte and include the alignment
1542 bits within the address. For unaligned access, we check that we don't
1543 cross pages using the address of the last byte of the access. */
1544 a_off
= (a_bits
>= s_bits
? 0 : s_mask
- a_mask
);
1545 tlb_mask
= (uint64_t)TARGET_PAGE_MASK
| a_mask
;
1547 if (s390_facilities
& FACILITY_GEN_INST_EXT
) {
1548 tcg_out_risbg(s
, TCG_REG_R2
, addr_reg
,
1549 64 - CPU_TLB_BITS
- CPU_TLB_ENTRY_BITS
,
1550 63 - CPU_TLB_ENTRY_BITS
,
1551 64 + CPU_TLB_ENTRY_BITS
- TARGET_PAGE_BITS
, 1);
1553 tcg_out_insn(s
, RX
, LA
, TCG_REG_R3
, addr_reg
, TCG_REG_NONE
, a_off
);
1554 tgen_andi(s
, TCG_TYPE_TL
, TCG_REG_R3
, tlb_mask
);
1556 tgen_andi_risbg(s
, TCG_REG_R3
, addr_reg
, tlb_mask
);
1559 tcg_out_sh64(s
, RSY_SRLG
, TCG_REG_R2
, addr_reg
, TCG_REG_NONE
,
1560 TARGET_PAGE_BITS
- CPU_TLB_ENTRY_BITS
);
1561 tcg_out_insn(s
, RX
, LA
, TCG_REG_R3
, addr_reg
, TCG_REG_NONE
, a_off
);
1562 tgen_andi(s
, TCG_TYPE_I64
, TCG_REG_R2
,
1563 (CPU_TLB_SIZE
- 1) << CPU_TLB_ENTRY_BITS
);
1564 tgen_andi(s
, TCG_TYPE_TL
, TCG_REG_R3
, tlb_mask
);
1568 ofs
= offsetof(CPUArchState
, tlb_table
[mem_index
][0].addr_read
);
1570 ofs
= offsetof(CPUArchState
, tlb_table
[mem_index
][0].addr_write
);
1572 if (TARGET_LONG_BITS
== 32) {
1573 tcg_out_mem(s
, RX_C
, RXY_CY
, TCG_REG_R3
, TCG_REG_R2
, TCG_AREG0
, ofs
);
1575 tcg_out_mem(s
, 0, RXY_CG
, TCG_REG_R3
, TCG_REG_R2
, TCG_AREG0
, ofs
);
1578 ofs
= offsetof(CPUArchState
, tlb_table
[mem_index
][0].addend
);
1579 tcg_out_mem(s
, 0, RXY_LG
, TCG_REG_R2
, TCG_REG_R2
, TCG_AREG0
, ofs
);
1581 if (TARGET_LONG_BITS
== 32) {
1582 tgen_ext32u(s
, TCG_REG_R3
, addr_reg
);
1588 static void add_qemu_ldst_label(TCGContext
*s
, bool is_ld
, TCGMemOpIdx oi
,
1589 TCGReg data
, TCGReg addr
,
1590 tcg_insn_unit
*raddr
, tcg_insn_unit
*label_ptr
)
1592 TCGLabelQemuLdst
*label
= new_ldst_label(s
);
1594 label
->is_ld
= is_ld
;
1596 label
->datalo_reg
= data
;
1597 label
->addrlo_reg
= addr
;
1598 label
->raddr
= raddr
;
1599 label
->label_ptr
[0] = label_ptr
;
1602 static void tcg_out_qemu_ld_slow_path(TCGContext
*s
, TCGLabelQemuLdst
*lb
)
1604 TCGReg addr_reg
= lb
->addrlo_reg
;
1605 TCGReg data_reg
= lb
->datalo_reg
;
1606 TCGMemOpIdx oi
= lb
->oi
;
1607 TCGMemOp opc
= get_memop(oi
);
1609 patch_reloc(lb
->label_ptr
[0], R_390_PC16DBL
, (intptr_t)s
->code_ptr
, -2);
1611 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_REG_R2
, TCG_AREG0
);
1612 if (TARGET_LONG_BITS
== 64) {
1613 tcg_out_mov(s
, TCG_TYPE_I64
, TCG_REG_R3
, addr_reg
);
1615 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_R4
, oi
);
1616 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R5
, (uintptr_t)lb
->raddr
);
1617 tcg_out_call(s
, qemu_ld_helpers
[opc
& (MO_BSWAP
| MO_SSIZE
)]);
1618 tcg_out_mov(s
, TCG_TYPE_I64
, data_reg
, TCG_REG_R2
);
1620 tgen_gotoi(s
, S390_CC_ALWAYS
, lb
->raddr
);
1623 static void tcg_out_qemu_st_slow_path(TCGContext
*s
, TCGLabelQemuLdst
*lb
)
1625 TCGReg addr_reg
= lb
->addrlo_reg
;
1626 TCGReg data_reg
= lb
->datalo_reg
;
1627 TCGMemOpIdx oi
= lb
->oi
;
1628 TCGMemOp opc
= get_memop(oi
);
1630 patch_reloc(lb
->label_ptr
[0], R_390_PC16DBL
, (intptr_t)s
->code_ptr
, -2);
1632 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_REG_R2
, TCG_AREG0
);
1633 if (TARGET_LONG_BITS
== 64) {
1634 tcg_out_mov(s
, TCG_TYPE_I64
, TCG_REG_R3
, addr_reg
);
1636 switch (opc
& MO_SIZE
) {
1638 tgen_ext8u(s
, TCG_TYPE_I64
, TCG_REG_R4
, data_reg
);
1641 tgen_ext16u(s
, TCG_TYPE_I64
, TCG_REG_R4
, data_reg
);
1644 tgen_ext32u(s
, TCG_REG_R4
, data_reg
);
1647 tcg_out_mov(s
, TCG_TYPE_I64
, TCG_REG_R4
, data_reg
);
1652 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_R5
, oi
);
1653 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R6
, (uintptr_t)lb
->raddr
);
1654 tcg_out_call(s
, qemu_st_helpers
[opc
& (MO_BSWAP
| MO_SIZE
)]);
1656 tgen_gotoi(s
, S390_CC_ALWAYS
, lb
->raddr
);
1659 static void tcg_prepare_user_ldst(TCGContext
*s
, TCGReg
*addr_reg
,
1660 TCGReg
*index_reg
, tcg_target_long
*disp
)
1662 if (TARGET_LONG_BITS
== 32) {
1663 tgen_ext32u(s
, TCG_TMP0
, *addr_reg
);
1664 *addr_reg
= TCG_TMP0
;
1666 if (guest_base
< 0x80000) {
1667 *index_reg
= TCG_REG_NONE
;
1670 *index_reg
= TCG_GUEST_BASE_REG
;
1674 #endif /* CONFIG_SOFTMMU */
1676 static void tcg_out_qemu_ld(TCGContext
* s
, TCGReg data_reg
, TCGReg addr_reg
,
1679 TCGMemOp 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
, 1);
1687 /* We need to keep the offset unchanged for retranslation. */
1688 tcg_out16(s
, RI_BRC
| (S390_CC_NE
<< 4));
1689 label_ptr
= s
->code_ptr
;
1692 tcg_out_qemu_ld_direct(s
, opc
, data_reg
, base_reg
, TCG_REG_R2
, 0);
1694 add_qemu_ldst_label(s
, 1, oi
, data_reg
, addr_reg
, s
->code_ptr
, label_ptr
);
1697 tcg_target_long disp
;
1699 tcg_prepare_user_ldst(s
, &addr_reg
, &index_reg
, &disp
);
1700 tcg_out_qemu_ld_direct(s
, opc
, data_reg
, addr_reg
, index_reg
, disp
);
1704 static void tcg_out_qemu_st(TCGContext
* s
, TCGReg data_reg
, TCGReg addr_reg
,
1707 TCGMemOp opc
= get_memop(oi
);
1708 #ifdef CONFIG_SOFTMMU
1709 unsigned mem_index
= get_mmuidx(oi
);
1710 tcg_insn_unit
*label_ptr
;
1713 base_reg
= tcg_out_tlb_read(s
, addr_reg
, opc
, mem_index
, 0);
1715 /* We need to keep the offset unchanged for retranslation. */
1716 tcg_out16(s
, RI_BRC
| (S390_CC_NE
<< 4));
1717 label_ptr
= s
->code_ptr
;
1720 tcg_out_qemu_st_direct(s
, opc
, data_reg
, base_reg
, TCG_REG_R2
, 0);
1722 add_qemu_ldst_label(s
, 0, oi
, data_reg
, addr_reg
, s
->code_ptr
, label_ptr
);
1725 tcg_target_long disp
;
1727 tcg_prepare_user_ldst(s
, &addr_reg
, &index_reg
, &disp
);
1728 tcg_out_qemu_st_direct(s
, opc
, data_reg
, addr_reg
, index_reg
, disp
);
1732 # define OP_32_64(x) \
1733 case glue(glue(INDEX_op_,x),_i32): \
1734 case glue(glue(INDEX_op_,x),_i64)
1736 static inline void tcg_out_op(TCGContext
*s
, TCGOpcode opc
,
1737 const TCGArg
*args
, const int *const_args
)
1743 case INDEX_op_exit_tb
:
1745 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R2
, args
[0]);
1746 tgen_gotoi(s
, S390_CC_ALWAYS
, tb_ret_addr
);
1749 case INDEX_op_goto_tb
:
1750 if (s
->tb_jmp_insn_offset
) {
1751 /* branch displacement must be aligned for atomic patching;
1752 * see if we need to add extra nop before branch
1754 if (!QEMU_PTR_IS_ALIGNED(s
->code_ptr
+ 1, 4)) {
1757 tcg_out16(s
, RIL_BRCL
| (S390_CC_ALWAYS
<< 4));
1758 s
->tb_jmp_insn_offset
[args
[0]] = tcg_current_code_size(s
);
1761 /* load address stored at s->tb_jmp_target_addr + args[0] */
1762 tcg_out_ld_abs(s
, TCG_TYPE_PTR
, TCG_TMP0
,
1763 s
->tb_jmp_target_addr
+ args
[0]);
1765 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, TCG_TMP0
);
1767 s
->tb_jmp_reset_offset
[args
[0]] = tcg_current_code_size(s
);
1771 /* ??? LLC (RXY format) is only present with the extended-immediate
1772 facility, whereas LLGC is always present. */
1773 tcg_out_mem(s
, 0, RXY_LLGC
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1777 /* ??? LB is no smaller than LGB, so no point to using it. */
1778 tcg_out_mem(s
, 0, RXY_LGB
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1782 /* ??? LLH (RXY format) is only present with the extended-immediate
1783 facility, whereas LLGH is always present. */
1784 tcg_out_mem(s
, 0, RXY_LLGH
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1787 case INDEX_op_ld16s_i32
:
1788 tcg_out_mem(s
, RX_LH
, RXY_LHY
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1791 case INDEX_op_ld_i32
:
1792 tcg_out_ld(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1796 tcg_out_mem(s
, RX_STC
, RXY_STCY
, args
[0], args
[1],
1797 TCG_REG_NONE
, args
[2]);
1801 tcg_out_mem(s
, RX_STH
, RXY_STHY
, args
[0], args
[1],
1802 TCG_REG_NONE
, args
[2]);
1805 case INDEX_op_st_i32
:
1806 tcg_out_st(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1809 case INDEX_op_add_i32
:
1810 a0
= args
[0], a1
= args
[1], a2
= (int32_t)args
[2];
1811 if (const_args
[2]) {
1814 if (a2
== (int16_t)a2
) {
1815 tcg_out_insn(s
, RI
, AHI
, a0
, a2
);
1818 if (s390_facilities
& FACILITY_EXT_IMM
) {
1819 tcg_out_insn(s
, RIL
, AFI
, a0
, a2
);
1823 tcg_out_mem(s
, RX_LA
, RXY_LAY
, a0
, a1
, TCG_REG_NONE
, a2
);
1824 } else if (a0
== a1
) {
1825 tcg_out_insn(s
, RR
, AR
, a0
, a2
);
1827 tcg_out_insn(s
, RX
, LA
, a0
, a1
, a2
, 0);
1830 case INDEX_op_sub_i32
:
1831 a0
= args
[0], a1
= args
[1], a2
= (int32_t)args
[2];
1832 if (const_args
[2]) {
1836 tcg_out_insn(s
, RR
, SR
, args
[0], args
[2]);
1839 case INDEX_op_and_i32
:
1840 if (const_args
[2]) {
1841 tgen_andi(s
, TCG_TYPE_I32
, args
[0], args
[2]);
1843 tcg_out_insn(s
, RR
, NR
, args
[0], args
[2]);
1846 case INDEX_op_or_i32
:
1847 if (const_args
[2]) {
1848 tgen64_ori(s
, args
[0], args
[2] & 0xffffffff);
1850 tcg_out_insn(s
, RR
, OR
, args
[0], args
[2]);
1853 case INDEX_op_xor_i32
:
1854 if (const_args
[2]) {
1855 tgen64_xori(s
, args
[0], args
[2] & 0xffffffff);
1857 tcg_out_insn(s
, RR
, XR
, args
[0], args
[2]);
1861 case INDEX_op_neg_i32
:
1862 tcg_out_insn(s
, RR
, LCR
, args
[0], args
[1]);
1865 case INDEX_op_mul_i32
:
1866 if (const_args
[2]) {
1867 if ((int32_t)args
[2] == (int16_t)args
[2]) {
1868 tcg_out_insn(s
, RI
, MHI
, args
[0], args
[2]);
1870 tcg_out_insn(s
, RIL
, MSFI
, args
[0], args
[2]);
1873 tcg_out_insn(s
, RRE
, MSR
, args
[0], args
[2]);
1877 case INDEX_op_div2_i32
:
1878 tcg_out_insn(s
, RR
, DR
, TCG_REG_R2
, args
[4]);
1880 case INDEX_op_divu2_i32
:
1881 tcg_out_insn(s
, RRE
, DLR
, TCG_REG_R2
, args
[4]);
1884 case INDEX_op_shl_i32
:
1887 if (const_args
[2]) {
1888 tcg_out_sh32(s
, op
, args
[0], TCG_REG_NONE
, args
[2]);
1890 tcg_out_sh32(s
, op
, args
[0], args
[2], 0);
1893 case INDEX_op_shr_i32
:
1896 case INDEX_op_sar_i32
:
1900 case INDEX_op_rotl_i32
:
1901 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1902 if (const_args
[2]) {
1903 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1905 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], args
[2], 0);
1908 case INDEX_op_rotr_i32
:
1909 if (const_args
[2]) {
1910 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1],
1911 TCG_REG_NONE
, (32 - args
[2]) & 31);
1913 tcg_out_insn(s
, RR
, LCR
, TCG_TMP0
, args
[2]);
1914 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], TCG_TMP0
, 0);
1918 case INDEX_op_ext8s_i32
:
1919 tgen_ext8s(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1921 case INDEX_op_ext16s_i32
:
1922 tgen_ext16s(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1924 case INDEX_op_ext8u_i32
:
1925 tgen_ext8u(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1927 case INDEX_op_ext16u_i32
:
1928 tgen_ext16u(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1932 /* The TCG bswap definition requires bits 0-47 already be zero.
1933 Thus we don't need the G-type insns to implement bswap16_i64. */
1934 tcg_out_insn(s
, RRE
, LRVR
, args
[0], args
[1]);
1935 tcg_out_sh32(s
, RS_SRL
, args
[0], TCG_REG_NONE
, 16);
1938 tcg_out_insn(s
, RRE
, LRVR
, args
[0], args
[1]);
1941 case INDEX_op_add2_i32
:
1942 if (const_args
[4]) {
1943 tcg_out_insn(s
, RIL
, ALFI
, args
[0], args
[4]);
1945 tcg_out_insn(s
, RR
, ALR
, args
[0], args
[4]);
1947 tcg_out_insn(s
, RRE
, ALCR
, args
[1], args
[5]);
1949 case INDEX_op_sub2_i32
:
1950 if (const_args
[4]) {
1951 tcg_out_insn(s
, RIL
, SLFI
, args
[0], args
[4]);
1953 tcg_out_insn(s
, RR
, SLR
, args
[0], args
[4]);
1955 tcg_out_insn(s
, RRE
, SLBR
, args
[1], args
[5]);
1959 tgen_branch(s
, S390_CC_ALWAYS
, arg_label(args
[0]));
1962 case INDEX_op_brcond_i32
:
1963 tgen_brcond(s
, TCG_TYPE_I32
, args
[2], args
[0],
1964 args
[1], const_args
[1], arg_label(args
[3]));
1966 case INDEX_op_setcond_i32
:
1967 tgen_setcond(s
, TCG_TYPE_I32
, args
[3], args
[0], args
[1],
1968 args
[2], const_args
[2]);
1970 case INDEX_op_movcond_i32
:
1971 tgen_movcond(s
, TCG_TYPE_I32
, args
[5], args
[0], args
[1],
1972 args
[2], const_args
[2], args
[3]);
1975 case INDEX_op_qemu_ld_i32
:
1976 /* ??? Technically we can use a non-extending instruction. */
1977 case INDEX_op_qemu_ld_i64
:
1978 tcg_out_qemu_ld(s
, args
[0], args
[1], args
[2]);
1980 case INDEX_op_qemu_st_i32
:
1981 case INDEX_op_qemu_st_i64
:
1982 tcg_out_qemu_st(s
, args
[0], args
[1], args
[2]);
1985 case INDEX_op_ld16s_i64
:
1986 tcg_out_mem(s
, 0, RXY_LGH
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1988 case INDEX_op_ld32u_i64
:
1989 tcg_out_mem(s
, 0, RXY_LLGF
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1991 case INDEX_op_ld32s_i64
:
1992 tcg_out_mem(s
, 0, RXY_LGF
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1994 case INDEX_op_ld_i64
:
1995 tcg_out_ld(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
1998 case INDEX_op_st32_i64
:
1999 tcg_out_st(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
2001 case INDEX_op_st_i64
:
2002 tcg_out_st(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
2005 case INDEX_op_add_i64
:
2006 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2007 if (const_args
[2]) {
2010 if (a2
== (int16_t)a2
) {
2011 tcg_out_insn(s
, RI
, AGHI
, a0
, a2
);
2014 if (s390_facilities
& FACILITY_EXT_IMM
) {
2015 if (a2
== (int32_t)a2
) {
2016 tcg_out_insn(s
, RIL
, AGFI
, a0
, a2
);
2018 } else if (a2
== (uint32_t)a2
) {
2019 tcg_out_insn(s
, RIL
, ALGFI
, a0
, a2
);
2021 } else if (-a2
== (uint32_t)-a2
) {
2022 tcg_out_insn(s
, RIL
, SLGFI
, a0
, -a2
);
2027 tcg_out_mem(s
, RX_LA
, RXY_LAY
, a0
, a1
, TCG_REG_NONE
, a2
);
2028 } else if (a0
== a1
) {
2029 tcg_out_insn(s
, RRE
, AGR
, a0
, a2
);
2031 tcg_out_insn(s
, RX
, LA
, a0
, a1
, a2
, 0);
2034 case INDEX_op_sub_i64
:
2035 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2036 if (const_args
[2]) {
2040 tcg_out_insn(s
, RRE
, SGR
, args
[0], args
[2]);
2044 case INDEX_op_and_i64
:
2045 if (const_args
[2]) {
2046 tgen_andi(s
, TCG_TYPE_I64
, args
[0], args
[2]);
2048 tcg_out_insn(s
, RRE
, NGR
, args
[0], args
[2]);
2051 case INDEX_op_or_i64
:
2052 if (const_args
[2]) {
2053 tgen64_ori(s
, args
[0], args
[2]);
2055 tcg_out_insn(s
, RRE
, OGR
, args
[0], args
[2]);
2058 case INDEX_op_xor_i64
:
2059 if (const_args
[2]) {
2060 tgen64_xori(s
, args
[0], args
[2]);
2062 tcg_out_insn(s
, RRE
, XGR
, args
[0], args
[2]);
2066 case INDEX_op_neg_i64
:
2067 tcg_out_insn(s
, RRE
, LCGR
, args
[0], args
[1]);
2069 case INDEX_op_bswap64_i64
:
2070 tcg_out_insn(s
, RRE
, LRVGR
, args
[0], args
[1]);
2073 case INDEX_op_mul_i64
:
2074 if (const_args
[2]) {
2075 if (args
[2] == (int16_t)args
[2]) {
2076 tcg_out_insn(s
, RI
, MGHI
, args
[0], args
[2]);
2078 tcg_out_insn(s
, RIL
, MSGFI
, args
[0], args
[2]);
2081 tcg_out_insn(s
, RRE
, MSGR
, args
[0], args
[2]);
2085 case INDEX_op_div2_i64
:
2086 /* ??? We get an unnecessary sign-extension of the dividend
2087 into R3 with this definition, but as we do in fact always
2088 produce both quotient and remainder using INDEX_op_div_i64
2089 instead requires jumping through even more hoops. */
2090 tcg_out_insn(s
, RRE
, DSGR
, TCG_REG_R2
, args
[4]);
2092 case INDEX_op_divu2_i64
:
2093 tcg_out_insn(s
, RRE
, DLGR
, TCG_REG_R2
, args
[4]);
2095 case INDEX_op_mulu2_i64
:
2096 tcg_out_insn(s
, RRE
, MLGR
, TCG_REG_R2
, args
[3]);
2099 case INDEX_op_shl_i64
:
2102 if (const_args
[2]) {
2103 tcg_out_sh64(s
, op
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
2105 tcg_out_sh64(s
, op
, args
[0], args
[1], args
[2], 0);
2108 case INDEX_op_shr_i64
:
2111 case INDEX_op_sar_i64
:
2115 case INDEX_op_rotl_i64
:
2116 if (const_args
[2]) {
2117 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1],
2118 TCG_REG_NONE
, args
[2]);
2120 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1], args
[2], 0);
2123 case INDEX_op_rotr_i64
:
2124 if (const_args
[2]) {
2125 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1],
2126 TCG_REG_NONE
, (64 - args
[2]) & 63);
2128 /* We can use the smaller 32-bit negate because only the
2129 low 6 bits are examined for the rotate. */
2130 tcg_out_insn(s
, RR
, LCR
, TCG_TMP0
, args
[2]);
2131 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1], TCG_TMP0
, 0);
2135 case INDEX_op_ext8s_i64
:
2136 tgen_ext8s(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2138 case INDEX_op_ext16s_i64
:
2139 tgen_ext16s(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2141 case INDEX_op_ext_i32_i64
:
2142 case INDEX_op_ext32s_i64
:
2143 tgen_ext32s(s
, args
[0], args
[1]);
2145 case INDEX_op_ext8u_i64
:
2146 tgen_ext8u(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2148 case INDEX_op_ext16u_i64
:
2149 tgen_ext16u(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2151 case INDEX_op_extu_i32_i64
:
2152 case INDEX_op_ext32u_i64
:
2153 tgen_ext32u(s
, args
[0], args
[1]);
2156 case INDEX_op_add2_i64
:
2157 if (const_args
[4]) {
2158 if ((int64_t)args
[4] >= 0) {
2159 tcg_out_insn(s
, RIL
, ALGFI
, args
[0], args
[4]);
2161 tcg_out_insn(s
, RIL
, SLGFI
, args
[0], -args
[4]);
2164 tcg_out_insn(s
, RRE
, ALGR
, args
[0], args
[4]);
2166 tcg_out_insn(s
, RRE
, ALCGR
, args
[1], args
[5]);
2168 case INDEX_op_sub2_i64
:
2169 if (const_args
[4]) {
2170 if ((int64_t)args
[4] >= 0) {
2171 tcg_out_insn(s
, RIL
, SLGFI
, args
[0], args
[4]);
2173 tcg_out_insn(s
, RIL
, ALGFI
, args
[0], -args
[4]);
2176 tcg_out_insn(s
, RRE
, SLGR
, args
[0], args
[4]);
2178 tcg_out_insn(s
, RRE
, SLBGR
, args
[1], args
[5]);
2181 case INDEX_op_brcond_i64
:
2182 tgen_brcond(s
, TCG_TYPE_I64
, args
[2], args
[0],
2183 args
[1], const_args
[1], arg_label(args
[3]));
2185 case INDEX_op_setcond_i64
:
2186 tgen_setcond(s
, TCG_TYPE_I64
, args
[3], args
[0], args
[1],
2187 args
[2], const_args
[2]);
2189 case INDEX_op_movcond_i64
:
2190 tgen_movcond(s
, TCG_TYPE_I64
, args
[5], args
[0], args
[1],
2191 args
[2], const_args
[2], args
[3]);
2195 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2196 if (const_args
[1]) {
2197 tgen_deposit(s
, a0
, a2
, args
[3], args
[4], 1);
2199 /* Since we can't support "0Z" as a constraint, we allow a1 in
2200 any register. Fix things up as if a matching constraint. */
2202 TCGType type
= (opc
== INDEX_op_deposit_i64
);
2204 tcg_out_mov(s
, type
, TCG_TMP0
, a2
);
2207 tcg_out_mov(s
, type
, a0
, a1
);
2209 tgen_deposit(s
, a0
, a2
, args
[3], args
[4], 0);
2214 tgen_extract(s
, args
[0], args
[1], args
[2], args
[3]);
2217 case INDEX_op_clz_i64
:
2218 tgen_clz(s
, args
[0], args
[1], args
[2], const_args
[2]);
2222 /* The host memory model is quite strong, we simply need to
2223 serialize the instruction stream. */
2224 if (args
[0] & TCG_MO_ST_LD
) {
2225 tcg_out_insn(s
, RR
, BCR
,
2226 s390_facilities
& FACILITY_FAST_BCR_SER
? 14 : 15, 0);
2230 case INDEX_op_mov_i32
: /* Always emitted via tcg_out_mov. */
2231 case INDEX_op_mov_i64
:
2232 case INDEX_op_movi_i32
: /* Always emitted via tcg_out_movi. */
2233 case INDEX_op_movi_i64
:
2234 case INDEX_op_call
: /* Always emitted via tcg_out_call. */
2240 static const TCGTargetOpDef s390_op_defs
[] = {
2241 { INDEX_op_exit_tb
, { } },
2242 { INDEX_op_goto_tb
, { } },
2243 { INDEX_op_br
, { } },
2245 { INDEX_op_ld8u_i32
, { "r", "r" } },
2246 { INDEX_op_ld8s_i32
, { "r", "r" } },
2247 { INDEX_op_ld16u_i32
, { "r", "r" } },
2248 { INDEX_op_ld16s_i32
, { "r", "r" } },
2249 { INDEX_op_ld_i32
, { "r", "r" } },
2250 { INDEX_op_st8_i32
, { "r", "r" } },
2251 { INDEX_op_st16_i32
, { "r", "r" } },
2252 { INDEX_op_st_i32
, { "r", "r" } },
2254 { INDEX_op_add_i32
, { "r", "r", "ri" } },
2255 { INDEX_op_sub_i32
, { "r", "0", "ri" } },
2256 { INDEX_op_mul_i32
, { "r", "0", "rK" } },
2258 { INDEX_op_div2_i32
, { "b", "a", "0", "1", "r" } },
2259 { INDEX_op_divu2_i32
, { "b", "a", "0", "1", "r" } },
2261 { INDEX_op_and_i32
, { "r", "0", "ri" } },
2262 { INDEX_op_or_i32
, { "r", "0", "rO" } },
2263 { INDEX_op_xor_i32
, { "r", "0", "rX" } },
2265 { INDEX_op_neg_i32
, { "r", "r" } },
2267 { INDEX_op_shl_i32
, { "r", "0", "ri" } },
2268 { INDEX_op_shr_i32
, { "r", "0", "ri" } },
2269 { INDEX_op_sar_i32
, { "r", "0", "ri" } },
2271 { INDEX_op_rotl_i32
, { "r", "r", "ri" } },
2272 { INDEX_op_rotr_i32
, { "r", "r", "ri" } },
2274 { INDEX_op_ext8s_i32
, { "r", "r" } },
2275 { INDEX_op_ext8u_i32
, { "r", "r" } },
2276 { INDEX_op_ext16s_i32
, { "r", "r" } },
2277 { INDEX_op_ext16u_i32
, { "r", "r" } },
2279 { INDEX_op_bswap16_i32
, { "r", "r" } },
2280 { INDEX_op_bswap32_i32
, { "r", "r" } },
2282 { INDEX_op_add2_i32
, { "r", "r", "0", "1", "rA", "r" } },
2283 { INDEX_op_sub2_i32
, { "r", "r", "0", "1", "rA", "r" } },
2285 { INDEX_op_brcond_i32
, { "r", "rC" } },
2286 { INDEX_op_setcond_i32
, { "r", "r", "rC" } },
2287 { INDEX_op_movcond_i32
, { "r", "r", "rC", "r", "0" } },
2288 { INDEX_op_deposit_i32
, { "r", "rZ", "r" } },
2289 { INDEX_op_extract_i32
, { "r", "r" } },
2291 { INDEX_op_qemu_ld_i32
, { "r", "L" } },
2292 { INDEX_op_qemu_ld_i64
, { "r", "L" } },
2293 { INDEX_op_qemu_st_i32
, { "L", "L" } },
2294 { INDEX_op_qemu_st_i64
, { "L", "L" } },
2296 { INDEX_op_ld8u_i64
, { "r", "r" } },
2297 { INDEX_op_ld8s_i64
, { "r", "r" } },
2298 { INDEX_op_ld16u_i64
, { "r", "r" } },
2299 { INDEX_op_ld16s_i64
, { "r", "r" } },
2300 { INDEX_op_ld32u_i64
, { "r", "r" } },
2301 { INDEX_op_ld32s_i64
, { "r", "r" } },
2302 { INDEX_op_ld_i64
, { "r", "r" } },
2304 { INDEX_op_st8_i64
, { "r", "r" } },
2305 { INDEX_op_st16_i64
, { "r", "r" } },
2306 { INDEX_op_st32_i64
, { "r", "r" } },
2307 { INDEX_op_st_i64
, { "r", "r" } },
2309 { INDEX_op_add_i64
, { "r", "r", "ri" } },
2310 { INDEX_op_sub_i64
, { "r", "0", "ri" } },
2311 { INDEX_op_mul_i64
, { "r", "0", "rK" } },
2313 { INDEX_op_div2_i64
, { "b", "a", "0", "1", "r" } },
2314 { INDEX_op_divu2_i64
, { "b", "a", "0", "1", "r" } },
2315 { INDEX_op_mulu2_i64
, { "b", "a", "0", "r" } },
2317 { INDEX_op_and_i64
, { "r", "0", "ri" } },
2318 { INDEX_op_or_i64
, { "r", "0", "rO" } },
2319 { INDEX_op_xor_i64
, { "r", "0", "rX" } },
2321 { INDEX_op_neg_i64
, { "r", "r" } },
2323 { INDEX_op_shl_i64
, { "r", "r", "ri" } },
2324 { INDEX_op_shr_i64
, { "r", "r", "ri" } },
2325 { INDEX_op_sar_i64
, { "r", "r", "ri" } },
2327 { INDEX_op_rotl_i64
, { "r", "r", "ri" } },
2328 { INDEX_op_rotr_i64
, { "r", "r", "ri" } },
2330 { INDEX_op_ext8s_i64
, { "r", "r" } },
2331 { INDEX_op_ext8u_i64
, { "r", "r" } },
2332 { INDEX_op_ext16s_i64
, { "r", "r" } },
2333 { INDEX_op_ext16u_i64
, { "r", "r" } },
2334 { INDEX_op_ext32s_i64
, { "r", "r" } },
2335 { INDEX_op_ext32u_i64
, { "r", "r" } },
2337 { INDEX_op_ext_i32_i64
, { "r", "r" } },
2338 { INDEX_op_extu_i32_i64
, { "r", "r" } },
2340 { INDEX_op_bswap16_i64
, { "r", "r" } },
2341 { INDEX_op_bswap32_i64
, { "r", "r" } },
2342 { INDEX_op_bswap64_i64
, { "r", "r" } },
2344 { INDEX_op_clz_i64
, { "r", "r", "ri" } },
2346 { INDEX_op_add2_i64
, { "r", "r", "0", "1", "rA", "r" } },
2347 { INDEX_op_sub2_i64
, { "r", "r", "0", "1", "rA", "r" } },
2349 { INDEX_op_brcond_i64
, { "r", "rC" } },
2350 { INDEX_op_setcond_i64
, { "r", "r", "rC" } },
2351 { INDEX_op_movcond_i64
, { "r", "r", "rC", "r", "0" } },
2352 { INDEX_op_deposit_i64
, { "r", "0", "r" } },
2353 { INDEX_op_extract_i64
, { "r", "r" } },
2355 { INDEX_op_mb
, { } },
2359 static const TCGTargetOpDef
*tcg_target_op_def(TCGOpcode op
)
2361 int i
, n
= ARRAY_SIZE(s390_op_defs
);
2363 for (i
= 0; i
< n
; ++i
) {
2364 if (s390_op_defs
[i
].op
== op
) {
2365 return &s390_op_defs
[i
];
2371 static void query_s390_facilities(void)
2373 unsigned long hwcap
= qemu_getauxval(AT_HWCAP
);
2375 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
2376 is present on all 64-bit systems, but let's check for it anyway. */
2377 if (hwcap
& HWCAP_S390_STFLE
) {
2378 register int r0
__asm__("0");
2379 register void *r1
__asm__("1");
2382 r1
= &s390_facilities
;
2383 asm volatile(".word 0xb2b0,0x1000"
2384 : "=r"(r0
) : "0"(0), "r"(r1
) : "memory", "cc");
2388 static void tcg_target_init(TCGContext
*s
)
2390 query_s390_facilities();
2392 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I32
], 0, 0xffff);
2393 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I64
], 0, 0xffff);
2395 tcg_regset_clear(tcg_target_call_clobber_regs
);
2396 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R0
);
2397 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R1
);
2398 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R2
);
2399 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R3
);
2400 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R4
);
2401 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R5
);
2402 /* The r6 register is technically call-saved, but it's also a parameter
2403 register, so it can get killed by setup for the qemu_st helper. */
2404 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R6
);
2405 /* The return register can be considered call-clobbered. */
2406 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R14
);
2408 tcg_regset_clear(s
->reserved_regs
);
2409 tcg_regset_set_reg(s
->reserved_regs
, TCG_TMP0
);
2410 /* XXX many insns can't be used with R0, so we better avoid it for now */
2411 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_R0
);
2412 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_CALL_STACK
);
2415 #define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
2416 + TCG_STATIC_CALL_ARGS_SIZE \
2417 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
2419 static void tcg_target_qemu_prologue(TCGContext
*s
)
2421 /* stmg %r6,%r15,48(%r15) (save registers) */
2422 tcg_out_insn(s
, RXY
, STMG
, TCG_REG_R6
, TCG_REG_R15
, TCG_REG_R15
, 48);
2424 /* aghi %r15,-frame_size */
2425 tcg_out_insn(s
, RI
, AGHI
, TCG_REG_R15
, -FRAME_SIZE
);
2427 tcg_set_frame(s
, TCG_REG_CALL_STACK
,
2428 TCG_STATIC_CALL_ARGS_SIZE
+ TCG_TARGET_CALL_STACK_OFFSET
,
2429 CPU_TEMP_BUF_NLONGS
* sizeof(long));
2431 #ifndef CONFIG_SOFTMMU
2432 if (guest_base
>= 0x80000) {
2433 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_GUEST_BASE_REG
, guest_base
);
2434 tcg_regset_set_reg(s
->reserved_regs
, TCG_GUEST_BASE_REG
);
2438 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_AREG0
, tcg_target_call_iarg_regs
[0]);
2439 /* br %r3 (go to TB) */
2440 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, tcg_target_call_iarg_regs
[1]);
2442 tb_ret_addr
= s
->code_ptr
;
2444 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2445 tcg_out_insn(s
, RXY
, LMG
, TCG_REG_R6
, TCG_REG_R15
, TCG_REG_R15
,
2448 /* br %r14 (return) */
2449 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, TCG_REG_R14
);
2454 uint8_t fde_def_cfa
[4];
2455 uint8_t fde_reg_ofs
[18];
2458 /* We're expecting a 2 byte uleb128 encoded value. */
2459 QEMU_BUILD_BUG_ON(FRAME_SIZE
>= (1 << 14));
2461 #define ELF_HOST_MACHINE EM_S390
2463 static const DebugFrame debug_frame
= {
2464 .h
.cie
.len
= sizeof(DebugFrameCIE
)-4, /* length after .len member */
2467 .h
.cie
.code_align
= 1,
2468 .h
.cie
.data_align
= 8, /* sleb128 8 */
2469 .h
.cie
.return_column
= TCG_REG_R14
,
2471 /* Total FDE size does not include the "len" member. */
2472 .h
.fde
.len
= sizeof(DebugFrame
) - offsetof(DebugFrame
, h
.fde
.cie_offset
),
2475 12, TCG_REG_CALL_STACK
, /* DW_CFA_def_cfa %r15, ... */
2476 (FRAME_SIZE
& 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2480 0x86, 6, /* DW_CFA_offset, %r6, 48 */
2481 0x87, 7, /* DW_CFA_offset, %r7, 56 */
2482 0x88, 8, /* DW_CFA_offset, %r8, 64 */
2483 0x89, 9, /* DW_CFA_offset, %r92, 72 */
2484 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
2485 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
2486 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
2487 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
2488 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
2492 void tcg_register_jit(void *buf
, size_t buf_size
)
2494 tcg_register_jit_int(buf
, buf_size
, &debug_frame
, sizeof(debug_frame
));