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