target/s390x: Fix typo
[qemu/ar7.git] / tcg / s390 / tcg-target.inc.c
bloba679280b92a022affcd76841d030c662bf212303
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 /* return value */
1745 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, args[0]);
1746 tgen_gotoi(s, S390_CC_ALWAYS, tb_ret_addr);
1747 break;
1749 case INDEX_op_goto_tb:
1750 if (s->tb_jmp_insn_offset) {
1751 /* branch displacement must be aligned for atomic patching;
1752 * see if we need to add extra nop before branch
1754 if (!QEMU_PTR_IS_ALIGNED(s->code_ptr + 1, 4)) {
1755 tcg_out16(s, NOP);
1757 tcg_out16(s, RIL_BRCL | (S390_CC_ALWAYS << 4));
1758 s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
1759 s->code_ptr += 2;
1760 } else {
1761 /* load address stored at s->tb_jmp_target_addr + args[0] */
1762 tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_TMP0,
1763 s->tb_jmp_target_addr + args[0]);
1764 /* and go there */
1765 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_TMP0);
1767 s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
1768 break;
1770 OP_32_64(ld8u):
1771 /* ??? LLC (RXY format) is only present with the extended-immediate
1772 facility, whereas LLGC is always present. */
1773 tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
1774 break;
1776 OP_32_64(ld8s):
1777 /* ??? LB is no smaller than LGB, so no point to using it. */
1778 tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
1779 break;
1781 OP_32_64(ld16u):
1782 /* ??? LLH (RXY format) is only present with the extended-immediate
1783 facility, whereas LLGH is always present. */
1784 tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
1785 break;
1787 case INDEX_op_ld16s_i32:
1788 tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
1789 break;
1791 case INDEX_op_ld_i32:
1792 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1793 break;
1795 OP_32_64(st8):
1796 tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
1797 TCG_REG_NONE, args[2]);
1798 break;
1800 OP_32_64(st16):
1801 tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
1802 TCG_REG_NONE, args[2]);
1803 break;
1805 case INDEX_op_st_i32:
1806 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1807 break;
1809 case INDEX_op_add_i32:
1810 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1811 if (const_args[2]) {
1812 do_addi_32:
1813 if (a0 == a1) {
1814 if (a2 == (int16_t)a2) {
1815 tcg_out_insn(s, RI, AHI, a0, a2);
1816 break;
1818 if (s390_facilities & FACILITY_EXT_IMM) {
1819 tcg_out_insn(s, RIL, AFI, a0, a2);
1820 break;
1823 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
1824 } else if (a0 == a1) {
1825 tcg_out_insn(s, RR, AR, a0, a2);
1826 } else {
1827 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
1829 break;
1830 case INDEX_op_sub_i32:
1831 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1832 if (const_args[2]) {
1833 a2 = -a2;
1834 goto do_addi_32;
1836 tcg_out_insn(s, RR, SR, args[0], args[2]);
1837 break;
1839 case INDEX_op_and_i32:
1840 if (const_args[2]) {
1841 tgen_andi(s, TCG_TYPE_I32, args[0], args[2]);
1842 } else {
1843 tcg_out_insn(s, RR, NR, args[0], args[2]);
1845 break;
1846 case INDEX_op_or_i32:
1847 if (const_args[2]) {
1848 tgen64_ori(s, args[0], args[2] & 0xffffffff);
1849 } else {
1850 tcg_out_insn(s, RR, OR, args[0], args[2]);
1852 break;
1853 case INDEX_op_xor_i32:
1854 if (const_args[2]) {
1855 tgen64_xori(s, args[0], args[2] & 0xffffffff);
1856 } else {
1857 tcg_out_insn(s, RR, XR, args[0], args[2]);
1859 break;
1861 case INDEX_op_neg_i32:
1862 tcg_out_insn(s, RR, LCR, args[0], args[1]);
1863 break;
1865 case INDEX_op_mul_i32:
1866 if (const_args[2]) {
1867 if ((int32_t)args[2] == (int16_t)args[2]) {
1868 tcg_out_insn(s, RI, MHI, args[0], args[2]);
1869 } else {
1870 tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
1872 } else {
1873 tcg_out_insn(s, RRE, MSR, args[0], args[2]);
1875 break;
1877 case INDEX_op_div2_i32:
1878 tcg_out_insn(s, RR, DR, TCG_REG_R2, args[4]);
1879 break;
1880 case INDEX_op_divu2_i32:
1881 tcg_out_insn(s, RRE, DLR, TCG_REG_R2, args[4]);
1882 break;
1884 case INDEX_op_shl_i32:
1885 op = RS_SLL;
1886 do_shift32:
1887 if (const_args[2]) {
1888 tcg_out_sh32(s, op, args[0], TCG_REG_NONE, args[2]);
1889 } else {
1890 tcg_out_sh32(s, op, args[0], args[2], 0);
1892 break;
1893 case INDEX_op_shr_i32:
1894 op = RS_SRL;
1895 goto do_shift32;
1896 case INDEX_op_sar_i32:
1897 op = RS_SRA;
1898 goto do_shift32;
1900 case INDEX_op_rotl_i32:
1901 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1902 if (const_args[2]) {
1903 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
1904 } else {
1905 tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
1907 break;
1908 case INDEX_op_rotr_i32:
1909 if (const_args[2]) {
1910 tcg_out_sh64(s, RSY_RLL, args[0], args[1],
1911 TCG_REG_NONE, (32 - args[2]) & 31);
1912 } else {
1913 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
1914 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
1916 break;
1918 case INDEX_op_ext8s_i32:
1919 tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
1920 break;
1921 case INDEX_op_ext16s_i32:
1922 tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
1923 break;
1924 case INDEX_op_ext8u_i32:
1925 tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
1926 break;
1927 case INDEX_op_ext16u_i32:
1928 tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
1929 break;
1931 OP_32_64(bswap16):
1932 /* The TCG bswap definition requires bits 0-47 already be zero.
1933 Thus we don't need the G-type insns to implement bswap16_i64. */
1934 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1935 tcg_out_sh32(s, RS_SRL, args[0], TCG_REG_NONE, 16);
1936 break;
1937 OP_32_64(bswap32):
1938 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1939 break;
1941 case INDEX_op_add2_i32:
1942 if (const_args[4]) {
1943 tcg_out_insn(s, RIL, ALFI, args[0], args[4]);
1944 } else {
1945 tcg_out_insn(s, RR, ALR, args[0], args[4]);
1947 tcg_out_insn(s, RRE, ALCR, args[1], args[5]);
1948 break;
1949 case INDEX_op_sub2_i32:
1950 if (const_args[4]) {
1951 tcg_out_insn(s, RIL, SLFI, args[0], args[4]);
1952 } else {
1953 tcg_out_insn(s, RR, SLR, args[0], args[4]);
1955 tcg_out_insn(s, RRE, SLBR, args[1], args[5]);
1956 break;
1958 case INDEX_op_br:
1959 tgen_branch(s, S390_CC_ALWAYS, arg_label(args[0]));
1960 break;
1962 case INDEX_op_brcond_i32:
1963 tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
1964 args[1], const_args[1], arg_label(args[3]));
1965 break;
1966 case INDEX_op_setcond_i32:
1967 tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
1968 args[2], const_args[2]);
1969 break;
1970 case INDEX_op_movcond_i32:
1971 tgen_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1],
1972 args[2], const_args[2], args[3]);
1973 break;
1975 case INDEX_op_qemu_ld_i32:
1976 /* ??? Technically we can use a non-extending instruction. */
1977 case INDEX_op_qemu_ld_i64:
1978 tcg_out_qemu_ld(s, args[0], args[1], args[2]);
1979 break;
1980 case INDEX_op_qemu_st_i32:
1981 case INDEX_op_qemu_st_i64:
1982 tcg_out_qemu_st(s, args[0], args[1], args[2]);
1983 break;
1985 case INDEX_op_ld16s_i64:
1986 tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
1987 break;
1988 case INDEX_op_ld32u_i64:
1989 tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
1990 break;
1991 case INDEX_op_ld32s_i64:
1992 tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
1993 break;
1994 case INDEX_op_ld_i64:
1995 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1996 break;
1998 case INDEX_op_st32_i64:
1999 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
2000 break;
2001 case INDEX_op_st_i64:
2002 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2003 break;
2005 case INDEX_op_add_i64:
2006 a0 = args[0], a1 = args[1], a2 = args[2];
2007 if (const_args[2]) {
2008 do_addi_64:
2009 if (a0 == a1) {
2010 if (a2 == (int16_t)a2) {
2011 tcg_out_insn(s, RI, AGHI, a0, a2);
2012 break;
2014 if (s390_facilities & FACILITY_EXT_IMM) {
2015 if (a2 == (int32_t)a2) {
2016 tcg_out_insn(s, RIL, AGFI, a0, a2);
2017 break;
2018 } else if (a2 == (uint32_t)a2) {
2019 tcg_out_insn(s, RIL, ALGFI, a0, a2);
2020 break;
2021 } else if (-a2 == (uint32_t)-a2) {
2022 tcg_out_insn(s, RIL, SLGFI, a0, -a2);
2023 break;
2027 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
2028 } else if (a0 == a1) {
2029 tcg_out_insn(s, RRE, AGR, a0, a2);
2030 } else {
2031 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
2033 break;
2034 case INDEX_op_sub_i64:
2035 a0 = args[0], a1 = args[1], a2 = args[2];
2036 if (const_args[2]) {
2037 a2 = -a2;
2038 goto do_addi_64;
2039 } else {
2040 tcg_out_insn(s, RRE, SGR, args[0], args[2]);
2042 break;
2044 case INDEX_op_and_i64:
2045 if (const_args[2]) {
2046 tgen_andi(s, TCG_TYPE_I64, args[0], args[2]);
2047 } else {
2048 tcg_out_insn(s, RRE, NGR, args[0], args[2]);
2050 break;
2051 case INDEX_op_or_i64:
2052 if (const_args[2]) {
2053 tgen64_ori(s, args[0], args[2]);
2054 } else {
2055 tcg_out_insn(s, RRE, OGR, args[0], args[2]);
2057 break;
2058 case INDEX_op_xor_i64:
2059 if (const_args[2]) {
2060 tgen64_xori(s, args[0], args[2]);
2061 } else {
2062 tcg_out_insn(s, RRE, XGR, args[0], args[2]);
2064 break;
2066 case INDEX_op_neg_i64:
2067 tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
2068 break;
2069 case INDEX_op_bswap64_i64:
2070 tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
2071 break;
2073 case INDEX_op_mul_i64:
2074 if (const_args[2]) {
2075 if (args[2] == (int16_t)args[2]) {
2076 tcg_out_insn(s, RI, MGHI, args[0], args[2]);
2077 } else {
2078 tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
2080 } else {
2081 tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
2083 break;
2085 case INDEX_op_div2_i64:
2086 /* ??? We get an unnecessary sign-extension of the dividend
2087 into R3 with this definition, but as we do in fact always
2088 produce both quotient and remainder using INDEX_op_div_i64
2089 instead requires jumping through even more hoops. */
2090 tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
2091 break;
2092 case INDEX_op_divu2_i64:
2093 tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
2094 break;
2095 case INDEX_op_mulu2_i64:
2096 tcg_out_insn(s, RRE, MLGR, TCG_REG_R2, args[3]);
2097 break;
2099 case INDEX_op_shl_i64:
2100 op = RSY_SLLG;
2101 do_shift64:
2102 if (const_args[2]) {
2103 tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
2104 } else {
2105 tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
2107 break;
2108 case INDEX_op_shr_i64:
2109 op = RSY_SRLG;
2110 goto do_shift64;
2111 case INDEX_op_sar_i64:
2112 op = RSY_SRAG;
2113 goto do_shift64;
2115 case INDEX_op_rotl_i64:
2116 if (const_args[2]) {
2117 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2118 TCG_REG_NONE, args[2]);
2119 } else {
2120 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
2122 break;
2123 case INDEX_op_rotr_i64:
2124 if (const_args[2]) {
2125 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2126 TCG_REG_NONE, (64 - args[2]) & 63);
2127 } else {
2128 /* We can use the smaller 32-bit negate because only the
2129 low 6 bits are examined for the rotate. */
2130 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2131 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
2133 break;
2135 case INDEX_op_ext8s_i64:
2136 tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
2137 break;
2138 case INDEX_op_ext16s_i64:
2139 tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
2140 break;
2141 case INDEX_op_ext_i32_i64:
2142 case INDEX_op_ext32s_i64:
2143 tgen_ext32s(s, args[0], args[1]);
2144 break;
2145 case INDEX_op_ext8u_i64:
2146 tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
2147 break;
2148 case INDEX_op_ext16u_i64:
2149 tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
2150 break;
2151 case INDEX_op_extu_i32_i64:
2152 case INDEX_op_ext32u_i64:
2153 tgen_ext32u(s, args[0], args[1]);
2154 break;
2156 case INDEX_op_add2_i64:
2157 if (const_args[4]) {
2158 if ((int64_t)args[4] >= 0) {
2159 tcg_out_insn(s, RIL, ALGFI, args[0], args[4]);
2160 } else {
2161 tcg_out_insn(s, RIL, SLGFI, args[0], -args[4]);
2163 } else {
2164 tcg_out_insn(s, RRE, ALGR, args[0], args[4]);
2166 tcg_out_insn(s, RRE, ALCGR, args[1], args[5]);
2167 break;
2168 case INDEX_op_sub2_i64:
2169 if (const_args[4]) {
2170 if ((int64_t)args[4] >= 0) {
2171 tcg_out_insn(s, RIL, SLGFI, args[0], args[4]);
2172 } else {
2173 tcg_out_insn(s, RIL, ALGFI, args[0], -args[4]);
2175 } else {
2176 tcg_out_insn(s, RRE, SLGR, args[0], args[4]);
2178 tcg_out_insn(s, RRE, SLBGR, args[1], args[5]);
2179 break;
2181 case INDEX_op_brcond_i64:
2182 tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
2183 args[1], const_args[1], arg_label(args[3]));
2184 break;
2185 case INDEX_op_setcond_i64:
2186 tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2187 args[2], const_args[2]);
2188 break;
2189 case INDEX_op_movcond_i64:
2190 tgen_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1],
2191 args[2], const_args[2], args[3]);
2192 break;
2194 OP_32_64(deposit):
2195 a0 = args[0], a1 = args[1], a2 = args[2];
2196 if (const_args[1]) {
2197 tgen_deposit(s, a0, a2, args[3], args[4], 1);
2198 } else {
2199 /* Since we can't support "0Z" as a constraint, we allow a1 in
2200 any register. Fix things up as if a matching constraint. */
2201 if (a0 != a1) {
2202 TCGType type = (opc == INDEX_op_deposit_i64);
2203 if (a0 == a2) {
2204 tcg_out_mov(s, type, TCG_TMP0, a2);
2205 a2 = TCG_TMP0;
2207 tcg_out_mov(s, type, a0, a1);
2209 tgen_deposit(s, a0, a2, args[3], args[4], 0);
2211 break;
2213 OP_32_64(extract):
2214 tgen_extract(s, args[0], args[1], args[2], args[3]);
2215 break;
2217 case INDEX_op_clz_i64:
2218 tgen_clz(s, args[0], args[1], args[2], const_args[2]);
2219 break;
2221 case INDEX_op_mb:
2222 /* The host memory model is quite strong, we simply need to
2223 serialize the instruction stream. */
2224 if (args[0] & TCG_MO_ST_LD) {
2225 tcg_out_insn(s, RR, BCR,
2226 s390_facilities & FACILITY_FAST_BCR_SER ? 14 : 15, 0);
2228 break;
2230 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
2231 case INDEX_op_mov_i64:
2232 case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
2233 case INDEX_op_movi_i64:
2234 case INDEX_op_call: /* Always emitted via tcg_out_call. */
2235 default:
2236 tcg_abort();
2240 static const TCGTargetOpDef s390_op_defs[] = {
2241 { INDEX_op_exit_tb, { } },
2242 { INDEX_op_goto_tb, { } },
2243 { INDEX_op_br, { } },
2245 { INDEX_op_ld8u_i32, { "r", "r" } },
2246 { INDEX_op_ld8s_i32, { "r", "r" } },
2247 { INDEX_op_ld16u_i32, { "r", "r" } },
2248 { INDEX_op_ld16s_i32, { "r", "r" } },
2249 { INDEX_op_ld_i32, { "r", "r" } },
2250 { INDEX_op_st8_i32, { "r", "r" } },
2251 { INDEX_op_st16_i32, { "r", "r" } },
2252 { INDEX_op_st_i32, { "r", "r" } },
2254 { INDEX_op_add_i32, { "r", "r", "ri" } },
2255 { INDEX_op_sub_i32, { "r", "0", "ri" } },
2256 { INDEX_op_mul_i32, { "r", "0", "rK" } },
2258 { INDEX_op_div2_i32, { "b", "a", "0", "1", "r" } },
2259 { INDEX_op_divu2_i32, { "b", "a", "0", "1", "r" } },
2261 { INDEX_op_and_i32, { "r", "0", "ri" } },
2262 { INDEX_op_or_i32, { "r", "0", "rO" } },
2263 { INDEX_op_xor_i32, { "r", "0", "rX" } },
2265 { INDEX_op_neg_i32, { "r", "r" } },
2267 { INDEX_op_shl_i32, { "r", "0", "ri" } },
2268 { INDEX_op_shr_i32, { "r", "0", "ri" } },
2269 { INDEX_op_sar_i32, { "r", "0", "ri" } },
2271 { INDEX_op_rotl_i32, { "r", "r", "ri" } },
2272 { INDEX_op_rotr_i32, { "r", "r", "ri" } },
2274 { INDEX_op_ext8s_i32, { "r", "r" } },
2275 { INDEX_op_ext8u_i32, { "r", "r" } },
2276 { INDEX_op_ext16s_i32, { "r", "r" } },
2277 { INDEX_op_ext16u_i32, { "r", "r" } },
2279 { INDEX_op_bswap16_i32, { "r", "r" } },
2280 { INDEX_op_bswap32_i32, { "r", "r" } },
2282 { INDEX_op_add2_i32, { "r", "r", "0", "1", "rA", "r" } },
2283 { INDEX_op_sub2_i32, { "r", "r", "0", "1", "rA", "r" } },
2285 { INDEX_op_brcond_i32, { "r", "rC" } },
2286 { INDEX_op_setcond_i32, { "r", "r", "rC" } },
2287 { INDEX_op_movcond_i32, { "r", "r", "rC", "r", "0" } },
2288 { INDEX_op_deposit_i32, { "r", "rZ", "r" } },
2289 { INDEX_op_extract_i32, { "r", "r" } },
2291 { INDEX_op_qemu_ld_i32, { "r", "L" } },
2292 { INDEX_op_qemu_ld_i64, { "r", "L" } },
2293 { INDEX_op_qemu_st_i32, { "L", "L" } },
2294 { INDEX_op_qemu_st_i64, { "L", "L" } },
2296 { INDEX_op_ld8u_i64, { "r", "r" } },
2297 { INDEX_op_ld8s_i64, { "r", "r" } },
2298 { INDEX_op_ld16u_i64, { "r", "r" } },
2299 { INDEX_op_ld16s_i64, { "r", "r" } },
2300 { INDEX_op_ld32u_i64, { "r", "r" } },
2301 { INDEX_op_ld32s_i64, { "r", "r" } },
2302 { INDEX_op_ld_i64, { "r", "r" } },
2304 { INDEX_op_st8_i64, { "r", "r" } },
2305 { INDEX_op_st16_i64, { "r", "r" } },
2306 { INDEX_op_st32_i64, { "r", "r" } },
2307 { INDEX_op_st_i64, { "r", "r" } },
2309 { INDEX_op_add_i64, { "r", "r", "ri" } },
2310 { INDEX_op_sub_i64, { "r", "0", "ri" } },
2311 { INDEX_op_mul_i64, { "r", "0", "rK" } },
2313 { INDEX_op_div2_i64, { "b", "a", "0", "1", "r" } },
2314 { INDEX_op_divu2_i64, { "b", "a", "0", "1", "r" } },
2315 { INDEX_op_mulu2_i64, { "b", "a", "0", "r" } },
2317 { INDEX_op_and_i64, { "r", "0", "ri" } },
2318 { INDEX_op_or_i64, { "r", "0", "rO" } },
2319 { INDEX_op_xor_i64, { "r", "0", "rX" } },
2321 { INDEX_op_neg_i64, { "r", "r" } },
2323 { INDEX_op_shl_i64, { "r", "r", "ri" } },
2324 { INDEX_op_shr_i64, { "r", "r", "ri" } },
2325 { INDEX_op_sar_i64, { "r", "r", "ri" } },
2327 { INDEX_op_rotl_i64, { "r", "r", "ri" } },
2328 { INDEX_op_rotr_i64, { "r", "r", "ri" } },
2330 { INDEX_op_ext8s_i64, { "r", "r" } },
2331 { INDEX_op_ext8u_i64, { "r", "r" } },
2332 { INDEX_op_ext16s_i64, { "r", "r" } },
2333 { INDEX_op_ext16u_i64, { "r", "r" } },
2334 { INDEX_op_ext32s_i64, { "r", "r" } },
2335 { INDEX_op_ext32u_i64, { "r", "r" } },
2337 { INDEX_op_ext_i32_i64, { "r", "r" } },
2338 { INDEX_op_extu_i32_i64, { "r", "r" } },
2340 { INDEX_op_bswap16_i64, { "r", "r" } },
2341 { INDEX_op_bswap32_i64, { "r", "r" } },
2342 { INDEX_op_bswap64_i64, { "r", "r" } },
2344 { INDEX_op_clz_i64, { "r", "r", "ri" } },
2346 { INDEX_op_add2_i64, { "r", "r", "0", "1", "rA", "r" } },
2347 { INDEX_op_sub2_i64, { "r", "r", "0", "1", "rA", "r" } },
2349 { INDEX_op_brcond_i64, { "r", "rC" } },
2350 { INDEX_op_setcond_i64, { "r", "r", "rC" } },
2351 { INDEX_op_movcond_i64, { "r", "r", "rC", "r", "0" } },
2352 { INDEX_op_deposit_i64, { "r", "0", "r" } },
2353 { INDEX_op_extract_i64, { "r", "r" } },
2355 { INDEX_op_mb, { } },
2356 { -1 },
2359 static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
2361 int i, n = ARRAY_SIZE(s390_op_defs);
2363 for (i = 0; i < n; ++i) {
2364 if (s390_op_defs[i].op == op) {
2365 return &s390_op_defs[i];
2368 return NULL;
2371 static void query_s390_facilities(void)
2373 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2375 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
2376 is present on all 64-bit systems, but let's check for it anyway. */
2377 if (hwcap & HWCAP_S390_STFLE) {
2378 register int r0 __asm__("0");
2379 register void *r1 __asm__("1");
2381 /* stfle 0(%r1) */
2382 r1 = &s390_facilities;
2383 asm volatile(".word 0xb2b0,0x1000"
2384 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
2388 static void tcg_target_init(TCGContext *s)
2390 query_s390_facilities();
2392 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
2393 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
2395 tcg_regset_clear(tcg_target_call_clobber_regs);
2396 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2397 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
2398 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2399 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2400 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
2401 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
2402 /* The r6 register is technically call-saved, but it's also a parameter
2403 register, so it can get killed by setup for the qemu_st helper. */
2404 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6);
2405 /* The return register can be considered call-clobbered. */
2406 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2408 tcg_regset_clear(s->reserved_regs);
2409 tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
2410 /* XXX many insns can't be used with R0, so we better avoid it for now */
2411 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
2412 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2415 #define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
2416 + TCG_STATIC_CALL_ARGS_SIZE \
2417 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
2419 static void tcg_target_qemu_prologue(TCGContext *s)
2421 /* stmg %r6,%r15,48(%r15) (save registers) */
2422 tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
2424 /* aghi %r15,-frame_size */
2425 tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -FRAME_SIZE);
2427 tcg_set_frame(s, TCG_REG_CALL_STACK,
2428 TCG_STATIC_CALL_ARGS_SIZE + TCG_TARGET_CALL_STACK_OFFSET,
2429 CPU_TEMP_BUF_NLONGS * sizeof(long));
2431 #ifndef CONFIG_SOFTMMU
2432 if (guest_base >= 0x80000) {
2433 tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base);
2434 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2436 #endif
2438 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2439 /* br %r3 (go to TB) */
2440 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
2442 tb_ret_addr = s->code_ptr;
2444 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2445 tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15,
2446 FRAME_SIZE + 48);
2448 /* br %r14 (return) */
2449 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
2452 typedef struct {
2453 DebugFrameHeader h;
2454 uint8_t fde_def_cfa[4];
2455 uint8_t fde_reg_ofs[18];
2456 } DebugFrame;
2458 /* We're expecting a 2 byte uleb128 encoded value. */
2459 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2461 #define ELF_HOST_MACHINE EM_S390
2463 static const DebugFrame debug_frame = {
2464 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2465 .h.cie.id = -1,
2466 .h.cie.version = 1,
2467 .h.cie.code_align = 1,
2468 .h.cie.data_align = 8, /* sleb128 8 */
2469 .h.cie.return_column = TCG_REG_R14,
2471 /* Total FDE size does not include the "len" member. */
2472 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
2474 .fde_def_cfa = {
2475 12, TCG_REG_CALL_STACK, /* DW_CFA_def_cfa %r15, ... */
2476 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2477 (FRAME_SIZE >> 7)
2479 .fde_reg_ofs = {
2480 0x86, 6, /* DW_CFA_offset, %r6, 48 */
2481 0x87, 7, /* DW_CFA_offset, %r7, 56 */
2482 0x88, 8, /* DW_CFA_offset, %r8, 64 */
2483 0x89, 9, /* DW_CFA_offset, %r92, 72 */
2484 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
2485 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
2486 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
2487 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
2488 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
2492 void tcg_register_jit(void *buf, size_t buf_size)
2494 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));