]> git.proxmox.com Git - mirror_qemu.git/blob - tcg/mips/tcg-target.inc.c
tcg-mips: Add mips64 opcodes
[mirror_qemu.git] / tcg / mips / tcg-target.inc.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 #include "tcg-be-ldst.h"
28
29 #ifdef HOST_WORDS_BIGENDIAN
30 # define MIPS_BE 1
31 #else
32 # define MIPS_BE 0
33 #endif
34
35 #define LO_OFF (MIPS_BE * 4)
36 #define HI_OFF (4 - LO_OFF)
37
38 #ifdef CONFIG_DEBUG_TCG
39 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
40 "zero",
41 "at",
42 "v0",
43 "v1",
44 "a0",
45 "a1",
46 "a2",
47 "a3",
48 "t0",
49 "t1",
50 "t2",
51 "t3",
52 "t4",
53 "t5",
54 "t6",
55 "t7",
56 "s0",
57 "s1",
58 "s2",
59 "s3",
60 "s4",
61 "s5",
62 "s6",
63 "s7",
64 "t8",
65 "t9",
66 "k0",
67 "k1",
68 "gp",
69 "sp",
70 "s8",
71 "ra",
72 };
73 #endif
74
75 #define TCG_TMP0 TCG_REG_AT
76 #define TCG_TMP1 TCG_REG_T9
77 #define TCG_TMP2 TCG_REG_T8
78 #define TCG_TMP3 TCG_REG_T7
79
80 /* check if we really need so many registers :P */
81 static const int tcg_target_reg_alloc_order[] = {
82 /* Call saved registers. */
83 TCG_REG_S0,
84 TCG_REG_S1,
85 TCG_REG_S2,
86 TCG_REG_S3,
87 TCG_REG_S4,
88 TCG_REG_S5,
89 TCG_REG_S6,
90 TCG_REG_S7,
91 TCG_REG_S8,
92
93 /* Call clobbered registers. */
94 TCG_REG_T0,
95 TCG_REG_T1,
96 TCG_REG_T2,
97 TCG_REG_T3,
98 TCG_REG_T4,
99 TCG_REG_T5,
100 TCG_REG_T6,
101 TCG_REG_T7,
102 TCG_REG_T8,
103 TCG_REG_T9,
104 TCG_REG_V1,
105 TCG_REG_V0,
106
107 /* Argument registers, opposite order of allocation. */
108 TCG_REG_A3,
109 TCG_REG_A2,
110 TCG_REG_A1,
111 TCG_REG_A0,
112 };
113
114 static const TCGReg tcg_target_call_iarg_regs[4] = {
115 TCG_REG_A0,
116 TCG_REG_A1,
117 TCG_REG_A2,
118 TCG_REG_A3
119 };
120
121 static const TCGReg tcg_target_call_oarg_regs[2] = {
122 TCG_REG_V0,
123 TCG_REG_V1
124 };
125
126 static tcg_insn_unit *tb_ret_addr;
127 static tcg_insn_unit *bswap32_addr;
128
129 static inline uint32_t reloc_pc16_val(tcg_insn_unit *pc, tcg_insn_unit *target)
130 {
131 /* Let the compiler perform the right-shift as part of the arithmetic. */
132 ptrdiff_t disp = target - (pc + 1);
133 tcg_debug_assert(disp == (int16_t)disp);
134 return disp & 0xffff;
135 }
136
137 static inline void reloc_pc16(tcg_insn_unit *pc, tcg_insn_unit *target)
138 {
139 *pc = deposit32(*pc, 0, 16, reloc_pc16_val(pc, target));
140 }
141
142 static inline uint32_t reloc_26_val(tcg_insn_unit *pc, tcg_insn_unit *target)
143 {
144 tcg_debug_assert((((uintptr_t)pc ^ (uintptr_t)target) & 0xf0000000) == 0);
145 return ((uintptr_t)target >> 2) & 0x3ffffff;
146 }
147
148 static inline void reloc_26(tcg_insn_unit *pc, tcg_insn_unit *target)
149 {
150 *pc = deposit32(*pc, 0, 26, reloc_26_val(pc, target));
151 }
152
153 static void patch_reloc(tcg_insn_unit *code_ptr, int type,
154 intptr_t value, intptr_t addend)
155 {
156 tcg_debug_assert(type == R_MIPS_PC16);
157 tcg_debug_assert(addend == 0);
158 reloc_pc16(code_ptr, (tcg_insn_unit *)value);
159 }
160
161 #define TCG_CT_CONST_ZERO 0x100
162 #define TCG_CT_CONST_U16 0x200 /* Unsigned 16-bit: 0 - 0xffff. */
163 #define TCG_CT_CONST_S16 0x400 /* Signed 16-bit: -32768 - 32767 */
164 #define TCG_CT_CONST_P2M1 0x800 /* Power of 2 minus 1. */
165 #define TCG_CT_CONST_N16 0x1000 /* "Negatable" 16-bit: -32767 - 32767 */
166
167 static inline bool is_p2m1(tcg_target_long val)
168 {
169 return val && ((val + 1) & val) == 0;
170 }
171
172 /* parse target specific constraints */
173 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
174 {
175 const char *ct_str;
176
177 ct_str = *pct_str;
178 switch(ct_str[0]) {
179 case 'r':
180 ct->ct |= TCG_CT_REG;
181 tcg_regset_set(ct->u.regs, 0xffffffff);
182 break;
183 case 'L': /* qemu_ld input arg constraint */
184 ct->ct |= TCG_CT_REG;
185 tcg_regset_set(ct->u.regs, 0xffffffff);
186 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
187 #if defined(CONFIG_SOFTMMU)
188 if (TARGET_LONG_BITS == 64) {
189 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
190 }
191 #endif
192 break;
193 case 'S': /* qemu_st constraint */
194 ct->ct |= TCG_CT_REG;
195 tcg_regset_set(ct->u.regs, 0xffffffff);
196 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
197 #if defined(CONFIG_SOFTMMU)
198 if (TARGET_LONG_BITS == 32) {
199 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
200 } else {
201 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
202 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A3);
203 }
204 #endif
205 break;
206 case 'I':
207 ct->ct |= TCG_CT_CONST_U16;
208 break;
209 case 'J':
210 ct->ct |= TCG_CT_CONST_S16;
211 break;
212 case 'K':
213 ct->ct |= TCG_CT_CONST_P2M1;
214 break;
215 case 'N':
216 ct->ct |= TCG_CT_CONST_N16;
217 break;
218 case 'Z':
219 /* We are cheating a bit here, using the fact that the register
220 ZERO is also the register number 0. Hence there is no need
221 to check for const_args in each instruction. */
222 ct->ct |= TCG_CT_CONST_ZERO;
223 break;
224 default:
225 return -1;
226 }
227 ct_str++;
228 *pct_str = ct_str;
229 return 0;
230 }
231
232 /* test if a constant matches the constraint */
233 static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
234 const TCGArgConstraint *arg_ct)
235 {
236 int ct;
237 ct = arg_ct->ct;
238 if (ct & TCG_CT_CONST) {
239 return 1;
240 } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
241 return 1;
242 } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
243 return 1;
244 } else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
245 return 1;
246 } else if ((ct & TCG_CT_CONST_N16) && val >= -32767 && val <= 32767) {
247 return 1;
248 } else if ((ct & TCG_CT_CONST_P2M1)
249 && use_mips32r2_instructions && is_p2m1(val)) {
250 return 1;
251 }
252 return 0;
253 }
254
255 /* instruction opcodes */
256 typedef enum {
257 OPC_J = 002 << 26,
258 OPC_JAL = 003 << 26,
259 OPC_BEQ = 004 << 26,
260 OPC_BNE = 005 << 26,
261 OPC_BLEZ = 006 << 26,
262 OPC_BGTZ = 007 << 26,
263 OPC_ADDIU = 011 << 26,
264 OPC_SLTI = 012 << 26,
265 OPC_SLTIU = 013 << 26,
266 OPC_ANDI = 014 << 26,
267 OPC_ORI = 015 << 26,
268 OPC_XORI = 016 << 26,
269 OPC_LUI = 017 << 26,
270 OPC_DADDIU = 031 << 26,
271 OPC_LB = 040 << 26,
272 OPC_LH = 041 << 26,
273 OPC_LW = 043 << 26,
274 OPC_LBU = 044 << 26,
275 OPC_LHU = 045 << 26,
276 OPC_LWU = 047 << 26,
277 OPC_SB = 050 << 26,
278 OPC_SH = 051 << 26,
279 OPC_SW = 053 << 26,
280 OPC_LD = 067 << 26,
281 OPC_SD = 077 << 26,
282
283 OPC_SPECIAL = 000 << 26,
284 OPC_SLL = OPC_SPECIAL | 000,
285 OPC_SRL = OPC_SPECIAL | 002,
286 OPC_ROTR = OPC_SPECIAL | 002 | (1 << 21),
287 OPC_SRA = OPC_SPECIAL | 003,
288 OPC_SLLV = OPC_SPECIAL | 004,
289 OPC_SRLV = OPC_SPECIAL | 006,
290 OPC_ROTRV = OPC_SPECIAL | 006 | 0100,
291 OPC_SRAV = OPC_SPECIAL | 007,
292 OPC_JR_R5 = OPC_SPECIAL | 010,
293 OPC_JALR = OPC_SPECIAL | 011,
294 OPC_MOVZ = OPC_SPECIAL | 012,
295 OPC_MOVN = OPC_SPECIAL | 013,
296 OPC_SYNC = OPC_SPECIAL | 017,
297 OPC_MFHI = OPC_SPECIAL | 020,
298 OPC_MFLO = OPC_SPECIAL | 022,
299 OPC_DSLLV = OPC_SPECIAL | 024,
300 OPC_DSRLV = OPC_SPECIAL | 026,
301 OPC_DROTRV = OPC_SPECIAL | 026 | 0100,
302 OPC_DSRAV = OPC_SPECIAL | 027,
303 OPC_MULT = OPC_SPECIAL | 030,
304 OPC_MUL_R6 = OPC_SPECIAL | 030 | 0200,
305 OPC_MUH = OPC_SPECIAL | 030 | 0300,
306 OPC_MULTU = OPC_SPECIAL | 031,
307 OPC_MULU = OPC_SPECIAL | 031 | 0200,
308 OPC_MUHU = OPC_SPECIAL | 031 | 0300,
309 OPC_DIV = OPC_SPECIAL | 032,
310 OPC_DIV_R6 = OPC_SPECIAL | 032 | 0200,
311 OPC_MOD = OPC_SPECIAL | 032 | 0300,
312 OPC_DIVU = OPC_SPECIAL | 033,
313 OPC_DIVU_R6 = OPC_SPECIAL | 033 | 0200,
314 OPC_MODU = OPC_SPECIAL | 033 | 0300,
315 OPC_DMULT = OPC_SPECIAL | 034,
316 OPC_DMUL = OPC_SPECIAL | 034 | 0200,
317 OPC_DMUH = OPC_SPECIAL | 034 | 0300,
318 OPC_DMULTU = OPC_SPECIAL | 035,
319 OPC_DMULU = OPC_SPECIAL | 035 | 0200,
320 OPC_DMUHU = OPC_SPECIAL | 035 | 0300,
321 OPC_DDIV = OPC_SPECIAL | 036,
322 OPC_DDIV_R6 = OPC_SPECIAL | 036 | 0200,
323 OPC_DMOD = OPC_SPECIAL | 036 | 0300,
324 OPC_DDIVU = OPC_SPECIAL | 037,
325 OPC_DDIVU_R6 = OPC_SPECIAL | 037 | 0200,
326 OPC_DMODU = OPC_SPECIAL | 037 | 0300,
327 OPC_ADDU = OPC_SPECIAL | 041,
328 OPC_SUBU = OPC_SPECIAL | 043,
329 OPC_AND = OPC_SPECIAL | 044,
330 OPC_OR = OPC_SPECIAL | 045,
331 OPC_XOR = OPC_SPECIAL | 046,
332 OPC_NOR = OPC_SPECIAL | 047,
333 OPC_SLT = OPC_SPECIAL | 052,
334 OPC_SLTU = OPC_SPECIAL | 053,
335 OPC_DADDU = OPC_SPECIAL | 055,
336 OPC_DSUBU = OPC_SPECIAL | 057,
337 OPC_SELEQZ = OPC_SPECIAL | 065,
338 OPC_SELNEZ = OPC_SPECIAL | 067,
339 OPC_DSLL = OPC_SPECIAL | 070,
340 OPC_DSRL = OPC_SPECIAL | 072,
341 OPC_DROTR = OPC_SPECIAL | 072 | (1 << 21),
342 OPC_DSRA = OPC_SPECIAL | 073,
343 OPC_DSLL32 = OPC_SPECIAL | 074,
344 OPC_DSRL32 = OPC_SPECIAL | 076,
345 OPC_DROTR32 = OPC_SPECIAL | 076 | (1 << 21),
346 OPC_DSRA32 = OPC_SPECIAL | 077,
347
348 OPC_REGIMM = 001 << 26,
349 OPC_BLTZ = OPC_REGIMM | (000 << 16),
350 OPC_BGEZ = OPC_REGIMM | (001 << 16),
351
352 OPC_SPECIAL2 = 034 << 26,
353 OPC_MUL_R5 = OPC_SPECIAL2 | 002,
354
355 OPC_SPECIAL3 = 037 << 26,
356 OPC_EXT = OPC_SPECIAL3 | 000,
357 OPC_DEXTM = OPC_SPECIAL3 | 001,
358 OPC_DEXTU = OPC_SPECIAL3 | 002,
359 OPC_DEXT = OPC_SPECIAL3 | 003,
360 OPC_INS = OPC_SPECIAL3 | 004,
361 OPC_DINSM = OPC_SPECIAL3 | 005,
362 OPC_DINSU = OPC_SPECIAL3 | 006,
363 OPC_DINS = OPC_SPECIAL3 | 007,
364 OPC_WSBH = OPC_SPECIAL3 | 00240,
365 OPC_DSBH = OPC_SPECIAL3 | 00244,
366 OPC_DSHD = OPC_SPECIAL3 | 00544,
367 OPC_SEB = OPC_SPECIAL3 | 02040,
368 OPC_SEH = OPC_SPECIAL3 | 03040,
369
370 /* MIPS r6 doesn't have JR, JALR should be used instead */
371 OPC_JR = use_mips32r6_instructions ? OPC_JALR : OPC_JR_R5,
372
373 /*
374 * MIPS r6 replaces MUL with an alternative encoding which is
375 * backwards-compatible at the assembly level.
376 */
377 OPC_MUL = use_mips32r6_instructions ? OPC_MUL_R6 : OPC_MUL_R5,
378
379 /* MIPS r6 introduced names for weaker variants of SYNC. These are
380 backward compatible to previous architecture revisions. */
381 OPC_SYNC_WMB = OPC_SYNC | 0x04 << 5,
382 OPC_SYNC_MB = OPC_SYNC | 0x10 << 5,
383 OPC_SYNC_ACQUIRE = OPC_SYNC | 0x11 << 5,
384 OPC_SYNC_RELEASE = OPC_SYNC | 0x12 << 5,
385 OPC_SYNC_RMB = OPC_SYNC | 0x13 << 5,
386
387 /* Aliases for convenience. */
388 ALIAS_PADD = sizeof(void *) == 4 ? OPC_ADDU : OPC_DADDU,
389 ALIAS_PADDI = sizeof(void *) == 4 ? OPC_ADDIU : OPC_DADDIU,
390 ALIAS_TSRL = TARGET_LONG_BITS == 32 || TCG_TARGET_REG_BITS == 32
391 ? OPC_SRL : OPC_DSRL,
392 } MIPSInsn;
393
394 /*
395 * Type reg
396 */
397 static inline void tcg_out_opc_reg(TCGContext *s, MIPSInsn opc,
398 TCGReg rd, TCGReg rs, TCGReg rt)
399 {
400 int32_t inst;
401
402 inst = opc;
403 inst |= (rs & 0x1F) << 21;
404 inst |= (rt & 0x1F) << 16;
405 inst |= (rd & 0x1F) << 11;
406 tcg_out32(s, inst);
407 }
408
409 /*
410 * Type immediate
411 */
412 static inline void tcg_out_opc_imm(TCGContext *s, MIPSInsn opc,
413 TCGReg rt, TCGReg rs, TCGArg imm)
414 {
415 int32_t inst;
416
417 inst = opc;
418 inst |= (rs & 0x1F) << 21;
419 inst |= (rt & 0x1F) << 16;
420 inst |= (imm & 0xffff);
421 tcg_out32(s, inst);
422 }
423
424 /*
425 * Type bitfield
426 */
427 static inline void tcg_out_opc_bf(TCGContext *s, MIPSInsn opc, TCGReg rt,
428 TCGReg rs, int msb, int lsb)
429 {
430 int32_t inst;
431
432 inst = opc;
433 inst |= (rs & 0x1F) << 21;
434 inst |= (rt & 0x1F) << 16;
435 inst |= (msb & 0x1F) << 11;
436 inst |= (lsb & 0x1F) << 6;
437 tcg_out32(s, inst);
438 }
439
440 /*
441 * Type branch
442 */
443 static inline void tcg_out_opc_br(TCGContext *s, MIPSInsn opc,
444 TCGReg rt, TCGReg rs)
445 {
446 /* We pay attention here to not modify the branch target by reading
447 the existing value and using it again. This ensure that caches and
448 memory are kept coherent during retranslation. */
449 uint16_t offset = (uint16_t)*s->code_ptr;
450
451 tcg_out_opc_imm(s, opc, rt, rs, offset);
452 }
453
454 /*
455 * Type sa
456 */
457 static inline void tcg_out_opc_sa(TCGContext *s, MIPSInsn opc,
458 TCGReg rd, TCGReg rt, TCGArg sa)
459 {
460 int32_t inst;
461
462 inst = opc;
463 inst |= (rt & 0x1F) << 16;
464 inst |= (rd & 0x1F) << 11;
465 inst |= (sa & 0x1F) << 6;
466 tcg_out32(s, inst);
467
468 }
469
470 /*
471 * Type jump.
472 * Returns true if the branch was in range and the insn was emitted.
473 */
474 static bool tcg_out_opc_jmp(TCGContext *s, MIPSInsn opc, void *target)
475 {
476 uintptr_t dest = (uintptr_t)target;
477 uintptr_t from = (uintptr_t)s->code_ptr + 4;
478 int32_t inst;
479
480 /* The pc-region branch happens within the 256MB region of
481 the delay slot (thus the +4). */
482 if ((from ^ dest) & -(1 << 28)) {
483 return false;
484 }
485 tcg_debug_assert((dest & 3) == 0);
486
487 inst = opc;
488 inst |= (dest >> 2) & 0x3ffffff;
489 tcg_out32(s, inst);
490 return true;
491 }
492
493 static inline void tcg_out_nop(TCGContext *s)
494 {
495 tcg_out32(s, 0);
496 }
497
498 static inline void tcg_out_mov(TCGContext *s, TCGType type,
499 TCGReg ret, TCGReg arg)
500 {
501 /* Simple reg-reg move, optimising out the 'do nothing' case */
502 if (ret != arg) {
503 tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
504 }
505 }
506
507 static inline void tcg_out_movi(TCGContext *s, TCGType type,
508 TCGReg reg, tcg_target_long arg)
509 {
510 if (arg == (int16_t)arg) {
511 tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
512 } else if (arg == (uint16_t)arg) {
513 tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
514 } else {
515 tcg_out_opc_imm(s, OPC_LUI, reg, TCG_REG_ZERO, arg >> 16);
516 if (arg & 0xffff) {
517 tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
518 }
519 }
520 }
521
522 static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
523 {
524 if (use_mips32r2_instructions) {
525 tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
526 } else {
527 /* ret and arg can't be register at */
528 if (ret == TCG_TMP0 || arg == TCG_TMP0) {
529 tcg_abort();
530 }
531
532 tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8);
533 tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
534 tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
535 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
536 }
537 }
538
539 static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
540 {
541 if (use_mips32r2_instructions) {
542 tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
543 tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
544 } else {
545 /* ret and arg can't be register at */
546 if (ret == TCG_TMP0 || arg == TCG_TMP0) {
547 tcg_abort();
548 }
549
550 tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8);
551 tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
552 tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
553 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
554 }
555 }
556
557 static void tcg_out_bswap_subr(TCGContext *s, tcg_insn_unit *sub)
558 {
559 bool ok = tcg_out_opc_jmp(s, OPC_JAL, sub);
560 tcg_debug_assert(ok);
561 }
562
563 static void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
564 {
565 if (use_mips32r2_instructions) {
566 tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
567 tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
568 } else {
569 tcg_out_bswap_subr(s, bswap32_addr);
570 /* delay slot -- never omit the insn, like tcg_out_mov might. */
571 tcg_out_opc_reg(s, OPC_OR, TCG_TMP0, arg, TCG_REG_ZERO);
572 tcg_out_mov(s, TCG_TYPE_I32, ret, TCG_TMP3);
573 }
574 }
575
576 static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
577 {
578 if (use_mips32r2_instructions) {
579 tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
580 } else {
581 tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
582 tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
583 }
584 }
585
586 static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
587 {
588 if (use_mips32r2_instructions) {
589 tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
590 } else {
591 tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
592 tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
593 }
594 }
595
596 static void tcg_out_ldst(TCGContext *s, MIPSInsn opc, TCGReg data,
597 TCGReg addr, intptr_t ofs)
598 {
599 int16_t lo = ofs;
600 if (ofs != lo) {
601 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - lo);
602 if (addr != TCG_REG_ZERO) {
603 tcg_out_opc_reg(s, OPC_ADDU, TCG_TMP0, TCG_TMP0, addr);
604 }
605 addr = TCG_TMP0;
606 }
607 tcg_out_opc_imm(s, opc, data, addr, lo);
608 }
609
610 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
611 TCGReg arg1, intptr_t arg2)
612 {
613 tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
614 }
615
616 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
617 TCGReg arg1, intptr_t arg2)
618 {
619 tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
620 }
621
622 static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
623 TCGReg base, intptr_t ofs)
624 {
625 if (val == 0) {
626 tcg_out_st(s, type, TCG_REG_ZERO, base, ofs);
627 return true;
628 }
629 return false;
630 }
631
632 static inline void tcg_out_addi(TCGContext *s, TCGReg reg, TCGArg val)
633 {
634 if (val == (int16_t)val) {
635 tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
636 } else {
637 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, val);
638 tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_TMP0);
639 }
640 }
641
642 static void tcg_out_addsub2(TCGContext *s, TCGReg rl, TCGReg rh, TCGReg al,
643 TCGReg ah, TCGArg bl, TCGArg bh, bool cbl,
644 bool cbh, bool is_sub)
645 {
646 TCGReg th = TCG_TMP1;
647
648 /* If we have a negative constant such that negating it would
649 make the high part zero, we can (usually) eliminate one insn. */
650 if (cbl && cbh && bh == -1 && bl != 0) {
651 bl = -bl;
652 bh = 0;
653 is_sub = !is_sub;
654 }
655
656 /* By operating on the high part first, we get to use the final
657 carry operation to move back from the temporary. */
658 if (!cbh) {
659 tcg_out_opc_reg(s, (is_sub ? OPC_SUBU : OPC_ADDU), th, ah, bh);
660 } else if (bh != 0 || ah == rl) {
661 tcg_out_opc_imm(s, OPC_ADDIU, th, ah, (is_sub ? -bh : bh));
662 } else {
663 th = ah;
664 }
665
666 /* Note that tcg optimization should eliminate the bl == 0 case. */
667 if (is_sub) {
668 if (cbl) {
669 tcg_out_opc_imm(s, OPC_SLTIU, TCG_TMP0, al, bl);
670 tcg_out_opc_imm(s, OPC_ADDIU, rl, al, -bl);
671 } else {
672 tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP0, al, bl);
673 tcg_out_opc_reg(s, OPC_SUBU, rl, al, bl);
674 }
675 tcg_out_opc_reg(s, OPC_SUBU, rh, th, TCG_TMP0);
676 } else {
677 if (cbl) {
678 tcg_out_opc_imm(s, OPC_ADDIU, rl, al, bl);
679 tcg_out_opc_imm(s, OPC_SLTIU, TCG_TMP0, rl, bl);
680 } else if (rl == al && rl == bl) {
681 tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, al, 31);
682 tcg_out_opc_reg(s, OPC_ADDU, rl, al, bl);
683 } else {
684 tcg_out_opc_reg(s, OPC_ADDU, rl, al, bl);
685 tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP0, rl, (rl == bl ? al : bl));
686 }
687 tcg_out_opc_reg(s, OPC_ADDU, rh, th, TCG_TMP0);
688 }
689 }
690
691 /* Bit 0 set if inversion required; bit 1 set if swapping required. */
692 #define MIPS_CMP_INV 1
693 #define MIPS_CMP_SWAP 2
694
695 static const uint8_t mips_cmp_map[16] = {
696 [TCG_COND_LT] = 0,
697 [TCG_COND_LTU] = 0,
698 [TCG_COND_GE] = MIPS_CMP_INV,
699 [TCG_COND_GEU] = MIPS_CMP_INV,
700 [TCG_COND_LE] = MIPS_CMP_INV | MIPS_CMP_SWAP,
701 [TCG_COND_LEU] = MIPS_CMP_INV | MIPS_CMP_SWAP,
702 [TCG_COND_GT] = MIPS_CMP_SWAP,
703 [TCG_COND_GTU] = MIPS_CMP_SWAP,
704 };
705
706 static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
707 TCGReg arg1, TCGReg arg2)
708 {
709 MIPSInsn s_opc = OPC_SLTU;
710 int cmp_map;
711
712 switch (cond) {
713 case TCG_COND_EQ:
714 if (arg2 != 0) {
715 tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
716 arg1 = ret;
717 }
718 tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
719 break;
720
721 case TCG_COND_NE:
722 if (arg2 != 0) {
723 tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
724 arg1 = ret;
725 }
726 tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
727 break;
728
729 case TCG_COND_LT:
730 case TCG_COND_GE:
731 case TCG_COND_LE:
732 case TCG_COND_GT:
733 s_opc = OPC_SLT;
734 /* FALLTHRU */
735
736 case TCG_COND_LTU:
737 case TCG_COND_GEU:
738 case TCG_COND_LEU:
739 case TCG_COND_GTU:
740 cmp_map = mips_cmp_map[cond];
741 if (cmp_map & MIPS_CMP_SWAP) {
742 TCGReg t = arg1;
743 arg1 = arg2;
744 arg2 = t;
745 }
746 tcg_out_opc_reg(s, s_opc, ret, arg1, arg2);
747 if (cmp_map & MIPS_CMP_INV) {
748 tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
749 }
750 break;
751
752 default:
753 tcg_abort();
754 break;
755 }
756 }
757
758 static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
759 TCGReg arg2, TCGLabel *l)
760 {
761 static const MIPSInsn b_zero[16] = {
762 [TCG_COND_LT] = OPC_BLTZ,
763 [TCG_COND_GT] = OPC_BGTZ,
764 [TCG_COND_LE] = OPC_BLEZ,
765 [TCG_COND_GE] = OPC_BGEZ,
766 };
767
768 MIPSInsn s_opc = OPC_SLTU;
769 MIPSInsn b_opc;
770 int cmp_map;
771
772 switch (cond) {
773 case TCG_COND_EQ:
774 b_opc = OPC_BEQ;
775 break;
776 case TCG_COND_NE:
777 b_opc = OPC_BNE;
778 break;
779
780 case TCG_COND_LT:
781 case TCG_COND_GT:
782 case TCG_COND_LE:
783 case TCG_COND_GE:
784 if (arg2 == 0) {
785 b_opc = b_zero[cond];
786 arg2 = arg1;
787 arg1 = 0;
788 break;
789 }
790 s_opc = OPC_SLT;
791 /* FALLTHRU */
792
793 case TCG_COND_LTU:
794 case TCG_COND_GTU:
795 case TCG_COND_LEU:
796 case TCG_COND_GEU:
797 cmp_map = mips_cmp_map[cond];
798 if (cmp_map & MIPS_CMP_SWAP) {
799 TCGReg t = arg1;
800 arg1 = arg2;
801 arg2 = t;
802 }
803 tcg_out_opc_reg(s, s_opc, TCG_TMP0, arg1, arg2);
804 b_opc = (cmp_map & MIPS_CMP_INV ? OPC_BEQ : OPC_BNE);
805 arg1 = TCG_TMP0;
806 arg2 = TCG_REG_ZERO;
807 break;
808
809 default:
810 tcg_abort();
811 break;
812 }
813
814 tcg_out_opc_br(s, b_opc, arg1, arg2);
815 if (l->has_value) {
816 reloc_pc16(s->code_ptr - 1, l->u.value_ptr);
817 } else {
818 tcg_out_reloc(s, s->code_ptr - 1, R_MIPS_PC16, l, 0);
819 }
820 tcg_out_nop(s);
821 }
822
823 static TCGReg tcg_out_reduce_eq2(TCGContext *s, TCGReg tmp0, TCGReg tmp1,
824 TCGReg al, TCGReg ah,
825 TCGReg bl, TCGReg bh)
826 {
827 /* Merge highpart comparison into AH. */
828 if (bh != 0) {
829 if (ah != 0) {
830 tcg_out_opc_reg(s, OPC_XOR, tmp0, ah, bh);
831 ah = tmp0;
832 } else {
833 ah = bh;
834 }
835 }
836 /* Merge lowpart comparison into AL. */
837 if (bl != 0) {
838 if (al != 0) {
839 tcg_out_opc_reg(s, OPC_XOR, tmp1, al, bl);
840 al = tmp1;
841 } else {
842 al = bl;
843 }
844 }
845 /* Merge high and low part comparisons into AL. */
846 if (ah != 0) {
847 if (al != 0) {
848 tcg_out_opc_reg(s, OPC_OR, tmp0, ah, al);
849 al = tmp0;
850 } else {
851 al = ah;
852 }
853 }
854 return al;
855 }
856
857 static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
858 TCGReg al, TCGReg ah, TCGReg bl, TCGReg bh)
859 {
860 TCGReg tmp0 = TCG_TMP0;
861 TCGReg tmp1 = ret;
862
863 tcg_debug_assert(ret != TCG_TMP0);
864 if (ret == ah || ret == bh) {
865 tcg_debug_assert(ret != TCG_TMP1);
866 tmp1 = TCG_TMP1;
867 }
868
869 switch (cond) {
870 case TCG_COND_EQ:
871 case TCG_COND_NE:
872 tmp1 = tcg_out_reduce_eq2(s, tmp0, tmp1, al, ah, bl, bh);
873 tcg_out_setcond(s, cond, ret, tmp1, TCG_REG_ZERO);
874 break;
875
876 default:
877 tcg_out_setcond(s, TCG_COND_EQ, tmp0, ah, bh);
878 tcg_out_setcond(s, tcg_unsigned_cond(cond), tmp1, al, bl);
879 tcg_out_opc_reg(s, OPC_AND, tmp1, tmp1, tmp0);
880 tcg_out_setcond(s, tcg_high_cond(cond), tmp0, ah, bh);
881 tcg_out_opc_reg(s, OPC_OR, ret, tmp1, tmp0);
882 break;
883 }
884 }
885
886 static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
887 TCGReg bl, TCGReg bh, TCGLabel *l)
888 {
889 TCGCond b_cond = TCG_COND_NE;
890 TCGReg tmp = TCG_TMP1;
891
892 /* With branches, we emit between 4 and 9 insns with 2 or 3 branches.
893 With setcond, we emit between 3 and 10 insns and only 1 branch,
894 which ought to get better branch prediction. */
895 switch (cond) {
896 case TCG_COND_EQ:
897 case TCG_COND_NE:
898 b_cond = cond;
899 tmp = tcg_out_reduce_eq2(s, TCG_TMP0, TCG_TMP1, al, ah, bl, bh);
900 break;
901
902 default:
903 /* Minimize code size by preferring a compare not requiring INV. */
904 if (mips_cmp_map[cond] & MIPS_CMP_INV) {
905 cond = tcg_invert_cond(cond);
906 b_cond = TCG_COND_EQ;
907 }
908 tcg_out_setcond2(s, cond, tmp, al, ah, bl, bh);
909 break;
910 }
911
912 tcg_out_brcond(s, b_cond, tmp, TCG_REG_ZERO, l);
913 }
914
915 static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
916 TCGReg c1, TCGReg c2, TCGReg v1, TCGReg v2)
917 {
918 bool eqz = false;
919
920 /* If one of the values is zero, put it last to match SEL*Z instructions */
921 if (use_mips32r6_instructions && v1 == 0) {
922 v1 = v2;
923 v2 = 0;
924 cond = tcg_invert_cond(cond);
925 }
926
927 switch (cond) {
928 case TCG_COND_EQ:
929 eqz = true;
930 /* FALLTHRU */
931 case TCG_COND_NE:
932 if (c2 != 0) {
933 tcg_out_opc_reg(s, OPC_XOR, TCG_TMP0, c1, c2);
934 c1 = TCG_TMP0;
935 }
936 break;
937
938 default:
939 /* Minimize code size by preferring a compare not requiring INV. */
940 if (mips_cmp_map[cond] & MIPS_CMP_INV) {
941 cond = tcg_invert_cond(cond);
942 eqz = true;
943 }
944 tcg_out_setcond(s, cond, TCG_TMP0, c1, c2);
945 c1 = TCG_TMP0;
946 break;
947 }
948
949 if (use_mips32r6_instructions) {
950 MIPSInsn m_opc_t = eqz ? OPC_SELEQZ : OPC_SELNEZ;
951 MIPSInsn m_opc_f = eqz ? OPC_SELNEZ : OPC_SELEQZ;
952
953 if (v2 != 0) {
954 tcg_out_opc_reg(s, m_opc_f, TCG_TMP1, v2, c1);
955 }
956 tcg_out_opc_reg(s, m_opc_t, ret, v1, c1);
957 if (v2 != 0) {
958 tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP1);
959 }
960 } else {
961 MIPSInsn m_opc = eqz ? OPC_MOVZ : OPC_MOVN;
962
963 tcg_out_opc_reg(s, m_opc, ret, v1, c1);
964
965 /* This should be guaranteed via constraints */
966 tcg_debug_assert(v2 == ret);
967 }
968 }
969
970 static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail)
971 {
972 /* Note that the ABI requires the called function's address to be
973 loaded into T9, even if a direct branch is in range. */
974 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T9, (uintptr_t)arg);
975
976 /* But do try a direct branch, allowing the cpu better insn prefetch. */
977 if (tail) {
978 if (!tcg_out_opc_jmp(s, OPC_J, arg)) {
979 tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_T9, 0);
980 }
981 } else {
982 if (!tcg_out_opc_jmp(s, OPC_JAL, arg)) {
983 tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
984 }
985 }
986 }
987
988 static void tcg_out_call(TCGContext *s, tcg_insn_unit *arg)
989 {
990 tcg_out_call_int(s, arg, false);
991 tcg_out_nop(s);
992 }
993
994 #if defined(CONFIG_SOFTMMU)
995 static void * const qemu_ld_helpers[16] = {
996 [MO_UB] = helper_ret_ldub_mmu,
997 [MO_SB] = helper_ret_ldsb_mmu,
998 [MO_LEUW] = helper_le_lduw_mmu,
999 [MO_LESW] = helper_le_ldsw_mmu,
1000 [MO_LEUL] = helper_le_ldul_mmu,
1001 [MO_LEQ] = helper_le_ldq_mmu,
1002 [MO_BEUW] = helper_be_lduw_mmu,
1003 [MO_BESW] = helper_be_ldsw_mmu,
1004 [MO_BEUL] = helper_be_ldul_mmu,
1005 [MO_BEQ] = helper_be_ldq_mmu,
1006 };
1007
1008 static void * const qemu_st_helpers[16] = {
1009 [MO_UB] = helper_ret_stb_mmu,
1010 [MO_LEUW] = helper_le_stw_mmu,
1011 [MO_LEUL] = helper_le_stl_mmu,
1012 [MO_LEQ] = helper_le_stq_mmu,
1013 [MO_BEUW] = helper_be_stw_mmu,
1014 [MO_BEUL] = helper_be_stl_mmu,
1015 [MO_BEQ] = helper_be_stq_mmu,
1016 };
1017
1018 /* Helper routines for marshalling helper function arguments into
1019 * the correct registers and stack.
1020 * I is where we want to put this argument, and is updated and returned
1021 * for the next call. ARG is the argument itself.
1022 *
1023 * We provide routines for arguments which are: immediate, 32 bit
1024 * value in register, 16 and 8 bit values in register (which must be zero
1025 * extended before use) and 64 bit value in a lo:hi register pair.
1026 */
1027
1028 static int tcg_out_call_iarg_reg(TCGContext *s, int i, TCGReg arg)
1029 {
1030 if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
1031 tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[i], arg);
1032 } else {
1033 tcg_out_st(s, TCG_TYPE_REG, arg, TCG_REG_SP, 4 * i);
1034 }
1035 return i + 1;
1036 }
1037
1038 static int tcg_out_call_iarg_reg8(TCGContext *s, int i, TCGReg arg)
1039 {
1040 TCGReg tmp = TCG_TMP0;
1041 if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
1042 tmp = tcg_target_call_iarg_regs[i];
1043 }
1044 tcg_out_opc_imm(s, OPC_ANDI, tmp, arg, 0xff);
1045 return tcg_out_call_iarg_reg(s, i, tmp);
1046 }
1047
1048 static int tcg_out_call_iarg_reg16(TCGContext *s, int i, TCGReg arg)
1049 {
1050 TCGReg tmp = TCG_TMP0;
1051 if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
1052 tmp = tcg_target_call_iarg_regs[i];
1053 }
1054 tcg_out_opc_imm(s, OPC_ANDI, tmp, arg, 0xffff);
1055 return tcg_out_call_iarg_reg(s, i, tmp);
1056 }
1057
1058 static int tcg_out_call_iarg_imm(TCGContext *s, int i, TCGArg arg)
1059 {
1060 TCGReg tmp = TCG_TMP0;
1061 if (arg == 0) {
1062 tmp = TCG_REG_ZERO;
1063 } else {
1064 if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
1065 tmp = tcg_target_call_iarg_regs[i];
1066 }
1067 tcg_out_movi(s, TCG_TYPE_REG, tmp, arg);
1068 }
1069 return tcg_out_call_iarg_reg(s, i, tmp);
1070 }
1071
1072 static int tcg_out_call_iarg_reg2(TCGContext *s, int i, TCGReg al, TCGReg ah)
1073 {
1074 i = (i + 1) & ~1;
1075 i = tcg_out_call_iarg_reg(s, i, (MIPS_BE ? ah : al));
1076 i = tcg_out_call_iarg_reg(s, i, (MIPS_BE ? al : ah));
1077 return i;
1078 }
1079
1080 /* Perform the tlb comparison operation. The complete host address is
1081 placed in BASE. Clobbers TMP0, TMP1, A0. */
1082 static void tcg_out_tlb_load(TCGContext *s, TCGReg base, TCGReg addrl,
1083 TCGReg addrh, TCGMemOpIdx oi,
1084 tcg_insn_unit *label_ptr[2], bool is_load)
1085 {
1086 TCGMemOp opc = get_memop(oi);
1087 unsigned s_bits = opc & MO_SIZE;
1088 unsigned a_bits = get_alignment_bits(opc);
1089 int mem_index = get_mmuidx(oi);
1090 int cmp_off
1091 = (is_load
1092 ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
1093 : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
1094 int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
1095
1096 tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addrl,
1097 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1098 tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0,
1099 (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1100 tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1101
1102 /* Compensate for very large offsets. */
1103 if (add_off >= 0x8000) {
1104 /* Most target env are smaller than 32k; none are larger than 64k.
1105 Simplify the logic here merely to offset by 0x7ff0, giving us a
1106 range just shy of 64k. Check this assumption. */
1107 QEMU_BUILD_BUG_ON(offsetof(CPUArchState,
1108 tlb_table[NB_MMU_MODES - 1][1])
1109 > 0x7ff0 + 0x7fff);
1110 tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, TCG_REG_A0, 0x7ff0);
1111 cmp_off -= 0x7ff0;
1112 add_off -= 0x7ff0;
1113 }
1114
1115 /* Load the (low half) tlb comparator. */
1116 tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, TCG_REG_A0,
1117 cmp_off + (TARGET_LONG_BITS == 64 ? LO_OFF : 0));
1118
1119 /* We don't currently support unaligned accesses.
1120 We could do so with mips32r6. */
1121 if (a_bits < s_bits) {
1122 a_bits = s_bits;
1123 }
1124 /* Mask the page bits, keeping the alignment bits to compare against.
1125 In between on 32-bit targets, load the tlb addend for the fast path. */
1126 tcg_out_movi(s, TCG_TYPE_I32, TCG_TMP1,
1127 TARGET_PAGE_MASK | ((1 << a_bits) - 1));
1128 if (TARGET_LONG_BITS == 32) {
1129 tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0, add_off);
1130 }
1131 tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, addrl);
1132
1133 label_ptr[0] = s->code_ptr;
1134 tcg_out_opc_br(s, OPC_BNE, TCG_TMP1, TCG_TMP0);
1135
1136 /* Load and test the high half tlb comparator. */
1137 if (TARGET_LONG_BITS == 64) {
1138 /* delay slot */
1139 tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, TCG_REG_A0, cmp_off + HI_OFF);
1140
1141 /* Load the tlb addend for the fast path. We can't do it earlier with
1142 64-bit targets or we'll clobber a0 before reading the high half tlb
1143 comparator. */
1144 tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0, add_off);
1145
1146 label_ptr[1] = s->code_ptr;
1147 tcg_out_opc_br(s, OPC_BNE, addrh, TCG_TMP0);
1148 }
1149
1150 /* delay slot */
1151 tcg_out_opc_reg(s, OPC_ADDU, base, TCG_REG_A0, addrl);
1152 }
1153
1154 static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi,
1155 TCGReg datalo, TCGReg datahi,
1156 TCGReg addrlo, TCGReg addrhi,
1157 void *raddr, tcg_insn_unit *label_ptr[2])
1158 {
1159 TCGLabelQemuLdst *label = new_ldst_label(s);
1160
1161 label->is_ld = is_ld;
1162 label->oi = oi;
1163 label->datalo_reg = datalo;
1164 label->datahi_reg = datahi;
1165 label->addrlo_reg = addrlo;
1166 label->addrhi_reg = addrhi;
1167 label->raddr = raddr;
1168 label->label_ptr[0] = label_ptr[0];
1169 if (TARGET_LONG_BITS == 64) {
1170 label->label_ptr[1] = label_ptr[1];
1171 }
1172 }
1173
1174 static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1175 {
1176 TCGMemOpIdx oi = l->oi;
1177 TCGMemOp opc = get_memop(oi);
1178 TCGReg v0;
1179 int i;
1180
1181 /* resolve label address */
1182 reloc_pc16(l->label_ptr[0], s->code_ptr);
1183 if (TARGET_LONG_BITS == 64) {
1184 reloc_pc16(l->label_ptr[1], s->code_ptr);
1185 }
1186
1187 i = 1;
1188 if (TARGET_LONG_BITS == 64) {
1189 i = tcg_out_call_iarg_reg2(s, i, l->addrlo_reg, l->addrhi_reg);
1190 } else {
1191 i = tcg_out_call_iarg_reg(s, i, l->addrlo_reg);
1192 }
1193 i = tcg_out_call_iarg_imm(s, i, oi);
1194 i = tcg_out_call_iarg_imm(s, i, (intptr_t)l->raddr);
1195 tcg_out_call_int(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)], false);
1196 /* delay slot */
1197 tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
1198
1199 v0 = l->datalo_reg;
1200 if ((opc & MO_SIZE) == MO_64) {
1201 /* We eliminated V0 from the possible output registers, so it
1202 cannot be clobbered here. So we must move V1 first. */
1203 if (MIPS_BE) {
1204 tcg_out_mov(s, TCG_TYPE_I32, v0, TCG_REG_V1);
1205 v0 = l->datahi_reg;
1206 } else {
1207 tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_V1);
1208 }
1209 }
1210
1211 reloc_pc16(s->code_ptr, l->raddr);
1212 tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1213 /* delay slot */
1214 tcg_out_mov(s, TCG_TYPE_REG, v0, TCG_REG_V0);
1215 }
1216
1217 static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1218 {
1219 TCGMemOpIdx oi = l->oi;
1220 TCGMemOp opc = get_memop(oi);
1221 TCGMemOp s_bits = opc & MO_SIZE;
1222 int i;
1223
1224 /* resolve label address */
1225 reloc_pc16(l->label_ptr[0], s->code_ptr);
1226 if (TARGET_LONG_BITS == 64) {
1227 reloc_pc16(l->label_ptr[1], s->code_ptr);
1228 }
1229
1230 i = 1;
1231 if (TARGET_LONG_BITS == 64) {
1232 i = tcg_out_call_iarg_reg2(s, i, l->addrlo_reg, l->addrhi_reg);
1233 } else {
1234 i = tcg_out_call_iarg_reg(s, i, l->addrlo_reg);
1235 }
1236 switch (s_bits) {
1237 case MO_8:
1238 i = tcg_out_call_iarg_reg8(s, i, l->datalo_reg);
1239 break;
1240 case MO_16:
1241 i = tcg_out_call_iarg_reg16(s, i, l->datalo_reg);
1242 break;
1243 case MO_32:
1244 i = tcg_out_call_iarg_reg(s, i, l->datalo_reg);
1245 break;
1246 case MO_64:
1247 i = tcg_out_call_iarg_reg2(s, i, l->datalo_reg, l->datahi_reg);
1248 break;
1249 default:
1250 tcg_abort();
1251 }
1252 i = tcg_out_call_iarg_imm(s, i, oi);
1253
1254 /* Tail call to the store helper. Thus force the return address
1255 computation to take place in the return address register. */
1256 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (intptr_t)l->raddr);
1257 i = tcg_out_call_iarg_reg(s, i, TCG_REG_RA);
1258 tcg_out_call_int(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)], true);
1259 /* delay slot */
1260 tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
1261 }
1262 #endif
1263
1264 static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi,
1265 TCGReg base, TCGMemOp opc)
1266 {
1267 switch (opc & (MO_SSIZE | MO_BSWAP)) {
1268 case MO_UB:
1269 tcg_out_opc_imm(s, OPC_LBU, lo, base, 0);
1270 break;
1271 case MO_SB:
1272 tcg_out_opc_imm(s, OPC_LB, lo, base, 0);
1273 break;
1274 case MO_UW | MO_BSWAP:
1275 tcg_out_opc_imm(s, OPC_LHU, TCG_TMP1, base, 0);
1276 tcg_out_bswap16(s, lo, TCG_TMP1);
1277 break;
1278 case MO_UW:
1279 tcg_out_opc_imm(s, OPC_LHU, lo, base, 0);
1280 break;
1281 case MO_SW | MO_BSWAP:
1282 tcg_out_opc_imm(s, OPC_LHU, TCG_TMP1, base, 0);
1283 tcg_out_bswap16s(s, lo, TCG_TMP1);
1284 break;
1285 case MO_SW:
1286 tcg_out_opc_imm(s, OPC_LH, lo, base, 0);
1287 break;
1288 case MO_UL | MO_BSWAP:
1289 if (use_mips32r2_instructions) {
1290 tcg_out_opc_imm(s, OPC_LW, lo, base, 0);
1291 tcg_out_bswap32(s, lo, lo);
1292 } else {
1293 tcg_out_bswap_subr(s, bswap32_addr);
1294 /* delay slot */
1295 tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, base, 0);
1296 tcg_out_mov(s, TCG_TYPE_I32, lo, TCG_TMP3);
1297 }
1298 break;
1299 case MO_UL:
1300 tcg_out_opc_imm(s, OPC_LW, lo, base, 0);
1301 break;
1302 case MO_Q | MO_BSWAP:
1303 if (use_mips32r2_instructions) {
1304 tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, base, 0);
1305 tcg_out_opc_imm(s, OPC_LW, TCG_TMP1, base, 4);
1306 tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP0, 0, TCG_TMP0);
1307 tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP1, 0, TCG_TMP1);
1308 tcg_out_opc_sa(s, OPC_ROTR, MIPS_BE ? lo : hi, TCG_TMP0, 16);
1309 tcg_out_opc_sa(s, OPC_ROTR, MIPS_BE ? hi : lo, TCG_TMP1, 16);
1310 } else {
1311 tcg_out_bswap_subr(s, bswap32_addr);
1312 /* delay slot */
1313 tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, base, 0);
1314 tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, base, 4);
1315 tcg_out_bswap_subr(s, bswap32_addr);
1316 /* delay slot */
1317 tcg_out_mov(s, TCG_TYPE_I32, MIPS_BE ? lo : hi, TCG_TMP3);
1318 tcg_out_mov(s, TCG_TYPE_I32, MIPS_BE ? hi : lo, TCG_TMP3);
1319 }
1320 break;
1321 case MO_Q:
1322 /* Prefer to load from offset 0 first, but allow for overlap. */
1323 if (MIPS_BE ? hi != base : lo == base) {
1324 tcg_out_opc_imm(s, OPC_LW, hi, base, HI_OFF);
1325 tcg_out_opc_imm(s, OPC_LW, lo, base, LO_OFF);
1326 } else {
1327 tcg_out_opc_imm(s, OPC_LW, lo, base, LO_OFF);
1328 tcg_out_opc_imm(s, OPC_LW, hi, base, HI_OFF);
1329 }
1330 break;
1331 default:
1332 tcg_abort();
1333 }
1334 }
1335
1336 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
1337 {
1338 TCGReg addr_regl, addr_regh __attribute__((unused));
1339 TCGReg data_regl, data_regh;
1340 TCGMemOpIdx oi;
1341 TCGMemOp opc;
1342 #if defined(CONFIG_SOFTMMU)
1343 tcg_insn_unit *label_ptr[2];
1344 #endif
1345 TCGReg base = TCG_REG_A0;
1346
1347 data_regl = *args++;
1348 data_regh = (is_64 ? *args++ : 0);
1349 addr_regl = *args++;
1350 addr_regh = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1351 oi = *args++;
1352 opc = get_memop(oi);
1353
1354 #if defined(CONFIG_SOFTMMU)
1355 tcg_out_tlb_load(s, base, addr_regl, addr_regh, oi, label_ptr, 1);
1356 tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc);
1357 add_qemu_ldst_label(s, 1, oi, data_regl, data_regh, addr_regl, addr_regh,
1358 s->code_ptr, label_ptr);
1359 #else
1360 if (guest_base == 0 && data_regl != addr_regl) {
1361 base = addr_regl;
1362 } else if (guest_base == (int16_t)guest_base) {
1363 tcg_out_opc_imm(s, OPC_ADDIU, base, addr_regl, guest_base);
1364 } else {
1365 tcg_out_movi(s, TCG_TYPE_PTR, base, guest_base);
1366 tcg_out_opc_reg(s, OPC_ADDU, base, base, addr_regl);
1367 }
1368 tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc);
1369 #endif
1370 }
1371
1372 static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg lo, TCGReg hi,
1373 TCGReg base, TCGMemOp opc)
1374 {
1375 /* Don't clutter the code below with checks to avoid bswapping ZERO. */
1376 if ((lo | hi) == 0) {
1377 opc &= ~MO_BSWAP;
1378 }
1379
1380 switch (opc & (MO_SIZE | MO_BSWAP)) {
1381 case MO_8:
1382 tcg_out_opc_imm(s, OPC_SB, lo, base, 0);
1383 break;
1384
1385 case MO_16 | MO_BSWAP:
1386 tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, lo, 0xffff);
1387 tcg_out_bswap16(s, TCG_TMP1, TCG_TMP1);
1388 lo = TCG_TMP1;
1389 /* FALLTHRU */
1390 case MO_16:
1391 tcg_out_opc_imm(s, OPC_SH, lo, base, 0);
1392 break;
1393
1394 case MO_32 | MO_BSWAP:
1395 tcg_out_bswap32(s, TCG_TMP3, lo);
1396 lo = TCG_TMP3;
1397 /* FALLTHRU */
1398 case MO_32:
1399 tcg_out_opc_imm(s, OPC_SW, lo, base, 0);
1400 break;
1401
1402 case MO_64 | MO_BSWAP:
1403 if (use_mips32r2_instructions) {
1404 tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP0, 0, MIPS_BE ? lo : hi);
1405 tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP1, 0, MIPS_BE ? hi : lo);
1406 tcg_out_opc_sa(s, OPC_ROTR, TCG_TMP0, TCG_TMP0, 16);
1407 tcg_out_opc_sa(s, OPC_ROTR, TCG_TMP1, TCG_TMP1, 16);
1408 tcg_out_opc_imm(s, OPC_SW, TCG_TMP0, base, 0);
1409 tcg_out_opc_imm(s, OPC_SW, TCG_TMP1, base, 4);
1410 } else {
1411 tcg_out_bswap32(s, TCG_TMP3, MIPS_BE ? lo : hi);
1412 tcg_out_opc_imm(s, OPC_SW, TCG_TMP3, base, 0);
1413 tcg_out_bswap32(s, TCG_TMP3, MIPS_BE ? hi : lo);
1414 tcg_out_opc_imm(s, OPC_SW, TCG_TMP3, base, 4);
1415 }
1416 break;
1417 case MO_64:
1418 tcg_out_opc_imm(s, OPC_SW, MIPS_BE ? hi : lo, base, 0);
1419 tcg_out_opc_imm(s, OPC_SW, MIPS_BE ? lo : hi, base, 4);
1420 break;
1421
1422 default:
1423 tcg_abort();
1424 }
1425 }
1426
1427 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
1428 {
1429 TCGReg addr_regl, addr_regh __attribute__((unused));
1430 TCGReg data_regl, data_regh;
1431 TCGMemOpIdx oi;
1432 TCGMemOp opc;
1433 #if defined(CONFIG_SOFTMMU)
1434 tcg_insn_unit *label_ptr[2];
1435 #endif
1436 TCGReg base = TCG_REG_A0;
1437
1438 data_regl = *args++;
1439 data_regh = (is_64 ? *args++ : 0);
1440 addr_regl = *args++;
1441 addr_regh = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1442 oi = *args++;
1443 opc = get_memop(oi);
1444
1445 #if defined(CONFIG_SOFTMMU)
1446 tcg_out_tlb_load(s, base, addr_regl, addr_regh, oi, label_ptr, 0);
1447 tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
1448 add_qemu_ldst_label(s, 0, oi, data_regl, data_regh, addr_regl, addr_regh,
1449 s->code_ptr, label_ptr);
1450 #else
1451 if (guest_base == 0) {
1452 base = addr_regl;
1453 } else {
1454 if (guest_base == (int16_t)guest_base) {
1455 tcg_out_opc_imm(s, OPC_ADDIU, base, addr_regl, guest_base);
1456 } else {
1457 tcg_out_movi(s, TCG_TYPE_PTR, base, guest_base);
1458 tcg_out_opc_reg(s, OPC_ADDU, base, base, addr_regl);
1459 }
1460 }
1461 tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
1462 #endif
1463 }
1464
1465 static void tcg_out_mb(TCGContext *s, TCGArg a0)
1466 {
1467 static const MIPSInsn sync[] = {
1468 /* Note that SYNC_MB is a slightly weaker than SYNC 0,
1469 as the former is an ordering barrier and the latter
1470 is a completion barrier. */
1471 [0 ... TCG_MO_ALL] = OPC_SYNC_MB,
1472 [TCG_MO_LD_LD] = OPC_SYNC_RMB,
1473 [TCG_MO_ST_ST] = OPC_SYNC_WMB,
1474 [TCG_MO_LD_ST] = OPC_SYNC_RELEASE,
1475 [TCG_MO_LD_ST | TCG_MO_ST_ST] = OPC_SYNC_RELEASE,
1476 [TCG_MO_LD_ST | TCG_MO_LD_LD] = OPC_SYNC_ACQUIRE,
1477 };
1478 tcg_out32(s, sync[a0 & TCG_MO_ALL]);
1479 }
1480
1481 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1482 const TCGArg *args, const int *const_args)
1483 {
1484 MIPSInsn i1, i2;
1485 TCGArg a0, a1, a2;
1486 int c2;
1487
1488 a0 = args[0];
1489 a1 = args[1];
1490 a2 = args[2];
1491 c2 = const_args[2];
1492
1493 switch (opc) {
1494 case INDEX_op_exit_tb:
1495 {
1496 TCGReg b0 = TCG_REG_ZERO;
1497
1498 if (a0 & ~0xffff) {
1499 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, a0 & ~0xffff);
1500 b0 = TCG_REG_V0;
1501 }
1502 if (!tcg_out_opc_jmp(s, OPC_J, tb_ret_addr)) {
1503 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0,
1504 (uintptr_t)tb_ret_addr);
1505 tcg_out_opc_reg(s, OPC_JR, 0, TCG_TMP0, 0);
1506 }
1507 tcg_out_opc_imm(s, OPC_ORI, TCG_REG_V0, b0, a0 & 0xffff);
1508 }
1509 break;
1510 case INDEX_op_goto_tb:
1511 if (s->tb_jmp_insn_offset) {
1512 /* direct jump method */
1513 s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
1514 /* Avoid clobbering the address during retranslation. */
1515 tcg_out32(s, OPC_J | (*(uint32_t *)s->code_ptr & 0x3ffffff));
1516 } else {
1517 /* indirect jump method */
1518 tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_REG_ZERO,
1519 (uintptr_t)(s->tb_jmp_target_addr + a0));
1520 tcg_out_opc_reg(s, OPC_JR, 0, TCG_TMP0, 0);
1521 }
1522 tcg_out_nop(s);
1523 s->tb_jmp_reset_offset[a0] = tcg_current_code_size(s);
1524 break;
1525 case INDEX_op_br:
1526 tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO,
1527 arg_label(a0));
1528 break;
1529
1530 case INDEX_op_ld8u_i32:
1531 i1 = OPC_LBU;
1532 goto do_ldst;
1533 case INDEX_op_ld8s_i32:
1534 i1 = OPC_LB;
1535 goto do_ldst;
1536 case INDEX_op_ld16u_i32:
1537 i1 = OPC_LHU;
1538 goto do_ldst;
1539 case INDEX_op_ld16s_i32:
1540 i1 = OPC_LH;
1541 goto do_ldst;
1542 case INDEX_op_ld_i32:
1543 i1 = OPC_LW;
1544 goto do_ldst;
1545 case INDEX_op_st8_i32:
1546 i1 = OPC_SB;
1547 goto do_ldst;
1548 case INDEX_op_st16_i32:
1549 i1 = OPC_SH;
1550 goto do_ldst;
1551 case INDEX_op_st_i32:
1552 i1 = OPC_SW;
1553 do_ldst:
1554 tcg_out_ldst(s, i1, a0, a1, a2);
1555 break;
1556
1557 case INDEX_op_add_i32:
1558 i1 = OPC_ADDU, i2 = OPC_ADDIU;
1559 goto do_binary;
1560 case INDEX_op_or_i32:
1561 i1 = OPC_OR, i2 = OPC_ORI;
1562 goto do_binary;
1563 case INDEX_op_xor_i32:
1564 i1 = OPC_XOR, i2 = OPC_XORI;
1565 do_binary:
1566 if (c2) {
1567 tcg_out_opc_imm(s, i2, a0, a1, a2);
1568 break;
1569 }
1570 do_binaryv:
1571 tcg_out_opc_reg(s, i1, a0, a1, a2);
1572 break;
1573
1574 case INDEX_op_sub_i32:
1575 if (c2) {
1576 tcg_out_opc_imm(s, OPC_ADDIU, a0, a1, -a2);
1577 break;
1578 }
1579 i1 = OPC_SUBU;
1580 goto do_binary;
1581 case INDEX_op_and_i32:
1582 if (c2 && a2 != (uint16_t)a2) {
1583 int msb = ctz32(~a2) - 1;
1584 tcg_debug_assert(use_mips32r2_instructions);
1585 tcg_debug_assert(is_p2m1(a2));
1586 tcg_out_opc_bf(s, OPC_EXT, a0, a1, msb, 0);
1587 break;
1588 }
1589 i1 = OPC_AND, i2 = OPC_ANDI;
1590 goto do_binary;
1591 case INDEX_op_nor_i32:
1592 i1 = OPC_NOR;
1593 goto do_binaryv;
1594
1595 case INDEX_op_mul_i32:
1596 if (use_mips32_instructions) {
1597 tcg_out_opc_reg(s, OPC_MUL, a0, a1, a2);
1598 break;
1599 }
1600 i1 = OPC_MULT, i2 = OPC_MFLO;
1601 goto do_hilo1;
1602 case INDEX_op_mulsh_i32:
1603 if (use_mips32r6_instructions) {
1604 tcg_out_opc_reg(s, OPC_MUH, a0, a1, a2);
1605 break;
1606 }
1607 i1 = OPC_MULT, i2 = OPC_MFHI;
1608 goto do_hilo1;
1609 case INDEX_op_muluh_i32:
1610 if (use_mips32r6_instructions) {
1611 tcg_out_opc_reg(s, OPC_MUHU, a0, a1, a2);
1612 break;
1613 }
1614 i1 = OPC_MULTU, i2 = OPC_MFHI;
1615 goto do_hilo1;
1616 case INDEX_op_div_i32:
1617 if (use_mips32r6_instructions) {
1618 tcg_out_opc_reg(s, OPC_DIV_R6, a0, a1, a2);
1619 break;
1620 }
1621 i1 = OPC_DIV, i2 = OPC_MFLO;
1622 goto do_hilo1;
1623 case INDEX_op_divu_i32:
1624 if (use_mips32r6_instructions) {
1625 tcg_out_opc_reg(s, OPC_DIVU_R6, a0, a1, a2);
1626 break;
1627 }
1628 i1 = OPC_DIVU, i2 = OPC_MFLO;
1629 goto do_hilo1;
1630 case INDEX_op_rem_i32:
1631 if (use_mips32r6_instructions) {
1632 tcg_out_opc_reg(s, OPC_MOD, a0, a1, a2);
1633 break;
1634 }
1635 i1 = OPC_DIV, i2 = OPC_MFHI;
1636 goto do_hilo1;
1637 case INDEX_op_remu_i32:
1638 if (use_mips32r6_instructions) {
1639 tcg_out_opc_reg(s, OPC_MODU, a0, a1, a2);
1640 break;
1641 }
1642 i1 = OPC_DIVU, i2 = OPC_MFHI;
1643 do_hilo1:
1644 tcg_out_opc_reg(s, i1, 0, a1, a2);
1645 tcg_out_opc_reg(s, i2, a0, 0, 0);
1646 break;
1647
1648 case INDEX_op_muls2_i32:
1649 i1 = OPC_MULT;
1650 goto do_hilo2;
1651 case INDEX_op_mulu2_i32:
1652 i1 = OPC_MULTU;
1653 do_hilo2:
1654 tcg_out_opc_reg(s, i1, 0, a2, args[3]);
1655 tcg_out_opc_reg(s, OPC_MFLO, a0, 0, 0);
1656 tcg_out_opc_reg(s, OPC_MFHI, a1, 0, 0);
1657 break;
1658
1659 case INDEX_op_not_i32:
1660 i1 = OPC_NOR;
1661 goto do_unary;
1662 case INDEX_op_bswap16_i32:
1663 i1 = OPC_WSBH;
1664 goto do_unary;
1665 case INDEX_op_ext8s_i32:
1666 i1 = OPC_SEB;
1667 goto do_unary;
1668 case INDEX_op_ext16s_i32:
1669 i1 = OPC_SEH;
1670 do_unary:
1671 tcg_out_opc_reg(s, i1, a0, TCG_REG_ZERO, a1);
1672 break;
1673
1674 case INDEX_op_sar_i32:
1675 i1 = OPC_SRAV, i2 = OPC_SRA;
1676 goto do_shift;
1677 case INDEX_op_shl_i32:
1678 i1 = OPC_SLLV, i2 = OPC_SLL;
1679 goto do_shift;
1680 case INDEX_op_shr_i32:
1681 i1 = OPC_SRLV, i2 = OPC_SRL;
1682 goto do_shift;
1683 case INDEX_op_rotr_i32:
1684 i1 = OPC_ROTRV, i2 = OPC_ROTR;
1685 do_shift:
1686 if (c2) {
1687 tcg_out_opc_sa(s, i2, a0, a1, a2);
1688 } else {
1689 tcg_out_opc_reg(s, i1, a0, a2, a1);
1690 }
1691 break;
1692 case INDEX_op_rotl_i32:
1693 if (c2) {
1694 tcg_out_opc_sa(s, OPC_ROTR, a0, a1, 32 - a2);
1695 } else {
1696 tcg_out_opc_reg(s, OPC_SUBU, TCG_TMP0, TCG_REG_ZERO, a2);
1697 tcg_out_opc_reg(s, OPC_ROTRV, a0, TCG_TMP0, a1);
1698 }
1699 break;
1700
1701 case INDEX_op_bswap32_i32:
1702 tcg_out_bswap32(s, a0, a1);
1703 break;
1704
1705 case INDEX_op_deposit_i32:
1706 tcg_out_opc_bf(s, OPC_INS, a0, a2, args[3] + args[4] - 1, args[3]);
1707 break;
1708
1709 case INDEX_op_brcond_i32:
1710 tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
1711 break;
1712 case INDEX_op_brcond2_i32:
1713 tcg_out_brcond2(s, args[4], a0, a1, a2, args[3], arg_label(args[5]));
1714 break;
1715
1716 case INDEX_op_movcond_i32:
1717 tcg_out_movcond(s, args[5], a0, a1, a2, args[3], args[4]);
1718 break;
1719
1720 case INDEX_op_setcond_i32:
1721 tcg_out_setcond(s, args[3], a0, a1, a2);
1722 break;
1723 case INDEX_op_setcond2_i32:
1724 tcg_out_setcond2(s, args[5], a0, a1, a2, args[3], args[4]);
1725 break;
1726
1727 case INDEX_op_qemu_ld_i32:
1728 tcg_out_qemu_ld(s, args, false);
1729 break;
1730 case INDEX_op_qemu_ld_i64:
1731 tcg_out_qemu_ld(s, args, true);
1732 break;
1733 case INDEX_op_qemu_st_i32:
1734 tcg_out_qemu_st(s, args, false);
1735 break;
1736 case INDEX_op_qemu_st_i64:
1737 tcg_out_qemu_st(s, args, true);
1738 break;
1739
1740 case INDEX_op_add2_i32:
1741 tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
1742 const_args[4], const_args[5], false);
1743 break;
1744 case INDEX_op_sub2_i32:
1745 tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
1746 const_args[4], const_args[5], true);
1747 break;
1748
1749 case INDEX_op_mb:
1750 tcg_out_mb(s, a0);
1751 break;
1752 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
1753 case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
1754 case INDEX_op_call: /* Always emitted via tcg_out_call. */
1755 default:
1756 tcg_abort();
1757 }
1758 }
1759
1760 static const TCGTargetOpDef mips_op_defs[] = {
1761 { INDEX_op_exit_tb, { } },
1762 { INDEX_op_goto_tb, { } },
1763 { INDEX_op_br, { } },
1764
1765 { INDEX_op_ld8u_i32, { "r", "r" } },
1766 { INDEX_op_ld8s_i32, { "r", "r" } },
1767 { INDEX_op_ld16u_i32, { "r", "r" } },
1768 { INDEX_op_ld16s_i32, { "r", "r" } },
1769 { INDEX_op_ld_i32, { "r", "r" } },
1770 { INDEX_op_st8_i32, { "rZ", "r" } },
1771 { INDEX_op_st16_i32, { "rZ", "r" } },
1772 { INDEX_op_st_i32, { "rZ", "r" } },
1773
1774 { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
1775 { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1776 #if !use_mips32r6_instructions
1777 { INDEX_op_muls2_i32, { "r", "r", "rZ", "rZ" } },
1778 { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1779 #endif
1780 { INDEX_op_mulsh_i32, { "r", "rZ", "rZ" } },
1781 { INDEX_op_muluh_i32, { "r", "rZ", "rZ" } },
1782 { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1783 { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1784 { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1785 { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1786 { INDEX_op_sub_i32, { "r", "rZ", "rN" } },
1787
1788 { INDEX_op_and_i32, { "r", "rZ", "rIK" } },
1789 { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1790 { INDEX_op_not_i32, { "r", "rZ" } },
1791 { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1792 { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1793
1794 { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
1795 { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
1796 { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
1797 { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
1798 { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
1799
1800 { INDEX_op_bswap16_i32, { "r", "r" } },
1801 { INDEX_op_bswap32_i32, { "r", "r" } },
1802
1803 { INDEX_op_ext8s_i32, { "r", "rZ" } },
1804 { INDEX_op_ext16s_i32, { "r", "rZ" } },
1805
1806 { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
1807
1808 { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1809 #if use_mips32r6_instructions
1810 { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1811 #else
1812 { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "0" } },
1813 #endif
1814 { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1815 { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1816
1817 { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rN", "rN" } },
1818 { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rN", "rN" } },
1819 { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1820
1821 #if TARGET_LONG_BITS == 32
1822 { INDEX_op_qemu_ld_i32, { "r", "LZ" } },
1823 { INDEX_op_qemu_st_i32, { "SZ", "SZ" } },
1824 { INDEX_op_qemu_ld_i64, { "r", "r", "LZ" } },
1825 { INDEX_op_qemu_st_i64, { "SZ", "SZ", "SZ" } },
1826 #else
1827 { INDEX_op_qemu_ld_i32, { "r", "LZ", "LZ" } },
1828 { INDEX_op_qemu_st_i32, { "SZ", "SZ", "SZ" } },
1829 { INDEX_op_qemu_ld_i64, { "r", "r", "LZ", "LZ" } },
1830 { INDEX_op_qemu_st_i64, { "SZ", "SZ", "SZ", "SZ" } },
1831 #endif
1832
1833 { INDEX_op_mb, { } },
1834 { -1 },
1835 };
1836
1837 static int tcg_target_callee_save_regs[] = {
1838 TCG_REG_S0, /* used for the global env (TCG_AREG0) */
1839 TCG_REG_S1,
1840 TCG_REG_S2,
1841 TCG_REG_S3,
1842 TCG_REG_S4,
1843 TCG_REG_S5,
1844 TCG_REG_S6,
1845 TCG_REG_S7,
1846 TCG_REG_S8,
1847 TCG_REG_RA, /* should be last for ABI compliance */
1848 };
1849
1850 /* The Linux kernel doesn't provide any information about the available
1851 instruction set. Probe it using a signal handler. */
1852
1853
1854 #ifndef use_movnz_instructions
1855 bool use_movnz_instructions = false;
1856 #endif
1857
1858 #ifndef use_mips32_instructions
1859 bool use_mips32_instructions = false;
1860 #endif
1861
1862 #ifndef use_mips32r2_instructions
1863 bool use_mips32r2_instructions = false;
1864 #endif
1865
1866 static volatile sig_atomic_t got_sigill;
1867
1868 static void sigill_handler(int signo, siginfo_t *si, void *data)
1869 {
1870 /* Skip the faulty instruction */
1871 ucontext_t *uc = (ucontext_t *)data;
1872 uc->uc_mcontext.pc += 4;
1873
1874 got_sigill = 1;
1875 }
1876
1877 static void tcg_target_detect_isa(void)
1878 {
1879 struct sigaction sa_old, sa_new;
1880
1881 memset(&sa_new, 0, sizeof(sa_new));
1882 sa_new.sa_flags = SA_SIGINFO;
1883 sa_new.sa_sigaction = sigill_handler;
1884 sigaction(SIGILL, &sa_new, &sa_old);
1885
1886 /* Probe for movn/movz, necessary to implement movcond. */
1887 #ifndef use_movnz_instructions
1888 got_sigill = 0;
1889 asm volatile(".set push\n"
1890 ".set mips32\n"
1891 "movn $zero, $zero, $zero\n"
1892 "movz $zero, $zero, $zero\n"
1893 ".set pop\n"
1894 : : : );
1895 use_movnz_instructions = !got_sigill;
1896 #endif
1897
1898 /* Probe for MIPS32 instructions. As no subsetting is allowed
1899 by the specification, it is only necessary to probe for one
1900 of the instructions. */
1901 #ifndef use_mips32_instructions
1902 got_sigill = 0;
1903 asm volatile(".set push\n"
1904 ".set mips32\n"
1905 "mul $zero, $zero\n"
1906 ".set pop\n"
1907 : : : );
1908 use_mips32_instructions = !got_sigill;
1909 #endif
1910
1911 /* Probe for MIPS32r2 instructions if MIPS32 instructions are
1912 available. As no subsetting is allowed by the specification,
1913 it is only necessary to probe for one of the instructions. */
1914 #ifndef use_mips32r2_instructions
1915 if (use_mips32_instructions) {
1916 got_sigill = 0;
1917 asm volatile(".set push\n"
1918 ".set mips32r2\n"
1919 "seb $zero, $zero\n"
1920 ".set pop\n"
1921 : : : );
1922 use_mips32r2_instructions = !got_sigill;
1923 }
1924 #endif
1925
1926 sigaction(SIGILL, &sa_old, NULL);
1927 }
1928
1929 static tcg_insn_unit *align_code_ptr(TCGContext *s)
1930 {
1931 uintptr_t p = (uintptr_t)s->code_ptr;
1932 if (p & 15) {
1933 p = (p + 15) & -16;
1934 s->code_ptr = (void *)p;
1935 }
1936 return s->code_ptr;
1937 }
1938
1939 /* Generate global QEMU prologue and epilogue code */
1940 static void tcg_target_qemu_prologue(TCGContext *s)
1941 {
1942 int i, frame_size;
1943
1944 /* reserve some stack space, also for TCG temps. */
1945 frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1946 + TCG_STATIC_CALL_ARGS_SIZE
1947 + CPU_TEMP_BUF_NLONGS * sizeof(long);
1948 frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1949 ~(TCG_TARGET_STACK_ALIGN - 1);
1950 tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1951 + TCG_STATIC_CALL_ARGS_SIZE,
1952 CPU_TEMP_BUF_NLONGS * sizeof(long));
1953
1954 /* TB prologue */
1955 tcg_out_addi(s, TCG_REG_SP, -frame_size);
1956 for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1957 tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1958 TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1959 }
1960
1961 /* Call generated code */
1962 tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
1963 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1964 tb_ret_addr = s->code_ptr;
1965
1966 /* TB epilogue */
1967 for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1968 tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1969 TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1970 }
1971
1972 tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1973 /* delay slot */
1974 tcg_out_addi(s, TCG_REG_SP, frame_size);
1975
1976 if (use_mips32r2_instructions) {
1977 return;
1978 }
1979
1980 /* Bswap subroutine: Input in TCG_TMP0, output in TCG_TMP3;
1981 clobbers TCG_TMP1, TCG_TMP2. */
1982
1983 /*
1984 * bswap32 -- 32-bit swap (signed result for mips64). a0 = abcd.
1985 */
1986 bswap32_addr = align_code_ptr(s);
1987 /* t3 = (ssss)d000 */
1988 tcg_out_opc_sa(s, OPC_SLL, TCG_TMP3, TCG_TMP0, 24);
1989 /* t1 = 000a */
1990 tcg_out_opc_sa(s, OPC_SRL, TCG_TMP1, TCG_TMP0, 24);
1991 /* t2 = 00c0 */
1992 tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP0, 0xff00);
1993 /* t3 = d00a */
1994 tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
1995 /* t1 = 0abc */
1996 tcg_out_opc_sa(s, OPC_SRL, TCG_TMP1, TCG_TMP0, 8);
1997 /* t2 = 0c00 */
1998 tcg_out_opc_sa(s, OPC_SLL, TCG_TMP2, TCG_TMP2, 8);
1999 /* t1 = 00b0 */
2000 tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP1, 0xff00);
2001 /* t3 = dc0a */
2002 tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2003 tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
2004 /* t3 = dcba -- delay slot */
2005 tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2006 }
2007
2008 static void tcg_target_init(TCGContext *s)
2009 {
2010 tcg_target_detect_isa();
2011 tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
2012 tcg_regset_set(tcg_target_call_clobber_regs,
2013 (1 << TCG_REG_V0) |
2014 (1 << TCG_REG_V1) |
2015 (1 << TCG_REG_A0) |
2016 (1 << TCG_REG_A1) |
2017 (1 << TCG_REG_A2) |
2018 (1 << TCG_REG_A3) |
2019 (1 << TCG_REG_T0) |
2020 (1 << TCG_REG_T1) |
2021 (1 << TCG_REG_T2) |
2022 (1 << TCG_REG_T3) |
2023 (1 << TCG_REG_T4) |
2024 (1 << TCG_REG_T5) |
2025 (1 << TCG_REG_T6) |
2026 (1 << TCG_REG_T7) |
2027 (1 << TCG_REG_T8) |
2028 (1 << TCG_REG_T9));
2029
2030 tcg_regset_clear(s->reserved_regs);
2031 tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
2032 tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0); /* kernel use only */
2033 tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1); /* kernel use only */
2034 tcg_regset_set_reg(s->reserved_regs, TCG_TMP0); /* internal use */
2035 tcg_regset_set_reg(s->reserved_regs, TCG_TMP1); /* internal use */
2036 tcg_regset_set_reg(s->reserved_regs, TCG_TMP2); /* internal use */
2037 tcg_regset_set_reg(s->reserved_regs, TCG_TMP3); /* internal use */
2038 tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA); /* return address */
2039 tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); /* stack pointer */
2040 tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP); /* global pointer */
2041
2042 tcg_add_target_add_op_defs(mips_op_defs);
2043 }
2044
2045 void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
2046 {
2047 atomic_set((uint32_t *)jmp_addr, deposit32(OPC_J, 0, 26, addr >> 2));
2048 flush_icache_range(jmp_addr, jmp_addr + 4);
2049 }