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