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_S16 0x100
42 #define TCG_CT_CONST_S32 0x200
43 #define TCG_CT_CONST_NN16 0x400
44 #define TCG_CT_CONST_NN32 0x800
45 #define TCG_CT_CONST_U31 0x1000
46 #define TCG_CT_CONST_S33 0x2000
47 #define TCG_CT_CONST_ZERO 0x4000
49 /* Several places within the instruction set 0 means "no register"
50 rather than TCG_REG_R0. */
51 #define TCG_REG_NONE 0
53 /* A scratch register that may be be used throughout the backend. */
54 #define TCG_TMP0 TCG_REG_R1
56 #ifndef CONFIG_SOFTMMU
57 #define TCG_GUEST_BASE_REG TCG_REG_R13
60 /* All of the following instructions are prefixed with their instruction
61 format, and are defined as 8- or 16-bit quantities, even when the two
62 halves of the 16-bit quantity may appear 32 bits apart in the insn.
63 This makes it easy to copy the values from the tables in Appendix B. */
64 typedef enum S390Opcode
{
243 #ifdef CONFIG_DEBUG_TCG
244 static const char * const tcg_target_reg_names
[TCG_TARGET_NB_REGS
] = {
245 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
246 "%r8", "%r9", "%r10" "%r11" "%r12" "%r13" "%r14" "%r15"
250 /* Since R6 is a potential argument register, choose it last of the
251 call-saved registers. Likewise prefer the call-clobbered registers
252 in reverse order to maximize the chance of avoiding the arguments. */
253 static const int tcg_target_reg_alloc_order
[] = {
254 /* Call saved registers. */
263 /* Call clobbered registers. */
267 /* Argument registers, in reverse order of allocation. */
274 static const int tcg_target_call_iarg_regs
[] = {
282 static const int tcg_target_call_oarg_regs
[] = {
290 #define S390_CC_NE (S390_CC_LT | S390_CC_GT)
291 #define S390_CC_LE (S390_CC_LT | S390_CC_EQ)
292 #define S390_CC_GE (S390_CC_GT | S390_CC_EQ)
293 #define S390_CC_NEVER 0
294 #define S390_CC_ALWAYS 15
296 /* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
297 static const uint8_t tcg_cond_to_s390_cond
[] = {
298 [TCG_COND_EQ
] = S390_CC_EQ
,
299 [TCG_COND_NE
] = S390_CC_NE
,
300 [TCG_COND_LT
] = S390_CC_LT
,
301 [TCG_COND_LE
] = S390_CC_LE
,
302 [TCG_COND_GT
] = S390_CC_GT
,
303 [TCG_COND_GE
] = S390_CC_GE
,
304 [TCG_COND_LTU
] = S390_CC_LT
,
305 [TCG_COND_LEU
] = S390_CC_LE
,
306 [TCG_COND_GTU
] = S390_CC_GT
,
307 [TCG_COND_GEU
] = S390_CC_GE
,
310 /* Condition codes that result from a LOAD AND TEST. Here, we have no
311 unsigned instruction variation, however since the test is vs zero we
312 can re-map the outcomes appropriately. */
313 static const uint8_t tcg_cond_to_ltr_cond
[] = {
314 [TCG_COND_EQ
] = S390_CC_EQ
,
315 [TCG_COND_NE
] = S390_CC_NE
,
316 [TCG_COND_LT
] = S390_CC_LT
,
317 [TCG_COND_LE
] = S390_CC_LE
,
318 [TCG_COND_GT
] = S390_CC_GT
,
319 [TCG_COND_GE
] = S390_CC_GE
,
320 [TCG_COND_LTU
] = S390_CC_NEVER
,
321 [TCG_COND_LEU
] = S390_CC_EQ
,
322 [TCG_COND_GTU
] = S390_CC_NE
,
323 [TCG_COND_GEU
] = S390_CC_ALWAYS
,
326 #ifdef CONFIG_SOFTMMU
327 static void * const qemu_ld_helpers
[16] = {
328 [MO_UB
] = helper_ret_ldub_mmu
,
329 [MO_SB
] = helper_ret_ldsb_mmu
,
330 [MO_LEUW
] = helper_le_lduw_mmu
,
331 [MO_LESW
] = helper_le_ldsw_mmu
,
332 [MO_LEUL
] = helper_le_ldul_mmu
,
333 [MO_LESL
] = helper_le_ldsl_mmu
,
334 [MO_LEQ
] = helper_le_ldq_mmu
,
335 [MO_BEUW
] = helper_be_lduw_mmu
,
336 [MO_BESW
] = helper_be_ldsw_mmu
,
337 [MO_BEUL
] = helper_be_ldul_mmu
,
338 [MO_BESL
] = helper_be_ldsl_mmu
,
339 [MO_BEQ
] = helper_be_ldq_mmu
,
342 static void * const qemu_st_helpers
[16] = {
343 [MO_UB
] = helper_ret_stb_mmu
,
344 [MO_LEUW
] = helper_le_stw_mmu
,
345 [MO_LEUL
] = helper_le_stl_mmu
,
346 [MO_LEQ
] = helper_le_stq_mmu
,
347 [MO_BEUW
] = helper_be_stw_mmu
,
348 [MO_BEUL
] = helper_be_stl_mmu
,
349 [MO_BEQ
] = helper_be_stq_mmu
,
353 static tcg_insn_unit
*tb_ret_addr
;
354 uint64_t s390_facilities
;
356 static void patch_reloc(tcg_insn_unit
*code_ptr
, int type
,
357 intptr_t value
, intptr_t addend
)
359 intptr_t pcrel2
= (tcg_insn_unit
*)value
- (code_ptr
- 1);
360 tcg_debug_assert(addend
== -2);
364 tcg_debug_assert(pcrel2
== (int16_t)pcrel2
);
365 tcg_patch16(code_ptr
, pcrel2
);
368 tcg_debug_assert(pcrel2
== (int32_t)pcrel2
);
369 tcg_patch32(code_ptr
, pcrel2
);
377 /* parse target specific constraints */
378 static const char *target_parse_constraint(TCGArgConstraint
*ct
,
379 const char *ct_str
, TCGType type
)
382 case 'r': /* all registers */
383 ct
->ct
|= TCG_CT_REG
;
384 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
386 case 'L': /* qemu_ld/st constraint */
387 ct
->ct
|= TCG_CT_REG
;
388 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
389 tcg_regset_reset_reg (ct
->u
.regs
, TCG_REG_R2
);
390 tcg_regset_reset_reg (ct
->u
.regs
, TCG_REG_R3
);
391 tcg_regset_reset_reg (ct
->u
.regs
, TCG_REG_R4
);
393 case 'a': /* force R2 for division */
394 ct
->ct
|= TCG_CT_REG
;
395 tcg_regset_clear(ct
->u
.regs
);
396 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_R2
);
398 case 'b': /* force R3 for division */
399 ct
->ct
|= TCG_CT_REG
;
400 tcg_regset_clear(ct
->u
.regs
);
401 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_R3
);
404 ct
->ct
|= TCG_CT_CONST_S33
;
407 ct
->ct
|= TCG_CT_CONST_S16
;
410 ct
->ct
|= TCG_CT_CONST_S32
;
413 ct
->ct
|= TCG_CT_CONST_NN16
;
416 ct
->ct
|= TCG_CT_CONST_NN32
;
419 /* ??? We have no insight here into whether the comparison is
420 signed or unsigned. The COMPARE IMMEDIATE insn uses a 32-bit
421 signed immediate, and the COMPARE LOGICAL IMMEDIATE insn uses
422 a 32-bit unsigned immediate. If we were to use the (semi)
423 obvious "val == (int32_t)val" we would be enabling unsigned
424 comparisons vs very large numbers. The only solution is to
425 take the intersection of the ranges. */
426 /* ??? Another possible solution is to simply lie and allow all
427 constants here and force the out-of-range values into a temp
428 register in tgen_cmp when we have knowledge of the actual
429 comparison code in use. */
430 ct
->ct
|= TCG_CT_CONST_U31
;
433 ct
->ct
|= TCG_CT_CONST_ZERO
;
441 /* Test if a constant matches the constraint. */
442 static int tcg_target_const_match(tcg_target_long val
, TCGType type
,
443 const TCGArgConstraint
*arg_ct
)
447 if (ct
& TCG_CT_CONST
) {
451 if (type
== TCG_TYPE_I32
) {
455 /* The following are mutually exclusive. */
456 if (ct
& TCG_CT_CONST_S16
) {
457 return val
== (int16_t)val
;
458 } else if (ct
& TCG_CT_CONST_S32
) {
459 return val
== (int32_t)val
;
460 } else if (ct
& TCG_CT_CONST_S33
) {
461 return val
>= -0xffffffffll
&& val
<= 0xffffffffll
;
462 } else if (ct
& TCG_CT_CONST_NN16
) {
463 return !(val
< 0 && val
== (int16_t)val
);
464 } else if (ct
& TCG_CT_CONST_NN32
) {
465 return !(val
< 0 && val
== (int32_t)val
);
466 } else if (ct
& TCG_CT_CONST_U31
) {
467 return val
>= 0 && val
<= 0x7fffffff;
468 } else if (ct
& TCG_CT_CONST_ZERO
) {
475 /* Emit instructions according to the given instruction format. */
477 static void tcg_out_insn_RR(TCGContext
*s
, S390Opcode op
, TCGReg r1
, TCGReg r2
)
479 tcg_out16(s
, (op
<< 8) | (r1
<< 4) | r2
);
482 static void tcg_out_insn_RRE(TCGContext
*s
, S390Opcode op
,
483 TCGReg r1
, TCGReg r2
)
485 tcg_out32(s
, (op
<< 16) | (r1
<< 4) | r2
);
488 static void tcg_out_insn_RRF(TCGContext
*s
, S390Opcode op
,
489 TCGReg r1
, TCGReg r2
, int m3
)
491 tcg_out32(s
, (op
<< 16) | (m3
<< 12) | (r1
<< 4) | r2
);
494 static void tcg_out_insn_RI(TCGContext
*s
, S390Opcode op
, TCGReg r1
, int i2
)
496 tcg_out32(s
, (op
<< 16) | (r1
<< 20) | (i2
& 0xffff));
499 static void tcg_out_insn_RIE(TCGContext
*s
, S390Opcode op
, TCGReg r1
,
502 tcg_out16(s
, (op
& 0xff00) | (r1
<< 4) | m3
);
503 tcg_out32(s
, (i2
<< 16) | (op
& 0xff));
506 static void tcg_out_insn_RIL(TCGContext
*s
, S390Opcode op
, TCGReg r1
, int i2
)
508 tcg_out16(s
, op
| (r1
<< 4));
512 static void tcg_out_insn_RS(TCGContext
*s
, S390Opcode op
, TCGReg r1
,
513 TCGReg b2
, TCGReg r3
, int disp
)
515 tcg_out32(s
, (op
<< 24) | (r1
<< 20) | (r3
<< 16) | (b2
<< 12)
519 static void tcg_out_insn_RSY(TCGContext
*s
, S390Opcode op
, TCGReg r1
,
520 TCGReg b2
, TCGReg r3
, int disp
)
522 tcg_out16(s
, (op
& 0xff00) | (r1
<< 4) | r3
);
523 tcg_out32(s
, (op
& 0xff) | (b2
<< 28)
524 | ((disp
& 0xfff) << 16) | ((disp
& 0xff000) >> 4));
527 #define tcg_out_insn_RX tcg_out_insn_RS
528 #define tcg_out_insn_RXY tcg_out_insn_RSY
530 /* Emit an opcode with "type-checking" of the format. */
531 #define tcg_out_insn(S, FMT, OP, ...) \
532 glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
535 /* emit 64-bit shifts */
536 static void tcg_out_sh64(TCGContext
* s
, S390Opcode op
, TCGReg dest
,
537 TCGReg src
, TCGReg sh_reg
, int sh_imm
)
539 tcg_out_insn_RSY(s
, op
, dest
, sh_reg
, src
, sh_imm
);
542 /* emit 32-bit shifts */
543 static void tcg_out_sh32(TCGContext
* s
, S390Opcode op
, TCGReg dest
,
544 TCGReg sh_reg
, int sh_imm
)
546 tcg_out_insn_RS(s
, op
, dest
, sh_reg
, 0, sh_imm
);
549 static void tcg_out_mov(TCGContext
*s
, TCGType type
, TCGReg dst
, TCGReg src
)
552 if (type
== TCG_TYPE_I32
) {
553 tcg_out_insn(s
, RR
, LR
, dst
, src
);
555 tcg_out_insn(s
, RRE
, LGR
, dst
, src
);
560 /* load a register with an immediate value */
561 static void tcg_out_movi(TCGContext
*s
, TCGType type
,
562 TCGReg ret
, tcg_target_long sval
)
564 static const S390Opcode lli_insns
[4] = {
565 RI_LLILL
, RI_LLILH
, RI_LLIHL
, RI_LLIHH
568 tcg_target_ulong uval
= sval
;
571 if (type
== TCG_TYPE_I32
) {
572 uval
= (uint32_t)sval
;
573 sval
= (int32_t)sval
;
576 /* Try all 32-bit insns that can load it in one go. */
577 if (sval
>= -0x8000 && sval
< 0x8000) {
578 tcg_out_insn(s
, RI
, LGHI
, ret
, sval
);
582 for (i
= 0; i
< 4; i
++) {
583 tcg_target_long mask
= 0xffffull
<< i
*16;
584 if ((uval
& mask
) == uval
) {
585 tcg_out_insn_RI(s
, lli_insns
[i
], ret
, uval
>> i
*16);
590 /* Try all 48-bit insns that can load it in one go. */
591 if (s390_facilities
& FACILITY_EXT_IMM
) {
592 if (sval
== (int32_t)sval
) {
593 tcg_out_insn(s
, RIL
, LGFI
, ret
, sval
);
596 if (uval
<= 0xffffffff) {
597 tcg_out_insn(s
, RIL
, LLILF
, ret
, uval
);
600 if ((uval
& 0xffffffff) == 0) {
601 tcg_out_insn(s
, RIL
, LLIHF
, ret
, uval
>> 31 >> 1);
606 /* Try for PC-relative address load. */
607 if ((sval
& 1) == 0) {
608 ptrdiff_t off
= tcg_pcrel_diff(s
, (void *)sval
) >> 1;
609 if (off
== (int32_t)off
) {
610 tcg_out_insn(s
, RIL
, LARL
, ret
, off
);
615 /* If extended immediates are not present, then we may have to issue
616 several instructions to load the low 32 bits. */
617 if (!(s390_facilities
& FACILITY_EXT_IMM
)) {
618 /* A 32-bit unsigned value can be loaded in 2 insns. And given
619 that the lli_insns loop above did not succeed, we know that
620 both insns are required. */
621 if (uval
<= 0xffffffff) {
622 tcg_out_insn(s
, RI
, LLILL
, ret
, uval
);
623 tcg_out_insn(s
, RI
, IILH
, ret
, uval
>> 16);
627 /* If all high bits are set, the value can be loaded in 2 or 3 insns.
628 We first want to make sure that all the high bits get set. With
629 luck the low 16-bits can be considered negative to perform that for
630 free, otherwise we load an explicit -1. */
631 if (sval
>> 31 >> 1 == -1) {
633 tcg_out_insn(s
, RI
, LGHI
, ret
, uval
);
635 tcg_out_insn(s
, RI
, LGHI
, ret
, -1);
636 tcg_out_insn(s
, RI
, IILL
, ret
, uval
);
638 tcg_out_insn(s
, RI
, IILH
, ret
, uval
>> 16);
643 /* If we get here, both the high and low parts have non-zero bits. */
645 /* Recurse to load the lower 32-bits. */
646 tcg_out_movi(s
, TCG_TYPE_I64
, ret
, uval
& 0xffffffff);
648 /* Insert data into the high 32-bits. */
649 uval
= uval
>> 31 >> 1;
650 if (s390_facilities
& FACILITY_EXT_IMM
) {
651 if (uval
< 0x10000) {
652 tcg_out_insn(s
, RI
, IIHL
, ret
, uval
);
653 } else if ((uval
& 0xffff) == 0) {
654 tcg_out_insn(s
, RI
, IIHH
, ret
, uval
>> 16);
656 tcg_out_insn(s
, RIL
, IIHF
, ret
, uval
);
660 tcg_out_insn(s
, RI
, IIHL
, ret
, uval
);
662 if (uval
& 0xffff0000) {
663 tcg_out_insn(s
, RI
, IIHH
, ret
, uval
>> 16);
669 /* Emit a load/store type instruction. Inputs are:
670 DATA: The register to be loaded or stored.
671 BASE+OFS: The effective address.
672 OPC_RX: If the operation has an RX format opcode (e.g. STC), otherwise 0.
673 OPC_RXY: The RXY format opcode for the operation (e.g. STCY). */
675 static void tcg_out_mem(TCGContext
*s
, S390Opcode opc_rx
, S390Opcode opc_rxy
,
676 TCGReg data
, TCGReg base
, TCGReg index
,
679 if (ofs
< -0x80000 || ofs
>= 0x80000) {
680 /* Combine the low 20 bits of the offset with the actual load insn;
681 the high 44 bits must come from an immediate load. */
682 tcg_target_long low
= ((ofs
& 0xfffff) ^ 0x80000) - 0x80000;
683 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_TMP0
, ofs
- low
);
686 /* If we were already given an index register, add it in. */
687 if (index
!= TCG_REG_NONE
) {
688 tcg_out_insn(s
, RRE
, AGR
, TCG_TMP0
, index
);
693 if (opc_rx
&& ofs
>= 0 && ofs
< 0x1000) {
694 tcg_out_insn_RX(s
, opc_rx
, data
, base
, index
, ofs
);
696 tcg_out_insn_RXY(s
, opc_rxy
, data
, base
, index
, ofs
);
701 /* load data without address translation or endianness conversion */
702 static inline void tcg_out_ld(TCGContext
*s
, TCGType type
, TCGReg data
,
703 TCGReg base
, intptr_t ofs
)
705 if (type
== TCG_TYPE_I32
) {
706 tcg_out_mem(s
, RX_L
, RXY_LY
, data
, base
, TCG_REG_NONE
, ofs
);
708 tcg_out_mem(s
, 0, RXY_LG
, data
, base
, TCG_REG_NONE
, ofs
);
712 static inline void tcg_out_st(TCGContext
*s
, TCGType type
, TCGReg data
,
713 TCGReg base
, intptr_t ofs
)
715 if (type
== TCG_TYPE_I32
) {
716 tcg_out_mem(s
, RX_ST
, RXY_STY
, data
, base
, TCG_REG_NONE
, ofs
);
718 tcg_out_mem(s
, 0, RXY_STG
, data
, base
, TCG_REG_NONE
, ofs
);
722 static inline bool tcg_out_sti(TCGContext
*s
, TCGType type
, TCGArg val
,
723 TCGReg base
, intptr_t ofs
)
728 /* load data from an absolute host address */
729 static void tcg_out_ld_abs(TCGContext
*s
, TCGType type
, TCGReg dest
, void *abs
)
731 intptr_t addr
= (intptr_t)abs
;
733 if ((s390_facilities
& FACILITY_GEN_INST_EXT
) && !(addr
& 1)) {
734 ptrdiff_t disp
= tcg_pcrel_diff(s
, abs
) >> 1;
735 if (disp
== (int32_t)disp
) {
736 if (type
== TCG_TYPE_I32
) {
737 tcg_out_insn(s
, RIL
, LRL
, dest
, disp
);
739 tcg_out_insn(s
, RIL
, LGRL
, dest
, disp
);
745 tcg_out_movi(s
, TCG_TYPE_PTR
, dest
, addr
& ~0xffff);
746 tcg_out_ld(s
, type
, dest
, dest
, addr
& 0xffff);
749 static inline void tcg_out_risbg(TCGContext
*s
, TCGReg dest
, TCGReg src
,
750 int msb
, int lsb
, int ofs
, int z
)
753 tcg_out16(s
, (RIE_RISBG
& 0xff00) | (dest
<< 4) | src
);
754 tcg_out16(s
, (msb
<< 8) | (z
<< 7) | lsb
);
755 tcg_out16(s
, (ofs
<< 8) | (RIE_RISBG
& 0xff));
758 static void tgen_ext8s(TCGContext
*s
, TCGType type
, TCGReg dest
, TCGReg src
)
760 if (s390_facilities
& FACILITY_EXT_IMM
) {
761 tcg_out_insn(s
, RRE
, LGBR
, dest
, src
);
765 if (type
== TCG_TYPE_I32
) {
767 tcg_out_sh32(s
, RS_SLL
, dest
, TCG_REG_NONE
, 24);
769 tcg_out_sh64(s
, RSY_SLLG
, dest
, src
, TCG_REG_NONE
, 24);
771 tcg_out_sh32(s
, RS_SRA
, dest
, TCG_REG_NONE
, 24);
773 tcg_out_sh64(s
, RSY_SLLG
, dest
, src
, TCG_REG_NONE
, 56);
774 tcg_out_sh64(s
, RSY_SRAG
, dest
, dest
, TCG_REG_NONE
, 56);
778 static void tgen_ext8u(TCGContext
*s
, TCGType type
, TCGReg dest
, TCGReg src
)
780 if (s390_facilities
& FACILITY_EXT_IMM
) {
781 tcg_out_insn(s
, RRE
, LLGCR
, dest
, src
);
786 tcg_out_movi(s
, type
, TCG_TMP0
, 0xff);
789 tcg_out_movi(s
, type
, dest
, 0xff);
791 if (type
== TCG_TYPE_I32
) {
792 tcg_out_insn(s
, RR
, NR
, dest
, src
);
794 tcg_out_insn(s
, RRE
, NGR
, dest
, src
);
798 static void tgen_ext16s(TCGContext
*s
, TCGType type
, TCGReg dest
, TCGReg src
)
800 if (s390_facilities
& FACILITY_EXT_IMM
) {
801 tcg_out_insn(s
, RRE
, LGHR
, dest
, src
);
805 if (type
== TCG_TYPE_I32
) {
807 tcg_out_sh32(s
, RS_SLL
, dest
, TCG_REG_NONE
, 16);
809 tcg_out_sh64(s
, RSY_SLLG
, dest
, src
, TCG_REG_NONE
, 16);
811 tcg_out_sh32(s
, RS_SRA
, dest
, TCG_REG_NONE
, 16);
813 tcg_out_sh64(s
, RSY_SLLG
, dest
, src
, TCG_REG_NONE
, 48);
814 tcg_out_sh64(s
, RSY_SRAG
, dest
, dest
, TCG_REG_NONE
, 48);
818 static void tgen_ext16u(TCGContext
*s
, TCGType type
, TCGReg dest
, TCGReg src
)
820 if (s390_facilities
& FACILITY_EXT_IMM
) {
821 tcg_out_insn(s
, RRE
, LLGHR
, dest
, src
);
826 tcg_out_movi(s
, type
, TCG_TMP0
, 0xffff);
829 tcg_out_movi(s
, type
, dest
, 0xffff);
831 if (type
== TCG_TYPE_I32
) {
832 tcg_out_insn(s
, RR
, NR
, dest
, src
);
834 tcg_out_insn(s
, RRE
, NGR
, dest
, src
);
838 static inline void tgen_ext32s(TCGContext
*s
, TCGReg dest
, TCGReg src
)
840 tcg_out_insn(s
, RRE
, LGFR
, dest
, src
);
843 static inline void tgen_ext32u(TCGContext
*s
, TCGReg dest
, TCGReg src
)
845 tcg_out_insn(s
, RRE
, LLGFR
, dest
, src
);
848 /* Accept bit patterns like these:
853 Copied from gcc sources. */
854 static inline bool risbg_mask(uint64_t c
)
857 /* We don't change the number of transitions by inverting,
858 so make sure we start with the LSB zero. */
862 /* Reject all zeros or all ones. */
866 /* Find the first transition. */
868 /* Invert to look for a second transition. */
870 /* Erase the first transition. */
872 /* Find the second transition, if any. */
874 /* Match if all the bits are 1's, or if c is zero. */
878 static void tgen_andi_risbg(TCGContext
*s
, TCGReg out
, TCGReg in
, uint64_t val
)
881 if ((val
& 0x8000000000000001ull
) == 0x8000000000000001ull
) {
882 /* Achieve wraparound by swapping msb and lsb. */
883 msb
= 64 - ctz64(~val
);
884 lsb
= clz64(~val
) - 1;
887 lsb
= 63 - ctz64(val
);
889 tcg_out_risbg(s
, out
, in
, msb
, lsb
, 0, 1);
892 static void tgen_andi(TCGContext
*s
, TCGType type
, TCGReg dest
, uint64_t val
)
894 static const S390Opcode ni_insns
[4] = {
895 RI_NILL
, RI_NILH
, RI_NIHL
, RI_NIHH
897 static const S390Opcode nif_insns
[2] = {
900 uint64_t valid
= (type
== TCG_TYPE_I32
? 0xffffffffull
: -1ull);
903 /* Look for the zero-extensions. */
904 if ((val
& valid
) == 0xffffffff) {
905 tgen_ext32u(s
, dest
, dest
);
908 if (s390_facilities
& FACILITY_EXT_IMM
) {
909 if ((val
& valid
) == 0xff) {
910 tgen_ext8u(s
, TCG_TYPE_I64
, dest
, dest
);
913 if ((val
& valid
) == 0xffff) {
914 tgen_ext16u(s
, TCG_TYPE_I64
, dest
, dest
);
919 /* Try all 32-bit insns that can perform it in one go. */
920 for (i
= 0; i
< 4; i
++) {
921 tcg_target_ulong mask
= ~(0xffffull
<< i
*16);
922 if (((val
| ~valid
) & mask
) == mask
) {
923 tcg_out_insn_RI(s
, ni_insns
[i
], dest
, val
>> i
*16);
928 /* Try all 48-bit insns that can perform it in one go. */
929 if (s390_facilities
& FACILITY_EXT_IMM
) {
930 for (i
= 0; i
< 2; i
++) {
931 tcg_target_ulong mask
= ~(0xffffffffull
<< i
*32);
932 if (((val
| ~valid
) & mask
) == mask
) {
933 tcg_out_insn_RIL(s
, nif_insns
[i
], dest
, val
>> i
*32);
938 if ((s390_facilities
& FACILITY_GEN_INST_EXT
) && risbg_mask(val
)) {
939 tgen_andi_risbg(s
, dest
, dest
, val
);
943 /* Fall back to loading the constant. */
944 tcg_out_movi(s
, type
, TCG_TMP0
, val
);
945 if (type
== TCG_TYPE_I32
) {
946 tcg_out_insn(s
, RR
, NR
, dest
, TCG_TMP0
);
948 tcg_out_insn(s
, RRE
, NGR
, dest
, TCG_TMP0
);
952 static void tgen64_ori(TCGContext
*s
, TCGReg dest
, tcg_target_ulong val
)
954 static const S390Opcode oi_insns
[4] = {
955 RI_OILL
, RI_OILH
, RI_OIHL
, RI_OIHH
957 static const S390Opcode nif_insns
[2] = {
963 /* Look for no-op. */
968 if (s390_facilities
& FACILITY_EXT_IMM
) {
969 /* Try all 32-bit insns that can perform it in one go. */
970 for (i
= 0; i
< 4; i
++) {
971 tcg_target_ulong mask
= (0xffffull
<< i
*16);
972 if ((val
& mask
) != 0 && (val
& ~mask
) == 0) {
973 tcg_out_insn_RI(s
, oi_insns
[i
], dest
, val
>> i
*16);
978 /* Try all 48-bit insns that can perform it in one go. */
979 for (i
= 0; i
< 2; i
++) {
980 tcg_target_ulong mask
= (0xffffffffull
<< i
*32);
981 if ((val
& mask
) != 0 && (val
& ~mask
) == 0) {
982 tcg_out_insn_RIL(s
, nif_insns
[i
], dest
, val
>> i
*32);
987 /* Perform the OR via sequential modifications to the high and
988 low parts. Do this via recursion to handle 16-bit vs 32-bit
989 masks in each half. */
990 tgen64_ori(s
, dest
, val
& 0x00000000ffffffffull
);
991 tgen64_ori(s
, dest
, val
& 0xffffffff00000000ull
);
993 /* With no extended-immediate facility, we don't need to be so
994 clever. Just iterate over the insns and mask in the constant. */
995 for (i
= 0; i
< 4; i
++) {
996 tcg_target_ulong mask
= (0xffffull
<< i
*16);
997 if ((val
& mask
) != 0) {
998 tcg_out_insn_RI(s
, oi_insns
[i
], dest
, val
>> i
*16);
1004 static void tgen64_xori(TCGContext
*s
, TCGReg dest
, tcg_target_ulong val
)
1006 /* Perform the xor by parts. */
1007 if (val
& 0xffffffff) {
1008 tcg_out_insn(s
, RIL
, XILF
, dest
, val
);
1010 if (val
> 0xffffffff) {
1011 tcg_out_insn(s
, RIL
, XIHF
, dest
, val
>> 31 >> 1);
1015 static int tgen_cmp(TCGContext
*s
, TCGType type
, TCGCond c
, TCGReg r1
,
1016 TCGArg c2
, bool c2const
, bool need_carry
)
1018 bool is_unsigned
= is_unsigned_cond(c
);
1021 if (!(is_unsigned
&& need_carry
)) {
1022 if (type
== TCG_TYPE_I32
) {
1023 tcg_out_insn(s
, RR
, LTR
, r1
, r1
);
1025 tcg_out_insn(s
, RRE
, LTGR
, r1
, r1
);
1027 return tcg_cond_to_ltr_cond
[c
];
1029 /* If we only got here because of load-and-test,
1030 and we couldn't use that, then we need to load
1031 the constant into a register. */
1032 if (!(s390_facilities
& FACILITY_EXT_IMM
)) {
1034 tcg_out_movi(s
, type
, c2
, 0);
1039 if (type
== TCG_TYPE_I32
) {
1040 tcg_out_insn(s
, RIL
, CLFI
, r1
, c2
);
1042 tcg_out_insn(s
, RIL
, CLGFI
, r1
, c2
);
1045 if (type
== TCG_TYPE_I32
) {
1046 tcg_out_insn(s
, RIL
, CFI
, r1
, c2
);
1048 tcg_out_insn(s
, RIL
, CGFI
, r1
, c2
);
1054 if (type
== TCG_TYPE_I32
) {
1055 tcg_out_insn(s
, RR
, CLR
, r1
, c2
);
1057 tcg_out_insn(s
, RRE
, CLGR
, r1
, c2
);
1060 if (type
== TCG_TYPE_I32
) {
1061 tcg_out_insn(s
, RR
, CR
, r1
, c2
);
1063 tcg_out_insn(s
, RRE
, CGR
, r1
, c2
);
1067 return tcg_cond_to_s390_cond
[c
];
1070 static void tgen_setcond(TCGContext
*s
, TCGType type
, TCGCond cond
,
1071 TCGReg dest
, TCGReg c1
, TCGArg c2
, int c2const
)
1076 /* With LOC2, we can always emit the minimum 3 insns. */
1077 if (s390_facilities
& FACILITY_LOAD_ON_COND2
) {
1078 /* Emit: d = 0, d = (cc ? 1 : d). */
1079 cc
= tgen_cmp(s
, type
, cond
, c1
, c2
, c2const
, false);
1080 tcg_out_movi(s
, TCG_TYPE_I64
, dest
, 0);
1081 tcg_out_insn(s
, RIE
, LOCGHI
, dest
, 1, cc
);
1085 have_loc
= (s390_facilities
& FACILITY_LOAD_ON_COND
) != 0;
1087 /* For HAVE_LOC, only the paths through GTU/GT/LEU/LE are smaller. */
1091 /* X != 0 is X > 0. */
1092 if (c2const
&& c2
== 0) {
1093 cond
= TCG_COND_GTU
;
1101 /* The result of a compare has CC=2 for GT and CC=3 unused.
1102 ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */
1103 tgen_cmp(s
, type
, cond
, c1
, c2
, c2const
, true);
1104 tcg_out_movi(s
, type
, dest
, 0);
1105 tcg_out_insn(s
, RRE
, ALCGR
, dest
, dest
);
1109 /* X == 0 is X <= 0. */
1110 if (c2const
&& c2
== 0) {
1111 cond
= TCG_COND_LEU
;
1119 /* As above, but we're looking for borrow, or !carry.
1120 The second insn computes d - d - borrow, or -1 for true
1121 and 0 for false. So we must mask to 1 bit afterward. */
1122 tgen_cmp(s
, type
, cond
, c1
, c2
, c2const
, true);
1123 tcg_out_insn(s
, RRE
, SLBGR
, dest
, dest
);
1124 tgen_andi(s
, type
, dest
, 1);
1131 /* Swap operands so that we can use LEU/GTU/GT/LE. */
1136 tcg_out_movi(s
, type
, TCG_TMP0
, c2
);
1145 cond
= tcg_swap_cond(cond
);
1149 g_assert_not_reached();
1152 cc
= tgen_cmp(s
, type
, cond
, c1
, c2
, c2const
, false);
1154 /* Emit: d = 0, t = 1, d = (cc ? t : d). */
1155 tcg_out_movi(s
, TCG_TYPE_I64
, dest
, 0);
1156 tcg_out_movi(s
, TCG_TYPE_I64
, TCG_TMP0
, 1);
1157 tcg_out_insn(s
, RRF
, LOCGR
, dest
, TCG_TMP0
, cc
);
1159 /* Emit: d = 1; if (cc) goto over; d = 0; over: */
1160 tcg_out_movi(s
, type
, dest
, 1);
1161 tcg_out_insn(s
, RI
, BRC
, cc
, (4 + 4) >> 1);
1162 tcg_out_movi(s
, type
, dest
, 0);
1166 static void tgen_movcond(TCGContext
*s
, TCGType type
, TCGCond c
, TCGReg dest
,
1167 TCGReg c1
, TCGArg c2
, int c2const
,
1168 TCGArg v3
, int v3const
)
1171 if (s390_facilities
& FACILITY_LOAD_ON_COND
) {
1172 cc
= tgen_cmp(s
, type
, c
, c1
, c2
, c2const
, false);
1174 tcg_out_insn(s
, RIE
, LOCGHI
, dest
, v3
, cc
);
1176 tcg_out_insn(s
, RRF
, LOCGR
, dest
, v3
, cc
);
1179 c
= tcg_invert_cond(c
);
1180 cc
= tgen_cmp(s
, type
, c
, c1
, c2
, c2const
, false);
1182 /* Emit: if (cc) goto over; dest = r3; over: */
1183 tcg_out_insn(s
, RI
, BRC
, cc
, (4 + 4) >> 1);
1184 tcg_out_insn(s
, RRE
, LGR
, dest
, v3
);
1188 static void tgen_clz(TCGContext
*s
, TCGReg dest
, TCGReg a1
,
1189 TCGArg a2
, int a2const
)
1191 /* Since this sets both R and R+1, we have no choice but to store the
1192 result into R0, allowing R1 == TCG_TMP0 to be clobbered as well. */
1193 QEMU_BUILD_BUG_ON(TCG_TMP0
!= TCG_REG_R1
);
1194 tcg_out_insn(s
, RRE
, FLOGR
, TCG_REG_R0
, a1
);
1196 if (a2const
&& a2
== 64) {
1197 tcg_out_mov(s
, TCG_TYPE_I64
, dest
, TCG_REG_R0
);
1200 tcg_out_movi(s
, TCG_TYPE_I64
, dest
, a2
);
1202 tcg_out_mov(s
, TCG_TYPE_I64
, dest
, a2
);
1204 if (s390_facilities
& FACILITY_LOAD_ON_COND
) {
1205 /* Emit: if (one bit found) dest = r0. */
1206 tcg_out_insn(s
, RRF
, LOCGR
, dest
, TCG_REG_R0
, 2);
1208 /* Emit: if (no one bit found) goto over; dest = r0; over: */
1209 tcg_out_insn(s
, RI
, BRC
, 8, (4 + 4) >> 1);
1210 tcg_out_insn(s
, RRE
, LGR
, dest
, TCG_REG_R0
);
1215 static void tgen_deposit(TCGContext
*s
, TCGReg dest
, TCGReg src
,
1216 int ofs
, int len
, int z
)
1218 int lsb
= (63 - ofs
);
1219 int msb
= lsb
- (len
- 1);
1220 tcg_out_risbg(s
, dest
, src
, msb
, lsb
, ofs
, z
);
1223 static void tgen_extract(TCGContext
*s
, TCGReg dest
, TCGReg src
,
1226 tcg_out_risbg(s
, dest
, src
, 64 - len
, 63, 64 - ofs
, 1);
1229 static void tgen_gotoi(TCGContext
*s
, int cc
, tcg_insn_unit
*dest
)
1231 ptrdiff_t off
= dest
- s
->code_ptr
;
1232 if (off
== (int16_t)off
) {
1233 tcg_out_insn(s
, RI
, BRC
, cc
, off
);
1234 } else if (off
== (int32_t)off
) {
1235 tcg_out_insn(s
, RIL
, BRCL
, cc
, off
);
1237 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_TMP0
, (uintptr_t)dest
);
1238 tcg_out_insn(s
, RR
, BCR
, cc
, TCG_TMP0
);
1242 static void tgen_branch(TCGContext
*s
, int cc
, TCGLabel
*l
)
1245 tgen_gotoi(s
, cc
, l
->u
.value_ptr
);
1246 } else if (USE_LONG_BRANCHES
) {
1247 tcg_out16(s
, RIL_BRCL
| (cc
<< 4));
1248 tcg_out_reloc(s
, s
->code_ptr
, R_390_PC32DBL
, l
, -2);
1251 tcg_out16(s
, RI_BRC
| (cc
<< 4));
1252 tcg_out_reloc(s
, s
->code_ptr
, R_390_PC16DBL
, l
, -2);
1257 static void tgen_compare_branch(TCGContext
*s
, S390Opcode opc
, int cc
,
1258 TCGReg r1
, TCGReg r2
, TCGLabel
*l
)
1263 off
= l
->u
.value_ptr
- s
->code_ptr
;
1265 /* We need to keep the offset unchanged for retranslation. */
1266 off
= s
->code_ptr
[1];
1267 tcg_out_reloc(s
, s
->code_ptr
+ 1, R_390_PC16DBL
, l
, -2);
1270 tcg_out16(s
, (opc
& 0xff00) | (r1
<< 4) | r2
);
1272 tcg_out16(s
, cc
<< 12 | (opc
& 0xff));
1275 static void tgen_compare_imm_branch(TCGContext
*s
, S390Opcode opc
, int cc
,
1276 TCGReg r1
, int i2
, TCGLabel
*l
)
1278 tcg_target_long off
;
1281 off
= l
->u
.value_ptr
- s
->code_ptr
;
1283 /* We need to keep the offset unchanged for retranslation. */
1284 off
= s
->code_ptr
[1];
1285 tcg_out_reloc(s
, s
->code_ptr
+ 1, R_390_PC16DBL
, l
, -2);
1288 tcg_out16(s
, (opc
& 0xff00) | (r1
<< 4) | cc
);
1290 tcg_out16(s
, (i2
<< 8) | (opc
& 0xff));
1293 static void tgen_brcond(TCGContext
*s
, TCGType type
, TCGCond c
,
1294 TCGReg r1
, TCGArg c2
, int c2const
, TCGLabel
*l
)
1298 if (s390_facilities
& FACILITY_GEN_INST_EXT
) {
1299 bool is_unsigned
= is_unsigned_cond(c
);
1303 cc
= tcg_cond_to_s390_cond
[c
];
1306 opc
= (type
== TCG_TYPE_I32
1307 ? (is_unsigned
? RIE_CLRJ
: RIE_CRJ
)
1308 : (is_unsigned
? RIE_CLGRJ
: RIE_CGRJ
));
1309 tgen_compare_branch(s
, opc
, cc
, r1
, c2
, l
);
1313 /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1314 If the immediate we've been given does not fit that range, we'll
1315 fall back to separate compare and branch instructions using the
1316 larger comparison range afforded by COMPARE IMMEDIATE. */
1317 if (type
== TCG_TYPE_I32
) {
1320 in_range
= (uint32_t)c2
== (uint8_t)c2
;
1323 in_range
= (int32_t)c2
== (int8_t)c2
;
1328 in_range
= (uint64_t)c2
== (uint8_t)c2
;
1331 in_range
= (int64_t)c2
== (int8_t)c2
;
1335 tgen_compare_imm_branch(s
, opc
, cc
, r1
, c2
, l
);
1340 cc
= tgen_cmp(s
, type
, c
, r1
, c2
, c2const
, false);
1341 tgen_branch(s
, cc
, l
);
1344 static void tcg_out_call(TCGContext
*s
, tcg_insn_unit
*dest
)
1346 ptrdiff_t off
= dest
- s
->code_ptr
;
1347 if (off
== (int32_t)off
) {
1348 tcg_out_insn(s
, RIL
, BRASL
, TCG_REG_R14
, off
);
1350 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_TMP0
, (uintptr_t)dest
);
1351 tcg_out_insn(s
, RR
, BASR
, TCG_REG_R14
, TCG_TMP0
);
1355 static void tcg_out_qemu_ld_direct(TCGContext
*s
, TCGMemOp opc
, TCGReg data
,
1356 TCGReg base
, TCGReg index
, int disp
)
1358 switch (opc
& (MO_SSIZE
| MO_BSWAP
)) {
1360 tcg_out_insn(s
, RXY
, LLGC
, data
, base
, index
, disp
);
1363 tcg_out_insn(s
, RXY
, LGB
, data
, base
, index
, disp
);
1366 case MO_UW
| MO_BSWAP
:
1367 /* swapped unsigned halfword load with upper bits zeroed */
1368 tcg_out_insn(s
, RXY
, LRVH
, data
, base
, index
, disp
);
1369 tgen_ext16u(s
, TCG_TYPE_I64
, data
, data
);
1372 tcg_out_insn(s
, RXY
, LLGH
, data
, base
, index
, disp
);
1375 case MO_SW
| MO_BSWAP
:
1376 /* swapped sign-extended halfword load */
1377 tcg_out_insn(s
, RXY
, LRVH
, data
, base
, index
, disp
);
1378 tgen_ext16s(s
, TCG_TYPE_I64
, data
, data
);
1381 tcg_out_insn(s
, RXY
, LGH
, data
, base
, index
, disp
);
1384 case MO_UL
| MO_BSWAP
:
1385 /* swapped unsigned int load with upper bits zeroed */
1386 tcg_out_insn(s
, RXY
, LRV
, data
, base
, index
, disp
);
1387 tgen_ext32u(s
, data
, data
);
1390 tcg_out_insn(s
, RXY
, LLGF
, data
, base
, index
, disp
);
1393 case MO_SL
| MO_BSWAP
:
1394 /* swapped sign-extended int load */
1395 tcg_out_insn(s
, RXY
, LRV
, data
, base
, index
, disp
);
1396 tgen_ext32s(s
, data
, data
);
1399 tcg_out_insn(s
, RXY
, LGF
, data
, base
, index
, disp
);
1402 case MO_Q
| MO_BSWAP
:
1403 tcg_out_insn(s
, RXY
, LRVG
, data
, base
, index
, disp
);
1406 tcg_out_insn(s
, RXY
, LG
, data
, base
, index
, disp
);
1414 static void tcg_out_qemu_st_direct(TCGContext
*s
, TCGMemOp opc
, TCGReg data
,
1415 TCGReg base
, TCGReg index
, int disp
)
1417 switch (opc
& (MO_SIZE
| MO_BSWAP
)) {
1419 if (disp
>= 0 && disp
< 0x1000) {
1420 tcg_out_insn(s
, RX
, STC
, data
, base
, index
, disp
);
1422 tcg_out_insn(s
, RXY
, STCY
, data
, base
, index
, disp
);
1426 case MO_UW
| MO_BSWAP
:
1427 tcg_out_insn(s
, RXY
, STRVH
, data
, base
, index
, disp
);
1430 if (disp
>= 0 && disp
< 0x1000) {
1431 tcg_out_insn(s
, RX
, STH
, data
, base
, index
, disp
);
1433 tcg_out_insn(s
, RXY
, STHY
, data
, base
, index
, disp
);
1437 case MO_UL
| MO_BSWAP
:
1438 tcg_out_insn(s
, RXY
, STRV
, data
, base
, index
, disp
);
1441 if (disp
>= 0 && disp
< 0x1000) {
1442 tcg_out_insn(s
, RX
, ST
, data
, base
, index
, disp
);
1444 tcg_out_insn(s
, RXY
, STY
, data
, base
, index
, disp
);
1448 case MO_Q
| MO_BSWAP
:
1449 tcg_out_insn(s
, RXY
, STRVG
, data
, base
, index
, disp
);
1452 tcg_out_insn(s
, RXY
, STG
, data
, base
, index
, disp
);
1460 #if defined(CONFIG_SOFTMMU)
1461 /* We're expecting to use a 20-bit signed offset on the tlb memory ops.
1462 Using the offset of the second entry in the last tlb table ensures
1463 that we can index all of the elements of the first entry. */
1464 QEMU_BUILD_BUG_ON(offsetof(CPUArchState
, tlb_table
[NB_MMU_MODES
- 1][1])
1467 /* Load and compare a TLB entry, leaving the flags set. Loads the TLB
1468 addend into R2. Returns a register with the santitized guest address. */
1469 static TCGReg
tcg_out_tlb_read(TCGContext
* s
, TCGReg addr_reg
, TCGMemOp opc
,
1470 int mem_index
, bool is_ld
)
1472 unsigned s_bits
= opc
& MO_SIZE
;
1473 unsigned a_bits
= get_alignment_bits(opc
);
1474 unsigned s_mask
= (1 << s_bits
) - 1;
1475 unsigned a_mask
= (1 << a_bits
) - 1;
1479 /* For aligned accesses, we check the first byte and include the alignment
1480 bits within the address. For unaligned access, we check that we don't
1481 cross pages using the address of the last byte of the access. */
1482 a_off
= (a_bits
>= s_bits
? 0 : s_mask
- a_mask
);
1483 tlb_mask
= (uint64_t)TARGET_PAGE_MASK
| a_mask
;
1485 if (s390_facilities
& FACILITY_GEN_INST_EXT
) {
1486 tcg_out_risbg(s
, TCG_REG_R2
, addr_reg
,
1487 64 - CPU_TLB_BITS
- CPU_TLB_ENTRY_BITS
,
1488 63 - CPU_TLB_ENTRY_BITS
,
1489 64 + CPU_TLB_ENTRY_BITS
- TARGET_PAGE_BITS
, 1);
1491 tcg_out_insn(s
, RX
, LA
, TCG_REG_R3
, addr_reg
, TCG_REG_NONE
, a_off
);
1492 tgen_andi(s
, TCG_TYPE_TL
, TCG_REG_R3
, tlb_mask
);
1494 tgen_andi_risbg(s
, TCG_REG_R3
, addr_reg
, tlb_mask
);
1497 tcg_out_sh64(s
, RSY_SRLG
, TCG_REG_R2
, addr_reg
, TCG_REG_NONE
,
1498 TARGET_PAGE_BITS
- CPU_TLB_ENTRY_BITS
);
1499 tcg_out_insn(s
, RX
, LA
, TCG_REG_R3
, addr_reg
, TCG_REG_NONE
, a_off
);
1500 tgen_andi(s
, TCG_TYPE_I64
, TCG_REG_R2
,
1501 (CPU_TLB_SIZE
- 1) << CPU_TLB_ENTRY_BITS
);
1502 tgen_andi(s
, TCG_TYPE_TL
, TCG_REG_R3
, tlb_mask
);
1506 ofs
= offsetof(CPUArchState
, tlb_table
[mem_index
][0].addr_read
);
1508 ofs
= offsetof(CPUArchState
, tlb_table
[mem_index
][0].addr_write
);
1510 if (TARGET_LONG_BITS
== 32) {
1511 tcg_out_mem(s
, RX_C
, RXY_CY
, TCG_REG_R3
, TCG_REG_R2
, TCG_AREG0
, ofs
);
1513 tcg_out_mem(s
, 0, RXY_CG
, TCG_REG_R3
, TCG_REG_R2
, TCG_AREG0
, ofs
);
1516 ofs
= offsetof(CPUArchState
, tlb_table
[mem_index
][0].addend
);
1517 tcg_out_mem(s
, 0, RXY_LG
, TCG_REG_R2
, TCG_REG_R2
, TCG_AREG0
, ofs
);
1519 if (TARGET_LONG_BITS
== 32) {
1520 tgen_ext32u(s
, TCG_REG_R3
, addr_reg
);
1526 static void add_qemu_ldst_label(TCGContext
*s
, bool is_ld
, TCGMemOpIdx oi
,
1527 TCGReg data
, TCGReg addr
,
1528 tcg_insn_unit
*raddr
, tcg_insn_unit
*label_ptr
)
1530 TCGLabelQemuLdst
*label
= new_ldst_label(s
);
1532 label
->is_ld
= is_ld
;
1534 label
->datalo_reg
= data
;
1535 label
->addrlo_reg
= addr
;
1536 label
->raddr
= raddr
;
1537 label
->label_ptr
[0] = label_ptr
;
1540 static void tcg_out_qemu_ld_slow_path(TCGContext
*s
, TCGLabelQemuLdst
*lb
)
1542 TCGReg addr_reg
= lb
->addrlo_reg
;
1543 TCGReg data_reg
= lb
->datalo_reg
;
1544 TCGMemOpIdx oi
= lb
->oi
;
1545 TCGMemOp opc
= get_memop(oi
);
1547 patch_reloc(lb
->label_ptr
[0], R_390_PC16DBL
, (intptr_t)s
->code_ptr
, -2);
1549 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_REG_R2
, TCG_AREG0
);
1550 if (TARGET_LONG_BITS
== 64) {
1551 tcg_out_mov(s
, TCG_TYPE_I64
, TCG_REG_R3
, addr_reg
);
1553 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_R4
, oi
);
1554 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R5
, (uintptr_t)lb
->raddr
);
1555 tcg_out_call(s
, qemu_ld_helpers
[opc
& (MO_BSWAP
| MO_SSIZE
)]);
1556 tcg_out_mov(s
, TCG_TYPE_I64
, data_reg
, TCG_REG_R2
);
1558 tgen_gotoi(s
, S390_CC_ALWAYS
, lb
->raddr
);
1561 static void tcg_out_qemu_st_slow_path(TCGContext
*s
, TCGLabelQemuLdst
*lb
)
1563 TCGReg addr_reg
= lb
->addrlo_reg
;
1564 TCGReg data_reg
= lb
->datalo_reg
;
1565 TCGMemOpIdx oi
= lb
->oi
;
1566 TCGMemOp opc
= get_memop(oi
);
1568 patch_reloc(lb
->label_ptr
[0], R_390_PC16DBL
, (intptr_t)s
->code_ptr
, -2);
1570 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_REG_R2
, TCG_AREG0
);
1571 if (TARGET_LONG_BITS
== 64) {
1572 tcg_out_mov(s
, TCG_TYPE_I64
, TCG_REG_R3
, addr_reg
);
1574 switch (opc
& MO_SIZE
) {
1576 tgen_ext8u(s
, TCG_TYPE_I64
, TCG_REG_R4
, data_reg
);
1579 tgen_ext16u(s
, TCG_TYPE_I64
, TCG_REG_R4
, data_reg
);
1582 tgen_ext32u(s
, TCG_REG_R4
, data_reg
);
1585 tcg_out_mov(s
, TCG_TYPE_I64
, TCG_REG_R4
, data_reg
);
1590 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_R5
, oi
);
1591 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R6
, (uintptr_t)lb
->raddr
);
1592 tcg_out_call(s
, qemu_st_helpers
[opc
& (MO_BSWAP
| MO_SIZE
)]);
1594 tgen_gotoi(s
, S390_CC_ALWAYS
, lb
->raddr
);
1597 static void tcg_prepare_user_ldst(TCGContext
*s
, TCGReg
*addr_reg
,
1598 TCGReg
*index_reg
, tcg_target_long
*disp
)
1600 if (TARGET_LONG_BITS
== 32) {
1601 tgen_ext32u(s
, TCG_TMP0
, *addr_reg
);
1602 *addr_reg
= TCG_TMP0
;
1604 if (guest_base
< 0x80000) {
1605 *index_reg
= TCG_REG_NONE
;
1608 *index_reg
= TCG_GUEST_BASE_REG
;
1612 #endif /* CONFIG_SOFTMMU */
1614 static void tcg_out_qemu_ld(TCGContext
* s
, TCGReg data_reg
, TCGReg addr_reg
,
1617 TCGMemOp opc
= get_memop(oi
);
1618 #ifdef CONFIG_SOFTMMU
1619 unsigned mem_index
= get_mmuidx(oi
);
1620 tcg_insn_unit
*label_ptr
;
1623 base_reg
= tcg_out_tlb_read(s
, addr_reg
, opc
, mem_index
, 1);
1625 /* We need to keep the offset unchanged for retranslation. */
1626 tcg_out16(s
, RI_BRC
| (S390_CC_NE
<< 4));
1627 label_ptr
= s
->code_ptr
;
1630 tcg_out_qemu_ld_direct(s
, opc
, data_reg
, base_reg
, TCG_REG_R2
, 0);
1632 add_qemu_ldst_label(s
, 1, oi
, data_reg
, addr_reg
, s
->code_ptr
, label_ptr
);
1635 tcg_target_long disp
;
1637 tcg_prepare_user_ldst(s
, &addr_reg
, &index_reg
, &disp
);
1638 tcg_out_qemu_ld_direct(s
, opc
, data_reg
, addr_reg
, index_reg
, disp
);
1642 static void tcg_out_qemu_st(TCGContext
* s
, TCGReg data_reg
, TCGReg addr_reg
,
1645 TCGMemOp opc
= get_memop(oi
);
1646 #ifdef CONFIG_SOFTMMU
1647 unsigned mem_index
= get_mmuidx(oi
);
1648 tcg_insn_unit
*label_ptr
;
1651 base_reg
= tcg_out_tlb_read(s
, addr_reg
, opc
, mem_index
, 0);
1653 /* We need to keep the offset unchanged for retranslation. */
1654 tcg_out16(s
, RI_BRC
| (S390_CC_NE
<< 4));
1655 label_ptr
= s
->code_ptr
;
1658 tcg_out_qemu_st_direct(s
, opc
, data_reg
, base_reg
, TCG_REG_R2
, 0);
1660 add_qemu_ldst_label(s
, 0, oi
, data_reg
, addr_reg
, s
->code_ptr
, label_ptr
);
1663 tcg_target_long disp
;
1665 tcg_prepare_user_ldst(s
, &addr_reg
, &index_reg
, &disp
);
1666 tcg_out_qemu_st_direct(s
, opc
, data_reg
, addr_reg
, index_reg
, disp
);
1670 # define OP_32_64(x) \
1671 case glue(glue(INDEX_op_,x),_i32): \
1672 case glue(glue(INDEX_op_,x),_i64)
1674 static inline void tcg_out_op(TCGContext
*s
, TCGOpcode opc
,
1675 const TCGArg
*args
, const int *const_args
)
1681 case INDEX_op_exit_tb
:
1682 /* Reuse the zeroing that exists for goto_ptr. */
1685 tgen_gotoi(s
, S390_CC_ALWAYS
, s
->code_gen_epilogue
);
1687 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R2
, a0
);
1688 tgen_gotoi(s
, S390_CC_ALWAYS
, tb_ret_addr
);
1692 case INDEX_op_goto_tb
:
1693 if (s
->tb_jmp_insn_offset
) {
1694 /* branch displacement must be aligned for atomic patching;
1695 * see if we need to add extra nop before branch
1697 if (!QEMU_PTR_IS_ALIGNED(s
->code_ptr
+ 1, 4)) {
1700 tcg_out16(s
, RIL_BRCL
| (S390_CC_ALWAYS
<< 4));
1701 s
->tb_jmp_insn_offset
[args
[0]] = tcg_current_code_size(s
);
1704 /* load address stored at s->tb_jmp_target_addr + args[0] */
1705 tcg_out_ld_abs(s
, TCG_TYPE_PTR
, TCG_TMP0
,
1706 s
->tb_jmp_target_addr
+ args
[0]);
1708 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, TCG_TMP0
);
1710 s
->tb_jmp_reset_offset
[args
[0]] = tcg_current_code_size(s
);
1713 case INDEX_op_goto_ptr
:
1714 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, args
[0]);
1718 /* ??? LLC (RXY format) is only present with the extended-immediate
1719 facility, whereas LLGC is always present. */
1720 tcg_out_mem(s
, 0, RXY_LLGC
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1724 /* ??? LB is no smaller than LGB, so no point to using it. */
1725 tcg_out_mem(s
, 0, RXY_LGB
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1729 /* ??? LLH (RXY format) is only present with the extended-immediate
1730 facility, whereas LLGH is always present. */
1731 tcg_out_mem(s
, 0, RXY_LLGH
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1734 case INDEX_op_ld16s_i32
:
1735 tcg_out_mem(s
, RX_LH
, RXY_LHY
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1738 case INDEX_op_ld_i32
:
1739 tcg_out_ld(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1743 tcg_out_mem(s
, RX_STC
, RXY_STCY
, args
[0], args
[1],
1744 TCG_REG_NONE
, args
[2]);
1748 tcg_out_mem(s
, RX_STH
, RXY_STHY
, args
[0], args
[1],
1749 TCG_REG_NONE
, args
[2]);
1752 case INDEX_op_st_i32
:
1753 tcg_out_st(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1756 case INDEX_op_add_i32
:
1757 a0
= args
[0], a1
= args
[1], a2
= (int32_t)args
[2];
1758 if (const_args
[2]) {
1761 if (a2
== (int16_t)a2
) {
1762 tcg_out_insn(s
, RI
, AHI
, a0
, a2
);
1765 if (s390_facilities
& FACILITY_EXT_IMM
) {
1766 tcg_out_insn(s
, RIL
, AFI
, a0
, a2
);
1770 tcg_out_mem(s
, RX_LA
, RXY_LAY
, a0
, a1
, TCG_REG_NONE
, a2
);
1771 } else if (a0
== a1
) {
1772 tcg_out_insn(s
, RR
, AR
, a0
, a2
);
1774 tcg_out_insn(s
, RX
, LA
, a0
, a1
, a2
, 0);
1777 case INDEX_op_sub_i32
:
1778 a0
= args
[0], a1
= args
[1], a2
= (int32_t)args
[2];
1779 if (const_args
[2]) {
1782 } else if (a0
== a1
) {
1783 tcg_out_insn(s
, RR
, SR
, a0
, a2
);
1785 tcg_out_insn(s
, RRF
, SRK
, a0
, a1
, a2
);
1789 case INDEX_op_and_i32
:
1790 a0
= args
[0], a1
= args
[1], a2
= (uint32_t)args
[2];
1791 if (const_args
[2]) {
1792 tcg_out_mov(s
, TCG_TYPE_I32
, a0
, a1
);
1793 tgen_andi(s
, TCG_TYPE_I32
, a0
, a2
);
1794 } else if (a0
== a1
) {
1795 tcg_out_insn(s
, RR
, NR
, a0
, a2
);
1797 tcg_out_insn(s
, RRF
, NRK
, a0
, a1
, a2
);
1800 case INDEX_op_or_i32
:
1801 a0
= args
[0], a1
= args
[1], a2
= (uint32_t)args
[2];
1802 if (const_args
[2]) {
1803 tcg_out_mov(s
, TCG_TYPE_I32
, a0
, a1
);
1804 tgen64_ori(s
, a0
, a2
);
1805 } else if (a0
== a1
) {
1806 tcg_out_insn(s
, RR
, OR
, a0
, a2
);
1808 tcg_out_insn(s
, RRF
, ORK
, a0
, a1
, a2
);
1811 case INDEX_op_xor_i32
:
1812 a0
= args
[0], a1
= args
[1], a2
= (uint32_t)args
[2];
1813 if (const_args
[2]) {
1814 tcg_out_mov(s
, TCG_TYPE_I32
, a0
, a1
);
1815 tgen64_xori(s
, a0
, a2
);
1816 } else if (a0
== a1
) {
1817 tcg_out_insn(s
, RR
, XR
, args
[0], args
[2]);
1819 tcg_out_insn(s
, RRF
, XRK
, a0
, a1
, a2
);
1823 case INDEX_op_neg_i32
:
1824 tcg_out_insn(s
, RR
, LCR
, args
[0], args
[1]);
1827 case INDEX_op_mul_i32
:
1828 if (const_args
[2]) {
1829 if ((int32_t)args
[2] == (int16_t)args
[2]) {
1830 tcg_out_insn(s
, RI
, MHI
, args
[0], args
[2]);
1832 tcg_out_insn(s
, RIL
, MSFI
, args
[0], args
[2]);
1835 tcg_out_insn(s
, RRE
, MSR
, args
[0], args
[2]);
1839 case INDEX_op_div2_i32
:
1840 tcg_out_insn(s
, RR
, DR
, TCG_REG_R2
, args
[4]);
1842 case INDEX_op_divu2_i32
:
1843 tcg_out_insn(s
, RRE
, DLR
, TCG_REG_R2
, args
[4]);
1846 case INDEX_op_shl_i32
:
1850 a0
= args
[0], a1
= args
[1], a2
= (int32_t)args
[2];
1852 if (const_args
[2]) {
1853 tcg_out_sh32(s
, op
, a0
, TCG_REG_NONE
, a2
);
1855 tcg_out_sh32(s
, op
, a0
, a2
, 0);
1858 /* Using tcg_out_sh64 here for the format; it is a 32-bit shift. */
1859 if (const_args
[2]) {
1860 tcg_out_sh64(s
, op2
, a0
, a1
, TCG_REG_NONE
, a2
);
1862 tcg_out_sh64(s
, op2
, a0
, a1
, a2
, 0);
1866 case INDEX_op_shr_i32
:
1870 case INDEX_op_sar_i32
:
1875 case INDEX_op_rotl_i32
:
1876 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1877 if (const_args
[2]) {
1878 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1880 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], args
[2], 0);
1883 case INDEX_op_rotr_i32
:
1884 if (const_args
[2]) {
1885 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1],
1886 TCG_REG_NONE
, (32 - args
[2]) & 31);
1888 tcg_out_insn(s
, RR
, LCR
, TCG_TMP0
, args
[2]);
1889 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], TCG_TMP0
, 0);
1893 case INDEX_op_ext8s_i32
:
1894 tgen_ext8s(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1896 case INDEX_op_ext16s_i32
:
1897 tgen_ext16s(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1899 case INDEX_op_ext8u_i32
:
1900 tgen_ext8u(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1902 case INDEX_op_ext16u_i32
:
1903 tgen_ext16u(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1907 /* The TCG bswap definition requires bits 0-47 already be zero.
1908 Thus we don't need the G-type insns to implement bswap16_i64. */
1909 tcg_out_insn(s
, RRE
, LRVR
, args
[0], args
[1]);
1910 tcg_out_sh32(s
, RS_SRL
, args
[0], TCG_REG_NONE
, 16);
1913 tcg_out_insn(s
, RRE
, LRVR
, args
[0], args
[1]);
1916 case INDEX_op_add2_i32
:
1917 if (const_args
[4]) {
1918 tcg_out_insn(s
, RIL
, ALFI
, args
[0], args
[4]);
1920 tcg_out_insn(s
, RR
, ALR
, args
[0], args
[4]);
1922 tcg_out_insn(s
, RRE
, ALCR
, args
[1], args
[5]);
1924 case INDEX_op_sub2_i32
:
1925 if (const_args
[4]) {
1926 tcg_out_insn(s
, RIL
, SLFI
, args
[0], args
[4]);
1928 tcg_out_insn(s
, RR
, SLR
, args
[0], args
[4]);
1930 tcg_out_insn(s
, RRE
, SLBR
, args
[1], args
[5]);
1934 tgen_branch(s
, S390_CC_ALWAYS
, arg_label(args
[0]));
1937 case INDEX_op_brcond_i32
:
1938 tgen_brcond(s
, TCG_TYPE_I32
, args
[2], args
[0],
1939 args
[1], const_args
[1], arg_label(args
[3]));
1941 case INDEX_op_setcond_i32
:
1942 tgen_setcond(s
, TCG_TYPE_I32
, args
[3], args
[0], args
[1],
1943 args
[2], const_args
[2]);
1945 case INDEX_op_movcond_i32
:
1946 tgen_movcond(s
, TCG_TYPE_I32
, args
[5], args
[0], args
[1],
1947 args
[2], const_args
[2], args
[3], const_args
[3]);
1950 case INDEX_op_qemu_ld_i32
:
1951 /* ??? Technically we can use a non-extending instruction. */
1952 case INDEX_op_qemu_ld_i64
:
1953 tcg_out_qemu_ld(s
, args
[0], args
[1], args
[2]);
1955 case INDEX_op_qemu_st_i32
:
1956 case INDEX_op_qemu_st_i64
:
1957 tcg_out_qemu_st(s
, args
[0], args
[1], args
[2]);
1960 case INDEX_op_ld16s_i64
:
1961 tcg_out_mem(s
, 0, RXY_LGH
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1963 case INDEX_op_ld32u_i64
:
1964 tcg_out_mem(s
, 0, RXY_LLGF
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1966 case INDEX_op_ld32s_i64
:
1967 tcg_out_mem(s
, 0, RXY_LGF
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1969 case INDEX_op_ld_i64
:
1970 tcg_out_ld(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
1973 case INDEX_op_st32_i64
:
1974 tcg_out_st(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1976 case INDEX_op_st_i64
:
1977 tcg_out_st(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
1980 case INDEX_op_add_i64
:
1981 a0
= args
[0], a1
= args
[1], a2
= args
[2];
1982 if (const_args
[2]) {
1985 if (a2
== (int16_t)a2
) {
1986 tcg_out_insn(s
, RI
, AGHI
, a0
, a2
);
1989 if (s390_facilities
& FACILITY_EXT_IMM
) {
1990 if (a2
== (int32_t)a2
) {
1991 tcg_out_insn(s
, RIL
, AGFI
, a0
, a2
);
1993 } else if (a2
== (uint32_t)a2
) {
1994 tcg_out_insn(s
, RIL
, ALGFI
, a0
, a2
);
1996 } else if (-a2
== (uint32_t)-a2
) {
1997 tcg_out_insn(s
, RIL
, SLGFI
, a0
, -a2
);
2002 tcg_out_mem(s
, RX_LA
, RXY_LAY
, a0
, a1
, TCG_REG_NONE
, a2
);
2003 } else if (a0
== a1
) {
2004 tcg_out_insn(s
, RRE
, AGR
, a0
, a2
);
2006 tcg_out_insn(s
, RX
, LA
, a0
, a1
, a2
, 0);
2009 case INDEX_op_sub_i64
:
2010 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2011 if (const_args
[2]) {
2014 } else if (a0
== a1
) {
2015 tcg_out_insn(s
, RRE
, SGR
, a0
, a2
);
2017 tcg_out_insn(s
, RRF
, SGRK
, a0
, a1
, a2
);
2021 case INDEX_op_and_i64
:
2022 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2023 if (const_args
[2]) {
2024 tcg_out_mov(s
, TCG_TYPE_I64
, a0
, a1
);
2025 tgen_andi(s
, TCG_TYPE_I64
, args
[0], args
[2]);
2026 } else if (a0
== a1
) {
2027 tcg_out_insn(s
, RRE
, NGR
, args
[0], args
[2]);
2029 tcg_out_insn(s
, RRF
, NGRK
, a0
, a1
, a2
);
2032 case INDEX_op_or_i64
:
2033 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2034 if (const_args
[2]) {
2035 tcg_out_mov(s
, TCG_TYPE_I64
, a0
, a1
);
2036 tgen64_ori(s
, a0
, a2
);
2037 } else if (a0
== a1
) {
2038 tcg_out_insn(s
, RRE
, OGR
, a0
, a2
);
2040 tcg_out_insn(s
, RRF
, OGRK
, a0
, a1
, a2
);
2043 case INDEX_op_xor_i64
:
2044 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2045 if (const_args
[2]) {
2046 tcg_out_mov(s
, TCG_TYPE_I64
, a0
, a1
);
2047 tgen64_xori(s
, a0
, a2
);
2048 } else if (a0
== a1
) {
2049 tcg_out_insn(s
, RRE
, XGR
, a0
, a2
);
2051 tcg_out_insn(s
, RRF
, XGRK
, a0
, a1
, a2
);
2055 case INDEX_op_neg_i64
:
2056 tcg_out_insn(s
, RRE
, LCGR
, args
[0], args
[1]);
2058 case INDEX_op_bswap64_i64
:
2059 tcg_out_insn(s
, RRE
, LRVGR
, args
[0], args
[1]);
2062 case INDEX_op_mul_i64
:
2063 if (const_args
[2]) {
2064 if (args
[2] == (int16_t)args
[2]) {
2065 tcg_out_insn(s
, RI
, MGHI
, args
[0], args
[2]);
2067 tcg_out_insn(s
, RIL
, MSGFI
, args
[0], args
[2]);
2070 tcg_out_insn(s
, RRE
, MSGR
, args
[0], args
[2]);
2074 case INDEX_op_div2_i64
:
2075 /* ??? We get an unnecessary sign-extension of the dividend
2076 into R3 with this definition, but as we do in fact always
2077 produce both quotient and remainder using INDEX_op_div_i64
2078 instead requires jumping through even more hoops. */
2079 tcg_out_insn(s
, RRE
, DSGR
, TCG_REG_R2
, args
[4]);
2081 case INDEX_op_divu2_i64
:
2082 tcg_out_insn(s
, RRE
, DLGR
, TCG_REG_R2
, args
[4]);
2084 case INDEX_op_mulu2_i64
:
2085 tcg_out_insn(s
, RRE
, MLGR
, TCG_REG_R2
, args
[3]);
2088 case INDEX_op_shl_i64
:
2091 if (const_args
[2]) {
2092 tcg_out_sh64(s
, op
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
2094 tcg_out_sh64(s
, op
, args
[0], args
[1], args
[2], 0);
2097 case INDEX_op_shr_i64
:
2100 case INDEX_op_sar_i64
:
2104 case INDEX_op_rotl_i64
:
2105 if (const_args
[2]) {
2106 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1],
2107 TCG_REG_NONE
, args
[2]);
2109 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1], args
[2], 0);
2112 case INDEX_op_rotr_i64
:
2113 if (const_args
[2]) {
2114 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1],
2115 TCG_REG_NONE
, (64 - args
[2]) & 63);
2117 /* We can use the smaller 32-bit negate because only the
2118 low 6 bits are examined for the rotate. */
2119 tcg_out_insn(s
, RR
, LCR
, TCG_TMP0
, args
[2]);
2120 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1], TCG_TMP0
, 0);
2124 case INDEX_op_ext8s_i64
:
2125 tgen_ext8s(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2127 case INDEX_op_ext16s_i64
:
2128 tgen_ext16s(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2130 case INDEX_op_ext_i32_i64
:
2131 case INDEX_op_ext32s_i64
:
2132 tgen_ext32s(s
, args
[0], args
[1]);
2134 case INDEX_op_ext8u_i64
:
2135 tgen_ext8u(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2137 case INDEX_op_ext16u_i64
:
2138 tgen_ext16u(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2140 case INDEX_op_extu_i32_i64
:
2141 case INDEX_op_ext32u_i64
:
2142 tgen_ext32u(s
, args
[0], args
[1]);
2145 case INDEX_op_add2_i64
:
2146 if (const_args
[4]) {
2147 if ((int64_t)args
[4] >= 0) {
2148 tcg_out_insn(s
, RIL
, ALGFI
, args
[0], args
[4]);
2150 tcg_out_insn(s
, RIL
, SLGFI
, args
[0], -args
[4]);
2153 tcg_out_insn(s
, RRE
, ALGR
, args
[0], args
[4]);
2155 tcg_out_insn(s
, RRE
, ALCGR
, args
[1], args
[5]);
2157 case INDEX_op_sub2_i64
:
2158 if (const_args
[4]) {
2159 if ((int64_t)args
[4] >= 0) {
2160 tcg_out_insn(s
, RIL
, SLGFI
, args
[0], args
[4]);
2162 tcg_out_insn(s
, RIL
, ALGFI
, args
[0], -args
[4]);
2165 tcg_out_insn(s
, RRE
, SLGR
, args
[0], args
[4]);
2167 tcg_out_insn(s
, RRE
, SLBGR
, args
[1], args
[5]);
2170 case INDEX_op_brcond_i64
:
2171 tgen_brcond(s
, TCG_TYPE_I64
, args
[2], args
[0],
2172 args
[1], const_args
[1], arg_label(args
[3]));
2174 case INDEX_op_setcond_i64
:
2175 tgen_setcond(s
, TCG_TYPE_I64
, args
[3], args
[0], args
[1],
2176 args
[2], const_args
[2]);
2178 case INDEX_op_movcond_i64
:
2179 tgen_movcond(s
, TCG_TYPE_I64
, args
[5], args
[0], args
[1],
2180 args
[2], const_args
[2], args
[3], const_args
[3]);
2184 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2185 if (const_args
[1]) {
2186 tgen_deposit(s
, a0
, a2
, args
[3], args
[4], 1);
2188 /* Since we can't support "0Z" as a constraint, we allow a1 in
2189 any register. Fix things up as if a matching constraint. */
2191 TCGType type
= (opc
== INDEX_op_deposit_i64
);
2193 tcg_out_mov(s
, type
, TCG_TMP0
, a2
);
2196 tcg_out_mov(s
, type
, a0
, a1
);
2198 tgen_deposit(s
, a0
, a2
, args
[3], args
[4], 0);
2203 tgen_extract(s
, args
[0], args
[1], args
[2], args
[3]);
2206 case INDEX_op_clz_i64
:
2207 tgen_clz(s
, args
[0], args
[1], args
[2], const_args
[2]);
2211 /* The host memory model is quite strong, we simply need to
2212 serialize the instruction stream. */
2213 if (args
[0] & TCG_MO_ST_LD
) {
2214 tcg_out_insn(s
, RR
, BCR
,
2215 s390_facilities
& FACILITY_FAST_BCR_SER
? 14 : 15, 0);
2219 case INDEX_op_mov_i32
: /* Always emitted via tcg_out_mov. */
2220 case INDEX_op_mov_i64
:
2221 case INDEX_op_movi_i32
: /* Always emitted via tcg_out_movi. */
2222 case INDEX_op_movi_i64
:
2223 case INDEX_op_call
: /* Always emitted via tcg_out_call. */
2229 static const TCGTargetOpDef
*tcg_target_op_def(TCGOpcode op
)
2231 static const TCGTargetOpDef r
= { .args_ct_str
= { "r" } };
2232 static const TCGTargetOpDef r_r
= { .args_ct_str
= { "r", "r" } };
2233 static const TCGTargetOpDef r_L
= { .args_ct_str
= { "r", "L" } };
2234 static const TCGTargetOpDef L_L
= { .args_ct_str
= { "L", "L" } };
2235 static const TCGTargetOpDef r_ri
= { .args_ct_str
= { "r", "ri" } };
2236 static const TCGTargetOpDef r_rC
= { .args_ct_str
= { "r", "rC" } };
2237 static const TCGTargetOpDef r_rZ
= { .args_ct_str
= { "r", "rZ" } };
2238 static const TCGTargetOpDef r_r_ri
= { .args_ct_str
= { "r", "r", "ri" } };
2239 static const TCGTargetOpDef r_r_rM
= { .args_ct_str
= { "r", "r", "rM" } };
2240 static const TCGTargetOpDef r_0_r
= { .args_ct_str
= { "r", "0", "r" } };
2241 static const TCGTargetOpDef r_0_ri
= { .args_ct_str
= { "r", "0", "ri" } };
2242 static const TCGTargetOpDef r_0_rI
= { .args_ct_str
= { "r", "0", "rI" } };
2243 static const TCGTargetOpDef r_0_rJ
= { .args_ct_str
= { "r", "0", "rJ" } };
2244 static const TCGTargetOpDef r_0_rN
= { .args_ct_str
= { "r", "0", "rN" } };
2245 static const TCGTargetOpDef r_0_rM
= { .args_ct_str
= { "r", "0", "rM" } };
2246 static const TCGTargetOpDef a2_r
2247 = { .args_ct_str
= { "r", "r", "0", "1", "r", "r" } };
2248 static const TCGTargetOpDef a2_ri
2249 = { .args_ct_str
= { "r", "r", "0", "1", "ri", "r" } };
2250 static const TCGTargetOpDef a2_rA
2251 = { .args_ct_str
= { "r", "r", "0", "1", "rA", "r" } };
2254 case INDEX_op_goto_ptr
:
2257 case INDEX_op_ld8u_i32
:
2258 case INDEX_op_ld8u_i64
:
2259 case INDEX_op_ld8s_i32
:
2260 case INDEX_op_ld8s_i64
:
2261 case INDEX_op_ld16u_i32
:
2262 case INDEX_op_ld16u_i64
:
2263 case INDEX_op_ld16s_i32
:
2264 case INDEX_op_ld16s_i64
:
2265 case INDEX_op_ld_i32
:
2266 case INDEX_op_ld32u_i64
:
2267 case INDEX_op_ld32s_i64
:
2268 case INDEX_op_ld_i64
:
2269 case INDEX_op_st8_i32
:
2270 case INDEX_op_st8_i64
:
2271 case INDEX_op_st16_i32
:
2272 case INDEX_op_st16_i64
:
2273 case INDEX_op_st_i32
:
2274 case INDEX_op_st32_i64
:
2275 case INDEX_op_st_i64
:
2278 case INDEX_op_add_i32
:
2279 case INDEX_op_add_i64
:
2281 case INDEX_op_sub_i32
:
2282 case INDEX_op_sub_i64
:
2283 return (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_ri
: &r_0_ri
);
2285 case INDEX_op_mul_i32
:
2286 /* If we have the general-instruction-extensions, then we have
2287 MULTIPLY SINGLE IMMEDIATE with a signed 32-bit, otherwise we
2288 have only MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
2289 return (s390_facilities
& FACILITY_GEN_INST_EXT
? &r_0_ri
: &r_0_rI
);
2290 case INDEX_op_mul_i64
:
2291 return (s390_facilities
& FACILITY_GEN_INST_EXT
? &r_0_rJ
: &r_0_rI
);
2293 case INDEX_op_or_i32
:
2294 /* The use of [iNM] constraints are optimization only, since a full
2295 64-bit immediate OR can always be performed with 4 sequential
2296 OI[LH][LH] instructions. By rejecting certain negative ranges,
2297 the immediate load plus the reg-reg OR is smaller. */
2298 return (s390_facilities
& FACILITY_EXT_IMM
2299 ? (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_ri
: &r_0_ri
)
2301 case INDEX_op_or_i64
:
2302 return (s390_facilities
& FACILITY_EXT_IMM
2303 ? (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_rM
: &r_0_rM
)
2306 case INDEX_op_xor_i32
:
2307 /* Without EXT_IMM, no immediates are supported. Otherwise,
2308 rejecting certain negative ranges leads to smaller code. */
2309 return (s390_facilities
& FACILITY_EXT_IMM
2310 ? (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_ri
: &r_0_ri
)
2312 case INDEX_op_xor_i64
:
2313 return (s390_facilities
& FACILITY_EXT_IMM
2314 ? (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_rM
: &r_0_rM
)
2317 case INDEX_op_and_i32
:
2318 case INDEX_op_and_i64
:
2319 return (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_ri
: &r_0_ri
);
2321 case INDEX_op_shl_i32
:
2322 case INDEX_op_shr_i32
:
2323 case INDEX_op_sar_i32
:
2324 return (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_ri
: &r_0_ri
);
2326 case INDEX_op_shl_i64
:
2327 case INDEX_op_shr_i64
:
2328 case INDEX_op_sar_i64
:
2331 case INDEX_op_rotl_i32
:
2332 case INDEX_op_rotl_i64
:
2333 case INDEX_op_rotr_i32
:
2334 case INDEX_op_rotr_i64
:
2337 case INDEX_op_brcond_i32
:
2338 /* Without EXT_IMM, only the LOAD AND TEST insn is available. */
2339 return (s390_facilities
& FACILITY_EXT_IMM
? &r_ri
: &r_rZ
);
2340 case INDEX_op_brcond_i64
:
2341 return (s390_facilities
& FACILITY_EXT_IMM
? &r_rC
: &r_rZ
);
2343 case INDEX_op_bswap16_i32
:
2344 case INDEX_op_bswap16_i64
:
2345 case INDEX_op_bswap32_i32
:
2346 case INDEX_op_bswap32_i64
:
2347 case INDEX_op_bswap64_i64
:
2348 case INDEX_op_neg_i32
:
2349 case INDEX_op_neg_i64
:
2350 case INDEX_op_ext8s_i32
:
2351 case INDEX_op_ext8s_i64
:
2352 case INDEX_op_ext8u_i32
:
2353 case INDEX_op_ext8u_i64
:
2354 case INDEX_op_ext16s_i32
:
2355 case INDEX_op_ext16s_i64
:
2356 case INDEX_op_ext16u_i32
:
2357 case INDEX_op_ext16u_i64
:
2358 case INDEX_op_ext32s_i64
:
2359 case INDEX_op_ext32u_i64
:
2360 case INDEX_op_ext_i32_i64
:
2361 case INDEX_op_extu_i32_i64
:
2362 case INDEX_op_extract_i32
:
2363 case INDEX_op_extract_i64
:
2366 case INDEX_op_clz_i64
:
2369 case INDEX_op_qemu_ld_i32
:
2370 case INDEX_op_qemu_ld_i64
:
2372 case INDEX_op_qemu_st_i64
:
2373 case INDEX_op_qemu_st_i32
:
2376 case INDEX_op_deposit_i32
:
2377 case INDEX_op_deposit_i64
:
2379 static const TCGTargetOpDef dep
2380 = { .args_ct_str
= { "r", "rZ", "r" } };
2383 case INDEX_op_setcond_i32
:
2384 case INDEX_op_setcond_i64
:
2386 /* Without EXT_IMM, only the LOAD AND TEST insn is available. */
2387 static const TCGTargetOpDef setc_z
2388 = { .args_ct_str
= { "r", "r", "rZ" } };
2389 static const TCGTargetOpDef setc_c
2390 = { .args_ct_str
= { "r", "r", "rC" } };
2391 return (s390_facilities
& FACILITY_EXT_IMM
? &setc_c
: &setc_z
);
2393 case INDEX_op_movcond_i32
:
2394 case INDEX_op_movcond_i64
:
2396 /* Without EXT_IMM, only the LOAD AND TEST insn is available. */
2397 static const TCGTargetOpDef movc_z
2398 = { .args_ct_str
= { "r", "r", "rZ", "r", "0" } };
2399 static const TCGTargetOpDef movc_c
2400 = { .args_ct_str
= { "r", "r", "rC", "r", "0" } };
2401 static const TCGTargetOpDef movc_l
2402 = { .args_ct_str
= { "r", "r", "rC", "rI", "0" } };
2403 return (s390_facilities
& FACILITY_EXT_IMM
2404 ? (s390_facilities
& FACILITY_LOAD_ON_COND2
2405 ? &movc_l
: &movc_c
)
2408 case INDEX_op_div2_i32
:
2409 case INDEX_op_div2_i64
:
2410 case INDEX_op_divu2_i32
:
2411 case INDEX_op_divu2_i64
:
2413 static const TCGTargetOpDef div2
2414 = { .args_ct_str
= { "b", "a", "0", "1", "r" } };
2417 case INDEX_op_mulu2_i64
:
2419 static const TCGTargetOpDef mul2
2420 = { .args_ct_str
= { "b", "a", "0", "r" } };
2424 case INDEX_op_add2_i32
:
2425 case INDEX_op_sub2_i32
:
2426 return (s390_facilities
& FACILITY_EXT_IMM
? &a2_ri
: &a2_r
);
2427 case INDEX_op_add2_i64
:
2428 case INDEX_op_sub2_i64
:
2429 return (s390_facilities
& FACILITY_EXT_IMM
? &a2_rA
: &a2_r
);
2437 static void query_s390_facilities(void)
2439 unsigned long hwcap
= qemu_getauxval(AT_HWCAP
);
2441 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
2442 is present on all 64-bit systems, but let's check for it anyway. */
2443 if (hwcap
& HWCAP_S390_STFLE
) {
2444 register int r0
__asm__("0");
2445 register void *r1
__asm__("1");
2448 r1
= &s390_facilities
;
2449 asm volatile(".word 0xb2b0,0x1000"
2450 : "=r"(r0
) : "0"(0), "r"(r1
) : "memory", "cc");
2454 static void tcg_target_init(TCGContext
*s
)
2456 query_s390_facilities();
2458 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I32
], 0, 0xffff);
2459 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I64
], 0, 0xffff);
2461 tcg_regset_clear(tcg_target_call_clobber_regs
);
2462 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R0
);
2463 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R1
);
2464 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R2
);
2465 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R3
);
2466 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R4
);
2467 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R5
);
2468 /* The r6 register is technically call-saved, but it's also a parameter
2469 register, so it can get killed by setup for the qemu_st helper. */
2470 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R6
);
2471 /* The return register can be considered call-clobbered. */
2472 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R14
);
2474 tcg_regset_clear(s
->reserved_regs
);
2475 tcg_regset_set_reg(s
->reserved_regs
, TCG_TMP0
);
2476 /* XXX many insns can't be used with R0, so we better avoid it for now */
2477 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_R0
);
2478 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_CALL_STACK
);
2481 #define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
2482 + TCG_STATIC_CALL_ARGS_SIZE \
2483 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
2485 static void tcg_target_qemu_prologue(TCGContext
*s
)
2487 /* stmg %r6,%r15,48(%r15) (save registers) */
2488 tcg_out_insn(s
, RXY
, STMG
, TCG_REG_R6
, TCG_REG_R15
, TCG_REG_R15
, 48);
2490 /* aghi %r15,-frame_size */
2491 tcg_out_insn(s
, RI
, AGHI
, TCG_REG_R15
, -FRAME_SIZE
);
2493 tcg_set_frame(s
, TCG_REG_CALL_STACK
,
2494 TCG_STATIC_CALL_ARGS_SIZE
+ TCG_TARGET_CALL_STACK_OFFSET
,
2495 CPU_TEMP_BUF_NLONGS
* sizeof(long));
2497 #ifndef CONFIG_SOFTMMU
2498 if (guest_base
>= 0x80000) {
2499 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_GUEST_BASE_REG
, guest_base
);
2500 tcg_regset_set_reg(s
->reserved_regs
, TCG_GUEST_BASE_REG
);
2504 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_AREG0
, tcg_target_call_iarg_regs
[0]);
2505 /* br %r3 (go to TB) */
2506 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, tcg_target_call_iarg_regs
[1]);
2509 * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2510 * and fall through to the rest of the epilogue.
2512 s
->code_gen_epilogue
= s
->code_ptr
;
2513 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R2
, 0);
2516 tb_ret_addr
= s
->code_ptr
;
2518 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2519 tcg_out_insn(s
, RXY
, LMG
, TCG_REG_R6
, TCG_REG_R15
, TCG_REG_R15
,
2522 /* br %r14 (return) */
2523 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, TCG_REG_R14
);
2528 uint8_t fde_def_cfa
[4];
2529 uint8_t fde_reg_ofs
[18];
2532 /* We're expecting a 2 byte uleb128 encoded value. */
2533 QEMU_BUILD_BUG_ON(FRAME_SIZE
>= (1 << 14));
2535 #define ELF_HOST_MACHINE EM_S390
2537 static const DebugFrame debug_frame
= {
2538 .h
.cie
.len
= sizeof(DebugFrameCIE
)-4, /* length after .len member */
2541 .h
.cie
.code_align
= 1,
2542 .h
.cie
.data_align
= 8, /* sleb128 8 */
2543 .h
.cie
.return_column
= TCG_REG_R14
,
2545 /* Total FDE size does not include the "len" member. */
2546 .h
.fde
.len
= sizeof(DebugFrame
) - offsetof(DebugFrame
, h
.fde
.cie_offset
),
2549 12, TCG_REG_CALL_STACK
, /* DW_CFA_def_cfa %r15, ... */
2550 (FRAME_SIZE
& 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2554 0x86, 6, /* DW_CFA_offset, %r6, 48 */
2555 0x87, 7, /* DW_CFA_offset, %r7, 56 */
2556 0x88, 8, /* DW_CFA_offset, %r8, 64 */
2557 0x89, 9, /* DW_CFA_offset, %r92, 72 */
2558 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
2559 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
2560 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
2561 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
2562 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
2566 void tcg_register_jit(void *buf
, size_t buf_size
)
2568 tcg_register_jit_int(buf
, buf_size
, &debug_frame
, sizeof(debug_frame
));