Statistics
| Branch: | Revision:

root / tcg / s390 / tcg-target.c @ 7fee199c

History | View | Annotate | Download (69.8 kB)

1 2827822e Alexander Graf
/*
2 2827822e Alexander Graf
 * Tiny Code Generator for QEMU
3 2827822e Alexander Graf
 *
4 2827822e Alexander Graf
 * Copyright (c) 2009 Ulrich Hecht <uli@suse.de>
5 48bb3750 Richard Henderson
 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
6 48bb3750 Richard Henderson
 * Copyright (c) 2010 Richard Henderson <rth@twiddle.net>
7 2827822e Alexander Graf
 *
8 2827822e Alexander Graf
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 2827822e Alexander Graf
 * of this software and associated documentation files (the "Software"), to deal
10 2827822e Alexander Graf
 * in the Software without restriction, including without limitation the rights
11 2827822e Alexander Graf
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 2827822e Alexander Graf
 * copies of the Software, and to permit persons to whom the Software is
13 2827822e Alexander Graf
 * furnished to do so, subject to the following conditions:
14 2827822e Alexander Graf
 *
15 2827822e Alexander Graf
 * The above copyright notice and this permission notice shall be included in
16 2827822e Alexander Graf
 * all copies or substantial portions of the Software.
17 2827822e Alexander Graf
 *
18 2827822e Alexander Graf
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 2827822e Alexander Graf
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 2827822e Alexander Graf
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 2827822e Alexander Graf
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 2827822e Alexander Graf
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 2827822e Alexander Graf
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 2827822e Alexander Graf
 * THE SOFTWARE.
25 2827822e Alexander Graf
 */
26 2827822e Alexander Graf
27 48bb3750 Richard Henderson
/* ??? The translation blocks produced by TCG are generally small enough to
28 48bb3750 Richard Henderson
   be entirely reachable with a 16-bit displacement.  Leaving the option for
29 48bb3750 Richard Henderson
   a 32-bit displacement here Just In Case.  */
30 48bb3750 Richard Henderson
#define USE_LONG_BRANCHES 0
31 48bb3750 Richard Henderson
32 48bb3750 Richard Henderson
#define TCG_CT_CONST_32    0x0100
33 48bb3750 Richard Henderson
#define TCG_CT_CONST_NEG   0x0200
34 48bb3750 Richard Henderson
#define TCG_CT_CONST_ADDI  0x0400
35 48bb3750 Richard Henderson
#define TCG_CT_CONST_MULI  0x0800
36 48bb3750 Richard Henderson
#define TCG_CT_CONST_ANDI  0x1000
37 48bb3750 Richard Henderson
#define TCG_CT_CONST_ORI   0x2000
38 48bb3750 Richard Henderson
#define TCG_CT_CONST_XORI  0x4000
39 48bb3750 Richard Henderson
#define TCG_CT_CONST_CMPI  0x8000
40 48bb3750 Richard Henderson
41 48bb3750 Richard Henderson
/* Several places within the instruction set 0 means "no register"
42 48bb3750 Richard Henderson
   rather than TCG_REG_R0.  */
43 48bb3750 Richard Henderson
#define TCG_REG_NONE    0
44 48bb3750 Richard Henderson
45 48bb3750 Richard Henderson
/* A scratch register that may be be used throughout the backend.  */
46 48bb3750 Richard Henderson
#define TCG_TMP0        TCG_REG_R14
47 48bb3750 Richard Henderson
48 48bb3750 Richard Henderson
#ifdef CONFIG_USE_GUEST_BASE
49 48bb3750 Richard Henderson
#define TCG_GUEST_BASE_REG TCG_REG_R13
50 48bb3750 Richard Henderson
#else
51 48bb3750 Richard Henderson
#define TCG_GUEST_BASE_REG TCG_REG_R0
52 48bb3750 Richard Henderson
#endif
53 48bb3750 Richard Henderson
54 48bb3750 Richard Henderson
#ifndef GUEST_BASE
55 48bb3750 Richard Henderson
#define GUEST_BASE 0
56 48bb3750 Richard Henderson
#endif
57 48bb3750 Richard Henderson
58 48bb3750 Richard Henderson
59 48bb3750 Richard Henderson
/* All of the following instructions are prefixed with their instruction
60 48bb3750 Richard Henderson
   format, and are defined as 8- or 16-bit quantities, even when the two
61 48bb3750 Richard Henderson
   halves of the 16-bit quantity may appear 32 bits apart in the insn.
62 48bb3750 Richard Henderson
   This makes it easy to copy the values from the tables in Appendix B.  */
63 48bb3750 Richard Henderson
typedef enum S390Opcode {
64 48bb3750 Richard Henderson
    RIL_AFI     = 0xc209,
65 48bb3750 Richard Henderson
    RIL_AGFI    = 0xc208,
66 48bb3750 Richard Henderson
    RIL_ALGFI   = 0xc20a,
67 48bb3750 Richard Henderson
    RIL_BRASL   = 0xc005,
68 48bb3750 Richard Henderson
    RIL_BRCL    = 0xc004,
69 48bb3750 Richard Henderson
    RIL_CFI     = 0xc20d,
70 48bb3750 Richard Henderson
    RIL_CGFI    = 0xc20c,
71 48bb3750 Richard Henderson
    RIL_CLFI    = 0xc20f,
72 48bb3750 Richard Henderson
    RIL_CLGFI   = 0xc20e,
73 48bb3750 Richard Henderson
    RIL_IIHF    = 0xc008,
74 48bb3750 Richard Henderson
    RIL_IILF    = 0xc009,
75 48bb3750 Richard Henderson
    RIL_LARL    = 0xc000,
76 48bb3750 Richard Henderson
    RIL_LGFI    = 0xc001,
77 48bb3750 Richard Henderson
    RIL_LGRL    = 0xc408,
78 48bb3750 Richard Henderson
    RIL_LLIHF   = 0xc00e,
79 48bb3750 Richard Henderson
    RIL_LLILF   = 0xc00f,
80 48bb3750 Richard Henderson
    RIL_LRL     = 0xc40d,
81 48bb3750 Richard Henderson
    RIL_MSFI    = 0xc201,
82 48bb3750 Richard Henderson
    RIL_MSGFI   = 0xc200,
83 48bb3750 Richard Henderson
    RIL_NIHF    = 0xc00a,
84 48bb3750 Richard Henderson
    RIL_NILF    = 0xc00b,
85 48bb3750 Richard Henderson
    RIL_OIHF    = 0xc00c,
86 48bb3750 Richard Henderson
    RIL_OILF    = 0xc00d,
87 48bb3750 Richard Henderson
    RIL_XIHF    = 0xc006,
88 48bb3750 Richard Henderson
    RIL_XILF    = 0xc007,
89 48bb3750 Richard Henderson
90 48bb3750 Richard Henderson
    RI_AGHI     = 0xa70b,
91 48bb3750 Richard Henderson
    RI_AHI      = 0xa70a,
92 48bb3750 Richard Henderson
    RI_BRC      = 0xa704,
93 48bb3750 Richard Henderson
    RI_IIHH     = 0xa500,
94 48bb3750 Richard Henderson
    RI_IIHL     = 0xa501,
95 48bb3750 Richard Henderson
    RI_IILH     = 0xa502,
96 48bb3750 Richard Henderson
    RI_IILL     = 0xa503,
97 48bb3750 Richard Henderson
    RI_LGHI     = 0xa709,
98 48bb3750 Richard Henderson
    RI_LLIHH    = 0xa50c,
99 48bb3750 Richard Henderson
    RI_LLIHL    = 0xa50d,
100 48bb3750 Richard Henderson
    RI_LLILH    = 0xa50e,
101 48bb3750 Richard Henderson
    RI_LLILL    = 0xa50f,
102 48bb3750 Richard Henderson
    RI_MGHI     = 0xa70d,
103 48bb3750 Richard Henderson
    RI_MHI      = 0xa70c,
104 48bb3750 Richard Henderson
    RI_NIHH     = 0xa504,
105 48bb3750 Richard Henderson
    RI_NIHL     = 0xa505,
106 48bb3750 Richard Henderson
    RI_NILH     = 0xa506,
107 48bb3750 Richard Henderson
    RI_NILL     = 0xa507,
108 48bb3750 Richard Henderson
    RI_OIHH     = 0xa508,
109 48bb3750 Richard Henderson
    RI_OIHL     = 0xa509,
110 48bb3750 Richard Henderson
    RI_OILH     = 0xa50a,
111 48bb3750 Richard Henderson
    RI_OILL     = 0xa50b,
112 48bb3750 Richard Henderson
113 48bb3750 Richard Henderson
    RIE_CGIJ    = 0xec7c,
114 48bb3750 Richard Henderson
    RIE_CGRJ    = 0xec64,
115 48bb3750 Richard Henderson
    RIE_CIJ     = 0xec7e,
116 48bb3750 Richard Henderson
    RIE_CLGRJ   = 0xec65,
117 48bb3750 Richard Henderson
    RIE_CLIJ    = 0xec7f,
118 48bb3750 Richard Henderson
    RIE_CLGIJ   = 0xec7d,
119 48bb3750 Richard Henderson
    RIE_CLRJ    = 0xec77,
120 48bb3750 Richard Henderson
    RIE_CRJ     = 0xec76,
121 48bb3750 Richard Henderson
122 48bb3750 Richard Henderson
    RRE_AGR     = 0xb908,
123 48bb3750 Richard Henderson
    RRE_CGR     = 0xb920,
124 48bb3750 Richard Henderson
    RRE_CLGR    = 0xb921,
125 48bb3750 Richard Henderson
    RRE_DLGR    = 0xb987,
126 48bb3750 Richard Henderson
    RRE_DLR     = 0xb997,
127 48bb3750 Richard Henderson
    RRE_DSGFR   = 0xb91d,
128 48bb3750 Richard Henderson
    RRE_DSGR    = 0xb90d,
129 48bb3750 Richard Henderson
    RRE_LGBR    = 0xb906,
130 48bb3750 Richard Henderson
    RRE_LCGR    = 0xb903,
131 48bb3750 Richard Henderson
    RRE_LGFR    = 0xb914,
132 48bb3750 Richard Henderson
    RRE_LGHR    = 0xb907,
133 48bb3750 Richard Henderson
    RRE_LGR     = 0xb904,
134 48bb3750 Richard Henderson
    RRE_LLGCR   = 0xb984,
135 48bb3750 Richard Henderson
    RRE_LLGFR   = 0xb916,
136 48bb3750 Richard Henderson
    RRE_LLGHR   = 0xb985,
137 48bb3750 Richard Henderson
    RRE_LRVR    = 0xb91f,
138 48bb3750 Richard Henderson
    RRE_LRVGR   = 0xb90f,
139 48bb3750 Richard Henderson
    RRE_LTGR    = 0xb902,
140 48bb3750 Richard Henderson
    RRE_MSGR    = 0xb90c,
141 48bb3750 Richard Henderson
    RRE_MSR     = 0xb252,
142 48bb3750 Richard Henderson
    RRE_NGR     = 0xb980,
143 48bb3750 Richard Henderson
    RRE_OGR     = 0xb981,
144 48bb3750 Richard Henderson
    RRE_SGR     = 0xb909,
145 48bb3750 Richard Henderson
    RRE_XGR     = 0xb982,
146 48bb3750 Richard Henderson
147 48bb3750 Richard Henderson
    RR_AR       = 0x1a,
148 48bb3750 Richard Henderson
    RR_BASR     = 0x0d,
149 48bb3750 Richard Henderson
    RR_BCR      = 0x07,
150 48bb3750 Richard Henderson
    RR_CLR      = 0x15,
151 48bb3750 Richard Henderson
    RR_CR       = 0x19,
152 48bb3750 Richard Henderson
    RR_DR       = 0x1d,
153 48bb3750 Richard Henderson
    RR_LCR      = 0x13,
154 48bb3750 Richard Henderson
    RR_LR       = 0x18,
155 48bb3750 Richard Henderson
    RR_LTR      = 0x12,
156 48bb3750 Richard Henderson
    RR_NR       = 0x14,
157 48bb3750 Richard Henderson
    RR_OR       = 0x16,
158 48bb3750 Richard Henderson
    RR_SR       = 0x1b,
159 48bb3750 Richard Henderson
    RR_XR       = 0x17,
160 48bb3750 Richard Henderson
161 48bb3750 Richard Henderson
    RSY_RLL     = 0xeb1d,
162 48bb3750 Richard Henderson
    RSY_RLLG    = 0xeb1c,
163 48bb3750 Richard Henderson
    RSY_SLLG    = 0xeb0d,
164 48bb3750 Richard Henderson
    RSY_SRAG    = 0xeb0a,
165 48bb3750 Richard Henderson
    RSY_SRLG    = 0xeb0c,
166 48bb3750 Richard Henderson
167 48bb3750 Richard Henderson
    RS_SLL      = 0x89,
168 48bb3750 Richard Henderson
    RS_SRA      = 0x8a,
169 48bb3750 Richard Henderson
    RS_SRL      = 0x88,
170 48bb3750 Richard Henderson
171 48bb3750 Richard Henderson
    RXY_AG      = 0xe308,
172 48bb3750 Richard Henderson
    RXY_AY      = 0xe35a,
173 48bb3750 Richard Henderson
    RXY_CG      = 0xe320,
174 48bb3750 Richard Henderson
    RXY_CY      = 0xe359,
175 48bb3750 Richard Henderson
    RXY_LB      = 0xe376,
176 48bb3750 Richard Henderson
    RXY_LG      = 0xe304,
177 48bb3750 Richard Henderson
    RXY_LGB     = 0xe377,
178 48bb3750 Richard Henderson
    RXY_LGF     = 0xe314,
179 48bb3750 Richard Henderson
    RXY_LGH     = 0xe315,
180 48bb3750 Richard Henderson
    RXY_LHY     = 0xe378,
181 48bb3750 Richard Henderson
    RXY_LLGC    = 0xe390,
182 48bb3750 Richard Henderson
    RXY_LLGF    = 0xe316,
183 48bb3750 Richard Henderson
    RXY_LLGH    = 0xe391,
184 48bb3750 Richard Henderson
    RXY_LMG     = 0xeb04,
185 48bb3750 Richard Henderson
    RXY_LRV     = 0xe31e,
186 48bb3750 Richard Henderson
    RXY_LRVG    = 0xe30f,
187 48bb3750 Richard Henderson
    RXY_LRVH    = 0xe31f,
188 48bb3750 Richard Henderson
    RXY_LY      = 0xe358,
189 48bb3750 Richard Henderson
    RXY_STCY    = 0xe372,
190 48bb3750 Richard Henderson
    RXY_STG     = 0xe324,
191 48bb3750 Richard Henderson
    RXY_STHY    = 0xe370,
192 48bb3750 Richard Henderson
    RXY_STMG    = 0xeb24,
193 48bb3750 Richard Henderson
    RXY_STRV    = 0xe33e,
194 48bb3750 Richard Henderson
    RXY_STRVG   = 0xe32f,
195 48bb3750 Richard Henderson
    RXY_STRVH   = 0xe33f,
196 48bb3750 Richard Henderson
    RXY_STY     = 0xe350,
197 48bb3750 Richard Henderson
198 48bb3750 Richard Henderson
    RX_A        = 0x5a,
199 48bb3750 Richard Henderson
    RX_C        = 0x59,
200 48bb3750 Richard Henderson
    RX_L        = 0x58,
201 48bb3750 Richard Henderson
    RX_LH       = 0x48,
202 48bb3750 Richard Henderson
    RX_ST       = 0x50,
203 48bb3750 Richard Henderson
    RX_STC      = 0x42,
204 48bb3750 Richard Henderson
    RX_STH      = 0x40,
205 48bb3750 Richard Henderson
} S390Opcode;
206 48bb3750 Richard Henderson
207 48bb3750 Richard Henderson
#define LD_SIGNED      0x04
208 48bb3750 Richard Henderson
#define LD_UINT8       0x00
209 48bb3750 Richard Henderson
#define LD_INT8        (LD_UINT8 | LD_SIGNED)
210 48bb3750 Richard Henderson
#define LD_UINT16      0x01
211 48bb3750 Richard Henderson
#define LD_INT16       (LD_UINT16 | LD_SIGNED)
212 48bb3750 Richard Henderson
#define LD_UINT32      0x02
213 48bb3750 Richard Henderson
#define LD_INT32       (LD_UINT32 | LD_SIGNED)
214 48bb3750 Richard Henderson
#define LD_UINT64      0x03
215 48bb3750 Richard Henderson
#define LD_INT64       (LD_UINT64 | LD_SIGNED)
216 48bb3750 Richard Henderson
217 48bb3750 Richard Henderson
#ifndef NDEBUG
218 48bb3750 Richard Henderson
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
219 48bb3750 Richard Henderson
    "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
220 48bb3750 Richard Henderson
    "%r8", "%r9", "%r10" "%r11" "%r12" "%r13" "%r14" "%r15"
221 48bb3750 Richard Henderson
};
222 48bb3750 Richard Henderson
#endif
223 48bb3750 Richard Henderson
224 48bb3750 Richard Henderson
/* Since R6 is a potential argument register, choose it last of the
225 48bb3750 Richard Henderson
   call-saved registers.  Likewise prefer the call-clobbered registers
226 48bb3750 Richard Henderson
   in reverse order to maximize the chance of avoiding the arguments.  */
227 2827822e Alexander Graf
static const int tcg_target_reg_alloc_order[] = {
228 48bb3750 Richard Henderson
    TCG_REG_R13,
229 48bb3750 Richard Henderson
    TCG_REG_R12,
230 48bb3750 Richard Henderson
    TCG_REG_R11,
231 48bb3750 Richard Henderson
    TCG_REG_R10,
232 48bb3750 Richard Henderson
    TCG_REG_R9,
233 48bb3750 Richard Henderson
    TCG_REG_R8,
234 48bb3750 Richard Henderson
    TCG_REG_R7,
235 48bb3750 Richard Henderson
    TCG_REG_R6,
236 48bb3750 Richard Henderson
    TCG_REG_R14,
237 48bb3750 Richard Henderson
    TCG_REG_R0,
238 48bb3750 Richard Henderson
    TCG_REG_R1,
239 48bb3750 Richard Henderson
    TCG_REG_R5,
240 48bb3750 Richard Henderson
    TCG_REG_R4,
241 48bb3750 Richard Henderson
    TCG_REG_R3,
242 48bb3750 Richard Henderson
    TCG_REG_R2,
243 2827822e Alexander Graf
};
244 2827822e Alexander Graf
245 2827822e Alexander Graf
static const int tcg_target_call_iarg_regs[] = {
246 48bb3750 Richard Henderson
    TCG_REG_R2,
247 48bb3750 Richard Henderson
    TCG_REG_R3,
248 48bb3750 Richard Henderson
    TCG_REG_R4,
249 48bb3750 Richard Henderson
    TCG_REG_R5,
250 48bb3750 Richard Henderson
    TCG_REG_R6,
251 2827822e Alexander Graf
};
252 2827822e Alexander Graf
253 2827822e Alexander Graf
static const int tcg_target_call_oarg_regs[] = {
254 48bb3750 Richard Henderson
    TCG_REG_R2,
255 48bb3750 Richard Henderson
    TCG_REG_R3,
256 48bb3750 Richard Henderson
};
257 48bb3750 Richard Henderson
258 48bb3750 Richard Henderson
#define S390_CC_EQ      8
259 48bb3750 Richard Henderson
#define S390_CC_LT      4
260 48bb3750 Richard Henderson
#define S390_CC_GT      2
261 48bb3750 Richard Henderson
#define S390_CC_OV      1
262 48bb3750 Richard Henderson
#define S390_CC_NE      (S390_CC_LT | S390_CC_GT)
263 48bb3750 Richard Henderson
#define S390_CC_LE      (S390_CC_LT | S390_CC_EQ)
264 48bb3750 Richard Henderson
#define S390_CC_GE      (S390_CC_GT | S390_CC_EQ)
265 48bb3750 Richard Henderson
#define S390_CC_NEVER   0
266 48bb3750 Richard Henderson
#define S390_CC_ALWAYS  15
267 48bb3750 Richard Henderson
268 48bb3750 Richard Henderson
/* Condition codes that result from a COMPARE and COMPARE LOGICAL.  */
269 48bb3750 Richard Henderson
static const uint8_t tcg_cond_to_s390_cond[10] = {
270 48bb3750 Richard Henderson
    [TCG_COND_EQ]  = S390_CC_EQ,
271 48bb3750 Richard Henderson
    [TCG_COND_NE]  = S390_CC_NE,
272 48bb3750 Richard Henderson
    [TCG_COND_LT]  = S390_CC_LT,
273 48bb3750 Richard Henderson
    [TCG_COND_LE]  = S390_CC_LE,
274 48bb3750 Richard Henderson
    [TCG_COND_GT]  = S390_CC_GT,
275 48bb3750 Richard Henderson
    [TCG_COND_GE]  = S390_CC_GE,
276 48bb3750 Richard Henderson
    [TCG_COND_LTU] = S390_CC_LT,
277 48bb3750 Richard Henderson
    [TCG_COND_LEU] = S390_CC_LE,
278 48bb3750 Richard Henderson
    [TCG_COND_GTU] = S390_CC_GT,
279 48bb3750 Richard Henderson
    [TCG_COND_GEU] = S390_CC_GE,
280 48bb3750 Richard Henderson
};
281 48bb3750 Richard Henderson
282 48bb3750 Richard Henderson
/* Condition codes that result from a LOAD AND TEST.  Here, we have no
283 48bb3750 Richard Henderson
   unsigned instruction variation, however since the test is vs zero we
284 48bb3750 Richard Henderson
   can re-map the outcomes appropriately.  */
285 48bb3750 Richard Henderson
static const uint8_t tcg_cond_to_ltr_cond[10] = {
286 48bb3750 Richard Henderson
    [TCG_COND_EQ]  = S390_CC_EQ,
287 48bb3750 Richard Henderson
    [TCG_COND_NE]  = S390_CC_NE,
288 48bb3750 Richard Henderson
    [TCG_COND_LT]  = S390_CC_LT,
289 48bb3750 Richard Henderson
    [TCG_COND_LE]  = S390_CC_LE,
290 48bb3750 Richard Henderson
    [TCG_COND_GT]  = S390_CC_GT,
291 48bb3750 Richard Henderson
    [TCG_COND_GE]  = S390_CC_GE,
292 48bb3750 Richard Henderson
    [TCG_COND_LTU] = S390_CC_NEVER,
293 48bb3750 Richard Henderson
    [TCG_COND_LEU] = S390_CC_EQ,
294 48bb3750 Richard Henderson
    [TCG_COND_GTU] = S390_CC_NE,
295 48bb3750 Richard Henderson
    [TCG_COND_GEU] = S390_CC_ALWAYS,
296 48bb3750 Richard Henderson
};
297 48bb3750 Richard Henderson
298 48bb3750 Richard Henderson
#ifdef CONFIG_SOFTMMU
299 48bb3750 Richard Henderson
300 48bb3750 Richard Henderson
#include "../../softmmu_defs.h"
301 48bb3750 Richard Henderson
302 48bb3750 Richard Henderson
static void *qemu_ld_helpers[4] = {
303 48bb3750 Richard Henderson
    __ldb_mmu,
304 48bb3750 Richard Henderson
    __ldw_mmu,
305 48bb3750 Richard Henderson
    __ldl_mmu,
306 48bb3750 Richard Henderson
    __ldq_mmu,
307 48bb3750 Richard Henderson
};
308 48bb3750 Richard Henderson
309 48bb3750 Richard Henderson
static void *qemu_st_helpers[4] = {
310 48bb3750 Richard Henderson
    __stb_mmu,
311 48bb3750 Richard Henderson
    __stw_mmu,
312 48bb3750 Richard Henderson
    __stl_mmu,
313 48bb3750 Richard Henderson
    __stq_mmu,
314 2827822e Alexander Graf
};
315 48bb3750 Richard Henderson
#endif
316 48bb3750 Richard Henderson
317 48bb3750 Richard Henderson
static uint8_t *tb_ret_addr;
318 48bb3750 Richard Henderson
319 48bb3750 Richard Henderson
/* A list of relevant facilities used by this translator.  Some of these
320 48bb3750 Richard Henderson
   are required for proper operation, and these are checked at startup.  */
321 48bb3750 Richard Henderson
322 48bb3750 Richard Henderson
#define FACILITY_ZARCH_ACTIVE        (1ULL << (63 - 2))
323 48bb3750 Richard Henderson
#define FACILITY_LONG_DISP        (1ULL << (63 - 18))
324 48bb3750 Richard Henderson
#define FACILITY_EXT_IMM        (1ULL << (63 - 21))
325 48bb3750 Richard Henderson
#define FACILITY_GEN_INST_EXT        (1ULL << (63 - 34))
326 48bb3750 Richard Henderson
327 48bb3750 Richard Henderson
static uint64_t facilities;
328 2827822e Alexander Graf
329 2827822e Alexander Graf
static void patch_reloc(uint8_t *code_ptr, int type,
330 48bb3750 Richard Henderson
                        tcg_target_long value, tcg_target_long addend)
331 2827822e Alexander Graf
{
332 48bb3750 Richard Henderson
    tcg_target_long code_ptr_tl = (tcg_target_long)code_ptr;
333 48bb3750 Richard Henderson
    tcg_target_long pcrel2;
334 48bb3750 Richard Henderson
335 48bb3750 Richard Henderson
    /* ??? Not the usual definition of "addend".  */
336 48bb3750 Richard Henderson
    pcrel2 = (value - (code_ptr_tl + addend)) >> 1;
337 48bb3750 Richard Henderson
338 48bb3750 Richard Henderson
    switch (type) {
339 48bb3750 Richard Henderson
    case R_390_PC16DBL:
340 48bb3750 Richard Henderson
        assert(pcrel2 == (int16_t)pcrel2);
341 48bb3750 Richard Henderson
        *(int16_t *)code_ptr = pcrel2;
342 48bb3750 Richard Henderson
        break;
343 48bb3750 Richard Henderson
    case R_390_PC32DBL:
344 48bb3750 Richard Henderson
        assert(pcrel2 == (int32_t)pcrel2);
345 48bb3750 Richard Henderson
        *(int32_t *)code_ptr = pcrel2;
346 48bb3750 Richard Henderson
        break;
347 48bb3750 Richard Henderson
    default:
348 48bb3750 Richard Henderson
        tcg_abort();
349 48bb3750 Richard Henderson
        break;
350 48bb3750 Richard Henderson
    }
351 2827822e Alexander Graf
}
352 2827822e Alexander Graf
353 48bb3750 Richard Henderson
static int tcg_target_get_call_iarg_regs_count(int flags)
354 2827822e Alexander Graf
{
355 48bb3750 Richard Henderson
    return sizeof(tcg_target_call_iarg_regs) / sizeof(int);
356 2827822e Alexander Graf
}
357 2827822e Alexander Graf
358 2827822e Alexander Graf
/* parse target specific constraints */
359 2827822e Alexander Graf
static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
360 2827822e Alexander Graf
{
361 48bb3750 Richard Henderson
    const char *ct_str = *pct_str;
362 48bb3750 Richard Henderson
363 48bb3750 Richard Henderson
    switch (ct_str[0]) {
364 48bb3750 Richard Henderson
    case 'r':                  /* all registers */
365 48bb3750 Richard Henderson
        ct->ct |= TCG_CT_REG;
366 48bb3750 Richard Henderson
        tcg_regset_set32(ct->u.regs, 0, 0xffff);
367 48bb3750 Richard Henderson
        break;
368 48bb3750 Richard Henderson
    case 'R':                  /* not R0 */
369 48bb3750 Richard Henderson
        ct->ct |= TCG_CT_REG;
370 48bb3750 Richard Henderson
        tcg_regset_set32(ct->u.regs, 0, 0xffff);
371 48bb3750 Richard Henderson
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
372 48bb3750 Richard Henderson
        break;
373 48bb3750 Richard Henderson
    case 'L':                  /* qemu_ld/st constraint */
374 48bb3750 Richard Henderson
        ct->ct |= TCG_CT_REG;
375 48bb3750 Richard Henderson
        tcg_regset_set32(ct->u.regs, 0, 0xffff);
376 48bb3750 Richard Henderson
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R2);
377 48bb3750 Richard Henderson
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
378 48bb3750 Richard Henderson
        break;
379 48bb3750 Richard Henderson
    case 'a':                  /* force R2 for division */
380 48bb3750 Richard Henderson
        ct->ct |= TCG_CT_REG;
381 48bb3750 Richard Henderson
        tcg_regset_clear(ct->u.regs);
382 48bb3750 Richard Henderson
        tcg_regset_set_reg(ct->u.regs, TCG_REG_R2);
383 48bb3750 Richard Henderson
        break;
384 48bb3750 Richard Henderson
    case 'b':                  /* force R3 for division */
385 48bb3750 Richard Henderson
        ct->ct |= TCG_CT_REG;
386 48bb3750 Richard Henderson
        tcg_regset_clear(ct->u.regs);
387 48bb3750 Richard Henderson
        tcg_regset_set_reg(ct->u.regs, TCG_REG_R3);
388 48bb3750 Richard Henderson
        break;
389 48bb3750 Richard Henderson
    case 'N':                  /* force immediate negate */
390 48bb3750 Richard Henderson
        ct->ct |= TCG_CT_CONST_NEG;
391 48bb3750 Richard Henderson
        break;
392 48bb3750 Richard Henderson
    case 'W':                  /* force 32-bit ("word") immediate */
393 48bb3750 Richard Henderson
        ct->ct |= TCG_CT_CONST_32;
394 48bb3750 Richard Henderson
        break;
395 48bb3750 Richard Henderson
    case 'I':
396 48bb3750 Richard Henderson
        ct->ct |= TCG_CT_CONST_ADDI;
397 48bb3750 Richard Henderson
        break;
398 48bb3750 Richard Henderson
    case 'K':
399 48bb3750 Richard Henderson
        ct->ct |= TCG_CT_CONST_MULI;
400 48bb3750 Richard Henderson
        break;
401 48bb3750 Richard Henderson
    case 'A':
402 48bb3750 Richard Henderson
        ct->ct |= TCG_CT_CONST_ANDI;
403 48bb3750 Richard Henderson
        break;
404 48bb3750 Richard Henderson
    case 'O':
405 48bb3750 Richard Henderson
        ct->ct |= TCG_CT_CONST_ORI;
406 48bb3750 Richard Henderson
        break;
407 48bb3750 Richard Henderson
    case 'X':
408 48bb3750 Richard Henderson
        ct->ct |= TCG_CT_CONST_XORI;
409 48bb3750 Richard Henderson
        break;
410 48bb3750 Richard Henderson
    case 'C':
411 48bb3750 Richard Henderson
        ct->ct |= TCG_CT_CONST_CMPI;
412 48bb3750 Richard Henderson
        break;
413 48bb3750 Richard Henderson
    default:
414 48bb3750 Richard Henderson
        return -1;
415 48bb3750 Richard Henderson
    }
416 48bb3750 Richard Henderson
    ct_str++;
417 48bb3750 Richard Henderson
    *pct_str = ct_str;
418 48bb3750 Richard Henderson
419 2827822e Alexander Graf
    return 0;
420 2827822e Alexander Graf
}
421 2827822e Alexander Graf
422 48bb3750 Richard Henderson
/* Immediates to be used with logical AND.  This is an optimization only,
423 48bb3750 Richard Henderson
   since a full 64-bit immediate AND can always be performed with 4 sequential
424 48bb3750 Richard Henderson
   NI[LH][LH] instructions.  What we're looking for is immediates that we
425 48bb3750 Richard Henderson
   can load efficiently, and the immediate load plus the reg-reg AND is
426 48bb3750 Richard Henderson
   smaller than the sequential NI's.  */
427 48bb3750 Richard Henderson
428 48bb3750 Richard Henderson
static int tcg_match_andi(int ct, tcg_target_ulong val)
429 48bb3750 Richard Henderson
{
430 48bb3750 Richard Henderson
    int i;
431 48bb3750 Richard Henderson
432 48bb3750 Richard Henderson
    if (facilities & FACILITY_EXT_IMM) {
433 48bb3750 Richard Henderson
        if (ct & TCG_CT_CONST_32) {
434 48bb3750 Richard Henderson
            /* All 32-bit ANDs can be performed with 1 48-bit insn.  */
435 48bb3750 Richard Henderson
            return 1;
436 48bb3750 Richard Henderson
        }
437 48bb3750 Richard Henderson
438 48bb3750 Richard Henderson
        /* Zero-extensions.  */
439 48bb3750 Richard Henderson
        if (val == 0xff || val == 0xffff || val == 0xffffffff) {
440 48bb3750 Richard Henderson
            return 1;
441 48bb3750 Richard Henderson
        }
442 48bb3750 Richard Henderson
    } else {
443 48bb3750 Richard Henderson
        if (ct & TCG_CT_CONST_32) {
444 48bb3750 Richard Henderson
            val = (uint32_t)val;
445 48bb3750 Richard Henderson
        } else if (val == 0xffffffff) {
446 48bb3750 Richard Henderson
            return 1;
447 48bb3750 Richard Henderson
        }
448 48bb3750 Richard Henderson
    }
449 48bb3750 Richard Henderson
450 48bb3750 Richard Henderson
    /* Try all 32-bit insns that can perform it in one go.  */
451 48bb3750 Richard Henderson
    for (i = 0; i < 4; i++) {
452 48bb3750 Richard Henderson
        tcg_target_ulong mask = ~(0xffffull << i*16);
453 48bb3750 Richard Henderson
        if ((val & mask) == mask) {
454 48bb3750 Richard Henderson
            return 1;
455 48bb3750 Richard Henderson
        }
456 48bb3750 Richard Henderson
    }
457 48bb3750 Richard Henderson
458 48bb3750 Richard Henderson
    /* Look for 16-bit values performing the mask.  These are better
459 48bb3750 Richard Henderson
       to load with LLI[LH][LH].  */
460 48bb3750 Richard Henderson
    for (i = 0; i < 4; i++) {
461 48bb3750 Richard Henderson
        tcg_target_ulong mask = 0xffffull << i*16;
462 48bb3750 Richard Henderson
        if ((val & mask) == val) {
463 48bb3750 Richard Henderson
            return 0;
464 48bb3750 Richard Henderson
        }
465 48bb3750 Richard Henderson
    }
466 48bb3750 Richard Henderson
467 48bb3750 Richard Henderson
    /* Look for 32-bit values performing the 64-bit mask.  These
468 48bb3750 Richard Henderson
       are better to load with LLI[LH]F, or if extended immediates
469 48bb3750 Richard Henderson
       not available, with a pair of LLI insns.  */
470 48bb3750 Richard Henderson
    if ((ct & TCG_CT_CONST_32) == 0) {
471 48bb3750 Richard Henderson
        if (val <= 0xffffffff || (val & 0xffffffff) == 0) {
472 48bb3750 Richard Henderson
            return 0;
473 48bb3750 Richard Henderson
        }
474 48bb3750 Richard Henderson
    }
475 48bb3750 Richard Henderson
476 48bb3750 Richard Henderson
    return 1;
477 48bb3750 Richard Henderson
}
478 48bb3750 Richard Henderson
479 48bb3750 Richard Henderson
/* Immediates to be used with logical OR.  This is an optimization only,
480 48bb3750 Richard Henderson
   since a full 64-bit immediate OR can always be performed with 4 sequential
481 48bb3750 Richard Henderson
   OI[LH][LH] instructions.  What we're looking for is immediates that we
482 48bb3750 Richard Henderson
   can load efficiently, and the immediate load plus the reg-reg OR is
483 48bb3750 Richard Henderson
   smaller than the sequential OI's.  */
484 48bb3750 Richard Henderson
485 48bb3750 Richard Henderson
static int tcg_match_ori(int ct, tcg_target_long val)
486 48bb3750 Richard Henderson
{
487 48bb3750 Richard Henderson
    if (facilities & FACILITY_EXT_IMM) {
488 48bb3750 Richard Henderson
        if (ct & TCG_CT_CONST_32) {
489 48bb3750 Richard Henderson
            /* All 32-bit ORs can be performed with 1 48-bit insn.  */
490 48bb3750 Richard Henderson
            return 1;
491 48bb3750 Richard Henderson
        }
492 48bb3750 Richard Henderson
    }
493 48bb3750 Richard Henderson
494 48bb3750 Richard Henderson
    /* Look for negative values.  These are best to load with LGHI.  */
495 48bb3750 Richard Henderson
    if (val < 0) {
496 48bb3750 Richard Henderson
        if (val == (int16_t)val) {
497 48bb3750 Richard Henderson
            return 0;
498 48bb3750 Richard Henderson
        }
499 48bb3750 Richard Henderson
        if (facilities & FACILITY_EXT_IMM) {
500 48bb3750 Richard Henderson
            if (val == (int32_t)val) {
501 48bb3750 Richard Henderson
                return 0;
502 48bb3750 Richard Henderson
            }
503 48bb3750 Richard Henderson
        }
504 48bb3750 Richard Henderson
    }
505 48bb3750 Richard Henderson
506 48bb3750 Richard Henderson
    return 1;
507 48bb3750 Richard Henderson
}
508 48bb3750 Richard Henderson
509 48bb3750 Richard Henderson
/* Immediates to be used with logical XOR.  This is almost, but not quite,
510 48bb3750 Richard Henderson
   only an optimization.  XOR with immediate is only supported with the
511 48bb3750 Richard Henderson
   extended-immediate facility.  That said, there are a few patterns for
512 48bb3750 Richard Henderson
   which it is better to load the value into a register first.  */
513 48bb3750 Richard Henderson
514 48bb3750 Richard Henderson
static int tcg_match_xori(int ct, tcg_target_long val)
515 48bb3750 Richard Henderson
{
516 48bb3750 Richard Henderson
    if ((facilities & FACILITY_EXT_IMM) == 0) {
517 48bb3750 Richard Henderson
        return 0;
518 48bb3750 Richard Henderson
    }
519 48bb3750 Richard Henderson
520 48bb3750 Richard Henderson
    if (ct & TCG_CT_CONST_32) {
521 48bb3750 Richard Henderson
        /* All 32-bit XORs can be performed with 1 48-bit insn.  */
522 48bb3750 Richard Henderson
        return 1;
523 48bb3750 Richard Henderson
    }
524 48bb3750 Richard Henderson
525 48bb3750 Richard Henderson
    /* Look for negative values.  These are best to load with LGHI.  */
526 48bb3750 Richard Henderson
    if (val < 0 && val == (int32_t)val) {
527 48bb3750 Richard Henderson
        return 0;
528 48bb3750 Richard Henderson
    }
529 48bb3750 Richard Henderson
530 48bb3750 Richard Henderson
    return 1;
531 48bb3750 Richard Henderson
}
532 48bb3750 Richard Henderson
533 48bb3750 Richard Henderson
/* Imediates to be used with comparisons.  */
534 48bb3750 Richard Henderson
535 48bb3750 Richard Henderson
static int tcg_match_cmpi(int ct, tcg_target_long val)
536 48bb3750 Richard Henderson
{
537 48bb3750 Richard Henderson
    if (facilities & FACILITY_EXT_IMM) {
538 48bb3750 Richard Henderson
        /* The COMPARE IMMEDIATE instruction is available.  */
539 48bb3750 Richard Henderson
        if (ct & TCG_CT_CONST_32) {
540 48bb3750 Richard Henderson
            /* We have a 32-bit immediate and can compare against anything.  */
541 48bb3750 Richard Henderson
            return 1;
542 48bb3750 Richard Henderson
        } else {
543 48bb3750 Richard Henderson
            /* ??? We have no insight here into whether the comparison is
544 48bb3750 Richard Henderson
               signed or unsigned.  The COMPARE IMMEDIATE insn uses a 32-bit
545 48bb3750 Richard Henderson
               signed immediate, and the COMPARE LOGICAL IMMEDIATE insn uses
546 48bb3750 Richard Henderson
               a 32-bit unsigned immediate.  If we were to use the (semi)
547 48bb3750 Richard Henderson
               obvious "val == (int32_t)val" we would be enabling unsigned
548 48bb3750 Richard Henderson
               comparisons vs very large numbers.  The only solution is to
549 48bb3750 Richard Henderson
               take the intersection of the ranges.  */
550 48bb3750 Richard Henderson
            /* ??? Another possible solution is to simply lie and allow all
551 48bb3750 Richard Henderson
               constants here and force the out-of-range values into a temp
552 48bb3750 Richard Henderson
               register in tgen_cmp when we have knowledge of the actual
553 48bb3750 Richard Henderson
               comparison code in use.  */
554 48bb3750 Richard Henderson
            return val >= 0 && val <= 0x7fffffff;
555 48bb3750 Richard Henderson
        }
556 48bb3750 Richard Henderson
    } else {
557 48bb3750 Richard Henderson
        /* Only the LOAD AND TEST instruction is available.  */
558 48bb3750 Richard Henderson
        return val == 0;
559 48bb3750 Richard Henderson
    }
560 48bb3750 Richard Henderson
}
561 48bb3750 Richard Henderson
562 2827822e Alexander Graf
/* Test if a constant matches the constraint. */
563 48bb3750 Richard Henderson
static int tcg_target_const_match(tcg_target_long val,
564 48bb3750 Richard Henderson
                                  const TCGArgConstraint *arg_ct)
565 2827822e Alexander Graf
{
566 48bb3750 Richard Henderson
    int ct = arg_ct->ct;
567 48bb3750 Richard Henderson
568 48bb3750 Richard Henderson
    if (ct & TCG_CT_CONST) {
569 48bb3750 Richard Henderson
        return 1;
570 48bb3750 Richard Henderson
    }
571 48bb3750 Richard Henderson
572 48bb3750 Richard Henderson
    /* Handle the modifiers.  */
573 48bb3750 Richard Henderson
    if (ct & TCG_CT_CONST_NEG) {
574 48bb3750 Richard Henderson
        val = -val;
575 48bb3750 Richard Henderson
    }
576 48bb3750 Richard Henderson
    if (ct & TCG_CT_CONST_32) {
577 48bb3750 Richard Henderson
        val = (int32_t)val;
578 48bb3750 Richard Henderson
    }
579 48bb3750 Richard Henderson
580 48bb3750 Richard Henderson
    /* The following are mutually exclusive.  */
581 48bb3750 Richard Henderson
    if (ct & TCG_CT_CONST_ADDI) {
582 48bb3750 Richard Henderson
        /* Immediates that may be used with add.  If we have the
583 48bb3750 Richard Henderson
           extended-immediates facility then we have ADD IMMEDIATE
584 48bb3750 Richard Henderson
           with signed and unsigned 32-bit, otherwise we have only
585 48bb3750 Richard Henderson
           ADD HALFWORD IMMEDIATE with a signed 16-bit.  */
586 48bb3750 Richard Henderson
        if (facilities & FACILITY_EXT_IMM) {
587 48bb3750 Richard Henderson
            return val == (int32_t)val || val == (uint32_t)val;
588 48bb3750 Richard Henderson
        } else {
589 48bb3750 Richard Henderson
            return val == (int16_t)val;
590 48bb3750 Richard Henderson
        }
591 48bb3750 Richard Henderson
    } else if (ct & TCG_CT_CONST_MULI) {
592 48bb3750 Richard Henderson
        /* Immediates that may be used with multiply.  If we have the
593 48bb3750 Richard Henderson
           general-instruction-extensions, then we have MULTIPLY SINGLE
594 48bb3750 Richard Henderson
           IMMEDIATE with a signed 32-bit, otherwise we have only
595 48bb3750 Richard Henderson
           MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit.  */
596 48bb3750 Richard Henderson
        if (facilities & FACILITY_GEN_INST_EXT) {
597 48bb3750 Richard Henderson
            return val == (int32_t)val;
598 48bb3750 Richard Henderson
        } else {
599 48bb3750 Richard Henderson
            return val == (int16_t)val;
600 48bb3750 Richard Henderson
        }
601 48bb3750 Richard Henderson
    } else if (ct & TCG_CT_CONST_ANDI) {
602 48bb3750 Richard Henderson
        return tcg_match_andi(ct, val);
603 48bb3750 Richard Henderson
    } else if (ct & TCG_CT_CONST_ORI) {
604 48bb3750 Richard Henderson
        return tcg_match_ori(ct, val);
605 48bb3750 Richard Henderson
    } else if (ct & TCG_CT_CONST_XORI) {
606 48bb3750 Richard Henderson
        return tcg_match_xori(ct, val);
607 48bb3750 Richard Henderson
    } else if (ct & TCG_CT_CONST_CMPI) {
608 48bb3750 Richard Henderson
        return tcg_match_cmpi(ct, val);
609 48bb3750 Richard Henderson
    }
610 48bb3750 Richard Henderson
611 2827822e Alexander Graf
    return 0;
612 2827822e Alexander Graf
}
613 2827822e Alexander Graf
614 48bb3750 Richard Henderson
/* Emit instructions according to the given instruction format.  */
615 48bb3750 Richard Henderson
616 48bb3750 Richard Henderson
static void tcg_out_insn_RR(TCGContext *s, S390Opcode op, TCGReg r1, TCGReg r2)
617 48bb3750 Richard Henderson
{
618 48bb3750 Richard Henderson
    tcg_out16(s, (op << 8) | (r1 << 4) | r2);
619 48bb3750 Richard Henderson
}
620 48bb3750 Richard Henderson
621 48bb3750 Richard Henderson
static void tcg_out_insn_RRE(TCGContext *s, S390Opcode op,
622 48bb3750 Richard Henderson
                             TCGReg r1, TCGReg r2)
623 48bb3750 Richard Henderson
{
624 48bb3750 Richard Henderson
    tcg_out32(s, (op << 16) | (r1 << 4) | r2);
625 48bb3750 Richard Henderson
}
626 48bb3750 Richard Henderson
627 48bb3750 Richard Henderson
static void tcg_out_insn_RI(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
628 48bb3750 Richard Henderson
{
629 48bb3750 Richard Henderson
    tcg_out32(s, (op << 16) | (r1 << 20) | (i2 & 0xffff));
630 48bb3750 Richard Henderson
}
631 48bb3750 Richard Henderson
632 48bb3750 Richard Henderson
static void tcg_out_insn_RIL(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
633 48bb3750 Richard Henderson
{
634 48bb3750 Richard Henderson
    tcg_out16(s, op | (r1 << 4));
635 48bb3750 Richard Henderson
    tcg_out32(s, i2);
636 48bb3750 Richard Henderson
}
637 48bb3750 Richard Henderson
638 48bb3750 Richard Henderson
static void tcg_out_insn_RS(TCGContext *s, S390Opcode op, TCGReg r1,
639 48bb3750 Richard Henderson
                            TCGReg b2, TCGReg r3, int disp)
640 48bb3750 Richard Henderson
{
641 48bb3750 Richard Henderson
    tcg_out32(s, (op << 24) | (r1 << 20) | (r3 << 16) | (b2 << 12)
642 48bb3750 Richard Henderson
              | (disp & 0xfff));
643 48bb3750 Richard Henderson
}
644 48bb3750 Richard Henderson
645 48bb3750 Richard Henderson
static void tcg_out_insn_RSY(TCGContext *s, S390Opcode op, TCGReg r1,
646 48bb3750 Richard Henderson
                             TCGReg b2, TCGReg r3, int disp)
647 48bb3750 Richard Henderson
{
648 48bb3750 Richard Henderson
    tcg_out16(s, (op & 0xff00) | (r1 << 4) | r3);
649 48bb3750 Richard Henderson
    tcg_out32(s, (op & 0xff) | (b2 << 28)
650 48bb3750 Richard Henderson
              | ((disp & 0xfff) << 16) | ((disp & 0xff000) >> 4));
651 48bb3750 Richard Henderson
}
652 48bb3750 Richard Henderson
653 48bb3750 Richard Henderson
#define tcg_out_insn_RX   tcg_out_insn_RS
654 48bb3750 Richard Henderson
#define tcg_out_insn_RXY  tcg_out_insn_RSY
655 48bb3750 Richard Henderson
656 48bb3750 Richard Henderson
/* Emit an opcode with "type-checking" of the format.  */
657 48bb3750 Richard Henderson
#define tcg_out_insn(S, FMT, OP, ...) \
658 48bb3750 Richard Henderson
    glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
659 48bb3750 Richard Henderson
660 48bb3750 Richard Henderson
661 48bb3750 Richard Henderson
/* emit 64-bit shifts */
662 48bb3750 Richard Henderson
static void tcg_out_sh64(TCGContext* s, S390Opcode op, TCGReg dest,
663 48bb3750 Richard Henderson
                         TCGReg src, TCGReg sh_reg, int sh_imm)
664 48bb3750 Richard Henderson
{
665 48bb3750 Richard Henderson
    tcg_out_insn_RSY(s, op, dest, sh_reg, src, sh_imm);
666 48bb3750 Richard Henderson
}
667 48bb3750 Richard Henderson
668 48bb3750 Richard Henderson
/* emit 32-bit shifts */
669 48bb3750 Richard Henderson
static void tcg_out_sh32(TCGContext* s, S390Opcode op, TCGReg dest,
670 48bb3750 Richard Henderson
                         TCGReg sh_reg, int sh_imm)
671 48bb3750 Richard Henderson
{
672 48bb3750 Richard Henderson
    tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
673 48bb3750 Richard Henderson
}
674 48bb3750 Richard Henderson
675 48bb3750 Richard Henderson
static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
676 48bb3750 Richard Henderson
{
677 48bb3750 Richard Henderson
    if (src != dst) {
678 48bb3750 Richard Henderson
        if (type == TCG_TYPE_I32) {
679 48bb3750 Richard Henderson
            tcg_out_insn(s, RR, LR, dst, src);
680 48bb3750 Richard Henderson
        } else {
681 48bb3750 Richard Henderson
            tcg_out_insn(s, RRE, LGR, dst, src);
682 48bb3750 Richard Henderson
        }
683 48bb3750 Richard Henderson
    }
684 48bb3750 Richard Henderson
}
685 48bb3750 Richard Henderson
686 2827822e Alexander Graf
/* load a register with an immediate value */
687 48bb3750 Richard Henderson
static void tcg_out_movi(TCGContext *s, TCGType type,
688 48bb3750 Richard Henderson
                         TCGReg ret, tcg_target_long sval)
689 2827822e Alexander Graf
{
690 48bb3750 Richard Henderson
    static const S390Opcode lli_insns[4] = {
691 48bb3750 Richard Henderson
        RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
692 48bb3750 Richard Henderson
    };
693 48bb3750 Richard Henderson
694 48bb3750 Richard Henderson
    tcg_target_ulong uval = sval;
695 48bb3750 Richard Henderson
    int i;
696 48bb3750 Richard Henderson
697 48bb3750 Richard Henderson
    if (type == TCG_TYPE_I32) {
698 48bb3750 Richard Henderson
        uval = (uint32_t)sval;
699 48bb3750 Richard Henderson
        sval = (int32_t)sval;
700 48bb3750 Richard Henderson
    }
701 48bb3750 Richard Henderson
702 48bb3750 Richard Henderson
    /* Try all 32-bit insns that can load it in one go.  */
703 48bb3750 Richard Henderson
    if (sval >= -0x8000 && sval < 0x8000) {
704 48bb3750 Richard Henderson
        tcg_out_insn(s, RI, LGHI, ret, sval);
705 48bb3750 Richard Henderson
        return;
706 48bb3750 Richard Henderson
    }
707 48bb3750 Richard Henderson
708 48bb3750 Richard Henderson
    for (i = 0; i < 4; i++) {
709 48bb3750 Richard Henderson
        tcg_target_long mask = 0xffffull << i*16;
710 48bb3750 Richard Henderson
        if ((uval & mask) == uval) {
711 48bb3750 Richard Henderson
            tcg_out_insn_RI(s, lli_insns[i], ret, uval >> i*16);
712 48bb3750 Richard Henderson
            return;
713 48bb3750 Richard Henderson
        }
714 48bb3750 Richard Henderson
    }
715 48bb3750 Richard Henderson
716 48bb3750 Richard Henderson
    /* Try all 48-bit insns that can load it in one go.  */
717 48bb3750 Richard Henderson
    if (facilities & FACILITY_EXT_IMM) {
718 48bb3750 Richard Henderson
        if (sval == (int32_t)sval) {
719 48bb3750 Richard Henderson
            tcg_out_insn(s, RIL, LGFI, ret, sval);
720 48bb3750 Richard Henderson
            return;
721 48bb3750 Richard Henderson
        }
722 48bb3750 Richard Henderson
        if (uval <= 0xffffffff) {
723 48bb3750 Richard Henderson
            tcg_out_insn(s, RIL, LLILF, ret, uval);
724 48bb3750 Richard Henderson
            return;
725 48bb3750 Richard Henderson
        }
726 48bb3750 Richard Henderson
        if ((uval & 0xffffffff) == 0) {
727 48bb3750 Richard Henderson
            tcg_out_insn(s, RIL, LLIHF, ret, uval >> 31 >> 1);
728 48bb3750 Richard Henderson
            return;
729 48bb3750 Richard Henderson
        }
730 48bb3750 Richard Henderson
    }
731 48bb3750 Richard Henderson
732 48bb3750 Richard Henderson
    /* Try for PC-relative address load.  */
733 48bb3750 Richard Henderson
    if ((sval & 1) == 0) {
734 48bb3750 Richard Henderson
        intptr_t off = (sval - (intptr_t)s->code_ptr) >> 1;
735 48bb3750 Richard Henderson
        if (off == (int32_t)off) {
736 48bb3750 Richard Henderson
            tcg_out_insn(s, RIL, LARL, ret, off);
737 48bb3750 Richard Henderson
            return;
738 48bb3750 Richard Henderson
        }
739 48bb3750 Richard Henderson
    }
740 48bb3750 Richard Henderson
741 48bb3750 Richard Henderson
    /* If extended immediates are not present, then we may have to issue
742 48bb3750 Richard Henderson
       several instructions to load the low 32 bits.  */
743 48bb3750 Richard Henderson
    if (!(facilities & FACILITY_EXT_IMM)) {
744 48bb3750 Richard Henderson
        /* A 32-bit unsigned value can be loaded in 2 insns.  And given
745 48bb3750 Richard Henderson
           that the lli_insns loop above did not succeed, we know that
746 48bb3750 Richard Henderson
           both insns are required.  */
747 48bb3750 Richard Henderson
        if (uval <= 0xffffffff) {
748 48bb3750 Richard Henderson
            tcg_out_insn(s, RI, LLILL, ret, uval);
749 48bb3750 Richard Henderson
            tcg_out_insn(s, RI, IILH, ret, uval >> 16);
750 48bb3750 Richard Henderson
            return;
751 48bb3750 Richard Henderson
        }
752 48bb3750 Richard Henderson
753 48bb3750 Richard Henderson
        /* If all high bits are set, the value can be loaded in 2 or 3 insns.
754 48bb3750 Richard Henderson
           We first want to make sure that all the high bits get set.  With
755 48bb3750 Richard Henderson
           luck the low 16-bits can be considered negative to perform that for
756 48bb3750 Richard Henderson
           free, otherwise we load an explicit -1.  */
757 48bb3750 Richard Henderson
        if (sval >> 31 >> 1 == -1) {
758 48bb3750 Richard Henderson
            if (uval & 0x8000) {
759 48bb3750 Richard Henderson
                tcg_out_insn(s, RI, LGHI, ret, uval);
760 48bb3750 Richard Henderson
            } else {
761 48bb3750 Richard Henderson
                tcg_out_insn(s, RI, LGHI, ret, -1);
762 48bb3750 Richard Henderson
                tcg_out_insn(s, RI, IILL, ret, uval);
763 48bb3750 Richard Henderson
            }
764 48bb3750 Richard Henderson
            tcg_out_insn(s, RI, IILH, ret, uval >> 16);
765 48bb3750 Richard Henderson
            return;
766 48bb3750 Richard Henderson
        }
767 48bb3750 Richard Henderson
    }
768 48bb3750 Richard Henderson
769 48bb3750 Richard Henderson
    /* If we get here, both the high and low parts have non-zero bits.  */
770 48bb3750 Richard Henderson
771 48bb3750 Richard Henderson
    /* Recurse to load the lower 32-bits.  */
772 48bb3750 Richard Henderson
    tcg_out_movi(s, TCG_TYPE_I32, ret, sval);
773 48bb3750 Richard Henderson
774 48bb3750 Richard Henderson
    /* Insert data into the high 32-bits.  */
775 48bb3750 Richard Henderson
    uval = uval >> 31 >> 1;
776 48bb3750 Richard Henderson
    if (facilities & FACILITY_EXT_IMM) {
777 48bb3750 Richard Henderson
        if (uval < 0x10000) {
778 48bb3750 Richard Henderson
            tcg_out_insn(s, RI, IIHL, ret, uval);
779 48bb3750 Richard Henderson
        } else if ((uval & 0xffff) == 0) {
780 48bb3750 Richard Henderson
            tcg_out_insn(s, RI, IIHH, ret, uval >> 16);
781 48bb3750 Richard Henderson
        } else {
782 48bb3750 Richard Henderson
            tcg_out_insn(s, RIL, IIHF, ret, uval);
783 48bb3750 Richard Henderson
        }
784 48bb3750 Richard Henderson
    } else {
785 48bb3750 Richard Henderson
        if (uval & 0xffff) {
786 48bb3750 Richard Henderson
            tcg_out_insn(s, RI, IIHL, ret, uval);
787 48bb3750 Richard Henderson
        }
788 48bb3750 Richard Henderson
        if (uval & 0xffff0000) {
789 48bb3750 Richard Henderson
            tcg_out_insn(s, RI, IIHH, ret, uval >> 16);
790 48bb3750 Richard Henderson
        }
791 48bb3750 Richard Henderson
    }
792 48bb3750 Richard Henderson
}
793 48bb3750 Richard Henderson
794 48bb3750 Richard Henderson
795 48bb3750 Richard Henderson
/* Emit a load/store type instruction.  Inputs are:
796 48bb3750 Richard Henderson
   DATA:     The register to be loaded or stored.
797 48bb3750 Richard Henderson
   BASE+OFS: The effective address.
798 48bb3750 Richard Henderson
   OPC_RX:   If the operation has an RX format opcode (e.g. STC), otherwise 0.
799 48bb3750 Richard Henderson
   OPC_RXY:  The RXY format opcode for the operation (e.g. STCY).  */
800 48bb3750 Richard Henderson
801 48bb3750 Richard Henderson
static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
802 48bb3750 Richard Henderson
                        TCGReg data, TCGReg base, TCGReg index,
803 48bb3750 Richard Henderson
                        tcg_target_long ofs)
804 48bb3750 Richard Henderson
{
805 48bb3750 Richard Henderson
    if (ofs < -0x80000 || ofs >= 0x80000) {
806 48bb3750 Richard Henderson
        /* Combine the low 16 bits of the offset with the actual load insn;
807 48bb3750 Richard Henderson
           the high 48 bits must come from an immediate load.  */
808 48bb3750 Richard Henderson
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs & ~0xffff);
809 48bb3750 Richard Henderson
        ofs &= 0xffff;
810 48bb3750 Richard Henderson
811 48bb3750 Richard Henderson
        /* If we were already given an index register, add it in.  */
812 48bb3750 Richard Henderson
        if (index != TCG_REG_NONE) {
813 48bb3750 Richard Henderson
            tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
814 48bb3750 Richard Henderson
        }
815 48bb3750 Richard Henderson
        index = TCG_TMP0;
816 48bb3750 Richard Henderson
    }
817 48bb3750 Richard Henderson
818 48bb3750 Richard Henderson
    if (opc_rx && ofs >= 0 && ofs < 0x1000) {
819 48bb3750 Richard Henderson
        tcg_out_insn_RX(s, opc_rx, data, base, index, ofs);
820 48bb3750 Richard Henderson
    } else {
821 48bb3750 Richard Henderson
        tcg_out_insn_RXY(s, opc_rxy, data, base, index, ofs);
822 48bb3750 Richard Henderson
    }
823 2827822e Alexander Graf
}
824 2827822e Alexander Graf
825 48bb3750 Richard Henderson
826 2827822e Alexander Graf
/* load data without address translation or endianness conversion */
827 48bb3750 Richard Henderson
static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
828 48bb3750 Richard Henderson
                              TCGReg base, tcg_target_long ofs)
829 2827822e Alexander Graf
{
830 48bb3750 Richard Henderson
    if (type == TCG_TYPE_I32) {
831 48bb3750 Richard Henderson
        tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs);
832 48bb3750 Richard Henderson
    } else {
833 48bb3750 Richard Henderson
        tcg_out_mem(s, 0, RXY_LG, data, base, TCG_REG_NONE, ofs);
834 48bb3750 Richard Henderson
    }
835 2827822e Alexander Graf
}
836 2827822e Alexander Graf
837 48bb3750 Richard Henderson
static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
838 48bb3750 Richard Henderson
                              TCGReg base, tcg_target_long ofs)
839 2827822e Alexander Graf
{
840 48bb3750 Richard Henderson
    if (type == TCG_TYPE_I32) {
841 48bb3750 Richard Henderson
        tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs);
842 48bb3750 Richard Henderson
    } else {
843 48bb3750 Richard Henderson
        tcg_out_mem(s, 0, RXY_STG, data, base, TCG_REG_NONE, ofs);
844 48bb3750 Richard Henderson
    }
845 48bb3750 Richard Henderson
}
846 48bb3750 Richard Henderson
847 48bb3750 Richard Henderson
/* load data from an absolute host address */
848 48bb3750 Richard Henderson
static void tcg_out_ld_abs(TCGContext *s, TCGType type, TCGReg dest, void *abs)
849 48bb3750 Richard Henderson
{
850 48bb3750 Richard Henderson
    tcg_target_long addr = (tcg_target_long)abs;
851 48bb3750 Richard Henderson
852 48bb3750 Richard Henderson
    if (facilities & FACILITY_GEN_INST_EXT) {
853 48bb3750 Richard Henderson
        tcg_target_long disp = (addr - (tcg_target_long)s->code_ptr) >> 1;
854 48bb3750 Richard Henderson
        if (disp == (int32_t)disp) {
855 48bb3750 Richard Henderson
            if (type == TCG_TYPE_I32) {
856 48bb3750 Richard Henderson
                tcg_out_insn(s, RIL, LRL, dest, disp);
857 48bb3750 Richard Henderson
            } else {
858 48bb3750 Richard Henderson
                tcg_out_insn(s, RIL, LGRL, dest, disp);
859 48bb3750 Richard Henderson
            }
860 48bb3750 Richard Henderson
            return;
861 48bb3750 Richard Henderson
        }
862 48bb3750 Richard Henderson
    }
863 48bb3750 Richard Henderson
864 48bb3750 Richard Henderson
    tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
865 48bb3750 Richard Henderson
    tcg_out_ld(s, type, dest, dest, addr & 0xffff);
866 48bb3750 Richard Henderson
}
867 48bb3750 Richard Henderson
868 48bb3750 Richard Henderson
static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
869 48bb3750 Richard Henderson
{
870 48bb3750 Richard Henderson
    if (facilities & FACILITY_EXT_IMM) {
871 48bb3750 Richard Henderson
        tcg_out_insn(s, RRE, LGBR, dest, src);
872 48bb3750 Richard Henderson
        return;
873 48bb3750 Richard Henderson
    }
874 48bb3750 Richard Henderson
875 48bb3750 Richard Henderson
    if (type == TCG_TYPE_I32) {
876 48bb3750 Richard Henderson
        if (dest == src) {
877 48bb3750 Richard Henderson
            tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 24);
878 48bb3750 Richard Henderson
        } else {
879 48bb3750 Richard Henderson
            tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 24);
880 48bb3750 Richard Henderson
        }
881 48bb3750 Richard Henderson
        tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 24);
882 48bb3750 Richard Henderson
    } else {
883 48bb3750 Richard Henderson
        tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 56);
884 48bb3750 Richard Henderson
        tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 56);
885 48bb3750 Richard Henderson
    }
886 48bb3750 Richard Henderson
}
887 48bb3750 Richard Henderson
888 48bb3750 Richard Henderson
static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
889 48bb3750 Richard Henderson
{
890 48bb3750 Richard Henderson
    if (facilities & FACILITY_EXT_IMM) {
891 48bb3750 Richard Henderson
        tcg_out_insn(s, RRE, LLGCR, dest, src);
892 48bb3750 Richard Henderson
        return;
893 48bb3750 Richard Henderson
    }
894 48bb3750 Richard Henderson
895 48bb3750 Richard Henderson
    if (dest == src) {
896 48bb3750 Richard Henderson
        tcg_out_movi(s, type, TCG_TMP0, 0xff);
897 48bb3750 Richard Henderson
        src = TCG_TMP0;
898 48bb3750 Richard Henderson
    } else {
899 48bb3750 Richard Henderson
        tcg_out_movi(s, type, dest, 0xff);
900 48bb3750 Richard Henderson
    }
901 48bb3750 Richard Henderson
    if (type == TCG_TYPE_I32) {
902 48bb3750 Richard Henderson
        tcg_out_insn(s, RR, NR, dest, src);
903 48bb3750 Richard Henderson
    } else {
904 48bb3750 Richard Henderson
        tcg_out_insn(s, RRE, NGR, dest, src);
905 48bb3750 Richard Henderson
    }
906 48bb3750 Richard Henderson
}
907 48bb3750 Richard Henderson
908 48bb3750 Richard Henderson
static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
909 48bb3750 Richard Henderson
{
910 48bb3750 Richard Henderson
    if (facilities & FACILITY_EXT_IMM) {
911 48bb3750 Richard Henderson
        tcg_out_insn(s, RRE, LGHR, dest, src);
912 48bb3750 Richard Henderson
        return;
913 48bb3750 Richard Henderson
    }
914 48bb3750 Richard Henderson
915 48bb3750 Richard Henderson
    if (type == TCG_TYPE_I32) {
916 48bb3750 Richard Henderson
        if (dest == src) {
917 48bb3750 Richard Henderson
            tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 16);
918 48bb3750 Richard Henderson
        } else {
919 48bb3750 Richard Henderson
            tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 16);
920 48bb3750 Richard Henderson
        }
921 48bb3750 Richard Henderson
        tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 16);
922 48bb3750 Richard Henderson
    } else {
923 48bb3750 Richard Henderson
        tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 48);
924 48bb3750 Richard Henderson
        tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 48);
925 48bb3750 Richard Henderson
    }
926 48bb3750 Richard Henderson
}
927 48bb3750 Richard Henderson
928 48bb3750 Richard Henderson
static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
929 48bb3750 Richard Henderson
{
930 48bb3750 Richard Henderson
    if (facilities & FACILITY_EXT_IMM) {
931 48bb3750 Richard Henderson
        tcg_out_insn(s, RRE, LLGHR, dest, src);
932 48bb3750 Richard Henderson
        return;
933 48bb3750 Richard Henderson
    }
934 48bb3750 Richard Henderson
935 48bb3750 Richard Henderson
    if (dest == src) {
936 48bb3750 Richard Henderson
        tcg_out_movi(s, type, TCG_TMP0, 0xffff);
937 48bb3750 Richard Henderson
        src = TCG_TMP0;
938 48bb3750 Richard Henderson
    } else {
939 48bb3750 Richard Henderson
        tcg_out_movi(s, type, dest, 0xffff);
940 48bb3750 Richard Henderson
    }
941 48bb3750 Richard Henderson
    if (type == TCG_TYPE_I32) {
942 48bb3750 Richard Henderson
        tcg_out_insn(s, RR, NR, dest, src);
943 48bb3750 Richard Henderson
    } else {
944 48bb3750 Richard Henderson
        tcg_out_insn(s, RRE, NGR, dest, src);
945 48bb3750 Richard Henderson
    }
946 48bb3750 Richard Henderson
}
947 48bb3750 Richard Henderson
948 48bb3750 Richard Henderson
static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
949 48bb3750 Richard Henderson
{
950 48bb3750 Richard Henderson
    tcg_out_insn(s, RRE, LGFR, dest, src);
951 48bb3750 Richard Henderson
}
952 48bb3750 Richard Henderson
953 48bb3750 Richard Henderson
static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
954 48bb3750 Richard Henderson
{
955 48bb3750 Richard Henderson
    tcg_out_insn(s, RRE, LLGFR, dest, src);
956 48bb3750 Richard Henderson
}
957 48bb3750 Richard Henderson
958 48bb3750 Richard Henderson
static inline void tgen32_addi(TCGContext *s, TCGReg dest, int32_t val)
959 48bb3750 Richard Henderson
{
960 48bb3750 Richard Henderson
    if (val == (int16_t)val) {
961 48bb3750 Richard Henderson
        tcg_out_insn(s, RI, AHI, dest, val);
962 48bb3750 Richard Henderson
    } else {
963 48bb3750 Richard Henderson
        tcg_out_insn(s, RIL, AFI, dest, val);
964 48bb3750 Richard Henderson
    }
965 48bb3750 Richard Henderson
}
966 48bb3750 Richard Henderson
967 48bb3750 Richard Henderson
static inline void tgen64_addi(TCGContext *s, TCGReg dest, int64_t val)
968 48bb3750 Richard Henderson
{
969 48bb3750 Richard Henderson
    if (val == (int16_t)val) {
970 48bb3750 Richard Henderson
        tcg_out_insn(s, RI, AGHI, dest, val);
971 48bb3750 Richard Henderson
    } else if (val == (int32_t)val) {
972 48bb3750 Richard Henderson
        tcg_out_insn(s, RIL, AGFI, dest, val);
973 48bb3750 Richard Henderson
    } else if (val == (uint32_t)val) {
974 48bb3750 Richard Henderson
        tcg_out_insn(s, RIL, ALGFI, dest, val);
975 48bb3750 Richard Henderson
    } else {
976 48bb3750 Richard Henderson
        tcg_abort();
977 48bb3750 Richard Henderson
    }
978 48bb3750 Richard Henderson
979 48bb3750 Richard Henderson
}
980 48bb3750 Richard Henderson
981 48bb3750 Richard Henderson
static void tgen64_andi(TCGContext *s, TCGReg dest, tcg_target_ulong val)
982 48bb3750 Richard Henderson
{
983 48bb3750 Richard Henderson
    static const S390Opcode ni_insns[4] = {
984 48bb3750 Richard Henderson
        RI_NILL, RI_NILH, RI_NIHL, RI_NIHH
985 48bb3750 Richard Henderson
    };
986 48bb3750 Richard Henderson
    static const S390Opcode nif_insns[2] = {
987 48bb3750 Richard Henderson
        RIL_NILF, RIL_NIHF
988 48bb3750 Richard Henderson
    };
989 48bb3750 Richard Henderson
990 48bb3750 Richard Henderson
    int i;
991 48bb3750 Richard Henderson
992 48bb3750 Richard Henderson
    /* Look for no-op.  */
993 48bb3750 Richard Henderson
    if (val == -1) {
994 48bb3750 Richard Henderson
        return;
995 48bb3750 Richard Henderson
    }
996 48bb3750 Richard Henderson
997 48bb3750 Richard Henderson
    /* Look for the zero-extensions.  */
998 48bb3750 Richard Henderson
    if (val == 0xffffffff) {
999 48bb3750 Richard Henderson
        tgen_ext32u(s, dest, dest);
1000 48bb3750 Richard Henderson
        return;
1001 48bb3750 Richard Henderson
    }
1002 48bb3750 Richard Henderson
1003 48bb3750 Richard Henderson
    if (facilities & FACILITY_EXT_IMM) {
1004 48bb3750 Richard Henderson
        if (val == 0xff) {
1005 48bb3750 Richard Henderson
            tgen_ext8u(s, TCG_TYPE_I64, dest, dest);
1006 48bb3750 Richard Henderson
            return;
1007 48bb3750 Richard Henderson
        }
1008 48bb3750 Richard Henderson
        if (val == 0xffff) {
1009 48bb3750 Richard Henderson
            tgen_ext16u(s, TCG_TYPE_I64, dest, dest);
1010 48bb3750 Richard Henderson
            return;
1011 48bb3750 Richard Henderson
        }
1012 48bb3750 Richard Henderson
1013 48bb3750 Richard Henderson
        /* Try all 32-bit insns that can perform it in one go.  */
1014 48bb3750 Richard Henderson
        for (i = 0; i < 4; i++) {
1015 48bb3750 Richard Henderson
            tcg_target_ulong mask = ~(0xffffull << i*16);
1016 48bb3750 Richard Henderson
            if ((val & mask) == mask) {
1017 48bb3750 Richard Henderson
                tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
1018 48bb3750 Richard Henderson
                return;
1019 48bb3750 Richard Henderson
            }
1020 48bb3750 Richard Henderson
        }
1021 48bb3750 Richard Henderson
1022 48bb3750 Richard Henderson
        /* Try all 48-bit insns that can perform it in one go.  */
1023 48bb3750 Richard Henderson
        if (facilities & FACILITY_EXT_IMM) {
1024 48bb3750 Richard Henderson
            for (i = 0; i < 2; i++) {
1025 48bb3750 Richard Henderson
                tcg_target_ulong mask = ~(0xffffffffull << i*32);
1026 48bb3750 Richard Henderson
                if ((val & mask) == mask) {
1027 48bb3750 Richard Henderson
                    tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
1028 48bb3750 Richard Henderson
                    return;
1029 48bb3750 Richard Henderson
                }
1030 48bb3750 Richard Henderson
            }
1031 48bb3750 Richard Henderson
        }
1032 48bb3750 Richard Henderson
1033 48bb3750 Richard Henderson
        /* Perform the AND via sequential modifications to the high and low
1034 48bb3750 Richard Henderson
           parts.  Do this via recursion to handle 16-bit vs 32-bit masks in
1035 48bb3750 Richard Henderson
           each half.  */
1036 48bb3750 Richard Henderson
        tgen64_andi(s, dest, val | 0xffffffff00000000ull);
1037 48bb3750 Richard Henderson
        tgen64_andi(s, dest, val | 0x00000000ffffffffull);
1038 48bb3750 Richard Henderson
    } else {
1039 48bb3750 Richard Henderson
        /* With no extended-immediate facility, just emit the sequence.  */
1040 48bb3750 Richard Henderson
        for (i = 0; i < 4; i++) {
1041 48bb3750 Richard Henderson
            tcg_target_ulong mask = 0xffffull << i*16;
1042 48bb3750 Richard Henderson
            if ((val & mask) != mask) {
1043 48bb3750 Richard Henderson
                tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
1044 48bb3750 Richard Henderson
            }
1045 48bb3750 Richard Henderson
        }
1046 48bb3750 Richard Henderson
    }
1047 48bb3750 Richard Henderson
}
1048 48bb3750 Richard Henderson
1049 48bb3750 Richard Henderson
static void tgen64_ori(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1050 48bb3750 Richard Henderson
{
1051 48bb3750 Richard Henderson
    static const S390Opcode oi_insns[4] = {
1052 48bb3750 Richard Henderson
        RI_OILL, RI_OILH, RI_OIHL, RI_OIHH
1053 48bb3750 Richard Henderson
    };
1054 48bb3750 Richard Henderson
    static const S390Opcode nif_insns[2] = {
1055 48bb3750 Richard Henderson
        RIL_OILF, RIL_OIHF
1056 48bb3750 Richard Henderson
    };
1057 48bb3750 Richard Henderson
1058 48bb3750 Richard Henderson
    int i;
1059 48bb3750 Richard Henderson
1060 48bb3750 Richard Henderson
    /* Look for no-op.  */
1061 48bb3750 Richard Henderson
    if (val == 0) {
1062 48bb3750 Richard Henderson
        return;
1063 48bb3750 Richard Henderson
    }
1064 48bb3750 Richard Henderson
1065 48bb3750 Richard Henderson
    if (facilities & FACILITY_EXT_IMM) {
1066 48bb3750 Richard Henderson
        /* Try all 32-bit insns that can perform it in one go.  */
1067 48bb3750 Richard Henderson
        for (i = 0; i < 4; i++) {
1068 48bb3750 Richard Henderson
            tcg_target_ulong mask = (0xffffull << i*16);
1069 48bb3750 Richard Henderson
            if ((val & mask) != 0 && (val & ~mask) == 0) {
1070 48bb3750 Richard Henderson
                tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
1071 48bb3750 Richard Henderson
                return;
1072 48bb3750 Richard Henderson
            }
1073 48bb3750 Richard Henderson
        }
1074 48bb3750 Richard Henderson
1075 48bb3750 Richard Henderson
        /* Try all 48-bit insns that can perform it in one go.  */
1076 48bb3750 Richard Henderson
        for (i = 0; i < 2; i++) {
1077 48bb3750 Richard Henderson
            tcg_target_ulong mask = (0xffffffffull << i*32);
1078 48bb3750 Richard Henderson
            if ((val & mask) != 0 && (val & ~mask) == 0) {
1079 48bb3750 Richard Henderson
                tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
1080 48bb3750 Richard Henderson
                return;
1081 48bb3750 Richard Henderson
            }
1082 48bb3750 Richard Henderson
        }
1083 48bb3750 Richard Henderson
1084 48bb3750 Richard Henderson
        /* Perform the OR via sequential modifications to the high and
1085 48bb3750 Richard Henderson
           low parts.  Do this via recursion to handle 16-bit vs 32-bit
1086 48bb3750 Richard Henderson
           masks in each half.  */
1087 48bb3750 Richard Henderson
        tgen64_ori(s, dest, val & 0x00000000ffffffffull);
1088 48bb3750 Richard Henderson
        tgen64_ori(s, dest, val & 0xffffffff00000000ull);
1089 48bb3750 Richard Henderson
    } else {
1090 48bb3750 Richard Henderson
        /* With no extended-immediate facility, we don't need to be so
1091 48bb3750 Richard Henderson
           clever.  Just iterate over the insns and mask in the constant.  */
1092 48bb3750 Richard Henderson
        for (i = 0; i < 4; i++) {
1093 48bb3750 Richard Henderson
            tcg_target_ulong mask = (0xffffull << i*16);
1094 48bb3750 Richard Henderson
            if ((val & mask) != 0) {
1095 48bb3750 Richard Henderson
                tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
1096 48bb3750 Richard Henderson
            }
1097 48bb3750 Richard Henderson
        }
1098 48bb3750 Richard Henderson
    }
1099 48bb3750 Richard Henderson
}
1100 48bb3750 Richard Henderson
1101 48bb3750 Richard Henderson
static void tgen64_xori(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1102 48bb3750 Richard Henderson
{
1103 48bb3750 Richard Henderson
    /* Perform the xor by parts.  */
1104 48bb3750 Richard Henderson
    if (val & 0xffffffff) {
1105 48bb3750 Richard Henderson
        tcg_out_insn(s, RIL, XILF, dest, val);
1106 48bb3750 Richard Henderson
    }
1107 48bb3750 Richard Henderson
    if (val > 0xffffffff) {
1108 48bb3750 Richard Henderson
        tcg_out_insn(s, RIL, XIHF, dest, val >> 31 >> 1);
1109 48bb3750 Richard Henderson
    }
1110 48bb3750 Richard Henderson
}
1111 48bb3750 Richard Henderson
1112 48bb3750 Richard Henderson
static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
1113 48bb3750 Richard Henderson
                    TCGArg c2, int c2const)
1114 48bb3750 Richard Henderson
{
1115 48bb3750 Richard Henderson
    bool is_unsigned = (c > TCG_COND_GT);
1116 48bb3750 Richard Henderson
    if (c2const) {
1117 48bb3750 Richard Henderson
        if (c2 == 0) {
1118 48bb3750 Richard Henderson
            if (type == TCG_TYPE_I32) {
1119 48bb3750 Richard Henderson
                tcg_out_insn(s, RR, LTR, r1, r1);
1120 48bb3750 Richard Henderson
            } else {
1121 48bb3750 Richard Henderson
                tcg_out_insn(s, RRE, LTGR, r1, r1);
1122 48bb3750 Richard Henderson
            }
1123 48bb3750 Richard Henderson
            return tcg_cond_to_ltr_cond[c];
1124 48bb3750 Richard Henderson
        } else {
1125 48bb3750 Richard Henderson
            if (is_unsigned) {
1126 48bb3750 Richard Henderson
                if (type == TCG_TYPE_I32) {
1127 48bb3750 Richard Henderson
                    tcg_out_insn(s, RIL, CLFI, r1, c2);
1128 48bb3750 Richard Henderson
                } else {
1129 48bb3750 Richard Henderson
                    tcg_out_insn(s, RIL, CLGFI, r1, c2);
1130 48bb3750 Richard Henderson
                }
1131 48bb3750 Richard Henderson
            } else {
1132 48bb3750 Richard Henderson
                if (type == TCG_TYPE_I32) {
1133 48bb3750 Richard Henderson
                    tcg_out_insn(s, RIL, CFI, r1, c2);
1134 48bb3750 Richard Henderson
                } else {
1135 48bb3750 Richard Henderson
                    tcg_out_insn(s, RIL, CGFI, r1, c2);
1136 48bb3750 Richard Henderson
                }
1137 48bb3750 Richard Henderson
            }
1138 48bb3750 Richard Henderson
        }
1139 48bb3750 Richard Henderson
    } else {
1140 48bb3750 Richard Henderson
        if (is_unsigned) {
1141 48bb3750 Richard Henderson
            if (type == TCG_TYPE_I32) {
1142 48bb3750 Richard Henderson
                tcg_out_insn(s, RR, CLR, r1, c2);
1143 48bb3750 Richard Henderson
            } else {
1144 48bb3750 Richard Henderson
                tcg_out_insn(s, RRE, CLGR, r1, c2);
1145 48bb3750 Richard Henderson
            }
1146 48bb3750 Richard Henderson
        } else {
1147 48bb3750 Richard Henderson
            if (type == TCG_TYPE_I32) {
1148 48bb3750 Richard Henderson
                tcg_out_insn(s, RR, CR, r1, c2);
1149 48bb3750 Richard Henderson
            } else {
1150 48bb3750 Richard Henderson
                tcg_out_insn(s, RRE, CGR, r1, c2);
1151 48bb3750 Richard Henderson
            }
1152 48bb3750 Richard Henderson
        }
1153 48bb3750 Richard Henderson
    }
1154 48bb3750 Richard Henderson
    return tcg_cond_to_s390_cond[c];
1155 48bb3750 Richard Henderson
}
1156 48bb3750 Richard Henderson
1157 48bb3750 Richard Henderson
static void tgen_setcond(TCGContext *s, TCGType type, TCGCond c,
1158 48bb3750 Richard Henderson
                         TCGReg dest, TCGReg r1, TCGArg c2, int c2const)
1159 48bb3750 Richard Henderson
{
1160 48bb3750 Richard Henderson
    int cc = tgen_cmp(s, type, c, r1, c2, c2const);
1161 48bb3750 Richard Henderson
1162 48bb3750 Richard Henderson
    /* Emit: r1 = 1; if (cc) goto over; r1 = 0; over:  */
1163 48bb3750 Richard Henderson
    tcg_out_movi(s, type, dest, 1);
1164 48bb3750 Richard Henderson
    tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1165 48bb3750 Richard Henderson
    tcg_out_movi(s, type, dest, 0);
1166 48bb3750 Richard Henderson
}
1167 48bb3750 Richard Henderson
1168 48bb3750 Richard Henderson
static void tgen_gotoi(TCGContext *s, int cc, tcg_target_long dest)
1169 48bb3750 Richard Henderson
{
1170 48bb3750 Richard Henderson
    tcg_target_long off = (dest - (tcg_target_long)s->code_ptr) >> 1;
1171 48bb3750 Richard Henderson
    if (off > -0x8000 && off < 0x7fff) {
1172 48bb3750 Richard Henderson
        tcg_out_insn(s, RI, BRC, cc, off);
1173 48bb3750 Richard Henderson
    } else if (off == (int32_t)off) {
1174 48bb3750 Richard Henderson
        tcg_out_insn(s, RIL, BRCL, cc, off);
1175 48bb3750 Richard Henderson
    } else {
1176 48bb3750 Richard Henderson
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, dest);
1177 48bb3750 Richard Henderson
        tcg_out_insn(s, RR, BCR, cc, TCG_TMP0);
1178 48bb3750 Richard Henderson
    }
1179 48bb3750 Richard Henderson
}
1180 48bb3750 Richard Henderson
1181 48bb3750 Richard Henderson
static void tgen_branch(TCGContext *s, int cc, int labelno)
1182 48bb3750 Richard Henderson
{
1183 48bb3750 Richard Henderson
    TCGLabel* l = &s->labels[labelno];
1184 48bb3750 Richard Henderson
    if (l->has_value) {
1185 48bb3750 Richard Henderson
        tgen_gotoi(s, cc, l->u.value);
1186 48bb3750 Richard Henderson
    } else if (USE_LONG_BRANCHES) {
1187 48bb3750 Richard Henderson
        tcg_out16(s, RIL_BRCL | (cc << 4));
1188 48bb3750 Richard Henderson
        tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, labelno, -2);
1189 48bb3750 Richard Henderson
        s->code_ptr += 4;
1190 48bb3750 Richard Henderson
    } else {
1191 48bb3750 Richard Henderson
        tcg_out16(s, RI_BRC | (cc << 4));
1192 48bb3750 Richard Henderson
        tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, labelno, -2);
1193 48bb3750 Richard Henderson
        s->code_ptr += 2;
1194 48bb3750 Richard Henderson
    }
1195 48bb3750 Richard Henderson
}
1196 48bb3750 Richard Henderson
1197 48bb3750 Richard Henderson
static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
1198 48bb3750 Richard Henderson
                                TCGReg r1, TCGReg r2, int labelno)
1199 48bb3750 Richard Henderson
{
1200 48bb3750 Richard Henderson
    TCGLabel* l = &s->labels[labelno];
1201 48bb3750 Richard Henderson
    tcg_target_long off;
1202 48bb3750 Richard Henderson
1203 48bb3750 Richard Henderson
    if (l->has_value) {
1204 48bb3750 Richard Henderson
        off = (l->u.value - (tcg_target_long)s->code_ptr) >> 1;
1205 48bb3750 Richard Henderson
    } else {
1206 48bb3750 Richard Henderson
        /* We need to keep the offset unchanged for retranslation.  */
1207 48bb3750 Richard Henderson
        off = ((int16_t *)s->code_ptr)[1];
1208 48bb3750 Richard Henderson
        tcg_out_reloc(s, s->code_ptr + 2, R_390_PC16DBL, labelno, -2);
1209 48bb3750 Richard Henderson
    }
1210 48bb3750 Richard Henderson
1211 48bb3750 Richard Henderson
    tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
1212 48bb3750 Richard Henderson
    tcg_out16(s, off);
1213 48bb3750 Richard Henderson
    tcg_out16(s, cc << 12 | (opc & 0xff));
1214 48bb3750 Richard Henderson
}
1215 48bb3750 Richard Henderson
1216 48bb3750 Richard Henderson
static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
1217 48bb3750 Richard Henderson
                                    TCGReg r1, int i2, int labelno)
1218 48bb3750 Richard Henderson
{
1219 48bb3750 Richard Henderson
    TCGLabel* l = &s->labels[labelno];
1220 48bb3750 Richard Henderson
    tcg_target_long off;
1221 48bb3750 Richard Henderson
1222 48bb3750 Richard Henderson
    if (l->has_value) {
1223 48bb3750 Richard Henderson
        off = (l->u.value - (tcg_target_long)s->code_ptr) >> 1;
1224 48bb3750 Richard Henderson
    } else {
1225 48bb3750 Richard Henderson
        /* We need to keep the offset unchanged for retranslation.  */
1226 48bb3750 Richard Henderson
        off = ((int16_t *)s->code_ptr)[1];
1227 48bb3750 Richard Henderson
        tcg_out_reloc(s, s->code_ptr + 2, R_390_PC16DBL, labelno, -2);
1228 48bb3750 Richard Henderson
    }
1229 48bb3750 Richard Henderson
1230 48bb3750 Richard Henderson
    tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
1231 48bb3750 Richard Henderson
    tcg_out16(s, off);
1232 48bb3750 Richard Henderson
    tcg_out16(s, (i2 << 8) | (opc & 0xff));
1233 48bb3750 Richard Henderson
}
1234 48bb3750 Richard Henderson
1235 48bb3750 Richard Henderson
static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
1236 48bb3750 Richard Henderson
                        TCGReg r1, TCGArg c2, int c2const, int labelno)
1237 48bb3750 Richard Henderson
{
1238 48bb3750 Richard Henderson
    int cc;
1239 48bb3750 Richard Henderson
1240 48bb3750 Richard Henderson
    if (facilities & FACILITY_GEN_INST_EXT) {
1241 48bb3750 Richard Henderson
        bool is_unsigned = (c > TCG_COND_GT);
1242 48bb3750 Richard Henderson
        bool in_range;
1243 48bb3750 Richard Henderson
        S390Opcode opc;
1244 48bb3750 Richard Henderson
1245 48bb3750 Richard Henderson
        cc = tcg_cond_to_s390_cond[c];
1246 48bb3750 Richard Henderson
1247 48bb3750 Richard Henderson
        if (!c2const) {
1248 48bb3750 Richard Henderson
            opc = (type == TCG_TYPE_I32
1249 48bb3750 Richard Henderson
                   ? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
1250 48bb3750 Richard Henderson
                   : (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
1251 48bb3750 Richard Henderson
            tgen_compare_branch(s, opc, cc, r1, c2, labelno);
1252 48bb3750 Richard Henderson
            return;
1253 48bb3750 Richard Henderson
        }
1254 48bb3750 Richard Henderson
1255 48bb3750 Richard Henderson
        /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1256 48bb3750 Richard Henderson
           If the immediate we've been given does not fit that range, we'll
1257 48bb3750 Richard Henderson
           fall back to separate compare and branch instructions using the
1258 48bb3750 Richard Henderson
           larger comparison range afforded by COMPARE IMMEDIATE.  */
1259 48bb3750 Richard Henderson
        if (type == TCG_TYPE_I32) {
1260 48bb3750 Richard Henderson
            if (is_unsigned) {
1261 48bb3750 Richard Henderson
                opc = RIE_CLIJ;
1262 48bb3750 Richard Henderson
                in_range = (uint32_t)c2 == (uint8_t)c2;
1263 48bb3750 Richard Henderson
            } else {
1264 48bb3750 Richard Henderson
                opc = RIE_CIJ;
1265 48bb3750 Richard Henderson
                in_range = (int32_t)c2 == (int8_t)c2;
1266 48bb3750 Richard Henderson
            }
1267 48bb3750 Richard Henderson
        } else {
1268 48bb3750 Richard Henderson
            if (is_unsigned) {
1269 48bb3750 Richard Henderson
                opc = RIE_CLGIJ;
1270 48bb3750 Richard Henderson
                in_range = (uint64_t)c2 == (uint8_t)c2;
1271 48bb3750 Richard Henderson
            } else {
1272 48bb3750 Richard Henderson
                opc = RIE_CGIJ;
1273 48bb3750 Richard Henderson
                in_range = (int64_t)c2 == (int8_t)c2;
1274 48bb3750 Richard Henderson
            }
1275 48bb3750 Richard Henderson
        }
1276 48bb3750 Richard Henderson
        if (in_range) {
1277 48bb3750 Richard Henderson
            tgen_compare_imm_branch(s, opc, cc, r1, c2, labelno);
1278 48bb3750 Richard Henderson
            return;
1279 48bb3750 Richard Henderson
        }
1280 48bb3750 Richard Henderson
    }
1281 48bb3750 Richard Henderson
1282 48bb3750 Richard Henderson
    cc = tgen_cmp(s, type, c, r1, c2, c2const);
1283 48bb3750 Richard Henderson
    tgen_branch(s, cc, labelno);
1284 48bb3750 Richard Henderson
}
1285 48bb3750 Richard Henderson
1286 48bb3750 Richard Henderson
static void tgen_calli(TCGContext *s, tcg_target_long dest)
1287 48bb3750 Richard Henderson
{
1288 48bb3750 Richard Henderson
    tcg_target_long off = (dest - (tcg_target_long)s->code_ptr) >> 1;
1289 48bb3750 Richard Henderson
    if (off == (int32_t)off) {
1290 48bb3750 Richard Henderson
        tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
1291 48bb3750 Richard Henderson
    } else {
1292 48bb3750 Richard Henderson
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, dest);
1293 48bb3750 Richard Henderson
        tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_TMP0);
1294 48bb3750 Richard Henderson
    }
1295 48bb3750 Richard Henderson
}
1296 48bb3750 Richard Henderson
1297 48bb3750 Richard Henderson
static void tcg_out_qemu_ld_direct(TCGContext *s, int opc, TCGReg data,
1298 48bb3750 Richard Henderson
                                   TCGReg base, TCGReg index, int disp)
1299 48bb3750 Richard Henderson
{
1300 48bb3750 Richard Henderson
#ifdef TARGET_WORDS_BIGENDIAN
1301 48bb3750 Richard Henderson
    const int bswap = 0;
1302 48bb3750 Richard Henderson
#else
1303 48bb3750 Richard Henderson
    const int bswap = 1;
1304 48bb3750 Richard Henderson
#endif
1305 48bb3750 Richard Henderson
    switch (opc) {
1306 48bb3750 Richard Henderson
    case LD_UINT8:
1307 48bb3750 Richard Henderson
        tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
1308 48bb3750 Richard Henderson
        break;
1309 48bb3750 Richard Henderson
    case LD_INT8:
1310 48bb3750 Richard Henderson
        tcg_out_insn(s, RXY, LGB, data, base, index, disp);
1311 48bb3750 Richard Henderson
        break;
1312 48bb3750 Richard Henderson
    case LD_UINT16:
1313 48bb3750 Richard Henderson
        if (bswap) {
1314 48bb3750 Richard Henderson
            /* swapped unsigned halfword load with upper bits zeroed */
1315 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1316 48bb3750 Richard Henderson
            tgen_ext16u(s, TCG_TYPE_I64, data, data);
1317 48bb3750 Richard Henderson
        } else {
1318 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
1319 48bb3750 Richard Henderson
        }
1320 48bb3750 Richard Henderson
        break;
1321 48bb3750 Richard Henderson
    case LD_INT16:
1322 48bb3750 Richard Henderson
        if (bswap) {
1323 48bb3750 Richard Henderson
            /* swapped sign-extended halfword load */
1324 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1325 48bb3750 Richard Henderson
            tgen_ext16s(s, TCG_TYPE_I64, data, data);
1326 48bb3750 Richard Henderson
        } else {
1327 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, LGH, data, base, index, disp);
1328 48bb3750 Richard Henderson
        }
1329 48bb3750 Richard Henderson
        break;
1330 48bb3750 Richard Henderson
    case LD_UINT32:
1331 48bb3750 Richard Henderson
        if (bswap) {
1332 48bb3750 Richard Henderson
            /* swapped unsigned int load with upper bits zeroed */
1333 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1334 48bb3750 Richard Henderson
            tgen_ext32u(s, data, data);
1335 48bb3750 Richard Henderson
        } else {
1336 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
1337 48bb3750 Richard Henderson
        }
1338 48bb3750 Richard Henderson
        break;
1339 48bb3750 Richard Henderson
    case LD_INT32:
1340 48bb3750 Richard Henderson
        if (bswap) {
1341 48bb3750 Richard Henderson
            /* swapped sign-extended int load */
1342 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1343 48bb3750 Richard Henderson
            tgen_ext32s(s, data, data);
1344 48bb3750 Richard Henderson
        } else {
1345 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, LGF, data, base, index, disp);
1346 48bb3750 Richard Henderson
        }
1347 48bb3750 Richard Henderson
        break;
1348 48bb3750 Richard Henderson
    case LD_UINT64:
1349 48bb3750 Richard Henderson
        if (bswap) {
1350 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
1351 48bb3750 Richard Henderson
        } else {
1352 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, LG, data, base, index, disp);
1353 48bb3750 Richard Henderson
        }
1354 48bb3750 Richard Henderson
        break;
1355 48bb3750 Richard Henderson
    default:
1356 48bb3750 Richard Henderson
        tcg_abort();
1357 48bb3750 Richard Henderson
    }
1358 48bb3750 Richard Henderson
}
1359 48bb3750 Richard Henderson
1360 48bb3750 Richard Henderson
static void tcg_out_qemu_st_direct(TCGContext *s, int opc, TCGReg data,
1361 48bb3750 Richard Henderson
                                   TCGReg base, TCGReg index, int disp)
1362 48bb3750 Richard Henderson
{
1363 48bb3750 Richard Henderson
#ifdef TARGET_WORDS_BIGENDIAN
1364 48bb3750 Richard Henderson
    const int bswap = 0;
1365 48bb3750 Richard Henderson
#else
1366 48bb3750 Richard Henderson
    const int bswap = 1;
1367 48bb3750 Richard Henderson
#endif
1368 48bb3750 Richard Henderson
    switch (opc) {
1369 48bb3750 Richard Henderson
    case LD_UINT8:
1370 48bb3750 Richard Henderson
        if (disp >= 0 && disp < 0x1000) {
1371 48bb3750 Richard Henderson
            tcg_out_insn(s, RX, STC, data, base, index, disp);
1372 48bb3750 Richard Henderson
        } else {
1373 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, STCY, data, base, index, disp);
1374 48bb3750 Richard Henderson
        }
1375 48bb3750 Richard Henderson
        break;
1376 48bb3750 Richard Henderson
    case LD_UINT16:
1377 48bb3750 Richard Henderson
        if (bswap) {
1378 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
1379 48bb3750 Richard Henderson
        } else if (disp >= 0 && disp < 0x1000) {
1380 48bb3750 Richard Henderson
            tcg_out_insn(s, RX, STH, data, base, index, disp);
1381 48bb3750 Richard Henderson
        } else {
1382 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, STHY, data, base, index, disp);
1383 48bb3750 Richard Henderson
        }
1384 48bb3750 Richard Henderson
        break;
1385 48bb3750 Richard Henderson
    case LD_UINT32:
1386 48bb3750 Richard Henderson
        if (bswap) {
1387 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, STRV, data, base, index, disp);
1388 48bb3750 Richard Henderson
        } else if (disp >= 0 && disp < 0x1000) {
1389 48bb3750 Richard Henderson
            tcg_out_insn(s, RX, ST, data, base, index, disp);
1390 48bb3750 Richard Henderson
        } else {
1391 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, STY, data, base, index, disp);
1392 48bb3750 Richard Henderson
        }
1393 48bb3750 Richard Henderson
        break;
1394 48bb3750 Richard Henderson
    case LD_UINT64:
1395 48bb3750 Richard Henderson
        if (bswap) {
1396 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
1397 48bb3750 Richard Henderson
        } else {
1398 48bb3750 Richard Henderson
            tcg_out_insn(s, RXY, STG, data, base, index, disp);
1399 48bb3750 Richard Henderson
        }
1400 48bb3750 Richard Henderson
        break;
1401 48bb3750 Richard Henderson
    default:
1402 48bb3750 Richard Henderson
        tcg_abort();
1403 48bb3750 Richard Henderson
    }
1404 48bb3750 Richard Henderson
}
1405 48bb3750 Richard Henderson
1406 48bb3750 Richard Henderson
#if defined(CONFIG_SOFTMMU)
1407 48bb3750 Richard Henderson
static void tgen64_andi_tmp(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1408 48bb3750 Richard Henderson
{
1409 48bb3750 Richard Henderson
    if (tcg_match_andi(0, val)) {
1410 48bb3750 Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, val);
1411 48bb3750 Richard Henderson
        tcg_out_insn(s, RRE, NGR, dest, TCG_TMP0);
1412 48bb3750 Richard Henderson
    } else {
1413 48bb3750 Richard Henderson
        tgen64_andi(s, dest, val);
1414 48bb3750 Richard Henderson
    }
1415 48bb3750 Richard Henderson
}
1416 48bb3750 Richard Henderson
1417 48bb3750 Richard Henderson
static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
1418 48bb3750 Richard Henderson
                                  TCGReg addr_reg, int mem_index, int opc,
1419 48bb3750 Richard Henderson
                                  uint16_t **label2_ptr_p, int is_store)
1420 48bb3750 Richard Henderson
{
1421 48bb3750 Richard Henderson
    const TCGReg arg0 = TCG_REG_R2;
1422 48bb3750 Richard Henderson
    const TCGReg arg1 = TCG_REG_R3;
1423 48bb3750 Richard Henderson
    int s_bits = opc & 3;
1424 48bb3750 Richard Henderson
    uint16_t *label1_ptr;
1425 48bb3750 Richard Henderson
    tcg_target_long ofs;
1426 48bb3750 Richard Henderson
1427 48bb3750 Richard Henderson
    if (TARGET_LONG_BITS == 32) {
1428 48bb3750 Richard Henderson
        tgen_ext32u(s, arg0, addr_reg);
1429 48bb3750 Richard Henderson
    } else {
1430 48bb3750 Richard Henderson
        tcg_out_mov(s, TCG_TYPE_I64, arg0, addr_reg);
1431 48bb3750 Richard Henderson
    }
1432 48bb3750 Richard Henderson
1433 48bb3750 Richard Henderson
    tcg_out_sh64(s, RSY_SRLG, arg1, addr_reg, TCG_REG_NONE,
1434 48bb3750 Richard Henderson
                 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1435 48bb3750 Richard Henderson
1436 48bb3750 Richard Henderson
    tgen64_andi_tmp(s, arg0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1437 48bb3750 Richard Henderson
    tgen64_andi_tmp(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1438 48bb3750 Richard Henderson
1439 48bb3750 Richard Henderson
    if (is_store) {
1440 48bb3750 Richard Henderson
        ofs = offsetof(CPUState, tlb_table[mem_index][0].addr_write);
1441 48bb3750 Richard Henderson
    } else {
1442 48bb3750 Richard Henderson
        ofs = offsetof(CPUState, tlb_table[mem_index][0].addr_read);
1443 48bb3750 Richard Henderson
    }
1444 48bb3750 Richard Henderson
    assert(ofs < 0x80000);
1445 48bb3750 Richard Henderson
1446 48bb3750 Richard Henderson
    if (TARGET_LONG_BITS == 32) {
1447 48bb3750 Richard Henderson
        tcg_out_mem(s, RX_C, RXY_CY, arg0, arg1, TCG_AREG0, ofs);
1448 48bb3750 Richard Henderson
    } else {
1449 48bb3750 Richard Henderson
        tcg_out_mem(s, 0, RXY_CG, arg0, arg1, TCG_AREG0, ofs);
1450 48bb3750 Richard Henderson
    }
1451 48bb3750 Richard Henderson
1452 48bb3750 Richard Henderson
    if (TARGET_LONG_BITS == 32) {
1453 48bb3750 Richard Henderson
        tgen_ext32u(s, arg0, addr_reg);
1454 48bb3750 Richard Henderson
    } else {
1455 48bb3750 Richard Henderson
        tcg_out_mov(s, TCG_TYPE_I64, arg0, addr_reg);
1456 48bb3750 Richard Henderson
    }
1457 48bb3750 Richard Henderson
1458 48bb3750 Richard Henderson
    label1_ptr = (uint16_t*)s->code_ptr;
1459 48bb3750 Richard Henderson
1460 48bb3750 Richard Henderson
    /* je label1 (offset will be patched in later) */
1461 48bb3750 Richard Henderson
    tcg_out_insn(s, RI, BRC, S390_CC_EQ, 0);
1462 48bb3750 Richard Henderson
1463 48bb3750 Richard Henderson
    /* call load/store helper */
1464 48bb3750 Richard Henderson
    if (is_store) {
1465 48bb3750 Richard Henderson
        /* Make sure to zero-extend the value to the full register
1466 48bb3750 Richard Henderson
           for the calling convention.  */
1467 48bb3750 Richard Henderson
        switch (opc) {
1468 48bb3750 Richard Henderson
        case LD_UINT8:
1469 48bb3750 Richard Henderson
            tgen_ext8u(s, TCG_TYPE_I64, arg1, data_reg);
1470 48bb3750 Richard Henderson
            break;
1471 48bb3750 Richard Henderson
        case LD_UINT16:
1472 48bb3750 Richard Henderson
            tgen_ext16u(s, TCG_TYPE_I64, arg1, data_reg);
1473 48bb3750 Richard Henderson
            break;
1474 48bb3750 Richard Henderson
        case LD_UINT32:
1475 48bb3750 Richard Henderson
            tgen_ext32u(s, arg1, data_reg);
1476 48bb3750 Richard Henderson
            break;
1477 48bb3750 Richard Henderson
        case LD_UINT64:
1478 48bb3750 Richard Henderson
            tcg_out_mov(s, TCG_TYPE_I64, arg1, data_reg);
1479 48bb3750 Richard Henderson
            break;
1480 48bb3750 Richard Henderson
        default:
1481 48bb3750 Richard Henderson
            tcg_abort();
1482 48bb3750 Richard Henderson
        }
1483 48bb3750 Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, mem_index);
1484 48bb3750 Richard Henderson
        tgen_calli(s, (tcg_target_ulong)qemu_st_helpers[s_bits]);
1485 48bb3750 Richard Henderson
    } else {
1486 48bb3750 Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
1487 48bb3750 Richard Henderson
        tgen_calli(s, (tcg_target_ulong)qemu_ld_helpers[s_bits]);
1488 48bb3750 Richard Henderson
1489 48bb3750 Richard Henderson
        /* sign extension */
1490 48bb3750 Richard Henderson
        switch (opc) {
1491 48bb3750 Richard Henderson
        case LD_INT8:
1492 48bb3750 Richard Henderson
            tgen_ext8s(s, TCG_TYPE_I64, data_reg, arg0);
1493 48bb3750 Richard Henderson
            break;
1494 48bb3750 Richard Henderson
        case LD_INT16:
1495 48bb3750 Richard Henderson
            tgen_ext16s(s, TCG_TYPE_I64, data_reg, arg0);
1496 48bb3750 Richard Henderson
            break;
1497 48bb3750 Richard Henderson
        case LD_INT32:
1498 48bb3750 Richard Henderson
            tgen_ext32s(s, data_reg, arg0);
1499 48bb3750 Richard Henderson
            break;
1500 48bb3750 Richard Henderson
        default:
1501 48bb3750 Richard Henderson
            /* unsigned -> just copy */
1502 48bb3750 Richard Henderson
            tcg_out_mov(s, TCG_TYPE_I64, data_reg, arg0);
1503 48bb3750 Richard Henderson
            break;
1504 48bb3750 Richard Henderson
        }
1505 48bb3750 Richard Henderson
    }
1506 48bb3750 Richard Henderson
1507 48bb3750 Richard Henderson
    /* jump to label2 (end) */
1508 48bb3750 Richard Henderson
    *label2_ptr_p = (uint16_t*)s->code_ptr;
1509 48bb3750 Richard Henderson
1510 48bb3750 Richard Henderson
    tcg_out_insn(s, RI, BRC, S390_CC_ALWAYS, 0);
1511 48bb3750 Richard Henderson
1512 48bb3750 Richard Henderson
    /* this is label1, patch branch */
1513 48bb3750 Richard Henderson
    *(label1_ptr + 1) = ((unsigned long)s->code_ptr -
1514 48bb3750 Richard Henderson
                         (unsigned long)label1_ptr) >> 1;
1515 48bb3750 Richard Henderson
1516 48bb3750 Richard Henderson
    ofs = offsetof(CPUState, tlb_table[mem_index][0].addend);
1517 48bb3750 Richard Henderson
    assert(ofs < 0x80000);
1518 48bb3750 Richard Henderson
1519 48bb3750 Richard Henderson
    tcg_out_mem(s, 0, RXY_AG, arg0, arg1, TCG_AREG0, ofs);
1520 48bb3750 Richard Henderson
}
1521 48bb3750 Richard Henderson
1522 48bb3750 Richard Henderson
static void tcg_finish_qemu_ldst(TCGContext* s, uint16_t *label2_ptr)
1523 48bb3750 Richard Henderson
{
1524 48bb3750 Richard Henderson
    /* patch branch */
1525 48bb3750 Richard Henderson
    *(label2_ptr + 1) = ((unsigned long)s->code_ptr -
1526 48bb3750 Richard Henderson
                         (unsigned long)label2_ptr) >> 1;
1527 48bb3750 Richard Henderson
}
1528 48bb3750 Richard Henderson
#else
1529 48bb3750 Richard Henderson
static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
1530 48bb3750 Richard Henderson
                                  TCGReg *index_reg, tcg_target_long *disp)
1531 48bb3750 Richard Henderson
{
1532 48bb3750 Richard Henderson
    if (TARGET_LONG_BITS == 32) {
1533 48bb3750 Richard Henderson
        tgen_ext32u(s, TCG_TMP0, *addr_reg);
1534 48bb3750 Richard Henderson
        *addr_reg = TCG_TMP0;
1535 48bb3750 Richard Henderson
    }
1536 48bb3750 Richard Henderson
    if (GUEST_BASE < 0x80000) {
1537 48bb3750 Richard Henderson
        *index_reg = TCG_REG_NONE;
1538 48bb3750 Richard Henderson
        *disp = GUEST_BASE;
1539 48bb3750 Richard Henderson
    } else {
1540 48bb3750 Richard Henderson
        *index_reg = TCG_GUEST_BASE_REG;
1541 48bb3750 Richard Henderson
        *disp = 0;
1542 48bb3750 Richard Henderson
    }
1543 48bb3750 Richard Henderson
}
1544 48bb3750 Richard Henderson
#endif /* CONFIG_SOFTMMU */
1545 48bb3750 Richard Henderson
1546 48bb3750 Richard Henderson
/* load data with address translation (if applicable)
1547 48bb3750 Richard Henderson
   and endianness conversion */
1548 48bb3750 Richard Henderson
static void tcg_out_qemu_ld(TCGContext* s, const TCGArg* args, int opc)
1549 48bb3750 Richard Henderson
{
1550 48bb3750 Richard Henderson
    TCGReg addr_reg, data_reg;
1551 48bb3750 Richard Henderson
#if defined(CONFIG_SOFTMMU)
1552 48bb3750 Richard Henderson
    int mem_index;
1553 48bb3750 Richard Henderson
    uint16_t *label2_ptr;
1554 48bb3750 Richard Henderson
#else
1555 48bb3750 Richard Henderson
    TCGReg index_reg;
1556 48bb3750 Richard Henderson
    tcg_target_long disp;
1557 48bb3750 Richard Henderson
#endif
1558 48bb3750 Richard Henderson
1559 48bb3750 Richard Henderson
    data_reg = *args++;
1560 48bb3750 Richard Henderson
    addr_reg = *args++;
1561 48bb3750 Richard Henderson
1562 48bb3750 Richard Henderson
#if defined(CONFIG_SOFTMMU)
1563 48bb3750 Richard Henderson
    mem_index = *args;
1564 48bb3750 Richard Henderson
1565 48bb3750 Richard Henderson
    tcg_prepare_qemu_ldst(s, data_reg, addr_reg, mem_index,
1566 48bb3750 Richard Henderson
                          opc, &label2_ptr, 0);
1567 48bb3750 Richard Henderson
1568 48bb3750 Richard Henderson
    tcg_out_qemu_ld_direct(s, opc, data_reg, TCG_REG_R2, TCG_REG_NONE, 0);
1569 48bb3750 Richard Henderson
1570 48bb3750 Richard Henderson
    tcg_finish_qemu_ldst(s, label2_ptr);
1571 48bb3750 Richard Henderson
#else
1572 48bb3750 Richard Henderson
    tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1573 48bb3750 Richard Henderson
    tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1574 48bb3750 Richard Henderson
#endif
1575 48bb3750 Richard Henderson
}
1576 48bb3750 Richard Henderson
1577 48bb3750 Richard Henderson
static void tcg_out_qemu_st(TCGContext* s, const TCGArg* args, int opc)
1578 48bb3750 Richard Henderson
{
1579 48bb3750 Richard Henderson
    TCGReg addr_reg, data_reg;
1580 48bb3750 Richard Henderson
#if defined(CONFIG_SOFTMMU)
1581 48bb3750 Richard Henderson
    int mem_index;
1582 48bb3750 Richard Henderson
    uint16_t *label2_ptr;
1583 48bb3750 Richard Henderson
#else
1584 48bb3750 Richard Henderson
    TCGReg index_reg;
1585 48bb3750 Richard Henderson
    tcg_target_long disp;
1586 48bb3750 Richard Henderson
#endif
1587 48bb3750 Richard Henderson
1588 48bb3750 Richard Henderson
    data_reg = *args++;
1589 48bb3750 Richard Henderson
    addr_reg = *args++;
1590 48bb3750 Richard Henderson
1591 48bb3750 Richard Henderson
#if defined(CONFIG_SOFTMMU)
1592 48bb3750 Richard Henderson
    mem_index = *args;
1593 48bb3750 Richard Henderson
1594 48bb3750 Richard Henderson
    tcg_prepare_qemu_ldst(s, data_reg, addr_reg, mem_index,
1595 48bb3750 Richard Henderson
                          opc, &label2_ptr, 1);
1596 48bb3750 Richard Henderson
1597 48bb3750 Richard Henderson
    tcg_out_qemu_st_direct(s, opc, data_reg, TCG_REG_R2, TCG_REG_NONE, 0);
1598 48bb3750 Richard Henderson
1599 48bb3750 Richard Henderson
    tcg_finish_qemu_ldst(s, label2_ptr);
1600 48bb3750 Richard Henderson
#else
1601 48bb3750 Richard Henderson
    tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1602 48bb3750 Richard Henderson
    tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1603 48bb3750 Richard Henderson
#endif
1604 2827822e Alexander Graf
}
1605 2827822e Alexander Graf
1606 48bb3750 Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1607 48bb3750 Richard Henderson
# define OP_32_64(x) \
1608 48bb3750 Richard Henderson
        case glue(glue(INDEX_op_,x),_i32): \
1609 48bb3750 Richard Henderson
        case glue(glue(INDEX_op_,x),_i64)
1610 48bb3750 Richard Henderson
#else
1611 48bb3750 Richard Henderson
# define OP_32_64(x) \
1612 48bb3750 Richard Henderson
        case glue(glue(INDEX_op_,x),_i32)
1613 48bb3750 Richard Henderson
#endif
1614 48bb3750 Richard Henderson
1615 a9751609 Richard Henderson
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1616 2827822e Alexander Graf
                const TCGArg *args, const int *const_args)
1617 2827822e Alexander Graf
{
1618 48bb3750 Richard Henderson
    S390Opcode op;
1619 48bb3750 Richard Henderson
1620 48bb3750 Richard Henderson
    switch (opc) {
1621 48bb3750 Richard Henderson
    case INDEX_op_exit_tb:
1622 48bb3750 Richard Henderson
        /* return value */
1623 48bb3750 Richard Henderson
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, args[0]);
1624 48bb3750 Richard Henderson
        tgen_gotoi(s, S390_CC_ALWAYS, (unsigned long)tb_ret_addr);
1625 48bb3750 Richard Henderson
        break;
1626 48bb3750 Richard Henderson
1627 48bb3750 Richard Henderson
    case INDEX_op_goto_tb:
1628 48bb3750 Richard Henderson
        if (s->tb_jmp_offset) {
1629 48bb3750 Richard Henderson
            tcg_abort();
1630 48bb3750 Richard Henderson
        } else {
1631 48bb3750 Richard Henderson
            /* load address stored at s->tb_next + args[0] */
1632 48bb3750 Richard Henderson
            tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_TMP0, s->tb_next + args[0]);
1633 48bb3750 Richard Henderson
            /* and go there */
1634 48bb3750 Richard Henderson
            tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_TMP0);
1635 48bb3750 Richard Henderson
        }
1636 48bb3750 Richard Henderson
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1637 48bb3750 Richard Henderson
        break;
1638 48bb3750 Richard Henderson
1639 48bb3750 Richard Henderson
    case INDEX_op_call:
1640 48bb3750 Richard Henderson
        if (const_args[0]) {
1641 48bb3750 Richard Henderson
            tgen_calli(s, args[0]);
1642 48bb3750 Richard Henderson
        } else {
1643 48bb3750 Richard Henderson
            tcg_out_insn(s, RR, BASR, TCG_REG_R14, args[0]);
1644 48bb3750 Richard Henderson
        }
1645 48bb3750 Richard Henderson
        break;
1646 48bb3750 Richard Henderson
1647 48bb3750 Richard Henderson
    case INDEX_op_mov_i32:
1648 48bb3750 Richard Henderson
        tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1649 48bb3750 Richard Henderson
        break;
1650 48bb3750 Richard Henderson
    case INDEX_op_movi_i32:
1651 48bb3750 Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1652 48bb3750 Richard Henderson
        break;
1653 48bb3750 Richard Henderson
1654 48bb3750 Richard Henderson
    OP_32_64(ld8u):
1655 48bb3750 Richard Henderson
        /* ??? LLC (RXY format) is only present with the extended-immediate
1656 48bb3750 Richard Henderson
           facility, whereas LLGC is always present.  */
1657 48bb3750 Richard Henderson
        tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
1658 48bb3750 Richard Henderson
        break;
1659 48bb3750 Richard Henderson
1660 48bb3750 Richard Henderson
    OP_32_64(ld8s):
1661 48bb3750 Richard Henderson
        /* ??? LB is no smaller than LGB, so no point to using it.  */
1662 48bb3750 Richard Henderson
        tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
1663 48bb3750 Richard Henderson
        break;
1664 48bb3750 Richard Henderson
1665 48bb3750 Richard Henderson
    OP_32_64(ld16u):
1666 48bb3750 Richard Henderson
        /* ??? LLH (RXY format) is only present with the extended-immediate
1667 48bb3750 Richard Henderson
           facility, whereas LLGH is always present.  */
1668 48bb3750 Richard Henderson
        tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
1669 48bb3750 Richard Henderson
        break;
1670 48bb3750 Richard Henderson
1671 48bb3750 Richard Henderson
    case INDEX_op_ld16s_i32:
1672 48bb3750 Richard Henderson
        tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
1673 48bb3750 Richard Henderson
        break;
1674 48bb3750 Richard Henderson
1675 48bb3750 Richard Henderson
    case INDEX_op_ld_i32:
1676 48bb3750 Richard Henderson
        tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1677 48bb3750 Richard Henderson
        break;
1678 48bb3750 Richard Henderson
1679 48bb3750 Richard Henderson
    OP_32_64(st8):
1680 48bb3750 Richard Henderson
        tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
1681 48bb3750 Richard Henderson
                    TCG_REG_NONE, args[2]);
1682 48bb3750 Richard Henderson
        break;
1683 48bb3750 Richard Henderson
1684 48bb3750 Richard Henderson
    OP_32_64(st16):
1685 48bb3750 Richard Henderson
        tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
1686 48bb3750 Richard Henderson
                    TCG_REG_NONE, args[2]);
1687 48bb3750 Richard Henderson
        break;
1688 48bb3750 Richard Henderson
1689 48bb3750 Richard Henderson
    case INDEX_op_st_i32:
1690 48bb3750 Richard Henderson
        tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1691 48bb3750 Richard Henderson
        break;
1692 48bb3750 Richard Henderson
1693 48bb3750 Richard Henderson
    case INDEX_op_add_i32:
1694 48bb3750 Richard Henderson
        if (const_args[2]) {
1695 48bb3750 Richard Henderson
            tgen32_addi(s, args[0], args[2]);
1696 48bb3750 Richard Henderson
        } else {
1697 48bb3750 Richard Henderson
            tcg_out_insn(s, RR, AR, args[0], args[2]);
1698 48bb3750 Richard Henderson
        }
1699 48bb3750 Richard Henderson
        break;
1700 48bb3750 Richard Henderson
    case INDEX_op_sub_i32:
1701 48bb3750 Richard Henderson
        if (const_args[2]) {
1702 48bb3750 Richard Henderson
            tgen32_addi(s, args[0], -args[2]);
1703 48bb3750 Richard Henderson
        } else {
1704 48bb3750 Richard Henderson
            tcg_out_insn(s, RR, SR, args[0], args[2]);
1705 48bb3750 Richard Henderson
        }
1706 48bb3750 Richard Henderson
        break;
1707 48bb3750 Richard Henderson
1708 48bb3750 Richard Henderson
    case INDEX_op_and_i32:
1709 48bb3750 Richard Henderson
        if (const_args[2]) {
1710 48bb3750 Richard Henderson
            tgen64_andi(s, args[0], args[2] | 0xffffffff00000000ull);
1711 48bb3750 Richard Henderson
        } else {
1712 48bb3750 Richard Henderson
            tcg_out_insn(s, RR, NR, args[0], args[2]);
1713 48bb3750 Richard Henderson
        }
1714 48bb3750 Richard Henderson
        break;
1715 48bb3750 Richard Henderson
    case INDEX_op_or_i32:
1716 48bb3750 Richard Henderson
        if (const_args[2]) {
1717 48bb3750 Richard Henderson
            tgen64_ori(s, args[0], args[2] & 0xffffffff);
1718 48bb3750 Richard Henderson
        } else {
1719 48bb3750 Richard Henderson
            tcg_out_insn(s, RR, OR, args[0], args[2]);
1720 48bb3750 Richard Henderson
        }
1721 48bb3750 Richard Henderson
        break;
1722 48bb3750 Richard Henderson
    case INDEX_op_xor_i32:
1723 48bb3750 Richard Henderson
        if (const_args[2]) {
1724 48bb3750 Richard Henderson
            tgen64_xori(s, args[0], args[2] & 0xffffffff);
1725 48bb3750 Richard Henderson
        } else {
1726 48bb3750 Richard Henderson
            tcg_out_insn(s, RR, XR, args[0], args[2]);
1727 48bb3750 Richard Henderson
        }
1728 48bb3750 Richard Henderson
        break;
1729 48bb3750 Richard Henderson
1730 48bb3750 Richard Henderson
    case INDEX_op_neg_i32:
1731 48bb3750 Richard Henderson
        tcg_out_insn(s, RR, LCR, args[0], args[1]);
1732 48bb3750 Richard Henderson
        break;
1733 48bb3750 Richard Henderson
1734 48bb3750 Richard Henderson
    case INDEX_op_mul_i32:
1735 48bb3750 Richard Henderson
        if (const_args[2]) {
1736 48bb3750 Richard Henderson
            if ((int32_t)args[2] == (int16_t)args[2]) {
1737 48bb3750 Richard Henderson
                tcg_out_insn(s, RI, MHI, args[0], args[2]);
1738 48bb3750 Richard Henderson
            } else {
1739 48bb3750 Richard Henderson
                tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
1740 48bb3750 Richard Henderson
            }
1741 48bb3750 Richard Henderson
        } else {
1742 48bb3750 Richard Henderson
            tcg_out_insn(s, RRE, MSR, args[0], args[2]);
1743 48bb3750 Richard Henderson
        }
1744 48bb3750 Richard Henderson
        break;
1745 48bb3750 Richard Henderson
1746 48bb3750 Richard Henderson
    case INDEX_op_div2_i32:
1747 48bb3750 Richard Henderson
        tcg_out_insn(s, RR, DR, TCG_REG_R2, args[4]);
1748 48bb3750 Richard Henderson
        break;
1749 48bb3750 Richard Henderson
    case INDEX_op_divu2_i32:
1750 48bb3750 Richard Henderson
        tcg_out_insn(s, RRE, DLR, TCG_REG_R2, args[4]);
1751 48bb3750 Richard Henderson
        break;
1752 48bb3750 Richard Henderson
1753 48bb3750 Richard Henderson
    case INDEX_op_shl_i32:
1754 48bb3750 Richard Henderson
        op = RS_SLL;
1755 48bb3750 Richard Henderson
    do_shift32:
1756 48bb3750 Richard Henderson
        if (const_args[2]) {
1757 48bb3750 Richard Henderson
            tcg_out_sh32(s, op, args[0], TCG_REG_NONE, args[2]);
1758 48bb3750 Richard Henderson
        } else {
1759 48bb3750 Richard Henderson
            tcg_out_sh32(s, op, args[0], args[2], 0);
1760 48bb3750 Richard Henderson
        }
1761 48bb3750 Richard Henderson
        break;
1762 48bb3750 Richard Henderson
    case INDEX_op_shr_i32:
1763 48bb3750 Richard Henderson
        op = RS_SRL;
1764 48bb3750 Richard Henderson
        goto do_shift32;
1765 48bb3750 Richard Henderson
    case INDEX_op_sar_i32:
1766 48bb3750 Richard Henderson
        op = RS_SRA;
1767 48bb3750 Richard Henderson
        goto do_shift32;
1768 48bb3750 Richard Henderson
1769 48bb3750 Richard Henderson
    case INDEX_op_rotl_i32:
1770 48bb3750 Richard Henderson
        /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol.  */
1771 48bb3750 Richard Henderson
        if (const_args[2]) {
1772 48bb3750 Richard Henderson
            tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
1773 48bb3750 Richard Henderson
        } else {
1774 48bb3750 Richard Henderson
            tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
1775 48bb3750 Richard Henderson
        }
1776 48bb3750 Richard Henderson
        break;
1777 48bb3750 Richard Henderson
    case INDEX_op_rotr_i32:
1778 48bb3750 Richard Henderson
        if (const_args[2]) {
1779 48bb3750 Richard Henderson
            tcg_out_sh64(s, RSY_RLL, args[0], args[1],
1780 48bb3750 Richard Henderson
                         TCG_REG_NONE, (32 - args[2]) & 31);
1781 48bb3750 Richard Henderson
        } else {
1782 48bb3750 Richard Henderson
            tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
1783 48bb3750 Richard Henderson
            tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
1784 48bb3750 Richard Henderson
        }
1785 48bb3750 Richard Henderson
        break;
1786 48bb3750 Richard Henderson
1787 48bb3750 Richard Henderson
    case INDEX_op_ext8s_i32:
1788 48bb3750 Richard Henderson
        tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
1789 48bb3750 Richard Henderson
        break;
1790 48bb3750 Richard Henderson
    case INDEX_op_ext16s_i32:
1791 48bb3750 Richard Henderson
        tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
1792 48bb3750 Richard Henderson
        break;
1793 48bb3750 Richard Henderson
    case INDEX_op_ext8u_i32:
1794 48bb3750 Richard Henderson
        tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
1795 48bb3750 Richard Henderson
        break;
1796 48bb3750 Richard Henderson
    case INDEX_op_ext16u_i32:
1797 48bb3750 Richard Henderson
        tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
1798 48bb3750 Richard Henderson
        break;
1799 48bb3750 Richard Henderson
1800 48bb3750 Richard Henderson
    OP_32_64(bswap16):
1801 48bb3750 Richard Henderson
        /* The TCG bswap definition requires bits 0-47 already be zero.
1802 48bb3750 Richard Henderson
           Thus we don't need the G-type insns to implement bswap16_i64.  */
1803 48bb3750 Richard Henderson
        tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1804 48bb3750 Richard Henderson
        tcg_out_sh32(s, RS_SRL, args[0], TCG_REG_NONE, 16);
1805 48bb3750 Richard Henderson
        break;
1806 48bb3750 Richard Henderson
    OP_32_64(bswap32):
1807 48bb3750 Richard Henderson
        tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1808 48bb3750 Richard Henderson
        break;
1809 48bb3750 Richard Henderson
1810 48bb3750 Richard Henderson
    case INDEX_op_br:
1811 48bb3750 Richard Henderson
        tgen_branch(s, S390_CC_ALWAYS, args[0]);
1812 48bb3750 Richard Henderson
        break;
1813 48bb3750 Richard Henderson
1814 48bb3750 Richard Henderson
    case INDEX_op_brcond_i32:
1815 48bb3750 Richard Henderson
        tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
1816 48bb3750 Richard Henderson
                    args[1], const_args[1], args[3]);
1817 48bb3750 Richard Henderson
        break;
1818 48bb3750 Richard Henderson
    case INDEX_op_setcond_i32:
1819 48bb3750 Richard Henderson
        tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
1820 48bb3750 Richard Henderson
                     args[2], const_args[2]);
1821 48bb3750 Richard Henderson
        break;
1822 48bb3750 Richard Henderson
1823 48bb3750 Richard Henderson
    case INDEX_op_qemu_ld8u:
1824 48bb3750 Richard Henderson
        tcg_out_qemu_ld(s, args, LD_UINT8);
1825 48bb3750 Richard Henderson
        break;
1826 48bb3750 Richard Henderson
    case INDEX_op_qemu_ld8s:
1827 48bb3750 Richard Henderson
        tcg_out_qemu_ld(s, args, LD_INT8);
1828 48bb3750 Richard Henderson
        break;
1829 48bb3750 Richard Henderson
    case INDEX_op_qemu_ld16u:
1830 48bb3750 Richard Henderson
        tcg_out_qemu_ld(s, args, LD_UINT16);
1831 48bb3750 Richard Henderson
        break;
1832 48bb3750 Richard Henderson
    case INDEX_op_qemu_ld16s:
1833 48bb3750 Richard Henderson
        tcg_out_qemu_ld(s, args, LD_INT16);
1834 48bb3750 Richard Henderson
        break;
1835 48bb3750 Richard Henderson
    case INDEX_op_qemu_ld32:
1836 48bb3750 Richard Henderson
        /* ??? Technically we can use a non-extending instruction.  */
1837 48bb3750 Richard Henderson
        tcg_out_qemu_ld(s, args, LD_UINT32);
1838 48bb3750 Richard Henderson
        break;
1839 48bb3750 Richard Henderson
    case INDEX_op_qemu_ld64:
1840 48bb3750 Richard Henderson
        tcg_out_qemu_ld(s, args, LD_UINT64);
1841 48bb3750 Richard Henderson
        break;
1842 48bb3750 Richard Henderson
1843 48bb3750 Richard Henderson
    case INDEX_op_qemu_st8:
1844 48bb3750 Richard Henderson
        tcg_out_qemu_st(s, args, LD_UINT8);
1845 48bb3750 Richard Henderson
        break;
1846 48bb3750 Richard Henderson
    case INDEX_op_qemu_st16:
1847 48bb3750 Richard Henderson
        tcg_out_qemu_st(s, args, LD_UINT16);
1848 48bb3750 Richard Henderson
        break;
1849 48bb3750 Richard Henderson
    case INDEX_op_qemu_st32:
1850 48bb3750 Richard Henderson
        tcg_out_qemu_st(s, args, LD_UINT32);
1851 48bb3750 Richard Henderson
        break;
1852 48bb3750 Richard Henderson
    case INDEX_op_qemu_st64:
1853 48bb3750 Richard Henderson
        tcg_out_qemu_st(s, args, LD_UINT64);
1854 48bb3750 Richard Henderson
        break;
1855 48bb3750 Richard Henderson
1856 48bb3750 Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1857 48bb3750 Richard Henderson
    case INDEX_op_mov_i64:
1858 48bb3750 Richard Henderson
        tcg_out_mov(s, TCG_TYPE_I64, args[0], args[1]);
1859 48bb3750 Richard Henderson
        break;
1860 48bb3750 Richard Henderson
    case INDEX_op_movi_i64:
1861 48bb3750 Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
1862 48bb3750 Richard Henderson
        break;
1863 48bb3750 Richard Henderson
1864 48bb3750 Richard Henderson
    case INDEX_op_ld16s_i64:
1865 48bb3750 Richard Henderson
        tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
1866 48bb3750 Richard Henderson
        break;
1867 48bb3750 Richard Henderson
    case INDEX_op_ld32u_i64:
1868 48bb3750 Richard Henderson
        tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
1869 48bb3750 Richard Henderson
        break;
1870 48bb3750 Richard Henderson
    case INDEX_op_ld32s_i64:
1871 48bb3750 Richard Henderson
        tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
1872 48bb3750 Richard Henderson
        break;
1873 48bb3750 Richard Henderson
    case INDEX_op_ld_i64:
1874 48bb3750 Richard Henderson
        tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1875 48bb3750 Richard Henderson
        break;
1876 48bb3750 Richard Henderson
1877 48bb3750 Richard Henderson
    case INDEX_op_st32_i64:
1878 48bb3750 Richard Henderson
        tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1879 48bb3750 Richard Henderson
        break;
1880 48bb3750 Richard Henderson
    case INDEX_op_st_i64:
1881 48bb3750 Richard Henderson
        tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1882 48bb3750 Richard Henderson
        break;
1883 48bb3750 Richard Henderson
1884 48bb3750 Richard Henderson
    case INDEX_op_add_i64:
1885 48bb3750 Richard Henderson
        if (const_args[2]) {
1886 48bb3750 Richard Henderson
            tgen64_addi(s, args[0], args[2]);
1887 48bb3750 Richard Henderson
        } else {
1888 48bb3750 Richard Henderson
            tcg_out_insn(s, RRE, AGR, args[0], args[2]);
1889 48bb3750 Richard Henderson
        }
1890 48bb3750 Richard Henderson
        break;
1891 48bb3750 Richard Henderson
    case INDEX_op_sub_i64:
1892 48bb3750 Richard Henderson
        if (const_args[2]) {
1893 48bb3750 Richard Henderson
            tgen64_addi(s, args[0], -args[2]);
1894 48bb3750 Richard Henderson
        } else {
1895 48bb3750 Richard Henderson
            tcg_out_insn(s, RRE, SGR, args[0], args[2]);
1896 48bb3750 Richard Henderson
        }
1897 48bb3750 Richard Henderson
        break;
1898 48bb3750 Richard Henderson
1899 48bb3750 Richard Henderson
    case INDEX_op_and_i64:
1900 48bb3750 Richard Henderson
        if (const_args[2]) {
1901 48bb3750 Richard Henderson
            tgen64_andi(s, args[0], args[2]);
1902 48bb3750 Richard Henderson
        } else {
1903 48bb3750 Richard Henderson
            tcg_out_insn(s, RRE, NGR, args[0], args[2]);
1904 48bb3750 Richard Henderson
        }
1905 48bb3750 Richard Henderson
        break;
1906 48bb3750 Richard Henderson
    case INDEX_op_or_i64:
1907 48bb3750 Richard Henderson
        if (const_args[2]) {
1908 48bb3750 Richard Henderson
            tgen64_ori(s, args[0], args[2]);
1909 48bb3750 Richard Henderson
        } else {
1910 48bb3750 Richard Henderson
            tcg_out_insn(s, RRE, OGR, args[0], args[2]);
1911 48bb3750 Richard Henderson
        }
1912 48bb3750 Richard Henderson
        break;
1913 48bb3750 Richard Henderson
    case INDEX_op_xor_i64:
1914 48bb3750 Richard Henderson
        if (const_args[2]) {
1915 48bb3750 Richard Henderson
            tgen64_xori(s, args[0], args[2]);
1916 48bb3750 Richard Henderson
        } else {
1917 48bb3750 Richard Henderson
            tcg_out_insn(s, RRE, XGR, args[0], args[2]);
1918 48bb3750 Richard Henderson
        }
1919 48bb3750 Richard Henderson
        break;
1920 48bb3750 Richard Henderson
1921 48bb3750 Richard Henderson
    case INDEX_op_neg_i64:
1922 48bb3750 Richard Henderson
        tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
1923 48bb3750 Richard Henderson
        break;
1924 48bb3750 Richard Henderson
    case INDEX_op_bswap64_i64:
1925 48bb3750 Richard Henderson
        tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
1926 48bb3750 Richard Henderson
        break;
1927 48bb3750 Richard Henderson
1928 48bb3750 Richard Henderson
    case INDEX_op_mul_i64:
1929 48bb3750 Richard Henderson
        if (const_args[2]) {
1930 48bb3750 Richard Henderson
            if (args[2] == (int16_t)args[2]) {
1931 48bb3750 Richard Henderson
                tcg_out_insn(s, RI, MGHI, args[0], args[2]);
1932 48bb3750 Richard Henderson
            } else {
1933 48bb3750 Richard Henderson
                tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
1934 48bb3750 Richard Henderson
            }
1935 48bb3750 Richard Henderson
        } else {
1936 48bb3750 Richard Henderson
            tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
1937 48bb3750 Richard Henderson
        }
1938 48bb3750 Richard Henderson
        break;
1939 48bb3750 Richard Henderson
1940 48bb3750 Richard Henderson
    case INDEX_op_div2_i64:
1941 48bb3750 Richard Henderson
        /* ??? We get an unnecessary sign-extension of the dividend
1942 48bb3750 Richard Henderson
           into R3 with this definition, but as we do in fact always
1943 48bb3750 Richard Henderson
           produce both quotient and remainder using INDEX_op_div_i64
1944 48bb3750 Richard Henderson
           instead requires jumping through even more hoops.  */
1945 48bb3750 Richard Henderson
        tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
1946 48bb3750 Richard Henderson
        break;
1947 48bb3750 Richard Henderson
    case INDEX_op_divu2_i64:
1948 48bb3750 Richard Henderson
        tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
1949 48bb3750 Richard Henderson
        break;
1950 48bb3750 Richard Henderson
1951 48bb3750 Richard Henderson
    case INDEX_op_shl_i64:
1952 48bb3750 Richard Henderson
        op = RSY_SLLG;
1953 48bb3750 Richard Henderson
    do_shift64:
1954 48bb3750 Richard Henderson
        if (const_args[2]) {
1955 48bb3750 Richard Henderson
            tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
1956 48bb3750 Richard Henderson
        } else {
1957 48bb3750 Richard Henderson
            tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
1958 48bb3750 Richard Henderson
        }
1959 48bb3750 Richard Henderson
        break;
1960 48bb3750 Richard Henderson
    case INDEX_op_shr_i64:
1961 48bb3750 Richard Henderson
        op = RSY_SRLG;
1962 48bb3750 Richard Henderson
        goto do_shift64;
1963 48bb3750 Richard Henderson
    case INDEX_op_sar_i64:
1964 48bb3750 Richard Henderson
        op = RSY_SRAG;
1965 48bb3750 Richard Henderson
        goto do_shift64;
1966 48bb3750 Richard Henderson
1967 48bb3750 Richard Henderson
    case INDEX_op_rotl_i64:
1968 48bb3750 Richard Henderson
        if (const_args[2]) {
1969 48bb3750 Richard Henderson
            tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
1970 48bb3750 Richard Henderson
                         TCG_REG_NONE, args[2]);
1971 48bb3750 Richard Henderson
        } else {
1972 48bb3750 Richard Henderson
            tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
1973 48bb3750 Richard Henderson
        }
1974 48bb3750 Richard Henderson
        break;
1975 48bb3750 Richard Henderson
    case INDEX_op_rotr_i64:
1976 48bb3750 Richard Henderson
        if (const_args[2]) {
1977 48bb3750 Richard Henderson
            tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
1978 48bb3750 Richard Henderson
                         TCG_REG_NONE, (64 - args[2]) & 63);
1979 48bb3750 Richard Henderson
        } else {
1980 48bb3750 Richard Henderson
            /* We can use the smaller 32-bit negate because only the
1981 48bb3750 Richard Henderson
               low 6 bits are examined for the rotate.  */
1982 48bb3750 Richard Henderson
            tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
1983 48bb3750 Richard Henderson
            tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
1984 48bb3750 Richard Henderson
        }
1985 48bb3750 Richard Henderson
        break;
1986 48bb3750 Richard Henderson
1987 48bb3750 Richard Henderson
    case INDEX_op_ext8s_i64:
1988 48bb3750 Richard Henderson
        tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
1989 48bb3750 Richard Henderson
        break;
1990 48bb3750 Richard Henderson
    case INDEX_op_ext16s_i64:
1991 48bb3750 Richard Henderson
        tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
1992 48bb3750 Richard Henderson
        break;
1993 48bb3750 Richard Henderson
    case INDEX_op_ext32s_i64:
1994 48bb3750 Richard Henderson
        tgen_ext32s(s, args[0], args[1]);
1995 48bb3750 Richard Henderson
        break;
1996 48bb3750 Richard Henderson
    case INDEX_op_ext8u_i64:
1997 48bb3750 Richard Henderson
        tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
1998 48bb3750 Richard Henderson
        break;
1999 48bb3750 Richard Henderson
    case INDEX_op_ext16u_i64:
2000 48bb3750 Richard Henderson
        tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
2001 48bb3750 Richard Henderson
        break;
2002 48bb3750 Richard Henderson
    case INDEX_op_ext32u_i64:
2003 48bb3750 Richard Henderson
        tgen_ext32u(s, args[0], args[1]);
2004 48bb3750 Richard Henderson
        break;
2005 48bb3750 Richard Henderson
2006 48bb3750 Richard Henderson
    case INDEX_op_brcond_i64:
2007 48bb3750 Richard Henderson
        tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
2008 48bb3750 Richard Henderson
                    args[1], const_args[1], args[3]);
2009 48bb3750 Richard Henderson
        break;
2010 48bb3750 Richard Henderson
    case INDEX_op_setcond_i64:
2011 48bb3750 Richard Henderson
        tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2012 48bb3750 Richard Henderson
                     args[2], const_args[2]);
2013 48bb3750 Richard Henderson
        break;
2014 48bb3750 Richard Henderson
2015 48bb3750 Richard Henderson
    case INDEX_op_qemu_ld32u:
2016 48bb3750 Richard Henderson
        tcg_out_qemu_ld(s, args, LD_UINT32);
2017 48bb3750 Richard Henderson
        break;
2018 48bb3750 Richard Henderson
    case INDEX_op_qemu_ld32s:
2019 48bb3750 Richard Henderson
        tcg_out_qemu_ld(s, args, LD_INT32);
2020 48bb3750 Richard Henderson
        break;
2021 48bb3750 Richard Henderson
#endif /* TCG_TARGET_REG_BITS == 64 */
2022 48bb3750 Richard Henderson
2023 48bb3750 Richard Henderson
    case INDEX_op_jmp:
2024 48bb3750 Richard Henderson
        /* This one is obsolete and never emitted.  */
2025 48bb3750 Richard Henderson
        tcg_abort();
2026 48bb3750 Richard Henderson
        break;
2027 48bb3750 Richard Henderson
2028 48bb3750 Richard Henderson
    default:
2029 48bb3750 Richard Henderson
        fprintf(stderr,"unimplemented opc 0x%x\n",opc);
2030 48bb3750 Richard Henderson
        tcg_abort();
2031 48bb3750 Richard Henderson
    }
2032 2827822e Alexander Graf
}
2033 2827822e Alexander Graf
2034 48bb3750 Richard Henderson
static const TCGTargetOpDef s390_op_defs[] = {
2035 48bb3750 Richard Henderson
    { INDEX_op_exit_tb, { } },
2036 48bb3750 Richard Henderson
    { INDEX_op_goto_tb, { } },
2037 48bb3750 Richard Henderson
    { INDEX_op_call, { "ri" } },
2038 48bb3750 Richard Henderson
    { INDEX_op_jmp, { "ri" } },
2039 48bb3750 Richard Henderson
    { INDEX_op_br, { } },
2040 48bb3750 Richard Henderson
2041 48bb3750 Richard Henderson
    { INDEX_op_mov_i32, { "r", "r" } },
2042 48bb3750 Richard Henderson
    { INDEX_op_movi_i32, { "r" } },
2043 48bb3750 Richard Henderson
2044 48bb3750 Richard Henderson
    { INDEX_op_ld8u_i32, { "r", "r" } },
2045 48bb3750 Richard Henderson
    { INDEX_op_ld8s_i32, { "r", "r" } },
2046 48bb3750 Richard Henderson
    { INDEX_op_ld16u_i32, { "r", "r" } },
2047 48bb3750 Richard Henderson
    { INDEX_op_ld16s_i32, { "r", "r" } },
2048 48bb3750 Richard Henderson
    { INDEX_op_ld_i32, { "r", "r" } },
2049 48bb3750 Richard Henderson
    { INDEX_op_st8_i32, { "r", "r" } },
2050 48bb3750 Richard Henderson
    { INDEX_op_st16_i32, { "r", "r" } },
2051 48bb3750 Richard Henderson
    { INDEX_op_st_i32, { "r", "r" } },
2052 48bb3750 Richard Henderson
2053 48bb3750 Richard Henderson
    { INDEX_op_add_i32, { "r", "0", "rWI" } },
2054 48bb3750 Richard Henderson
    { INDEX_op_sub_i32, { "r", "0", "rWNI" } },
2055 48bb3750 Richard Henderson
    { INDEX_op_mul_i32, { "r", "0", "rK" } },
2056 48bb3750 Richard Henderson
2057 48bb3750 Richard Henderson
    { INDEX_op_div2_i32, { "b", "a", "0", "1", "r" } },
2058 48bb3750 Richard Henderson
    { INDEX_op_divu2_i32, { "b", "a", "0", "1", "r" } },
2059 48bb3750 Richard Henderson
2060 48bb3750 Richard Henderson
    { INDEX_op_and_i32, { "r", "0", "rWA" } },
2061 48bb3750 Richard Henderson
    { INDEX_op_or_i32, { "r", "0", "rWO" } },
2062 48bb3750 Richard Henderson
    { INDEX_op_xor_i32, { "r", "0", "rWX" } },
2063 48bb3750 Richard Henderson
2064 48bb3750 Richard Henderson
    { INDEX_op_neg_i32, { "r", "r" } },
2065 48bb3750 Richard Henderson
2066 48bb3750 Richard Henderson
    { INDEX_op_shl_i32, { "r", "0", "Ri" } },
2067 48bb3750 Richard Henderson
    { INDEX_op_shr_i32, { "r", "0", "Ri" } },
2068 48bb3750 Richard Henderson
    { INDEX_op_sar_i32, { "r", "0", "Ri" } },
2069 48bb3750 Richard Henderson
2070 48bb3750 Richard Henderson
    { INDEX_op_rotl_i32, { "r", "r", "Ri" } },
2071 48bb3750 Richard Henderson
    { INDEX_op_rotr_i32, { "r", "r", "Ri" } },
2072 48bb3750 Richard Henderson
2073 48bb3750 Richard Henderson
    { INDEX_op_ext8s_i32, { "r", "r" } },
2074 48bb3750 Richard Henderson
    { INDEX_op_ext8u_i32, { "r", "r" } },
2075 48bb3750 Richard Henderson
    { INDEX_op_ext16s_i32, { "r", "r" } },
2076 48bb3750 Richard Henderson
    { INDEX_op_ext16u_i32, { "r", "r" } },
2077 48bb3750 Richard Henderson
2078 48bb3750 Richard Henderson
    { INDEX_op_bswap16_i32, { "r", "r" } },
2079 48bb3750 Richard Henderson
    { INDEX_op_bswap32_i32, { "r", "r" } },
2080 48bb3750 Richard Henderson
2081 48bb3750 Richard Henderson
    { INDEX_op_brcond_i32, { "r", "rWC" } },
2082 48bb3750 Richard Henderson
    { INDEX_op_setcond_i32, { "r", "r", "rWC" } },
2083 48bb3750 Richard Henderson
2084 48bb3750 Richard Henderson
    { INDEX_op_qemu_ld8u, { "r", "L" } },
2085 48bb3750 Richard Henderson
    { INDEX_op_qemu_ld8s, { "r", "L" } },
2086 48bb3750 Richard Henderson
    { INDEX_op_qemu_ld16u, { "r", "L" } },
2087 48bb3750 Richard Henderson
    { INDEX_op_qemu_ld16s, { "r", "L" } },
2088 48bb3750 Richard Henderson
    { INDEX_op_qemu_ld32, { "r", "L" } },
2089 48bb3750 Richard Henderson
    { INDEX_op_qemu_ld64, { "r", "L" } },
2090 48bb3750 Richard Henderson
2091 48bb3750 Richard Henderson
    { INDEX_op_qemu_st8, { "L", "L" } },
2092 48bb3750 Richard Henderson
    { INDEX_op_qemu_st16, { "L", "L" } },
2093 48bb3750 Richard Henderson
    { INDEX_op_qemu_st32, { "L", "L" } },
2094 48bb3750 Richard Henderson
    { INDEX_op_qemu_st64, { "L", "L" } },
2095 48bb3750 Richard Henderson
2096 48bb3750 Richard Henderson
#if defined(__s390x__)
2097 48bb3750 Richard Henderson
    { INDEX_op_mov_i64, { "r", "r" } },
2098 48bb3750 Richard Henderson
    { INDEX_op_movi_i64, { "r" } },
2099 48bb3750 Richard Henderson
2100 48bb3750 Richard Henderson
    { INDEX_op_ld8u_i64, { "r", "r" } },
2101 48bb3750 Richard Henderson
    { INDEX_op_ld8s_i64, { "r", "r" } },
2102 48bb3750 Richard Henderson
    { INDEX_op_ld16u_i64, { "r", "r" } },
2103 48bb3750 Richard Henderson
    { INDEX_op_ld16s_i64, { "r", "r" } },
2104 48bb3750 Richard Henderson
    { INDEX_op_ld32u_i64, { "r", "r" } },
2105 48bb3750 Richard Henderson
    { INDEX_op_ld32s_i64, { "r", "r" } },
2106 48bb3750 Richard Henderson
    { INDEX_op_ld_i64, { "r", "r" } },
2107 48bb3750 Richard Henderson
2108 48bb3750 Richard Henderson
    { INDEX_op_st8_i64, { "r", "r" } },
2109 48bb3750 Richard Henderson
    { INDEX_op_st16_i64, { "r", "r" } },
2110 48bb3750 Richard Henderson
    { INDEX_op_st32_i64, { "r", "r" } },
2111 48bb3750 Richard Henderson
    { INDEX_op_st_i64, { "r", "r" } },
2112 48bb3750 Richard Henderson
2113 48bb3750 Richard Henderson
    { INDEX_op_add_i64, { "r", "0", "rI" } },
2114 48bb3750 Richard Henderson
    { INDEX_op_sub_i64, { "r", "0", "rNI" } },
2115 48bb3750 Richard Henderson
    { INDEX_op_mul_i64, { "r", "0", "rK" } },
2116 48bb3750 Richard Henderson
2117 48bb3750 Richard Henderson
    { INDEX_op_div2_i64, { "b", "a", "0", "1", "r" } },
2118 48bb3750 Richard Henderson
    { INDEX_op_divu2_i64, { "b", "a", "0", "1", "r" } },
2119 48bb3750 Richard Henderson
2120 48bb3750 Richard Henderson
    { INDEX_op_and_i64, { "r", "0", "rA" } },
2121 48bb3750 Richard Henderson
    { INDEX_op_or_i64, { "r", "0", "rO" } },
2122 48bb3750 Richard Henderson
    { INDEX_op_xor_i64, { "r", "0", "rX" } },
2123 48bb3750 Richard Henderson
2124 48bb3750 Richard Henderson
    { INDEX_op_neg_i64, { "r", "r" } },
2125 48bb3750 Richard Henderson
2126 48bb3750 Richard Henderson
    { INDEX_op_shl_i64, { "r", "r", "Ri" } },
2127 48bb3750 Richard Henderson
    { INDEX_op_shr_i64, { "r", "r", "Ri" } },
2128 48bb3750 Richard Henderson
    { INDEX_op_sar_i64, { "r", "r", "Ri" } },
2129 48bb3750 Richard Henderson
2130 48bb3750 Richard Henderson
    { INDEX_op_rotl_i64, { "r", "r", "Ri" } },
2131 48bb3750 Richard Henderson
    { INDEX_op_rotr_i64, { "r", "r", "Ri" } },
2132 48bb3750 Richard Henderson
2133 48bb3750 Richard Henderson
    { INDEX_op_ext8s_i64, { "r", "r" } },
2134 48bb3750 Richard Henderson
    { INDEX_op_ext8u_i64, { "r", "r" } },
2135 48bb3750 Richard Henderson
    { INDEX_op_ext16s_i64, { "r", "r" } },
2136 48bb3750 Richard Henderson
    { INDEX_op_ext16u_i64, { "r", "r" } },
2137 48bb3750 Richard Henderson
    { INDEX_op_ext32s_i64, { "r", "r" } },
2138 48bb3750 Richard Henderson
    { INDEX_op_ext32u_i64, { "r", "r" } },
2139 48bb3750 Richard Henderson
2140 48bb3750 Richard Henderson
    { INDEX_op_bswap16_i64, { "r", "r" } },
2141 48bb3750 Richard Henderson
    { INDEX_op_bswap32_i64, { "r", "r" } },
2142 48bb3750 Richard Henderson
    { INDEX_op_bswap64_i64, { "r", "r" } },
2143 48bb3750 Richard Henderson
2144 48bb3750 Richard Henderson
    { INDEX_op_brcond_i64, { "r", "rC" } },
2145 48bb3750 Richard Henderson
    { INDEX_op_setcond_i64, { "r", "r", "rC" } },
2146 48bb3750 Richard Henderson
2147 48bb3750 Richard Henderson
    { INDEX_op_qemu_ld32u, { "r", "L" } },
2148 48bb3750 Richard Henderson
    { INDEX_op_qemu_ld32s, { "r", "L" } },
2149 48bb3750 Richard Henderson
#endif
2150 48bb3750 Richard Henderson
2151 48bb3750 Richard Henderson
    { -1 },
2152 48bb3750 Richard Henderson
};
2153 48bb3750 Richard Henderson
2154 48bb3750 Richard Henderson
/* ??? Linux kernels provide an AUXV entry AT_HWCAP that provides most of
2155 48bb3750 Richard Henderson
   this information.  However, getting at that entry is not easy this far
2156 48bb3750 Richard Henderson
   away from main.  Our options are: start searching from environ, but
2157 48bb3750 Richard Henderson
   that fails as soon as someone does a setenv in between.  Read the data
2158 48bb3750 Richard Henderson
   from /proc/self/auxv.  Or do the probing ourselves.  The only thing
2159 48bb3750 Richard Henderson
   extra that AT_HWCAP gives us is HWCAP_S390_HIGH_GPRS, which indicates
2160 48bb3750 Richard Henderson
   that the kernel saves all 64-bits of the registers around traps while
2161 48bb3750 Richard Henderson
   in 31-bit mode.  But this is true of all "recent" kernels (ought to dig
2162 48bb3750 Richard Henderson
   back and see from when this might not be true).  */
2163 48bb3750 Richard Henderson
2164 48bb3750 Richard Henderson
#include <signal.h>
2165 48bb3750 Richard Henderson
2166 48bb3750 Richard Henderson
static volatile sig_atomic_t got_sigill;
2167 48bb3750 Richard Henderson
2168 48bb3750 Richard Henderson
static void sigill_handler(int sig)
2169 2827822e Alexander Graf
{
2170 48bb3750 Richard Henderson
    got_sigill = 1;
2171 2827822e Alexander Graf
}
2172 2827822e Alexander Graf
2173 48bb3750 Richard Henderson
static void query_facilities(void)
2174 48bb3750 Richard Henderson
{
2175 48bb3750 Richard Henderson
    struct sigaction sa_old, sa_new;
2176 48bb3750 Richard Henderson
    register int r0 __asm__("0");
2177 48bb3750 Richard Henderson
    register void *r1 __asm__("1");
2178 48bb3750 Richard Henderson
    int fail;
2179 48bb3750 Richard Henderson
2180 48bb3750 Richard Henderson
    memset(&sa_new, 0, sizeof(sa_new));
2181 48bb3750 Richard Henderson
    sa_new.sa_handler = sigill_handler;
2182 48bb3750 Richard Henderson
    sigaction(SIGILL, &sa_new, &sa_old);
2183 48bb3750 Richard Henderson
2184 48bb3750 Richard Henderson
    /* First, try STORE FACILITY LIST EXTENDED.  If this is present, then
2185 48bb3750 Richard Henderson
       we need not do any more probing.  Unfortunately, this itself is an
2186 48bb3750 Richard Henderson
       extension and the original STORE FACILITY LIST instruction is
2187 48bb3750 Richard Henderson
       kernel-only, storing its results at absolute address 200.  */
2188 48bb3750 Richard Henderson
    /* stfle 0(%r1) */
2189 48bb3750 Richard Henderson
    r1 = &facilities;
2190 48bb3750 Richard Henderson
    asm volatile(".word 0xb2b0,0x1000"
2191 48bb3750 Richard Henderson
                 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
2192 48bb3750 Richard Henderson
2193 48bb3750 Richard Henderson
    if (got_sigill) {
2194 48bb3750 Richard Henderson
        /* STORE FACILITY EXTENDED is not available.  Probe for one of each
2195 48bb3750 Richard Henderson
           kind of instruction that we're interested in.  */
2196 48bb3750 Richard Henderson
        /* ??? Possibly some of these are in practice never present unless
2197 48bb3750 Richard Henderson
           the store-facility-extended facility is also present.  But since
2198 48bb3750 Richard Henderson
           that isn't documented it's just better to probe for each.  */
2199 48bb3750 Richard Henderson
2200 48bb3750 Richard Henderson
        /* Test for z/Architecture.  Required even in 31-bit mode.  */
2201 48bb3750 Richard Henderson
        got_sigill = 0;
2202 48bb3750 Richard Henderson
        /* agr %r0,%r0 */
2203 48bb3750 Richard Henderson
        asm volatile(".word 0xb908,0x0000" : "=r"(r0) : : "cc");
2204 48bb3750 Richard Henderson
        if (!got_sigill) {
2205 48bb3750 Richard Henderson
            facilities |= FACILITY_ZARCH_ACTIVE;
2206 48bb3750 Richard Henderson
        }
2207 48bb3750 Richard Henderson
2208 48bb3750 Richard Henderson
        /* Test for long displacement.  */
2209 48bb3750 Richard Henderson
        got_sigill = 0;
2210 48bb3750 Richard Henderson
        /* ly %r0,0(%r1) */
2211 48bb3750 Richard Henderson
        r1 = &facilities;
2212 48bb3750 Richard Henderson
        asm volatile(".word 0xe300,0x1000,0x0058"
2213 48bb3750 Richard Henderson
                     : "=r"(r0) : "r"(r1) : "cc");
2214 48bb3750 Richard Henderson
        if (!got_sigill) {
2215 48bb3750 Richard Henderson
            facilities |= FACILITY_LONG_DISP;
2216 48bb3750 Richard Henderson
        }
2217 48bb3750 Richard Henderson
2218 48bb3750 Richard Henderson
        /* Test for extended immediates.  */
2219 48bb3750 Richard Henderson
        got_sigill = 0;
2220 48bb3750 Richard Henderson
        /* afi %r0,0 */
2221 48bb3750 Richard Henderson
        asm volatile(".word 0xc209,0x0000,0x0000" : : : "cc");
2222 48bb3750 Richard Henderson
        if (!got_sigill) {
2223 48bb3750 Richard Henderson
            facilities |= FACILITY_EXT_IMM;
2224 48bb3750 Richard Henderson
        }
2225 48bb3750 Richard Henderson
2226 48bb3750 Richard Henderson
        /* Test for general-instructions-extension.  */
2227 48bb3750 Richard Henderson
        got_sigill = 0;
2228 48bb3750 Richard Henderson
        /* msfi %r0,1 */
2229 48bb3750 Richard Henderson
        asm volatile(".word 0xc201,0x0000,0x0001");
2230 48bb3750 Richard Henderson
        if (!got_sigill) {
2231 48bb3750 Richard Henderson
            facilities |= FACILITY_GEN_INST_EXT;
2232 48bb3750 Richard Henderson
        }
2233 48bb3750 Richard Henderson
    }
2234 48bb3750 Richard Henderson
2235 48bb3750 Richard Henderson
    sigaction(SIGILL, &sa_old, NULL);
2236 48bb3750 Richard Henderson
2237 48bb3750 Richard Henderson
    /* The translator currently uses these extensions unconditionally.
2238 48bb3750 Richard Henderson
       Pruning this back to the base ESA/390 architecture doesn't seem
2239 48bb3750 Richard Henderson
       worthwhile, since even the KVM target requires z/Arch.  */
2240 48bb3750 Richard Henderson
    fail = 0;
2241 48bb3750 Richard Henderson
    if ((facilities & FACILITY_ZARCH_ACTIVE) == 0) {
2242 48bb3750 Richard Henderson
        fprintf(stderr, "TCG: z/Arch facility is required.\n");
2243 48bb3750 Richard Henderson
        fprintf(stderr, "TCG: Boot with a 64-bit enabled kernel.\n");
2244 48bb3750 Richard Henderson
        fail = 1;
2245 48bb3750 Richard Henderson
    }
2246 48bb3750 Richard Henderson
    if ((facilities & FACILITY_LONG_DISP) == 0) {
2247 48bb3750 Richard Henderson
        fprintf(stderr, "TCG: long-displacement facility is required.\n");
2248 48bb3750 Richard Henderson
        fail = 1;
2249 48bb3750 Richard Henderson
    }
2250 48bb3750 Richard Henderson
2251 48bb3750 Richard Henderson
    /* So far there's just enough support for 31-bit mode to let the
2252 48bb3750 Richard Henderson
       compile succeed.  This is good enough to run QEMU with KVM.  */
2253 48bb3750 Richard Henderson
    if (sizeof(void *) != 8) {
2254 48bb3750 Richard Henderson
        fprintf(stderr, "TCG: 31-bit mode is not supported.\n");
2255 48bb3750 Richard Henderson
        fail = 1;
2256 48bb3750 Richard Henderson
    }
2257 48bb3750 Richard Henderson
2258 48bb3750 Richard Henderson
    if (fail) {
2259 48bb3750 Richard Henderson
        exit(-1);
2260 48bb3750 Richard Henderson
    }
2261 48bb3750 Richard Henderson
}
2262 48bb3750 Richard Henderson
2263 48bb3750 Richard Henderson
static void tcg_target_init(TCGContext *s)
2264 2827822e Alexander Graf
{
2265 48bb3750 Richard Henderson
#if !defined(CONFIG_USER_ONLY)
2266 48bb3750 Richard Henderson
    /* fail safe */
2267 48bb3750 Richard Henderson
    if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry)) {
2268 48bb3750 Richard Henderson
        tcg_abort();
2269 48bb3750 Richard Henderson
    }
2270 48bb3750 Richard Henderson
#endif
2271 48bb3750 Richard Henderson
2272 48bb3750 Richard Henderson
    query_facilities();
2273 48bb3750 Richard Henderson
2274 48bb3750 Richard Henderson
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
2275 48bb3750 Richard Henderson
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
2276 48bb3750 Richard Henderson
2277 48bb3750 Richard Henderson
    tcg_regset_clear(tcg_target_call_clobber_regs);
2278 48bb3750 Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2279 48bb3750 Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
2280 48bb3750 Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2281 48bb3750 Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2282 48bb3750 Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
2283 48bb3750 Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
2284 48bb3750 Richard Henderson
    /* The return register can be considered call-clobbered.  */
2285 48bb3750 Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2286 48bb3750 Richard Henderson
2287 48bb3750 Richard Henderson
    tcg_regset_clear(s->reserved_regs);
2288 48bb3750 Richard Henderson
    tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
2289 48bb3750 Richard Henderson
    /* XXX many insns can't be used with R0, so we better avoid it for now */
2290 48bb3750 Richard Henderson
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
2291 48bb3750 Richard Henderson
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2292 48bb3750 Richard Henderson
2293 48bb3750 Richard Henderson
    tcg_add_target_add_op_defs(s390_op_defs);
2294 2827822e Alexander Graf
}
2295 2827822e Alexander Graf
2296 48bb3750 Richard Henderson
static void tcg_target_qemu_prologue(TCGContext *s)
2297 2827822e Alexander Graf
{
2298 48bb3750 Richard Henderson
    /* stmg %r6,%r15,48(%r15) (save registers) */
2299 48bb3750 Richard Henderson
    tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
2300 48bb3750 Richard Henderson
2301 48bb3750 Richard Henderson
    /* aghi %r15,-160 (stack frame) */
2302 48bb3750 Richard Henderson
    tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -160);
2303 48bb3750 Richard Henderson
2304 48bb3750 Richard Henderson
    if (GUEST_BASE >= 0x80000) {
2305 48bb3750 Richard Henderson
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
2306 48bb3750 Richard Henderson
        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2307 48bb3750 Richard Henderson
    }
2308 48bb3750 Richard Henderson
2309 48bb3750 Richard Henderson
    /* br %r2 (go to TB) */
2310 48bb3750 Richard Henderson
    tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R2);
2311 48bb3750 Richard Henderson
2312 48bb3750 Richard Henderson
    tb_ret_addr = s->code_ptr;
2313 48bb3750 Richard Henderson
2314 48bb3750 Richard Henderson
    /* lmg %r6,%r15,208(%r15) (restore registers) */
2315 48bb3750 Richard Henderson
    tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 208);
2316 48bb3750 Richard Henderson
2317 48bb3750 Richard Henderson
    /* br %r14 (return) */
2318 48bb3750 Richard Henderson
    tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
2319 2827822e Alexander Graf
}
2320 2827822e Alexander Graf
2321 2827822e Alexander Graf
static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
2322 2827822e Alexander Graf
{
2323 2827822e Alexander Graf
    tcg_abort();
2324 2827822e Alexander Graf
}