vnc: fix unfinalized tlscreds for VncDisplay
[qemu/ar7.git] / tcg / s390 / tcg-target.c.inc
blobd7ef079055670b215ccceae56feae3b12ebef582
1 /*
2  * Tiny Code Generator for QEMU
3  *
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>
7  *
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:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
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
24  * THE SOFTWARE.
25  */
27 /* We only support generating code for 64-bit mode.  */
28 #if TCG_TARGET_REG_BITS != 64
29 #error "unsupported code generation mode"
30 #endif
32 #include "../tcg-pool.c.inc"
33 #include "elf.h"
35 /* ??? The translation blocks produced by TCG are generally small enough to
36    be entirely reachable with a 16-bit displacement.  Leaving the option for
37    a 32-bit displacement here Just In Case.  */
38 #define USE_LONG_BRANCHES 0
40 #define TCG_CT_CONST_S16   0x100
41 #define TCG_CT_CONST_S32   0x200
42 #define TCG_CT_CONST_S33   0x400
43 #define TCG_CT_CONST_ZERO  0x800
45 /* Several places within the instruction set 0 means "no register"
46    rather than TCG_REG_R0.  */
47 #define TCG_REG_NONE    0
49 /* A scratch register that may be be used throughout the backend.  */
50 #define TCG_TMP0        TCG_REG_R1
52 /* A scratch register that holds a pointer to the beginning of the TB.
53    We don't need this when we have pc-relative loads with the general
54    instructions extension facility.  */
55 #define TCG_REG_TB      TCG_REG_R12
56 #define USE_REG_TB      (!(s390_facilities & FACILITY_GEN_INST_EXT))
58 #ifndef CONFIG_SOFTMMU
59 #define TCG_GUEST_BASE_REG TCG_REG_R13
60 #endif
62 /* All of the following instructions are prefixed with their instruction
63    format, and are defined as 8- or 16-bit quantities, even when the two
64    halves of the 16-bit quantity may appear 32 bits apart in the insn.
65    This makes it easy to copy the values from the tables in Appendix B.  */
66 typedef enum S390Opcode {
67     RIL_AFI     = 0xc209,
68     RIL_AGFI    = 0xc208,
69     RIL_ALFI    = 0xc20b,
70     RIL_ALGFI   = 0xc20a,
71     RIL_BRASL   = 0xc005,
72     RIL_BRCL    = 0xc004,
73     RIL_CFI     = 0xc20d,
74     RIL_CGFI    = 0xc20c,
75     RIL_CLFI    = 0xc20f,
76     RIL_CLGFI   = 0xc20e,
77     RIL_CLRL    = 0xc60f,
78     RIL_CLGRL   = 0xc60a,
79     RIL_CRL     = 0xc60d,
80     RIL_CGRL    = 0xc608,
81     RIL_IIHF    = 0xc008,
82     RIL_IILF    = 0xc009,
83     RIL_LARL    = 0xc000,
84     RIL_LGFI    = 0xc001,
85     RIL_LGRL    = 0xc408,
86     RIL_LLIHF   = 0xc00e,
87     RIL_LLILF   = 0xc00f,
88     RIL_LRL     = 0xc40d,
89     RIL_MSFI    = 0xc201,
90     RIL_MSGFI   = 0xc200,
91     RIL_NIHF    = 0xc00a,
92     RIL_NILF    = 0xc00b,
93     RIL_OIHF    = 0xc00c,
94     RIL_OILF    = 0xc00d,
95     RIL_SLFI    = 0xc205,
96     RIL_SLGFI   = 0xc204,
97     RIL_XIHF    = 0xc006,
98     RIL_XILF    = 0xc007,
100     RI_AGHI     = 0xa70b,
101     RI_AHI      = 0xa70a,
102     RI_BRC      = 0xa704,
103     RI_CHI      = 0xa70e,
104     RI_CGHI     = 0xa70f,
105     RI_IIHH     = 0xa500,
106     RI_IIHL     = 0xa501,
107     RI_IILH     = 0xa502,
108     RI_IILL     = 0xa503,
109     RI_LGHI     = 0xa709,
110     RI_LLIHH    = 0xa50c,
111     RI_LLIHL    = 0xa50d,
112     RI_LLILH    = 0xa50e,
113     RI_LLILL    = 0xa50f,
114     RI_MGHI     = 0xa70d,
115     RI_MHI      = 0xa70c,
116     RI_NIHH     = 0xa504,
117     RI_NIHL     = 0xa505,
118     RI_NILH     = 0xa506,
119     RI_NILL     = 0xa507,
120     RI_OIHH     = 0xa508,
121     RI_OIHL     = 0xa509,
122     RI_OILH     = 0xa50a,
123     RI_OILL     = 0xa50b,
125     RIE_CGIJ    = 0xec7c,
126     RIE_CGRJ    = 0xec64,
127     RIE_CIJ     = 0xec7e,
128     RIE_CLGRJ   = 0xec65,
129     RIE_CLIJ    = 0xec7f,
130     RIE_CLGIJ   = 0xec7d,
131     RIE_CLRJ    = 0xec77,
132     RIE_CRJ     = 0xec76,
133     RIE_LOCGHI  = 0xec46,
134     RIE_RISBG   = 0xec55,
136     RRE_AGR     = 0xb908,
137     RRE_ALGR    = 0xb90a,
138     RRE_ALCR    = 0xb998,
139     RRE_ALCGR   = 0xb988,
140     RRE_CGR     = 0xb920,
141     RRE_CLGR    = 0xb921,
142     RRE_DLGR    = 0xb987,
143     RRE_DLR     = 0xb997,
144     RRE_DSGFR   = 0xb91d,
145     RRE_DSGR    = 0xb90d,
146     RRE_FLOGR   = 0xb983,
147     RRE_LGBR    = 0xb906,
148     RRE_LCGR    = 0xb903,
149     RRE_LGFR    = 0xb914,
150     RRE_LGHR    = 0xb907,
151     RRE_LGR     = 0xb904,
152     RRE_LLGCR   = 0xb984,
153     RRE_LLGFR   = 0xb916,
154     RRE_LLGHR   = 0xb985,
155     RRE_LRVR    = 0xb91f,
156     RRE_LRVGR   = 0xb90f,
157     RRE_LTGR    = 0xb902,
158     RRE_MLGR    = 0xb986,
159     RRE_MSGR    = 0xb90c,
160     RRE_MSR     = 0xb252,
161     RRE_NGR     = 0xb980,
162     RRE_OGR     = 0xb981,
163     RRE_SGR     = 0xb909,
164     RRE_SLGR    = 0xb90b,
165     RRE_SLBR    = 0xb999,
166     RRE_SLBGR   = 0xb989,
167     RRE_XGR     = 0xb982,
169     RRF_LOCR    = 0xb9f2,
170     RRF_LOCGR   = 0xb9e2,
171     RRF_NRK     = 0xb9f4,
172     RRF_NGRK    = 0xb9e4,
173     RRF_ORK     = 0xb9f6,
174     RRF_OGRK    = 0xb9e6,
175     RRF_SRK     = 0xb9f9,
176     RRF_SGRK    = 0xb9e9,
177     RRF_SLRK    = 0xb9fb,
178     RRF_SLGRK   = 0xb9eb,
179     RRF_XRK     = 0xb9f7,
180     RRF_XGRK    = 0xb9e7,
182     RR_AR       = 0x1a,
183     RR_ALR      = 0x1e,
184     RR_BASR     = 0x0d,
185     RR_BCR      = 0x07,
186     RR_CLR      = 0x15,
187     RR_CR       = 0x19,
188     RR_DR       = 0x1d,
189     RR_LCR      = 0x13,
190     RR_LR       = 0x18,
191     RR_LTR      = 0x12,
192     RR_NR       = 0x14,
193     RR_OR       = 0x16,
194     RR_SR       = 0x1b,
195     RR_SLR      = 0x1f,
196     RR_XR       = 0x17,
198     RSY_RLL     = 0xeb1d,
199     RSY_RLLG    = 0xeb1c,
200     RSY_SLLG    = 0xeb0d,
201     RSY_SLLK    = 0xebdf,
202     RSY_SRAG    = 0xeb0a,
203     RSY_SRAK    = 0xebdc,
204     RSY_SRLG    = 0xeb0c,
205     RSY_SRLK    = 0xebde,
207     RS_SLL      = 0x89,
208     RS_SRA      = 0x8a,
209     RS_SRL      = 0x88,
211     RXY_AG      = 0xe308,
212     RXY_AY      = 0xe35a,
213     RXY_CG      = 0xe320,
214     RXY_CLG     = 0xe321,
215     RXY_CLY     = 0xe355,
216     RXY_CY      = 0xe359,
217     RXY_LAY     = 0xe371,
218     RXY_LB      = 0xe376,
219     RXY_LG      = 0xe304,
220     RXY_LGB     = 0xe377,
221     RXY_LGF     = 0xe314,
222     RXY_LGH     = 0xe315,
223     RXY_LHY     = 0xe378,
224     RXY_LLGC    = 0xe390,
225     RXY_LLGF    = 0xe316,
226     RXY_LLGH    = 0xe391,
227     RXY_LMG     = 0xeb04,
228     RXY_LRV     = 0xe31e,
229     RXY_LRVG    = 0xe30f,
230     RXY_LRVH    = 0xe31f,
231     RXY_LY      = 0xe358,
232     RXY_NG      = 0xe380,
233     RXY_OG      = 0xe381,
234     RXY_STCY    = 0xe372,
235     RXY_STG     = 0xe324,
236     RXY_STHY    = 0xe370,
237     RXY_STMG    = 0xeb24,
238     RXY_STRV    = 0xe33e,
239     RXY_STRVG   = 0xe32f,
240     RXY_STRVH   = 0xe33f,
241     RXY_STY     = 0xe350,
242     RXY_XG      = 0xe382,
244     RX_A        = 0x5a,
245     RX_C        = 0x59,
246     RX_L        = 0x58,
247     RX_LA       = 0x41,
248     RX_LH       = 0x48,
249     RX_ST       = 0x50,
250     RX_STC      = 0x42,
251     RX_STH      = 0x40,
253     NOP         = 0x0707,
254 } S390Opcode;
256 #ifdef CONFIG_DEBUG_TCG
257 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
258     "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
259     "%r8", "%r9", "%r10" "%r11" "%r12" "%r13" "%r14" "%r15"
261 #endif
263 /* Since R6 is a potential argument register, choose it last of the
264    call-saved registers.  Likewise prefer the call-clobbered registers
265    in reverse order to maximize the chance of avoiding the arguments.  */
266 static const int tcg_target_reg_alloc_order[] = {
267     /* Call saved registers.  */
268     TCG_REG_R13,
269     TCG_REG_R12,
270     TCG_REG_R11,
271     TCG_REG_R10,
272     TCG_REG_R9,
273     TCG_REG_R8,
274     TCG_REG_R7,
275     TCG_REG_R6,
276     /* Call clobbered registers.  */
277     TCG_REG_R14,
278     TCG_REG_R0,
279     TCG_REG_R1,
280     /* Argument registers, in reverse order of allocation.  */
281     TCG_REG_R5,
282     TCG_REG_R4,
283     TCG_REG_R3,
284     TCG_REG_R2,
287 static const int tcg_target_call_iarg_regs[] = {
288     TCG_REG_R2,
289     TCG_REG_R3,
290     TCG_REG_R4,
291     TCG_REG_R5,
292     TCG_REG_R6,
295 static const int tcg_target_call_oarg_regs[] = {
296     TCG_REG_R2,
299 #define S390_CC_EQ      8
300 #define S390_CC_LT      4
301 #define S390_CC_GT      2
302 #define S390_CC_OV      1
303 #define S390_CC_NE      (S390_CC_LT | S390_CC_GT)
304 #define S390_CC_LE      (S390_CC_LT | S390_CC_EQ)
305 #define S390_CC_GE      (S390_CC_GT | S390_CC_EQ)
306 #define S390_CC_NEVER   0
307 #define S390_CC_ALWAYS  15
309 /* Condition codes that result from a COMPARE and COMPARE LOGICAL.  */
310 static const uint8_t tcg_cond_to_s390_cond[] = {
311     [TCG_COND_EQ]  = S390_CC_EQ,
312     [TCG_COND_NE]  = S390_CC_NE,
313     [TCG_COND_LT]  = S390_CC_LT,
314     [TCG_COND_LE]  = S390_CC_LE,
315     [TCG_COND_GT]  = S390_CC_GT,
316     [TCG_COND_GE]  = S390_CC_GE,
317     [TCG_COND_LTU] = S390_CC_LT,
318     [TCG_COND_LEU] = S390_CC_LE,
319     [TCG_COND_GTU] = S390_CC_GT,
320     [TCG_COND_GEU] = S390_CC_GE,
323 /* Condition codes that result from a LOAD AND TEST.  Here, we have no
324    unsigned instruction variation, however since the test is vs zero we
325    can re-map the outcomes appropriately.  */
326 static const uint8_t tcg_cond_to_ltr_cond[] = {
327     [TCG_COND_EQ]  = S390_CC_EQ,
328     [TCG_COND_NE]  = S390_CC_NE,
329     [TCG_COND_LT]  = S390_CC_LT,
330     [TCG_COND_LE]  = S390_CC_LE,
331     [TCG_COND_GT]  = S390_CC_GT,
332     [TCG_COND_GE]  = S390_CC_GE,
333     [TCG_COND_LTU] = S390_CC_NEVER,
334     [TCG_COND_LEU] = S390_CC_EQ,
335     [TCG_COND_GTU] = S390_CC_NE,
336     [TCG_COND_GEU] = S390_CC_ALWAYS,
339 #ifdef CONFIG_SOFTMMU
340 static void * const qemu_ld_helpers[16] = {
341     [MO_UB]   = helper_ret_ldub_mmu,
342     [MO_SB]   = helper_ret_ldsb_mmu,
343     [MO_LEUW] = helper_le_lduw_mmu,
344     [MO_LESW] = helper_le_ldsw_mmu,
345     [MO_LEUL] = helper_le_ldul_mmu,
346     [MO_LESL] = helper_le_ldsl_mmu,
347     [MO_LEQ]  = helper_le_ldq_mmu,
348     [MO_BEUW] = helper_be_lduw_mmu,
349     [MO_BESW] = helper_be_ldsw_mmu,
350     [MO_BEUL] = helper_be_ldul_mmu,
351     [MO_BESL] = helper_be_ldsl_mmu,
352     [MO_BEQ]  = helper_be_ldq_mmu,
355 static void * const qemu_st_helpers[16] = {
356     [MO_UB]   = helper_ret_stb_mmu,
357     [MO_LEUW] = helper_le_stw_mmu,
358     [MO_LEUL] = helper_le_stl_mmu,
359     [MO_LEQ]  = helper_le_stq_mmu,
360     [MO_BEUW] = helper_be_stw_mmu,
361     [MO_BEUL] = helper_be_stl_mmu,
362     [MO_BEQ]  = helper_be_stq_mmu,
364 #endif
366 static const tcg_insn_unit *tb_ret_addr;
367 uint64_t s390_facilities;
369 static bool patch_reloc(tcg_insn_unit *src_rw, int type,
370                         intptr_t value, intptr_t addend)
372     const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
373     intptr_t pcrel2;
374     uint32_t old;
376     value += addend;
377     pcrel2 = (tcg_insn_unit *)value - src_rx;
379     switch (type) {
380     case R_390_PC16DBL:
381         if (pcrel2 == (int16_t)pcrel2) {
382             tcg_patch16(src_rw, pcrel2);
383             return true;
384         }
385         break;
386     case R_390_PC32DBL:
387         if (pcrel2 == (int32_t)pcrel2) {
388             tcg_patch32(src_rw, pcrel2);
389             return true;
390         }
391         break;
392     case R_390_20:
393         if (value == sextract64(value, 0, 20)) {
394             old = *(uint32_t *)src_rw & 0xf00000ff;
395             old |= ((value & 0xfff) << 16) | ((value & 0xff000) >> 4);
396             tcg_patch32(src_rw, old);
397             return true;
398         }
399         break;
400     default:
401         g_assert_not_reached();
402     }
403     return false;
406 /* parse target specific constraints */
407 static const char *target_parse_constraint(TCGArgConstraint *ct,
408                                            const char *ct_str, TCGType type)
410     switch (*ct_str++) {
411     case 'r':                  /* all registers */
412         ct->regs = 0xffff;
413         break;
414     case 'L':                  /* qemu_ld/st constraint */
415         ct->regs = 0xffff;
416         tcg_regset_reset_reg(ct->regs, TCG_REG_R2);
417         tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
418         tcg_regset_reset_reg(ct->regs, TCG_REG_R4);
419         break;
420     case 'a':                  /* force R2 for division */
421         ct->regs = 0;
422         tcg_regset_set_reg(ct->regs, TCG_REG_R2);
423         break;
424     case 'b':                  /* force R3 for division */
425         ct->regs = 0;
426         tcg_regset_set_reg(ct->regs, TCG_REG_R3);
427         break;
428     case 'A':
429         ct->ct |= TCG_CT_CONST_S33;
430         break;
431     case 'I':
432         ct->ct |= TCG_CT_CONST_S16;
433         break;
434     case 'J':
435         ct->ct |= TCG_CT_CONST_S32;
436         break;
437     case 'Z':
438         ct->ct |= TCG_CT_CONST_ZERO;
439         break;
440     default:
441         return NULL;
442     }
443     return ct_str;
446 /* Test if a constant matches the constraint. */
447 static int tcg_target_const_match(tcg_target_long val, TCGType type,
448                                   const TCGArgConstraint *arg_ct)
450     int ct = arg_ct->ct;
452     if (ct & TCG_CT_CONST) {
453         return 1;
454     }
456     if (type == TCG_TYPE_I32) {
457         val = (int32_t)val;
458     }
460     /* The following are mutually exclusive.  */
461     if (ct & TCG_CT_CONST_S16) {
462         return val == (int16_t)val;
463     } else if (ct & TCG_CT_CONST_S32) {
464         return val == (int32_t)val;
465     } else if (ct & TCG_CT_CONST_S33) {
466         return val >= -0xffffffffll && val <= 0xffffffffll;
467     } else if (ct & TCG_CT_CONST_ZERO) {
468         return val == 0;
469     }
471     return 0;
474 /* Emit instructions according to the given instruction format.  */
476 static void tcg_out_insn_RR(TCGContext *s, S390Opcode op, TCGReg r1, TCGReg r2)
478     tcg_out16(s, (op << 8) | (r1 << 4) | r2);
481 static void tcg_out_insn_RRE(TCGContext *s, S390Opcode op,
482                              TCGReg r1, TCGReg r2)
484     tcg_out32(s, (op << 16) | (r1 << 4) | r2);
487 static void tcg_out_insn_RRF(TCGContext *s, S390Opcode op,
488                              TCGReg r1, TCGReg r2, int m3)
490     tcg_out32(s, (op << 16) | (m3 << 12) | (r1 << 4) | r2);
493 static void tcg_out_insn_RI(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
495     tcg_out32(s, (op << 16) | (r1 << 20) | (i2 & 0xffff));
498 static void tcg_out_insn_RIE(TCGContext *s, S390Opcode op, TCGReg r1,
499                              int i2, int m3)
501     tcg_out16(s, (op & 0xff00) | (r1 << 4) | m3);
502     tcg_out32(s, (i2 << 16) | (op & 0xff));
505 static void tcg_out_insn_RIL(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
507     tcg_out16(s, op | (r1 << 4));
508     tcg_out32(s, i2);
511 static void tcg_out_insn_RS(TCGContext *s, S390Opcode op, TCGReg r1,
512                             TCGReg b2, TCGReg r3, int disp)
514     tcg_out32(s, (op << 24) | (r1 << 20) | (r3 << 16) | (b2 << 12)
515               | (disp & 0xfff));
518 static void tcg_out_insn_RSY(TCGContext *s, S390Opcode op, TCGReg r1,
519                              TCGReg b2, TCGReg r3, int disp)
521     tcg_out16(s, (op & 0xff00) | (r1 << 4) | r3);
522     tcg_out32(s, (op & 0xff) | (b2 << 28)
523               | ((disp & 0xfff) << 16) | ((disp & 0xff000) >> 4));
526 #define tcg_out_insn_RX   tcg_out_insn_RS
527 #define tcg_out_insn_RXY  tcg_out_insn_RSY
529 /* Emit an opcode with "type-checking" of the format.  */
530 #define tcg_out_insn(S, FMT, OP, ...) \
531     glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
534 /* emit 64-bit shifts */
535 static void tcg_out_sh64(TCGContext* s, S390Opcode op, TCGReg dest,
536                          TCGReg src, TCGReg sh_reg, int sh_imm)
538     tcg_out_insn_RSY(s, op, dest, sh_reg, src, sh_imm);
541 /* emit 32-bit shifts */
542 static void tcg_out_sh32(TCGContext* s, S390Opcode op, TCGReg dest,
543                          TCGReg sh_reg, int sh_imm)
545     tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
548 static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
550     if (src != dst) {
551         if (type == TCG_TYPE_I32) {
552             tcg_out_insn(s, RR, LR, dst, src);
553         } else {
554             tcg_out_insn(s, RRE, LGR, dst, src);
555         }
556     }
557     return true;
560 static const S390Opcode lli_insns[4] = {
561     RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
564 static bool maybe_out_small_movi(TCGContext *s, TCGType type,
565                                  TCGReg ret, tcg_target_long sval)
567     tcg_target_ulong uval = sval;
568     int i;
570     if (type == TCG_TYPE_I32) {
571         uval = (uint32_t)sval;
572         sval = (int32_t)sval;
573     }
575     /* Try all 32-bit insns that can load it in one go.  */
576     if (sval >= -0x8000 && sval < 0x8000) {
577         tcg_out_insn(s, RI, LGHI, ret, sval);
578         return true;
579     }
581     for (i = 0; i < 4; i++) {
582         tcg_target_long mask = 0xffffull << i*16;
583         if ((uval & mask) == uval) {
584             tcg_out_insn_RI(s, lli_insns[i], ret, uval >> i*16);
585             return true;
586         }
587     }
589     return false;
592 /* load a register with an immediate value */
593 static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
594                              tcg_target_long sval, bool in_prologue)
596     tcg_target_ulong uval;
598     /* Try all 32-bit insns that can load it in one go.  */
599     if (maybe_out_small_movi(s, type, ret, sval)) {
600         return;
601     }
603     uval = sval;
604     if (type == TCG_TYPE_I32) {
605         uval = (uint32_t)sval;
606         sval = (int32_t)sval;
607     }
609     /* Try all 48-bit insns that can load it in one go.  */
610     if (s390_facilities & FACILITY_EXT_IMM) {
611         if (sval == (int32_t)sval) {
612             tcg_out_insn(s, RIL, LGFI, ret, sval);
613             return;
614         }
615         if (uval <= 0xffffffff) {
616             tcg_out_insn(s, RIL, LLILF, ret, uval);
617             return;
618         }
619         if ((uval & 0xffffffff) == 0) {
620             tcg_out_insn(s, RIL, LLIHF, ret, uval >> 32);
621             return;
622         }
623     }
625     /* Try for PC-relative address load.  For odd addresses,
626        attempt to use an offset from the start of the TB.  */
627     if ((sval & 1) == 0) {
628         ptrdiff_t off = tcg_pcrel_diff(s, (void *)sval) >> 1;
629         if (off == (int32_t)off) {
630             tcg_out_insn(s, RIL, LARL, ret, off);
631             return;
632         }
633     } else if (USE_REG_TB && !in_prologue) {
634         ptrdiff_t off = tcg_tbrel_diff(s, (void *)sval);
635         if (off == sextract64(off, 0, 20)) {
636             /* This is certain to be an address within TB, and therefore
637                OFF will be negative; don't try RX_LA.  */
638             tcg_out_insn(s, RXY, LAY, ret, TCG_REG_TB, TCG_REG_NONE, off);
639             return;
640         }
641     }
643     /* A 32-bit unsigned value can be loaded in 2 insns.  And given
644        that LLILL, LLIHL, LLILF above did not succeed, we know that
645        both insns are required.  */
646     if (uval <= 0xffffffff) {
647         tcg_out_insn(s, RI, LLILL, ret, uval);
648         tcg_out_insn(s, RI, IILH, ret, uval >> 16);
649         return;
650     }
652     /* Otherwise, stuff it in the constant pool.  */
653     if (s390_facilities & FACILITY_GEN_INST_EXT) {
654         tcg_out_insn(s, RIL, LGRL, ret, 0);
655         new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
656     } else if (USE_REG_TB && !in_prologue) {
657         tcg_out_insn(s, RXY, LG, ret, TCG_REG_TB, TCG_REG_NONE, 0);
658         new_pool_label(s, sval, R_390_20, s->code_ptr - 2,
659                        tcg_tbrel_diff(s, NULL));
660     } else {
661         TCGReg base = ret ? ret : TCG_TMP0;
662         tcg_out_insn(s, RIL, LARL, base, 0);
663         new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
664         tcg_out_insn(s, RXY, LG, ret, base, TCG_REG_NONE, 0);
665     }
668 static void tcg_out_movi(TCGContext *s, TCGType type,
669                          TCGReg ret, tcg_target_long sval)
671     tcg_out_movi_int(s, type, ret, sval, false);
674 /* Emit a load/store type instruction.  Inputs are:
675    DATA:     The register to be loaded or stored.
676    BASE+OFS: The effective address.
677    OPC_RX:   If the operation has an RX format opcode (e.g. STC), otherwise 0.
678    OPC_RXY:  The RXY format opcode for the operation (e.g. STCY).  */
680 static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
681                         TCGReg data, TCGReg base, TCGReg index,
682                         tcg_target_long ofs)
684     if (ofs < -0x80000 || ofs >= 0x80000) {
685         /* Combine the low 20 bits of the offset with the actual load insn;
686            the high 44 bits must come from an immediate load.  */
687         tcg_target_long low = ((ofs & 0xfffff) ^ 0x80000) - 0x80000;
688         tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - low);
689         ofs = low;
691         /* If we were already given an index register, add it in.  */
692         if (index != TCG_REG_NONE) {
693             tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
694         }
695         index = TCG_TMP0;
696     }
698     if (opc_rx && ofs >= 0 && ofs < 0x1000) {
699         tcg_out_insn_RX(s, opc_rx, data, base, index, ofs);
700     } else {
701         tcg_out_insn_RXY(s, opc_rxy, data, base, index, ofs);
702     }
706 /* load data without address translation or endianness conversion */
707 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
708                               TCGReg base, intptr_t ofs)
710     if (type == TCG_TYPE_I32) {
711         tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs);
712     } else {
713         tcg_out_mem(s, 0, RXY_LG, data, base, TCG_REG_NONE, ofs);
714     }
717 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
718                               TCGReg base, intptr_t ofs)
720     if (type == TCG_TYPE_I32) {
721         tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs);
722     } else {
723         tcg_out_mem(s, 0, RXY_STG, data, base, TCG_REG_NONE, ofs);
724     }
727 static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
728                                TCGReg base, intptr_t ofs)
730     return false;
733 /* load data from an absolute host address */
734 static void tcg_out_ld_abs(TCGContext *s, TCGType type,
735                            TCGReg dest, const void *abs)
737     intptr_t addr = (intptr_t)abs;
739     if ((s390_facilities & FACILITY_GEN_INST_EXT) && !(addr & 1)) {
740         ptrdiff_t disp = tcg_pcrel_diff(s, abs) >> 1;
741         if (disp == (int32_t)disp) {
742             if (type == TCG_TYPE_I32) {
743                 tcg_out_insn(s, RIL, LRL, dest, disp);
744             } else {
745                 tcg_out_insn(s, RIL, LGRL, dest, disp);
746             }
747             return;
748         }
749     }
750     if (USE_REG_TB) {
751         ptrdiff_t disp = tcg_tbrel_diff(s, abs);
752         if (disp == sextract64(disp, 0, 20)) {
753             tcg_out_ld(s, type, dest, TCG_REG_TB, disp);
754             return;
755         }
756     }
758     tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
759     tcg_out_ld(s, type, dest, dest, addr & 0xffff);
762 static inline void tcg_out_risbg(TCGContext *s, TCGReg dest, TCGReg src,
763                                  int msb, int lsb, int ofs, int z)
765     /* Format RIE-f */
766     tcg_out16(s, (RIE_RISBG & 0xff00) | (dest << 4) | src);
767     tcg_out16(s, (msb << 8) | (z << 7) | lsb);
768     tcg_out16(s, (ofs << 8) | (RIE_RISBG & 0xff));
771 static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
773     if (s390_facilities & FACILITY_EXT_IMM) {
774         tcg_out_insn(s, RRE, LGBR, dest, src);
775         return;
776     }
778     if (type == TCG_TYPE_I32) {
779         if (dest == src) {
780             tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 24);
781         } else {
782             tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 24);
783         }
784         tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 24);
785     } else {
786         tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 56);
787         tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 56);
788     }
791 static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
793     if (s390_facilities & FACILITY_EXT_IMM) {
794         tcg_out_insn(s, RRE, LLGCR, dest, src);
795         return;
796     }
798     if (dest == src) {
799         tcg_out_movi(s, type, TCG_TMP0, 0xff);
800         src = TCG_TMP0;
801     } else {
802         tcg_out_movi(s, type, dest, 0xff);
803     }
804     if (type == TCG_TYPE_I32) {
805         tcg_out_insn(s, RR, NR, dest, src);
806     } else {
807         tcg_out_insn(s, RRE, NGR, dest, src);
808     }
811 static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
813     if (s390_facilities & FACILITY_EXT_IMM) {
814         tcg_out_insn(s, RRE, LGHR, dest, src);
815         return;
816     }
818     if (type == TCG_TYPE_I32) {
819         if (dest == src) {
820             tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 16);
821         } else {
822             tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 16);
823         }
824         tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 16);
825     } else {
826         tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 48);
827         tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 48);
828     }
831 static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
833     if (s390_facilities & FACILITY_EXT_IMM) {
834         tcg_out_insn(s, RRE, LLGHR, dest, src);
835         return;
836     }
838     if (dest == src) {
839         tcg_out_movi(s, type, TCG_TMP0, 0xffff);
840         src = TCG_TMP0;
841     } else {
842         tcg_out_movi(s, type, dest, 0xffff);
843     }
844     if (type == TCG_TYPE_I32) {
845         tcg_out_insn(s, RR, NR, dest, src);
846     } else {
847         tcg_out_insn(s, RRE, NGR, dest, src);
848     }
851 static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
853     tcg_out_insn(s, RRE, LGFR, dest, src);
856 static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
858     tcg_out_insn(s, RRE, LLGFR, dest, src);
861 /* Accept bit patterns like these:
862     0....01....1
863     1....10....0
864     1..10..01..1
865     0..01..10..0
866    Copied from gcc sources.  */
867 static inline bool risbg_mask(uint64_t c)
869     uint64_t lsb;
870     /* We don't change the number of transitions by inverting,
871        so make sure we start with the LSB zero.  */
872     if (c & 1) {
873         c = ~c;
874     }
875     /* Reject all zeros or all ones.  */
876     if (c == 0) {
877         return false;
878     }
879     /* Find the first transition.  */
880     lsb = c & -c;
881     /* Invert to look for a second transition.  */
882     c = ~c;
883     /* Erase the first transition.  */
884     c &= -lsb;
885     /* Find the second transition, if any.  */
886     lsb = c & -c;
887     /* Match if all the bits are 1's, or if c is zero.  */
888     return c == -lsb;
891 static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val)
893     int msb, lsb;
894     if ((val & 0x8000000000000001ull) == 0x8000000000000001ull) {
895         /* Achieve wraparound by swapping msb and lsb.  */
896         msb = 64 - ctz64(~val);
897         lsb = clz64(~val) - 1;
898     } else {
899         msb = clz64(val);
900         lsb = 63 - ctz64(val);
901     }
902     tcg_out_risbg(s, out, in, msb, lsb, 0, 1);
905 static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
907     static const S390Opcode ni_insns[4] = {
908         RI_NILL, RI_NILH, RI_NIHL, RI_NIHH
909     };
910     static const S390Opcode nif_insns[2] = {
911         RIL_NILF, RIL_NIHF
912     };
913     uint64_t valid = (type == TCG_TYPE_I32 ? 0xffffffffull : -1ull);
914     int i;
916     /* Look for the zero-extensions.  */
917     if ((val & valid) == 0xffffffff) {
918         tgen_ext32u(s, dest, dest);
919         return;
920     }
921     if (s390_facilities & FACILITY_EXT_IMM) {
922         if ((val & valid) == 0xff) {
923             tgen_ext8u(s, TCG_TYPE_I64, dest, dest);
924             return;
925         }
926         if ((val & valid) == 0xffff) {
927             tgen_ext16u(s, TCG_TYPE_I64, dest, dest);
928             return;
929         }
930     }
932     /* Try all 32-bit insns that can perform it in one go.  */
933     for (i = 0; i < 4; i++) {
934         tcg_target_ulong mask = ~(0xffffull << i*16);
935         if (((val | ~valid) & mask) == mask) {
936             tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
937             return;
938         }
939     }
941     /* Try all 48-bit insns that can perform it in one go.  */
942     if (s390_facilities & FACILITY_EXT_IMM) {
943         for (i = 0; i < 2; i++) {
944             tcg_target_ulong mask = ~(0xffffffffull << i*32);
945             if (((val | ~valid) & mask) == mask) {
946                 tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
947                 return;
948             }
949         }
950     }
951     if ((s390_facilities & FACILITY_GEN_INST_EXT) && risbg_mask(val)) {
952         tgen_andi_risbg(s, dest, dest, val);
953         return;
954     }
956     /* Use the constant pool if USE_REG_TB, but not for small constants.  */
957     if (USE_REG_TB) {
958         if (!maybe_out_small_movi(s, type, TCG_TMP0, val)) {
959             tcg_out_insn(s, RXY, NG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
960             new_pool_label(s, val & valid, R_390_20, s->code_ptr - 2,
961                            tcg_tbrel_diff(s, NULL));
962             return;
963         }
964     } else {
965         tcg_out_movi(s, type, TCG_TMP0, val);
966     }
967     if (type == TCG_TYPE_I32) {
968         tcg_out_insn(s, RR, NR, dest, TCG_TMP0);
969     } else {
970         tcg_out_insn(s, RRE, NGR, dest, TCG_TMP0);
971     }
974 static void tgen_ori(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
976     static const S390Opcode oi_insns[4] = {
977         RI_OILL, RI_OILH, RI_OIHL, RI_OIHH
978     };
979     static const S390Opcode oif_insns[2] = {
980         RIL_OILF, RIL_OIHF
981     };
983     int i;
985     /* Look for no-op.  */
986     if (unlikely(val == 0)) {
987         return;
988     }
990     /* Try all 32-bit insns that can perform it in one go.  */
991     for (i = 0; i < 4; i++) {
992         tcg_target_ulong mask = (0xffffull << i*16);
993         if ((val & mask) != 0 && (val & ~mask) == 0) {
994             tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
995             return;
996         }
997     }
999     /* Try all 48-bit insns that can perform it in one go.  */
1000     if (s390_facilities & FACILITY_EXT_IMM) {
1001         for (i = 0; i < 2; i++) {
1002             tcg_target_ulong mask = (0xffffffffull << i*32);
1003             if ((val & mask) != 0 && (val & ~mask) == 0) {
1004                 tcg_out_insn_RIL(s, oif_insns[i], dest, val >> i*32);
1005                 return;
1006             }
1007         }
1008     }
1010     /* Use the constant pool if USE_REG_TB, but not for small constants.  */
1011     if (maybe_out_small_movi(s, type, TCG_TMP0, val)) {
1012         if (type == TCG_TYPE_I32) {
1013             tcg_out_insn(s, RR, OR, dest, TCG_TMP0);
1014         } else {
1015             tcg_out_insn(s, RRE, OGR, dest, TCG_TMP0);
1016         }
1017     } else if (USE_REG_TB) {
1018         tcg_out_insn(s, RXY, OG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
1019         new_pool_label(s, val, R_390_20, s->code_ptr - 2,
1020                        tcg_tbrel_diff(s, NULL));
1021     } else {
1022         /* Perform the OR via sequential modifications to the high and
1023            low parts.  Do this via recursion to handle 16-bit vs 32-bit
1024            masks in each half.  */
1025         tcg_debug_assert(s390_facilities & FACILITY_EXT_IMM);
1026         tgen_ori(s, type, dest, val & 0x00000000ffffffffull);
1027         tgen_ori(s, type, dest, val & 0xffffffff00000000ull);
1028     }
1031 static void tgen_xori(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
1033     /* Try all 48-bit insns that can perform it in one go.  */
1034     if (s390_facilities & FACILITY_EXT_IMM) {
1035         if ((val & 0xffffffff00000000ull) == 0) {
1036             tcg_out_insn(s, RIL, XILF, dest, val);
1037             return;
1038         }
1039         if ((val & 0x00000000ffffffffull) == 0) {
1040             tcg_out_insn(s, RIL, XIHF, dest, val >> 32);
1041             return;
1042         }
1043     }
1045     /* Use the constant pool if USE_REG_TB, but not for small constants.  */
1046     if (maybe_out_small_movi(s, type, TCG_TMP0, val)) {
1047         if (type == TCG_TYPE_I32) {
1048             tcg_out_insn(s, RR, XR, dest, TCG_TMP0);
1049         } else {
1050             tcg_out_insn(s, RRE, XGR, dest, TCG_TMP0);
1051         }
1052     } else if (USE_REG_TB) {
1053         tcg_out_insn(s, RXY, XG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
1054         new_pool_label(s, val, R_390_20, s->code_ptr - 2,
1055                        tcg_tbrel_diff(s, NULL));
1056     } else {
1057         /* Perform the xor by parts.  */
1058         tcg_debug_assert(s390_facilities & FACILITY_EXT_IMM);
1059         if (val & 0xffffffff) {
1060             tcg_out_insn(s, RIL, XILF, dest, val);
1061         }
1062         if (val > 0xffffffff) {
1063             tcg_out_insn(s, RIL, XIHF, dest, val >> 32);
1064         }
1065     }
1068 static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
1069                     TCGArg c2, bool c2const, bool need_carry)
1071     bool is_unsigned = is_unsigned_cond(c);
1072     S390Opcode op;
1074     if (c2const) {
1075         if (c2 == 0) {
1076             if (!(is_unsigned && need_carry)) {
1077                 if (type == TCG_TYPE_I32) {
1078                     tcg_out_insn(s, RR, LTR, r1, r1);
1079                 } else {
1080                     tcg_out_insn(s, RRE, LTGR, r1, r1);
1081                 }
1082                 return tcg_cond_to_ltr_cond[c];
1083             }
1084         }
1086         if (!is_unsigned && c2 == (int16_t)c2) {
1087             op = (type == TCG_TYPE_I32 ? RI_CHI : RI_CGHI);
1088             tcg_out_insn_RI(s, op, r1, c2);
1089             goto exit;
1090         }
1092         if (s390_facilities & FACILITY_EXT_IMM) {
1093             if (type == TCG_TYPE_I32) {
1094                 op = (is_unsigned ? RIL_CLFI : RIL_CFI);
1095                 tcg_out_insn_RIL(s, op, r1, c2);
1096                 goto exit;
1097             } else if (c2 == (is_unsigned ? (uint32_t)c2 : (int32_t)c2)) {
1098                 op = (is_unsigned ? RIL_CLGFI : RIL_CGFI);
1099                 tcg_out_insn_RIL(s, op, r1, c2);
1100                 goto exit;
1101             }
1102         }
1104         /* Use the constant pool, but not for small constants.  */
1105         if (maybe_out_small_movi(s, type, TCG_TMP0, c2)) {
1106             c2 = TCG_TMP0;
1107             /* fall through to reg-reg */
1108         } else if (USE_REG_TB) {
1109             if (type == TCG_TYPE_I32) {
1110                 op = (is_unsigned ? RXY_CLY : RXY_CY);
1111                 tcg_out_insn_RXY(s, op, r1, TCG_REG_TB, TCG_REG_NONE, 0);
1112                 new_pool_label(s, (uint32_t)c2, R_390_20, s->code_ptr - 2,
1113                                4 - tcg_tbrel_diff(s, NULL));
1114             } else {
1115                 op = (is_unsigned ? RXY_CLG : RXY_CG);
1116                 tcg_out_insn_RXY(s, op, r1, TCG_REG_TB, TCG_REG_NONE, 0);
1117                 new_pool_label(s, c2, R_390_20, s->code_ptr - 2,
1118                                tcg_tbrel_diff(s, NULL));
1119             }
1120             goto exit;
1121         } else {
1122             if (type == TCG_TYPE_I32) {
1123                 op = (is_unsigned ? RIL_CLRL : RIL_CRL);
1124                 tcg_out_insn_RIL(s, op, r1, 0);
1125                 new_pool_label(s, (uint32_t)c2, R_390_PC32DBL,
1126                                s->code_ptr - 2, 2 + 4);
1127             } else {
1128                 op = (is_unsigned ? RIL_CLGRL : RIL_CGRL);
1129                 tcg_out_insn_RIL(s, op, r1, 0);
1130                 new_pool_label(s, c2, R_390_PC32DBL, s->code_ptr - 2, 2);
1131             }
1132             goto exit;
1133         }
1134     }
1136     if (type == TCG_TYPE_I32) {
1137         op = (is_unsigned ? RR_CLR : RR_CR);
1138         tcg_out_insn_RR(s, op, r1, c2);
1139     } else {
1140         op = (is_unsigned ? RRE_CLGR : RRE_CGR);
1141         tcg_out_insn_RRE(s, op, r1, c2);
1142     }
1144  exit:
1145     return tcg_cond_to_s390_cond[c];
1148 static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
1149                          TCGReg dest, TCGReg c1, TCGArg c2, int c2const)
1151     int cc;
1152     bool have_loc;
1154     /* With LOC2, we can always emit the minimum 3 insns.  */
1155     if (s390_facilities & FACILITY_LOAD_ON_COND2) {
1156         /* Emit: d = 0, d = (cc ? 1 : d).  */
1157         cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1158         tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1159         tcg_out_insn(s, RIE, LOCGHI, dest, 1, cc);
1160         return;
1161     }
1163     have_loc = (s390_facilities & FACILITY_LOAD_ON_COND) != 0;
1165     /* For HAVE_LOC, only the paths through GTU/GT/LEU/LE are smaller.  */
1166  restart:
1167     switch (cond) {
1168     case TCG_COND_NE:
1169         /* X != 0 is X > 0.  */
1170         if (c2const && c2 == 0) {
1171             cond = TCG_COND_GTU;
1172         } else {
1173             break;
1174         }
1175         /* fallthru */
1177     case TCG_COND_GTU:
1178     case TCG_COND_GT:
1179         /* The result of a compare has CC=2 for GT and CC=3 unused.
1180            ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit.  */
1181         tgen_cmp(s, type, cond, c1, c2, c2const, true);
1182         tcg_out_movi(s, type, dest, 0);
1183         tcg_out_insn(s, RRE, ALCGR, dest, dest);
1184         return;
1186     case TCG_COND_EQ:
1187         /* X == 0 is X <= 0.  */
1188         if (c2const && c2 == 0) {
1189             cond = TCG_COND_LEU;
1190         } else {
1191             break;
1192         }
1193         /* fallthru */
1195     case TCG_COND_LEU:
1196     case TCG_COND_LE:
1197         /* As above, but we're looking for borrow, or !carry.
1198            The second insn computes d - d - borrow, or -1 for true
1199            and 0 for false.  So we must mask to 1 bit afterward.  */
1200         tgen_cmp(s, type, cond, c1, c2, c2const, true);
1201         tcg_out_insn(s, RRE, SLBGR, dest, dest);
1202         tgen_andi(s, type, dest, 1);
1203         return;
1205     case TCG_COND_GEU:
1206     case TCG_COND_LTU:
1207     case TCG_COND_LT:
1208     case TCG_COND_GE:
1209         /* Swap operands so that we can use LEU/GTU/GT/LE.  */
1210         if (c2const) {
1211             if (have_loc) {
1212                 break;
1213             }
1214             tcg_out_movi(s, type, TCG_TMP0, c2);
1215             c2 = c1;
1216             c2const = 0;
1217             c1 = TCG_TMP0;
1218         } else {
1219             TCGReg t = c1;
1220             c1 = c2;
1221             c2 = t;
1222         }
1223         cond = tcg_swap_cond(cond);
1224         goto restart;
1226     default:
1227         g_assert_not_reached();
1228     }
1230     cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1231     if (have_loc) {
1232         /* Emit: d = 0, t = 1, d = (cc ? t : d).  */
1233         tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1234         tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 1);
1235         tcg_out_insn(s, RRF, LOCGR, dest, TCG_TMP0, cc);
1236     } else {
1237         /* Emit: d = 1; if (cc) goto over; d = 0; over:  */
1238         tcg_out_movi(s, type, dest, 1);
1239         tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1240         tcg_out_movi(s, type, dest, 0);
1241     }
1244 static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest,
1245                          TCGReg c1, TCGArg c2, int c2const,
1246                          TCGArg v3, int v3const)
1248     int cc;
1249     if (s390_facilities & FACILITY_LOAD_ON_COND) {
1250         cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1251         if (v3const) {
1252             tcg_out_insn(s, RIE, LOCGHI, dest, v3, cc);
1253         } else {
1254             tcg_out_insn(s, RRF, LOCGR, dest, v3, cc);
1255         }
1256     } else {
1257         c = tcg_invert_cond(c);
1258         cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1260         /* Emit: if (cc) goto over; dest = r3; over:  */
1261         tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1262         tcg_out_insn(s, RRE, LGR, dest, v3);
1263     }
1266 static void tgen_clz(TCGContext *s, TCGReg dest, TCGReg a1,
1267                      TCGArg a2, int a2const)
1269     /* Since this sets both R and R+1, we have no choice but to store the
1270        result into R0, allowing R1 == TCG_TMP0 to be clobbered as well.  */
1271     QEMU_BUILD_BUG_ON(TCG_TMP0 != TCG_REG_R1);
1272     tcg_out_insn(s, RRE, FLOGR, TCG_REG_R0, a1);
1274     if (a2const && a2 == 64) {
1275         tcg_out_mov(s, TCG_TYPE_I64, dest, TCG_REG_R0);
1276     } else {
1277         if (a2const) {
1278             tcg_out_movi(s, TCG_TYPE_I64, dest, a2);
1279         } else {
1280             tcg_out_mov(s, TCG_TYPE_I64, dest, a2);
1281         }
1282         if (s390_facilities & FACILITY_LOAD_ON_COND) {
1283             /* Emit: if (one bit found) dest = r0.  */
1284             tcg_out_insn(s, RRF, LOCGR, dest, TCG_REG_R0, 2);
1285         } else {
1286             /* Emit: if (no one bit found) goto over; dest = r0; over:  */
1287             tcg_out_insn(s, RI, BRC, 8, (4 + 4) >> 1);
1288             tcg_out_insn(s, RRE, LGR, dest, TCG_REG_R0);
1289         }
1290     }
1293 static void tgen_deposit(TCGContext *s, TCGReg dest, TCGReg src,
1294                          int ofs, int len, int z)
1296     int lsb = (63 - ofs);
1297     int msb = lsb - (len - 1);
1298     tcg_out_risbg(s, dest, src, msb, lsb, ofs, z);
1301 static void tgen_extract(TCGContext *s, TCGReg dest, TCGReg src,
1302                          int ofs, int len)
1304     tcg_out_risbg(s, dest, src, 64 - len, 63, 64 - ofs, 1);
1307 static void tgen_gotoi(TCGContext *s, int cc, const tcg_insn_unit *dest)
1309     ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
1310     if (off == (int16_t)off) {
1311         tcg_out_insn(s, RI, BRC, cc, off);
1312     } else if (off == (int32_t)off) {
1313         tcg_out_insn(s, RIL, BRCL, cc, off);
1314     } else {
1315         tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1316         tcg_out_insn(s, RR, BCR, cc, TCG_TMP0);
1317     }
1320 static void tgen_branch(TCGContext *s, int cc, TCGLabel *l)
1322     if (l->has_value) {
1323         tgen_gotoi(s, cc, l->u.value_ptr);
1324     } else if (USE_LONG_BRANCHES) {
1325         tcg_out16(s, RIL_BRCL | (cc << 4));
1326         tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, l, 2);
1327         s->code_ptr += 2;
1328     } else {
1329         tcg_out16(s, RI_BRC | (cc << 4));
1330         tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, l, 2);
1331         s->code_ptr += 1;
1332     }
1335 static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
1336                                 TCGReg r1, TCGReg r2, TCGLabel *l)
1338     tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
1339     tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
1340     tcg_out16(s, 0);
1341     tcg_out16(s, cc << 12 | (opc & 0xff));
1344 static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
1345                                     TCGReg r1, int i2, TCGLabel *l)
1347     tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
1348     tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
1349     tcg_out16(s, 0);
1350     tcg_out16(s, (i2 << 8) | (opc & 0xff));
1353 static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
1354                         TCGReg r1, TCGArg c2, int c2const, TCGLabel *l)
1356     int cc;
1358     if (s390_facilities & FACILITY_GEN_INST_EXT) {
1359         bool is_unsigned = is_unsigned_cond(c);
1360         bool in_range;
1361         S390Opcode opc;
1363         cc = tcg_cond_to_s390_cond[c];
1365         if (!c2const) {
1366             opc = (type == TCG_TYPE_I32
1367                    ? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
1368                    : (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
1369             tgen_compare_branch(s, opc, cc, r1, c2, l);
1370             return;
1371         }
1373         /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1374            If the immediate we've been given does not fit that range, we'll
1375            fall back to separate compare and branch instructions using the
1376            larger comparison range afforded by COMPARE IMMEDIATE.  */
1377         if (type == TCG_TYPE_I32) {
1378             if (is_unsigned) {
1379                 opc = RIE_CLIJ;
1380                 in_range = (uint32_t)c2 == (uint8_t)c2;
1381             } else {
1382                 opc = RIE_CIJ;
1383                 in_range = (int32_t)c2 == (int8_t)c2;
1384             }
1385         } else {
1386             if (is_unsigned) {
1387                 opc = RIE_CLGIJ;
1388                 in_range = (uint64_t)c2 == (uint8_t)c2;
1389             } else {
1390                 opc = RIE_CGIJ;
1391                 in_range = (int64_t)c2 == (int8_t)c2;
1392             }
1393         }
1394         if (in_range) {
1395             tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
1396             return;
1397         }
1398     }
1400     cc = tgen_cmp(s, type, c, r1, c2, c2const, false);
1401     tgen_branch(s, cc, l);
1404 static void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest)
1406     ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
1407     if (off == (int32_t)off) {
1408         tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
1409     } else {
1410         tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1411         tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_TMP0);
1412     }
1415 static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data,
1416                                    TCGReg base, TCGReg index, int disp)
1418     switch (opc & (MO_SSIZE | MO_BSWAP)) {
1419     case MO_UB:
1420         tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
1421         break;
1422     case MO_SB:
1423         tcg_out_insn(s, RXY, LGB, data, base, index, disp);
1424         break;
1426     case MO_UW | MO_BSWAP:
1427         /* swapped unsigned halfword load with upper bits zeroed */
1428         tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1429         tgen_ext16u(s, TCG_TYPE_I64, data, data);
1430         break;
1431     case MO_UW:
1432         tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
1433         break;
1435     case MO_SW | MO_BSWAP:
1436         /* swapped sign-extended halfword load */
1437         tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1438         tgen_ext16s(s, TCG_TYPE_I64, data, data);
1439         break;
1440     case MO_SW:
1441         tcg_out_insn(s, RXY, LGH, data, base, index, disp);
1442         break;
1444     case MO_UL | MO_BSWAP:
1445         /* swapped unsigned int load with upper bits zeroed */
1446         tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1447         tgen_ext32u(s, data, data);
1448         break;
1449     case MO_UL:
1450         tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
1451         break;
1453     case MO_SL | MO_BSWAP:
1454         /* swapped sign-extended int load */
1455         tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1456         tgen_ext32s(s, data, data);
1457         break;
1458     case MO_SL:
1459         tcg_out_insn(s, RXY, LGF, data, base, index, disp);
1460         break;
1462     case MO_Q | MO_BSWAP:
1463         tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
1464         break;
1465     case MO_Q:
1466         tcg_out_insn(s, RXY, LG, data, base, index, disp);
1467         break;
1469     default:
1470         tcg_abort();
1471     }
1474 static void tcg_out_qemu_st_direct(TCGContext *s, MemOp opc, TCGReg data,
1475                                    TCGReg base, TCGReg index, int disp)
1477     switch (opc & (MO_SIZE | MO_BSWAP)) {
1478     case MO_UB:
1479         if (disp >= 0 && disp < 0x1000) {
1480             tcg_out_insn(s, RX, STC, data, base, index, disp);
1481         } else {
1482             tcg_out_insn(s, RXY, STCY, data, base, index, disp);
1483         }
1484         break;
1486     case MO_UW | MO_BSWAP:
1487         tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
1488         break;
1489     case MO_UW:
1490         if (disp >= 0 && disp < 0x1000) {
1491             tcg_out_insn(s, RX, STH, data, base, index, disp);
1492         } else {
1493             tcg_out_insn(s, RXY, STHY, data, base, index, disp);
1494         }
1495         break;
1497     case MO_UL | MO_BSWAP:
1498         tcg_out_insn(s, RXY, STRV, data, base, index, disp);
1499         break;
1500     case MO_UL:
1501         if (disp >= 0 && disp < 0x1000) {
1502             tcg_out_insn(s, RX, ST, data, base, index, disp);
1503         } else {
1504             tcg_out_insn(s, RXY, STY, data, base, index, disp);
1505         }
1506         break;
1508     case MO_Q | MO_BSWAP:
1509         tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
1510         break;
1511     case MO_Q:
1512         tcg_out_insn(s, RXY, STG, data, base, index, disp);
1513         break;
1515     default:
1516         tcg_abort();
1517     }
1520 #if defined(CONFIG_SOFTMMU)
1521 #include "../tcg-ldst.c.inc"
1523 /* We're expecting to use a 20-bit negative offset on the tlb memory ops.  */
1524 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
1525 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 19));
1527 /* Load and compare a TLB entry, leaving the flags set.  Loads the TLB
1528    addend into R2.  Returns a register with the santitized guest address.  */
1529 static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, MemOp opc,
1530                                int mem_index, bool is_ld)
1532     unsigned s_bits = opc & MO_SIZE;
1533     unsigned a_bits = get_alignment_bits(opc);
1534     unsigned s_mask = (1 << s_bits) - 1;
1535     unsigned a_mask = (1 << a_bits) - 1;
1536     int fast_off = TLB_MASK_TABLE_OFS(mem_index);
1537     int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
1538     int table_off = fast_off + offsetof(CPUTLBDescFast, table);
1539     int ofs, a_off;
1540     uint64_t tlb_mask;
1542     tcg_out_sh64(s, RSY_SRLG, TCG_REG_R2, addr_reg, TCG_REG_NONE,
1543                  TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1544     tcg_out_insn(s, RXY, NG, TCG_REG_R2, TCG_AREG0, TCG_REG_NONE, mask_off);
1545     tcg_out_insn(s, RXY, AG, TCG_REG_R2, TCG_AREG0, TCG_REG_NONE, table_off);
1547     /* For aligned accesses, we check the first byte and include the alignment
1548        bits within the address.  For unaligned access, we check that we don't
1549        cross pages using the address of the last byte of the access.  */
1550     a_off = (a_bits >= s_bits ? 0 : s_mask - a_mask);
1551     tlb_mask = (uint64_t)TARGET_PAGE_MASK | a_mask;
1552     if ((s390_facilities & FACILITY_GEN_INST_EXT) && a_off == 0) {
1553         tgen_andi_risbg(s, TCG_REG_R3, addr_reg, tlb_mask);
1554     } else {
1555         tcg_out_insn(s, RX, LA, TCG_REG_R3, addr_reg, TCG_REG_NONE, a_off);
1556         tgen_andi(s, TCG_TYPE_TL, TCG_REG_R3, tlb_mask);
1557     }
1559     if (is_ld) {
1560         ofs = offsetof(CPUTLBEntry, addr_read);
1561     } else {
1562         ofs = offsetof(CPUTLBEntry, addr_write);
1563     }
1564     if (TARGET_LONG_BITS == 32) {
1565         tcg_out_insn(s, RX, C, TCG_REG_R3, TCG_REG_R2, TCG_REG_NONE, ofs);
1566     } else {
1567         tcg_out_insn(s, RXY, CG, TCG_REG_R3, TCG_REG_R2, TCG_REG_NONE, ofs);
1568     }
1570     tcg_out_insn(s, RXY, LG, TCG_REG_R2, TCG_REG_R2, TCG_REG_NONE,
1571                  offsetof(CPUTLBEntry, addend));
1573     if (TARGET_LONG_BITS == 32) {
1574         tgen_ext32u(s, TCG_REG_R3, addr_reg);
1575         return TCG_REG_R3;
1576     }
1577     return addr_reg;
1580 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
1581                                 TCGReg data, TCGReg addr,
1582                                 tcg_insn_unit *raddr, tcg_insn_unit *label_ptr)
1584     TCGLabelQemuLdst *label = new_ldst_label(s);
1586     label->is_ld = is_ld;
1587     label->oi = oi;
1588     label->datalo_reg = data;
1589     label->addrlo_reg = addr;
1590     label->raddr = tcg_splitwx_to_rx(raddr);
1591     label->label_ptr[0] = label_ptr;
1594 static bool tcg_out_qemu_ld_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     MemOp opc = get_memop(oi);
1601     if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
1602                      (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
1603         return false;
1604     }
1606     tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1607     if (TARGET_LONG_BITS == 64) {
1608         tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
1609     }
1610     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, oi);
1611     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R5, (uintptr_t)lb->raddr);
1612     tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)]);
1613     tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_R2);
1615     tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1616     return true;
1619 static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1621     TCGReg addr_reg = lb->addrlo_reg;
1622     TCGReg data_reg = lb->datalo_reg;
1623     TCGMemOpIdx oi = lb->oi;
1624     MemOp opc = get_memop(oi);
1626     if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
1627                      (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
1628         return false;
1629     }
1631     tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1632     if (TARGET_LONG_BITS == 64) {
1633         tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
1634     }
1635     switch (opc & MO_SIZE) {
1636     case MO_UB:
1637         tgen_ext8u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1638         break;
1639     case MO_UW:
1640         tgen_ext16u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1641         break;
1642     case MO_UL:
1643         tgen_ext32u(s, TCG_REG_R4, data_reg);
1644         break;
1645     case MO_Q:
1646         tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1647         break;
1648     default:
1649         tcg_abort();
1650     }
1651     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, oi);
1652     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R6, (uintptr_t)lb->raddr);
1653     tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1655     tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1656     return true;
1658 #else
1659 static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
1660                                   TCGReg *index_reg, tcg_target_long *disp)
1662     if (TARGET_LONG_BITS == 32) {
1663         tgen_ext32u(s, TCG_TMP0, *addr_reg);
1664         *addr_reg = TCG_TMP0;
1665     }
1666     if (guest_base < 0x80000) {
1667         *index_reg = TCG_REG_NONE;
1668         *disp = guest_base;
1669     } else {
1670         *index_reg = TCG_GUEST_BASE_REG;
1671         *disp = 0;
1672     }
1674 #endif /* CONFIG_SOFTMMU */
1676 static void tcg_out_qemu_ld(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
1677                             TCGMemOpIdx oi)
1679     MemOp opc = get_memop(oi);
1680 #ifdef CONFIG_SOFTMMU
1681     unsigned mem_index = get_mmuidx(oi);
1682     tcg_insn_unit *label_ptr;
1683     TCGReg base_reg;
1685     base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 1);
1687     tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
1688     label_ptr = s->code_ptr;
1689     s->code_ptr += 1;
1691     tcg_out_qemu_ld_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
1693     add_qemu_ldst_label(s, 1, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
1694 #else
1695     TCGReg index_reg;
1696     tcg_target_long disp;
1698     tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1699     tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1700 #endif
1703 static void tcg_out_qemu_st(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
1704                             TCGMemOpIdx oi)
1706     MemOp opc = get_memop(oi);
1707 #ifdef CONFIG_SOFTMMU
1708     unsigned mem_index = get_mmuidx(oi);
1709     tcg_insn_unit *label_ptr;
1710     TCGReg base_reg;
1712     base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 0);
1714     tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
1715     label_ptr = s->code_ptr;
1716     s->code_ptr += 1;
1718     tcg_out_qemu_st_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
1720     add_qemu_ldst_label(s, 0, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
1721 #else
1722     TCGReg index_reg;
1723     tcg_target_long disp;
1725     tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1726     tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1727 #endif
1730 # define OP_32_64(x) \
1731         case glue(glue(INDEX_op_,x),_i32): \
1732         case glue(glue(INDEX_op_,x),_i64)
1734 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1735                 const TCGArg *args, const int *const_args)
1737     S390Opcode op, op2;
1738     TCGArg a0, a1, a2;
1740     switch (opc) {
1741     case INDEX_op_exit_tb:
1742         /* Reuse the zeroing that exists for goto_ptr.  */
1743         a0 = args[0];
1744         if (a0 == 0) {
1745             tgen_gotoi(s, S390_CC_ALWAYS, tcg_code_gen_epilogue);
1746         } else {
1747             tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, a0);
1748             tgen_gotoi(s, S390_CC_ALWAYS, tb_ret_addr);
1749         }
1750         break;
1752     case INDEX_op_goto_tb:
1753         a0 = args[0];
1754         if (s->tb_jmp_insn_offset) {
1755             /*
1756              * branch displacement must be aligned for atomic patching;
1757              * see if we need to add extra nop before branch
1758              */
1759             if (!QEMU_PTR_IS_ALIGNED(s->code_ptr + 1, 4)) {
1760                 tcg_out16(s, NOP);
1761             }
1762             tcg_debug_assert(!USE_REG_TB);
1763             tcg_out16(s, RIL_BRCL | (S390_CC_ALWAYS << 4));
1764             s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
1765             s->code_ptr += 2;
1766         } else {
1767             /* load address stored at s->tb_jmp_target_addr + a0 */
1768             tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_REG_TB,
1769                            tcg_splitwx_to_rx(s->tb_jmp_target_addr + a0));
1770             /* and go there */
1771             tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_TB);
1772         }
1773         set_jmp_reset_offset(s, a0);
1775         /* For the unlinked path of goto_tb, we need to reset
1776            TCG_REG_TB to the beginning of this TB.  */
1777         if (USE_REG_TB) {
1778             int ofs = -tcg_current_code_size(s);
1779             /* All TB are restricted to 64KiB by unwind info. */
1780             tcg_debug_assert(ofs == sextract64(ofs, 0, 20));
1781             tcg_out_insn(s, RXY, LAY, TCG_REG_TB,
1782                          TCG_REG_TB, TCG_REG_NONE, ofs);
1783         }
1784         break;
1786     case INDEX_op_goto_ptr:
1787         a0 = args[0];
1788         if (USE_REG_TB) {
1789             tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, a0);
1790         }
1791         tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, a0);
1792         break;
1794     OP_32_64(ld8u):
1795         /* ??? LLC (RXY format) is only present with the extended-immediate
1796            facility, whereas LLGC is always present.  */
1797         tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
1798         break;
1800     OP_32_64(ld8s):
1801         /* ??? LB is no smaller than LGB, so no point to using it.  */
1802         tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
1803         break;
1805     OP_32_64(ld16u):
1806         /* ??? LLH (RXY format) is only present with the extended-immediate
1807            facility, whereas LLGH is always present.  */
1808         tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
1809         break;
1811     case INDEX_op_ld16s_i32:
1812         tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
1813         break;
1815     case INDEX_op_ld_i32:
1816         tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1817         break;
1819     OP_32_64(st8):
1820         tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
1821                     TCG_REG_NONE, args[2]);
1822         break;
1824     OP_32_64(st16):
1825         tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
1826                     TCG_REG_NONE, args[2]);
1827         break;
1829     case INDEX_op_st_i32:
1830         tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1831         break;
1833     case INDEX_op_add_i32:
1834         a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1835         if (const_args[2]) {
1836         do_addi_32:
1837             if (a0 == a1) {
1838                 if (a2 == (int16_t)a2) {
1839                     tcg_out_insn(s, RI, AHI, a0, a2);
1840                     break;
1841                 }
1842                 if (s390_facilities & FACILITY_EXT_IMM) {
1843                     tcg_out_insn(s, RIL, AFI, a0, a2);
1844                     break;
1845                 }
1846             }
1847             tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
1848         } else if (a0 == a1) {
1849             tcg_out_insn(s, RR, AR, a0, a2);
1850         } else {
1851             tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
1852         }
1853         break;
1854     case INDEX_op_sub_i32:
1855         a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1856         if (const_args[2]) {
1857             a2 = -a2;
1858             goto do_addi_32;
1859         } else if (a0 == a1) {
1860             tcg_out_insn(s, RR, SR, a0, a2);
1861         } else {
1862             tcg_out_insn(s, RRF, SRK, a0, a1, a2);
1863         }
1864         break;
1866     case INDEX_op_and_i32:
1867         a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1868         if (const_args[2]) {
1869             tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1870             tgen_andi(s, TCG_TYPE_I32, a0, a2);
1871         } else if (a0 == a1) {
1872             tcg_out_insn(s, RR, NR, a0, a2);
1873         } else {
1874             tcg_out_insn(s, RRF, NRK, a0, a1, a2);
1875         }
1876         break;
1877     case INDEX_op_or_i32:
1878         a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1879         if (const_args[2]) {
1880             tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1881             tgen_ori(s, TCG_TYPE_I32, a0, a2);
1882         } else if (a0 == a1) {
1883             tcg_out_insn(s, RR, OR, a0, a2);
1884         } else {
1885             tcg_out_insn(s, RRF, ORK, a0, a1, a2);
1886         }
1887         break;
1888     case INDEX_op_xor_i32:
1889         a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
1890         if (const_args[2]) {
1891             tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1892             tgen_xori(s, TCG_TYPE_I32, a0, a2);
1893         } else if (a0 == a1) {
1894             tcg_out_insn(s, RR, XR, args[0], args[2]);
1895         } else {
1896             tcg_out_insn(s, RRF, XRK, a0, a1, a2);
1897         }
1898         break;
1900     case INDEX_op_neg_i32:
1901         tcg_out_insn(s, RR, LCR, args[0], args[1]);
1902         break;
1904     case INDEX_op_mul_i32:
1905         if (const_args[2]) {
1906             if ((int32_t)args[2] == (int16_t)args[2]) {
1907                 tcg_out_insn(s, RI, MHI, args[0], args[2]);
1908             } else {
1909                 tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
1910             }
1911         } else {
1912             tcg_out_insn(s, RRE, MSR, args[0], args[2]);
1913         }
1914         break;
1916     case INDEX_op_div2_i32:
1917         tcg_out_insn(s, RR, DR, TCG_REG_R2, args[4]);
1918         break;
1919     case INDEX_op_divu2_i32:
1920         tcg_out_insn(s, RRE, DLR, TCG_REG_R2, args[4]);
1921         break;
1923     case INDEX_op_shl_i32:
1924         op = RS_SLL;
1925         op2 = RSY_SLLK;
1926     do_shift32:
1927         a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1928         if (a0 == a1) {
1929             if (const_args[2]) {
1930                 tcg_out_sh32(s, op, a0, TCG_REG_NONE, a2);
1931             } else {
1932                 tcg_out_sh32(s, op, a0, a2, 0);
1933             }
1934         } else {
1935             /* Using tcg_out_sh64 here for the format; it is a 32-bit shift.  */
1936             if (const_args[2]) {
1937                 tcg_out_sh64(s, op2, a0, a1, TCG_REG_NONE, a2);
1938             } else {
1939                 tcg_out_sh64(s, op2, a0, a1, a2, 0);
1940             }
1941         }
1942         break;
1943     case INDEX_op_shr_i32:
1944         op = RS_SRL;
1945         op2 = RSY_SRLK;
1946         goto do_shift32;
1947     case INDEX_op_sar_i32:
1948         op = RS_SRA;
1949         op2 = RSY_SRAK;
1950         goto do_shift32;
1952     case INDEX_op_rotl_i32:
1953         /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol.  */
1954         if (const_args[2]) {
1955             tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
1956         } else {
1957             tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
1958         }
1959         break;
1960     case INDEX_op_rotr_i32:
1961         if (const_args[2]) {
1962             tcg_out_sh64(s, RSY_RLL, args[0], args[1],
1963                          TCG_REG_NONE, (32 - args[2]) & 31);
1964         } else {
1965             tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
1966             tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
1967         }
1968         break;
1970     case INDEX_op_ext8s_i32:
1971         tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
1972         break;
1973     case INDEX_op_ext16s_i32:
1974         tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
1975         break;
1976     case INDEX_op_ext8u_i32:
1977         tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
1978         break;
1979     case INDEX_op_ext16u_i32:
1980         tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
1981         break;
1983     OP_32_64(bswap16):
1984         /* The TCG bswap definition requires bits 0-47 already be zero.
1985            Thus we don't need the G-type insns to implement bswap16_i64.  */
1986         tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1987         tcg_out_sh32(s, RS_SRL, args[0], TCG_REG_NONE, 16);
1988         break;
1989     OP_32_64(bswap32):
1990         tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1991         break;
1993     case INDEX_op_add2_i32:
1994         if (const_args[4]) {
1995             tcg_out_insn(s, RIL, ALFI, args[0], args[4]);
1996         } else {
1997             tcg_out_insn(s, RR, ALR, args[0], args[4]);
1998         }
1999         tcg_out_insn(s, RRE, ALCR, args[1], args[5]);
2000         break;
2001     case INDEX_op_sub2_i32:
2002         if (const_args[4]) {
2003             tcg_out_insn(s, RIL, SLFI, args[0], args[4]);
2004         } else {
2005             tcg_out_insn(s, RR, SLR, args[0], args[4]);
2006         }
2007         tcg_out_insn(s, RRE, SLBR, args[1], args[5]);
2008         break;
2010     case INDEX_op_br:
2011         tgen_branch(s, S390_CC_ALWAYS, arg_label(args[0]));
2012         break;
2014     case INDEX_op_brcond_i32:
2015         tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
2016                     args[1], const_args[1], arg_label(args[3]));
2017         break;
2018     case INDEX_op_setcond_i32:
2019         tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
2020                      args[2], const_args[2]);
2021         break;
2022     case INDEX_op_movcond_i32:
2023         tgen_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1],
2024                      args[2], const_args[2], args[3], const_args[3]);
2025         break;
2027     case INDEX_op_qemu_ld_i32:
2028         /* ??? Technically we can use a non-extending instruction.  */
2029     case INDEX_op_qemu_ld_i64:
2030         tcg_out_qemu_ld(s, args[0], args[1], args[2]);
2031         break;
2032     case INDEX_op_qemu_st_i32:
2033     case INDEX_op_qemu_st_i64:
2034         tcg_out_qemu_st(s, args[0], args[1], args[2]);
2035         break;
2037     case INDEX_op_ld16s_i64:
2038         tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
2039         break;
2040     case INDEX_op_ld32u_i64:
2041         tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
2042         break;
2043     case INDEX_op_ld32s_i64:
2044         tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
2045         break;
2046     case INDEX_op_ld_i64:
2047         tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2048         break;
2050     case INDEX_op_st32_i64:
2051         tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
2052         break;
2053     case INDEX_op_st_i64:
2054         tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2055         break;
2057     case INDEX_op_add_i64:
2058         a0 = args[0], a1 = args[1], a2 = args[2];
2059         if (const_args[2]) {
2060         do_addi_64:
2061             if (a0 == a1) {
2062                 if (a2 == (int16_t)a2) {
2063                     tcg_out_insn(s, RI, AGHI, a0, a2);
2064                     break;
2065                 }
2066                 if (s390_facilities & FACILITY_EXT_IMM) {
2067                     if (a2 == (int32_t)a2) {
2068                         tcg_out_insn(s, RIL, AGFI, a0, a2);
2069                         break;
2070                     } else if (a2 == (uint32_t)a2) {
2071                         tcg_out_insn(s, RIL, ALGFI, a0, a2);
2072                         break;
2073                     } else if (-a2 == (uint32_t)-a2) {
2074                         tcg_out_insn(s, RIL, SLGFI, a0, -a2);
2075                         break;
2076                     }
2077                 }
2078             }
2079             tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
2080         } else if (a0 == a1) {
2081             tcg_out_insn(s, RRE, AGR, a0, a2);
2082         } else {
2083             tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
2084         }
2085         break;
2086     case INDEX_op_sub_i64:
2087         a0 = args[0], a1 = args[1], a2 = args[2];
2088         if (const_args[2]) {
2089             a2 = -a2;
2090             goto do_addi_64;
2091         } else if (a0 == a1) {
2092             tcg_out_insn(s, RRE, SGR, a0, a2);
2093         } else {
2094             tcg_out_insn(s, RRF, SGRK, a0, a1, a2);
2095         }
2096         break;
2098     case INDEX_op_and_i64:
2099         a0 = args[0], a1 = args[1], a2 = args[2];
2100         if (const_args[2]) {
2101             tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2102             tgen_andi(s, TCG_TYPE_I64, args[0], args[2]);
2103         } else if (a0 == a1) {
2104             tcg_out_insn(s, RRE, NGR, args[0], args[2]);
2105         } else {
2106             tcg_out_insn(s, RRF, NGRK, a0, a1, a2);
2107         }
2108         break;
2109     case INDEX_op_or_i64:
2110         a0 = args[0], a1 = args[1], a2 = args[2];
2111         if (const_args[2]) {
2112             tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2113             tgen_ori(s, TCG_TYPE_I64, a0, a2);
2114         } else if (a0 == a1) {
2115             tcg_out_insn(s, RRE, OGR, a0, a2);
2116         } else {
2117             tcg_out_insn(s, RRF, OGRK, a0, a1, a2);
2118         }
2119         break;
2120     case INDEX_op_xor_i64:
2121         a0 = args[0], a1 = args[1], a2 = args[2];
2122         if (const_args[2]) {
2123             tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2124             tgen_xori(s, TCG_TYPE_I64, a0, a2);
2125         } else if (a0 == a1) {
2126             tcg_out_insn(s, RRE, XGR, a0, a2);
2127         } else {
2128             tcg_out_insn(s, RRF, XGRK, a0, a1, a2);
2129         }
2130         break;
2132     case INDEX_op_neg_i64:
2133         tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
2134         break;
2135     case INDEX_op_bswap64_i64:
2136         tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
2137         break;
2139     case INDEX_op_mul_i64:
2140         if (const_args[2]) {
2141             if (args[2] == (int16_t)args[2]) {
2142                 tcg_out_insn(s, RI, MGHI, args[0], args[2]);
2143             } else {
2144                 tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
2145             }
2146         } else {
2147             tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
2148         }
2149         break;
2151     case INDEX_op_div2_i64:
2152         /* ??? We get an unnecessary sign-extension of the dividend
2153            into R3 with this definition, but as we do in fact always
2154            produce both quotient and remainder using INDEX_op_div_i64
2155            instead requires jumping through even more hoops.  */
2156         tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
2157         break;
2158     case INDEX_op_divu2_i64:
2159         tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
2160         break;
2161     case INDEX_op_mulu2_i64:
2162         tcg_out_insn(s, RRE, MLGR, TCG_REG_R2, args[3]);
2163         break;
2165     case INDEX_op_shl_i64:
2166         op = RSY_SLLG;
2167     do_shift64:
2168         if (const_args[2]) {
2169             tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
2170         } else {
2171             tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
2172         }
2173         break;
2174     case INDEX_op_shr_i64:
2175         op = RSY_SRLG;
2176         goto do_shift64;
2177     case INDEX_op_sar_i64:
2178         op = RSY_SRAG;
2179         goto do_shift64;
2181     case INDEX_op_rotl_i64:
2182         if (const_args[2]) {
2183             tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2184                          TCG_REG_NONE, args[2]);
2185         } else {
2186             tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
2187         }
2188         break;
2189     case INDEX_op_rotr_i64:
2190         if (const_args[2]) {
2191             tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2192                          TCG_REG_NONE, (64 - args[2]) & 63);
2193         } else {
2194             /* We can use the smaller 32-bit negate because only the
2195                low 6 bits are examined for the rotate.  */
2196             tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2197             tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
2198         }
2199         break;
2201     case INDEX_op_ext8s_i64:
2202         tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
2203         break;
2204     case INDEX_op_ext16s_i64:
2205         tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
2206         break;
2207     case INDEX_op_ext_i32_i64:
2208     case INDEX_op_ext32s_i64:
2209         tgen_ext32s(s, args[0], args[1]);
2210         break;
2211     case INDEX_op_ext8u_i64:
2212         tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
2213         break;
2214     case INDEX_op_ext16u_i64:
2215         tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
2216         break;
2217     case INDEX_op_extu_i32_i64:
2218     case INDEX_op_ext32u_i64:
2219         tgen_ext32u(s, args[0], args[1]);
2220         break;
2222     case INDEX_op_add2_i64:
2223         if (const_args[4]) {
2224             if ((int64_t)args[4] >= 0) {
2225                 tcg_out_insn(s, RIL, ALGFI, args[0], args[4]);
2226             } else {
2227                 tcg_out_insn(s, RIL, SLGFI, args[0], -args[4]);
2228             }
2229         } else {
2230             tcg_out_insn(s, RRE, ALGR, args[0], args[4]);
2231         }
2232         tcg_out_insn(s, RRE, ALCGR, args[1], args[5]);
2233         break;
2234     case INDEX_op_sub2_i64:
2235         if (const_args[4]) {
2236             if ((int64_t)args[4] >= 0) {
2237                 tcg_out_insn(s, RIL, SLGFI, args[0], args[4]);
2238             } else {
2239                 tcg_out_insn(s, RIL, ALGFI, args[0], -args[4]);
2240             }
2241         } else {
2242             tcg_out_insn(s, RRE, SLGR, args[0], args[4]);
2243         }
2244         tcg_out_insn(s, RRE, SLBGR, args[1], args[5]);
2245         break;
2247     case INDEX_op_brcond_i64:
2248         tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
2249                     args[1], const_args[1], arg_label(args[3]));
2250         break;
2251     case INDEX_op_setcond_i64:
2252         tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2253                      args[2], const_args[2]);
2254         break;
2255     case INDEX_op_movcond_i64:
2256         tgen_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1],
2257                      args[2], const_args[2], args[3], const_args[3]);
2258         break;
2260     OP_32_64(deposit):
2261         a0 = args[0], a1 = args[1], a2 = args[2];
2262         if (const_args[1]) {
2263             tgen_deposit(s, a0, a2, args[3], args[4], 1);
2264         } else {
2265             /* Since we can't support "0Z" as a constraint, we allow a1 in
2266                any register.  Fix things up as if a matching constraint.  */
2267             if (a0 != a1) {
2268                 TCGType type = (opc == INDEX_op_deposit_i64);
2269                 if (a0 == a2) {
2270                     tcg_out_mov(s, type, TCG_TMP0, a2);
2271                     a2 = TCG_TMP0;
2272                 }
2273                 tcg_out_mov(s, type, a0, a1);
2274             }
2275             tgen_deposit(s, a0, a2, args[3], args[4], 0);
2276         }
2277         break;
2279     OP_32_64(extract):
2280         tgen_extract(s, args[0], args[1], args[2], args[3]);
2281         break;
2283     case INDEX_op_clz_i64:
2284         tgen_clz(s, args[0], args[1], args[2], const_args[2]);
2285         break;
2287     case INDEX_op_mb:
2288         /* The host memory model is quite strong, we simply need to
2289            serialize the instruction stream.  */
2290         if (args[0] & TCG_MO_ST_LD) {
2291             tcg_out_insn(s, RR, BCR,
2292                          s390_facilities & FACILITY_FAST_BCR_SER ? 14 : 15, 0);
2293         }
2294         break;
2296     case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
2297     case INDEX_op_mov_i64:
2298     case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi.  */
2299     case INDEX_op_movi_i64:
2300     case INDEX_op_call:     /* Always emitted via tcg_out_call.  */
2301     default:
2302         tcg_abort();
2303     }
2306 static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
2308     static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
2309     static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
2310     static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
2311     static const TCGTargetOpDef L_L = { .args_ct_str = { "L", "L" } };
2312     static const TCGTargetOpDef r_ri = { .args_ct_str = { "r", "ri" } };
2313     static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
2314     static const TCGTargetOpDef r_0_ri = { .args_ct_str = { "r", "0", "ri" } };
2315     static const TCGTargetOpDef r_0_rI = { .args_ct_str = { "r", "0", "rI" } };
2316     static const TCGTargetOpDef r_0_rJ = { .args_ct_str = { "r", "0", "rJ" } };
2317     static const TCGTargetOpDef a2_r
2318         = { .args_ct_str = { "r", "r", "0", "1", "r", "r" } };
2319     static const TCGTargetOpDef a2_ri
2320         = { .args_ct_str = { "r", "r", "0", "1", "ri", "r" } };
2321     static const TCGTargetOpDef a2_rA
2322         = { .args_ct_str = { "r", "r", "0", "1", "rA", "r" } };
2324     switch (op) {
2325     case INDEX_op_goto_ptr:
2326         return &r;
2328     case INDEX_op_ld8u_i32:
2329     case INDEX_op_ld8u_i64:
2330     case INDEX_op_ld8s_i32:
2331     case INDEX_op_ld8s_i64:
2332     case INDEX_op_ld16u_i32:
2333     case INDEX_op_ld16u_i64:
2334     case INDEX_op_ld16s_i32:
2335     case INDEX_op_ld16s_i64:
2336     case INDEX_op_ld_i32:
2337     case INDEX_op_ld32u_i64:
2338     case INDEX_op_ld32s_i64:
2339     case INDEX_op_ld_i64:
2340     case INDEX_op_st8_i32:
2341     case INDEX_op_st8_i64:
2342     case INDEX_op_st16_i32:
2343     case INDEX_op_st16_i64:
2344     case INDEX_op_st_i32:
2345     case INDEX_op_st32_i64:
2346     case INDEX_op_st_i64:
2347         return &r_r;
2349     case INDEX_op_add_i32:
2350     case INDEX_op_add_i64:
2351         return &r_r_ri;
2352     case INDEX_op_sub_i32:
2353     case INDEX_op_sub_i64:
2354     case INDEX_op_and_i32:
2355     case INDEX_op_and_i64:
2356     case INDEX_op_or_i32:
2357     case INDEX_op_or_i64:
2358     case INDEX_op_xor_i32:
2359     case INDEX_op_xor_i64:
2360         return (s390_facilities & FACILITY_DISTINCT_OPS ? &r_r_ri : &r_0_ri);
2362     case INDEX_op_mul_i32:
2363         /* If we have the general-instruction-extensions, then we have
2364            MULTIPLY SINGLE IMMEDIATE with a signed 32-bit, otherwise we
2365            have only MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit.  */
2366         return (s390_facilities & FACILITY_GEN_INST_EXT ? &r_0_ri : &r_0_rI);
2367     case INDEX_op_mul_i64:
2368         return (s390_facilities & FACILITY_GEN_INST_EXT ? &r_0_rJ : &r_0_rI);
2370     case INDEX_op_shl_i32:
2371     case INDEX_op_shr_i32:
2372     case INDEX_op_sar_i32:
2373         return (s390_facilities & FACILITY_DISTINCT_OPS ? &r_r_ri : &r_0_ri);
2375     case INDEX_op_shl_i64:
2376     case INDEX_op_shr_i64:
2377     case INDEX_op_sar_i64:
2378         return &r_r_ri;
2380     case INDEX_op_rotl_i32:
2381     case INDEX_op_rotl_i64:
2382     case INDEX_op_rotr_i32:
2383     case INDEX_op_rotr_i64:
2384         return &r_r_ri;
2386     case INDEX_op_brcond_i32:
2387     case INDEX_op_brcond_i64:
2388         return &r_ri;
2390     case INDEX_op_bswap16_i32:
2391     case INDEX_op_bswap16_i64:
2392     case INDEX_op_bswap32_i32:
2393     case INDEX_op_bswap32_i64:
2394     case INDEX_op_bswap64_i64:
2395     case INDEX_op_neg_i32:
2396     case INDEX_op_neg_i64:
2397     case INDEX_op_ext8s_i32:
2398     case INDEX_op_ext8s_i64:
2399     case INDEX_op_ext8u_i32:
2400     case INDEX_op_ext8u_i64:
2401     case INDEX_op_ext16s_i32:
2402     case INDEX_op_ext16s_i64:
2403     case INDEX_op_ext16u_i32:
2404     case INDEX_op_ext16u_i64:
2405     case INDEX_op_ext32s_i64:
2406     case INDEX_op_ext32u_i64:
2407     case INDEX_op_ext_i32_i64:
2408     case INDEX_op_extu_i32_i64:
2409     case INDEX_op_extract_i32:
2410     case INDEX_op_extract_i64:
2411         return &r_r;
2413     case INDEX_op_clz_i64:
2414     case INDEX_op_setcond_i32:
2415     case INDEX_op_setcond_i64:
2416         return &r_r_ri;
2418     case INDEX_op_qemu_ld_i32:
2419     case INDEX_op_qemu_ld_i64:
2420         return &r_L;
2421     case INDEX_op_qemu_st_i64:
2422     case INDEX_op_qemu_st_i32:
2423         return &L_L;
2425     case INDEX_op_deposit_i32:
2426     case INDEX_op_deposit_i64:
2427         {
2428             static const TCGTargetOpDef dep
2429                 = { .args_ct_str = { "r", "rZ", "r" } };
2430             return &dep;
2431         }
2432     case INDEX_op_movcond_i32:
2433     case INDEX_op_movcond_i64:
2434         {
2435             static const TCGTargetOpDef movc
2436                 = { .args_ct_str = { "r", "r", "ri", "r", "0" } };
2437             static const TCGTargetOpDef movc_l
2438                 = { .args_ct_str = { "r", "r", "ri", "rI", "0" } };
2439             return (s390_facilities & FACILITY_LOAD_ON_COND2 ? &movc_l : &movc);
2440         }
2441     case INDEX_op_div2_i32:
2442     case INDEX_op_div2_i64:
2443     case INDEX_op_divu2_i32:
2444     case INDEX_op_divu2_i64:
2445         {
2446             static const TCGTargetOpDef div2
2447                 = { .args_ct_str = { "b", "a", "0", "1", "r" } };
2448             return &div2;
2449         }
2450     case INDEX_op_mulu2_i64:
2451         {
2452             static const TCGTargetOpDef mul2
2453                 = { .args_ct_str = { "b", "a", "0", "r" } };
2454             return &mul2;
2455         }
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);
2464     default:
2465         break;
2466     }
2467     return NULL;
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");
2480         /* stfle 0(%r1) */
2481         r1 = &s390_facilities;
2482         asm volatile(".word 0xb2b0,0x1000"
2483                      : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
2484     }
2487 static void tcg_target_init(TCGContext *s)
2489     query_s390_facilities();
2491     tcg_target_available_regs[TCG_TYPE_I32] = 0xffff;
2492     tcg_target_available_regs[TCG_TYPE_I64] = 0xffff;
2494     tcg_target_call_clobber_regs = 0;
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     s->reserved_regs = 0;
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);
2512     if (USE_REG_TB) {
2513         tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB);
2514     }
2517 #define FRAME_SIZE  ((int)(TCG_TARGET_CALL_STACK_OFFSET          \
2518                            + TCG_STATIC_CALL_ARGS_SIZE           \
2519                            + CPU_TEMP_BUF_NLONGS * sizeof(long)))
2521 static void tcg_target_qemu_prologue(TCGContext *s)
2523     /* stmg %r6,%r15,48(%r15) (save registers) */
2524     tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
2526     /* aghi %r15,-frame_size */
2527     tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -FRAME_SIZE);
2529     tcg_set_frame(s, TCG_REG_CALL_STACK,
2530                   TCG_STATIC_CALL_ARGS_SIZE + TCG_TARGET_CALL_STACK_OFFSET,
2531                   CPU_TEMP_BUF_NLONGS * sizeof(long));
2533 #ifndef CONFIG_SOFTMMU
2534     if (guest_base >= 0x80000) {
2535         tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base, true);
2536         tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2537     }
2538 #endif
2540     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2541     if (USE_REG_TB) {
2542         tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB,
2543                     tcg_target_call_iarg_regs[1]);
2544     }
2546     /* br %r3 (go to TB) */
2547     tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
2549     /*
2550      * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2551      * and fall through to the rest of the epilogue.
2552      */
2553     tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
2554     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, 0);
2556     /* TB epilogue */
2557     tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
2559     /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2560     tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15,
2561                  FRAME_SIZE + 48);
2563     /* br %r14 (return) */
2564     tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
2567 static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
2569     memset(p, 0x07, count * sizeof(tcg_insn_unit));
2572 typedef struct {
2573     DebugFrameHeader h;
2574     uint8_t fde_def_cfa[4];
2575     uint8_t fde_reg_ofs[18];
2576 } DebugFrame;
2578 /* We're expecting a 2 byte uleb128 encoded value.  */
2579 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2581 #define ELF_HOST_MACHINE  EM_S390
2583 static const DebugFrame debug_frame = {
2584     .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2585     .h.cie.id = -1,
2586     .h.cie.version = 1,
2587     .h.cie.code_align = 1,
2588     .h.cie.data_align = 8,                /* sleb128 8 */
2589     .h.cie.return_column = TCG_REG_R14,
2591     /* Total FDE size does not include the "len" member.  */
2592     .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
2594     .fde_def_cfa = {
2595         12, TCG_REG_CALL_STACK,         /* DW_CFA_def_cfa %r15, ... */
2596         (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
2597         (FRAME_SIZE >> 7)
2598     },
2599     .fde_reg_ofs = {
2600         0x86, 6,                        /* DW_CFA_offset, %r6, 48 */
2601         0x87, 7,                        /* DW_CFA_offset, %r7, 56 */
2602         0x88, 8,                        /* DW_CFA_offset, %r8, 64 */
2603         0x89, 9,                        /* DW_CFA_offset, %r92, 72 */
2604         0x8a, 10,                       /* DW_CFA_offset, %r10, 80 */
2605         0x8b, 11,                       /* DW_CFA_offset, %r11, 88 */
2606         0x8c, 12,                       /* DW_CFA_offset, %r12, 96 */
2607         0x8d, 13,                       /* DW_CFA_offset, %r13, 104 */
2608         0x8e, 14,                       /* DW_CFA_offset, %r14, 112 */
2609     }
2612 void tcg_register_jit(const void *buf, size_t buf_size)
2614     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));