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