|
|
1.1 root 1: /*
2: * Tiny Code Generator for QEMU
3: *
4: * Copyright (c) 2009 Ulrich Hecht <[email protected]>
1.1.1.2 root 5: * Copyright (c) 2009 Alexander Graf <[email protected]>
6: * Copyright (c) 2010 Richard Henderson <[email protected]>
1.1 root 7: *
8: * Permission is hereby granted, free of charge, to any person obtaining a copy
9: * of this software and associated documentation files (the "Software"), to deal
10: * in the Software without restriction, including without limitation the rights
11: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12: * copies of the Software, and to permit persons to whom the Software is
13: * furnished to do so, subject to the following conditions:
14: *
15: * The above copyright notice and this permission notice shall be included in
16: * all copies or substantial portions of the Software.
17: *
18: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24: * THE SOFTWARE.
25: */
26:
1.1.1.2 root 27: /* ??? The translation blocks produced by TCG are generally small enough to
28: be entirely reachable with a 16-bit displacement. Leaving the option for
29: a 32-bit displacement here Just In Case. */
30: #define USE_LONG_BRANCHES 0
31:
32: #define TCG_CT_CONST_32 0x0100
33: #define TCG_CT_CONST_NEG 0x0200
34: #define TCG_CT_CONST_ADDI 0x0400
35: #define TCG_CT_CONST_MULI 0x0800
36: #define TCG_CT_CONST_ANDI 0x1000
37: #define TCG_CT_CONST_ORI 0x2000
38: #define TCG_CT_CONST_XORI 0x4000
39: #define TCG_CT_CONST_CMPI 0x8000
40:
41: /* Several places within the instruction set 0 means "no register"
42: rather than TCG_REG_R0. */
43: #define TCG_REG_NONE 0
44:
45: /* A scratch register that may be be used throughout the backend. */
46: #define TCG_TMP0 TCG_REG_R14
47:
48: #ifdef CONFIG_USE_GUEST_BASE
49: #define TCG_GUEST_BASE_REG TCG_REG_R13
50: #else
51: #define TCG_GUEST_BASE_REG TCG_REG_R0
52: #endif
53:
54: #ifndef GUEST_BASE
55: #define GUEST_BASE 0
56: #endif
57:
58:
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_ALGFI = 0xc20a,
67: RIL_BRASL = 0xc005,
68: RIL_BRCL = 0xc004,
69: RIL_CFI = 0xc20d,
70: RIL_CGFI = 0xc20c,
71: RIL_CLFI = 0xc20f,
72: RIL_CLGFI = 0xc20e,
73: RIL_IIHF = 0xc008,
74: RIL_IILF = 0xc009,
75: RIL_LARL = 0xc000,
76: RIL_LGFI = 0xc001,
77: RIL_LGRL = 0xc408,
78: RIL_LLIHF = 0xc00e,
79: RIL_LLILF = 0xc00f,
80: RIL_LRL = 0xc40d,
81: RIL_MSFI = 0xc201,
82: RIL_MSGFI = 0xc200,
83: RIL_NIHF = 0xc00a,
84: RIL_NILF = 0xc00b,
85: RIL_OIHF = 0xc00c,
86: RIL_OILF = 0xc00d,
87: RIL_XIHF = 0xc006,
88: RIL_XILF = 0xc007,
89:
90: RI_AGHI = 0xa70b,
91: RI_AHI = 0xa70a,
92: RI_BRC = 0xa704,
93: RI_IIHH = 0xa500,
94: RI_IIHL = 0xa501,
95: RI_IILH = 0xa502,
96: RI_IILL = 0xa503,
97: RI_LGHI = 0xa709,
98: RI_LLIHH = 0xa50c,
99: RI_LLIHL = 0xa50d,
100: RI_LLILH = 0xa50e,
101: RI_LLILL = 0xa50f,
102: RI_MGHI = 0xa70d,
103: RI_MHI = 0xa70c,
104: RI_NIHH = 0xa504,
105: RI_NIHL = 0xa505,
106: RI_NILH = 0xa506,
107: RI_NILL = 0xa507,
108: RI_OIHH = 0xa508,
109: RI_OIHL = 0xa509,
110: RI_OILH = 0xa50a,
111: RI_OILL = 0xa50b,
112:
113: RIE_CGIJ = 0xec7c,
114: RIE_CGRJ = 0xec64,
115: RIE_CIJ = 0xec7e,
116: RIE_CLGRJ = 0xec65,
117: RIE_CLIJ = 0xec7f,
118: RIE_CLGIJ = 0xec7d,
119: RIE_CLRJ = 0xec77,
120: RIE_CRJ = 0xec76,
121:
122: RRE_AGR = 0xb908,
123: RRE_CGR = 0xb920,
124: RRE_CLGR = 0xb921,
125: RRE_DLGR = 0xb987,
126: RRE_DLR = 0xb997,
127: RRE_DSGFR = 0xb91d,
128: RRE_DSGR = 0xb90d,
129: RRE_LGBR = 0xb906,
130: RRE_LCGR = 0xb903,
131: RRE_LGFR = 0xb914,
132: RRE_LGHR = 0xb907,
133: RRE_LGR = 0xb904,
134: RRE_LLGCR = 0xb984,
135: RRE_LLGFR = 0xb916,
136: RRE_LLGHR = 0xb985,
137: RRE_LRVR = 0xb91f,
138: RRE_LRVGR = 0xb90f,
139: RRE_LTGR = 0xb902,
140: RRE_MSGR = 0xb90c,
141: RRE_MSR = 0xb252,
142: RRE_NGR = 0xb980,
143: RRE_OGR = 0xb981,
144: RRE_SGR = 0xb909,
145: RRE_XGR = 0xb982,
146:
147: RR_AR = 0x1a,
148: RR_BASR = 0x0d,
149: RR_BCR = 0x07,
150: RR_CLR = 0x15,
151: RR_CR = 0x19,
152: RR_DR = 0x1d,
153: RR_LCR = 0x13,
154: RR_LR = 0x18,
155: RR_LTR = 0x12,
156: RR_NR = 0x14,
157: RR_OR = 0x16,
158: RR_SR = 0x1b,
159: RR_XR = 0x17,
160:
161: RSY_RLL = 0xeb1d,
162: RSY_RLLG = 0xeb1c,
163: RSY_SLLG = 0xeb0d,
164: RSY_SRAG = 0xeb0a,
165: RSY_SRLG = 0xeb0c,
166:
167: RS_SLL = 0x89,
168: RS_SRA = 0x8a,
169: RS_SRL = 0x88,
170:
171: RXY_AG = 0xe308,
172: RXY_AY = 0xe35a,
173: RXY_CG = 0xe320,
174: RXY_CY = 0xe359,
175: RXY_LB = 0xe376,
176: RXY_LG = 0xe304,
177: RXY_LGB = 0xe377,
178: RXY_LGF = 0xe314,
179: RXY_LGH = 0xe315,
180: RXY_LHY = 0xe378,
181: RXY_LLGC = 0xe390,
182: RXY_LLGF = 0xe316,
183: RXY_LLGH = 0xe391,
184: RXY_LMG = 0xeb04,
185: RXY_LRV = 0xe31e,
186: RXY_LRVG = 0xe30f,
187: RXY_LRVH = 0xe31f,
188: RXY_LY = 0xe358,
189: RXY_STCY = 0xe372,
190: RXY_STG = 0xe324,
191: RXY_STHY = 0xe370,
192: RXY_STMG = 0xeb24,
193: RXY_STRV = 0xe33e,
194: RXY_STRVG = 0xe32f,
195: RXY_STRVH = 0xe33f,
196: RXY_STY = 0xe350,
197:
198: RX_A = 0x5a,
199: RX_C = 0x59,
200: RX_L = 0x58,
201: RX_LH = 0x48,
202: RX_ST = 0x50,
203: RX_STC = 0x42,
204: RX_STH = 0x40,
205: } S390Opcode;
206:
207: #define LD_SIGNED 0x04
208: #define LD_UINT8 0x00
209: #define LD_INT8 (LD_UINT8 | LD_SIGNED)
210: #define LD_UINT16 0x01
211: #define LD_INT16 (LD_UINT16 | LD_SIGNED)
212: #define LD_UINT32 0x02
213: #define LD_INT32 (LD_UINT32 | LD_SIGNED)
214: #define LD_UINT64 0x03
215: #define LD_INT64 (LD_UINT64 | LD_SIGNED)
216:
217: #ifndef NDEBUG
218: static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
219: "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
220: "%r8", "%r9", "%r10" "%r11" "%r12" "%r13" "%r14" "%r15"
221: };
222: #endif
223:
224: /* Since R6 is a potential argument register, choose it last of the
225: call-saved registers. Likewise prefer the call-clobbered registers
226: in reverse order to maximize the chance of avoiding the arguments. */
1.1 root 227: static const int tcg_target_reg_alloc_order[] = {
1.1.1.2 root 228: TCG_REG_R13,
229: TCG_REG_R12,
230: TCG_REG_R11,
231: TCG_REG_R10,
232: TCG_REG_R9,
233: TCG_REG_R8,
234: TCG_REG_R7,
235: TCG_REG_R6,
236: TCG_REG_R14,
237: TCG_REG_R0,
238: TCG_REG_R1,
239: TCG_REG_R5,
240: TCG_REG_R4,
241: TCG_REG_R3,
242: TCG_REG_R2,
1.1 root 243: };
244:
245: static const int tcg_target_call_iarg_regs[] = {
1.1.1.2 root 246: TCG_REG_R2,
247: TCG_REG_R3,
248: TCG_REG_R4,
249: TCG_REG_R5,
250: TCG_REG_R6,
1.1 root 251: };
252:
253: static const int tcg_target_call_oarg_regs[] = {
1.1.1.2 root 254: TCG_REG_R2,
1.1.1.4 ! root 255: #if TCG_TARGET_REG_BITS == 32
! 256: TCG_REG_R3
! 257: #endif
1.1.1.2 root 258: };
259:
260: #define S390_CC_EQ 8
261: #define S390_CC_LT 4
262: #define S390_CC_GT 2
263: #define S390_CC_OV 1
264: #define S390_CC_NE (S390_CC_LT | S390_CC_GT)
265: #define S390_CC_LE (S390_CC_LT | S390_CC_EQ)
266: #define S390_CC_GE (S390_CC_GT | S390_CC_EQ)
267: #define S390_CC_NEVER 0
268: #define S390_CC_ALWAYS 15
269:
270: /* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
271: static const uint8_t tcg_cond_to_s390_cond[10] = {
272: [TCG_COND_EQ] = S390_CC_EQ,
273: [TCG_COND_NE] = S390_CC_NE,
274: [TCG_COND_LT] = S390_CC_LT,
275: [TCG_COND_LE] = S390_CC_LE,
276: [TCG_COND_GT] = S390_CC_GT,
277: [TCG_COND_GE] = S390_CC_GE,
278: [TCG_COND_LTU] = S390_CC_LT,
279: [TCG_COND_LEU] = S390_CC_LE,
280: [TCG_COND_GTU] = S390_CC_GT,
281: [TCG_COND_GEU] = S390_CC_GE,
282: };
283:
284: /* Condition codes that result from a LOAD AND TEST. Here, we have no
285: unsigned instruction variation, however since the test is vs zero we
286: can re-map the outcomes appropriately. */
287: static const uint8_t tcg_cond_to_ltr_cond[10] = {
288: [TCG_COND_EQ] = S390_CC_EQ,
289: [TCG_COND_NE] = S390_CC_NE,
290: [TCG_COND_LT] = S390_CC_LT,
291: [TCG_COND_LE] = S390_CC_LE,
292: [TCG_COND_GT] = S390_CC_GT,
293: [TCG_COND_GE] = S390_CC_GE,
294: [TCG_COND_LTU] = S390_CC_NEVER,
295: [TCG_COND_LEU] = S390_CC_EQ,
296: [TCG_COND_GTU] = S390_CC_NE,
297: [TCG_COND_GEU] = S390_CC_ALWAYS,
298: };
299:
300: #ifdef CONFIG_SOFTMMU
301:
302: #include "../../softmmu_defs.h"
303:
304: static void *qemu_ld_helpers[4] = {
305: __ldb_mmu,
306: __ldw_mmu,
307: __ldl_mmu,
308: __ldq_mmu,
309: };
310:
311: static void *qemu_st_helpers[4] = {
312: __stb_mmu,
313: __stw_mmu,
314: __stl_mmu,
315: __stq_mmu,
1.1 root 316: };
1.1.1.2 root 317: #endif
318:
319: static uint8_t *tb_ret_addr;
320:
321: /* A list of relevant facilities used by this translator. Some of these
322: are required for proper operation, and these are checked at startup. */
323:
324: #define FACILITY_ZARCH_ACTIVE (1ULL << (63 - 2))
325: #define FACILITY_LONG_DISP (1ULL << (63 - 18))
326: #define FACILITY_EXT_IMM (1ULL << (63 - 21))
327: #define FACILITY_GEN_INST_EXT (1ULL << (63 - 34))
328:
329: static uint64_t facilities;
1.1 root 330:
331: static void patch_reloc(uint8_t *code_ptr, int type,
1.1.1.2 root 332: tcg_target_long value, tcg_target_long addend)
1.1 root 333: {
1.1.1.2 root 334: tcg_target_long code_ptr_tl = (tcg_target_long)code_ptr;
335: tcg_target_long pcrel2;
336:
337: /* ??? Not the usual definition of "addend". */
338: pcrel2 = (value - (code_ptr_tl + addend)) >> 1;
339:
340: switch (type) {
341: case R_390_PC16DBL:
342: assert(pcrel2 == (int16_t)pcrel2);
343: *(int16_t *)code_ptr = pcrel2;
344: break;
345: case R_390_PC32DBL:
346: assert(pcrel2 == (int32_t)pcrel2);
347: *(int32_t *)code_ptr = pcrel2;
348: break;
349: default:
350: tcg_abort();
351: break;
352: }
1.1 root 353: }
354:
1.1.1.2 root 355: static int tcg_target_get_call_iarg_regs_count(int flags)
1.1 root 356: {
1.1.1.2 root 357: return sizeof(tcg_target_call_iarg_regs) / sizeof(int);
1.1 root 358: }
359:
360: /* parse target specific constraints */
361: static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
362: {
1.1.1.2 root 363: const char *ct_str = *pct_str;
364:
365: switch (ct_str[0]) {
366: case 'r': /* all registers */
367: ct->ct |= TCG_CT_REG;
368: tcg_regset_set32(ct->u.regs, 0, 0xffff);
369: break;
370: case 'R': /* not R0 */
371: ct->ct |= TCG_CT_REG;
372: tcg_regset_set32(ct->u.regs, 0, 0xffff);
373: tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
374: break;
375: case 'L': /* qemu_ld/st constraint */
376: ct->ct |= TCG_CT_REG;
377: tcg_regset_set32(ct->u.regs, 0, 0xffff);
378: tcg_regset_reset_reg (ct->u.regs, TCG_REG_R2);
379: tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
380: break;
381: case 'a': /* force R2 for division */
382: ct->ct |= TCG_CT_REG;
383: tcg_regset_clear(ct->u.regs);
384: tcg_regset_set_reg(ct->u.regs, TCG_REG_R2);
385: break;
386: case 'b': /* force R3 for division */
387: ct->ct |= TCG_CT_REG;
388: tcg_regset_clear(ct->u.regs);
389: tcg_regset_set_reg(ct->u.regs, TCG_REG_R3);
390: break;
391: case 'N': /* force immediate negate */
392: ct->ct |= TCG_CT_CONST_NEG;
393: break;
394: case 'W': /* force 32-bit ("word") immediate */
395: ct->ct |= TCG_CT_CONST_32;
396: break;
397: case 'I':
398: ct->ct |= TCG_CT_CONST_ADDI;
399: break;
400: case 'K':
401: ct->ct |= TCG_CT_CONST_MULI;
402: break;
403: case 'A':
404: ct->ct |= TCG_CT_CONST_ANDI;
405: break;
406: case 'O':
407: ct->ct |= TCG_CT_CONST_ORI;
408: break;
409: case 'X':
410: ct->ct |= TCG_CT_CONST_XORI;
411: break;
412: case 'C':
413: ct->ct |= TCG_CT_CONST_CMPI;
414: break;
415: default:
416: return -1;
417: }
418: ct_str++;
419: *pct_str = ct_str;
420:
1.1 root 421: return 0;
422: }
423:
1.1.1.2 root 424: /* Immediates to be used with logical AND. This is an optimization only,
425: since a full 64-bit immediate AND can always be performed with 4 sequential
426: NI[LH][LH] instructions. What we're looking for is immediates that we
427: can load efficiently, and the immediate load plus the reg-reg AND is
428: smaller than the sequential NI's. */
429:
430: static int tcg_match_andi(int ct, tcg_target_ulong val)
431: {
432: int i;
433:
434: if (facilities & FACILITY_EXT_IMM) {
435: if (ct & TCG_CT_CONST_32) {
436: /* All 32-bit ANDs can be performed with 1 48-bit insn. */
437: return 1;
438: }
439:
440: /* Zero-extensions. */
441: if (val == 0xff || val == 0xffff || val == 0xffffffff) {
442: return 1;
443: }
444: } else {
445: if (ct & TCG_CT_CONST_32) {
446: val = (uint32_t)val;
447: } else if (val == 0xffffffff) {
448: return 1;
449: }
450: }
451:
452: /* Try all 32-bit insns that can perform it in one go. */
453: for (i = 0; i < 4; i++) {
454: tcg_target_ulong mask = ~(0xffffull << i*16);
455: if ((val & mask) == mask) {
456: return 1;
457: }
458: }
459:
460: /* Look for 16-bit values performing the mask. These are better
461: to load with LLI[LH][LH]. */
462: for (i = 0; i < 4; i++) {
463: tcg_target_ulong mask = 0xffffull << i*16;
464: if ((val & mask) == val) {
465: return 0;
466: }
467: }
468:
469: /* Look for 32-bit values performing the 64-bit mask. These
470: are better to load with LLI[LH]F, or if extended immediates
471: not available, with a pair of LLI insns. */
472: if ((ct & TCG_CT_CONST_32) == 0) {
473: if (val <= 0xffffffff || (val & 0xffffffff) == 0) {
474: return 0;
475: }
476: }
477:
478: return 1;
479: }
480:
481: /* Immediates to be used with logical OR. This is an optimization only,
482: since a full 64-bit immediate OR can always be performed with 4 sequential
483: OI[LH][LH] instructions. What we're looking for is immediates that we
484: can load efficiently, and the immediate load plus the reg-reg OR is
485: smaller than the sequential OI's. */
486:
487: static int tcg_match_ori(int ct, tcg_target_long val)
488: {
489: if (facilities & FACILITY_EXT_IMM) {
490: if (ct & TCG_CT_CONST_32) {
491: /* All 32-bit ORs can be performed with 1 48-bit insn. */
492: return 1;
493: }
494: }
495:
496: /* Look for negative values. These are best to load with LGHI. */
497: if (val < 0) {
498: if (val == (int16_t)val) {
499: return 0;
500: }
501: if (facilities & FACILITY_EXT_IMM) {
502: if (val == (int32_t)val) {
503: return 0;
504: }
505: }
506: }
507:
508: return 1;
509: }
510:
511: /* Immediates to be used with logical XOR. This is almost, but not quite,
512: only an optimization. XOR with immediate is only supported with the
513: extended-immediate facility. That said, there are a few patterns for
514: which it is better to load the value into a register first. */
515:
516: static int tcg_match_xori(int ct, tcg_target_long val)
517: {
518: if ((facilities & FACILITY_EXT_IMM) == 0) {
519: return 0;
520: }
521:
522: if (ct & TCG_CT_CONST_32) {
523: /* All 32-bit XORs can be performed with 1 48-bit insn. */
524: return 1;
525: }
526:
527: /* Look for negative values. These are best to load with LGHI. */
528: if (val < 0 && val == (int32_t)val) {
529: return 0;
530: }
531:
532: return 1;
533: }
534:
535: /* Imediates to be used with comparisons. */
536:
537: static int tcg_match_cmpi(int ct, tcg_target_long val)
538: {
539: if (facilities & FACILITY_EXT_IMM) {
540: /* The COMPARE IMMEDIATE instruction is available. */
541: if (ct & TCG_CT_CONST_32) {
542: /* We have a 32-bit immediate and can compare against anything. */
543: return 1;
544: } else {
545: /* ??? We have no insight here into whether the comparison is
546: signed or unsigned. The COMPARE IMMEDIATE insn uses a 32-bit
547: signed immediate, and the COMPARE LOGICAL IMMEDIATE insn uses
548: a 32-bit unsigned immediate. If we were to use the (semi)
549: obvious "val == (int32_t)val" we would be enabling unsigned
550: comparisons vs very large numbers. The only solution is to
551: take the intersection of the ranges. */
552: /* ??? Another possible solution is to simply lie and allow all
553: constants here and force the out-of-range values into a temp
554: register in tgen_cmp when we have knowledge of the actual
555: comparison code in use. */
556: return val >= 0 && val <= 0x7fffffff;
557: }
558: } else {
559: /* Only the LOAD AND TEST instruction is available. */
560: return val == 0;
561: }
562: }
563:
1.1 root 564: /* Test if a constant matches the constraint. */
1.1.1.2 root 565: static int tcg_target_const_match(tcg_target_long val,
566: const TCGArgConstraint *arg_ct)
1.1 root 567: {
1.1.1.2 root 568: int ct = arg_ct->ct;
569:
570: if (ct & TCG_CT_CONST) {
571: return 1;
572: }
573:
574: /* Handle the modifiers. */
575: if (ct & TCG_CT_CONST_NEG) {
576: val = -val;
577: }
578: if (ct & TCG_CT_CONST_32) {
579: val = (int32_t)val;
580: }
581:
582: /* The following are mutually exclusive. */
583: if (ct & TCG_CT_CONST_ADDI) {
584: /* Immediates that may be used with add. If we have the
585: extended-immediates facility then we have ADD IMMEDIATE
586: with signed and unsigned 32-bit, otherwise we have only
587: ADD HALFWORD IMMEDIATE with a signed 16-bit. */
588: if (facilities & FACILITY_EXT_IMM) {
589: return val == (int32_t)val || val == (uint32_t)val;
590: } else {
591: return val == (int16_t)val;
592: }
593: } else if (ct & TCG_CT_CONST_MULI) {
594: /* Immediates that may be used with multiply. If we have the
595: general-instruction-extensions, then we have MULTIPLY SINGLE
596: IMMEDIATE with a signed 32-bit, otherwise we have only
597: MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
598: if (facilities & FACILITY_GEN_INST_EXT) {
599: return val == (int32_t)val;
600: } else {
601: return val == (int16_t)val;
602: }
603: } else if (ct & TCG_CT_CONST_ANDI) {
604: return tcg_match_andi(ct, val);
605: } else if (ct & TCG_CT_CONST_ORI) {
606: return tcg_match_ori(ct, val);
607: } else if (ct & TCG_CT_CONST_XORI) {
608: return tcg_match_xori(ct, val);
609: } else if (ct & TCG_CT_CONST_CMPI) {
610: return tcg_match_cmpi(ct, val);
611: }
612:
1.1 root 613: return 0;
614: }
615:
1.1.1.2 root 616: /* Emit instructions according to the given instruction format. */
617:
618: static void tcg_out_insn_RR(TCGContext *s, S390Opcode op, TCGReg r1, TCGReg r2)
619: {
620: tcg_out16(s, (op << 8) | (r1 << 4) | r2);
621: }
622:
623: static void tcg_out_insn_RRE(TCGContext *s, S390Opcode op,
624: TCGReg r1, TCGReg r2)
625: {
626: tcg_out32(s, (op << 16) | (r1 << 4) | r2);
627: }
628:
629: static void tcg_out_insn_RI(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
630: {
631: tcg_out32(s, (op << 16) | (r1 << 20) | (i2 & 0xffff));
632: }
633:
634: static void tcg_out_insn_RIL(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
635: {
636: tcg_out16(s, op | (r1 << 4));
637: tcg_out32(s, i2);
638: }
639:
640: static void tcg_out_insn_RS(TCGContext *s, S390Opcode op, TCGReg r1,
641: TCGReg b2, TCGReg r3, int disp)
642: {
643: tcg_out32(s, (op << 24) | (r1 << 20) | (r3 << 16) | (b2 << 12)
644: | (disp & 0xfff));
645: }
646:
647: static void tcg_out_insn_RSY(TCGContext *s, S390Opcode op, TCGReg r1,
648: TCGReg b2, TCGReg r3, int disp)
649: {
650: tcg_out16(s, (op & 0xff00) | (r1 << 4) | r3);
651: tcg_out32(s, (op & 0xff) | (b2 << 28)
652: | ((disp & 0xfff) << 16) | ((disp & 0xff000) >> 4));
653: }
654:
655: #define tcg_out_insn_RX tcg_out_insn_RS
656: #define tcg_out_insn_RXY tcg_out_insn_RSY
657:
658: /* Emit an opcode with "type-checking" of the format. */
659: #define tcg_out_insn(S, FMT, OP, ...) \
660: glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
661:
662:
663: /* emit 64-bit shifts */
664: static void tcg_out_sh64(TCGContext* s, S390Opcode op, TCGReg dest,
665: TCGReg src, TCGReg sh_reg, int sh_imm)
666: {
667: tcg_out_insn_RSY(s, op, dest, sh_reg, src, sh_imm);
668: }
669:
670: /* emit 32-bit shifts */
671: static void tcg_out_sh32(TCGContext* s, S390Opcode op, TCGReg dest,
672: TCGReg sh_reg, int sh_imm)
673: {
674: tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
675: }
676:
677: static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
678: {
679: if (src != dst) {
680: if (type == TCG_TYPE_I32) {
681: tcg_out_insn(s, RR, LR, dst, src);
682: } else {
683: tcg_out_insn(s, RRE, LGR, dst, src);
684: }
685: }
686: }
687:
1.1 root 688: /* load a register with an immediate value */
1.1.1.2 root 689: static void tcg_out_movi(TCGContext *s, TCGType type,
690: TCGReg ret, tcg_target_long sval)
1.1 root 691: {
1.1.1.2 root 692: static const S390Opcode lli_insns[4] = {
693: RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
694: };
695:
696: tcg_target_ulong uval = sval;
697: int i;
698:
699: if (type == TCG_TYPE_I32) {
700: uval = (uint32_t)sval;
701: sval = (int32_t)sval;
702: }
703:
704: /* Try all 32-bit insns that can load it in one go. */
705: if (sval >= -0x8000 && sval < 0x8000) {
706: tcg_out_insn(s, RI, LGHI, ret, sval);
707: return;
708: }
709:
710: for (i = 0; i < 4; i++) {
711: tcg_target_long mask = 0xffffull << i*16;
712: if ((uval & mask) == uval) {
713: tcg_out_insn_RI(s, lli_insns[i], ret, uval >> i*16);
714: return;
715: }
716: }
717:
718: /* Try all 48-bit insns that can load it in one go. */
719: if (facilities & FACILITY_EXT_IMM) {
720: if (sval == (int32_t)sval) {
721: tcg_out_insn(s, RIL, LGFI, ret, sval);
722: return;
723: }
724: if (uval <= 0xffffffff) {
725: tcg_out_insn(s, RIL, LLILF, ret, uval);
726: return;
727: }
728: if ((uval & 0xffffffff) == 0) {
729: tcg_out_insn(s, RIL, LLIHF, ret, uval >> 31 >> 1);
730: return;
731: }
732: }
733:
734: /* Try for PC-relative address load. */
735: if ((sval & 1) == 0) {
736: intptr_t off = (sval - (intptr_t)s->code_ptr) >> 1;
737: if (off == (int32_t)off) {
738: tcg_out_insn(s, RIL, LARL, ret, off);
739: return;
740: }
741: }
742:
743: /* If extended immediates are not present, then we may have to issue
744: several instructions to load the low 32 bits. */
745: if (!(facilities & FACILITY_EXT_IMM)) {
746: /* A 32-bit unsigned value can be loaded in 2 insns. And given
747: that the lli_insns loop above did not succeed, we know that
748: both insns are required. */
749: if (uval <= 0xffffffff) {
750: tcg_out_insn(s, RI, LLILL, ret, uval);
751: tcg_out_insn(s, RI, IILH, ret, uval >> 16);
752: return;
753: }
754:
755: /* If all high bits are set, the value can be loaded in 2 or 3 insns.
756: We first want to make sure that all the high bits get set. With
757: luck the low 16-bits can be considered negative to perform that for
758: free, otherwise we load an explicit -1. */
759: if (sval >> 31 >> 1 == -1) {
760: if (uval & 0x8000) {
761: tcg_out_insn(s, RI, LGHI, ret, uval);
762: } else {
763: tcg_out_insn(s, RI, LGHI, ret, -1);
764: tcg_out_insn(s, RI, IILL, ret, uval);
765: }
766: tcg_out_insn(s, RI, IILH, ret, uval >> 16);
767: return;
768: }
769: }
770:
771: /* If we get here, both the high and low parts have non-zero bits. */
772:
773: /* Recurse to load the lower 32-bits. */
774: tcg_out_movi(s, TCG_TYPE_I32, ret, sval);
775:
776: /* Insert data into the high 32-bits. */
777: uval = uval >> 31 >> 1;
778: if (facilities & FACILITY_EXT_IMM) {
779: if (uval < 0x10000) {
780: tcg_out_insn(s, RI, IIHL, ret, uval);
781: } else if ((uval & 0xffff) == 0) {
782: tcg_out_insn(s, RI, IIHH, ret, uval >> 16);
783: } else {
784: tcg_out_insn(s, RIL, IIHF, ret, uval);
785: }
786: } else {
787: if (uval & 0xffff) {
788: tcg_out_insn(s, RI, IIHL, ret, uval);
789: }
790: if (uval & 0xffff0000) {
791: tcg_out_insn(s, RI, IIHH, ret, uval >> 16);
792: }
793: }
794: }
795:
796:
797: /* Emit a load/store type instruction. Inputs are:
798: DATA: The register to be loaded or stored.
799: BASE+OFS: The effective address.
800: OPC_RX: If the operation has an RX format opcode (e.g. STC), otherwise 0.
801: OPC_RXY: The RXY format opcode for the operation (e.g. STCY). */
802:
803: static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
804: TCGReg data, TCGReg base, TCGReg index,
805: tcg_target_long ofs)
806: {
807: if (ofs < -0x80000 || ofs >= 0x80000) {
808: /* Combine the low 16 bits of the offset with the actual load insn;
809: the high 48 bits must come from an immediate load. */
810: tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs & ~0xffff);
811: ofs &= 0xffff;
812:
813: /* If we were already given an index register, add it in. */
814: if (index != TCG_REG_NONE) {
815: tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
816: }
817: index = TCG_TMP0;
818: }
819:
820: if (opc_rx && ofs >= 0 && ofs < 0x1000) {
821: tcg_out_insn_RX(s, opc_rx, data, base, index, ofs);
822: } else {
823: tcg_out_insn_RXY(s, opc_rxy, data, base, index, ofs);
824: }
1.1 root 825: }
826:
1.1.1.2 root 827:
1.1 root 828: /* load data without address translation or endianness conversion */
1.1.1.2 root 829: static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
830: TCGReg base, tcg_target_long ofs)
1.1 root 831: {
1.1.1.2 root 832: if (type == TCG_TYPE_I32) {
833: tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs);
834: } else {
835: tcg_out_mem(s, 0, RXY_LG, data, base, TCG_REG_NONE, ofs);
836: }
1.1 root 837: }
838:
1.1.1.2 root 839: static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
840: TCGReg base, tcg_target_long ofs)
1.1 root 841: {
1.1.1.2 root 842: if (type == TCG_TYPE_I32) {
843: tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs);
844: } else {
845: tcg_out_mem(s, 0, RXY_STG, data, base, TCG_REG_NONE, ofs);
846: }
847: }
848:
849: /* load data from an absolute host address */
850: static void tcg_out_ld_abs(TCGContext *s, TCGType type, TCGReg dest, void *abs)
851: {
852: tcg_target_long addr = (tcg_target_long)abs;
853:
854: if (facilities & FACILITY_GEN_INST_EXT) {
855: tcg_target_long disp = (addr - (tcg_target_long)s->code_ptr) >> 1;
856: if (disp == (int32_t)disp) {
857: if (type == TCG_TYPE_I32) {
858: tcg_out_insn(s, RIL, LRL, dest, disp);
859: } else {
860: tcg_out_insn(s, RIL, LGRL, dest, disp);
861: }
862: return;
863: }
864: }
865:
866: tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
867: tcg_out_ld(s, type, dest, dest, addr & 0xffff);
868: }
869:
870: static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
871: {
872: if (facilities & FACILITY_EXT_IMM) {
873: tcg_out_insn(s, RRE, LGBR, dest, src);
874: return;
875: }
876:
877: if (type == TCG_TYPE_I32) {
878: if (dest == src) {
879: tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 24);
880: } else {
881: tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 24);
882: }
883: tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 24);
884: } else {
885: tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 56);
886: tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 56);
887: }
888: }
889:
890: static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
891: {
892: if (facilities & FACILITY_EXT_IMM) {
893: tcg_out_insn(s, RRE, LLGCR, dest, src);
894: return;
895: }
896:
897: if (dest == src) {
898: tcg_out_movi(s, type, TCG_TMP0, 0xff);
899: src = TCG_TMP0;
900: } else {
901: tcg_out_movi(s, type, dest, 0xff);
902: }
903: if (type == TCG_TYPE_I32) {
904: tcg_out_insn(s, RR, NR, dest, src);
905: } else {
906: tcg_out_insn(s, RRE, NGR, dest, src);
907: }
908: }
909:
910: static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
911: {
912: if (facilities & FACILITY_EXT_IMM) {
913: tcg_out_insn(s, RRE, LGHR, dest, src);
914: return;
915: }
916:
917: if (type == TCG_TYPE_I32) {
918: if (dest == src) {
919: tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 16);
920: } else {
921: tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 16);
922: }
923: tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 16);
924: } else {
925: tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 48);
926: tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 48);
927: }
928: }
929:
930: static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
931: {
932: if (facilities & FACILITY_EXT_IMM) {
933: tcg_out_insn(s, RRE, LLGHR, dest, src);
934: return;
935: }
936:
937: if (dest == src) {
938: tcg_out_movi(s, type, TCG_TMP0, 0xffff);
939: src = TCG_TMP0;
940: } else {
941: tcg_out_movi(s, type, dest, 0xffff);
942: }
943: if (type == TCG_TYPE_I32) {
944: tcg_out_insn(s, RR, NR, dest, src);
945: } else {
946: tcg_out_insn(s, RRE, NGR, dest, src);
947: }
948: }
949:
950: static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
951: {
952: tcg_out_insn(s, RRE, LGFR, dest, src);
953: }
954:
955: static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
956: {
957: tcg_out_insn(s, RRE, LLGFR, dest, src);
958: }
959:
960: static inline void tgen32_addi(TCGContext *s, TCGReg dest, int32_t val)
961: {
962: if (val == (int16_t)val) {
963: tcg_out_insn(s, RI, AHI, dest, val);
964: } else {
965: tcg_out_insn(s, RIL, AFI, dest, val);
966: }
967: }
968:
969: static inline void tgen64_addi(TCGContext *s, TCGReg dest, int64_t val)
970: {
971: if (val == (int16_t)val) {
972: tcg_out_insn(s, RI, AGHI, dest, val);
973: } else if (val == (int32_t)val) {
974: tcg_out_insn(s, RIL, AGFI, dest, val);
975: } else if (val == (uint32_t)val) {
976: tcg_out_insn(s, RIL, ALGFI, dest, val);
977: } else {
978: tcg_abort();
979: }
980:
981: }
982:
983: static void tgen64_andi(TCGContext *s, TCGReg dest, tcg_target_ulong val)
984: {
985: static const S390Opcode ni_insns[4] = {
986: RI_NILL, RI_NILH, RI_NIHL, RI_NIHH
987: };
988: static const S390Opcode nif_insns[2] = {
989: RIL_NILF, RIL_NIHF
990: };
991:
992: int i;
993:
994: /* Look for no-op. */
995: if (val == -1) {
996: return;
997: }
998:
999: /* Look for the zero-extensions. */
1000: if (val == 0xffffffff) {
1001: tgen_ext32u(s, dest, dest);
1002: return;
1003: }
1004:
1005: if (facilities & FACILITY_EXT_IMM) {
1006: if (val == 0xff) {
1007: tgen_ext8u(s, TCG_TYPE_I64, dest, dest);
1008: return;
1009: }
1010: if (val == 0xffff) {
1011: tgen_ext16u(s, TCG_TYPE_I64, dest, dest);
1012: return;
1013: }
1014:
1015: /* Try all 32-bit insns that can perform it in one go. */
1016: for (i = 0; i < 4; i++) {
1017: tcg_target_ulong mask = ~(0xffffull << i*16);
1018: if ((val & mask) == mask) {
1019: tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
1020: return;
1021: }
1022: }
1023:
1024: /* Try all 48-bit insns that can perform it in one go. */
1025: if (facilities & FACILITY_EXT_IMM) {
1026: for (i = 0; i < 2; i++) {
1027: tcg_target_ulong mask = ~(0xffffffffull << i*32);
1028: if ((val & mask) == mask) {
1029: tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
1030: return;
1031: }
1032: }
1033: }
1034:
1035: /* Perform the AND via sequential modifications to the high and low
1036: parts. Do this via recursion to handle 16-bit vs 32-bit masks in
1037: each half. */
1038: tgen64_andi(s, dest, val | 0xffffffff00000000ull);
1039: tgen64_andi(s, dest, val | 0x00000000ffffffffull);
1040: } else {
1041: /* With no extended-immediate facility, just emit the sequence. */
1042: for (i = 0; i < 4; i++) {
1043: tcg_target_ulong mask = 0xffffull << i*16;
1044: if ((val & mask) != mask) {
1045: tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
1046: }
1047: }
1048: }
1049: }
1050:
1051: static void tgen64_ori(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1052: {
1053: static const S390Opcode oi_insns[4] = {
1054: RI_OILL, RI_OILH, RI_OIHL, RI_OIHH
1055: };
1056: static const S390Opcode nif_insns[2] = {
1057: RIL_OILF, RIL_OIHF
1058: };
1059:
1060: int i;
1061:
1062: /* Look for no-op. */
1063: if (val == 0) {
1064: return;
1065: }
1066:
1067: if (facilities & FACILITY_EXT_IMM) {
1068: /* Try all 32-bit insns that can perform it in one go. */
1069: for (i = 0; i < 4; i++) {
1070: tcg_target_ulong mask = (0xffffull << i*16);
1071: if ((val & mask) != 0 && (val & ~mask) == 0) {
1072: tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
1073: return;
1074: }
1075: }
1076:
1077: /* Try all 48-bit insns that can perform it in one go. */
1078: for (i = 0; i < 2; i++) {
1079: tcg_target_ulong mask = (0xffffffffull << i*32);
1080: if ((val & mask) != 0 && (val & ~mask) == 0) {
1081: tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
1082: return;
1083: }
1084: }
1085:
1086: /* Perform the OR via sequential modifications to the high and
1087: low parts. Do this via recursion to handle 16-bit vs 32-bit
1088: masks in each half. */
1089: tgen64_ori(s, dest, val & 0x00000000ffffffffull);
1090: tgen64_ori(s, dest, val & 0xffffffff00000000ull);
1091: } else {
1092: /* With no extended-immediate facility, we don't need to be so
1093: clever. Just iterate over the insns and mask in the constant. */
1094: for (i = 0; i < 4; i++) {
1095: tcg_target_ulong mask = (0xffffull << i*16);
1096: if ((val & mask) != 0) {
1097: tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
1098: }
1099: }
1100: }
1101: }
1102:
1103: static void tgen64_xori(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1104: {
1105: /* Perform the xor by parts. */
1106: if (val & 0xffffffff) {
1107: tcg_out_insn(s, RIL, XILF, dest, val);
1108: }
1109: if (val > 0xffffffff) {
1110: tcg_out_insn(s, RIL, XIHF, dest, val >> 31 >> 1);
1111: }
1.1 root 1112: }
1113:
1.1.1.2 root 1114: static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
1115: TCGArg c2, int c2const)
1116: {
1117: bool is_unsigned = (c > TCG_COND_GT);
1118: if (c2const) {
1119: if (c2 == 0) {
1120: if (type == TCG_TYPE_I32) {
1121: tcg_out_insn(s, RR, LTR, r1, r1);
1122: } else {
1123: tcg_out_insn(s, RRE, LTGR, r1, r1);
1124: }
1125: return tcg_cond_to_ltr_cond[c];
1126: } else {
1127: if (is_unsigned) {
1128: if (type == TCG_TYPE_I32) {
1129: tcg_out_insn(s, RIL, CLFI, r1, c2);
1130: } else {
1131: tcg_out_insn(s, RIL, CLGFI, r1, c2);
1132: }
1133: } else {
1134: if (type == TCG_TYPE_I32) {
1135: tcg_out_insn(s, RIL, CFI, r1, c2);
1136: } else {
1137: tcg_out_insn(s, RIL, CGFI, r1, c2);
1138: }
1139: }
1140: }
1141: } else {
1142: if (is_unsigned) {
1143: if (type == TCG_TYPE_I32) {
1144: tcg_out_insn(s, RR, CLR, r1, c2);
1145: } else {
1146: tcg_out_insn(s, RRE, CLGR, r1, c2);
1147: }
1148: } else {
1149: if (type == TCG_TYPE_I32) {
1150: tcg_out_insn(s, RR, CR, r1, c2);
1151: } else {
1152: tcg_out_insn(s, RRE, CGR, r1, c2);
1153: }
1154: }
1155: }
1156: return tcg_cond_to_s390_cond[c];
1157: }
1158:
1159: static void tgen_setcond(TCGContext *s, TCGType type, TCGCond c,
1160: TCGReg dest, TCGReg r1, TCGArg c2, int c2const)
1161: {
1162: int cc = tgen_cmp(s, type, c, r1, c2, c2const);
1163:
1164: /* Emit: r1 = 1; if (cc) goto over; r1 = 0; over: */
1165: tcg_out_movi(s, type, dest, 1);
1166: tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1167: tcg_out_movi(s, type, dest, 0);
1168: }
1169:
1170: static void tgen_gotoi(TCGContext *s, int cc, tcg_target_long dest)
1171: {
1172: tcg_target_long off = (dest - (tcg_target_long)s->code_ptr) >> 1;
1173: if (off > -0x8000 && off < 0x7fff) {
1174: tcg_out_insn(s, RI, BRC, cc, off);
1175: } else if (off == (int32_t)off) {
1176: tcg_out_insn(s, RIL, BRCL, cc, off);
1177: } else {
1178: tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, dest);
1179: tcg_out_insn(s, RR, BCR, cc, TCG_TMP0);
1180: }
1181: }
1182:
1183: static void tgen_branch(TCGContext *s, int cc, int labelno)
1184: {
1185: TCGLabel* l = &s->labels[labelno];
1186: if (l->has_value) {
1187: tgen_gotoi(s, cc, l->u.value);
1188: } else if (USE_LONG_BRANCHES) {
1189: tcg_out16(s, RIL_BRCL | (cc << 4));
1190: tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, labelno, -2);
1191: s->code_ptr += 4;
1192: } else {
1193: tcg_out16(s, RI_BRC | (cc << 4));
1194: tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, labelno, -2);
1195: s->code_ptr += 2;
1196: }
1197: }
1198:
1199: static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
1200: TCGReg r1, TCGReg r2, int labelno)
1201: {
1202: TCGLabel* l = &s->labels[labelno];
1203: tcg_target_long off;
1204:
1205: if (l->has_value) {
1206: off = (l->u.value - (tcg_target_long)s->code_ptr) >> 1;
1207: } else {
1208: /* We need to keep the offset unchanged for retranslation. */
1209: off = ((int16_t *)s->code_ptr)[1];
1210: tcg_out_reloc(s, s->code_ptr + 2, R_390_PC16DBL, labelno, -2);
1211: }
1212:
1213: tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
1214: tcg_out16(s, off);
1215: tcg_out16(s, cc << 12 | (opc & 0xff));
1216: }
1217:
1218: static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
1219: TCGReg r1, int i2, int labelno)
1220: {
1221: TCGLabel* l = &s->labels[labelno];
1222: tcg_target_long off;
1223:
1224: if (l->has_value) {
1225: off = (l->u.value - (tcg_target_long)s->code_ptr) >> 1;
1226: } else {
1227: /* We need to keep the offset unchanged for retranslation. */
1228: off = ((int16_t *)s->code_ptr)[1];
1229: tcg_out_reloc(s, s->code_ptr + 2, R_390_PC16DBL, labelno, -2);
1230: }
1231:
1232: tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
1233: tcg_out16(s, off);
1234: tcg_out16(s, (i2 << 8) | (opc & 0xff));
1235: }
1236:
1237: static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
1238: TCGReg r1, TCGArg c2, int c2const, int labelno)
1239: {
1240: int cc;
1241:
1242: if (facilities & FACILITY_GEN_INST_EXT) {
1243: bool is_unsigned = (c > TCG_COND_GT);
1244: bool in_range;
1245: S390Opcode opc;
1246:
1247: cc = tcg_cond_to_s390_cond[c];
1248:
1249: if (!c2const) {
1250: opc = (type == TCG_TYPE_I32
1251: ? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
1252: : (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
1253: tgen_compare_branch(s, opc, cc, r1, c2, labelno);
1254: return;
1255: }
1256:
1257: /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1258: If the immediate we've been given does not fit that range, we'll
1259: fall back to separate compare and branch instructions using the
1260: larger comparison range afforded by COMPARE IMMEDIATE. */
1261: if (type == TCG_TYPE_I32) {
1262: if (is_unsigned) {
1263: opc = RIE_CLIJ;
1264: in_range = (uint32_t)c2 == (uint8_t)c2;
1265: } else {
1266: opc = RIE_CIJ;
1267: in_range = (int32_t)c2 == (int8_t)c2;
1268: }
1269: } else {
1270: if (is_unsigned) {
1271: opc = RIE_CLGIJ;
1272: in_range = (uint64_t)c2 == (uint8_t)c2;
1273: } else {
1274: opc = RIE_CGIJ;
1275: in_range = (int64_t)c2 == (int8_t)c2;
1276: }
1277: }
1278: if (in_range) {
1279: tgen_compare_imm_branch(s, opc, cc, r1, c2, labelno);
1280: return;
1281: }
1282: }
1283:
1284: cc = tgen_cmp(s, type, c, r1, c2, c2const);
1285: tgen_branch(s, cc, labelno);
1286: }
1287:
1288: static void tgen_calli(TCGContext *s, tcg_target_long dest)
1289: {
1290: tcg_target_long off = (dest - (tcg_target_long)s->code_ptr) >> 1;
1291: if (off == (int32_t)off) {
1292: tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
1293: } else {
1294: tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, dest);
1295: tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_TMP0);
1296: }
1297: }
1298:
1299: static void tcg_out_qemu_ld_direct(TCGContext *s, int opc, TCGReg data,
1300: TCGReg base, TCGReg index, int disp)
1301: {
1302: #ifdef TARGET_WORDS_BIGENDIAN
1303: const int bswap = 0;
1304: #else
1305: const int bswap = 1;
1306: #endif
1307: switch (opc) {
1308: case LD_UINT8:
1309: tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
1310: break;
1311: case LD_INT8:
1312: tcg_out_insn(s, RXY, LGB, data, base, index, disp);
1313: break;
1314: case LD_UINT16:
1315: if (bswap) {
1316: /* swapped unsigned halfword load with upper bits zeroed */
1317: tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1318: tgen_ext16u(s, TCG_TYPE_I64, data, data);
1319: } else {
1320: tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
1321: }
1322: break;
1323: case LD_INT16:
1324: if (bswap) {
1325: /* swapped sign-extended halfword load */
1326: tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1327: tgen_ext16s(s, TCG_TYPE_I64, data, data);
1328: } else {
1329: tcg_out_insn(s, RXY, LGH, data, base, index, disp);
1330: }
1331: break;
1332: case LD_UINT32:
1333: if (bswap) {
1334: /* swapped unsigned int load with upper bits zeroed */
1335: tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1336: tgen_ext32u(s, data, data);
1337: } else {
1338: tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
1339: }
1340: break;
1341: case LD_INT32:
1342: if (bswap) {
1343: /* swapped sign-extended int load */
1344: tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1345: tgen_ext32s(s, data, data);
1346: } else {
1347: tcg_out_insn(s, RXY, LGF, data, base, index, disp);
1348: }
1349: break;
1350: case LD_UINT64:
1351: if (bswap) {
1352: tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
1353: } else {
1354: tcg_out_insn(s, RXY, LG, data, base, index, disp);
1355: }
1356: break;
1357: default:
1358: tcg_abort();
1359: }
1360: }
1361:
1362: static void tcg_out_qemu_st_direct(TCGContext *s, int opc, TCGReg data,
1363: TCGReg base, TCGReg index, int disp)
1364: {
1365: #ifdef TARGET_WORDS_BIGENDIAN
1366: const int bswap = 0;
1367: #else
1368: const int bswap = 1;
1369: #endif
1370: switch (opc) {
1371: case LD_UINT8:
1372: if (disp >= 0 && disp < 0x1000) {
1373: tcg_out_insn(s, RX, STC, data, base, index, disp);
1374: } else {
1375: tcg_out_insn(s, RXY, STCY, data, base, index, disp);
1376: }
1377: break;
1378: case LD_UINT16:
1379: if (bswap) {
1380: tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
1381: } else if (disp >= 0 && disp < 0x1000) {
1382: tcg_out_insn(s, RX, STH, data, base, index, disp);
1383: } else {
1384: tcg_out_insn(s, RXY, STHY, data, base, index, disp);
1385: }
1386: break;
1387: case LD_UINT32:
1388: if (bswap) {
1389: tcg_out_insn(s, RXY, STRV, data, base, index, disp);
1390: } else if (disp >= 0 && disp < 0x1000) {
1391: tcg_out_insn(s, RX, ST, data, base, index, disp);
1392: } else {
1393: tcg_out_insn(s, RXY, STY, data, base, index, disp);
1394: }
1395: break;
1396: case LD_UINT64:
1397: if (bswap) {
1398: tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
1399: } else {
1400: tcg_out_insn(s, RXY, STG, data, base, index, disp);
1401: }
1402: break;
1403: default:
1404: tcg_abort();
1405: }
1406: }
1407:
1408: #if defined(CONFIG_SOFTMMU)
1409: static void tgen64_andi_tmp(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1410: {
1411: if (tcg_match_andi(0, val)) {
1412: tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, val);
1413: tcg_out_insn(s, RRE, NGR, dest, TCG_TMP0);
1414: } else {
1415: tgen64_andi(s, dest, val);
1416: }
1417: }
1418:
1419: static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
1420: TCGReg addr_reg, int mem_index, int opc,
1421: uint16_t **label2_ptr_p, int is_store)
1422: {
1423: const TCGReg arg0 = TCG_REG_R2;
1424: const TCGReg arg1 = TCG_REG_R3;
1425: int s_bits = opc & 3;
1426: uint16_t *label1_ptr;
1427: tcg_target_long ofs;
1428:
1429: if (TARGET_LONG_BITS == 32) {
1430: tgen_ext32u(s, arg0, addr_reg);
1431: } else {
1432: tcg_out_mov(s, TCG_TYPE_I64, arg0, addr_reg);
1433: }
1434:
1435: tcg_out_sh64(s, RSY_SRLG, arg1, addr_reg, TCG_REG_NONE,
1436: TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1437:
1438: tgen64_andi_tmp(s, arg0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1439: tgen64_andi_tmp(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1440:
1441: if (is_store) {
1442: ofs = offsetof(CPUState, tlb_table[mem_index][0].addr_write);
1443: } else {
1444: ofs = offsetof(CPUState, tlb_table[mem_index][0].addr_read);
1445: }
1446: assert(ofs < 0x80000);
1447:
1448: if (TARGET_LONG_BITS == 32) {
1449: tcg_out_mem(s, RX_C, RXY_CY, arg0, arg1, TCG_AREG0, ofs);
1450: } else {
1451: tcg_out_mem(s, 0, RXY_CG, arg0, arg1, TCG_AREG0, ofs);
1452: }
1453:
1454: if (TARGET_LONG_BITS == 32) {
1455: tgen_ext32u(s, arg0, addr_reg);
1456: } else {
1457: tcg_out_mov(s, TCG_TYPE_I64, arg0, addr_reg);
1458: }
1459:
1460: label1_ptr = (uint16_t*)s->code_ptr;
1461:
1462: /* je label1 (offset will be patched in later) */
1463: tcg_out_insn(s, RI, BRC, S390_CC_EQ, 0);
1464:
1465: /* call load/store helper */
1466: if (is_store) {
1467: /* Make sure to zero-extend the value to the full register
1468: for the calling convention. */
1469: switch (opc) {
1470: case LD_UINT8:
1471: tgen_ext8u(s, TCG_TYPE_I64, arg1, data_reg);
1472: break;
1473: case LD_UINT16:
1474: tgen_ext16u(s, TCG_TYPE_I64, arg1, data_reg);
1475: break;
1476: case LD_UINT32:
1477: tgen_ext32u(s, arg1, data_reg);
1478: break;
1479: case LD_UINT64:
1480: tcg_out_mov(s, TCG_TYPE_I64, arg1, data_reg);
1481: break;
1482: default:
1483: tcg_abort();
1484: }
1485: tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, mem_index);
1486: tgen_calli(s, (tcg_target_ulong)qemu_st_helpers[s_bits]);
1487: } else {
1488: tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
1489: tgen_calli(s, (tcg_target_ulong)qemu_ld_helpers[s_bits]);
1490:
1491: /* sign extension */
1492: switch (opc) {
1493: case LD_INT8:
1494: tgen_ext8s(s, TCG_TYPE_I64, data_reg, arg0);
1495: break;
1496: case LD_INT16:
1497: tgen_ext16s(s, TCG_TYPE_I64, data_reg, arg0);
1498: break;
1499: case LD_INT32:
1500: tgen_ext32s(s, data_reg, arg0);
1501: break;
1502: default:
1503: /* unsigned -> just copy */
1504: tcg_out_mov(s, TCG_TYPE_I64, data_reg, arg0);
1505: break;
1506: }
1507: }
1508:
1509: /* jump to label2 (end) */
1510: *label2_ptr_p = (uint16_t*)s->code_ptr;
1511:
1512: tcg_out_insn(s, RI, BRC, S390_CC_ALWAYS, 0);
1513:
1514: /* this is label1, patch branch */
1515: *(label1_ptr + 1) = ((unsigned long)s->code_ptr -
1516: (unsigned long)label1_ptr) >> 1;
1517:
1518: ofs = offsetof(CPUState, tlb_table[mem_index][0].addend);
1519: assert(ofs < 0x80000);
1520:
1521: tcg_out_mem(s, 0, RXY_AG, arg0, arg1, TCG_AREG0, ofs);
1522: }
1523:
1524: static void tcg_finish_qemu_ldst(TCGContext* s, uint16_t *label2_ptr)
1525: {
1526: /* patch branch */
1527: *(label2_ptr + 1) = ((unsigned long)s->code_ptr -
1528: (unsigned long)label2_ptr) >> 1;
1529: }
1530: #else
1531: static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
1532: TCGReg *index_reg, tcg_target_long *disp)
1533: {
1534: if (TARGET_LONG_BITS == 32) {
1535: tgen_ext32u(s, TCG_TMP0, *addr_reg);
1536: *addr_reg = TCG_TMP0;
1537: }
1538: if (GUEST_BASE < 0x80000) {
1539: *index_reg = TCG_REG_NONE;
1540: *disp = GUEST_BASE;
1541: } else {
1542: *index_reg = TCG_GUEST_BASE_REG;
1543: *disp = 0;
1544: }
1545: }
1546: #endif /* CONFIG_SOFTMMU */
1547:
1548: /* load data with address translation (if applicable)
1549: and endianness conversion */
1550: static void tcg_out_qemu_ld(TCGContext* s, const TCGArg* args, int opc)
1551: {
1552: TCGReg addr_reg, data_reg;
1553: #if defined(CONFIG_SOFTMMU)
1554: int mem_index;
1555: uint16_t *label2_ptr;
1556: #else
1557: TCGReg index_reg;
1558: tcg_target_long disp;
1559: #endif
1560:
1561: data_reg = *args++;
1562: addr_reg = *args++;
1563:
1564: #if defined(CONFIG_SOFTMMU)
1565: mem_index = *args;
1566:
1567: tcg_prepare_qemu_ldst(s, data_reg, addr_reg, mem_index,
1568: opc, &label2_ptr, 0);
1569:
1570: tcg_out_qemu_ld_direct(s, opc, data_reg, TCG_REG_R2, TCG_REG_NONE, 0);
1571:
1572: tcg_finish_qemu_ldst(s, label2_ptr);
1573: #else
1574: tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1575: tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1576: #endif
1577: }
1578:
1579: static void tcg_out_qemu_st(TCGContext* s, const TCGArg* args, int opc)
1580: {
1581: TCGReg addr_reg, data_reg;
1582: #if defined(CONFIG_SOFTMMU)
1583: int mem_index;
1584: uint16_t *label2_ptr;
1585: #else
1586: TCGReg index_reg;
1587: tcg_target_long disp;
1588: #endif
1589:
1590: data_reg = *args++;
1591: addr_reg = *args++;
1592:
1593: #if defined(CONFIG_SOFTMMU)
1594: mem_index = *args;
1595:
1596: tcg_prepare_qemu_ldst(s, data_reg, addr_reg, mem_index,
1597: opc, &label2_ptr, 1);
1598:
1599: tcg_out_qemu_st_direct(s, opc, data_reg, TCG_REG_R2, TCG_REG_NONE, 0);
1600:
1601: tcg_finish_qemu_ldst(s, label2_ptr);
1602: #else
1603: tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1604: tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1605: #endif
1606: }
1607:
1608: #if TCG_TARGET_REG_BITS == 64
1609: # define OP_32_64(x) \
1610: case glue(glue(INDEX_op_,x),_i32): \
1611: case glue(glue(INDEX_op_,x),_i64)
1612: #else
1613: # define OP_32_64(x) \
1614: case glue(glue(INDEX_op_,x),_i32)
1615: #endif
1616:
1617: static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1.1 root 1618: const TCGArg *args, const int *const_args)
1619: {
1.1.1.2 root 1620: S390Opcode op;
1621:
1622: switch (opc) {
1623: case INDEX_op_exit_tb:
1624: /* return value */
1625: tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, args[0]);
1626: tgen_gotoi(s, S390_CC_ALWAYS, (unsigned long)tb_ret_addr);
1627: break;
1628:
1629: case INDEX_op_goto_tb:
1630: if (s->tb_jmp_offset) {
1631: tcg_abort();
1632: } else {
1633: /* load address stored at s->tb_next + args[0] */
1634: tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_TMP0, s->tb_next + args[0]);
1635: /* and go there */
1636: tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_TMP0);
1637: }
1638: s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1639: break;
1640:
1641: case INDEX_op_call:
1642: if (const_args[0]) {
1643: tgen_calli(s, args[0]);
1644: } else {
1645: tcg_out_insn(s, RR, BASR, TCG_REG_R14, args[0]);
1646: }
1647: break;
1648:
1649: case INDEX_op_mov_i32:
1650: tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1651: break;
1652: case INDEX_op_movi_i32:
1653: tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1654: break;
1655:
1656: OP_32_64(ld8u):
1657: /* ??? LLC (RXY format) is only present with the extended-immediate
1658: facility, whereas LLGC is always present. */
1659: tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
1660: break;
1661:
1662: OP_32_64(ld8s):
1663: /* ??? LB is no smaller than LGB, so no point to using it. */
1664: tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
1665: break;
1666:
1667: OP_32_64(ld16u):
1668: /* ??? LLH (RXY format) is only present with the extended-immediate
1669: facility, whereas LLGH is always present. */
1670: tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
1671: break;
1672:
1673: case INDEX_op_ld16s_i32:
1674: tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
1675: break;
1676:
1677: case INDEX_op_ld_i32:
1678: tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1679: break;
1680:
1681: OP_32_64(st8):
1682: tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
1683: TCG_REG_NONE, args[2]);
1684: break;
1685:
1686: OP_32_64(st16):
1687: tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
1688: TCG_REG_NONE, args[2]);
1689: break;
1690:
1691: case INDEX_op_st_i32:
1692: tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1693: break;
1694:
1695: case INDEX_op_add_i32:
1696: if (const_args[2]) {
1697: tgen32_addi(s, args[0], args[2]);
1698: } else {
1699: tcg_out_insn(s, RR, AR, args[0], args[2]);
1700: }
1701: break;
1702: case INDEX_op_sub_i32:
1703: if (const_args[2]) {
1704: tgen32_addi(s, args[0], -args[2]);
1705: } else {
1706: tcg_out_insn(s, RR, SR, args[0], args[2]);
1707: }
1708: break;
1709:
1710: case INDEX_op_and_i32:
1711: if (const_args[2]) {
1712: tgen64_andi(s, args[0], args[2] | 0xffffffff00000000ull);
1713: } else {
1714: tcg_out_insn(s, RR, NR, args[0], args[2]);
1715: }
1716: break;
1717: case INDEX_op_or_i32:
1718: if (const_args[2]) {
1719: tgen64_ori(s, args[0], args[2] & 0xffffffff);
1720: } else {
1721: tcg_out_insn(s, RR, OR, args[0], args[2]);
1722: }
1723: break;
1724: case INDEX_op_xor_i32:
1725: if (const_args[2]) {
1726: tgen64_xori(s, args[0], args[2] & 0xffffffff);
1727: } else {
1728: tcg_out_insn(s, RR, XR, args[0], args[2]);
1729: }
1730: break;
1731:
1732: case INDEX_op_neg_i32:
1733: tcg_out_insn(s, RR, LCR, args[0], args[1]);
1734: break;
1735:
1736: case INDEX_op_mul_i32:
1737: if (const_args[2]) {
1738: if ((int32_t)args[2] == (int16_t)args[2]) {
1739: tcg_out_insn(s, RI, MHI, args[0], args[2]);
1740: } else {
1741: tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
1742: }
1743: } else {
1744: tcg_out_insn(s, RRE, MSR, args[0], args[2]);
1745: }
1746: break;
1747:
1748: case INDEX_op_div2_i32:
1749: tcg_out_insn(s, RR, DR, TCG_REG_R2, args[4]);
1750: break;
1751: case INDEX_op_divu2_i32:
1752: tcg_out_insn(s, RRE, DLR, TCG_REG_R2, args[4]);
1753: break;
1754:
1755: case INDEX_op_shl_i32:
1756: op = RS_SLL;
1757: do_shift32:
1758: if (const_args[2]) {
1759: tcg_out_sh32(s, op, args[0], TCG_REG_NONE, args[2]);
1760: } else {
1761: tcg_out_sh32(s, op, args[0], args[2], 0);
1762: }
1763: break;
1764: case INDEX_op_shr_i32:
1765: op = RS_SRL;
1766: goto do_shift32;
1767: case INDEX_op_sar_i32:
1768: op = RS_SRA;
1769: goto do_shift32;
1770:
1771: case INDEX_op_rotl_i32:
1772: /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1773: if (const_args[2]) {
1774: tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
1775: } else {
1776: tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
1777: }
1778: break;
1779: case INDEX_op_rotr_i32:
1780: if (const_args[2]) {
1781: tcg_out_sh64(s, RSY_RLL, args[0], args[1],
1782: TCG_REG_NONE, (32 - args[2]) & 31);
1783: } else {
1784: tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
1785: tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
1786: }
1787: break;
1788:
1789: case INDEX_op_ext8s_i32:
1790: tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
1791: break;
1792: case INDEX_op_ext16s_i32:
1793: tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
1794: break;
1795: case INDEX_op_ext8u_i32:
1796: tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
1797: break;
1798: case INDEX_op_ext16u_i32:
1799: tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
1800: break;
1801:
1802: OP_32_64(bswap16):
1803: /* The TCG bswap definition requires bits 0-47 already be zero.
1804: Thus we don't need the G-type insns to implement bswap16_i64. */
1805: tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1806: tcg_out_sh32(s, RS_SRL, args[0], TCG_REG_NONE, 16);
1807: break;
1808: OP_32_64(bswap32):
1809: tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1810: break;
1811:
1812: case INDEX_op_br:
1813: tgen_branch(s, S390_CC_ALWAYS, args[0]);
1814: break;
1815:
1816: case INDEX_op_brcond_i32:
1817: tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
1818: args[1], const_args[1], args[3]);
1819: break;
1820: case INDEX_op_setcond_i32:
1821: tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
1822: args[2], const_args[2]);
1823: break;
1824:
1825: case INDEX_op_qemu_ld8u:
1826: tcg_out_qemu_ld(s, args, LD_UINT8);
1827: break;
1828: case INDEX_op_qemu_ld8s:
1829: tcg_out_qemu_ld(s, args, LD_INT8);
1830: break;
1831: case INDEX_op_qemu_ld16u:
1832: tcg_out_qemu_ld(s, args, LD_UINT16);
1833: break;
1834: case INDEX_op_qemu_ld16s:
1835: tcg_out_qemu_ld(s, args, LD_INT16);
1836: break;
1837: case INDEX_op_qemu_ld32:
1838: /* ??? Technically we can use a non-extending instruction. */
1839: tcg_out_qemu_ld(s, args, LD_UINT32);
1840: break;
1841: case INDEX_op_qemu_ld64:
1842: tcg_out_qemu_ld(s, args, LD_UINT64);
1843: break;
1844:
1845: case INDEX_op_qemu_st8:
1846: tcg_out_qemu_st(s, args, LD_UINT8);
1847: break;
1848: case INDEX_op_qemu_st16:
1849: tcg_out_qemu_st(s, args, LD_UINT16);
1850: break;
1851: case INDEX_op_qemu_st32:
1852: tcg_out_qemu_st(s, args, LD_UINT32);
1853: break;
1854: case INDEX_op_qemu_st64:
1855: tcg_out_qemu_st(s, args, LD_UINT64);
1856: break;
1857:
1858: #if TCG_TARGET_REG_BITS == 64
1859: case INDEX_op_mov_i64:
1860: tcg_out_mov(s, TCG_TYPE_I64, args[0], args[1]);
1861: break;
1862: case INDEX_op_movi_i64:
1863: tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
1864: break;
1865:
1866: case INDEX_op_ld16s_i64:
1867: tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
1868: break;
1869: case INDEX_op_ld32u_i64:
1870: tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
1871: break;
1872: case INDEX_op_ld32s_i64:
1873: tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
1874: break;
1875: case INDEX_op_ld_i64:
1876: tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1877: break;
1878:
1879: case INDEX_op_st32_i64:
1880: tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1881: break;
1882: case INDEX_op_st_i64:
1883: tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1884: break;
1885:
1886: case INDEX_op_add_i64:
1887: if (const_args[2]) {
1888: tgen64_addi(s, args[0], args[2]);
1889: } else {
1890: tcg_out_insn(s, RRE, AGR, args[0], args[2]);
1891: }
1892: break;
1893: case INDEX_op_sub_i64:
1894: if (const_args[2]) {
1895: tgen64_addi(s, args[0], -args[2]);
1896: } else {
1897: tcg_out_insn(s, RRE, SGR, args[0], args[2]);
1898: }
1899: break;
1900:
1901: case INDEX_op_and_i64:
1902: if (const_args[2]) {
1903: tgen64_andi(s, args[0], args[2]);
1904: } else {
1905: tcg_out_insn(s, RRE, NGR, args[0], args[2]);
1906: }
1907: break;
1908: case INDEX_op_or_i64:
1909: if (const_args[2]) {
1910: tgen64_ori(s, args[0], args[2]);
1911: } else {
1912: tcg_out_insn(s, RRE, OGR, args[0], args[2]);
1913: }
1914: break;
1915: case INDEX_op_xor_i64:
1916: if (const_args[2]) {
1917: tgen64_xori(s, args[0], args[2]);
1918: } else {
1919: tcg_out_insn(s, RRE, XGR, args[0], args[2]);
1920: }
1921: break;
1922:
1923: case INDEX_op_neg_i64:
1924: tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
1925: break;
1926: case INDEX_op_bswap64_i64:
1927: tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
1928: break;
1929:
1930: case INDEX_op_mul_i64:
1931: if (const_args[2]) {
1932: if (args[2] == (int16_t)args[2]) {
1933: tcg_out_insn(s, RI, MGHI, args[0], args[2]);
1934: } else {
1935: tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
1936: }
1937: } else {
1938: tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
1939: }
1940: break;
1941:
1942: case INDEX_op_div2_i64:
1943: /* ??? We get an unnecessary sign-extension of the dividend
1944: into R3 with this definition, but as we do in fact always
1945: produce both quotient and remainder using INDEX_op_div_i64
1946: instead requires jumping through even more hoops. */
1947: tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
1948: break;
1949: case INDEX_op_divu2_i64:
1950: tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
1951: break;
1952:
1953: case INDEX_op_shl_i64:
1954: op = RSY_SLLG;
1955: do_shift64:
1956: if (const_args[2]) {
1957: tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
1958: } else {
1959: tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
1960: }
1961: break;
1962: case INDEX_op_shr_i64:
1963: op = RSY_SRLG;
1964: goto do_shift64;
1965: case INDEX_op_sar_i64:
1966: op = RSY_SRAG;
1967: goto do_shift64;
1968:
1969: case INDEX_op_rotl_i64:
1970: if (const_args[2]) {
1971: tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
1972: TCG_REG_NONE, args[2]);
1973: } else {
1974: tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
1975: }
1976: break;
1977: case INDEX_op_rotr_i64:
1978: if (const_args[2]) {
1979: tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
1980: TCG_REG_NONE, (64 - args[2]) & 63);
1981: } else {
1982: /* We can use the smaller 32-bit negate because only the
1983: low 6 bits are examined for the rotate. */
1984: tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
1985: tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
1986: }
1987: break;
1988:
1989: case INDEX_op_ext8s_i64:
1990: tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
1991: break;
1992: case INDEX_op_ext16s_i64:
1993: tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
1994: break;
1995: case INDEX_op_ext32s_i64:
1996: tgen_ext32s(s, args[0], args[1]);
1997: break;
1998: case INDEX_op_ext8u_i64:
1999: tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
2000: break;
2001: case INDEX_op_ext16u_i64:
2002: tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
2003: break;
2004: case INDEX_op_ext32u_i64:
2005: tgen_ext32u(s, args[0], args[1]);
2006: break;
2007:
2008: case INDEX_op_brcond_i64:
2009: tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
2010: args[1], const_args[1], args[3]);
2011: break;
2012: case INDEX_op_setcond_i64:
2013: tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2014: args[2], const_args[2]);
2015: break;
2016:
2017: case INDEX_op_qemu_ld32u:
2018: tcg_out_qemu_ld(s, args, LD_UINT32);
2019: break;
2020: case INDEX_op_qemu_ld32s:
2021: tcg_out_qemu_ld(s, args, LD_INT32);
2022: break;
2023: #endif /* TCG_TARGET_REG_BITS == 64 */
2024:
2025: case INDEX_op_jmp:
2026: /* This one is obsolete and never emitted. */
2027: tcg_abort();
2028: break;
2029:
2030: default:
2031: fprintf(stderr,"unimplemented opc 0x%x\n",opc);
2032: tcg_abort();
2033: }
1.1 root 2034: }
2035:
1.1.1.2 root 2036: static const TCGTargetOpDef s390_op_defs[] = {
2037: { INDEX_op_exit_tb, { } },
2038: { INDEX_op_goto_tb, { } },
2039: { INDEX_op_call, { "ri" } },
2040: { INDEX_op_jmp, { "ri" } },
2041: { INDEX_op_br, { } },
2042:
2043: { INDEX_op_mov_i32, { "r", "r" } },
2044: { INDEX_op_movi_i32, { "r" } },
2045:
2046: { INDEX_op_ld8u_i32, { "r", "r" } },
2047: { INDEX_op_ld8s_i32, { "r", "r" } },
2048: { INDEX_op_ld16u_i32, { "r", "r" } },
2049: { INDEX_op_ld16s_i32, { "r", "r" } },
2050: { INDEX_op_ld_i32, { "r", "r" } },
2051: { INDEX_op_st8_i32, { "r", "r" } },
2052: { INDEX_op_st16_i32, { "r", "r" } },
2053: { INDEX_op_st_i32, { "r", "r" } },
2054:
2055: { INDEX_op_add_i32, { "r", "0", "rWI" } },
2056: { INDEX_op_sub_i32, { "r", "0", "rWNI" } },
2057: { INDEX_op_mul_i32, { "r", "0", "rK" } },
2058:
2059: { INDEX_op_div2_i32, { "b", "a", "0", "1", "r" } },
2060: { INDEX_op_divu2_i32, { "b", "a", "0", "1", "r" } },
2061:
2062: { INDEX_op_and_i32, { "r", "0", "rWA" } },
2063: { INDEX_op_or_i32, { "r", "0", "rWO" } },
2064: { INDEX_op_xor_i32, { "r", "0", "rWX" } },
2065:
2066: { INDEX_op_neg_i32, { "r", "r" } },
2067:
2068: { INDEX_op_shl_i32, { "r", "0", "Ri" } },
2069: { INDEX_op_shr_i32, { "r", "0", "Ri" } },
2070: { INDEX_op_sar_i32, { "r", "0", "Ri" } },
2071:
2072: { INDEX_op_rotl_i32, { "r", "r", "Ri" } },
2073: { INDEX_op_rotr_i32, { "r", "r", "Ri" } },
2074:
2075: { INDEX_op_ext8s_i32, { "r", "r" } },
2076: { INDEX_op_ext8u_i32, { "r", "r" } },
2077: { INDEX_op_ext16s_i32, { "r", "r" } },
2078: { INDEX_op_ext16u_i32, { "r", "r" } },
2079:
2080: { INDEX_op_bswap16_i32, { "r", "r" } },
2081: { INDEX_op_bswap32_i32, { "r", "r" } },
2082:
2083: { INDEX_op_brcond_i32, { "r", "rWC" } },
2084: { INDEX_op_setcond_i32, { "r", "r", "rWC" } },
2085:
2086: { INDEX_op_qemu_ld8u, { "r", "L" } },
2087: { INDEX_op_qemu_ld8s, { "r", "L" } },
2088: { INDEX_op_qemu_ld16u, { "r", "L" } },
2089: { INDEX_op_qemu_ld16s, { "r", "L" } },
2090: { INDEX_op_qemu_ld32, { "r", "L" } },
2091: { INDEX_op_qemu_ld64, { "r", "L" } },
2092:
2093: { INDEX_op_qemu_st8, { "L", "L" } },
2094: { INDEX_op_qemu_st16, { "L", "L" } },
2095: { INDEX_op_qemu_st32, { "L", "L" } },
2096: { INDEX_op_qemu_st64, { "L", "L" } },
2097:
2098: #if defined(__s390x__)
2099: { INDEX_op_mov_i64, { "r", "r" } },
2100: { INDEX_op_movi_i64, { "r" } },
2101:
2102: { INDEX_op_ld8u_i64, { "r", "r" } },
2103: { INDEX_op_ld8s_i64, { "r", "r" } },
2104: { INDEX_op_ld16u_i64, { "r", "r" } },
2105: { INDEX_op_ld16s_i64, { "r", "r" } },
2106: { INDEX_op_ld32u_i64, { "r", "r" } },
2107: { INDEX_op_ld32s_i64, { "r", "r" } },
2108: { INDEX_op_ld_i64, { "r", "r" } },
2109:
2110: { INDEX_op_st8_i64, { "r", "r" } },
2111: { INDEX_op_st16_i64, { "r", "r" } },
2112: { INDEX_op_st32_i64, { "r", "r" } },
2113: { INDEX_op_st_i64, { "r", "r" } },
2114:
2115: { INDEX_op_add_i64, { "r", "0", "rI" } },
2116: { INDEX_op_sub_i64, { "r", "0", "rNI" } },
2117: { INDEX_op_mul_i64, { "r", "0", "rK" } },
2118:
2119: { INDEX_op_div2_i64, { "b", "a", "0", "1", "r" } },
2120: { INDEX_op_divu2_i64, { "b", "a", "0", "1", "r" } },
2121:
2122: { INDEX_op_and_i64, { "r", "0", "rA" } },
2123: { INDEX_op_or_i64, { "r", "0", "rO" } },
2124: { INDEX_op_xor_i64, { "r", "0", "rX" } },
2125:
2126: { INDEX_op_neg_i64, { "r", "r" } },
2127:
2128: { INDEX_op_shl_i64, { "r", "r", "Ri" } },
2129: { INDEX_op_shr_i64, { "r", "r", "Ri" } },
2130: { INDEX_op_sar_i64, { "r", "r", "Ri" } },
2131:
2132: { INDEX_op_rotl_i64, { "r", "r", "Ri" } },
2133: { INDEX_op_rotr_i64, { "r", "r", "Ri" } },
2134:
2135: { INDEX_op_ext8s_i64, { "r", "r" } },
2136: { INDEX_op_ext8u_i64, { "r", "r" } },
2137: { INDEX_op_ext16s_i64, { "r", "r" } },
2138: { INDEX_op_ext16u_i64, { "r", "r" } },
2139: { INDEX_op_ext32s_i64, { "r", "r" } },
2140: { INDEX_op_ext32u_i64, { "r", "r" } },
2141:
2142: { INDEX_op_bswap16_i64, { "r", "r" } },
2143: { INDEX_op_bswap32_i64, { "r", "r" } },
2144: { INDEX_op_bswap64_i64, { "r", "r" } },
2145:
2146: { INDEX_op_brcond_i64, { "r", "rC" } },
2147: { INDEX_op_setcond_i64, { "r", "r", "rC" } },
2148:
2149: { INDEX_op_qemu_ld32u, { "r", "L" } },
2150: { INDEX_op_qemu_ld32s, { "r", "L" } },
2151: #endif
2152:
2153: { -1 },
2154: };
2155:
2156: /* ??? Linux kernels provide an AUXV entry AT_HWCAP that provides most of
2157: this information. However, getting at that entry is not easy this far
2158: away from main. Our options are: start searching from environ, but
2159: that fails as soon as someone does a setenv in between. Read the data
2160: from /proc/self/auxv. Or do the probing ourselves. The only thing
2161: extra that AT_HWCAP gives us is HWCAP_S390_HIGH_GPRS, which indicates
2162: that the kernel saves all 64-bits of the registers around traps while
2163: in 31-bit mode. But this is true of all "recent" kernels (ought to dig
2164: back and see from when this might not be true). */
2165:
2166: #include <signal.h>
2167:
2168: static volatile sig_atomic_t got_sigill;
2169:
2170: static void sigill_handler(int sig)
1.1 root 2171: {
1.1.1.2 root 2172: got_sigill = 1;
1.1 root 2173: }
2174:
1.1.1.2 root 2175: static void query_facilities(void)
1.1 root 2176: {
1.1.1.2 root 2177: struct sigaction sa_old, sa_new;
2178: register int r0 __asm__("0");
2179: register void *r1 __asm__("1");
2180: int fail;
2181:
2182: memset(&sa_new, 0, sizeof(sa_new));
2183: sa_new.sa_handler = sigill_handler;
2184: sigaction(SIGILL, &sa_new, &sa_old);
2185:
2186: /* First, try STORE FACILITY LIST EXTENDED. If this is present, then
2187: we need not do any more probing. Unfortunately, this itself is an
2188: extension and the original STORE FACILITY LIST instruction is
2189: kernel-only, storing its results at absolute address 200. */
2190: /* stfle 0(%r1) */
2191: r1 = &facilities;
2192: asm volatile(".word 0xb2b0,0x1000"
2193: : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
2194:
2195: if (got_sigill) {
2196: /* STORE FACILITY EXTENDED is not available. Probe for one of each
2197: kind of instruction that we're interested in. */
2198: /* ??? Possibly some of these are in practice never present unless
2199: the store-facility-extended facility is also present. But since
2200: that isn't documented it's just better to probe for each. */
2201:
2202: /* Test for z/Architecture. Required even in 31-bit mode. */
2203: got_sigill = 0;
2204: /* agr %r0,%r0 */
2205: asm volatile(".word 0xb908,0x0000" : "=r"(r0) : : "cc");
2206: if (!got_sigill) {
2207: facilities |= FACILITY_ZARCH_ACTIVE;
2208: }
2209:
2210: /* Test for long displacement. */
2211: got_sigill = 0;
2212: /* ly %r0,0(%r1) */
2213: r1 = &facilities;
2214: asm volatile(".word 0xe300,0x1000,0x0058"
2215: : "=r"(r0) : "r"(r1) : "cc");
2216: if (!got_sigill) {
2217: facilities |= FACILITY_LONG_DISP;
2218: }
2219:
2220: /* Test for extended immediates. */
2221: got_sigill = 0;
2222: /* afi %r0,0 */
2223: asm volatile(".word 0xc209,0x0000,0x0000" : : : "cc");
2224: if (!got_sigill) {
2225: facilities |= FACILITY_EXT_IMM;
2226: }
2227:
2228: /* Test for general-instructions-extension. */
2229: got_sigill = 0;
2230: /* msfi %r0,1 */
2231: asm volatile(".word 0xc201,0x0000,0x0001");
2232: if (!got_sigill) {
2233: facilities |= FACILITY_GEN_INST_EXT;
2234: }
2235: }
2236:
2237: sigaction(SIGILL, &sa_old, NULL);
2238:
2239: /* The translator currently uses these extensions unconditionally.
2240: Pruning this back to the base ESA/390 architecture doesn't seem
2241: worthwhile, since even the KVM target requires z/Arch. */
2242: fail = 0;
2243: if ((facilities & FACILITY_ZARCH_ACTIVE) == 0) {
2244: fprintf(stderr, "TCG: z/Arch facility is required.\n");
2245: fprintf(stderr, "TCG: Boot with a 64-bit enabled kernel.\n");
2246: fail = 1;
2247: }
2248: if ((facilities & FACILITY_LONG_DISP) == 0) {
2249: fprintf(stderr, "TCG: long-displacement facility is required.\n");
2250: fail = 1;
2251: }
2252:
2253: /* So far there's just enough support for 31-bit mode to let the
2254: compile succeed. This is good enough to run QEMU with KVM. */
2255: if (sizeof(void *) != 8) {
2256: fprintf(stderr, "TCG: 31-bit mode is not supported.\n");
2257: fail = 1;
2258: }
2259:
2260: if (fail) {
2261: exit(-1);
2262: }
1.1 root 2263: }
2264:
1.1.1.2 root 2265: static void tcg_target_init(TCGContext *s)
1.1 root 2266: {
1.1.1.2 root 2267: #if !defined(CONFIG_USER_ONLY)
2268: /* fail safe */
2269: if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry)) {
2270: tcg_abort();
2271: }
2272: #endif
2273:
2274: query_facilities();
2275:
2276: tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
2277: tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
2278:
2279: tcg_regset_clear(tcg_target_call_clobber_regs);
2280: tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2281: tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
2282: tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2283: tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2284: tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
2285: tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
2286: /* The return register can be considered call-clobbered. */
2287: tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2288:
2289: tcg_regset_clear(s->reserved_regs);
2290: tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
2291: /* XXX many insns can't be used with R0, so we better avoid it for now */
2292: tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
2293: tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2294:
2295: tcg_add_target_add_op_defs(s390_op_defs);
1.1.1.3 root 2296: tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
2297: CPU_TEMP_BUF_NLONGS * sizeof(long));
1.1.1.2 root 2298: }
2299:
2300: static void tcg_target_qemu_prologue(TCGContext *s)
2301: {
2302: /* stmg %r6,%r15,48(%r15) (save registers) */
2303: tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
2304:
2305: /* aghi %r15,-160 (stack frame) */
2306: tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -160);
2307:
2308: if (GUEST_BASE >= 0x80000) {
2309: tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
2310: tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2311: }
2312:
1.1.1.3 root 2313: tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2314: /* br %r3 (go to TB) */
2315: tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
1.1.1.2 root 2316:
2317: tb_ret_addr = s->code_ptr;
2318:
2319: /* lmg %r6,%r15,208(%r15) (restore registers) */
2320: tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 208);
2321:
2322: /* br %r14 (return) */
2323: tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
1.1 root 2324: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.