Statistics
| Branch: | Revision:

root / tcg / s390 / tcg-target.c @ f53f81e0

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