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