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