]> git.proxmox.com Git - mirror_qemu.git/blame - target-tilegx/translate.c
target-tilegx: Handle mtspr, mfspr
[mirror_qemu.git] / target-tilegx / translate.c
CommitLineData
8fd29dd7
RH
1/*
2 * QEMU TILE-Gx CPU
3 *
4 * Copyright (c) 2015 Chen Gang
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see
18 * <http://www.gnu.org/licenses/lgpl-2.1.html>
19 */
20
21#include "cpu.h"
22#include "qemu/log.h"
23#include "disas/disas.h"
24#include "tcg-op.h"
25#include "exec/cpu_ldst.h"
26#include "opcode_tilegx.h"
03b217b1 27#include "spr_def_64.h"
8fd29dd7
RH
28
29#define FMT64X "%016" PRIx64
30
31static TCGv_ptr cpu_env;
32static TCGv cpu_pc;
33static TCGv cpu_regs[TILEGX_R_COUNT];
34
35static const char * const reg_names[64] = {
36 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
37 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
38 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
39 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
40 "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
41 "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
42 "r48", "r49", "r50", "r51", "bp", "tp", "sp", "lr",
43 "sn", "idn0", "idn1", "udn0", "udn1", "udn2", "udn2", "zero"
44};
45
46/* Modified registers are cached in temporaries until the end of the bundle. */
47typedef struct {
48 unsigned reg;
49 TCGv val;
50} DisasContextTemp;
51
52#define MAX_WRITEBACK 4
53
54/* This is the state at translation time. */
55typedef struct {
56 uint64_t pc; /* Current pc */
57
58 TCGv zero; /* For zero register */
59
60 DisasContextTemp wb[MAX_WRITEBACK];
61 int num_wb;
62 int mmuidx;
63 bool exit_tb;
64
65 struct {
66 TCGCond cond; /* branch condition */
67 TCGv dest; /* branch destination */
68 TCGv val1; /* value to be compared against zero, for cond */
69 } jmp; /* Jump object, only once in each TB block */
70} DisasContext;
71
72#include "exec/gen-icount.h"
73
74/* Differentiate the various pipe encodings. */
75#define TY_X0 0
76#define TY_X1 1
77#define TY_Y0 2
78#define TY_Y1 3
79
80/* Remerge the base opcode and extension fields for switching.
81 The X opcode fields are 3 bits; Y0/Y1 opcode fields are 4 bits;
82 Y2 opcode field is 2 bits. */
83#define OE(OP, EXT, XY) (TY_##XY + OP * 4 + EXT * 64)
84
85/* Similar, but for Y2 only. */
86#define OEY2(OP, MODE) (OP + MODE * 4)
87
88/* Similar, but make sure opcode names match up. */
89#define OE_RR_X0(E) OE(RRR_0_OPCODE_X0, E##_UNARY_OPCODE_X0, X0)
90#define OE_RR_X1(E) OE(RRR_0_OPCODE_X1, E##_UNARY_OPCODE_X1, X1)
91#define OE_RR_Y0(E) OE(RRR_1_OPCODE_Y0, E##_UNARY_OPCODE_Y0, Y0)
92#define OE_RR_Y1(E) OE(RRR_1_OPCODE_Y1, E##_UNARY_OPCODE_Y1, Y1)
93#define OE_RRR(E,N,XY) OE(RRR_##N##_OPCODE_##XY, E##_RRR_##N##_OPCODE_##XY, XY)
94#define OE_IM(E,XY) OE(IMM8_OPCODE_##XY, E##_IMM8_OPCODE_##XY, XY)
95#define OE_SH(E,XY) OE(SHIFT_OPCODE_##XY, E##_SHIFT_OPCODE_##XY, XY)
96
e7346cf0
RH
97#define V1_IMM(X) (((X) & 0xff) * 0x0101010101010101ull)
98
8fd29dd7
RH
99
100static void gen_exception(DisasContext *dc, TileExcp num)
101{
102 TCGv_i32 tmp;
103
104 tcg_gen_movi_tl(cpu_pc, dc->pc + TILEGX_BUNDLE_SIZE_IN_BYTES);
105
106 tmp = tcg_const_i32(num);
107 gen_helper_exception(cpu_env, tmp);
108 tcg_temp_free_i32(tmp);
109 dc->exit_tb = true;
110}
111
a9fdfc7e
RH
112static bool check_gr(DisasContext *dc, uint8_t reg)
113{
114 if (likely(reg < TILEGX_R_COUNT)) {
115 return true;
116 }
117
118 switch (reg) {
119 case TILEGX_R_SN:
120 case TILEGX_R_ZERO:
121 break;
122 case TILEGX_R_IDN0:
123 case TILEGX_R_IDN1:
124 gen_exception(dc, TILEGX_EXCP_REG_IDN_ACCESS);
125 break;
126 case TILEGX_R_UDN0:
127 case TILEGX_R_UDN1:
128 case TILEGX_R_UDN2:
129 case TILEGX_R_UDN3:
130 gen_exception(dc, TILEGX_EXCP_REG_UDN_ACCESS);
131 break;
132 default:
133 g_assert_not_reached();
134 }
135 return false;
136}
137
138static TCGv load_zero(DisasContext *dc)
139{
140 if (TCGV_IS_UNUSED_I64(dc->zero)) {
141 dc->zero = tcg_const_i64(0);
142 }
143 return dc->zero;
144}
145
146static TCGv load_gr(DisasContext *dc, unsigned reg)
147{
148 if (check_gr(dc, reg)) {
149 return cpu_regs[reg];
150 }
151 return load_zero(dc);
152}
153
154static TCGv dest_gr(DisasContext *dc, unsigned reg)
155{
156 int n;
157
158 /* Skip the result, mark the exception if necessary, and continue */
159 check_gr(dc, reg);
160
161 n = dc->num_wb++;
162 dc->wb[n].reg = reg;
163 return dc->wb[n].val = tcg_temp_new_i64();
164}
165
89b8c750
RH
166static void gen_saturate_op(TCGv tdest, TCGv tsrca, TCGv tsrcb,
167 void (*operate)(TCGv, TCGv, TCGv))
168{
169 TCGv t0 = tcg_temp_new();
170
171 tcg_gen_ext32s_tl(tdest, tsrca);
172 tcg_gen_ext32s_tl(t0, tsrcb);
173 operate(tdest, tdest, t0);
174
175 tcg_gen_movi_tl(t0, 0x7fffffff);
176 tcg_gen_movcond_tl(TCG_COND_GT, tdest, tdest, t0, t0, tdest);
177 tcg_gen_movi_tl(t0, -0x80000000LL);
178 tcg_gen_movcond_tl(TCG_COND_LT, tdest, tdest, t0, t0, tdest);
179
180 tcg_temp_free(t0);
181}
182
7f41a8d6
RH
183/* Shift the 128-bit value TSRCA:TSRCD right by the number of bytes
184 specified by the bottom 3 bits of TSRCB, and set TDEST to the
185 low 64 bits of the resulting value. */
186static void gen_dblalign(TCGv tdest, TCGv tsrcd, TCGv tsrca, TCGv tsrcb)
187{
188 TCGv t0 = tcg_temp_new();
189
190 tcg_gen_andi_tl(t0, tsrcb, 7);
191 tcg_gen_shli_tl(t0, t0, 3);
192 tcg_gen_shr_tl(tdest, tsrcd, t0);
193
194 /* We want to do "t0 = tsrca << (64 - t0)". Two's complement
195 arithmetic on a 6-bit field tells us that 64 - t0 is equal
196 to (t0 ^ 63) + 1. So we can do the shift in two parts,
197 neither of which will be an invalid shift by 64. */
198 tcg_gen_xori_tl(t0, t0, 63);
199 tcg_gen_shl_tl(t0, tsrca, t0);
200 tcg_gen_shli_tl(t0, t0, 1);
201 tcg_gen_or_tl(tdest, tdest, t0);
202
203 tcg_temp_free(t0);
204}
205
206/* Similarly, except that the 128-bit value is TSRCA:TSRCB, and the
207 right shift is an immediate. */
208static void gen_dblaligni(TCGv tdest, TCGv tsrca, TCGv tsrcb, int shr)
209{
210 TCGv t0 = tcg_temp_new();
211
212 tcg_gen_shri_tl(t0, tsrcb, shr);
213 tcg_gen_shli_tl(tdest, tsrca, 64 - shr);
214 tcg_gen_or_tl(tdest, tdest, t0);
215
216 tcg_temp_free(t0);
217}
218
4ff49775
RH
219typedef enum {
220 LU, LS, HU, HS
221} MulHalf;
222
223static void gen_ext_half(TCGv d, TCGv s, MulHalf h)
224{
225 switch (h) {
226 case LU:
227 tcg_gen_ext32u_tl(d, s);
228 break;
229 case LS:
230 tcg_gen_ext32s_tl(d, s);
231 break;
232 case HU:
233 tcg_gen_shri_tl(d, s, 32);
234 break;
235 case HS:
236 tcg_gen_sari_tl(d, s, 32);
237 break;
238 }
239}
240
241static void gen_mul_half(TCGv tdest, TCGv tsrca, TCGv tsrcb,
242 MulHalf ha, MulHalf hb)
243{
244 TCGv t = tcg_temp_new();
245 gen_ext_half(t, tsrca, ha);
246 gen_ext_half(tdest, tsrcb, hb);
247 tcg_gen_mul_tl(tdest, tdest, t);
248 tcg_temp_free(t);
249}
250
e7346cf0
RH
251/* Equality comparison with zero can be done quickly and efficiently. */
252static void gen_v1cmpeq0(TCGv v)
253{
254 TCGv m = tcg_const_tl(V1_IMM(0x7f));
255 TCGv c = tcg_temp_new();
256
257 /* ~(((v & m) + m) | m | v). Sets the msb for each byte == 0. */
258 tcg_gen_and_tl(c, v, m);
259 tcg_gen_add_tl(c, c, m);
260 tcg_gen_or_tl(c, c, m);
261 tcg_gen_nor_tl(c, c, v);
262 tcg_temp_free(m);
263
264 /* Shift the msb down to form the lsb boolean result. */
265 tcg_gen_shri_tl(v, c, 7);
266 tcg_temp_free(c);
267}
268
269static void gen_v1cmpne0(TCGv v)
270{
271 TCGv m = tcg_const_tl(V1_IMM(0x7f));
272 TCGv c = tcg_temp_new();
273
274 /* (((v & m) + m) | v) & ~m. Sets the msb for each byte != 0. */
275 tcg_gen_and_tl(c, v, m);
276 tcg_gen_add_tl(c, c, m);
277 tcg_gen_or_tl(c, c, v);
278 tcg_gen_andc_tl(c, c, m);
279 tcg_temp_free(m);
280
281 /* Shift the msb down to form the lsb boolean result. */
282 tcg_gen_shri_tl(v, c, 7);
283 tcg_temp_free(c);
284}
285
0426335d
RH
286static TileExcp gen_st_opcode(DisasContext *dc, unsigned dest, unsigned srca,
287 unsigned srcb, TCGMemOp memop, const char *name)
288{
289 if (dest) {
290 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
291 }
292
293 tcg_gen_qemu_st_tl(load_gr(dc, srcb), load_gr(dc, srca),
294 dc->mmuidx, memop);
295
296 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s", name,
297 reg_names[srca], reg_names[srcb]);
298 return TILEGX_EXCP_NONE;
299}
7f41a8d6 300
01cd675c
RH
301static TileExcp gen_st_add_opcode(DisasContext *dc, unsigned srca, unsigned srcb,
302 int imm, TCGMemOp memop, const char *name)
303{
304 TCGv tsrca = load_gr(dc, srca);
305 TCGv tsrcb = load_gr(dc, srcb);
306
307 tcg_gen_qemu_st_tl(tsrcb, tsrca, dc->mmuidx, memop);
308 tcg_gen_addi_tl(dest_gr(dc, srca), tsrca, imm);
309
310 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s, %d", name,
311 reg_names[srca], reg_names[srcb], imm);
312 return TILEGX_EXCP_NONE;
313}
314
8fd29dd7
RH
315static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
316 unsigned dest, unsigned srca)
317{
a9fdfc7e 318 TCGv tdest, tsrca;
8fd29dd7 319 const char *mnemonic;
0426335d 320 TCGMemOp memop;
d5dbd6eb 321 TileExcp ret = TILEGX_EXCP_NONE;
8fd29dd7 322
d5dbd6eb 323 /* Eliminate instructions with no output before doing anything else. */
8fd29dd7
RH
324 switch (opext) {
325 case OE_RR_Y0(NOP):
326 case OE_RR_Y1(NOP):
327 case OE_RR_X0(NOP):
328 case OE_RR_X1(NOP):
329 mnemonic = "nop";
d5dbd6eb 330 goto done0;
8fd29dd7
RH
331 case OE_RR_Y0(FNOP):
332 case OE_RR_Y1(FNOP):
333 case OE_RR_X0(FNOP):
334 case OE_RR_X1(FNOP):
335 mnemonic = "fnop";
d5dbd6eb
RH
336 goto done0;
337 case OE_RR_X1(DRAIN):
338 mnemonic = "drain";
339 goto done0;
340 case OE_RR_X1(FLUSHWB):
341 mnemonic = "flushwb";
342 goto done0;
343 case OE_RR_X1(ILL):
344 case OE_RR_Y1(ILL):
345 mnemonic = (dest == 0x1c && srca == 0x25 ? "bpt" : "ill");
346 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s", mnemonic);
347 return TILEGX_EXCP_OPCODE_UNKNOWN;
348 case OE_RR_X1(MF):
349 mnemonic = "mf";
350 goto done0;
351 case OE_RR_X1(NAP):
352 /* ??? This should yield, especially in system mode. */
353 mnemonic = "nap";
354 goto done0;
355 case OE_RR_X1(SWINT0):
356 case OE_RR_X1(SWINT2):
357 case OE_RR_X1(SWINT3):
358 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
359 case OE_RR_X1(SWINT1):
360 ret = TILEGX_EXCP_SYSCALL;
361 mnemonic = "swint1";
362 done0:
8fd29dd7
RH
363 if (srca || dest) {
364 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
365 }
366 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s", mnemonic);
d5dbd6eb 367 return ret;
c230a994 368
d5dbd6eb
RH
369 case OE_RR_X1(DTLBPR):
370 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
371 case OE_RR_X1(FINV):
372 mnemonic = "finv";
373 goto done1;
374 case OE_RR_X1(FLUSH):
375 mnemonic = "flush";
376 goto done1;
377 case OE_RR_X1(ICOH):
378 mnemonic = "icoh";
379 goto done1;
380 case OE_RR_X1(INV):
381 mnemonic = "inv";
382 goto done1;
383 case OE_RR_X1(WH64):
384 mnemonic = "wh64";
385 goto done1;
c230a994
RH
386 case OE_RR_X1(JRP):
387 case OE_RR_Y1(JRP):
388 mnemonic = "jrp";
389 goto do_jr;
390 case OE_RR_X1(JR):
391 case OE_RR_Y1(JR):
392 mnemonic = "jr";
393 goto do_jr;
394 case OE_RR_X1(JALRP):
395 case OE_RR_Y1(JALRP):
396 mnemonic = "jalrp";
397 goto do_jalr;
398 case OE_RR_X1(JALR):
399 case OE_RR_Y1(JALR):
400 mnemonic = "jalr";
401 do_jalr:
402 tcg_gen_movi_tl(dest_gr(dc, TILEGX_R_LR),
403 dc->pc + TILEGX_BUNDLE_SIZE_IN_BYTES);
404 do_jr:
405 dc->jmp.cond = TCG_COND_ALWAYS;
406 dc->jmp.dest = tcg_temp_new();
407 tcg_gen_andi_tl(dc->jmp.dest, load_gr(dc, srca), ~7);
d5dbd6eb
RH
408 done1:
409 if (dest) {
410 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
411 }
c230a994 412 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s", mnemonic, reg_names[srca]);
d5dbd6eb 413 return ret;
8fd29dd7
RH
414 }
415
a9fdfc7e
RH
416 tdest = dest_gr(dc, dest);
417 tsrca = load_gr(dc, srca);
418
8fd29dd7
RH
419 switch (opext) {
420 case OE_RR_X0(CNTLZ):
421 case OE_RR_Y0(CNTLZ):
7f41a8d6
RH
422 gen_helper_cntlz(tdest, tsrca);
423 mnemonic = "cntlz";
424 break;
8fd29dd7
RH
425 case OE_RR_X0(CNTTZ):
426 case OE_RR_Y0(CNTTZ):
7f41a8d6
RH
427 gen_helper_cnttz(tdest, tsrca);
428 mnemonic = "cnttz";
429 break;
8fd29dd7
RH
430 case OE_RR_X0(FSINGLE_PACK1):
431 case OE_RR_Y0(FSINGLE_PACK1):
8fd29dd7 432 case OE_RR_X1(IRET):
0426335d 433 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
8fd29dd7 434 case OE_RR_X1(LD1S):
0426335d
RH
435 memop = MO_SB;
436 mnemonic = "ld1s";
437 goto do_load;
8fd29dd7 438 case OE_RR_X1(LD1U):
0426335d
RH
439 memop = MO_UB;
440 mnemonic = "ld1u";
441 goto do_load;
8fd29dd7 442 case OE_RR_X1(LD2S):
0426335d
RH
443 memop = MO_TESW;
444 mnemonic = "ld2s";
445 goto do_load;
8fd29dd7 446 case OE_RR_X1(LD2U):
0426335d
RH
447 memop = MO_TEUW;
448 mnemonic = "ld2u";
449 goto do_load;
8fd29dd7 450 case OE_RR_X1(LD4S):
0426335d
RH
451 memop = MO_TESL;
452 mnemonic = "ld4s";
453 goto do_load;
8fd29dd7 454 case OE_RR_X1(LD4U):
0426335d
RH
455 memop = MO_TEUL;
456 mnemonic = "ld4u";
457 goto do_load;
8fd29dd7 458 case OE_RR_X1(LDNT1S):
0426335d
RH
459 memop = MO_SB;
460 mnemonic = "ldnt1s";
461 goto do_load;
8fd29dd7 462 case OE_RR_X1(LDNT1U):
0426335d
RH
463 memop = MO_UB;
464 mnemonic = "ldnt1u";
465 goto do_load;
8fd29dd7 466 case OE_RR_X1(LDNT2S):
0426335d
RH
467 memop = MO_TESW;
468 mnemonic = "ldnt2s";
469 goto do_load;
8fd29dd7 470 case OE_RR_X1(LDNT2U):
0426335d
RH
471 memop = MO_TEUW;
472 mnemonic = "ldnt2u";
473 goto do_load;
8fd29dd7 474 case OE_RR_X1(LDNT4S):
0426335d
RH
475 memop = MO_TESL;
476 mnemonic = "ldnt4s";
477 goto do_load;
8fd29dd7 478 case OE_RR_X1(LDNT4U):
0426335d
RH
479 memop = MO_TEUL;
480 mnemonic = "ldnt4u";
481 goto do_load;
8fd29dd7 482 case OE_RR_X1(LDNT):
0426335d
RH
483 memop = MO_TEQ;
484 mnemonic = "ldnt";
485 goto do_load;
8fd29dd7 486 case OE_RR_X1(LD):
0426335d
RH
487 memop = MO_TEQ;
488 mnemonic = "ld";
489 do_load:
490 tcg_gen_qemu_ld_tl(tdest, tsrca, dc->mmuidx, memop);
491 break;
492 case OE_RR_X1(LDNA):
493 tcg_gen_andi_tl(tdest, tsrca, ~7);
494 tcg_gen_qemu_ld_tl(tdest, tdest, dc->mmuidx, MO_TEQ);
495 mnemonic = "ldna";
496 break;
8fd29dd7
RH
497 case OE_RR_X1(LNK):
498 case OE_RR_Y1(LNK):
c230a994
RH
499 if (srca) {
500 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
501 }
502 tcg_gen_movi_tl(tdest, dc->pc + TILEGX_BUNDLE_SIZE_IN_BYTES);
503 mnemonic = "lnk";
504 break;
8fd29dd7
RH
505 case OE_RR_X0(PCNT):
506 case OE_RR_Y0(PCNT):
7f41a8d6
RH
507 gen_helper_pcnt(tdest, tsrca);
508 mnemonic = "pcnt";
509 break;
8fd29dd7
RH
510 case OE_RR_X0(REVBITS):
511 case OE_RR_Y0(REVBITS):
7f41a8d6
RH
512 gen_helper_revbits(tdest, tsrca);
513 mnemonic = "revbits";
514 break;
8fd29dd7
RH
515 case OE_RR_X0(REVBYTES):
516 case OE_RR_Y0(REVBYTES):
a9fdfc7e
RH
517 tcg_gen_bswap64_tl(tdest, tsrca);
518 mnemonic = "revbytes";
519 break;
8fd29dd7
RH
520 case OE_RR_X0(TBLIDXB0):
521 case OE_RR_Y0(TBLIDXB0):
522 case OE_RR_X0(TBLIDXB1):
523 case OE_RR_Y0(TBLIDXB1):
524 case OE_RR_X0(TBLIDXB2):
525 case OE_RR_Y0(TBLIDXB2):
526 case OE_RR_X0(TBLIDXB3):
527 case OE_RR_Y0(TBLIDXB3):
8fd29dd7
RH
528 default:
529 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
530 }
531
532 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s", mnemonic,
533 reg_names[dest], reg_names[srca]);
d5dbd6eb 534 return ret;
8fd29dd7
RH
535}
536
537static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext,
538 unsigned dest, unsigned srca, unsigned srcb)
539{
a9fdfc7e
RH
540 TCGv tdest = dest_gr(dc, dest);
541 TCGv tsrca = load_gr(dc, srca);
542 TCGv tsrcb = load_gr(dc, srcb);
2369976d 543 TCGv t0;
8fd29dd7
RH
544 const char *mnemonic;
545
546 switch (opext) {
547 case OE_RRR(ADDXSC, 0, X0):
548 case OE_RRR(ADDXSC, 0, X1):
89b8c750
RH
549 gen_saturate_op(tdest, tsrca, tsrcb, tcg_gen_add_tl);
550 mnemonic = "addxsc";
551 break;
8fd29dd7
RH
552 case OE_RRR(ADDX, 0, X0):
553 case OE_RRR(ADDX, 0, X1):
554 case OE_RRR(ADDX, 0, Y0):
555 case OE_RRR(ADDX, 0, Y1):
89b8c750
RH
556 tcg_gen_add_tl(tdest, tsrca, tsrcb);
557 tcg_gen_ext32s_tl(tdest, tdest);
558 mnemonic = "addx";
559 break;
8fd29dd7
RH
560 case OE_RRR(ADD, 0, X0):
561 case OE_RRR(ADD, 0, X1):
562 case OE_RRR(ADD, 0, Y0):
563 case OE_RRR(ADD, 0, Y1):
89b8c750
RH
564 tcg_gen_add_tl(tdest, tsrca, tsrcb);
565 mnemonic = "add";
566 break;
8fd29dd7
RH
567 case OE_RRR(AND, 0, X0):
568 case OE_RRR(AND, 0, X1):
569 case OE_RRR(AND, 5, Y0):
570 case OE_RRR(AND, 5, Y1):
a9fdfc7e
RH
571 tcg_gen_and_tl(tdest, tsrca, tsrcb);
572 mnemonic = "and";
573 break;
8fd29dd7
RH
574 case OE_RRR(CMOVEQZ, 0, X0):
575 case OE_RRR(CMOVEQZ, 4, Y0):
f090f9f7
RH
576 tcg_gen_movcond_tl(TCG_COND_EQ, tdest, tsrca, load_zero(dc),
577 tsrcb, load_gr(dc, dest));
578 mnemonic = "cmoveqz";
579 break;
8fd29dd7
RH
580 case OE_RRR(CMOVNEZ, 0, X0):
581 case OE_RRR(CMOVNEZ, 4, Y0):
f090f9f7
RH
582 tcg_gen_movcond_tl(TCG_COND_NE, tdest, tsrca, load_zero(dc),
583 tsrcb, load_gr(dc, dest));
584 mnemonic = "cmovnez";
585 break;
8fd29dd7
RH
586 case OE_RRR(CMPEQ, 0, X0):
587 case OE_RRR(CMPEQ, 0, X1):
588 case OE_RRR(CMPEQ, 3, Y0):
589 case OE_RRR(CMPEQ, 3, Y1):
73c54377
RH
590 tcg_gen_setcond_tl(TCG_COND_EQ, tdest, tsrca, tsrcb);
591 mnemonic = "cmpeq";
592 break;
8fd29dd7
RH
593 case OE_RRR(CMPEXCH4, 0, X1):
594 case OE_RRR(CMPEXCH, 0, X1):
73c54377 595 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
8fd29dd7
RH
596 case OE_RRR(CMPLES, 0, X0):
597 case OE_RRR(CMPLES, 0, X1):
598 case OE_RRR(CMPLES, 2, Y0):
599 case OE_RRR(CMPLES, 2, Y1):
73c54377
RH
600 tcg_gen_setcond_tl(TCG_COND_LE, tdest, tsrca, tsrcb);
601 mnemonic = "cmples";
602 break;
8fd29dd7
RH
603 case OE_RRR(CMPLEU, 0, X0):
604 case OE_RRR(CMPLEU, 0, X1):
605 case OE_RRR(CMPLEU, 2, Y0):
606 case OE_RRR(CMPLEU, 2, Y1):
73c54377
RH
607 tcg_gen_setcond_tl(TCG_COND_LEU, tdest, tsrca, tsrcb);
608 mnemonic = "cmpleu";
609 break;
8fd29dd7
RH
610 case OE_RRR(CMPLTS, 0, X0):
611 case OE_RRR(CMPLTS, 0, X1):
612 case OE_RRR(CMPLTS, 2, Y0):
613 case OE_RRR(CMPLTS, 2, Y1):
73c54377
RH
614 tcg_gen_setcond_tl(TCG_COND_LT, tdest, tsrca, tsrcb);
615 mnemonic = "cmplts";
616 break;
8fd29dd7
RH
617 case OE_RRR(CMPLTU, 0, X0):
618 case OE_RRR(CMPLTU, 0, X1):
619 case OE_RRR(CMPLTU, 2, Y0):
620 case OE_RRR(CMPLTU, 2, Y1):
73c54377
RH
621 tcg_gen_setcond_tl(TCG_COND_LTU, tdest, tsrca, tsrcb);
622 mnemonic = "cmpltu";
623 break;
8fd29dd7
RH
624 case OE_RRR(CMPNE, 0, X0):
625 case OE_RRR(CMPNE, 0, X1):
626 case OE_RRR(CMPNE, 3, Y0):
627 case OE_RRR(CMPNE, 3, Y1):
73c54377
RH
628 tcg_gen_setcond_tl(TCG_COND_NE, tdest, tsrca, tsrcb);
629 mnemonic = "cmpne";
630 break;
8fd29dd7
RH
631 case OE_RRR(CMULAF, 0, X0):
632 case OE_RRR(CMULA, 0, X0):
633 case OE_RRR(CMULFR, 0, X0):
634 case OE_RRR(CMULF, 0, X0):
635 case OE_RRR(CMULHR, 0, X0):
636 case OE_RRR(CMULH, 0, X0):
637 case OE_RRR(CMUL, 0, X0):
638 case OE_RRR(CRC32_32, 0, X0):
639 case OE_RRR(CRC32_8, 0, X0):
7f41a8d6 640 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
8fd29dd7
RH
641 case OE_RRR(DBLALIGN2, 0, X0):
642 case OE_RRR(DBLALIGN2, 0, X1):
7f41a8d6
RH
643 gen_dblaligni(tdest, tsrca, tsrcb, 16);
644 mnemonic = "dblalign2";
645 break;
8fd29dd7
RH
646 case OE_RRR(DBLALIGN4, 0, X0):
647 case OE_RRR(DBLALIGN4, 0, X1):
7f41a8d6
RH
648 gen_dblaligni(tdest, tsrca, tsrcb, 32);
649 mnemonic = "dblalign4";
650 break;
8fd29dd7
RH
651 case OE_RRR(DBLALIGN6, 0, X0):
652 case OE_RRR(DBLALIGN6, 0, X1):
7f41a8d6
RH
653 gen_dblaligni(tdest, tsrca, tsrcb, 48);
654 mnemonic = "dblalign6";
655 break;
8fd29dd7 656 case OE_RRR(DBLALIGN, 0, X0):
7f41a8d6
RH
657 gen_dblalign(tdest, load_gr(dc, dest), tsrca, tsrcb);
658 mnemonic = "dblalign";
659 break;
8fd29dd7
RH
660 case OE_RRR(EXCH4, 0, X1):
661 case OE_RRR(EXCH, 0, X1):
662 case OE_RRR(FDOUBLE_ADDSUB, 0, X0):
663 case OE_RRR(FDOUBLE_ADD_FLAGS, 0, X0):
664 case OE_RRR(FDOUBLE_MUL_FLAGS, 0, X0):
665 case OE_RRR(FDOUBLE_PACK1, 0, X0):
666 case OE_RRR(FDOUBLE_PACK2, 0, X0):
667 case OE_RRR(FDOUBLE_SUB_FLAGS, 0, X0):
668 case OE_RRR(FDOUBLE_UNPACK_MAX, 0, X0):
669 case OE_RRR(FDOUBLE_UNPACK_MIN, 0, X0):
670 case OE_RRR(FETCHADD4, 0, X1):
671 case OE_RRR(FETCHADDGEZ4, 0, X1):
672 case OE_RRR(FETCHADDGEZ, 0, X1):
673 case OE_RRR(FETCHADD, 0, X1):
674 case OE_RRR(FETCHAND4, 0, X1):
675 case OE_RRR(FETCHAND, 0, X1):
676 case OE_RRR(FETCHOR4, 0, X1):
677 case OE_RRR(FETCHOR, 0, X1):
678 case OE_RRR(FSINGLE_ADD1, 0, X0):
679 case OE_RRR(FSINGLE_ADDSUB2, 0, X0):
680 case OE_RRR(FSINGLE_MUL1, 0, X0):
681 case OE_RRR(FSINGLE_MUL2, 0, X0):
682 case OE_RRR(FSINGLE_PACK2, 0, X0):
683 case OE_RRR(FSINGLE_SUB1, 0, X0):
661ff743 684 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
8fd29dd7
RH
685 case OE_RRR(MNZ, 0, X0):
686 case OE_RRR(MNZ, 0, X1):
687 case OE_RRR(MNZ, 4, Y0):
688 case OE_RRR(MNZ, 4, Y1):
661ff743
RH
689 t0 = load_zero(dc);
690 tcg_gen_movcond_tl(TCG_COND_NE, tdest, tsrca, t0, tsrcb, t0);
691 mnemonic = "mnz";
692 break;
8fd29dd7
RH
693 case OE_RRR(MULAX, 0, X0):
694 case OE_RRR(MULAX, 3, Y0):
4ff49775
RH
695 tcg_gen_mul_tl(tdest, tsrca, tsrcb);
696 tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
697 tcg_gen_ext32s_tl(tdest, tdest);
698 mnemonic = "mulax";
699 break;
8fd29dd7
RH
700 case OE_RRR(MULA_HS_HS, 0, X0):
701 case OE_RRR(MULA_HS_HS, 9, Y0):
4ff49775
RH
702 gen_mul_half(tdest, tsrca, tsrcb, HS, HS);
703 tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
704 mnemonic = "mula_hs_hs";
705 break;
8fd29dd7 706 case OE_RRR(MULA_HS_HU, 0, X0):
4ff49775
RH
707 gen_mul_half(tdest, tsrca, tsrcb, HS, HU);
708 tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
709 mnemonic = "mula_hs_hu";
710 break;
8fd29dd7 711 case OE_RRR(MULA_HS_LS, 0, X0):
4ff49775
RH
712 gen_mul_half(tdest, tsrca, tsrcb, HS, LS);
713 tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
714 mnemonic = "mula_hs_ls";
715 break;
8fd29dd7 716 case OE_RRR(MULA_HS_LU, 0, X0):
4ff49775
RH
717 gen_mul_half(tdest, tsrca, tsrcb, HS, LU);
718 tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
719 mnemonic = "mula_hs_lu";
720 break;
8fd29dd7
RH
721 case OE_RRR(MULA_HU_HU, 0, X0):
722 case OE_RRR(MULA_HU_HU, 9, Y0):
4ff49775
RH
723 gen_mul_half(tdest, tsrca, tsrcb, HU, HU);
724 tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
725 mnemonic = "mula_hu_hu";
726 break;
8fd29dd7 727 case OE_RRR(MULA_HU_LS, 0, X0):
4ff49775
RH
728 gen_mul_half(tdest, tsrca, tsrcb, HU, LS);
729 tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
730 mnemonic = "mula_hu_ls";
731 break;
8fd29dd7 732 case OE_RRR(MULA_HU_LU, 0, X0):
4ff49775
RH
733 gen_mul_half(tdest, tsrca, tsrcb, HU, LU);
734 tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
735 mnemonic = "mula_hu_lu";
736 break;
8fd29dd7
RH
737 case OE_RRR(MULA_LS_LS, 0, X0):
738 case OE_RRR(MULA_LS_LS, 9, Y0):
4ff49775
RH
739 gen_mul_half(tdest, tsrca, tsrcb, LS, LS);
740 tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
741 mnemonic = "mula_ls_ls";
742 break;
8fd29dd7 743 case OE_RRR(MULA_LS_LU, 0, X0):
4ff49775
RH
744 gen_mul_half(tdest, tsrca, tsrcb, LS, LU);
745 tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
746 mnemonic = "mula_ls_lu";
747 break;
8fd29dd7
RH
748 case OE_RRR(MULA_LU_LU, 0, X0):
749 case OE_RRR(MULA_LU_LU, 9, Y0):
4ff49775
RH
750 gen_mul_half(tdest, tsrca, tsrcb, LU, LU);
751 tcg_gen_add_tl(tdest, tdest, load_gr(dc, dest));
752 mnemonic = "mula_lu_lu";
753 break;
8fd29dd7
RH
754 case OE_RRR(MULX, 0, X0):
755 case OE_RRR(MULX, 3, Y0):
4ff49775
RH
756 tcg_gen_mul_tl(tdest, tsrca, tsrcb);
757 tcg_gen_ext32s_tl(tdest, tdest);
758 mnemonic = "mulx";
759 break;
8fd29dd7
RH
760 case OE_RRR(MUL_HS_HS, 0, X0):
761 case OE_RRR(MUL_HS_HS, 8, Y0):
4ff49775
RH
762 gen_mul_half(tdest, tsrca, tsrcb, HS, HS);
763 mnemonic = "mul_hs_hs";
764 break;
8fd29dd7 765 case OE_RRR(MUL_HS_HU, 0, X0):
4ff49775
RH
766 gen_mul_half(tdest, tsrca, tsrcb, HS, HU);
767 mnemonic = "mul_hs_hu";
768 break;
8fd29dd7 769 case OE_RRR(MUL_HS_LS, 0, X0):
4ff49775
RH
770 gen_mul_half(tdest, tsrca, tsrcb, HS, LS);
771 mnemonic = "mul_hs_ls";
772 break;
8fd29dd7 773 case OE_RRR(MUL_HS_LU, 0, X0):
4ff49775
RH
774 gen_mul_half(tdest, tsrca, tsrcb, HS, LU);
775 mnemonic = "mul_hs_lu";
776 break;
8fd29dd7
RH
777 case OE_RRR(MUL_HU_HU, 0, X0):
778 case OE_RRR(MUL_HU_HU, 8, Y0):
4ff49775
RH
779 gen_mul_half(tdest, tsrca, tsrcb, HU, HU);
780 mnemonic = "mul_hu_hu";
781 break;
8fd29dd7 782 case OE_RRR(MUL_HU_LS, 0, X0):
4ff49775
RH
783 gen_mul_half(tdest, tsrca, tsrcb, HU, LS);
784 mnemonic = "mul_hu_ls";
785 break;
8fd29dd7 786 case OE_RRR(MUL_HU_LU, 0, X0):
4ff49775
RH
787 gen_mul_half(tdest, tsrca, tsrcb, HU, LU);
788 mnemonic = "mul_hu_lu";
789 break;
8fd29dd7
RH
790 case OE_RRR(MUL_LS_LS, 0, X0):
791 case OE_RRR(MUL_LS_LS, 8, Y0):
4ff49775
RH
792 gen_mul_half(tdest, tsrca, tsrcb, LS, LS);
793 mnemonic = "mul_ls_ls";
794 break;
8fd29dd7 795 case OE_RRR(MUL_LS_LU, 0, X0):
4ff49775
RH
796 gen_mul_half(tdest, tsrca, tsrcb, LS, LU);
797 mnemonic = "mul_ls_lu";
798 break;
8fd29dd7
RH
799 case OE_RRR(MUL_LU_LU, 0, X0):
800 case OE_RRR(MUL_LU_LU, 8, Y0):
4ff49775
RH
801 gen_mul_half(tdest, tsrca, tsrcb, LU, LU);
802 mnemonic = "mul_lu_lu";
803 break;
8fd29dd7
RH
804 case OE_RRR(MZ, 0, X0):
805 case OE_RRR(MZ, 0, X1):
806 case OE_RRR(MZ, 4, Y0):
807 case OE_RRR(MZ, 4, Y1):
661ff743
RH
808 t0 = load_zero(dc);
809 tcg_gen_movcond_tl(TCG_COND_EQ, tdest, tsrca, t0, tsrcb, t0);
810 mnemonic = "mz";
811 break;
8fd29dd7
RH
812 case OE_RRR(NOR, 0, X0):
813 case OE_RRR(NOR, 0, X1):
814 case OE_RRR(NOR, 5, Y0):
815 case OE_RRR(NOR, 5, Y1):
a9fdfc7e
RH
816 tcg_gen_nor_tl(tdest, tsrca, tsrcb);
817 mnemonic = "nor";
818 break;
8fd29dd7
RH
819 case OE_RRR(OR, 0, X0):
820 case OE_RRR(OR, 0, X1):
821 case OE_RRR(OR, 5, Y0):
822 case OE_RRR(OR, 5, Y1):
a9fdfc7e
RH
823 tcg_gen_or_tl(tdest, tsrca, tsrcb);
824 mnemonic = "or";
825 break;
8fd29dd7
RH
826 case OE_RRR(ROTL, 0, X0):
827 case OE_RRR(ROTL, 0, X1):
828 case OE_RRR(ROTL, 6, Y0):
829 case OE_RRR(ROTL, 6, Y1):
2369976d
RH
830 tcg_gen_andi_tl(tdest, tsrcb, 63);
831 tcg_gen_rotl_tl(tdest, tsrca, tdest);
832 mnemonic = "rotl";
833 break;
8fd29dd7
RH
834 case OE_RRR(SHL1ADDX, 0, X0):
835 case OE_RRR(SHL1ADDX, 0, X1):
836 case OE_RRR(SHL1ADDX, 7, Y0):
837 case OE_RRR(SHL1ADDX, 7, Y1):
89b8c750
RH
838 tcg_gen_shli_tl(tdest, tsrca, 1);
839 tcg_gen_add_tl(tdest, tdest, tsrcb);
840 tcg_gen_ext32s_tl(tdest, tdest);
841 mnemonic = "shl1addx";
842 break;
8fd29dd7
RH
843 case OE_RRR(SHL1ADD, 0, X0):
844 case OE_RRR(SHL1ADD, 0, X1):
845 case OE_RRR(SHL1ADD, 1, Y0):
846 case OE_RRR(SHL1ADD, 1, Y1):
89b8c750
RH
847 tcg_gen_shli_tl(tdest, tsrca, 1);
848 tcg_gen_add_tl(tdest, tdest, tsrcb);
849 mnemonic = "shl1add";
850 break;
8fd29dd7
RH
851 case OE_RRR(SHL2ADDX, 0, X0):
852 case OE_RRR(SHL2ADDX, 0, X1):
853 case OE_RRR(SHL2ADDX, 7, Y0):
854 case OE_RRR(SHL2ADDX, 7, Y1):
89b8c750
RH
855 tcg_gen_shli_tl(tdest, tsrca, 2);
856 tcg_gen_add_tl(tdest, tdest, tsrcb);
857 tcg_gen_ext32s_tl(tdest, tdest);
858 mnemonic = "shl2addx";
859 break;
8fd29dd7
RH
860 case OE_RRR(SHL2ADD, 0, X0):
861 case OE_RRR(SHL2ADD, 0, X1):
862 case OE_RRR(SHL2ADD, 1, Y0):
863 case OE_RRR(SHL2ADD, 1, Y1):
89b8c750
RH
864 tcg_gen_shli_tl(tdest, tsrca, 2);
865 tcg_gen_add_tl(tdest, tdest, tsrcb);
866 mnemonic = "shl2add";
867 break;
8fd29dd7
RH
868 case OE_RRR(SHL3ADDX, 0, X0):
869 case OE_RRR(SHL3ADDX, 0, X1):
870 case OE_RRR(SHL3ADDX, 7, Y0):
871 case OE_RRR(SHL3ADDX, 7, Y1):
89b8c750
RH
872 tcg_gen_shli_tl(tdest, tsrca, 3);
873 tcg_gen_add_tl(tdest, tdest, tsrcb);
874 tcg_gen_ext32s_tl(tdest, tdest);
875 mnemonic = "shl3addx";
876 break;
8fd29dd7
RH
877 case OE_RRR(SHL3ADD, 0, X0):
878 case OE_RRR(SHL3ADD, 0, X1):
879 case OE_RRR(SHL3ADD, 1, Y0):
880 case OE_RRR(SHL3ADD, 1, Y1):
89b8c750
RH
881 tcg_gen_shli_tl(tdest, tsrca, 3);
882 tcg_gen_add_tl(tdest, tdest, tsrcb);
883 mnemonic = "shl3add";
884 break;
8fd29dd7
RH
885 case OE_RRR(SHLX, 0, X0):
886 case OE_RRR(SHLX, 0, X1):
2369976d
RH
887 tcg_gen_andi_tl(tdest, tsrcb, 31);
888 tcg_gen_shl_tl(tdest, tsrca, tdest);
889 tcg_gen_ext32s_tl(tdest, tdest);
890 mnemonic = "shlx";
891 break;
8fd29dd7
RH
892 case OE_RRR(SHL, 0, X0):
893 case OE_RRR(SHL, 0, X1):
894 case OE_RRR(SHL, 6, Y0):
895 case OE_RRR(SHL, 6, Y1):
2369976d
RH
896 tcg_gen_andi_tl(tdest, tsrcb, 63);
897 tcg_gen_shl_tl(tdest, tsrca, tdest);
898 mnemonic = "shl";
899 break;
8fd29dd7
RH
900 case OE_RRR(SHRS, 0, X0):
901 case OE_RRR(SHRS, 0, X1):
902 case OE_RRR(SHRS, 6, Y0):
903 case OE_RRR(SHRS, 6, Y1):
2369976d
RH
904 tcg_gen_andi_tl(tdest, tsrcb, 63);
905 tcg_gen_sar_tl(tdest, tsrca, tdest);
906 mnemonic = "shrs";
907 break;
8fd29dd7
RH
908 case OE_RRR(SHRUX, 0, X0):
909 case OE_RRR(SHRUX, 0, X1):
2369976d
RH
910 t0 = tcg_temp_new();
911 tcg_gen_andi_tl(t0, tsrcb, 31);
912 tcg_gen_ext32u_tl(tdest, tsrca);
913 tcg_gen_shr_tl(tdest, tdest, t0);
914 tcg_gen_ext32s_tl(tdest, tdest);
915 tcg_temp_free(t0);
916 mnemonic = "shrux";
917 break;
8fd29dd7
RH
918 case OE_RRR(SHRU, 0, X0):
919 case OE_RRR(SHRU, 0, X1):
920 case OE_RRR(SHRU, 6, Y0):
921 case OE_RRR(SHRU, 6, Y1):
2369976d
RH
922 tcg_gen_andi_tl(tdest, tsrcb, 63);
923 tcg_gen_shr_tl(tdest, tsrca, tdest);
924 mnemonic = "shru";
925 break;
8fd29dd7 926 case OE_RRR(SHUFFLEBYTES, 0, X0):
7f41a8d6
RH
927 gen_helper_shufflebytes(tdest, load_gr(dc, dest), tsrca, tsrca);
928 mnemonic = "shufflebytes";
929 break;
8fd29dd7
RH
930 case OE_RRR(SUBXSC, 0, X0):
931 case OE_RRR(SUBXSC, 0, X1):
89b8c750
RH
932 gen_saturate_op(tdest, tsrca, tsrcb, tcg_gen_sub_tl);
933 mnemonic = "subxsc";
934 break;
8fd29dd7
RH
935 case OE_RRR(SUBX, 0, X0):
936 case OE_RRR(SUBX, 0, X1):
937 case OE_RRR(SUBX, 0, Y0):
938 case OE_RRR(SUBX, 0, Y1):
89b8c750
RH
939 tcg_gen_sub_tl(tdest, tsrca, tsrcb);
940 tcg_gen_ext32s_tl(tdest, tdest);
941 mnemonic = "subx";
942 break;
8fd29dd7
RH
943 case OE_RRR(SUB, 0, X0):
944 case OE_RRR(SUB, 0, X1):
945 case OE_RRR(SUB, 0, Y0):
946 case OE_RRR(SUB, 0, Y1):
89b8c750
RH
947 tcg_gen_sub_tl(tdest, tsrca, tsrcb);
948 mnemonic = "sub";
949 break;
8fd29dd7
RH
950 case OE_RRR(V1ADDUC, 0, X0):
951 case OE_RRR(V1ADDUC, 0, X1):
952 case OE_RRR(V1ADD, 0, X0):
953 case OE_RRR(V1ADD, 0, X1):
954 case OE_RRR(V1ADIFFU, 0, X0):
955 case OE_RRR(V1AVGU, 0, X0):
e7346cf0 956 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
8fd29dd7
RH
957 case OE_RRR(V1CMPEQ, 0, X0):
958 case OE_RRR(V1CMPEQ, 0, X1):
e7346cf0
RH
959 tcg_gen_xor_tl(tdest, tsrca, tsrcb);
960 gen_v1cmpeq0(tdest);
961 mnemonic = "v1cmpeq";
962 break;
8fd29dd7
RH
963 case OE_RRR(V1CMPLES, 0, X0):
964 case OE_RRR(V1CMPLES, 0, X1):
965 case OE_RRR(V1CMPLEU, 0, X0):
966 case OE_RRR(V1CMPLEU, 0, X1):
967 case OE_RRR(V1CMPLTS, 0, X0):
968 case OE_RRR(V1CMPLTS, 0, X1):
969 case OE_RRR(V1CMPLTU, 0, X0):
970 case OE_RRR(V1CMPLTU, 0, X1):
e7346cf0 971 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
8fd29dd7
RH
972 case OE_RRR(V1CMPNE, 0, X0):
973 case OE_RRR(V1CMPNE, 0, X1):
e7346cf0
RH
974 tcg_gen_xor_tl(tdest, tsrca, tsrcb);
975 gen_v1cmpne0(tdest);
976 mnemonic = "v1cmpne";
977 break;
8fd29dd7
RH
978 case OE_RRR(V1DDOTPUA, 0, X0):
979 case OE_RRR(V1DDOTPUSA, 0, X0):
980 case OE_RRR(V1DDOTPUS, 0, X0):
981 case OE_RRR(V1DDOTPU, 0, X0):
982 case OE_RRR(V1DOTPA, 0, X0):
983 case OE_RRR(V1DOTPUA, 0, X0):
984 case OE_RRR(V1DOTPUSA, 0, X0):
985 case OE_RRR(V1DOTPUS, 0, X0):
986 case OE_RRR(V1DOTPU, 0, X0):
987 case OE_RRR(V1DOTP, 0, X0):
988 case OE_RRR(V1INT_H, 0, X0):
989 case OE_RRR(V1INT_H, 0, X1):
990 case OE_RRR(V1INT_L, 0, X0):
991 case OE_RRR(V1INT_L, 0, X1):
992 case OE_RRR(V1MAXU, 0, X0):
993 case OE_RRR(V1MAXU, 0, X1):
994 case OE_RRR(V1MINU, 0, X0):
995 case OE_RRR(V1MINU, 0, X1):
996 case OE_RRR(V1MNZ, 0, X0):
997 case OE_RRR(V1MNZ, 0, X1):
998 case OE_RRR(V1MULTU, 0, X0):
999 case OE_RRR(V1MULUS, 0, X0):
1000 case OE_RRR(V1MULU, 0, X0):
1001 case OE_RRR(V1MZ, 0, X0):
1002 case OE_RRR(V1MZ, 0, X1):
1003 case OE_RRR(V1SADAU, 0, X0):
1004 case OE_RRR(V1SADU, 0, X0):
1005 case OE_RRR(V1SHL, 0, X0):
1006 case OE_RRR(V1SHL, 0, X1):
1007 case OE_RRR(V1SHRS, 0, X0):
1008 case OE_RRR(V1SHRS, 0, X1):
1009 case OE_RRR(V1SHRU, 0, X0):
1010 case OE_RRR(V1SHRU, 0, X1):
1011 case OE_RRR(V1SUBUC, 0, X0):
1012 case OE_RRR(V1SUBUC, 0, X1):
1013 case OE_RRR(V1SUB, 0, X0):
1014 case OE_RRR(V1SUB, 0, X1):
1015 case OE_RRR(V2ADDSC, 0, X0):
1016 case OE_RRR(V2ADDSC, 0, X1):
1017 case OE_RRR(V2ADD, 0, X0):
1018 case OE_RRR(V2ADD, 0, X1):
1019 case OE_RRR(V2ADIFFS, 0, X0):
1020 case OE_RRR(V2AVGS, 0, X0):
1021 case OE_RRR(V2CMPEQ, 0, X0):
1022 case OE_RRR(V2CMPEQ, 0, X1):
1023 case OE_RRR(V2CMPLES, 0, X0):
1024 case OE_RRR(V2CMPLES, 0, X1):
1025 case OE_RRR(V2CMPLEU, 0, X0):
1026 case OE_RRR(V2CMPLEU, 0, X1):
1027 case OE_RRR(V2CMPLTS, 0, X0):
1028 case OE_RRR(V2CMPLTS, 0, X1):
1029 case OE_RRR(V2CMPLTU, 0, X0):
1030 case OE_RRR(V2CMPLTU, 0, X1):
1031 case OE_RRR(V2CMPNE, 0, X0):
1032 case OE_RRR(V2CMPNE, 0, X1):
1033 case OE_RRR(V2DOTPA, 0, X0):
1034 case OE_RRR(V2DOTP, 0, X0):
1035 case OE_RRR(V2INT_H, 0, X0):
1036 case OE_RRR(V2INT_H, 0, X1):
1037 case OE_RRR(V2INT_L, 0, X0):
1038 case OE_RRR(V2INT_L, 0, X1):
1039 case OE_RRR(V2MAXS, 0, X0):
1040 case OE_RRR(V2MAXS, 0, X1):
1041 case OE_RRR(V2MINS, 0, X0):
1042 case OE_RRR(V2MINS, 0, X1):
1043 case OE_RRR(V2MNZ, 0, X0):
1044 case OE_RRR(V2MNZ, 0, X1):
1045 case OE_RRR(V2MULFSC, 0, X0):
1046 case OE_RRR(V2MULS, 0, X0):
1047 case OE_RRR(V2MULTS, 0, X0):
1048 case OE_RRR(V2MZ, 0, X0):
1049 case OE_RRR(V2MZ, 0, X1):
1050 case OE_RRR(V2PACKH, 0, X0):
1051 case OE_RRR(V2PACKH, 0, X1):
1052 case OE_RRR(V2PACKL, 0, X0):
1053 case OE_RRR(V2PACKL, 0, X1):
1054 case OE_RRR(V2PACKUC, 0, X0):
1055 case OE_RRR(V2PACKUC, 0, X1):
1056 case OE_RRR(V2SADAS, 0, X0):
1057 case OE_RRR(V2SADAU, 0, X0):
1058 case OE_RRR(V2SADS, 0, X0):
1059 case OE_RRR(V2SADU, 0, X0):
1060 case OE_RRR(V2SHLSC, 0, X0):
1061 case OE_RRR(V2SHLSC, 0, X1):
1062 case OE_RRR(V2SHL, 0, X0):
1063 case OE_RRR(V2SHL, 0, X1):
1064 case OE_RRR(V2SHRS, 0, X0):
1065 case OE_RRR(V2SHRS, 0, X1):
1066 case OE_RRR(V2SHRU, 0, X0):
1067 case OE_RRR(V2SHRU, 0, X1):
1068 case OE_RRR(V2SUBSC, 0, X0):
1069 case OE_RRR(V2SUBSC, 0, X1):
1070 case OE_RRR(V2SUB, 0, X0):
1071 case OE_RRR(V2SUB, 0, X1):
1072 case OE_RRR(V4ADDSC, 0, X0):
1073 case OE_RRR(V4ADDSC, 0, X1):
1074 case OE_RRR(V4ADD, 0, X0):
1075 case OE_RRR(V4ADD, 0, X1):
1076 case OE_RRR(V4INT_H, 0, X0):
1077 case OE_RRR(V4INT_H, 0, X1):
1078 case OE_RRR(V4INT_L, 0, X0):
1079 case OE_RRR(V4INT_L, 0, X1):
1080 case OE_RRR(V4PACKSC, 0, X0):
1081 case OE_RRR(V4PACKSC, 0, X1):
1082 case OE_RRR(V4SHLSC, 0, X0):
1083 case OE_RRR(V4SHLSC, 0, X1):
1084 case OE_RRR(V4SHL, 0, X0):
1085 case OE_RRR(V4SHL, 0, X1):
1086 case OE_RRR(V4SHRS, 0, X0):
1087 case OE_RRR(V4SHRS, 0, X1):
1088 case OE_RRR(V4SHRU, 0, X0):
1089 case OE_RRR(V4SHRU, 0, X1):
1090 case OE_RRR(V4SUBSC, 0, X0):
1091 case OE_RRR(V4SUBSC, 0, X1):
1092 case OE_RRR(V4SUB, 0, X0):
1093 case OE_RRR(V4SUB, 0, X1):
a9fdfc7e 1094 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
8fd29dd7
RH
1095 case OE_RRR(XOR, 0, X0):
1096 case OE_RRR(XOR, 0, X1):
1097 case OE_RRR(XOR, 5, Y0):
1098 case OE_RRR(XOR, 5, Y1):
a9fdfc7e
RH
1099 tcg_gen_xor_tl(tdest, tsrca, tsrcb);
1100 mnemonic = "xor";
1101 break;
8fd29dd7
RH
1102 default:
1103 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
1104 }
1105
1106 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s, %s", mnemonic,
1107 reg_names[dest], reg_names[srca], reg_names[srcb]);
1108 return TILEGX_EXCP_NONE;
1109}
1110
1111static TileExcp gen_rri_opcode(DisasContext *dc, unsigned opext,
1112 unsigned dest, unsigned srca, int imm)
1113{
a9fdfc7e
RH
1114 TCGv tdest = dest_gr(dc, dest);
1115 TCGv tsrca = load_gr(dc, srca);
8fd29dd7 1116 const char *mnemonic;
01cd675c 1117 TCGMemOp memop;
8fd29dd7
RH
1118
1119 switch (opext) {
89b8c750
RH
1120 case OE(ADDI_OPCODE_Y0, 0, Y0):
1121 case OE(ADDI_OPCODE_Y1, 0, Y1):
8fd29dd7
RH
1122 case OE_IM(ADDI, X0):
1123 case OE_IM(ADDI, X1):
89b8c750
RH
1124 tcg_gen_addi_tl(tdest, tsrca, imm);
1125 mnemonic = "addi";
1126 break;
1127 case OE(ADDXI_OPCODE_Y0, 0, Y0):
1128 case OE(ADDXI_OPCODE_Y1, 0, Y1):
8fd29dd7
RH
1129 case OE_IM(ADDXI, X0):
1130 case OE_IM(ADDXI, X1):
89b8c750
RH
1131 tcg_gen_addi_tl(tdest, tsrca, imm);
1132 tcg_gen_ext32s_tl(tdest, tdest);
1133 mnemonic = "addxi";
1134 break;
a9fdfc7e
RH
1135 case OE(ANDI_OPCODE_Y0, 0, Y0):
1136 case OE(ANDI_OPCODE_Y1, 0, Y1):
8fd29dd7
RH
1137 case OE_IM(ANDI, X0):
1138 case OE_IM(ANDI, X1):
a9fdfc7e
RH
1139 tcg_gen_andi_tl(tdest, tsrca, imm);
1140 mnemonic = "andi";
1141 break;
73c54377
RH
1142 case OE(CMPEQI_OPCODE_Y0, 0, Y0):
1143 case OE(CMPEQI_OPCODE_Y1, 0, Y1):
8fd29dd7
RH
1144 case OE_IM(CMPEQI, X0):
1145 case OE_IM(CMPEQI, X1):
73c54377
RH
1146 tcg_gen_setcondi_tl(TCG_COND_EQ, tdest, tsrca, imm);
1147 mnemonic = "cmpeqi";
1148 break;
1149 case OE(CMPLTSI_OPCODE_Y0, 0, Y0):
1150 case OE(CMPLTSI_OPCODE_Y1, 0, Y1):
8fd29dd7
RH
1151 case OE_IM(CMPLTSI, X0):
1152 case OE_IM(CMPLTSI, X1):
73c54377
RH
1153 tcg_gen_setcondi_tl(TCG_COND_LT, tdest, tsrca, imm);
1154 mnemonic = "cmpltsi";
1155 break;
8fd29dd7
RH
1156 case OE_IM(CMPLTUI, X0):
1157 case OE_IM(CMPLTUI, X1):
73c54377
RH
1158 tcg_gen_setcondi_tl(TCG_COND_LTU, tdest, tsrca, imm);
1159 mnemonic = "cmpltui";
1160 break;
8fd29dd7 1161 case OE_IM(LD1S_ADD, X1):
01cd675c
RH
1162 memop = MO_SB;
1163 mnemonic = "ld1s_add";
1164 goto do_load_add;
8fd29dd7 1165 case OE_IM(LD1U_ADD, X1):
01cd675c
RH
1166 memop = MO_UB;
1167 mnemonic = "ld1u_add";
1168 goto do_load_add;
8fd29dd7 1169 case OE_IM(LD2S_ADD, X1):
01cd675c
RH
1170 memop = MO_TESW;
1171 mnemonic = "ld2s_add";
1172 goto do_load_add;
8fd29dd7 1173 case OE_IM(LD2U_ADD, X1):
01cd675c
RH
1174 memop = MO_TEUW;
1175 mnemonic = "ld2u_add";
1176 goto do_load_add;
8fd29dd7 1177 case OE_IM(LD4S_ADD, X1):
01cd675c
RH
1178 memop = MO_TESL;
1179 mnemonic = "ld4s_add";
1180 goto do_load_add;
8fd29dd7 1181 case OE_IM(LD4U_ADD, X1):
01cd675c
RH
1182 memop = MO_TEUL;
1183 mnemonic = "ld4u_add";
1184 goto do_load_add;
8fd29dd7 1185 case OE_IM(LDNT1S_ADD, X1):
01cd675c
RH
1186 memop = MO_SB;
1187 mnemonic = "ldnt1s_add";
1188 goto do_load_add;
8fd29dd7 1189 case OE_IM(LDNT1U_ADD, X1):
01cd675c
RH
1190 memop = MO_UB;
1191 mnemonic = "ldnt1u_add";
1192 goto do_load_add;
8fd29dd7 1193 case OE_IM(LDNT2S_ADD, X1):
01cd675c
RH
1194 memop = MO_TESW;
1195 mnemonic = "ldnt2s_add";
1196 goto do_load_add;
8fd29dd7 1197 case OE_IM(LDNT2U_ADD, X1):
01cd675c
RH
1198 memop = MO_TEUW;
1199 mnemonic = "ldnt2u_add";
1200 goto do_load_add;
8fd29dd7 1201 case OE_IM(LDNT4S_ADD, X1):
01cd675c
RH
1202 memop = MO_TESL;
1203 mnemonic = "ldnt4s_add";
1204 goto do_load_add;
8fd29dd7 1205 case OE_IM(LDNT4U_ADD, X1):
01cd675c
RH
1206 memop = MO_TEUL;
1207 mnemonic = "ldnt4u_add";
1208 goto do_load_add;
8fd29dd7 1209 case OE_IM(LDNT_ADD, X1):
01cd675c
RH
1210 memop = MO_TEQ;
1211 mnemonic = "ldnt_add";
1212 goto do_load_add;
8fd29dd7 1213 case OE_IM(LD_ADD, X1):
01cd675c
RH
1214 memop = MO_TEQ;
1215 mnemonic = "ldnt_add";
1216 do_load_add:
1217 tcg_gen_qemu_ld_tl(tdest, tsrca, dc->mmuidx, memop);
1218 tcg_gen_addi_tl(dest_gr(dc, srca), tsrca, imm);
1219 break;
8fd29dd7 1220 case OE_IM(LDNA_ADD, X1):
01cd675c
RH
1221 tcg_gen_andi_tl(tdest, tsrca, ~7);
1222 tcg_gen_qemu_ld_tl(tdest, tdest, dc->mmuidx, MO_TEQ);
1223 tcg_gen_addi_tl(dest_gr(dc, srca), tsrca, imm);
1224 mnemonic = "ldna_add";
1225 break;
8fd29dd7
RH
1226 case OE_IM(ORI, X0):
1227 case OE_IM(ORI, X1):
a9fdfc7e
RH
1228 tcg_gen_ori_tl(tdest, tsrca, imm);
1229 mnemonic = "ori";
1230 break;
8fd29dd7
RH
1231 case OE_IM(V1ADDI, X0):
1232 case OE_IM(V1ADDI, X1):
1233 case OE_IM(V1CMPEQI, X0):
1234 case OE_IM(V1CMPEQI, X1):
e7346cf0
RH
1235 tcg_gen_xori_tl(tdest, tsrca, V1_IMM(imm));
1236 gen_v1cmpeq0(tdest);
1237 mnemonic = "v1cmpeqi";
1238 break;
8fd29dd7
RH
1239 case OE_IM(V1CMPLTSI, X0):
1240 case OE_IM(V1CMPLTSI, X1):
1241 case OE_IM(V1CMPLTUI, X0):
1242 case OE_IM(V1CMPLTUI, X1):
1243 case OE_IM(V1MAXUI, X0):
1244 case OE_IM(V1MAXUI, X1):
1245 case OE_IM(V1MINUI, X0):
1246 case OE_IM(V1MINUI, X1):
1247 case OE_IM(V2ADDI, X0):
1248 case OE_IM(V2ADDI, X1):
1249 case OE_IM(V2CMPEQI, X0):
1250 case OE_IM(V2CMPEQI, X1):
1251 case OE_IM(V2CMPLTSI, X0):
1252 case OE_IM(V2CMPLTSI, X1):
1253 case OE_IM(V2CMPLTUI, X0):
1254 case OE_IM(V2CMPLTUI, X1):
1255 case OE_IM(V2MAXSI, X0):
1256 case OE_IM(V2MAXSI, X1):
1257 case OE_IM(V2MINSI, X0):
1258 case OE_IM(V2MINSI, X1):
a9fdfc7e 1259 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
8fd29dd7
RH
1260 case OE_IM(XORI, X0):
1261 case OE_IM(XORI, X1):
a9fdfc7e
RH
1262 tcg_gen_xori_tl(tdest, tsrca, imm);
1263 mnemonic = "xori";
1264 break;
8fd29dd7
RH
1265
1266 case OE_SH(ROTLI, X0):
1267 case OE_SH(ROTLI, X1):
1268 case OE_SH(ROTLI, Y0):
1269 case OE_SH(ROTLI, Y1):
2369976d
RH
1270 tcg_gen_rotli_tl(tdest, tsrca, imm);
1271 mnemonic = "rotli";
1272 break;
8fd29dd7
RH
1273 case OE_SH(SHLI, X0):
1274 case OE_SH(SHLI, X1):
1275 case OE_SH(SHLI, Y0):
1276 case OE_SH(SHLI, Y1):
2369976d
RH
1277 tcg_gen_shli_tl(tdest, tsrca, imm);
1278 mnemonic = "shli";
1279 break;
8fd29dd7
RH
1280 case OE_SH(SHLXI, X0):
1281 case OE_SH(SHLXI, X1):
2369976d
RH
1282 tcg_gen_shli_tl(tdest, tsrca, imm & 31);
1283 tcg_gen_ext32s_tl(tdest, tdest);
1284 mnemonic = "shlxi";
1285 break;
8fd29dd7
RH
1286 case OE_SH(SHRSI, X0):
1287 case OE_SH(SHRSI, X1):
1288 case OE_SH(SHRSI, Y0):
1289 case OE_SH(SHRSI, Y1):
2369976d
RH
1290 tcg_gen_sari_tl(tdest, tsrca, imm);
1291 mnemonic = "shrsi";
1292 break;
8fd29dd7
RH
1293 case OE_SH(SHRUI, X0):
1294 case OE_SH(SHRUI, X1):
1295 case OE_SH(SHRUI, Y0):
1296 case OE_SH(SHRUI, Y1):
2369976d
RH
1297 tcg_gen_shri_tl(tdest, tsrca, imm);
1298 mnemonic = "shrui";
1299 break;
8fd29dd7
RH
1300 case OE_SH(SHRUXI, X0):
1301 case OE_SH(SHRUXI, X1):
2369976d
RH
1302 if ((imm & 31) == 0) {
1303 tcg_gen_ext32s_tl(tdest, tsrca);
1304 } else {
1305 tcg_gen_ext32u_tl(tdest, tsrca);
1306 tcg_gen_shri_tl(tdest, tdest, imm & 31);
1307 }
1308 mnemonic = "shlxi";
1309 break;
8fd29dd7
RH
1310 case OE_SH(V1SHLI, X0):
1311 case OE_SH(V1SHLI, X1):
1312 case OE_SH(V1SHRSI, X0):
1313 case OE_SH(V1SHRSI, X1):
1314 case OE_SH(V1SHRUI, X0):
1315 case OE_SH(V1SHRUI, X1):
1316 case OE_SH(V2SHLI, X0):
1317 case OE_SH(V2SHLI, X1):
1318 case OE_SH(V2SHRSI, X0):
1319 case OE_SH(V2SHRSI, X1):
1320 case OE_SH(V2SHRUI, X0):
1321 case OE_SH(V2SHRUI, X1):
89b8c750 1322 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
8fd29dd7 1323
8fd29dd7
RH
1324 case OE(ADDLI_OPCODE_X0, 0, X0):
1325 case OE(ADDLI_OPCODE_X1, 0, X1):
89b8c750
RH
1326 tcg_gen_addi_tl(tdest, tsrca, imm);
1327 mnemonic = "addli";
1328 break;
8fd29dd7
RH
1329 case OE(ADDXLI_OPCODE_X0, 0, X0):
1330 case OE(ADDXLI_OPCODE_X1, 0, X1):
89b8c750
RH
1331 tcg_gen_addi_tl(tdest, tsrca, imm);
1332 tcg_gen_ext32s_tl(tdest, tdest);
1333 mnemonic = "addxli";
1334 break;
8fd29dd7
RH
1335 case OE(SHL16INSLI_OPCODE_X0, 0, X0):
1336 case OE(SHL16INSLI_OPCODE_X1, 0, X1):
89b8c750
RH
1337 tcg_gen_shli_tl(tdest, tsrca, 16);
1338 tcg_gen_ori_tl(tdest, tdest, imm & 0xffff);
1339 mnemonic = "shl16insli";
1340 break;
8fd29dd7
RH
1341
1342 default:
1343 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
1344 }
1345
1346 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s, %d", mnemonic,
1347 reg_names[dest], reg_names[srca], imm);
1348 return TILEGX_EXCP_NONE;
1349}
1350
1351static TileExcp gen_bf_opcode_x0(DisasContext *dc, unsigned ext,
1352 unsigned dest, unsigned srca,
1353 unsigned bfs, unsigned bfe)
1354{
c06b1817
RH
1355 TCGv tdest = dest_gr(dc, dest);
1356 TCGv tsrca = load_gr(dc, srca);
1357 TCGv tsrcd;
1358 int len;
8fd29dd7
RH
1359 const char *mnemonic;
1360
c06b1817
RH
1361 /* The bitfield is either between E and S inclusive,
1362 or up from S and down from E inclusive. */
1363 if (bfs <= bfe) {
1364 len = bfe - bfs + 1;
1365 } else {
1366 len = (64 - bfs) + (bfe + 1);
1367 }
1368
8fd29dd7
RH
1369 switch (ext) {
1370 case BFEXTU_BF_OPCODE_X0:
c06b1817
RH
1371 if (bfs == 0 && bfe == 7) {
1372 tcg_gen_ext8u_tl(tdest, tsrca);
1373 } else if (bfs == 0 && bfe == 15) {
1374 tcg_gen_ext16u_tl(tdest, tsrca);
1375 } else if (bfs == 0 && bfe == 31) {
1376 tcg_gen_ext32u_tl(tdest, tsrca);
1377 } else {
1378 int rol = 63 - bfe;
1379 if (bfs <= bfe) {
1380 tcg_gen_shli_tl(tdest, tsrca, rol);
1381 } else {
1382 tcg_gen_rotli_tl(tdest, tsrca, rol);
1383 }
1384 tcg_gen_shri_tl(tdest, tdest, (bfs + rol) & 63);
1385 }
1386 mnemonic = "bfextu";
1387 break;
1388
8fd29dd7 1389 case BFEXTS_BF_OPCODE_X0:
c06b1817
RH
1390 if (bfs == 0 && bfe == 7) {
1391 tcg_gen_ext8s_tl(tdest, tsrca);
1392 } else if (bfs == 0 && bfe == 15) {
1393 tcg_gen_ext16s_tl(tdest, tsrca);
1394 } else if (bfs == 0 && bfe == 31) {
1395 tcg_gen_ext32s_tl(tdest, tsrca);
1396 } else {
1397 int rol = 63 - bfe;
1398 if (bfs <= bfe) {
1399 tcg_gen_shli_tl(tdest, tsrca, rol);
1400 } else {
1401 tcg_gen_rotli_tl(tdest, tsrca, rol);
1402 }
1403 tcg_gen_sari_tl(tdest, tdest, (bfs + rol) & 63);
1404 }
1405 mnemonic = "bfexts";
1406 break;
1407
8fd29dd7 1408 case BFINS_BF_OPCODE_X0:
c06b1817
RH
1409 tsrcd = load_gr(dc, dest);
1410 if (bfs <= bfe) {
1411 tcg_gen_deposit_tl(tdest, tsrcd, tsrca, bfs, len);
1412 } else {
1413 tcg_gen_rotri_tl(tdest, tsrcd, bfs);
1414 tcg_gen_deposit_tl(tdest, tdest, tsrca, 0, len);
1415 tcg_gen_rotli_tl(tdest, tdest, bfs);
1416 }
1417 mnemonic = "bfins";
1418 break;
1419
8fd29dd7 1420 case MM_BF_OPCODE_X0:
c06b1817
RH
1421 tsrcd = load_gr(dc, dest);
1422 if (bfs == 0) {
1423 tcg_gen_deposit_tl(tdest, tsrca, tsrcd, 0, len);
1424 } else {
1425 uint64_t mask = len == 64 ? -1 : rol64((1ULL << len) - 1, bfs);
1426 TCGv tmp = tcg_const_tl(mask);
1427
1428 tcg_gen_and_tl(tdest, tsrcd, tmp);
1429 tcg_gen_andc_tl(tmp, tsrca, tmp);
1430 tcg_gen_or_tl(tdest, tdest, tmp);
1431 tcg_temp_free(tmp);
1432 }
1433 mnemonic = "mm";
1434 break;
1435
8fd29dd7
RH
1436 default:
1437 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
1438 }
1439
1440 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s, %u, %u", mnemonic,
1441 reg_names[dest], reg_names[srca], bfs, bfe);
1442 return TILEGX_EXCP_NONE;
1443}
1444
1445static TileExcp gen_branch_opcode_x1(DisasContext *dc, unsigned ext,
1446 unsigned srca, int off)
1447{
1448 target_ulong tgt = dc->pc + off * TILEGX_BUNDLE_SIZE_IN_BYTES;
1449 const char *mnemonic;
1450
e04e98bf
RH
1451 dc->jmp.dest = tcg_const_tl(tgt);
1452 dc->jmp.val1 = tcg_temp_new();
1453 tcg_gen_mov_tl(dc->jmp.val1, load_gr(dc, srca));
1454
1455 /* Note that the "predict taken" opcodes have bit 0 clear.
1456 Therefore, fold the two cases together by setting bit 0. */
1457 switch (ext | 1) {
8fd29dd7 1458 case BEQZ_BRANCH_OPCODE_X1:
e04e98bf
RH
1459 dc->jmp.cond = TCG_COND_EQ;
1460 mnemonic = "beqz";
1461 break;
8fd29dd7 1462 case BNEZ_BRANCH_OPCODE_X1:
e04e98bf
RH
1463 dc->jmp.cond = TCG_COND_NE;
1464 mnemonic = "bnez";
1465 break;
8fd29dd7 1466 case BGEZ_BRANCH_OPCODE_X1:
e04e98bf
RH
1467 dc->jmp.cond = TCG_COND_GE;
1468 mnemonic = "bgez";
1469 break;
8fd29dd7 1470 case BGTZ_BRANCH_OPCODE_X1:
e04e98bf
RH
1471 dc->jmp.cond = TCG_COND_GT;
1472 mnemonic = "bgtz";
1473 break;
8fd29dd7 1474 case BLEZ_BRANCH_OPCODE_X1:
e04e98bf
RH
1475 dc->jmp.cond = TCG_COND_LE;
1476 mnemonic = "blez";
1477 break;
8fd29dd7 1478 case BLTZ_BRANCH_OPCODE_X1:
e04e98bf
RH
1479 dc->jmp.cond = TCG_COND_LT;
1480 mnemonic = "bltz";
1481 break;
1482 case BLBC_BRANCH_OPCODE_X1:
1483 dc->jmp.cond = TCG_COND_EQ;
1484 tcg_gen_andi_tl(dc->jmp.val1, dc->jmp.val1, 1);
1485 mnemonic = "blbc";
1486 break;
1487 case BLBS_BRANCH_OPCODE_X1:
1488 dc->jmp.cond = TCG_COND_NE;
1489 tcg_gen_andi_tl(dc->jmp.val1, dc->jmp.val1, 1);
1490 mnemonic = "blbs";
1491 break;
8fd29dd7
RH
1492 default:
1493 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
1494 }
1495
1496 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
e04e98bf
RH
1497 qemu_log("%s%s %s, " TARGET_FMT_lx " <%s>",
1498 mnemonic, ext & 1 ? "" : "t",
1499 reg_names[srca], tgt, lookup_symbol(tgt));
8fd29dd7
RH
1500 }
1501 return TILEGX_EXCP_NONE;
1502}
1503
c230a994 1504static TileExcp gen_jump_opcode_x1(DisasContext *dc, unsigned ext, int off)
8fd29dd7
RH
1505{
1506 target_ulong tgt = dc->pc + off * TILEGX_BUNDLE_SIZE_IN_BYTES;
c230a994 1507 const char *mnemonic = "j";
8fd29dd7 1508
c230a994
RH
1509 /* The extension field is 1 bit, therefore we only have JAL and J. */
1510 if (ext == JAL_JUMP_OPCODE_X1) {
1511 tcg_gen_movi_tl(dest_gr(dc, TILEGX_R_LR),
1512 dc->pc + TILEGX_BUNDLE_SIZE_IN_BYTES);
1513 mnemonic = "jal";
8fd29dd7 1514 }
c230a994
RH
1515 dc->jmp.cond = TCG_COND_ALWAYS;
1516 dc->jmp.dest = tcg_const_tl(tgt);
8fd29dd7
RH
1517
1518 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1519 qemu_log("%s " TARGET_FMT_lx " <%s>",
1520 mnemonic, tgt, lookup_symbol(tgt));
1521 }
1522 return TILEGX_EXCP_NONE;
1523}
1524
03b217b1
RH
1525typedef struct {
1526 const char *name;
1527 intptr_t offset;
1528 void (*get)(TCGv, TCGv_ptr);
1529 void (*put)(TCGv_ptr, TCGv);
1530} TileSPR;
1531
1532static const TileSPR *find_spr(unsigned spr)
1533{
1534 /* Allow the compiler to construct the binary search tree. */
1535#define D(N, O, G, P) \
1536 case SPR_##N: { static const TileSPR x = { #N, O, G, P }; return &x; }
1537
1538 switch (spr) {
1539 D(CMPEXCH_VALUE,
1540 offsetof(CPUTLGState, spregs[TILEGX_SPR_CMPEXCH]), 0, 0)
1541 D(INTERRUPT_CRITICAL_SECTION,
1542 offsetof(CPUTLGState, spregs[TILEGX_SPR_CRITICAL_SEC]), 0, 0)
1543 D(SIM_CONTROL,
1544 offsetof(CPUTLGState, spregs[TILEGX_SPR_SIM_CONTROL]), 0, 0)
1545 }
1546
1547#undef D
1548
1549 qemu_log_mask(LOG_UNIMP, "UNIMP SPR %u\n", spr);
1550 return NULL;
1551}
1552
1553static TileExcp gen_mtspr_x1(DisasContext *dc, unsigned spr, unsigned srca)
1554{
1555 const TileSPR *def = find_spr(spr);
1556 TCGv tsrca;
1557
1558 if (def == NULL) {
1559 qemu_log_mask(CPU_LOG_TB_IN_ASM, "mtspr spr[%u], %s", spr, reg_names[srca]);
1560 return TILEGX_EXCP_OPCODE_UNKNOWN;
1561 }
1562
1563 tsrca = load_gr(dc, srca);
1564 if (def->put) {
1565 def->put(cpu_env, tsrca);
1566 } else {
1567 tcg_gen_st_tl(tsrca, cpu_env, def->offset);
1568 }
1569 qemu_log_mask(CPU_LOG_TB_IN_ASM, "mtspr %s, %s", def->name, reg_names[srca]);
1570 return TILEGX_EXCP_NONE;
1571}
1572
1573static TileExcp gen_mfspr_x1(DisasContext *dc, unsigned dest, unsigned spr)
1574{
1575 const TileSPR *def = find_spr(spr);
1576 TCGv tdest;
1577
1578 if (def == NULL) {
1579 qemu_log_mask(CPU_LOG_TB_IN_ASM, "mtspr %s, spr[%u]", reg_names[dest], spr);
1580 return TILEGX_EXCP_OPCODE_UNKNOWN;
1581 }
1582
1583 tdest = dest_gr(dc, dest);
1584 if (def->get) {
1585 def->get(tdest, cpu_env);
1586 } else {
1587 tcg_gen_ld_tl(tdest, cpu_env, def->offset);
1588 }
1589 qemu_log_mask(CPU_LOG_TB_IN_ASM, "mfspr %s, %s", reg_names[dest], def->name);
1590 return TILEGX_EXCP_NONE;
1591}
1592
8fd29dd7
RH
1593static TileExcp decode_y0(DisasContext *dc, tilegx_bundle_bits bundle)
1594{
1595 unsigned opc = get_Opcode_Y0(bundle);
1596 unsigned ext = get_RRROpcodeExtension_Y0(bundle);
1597 unsigned dest = get_Dest_Y0(bundle);
1598 unsigned srca = get_SrcA_Y0(bundle);
1599 unsigned srcb;
1600 int imm;
1601
1602 switch (opc) {
1603 case RRR_1_OPCODE_Y0:
1604 if (ext == UNARY_RRR_1_OPCODE_Y0) {
1605 ext = get_UnaryOpcodeExtension_Y0(bundle);
1606 return gen_rr_opcode(dc, OE(opc, ext, Y0), dest, srca);
1607 }
1608 /* fallthru */
1609 case RRR_0_OPCODE_Y0:
1610 case RRR_2_OPCODE_Y0:
1611 case RRR_3_OPCODE_Y0:
1612 case RRR_4_OPCODE_Y0:
1613 case RRR_5_OPCODE_Y0:
1614 case RRR_6_OPCODE_Y0:
1615 case RRR_7_OPCODE_Y0:
1616 case RRR_8_OPCODE_Y0:
1617 case RRR_9_OPCODE_Y0:
1618 srcb = get_SrcB_Y0(bundle);
1619 return gen_rrr_opcode(dc, OE(opc, ext, Y0), dest, srca, srcb);
1620
1621 case SHIFT_OPCODE_Y0:
1622 ext = get_ShiftOpcodeExtension_Y0(bundle);
1623 imm = get_ShAmt_Y0(bundle);
1624 return gen_rri_opcode(dc, OE(opc, ext, Y0), dest, srca, imm);
1625
1626 case ADDI_OPCODE_Y0:
1627 case ADDXI_OPCODE_Y0:
1628 case ANDI_OPCODE_Y0:
1629 case CMPEQI_OPCODE_Y0:
1630 case CMPLTSI_OPCODE_Y0:
1631 imm = (int8_t)get_Imm8_Y0(bundle);
1632 return gen_rri_opcode(dc, OE(opc, 0, Y0), dest, srca, imm);
1633
1634 default:
1635 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
1636 }
1637}
1638
1639static TileExcp decode_y1(DisasContext *dc, tilegx_bundle_bits bundle)
1640{
1641 unsigned opc = get_Opcode_Y1(bundle);
1642 unsigned ext = get_RRROpcodeExtension_Y1(bundle);
1643 unsigned dest = get_Dest_Y1(bundle);
1644 unsigned srca = get_SrcA_Y1(bundle);
1645 unsigned srcb;
1646 int imm;
1647
1648 switch (get_Opcode_Y1(bundle)) {
1649 case RRR_1_OPCODE_Y1:
1650 if (ext == UNARY_RRR_1_OPCODE_Y0) {
1651 ext = get_UnaryOpcodeExtension_Y1(bundle);
1652 return gen_rr_opcode(dc, OE(opc, ext, Y1), dest, srca);
1653 }
1654 /* fallthru */
1655 case RRR_0_OPCODE_Y1:
1656 case RRR_2_OPCODE_Y1:
1657 case RRR_3_OPCODE_Y1:
1658 case RRR_4_OPCODE_Y1:
1659 case RRR_5_OPCODE_Y1:
1660 case RRR_6_OPCODE_Y1:
1661 case RRR_7_OPCODE_Y1:
1662 srcb = get_SrcB_Y1(bundle);
1663 return gen_rrr_opcode(dc, OE(opc, ext, Y1), dest, srca, srcb);
1664
1665 case SHIFT_OPCODE_Y1:
1666 ext = get_ShiftOpcodeExtension_Y1(bundle);
1667 imm = get_ShAmt_Y1(bundle);
1668 return gen_rri_opcode(dc, OE(opc, ext, Y1), dest, srca, imm);
1669
1670 case ADDI_OPCODE_Y1:
1671 case ADDXI_OPCODE_Y1:
1672 case ANDI_OPCODE_Y1:
1673 case CMPEQI_OPCODE_Y1:
1674 case CMPLTSI_OPCODE_Y1:
1675 imm = (int8_t)get_Imm8_Y1(bundle);
1676 return gen_rri_opcode(dc, OE(opc, 0, Y1), dest, srca, imm);
1677
1678 default:
1679 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
1680 }
1681}
1682
1683static TileExcp decode_y2(DisasContext *dc, tilegx_bundle_bits bundle)
1684{
1685 unsigned mode = get_Mode(bundle);
1686 unsigned opc = get_Opcode_Y2(bundle);
1687 unsigned srca = get_SrcA_Y2(bundle);
1688 unsigned srcbdest = get_SrcBDest_Y2(bundle);
1689 const char *mnemonic;
0426335d 1690 TCGMemOp memop;
8fd29dd7
RH
1691
1692 switch (OEY2(opc, mode)) {
1693 case OEY2(LD1S_OPCODE_Y2, MODE_OPCODE_YA2):
0426335d
RH
1694 memop = MO_SB;
1695 mnemonic = "ld1s";
1696 goto do_load;
8fd29dd7 1697 case OEY2(LD1U_OPCODE_Y2, MODE_OPCODE_YA2):
0426335d
RH
1698 memop = MO_UB;
1699 mnemonic = "ld1u";
1700 goto do_load;
8fd29dd7 1701 case OEY2(LD2S_OPCODE_Y2, MODE_OPCODE_YA2):
0426335d
RH
1702 memop = MO_TESW;
1703 mnemonic = "ld2s";
1704 goto do_load;
8fd29dd7 1705 case OEY2(LD2U_OPCODE_Y2, MODE_OPCODE_YA2):
0426335d
RH
1706 memop = MO_TEUW;
1707 mnemonic = "ld2u";
1708 goto do_load;
8fd29dd7 1709 case OEY2(LD4S_OPCODE_Y2, MODE_OPCODE_YB2):
0426335d
RH
1710 memop = MO_TESL;
1711 mnemonic = "ld4s";
1712 goto do_load;
8fd29dd7 1713 case OEY2(LD4U_OPCODE_Y2, MODE_OPCODE_YB2):
0426335d
RH
1714 memop = MO_TEUL;
1715 mnemonic = "ld4u";
1716 goto do_load;
8fd29dd7 1717 case OEY2(LD_OPCODE_Y2, MODE_OPCODE_YB2):
0426335d
RH
1718 memop = MO_TEQ;
1719 mnemonic = "ld";
1720 do_load:
1721 tcg_gen_qemu_ld_tl(dest_gr(dc, srcbdest), load_gr(dc, srca),
1722 dc->mmuidx, memop);
1723 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s", mnemonic,
1724 reg_names[srcbdest], reg_names[srca]);
1725 return TILEGX_EXCP_NONE;
8fd29dd7
RH
1726
1727 case OEY2(ST1_OPCODE_Y2, MODE_OPCODE_YC2):
0426335d 1728 return gen_st_opcode(dc, 0, srca, srcbdest, MO_UB, "st1");
8fd29dd7 1729 case OEY2(ST2_OPCODE_Y2, MODE_OPCODE_YC2):
0426335d 1730 return gen_st_opcode(dc, 0, srca, srcbdest, MO_TEUW, "st2");
8fd29dd7 1731 case OEY2(ST4_OPCODE_Y2, MODE_OPCODE_YC2):
0426335d 1732 return gen_st_opcode(dc, 0, srca, srcbdest, MO_TEUL, "st4");
8fd29dd7 1733 case OEY2(ST_OPCODE_Y2, MODE_OPCODE_YC2):
0426335d 1734 return gen_st_opcode(dc, 0, srca, srcbdest, MO_TEQ, "st");
8fd29dd7
RH
1735
1736 default:
1737 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
1738 }
8fd29dd7
RH
1739}
1740
1741static TileExcp decode_x0(DisasContext *dc, tilegx_bundle_bits bundle)
1742{
1743 unsigned opc = get_Opcode_X0(bundle);
1744 unsigned dest = get_Dest_X0(bundle);
1745 unsigned srca = get_SrcA_X0(bundle);
1746 unsigned ext, srcb, bfs, bfe;
1747 int imm;
1748
1749 switch (opc) {
1750 case RRR_0_OPCODE_X0:
1751 ext = get_RRROpcodeExtension_X0(bundle);
1752 if (ext == UNARY_RRR_0_OPCODE_X0) {
1753 ext = get_UnaryOpcodeExtension_X0(bundle);
1754 return gen_rr_opcode(dc, OE(opc, ext, X0), dest, srca);
1755 }
1756 srcb = get_SrcB_X0(bundle);
1757 return gen_rrr_opcode(dc, OE(opc, ext, X0), dest, srca, srcb);
1758
1759 case SHIFT_OPCODE_X0:
1760 ext = get_ShiftOpcodeExtension_X0(bundle);
1761 imm = get_ShAmt_X0(bundle);
1762 return gen_rri_opcode(dc, OE(opc, ext, X0), dest, srca, imm);
1763
1764 case IMM8_OPCODE_X0:
1765 ext = get_Imm8OpcodeExtension_X0(bundle);
1766 imm = (int8_t)get_Imm8_X0(bundle);
1767 return gen_rri_opcode(dc, OE(opc, ext, X0), dest, srca, imm);
1768
1769 case BF_OPCODE_X0:
1770 ext = get_BFOpcodeExtension_X0(bundle);
1771 bfs = get_BFStart_X0(bundle);
1772 bfe = get_BFEnd_X0(bundle);
1773 return gen_bf_opcode_x0(dc, ext, dest, srca, bfs, bfe);
1774
1775 case ADDLI_OPCODE_X0:
1776 case SHL16INSLI_OPCODE_X0:
1777 case ADDXLI_OPCODE_X0:
1778 imm = (int16_t)get_Imm16_X0(bundle);
1779 return gen_rri_opcode(dc, OE(opc, 0, X0), dest, srca, imm);
1780
1781 default:
1782 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
1783 }
1784}
1785
1786static TileExcp decode_x1(DisasContext *dc, tilegx_bundle_bits bundle)
1787{
1788 unsigned opc = get_Opcode_X1(bundle);
1789 unsigned dest = get_Dest_X1(bundle);
1790 unsigned srca = get_SrcA_X1(bundle);
1791 unsigned ext, srcb;
1792 int imm;
1793
1794 switch (opc) {
1795 case RRR_0_OPCODE_X1:
1796 ext = get_RRROpcodeExtension_X1(bundle);
0426335d
RH
1797 srcb = get_SrcB_X1(bundle);
1798 switch (ext) {
1799 case UNARY_RRR_0_OPCODE_X1:
8fd29dd7
RH
1800 ext = get_UnaryOpcodeExtension_X1(bundle);
1801 return gen_rr_opcode(dc, OE(opc, ext, X1), dest, srca);
0426335d
RH
1802 case ST1_RRR_0_OPCODE_X1:
1803 return gen_st_opcode(dc, dest, srca, srcb, MO_UB, "st1");
1804 case ST2_RRR_0_OPCODE_X1:
1805 return gen_st_opcode(dc, dest, srca, srcb, MO_TEUW, "st2");
1806 case ST4_RRR_0_OPCODE_X1:
1807 return gen_st_opcode(dc, dest, srca, srcb, MO_TEUL, "st4");
1808 case STNT1_RRR_0_OPCODE_X1:
1809 return gen_st_opcode(dc, dest, srca, srcb, MO_UB, "stnt1");
1810 case STNT2_RRR_0_OPCODE_X1:
1811 return gen_st_opcode(dc, dest, srca, srcb, MO_TEUW, "stnt2");
1812 case STNT4_RRR_0_OPCODE_X1:
1813 return gen_st_opcode(dc, dest, srca, srcb, MO_TEUL, "stnt4");
1814 case STNT_RRR_0_OPCODE_X1:
1815 return gen_st_opcode(dc, dest, srca, srcb, MO_TEQ, "stnt");
1816 case ST_RRR_0_OPCODE_X1:
1817 return gen_st_opcode(dc, dest, srca, srcb, MO_TEQ, "st");
8fd29dd7 1818 }
8fd29dd7
RH
1819 return gen_rrr_opcode(dc, OE(opc, ext, X1), dest, srca, srcb);
1820
1821 case SHIFT_OPCODE_X1:
1822 ext = get_ShiftOpcodeExtension_X1(bundle);
1823 imm = get_ShAmt_X1(bundle);
1824 return gen_rri_opcode(dc, OE(opc, ext, X1), dest, srca, imm);
1825
1826 case IMM8_OPCODE_X1:
1827 ext = get_Imm8OpcodeExtension_X1(bundle);
01cd675c
RH
1828 imm = (int8_t)get_Dest_Imm8_X1(bundle);
1829 srcb = get_SrcB_X1(bundle);
1830 switch (ext) {
1831 case ST1_ADD_IMM8_OPCODE_X1:
1832 return gen_st_add_opcode(dc, srca, srcb, imm, MO_UB, "st1_add");
1833 case ST2_ADD_IMM8_OPCODE_X1:
1834 return gen_st_add_opcode(dc, srca, srcb, imm, MO_TEUW, "st2_add");
1835 case ST4_ADD_IMM8_OPCODE_X1:
1836 return gen_st_add_opcode(dc, srca, srcb, imm, MO_TEUL, "st4_add");
1837 case STNT1_ADD_IMM8_OPCODE_X1:
1838 return gen_st_add_opcode(dc, srca, srcb, imm, MO_UB, "stnt1_add");
1839 case STNT2_ADD_IMM8_OPCODE_X1:
1840 return gen_st_add_opcode(dc, srca, srcb, imm, MO_TEUW, "stnt2_add");
1841 case STNT4_ADD_IMM8_OPCODE_X1:
1842 return gen_st_add_opcode(dc, srca, srcb, imm, MO_TEUL, "stnt4_add");
1843 case STNT_ADD_IMM8_OPCODE_X1:
1844 return gen_st_add_opcode(dc, srca, srcb, imm, MO_TEQ, "stnt_add");
1845 case ST_ADD_IMM8_OPCODE_X1:
1846 return gen_st_add_opcode(dc, srca, srcb, imm, MO_TEQ, "st_add");
03b217b1
RH
1847 case MFSPR_IMM8_OPCODE_X1:
1848 return gen_mfspr_x1(dc, dest, get_MF_Imm14_X1(bundle));
1849 case MTSPR_IMM8_OPCODE_X1:
1850 return gen_mtspr_x1(dc, get_MT_Imm14_X1(bundle), srca);
01cd675c 1851 }
8fd29dd7
RH
1852 imm = (int8_t)get_Imm8_X1(bundle);
1853 return gen_rri_opcode(dc, OE(opc, ext, X1), dest, srca, imm);
1854
1855 case BRANCH_OPCODE_X1:
1856 ext = get_BrType_X1(bundle);
1857 imm = sextract32(get_BrOff_X1(bundle), 0, 17);
1858 return gen_branch_opcode_x1(dc, ext, srca, imm);
1859
1860 case JUMP_OPCODE_X1:
1861 ext = get_JumpOpcodeExtension_X1(bundle);
1862 imm = sextract32(get_JumpOff_X1(bundle), 0, 27);
1863 return gen_jump_opcode_x1(dc, ext, imm);
1864
1865 case ADDLI_OPCODE_X1:
1866 case SHL16INSLI_OPCODE_X1:
1867 case ADDXLI_OPCODE_X1:
1868 imm = (int16_t)get_Imm16_X1(bundle);
1869 return gen_rri_opcode(dc, OE(opc, 0, X1), dest, srca, imm);
1870
1871 default:
1872 return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
1873 }
1874}
1875
1876static void notice_excp(DisasContext *dc, uint64_t bundle,
1877 const char *type, TileExcp excp)
1878{
1879 if (likely(excp == TILEGX_EXCP_NONE)) {
1880 return;
1881 }
1882 gen_exception(dc, excp);
1883 if (excp == TILEGX_EXCP_OPCODE_UNIMPLEMENTED) {
1884 qemu_log_mask(LOG_UNIMP, "UNIMP %s, [" FMT64X "]\n", type, bundle);
1885 }
1886}
1887
1888static void translate_one_bundle(DisasContext *dc, uint64_t bundle)
1889{
1890 int i;
1891
1892 for (i = 0; i < ARRAY_SIZE(dc->wb); i++) {
1893 DisasContextTemp *wb = &dc->wb[i];
1894 wb->reg = TILEGX_R_NOREG;
1895 TCGV_UNUSED_I64(wb->val);
1896 }
1897 dc->num_wb = 0;
1898
1899 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
1900 tcg_gen_debug_insn_start(dc->pc);
1901 }
1902
1903 qemu_log_mask(CPU_LOG_TB_IN_ASM, " %" PRIx64 ": { ", dc->pc);
1904 if (get_Mode(bundle)) {
1905 notice_excp(dc, bundle, "y0", decode_y0(dc, bundle));
1906 qemu_log_mask(CPU_LOG_TB_IN_ASM, " ; ");
1907 notice_excp(dc, bundle, "y1", decode_y1(dc, bundle));
1908 qemu_log_mask(CPU_LOG_TB_IN_ASM, " ; ");
1909 notice_excp(dc, bundle, "y2", decode_y2(dc, bundle));
1910 } else {
1911 notice_excp(dc, bundle, "x0", decode_x0(dc, bundle));
1912 qemu_log_mask(CPU_LOG_TB_IN_ASM, " ; ");
1913 notice_excp(dc, bundle, "x1", decode_x1(dc, bundle));
1914 }
1915 qemu_log_mask(CPU_LOG_TB_IN_ASM, " }\n");
1916
1917 for (i = dc->num_wb - 1; i >= 0; --i) {
1918 DisasContextTemp *wb = &dc->wb[i];
1919 if (wb->reg < TILEGX_R_COUNT) {
1920 tcg_gen_mov_i64(cpu_regs[wb->reg], wb->val);
1921 }
1922 tcg_temp_free_i64(wb->val);
1923 }
1924
1925 if (dc->jmp.cond != TCG_COND_NEVER) {
1926 if (dc->jmp.cond == TCG_COND_ALWAYS) {
1927 tcg_gen_mov_i64(cpu_pc, dc->jmp.dest);
1928 } else {
1929 TCGv next = tcg_const_i64(dc->pc + TILEGX_BUNDLE_SIZE_IN_BYTES);
1930 tcg_gen_movcond_i64(dc->jmp.cond, cpu_pc,
1931 dc->jmp.val1, load_zero(dc),
1932 dc->jmp.dest, next);
1933 tcg_temp_free_i64(dc->jmp.val1);
1934 tcg_temp_free_i64(next);
1935 }
1936 tcg_temp_free_i64(dc->jmp.dest);
1937 tcg_gen_exit_tb(0);
1938 dc->exit_tb = true;
1939 }
1940}
1941
1942static inline void gen_intermediate_code_internal(TileGXCPU *cpu,
1943 TranslationBlock *tb,
1944 bool search_pc)
1945{
1946 DisasContext ctx;
1947 DisasContext *dc = &ctx;
1948 CPUState *cs = CPU(cpu);
1949 CPUTLGState *env = &cpu->env;
1950 uint64_t pc_start = tb->pc;
1951 uint64_t next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
1952 int j, lj = -1;
1953 int num_insns = 0;
1954 int max_insns = tb->cflags & CF_COUNT_MASK;
1955
1956 dc->pc = pc_start;
1957 dc->mmuidx = 0;
1958 dc->exit_tb = false;
1959 dc->jmp.cond = TCG_COND_NEVER;
1960 TCGV_UNUSED_I64(dc->jmp.dest);
1961 TCGV_UNUSED_I64(dc->jmp.val1);
8fd29dd7
RH
1962 TCGV_UNUSED_I64(dc->zero);
1963
1964 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1965 qemu_log("IN: %s\n", lookup_symbol(pc_start));
1966 }
1967 if (!max_insns) {
1968 max_insns = CF_COUNT_MASK;
1969 }
1970 if (cs->singlestep_enabled || singlestep) {
1971 max_insns = 1;
1972 }
1973 gen_tb_start(tb);
1974
1975 while (1) {
1976 if (search_pc) {
1977 j = tcg_op_buf_count();
1978 if (lj < j) {
1979 lj++;
1980 while (lj < j) {
1981 tcg_ctx.gen_opc_instr_start[lj++] = 0;
1982 }
1983 }
1984 tcg_ctx.gen_opc_pc[lj] = dc->pc;
1985 tcg_ctx.gen_opc_instr_start[lj] = 1;
1986 tcg_ctx.gen_opc_icount[lj] = num_insns;
1987 }
1988 translate_one_bundle(dc, cpu_ldq_data(env, dc->pc));
1989
1990 if (dc->exit_tb) {
1991 /* PC updated and EXIT_TB/GOTO_TB/exception emitted. */
1992 break;
1993 }
1994 dc->pc += TILEGX_BUNDLE_SIZE_IN_BYTES;
1995 if (++num_insns >= max_insns
1996 || dc->pc >= next_page_start
1997 || tcg_op_buf_full()) {
1998 /* Ending the TB due to TB size or page boundary. Set PC. */
1999 tcg_gen_movi_tl(cpu_pc, dc->pc);
2000 tcg_gen_exit_tb(0);
2001 break;
2002 }
2003 }
2004
2005 gen_tb_end(tb, num_insns);
2006 if (search_pc) {
2007 j = tcg_op_buf_count();
2008 lj++;
2009 while (lj <= j) {
2010 tcg_ctx.gen_opc_instr_start[lj++] = 0;
2011 }
2012 } else {
2013 tb->size = dc->pc - pc_start;
2014 tb->icount = num_insns;
2015 }
2016
2017 qemu_log_mask(CPU_LOG_TB_IN_ASM, "\n");
2018}
2019
2020void gen_intermediate_code(CPUTLGState *env, struct TranslationBlock *tb)
2021{
2022 gen_intermediate_code_internal(tilegx_env_get_cpu(env), tb, false);
2023}
2024
2025void gen_intermediate_code_pc(CPUTLGState *env, struct TranslationBlock *tb)
2026{
2027 gen_intermediate_code_internal(tilegx_env_get_cpu(env), tb, true);
2028}
2029
2030void restore_state_to_opc(CPUTLGState *env, TranslationBlock *tb, int pc_pos)
2031{
2032 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
2033}
2034
2035void tilegx_tcg_init(void)
2036{
2037 int i;
2038
2039 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
2040 cpu_pc = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUTLGState, pc), "pc");
2041 for (i = 0; i < TILEGX_R_COUNT; i++) {
2042 cpu_regs[i] = tcg_global_mem_new_i64(TCG_AREG0,
2043 offsetof(CPUTLGState, regs[i]),
2044 reg_names[i]);
2045 }
2046}