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 path through do_greater is smaller. */
1092 /* The result of a compare has CC=2 for GT and CC=3 unused.
1093 ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */
1094 tgen_cmp(s
, type
, cond
, c1
, c2
, c2const
, true);
1095 tcg_out_movi(s
, type
, dest
, 0);
1096 tcg_out_insn(s
, RRE
, ALCGR
, dest
, dest
);
1104 /* We need "real" carry semantics, so use SUBTRACT LOGICAL
1105 instead of COMPARE LOGICAL. This may need an extra move. */
1107 tcg_out_mov(s
, type
, TCG_TMP0
, c1
);
1108 if (type
== TCG_TYPE_I32
) {
1109 tcg_out_insn(s
, RIL
, SLFI
, TCG_TMP0
, c2
);
1111 tcg_out_insn(s
, RIL
, SLGFI
, TCG_TMP0
, c2
);
1113 } else if (s390_facilities
& FACILITY_DISTINCT_OPS
) {
1114 if (type
== TCG_TYPE_I32
) {
1115 tcg_out_insn(s
, RRF
, SLRK
, TCG_TMP0
, c1
, c2
);
1117 tcg_out_insn(s
, RRF
, SLGRK
, TCG_TMP0
, c1
, c2
);
1120 tcg_out_mov(s
, type
, TCG_TMP0
, c1
);
1121 if (type
== TCG_TYPE_I32
) {
1122 tcg_out_insn(s
, RR
, SLR
, TCG_TMP0
, c2
);
1124 tcg_out_insn(s
, RRE
, SLGR
, TCG_TMP0
, c2
);
1127 tcg_out_movi(s
, TCG_TYPE_I64
, dest
, 0);
1128 tcg_out_insn(s
, RRE
, ALCGR
, dest
, dest
);
1138 /* Swap operands so that we can use GEU/GTU/GT. */
1143 tcg_out_movi(s
, type
, TCG_TMP0
, c2
);
1152 if (cond
== TCG_COND_LEU
) {
1155 cond
= tcg_swap_cond(cond
);
1159 /* X != 0 is X > 0. */
1160 if (c2const
&& c2
== 0) {
1161 cond
= TCG_COND_GTU
;
1170 /* X == 0 is X <= 0 is 0 >= X. */
1171 if (c2const
&& c2
== 0) {
1172 tcg_out_movi(s
, TCG_TYPE_I64
, TCG_TMP0
, 0);
1184 cc
= tgen_cmp(s
, type
, cond
, c1
, c2
, c2const
, false);
1185 /* Emit: d = 1; if (cc) goto over; d = 0; over: */
1186 tcg_out_movi(s
, type
, dest
, 1);
1187 tcg_out_insn(s
, RI
, BRC
, cc
, (4 + 4) >> 1);
1188 tcg_out_movi(s
, type
, dest
, 0);
1192 cc
= tgen_cmp(s
, type
, cond
, c1
, c2
, c2const
, false);
1193 /* Emit: d = 0, t = 1, d = (cc ? t : d). */
1194 tcg_out_movi(s
, TCG_TYPE_I64
, dest
, 0);
1195 tcg_out_movi(s
, TCG_TYPE_I64
, TCG_TMP0
, 1);
1196 tcg_out_insn(s
, RRF
, LOCGR
, dest
, TCG_TMP0
, cc
);
1199 static void tgen_movcond(TCGContext
*s
, TCGType type
, TCGCond c
, TCGReg dest
,
1200 TCGReg c1
, TCGArg c2
, int c2const
,
1201 TCGArg v3
, int v3const
)
1204 if (s390_facilities
& FACILITY_LOAD_ON_COND
) {
1205 cc
= tgen_cmp(s
, type
, c
, c1
, c2
, c2const
, false);
1207 tcg_out_insn(s
, RIE
, LOCGHI
, dest
, v3
, cc
);
1209 tcg_out_insn(s
, RRF
, LOCGR
, dest
, v3
, cc
);
1212 c
= tcg_invert_cond(c
);
1213 cc
= tgen_cmp(s
, type
, c
, c1
, c2
, c2const
, false);
1215 /* Emit: if (cc) goto over; dest = r3; over: */
1216 tcg_out_insn(s
, RI
, BRC
, cc
, (4 + 4) >> 1);
1217 tcg_out_insn(s
, RRE
, LGR
, dest
, v3
);
1221 static void tgen_clz(TCGContext
*s
, TCGReg dest
, TCGReg a1
,
1222 TCGArg a2
, int a2const
)
1224 /* Since this sets both R and R+1, we have no choice but to store the
1225 result into R0, allowing R1 == TCG_TMP0 to be clobbered as well. */
1226 QEMU_BUILD_BUG_ON(TCG_TMP0
!= TCG_REG_R1
);
1227 tcg_out_insn(s
, RRE
, FLOGR
, TCG_REG_R0
, a1
);
1229 if (a2const
&& a2
== 64) {
1230 tcg_out_mov(s
, TCG_TYPE_I64
, dest
, TCG_REG_R0
);
1233 tcg_out_movi(s
, TCG_TYPE_I64
, dest
, a2
);
1235 tcg_out_mov(s
, TCG_TYPE_I64
, dest
, a2
);
1237 if (s390_facilities
& FACILITY_LOAD_ON_COND
) {
1238 /* Emit: if (one bit found) dest = r0. */
1239 tcg_out_insn(s
, RRF
, LOCGR
, dest
, TCG_REG_R0
, 2);
1241 /* Emit: if (no one bit found) goto over; dest = r0; over: */
1242 tcg_out_insn(s
, RI
, BRC
, 8, (4 + 4) >> 1);
1243 tcg_out_insn(s
, RRE
, LGR
, dest
, TCG_REG_R0
);
1248 static void tgen_deposit(TCGContext
*s
, TCGReg dest
, TCGReg src
,
1249 int ofs
, int len
, int z
)
1251 int lsb
= (63 - ofs
);
1252 int msb
= lsb
- (len
- 1);
1253 tcg_out_risbg(s
, dest
, src
, msb
, lsb
, ofs
, z
);
1256 static void tgen_extract(TCGContext
*s
, TCGReg dest
, TCGReg src
,
1259 tcg_out_risbg(s
, dest
, src
, 64 - len
, 63, 64 - ofs
, 1);
1262 static void tgen_gotoi(TCGContext
*s
, int cc
, tcg_insn_unit
*dest
)
1264 ptrdiff_t off
= dest
- s
->code_ptr
;
1265 if (off
== (int16_t)off
) {
1266 tcg_out_insn(s
, RI
, BRC
, cc
, off
);
1267 } else if (off
== (int32_t)off
) {
1268 tcg_out_insn(s
, RIL
, BRCL
, cc
, off
);
1270 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_TMP0
, (uintptr_t)dest
);
1271 tcg_out_insn(s
, RR
, BCR
, cc
, TCG_TMP0
);
1275 static void tgen_branch(TCGContext
*s
, int cc
, TCGLabel
*l
)
1278 tgen_gotoi(s
, cc
, l
->u
.value_ptr
);
1279 } else if (USE_LONG_BRANCHES
) {
1280 tcg_out16(s
, RIL_BRCL
| (cc
<< 4));
1281 tcg_out_reloc(s
, s
->code_ptr
, R_390_PC32DBL
, l
, -2);
1284 tcg_out16(s
, RI_BRC
| (cc
<< 4));
1285 tcg_out_reloc(s
, s
->code_ptr
, R_390_PC16DBL
, l
, -2);
1290 static void tgen_compare_branch(TCGContext
*s
, S390Opcode opc
, int cc
,
1291 TCGReg r1
, TCGReg r2
, TCGLabel
*l
)
1296 off
= l
->u
.value_ptr
- s
->code_ptr
;
1298 /* We need to keep the offset unchanged for retranslation. */
1299 off
= s
->code_ptr
[1];
1300 tcg_out_reloc(s
, s
->code_ptr
+ 1, R_390_PC16DBL
, l
, -2);
1303 tcg_out16(s
, (opc
& 0xff00) | (r1
<< 4) | r2
);
1305 tcg_out16(s
, cc
<< 12 | (opc
& 0xff));
1308 static void tgen_compare_imm_branch(TCGContext
*s
, S390Opcode opc
, int cc
,
1309 TCGReg r1
, int i2
, TCGLabel
*l
)
1311 tcg_target_long off
;
1314 off
= l
->u
.value_ptr
- s
->code_ptr
;
1316 /* We need to keep the offset unchanged for retranslation. */
1317 off
= s
->code_ptr
[1];
1318 tcg_out_reloc(s
, s
->code_ptr
+ 1, R_390_PC16DBL
, l
, -2);
1321 tcg_out16(s
, (opc
& 0xff00) | (r1
<< 4) | cc
);
1323 tcg_out16(s
, (i2
<< 8) | (opc
& 0xff));
1326 static void tgen_brcond(TCGContext
*s
, TCGType type
, TCGCond c
,
1327 TCGReg r1
, TCGArg c2
, int c2const
, TCGLabel
*l
)
1331 if (s390_facilities
& FACILITY_GEN_INST_EXT
) {
1332 bool is_unsigned
= is_unsigned_cond(c
);
1336 cc
= tcg_cond_to_s390_cond
[c
];
1339 opc
= (type
== TCG_TYPE_I32
1340 ? (is_unsigned
? RIE_CLRJ
: RIE_CRJ
)
1341 : (is_unsigned
? RIE_CLGRJ
: RIE_CGRJ
));
1342 tgen_compare_branch(s
, opc
, cc
, r1
, c2
, l
);
1346 /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1347 If the immediate we've been given does not fit that range, we'll
1348 fall back to separate compare and branch instructions using the
1349 larger comparison range afforded by COMPARE IMMEDIATE. */
1350 if (type
== TCG_TYPE_I32
) {
1353 in_range
= (uint32_t)c2
== (uint8_t)c2
;
1356 in_range
= (int32_t)c2
== (int8_t)c2
;
1361 in_range
= (uint64_t)c2
== (uint8_t)c2
;
1364 in_range
= (int64_t)c2
== (int8_t)c2
;
1368 tgen_compare_imm_branch(s
, opc
, cc
, r1
, c2
, l
);
1373 cc
= tgen_cmp(s
, type
, c
, r1
, c2
, c2const
, false);
1374 tgen_branch(s
, cc
, l
);
1377 static void tcg_out_call(TCGContext
*s
, tcg_insn_unit
*dest
)
1379 ptrdiff_t off
= dest
- s
->code_ptr
;
1380 if (off
== (int32_t)off
) {
1381 tcg_out_insn(s
, RIL
, BRASL
, TCG_REG_R14
, off
);
1383 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_TMP0
, (uintptr_t)dest
);
1384 tcg_out_insn(s
, RR
, BASR
, TCG_REG_R14
, TCG_TMP0
);
1388 static void tcg_out_qemu_ld_direct(TCGContext
*s
, TCGMemOp opc
, TCGReg data
,
1389 TCGReg base
, TCGReg index
, int disp
)
1391 switch (opc
& (MO_SSIZE
| MO_BSWAP
)) {
1393 tcg_out_insn(s
, RXY
, LLGC
, data
, base
, index
, disp
);
1396 tcg_out_insn(s
, RXY
, LGB
, data
, base
, index
, disp
);
1399 case MO_UW
| MO_BSWAP
:
1400 /* swapped unsigned halfword load with upper bits zeroed */
1401 tcg_out_insn(s
, RXY
, LRVH
, data
, base
, index
, disp
);
1402 tgen_ext16u(s
, TCG_TYPE_I64
, data
, data
);
1405 tcg_out_insn(s
, RXY
, LLGH
, data
, base
, index
, disp
);
1408 case MO_SW
| MO_BSWAP
:
1409 /* swapped sign-extended halfword load */
1410 tcg_out_insn(s
, RXY
, LRVH
, data
, base
, index
, disp
);
1411 tgen_ext16s(s
, TCG_TYPE_I64
, data
, data
);
1414 tcg_out_insn(s
, RXY
, LGH
, data
, base
, index
, disp
);
1417 case MO_UL
| MO_BSWAP
:
1418 /* swapped unsigned int load with upper bits zeroed */
1419 tcg_out_insn(s
, RXY
, LRV
, data
, base
, index
, disp
);
1420 tgen_ext32u(s
, data
, data
);
1423 tcg_out_insn(s
, RXY
, LLGF
, data
, base
, index
, disp
);
1426 case MO_SL
| MO_BSWAP
:
1427 /* swapped sign-extended int load */
1428 tcg_out_insn(s
, RXY
, LRV
, data
, base
, index
, disp
);
1429 tgen_ext32s(s
, data
, data
);
1432 tcg_out_insn(s
, RXY
, LGF
, data
, base
, index
, disp
);
1435 case MO_Q
| MO_BSWAP
:
1436 tcg_out_insn(s
, RXY
, LRVG
, data
, base
, index
, disp
);
1439 tcg_out_insn(s
, RXY
, LG
, data
, base
, index
, disp
);
1447 static void tcg_out_qemu_st_direct(TCGContext
*s
, TCGMemOp opc
, TCGReg data
,
1448 TCGReg base
, TCGReg index
, int disp
)
1450 switch (opc
& (MO_SIZE
| MO_BSWAP
)) {
1452 if (disp
>= 0 && disp
< 0x1000) {
1453 tcg_out_insn(s
, RX
, STC
, data
, base
, index
, disp
);
1455 tcg_out_insn(s
, RXY
, STCY
, data
, base
, index
, disp
);
1459 case MO_UW
| MO_BSWAP
:
1460 tcg_out_insn(s
, RXY
, STRVH
, data
, base
, index
, disp
);
1463 if (disp
>= 0 && disp
< 0x1000) {
1464 tcg_out_insn(s
, RX
, STH
, data
, base
, index
, disp
);
1466 tcg_out_insn(s
, RXY
, STHY
, data
, base
, index
, disp
);
1470 case MO_UL
| MO_BSWAP
:
1471 tcg_out_insn(s
, RXY
, STRV
, data
, base
, index
, disp
);
1474 if (disp
>= 0 && disp
< 0x1000) {
1475 tcg_out_insn(s
, RX
, ST
, data
, base
, index
, disp
);
1477 tcg_out_insn(s
, RXY
, STY
, data
, base
, index
, disp
);
1481 case MO_Q
| MO_BSWAP
:
1482 tcg_out_insn(s
, RXY
, STRVG
, data
, base
, index
, disp
);
1485 tcg_out_insn(s
, RXY
, STG
, data
, base
, index
, disp
);
1493 #if defined(CONFIG_SOFTMMU)
1494 /* We're expecting to use a 20-bit signed offset on the tlb memory ops.
1495 Using the offset of the second entry in the last tlb table ensures
1496 that we can index all of the elements of the first entry. */
1497 QEMU_BUILD_BUG_ON(offsetof(CPUArchState
, tlb_table
[NB_MMU_MODES
- 1][1])
1500 /* Load and compare a TLB entry, leaving the flags set. Loads the TLB
1501 addend into R2. Returns a register with the santitized guest address. */
1502 static TCGReg
tcg_out_tlb_read(TCGContext
* s
, TCGReg addr_reg
, TCGMemOp opc
,
1503 int mem_index
, bool is_ld
)
1505 unsigned s_bits
= opc
& MO_SIZE
;
1506 unsigned a_bits
= get_alignment_bits(opc
);
1507 unsigned s_mask
= (1 << s_bits
) - 1;
1508 unsigned a_mask
= (1 << a_bits
) - 1;
1512 /* For aligned accesses, we check the first byte and include the alignment
1513 bits within the address. For unaligned access, we check that we don't
1514 cross pages using the address of the last byte of the access. */
1515 a_off
= (a_bits
>= s_bits
? 0 : s_mask
- a_mask
);
1516 tlb_mask
= (uint64_t)TARGET_PAGE_MASK
| a_mask
;
1518 if (s390_facilities
& FACILITY_GEN_INST_EXT
) {
1519 tcg_out_risbg(s
, TCG_REG_R2
, addr_reg
,
1520 64 - CPU_TLB_BITS
- CPU_TLB_ENTRY_BITS
,
1521 63 - CPU_TLB_ENTRY_BITS
,
1522 64 + CPU_TLB_ENTRY_BITS
- TARGET_PAGE_BITS
, 1);
1524 tcg_out_insn(s
, RX
, LA
, TCG_REG_R3
, addr_reg
, TCG_REG_NONE
, a_off
);
1525 tgen_andi(s
, TCG_TYPE_TL
, TCG_REG_R3
, tlb_mask
);
1527 tgen_andi_risbg(s
, TCG_REG_R3
, addr_reg
, tlb_mask
);
1530 tcg_out_sh64(s
, RSY_SRLG
, TCG_REG_R2
, addr_reg
, TCG_REG_NONE
,
1531 TARGET_PAGE_BITS
- CPU_TLB_ENTRY_BITS
);
1532 tcg_out_insn(s
, RX
, LA
, TCG_REG_R3
, addr_reg
, TCG_REG_NONE
, a_off
);
1533 tgen_andi(s
, TCG_TYPE_I64
, TCG_REG_R2
,
1534 (CPU_TLB_SIZE
- 1) << CPU_TLB_ENTRY_BITS
);
1535 tgen_andi(s
, TCG_TYPE_TL
, TCG_REG_R3
, tlb_mask
);
1539 ofs
= offsetof(CPUArchState
, tlb_table
[mem_index
][0].addr_read
);
1541 ofs
= offsetof(CPUArchState
, tlb_table
[mem_index
][0].addr_write
);
1543 if (TARGET_LONG_BITS
== 32) {
1544 tcg_out_mem(s
, RX_C
, RXY_CY
, TCG_REG_R3
, TCG_REG_R2
, TCG_AREG0
, ofs
);
1546 tcg_out_mem(s
, 0, RXY_CG
, TCG_REG_R3
, TCG_REG_R2
, TCG_AREG0
, ofs
);
1549 ofs
= offsetof(CPUArchState
, tlb_table
[mem_index
][0].addend
);
1550 tcg_out_mem(s
, 0, RXY_LG
, TCG_REG_R2
, TCG_REG_R2
, TCG_AREG0
, ofs
);
1552 if (TARGET_LONG_BITS
== 32) {
1553 tgen_ext32u(s
, TCG_REG_R3
, addr_reg
);
1559 static void add_qemu_ldst_label(TCGContext
*s
, bool is_ld
, TCGMemOpIdx oi
,
1560 TCGReg data
, TCGReg addr
,
1561 tcg_insn_unit
*raddr
, tcg_insn_unit
*label_ptr
)
1563 TCGLabelQemuLdst
*label
= new_ldst_label(s
);
1565 label
->is_ld
= is_ld
;
1567 label
->datalo_reg
= data
;
1568 label
->addrlo_reg
= addr
;
1569 label
->raddr
= raddr
;
1570 label
->label_ptr
[0] = label_ptr
;
1573 static void tcg_out_qemu_ld_slow_path(TCGContext
*s
, TCGLabelQemuLdst
*lb
)
1575 TCGReg addr_reg
= lb
->addrlo_reg
;
1576 TCGReg data_reg
= lb
->datalo_reg
;
1577 TCGMemOpIdx oi
= lb
->oi
;
1578 TCGMemOp opc
= get_memop(oi
);
1580 patch_reloc(lb
->label_ptr
[0], R_390_PC16DBL
, (intptr_t)s
->code_ptr
, -2);
1582 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_REG_R2
, TCG_AREG0
);
1583 if (TARGET_LONG_BITS
== 64) {
1584 tcg_out_mov(s
, TCG_TYPE_I64
, TCG_REG_R3
, addr_reg
);
1586 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_R4
, oi
);
1587 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R5
, (uintptr_t)lb
->raddr
);
1588 tcg_out_call(s
, qemu_ld_helpers
[opc
& (MO_BSWAP
| MO_SSIZE
)]);
1589 tcg_out_mov(s
, TCG_TYPE_I64
, data_reg
, TCG_REG_R2
);
1591 tgen_gotoi(s
, S390_CC_ALWAYS
, lb
->raddr
);
1594 static void tcg_out_qemu_st_slow_path(TCGContext
*s
, TCGLabelQemuLdst
*lb
)
1596 TCGReg addr_reg
= lb
->addrlo_reg
;
1597 TCGReg data_reg
= lb
->datalo_reg
;
1598 TCGMemOpIdx oi
= lb
->oi
;
1599 TCGMemOp opc
= get_memop(oi
);
1601 patch_reloc(lb
->label_ptr
[0], R_390_PC16DBL
, (intptr_t)s
->code_ptr
, -2);
1603 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_REG_R2
, TCG_AREG0
);
1604 if (TARGET_LONG_BITS
== 64) {
1605 tcg_out_mov(s
, TCG_TYPE_I64
, TCG_REG_R3
, addr_reg
);
1607 switch (opc
& MO_SIZE
) {
1609 tgen_ext8u(s
, TCG_TYPE_I64
, TCG_REG_R4
, data_reg
);
1612 tgen_ext16u(s
, TCG_TYPE_I64
, TCG_REG_R4
, data_reg
);
1615 tgen_ext32u(s
, TCG_REG_R4
, data_reg
);
1618 tcg_out_mov(s
, TCG_TYPE_I64
, TCG_REG_R4
, data_reg
);
1623 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_R5
, oi
);
1624 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R6
, (uintptr_t)lb
->raddr
);
1625 tcg_out_call(s
, qemu_st_helpers
[opc
& (MO_BSWAP
| MO_SIZE
)]);
1627 tgen_gotoi(s
, S390_CC_ALWAYS
, lb
->raddr
);
1630 static void tcg_prepare_user_ldst(TCGContext
*s
, TCGReg
*addr_reg
,
1631 TCGReg
*index_reg
, tcg_target_long
*disp
)
1633 if (TARGET_LONG_BITS
== 32) {
1634 tgen_ext32u(s
, TCG_TMP0
, *addr_reg
);
1635 *addr_reg
= TCG_TMP0
;
1637 if (guest_base
< 0x80000) {
1638 *index_reg
= TCG_REG_NONE
;
1641 *index_reg
= TCG_GUEST_BASE_REG
;
1645 #endif /* CONFIG_SOFTMMU */
1647 static void tcg_out_qemu_ld(TCGContext
* s
, TCGReg data_reg
, TCGReg addr_reg
,
1650 TCGMemOp opc
= get_memop(oi
);
1651 #ifdef CONFIG_SOFTMMU
1652 unsigned mem_index
= get_mmuidx(oi
);
1653 tcg_insn_unit
*label_ptr
;
1656 base_reg
= tcg_out_tlb_read(s
, addr_reg
, opc
, mem_index
, 1);
1658 /* We need to keep the offset unchanged for retranslation. */
1659 tcg_out16(s
, RI_BRC
| (S390_CC_NE
<< 4));
1660 label_ptr
= s
->code_ptr
;
1663 tcg_out_qemu_ld_direct(s
, opc
, data_reg
, base_reg
, TCG_REG_R2
, 0);
1665 add_qemu_ldst_label(s
, 1, oi
, data_reg
, addr_reg
, s
->code_ptr
, label_ptr
);
1668 tcg_target_long disp
;
1670 tcg_prepare_user_ldst(s
, &addr_reg
, &index_reg
, &disp
);
1671 tcg_out_qemu_ld_direct(s
, opc
, data_reg
, addr_reg
, index_reg
, disp
);
1675 static void tcg_out_qemu_st(TCGContext
* s
, TCGReg data_reg
, TCGReg addr_reg
,
1678 TCGMemOp opc
= get_memop(oi
);
1679 #ifdef CONFIG_SOFTMMU
1680 unsigned mem_index
= get_mmuidx(oi
);
1681 tcg_insn_unit
*label_ptr
;
1684 base_reg
= tcg_out_tlb_read(s
, addr_reg
, opc
, mem_index
, 0);
1686 /* We need to keep the offset unchanged for retranslation. */
1687 tcg_out16(s
, RI_BRC
| (S390_CC_NE
<< 4));
1688 label_ptr
= s
->code_ptr
;
1691 tcg_out_qemu_st_direct(s
, opc
, data_reg
, base_reg
, TCG_REG_R2
, 0);
1693 add_qemu_ldst_label(s
, 0, oi
, data_reg
, addr_reg
, s
->code_ptr
, label_ptr
);
1696 tcg_target_long disp
;
1698 tcg_prepare_user_ldst(s
, &addr_reg
, &index_reg
, &disp
);
1699 tcg_out_qemu_st_direct(s
, opc
, data_reg
, addr_reg
, index_reg
, disp
);
1703 # define OP_32_64(x) \
1704 case glue(glue(INDEX_op_,x),_i32): \
1705 case glue(glue(INDEX_op_,x),_i64)
1707 static inline void tcg_out_op(TCGContext
*s
, TCGOpcode opc
,
1708 const TCGArg
*args
, const int *const_args
)
1714 case INDEX_op_exit_tb
:
1715 /* Reuse the zeroing that exists for goto_ptr. */
1718 tgen_gotoi(s
, S390_CC_ALWAYS
, s
->code_gen_epilogue
);
1720 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R2
, a0
);
1721 tgen_gotoi(s
, S390_CC_ALWAYS
, tb_ret_addr
);
1725 case INDEX_op_goto_tb
:
1726 if (s
->tb_jmp_insn_offset
) {
1727 /* branch displacement must be aligned for atomic patching;
1728 * see if we need to add extra nop before branch
1730 if (!QEMU_PTR_IS_ALIGNED(s
->code_ptr
+ 1, 4)) {
1733 tcg_out16(s
, RIL_BRCL
| (S390_CC_ALWAYS
<< 4));
1734 s
->tb_jmp_insn_offset
[args
[0]] = tcg_current_code_size(s
);
1737 /* load address stored at s->tb_jmp_target_addr + args[0] */
1738 tcg_out_ld_abs(s
, TCG_TYPE_PTR
, TCG_TMP0
,
1739 s
->tb_jmp_target_addr
+ args
[0]);
1741 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, TCG_TMP0
);
1743 s
->tb_jmp_reset_offset
[args
[0]] = tcg_current_code_size(s
);
1746 case INDEX_op_goto_ptr
:
1747 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, args
[0]);
1751 /* ??? LLC (RXY format) is only present with the extended-immediate
1752 facility, whereas LLGC is always present. */
1753 tcg_out_mem(s
, 0, RXY_LLGC
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1757 /* ??? LB is no smaller than LGB, so no point to using it. */
1758 tcg_out_mem(s
, 0, RXY_LGB
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1762 /* ??? LLH (RXY format) is only present with the extended-immediate
1763 facility, whereas LLGH is always present. */
1764 tcg_out_mem(s
, 0, RXY_LLGH
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1767 case INDEX_op_ld16s_i32
:
1768 tcg_out_mem(s
, RX_LH
, RXY_LHY
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1771 case INDEX_op_ld_i32
:
1772 tcg_out_ld(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1776 tcg_out_mem(s
, RX_STC
, RXY_STCY
, args
[0], args
[1],
1777 TCG_REG_NONE
, args
[2]);
1781 tcg_out_mem(s
, RX_STH
, RXY_STHY
, args
[0], args
[1],
1782 TCG_REG_NONE
, args
[2]);
1785 case INDEX_op_st_i32
:
1786 tcg_out_st(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1789 case INDEX_op_add_i32
:
1790 a0
= args
[0], a1
= args
[1], a2
= (int32_t)args
[2];
1791 if (const_args
[2]) {
1794 if (a2
== (int16_t)a2
) {
1795 tcg_out_insn(s
, RI
, AHI
, a0
, a2
);
1798 if (s390_facilities
& FACILITY_EXT_IMM
) {
1799 tcg_out_insn(s
, RIL
, AFI
, a0
, a2
);
1803 tcg_out_mem(s
, RX_LA
, RXY_LAY
, a0
, a1
, TCG_REG_NONE
, a2
);
1804 } else if (a0
== a1
) {
1805 tcg_out_insn(s
, RR
, AR
, a0
, a2
);
1807 tcg_out_insn(s
, RX
, LA
, a0
, a1
, a2
, 0);
1810 case INDEX_op_sub_i32
:
1811 a0
= args
[0], a1
= args
[1], a2
= (int32_t)args
[2];
1812 if (const_args
[2]) {
1815 } else if (a0
== a1
) {
1816 tcg_out_insn(s
, RR
, SR
, a0
, a2
);
1818 tcg_out_insn(s
, RRF
, SRK
, a0
, a1
, a2
);
1822 case INDEX_op_and_i32
:
1823 a0
= args
[0], a1
= args
[1], a2
= (uint32_t)args
[2];
1824 if (const_args
[2]) {
1825 tcg_out_mov(s
, TCG_TYPE_I32
, a0
, a1
);
1826 tgen_andi(s
, TCG_TYPE_I32
, a0
, a2
);
1827 } else if (a0
== a1
) {
1828 tcg_out_insn(s
, RR
, NR
, a0
, a2
);
1830 tcg_out_insn(s
, RRF
, NRK
, a0
, a1
, a2
);
1833 case INDEX_op_or_i32
:
1834 a0
= args
[0], a1
= args
[1], a2
= (uint32_t)args
[2];
1835 if (const_args
[2]) {
1836 tcg_out_mov(s
, TCG_TYPE_I32
, a0
, a1
);
1837 tgen64_ori(s
, a0
, a2
);
1838 } else if (a0
== a1
) {
1839 tcg_out_insn(s
, RR
, OR
, a0
, a2
);
1841 tcg_out_insn(s
, RRF
, ORK
, a0
, a1
, a2
);
1844 case INDEX_op_xor_i32
:
1845 a0
= args
[0], a1
= args
[1], a2
= (uint32_t)args
[2];
1846 if (const_args
[2]) {
1847 tcg_out_mov(s
, TCG_TYPE_I32
, a0
, a1
);
1848 tgen64_xori(s
, a0
, a2
);
1849 } else if (a0
== a1
) {
1850 tcg_out_insn(s
, RR
, XR
, args
[0], args
[2]);
1852 tcg_out_insn(s
, RRF
, XRK
, a0
, a1
, a2
);
1856 case INDEX_op_neg_i32
:
1857 tcg_out_insn(s
, RR
, LCR
, args
[0], args
[1]);
1860 case INDEX_op_mul_i32
:
1861 if (const_args
[2]) {
1862 if ((int32_t)args
[2] == (int16_t)args
[2]) {
1863 tcg_out_insn(s
, RI
, MHI
, args
[0], args
[2]);
1865 tcg_out_insn(s
, RIL
, MSFI
, args
[0], args
[2]);
1868 tcg_out_insn(s
, RRE
, MSR
, args
[0], args
[2]);
1872 case INDEX_op_div2_i32
:
1873 tcg_out_insn(s
, RR
, DR
, TCG_REG_R2
, args
[4]);
1875 case INDEX_op_divu2_i32
:
1876 tcg_out_insn(s
, RRE
, DLR
, TCG_REG_R2
, args
[4]);
1879 case INDEX_op_shl_i32
:
1883 a0
= args
[0], a1
= args
[1], a2
= (int32_t)args
[2];
1885 if (const_args
[2]) {
1886 tcg_out_sh32(s
, op
, a0
, TCG_REG_NONE
, a2
);
1888 tcg_out_sh32(s
, op
, a0
, a2
, 0);
1891 /* Using tcg_out_sh64 here for the format; it is a 32-bit shift. */
1892 if (const_args
[2]) {
1893 tcg_out_sh64(s
, op2
, a0
, a1
, TCG_REG_NONE
, a2
);
1895 tcg_out_sh64(s
, op2
, a0
, a1
, a2
, 0);
1899 case INDEX_op_shr_i32
:
1903 case INDEX_op_sar_i32
:
1908 case INDEX_op_rotl_i32
:
1909 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1910 if (const_args
[2]) {
1911 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1913 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], args
[2], 0);
1916 case INDEX_op_rotr_i32
:
1917 if (const_args
[2]) {
1918 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1],
1919 TCG_REG_NONE
, (32 - args
[2]) & 31);
1921 tcg_out_insn(s
, RR
, LCR
, TCG_TMP0
, args
[2]);
1922 tcg_out_sh64(s
, RSY_RLL
, args
[0], args
[1], TCG_TMP0
, 0);
1926 case INDEX_op_ext8s_i32
:
1927 tgen_ext8s(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1929 case INDEX_op_ext16s_i32
:
1930 tgen_ext16s(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1932 case INDEX_op_ext8u_i32
:
1933 tgen_ext8u(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1935 case INDEX_op_ext16u_i32
:
1936 tgen_ext16u(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1940 /* The TCG bswap definition requires bits 0-47 already be zero.
1941 Thus we don't need the G-type insns to implement bswap16_i64. */
1942 tcg_out_insn(s
, RRE
, LRVR
, args
[0], args
[1]);
1943 tcg_out_sh32(s
, RS_SRL
, args
[0], TCG_REG_NONE
, 16);
1946 tcg_out_insn(s
, RRE
, LRVR
, args
[0], args
[1]);
1949 case INDEX_op_add2_i32
:
1950 if (const_args
[4]) {
1951 tcg_out_insn(s
, RIL
, ALFI
, args
[0], args
[4]);
1953 tcg_out_insn(s
, RR
, ALR
, args
[0], args
[4]);
1955 tcg_out_insn(s
, RRE
, ALCR
, args
[1], args
[5]);
1957 case INDEX_op_sub2_i32
:
1958 if (const_args
[4]) {
1959 tcg_out_insn(s
, RIL
, SLFI
, args
[0], args
[4]);
1961 tcg_out_insn(s
, RR
, SLR
, args
[0], args
[4]);
1963 tcg_out_insn(s
, RRE
, SLBR
, args
[1], args
[5]);
1967 tgen_branch(s
, S390_CC_ALWAYS
, arg_label(args
[0]));
1970 case INDEX_op_brcond_i32
:
1971 tgen_brcond(s
, TCG_TYPE_I32
, args
[2], args
[0],
1972 args
[1], const_args
[1], arg_label(args
[3]));
1974 case INDEX_op_setcond_i32
:
1975 tgen_setcond(s
, TCG_TYPE_I32
, args
[3], args
[0], args
[1],
1976 args
[2], const_args
[2]);
1978 case INDEX_op_movcond_i32
:
1979 tgen_movcond(s
, TCG_TYPE_I32
, args
[5], args
[0], args
[1],
1980 args
[2], const_args
[2], args
[3], const_args
[3]);
1983 case INDEX_op_qemu_ld_i32
:
1984 /* ??? Technically we can use a non-extending instruction. */
1985 case INDEX_op_qemu_ld_i64
:
1986 tcg_out_qemu_ld(s
, args
[0], args
[1], args
[2]);
1988 case INDEX_op_qemu_st_i32
:
1989 case INDEX_op_qemu_st_i64
:
1990 tcg_out_qemu_st(s
, args
[0], args
[1], args
[2]);
1993 case INDEX_op_ld16s_i64
:
1994 tcg_out_mem(s
, 0, RXY_LGH
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1996 case INDEX_op_ld32u_i64
:
1997 tcg_out_mem(s
, 0, RXY_LLGF
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
1999 case INDEX_op_ld32s_i64
:
2000 tcg_out_mem(s
, 0, RXY_LGF
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
2002 case INDEX_op_ld_i64
:
2003 tcg_out_ld(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
2006 case INDEX_op_st32_i64
:
2007 tcg_out_st(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
2009 case INDEX_op_st_i64
:
2010 tcg_out_st(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
2013 case INDEX_op_add_i64
:
2014 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2015 if (const_args
[2]) {
2018 if (a2
== (int16_t)a2
) {
2019 tcg_out_insn(s
, RI
, AGHI
, a0
, a2
);
2022 if (s390_facilities
& FACILITY_EXT_IMM
) {
2023 if (a2
== (int32_t)a2
) {
2024 tcg_out_insn(s
, RIL
, AGFI
, a0
, a2
);
2026 } else if (a2
== (uint32_t)a2
) {
2027 tcg_out_insn(s
, RIL
, ALGFI
, a0
, a2
);
2029 } else if (-a2
== (uint32_t)-a2
) {
2030 tcg_out_insn(s
, RIL
, SLGFI
, a0
, -a2
);
2035 tcg_out_mem(s
, RX_LA
, RXY_LAY
, a0
, a1
, TCG_REG_NONE
, a2
);
2036 } else if (a0
== a1
) {
2037 tcg_out_insn(s
, RRE
, AGR
, a0
, a2
);
2039 tcg_out_insn(s
, RX
, LA
, a0
, a1
, a2
, 0);
2042 case INDEX_op_sub_i64
:
2043 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2044 if (const_args
[2]) {
2047 } else if (a0
== a1
) {
2048 tcg_out_insn(s
, RRE
, SGR
, a0
, a2
);
2050 tcg_out_insn(s
, RRF
, SGRK
, a0
, a1
, a2
);
2054 case INDEX_op_and_i64
:
2055 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2056 if (const_args
[2]) {
2057 tcg_out_mov(s
, TCG_TYPE_I64
, a0
, a1
);
2058 tgen_andi(s
, TCG_TYPE_I64
, args
[0], args
[2]);
2059 } else if (a0
== a1
) {
2060 tcg_out_insn(s
, RRE
, NGR
, args
[0], args
[2]);
2062 tcg_out_insn(s
, RRF
, NGRK
, a0
, a1
, a2
);
2065 case INDEX_op_or_i64
:
2066 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2067 if (const_args
[2]) {
2068 tcg_out_mov(s
, TCG_TYPE_I64
, a0
, a1
);
2069 tgen64_ori(s
, a0
, a2
);
2070 } else if (a0
== a1
) {
2071 tcg_out_insn(s
, RRE
, OGR
, a0
, a2
);
2073 tcg_out_insn(s
, RRF
, OGRK
, a0
, a1
, a2
);
2076 case INDEX_op_xor_i64
:
2077 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2078 if (const_args
[2]) {
2079 tcg_out_mov(s
, TCG_TYPE_I64
, a0
, a1
);
2080 tgen64_xori(s
, a0
, a2
);
2081 } else if (a0
== a1
) {
2082 tcg_out_insn(s
, RRE
, XGR
, a0
, a2
);
2084 tcg_out_insn(s
, RRF
, XGRK
, a0
, a1
, a2
);
2088 case INDEX_op_neg_i64
:
2089 tcg_out_insn(s
, RRE
, LCGR
, args
[0], args
[1]);
2091 case INDEX_op_bswap64_i64
:
2092 tcg_out_insn(s
, RRE
, LRVGR
, args
[0], args
[1]);
2095 case INDEX_op_mul_i64
:
2096 if (const_args
[2]) {
2097 if (args
[2] == (int16_t)args
[2]) {
2098 tcg_out_insn(s
, RI
, MGHI
, args
[0], args
[2]);
2100 tcg_out_insn(s
, RIL
, MSGFI
, args
[0], args
[2]);
2103 tcg_out_insn(s
, RRE
, MSGR
, args
[0], args
[2]);
2107 case INDEX_op_div2_i64
:
2108 /* ??? We get an unnecessary sign-extension of the dividend
2109 into R3 with this definition, but as we do in fact always
2110 produce both quotient and remainder using INDEX_op_div_i64
2111 instead requires jumping through even more hoops. */
2112 tcg_out_insn(s
, RRE
, DSGR
, TCG_REG_R2
, args
[4]);
2114 case INDEX_op_divu2_i64
:
2115 tcg_out_insn(s
, RRE
, DLGR
, TCG_REG_R2
, args
[4]);
2117 case INDEX_op_mulu2_i64
:
2118 tcg_out_insn(s
, RRE
, MLGR
, TCG_REG_R2
, args
[3]);
2121 case INDEX_op_shl_i64
:
2124 if (const_args
[2]) {
2125 tcg_out_sh64(s
, op
, args
[0], args
[1], TCG_REG_NONE
, args
[2]);
2127 tcg_out_sh64(s
, op
, args
[0], args
[1], args
[2], 0);
2130 case INDEX_op_shr_i64
:
2133 case INDEX_op_sar_i64
:
2137 case INDEX_op_rotl_i64
:
2138 if (const_args
[2]) {
2139 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1],
2140 TCG_REG_NONE
, args
[2]);
2142 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1], args
[2], 0);
2145 case INDEX_op_rotr_i64
:
2146 if (const_args
[2]) {
2147 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1],
2148 TCG_REG_NONE
, (64 - args
[2]) & 63);
2150 /* We can use the smaller 32-bit negate because only the
2151 low 6 bits are examined for the rotate. */
2152 tcg_out_insn(s
, RR
, LCR
, TCG_TMP0
, args
[2]);
2153 tcg_out_sh64(s
, RSY_RLLG
, args
[0], args
[1], TCG_TMP0
, 0);
2157 case INDEX_op_ext8s_i64
:
2158 tgen_ext8s(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2160 case INDEX_op_ext16s_i64
:
2161 tgen_ext16s(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2163 case INDEX_op_ext_i32_i64
:
2164 case INDEX_op_ext32s_i64
:
2165 tgen_ext32s(s
, args
[0], args
[1]);
2167 case INDEX_op_ext8u_i64
:
2168 tgen_ext8u(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2170 case INDEX_op_ext16u_i64
:
2171 tgen_ext16u(s
, TCG_TYPE_I64
, args
[0], args
[1]);
2173 case INDEX_op_extu_i32_i64
:
2174 case INDEX_op_ext32u_i64
:
2175 tgen_ext32u(s
, args
[0], args
[1]);
2178 case INDEX_op_add2_i64
:
2179 if (const_args
[4]) {
2180 if ((int64_t)args
[4] >= 0) {
2181 tcg_out_insn(s
, RIL
, ALGFI
, args
[0], args
[4]);
2183 tcg_out_insn(s
, RIL
, SLGFI
, args
[0], -args
[4]);
2186 tcg_out_insn(s
, RRE
, ALGR
, args
[0], args
[4]);
2188 tcg_out_insn(s
, RRE
, ALCGR
, args
[1], args
[5]);
2190 case INDEX_op_sub2_i64
:
2191 if (const_args
[4]) {
2192 if ((int64_t)args
[4] >= 0) {
2193 tcg_out_insn(s
, RIL
, SLGFI
, args
[0], args
[4]);
2195 tcg_out_insn(s
, RIL
, ALGFI
, args
[0], -args
[4]);
2198 tcg_out_insn(s
, RRE
, SLGR
, args
[0], args
[4]);
2200 tcg_out_insn(s
, RRE
, SLBGR
, args
[1], args
[5]);
2203 case INDEX_op_brcond_i64
:
2204 tgen_brcond(s
, TCG_TYPE_I64
, args
[2], args
[0],
2205 args
[1], const_args
[1], arg_label(args
[3]));
2207 case INDEX_op_setcond_i64
:
2208 tgen_setcond(s
, TCG_TYPE_I64
, args
[3], args
[0], args
[1],
2209 args
[2], const_args
[2]);
2211 case INDEX_op_movcond_i64
:
2212 tgen_movcond(s
, TCG_TYPE_I64
, args
[5], args
[0], args
[1],
2213 args
[2], const_args
[2], args
[3], const_args
[3]);
2217 a0
= args
[0], a1
= args
[1], a2
= args
[2];
2218 if (const_args
[1]) {
2219 tgen_deposit(s
, a0
, a2
, args
[3], args
[4], 1);
2221 /* Since we can't support "0Z" as a constraint, we allow a1 in
2222 any register. Fix things up as if a matching constraint. */
2224 TCGType type
= (opc
== INDEX_op_deposit_i64
);
2226 tcg_out_mov(s
, type
, TCG_TMP0
, a2
);
2229 tcg_out_mov(s
, type
, a0
, a1
);
2231 tgen_deposit(s
, a0
, a2
, args
[3], args
[4], 0);
2236 tgen_extract(s
, args
[0], args
[1], args
[2], args
[3]);
2239 case INDEX_op_clz_i64
:
2240 tgen_clz(s
, args
[0], args
[1], args
[2], const_args
[2]);
2244 /* The host memory model is quite strong, we simply need to
2245 serialize the instruction stream. */
2246 if (args
[0] & TCG_MO_ST_LD
) {
2247 tcg_out_insn(s
, RR
, BCR
,
2248 s390_facilities
& FACILITY_FAST_BCR_SER
? 14 : 15, 0);
2252 case INDEX_op_mov_i32
: /* Always emitted via tcg_out_mov. */
2253 case INDEX_op_mov_i64
:
2254 case INDEX_op_movi_i32
: /* Always emitted via tcg_out_movi. */
2255 case INDEX_op_movi_i64
:
2256 case INDEX_op_call
: /* Always emitted via tcg_out_call. */
2262 static const TCGTargetOpDef
*tcg_target_op_def(TCGOpcode op
)
2264 static const TCGTargetOpDef r
= { .args_ct_str
= { "r" } };
2265 static const TCGTargetOpDef r_r
= { .args_ct_str
= { "r", "r" } };
2266 static const TCGTargetOpDef r_L
= { .args_ct_str
= { "r", "L" } };
2267 static const TCGTargetOpDef L_L
= { .args_ct_str
= { "L", "L" } };
2268 static const TCGTargetOpDef r_ri
= { .args_ct_str
= { "r", "ri" } };
2269 static const TCGTargetOpDef r_rC
= { .args_ct_str
= { "r", "rC" } };
2270 static const TCGTargetOpDef r_rZ
= { .args_ct_str
= { "r", "rZ" } };
2271 static const TCGTargetOpDef r_r_ri
= { .args_ct_str
= { "r", "r", "ri" } };
2272 static const TCGTargetOpDef r_r_rM
= { .args_ct_str
= { "r", "r", "rM" } };
2273 static const TCGTargetOpDef r_0_r
= { .args_ct_str
= { "r", "0", "r" } };
2274 static const TCGTargetOpDef r_0_ri
= { .args_ct_str
= { "r", "0", "ri" } };
2275 static const TCGTargetOpDef r_0_rI
= { .args_ct_str
= { "r", "0", "rI" } };
2276 static const TCGTargetOpDef r_0_rJ
= { .args_ct_str
= { "r", "0", "rJ" } };
2277 static const TCGTargetOpDef r_0_rN
= { .args_ct_str
= { "r", "0", "rN" } };
2278 static const TCGTargetOpDef r_0_rM
= { .args_ct_str
= { "r", "0", "rM" } };
2279 static const TCGTargetOpDef a2_r
2280 = { .args_ct_str
= { "r", "r", "0", "1", "r", "r" } };
2281 static const TCGTargetOpDef a2_ri
2282 = { .args_ct_str
= { "r", "r", "0", "1", "ri", "r" } };
2283 static const TCGTargetOpDef a2_rA
2284 = { .args_ct_str
= { "r", "r", "0", "1", "rA", "r" } };
2287 case INDEX_op_goto_ptr
:
2290 case INDEX_op_ld8u_i32
:
2291 case INDEX_op_ld8u_i64
:
2292 case INDEX_op_ld8s_i32
:
2293 case INDEX_op_ld8s_i64
:
2294 case INDEX_op_ld16u_i32
:
2295 case INDEX_op_ld16u_i64
:
2296 case INDEX_op_ld16s_i32
:
2297 case INDEX_op_ld16s_i64
:
2298 case INDEX_op_ld_i32
:
2299 case INDEX_op_ld32u_i64
:
2300 case INDEX_op_ld32s_i64
:
2301 case INDEX_op_ld_i64
:
2302 case INDEX_op_st8_i32
:
2303 case INDEX_op_st8_i64
:
2304 case INDEX_op_st16_i32
:
2305 case INDEX_op_st16_i64
:
2306 case INDEX_op_st_i32
:
2307 case INDEX_op_st32_i64
:
2308 case INDEX_op_st_i64
:
2311 case INDEX_op_add_i32
:
2312 case INDEX_op_add_i64
:
2314 case INDEX_op_sub_i32
:
2315 case INDEX_op_sub_i64
:
2316 return (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_ri
: &r_0_ri
);
2318 case INDEX_op_mul_i32
:
2319 /* If we have the general-instruction-extensions, then we have
2320 MULTIPLY SINGLE IMMEDIATE with a signed 32-bit, otherwise we
2321 have only MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
2322 return (s390_facilities
& FACILITY_GEN_INST_EXT
? &r_0_ri
: &r_0_rI
);
2323 case INDEX_op_mul_i64
:
2324 return (s390_facilities
& FACILITY_GEN_INST_EXT
? &r_0_rJ
: &r_0_rI
);
2326 case INDEX_op_or_i32
:
2327 /* The use of [iNM] constraints are optimization only, since a full
2328 64-bit immediate OR can always be performed with 4 sequential
2329 OI[LH][LH] instructions. By rejecting certain negative ranges,
2330 the immediate load plus the reg-reg OR is smaller. */
2331 return (s390_facilities
& FACILITY_EXT_IMM
2332 ? (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_ri
: &r_0_ri
)
2334 case INDEX_op_or_i64
:
2335 return (s390_facilities
& FACILITY_EXT_IMM
2336 ? (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_rM
: &r_0_rM
)
2339 case INDEX_op_xor_i32
:
2340 /* Without EXT_IMM, no immediates are supported. Otherwise,
2341 rejecting certain negative ranges leads to smaller code. */
2342 return (s390_facilities
& FACILITY_EXT_IMM
2343 ? (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_ri
: &r_0_ri
)
2345 case INDEX_op_xor_i64
:
2346 return (s390_facilities
& FACILITY_EXT_IMM
2347 ? (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_rM
: &r_0_rM
)
2350 case INDEX_op_and_i32
:
2351 case INDEX_op_and_i64
:
2352 return (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_ri
: &r_0_ri
);
2354 case INDEX_op_shl_i32
:
2355 case INDEX_op_shr_i32
:
2356 case INDEX_op_sar_i32
:
2357 return (s390_facilities
& FACILITY_DISTINCT_OPS
? &r_r_ri
: &r_0_ri
);
2359 case INDEX_op_shl_i64
:
2360 case INDEX_op_shr_i64
:
2361 case INDEX_op_sar_i64
:
2364 case INDEX_op_rotl_i32
:
2365 case INDEX_op_rotl_i64
:
2366 case INDEX_op_rotr_i32
:
2367 case INDEX_op_rotr_i64
:
2370 case INDEX_op_brcond_i32
:
2371 /* Without EXT_IMM, only the LOAD AND TEST insn is available. */
2372 return (s390_facilities
& FACILITY_EXT_IMM
? &r_ri
: &r_rZ
);
2373 case INDEX_op_brcond_i64
:
2374 return (s390_facilities
& FACILITY_EXT_IMM
? &r_rC
: &r_rZ
);
2376 case INDEX_op_bswap16_i32
:
2377 case INDEX_op_bswap16_i64
:
2378 case INDEX_op_bswap32_i32
:
2379 case INDEX_op_bswap32_i64
:
2380 case INDEX_op_bswap64_i64
:
2381 case INDEX_op_neg_i32
:
2382 case INDEX_op_neg_i64
:
2383 case INDEX_op_ext8s_i32
:
2384 case INDEX_op_ext8s_i64
:
2385 case INDEX_op_ext8u_i32
:
2386 case INDEX_op_ext8u_i64
:
2387 case INDEX_op_ext16s_i32
:
2388 case INDEX_op_ext16s_i64
:
2389 case INDEX_op_ext16u_i32
:
2390 case INDEX_op_ext16u_i64
:
2391 case INDEX_op_ext32s_i64
:
2392 case INDEX_op_ext32u_i64
:
2393 case INDEX_op_ext_i32_i64
:
2394 case INDEX_op_extu_i32_i64
:
2395 case INDEX_op_extract_i32
:
2396 case INDEX_op_extract_i64
:
2399 case INDEX_op_clz_i64
:
2402 case INDEX_op_qemu_ld_i32
:
2403 case INDEX_op_qemu_ld_i64
:
2405 case INDEX_op_qemu_st_i64
:
2406 case INDEX_op_qemu_st_i32
:
2409 case INDEX_op_deposit_i32
:
2410 case INDEX_op_deposit_i64
:
2412 static const TCGTargetOpDef dep
2413 = { .args_ct_str
= { "r", "rZ", "r" } };
2416 case INDEX_op_setcond_i32
:
2417 case INDEX_op_setcond_i64
:
2419 /* Without EXT_IMM, only the LOAD AND TEST insn is available. */
2420 static const TCGTargetOpDef setc_z
2421 = { .args_ct_str
= { "r", "r", "rZ" } };
2422 static const TCGTargetOpDef setc_c
2423 = { .args_ct_str
= { "r", "r", "rC" } };
2424 return (s390_facilities
& FACILITY_EXT_IMM
? &setc_c
: &setc_z
);
2426 case INDEX_op_movcond_i32
:
2427 case INDEX_op_movcond_i64
:
2429 /* Without EXT_IMM, only the LOAD AND TEST insn is available. */
2430 static const TCGTargetOpDef movc_z
2431 = { .args_ct_str
= { "r", "r", "rZ", "r", "0" } };
2432 static const TCGTargetOpDef movc_c
2433 = { .args_ct_str
= { "r", "r", "rC", "r", "0" } };
2434 static const TCGTargetOpDef movc_l
2435 = { .args_ct_str
= { "r", "r", "rC", "rI", "0" } };
2436 return (s390_facilities
& FACILITY_EXT_IMM
2437 ? (s390_facilities
& FACILITY_LOAD_ON_COND2
2438 ? &movc_l
: &movc_c
)
2441 case INDEX_op_div2_i32
:
2442 case INDEX_op_div2_i64
:
2443 case INDEX_op_divu2_i32
:
2444 case INDEX_op_divu2_i64
:
2446 static const TCGTargetOpDef div2
2447 = { .args_ct_str
= { "b", "a", "0", "1", "r" } };
2450 case INDEX_op_mulu2_i64
:
2452 static const TCGTargetOpDef mul2
2453 = { .args_ct_str
= { "b", "a", "0", "r" } };
2457 case INDEX_op_add2_i32
:
2458 case INDEX_op_sub2_i32
:
2459 return (s390_facilities
& FACILITY_EXT_IMM
? &a2_ri
: &a2_r
);
2460 case INDEX_op_add2_i64
:
2461 case INDEX_op_sub2_i64
:
2462 return (s390_facilities
& FACILITY_EXT_IMM
? &a2_rA
: &a2_r
);
2470 static void query_s390_facilities(void)
2472 unsigned long hwcap
= qemu_getauxval(AT_HWCAP
);
2474 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
2475 is present on all 64-bit systems, but let's check for it anyway. */
2476 if (hwcap
& HWCAP_S390_STFLE
) {
2477 register int r0
__asm__("0");
2478 register void *r1
__asm__("1");
2481 r1
= &s390_facilities
;
2482 asm volatile(".word 0xb2b0,0x1000"
2483 : "=r"(r0
) : "0"(0), "r"(r1
) : "memory", "cc");
2487 static void tcg_target_init(TCGContext
*s
)
2489 query_s390_facilities();
2491 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I32
], 0, 0xffff);
2492 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I64
], 0, 0xffff);
2494 tcg_regset_clear(tcg_target_call_clobber_regs
);
2495 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R0
);
2496 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R1
);
2497 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R2
);
2498 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R3
);
2499 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R4
);
2500 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R5
);
2501 /* The r6 register is technically call-saved, but it's also a parameter
2502 register, so it can get killed by setup for the qemu_st helper. */
2503 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R6
);
2504 /* The return register can be considered call-clobbered. */
2505 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R14
);
2507 tcg_regset_clear(s
->reserved_regs
);
2508 tcg_regset_set_reg(s
->reserved_regs
, TCG_TMP0
);
2509 /* XXX many insns can't be used with R0, so we better avoid it for now */
2510 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_R0
);
2511 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_CALL_STACK
);
2514 #define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
2515 + TCG_STATIC_CALL_ARGS_SIZE \
2516 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
2518 static void tcg_target_qemu_prologue(TCGContext
*s
)
2520 /* stmg %r6,%r15,48(%r15) (save registers) */
2521 tcg_out_insn(s
, RXY
, STMG
, TCG_REG_R6
, TCG_REG_R15
, TCG_REG_R15
, 48);
2523 /* aghi %r15,-frame_size */
2524 tcg_out_insn(s
, RI
, AGHI
, TCG_REG_R15
, -FRAME_SIZE
);
2526 tcg_set_frame(s
, TCG_REG_CALL_STACK
,
2527 TCG_STATIC_CALL_ARGS_SIZE
+ TCG_TARGET_CALL_STACK_OFFSET
,
2528 CPU_TEMP_BUF_NLONGS
* sizeof(long));
2530 #ifndef CONFIG_SOFTMMU
2531 if (guest_base
>= 0x80000) {
2532 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_GUEST_BASE_REG
, guest_base
);
2533 tcg_regset_set_reg(s
->reserved_regs
, TCG_GUEST_BASE_REG
);
2537 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_AREG0
, tcg_target_call_iarg_regs
[0]);
2538 /* br %r3 (go to TB) */
2539 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, tcg_target_call_iarg_regs
[1]);
2542 * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2543 * and fall through to the rest of the epilogue.
2545 s
->code_gen_epilogue
= s
->code_ptr
;
2546 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R2
, 0);
2549 tb_ret_addr
= s
->code_ptr
;
2551 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2552 tcg_out_insn(s
, RXY
, LMG
, TCG_REG_R6
, TCG_REG_R15
, TCG_REG_R15
,
2555 /* br %r14 (return) */
2556 tcg_out_insn(s
, RR
, BCR
, S390_CC_ALWAYS
, TCG_REG_R14
);
2561 uint8_t fde_def_cfa
[4];
2562 uint8_t fde_reg_ofs
[18];
2565 /* We're expecting a 2 byte uleb128 encoded value. */
2566 QEMU_BUILD_BUG_ON(FRAME_SIZE
>= (1 << 14));
2568 #define ELF_HOST_MACHINE EM_S390
2570 static const DebugFrame debug_frame
= {
2571 .h
.cie
.len
= sizeof(DebugFrameCIE
)-4, /* length after .len member */
2574 .h
.cie
.code_align
= 1,
2575 .h
.cie
.data_align
= 8, /* sleb128 8 */
2576 .h
.cie
.return_column
= TCG_REG_R14
,
2578 /* Total FDE size does not include the "len" member. */
2579 .h
.fde
.len
= sizeof(DebugFrame
) - offsetof(DebugFrame
, h
.fde
.cie_offset
),
2582 12, TCG_REG_CALL_STACK
, /* DW_CFA_def_cfa %r15, ... */
2583 (FRAME_SIZE
& 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2587 0x86, 6, /* DW_CFA_offset, %r6, 48 */
2588 0x87, 7, /* DW_CFA_offset, %r7, 56 */
2589 0x88, 8, /* DW_CFA_offset, %r8, 64 */
2590 0x89, 9, /* DW_CFA_offset, %r92, 72 */
2591 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
2592 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
2593 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
2594 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
2595 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
2599 void tcg_register_jit(void *buf
, size_t buf_size
)
2601 tcg_register_jit_int(buf
, buf_size
, &debug_frame
, sizeof(debug_frame
));