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