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