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