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