master
inc 1,123 lines 30.1 KB
Raw
1 /*
2 * MIPS16 extension (Code Compaction) ASE translation routines
3 *
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 *
9 * SPDX-License-Identifier: LGPL-2.1-or-later
10 */
11
12 /* MIPS16 major opcodes */
13 enum {
14 M16_OPC_ADDIUSP = 0x00,
15 M16_OPC_ADDIUPC = 0x01,
16 M16_OPC_B = 0x02,
17 M16_OPC_JAL = 0x03,
18 M16_OPC_BEQZ = 0x04,
19 M16_OPC_BNEQZ = 0x05,
20 M16_OPC_SHIFT = 0x06,
21 M16_OPC_LD = 0x07,
22 M16_OPC_RRIA = 0x08,
23 M16_OPC_ADDIU8 = 0x09,
24 M16_OPC_SLTI = 0x0a,
25 M16_OPC_SLTIU = 0x0b,
26 M16_OPC_I8 = 0x0c,
27 M16_OPC_LI = 0x0d,
28 M16_OPC_CMPI = 0x0e,
29 M16_OPC_SD = 0x0f,
30 M16_OPC_LB = 0x10,
31 M16_OPC_LH = 0x11,
32 M16_OPC_LWSP = 0x12,
33 M16_OPC_LW = 0x13,
34 M16_OPC_LBU = 0x14,
35 M16_OPC_LHU = 0x15,
36 M16_OPC_LWPC = 0x16,
37 M16_OPC_LWU = 0x17,
38 M16_OPC_SB = 0x18,
39 M16_OPC_SH = 0x19,
40 M16_OPC_SWSP = 0x1a,
41 M16_OPC_SW = 0x1b,
42 M16_OPC_RRR = 0x1c,
43 M16_OPC_RR = 0x1d,
44 M16_OPC_EXTEND = 0x1e,
45 M16_OPC_I64 = 0x1f
46 };
47
48 /* I8 funct field */
49 enum {
50 I8_BTEQZ = 0x0,
51 I8_BTNEZ = 0x1,
52 I8_SWRASP = 0x2,
53 I8_ADJSP = 0x3,
54 I8_SVRS = 0x4,
55 I8_MOV32R = 0x5,
56 I8_MOVR32 = 0x7
57 };
58
59 /* RRR f field */
60 enum {
61 RRR_DADDU = 0x0,
62 RRR_ADDU = 0x1,
63 RRR_DSUBU = 0x2,
64 RRR_SUBU = 0x3
65 };
66
67 /* RR funct field */
68 enum {
69 RR_JR = 0x00,
70 RR_SDBBP = 0x01,
71 RR_SLT = 0x02,
72 RR_SLTU = 0x03,
73 RR_SLLV = 0x04,
74 RR_BREAK = 0x05,
75 RR_SRLV = 0x06,
76 RR_SRAV = 0x07,
77 RR_DSRL = 0x08,
78 RR_CMP = 0x0a,
79 RR_NEG = 0x0b,
80 RR_AND = 0x0c,
81 RR_OR = 0x0d,
82 RR_XOR = 0x0e,
83 RR_NOT = 0x0f,
84 RR_MFHI = 0x10,
85 RR_CNVT = 0x11,
86 RR_MFLO = 0x12,
87 RR_DSRA = 0x13,
88 RR_DSLLV = 0x14,
89 RR_DSRLV = 0x16,
90 RR_DSRAV = 0x17,
91 RR_MULT = 0x18,
92 RR_MULTU = 0x19,
93 RR_DIV = 0x1a,
94 RR_DIVU = 0x1b,
95 RR_DMULT = 0x1c,
96 RR_DMULTU = 0x1d,
97 RR_DDIV = 0x1e,
98 RR_DDIVU = 0x1f
99 };
100
101 /* I64 funct field */
102 enum {
103 I64_LDSP = 0x0,
104 I64_SDSP = 0x1,
105 I64_SDRASP = 0x2,
106 I64_DADJSP = 0x3,
107 I64_LDPC = 0x4,
108 I64_DADDIU5 = 0x5,
109 I64_DADDIUPC = 0x6,
110 I64_DADDIUSP = 0x7
111 };
112
113 /* RR ry field for CNVT */
114 enum {
115 RR_RY_CNVT_ZEB = 0x0,
116 RR_RY_CNVT_ZEH = 0x1,
117 RR_RY_CNVT_ZEW = 0x2,
118 RR_RY_CNVT_SEB = 0x4,
119 RR_RY_CNVT_SEH = 0x5,
120 RR_RY_CNVT_SEW = 0x6,
121 };
122
123 static int xlat(int r)
124 {
125 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
126
127 return map[r];
128 }
129
130 static void decr_and_store(DisasContext *ctx, unsigned regidx, TCGv t0)
131 {
132 TCGv t1 = tcg_temp_new();
133
134 gen_op_addr_addi(ctx, t0, t0, -4);
135 gen_load_gpr(t1, regidx);
136 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
137 ctx->default_tcg_memop_mask);
138 }
139
140 static void gen_mips16_save(DisasContext *ctx,
141 int xsregs, int aregs,
142 int do_ra, int do_s0, int do_s1,
143 int framesize)
144 {
145 TCGv t0 = tcg_temp_new();
146 TCGv t1 = tcg_temp_new();
147 int args, astatic;
148
149 switch (aregs) {
150 case 0:
151 case 1:
152 case 2:
153 case 3:
154 case 11:
155 args = 0;
156 break;
157 case 4:
158 case 5:
159 case 6:
160 case 7:
161 args = 1;
162 break;
163 case 8:
164 case 9:
165 case 10:
166 args = 2;
167 break;
168 case 12:
169 case 13:
170 args = 3;
171 break;
172 case 14:
173 args = 4;
174 break;
175 default:
176 gen_reserved_instruction(ctx);
177 return;
178 }
179
180 switch (args) {
181 case 4:
182 gen_base_offset_addr(ctx, t0, 29, 12);
183 gen_load_gpr(t1, 7);
184 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
185 ctx->default_tcg_memop_mask);
186 /* Fall through */
187 case 3:
188 gen_base_offset_addr(ctx, t0, 29, 8);
189 gen_load_gpr(t1, 6);
190 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
191 ctx->default_tcg_memop_mask);
192 /* Fall through */
193 case 2:
194 gen_base_offset_addr(ctx, t0, 29, 4);
195 gen_load_gpr(t1, 5);
196 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
197 ctx->default_tcg_memop_mask);
198 /* Fall through */
199 case 1:
200 gen_base_offset_addr(ctx, t0, 29, 0);
201 gen_load_gpr(t1, 4);
202 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
203 ctx->default_tcg_memop_mask);
204 }
205
206 gen_load_gpr(t0, 29);
207
208 if (do_ra) {
209 decr_and_store(ctx, 31, t0);
210 }
211
212 switch (xsregs) {
213 case 7:
214 decr_and_store(ctx, 30, t0);
215 /* Fall through */
216 case 6:
217 decr_and_store(ctx, 23, t0);
218 /* Fall through */
219 case 5:
220 decr_and_store(ctx, 22, t0);
221 /* Fall through */
222 case 4:
223 decr_and_store(ctx, 21, t0);
224 /* Fall through */
225 case 3:
226 decr_and_store(ctx, 20, t0);
227 /* Fall through */
228 case 2:
229 decr_and_store(ctx, 19, t0);
230 /* Fall through */
231 case 1:
232 decr_and_store(ctx, 18, t0);
233 }
234
235 if (do_s1) {
236 decr_and_store(ctx, 17, t0);
237 }
238 if (do_s0) {
239 decr_and_store(ctx, 16, t0);
240 }
241
242 switch (aregs) {
243 case 0:
244 case 4:
245 case 8:
246 case 12:
247 case 14:
248 astatic = 0;
249 break;
250 case 1:
251 case 5:
252 case 9:
253 case 13:
254 astatic = 1;
255 break;
256 case 2:
257 case 6:
258 case 10:
259 astatic = 2;
260 break;
261 case 3:
262 case 7:
263 astatic = 3;
264 break;
265 case 11:
266 astatic = 4;
267 break;
268 default:
269 gen_reserved_instruction(ctx);
270 return;
271 }
272
273 if (astatic > 0) {
274 decr_and_store(ctx, 7, t0);
275 if (astatic > 1) {
276 decr_and_store(ctx, 6, t0);
277 if (astatic > 2) {
278 decr_and_store(ctx, 5, t0);
279 if (astatic > 3) {
280 decr_and_store(ctx, 4, t0);
281 }
282 }
283 }
284 }
285
286 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], -framesize);
287 }
288
289 static void decr_and_load(DisasContext *ctx, unsigned regidx, TCGv t0)
290 {
291 TCGv t1 = tcg_temp_new();
292 TCGv t2 = tcg_temp_new();
293
294 tcg_gen_movi_tl(t2, -4);
295 gen_op_addr_add(ctx, t0, t0, t2);
296 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
297 ctx->default_tcg_memop_mask);
298 gen_store_gpr(t1, regidx);
299 }
300
301 static void gen_mips16_restore(DisasContext *ctx,
302 int xsregs, int aregs,
303 int do_ra, int do_s0, int do_s1,
304 int framesize)
305 {
306 int astatic;
307 TCGv t0 = tcg_temp_new();
308
309 gen_op_addr_addi(ctx, t0, cpu_gpr[29], framesize);
310
311 if (do_ra) {
312 decr_and_load(ctx, 31, t0);
313 }
314
315 switch (xsregs) {
316 case 7:
317 decr_and_load(ctx, 30, t0);
318 /* Fall through */
319 case 6:
320 decr_and_load(ctx, 23, t0);
321 /* Fall through */
322 case 5:
323 decr_and_load(ctx, 22, t0);
324 /* Fall through */
325 case 4:
326 decr_and_load(ctx, 21, t0);
327 /* Fall through */
328 case 3:
329 decr_and_load(ctx, 20, t0);
330 /* Fall through */
331 case 2:
332 decr_and_load(ctx, 19, t0);
333 /* Fall through */
334 case 1:
335 decr_and_load(ctx, 18, t0);
336 }
337
338 if (do_s1) {
339 decr_and_load(ctx, 17, t0);
340 }
341 if (do_s0) {
342 decr_and_load(ctx, 16, t0);
343 }
344
345 switch (aregs) {
346 case 0:
347 case 4:
348 case 8:
349 case 12:
350 case 14:
351 astatic = 0;
352 break;
353 case 1:
354 case 5:
355 case 9:
356 case 13:
357 astatic = 1;
358 break;
359 case 2:
360 case 6:
361 case 10:
362 astatic = 2;
363 break;
364 case 3:
365 case 7:
366 astatic = 3;
367 break;
368 case 11:
369 astatic = 4;
370 break;
371 default:
372 gen_reserved_instruction(ctx);
373 return;
374 }
375
376 if (astatic > 0) {
377 decr_and_load(ctx, 7, t0);
378 if (astatic > 1) {
379 decr_and_load(ctx, 6, t0);
380 if (astatic > 2) {
381 decr_and_load(ctx, 5, t0);
382 if (astatic > 3) {
383 decr_and_load(ctx, 4, t0);
384 }
385 }
386 }
387 }
388
389 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], framesize);
390 }
391
392 #if defined(TARGET_MIPS64)
393 static void decode_i64_mips16(DisasContext *ctx,
394 int ry, int funct, int16_t offset,
395 int extended)
396 {
397 switch (funct) {
398 case I64_LDSP:
399 check_insn(ctx, ISA_MIPS3);
400 check_mips_64(ctx);
401 offset = extended ? offset : offset << 3;
402 gen_ld(ctx, OPC_LD, ry, 29, offset);
403 break;
404 case I64_SDSP:
405 check_insn(ctx, ISA_MIPS3);
406 check_mips_64(ctx);
407 offset = extended ? offset : offset << 3;
408 gen_st(ctx, OPC_SD, ry, 29, offset);
409 break;
410 case I64_SDRASP:
411 check_insn(ctx, ISA_MIPS3);
412 check_mips_64(ctx);
413 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
414 gen_st(ctx, OPC_SD, 31, 29, offset);
415 break;
416 case I64_DADJSP:
417 check_insn(ctx, ISA_MIPS3);
418 check_mips_64(ctx);
419 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
420 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
421 break;
422 case I64_LDPC:
423 check_insn(ctx, ISA_MIPS3);
424 check_mips_64(ctx);
425 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
426 gen_reserved_instruction(ctx);
427 } else {
428 offset = extended ? offset : offset << 3;
429 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
430 }
431 break;
432 case I64_DADDIU5:
433 check_insn(ctx, ISA_MIPS3);
434 check_mips_64(ctx);
435 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
436 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
437 break;
438 case I64_DADDIUPC:
439 check_insn(ctx, ISA_MIPS3);
440 check_mips_64(ctx);
441 offset = extended ? offset : offset << 2;
442 gen_addiupc(ctx, ry, offset, 1, extended);
443 break;
444 case I64_DADDIUSP:
445 check_insn(ctx, ISA_MIPS3);
446 check_mips_64(ctx);
447 offset = extended ? offset : offset << 2;
448 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
449 break;
450 }
451 }
452 #endif
453
454 static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
455 {
456 int extend = translator_lduw_end(env, &ctx->base, ctx->base.pc_next + 2,
457 mo_endian(ctx));
458 int op, rx, ry, funct, sa;
459 int16_t imm, offset;
460
461 ctx->opcode = (ctx->opcode << 16) | extend;
462 op = (ctx->opcode >> 11) & 0x1f;
463 sa = (ctx->opcode >> 22) & 0x1f;
464 funct = (ctx->opcode >> 8) & 0x7;
465 rx = xlat((ctx->opcode >> 8) & 0x7);
466 ry = xlat((ctx->opcode >> 5) & 0x7);
467 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
468 | ((ctx->opcode >> 21) & 0x3f) << 5
469 | (ctx->opcode & 0x1f));
470
471 /*
472 * The extended opcodes cleverly reuse the opcodes from their 16-bit
473 * counterparts.
474 */
475 switch (op) {
476 case M16_OPC_ADDIUSP:
477 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
478 break;
479 case M16_OPC_ADDIUPC:
480 gen_addiupc(ctx, rx, imm, 0, 1);
481 break;
482 case M16_OPC_B:
483 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
484 /* No delay slot, so just process as a normal instruction */
485 break;
486 case M16_OPC_BEQZ:
487 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
488 /* No delay slot, so just process as a normal instruction */
489 break;
490 case M16_OPC_BNEQZ:
491 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
492 /* No delay slot, so just process as a normal instruction */
493 break;
494 case M16_OPC_SHIFT:
495 switch (ctx->opcode & 0x3) {
496 case 0x0:
497 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
498 break;
499 case 0x1:
500 #if defined(TARGET_MIPS64)
501 check_mips_64(ctx);
502 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
503 #else
504 gen_reserved_instruction(ctx);
505 #endif
506 break;
507 case 0x2:
508 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
509 break;
510 case 0x3:
511 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
512 break;
513 }
514 break;
515 #if defined(TARGET_MIPS64)
516 case M16_OPC_LD:
517 check_insn(ctx, ISA_MIPS3);
518 check_mips_64(ctx);
519 gen_ld(ctx, OPC_LD, ry, rx, offset);
520 break;
521 #endif
522 case M16_OPC_RRIA:
523 imm = ctx->opcode & 0xf;
524 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
525 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
526 imm = (int16_t) (imm << 1) >> 1;
527 if ((ctx->opcode >> 4) & 0x1) {
528 #if defined(TARGET_MIPS64)
529 check_mips_64(ctx);
530 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
531 #else
532 gen_reserved_instruction(ctx);
533 #endif
534 } else {
535 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
536 }
537 break;
538 case M16_OPC_ADDIU8:
539 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
540 break;
541 case M16_OPC_SLTI:
542 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
543 break;
544 case M16_OPC_SLTIU:
545 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
546 break;
547 case M16_OPC_I8:
548 switch (funct) {
549 case I8_BTEQZ:
550 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
551 break;
552 case I8_BTNEZ:
553 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
554 break;
555 case I8_SWRASP:
556 gen_st(ctx, OPC_SW, 31, 29, imm);
557 break;
558 case I8_ADJSP:
559 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
560 break;
561 case I8_SVRS:
562 check_insn(ctx, ISA_MIPS_R1);
563 {
564 int xsregs = (ctx->opcode >> 24) & 0x7;
565 int aregs = (ctx->opcode >> 16) & 0xf;
566 int do_ra = (ctx->opcode >> 6) & 0x1;
567 int do_s0 = (ctx->opcode >> 5) & 0x1;
568 int do_s1 = (ctx->opcode >> 4) & 0x1;
569 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
570 | (ctx->opcode & 0xf)) << 3;
571
572 if (ctx->opcode & (1 << 7)) {
573 gen_mips16_save(ctx, xsregs, aregs,
574 do_ra, do_s0, do_s1,
575 framesize);
576 } else {
577 gen_mips16_restore(ctx, xsregs, aregs,
578 do_ra, do_s0, do_s1,
579 framesize);
580 }
581 }
582 break;
583 default:
584 gen_reserved_instruction(ctx);
585 break;
586 }
587 break;
588 case M16_OPC_LI:
589 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
590 break;
591 case M16_OPC_CMPI:
592 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
593 break;
594 #if defined(TARGET_MIPS64)
595 case M16_OPC_SD:
596 check_insn(ctx, ISA_MIPS3);
597 check_mips_64(ctx);
598 gen_st(ctx, OPC_SD, ry, rx, offset);
599 break;
600 #endif
601 case M16_OPC_LB:
602 gen_ld(ctx, OPC_LB, ry, rx, offset);
603 break;
604 case M16_OPC_LH:
605 gen_ld(ctx, OPC_LH, ry, rx, offset);
606 break;
607 case M16_OPC_LWSP:
608 gen_ld(ctx, OPC_LW, rx, 29, offset);
609 break;
610 case M16_OPC_LW:
611 gen_ld(ctx, OPC_LW, ry, rx, offset);
612 break;
613 case M16_OPC_LBU:
614 gen_ld(ctx, OPC_LBU, ry, rx, offset);
615 break;
616 case M16_OPC_LHU:
617 gen_ld(ctx, OPC_LHU, ry, rx, offset);
618 break;
619 case M16_OPC_LWPC:
620 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
621 break;
622 #if defined(TARGET_MIPS64)
623 case M16_OPC_LWU:
624 check_insn(ctx, ISA_MIPS3);
625 check_mips_64(ctx);
626 gen_ld(ctx, OPC_LWU, ry, rx, offset);
627 break;
628 #endif
629 case M16_OPC_SB:
630 gen_st(ctx, OPC_SB, ry, rx, offset);
631 break;
632 case M16_OPC_SH:
633 gen_st(ctx, OPC_SH, ry, rx, offset);
634 break;
635 case M16_OPC_SWSP:
636 gen_st(ctx, OPC_SW, rx, 29, offset);
637 break;
638 case M16_OPC_SW:
639 gen_st(ctx, OPC_SW, ry, rx, offset);
640 break;
641 #if defined(TARGET_MIPS64)
642 case M16_OPC_I64:
643 decode_i64_mips16(ctx, ry, funct, offset, 1);
644 break;
645 #endif
646 default:
647 gen_reserved_instruction(ctx);
648 break;
649 }
650
651 return 4;
652 }
653
654 static int decode_ase_mips16e(CPUMIPSState *env, DisasContext *ctx)
655 {
656 int rx, ry;
657 int sa;
658 int op, cnvt_op, op1, offset;
659 int funct;
660 int n_bytes;
661
662 op = (ctx->opcode >> 11) & 0x1f;
663 sa = (ctx->opcode >> 2) & 0x7;
664 sa = sa == 0 ? 8 : sa;
665 rx = xlat((ctx->opcode >> 8) & 0x7);
666 cnvt_op = (ctx->opcode >> 5) & 0x7;
667 ry = xlat((ctx->opcode >> 5) & 0x7);
668 op1 = offset = ctx->opcode & 0x1f;
669
670 n_bytes = 2;
671
672 switch (op) {
673 case M16_OPC_ADDIUSP:
674 {
675 int16_t imm = ((uint8_t) ctx->opcode) << 2;
676
677 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
678 }
679 break;
680 case M16_OPC_ADDIUPC:
681 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
682 break;
683 case M16_OPC_B:
684 offset = (ctx->opcode & 0x7ff) << 1;
685 offset = (int16_t)(offset << 4) >> 4;
686 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
687 /* No delay slot, so just process as a normal instruction */
688 break;
689 case M16_OPC_JAL:
690 offset = translator_lduw_end(env, &ctx->base, ctx->base.pc_next + 2,
691 mo_endian(ctx));
692 offset = (((ctx->opcode & 0x1f) << 21)
693 | ((ctx->opcode >> 5) & 0x1f) << 16
694 | offset) << 2;
695 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
696 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
697 n_bytes = 4;
698 break;
699 case M16_OPC_BEQZ:
700 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
701 ((int8_t)ctx->opcode) << 1, 0);
702 /* No delay slot, so just process as a normal instruction */
703 break;
704 case M16_OPC_BNEQZ:
705 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
706 ((int8_t)ctx->opcode) << 1, 0);
707 /* No delay slot, so just process as a normal instruction */
708 break;
709 case M16_OPC_SHIFT:
710 switch (ctx->opcode & 0x3) {
711 case 0x0:
712 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
713 break;
714 case 0x1:
715 #if defined(TARGET_MIPS64)
716 check_insn(ctx, ISA_MIPS3);
717 check_mips_64(ctx);
718 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
719 #else
720 gen_reserved_instruction(ctx);
721 #endif
722 break;
723 case 0x2:
724 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
725 break;
726 case 0x3:
727 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
728 break;
729 }
730 break;
731 #if defined(TARGET_MIPS64)
732 case M16_OPC_LD:
733 check_insn(ctx, ISA_MIPS3);
734 check_mips_64(ctx);
735 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
736 break;
737 #endif
738 case M16_OPC_RRIA:
739 {
740 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
741
742 if ((ctx->opcode >> 4) & 1) {
743 #if defined(TARGET_MIPS64)
744 check_insn(ctx, ISA_MIPS3);
745 check_mips_64(ctx);
746 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
747 #else
748 gen_reserved_instruction(ctx);
749 #endif
750 } else {
751 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
752 }
753 }
754 break;
755 case M16_OPC_ADDIU8:
756 {
757 int16_t imm = (int8_t) ctx->opcode;
758
759 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
760 }
761 break;
762 case M16_OPC_SLTI:
763 {
764 int16_t imm = (uint8_t) ctx->opcode;
765 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
766 }
767 break;
768 case M16_OPC_SLTIU:
769 {
770 int16_t imm = (uint8_t) ctx->opcode;
771 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
772 }
773 break;
774 case M16_OPC_I8:
775 {
776 int reg32;
777
778 funct = (ctx->opcode >> 8) & 0x7;
779 switch (funct) {
780 case I8_BTEQZ:
781 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
782 ((int8_t)ctx->opcode) << 1, 0);
783 break;
784 case I8_BTNEZ:
785 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
786 ((int8_t)ctx->opcode) << 1, 0);
787 break;
788 case I8_SWRASP:
789 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
790 break;
791 case I8_ADJSP:
792 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
793 ((int8_t)ctx->opcode) << 3);
794 break;
795 case I8_SVRS:
796 check_insn(ctx, ISA_MIPS_R1);
797 {
798 int do_ra = ctx->opcode & (1 << 6);
799 int do_s0 = ctx->opcode & (1 << 5);
800 int do_s1 = ctx->opcode & (1 << 4);
801 int framesize = ctx->opcode & 0xf;
802
803 if (framesize == 0) {
804 framesize = 128;
805 } else {
806 framesize = framesize << 3;
807 }
808
809 if (ctx->opcode & (1 << 7)) {
810 gen_mips16_save(ctx, 0, 0,
811 do_ra, do_s0, do_s1, framesize);
812 } else {
813 gen_mips16_restore(ctx, 0, 0,
814 do_ra, do_s0, do_s1, framesize);
815 }
816 }
817 break;
818 case I8_MOV32R:
819 {
820 int rz = xlat(ctx->opcode & 0x7);
821
822 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
823 ((ctx->opcode >> 5) & 0x7);
824 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
825 }
826 break;
827 case I8_MOVR32:
828 reg32 = ctx->opcode & 0x1f;
829 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
830 break;
831 default:
832 gen_reserved_instruction(ctx);
833 break;
834 }
835 }
836 break;
837 case M16_OPC_LI:
838 {
839 int16_t imm = (uint8_t) ctx->opcode;
840
841 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
842 }
843 break;
844 case M16_OPC_CMPI:
845 {
846 int16_t imm = (uint8_t) ctx->opcode;
847 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
848 }
849 break;
850 #if defined(TARGET_MIPS64)
851 case M16_OPC_SD:
852 check_insn(ctx, ISA_MIPS3);
853 check_mips_64(ctx);
854 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
855 break;
856 #endif
857 case M16_OPC_LB:
858 gen_ld(ctx, OPC_LB, ry, rx, offset);
859 break;
860 case M16_OPC_LH:
861 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
862 break;
863 case M16_OPC_LWSP:
864 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
865 break;
866 case M16_OPC_LW:
867 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
868 break;
869 case M16_OPC_LBU:
870 gen_ld(ctx, OPC_LBU, ry, rx, offset);
871 break;
872 case M16_OPC_LHU:
873 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
874 break;
875 case M16_OPC_LWPC:
876 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
877 break;
878 #if defined(TARGET_MIPS64)
879 case M16_OPC_LWU:
880 check_insn(ctx, ISA_MIPS3);
881 check_mips_64(ctx);
882 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
883 break;
884 #endif
885 case M16_OPC_SB:
886 gen_st(ctx, OPC_SB, ry, rx, offset);
887 break;
888 case M16_OPC_SH:
889 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
890 break;
891 case M16_OPC_SWSP:
892 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
893 break;
894 case M16_OPC_SW:
895 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
896 break;
897 case M16_OPC_RRR:
898 {
899 int rz = xlat((ctx->opcode >> 2) & 0x7);
900 int mips32_op;
901
902 switch (ctx->opcode & 0x3) {
903 case RRR_ADDU:
904 mips32_op = OPC_ADDU;
905 break;
906 case RRR_SUBU:
907 mips32_op = OPC_SUBU;
908 break;
909 #if defined(TARGET_MIPS64)
910 case RRR_DADDU:
911 mips32_op = OPC_DADDU;
912 check_insn(ctx, ISA_MIPS3);
913 check_mips_64(ctx);
914 break;
915 case RRR_DSUBU:
916 mips32_op = OPC_DSUBU;
917 check_insn(ctx, ISA_MIPS3);
918 check_mips_64(ctx);
919 break;
920 #endif
921 default:
922 gen_reserved_instruction(ctx);
923 goto done;
924 }
925
926 gen_arith(ctx, mips32_op, rz, rx, ry);
927 done:
928 ;
929 }
930 break;
931 case M16_OPC_RR:
932 switch (op1) {
933 case RR_JR:
934 {
935 int nd = (ctx->opcode >> 7) & 0x1;
936 int link = (ctx->opcode >> 6) & 0x1;
937 int ra = (ctx->opcode >> 5) & 0x1;
938
939 if (nd) {
940 check_insn(ctx, ISA_MIPS_R1);
941 }
942
943 if (link) {
944 op = OPC_JALR;
945 } else {
946 op = OPC_JR;
947 }
948
949 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
950 (nd ? 0 : 2));
951 }
952 break;
953 case RR_SDBBP:
954 if (is_uhi(ctx, extract32(ctx->opcode, 5, 6))) {
955 ctx->base.is_jmp = DISAS_SEMIHOST;
956 } else {
957 /*
958 * XXX: not clear which exception should be raised
959 * when in debug mode...
960 */
961 check_insn(ctx, ISA_MIPS_R1);
962 generate_exception_end(ctx, EXCP_DBp);
963 }
964 break;
965 case RR_SLT:
966 gen_slt(ctx, OPC_SLT, 24, rx, ry);
967 break;
968 case RR_SLTU:
969 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
970 break;
971 case RR_BREAK:
972 generate_exception_break(ctx, extract32(ctx->opcode, 5, 6));
973 break;
974 case RR_SLLV:
975 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
976 break;
977 case RR_SRLV:
978 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
979 break;
980 case RR_SRAV:
981 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
982 break;
983 #if defined(TARGET_MIPS64)
984 case RR_DSRL:
985 check_insn(ctx, ISA_MIPS3);
986 check_mips_64(ctx);
987 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
988 break;
989 #endif
990 case RR_CMP:
991 gen_logic(ctx, OPC_XOR, 24, rx, ry);
992 break;
993 case RR_NEG:
994 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
995 break;
996 case RR_AND:
997 gen_logic(ctx, OPC_AND, rx, rx, ry);
998 break;
999 case RR_OR:
1000 gen_logic(ctx, OPC_OR, rx, rx, ry);
1001 break;
1002 case RR_XOR:
1003 gen_logic(ctx, OPC_XOR, rx, rx, ry);
1004 break;
1005 case RR_NOT:
1006 gen_logic(ctx, OPC_NOR, rx, ry, 0);
1007 break;
1008 case RR_MFHI:
1009 gen_HILO(ctx, OPC_MFHI, 0, rx);
1010 break;
1011 case RR_CNVT:
1012 check_insn(ctx, ISA_MIPS_R1);
1013 switch (cnvt_op) {
1014 case RR_RY_CNVT_ZEB:
1015 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
1016 break;
1017 case RR_RY_CNVT_ZEH:
1018 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
1019 break;
1020 case RR_RY_CNVT_SEB:
1021 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
1022 break;
1023 case RR_RY_CNVT_SEH:
1024 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
1025 break;
1026 #if defined(TARGET_MIPS64)
1027 case RR_RY_CNVT_ZEW:
1028 check_insn(ctx, ISA_MIPS_R1);
1029 check_mips_64(ctx);
1030 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
1031 break;
1032 case RR_RY_CNVT_SEW:
1033 check_insn(ctx, ISA_MIPS_R1);
1034 check_mips_64(ctx);
1035 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
1036 break;
1037 #endif
1038 default:
1039 gen_reserved_instruction(ctx);
1040 break;
1041 }
1042 break;
1043 case RR_MFLO:
1044 gen_HILO(ctx, OPC_MFLO, 0, rx);
1045 break;
1046 #if defined(TARGET_MIPS64)
1047 case RR_DSRA:
1048 check_insn(ctx, ISA_MIPS3);
1049 check_mips_64(ctx);
1050 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
1051 break;
1052 case RR_DSLLV:
1053 check_insn(ctx, ISA_MIPS3);
1054 check_mips_64(ctx);
1055 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
1056 break;
1057 case RR_DSRLV:
1058 check_insn(ctx, ISA_MIPS3);
1059 check_mips_64(ctx);
1060 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
1061 break;
1062 case RR_DSRAV:
1063 check_insn(ctx, ISA_MIPS3);
1064 check_mips_64(ctx);
1065 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
1066 break;
1067 #endif
1068 case RR_MULT:
1069 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
1070 break;
1071 case RR_MULTU:
1072 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
1073 break;
1074 case RR_DIV:
1075 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
1076 break;
1077 case RR_DIVU:
1078 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
1079 break;
1080 #if defined(TARGET_MIPS64)
1081 case RR_DMULT:
1082 check_insn(ctx, ISA_MIPS3);
1083 check_mips_64(ctx);
1084 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
1085 break;
1086 case RR_DMULTU:
1087 check_insn(ctx, ISA_MIPS3);
1088 check_mips_64(ctx);
1089 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
1090 break;
1091 case RR_DDIV:
1092 check_insn(ctx, ISA_MIPS3);
1093 check_mips_64(ctx);
1094 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
1095 break;
1096 case RR_DDIVU:
1097 check_insn(ctx, ISA_MIPS3);
1098 check_mips_64(ctx);
1099 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
1100 break;
1101 #endif
1102 default:
1103 gen_reserved_instruction(ctx);
1104 break;
1105 }
1106 break;
1107 case M16_OPC_EXTEND:
1108 decode_extended_mips16_opc(env, ctx);
1109 n_bytes = 4;
1110 break;
1111 #if defined(TARGET_MIPS64)
1112 case M16_OPC_I64:
1113 funct = (ctx->opcode >> 8) & 0x7;
1114 decode_i64_mips16(ctx, ry, funct, offset, 0);
1115 break;
1116 #endif
1117 default:
1118 gen_reserved_instruction(ctx);
1119 break;
1120 }
1121
1122 return n_bytes;
1123 }