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