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
:
1744 /* Reuse the zeroing that exists for goto_ptr. */
1747 tgen_gotoi(s
, S390_CC_ALWAYS
, s
->code_gen_epilogue
);
1749 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R2
, a0
);
1750 tgen_gotoi(s
, S390_CC_ALWAYS
, tb_ret_addr
);
1754 case INDEX_op_goto_tb
:
1755 if (s
->tb_jmp_insn_offset
) {
1756 /* branch displacement must be aligned for atomic patching;
1757 * see if we need to add extra nop before branch
1759 if (!QEMU_PTR_IS_ALIGNED(s
->code_ptr
+ 1, 4)) {
1762 tcg_out16(s
, RIL_BRCL
| (S390_CC_ALWAYS
<< 4));
1763 s
->tb_jmp_insn_offset
[args
[0]] = tcg_current_code_size(s
);
1766 /* load address stored at s->tb_jmp_target_addr + args[0] */
1767 tcg_out_ld_abs(s
, TCG_TYPE_PTR
, TCG_TMP0
,
1768 s
->tb_jmp_target_addr
+ args
[0]);
1770 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, TCG_TMP0
);
1772 s
->tb_jmp_reset_offset
[args
[0]] = tcg_current_code_size(s
);
1775 case INDEX_op_goto_ptr
:
1776 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, args
[0]);
1780 /* ??? LLC (RXY format) is only present with the extended-immediate
1781 facility, whereas LLGC is always present. */
1782 tcg_out_mem(s
, 0, RXY_LLGC
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1786 /* ??? LB is no smaller than LGB, so no point to using it. */
1787 tcg_out_mem(s
, 0, RXY_LGB
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1791 /* ??? LLH (RXY format) is only present with the extended-immediate
1792 facility, whereas LLGH is always present. */
1793 tcg_out_mem(s
, 0, RXY_LLGH
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1796 case INDEX_op_ld16s_i32
:
1797 tcg_out_mem(s
, RX_LH
, RXY_LHY
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1800 case INDEX_op_ld_i32
:
1801 tcg_out_ld(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1805 tcg_out_mem(s
, RX_STC
, RXY_STCY
, args
[0], args
[1],
1806 TCG_REG_NONE
, args
[2]);
1810 tcg_out_mem(s
, RX_STH
, RXY_STHY
, args
[0], args
[1],
1811 TCG_REG_NONE
, args
[2]);
1814 case INDEX_op_st_i32
:
1815 tcg_out_st(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1818 case INDEX_op_add_i32
:
1819 a0
= args
[0], a1
= args
[1], a2
= (int32_t)args
[2];
1820 if (const_args
[2]) {
1823 if (a2
== (int16_t)a2
) {
1824 tcg_out_insn(s
, RI
, AHI
, a0
, a2
);
1827 if (s390_facilities
& FACILITY_EXT_IMM
) {
1828 tcg_out_insn(s
, RIL
, AFI
, a0
, a2
);
1832 tcg_out_mem(s
, RX_LA
, RXY_LAY
, a0
, a1
, TCG_REG_NONE
, a2
);
1833 } else if (a0
== a1
) {
1834 tcg_out_insn(s
, RR
, AR
, a0
, a2
);
1836 tcg_out_insn(s
, RX
, LA
, a0
, a1
, a2
, 0);
1839 case INDEX_op_sub_i32
:
1840 a0
= args
[0], a1
= args
[1], a2
= (int32_t)args
[2];
1841 if (const_args
[2]) {
1845 tcg_out_insn(s
, RR
, SR
, args
[0], args
[2]);
1848 case INDEX_op_and_i32
:
1849 if (const_args
[2]) {
1850 tgen_andi(s
, TCG_TYPE_I32
, args
[0], args
[2]);
1852 tcg_out_insn(s
, RR
, NR
, args
[0], args
[2]);
1855 case INDEX_op_or_i32
:
1856 if (const_args
[2]) {
1857 tgen64_ori(s
, args
[0], args
[2] & 0xffffffff);
1859 tcg_out_insn(s
, RR
, OR
, args
[0], args
[2]);
1862 case INDEX_op_xor_i32
:
1863 if (const_args
[2]) {
1864 tgen64_xori(s
, args
[0], args
[2] & 0xffffffff);
1866 tcg_out_insn(s
, RR
, XR
, args
[0], args
[2]);
1870 case INDEX_op_neg_i32
:
1871 tcg_out_insn(s
, RR
, LCR
, args
[0], args
[1]);
1874 case INDEX_op_mul_i32
:
1875 if (const_args
[2]) {
1876 if ((int32_t)args
[2] == (int16_t)args
[2]) {
1877 tcg_out_insn(s
, RI
, MHI
, args
[0], args
[2]);
1879 tcg_out_insn(s
, RIL
, MSFI
, args
[0], args
[2]);
1882 tcg_out_insn(s
, RRE
, MSR
, args
[0], args
[2]);
1886 case INDEX_op_div2_i32
:
1887 tcg_out_insn(s
, RR
, DR
, TCG_REG_R2
, args
[4]);
1889 case INDEX_op_divu2_i32
:
1890 tcg_out_insn(s
, RRE
, DLR
, TCG_REG_R2
, args
[4]);
1893 case INDEX_op_shl_i32
:
1896 if (const_args
[2]) {
1897 tcg_out_sh32(s
, op
, args
[0], TCG_REG_NONE
, args
[2]);
1899 tcg_out_sh32(s
, op
, args
[0], args
[2], 0);
1902 case INDEX_op_shr_i32
:
1905 case INDEX_op_sar_i32
:
1909 case INDEX_op_rotl_i32
:
1910 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1911 if (const_args
[2]) {
1912 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1914 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], args
[2], 0);
1917 case INDEX_op_rotr_i32
:
1918 if (const_args
[2]) {
1919 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1],
1920 TCG_REG_NONE
, (32 - args
[2]) & 31);
1922 tcg_out_insn(s
, RR
, LCR
, TCG_TMP0
, args
[2]);
1923 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], TCG_TMP0
, 0);
1927 case INDEX_op_ext8s_i32
:
1928 tgen_ext8s(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1930 case INDEX_op_ext16s_i32
:
1931 tgen_ext16s(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1933 case INDEX_op_ext8u_i32
:
1934 tgen_ext8u(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1936 case INDEX_op_ext16u_i32
:
1937 tgen_ext16u(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1941 /* The TCG bswap definition requires bits 0-47 already be zero.
1942 Thus we don't need the G-type insns to implement bswap16_i64. */
1943 tcg_out_insn(s
, RRE
, LRVR
, args
[0], args
[1]);
1944 tcg_out_sh32(s
, RS_SRL
, args
[0], TCG_REG_NONE
, 16);
1947 tcg_out_insn(s
, RRE
, LRVR
, args
[0], args
[1]);
1950 case INDEX_op_add2_i32
:
1951 if (const_args
[4]) {
1952 tcg_out_insn(s
, RIL
, ALFI
, args
[0], args
[4]);
1954 tcg_out_insn(s
, RR
, ALR
, args
[0], args
[4]);
1956 tcg_out_insn(s
, RRE
, ALCR
, args
[1], args
[5]);
1958 case INDEX_op_sub2_i32
:
1959 if (const_args
[4]) {
1960 tcg_out_insn(s
, RIL
, SLFI
, args
[0], args
[4]);
1962 tcg_out_insn(s
, RR
, SLR
, args
[0], args
[4]);
1964 tcg_out_insn(s
, RRE
, SLBR
, args
[1], args
[5]);
1968 tgen_branch(s
, S390_CC_ALWAYS
, arg_label(args
[0]));
1971 case INDEX_op_brcond_i32
:
1972 tgen_brcond(s
, TCG_TYPE_I32
, args
[2], args
[0],
1973 args
[1], const_args
[1], arg_label(args
[3]));
1975 case INDEX_op_setcond_i32
:
1976 tgen_setcond(s
, TCG_TYPE_I32
, args
[3], args
[0], args
[1],
1977 args
[2], const_args
[2]);
1979 case INDEX_op_movcond_i32
:
1980 tgen_movcond(s
, TCG_TYPE_I32
, args
[5], args
[0], args
[1],
1981 args
[2], const_args
[2], args
[3]);
1984 case INDEX_op_qemu_ld_i32
:
1985 /* ??? Technically we can use a non-extending instruction. */
1986 case INDEX_op_qemu_ld_i64
:
1987 tcg_out_qemu_ld(s
, args
[0], args
[1], args
[2]);
1989 case INDEX_op_qemu_st_i32
:
1990 case INDEX_op_qemu_st_i64
:
1991 tcg_out_qemu_st(s
, args
[0], args
[1], args
[2]);
1994 case INDEX_op_ld16s_i64
:
1995 tcg_out_mem(s
, 0, RXY_LGH
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1997 case INDEX_op_ld32u_i64
:
1998 tcg_out_mem(s
, 0, RXY_LLGF
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
2000 case INDEX_op_ld32s_i64
:
2001 tcg_out_mem(s
, 0, RXY_LGF
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
2003 case INDEX_op_ld_i64
:
2004 tcg_out_ld(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
2007 case INDEX_op_st32_i64
:
2008 tcg_out_st(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
2010 case INDEX_op_st_i64
:
2011 tcg_out_st(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
2014 case INDEX_op_add_i64
:
2015 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2016 if (const_args
[2]) {
2019 if (a2
== (int16_t)a2
) {
2020 tcg_out_insn(s
, RI
, AGHI
, a0
, a2
);
2023 if (s390_facilities
& FACILITY_EXT_IMM
) {
2024 if (a2
== (int32_t)a2
) {
2025 tcg_out_insn(s
, RIL
, AGFI
, a0
, a2
);
2027 } else if (a2
== (uint32_t)a2
) {
2028 tcg_out_insn(s
, RIL
, ALGFI
, a0
, a2
);
2030 } else if (-a2
== (uint32_t)-a2
) {
2031 tcg_out_insn(s
, RIL
, SLGFI
, a0
, -a2
);
2036 tcg_out_mem(s
, RX_LA
, RXY_LAY
, a0
, a1
, TCG_REG_NONE
, a2
);
2037 } else if (a0
== a1
) {
2038 tcg_out_insn(s
, RRE
, AGR
, a0
, a2
);
2040 tcg_out_insn(s
, RX
, LA
, a0
, a1
, a2
, 0);
2043 case INDEX_op_sub_i64
:
2044 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2045 if (const_args
[2]) {
2049 tcg_out_insn(s
, RRE
, SGR
, args
[0], args
[2]);
2053 case INDEX_op_and_i64
:
2054 if (const_args
[2]) {
2055 tgen_andi(s
, TCG_TYPE_I64
, args
[0], args
[2]);
2057 tcg_out_insn(s
, RRE
, NGR
, args
[0], args
[2]);
2060 case INDEX_op_or_i64
:
2061 if (const_args
[2]) {
2062 tgen64_ori(s
, args
[0], args
[2]);
2064 tcg_out_insn(s
, RRE
, OGR
, args
[0], args
[2]);
2067 case INDEX_op_xor_i64
:
2068 if (const_args
[2]) {
2069 tgen64_xori(s
, args
[0], args
[2]);
2071 tcg_out_insn(s
, RRE
, XGR
, args
[0], args
[2]);
2075 case INDEX_op_neg_i64
:
2076 tcg_out_insn(s
, RRE
, LCGR
, args
[0], args
[1]);
2078 case INDEX_op_bswap64_i64
:
2079 tcg_out_insn(s
, RRE
, LRVGR
, args
[0], args
[1]);
2082 case INDEX_op_mul_i64
:
2083 if (const_args
[2]) {
2084 if (args
[2] == (int16_t)args
[2]) {
2085 tcg_out_insn(s
, RI
, MGHI
, args
[0], args
[2]);
2087 tcg_out_insn(s
, RIL
, MSGFI
, args
[0], args
[2]);
2090 tcg_out_insn(s
, RRE
, MSGR
, args
[0], args
[2]);
2094 case INDEX_op_div2_i64
:
2095 /* ??? We get an unnecessary sign-extension of the dividend
2096 into R3 with this definition, but as we do in fact always
2097 produce both quotient and remainder using INDEX_op_div_i64
2098 instead requires jumping through even more hoops. */
2099 tcg_out_insn(s
, RRE
, DSGR
, TCG_REG_R2
, args
[4]);
2101 case INDEX_op_divu2_i64
:
2102 tcg_out_insn(s
, RRE
, DLGR
, TCG_REG_R2
, args
[4]);
2104 case INDEX_op_mulu2_i64
:
2105 tcg_out_insn(s
, RRE
, MLGR
, TCG_REG_R2
, args
[3]);
2108 case INDEX_op_shl_i64
:
2111 if (const_args
[2]) {
2112 tcg_out_sh64(s
, op
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
2114 tcg_out_sh64(s
, op
, args
[0], args
[1], args
[2], 0);
2117 case INDEX_op_shr_i64
:
2120 case INDEX_op_sar_i64
:
2124 case INDEX_op_rotl_i64
:
2125 if (const_args
[2]) {
2126 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1],
2127 TCG_REG_NONE
, args
[2]);
2129 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1], args
[2], 0);
2132 case INDEX_op_rotr_i64
:
2133 if (const_args
[2]) {
2134 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1],
2135 TCG_REG_NONE
, (64 - args
[2]) & 63);
2137 /* We can use the smaller 32-bit negate because only the
2138 low 6 bits are examined for the rotate. */
2139 tcg_out_insn(s
, RR
, LCR
, TCG_TMP0
, args
[2]);
2140 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1], TCG_TMP0
, 0);
2144 case INDEX_op_ext8s_i64
:
2145 tgen_ext8s(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2147 case INDEX_op_ext16s_i64
:
2148 tgen_ext16s(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2150 case INDEX_op_ext_i32_i64
:
2151 case INDEX_op_ext32s_i64
:
2152 tgen_ext32s(s
, args
[0], args
[1]);
2154 case INDEX_op_ext8u_i64
:
2155 tgen_ext8u(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2157 case INDEX_op_ext16u_i64
:
2158 tgen_ext16u(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2160 case INDEX_op_extu_i32_i64
:
2161 case INDEX_op_ext32u_i64
:
2162 tgen_ext32u(s
, args
[0], args
[1]);
2165 case INDEX_op_add2_i64
:
2166 if (const_args
[4]) {
2167 if ((int64_t)args
[4] >= 0) {
2168 tcg_out_insn(s
, RIL
, ALGFI
, args
[0], args
[4]);
2170 tcg_out_insn(s
, RIL
, SLGFI
, args
[0], -args
[4]);
2173 tcg_out_insn(s
, RRE
, ALGR
, args
[0], args
[4]);
2175 tcg_out_insn(s
, RRE
, ALCGR
, args
[1], args
[5]);
2177 case INDEX_op_sub2_i64
:
2178 if (const_args
[4]) {
2179 if ((int64_t)args
[4] >= 0) {
2180 tcg_out_insn(s
, RIL
, SLGFI
, args
[0], args
[4]);
2182 tcg_out_insn(s
, RIL
, ALGFI
, args
[0], -args
[4]);
2185 tcg_out_insn(s
, RRE
, SLGR
, args
[0], args
[4]);
2187 tcg_out_insn(s
, RRE
, SLBGR
, args
[1], args
[5]);
2190 case INDEX_op_brcond_i64
:
2191 tgen_brcond(s
, TCG_TYPE_I64
, args
[2], args
[0],
2192 args
[1], const_args
[1], arg_label(args
[3]));
2194 case INDEX_op_setcond_i64
:
2195 tgen_setcond(s
, TCG_TYPE_I64
, args
[3], args
[0], args
[1],
2196 args
[2], const_args
[2]);
2198 case INDEX_op_movcond_i64
:
2199 tgen_movcond(s
, TCG_TYPE_I64
, args
[5], args
[0], args
[1],
2200 args
[2], const_args
[2], args
[3]);
2204 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2205 if (const_args
[1]) {
2206 tgen_deposit(s
, a0
, a2
, args
[3], args
[4], 1);
2208 /* Since we can't support "0Z" as a constraint, we allow a1 in
2209 any register. Fix things up as if a matching constraint. */
2211 TCGType type
= (opc
== INDEX_op_deposit_i64
);
2213 tcg_out_mov(s
, type
, TCG_TMP0
, a2
);
2216 tcg_out_mov(s
, type
, a0
, a1
);
2218 tgen_deposit(s
, a0
, a2
, args
[3], args
[4], 0);
2223 tgen_extract(s
, args
[0], args
[1], args
[2], args
[3]);
2226 case INDEX_op_clz_i64
:
2227 tgen_clz(s
, args
[0], args
[1], args
[2], const_args
[2]);
2231 /* The host memory model is quite strong, we simply need to
2232 serialize the instruction stream. */
2233 if (args
[0] & TCG_MO_ST_LD
) {
2234 tcg_out_insn(s
, RR
, BCR
,
2235 s390_facilities
& FACILITY_FAST_BCR_SER
? 14 : 15, 0);
2239 case INDEX_op_mov_i32
: /* Always emitted via tcg_out_mov. */
2240 case INDEX_op_mov_i64
:
2241 case INDEX_op_movi_i32
: /* Always emitted via tcg_out_movi. */
2242 case INDEX_op_movi_i64
:
2243 case INDEX_op_call
: /* Always emitted via tcg_out_call. */
2249 static const TCGTargetOpDef s390_op_defs
[] = {
2250 { INDEX_op_exit_tb
, { } },
2251 { INDEX_op_goto_tb
, { } },
2252 { INDEX_op_br
, { } },
2253 { INDEX_op_goto_ptr
, { "r" } },
2255 { INDEX_op_ld8u_i32
, { "r", "r" } },
2256 { INDEX_op_ld8s_i32
, { "r", "r" } },
2257 { INDEX_op_ld16u_i32
, { "r", "r" } },
2258 { INDEX_op_ld16s_i32
, { "r", "r" } },
2259 { INDEX_op_ld_i32
, { "r", "r" } },
2260 { INDEX_op_st8_i32
, { "r", "r" } },
2261 { INDEX_op_st16_i32
, { "r", "r" } },
2262 { INDEX_op_st_i32
, { "r", "r" } },
2264 { INDEX_op_add_i32
, { "r", "r", "ri" } },
2265 { INDEX_op_sub_i32
, { "r", "0", "ri" } },
2266 { INDEX_op_mul_i32
, { "r", "0", "rK" } },
2268 { INDEX_op_div2_i32
, { "b", "a", "0", "1", "r" } },
2269 { INDEX_op_divu2_i32
, { "b", "a", "0", "1", "r" } },
2271 { INDEX_op_and_i32
, { "r", "0", "ri" } },
2272 { INDEX_op_or_i32
, { "r", "0", "rO" } },
2273 { INDEX_op_xor_i32
, { "r", "0", "rX" } },
2275 { INDEX_op_neg_i32
, { "r", "r" } },
2277 { INDEX_op_shl_i32
, { "r", "0", "ri" } },
2278 { INDEX_op_shr_i32
, { "r", "0", "ri" } },
2279 { INDEX_op_sar_i32
, { "r", "0", "ri" } },
2281 { INDEX_op_rotl_i32
, { "r", "r", "ri" } },
2282 { INDEX_op_rotr_i32
, { "r", "r", "ri" } },
2284 { INDEX_op_ext8s_i32
, { "r", "r" } },
2285 { INDEX_op_ext8u_i32
, { "r", "r" } },
2286 { INDEX_op_ext16s_i32
, { "r", "r" } },
2287 { INDEX_op_ext16u_i32
, { "r", "r" } },
2289 { INDEX_op_bswap16_i32
, { "r", "r" } },
2290 { INDEX_op_bswap32_i32
, { "r", "r" } },
2292 { INDEX_op_add2_i32
, { "r", "r", "0", "1", "rA", "r" } },
2293 { INDEX_op_sub2_i32
, { "r", "r", "0", "1", "rA", "r" } },
2295 { INDEX_op_brcond_i32
, { "r", "rC" } },
2296 { INDEX_op_setcond_i32
, { "r", "r", "rC" } },
2297 { INDEX_op_movcond_i32
, { "r", "r", "rC", "r", "0" } },
2298 { INDEX_op_deposit_i32
, { "r", "rZ", "r" } },
2299 { INDEX_op_extract_i32
, { "r", "r" } },
2301 { INDEX_op_qemu_ld_i32
, { "r", "L" } },
2302 { INDEX_op_qemu_ld_i64
, { "r", "L" } },
2303 { INDEX_op_qemu_st_i32
, { "L", "L" } },
2304 { INDEX_op_qemu_st_i64
, { "L", "L" } },
2306 { INDEX_op_ld8u_i64
, { "r", "r" } },
2307 { INDEX_op_ld8s_i64
, { "r", "r" } },
2308 { INDEX_op_ld16u_i64
, { "r", "r" } },
2309 { INDEX_op_ld16s_i64
, { "r", "r" } },
2310 { INDEX_op_ld32u_i64
, { "r", "r" } },
2311 { INDEX_op_ld32s_i64
, { "r", "r" } },
2312 { INDEX_op_ld_i64
, { "r", "r" } },
2314 { INDEX_op_st8_i64
, { "r", "r" } },
2315 { INDEX_op_st16_i64
, { "r", "r" } },
2316 { INDEX_op_st32_i64
, { "r", "r" } },
2317 { INDEX_op_st_i64
, { "r", "r" } },
2319 { INDEX_op_add_i64
, { "r", "r", "ri" } },
2320 { INDEX_op_sub_i64
, { "r", "0", "ri" } },
2321 { INDEX_op_mul_i64
, { "r", "0", "rK" } },
2323 { INDEX_op_div2_i64
, { "b", "a", "0", "1", "r" } },
2324 { INDEX_op_divu2_i64
, { "b", "a", "0", "1", "r" } },
2325 { INDEX_op_mulu2_i64
, { "b", "a", "0", "r" } },
2327 { INDEX_op_and_i64
, { "r", "0", "ri" } },
2328 { INDEX_op_or_i64
, { "r", "0", "rO" } },
2329 { INDEX_op_xor_i64
, { "r", "0", "rX" } },
2331 { INDEX_op_neg_i64
, { "r", "r" } },
2333 { INDEX_op_shl_i64
, { "r", "r", "ri" } },
2334 { INDEX_op_shr_i64
, { "r", "r", "ri" } },
2335 { INDEX_op_sar_i64
, { "r", "r", "ri" } },
2337 { INDEX_op_rotl_i64
, { "r", "r", "ri" } },
2338 { INDEX_op_rotr_i64
, { "r", "r", "ri" } },
2340 { INDEX_op_ext8s_i64
, { "r", "r" } },
2341 { INDEX_op_ext8u_i64
, { "r", "r" } },
2342 { INDEX_op_ext16s_i64
, { "r", "r" } },
2343 { INDEX_op_ext16u_i64
, { "r", "r" } },
2344 { INDEX_op_ext32s_i64
, { "r", "r" } },
2345 { INDEX_op_ext32u_i64
, { "r", "r" } },
2347 { INDEX_op_ext_i32_i64
, { "r", "r" } },
2348 { INDEX_op_extu_i32_i64
, { "r", "r" } },
2350 { INDEX_op_bswap16_i64
, { "r", "r" } },
2351 { INDEX_op_bswap32_i64
, { "r", "r" } },
2352 { INDEX_op_bswap64_i64
, { "r", "r" } },
2354 { INDEX_op_clz_i64
, { "r", "r", "ri" } },
2356 { INDEX_op_add2_i64
, { "r", "r", "0", "1", "rA", "r" } },
2357 { INDEX_op_sub2_i64
, { "r", "r", "0", "1", "rA", "r" } },
2359 { INDEX_op_brcond_i64
, { "r", "rC" } },
2360 { INDEX_op_setcond_i64
, { "r", "r", "rC" } },
2361 { INDEX_op_movcond_i64
, { "r", "r", "rC", "r", "0" } },
2362 { INDEX_op_deposit_i64
, { "r", "0", "r" } },
2363 { INDEX_op_extract_i64
, { "r", "r" } },
2365 { INDEX_op_mb
, { } },
2369 static const TCGTargetOpDef
*tcg_target_op_def(TCGOpcode op
)
2371 int i
, n
= ARRAY_SIZE(s390_op_defs
);
2373 for (i
= 0; i
< n
; ++i
) {
2374 if (s390_op_defs
[i
].op
== op
) {
2375 return &s390_op_defs
[i
];
2381 static void query_s390_facilities(void)
2383 unsigned long hwcap
= qemu_getauxval(AT_HWCAP
);
2385 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
2386 is present on all 64-bit systems, but let's check for it anyway. */
2387 if (hwcap
& HWCAP_S390_STFLE
) {
2388 register int r0
__asm__("0");
2389 register void *r1
__asm__("1");
2392 r1
= &s390_facilities
;
2393 asm volatile(".word 0xb2b0,0x1000"
2394 : "=r"(r0
) : "0"(0), "r"(r1
) : "memory", "cc");
2398 static void tcg_target_init(TCGContext
*s
)
2400 query_s390_facilities();
2402 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I32
], 0, 0xffff);
2403 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I64
], 0, 0xffff);
2405 tcg_regset_clear(tcg_target_call_clobber_regs
);
2406 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R0
);
2407 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R1
);
2408 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R2
);
2409 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R3
);
2410 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R4
);
2411 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R5
);
2412 /* The r6 register is technically call-saved, but it's also a parameter
2413 register, so it can get killed by setup for the qemu_st helper. */
2414 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R6
);
2415 /* The return register can be considered call-clobbered. */
2416 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R14
);
2418 tcg_regset_clear(s
->reserved_regs
);
2419 tcg_regset_set_reg(s
->reserved_regs
, TCG_TMP0
);
2420 /* XXX many insns can't be used with R0, so we better avoid it for now */
2421 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_R0
);
2422 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_CALL_STACK
);
2425 #define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
2426 + TCG_STATIC_CALL_ARGS_SIZE \
2427 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
2429 static void tcg_target_qemu_prologue(TCGContext
*s
)
2431 /* stmg %r6,%r15,48(%r15) (save registers) */
2432 tcg_out_insn(s
, RXY
, STMG
, TCG_REG_R6
, TCG_REG_R15
, TCG_REG_R15
, 48);
2434 /* aghi %r15,-frame_size */
2435 tcg_out_insn(s
, RI
, AGHI
, TCG_REG_R15
, -FRAME_SIZE
);
2437 tcg_set_frame(s
, TCG_REG_CALL_STACK
,
2438 TCG_STATIC_CALL_ARGS_SIZE
+ TCG_TARGET_CALL_STACK_OFFSET
,
2439 CPU_TEMP_BUF_NLONGS
* sizeof(long));
2441 #ifndef CONFIG_SOFTMMU
2442 if (guest_base
>= 0x80000) {
2443 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_GUEST_BASE_REG
, guest_base
);
2444 tcg_regset_set_reg(s
->reserved_regs
, TCG_GUEST_BASE_REG
);
2448 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_AREG0
, tcg_target_call_iarg_regs
[0]);
2449 /* br %r3 (go to TB) */
2450 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, tcg_target_call_iarg_regs
[1]);
2453 * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2454 * and fall through to the rest of the epilogue.
2456 s
->code_gen_epilogue
= s
->code_ptr
;
2457 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R2
, 0);
2460 tb_ret_addr
= s
->code_ptr
;
2462 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2463 tcg_out_insn(s
, RXY
, LMG
, TCG_REG_R6
, TCG_REG_R15
, TCG_REG_R15
,
2466 /* br %r14 (return) */
2467 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, TCG_REG_R14
);
2472 uint8_t fde_def_cfa
[4];
2473 uint8_t fde_reg_ofs
[18];
2476 /* We're expecting a 2 byte uleb128 encoded value. */
2477 QEMU_BUILD_BUG_ON(FRAME_SIZE
>= (1 << 14));
2479 #define ELF_HOST_MACHINE EM_S390
2481 static const DebugFrame debug_frame
= {
2482 .h
.cie
.len
= sizeof(DebugFrameCIE
)-4, /* length after .len member */
2485 .h
.cie
.code_align
= 1,
2486 .h
.cie
.data_align
= 8, /* sleb128 8 */
2487 .h
.cie
.return_column
= TCG_REG_R14
,
2489 /* Total FDE size does not include the "len" member. */
2490 .h
.fde
.len
= sizeof(DebugFrame
) - offsetof(DebugFrame
, h
.fde
.cie_offset
),
2493 12, TCG_REG_CALL_STACK
, /* DW_CFA_def_cfa %r15, ... */
2494 (FRAME_SIZE
& 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2498 0x86, 6, /* DW_CFA_offset, %r6, 48 */
2499 0x87, 7, /* DW_CFA_offset, %r7, 56 */
2500 0x88, 8, /* DW_CFA_offset, %r8, 64 */
2501 0x89, 9, /* DW_CFA_offset, %r92, 72 */
2502 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
2503 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
2504 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
2505 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
2506 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
2510 void tcg_register_jit(void *buf
, size_t buf_size
)
2512 tcg_register_jit_int(buf
, buf_size
, &debug_frame
, sizeof(debug_frame
));