]> git.proxmox.com Git - mirror_qemu.git/blame - tcg/s390x/tcg-target.c.inc
tcg: Add tlb_fast_offset to TCGContext
[mirror_qemu.git] / tcg / s390x / tcg-target.c.inc
CommitLineData
2827822e
AG
1/*
2 * Tiny Code Generator for QEMU
3 *
4 * Copyright (c) 2009 Ulrich Hecht <uli@suse.de>
48bb3750
RH
5 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
6 * Copyright (c) 2010 Richard Henderson <rth@twiddle.net>
2827822e
AG
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
a01fc30d
RH
27/* We only support generating code for 64-bit mode. */
28#if TCG_TARGET_REG_BITS != 64
29#error "unsupported code generation mode"
30#endif
31
1cd49868 32#include "../tcg-ldst.c.inc"
139c1837 33#include "../tcg-pool.c.inc"
c9baa30f
RH
34#include "elf.h"
35
4134083f
RH
36#define TCG_CT_CONST_S16 (1 << 8)
37#define TCG_CT_CONST_S32 (1 << 9)
38#define TCG_CT_CONST_S33 (1 << 10)
39#define TCG_CT_CONST_ZERO (1 << 11)
40#define TCG_CT_CONST_P32 (1 << 12)
41#define TCG_CT_CONST_INV (1 << 13)
42#define TCG_CT_CONST_INVRISBG (1 << 14)
48bb3750 43
c947deb1 44#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 16)
34ef7676
RH
45#define ALL_VECTOR_REGS MAKE_64BIT_MASK(32, 32)
46
48bb3750
RH
47/* Several places within the instruction set 0 means "no register"
48 rather than TCG_REG_R0. */
49#define TCG_REG_NONE 0
50
51/* A scratch register that may be be used throughout the backend. */
ce411066 52#define TCG_TMP0 TCG_REG_R1
48bb3750 53
4cbea598 54#ifndef CONFIG_SOFTMMU
48bb3750 55#define TCG_GUEST_BASE_REG TCG_REG_R13
48bb3750
RH
56#endif
57
48bb3750
RH
58/* All of the following instructions are prefixed with their instruction
59 format, and are defined as 8- or 16-bit quantities, even when the two
60 halves of the 16-bit quantity may appear 32 bits apart in the insn.
61 This makes it easy to copy the values from the tables in Appendix B. */
62typedef enum S390Opcode {
63 RIL_AFI = 0xc209,
64 RIL_AGFI = 0xc208,
3790b918 65 RIL_ALFI = 0xc20b,
48bb3750
RH
66 RIL_ALGFI = 0xc20a,
67 RIL_BRASL = 0xc005,
68 RIL_BRCL = 0xc004,
69 RIL_CFI = 0xc20d,
70 RIL_CGFI = 0xc20c,
71 RIL_CLFI = 0xc20f,
72 RIL_CLGFI = 0xc20e,
a534bb15
RH
73 RIL_CLRL = 0xc60f,
74 RIL_CLGRL = 0xc60a,
75 RIL_CRL = 0xc60d,
76 RIL_CGRL = 0xc608,
48bb3750
RH
77 RIL_IIHF = 0xc008,
78 RIL_IILF = 0xc009,
79 RIL_LARL = 0xc000,
80 RIL_LGFI = 0xc001,
81 RIL_LGRL = 0xc408,
82 RIL_LLIHF = 0xc00e,
83 RIL_LLILF = 0xc00f,
84 RIL_LRL = 0xc40d,
85 RIL_MSFI = 0xc201,
86 RIL_MSGFI = 0xc200,
87 RIL_NIHF = 0xc00a,
88 RIL_NILF = 0xc00b,
89 RIL_OIHF = 0xc00c,
90 RIL_OILF = 0xc00d,
3790b918 91 RIL_SLFI = 0xc205,
0db921e6 92 RIL_SLGFI = 0xc204,
48bb3750
RH
93 RIL_XIHF = 0xc006,
94 RIL_XILF = 0xc007,
95
96 RI_AGHI = 0xa70b,
97 RI_AHI = 0xa70a,
98 RI_BRC = 0xa704,
a534bb15
RH
99 RI_CHI = 0xa70e,
100 RI_CGHI = 0xa70f,
48bb3750
RH
101 RI_IIHH = 0xa500,
102 RI_IIHL = 0xa501,
103 RI_IILH = 0xa502,
104 RI_IILL = 0xa503,
105 RI_LGHI = 0xa709,
106 RI_LLIHH = 0xa50c,
107 RI_LLIHL = 0xa50d,
108 RI_LLILH = 0xa50e,
109 RI_LLILL = 0xa50f,
110 RI_MGHI = 0xa70d,
111 RI_MHI = 0xa70c,
112 RI_NIHH = 0xa504,
113 RI_NIHL = 0xa505,
114 RI_NILH = 0xa506,
115 RI_NILL = 0xa507,
116 RI_OIHH = 0xa508,
117 RI_OIHL = 0xa509,
118 RI_OILH = 0xa50a,
119 RI_OILL = 0xa50b,
1cd49868 120 RI_TMLL = 0xa701,
48bb3750 121
d84ca804
RH
122 RIEb_CGRJ = 0xec64,
123 RIEb_CLGRJ = 0xec65,
124 RIEb_CLRJ = 0xec77,
125 RIEb_CRJ = 0xec76,
126
127 RIEc_CGIJ = 0xec7c,
128 RIEc_CIJ = 0xec7e,
129 RIEc_CLGIJ = 0xec7d,
130 RIEc_CLIJ = 0xec7f,
131
132 RIEf_RISBG = 0xec55,
133
134 RIEg_LOCGHI = 0xec46,
48bb3750
RH
135
136 RRE_AGR = 0xb908,
3790b918
RH
137 RRE_ALGR = 0xb90a,
138 RRE_ALCR = 0xb998,
139 RRE_ALCGR = 0xb988,
8b1b4597 140 RRE_ALGFR = 0xb91a,
48bb3750
RH
141 RRE_CGR = 0xb920,
142 RRE_CLGR = 0xb921,
143 RRE_DLGR = 0xb987,
144 RRE_DLR = 0xb997,
145 RRE_DSGFR = 0xb91d,
146 RRE_DSGR = 0xb90d,
ce411066 147 RRE_FLOGR = 0xb983,
48bb3750
RH
148 RRE_LGBR = 0xb906,
149 RRE_LCGR = 0xb903,
150 RRE_LGFR = 0xb914,
151 RRE_LGHR = 0xb907,
152 RRE_LGR = 0xb904,
153 RRE_LLGCR = 0xb984,
154 RRE_LLGFR = 0xb916,
155 RRE_LLGHR = 0xb985,
156 RRE_LRVR = 0xb91f,
157 RRE_LRVGR = 0xb90f,
158 RRE_LTGR = 0xb902,
36017dc6 159 RRE_MLGR = 0xb986,
48bb3750
RH
160 RRE_MSGR = 0xb90c,
161 RRE_MSR = 0xb252,
162 RRE_NGR = 0xb980,
163 RRE_OGR = 0xb981,
164 RRE_SGR = 0xb909,
3790b918
RH
165 RRE_SLGR = 0xb90b,
166 RRE_SLBR = 0xb999,
167 RRE_SLBGR = 0xb989,
48bb3750
RH
168 RRE_XGR = 0xb982,
169
668ce343 170 RRFa_MGRK = 0xb9ec,
92c89a07
RH
171 RRFa_MSRKC = 0xb9fd,
172 RRFa_MSGRKC = 0xb9ed,
6c9b5c0f
RH
173 RRFa_NCRK = 0xb9f5,
174 RRFa_NCGRK = 0xb9e5,
175 RRFa_NNRK = 0xb974,
176 RRFa_NNGRK = 0xb964,
177 RRFa_NORK = 0xb976,
178 RRFa_NOGRK = 0xb966,
1dd06b1a
RH
179 RRFa_NRK = 0xb9f4,
180 RRFa_NGRK = 0xb9e4,
6c9b5c0f
RH
181 RRFa_NXRK = 0xb977,
182 RRFa_NXGRK = 0xb967,
183 RRFa_OCRK = 0xb975,
184 RRFa_OCGRK = 0xb965,
1dd06b1a
RH
185 RRFa_ORK = 0xb9f6,
186 RRFa_OGRK = 0xb9e6,
187 RRFa_SRK = 0xb9f9,
188 RRFa_SGRK = 0xb9e9,
189 RRFa_SLRK = 0xb9fb,
190 RRFa_SLGRK = 0xb9eb,
191 RRFa_XRK = 0xb9f7,
192 RRFa_XGRK = 0xb9e7,
193
0bbf0f7a
RH
194 RRFam_SELGR = 0xb9e3,
195
1dd06b1a
RH
196 RRFc_LOCR = 0xb9f2,
197 RRFc_LOCGR = 0xb9e2,
29a5ea73 198 RRFc_POPCNT = 0xb9e1,
96a9f093 199
48bb3750 200 RR_AR = 0x1a,
3790b918 201 RR_ALR = 0x1e,
48bb3750
RH
202 RR_BASR = 0x0d,
203 RR_BCR = 0x07,
204 RR_CLR = 0x15,
205 RR_CR = 0x19,
206 RR_DR = 0x1d,
207 RR_LCR = 0x13,
208 RR_LR = 0x18,
209 RR_LTR = 0x12,
210 RR_NR = 0x14,
211 RR_OR = 0x16,
212 RR_SR = 0x1b,
3790b918 213 RR_SLR = 0x1f,
48bb3750
RH
214 RR_XR = 0x17,
215
216 RSY_RLL = 0xeb1d,
217 RSY_RLLG = 0xeb1c,
218 RSY_SLLG = 0xeb0d,
c2097136 219 RSY_SLLK = 0xebdf,
48bb3750 220 RSY_SRAG = 0xeb0a,
c2097136 221 RSY_SRAK = 0xebdc,
48bb3750 222 RSY_SRLG = 0xeb0c,
c2097136 223 RSY_SRLK = 0xebde,
48bb3750
RH
224
225 RS_SLL = 0x89,
226 RS_SRA = 0x8a,
227 RS_SRL = 0x88,
228
229 RXY_AG = 0xe308,
230 RXY_AY = 0xe35a,
231 RXY_CG = 0xe320,
a534bb15
RH
232 RXY_CLG = 0xe321,
233 RXY_CLY = 0xe355,
48bb3750 234 RXY_CY = 0xe359,
0db921e6 235 RXY_LAY = 0xe371,
48bb3750
RH
236 RXY_LB = 0xe376,
237 RXY_LG = 0xe304,
238 RXY_LGB = 0xe377,
239 RXY_LGF = 0xe314,
240 RXY_LGH = 0xe315,
241 RXY_LHY = 0xe378,
242 RXY_LLGC = 0xe390,
243 RXY_LLGF = 0xe316,
244 RXY_LLGH = 0xe391,
245 RXY_LMG = 0xeb04,
4caad79f 246 RXY_LPQ = 0xe38f,
48bb3750
RH
247 RXY_LRV = 0xe31e,
248 RXY_LRVG = 0xe30f,
249 RXY_LRVH = 0xe31f,
250 RXY_LY = 0xe358,
bdcd5d19 251 RXY_NG = 0xe380,
4046d9ca 252 RXY_OG = 0xe381,
48bb3750
RH
253 RXY_STCY = 0xe372,
254 RXY_STG = 0xe324,
255 RXY_STHY = 0xe370,
256 RXY_STMG = 0xeb24,
4caad79f 257 RXY_STPQ = 0xe38e,
48bb3750
RH
258 RXY_STRV = 0xe33e,
259 RXY_STRVG = 0xe32f,
260 RXY_STRVH = 0xe33f,
261 RXY_STY = 0xe350,
5bf67a92 262 RXY_XG = 0xe382,
48bb3750
RH
263
264 RX_A = 0x5a,
265 RX_C = 0x59,
266 RX_L = 0x58,
0db921e6 267 RX_LA = 0x41,
48bb3750
RH
268 RX_LH = 0x48,
269 RX_ST = 0x50,
270 RX_STC = 0x42,
271 RX_STH = 0x40,
ed3d51ec 272
79cada86
RH
273 VRIa_VGBM = 0xe744,
274 VRIa_VREPI = 0xe745,
275 VRIb_VGM = 0xe746,
276 VRIc_VREP = 0xe74d,
277
ae77bbe5
RH
278 VRRa_VLC = 0xe7de,
279 VRRa_VLP = 0xe7df,
b33ce725 280 VRRa_VLR = 0xe756,
a429ee29
RH
281 VRRc_VA = 0xe7f3,
282 VRRc_VCEQ = 0xe7f8, /* we leave the m5 cs field 0 */
283 VRRc_VCH = 0xe7fb, /* " */
284 VRRc_VCHL = 0xe7f9, /* " */
22cb37b4
RH
285 VRRc_VERLLV = 0xe773,
286 VRRc_VESLV = 0xe770,
287 VRRc_VESRAV = 0xe77a,
288 VRRc_VESRLV = 0xe778,
479b61cb 289 VRRc_VML = 0xe7a2,
220db7a6
RH
290 VRRc_VMN = 0xe7fe,
291 VRRc_VMNL = 0xe7fc,
292 VRRc_VMX = 0xe7ff,
293 VRRc_VMXL = 0xe7fd,
a429ee29 294 VRRc_VN = 0xe768,
ae77bbe5 295 VRRc_VNC = 0xe769,
21eab5bf 296 VRRc_VNN = 0xe76e,
ae77bbe5 297 VRRc_VNO = 0xe76b,
21eab5bf 298 VRRc_VNX = 0xe76c,
a429ee29 299 VRRc_VO = 0xe76a,
ae77bbe5 300 VRRc_VOC = 0xe76f,
4223c9c1 301 VRRc_VPKS = 0xe797, /* we leave the m5 cs field 0 */
a429ee29 302 VRRc_VS = 0xe7f7,
4223c9c1
RH
303 VRRa_VUPH = 0xe7d7,
304 VRRa_VUPL = 0xe7d6,
a429ee29 305 VRRc_VX = 0xe76d,
9bca986d 306 VRRe_VSEL = 0xe78d,
79cada86 307 VRRf_VLVGP = 0xe762,
b33ce725 308
22cb37b4
RH
309 VRSa_VERLL = 0xe733,
310 VRSa_VESL = 0xe730,
311 VRSa_VESRA = 0xe73a,
312 VRSa_VESRL = 0xe738,
b33ce725
RH
313 VRSb_VLVG = 0xe722,
314 VRSc_VLGV = 0xe721,
315
2dabf742
RH
316 VRX_VL = 0xe706,
317 VRX_VLLEZ = 0xe704,
79cada86 318 VRX_VLREP = 0xe705,
2dabf742
RH
319 VRX_VST = 0xe70e,
320 VRX_VSTEF = 0xe70b,
321 VRX_VSTEG = 0xe70a,
322
ed3d51ec 323 NOP = 0x0707,
48bb3750
RH
324} S390Opcode;
325
8d8fdbae 326#ifdef CONFIG_DEBUG_TCG
48bb3750 327static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
34ef7676
RH
328 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
329 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
330 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
331 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
332 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
333 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
334 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
48bb3750
RH
335};
336#endif
337
338/* Since R6 is a potential argument register, choose it last of the
339 call-saved registers. Likewise prefer the call-clobbered registers
340 in reverse order to maximize the chance of avoiding the arguments. */
2827822e 341static const int tcg_target_reg_alloc_order[] = {
f24efee4 342 /* Call saved registers. */
48bb3750
RH
343 TCG_REG_R13,
344 TCG_REG_R12,
345 TCG_REG_R11,
346 TCG_REG_R10,
347 TCG_REG_R9,
348 TCG_REG_R8,
349 TCG_REG_R7,
350 TCG_REG_R6,
f24efee4 351 /* Call clobbered registers. */
48bb3750
RH
352 TCG_REG_R14,
353 TCG_REG_R0,
354 TCG_REG_R1,
f24efee4 355 /* Argument registers, in reverse order of allocation. */
48bb3750
RH
356 TCG_REG_R5,
357 TCG_REG_R4,
358 TCG_REG_R3,
359 TCG_REG_R2,
34ef7676
RH
360
361 /* V8-V15 are call saved, and omitted. */
362 TCG_REG_V0,
363 TCG_REG_V1,
364 TCG_REG_V2,
365 TCG_REG_V3,
366 TCG_REG_V4,
367 TCG_REG_V5,
368 TCG_REG_V6,
369 TCG_REG_V7,
370 TCG_REG_V16,
371 TCG_REG_V17,
372 TCG_REG_V18,
373 TCG_REG_V19,
374 TCG_REG_V20,
375 TCG_REG_V21,
376 TCG_REG_V22,
377 TCG_REG_V23,
378 TCG_REG_V24,
379 TCG_REG_V25,
380 TCG_REG_V26,
381 TCG_REG_V27,
382 TCG_REG_V28,
383 TCG_REG_V29,
384 TCG_REG_V30,
385 TCG_REG_V31,
2827822e
AG
386};
387
388static const int tcg_target_call_iarg_regs[] = {
48bb3750
RH
389 TCG_REG_R2,
390 TCG_REG_R3,
391 TCG_REG_R4,
392 TCG_REG_R5,
393 TCG_REG_R6,
2827822e
AG
394};
395
5e3d0c19
RH
396static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
397{
398 tcg_debug_assert(kind == TCG_CALL_RET_NORMAL);
399 tcg_debug_assert(slot == 0);
400 return TCG_REG_R2;
401}
48bb3750
RH
402
403#define S390_CC_EQ 8
404#define S390_CC_LT 4
405#define S390_CC_GT 2
406#define S390_CC_OV 1
407#define S390_CC_NE (S390_CC_LT | S390_CC_GT)
408#define S390_CC_LE (S390_CC_LT | S390_CC_EQ)
409#define S390_CC_GE (S390_CC_GT | S390_CC_EQ)
410#define S390_CC_NEVER 0
411#define S390_CC_ALWAYS 15
412
413/* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
0aed257f 414static const uint8_t tcg_cond_to_s390_cond[] = {
48bb3750
RH
415 [TCG_COND_EQ] = S390_CC_EQ,
416 [TCG_COND_NE] = S390_CC_NE,
417 [TCG_COND_LT] = S390_CC_LT,
418 [TCG_COND_LE] = S390_CC_LE,
419 [TCG_COND_GT] = S390_CC_GT,
420 [TCG_COND_GE] = S390_CC_GE,
421 [TCG_COND_LTU] = S390_CC_LT,
422 [TCG_COND_LEU] = S390_CC_LE,
423 [TCG_COND_GTU] = S390_CC_GT,
424 [TCG_COND_GEU] = S390_CC_GE,
425};
426
427/* Condition codes that result from a LOAD AND TEST. Here, we have no
428 unsigned instruction variation, however since the test is vs zero we
429 can re-map the outcomes appropriately. */
0aed257f 430static const uint8_t tcg_cond_to_ltr_cond[] = {
48bb3750
RH
431 [TCG_COND_EQ] = S390_CC_EQ,
432 [TCG_COND_NE] = S390_CC_NE,
433 [TCG_COND_LT] = S390_CC_LT,
434 [TCG_COND_LE] = S390_CC_LE,
435 [TCG_COND_GT] = S390_CC_GT,
436 [TCG_COND_GE] = S390_CC_GE,
437 [TCG_COND_LTU] = S390_CC_NEVER,
438 [TCG_COND_LEU] = S390_CC_EQ,
439 [TCG_COND_GTU] = S390_CC_NE,
440 [TCG_COND_GEU] = S390_CC_ALWAYS,
441};
442
79dae4dd 443static const tcg_insn_unit *tb_ret_addr;
34ef7676 444uint64_t s390_facilities[3];
2827822e 445
2dabf742
RH
446static inline bool is_general_reg(TCGReg r)
447{
448 return r <= TCG_REG_R15;
449}
450
451static inline bool is_vector_reg(TCGReg r)
452{
453 return r >= TCG_REG_V0 && r <= TCG_REG_V31;
454}
455
79dae4dd 456static bool patch_reloc(tcg_insn_unit *src_rw, int type,
2ba7fae2 457 intptr_t value, intptr_t addend)
2827822e 458{
79dae4dd 459 const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
e692a349 460 intptr_t pcrel2;
28eef8aa 461 uint32_t old;
e692a349
RH
462
463 value += addend;
79dae4dd 464 pcrel2 = (tcg_insn_unit *)value - src_rx;
48bb3750
RH
465
466 switch (type) {
467 case R_390_PC16DBL:
55dfd8fe 468 if (pcrel2 == (int16_t)pcrel2) {
79dae4dd 469 tcg_patch16(src_rw, pcrel2);
55dfd8fe
RH
470 return true;
471 }
48bb3750
RH
472 break;
473 case R_390_PC32DBL:
55dfd8fe 474 if (pcrel2 == (int32_t)pcrel2) {
79dae4dd 475 tcg_patch32(src_rw, pcrel2);
55dfd8fe
RH
476 return true;
477 }
48bb3750 478 break;
28eef8aa 479 case R_390_20:
55dfd8fe 480 if (value == sextract64(value, 0, 20)) {
79dae4dd 481 old = *(uint32_t *)src_rw & 0xf00000ff;
55dfd8fe 482 old |= ((value & 0xfff) << 16) | ((value & 0xff000) >> 4);
79dae4dd 483 tcg_patch32(src_rw, old);
55dfd8fe
RH
484 return true;
485 }
28eef8aa 486 break;
48bb3750 487 default:
e692a349 488 g_assert_not_reached();
48bb3750 489 }
55dfd8fe 490 return false;
2827822e
AG
491}
492
b2509acc
RH
493static int is_const_p16(uint64_t val)
494{
495 for (int i = 0; i < 4; ++i) {
496 uint64_t mask = 0xffffull << (i * 16);
497 if ((val & ~mask) == 0) {
498 return i;
499 }
500 }
501 return -1;
502}
503
504static int is_const_p32(uint64_t val)
505{
506 if ((val & 0xffffffff00000000ull) == 0) {
507 return 0;
508 }
509 if ((val & 0x00000000ffffffffull) == 0) {
510 return 1;
511 }
512 return -1;
513}
514
4134083f
RH
515/*
516 * Accept bit patterns like these:
517 * 0....01....1
518 * 1....10....0
519 * 1..10..01..1
520 * 0..01..10..0
521 * Copied from gcc sources.
522 */
523static bool risbg_mask(uint64_t c)
524{
525 uint64_t lsb;
526 /* We don't change the number of transitions by inverting,
527 so make sure we start with the LSB zero. */
528 if (c & 1) {
529 c = ~c;
530 }
531 /* Reject all zeros or all ones. */
532 if (c == 0) {
533 return false;
534 }
535 /* Find the first transition. */
536 lsb = c & -c;
537 /* Invert to look for a second transition. */
538 c = ~c;
539 /* Erase the first transition. */
540 c &= -lsb;
541 /* Find the second transition, if any. */
542 lsb = c & -c;
543 /* Match if all the bits are 1's, or if c is zero. */
544 return c == -lsb;
545}
546
2827822e 547/* Test if a constant matches the constraint. */
a4fbbd77 548static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
2827822e 549{
48bb3750
RH
550 if (ct & TCG_CT_CONST) {
551 return 1;
552 }
553
671c835b 554 if (type == TCG_TYPE_I32) {
48bb3750
RH
555 val = (int32_t)val;
556 }
557
558 /* The following are mutually exclusive. */
a8f0269e
RH
559 if (ct & TCG_CT_CONST_S16) {
560 return val == (int16_t)val;
561 } else if (ct & TCG_CT_CONST_S32) {
562 return val == (int32_t)val;
ba18b07d
RH
563 } else if (ct & TCG_CT_CONST_S33) {
564 return val >= -0xffffffffll && val <= 0xffffffffll;
752b1be9
RH
565 } else if (ct & TCG_CT_CONST_ZERO) {
566 return val == 0;
48bb3750
RH
567 }
568
4134083f
RH
569 if (ct & TCG_CT_CONST_INV) {
570 val = ~val;
571 }
b2509acc
RH
572 /*
573 * Note that is_const_p16 is a subset of is_const_p32,
574 * so we don't need both constraints.
575 */
576 if ((ct & TCG_CT_CONST_P32) && is_const_p32(val) >= 0) {
577 return true;
578 }
4134083f
RH
579 if ((ct & TCG_CT_CONST_INVRISBG) && risbg_mask(~val)) {
580 return true;
581 }
b2509acc 582
2827822e
AG
583 return 0;
584}
585
48bb3750
RH
586/* Emit instructions according to the given instruction format. */
587
588static void tcg_out_insn_RR(TCGContext *s, S390Opcode op, TCGReg r1, TCGReg r2)
589{
590 tcg_out16(s, (op << 8) | (r1 << 4) | r2);
591}
592
593static void tcg_out_insn_RRE(TCGContext *s, S390Opcode op,
594 TCGReg r1, TCGReg r2)
595{
596 tcg_out32(s, (op << 16) | (r1 << 4) | r2);
597}
598
0bbf0f7a 599/* RRF-a without the m4 field */
1dd06b1a
RH
600static void tcg_out_insn_RRFa(TCGContext *s, S390Opcode op,
601 TCGReg r1, TCGReg r2, TCGReg r3)
602{
603 tcg_out32(s, (op << 16) | (r3 << 12) | (r1 << 4) | r2);
604}
605
0bbf0f7a
RH
606/* RRF-a with the m4 field */
607static void tcg_out_insn_RRFam(TCGContext *s, S390Opcode op,
608 TCGReg r1, TCGReg r2, TCGReg r3, int m4)
609{
610 tcg_out32(s, (op << 16) | (r3 << 12) | (m4 << 8) | (r1 << 4) | r2);
611}
612
1dd06b1a
RH
613static void tcg_out_insn_RRFc(TCGContext *s, S390Opcode op,
614 TCGReg r1, TCGReg r2, int m3)
96a9f093
RH
615{
616 tcg_out32(s, (op << 16) | (m3 << 12) | (r1 << 4) | r2);
617}
618
48bb3750
RH
619static void tcg_out_insn_RI(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
620{
621 tcg_out32(s, (op << 16) | (r1 << 20) | (i2 & 0xffff));
622}
623
d84ca804 624static void tcg_out_insn_RIEg(TCGContext *s, S390Opcode op, TCGReg r1,
7af525af
RH
625 int i2, int m3)
626{
627 tcg_out16(s, (op & 0xff00) | (r1 << 4) | m3);
628 tcg_out32(s, (i2 << 16) | (op & 0xff));
629}
630
48bb3750
RH
631static void tcg_out_insn_RIL(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
632{
633 tcg_out16(s, op | (r1 << 4));
634 tcg_out32(s, i2);
635}
636
637static void tcg_out_insn_RS(TCGContext *s, S390Opcode op, TCGReg r1,
638 TCGReg b2, TCGReg r3, int disp)
639{
640 tcg_out32(s, (op << 24) | (r1 << 20) | (r3 << 16) | (b2 << 12)
641 | (disp & 0xfff));
642}
643
644static void tcg_out_insn_RSY(TCGContext *s, S390Opcode op, TCGReg r1,
645 TCGReg b2, TCGReg r3, int disp)
646{
647 tcg_out16(s, (op & 0xff00) | (r1 << 4) | r3);
648 tcg_out32(s, (op & 0xff) | (b2 << 28)
649 | ((disp & 0xfff) << 16) | ((disp & 0xff000) >> 4));
650}
651
652#define tcg_out_insn_RX tcg_out_insn_RS
653#define tcg_out_insn_RXY tcg_out_insn_RSY
654
2dabf742
RH
655static int RXB(TCGReg v1, TCGReg v2, TCGReg v3, TCGReg v4)
656{
657 /*
658 * Shift bit 4 of each regno to its corresponding bit of RXB.
659 * RXB itself begins at bit 8 of the instruction so 8 - 4 = 4
660 * is the left-shift of the 4th operand.
661 */
662 return ((v1 & 0x10) << (4 + 3))
663 | ((v2 & 0x10) << (4 + 2))
664 | ((v3 & 0x10) << (4 + 1))
665 | ((v4 & 0x10) << (4 + 0));
666}
667
79cada86
RH
668static void tcg_out_insn_VRIa(TCGContext *s, S390Opcode op,
669 TCGReg v1, uint16_t i2, int m3)
670{
671 tcg_debug_assert(is_vector_reg(v1));
672 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4));
673 tcg_out16(s, i2);
674 tcg_out16(s, (op & 0x00ff) | RXB(v1, 0, 0, 0) | (m3 << 12));
675}
676
677static void tcg_out_insn_VRIb(TCGContext *s, S390Opcode op,
678 TCGReg v1, uint8_t i2, uint8_t i3, int m4)
679{
680 tcg_debug_assert(is_vector_reg(v1));
681 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4));
682 tcg_out16(s, (i2 << 8) | (i3 & 0xff));
683 tcg_out16(s, (op & 0x00ff) | RXB(v1, 0, 0, 0) | (m4 << 12));
684}
685
686static void tcg_out_insn_VRIc(TCGContext *s, S390Opcode op,
687 TCGReg v1, uint16_t i2, TCGReg v3, int m4)
688{
689 tcg_debug_assert(is_vector_reg(v1));
690 tcg_debug_assert(is_vector_reg(v3));
691 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | (v3 & 0xf));
692 tcg_out16(s, i2);
693 tcg_out16(s, (op & 0x00ff) | RXB(v1, 0, v3, 0) | (m4 << 12));
694}
695
b33ce725
RH
696static void tcg_out_insn_VRRa(TCGContext *s, S390Opcode op,
697 TCGReg v1, TCGReg v2, int m3)
698{
699 tcg_debug_assert(is_vector_reg(v1));
700 tcg_debug_assert(is_vector_reg(v2));
701 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | (v2 & 0xf));
702 tcg_out32(s, (op & 0x00ff) | RXB(v1, v2, 0, 0) | (m3 << 12));
703}
704
a429ee29
RH
705static void tcg_out_insn_VRRc(TCGContext *s, S390Opcode op,
706 TCGReg v1, TCGReg v2, TCGReg v3, int m4)
707{
708 tcg_debug_assert(is_vector_reg(v1));
709 tcg_debug_assert(is_vector_reg(v2));
710 tcg_debug_assert(is_vector_reg(v3));
711 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | (v2 & 0xf));
712 tcg_out16(s, v3 << 12);
713 tcg_out16(s, (op & 0x00ff) | RXB(v1, v2, v3, 0) | (m4 << 12));
714}
715
9bca986d
RH
716static void tcg_out_insn_VRRe(TCGContext *s, S390Opcode op,
717 TCGReg v1, TCGReg v2, TCGReg v3, TCGReg v4)
718{
719 tcg_debug_assert(is_vector_reg(v1));
720 tcg_debug_assert(is_vector_reg(v2));
721 tcg_debug_assert(is_vector_reg(v3));
722 tcg_debug_assert(is_vector_reg(v4));
723 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | (v2 & 0xf));
724 tcg_out16(s, v3 << 12);
725 tcg_out16(s, (op & 0x00ff) | RXB(v1, v2, v3, v4) | (v4 << 12));
726}
727
79cada86
RH
728static void tcg_out_insn_VRRf(TCGContext *s, S390Opcode op,
729 TCGReg v1, TCGReg r2, TCGReg r3)
730{
731 tcg_debug_assert(is_vector_reg(v1));
732 tcg_debug_assert(is_general_reg(r2));
733 tcg_debug_assert(is_general_reg(r3));
734 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | r2);
735 tcg_out16(s, r3 << 12);
736 tcg_out16(s, (op & 0x00ff) | RXB(v1, 0, 0, 0));
737}
738
22cb37b4
RH
739static void tcg_out_insn_VRSa(TCGContext *s, S390Opcode op, TCGReg v1,
740 intptr_t d2, TCGReg b2, TCGReg v3, int m4)
741{
742 tcg_debug_assert(is_vector_reg(v1));
743 tcg_debug_assert(d2 >= 0 && d2 <= 0xfff);
744 tcg_debug_assert(is_general_reg(b2));
745 tcg_debug_assert(is_vector_reg(v3));
746 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | (v3 & 0xf));
747 tcg_out16(s, b2 << 12 | d2);
748 tcg_out16(s, (op & 0x00ff) | RXB(v1, 0, v3, 0) | (m4 << 12));
749}
750
b33ce725
RH
751static void tcg_out_insn_VRSb(TCGContext *s, S390Opcode op, TCGReg v1,
752 intptr_t d2, TCGReg b2, TCGReg r3, int m4)
753{
754 tcg_debug_assert(is_vector_reg(v1));
755 tcg_debug_assert(d2 >= 0 && d2 <= 0xfff);
756 tcg_debug_assert(is_general_reg(b2));
757 tcg_debug_assert(is_general_reg(r3));
758 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | r3);
759 tcg_out16(s, b2 << 12 | d2);
760 tcg_out16(s, (op & 0x00ff) | RXB(v1, 0, 0, 0) | (m4 << 12));
761}
762
763static void tcg_out_insn_VRSc(TCGContext *s, S390Opcode op, TCGReg r1,
764 intptr_t d2, TCGReg b2, TCGReg v3, int m4)
765{
766 tcg_debug_assert(is_general_reg(r1));
767 tcg_debug_assert(d2 >= 0 && d2 <= 0xfff);
768 tcg_debug_assert(is_general_reg(b2));
769 tcg_debug_assert(is_vector_reg(v3));
770 tcg_out16(s, (op & 0xff00) | (r1 << 4) | (v3 & 0xf));
771 tcg_out16(s, b2 << 12 | d2);
772 tcg_out16(s, (op & 0x00ff) | RXB(0, 0, v3, 0) | (m4 << 12));
773}
774
2dabf742
RH
775static void tcg_out_insn_VRX(TCGContext *s, S390Opcode op, TCGReg v1,
776 TCGReg b2, TCGReg x2, intptr_t d2, int m3)
777{
778 tcg_debug_assert(is_vector_reg(v1));
779 tcg_debug_assert(d2 >= 0 && d2 <= 0xfff);
780 tcg_debug_assert(is_general_reg(x2));
781 tcg_debug_assert(is_general_reg(b2));
782 tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | x2);
783 tcg_out16(s, (b2 << 12) | d2);
784 tcg_out16(s, (op & 0x00ff) | RXB(v1, 0, 0, 0) | (m3 << 12));
785}
786
48bb3750
RH
787/* Emit an opcode with "type-checking" of the format. */
788#define tcg_out_insn(S, FMT, OP, ...) \
789 glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
790
791
792/* emit 64-bit shifts */
793static void tcg_out_sh64(TCGContext* s, S390Opcode op, TCGReg dest,
794 TCGReg src, TCGReg sh_reg, int sh_imm)
795{
796 tcg_out_insn_RSY(s, op, dest, sh_reg, src, sh_imm);
797}
798
799/* emit 32-bit shifts */
800static void tcg_out_sh32(TCGContext* s, S390Opcode op, TCGReg dest,
801 TCGReg sh_reg, int sh_imm)
802{
803 tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
804}
805
78113e83 806static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
48bb3750 807{
b33ce725
RH
808 if (src == dst) {
809 return true;
810 }
811 switch (type) {
812 case TCG_TYPE_I32:
813 if (likely(is_general_reg(dst) && is_general_reg(src))) {
48bb3750 814 tcg_out_insn(s, RR, LR, dst, src);
b33ce725 815 break;
48bb3750 816 }
b33ce725
RH
817 /* fallthru */
818
819 case TCG_TYPE_I64:
820 if (likely(is_general_reg(dst))) {
821 if (likely(is_general_reg(src))) {
822 tcg_out_insn(s, RRE, LGR, dst, src);
823 } else {
824 tcg_out_insn(s, VRSc, VLGV, dst, 0, 0, src, 3);
825 }
826 break;
827 } else if (is_general_reg(src)) {
828 tcg_out_insn(s, VRSb, VLVG, dst, 0, 0, src, 3);
829 break;
830 }
831 /* fallthru */
832
833 case TCG_TYPE_V64:
834 case TCG_TYPE_V128:
835 tcg_out_insn(s, VRRa, VLR, dst, src, 0);
836 break;
837
838 default:
839 g_assert_not_reached();
48bb3750 840 }
78113e83 841 return true;
48bb3750
RH
842}
843
1818c71b 844static const S390Opcode li_insns[4] = {
28eef8aa
RH
845 RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
846};
90497e03
RH
847static const S390Opcode oi_insns[4] = {
848 RI_OILL, RI_OILH, RI_OIHL, RI_OIHH
849};
1818c71b
RH
850static const S390Opcode lif_insns[2] = {
851 RIL_LLILF, RIL_LLIHF,
852};
48bb3750 853
1818c71b
RH
854/* load a register with an immediate value */
855static void tcg_out_movi(TCGContext *s, TCGType type,
856 TCGReg ret, tcg_target_long sval)
28eef8aa 857{
48bb3750 858 tcg_target_ulong uval = sval;
1818c71b 859 ptrdiff_t pc_off;
48bb3750
RH
860 int i;
861
862 if (type == TCG_TYPE_I32) {
863 uval = (uint32_t)sval;
864 sval = (int32_t)sval;
865 }
866
867 /* Try all 32-bit insns that can load it in one go. */
868 if (sval >= -0x8000 && sval < 0x8000) {
869 tcg_out_insn(s, RI, LGHI, ret, sval);
28eef8aa
RH
870 return;
871 }
872
1818c71b
RH
873 i = is_const_p16(uval);
874 if (i >= 0) {
875 tcg_out_insn_RI(s, li_insns[i], ret, uval >> (i * 16));
876 return;
28eef8aa
RH
877 }
878
48bb3750 879 /* Try all 48-bit insns that can load it in one go. */
3e25f7da
RH
880 if (sval == (int32_t)sval) {
881 tcg_out_insn(s, RIL, LGFI, ret, sval);
882 return;
883 }
1818c71b
RH
884
885 i = is_const_p32(uval);
886 if (i >= 0) {
887 tcg_out_insn_RIL(s, lif_insns[i], ret, uval >> (i * 32));
3e25f7da 888 return;
48bb3750
RH
889 }
890
1b74cf6e
RH
891 /* Try for PC-relative address load. For odd addresses, add one. */
892 pc_off = tcg_pcrel_diff(s, (void *)sval) >> 1;
893 if (pc_off == (int32_t)pc_off) {
894 tcg_out_insn(s, RIL, LARL, ret, pc_off);
895 if (sval & 1) {
896 tcg_out_insn(s, RI, AGHI, ret, 1);
48bb3750 897 }
1b74cf6e 898 return;
48bb3750
RH
899 }
900
90497e03
RH
901 /* Otherwise, load it by parts. */
902 i = is_const_p16((uint32_t)uval);
903 if (i >= 0) {
904 tcg_out_insn_RI(s, li_insns[i], ret, uval >> (i * 16));
905 } else {
906 tcg_out_insn(s, RIL, LLILF, ret, uval);
907 }
908 uval >>= 32;
909 i = is_const_p16(uval);
910 if (i >= 0) {
911 tcg_out_insn_RI(s, oi_insns[i + 2], ret, uval >> (i * 16));
912 } else {
913 tcg_out_insn(s, RIL, OIHF, ret, uval);
914 }
48bb3750
RH
915}
916
48bb3750
RH
917/* Emit a load/store type instruction. Inputs are:
918 DATA: The register to be loaded or stored.
919 BASE+OFS: The effective address.
920 OPC_RX: If the operation has an RX format opcode (e.g. STC), otherwise 0.
921 OPC_RXY: The RXY format opcode for the operation (e.g. STCY). */
922
923static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
924 TCGReg data, TCGReg base, TCGReg index,
925 tcg_target_long ofs)
926{
927 if (ofs < -0x80000 || ofs >= 0x80000) {
78c9f7c5
RH
928 /* Combine the low 20 bits of the offset with the actual load insn;
929 the high 44 bits must come from an immediate load. */
930 tcg_target_long low = ((ofs & 0xfffff) ^ 0x80000) - 0x80000;
931 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - low);
932 ofs = low;
48bb3750
RH
933
934 /* If we were already given an index register, add it in. */
935 if (index != TCG_REG_NONE) {
936 tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
937 }
938 index = TCG_TMP0;
939 }
940
941 if (opc_rx && ofs >= 0 && ofs < 0x1000) {
942 tcg_out_insn_RX(s, opc_rx, data, base, index, ofs);
943 } else {
944 tcg_out_insn_RXY(s, opc_rxy, data, base, index, ofs);
945 }
2827822e
AG
946}
947
2dabf742
RH
948static void tcg_out_vrx_mem(TCGContext *s, S390Opcode opc_vrx,
949 TCGReg data, TCGReg base, TCGReg index,
950 tcg_target_long ofs, int m3)
951{
952 if (ofs < 0 || ofs >= 0x1000) {
953 if (ofs >= -0x80000 && ofs < 0x80000) {
954 tcg_out_insn(s, RXY, LAY, TCG_TMP0, base, index, ofs);
955 base = TCG_TMP0;
956 index = TCG_REG_NONE;
957 ofs = 0;
958 } else {
959 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs);
960 if (index != TCG_REG_NONE) {
961 tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
962 }
963 index = TCG_TMP0;
964 ofs = 0;
965 }
966 }
967 tcg_out_insn_VRX(s, opc_vrx, data, base, index, ofs, m3);
968}
48bb3750 969
2827822e 970/* load data without address translation or endianness conversion */
2dabf742
RH
971static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
972 TCGReg base, intptr_t ofs)
2827822e 973{
2dabf742
RH
974 switch (type) {
975 case TCG_TYPE_I32:
976 if (likely(is_general_reg(data))) {
977 tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs);
978 break;
979 }
980 tcg_out_vrx_mem(s, VRX_VLLEZ, data, base, TCG_REG_NONE, ofs, MO_32);
981 break;
982
983 case TCG_TYPE_I64:
984 if (likely(is_general_reg(data))) {
985 tcg_out_mem(s, 0, RXY_LG, data, base, TCG_REG_NONE, ofs);
986 break;
987 }
988 /* fallthru */
989
990 case TCG_TYPE_V64:
991 tcg_out_vrx_mem(s, VRX_VLLEZ, data, base, TCG_REG_NONE, ofs, MO_64);
992 break;
993
994 case TCG_TYPE_V128:
995 /* Hint quadword aligned. */
996 tcg_out_vrx_mem(s, VRX_VL, data, base, TCG_REG_NONE, ofs, 4);
997 break;
998
999 default:
1000 g_assert_not_reached();
48bb3750 1001 }
2827822e
AG
1002}
1003
2dabf742
RH
1004static void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
1005 TCGReg base, intptr_t ofs)
2827822e 1006{
2dabf742
RH
1007 switch (type) {
1008 case TCG_TYPE_I32:
1009 if (likely(is_general_reg(data))) {
1010 tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs);
1011 } else {
1012 tcg_out_vrx_mem(s, VRX_VSTEF, data, base, TCG_REG_NONE, ofs, 1);
1013 }
1014 break;
1015
1016 case TCG_TYPE_I64:
1017 if (likely(is_general_reg(data))) {
1018 tcg_out_mem(s, 0, RXY_STG, data, base, TCG_REG_NONE, ofs);
1019 break;
1020 }
1021 /* fallthru */
1022
1023 case TCG_TYPE_V64:
1024 tcg_out_vrx_mem(s, VRX_VSTEG, data, base, TCG_REG_NONE, ofs, 0);
1025 break;
1026
1027 case TCG_TYPE_V128:
1028 /* Hint quadword aligned. */
1029 tcg_out_vrx_mem(s, VRX_VST, data, base, TCG_REG_NONE, ofs, 4);
1030 break;
1031
1032 default:
1033 g_assert_not_reached();
48bb3750
RH
1034 }
1035}
1036
59d7c14e
RH
1037static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
1038 TCGReg base, intptr_t ofs)
1039{
1040 return false;
1041}
1042
767c2503
RH
1043static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
1044{
1045 return false;
1046}
1047
6a6d772e
RH
1048static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
1049 tcg_target_long imm)
1050{
1051 /* This function is only used for passing structs by reference. */
1052 tcg_out_mem(s, RX_LA, RXY_LAY, rd, rs, TCG_REG_NONE, imm);
1053}
1054
f0bffc27
RH
1055static inline void tcg_out_risbg(TCGContext *s, TCGReg dest, TCGReg src,
1056 int msb, int lsb, int ofs, int z)
1057{
1058 /* Format RIE-f */
d84ca804 1059 tcg_out16(s, (RIEf_RISBG & 0xff00) | (dest << 4) | src);
f0bffc27 1060 tcg_out16(s, (msb << 8) | (z << 7) | lsb);
d84ca804 1061 tcg_out16(s, (ofs << 8) | (RIEf_RISBG & 0xff));
f0bffc27
RH
1062}
1063
678155b2 1064static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
48bb3750 1065{
3e25f7da 1066 tcg_out_insn(s, RRE, LGBR, dest, src);
48bb3750
RH
1067}
1068
d0e66c89 1069static void tcg_out_ext8u(TCGContext *s, TCGReg dest, TCGReg src)
48bb3750 1070{
3e25f7da 1071 tcg_out_insn(s, RRE, LLGCR, dest, src);
48bb3750
RH
1072}
1073
753e42ea 1074static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
48bb3750 1075{
3e25f7da 1076 tcg_out_insn(s, RRE, LGHR, dest, src);
48bb3750
RH
1077}
1078
379afdff 1079static void tcg_out_ext16u(TCGContext *s, TCGReg dest, TCGReg src)
48bb3750 1080{
3e25f7da 1081 tcg_out_insn(s, RRE, LLGHR, dest, src);
48bb3750
RH
1082}
1083
52bf3398 1084static void tcg_out_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
48bb3750
RH
1085{
1086 tcg_out_insn(s, RRE, LGFR, dest, src);
1087}
1088
9ecf5f61 1089static void tcg_out_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
48bb3750
RH
1090{
1091 tcg_out_insn(s, RRE, LLGFR, dest, src);
1092}
1093
9c6aa274
RH
1094static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg dest, TCGReg src)
1095{
1096 tcg_out_ext32s(s, dest, src);
1097}
1098
b9bfe000
RH
1099static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg dest, TCGReg src)
1100{
1101 tcg_out_ext32u(s, dest, src);
1102}
1103
b8b94ac6
RH
1104static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg dest, TCGReg src)
1105{
1106 tcg_out_mov(s, TCG_TYPE_I32, dest, src);
1107}
1108
547ec121
RH
1109static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val)
1110{
1111 int msb, lsb;
1112 if ((val & 0x8000000000000001ull) == 0x8000000000000001ull) {
1113 /* Achieve wraparound by swapping msb and lsb. */
1114 msb = 64 - ctz64(~val);
1115 lsb = clz64(~val) - 1;
1116 } else {
1117 msb = clz64(val);
1118 lsb = 63 - ctz64(val);
1119 }
1120 tcg_out_risbg(s, out, in, msb, lsb, 0, 1);
1121}
1122
07ff7983 1123static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
48bb3750
RH
1124{
1125 static const S390Opcode ni_insns[4] = {
1126 RI_NILL, RI_NILH, RI_NIHL, RI_NIHH
1127 };
1128 static const S390Opcode nif_insns[2] = {
1129 RIL_NILF, RIL_NIHF
1130 };
07ff7983 1131 uint64_t valid = (type == TCG_TYPE_I32 ? 0xffffffffull : -1ull);
48bb3750
RH
1132 int i;
1133
48bb3750 1134 /* Look for the zero-extensions. */
07ff7983 1135 if ((val & valid) == 0xffffffff) {
9ecf5f61 1136 tcg_out_ext32u(s, dest, dest);
48bb3750
RH
1137 return;
1138 }
3e25f7da 1139 if ((val & valid) == 0xff) {
d0e66c89 1140 tcg_out_ext8u(s, dest, dest);
3e25f7da
RH
1141 return;
1142 }
1143 if ((val & valid) == 0xffff) {
379afdff 1144 tcg_out_ext16u(s, dest, dest);
3e25f7da 1145 return;
07ff7983 1146 }
48bb3750 1147
4134083f
RH
1148 i = is_const_p16(~val & valid);
1149 if (i >= 0) {
1150 tcg_out_insn_RI(s, ni_insns[i], dest, val >> (i * 16));
1151 return;
07ff7983 1152 }
48bb3750 1153
4134083f
RH
1154 i = is_const_p32(~val & valid);
1155 tcg_debug_assert(i == 0 || type != TCG_TYPE_I32);
1156 if (i >= 0) {
1157 tcg_out_insn_RIL(s, nif_insns[i], dest, val >> (i * 32));
1158 return;
07ff7983 1159 }
4134083f 1160
9c3bfb79 1161 if (risbg_mask(val)) {
547ec121 1162 tgen_andi_risbg(s, dest, dest, val);
f0bffc27
RH
1163 return;
1164 }
48bb3750 1165
4134083f 1166 g_assert_not_reached();
48bb3750
RH
1167}
1168
b2509acc 1169static void tgen_ori(TCGContext *s, TCGReg dest, uint64_t val)
48bb3750 1170{
4046d9ca 1171 static const S390Opcode oif_insns[2] = {
48bb3750
RH
1172 RIL_OILF, RIL_OIHF
1173 };
1174
1175 int i;
1176
b2509acc
RH
1177 i = is_const_p16(val);
1178 if (i >= 0) {
1179 tcg_out_insn_RI(s, oi_insns[i], dest, val >> (i * 16));
48bb3750
RH
1180 return;
1181 }
1182
b2509acc
RH
1183 i = is_const_p32(val);
1184 if (i >= 0) {
1185 tcg_out_insn_RIL(s, oif_insns[i], dest, val >> (i * 32));
1186 return;
4046d9ca 1187 }
48bb3750 1188
b2509acc 1189 g_assert_not_reached();
48bb3750
RH
1190}
1191
b2509acc 1192static void tgen_xori(TCGContext *s, TCGReg dest, uint64_t val)
48bb3750 1193{
b2509acc
RH
1194 switch (is_const_p32(val)) {
1195 case 0:
3e25f7da 1196 tcg_out_insn(s, RIL, XILF, dest, val);
b2509acc
RH
1197 break;
1198 case 1:
3e25f7da 1199 tcg_out_insn(s, RIL, XIHF, dest, val >> 32);
b2509acc
RH
1200 break;
1201 default:
1202 g_assert_not_reached();
48bb3750
RH
1203 }
1204}
1205
5c837bbc
RH
1206static int tgen_cmp2(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
1207 TCGArg c2, bool c2const, bool need_carry, int *inv_cc)
48bb3750 1208{
bcc66562 1209 bool is_unsigned = is_unsigned_cond(c);
5c837bbc 1210 TCGCond inv_c = tcg_invert_cond(c);
a534bb15
RH
1211 S390Opcode op;
1212
48bb3750
RH
1213 if (c2const) {
1214 if (c2 == 0) {
65839b56
RH
1215 if (!(is_unsigned && need_carry)) {
1216 if (type == TCG_TYPE_I32) {
1217 tcg_out_insn(s, RR, LTR, r1, r1);
1218 } else {
1219 tcg_out_insn(s, RRE, LTGR, r1, r1);
1220 }
5c837bbc 1221 *inv_cc = tcg_cond_to_ltr_cond[inv_c];
65839b56
RH
1222 return tcg_cond_to_ltr_cond[c];
1223 }
65839b56 1224 }
a534bb15
RH
1225
1226 if (!is_unsigned && c2 == (int16_t)c2) {
1227 op = (type == TCG_TYPE_I32 ? RI_CHI : RI_CGHI);
1228 tcg_out_insn_RI(s, op, r1, c2);
1229 goto exit;
1230 }
1231
3e25f7da
RH
1232 if (type == TCG_TYPE_I32) {
1233 op = (is_unsigned ? RIL_CLFI : RIL_CFI);
1234 tcg_out_insn_RIL(s, op, r1, c2);
1235 goto exit;
1236 }
32c256ed
RH
1237
1238 /*
1239 * Constraints are for a signed 33-bit operand, which is a
1240 * convenient superset of this signed/unsigned test.
1241 */
3e25f7da
RH
1242 if (c2 == (is_unsigned ? (TCGArg)(uint32_t)c2 : (TCGArg)(int32_t)c2)) {
1243 op = (is_unsigned ? RIL_CLGFI : RIL_CGFI);
1244 tcg_out_insn_RIL(s, op, r1, c2);
1245 goto exit;
48bb3750 1246 }
a534bb15 1247
32c256ed
RH
1248 /* Load everything else into a register. */
1249 tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, c2);
1250 c2 = TCG_TMP0;
48bb3750 1251 }
a534bb15
RH
1252
1253 if (type == TCG_TYPE_I32) {
1254 op = (is_unsigned ? RR_CLR : RR_CR);
1255 tcg_out_insn_RR(s, op, r1, c2);
1256 } else {
1257 op = (is_unsigned ? RRE_CLGR : RRE_CGR);
1258 tcg_out_insn_RRE(s, op, r1, c2);
1259 }
1260
1261 exit:
5c837bbc 1262 *inv_cc = tcg_cond_to_s390_cond[inv_c];
48bb3750
RH
1263 return tcg_cond_to_s390_cond[c];
1264}
1265
5c837bbc
RH
1266static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
1267 TCGArg c2, bool c2const, bool need_carry)
1268{
1269 int inv_cc;
1270 return tgen_cmp2(s, type, c, r1, c2, c2const, need_carry, &inv_cc);
1271}
1272
7b7066b1 1273static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
96a9f093 1274 TCGReg dest, TCGReg c1, TCGArg c2, int c2const)
48bb3750 1275{
7b7066b1
RH
1276 int cc;
1277
7af525af 1278 /* With LOC2, we can always emit the minimum 3 insns. */
748b7f3e 1279 if (HAVE_FACILITY(LOAD_ON_COND2)) {
7af525af
RH
1280 /* Emit: d = 0, d = (cc ? 1 : d). */
1281 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1282 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
d84ca804 1283 tcg_out_insn(s, RIEg, LOCGHI, dest, 1, cc);
7af525af
RH
1284 return;
1285 }
1286
4609190b 1287 restart:
7b7066b1 1288 switch (cond) {
4609190b
RH
1289 case TCG_COND_NE:
1290 /* X != 0 is X > 0. */
1291 if (c2const && c2 == 0) {
1292 cond = TCG_COND_GTU;
1293 } else {
1294 break;
1295 }
1296 /* fallthru */
1297
7b7066b1
RH
1298 case TCG_COND_GTU:
1299 case TCG_COND_GT:
7b7066b1
RH
1300 /* The result of a compare has CC=2 for GT and CC=3 unused.
1301 ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */
65839b56 1302 tgen_cmp(s, type, cond, c1, c2, c2const, true);
7b7066b1
RH
1303 tcg_out_movi(s, type, dest, 0);
1304 tcg_out_insn(s, RRE, ALCGR, dest, dest);
1305 return;
1306
4609190b
RH
1307 case TCG_COND_EQ:
1308 /* X == 0 is X <= 0. */
1309 if (c2const && c2 == 0) {
1310 cond = TCG_COND_LEU;
7b7066b1 1311 } else {
4609190b 1312 break;
7b7066b1 1313 }
4609190b 1314 /* fallthru */
7b7066b1
RH
1315
1316 case TCG_COND_LEU:
4609190b
RH
1317 case TCG_COND_LE:
1318 /* As above, but we're looking for borrow, or !carry.
1319 The second insn computes d - d - borrow, or -1 for true
1320 and 0 for false. So we must mask to 1 bit afterward. */
1321 tgen_cmp(s, type, cond, c1, c2, c2const, true);
1322 tcg_out_insn(s, RRE, SLBGR, dest, dest);
1323 tgen_andi(s, type, dest, 1);
1324 return;
1325
1326 case TCG_COND_GEU:
7b7066b1
RH
1327 case TCG_COND_LTU:
1328 case TCG_COND_LT:
4609190b
RH
1329 case TCG_COND_GE:
1330 /* Swap operands so that we can use LEU/GTU/GT/LE. */
c68d5b7a 1331 if (!c2const) {
7b7066b1
RH
1332 TCGReg t = c1;
1333 c1 = c2;
1334 c2 = t;
c68d5b7a
RH
1335 cond = tcg_swap_cond(cond);
1336 goto restart;
7b7066b1 1337 }
c68d5b7a 1338 break;
48bb3750 1339
7b7066b1 1340 default:
4609190b 1341 g_assert_not_reached();
7b7066b1
RH
1342 }
1343
65839b56 1344 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
c68d5b7a
RH
1345 /* Emit: d = 0, t = 1, d = (cc ? t : d). */
1346 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1347 tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 1);
1dd06b1a 1348 tcg_out_insn(s, RRFc, LOCGR, dest, TCG_TMP0, cc);
48bb3750
RH
1349}
1350
23d1394a
RH
1351static void tgen_movcond_int(TCGContext *s, TCGType type, TCGReg dest,
1352 TCGArg v3, int v3const, TCGReg v4,
1353 int cc, int inv_cc)
1354{
1355 TCGReg src;
1356
1357 if (v3const) {
1358 if (dest == v4) {
1359 if (HAVE_FACILITY(LOAD_ON_COND2)) {
1360 /* Emit: if (cc) dest = v3. */
1361 tcg_out_insn(s, RIEg, LOCGHI, dest, v3, cc);
1362 return;
1363 }
1364 tcg_out_insn(s, RI, LGHI, TCG_TMP0, v3);
1365 src = TCG_TMP0;
1366 } else {
1367 /* LGR+LOCGHI is larger than LGHI+LOCGR. */
1368 tcg_out_insn(s, RI, LGHI, dest, v3);
1369 cc = inv_cc;
1370 src = v4;
1371 }
1372 } else {
0bbf0f7a
RH
1373 if (HAVE_FACILITY(MISC_INSN_EXT3)) {
1374 /* Emit: dest = cc ? v3 : v4. */
1375 tcg_out_insn(s, RRFam, SELGR, dest, v3, v4, cc);
1376 return;
1377 }
23d1394a
RH
1378 if (dest == v4) {
1379 src = v3;
1380 } else {
1381 tcg_out_mov(s, type, dest, v3);
1382 cc = inv_cc;
1383 src = v4;
1384 }
1385 }
1386
1387 /* Emit: if (cc) dest = src. */
1388 tcg_out_insn(s, RRFc, LOCGR, dest, src, cc);
1389}
1390
96a9f093 1391static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest,
7af525af 1392 TCGReg c1, TCGArg c2, int c2const,
23d1394a 1393 TCGArg v3, int v3const, TCGReg v4)
96a9f093 1394{
5c837bbc
RH
1395 int cc, inv_cc;
1396
1397 cc = tgen_cmp2(s, type, c, c1, c2, c2const, false, &inv_cc);
23d1394a 1398 tgen_movcond_int(s, type, dest, v3, v3const, v4, cc, inv_cc);
96a9f093
RH
1399}
1400
ce411066
RH
1401static void tgen_clz(TCGContext *s, TCGReg dest, TCGReg a1,
1402 TCGArg a2, int a2const)
1403{
1404 /* Since this sets both R and R+1, we have no choice but to store the
1405 result into R0, allowing R1 == TCG_TMP0 to be clobbered as well. */
1406 QEMU_BUILD_BUG_ON(TCG_TMP0 != TCG_REG_R1);
1407 tcg_out_insn(s, RRE, FLOGR, TCG_REG_R0, a1);
1408
1409 if (a2const && a2 == 64) {
1410 tcg_out_mov(s, TCG_TYPE_I64, dest, TCG_REG_R0);
bfff8518 1411 return;
ce411066 1412 }
bfff8518
RH
1413
1414 /*
1415 * Conditions from FLOGR are:
1416 * 2 -> one bit found
1417 * 8 -> no one bit found
1418 */
1419 tgen_movcond_int(s, TCG_TYPE_I64, dest, a2, a2const, TCG_REG_R0, 8, 2);
ce411066
RH
1420}
1421
29a5ea73
RH
1422static void tgen_ctpop(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
1423{
1424 /* With MIE3, and bit 0 of m4 set, we get the complete result. */
1425 if (HAVE_FACILITY(MISC_INSN_EXT3)) {
1426 if (type == TCG_TYPE_I32) {
9ecf5f61 1427 tcg_out_ext32u(s, dest, src);
29a5ea73
RH
1428 src = dest;
1429 }
1430 tcg_out_insn(s, RRFc, POPCNT, dest, src, 8);
1431 return;
1432 }
1433
1434 /* Without MIE3, each byte gets the count of bits for the byte. */
1435 tcg_out_insn(s, RRFc, POPCNT, dest, src, 0);
1436
1437 /* Multiply to sum each byte at the top of the word. */
1438 if (type == TCG_TYPE_I32) {
1439 tcg_out_insn(s, RIL, MSFI, dest, 0x01010101);
1440 tcg_out_sh32(s, RS_SRL, dest, TCG_REG_NONE, 24);
1441 } else {
1442 tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 0x0101010101010101ull);
1443 tcg_out_insn(s, RRE, MSGR, dest, TCG_TMP0);
1444 tcg_out_sh64(s, RSY_SRLG, dest, dest, TCG_REG_NONE, 56);
1445 }
1446}
1447
d5690ea4 1448static void tgen_deposit(TCGContext *s, TCGReg dest, TCGReg src,
752b1be9 1449 int ofs, int len, int z)
d5690ea4
RH
1450{
1451 int lsb = (63 - ofs);
1452 int msb = lsb - (len - 1);
752b1be9 1453 tcg_out_risbg(s, dest, src, msb, lsb, ofs, z);
d5690ea4
RH
1454}
1455
b0bf5fe8
RH
1456static void tgen_extract(TCGContext *s, TCGReg dest, TCGReg src,
1457 int ofs, int len)
1458{
1459 tcg_out_risbg(s, dest, src, 64 - len, 63, 64 - ofs, 1);
1460}
1461
ffd0e507 1462static void tgen_gotoi(TCGContext *s, int cc, const tcg_insn_unit *dest)
48bb3750 1463{
79dae4dd 1464 ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
8c081b18 1465 if (off == (int16_t)off) {
48bb3750
RH
1466 tcg_out_insn(s, RI, BRC, cc, off);
1467 } else if (off == (int32_t)off) {
1468 tcg_out_insn(s, RIL, BRCL, cc, off);
1469 } else {
8c081b18 1470 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
48bb3750
RH
1471 tcg_out_insn(s, RR, BCR, cc, TCG_TMP0);
1472 }
1473}
1474
bec16311 1475static void tgen_branch(TCGContext *s, int cc, TCGLabel *l)
48bb3750 1476{
48bb3750 1477 if (l->has_value) {
8c081b18 1478 tgen_gotoi(s, cc, l->u.value_ptr);
48bb3750
RH
1479 } else {
1480 tcg_out16(s, RI_BRC | (cc << 4));
e692a349 1481 tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, l, 2);
8c081b18 1482 s->code_ptr += 1;
48bb3750
RH
1483 }
1484}
1485
1486static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
bec16311 1487 TCGReg r1, TCGReg r2, TCGLabel *l)
48bb3750 1488{
79dae4dd 1489 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
d84ca804 1490 /* Format RIE-b */
48bb3750 1491 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
79dae4dd 1492 tcg_out16(s, 0);
48bb3750
RH
1493 tcg_out16(s, cc << 12 | (opc & 0xff));
1494}
1495
1496static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
bec16311 1497 TCGReg r1, int i2, TCGLabel *l)
48bb3750 1498{
79dae4dd 1499 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
d84ca804 1500 /* Format RIE-c */
48bb3750 1501 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
79dae4dd 1502 tcg_out16(s, 0);
48bb3750
RH
1503 tcg_out16(s, (i2 << 8) | (opc & 0xff));
1504}
1505
1506static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
bec16311 1507 TCGReg r1, TCGArg c2, int c2const, TCGLabel *l)
48bb3750
RH
1508{
1509 int cc;
9c3bfb79
RH
1510 bool is_unsigned = is_unsigned_cond(c);
1511 bool in_range;
1512 S390Opcode opc;
48bb3750 1513
9c3bfb79 1514 cc = tcg_cond_to_s390_cond[c];
48bb3750 1515
9c3bfb79
RH
1516 if (!c2const) {
1517 opc = (type == TCG_TYPE_I32
d84ca804
RH
1518 ? (is_unsigned ? RIEb_CLRJ : RIEb_CRJ)
1519 : (is_unsigned ? RIEb_CLGRJ : RIEb_CGRJ));
9c3bfb79
RH
1520 tgen_compare_branch(s, opc, cc, r1, c2, l);
1521 return;
1522 }
48bb3750 1523
9c3bfb79
RH
1524 /*
1525 * COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1526 * If the immediate we've been given does not fit that range, we'll
1527 * fall back to separate compare and branch instructions using the
1528 * larger comparison range afforded by COMPARE IMMEDIATE.
1529 */
1530 if (type == TCG_TYPE_I32) {
1531 if (is_unsigned) {
d84ca804 1532 opc = RIEc_CLIJ;
9c3bfb79 1533 in_range = (uint32_t)c2 == (uint8_t)c2;
48bb3750 1534 } else {
d84ca804 1535 opc = RIEc_CIJ;
9c3bfb79 1536 in_range = (int32_t)c2 == (int8_t)c2;
48bb3750 1537 }
9c3bfb79
RH
1538 } else {
1539 if (is_unsigned) {
d84ca804 1540 opc = RIEc_CLGIJ;
9c3bfb79
RH
1541 in_range = (uint64_t)c2 == (uint8_t)c2;
1542 } else {
d84ca804 1543 opc = RIEc_CGIJ;
9c3bfb79 1544 in_range = (int64_t)c2 == (int8_t)c2;
48bb3750
RH
1545 }
1546 }
9c3bfb79
RH
1547 if (in_range) {
1548 tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
1549 return;
1550 }
48bb3750 1551
65839b56 1552 cc = tgen_cmp(s, type, c, r1, c2, c2const, false);
bec16311 1553 tgen_branch(s, cc, l);
48bb3750
RH
1554}
1555
cee44b03 1556static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *dest)
48bb3750 1557{
79dae4dd 1558 ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
48bb3750
RH
1559 if (off == (int32_t)off) {
1560 tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
1561 } else {
8c081b18 1562 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
48bb3750
RH
1563 tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_TMP0);
1564 }
1565}
1566
cee44b03
RH
1567static void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest,
1568 const TCGHelperInfo *info)
1569{
1570 tcg_out_call_int(s, dest);
1571}
1572
03654748
RH
1573typedef struct {
1574 TCGReg base;
1575 TCGReg index;
1576 int disp;
00406e6d 1577 TCGAtomAlign aa;
03654748
RH
1578} HostAddress;
1579
7b880107
RH
1580bool tcg_target_has_memory_bswap(MemOp memop)
1581{
4caad79f
RH
1582 TCGAtomAlign aa;
1583
1584 if ((memop & MO_SIZE) <= MO_64) {
1585 return true;
1586 }
1587
1588 /*
1589 * Reject 16-byte memop with 16-byte atomicity,
1590 * but do allow a pair of 64-bit operations.
1591 */
1592 aa = atom_and_align_for_opc(tcg_ctx, memop, MO_ATOM_IFALIGN, true);
1593 return aa.atom <= MO_64;
7b880107
RH
1594}
1595
14776ab5 1596static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data,
03654748 1597 HostAddress h)
48bb3750 1598{
3c8691f5 1599 switch (opc & (MO_SSIZE | MO_BSWAP)) {
a5a04f28 1600 case MO_UB:
03654748 1601 tcg_out_insn(s, RXY, LLGC, data, h.base, h.index, h.disp);
48bb3750 1602 break;
a5a04f28 1603 case MO_SB:
03654748 1604 tcg_out_insn(s, RXY, LGB, data, h.base, h.index, h.disp);
48bb3750 1605 break;
b8dd88b8
RH
1606
1607 case MO_UW | MO_BSWAP:
1608 /* swapped unsigned halfword load with upper bits zeroed */
03654748 1609 tcg_out_insn(s, RXY, LRVH, data, h.base, h.index, h.disp);
379afdff 1610 tcg_out_ext16u(s, data, data);
b8dd88b8 1611 break;
a5a04f28 1612 case MO_UW:
03654748 1613 tcg_out_insn(s, RXY, LLGH, data, h.base, h.index, h.disp);
b8dd88b8
RH
1614 break;
1615
1616 case MO_SW | MO_BSWAP:
1617 /* swapped sign-extended halfword load */
03654748 1618 tcg_out_insn(s, RXY, LRVH, data, h.base, h.index, h.disp);
753e42ea 1619 tcg_out_ext16s(s, TCG_TYPE_REG, data, data);
48bb3750 1620 break;
a5a04f28 1621 case MO_SW:
03654748 1622 tcg_out_insn(s, RXY, LGH, data, h.base, h.index, h.disp);
b8dd88b8
RH
1623 break;
1624
1625 case MO_UL | MO_BSWAP:
1626 /* swapped unsigned int load with upper bits zeroed */
03654748 1627 tcg_out_insn(s, RXY, LRV, data, h.base, h.index, h.disp);
9ecf5f61 1628 tcg_out_ext32u(s, data, data);
48bb3750 1629 break;
a5a04f28 1630 case MO_UL:
03654748 1631 tcg_out_insn(s, RXY, LLGF, data, h.base, h.index, h.disp);
b8dd88b8
RH
1632 break;
1633
1634 case MO_SL | MO_BSWAP:
1635 /* swapped sign-extended int load */
03654748 1636 tcg_out_insn(s, RXY, LRV, data, h.base, h.index, h.disp);
52bf3398 1637 tcg_out_ext32s(s, data, data);
48bb3750 1638 break;
a5a04f28 1639 case MO_SL:
03654748 1640 tcg_out_insn(s, RXY, LGF, data, h.base, h.index, h.disp);
b8dd88b8
RH
1641 break;
1642
fc313c64 1643 case MO_UQ | MO_BSWAP:
03654748 1644 tcg_out_insn(s, RXY, LRVG, data, h.base, h.index, h.disp);
48bb3750 1645 break;
fc313c64 1646 case MO_UQ:
03654748 1647 tcg_out_insn(s, RXY, LG, data, h.base, h.index, h.disp);
48bb3750 1648 break;
b8dd88b8 1649
48bb3750 1650 default:
732e89f4 1651 g_assert_not_reached();
48bb3750
RH
1652 }
1653}
1654
14776ab5 1655static void tcg_out_qemu_st_direct(TCGContext *s, MemOp opc, TCGReg data,
03654748 1656 HostAddress h)
48bb3750 1657{
3c8691f5 1658 switch (opc & (MO_SIZE | MO_BSWAP)) {
a5a04f28 1659 case MO_UB:
03654748
RH
1660 if (h.disp >= 0 && h.disp < 0x1000) {
1661 tcg_out_insn(s, RX, STC, data, h.base, h.index, h.disp);
48bb3750 1662 } else {
03654748 1663 tcg_out_insn(s, RXY, STCY, data, h.base, h.index, h.disp);
48bb3750
RH
1664 }
1665 break;
b8dd88b8
RH
1666
1667 case MO_UW | MO_BSWAP:
03654748 1668 tcg_out_insn(s, RXY, STRVH, data, h.base, h.index, h.disp);
b8dd88b8 1669 break;
a5a04f28 1670 case MO_UW:
03654748
RH
1671 if (h.disp >= 0 && h.disp < 0x1000) {
1672 tcg_out_insn(s, RX, STH, data, h.base, h.index, h.disp);
48bb3750 1673 } else {
03654748 1674 tcg_out_insn(s, RXY, STHY, data, h.base, h.index, h.disp);
48bb3750
RH
1675 }
1676 break;
b8dd88b8
RH
1677
1678 case MO_UL | MO_BSWAP:
03654748 1679 tcg_out_insn(s, RXY, STRV, data, h.base, h.index, h.disp);
b8dd88b8 1680 break;
a5a04f28 1681 case MO_UL:
03654748
RH
1682 if (h.disp >= 0 && h.disp < 0x1000) {
1683 tcg_out_insn(s, RX, ST, data, h.base, h.index, h.disp);
48bb3750 1684 } else {
03654748 1685 tcg_out_insn(s, RXY, STY, data, h.base, h.index, h.disp);
48bb3750
RH
1686 }
1687 break;
b8dd88b8 1688
fc313c64 1689 case MO_UQ | MO_BSWAP:
03654748 1690 tcg_out_insn(s, RXY, STRVG, data, h.base, h.index, h.disp);
b8dd88b8 1691 break;
fc313c64 1692 case MO_UQ:
03654748 1693 tcg_out_insn(s, RXY, STG, data, h.base, h.index, h.disp);
48bb3750 1694 break;
b8dd88b8 1695
48bb3750 1696 default:
732e89f4 1697 g_assert_not_reached();
48bb3750
RH
1698 }
1699}
1700
eb491329
RH
1701static const TCGLdstHelperParam ldst_helper_param = {
1702 .ntmp = 1, .tmp = { TCG_TMP0 }
1703};
1704
aeee05f5 1705static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
fb596415 1706{
eb491329 1707 MemOp opc = get_memop(lb->oi);
48bb3750 1708
aeee05f5 1709 if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
79dae4dd 1710 (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
aeee05f5
RH
1711 return false;
1712 }
48bb3750 1713
eb491329 1714 tcg_out_ld_helper_args(s, lb, &ldst_helper_param);
0cadc1ed 1715 tcg_out_call_int(s, qemu_ld_helpers[opc & MO_SIZE]);
eb491329 1716 tcg_out_ld_helper_ret(s, lb, false, &ldst_helper_param);
65a62a75 1717
fb596415 1718 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
aeee05f5 1719 return true;
48bb3750
RH
1720}
1721
aeee05f5 1722static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
48bb3750 1723{
eb491329 1724 MemOp opc = get_memop(lb->oi);
fb596415 1725
aeee05f5 1726 if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
79dae4dd 1727 (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
aeee05f5
RH
1728 return false;
1729 }
fb596415 1730
eb491329 1731 tcg_out_st_helper_args(s, lb, &ldst_helper_param);
0cadc1ed 1732 tcg_out_call_int(s, qemu_st_helpers[opc & MO_SIZE]);
fb596415
RH
1733
1734 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
aeee05f5 1735 return true;
48bb3750 1736}
1cd49868 1737
d0a9bb5e
RH
1738/* We're expecting to use a 20-bit negative offset on the tlb memory ops. */
1739#define MIN_TLB_MASK_TABLE_OFS -(1 << 19)
1740
0741b25e
RH
1741/*
1742 * For softmmu, perform the TLB load and compare.
1743 * For useronly, perform any required alignment tests.
1744 * In both cases, return a TCGLabelQemuLdst structure if the slow path
1745 * is required and fill in @h with the host address for the fast path.
1746 */
1747static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
1748 TCGReg addr_reg, MemOpIdx oi,
1749 bool is_ld)
48bb3750 1750{
d588946b 1751 TCGType addr_type = s->addr_type;
0741b25e
RH
1752 TCGLabelQemuLdst *ldst = NULL;
1753 MemOp opc = get_memop(oi);
4caad79f 1754 MemOp s_bits = opc & MO_SIZE;
00406e6d
RH
1755 unsigned a_mask;
1756
4caad79f 1757 h->aa = atom_and_align_for_opc(s, opc, MO_ATOM_IFALIGN, s_bits == MO_128);
00406e6d 1758 a_mask = (1 << h->aa.align) - 1;
0741b25e
RH
1759
1760#ifdef CONFIG_SOFTMMU
0741b25e
RH
1761 unsigned s_mask = (1 << s_bits) - 1;
1762 int mem_index = get_mmuidx(oi);
d0a9bb5e 1763 int fast_off = tlb_mask_table_ofs(s, mem_index);
0741b25e
RH
1764 int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
1765 int table_off = fast_off + offsetof(CPUTLBDescFast, table);
1766 int ofs, a_off;
1767 uint64_t tlb_mask;
1768
1769 ldst = new_ldst_label(s);
1770 ldst->is_ld = is_ld;
1771 ldst->oi = oi;
1772 ldst->addrlo_reg = addr_reg;
1773
94901422 1774 tcg_out_sh64(s, RSY_SRLG, TCG_TMP0, addr_reg, TCG_REG_NONE,
aece72b7 1775 s->page_bits - CPU_TLB_ENTRY_BITS);
0741b25e 1776
94901422
RH
1777 tcg_out_insn(s, RXY, NG, TCG_TMP0, TCG_AREG0, TCG_REG_NONE, mask_off);
1778 tcg_out_insn(s, RXY, AG, TCG_TMP0, TCG_AREG0, TCG_REG_NONE, table_off);
0741b25e
RH
1779
1780 /*
1781 * For aligned accesses, we check the first byte and include the alignment
1782 * bits within the address. For unaligned access, we check that we don't
1783 * cross pages using the address of the last byte of the access.
1784 */
00406e6d 1785 a_off = (a_mask >= s_mask ? 0 : s_mask - a_mask);
aece72b7 1786 tlb_mask = (uint64_t)s->page_mask | a_mask;
0741b25e 1787 if (a_off == 0) {
94901422 1788 tgen_andi_risbg(s, TCG_REG_R0, addr_reg, tlb_mask);
0741b25e 1789 } else {
94901422 1790 tcg_out_insn(s, RX, LA, TCG_REG_R0, addr_reg, TCG_REG_NONE, a_off);
d588946b 1791 tgen_andi(s, addr_type, TCG_REG_R0, tlb_mask);
0741b25e 1792 }
03654748 1793
0741b25e
RH
1794 if (is_ld) {
1795 ofs = offsetof(CPUTLBEntry, addr_read);
1796 } else {
1797 ofs = offsetof(CPUTLBEntry, addr_write);
1798 }
d588946b 1799 if (addr_type == TCG_TYPE_I32) {
238f4380 1800 ofs += HOST_BIG_ENDIAN * 4;
94901422 1801 tcg_out_insn(s, RX, C, TCG_REG_R0, TCG_TMP0, TCG_REG_NONE, ofs);
0741b25e 1802 } else {
94901422 1803 tcg_out_insn(s, RXY, CG, TCG_REG_R0, TCG_TMP0, TCG_REG_NONE, ofs);
0741b25e
RH
1804 }
1805
1806 tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
1807 ldst->label_ptr[0] = s->code_ptr++;
1808
94901422
RH
1809 h->index = TCG_TMP0;
1810 tcg_out_insn(s, RXY, LG, h->index, TCG_TMP0, TCG_REG_NONE,
0741b25e
RH
1811 offsetof(CPUTLBEntry, addend));
1812
d588946b 1813 if (addr_type == TCG_TYPE_I32) {
8b1b4597
RH
1814 tcg_out_insn(s, RRE, ALGFR, h->index, addr_reg);
1815 h->base = TCG_REG_NONE;
1816 } else {
1817 h->base = addr_reg;
0741b25e
RH
1818 }
1819 h->disp = 0;
1820#else
1821 if (a_mask) {
1822 ldst = new_ldst_label(s);
1823 ldst->is_ld = is_ld;
1824 ldst->oi = oi;
1825 ldst->addrlo_reg = addr_reg;
1826
1827 /* We are expecting a_bits to max out at 7, much lower than TMLL. */
00406e6d 1828 tcg_debug_assert(a_mask <= 0xffff);
0741b25e
RH
1829 tcg_out_insn(s, RI, TMLL, addr_reg, a_mask);
1830
1831 tcg_out16(s, RI_BRC | (7 << 4)); /* CC in {1,2,3} */
1832 ldst->label_ptr[0] = s->code_ptr++;
1833 }
1834
1835 h->base = addr_reg;
d588946b 1836 if (addr_type == TCG_TYPE_I32) {
03654748 1837 tcg_out_ext32u(s, TCG_TMP0, addr_reg);
0741b25e 1838 h->base = TCG_TMP0;
48bb3750 1839 }
b76f21a7 1840 if (guest_base < 0x80000) {
0741b25e
RH
1841 h->index = TCG_REG_NONE;
1842 h->disp = guest_base;
48bb3750 1843 } else {
0741b25e
RH
1844 h->index = TCG_GUEST_BASE_REG;
1845 h->disp = 0;
48bb3750 1846 }
0741b25e
RH
1847#endif
1848
1849 return ldst;
48bb3750 1850}
48bb3750 1851
f24efee4 1852static void tcg_out_qemu_ld(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
01a3b5de 1853 MemOpIdx oi, TCGType data_type)
48bb3750 1854{
0741b25e 1855 TCGLabelQemuLdst *ldst;
03654748
RH
1856 HostAddress h;
1857
0741b25e
RH
1858 ldst = prepare_host_addr(s, &h, addr_reg, oi, true);
1859 tcg_out_qemu_ld_direct(s, get_memop(oi), data_reg, h);
fb596415 1860
0741b25e
RH
1861 if (ldst) {
1862 ldst->type = data_type;
1863 ldst->datalo_reg = data_reg;
1864 ldst->raddr = tcg_splitwx_to_rx(s->code_ptr);
1cd49868 1865 }
48bb3750
RH
1866}
1867
f24efee4 1868static void tcg_out_qemu_st(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
01a3b5de 1869 MemOpIdx oi, TCGType data_type)
48bb3750 1870{
0741b25e 1871 TCGLabelQemuLdst *ldst;
03654748
RH
1872 HostAddress h;
1873
0741b25e
RH
1874 ldst = prepare_host_addr(s, &h, addr_reg, oi, false);
1875 tcg_out_qemu_st_direct(s, get_memop(oi), data_reg, h);
48bb3750 1876
0741b25e
RH
1877 if (ldst) {
1878 ldst->type = data_type;
1879 ldst->datalo_reg = data_reg;
1880 ldst->raddr = tcg_splitwx_to_rx(s->code_ptr);
1cd49868 1881 }
2827822e
AG
1882}
1883
4caad79f
RH
1884static void tcg_out_qemu_ldst_i128(TCGContext *s, TCGReg datalo, TCGReg datahi,
1885 TCGReg addr_reg, MemOpIdx oi, bool is_ld)
1886{
1887 TCGLabel *l1 = NULL, *l2 = NULL;
1888 TCGLabelQemuLdst *ldst;
1889 HostAddress h;
1890 bool need_bswap;
1891 bool use_pair;
1892 S390Opcode insn;
1893
1894 ldst = prepare_host_addr(s, &h, addr_reg, oi, is_ld);
1895
1896 use_pair = h.aa.atom < MO_128;
1897 need_bswap = get_memop(oi) & MO_BSWAP;
1898
1899 if (!use_pair) {
1900 /*
1901 * Atomicity requires we use LPQ. If we've already checked for
1902 * 16-byte alignment, that's all we need. If we arrive with
1903 * lesser alignment, we have determined that less than 16-byte
1904 * alignment can be satisfied with two 8-byte loads.
1905 */
1906 if (h.aa.align < MO_128) {
1907 use_pair = true;
1908 l1 = gen_new_label();
1909 l2 = gen_new_label();
1910
1911 tcg_out_insn(s, RI, TMLL, addr_reg, 15);
1912 tgen_branch(s, 7, l1); /* CC in {1,2,3} */
1913 }
1914
1915 tcg_debug_assert(!need_bswap);
1916 tcg_debug_assert(datalo & 1);
1917 tcg_debug_assert(datahi == datalo - 1);
1918 insn = is_ld ? RXY_LPQ : RXY_STPQ;
1919 tcg_out_insn_RXY(s, insn, datahi, h.base, h.index, h.disp);
1920
1921 if (use_pair) {
1922 tgen_branch(s, S390_CC_ALWAYS, l2);
1923 tcg_out_label(s, l1);
1924 }
1925 }
1926 if (use_pair) {
1927 TCGReg d1, d2;
1928
1929 if (need_bswap) {
1930 d1 = datalo, d2 = datahi;
1931 insn = is_ld ? RXY_LRVG : RXY_STRVG;
1932 } else {
1933 d1 = datahi, d2 = datalo;
1934 insn = is_ld ? RXY_LG : RXY_STG;
1935 }
1936
1937 if (h.base == d1 || h.index == d1) {
1938 tcg_out_insn(s, RXY, LAY, TCG_TMP0, h.base, h.index, h.disp);
1939 h.base = TCG_TMP0;
1940 h.index = TCG_REG_NONE;
1941 h.disp = 0;
1942 }
1943 tcg_out_insn_RXY(s, insn, d1, h.base, h.index, h.disp);
1944 tcg_out_insn_RXY(s, insn, d2, h.base, h.index, h.disp + 8);
1945 }
1946 if (l2) {
1947 tcg_out_label(s, l2);
1948 }
1949
1950 if (ldst) {
1951 ldst->type = TCG_TYPE_I128;
1952 ldst->datalo_reg = datalo;
1953 ldst->datahi_reg = datahi;
1954 ldst->raddr = tcg_splitwx_to_rx(s->code_ptr);
1955 }
1956}
1957
b55a8d9d
RH
1958static void tcg_out_exit_tb(TCGContext *s, uintptr_t a0)
1959{
1960 /* Reuse the zeroing that exists for goto_ptr. */
1961 if (a0 == 0) {
1962 tgen_gotoi(s, S390_CC_ALWAYS, tcg_code_gen_epilogue);
1963 } else {
1964 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, a0);
1965 tgen_gotoi(s, S390_CC_ALWAYS, tb_ret_addr);
1966 }
1967}
1968
cf7d6b8e
RH
1969static void tcg_out_goto_tb(TCGContext *s, int which)
1970{
1971 /*
1972 * Branch displacement must be aligned for atomic patching;
1973 * see if we need to add extra nop before branch
1974 */
1975 if (!QEMU_PTR_IS_ALIGNED(s->code_ptr + 1, 4)) {
1976 tcg_out16(s, NOP);
1977 }
1978 tcg_out16(s, RIL_BRCL | (S390_CC_ALWAYS << 4));
1979 set_jmp_insn_offset(s, which);
1980 s->code_ptr += 2;
1981 set_jmp_reset_offset(s, which);
1982}
1983
0fe1c98d
RH
1984void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
1985 uintptr_t jmp_rx, uintptr_t jmp_rw)
1986{
2fd2e78d
RH
1987 if (!HAVE_FACILITY(GEN_INST_EXT)) {
1988 return;
1989 }
0fe1c98d
RH
1990 /* patch the branch destination */
1991 uintptr_t addr = tb->jmp_target_addr[n];
1992 intptr_t disp = addr - (jmp_rx - 2);
1993 qatomic_set((int32_t *)jmp_rw, disp / 2);
1994 /* no need to flush icache explicitly */
1995}
1996
48bb3750
RH
1997# define OP_32_64(x) \
1998 case glue(glue(INDEX_op_,x),_i32): \
1999 case glue(glue(INDEX_op_,x),_i64)
48bb3750 2000
a9751609 2001static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
5e8892db
MR
2002 const TCGArg args[TCG_MAX_OP_ARGS],
2003 const int const_args[TCG_MAX_OP_ARGS])
2827822e 2004{
c2097136 2005 S390Opcode op, op2;
0db921e6 2006 TCGArg a0, a1, a2;
48bb3750
RH
2007
2008 switch (opc) {
46644483 2009 case INDEX_op_goto_ptr:
829e1376 2010 a0 = args[0];
829e1376 2011 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, a0);
46644483
RH
2012 break;
2013
48bb3750
RH
2014 OP_32_64(ld8u):
2015 /* ??? LLC (RXY format) is only present with the extended-immediate
2016 facility, whereas LLGC is always present. */
2017 tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
2018 break;
2019
2020 OP_32_64(ld8s):
2021 /* ??? LB is no smaller than LGB, so no point to using it. */
2022 tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
2023 break;
2024
2025 OP_32_64(ld16u):
2026 /* ??? LLH (RXY format) is only present with the extended-immediate
2027 facility, whereas LLGH is always present. */
2028 tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
2029 break;
2030
2031 case INDEX_op_ld16s_i32:
2032 tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
2033 break;
2034
2035 case INDEX_op_ld_i32:
2036 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
2037 break;
2038
2039 OP_32_64(st8):
2040 tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
2041 TCG_REG_NONE, args[2]);
2042 break;
2043
2044 OP_32_64(st16):
2045 tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
2046 TCG_REG_NONE, args[2]);
2047 break;
2048
2049 case INDEX_op_st_i32:
2050 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
2051 break;
2052
2053 case INDEX_op_add_i32:
0db921e6 2054 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
48bb3750 2055 if (const_args[2]) {
0db921e6
RH
2056 do_addi_32:
2057 if (a0 == a1) {
2058 if (a2 == (int16_t)a2) {
2059 tcg_out_insn(s, RI, AHI, a0, a2);
2060 break;
2061 }
3e25f7da
RH
2062 tcg_out_insn(s, RIL, AFI, a0, a2);
2063 break;
0db921e6
RH
2064 }
2065 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
2066 } else if (a0 == a1) {
2067 tcg_out_insn(s, RR, AR, a0, a2);
48bb3750 2068 } else {
0db921e6 2069 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
48bb3750
RH
2070 }
2071 break;
2072 case INDEX_op_sub_i32:
0db921e6 2073 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
48bb3750 2074 if (const_args[2]) {
0db921e6
RH
2075 a2 = -a2;
2076 goto do_addi_32;
c2097136
RH
2077 } else if (a0 == a1) {
2078 tcg_out_insn(s, RR, SR, a0, a2);
2079 } else {
1dd06b1a 2080 tcg_out_insn(s, RRFa, SRK, a0, a1, a2);
48bb3750
RH
2081 }
2082 break;
2083
2084 case INDEX_op_and_i32:
c2097136 2085 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
48bb3750 2086 if (const_args[2]) {
c2097136
RH
2087 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
2088 tgen_andi(s, TCG_TYPE_I32, a0, a2);
2089 } else if (a0 == a1) {
2090 tcg_out_insn(s, RR, NR, a0, a2);
48bb3750 2091 } else {
1dd06b1a 2092 tcg_out_insn(s, RRFa, NRK, a0, a1, a2);
48bb3750
RH
2093 }
2094 break;
2095 case INDEX_op_or_i32:
c2097136 2096 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
48bb3750 2097 if (const_args[2]) {
c2097136 2098 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
b2509acc 2099 tgen_ori(s, a0, a2);
c2097136
RH
2100 } else if (a0 == a1) {
2101 tcg_out_insn(s, RR, OR, a0, a2);
48bb3750 2102 } else {
1dd06b1a 2103 tcg_out_insn(s, RRFa, ORK, a0, a1, a2);
48bb3750
RH
2104 }
2105 break;
2106 case INDEX_op_xor_i32:
c2097136 2107 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
48bb3750 2108 if (const_args[2]) {
c2097136 2109 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
a0332aca 2110 tcg_out_insn(s, RIL, XILF, a0, a2);
c2097136 2111 } else if (a0 == a1) {
48bb3750 2112 tcg_out_insn(s, RR, XR, args[0], args[2]);
c2097136 2113 } else {
1dd06b1a 2114 tcg_out_insn(s, RRFa, XRK, a0, a1, a2);
48bb3750
RH
2115 }
2116 break;
2117
6c9b5c0f
RH
2118 case INDEX_op_andc_i32:
2119 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
2120 if (const_args[2]) {
2121 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
2122 tgen_andi(s, TCG_TYPE_I32, a0, (uint32_t)~a2);
2123 } else {
2124 tcg_out_insn(s, RRFa, NCRK, a0, a1, a2);
2125 }
2126 break;
2127 case INDEX_op_orc_i32:
2128 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
2129 if (const_args[2]) {
2130 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
2131 tgen_ori(s, a0, (uint32_t)~a2);
2132 } else {
2133 tcg_out_insn(s, RRFa, OCRK, a0, a1, a2);
2134 }
2135 break;
2136 case INDEX_op_eqv_i32:
2137 a0 = args[0], a1 = args[1], a2 = (uint32_t)args[2];
2138 if (const_args[2]) {
2139 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
2140 tcg_out_insn(s, RIL, XILF, a0, ~a2);
2141 } else {
2142 tcg_out_insn(s, RRFa, NXRK, a0, a1, a2);
2143 }
2144 break;
2145 case INDEX_op_nand_i32:
2146 tcg_out_insn(s, RRFa, NNRK, args[0], args[1], args[2]);
2147 break;
2148 case INDEX_op_nor_i32:
2149 tcg_out_insn(s, RRFa, NORK, args[0], args[1], args[2]);
2150 break;
2151
48bb3750
RH
2152 case INDEX_op_neg_i32:
2153 tcg_out_insn(s, RR, LCR, args[0], args[1]);
2154 break;
6c9b5c0f
RH
2155 case INDEX_op_not_i32:
2156 tcg_out_insn(s, RRFa, NORK, args[0], args[1], args[1]);
2157 break;
48bb3750
RH
2158
2159 case INDEX_op_mul_i32:
92c89a07 2160 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
48bb3750 2161 if (const_args[2]) {
92c89a07
RH
2162 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
2163 if (a2 == (int16_t)a2) {
2164 tcg_out_insn(s, RI, MHI, a0, a2);
48bb3750 2165 } else {
92c89a07 2166 tcg_out_insn(s, RIL, MSFI, a0, a2);
48bb3750 2167 }
92c89a07
RH
2168 } else if (a0 == a1) {
2169 tcg_out_insn(s, RRE, MSR, a0, a2);
48bb3750 2170 } else {
92c89a07 2171 tcg_out_insn(s, RRFa, MSRKC, a0, a1, a2);
48bb3750
RH
2172 }
2173 break;
2174
2175 case INDEX_op_div2_i32:
4143f78d
RH
2176 tcg_debug_assert(args[0] == args[2]);
2177 tcg_debug_assert(args[1] == args[3]);
2178 tcg_debug_assert((args[1] & 1) == 0);
2179 tcg_debug_assert(args[0] == args[1] + 1);
2180 tcg_out_insn(s, RR, DR, args[1], args[4]);
48bb3750
RH
2181 break;
2182 case INDEX_op_divu2_i32:
4143f78d
RH
2183 tcg_debug_assert(args[0] == args[2]);
2184 tcg_debug_assert(args[1] == args[3]);
2185 tcg_debug_assert((args[1] & 1) == 0);
2186 tcg_debug_assert(args[0] == args[1] + 1);
2187 tcg_out_insn(s, RRE, DLR, args[1], args[4]);
48bb3750
RH
2188 break;
2189
2190 case INDEX_op_shl_i32:
2191 op = RS_SLL;
c2097136 2192 op2 = RSY_SLLK;
48bb3750 2193 do_shift32:
c2097136
RH
2194 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
2195 if (a0 == a1) {
2196 if (const_args[2]) {
2197 tcg_out_sh32(s, op, a0, TCG_REG_NONE, a2);
2198 } else {
2199 tcg_out_sh32(s, op, a0, a2, 0);
2200 }
48bb3750 2201 } else {
c2097136
RH
2202 /* Using tcg_out_sh64 here for the format; it is a 32-bit shift. */
2203 if (const_args[2]) {
2204 tcg_out_sh64(s, op2, a0, a1, TCG_REG_NONE, a2);
2205 } else {
2206 tcg_out_sh64(s, op2, a0, a1, a2, 0);
2207 }
48bb3750
RH
2208 }
2209 break;
2210 case INDEX_op_shr_i32:
2211 op = RS_SRL;
c2097136 2212 op2 = RSY_SRLK;
48bb3750
RH
2213 goto do_shift32;
2214 case INDEX_op_sar_i32:
2215 op = RS_SRA;
c2097136 2216 op2 = RSY_SRAK;
48bb3750
RH
2217 goto do_shift32;
2218
2219 case INDEX_op_rotl_i32:
2220 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
2221 if (const_args[2]) {
2222 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
2223 } else {
2224 tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
2225 }
2226 break;
2227 case INDEX_op_rotr_i32:
2228 if (const_args[2]) {
2229 tcg_out_sh64(s, RSY_RLL, args[0], args[1],
2230 TCG_REG_NONE, (32 - args[2]) & 31);
2231 } else {
2232 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2233 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
2234 }
2235 break;
2236
1619ee9e
RH
2237 case INDEX_op_bswap16_i32:
2238 a0 = args[0], a1 = args[1], a2 = args[2];
2239 tcg_out_insn(s, RRE, LRVR, a0, a1);
2240 if (a2 & TCG_BSWAP_OS) {
2241 tcg_out_sh32(s, RS_SRA, a0, TCG_REG_NONE, 16);
2242 } else {
2243 tcg_out_sh32(s, RS_SRL, a0, TCG_REG_NONE, 16);
2244 }
48bb3750 2245 break;
1619ee9e
RH
2246 case INDEX_op_bswap16_i64:
2247 a0 = args[0], a1 = args[1], a2 = args[2];
2248 tcg_out_insn(s, RRE, LRVGR, a0, a1);
2249 if (a2 & TCG_BSWAP_OS) {
2250 tcg_out_sh64(s, RSY_SRAG, a0, a0, TCG_REG_NONE, 48);
2251 } else {
2252 tcg_out_sh64(s, RSY_SRLG, a0, a0, TCG_REG_NONE, 48);
2253 }
2254 break;
2255
2256 case INDEX_op_bswap32_i32:
48bb3750
RH
2257 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
2258 break;
1619ee9e
RH
2259 case INDEX_op_bswap32_i64:
2260 a0 = args[0], a1 = args[1], a2 = args[2];
2261 tcg_out_insn(s, RRE, LRVR, a0, a1);
2262 if (a2 & TCG_BSWAP_OS) {
52bf3398 2263 tcg_out_ext32s(s, a0, a0);
1619ee9e 2264 } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) {
9ecf5f61 2265 tcg_out_ext32u(s, a0, a0);
1619ee9e
RH
2266 }
2267 break;
48bb3750 2268
3790b918 2269 case INDEX_op_add2_i32:
ad19b358
RH
2270 if (const_args[4]) {
2271 tcg_out_insn(s, RIL, ALFI, args[0], args[4]);
2272 } else {
2273 tcg_out_insn(s, RR, ALR, args[0], args[4]);
2274 }
3790b918
RH
2275 tcg_out_insn(s, RRE, ALCR, args[1], args[5]);
2276 break;
2277 case INDEX_op_sub2_i32:
ad19b358
RH
2278 if (const_args[4]) {
2279 tcg_out_insn(s, RIL, SLFI, args[0], args[4]);
2280 } else {
2281 tcg_out_insn(s, RR, SLR, args[0], args[4]);
2282 }
3790b918
RH
2283 tcg_out_insn(s, RRE, SLBR, args[1], args[5]);
2284 break;
2285
48bb3750 2286 case INDEX_op_br:
bec16311 2287 tgen_branch(s, S390_CC_ALWAYS, arg_label(args[0]));
48bb3750
RH
2288 break;
2289
2290 case INDEX_op_brcond_i32:
2291 tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
bec16311 2292 args[1], const_args[1], arg_label(args[3]));
48bb3750
RH
2293 break;
2294 case INDEX_op_setcond_i32:
2295 tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
2296 args[2], const_args[2]);
2297 break;
96a9f093
RH
2298 case INDEX_op_movcond_i32:
2299 tgen_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1],
23d1394a 2300 args[2], const_args[2], args[3], const_args[3], args[4]);
96a9f093 2301 break;
48bb3750 2302
fecccfcc
RH
2303 case INDEX_op_qemu_ld_a32_i32:
2304 case INDEX_op_qemu_ld_a64_i32:
01a3b5de
RH
2305 tcg_out_qemu_ld(s, args[0], args[1], args[2], TCG_TYPE_I32);
2306 break;
fecccfcc
RH
2307 case INDEX_op_qemu_ld_a32_i64:
2308 case INDEX_op_qemu_ld_a64_i64:
01a3b5de 2309 tcg_out_qemu_ld(s, args[0], args[1], args[2], TCG_TYPE_I64);
48bb3750 2310 break;
fecccfcc
RH
2311 case INDEX_op_qemu_st_a32_i32:
2312 case INDEX_op_qemu_st_a64_i32:
01a3b5de
RH
2313 tcg_out_qemu_st(s, args[0], args[1], args[2], TCG_TYPE_I32);
2314 break;
fecccfcc
RH
2315 case INDEX_op_qemu_st_a32_i64:
2316 case INDEX_op_qemu_st_a64_i64:
01a3b5de 2317 tcg_out_qemu_st(s, args[0], args[1], args[2], TCG_TYPE_I64);
48bb3750 2318 break;
4caad79f
RH
2319 case INDEX_op_qemu_ld_a32_i128:
2320 case INDEX_op_qemu_ld_a64_i128:
2321 tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], true);
2322 break;
2323 case INDEX_op_qemu_st_a32_i128:
2324 case INDEX_op_qemu_st_a64_i128:
2325 tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], false);
2326 break;
48bb3750 2327
48bb3750
RH
2328 case INDEX_op_ld16s_i64:
2329 tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
2330 break;
2331 case INDEX_op_ld32u_i64:
2332 tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
2333 break;
2334 case INDEX_op_ld32s_i64:
2335 tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
2336 break;
2337 case INDEX_op_ld_i64:
2338 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2339 break;
2340
2341 case INDEX_op_st32_i64:
2342 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
2343 break;
2344 case INDEX_op_st_i64:
2345 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2346 break;
2347
2348 case INDEX_op_add_i64:
0db921e6 2349 a0 = args[0], a1 = args[1], a2 = args[2];
48bb3750 2350 if (const_args[2]) {
0db921e6
RH
2351 do_addi_64:
2352 if (a0 == a1) {
2353 if (a2 == (int16_t)a2) {
2354 tcg_out_insn(s, RI, AGHI, a0, a2);
2355 break;
2356 }
3e25f7da
RH
2357 if (a2 == (int32_t)a2) {
2358 tcg_out_insn(s, RIL, AGFI, a0, a2);
2359 break;
2360 }
2361 if (a2 == (uint32_t)a2) {
2362 tcg_out_insn(s, RIL, ALGFI, a0, a2);
2363 break;
2364 }
2365 if (-a2 == (uint32_t)-a2) {
2366 tcg_out_insn(s, RIL, SLGFI, a0, -a2);
2367 break;
0db921e6
RH
2368 }
2369 }
2370 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
2371 } else if (a0 == a1) {
2372 tcg_out_insn(s, RRE, AGR, a0, a2);
48bb3750 2373 } else {
0db921e6 2374 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
48bb3750
RH
2375 }
2376 break;
2377 case INDEX_op_sub_i64:
0db921e6 2378 a0 = args[0], a1 = args[1], a2 = args[2];
48bb3750 2379 if (const_args[2]) {
0db921e6
RH
2380 a2 = -a2;
2381 goto do_addi_64;
48bb3750 2382 } else {
1dd06b1a 2383 tcg_out_insn(s, RRFa, SGRK, a0, a1, a2);
48bb3750
RH
2384 }
2385 break;
2386
2387 case INDEX_op_and_i64:
c2097136 2388 a0 = args[0], a1 = args[1], a2 = args[2];
48bb3750 2389 if (const_args[2]) {
c2097136 2390 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
07ff7983 2391 tgen_andi(s, TCG_TYPE_I64, args[0], args[2]);
c2097136 2392 } else {
1dd06b1a 2393 tcg_out_insn(s, RRFa, NGRK, a0, a1, a2);
48bb3750
RH
2394 }
2395 break;
2396 case INDEX_op_or_i64:
c2097136 2397 a0 = args[0], a1 = args[1], a2 = args[2];
48bb3750 2398 if (const_args[2]) {
c2097136 2399 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
b2509acc 2400 tgen_ori(s, a0, a2);
48bb3750 2401 } else {
1dd06b1a 2402 tcg_out_insn(s, RRFa, OGRK, a0, a1, a2);
48bb3750
RH
2403 }
2404 break;
2405 case INDEX_op_xor_i64:
c2097136 2406 a0 = args[0], a1 = args[1], a2 = args[2];
48bb3750 2407 if (const_args[2]) {
c2097136 2408 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
b2509acc 2409 tgen_xori(s, a0, a2);
48bb3750 2410 } else {
1dd06b1a 2411 tcg_out_insn(s, RRFa, XGRK, a0, a1, a2);
48bb3750
RH
2412 }
2413 break;
2414
6c9b5c0f
RH
2415 case INDEX_op_andc_i64:
2416 a0 = args[0], a1 = args[1], a2 = args[2];
2417 if (const_args[2]) {
2418 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2419 tgen_andi(s, TCG_TYPE_I64, a0, ~a2);
2420 } else {
2421 tcg_out_insn(s, RRFa, NCGRK, a0, a1, a2);
2422 }
2423 break;
2424 case INDEX_op_orc_i64:
2425 a0 = args[0], a1 = args[1], a2 = args[2];
2426 if (const_args[2]) {
2427 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2428 tgen_ori(s, a0, ~a2);
2429 } else {
2430 tcg_out_insn(s, RRFa, OCGRK, a0, a1, a2);
2431 }
2432 break;
2433 case INDEX_op_eqv_i64:
2434 a0 = args[0], a1 = args[1], a2 = args[2];
2435 if (const_args[2]) {
2436 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2437 tgen_xori(s, a0, ~a2);
2438 } else {
2439 tcg_out_insn(s, RRFa, NXGRK, a0, a1, a2);
2440 }
2441 break;
2442 case INDEX_op_nand_i64:
2443 tcg_out_insn(s, RRFa, NNGRK, args[0], args[1], args[2]);
2444 break;
2445 case INDEX_op_nor_i64:
2446 tcg_out_insn(s, RRFa, NOGRK, args[0], args[1], args[2]);
2447 break;
2448
48bb3750
RH
2449 case INDEX_op_neg_i64:
2450 tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
2451 break;
6c9b5c0f
RH
2452 case INDEX_op_not_i64:
2453 tcg_out_insn(s, RRFa, NOGRK, args[0], args[1], args[1]);
2454 break;
48bb3750
RH
2455 case INDEX_op_bswap64_i64:
2456 tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
2457 break;
2458
2459 case INDEX_op_mul_i64:
92c89a07 2460 a0 = args[0], a1 = args[1], a2 = args[2];
48bb3750 2461 if (const_args[2]) {
92c89a07
RH
2462 tcg_out_mov(s, TCG_TYPE_I64, a0, a1);
2463 if (a2 == (int16_t)a2) {
2464 tcg_out_insn(s, RI, MGHI, a0, a2);
48bb3750 2465 } else {
92c89a07 2466 tcg_out_insn(s, RIL, MSGFI, a0, a2);
48bb3750 2467 }
92c89a07
RH
2468 } else if (a0 == a1) {
2469 tcg_out_insn(s, RRE, MSGR, a0, a2);
48bb3750 2470 } else {
92c89a07 2471 tcg_out_insn(s, RRFa, MSGRKC, a0, a1, a2);
48bb3750
RH
2472 }
2473 break;
2474
2475 case INDEX_op_div2_i64:
4143f78d
RH
2476 /*
2477 * ??? We get an unnecessary sign-extension of the dividend
2478 * into op0 with this definition, but as we do in fact always
2479 * produce both quotient and remainder using INDEX_op_div_i64
2480 * instead requires jumping through even more hoops.
2481 */
2482 tcg_debug_assert(args[0] == args[2]);
2483 tcg_debug_assert(args[1] == args[3]);
2484 tcg_debug_assert((args[1] & 1) == 0);
2485 tcg_debug_assert(args[0] == args[1] + 1);
2486 tcg_out_insn(s, RRE, DSGR, args[1], args[4]);
48bb3750
RH
2487 break;
2488 case INDEX_op_divu2_i64:
4143f78d
RH
2489 tcg_debug_assert(args[0] == args[2]);
2490 tcg_debug_assert(args[1] == args[3]);
2491 tcg_debug_assert((args[1] & 1) == 0);
2492 tcg_debug_assert(args[0] == args[1] + 1);
2493 tcg_out_insn(s, RRE, DLGR, args[1], args[4]);
48bb3750 2494 break;
36017dc6 2495 case INDEX_op_mulu2_i64:
4143f78d
RH
2496 tcg_debug_assert(args[0] == args[2]);
2497 tcg_debug_assert((args[1] & 1) == 0);
2498 tcg_debug_assert(args[0] == args[1] + 1);
2499 tcg_out_insn(s, RRE, MLGR, args[1], args[3]);
36017dc6 2500 break;
668ce343
RH
2501 case INDEX_op_muls2_i64:
2502 tcg_debug_assert((args[1] & 1) == 0);
2503 tcg_debug_assert(args[0] == args[1] + 1);
2504 tcg_out_insn(s, RRFa, MGRK, args[1], args[2], args[3]);
2505 break;
48bb3750
RH
2506
2507 case INDEX_op_shl_i64:
2508 op = RSY_SLLG;
2509 do_shift64:
2510 if (const_args[2]) {
2511 tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
2512 } else {
2513 tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
2514 }
2515 break;
2516 case INDEX_op_shr_i64:
2517 op = RSY_SRLG;
2518 goto do_shift64;
2519 case INDEX_op_sar_i64:
2520 op = RSY_SRAG;
2521 goto do_shift64;
2522
2523 case INDEX_op_rotl_i64:
2524 if (const_args[2]) {
2525 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2526 TCG_REG_NONE, args[2]);
2527 } else {
2528 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
2529 }
2530 break;
2531 case INDEX_op_rotr_i64:
2532 if (const_args[2]) {
2533 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2534 TCG_REG_NONE, (64 - args[2]) & 63);
2535 } else {
2536 /* We can use the smaller 32-bit negate because only the
2537 low 6 bits are examined for the rotate. */
2538 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2539 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
2540 }
2541 break;
2542
3790b918 2543 case INDEX_op_add2_i64:
ad19b358
RH
2544 if (const_args[4]) {
2545 if ((int64_t)args[4] >= 0) {
2546 tcg_out_insn(s, RIL, ALGFI, args[0], args[4]);
2547 } else {
2548 tcg_out_insn(s, RIL, SLGFI, args[0], -args[4]);
2549 }
2550 } else {
2551 tcg_out_insn(s, RRE, ALGR, args[0], args[4]);
2552 }
3790b918
RH
2553 tcg_out_insn(s, RRE, ALCGR, args[1], args[5]);
2554 break;
2555 case INDEX_op_sub2_i64:
ad19b358
RH
2556 if (const_args[4]) {
2557 if ((int64_t)args[4] >= 0) {
2558 tcg_out_insn(s, RIL, SLGFI, args[0], args[4]);
2559 } else {
2560 tcg_out_insn(s, RIL, ALGFI, args[0], -args[4]);
2561 }
2562 } else {
2563 tcg_out_insn(s, RRE, SLGR, args[0], args[4]);
2564 }
3790b918
RH
2565 tcg_out_insn(s, RRE, SLBGR, args[1], args[5]);
2566 break;
2567
48bb3750
RH
2568 case INDEX_op_brcond_i64:
2569 tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
bec16311 2570 args[1], const_args[1], arg_label(args[3]));
48bb3750
RH
2571 break;
2572 case INDEX_op_setcond_i64:
2573 tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2574 args[2], const_args[2]);
2575 break;
96a9f093
RH
2576 case INDEX_op_movcond_i64:
2577 tgen_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1],
23d1394a 2578 args[2], const_args[2], args[3], const_args[3], args[4]);
96a9f093 2579 break;
48bb3750 2580
d5690ea4 2581 OP_32_64(deposit):
752b1be9
RH
2582 a0 = args[0], a1 = args[1], a2 = args[2];
2583 if (const_args[1]) {
2584 tgen_deposit(s, a0, a2, args[3], args[4], 1);
2585 } else {
2586 /* Since we can't support "0Z" as a constraint, we allow a1 in
2587 any register. Fix things up as if a matching constraint. */
2588 if (a0 != a1) {
2589 TCGType type = (opc == INDEX_op_deposit_i64);
2590 if (a0 == a2) {
2591 tcg_out_mov(s, type, TCG_TMP0, a2);
2592 a2 = TCG_TMP0;
2593 }
2594 tcg_out_mov(s, type, a0, a1);
2595 }
2596 tgen_deposit(s, a0, a2, args[3], args[4], 0);
2597 }
d5690ea4 2598 break;
752b1be9 2599
b0bf5fe8
RH
2600 OP_32_64(extract):
2601 tgen_extract(s, args[0], args[1], args[2], args[3]);
2602 break;
d5690ea4 2603
ce411066
RH
2604 case INDEX_op_clz_i64:
2605 tgen_clz(s, args[0], args[1], args[2], const_args[2]);
2606 break;
2607
29a5ea73
RH
2608 case INDEX_op_ctpop_i32:
2609 tgen_ctpop(s, TCG_TYPE_I32, args[0], args[1]);
2610 break;
2611 case INDEX_op_ctpop_i64:
2612 tgen_ctpop(s, TCG_TYPE_I64, args[0], args[1]);
2613 break;
2614
c9314d61
PK
2615 case INDEX_op_mb:
2616 /* The host memory model is quite strong, we simply need to
2617 serialize the instruction stream. */
2618 if (args[0] & TCG_MO_ST_LD) {
e62d5752
RH
2619 /* fast-bcr-serialization facility (45) is present */
2620 tcg_out_insn(s, RR, BCR, 14, 0);
c9314d61
PK
2621 }
2622 break;
2623
96d0ee7f
RH
2624 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
2625 case INDEX_op_mov_i64:
96d0ee7f 2626 case INDEX_op_call: /* Always emitted via tcg_out_call. */
b55a8d9d 2627 case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
cf7d6b8e 2628 case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
678155b2
RH
2629 case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
2630 case INDEX_op_ext8s_i64:
d0e66c89
RH
2631 case INDEX_op_ext8u_i32:
2632 case INDEX_op_ext8u_i64:
753e42ea
RH
2633 case INDEX_op_ext16s_i32:
2634 case INDEX_op_ext16s_i64:
379afdff
RH
2635 case INDEX_op_ext16u_i32:
2636 case INDEX_op_ext16u_i64:
52bf3398 2637 case INDEX_op_ext32s_i64:
9ecf5f61 2638 case INDEX_op_ext32u_i64:
9c6aa274 2639 case INDEX_op_ext_i32_i64:
b9bfe000 2640 case INDEX_op_extu_i32_i64:
b8b94ac6 2641 case INDEX_op_extrl_i64_i32:
48bb3750 2642 default:
732e89f4 2643 g_assert_not_reached();
48bb3750 2644 }
2827822e
AG
2645}
2646
34ef7676
RH
2647static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
2648 TCGReg dst, TCGReg src)
2649{
79cada86
RH
2650 if (is_general_reg(src)) {
2651 /* Replicate general register into two MO_64. */
2652 tcg_out_insn(s, VRRf, VLVGP, dst, src, src);
2653 if (vece == MO_64) {
2654 return true;
2655 }
6e591a85 2656 src = dst;
79cada86
RH
2657 }
2658
2659 /*
2660 * Recall that the "standard" integer, within a vector, is the
2661 * rightmost element of the leftmost doubleword, a-la VLLEZ.
2662 */
2663 tcg_out_insn(s, VRIc, VREP, dst, (8 >> vece) - 1, src, vece);
2664 return true;
34ef7676
RH
2665}
2666
2667static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
2668 TCGReg dst, TCGReg base, intptr_t offset)
2669{
79cada86
RH
2670 tcg_out_vrx_mem(s, VRX_VLREP, dst, base, TCG_REG_NONE, offset, vece);
2671 return true;
34ef7676
RH
2672}
2673
2674static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
2675 TCGReg dst, int64_t val)
2676{
79cada86
RH
2677 int i, mask, msb, lsb;
2678
2679 /* Look for int16_t elements. */
2680 if (vece <= MO_16 ||
2681 (vece == MO_32 ? (int32_t)val : val) == (int16_t)val) {
2682 tcg_out_insn(s, VRIa, VREPI, dst, val, vece);
2683 return;
2684 }
2685
2686 /* Look for bit masks. */
2687 if (vece == MO_32) {
2688 if (risbg_mask((int32_t)val)) {
2689 /* Handle wraparound by swapping msb and lsb. */
2690 if ((val & 0x80000001u) == 0x80000001u) {
2691 msb = 32 - ctz32(~val);
2692 lsb = clz32(~val) - 1;
2693 } else {
2694 msb = clz32(val);
2695 lsb = 31 - ctz32(val);
2696 }
a66669c9 2697 tcg_out_insn(s, VRIb, VGM, dst, msb, lsb, MO_32);
79cada86
RH
2698 return;
2699 }
2700 } else {
2701 if (risbg_mask(val)) {
2702 /* Handle wraparound by swapping msb and lsb. */
2703 if ((val & 0x8000000000000001ull) == 0x8000000000000001ull) {
2704 /* Handle wraparound by swapping msb and lsb. */
2705 msb = 64 - ctz64(~val);
2706 lsb = clz64(~val) - 1;
2707 } else {
2708 msb = clz64(val);
2709 lsb = 63 - ctz64(val);
2710 }
a66669c9 2711 tcg_out_insn(s, VRIb, VGM, dst, msb, lsb, MO_64);
79cada86
RH
2712 return;
2713 }
2714 }
2715
2716 /* Look for all bytes 0x00 or 0xff. */
2717 for (i = mask = 0; i < 8; i++) {
2718 uint8_t byte = val >> (i * 8);
2719 if (byte == 0xff) {
2720 mask |= 1 << i;
2721 } else if (byte != 0) {
2722 break;
2723 }
2724 }
2725 if (i == 8) {
2726 tcg_out_insn(s, VRIa, VGBM, dst, mask * 0x0101, 0);
2727 return;
2728 }
2729
2730 /* Otherwise, stuff it in the constant pool. */
2731 tcg_out_insn(s, RIL, LARL, TCG_TMP0, 0);
2732 new_pool_label(s, val, R_390_PC32DBL, s->code_ptr - 2, 2);
2733 tcg_out_insn(s, VRX, VLREP, dst, TCG_TMP0, TCG_REG_NONE, 0, MO_64);
34ef7676
RH
2734}
2735
2736static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
2737 unsigned vecl, unsigned vece,
d58f0173
MR
2738 const TCGArg args[TCG_MAX_OP_ARGS],
2739 const int const_args[TCG_MAX_OP_ARGS])
34ef7676 2740{
a429ee29
RH
2741 TCGType type = vecl + TCG_TYPE_V64;
2742 TCGArg a0 = args[0], a1 = args[1], a2 = args[2];
2743
2744 switch (opc) {
2745 case INDEX_op_ld_vec:
2746 tcg_out_ld(s, type, a0, a1, a2);
2747 break;
2748 case INDEX_op_st_vec:
2749 tcg_out_st(s, type, a0, a1, a2);
2750 break;
2751 case INDEX_op_dupm_vec:
2752 tcg_out_dupm_vec(s, type, vece, a0, a1, a2);
2753 break;
2754
ae77bbe5
RH
2755 case INDEX_op_abs_vec:
2756 tcg_out_insn(s, VRRa, VLP, a0, a1, vece);
2757 break;
2758 case INDEX_op_neg_vec:
2759 tcg_out_insn(s, VRRa, VLC, a0, a1, vece);
2760 break;
2761 case INDEX_op_not_vec:
2762 tcg_out_insn(s, VRRc, VNO, a0, a1, a1, 0);
2763 break;
2764
a429ee29
RH
2765 case INDEX_op_add_vec:
2766 tcg_out_insn(s, VRRc, VA, a0, a1, a2, vece);
2767 break;
2768 case INDEX_op_sub_vec:
2769 tcg_out_insn(s, VRRc, VS, a0, a1, a2, vece);
2770 break;
2771 case INDEX_op_and_vec:
2772 tcg_out_insn(s, VRRc, VN, a0, a1, a2, 0);
2773 break;
ae77bbe5
RH
2774 case INDEX_op_andc_vec:
2775 tcg_out_insn(s, VRRc, VNC, a0, a1, a2, 0);
2776 break;
479b61cb
RH
2777 case INDEX_op_mul_vec:
2778 tcg_out_insn(s, VRRc, VML, a0, a1, a2, vece);
2779 break;
a429ee29
RH
2780 case INDEX_op_or_vec:
2781 tcg_out_insn(s, VRRc, VO, a0, a1, a2, 0);
2782 break;
ae77bbe5
RH
2783 case INDEX_op_orc_vec:
2784 tcg_out_insn(s, VRRc, VOC, a0, a1, a2, 0);
2785 break;
a429ee29
RH
2786 case INDEX_op_xor_vec:
2787 tcg_out_insn(s, VRRc, VX, a0, a1, a2, 0);
2788 break;
21eab5bf
RH
2789 case INDEX_op_nand_vec:
2790 tcg_out_insn(s, VRRc, VNN, a0, a1, a2, 0);
2791 break;
2792 case INDEX_op_nor_vec:
2793 tcg_out_insn(s, VRRc, VNO, a0, a1, a2, 0);
2794 break;
2795 case INDEX_op_eqv_vec:
2796 tcg_out_insn(s, VRRc, VNX, a0, a1, a2, 0);
2797 break;
a429ee29 2798
22cb37b4
RH
2799 case INDEX_op_shli_vec:
2800 tcg_out_insn(s, VRSa, VESL, a0, a2, TCG_REG_NONE, a1, vece);
2801 break;
2802 case INDEX_op_shri_vec:
2803 tcg_out_insn(s, VRSa, VESRL, a0, a2, TCG_REG_NONE, a1, vece);
2804 break;
2805 case INDEX_op_sari_vec:
2806 tcg_out_insn(s, VRSa, VESRA, a0, a2, TCG_REG_NONE, a1, vece);
2807 break;
2808 case INDEX_op_rotli_vec:
2809 tcg_out_insn(s, VRSa, VERLL, a0, a2, TCG_REG_NONE, a1, vece);
2810 break;
2811 case INDEX_op_shls_vec:
2812 tcg_out_insn(s, VRSa, VESL, a0, 0, a2, a1, vece);
2813 break;
2814 case INDEX_op_shrs_vec:
2815 tcg_out_insn(s, VRSa, VESRL, a0, 0, a2, a1, vece);
2816 break;
2817 case INDEX_op_sars_vec:
2818 tcg_out_insn(s, VRSa, VESRA, a0, 0, a2, a1, vece);
2819 break;
2820 case INDEX_op_rotls_vec:
2821 tcg_out_insn(s, VRSa, VERLL, a0, 0, a2, a1, vece);
2822 break;
2823 case INDEX_op_shlv_vec:
2824 tcg_out_insn(s, VRRc, VESLV, a0, a1, a2, vece);
2825 break;
2826 case INDEX_op_shrv_vec:
2827 tcg_out_insn(s, VRRc, VESRLV, a0, a1, a2, vece);
2828 break;
2829 case INDEX_op_sarv_vec:
2830 tcg_out_insn(s, VRRc, VESRAV, a0, a1, a2, vece);
2831 break;
2832 case INDEX_op_rotlv_vec:
2833 tcg_out_insn(s, VRRc, VERLLV, a0, a1, a2, vece);
2834 break;
2835
220db7a6
RH
2836 case INDEX_op_smin_vec:
2837 tcg_out_insn(s, VRRc, VMN, a0, a1, a2, vece);
2838 break;
2839 case INDEX_op_smax_vec:
2840 tcg_out_insn(s, VRRc, VMX, a0, a1, a2, vece);
2841 break;
2842 case INDEX_op_umin_vec:
2843 tcg_out_insn(s, VRRc, VMNL, a0, a1, a2, vece);
2844 break;
2845 case INDEX_op_umax_vec:
2846 tcg_out_insn(s, VRRc, VMXL, a0, a1, a2, vece);
2847 break;
2848
9bca986d 2849 case INDEX_op_bitsel_vec:
6e5f9fb7 2850 tcg_out_insn(s, VRRe, VSEL, a0, a2, args[3], a1);
9bca986d
RH
2851 break;
2852
a429ee29
RH
2853 case INDEX_op_cmp_vec:
2854 switch ((TCGCond)args[3]) {
2855 case TCG_COND_EQ:
2856 tcg_out_insn(s, VRRc, VCEQ, a0, a1, a2, vece);
2857 break;
2858 case TCG_COND_GT:
2859 tcg_out_insn(s, VRRc, VCH, a0, a1, a2, vece);
2860 break;
2861 case TCG_COND_GTU:
2862 tcg_out_insn(s, VRRc, VCHL, a0, a1, a2, vece);
2863 break;
2864 default:
2865 g_assert_not_reached();
2866 }
2867 break;
2868
4223c9c1
RH
2869 case INDEX_op_s390_vuph_vec:
2870 tcg_out_insn(s, VRRa, VUPH, a0, a1, vece);
2871 break;
2872 case INDEX_op_s390_vupl_vec:
2873 tcg_out_insn(s, VRRa, VUPL, a0, a1, vece);
2874 break;
2875 case INDEX_op_s390_vpks_vec:
2876 tcg_out_insn(s, VRRc, VPKS, a0, a1, a2, vece);
2877 break;
2878
a429ee29
RH
2879 case INDEX_op_mov_vec: /* Always emitted via tcg_out_mov. */
2880 case INDEX_op_dup_vec: /* Always emitted via tcg_out_dup_vec. */
2881 default:
2882 g_assert_not_reached();
2883 }
34ef7676
RH
2884}
2885
2886int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
2887{
a429ee29 2888 switch (opc) {
ae77bbe5 2889 case INDEX_op_abs_vec:
a429ee29
RH
2890 case INDEX_op_add_vec:
2891 case INDEX_op_and_vec:
ae77bbe5 2892 case INDEX_op_andc_vec:
9bca986d 2893 case INDEX_op_bitsel_vec:
21eab5bf
RH
2894 case INDEX_op_eqv_vec:
2895 case INDEX_op_nand_vec:
ae77bbe5 2896 case INDEX_op_neg_vec:
21eab5bf 2897 case INDEX_op_nor_vec:
ae77bbe5 2898 case INDEX_op_not_vec:
a429ee29 2899 case INDEX_op_or_vec:
ae77bbe5 2900 case INDEX_op_orc_vec:
22cb37b4
RH
2901 case INDEX_op_rotli_vec:
2902 case INDEX_op_rotls_vec:
2903 case INDEX_op_rotlv_vec:
2904 case INDEX_op_sari_vec:
2905 case INDEX_op_sars_vec:
2906 case INDEX_op_sarv_vec:
2907 case INDEX_op_shli_vec:
2908 case INDEX_op_shls_vec:
2909 case INDEX_op_shlv_vec:
2910 case INDEX_op_shri_vec:
2911 case INDEX_op_shrs_vec:
2912 case INDEX_op_shrv_vec:
220db7a6
RH
2913 case INDEX_op_smax_vec:
2914 case INDEX_op_smin_vec:
a429ee29 2915 case INDEX_op_sub_vec:
220db7a6
RH
2916 case INDEX_op_umax_vec:
2917 case INDEX_op_umin_vec:
a429ee29
RH
2918 case INDEX_op_xor_vec:
2919 return 1;
2920 case INDEX_op_cmp_vec:
ea3f2af8 2921 case INDEX_op_cmpsel_vec:
22cb37b4 2922 case INDEX_op_rotrv_vec:
a429ee29 2923 return -1;
479b61cb
RH
2924 case INDEX_op_mul_vec:
2925 return vece < MO_64;
4223c9c1
RH
2926 case INDEX_op_ssadd_vec:
2927 case INDEX_op_sssub_vec:
2928 return vece < MO_64 ? -1 : 0;
a429ee29
RH
2929 default:
2930 return 0;
2931 }
2932}
2933
2934static bool expand_vec_cmp_noinv(TCGType type, unsigned vece, TCGv_vec v0,
2935 TCGv_vec v1, TCGv_vec v2, TCGCond cond)
2936{
2937 bool need_swap = false, need_inv = false;
2938
2939 switch (cond) {
2940 case TCG_COND_EQ:
2941 case TCG_COND_GT:
2942 case TCG_COND_GTU:
2943 break;
2944 case TCG_COND_NE:
2945 case TCG_COND_LE:
2946 case TCG_COND_LEU:
2947 need_inv = true;
2948 break;
2949 case TCG_COND_LT:
2950 case TCG_COND_LTU:
2951 need_swap = true;
2952 break;
2953 case TCG_COND_GE:
2954 case TCG_COND_GEU:
2955 need_swap = need_inv = true;
2956 break;
2957 default:
2958 g_assert_not_reached();
2959 }
2960
2961 if (need_inv) {
2962 cond = tcg_invert_cond(cond);
2963 }
2964 if (need_swap) {
2965 TCGv_vec t1;
2966 t1 = v1, v1 = v2, v2 = t1;
2967 cond = tcg_swap_cond(cond);
2968 }
2969
2970 vec_gen_4(INDEX_op_cmp_vec, type, vece, tcgv_vec_arg(v0),
2971 tcgv_vec_arg(v1), tcgv_vec_arg(v2), cond);
2972
2973 return need_inv;
2974}
2975
2976static void expand_vec_cmp(TCGType type, unsigned vece, TCGv_vec v0,
2977 TCGv_vec v1, TCGv_vec v2, TCGCond cond)
2978{
2979 if (expand_vec_cmp_noinv(type, vece, v0, v1, v2, cond)) {
2980 tcg_gen_not_vec(vece, v0, v0);
2981 }
34ef7676
RH
2982}
2983
ea3f2af8
RH
2984static void expand_vec_cmpsel(TCGType type, unsigned vece, TCGv_vec v0,
2985 TCGv_vec c1, TCGv_vec c2,
2986 TCGv_vec v3, TCGv_vec v4, TCGCond cond)
2987{
2988 TCGv_vec t = tcg_temp_new_vec(type);
2989
2990 if (expand_vec_cmp_noinv(type, vece, t, c1, c2, cond)) {
2991 /* Invert the sense of the compare by swapping arguments. */
2992 tcg_gen_bitsel_vec(vece, v0, t, v4, v3);
2993 } else {
2994 tcg_gen_bitsel_vec(vece, v0, t, v3, v4);
2995 }
2996 tcg_temp_free_vec(t);
2997}
2998
4223c9c1
RH
2999static void expand_vec_sat(TCGType type, unsigned vece, TCGv_vec v0,
3000 TCGv_vec v1, TCGv_vec v2, TCGOpcode add_sub_opc)
3001{
3002 TCGv_vec h1 = tcg_temp_new_vec(type);
3003 TCGv_vec h2 = tcg_temp_new_vec(type);
3004 TCGv_vec l1 = tcg_temp_new_vec(type);
3005 TCGv_vec l2 = tcg_temp_new_vec(type);
3006
3007 tcg_debug_assert (vece < MO_64);
3008
3009 /* Unpack with sign-extension. */
3010 vec_gen_2(INDEX_op_s390_vuph_vec, type, vece,
3011 tcgv_vec_arg(h1), tcgv_vec_arg(v1));
3012 vec_gen_2(INDEX_op_s390_vuph_vec, type, vece,
3013 tcgv_vec_arg(h2), tcgv_vec_arg(v2));
3014
3015 vec_gen_2(INDEX_op_s390_vupl_vec, type, vece,
3016 tcgv_vec_arg(l1), tcgv_vec_arg(v1));
3017 vec_gen_2(INDEX_op_s390_vupl_vec, type, vece,
3018 tcgv_vec_arg(l2), tcgv_vec_arg(v2));
3019
3020 /* Arithmetic on a wider element size. */
3021 vec_gen_3(add_sub_opc, type, vece + 1, tcgv_vec_arg(h1),
3022 tcgv_vec_arg(h1), tcgv_vec_arg(h2));
3023 vec_gen_3(add_sub_opc, type, vece + 1, tcgv_vec_arg(l1),
3024 tcgv_vec_arg(l1), tcgv_vec_arg(l2));
3025
3026 /* Pack with saturation. */
3027 vec_gen_3(INDEX_op_s390_vpks_vec, type, vece + 1,
3028 tcgv_vec_arg(v0), tcgv_vec_arg(h1), tcgv_vec_arg(l1));
3029
3030 tcg_temp_free_vec(h1);
3031 tcg_temp_free_vec(h2);
3032 tcg_temp_free_vec(l1);
3033 tcg_temp_free_vec(l2);
3034}
3035
34ef7676
RH
3036void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
3037 TCGArg a0, ...)
3038{
a429ee29 3039 va_list va;
ea3f2af8 3040 TCGv_vec v0, v1, v2, v3, v4, t0;
a429ee29
RH
3041
3042 va_start(va, a0);
3043 v0 = temp_tcgv_vec(arg_temp(a0));
3044 v1 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
3045 v2 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
3046
3047 switch (opc) {
3048 case INDEX_op_cmp_vec:
3049 expand_vec_cmp(type, vece, v0, v1, v2, va_arg(va, TCGArg));
3050 break;
3051
ea3f2af8
RH
3052 case INDEX_op_cmpsel_vec:
3053 v3 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
3054 v4 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
3055 expand_vec_cmpsel(type, vece, v0, v1, v2, v3, v4, va_arg(va, TCGArg));
3056 break;
3057
22cb37b4
RH
3058 case INDEX_op_rotrv_vec:
3059 t0 = tcg_temp_new_vec(type);
3060 tcg_gen_neg_vec(vece, t0, v2);
3061 tcg_gen_rotlv_vec(vece, v0, v1, t0);
3062 tcg_temp_free_vec(t0);
3063 break;
3064
4223c9c1
RH
3065 case INDEX_op_ssadd_vec:
3066 expand_vec_sat(type, vece, v0, v1, v2, INDEX_op_add_vec);
3067 break;
3068 case INDEX_op_sssub_vec:
3069 expand_vec_sat(type, vece, v0, v1, v2, INDEX_op_sub_vec);
3070 break;
3071
a429ee29
RH
3072 default:
3073 g_assert_not_reached();
3074 }
3075 va_end(va);
34ef7676
RH
3076}
3077
d1c36a90 3078static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
f69d277e 3079{
9b5500b6
RH
3080 switch (op) {
3081 case INDEX_op_goto_ptr:
d1c36a90 3082 return C_O0_I1(r);
9b5500b6
RH
3083
3084 case INDEX_op_ld8u_i32:
3085 case INDEX_op_ld8u_i64:
3086 case INDEX_op_ld8s_i32:
3087 case INDEX_op_ld8s_i64:
3088 case INDEX_op_ld16u_i32:
3089 case INDEX_op_ld16u_i64:
3090 case INDEX_op_ld16s_i32:
3091 case INDEX_op_ld16s_i64:
3092 case INDEX_op_ld_i32:
3093 case INDEX_op_ld32u_i64:
3094 case INDEX_op_ld32s_i64:
3095 case INDEX_op_ld_i64:
d1c36a90
RH
3096 return C_O1_I1(r, r);
3097
9b5500b6
RH
3098 case INDEX_op_st8_i32:
3099 case INDEX_op_st8_i64:
3100 case INDEX_op_st16_i32:
3101 case INDEX_op_st16_i64:
3102 case INDEX_op_st_i32:
3103 case INDEX_op_st32_i64:
3104 case INDEX_op_st_i64:
d1c36a90 3105 return C_O0_I2(r, r);
9b5500b6
RH
3106
3107 case INDEX_op_add_i32:
3108 case INDEX_op_add_i64:
d1c36a90
RH
3109 case INDEX_op_shl_i64:
3110 case INDEX_op_shr_i64:
3111 case INDEX_op_sar_i64:
3112 case INDEX_op_rotl_i32:
3113 case INDEX_op_rotl_i64:
3114 case INDEX_op_rotr_i32:
3115 case INDEX_op_rotr_i64:
d1c36a90 3116 case INDEX_op_setcond_i32:
d1c36a90 3117 return C_O1_I2(r, r, ri);
32c256ed
RH
3118 case INDEX_op_setcond_i64:
3119 return C_O1_I2(r, r, rA);
d1c36a90 3120
bfff8518
RH
3121 case INDEX_op_clz_i64:
3122 return C_O1_I2(r, r, rI);
3123
9b5500b6
RH
3124 case INDEX_op_sub_i32:
3125 case INDEX_op_sub_i64:
bdcd5d19 3126 case INDEX_op_and_i32:
4046d9ca 3127 case INDEX_op_or_i32:
5bf67a92 3128 case INDEX_op_xor_i32:
238da1c9 3129 return C_O1_I2(r, r, ri);
4134083f
RH
3130 case INDEX_op_and_i64:
3131 return C_O1_I2(r, r, rNKR);
b2509acc
RH
3132 case INDEX_op_or_i64:
3133 case INDEX_op_xor_i64:
3134 return C_O1_I2(r, r, rK);
a8f0269e 3135
6c9b5c0f
RH
3136 case INDEX_op_andc_i32:
3137 case INDEX_op_orc_i32:
3138 case INDEX_op_eqv_i32:
3139 return C_O1_I2(r, r, ri);
3140 case INDEX_op_andc_i64:
3141 return C_O1_I2(r, r, rKR);
3142 case INDEX_op_orc_i64:
3143 case INDEX_op_eqv_i64:
3144 return C_O1_I2(r, r, rNK);
3145
3146 case INDEX_op_nand_i32:
3147 case INDEX_op_nand_i64:
3148 case INDEX_op_nor_i32:
3149 case INDEX_op_nor_i64:
3150 return C_O1_I2(r, r, r);
3151
9b5500b6 3152 case INDEX_op_mul_i32:
92c89a07
RH
3153 return (HAVE_FACILITY(MISC_INSN_EXT2)
3154 ? C_O1_I2(r, r, ri)
3155 : C_O1_I2(r, 0, ri));
9b5500b6 3156 case INDEX_op_mul_i64:
92c89a07
RH
3157 return (HAVE_FACILITY(MISC_INSN_EXT2)
3158 ? C_O1_I2(r, r, rJ)
3159 : C_O1_I2(r, 0, rJ));
a8f0269e 3160
9b5500b6
RH
3161 case INDEX_op_shl_i32:
3162 case INDEX_op_shr_i32:
3163 case INDEX_op_sar_i32:
238da1c9 3164 return C_O1_I2(r, r, ri);
9b5500b6
RH
3165
3166 case INDEX_op_brcond_i32:
d1c36a90 3167 return C_O0_I2(r, ri);
32c256ed
RH
3168 case INDEX_op_brcond_i64:
3169 return C_O0_I2(r, rA);
9b5500b6
RH
3170
3171 case INDEX_op_bswap16_i32:
3172 case INDEX_op_bswap16_i64:
3173 case INDEX_op_bswap32_i32:
3174 case INDEX_op_bswap32_i64:
3175 case INDEX_op_bswap64_i64:
3176 case INDEX_op_neg_i32:
3177 case INDEX_op_neg_i64:
6c9b5c0f
RH
3178 case INDEX_op_not_i32:
3179 case INDEX_op_not_i64:
9b5500b6
RH
3180 case INDEX_op_ext8s_i32:
3181 case INDEX_op_ext8s_i64:
3182 case INDEX_op_ext8u_i32:
3183 case INDEX_op_ext8u_i64:
3184 case INDEX_op_ext16s_i32:
3185 case INDEX_op_ext16s_i64:
3186 case INDEX_op_ext16u_i32:
3187 case INDEX_op_ext16u_i64:
3188 case INDEX_op_ext32s_i64:
3189 case INDEX_op_ext32u_i64:
3190 case INDEX_op_ext_i32_i64:
3191 case INDEX_op_extu_i32_i64:
3192 case INDEX_op_extract_i32:
3193 case INDEX_op_extract_i64:
29a5ea73
RH
3194 case INDEX_op_ctpop_i32:
3195 case INDEX_op_ctpop_i64:
d1c36a90 3196 return C_O1_I1(r, r);
9b5500b6 3197
fecccfcc
RH
3198 case INDEX_op_qemu_ld_a32_i32:
3199 case INDEX_op_qemu_ld_a64_i32:
3200 case INDEX_op_qemu_ld_a32_i64:
3201 case INDEX_op_qemu_ld_a64_i64:
94901422 3202 return C_O1_I1(r, r);
fecccfcc
RH
3203 case INDEX_op_qemu_st_a32_i64:
3204 case INDEX_op_qemu_st_a64_i64:
3205 case INDEX_op_qemu_st_a32_i32:
3206 case INDEX_op_qemu_st_a64_i32:
94901422 3207 return C_O0_I2(r, r);
4caad79f
RH
3208 case INDEX_op_qemu_ld_a32_i128:
3209 case INDEX_op_qemu_ld_a64_i128:
3210 return C_O2_I1(o, m, r);
3211 case INDEX_op_qemu_st_a32_i128:
3212 case INDEX_op_qemu_st_a64_i128:
3213 return C_O0_I3(o, m, r);
f69d277e 3214
9b5500b6
RH
3215 case INDEX_op_deposit_i32:
3216 case INDEX_op_deposit_i64:
d1c36a90
RH
3217 return C_O1_I2(r, rZ, r);
3218
9b5500b6 3219 case INDEX_op_movcond_i32:
23d1394a 3220 return C_O1_I4(r, r, ri, rI, r);
32c256ed
RH
3221 case INDEX_op_movcond_i64:
3222 return C_O1_I4(r, r, rA, rI, r);
d1c36a90 3223
9b5500b6
RH
3224 case INDEX_op_div2_i32:
3225 case INDEX_op_div2_i64:
3226 case INDEX_op_divu2_i32:
3227 case INDEX_op_divu2_i64:
4143f78d 3228 return C_O2_I3(o, m, 0, 1, r);
d1c36a90 3229
9b5500b6 3230 case INDEX_op_mulu2_i64:
4143f78d 3231 return C_O2_I2(o, m, 0, r);
668ce343
RH
3232 case INDEX_op_muls2_i64:
3233 return C_O2_I2(o, m, r, r);
ba18b07d 3234
9b5500b6 3235 case INDEX_op_add2_i32:
9b5500b6 3236 case INDEX_op_sub2_i32:
3e25f7da 3237 return C_O2_I4(r, r, 0, 1, ri, r);
d1c36a90 3238
ba18b07d 3239 case INDEX_op_add2_i64:
9b5500b6 3240 case INDEX_op_sub2_i64:
3e25f7da 3241 return C_O2_I4(r, r, 0, 1, rA, r);
9b5500b6 3242
34ef7676
RH
3243 case INDEX_op_st_vec:
3244 return C_O0_I2(v, r);
3245 case INDEX_op_ld_vec:
3246 case INDEX_op_dupm_vec:
3247 return C_O1_I1(v, r);
3248 case INDEX_op_dup_vec:
3249 return C_O1_I1(v, vr);
ae77bbe5
RH
3250 case INDEX_op_abs_vec:
3251 case INDEX_op_neg_vec:
3252 case INDEX_op_not_vec:
22cb37b4
RH
3253 case INDEX_op_rotli_vec:
3254 case INDEX_op_sari_vec:
3255 case INDEX_op_shli_vec:
3256 case INDEX_op_shri_vec:
4223c9c1
RH
3257 case INDEX_op_s390_vuph_vec:
3258 case INDEX_op_s390_vupl_vec:
ae77bbe5 3259 return C_O1_I1(v, v);
34ef7676
RH
3260 case INDEX_op_add_vec:
3261 case INDEX_op_sub_vec:
3262 case INDEX_op_and_vec:
ae77bbe5 3263 case INDEX_op_andc_vec:
34ef7676 3264 case INDEX_op_or_vec:
ae77bbe5 3265 case INDEX_op_orc_vec:
34ef7676 3266 case INDEX_op_xor_vec:
21eab5bf
RH
3267 case INDEX_op_nand_vec:
3268 case INDEX_op_nor_vec:
3269 case INDEX_op_eqv_vec:
34ef7676 3270 case INDEX_op_cmp_vec:
479b61cb 3271 case INDEX_op_mul_vec:
22cb37b4
RH
3272 case INDEX_op_rotlv_vec:
3273 case INDEX_op_rotrv_vec:
3274 case INDEX_op_shlv_vec:
3275 case INDEX_op_shrv_vec:
3276 case INDEX_op_sarv_vec:
220db7a6
RH
3277 case INDEX_op_smax_vec:
3278 case INDEX_op_smin_vec:
3279 case INDEX_op_umax_vec:
3280 case INDEX_op_umin_vec:
4223c9c1 3281 case INDEX_op_s390_vpks_vec:
34ef7676 3282 return C_O1_I2(v, v, v);
22cb37b4
RH
3283 case INDEX_op_rotls_vec:
3284 case INDEX_op_shls_vec:
3285 case INDEX_op_shrs_vec:
3286 case INDEX_op_sars_vec:
3287 return C_O1_I2(v, v, r);
9bca986d
RH
3288 case INDEX_op_bitsel_vec:
3289 return C_O1_I3(v, v, v, v);
34ef7676 3290
9b5500b6 3291 default:
d1c36a90 3292 g_assert_not_reached();
f69d277e 3293 }
f69d277e
RH
3294}
3295
34ef7676
RH
3296/*
3297 * Mainline glibc added HWCAP_S390_VX before it was kernel abi.
3298 * Some distros have fixed this up locally, others have not.
3299 */
3300#ifndef HWCAP_S390_VXRS
3301#define HWCAP_S390_VXRS 2048
3302#endif
3303
b2c98d9d 3304static void query_s390_facilities(void)
48bb3750 3305{
c9baa30f 3306 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
761ea522 3307 const char *which;
48bb3750 3308
c9baa30f
RH
3309 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
3310 is present on all 64-bit systems, but let's check for it anyway. */
3311 if (hwcap & HWCAP_S390_STFLE) {
748b7f3e
RH
3312 register int r0 __asm__("0") = ARRAY_SIZE(s390_facilities) - 1;
3313 register void *r1 __asm__("1") = s390_facilities;
48bb3750 3314
c9baa30f 3315 /* stfle 0(%r1) */
c9baa30f 3316 asm volatile(".word 0xb2b0,0x1000"
748b7f3e 3317 : "=r"(r0) : "r"(r0), "r"(r1) : "memory", "cc");
48bb3750 3318 }
34ef7676
RH
3319
3320 /*
3321 * Use of vector registers requires os support beyond the facility bit.
3322 * If the kernel does not advertise support, disable the facility bits.
3323 * There is nothing else we currently care about in the 3rd word, so
3324 * disable VECTOR with one store.
3325 */
a429ee29 3326 if (!(hwcap & HWCAP_S390_VXRS)) {
34ef7676
RH
3327 s390_facilities[2] = 0;
3328 }
761ea522
RH
3329
3330 /*
c68d5b7a 3331 * Minimum supported cpu revision is z196.
761ea522
RH
3332 * Check for all required facilities.
3333 * ZARCH_ACTIVE is done via preprocessor check for 64-bit.
3334 */
3335 if (!HAVE_FACILITY(LONG_DISP)) {
3336 which = "long-displacement";
3337 goto fail;
3338 }
3e25f7da
RH
3339 if (!HAVE_FACILITY(EXT_IMM)) {
3340 which = "extended-immediate";
3341 goto fail;
3342 }
9c3bfb79
RH
3343 if (!HAVE_FACILITY(GEN_INST_EXT)) {
3344 which = "general-instructions-extension";
3345 goto fail;
3346 }
c68d5b7a
RH
3347 /*
3348 * Facility 45 is a big bin that contains: distinct-operands,
3349 * fast-BCR-serialization, high-word, population-count,
3350 * interlocked-access-1, and load/store-on-condition-1
3351 */
3352 if (!HAVE_FACILITY(45)) {
3353 which = "45";
3354 goto fail;
3355 }
761ea522
RH
3356 return;
3357
3358 fail:
3359 error_report("%s: missing required facility %s", __func__, which);
3360 exit(EXIT_FAILURE);
48bb3750
RH
3361}
3362
3363static void tcg_target_init(TCGContext *s)
2827822e 3364{
b2c98d9d 3365 query_s390_facilities();
48bb3750 3366
f46934df
RH
3367 tcg_target_available_regs[TCG_TYPE_I32] = 0xffff;
3368 tcg_target_available_regs[TCG_TYPE_I64] = 0xffff;
34ef7676
RH
3369 if (HAVE_FACILITY(VECTOR)) {
3370 tcg_target_available_regs[TCG_TYPE_V64] = 0xffffffff00000000ull;
3371 tcg_target_available_regs[TCG_TYPE_V128] = 0xffffffff00000000ull;
3372 }
48bb3750 3373
ccb1bb66 3374 tcg_target_call_clobber_regs = 0;
48bb3750
RH
3375 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
3376 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
3377 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
3378 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
3379 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
3380 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
f24efee4
RH
3381 /* The r6 register is technically call-saved, but it's also a parameter
3382 register, so it can get killed by setup for the qemu_st helper. */
3383 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6);
48bb3750
RH
3384 /* The return register can be considered call-clobbered. */
3385 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
3386
34ef7676
RH
3387 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V0);
3388 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V1);
3389 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V2);
3390 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V3);
3391 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V4);
3392 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V5);
3393 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V6);
3394 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V7);
3395 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V16);
3396 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V17);
3397 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V18);
3398 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V19);
3399 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V20);
3400 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V21);
3401 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V22);
3402 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V23);
3403 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V24);
3404 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V25);
3405 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V26);
3406 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V27);
3407 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V28);
3408 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V29);
3409 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V30);
3410 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V31);
3411
ccb1bb66 3412 s->reserved_regs = 0;
48bb3750
RH
3413 tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
3414 /* XXX many insns can't be used with R0, so we better avoid it for now */
3415 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
3416 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2827822e
AG
3417}
3418
f167dc37
RH
3419#define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
3420 + TCG_STATIC_CALL_ARGS_SIZE \
3421 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
3422
48bb3750 3423static void tcg_target_qemu_prologue(TCGContext *s)
2827822e 3424{
48bb3750
RH
3425 /* stmg %r6,%r15,48(%r15) (save registers) */
3426 tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
3427
a4924e8b 3428 /* aghi %r15,-frame_size */
f167dc37 3429 tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -FRAME_SIZE);
a4924e8b
RH
3430
3431 tcg_set_frame(s, TCG_REG_CALL_STACK,
3432 TCG_STATIC_CALL_ARGS_SIZE + TCG_TARGET_CALL_STACK_OFFSET,
3433 CPU_TEMP_BUF_NLONGS * sizeof(long));
48bb3750 3434
090d0bfd 3435#ifndef CONFIG_SOFTMMU
b76f21a7 3436 if (guest_base >= 0x80000) {
ccbecb44 3437 tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base);
48bb3750
RH
3438 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
3439 }
090d0bfd 3440#endif
48bb3750 3441
cea5f9a2 3442 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
829e1376 3443
cea5f9a2
BS
3444 /* br %r3 (go to TB) */
3445 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
48bb3750 3446
46644483
RH
3447 /*
3448 * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
3449 * and fall through to the rest of the epilogue.
3450 */
c8bc1168 3451 tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
46644483
RH
3452 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, 0);
3453
3454 /* TB epilogue */
79dae4dd 3455 tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
48bb3750 3456
a4924e8b
RH
3457 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
3458 tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15,
f167dc37 3459 FRAME_SIZE + 48);
48bb3750
RH
3460
3461 /* br %r14 (return) */
3462 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
2827822e 3463}
f167dc37 3464
28eef8aa
RH
3465static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
3466{
3467 memset(p, 0x07, count * sizeof(tcg_insn_unit));
3468}
3469
f167dc37 3470typedef struct {
d2e16f2c 3471 DebugFrameHeader h;
f167dc37
RH
3472 uint8_t fde_def_cfa[4];
3473 uint8_t fde_reg_ofs[18];
3474} DebugFrame;
3475
3476/* We're expecting a 2 byte uleb128 encoded value. */
3477QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
3478
3479#define ELF_HOST_MACHINE EM_S390
3480
d2e16f2c
RH
3481static const DebugFrame debug_frame = {
3482 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
3483 .h.cie.id = -1,
3484 .h.cie.version = 1,
3485 .h.cie.code_align = 1,
3486 .h.cie.data_align = 8, /* sleb128 8 */
3487 .h.cie.return_column = TCG_REG_R14,
f167dc37
RH
3488
3489 /* Total FDE size does not include the "len" member. */
d2e16f2c 3490 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
f167dc37
RH
3491
3492 .fde_def_cfa = {
3493 12, TCG_REG_CALL_STACK, /* DW_CFA_def_cfa %r15, ... */
3494 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
3495 (FRAME_SIZE >> 7)
3496 },
3497 .fde_reg_ofs = {
3498 0x86, 6, /* DW_CFA_offset, %r6, 48 */
3499 0x87, 7, /* DW_CFA_offset, %r7, 56 */
3500 0x88, 8, /* DW_CFA_offset, %r8, 64 */
3501 0x89, 9, /* DW_CFA_offset, %r92, 72 */
3502 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
3503 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
3504 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
3505 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
3506 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
3507 }
3508};
3509
755bf9e5 3510void tcg_register_jit(const void *buf, size_t buf_size)
f167dc37 3511{
f167dc37
RH
3512 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
3513}