]> Git Repo - qemu.git/blob - tcg/mips/tcg-target.c
softmmu templates: optionally pass CPUState to memory access functions
[qemu.git] / tcg / mips / tcg-target.c
1 /*
2  * Tiny Code Generator for QEMU
3  *
4  * Copyright (c) 2008-2009 Arnaud Patard <[email protected]>
5  * Copyright (c) 2009 Aurelien Jarno <[email protected]>
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 #ifdef CONFIG_TCG_PASS_AREG0
754 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
755    int mmu_idx) */
756 static 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 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
764    uintxx_t val, int mmu_idx) */
765 static 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 /* legacy helper signature: __ld_mmu(target_ulong addr, int
773    mmu_idx) */
774 static void *qemu_ld_helpers[4] = {
775     __ldb_mmu,
776     __ldw_mmu,
777     __ldl_mmu,
778     __ldq_mmu,
779 };
780
781 /* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
782    int mmu_idx) */
783 static void *qemu_st_helpers[4] = {
784     __stb_mmu,
785     __stw_mmu,
786     __stl_mmu,
787     __stq_mmu,
788 };
789 #endif
790 #endif
791
792 static 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     /* slow path */
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     /* XXX/FIXME: suboptimal and incorrect for 64 on 32 bit */
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     /* label1: fast path */
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
991 static 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     /* slow path */
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         /* Push mem_index on the stack */
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     /* XXX/FIXME: suboptimal and incorrect for 64 on 32 bit */
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     /* label1: fast path */
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
1179 static 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             /* direct jump method */
1192             tcg_abort();
1193         } else {
1194             /* indirect jump method */
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
1423 static 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
1499 static int tcg_target_callee_save_regs[] = {
1500     TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
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,       /* should be last for ABI compliance */
1511 };
1512
1513 /* Generate global QEMU prologue and epilogue code */
1514 static void tcg_target_qemu_prologue(TCGContext *s)
1515 {
1516     int i, frame_size;
1517
1518     /* reserve some stack space */
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     /* TB prologue */
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     /* Call generated code */
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     /* TB epilogue */
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
1546 static 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); /* zero register */
1568     tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
1569     tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
1570     tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT);   /* internal use */
1571     tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0);   /* internal use */
1572     tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
1573     tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
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 }
This page took 0.107228 seconds and 4 git commands to generate.