qemu-iotests/162: Fix leaked temporary files
[qemu/kevin.git] / tcg / s390 / tcg-target.inc.c
blob5d7083e90c4f70e660eb059058c9e5eb8eeb415c
1 /*
2 * Tiny Code Generator for QEMU
4 * Copyright (c) 2009 Ulrich Hecht <uli@suse.de>
5 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
6 * Copyright (c) 2010 Richard Henderson <rth@twiddle.net>
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:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
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.
27 #include "tcg-be-ldst.h"
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
34 #include "elf.h"
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
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
45 #define TCG_CT_CONST_ADLI 0x1000
46 #define TCG_CT_CONST_ZERO 0x2000
48 /* Several places within the instruction set 0 means "no register"
49 rather than TCG_REG_R0. */
50 #define TCG_REG_NONE 0
52 /* A scratch register that may be be used throughout the backend. */
53 #define TCG_TMP0 TCG_REG_R1
55 #ifndef CONFIG_SOFTMMU
56 #define TCG_GUEST_BASE_REG TCG_REG_R13
57 #endif
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. */
63 typedef enum S390Opcode {
64 RIL_AFI = 0xc209,
65 RIL_AGFI = 0xc208,
66 RIL_ALFI = 0xc20b,
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,
88 RIL_SLFI = 0xc205,
89 RIL_SLGFI = 0xc204,
90 RIL_XIHF = 0xc006,
91 RIL_XILF = 0xc007,
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,
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,
124 RIE_RISBG = 0xec55,
126 RRE_AGR = 0xb908,
127 RRE_ALGR = 0xb90a,
128 RRE_ALCR = 0xb998,
129 RRE_ALCGR = 0xb988,
130 RRE_CGR = 0xb920,
131 RRE_CLGR = 0xb921,
132 RRE_DLGR = 0xb987,
133 RRE_DLR = 0xb997,
134 RRE_DSGFR = 0xb91d,
135 RRE_DSGR = 0xb90d,
136 RRE_FLOGR = 0xb983,
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,
148 RRE_MLGR = 0xb986,
149 RRE_MSGR = 0xb90c,
150 RRE_MSR = 0xb252,
151 RRE_NGR = 0xb980,
152 RRE_OGR = 0xb981,
153 RRE_SGR = 0xb909,
154 RRE_SLGR = 0xb90b,
155 RRE_SLBR = 0xb999,
156 RRE_SLBGR = 0xb989,
157 RRE_XGR = 0xb982,
159 RRF_LOCR = 0xb9f2,
160 RRF_LOCGR = 0xb9e2,
162 RR_AR = 0x1a,
163 RR_ALR = 0x1e,
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,
175 RR_SLR = 0x1f,
176 RR_XR = 0x17,
178 RSY_RLL = 0xeb1d,
179 RSY_RLLG = 0xeb1c,
180 RSY_SLLG = 0xeb0d,
181 RSY_SRAG = 0xeb0a,
182 RSY_SRLG = 0xeb0c,
184 RS_SLL = 0x89,
185 RS_SRA = 0x8a,
186 RS_SRL = 0x88,
188 RXY_AG = 0xe308,
189 RXY_AY = 0xe35a,
190 RXY_CG = 0xe320,
191 RXY_CY = 0xe359,
192 RXY_LAY = 0xe371,
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,
216 RX_A = 0x5a,
217 RX_C = 0x59,
218 RX_L = 0x58,
219 RX_LA = 0x41,
220 RX_LH = 0x48,
221 RX_ST = 0x50,
222 RX_STC = 0x42,
223 RX_STH = 0x40,
225 NOP = 0x0707,
226 } S390Opcode;
228 #ifdef CONFIG_DEBUG_TCG
229 static 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"
233 #endif
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. */
238 static const int tcg_target_reg_alloc_order[] = {
239 /* Call saved registers. */
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,
248 /* Call clobbered registers. */
249 TCG_REG_R14,
250 TCG_REG_R0,
251 TCG_REG_R1,
252 /* Argument registers, in reverse order of allocation. */
253 TCG_REG_R5,
254 TCG_REG_R4,
255 TCG_REG_R3,
256 TCG_REG_R2,
259 static const int tcg_target_call_iarg_regs[] = {
260 TCG_REG_R2,
261 TCG_REG_R3,
262 TCG_REG_R4,
263 TCG_REG_R5,
264 TCG_REG_R6,
267 static const int tcg_target_call_oarg_regs[] = {
268 TCG_REG_R2,
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
281 /* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
282 static const uint8_t tcg_cond_to_s390_cond[] = {
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,
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. */
298 static const uint8_t tcg_cond_to_ltr_cond[] = {
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,
311 #ifdef CONFIG_SOFTMMU
312 static 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,
327 static 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,
336 #endif
338 static tcg_insn_unit *tb_ret_addr;
339 uint64_t s390_facilities;
341 static void patch_reloc(tcg_insn_unit *code_ptr, int type,
342 intptr_t value, intptr_t addend)
344 intptr_t pcrel2 = (tcg_insn_unit *)value - (code_ptr - 1);
345 tcg_debug_assert(addend == -2);
347 switch (type) {
348 case R_390_PC16DBL:
349 tcg_debug_assert(pcrel2 == (int16_t)pcrel2);
350 tcg_patch16(code_ptr, pcrel2);
351 break;
352 case R_390_PC32DBL:
353 tcg_debug_assert(pcrel2 == (int32_t)pcrel2);
354 tcg_patch32(code_ptr, pcrel2);
355 break;
356 default:
357 tcg_abort();
358 break;
362 /* parse target specific constraints */
363 static const char *target_parse_constraint(TCGArgConstraint *ct,
364 const char *ct_str, TCGType type)
366 switch (*ct_str++) {
367 case 'r': /* all registers */
368 ct->ct |= TCG_CT_REG;
369 tcg_regset_set32(ct->u.regs, 0, 0xffff);
370 break;
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);
376 tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
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;
388 case 'A':
389 ct->ct |= TCG_CT_CONST_ADLI;
390 break;
391 case 'K':
392 ct->ct |= TCG_CT_CONST_MULI;
393 break;
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;
403 case 'Z':
404 ct->ct |= TCG_CT_CONST_ZERO;
405 break;
406 default:
407 return NULL;
409 return ct_str;
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. */
418 static int tcg_match_ori(TCGType type, tcg_target_long val)
420 if (s390_facilities & FACILITY_EXT_IMM) {
421 if (type == TCG_TYPE_I32) {
422 /* All 32-bit ORs can be performed with 1 48-bit insn. */
423 return 1;
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;
432 if (s390_facilities & FACILITY_EXT_IMM) {
433 if (val == (int32_t)val) {
434 return 0;
439 return 1;
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. */
447 static int tcg_match_xori(TCGType type, tcg_target_long val)
449 if ((s390_facilities & FACILITY_EXT_IMM) == 0) {
450 return 0;
453 if (type == TCG_TYPE_I32) {
454 /* All 32-bit XORs can be performed with 1 48-bit insn. */
455 return 1;
458 /* Look for negative values. These are best to load with LGHI. */
459 if (val < 0 && val == (int32_t)val) {
460 return 0;
463 return 1;
466 /* Imediates to be used with comparisons. */
468 static int tcg_match_cmpi(TCGType type, tcg_target_long val)
470 if (s390_facilities & FACILITY_EXT_IMM) {
471 /* The COMPARE IMMEDIATE instruction is available. */
472 if (type == TCG_TYPE_I32) {
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;
489 } else {
490 /* Only the LOAD AND TEST instruction is available. */
491 return val == 0;
495 /* Immediates to be used with add2/sub2. */
497 static int tcg_match_add2i(TCGType type, tcg_target_long val)
499 if (s390_facilities & FACILITY_EXT_IMM) {
500 if (type == TCG_TYPE_I32) {
501 return 1;
502 } else if (val >= -0xffffffffll && val <= 0xffffffffll) {
503 return 1;
506 return 0;
509 /* Test if a constant matches the constraint. */
510 static int tcg_target_const_match(tcg_target_long val, TCGType type,
511 const TCGArgConstraint *arg_ct)
513 int ct = arg_ct->ct;
515 if (ct & TCG_CT_CONST) {
516 return 1;
519 if (type == TCG_TYPE_I32) {
520 val = (int32_t)val;
523 /* The following are mutually exclusive. */
524 if (ct & TCG_CT_CONST_MULI) {
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. */
529 if (s390_facilities & FACILITY_GEN_INST_EXT) {
530 return val == (int32_t)val;
531 } else {
532 return val == (int16_t)val;
534 } else if (ct & TCG_CT_CONST_ADLI) {
535 return tcg_match_add2i(type, val);
536 } else if (ct & TCG_CT_CONST_ORI) {
537 return tcg_match_ori(type, val);
538 } else if (ct & TCG_CT_CONST_XORI) {
539 return tcg_match_xori(type, val);
540 } else if (ct & TCG_CT_CONST_CMPI) {
541 return tcg_match_cmpi(type, val);
542 } else if (ct & TCG_CT_CONST_ZERO) {
543 return val == 0;
546 return 0;
549 /* Emit instructions according to the given instruction format. */
551 static void tcg_out_insn_RR(TCGContext *s, S390Opcode op, TCGReg r1, TCGReg r2)
553 tcg_out16(s, (op << 8) | (r1 << 4) | r2);
556 static void tcg_out_insn_RRE(TCGContext *s, S390Opcode op,
557 TCGReg r1, TCGReg r2)
559 tcg_out32(s, (op << 16) | (r1 << 4) | r2);
562 static void tcg_out_insn_RRF(TCGContext *s, S390Opcode op,
563 TCGReg r1, TCGReg r2, int m3)
565 tcg_out32(s, (op << 16) | (m3 << 12) | (r1 << 4) | r2);
568 static void tcg_out_insn_RI(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
570 tcg_out32(s, (op << 16) | (r1 << 20) | (i2 & 0xffff));
573 static void tcg_out_insn_RIL(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
575 tcg_out16(s, op | (r1 << 4));
576 tcg_out32(s, i2);
579 static void tcg_out_insn_RS(TCGContext *s, S390Opcode op, TCGReg r1,
580 TCGReg b2, TCGReg r3, int disp)
582 tcg_out32(s, (op << 24) | (r1 << 20) | (r3 << 16) | (b2 << 12)
583 | (disp & 0xfff));
586 static void tcg_out_insn_RSY(TCGContext *s, S390Opcode op, TCGReg r1,
587 TCGReg b2, TCGReg r3, int disp)
589 tcg_out16(s, (op & 0xff00) | (r1 << 4) | r3);
590 tcg_out32(s, (op & 0xff) | (b2 << 28)
591 | ((disp & 0xfff) << 16) | ((disp & 0xff000) >> 4));
594 #define tcg_out_insn_RX tcg_out_insn_RS
595 #define tcg_out_insn_RXY tcg_out_insn_RSY
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__)
602 /* emit 64-bit shifts */
603 static void tcg_out_sh64(TCGContext* s, S390Opcode op, TCGReg dest,
604 TCGReg src, TCGReg sh_reg, int sh_imm)
606 tcg_out_insn_RSY(s, op, dest, sh_reg, src, sh_imm);
609 /* emit 32-bit shifts */
610 static void tcg_out_sh32(TCGContext* s, S390Opcode op, TCGReg dest,
611 TCGReg sh_reg, int sh_imm)
613 tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
616 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
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);
627 /* load a register with an immediate value */
628 static void tcg_out_movi(TCGContext *s, TCGType type,
629 TCGReg ret, tcg_target_long sval)
631 static const S390Opcode lli_insns[4] = {
632 RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
635 tcg_target_ulong uval = sval;
636 int i;
638 if (type == TCG_TYPE_I32) {
639 uval = (uint32_t)sval;
640 sval = (int32_t)sval;
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;
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;
657 /* Try all 48-bit insns that can load it in one go. */
658 if (s390_facilities & FACILITY_EXT_IMM) {
659 if (sval == (int32_t)sval) {
660 tcg_out_insn(s, RIL, LGFI, ret, sval);
661 return;
663 if (uval <= 0xffffffff) {
664 tcg_out_insn(s, RIL, LLILF, ret, uval);
665 return;
667 if ((uval & 0xffffffff) == 0) {
668 tcg_out_insn(s, RIL, LLIHF, ret, uval >> 31 >> 1);
669 return;
673 /* Try for PC-relative address load. */
674 if ((sval & 1) == 0) {
675 ptrdiff_t off = tcg_pcrel_diff(s, (void *)sval) >> 1;
676 if (off == (int32_t)off) {
677 tcg_out_insn(s, RIL, LARL, ret, off);
678 return;
682 /* If extended immediates are not present, then we may have to issue
683 several instructions to load the low 32 bits. */
684 if (!(s390_facilities & FACILITY_EXT_IMM)) {
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;
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);
705 tcg_out_insn(s, RI, IILH, ret, uval >> 16);
706 return;
710 /* If we get here, both the high and low parts have non-zero bits. */
712 /* Recurse to load the lower 32-bits. */
713 tcg_out_movi(s, TCG_TYPE_I64, ret, uval & 0xffffffff);
715 /* Insert data into the high 32-bits. */
716 uval = uval >> 31 >> 1;
717 if (s390_facilities & FACILITY_EXT_IMM) {
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);
725 } else {
726 if (uval & 0xffff) {
727 tcg_out_insn(s, RI, IIHL, ret, uval);
729 if (uval & 0xffff0000) {
730 tcg_out_insn(s, RI, IIHH, ret, uval >> 16);
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). */
742 static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
743 TCGReg data, TCGReg base, TCGReg index,
744 tcg_target_long ofs)
746 if (ofs < -0x80000 || ofs >= 0x80000) {
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;
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);
757 index = TCG_TMP0;
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);
768 /* load data without address translation or endianness conversion */
769 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
770 TCGReg base, intptr_t ofs)
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);
779 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
780 TCGReg base, intptr_t ofs)
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);
789 static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
790 TCGReg base, intptr_t ofs)
792 return false;
795 /* load data from an absolute host address */
796 static void tcg_out_ld_abs(TCGContext *s, TCGType type, TCGReg dest, void *abs)
798 intptr_t addr = (intptr_t)abs;
800 if ((s390_facilities & FACILITY_GEN_INST_EXT) && !(addr & 1)) {
801 ptrdiff_t disp = tcg_pcrel_diff(s, abs) >> 1;
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);
808 return;
812 tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
813 tcg_out_ld(s, type, dest, dest, addr & 0xffff);
816 static inline void tcg_out_risbg(TCGContext *s, TCGReg dest, TCGReg src,
817 int msb, int lsb, int ofs, int z)
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));
825 static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
827 if (s390_facilities & FACILITY_EXT_IMM) {
828 tcg_out_insn(s, RRE, LGBR, dest, src);
829 return;
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);
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);
845 static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
847 if (s390_facilities & FACILITY_EXT_IMM) {
848 tcg_out_insn(s, RRE, LLGCR, dest, src);
849 return;
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);
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);
865 static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
867 if (s390_facilities & FACILITY_EXT_IMM) {
868 tcg_out_insn(s, RRE, LGHR, dest, src);
869 return;
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);
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);
885 static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
887 if (s390_facilities & FACILITY_EXT_IMM) {
888 tcg_out_insn(s, RRE, LLGHR, dest, src);
889 return;
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);
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);
905 static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
907 tcg_out_insn(s, RRE, LGFR, dest, src);
910 static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
912 tcg_out_insn(s, RRE, LLGFR, dest, src);
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. */
921 static inline bool risbg_mask(uint64_t c)
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;
929 /* Reject all zeros or all ones. */
930 if (c == 0) {
931 return false;
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;
945 static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val)
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);
956 tcg_out_risbg(s, out, in, msb, lsb, 0, 1);
959 static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
961 static const S390Opcode ni_insns[4] = {
962 RI_NILL, RI_NILH, RI_NIHL, RI_NIHH
964 static const S390Opcode nif_insns[2] = {
965 RIL_NILF, RIL_NIHF
967 uint64_t valid = (type == TCG_TYPE_I32 ? 0xffffffffull : -1ull);
968 int i;
970 /* Look for the zero-extensions. */
971 if ((val & valid) == 0xffffffff) {
972 tgen_ext32u(s, dest, dest);
973 return;
975 if (s390_facilities & FACILITY_EXT_IMM) {
976 if ((val & valid) == 0xff) {
977 tgen_ext8u(s, TCG_TYPE_I64, dest, dest);
978 return;
980 if ((val & valid) == 0xffff) {
981 tgen_ext16u(s, TCG_TYPE_I64, dest, dest);
982 return;
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;
995 /* Try all 48-bit insns that can perform it in one go. */
996 if (s390_facilities & FACILITY_EXT_IMM) {
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;
1005 if ((s390_facilities & FACILITY_GEN_INST_EXT) && risbg_mask(val)) {
1006 tgen_andi_risbg(s, dest, dest, val);
1007 return;
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);
1014 } else {
1015 tcg_out_insn(s, RRE, NGR, dest, TCG_TMP0);
1019 static void tgen64_ori(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1021 static const S390Opcode oi_insns[4] = {
1022 RI_OILL, RI_OILH, RI_OIHL, RI_OIHH
1024 static const S390Opcode nif_insns[2] = {
1025 RIL_OILF, RIL_OIHF
1028 int i;
1030 /* Look for no-op. */
1031 if (val == 0) {
1032 return;
1035 if (s390_facilities & FACILITY_EXT_IMM) {
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;
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;
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);
1071 static void tgen64_xori(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1073 /* Perform the xor by parts. */
1074 if (val & 0xffffffff) {
1075 tcg_out_insn(s, RIL, XILF, dest, val);
1077 if (val > 0xffffffff) {
1078 tcg_out_insn(s, RIL, XIHF, dest, val >> 31 >> 1);
1082 static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
1083 TCGArg c2, bool c2const, bool need_carry)
1085 bool is_unsigned = is_unsigned_cond(c);
1086 if (c2const) {
1087 if (c2 == 0) {
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);
1094 return tcg_cond_to_ltr_cond[c];
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. */
1099 if (!(s390_facilities & FACILITY_EXT_IMM)) {
1100 c2 = TCG_TMP0;
1101 tcg_out_movi(s, type, c2, 0);
1102 goto do_reg;
1105 if (is_unsigned) {
1106 if (type == TCG_TYPE_I32) {
1107 tcg_out_insn(s, RIL, CLFI, r1, c2);
1108 } else {
1109 tcg_out_insn(s, RIL, CLGFI, r1, c2);
1111 } else {
1112 if (type == TCG_TYPE_I32) {
1113 tcg_out_insn(s, RIL, CFI, r1, c2);
1114 } else {
1115 tcg_out_insn(s, RIL, CGFI, r1, c2);
1118 } else {
1119 do_reg:
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);
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);
1134 return tcg_cond_to_s390_cond[c];
1137 static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
1138 TCGReg dest, TCGReg c1, TCGArg c2, int c2const)
1140 int cc;
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. */
1148 tgen_cmp(s, type, cond, c1, c2, c2const, true);
1149 tcg_out_movi(s, type, dest, 0);
1150 tcg_out_insn(s, RRE, ALCGR, dest, dest);
1151 return;
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);
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);
1171 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1173 tcg_out_insn(s, RRE, ALCGR, dest, dest);
1174 return;
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;
1190 if (cond == TCG_COND_LEU) {
1191 goto do_geu;
1193 cond = tcg_swap_cond(cond);
1194 goto do_greater;
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;
1202 break;
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;
1213 break;
1215 default:
1216 break;
1219 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1220 if (s390_facilities & FACILITY_LOAD_ON_COND) {
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);
1233 static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest,
1234 TCGReg c1, TCGArg c2, int c2const, TCGReg r3)
1236 int cc;
1237 if (s390_facilities & FACILITY_LOAD_ON_COND) {
1238 cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1239 tcg_out_insn(s, RRF, LOCGR, dest, r3, cc);
1240 } else {
1241 c = tcg_invert_cond(c);
1242 cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
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);
1250 static void tgen_clz(TCGContext *s, TCGReg dest, TCGReg a1,
1251 TCGArg a2, int a2const)
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);
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);
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);
1277 static void tgen_deposit(TCGContext *s, TCGReg dest, TCGReg src,
1278 int ofs, int len, int z)
1280 int lsb = (63 - ofs);
1281 int msb = lsb - (len - 1);
1282 tcg_out_risbg(s, dest, src, msb, lsb, ofs, z);
1285 static void tgen_extract(TCGContext *s, TCGReg dest, TCGReg src,
1286 int ofs, int len)
1288 tcg_out_risbg(s, dest, src, 64 - len, 63, 64 - ofs, 1);
1291 static void tgen_gotoi(TCGContext *s, int cc, tcg_insn_unit *dest)
1293 ptrdiff_t off = dest - s->code_ptr;
1294 if (off == (int16_t)off) {
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 {
1299 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1300 tcg_out_insn(s, RR, BCR, cc, TCG_TMP0);
1304 static void tgen_branch(TCGContext *s, int cc, TCGLabel *l)
1306 if (l->has_value) {
1307 tgen_gotoi(s, cc, l->u.value_ptr);
1308 } else if (USE_LONG_BRANCHES) {
1309 tcg_out16(s, RIL_BRCL | (cc << 4));
1310 tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, l, -2);
1311 s->code_ptr += 2;
1312 } else {
1313 tcg_out16(s, RI_BRC | (cc << 4));
1314 tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, l, -2);
1315 s->code_ptr += 1;
1319 static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
1320 TCGReg r1, TCGReg r2, TCGLabel *l)
1322 intptr_t off;
1324 if (l->has_value) {
1325 off = l->u.value_ptr - s->code_ptr;
1326 } else {
1327 /* We need to keep the offset unchanged for retranslation. */
1328 off = s->code_ptr[1];
1329 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, -2);
1332 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
1333 tcg_out16(s, off);
1334 tcg_out16(s, cc << 12 | (opc & 0xff));
1337 static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
1338 TCGReg r1, int i2, TCGLabel *l)
1340 tcg_target_long off;
1342 if (l->has_value) {
1343 off = l->u.value_ptr - s->code_ptr;
1344 } else {
1345 /* We need to keep the offset unchanged for retranslation. */
1346 off = s->code_ptr[1];
1347 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, -2);
1350 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
1351 tcg_out16(s, off);
1352 tcg_out16(s, (i2 << 8) | (opc & 0xff));
1355 static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
1356 TCGReg r1, TCGArg c2, int c2const, TCGLabel *l)
1358 int cc;
1360 if (s390_facilities & FACILITY_GEN_INST_EXT) {
1361 bool is_unsigned = is_unsigned_cond(c);
1362 bool in_range;
1363 S390Opcode opc;
1365 cc = tcg_cond_to_s390_cond[c];
1367 if (!c2const) {
1368 opc = (type == TCG_TYPE_I32
1369 ? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
1370 : (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
1371 tgen_compare_branch(s, opc, cc, r1, c2, l);
1372 return;
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;
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;
1396 if (in_range) {
1397 tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
1398 return;
1402 cc = tgen_cmp(s, type, c, r1, c2, c2const, false);
1403 tgen_branch(s, cc, l);
1406 static void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
1408 ptrdiff_t off = dest - s->code_ptr;
1409 if (off == (int32_t)off) {
1410 tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
1411 } else {
1412 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1413 tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_TMP0);
1417 static void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp opc, TCGReg data,
1418 TCGReg base, TCGReg index, int disp)
1420 switch (opc & (MO_SSIZE | MO_BSWAP)) {
1421 case MO_UB:
1422 tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
1423 break;
1424 case MO_SB:
1425 tcg_out_insn(s, RXY, LGB, data, base, index, disp);
1426 break;
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;
1433 case MO_UW:
1434 tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
1435 break;
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);
1441 break;
1442 case MO_SW:
1443 tcg_out_insn(s, RXY, LGH, data, base, index, disp);
1444 break;
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);
1450 break;
1451 case MO_UL:
1452 tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
1453 break;
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);
1459 break;
1460 case MO_SL:
1461 tcg_out_insn(s, RXY, LGF, data, base, index, disp);
1462 break;
1464 case MO_Q | MO_BSWAP:
1465 tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
1466 break;
1467 case MO_Q:
1468 tcg_out_insn(s, RXY, LG, data, base, index, disp);
1469 break;
1471 default:
1472 tcg_abort();
1476 static void tcg_out_qemu_st_direct(TCGContext *s, TCGMemOp opc, TCGReg data,
1477 TCGReg base, TCGReg index, int disp)
1479 switch (opc & (MO_SIZE | MO_BSWAP)) {
1480 case MO_UB:
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);
1486 break;
1488 case MO_UW | MO_BSWAP:
1489 tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
1490 break;
1491 case MO_UW:
1492 if (disp >= 0 && disp < 0x1000) {
1493 tcg_out_insn(s, RX, STH, data, base, index, disp);
1494 } else {
1495 tcg_out_insn(s, RXY, STHY, data, base, index, disp);
1497 break;
1499 case MO_UL | MO_BSWAP:
1500 tcg_out_insn(s, RXY, STRV, data, base, index, disp);
1501 break;
1502 case MO_UL:
1503 if (disp >= 0 && disp < 0x1000) {
1504 tcg_out_insn(s, RX, ST, data, base, index, disp);
1505 } else {
1506 tcg_out_insn(s, RXY, STY, data, base, index, disp);
1508 break;
1510 case MO_Q | MO_BSWAP:
1511 tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
1512 break;
1513 case MO_Q:
1514 tcg_out_insn(s, RXY, STG, data, base, index, disp);
1515 break;
1517 default:
1518 tcg_abort();
1522 #if defined(CONFIG_SOFTMMU)
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. */
1526 QEMU_BUILD_BUG_ON(offsetof(CPUArchState, tlb_table[NB_MMU_MODES - 1][1])
1527 > 0x7ffff);
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. */
1531 static TCGReg tcg_out_tlb_read(TCGContext* s, TCGReg addr_reg, TCGMemOp opc,
1532 int mem_index, bool is_ld)
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;
1538 int ofs, a_off;
1539 uint64_t tlb_mask;
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. */
1544 a_off = (a_bits >= s_bits ? 0 : s_mask - a_mask);
1545 tlb_mask = (uint64_t)TARGET_PAGE_MASK | a_mask;
1547 if (s390_facilities & FACILITY_GEN_INST_EXT) {
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);
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);
1558 } else {
1559 tcg_out_sh64(s, RSY_SRLG, TCG_REG_R2, addr_reg, TCG_REG_NONE,
1560 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1561 tcg_out_insn(s, RX, LA, TCG_REG_R3, addr_reg, TCG_REG_NONE, a_off);
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);
1567 if (is_ld) {
1568 ofs = offsetof(CPUArchState, tlb_table[mem_index][0].addr_read);
1569 } else {
1570 ofs = offsetof(CPUArchState, tlb_table[mem_index][0].addr_write);
1572 if (TARGET_LONG_BITS == 32) {
1573 tcg_out_mem(s, RX_C, RXY_CY, TCG_REG_R3, TCG_REG_R2, TCG_AREG0, ofs);
1574 } else {
1575 tcg_out_mem(s, 0, RXY_CG, TCG_REG_R3, TCG_REG_R2, TCG_AREG0, ofs);
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);
1581 if (TARGET_LONG_BITS == 32) {
1582 tgen_ext32u(s, TCG_REG_R3, addr_reg);
1583 return TCG_REG_R3;
1585 return addr_reg;
1588 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
1589 TCGReg data, TCGReg addr,
1590 tcg_insn_unit *raddr, tcg_insn_unit *label_ptr)
1592 TCGLabelQemuLdst *label = new_ldst_label(s);
1594 label->is_ld = is_ld;
1595 label->oi = oi;
1596 label->datalo_reg = data;
1597 label->addrlo_reg = addr;
1598 label->raddr = raddr;
1599 label->label_ptr[0] = label_ptr;
1602 static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1604 TCGReg addr_reg = lb->addrlo_reg;
1605 TCGReg data_reg = lb->datalo_reg;
1606 TCGMemOpIdx oi = lb->oi;
1607 TCGMemOp opc = get_memop(oi);
1609 patch_reloc(lb->label_ptr[0], R_390_PC16DBL, (intptr_t)s->code_ptr, -2);
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);
1615 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, oi);
1616 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R5, (uintptr_t)lb->raddr);
1617 tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)]);
1618 tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_R2);
1620 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1623 static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1625 TCGReg addr_reg = lb->addrlo_reg;
1626 TCGReg data_reg = lb->datalo_reg;
1627 TCGMemOpIdx oi = lb->oi;
1628 TCGMemOp opc = get_memop(oi);
1630 patch_reloc(lb->label_ptr[0], R_390_PC16DBL, (intptr_t)s->code_ptr, -2);
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);
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();
1652 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, oi);
1653 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R6, (uintptr_t)lb->raddr);
1654 tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1656 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1658 #else
1659 static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
1660 TCGReg *index_reg, tcg_target_long *disp)
1662 if (TARGET_LONG_BITS == 32) {
1663 tgen_ext32u(s, TCG_TMP0, *addr_reg);
1664 *addr_reg = TCG_TMP0;
1666 if (guest_base < 0x80000) {
1667 *index_reg = TCG_REG_NONE;
1668 *disp = guest_base;
1669 } else {
1670 *index_reg = TCG_GUEST_BASE_REG;
1671 *disp = 0;
1674 #endif /* CONFIG_SOFTMMU */
1676 static void tcg_out_qemu_ld(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
1677 TCGMemOpIdx oi)
1679 TCGMemOp opc = get_memop(oi);
1680 #ifdef CONFIG_SOFTMMU
1681 unsigned mem_index = get_mmuidx(oi);
1682 tcg_insn_unit *label_ptr;
1683 TCGReg base_reg;
1685 base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 1);
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;
1692 tcg_out_qemu_ld_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
1694 add_qemu_ldst_label(s, 1, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
1695 #else
1696 TCGReg index_reg;
1697 tcg_target_long disp;
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
1704 static void tcg_out_qemu_st(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
1705 TCGMemOpIdx oi)
1707 TCGMemOp opc = get_memop(oi);
1708 #ifdef CONFIG_SOFTMMU
1709 unsigned mem_index = get_mmuidx(oi);
1710 tcg_insn_unit *label_ptr;
1711 TCGReg base_reg;
1713 base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 0);
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;
1720 tcg_out_qemu_st_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
1722 add_qemu_ldst_label(s, 0, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
1723 #else
1724 TCGReg index_reg;
1725 tcg_target_long disp;
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
1732 # define OP_32_64(x) \
1733 case glue(glue(INDEX_op_,x),_i32): \
1734 case glue(glue(INDEX_op_,x),_i64)
1736 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1737 const TCGArg *args, const int *const_args)
1739 S390Opcode op;
1740 TCGArg a0, a1, a2;
1742 switch (opc) {
1743 case INDEX_op_exit_tb:
1744 /* Reuse the zeroing that exists for goto_ptr. */
1745 a0 = args[0];
1746 if (a0 == 0) {
1747 tgen_gotoi(s, S390_CC_ALWAYS, s->code_gen_epilogue);
1748 } else {
1749 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, a0);
1750 tgen_gotoi(s, S390_CC_ALWAYS, tb_ret_addr);
1752 break;
1754 case INDEX_op_goto_tb:
1755 if (s->tb_jmp_insn_offset) {
1756 /* branch displacement must be aligned for atomic patching;
1757 * see if we need to add extra nop before branch
1759 if (!QEMU_PTR_IS_ALIGNED(s->code_ptr + 1, 4)) {
1760 tcg_out16(s, NOP);
1762 tcg_out16(s, RIL_BRCL | (S390_CC_ALWAYS << 4));
1763 s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
1764 s->code_ptr += 2;
1765 } else {
1766 /* load address stored at s->tb_jmp_target_addr + args[0] */
1767 tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_TMP0,
1768 s->tb_jmp_target_addr + args[0]);
1769 /* and go there */
1770 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_TMP0);
1772 s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
1773 break;
1775 case INDEX_op_goto_ptr:
1776 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, args[0]);
1777 break;
1779 OP_32_64(ld8u):
1780 /* ??? LLC (RXY format) is only present with the extended-immediate
1781 facility, whereas LLGC is always present. */
1782 tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
1783 break;
1785 OP_32_64(ld8s):
1786 /* ??? LB is no smaller than LGB, so no point to using it. */
1787 tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
1788 break;
1790 OP_32_64(ld16u):
1791 /* ??? LLH (RXY format) is only present with the extended-immediate
1792 facility, whereas LLGH is always present. */
1793 tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
1794 break;
1796 case INDEX_op_ld16s_i32:
1797 tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
1798 break;
1800 case INDEX_op_ld_i32:
1801 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1802 break;
1804 OP_32_64(st8):
1805 tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
1806 TCG_REG_NONE, args[2]);
1807 break;
1809 OP_32_64(st16):
1810 tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
1811 TCG_REG_NONE, args[2]);
1812 break;
1814 case INDEX_op_st_i32:
1815 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1816 break;
1818 case INDEX_op_add_i32:
1819 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1820 if (const_args[2]) {
1821 do_addi_32:
1822 if (a0 == a1) {
1823 if (a2 == (int16_t)a2) {
1824 tcg_out_insn(s, RI, AHI, a0, a2);
1825 break;
1827 if (s390_facilities & FACILITY_EXT_IMM) {
1828 tcg_out_insn(s, RIL, AFI, a0, a2);
1829 break;
1832 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
1833 } else if (a0 == a1) {
1834 tcg_out_insn(s, RR, AR, a0, a2);
1835 } else {
1836 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
1838 break;
1839 case INDEX_op_sub_i32:
1840 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1841 if (const_args[2]) {
1842 a2 = -a2;
1843 goto do_addi_32;
1845 tcg_out_insn(s, RR, SR, args[0], args[2]);
1846 break;
1848 case INDEX_op_and_i32:
1849 if (const_args[2]) {
1850 tgen_andi(s, TCG_TYPE_I32, args[0], args[2]);
1851 } else {
1852 tcg_out_insn(s, RR, NR, args[0], args[2]);
1854 break;
1855 case INDEX_op_or_i32:
1856 if (const_args[2]) {
1857 tgen64_ori(s, args[0], args[2] & 0xffffffff);
1858 } else {
1859 tcg_out_insn(s, RR, OR, args[0], args[2]);
1861 break;
1862 case INDEX_op_xor_i32:
1863 if (const_args[2]) {
1864 tgen64_xori(s, args[0], args[2] & 0xffffffff);
1865 } else {
1866 tcg_out_insn(s, RR, XR, args[0], args[2]);
1868 break;
1870 case INDEX_op_neg_i32:
1871 tcg_out_insn(s, RR, LCR, args[0], args[1]);
1872 break;
1874 case INDEX_op_mul_i32:
1875 if (const_args[2]) {
1876 if ((int32_t)args[2] == (int16_t)args[2]) {
1877 tcg_out_insn(s, RI, MHI, args[0], args[2]);
1878 } else {
1879 tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
1881 } else {
1882 tcg_out_insn(s, RRE, MSR, args[0], args[2]);
1884 break;
1886 case INDEX_op_div2_i32:
1887 tcg_out_insn(s, RR, DR, TCG_REG_R2, args[4]);
1888 break;
1889 case INDEX_op_divu2_i32:
1890 tcg_out_insn(s, RRE, DLR, TCG_REG_R2, args[4]);
1891 break;
1893 case INDEX_op_shl_i32:
1894 op = RS_SLL;
1895 do_shift32:
1896 if (const_args[2]) {
1897 tcg_out_sh32(s, op, args[0], TCG_REG_NONE, args[2]);
1898 } else {
1899 tcg_out_sh32(s, op, args[0], args[2], 0);
1901 break;
1902 case INDEX_op_shr_i32:
1903 op = RS_SRL;
1904 goto do_shift32;
1905 case INDEX_op_sar_i32:
1906 op = RS_SRA;
1907 goto do_shift32;
1909 case INDEX_op_rotl_i32:
1910 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1911 if (const_args[2]) {
1912 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
1913 } else {
1914 tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
1916 break;
1917 case INDEX_op_rotr_i32:
1918 if (const_args[2]) {
1919 tcg_out_sh64(s, RSY_RLL, args[0], args[1],
1920 TCG_REG_NONE, (32 - args[2]) & 31);
1921 } else {
1922 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
1923 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
1925 break;
1927 case INDEX_op_ext8s_i32:
1928 tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
1929 break;
1930 case INDEX_op_ext16s_i32:
1931 tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
1932 break;
1933 case INDEX_op_ext8u_i32:
1934 tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
1935 break;
1936 case INDEX_op_ext16u_i32:
1937 tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
1938 break;
1940 OP_32_64(bswap16):
1941 /* The TCG bswap definition requires bits 0-47 already be zero.
1942 Thus we don't need the G-type insns to implement bswap16_i64. */
1943 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1944 tcg_out_sh32(s, RS_SRL, args[0], TCG_REG_NONE, 16);
1945 break;
1946 OP_32_64(bswap32):
1947 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1948 break;
1950 case INDEX_op_add2_i32:
1951 if (const_args[4]) {
1952 tcg_out_insn(s, RIL, ALFI, args[0], args[4]);
1953 } else {
1954 tcg_out_insn(s, RR, ALR, args[0], args[4]);
1956 tcg_out_insn(s, RRE, ALCR, args[1], args[5]);
1957 break;
1958 case INDEX_op_sub2_i32:
1959 if (const_args[4]) {
1960 tcg_out_insn(s, RIL, SLFI, args[0], args[4]);
1961 } else {
1962 tcg_out_insn(s, RR, SLR, args[0], args[4]);
1964 tcg_out_insn(s, RRE, SLBR, args[1], args[5]);
1965 break;
1967 case INDEX_op_br:
1968 tgen_branch(s, S390_CC_ALWAYS, arg_label(args[0]));
1969 break;
1971 case INDEX_op_brcond_i32:
1972 tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
1973 args[1], const_args[1], arg_label(args[3]));
1974 break;
1975 case INDEX_op_setcond_i32:
1976 tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
1977 args[2], const_args[2]);
1978 break;
1979 case INDEX_op_movcond_i32:
1980 tgen_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1],
1981 args[2], const_args[2], args[3]);
1982 break;
1984 case INDEX_op_qemu_ld_i32:
1985 /* ??? Technically we can use a non-extending instruction. */
1986 case INDEX_op_qemu_ld_i64:
1987 tcg_out_qemu_ld(s, args[0], args[1], args[2]);
1988 break;
1989 case INDEX_op_qemu_st_i32:
1990 case INDEX_op_qemu_st_i64:
1991 tcg_out_qemu_st(s, args[0], args[1], args[2]);
1992 break;
1994 case INDEX_op_ld16s_i64:
1995 tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
1996 break;
1997 case INDEX_op_ld32u_i64:
1998 tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
1999 break;
2000 case INDEX_op_ld32s_i64:
2001 tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
2002 break;
2003 case INDEX_op_ld_i64:
2004 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2005 break;
2007 case INDEX_op_st32_i64:
2008 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
2009 break;
2010 case INDEX_op_st_i64:
2011 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2012 break;
2014 case INDEX_op_add_i64:
2015 a0 = args[0], a1 = args[1], a2 = args[2];
2016 if (const_args[2]) {
2017 do_addi_64:
2018 if (a0 == a1) {
2019 if (a2 == (int16_t)a2) {
2020 tcg_out_insn(s, RI, AGHI, a0, a2);
2021 break;
2023 if (s390_facilities & FACILITY_EXT_IMM) {
2024 if (a2 == (int32_t)a2) {
2025 tcg_out_insn(s, RIL, AGFI, a0, a2);
2026 break;
2027 } else if (a2 == (uint32_t)a2) {
2028 tcg_out_insn(s, RIL, ALGFI, a0, a2);
2029 break;
2030 } else if (-a2 == (uint32_t)-a2) {
2031 tcg_out_insn(s, RIL, SLGFI, a0, -a2);
2032 break;
2036 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
2037 } else if (a0 == a1) {
2038 tcg_out_insn(s, RRE, AGR, a0, a2);
2039 } else {
2040 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
2042 break;
2043 case INDEX_op_sub_i64:
2044 a0 = args[0], a1 = args[1], a2 = args[2];
2045 if (const_args[2]) {
2046 a2 = -a2;
2047 goto do_addi_64;
2048 } else {
2049 tcg_out_insn(s, RRE, SGR, args[0], args[2]);
2051 break;
2053 case INDEX_op_and_i64:
2054 if (const_args[2]) {
2055 tgen_andi(s, TCG_TYPE_I64, args[0], args[2]);
2056 } else {
2057 tcg_out_insn(s, RRE, NGR, args[0], args[2]);
2059 break;
2060 case INDEX_op_or_i64:
2061 if (const_args[2]) {
2062 tgen64_ori(s, args[0], args[2]);
2063 } else {
2064 tcg_out_insn(s, RRE, OGR, args[0], args[2]);
2066 break;
2067 case INDEX_op_xor_i64:
2068 if (const_args[2]) {
2069 tgen64_xori(s, args[0], args[2]);
2070 } else {
2071 tcg_out_insn(s, RRE, XGR, args[0], args[2]);
2073 break;
2075 case INDEX_op_neg_i64:
2076 tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
2077 break;
2078 case INDEX_op_bswap64_i64:
2079 tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
2080 break;
2082 case INDEX_op_mul_i64:
2083 if (const_args[2]) {
2084 if (args[2] == (int16_t)args[2]) {
2085 tcg_out_insn(s, RI, MGHI, args[0], args[2]);
2086 } else {
2087 tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
2089 } else {
2090 tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
2092 break;
2094 case INDEX_op_div2_i64:
2095 /* ??? We get an unnecessary sign-extension of the dividend
2096 into R3 with this definition, but as we do in fact always
2097 produce both quotient and remainder using INDEX_op_div_i64
2098 instead requires jumping through even more hoops. */
2099 tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
2100 break;
2101 case INDEX_op_divu2_i64:
2102 tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
2103 break;
2104 case INDEX_op_mulu2_i64:
2105 tcg_out_insn(s, RRE, MLGR, TCG_REG_R2, args[3]);
2106 break;
2108 case INDEX_op_shl_i64:
2109 op = RSY_SLLG;
2110 do_shift64:
2111 if (const_args[2]) {
2112 tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
2113 } else {
2114 tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
2116 break;
2117 case INDEX_op_shr_i64:
2118 op = RSY_SRLG;
2119 goto do_shift64;
2120 case INDEX_op_sar_i64:
2121 op = RSY_SRAG;
2122 goto do_shift64;
2124 case INDEX_op_rotl_i64:
2125 if (const_args[2]) {
2126 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2127 TCG_REG_NONE, args[2]);
2128 } else {
2129 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
2131 break;
2132 case INDEX_op_rotr_i64:
2133 if (const_args[2]) {
2134 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2135 TCG_REG_NONE, (64 - args[2]) & 63);
2136 } else {
2137 /* We can use the smaller 32-bit negate because only the
2138 low 6 bits are examined for the rotate. */
2139 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2140 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
2142 break;
2144 case INDEX_op_ext8s_i64:
2145 tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
2146 break;
2147 case INDEX_op_ext16s_i64:
2148 tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
2149 break;
2150 case INDEX_op_ext_i32_i64:
2151 case INDEX_op_ext32s_i64:
2152 tgen_ext32s(s, args[0], args[1]);
2153 break;
2154 case INDEX_op_ext8u_i64:
2155 tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
2156 break;
2157 case INDEX_op_ext16u_i64:
2158 tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
2159 break;
2160 case INDEX_op_extu_i32_i64:
2161 case INDEX_op_ext32u_i64:
2162 tgen_ext32u(s, args[0], args[1]);
2163 break;
2165 case INDEX_op_add2_i64:
2166 if (const_args[4]) {
2167 if ((int64_t)args[4] >= 0) {
2168 tcg_out_insn(s, RIL, ALGFI, args[0], args[4]);
2169 } else {
2170 tcg_out_insn(s, RIL, SLGFI, args[0], -args[4]);
2172 } else {
2173 tcg_out_insn(s, RRE, ALGR, args[0], args[4]);
2175 tcg_out_insn(s, RRE, ALCGR, args[1], args[5]);
2176 break;
2177 case INDEX_op_sub2_i64:
2178 if (const_args[4]) {
2179 if ((int64_t)args[4] >= 0) {
2180 tcg_out_insn(s, RIL, SLGFI, args[0], args[4]);
2181 } else {
2182 tcg_out_insn(s, RIL, ALGFI, args[0], -args[4]);
2184 } else {
2185 tcg_out_insn(s, RRE, SLGR, args[0], args[4]);
2187 tcg_out_insn(s, RRE, SLBGR, args[1], args[5]);
2188 break;
2190 case INDEX_op_brcond_i64:
2191 tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
2192 args[1], const_args[1], arg_label(args[3]));
2193 break;
2194 case INDEX_op_setcond_i64:
2195 tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2196 args[2], const_args[2]);
2197 break;
2198 case INDEX_op_movcond_i64:
2199 tgen_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1],
2200 args[2], const_args[2], args[3]);
2201 break;
2203 OP_32_64(deposit):
2204 a0 = args[0], a1 = args[1], a2 = args[2];
2205 if (const_args[1]) {
2206 tgen_deposit(s, a0, a2, args[3], args[4], 1);
2207 } else {
2208 /* Since we can't support "0Z" as a constraint, we allow a1 in
2209 any register. Fix things up as if a matching constraint. */
2210 if (a0 != a1) {
2211 TCGType type = (opc == INDEX_op_deposit_i64);
2212 if (a0 == a2) {
2213 tcg_out_mov(s, type, TCG_TMP0, a2);
2214 a2 = TCG_TMP0;
2216 tcg_out_mov(s, type, a0, a1);
2218 tgen_deposit(s, a0, a2, args[3], args[4], 0);
2220 break;
2222 OP_32_64(extract):
2223 tgen_extract(s, args[0], args[1], args[2], args[3]);
2224 break;
2226 case INDEX_op_clz_i64:
2227 tgen_clz(s, args[0], args[1], args[2], const_args[2]);
2228 break;
2230 case INDEX_op_mb:
2231 /* The host memory model is quite strong, we simply need to
2232 serialize the instruction stream. */
2233 if (args[0] & TCG_MO_ST_LD) {
2234 tcg_out_insn(s, RR, BCR,
2235 s390_facilities & FACILITY_FAST_BCR_SER ? 14 : 15, 0);
2237 break;
2239 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
2240 case INDEX_op_mov_i64:
2241 case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
2242 case INDEX_op_movi_i64:
2243 case INDEX_op_call: /* Always emitted via tcg_out_call. */
2244 default:
2245 tcg_abort();
2249 static const TCGTargetOpDef s390_op_defs[] = {
2250 { INDEX_op_exit_tb, { } },
2251 { INDEX_op_goto_tb, { } },
2252 { INDEX_op_br, { } },
2253 { INDEX_op_goto_ptr, { "r" } },
2255 { INDEX_op_ld8u_i32, { "r", "r" } },
2256 { INDEX_op_ld8s_i32, { "r", "r" } },
2257 { INDEX_op_ld16u_i32, { "r", "r" } },
2258 { INDEX_op_ld16s_i32, { "r", "r" } },
2259 { INDEX_op_ld_i32, { "r", "r" } },
2260 { INDEX_op_st8_i32, { "r", "r" } },
2261 { INDEX_op_st16_i32, { "r", "r" } },
2262 { INDEX_op_st_i32, { "r", "r" } },
2264 { INDEX_op_add_i32, { "r", "r", "ri" } },
2265 { INDEX_op_sub_i32, { "r", "0", "ri" } },
2266 { INDEX_op_mul_i32, { "r", "0", "rK" } },
2268 { INDEX_op_div2_i32, { "b", "a", "0", "1", "r" } },
2269 { INDEX_op_divu2_i32, { "b", "a", "0", "1", "r" } },
2271 { INDEX_op_and_i32, { "r", "0", "ri" } },
2272 { INDEX_op_or_i32, { "r", "0", "rO" } },
2273 { INDEX_op_xor_i32, { "r", "0", "rX" } },
2275 { INDEX_op_neg_i32, { "r", "r" } },
2277 { INDEX_op_shl_i32, { "r", "0", "ri" } },
2278 { INDEX_op_shr_i32, { "r", "0", "ri" } },
2279 { INDEX_op_sar_i32, { "r", "0", "ri" } },
2281 { INDEX_op_rotl_i32, { "r", "r", "ri" } },
2282 { INDEX_op_rotr_i32, { "r", "r", "ri" } },
2284 { INDEX_op_ext8s_i32, { "r", "r" } },
2285 { INDEX_op_ext8u_i32, { "r", "r" } },
2286 { INDEX_op_ext16s_i32, { "r", "r" } },
2287 { INDEX_op_ext16u_i32, { "r", "r" } },
2289 { INDEX_op_bswap16_i32, { "r", "r" } },
2290 { INDEX_op_bswap32_i32, { "r", "r" } },
2292 { INDEX_op_add2_i32, { "r", "r", "0", "1", "rA", "r" } },
2293 { INDEX_op_sub2_i32, { "r", "r", "0", "1", "rA", "r" } },
2295 { INDEX_op_brcond_i32, { "r", "rC" } },
2296 { INDEX_op_setcond_i32, { "r", "r", "rC" } },
2297 { INDEX_op_movcond_i32, { "r", "r", "rC", "r", "0" } },
2298 { INDEX_op_deposit_i32, { "r", "rZ", "r" } },
2299 { INDEX_op_extract_i32, { "r", "r" } },
2301 { INDEX_op_qemu_ld_i32, { "r", "L" } },
2302 { INDEX_op_qemu_ld_i64, { "r", "L" } },
2303 { INDEX_op_qemu_st_i32, { "L", "L" } },
2304 { INDEX_op_qemu_st_i64, { "L", "L" } },
2306 { INDEX_op_ld8u_i64, { "r", "r" } },
2307 { INDEX_op_ld8s_i64, { "r", "r" } },
2308 { INDEX_op_ld16u_i64, { "r", "r" } },
2309 { INDEX_op_ld16s_i64, { "r", "r" } },
2310 { INDEX_op_ld32u_i64, { "r", "r" } },
2311 { INDEX_op_ld32s_i64, { "r", "r" } },
2312 { INDEX_op_ld_i64, { "r", "r" } },
2314 { INDEX_op_st8_i64, { "r", "r" } },
2315 { INDEX_op_st16_i64, { "r", "r" } },
2316 { INDEX_op_st32_i64, { "r", "r" } },
2317 { INDEX_op_st_i64, { "r", "r" } },
2319 { INDEX_op_add_i64, { "r", "r", "ri" } },
2320 { INDEX_op_sub_i64, { "r", "0", "ri" } },
2321 { INDEX_op_mul_i64, { "r", "0", "rK" } },
2323 { INDEX_op_div2_i64, { "b", "a", "0", "1", "r" } },
2324 { INDEX_op_divu2_i64, { "b", "a", "0", "1", "r" } },
2325 { INDEX_op_mulu2_i64, { "b", "a", "0", "r" } },
2327 { INDEX_op_and_i64, { "r", "0", "ri" } },
2328 { INDEX_op_or_i64, { "r", "0", "rO" } },
2329 { INDEX_op_xor_i64, { "r", "0", "rX" } },
2331 { INDEX_op_neg_i64, { "r", "r" } },
2333 { INDEX_op_shl_i64, { "r", "r", "ri" } },
2334 { INDEX_op_shr_i64, { "r", "r", "ri" } },
2335 { INDEX_op_sar_i64, { "r", "r", "ri" } },
2337 { INDEX_op_rotl_i64, { "r", "r", "ri" } },
2338 { INDEX_op_rotr_i64, { "r", "r", "ri" } },
2340 { INDEX_op_ext8s_i64, { "r", "r" } },
2341 { INDEX_op_ext8u_i64, { "r", "r" } },
2342 { INDEX_op_ext16s_i64, { "r", "r" } },
2343 { INDEX_op_ext16u_i64, { "r", "r" } },
2344 { INDEX_op_ext32s_i64, { "r", "r" } },
2345 { INDEX_op_ext32u_i64, { "r", "r" } },
2347 { INDEX_op_ext_i32_i64, { "r", "r" } },
2348 { INDEX_op_extu_i32_i64, { "r", "r" } },
2350 { INDEX_op_bswap16_i64, { "r", "r" } },
2351 { INDEX_op_bswap32_i64, { "r", "r" } },
2352 { INDEX_op_bswap64_i64, { "r", "r" } },
2354 { INDEX_op_clz_i64, { "r", "r", "ri" } },
2356 { INDEX_op_add2_i64, { "r", "r", "0", "1", "rA", "r" } },
2357 { INDEX_op_sub2_i64, { "r", "r", "0", "1", "rA", "r" } },
2359 { INDEX_op_brcond_i64, { "r", "rC" } },
2360 { INDEX_op_setcond_i64, { "r", "r", "rC" } },
2361 { INDEX_op_movcond_i64, { "r", "r", "rC", "r", "0" } },
2362 { INDEX_op_deposit_i64, { "r", "0", "r" } },
2363 { INDEX_op_extract_i64, { "r", "r" } },
2365 { INDEX_op_mb, { } },
2366 { -1 },
2369 static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
2371 int i, n = ARRAY_SIZE(s390_op_defs);
2373 for (i = 0; i < n; ++i) {
2374 if (s390_op_defs[i].op == op) {
2375 return &s390_op_defs[i];
2378 return NULL;
2381 static void query_s390_facilities(void)
2383 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2385 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
2386 is present on all 64-bit systems, but let's check for it anyway. */
2387 if (hwcap & HWCAP_S390_STFLE) {
2388 register int r0 __asm__("0");
2389 register void *r1 __asm__("1");
2391 /* stfle 0(%r1) */
2392 r1 = &s390_facilities;
2393 asm volatile(".word 0xb2b0,0x1000"
2394 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
2398 static void tcg_target_init(TCGContext *s)
2400 query_s390_facilities();
2402 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
2403 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
2405 tcg_regset_clear(tcg_target_call_clobber_regs);
2406 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2407 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
2408 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2409 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2410 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
2411 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
2412 /* The r6 register is technically call-saved, but it's also a parameter
2413 register, so it can get killed by setup for the qemu_st helper. */
2414 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6);
2415 /* The return register can be considered call-clobbered. */
2416 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2418 tcg_regset_clear(s->reserved_regs);
2419 tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
2420 /* XXX many insns can't be used with R0, so we better avoid it for now */
2421 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
2422 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2425 #define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
2426 + TCG_STATIC_CALL_ARGS_SIZE \
2427 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
2429 static void tcg_target_qemu_prologue(TCGContext *s)
2431 /* stmg %r6,%r15,48(%r15) (save registers) */
2432 tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
2434 /* aghi %r15,-frame_size */
2435 tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -FRAME_SIZE);
2437 tcg_set_frame(s, TCG_REG_CALL_STACK,
2438 TCG_STATIC_CALL_ARGS_SIZE + TCG_TARGET_CALL_STACK_OFFSET,
2439 CPU_TEMP_BUF_NLONGS * sizeof(long));
2441 #ifndef CONFIG_SOFTMMU
2442 if (guest_base >= 0x80000) {
2443 tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base);
2444 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2446 #endif
2448 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2449 /* br %r3 (go to TB) */
2450 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
2453 * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2454 * and fall through to the rest of the epilogue.
2456 s->code_gen_epilogue = s->code_ptr;
2457 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, 0);
2459 /* TB epilogue */
2460 tb_ret_addr = s->code_ptr;
2462 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2463 tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15,
2464 FRAME_SIZE + 48);
2466 /* br %r14 (return) */
2467 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
2470 typedef struct {
2471 DebugFrameHeader h;
2472 uint8_t fde_def_cfa[4];
2473 uint8_t fde_reg_ofs[18];
2474 } DebugFrame;
2476 /* We're expecting a 2 byte uleb128 encoded value. */
2477 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2479 #define ELF_HOST_MACHINE EM_S390
2481 static const DebugFrame debug_frame = {
2482 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2483 .h.cie.id = -1,
2484 .h.cie.version = 1,
2485 .h.cie.code_align = 1,
2486 .h.cie.data_align = 8, /* sleb128 8 */
2487 .h.cie.return_column = TCG_REG_R14,
2489 /* Total FDE size does not include the "len" member. */
2490 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
2492 .fde_def_cfa = {
2493 12, TCG_REG_CALL_STACK, /* DW_CFA_def_cfa %r15, ... */
2494 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2495 (FRAME_SIZE >> 7)
2497 .fde_reg_ofs = {
2498 0x86, 6, /* DW_CFA_offset, %r6, 48 */
2499 0x87, 7, /* DW_CFA_offset, %r7, 56 */
2500 0x88, 8, /* DW_CFA_offset, %r8, 64 */
2501 0x89, 9, /* DW_CFA_offset, %r92, 72 */
2502 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
2503 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
2504 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
2505 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
2506 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
2510 void tcg_register_jit(void *buf, size_t buf_size)
2512 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));