1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
34static 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
71static 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
97static 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
104static const int tcg_target_call_oarg_regs[2] = {
105 TCG_REG_V0,
106 TCG_REG_V1
107};
108
109static uint8_t *tb_ret_addr;
110
111static inline uint32_t reloc_lo16_val (void *pc, tcg_target_long target)
112{
113 return target & 0xffff;
114}
115
116static 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
122static inline uint32_t reloc_hi16_val (void *pc, tcg_target_long target)
123{
124 return (target >> 16) & 0xffff;
125}
126
127static 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
133static 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
145static 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
151static 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
160static 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
166static 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
189static inline int tcg_target_get_call_iarg_regs_count(int flags)
190{
191 return 4;
192}
193
194
195static 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':
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':
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':
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
241
242
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
254static 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
272enum {
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
323
324static 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
337
338static 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
351
352static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
353{
354
355
356
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
364
365static 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
377static inline void tcg_out_nop(TCGContext *s)
378{
379 tcg_out32(s, 0);
380}
381
382static 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
388static 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
401static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
402{
403
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
416static inline void tcg_out_bswap16s(TCGContext *s, int ret, int arg)
417{
418
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
431static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
432{
433
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
452static 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
462static 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
472static 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
484static 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
490static 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
496static 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
506static 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
563
564static 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
627static 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
686
687static 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#ifdef CONFIG_TCG_PASS_AREG0
754
755
756static const void * const qemu_ld_helpers[4] = {
757 helper_ldb_mmu,
758 helper_ldw_mmu,
759 helper_ldl_mmu,
760 helper_ldq_mmu,
761};
762
763
764
765static const void * const qemu_st_helpers[4] = {
766 helper_stb_mmu,
767 helper_stw_mmu,
768 helper_stl_mmu,
769 helper_stq_mmu,
770};
771#else
772
773
774static void *qemu_ld_helpers[4] = {
775 __ldb_mmu,
776 __ldw_mmu,
777 __ldl_mmu,
778 __ldq_mmu,
779};
780
781
782
783static void *qemu_st_helpers[4] = {
784 __stb_mmu,
785 __stw_mmu,
786 __stl_mmu,
787 __stq_mmu,
788};
789#endif
790#endif
791
792static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
793 int opc)
794{
795 int addr_regl, addr_reg1, addr_meml;
796 int data_regl, data_regh, data_reg1, data_reg2;
797 int mem_index, s_bits;
798#if defined(CONFIG_SOFTMMU)
799 void *label1_ptr, *label2_ptr;
800 int sp_args;
801#endif
802#if TARGET_LONG_BITS == 64
803# if defined(CONFIG_SOFTMMU)
804 uint8_t *label3_ptr;
805# endif
806 int addr_regh, addr_reg2, addr_memh;
807#endif
808 data_regl = *args++;
809 if (opc == 3)
810 data_regh = *args++;
811 else
812 data_regh = 0;
813 addr_regl = *args++;
814#if TARGET_LONG_BITS == 64
815 addr_regh = *args++;
816#endif
817 mem_index = *args;
818 s_bits = opc & 3;
819
820 if (opc == 3) {
821#if defined(TCG_TARGET_WORDS_BIGENDIAN)
822 data_reg1 = data_regh;
823 data_reg2 = data_regl;
824#else
825 data_reg1 = data_regl;
826 data_reg2 = data_regh;
827#endif
828 } else {
829 data_reg1 = data_regl;
830 data_reg2 = 0;
831 }
832#if TARGET_LONG_BITS == 64
833# if defined(TCG_TARGET_WORDS_BIGENDIAN)
834 addr_reg1 = addr_regh;
835 addr_reg2 = addr_regl;
836 addr_memh = 0;
837 addr_meml = 4;
838# else
839 addr_reg1 = addr_regl;
840 addr_reg2 = addr_regh;
841 addr_memh = 4;
842 addr_meml = 0;
843# endif
844#else
845 addr_reg1 = addr_regl;
846 addr_meml = 0;
847#endif
848
849#if defined(CONFIG_SOFTMMU)
850 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
851 tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
852 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
853 tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
854 offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_meml);
855 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
856 tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
857
858# if TARGET_LONG_BITS == 64
859 label3_ptr = s->code_ptr;
860 tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
861 tcg_out_nop(s);
862
863 tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
864 offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_memh);
865
866 label1_ptr = s->code_ptr;
867 tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
868 tcg_out_nop(s);
869
870 reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
871# else
872 label1_ptr = s->code_ptr;
873 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
874 tcg_out_nop(s);
875# endif
876
877
878 sp_args = TCG_REG_A0;
879 tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1);
880# if TARGET_LONG_BITS == 64
881 tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2);
882# endif
883 tcg_out_movi(s, TCG_TYPE_I32, sp_args++, mem_index);
884 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);
885#ifdef CONFIG_TCG_PASS_AREG0
886
887 tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
888 tcg_target_call_iarg_regs[1]);
889 tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
890 tcg_target_call_iarg_regs[0]);
891 tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
892 TCG_AREG0);
893#endif
894 tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
895 tcg_out_nop(s);
896
897 switch(opc) {
898 case 0:
899 tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);
900 break;
901 case 0 | 4:
902 tcg_out_ext8s(s, data_reg1, TCG_REG_V0);
903 break;
904 case 1:
905 tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);
906 break;
907 case 1 | 4:
908 tcg_out_ext16s(s, data_reg1, TCG_REG_V0);
909 break;
910 case 2:
911 tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
912 break;
913 case 3:
914 tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_V1);
915 tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
916 break;
917 default:
918 tcg_abort();
919 }
920
921 label2_ptr = s->code_ptr;
922 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
923 tcg_out_nop(s);
924
925
926 reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
927
928 tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
929 offsetof(CPUArchState, tlb_table[mem_index][0].addend));
930 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
931#else
932 if (GUEST_BASE == (int16_t)GUEST_BASE) {
933 tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_regl, GUEST_BASE);
934 } else {
935 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);
936 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);
937 }
938#endif
939
940 switch(opc) {
941 case 0:
942 tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);
943 break;
944 case 0 | 4:
945 tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);
946 break;
947 case 1:
948 if (TCG_NEED_BSWAP) {
949 tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
950 tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
951 } else {
952 tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);
953 }
954 break;
955 case 1 | 4:
956 if (TCG_NEED_BSWAP) {
957 tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
958 tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
959 } else {
960 tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);
961 }
962 break;
963 case 2:
964 if (TCG_NEED_BSWAP) {
965 tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
966 tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
967 } else {
968 tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
969 }
970 break;
971 case 3:
972 if (TCG_NEED_BSWAP) {
973 tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);
974 tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
975 tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
976 tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
977 } else {
978 tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
979 tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);
980 }
981 break;
982 default:
983 tcg_abort();
984 }
985
986#if defined(CONFIG_SOFTMMU)
987 reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
988#endif
989}
990
991static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
992 int opc)
993{
994 int addr_regl, addr_reg1, addr_meml;
995 int data_regl, data_regh, data_reg1, data_reg2;
996 int mem_index, s_bits;
997#if defined(CONFIG_SOFTMMU)
998 uint8_t *label1_ptr, *label2_ptr;
999 int sp_args;
1000#endif
1001#if TARGET_LONG_BITS == 64
1002# if defined(CONFIG_SOFTMMU)
1003 uint8_t *label3_ptr;
1004# endif
1005 int addr_regh, addr_reg2, addr_memh;
1006#endif
1007
1008 data_regl = *args++;
1009 if (opc == 3) {
1010 data_regh = *args++;
1011#if defined(TCG_TARGET_WORDS_BIGENDIAN)
1012 data_reg1 = data_regh;
1013 data_reg2 = data_regl;
1014#else
1015 data_reg1 = data_regl;
1016 data_reg2 = data_regh;
1017#endif
1018 } else {
1019 data_reg1 = data_regl;
1020 data_reg2 = 0;
1021 data_regh = 0;
1022 }
1023 addr_regl = *args++;
1024#if TARGET_LONG_BITS == 64
1025 addr_regh = *args++;
1026# if defined(TCG_TARGET_WORDS_BIGENDIAN)
1027 addr_reg1 = addr_regh;
1028 addr_reg2 = addr_regl;
1029 addr_memh = 0;
1030 addr_meml = 4;
1031# else
1032 addr_reg1 = addr_regl;
1033 addr_reg2 = addr_regh;
1034 addr_memh = 4;
1035 addr_meml = 0;
1036# endif
1037#else
1038 addr_reg1 = addr_regl;
1039 addr_meml = 0;
1040#endif
1041 mem_index = *args;
1042 s_bits = opc;
1043
1044#if defined(CONFIG_SOFTMMU)
1045 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1046 tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1047 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1048 tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1049 offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_meml);
1050 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1051 tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
1052
1053# if TARGET_LONG_BITS == 64
1054 label3_ptr = s->code_ptr;
1055 tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1056 tcg_out_nop(s);
1057
1058 tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1059 offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_memh);
1060
1061 label1_ptr = s->code_ptr;
1062 tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1063 tcg_out_nop(s);
1064
1065 reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1066# else
1067 label1_ptr = s->code_ptr;
1068 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1069 tcg_out_nop(s);
1070# endif
1071
1072
1073 sp_args = TCG_REG_A0;
1074 tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1);
1075# if TARGET_LONG_BITS == 64
1076 tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2);
1077# endif
1078 switch(opc) {
1079 case 0:
1080 tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xff);
1081 break;
1082 case 1:
1083 tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xffff);
1084 break;
1085 case 2:
1086 tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1);
1087 break;
1088 case 3:
1089 sp_args = (sp_args + 1) & ~1;
1090 tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1);
1091 tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg2);
1092 break;
1093 default:
1094 tcg_abort();
1095 }
1096 if (sp_args > TCG_REG_A3) {
1097
1098 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, mem_index);
1099 tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 16);
1100 } else {
1101 tcg_out_movi(s, TCG_TYPE_I32, sp_args, mem_index);
1102 }
1103
1104 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]);
1105#ifdef CONFIG_TCG_PASS_AREG0
1106
1107 tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
1108 tcg_target_call_iarg_regs[2]);
1109 tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
1110 tcg_target_call_iarg_regs[1]);
1111 tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
1112 tcg_target_call_iarg_regs[0]);
1113 tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
1114 TCG_AREG0);
1115#endif
1116 tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1117 tcg_out_nop(s);
1118
1119 label2_ptr = s->code_ptr;
1120 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1121 tcg_out_nop(s);
1122
1123
1124 reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1125
1126 tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1127 offsetof(CPUArchState, tlb_table[mem_index][0].addend));
1128 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1129#else
1130 if (GUEST_BASE == (int16_t)GUEST_BASE) {
1131 tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, addr_regl, GUEST_BASE);
1132 } else {
1133 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, GUEST_BASE);
1134 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1135 }
1136
1137#endif
1138
1139 switch(opc) {
1140 case 0:
1141 tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
1142 break;
1143 case 1:
1144 if (TCG_NEED_BSWAP) {
1145 tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
1146 tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
1147 } else {
1148 tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
1149 }
1150 break;
1151 case 2:
1152 if (TCG_NEED_BSWAP) {
1153 tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1154 tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1155 } else {
1156 tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1157 }
1158 break;
1159 case 3:
1160 if (TCG_NEED_BSWAP) {
1161 tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
1162 tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1163 tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1164 tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
1165 } else {
1166 tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1167 tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4);
1168 }
1169 break;
1170 default:
1171 tcg_abort();
1172 }
1173
1174#if defined(CONFIG_SOFTMMU)
1175 reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1176#endif
1177}
1178
1179static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1180 const TCGArg *args, const int *const_args)
1181{
1182 switch(opc) {
1183 case INDEX_op_exit_tb:
1184 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_V0, args[0]);
1185 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, (tcg_target_long)tb_ret_addr);
1186 tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1187 tcg_out_nop(s);
1188 break;
1189 case INDEX_op_goto_tb:
1190 if (s->tb_jmp_offset) {
1191
1192 tcg_abort();
1193 } else {
1194
1195 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
1196 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_AT, TCG_REG_AT, 0);
1197 tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1198 }
1199 tcg_out_nop(s);
1200 s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1201 break;
1202 case INDEX_op_call:
1203 tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0);
1204 tcg_out_nop(s);
1205 break;
1206 case INDEX_op_jmp:
1207 tcg_out_opc_reg(s, OPC_JR, 0, args[0], 0);
1208 tcg_out_nop(s);
1209 break;
1210 case INDEX_op_br:
1211 tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]);
1212 break;
1213
1214 case INDEX_op_mov_i32:
1215 tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1216 break;
1217 case INDEX_op_movi_i32:
1218 tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1219 break;
1220
1221 case INDEX_op_ld8u_i32:
1222 tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1223 break;
1224 case INDEX_op_ld8s_i32:
1225 tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
1226 break;
1227 case INDEX_op_ld16u_i32:
1228 tcg_out_ldst(s, OPC_LHU, args[0], args[1], args[2]);
1229 break;
1230 case INDEX_op_ld16s_i32:
1231 tcg_out_ldst(s, OPC_LH, args[0], args[1], args[2]);
1232 break;
1233 case INDEX_op_ld_i32:
1234 tcg_out_ldst(s, OPC_LW, args[0], args[1], args[2]);
1235 break;
1236 case INDEX_op_st8_i32:
1237 tcg_out_ldst(s, OPC_SB, args[0], args[1], args[2]);
1238 break;
1239 case INDEX_op_st16_i32:
1240 tcg_out_ldst(s, OPC_SH, args[0], args[1], args[2]);
1241 break;
1242 case INDEX_op_st_i32:
1243 tcg_out_ldst(s, OPC_SW, args[0], args[1], args[2]);
1244 break;
1245
1246 case INDEX_op_add_i32:
1247 if (const_args[2]) {
1248 tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], args[2]);
1249 } else {
1250 tcg_out_opc_reg(s, OPC_ADDU, args[0], args[1], args[2]);
1251 }
1252 break;
1253 case INDEX_op_add2_i32:
1254 if (const_args[4]) {
1255 tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], args[4]);
1256 } else {
1257 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, args[2], args[4]);
1258 }
1259 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, TCG_REG_AT, args[2]);
1260 if (const_args[5]) {
1261 tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], args[5]);
1262 } else {
1263 tcg_out_opc_reg(s, OPC_ADDU, args[1], args[3], args[5]);
1264 }
1265 tcg_out_opc_reg(s, OPC_ADDU, args[1], args[1], TCG_REG_T0);
1266 tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1267 break;
1268 case INDEX_op_sub_i32:
1269 if (const_args[2]) {
1270 tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], -args[2]);
1271 } else {
1272 tcg_out_opc_reg(s, OPC_SUBU, args[0], args[1], args[2]);
1273 }
1274 break;
1275 case INDEX_op_sub2_i32:
1276 if (const_args[4]) {
1277 tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], -args[4]);
1278 } else {
1279 tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, args[2], args[4]);
1280 }
1281 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, args[2], TCG_REG_AT);
1282 if (const_args[5]) {
1283 tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], -args[5]);
1284 } else {
1285 tcg_out_opc_reg(s, OPC_SUBU, args[1], args[3], args[5]);
1286 }
1287 tcg_out_opc_reg(s, OPC_SUBU, args[1], args[1], TCG_REG_T0);
1288 tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1289 break;
1290 case INDEX_op_mul_i32:
1291 tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
1292 tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1293 break;
1294 case INDEX_op_mulu2_i32:
1295 tcg_out_opc_reg(s, OPC_MULTU, 0, args[2], args[3]);
1296 tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1297 tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0);
1298 break;
1299 case INDEX_op_div_i32:
1300 tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1301 tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1302 break;
1303 case INDEX_op_divu_i32:
1304 tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1305 tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1306 break;
1307 case INDEX_op_rem_i32:
1308 tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1309 tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1310 break;
1311 case INDEX_op_remu_i32:
1312 tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1313 tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1314 break;
1315
1316 case INDEX_op_and_i32:
1317 if (const_args[2]) {
1318 tcg_out_opc_imm(s, OPC_ANDI, args[0], args[1], args[2]);
1319 } else {
1320 tcg_out_opc_reg(s, OPC_AND, args[0], args[1], args[2]);
1321 }
1322 break;
1323 case INDEX_op_or_i32:
1324 if (const_args[2]) {
1325 tcg_out_opc_imm(s, OPC_ORI, args[0], args[1], args[2]);
1326 } else {
1327 tcg_out_opc_reg(s, OPC_OR, args[0], args[1], args[2]);
1328 }
1329 break;
1330 case INDEX_op_nor_i32:
1331 tcg_out_opc_reg(s, OPC_NOR, args[0], args[1], args[2]);
1332 break;
1333 case INDEX_op_not_i32:
1334 tcg_out_opc_reg(s, OPC_NOR, args[0], TCG_REG_ZERO, args[1]);
1335 break;
1336 case INDEX_op_xor_i32:
1337 if (const_args[2]) {
1338 tcg_out_opc_imm(s, OPC_XORI, args[0], args[1], args[2]);
1339 } else {
1340 tcg_out_opc_reg(s, OPC_XOR, args[0], args[1], args[2]);
1341 }
1342 break;
1343
1344 case INDEX_op_sar_i32:
1345 if (const_args[2]) {
1346 tcg_out_opc_sa(s, OPC_SRA, args[0], args[1], args[2]);
1347 } else {
1348 tcg_out_opc_reg(s, OPC_SRAV, args[0], args[2], args[1]);
1349 }
1350 break;
1351 case INDEX_op_shl_i32:
1352 if (const_args[2]) {
1353 tcg_out_opc_sa(s, OPC_SLL, args[0], args[1], args[2]);
1354 } else {
1355 tcg_out_opc_reg(s, OPC_SLLV, args[0], args[2], args[1]);
1356 }
1357 break;
1358 case INDEX_op_shr_i32:
1359 if (const_args[2]) {
1360 tcg_out_opc_sa(s, OPC_SRL, args[0], args[1], args[2]);
1361 } else {
1362 tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
1363 }
1364 break;
1365
1366 case INDEX_op_ext8s_i32:
1367 tcg_out_ext8s(s, args[0], args[1]);
1368 break;
1369 case INDEX_op_ext16s_i32:
1370 tcg_out_ext16s(s, args[0], args[1]);
1371 break;
1372
1373 case INDEX_op_brcond_i32:
1374 tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
1375 break;
1376 case INDEX_op_brcond2_i32:
1377 tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
1378 break;
1379
1380 case INDEX_op_setcond_i32:
1381 tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
1382 break;
1383 case INDEX_op_setcond2_i32:
1384 tcg_out_setcond2(s, args[5], args[0], args[1], args[2], args[3], args[4]);
1385 break;
1386
1387 case INDEX_op_qemu_ld8u:
1388 tcg_out_qemu_ld(s, args, 0);
1389 break;
1390 case INDEX_op_qemu_ld8s:
1391 tcg_out_qemu_ld(s, args, 0 | 4);
1392 break;
1393 case INDEX_op_qemu_ld16u:
1394 tcg_out_qemu_ld(s, args, 1);
1395 break;
1396 case INDEX_op_qemu_ld16s:
1397 tcg_out_qemu_ld(s, args, 1 | 4);
1398 break;
1399 case INDEX_op_qemu_ld32:
1400 tcg_out_qemu_ld(s, args, 2);
1401 break;
1402 case INDEX_op_qemu_ld64:
1403 tcg_out_qemu_ld(s, args, 3);
1404 break;
1405 case INDEX_op_qemu_st8:
1406 tcg_out_qemu_st(s, args, 0);
1407 break;
1408 case INDEX_op_qemu_st16:
1409 tcg_out_qemu_st(s, args, 1);
1410 break;
1411 case INDEX_op_qemu_st32:
1412 tcg_out_qemu_st(s, args, 2);
1413 break;
1414 case INDEX_op_qemu_st64:
1415 tcg_out_qemu_st(s, args, 3);
1416 break;
1417
1418 default:
1419 tcg_abort();
1420 }
1421}
1422
1423static const TCGTargetOpDef mips_op_defs[] = {
1424 { INDEX_op_exit_tb, { } },
1425 { INDEX_op_goto_tb, { } },
1426 { INDEX_op_call, { "C" } },
1427 { INDEX_op_jmp, { "r" } },
1428 { INDEX_op_br, { } },
1429
1430 { INDEX_op_mov_i32, { "r", "r" } },
1431 { INDEX_op_movi_i32, { "r" } },
1432 { INDEX_op_ld8u_i32, { "r", "r" } },
1433 { INDEX_op_ld8s_i32, { "r", "r" } },
1434 { INDEX_op_ld16u_i32, { "r", "r" } },
1435 { INDEX_op_ld16s_i32, { "r", "r" } },
1436 { INDEX_op_ld_i32, { "r", "r" } },
1437 { INDEX_op_st8_i32, { "rZ", "r" } },
1438 { INDEX_op_st16_i32, { "rZ", "r" } },
1439 { INDEX_op_st_i32, { "rZ", "r" } },
1440
1441 { INDEX_op_add_i32, { "r", "rZ", "rJZ" } },
1442 { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1443 { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1444 { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1445 { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1446 { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1447 { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1448 { INDEX_op_sub_i32, { "r", "rZ", "rJZ" } },
1449
1450 { INDEX_op_and_i32, { "r", "rZ", "rIZ" } },
1451 { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1452 { INDEX_op_not_i32, { "r", "rZ" } },
1453 { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1454 { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1455
1456 { INDEX_op_shl_i32, { "r", "rZ", "riZ" } },
1457 { INDEX_op_shr_i32, { "r", "rZ", "riZ" } },
1458 { INDEX_op_sar_i32, { "r", "rZ", "riZ" } },
1459
1460 { INDEX_op_ext8s_i32, { "r", "rZ" } },
1461 { INDEX_op_ext16s_i32, { "r", "rZ" } },
1462
1463 { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1464 { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1465 { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1466
1467 { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
1468 { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
1469 { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1470
1471#if TARGET_LONG_BITS == 32
1472 { INDEX_op_qemu_ld8u, { "L", "lZ" } },
1473 { INDEX_op_qemu_ld8s, { "L", "lZ" } },
1474 { INDEX_op_qemu_ld16u, { "L", "lZ" } },
1475 { INDEX_op_qemu_ld16s, { "L", "lZ" } },
1476 { INDEX_op_qemu_ld32, { "L", "lZ" } },
1477 { INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
1478
1479 { INDEX_op_qemu_st8, { "SZ", "SZ" } },
1480 { INDEX_op_qemu_st16, { "SZ", "SZ" } },
1481 { INDEX_op_qemu_st32, { "SZ", "SZ" } },
1482 { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ" } },
1483#else
1484 { INDEX_op_qemu_ld8u, { "L", "lZ", "lZ" } },
1485 { INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
1486 { INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
1487 { INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
1488 { INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
1489 { INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
1490
1491 { INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
1492 { INDEX_op_qemu_st16, { "SZ", "SZ", "SZ" } },
1493 { INDEX_op_qemu_st32, { "SZ", "SZ", "SZ" } },
1494 { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ", "SZ" } },
1495#endif
1496 { -1 },
1497};
1498
1499static int tcg_target_callee_save_regs[] = {
1500 TCG_REG_S0,
1501 TCG_REG_S1,
1502 TCG_REG_S2,
1503 TCG_REG_S3,
1504 TCG_REG_S4,
1505 TCG_REG_S5,
1506 TCG_REG_S6,
1507 TCG_REG_S7,
1508 TCG_REG_GP,
1509 TCG_REG_FP,
1510 TCG_REG_RA,
1511};
1512
1513
1514static void tcg_target_qemu_prologue(TCGContext *s)
1515{
1516 int i, frame_size;
1517
1518
1519 frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1520 + TCG_STATIC_CALL_ARGS_SIZE;
1521 frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1522 ~(TCG_TARGET_STACK_ALIGN - 1);
1523
1524
1525 tcg_out_addi(s, TCG_REG_SP, -frame_size);
1526 for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1527 tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1528 TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1529 }
1530
1531
1532 tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
1533 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1534 tb_ret_addr = s->code_ptr;
1535
1536
1537 for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1538 tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1539 TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1540 }
1541
1542 tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1543 tcg_out_addi(s, TCG_REG_SP, frame_size);
1544}
1545
1546static void tcg_target_init(TCGContext *s)
1547{
1548 tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
1549 tcg_regset_set(tcg_target_call_clobber_regs,
1550 (1 << TCG_REG_V0) |
1551 (1 << TCG_REG_V1) |
1552 (1 << TCG_REG_A0) |
1553 (1 << TCG_REG_A1) |
1554 (1 << TCG_REG_A2) |
1555 (1 << TCG_REG_A3) |
1556 (1 << TCG_REG_T1) |
1557 (1 << TCG_REG_T2) |
1558 (1 << TCG_REG_T3) |
1559 (1 << TCG_REG_T4) |
1560 (1 << TCG_REG_T5) |
1561 (1 << TCG_REG_T6) |
1562 (1 << TCG_REG_T7) |
1563 (1 << TCG_REG_T8) |
1564 (1 << TCG_REG_T9));
1565
1566 tcg_regset_clear(s->reserved_regs);
1567 tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO);
1568 tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);
1569 tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);
1570 tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT);
1571 tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0);
1572 tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);
1573 tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);
1574
1575 tcg_add_target_add_op_defs(mips_op_defs);
1576 tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
1577 CPU_TEMP_BUF_NLONGS * sizeof(long));
1578}
1579