]> git.proxmox.com Git - qemu.git/blob - tcg/ia64/tcg-target.c
aeb6bc7450f5eea57618c1a0668e2cef5ed6fee8
[qemu.git] / tcg / ia64 / tcg-target.c
1 /*
2 * Tiny Code Generator for QEMU
3 *
4 * Copyright (c) 2009-2010 Aurelien Jarno <aurelien@aurel32.net>
5 * Based on i386/tcg-target.c - Copyright (c) 2008 Fabrice Bellard
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26 #include "tcg-be-null.h"
27
28 /*
29 * Register definitions
30 */
31
32 #ifndef NDEBUG
33 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
34 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
35 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
36 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
37 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
38 "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
39 "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
40 "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
41 "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63",
42 };
43 #endif
44
45 #ifdef CONFIG_USE_GUEST_BASE
46 #define TCG_GUEST_BASE_REG TCG_REG_R55
47 #else
48 #define TCG_GUEST_BASE_REG TCG_REG_R0
49 #endif
50 #ifndef GUEST_BASE
51 #define GUEST_BASE 0
52 #endif
53
54 /* Branch registers */
55 enum {
56 TCG_REG_B0 = 0,
57 TCG_REG_B1,
58 TCG_REG_B2,
59 TCG_REG_B3,
60 TCG_REG_B4,
61 TCG_REG_B5,
62 TCG_REG_B6,
63 TCG_REG_B7,
64 };
65
66 /* Floating point registers */
67 enum {
68 TCG_REG_F0 = 0,
69 TCG_REG_F1,
70 TCG_REG_F2,
71 TCG_REG_F3,
72 TCG_REG_F4,
73 TCG_REG_F5,
74 TCG_REG_F6,
75 TCG_REG_F7,
76 TCG_REG_F8,
77 TCG_REG_F9,
78 TCG_REG_F10,
79 TCG_REG_F11,
80 TCG_REG_F12,
81 TCG_REG_F13,
82 TCG_REG_F14,
83 TCG_REG_F15,
84 };
85
86 /* Predicate registers */
87 enum {
88 TCG_REG_P0 = 0,
89 TCG_REG_P1,
90 TCG_REG_P2,
91 TCG_REG_P3,
92 TCG_REG_P4,
93 TCG_REG_P5,
94 TCG_REG_P6,
95 TCG_REG_P7,
96 TCG_REG_P8,
97 TCG_REG_P9,
98 TCG_REG_P10,
99 TCG_REG_P11,
100 TCG_REG_P12,
101 TCG_REG_P13,
102 TCG_REG_P14,
103 TCG_REG_P15,
104 };
105
106 /* Application registers */
107 enum {
108 TCG_REG_PFS = 64,
109 };
110
111 static const int tcg_target_reg_alloc_order[] = {
112 TCG_REG_R35,
113 TCG_REG_R36,
114 TCG_REG_R37,
115 TCG_REG_R38,
116 TCG_REG_R39,
117 TCG_REG_R40,
118 TCG_REG_R41,
119 TCG_REG_R42,
120 TCG_REG_R43,
121 TCG_REG_R44,
122 TCG_REG_R45,
123 TCG_REG_R46,
124 TCG_REG_R47,
125 TCG_REG_R48,
126 TCG_REG_R49,
127 TCG_REG_R50,
128 TCG_REG_R51,
129 TCG_REG_R52,
130 TCG_REG_R53,
131 TCG_REG_R54,
132 TCG_REG_R55,
133 TCG_REG_R14,
134 TCG_REG_R15,
135 TCG_REG_R16,
136 TCG_REG_R17,
137 TCG_REG_R18,
138 TCG_REG_R19,
139 TCG_REG_R20,
140 TCG_REG_R21,
141 TCG_REG_R22,
142 TCG_REG_R23,
143 TCG_REG_R24,
144 TCG_REG_R25,
145 TCG_REG_R26,
146 TCG_REG_R27,
147 TCG_REG_R28,
148 TCG_REG_R29,
149 TCG_REG_R30,
150 TCG_REG_R31,
151 TCG_REG_R56,
152 TCG_REG_R57,
153 TCG_REG_R58,
154 TCG_REG_R59,
155 TCG_REG_R60,
156 TCG_REG_R61,
157 TCG_REG_R62,
158 TCG_REG_R63,
159 TCG_REG_R8,
160 TCG_REG_R9,
161 TCG_REG_R10,
162 TCG_REG_R11
163 };
164
165 static const int tcg_target_call_iarg_regs[8] = {
166 TCG_REG_R56,
167 TCG_REG_R57,
168 TCG_REG_R58,
169 TCG_REG_R59,
170 TCG_REG_R60,
171 TCG_REG_R61,
172 TCG_REG_R62,
173 TCG_REG_R63,
174 };
175
176 static const int tcg_target_call_oarg_regs[] = {
177 TCG_REG_R8
178 };
179
180 /*
181 * opcode formation
182 */
183
184 /* bundle templates: stops (double bar in the IA64 manual) are marked with
185 an uppercase letter. */
186 enum {
187 mii = 0x00,
188 miI = 0x01,
189 mIi = 0x02,
190 mII = 0x03,
191 mlx = 0x04,
192 mLX = 0x05,
193 mmi = 0x08,
194 mmI = 0x09,
195 Mmi = 0x0a,
196 MmI = 0x0b,
197 mfi = 0x0c,
198 mfI = 0x0d,
199 mmf = 0x0e,
200 mmF = 0x0f,
201 mib = 0x10,
202 miB = 0x11,
203 mbb = 0x12,
204 mbB = 0x13,
205 bbb = 0x16,
206 bbB = 0x17,
207 mmb = 0x18,
208 mmB = 0x19,
209 mfb = 0x1c,
210 mfB = 0x1d,
211 };
212
213 enum {
214 OPC_ADD_A1 = 0x10000000000ull,
215 OPC_AND_A1 = 0x10060000000ull,
216 OPC_AND_A3 = 0x10160000000ull,
217 OPC_ANDCM_A1 = 0x10068000000ull,
218 OPC_ANDCM_A3 = 0x10168000000ull,
219 OPC_ADDS_A4 = 0x10800000000ull,
220 OPC_ADDL_A5 = 0x12000000000ull,
221 OPC_ALLOC_M34 = 0x02c00000000ull,
222 OPC_BR_DPTK_FEW_B1 = 0x08400000000ull,
223 OPC_BR_SPTK_MANY_B1 = 0x08000001000ull,
224 OPC_BR_SPTK_MANY_B4 = 0x00100001000ull,
225 OPC_BR_CALL_SPTK_MANY_B5 = 0x02100001000ull,
226 OPC_BR_RET_SPTK_MANY_B4 = 0x00108001100ull,
227 OPC_BRL_SPTK_MANY_X3 = 0x18000001000ull,
228 OPC_BRL_CALL_SPTK_MANY_X4 = 0x1a000001000ull,
229 OPC_CMP_LT_A6 = 0x18000000000ull,
230 OPC_CMP_LTU_A6 = 0x1a000000000ull,
231 OPC_CMP_EQ_A6 = 0x1c000000000ull,
232 OPC_CMP4_LT_A6 = 0x18400000000ull,
233 OPC_CMP4_LTU_A6 = 0x1a400000000ull,
234 OPC_CMP4_EQ_A6 = 0x1c400000000ull,
235 OPC_DEP_I14 = 0x0ae00000000ull,
236 OPC_DEP_I15 = 0x08000000000ull,
237 OPC_DEP_Z_I12 = 0x0a600000000ull,
238 OPC_EXTR_I11 = 0x0a400002000ull,
239 OPC_EXTR_U_I11 = 0x0a400000000ull,
240 OPC_FCVT_FX_TRUNC_S1_F10 = 0x004d0000000ull,
241 OPC_FCVT_FXU_TRUNC_S1_F10 = 0x004d8000000ull,
242 OPC_FCVT_XF_F11 = 0x000e0000000ull,
243 OPC_FMA_S1_F1 = 0x10400000000ull,
244 OPC_FNMA_S1_F1 = 0x18400000000ull,
245 OPC_FRCPA_S1_F6 = 0x00600000000ull,
246 OPC_GETF_SIG_M19 = 0x08708000000ull,
247 OPC_LD1_M1 = 0x08000000000ull,
248 OPC_LD1_M3 = 0x0a000000000ull,
249 OPC_LD2_M1 = 0x08040000000ull,
250 OPC_LD2_M3 = 0x0a040000000ull,
251 OPC_LD4_M1 = 0x08080000000ull,
252 OPC_LD4_M3 = 0x0a080000000ull,
253 OPC_LD8_M1 = 0x080c0000000ull,
254 OPC_LD8_M3 = 0x0a0c0000000ull,
255 OPC_MUX1_I3 = 0x0eca0000000ull,
256 OPC_NOP_B9 = 0x04008000000ull,
257 OPC_NOP_F16 = 0x00008000000ull,
258 OPC_NOP_I18 = 0x00008000000ull,
259 OPC_NOP_M48 = 0x00008000000ull,
260 OPC_MOV_I21 = 0x00e00100000ull,
261 OPC_MOV_RET_I21 = 0x00e00500000ull,
262 OPC_MOV_I22 = 0x00188000000ull,
263 OPC_MOV_I_I26 = 0x00150000000ull,
264 OPC_MOVL_X2 = 0x0c000000000ull,
265 OPC_OR_A1 = 0x10070000000ull,
266 OPC_SETF_EXP_M18 = 0x0c748000000ull,
267 OPC_SETF_SIG_M18 = 0x0c708000000ull,
268 OPC_SHL_I7 = 0x0f240000000ull,
269 OPC_SHR_I5 = 0x0f220000000ull,
270 OPC_SHR_U_I5 = 0x0f200000000ull,
271 OPC_SHRP_I10 = 0x0ac00000000ull,
272 OPC_SXT1_I29 = 0x000a0000000ull,
273 OPC_SXT2_I29 = 0x000a8000000ull,
274 OPC_SXT4_I29 = 0x000b0000000ull,
275 OPC_ST1_M4 = 0x08c00000000ull,
276 OPC_ST2_M4 = 0x08c40000000ull,
277 OPC_ST4_M4 = 0x08c80000000ull,
278 OPC_ST8_M4 = 0x08cc0000000ull,
279 OPC_SUB_A1 = 0x10028000000ull,
280 OPC_SUB_A3 = 0x10128000000ull,
281 OPC_UNPACK4_L_I2 = 0x0f860000000ull,
282 OPC_XMA_L_F2 = 0x1d000000000ull,
283 OPC_XOR_A1 = 0x10078000000ull,
284 OPC_ZXT1_I29 = 0x00080000000ull,
285 OPC_ZXT2_I29 = 0x00088000000ull,
286 OPC_ZXT4_I29 = 0x00090000000ull,
287
288 INSN_NOP_M = OPC_NOP_M48, /* nop.m 0 */
289 INSN_NOP_I = OPC_NOP_I18, /* nop.i 0 */
290 };
291
292 static inline uint64_t tcg_opc_a1(int qp, uint64_t opc, int r1,
293 int r2, int r3)
294 {
295 return opc
296 | ((r3 & 0x7f) << 20)
297 | ((r2 & 0x7f) << 13)
298 | ((r1 & 0x7f) << 6)
299 | (qp & 0x3f);
300 }
301
302 static inline uint64_t tcg_opc_a3(int qp, uint64_t opc, int r1,
303 uint64_t imm, int r3)
304 {
305 return opc
306 | ((imm & 0x80) << 29) /* s */
307 | ((imm & 0x7f) << 13) /* imm7b */
308 | ((r3 & 0x7f) << 20)
309 | ((r1 & 0x7f) << 6)
310 | (qp & 0x3f);
311 }
312
313 static inline uint64_t tcg_opc_a4(int qp, uint64_t opc, int r1,
314 uint64_t imm, int r3)
315 {
316 return opc
317 | ((imm & 0x2000) << 23) /* s */
318 | ((imm & 0x1f80) << 20) /* imm6d */
319 | ((imm & 0x007f) << 13) /* imm7b */
320 | ((r3 & 0x7f) << 20)
321 | ((r1 & 0x7f) << 6)
322 | (qp & 0x3f);
323 }
324
325 static inline uint64_t tcg_opc_a5(int qp, uint64_t opc, int r1,
326 uint64_t imm, int r3)
327 {
328 return opc
329 | ((imm & 0x200000) << 15) /* s */
330 | ((imm & 0x1f0000) << 6) /* imm5c */
331 | ((imm & 0x00ff80) << 20) /* imm9d */
332 | ((imm & 0x00007f) << 13) /* imm7b */
333 | ((r3 & 0x03) << 20)
334 | ((r1 & 0x7f) << 6)
335 | (qp & 0x3f);
336 }
337
338 static inline uint64_t tcg_opc_a6(int qp, uint64_t opc, int p1,
339 int p2, int r2, int r3)
340 {
341 return opc
342 | ((p2 & 0x3f) << 27)
343 | ((r3 & 0x7f) << 20)
344 | ((r2 & 0x7f) << 13)
345 | ((p1 & 0x3f) << 6)
346 | (qp & 0x3f);
347 }
348
349 static inline uint64_t tcg_opc_b1(int qp, uint64_t opc, uint64_t imm)
350 {
351 return opc
352 | ((imm & 0x100000) << 16) /* s */
353 | ((imm & 0x0fffff) << 13) /* imm20b */
354 | (qp & 0x3f);
355 }
356
357 static inline uint64_t tcg_opc_b4(int qp, uint64_t opc, int b2)
358 {
359 return opc
360 | ((b2 & 0x7) << 13)
361 | (qp & 0x3f);
362 }
363
364 static inline uint64_t tcg_opc_b5(int qp, uint64_t opc, int b1, int b2)
365 {
366 return opc
367 | ((b2 & 0x7) << 13)
368 | ((b1 & 0x7) << 6)
369 | (qp & 0x3f);
370 }
371
372
373 static inline uint64_t tcg_opc_b9(int qp, uint64_t opc, uint64_t imm)
374 {
375 return opc
376 | ((imm & 0x100000) << 16) /* i */
377 | ((imm & 0x0fffff) << 6) /* imm20a */
378 | (qp & 0x3f);
379 }
380
381 static inline uint64_t tcg_opc_f1(int qp, uint64_t opc, int f1,
382 int f3, int f4, int f2)
383 {
384 return opc
385 | ((f4 & 0x7f) << 27)
386 | ((f3 & 0x7f) << 20)
387 | ((f2 & 0x7f) << 13)
388 | ((f1 & 0x7f) << 6)
389 | (qp & 0x3f);
390 }
391
392 static inline uint64_t tcg_opc_f2(int qp, uint64_t opc, int f1,
393 int f3, int f4, int f2)
394 {
395 return opc
396 | ((f4 & 0x7f) << 27)
397 | ((f3 & 0x7f) << 20)
398 | ((f2 & 0x7f) << 13)
399 | ((f1 & 0x7f) << 6)
400 | (qp & 0x3f);
401 }
402
403 static inline uint64_t tcg_opc_f6(int qp, uint64_t opc, int f1,
404 int p2, int f2, int f3)
405 {
406 return opc
407 | ((p2 & 0x3f) << 27)
408 | ((f3 & 0x7f) << 20)
409 | ((f2 & 0x7f) << 13)
410 | ((f1 & 0x7f) << 6)
411 | (qp & 0x3f);
412 }
413
414 static inline uint64_t tcg_opc_f10(int qp, uint64_t opc, int f1, int f2)
415 {
416 return opc
417 | ((f2 & 0x7f) << 13)
418 | ((f1 & 0x7f) << 6)
419 | (qp & 0x3f);
420 }
421
422 static inline uint64_t tcg_opc_f11(int qp, uint64_t opc, int f1, int f2)
423 {
424 return opc
425 | ((f2 & 0x7f) << 13)
426 | ((f1 & 0x7f) << 6)
427 | (qp & 0x3f);
428 }
429
430 static inline uint64_t tcg_opc_f16(int qp, uint64_t opc, uint64_t imm)
431 {
432 return opc
433 | ((imm & 0x100000) << 16) /* i */
434 | ((imm & 0x0fffff) << 6) /* imm20a */
435 | (qp & 0x3f);
436 }
437
438 static inline uint64_t tcg_opc_i2(int qp, uint64_t opc, int r1,
439 int r2, int r3)
440 {
441 return opc
442 | ((r3 & 0x7f) << 20)
443 | ((r2 & 0x7f) << 13)
444 | ((r1 & 0x7f) << 6)
445 | (qp & 0x3f);
446 }
447
448 static inline uint64_t tcg_opc_i3(int qp, uint64_t opc, int r1,
449 int r2, int mbtype)
450 {
451 return opc
452 | ((mbtype & 0x0f) << 20)
453 | ((r2 & 0x7f) << 13)
454 | ((r1 & 0x7f) << 6)
455 | (qp & 0x3f);
456 }
457
458 static inline uint64_t tcg_opc_i5(int qp, uint64_t opc, int r1,
459 int r3, int r2)
460 {
461 return opc
462 | ((r3 & 0x7f) << 20)
463 | ((r2 & 0x7f) << 13)
464 | ((r1 & 0x7f) << 6)
465 | (qp & 0x3f);
466 }
467
468 static inline uint64_t tcg_opc_i7(int qp, uint64_t opc, int r1,
469 int r2, int r3)
470 {
471 return opc
472 | ((r3 & 0x7f) << 20)
473 | ((r2 & 0x7f) << 13)
474 | ((r1 & 0x7f) << 6)
475 | (qp & 0x3f);
476 }
477
478 static inline uint64_t tcg_opc_i10(int qp, uint64_t opc, int r1,
479 int r2, int r3, uint64_t count)
480 {
481 return opc
482 | ((count & 0x3f) << 27)
483 | ((r3 & 0x7f) << 20)
484 | ((r2 & 0x7f) << 13)
485 | ((r1 & 0x7f) << 6)
486 | (qp & 0x3f);
487 }
488
489 static inline uint64_t tcg_opc_i11(int qp, uint64_t opc, int r1,
490 int r3, uint64_t pos, uint64_t len)
491 {
492 return opc
493 | ((len & 0x3f) << 27)
494 | ((r3 & 0x7f) << 20)
495 | ((pos & 0x3f) << 14)
496 | ((r1 & 0x7f) << 6)
497 | (qp & 0x3f);
498 }
499
500 static inline uint64_t tcg_opc_i12(int qp, uint64_t opc, int r1,
501 int r2, uint64_t pos, uint64_t len)
502 {
503 return opc
504 | ((len & 0x3f) << 27)
505 | ((pos & 0x3f) << 20)
506 | ((r2 & 0x7f) << 13)
507 | ((r1 & 0x7f) << 6)
508 | (qp & 0x3f);
509 }
510
511 static inline uint64_t tcg_opc_i14(int qp, uint64_t opc, int r1, uint64_t imm,
512 int r3, uint64_t pos, uint64_t len)
513 {
514 return opc
515 | ((imm & 0x01) << 36)
516 | ((len & 0x3f) << 27)
517 | ((r3 & 0x7f) << 20)
518 | ((pos & 0x3f) << 14)
519 | ((r1 & 0x7f) << 6)
520 | (qp & 0x3f);
521 }
522
523 static inline uint64_t tcg_opc_i15(int qp, uint64_t opc, int r1, int r2,
524 int r3, uint64_t pos, uint64_t len)
525 {
526 return opc
527 | ((pos & 0x3f) << 31)
528 | ((len & 0x0f) << 27)
529 | ((r3 & 0x7f) << 20)
530 | ((r2 & 0x7f) << 13)
531 | ((r1 & 0x7f) << 6)
532 | (qp & 0x3f);
533 }
534
535 static inline uint64_t tcg_opc_i18(int qp, uint64_t opc, uint64_t imm)
536 {
537 return opc
538 | ((imm & 0x100000) << 16) /* i */
539 | ((imm & 0x0fffff) << 6) /* imm20a */
540 | (qp & 0x3f);
541 }
542
543 static inline uint64_t tcg_opc_i21(int qp, uint64_t opc, int b1,
544 int r2, uint64_t imm)
545 {
546 return opc
547 | ((imm & 0x1ff) << 24)
548 | ((r2 & 0x7f) << 13)
549 | ((b1 & 0x7) << 6)
550 | (qp & 0x3f);
551 }
552
553 static inline uint64_t tcg_opc_i22(int qp, uint64_t opc, int r1, int b2)
554 {
555 return opc
556 | ((b2 & 0x7) << 13)
557 | ((r1 & 0x7f) << 6)
558 | (qp & 0x3f);
559 }
560
561 static inline uint64_t tcg_opc_i26(int qp, uint64_t opc, int ar3, int r2)
562 {
563 return opc
564 | ((ar3 & 0x7f) << 20)
565 | ((r2 & 0x7f) << 13)
566 | (qp & 0x3f);
567 }
568
569 static inline uint64_t tcg_opc_i29(int qp, uint64_t opc, int r1, int r3)
570 {
571 return opc
572 | ((r3 & 0x7f) << 20)
573 | ((r1 & 0x7f) << 6)
574 | (qp & 0x3f);
575 }
576
577 static inline uint64_t tcg_opc_l2(uint64_t imm)
578 {
579 return (imm & 0x7fffffffffc00000ull) >> 22;
580 }
581
582 static inline uint64_t tcg_opc_l3(uint64_t imm)
583 {
584 return (imm & 0x07fffffffff00000ull) >> 18;
585 }
586
587 #define tcg_opc_l4 tcg_opc_l3
588
589 static inline uint64_t tcg_opc_m1(int qp, uint64_t opc, int r1, int r3)
590 {
591 return opc
592 | ((r3 & 0x7f) << 20)
593 | ((r1 & 0x7f) << 6)
594 | (qp & 0x3f);
595 }
596
597 static inline uint64_t tcg_opc_m3(int qp, uint64_t opc, int r1,
598 int r3, uint64_t imm)
599 {
600 return opc
601 | ((imm & 0x100) << 28) /* s */
602 | ((imm & 0x080) << 20) /* i */
603 | ((imm & 0x07f) << 13) /* imm7b */
604 | ((r3 & 0x7f) << 20)
605 | ((r1 & 0x7f) << 6)
606 | (qp & 0x3f);
607 }
608
609 static inline uint64_t tcg_opc_m4(int qp, uint64_t opc, int r2, int r3)
610 {
611 return opc
612 | ((r3 & 0x7f) << 20)
613 | ((r2 & 0x7f) << 13)
614 | (qp & 0x3f);
615 }
616
617 static inline uint64_t tcg_opc_m18(int qp, uint64_t opc, int f1, int r2)
618 {
619 return opc
620 | ((r2 & 0x7f) << 13)
621 | ((f1 & 0x7f) << 6)
622 | (qp & 0x3f);
623 }
624
625 static inline uint64_t tcg_opc_m19(int qp, uint64_t opc, int r1, int f2)
626 {
627 return opc
628 | ((f2 & 0x7f) << 13)
629 | ((r1 & 0x7f) << 6)
630 | (qp & 0x3f);
631 }
632
633 static inline uint64_t tcg_opc_m34(int qp, uint64_t opc, int r1,
634 int sof, int sol, int sor)
635 {
636 return opc
637 | ((sor & 0x0f) << 27)
638 | ((sol & 0x7f) << 20)
639 | ((sof & 0x7f) << 13)
640 | ((r1 & 0x7f) << 6)
641 | (qp & 0x3f);
642 }
643
644 static inline uint64_t tcg_opc_m48(int qp, uint64_t opc, uint64_t imm)
645 {
646 return opc
647 | ((imm & 0x100000) << 16) /* i */
648 | ((imm & 0x0fffff) << 6) /* imm20a */
649 | (qp & 0x3f);
650 }
651
652 static inline uint64_t tcg_opc_x2(int qp, uint64_t opc,
653 int r1, uint64_t imm)
654 {
655 return opc
656 | ((imm & 0x8000000000000000ull) >> 27) /* i */
657 | (imm & 0x0000000000200000ull) /* ic */
658 | ((imm & 0x00000000001f0000ull) << 6) /* imm5c */
659 | ((imm & 0x000000000000ff80ull) << 20) /* imm9d */
660 | ((imm & 0x000000000000007full) << 13) /* imm7b */
661 | ((r1 & 0x7f) << 6)
662 | (qp & 0x3f);
663 }
664
665 static inline uint64_t tcg_opc_x3(int qp, uint64_t opc, uint64_t imm)
666 {
667 return opc
668 | ((imm & 0x0800000000000000ull) >> 23) /* i */
669 | ((imm & 0x00000000000fffffull) << 13) /* imm20b */
670 | (qp & 0x3f);
671 }
672
673 static inline uint64_t tcg_opc_x4(int qp, uint64_t opc, int b1, uint64_t imm)
674 {
675 return opc
676 | ((imm & 0x0800000000000000ull) >> 23) /* i */
677 | ((imm & 0x00000000000fffffull) << 13) /* imm20b */
678 | ((b1 & 0x7) << 6)
679 | (qp & 0x3f);
680 }
681
682
683 /*
684 * Relocations
685 */
686
687 static inline void reloc_pcrel21b(void *pc, intptr_t target)
688 {
689 uint64_t imm;
690 int64_t disp;
691 int slot;
692
693 slot = (intptr_t)pc & 3;
694 pc = (void *)((intptr_t)pc & ~3);
695
696 disp = target - (intptr_t)pc;
697 imm = (uint64_t) disp >> 4;
698
699 switch(slot) {
700 case 0:
701 *(uint64_t *)(pc + 0) = (*(uint64_t *)(pc + 8) & 0xfffffdc00003ffffull)
702 | ((imm & 0x100000) << 21) /* s */
703 | ((imm & 0x0fffff) << 18); /* imm20b */
704 break;
705 case 1:
706 *(uint64_t *)(pc + 8) = (*(uint64_t *)(pc + 8) & 0xfffffffffffb8000ull)
707 | ((imm & 0x100000) >> 2) /* s */
708 | ((imm & 0x0fffe0) >> 5); /* imm20b */
709 *(uint64_t *)(pc + 0) = (*(uint64_t *)(pc + 0) & 0x07ffffffffffffffull)
710 | ((imm & 0x00001f) << 59); /* imm20b */
711 break;
712 case 2:
713 *(uint64_t *)(pc + 8) = (*(uint64_t *)(pc + 8) & 0xf700000fffffffffull)
714 | ((imm & 0x100000) << 39) /* s */
715 | ((imm & 0x0fffff) << 36); /* imm20b */
716 break;
717 }
718 }
719
720 static inline uint64_t get_reloc_pcrel21b (void *pc)
721 {
722 int64_t low, high;
723 int slot;
724
725 slot = (tcg_target_long) pc & 3;
726 pc = (void *)((tcg_target_long) pc & ~3);
727
728 low = (*(uint64_t *)(pc + 0));
729 high = (*(uint64_t *)(pc + 8));
730
731 switch(slot) {
732 case 0:
733 return ((low >> 21) & 0x100000) + /* s */
734 ((low >> 18) & 0x0fffff); /* imm20b */
735 case 1:
736 return ((high << 2) & 0x100000) + /* s */
737 ((high << 5) & 0x0fffe0) + /* imm20b */
738 ((low >> 59) & 0x00001f); /* imm20b */
739 case 2:
740 return ((high >> 39) & 0x100000) + /* s */
741 ((high >> 36) & 0x0fffff); /* imm20b */
742 default:
743 tcg_abort();
744 }
745 }
746
747 static inline void reloc_pcrel60b(void *pc, intptr_t target)
748 {
749 int64_t disp;
750 uint64_t imm;
751
752 disp = target - (intptr_t)pc;
753 imm = (uint64_t) disp >> 4;
754
755 *(uint64_t *)(pc + 8) = (*(uint64_t *)(pc + 8) & 0xf700000fff800000ull)
756 | (imm & 0x0800000000000000ull) /* s */
757 | ((imm & 0x07fffff000000000ull) >> 36) /* imm39 */
758 | ((imm & 0x00000000000fffffull) << 36); /* imm20b */
759 *(uint64_t *)(pc + 0) = (*(uint64_t *)(pc + 0) & 0x00003fffffffffffull)
760 | ((imm & 0x0000000ffff00000ull) << 28); /* imm39 */
761 }
762
763 static inline uint64_t get_reloc_pcrel60b (void *pc)
764 {
765 int64_t low, high;
766
767 low = (*(uint64_t *)(pc + 0));
768 high = (*(uint64_t *)(pc + 8));
769
770 return ((high) & 0x0800000000000000ull) + /* s */
771 ((high >> 36) & 0x00000000000fffffull) + /* imm20b */
772 ((high << 36) & 0x07fffff000000000ull) + /* imm39 */
773 ((low >> 28) & 0x0000000ffff00000ull); /* imm39 */
774 }
775
776
777 static void patch_reloc(uint8_t *code_ptr, int type,
778 intptr_t value, intptr_t addend)
779 {
780 value += addend;
781 switch (type) {
782 case R_IA64_PCREL21B:
783 reloc_pcrel21b(code_ptr, value);
784 break;
785 case R_IA64_PCREL60B:
786 reloc_pcrel60b(code_ptr, value);
787 default:
788 tcg_abort();
789 }
790 }
791
792 /*
793 * Constraints
794 */
795
796 /* parse target specific constraints */
797 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
798 {
799 const char *ct_str;
800
801 ct_str = *pct_str;
802 switch(ct_str[0]) {
803 case 'r':
804 ct->ct |= TCG_CT_REG;
805 tcg_regset_set(ct->u.regs, 0xffffffffffffffffull);
806 break;
807 case 'I':
808 ct->ct |= TCG_CT_CONST_S22;
809 break;
810 case 'S':
811 ct->ct |= TCG_CT_REG;
812 tcg_regset_set(ct->u.regs, 0xffffffffffffffffull);
813 #if defined(CONFIG_SOFTMMU)
814 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R56);
815 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R57);
816 #endif
817 break;
818 case 'Z':
819 /* We are cheating a bit here, using the fact that the register
820 r0 is also the register number 0. Hence there is no need
821 to check for const_args in each instruction. */
822 ct->ct |= TCG_CT_CONST_ZERO;
823 break;
824 default:
825 return -1;
826 }
827 ct_str++;
828 *pct_str = ct_str;
829 return 0;
830 }
831
832 /* test if a constant matches the constraint */
833 static inline int tcg_target_const_match(tcg_target_long val,
834 const TCGArgConstraint *arg_ct)
835 {
836 int ct;
837 ct = arg_ct->ct;
838 if (ct & TCG_CT_CONST)
839 return 1;
840 else if ((ct & TCG_CT_CONST_ZERO) && val == 0)
841 return 1;
842 else if ((ct & TCG_CT_CONST_S22) && val == ((int32_t)val << 10) >> 10)
843 return 1;
844 else
845 return 0;
846 }
847
848 /*
849 * Code generation
850 */
851
852 static uint8_t *tb_ret_addr;
853
854 static inline void tcg_out_bundle(TCGContext *s, int template,
855 uint64_t slot0, uint64_t slot1,
856 uint64_t slot2)
857 {
858 template &= 0x1f; /* 5 bits */
859 slot0 &= 0x1ffffffffffull; /* 41 bits */
860 slot1 &= 0x1ffffffffffull; /* 41 bits */
861 slot2 &= 0x1ffffffffffull; /* 41 bits */
862
863 *(uint64_t *)(s->code_ptr + 0) = (slot1 << 46) | (slot0 << 5) | template;
864 *(uint64_t *)(s->code_ptr + 8) = (slot2 << 23) | (slot1 >> 18);
865 s->code_ptr += 16;
866 }
867
868 static inline void tcg_out_mov(TCGContext *s, TCGType type,
869 TCGReg ret, TCGReg arg)
870 {
871 tcg_out_bundle(s, mmI,
872 INSN_NOP_M,
873 INSN_NOP_M,
874 tcg_opc_a4(TCG_REG_P0, OPC_ADDS_A4, ret, 0, arg));
875 }
876
877 static inline void tcg_out_movi(TCGContext *s, TCGType type,
878 TCGReg reg, tcg_target_long arg)
879 {
880 tcg_out_bundle(s, mLX,
881 INSN_NOP_M,
882 tcg_opc_l2 (arg),
883 tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2, reg, arg));
884 }
885
886 static void tcg_out_br(TCGContext *s, int label_index)
887 {
888 TCGLabel *l = &s->labels[label_index];
889
890 /* We pay attention here to not modify the branch target by reading
891 the existing value and using it again. This ensure that caches and
892 memory are kept coherent during retranslation. */
893 tcg_out_bundle(s, mmB,
894 INSN_NOP_M,
895 INSN_NOP_M,
896 tcg_opc_b1 (TCG_REG_P0, OPC_BR_SPTK_MANY_B1,
897 get_reloc_pcrel21b(s->code_ptr + 2)));
898
899 if (l->has_value) {
900 reloc_pcrel21b((s->code_ptr - 16) + 2, l->u.value);
901 } else {
902 tcg_out_reloc(s, (s->code_ptr - 16) + 2,
903 R_IA64_PCREL21B, label_index, 0);
904 }
905 }
906
907 static inline void tcg_out_calli(TCGContext *s, uintptr_t addr)
908 {
909 /* Look through the function descriptor. */
910 uintptr_t disp, *desc = (uintptr_t *)addr;
911 tcg_out_bundle(s, mlx,
912 INSN_NOP_M,
913 tcg_opc_l2 (desc[1]),
914 tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2, TCG_REG_R1, desc[1]));
915 disp = (desc[0] - (uintptr_t)s->code_ptr) >> 4;
916 tcg_out_bundle(s, mLX,
917 INSN_NOP_M,
918 tcg_opc_l4 (disp),
919 tcg_opc_x4 (TCG_REG_P0, OPC_BRL_CALL_SPTK_MANY_X4,
920 TCG_REG_B0, disp));
921 }
922
923 static inline void tcg_out_callr(TCGContext *s, TCGReg addr)
924 {
925 tcg_out_bundle(s, MmI,
926 tcg_opc_m1 (TCG_REG_P0, OPC_LD8_M1, TCG_REG_R2, addr),
927 tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4, TCG_REG_R3, 8, addr),
928 tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21,
929 TCG_REG_B6, TCG_REG_R2, 0));
930 tcg_out_bundle(s, mmB,
931 tcg_opc_m1 (TCG_REG_P0, OPC_LD8_M1, TCG_REG_R1, TCG_REG_R3),
932 INSN_NOP_M,
933 tcg_opc_b5 (TCG_REG_P0, OPC_BR_CALL_SPTK_MANY_B5,
934 TCG_REG_B0, TCG_REG_B6));
935 }
936
937 static void tcg_out_exit_tb(TCGContext *s, tcg_target_long arg)
938 {
939 int64_t disp;
940 uint64_t imm;
941
942 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R8, arg);
943
944 disp = tb_ret_addr - s->code_ptr;
945 imm = (uint64_t)disp >> 4;
946
947 tcg_out_bundle(s, mLX,
948 INSN_NOP_M,
949 tcg_opc_l3 (imm),
950 tcg_opc_x3 (TCG_REG_P0, OPC_BRL_SPTK_MANY_X3, imm));
951 }
952
953 static inline void tcg_out_goto_tb(TCGContext *s, TCGArg arg)
954 {
955 if (s->tb_jmp_offset) {
956 /* direct jump method */
957 tcg_abort();
958 } else {
959 /* indirect jump method */
960 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2,
961 (tcg_target_long)(s->tb_next + arg));
962 tcg_out_bundle(s, MmI,
963 tcg_opc_m1 (TCG_REG_P0, OPC_LD8_M1,
964 TCG_REG_R2, TCG_REG_R2),
965 INSN_NOP_M,
966 tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21, TCG_REG_B6,
967 TCG_REG_R2, 0));
968 tcg_out_bundle(s, mmB,
969 INSN_NOP_M,
970 INSN_NOP_M,
971 tcg_opc_b4 (TCG_REG_P0, OPC_BR_SPTK_MANY_B4,
972 TCG_REG_B6));
973 }
974 s->tb_next_offset[arg] = s->code_ptr - s->code_buf;
975 }
976
977 static inline void tcg_out_jmp(TCGContext *s, TCGArg addr)
978 {
979 tcg_out_bundle(s, mmI,
980 INSN_NOP_M,
981 INSN_NOP_M,
982 tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21, TCG_REG_B6, addr, 0));
983 tcg_out_bundle(s, mmB,
984 INSN_NOP_M,
985 INSN_NOP_M,
986 tcg_opc_b4(TCG_REG_P0, OPC_BR_SPTK_MANY_B4, TCG_REG_B6));
987 }
988
989 static inline void tcg_out_ld_rel(TCGContext *s, uint64_t opc_m4, TCGArg arg,
990 TCGArg arg1, tcg_target_long arg2)
991 {
992 if (arg2 == ((int16_t)arg2 >> 2) << 2) {
993 tcg_out_bundle(s, MmI,
994 tcg_opc_a4(TCG_REG_P0, OPC_ADDS_A4,
995 TCG_REG_R2, arg2, arg1),
996 tcg_opc_m1 (TCG_REG_P0, opc_m4, arg, TCG_REG_R2),
997 INSN_NOP_I);
998 } else {
999 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, arg2);
1000 tcg_out_bundle(s, MmI,
1001 tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1,
1002 TCG_REG_R2, TCG_REG_R2, arg1),
1003 tcg_opc_m1 (TCG_REG_P0, opc_m4, arg, TCG_REG_R2),
1004 INSN_NOP_I);
1005 }
1006 }
1007
1008 static inline void tcg_out_st_rel(TCGContext *s, uint64_t opc_m4, TCGArg arg,
1009 TCGArg arg1, tcg_target_long arg2)
1010 {
1011 if (arg2 == ((int16_t)arg2 >> 2) << 2) {
1012 tcg_out_bundle(s, MmI,
1013 tcg_opc_a4(TCG_REG_P0, OPC_ADDS_A4,
1014 TCG_REG_R2, arg2, arg1),
1015 tcg_opc_m4 (TCG_REG_P0, opc_m4, arg, TCG_REG_R2),
1016 INSN_NOP_I);
1017 } else {
1018 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, arg2);
1019 tcg_out_bundle(s, MmI,
1020 tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1,
1021 TCG_REG_R2, TCG_REG_R2, arg1),
1022 tcg_opc_m4 (TCG_REG_P0, opc_m4, arg, TCG_REG_R2),
1023 INSN_NOP_I);
1024 }
1025 }
1026
1027 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
1028 TCGReg arg1, intptr_t arg2)
1029 {
1030 if (type == TCG_TYPE_I32) {
1031 tcg_out_ld_rel(s, OPC_LD4_M1, arg, arg1, arg2);
1032 } else {
1033 tcg_out_ld_rel(s, OPC_LD8_M1, arg, arg1, arg2);
1034 }
1035 }
1036
1037 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
1038 TCGReg arg1, intptr_t arg2)
1039 {
1040 if (type == TCG_TYPE_I32) {
1041 tcg_out_st_rel(s, OPC_ST4_M4, arg, arg1, arg2);
1042 } else {
1043 tcg_out_st_rel(s, OPC_ST8_M4, arg, arg1, arg2);
1044 }
1045 }
1046
1047 static void tcg_out_alu(TCGContext *s, uint64_t opc_a1, TCGReg ret, TCGArg arg1,
1048 int const_arg1, TCGArg arg2, int const_arg2)
1049 {
1050 uint64_t opc1 = 0, opc2 = 0;
1051
1052 if (const_arg1 && arg1 != 0) {
1053 opc1 = tcg_opc_a5(TCG_REG_P0, OPC_ADDL_A5,
1054 TCG_REG_R2, arg1, TCG_REG_R0);
1055 arg1 = TCG_REG_R2;
1056 }
1057
1058 if (const_arg2 && arg2 != 0) {
1059 opc2 = tcg_opc_a5(TCG_REG_P0, OPC_ADDL_A5,
1060 TCG_REG_R3, arg2, TCG_REG_R0);
1061 arg2 = TCG_REG_R3;
1062 }
1063
1064 tcg_out_bundle(s, (opc1 || opc2 ? mII : miI),
1065 opc1 ? opc1 : INSN_NOP_M,
1066 opc2 ? opc2 : INSN_NOP_I,
1067 tcg_opc_a1(TCG_REG_P0, opc_a1, ret, arg1, arg2));
1068 }
1069
1070 static inline void tcg_out_eqv(TCGContext *s, TCGArg ret,
1071 TCGArg arg1, int const_arg1,
1072 TCGArg arg2, int const_arg2)
1073 {
1074 tcg_out_bundle(s, mII,
1075 INSN_NOP_M,
1076 tcg_opc_a1 (TCG_REG_P0, OPC_XOR_A1, ret, arg1, arg2),
1077 tcg_opc_a3 (TCG_REG_P0, OPC_ANDCM_A3, ret, -1, ret));
1078 }
1079
1080 static inline void tcg_out_nand(TCGContext *s, TCGArg ret,
1081 TCGArg arg1, int const_arg1,
1082 TCGArg arg2, int const_arg2)
1083 {
1084 tcg_out_bundle(s, mII,
1085 INSN_NOP_M,
1086 tcg_opc_a1 (TCG_REG_P0, OPC_AND_A1, ret, arg1, arg2),
1087 tcg_opc_a3 (TCG_REG_P0, OPC_ANDCM_A3, ret, -1, ret));
1088 }
1089
1090 static inline void tcg_out_nor(TCGContext *s, TCGArg ret,
1091 TCGArg arg1, int const_arg1,
1092 TCGArg arg2, int const_arg2)
1093 {
1094 tcg_out_bundle(s, mII,
1095 INSN_NOP_M,
1096 tcg_opc_a1 (TCG_REG_P0, OPC_OR_A1, ret, arg1, arg2),
1097 tcg_opc_a3 (TCG_REG_P0, OPC_ANDCM_A3, ret, -1, ret));
1098 }
1099
1100 static inline void tcg_out_orc(TCGContext *s, TCGArg ret,
1101 TCGArg arg1, int const_arg1,
1102 TCGArg arg2, int const_arg2)
1103 {
1104 tcg_out_bundle(s, mII,
1105 INSN_NOP_M,
1106 tcg_opc_a3 (TCG_REG_P0, OPC_ANDCM_A3, TCG_REG_R2, -1, arg2),
1107 tcg_opc_a1 (TCG_REG_P0, OPC_OR_A1, ret, arg1, TCG_REG_R2));
1108 }
1109
1110 static inline void tcg_out_mul(TCGContext *s, TCGArg ret,
1111 TCGArg arg1, TCGArg arg2)
1112 {
1113 tcg_out_bundle(s, mmI,
1114 tcg_opc_m18(TCG_REG_P0, OPC_SETF_SIG_M18, TCG_REG_F6, arg1),
1115 tcg_opc_m18(TCG_REG_P0, OPC_SETF_SIG_M18, TCG_REG_F7, arg2),
1116 INSN_NOP_I);
1117 tcg_out_bundle(s, mmF,
1118 INSN_NOP_M,
1119 INSN_NOP_M,
1120 tcg_opc_f2 (TCG_REG_P0, OPC_XMA_L_F2, TCG_REG_F6, TCG_REG_F6,
1121 TCG_REG_F7, TCG_REG_F0));
1122 tcg_out_bundle(s, miI,
1123 tcg_opc_m19(TCG_REG_P0, OPC_GETF_SIG_M19, ret, TCG_REG_F6),
1124 INSN_NOP_I,
1125 INSN_NOP_I);
1126 }
1127
1128 static inline void tcg_out_sar_i32(TCGContext *s, TCGArg ret, TCGArg arg1,
1129 TCGArg arg2, int const_arg2)
1130 {
1131 if (const_arg2) {
1132 tcg_out_bundle(s, miI,
1133 INSN_NOP_M,
1134 INSN_NOP_I,
1135 tcg_opc_i11(TCG_REG_P0, OPC_EXTR_I11,
1136 ret, arg1, arg2, 31 - arg2));
1137 } else {
1138 tcg_out_bundle(s, mII,
1139 tcg_opc_a3 (TCG_REG_P0, OPC_AND_A3,
1140 TCG_REG_R3, 0x1f, arg2),
1141 tcg_opc_i29(TCG_REG_P0, OPC_SXT4_I29, TCG_REG_R2, arg1),
1142 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_I5, ret,
1143 TCG_REG_R2, TCG_REG_R3));
1144 }
1145 }
1146
1147 static inline void tcg_out_sar_i64(TCGContext *s, TCGArg ret, TCGArg arg1,
1148 TCGArg arg2, int const_arg2)
1149 {
1150 if (const_arg2) {
1151 tcg_out_bundle(s, miI,
1152 INSN_NOP_M,
1153 INSN_NOP_I,
1154 tcg_opc_i11(TCG_REG_P0, OPC_EXTR_I11,
1155 ret, arg1, arg2, 63 - arg2));
1156 } else {
1157 tcg_out_bundle(s, miI,
1158 INSN_NOP_M,
1159 INSN_NOP_I,
1160 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_I5, ret, arg1, arg2));
1161 }
1162 }
1163
1164 static inline void tcg_out_shl_i32(TCGContext *s, TCGArg ret, TCGArg arg1,
1165 TCGArg arg2, int const_arg2)
1166 {
1167 if (const_arg2) {
1168 tcg_out_bundle(s, miI,
1169 INSN_NOP_M,
1170 INSN_NOP_I,
1171 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12, ret,
1172 arg1, 63 - arg2, 31 - arg2));
1173 } else {
1174 tcg_out_bundle(s, mII,
1175 INSN_NOP_M,
1176 tcg_opc_a3 (TCG_REG_P0, OPC_AND_A3, TCG_REG_R2,
1177 0x1f, arg2),
1178 tcg_opc_i7 (TCG_REG_P0, OPC_SHL_I7, ret,
1179 arg1, TCG_REG_R2));
1180 }
1181 }
1182
1183 static inline void tcg_out_shl_i64(TCGContext *s, TCGArg ret, TCGArg arg1,
1184 TCGArg arg2, int const_arg2)
1185 {
1186 if (const_arg2) {
1187 tcg_out_bundle(s, miI,
1188 INSN_NOP_M,
1189 INSN_NOP_I,
1190 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12, ret,
1191 arg1, 63 - arg2, 63 - arg2));
1192 } else {
1193 tcg_out_bundle(s, miI,
1194 INSN_NOP_M,
1195 INSN_NOP_I,
1196 tcg_opc_i7 (TCG_REG_P0, OPC_SHL_I7, ret,
1197 arg1, arg2));
1198 }
1199 }
1200
1201 static inline void tcg_out_shr_i32(TCGContext *s, TCGArg ret, TCGArg arg1,
1202 TCGArg arg2, int const_arg2)
1203 {
1204 if (const_arg2) {
1205 tcg_out_bundle(s, miI,
1206 INSN_NOP_M,
1207 INSN_NOP_I,
1208 tcg_opc_i11(TCG_REG_P0, OPC_EXTR_U_I11, ret,
1209 arg1, arg2, 31 - arg2));
1210 } else {
1211 tcg_out_bundle(s, mII,
1212 tcg_opc_a3 (TCG_REG_P0, OPC_AND_A3, TCG_REG_R3,
1213 0x1f, arg2),
1214 tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29, TCG_REG_R2, arg1),
1215 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_U_I5, ret,
1216 TCG_REG_R2, TCG_REG_R3));
1217 }
1218 }
1219
1220 static inline void tcg_out_shr_i64(TCGContext *s, TCGArg ret, TCGArg arg1,
1221 TCGArg arg2, int const_arg2)
1222 {
1223 if (const_arg2) {
1224 tcg_out_bundle(s, miI,
1225 INSN_NOP_M,
1226 INSN_NOP_I,
1227 tcg_opc_i11(TCG_REG_P0, OPC_EXTR_U_I11, ret,
1228 arg1, arg2, 63 - arg2));
1229 } else {
1230 tcg_out_bundle(s, miI,
1231 INSN_NOP_M,
1232 INSN_NOP_I,
1233 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_U_I5, ret,
1234 arg1, arg2));
1235 }
1236 }
1237
1238 static inline void tcg_out_rotl_i32(TCGContext *s, TCGArg ret, TCGArg arg1,
1239 TCGArg arg2, int const_arg2)
1240 {
1241 if (const_arg2) {
1242 tcg_out_bundle(s, mII,
1243 INSN_NOP_M,
1244 tcg_opc_i2 (TCG_REG_P0, OPC_UNPACK4_L_I2,
1245 TCG_REG_R2, arg1, arg1),
1246 tcg_opc_i11(TCG_REG_P0, OPC_EXTR_U_I11, ret,
1247 TCG_REG_R2, 32 - arg2, 31));
1248 } else {
1249 tcg_out_bundle(s, miI,
1250 INSN_NOP_M,
1251 tcg_opc_i2 (TCG_REG_P0, OPC_UNPACK4_L_I2,
1252 TCG_REG_R2, arg1, arg1),
1253 tcg_opc_a3 (TCG_REG_P0, OPC_AND_A3, TCG_REG_R3,
1254 0x1f, arg2));
1255 tcg_out_bundle(s, mII,
1256 INSN_NOP_M,
1257 tcg_opc_a3 (TCG_REG_P0, OPC_SUB_A3, TCG_REG_R3,
1258 0x20, TCG_REG_R3),
1259 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_U_I5, ret,
1260 TCG_REG_R2, TCG_REG_R3));
1261 }
1262 }
1263
1264 static inline void tcg_out_rotl_i64(TCGContext *s, TCGArg ret, TCGArg arg1,
1265 TCGArg arg2, int const_arg2)
1266 {
1267 if (const_arg2) {
1268 tcg_out_bundle(s, miI,
1269 INSN_NOP_M,
1270 INSN_NOP_I,
1271 tcg_opc_i10(TCG_REG_P0, OPC_SHRP_I10, ret, arg1,
1272 arg1, 0x40 - arg2));
1273 } else {
1274 tcg_out_bundle(s, mII,
1275 tcg_opc_a3 (TCG_REG_P0, OPC_SUB_A3, TCG_REG_R2,
1276 0x40, arg2),
1277 tcg_opc_i7 (TCG_REG_P0, OPC_SHL_I7, TCG_REG_R3,
1278 arg1, arg2),
1279 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_U_I5, TCG_REG_R2,
1280 arg1, TCG_REG_R2));
1281 tcg_out_bundle(s, miI,
1282 INSN_NOP_M,
1283 INSN_NOP_I,
1284 tcg_opc_a1 (TCG_REG_P0, OPC_OR_A1, ret,
1285 TCG_REG_R2, TCG_REG_R3));
1286 }
1287 }
1288
1289 static inline void tcg_out_rotr_i32(TCGContext *s, TCGArg ret, TCGArg arg1,
1290 TCGArg arg2, int const_arg2)
1291 {
1292 if (const_arg2) {
1293 tcg_out_bundle(s, mII,
1294 INSN_NOP_M,
1295 tcg_opc_i2 (TCG_REG_P0, OPC_UNPACK4_L_I2,
1296 TCG_REG_R2, arg1, arg1),
1297 tcg_opc_i11(TCG_REG_P0, OPC_EXTR_U_I11, ret,
1298 TCG_REG_R2, arg2, 31));
1299 } else {
1300 tcg_out_bundle(s, mII,
1301 tcg_opc_a3 (TCG_REG_P0, OPC_AND_A3, TCG_REG_R3,
1302 0x1f, arg2),
1303 tcg_opc_i2 (TCG_REG_P0, OPC_UNPACK4_L_I2,
1304 TCG_REG_R2, arg1, arg1),
1305 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_U_I5, ret,
1306 TCG_REG_R2, TCG_REG_R3));
1307 }
1308 }
1309
1310 static inline void tcg_out_rotr_i64(TCGContext *s, TCGArg ret, TCGArg arg1,
1311 TCGArg arg2, int const_arg2)
1312 {
1313 if (const_arg2) {
1314 tcg_out_bundle(s, miI,
1315 INSN_NOP_M,
1316 INSN_NOP_I,
1317 tcg_opc_i10(TCG_REG_P0, OPC_SHRP_I10, ret, arg1,
1318 arg1, arg2));
1319 } else {
1320 tcg_out_bundle(s, mII,
1321 tcg_opc_a3 (TCG_REG_P0, OPC_SUB_A3, TCG_REG_R2,
1322 0x40, arg2),
1323 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_U_I5, TCG_REG_R3,
1324 arg1, arg2),
1325 tcg_opc_i7 (TCG_REG_P0, OPC_SHL_I7, TCG_REG_R2,
1326 arg1, TCG_REG_R2));
1327 tcg_out_bundle(s, miI,
1328 INSN_NOP_M,
1329 INSN_NOP_I,
1330 tcg_opc_a1 (TCG_REG_P0, OPC_OR_A1, ret,
1331 TCG_REG_R2, TCG_REG_R3));
1332 }
1333 }
1334
1335 static inline void tcg_out_ext(TCGContext *s, uint64_t opc_i29,
1336 TCGArg ret, TCGArg arg)
1337 {
1338 tcg_out_bundle(s, miI,
1339 INSN_NOP_M,
1340 INSN_NOP_I,
1341 tcg_opc_i29(TCG_REG_P0, opc_i29, ret, arg));
1342 }
1343
1344 static inline void tcg_out_bswap16(TCGContext *s, TCGArg ret, TCGArg arg)
1345 {
1346 tcg_out_bundle(s, mII,
1347 INSN_NOP_M,
1348 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12, ret, arg, 15, 15),
1349 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3, ret, ret, 0xb));
1350 }
1351
1352 static inline void tcg_out_bswap32(TCGContext *s, TCGArg ret, TCGArg arg)
1353 {
1354 tcg_out_bundle(s, mII,
1355 INSN_NOP_M,
1356 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12, ret, arg, 31, 31),
1357 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3, ret, ret, 0xb));
1358 }
1359
1360 static inline void tcg_out_bswap64(TCGContext *s, TCGArg ret, TCGArg arg)
1361 {
1362 tcg_out_bundle(s, miI,
1363 INSN_NOP_M,
1364 INSN_NOP_I,
1365 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3, ret, arg, 0xb));
1366 }
1367
1368 static inline void tcg_out_deposit(TCGContext *s, TCGArg ret, TCGArg a1,
1369 TCGArg a2, int const_a2, int pos, int len)
1370 {
1371 uint64_t i1 = 0, i2 = 0;
1372 int cpos = 63 - pos, lm1 = len - 1;
1373
1374 if (const_a2) {
1375 /* Truncate the value of a constant a2 to the width of the field. */
1376 int mask = (1u << len) - 1;
1377 a2 &= mask;
1378
1379 if (a2 == 0 || a2 == mask) {
1380 /* 1-bit signed constant inserted into register. */
1381 i2 = tcg_opc_i14(TCG_REG_P0, OPC_DEP_I14, ret, a2, a1, cpos, lm1);
1382 } else {
1383 /* Otherwise, load any constant into a temporary. Do this into
1384 the first I slot to help out with cross-unit delays. */
1385 i1 = tcg_opc_a5(TCG_REG_P0, OPC_ADDL_A5,
1386 TCG_REG_R2, a2, TCG_REG_R0);
1387 a2 = TCG_REG_R2;
1388 }
1389 }
1390 if (i2 == 0) {
1391 i2 = tcg_opc_i15(TCG_REG_P0, OPC_DEP_I15, ret, a2, a1, cpos, lm1);
1392 }
1393 tcg_out_bundle(s, (i1 ? mII : miI),
1394 INSN_NOP_M,
1395 i1 ? i1 : INSN_NOP_I,
1396 i2);
1397 }
1398
1399 static inline uint64_t tcg_opc_cmp_a(int qp, TCGCond cond, TCGArg arg1,
1400 TCGArg arg2, int cmp4)
1401 {
1402 uint64_t opc_eq_a6, opc_lt_a6, opc_ltu_a6;
1403
1404 if (cmp4) {
1405 opc_eq_a6 = OPC_CMP4_EQ_A6;
1406 opc_lt_a6 = OPC_CMP4_LT_A6;
1407 opc_ltu_a6 = OPC_CMP4_LTU_A6;
1408 } else {
1409 opc_eq_a6 = OPC_CMP_EQ_A6;
1410 opc_lt_a6 = OPC_CMP_LT_A6;
1411 opc_ltu_a6 = OPC_CMP_LTU_A6;
1412 }
1413
1414 switch (cond) {
1415 case TCG_COND_EQ:
1416 return tcg_opc_a6 (qp, opc_eq_a6, TCG_REG_P6, TCG_REG_P7, arg1, arg2);
1417 case TCG_COND_NE:
1418 return tcg_opc_a6 (qp, opc_eq_a6, TCG_REG_P7, TCG_REG_P6, arg1, arg2);
1419 case TCG_COND_LT:
1420 return tcg_opc_a6 (qp, opc_lt_a6, TCG_REG_P6, TCG_REG_P7, arg1, arg2);
1421 case TCG_COND_LTU:
1422 return tcg_opc_a6 (qp, opc_ltu_a6, TCG_REG_P6, TCG_REG_P7, arg1, arg2);
1423 case TCG_COND_GE:
1424 return tcg_opc_a6 (qp, opc_lt_a6, TCG_REG_P7, TCG_REG_P6, arg1, arg2);
1425 case TCG_COND_GEU:
1426 return tcg_opc_a6 (qp, opc_ltu_a6, TCG_REG_P7, TCG_REG_P6, arg1, arg2);
1427 case TCG_COND_LE:
1428 return tcg_opc_a6 (qp, opc_lt_a6, TCG_REG_P7, TCG_REG_P6, arg2, arg1);
1429 case TCG_COND_LEU:
1430 return tcg_opc_a6 (qp, opc_ltu_a6, TCG_REG_P7, TCG_REG_P6, arg2, arg1);
1431 case TCG_COND_GT:
1432 return tcg_opc_a6 (qp, opc_lt_a6, TCG_REG_P6, TCG_REG_P7, arg2, arg1);
1433 case TCG_COND_GTU:
1434 return tcg_opc_a6 (qp, opc_ltu_a6, TCG_REG_P6, TCG_REG_P7, arg2, arg1);
1435 default:
1436 tcg_abort();
1437 break;
1438 }
1439 }
1440
1441 static inline void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
1442 TCGReg arg2, int label_index, int cmp4)
1443 {
1444 TCGLabel *l = &s->labels[label_index];
1445
1446 tcg_out_bundle(s, miB,
1447 INSN_NOP_M,
1448 tcg_opc_cmp_a(TCG_REG_P0, cond, arg1, arg2, cmp4),
1449 tcg_opc_b1(TCG_REG_P6, OPC_BR_DPTK_FEW_B1,
1450 get_reloc_pcrel21b(s->code_ptr + 2)));
1451
1452 if (l->has_value) {
1453 reloc_pcrel21b((s->code_ptr - 16) + 2, l->u.value);
1454 } else {
1455 tcg_out_reloc(s, (s->code_ptr - 16) + 2,
1456 R_IA64_PCREL21B, label_index, 0);
1457 }
1458 }
1459
1460 static inline void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGArg ret,
1461 TCGArg arg1, TCGArg arg2, int cmp4)
1462 {
1463 tcg_out_bundle(s, MmI,
1464 tcg_opc_cmp_a(TCG_REG_P0, cond, arg1, arg2, cmp4),
1465 tcg_opc_a5(TCG_REG_P6, OPC_ADDL_A5, ret, 1, TCG_REG_R0),
1466 tcg_opc_a5(TCG_REG_P7, OPC_ADDL_A5, ret, 0, TCG_REG_R0));
1467 }
1468
1469 static inline void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGArg ret,
1470 TCGArg c1, TCGArg c2,
1471 TCGArg v1, int const_v1,
1472 TCGArg v2, int const_v2, int cmp4)
1473 {
1474 uint64_t opc1, opc2;
1475
1476 if (const_v1) {
1477 opc1 = tcg_opc_a5(TCG_REG_P6, OPC_ADDL_A5, ret, v1, TCG_REG_R0);
1478 } else if (ret == v1) {
1479 opc1 = INSN_NOP_M;
1480 } else {
1481 opc1 = tcg_opc_a4(TCG_REG_P6, OPC_ADDS_A4, ret, 0, v1);
1482 }
1483 if (const_v2) {
1484 opc2 = tcg_opc_a5(TCG_REG_P7, OPC_ADDL_A5, ret, v2, TCG_REG_R0);
1485 } else if (ret == v2) {
1486 opc2 = INSN_NOP_I;
1487 } else {
1488 opc2 = tcg_opc_a4(TCG_REG_P7, OPC_ADDS_A4, ret, 0, v2);
1489 }
1490
1491 tcg_out_bundle(s, MmI,
1492 tcg_opc_cmp_a(TCG_REG_P0, cond, c1, c2, cmp4),
1493 opc1,
1494 opc2);
1495 }
1496
1497 #if defined(CONFIG_SOFTMMU)
1498 /* Load and compare a TLB entry, and return the result in (p6, p7).
1499 R2 is loaded with the address of the addend TLB entry.
1500 R57 is loaded with the address, zero extented on 32-bit targets. */
1501 static inline void tcg_out_qemu_tlb(TCGContext *s, TCGArg addr_reg,
1502 TCGMemOp s_bits, uint64_t offset_rw,
1503 uint64_t offset_addend)
1504 {
1505 tcg_out_bundle(s, mII,
1506 INSN_NOP_M,
1507 tcg_opc_i11(TCG_REG_P0, OPC_EXTR_U_I11, TCG_REG_R2,
1508 addr_reg, TARGET_PAGE_BITS, CPU_TLB_BITS - 1),
1509 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12, TCG_REG_R2,
1510 TCG_REG_R2, 63 - CPU_TLB_ENTRY_BITS,
1511 63 - CPU_TLB_ENTRY_BITS));
1512 tcg_out_bundle(s, mII,
1513 tcg_opc_a5 (TCG_REG_P0, OPC_ADDL_A5, TCG_REG_R2,
1514 offset_rw, TCG_REG_R2),
1515 #if TARGET_LONG_BITS == 32
1516 tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29, TCG_REG_R57, addr_reg),
1517 #else
1518 tcg_opc_a4(TCG_REG_P0, OPC_ADDS_A4, TCG_REG_R57,
1519 0, addr_reg),
1520 #endif
1521 tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
1522 TCG_REG_R2, TCG_AREG0));
1523 tcg_out_bundle(s, mII,
1524 tcg_opc_m3 (TCG_REG_P0,
1525 (TARGET_LONG_BITS == 32
1526 ? OPC_LD4_M3 : OPC_LD8_M3), TCG_REG_R56,
1527 TCG_REG_R2, offset_addend - offset_rw),
1528 tcg_opc_i14(TCG_REG_P0, OPC_DEP_I14, TCG_REG_R3, 0,
1529 TCG_REG_R57, 63 - s_bits,
1530 TARGET_PAGE_BITS - s_bits - 1),
1531 tcg_opc_a6 (TCG_REG_P0, OPC_CMP_EQ_A6, TCG_REG_P6,
1532 TCG_REG_P7, TCG_REG_R3, TCG_REG_R56));
1533 }
1534
1535 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
1536 int mmu_idx) */
1537 static const void * const qemu_ld_helpers[4] = {
1538 helper_ldb_mmu,
1539 helper_ldw_mmu,
1540 helper_ldl_mmu,
1541 helper_ldq_mmu,
1542 };
1543
1544 static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
1545 TCGMemOp opc)
1546 {
1547 static const uint64_t opc_ld_m1[4] = {
1548 OPC_LD1_M1, OPC_LD2_M1, OPC_LD4_M1, OPC_LD8_M1
1549 };
1550 static const uint64_t opc_ext_i29[8] = {
1551 OPC_ZXT1_I29, OPC_ZXT2_I29, OPC_ZXT4_I29, 0,
1552 OPC_SXT1_I29, OPC_SXT2_I29, OPC_SXT4_I29, 0
1553 };
1554 int addr_reg, data_reg, mem_index;
1555 TCGMemOp s_bits, bswap;
1556
1557 data_reg = *args++;
1558 addr_reg = *args++;
1559 mem_index = *args;
1560 s_bits = opc & MO_SIZE;
1561 bswap = opc & MO_BSWAP;
1562
1563 /* Read the TLB entry */
1564 tcg_out_qemu_tlb(s, addr_reg, s_bits,
1565 offsetof(CPUArchState, tlb_table[mem_index][0].addr_read),
1566 offsetof(CPUArchState, tlb_table[mem_index][0].addend));
1567
1568 /* P6 is the fast path, and P7 the slow path */
1569 tcg_out_bundle(s, mLX,
1570 tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4,
1571 TCG_REG_R56, 0, TCG_AREG0),
1572 tcg_opc_l2 ((tcg_target_long) qemu_ld_helpers[s_bits]),
1573 tcg_opc_x2 (TCG_REG_P7, OPC_MOVL_X2, TCG_REG_R2,
1574 (tcg_target_long) qemu_ld_helpers[s_bits]));
1575 tcg_out_bundle(s, MmI,
1576 tcg_opc_m3 (TCG_REG_P0, OPC_LD8_M3, TCG_REG_R3,
1577 TCG_REG_R2, 8),
1578 tcg_opc_a1 (TCG_REG_P6, OPC_ADD_A1, TCG_REG_R3,
1579 TCG_REG_R3, TCG_REG_R57),
1580 tcg_opc_i21(TCG_REG_P7, OPC_MOV_I21, TCG_REG_B6,
1581 TCG_REG_R3, 0));
1582 if (bswap && s_bits == MO_16) {
1583 tcg_out_bundle(s, MmI,
1584 tcg_opc_m1 (TCG_REG_P6, opc_ld_m1[s_bits],
1585 TCG_REG_R8, TCG_REG_R3),
1586 tcg_opc_m1 (TCG_REG_P7, OPC_LD8_M1, TCG_REG_R1, TCG_REG_R2),
1587 tcg_opc_i12(TCG_REG_P6, OPC_DEP_Z_I12,
1588 TCG_REG_R8, TCG_REG_R8, 15, 15));
1589 } else if (bswap && s_bits == MO_32) {
1590 tcg_out_bundle(s, MmI,
1591 tcg_opc_m1 (TCG_REG_P6, opc_ld_m1[s_bits],
1592 TCG_REG_R8, TCG_REG_R3),
1593 tcg_opc_m1 (TCG_REG_P7, OPC_LD8_M1, TCG_REG_R1, TCG_REG_R2),
1594 tcg_opc_i12(TCG_REG_P6, OPC_DEP_Z_I12,
1595 TCG_REG_R8, TCG_REG_R8, 31, 31));
1596 } else {
1597 tcg_out_bundle(s, mmI,
1598 tcg_opc_m1 (TCG_REG_P6, opc_ld_m1[s_bits],
1599 TCG_REG_R8, TCG_REG_R3),
1600 tcg_opc_m1 (TCG_REG_P7, OPC_LD8_M1, TCG_REG_R1, TCG_REG_R2),
1601 INSN_NOP_I);
1602 }
1603 if (!bswap) {
1604 tcg_out_bundle(s, miB,
1605 tcg_opc_a5 (TCG_REG_P7, OPC_ADDL_A5, TCG_REG_R58,
1606 mem_index, TCG_REG_R0),
1607 INSN_NOP_I,
1608 tcg_opc_b5 (TCG_REG_P7, OPC_BR_CALL_SPTK_MANY_B5,
1609 TCG_REG_B0, TCG_REG_B6));
1610 } else {
1611 tcg_out_bundle(s, miB,
1612 tcg_opc_a5 (TCG_REG_P7, OPC_ADDL_A5, TCG_REG_R58,
1613 mem_index, TCG_REG_R0),
1614 tcg_opc_i3 (TCG_REG_P6, OPC_MUX1_I3,
1615 TCG_REG_R8, TCG_REG_R8, 0xb),
1616 tcg_opc_b5 (TCG_REG_P7, OPC_BR_CALL_SPTK_MANY_B5,
1617 TCG_REG_B0, TCG_REG_B6));
1618 }
1619
1620 if (s_bits == MO_64) {
1621 tcg_out_bundle(s, miI,
1622 INSN_NOP_M,
1623 INSN_NOP_I,
1624 tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
1625 data_reg, 0, TCG_REG_R8));
1626 } else {
1627 tcg_out_bundle(s, miI,
1628 INSN_NOP_M,
1629 INSN_NOP_I,
1630 tcg_opc_i29(TCG_REG_P0, opc_ext_i29[opc & MO_SSIZE],
1631 data_reg, TCG_REG_R8));
1632 }
1633 }
1634
1635 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
1636 uintxx_t val, int mmu_idx) */
1637 static const void * const qemu_st_helpers[4] = {
1638 helper_stb_mmu,
1639 helper_stw_mmu,
1640 helper_stl_mmu,
1641 helper_stq_mmu,
1642 };
1643
1644 static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1645 TCGMemOp opc)
1646 {
1647 static const uint64_t opc_st_m4[4] = {
1648 OPC_ST1_M4, OPC_ST2_M4, OPC_ST4_M4, OPC_ST8_M4
1649 };
1650 int addr_reg, data_reg, mem_index;
1651 TCGMemOp s_bits;
1652
1653 data_reg = *args++;
1654 addr_reg = *args++;
1655 mem_index = *args;
1656 s_bits = opc & MO_SIZE;
1657
1658 tcg_out_qemu_tlb(s, addr_reg, s_bits,
1659 offsetof(CPUArchState, tlb_table[mem_index][0].addr_write),
1660 offsetof(CPUArchState, tlb_table[mem_index][0].addend));
1661
1662 /* P6 is the fast path, and P7 the slow path */
1663 tcg_out_bundle(s, mLX,
1664 tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4,
1665 TCG_REG_R56, 0, TCG_AREG0),
1666 tcg_opc_l2 ((tcg_target_long) qemu_st_helpers[s_bits]),
1667 tcg_opc_x2 (TCG_REG_P7, OPC_MOVL_X2, TCG_REG_R2,
1668 (tcg_target_long) qemu_st_helpers[s_bits]));
1669 tcg_out_bundle(s, MmI,
1670 tcg_opc_m3 (TCG_REG_P0, OPC_LD8_M3, TCG_REG_R3,
1671 TCG_REG_R2, 8),
1672 tcg_opc_a1 (TCG_REG_P6, OPC_ADD_A1, TCG_REG_R3,
1673 TCG_REG_R3, TCG_REG_R57),
1674 tcg_opc_i21(TCG_REG_P7, OPC_MOV_I21, TCG_REG_B6,
1675 TCG_REG_R3, 0));
1676
1677 switch (opc) {
1678 case MO_8:
1679 case MO_16:
1680 case MO_32:
1681 case MO_64:
1682 tcg_out_bundle(s, mii,
1683 tcg_opc_m1 (TCG_REG_P7, OPC_LD8_M1,
1684 TCG_REG_R1, TCG_REG_R2),
1685 tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4, TCG_REG_R58,
1686 0, data_reg),
1687 INSN_NOP_I);
1688 break;
1689
1690 case MO_16 | MO_BSWAP:
1691 tcg_out_bundle(s, miI,
1692 tcg_opc_m1 (TCG_REG_P7, OPC_LD8_M1,
1693 TCG_REG_R1, TCG_REG_R2),
1694 INSN_NOP_I,
1695 tcg_opc_i12(TCG_REG_P6, OPC_DEP_Z_I12,
1696 TCG_REG_R2, data_reg, 15, 15));
1697 tcg_out_bundle(s, miI,
1698 tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4, TCG_REG_R58,
1699 0, data_reg),
1700 INSN_NOP_I,
1701 tcg_opc_i3 (TCG_REG_P6, OPC_MUX1_I3,
1702 TCG_REG_R2, TCG_REG_R2, 0xb));
1703 data_reg = TCG_REG_R2;
1704 break;
1705
1706 case MO_32 | MO_BSWAP:
1707 tcg_out_bundle(s, miI,
1708 tcg_opc_m1 (TCG_REG_P7, OPC_LD8_M1,
1709 TCG_REG_R1, TCG_REG_R2),
1710 INSN_NOP_I,
1711 tcg_opc_i12(TCG_REG_P6, OPC_DEP_Z_I12,
1712 TCG_REG_R2, data_reg, 31, 31));
1713 tcg_out_bundle(s, miI,
1714 tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4, TCG_REG_R58,
1715 0, data_reg),
1716 INSN_NOP_I,
1717 tcg_opc_i3 (TCG_REG_P6, OPC_MUX1_I3,
1718 TCG_REG_R2, TCG_REG_R2, 0xb));
1719 data_reg = TCG_REG_R2;
1720 break;
1721
1722 case MO_64 | MO_BSWAP:
1723 tcg_out_bundle(s, miI,
1724 tcg_opc_m1 (TCG_REG_P7, OPC_LD8_M1,
1725 TCG_REG_R1, TCG_REG_R2),
1726 tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4, TCG_REG_R58,
1727 0, data_reg),
1728 tcg_opc_i3 (TCG_REG_P6, OPC_MUX1_I3,
1729 TCG_REG_R2, data_reg, 0xb));
1730 data_reg = TCG_REG_R2;
1731 break;
1732
1733 default:
1734 tcg_abort();
1735 }
1736
1737 tcg_out_bundle(s, miB,
1738 tcg_opc_m4 (TCG_REG_P6, opc_st_m4[s_bits],
1739 data_reg, TCG_REG_R3),
1740 tcg_opc_a5 (TCG_REG_P7, OPC_ADDL_A5, TCG_REG_R59,
1741 mem_index, TCG_REG_R0),
1742 tcg_opc_b5 (TCG_REG_P7, OPC_BR_CALL_SPTK_MANY_B5,
1743 TCG_REG_B0, TCG_REG_B6));
1744 }
1745
1746 #else /* !CONFIG_SOFTMMU */
1747
1748 static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
1749 TCGMemOp opc)
1750 {
1751 static uint64_t const opc_ld_m1[4] = {
1752 OPC_LD1_M1, OPC_LD2_M1, OPC_LD4_M1, OPC_LD8_M1
1753 };
1754 static uint64_t const opc_sxt_i29[4] = {
1755 OPC_SXT1_I29, OPC_SXT2_I29, OPC_SXT4_I29, 0
1756 };
1757 int addr_reg, data_reg;
1758 TCGMemOp s_bits, bswap;
1759
1760 data_reg = *args++;
1761 addr_reg = *args++;
1762 s_bits = opc & MO_SIZE;
1763 bswap = opc & MO_BSWAP;
1764
1765 #if TARGET_LONG_BITS == 32
1766 if (GUEST_BASE != 0) {
1767 tcg_out_bundle(s, mII,
1768 INSN_NOP_M,
1769 tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
1770 TCG_REG_R3, addr_reg),
1771 tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
1772 TCG_GUEST_BASE_REG, TCG_REG_R3));
1773 } else {
1774 tcg_out_bundle(s, miI,
1775 INSN_NOP_M,
1776 tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
1777 TCG_REG_R2, addr_reg),
1778 INSN_NOP_I);
1779 }
1780
1781 if (!bswap) {
1782 if (!(opc & MO_SIGN)) {
1783 tcg_out_bundle(s, miI,
1784 tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
1785 data_reg, TCG_REG_R2),
1786 INSN_NOP_I,
1787 INSN_NOP_I);
1788 } else {
1789 tcg_out_bundle(s, mII,
1790 tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
1791 data_reg, TCG_REG_R2),
1792 INSN_NOP_I,
1793 tcg_opc_i29(TCG_REG_P0, opc_sxt_i29[s_bits],
1794 data_reg, data_reg));
1795 }
1796 } else if (s_bits == MO_64) {
1797 tcg_out_bundle(s, mII,
1798 tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
1799 data_reg, TCG_REG_R2),
1800 INSN_NOP_I,
1801 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
1802 data_reg, data_reg, 0xb));
1803 } else {
1804 if (s_bits == MO_16) {
1805 tcg_out_bundle(s, mII,
1806 tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
1807 data_reg, TCG_REG_R2),
1808 INSN_NOP_I,
1809 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
1810 data_reg, data_reg, 15, 15));
1811 } else {
1812 tcg_out_bundle(s, mII,
1813 tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
1814 data_reg, TCG_REG_R2),
1815 INSN_NOP_I,
1816 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
1817 data_reg, data_reg, 31, 31));
1818 }
1819 if (!(opc & MO_SIGN)) {
1820 tcg_out_bundle(s, miI,
1821 INSN_NOP_M,
1822 INSN_NOP_I,
1823 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
1824 data_reg, data_reg, 0xb));
1825 } else {
1826 tcg_out_bundle(s, mII,
1827 INSN_NOP_M,
1828 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
1829 data_reg, data_reg, 0xb),
1830 tcg_opc_i29(TCG_REG_P0, opc_sxt_i29[s_bits],
1831 data_reg, data_reg));
1832 }
1833 }
1834 #else
1835 if (GUEST_BASE != 0) {
1836 tcg_out_bundle(s, MmI,
1837 tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
1838 TCG_GUEST_BASE_REG, addr_reg),
1839 tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
1840 data_reg, TCG_REG_R2),
1841 INSN_NOP_I);
1842 } else {
1843 tcg_out_bundle(s, mmI,
1844 INSN_NOP_M,
1845 tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
1846 data_reg, addr_reg),
1847 INSN_NOP_I);
1848 }
1849
1850 if (bswap && s_bits == MO_16) {
1851 tcg_out_bundle(s, mII,
1852 INSN_NOP_M,
1853 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
1854 data_reg, data_reg, 15, 15),
1855 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
1856 data_reg, data_reg, 0xb));
1857 } else if (bswap && s_bits == MO_32) {
1858 tcg_out_bundle(s, mII,
1859 INSN_NOP_M,
1860 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
1861 data_reg, data_reg, 31, 31),
1862 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
1863 data_reg, data_reg, 0xb));
1864 } else if (bswap && s_bits == MO_64) {
1865 tcg_out_bundle(s, miI,
1866 INSN_NOP_M,
1867 INSN_NOP_I,
1868 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
1869 data_reg, data_reg, 0xb));
1870 }
1871 if (opc & MO_SIGN) {
1872 tcg_out_bundle(s, miI,
1873 INSN_NOP_M,
1874 INSN_NOP_I,
1875 tcg_opc_i29(TCG_REG_P0, opc_sxt_i29[s_bits],
1876 data_reg, data_reg));
1877 }
1878 #endif
1879 }
1880
1881 static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1882 TCGMemOp opc)
1883 {
1884 static uint64_t const opc_st_m4[4] = {
1885 OPC_ST1_M4, OPC_ST2_M4, OPC_ST4_M4, OPC_ST8_M4
1886 };
1887 int addr_reg, data_reg;
1888 #if TARGET_LONG_BITS == 64
1889 uint64_t add_guest_base;
1890 #endif
1891 TCGMemOp s_bits, bswap;
1892
1893 data_reg = *args++;
1894 addr_reg = *args++;
1895 s_bits = opc & MO_SIZE;
1896 bswap = opc & MO_BSWAP;
1897
1898 #if TARGET_LONG_BITS == 32
1899 if (GUEST_BASE != 0) {
1900 tcg_out_bundle(s, mII,
1901 INSN_NOP_M,
1902 tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
1903 TCG_REG_R3, addr_reg),
1904 tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
1905 TCG_GUEST_BASE_REG, TCG_REG_R3));
1906 } else {
1907 tcg_out_bundle(s, miI,
1908 INSN_NOP_M,
1909 tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
1910 TCG_REG_R2, addr_reg),
1911 INSN_NOP_I);
1912 }
1913
1914 if (bswap) {
1915 if (s_bits == MO_16) {
1916 tcg_out_bundle(s, mII,
1917 INSN_NOP_M,
1918 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
1919 TCG_REG_R3, data_reg, 15, 15),
1920 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
1921 TCG_REG_R3, TCG_REG_R3, 0xb));
1922 data_reg = TCG_REG_R3;
1923 } else if (s_bits == MO_32) {
1924 tcg_out_bundle(s, mII,
1925 INSN_NOP_M,
1926 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
1927 TCG_REG_R3, data_reg, 31, 31),
1928 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
1929 TCG_REG_R3, TCG_REG_R3, 0xb));
1930 data_reg = TCG_REG_R3;
1931 } else if (s_bits == MO_64) {
1932 tcg_out_bundle(s, miI,
1933 INSN_NOP_M,
1934 INSN_NOP_I,
1935 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
1936 TCG_REG_R3, data_reg, 0xb));
1937 data_reg = TCG_REG_R3;
1938 }
1939 }
1940 tcg_out_bundle(s, mmI,
1941 tcg_opc_m4 (TCG_REG_P0, opc_st_m4[s_bits],
1942 data_reg, TCG_REG_R2),
1943 INSN_NOP_M,
1944 INSN_NOP_I);
1945 #else
1946 if (GUEST_BASE != 0) {
1947 add_guest_base = tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
1948 TCG_GUEST_BASE_REG, addr_reg);
1949 addr_reg = TCG_REG_R2;
1950 } else {
1951 add_guest_base = INSN_NOP_M;
1952 }
1953
1954 if (!bswap) {
1955 tcg_out_bundle(s, (GUEST_BASE ? MmI : mmI),
1956 add_guest_base,
1957 tcg_opc_m4 (TCG_REG_P0, opc_st_m4[s_bits],
1958 data_reg, addr_reg),
1959 INSN_NOP_I);
1960 } else {
1961 if (s_bits == MO_16) {
1962 tcg_out_bundle(s, mII,
1963 add_guest_base,
1964 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
1965 TCG_REG_R3, data_reg, 15, 15),
1966 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
1967 TCG_REG_R3, TCG_REG_R3, 0xb));
1968 data_reg = TCG_REG_R3;
1969 } else if (s_bits == MO_32) {
1970 tcg_out_bundle(s, mII,
1971 add_guest_base,
1972 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
1973 TCG_REG_R3, data_reg, 31, 31),
1974 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
1975 TCG_REG_R3, TCG_REG_R3, 0xb));
1976 data_reg = TCG_REG_R3;
1977 } else if (s_bits == MO_64) {
1978 tcg_out_bundle(s, miI,
1979 add_guest_base,
1980 INSN_NOP_I,
1981 tcg_opc_i3 (TCG_REG_P0, OPC_MUX1_I3,
1982 TCG_REG_R3, data_reg, 0xb));
1983 data_reg = TCG_REG_R3;
1984 }
1985 tcg_out_bundle(s, miI,
1986 tcg_opc_m4 (TCG_REG_P0, opc_st_m4[s_bits],
1987 data_reg, addr_reg),
1988 INSN_NOP_I,
1989 INSN_NOP_I);
1990 }
1991 #endif
1992 }
1993
1994 #endif
1995
1996 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1997 const TCGArg *args, const int *const_args)
1998 {
1999 switch(opc) {
2000 case INDEX_op_exit_tb:
2001 tcg_out_exit_tb(s, args[0]);
2002 break;
2003 case INDEX_op_br:
2004 tcg_out_br(s, args[0]);
2005 break;
2006 case INDEX_op_call:
2007 if (likely(const_args[0])) {
2008 tcg_out_calli(s, args[0]);
2009 } else {
2010 tcg_out_callr(s, args[0]);
2011 }
2012 break;
2013 case INDEX_op_goto_tb:
2014 tcg_out_goto_tb(s, args[0]);
2015 break;
2016
2017 case INDEX_op_movi_i32:
2018 tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
2019 break;
2020 case INDEX_op_movi_i64:
2021 tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
2022 break;
2023
2024 case INDEX_op_ld8u_i32:
2025 case INDEX_op_ld8u_i64:
2026 tcg_out_ld_rel(s, OPC_LD1_M1, args[0], args[1], args[2]);
2027 break;
2028 case INDEX_op_ld8s_i32:
2029 case INDEX_op_ld8s_i64:
2030 tcg_out_ld_rel(s, OPC_LD1_M1, args[0], args[1], args[2]);
2031 tcg_out_ext(s, OPC_SXT1_I29, args[0], args[0]);
2032 break;
2033 case INDEX_op_ld16u_i32:
2034 case INDEX_op_ld16u_i64:
2035 tcg_out_ld_rel(s, OPC_LD2_M1, args[0], args[1], args[2]);
2036 break;
2037 case INDEX_op_ld16s_i32:
2038 case INDEX_op_ld16s_i64:
2039 tcg_out_ld_rel(s, OPC_LD2_M1, args[0], args[1], args[2]);
2040 tcg_out_ext(s, OPC_SXT2_I29, args[0], args[0]);
2041 break;
2042 case INDEX_op_ld_i32:
2043 case INDEX_op_ld32u_i64:
2044 tcg_out_ld_rel(s, OPC_LD4_M1, args[0], args[1], args[2]);
2045 break;
2046 case INDEX_op_ld32s_i64:
2047 tcg_out_ld_rel(s, OPC_LD4_M1, args[0], args[1], args[2]);
2048 tcg_out_ext(s, OPC_SXT4_I29, args[0], args[0]);
2049 break;
2050 case INDEX_op_ld_i64:
2051 tcg_out_ld_rel(s, OPC_LD8_M1, args[0], args[1], args[2]);
2052 break;
2053 case INDEX_op_st8_i32:
2054 case INDEX_op_st8_i64:
2055 tcg_out_st_rel(s, OPC_ST1_M4, args[0], args[1], args[2]);
2056 break;
2057 case INDEX_op_st16_i32:
2058 case INDEX_op_st16_i64:
2059 tcg_out_st_rel(s, OPC_ST2_M4, args[0], args[1], args[2]);
2060 break;
2061 case INDEX_op_st_i32:
2062 case INDEX_op_st32_i64:
2063 tcg_out_st_rel(s, OPC_ST4_M4, args[0], args[1], args[2]);
2064 break;
2065 case INDEX_op_st_i64:
2066 tcg_out_st_rel(s, OPC_ST8_M4, args[0], args[1], args[2]);
2067 break;
2068
2069 case INDEX_op_add_i32:
2070 case INDEX_op_add_i64:
2071 tcg_out_alu(s, OPC_ADD_A1, args[0], args[1], const_args[1],
2072 args[2], const_args[2]);
2073 break;
2074 case INDEX_op_sub_i32:
2075 case INDEX_op_sub_i64:
2076 tcg_out_alu(s, OPC_SUB_A1, args[0], args[1], const_args[1],
2077 args[2], const_args[2]);
2078 break;
2079
2080 case INDEX_op_and_i32:
2081 case INDEX_op_and_i64:
2082 tcg_out_alu(s, OPC_AND_A1, args[0], args[1], const_args[1],
2083 args[2], const_args[2]);
2084 break;
2085 case INDEX_op_andc_i32:
2086 case INDEX_op_andc_i64:
2087 tcg_out_alu(s, OPC_ANDCM_A1, args[0], args[1], const_args[1],
2088 args[2], const_args[2]);
2089 break;
2090 case INDEX_op_eqv_i32:
2091 case INDEX_op_eqv_i64:
2092 tcg_out_eqv(s, args[0], args[1], const_args[1],
2093 args[2], const_args[2]);
2094 break;
2095 case INDEX_op_nand_i32:
2096 case INDEX_op_nand_i64:
2097 tcg_out_nand(s, args[0], args[1], const_args[1],
2098 args[2], const_args[2]);
2099 break;
2100 case INDEX_op_nor_i32:
2101 case INDEX_op_nor_i64:
2102 tcg_out_nor(s, args[0], args[1], const_args[1],
2103 args[2], const_args[2]);
2104 break;
2105 case INDEX_op_or_i32:
2106 case INDEX_op_or_i64:
2107 tcg_out_alu(s, OPC_OR_A1, args[0], args[1], const_args[1],
2108 args[2], const_args[2]);
2109 break;
2110 case INDEX_op_orc_i32:
2111 case INDEX_op_orc_i64:
2112 tcg_out_orc(s, args[0], args[1], const_args[1],
2113 args[2], const_args[2]);
2114 break;
2115 case INDEX_op_xor_i32:
2116 case INDEX_op_xor_i64:
2117 tcg_out_alu(s, OPC_XOR_A1, args[0], args[1], const_args[1],
2118 args[2], const_args[2]);
2119 break;
2120
2121 case INDEX_op_mul_i32:
2122 case INDEX_op_mul_i64:
2123 tcg_out_mul(s, args[0], args[1], args[2]);
2124 break;
2125
2126 case INDEX_op_sar_i32:
2127 tcg_out_sar_i32(s, args[0], args[1], args[2], const_args[2]);
2128 break;
2129 case INDEX_op_sar_i64:
2130 tcg_out_sar_i64(s, args[0], args[1], args[2], const_args[2]);
2131 break;
2132 case INDEX_op_shl_i32:
2133 tcg_out_shl_i32(s, args[0], args[1], args[2], const_args[2]);
2134 break;
2135 case INDEX_op_shl_i64:
2136 tcg_out_shl_i64(s, args[0], args[1], args[2], const_args[2]);
2137 break;
2138 case INDEX_op_shr_i32:
2139 tcg_out_shr_i32(s, args[0], args[1], args[2], const_args[2]);
2140 break;
2141 case INDEX_op_shr_i64:
2142 tcg_out_shr_i64(s, args[0], args[1], args[2], const_args[2]);
2143 break;
2144 case INDEX_op_rotl_i32:
2145 tcg_out_rotl_i32(s, args[0], args[1], args[2], const_args[2]);
2146 break;
2147 case INDEX_op_rotl_i64:
2148 tcg_out_rotl_i64(s, args[0], args[1], args[2], const_args[2]);
2149 break;
2150 case INDEX_op_rotr_i32:
2151 tcg_out_rotr_i32(s, args[0], args[1], args[2], const_args[2]);
2152 break;
2153 case INDEX_op_rotr_i64:
2154 tcg_out_rotr_i64(s, args[0], args[1], args[2], const_args[2]);
2155 break;
2156
2157 case INDEX_op_ext8s_i32:
2158 case INDEX_op_ext8s_i64:
2159 tcg_out_ext(s, OPC_SXT1_I29, args[0], args[1]);
2160 break;
2161 case INDEX_op_ext8u_i32:
2162 case INDEX_op_ext8u_i64:
2163 tcg_out_ext(s, OPC_ZXT1_I29, args[0], args[1]);
2164 break;
2165 case INDEX_op_ext16s_i32:
2166 case INDEX_op_ext16s_i64:
2167 tcg_out_ext(s, OPC_SXT2_I29, args[0], args[1]);
2168 break;
2169 case INDEX_op_ext16u_i32:
2170 case INDEX_op_ext16u_i64:
2171 tcg_out_ext(s, OPC_ZXT2_I29, args[0], args[1]);
2172 break;
2173 case INDEX_op_ext32s_i64:
2174 tcg_out_ext(s, OPC_SXT4_I29, args[0], args[1]);
2175 break;
2176 case INDEX_op_ext32u_i64:
2177 tcg_out_ext(s, OPC_ZXT4_I29, args[0], args[1]);
2178 break;
2179
2180 case INDEX_op_bswap16_i32:
2181 case INDEX_op_bswap16_i64:
2182 tcg_out_bswap16(s, args[0], args[1]);
2183 break;
2184 case INDEX_op_bswap32_i32:
2185 case INDEX_op_bswap32_i64:
2186 tcg_out_bswap32(s, args[0], args[1]);
2187 break;
2188 case INDEX_op_bswap64_i64:
2189 tcg_out_bswap64(s, args[0], args[1]);
2190 break;
2191
2192 case INDEX_op_deposit_i32:
2193 case INDEX_op_deposit_i64:
2194 tcg_out_deposit(s, args[0], args[1], args[2], const_args[2],
2195 args[3], args[4]);
2196 break;
2197
2198 case INDEX_op_brcond_i32:
2199 tcg_out_brcond(s, args[2], args[0], args[1], args[3], 1);
2200 break;
2201 case INDEX_op_brcond_i64:
2202 tcg_out_brcond(s, args[2], args[0], args[1], args[3], 0);
2203 break;
2204 case INDEX_op_setcond_i32:
2205 tcg_out_setcond(s, args[3], args[0], args[1], args[2], 1);
2206 break;
2207 case INDEX_op_setcond_i64:
2208 tcg_out_setcond(s, args[3], args[0], args[1], args[2], 0);
2209 break;
2210 case INDEX_op_movcond_i32:
2211 tcg_out_movcond(s, args[5], args[0], args[1], args[2],
2212 args[3], const_args[3], args[4], const_args[4], 1);
2213 break;
2214 case INDEX_op_movcond_i64:
2215 tcg_out_movcond(s, args[5], args[0], args[1], args[2],
2216 args[3], const_args[3], args[4], const_args[4], 0);
2217 break;
2218
2219 case INDEX_op_qemu_ld8u:
2220 tcg_out_qemu_ld(s, args, MO_UB);
2221 break;
2222 case INDEX_op_qemu_ld8s:
2223 tcg_out_qemu_ld(s, args, MO_SB);
2224 break;
2225 case INDEX_op_qemu_ld16u:
2226 tcg_out_qemu_ld(s, args, MO_TEUW);
2227 break;
2228 case INDEX_op_qemu_ld16s:
2229 tcg_out_qemu_ld(s, args, MO_TESW);
2230 break;
2231 case INDEX_op_qemu_ld32:
2232 case INDEX_op_qemu_ld32u:
2233 tcg_out_qemu_ld(s, args, MO_TEUL);
2234 break;
2235 case INDEX_op_qemu_ld32s:
2236 tcg_out_qemu_ld(s, args, MO_TESL);
2237 break;
2238 case INDEX_op_qemu_ld64:
2239 tcg_out_qemu_ld(s, args, MO_TEQ);
2240 break;
2241
2242 case INDEX_op_qemu_st8:
2243 tcg_out_qemu_st(s, args, MO_UB);
2244 break;
2245 case INDEX_op_qemu_st16:
2246 tcg_out_qemu_st(s, args, MO_TEUW);
2247 break;
2248 case INDEX_op_qemu_st32:
2249 tcg_out_qemu_st(s, args, MO_TEUL);
2250 break;
2251 case INDEX_op_qemu_st64:
2252 tcg_out_qemu_st(s, args, MO_TEQ);
2253 break;
2254
2255 default:
2256 tcg_abort();
2257 }
2258 }
2259
2260 static const TCGTargetOpDef ia64_op_defs[] = {
2261 { INDEX_op_br, { } },
2262 { INDEX_op_call, { "ri" } },
2263 { INDEX_op_exit_tb, { } },
2264 { INDEX_op_goto_tb, { } },
2265
2266 { INDEX_op_mov_i32, { "r", "r" } },
2267 { INDEX_op_movi_i32, { "r" } },
2268
2269 { INDEX_op_ld8u_i32, { "r", "r" } },
2270 { INDEX_op_ld8s_i32, { "r", "r" } },
2271 { INDEX_op_ld16u_i32, { "r", "r" } },
2272 { INDEX_op_ld16s_i32, { "r", "r" } },
2273 { INDEX_op_ld_i32, { "r", "r" } },
2274 { INDEX_op_st8_i32, { "rZ", "r" } },
2275 { INDEX_op_st16_i32, { "rZ", "r" } },
2276 { INDEX_op_st_i32, { "rZ", "r" } },
2277
2278 { INDEX_op_add_i32, { "r", "rI", "rI" } },
2279 { INDEX_op_sub_i32, { "r", "rI", "rI" } },
2280
2281 { INDEX_op_and_i32, { "r", "rI", "rI" } },
2282 { INDEX_op_andc_i32, { "r", "rI", "rI" } },
2283 { INDEX_op_eqv_i32, { "r", "rZ", "rZ" } },
2284 { INDEX_op_nand_i32, { "r", "rZ", "rZ" } },
2285 { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
2286 { INDEX_op_or_i32, { "r", "rI", "rI" } },
2287 { INDEX_op_orc_i32, { "r", "rZ", "rZ" } },
2288 { INDEX_op_xor_i32, { "r", "rI", "rI" } },
2289
2290 { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
2291
2292 { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
2293 { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
2294 { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
2295 { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
2296 { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
2297
2298 { INDEX_op_ext8s_i32, { "r", "rZ"} },
2299 { INDEX_op_ext8u_i32, { "r", "rZ"} },
2300 { INDEX_op_ext16s_i32, { "r", "rZ"} },
2301 { INDEX_op_ext16u_i32, { "r", "rZ"} },
2302
2303 { INDEX_op_bswap16_i32, { "r", "rZ" } },
2304 { INDEX_op_bswap32_i32, { "r", "rZ" } },
2305
2306 { INDEX_op_brcond_i32, { "rZ", "rZ" } },
2307 { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
2308 { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rI", "rI" } },
2309
2310 { INDEX_op_mov_i64, { "r", "r" } },
2311 { INDEX_op_movi_i64, { "r" } },
2312
2313 { INDEX_op_ld8u_i64, { "r", "r" } },
2314 { INDEX_op_ld8s_i64, { "r", "r" } },
2315 { INDEX_op_ld16u_i64, { "r", "r" } },
2316 { INDEX_op_ld16s_i64, { "r", "r" } },
2317 { INDEX_op_ld32u_i64, { "r", "r" } },
2318 { INDEX_op_ld32s_i64, { "r", "r" } },
2319 { INDEX_op_ld_i64, { "r", "r" } },
2320 { INDEX_op_st8_i64, { "rZ", "r" } },
2321 { INDEX_op_st16_i64, { "rZ", "r" } },
2322 { INDEX_op_st32_i64, { "rZ", "r" } },
2323 { INDEX_op_st_i64, { "rZ", "r" } },
2324
2325 { INDEX_op_add_i64, { "r", "rI", "rI" } },
2326 { INDEX_op_sub_i64, { "r", "rI", "rI" } },
2327
2328 { INDEX_op_and_i64, { "r", "rI", "rI" } },
2329 { INDEX_op_andc_i64, { "r", "rI", "rI" } },
2330 { INDEX_op_eqv_i64, { "r", "rZ", "rZ" } },
2331 { INDEX_op_nand_i64, { "r", "rZ", "rZ" } },
2332 { INDEX_op_nor_i64, { "r", "rZ", "rZ" } },
2333 { INDEX_op_or_i64, { "r", "rI", "rI" } },
2334 { INDEX_op_orc_i64, { "r", "rZ", "rZ" } },
2335 { INDEX_op_xor_i64, { "r", "rI", "rI" } },
2336
2337 { INDEX_op_mul_i64, { "r", "rZ", "rZ" } },
2338
2339 { INDEX_op_sar_i64, { "r", "rZ", "ri" } },
2340 { INDEX_op_shl_i64, { "r", "rZ", "ri" } },
2341 { INDEX_op_shr_i64, { "r", "rZ", "ri" } },
2342 { INDEX_op_rotl_i64, { "r", "rZ", "ri" } },
2343 { INDEX_op_rotr_i64, { "r", "rZ", "ri" } },
2344
2345 { INDEX_op_ext8s_i64, { "r", "rZ"} },
2346 { INDEX_op_ext8u_i64, { "r", "rZ"} },
2347 { INDEX_op_ext16s_i64, { "r", "rZ"} },
2348 { INDEX_op_ext16u_i64, { "r", "rZ"} },
2349 { INDEX_op_ext32s_i64, { "r", "rZ"} },
2350 { INDEX_op_ext32u_i64, { "r", "rZ"} },
2351
2352 { INDEX_op_bswap16_i64, { "r", "rZ" } },
2353 { INDEX_op_bswap32_i64, { "r", "rZ" } },
2354 { INDEX_op_bswap64_i64, { "r", "rZ" } },
2355
2356 { INDEX_op_brcond_i64, { "rZ", "rZ" } },
2357 { INDEX_op_setcond_i64, { "r", "rZ", "rZ" } },
2358 { INDEX_op_movcond_i64, { "r", "rZ", "rZ", "rI", "rI" } },
2359
2360 { INDEX_op_deposit_i32, { "r", "rZ", "ri" } },
2361 { INDEX_op_deposit_i64, { "r", "rZ", "ri" } },
2362
2363 { INDEX_op_qemu_ld8u, { "r", "r" } },
2364 { INDEX_op_qemu_ld8s, { "r", "r" } },
2365 { INDEX_op_qemu_ld16u, { "r", "r" } },
2366 { INDEX_op_qemu_ld16s, { "r", "r" } },
2367 { INDEX_op_qemu_ld32, { "r", "r" } },
2368 { INDEX_op_qemu_ld32u, { "r", "r" } },
2369 { INDEX_op_qemu_ld32s, { "r", "r" } },
2370 { INDEX_op_qemu_ld64, { "r", "r" } },
2371
2372 { INDEX_op_qemu_st8, { "SZ", "r" } },
2373 { INDEX_op_qemu_st16, { "SZ", "r" } },
2374 { INDEX_op_qemu_st32, { "SZ", "r" } },
2375 { INDEX_op_qemu_st64, { "SZ", "r" } },
2376
2377 { -1 },
2378 };
2379
2380 /* Generate global QEMU prologue and epilogue code */
2381 static void tcg_target_qemu_prologue(TCGContext *s)
2382 {
2383 int frame_size;
2384
2385 /* reserve some stack space */
2386 frame_size = TCG_STATIC_CALL_ARGS_SIZE +
2387 CPU_TEMP_BUF_NLONGS * sizeof(long);
2388 frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
2389 ~(TCG_TARGET_STACK_ALIGN - 1);
2390 tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
2391 CPU_TEMP_BUF_NLONGS * sizeof(long));
2392
2393 /* First emit adhoc function descriptor */
2394 *(uint64_t *)(s->code_ptr) = (uint64_t)s->code_ptr + 16; /* entry point */
2395 s->code_ptr += 16; /* skip GP */
2396
2397 /* prologue */
2398 tcg_out_bundle(s, miI,
2399 tcg_opc_m34(TCG_REG_P0, OPC_ALLOC_M34,
2400 TCG_REG_R34, 32, 24, 0),
2401 INSN_NOP_I,
2402 tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21,
2403 TCG_REG_B6, TCG_REG_R33, 0));
2404
2405 /* ??? If GUEST_BASE < 0x200000, we could load the register via
2406 an ADDL in the M slot of the next bundle. */
2407 if (GUEST_BASE != 0) {
2408 tcg_out_bundle(s, mlx,
2409 INSN_NOP_M,
2410 tcg_opc_l2 (GUEST_BASE),
2411 tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2,
2412 TCG_GUEST_BASE_REG, GUEST_BASE));
2413 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2414 }
2415
2416 tcg_out_bundle(s, miB,
2417 tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
2418 TCG_REG_R12, -frame_size, TCG_REG_R12),
2419 tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22,
2420 TCG_REG_R33, TCG_REG_B0),
2421 tcg_opc_b4 (TCG_REG_P0, OPC_BR_SPTK_MANY_B4, TCG_REG_B6));
2422
2423 /* epilogue */
2424 tb_ret_addr = s->code_ptr;
2425 tcg_out_bundle(s, miI,
2426 INSN_NOP_M,
2427 tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21,
2428 TCG_REG_B0, TCG_REG_R33, 0),
2429 tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
2430 TCG_REG_R12, frame_size, TCG_REG_R12));
2431 tcg_out_bundle(s, miB,
2432 INSN_NOP_M,
2433 tcg_opc_i26(TCG_REG_P0, OPC_MOV_I_I26,
2434 TCG_REG_PFS, TCG_REG_R34),
2435 tcg_opc_b4 (TCG_REG_P0, OPC_BR_RET_SPTK_MANY_B4,
2436 TCG_REG_B0));
2437 }
2438
2439 static void tcg_target_init(TCGContext *s)
2440 {
2441 tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32],
2442 0xffffffffffffffffull);
2443 tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I64],
2444 0xffffffffffffffffull);
2445
2446 tcg_regset_clear(tcg_target_call_clobber_regs);
2447 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
2448 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
2449 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
2450 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11);
2451 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2452 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R15);
2453 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R16);
2454 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R17);
2455 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R18);
2456 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R19);
2457 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R20);
2458 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R21);
2459 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R22);
2460 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R23);
2461 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R24);
2462 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R25);
2463 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R26);
2464 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R27);
2465 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R28);
2466 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R29);
2467 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R30);
2468 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R31);
2469 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R56);
2470 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R57);
2471 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R58);
2472 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R59);
2473 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R60);
2474 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R61);
2475 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R62);
2476 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R63);
2477
2478 tcg_regset_clear(s->reserved_regs);
2479 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0); /* zero register */
2480 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1); /* global pointer */
2481 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2); /* internal use */
2482 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R3); /* internal use */
2483 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R12); /* stack pointer */
2484 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); /* thread pointer */
2485 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R33); /* return address */
2486 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R34); /* PFS */
2487
2488 /* The following 4 are not in use, are call-saved, but *not* saved
2489 by the prologue. Therefore we cannot use them without modifying
2490 the prologue. There doesn't seem to be any good reason to use
2491 these as opposed to the windowed registers. */
2492 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R4);
2493 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R5);
2494 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R6);
2495 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R7);
2496
2497 tcg_add_target_add_op_defs(ia64_op_defs);
2498 }