cpu: Avoid QOM casts for CPU()
[qemu/ar7.git] / tcg / s390 / tcg-target.c
blob907d9d17446712cee68fc6258d4033c20c5dd926
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-null.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_32 0x0100
42 #define TCG_CT_CONST_MULI 0x0800
43 #define TCG_CT_CONST_ORI 0x2000
44 #define TCG_CT_CONST_XORI 0x4000
45 #define TCG_CT_CONST_CMPI 0x8000
47 /* Several places within the instruction set 0 means "no register"
48 rather than TCG_REG_R0. */
49 #define TCG_REG_NONE 0
51 /* A scratch register that may be be used throughout the backend. */
52 #define TCG_TMP0 TCG_REG_R14
54 #ifdef CONFIG_USE_GUEST_BASE
55 #define TCG_GUEST_BASE_REG TCG_REG_R13
56 #else
57 #define TCG_GUEST_BASE_REG TCG_REG_R0
58 #endif
60 #ifndef GUEST_BASE
61 #define GUEST_BASE 0
62 #endif
65 /* All of the following instructions are prefixed with their instruction
66 format, and are defined as 8- or 16-bit quantities, even when the two
67 halves of the 16-bit quantity may appear 32 bits apart in the insn.
68 This makes it easy to copy the values from the tables in Appendix B. */
69 typedef enum S390Opcode {
70 RIL_AFI = 0xc209,
71 RIL_AGFI = 0xc208,
72 RIL_ALFI = 0xc20b,
73 RIL_ALGFI = 0xc20a,
74 RIL_BRASL = 0xc005,
75 RIL_BRCL = 0xc004,
76 RIL_CFI = 0xc20d,
77 RIL_CGFI = 0xc20c,
78 RIL_CLFI = 0xc20f,
79 RIL_CLGFI = 0xc20e,
80 RIL_IIHF = 0xc008,
81 RIL_IILF = 0xc009,
82 RIL_LARL = 0xc000,
83 RIL_LGFI = 0xc001,
84 RIL_LGRL = 0xc408,
85 RIL_LLIHF = 0xc00e,
86 RIL_LLILF = 0xc00f,
87 RIL_LRL = 0xc40d,
88 RIL_MSFI = 0xc201,
89 RIL_MSGFI = 0xc200,
90 RIL_NIHF = 0xc00a,
91 RIL_NILF = 0xc00b,
92 RIL_OIHF = 0xc00c,
93 RIL_OILF = 0xc00d,
94 RIL_SLFI = 0xc205,
95 RIL_SLGFI = 0xc204,
96 RIL_XIHF = 0xc006,
97 RIL_XILF = 0xc007,
99 RI_AGHI = 0xa70b,
100 RI_AHI = 0xa70a,
101 RI_BRC = 0xa704,
102 RI_IIHH = 0xa500,
103 RI_IIHL = 0xa501,
104 RI_IILH = 0xa502,
105 RI_IILL = 0xa503,
106 RI_LGHI = 0xa709,
107 RI_LLIHH = 0xa50c,
108 RI_LLIHL = 0xa50d,
109 RI_LLILH = 0xa50e,
110 RI_LLILL = 0xa50f,
111 RI_MGHI = 0xa70d,
112 RI_MHI = 0xa70c,
113 RI_NIHH = 0xa504,
114 RI_NIHL = 0xa505,
115 RI_NILH = 0xa506,
116 RI_NILL = 0xa507,
117 RI_OIHH = 0xa508,
118 RI_OIHL = 0xa509,
119 RI_OILH = 0xa50a,
120 RI_OILL = 0xa50b,
122 RIE_CGIJ = 0xec7c,
123 RIE_CGRJ = 0xec64,
124 RIE_CIJ = 0xec7e,
125 RIE_CLGRJ = 0xec65,
126 RIE_CLIJ = 0xec7f,
127 RIE_CLGIJ = 0xec7d,
128 RIE_CLRJ = 0xec77,
129 RIE_CRJ = 0xec76,
130 RIE_RISBG = 0xec55,
132 RRE_AGR = 0xb908,
133 RRE_ALGR = 0xb90a,
134 RRE_ALCR = 0xb998,
135 RRE_ALCGR = 0xb988,
136 RRE_CGR = 0xb920,
137 RRE_CLGR = 0xb921,
138 RRE_DLGR = 0xb987,
139 RRE_DLR = 0xb997,
140 RRE_DSGFR = 0xb91d,
141 RRE_DSGR = 0xb90d,
142 RRE_LGBR = 0xb906,
143 RRE_LCGR = 0xb903,
144 RRE_LGFR = 0xb914,
145 RRE_LGHR = 0xb907,
146 RRE_LGR = 0xb904,
147 RRE_LLGCR = 0xb984,
148 RRE_LLGFR = 0xb916,
149 RRE_LLGHR = 0xb985,
150 RRE_LRVR = 0xb91f,
151 RRE_LRVGR = 0xb90f,
152 RRE_LTGR = 0xb902,
153 RRE_MLGR = 0xb986,
154 RRE_MSGR = 0xb90c,
155 RRE_MSR = 0xb252,
156 RRE_NGR = 0xb980,
157 RRE_OGR = 0xb981,
158 RRE_SGR = 0xb909,
159 RRE_SLGR = 0xb90b,
160 RRE_SLBR = 0xb999,
161 RRE_SLBGR = 0xb989,
162 RRE_XGR = 0xb982,
164 RRF_LOCR = 0xb9f2,
165 RRF_LOCGR = 0xb9e2,
167 RR_AR = 0x1a,
168 RR_ALR = 0x1e,
169 RR_BASR = 0x0d,
170 RR_BCR = 0x07,
171 RR_CLR = 0x15,
172 RR_CR = 0x19,
173 RR_DR = 0x1d,
174 RR_LCR = 0x13,
175 RR_LR = 0x18,
176 RR_LTR = 0x12,
177 RR_NR = 0x14,
178 RR_OR = 0x16,
179 RR_SR = 0x1b,
180 RR_SLR = 0x1f,
181 RR_XR = 0x17,
183 RSY_RLL = 0xeb1d,
184 RSY_RLLG = 0xeb1c,
185 RSY_SLLG = 0xeb0d,
186 RSY_SRAG = 0xeb0a,
187 RSY_SRLG = 0xeb0c,
189 RS_SLL = 0x89,
190 RS_SRA = 0x8a,
191 RS_SRL = 0x88,
193 RXY_AG = 0xe308,
194 RXY_AY = 0xe35a,
195 RXY_CG = 0xe320,
196 RXY_CY = 0xe359,
197 RXY_LAY = 0xe371,
198 RXY_LB = 0xe376,
199 RXY_LG = 0xe304,
200 RXY_LGB = 0xe377,
201 RXY_LGF = 0xe314,
202 RXY_LGH = 0xe315,
203 RXY_LHY = 0xe378,
204 RXY_LLGC = 0xe390,
205 RXY_LLGF = 0xe316,
206 RXY_LLGH = 0xe391,
207 RXY_LMG = 0xeb04,
208 RXY_LRV = 0xe31e,
209 RXY_LRVG = 0xe30f,
210 RXY_LRVH = 0xe31f,
211 RXY_LY = 0xe358,
212 RXY_STCY = 0xe372,
213 RXY_STG = 0xe324,
214 RXY_STHY = 0xe370,
215 RXY_STMG = 0xeb24,
216 RXY_STRV = 0xe33e,
217 RXY_STRVG = 0xe32f,
218 RXY_STRVH = 0xe33f,
219 RXY_STY = 0xe350,
221 RX_A = 0x5a,
222 RX_C = 0x59,
223 RX_L = 0x58,
224 RX_LA = 0x41,
225 RX_LH = 0x48,
226 RX_ST = 0x50,
227 RX_STC = 0x42,
228 RX_STH = 0x40,
229 } S390Opcode;
231 #define LD_SIGNED 0x04
232 #define LD_UINT8 0x00
233 #define LD_INT8 (LD_UINT8 | LD_SIGNED)
234 #define LD_UINT16 0x01
235 #define LD_INT16 (LD_UINT16 | LD_SIGNED)
236 #define LD_UINT32 0x02
237 #define LD_INT32 (LD_UINT32 | LD_SIGNED)
238 #define LD_UINT64 0x03
239 #define LD_INT64 (LD_UINT64 | LD_SIGNED)
241 #ifndef NDEBUG
242 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
243 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
244 "%r8", "%r9", "%r10" "%r11" "%r12" "%r13" "%r14" "%r15"
246 #endif
248 /* Since R6 is a potential argument register, choose it last of the
249 call-saved registers. Likewise prefer the call-clobbered registers
250 in reverse order to maximize the chance of avoiding the arguments. */
251 static const int tcg_target_reg_alloc_order[] = {
252 TCG_REG_R13,
253 TCG_REG_R12,
254 TCG_REG_R11,
255 TCG_REG_R10,
256 TCG_REG_R9,
257 TCG_REG_R8,
258 TCG_REG_R7,
259 TCG_REG_R6,
260 TCG_REG_R14,
261 TCG_REG_R0,
262 TCG_REG_R1,
263 TCG_REG_R5,
264 TCG_REG_R4,
265 TCG_REG_R3,
266 TCG_REG_R2,
269 static const int tcg_target_call_iarg_regs[] = {
270 TCG_REG_R2,
271 TCG_REG_R3,
272 TCG_REG_R4,
273 TCG_REG_R5,
274 TCG_REG_R6,
277 static const int tcg_target_call_oarg_regs[] = {
278 TCG_REG_R2,
281 #define S390_CC_EQ 8
282 #define S390_CC_LT 4
283 #define S390_CC_GT 2
284 #define S390_CC_OV 1
285 #define S390_CC_NE (S390_CC_LT | S390_CC_GT)
286 #define S390_CC_LE (S390_CC_LT | S390_CC_EQ)
287 #define S390_CC_GE (S390_CC_GT | S390_CC_EQ)
288 #define S390_CC_NEVER 0
289 #define S390_CC_ALWAYS 15
291 /* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
292 static const uint8_t tcg_cond_to_s390_cond[] = {
293 [TCG_COND_EQ] = S390_CC_EQ,
294 [TCG_COND_NE] = S390_CC_NE,
295 [TCG_COND_LT] = S390_CC_LT,
296 [TCG_COND_LE] = S390_CC_LE,
297 [TCG_COND_GT] = S390_CC_GT,
298 [TCG_COND_GE] = S390_CC_GE,
299 [TCG_COND_LTU] = S390_CC_LT,
300 [TCG_COND_LEU] = S390_CC_LE,
301 [TCG_COND_GTU] = S390_CC_GT,
302 [TCG_COND_GEU] = S390_CC_GE,
305 /* Condition codes that result from a LOAD AND TEST. Here, we have no
306 unsigned instruction variation, however since the test is vs zero we
307 can re-map the outcomes appropriately. */
308 static const uint8_t tcg_cond_to_ltr_cond[] = {
309 [TCG_COND_EQ] = S390_CC_EQ,
310 [TCG_COND_NE] = S390_CC_NE,
311 [TCG_COND_LT] = S390_CC_LT,
312 [TCG_COND_LE] = S390_CC_LE,
313 [TCG_COND_GT] = S390_CC_GT,
314 [TCG_COND_GE] = S390_CC_GE,
315 [TCG_COND_LTU] = S390_CC_NEVER,
316 [TCG_COND_LEU] = S390_CC_EQ,
317 [TCG_COND_GTU] = S390_CC_NE,
318 [TCG_COND_GEU] = S390_CC_ALWAYS,
321 #ifdef CONFIG_SOFTMMU
322 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
323 int mmu_idx) */
324 static const void * const qemu_ld_helpers[4] = {
325 helper_ldb_mmu,
326 helper_ldw_mmu,
327 helper_ldl_mmu,
328 helper_ldq_mmu,
331 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
332 uintxx_t val, int mmu_idx) */
333 static const void * const qemu_st_helpers[4] = {
334 helper_stb_mmu,
335 helper_stw_mmu,
336 helper_stl_mmu,
337 helper_stq_mmu,
339 #endif
341 static uint8_t *tb_ret_addr;
343 /* A list of relevant facilities used by this translator. Some of these
344 are required for proper operation, and these are checked at startup. */
346 #define FACILITY_ZARCH_ACTIVE (1ULL << (63 - 2))
347 #define FACILITY_LONG_DISP (1ULL << (63 - 18))
348 #define FACILITY_EXT_IMM (1ULL << (63 - 21))
349 #define FACILITY_GEN_INST_EXT (1ULL << (63 - 34))
350 #define FACILITY_LOAD_ON_COND (1ULL << (63 - 45))
352 static uint64_t facilities;
354 static void patch_reloc(uint8_t *code_ptr, int type,
355 intptr_t value, intptr_t addend)
357 intptr_t code_ptr_tl = (intptr_t)code_ptr;
358 intptr_t pcrel2;
360 /* ??? Not the usual definition of "addend". */
361 pcrel2 = (value - (code_ptr_tl + addend)) >> 1;
363 switch (type) {
364 case R_390_PC16DBL:
365 assert(pcrel2 == (int16_t)pcrel2);
366 *(int16_t *)code_ptr = pcrel2;
367 break;
368 case R_390_PC32DBL:
369 assert(pcrel2 == (int32_t)pcrel2);
370 *(int32_t *)code_ptr = pcrel2;
371 break;
372 default:
373 tcg_abort();
374 break;
378 /* parse target specific constraints */
379 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
381 const char *ct_str = *pct_str;
383 switch (ct_str[0]) {
384 case 'r': /* all registers */
385 ct->ct |= TCG_CT_REG;
386 tcg_regset_set32(ct->u.regs, 0, 0xffff);
387 break;
388 case 'R': /* not R0 */
389 ct->ct |= TCG_CT_REG;
390 tcg_regset_set32(ct->u.regs, 0, 0xffff);
391 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
392 break;
393 case 'L': /* qemu_ld/st constraint */
394 ct->ct |= TCG_CT_REG;
395 tcg_regset_set32(ct->u.regs, 0, 0xffff);
396 tcg_regset_reset_reg (ct->u.regs, TCG_REG_R2);
397 tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
398 tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
399 break;
400 case 'a': /* force R2 for division */
401 ct->ct |= TCG_CT_REG;
402 tcg_regset_clear(ct->u.regs);
403 tcg_regset_set_reg(ct->u.regs, TCG_REG_R2);
404 break;
405 case 'b': /* force R3 for division */
406 ct->ct |= TCG_CT_REG;
407 tcg_regset_clear(ct->u.regs);
408 tcg_regset_set_reg(ct->u.regs, TCG_REG_R3);
409 break;
410 case 'W': /* force 32-bit ("word") immediate */
411 ct->ct |= TCG_CT_CONST_32;
412 break;
413 case 'K':
414 ct->ct |= TCG_CT_CONST_MULI;
415 break;
416 case 'O':
417 ct->ct |= TCG_CT_CONST_ORI;
418 break;
419 case 'X':
420 ct->ct |= TCG_CT_CONST_XORI;
421 break;
422 case 'C':
423 ct->ct |= TCG_CT_CONST_CMPI;
424 break;
425 default:
426 return -1;
428 ct_str++;
429 *pct_str = ct_str;
431 return 0;
434 /* Immediates to be used with logical OR. This is an optimization only,
435 since a full 64-bit immediate OR can always be performed with 4 sequential
436 OI[LH][LH] instructions. What we're looking for is immediates that we
437 can load efficiently, and the immediate load plus the reg-reg OR is
438 smaller than the sequential OI's. */
440 static int tcg_match_ori(int ct, tcg_target_long val)
442 if (facilities & FACILITY_EXT_IMM) {
443 if (ct & TCG_CT_CONST_32) {
444 /* All 32-bit ORs can be performed with 1 48-bit insn. */
445 return 1;
449 /* Look for negative values. These are best to load with LGHI. */
450 if (val < 0) {
451 if (val == (int16_t)val) {
452 return 0;
454 if (facilities & FACILITY_EXT_IMM) {
455 if (val == (int32_t)val) {
456 return 0;
461 return 1;
464 /* Immediates to be used with logical XOR. This is almost, but not quite,
465 only an optimization. XOR with immediate is only supported with the
466 extended-immediate facility. That said, there are a few patterns for
467 which it is better to load the value into a register first. */
469 static int tcg_match_xori(int ct, tcg_target_long val)
471 if ((facilities & FACILITY_EXT_IMM) == 0) {
472 return 0;
475 if (ct & TCG_CT_CONST_32) {
476 /* All 32-bit XORs can be performed with 1 48-bit insn. */
477 return 1;
480 /* Look for negative values. These are best to load with LGHI. */
481 if (val < 0 && val == (int32_t)val) {
482 return 0;
485 return 1;
488 /* Imediates to be used with comparisons. */
490 static int tcg_match_cmpi(int ct, tcg_target_long val)
492 if (facilities & FACILITY_EXT_IMM) {
493 /* The COMPARE IMMEDIATE instruction is available. */
494 if (ct & TCG_CT_CONST_32) {
495 /* We have a 32-bit immediate and can compare against anything. */
496 return 1;
497 } else {
498 /* ??? We have no insight here into whether the comparison is
499 signed or unsigned. The COMPARE IMMEDIATE insn uses a 32-bit
500 signed immediate, and the COMPARE LOGICAL IMMEDIATE insn uses
501 a 32-bit unsigned immediate. If we were to use the (semi)
502 obvious "val == (int32_t)val" we would be enabling unsigned
503 comparisons vs very large numbers. The only solution is to
504 take the intersection of the ranges. */
505 /* ??? Another possible solution is to simply lie and allow all
506 constants here and force the out-of-range values into a temp
507 register in tgen_cmp when we have knowledge of the actual
508 comparison code in use. */
509 return val >= 0 && val <= 0x7fffffff;
511 } else {
512 /* Only the LOAD AND TEST instruction is available. */
513 return val == 0;
517 /* Test if a constant matches the constraint. */
518 static int tcg_target_const_match(tcg_target_long val,
519 const TCGArgConstraint *arg_ct)
521 int ct = arg_ct->ct;
523 if (ct & TCG_CT_CONST) {
524 return 1;
527 /* Handle the modifiers. */
528 if (ct & TCG_CT_CONST_32) {
529 val = (int32_t)val;
532 /* The following are mutually exclusive. */
533 if (ct & TCG_CT_CONST_MULI) {
534 /* Immediates that may be used with multiply. If we have the
535 general-instruction-extensions, then we have MULTIPLY SINGLE
536 IMMEDIATE with a signed 32-bit, otherwise we have only
537 MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
538 if (facilities & FACILITY_GEN_INST_EXT) {
539 return val == (int32_t)val;
540 } else {
541 return val == (int16_t)val;
543 } else if (ct & TCG_CT_CONST_ORI) {
544 return tcg_match_ori(ct, val);
545 } else if (ct & TCG_CT_CONST_XORI) {
546 return tcg_match_xori(ct, val);
547 } else if (ct & TCG_CT_CONST_CMPI) {
548 return tcg_match_cmpi(ct, val);
551 return 0;
554 /* Emit instructions according to the given instruction format. */
556 static void tcg_out_insn_RR(TCGContext *s, S390Opcode op, TCGReg r1, TCGReg r2)
558 tcg_out16(s, (op << 8) | (r1 << 4) | r2);
561 static void tcg_out_insn_RRE(TCGContext *s, S390Opcode op,
562 TCGReg r1, TCGReg r2)
564 tcg_out32(s, (op << 16) | (r1 << 4) | r2);
567 static void tcg_out_insn_RRF(TCGContext *s, S390Opcode op,
568 TCGReg r1, TCGReg r2, int m3)
570 tcg_out32(s, (op << 16) | (m3 << 12) | (r1 << 4) | r2);
573 static void tcg_out_insn_RI(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
575 tcg_out32(s, (op << 16) | (r1 << 20) | (i2 & 0xffff));
578 static void tcg_out_insn_RIL(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
580 tcg_out16(s, op | (r1 << 4));
581 tcg_out32(s, i2);
584 static void tcg_out_insn_RS(TCGContext *s, S390Opcode op, TCGReg r1,
585 TCGReg b2, TCGReg r3, int disp)
587 tcg_out32(s, (op << 24) | (r1 << 20) | (r3 << 16) | (b2 << 12)
588 | (disp & 0xfff));
591 static void tcg_out_insn_RSY(TCGContext *s, S390Opcode op, TCGReg r1,
592 TCGReg b2, TCGReg r3, int disp)
594 tcg_out16(s, (op & 0xff00) | (r1 << 4) | r3);
595 tcg_out32(s, (op & 0xff) | (b2 << 28)
596 | ((disp & 0xfff) << 16) | ((disp & 0xff000) >> 4));
599 #define tcg_out_insn_RX tcg_out_insn_RS
600 #define tcg_out_insn_RXY tcg_out_insn_RSY
602 /* Emit an opcode with "type-checking" of the format. */
603 #define tcg_out_insn(S, FMT, OP, ...) \
604 glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
607 /* emit 64-bit shifts */
608 static void tcg_out_sh64(TCGContext* s, S390Opcode op, TCGReg dest,
609 TCGReg src, TCGReg sh_reg, int sh_imm)
611 tcg_out_insn_RSY(s, op, dest, sh_reg, src, sh_imm);
614 /* emit 32-bit shifts */
615 static void tcg_out_sh32(TCGContext* s, S390Opcode op, TCGReg dest,
616 TCGReg sh_reg, int sh_imm)
618 tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
621 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
623 if (src != dst) {
624 if (type == TCG_TYPE_I32) {
625 tcg_out_insn(s, RR, LR, dst, src);
626 } else {
627 tcg_out_insn(s, RRE, LGR, dst, src);
632 /* load a register with an immediate value */
633 static void tcg_out_movi(TCGContext *s, TCGType type,
634 TCGReg ret, tcg_target_long sval)
636 static const S390Opcode lli_insns[4] = {
637 RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
640 tcg_target_ulong uval = sval;
641 int i;
643 if (type == TCG_TYPE_I32) {
644 uval = (uint32_t)sval;
645 sval = (int32_t)sval;
648 /* Try all 32-bit insns that can load it in one go. */
649 if (sval >= -0x8000 && sval < 0x8000) {
650 tcg_out_insn(s, RI, LGHI, ret, sval);
651 return;
654 for (i = 0; i < 4; i++) {
655 tcg_target_long mask = 0xffffull << i*16;
656 if ((uval & mask) == uval) {
657 tcg_out_insn_RI(s, lli_insns[i], ret, uval >> i*16);
658 return;
662 /* Try all 48-bit insns that can load it in one go. */
663 if (facilities & FACILITY_EXT_IMM) {
664 if (sval == (int32_t)sval) {
665 tcg_out_insn(s, RIL, LGFI, ret, sval);
666 return;
668 if (uval <= 0xffffffff) {
669 tcg_out_insn(s, RIL, LLILF, ret, uval);
670 return;
672 if ((uval & 0xffffffff) == 0) {
673 tcg_out_insn(s, RIL, LLIHF, ret, uval >> 31 >> 1);
674 return;
678 /* Try for PC-relative address load. */
679 if ((sval & 1) == 0) {
680 intptr_t off = (sval - (intptr_t)s->code_ptr) >> 1;
681 if (off == (int32_t)off) {
682 tcg_out_insn(s, RIL, LARL, ret, off);
683 return;
687 /* If extended immediates are not present, then we may have to issue
688 several instructions to load the low 32 bits. */
689 if (!(facilities & FACILITY_EXT_IMM)) {
690 /* A 32-bit unsigned value can be loaded in 2 insns. And given
691 that the lli_insns loop above did not succeed, we know that
692 both insns are required. */
693 if (uval <= 0xffffffff) {
694 tcg_out_insn(s, RI, LLILL, ret, uval);
695 tcg_out_insn(s, RI, IILH, ret, uval >> 16);
696 return;
699 /* If all high bits are set, the value can be loaded in 2 or 3 insns.
700 We first want to make sure that all the high bits get set. With
701 luck the low 16-bits can be considered negative to perform that for
702 free, otherwise we load an explicit -1. */
703 if (sval >> 31 >> 1 == -1) {
704 if (uval & 0x8000) {
705 tcg_out_insn(s, RI, LGHI, ret, uval);
706 } else {
707 tcg_out_insn(s, RI, LGHI, ret, -1);
708 tcg_out_insn(s, RI, IILL, ret, uval);
710 tcg_out_insn(s, RI, IILH, ret, uval >> 16);
711 return;
715 /* If we get here, both the high and low parts have non-zero bits. */
717 /* Recurse to load the lower 32-bits. */
718 tcg_out_movi(s, TCG_TYPE_I64, ret, uval & 0xffffffff);
720 /* Insert data into the high 32-bits. */
721 uval = uval >> 31 >> 1;
722 if (facilities & FACILITY_EXT_IMM) {
723 if (uval < 0x10000) {
724 tcg_out_insn(s, RI, IIHL, ret, uval);
725 } else if ((uval & 0xffff) == 0) {
726 tcg_out_insn(s, RI, IIHH, ret, uval >> 16);
727 } else {
728 tcg_out_insn(s, RIL, IIHF, ret, uval);
730 } else {
731 if (uval & 0xffff) {
732 tcg_out_insn(s, RI, IIHL, ret, uval);
734 if (uval & 0xffff0000) {
735 tcg_out_insn(s, RI, IIHH, ret, uval >> 16);
741 /* Emit a load/store type instruction. Inputs are:
742 DATA: The register to be loaded or stored.
743 BASE+OFS: The effective address.
744 OPC_RX: If the operation has an RX format opcode (e.g. STC), otherwise 0.
745 OPC_RXY: The RXY format opcode for the operation (e.g. STCY). */
747 static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
748 TCGReg data, TCGReg base, TCGReg index,
749 tcg_target_long ofs)
751 if (ofs < -0x80000 || ofs >= 0x80000) {
752 /* Combine the low 20 bits of the offset with the actual load insn;
753 the high 44 bits must come from an immediate load. */
754 tcg_target_long low = ((ofs & 0xfffff) ^ 0x80000) - 0x80000;
755 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - low);
756 ofs = low;
758 /* If we were already given an index register, add it in. */
759 if (index != TCG_REG_NONE) {
760 tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
762 index = TCG_TMP0;
765 if (opc_rx && ofs >= 0 && ofs < 0x1000) {
766 tcg_out_insn_RX(s, opc_rx, data, base, index, ofs);
767 } else {
768 tcg_out_insn_RXY(s, opc_rxy, data, base, index, ofs);
773 /* load data without address translation or endianness conversion */
774 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
775 TCGReg base, intptr_t ofs)
777 if (type == TCG_TYPE_I32) {
778 tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs);
779 } else {
780 tcg_out_mem(s, 0, RXY_LG, data, base, TCG_REG_NONE, ofs);
784 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
785 TCGReg base, intptr_t ofs)
787 if (type == TCG_TYPE_I32) {
788 tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs);
789 } else {
790 tcg_out_mem(s, 0, RXY_STG, data, base, TCG_REG_NONE, ofs);
794 /* load data from an absolute host address */
795 static void tcg_out_ld_abs(TCGContext *s, TCGType type, TCGReg dest, void *abs)
797 tcg_target_long addr = (tcg_target_long)abs;
799 if (facilities & FACILITY_GEN_INST_EXT) {
800 tcg_target_long disp = (addr - (tcg_target_long)s->code_ptr) >> 1;
801 if (disp == (int32_t)disp) {
802 if (type == TCG_TYPE_I32) {
803 tcg_out_insn(s, RIL, LRL, dest, disp);
804 } else {
805 tcg_out_insn(s, RIL, LGRL, dest, disp);
807 return;
811 tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
812 tcg_out_ld(s, type, dest, dest, addr & 0xffff);
815 static inline void tcg_out_risbg(TCGContext *s, TCGReg dest, TCGReg src,
816 int msb, int lsb, int ofs, int z)
818 /* Format RIE-f */
819 tcg_out16(s, (RIE_RISBG & 0xff00) | (dest << 4) | src);
820 tcg_out16(s, (msb << 8) | (z << 7) | lsb);
821 tcg_out16(s, (ofs << 8) | (RIE_RISBG & 0xff));
824 static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
826 if (facilities & FACILITY_EXT_IMM) {
827 tcg_out_insn(s, RRE, LGBR, dest, src);
828 return;
831 if (type == TCG_TYPE_I32) {
832 if (dest == src) {
833 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 24);
834 } else {
835 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 24);
837 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 24);
838 } else {
839 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 56);
840 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 56);
844 static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
846 if (facilities & FACILITY_EXT_IMM) {
847 tcg_out_insn(s, RRE, LLGCR, dest, src);
848 return;
851 if (dest == src) {
852 tcg_out_movi(s, type, TCG_TMP0, 0xff);
853 src = TCG_TMP0;
854 } else {
855 tcg_out_movi(s, type, dest, 0xff);
857 if (type == TCG_TYPE_I32) {
858 tcg_out_insn(s, RR, NR, dest, src);
859 } else {
860 tcg_out_insn(s, RRE, NGR, dest, src);
864 static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
866 if (facilities & FACILITY_EXT_IMM) {
867 tcg_out_insn(s, RRE, LGHR, dest, src);
868 return;
871 if (type == TCG_TYPE_I32) {
872 if (dest == src) {
873 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 16);
874 } else {
875 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 16);
877 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 16);
878 } else {
879 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 48);
880 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 48);
884 static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
886 if (facilities & FACILITY_EXT_IMM) {
887 tcg_out_insn(s, RRE, LLGHR, dest, src);
888 return;
891 if (dest == src) {
892 tcg_out_movi(s, type, TCG_TMP0, 0xffff);
893 src = TCG_TMP0;
894 } else {
895 tcg_out_movi(s, type, dest, 0xffff);
897 if (type == TCG_TYPE_I32) {
898 tcg_out_insn(s, RR, NR, dest, src);
899 } else {
900 tcg_out_insn(s, RRE, NGR, dest, src);
904 static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
906 tcg_out_insn(s, RRE, LGFR, dest, src);
909 static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
911 tcg_out_insn(s, RRE, LLGFR, dest, src);
914 /* Accept bit patterns like these:
915 0....01....1
916 1....10....0
917 1..10..01..1
918 0..01..10..0
919 Copied from gcc sources. */
920 static inline bool risbg_mask(uint64_t c)
922 uint64_t lsb;
923 /* We don't change the number of transitions by inverting,
924 so make sure we start with the LSB zero. */
925 if (c & 1) {
926 c = ~c;
928 /* Reject all zeros or all ones. */
929 if (c == 0) {
930 return false;
932 /* Find the first transition. */
933 lsb = c & -c;
934 /* Invert to look for a second transition. */
935 c = ~c;
936 /* Erase the first transition. */
937 c &= -lsb;
938 /* Find the second transition, if any. */
939 lsb = c & -c;
940 /* Match if all the bits are 1's, or if c is zero. */
941 return c == -lsb;
944 static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
946 static const S390Opcode ni_insns[4] = {
947 RI_NILL, RI_NILH, RI_NIHL, RI_NIHH
949 static const S390Opcode nif_insns[2] = {
950 RIL_NILF, RIL_NIHF
952 uint64_t valid = (type == TCG_TYPE_I32 ? 0xffffffffull : -1ull);
953 int i;
955 /* Look for the zero-extensions. */
956 if ((val & valid) == 0xffffffff) {
957 tgen_ext32u(s, dest, dest);
958 return;
960 if (facilities & FACILITY_EXT_IMM) {
961 if ((val & valid) == 0xff) {
962 tgen_ext8u(s, TCG_TYPE_I64, dest, dest);
963 return;
965 if ((val & valid) == 0xffff) {
966 tgen_ext16u(s, TCG_TYPE_I64, dest, dest);
967 return;
971 /* Try all 32-bit insns that can perform it in one go. */
972 for (i = 0; i < 4; i++) {
973 tcg_target_ulong mask = ~(0xffffull << i*16);
974 if (((val | ~valid) & mask) == mask) {
975 tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
976 return;
980 /* Try all 48-bit insns that can perform it in one go. */
981 if (facilities & FACILITY_EXT_IMM) {
982 for (i = 0; i < 2; i++) {
983 tcg_target_ulong mask = ~(0xffffffffull << i*32);
984 if (((val | ~valid) & mask) == mask) {
985 tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
986 return;
990 if ((facilities & FACILITY_GEN_INST_EXT) && risbg_mask(val)) {
991 int msb, lsb;
992 if ((val & 0x8000000000000001ull) == 0x8000000000000001ull) {
993 /* Achieve wraparound by swapping msb and lsb. */
994 msb = 63 - ctz64(~val);
995 lsb = clz64(~val) + 1;
996 } else {
997 msb = clz64(val);
998 lsb = 63 - ctz64(val);
1000 tcg_out_risbg(s, dest, dest, msb, lsb, 0, 1);
1001 return;
1004 /* Fall back to loading the constant. */
1005 tcg_out_movi(s, type, TCG_TMP0, val);
1006 if (type == TCG_TYPE_I32) {
1007 tcg_out_insn(s, RR, NR, dest, TCG_TMP0);
1008 } else {
1009 tcg_out_insn(s, RRE, NGR, dest, TCG_TMP0);
1013 static void tgen64_ori(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1015 static const S390Opcode oi_insns[4] = {
1016 RI_OILL, RI_OILH, RI_OIHL, RI_OIHH
1018 static const S390Opcode nif_insns[2] = {
1019 RIL_OILF, RIL_OIHF
1022 int i;
1024 /* Look for no-op. */
1025 if (val == 0) {
1026 return;
1029 if (facilities & FACILITY_EXT_IMM) {
1030 /* Try all 32-bit insns that can perform it in one go. */
1031 for (i = 0; i < 4; i++) {
1032 tcg_target_ulong mask = (0xffffull << i*16);
1033 if ((val & mask) != 0 && (val & ~mask) == 0) {
1034 tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
1035 return;
1039 /* Try all 48-bit insns that can perform it in one go. */
1040 for (i = 0; i < 2; i++) {
1041 tcg_target_ulong mask = (0xffffffffull << i*32);
1042 if ((val & mask) != 0 && (val & ~mask) == 0) {
1043 tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
1044 return;
1048 /* Perform the OR via sequential modifications to the high and
1049 low parts. Do this via recursion to handle 16-bit vs 32-bit
1050 masks in each half. */
1051 tgen64_ori(s, dest, val & 0x00000000ffffffffull);
1052 tgen64_ori(s, dest, val & 0xffffffff00000000ull);
1053 } else {
1054 /* With no extended-immediate facility, we don't need to be so
1055 clever. Just iterate over the insns and mask in the constant. */
1056 for (i = 0; i < 4; i++) {
1057 tcg_target_ulong mask = (0xffffull << i*16);
1058 if ((val & mask) != 0) {
1059 tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
1065 static void tgen64_xori(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1067 /* Perform the xor by parts. */
1068 if (val & 0xffffffff) {
1069 tcg_out_insn(s, RIL, XILF, dest, val);
1071 if (val > 0xffffffff) {
1072 tcg_out_insn(s, RIL, XIHF, dest, val >> 31 >> 1);
1076 static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
1077 TCGArg c2, int c2const)
1079 bool is_unsigned = is_unsigned_cond(c);
1080 if (c2const) {
1081 if (c2 == 0) {
1082 if (type == TCG_TYPE_I32) {
1083 tcg_out_insn(s, RR, LTR, r1, r1);
1084 } else {
1085 tcg_out_insn(s, RRE, LTGR, r1, r1);
1087 return tcg_cond_to_ltr_cond[c];
1088 } else {
1089 if (is_unsigned) {
1090 if (type == TCG_TYPE_I32) {
1091 tcg_out_insn(s, RIL, CLFI, r1, c2);
1092 } else {
1093 tcg_out_insn(s, RIL, CLGFI, r1, c2);
1095 } else {
1096 if (type == TCG_TYPE_I32) {
1097 tcg_out_insn(s, RIL, CFI, r1, c2);
1098 } else {
1099 tcg_out_insn(s, RIL, CGFI, r1, c2);
1103 } else {
1104 if (is_unsigned) {
1105 if (type == TCG_TYPE_I32) {
1106 tcg_out_insn(s, RR, CLR, r1, c2);
1107 } else {
1108 tcg_out_insn(s, RRE, CLGR, r1, c2);
1110 } else {
1111 if (type == TCG_TYPE_I32) {
1112 tcg_out_insn(s, RR, CR, r1, c2);
1113 } else {
1114 tcg_out_insn(s, RRE, CGR, r1, c2);
1118 return tcg_cond_to_s390_cond[c];
1121 static void tgen_setcond(TCGContext *s, TCGType type, TCGCond c,
1122 TCGReg dest, TCGReg c1, TCGArg c2, int c2const)
1124 int cc = tgen_cmp(s, type, c, c1, c2, c2const);
1126 /* Emit: r1 = 1; if (cc) goto over; r1 = 0; over: */
1127 tcg_out_movi(s, type, dest, 1);
1128 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1129 tcg_out_movi(s, type, dest, 0);
1132 static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest,
1133 TCGReg c1, TCGArg c2, int c2const, TCGReg r3)
1135 int cc;
1136 if (facilities & FACILITY_LOAD_ON_COND) {
1137 cc = tgen_cmp(s, type, c, c1, c2, c2const);
1138 tcg_out_insn(s, RRF, LOCGR, dest, r3, cc);
1139 } else {
1140 c = tcg_invert_cond(c);
1141 cc = tgen_cmp(s, type, c, c1, c2, c2const);
1143 /* Emit: if (cc) goto over; dest = r3; over: */
1144 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1145 tcg_out_insn(s, RRE, LGR, dest, r3);
1149 bool tcg_target_deposit_valid(int ofs, int len)
1151 return (facilities & FACILITY_GEN_INST_EXT) != 0;
1154 static void tgen_deposit(TCGContext *s, TCGReg dest, TCGReg src,
1155 int ofs, int len)
1157 int lsb = (63 - ofs);
1158 int msb = lsb - (len - 1);
1159 tcg_out_risbg(s, dest, src, msb, lsb, ofs, 0);
1162 static void tgen_gotoi(TCGContext *s, int cc, tcg_target_long dest)
1164 tcg_target_long off = (dest - (tcg_target_long)s->code_ptr) >> 1;
1165 if (off > -0x8000 && off < 0x7fff) {
1166 tcg_out_insn(s, RI, BRC, cc, off);
1167 } else if (off == (int32_t)off) {
1168 tcg_out_insn(s, RIL, BRCL, cc, off);
1169 } else {
1170 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, dest);
1171 tcg_out_insn(s, RR, BCR, cc, TCG_TMP0);
1175 static void tgen_branch(TCGContext *s, int cc, int labelno)
1177 TCGLabel* l = &s->labels[labelno];
1178 if (l->has_value) {
1179 tgen_gotoi(s, cc, l->u.value);
1180 } else if (USE_LONG_BRANCHES) {
1181 tcg_out16(s, RIL_BRCL | (cc << 4));
1182 tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, labelno, -2);
1183 s->code_ptr += 4;
1184 } else {
1185 tcg_out16(s, RI_BRC | (cc << 4));
1186 tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, labelno, -2);
1187 s->code_ptr += 2;
1191 static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
1192 TCGReg r1, TCGReg r2, int labelno)
1194 TCGLabel* l = &s->labels[labelno];
1195 tcg_target_long off;
1197 if (l->has_value) {
1198 off = (l->u.value - (tcg_target_long)s->code_ptr) >> 1;
1199 } else {
1200 /* We need to keep the offset unchanged for retranslation. */
1201 off = ((int16_t *)s->code_ptr)[1];
1202 tcg_out_reloc(s, s->code_ptr + 2, R_390_PC16DBL, labelno, -2);
1205 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
1206 tcg_out16(s, off);
1207 tcg_out16(s, cc << 12 | (opc & 0xff));
1210 static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
1211 TCGReg r1, int i2, int labelno)
1213 TCGLabel* l = &s->labels[labelno];
1214 tcg_target_long off;
1216 if (l->has_value) {
1217 off = (l->u.value - (tcg_target_long)s->code_ptr) >> 1;
1218 } else {
1219 /* We need to keep the offset unchanged for retranslation. */
1220 off = ((int16_t *)s->code_ptr)[1];
1221 tcg_out_reloc(s, s->code_ptr + 2, R_390_PC16DBL, labelno, -2);
1224 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
1225 tcg_out16(s, off);
1226 tcg_out16(s, (i2 << 8) | (opc & 0xff));
1229 static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
1230 TCGReg r1, TCGArg c2, int c2const, int labelno)
1232 int cc;
1234 if (facilities & FACILITY_GEN_INST_EXT) {
1235 bool is_unsigned = is_unsigned_cond(c);
1236 bool in_range;
1237 S390Opcode opc;
1239 cc = tcg_cond_to_s390_cond[c];
1241 if (!c2const) {
1242 opc = (type == TCG_TYPE_I32
1243 ? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
1244 : (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
1245 tgen_compare_branch(s, opc, cc, r1, c2, labelno);
1246 return;
1249 /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1250 If the immediate we've been given does not fit that range, we'll
1251 fall back to separate compare and branch instructions using the
1252 larger comparison range afforded by COMPARE IMMEDIATE. */
1253 if (type == TCG_TYPE_I32) {
1254 if (is_unsigned) {
1255 opc = RIE_CLIJ;
1256 in_range = (uint32_t)c2 == (uint8_t)c2;
1257 } else {
1258 opc = RIE_CIJ;
1259 in_range = (int32_t)c2 == (int8_t)c2;
1261 } else {
1262 if (is_unsigned) {
1263 opc = RIE_CLGIJ;
1264 in_range = (uint64_t)c2 == (uint8_t)c2;
1265 } else {
1266 opc = RIE_CGIJ;
1267 in_range = (int64_t)c2 == (int8_t)c2;
1270 if (in_range) {
1271 tgen_compare_imm_branch(s, opc, cc, r1, c2, labelno);
1272 return;
1276 cc = tgen_cmp(s, type, c, r1, c2, c2const);
1277 tgen_branch(s, cc, labelno);
1280 static void tgen_calli(TCGContext *s, tcg_target_long dest)
1282 tcg_target_long off = (dest - (tcg_target_long)s->code_ptr) >> 1;
1283 if (off == (int32_t)off) {
1284 tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
1285 } else {
1286 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, dest);
1287 tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_TMP0);
1291 static void tcg_out_qemu_ld_direct(TCGContext *s, int opc, TCGReg data,
1292 TCGReg base, TCGReg index, int disp)
1294 #ifdef TARGET_WORDS_BIGENDIAN
1295 const int bswap = 0;
1296 #else
1297 const int bswap = 1;
1298 #endif
1299 switch (opc) {
1300 case LD_UINT8:
1301 tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
1302 break;
1303 case LD_INT8:
1304 tcg_out_insn(s, RXY, LGB, data, base, index, disp);
1305 break;
1306 case LD_UINT16:
1307 if (bswap) {
1308 /* swapped unsigned halfword load with upper bits zeroed */
1309 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1310 tgen_ext16u(s, TCG_TYPE_I64, data, data);
1311 } else {
1312 tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
1314 break;
1315 case LD_INT16:
1316 if (bswap) {
1317 /* swapped sign-extended halfword load */
1318 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1319 tgen_ext16s(s, TCG_TYPE_I64, data, data);
1320 } else {
1321 tcg_out_insn(s, RXY, LGH, data, base, index, disp);
1323 break;
1324 case LD_UINT32:
1325 if (bswap) {
1326 /* swapped unsigned int load with upper bits zeroed */
1327 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1328 tgen_ext32u(s, data, data);
1329 } else {
1330 tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
1332 break;
1333 case LD_INT32:
1334 if (bswap) {
1335 /* swapped sign-extended int load */
1336 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1337 tgen_ext32s(s, data, data);
1338 } else {
1339 tcg_out_insn(s, RXY, LGF, data, base, index, disp);
1341 break;
1342 case LD_UINT64:
1343 if (bswap) {
1344 tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
1345 } else {
1346 tcg_out_insn(s, RXY, LG, data, base, index, disp);
1348 break;
1349 default:
1350 tcg_abort();
1354 static void tcg_out_qemu_st_direct(TCGContext *s, int opc, TCGReg data,
1355 TCGReg base, TCGReg index, int disp)
1357 #ifdef TARGET_WORDS_BIGENDIAN
1358 const int bswap = 0;
1359 #else
1360 const int bswap = 1;
1361 #endif
1362 switch (opc) {
1363 case LD_UINT8:
1364 if (disp >= 0 && disp < 0x1000) {
1365 tcg_out_insn(s, RX, STC, data, base, index, disp);
1366 } else {
1367 tcg_out_insn(s, RXY, STCY, data, base, index, disp);
1369 break;
1370 case LD_UINT16:
1371 if (bswap) {
1372 tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
1373 } else if (disp >= 0 && disp < 0x1000) {
1374 tcg_out_insn(s, RX, STH, data, base, index, disp);
1375 } else {
1376 tcg_out_insn(s, RXY, STHY, data, base, index, disp);
1378 break;
1379 case LD_UINT32:
1380 if (bswap) {
1381 tcg_out_insn(s, RXY, STRV, data, base, index, disp);
1382 } else if (disp >= 0 && disp < 0x1000) {
1383 tcg_out_insn(s, RX, ST, data, base, index, disp);
1384 } else {
1385 tcg_out_insn(s, RXY, STY, data, base, index, disp);
1387 break;
1388 case LD_UINT64:
1389 if (bswap) {
1390 tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
1391 } else {
1392 tcg_out_insn(s, RXY, STG, data, base, index, disp);
1394 break;
1395 default:
1396 tcg_abort();
1400 #if defined(CONFIG_SOFTMMU)
1401 static TCGReg tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
1402 TCGReg addr_reg, int mem_index, int opc,
1403 uint16_t **label2_ptr_p, int is_store)
1405 const TCGReg arg0 = tcg_target_call_iarg_regs[0];
1406 const TCGReg arg1 = tcg_target_call_iarg_regs[1];
1407 const TCGReg arg2 = tcg_target_call_iarg_regs[2];
1408 const TCGReg arg3 = tcg_target_call_iarg_regs[3];
1409 int s_bits = opc & 3;
1410 uint16_t *label1_ptr;
1411 tcg_target_long ofs;
1413 if (TARGET_LONG_BITS == 32) {
1414 tgen_ext32u(s, arg1, addr_reg);
1415 } else {
1416 tcg_out_mov(s, TCG_TYPE_I64, arg1, addr_reg);
1419 tcg_out_sh64(s, RSY_SRLG, arg2, addr_reg, TCG_REG_NONE,
1420 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1422 tgen_andi(s, TCG_TYPE_I64, arg1, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1423 tgen_andi(s, TCG_TYPE_I64, arg2, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1425 if (is_store) {
1426 ofs = offsetof(CPUArchState, tlb_table[mem_index][0].addr_write);
1427 } else {
1428 ofs = offsetof(CPUArchState, tlb_table[mem_index][0].addr_read);
1430 assert(ofs < 0x80000);
1432 if (TARGET_LONG_BITS == 32) {
1433 tcg_out_mem(s, RX_C, RXY_CY, arg1, arg2, TCG_AREG0, ofs);
1434 } else {
1435 tcg_out_mem(s, 0, RXY_CG, arg1, arg2, TCG_AREG0, ofs);
1438 if (TARGET_LONG_BITS == 32) {
1439 tgen_ext32u(s, arg1, addr_reg);
1440 } else {
1441 tcg_out_mov(s, TCG_TYPE_I64, arg1, addr_reg);
1444 label1_ptr = (uint16_t*)s->code_ptr;
1446 /* je label1 (offset will be patched in later) */
1447 tcg_out_insn(s, RI, BRC, S390_CC_EQ, 0);
1449 /* call load/store helper */
1450 if (is_store) {
1451 /* Make sure to zero-extend the value to the full register
1452 for the calling convention. */
1453 switch (opc) {
1454 case LD_UINT8:
1455 tgen_ext8u(s, TCG_TYPE_I64, arg2, data_reg);
1456 break;
1457 case LD_UINT16:
1458 tgen_ext16u(s, TCG_TYPE_I64, arg2, data_reg);
1459 break;
1460 case LD_UINT32:
1461 tgen_ext32u(s, arg2, data_reg);
1462 break;
1463 case LD_UINT64:
1464 tcg_out_mov(s, TCG_TYPE_I64, arg2, data_reg);
1465 break;
1466 default:
1467 tcg_abort();
1469 tcg_out_movi(s, TCG_TYPE_I32, arg3, mem_index);
1470 tcg_out_mov(s, TCG_TYPE_I64, arg0, TCG_AREG0);
1471 tgen_calli(s, (tcg_target_ulong)qemu_st_helpers[s_bits]);
1472 } else {
1473 tcg_out_movi(s, TCG_TYPE_I32, arg2, mem_index);
1474 tcg_out_mov(s, TCG_TYPE_I64, arg0, TCG_AREG0);
1475 tgen_calli(s, (tcg_target_ulong)qemu_ld_helpers[s_bits]);
1477 /* sign extension */
1478 switch (opc) {
1479 case LD_INT8:
1480 tgen_ext8s(s, TCG_TYPE_I64, data_reg, TCG_REG_R2);
1481 break;
1482 case LD_INT16:
1483 tgen_ext16s(s, TCG_TYPE_I64, data_reg, TCG_REG_R2);
1484 break;
1485 case LD_INT32:
1486 tgen_ext32s(s, data_reg, TCG_REG_R2);
1487 break;
1488 default:
1489 /* unsigned -> just copy */
1490 tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_R2);
1491 break;
1495 /* jump to label2 (end) */
1496 *label2_ptr_p = (uint16_t*)s->code_ptr;
1498 tcg_out_insn(s, RI, BRC, S390_CC_ALWAYS, 0);
1500 /* this is label1, patch branch */
1501 *(label1_ptr + 1) = ((unsigned long)s->code_ptr -
1502 (unsigned long)label1_ptr) >> 1;
1504 ofs = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
1505 assert(ofs < 0x80000);
1507 tcg_out_mem(s, 0, RXY_AG, arg1, arg2, TCG_AREG0, ofs);
1509 return arg1;
1512 static void tcg_finish_qemu_ldst(TCGContext* s, uint16_t *label2_ptr)
1514 /* patch branch */
1515 *(label2_ptr + 1) = ((unsigned long)s->code_ptr -
1516 (unsigned long)label2_ptr) >> 1;
1518 #else
1519 static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
1520 TCGReg *index_reg, tcg_target_long *disp)
1522 if (TARGET_LONG_BITS == 32) {
1523 tgen_ext32u(s, TCG_TMP0, *addr_reg);
1524 *addr_reg = TCG_TMP0;
1526 if (GUEST_BASE < 0x80000) {
1527 *index_reg = TCG_REG_NONE;
1528 *disp = GUEST_BASE;
1529 } else {
1530 *index_reg = TCG_GUEST_BASE_REG;
1531 *disp = 0;
1534 #endif /* CONFIG_SOFTMMU */
1536 /* load data with address translation (if applicable)
1537 and endianness conversion */
1538 static void tcg_out_qemu_ld(TCGContext* s, const TCGArg* args, int opc)
1540 TCGReg addr_reg, data_reg;
1541 #if defined(CONFIG_SOFTMMU)
1542 int mem_index;
1543 uint16_t *label2_ptr;
1544 #else
1545 TCGReg index_reg;
1546 tcg_target_long disp;
1547 #endif
1549 data_reg = *args++;
1550 addr_reg = *args++;
1552 #if defined(CONFIG_SOFTMMU)
1553 mem_index = *args;
1555 addr_reg = tcg_prepare_qemu_ldst(s, data_reg, addr_reg, mem_index,
1556 opc, &label2_ptr, 0);
1558 tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, TCG_REG_NONE, 0);
1560 tcg_finish_qemu_ldst(s, label2_ptr);
1561 #else
1562 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1563 tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1564 #endif
1567 static void tcg_out_qemu_st(TCGContext* s, const TCGArg* args, int opc)
1569 TCGReg addr_reg, data_reg;
1570 #if defined(CONFIG_SOFTMMU)
1571 int mem_index;
1572 uint16_t *label2_ptr;
1573 #else
1574 TCGReg index_reg;
1575 tcg_target_long disp;
1576 #endif
1578 data_reg = *args++;
1579 addr_reg = *args++;
1581 #if defined(CONFIG_SOFTMMU)
1582 mem_index = *args;
1584 addr_reg = tcg_prepare_qemu_ldst(s, data_reg, addr_reg, mem_index,
1585 opc, &label2_ptr, 1);
1587 tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg, TCG_REG_NONE, 0);
1589 tcg_finish_qemu_ldst(s, label2_ptr);
1590 #else
1591 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1592 tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1593 #endif
1596 # define OP_32_64(x) \
1597 case glue(glue(INDEX_op_,x),_i32): \
1598 case glue(glue(INDEX_op_,x),_i64)
1600 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1601 const TCGArg *args, const int *const_args)
1603 S390Opcode op;
1604 TCGArg a0, a1, a2;
1606 switch (opc) {
1607 case INDEX_op_exit_tb:
1608 /* return value */
1609 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, args[0]);
1610 tgen_gotoi(s, S390_CC_ALWAYS, (unsigned long)tb_ret_addr);
1611 break;
1613 case INDEX_op_goto_tb:
1614 if (s->tb_jmp_offset) {
1615 tcg_abort();
1616 } else {
1617 /* load address stored at s->tb_next + args[0] */
1618 tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_TMP0, s->tb_next + args[0]);
1619 /* and go there */
1620 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_TMP0);
1622 s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1623 break;
1625 case INDEX_op_call:
1626 if (const_args[0]) {
1627 tgen_calli(s, args[0]);
1628 } else {
1629 tcg_out_insn(s, RR, BASR, TCG_REG_R14, args[0]);
1631 break;
1633 case INDEX_op_mov_i32:
1634 tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1635 break;
1636 case INDEX_op_movi_i32:
1637 tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1638 break;
1640 OP_32_64(ld8u):
1641 /* ??? LLC (RXY format) is only present with the extended-immediate
1642 facility, whereas LLGC is always present. */
1643 tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
1644 break;
1646 OP_32_64(ld8s):
1647 /* ??? LB is no smaller than LGB, so no point to using it. */
1648 tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
1649 break;
1651 OP_32_64(ld16u):
1652 /* ??? LLH (RXY format) is only present with the extended-immediate
1653 facility, whereas LLGH is always present. */
1654 tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
1655 break;
1657 case INDEX_op_ld16s_i32:
1658 tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
1659 break;
1661 case INDEX_op_ld_i32:
1662 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1663 break;
1665 OP_32_64(st8):
1666 tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
1667 TCG_REG_NONE, args[2]);
1668 break;
1670 OP_32_64(st16):
1671 tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
1672 TCG_REG_NONE, args[2]);
1673 break;
1675 case INDEX_op_st_i32:
1676 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1677 break;
1679 case INDEX_op_add_i32:
1680 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1681 if (const_args[2]) {
1682 do_addi_32:
1683 if (a0 == a1) {
1684 if (a2 == (int16_t)a2) {
1685 tcg_out_insn(s, RI, AHI, a0, a2);
1686 break;
1688 if (facilities & FACILITY_EXT_IMM) {
1689 tcg_out_insn(s, RIL, AFI, a0, a2);
1690 break;
1693 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
1694 } else if (a0 == a1) {
1695 tcg_out_insn(s, RR, AR, a0, a2);
1696 } else {
1697 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
1699 break;
1700 case INDEX_op_sub_i32:
1701 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1702 if (const_args[2]) {
1703 a2 = -a2;
1704 goto do_addi_32;
1706 tcg_out_insn(s, RR, SR, args[0], args[2]);
1707 break;
1709 case INDEX_op_and_i32:
1710 if (const_args[2]) {
1711 tgen_andi(s, TCG_TYPE_I32, args[0], args[2]);
1712 } else {
1713 tcg_out_insn(s, RR, NR, args[0], args[2]);
1715 break;
1716 case INDEX_op_or_i32:
1717 if (const_args[2]) {
1718 tgen64_ori(s, args[0], args[2] & 0xffffffff);
1719 } else {
1720 tcg_out_insn(s, RR, OR, args[0], args[2]);
1722 break;
1723 case INDEX_op_xor_i32:
1724 if (const_args[2]) {
1725 tgen64_xori(s, args[0], args[2] & 0xffffffff);
1726 } else {
1727 tcg_out_insn(s, RR, XR, args[0], args[2]);
1729 break;
1731 case INDEX_op_neg_i32:
1732 tcg_out_insn(s, RR, LCR, args[0], args[1]);
1733 break;
1735 case INDEX_op_mul_i32:
1736 if (const_args[2]) {
1737 if ((int32_t)args[2] == (int16_t)args[2]) {
1738 tcg_out_insn(s, RI, MHI, args[0], args[2]);
1739 } else {
1740 tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
1742 } else {
1743 tcg_out_insn(s, RRE, MSR, args[0], args[2]);
1745 break;
1747 case INDEX_op_div2_i32:
1748 tcg_out_insn(s, RR, DR, TCG_REG_R2, args[4]);
1749 break;
1750 case INDEX_op_divu2_i32:
1751 tcg_out_insn(s, RRE, DLR, TCG_REG_R2, args[4]);
1752 break;
1754 case INDEX_op_shl_i32:
1755 op = RS_SLL;
1756 do_shift32:
1757 if (const_args[2]) {
1758 tcg_out_sh32(s, op, args[0], TCG_REG_NONE, args[2]);
1759 } else {
1760 tcg_out_sh32(s, op, args[0], args[2], 0);
1762 break;
1763 case INDEX_op_shr_i32:
1764 op = RS_SRL;
1765 goto do_shift32;
1766 case INDEX_op_sar_i32:
1767 op = RS_SRA;
1768 goto do_shift32;
1770 case INDEX_op_rotl_i32:
1771 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1772 if (const_args[2]) {
1773 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
1774 } else {
1775 tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
1777 break;
1778 case INDEX_op_rotr_i32:
1779 if (const_args[2]) {
1780 tcg_out_sh64(s, RSY_RLL, args[0], args[1],
1781 TCG_REG_NONE, (32 - args[2]) & 31);
1782 } else {
1783 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
1784 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
1786 break;
1788 case INDEX_op_ext8s_i32:
1789 tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
1790 break;
1791 case INDEX_op_ext16s_i32:
1792 tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
1793 break;
1794 case INDEX_op_ext8u_i32:
1795 tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
1796 break;
1797 case INDEX_op_ext16u_i32:
1798 tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
1799 break;
1801 OP_32_64(bswap16):
1802 /* The TCG bswap definition requires bits 0-47 already be zero.
1803 Thus we don't need the G-type insns to implement bswap16_i64. */
1804 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1805 tcg_out_sh32(s, RS_SRL, args[0], TCG_REG_NONE, 16);
1806 break;
1807 OP_32_64(bswap32):
1808 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1809 break;
1811 case INDEX_op_add2_i32:
1812 /* ??? Make use of ALFI. */
1813 tcg_out_insn(s, RR, ALR, args[0], args[4]);
1814 tcg_out_insn(s, RRE, ALCR, args[1], args[5]);
1815 break;
1816 case INDEX_op_sub2_i32:
1817 /* ??? Make use of SLFI. */
1818 tcg_out_insn(s, RR, SLR, args[0], args[4]);
1819 tcg_out_insn(s, RRE, SLBR, args[1], args[5]);
1820 break;
1822 case INDEX_op_br:
1823 tgen_branch(s, S390_CC_ALWAYS, args[0]);
1824 break;
1826 case INDEX_op_brcond_i32:
1827 tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
1828 args[1], const_args[1], args[3]);
1829 break;
1830 case INDEX_op_setcond_i32:
1831 tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
1832 args[2], const_args[2]);
1833 break;
1834 case INDEX_op_movcond_i32:
1835 tgen_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1],
1836 args[2], const_args[2], args[3]);
1837 break;
1839 case INDEX_op_qemu_ld8u:
1840 tcg_out_qemu_ld(s, args, LD_UINT8);
1841 break;
1842 case INDEX_op_qemu_ld8s:
1843 tcg_out_qemu_ld(s, args, LD_INT8);
1844 break;
1845 case INDEX_op_qemu_ld16u:
1846 tcg_out_qemu_ld(s, args, LD_UINT16);
1847 break;
1848 case INDEX_op_qemu_ld16s:
1849 tcg_out_qemu_ld(s, args, LD_INT16);
1850 break;
1851 case INDEX_op_qemu_ld32:
1852 /* ??? Technically we can use a non-extending instruction. */
1853 tcg_out_qemu_ld(s, args, LD_UINT32);
1854 break;
1855 case INDEX_op_qemu_ld64:
1856 tcg_out_qemu_ld(s, args, LD_UINT64);
1857 break;
1859 case INDEX_op_qemu_st8:
1860 tcg_out_qemu_st(s, args, LD_UINT8);
1861 break;
1862 case INDEX_op_qemu_st16:
1863 tcg_out_qemu_st(s, args, LD_UINT16);
1864 break;
1865 case INDEX_op_qemu_st32:
1866 tcg_out_qemu_st(s, args, LD_UINT32);
1867 break;
1868 case INDEX_op_qemu_st64:
1869 tcg_out_qemu_st(s, args, LD_UINT64);
1870 break;
1872 case INDEX_op_mov_i64:
1873 tcg_out_mov(s, TCG_TYPE_I64, args[0], args[1]);
1874 break;
1875 case INDEX_op_movi_i64:
1876 tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
1877 break;
1879 case INDEX_op_ld16s_i64:
1880 tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
1881 break;
1882 case INDEX_op_ld32u_i64:
1883 tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
1884 break;
1885 case INDEX_op_ld32s_i64:
1886 tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
1887 break;
1888 case INDEX_op_ld_i64:
1889 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1890 break;
1892 case INDEX_op_st32_i64:
1893 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1894 break;
1895 case INDEX_op_st_i64:
1896 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1897 break;
1899 case INDEX_op_add_i64:
1900 a0 = args[0], a1 = args[1], a2 = args[2];
1901 if (const_args[2]) {
1902 do_addi_64:
1903 if (a0 == a1) {
1904 if (a2 == (int16_t)a2) {
1905 tcg_out_insn(s, RI, AGHI, a0, a2);
1906 break;
1908 if (facilities & FACILITY_EXT_IMM) {
1909 if (a2 == (int32_t)a2) {
1910 tcg_out_insn(s, RIL, AGFI, a0, a2);
1911 break;
1912 } else if (a2 == (uint32_t)a2) {
1913 tcg_out_insn(s, RIL, ALGFI, a0, a2);
1914 break;
1915 } else if (-a2 == (uint32_t)-a2) {
1916 tcg_out_insn(s, RIL, SLGFI, a0, -a2);
1917 break;
1921 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
1922 } else if (a0 == a1) {
1923 tcg_out_insn(s, RRE, AGR, a0, a2);
1924 } else {
1925 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
1927 break;
1928 case INDEX_op_sub_i64:
1929 a0 = args[0], a1 = args[1], a2 = args[2];
1930 if (const_args[2]) {
1931 a2 = -a2;
1932 goto do_addi_64;
1933 } else {
1934 tcg_out_insn(s, RRE, SGR, args[0], args[2]);
1936 break;
1938 case INDEX_op_and_i64:
1939 if (const_args[2]) {
1940 tgen_andi(s, TCG_TYPE_I64, args[0], args[2]);
1941 } else {
1942 tcg_out_insn(s, RRE, NGR, args[0], args[2]);
1944 break;
1945 case INDEX_op_or_i64:
1946 if (const_args[2]) {
1947 tgen64_ori(s, args[0], args[2]);
1948 } else {
1949 tcg_out_insn(s, RRE, OGR, args[0], args[2]);
1951 break;
1952 case INDEX_op_xor_i64:
1953 if (const_args[2]) {
1954 tgen64_xori(s, args[0], args[2]);
1955 } else {
1956 tcg_out_insn(s, RRE, XGR, args[0], args[2]);
1958 break;
1960 case INDEX_op_neg_i64:
1961 tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
1962 break;
1963 case INDEX_op_bswap64_i64:
1964 tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
1965 break;
1967 case INDEX_op_mul_i64:
1968 if (const_args[2]) {
1969 if (args[2] == (int16_t)args[2]) {
1970 tcg_out_insn(s, RI, MGHI, args[0], args[2]);
1971 } else {
1972 tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
1974 } else {
1975 tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
1977 break;
1979 case INDEX_op_div2_i64:
1980 /* ??? We get an unnecessary sign-extension of the dividend
1981 into R3 with this definition, but as we do in fact always
1982 produce both quotient and remainder using INDEX_op_div_i64
1983 instead requires jumping through even more hoops. */
1984 tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
1985 break;
1986 case INDEX_op_divu2_i64:
1987 tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
1988 break;
1989 case INDEX_op_mulu2_i64:
1990 tcg_out_insn(s, RRE, MLGR, TCG_REG_R2, args[3]);
1991 break;
1993 case INDEX_op_shl_i64:
1994 op = RSY_SLLG;
1995 do_shift64:
1996 if (const_args[2]) {
1997 tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
1998 } else {
1999 tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
2001 break;
2002 case INDEX_op_shr_i64:
2003 op = RSY_SRLG;
2004 goto do_shift64;
2005 case INDEX_op_sar_i64:
2006 op = RSY_SRAG;
2007 goto do_shift64;
2009 case INDEX_op_rotl_i64:
2010 if (const_args[2]) {
2011 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2012 TCG_REG_NONE, args[2]);
2013 } else {
2014 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
2016 break;
2017 case INDEX_op_rotr_i64:
2018 if (const_args[2]) {
2019 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2020 TCG_REG_NONE, (64 - args[2]) & 63);
2021 } else {
2022 /* We can use the smaller 32-bit negate because only the
2023 low 6 bits are examined for the rotate. */
2024 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2025 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
2027 break;
2029 case INDEX_op_ext8s_i64:
2030 tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
2031 break;
2032 case INDEX_op_ext16s_i64:
2033 tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
2034 break;
2035 case INDEX_op_ext32s_i64:
2036 tgen_ext32s(s, args[0], args[1]);
2037 break;
2038 case INDEX_op_ext8u_i64:
2039 tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
2040 break;
2041 case INDEX_op_ext16u_i64:
2042 tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
2043 break;
2044 case INDEX_op_ext32u_i64:
2045 tgen_ext32u(s, args[0], args[1]);
2046 break;
2048 case INDEX_op_add2_i64:
2049 /* ??? Make use of ALGFI and SLGFI. */
2050 tcg_out_insn(s, RRE, ALGR, args[0], args[4]);
2051 tcg_out_insn(s, RRE, ALCGR, args[1], args[5]);
2052 break;
2053 case INDEX_op_sub2_i64:
2054 /* ??? Make use of ALGFI and SLGFI. */
2055 tcg_out_insn(s, RRE, SLGR, args[0], args[4]);
2056 tcg_out_insn(s, RRE, SLBGR, args[1], args[5]);
2057 break;
2059 case INDEX_op_brcond_i64:
2060 tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
2061 args[1], const_args[1], args[3]);
2062 break;
2063 case INDEX_op_setcond_i64:
2064 tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2065 args[2], const_args[2]);
2066 break;
2067 case INDEX_op_movcond_i64:
2068 tgen_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1],
2069 args[2], const_args[2], args[3]);
2070 break;
2072 case INDEX_op_qemu_ld32u:
2073 tcg_out_qemu_ld(s, args, LD_UINT32);
2074 break;
2075 case INDEX_op_qemu_ld32s:
2076 tcg_out_qemu_ld(s, args, LD_INT32);
2077 break;
2079 OP_32_64(deposit):
2080 tgen_deposit(s, args[0], args[2], args[3], args[4]);
2081 break;
2083 default:
2084 fprintf(stderr,"unimplemented opc 0x%x\n",opc);
2085 tcg_abort();
2089 static const TCGTargetOpDef s390_op_defs[] = {
2090 { INDEX_op_exit_tb, { } },
2091 { INDEX_op_goto_tb, { } },
2092 { INDEX_op_call, { "ri" } },
2093 { INDEX_op_br, { } },
2095 { INDEX_op_mov_i32, { "r", "r" } },
2096 { INDEX_op_movi_i32, { "r" } },
2098 { INDEX_op_ld8u_i32, { "r", "r" } },
2099 { INDEX_op_ld8s_i32, { "r", "r" } },
2100 { INDEX_op_ld16u_i32, { "r", "r" } },
2101 { INDEX_op_ld16s_i32, { "r", "r" } },
2102 { INDEX_op_ld_i32, { "r", "r" } },
2103 { INDEX_op_st8_i32, { "r", "r" } },
2104 { INDEX_op_st16_i32, { "r", "r" } },
2105 { INDEX_op_st_i32, { "r", "r" } },
2107 { INDEX_op_add_i32, { "r", "r", "ri" } },
2108 { INDEX_op_sub_i32, { "r", "0", "ri" } },
2109 { INDEX_op_mul_i32, { "r", "0", "rK" } },
2111 { INDEX_op_div2_i32, { "b", "a", "0", "1", "r" } },
2112 { INDEX_op_divu2_i32, { "b", "a", "0", "1", "r" } },
2114 { INDEX_op_and_i32, { "r", "0", "ri" } },
2115 { INDEX_op_or_i32, { "r", "0", "rWO" } },
2116 { INDEX_op_xor_i32, { "r", "0", "rWX" } },
2118 { INDEX_op_neg_i32, { "r", "r" } },
2120 { INDEX_op_shl_i32, { "r", "0", "Ri" } },
2121 { INDEX_op_shr_i32, { "r", "0", "Ri" } },
2122 { INDEX_op_sar_i32, { "r", "0", "Ri" } },
2124 { INDEX_op_rotl_i32, { "r", "r", "Ri" } },
2125 { INDEX_op_rotr_i32, { "r", "r", "Ri" } },
2127 { INDEX_op_ext8s_i32, { "r", "r" } },
2128 { INDEX_op_ext8u_i32, { "r", "r" } },
2129 { INDEX_op_ext16s_i32, { "r", "r" } },
2130 { INDEX_op_ext16u_i32, { "r", "r" } },
2132 { INDEX_op_bswap16_i32, { "r", "r" } },
2133 { INDEX_op_bswap32_i32, { "r", "r" } },
2135 { INDEX_op_add2_i32, { "r", "r", "0", "1", "r", "r" } },
2136 { INDEX_op_sub2_i32, { "r", "r", "0", "1", "r", "r" } },
2138 { INDEX_op_brcond_i32, { "r", "rWC" } },
2139 { INDEX_op_setcond_i32, { "r", "r", "rWC" } },
2140 { INDEX_op_movcond_i32, { "r", "r", "rWC", "r", "0" } },
2141 { INDEX_op_deposit_i32, { "r", "0", "r" } },
2143 { INDEX_op_qemu_ld8u, { "r", "L" } },
2144 { INDEX_op_qemu_ld8s, { "r", "L" } },
2145 { INDEX_op_qemu_ld16u, { "r", "L" } },
2146 { INDEX_op_qemu_ld16s, { "r", "L" } },
2147 { INDEX_op_qemu_ld32, { "r", "L" } },
2148 { INDEX_op_qemu_ld64, { "r", "L" } },
2150 { INDEX_op_qemu_st8, { "L", "L" } },
2151 { INDEX_op_qemu_st16, { "L", "L" } },
2152 { INDEX_op_qemu_st32, { "L", "L" } },
2153 { INDEX_op_qemu_st64, { "L", "L" } },
2155 { INDEX_op_mov_i64, { "r", "r" } },
2156 { INDEX_op_movi_i64, { "r" } },
2158 { INDEX_op_ld8u_i64, { "r", "r" } },
2159 { INDEX_op_ld8s_i64, { "r", "r" } },
2160 { INDEX_op_ld16u_i64, { "r", "r" } },
2161 { INDEX_op_ld16s_i64, { "r", "r" } },
2162 { INDEX_op_ld32u_i64, { "r", "r" } },
2163 { INDEX_op_ld32s_i64, { "r", "r" } },
2164 { INDEX_op_ld_i64, { "r", "r" } },
2166 { INDEX_op_st8_i64, { "r", "r" } },
2167 { INDEX_op_st16_i64, { "r", "r" } },
2168 { INDEX_op_st32_i64, { "r", "r" } },
2169 { INDEX_op_st_i64, { "r", "r" } },
2171 { INDEX_op_add_i64, { "r", "r", "ri" } },
2172 { INDEX_op_sub_i64, { "r", "0", "ri" } },
2173 { INDEX_op_mul_i64, { "r", "0", "rK" } },
2175 { INDEX_op_div2_i64, { "b", "a", "0", "1", "r" } },
2176 { INDEX_op_divu2_i64, { "b", "a", "0", "1", "r" } },
2177 { INDEX_op_mulu2_i64, { "b", "a", "0", "r" } },
2179 { INDEX_op_and_i64, { "r", "0", "ri" } },
2180 { INDEX_op_or_i64, { "r", "0", "rO" } },
2181 { INDEX_op_xor_i64, { "r", "0", "rX" } },
2183 { INDEX_op_neg_i64, { "r", "r" } },
2185 { INDEX_op_shl_i64, { "r", "r", "Ri" } },
2186 { INDEX_op_shr_i64, { "r", "r", "Ri" } },
2187 { INDEX_op_sar_i64, { "r", "r", "Ri" } },
2189 { INDEX_op_rotl_i64, { "r", "r", "Ri" } },
2190 { INDEX_op_rotr_i64, { "r", "r", "Ri" } },
2192 { INDEX_op_ext8s_i64, { "r", "r" } },
2193 { INDEX_op_ext8u_i64, { "r", "r" } },
2194 { INDEX_op_ext16s_i64, { "r", "r" } },
2195 { INDEX_op_ext16u_i64, { "r", "r" } },
2196 { INDEX_op_ext32s_i64, { "r", "r" } },
2197 { INDEX_op_ext32u_i64, { "r", "r" } },
2199 { INDEX_op_bswap16_i64, { "r", "r" } },
2200 { INDEX_op_bswap32_i64, { "r", "r" } },
2201 { INDEX_op_bswap64_i64, { "r", "r" } },
2203 { INDEX_op_add2_i64, { "r", "r", "0", "1", "r", "r" } },
2204 { INDEX_op_sub2_i64, { "r", "r", "0", "1", "r", "r" } },
2206 { INDEX_op_brcond_i64, { "r", "rC" } },
2207 { INDEX_op_setcond_i64, { "r", "r", "rC" } },
2208 { INDEX_op_movcond_i64, { "r", "r", "rC", "r", "0" } },
2209 { INDEX_op_deposit_i64, { "r", "0", "r" } },
2211 { INDEX_op_qemu_ld32u, { "r", "L" } },
2212 { INDEX_op_qemu_ld32s, { "r", "L" } },
2214 { -1 },
2217 static void query_facilities(void)
2219 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2221 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
2222 is present on all 64-bit systems, but let's check for it anyway. */
2223 if (hwcap & HWCAP_S390_STFLE) {
2224 register int r0 __asm__("0");
2225 register void *r1 __asm__("1");
2227 /* stfle 0(%r1) */
2228 r1 = &facilities;
2229 asm volatile(".word 0xb2b0,0x1000"
2230 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
2234 static void tcg_target_init(TCGContext *s)
2236 query_facilities();
2238 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
2239 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
2241 tcg_regset_clear(tcg_target_call_clobber_regs);
2242 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2243 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
2244 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2245 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2246 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
2247 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
2248 /* The return register can be considered call-clobbered. */
2249 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2251 tcg_regset_clear(s->reserved_regs);
2252 tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
2253 /* XXX many insns can't be used with R0, so we better avoid it for now */
2254 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
2255 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2257 tcg_add_target_add_op_defs(s390_op_defs);
2260 static void tcg_target_qemu_prologue(TCGContext *s)
2262 tcg_target_long frame_size;
2264 /* stmg %r6,%r15,48(%r15) (save registers) */
2265 tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
2267 /* aghi %r15,-frame_size */
2268 frame_size = TCG_TARGET_CALL_STACK_OFFSET;
2269 frame_size += TCG_STATIC_CALL_ARGS_SIZE;
2270 frame_size += CPU_TEMP_BUF_NLONGS * sizeof(long);
2271 tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -frame_size);
2273 tcg_set_frame(s, TCG_REG_CALL_STACK,
2274 TCG_STATIC_CALL_ARGS_SIZE + TCG_TARGET_CALL_STACK_OFFSET,
2275 CPU_TEMP_BUF_NLONGS * sizeof(long));
2277 if (GUEST_BASE >= 0x80000) {
2278 tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
2279 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2282 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2283 /* br %r3 (go to TB) */
2284 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
2286 tb_ret_addr = s->code_ptr;
2288 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2289 tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15,
2290 frame_size + 48);
2292 /* br %r14 (return) */
2293 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);