1 /* Simulator for Analog Devices Blackfin processors.
3 Copyright (C) 2005-2011 Free Software Foundation, Inc.
4 Contributed by Analog Devices, Inc.
6 This file is part of simulators.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
28 #include "opcode/bfin.h"
30 #include "dv-bfin_cec.h"
31 #include "dv-bfin_mmu.h"
33 #define HOST_LONG_WORD_SIZE (sizeof (long) * 8)
35 #define SIGNEXTEND(v, n) \
36 (((bs32)(v) << (HOST_LONG_WORD_SIZE - (n))) >> (HOST_LONG_WORD_SIZE - (n)))
38 static __attribute__ ((noreturn)) void
39 illegal_instruction (SIM_CPU *cpu)
41 TRACE_INSN (cpu, "ILLEGAL INSTRUCTION");
43 cec_exception (cpu, VEC_UNDEF_I);
46 static __attribute__ ((noreturn)) void
47 illegal_instruction_combination (SIM_CPU *cpu)
49 TRACE_INSN (cpu, "ILLEGAL INSTRUCTION COMBINATION");
51 cec_exception (cpu, VEC_ILGAL_I);
54 static __attribute__ ((noreturn)) void
55 unhandled_instruction (SIM_CPU *cpu, const char *insn)
57 SIM_DESC sd = CPU_STATE (cpu);
61 TRACE_EVENTS (cpu, "unhandled instruction");
64 iw1 = IFETCH (PCREG + 2);
65 iw2 = ((bu32)iw0 << 16) | iw1;
67 sim_io_eprintf (sd, "Unhandled instruction at 0x%08x (%s opcode 0x", PCREG, insn);
68 if ((iw0 & 0xc000) == 0xc000)
69 sim_io_eprintf (sd, "%08x", iw2);
71 sim_io_eprintf (sd, "%04x", iw0);
73 sim_io_eprintf (sd, ") ... aborting\n");
75 illegal_instruction (cpu);
78 static const char * const astat_names[] =
116 c_0, c_1, c_4, c_2, c_uimm2, c_uimm3, c_imm3, c_pcrel4,
117 c_imm4, c_uimm4s4, c_uimm4s4d, c_uimm4, c_uimm4s2, c_negimm5s4, c_imm5,
118 c_imm5d, c_uimm5, c_imm6, c_imm7, c_imm7d, c_imm8, c_uimm8, c_pcrel8,
119 c_uimm8s4, c_pcrel8s4, c_lppcrel10, c_pcrel10, c_pcrel12, c_imm16s4,
120 c_luimm16, c_imm16, c_imm16d, c_huimm16, c_rimm16, c_imm16s2, c_uimm16s4,
121 c_uimm16s4d, c_uimm16, c_pcrel24, c_uimm32, c_imm32, c_huimm32, c_huimm32e,
138 } constant_formats[] =
140 { "0", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
141 { "1", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
142 { "4", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
143 { "2", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
144 { "uimm2", 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
145 { "uimm3", 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
146 { "imm3", 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
147 { "pcrel4", 4, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
148 { "imm4", 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
149 { "uimm4s4", 4, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0},
150 { "uimm4s4d", 4, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0},
151 { "uimm4", 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
152 { "uimm4s2", 4, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0},
153 { "negimm5s4", 5, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0},
154 { "imm5", 5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
155 { "imm5d", 5, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0},
156 { "uimm5", 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
157 { "imm6", 6, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
158 { "imm7", 7, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
159 { "imm7d", 7, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
160 { "imm8", 8, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
161 { "uimm8", 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
162 { "pcrel8", 8, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
163 { "uimm8s4", 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0},
164 { "pcrel8s4", 8, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
165 { "lppcrel10", 10, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
166 { "pcrel10", 10, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
167 { "pcrel12", 12, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
168 { "imm16s4", 16, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0},
169 { "luimm16", 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
170 { "imm16", 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
171 { "imm16d", 16, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
172 { "huimm16", 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
173 { "rimm16", 16, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
174 { "imm16s2", 16, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0},
175 { "uimm16s4", 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0},
176 { "uimm16s4d", 16, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0},
177 { "uimm16", 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
178 { "pcrel24", 24, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
179 { "uimm32", 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
180 { "imm32", 32, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
181 { "huimm32", 32, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
182 { "huimm32e", 32, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
186 fmtconst_str (const_forms_t cf, bs32 x, bu32 pc)
190 if (constant_formats[cf].reloc)
192 bu32 ea = (((constant_formats[cf].pcrel ? SIGNEXTEND (x, constant_formats[cf].nbits)
193 : x) + constant_formats[cf].offset) << constant_formats[cf].scale);
194 if (constant_formats[cf].pcrel)
196 /*if (outf->symbol_at_address_func (ea, outf) || !constant_formats[cf].exact)
198 outf->print_address_func (ea, outf);
203 sprintf (buf, "%#x", x);
208 /* Negative constants have an implied sign bit. */
209 if (constant_formats[cf].negative)
211 int nb = constant_formats[cf].nbits + 1;
213 x = x | (1 << constant_formats[cf].nbits);
214 x = SIGNEXTEND (x, nb);
217 x = constant_formats[cf].issigned ? SIGNEXTEND (x, constant_formats[cf].nbits) : x;
219 if (constant_formats[cf].offset)
220 x += constant_formats[cf].offset;
222 if (constant_formats[cf].scale)
223 x <<= constant_formats[cf].scale;
225 if (constant_formats[cf].decimal)
227 if (constant_formats[cf].leading)
230 sprintf (ps, "%%%ii", constant_formats[cf].leading);
231 sprintf (buf, ps, x);
234 sprintf (buf, "%i", x);
238 if (constant_formats[cf].issigned && x < 0)
239 sprintf (buf, "-0x%x", abs (x));
241 sprintf (buf, "0x%x", x);
248 fmtconst_val (const_forms_t cf, bu32 x, bu32 pc)
250 if (0 && constant_formats[cf].reloc)
252 bu32 ea = (((constant_formats[cf].pcrel
253 ? (bu32)SIGNEXTEND (x, constant_formats[cf].nbits)
254 : x) + constant_formats[cf].offset)
255 << constant_formats[cf].scale);
256 if (constant_formats[cf].pcrel)
262 /* Negative constants have an implied sign bit. */
263 if (constant_formats[cf].negative)
265 int nb = constant_formats[cf].nbits + 1;
266 x = x | (1 << constant_formats[cf].nbits);
267 x = SIGNEXTEND (x, nb);
269 else if (constant_formats[cf].issigned)
270 x = SIGNEXTEND (x, constant_formats[cf].nbits);
272 x += constant_formats[cf].offset;
273 x <<= constant_formats[cf].scale;
278 #define uimm16s4(x) fmtconst_val (c_uimm16s4, x, 0)
279 #define uimm16s4_str(x) fmtconst_str (c_uimm16s4, x, 0)
280 #define uimm16s4d(x) fmtconst_val (c_uimm16s4d, x, 0)
281 #define pcrel4(x) fmtconst_val (c_pcrel4, x, pc)
282 #define pcrel8(x) fmtconst_val (c_pcrel8, x, pc)
283 #define pcrel8s4(x) fmtconst_val (c_pcrel8s4, x, pc)
284 #define pcrel10(x) fmtconst_val (c_pcrel10, x, pc)
285 #define pcrel12(x) fmtconst_val (c_pcrel12, x, pc)
286 #define negimm5s4(x) fmtconst_val (c_negimm5s4, x, 0)
287 #define negimm5s4_str(x) fmtconst_str (c_negimm5s4, x, 0)
288 #define rimm16(x) fmtconst_val (c_rimm16, x, 0)
289 #define huimm16(x) fmtconst_val (c_huimm16, x, 0)
290 #define imm16(x) fmtconst_val (c_imm16, x, 0)
291 #define imm16_str(x) fmtconst_str (c_imm16, x, 0)
292 #define imm16d(x) fmtconst_val (c_imm16d, x, 0)
293 #define uimm2(x) fmtconst_val (c_uimm2, x, 0)
294 #define uimm3(x) fmtconst_val (c_uimm3, x, 0)
295 #define uimm3_str(x) fmtconst_str (c_uimm3, x, 0)
296 #define luimm16(x) fmtconst_val (c_luimm16, x, 0)
297 #define luimm16_str(x) fmtconst_str (c_luimm16, x, 0)
298 #define uimm4(x) fmtconst_val (c_uimm4, x, 0)
299 #define uimm4_str(x) fmtconst_str (c_uimm4, x, 0)
300 #define uimm5(x) fmtconst_val (c_uimm5, x, 0)
301 #define uimm5_str(x) fmtconst_str (c_uimm5, x, 0)
302 #define imm16s2(x) fmtconst_val (c_imm16s2, x, 0)
303 #define imm16s2_str(x) fmtconst_str (c_imm16s2, x, 0)
304 #define uimm8(x) fmtconst_val (c_uimm8, x, 0)
305 #define imm16s4(x) fmtconst_val (c_imm16s4, x, 0)
306 #define imm16s4_str(x) fmtconst_str (c_imm16s4, x, 0)
307 #define uimm4s2(x) fmtconst_val (c_uimm4s2, x, 0)
308 #define uimm4s2_str(x) fmtconst_str (c_uimm4s2, x, 0)
309 #define uimm4s4(x) fmtconst_val (c_uimm4s4, x, 0)
310 #define uimm4s4_str(x) fmtconst_str (c_uimm4s4, x, 0)
311 #define uimm4s4d(x) fmtconst_val (c_uimm4s4d, x, 0)
312 #define lppcrel10(x) fmtconst_val (c_lppcrel10, x, pc)
313 #define imm3(x) fmtconst_val (c_imm3, x, 0)
314 #define imm3_str(x) fmtconst_str (c_imm3, x, 0)
315 #define imm4(x) fmtconst_val (c_imm4, x, 0)
316 #define uimm8s4(x) fmtconst_val (c_uimm8s4, x, 0)
317 #define imm5(x) fmtconst_val (c_imm5, x, 0)
318 #define imm5d(x) fmtconst_val (c_imm5d, x, 0)
319 #define imm6(x) fmtconst_val (c_imm6, x, 0)
320 #define imm7(x) fmtconst_val (c_imm7, x, 0)
321 #define imm7_str(x) fmtconst_str (c_imm7, x, 0)
322 #define imm7d(x) fmtconst_val (c_imm7d, x, 0)
323 #define imm8(x) fmtconst_val (c_imm8, x, 0)
324 #define pcrel24(x) fmtconst_val (c_pcrel24, x, pc)
325 #define pcrel24_str(x) fmtconst_str (c_pcrel24, x, pc)
326 #define uimm16(x) fmtconst_val (c_uimm16, x, 0)
327 #define uimm32(x) fmtconst_val (c_uimm32, x, 0)
328 #define imm32(x) fmtconst_val (c_imm32, x, 0)
329 #define huimm32(x) fmtconst_val (c_huimm32, x, 0)
330 #define huimm32e(x) fmtconst_val (c_huimm32e, x, 0)
332 /* Table C-4. Core Register Encoding Map. */
333 const char * const greg_names[] =
335 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
336 "P0", "P1", "P2", "P3", "P4", "P5", "SP", "FP",
337 "I0", "I1", "I2", "I3", "M0", "M1", "M2", "M3",
338 "B0", "B1", "B2", "B3", "L0", "L1", "L2", "L3",
339 "A0.X", "A0.W", "A1.X", "A1.W", "<res>", "<res>", "ASTAT", "RETS",
340 "<res>", "<res>", "<res>", "<res>", "<res>", "<res>", "<res>", "<res>",
341 "LC0", "LT0", "LB0", "LC1", "LT1", "LB1", "CYCLES", "CYCLES2",
342 "USP", "SEQSTAT", "SYSCFG", "RETI", "RETX", "RETN", "RETE", "EMUDAT",
345 get_allreg_name (int grp, int reg)
347 return greg_names[(grp << 3) | reg];
350 get_preg_name (int reg)
352 return get_allreg_name (1, reg);
356 reg_is_reserved (int grp, int reg)
358 return (grp == 4 && (reg == 4 || reg == 5)) || (grp == 5);
362 get_allreg (SIM_CPU *cpu, int grp, int reg)
364 int fullreg = (grp << 3) | reg;
365 /* REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7,
366 REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP,
367 REG_I0, REG_I1, REG_I2, REG_I3, REG_M0, REG_M1, REG_M2, REG_M3,
368 REG_B0, REG_B1, REG_B2, REG_B3, REG_L0, REG_L1, REG_L2, REG_L3,
369 REG_A0x, REG_A0w, REG_A1x, REG_A1w, , , REG_ASTAT, REG_RETS,
371 REG_LC0, REG_LT0, REG_LB0, REG_LC1, REG_LT1, REG_LB1, REG_CYCLES,
373 REG_USP, REG_SEQSTAT, REG_SYSCFG, REG_RETI, REG_RETX, REG_RETN, REG_RETE,
375 switch (fullreg >> 2)
377 case 0: case 1: return &DREG (reg);
378 case 2: case 3: return &PREG (reg);
379 case 4: return &IREG (reg & 3);
380 case 5: return &MREG (reg & 3);
381 case 6: return &BREG (reg & 3);
382 case 7: return &LREG (reg & 3);
386 case 32: return &AXREG (0);
387 case 33: return &AWREG (0);
388 case 34: return &AXREG (1);
389 case 35: return &AWREG (1);
390 case 39: return &RETSREG;
391 case 48: return &LCREG (0);
392 case 49: return <REG (0);
393 case 50: return &LBREG (0);
394 case 51: return &LCREG (1);
395 case 52: return <REG (1);
396 case 53: return &LBREG (1);
397 case 54: return &CYCLESREG;
398 case 55: return &CYCLES2REG;
399 case 56: return &USPREG;
400 case 57: return &SEQSTATREG;
401 case 58: return &SYSCFGREG;
402 case 59: return &RETIREG;
403 case 60: return &RETXREG;
404 case 61: return &RETNREG;
405 case 62: return &RETEREG;
406 case 63: return &EMUDAT_INREG;
408 illegal_instruction (cpu);
413 amod0 (int s0, int x0)
415 static const char * const mod0[] = {
416 "", " (S)", " (CO)", " (SCO)",
418 int i = s0 + (x0 << 1);
420 if (i < ARRAY_SIZE (mod0))
427 amod0amod2 (int s0, int x0, int aop0)
429 static const char * const mod02[] = {
430 "", " (S)", " (CO)", " (SCO)",
432 " (ASR)", " (S, ASR)", " (CO, ASR)", " (SCO, ASR)",
433 " (ASL)", " (S, ASL)", " (CO, ASL)", " (SCO, ASL)",
435 int i = s0 + (x0 << 1) + (aop0 << 2);
437 if (i < ARRAY_SIZE (mod02))
444 amod1 (int s0, int x0)
446 static const char * const mod1[] = {
449 int i = s0 + (x0 << 1);
451 if (i < ARRAY_SIZE (mod1))
458 mac_optmode (int mmod, int MM)
460 static const char * const omode[] = {
461 [(M_S2RND << 1) + 0] = " (S2RND)",
462 [(M_T << 1) + 0] = " (T)",
463 [(M_W32 << 1) + 0] = " (W32)",
464 [(M_FU << 1) + 0] = " (FU)",
465 [(M_TFU << 1) + 0] = " (TFU)",
466 [(M_IS << 1) + 0] = " (IS)",
467 [(M_ISS2 << 1) + 0] = " (ISS2)",
468 [(M_IH << 1) + 0] = " (IH)",
469 [(M_IU << 1) + 0] = " (IU)",
470 [(M_S2RND << 1) + 1] = " (M, S2RND)",
471 [(M_T << 1) + 1] = " (M, T)",
472 [(M_W32 << 1) + 1] = " (M, W32)",
473 [(M_FU << 1) + 1] = " (M, FU)",
474 [(M_TFU << 1) + 1] = " (M, TFU)",
475 [(M_IS << 1) + 1] = " (M, IS)",
476 [(M_ISS2 << 1) + 1] = " (M, ISS2)",
477 [(M_IH << 1) + 1] = " (M, IH)",
478 [(M_IU << 1) + 1] = " (M, IU)",
480 int i = MM + (mmod << 1);
482 if (i < ARRAY_SIZE (omode) && omode[i])
489 get_store_name (SIM_CPU *cpu, bu32 *p)
491 if (p >= &DREG (0) && p <= &CYCLESREG)
492 return greg_names[p - &DREG (0)];
493 else if (p == &AXREG (0))
494 return greg_names[4 * 8 + 0];
495 else if (p == &AWREG (0))
496 return greg_names[4 * 8 + 1];
497 else if (p == &AXREG (1))
498 return greg_names[4 * 8 + 2];
499 else if (p == &AWREG (1))
500 return greg_names[4 * 8 + 3];
501 else if (p == &ASTATREG (av0))
503 else if (p == &ASTATREG (av0s))
504 return "ASTAT[av0s]";
505 else if (p == &ASTATREG (av1))
507 else if (p == &ASTATREG (av1s))
508 return "ASTAT[av1s]";
509 else if (p == &ASTATREG (v))
511 else if (p == &ASTATREG (vs))
513 else if (p == &ASTATREG (v_copy))
514 return "ASTAT[v_copy]";
515 else if (p == &ASTATREG (az))
517 else if (p == &ASTATREG (an))
519 else if (p == &ASTATREG (az))
521 else if (p == &ASTATREG (ac0))
523 else if (p == &ASTATREG (ac0_copy))
524 return "ASTAT[ac0_copy]";
527 /* Worry about this when we start to STORE() it. */
528 sim_io_eprintf (CPU_STATE (cpu), "STORE(): unknown register\n");
534 queue_store (SIM_CPU *cpu, bu32 *addr, bu32 val)
536 struct store *s = &BFIN_CPU_STATE.stores[BFIN_CPU_STATE.n_stores];
539 TRACE_REGISTER (cpu, "queuing write %s = %#x",
540 get_store_name (cpu, addr), val);
541 ++BFIN_CPU_STATE.n_stores;
543 #define STORE(X, Y) \
545 if (BFIN_CPU_STATE.n_stores == 20) abort (); \
546 queue_store (cpu, &(X), (Y)); \
550 setflags_nz (SIM_CPU *cpu, bu32 val)
552 SET_ASTATREG (az, val == 0);
553 SET_ASTATREG (an, val >> 31);
557 setflags_nz_2x16 (SIM_CPU *cpu, bu32 val)
559 SET_ASTATREG (an, (bs16)val < 0 || (bs16)(val >> 16) < 0);
560 SET_ASTATREG (az, (bs16)val == 0 || (bs16)(val >> 16) == 0);
564 setflags_logical (SIM_CPU *cpu, bu32 val)
566 setflags_nz (cpu, val);
567 SET_ASTATREG (ac0, 0);
572 add_brev (bu32 addend1, bu32 addend2)
581 for (i = 31; i >= 0; --i)
583 b = ((addend1 & mask) >> i) + ((addend2 & mask) >> i);
594 /* This is a bit crazy, but we want to simulate the hardware behavior exactly
595 rather than worry about the circular buffers being used correctly. Which
596 isn't to say there isn't room for improvement here, just that we want to
597 be conservative. See also dagsub(). */
599 dagadd (SIM_CPU *cpu, int dagno, bs32 M)
601 bu64 i = IREG (dagno);
602 bu64 l = LREG (dagno);
603 bu64 b = BREG (dagno);
607 bu32 im32, iml32, lb32, res;
610 /* A naïve implementation that mostly works:
612 if (l && res >= b + l)
614 STORE (IREG (dagno), res);
629 if ((i & msb) || (IM & car))
630 res = (im32 < b) ? iml32 : im32;
632 res = (im32 < b) ? im32 : iml32;
638 if ((IM & car) == (LB & car))
639 res = (im32 < lb32) ? im32 : iml32;
641 res = (im32 < lb32) ? iml32 : im32;
644 STORE (IREG (dagno), res);
648 /* See dagadd() notes above. */
650 dagsub (SIM_CPU *cpu, int dagno, bs32 M)
652 bu64 i = IREG (dagno);
653 bu64 l = LREG (dagno);
654 bu64 b = BREG (dagno);
657 bu64 mbar = (bu32)(~m + 1);
659 bu32 b32, im32, iml32, lb32, res;
662 /* A naïve implementation that mostly works:
666 STORE (IREG (dagno), newi);
681 if (!!((i & msb) && (IM & car)) == !!(LB & car))
682 res = (im32 < lb32) ? im32 : iml32;
684 res = (im32 < lb32) ? iml32 : im32;
691 if (M == 0 || IM & car)
692 res = (im32 < b32) ? iml32 : im32;
694 res = (im32 < b32) ? im32 : iml32;
697 STORE (IREG (dagno), res);
702 ashiftrt (SIM_CPU *cpu, bu40 val, int cnt, int size)
704 int real_cnt = cnt > size ? size : cnt;
705 bu40 sgn = ~(((val & 0xFFFFFFFFFFull) >> (size - 1)) - 1);
706 int sgncnt = size - real_cnt;
708 sgn <<= 16, sgncnt -= 16;
711 val >>= 16, real_cnt -= 16;
714 SET_ASTATREG (an, val >> (size - 1));
715 SET_ASTATREG (az, val == 0);
716 /* XXX: Need to check ASTAT[v] behavior here. */
722 lshiftrt (SIM_CPU *cpu, bu64 val, int cnt, int size)
724 int real_cnt = cnt > size ? size : cnt;
726 val >>= 16, real_cnt -= 16;
737 val &= 0xFFFFFFFFFFull;
740 illegal_instruction (cpu);
743 SET_ASTATREG (an, val >> (size - 1));
744 SET_ASTATREG (az, val == 0);
750 lshift (SIM_CPU *cpu, bu64 val, int cnt, int size, bool saturate)
752 int i, j, real_cnt = cnt > size ? size : cnt;
753 bu64 sgn = ~((val >> (size - 1)) - 1);
754 int mask_cnt = size - 1;
755 bu64 masked, new_val = val, tmp;
763 new_val <<= 16, real_cnt -= 16;
765 new_val <<= real_cnt;
767 masked = new_val & mask;
769 /* If an operation would otherwise cause a positive value to overflow
770 and become negative, instead, saturation limits the result to the
771 maximum positive value for the size register being used.
773 Conversely, if an operation would otherwise cause a negative value
774 to overflow and become positive, saturation limits the result to the
775 maximum negative value for the register size.
777 However, it's a little more complex than looking at sign bits, we need
778 to see if we are shifting the sign information away... */
779 tmp = val & ((~mask << 1) | 1);
782 for (i = 1; i <= real_cnt && saturate; i++)
784 if ((tmp & ((bu64)1 << (size - 1))) !=
785 (((val >> mask_cnt) & 0x1) << mask_cnt))
789 saturate &= (!sgn && (new_val & (1 << mask_cnt)))
790 || (sgn && !(new_val & (1 << mask_cnt)));
795 if (j || (saturate && (new_val & mask)))
796 new_val = sgn == 0 ? 0x7fff : 0x8000, saturate = 1;
800 new_val &= 0xFFFFFFFF;
801 masked &= 0xFFFFFFFF;
802 if (j || (saturate && ((sgn != masked) || (!sgn && new_val == 0))))
803 new_val = sgn == 0 ? 0x7fffffff : 0x80000000, saturate = 1;
806 new_val &= 0xFFFFFFFFFFull;
807 masked &= 0xFFFFFFFFFFull;
810 illegal_instruction (cpu);
814 SET_ASTATREG (an, new_val >> (size - 1));
815 SET_ASTATREG (az, new_val == 0);
816 SET_ASTATREG (v, !!(saturate || j));
818 SET_ASTATREG (vs, 1);
823 algn (bu32 l, bu32 h, bu32 aln)
828 return (l >> (8 * aln)) | (h << (32 - 8 * aln));
832 saturate_s16 (bu64 val, bu32 *overflow)
834 if ((bs64)val < -0x8000ll)
840 if ((bs64)val > 0x7fff)
850 rot40 (bu40 val, int shift, bu32 *cc)
852 const int nbits = 40;
855 shift = CLAMP (shift, -nbits, nbits);
859 /* Reduce everything to rotate left. */
863 ret = shift == nbits ? 0 : val << shift;
864 ret |= shift == 1 ? 0 : val >> ((nbits + 1) - shift);
865 ret |= (bu40)*cc << (shift - 1);
866 *cc = (val >> (nbits - shift)) & 1;
872 rot32 (bu32 val, int shift, bu32 *cc)
874 const int nbits = 32;
877 shift = CLAMP (shift, -nbits, nbits);
881 /* Reduce everything to rotate left. */
885 ret = shift == nbits ? 0 : val << shift;
886 ret |= shift == 1 ? 0 : val >> ((nbits + 1) - shift);
887 ret |= (bu32)*cc << (shift - 1);
888 *cc = (val >> (nbits - shift)) & 1;
894 add32 (SIM_CPU *cpu, bu32 a, bu32 b, int carry, int sat)
896 int flgs = (a >> 31) & 1;
897 int flgo = (b >> 31) & 1;
899 int flgn = (v >> 31) & 1;
900 int overflow = (flgs ^ flgn) & (flgo ^ flgn);
907 flgn = (v >> 31) & 1;
910 SET_ASTATREG (an, flgn);
912 SET_ASTATREG (vs, 1);
913 SET_ASTATREG (v, overflow);
914 ASTATREG (v_internal) |= overflow;
915 SET_ASTATREG (az, v == 0);
917 SET_ASTATREG (ac0, ~a < b);
923 sub32 (SIM_CPU *cpu, bu32 a, bu32 b, int carry, int sat, int parallel)
925 int flgs = (a >> 31) & 1;
926 int flgo = (b >> 31) & 1;
928 int flgn = (v >> 31) & 1;
929 int overflow = (flgs ^ flgo) & (flgn ^ flgs);
936 flgn = (v >> 31) & 1;
939 if (!parallel || flgn)
940 SET_ASTATREG (an, flgn);
942 SET_ASTATREG (vs, 1);
943 if (!parallel || overflow)
944 SET_ASTATREG (v, overflow);
945 if (!parallel || overflow)
946 ASTATREG (v_internal) |= overflow;
947 if (!parallel || v == 0)
948 SET_ASTATREG (az, v == 0);
949 if (carry && (!parallel || b <= a))
950 SET_ASTATREG (ac0, b <= a);
956 add16 (SIM_CPU *cpu, bu16 a, bu16 b, bu32 *carry, bu32 *overfl,
957 bu32 *zero, bu32 *neg, int sat, int scale)
959 int flgs = (a >> 15) & 1;
960 int flgo = (b >> 15) & 1;
961 bs64 v = (bs16)a + (bs16)b;
962 int flgn = (v >> 15) & 1;
963 int overflow = (flgs ^ flgn) & (flgo ^ flgn);
971 v = (a >> 1) + (a & 0x8000) + (b >> 1) + (b & 0x8000)
972 + (((a & 1) + (b & 1)) >> 1);
980 illegal_instruction (cpu);
983 flgn = (v >> 15) & 1;
984 overflow = (flgs ^ flgn) & (flgo ^ flgn);
986 if (v > (bs64)0xffff)
990 v = saturate_s16 (v, 0);
993 *neg |= (v >> 15) & 1;
997 *zero |= (v & 0xFFFF) == 0;
999 *carry |= ((bu16)~a < (bu16)b);
1005 sub16 (SIM_CPU *cpu, bu16 a, bu16 b, bu32 *carry, bu32 *overfl,
1006 bu32 *zero, bu32 *neg, int sat, int scale)
1008 int flgs = (a >> 15) & 1;
1009 int flgo = (b >> 15) & 1;
1010 bs64 v = (bs16)a - (bs16)b;
1011 int flgn = (v >> 15) & 1;
1012 int overflow = (flgs ^ flgo) & (flgn ^ flgs);
1021 v = ((a >> 1) + (a & 0x8000)) - ( (b >> 1) + (b & 0x8000))
1022 + (((a & 1)-(b & 1)));
1025 v = ((v & 0xFFFF) >> 1);
1026 if ((!flgs & !flgo & flgn)
1027 || (flgs & !flgo & !flgn)
1028 || (flgs & flgo & flgn)
1029 || (flgs & !flgo & flgn))
1033 flgn = (v >> 15) & 1;
1034 overflow = (flgs ^ flgo) & (flgn ^ flgs);
1039 if (v > (bs64)0x7fff || v < (bs64)-0xffff)
1043 illegal_instruction (cpu);
1048 v = saturate_s16 (v, 0);
1051 *neg |= (v >> 15) & 1;
1053 *zero |= (v & 0xFFFF) == 0;
1055 *overfl |= overflow;
1057 *carry |= (bu16)b <= (bu16)a;
1062 min32 (SIM_CPU *cpu, bu32 a, bu32 b)
1065 if ((bs32)a > (bs32)b)
1067 setflags_nz (cpu, val);
1068 SET_ASTATREG (v, 0);
1073 max32 (SIM_CPU *cpu, bu32 a, bu32 b)
1076 if ((bs32)a < (bs32)b)
1078 setflags_nz (cpu, val);
1079 SET_ASTATREG (v, 0);
1084 min2x16 (SIM_CPU *cpu, bu32 a, bu32 b)
1087 if ((bs16)a > (bs16)b)
1088 val = (val & 0xFFFF0000) | (b & 0xFFFF);
1089 if ((bs16)(a >> 16) > (bs16)(b >> 16))
1090 val = (val & 0xFFFF) | (b & 0xFFFF0000);
1091 setflags_nz_2x16 (cpu, val);
1092 SET_ASTATREG (v, 0);
1097 max2x16 (SIM_CPU *cpu, bu32 a, bu32 b)
1100 if ((bs16)a < (bs16)b)
1101 val = (val & 0xFFFF0000) | (b & 0xFFFF);
1102 if ((bs16)(a >> 16) < (bs16)(b >> 16))
1103 val = (val & 0xFFFF) | (b & 0xFFFF0000);
1104 setflags_nz_2x16 (cpu, val);
1105 SET_ASTATREG (v, 0);
1110 add_and_shift (SIM_CPU *cpu, bu32 a, bu32 b, int shift)
1113 ASTATREG (v_internal) = 0;
1114 v = add32 (cpu, a, b, 0, 0);
1117 int x = (v >> 30) & 0x3;
1118 if (x == 1 || x == 2)
1119 ASTATREG (v_internal) = 1;
1122 SET_ASTATREG (az, v == 0);
1123 SET_ASTATREG (an, v & 0x80000000);
1124 SET_ASTATREG (v, ASTATREG (v_internal));
1126 SET_ASTATREG (vs, 1);
1131 xor_reduce (bu64 acc0, bu64 acc1)
1135 for (i = 0; i < 40; ++i)
1137 v ^= (acc0 & acc1 & 1);
1144 /* DIVS ( Dreg, Dreg ) ;
1145 Initialize for DIVQ. Set the AQ status bit based on the signs of
1146 the 32-bit dividend and the 16-bit divisor. Left shift the dividend
1147 one bit. Copy AQ into the dividend LSB. */
1149 divs (SIM_CPU *cpu, bu32 pquo, bu16 divisor)
1151 bu16 r = pquo >> 16;
1154 aq = (r ^ divisor) >> 15; /* Extract msb's and compute quotient bit. */
1155 SET_ASTATREG (aq, aq); /* Update global quotient state. */
1159 pquo = (pquo & 0x1FFFF) | (r << 17);
1163 /* DIVQ ( Dreg, Dreg ) ;
1164 Based on AQ status bit, either add or subtract the divisor from
1165 the dividend. Then set the AQ status bit based on the MSBs of the
1166 32-bit dividend and the 16-bit divisor. Left shift the dividend one
1167 bit. Copy the logical inverse of AQ into the dividend LSB. */
1169 divq (SIM_CPU *cpu, bu32 pquo, bu16 divisor)
1171 unsigned short af = pquo >> 16;
1180 aq = (r ^ divisor) >> 15; /* Extract msb's and compute quotient bit. */
1181 SET_ASTATREG (aq, aq); /* Update global quotient state. */
1185 pquo = (pquo & 0x1FFFF) | (r << 17);
1190 Count the number of bits set to 1 in the 32bit value. */
1198 for (i = 0; i < 32; ++i)
1199 ret += !!(val & (1 << i));
1205 reg_check_sup (SIM_CPU *cpu, int grp, int reg)
1208 cec_require_supervisor (cpu);
1212 reg_write (SIM_CPU *cpu, int grp, int reg, bu32 value)
1216 /* ASTAT is special! */
1217 if (grp == 4 && reg == 6)
1223 /* Check supervisor after get_allreg() so exception order is correct. */
1224 whichreg = get_allreg (cpu, grp, reg);
1225 reg_check_sup (cpu, grp, reg);
1227 if (whichreg == &CYCLES2REG)
1228 /* Writes to CYCLES2 goes to the shadow. */
1229 whichreg = &CYCLES2SHDREG;
1230 else if (whichreg == &SEQSTATREG)
1231 /* Register is read only -- discard writes. */
1233 else if (whichreg == &EMUDAT_INREG)
1234 /* Writes to EMUDAT goes to the output. */
1235 whichreg = &EMUDAT_OUTREG;
1236 else if (whichreg == <REG (0) || whichreg == <REG (1))
1237 /* Writes to LT clears LSB automatically. */
1239 else if (whichreg == &AXREG (0) || whichreg == &AXREG (1))
1242 TRACE_REGISTER (cpu, "wrote %s = %#x", get_allreg_name (grp, reg), value);
1248 reg_read (SIM_CPU *cpu, int grp, int reg)
1253 /* ASTAT is special! */
1254 if (grp == 4 && reg == 6)
1257 /* Check supervisor after get_allreg() so exception order is correct. */
1258 whichreg = get_allreg (cpu, grp, reg);
1259 reg_check_sup (cpu, grp, reg);
1263 if (whichreg == &CYCLESREG)
1264 /* Reads of CYCLES reloads CYCLES2 from the shadow. */
1265 SET_CYCLES2REG (CYCLES2SHDREG);
1266 else if ((whichreg == &AXREG (1) || whichreg == &AXREG (0)) && (value & 0x80))
1267 /* Sign extend if necessary. */
1268 value |= 0xFFFFFF00;
1274 get_extended_cycles (SIM_CPU *cpu)
1276 return ((bu64)CYCLES2SHDREG << 32) | CYCLESREG;
1279 /* We can't re-use sim_events_time() because the CYCLES registers may be
1280 written/cleared/reset/stopped/started at any time by software. */
1282 cycles_inc (SIM_CPU *cpu, bu32 inc)
1287 if (!(SYSCFGREG & SYSCFG_CCEN))
1290 cycles = get_extended_cycles (cpu) + inc;
1291 SET_CYCLESREG (cycles);
1292 cycles2 = cycles >> 32;
1293 if (CYCLES2SHDREG != cycles2)
1294 SET_CYCLES2SHDREG (cycles2);
1298 get_unextended_acc (SIM_CPU *cpu, int which)
1300 return ((bu64)(AXREG (which) & 0xff) << 32) | AWREG (which);
1304 get_extended_acc (SIM_CPU *cpu, int which)
1306 bu64 acc = AXREG (which);
1307 /* Sign extend accumulator values before adding. */
1313 acc |= AWREG (which);
1317 /* Perform a multiplication of D registers SRC0 and SRC1, sign- or
1318 zero-extending the result to 64 bit. H0 and H1 determine whether the
1319 high part or the low part of the source registers is used. Store 1 in
1320 *PSAT if saturation occurs, 0 otherwise. */
1322 decode_multfunc (SIM_CPU *cpu, int h0, int h1, int src0, int src1, int mmod,
1325 bu32 s0 = DREG (src0), s1 = DREG (src1);
1339 sgn0 = -(s0 & 0x8000);
1340 sgn1 = -(s1 & 0x8000);
1362 illegal_instruction (cpu);
1366 /* Perform shift correction if appropriate for the mode. */
1368 if (!MM && (mmod == 0 || mmod == M_T || mmod == M_S2RND || mmod == M_W32))
1370 if (val == 0x40000000)
1383 if (mmod == 0 || mmod == M_IS || mmod == M_T || mmod == M_S2RND
1384 || mmod == M_ISS2 || mmod == M_IH || (MM && mmod == M_FU))
1385 val1 |= -(val1 & 0x80000000);
1388 val1 &= 0xFFFFFFFFull;
1394 saturate_s40_astat (bu64 val, bu32 *v)
1396 if ((bs64)val < -((bs64)1 << 39))
1399 return -((bs64)1 << 39);
1401 else if ((bs64)val >= ((bs64)1 << 39) - 1)
1404 return ((bu64)1 << 39) - 1;
1406 *v = 0; /* No overflow. */
1411 saturate_s40 (bu64 val)
1414 return saturate_s40_astat (val, &v);
1418 saturate_s32 (bu64 val, bu32 *overflow)
1420 if ((bs64)val < -0x80000000ll)
1426 if ((bs64)val > 0x7fffffff)
1436 saturate_u32 (bu64 val, bu32 *overflow)
1438 if (val > 0xffffffff)
1448 saturate_u16 (bu64 val, bu32 *overflow)
1464 /* FIXME: Should honour rounding mode. */
1465 if ((val & 0xffff) > 0x8000
1466 || ((val & 0xffff) == 0x8000 && (val & 0x10000)))
1469 sgnbits = val & 0xffff000000000000ull;
1471 return val | sgnbits;
1477 bu64 sgnbits = val & 0xffff000000000000ull;
1479 return val | sgnbits;
1483 signbits (bu64 val, int size)
1485 bu64 mask = (bu64)1 << (size - 1);
1486 bu64 bit = val & mask;
1494 if ((val & mask) != bit)
1504 /* Extract a 16 or 32 bit value from a 64 bit multiplication result.
1505 These 64 bits must be sign- or zero-extended properly from the source
1506 we want to extract, either a 32 bit multiply or a 40 bit accumulator. */
1509 extract_mult (SIM_CPU *cpu, bu64 res, int mmod, int MM,
1510 int fullword, bu32 *overflow)
1517 return saturate_s32 (res, overflow);
1519 return saturate_u32 (res, overflow);
1522 return saturate_s32 (res, overflow);
1523 return saturate_u32 (res, overflow);
1526 return saturate_s32 (res << 1, overflow);
1528 illegal_instruction (cpu);
1535 return saturate_s16 (rnd16 (res), overflow);
1537 return saturate_s32 (rnd16 (res), overflow) & 0xFFFF;
1539 return saturate_s16 (res, overflow);
1542 return saturate_s16 (rnd16 (res), overflow);
1543 return saturate_u16 (rnd16 (res), overflow);
1546 return saturate_s16 (res, overflow);
1547 return saturate_u16 (res, overflow);
1550 return saturate_s16 (trunc16 (res), overflow);
1552 return saturate_u16 (trunc16 (res), overflow);
1555 return saturate_s16 (rnd16 (res << 1), overflow);
1557 return saturate_s16 (res << 1, overflow);
1559 illegal_instruction (cpu);
1564 decode_macfunc (SIM_CPU *cpu, int which, int op, int h0, int h1, int src0,
1565 int src1, int mmod, int MM, int fullword, bu32 *overflow,
1569 bu32 sat = 0, tsat, ret;
1571 /* Sign extend accumulator if necessary, otherwise unsigned. */
1572 if (mmod == 0 || mmod == M_T || mmod == M_IS || mmod == M_ISS2
1573 || mmod == M_S2RND || mmod == M_IH || mmod == M_W32)
1574 acc = get_extended_acc (cpu, which);
1576 acc = get_unextended_acc (cpu, which);
1578 if (MM && (mmod == M_T || mmod == M_IS || mmod == M_ISS2
1579 || mmod == M_S2RND || mmod == M_IH || mmod == M_W32))
1580 acc |= -(acc & 0x80000000);
1584 bu8 sgn0 = (acc >> 31) & 1;
1585 /* This can't saturate, so we don't keep track of the sat flag. */
1586 bu64 res = decode_multfunc (cpu, h0, h1, src0, src1, mmod,
1589 /* Perform accumulation. */
1594 sgn0 = (acc >> 31) & 1;
1612 if ((bs64)acc < -((bs64)1 << 39))
1613 acc = -((bu64)1 << 39), sat = 1;
1614 else if ((bs64)acc > 0x7fffffffffll)
1615 acc = 0x7fffffffffull, sat = 1;
1618 if (!MM && acc > 0xFFFFFFFFFFull)
1620 if (MM && acc > 0xFFFFFFFF)
1624 if (acc & 0x8000000000000000ull)
1626 if (acc > 0xFFFFFFFFFFull)
1627 acc &= 0xFFFFFFFFFFull, sat = 1;
1628 if (MM && acc > 0xFFFFFFFF)
1630 if (acc & 0x80000000)
1631 acc |= 0xffffffff00000000ull;
1634 if (!MM && (bs64)acc < 0)
1636 if (MM && (bs64)acc < -((bs64)1 << 39))
1637 acc = -((bu64)1 << 39), sat = 1;
1638 if (!MM && (bs64)acc > (bs64)0xFFFFFFFFFFll)
1639 acc = 0xFFFFFFFFFFull, sat = 1;
1640 if (MM && acc > 0xFFFFFFFFFFull)
1641 acc &= 0xFFFFFFFFFFull;
1642 if (MM && acc & 0x80000000)
1643 acc |= 0xffffffff00000000ull;
1646 if ((bs64)acc < -0x80000000ll)
1647 acc = -0x80000000ull, sat = 1;
1648 else if ((bs64)acc >= 0x7fffffffll)
1649 acc = 0x7fffffffull, sat = 1;
1652 if (sgn0 && (sgn0 != ((acc >> 31) & 1))
1653 && (((acc >> 32) & 0xFF) == 0xff))
1656 if (acc & 0x80000000)
1657 acc |= 0xffffffff00000000ull;
1660 illegal_instruction (cpu);
1663 if (acc & 0x8000000000ull)
1666 STORE (AXREG (which), (acc >> 32) & 0xff);
1667 STORE (AWREG (which), acc & 0xffffffff);
1668 STORE (ASTATREG (av[which]), sat);
1670 STORE (ASTATREG (avs[which]), sat);
1673 ret = extract_mult (cpu, acc, mmod, MM, fullword, overflow);
1682 if (ret & 0x80000000)
1690 hwloop_get_next_pc (SIM_CPU *cpu, bu32 pc, bu32 insn_len)
1697 /* If our PC has reached the bottom of a hardware loop,
1698 move back up to the top of the hardware loop. */
1699 for (i = 1; i >= 0; --i)
1700 if (LCREG (i) > 1 && pc == LBREG (i))
1702 TRACE_BRANCH (cpu, pc, LTREG (i), i, "Hardware loop %i", i);
1706 return pc + insn_len;
1710 decode_ProgCtrl_0 (SIM_CPU *cpu, bu16 iw0, bu32 pc)
1713 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
1714 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |.prgfunc.......|.poprnd........|
1715 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
1716 int poprnd = ((iw0 >> ProgCtrl_poprnd_bits) & ProgCtrl_poprnd_mask);
1717 int prgfunc = ((iw0 >> ProgCtrl_prgfunc_bits) & ProgCtrl_prgfunc_mask);
1719 TRACE_EXTRACT (cpu, "%s: poprnd:%i prgfunc:%i", __func__, poprnd, prgfunc);
1721 if (prgfunc == 0 && poprnd == 0)
1723 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_nop);
1724 TRACE_INSN (cpu, "NOP;");
1726 else if (prgfunc == 1 && poprnd == 0)
1728 bu32 newpc = RETSREG;
1729 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1730 TRACE_INSN (cpu, "RTS;");
1731 IFETCH_CHECK (newpc);
1733 illegal_instruction_combination (cpu);
1734 TRACE_BRANCH (cpu, pc, newpc, -1, "RTS");
1736 BFIN_CPU_STATE.did_jump = true;
1739 else if (prgfunc == 1 && poprnd == 1)
1741 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1742 TRACE_INSN (cpu, "RTI;");
1743 /* Do not do IFETCH_CHECK here -- LSB has special meaning. */
1745 illegal_instruction_combination (cpu);
1746 cec_return (cpu, -1);
1749 else if (prgfunc == 1 && poprnd == 2)
1751 bu32 newpc = RETXREG;
1752 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1753 TRACE_INSN (cpu, "RTX;");
1754 /* XXX: Not sure if this is what the hardware does. */
1755 IFETCH_CHECK (newpc);
1757 illegal_instruction_combination (cpu);
1758 cec_return (cpu, IVG_EVX);
1761 else if (prgfunc == 1 && poprnd == 3)
1763 bu32 newpc = RETNREG;
1764 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1765 TRACE_INSN (cpu, "RTN;");
1766 /* XXX: Not sure if this is what the hardware does. */
1767 IFETCH_CHECK (newpc);
1769 illegal_instruction_combination (cpu);
1770 cec_return (cpu, IVG_NMI);
1773 else if (prgfunc == 1 && poprnd == 4)
1775 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1776 TRACE_INSN (cpu, "RTE;");
1778 illegal_instruction_combination (cpu);
1779 cec_return (cpu, IVG_EMU);
1782 else if (prgfunc == 2 && poprnd == 0)
1784 SIM_DESC sd = CPU_STATE (cpu);
1785 sim_events *events = STATE_EVENTS (sd);
1787 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync);
1788 /* XXX: in supervisor mode, utilizes wake up sources
1789 in user mode, it's a NOP ... */
1790 TRACE_INSN (cpu, "IDLE;");
1793 illegal_instruction_combination (cpu);
1797 CYCLE_DELAY = events->time_from_event;
1799 abort (); /* XXX: Should this ever happen ? */
1801 else if (prgfunc == 2 && poprnd == 3)
1803 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync);
1805 TRACE_INSN (cpu, "CSYNC;");
1807 illegal_instruction_combination (cpu);
1810 else if (prgfunc == 2 && poprnd == 4)
1812 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync);
1814 TRACE_INSN (cpu, "SSYNC;");
1816 illegal_instruction_combination (cpu);
1818 /* Really 10+, but no model info for this. */
1821 else if (prgfunc == 2 && poprnd == 5)
1823 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
1824 TRACE_INSN (cpu, "EMUEXCPT;");
1826 illegal_instruction_combination (cpu);
1827 cec_exception (cpu, VEC_SIM_TRAP);
1829 else if (prgfunc == 3 && poprnd < 8)
1831 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
1832 TRACE_INSN (cpu, "CLI R%i;", poprnd);
1834 illegal_instruction_combination (cpu);
1835 SET_DREG (poprnd, cec_cli (cpu));
1837 else if (prgfunc == 4 && poprnd < 8)
1839 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
1840 TRACE_INSN (cpu, "STI R%i;", poprnd);
1842 illegal_instruction_combination (cpu);
1843 cec_sti (cpu, DREG (poprnd));
1846 else if (prgfunc == 5 && poprnd < 8)
1848 bu32 newpc = PREG (poprnd);
1849 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1850 TRACE_INSN (cpu, "JUMP (%s);", get_preg_name (poprnd));
1851 IFETCH_CHECK (newpc);
1853 illegal_instruction_combination (cpu);
1854 TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP (Preg)");
1856 BFIN_CPU_STATE.did_jump = true;
1857 PROFILE_BRANCH_TAKEN (cpu);
1860 else if (prgfunc == 6 && poprnd < 8)
1862 bu32 newpc = PREG (poprnd);
1863 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1864 TRACE_INSN (cpu, "CALL (%s);", get_preg_name (poprnd));
1865 IFETCH_CHECK (newpc);
1867 illegal_instruction_combination (cpu);
1868 TRACE_BRANCH (cpu, pc, newpc, -1, "CALL (Preg)");
1869 /* If we're at the end of a hardware loop, RETS is going to be
1870 the top of the loop rather than the next instruction. */
1871 SET_RETSREG (hwloop_get_next_pc (cpu, pc, 2));
1873 BFIN_CPU_STATE.did_jump = true;
1874 PROFILE_BRANCH_TAKEN (cpu);
1877 else if (prgfunc == 7 && poprnd < 8)
1879 bu32 newpc = pc + PREG (poprnd);
1880 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1881 TRACE_INSN (cpu, "CALL (PC + %s);", get_preg_name (poprnd));
1882 IFETCH_CHECK (newpc);
1884 illegal_instruction_combination (cpu);
1885 TRACE_BRANCH (cpu, pc, newpc, -1, "CALL (PC + Preg)");
1886 SET_RETSREG (hwloop_get_next_pc (cpu, pc, 2));
1888 BFIN_CPU_STATE.did_jump = true;
1889 PROFILE_BRANCH_TAKEN (cpu);
1892 else if (prgfunc == 8 && poprnd < 8)
1894 bu32 newpc = pc + PREG (poprnd);
1895 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
1896 TRACE_INSN (cpu, "JUMP (PC + %s);", get_preg_name (poprnd));
1897 IFETCH_CHECK (newpc);
1899 illegal_instruction_combination (cpu);
1900 TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP (PC + Preg)");
1902 BFIN_CPU_STATE.did_jump = true;
1903 PROFILE_BRANCH_TAKEN (cpu);
1906 else if (prgfunc == 9)
1908 int raise = uimm4 (poprnd);
1909 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
1910 TRACE_INSN (cpu, "RAISE %s;", uimm4_str (raise));
1912 illegal_instruction_combination (cpu);
1913 cec_require_supervisor (cpu);
1914 if (raise == IVG_IVHW)
1915 cec_hwerr (cpu, HWERR_RAISE_5);
1917 cec_latch (cpu, raise);
1918 CYCLE_DELAY = 3; /* XXX: Only if IVG is unmasked. */
1920 else if (prgfunc == 10)
1922 int excpt = uimm4 (poprnd);
1923 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
1924 TRACE_INSN (cpu, "EXCPT %s;", uimm4_str (excpt));
1926 illegal_instruction_combination (cpu);
1927 cec_exception (cpu, excpt);
1930 else if (prgfunc == 11 && poprnd < 6)
1932 bu32 addr = PREG (poprnd);
1934 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_atomic);
1935 TRACE_INSN (cpu, "TESTSET (%s);", get_preg_name (poprnd));
1937 illegal_instruction_combination (cpu);
1938 byte = GET_WORD (addr);
1939 SET_CCREG (byte == 0);
1940 PUT_BYTE (addr, byte | 0x80);
1941 /* Also includes memory stalls, but we don't model that. */
1945 illegal_instruction (cpu);
1949 decode_CaCTRL_0 (SIM_CPU *cpu, bu16 iw0)
1952 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
1953 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |.a.|.op....|.reg.......|
1954 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
1955 int a = ((iw0 >> CaCTRL_a_bits) & CaCTRL_a_mask);
1956 int op = ((iw0 >> CaCTRL_op_bits) & CaCTRL_op_mask);
1957 int reg = ((iw0 >> CaCTRL_reg_bits) & CaCTRL_reg_mask);
1958 bu32 preg = PREG (reg);
1959 const char * const sinsn[] = { "PREFETCH", "FLUSHINV", "FLUSH", "IFLUSH", };
1961 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CaCTRL);
1962 TRACE_EXTRACT (cpu, "%s: a:%i op:%i reg:%i", __func__, a, op, reg);
1963 TRACE_INSN (cpu, "%s [%s%s];", sinsn[op], get_preg_name (reg), a ? "++" : "");
1966 /* None of these can be part of a parallel instruction. */
1967 illegal_instruction_combination (cpu);
1969 /* No cache simulation, so these are (mostly) all NOPs.
1970 XXX: The hardware takes care of masking to cache lines, but need
1971 to check behavior of the post increment. Should we be aligning
1972 the value to the cache line before adding the cache line size, or
1973 do we just add the cache line size ? */
1976 mmu_check_cache_addr (cpu, preg, false, false);
1980 mmu_check_cache_addr (cpu, preg, true, false);
1984 mmu_check_cache_addr (cpu, preg, true, false);
1988 mmu_check_cache_addr (cpu, preg, false, true);
1992 SET_PREG (reg, preg + BFIN_L1_CACHE_BYTES);
1996 decode_PushPopReg_0 (SIM_CPU *cpu, bu16 iw0)
1999 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |.W.|.grp.......|.reg.......|
2001 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2002 int W = ((iw0 >> PushPopReg_W_bits) & PushPopReg_W_mask);
2003 int grp = ((iw0 >> PushPopReg_grp_bits) & PushPopReg_grp_mask);
2004 int reg = ((iw0 >> PushPopReg_reg_bits) & PushPopReg_reg_mask);
2005 const char *reg_name = get_allreg_name (grp, reg);
2009 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PushPopReg);
2010 TRACE_EXTRACT (cpu, "%s: W:%i grp:%i reg:%i", __func__, W, grp, reg);
2011 TRACE_DECODE (cpu, "%s: reg:%s", __func__, reg_name);
2013 /* Can't push/pop reserved registers */
2014 if (reg_is_reserved (grp, reg))
2015 illegal_instruction (cpu);
2019 /* Dreg and Preg are not supported by this instruction. */
2020 if (grp == 0 || grp == 1)
2021 illegal_instruction (cpu);
2022 TRACE_INSN (cpu, "%s = [SP++];", reg_name);
2023 /* Can't pop USP while in userspace. */
2024 if (INSN_LEN == 8 || (grp == 7 && reg == 0 && cec_is_user_mode(cpu)))
2025 illegal_instruction_combination (cpu);
2026 /* XXX: The valid register check is in reg_write(), so we might
2027 incorrectly do a GET_LONG() here ... */
2028 value = GET_LONG (sp);
2029 reg_write (cpu, grp, reg, value);
2030 if (grp == 7 && reg == 3)
2037 TRACE_INSN (cpu, "[--SP] = %s;", reg_name);
2039 illegal_instruction_combination (cpu);
2042 value = reg_read (cpu, grp, reg);
2043 if (grp == 7 && reg == 3)
2044 cec_push_reti (cpu);
2046 PUT_LONG (sp, value);
2049 /* Note: SP update must be delayed until after all reads/writes; see
2050 comments in decode_PushPopMultiple_0() for more info. */
2055 decode_PushPopMultiple_0 (SIM_CPU *cpu, bu16 iw0)
2058 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2059 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |.d.|.p.|.W.|.dr........|.pr........|
2060 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2061 int p = ((iw0 >> PushPopMultiple_p_bits) & PushPopMultiple_p_mask);
2062 int d = ((iw0 >> PushPopMultiple_d_bits) & PushPopMultiple_d_mask);
2063 int W = ((iw0 >> PushPopMultiple_W_bits) & PushPopMultiple_W_mask);
2064 int dr = ((iw0 >> PushPopMultiple_dr_bits) & PushPopMultiple_dr_mask);
2065 int pr = ((iw0 >> PushPopMultiple_pr_bits) & PushPopMultiple_pr_mask);
2069 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PushPopMultiple);
2070 TRACE_EXTRACT (cpu, "%s: d:%i p:%i W:%i dr:%i pr:%i",
2071 __func__, d, p, W, dr, pr);
2073 if ((d == 0 && p == 0) || (p && imm5 (pr) > 5)
2074 || (d && !p && pr) || (p && !d && dr))
2075 illegal_instruction (cpu);
2080 TRACE_INSN (cpu, "[--SP] = (R7:%i, P5:%i);", dr, pr);
2082 TRACE_INSN (cpu, "[--SP] = (R7:%i);", dr);
2084 TRACE_INSN (cpu, "[--SP] = (P5:%i);", pr);
2087 for (i = dr; i < 8; i++)
2090 PUT_LONG (sp, DREG (i));
2093 for (i = pr; i < 6; i++)
2096 PUT_LONG (sp, PREG (i));
2104 TRACE_INSN (cpu, "(R7:%i, P5:%i) = [SP++];", dr, pr);
2106 TRACE_INSN (cpu, "(R7:%i) = [SP++];", dr);
2108 TRACE_INSN (cpu, "(P5:%i) = [SP++];", pr);
2111 for (i = 5; i >= pr; i--)
2113 SET_PREG (i, GET_LONG (sp));
2117 for (i = 7; i >= dr; i--)
2119 SET_DREG (i, GET_LONG (sp));
2126 /* Note: SP update must be delayed until after all reads/writes so that
2127 if an exception does occur, the insn may be re-executed as the
2128 SP has not yet changed. */
2133 decode_ccMV_0 (SIM_CPU *cpu, bu16 iw0)
2136 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2137 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |.T.|.d.|.s.|.dst.......|.src.......|
2138 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2139 int s = ((iw0 >> CCmv_s_bits) & CCmv_s_mask);
2140 int d = ((iw0 >> CCmv_d_bits) & CCmv_d_mask);
2141 int T = ((iw0 >> CCmv_T_bits) & CCmv_T_mask);
2142 int src = ((iw0 >> CCmv_src_bits) & CCmv_src_mask);
2143 int dst = ((iw0 >> CCmv_dst_bits) & CCmv_dst_mask);
2144 int cond = T ? CCREG : ! CCREG;
2146 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ccMV);
2147 TRACE_EXTRACT (cpu, "%s: T:%i d:%i s:%i dst:%i src:%i",
2148 __func__, T, d, s, dst, src);
2150 TRACE_INSN (cpu, "IF %sCC %s = %s;", T ? "" : "! ",
2151 get_allreg_name (d, dst),
2152 get_allreg_name (s, src));
2154 illegal_instruction_combination (cpu);
2157 reg_write (cpu, d, dst, reg_read (cpu, s, src));
2161 decode_CCflag_0 (SIM_CPU *cpu, bu16 iw0)
2164 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2165 | 0 | 0 | 0 | 0 | 1 |.I.|.opc.......|.G.|.y.........|.x.........|
2166 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2167 int x = ((iw0 >> CCflag_x_bits) & CCflag_x_mask);
2168 int y = ((iw0 >> CCflag_y_bits) & CCflag_y_mask);
2169 int I = ((iw0 >> CCflag_I_bits) & CCflag_I_mask);
2170 int G = ((iw0 >> CCflag_G_bits) & CCflag_G_mask);
2171 int opc = ((iw0 >> CCflag_opc_bits) & CCflag_opc_mask);
2173 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CCflag);
2174 TRACE_EXTRACT (cpu, "%s: I:%i opc:%i G:%i y:%i x:%i",
2175 __func__, I, opc, G, y, x);
2179 bs64 acc0 = get_extended_acc (cpu, 0);
2180 bs64 acc1 = get_extended_acc (cpu, 1);
2181 bs64 diff = acc0 - acc1;
2183 if (x != 0 || y != 0)
2184 illegal_instruction (cpu);
2186 if (opc == 5 && I == 0 && G == 0)
2188 TRACE_INSN (cpu, "CC = A0 == A1;");
2190 illegal_instruction_combination (cpu);
2191 SET_CCREG (acc0 == acc1);
2193 else if (opc == 6 && I == 0 && G == 0)
2195 TRACE_INSN (cpu, "CC = A0 < A1");
2197 illegal_instruction_combination (cpu);
2198 SET_CCREG (acc0 < acc1);
2200 else if (opc == 7 && I == 0 && G == 0)
2202 TRACE_INSN (cpu, "CC = A0 <= A1");
2204 illegal_instruction_combination (cpu);
2205 SET_CCREG (acc0 <= acc1);
2208 illegal_instruction (cpu);
2210 SET_ASTATREG (az, diff == 0);
2211 SET_ASTATREG (an, diff < 0);
2212 SET_ASTATREG (ac0, (bu40)acc1 <= (bu40)acc0);
2216 int issigned = opc < 3;
2217 const char *sign = issigned ? "" : " (IU)";
2218 bu32 srcop = G ? PREG (x) : DREG (x);
2219 char s = G ? 'P' : 'R';
2220 bu32 dstop = I ? (issigned ? imm3 (y) : uimm3 (y)) : G ? PREG (y) : DREG (y);
2222 char d = G ? 'P' : 'R';
2223 int flgs = srcop >> 31;
2224 int flgo = dstop >> 31;
2226 bu32 result = srcop - dstop;
2228 int flgn = result >> 31;
2229 int overflow = (flgs ^ flgo) & (flgn ^ flgs);
2230 int az = result == 0;
2231 int ac0 = dstop <= srcop;
2234 an = (flgn && !overflow) || (!flgn && overflow);
2240 default: /* Shutup useless gcc warnings. */
2241 case 0: /* signed */
2245 case 1: /* signed */
2249 case 2: /* signed */
2253 case 3: /* unsigned */
2257 case 4: /* unsigned */
2264 TRACE_INSN (cpu, "CC = %c%i %s %s%s;", s, x, op,
2265 issigned ? imm3_str (y) : uimm3_str (y), sign);
2268 TRACE_DECODE (cpu, "%s %c%i:%x %c%i:%x", __func__,
2269 s, x, srcop, d, y, dstop);
2270 TRACE_INSN (cpu, "CC = %c%i %s %c%i%s;", s, x, op, d, y, sign);
2274 /* Pointer compares only touch CC. */
2277 SET_ASTATREG (az, az);
2278 SET_ASTATREG (an, an);
2279 SET_ASTATREG (ac0, ac0);
2285 decode_CC2dreg_0 (SIM_CPU *cpu, bu16 iw0)
2288 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2289 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |.op....|.reg.......|
2290 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2291 int op = ((iw0 >> CC2dreg_op_bits) & CC2dreg_op_mask);
2292 int reg = ((iw0 >> CC2dreg_reg_bits) & CC2dreg_reg_mask);
2294 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CC2dreg);
2295 TRACE_EXTRACT (cpu, "%s: op:%i reg:%i", __func__, op, reg);
2299 TRACE_INSN (cpu, "R%i = CC;", reg);
2301 illegal_instruction_combination (cpu);
2302 SET_DREG (reg, CCREG);
2306 TRACE_INSN (cpu, "CC = R%i;", reg);
2308 illegal_instruction_combination (cpu);
2309 SET_CCREG (DREG (reg) != 0);
2311 else if (op == 3 && reg == 0)
2313 TRACE_INSN (cpu, "CC = !CC;");
2315 illegal_instruction_combination (cpu);
2319 illegal_instruction (cpu);
2323 decode_CC2stat_0 (SIM_CPU *cpu, bu16 iw0)
2326 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2327 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |.D.|.op....|.cbit..............|
2328 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2329 int D = ((iw0 >> CC2stat_D_bits) & CC2stat_D_mask);
2330 int op = ((iw0 >> CC2stat_op_bits) & CC2stat_op_mask);
2331 int cbit = ((iw0 >> CC2stat_cbit_bits) & CC2stat_cbit_mask);
2334 const char * const op_names[] = { "", "|", "&", "^" } ;
2336 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CC2stat);
2337 TRACE_EXTRACT (cpu, "%s: D:%i op:%i cbit:%i", __func__, D, op, cbit);
2339 TRACE_INSN (cpu, "%s %s= %s;", D ? astat_names[cbit] : "CC",
2340 op_names[op], D ? "CC" : astat_names[cbit]);
2342 /* CC = CC; is invalid. */
2344 illegal_instruction (cpu);
2347 illegal_instruction_combination (cpu);
2349 pval = !!(ASTAT & (1 << cbit));
2353 case 0: SET_CCREG (pval); break;
2354 case 1: SET_CCREG (CCREG | pval); break;
2355 case 2: SET_CCREG (CCREG & pval); break;
2356 case 3: SET_CCREG (CCREG ^ pval); break;
2362 case 0: pval = CCREG; break;
2363 case 1: pval |= CCREG; break;
2364 case 2: pval &= CCREG; break;
2365 case 3: pval ^= CCREG; break;
2367 TRACE_REGISTER (cpu, "wrote ASTAT[%s] = %i", astat_names[cbit], pval);
2368 SET_ASTAT ((ASTAT & ~(1 << cbit)) | (pval << cbit));
2373 decode_BRCC_0 (SIM_CPU *cpu, bu16 iw0, bu32 pc)
2376 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2377 | 0 | 0 | 0 | 1 |.T.|.B.|.offset................................|
2378 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2379 int B = ((iw0 >> BRCC_B_bits) & BRCC_B_mask);
2380 int T = ((iw0 >> BRCC_T_bits) & BRCC_T_mask);
2381 int offset = ((iw0 >> BRCC_offset_bits) & BRCC_offset_mask);
2382 int cond = T ? CCREG : ! CCREG;
2383 int pcrel = pcrel10 (offset);
2385 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_BRCC);
2386 TRACE_EXTRACT (cpu, "%s: T:%i B:%i offset:%#x", __func__, T, B, offset);
2387 TRACE_DECODE (cpu, "%s: pcrel10:%#x", __func__, pcrel);
2389 TRACE_INSN (cpu, "IF %sCC JUMP %#x%s;", T ? "" : "! ",
2390 pcrel, B ? " (bp)" : "");
2393 illegal_instruction_combination (cpu);
2397 bu32 newpc = pc + pcrel;
2398 TRACE_BRANCH (cpu, pc, newpc, -1, "Conditional JUMP");
2400 BFIN_CPU_STATE.did_jump = true;
2401 PROFILE_BRANCH_TAKEN (cpu);
2402 CYCLE_DELAY = B ? 5 : 9;
2406 PROFILE_BRANCH_UNTAKEN (cpu);
2407 CYCLE_DELAY = B ? 9 : 1;
2412 decode_UJUMP_0 (SIM_CPU *cpu, bu16 iw0, bu32 pc)
2415 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2416 | 0 | 0 | 1 | 0 |.offset........................................|
2417 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2418 int offset = ((iw0 >> UJump_offset_bits) & UJump_offset_mask);
2419 int pcrel = pcrel12 (offset);
2420 bu32 newpc = pc + pcrel;
2422 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_UJUMP);
2423 TRACE_EXTRACT (cpu, "%s: offset:%#x", __func__, offset);
2424 TRACE_DECODE (cpu, "%s: pcrel12:%#x", __func__, pcrel);
2426 TRACE_INSN (cpu, "JUMP.S %#x;", pcrel);
2429 illegal_instruction_combination (cpu);
2431 TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP.S");
2434 BFIN_CPU_STATE.did_jump = true;
2435 PROFILE_BRANCH_TAKEN (cpu);
2440 decode_REGMV_0 (SIM_CPU *cpu, bu16 iw0)
2443 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2444 | 0 | 0 | 1 | 1 |.gd........|.gs........|.dst.......|.src.......|
2445 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2446 int gs = ((iw0 >> RegMv_gs_bits) & RegMv_gs_mask);
2447 int gd = ((iw0 >> RegMv_gd_bits) & RegMv_gd_mask);
2448 int src = ((iw0 >> RegMv_src_bits) & RegMv_src_mask);
2449 int dst = ((iw0 >> RegMv_dst_bits) & RegMv_dst_mask);
2450 const char *srcreg_name = get_allreg_name (gs, src);
2451 const char *dstreg_name = get_allreg_name (gd, dst);
2453 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_REGMV);
2454 TRACE_EXTRACT (cpu, "%s: gd:%i gs:%i dst:%i src:%i",
2455 __func__, gd, gs, dst, src);
2456 TRACE_DECODE (cpu, "%s: dst:%s src:%s", __func__, dstreg_name, srcreg_name);
2458 TRACE_INSN (cpu, "%s = %s;", dstreg_name, srcreg_name);
2460 /* Reserved slots cannot be a src/dst. */
2461 if (reg_is_reserved (gs, src) || reg_is_reserved (gd, dst))
2464 /* Standard register moves. */
2465 if ((gs < 2) /* Dregs/Pregs src */
2466 || (gd < 2) /* Dregs/Pregs dst */
2467 || (gs == 4 && src < 4) /* Accumulators src */
2468 || (gd == 4 && dst < 4 && (gs < 4)) /* Accumulators dst */
2469 || (gs == 7 && src == 7 && !(gd == 4 && dst < 4)) /* EMUDAT src */
2470 || (gd == 7 && dst == 7)) /* EMUDAT dst */
2473 /* dareg = dareg (IMBL) */
2474 if (gs < 4 && gd < 4)
2477 /* USP can be src to sysregs, but not dagregs. */
2478 if ((gs == 7 && src == 0) && (gd >= 4))
2481 /* USP can move between genregs (only check Accumulators). */
2482 if (((gs == 7 && src == 0) && (gd == 4 && dst < 4))
2483 || ((gd == 7 && dst == 0) && (gs == 4 && src < 4)))
2486 /* Still here ? Invalid reg pair. */
2488 illegal_instruction (cpu);
2491 reg_write (cpu, gd, dst, reg_read (cpu, gs, src));
2495 decode_ALU2op_0 (SIM_CPU *cpu, bu16 iw0)
2498 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2499 | 0 | 1 | 0 | 0 | 0 | 0 |.opc...........|.src.......|.dst.......|
2500 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2501 int src = ((iw0 >> ALU2op_src_bits) & ALU2op_src_mask);
2502 int opc = ((iw0 >> ALU2op_opc_bits) & ALU2op_opc_mask);
2503 int dst = ((iw0 >> ALU2op_dst_bits) & ALU2op_dst_mask);
2505 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ALU2op);
2506 TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst);
2510 TRACE_INSN (cpu, "R%i >>>= R%i;", dst, src);
2511 SET_DREG (dst, ashiftrt (cpu, DREG (dst), DREG (src), 32));
2516 TRACE_INSN (cpu, "R%i >>= R%i;", dst, src);
2517 if (DREG (src) <= 0x1F)
2518 val = lshiftrt (cpu, DREG (dst), DREG (src), 32);
2521 SET_DREG (dst, val);
2525 TRACE_INSN (cpu, "R%i <<= R%i;", dst, src);
2526 SET_DREG (dst, lshift (cpu, DREG (dst), DREG (src), 32, 0));
2530 TRACE_INSN (cpu, "R%i *= R%i;", dst, src);
2531 SET_DREG (dst, DREG (dst) * DREG (src));
2536 TRACE_INSN (cpu, "R%i = (R%i + R%i) << 1;", dst, dst, src);
2537 SET_DREG (dst, add_and_shift (cpu, DREG (dst), DREG (src), 1));
2541 TRACE_INSN (cpu, "R%i = (R%i + R%i) << 2;", dst, dst, src);
2542 SET_DREG (dst, add_and_shift (cpu, DREG (dst), DREG (src), 2));
2546 TRACE_INSN (cpu, "DIVQ ( R%i, R%i );", dst, src);
2547 SET_DREG (dst, divq (cpu, DREG (dst), (bu16)DREG (src)));
2551 TRACE_INSN (cpu, "DIVS ( R%i, R%i );", dst, src);
2552 SET_DREG (dst, divs (cpu, DREG (dst), (bu16)DREG (src)));
2556 TRACE_INSN (cpu, "R%i = R%i.L (X);", dst, src);
2557 SET_DREG (dst, (bs32) (bs16) DREG (src));
2558 setflags_logical (cpu, DREG (dst));
2562 TRACE_INSN (cpu, "R%i = R%i.L (Z);", dst, src);
2563 SET_DREG (dst, (bu32) (bu16) DREG (src));
2564 setflags_logical (cpu, DREG (dst));
2568 TRACE_INSN (cpu, "R%i = R%i.B (X);", dst, src);
2569 SET_DREG (dst, (bs32) (bs8) DREG (src));
2570 setflags_logical (cpu, DREG (dst));
2574 TRACE_INSN (cpu, "R%i = R%i.B (Z);", dst, src);
2575 SET_DREG (dst, (bu32) (bu8) DREG (src));
2576 setflags_logical (cpu, DREG (dst));
2580 bu32 val = DREG (src);
2581 TRACE_INSN (cpu, "R%i = - R%i;", dst, src);
2582 SET_DREG (dst, -val);
2583 setflags_nz (cpu, DREG (dst));
2584 SET_ASTATREG (v, val == 0x80000000);
2586 SET_ASTATREG (vs, 1);
2587 SET_ASTATREG (ac0, val == 0x0);
2588 /* XXX: Documentation isn't entirely clear about av0 and av1. */
2592 TRACE_INSN (cpu, "R%i = ~ R%i;", dst, src);
2593 SET_DREG (dst, ~DREG (src));
2594 setflags_logical (cpu, DREG (dst));
2597 illegal_instruction (cpu);
2601 decode_PTR2op_0 (SIM_CPU *cpu, bu16 iw0)
2604 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2605 | 0 | 1 | 0 | 0 | 0 | 1 | 0 |.opc.......|.src.......|.dst.......|
2606 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2607 int src = ((iw0 >> PTR2op_src_bits) & PTR2op_dst_mask);
2608 int opc = ((iw0 >> PTR2op_opc_bits) & PTR2op_opc_mask);
2609 int dst = ((iw0 >> PTR2op_dst_bits) & PTR2op_dst_mask);
2610 const char *src_name = get_preg_name (src);
2611 const char *dst_name = get_preg_name (dst);
2613 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PTR2op);
2614 TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst);
2618 TRACE_INSN (cpu, "%s -= %s", dst_name, src_name);
2619 SET_PREG (dst, PREG (dst) - PREG (src));
2623 TRACE_INSN (cpu, "%s = %s << 2", dst_name, src_name);
2624 SET_PREG (dst, PREG (src) << 2);
2628 TRACE_INSN (cpu, "%s = %s >> 2", dst_name, src_name);
2629 SET_PREG (dst, PREG (src) >> 2);
2633 TRACE_INSN (cpu, "%s = %s >> 1", dst_name, src_name);
2634 SET_PREG (dst, PREG (src) >> 1);
2638 TRACE_INSN (cpu, "%s += %s (BREV)", dst_name, src_name);
2639 SET_PREG (dst, add_brev (PREG (dst), PREG (src)));
2643 TRACE_INSN (cpu, "%s = (%s + %s) << 1", dst_name, dst_name, src_name);
2644 SET_PREG (dst, (PREG (dst) + PREG (src)) << 1);
2648 TRACE_INSN (cpu, "%s = (%s + %s) << 2", dst_name, dst_name, src_name);
2649 SET_PREG (dst, (PREG (dst) + PREG (src)) << 2);
2652 illegal_instruction (cpu);
2656 decode_LOGI2op_0 (SIM_CPU *cpu, bu16 iw0)
2659 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2660 | 0 | 1 | 0 | 0 | 1 |.opc.......|.src...............|.dst.......|
2661 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2662 int src = ((iw0 >> LOGI2op_src_bits) & LOGI2op_src_mask);
2663 int opc = ((iw0 >> LOGI2op_opc_bits) & LOGI2op_opc_mask);
2664 int dst = ((iw0 >> LOGI2op_dst_bits) & LOGI2op_dst_mask);
2665 int uimm = uimm5 (src);
2666 const char *uimm_str = uimm5_str (uimm);
2668 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LOGI2op);
2669 TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst);
2670 TRACE_DECODE (cpu, "%s: uimm5:%#x", __func__, uimm);
2674 TRACE_INSN (cpu, "CC = ! BITTST (R%i, %s);", dst, uimm_str);
2676 illegal_instruction_combination (cpu);
2677 SET_CCREG ((~DREG (dst) >> uimm) & 1);
2681 TRACE_INSN (cpu, "CC = BITTST (R%i, %s);", dst, uimm_str);
2683 illegal_instruction_combination (cpu);
2684 SET_CCREG ((DREG (dst) >> uimm) & 1);
2688 TRACE_INSN (cpu, "BITSET (R%i, %s);", dst, uimm_str);
2690 illegal_instruction_combination (cpu);
2691 SET_DREG (dst, DREG (dst) | (1 << uimm));
2692 setflags_logical (cpu, DREG (dst));
2696 TRACE_INSN (cpu, "BITTGL (R%i, %s);", dst, uimm_str);
2698 illegal_instruction_combination (cpu);
2699 SET_DREG (dst, DREG (dst) ^ (1 << uimm));
2700 setflags_logical (cpu, DREG (dst));
2704 TRACE_INSN (cpu, "BITCLR (R%i, %s);", dst, uimm_str);
2706 illegal_instruction_combination (cpu);
2707 SET_DREG (dst, DREG (dst) & ~(1 << uimm));
2708 setflags_logical (cpu, DREG (dst));
2712 TRACE_INSN (cpu, "R%i >>>= %s;", dst, uimm_str);
2714 illegal_instruction_combination (cpu);
2715 SET_DREG (dst, ashiftrt (cpu, DREG (dst), uimm, 32));
2719 TRACE_INSN (cpu, "R%i >>= %s;", dst, uimm_str);
2721 illegal_instruction_combination (cpu);
2722 SET_DREG (dst, lshiftrt (cpu, DREG (dst), uimm, 32));
2726 TRACE_INSN (cpu, "R%i <<= %s;", dst, uimm_str);
2728 illegal_instruction_combination (cpu);
2729 SET_DREG (dst, lshift (cpu, DREG (dst), uimm, 32, 0));
2734 decode_COMP3op_0 (SIM_CPU *cpu, bu16 iw0)
2737 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2738 | 0 | 1 | 0 | 1 |.opc.......|.dst.......|.src1......|.src0......|
2739 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2740 int opc = ((iw0 >> COMP3op_opc_bits) & COMP3op_opc_mask);
2741 int dst = ((iw0 >> COMP3op_dst_bits) & COMP3op_dst_mask);
2742 int src0 = ((iw0 >> COMP3op_src0_bits) & COMP3op_src0_mask);
2743 int src1 = ((iw0 >> COMP3op_src1_bits) & COMP3op_src1_mask);
2745 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMP3op);
2746 TRACE_EXTRACT (cpu, "%s: opc:%i dst:%i src1:%i src0:%i",
2747 __func__, opc, dst, src1, src0);
2751 TRACE_INSN (cpu, "R%i = R%i + R%i;", dst, src0, src1);
2752 SET_DREG (dst, add32 (cpu, DREG (src0), DREG (src1), 1, 0));
2756 TRACE_INSN (cpu, "R%i = R%i - R%i;", dst, src0, src1);
2757 SET_DREG (dst, sub32 (cpu, DREG (src0), DREG (src1), 1, 0, 0));
2761 TRACE_INSN (cpu, "R%i = R%i & R%i;", dst, src0, src1);
2762 SET_DREG (dst, DREG (src0) & DREG (src1));
2763 setflags_logical (cpu, DREG (dst));
2767 TRACE_INSN (cpu, "R%i = R%i | R%i;", dst, src0, src1);
2768 SET_DREG (dst, DREG (src0) | DREG (src1));
2769 setflags_logical (cpu, DREG (dst));
2773 TRACE_INSN (cpu, "R%i = R%i ^ R%i;", dst, src0, src1);
2774 SET_DREG (dst, DREG (src0) ^ DREG (src1));
2775 setflags_logical (cpu, DREG (dst));
2779 int shift = opc - 5;
2780 const char *dst_name = get_preg_name (dst);
2781 const char *src0_name = get_preg_name (src0);
2782 const char *src1_name = get_preg_name (src1);
2784 /* If src0 == src1 this is disassembled as a shift by 1, but this
2785 distinction doesn't matter for our purposes. */
2787 TRACE_INSN (cpu, "%s = (%s + %s) << %#x;",
2788 dst_name, src0_name, src1_name, shift);
2790 TRACE_INSN (cpu, "%s = %s + %s",
2791 dst_name, src0_name, src1_name);
2792 SET_PREG (dst, PREG (src0) + (PREG (src1) << shift));
2797 decode_COMPI2opD_0 (SIM_CPU *cpu, bu16 iw0)
2800 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2801 | 0 | 1 | 1 | 0 | 0 |.op|..src......................|.dst.......|
2802 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2803 int op = ((iw0 >> COMPI2opD_op_bits) & COMPI2opD_op_mask);
2804 int dst = ((iw0 >> COMPI2opD_dst_bits) & COMPI2opD_dst_mask);
2805 int src = ((iw0 >> COMPI2opD_src_bits) & COMPI2opD_src_mask);
2806 int imm = imm7 (src);
2808 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMPI2opD);
2809 TRACE_EXTRACT (cpu, "%s: op:%i src:%i dst:%i", __func__, op, src, dst);
2810 TRACE_DECODE (cpu, "%s: imm7:%#x", __func__, imm);
2814 TRACE_INSN (cpu, "R%i = %s (X);", dst, imm7_str (imm));
2815 SET_DREG (dst, imm);
2819 TRACE_INSN (cpu, "R%i += %s;", dst, imm7_str (imm));
2820 SET_DREG (dst, add32 (cpu, DREG (dst), imm, 1, 0));
2825 decode_COMPI2opP_0 (SIM_CPU *cpu, bu16 iw0)
2828 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2829 | 0 | 1 | 1 | 0 | 1 |.op|.src.......................|.dst.......|
2830 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2831 int op = ((iw0 >> COMPI2opP_op_bits) & COMPI2opP_op_mask);
2832 int src = ((iw0 >> COMPI2opP_src_bits) & COMPI2opP_src_mask);
2833 int dst = ((iw0 >> COMPI2opP_dst_bits) & COMPI2opP_dst_mask);
2834 int imm = imm7 (src);
2835 const char *dst_name = get_preg_name (dst);
2837 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMPI2opP);
2838 TRACE_EXTRACT (cpu, "%s: op:%i src:%i dst:%i", __func__, op, src, dst);
2839 TRACE_DECODE (cpu, "%s: imm:%#x", __func__, imm);
2843 TRACE_INSN (cpu, "%s = %s;", dst_name, imm7_str (imm));
2844 SET_PREG (dst, imm);
2848 TRACE_INSN (cpu, "%s += %s;", dst_name, imm7_str (imm));
2849 SET_PREG (dst, PREG (dst) + imm);
2854 decode_LDSTpmod_0 (SIM_CPU *cpu, bu16 iw0)
2857 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2858 | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
2859 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2860 int W = ((iw0 >> LDSTpmod_W_bits) & LDSTpmod_W_mask);
2861 int aop = ((iw0 >> LDSTpmod_aop_bits) & LDSTpmod_aop_mask);
2862 int idx = ((iw0 >> LDSTpmod_idx_bits) & LDSTpmod_idx_mask);
2863 int ptr = ((iw0 >> LDSTpmod_ptr_bits) & LDSTpmod_ptr_mask);
2864 int reg = ((iw0 >> LDSTpmod_reg_bits) & LDSTpmod_reg_mask);
2865 const char *ptr_name = get_preg_name (ptr);
2866 const char *idx_name = get_preg_name (idx);
2869 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTpmod);
2870 TRACE_EXTRACT (cpu, "%s: W:%i aop:%i reg:%i idx:%i ptr:%i",
2871 __func__, W, aop, reg, idx, ptr);
2873 if (aop == 1 && W == 0 && idx == ptr)
2875 TRACE_INSN (cpu, "R%i.L = W[%s];", reg, ptr_name);
2877 val = GET_WORD (addr);
2878 STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | val);
2880 else if (aop == 2 && W == 0 && idx == ptr)
2882 TRACE_INSN (cpu, "R%i.H = W[%s];", reg, ptr_name);
2884 val = GET_WORD (addr);
2885 STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (val << 16));
2887 else if (aop == 1 && W == 1 && idx == ptr)
2889 TRACE_INSN (cpu, "W[%s] = R%i.L;", ptr_name, reg);
2891 PUT_WORD (addr, DREG (reg));
2893 else if (aop == 2 && W == 1 && idx == ptr)
2895 TRACE_INSN (cpu, "W[%s] = R%i.H;", ptr_name, reg);
2897 PUT_WORD (addr, DREG (reg) >> 16);
2899 else if (aop == 0 && W == 0)
2901 TRACE_INSN (cpu, "R%i = [%s ++ %s];", reg, ptr_name, idx_name);
2903 val = GET_LONG (addr);
2904 STORE (DREG (reg), val);
2906 STORE (PREG (ptr), addr + PREG (idx));
2908 else if (aop == 1 && W == 0)
2910 TRACE_INSN (cpu, "R%i.L = W[%s ++ %s];", reg, ptr_name, idx_name);
2912 val = GET_WORD (addr);
2913 STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | val);
2915 STORE (PREG (ptr), addr + PREG (idx));
2917 else if (aop == 2 && W == 0)
2919 TRACE_INSN (cpu, "R%i.H = W[%s ++ %s];", reg, ptr_name, idx_name);
2921 val = GET_WORD (addr);
2922 STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (val << 16));
2924 STORE (PREG (ptr), addr + PREG (idx));
2926 else if (aop == 3 && W == 0)
2928 TRACE_INSN (cpu, "R%i = W[%s ++ %s] (Z);", reg, ptr_name, idx_name);
2930 val = GET_WORD (addr);
2931 STORE (DREG (reg), val);
2933 STORE (PREG (ptr), addr + PREG (idx));
2935 else if (aop == 3 && W == 1)
2937 TRACE_INSN (cpu, "R%i = W[%s ++ %s] (X);", reg, ptr_name, idx_name);
2939 val = GET_WORD (addr);
2940 STORE (DREG (reg), (bs32) (bs16) val);
2942 STORE (PREG (ptr), addr + PREG (idx));
2944 else if (aop == 0 && W == 1)
2946 TRACE_INSN (cpu, "[%s ++ %s] = R%i;", ptr_name, idx_name, reg);
2948 PUT_LONG (addr, DREG (reg));
2950 STORE (PREG (ptr), addr + PREG (idx));
2952 else if (aop == 1 && W == 1)
2954 TRACE_INSN (cpu, "W[%s ++ %s] = R%i.L;", ptr_name, idx_name, reg);
2956 PUT_WORD (addr, DREG (reg));
2958 STORE (PREG (ptr), addr + PREG (idx));
2960 else if (aop == 2 && W == 1)
2962 TRACE_INSN (cpu, "W[%s ++ %s] = R%i.H;", ptr_name, idx_name, reg);
2964 PUT_WORD (addr, DREG (reg) >> 16);
2966 STORE (PREG (ptr), addr + PREG (idx));
2969 illegal_instruction (cpu);
2973 decode_dagMODim_0 (SIM_CPU *cpu, bu16 iw0)
2976 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2977 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
2978 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2979 int i = ((iw0 >> DagMODim_i_bits) & DagMODim_i_mask);
2980 int m = ((iw0 >> DagMODim_m_bits) & DagMODim_m_mask);
2981 int br = ((iw0 >> DagMODim_br_bits) & DagMODim_br_mask);
2982 int op = ((iw0 >> DagMODim_op_bits) & DagMODim_op_mask);
2984 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dagMODim);
2985 TRACE_EXTRACT (cpu, "%s: br:%i op:%i m:%i i:%i", __func__, br, op, m, i);
2987 if (op == 0 && br == 1)
2989 TRACE_INSN (cpu, "I%i += M%i (BREV);", i, m);
2990 SET_IREG (i, add_brev (IREG (i), MREG (m)));
2994 TRACE_INSN (cpu, "I%i += M%i;", i, m);
2995 dagadd (cpu, i, MREG (m));
2997 else if (op == 1 && br == 0)
2999 TRACE_INSN (cpu, "I%i -= M%i;", i, m);
3000 dagsub (cpu, i, MREG (m));
3003 illegal_instruction (cpu);
3007 decode_dagMODik_0 (SIM_CPU *cpu, bu16 iw0)
3010 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3011 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
3012 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
3013 int i = ((iw0 >> DagMODik_i_bits) & DagMODik_i_mask);
3014 int op = ((iw0 >> DagMODik_op_bits) & DagMODik_op_mask);
3016 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dagMODik);
3017 TRACE_EXTRACT (cpu, "%s: op:%i i:%i", __func__, op, i);
3021 TRACE_INSN (cpu, "I%i += 2;", i);
3026 TRACE_INSN (cpu, "I%i -= 2;", i);
3031 TRACE_INSN (cpu, "I%i += 4;", i);
3036 TRACE_INSN (cpu, "I%i -= 4;", i);
3040 illegal_instruction (cpu);
3044 decode_dspLDST_0 (SIM_CPU *cpu, bu16 iw0)
3047 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3048 | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
3049 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
3050 int i = ((iw0 >> DspLDST_i_bits) & DspLDST_i_mask);
3051 int m = ((iw0 >> DspLDST_m_bits) & DspLDST_m_mask);
3052 int W = ((iw0 >> DspLDST_W_bits) & DspLDST_W_mask);
3053 int aop = ((iw0 >> DspLDST_aop_bits) & DspLDST_aop_mask);
3054 int reg = ((iw0 >> DspLDST_reg_bits) & DspLDST_reg_mask);
3057 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dspLDST);
3058 TRACE_EXTRACT (cpu, "%s: aop:%i m:%i i:%i reg:%i", __func__, aop, m, i, reg);
3060 if (aop == 0 && W == 0 && m == 0)
3062 TRACE_INSN (cpu, "R%i = [I%i++];", reg, i);
3064 if (DIS_ALGN_EXPT & 0x1)
3067 STORE (DREG (reg), GET_LONG (addr));
3069 else if (aop == 0 && W == 0 && m == 1)
3071 TRACE_INSN (cpu, "R%i.L = W[I%i++];", reg, i);
3074 STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | GET_WORD (addr));
3076 else if (aop == 0 && W == 0 && m == 2)
3078 TRACE_INSN (cpu, "R%i.H = W[I%i++];", reg, i);
3081 STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (GET_WORD (addr) << 16));
3083 else if (aop == 1 && W == 0 && m == 0)
3085 TRACE_INSN (cpu, "R%i = [I%i--];", reg, i);
3087 if (DIS_ALGN_EXPT & 0x1)
3090 STORE (DREG (reg), GET_LONG (addr));
3092 else if (aop == 1 && W == 0 && m == 1)
3094 TRACE_INSN (cpu, "R%i.L = W[I%i--];", reg, i);
3097 STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | GET_WORD (addr));
3099 else if (aop == 1 && W == 0 && m == 2)
3101 TRACE_INSN (cpu, "R%i.H = W[I%i--];", reg, i);
3104 STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (GET_WORD (addr) << 16));
3106 else if (aop == 2 && W == 0 && m == 0)
3108 TRACE_INSN (cpu, "R%i = [I%i];", reg, i);
3110 if (DIS_ALGN_EXPT & 0x1)
3112 STORE (DREG (reg), GET_LONG (addr));
3114 else if (aop == 2 && W == 0 && m == 1)
3116 TRACE_INSN (cpu, "R%i.L = W[I%i];", reg, i);
3118 STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | GET_WORD (addr));
3120 else if (aop == 2 && W == 0 && m == 2)
3122 TRACE_INSN (cpu, "R%i.H = W[I%i];", reg, i);
3124 STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (GET_WORD (addr) << 16));
3126 else if (aop == 0 && W == 1 && m == 0)
3128 TRACE_INSN (cpu, "[I%i++] = R%i;", i, reg);
3131 PUT_LONG (addr, DREG (reg));
3133 else if (aop == 0 && W == 1 && m == 1)
3135 TRACE_INSN (cpu, "W[I%i++] = R%i.L;", i, reg);
3138 PUT_WORD (addr, DREG (reg));
3140 else if (aop == 0 && W == 1 && m == 2)
3142 TRACE_INSN (cpu, "W[I%i++] = R%i.H;", i, reg);
3145 PUT_WORD (addr, DREG (reg) >> 16);
3147 else if (aop == 1 && W == 1 && m == 0)
3149 TRACE_INSN (cpu, "[I%i--] = R%i;", i, reg);
3152 PUT_LONG (addr, DREG (reg));
3154 else if (aop == 1 && W == 1 && m == 1)
3156 TRACE_INSN (cpu, "W[I%i--] = R%i.L;", i, reg);
3159 PUT_WORD (addr, DREG (reg));
3161 else if (aop == 1 && W == 1 && m == 2)
3163 TRACE_INSN (cpu, "W[I%i--] = R%i.H;", i, reg);
3166 PUT_WORD (addr, DREG (reg) >> 16);
3168 else if (aop == 2 && W == 1 && m == 0)
3170 TRACE_INSN (cpu, "[I%i] = R%i;", i, reg);
3172 PUT_LONG (addr, DREG (reg));
3174 else if (aop == 2 && W == 1 && m == 1)
3176 TRACE_INSN (cpu, "W[I%i] = R%i.L;", i, reg);
3178 PUT_WORD (addr, DREG (reg));
3180 else if (aop == 2 && W == 1 && m == 2)
3182 TRACE_INSN (cpu, "W[I%i] = R%i.H;", i, reg);
3184 PUT_WORD (addr, DREG (reg) >> 16);
3186 else if (aop == 3 && W == 0)
3188 TRACE_INSN (cpu, "R%i = [I%i ++ M%i];", reg, i, m);
3190 if (DIS_ALGN_EXPT & 0x1)
3192 dagadd (cpu, i, MREG (m));
3193 STORE (DREG (reg), GET_LONG (addr));
3195 else if (aop == 3 && W == 1)
3197 TRACE_INSN (cpu, "[I%i ++ M%i] = R%i;", i, m, reg);
3199 dagadd (cpu, i, MREG (m));
3200 PUT_LONG (addr, DREG (reg));
3203 illegal_instruction (cpu);
3207 decode_LDST_0 (SIM_CPU *cpu, bu16 iw0)
3210 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3211 | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
3212 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
3213 int Z = ((iw0 >> LDST_Z_bits) & LDST_Z_mask);
3214 int W = ((iw0 >> LDST_W_bits) & LDST_W_mask);
3215 int sz = ((iw0 >> LDST_sz_bits) & LDST_sz_mask);
3216 int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask);
3217 int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask);
3218 int ptr = ((iw0 >> LDST_ptr_bits) & LDST_ptr_mask);
3219 const char * const posts[] = { "++", "--", "" };
3220 const char *post = posts[aop];
3221 const char *ptr_name = get_preg_name (ptr);
3223 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDST);
3224 TRACE_EXTRACT (cpu, "%s: sz:%i W:%i aop:%i Z:%i ptr:%i reg:%i",
3225 __func__, sz, W, aop, Z, ptr, reg);
3228 illegal_instruction (cpu);
3232 if (sz == 0 && Z == 0)
3234 TRACE_INSN (cpu, "R%i = [%s%s];", reg, ptr_name, post);
3235 SET_DREG (reg, GET_LONG (PREG (ptr)));
3237 else if (sz == 0 && Z == 1)
3239 TRACE_INSN (cpu, "%s = [%s%s];", get_preg_name (reg), ptr_name, post);
3240 if (aop < 2 && ptr == reg)
3241 illegal_instruction_combination (cpu);
3242 SET_PREG (reg, GET_LONG (PREG (ptr)));
3244 else if (sz == 1 && Z == 0)
3246 TRACE_INSN (cpu, "R%i = W[%s%s] (Z);", reg, ptr_name, post);
3247 SET_DREG (reg, GET_WORD (PREG (ptr)));
3249 else if (sz == 1 && Z == 1)
3251 TRACE_INSN (cpu, "R%i = W[%s%s] (X);", reg, ptr_name, post);
3252 SET_DREG (reg, (bs32) (bs16) GET_WORD (PREG (ptr)));
3254 else if (sz == 2 && Z == 0)
3256 TRACE_INSN (cpu, "R%i = B[%s%s] (Z);", reg, ptr_name, post);
3257 SET_DREG (reg, GET_BYTE (PREG (ptr)));
3259 else if (sz == 2 && Z == 1)
3261 TRACE_INSN (cpu, "R%i = B[%s%s] (X);", reg, ptr_name, post);
3262 SET_DREG (reg, (bs32) (bs8) GET_BYTE (PREG (ptr)));
3265 illegal_instruction (cpu);
3269 if (sz == 0 && Z == 0)
3271 TRACE_INSN (cpu, "[%s%s] = R%i;", ptr_name, post, reg);
3272 PUT_LONG (PREG (ptr), DREG (reg));
3274 else if (sz == 0 && Z == 1)
3276 TRACE_INSN (cpu, "[%s%s] = %s;", ptr_name, post, get_preg_name (reg));
3277 PUT_LONG (PREG (ptr), PREG (reg));
3279 else if (sz == 1 && Z == 0)
3281 TRACE_INSN (cpu, "W[%s%s] = R%i;", ptr_name, post, reg);
3282 PUT_WORD (PREG (ptr), DREG (reg));
3284 else if (sz == 2 && Z == 0)
3286 TRACE_INSN (cpu, "B[%s%s] = R%i;", ptr_name, post, reg);
3287 PUT_BYTE (PREG (ptr), DREG (reg));
3290 illegal_instruction (cpu);
3294 SET_PREG (ptr, PREG (ptr) + (1 << (2 - sz)));
3296 SET_PREG (ptr, PREG (ptr) - (1 << (2 - sz)));
3300 decode_LDSTiiFP_0 (SIM_CPU *cpu, bu16 iw0)
3303 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3304 | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
3305 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
3306 /* This isn't exactly a grp:reg as this insn only supports Dregs & Pregs,
3307 but for our usage, its functionality the same thing. */
3308 int grp = ((iw0 >> 3) & 0x1);
3309 int reg = ((iw0 >> LDSTiiFP_reg_bits) & 0x7 /*LDSTiiFP_reg_mask*/);
3310 int offset = ((iw0 >> LDSTiiFP_offset_bits) & LDSTiiFP_offset_mask);
3311 int W = ((iw0 >> LDSTiiFP_W_bits) & LDSTiiFP_W_mask);
3312 bu32 imm = negimm5s4 (offset);
3313 bu32 ea = FPREG + imm;
3314 const char *imm_str = negimm5s4_str (offset);
3315 const char *reg_name = get_allreg_name (grp, reg);
3317 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTiiFP);
3318 TRACE_EXTRACT (cpu, "%s: W:%i offset:%#x grp:%i reg:%i", __func__,
3319 W, offset, grp, reg);
3320 TRACE_DECODE (cpu, "%s: negimm5s4:%#x", __func__, imm);
3324 TRACE_INSN (cpu, "%s = [FP + %s];", reg_name, imm_str);
3325 reg_write (cpu, grp, reg, GET_LONG (ea));
3329 TRACE_INSN (cpu, "[FP + %s] = %s;", imm_str, reg_name);
3330 PUT_LONG (ea, reg_read (cpu, grp, reg));
3335 decode_LDSTii_0 (SIM_CPU *cpu, bu16 iw0)
3338 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3339 | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
3340 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
3341 int reg = ((iw0 >> LDSTii_reg_bit) & LDSTii_reg_mask);
3342 int ptr = ((iw0 >> LDSTii_ptr_bit) & LDSTii_ptr_mask);
3343 int offset = ((iw0 >> LDSTii_offset_bit) & LDSTii_offset_mask);
3344 int op = ((iw0 >> LDSTii_op_bit) & LDSTii_op_mask);
3345 int W = ((iw0 >> LDSTii_W_bit) & LDSTii_W_mask);
3347 const char *imm_str;
3348 const char *ptr_name = get_preg_name (ptr);
3350 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTii);
3351 TRACE_EXTRACT (cpu, "%s: W:%i op:%i offset:%#x ptr:%i reg:%i",
3352 __func__, W, op, offset, ptr, reg);
3354 if (op == 0 || op == 3)
3355 imm = uimm4s4 (offset), imm_str = uimm4s4_str (offset);
3357 imm = uimm4s2 (offset), imm_str = uimm4s2_str (offset);
3358 ea = PREG (ptr) + imm;
3360 TRACE_DECODE (cpu, "%s: uimm4s4/uimm4s2:%#x", __func__, imm);
3362 if (W == 1 && op == 2)
3363 illegal_instruction (cpu);
3369 TRACE_INSN (cpu, "R%i = [%s + %s];", reg, ptr_name, imm_str);
3370 SET_DREG (reg, GET_LONG (ea));
3374 TRACE_INSN (cpu, "R%i = W[%s + %s] (Z);", reg, ptr_name, imm_str);
3375 SET_DREG (reg, GET_WORD (ea));
3379 TRACE_INSN (cpu, "R%i = W[%s + %s] (X);", reg, ptr_name, imm_str);
3380 SET_DREG (reg, (bs32) (bs16) GET_WORD (ea));
3384 TRACE_INSN (cpu, "%s = [%s + %s];",
3385 get_preg_name (reg), ptr_name, imm_str);
3386 SET_PREG (reg, GET_LONG (ea));
3393 TRACE_INSN (cpu, "[%s + %s] = R%i;", ptr_name, imm_str, reg);
3394 PUT_LONG (ea, DREG (reg));
3398 TRACE_INSN (cpu, "W[%s + %s] = R%i;", ptr_name, imm_str, reg);
3399 PUT_WORD (ea, DREG (reg));
3403 TRACE_INSN (cpu, "[%s + %s] = %s;",
3404 ptr_name, imm_str, get_preg_name (reg));
3405 PUT_LONG (ea, PREG (reg));
3411 decode_LoopSetup_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1, bu32 pc)
3414 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3415 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |.rop...|.c.|.soffset.......|
3416 |.reg...........| - | - |.eoffset...............................|
3417 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
3418 int c = ((iw0 >> (LoopSetup_c_bits - 16)) & LoopSetup_c_mask);
3419 int reg = ((iw1 >> LoopSetup_reg_bits) & LoopSetup_reg_mask);
3420 int rop = ((iw0 >> (LoopSetup_rop_bits - 16)) & LoopSetup_rop_mask);
3421 int soffset = ((iw0 >> (LoopSetup_soffset_bits - 16)) & LoopSetup_soffset_mask);
3422 int eoffset = ((iw1 >> LoopSetup_eoffset_bits) & LoopSetup_eoffset_mask);
3423 int spcrel = pcrel4 (soffset);
3424 int epcrel = lppcrel10 (eoffset);
3426 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LoopSetup);
3427 TRACE_EXTRACT (cpu, "%s: rop:%i c:%i soffset:%i reg:%i eoffset:%i",
3428 __func__, rop, c, soffset, reg, eoffset);
3429 TRACE_DECODE (cpu, "%s: s_pcrel4:%#x e_lppcrel10:%#x",
3430 __func__, spcrel, epcrel);
3433 illegal_instruction (cpu);
3436 illegal_instruction_combination (cpu);
3440 TRACE_INSN (cpu, "LSETUP (%#x, %#x) LC%i;", spcrel, epcrel, c);
3442 else if (rop == 1 && reg <= 7)
3444 TRACE_INSN (cpu, "LSETUP (%#x, %#x) LC%i = %s;",
3445 spcrel, epcrel, c, get_preg_name (reg));
3446 SET_LCREG (c, PREG (reg));
3448 else if (rop == 3 && reg <= 7)
3450 TRACE_INSN (cpu, "LSETUP (%#x, %#x) LC%i = %s >> 1;",
3451 spcrel, epcrel, c, get_preg_name (reg));
3452 SET_LCREG (c, PREG (reg) >> 1);
3455 illegal_instruction (cpu);
3457 SET_LTREG (c, pc + spcrel);
3458 SET_LBREG (c, pc + epcrel);
3462 decode_LDIMMhalf_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
3465 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3466 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |.Z.|.H.|.S.|.grp...|.reg.......|
3467 |.hword.........................................................|
3468 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
3469 int H = ((iw0 >> (LDIMMhalf_H_bits - 16)) & LDIMMhalf_H_mask);
3470 int Z = ((iw0 >> (LDIMMhalf_Z_bits - 16)) & LDIMMhalf_Z_mask);
3471 int S = ((iw0 >> (LDIMMhalf_S_bits - 16)) & LDIMMhalf_S_mask);
3472 int reg = ((iw0 >> (LDIMMhalf_reg_bits - 16)) & LDIMMhalf_reg_mask);
3473 int grp = ((iw0 >> (LDIMMhalf_grp_bits - 16)) & LDIMMhalf_grp_mask);
3474 int hword = ((iw1 >> LDIMMhalf_hword_bits) & LDIMMhalf_hword_mask);
3476 const char *val_str;
3477 const char *reg_name = get_allreg_name (grp, reg);
3479 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDIMMhalf);
3480 TRACE_EXTRACT (cpu, "%s: Z:%i H:%i S:%i grp:%i reg:%i hword:%#x",
3481 __func__, Z, H, S, grp, reg, hword);
3484 illegal_instruction_combination (cpu);
3487 val = imm16 (hword), val_str = imm16_str (hword);
3489 val = luimm16 (hword), val_str = luimm16_str (hword);
3491 if (H == 0 && S == 1 && Z == 0)
3493 TRACE_INSN (cpu, "%s = %s (X);", reg_name, val_str);
3495 else if (H == 0 && S == 0 && Z == 1)
3497 TRACE_INSN (cpu, "%s = %s (Z);", reg_name, val_str);
3499 else if (H == 0 && S == 0 && Z == 0)
3501 TRACE_INSN (cpu, "%s.L = %s;", reg_name, val_str);
3502 val = REG_H_L (reg_read (cpu, grp, reg), val);
3504 else if (H == 1 && S == 0 && Z == 0)
3506 TRACE_INSN (cpu, "%s.H = %s;", reg_name, val_str);
3507 val = REG_H_L (val << 16, reg_read (cpu, grp, reg));
3510 illegal_instruction (cpu);
3512 reg_write (cpu, grp, reg, val);
3516 decode_CALLa_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1, bu32 pc)
3519 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3520 | 1 | 1 | 1 | 0 | 0 | 0 | 1 |.S.|.msw...........................|
3521 |.lsw...........................................................|
3522 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
3523 int S = ((iw0 >> (CALLa_S_bits - 16)) & CALLa_S_mask);
3524 int lsw = ((iw1 >> 0) & 0xffff);
3525 int msw = ((iw0 >> 0) & 0xff);
3526 int pcrel = pcrel24 ((msw << 16) | lsw);
3527 bu32 newpc = pc + pcrel;
3529 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CALLa);
3530 TRACE_EXTRACT (cpu, "%s: S:%i msw:%#x lsw:%#x", __func__, S, msw, lsw);
3531 TRACE_DECODE (cpu, "%s: pcrel24:%#x", __func__, pcrel);
3533 TRACE_INSN (cpu, "%s %#x;", S ? "CALL" : "JUMP.L", pcrel);
3536 illegal_instruction_combination (cpu);
3540 TRACE_BRANCH (cpu, pc, newpc, -1, "CALL");
3541 SET_RETSREG (hwloop_get_next_pc (cpu, pc, 4));
3544 TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP.L");
3547 BFIN_CPU_STATE.did_jump = true;
3548 PROFILE_BRANCH_TAKEN (cpu);
3553 decode_LDSTidxI_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
3556 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3557 | 1 | 1 | 1 | 0 | 0 | 1 |.W.|.Z.|.sz....|.ptr.......|.reg.......|
3558 |.offset........................................................|
3559 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
3560 int Z = ((iw0 >> (LDSTidxI_Z_bits - 16)) & LDSTidxI_Z_mask);
3561 int W = ((iw0 >> (LDSTidxI_W_bits - 16)) & LDSTidxI_W_mask);
3562 int sz = ((iw0 >> (LDSTidxI_sz_bits - 16)) & LDSTidxI_sz_mask);
3563 int reg = ((iw0 >> (LDSTidxI_reg_bits - 16)) & LDSTidxI_reg_mask);
3564 int ptr = ((iw0 >> (LDSTidxI_ptr_bits - 16)) & LDSTidxI_ptr_mask);
3565 int offset = ((iw1 >> LDSTidxI_offset_bits) & LDSTidxI_offset_mask);
3566 const char *ptr_name = get_preg_name (ptr);
3567 bu32 imm_16s4 = imm16s4 (offset);
3568 bu32 imm_16s2 = imm16s2 (offset);
3569 bu32 imm_16 = imm16 (offset);
3571 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTidxI);
3572 TRACE_EXTRACT (cpu, "%s: W:%i Z:%i sz:%i ptr:%i reg:%i offset:%#x",
3573 __func__, W, Z, sz, ptr, reg, offset);
3576 illegal_instruction (cpu);
3580 if (sz == 0 && Z == 0)
3582 TRACE_INSN (cpu, "R%i = [%s + %s];",
3583 reg, ptr_name, imm16s4_str (offset));
3584 SET_DREG (reg, GET_LONG (PREG (ptr) + imm_16s4));
3586 else if (sz == 0 && Z == 1)
3588 TRACE_INSN (cpu, "%s = [%s + %s];",
3589 get_preg_name (reg), ptr_name, imm16s4_str (offset));
3590 SET_PREG (reg, GET_LONG (PREG (ptr) + imm_16s4));
3592 else if (sz == 1 && Z == 0)
3594 TRACE_INSN (cpu, "R%i = W[%s + %s] (Z);",
3595 reg, ptr_name, imm16s2_str (offset));
3596 SET_DREG (reg, GET_WORD (PREG (ptr) + imm_16s2));
3598 else if (sz == 1 && Z == 1)
3600 TRACE_INSN (cpu, "R%i = W[%s + %s] (X);",
3601 reg, ptr_name, imm16s2_str (offset));
3602 SET_DREG (reg, (bs32) (bs16) GET_WORD (PREG (ptr) + imm_16s2));
3604 else if (sz == 2 && Z == 0)
3606 TRACE_INSN (cpu, "R%i = B[%s + %s] (Z);",
3607 reg, ptr_name, imm16_str (offset));
3608 SET_DREG (reg, GET_BYTE (PREG (ptr) + imm_16));
3610 else if (sz == 2 && Z == 1)
3612 TRACE_INSN (cpu, "R%i = B[%s + %s] (X);",
3613 reg, ptr_name, imm16_str (offset));
3614 SET_DREG (reg, (bs32) (bs8) GET_BYTE (PREG (ptr) + imm_16));
3619 if (sz != 0 && Z != 0)
3620 illegal_instruction (cpu);
3622 if (sz == 0 && Z == 0)
3624 TRACE_INSN (cpu, "[%s + %s] = R%i;", ptr_name,
3625 imm16s4_str (offset), reg);
3626 PUT_LONG (PREG (ptr) + imm_16s4, DREG (reg));
3628 else if (sz == 0 && Z == 1)
3630 TRACE_INSN (cpu, "[%s + %s] = %s;",
3631 ptr_name, imm16s4_str (offset), get_preg_name (reg));
3632 PUT_LONG (PREG (ptr) + imm_16s4, PREG (reg));
3634 else if (sz == 1 && Z == 0)
3636 TRACE_INSN (cpu, "W[%s + %s] = R%i;",
3637 ptr_name, imm16s2_str (offset), reg);
3638 PUT_WORD (PREG (ptr) + imm_16s2, DREG (reg));
3640 else if (sz == 2 && Z == 0)
3642 TRACE_INSN (cpu, "B[%s + %s] = R%i;",
3643 ptr_name, imm16_str (offset), reg);
3644 PUT_BYTE (PREG (ptr) + imm_16, DREG (reg));
3650 decode_linkage_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
3653 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3654 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |.R.|
3655 |.framesize.....................................................|
3656 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
3657 int R = ((iw0 >> (Linkage_R_bits - 16)) & Linkage_R_mask);
3658 int framesize = ((iw1 >> Linkage_framesize_bits) & Linkage_framesize_mask);
3661 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_linkage);
3662 TRACE_EXTRACT (cpu, "%s: R:%i framesize:%#x", __func__, R, framesize);
3666 int size = uimm16s4 (framesize);
3668 TRACE_INSN (cpu, "LINK %s;", uimm16s4_str (framesize));
3670 illegal_instruction_combination (cpu);
3672 PUT_LONG (sp, RETSREG);
3674 PUT_LONG (sp, FPREG);
3681 /* Restore SP from FP. */
3683 TRACE_INSN (cpu, "UNLINK;");
3685 illegal_instruction_combination (cpu);
3686 SET_FPREG (GET_LONG (sp));
3688 SET_RETSREG (GET_LONG (sp));
3697 decode_dsp32mac_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
3700 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3701 | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
3702 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
3703 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
3704 int op1 = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask);
3705 int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
3706 int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
3707 int MM = ((iw0 >> (DSP32Mac_MM_bits - 16)) & DSP32Mac_MM_mask);
3708 int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
3709 int M = ((iw0 >> (DSP32Mac_M_bits - 16)) & DSP32Mac_M_mask);
3710 int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
3711 int src0 = ((iw1 >> DSP32Mac_src0_bits) & DSP32Mac_src0_mask);
3712 int src1 = ((iw1 >> DSP32Mac_src1_bits) & DSP32Mac_src1_mask);
3713 int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
3714 int h10 = ((iw1 >> DSP32Mac_h10_bits) & DSP32Mac_h10_mask);
3715 int h00 = ((iw1 >> DSP32Mac_h00_bits) & DSP32Mac_h00_mask);
3716 int op0 = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask);
3717 int h11 = ((iw1 >> DSP32Mac_h11_bits) & DSP32Mac_h11_mask);
3718 int h01 = ((iw1 >> DSP32Mac_h01_bits) & DSP32Mac_h01_mask);
3720 bu32 res = DREG (dst);
3721 bu32 v_i = 0, zero = 0, n_1 = 0, n_0 = 0;
3723 static const char * const ops[] = { "=", "+=", "-=" };
3724 char _buf[128], *buf = _buf;
3727 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32mac);
3728 TRACE_EXTRACT (cpu, "%s: M:%i mmod:%i MM:%i P:%i w1:%i op1:%i h01:%i h11:%i "
3729 "w0:%i op0:%i h00:%i h10:%i dst:%i src0:%i src1:%i",
3730 __func__, M, mmod, MM, P, w1, op1, h01, h11, w0, op0, h00, h10,
3733 if (w0 == 0 && w1 == 0 && op1 == 3 && op0 == 3)
3734 illegal_instruction (cpu);
3736 if ((w1 || w0) && mmod == M_W32)
3737 illegal_instruction (cpu);
3739 if (((1 << mmod) & (P ? 0x131b : 0x1b5f)) == 0)
3740 illegal_instruction (cpu);
3742 /* First handle MAC1 side. */
3743 if (w1 == 1 || op1 != 3)
3745 bu32 res1 = decode_macfunc (cpu, 1, op1, h01, h11, src0,
3746 src1, mmod, MM, P, &v_i, &n_1);
3749 buf += sprintf (buf, P ? "R%i" : "R%i.H", dst + P);
3753 buf += sprintf (buf, " = A1");
3754 zero = !!(res1 == 0);
3759 buf += sprintf (buf, " = (");
3760 buf += sprintf (buf, "A1 %s R%i.%c * R%i.%c", ops[op1],
3761 src0, h01 ? 'H' : 'L',
3762 src1, h11 ? 'H' : 'L');
3764 buf += sprintf (buf, ")");
3770 STORE (DREG (dst + 1), res1);
3773 if (res1 & 0xffff0000)
3774 illegal_instruction (cpu);
3775 res = REG_H_L (res1 << 16, res);
3779 if (w0 == 1 || op0 != 3)
3782 buf += sprintf (buf, " (M)");
3784 buf += sprintf (buf, ", ");
3788 /* Then handle MAC0 side. */
3789 if (w0 == 1 || op0 != 3)
3791 bu32 res0 = decode_macfunc (cpu, 0, op0, h00, h10, src0,
3792 src1, mmod, 0, P, &v_i, &n_0);
3795 buf += sprintf (buf, P ? "R%i" : "R%i.L", dst);
3799 buf += sprintf (buf, " = A0");
3800 zero |= !!(res0 == 0);
3805 buf += sprintf (buf, " = (");
3806 buf += sprintf (buf, "A0 %s R%i.%c * R%i.%c", ops[op0],
3807 src0, h00 ? 'H' : 'L',
3808 src1, h10 ? 'H' : 'L');
3810 buf += sprintf (buf, ")");
3816 STORE (DREG (dst), res0);
3819 if (res0 & 0xffff0000)
3820 illegal_instruction (cpu);
3821 res = REG_H_L (res, res0);
3826 TRACE_INSN (cpu, "%s%s;", _buf, mac_optmode (mmod, _MM));
3828 if (!P && (w0 || w1))
3830 STORE (DREG (dst), res);
3831 SET_ASTATREG (v, v_i);
3833 SET_ASTATREG (vs, v_i);
3837 SET_ASTATREG (v, v_i);
3839 SET_ASTATREG (vs, v_i);
3842 if ((w0 == 1 && op0 == 3) || (w1 == 1 && op1 == 3))
3844 SET_ASTATREG (az, zero);
3845 if (!(w0 == 1 && op0 == 3))
3847 if (!(w1 == 1 && op1 == 3))
3849 SET_ASTATREG (an, n_1 | n_0);
3854 decode_dsp32mult_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
3857 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3858 | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
3859 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
3860 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
3861 int op1 = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask);
3862 int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
3863 int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
3864 int MM = ((iw0 >> (DSP32Mac_MM_bits - 16)) & DSP32Mac_MM_mask);
3865 int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
3866 int M = ((iw0 >> (DSP32Mac_M_bits - 16)) & DSP32Mac_M_mask);
3867 int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
3868 int src0 = ((iw1 >> DSP32Mac_src0_bits) & DSP32Mac_src0_mask);
3869 int src1 = ((iw1 >> DSP32Mac_src1_bits) & DSP32Mac_src1_mask);
3870 int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
3871 int h10 = ((iw1 >> DSP32Mac_h10_bits) & DSP32Mac_h10_mask);
3872 int h00 = ((iw1 >> DSP32Mac_h00_bits) & DSP32Mac_h00_mask);
3873 int op0 = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask);
3874 int h11 = ((iw1 >> DSP32Mac_h11_bits) & DSP32Mac_h11_mask);
3875 int h01 = ((iw1 >> DSP32Mac_h01_bits) & DSP32Mac_h01_mask);
3877 bu32 res = DREG (dst);
3878 bu32 sat0 = 0, sat1 = 0, v_i0 = 0, v_i1 = 0;
3879 char _buf[128], *buf = _buf;
3882 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32mult);
3883 TRACE_EXTRACT (cpu, "%s: M:%i mmod:%i MM:%i P:%i w1:%i op1:%i h01:%i h11:%i "
3884 "w0:%i op0:%i h00:%i h10:%i dst:%i src0:%i src1:%i",
3885 __func__, M, mmod, MM, P, w1, op1, h01, h11, w0, op0, h00, h10,
3888 if (w1 == 0 && w0 == 0)
3889 illegal_instruction (cpu);
3890 if (((1 << mmod) & (P ? 0x313 : 0x1b57)) == 0)
3891 illegal_instruction (cpu);
3892 if (P && ((dst & 1) || (op1 != 0) || (op0 != 0) || !is_macmod_pmove (mmod)))
3893 illegal_instruction (cpu);
3894 if (!P && ((op1 != 0) || (op0 != 0) || !is_macmod_hmove (mmod)))
3895 illegal_instruction (cpu);
3897 /* First handle MAC1 side. */
3900 bu64 r = decode_multfunc (cpu, h01, h11, src0, src1, mmod, MM, &sat1);
3901 bu32 res1 = extract_mult (cpu, r, mmod, MM, P, &v_i1);
3903 buf += sprintf (buf, P ? "R%i" : "R%i.H", dst + P);
3904 buf += sprintf (buf, " = R%i.%c * R%i.%c",
3905 src0, h01 ? 'H' : 'L',
3906 src1, h11 ? 'H' : 'L');
3910 buf += sprintf (buf, " (M)");
3912 buf += sprintf (buf, ", ");
3916 STORE (DREG (dst + 1), res1);
3919 if (res1 & 0xFFFF0000)
3920 illegal_instruction (cpu);
3921 res = REG_H_L (res1 << 16, res);
3925 /* First handle MAC0 side. */
3928 bu64 r = decode_multfunc (cpu, h00, h10, src0, src1, mmod, 0, &sat0);
3929 bu32 res0 = extract_mult (cpu, r, mmod, 0, P, &v_i0);
3931 buf += sprintf (buf, P ? "R%i" : "R%i.L", dst);
3932 buf += sprintf (buf, " = R%i.%c * R%i.%c",
3933 src0, h01 ? 'H' : 'L',
3934 src1, h11 ? 'H' : 'L');
3937 STORE (DREG (dst), res0);
3940 if (res0 & 0xFFFF0000)
3941 illegal_instruction (cpu);
3942 res = REG_H_L (res, res0);
3946 TRACE_INSN (cpu, "%s%s;", _buf, mac_optmode (mmod, _MM));
3948 if (!P && (w0 || w1))
3949 STORE (DREG (dst), res);
3953 bu32 v = sat0 | sat1 | v_i0 | v_i1;
3955 STORE (ASTATREG (v), v);
3956 STORE (ASTATREG (v_copy), v);
3958 STORE (ASTATREG (vs), v);
3963 decode_dsp32alu_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
3966 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
3967 | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
3968 |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
3969 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
3970 int s = ((iw1 >> DSP32Alu_s_bits) & DSP32Alu_s_mask);
3971 int x = ((iw1 >> DSP32Alu_x_bits) & DSP32Alu_x_mask);
3972 int aop = ((iw1 >> DSP32Alu_aop_bits) & DSP32Alu_aop_mask);
3973 int src0 = ((iw1 >> DSP32Alu_src0_bits) & DSP32Alu_src0_mask);
3974 int src1 = ((iw1 >> DSP32Alu_src1_bits) & DSP32Alu_src1_mask);
3975 int dst0 = ((iw1 >> DSP32Alu_dst0_bits) & DSP32Alu_dst0_mask);
3976 int dst1 = ((iw1 >> DSP32Alu_dst1_bits) & DSP32Alu_dst1_mask);
3977 int M = ((iw0 >> (DSP32Alu_M_bits - 16)) & DSP32Alu_M_mask);
3978 int HL = ((iw0 >> (DSP32Alu_HL_bits - 16)) & DSP32Alu_HL_mask);
3979 int aopcde = ((iw0 >> (DSP32Alu_aopcde_bits - 16)) & DSP32Alu_aopcde_mask);
3981 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32alu);
3982 TRACE_EXTRACT (cpu, "%s: M:%i HL:%i aopcde:%i aop:%i s:%i x:%i dst0:%i "
3983 "dst1:%i src0:%i src1:%i",
3984 __func__, M, HL, aopcde, aop, s, x, dst0, dst1, src0, src1);
3986 if ((aop == 0 || aop == 2) && aopcde == 9 && HL == 0 && s == 0)
3989 TRACE_INSN (cpu, "A%i.L = R%i.L;", a, src0);
3990 SET_AWREG (a, REG_H_L (AWREG (a), DREG (src0)));
3992 else if ((aop == 0 || aop == 2) && aopcde == 9 && HL == 1 && s == 0)
3995 TRACE_INSN (cpu, "A%i.H = R%i.H;", a, src0);
3996 SET_AWREG (a, REG_H_L (DREG (src0), AWREG (a)));
3998 else if ((aop == 1 || aop == 0) && aopcde == 5)
4000 bs32 val0 = DREG (src0);
4001 bs32 val1 = DREG (src1);
4004 bs32 ovX, sBit1, sBit2, sBitRes1, sBitRes2;
4006 TRACE_INSN (cpu, "R%i.%s = R%i %s R%i (RND12)", dst0, HL ? "L" : "H",
4007 src0, aop & 0x1 ? "-" : "+", src1);
4009 /* If subtract, just invert and add one. */
4012 if (val1 == 0x80000000)
4018 /* Get the sign bits, since we need them later. */
4019 sBit1 = !!(val0 & 0x80000000);
4020 sBit2 = !!(val1 & 0x80000000);
4024 sBitRes1 = !!(res & 0x80000000);
4025 /* Round to the 12th bit. */
4027 sBitRes2 = !!(res & 0x80000000);
4035 positive_res + positive_round = neg
4036 Shift and upper 4 bits where not the same. */
4037 if ((!(sBit1 ^ sBit2) && (sBit1 ^ sBitRes1))
4038 || (!sBit1 && !sBit2 && sBitRes2)
4039 || ((signRes != 0) && (signRes != -1)))
4041 /* Both X1 and X2 Neg res is neg overflow. */
4044 /* Both X1 and X2 Pos res is pos overflow. */
4045 else if (!sBit1 && !sBit2)
4047 /* Pos+Neg or Neg+Pos take the sign of the result. */
4057 /* Shift up now after overflow detection. */
4065 STORE (DREG (dst0), REG_H_L (res << 16, DREG (dst0)));
4067 STORE (DREG (dst0), REG_H_L (DREG (dst0), res));
4069 SET_ASTATREG (az, res == 0);
4070 SET_ASTATREG (an, res & 0x8000);
4071 SET_ASTATREG (v, ovX);
4073 SET_ASTATREG (vs, ovX);
4075 else if ((aop == 2 || aop == 3) && aopcde == 5)
4077 bs32 val0 = DREG (src0);
4078 bs32 val1 = DREG (src1);
4081 TRACE_INSN (cpu, "R%i.%s = R%i %s R%i (RND20)", dst0, HL ? "L" : "H",
4082 src0, aop & 0x1 ? "-" : "+", src1);
4084 /* If subtract, just invert and add one. */
4088 res = (val0 >> 4) + (val1 >> 4) + (((val0 & 0xf) + (val1 & 0xf)) >> 4);
4090 /* Don't sign extend during the shift. */
4091 res = ((bu32)res >> 16);
4093 /* Don't worry about overflows, since we are shifting right. */
4096 STORE (DREG (dst0), REG_H_L (res << 16, DREG (dst0)));
4098 STORE (DREG (dst0), REG_H_L (DREG (dst0), res));
4100 SET_ASTATREG (az, res == 0);
4101 SET_ASTATREG (an, res & 0x8000);
4102 SET_ASTATREG (v, 0);
4104 else if (aopcde == 2 || aopcde == 3)
4106 bu32 s1, s2, val, ac0_i = 0, v_i = 0;
4108 TRACE_INSN (cpu, "R%i.%c = R%i.%c %c R%i.%c%s;",
4109 dst0, HL ? 'H' : 'L',
4110 src0, aop & 2 ? 'H' : 'L',
4111 aopcde == 2 ? '+' : '-',
4112 src1, aop & 1 ? 'H' : 'L',
4123 val = add16 (cpu, s1, s2, &ac0_i, &v_i, 0, 0, s, 0);
4125 val = sub16 (cpu, s1, s2, &ac0_i, &v_i, 0, 0, s, 0);
4127 SET_ASTATREG (ac0, ac0_i);
4128 SET_ASTATREG (v, v_i);
4130 SET_ASTATREG (vs, v_i);
4133 SET_DREG_H (dst0, val << 16);
4135 SET_DREG_L (dst0, val);
4137 SET_ASTATREG (an, val & 0x8000);
4138 SET_ASTATREG (az, val == 0);
4140 else if ((aop == 0 || aop == 2) && aopcde == 9 && s == 1)
4143 TRACE_INSN (cpu, "A%i = R%i;", a, src0);
4144 SET_AREG32 (a, DREG (src0));
4146 else if ((aop == 1 || aop == 3) && aopcde == 9 && s == 0)
4149 TRACE_INSN (cpu, "A%i.X = R%i.L;", a, src0);
4150 SET_AXREG (a, (bs8)DREG (src0));
4152 else if (aop == 3 && aopcde == 11 && (s == 0 || s == 1))
4154 bu64 acc0 = get_extended_acc (cpu, 0);
4155 bu64 acc1 = get_extended_acc (cpu, 1);
4156 bu32 carry = (bu40)acc1 < (bu40)acc0;
4159 TRACE_INSN (cpu, "A0 -= A1%s;", s ? " (W32)" : "");
4162 if ((bs64)acc0 < -0x8000000000ll)
4163 acc0 = -0x8000000000ull, sat = 1;
4164 else if ((bs64)acc0 >= 0x7fffffffffll)
4165 acc0 = 0x7fffffffffull, sat = 1;
4169 /* A0 -= A1 (W32) */
4170 if (acc0 & (bu64)0x8000000000ll)
4171 acc0 &= 0x80ffffffffll, sat = 1;
4173 acc0 &= 0xffffffffll;
4175 STORE (AXREG (0), (acc0 >> 32) & 0xff);
4176 STORE (AWREG (0), acc0 & 0xffffffff);
4177 STORE (ASTATREG (az), acc0 == 0);
4178 STORE (ASTATREG (an), !!(acc0 & (bu64)0x8000000000ll));
4179 STORE (ASTATREG (ac0), carry);
4180 STORE (ASTATREG (ac0_copy), carry);
4181 STORE (ASTATREG (av0), sat);
4183 STORE (ASTATREG (av0s), sat);
4185 else if ((aop == 0 || aop == 1) && aopcde == 22)
4187 bu32 s0, s0L, s0H, s1, s1L, s1H;
4189 const char * const opts[] = { "rndl", "rndh", "tl", "th" };
4191 TRACE_INSN (cpu, "R%i = BYTEOP2P (R%i:%i, R%i:%i) (%s%s);", dst0,
4192 src0 + 1, src0, src1 + 1, src1, opts[HL + (aop << 1)],
4196 s0H = DREG (src0 + 1);
4198 s1H = DREG (src1 + 1);
4201 s0 = algn (s0H, s0L, IREG (0) & 3);
4202 s1 = algn (s1H, s1L, IREG (0) & 3);
4206 s0 = algn (s0L, s0H, IREG (0) & 3);
4207 s1 = algn (s1L, s1H, IREG (0) & 3);
4211 tmp0 = ((((s1 >> 8) & 0xff) + ((s1 >> 0) & 0xff) +
4212 ((s0 >> 8) & 0xff) + ((s0 >> 0) & 0xff) + i) >> 2) & 0xff;
4213 tmp1 = ((((s1 >> 24) & 0xff) + ((s1 >> 16) & 0xff) +
4214 ((s0 >> 24) & 0xff) + ((s0 >> 16) & 0xff) + i) >> 2) & 0xff;
4215 STORE (DREG (dst0), (tmp1 << (16 + (HL * 8))) | (tmp0 << (HL * 8)));
4217 /* Implicit DISALGNEXCPT in parallel. */
4220 else if ((aop == 0 || aop == 1) && s == 0 && aopcde == 8)
4222 TRACE_INSN (cpu, "A%i = 0;", aop);
4225 else if (aop == 2 && s == 0 && aopcde == 8)
4227 TRACE_INSN (cpu, "A1 = A0 = 0;");
4231 else if ((aop == 0 || aop == 1 || aop == 2) && s == 1 && aopcde == 8)
4233 bs40 acc0 = get_extended_acc (cpu, 0);
4234 bs40 acc1 = get_extended_acc (cpu, 1);
4237 if (aop == 0 || aop == 1)
4238 TRACE_INSN (cpu, "A%i = A%i (S);", aop, aop);
4240 TRACE_INSN (cpu, "A1 = A1 (S), A0 = A0 (S);");
4242 if (aop == 0 || aop == 2)
4245 acc0 = saturate_s32 (acc0, &sat);
4246 acc0 |= -(acc0 & 0x80000000ull);
4247 SET_AXREG (0, (acc0 >> 31) & 0xFF);
4248 SET_AWREG (0, acc0 & 0xFFFFFFFF);
4249 SET_ASTATREG (av0, sat);
4251 SET_ASTATREG (av0s, sat);
4256 if (aop == 1 || aop == 2)
4259 acc1 = saturate_s32 (acc1, &sat);
4260 acc1 |= -(acc1 & 0x80000000ull);
4261 SET_AXREG (1, (acc1 >> 31) & 0xFF);
4262 SET_AWREG (1, acc1 & 0xFFFFFFFF);
4263 SET_ASTATREG (av1, sat);
4265 SET_ASTATREG (av1s, sat);
4270 SET_ASTATREG (az, (acc0 == 0) || (acc1 == 0));
4271 SET_ASTATREG (an, ((acc0 >> 31) & 1) || ((acc1 >> 31) & 1));
4273 else if (aop == 3 && (s == 0 || s == 1) && aopcde == 8)
4275 TRACE_INSN (cpu, "A%i = A%i;", s, !s);
4276 SET_AXREG (s, AXREG (!s));
4277 SET_AWREG (s, AWREG (!s));
4279 else if (aop == 3 && HL == 0 && aopcde == 16)
4284 TRACE_INSN (cpu, "A1 = ABS A1 , A0 = ABS A0;");
4287 for (i = 0; i < 2; ++i)
4290 bs40 acc = get_extended_acc (cpu, i);
4294 av = acc == ((bs40)1 << 39);
4296 acc = ((bs40)1 << 39) - 1;
4299 SET_ASTATREG (av[i], av);
4301 SET_ASTATREG (avs[i], av);
4304 SET_ASTATREG (az, az);
4305 SET_ASTATREG (an, 0);
4307 else if (aop == 0 && aopcde == 23)
4309 bu32 s0, s0L, s0H, s1, s1L, s1H;
4312 TRACE_INSN (cpu, "R%i = BYTEOP3P (R%i:%i, R%i:%i) (%s%s);", dst0,
4313 src0 + 1, src0, src1 + 1, src1, HL ? "HI" : "LO",
4317 s0H = DREG (src0 + 1);
4319 s1H = DREG (src1 + 1);
4322 s0 = algn (s0H, s0L, IREG (0) & 3);
4323 s1 = algn (s1H, s1L, IREG (1) & 3);
4327 s0 = algn (s0L, s0H, IREG (0) & 3);
4328 s1 = algn (s1L, s1H, IREG (1) & 3);
4331 tmp0 = (bs32)(bs16)(s0 >> 0) + ((s1 >> ( 0 + (8 * !HL))) & 0xff);
4332 tmp1 = (bs32)(bs16)(s0 >> 16) + ((s1 >> (16 + (8 * !HL))) & 0xff);
4333 STORE (DREG (dst0), (CLAMP (tmp0, 0, 255) << ( 0 + (8 * HL))) |
4334 (CLAMP (tmp1, 0, 255) << (16 + (8 * HL))));
4336 /* Implicit DISALGNEXCPT in parallel. */
4339 else if ((aop == 0 || aop == 1) && aopcde == 16)
4344 TRACE_INSN (cpu, "A%i = ABS A%i;", HL, aop);
4346 acc = get_extended_acc (cpu, aop);
4349 av = acc == ((bs40)1 << 39);
4351 acc = ((bs40)1 << 39) - 1;
4354 SET_ASTATREG (av[HL], av);
4356 SET_ASTATREG (avs[HL], av);
4357 SET_ASTATREG (az, acc == 0);
4358 SET_ASTATREG (an, 0);
4360 else if (aop == 3 && aopcde == 12)
4362 bs32 res = DREG (src0);
4364 bool sBit_a, sBit_b;
4366 TRACE_INSN (cpu, "R%i.%s = R%i (RND);", dst0, HL == 0 ? "L" : "H", src0);
4367 TRACE_DECODE (cpu, "R%i.%s = R%i:%#x (RND);", dst0,
4368 HL == 0 ? "L" : "H", src0, res);
4370 sBit_b = !!(res & 0x80000000);
4373 sBit_a = !!(res & 0x80000000);
4375 /* Overflow if the sign bit changed when we rounded. */
4376 if ((res >> 16) && (sBit_b != sBit_a))
4391 SET_DREG (dst0, REG_H_L (DREG (dst0), res));
4393 SET_DREG (dst0, REG_H_L (res << 16, DREG (dst0)));
4395 SET_ASTATREG (az, res == 0);
4396 SET_ASTATREG (an, res < 0);
4397 SET_ASTATREG (v, ovX);
4399 SET_ASTATREG (vs, ovX);
4401 else if (aop == 3 && HL == 0 && aopcde == 15)
4403 bu32 hi = (-(bs16)(DREG (src0) >> 16)) << 16;
4404 bu32 lo = (-(bs16)(DREG (src0) & 0xFFFF)) & 0xFFFF;
4407 TRACE_INSN (cpu, "R%i = -R%i (V);", dst0, src0);
4411 if (hi == 0x80000000)
4427 SET_DREG (dst0, hi | lo);
4429 SET_ASTATREG (v, v);
4431 SET_ASTATREG (vs, 1);
4432 SET_ASTATREG (ac0, ac0);
4433 SET_ASTATREG (ac1, ac1);
4434 setflags_nz_2x16 (cpu, DREG (dst0));
4436 else if (aop == 3 && HL == 0 && aopcde == 14)
4438 TRACE_INSN (cpu, "A1 = - A1 , A0 = - A0;");
4440 SET_AREG (0, saturate_s40 (-get_extended_acc (cpu, 0)));
4441 SET_AREG (1, saturate_s40 (-get_extended_acc (cpu, 1)));
4442 /* XXX: what ASTAT flags need updating ? */
4444 else if ((aop == 0 || aop == 1) && (HL == 0 || HL == 1) && aopcde == 14)
4446 bs40 src_acc = get_extended_acc (cpu, aop);
4449 TRACE_INSN (cpu, "A%i = - A%i;", HL, aop);
4451 SET_AREG (HL, saturate_s40_astat (-src_acc, &v));
4453 SET_ASTATREG (az, AWREG (HL) == 0 && AXREG (HL) == 0);
4454 SET_ASTATREG (an, AXREG (HL) >> 7);
4457 SET_ASTATREG (ac0, !src_acc);
4458 SET_ASTATREG (av0, v);
4460 SET_ASTATREG (av0s, 1);
4464 SET_ASTATREG (ac1, !src_acc);
4465 SET_ASTATREG (av1, v);
4467 SET_ASTATREG (av1s, 1);
4470 else if (aop == 0 && aopcde == 12)
4472 bs16 tmp0_hi = DREG (src0) >> 16;
4473 bs16 tmp0_lo = DREG (src0);
4474 bs16 tmp1_hi = DREG (src1) >> 16;
4475 bs16 tmp1_lo = DREG (src1);
4477 TRACE_INSN (cpu, "R%i.L = R%i.H = SIGN(R%i.H) * R%i.H + SIGN(R%i.L) * R%i.L;",
4478 dst0, dst0, src0, src1, src0, src1);
4480 if ((tmp0_hi >> 15) & 1)
4481 tmp1_hi = ~tmp1_hi + 1;
4483 if ((tmp0_lo >> 15) & 1)
4484 tmp1_lo = ~tmp1_lo + 1;
4486 tmp1_hi = tmp1_hi + tmp1_lo;
4488 STORE (DREG (dst0), REG_H_L (tmp1_hi << 16, tmp1_hi));
4490 else if (aopcde == 0)
4492 bu32 s0 = DREG (src0);
4493 bu32 s1 = DREG (src1);
4494 bu32 s0h = s0 >> 16;
4495 bu32 s0l = s0 & 0xFFFF;
4496 bu32 s1h = s1 >> 16;
4497 bu32 s1l = s1 & 0xFFFF;
4499 bu32 ac1_i = 0, ac0_i = 0, v_i = 0, z_i = 0, n_i = 0;
4501 TRACE_INSN (cpu, "R%i = R%i %c|%c R%i%s;", dst0, src0,
4502 (aop & 2) ? '-' : '+', (aop & 1) ? '-' : '+', src1,
4505 t0 = sub16 (cpu, s0h, s1h, &ac1_i, &v_i, &z_i, &n_i, s, 0);
4507 t0 = add16 (cpu, s0h, s1h, &ac1_i, &v_i, &z_i, &n_i, s, 0);
4510 t1 = sub16 (cpu, s0l, s1l, &ac0_i, &v_i, &z_i, &n_i, s, 0);
4512 t1 = add16 (cpu, s0l, s1l, &ac0_i, &v_i, &z_i, &n_i, s, 0);
4514 SET_ASTATREG (ac1, ac1_i);
4515 SET_ASTATREG (ac0, ac0_i);
4516 SET_ASTATREG (az, z_i);
4517 SET_ASTATREG (an, n_i);
4518 SET_ASTATREG (v, v_i);
4520 SET_ASTATREG (vs, v_i);
4525 SET_DREG (dst0, (t1 << 16) | t0);
4527 SET_DREG (dst0, (t0 << 16) | t1);
4529 else if (aop == 1 && aopcde == 12)
4531 bs32 val0 = (bs16)(AWREG (0) >> 16) + (bs16)AWREG (0);
4532 bs32 val1 = (bs16)(AWREG (1) >> 16) + (bs16)AWREG (1);
4534 TRACE_INSN (cpu, "R%i = A1.L + A1.H, R%i = A0.L + A0.H;", dst1, dst0);
4537 illegal_instruction_combination (cpu);
4539 SET_DREG (dst0, val0);
4540 SET_DREG (dst1, val1);
4542 else if (aopcde == 1)
4546 bu16 s0L = DREG (src0);
4547 bu16 s0H = DREG (src0) >> 16;
4548 bu16 s1L = DREG (src1);
4549 bu16 s1H = DREG (src1) >> 16;
4550 bu32 v_i = 0, n_i = 0, z_i = 0;
4552 TRACE_INSN (cpu, "R%i = R%i %s R%i, R%i = R%i %s R%i%s;",
4553 dst1, src0, HL ? "+|-" : "+|+", src1,
4554 dst0, src0, HL ? "-|+" : "-|-", src1,
4555 amod0amod2 (s, x, aop));
4558 illegal_instruction_combination (cpu);
4562 x0 = add16 (cpu, s0H, s1H, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4563 x1 = add16 (cpu, s0L, s1L, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4564 d1 = (x0 << 16) | x1;
4566 x0 = sub16 (cpu, s0H, s1H, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4567 x1 = sub16 (cpu, s0L, s1L, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4569 d0 = (x0 << 16) | x1;
4571 d0 = (x1 << 16) | x0;
4575 x0 = add16 (cpu, s0H, s1H, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4576 x1 = sub16 (cpu, s0L, s1L, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4577 d1 = (x0 << 16) | x1;
4579 x0 = sub16 (cpu, s0H, s1H, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4580 x1 = add16 (cpu, s0L, s1L, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
4582 d0 = (x0 << 16) | x1;
4584 d0 = (x1 << 16) | x0;
4586 SET_ASTATREG (az, z_i);
4587 SET_ASTATREG (an, n_i);
4588 SET_ASTATREG (v, v_i);
4590 SET_ASTATREG (vs, v_i);
4592 STORE (DREG (dst0), d0);
4593 STORE (DREG (dst1), d1);
4595 else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 11)
4597 bs40 acc0 = get_extended_acc (cpu, 0);
4598 bs40 acc1 = get_extended_acc (cpu, 1);
4599 bu32 v, dreg, sat = 0;
4600 bu32 carry = !!((bu40)~acc1 < (bu40)acc0);
4603 TRACE_INSN (cpu, "R%i = (A0 += A1);", dst0);
4605 TRACE_INSN (cpu, "R%i.%c = (A0 += A1);", dst0, HL ? 'H' : 'L');
4607 TRACE_INSN (cpu, "A0 += A1%s;", s ? " (W32)" : "");
4610 acc0 = saturate_s40_astat (acc0, &v);
4612 if (aop == 2 && s == 1) /* A0 += A1 (W32) */
4614 if (acc0 & (bs40)0x8000000000ll)
4615 acc0 &= 0x80ffffffffll;
4617 acc0 &= 0xffffffffll;
4620 STORE (AXREG (0), acc0 >> 32);
4621 STORE (AWREG (0), acc0);
4622 SET_ASTATREG (av0, v && acc1);
4624 SET_ASTATREG (av0s, v);
4626 if (aop == 0 || aop == 1)
4628 if (aop) /* Dregs_lo = A0 += A1 */
4630 dreg = saturate_s32 (rnd16 (acc0) << 16, &sat);
4632 STORE (DREG (dst0), REG_H_L (dreg, DREG (dst0)));
4634 STORE (DREG (dst0), REG_H_L (DREG (dst0), dreg >> 16));
4636 else /* Dregs = A0 += A1 */
4638 dreg = saturate_s32 (acc0, &sat);
4639 STORE (DREG (dst0), dreg);
4642 STORE (ASTATREG (az), dreg == 0);
4643 STORE (ASTATREG (an), !!(dreg & 0x80000000));
4644 STORE (ASTATREG (ac0), carry);
4645 STORE (ASTATREG (ac0_copy), carry);
4646 STORE (ASTATREG (v), sat);
4647 STORE (ASTATREG (v_copy), sat);
4649 STORE (ASTATREG (vs), sat);
4653 STORE (ASTATREG (az), acc0 == 0);
4654 STORE (ASTATREG (an), !!(acc0 & 0x8000000000ull));
4655 STORE (ASTATREG (ac0), carry);
4656 STORE (ASTATREG (ac0_copy), carry);
4659 else if ((aop == 0 || aop == 1) && aopcde == 10)
4661 TRACE_INSN (cpu, "R%i.L = A%i.X;", dst0, aop);
4662 SET_DREG_L (dst0, (bs8)AXREG (aop));
4664 else if (aop == 0 && aopcde == 4)
4666 TRACE_INSN (cpu, "R%i = R%i + R%i%s;", dst0, src0, src1, amod1 (s, x));
4667 SET_DREG (dst0, add32 (cpu, DREG (src0), DREG (src1), 1, s));
4669 else if (aop == 1 && aopcde == 4)
4671 TRACE_INSN (cpu, "R%i = R%i - R%i%s;", dst0, src0, src1, amod1 (s, x));
4672 SET_DREG (dst0, sub32 (cpu, DREG (src0), DREG (src1), 1, s, 0));
4674 else if (aop == 2 && aopcde == 4)
4676 TRACE_INSN (cpu, "R%i = R%i + R%i, R%i = R%i - R%i%s;",
4677 dst1, src0, src1, dst0, src0, src1, amod1 (s, x));
4680 illegal_instruction_combination (cpu);
4682 STORE (DREG (dst1), add32 (cpu, DREG (src0), DREG (src1), 1, s));
4683 STORE (DREG (dst0), sub32 (cpu, DREG (src0), DREG (src1), 1, s, 1));
4685 else if ((aop == 0 || aop == 1) && aopcde == 17)
4687 bs40 acc0 = get_extended_acc (cpu, 0);
4688 bs40 acc1 = get_extended_acc (cpu, 1);
4689 bs40 val0, val1, sval0, sval1;
4692 TRACE_INSN (cpu, "R%i = A%i + A%i, R%i = A%i - A%i%s",
4693 dst1, !aop, aop, dst0, !aop, aop, amod1 (s, x));
4694 TRACE_DECODE (cpu, "R%i = A%i:%#"PRIx64" + A%i:%#"PRIx64", "
4695 "R%i = A%i:%#"PRIx64" - A%i:%#"PRIx64"%s",
4696 dst1, !aop, aop ? acc0 : acc1, aop, aop ? acc1 : acc0,
4697 dst0, !aop, aop ? acc0 : acc1, aop, aop ? acc1 : acc0,
4701 illegal_instruction_combination (cpu);
4709 sval0 = saturate_s32 (val0, &sat);
4711 sval1 = saturate_s32 (val1, &sat);
4719 STORE (DREG (dst0), val0);
4720 STORE (DREG (dst1), val1);
4721 SET_ASTATREG (v, sat_i);
4723 SET_ASTATREG (vs, sat_i);
4724 SET_ASTATREG (an, val0 & 0x80000000 || val1 & 0x80000000);
4725 SET_ASTATREG (az, val0 == 0 || val1 == 0);
4726 SET_ASTATREG (ac1, (bu40)~acc0 < (bu40)acc1);
4728 SET_ASTATREG (ac0, !!((bu40)acc1 <= (bu40)acc0));
4730 SET_ASTATREG (ac0, !!((bu40)acc0 <= (bu40)acc1));
4732 else if (aop == 0 && aopcde == 18)
4734 bu40 acc0 = get_extended_acc (cpu, 0);
4735 bu40 acc1 = get_extended_acc (cpu, 1);
4736 bu32 s0L = DREG (src0);
4737 bu32 s0H = DREG (src0 + 1);
4738 bu32 s1L = DREG (src1);
4739 bu32 s1H = DREG (src1 + 1);
4741 bs16 tmp0, tmp1, tmp2, tmp3;
4743 /* This instruction is only defined for register pairs R1:0 and R3:2. */
4744 if (!((src0 == 0 || src0 == 2) && (src1 == 0 || src1 == 2)))
4745 illegal_instruction (cpu);
4747 TRACE_INSN (cpu, "SAA (R%i:%i, R%i:%i)%s", src0 + 1, src0,
4748 src1 + 1, src1, s ? " (R)" :"");
4750 /* Bit s determines the order of the two registers from a pair:
4751 if s=0 the low-order bytes come from the low reg in the pair,
4752 and if s=1 the low-order bytes come from the high reg. */
4756 s0 = algn (s0H, s0L, IREG (0) & 3);
4757 s1 = algn (s1H, s1L, IREG (1) & 3);
4761 s0 = algn (s0L, s0H, IREG (0) & 3);
4762 s1 = algn (s1L, s1H, IREG (1) & 3);
4765 /* Find the absolute difference between pairs, make it
4766 absolute, then add it to the existing accumulator half. */
4768 tmp0 = ((s0 << 24) >> 24) - ((s1 << 24) >> 24);
4769 tmp1 = ((s0 << 16) >> 24) - ((s1 << 16) >> 24);
4770 tmp2 = ((s0 << 8) >> 24) - ((s1 << 8) >> 24);
4771 tmp3 = ((s0 << 0) >> 24) - ((s1 << 0) >> 24);
4773 tmp0 = (tmp0 < 0) ? -tmp0 : tmp0;
4774 tmp1 = (tmp1 < 0) ? -tmp1 : tmp1;
4775 tmp2 = (tmp2 < 0) ? -tmp2 : tmp2;
4776 tmp3 = (tmp3 < 0) ? -tmp3 : tmp3;
4778 s0L = saturate_u16 ((bu32)tmp0 + ((acc0 >> 0) & 0xffff), 0);
4779 s0H = saturate_u16 ((bu32)tmp1 + ((acc0 >> 16) & 0xffff), 0);
4780 s1L = saturate_u16 ((bu32)tmp2 + ((acc1 >> 0) & 0xffff), 0);
4781 s1H = saturate_u16 ((bu32)tmp3 + ((acc1 >> 16) & 0xffff), 0);
4783 STORE (AWREG (0), (s0H << 16) | (s0L & 0xFFFF));
4784 STORE (AXREG (0), 0);
4785 STORE (AWREG (1), (s1H << 16) | (s1L & 0xFFFF));
4786 STORE (AXREG (1), 0);
4788 /* Implicit DISALGNEXCPT in parallel. */
4791 else if (aop == 3 && aopcde == 18)
4793 TRACE_INSN (cpu, "DISALGNEXCPT");
4796 else if ((aop == 0 || aop == 1) && aopcde == 20)
4798 bu32 s0, s0L, s0H, s1, s1L, s1H;
4799 const char * const opts[] = { "", " (R)", " (T)", " (T, R)" };
4801 TRACE_INSN (cpu, "R%i = BYTEOP1P (R%i:%i, R%i:%i)%s;", dst0,
4802 src0 + 1, src0, src1 + 1, src1, opts[s + (aop << 1)]);
4805 s0H = DREG (src0 + 1);
4807 s1H = DREG (src1 + 1);
4810 s0 = algn (s0H, s0L, IREG (0) & 3);
4811 s1 = algn (s1H, s1L, IREG (1) & 3);
4815 s0 = algn (s0L, s0H, IREG (0) & 3);
4816 s1 = algn (s1L, s1H, IREG (1) & 3);
4820 (((((s0 >> 0) & 0xff) + ((s1 >> 0) & 0xff) + !aop) >> 1) << 0) |
4821 (((((s0 >> 8) & 0xff) + ((s1 >> 8) & 0xff) + !aop) >> 1) << 8) |
4822 (((((s0 >> 16) & 0xff) + ((s1 >> 16) & 0xff) + !aop) >> 1) << 16) |
4823 (((((s0 >> 24) & 0xff) + ((s1 >> 24) & 0xff) + !aop) >> 1) << 24));
4825 /* Implicit DISALGNEXCPT in parallel. */
4828 else if (aop == 0 && aopcde == 21)
4830 bu32 s0, s0L, s0H, s1, s1L, s1H;
4832 TRACE_INSN (cpu, "(R%i, R%i) = BYTEOP16P (R%i:%i, R%i:%i)%s;", dst1, dst0,
4833 src0 + 1, src0, src1 + 1, src1, s ? " (R)" : "");
4836 illegal_instruction_combination (cpu);
4839 s0H = DREG (src0 + 1);
4841 s1H = DREG (src1 + 1);
4844 s0 = algn (s0H, s0L, IREG (0) & 3);
4845 s1 = algn (s1H, s1L, IREG (1) & 3);
4849 s0 = algn (s0L, s0H, IREG (0) & 3);
4850 s1 = algn (s1L, s1H, IREG (1) & 3);
4854 ((((s0 >> 0) & 0xff) + ((s1 >> 0) & 0xff)) << 0) |
4855 ((((s0 >> 8) & 0xff) + ((s1 >> 8) & 0xff)) << 16));
4857 ((((s0 >> 16) & 0xff) + ((s1 >> 16) & 0xff)) << 0) |
4858 ((((s0 >> 24) & 0xff) + ((s1 >> 24) & 0xff)) << 16));
4860 /* Implicit DISALGNEXCPT in parallel. */
4863 else if (aop == 1 && aopcde == 21)
4865 bu32 s0, s0L, s0H, s1, s1L, s1H;
4867 TRACE_INSN (cpu, "(R%i, R%i) = BYTEOP16M (R%i:%i, R%i:%i)%s;", dst1, dst0,
4868 src0 + 1, src0, src1 + 1, src1, s ? " (R)" : "");
4871 illegal_instruction_combination (cpu);
4874 s0H = DREG (src0 + 1);
4876 s1H = DREG (src1 + 1);
4879 s0 = algn (s0H, s0L, IREG (0) & 3);
4880 s1 = algn (s1H, s1L, IREG (1) & 3);
4884 s0 = algn (s0L, s0H, IREG (0) & 3);
4885 s1 = algn (s1L, s1H, IREG (1) & 3);
4889 (((((s0 >> 0) & 0xff) - ((s1 >> 0) & 0xff)) << 0) & 0xffff) |
4890 (((((s0 >> 8) & 0xff) - ((s1 >> 8) & 0xff)) << 16)));
4892 (((((s0 >> 16) & 0xff) - ((s1 >> 16) & 0xff)) << 0) & 0xffff) |
4893 (((((s0 >> 24) & 0xff) - ((s1 >> 24) & 0xff)) << 16)));
4895 /* Implicit DISALGNEXCPT in parallel. */
4898 else if (aop == 1 && aopcde == 7)
4900 TRACE_INSN (cpu, "R%i = MIN (R%i, R%i);", dst0, src0, src1);
4901 SET_DREG (dst0, min32 (cpu, DREG (src0), DREG (src1)));
4903 else if (aop == 0 && aopcde == 7)
4905 TRACE_INSN (cpu, "R%i = MAX (R%i, R%i);", dst0, src0, src1);
4906 SET_DREG (dst0, max32 (cpu, DREG (src0), DREG (src1)));
4908 else if (aop == 2 && aopcde == 7)
4910 bu32 val = DREG (src0);
4913 TRACE_INSN (cpu, "R%i = ABS R%i;", dst0, src0);
4917 v = (val == 0x80000000);
4920 SET_DREG (dst0, val);
4922 SET_ASTATREG (v, v);
4924 SET_ASTATREG (vs, 1);
4925 setflags_nz (cpu, val);
4927 else if (aop == 3 && aopcde == 7)
4929 bu32 val = DREG (src0);
4931 TRACE_INSN (cpu, "R%i = - R%i %s;", dst0, src0, amod1 (s, 0));
4933 if (s && val == 0x80000000)
4936 SET_ASTATREG (v, 1);
4937 SET_ASTATREG (vs, 1);
4939 else if (val == 0x80000000)
4943 SET_DREG (dst0, val);
4945 SET_ASTATREG (az, val == 0);
4946 SET_ASTATREG (an, val & 0x80000000);
4948 else if (aop == 2 && aopcde == 6)
4950 bu32 in = DREG (src0);
4951 bu32 hi = (in & 0x80000000 ? (bu32)-(bs16)(in >> 16) : in >> 16) << 16;
4952 bu32 lo = (in & 0x8000 ? (bu32)-(bs16)(in & 0xFFFF) : in) & 0xFFFF;
4955 TRACE_INSN (cpu, "R%i = ABS R%i (V);", dst0, src0);
4958 if (hi == 0x80000000)
4968 SET_DREG (dst0, hi | lo);
4970 SET_ASTATREG (v, v);
4972 SET_ASTATREG (vs, 1);
4973 setflags_nz_2x16 (cpu, DREG (dst0));
4975 else if (aop == 1 && aopcde == 6)
4977 TRACE_INSN (cpu, "R%i = MIN (R%i, R%i) (V);", dst0, src0, src1);
4978 SET_DREG (dst0, min2x16 (cpu, DREG (src0), DREG (src1)));
4980 else if (aop == 0 && aopcde == 6)
4982 TRACE_INSN (cpu, "R%i = MAX (R%i, R%i) (V);", dst0, src0, src1);
4983 SET_DREG (dst0, max2x16 (cpu, DREG (src0), DREG (src1)));
4985 else if (aop == 0 && aopcde == 24)
4987 TRACE_INSN (cpu, "R%i = BYTEPACK (R%i, R%i);", dst0, src0, src1);
4989 (((DREG (src0) >> 0) & 0xff) << 0) |
4990 (((DREG (src0) >> 16) & 0xff) << 8) |
4991 (((DREG (src1) >> 0) & 0xff) << 16) |
4992 (((DREG (src1) >> 16) & 0xff) << 24));
4994 /* Implicit DISALGNEXCPT in parallel. */
4997 else if (aop == 1 && aopcde == 24)
5001 bu8 bytea, byteb, bytec, byted;
5003 TRACE_INSN (cpu, "(R%i, R%i) = BYTEUNPACK R%i:%i%s;",
5004 dst1, dst0, src0 + 1, src0, s ? " (R)" : "");
5007 illegal_instruction_combination (cpu);
5009 order = IREG (0) & 0x3;
5011 hi = src0, lo = src0 + 1;
5013 hi = src0 + 1, lo = src0;
5014 comb_src = (((bu64)DREG (hi)) << 32) | DREG (lo);
5015 bytea = (comb_src >> (0 + 8 * order));
5016 byteb = (comb_src >> (8 + 8 * order));
5017 bytec = (comb_src >> (16 + 8 * order));
5018 byted = (comb_src >> (24 + 8 * order));
5019 STORE (DREG (dst0), bytea | ((bu32)byteb << 16));
5020 STORE (DREG (dst1), bytec | ((bu32)byted << 16));
5022 /* Implicit DISALGNEXCPT in parallel. */
5025 else if (aopcde == 13)
5027 const char *searchmodes[] = { "GT", "GE", "LT", "LE" };
5029 bs16 a0_lo, a1_lo, src_hi, src_lo;
5031 TRACE_INSN (cpu, "(R%i, R%i) = SEARCH R%i (%s);",
5032 dst1, dst0, src0, searchmodes[aop]);
5035 illegal_instruction_combination (cpu);
5037 up_hi = up_lo = false;
5040 src_lo = DREG (src0);
5041 src_hi = DREG (src0) >> 16;
5046 up_hi = (src_hi > a1_lo);
5047 up_lo = (src_lo > a0_lo);
5050 up_hi = (src_hi >= a1_lo);
5051 up_lo = (src_lo >= a0_lo);
5054 up_hi = (src_hi < a1_lo);
5055 up_lo = (src_lo < a0_lo);
5058 up_hi = (src_hi <= a1_lo);
5059 up_lo = (src_lo <= a0_lo);
5065 SET_AREG (1, src_hi);
5066 SET_DREG (dst1, PREG (0));
5069 SET_AREG (1, a1_lo);
5073 SET_AREG (0, src_lo);
5074 SET_DREG (dst0, PREG (0));
5077 SET_AREG (0, a0_lo);
5080 illegal_instruction (cpu);
5084 decode_dsp32shift_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
5087 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
5088 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
5089 |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
5090 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
5091 int HLs = ((iw1 >> DSP32Shift_HLs_bits) & DSP32Shift_HLs_mask);
5092 int sop = ((iw1 >> DSP32Shift_sop_bits) & DSP32Shift_sop_mask);
5093 int src0 = ((iw1 >> DSP32Shift_src0_bits) & DSP32Shift_src0_mask);
5094 int src1 = ((iw1 >> DSP32Shift_src1_bits) & DSP32Shift_src1_mask);
5095 int dst0 = ((iw1 >> DSP32Shift_dst0_bits) & DSP32Shift_dst0_mask);
5096 int sopcde = ((iw0 >> (DSP32Shift_sopcde_bits - 16)) & DSP32Shift_sopcde_mask);
5097 int M = ((iw0 >> (DSP32Shift_M_bits - 16)) & DSP32Shift_M_mask);
5099 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32shift);
5100 TRACE_EXTRACT (cpu, "%s: M:%i sopcde:%i sop:%i HLs:%i dst0:%i src0:%i src1:%i",
5101 __func__, M, sopcde, sop, HLs, dst0, src0, src1);
5103 if ((sop == 0 || sop == 1) && sopcde == 0)
5106 bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
5108 TRACE_INSN (cpu, "R%i.%c = ASHIFT R%i.%c BY R%i.L%s;",
5109 dst0, HLs < 2 ? 'L' : 'H',
5110 src1, HLs & 1 ? 'H' : 'L',
5111 src0, sop == 1 ? " (S)" : "");
5114 val = (bu16)(DREG (src1) & 0xFFFF);
5116 val = (bu16)((DREG (src1) & 0xFFFF0000) >> 16);
5118 /* Positive shift magnitudes produce Logical Left shifts.
5119 Negative shift magnitudes produce Arithmetic Right shifts. */
5121 val = ashiftrt (cpu, val, -shft, 16);
5123 val = lshift (cpu, val, shft, 16, sop == 1);
5126 STORE (DREG (dst0), REG_H_L (DREG (dst0), val));
5128 STORE (DREG (dst0), REG_H_L (val << 16, DREG (dst0)));
5130 else if (sop == 2 && sopcde == 0)
5132 bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
5135 TRACE_INSN (cpu, "R%i.%c = LSHIFT R%i.%c BY R%i.L;",
5136 dst0, HLs < 2 ? 'L' : 'H',
5137 src1, HLs & 1 ? 'H' : 'L', src0);
5140 val = (bu16)(DREG (src1) & 0xFFFF);
5142 val = (bu16)((DREG (src1) & 0xFFFF0000) >> 16);
5145 val = val >> (-1 * shft);
5150 SET_DREG (dst0, REG_H_L (DREG (dst0), val));
5152 SET_DREG (dst0, REG_H_L (val << 16, DREG (dst0)));
5154 SET_ASTATREG (az, !((val & 0xFFFF0000) == 0) || ((val & 0xFFFF) == 0));
5155 SET_ASTATREG (an, (!!(val & 0x80000000)) ^ (!!(val & 0x8000)));
5156 SET_ASTATREG (v, 0);
5158 else if (sop == 2 && sopcde == 3 && (HLs == 1 || HLs == 0))
5160 int shift = imm6 (DREG (src0) & 0xFFFF);
5162 bu40 acc = get_unextended_acc (cpu, HLs);
5164 TRACE_INSN (cpu, "A%i = ROT A%i BY R%i.L;", HLs, HLs, src0);
5165 TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i CC:%i", HLs, acc, shift, cc);
5167 acc = rot40 (acc, shift, &cc);
5168 SET_AREG (HLs, acc);
5172 else if (sop == 0 && sopcde == 3 && (HLs == 0 || HLs == 1))
5174 bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
5175 bu64 val = get_extended_acc (cpu, HLs);
5178 TRACE_INSN (cpu, "A%i = ASHIFT A%i BY R%i.L;", HLs, HLs, src0);
5179 TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i", HLs, val, shft);
5182 val = ashiftrt (cpu, val, -shft, 40);
5184 val = lshift (cpu, val, shft, 40, 0);
5186 STORE (AXREG (HLs), (val >> 32) & 0xff);
5187 STORE (AWREG (HLs), (val & 0xffffffff));
5189 else if (sop == 1 && sopcde == 3 && (HLs == 0 || HLs == 1))
5191 bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
5195 TRACE_INSN (cpu, "A%i = LSHIFT A%i BY R%i.L;", HLs, HLs, src0);
5196 val = get_extended_acc (cpu, HLs);
5199 val = lshiftrt (cpu, val, -shft, 40);
5201 val = lshift (cpu, val, shft, 40, 0);
5203 STORE (AXREG (HLs), (val >> 32) & 0xff);
5204 STORE (AWREG (HLs), (val & 0xffffffff));
5206 else if ((sop == 0 || sop == 1) && sopcde == 1)
5208 bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
5212 TRACE_INSN (cpu, "R%i = ASHIFT R%i BY R%i.L (V%s);",
5213 dst0, src1, src0, sop == 1 ? ",S" : "");
5215 val0 = (bu16)DREG (src1) & 0xFFFF;
5216 val1 = (bu16)((DREG (src1) & 0xFFFF0000) >> 16);
5220 val0 = ashiftrt (cpu, val0, -shft, 16);
5222 val1 = ashiftrt (cpu, val1, -shft, 16);
5226 val0 = lshift (cpu, val0, shft, 16, sop == 1);
5228 val1 = lshift (cpu, val1, shft, 16, sop == 1);
5230 SET_ASTAT (ASTAT | astat);
5231 STORE (DREG (dst0), (val1 << 16) | val0);
5233 else if ((sop == 0 || sop == 1 || sop == 2) && sopcde == 2)
5235 /* dregs = [LA]SHIFT dregs BY dregs_lo (opt_S) */
5236 /* sop == 1 : opt_S */
5237 bu32 v = DREG (src1);
5238 /* LSHIFT uses sign extended low 6 bits of dregs_lo. */
5239 bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
5241 TRACE_INSN (cpu, "R%i = %cSHIFT R%i BY R%i.L%s;", dst0,
5242 shft && sop != 2 ? 'A' : 'L', src1, src0,
5243 sop == 1 ? " (S)" : "");
5248 STORE (DREG (dst0), lshiftrt (cpu, v, -shft, 32));
5250 STORE (DREG (dst0), ashiftrt (cpu, v, -shft, 32));
5253 STORE (DREG (dst0), lshift (cpu, v, shft, 32, sop == 1));
5255 else if (sop == 3 && sopcde == 2)
5257 int shift = imm6 (DREG (src0) & 0xFFFF);
5258 bu32 src = DREG (src1);
5259 bu32 ret, cc = CCREG;
5261 TRACE_INSN (cpu, "R%i = ROT R%i BY R%i.L;", dst0, src1, src0);
5262 TRACE_DECODE (cpu, "R%i:%#x R%i:%#x shift:%i CC:%i",
5263 dst0, DREG (dst0), src1, src, shift, cc);
5265 ret = rot32 (src, shift, &cc);
5266 STORE (DREG (dst0), ret);
5270 else if (sop == 2 && sopcde == 1)
5272 bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
5276 TRACE_INSN (cpu, "R%i = LSHIFT R%i BY R%i.L (V);", dst0, src1, src0);
5278 val0 = (bu16)DREG (src1) & 0xFFFF;
5279 val1 = (bu16)((DREG (src1) & 0xFFFF0000) >> 16);
5283 val0 = lshiftrt (cpu, val0, -shft, 16);
5285 val1 = lshiftrt (cpu, val1, -shft, 16);
5289 val0 = lshift (cpu, val0, shft, 16, 0);
5291 val1 = lshift (cpu, val1, shft, 16, 0);
5293 SET_ASTAT (ASTAT | astat);
5294 STORE (DREG (dst0), (val1 << 16) | val0);
5296 else if (sopcde == 4)
5298 bu32 sv0 = DREG (src0);
5299 bu32 sv1 = DREG (src1);
5300 TRACE_INSN (cpu, "R%i = PACK (R%i.%c, R%i.%c);", dst0,
5301 src1, sop & 2 ? 'H' : 'L',
5302 src0, sop & 1 ? 'H' : 'L');
5307 STORE (DREG (dst0), (sv1 << 16) | (sv0 & 0xFFFF));
5309 else if (sop == 0 && sopcde == 5)
5311 bu32 sv1 = DREG (src1);
5312 TRACE_INSN (cpu, "R%i.L = SIGNBITS R%i;", dst0, src1);
5313 SET_DREG_L (dst0, signbits (sv1, 32));
5315 else if (sop == 1 && sopcde == 5)
5317 bu32 sv1 = DREG (src1);
5318 TRACE_INSN (cpu, "R%i.L = SIGNBITS R%i.L;", dst0, src1);
5319 SET_DREG_L (dst0, signbits (sv1, 16));
5321 else if (sop == 2 && sopcde == 5)
5323 bu32 sv1 = DREG (src1);
5324 TRACE_INSN (cpu, "R%i.L = SIGNBITS R%i.H;", dst0, src1);
5325 SET_DREG_L (dst0, signbits (sv1 >> 16, 16));
5327 else if ((sop == 0 || sop == 1) && sopcde == 6)
5329 bu64 acc = AXREG (sop);
5330 TRACE_INSN (cpu, "R%i.L = SIGNBITS A%i;", dst0, sop);
5333 SET_DREG_L (dst0, signbits (acc, 40) & 0xFFFF);
5335 else if (sop == 3 && sopcde == 6)
5337 bu32 v = ones (DREG (src1));
5338 TRACE_INSN (cpu, "R%i.L = ONES R%i;", dst0, src1);
5339 SET_DREG_L (dst0, v);
5341 else if (sop == 0 && sopcde == 7)
5343 bu16 sv1 = (bu16)signbits (DREG (src1), 32);
5344 bu16 sv0 = (bu16)DREG (src0);
5347 TRACE_INSN (cpu, "R%i.L = EXPADJ (R%i, R%i.L);", dst0, src1, src0);
5349 if ((sv1 & 0x1f) < (sv0 & 0x1f))
5353 STORE (DREG (dst0), REG_H_L (DREG (dst0), dst_lo));
5355 else if (sop == 1 && sopcde == 7)
5357 /* Exponent adjust on two 16-bit inputs. Select
5358 smallest norm among 3 inputs. */
5359 bs16 src1_hi = (DREG (src1) & 0xFFFF0000) >> 16;
5360 bs16 src1_lo = (DREG (src1) & 0xFFFF);
5361 bu16 src0_lo = (DREG (src0) & 0xFFFF);
5362 bu16 tmp_hi, tmp_lo, tmp;
5364 TRACE_INSN (cpu, "R%i.L = EXPADJ (R%i, R%i.L) (V);", dst0, src1, src0);
5366 tmp_hi = signbits (src1_hi, 16);
5367 tmp_lo = signbits (src1_lo, 16);
5369 if ((tmp_hi & 0xf) < (tmp_lo & 0xf))
5370 if ((tmp_hi & 0xf) < (src0_lo & 0xf))
5375 if ((tmp_lo & 0xf) < (src0_lo & 0xf))
5379 STORE (DREG (dst0), REG_H_L (DREG (dst0), tmp));
5381 else if (sop == 2 && sopcde == 7)
5383 /* Exponent adjust on single 16-bit register. */
5385 bu16 src0_lo = (bu16)(DREG (src0) & 0xFFFF);
5387 TRACE_INSN (cpu, "R%i.L = EXPADJ (R%i.L, R%i.L);", dst0, src1, src0);
5389 tmp = signbits (DREG (src1) & 0xFFFF, 16);
5391 if ((tmp & 0xf) < (src0_lo & 0xf))
5392 SET_DREG_L (dst0, tmp);
5394 SET_DREG_L (dst0, src0_lo);
5396 else if (sop == 3 && sopcde == 7)
5399 bu16 src0_lo = (bu16)(DREG (src0) & 0xFFFF);
5401 TRACE_INSN (cpu, "R%i.L = EXPADJ (R%i.H, R%i.L);", dst0, src1, src0);
5403 tmp = signbits ((DREG (src1) & 0xFFFF0000) >> 16, 16);
5405 if ((tmp & 0xf) < (src0_lo & 0xf))
5406 SET_DREG_L (dst0, tmp);
5408 SET_DREG_L (dst0, src0_lo);
5410 else if (sop == 0 && sopcde == 8)
5412 bu64 acc = get_unextended_acc (cpu, 0);
5415 TRACE_INSN (cpu, "BITMUX (R%i, R%i, A0) (ASR);", src0, src1);
5418 illegal_instruction_combination (cpu);
5423 (((bu64)s0 & 1) << 38) |
5424 (((bu64)s1 & 1) << 39);
5425 STORE (DREG (src0), s0 >> 1);
5426 STORE (DREG (src1), s1 >> 1);
5430 else if (sop == 1 && sopcde == 8)
5432 bu64 acc = get_unextended_acc (cpu, 0);
5435 TRACE_INSN (cpu, "BITMUX (R%i, R%i, A0) (ASL);", src0, src1);
5438 illegal_instruction_combination (cpu);
5445 STORE (DREG (src0), s0 << 1);
5446 STORE (DREG (src1), s1 << 1);
5450 else if ((sop == 0 || sop == 1) && sopcde == 9)
5452 bs40 acc0 = get_unextended_acc (cpu, 0);
5455 TRACE_INSN (cpu, "R%i.L = VIT_MAX (R%i) (AS%c);",
5456 dst0, src1, sop & 1 ? 'R' : 'L');
5459 sH = DREG (src1) >> 16;
5462 acc0 = (acc0 & 0xfeffffffffull) >> 1;
5466 if (((sH - sL) & 0x8000) == 0)
5469 acc0 |= (sop & 1) ? 0x80000000 : 1;
5475 SET_DREG (dst0, REG_H_L (DREG (dst0), out));
5477 else if ((sop == 2 || sop == 3) && sopcde == 9)
5479 bs40 acc0 = get_extended_acc (cpu, 0);
5480 bs16 s0L, s0H, s1L, s1H, out0, out1;
5482 TRACE_INSN (cpu, "R%i = VIT_MAX (R%i, R%i) (AS%c);",
5483 dst0, src1, src0, sop & 1 ? 'R' : 'L');
5486 s0H = DREG (src0) >> 16;
5488 s1H = DREG (src1) >> 16;
5495 if (((s0H - s0L) & 0x8000) == 0)
5498 acc0 |= (sop & 1) ? 0x40000000 : 2;
5503 if (((s1H - s1L) & 0x8000) == 0)
5506 acc0 |= (sop & 1) ? 0x80000000 : 1;
5512 SET_DREG (dst0, REG_H_L (out1 << 16, out0));
5514 else if (sop == 0 && sopcde == 10)
5516 bu32 v = DREG (src0);
5517 bu32 x = DREG (src1);
5518 bu32 mask = (1 << (v & 0x1f)) - 1;
5520 TRACE_INSN (cpu, "R%i = EXTRACT (R%i, R%i.L) (Z);", dst0, src1, src0);
5522 x >>= ((v >> 8) & 0x1f);
5524 STORE (DREG (dst0), x);
5525 setflags_logical (cpu, x);
5527 else if (sop == 1 && sopcde == 10)
5529 bu32 v = DREG (src0);
5530 bu32 x = DREG (src1);
5531 bu32 sgn = (1 << (v & 0x1f)) >> 1;
5532 bu32 mask = (1 << (v & 0x1f)) - 1;
5534 TRACE_INSN (cpu, "R%i = EXTRACT (R%i, R%i.L) (X);", dst0, src1, src0);
5536 x >>= ((v >> 8) & 0x1f);
5540 STORE (DREG (dst0), x);
5541 setflags_logical (cpu, x);
5543 else if ((sop == 2 || sop == 3) && sopcde == 10)
5545 /* The first dregs is the "background" while the second dregs is the
5546 "foreground". The fg reg is used to overlay the bg reg and is:
5547 | nnnn nnnn | nnnn nnnn | xxxp pppp | xxxL LLLL |
5548 n = the fg bit field
5549 p = bit position in bg reg to start LSB of fg field
5550 L = number of fg bits to extract
5551 Using (X) sign-extends the fg bit field. */
5552 bu32 fg = DREG (src0);
5553 bu32 bg = DREG (src1);
5554 bu32 len = fg & 0x1f;
5555 bu32 mask = (1 << MIN (16, len)) - 1;
5556 bu32 fgnd = (fg >> 16) & mask;
5557 int shft = ((fg >> 8) & 0x1f);
5559 TRACE_INSN (cpu, "R%i = DEPOSIT (R%i, R%i)%s;", dst0, src1, src0,
5560 sop == 3 ? " (X)" : "");
5564 /* Sign extend the fg bit field. */
5566 fgnd = ((bs32)(bs16)(fgnd << (16 - len))) >> (16 - len);
5573 STORE (DREG (dst0), bg);
5574 setflags_logical (cpu, bg);
5576 else if (sop == 0 && sopcde == 11)
5578 bu64 acc0 = get_unextended_acc (cpu, 0);
5580 TRACE_INSN (cpu, "R%i.L = CC = BXORSHIFT (A0, R%i);", dst0, src0);
5583 SET_CCREG (xor_reduce (acc0, DREG (src0)));
5584 SET_DREG (dst0, REG_H_L (DREG (dst0), CCREG));
5587 else if (sop == 1 && sopcde == 11)
5589 bu64 acc0 = get_unextended_acc (cpu, 0);
5591 TRACE_INSN (cpu, "R%i.L = CC = BXOR (A0, R%i);", dst0, src0);
5593 SET_CCREG (xor_reduce (acc0, DREG (src0)));
5594 SET_DREG (dst0, REG_H_L (DREG (dst0), CCREG));
5596 else if (sop == 0 && sopcde == 12)
5598 bu64 acc0 = get_unextended_acc (cpu, 0);
5599 bu64 acc1 = get_unextended_acc (cpu, 1);
5601 TRACE_INSN (cpu, "A0 = BXORSHIFT (A0, A1, CC);");
5603 acc0 = (acc0 << 1) | (CCREG ^ xor_reduce (acc0, acc1));
5606 else if (sop == 1 && sopcde == 12)
5608 bu64 acc0 = get_unextended_acc (cpu, 0);
5609 bu64 acc1 = get_unextended_acc (cpu, 1);
5611 TRACE_INSN (cpu, "R%i.L = CC = BXOR (A0, A1, CC);", dst0);
5613 SET_CCREG (CCREG ^ xor_reduce (acc0, acc1));
5614 acc0 = (acc0 << 1) | CCREG;
5615 SET_DREG (dst0, REG_H_L (DREG (dst0), CCREG));
5617 else if ((sop == 0 || sop == 1 || sop == 2) && sopcde == 13)
5619 int shift = (sop + 1) * 8;
5620 TRACE_INSN (cpu, "R%i = ALIGN%i (R%i, R%i);", dst0, shift, src1, src0);
5621 STORE (DREG (dst0), (DREG (src1) << (32 - shift)) | (DREG (src0) >> shift));
5624 illegal_instruction (cpu);
5628 decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
5631 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
5632 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
5633 |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
5634 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
5635 int src1 = ((iw1 >> DSP32ShiftImm_src1_bits) & DSP32ShiftImm_src1_mask);
5636 int sop = ((iw1 >> DSP32ShiftImm_sop_bits) & DSP32ShiftImm_sop_mask);
5637 int bit8 = ((iw1 >> 8) & 0x1);
5638 int immag = ((iw1 >> DSP32ShiftImm_immag_bits) & DSP32ShiftImm_immag_mask);
5639 int newimmag = (-(iw1 >> DSP32ShiftImm_immag_bits) & DSP32ShiftImm_immag_mask);
5640 int dst0 = ((iw1 >> DSP32ShiftImm_dst0_bits) & DSP32ShiftImm_dst0_mask);
5641 int M = ((iw0 >> (DSP32ShiftImm_M_bits - 16)) & DSP32ShiftImm_M_mask);
5642 int sopcde = ((iw0 >> (DSP32ShiftImm_sopcde_bits - 16)) & DSP32ShiftImm_sopcde_mask);
5643 int HLs = ((iw1 >> DSP32ShiftImm_HLs_bits) & DSP32ShiftImm_HLs_mask);
5645 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32shiftimm);
5646 TRACE_EXTRACT (cpu, "%s: M:%i sopcde:%i sop:%i HLs:%i dst0:%i immag:%#x src1:%i",
5647 __func__, M, sopcde, sop, HLs, dst0, immag, src1);
5651 bu16 in = DREG (src1) >> ((HLs & 1) ? 16 : 0);
5657 TRACE_INSN (cpu, "R%i.%c = R%i.%c >>> %i;",
5658 dst0, (HLs & 2) ? 'H' : 'L',
5659 src1, (HLs & 1) ? 'H' : 'L', newimmag);
5660 result = ashiftrt (cpu, in, newimmag, 16);
5662 else if (sop == 1 && bit8 == 0)
5664 TRACE_INSN (cpu, "R%i.%c = R%i.%c << %i (S);",
5665 dst0, (HLs & 2) ? 'H' : 'L',
5666 src1, (HLs & 1) ? 'H' : 'L', immag);
5667 result = lshift (cpu, in, immag, 16, 1);
5669 else if (sop == 1 && bit8)
5671 TRACE_INSN (cpu, "R%i.%c = R%i.%c >>> %i (S);",
5672 dst0, (HLs & 2) ? 'H' : 'L',
5673 src1, (HLs & 1) ? 'H' : 'L', immag);
5674 result = lshift (cpu, in, immag, 16, 1);
5676 else if (sop == 2 && bit8)
5678 TRACE_INSN (cpu, "R%i.%c = R%i.%c >> %i;",
5679 dst0, (HLs & 2) ? 'H' : 'L',
5680 src1, (HLs & 1) ? 'H' : 'L', newimmag);
5681 result = lshiftrt (cpu, in, newimmag, 16);
5683 else if (sop == 2 && bit8 == 0)
5685 TRACE_INSN (cpu, "R%i.%c = R%i.%c << %i;",
5686 dst0, (HLs & 2) ? 'H' : 'L',
5687 src1, (HLs & 1) ? 'H' : 'L', immag);
5688 result = lshift (cpu, in, immag, 16, 0);
5691 illegal_instruction (cpu);
5695 STORE (DREG (dst0), (v & 0xFFFF) | (result << 16));
5697 STORE (DREG (dst0), (v & 0xFFFF0000) | result);
5699 else if (sop == 2 && sopcde == 3 && (HLs == 1 || HLs == 0))
5701 int shift = imm6 (immag);
5703 bu40 acc = get_unextended_acc (cpu, HLs);
5705 TRACE_INSN (cpu, "A%i = ROT A%i BY %i;", HLs, HLs, shift);
5706 TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i CC:%i", HLs, acc, shift, cc);
5708 acc = rot40 (acc, shift, &cc);
5709 SET_AREG (HLs, acc);
5713 else if (sop == 0 && sopcde == 3 && bit8 == 1)
5715 /* Arithmetic shift, so shift in sign bit copies. */
5717 int shift = uimm5 (newimmag);
5720 TRACE_INSN (cpu, "A%i = A%i >>> %i;", HLs, HLs, shift);
5722 acc = get_extended_acc (cpu, HLs);
5724 /* Sign extend again. */
5725 if (acc & (1ULL << 39))
5726 acc |= -(1ULL << 39);
5728 acc &= ~(-(1ULL << 39));
5730 STORE (AXREG (HLs), (acc >> 32) & 0xFF);
5731 STORE (AWREG (HLs), acc & 0xFFFFFFFF);
5733 else if ((sop == 0 && sopcde == 3 && bit8 == 0)
5734 || (sop == 1 && sopcde == 3))
5737 int shiftup = uimm5 (immag);
5738 int shiftdn = uimm5 (newimmag);
5741 TRACE_INSN (cpu, "A%i = A%i %s %i;", HLs, HLs,
5742 sop == 0 ? "<<" : ">>",
5743 sop == 0 ? shiftup : shiftdn);
5746 /* Logical shift, so shift in zeroes. */
5756 SET_AREG (HLs, acc);
5757 SET_ASTATREG (an, !!(acc & 0x8000000000ull));
5758 SET_ASTATREG (az, acc == 0);
5760 else if (sop == 1 && sopcde == 1 && bit8 == 0)
5762 int count = imm5 (immag);
5763 bu16 val0 = DREG (src1) >> 16;
5764 bu16 val1 = DREG (src1) & 0xFFFF;
5767 TRACE_INSN (cpu, "R%i = R%i << %i (V,S);", dst0, src1, count);
5768 val0 = lshift (cpu, val0, count, 16, 1);
5770 val1 = lshift (cpu, val1, count, 16, 1);
5771 SET_ASTAT (ASTAT | astat);
5773 STORE (DREG (dst0), (val0 << 16) | val1);
5775 else if (sop == 2 && sopcde == 1 && bit8 == 1)
5777 int count = imm5 (newimmag);
5778 bu16 val0 = DREG (src1) & 0xFFFF;
5779 bu16 val1 = DREG (src1) >> 16;
5782 TRACE_INSN (cpu, "R%i = R%i >> %i (V);", dst0, src1, count);
5783 val0 = lshiftrt (cpu, val0, count, 16);
5785 val1 = lshiftrt (cpu, val1, count, 16);
5786 SET_ASTAT (ASTAT | astat);
5788 STORE (DREG (dst0), val0 | (val1 << 16));
5790 else if (sop == 2 && sopcde == 1 && bit8 == 0)
5792 int count = imm5 (immag);
5793 bu16 val0 = DREG (src1) & 0xFFFF;
5794 bu16 val1 = DREG (src1) >> 16;
5797 TRACE_INSN (cpu, "R%i = R%i << %i (V);", dst0, src1, count);
5798 val0 = lshift (cpu, val0, count, 16, 0);
5800 val1 = lshift (cpu, val1, count, 16, 0);
5801 SET_ASTAT (ASTAT | astat);
5803 STORE (DREG (dst0), val0 | (val1 << 16));
5805 else if (sopcde == 1 && (sop == 0 || (sop == 1 && bit8 == 1)))
5807 int count = uimm5 (newimmag);
5808 bu16 val0 = DREG (src1) & 0xFFFF;
5809 bu16 val1 = DREG (src1) >> 16;
5812 TRACE_INSN (cpu, "R%i = R%i >>> %i %s;", dst0, src1, count,
5813 sop == 0 ? "(V)" : "(V,S)");
5815 val0 = ashiftrt (cpu, val0, count, 16);
5817 val1 = ashiftrt (cpu, val1, count, 16);
5818 SET_ASTAT (ASTAT | astat);
5820 STORE (DREG (dst0), REG_H_L (val1 << 16, val0));
5822 else if (sop == 1 && sopcde == 2)
5824 int count = imm6 (immag);
5826 TRACE_INSN (cpu, "R%i = R%i << %i (S);", dst0, src1, count);
5827 STORE (DREG (dst0), lshift (cpu, DREG (src1), count, 32, 1));
5829 else if (sop == 2 && sopcde == 2)
5831 int count = imm6 (newimmag);
5833 TRACE_INSN (cpu, "R%i = R%i >> %i;", dst0, src1, count);
5836 STORE (DREG (dst0), lshift (cpu, DREG (src1), -count, 32, 0));
5838 STORE (DREG (dst0), lshiftrt (cpu, DREG (src1), count, 32));
5840 else if (sop == 3 && sopcde == 2)
5842 int shift = imm6 (immag);
5843 bu32 src = DREG (src1);
5844 bu32 ret, cc = CCREG;
5846 TRACE_INSN (cpu, "R%i = ROT R%i BY %i;", dst0, src1, shift);
5847 TRACE_DECODE (cpu, "R%i:%#x R%i:%#x shift:%i CC:%i",
5848 dst0, DREG (dst0), src1, src, shift, cc);
5850 ret = rot32 (src, shift, &cc);
5851 STORE (DREG (dst0), ret);
5855 else if (sop == 0 && sopcde == 2)
5857 int count = imm6 (newimmag);
5859 TRACE_INSN (cpu, "R%i = R%i >>> %i;", dst0, src1, count);
5862 STORE (DREG (dst0), lshift (cpu, DREG (src1), -count, 32, 0));
5864 STORE (DREG (dst0), ashiftrt (cpu, DREG (src1), count, 32));
5867 illegal_instruction (cpu);
5871 outc (SIM_CPU *cpu, char ch)
5873 SIM_DESC sd = CPU_STATE (cpu);
5874 sim_io_printf (sd, "%c", ch);
5876 sim_io_flush_stdout (sd);
5880 decode_psedoDEBUG_0 (SIM_CPU *cpu, bu16 iw0)
5883 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
5884 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |.fn....|.grp.......|.reg.......|
5885 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
5886 SIM_DESC sd = CPU_STATE (cpu);
5887 int fn = ((iw0 >> PseudoDbg_fn_bits) & PseudoDbg_fn_mask);
5888 int grp = ((iw0 >> PseudoDbg_grp_bits) & PseudoDbg_grp_mask);
5889 int reg = ((iw0 >> PseudoDbg_reg_bits) & PseudoDbg_reg_mask);
5891 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_psedoDEBUG);
5892 TRACE_EXTRACT (cpu, "%s: fn:%i grp:%i reg:%i", __func__, fn, grp, reg);
5894 if ((reg == 0 || reg == 1) && fn == 3)
5896 TRACE_INSN (cpu, "DBG A%i;", reg);
5897 sim_io_printf (sd, "DBG : A%i = %#"PRIx64"\n", reg,
5898 get_unextended_acc (cpu, reg));
5900 else if (reg == 3 && fn == 3)
5902 TRACE_INSN (cpu, "ABORT;");
5903 cec_exception (cpu, VEC_SIM_ABORT);
5906 else if (reg == 4 && fn == 3)
5908 TRACE_INSN (cpu, "HLT;");
5909 cec_exception (cpu, VEC_SIM_HLT);
5912 else if (reg == 5 && fn == 3)
5913 unhandled_instruction (cpu, "DBGHALT");
5914 else if (reg == 6 && fn == 3)
5915 unhandled_instruction (cpu, "DBGCMPLX (dregs)");
5916 else if (reg == 7 && fn == 3)
5917 unhandled_instruction (cpu, "DBG");
5918 else if (grp == 0 && fn == 2)
5920 TRACE_INSN (cpu, "OUTC R%i;", reg);
5921 outc (cpu, DREG (reg));
5925 const char *reg_name = get_allreg_name (grp, reg);
5926 TRACE_INSN (cpu, "DBG %s;", reg_name);
5927 sim_io_printf (sd, "DBG : %s = 0x%08x\n", reg_name,
5928 reg_read (cpu, grp, reg));
5931 unhandled_instruction (cpu, "PRNT allregs");
5933 illegal_instruction (cpu);
5937 decode_psedoOChar_0 (SIM_CPU *cpu, bu16 iw0)
5940 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
5941 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |.ch............................|
5942 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
5943 int ch = ((iw0 >> PseudoChr_ch_bits) & PseudoChr_ch_mask);
5945 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_psedoOChar);
5946 TRACE_EXTRACT (cpu, "%s: ch:%#x", __func__, ch);
5947 TRACE_INSN (cpu, "OUTC %#x;", ch);
5953 decode_psedodbg_assert_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1, bu32 pc)
5956 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
5957 | 1 | 1 | 1 | 1 | 0 | - | - | - | dbgop |.grp.......|.regtest...|
5958 |.expected......................................................|
5959 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
5960 SIM_DESC sd = CPU_STATE (cpu);
5961 int expected = ((iw1 >> PseudoDbg_Assert_expected_bits) & PseudoDbg_Assert_expected_mask);
5962 int dbgop = ((iw0 >> (PseudoDbg_Assert_dbgop_bits - 16)) & PseudoDbg_Assert_dbgop_mask);
5963 int grp = ((iw0 >> (PseudoDbg_Assert_grp_bits - 16)) & PseudoDbg_Assert_grp_mask);
5964 int regtest = ((iw0 >> (PseudoDbg_Assert_regtest_bits - 16)) & PseudoDbg_Assert_regtest_mask);
5967 bu32 val = reg_read (cpu, grp, regtest);
5968 const char *reg_name = get_allreg_name (grp, regtest);
5969 const char *dbg_name, *dbg_appd;
5971 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_psedodbg_assert);
5972 TRACE_EXTRACT (cpu, "%s: dbgop:%i grp:%i regtest:%i expected:%#x",
5973 __func__, dbgop, grp, regtest, expected);
5975 if (dbgop == 0 || dbgop == 2)
5977 dbg_name = dbgop == 0 ? "DBGA" : "DBGAL";
5978 dbg_appd = dbgop == 0 ? ".L" : "";
5981 else if (dbgop == 1 || dbgop == 3)
5983 dbg_name = dbgop == 1 ? "DBGA" : "DBGAH";
5984 dbg_appd = dbgop == 1 ? ".H" : "";
5988 illegal_instruction (cpu);
5990 actual = val >> offset;
5992 TRACE_INSN (cpu, "%s (%s%s, 0x%x);", dbg_name, reg_name, dbg_appd, expected);
5993 if (actual != expected)
5995 sim_io_printf (sd, "FAIL at %#x: %s (%s%s, 0x%04x); actual value %#x\n",
5996 pc, dbg_name, reg_name, dbg_appd, expected, actual);
5998 /* Decode the actual ASTAT bits that are different. */
5999 if (grp == 4 && regtest == 6)
6003 sim_io_printf (sd, "Expected ASTAT:\n");
6004 for (i = 0; i < 16; ++i)
6005 sim_io_printf (sd, " %8s%c%i%s",
6006 astat_names[i + offset],
6007 (((expected >> i) & 1) != ((actual >> i) & 1))
6009 (expected >> i) & 1,
6010 i == 7 ? "\n" : "");
6011 sim_io_printf (sd, "\n");
6013 sim_io_printf (sd, "Actual ASTAT:\n");
6014 for (i = 0; i < 16; ++i)
6015 sim_io_printf (sd, " %8s%c%i%s",
6016 astat_names[i + offset],
6017 (((expected >> i) & 1) != ((actual >> i) & 1))
6020 i == 7 ? "\n" : "");
6021 sim_io_printf (sd, "\n");
6024 cec_exception (cpu, VEC_SIM_DBGA);
6030 _interp_insn_bfin (SIM_CPU *cpu, bu32 pc)
6035 BFIN_CPU_STATE.multi_pc = pc;
6037 if ((iw0 & 0xc000) != 0xc000)
6039 /* 16-bit opcode. */
6042 INSN_LEN = insn_len;
6044 TRACE_EXTRACT (cpu, "%s: iw0:%#x", __func__, iw0);
6045 if ((iw0 & 0xFF00) == 0x0000)
6046 decode_ProgCtrl_0 (cpu, iw0, pc);
6047 else if ((iw0 & 0xFFC0) == 0x0240)
6048 decode_CaCTRL_0 (cpu, iw0);
6049 else if ((iw0 & 0xFF80) == 0x0100)
6050 decode_PushPopReg_0 (cpu, iw0);
6051 else if ((iw0 & 0xFE00) == 0x0400)
6052 decode_PushPopMultiple_0 (cpu, iw0);
6053 else if ((iw0 & 0xFE00) == 0x0600)
6054 decode_ccMV_0 (cpu, iw0);
6055 else if ((iw0 & 0xF800) == 0x0800)
6056 decode_CCflag_0 (cpu, iw0);
6057 else if ((iw0 & 0xFFE0) == 0x0200)
6058 decode_CC2dreg_0 (cpu, iw0);
6059 else if ((iw0 & 0xFF00) == 0x0300)
6060 decode_CC2stat_0 (cpu, iw0);
6061 else if ((iw0 & 0xF000) == 0x1000)
6062 decode_BRCC_0 (cpu, iw0, pc);
6063 else if ((iw0 & 0xF000) == 0x2000)
6064 decode_UJUMP_0 (cpu, iw0, pc);
6065 else if ((iw0 & 0xF000) == 0x3000)
6066 decode_REGMV_0 (cpu, iw0);
6067 else if ((iw0 & 0xFC00) == 0x4000)
6068 decode_ALU2op_0 (cpu, iw0);
6069 else if ((iw0 & 0xFE00) == 0x4400)
6070 decode_PTR2op_0 (cpu, iw0);
6071 else if ((iw0 & 0xF800) == 0x4800)
6072 decode_LOGI2op_0 (cpu, iw0);
6073 else if ((iw0 & 0xF000) == 0x5000)
6074 decode_COMP3op_0 (cpu, iw0);
6075 else if ((iw0 & 0xF800) == 0x6000)
6076 decode_COMPI2opD_0 (cpu, iw0);
6077 else if ((iw0 & 0xF800) == 0x6800)
6078 decode_COMPI2opP_0 (cpu, iw0);
6079 else if ((iw0 & 0xF000) == 0x8000)
6080 decode_LDSTpmod_0 (cpu, iw0);
6081 else if ((iw0 & 0xFF60) == 0x9E60)
6082 decode_dagMODim_0 (cpu, iw0);
6083 else if ((iw0 & 0xFFF0) == 0x9F60)
6084 decode_dagMODik_0 (cpu, iw0);
6085 else if ((iw0 & 0xFC00) == 0x9C00)
6086 decode_dspLDST_0 (cpu, iw0);
6087 else if ((iw0 & 0xF000) == 0x9000)
6088 decode_LDST_0 (cpu, iw0);
6089 else if ((iw0 & 0xFC00) == 0xB800)
6090 decode_LDSTiiFP_0 (cpu, iw0);
6091 else if ((iw0 & 0xE000) == 0xA000)
6092 decode_LDSTii_0 (cpu, iw0);
6095 TRACE_EXTRACT (cpu, "%s: no matching 16-bit pattern", __func__);
6096 illegal_instruction (cpu);
6101 /* Grab the next 16 bits to determine if it's a 32-bit or 64-bit opcode. */
6102 iw1 = IFETCH (pc + 2);
6103 if ((iw0 & BIT_MULTI_INS) && (iw0 & 0xe800) != 0xe800 /* not linkage */)
6105 SIM_DESC sd = CPU_STATE (cpu);
6106 trace_prefix (sd, cpu, NULL_CIA, pc, TRACE_LINENUM_P (cpu),
6107 NULL, 0, "|| %#"PRIx64, sim_events_time (sd));
6113 TRACE_EXTRACT (cpu, "%s: iw0:%#x iw1:%#x insn_len:%i", __func__,
6114 iw0, iw1, insn_len);
6116 /* Only cache on first run through (in case of parallel insns). */
6118 INSN_LEN = insn_len;
6120 if ((iw0 & 0xf7ff) == 0xc003 && (iw1 & 0xfe00) == 0x1800)
6122 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32mac);
6123 TRACE_INSN (cpu, "MNOP;");
6125 else if (((iw0 & 0xFF80) == 0xE080) && ((iw1 & 0x0C00) == 0x0000))
6126 decode_LoopSetup_0 (cpu, iw0, iw1, pc);
6127 else if (((iw0 & 0xFF00) == 0xE100) && ((iw1 & 0x0000) == 0x0000))
6128 decode_LDIMMhalf_0 (cpu, iw0, iw1);
6129 else if (((iw0 & 0xFE00) == 0xE200) && ((iw1 & 0x0000) == 0x0000))
6130 decode_CALLa_0 (cpu, iw0, iw1, pc);
6131 else if (((iw0 & 0xFC00) == 0xE400) && ((iw1 & 0x0000) == 0x0000))
6132 decode_LDSTidxI_0 (cpu, iw0, iw1);
6133 else if (((iw0 & 0xFFFE) == 0xE800) && ((iw1 & 0x0000) == 0x0000))
6134 decode_linkage_0 (cpu, iw0, iw1);
6135 else if (((iw0 & 0xF600) == 0xC000) && ((iw1 & 0x0000) == 0x0000))
6136 decode_dsp32mac_0 (cpu, iw0, iw1);
6137 else if (((iw0 & 0xF600) == 0xC200) && ((iw1 & 0x0000) == 0x0000))
6138 decode_dsp32mult_0 (cpu, iw0, iw1);
6139 else if (((iw0 & 0xF7C0) == 0xC400) && ((iw1 & 0x0000) == 0x0000))
6140 decode_dsp32alu_0 (cpu, iw0, iw1);
6141 else if (((iw0 & 0xF7E0) == 0xC600) && ((iw1 & 0x01C0) == 0x0000))
6142 decode_dsp32shift_0 (cpu, iw0, iw1);
6143 else if (((iw0 & 0xF7E0) == 0xC680) && ((iw1 & 0x0000) == 0x0000))
6144 decode_dsp32shiftimm_0 (cpu, iw0, iw1);
6145 else if ((iw0 & 0xFF00) == 0xF800)
6146 decode_psedoDEBUG_0 (cpu, iw0), insn_len = 2;
6147 else if ((iw0 & 0xFF00) == 0xF900)
6148 decode_psedoOChar_0 (cpu, iw0), insn_len = 2;
6149 else if (((iw0 & 0xFF00) == 0xF000) && ((iw1 & 0x0000) == 0x0000))
6150 decode_psedodbg_assert_0 (cpu, iw0, iw1, pc);
6153 TRACE_EXTRACT (cpu, "%s: no matching 32-bit pattern", __func__);
6154 illegal_instruction (cpu);
6161 interp_insn_bfin (SIM_CPU *cpu, bu32 pc)
6166 BFIN_CPU_STATE.n_stores = 0;
6167 DIS_ALGN_EXPT &= ~1;
6171 insn_len = _interp_insn_bfin (cpu, pc);
6173 /* Proper display of multiple issue instructions. */
6176 _interp_insn_bfin (cpu, pc + 4);
6177 _interp_insn_bfin (cpu, pc + 6);
6179 for (i = 0; i < BFIN_CPU_STATE.n_stores; i++)
6181 bu32 *addr = BFIN_CPU_STATE.stores[i].addr;
6182 *addr = BFIN_CPU_STATE.stores[i].val;
6183 TRACE_REGISTER (cpu, "dequeuing write %s = %#x",
6184 get_store_name (cpu, addr), *addr);
6187 cycles_inc (cpu, CYCLE_DELAY);
6189 /* Set back to zero in case a pending CEC event occurs
6190 after this this insn. */