]> git.proxmox.com Git - mirror_qemu.git/blob - tcg/mips/tcg-target.c
Merge remote-tracking branch 'afaerber/qom-cpu.v5' into staging
[mirror_qemu.git] / tcg / mips / tcg-target.c
1 /*
2 * Tiny Code Generator for QEMU
3 *
4 * Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org>
5 * Copyright (c) 2009 Aurelien Jarno <aurelien@aurel32.net>
6 * Based on i386/tcg-target.c - Copyright (c) 2008 Fabrice Bellard
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
27 #if defined(TCG_TARGET_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
28 # define TCG_NEED_BSWAP 0
29 #else
30 # define TCG_NEED_BSWAP 1
31 #endif
32
33 #ifndef NDEBUG
34 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
35 "zero",
36 "at",
37 "v0",
38 "v1",
39 "a0",
40 "a1",
41 "a2",
42 "a3",
43 "t0",
44 "t1",
45 "t2",
46 "t3",
47 "t4",
48 "t5",
49 "t6",
50 "t7",
51 "s0",
52 "s1",
53 "s2",
54 "s3",
55 "s4",
56 "s5",
57 "s6",
58 "s7",
59 "t8",
60 "t9",
61 "k0",
62 "k1",
63 "gp",
64 "sp",
65 "fp",
66 "ra",
67 };
68 #endif
69
70 /* check if we really need so many registers :P */
71 static const int tcg_target_reg_alloc_order[] = {
72 TCG_REG_S0,
73 TCG_REG_S1,
74 TCG_REG_S2,
75 TCG_REG_S3,
76 TCG_REG_S4,
77 TCG_REG_S5,
78 TCG_REG_S6,
79 TCG_REG_S7,
80 TCG_REG_T1,
81 TCG_REG_T2,
82 TCG_REG_T3,
83 TCG_REG_T4,
84 TCG_REG_T5,
85 TCG_REG_T6,
86 TCG_REG_T7,
87 TCG_REG_T8,
88 TCG_REG_T9,
89 TCG_REG_A0,
90 TCG_REG_A1,
91 TCG_REG_A2,
92 TCG_REG_A3,
93 TCG_REG_V0,
94 TCG_REG_V1
95 };
96
97 static const int tcg_target_call_iarg_regs[4] = {
98 TCG_REG_A0,
99 TCG_REG_A1,
100 TCG_REG_A2,
101 TCG_REG_A3
102 };
103
104 static const int tcg_target_call_oarg_regs[2] = {
105 TCG_REG_V0,
106 TCG_REG_V1
107 };
108
109 static uint8_t *tb_ret_addr;
110
111 static inline uint32_t reloc_lo16_val (void *pc, tcg_target_long target)
112 {
113 return target & 0xffff;
114 }
115
116 static inline void reloc_lo16 (void *pc, tcg_target_long target)
117 {
118 *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
119 | reloc_lo16_val(pc, target);
120 }
121
122 static inline uint32_t reloc_hi16_val (void *pc, tcg_target_long target)
123 {
124 return (target >> 16) & 0xffff;
125 }
126
127 static inline void reloc_hi16 (void *pc, tcg_target_long target)
128 {
129 *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
130 | reloc_hi16_val(pc, target);
131 }
132
133 static inline uint32_t reloc_pc16_val (void *pc, tcg_target_long target)
134 {
135 int32_t disp;
136
137 disp = target - (tcg_target_long) pc - 4;
138 if (disp != (disp << 14) >> 14) {
139 tcg_abort ();
140 }
141
142 return (disp >> 2) & 0xffff;
143 }
144
145 static inline void reloc_pc16 (void *pc, tcg_target_long target)
146 {
147 *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
148 | reloc_pc16_val(pc, target);
149 }
150
151 static inline uint32_t reloc_26_val (void *pc, tcg_target_long target)
152 {
153 if ((((tcg_target_long)pc + 4) & 0xf0000000) != (target & 0xf0000000)) {
154 tcg_abort ();
155 }
156
157 return (target >> 2) & 0x3ffffff;
158 }
159
160 static inline void reloc_pc26 (void *pc, tcg_target_long target)
161 {
162 *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3ffffff)
163 | reloc_26_val(pc, target);
164 }
165
166 static void patch_reloc(uint8_t *code_ptr, int type,
167 tcg_target_long value, tcg_target_long addend)
168 {
169 value += addend;
170 switch(type) {
171 case R_MIPS_LO16:
172 reloc_lo16(code_ptr, value);
173 break;
174 case R_MIPS_HI16:
175 reloc_hi16(code_ptr, value);
176 break;
177 case R_MIPS_PC16:
178 reloc_pc16(code_ptr, value);
179 break;
180 case R_MIPS_26:
181 reloc_pc26(code_ptr, value);
182 break;
183 default:
184 tcg_abort();
185 }
186 }
187
188 /* maximum number of register used for input function arguments */
189 static inline int tcg_target_get_call_iarg_regs_count(int flags)
190 {
191 return 4;
192 }
193
194 /* parse target specific constraints */
195 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
196 {
197 const char *ct_str;
198
199 ct_str = *pct_str;
200 switch(ct_str[0]) {
201 case 'r':
202 ct->ct |= TCG_CT_REG;
203 tcg_regset_set(ct->u.regs, 0xffffffff);
204 break;
205 case 'C':
206 ct->ct |= TCG_CT_REG;
207 tcg_regset_clear(ct->u.regs);
208 tcg_regset_set_reg(ct->u.regs, TCG_REG_T9);
209 break;
210 case 'L': /* qemu_ld output arg constraint */
211 ct->ct |= TCG_CT_REG;
212 tcg_regset_set(ct->u.regs, 0xffffffff);
213 tcg_regset_reset_reg(ct->u.regs, TCG_REG_V0);
214 break;
215 case 'l': /* qemu_ld input arg constraint */
216 ct->ct |= TCG_CT_REG;
217 tcg_regset_set(ct->u.regs, 0xffffffff);
218 #if defined(CONFIG_SOFTMMU)
219 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
220 #endif
221 break;
222 case 'S': /* qemu_st constraint */
223 ct->ct |= TCG_CT_REG;
224 tcg_regset_set(ct->u.regs, 0xffffffff);
225 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
226 #if defined(CONFIG_SOFTMMU)
227 # if TARGET_LONG_BITS == 64
228 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
229 # endif
230 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
231 #endif
232 break;
233 case 'I':
234 ct->ct |= TCG_CT_CONST_U16;
235 break;
236 case 'J':
237 ct->ct |= TCG_CT_CONST_S16;
238 break;
239 case 'Z':
240 /* We are cheating a bit here, using the fact that the register
241 ZERO is also the register number 0. Hence there is no need
242 to check for const_args in each instruction. */
243 ct->ct |= TCG_CT_CONST_ZERO;
244 break;
245 default:
246 return -1;
247 }
248 ct_str++;
249 *pct_str = ct_str;
250 return 0;
251 }
252
253 /* test if a constant matches the constraint */
254 static inline int tcg_target_const_match(tcg_target_long val,
255 const TCGArgConstraint *arg_ct)
256 {
257 int ct;
258 ct = arg_ct->ct;
259 if (ct & TCG_CT_CONST)
260 return 1;
261 else if ((ct & TCG_CT_CONST_ZERO) && val == 0)
262 return 1;
263 else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val)
264 return 1;
265 else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val)
266 return 1;
267 else
268 return 0;
269 }
270
271 /* instruction opcodes */
272 enum {
273 OPC_BEQ = 0x04 << 26,
274 OPC_BNE = 0x05 << 26,
275 OPC_ADDIU = 0x09 << 26,
276 OPC_SLTI = 0x0A << 26,
277 OPC_SLTIU = 0x0B << 26,
278 OPC_ANDI = 0x0C << 26,
279 OPC_ORI = 0x0D << 26,
280 OPC_XORI = 0x0E << 26,
281 OPC_LUI = 0x0F << 26,
282 OPC_LB = 0x20 << 26,
283 OPC_LH = 0x21 << 26,
284 OPC_LW = 0x23 << 26,
285 OPC_LBU = 0x24 << 26,
286 OPC_LHU = 0x25 << 26,
287 OPC_LWU = 0x27 << 26,
288 OPC_SB = 0x28 << 26,
289 OPC_SH = 0x29 << 26,
290 OPC_SW = 0x2B << 26,
291
292 OPC_SPECIAL = 0x00 << 26,
293 OPC_SLL = OPC_SPECIAL | 0x00,
294 OPC_SRL = OPC_SPECIAL | 0x02,
295 OPC_SRA = OPC_SPECIAL | 0x03,
296 OPC_SLLV = OPC_SPECIAL | 0x04,
297 OPC_SRLV = OPC_SPECIAL | 0x06,
298 OPC_SRAV = OPC_SPECIAL | 0x07,
299 OPC_JR = OPC_SPECIAL | 0x08,
300 OPC_JALR = OPC_SPECIAL | 0x09,
301 OPC_MFHI = OPC_SPECIAL | 0x10,
302 OPC_MFLO = OPC_SPECIAL | 0x12,
303 OPC_MULT = OPC_SPECIAL | 0x18,
304 OPC_MULTU = OPC_SPECIAL | 0x19,
305 OPC_DIV = OPC_SPECIAL | 0x1A,
306 OPC_DIVU = OPC_SPECIAL | 0x1B,
307 OPC_ADDU = OPC_SPECIAL | 0x21,
308 OPC_SUBU = OPC_SPECIAL | 0x23,
309 OPC_AND = OPC_SPECIAL | 0x24,
310 OPC_OR = OPC_SPECIAL | 0x25,
311 OPC_XOR = OPC_SPECIAL | 0x26,
312 OPC_NOR = OPC_SPECIAL | 0x27,
313 OPC_SLT = OPC_SPECIAL | 0x2A,
314 OPC_SLTU = OPC_SPECIAL | 0x2B,
315
316 OPC_SPECIAL3 = 0x1f << 26,
317 OPC_SEB = OPC_SPECIAL3 | 0x420,
318 OPC_SEH = OPC_SPECIAL3 | 0x620,
319 };
320
321 /*
322 * Type reg
323 */
324 static inline void tcg_out_opc_reg(TCGContext *s, int opc, int rd, int rs, int rt)
325 {
326 int32_t inst;
327
328 inst = opc;
329 inst |= (rs & 0x1F) << 21;
330 inst |= (rt & 0x1F) << 16;
331 inst |= (rd & 0x1F) << 11;
332 tcg_out32(s, inst);
333 }
334
335 /*
336 * Type immediate
337 */
338 static inline void tcg_out_opc_imm(TCGContext *s, int opc, int rt, int rs, int imm)
339 {
340 int32_t inst;
341
342 inst = opc;
343 inst |= (rs & 0x1F) << 21;
344 inst |= (rt & 0x1F) << 16;
345 inst |= (imm & 0xffff);
346 tcg_out32(s, inst);
347 }
348
349 /*
350 * Type branch
351 */
352 static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
353 {
354 /* We pay attention here to not modify the branch target by reading
355 the existing value and using it again. This ensure that caches and
356 memory are kept coherent during retranslation. */
357 uint16_t offset = (uint16_t)(*(uint32_t *) s->code_ptr);
358
359 tcg_out_opc_imm(s, opc, rt, rs, offset);
360 }
361
362 /*
363 * Type sa
364 */
365 static inline void tcg_out_opc_sa(TCGContext *s, int opc, int rd, int rt, int sa)
366 {
367 int32_t inst;
368
369 inst = opc;
370 inst |= (rt & 0x1F) << 16;
371 inst |= (rd & 0x1F) << 11;
372 inst |= (sa & 0x1F) << 6;
373 tcg_out32(s, inst);
374
375 }
376
377 static inline void tcg_out_nop(TCGContext *s)
378 {
379 tcg_out32(s, 0);
380 }
381
382 static inline void tcg_out_mov(TCGContext *s, TCGType type,
383 TCGReg ret, TCGReg arg)
384 {
385 tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
386 }
387
388 static inline void tcg_out_movi(TCGContext *s, TCGType type,
389 TCGReg reg, tcg_target_long arg)
390 {
391 if (arg == (int16_t)arg) {
392 tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
393 } else if (arg == (uint16_t)arg) {
394 tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
395 } else {
396 tcg_out_opc_imm(s, OPC_LUI, reg, 0, arg >> 16);
397 tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
398 }
399 }
400
401 static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
402 {
403 /* ret and arg can't be register at */
404 if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
405 tcg_abort();
406 }
407
408 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
409 tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0x00ff);
410
411 tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
412 tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
413 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
414 }
415
416 static inline void tcg_out_bswap16s(TCGContext *s, int ret, int arg)
417 {
418 /* ret and arg can't be register at */
419 if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
420 tcg_abort();
421 }
422
423 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
424 tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff);
425
426 tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
427 tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
428 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
429 }
430
431 static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
432 {
433 /* ret and arg must be different and can't be register at */
434 if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
435 tcg_abort();
436 }
437
438 tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
439
440 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
441 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
442
443 tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, arg, 0xff00);
444 tcg_out_opc_sa(s, OPC_SLL, TCG_REG_AT, TCG_REG_AT, 8);
445 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
446
447 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
448 tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
449 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
450 }
451
452 static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
453 {
454 #ifdef _MIPS_ARCH_MIPS32R2
455 tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
456 #else
457 tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
458 tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
459 #endif
460 }
461
462 static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
463 {
464 #ifdef _MIPS_ARCH_MIPS32R2
465 tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
466 #else
467 tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
468 tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
469 #endif
470 }
471
472 static inline void tcg_out_ldst(TCGContext *s, int opc, int arg,
473 int arg1, tcg_target_long arg2)
474 {
475 if (arg2 == (int16_t) arg2) {
476 tcg_out_opc_imm(s, opc, arg, arg1, arg2);
477 } else {
478 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, arg2);
479 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, TCG_REG_AT, arg1);
480 tcg_out_opc_imm(s, opc, arg, TCG_REG_AT, 0);
481 }
482 }
483
484 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
485 TCGReg arg1, tcg_target_long arg2)
486 {
487 tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
488 }
489
490 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
491 TCGReg arg1, tcg_target_long arg2)
492 {
493 tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
494 }
495
496 static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
497 {
498 if (val == (int16_t)val) {
499 tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
500 } else {
501 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, val);
502 tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_REG_AT);
503 }
504 }
505
506 static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1,
507 int arg2, int label_index)
508 {
509 TCGLabel *l = &s->labels[label_index];
510
511 switch (cond) {
512 case TCG_COND_EQ:
513 tcg_out_opc_br(s, OPC_BEQ, arg1, arg2);
514 break;
515 case TCG_COND_NE:
516 tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
517 break;
518 case TCG_COND_LT:
519 tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
520 tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
521 break;
522 case TCG_COND_LTU:
523 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
524 tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
525 break;
526 case TCG_COND_GE:
527 tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
528 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
529 break;
530 case TCG_COND_GEU:
531 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
532 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
533 break;
534 case TCG_COND_LE:
535 tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
536 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
537 break;
538 case TCG_COND_LEU:
539 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
540 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
541 break;
542 case TCG_COND_GT:
543 tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
544 tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
545 break;
546 case TCG_COND_GTU:
547 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
548 tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
549 break;
550 default:
551 tcg_abort();
552 break;
553 }
554 if (l->has_value) {
555 reloc_pc16(s->code_ptr - 4, l->u.value);
556 } else {
557 tcg_out_reloc(s, s->code_ptr - 4, R_MIPS_PC16, label_index, 0);
558 }
559 tcg_out_nop(s);
560 }
561
562 /* XXX: we implement it at the target level to avoid having to
563 handle cross basic blocks temporaries */
564 static void tcg_out_brcond2(TCGContext *s, TCGCond cond, int arg1,
565 int arg2, int arg3, int arg4, int label_index)
566 {
567 void *label_ptr;
568
569 switch(cond) {
570 case TCG_COND_NE:
571 tcg_out_brcond(s, TCG_COND_NE, arg2, arg4, label_index);
572 tcg_out_brcond(s, TCG_COND_NE, arg1, arg3, label_index);
573 return;
574 case TCG_COND_EQ:
575 break;
576 case TCG_COND_LT:
577 case TCG_COND_LE:
578 tcg_out_brcond(s, TCG_COND_LT, arg2, arg4, label_index);
579 break;
580 case TCG_COND_GT:
581 case TCG_COND_GE:
582 tcg_out_brcond(s, TCG_COND_GT, arg2, arg4, label_index);
583 break;
584 case TCG_COND_LTU:
585 case TCG_COND_LEU:
586 tcg_out_brcond(s, TCG_COND_LTU, arg2, arg4, label_index);
587 break;
588 case TCG_COND_GTU:
589 case TCG_COND_GEU:
590 tcg_out_brcond(s, TCG_COND_GTU, arg2, arg4, label_index);
591 break;
592 default:
593 tcg_abort();
594 }
595
596 label_ptr = s->code_ptr;
597 tcg_out_opc_br(s, OPC_BNE, arg2, arg4);
598 tcg_out_nop(s);
599
600 switch(cond) {
601 case TCG_COND_EQ:
602 tcg_out_brcond(s, TCG_COND_EQ, arg1, arg3, label_index);
603 break;
604 case TCG_COND_LT:
605 case TCG_COND_LTU:
606 tcg_out_brcond(s, TCG_COND_LTU, arg1, arg3, label_index);
607 break;
608 case TCG_COND_LE:
609 case TCG_COND_LEU:
610 tcg_out_brcond(s, TCG_COND_LEU, arg1, arg3, label_index);
611 break;
612 case TCG_COND_GT:
613 case TCG_COND_GTU:
614 tcg_out_brcond(s, TCG_COND_GTU, arg1, arg3, label_index);
615 break;
616 case TCG_COND_GE:
617 case TCG_COND_GEU:
618 tcg_out_brcond(s, TCG_COND_GEU, arg1, arg3, label_index);
619 break;
620 default:
621 tcg_abort();
622 }
623
624 reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
625 }
626
627 static void tcg_out_setcond(TCGContext *s, TCGCond cond, int ret,
628 int arg1, int arg2)
629 {
630 switch (cond) {
631 case TCG_COND_EQ:
632 if (arg1 == 0) {
633 tcg_out_opc_imm(s, OPC_SLTIU, ret, arg2, 1);
634 } else if (arg2 == 0) {
635 tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
636 } else {
637 tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
638 tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
639 }
640 break;
641 case TCG_COND_NE:
642 if (arg1 == 0) {
643 tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg2);
644 } else if (arg2 == 0) {
645 tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
646 } else {
647 tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
648 tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
649 }
650 break;
651 case TCG_COND_LT:
652 tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
653 break;
654 case TCG_COND_LTU:
655 tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
656 break;
657 case TCG_COND_GE:
658 tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
659 tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
660 break;
661 case TCG_COND_GEU:
662 tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
663 tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
664 break;
665 case TCG_COND_LE:
666 tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
667 tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
668 break;
669 case TCG_COND_LEU:
670 tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
671 tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
672 break;
673 case TCG_COND_GT:
674 tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
675 break;
676 case TCG_COND_GTU:
677 tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
678 break;
679 default:
680 tcg_abort();
681 break;
682 }
683 }
684
685 /* XXX: we implement it at the target level to avoid having to
686 handle cross basic blocks temporaries */
687 static void tcg_out_setcond2(TCGContext *s, TCGCond cond, int ret,
688 int arg1, int arg2, int arg3, int arg4)
689 {
690 switch (cond) {
691 case TCG_COND_EQ:
692 tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_AT, arg2, arg4);
693 tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg1, arg3);
694 tcg_out_opc_reg(s, OPC_AND, ret, TCG_REG_AT, TCG_REG_T0);
695 return;
696 case TCG_COND_NE:
697 tcg_out_setcond(s, TCG_COND_NE, TCG_REG_AT, arg2, arg4);
698 tcg_out_setcond(s, TCG_COND_NE, TCG_REG_T0, arg1, arg3);
699 tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_AT, TCG_REG_T0);
700 return;
701 case TCG_COND_LT:
702 case TCG_COND_LE:
703 tcg_out_setcond(s, TCG_COND_LT, TCG_REG_AT, arg2, arg4);
704 break;
705 case TCG_COND_GT:
706 case TCG_COND_GE:
707 tcg_out_setcond(s, TCG_COND_GT, TCG_REG_AT, arg2, arg4);
708 break;
709 case TCG_COND_LTU:
710 case TCG_COND_LEU:
711 tcg_out_setcond(s, TCG_COND_LTU, TCG_REG_AT, arg2, arg4);
712 break;
713 case TCG_COND_GTU:
714 case TCG_COND_GEU:
715 tcg_out_setcond(s, TCG_COND_GTU, TCG_REG_AT, arg2, arg4);
716 break;
717 default:
718 tcg_abort();
719 break;
720 }
721
722 tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg2, arg4);
723
724 switch(cond) {
725 case TCG_COND_LT:
726 case TCG_COND_LTU:
727 tcg_out_setcond(s, TCG_COND_LTU, ret, arg1, arg3);
728 break;
729 case TCG_COND_LE:
730 case TCG_COND_LEU:
731 tcg_out_setcond(s, TCG_COND_LEU, ret, arg1, arg3);
732 break;
733 case TCG_COND_GT:
734 case TCG_COND_GTU:
735 tcg_out_setcond(s, TCG_COND_GTU, ret, arg1, arg3);
736 break;
737 case TCG_COND_GE:
738 case TCG_COND_GEU:
739 tcg_out_setcond(s, TCG_COND_GEU, ret, arg1, arg3);
740 break;
741 default:
742 tcg_abort();
743 }
744
745 tcg_out_opc_reg(s, OPC_AND, ret, ret, TCG_REG_T0);
746 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
747 }
748
749 #if defined(CONFIG_SOFTMMU)
750
751 #include "../../softmmu_defs.h"
752
753 static void *qemu_ld_helpers[4] = {
754 __ldb_mmu,
755 __ldw_mmu,
756 __ldl_mmu,
757 __ldq_mmu,
758 };
759
760 static void *qemu_st_helpers[4] = {
761 __stb_mmu,
762 __stw_mmu,
763 __stl_mmu,
764 __stq_mmu,
765 };
766 #endif
767
768 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
769 int opc)
770 {
771 int addr_regl, addr_reg1, addr_meml;
772 int data_regl, data_regh, data_reg1, data_reg2;
773 int mem_index, s_bits;
774 #if defined(CONFIG_SOFTMMU)
775 void *label1_ptr, *label2_ptr;
776 int sp_args;
777 #endif
778 #if TARGET_LONG_BITS == 64
779 # if defined(CONFIG_SOFTMMU)
780 uint8_t *label3_ptr;
781 # endif
782 int addr_regh, addr_reg2, addr_memh;
783 #endif
784 data_regl = *args++;
785 if (opc == 3)
786 data_regh = *args++;
787 else
788 data_regh = 0;
789 addr_regl = *args++;
790 #if TARGET_LONG_BITS == 64
791 addr_regh = *args++;
792 #endif
793 mem_index = *args;
794 s_bits = opc & 3;
795
796 if (opc == 3) {
797 #if defined(TCG_TARGET_WORDS_BIGENDIAN)
798 data_reg1 = data_regh;
799 data_reg2 = data_regl;
800 #else
801 data_reg1 = data_regl;
802 data_reg2 = data_regh;
803 #endif
804 } else {
805 data_reg1 = data_regl;
806 data_reg2 = 0;
807 }
808 #if TARGET_LONG_BITS == 64
809 # if defined(TCG_TARGET_WORDS_BIGENDIAN)
810 addr_reg1 = addr_regh;
811 addr_reg2 = addr_regl;
812 addr_memh = 0;
813 addr_meml = 4;
814 # else
815 addr_reg1 = addr_regl;
816 addr_reg2 = addr_regh;
817 addr_memh = 4;
818 addr_meml = 0;
819 # endif
820 #else
821 addr_reg1 = addr_regl;
822 addr_meml = 0;
823 #endif
824
825 #if defined(CONFIG_SOFTMMU)
826 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
827 tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
828 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
829 tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
830 offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_meml);
831 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
832 tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
833
834 # if TARGET_LONG_BITS == 64
835 label3_ptr = s->code_ptr;
836 tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
837 tcg_out_nop(s);
838
839 tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
840 offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_memh);
841
842 label1_ptr = s->code_ptr;
843 tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
844 tcg_out_nop(s);
845
846 reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
847 # else
848 label1_ptr = s->code_ptr;
849 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
850 tcg_out_nop(s);
851 # endif
852
853 /* slow path */
854 sp_args = TCG_REG_A0;
855 tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1);
856 # if TARGET_LONG_BITS == 64
857 tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2);
858 # endif
859 tcg_out_movi(s, TCG_TYPE_I32, sp_args++, mem_index);
860 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);
861 tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
862 tcg_out_nop(s);
863
864 switch(opc) {
865 case 0:
866 tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);
867 break;
868 case 0 | 4:
869 tcg_out_ext8s(s, data_reg1, TCG_REG_V0);
870 break;
871 case 1:
872 tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);
873 break;
874 case 1 | 4:
875 tcg_out_ext16s(s, data_reg1, TCG_REG_V0);
876 break;
877 case 2:
878 tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
879 break;
880 case 3:
881 tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_V1);
882 tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
883 break;
884 default:
885 tcg_abort();
886 }
887
888 label2_ptr = s->code_ptr;
889 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
890 tcg_out_nop(s);
891
892 /* label1: fast path */
893 reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
894
895 tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
896 offsetof(CPUArchState, tlb_table[mem_index][0].addend));
897 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
898 #else
899 if (GUEST_BASE == (int16_t)GUEST_BASE) {
900 tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_regl, GUEST_BASE);
901 } else {
902 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);
903 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);
904 }
905 #endif
906
907 switch(opc) {
908 case 0:
909 tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);
910 break;
911 case 0 | 4:
912 tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);
913 break;
914 case 1:
915 if (TCG_NEED_BSWAP) {
916 tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
917 tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
918 } else {
919 tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);
920 }
921 break;
922 case 1 | 4:
923 if (TCG_NEED_BSWAP) {
924 tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
925 tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
926 } else {
927 tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);
928 }
929 break;
930 case 2:
931 if (TCG_NEED_BSWAP) {
932 tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
933 tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
934 } else {
935 tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
936 }
937 break;
938 case 3:
939 if (TCG_NEED_BSWAP) {
940 tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);
941 tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
942 tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
943 tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
944 } else {
945 tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
946 tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);
947 }
948 break;
949 default:
950 tcg_abort();
951 }
952
953 #if defined(CONFIG_SOFTMMU)
954 reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
955 #endif
956 }
957
958 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
959 int opc)
960 {
961 int addr_regl, addr_reg1, addr_meml;
962 int data_regl, data_regh, data_reg1, data_reg2;
963 int mem_index, s_bits;
964 #if defined(CONFIG_SOFTMMU)
965 uint8_t *label1_ptr, *label2_ptr;
966 int sp_args;
967 #endif
968 #if TARGET_LONG_BITS == 64
969 # if defined(CONFIG_SOFTMMU)
970 uint8_t *label3_ptr;
971 # endif
972 int addr_regh, addr_reg2, addr_memh;
973 #endif
974
975 data_regl = *args++;
976 if (opc == 3) {
977 data_regh = *args++;
978 #if defined(TCG_TARGET_WORDS_BIGENDIAN)
979 data_reg1 = data_regh;
980 data_reg2 = data_regl;
981 #else
982 data_reg1 = data_regl;
983 data_reg2 = data_regh;
984 #endif
985 } else {
986 data_reg1 = data_regl;
987 data_reg2 = 0;
988 data_regh = 0;
989 }
990 addr_regl = *args++;
991 #if TARGET_LONG_BITS == 64
992 addr_regh = *args++;
993 # if defined(TCG_TARGET_WORDS_BIGENDIAN)
994 addr_reg1 = addr_regh;
995 addr_reg2 = addr_regl;
996 addr_memh = 0;
997 addr_meml = 4;
998 # else
999 addr_reg1 = addr_regl;
1000 addr_reg2 = addr_regh;
1001 addr_memh = 4;
1002 addr_meml = 0;
1003 # endif
1004 #else
1005 addr_reg1 = addr_regl;
1006 addr_meml = 0;
1007 #endif
1008 mem_index = *args;
1009 s_bits = opc;
1010
1011 #if defined(CONFIG_SOFTMMU)
1012 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1013 tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1014 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1015 tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1016 offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_meml);
1017 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1018 tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
1019
1020 # if TARGET_LONG_BITS == 64
1021 label3_ptr = s->code_ptr;
1022 tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1023 tcg_out_nop(s);
1024
1025 tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1026 offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_memh);
1027
1028 label1_ptr = s->code_ptr;
1029 tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1030 tcg_out_nop(s);
1031
1032 reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1033 # else
1034 label1_ptr = s->code_ptr;
1035 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1036 tcg_out_nop(s);
1037 # endif
1038
1039 /* slow path */
1040 sp_args = TCG_REG_A0;
1041 tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1);
1042 # if TARGET_LONG_BITS == 64
1043 tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2);
1044 # endif
1045 switch(opc) {
1046 case 0:
1047 tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xff);
1048 break;
1049 case 1:
1050 tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xffff);
1051 break;
1052 case 2:
1053 tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1);
1054 break;
1055 case 3:
1056 sp_args = (sp_args + 1) & ~1;
1057 tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1);
1058 tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg2);
1059 break;
1060 default:
1061 tcg_abort();
1062 }
1063 if (sp_args > TCG_REG_A3) {
1064 /* Push mem_index on the stack */
1065 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, mem_index);
1066 tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 16);
1067 } else {
1068 tcg_out_movi(s, TCG_TYPE_I32, sp_args, mem_index);
1069 }
1070
1071 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]);
1072 tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1073 tcg_out_nop(s);
1074
1075 label2_ptr = s->code_ptr;
1076 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1077 tcg_out_nop(s);
1078
1079 /* label1: fast path */
1080 reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1081
1082 tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1083 offsetof(CPUArchState, tlb_table[mem_index][0].addend));
1084 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1085 #else
1086 if (GUEST_BASE == (int16_t)GUEST_BASE) {
1087 tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, addr_regl, GUEST_BASE);
1088 } else {
1089 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, GUEST_BASE);
1090 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1091 }
1092
1093 #endif
1094
1095 switch(opc) {
1096 case 0:
1097 tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
1098 break;
1099 case 1:
1100 if (TCG_NEED_BSWAP) {
1101 tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
1102 tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
1103 } else {
1104 tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
1105 }
1106 break;
1107 case 2:
1108 if (TCG_NEED_BSWAP) {
1109 tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1110 tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1111 } else {
1112 tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1113 }
1114 break;
1115 case 3:
1116 if (TCG_NEED_BSWAP) {
1117 tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
1118 tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1119 tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1120 tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
1121 } else {
1122 tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1123 tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4);
1124 }
1125 break;
1126 default:
1127 tcg_abort();
1128 }
1129
1130 #if defined(CONFIG_SOFTMMU)
1131 reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1132 #endif
1133 }
1134
1135 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1136 const TCGArg *args, const int *const_args)
1137 {
1138 switch(opc) {
1139 case INDEX_op_exit_tb:
1140 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_V0, args[0]);
1141 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, (tcg_target_long)tb_ret_addr);
1142 tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1143 tcg_out_nop(s);
1144 break;
1145 case INDEX_op_goto_tb:
1146 if (s->tb_jmp_offset) {
1147 /* direct jump method */
1148 tcg_abort();
1149 } else {
1150 /* indirect jump method */
1151 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
1152 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_AT, TCG_REG_AT, 0);
1153 tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1154 }
1155 tcg_out_nop(s);
1156 s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1157 break;
1158 case INDEX_op_call:
1159 tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0);
1160 tcg_out_nop(s);
1161 break;
1162 case INDEX_op_jmp:
1163 tcg_out_opc_reg(s, OPC_JR, 0, args[0], 0);
1164 tcg_out_nop(s);
1165 break;
1166 case INDEX_op_br:
1167 tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]);
1168 break;
1169
1170 case INDEX_op_mov_i32:
1171 tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1172 break;
1173 case INDEX_op_movi_i32:
1174 tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1175 break;
1176
1177 case INDEX_op_ld8u_i32:
1178 tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1179 break;
1180 case INDEX_op_ld8s_i32:
1181 tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
1182 break;
1183 case INDEX_op_ld16u_i32:
1184 tcg_out_ldst(s, OPC_LHU, args[0], args[1], args[2]);
1185 break;
1186 case INDEX_op_ld16s_i32:
1187 tcg_out_ldst(s, OPC_LH, args[0], args[1], args[2]);
1188 break;
1189 case INDEX_op_ld_i32:
1190 tcg_out_ldst(s, OPC_LW, args[0], args[1], args[2]);
1191 break;
1192 case INDEX_op_st8_i32:
1193 tcg_out_ldst(s, OPC_SB, args[0], args[1], args[2]);
1194 break;
1195 case INDEX_op_st16_i32:
1196 tcg_out_ldst(s, OPC_SH, args[0], args[1], args[2]);
1197 break;
1198 case INDEX_op_st_i32:
1199 tcg_out_ldst(s, OPC_SW, args[0], args[1], args[2]);
1200 break;
1201
1202 case INDEX_op_add_i32:
1203 if (const_args[2]) {
1204 tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], args[2]);
1205 } else {
1206 tcg_out_opc_reg(s, OPC_ADDU, args[0], args[1], args[2]);
1207 }
1208 break;
1209 case INDEX_op_add2_i32:
1210 if (const_args[4]) {
1211 tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], args[4]);
1212 } else {
1213 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, args[2], args[4]);
1214 }
1215 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, TCG_REG_AT, args[2]);
1216 if (const_args[5]) {
1217 tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], args[5]);
1218 } else {
1219 tcg_out_opc_reg(s, OPC_ADDU, args[1], args[3], args[5]);
1220 }
1221 tcg_out_opc_reg(s, OPC_ADDU, args[1], args[1], TCG_REG_T0);
1222 tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1223 break;
1224 case INDEX_op_sub_i32:
1225 if (const_args[2]) {
1226 tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], -args[2]);
1227 } else {
1228 tcg_out_opc_reg(s, OPC_SUBU, args[0], args[1], args[2]);
1229 }
1230 break;
1231 case INDEX_op_sub2_i32:
1232 if (const_args[4]) {
1233 tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], -args[4]);
1234 } else {
1235 tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, args[2], args[4]);
1236 }
1237 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, args[2], TCG_REG_AT);
1238 if (const_args[5]) {
1239 tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], -args[5]);
1240 } else {
1241 tcg_out_opc_reg(s, OPC_SUBU, args[1], args[3], args[5]);
1242 }
1243 tcg_out_opc_reg(s, OPC_SUBU, args[1], args[1], TCG_REG_T0);
1244 tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1245 break;
1246 case INDEX_op_mul_i32:
1247 tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
1248 tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1249 break;
1250 case INDEX_op_mulu2_i32:
1251 tcg_out_opc_reg(s, OPC_MULTU, 0, args[2], args[3]);
1252 tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1253 tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0);
1254 break;
1255 case INDEX_op_div_i32:
1256 tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1257 tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1258 break;
1259 case INDEX_op_divu_i32:
1260 tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1261 tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1262 break;
1263 case INDEX_op_rem_i32:
1264 tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1265 tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1266 break;
1267 case INDEX_op_remu_i32:
1268 tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1269 tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1270 break;
1271
1272 case INDEX_op_and_i32:
1273 if (const_args[2]) {
1274 tcg_out_opc_imm(s, OPC_ANDI, args[0], args[1], args[2]);
1275 } else {
1276 tcg_out_opc_reg(s, OPC_AND, args[0], args[1], args[2]);
1277 }
1278 break;
1279 case INDEX_op_or_i32:
1280 if (const_args[2]) {
1281 tcg_out_opc_imm(s, OPC_ORI, args[0], args[1], args[2]);
1282 } else {
1283 tcg_out_opc_reg(s, OPC_OR, args[0], args[1], args[2]);
1284 }
1285 break;
1286 case INDEX_op_nor_i32:
1287 tcg_out_opc_reg(s, OPC_NOR, args[0], args[1], args[2]);
1288 break;
1289 case INDEX_op_not_i32:
1290 tcg_out_opc_reg(s, OPC_NOR, args[0], TCG_REG_ZERO, args[1]);
1291 break;
1292 case INDEX_op_xor_i32:
1293 if (const_args[2]) {
1294 tcg_out_opc_imm(s, OPC_XORI, args[0], args[1], args[2]);
1295 } else {
1296 tcg_out_opc_reg(s, OPC_XOR, args[0], args[1], args[2]);
1297 }
1298 break;
1299
1300 case INDEX_op_sar_i32:
1301 if (const_args[2]) {
1302 tcg_out_opc_sa(s, OPC_SRA, args[0], args[1], args[2]);
1303 } else {
1304 tcg_out_opc_reg(s, OPC_SRAV, args[0], args[2], args[1]);
1305 }
1306 break;
1307 case INDEX_op_shl_i32:
1308 if (const_args[2]) {
1309 tcg_out_opc_sa(s, OPC_SLL, args[0], args[1], args[2]);
1310 } else {
1311 tcg_out_opc_reg(s, OPC_SLLV, args[0], args[2], args[1]);
1312 }
1313 break;
1314 case INDEX_op_shr_i32:
1315 if (const_args[2]) {
1316 tcg_out_opc_sa(s, OPC_SRL, args[0], args[1], args[2]);
1317 } else {
1318 tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
1319 }
1320 break;
1321
1322 case INDEX_op_ext8s_i32:
1323 tcg_out_ext8s(s, args[0], args[1]);
1324 break;
1325 case INDEX_op_ext16s_i32:
1326 tcg_out_ext16s(s, args[0], args[1]);
1327 break;
1328
1329 case INDEX_op_brcond_i32:
1330 tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
1331 break;
1332 case INDEX_op_brcond2_i32:
1333 tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
1334 break;
1335
1336 case INDEX_op_setcond_i32:
1337 tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
1338 break;
1339 case INDEX_op_setcond2_i32:
1340 tcg_out_setcond2(s, args[5], args[0], args[1], args[2], args[3], args[4]);
1341 break;
1342
1343 case INDEX_op_qemu_ld8u:
1344 tcg_out_qemu_ld(s, args, 0);
1345 break;
1346 case INDEX_op_qemu_ld8s:
1347 tcg_out_qemu_ld(s, args, 0 | 4);
1348 break;
1349 case INDEX_op_qemu_ld16u:
1350 tcg_out_qemu_ld(s, args, 1);
1351 break;
1352 case INDEX_op_qemu_ld16s:
1353 tcg_out_qemu_ld(s, args, 1 | 4);
1354 break;
1355 case INDEX_op_qemu_ld32:
1356 tcg_out_qemu_ld(s, args, 2);
1357 break;
1358 case INDEX_op_qemu_ld64:
1359 tcg_out_qemu_ld(s, args, 3);
1360 break;
1361 case INDEX_op_qemu_st8:
1362 tcg_out_qemu_st(s, args, 0);
1363 break;
1364 case INDEX_op_qemu_st16:
1365 tcg_out_qemu_st(s, args, 1);
1366 break;
1367 case INDEX_op_qemu_st32:
1368 tcg_out_qemu_st(s, args, 2);
1369 break;
1370 case INDEX_op_qemu_st64:
1371 tcg_out_qemu_st(s, args, 3);
1372 break;
1373
1374 default:
1375 tcg_abort();
1376 }
1377 }
1378
1379 static const TCGTargetOpDef mips_op_defs[] = {
1380 { INDEX_op_exit_tb, { } },
1381 { INDEX_op_goto_tb, { } },
1382 { INDEX_op_call, { "C" } },
1383 { INDEX_op_jmp, { "r" } },
1384 { INDEX_op_br, { } },
1385
1386 { INDEX_op_mov_i32, { "r", "r" } },
1387 { INDEX_op_movi_i32, { "r" } },
1388 { INDEX_op_ld8u_i32, { "r", "r" } },
1389 { INDEX_op_ld8s_i32, { "r", "r" } },
1390 { INDEX_op_ld16u_i32, { "r", "r" } },
1391 { INDEX_op_ld16s_i32, { "r", "r" } },
1392 { INDEX_op_ld_i32, { "r", "r" } },
1393 { INDEX_op_st8_i32, { "rZ", "r" } },
1394 { INDEX_op_st16_i32, { "rZ", "r" } },
1395 { INDEX_op_st_i32, { "rZ", "r" } },
1396
1397 { INDEX_op_add_i32, { "r", "rZ", "rJZ" } },
1398 { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1399 { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1400 { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1401 { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1402 { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1403 { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1404 { INDEX_op_sub_i32, { "r", "rZ", "rJZ" } },
1405
1406 { INDEX_op_and_i32, { "r", "rZ", "rIZ" } },
1407 { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1408 { INDEX_op_not_i32, { "r", "rZ" } },
1409 { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1410 { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1411
1412 { INDEX_op_shl_i32, { "r", "rZ", "riZ" } },
1413 { INDEX_op_shr_i32, { "r", "rZ", "riZ" } },
1414 { INDEX_op_sar_i32, { "r", "rZ", "riZ" } },
1415
1416 { INDEX_op_ext8s_i32, { "r", "rZ" } },
1417 { INDEX_op_ext16s_i32, { "r", "rZ" } },
1418
1419 { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1420 { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1421 { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1422
1423 { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
1424 { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
1425 { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1426
1427 #if TARGET_LONG_BITS == 32
1428 { INDEX_op_qemu_ld8u, { "L", "lZ" } },
1429 { INDEX_op_qemu_ld8s, { "L", "lZ" } },
1430 { INDEX_op_qemu_ld16u, { "L", "lZ" } },
1431 { INDEX_op_qemu_ld16s, { "L", "lZ" } },
1432 { INDEX_op_qemu_ld32, { "L", "lZ" } },
1433 { INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
1434
1435 { INDEX_op_qemu_st8, { "SZ", "SZ" } },
1436 { INDEX_op_qemu_st16, { "SZ", "SZ" } },
1437 { INDEX_op_qemu_st32, { "SZ", "SZ" } },
1438 { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ" } },
1439 #else
1440 { INDEX_op_qemu_ld8u, { "L", "lZ", "lZ" } },
1441 { INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
1442 { INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
1443 { INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
1444 { INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
1445 { INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
1446
1447 { INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
1448 { INDEX_op_qemu_st16, { "SZ", "SZ", "SZ" } },
1449 { INDEX_op_qemu_st32, { "SZ", "SZ", "SZ" } },
1450 { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ", "SZ" } },
1451 #endif
1452 { -1 },
1453 };
1454
1455 static int tcg_target_callee_save_regs[] = {
1456 TCG_REG_S0, /* used for the global env (TCG_AREG0) */
1457 TCG_REG_S1,
1458 TCG_REG_S2,
1459 TCG_REG_S3,
1460 TCG_REG_S4,
1461 TCG_REG_S5,
1462 TCG_REG_S6,
1463 TCG_REG_S7,
1464 TCG_REG_GP,
1465 TCG_REG_FP,
1466 TCG_REG_RA, /* should be last for ABI compliance */
1467 };
1468
1469 /* Generate global QEMU prologue and epilogue code */
1470 static void tcg_target_qemu_prologue(TCGContext *s)
1471 {
1472 int i, frame_size;
1473
1474 /* reserve some stack space */
1475 frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1476 + TCG_STATIC_CALL_ARGS_SIZE;
1477 frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1478 ~(TCG_TARGET_STACK_ALIGN - 1);
1479
1480 /* TB prologue */
1481 tcg_out_addi(s, TCG_REG_SP, -frame_size);
1482 for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1483 tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1484 TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1485 }
1486
1487 /* Call generated code */
1488 tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
1489 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1490 tb_ret_addr = s->code_ptr;
1491
1492 /* TB epilogue */
1493 for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1494 tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1495 TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1496 }
1497
1498 tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1499 tcg_out_addi(s, TCG_REG_SP, frame_size);
1500 }
1501
1502 static void tcg_target_init(TCGContext *s)
1503 {
1504 tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
1505 tcg_regset_set(tcg_target_call_clobber_regs,
1506 (1 << TCG_REG_V0) |
1507 (1 << TCG_REG_V1) |
1508 (1 << TCG_REG_A0) |
1509 (1 << TCG_REG_A1) |
1510 (1 << TCG_REG_A2) |
1511 (1 << TCG_REG_A3) |
1512 (1 << TCG_REG_T1) |
1513 (1 << TCG_REG_T2) |
1514 (1 << TCG_REG_T3) |
1515 (1 << TCG_REG_T4) |
1516 (1 << TCG_REG_T5) |
1517 (1 << TCG_REG_T6) |
1518 (1 << TCG_REG_T7) |
1519 (1 << TCG_REG_T8) |
1520 (1 << TCG_REG_T9));
1521
1522 tcg_regset_clear(s->reserved_regs);
1523 tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
1524 tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0); /* kernel use only */
1525 tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1); /* kernel use only */
1526 tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT); /* internal use */
1527 tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0); /* internal use */
1528 tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA); /* return address */
1529 tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); /* stack pointer */
1530
1531 tcg_add_target_add_op_defs(mips_op_defs);
1532 tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
1533 CPU_TEMP_BUF_NLONGS * sizeof(long));
1534 }