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 TCGReg 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 TCGReg 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 TCGReg 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 int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
190{
191 const char *ct_str;
192
193 ct_str = *pct_str;
194 switch(ct_str[0]) {
195 case 'r':
196 ct->ct |= TCG_CT_REG;
197 tcg_regset_set(ct->u.regs, 0xffffffff);
198 break;
199 case 'C':
200 ct->ct |= TCG_CT_REG;
201 tcg_regset_clear(ct->u.regs);
202 tcg_regset_set_reg(ct->u.regs, TCG_REG_T9);
203 break;
204 case 'L':
205 ct->ct |= TCG_CT_REG;
206 tcg_regset_set(ct->u.regs, 0xffffffff);
207 tcg_regset_reset_reg(ct->u.regs, TCG_REG_V0);
208 break;
209 case 'l':
210 ct->ct |= TCG_CT_REG;
211 tcg_regset_set(ct->u.regs, 0xffffffff);
212#if defined(CONFIG_SOFTMMU)
213 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
214# if (TARGET_LONG_BITS == 64)
215 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
216# endif
217#endif
218 break;
219 case 'S':
220 ct->ct |= TCG_CT_REG;
221 tcg_regset_set(ct->u.regs, 0xffffffff);
222 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
223#if defined(CONFIG_SOFTMMU)
224# if (TARGET_LONG_BITS == 32)
225 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
226# endif
227 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
228# if TARGET_LONG_BITS == 64
229 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A3);
230# endif
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_BLEZ = 0x06 << 26,
276 OPC_BGTZ = 0x07 << 26,
277 OPC_ADDIU = 0x09 << 26,
278 OPC_SLTI = 0x0A << 26,
279 OPC_SLTIU = 0x0B << 26,
280 OPC_ANDI = 0x0C << 26,
281 OPC_ORI = 0x0D << 26,
282 OPC_XORI = 0x0E << 26,
283 OPC_LUI = 0x0F << 26,
284 OPC_LB = 0x20 << 26,
285 OPC_LH = 0x21 << 26,
286 OPC_LW = 0x23 << 26,
287 OPC_LBU = 0x24 << 26,
288 OPC_LHU = 0x25 << 26,
289 OPC_LWU = 0x27 << 26,
290 OPC_SB = 0x28 << 26,
291 OPC_SH = 0x29 << 26,
292 OPC_SW = 0x2B << 26,
293
294 OPC_SPECIAL = 0x00 << 26,
295 OPC_SLL = OPC_SPECIAL | 0x00,
296 OPC_SRL = OPC_SPECIAL | 0x02,
297 OPC_ROTR = OPC_SPECIAL | (0x01 << 21) | 0x02,
298 OPC_SRA = OPC_SPECIAL | 0x03,
299 OPC_SLLV = OPC_SPECIAL | 0x04,
300 OPC_SRLV = OPC_SPECIAL | 0x06,
301 OPC_ROTRV = OPC_SPECIAL | (0x01 << 6) | 0x06,
302 OPC_SRAV = OPC_SPECIAL | 0x07,
303 OPC_JR = OPC_SPECIAL | 0x08,
304 OPC_JALR = OPC_SPECIAL | 0x09,
305 OPC_MOVZ = OPC_SPECIAL | 0x0A,
306 OPC_MOVN = OPC_SPECIAL | 0x0B,
307 OPC_MFHI = OPC_SPECIAL | 0x10,
308 OPC_MFLO = OPC_SPECIAL | 0x12,
309 OPC_MULT = OPC_SPECIAL | 0x18,
310 OPC_MULTU = OPC_SPECIAL | 0x19,
311 OPC_DIV = OPC_SPECIAL | 0x1A,
312 OPC_DIVU = OPC_SPECIAL | 0x1B,
313 OPC_ADDU = OPC_SPECIAL | 0x21,
314 OPC_SUBU = OPC_SPECIAL | 0x23,
315 OPC_AND = OPC_SPECIAL | 0x24,
316 OPC_OR = OPC_SPECIAL | 0x25,
317 OPC_XOR = OPC_SPECIAL | 0x26,
318 OPC_NOR = OPC_SPECIAL | 0x27,
319 OPC_SLT = OPC_SPECIAL | 0x2A,
320 OPC_SLTU = OPC_SPECIAL | 0x2B,
321
322 OPC_REGIMM = 0x01 << 26,
323 OPC_BLTZ = OPC_REGIMM | (0x00 << 16),
324 OPC_BGEZ = OPC_REGIMM | (0x01 << 16),
325
326 OPC_SPECIAL2 = 0x1c << 26,
327 OPC_MUL = OPC_SPECIAL2 | 0x002,
328
329 OPC_SPECIAL3 = 0x1f << 26,
330 OPC_INS = OPC_SPECIAL3 | 0x004,
331 OPC_WSBH = OPC_SPECIAL3 | 0x0a0,
332 OPC_SEB = OPC_SPECIAL3 | 0x420,
333 OPC_SEH = OPC_SPECIAL3 | 0x620,
334};
335
336
337
338
339static inline void tcg_out_opc_reg(TCGContext *s, int opc,
340 TCGReg rd, TCGReg rs, TCGReg rt)
341{
342 int32_t inst;
343
344 inst = opc;
345 inst |= (rs & 0x1F) << 21;
346 inst |= (rt & 0x1F) << 16;
347 inst |= (rd & 0x1F) << 11;
348 tcg_out32(s, inst);
349}
350
351
352
353
354static inline void tcg_out_opc_imm(TCGContext *s, int opc,
355 TCGReg rt, TCGReg rs, TCGArg imm)
356{
357 int32_t inst;
358
359 inst = opc;
360 inst |= (rs & 0x1F) << 21;
361 inst |= (rt & 0x1F) << 16;
362 inst |= (imm & 0xffff);
363 tcg_out32(s, inst);
364}
365
366
367
368
369static inline void tcg_out_opc_br(TCGContext *s, int opc,
370 TCGReg rt, TCGReg rs)
371{
372
373
374
375 uint16_t offset = (uint16_t)(*(uint32_t *) s->code_ptr);
376
377 tcg_out_opc_imm(s, opc, rt, rs, offset);
378}
379
380
381
382
383static inline void tcg_out_opc_sa(TCGContext *s, int opc,
384 TCGReg rd, TCGReg rt, TCGArg sa)
385{
386 int32_t inst;
387
388 inst = opc;
389 inst |= (rt & 0x1F) << 16;
390 inst |= (rd & 0x1F) << 11;
391 inst |= (sa & 0x1F) << 6;
392 tcg_out32(s, inst);
393
394}
395
396static inline void tcg_out_nop(TCGContext *s)
397{
398 tcg_out32(s, 0);
399}
400
401static inline void tcg_out_mov(TCGContext *s, TCGType type,
402 TCGReg ret, TCGReg arg)
403{
404
405 if (ret != arg) {
406 tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
407 }
408}
409
410static inline void tcg_out_movi(TCGContext *s, TCGType type,
411 TCGReg reg, tcg_target_long arg)
412{
413 if (arg == (int16_t)arg) {
414 tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
415 } else if (arg == (uint16_t)arg) {
416 tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
417 } else {
418 tcg_out_opc_imm(s, OPC_LUI, reg, 0, arg >> 16);
419 tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
420 }
421}
422
423static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
424{
425#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
426 tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
427#else
428
429 if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
430 tcg_abort();
431 }
432
433 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
434 tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
435 tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
436 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
437#endif
438}
439
440static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
441{
442#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
443 tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
444 tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
445#else
446
447 if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
448 tcg_abort();
449 }
450
451 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
452 tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
453 tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
454 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
455#endif
456}
457
458static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
459{
460#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
461 tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
462 tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
463#else
464
465 if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
466 tcg_abort();
467 }
468
469 tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
470
471 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
472 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
473
474 tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, arg, 0xff00);
475 tcg_out_opc_sa(s, OPC_SLL, TCG_REG_AT, TCG_REG_AT, 8);
476 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
477
478 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
479 tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
480 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
481#endif
482}
483
484static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
485{
486#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
487 tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
488#else
489 tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
490 tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
491#endif
492}
493
494static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
495{
496#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
497 tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
498#else
499 tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
500 tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
501#endif
502}
503
504static inline void tcg_out_ldst(TCGContext *s, int opc, TCGArg arg,
505 TCGReg arg1, TCGArg arg2)
506{
507 if (arg2 == (int16_t) arg2) {
508 tcg_out_opc_imm(s, opc, arg, arg1, arg2);
509 } else {
510 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, arg2);
511 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, TCG_REG_AT, arg1);
512 tcg_out_opc_imm(s, opc, arg, TCG_REG_AT, 0);
513 }
514}
515
516static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
517 TCGReg arg1, tcg_target_long arg2)
518{
519 tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
520}
521
522static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
523 TCGReg arg1, tcg_target_long arg2)
524{
525 tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
526}
527
528static inline void tcg_out_addi(TCGContext *s, TCGReg reg, TCGArg val)
529{
530 if (val == (int16_t)val) {
531 tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
532 } else {
533 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, val);
534 tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_REG_AT);
535 }
536}
537
538
539
540
541
542
543
544
545
546
547
548#define DEFINE_TCG_OUT_CALL_IARG(NAME, ARGPARAM) \
549 static inline void NAME(TCGContext *s, int *arg_num, ARGPARAM) \
550 { \
551 if (*arg_num < 4) { \
552 DEFINE_TCG_OUT_CALL_IARG_GET_ARG(tcg_target_call_iarg_regs[*arg_num]); \
553 } else { \
554 DEFINE_TCG_OUT_CALL_IARG_GET_ARG(TCG_REG_AT); \
555 tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 4 * (*arg_num)); \
556 } \
557 (*arg_num)++; \
558}
559#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
560 tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xff);
561DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg8, TCGReg arg)
562#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
563#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
564 tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xffff);
565DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg16, TCGReg arg)
566#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
567#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
568 tcg_out_movi(s, TCG_TYPE_I32, A, arg);
569DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32, TCGArg arg)
570#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
571
572
573
574static inline void tcg_out_call_iarg_reg32(TCGContext *s, int *arg_num,
575 TCGReg arg)
576{
577 if (*arg_num < 4) {
578 tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[*arg_num], arg);
579 } else {
580 tcg_out_st(s, TCG_TYPE_I32, arg, TCG_REG_SP, 4 * (*arg_num));
581 }
582 (*arg_num)++;
583}
584
585static inline void tcg_out_call_iarg_reg64(TCGContext *s, int *arg_num,
586 TCGReg arg_low, TCGReg arg_high)
587{
588 (*arg_num) = (*arg_num + 1) & ~1;
589
590#if defined(TCG_TARGET_WORDS_BIGENDIAN)
591 tcg_out_call_iarg_reg32(s, arg_num, arg_high);
592 tcg_out_call_iarg_reg32(s, arg_num, arg_low);
593#else
594 tcg_out_call_iarg_reg32(s, arg_num, arg_low);
595 tcg_out_call_iarg_reg32(s, arg_num, arg_high);
596#endif
597}
598
599static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGArg arg1,
600 TCGArg arg2, int label_index)
601{
602 TCGLabel *l = &s->labels[label_index];
603
604 switch (cond) {
605 case TCG_COND_EQ:
606 tcg_out_opc_br(s, OPC_BEQ, arg1, arg2);
607 break;
608 case TCG_COND_NE:
609 tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
610 break;
611 case TCG_COND_LT:
612 if (arg2 == 0) {
613 tcg_out_opc_br(s, OPC_BLTZ, 0, arg1);
614 } else {
615 tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
616 tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
617 }
618 break;
619 case TCG_COND_LTU:
620 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
621 tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
622 break;
623 case TCG_COND_GE:
624 if (arg2 == 0) {
625 tcg_out_opc_br(s, OPC_BGEZ, 0, arg1);
626 } else {
627 tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
628 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
629 }
630 break;
631 case TCG_COND_GEU:
632 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
633 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
634 break;
635 case TCG_COND_LE:
636 if (arg2 == 0) {
637 tcg_out_opc_br(s, OPC_BLEZ, 0, arg1);
638 } else {
639 tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
640 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
641 }
642 break;
643 case TCG_COND_LEU:
644 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
645 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
646 break;
647 case TCG_COND_GT:
648 if (arg2 == 0) {
649 tcg_out_opc_br(s, OPC_BGTZ, 0, arg1);
650 } else {
651 tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
652 tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
653 }
654 break;
655 case TCG_COND_GTU:
656 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
657 tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
658 break;
659 default:
660 tcg_abort();
661 break;
662 }
663 if (l->has_value) {
664 reloc_pc16(s->code_ptr - 4, l->u.value);
665 } else {
666 tcg_out_reloc(s, s->code_ptr - 4, R_MIPS_PC16, label_index, 0);
667 }
668 tcg_out_nop(s);
669}
670
671
672
673static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGArg arg1,
674 TCGArg arg2, TCGArg arg3, TCGArg arg4,
675 int label_index)
676{
677 void *label_ptr;
678
679 switch(cond) {
680 case TCG_COND_NE:
681 tcg_out_brcond(s, TCG_COND_NE, arg2, arg4, label_index);
682 tcg_out_brcond(s, TCG_COND_NE, arg1, arg3, label_index);
683 return;
684 case TCG_COND_EQ:
685 break;
686 case TCG_COND_LT:
687 case TCG_COND_LE:
688 tcg_out_brcond(s, TCG_COND_LT, arg2, arg4, label_index);
689 break;
690 case TCG_COND_GT:
691 case TCG_COND_GE:
692 tcg_out_brcond(s, TCG_COND_GT, arg2, arg4, label_index);
693 break;
694 case TCG_COND_LTU:
695 case TCG_COND_LEU:
696 tcg_out_brcond(s, TCG_COND_LTU, arg2, arg4, label_index);
697 break;
698 case TCG_COND_GTU:
699 case TCG_COND_GEU:
700 tcg_out_brcond(s, TCG_COND_GTU, arg2, arg4, label_index);
701 break;
702 default:
703 tcg_abort();
704 }
705
706 label_ptr = s->code_ptr;
707 tcg_out_opc_br(s, OPC_BNE, arg2, arg4);
708 tcg_out_nop(s);
709
710 switch(cond) {
711 case TCG_COND_EQ:
712 tcg_out_brcond(s, TCG_COND_EQ, arg1, arg3, label_index);
713 break;
714 case TCG_COND_LT:
715 case TCG_COND_LTU:
716 tcg_out_brcond(s, TCG_COND_LTU, arg1, arg3, label_index);
717 break;
718 case TCG_COND_LE:
719 case TCG_COND_LEU:
720 tcg_out_brcond(s, TCG_COND_LEU, arg1, arg3, label_index);
721 break;
722 case TCG_COND_GT:
723 case TCG_COND_GTU:
724 tcg_out_brcond(s, TCG_COND_GTU, arg1, arg3, label_index);
725 break;
726 case TCG_COND_GE:
727 case TCG_COND_GEU:
728 tcg_out_brcond(s, TCG_COND_GEU, arg1, arg3, label_index);
729 break;
730 default:
731 tcg_abort();
732 }
733
734 reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
735}
736
737static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
738 TCGArg c1, TCGArg c2, TCGArg v)
739{
740 switch (cond) {
741 case TCG_COND_EQ:
742 if (c1 == 0) {
743 tcg_out_opc_reg(s, OPC_MOVZ, ret, v, c2);
744 } else if (c2 == 0) {
745 tcg_out_opc_reg(s, OPC_MOVZ, ret, v, c1);
746 } else {
747 tcg_out_opc_reg(s, OPC_XOR, TCG_REG_AT, c1, c2);
748 tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
749 }
750 break;
751 case TCG_COND_NE:
752 if (c1 == 0) {
753 tcg_out_opc_reg(s, OPC_MOVN, ret, v, c2);
754 } else if (c2 == 0) {
755 tcg_out_opc_reg(s, OPC_MOVN, ret, v, c1);
756 } else {
757 tcg_out_opc_reg(s, OPC_XOR, TCG_REG_AT, c1, c2);
758 tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
759 }
760 break;
761 case TCG_COND_LT:
762 tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c1, c2);
763 tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
764 break;
765 case TCG_COND_LTU:
766 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c1, c2);
767 tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
768 break;
769 case TCG_COND_GE:
770 tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c1, c2);
771 tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
772 break;
773 case TCG_COND_GEU:
774 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c1, c2);
775 tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
776 break;
777 case TCG_COND_LE:
778 tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c2, c1);
779 tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
780 break;
781 case TCG_COND_LEU:
782 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c2, c1);
783 tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
784 break;
785 case TCG_COND_GT:
786 tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c2, c1);
787 tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
788 break;
789 case TCG_COND_GTU:
790 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c2, c1);
791 tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
792 break;
793 default:
794 tcg_abort();
795 break;
796 }
797}
798
799static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
800 TCGArg arg1, TCGArg arg2)
801{
802 switch (cond) {
803 case TCG_COND_EQ:
804 if (arg1 == 0) {
805 tcg_out_opc_imm(s, OPC_SLTIU, ret, arg2, 1);
806 } else if (arg2 == 0) {
807 tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
808 } else {
809 tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
810 tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
811 }
812 break;
813 case TCG_COND_NE:
814 if (arg1 == 0) {
815 tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg2);
816 } else if (arg2 == 0) {
817 tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
818 } else {
819 tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
820 tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
821 }
822 break;
823 case TCG_COND_LT:
824 tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
825 break;
826 case TCG_COND_LTU:
827 tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
828 break;
829 case TCG_COND_GE:
830 tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
831 tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
832 break;
833 case TCG_COND_GEU:
834 tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
835 tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
836 break;
837 case TCG_COND_LE:
838 tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
839 tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
840 break;
841 case TCG_COND_LEU:
842 tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
843 tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
844 break;
845 case TCG_COND_GT:
846 tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
847 break;
848 case TCG_COND_GTU:
849 tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
850 break;
851 default:
852 tcg_abort();
853 break;
854 }
855}
856
857
858
859static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
860 TCGArg arg1, TCGArg arg2, TCGArg arg3, TCGArg arg4)
861{
862 switch (cond) {
863 case TCG_COND_EQ:
864 tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_AT, arg2, arg4);
865 tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg1, arg3);
866 tcg_out_opc_reg(s, OPC_AND, ret, TCG_REG_AT, TCG_REG_T0);
867 return;
868 case TCG_COND_NE:
869 tcg_out_setcond(s, TCG_COND_NE, TCG_REG_AT, arg2, arg4);
870 tcg_out_setcond(s, TCG_COND_NE, TCG_REG_T0, arg1, arg3);
871 tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_AT, TCG_REG_T0);
872 return;
873 case TCG_COND_LT:
874 case TCG_COND_LE:
875 tcg_out_setcond(s, TCG_COND_LT, TCG_REG_AT, arg2, arg4);
876 break;
877 case TCG_COND_GT:
878 case TCG_COND_GE:
879 tcg_out_setcond(s, TCG_COND_GT, TCG_REG_AT, arg2, arg4);
880 break;
881 case TCG_COND_LTU:
882 case TCG_COND_LEU:
883 tcg_out_setcond(s, TCG_COND_LTU, TCG_REG_AT, arg2, arg4);
884 break;
885 case TCG_COND_GTU:
886 case TCG_COND_GEU:
887 tcg_out_setcond(s, TCG_COND_GTU, TCG_REG_AT, arg2, arg4);
888 break;
889 default:
890 tcg_abort();
891 break;
892 }
893
894 tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg2, arg4);
895
896 switch(cond) {
897 case TCG_COND_LT:
898 case TCG_COND_LTU:
899 tcg_out_setcond(s, TCG_COND_LTU, ret, arg1, arg3);
900 break;
901 case TCG_COND_LE:
902 case TCG_COND_LEU:
903 tcg_out_setcond(s, TCG_COND_LEU, ret, arg1, arg3);
904 break;
905 case TCG_COND_GT:
906 case TCG_COND_GTU:
907 tcg_out_setcond(s, TCG_COND_GTU, ret, arg1, arg3);
908 break;
909 case TCG_COND_GE:
910 case TCG_COND_GEU:
911 tcg_out_setcond(s, TCG_COND_GEU, ret, arg1, arg3);
912 break;
913 default:
914 tcg_abort();
915 }
916
917 tcg_out_opc_reg(s, OPC_AND, ret, ret, TCG_REG_T0);
918 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
919}
920
921#if defined(CONFIG_SOFTMMU)
922
923#include "exec/softmmu_defs.h"
924
925
926
927static const void * const qemu_ld_helpers[4] = {
928 helper_ldb_mmu,
929 helper_ldw_mmu,
930 helper_ldl_mmu,
931 helper_ldq_mmu,
932};
933
934
935
936static const void * const qemu_st_helpers[4] = {
937 helper_stb_mmu,
938 helper_stw_mmu,
939 helper_stl_mmu,
940 helper_stq_mmu,
941};
942#endif
943
944static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
945 int opc)
946{
947 TCGReg addr_regl, data_regl, data_regh, data_reg1, data_reg2;
948#if defined(CONFIG_SOFTMMU)
949 void *label1_ptr, *label2_ptr;
950 int arg_num;
951 int mem_index, s_bits;
952 int addr_meml;
953# if TARGET_LONG_BITS == 64
954 uint8_t *label3_ptr;
955 TCGReg addr_regh;
956 int addr_memh;
957# endif
958#endif
959 data_regl = *args++;
960 if (opc == 3)
961 data_regh = *args++;
962 else
963 data_regh = 0;
964 addr_regl = *args++;
965#if defined(CONFIG_SOFTMMU)
966# if TARGET_LONG_BITS == 64
967 addr_regh = *args++;
968# if defined(TCG_TARGET_WORDS_BIGENDIAN)
969 addr_memh = 0;
970 addr_meml = 4;
971# else
972 addr_memh = 4;
973 addr_meml = 0;
974# endif
975# else
976 addr_meml = 0;
977# endif
978 mem_index = *args;
979 s_bits = opc & 3;
980#endif
981
982 if (opc == 3) {
983#if defined(TCG_TARGET_WORDS_BIGENDIAN)
984 data_reg1 = data_regh;
985 data_reg2 = data_regl;
986#else
987 data_reg1 = data_regl;
988 data_reg2 = data_regh;
989#endif
990 } else {
991 data_reg1 = data_regl;
992 data_reg2 = 0;
993 }
994#if defined(CONFIG_SOFTMMU)
995 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
996 tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
997 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
998 tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
999 offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_meml);
1000 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1001 tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
1002
1003# if TARGET_LONG_BITS == 64
1004 label3_ptr = s->code_ptr;
1005 tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1006 tcg_out_nop(s);
1007
1008 tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1009 offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_memh);
1010
1011 label1_ptr = s->code_ptr;
1012 tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1013 tcg_out_nop(s);
1014
1015 reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1016# else
1017 label1_ptr = s->code_ptr;
1018 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1019 tcg_out_nop(s);
1020# endif
1021
1022
1023 arg_num = 0;
1024 tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0);
1025# if TARGET_LONG_BITS == 64
1026 tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh);
1027# else
1028 tcg_out_call_iarg_reg32(s, &arg_num, addr_regl);
1029# endif
1030 tcg_out_call_iarg_imm32(s, &arg_num, mem_index);
1031 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);
1032 tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1033 tcg_out_nop(s);
1034
1035 switch(opc) {
1036 case 0:
1037 tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);
1038 break;
1039 case 0 | 4:
1040 tcg_out_ext8s(s, data_reg1, TCG_REG_V0);
1041 break;
1042 case 1:
1043 tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);
1044 break;
1045 case 1 | 4:
1046 tcg_out_ext16s(s, data_reg1, TCG_REG_V0);
1047 break;
1048 case 2:
1049 tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
1050 break;
1051 case 3:
1052 tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_V1);
1053 tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
1054 break;
1055 default:
1056 tcg_abort();
1057 }
1058
1059 label2_ptr = s->code_ptr;
1060 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1061 tcg_out_nop(s);
1062
1063
1064 reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1065
1066 tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1067 offsetof(CPUArchState, tlb_table[mem_index][0].addend));
1068 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
1069#else
1070 if (GUEST_BASE == (int16_t)GUEST_BASE) {
1071 tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_regl, GUEST_BASE);
1072 } else {
1073 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);
1074 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);
1075 }
1076#endif
1077
1078 switch(opc) {
1079 case 0:
1080 tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);
1081 break;
1082 case 0 | 4:
1083 tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);
1084 break;
1085 case 1:
1086 if (TCG_NEED_BSWAP) {
1087 tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
1088 tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
1089 } else {
1090 tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);
1091 }
1092 break;
1093 case 1 | 4:
1094 if (TCG_NEED_BSWAP) {
1095 tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
1096 tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
1097 } else {
1098 tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);
1099 }
1100 break;
1101 case 2:
1102 if (TCG_NEED_BSWAP) {
1103 tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
1104 tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
1105 } else {
1106 tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
1107 }
1108 break;
1109 case 3:
1110 if (TCG_NEED_BSWAP) {
1111 tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);
1112 tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
1113 tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
1114 tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
1115 } else {
1116 tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
1117 tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);
1118 }
1119 break;
1120 default:
1121 tcg_abort();
1122 }
1123
1124#if defined(CONFIG_SOFTMMU)
1125 reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1126#endif
1127}
1128
1129static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1130 int opc)
1131{
1132 TCGReg addr_regl, data_regl, data_regh, data_reg1, data_reg2;
1133#if defined(CONFIG_SOFTMMU)
1134 uint8_t *label1_ptr, *label2_ptr;
1135 int arg_num;
1136 int mem_index, s_bits;
1137 int addr_meml;
1138#endif
1139#if TARGET_LONG_BITS == 64
1140# if defined(CONFIG_SOFTMMU)
1141 uint8_t *label3_ptr;
1142 TCGReg addr_regh;
1143 int addr_memh;
1144# endif
1145#endif
1146 data_regl = *args++;
1147 if (opc == 3) {
1148 data_regh = *args++;
1149 } else {
1150 data_regh = 0;
1151 }
1152 addr_regl = *args++;
1153#if defined(CONFIG_SOFTMMU)
1154# if TARGET_LONG_BITS == 64
1155 addr_regh = *args++;
1156# if defined(TCG_TARGET_WORDS_BIGENDIAN)
1157 addr_memh = 0;
1158 addr_meml = 4;
1159# else
1160 addr_memh = 4;
1161 addr_meml = 0;
1162# endif
1163# else
1164 addr_meml = 0;
1165# endif
1166 mem_index = *args;
1167 s_bits = opc;
1168#endif
1169
1170 if (opc == 3) {
1171#if defined(TCG_TARGET_WORDS_BIGENDIAN)
1172 data_reg1 = data_regh;
1173 data_reg2 = data_regl;
1174#else
1175 data_reg1 = data_regl;
1176 data_reg2 = data_regh;
1177#endif
1178 } else {
1179 data_reg1 = data_regl;
1180 data_reg2 = 0;
1181 }
1182
1183#if defined(CONFIG_SOFTMMU)
1184 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1185 tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1186 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1187 tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1188 offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_meml);
1189 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1190 tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
1191
1192# if TARGET_LONG_BITS == 64
1193 label3_ptr = s->code_ptr;
1194 tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1195 tcg_out_nop(s);
1196
1197 tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1198 offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_memh);
1199
1200 label1_ptr = s->code_ptr;
1201 tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1202 tcg_out_nop(s);
1203
1204 reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1205# else
1206 label1_ptr = s->code_ptr;
1207 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1208 tcg_out_nop(s);
1209# endif
1210
1211
1212 arg_num = 0;
1213 tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0);
1214# if TARGET_LONG_BITS == 64
1215 tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh);
1216# else
1217 tcg_out_call_iarg_reg32(s, &arg_num, addr_regl);
1218# endif
1219 switch(opc) {
1220 case 0:
1221 tcg_out_call_iarg_reg8(s, &arg_num, data_regl);
1222 break;
1223 case 1:
1224 tcg_out_call_iarg_reg16(s, &arg_num, data_regl);
1225 break;
1226 case 2:
1227 tcg_out_call_iarg_reg32(s, &arg_num, data_regl);
1228 break;
1229 case 3:
1230 tcg_out_call_iarg_reg64(s, &arg_num, data_regl, data_regh);
1231 break;
1232 default:
1233 tcg_abort();
1234 }
1235 tcg_out_call_iarg_imm32(s, &arg_num, mem_index);
1236 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]);
1237 tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1238 tcg_out_nop(s);
1239
1240 label2_ptr = s->code_ptr;
1241 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1242 tcg_out_nop(s);
1243
1244
1245 reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1246
1247 tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1248 offsetof(CPUArchState, tlb_table[mem_index][0].addend));
1249 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1250#else
1251 if (GUEST_BASE == (int16_t)GUEST_BASE) {
1252 tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, addr_regl, GUEST_BASE);
1253 } else {
1254 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, GUEST_BASE);
1255 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1256 }
1257
1258#endif
1259
1260 switch(opc) {
1261 case 0:
1262 tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
1263 break;
1264 case 1:
1265 if (TCG_NEED_BSWAP) {
1266 tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_T0, data_reg1, 0xffff);
1267 tcg_out_bswap16(s, TCG_REG_T0, TCG_REG_T0);
1268 tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
1269 } else {
1270 tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
1271 }
1272 break;
1273 case 2:
1274 if (TCG_NEED_BSWAP) {
1275 tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1276 tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1277 } else {
1278 tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1279 }
1280 break;
1281 case 3:
1282 if (TCG_NEED_BSWAP) {
1283 tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
1284 tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1285 tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1286 tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
1287 } else {
1288 tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1289 tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4);
1290 }
1291 break;
1292 default:
1293 tcg_abort();
1294 }
1295
1296#if defined(CONFIG_SOFTMMU)
1297 reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1298#endif
1299}
1300
1301static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1302 const TCGArg *args, const int *const_args)
1303{
1304 switch(opc) {
1305 case INDEX_op_exit_tb:
1306 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_V0, args[0]);
1307 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, (tcg_target_long)tb_ret_addr);
1308 tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1309 tcg_out_nop(s);
1310 break;
1311 case INDEX_op_goto_tb:
1312 if (s->tb_jmp_offset) {
1313
1314 tcg_abort();
1315 } else {
1316
1317 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
1318 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_AT, TCG_REG_AT, 0);
1319 tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1320 }
1321 tcg_out_nop(s);
1322 s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1323 break;
1324 case INDEX_op_call:
1325 tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0);
1326 tcg_out_nop(s);
1327 break;
1328 case INDEX_op_br:
1329 tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]);
1330 break;
1331
1332 case INDEX_op_mov_i32:
1333 tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1334 break;
1335 case INDEX_op_movi_i32:
1336 tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1337 break;
1338
1339 case INDEX_op_ld8u_i32:
1340 tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1341 break;
1342 case INDEX_op_ld8s_i32:
1343 tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
1344 break;
1345 case INDEX_op_ld16u_i32:
1346 tcg_out_ldst(s, OPC_LHU, args[0], args[1], args[2]);
1347 break;
1348 case INDEX_op_ld16s_i32:
1349 tcg_out_ldst(s, OPC_LH, args[0], args[1], args[2]);
1350 break;
1351 case INDEX_op_ld_i32:
1352 tcg_out_ldst(s, OPC_LW, args[0], args[1], args[2]);
1353 break;
1354 case INDEX_op_st8_i32:
1355 tcg_out_ldst(s, OPC_SB, args[0], args[1], args[2]);
1356 break;
1357 case INDEX_op_st16_i32:
1358 tcg_out_ldst(s, OPC_SH, args[0], args[1], args[2]);
1359 break;
1360 case INDEX_op_st_i32:
1361 tcg_out_ldst(s, OPC_SW, args[0], args[1], args[2]);
1362 break;
1363
1364 case INDEX_op_add_i32:
1365 if (const_args[2]) {
1366 tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], args[2]);
1367 } else {
1368 tcg_out_opc_reg(s, OPC_ADDU, args[0], args[1], args[2]);
1369 }
1370 break;
1371 case INDEX_op_add2_i32:
1372 if (const_args[4]) {
1373 tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], args[4]);
1374 } else {
1375 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, args[2], args[4]);
1376 }
1377 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, TCG_REG_AT, args[2]);
1378 if (const_args[5]) {
1379 tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], args[5]);
1380 } else {
1381 tcg_out_opc_reg(s, OPC_ADDU, args[1], args[3], args[5]);
1382 }
1383 tcg_out_opc_reg(s, OPC_ADDU, args[1], args[1], TCG_REG_T0);
1384 tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1385 break;
1386 case INDEX_op_sub_i32:
1387 if (const_args[2]) {
1388 tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], -args[2]);
1389 } else {
1390 tcg_out_opc_reg(s, OPC_SUBU, args[0], args[1], args[2]);
1391 }
1392 break;
1393 case INDEX_op_sub2_i32:
1394 if (const_args[4]) {
1395 tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], -args[4]);
1396 } else {
1397 tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, args[2], args[4]);
1398 }
1399 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, args[2], TCG_REG_AT);
1400 if (const_args[5]) {
1401 tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], -args[5]);
1402 } else {
1403 tcg_out_opc_reg(s, OPC_SUBU, args[1], args[3], args[5]);
1404 }
1405 tcg_out_opc_reg(s, OPC_SUBU, args[1], args[1], TCG_REG_T0);
1406 tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1407 break;
1408 case INDEX_op_mul_i32:
1409#if defined(__mips_isa_rev) && (__mips_isa_rev >= 1)
1410 tcg_out_opc_reg(s, OPC_MUL, args[0], args[1], args[2]);
1411#else
1412 tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
1413 tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1414#endif
1415 break;
1416 case INDEX_op_mulu2_i32:
1417 tcg_out_opc_reg(s, OPC_MULTU, 0, args[2], args[3]);
1418 tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1419 tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0);
1420 break;
1421 case INDEX_op_div_i32:
1422 tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1423 tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1424 break;
1425 case INDEX_op_divu_i32:
1426 tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1427 tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1428 break;
1429 case INDEX_op_rem_i32:
1430 tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1431 tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1432 break;
1433 case INDEX_op_remu_i32:
1434 tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1435 tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1436 break;
1437
1438 case INDEX_op_and_i32:
1439 if (const_args[2]) {
1440 tcg_out_opc_imm(s, OPC_ANDI, args[0], args[1], args[2]);
1441 } else {
1442 tcg_out_opc_reg(s, OPC_AND, args[0], args[1], args[2]);
1443 }
1444 break;
1445 case INDEX_op_or_i32:
1446 if (const_args[2]) {
1447 tcg_out_opc_imm(s, OPC_ORI, args[0], args[1], args[2]);
1448 } else {
1449 tcg_out_opc_reg(s, OPC_OR, args[0], args[1], args[2]);
1450 }
1451 break;
1452 case INDEX_op_nor_i32:
1453 tcg_out_opc_reg(s, OPC_NOR, args[0], args[1], args[2]);
1454 break;
1455 case INDEX_op_not_i32:
1456 tcg_out_opc_reg(s, OPC_NOR, args[0], TCG_REG_ZERO, args[1]);
1457 break;
1458 case INDEX_op_xor_i32:
1459 if (const_args[2]) {
1460 tcg_out_opc_imm(s, OPC_XORI, args[0], args[1], args[2]);
1461 } else {
1462 tcg_out_opc_reg(s, OPC_XOR, args[0], args[1], args[2]);
1463 }
1464 break;
1465
1466 case INDEX_op_sar_i32:
1467 if (const_args[2]) {
1468 tcg_out_opc_sa(s, OPC_SRA, args[0], args[1], args[2]);
1469 } else {
1470 tcg_out_opc_reg(s, OPC_SRAV, args[0], args[2], args[1]);
1471 }
1472 break;
1473 case INDEX_op_shl_i32:
1474 if (const_args[2]) {
1475 tcg_out_opc_sa(s, OPC_SLL, args[0], args[1], args[2]);
1476 } else {
1477 tcg_out_opc_reg(s, OPC_SLLV, args[0], args[2], args[1]);
1478 }
1479 break;
1480 case INDEX_op_shr_i32:
1481 if (const_args[2]) {
1482 tcg_out_opc_sa(s, OPC_SRL, args[0], args[1], args[2]);
1483 } else {
1484 tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
1485 }
1486 break;
1487 case INDEX_op_rotl_i32:
1488 if (const_args[2]) {
1489 tcg_out_opc_sa(s, OPC_ROTR, args[0], args[1], 0x20 - args[2]);
1490 } else {
1491 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, 32);
1492 tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, TCG_REG_AT, args[2]);
1493 tcg_out_opc_reg(s, OPC_ROTRV, args[0], TCG_REG_AT, args[1]);
1494 }
1495 break;
1496 case INDEX_op_rotr_i32:
1497 if (const_args[2]) {
1498 tcg_out_opc_sa(s, OPC_ROTR, args[0], args[1], args[2]);
1499 } else {
1500 tcg_out_opc_reg(s, OPC_ROTRV, args[0], args[2], args[1]);
1501 }
1502 break;
1503
1504
1505
1506 case INDEX_op_bswap16_i32:
1507 tcg_out_bswap16(s, args[0], args[1]);
1508 break;
1509 case INDEX_op_bswap32_i32:
1510 tcg_out_bswap32(s, args[0], args[1]);
1511 break;
1512
1513 case INDEX_op_ext8s_i32:
1514 tcg_out_ext8s(s, args[0], args[1]);
1515 break;
1516 case INDEX_op_ext16s_i32:
1517 tcg_out_ext16s(s, args[0], args[1]);
1518 break;
1519
1520 case INDEX_op_deposit_i32:
1521 tcg_out_opc_imm(s, OPC_INS, args[0], args[2],
1522 ((args[3] + args[4] - 1) << 11) | (args[3] << 6));
1523 break;
1524
1525 case INDEX_op_brcond_i32:
1526 tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
1527 break;
1528 case INDEX_op_brcond2_i32:
1529 tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
1530 break;
1531
1532 case INDEX_op_movcond_i32:
1533 tcg_out_movcond(s, args[5], args[0], args[1], args[2], args[3]);
1534 break;
1535
1536 case INDEX_op_setcond_i32:
1537 tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
1538 break;
1539 case INDEX_op_setcond2_i32:
1540 tcg_out_setcond2(s, args[5], args[0], args[1], args[2], args[3], args[4]);
1541 break;
1542
1543 case INDEX_op_qemu_ld8u:
1544 tcg_out_qemu_ld(s, args, 0);
1545 break;
1546 case INDEX_op_qemu_ld8s:
1547 tcg_out_qemu_ld(s, args, 0 | 4);
1548 break;
1549 case INDEX_op_qemu_ld16u:
1550 tcg_out_qemu_ld(s, args, 1);
1551 break;
1552 case INDEX_op_qemu_ld16s:
1553 tcg_out_qemu_ld(s, args, 1 | 4);
1554 break;
1555 case INDEX_op_qemu_ld32:
1556 tcg_out_qemu_ld(s, args, 2);
1557 break;
1558 case INDEX_op_qemu_ld64:
1559 tcg_out_qemu_ld(s, args, 3);
1560 break;
1561 case INDEX_op_qemu_st8:
1562 tcg_out_qemu_st(s, args, 0);
1563 break;
1564 case INDEX_op_qemu_st16:
1565 tcg_out_qemu_st(s, args, 1);
1566 break;
1567 case INDEX_op_qemu_st32:
1568 tcg_out_qemu_st(s, args, 2);
1569 break;
1570 case INDEX_op_qemu_st64:
1571 tcg_out_qemu_st(s, args, 3);
1572 break;
1573
1574 default:
1575 tcg_abort();
1576 }
1577}
1578
1579static const TCGTargetOpDef mips_op_defs[] = {
1580 { INDEX_op_exit_tb, { } },
1581 { INDEX_op_goto_tb, { } },
1582 { INDEX_op_call, { "C" } },
1583 { INDEX_op_br, { } },
1584
1585 { INDEX_op_mov_i32, { "r", "r" } },
1586 { INDEX_op_movi_i32, { "r" } },
1587 { INDEX_op_ld8u_i32, { "r", "r" } },
1588 { INDEX_op_ld8s_i32, { "r", "r" } },
1589 { INDEX_op_ld16u_i32, { "r", "r" } },
1590 { INDEX_op_ld16s_i32, { "r", "r" } },
1591 { INDEX_op_ld_i32, { "r", "r" } },
1592 { INDEX_op_st8_i32, { "rZ", "r" } },
1593 { INDEX_op_st16_i32, { "rZ", "r" } },
1594 { INDEX_op_st_i32, { "rZ", "r" } },
1595
1596 { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
1597 { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1598 { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1599 { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1600 { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1601 { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1602 { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1603 { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
1604
1605 { INDEX_op_and_i32, { "r", "rZ", "rI" } },
1606 { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1607 { INDEX_op_not_i32, { "r", "rZ" } },
1608 { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1609 { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1610
1611 { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
1612 { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
1613 { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
1614 { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
1615 { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
1616
1617 { INDEX_op_bswap16_i32, { "r", "r" } },
1618 { INDEX_op_bswap32_i32, { "r", "r" } },
1619
1620 { INDEX_op_ext8s_i32, { "r", "rZ" } },
1621 { INDEX_op_ext16s_i32, { "r", "rZ" } },
1622
1623 { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
1624
1625 { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1626 { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "0" } },
1627 { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1628 { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1629
1630 { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1631 { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1632 { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1633
1634#if TARGET_LONG_BITS == 32
1635 { INDEX_op_qemu_ld8u, { "L", "lZ" } },
1636 { INDEX_op_qemu_ld8s, { "L", "lZ" } },
1637 { INDEX_op_qemu_ld16u, { "L", "lZ" } },
1638 { INDEX_op_qemu_ld16s, { "L", "lZ" } },
1639 { INDEX_op_qemu_ld32, { "L", "lZ" } },
1640 { INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
1641
1642 { INDEX_op_qemu_st8, { "SZ", "SZ" } },
1643 { INDEX_op_qemu_st16, { "SZ", "SZ" } },
1644 { INDEX_op_qemu_st32, { "SZ", "SZ" } },
1645 { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ" } },
1646#else
1647 { INDEX_op_qemu_ld8u, { "L", "lZ", "lZ" } },
1648 { INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
1649 { INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
1650 { INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
1651 { INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
1652 { INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
1653
1654 { INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
1655 { INDEX_op_qemu_st16, { "SZ", "SZ", "SZ" } },
1656 { INDEX_op_qemu_st32, { "SZ", "SZ", "SZ" } },
1657 { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ", "SZ" } },
1658#endif
1659 { -1 },
1660};
1661
1662static int tcg_target_callee_save_regs[] = {
1663 TCG_REG_S0,
1664 TCG_REG_S1,
1665 TCG_REG_S2,
1666 TCG_REG_S3,
1667 TCG_REG_S4,
1668 TCG_REG_S5,
1669 TCG_REG_S6,
1670 TCG_REG_S7,
1671 TCG_REG_FP,
1672 TCG_REG_RA,
1673};
1674
1675
1676static void tcg_target_qemu_prologue(TCGContext *s)
1677{
1678 int i, frame_size;
1679
1680
1681 frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1682 + TCG_STATIC_CALL_ARGS_SIZE
1683 + CPU_TEMP_BUF_NLONGS * sizeof(long);
1684 frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1685 ~(TCG_TARGET_STACK_ALIGN - 1);
1686 tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1687 + TCG_STATIC_CALL_ARGS_SIZE,
1688 CPU_TEMP_BUF_NLONGS * sizeof(long));
1689
1690
1691 tcg_out_addi(s, TCG_REG_SP, -frame_size);
1692 for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1693 tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1694 TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1695 }
1696
1697
1698 tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
1699 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1700 tb_ret_addr = s->code_ptr;
1701
1702
1703 for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1704 tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1705 TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1706 }
1707
1708 tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1709 tcg_out_addi(s, TCG_REG_SP, frame_size);
1710}
1711
1712static void tcg_target_init(TCGContext *s)
1713{
1714 tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
1715 tcg_regset_set(tcg_target_call_clobber_regs,
1716 (1 << TCG_REG_V0) |
1717 (1 << TCG_REG_V1) |
1718 (1 << TCG_REG_A0) |
1719 (1 << TCG_REG_A1) |
1720 (1 << TCG_REG_A2) |
1721 (1 << TCG_REG_A3) |
1722 (1 << TCG_REG_T1) |
1723 (1 << TCG_REG_T2) |
1724 (1 << TCG_REG_T3) |
1725 (1 << TCG_REG_T4) |
1726 (1 << TCG_REG_T5) |
1727 (1 << TCG_REG_T6) |
1728 (1 << TCG_REG_T7) |
1729 (1 << TCG_REG_T8) |
1730 (1 << TCG_REG_T9));
1731
1732 tcg_regset_clear(s->reserved_regs);
1733 tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO);
1734 tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);
1735 tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);
1736 tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT);
1737 tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0);
1738 tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);
1739 tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);
1740 tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);
1741
1742 tcg_add_target_add_op_defs(mips_op_defs);
1743}
1744