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