xref: /netbsd-src/external/gpl3/gdb.old/dist/sim/m32c/r8c.opc (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1bb16d227Schristos/* r8c.opc --- semantics for r8c opcodes.		        -*- mode: c -*-
2bb16d227Schristos
3*8b657b07SchristosCopyright (C) 2005-2023 Free Software Foundation, Inc.
4bb16d227SchristosContributed by Red Hat, Inc.
5bb16d227Schristos
6bb16d227SchristosThis file is part of the GNU simulators.
7bb16d227Schristos
8bb16d227SchristosThis program is free software; you can redistribute it and/or modify
9bb16d227Schristosit under the terms of the GNU General Public License as published by
10bb16d227Schristosthe Free Software Foundation; either version 3 of the License, or
11bb16d227Schristos(at your option) any later version.
12bb16d227Schristos
13bb16d227SchristosThis program is distributed in the hope that it will be useful,
14bb16d227Schristosbut WITHOUT ANY WARRANTY; without even the implied warranty of
15bb16d227SchristosMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16bb16d227SchristosGNU General Public License for more details.
17bb16d227Schristos
18bb16d227SchristosYou should have received a copy of the GNU General Public License
19bb16d227Schristosalong with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20bb16d227Schristos
21*8b657b07Schristos/* This must come before any other includes.  */
22*8b657b07Schristos#include "defs.h"
23bb16d227Schristos
24bb16d227Schristos#include <stdio.h>
25bb16d227Schristos#include <stdlib.h>
26bb16d227Schristos
27*8b657b07Schristos#include "ansidecl.h"
28bb16d227Schristos#include "cpu.h"
29bb16d227Schristos#include "mem.h"
30bb16d227Schristos#include "misc.h"
31bb16d227Schristos#include "int.h"
32bb16d227Schristos
33bb16d227Schristos#define tprintf if (trace) printf
34bb16d227Schristos
35bb16d227Schristosstatic unsigned char
36bb16d227Schristosgetbyte (void)
37bb16d227Schristos{
38bb16d227Schristos  int tsave = trace;
39bb16d227Schristos  unsigned char b;
40bb16d227Schristos
41bb16d227Schristos  if (trace == 1)
42bb16d227Schristos    trace = 0;
43bb16d227Schristos  b = mem_get_pc ();
44bb16d227Schristos  regs.r_pc ++;
45bb16d227Schristos  trace = tsave;
46bb16d227Schristos  return b;
47bb16d227Schristos}
48bb16d227Schristos
49bb16d227Schristos#define M16C_ONLY() /* FIXME: add something here */
50bb16d227Schristos
51bb16d227Schristos#define GETBYTE() (op[opi++] = getbyte())
52bb16d227Schristos
53bb16d227Schristos#define UNSUPPORTED() unsupported("unsupported", orig_pc)
54bb16d227Schristos#define NOTYET() unsupported("unimplemented", orig_pc)
55bb16d227Schristos
56bb16d227Schristosstatic void
57bb16d227Schristosunsupported (char *tag, int orig_pc)
58bb16d227Schristos{
59bb16d227Schristos  int i;
60bb16d227Schristos  printf("%s opcode at %08x\n", tag, orig_pc);
61bb16d227Schristos  regs.r_pc = orig_pc;
62bb16d227Schristos  for (i=0; i<2; i++)
63bb16d227Schristos    {
64bb16d227Schristos      int b = mem_get_pc();
65bb16d227Schristos      printf(" %s", bits(b>>4, 4));
66bb16d227Schristos      printf(" %s", bits(b, 4));
67bb16d227Schristos      regs.r_pc ++;
68bb16d227Schristos    }
69bb16d227Schristos  printf("\n");
70bb16d227Schristos  regs.r_pc = orig_pc;
71bb16d227Schristos  for (i=0; i<6; i++)
72bb16d227Schristos    {
73bb16d227Schristos      printf(" %02x", mem_get_pc ());
74bb16d227Schristos      regs.r_pc ++;
75bb16d227Schristos    }
76bb16d227Schristos  printf("\n");
77bb16d227Schristos  exit(1);
78bb16d227Schristos}
79bb16d227Schristos
80bb16d227Schristosstatic int
81bb16d227SchristosIMM (int bw)
82bb16d227Schristos{
83bb16d227Schristos  int rv = getbyte ();
84bb16d227Schristos  if (bw)
85bb16d227Schristos    rv = rv + 256 * getbyte();
86bb16d227Schristos  if (bw == 2)
87bb16d227Schristos    rv = rv + 65536 * getbyte();
88bb16d227Schristos  return rv;
89bb16d227Schristos}
90bb16d227Schristos
91bb16d227Schristos#define IMM4() (immm >= 8 ? 7 - immm : immm + 1)
92bb16d227Schristos
93bb16d227Schristos#define UNARY_SOP \
94bb16d227Schristos  dc = decode_srcdest4 (dest, w); \
95bb16d227Schristos  v = sign_ext (get_src (dc), w?16:8);
96bb16d227Schristos
97bb16d227Schristos#define UNARY_UOP \
98bb16d227Schristos  dc = decode_srcdest4 (dest, w); \
99bb16d227Schristos  v = get_src (dc);
100bb16d227Schristos
101bb16d227Schristos#define BINARY_SOP \
102bb16d227Schristos  sc = decode_srcdest4 (srcx, w); \
103bb16d227Schristos  dc = decode_srcdest4 (dest, w); \
104bb16d227Schristos  a = sign_ext (get_src (sc), w?16:8); \
105bb16d227Schristos  b = sign_ext (get_src (dc), w?16:8);
106bb16d227Schristos
107bb16d227Schristos#define BINARY_UOP \
108bb16d227Schristos  sc = decode_srcdest4 (srcx, w); \
109bb16d227Schristos  dc = decode_srcdest4 (dest, w); \
110bb16d227Schristos  a = get_src (sc); \
111bb16d227Schristos  b = get_src (dc);
112bb16d227Schristos
113bb16d227Schristos#define carry (FLAG_C ? 1 : 0)
114bb16d227Schristos
115bb16d227Schristosstatic void
116bb16d227Schristoscmp (int d, int s, int w)
117bb16d227Schristos{
118bb16d227Schristos  int a, b, f=0;
119bb16d227Schristos  int mask = w ? 0xffff : 0xff;
120bb16d227Schristos  a = d - s;
121bb16d227Schristos  b = sign_ext (d, w?16:8) - sign_ext (s, w?16:8);
122bb16d227Schristos  tprintf ("cmp: %x - %x = %08x, %x - %x = %d\n",
123bb16d227Schristos	   d, s, a,
124bb16d227Schristos	   sign_ext(d,w?16:8), sign_ext(s,w?16:8), b);
125bb16d227Schristos
126bb16d227Schristos  if (b == 0)
127bb16d227Schristos    f |= FLAGBIT_Z;
128bb16d227Schristos  if (b & (w ? 0x8000 : 0x80))
129bb16d227Schristos    f |= FLAGBIT_S;
130bb16d227Schristos  if ((d & mask) >= (s & mask))
131bb16d227Schristos    f |= FLAGBIT_C;
132bb16d227Schristos  if (b < (w ? -32768 : -128) || b > (w ? 32767 : 127))
133bb16d227Schristos    f |= FLAGBIT_O;
134bb16d227Schristos
135bb16d227Schristos  set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O | FLAGBIT_C, f);
136bb16d227Schristos}
137bb16d227Schristos
138bb16d227Schristosstatic void
139bb16d227Schristosdiv_op (int s, int u, int x, int w)
140bb16d227Schristos{
141bb16d227Schristos  srcdest sc;
142bb16d227Schristos  int v, a, b;
143bb16d227Schristos
144bb16d227Schristos  if (s == -1)
145bb16d227Schristos    s = IMM(w);
146bb16d227Schristos  else
147bb16d227Schristos    {
148bb16d227Schristos      sc = decode_srcdest4 (s, w);
149bb16d227Schristos      s = get_src (sc);
150bb16d227Schristos    }
151bb16d227Schristos
152bb16d227Schristos  v = get_reg (w ? r2r0 : r0);
153bb16d227Schristos
154bb16d227Schristos  if (!u)
155bb16d227Schristos    {
156bb16d227Schristos      s = sign_ext (s, w ? 16 : 8);
157bb16d227Schristos      v = sign_ext (v, w ? 16 : 8);
158bb16d227Schristos    }
159bb16d227Schristos
160bb16d227Schristos  if (s == 0)
161bb16d227Schristos    {
162bb16d227Schristos      set_flags (FLAGBIT_O, FLAGBIT_O);
163bb16d227Schristos      return;
164bb16d227Schristos    }
165bb16d227Schristos
166bb16d227Schristos  if (u)
167bb16d227Schristos    {
168bb16d227Schristos      a = (unsigned int)v / (unsigned int)s;
169bb16d227Schristos      b = (unsigned int)v % (unsigned int)s;
170bb16d227Schristos    }
171bb16d227Schristos  else
172bb16d227Schristos    {
173bb16d227Schristos      a = v / s;
174bb16d227Schristos      b = v % s;
175bb16d227Schristos    }
176bb16d227Schristos  if (x)
177bb16d227Schristos    {
178bb16d227Schristos      if ((s > 0 && b < 0)
179bb16d227Schristos	  || (s < 0 && b > 0))
180bb16d227Schristos	{
181bb16d227Schristos	  a --;
182bb16d227Schristos	  b += s;
183bb16d227Schristos	}
184bb16d227Schristos    }
185bb16d227Schristos  tprintf ("%d / %d = %d rem %d\n", v, s, a, b);
186bb16d227Schristos  if ((!u && (a > (w ? 32767 : 127)
187bb16d227Schristos	     || a < (w ? -32768 : -129)))
188bb16d227Schristos      || (u && (a > (w ? 65536 : 255))))
189bb16d227Schristos    set_flags (FLAGBIT_O, FLAGBIT_O);
190bb16d227Schristos  else
191bb16d227Schristos    set_flags (FLAGBIT_O, 0);
192bb16d227Schristos
193bb16d227Schristos  put_reg (w ? r0 : r0l, a);
194bb16d227Schristos  put_reg (w ? r2 : r0h, b);
195bb16d227Schristos}
196bb16d227Schristos
197bb16d227Schristosstatic void
198bb16d227Schristosrot_op (srcdest sd, int rotc, int count)
199bb16d227Schristos{
200bb16d227Schristos  int mask = (sd.bytes == 2) ? 0xffff : 0xff;
201bb16d227Schristos  int msb = (sd.bytes == 2) ? 0x8000 : 0x80;
202bb16d227Schristos  int v = get_src (sd);
203bb16d227Schristos  int c = carry, ct;
204bb16d227Schristos
205bb16d227Schristos  tprintf("%s %x by %d\n", rotc ? "rotc" : "rot", v, count);
206bb16d227Schristos  tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
207bb16d227Schristos  while (count > 0)
208bb16d227Schristos    {
209bb16d227Schristos      ct = (v & msb) ? 1 : 0;
210bb16d227Schristos      v <<= 1;
211bb16d227Schristos      v |= rotc ? c : ct;
212bb16d227Schristos      v &= mask;
213bb16d227Schristos      c = ct;
214bb16d227Schristos      tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
215bb16d227Schristos      count --;
216bb16d227Schristos    }
217bb16d227Schristos  while (count < 0)
218bb16d227Schristos    {
219bb16d227Schristos      ct = v & 1;
220bb16d227Schristos      v >>= 1;
221bb16d227Schristos      v |= (rotc ? c : ct) * msb;
222bb16d227Schristos      c = ct;
223bb16d227Schristos      tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
224bb16d227Schristos      count ++;
225bb16d227Schristos    }
226bb16d227Schristos  put_dest (sd, v);
227bb16d227Schristos  set_szc (v, sd.bytes, c);
228bb16d227Schristos}
229bb16d227Schristos
230bb16d227Schristosstatic void
231bb16d227Schristosshift_op (srcdest sd, int arith, int count)
232bb16d227Schristos{
233bb16d227Schristos  int mask = (sd.bytes == 2) ? 0xffff : 0xff;
234bb16d227Schristos  int msb = (sd.bytes == 2) ? 0x8000 : 0x80;
235bb16d227Schristos  int v = get_src (sd);
236bb16d227Schristos  int c = 0;
237bb16d227Schristos
238bb16d227Schristos  if (sd.bytes == 4)
239bb16d227Schristos    {
240bb16d227Schristos      mask = 0xffffffffU;
241bb16d227Schristos      msb = 0x80000000U;
242bb16d227Schristos      if (count > 16 || count < -16)
243bb16d227Schristos	{
244bb16d227Schristos	  fprintf(stderr, "Error: SI shift of %d undefined\n", count);
245bb16d227Schristos	  exit(1);
246bb16d227Schristos	}
247bb16d227Schristos      if (count > 16)
248bb16d227Schristos	count = (count - 1) % 16 + 1;
249bb16d227Schristos      if (count < -16)
250bb16d227Schristos	count = -((-count - 1) % 16 + 1);
251bb16d227Schristos    }
252bb16d227Schristos
253bb16d227Schristos  tprintf("%s %x by %d\n", arith ? "sha" : "shl", v, count);
254bb16d227Schristos  tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
255bb16d227Schristos  while (count > 0)
256bb16d227Schristos    {
257bb16d227Schristos      c = (v & msb) ? 1 : 0;
258bb16d227Schristos      v <<= 1;
259bb16d227Schristos      v &= mask;
260bb16d227Schristos      tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
261bb16d227Schristos      count --;
262bb16d227Schristos    }
263bb16d227Schristos  while (count < 0)
264bb16d227Schristos    {
265bb16d227Schristos      c = v & 1;
266bb16d227Schristos      if (arith)
267bb16d227Schristos	v = (v & msb) | (v >> 1);
268bb16d227Schristos      else
269bb16d227Schristos	v = (v >> 1) & (msb - 1);
270bb16d227Schristos      tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
271bb16d227Schristos      count ++;
272bb16d227Schristos    }
273bb16d227Schristos  put_dest (sd, v);
274bb16d227Schristos  set_szc (v, sd.bytes, c);
275bb16d227Schristos}
276bb16d227Schristos
277bb16d227Schristos#define MATH_OP(dc,s,c,op,carryrel) \
278bb16d227Schristos  a = get_src(dc); \
279bb16d227Schristos  b = s & b2mask[dc.bytes]; \
280bb16d227Schristos  v2 = a op b op c; \
281bb16d227Schristos  tprintf("0x%x " #op " 0x%x " #op " 0x%x = 0x%x\n", a, b, c, v2); \
282bb16d227Schristos  a = sign_ext (a, dc.bytes * 8); \
283bb16d227Schristos  b = sign_ext (s, dc.bytes * 8); \
284bb16d227Schristos  v = a op b op c; \
285bb16d227Schristos  tprintf("%d " #op " %d " #op " %d = %d\n", a, b, c, v); \
286bb16d227Schristos  set_oszc (v, dc.bytes, v2 carryrel); \
287bb16d227Schristos  put_dest (dc, v2);
288bb16d227Schristos
289bb16d227Schristos#define BIT_OP(field,expr) \
290bb16d227Schristos  dc = decode_bit (field); \
291bb16d227Schristos  b = get_bit (dc); \
292bb16d227Schristos  v = expr; \
293bb16d227Schristos  tprintf ("b=%d, carry=%d, %s = %d\n", b, carry, #expr, v); \
294bb16d227Schristos  put_bit (dc, v);
295bb16d227Schristos
296bb16d227Schristos#define BIT_OPC(field,expr) \
297bb16d227Schristos  dc = decode_bit (field); \
298bb16d227Schristos  b = get_bit (dc); \
299bb16d227Schristos  v = expr; \
300bb16d227Schristos  tprintf ("b=%d, carry=%d, %s = %d\n", b, carry, #expr, v); \
301bb16d227Schristos  set_c (v);
302bb16d227Schristos
303bb16d227Schristos/* The "BMcnd dest" opcode uses a different encoding for the */
304bb16d227Schristos/* condition than other opcodes.  */
305bb16d227Schristosstatic int bmcnd_cond_map[] = {
306bb16d227Schristos  0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15
307bb16d227Schristos};
308bb16d227Schristos
309bb16d227Schristosint
310bb16d227Schristosdecode_r8c (void)
311bb16d227Schristos{
312bb16d227Schristos  unsigned char op[40];
313bb16d227Schristos  int opi = 0;
314bb16d227Schristos  int v, v2, a, b;
315bb16d227Schristos  int orig_pc = get_reg (pc);
316bb16d227Schristos  srcdest sc, dc;
317bb16d227Schristos  int imm;
318bb16d227Schristos
319bb16d227Schristos  step_result = M32C_MAKE_STEPPED ();
320bb16d227Schristos
321bb16d227Schristos  tprintf("trace: decode pc = %05x\n", orig_pc);
322bb16d227Schristos
323bb16d227Schristos  /** VARY dst 011 100 101 110 111 */
324bb16d227Schristos
325bb16d227Schristos  /** 0111 011w 1111 dest  ABS.size dest */
326bb16d227Schristos
327bb16d227Schristos  UNARY_SOP;
328bb16d227Schristos  a = v<0 ? -v : v;
329bb16d227Schristos  tprintf("abs(%d) = %d\n", v, a);
330bb16d227Schristos  set_osz(a, w+1);
331bb16d227Schristos  put_dest (dc, a);
332bb16d227Schristos
333bb16d227Schristos  /** 0111 011w 0110 dest  ADC.size #IMM,dest */
334bb16d227Schristos
335bb16d227Schristos  dc = decode_srcdest4(dest, w);
336bb16d227Schristos  imm = IMM(w);
337bb16d227Schristos  MATH_OP (dc, imm, carry, +, > (w?0xffff:0xff));
338bb16d227Schristos
339bb16d227Schristos  /** 1011 000w srcx dest  ADC.size src,dest */
340bb16d227Schristos
341bb16d227Schristos  sc = decode_srcdest4(srcx, w);
342bb16d227Schristos  dc = decode_srcdest4(dest, w);
343bb16d227Schristos  b = get_src (sc);
344bb16d227Schristos  MATH_OP (dc, b, carry, +, > (w?0xffff:0xff));
345bb16d227Schristos
346bb16d227Schristos  /** 0111 011w 1110 dest  ADCF.size dest */
347bb16d227Schristos
348bb16d227Schristos  dc = decode_srcdest4(dest, w);
349bb16d227Schristos  MATH_OP (dc, 0, carry, +, > (w?0xffff:0xff));
350bb16d227Schristos
351bb16d227Schristos  /** 0111 011w 0100 dest  ADD.size:G #imm,dest */
352bb16d227Schristos
353bb16d227Schristos  dc = decode_srcdest4(dest, w);
354bb16d227Schristos  imm = IMM(w);
355bb16d227Schristos  MATH_OP (dc, imm, 0, +, > (w?0xffff:0xff));
356bb16d227Schristos
357bb16d227Schristos  /** 1100 100w immm dest  ADD.size:Q #IMM,dest */
358bb16d227Schristos
359bb16d227Schristos  dc = decode_srcdest4(dest, w);
360bb16d227Schristos  imm = sign_ext (immm, 4);
361bb16d227Schristos  MATH_OP (dc, imm, 0, +, > (w?0xffff:0xff));
362bb16d227Schristos
363bb16d227Schristos  /** 1000 0dst            ADD.B:S #IMM8,dst */
364bb16d227Schristos
365bb16d227Schristos  imm = IMM(0);
366bb16d227Schristos  dc = decode_dest3 (dst, 0);
367bb16d227Schristos  MATH_OP (dc, imm, 0, +, > 0xff);
368bb16d227Schristos
369bb16d227Schristos  /** 1010 000w srcx dest  ADD.size:G src,dest */
370bb16d227Schristos
371bb16d227Schristos  sc = decode_srcdest4(srcx, w);
372bb16d227Schristos  dc = decode_srcdest4(dest, w);
373bb16d227Schristos  b = get_src (sc);
374bb16d227Schristos  MATH_OP (dc, b, 0, +, > (w?0xffff:0xff));
375bb16d227Schristos
376bb16d227Schristos  /** 0010 0d sr           ADD.B:S src,R0L/R0H */
377bb16d227Schristos
378bb16d227Schristos  sc = decode_src2 (sr, 0, d);
379bb16d227Schristos  dc = decode_dest1 (d, 0);
380bb16d227Schristos  b = get_src (sc);
381bb16d227Schristos  MATH_OP (dc, b, 0, +, > 0xff);
382bb16d227Schristos
383bb16d227Schristos  /** 0111 110w 1110 1011  ADD.size:G #IMM,sp */
384bb16d227Schristos
385bb16d227Schristos  dc = reg_sd (sp);
386bb16d227Schristos  imm = sign_ext (IMM(w), w?16:8);
387bb16d227Schristos  MATH_OP (dc, imm, 0, +, > 0xffff);
388bb16d227Schristos
389bb16d227Schristos  /** 0111 1101 1011 immm  ADD.size:Q #IMM,sp */
390bb16d227Schristos
391bb16d227Schristos  dc = reg_sd (sp);
392bb16d227Schristos  imm = sign_ext (immm, 4);
393bb16d227Schristos  MATH_OP (dc, imm, 0, +, > 0xffff);
394bb16d227Schristos
395bb16d227Schristos  /** 1111 100w immm dest  ADJNZ.size #IMM,dest,label */
396bb16d227Schristos
397bb16d227Schristos  UNARY_UOP;
398bb16d227Schristos  imm = sign_ext(immm, 4);
399bb16d227Schristos  tprintf("%x + %d = %x\n", v, imm, v+imm);
400bb16d227Schristos  v += imm;
401bb16d227Schristos  put_dest (dc, v);
402bb16d227Schristos  a = sign_ext (IMM(0), 8);
403bb16d227Schristos  if ((v & (w ? 0xffff : 0xff)) != 0)
404bb16d227Schristos    {
405bb16d227Schristos      tprintf("jmp: %x + 2 + %d = ", get_reg (pc), a);
406bb16d227Schristos      put_reg (pc, orig_pc + 2 + a);
407bb16d227Schristos      tprintf("%x\n", get_reg (pc));
408bb16d227Schristos    }
409bb16d227Schristos
410bb16d227Schristos  /** 0111 011w 0010 dest  AND.size:G #IMM,dest */
411bb16d227Schristos
412bb16d227Schristos  UNARY_UOP;
413bb16d227Schristos  imm = IMM(w);
414bb16d227Schristos  tprintf ("%x & %x = %x\n", v, imm, v & imm);
415bb16d227Schristos  v &= imm;
416bb16d227Schristos  set_sz (v, w+1);
417bb16d227Schristos  put_dest (dc, v);
418bb16d227Schristos
419bb16d227Schristos  /** 1001 0dst            AND.B:S #IMM8,dest */
420bb16d227Schristos
421bb16d227Schristos  imm = IMM(0);
422bb16d227Schristos  dc = decode_dest3 (dst, 0);
423bb16d227Schristos  v = get_src (dc);
424bb16d227Schristos  tprintf("%x & %x = %x\n", v, imm, v & imm);
425bb16d227Schristos  v &= imm;
426bb16d227Schristos  set_sz (v, 1);
427bb16d227Schristos  put_dest (dc, v);
428bb16d227Schristos
429bb16d227Schristos  /** 1001 000w srcx dest  AND.size:G src.dest */
430bb16d227Schristos
431bb16d227Schristos  BINARY_UOP;
432bb16d227Schristos  tprintf ("%x & %x = %x\n", a, b, a & b);
433bb16d227Schristos  v = a & b;
434bb16d227Schristos  set_sz (v, w+1);
435bb16d227Schristos  put_dest (dc, v);
436bb16d227Schristos
437bb16d227Schristos  /** 0001 0d sr           AND.B:S src,R0L/R0H */
438bb16d227Schristos
439bb16d227Schristos  sc = decode_src2 (sr, 0, d);
440bb16d227Schristos  dc = decode_dest1 (d, 0);
441bb16d227Schristos  a = get_src (sc);
442bb16d227Schristos  b = get_src (dc);
443bb16d227Schristos  v = a & b;
444bb16d227Schristos  tprintf("%x & %x = %x\n", a, b, v);
445bb16d227Schristos  set_sz (v, 1);
446bb16d227Schristos  put_dest (dc, v);
447bb16d227Schristos
448bb16d227Schristos  /** 0111 1110 0100 srcx  BAND src */
449bb16d227Schristos
450bb16d227Schristos  BIT_OPC (srcx, b & carry);
451bb16d227Schristos
452bb16d227Schristos  /** 0111 1110 1000 dest  BCLR:G dest */
453bb16d227Schristos
454bb16d227Schristos  dc = decode_bit (dest);
455bb16d227Schristos  put_bit (dc, 0);
456bb16d227Schristos
457bb16d227Schristos  /** 0100 0bit            BCLR:S bit,base:11[SB] */
458bb16d227Schristos
459bb16d227Schristos  dc = decode_bit11 (bit);
460bb16d227Schristos  put_bit (dc, 0);
461bb16d227Schristos
462bb16d227Schristos  /** 0111 1110 0010 dest  BMcnd dest  */
463bb16d227Schristos
464bb16d227Schristos  dc = decode_bit (dest);
465bb16d227Schristos  if (condition_true (bmcnd_cond_map [IMM (0) & 15]))
466bb16d227Schristos    put_bit (dc, 1);
467bb16d227Schristos  else
468bb16d227Schristos    put_bit (dc, 0);
469bb16d227Schristos
470bb16d227Schristos  /** 0111 1101 1101 cond  BMcnd C  */
471bb16d227Schristos
472bb16d227Schristos  if (condition_true (cond))
473bb16d227Schristos    set_c (1);
474bb16d227Schristos  else
475bb16d227Schristos    set_c (0);
476bb16d227Schristos
477bb16d227Schristos  /** 0111 1110 0101 srcx  BNAND src */
478bb16d227Schristos
479bb16d227Schristos  BIT_OPC (srcx, (!b) & carry);
480bb16d227Schristos
481bb16d227Schristos  /** 0111 1110 0111 srcx  BNOR src */
482bb16d227Schristos
483bb16d227Schristos  BIT_OPC (srcx, (!b) | carry);
484bb16d227Schristos
485bb16d227Schristos  /** 0111 1110 1010 dest  BNOT:G dest */
486bb16d227Schristos
487bb16d227Schristos  BIT_OP (dest, !b);
488bb16d227Schristos
489bb16d227Schristos  /** 0101 0bit            BNOT:S bit,base:11[SB] */
490bb16d227Schristos
491bb16d227Schristos  dc = decode_bit11 (bit);
492bb16d227Schristos  put_bit (dc, !get_bit (dc));
493bb16d227Schristos
494bb16d227Schristos  /** 0111 1110 0011 srcx  BNTST src */
495bb16d227Schristos
496bb16d227Schristos  dc = decode_bit (srcx);
497bb16d227Schristos  b = get_bit (dc);
498bb16d227Schristos  set_zc (!b, !b);
499bb16d227Schristos
500bb16d227Schristos  /** 0111 1110 1101 srcx  BNXOR src */
501bb16d227Schristos
502bb16d227Schristos  BIT_OPC (srcx, !b ^ carry);
503bb16d227Schristos
504bb16d227Schristos  /** 0111 1110 0110 srcx  BOR src */
505bb16d227Schristos
506bb16d227Schristos  BIT_OPC (srcx, b | carry);
507bb16d227Schristos
508bb16d227Schristos  /** 0000 0000            BRK */
509bb16d227Schristos
510bb16d227Schristos  /* We report the break to our caller with the PC still pointing at the
511bb16d227Schristos     breakpoint instruction.  */
512bb16d227Schristos  put_reg (pc, orig_pc);
513bb16d227Schristos  if (verbose)
514bb16d227Schristos    printf("[break]\n");
515bb16d227Schristos  return M32C_MAKE_HIT_BREAK ();
516bb16d227Schristos
517bb16d227Schristos  /** 0111 1110 1001 dest  BSET:G dest */
518bb16d227Schristos
519bb16d227Schristos  dc = decode_bit (dest);
520bb16d227Schristos  put_bit (dc, 1);
521bb16d227Schristos
522bb16d227Schristos  /** 0100 1bit            BSET:S bit,base:11[SB] */
523bb16d227Schristos
524bb16d227Schristos  dc = decode_bit11 (bit);
525bb16d227Schristos  put_bit (dc, 1);
526bb16d227Schristos
527bb16d227Schristos  /** 0111 1110 1011 srcx  BTST:G src */
528bb16d227Schristos
529bb16d227Schristos  dc = decode_bit (srcx);
530bb16d227Schristos  b = get_bit (dc);
531bb16d227Schristos  set_zc (!b, b);
532bb16d227Schristos
533bb16d227Schristos  /** 0101 1bit            BTST:S bit,base:11[SB] */
534bb16d227Schristos
535bb16d227Schristos  dc = decode_bit11 (bit);
536bb16d227Schristos  b = get_bit (dc);
537bb16d227Schristos  set_zc (!b, b);
538bb16d227Schristos
539bb16d227Schristos  /** 0111 1110 0000 dest  BTSTC dest */
540bb16d227Schristos
541bb16d227Schristos  dc = decode_bit (dest);
542bb16d227Schristos  b = get_bit (dc);
543bb16d227Schristos  set_zc (!b, b);
544bb16d227Schristos  put_bit (dc, 0);
545bb16d227Schristos
546bb16d227Schristos  /** 0111 1110 0001 dest  BTSTS dest */
547bb16d227Schristos
548bb16d227Schristos  dc = decode_bit (dest);
549bb16d227Schristos  b = get_bit (dc);
550bb16d227Schristos  set_zc (!b, b);
551bb16d227Schristos  put_bit (dc, 1);
552bb16d227Schristos
553bb16d227Schristos  /** 0111 1110 1100 srcx  BXOR src */
554bb16d227Schristos
555bb16d227Schristos  BIT_OPC (srcx, b ^ carry);
556bb16d227Schristos
557bb16d227Schristos  /** 0111 011w 1000 dest  CMP.size:G #IMM,dest */
558bb16d227Schristos
559bb16d227Schristos  UNARY_UOP;
560bb16d227Schristos  imm = IMM(w);
561bb16d227Schristos  cmp (v, imm, w);
562bb16d227Schristos
563bb16d227Schristos  /** 1101 000w immm dest  CMP.size:Q #IMM,dest */
564bb16d227Schristos
565bb16d227Schristos  UNARY_UOP;
566bb16d227Schristos  immm = sign_ext (immm, 4);
567bb16d227Schristos  cmp (v, immm, w);
568bb16d227Schristos
569bb16d227Schristos  /** 1110 0dst            CMP.B:S #IMM8,dest */
570bb16d227Schristos
571bb16d227Schristos  imm = IMM(0);
572bb16d227Schristos  dc = decode_dest3 (dst, 0);
573bb16d227Schristos  v = get_src (dc);
574bb16d227Schristos  cmp (v, imm, 0);
575bb16d227Schristos
576bb16d227Schristos  /** 1100 000w srcx dest  CMP.size:G src,dest */
577bb16d227Schristos
578bb16d227Schristos  BINARY_UOP;
579bb16d227Schristos  cmp(b, a, w);
580bb16d227Schristos
581bb16d227Schristos  /** 0011 1d sr           CMP.B:S src,R0L/R0H */
582bb16d227Schristos
583bb16d227Schristos  sc = decode_src2 (sr, 0, d);
584bb16d227Schristos  dc = decode_dest1 (d, 0);
585bb16d227Schristos  a = get_src (sc);
586bb16d227Schristos  b = get_src (dc);
587bb16d227Schristos  cmp (b, a, 0);
588bb16d227Schristos
589bb16d227Schristos  /** 0111 110w 1110 i1c s  DADC,DADD,DSBB,DSUB */
590bb16d227Schristos
591bb16d227Schristos  /* w = width, i = immediate, c = carry, s = subtract */
592bb16d227Schristos
593*8b657b07Schristos  {
594bb16d227Schristos  int src = i ? IMM(w) : get_reg (w ? r1 : r0h);
595bb16d227Schristos  int dest = get_reg (w ? r0 : r0l);
596bb16d227Schristos  int res;
597bb16d227Schristos
598bb16d227Schristos  src = bcd2int(src, w);
599bb16d227Schristos  dest = bcd2int(dest, w);
600bb16d227Schristos
601bb16d227Schristos  tprintf("decimal: %d %s %d", dest, s?"-":"+", src);
602bb16d227Schristos  if (c)
603bb16d227Schristos    tprintf(" c=%d", carry);
604bb16d227Schristos
605bb16d227Schristos  if (!s)
606bb16d227Schristos    {
607bb16d227Schristos      res = dest + src;
608bb16d227Schristos      if (c)
609bb16d227Schristos	res += carry;
610bb16d227Schristos      c = res > (w ? 9999 : 99);
611bb16d227Schristos    }
612bb16d227Schristos  else
613bb16d227Schristos    {
614bb16d227Schristos      res = dest - src;
615bb16d227Schristos      if (c)
616bb16d227Schristos	res -= (1-carry);
617bb16d227Schristos      c = res >= 0;
618bb16d227Schristos      if (res < 0)
619bb16d227Schristos	res += w ? 10000 : 100;
620bb16d227Schristos    }
621bb16d227Schristos
622bb16d227Schristos  res = int2bcd (res, w);
623bb16d227Schristos  tprintf(" = %x\n", res);
624bb16d227Schristos
625bb16d227Schristos  set_szc (res, w+1, c);
626bb16d227Schristos
627bb16d227Schristos  put_reg (w ? r0 : r0l, res);
628*8b657b07Schristos  }
629bb16d227Schristos
630bb16d227Schristos  /** 1010 1dst            DEC.B dest */
631bb16d227Schristos
632bb16d227Schristos  dc = decode_dest3 (dst, 0);
633bb16d227Schristos  v = get_src (dc);
634bb16d227Schristos  tprintf("%x -- = %x\n", v, v-1);
635bb16d227Schristos  v --;
636bb16d227Schristos  set_sz (v, 1);
637bb16d227Schristos  put_dest (dc, v);
638bb16d227Schristos
639bb16d227Schristos  /** 1111 d010            DEC.W dest */
640bb16d227Schristos
641bb16d227Schristos  v = get_reg (d ? a1 : a0);
642bb16d227Schristos  tprintf("%x -- = %x\n", v, v-1);
643bb16d227Schristos  v --;
644bb16d227Schristos  set_sz (v, 2);
645bb16d227Schristos  put_reg (d ? a1 : a0, v);
646bb16d227Schristos
647bb16d227Schristos  /** 0111 110w 1110 0001  DIV.size #IMM */
648bb16d227Schristos
649bb16d227Schristos  div_op (-1, 0, 0, w);
650bb16d227Schristos
651bb16d227Schristos  /** 0111 011w 1101 srcx  DIV.size src */
652bb16d227Schristos
653bb16d227Schristos  div_op (srcx, 0, 0, w);
654bb16d227Schristos
655bb16d227Schristos  /** 0111 110w 1110 0000  DIVU.size #IMM */
656bb16d227Schristos
657bb16d227Schristos  div_op (-1, 1, 0, w);
658bb16d227Schristos
659bb16d227Schristos  /** 0111 011w 1100 srcx  DIVU.size src */
660bb16d227Schristos
661bb16d227Schristos  div_op (srcx, 1, 0, w);
662bb16d227Schristos
663bb16d227Schristos  /** 0111 110w 1110 0011  DIVX.size #IMM */
664bb16d227Schristos
665bb16d227Schristos  div_op (-1, 0, 1, w);
666bb16d227Schristos
667bb16d227Schristos  /** 0111 011w 1001 srcx  DIVX.size src */
668bb16d227Schristos
669bb16d227Schristos  div_op (srcx, 0, 1, w);
670bb16d227Schristos
671bb16d227Schristos  /** 0111 1100 1111 0010  ENTER #IMM8 */
672bb16d227Schristos
673bb16d227Schristos  imm = IMM(0);
674bb16d227Schristos  put_reg (sp, get_reg (sp) - 2);
675bb16d227Schristos  mem_put_hi (get_reg (sp), get_reg (fb));
676bb16d227Schristos  put_reg (fb, get_reg (sp));
677bb16d227Schristos  put_reg (sp, get_reg (sp) - imm);
678bb16d227Schristos
679bb16d227Schristos  /** 0111 1101 1111 0010  EXITD */
680bb16d227Schristos
681bb16d227Schristos  put_reg (sp, get_reg (fb));
682bb16d227Schristos  put_reg (fb, mem_get_hi (get_reg (sp)));
683bb16d227Schristos  put_reg (sp, get_reg (sp) + 2);
684bb16d227Schristos  put_reg (pc, mem_get_psi (get_reg (sp)));
685bb16d227Schristos  put_reg (sp, get_reg (sp) + 3);
686bb16d227Schristos
687bb16d227Schristos  /** 0111 1100 0110 dest  EXTS.B dest */
688bb16d227Schristos
689bb16d227Schristos  dc = decode_srcdest4 (dest, 0);
690bb16d227Schristos  v = sign_ext (get_src (dc), 8);
691bb16d227Schristos  dc = widen_sd (dc);
692bb16d227Schristos  put_dest (dc, v);
693bb16d227Schristos  set_sz (v, 1);
694bb16d227Schristos
695bb16d227Schristos  /** 0111 1100 1111 0011  EXTS.W R0 */
696bb16d227Schristos
697bb16d227Schristos  v = sign_ext (get_reg (r0), 16);
698bb16d227Schristos  put_reg (r2r0, v);
699bb16d227Schristos  set_sz (v, 2);
700bb16d227Schristos
701bb16d227Schristos  /** 1110 1011 0flg 0101  FCLR dest */
702bb16d227Schristos
703bb16d227Schristos  set_flags (1 << flg, 0);
704bb16d227Schristos
705bb16d227Schristos  /** 1110 1011 0flg 0100  FSET dest */
706bb16d227Schristos
707bb16d227Schristos  set_flags (1 << flg, 1 << flg);
708bb16d227Schristos
709bb16d227Schristos  /** 1010 0dst            INC.B dest */
710bb16d227Schristos
711bb16d227Schristos  dc = decode_dest3 (dst, 0);
712bb16d227Schristos  v = get_src (dc);
713bb16d227Schristos  tprintf("%x ++ = %x\n", v, v+1);
714bb16d227Schristos  v ++;
715bb16d227Schristos  set_sz (v, 1);
716bb16d227Schristos  put_dest (dc, v);
717bb16d227Schristos
718bb16d227Schristos  /** 1011 d010            INC.W dest */
719bb16d227Schristos
720bb16d227Schristos  v = get_reg (d ? a1 : a0);
721bb16d227Schristos  tprintf("%x ++ = %x\n", v, v+1);
722bb16d227Schristos  v ++;
723bb16d227Schristos  set_sz (v, 2);
724bb16d227Schristos  put_reg (d ? a1 : a0, v);
725bb16d227Schristos
726bb16d227Schristos  /** 1110 1011 11vector   INT #imm */
727bb16d227Schristos
728bb16d227Schristos  trigger_based_interrupt (vector);
729bb16d227Schristos
730bb16d227Schristos  /** 1111 0110            INTO */
731bb16d227Schristos
732bb16d227Schristos  if (FLAG_O)
733bb16d227Schristos    trigger_fixed_interrupt (0xffe0);
734bb16d227Schristos
735bb16d227Schristos  /** 0110 1cnd            Jcnd label */
736bb16d227Schristos
737bb16d227Schristos  v = sign_ext (IMM(0), 8);
738bb16d227Schristos  if (condition_true (cnd))
739bb16d227Schristos    put_reg (pc, orig_pc + 1 + v);
740bb16d227Schristos
741bb16d227Schristos  /** 0111 1101 1100 cond  Jcnd label */
742bb16d227Schristos
743bb16d227Schristos  v = sign_ext (IMM(0), 8);
744bb16d227Schristos  if (condition_true (cond))
745bb16d227Schristos    put_reg (pc, orig_pc + 2 + v);
746bb16d227Schristos
747bb16d227Schristos  /** 0110 0dsp            JMP.S label */
748bb16d227Schristos
749bb16d227Schristos  put_reg (pc, orig_pc + 2 + dsp);
750bb16d227Schristos
751bb16d227Schristos  /** 1111 1110            JMP.B label */
752bb16d227Schristos
753bb16d227Schristos  imm = sign_ext (IMM(0), 8);
754bb16d227Schristos  if (imm == -1)
755bb16d227Schristos    {
756bb16d227Schristos      if (verbose)
757bb16d227Schristos	printf("[jmp-to-self detected as exit]\n");
758bb16d227Schristos      return M32C_MAKE_HIT_BREAK ();
759bb16d227Schristos    }
760bb16d227Schristos  put_reg (pc, orig_pc + 1 + imm);
761bb16d227Schristos
762bb16d227Schristos  /** 1111 0100            JMP.W label */
763bb16d227Schristos
764bb16d227Schristos  imm = sign_ext (IMM(1), 16);
765bb16d227Schristos  put_reg (pc, orig_pc + 1 + imm);
766bb16d227Schristos
767bb16d227Schristos  /** 1111 1100            JMP.A label */
768bb16d227Schristos
769bb16d227Schristos  imm = IMM(2);
770bb16d227Schristos  put_reg (pc, imm);
771bb16d227Schristos
772bb16d227Schristos  /** 0111 1101 0010 srcx  JMPI.W src */
773bb16d227Schristos
774bb16d227Schristos  sc = decode_jumpdest (srcx, 1);
775bb16d227Schristos  a = get_src (sc);
776bb16d227Schristos  a = sign_ext (a, 16);
777bb16d227Schristos  put_reg (pc, orig_pc + a);
778bb16d227Schristos
779bb16d227Schristos  /** 0111 1101 0000 srcx  JMPI.A src */
780bb16d227Schristos
781bb16d227Schristos  sc = decode_jumpdest (srcx, 0);
782bb16d227Schristos  a = get_src (sc);
783bb16d227Schristos  put_reg (pc, a);
784bb16d227Schristos
785bb16d227Schristos  /** 1110 1110            JMPS #IMM8 */
786bb16d227Schristos
787bb16d227Schristos  M16C_ONLY();
788bb16d227Schristos
789bb16d227Schristos  imm = IMM(0);
790bb16d227Schristos  a = 0xf0000 + mem_get_hi (0xffffe - imm * 2);
791bb16d227Schristos  put_reg (pc, a);
792bb16d227Schristos
793bb16d227Schristos  /** 1111 0101            JSR.W label */
794bb16d227Schristos
795bb16d227Schristos  imm = sign_ext (IMM(1), 16);
796bb16d227Schristos  put_reg (sp, get_reg (sp) - 3);
797bb16d227Schristos  mem_put_psi (get_reg (sp), get_reg (pc));
798bb16d227Schristos  put_reg (pc, orig_pc + imm + 1);
799bb16d227Schristos
800bb16d227Schristos  /** 1111 1101            JSR.A label */
801bb16d227Schristos
802bb16d227Schristos  imm = IMM(2);
803bb16d227Schristos  put_reg (sp, get_reg (sp) - 3);
804bb16d227Schristos  mem_put_psi (get_reg (sp), get_reg (pc));
805bb16d227Schristos  put_reg (pc, imm);
806bb16d227Schristos
807bb16d227Schristos  /** 0111 1101 0011 srcx  JSRI.W src */
808bb16d227Schristos
809bb16d227Schristos  sc = decode_jumpdest (srcx, 1);
810bb16d227Schristos  a = get_src (sc);
811bb16d227Schristos  a = sign_ext (a, 16);
812bb16d227Schristos
813bb16d227Schristos  put_reg (sp, get_reg (sp) - 3);
814bb16d227Schristos  mem_put_psi (get_reg (sp), get_reg (pc));
815bb16d227Schristos  put_reg (pc, orig_pc + a);
816bb16d227Schristos
817bb16d227Schristos  /** 0111 1101 0001 srcx  JSRI.A src */
818bb16d227Schristos
819bb16d227Schristos  sc = decode_jumpdest (srcx, 0);
820bb16d227Schristos  a = get_src (sc);
821bb16d227Schristos
822bb16d227Schristos  put_reg (sp, get_reg (sp) - 3);
823bb16d227Schristos  mem_put_psi (get_reg (sp), get_reg (pc));
824bb16d227Schristos  put_reg (pc, a);
825bb16d227Schristos
826bb16d227Schristos  /** 1110 1111            JSRS #IMM8 */
827bb16d227Schristos
828bb16d227Schristos  M16C_ONLY();
829bb16d227Schristos
830bb16d227Schristos  imm = IMM(0);
831bb16d227Schristos  a = 0xf0000 + mem_get_hi (0xffffe - imm * 2);
832bb16d227Schristos
833bb16d227Schristos  put_reg (sp, get_reg (sp) - 3);
834bb16d227Schristos  mem_put_psi (get_reg (sp), get_reg (pc));
835bb16d227Schristos  put_reg (pc, a);
836bb16d227Schristos
837bb16d227Schristos  /** 1110 1011 0reg 0000  LDC #IMM16,dest */
838bb16d227Schristos
839bb16d227Schristos  dc = decode_cr (reg);
840bb16d227Schristos  imm = IMM(1);
841bb16d227Schristos  put_dest (dc, imm);
842bb16d227Schristos
843bb16d227Schristos  /** 0111 1010 1reg srcx  LDC src,dest */
844bb16d227Schristos
845bb16d227Schristos  dc = decode_cr (reg);
846bb16d227Schristos  sc = decode_srcdest4 (srcx,1);
847bb16d227Schristos  put_dest (dc, get_src (sc));
848bb16d227Schristos
849bb16d227Schristos  /** 0111 1100 1111 0000  LDCTX abs16,abs20 */
850bb16d227Schristos
851bb16d227Schristos  NOTYET();
852bb16d227Schristos
853bb16d227Schristos  /** 0111 010w 1000 dest  LDE.size abs20,dest */
854bb16d227Schristos
855bb16d227Schristos  dc = decode_srcdest4 (dest, w);
856bb16d227Schristos  imm = IMM(2);
857bb16d227Schristos  if (w)
858bb16d227Schristos    v = mem_get_hi (imm);
859bb16d227Schristos  else
860bb16d227Schristos    v = mem_get_qi (imm);
861bb16d227Schristos  put_dest (dc, v);
862bb16d227Schristos
863bb16d227Schristos  /** 0111 010w 1001 dest  LDE.size dsp:20[a0], dest */
864bb16d227Schristos
865bb16d227Schristos  dc = decode_srcdest4 (dest, w);
866bb16d227Schristos  imm = IMM(2) + get_reg (a0);
867bb16d227Schristos  if (w)
868bb16d227Schristos    v = mem_get_hi (imm);
869bb16d227Schristos  else
870bb16d227Schristos    v = mem_get_qi (imm);
871bb16d227Schristos  put_dest (dc, v);
872bb16d227Schristos
873bb16d227Schristos  /** 0111 010w 1010 dest  LDE.size [a1a0],dest */
874bb16d227Schristos
875bb16d227Schristos  dc = decode_srcdest4 (dest, w);
876bb16d227Schristos  imm = get_reg (a1a0);
877bb16d227Schristos  if (w)
878bb16d227Schristos    v = mem_get_hi (imm);
879bb16d227Schristos  else
880bb16d227Schristos    v = mem_get_qi (imm);
881bb16d227Schristos  put_dest (dc, v);
882bb16d227Schristos
883bb16d227Schristos  /** 0111 1101 1010 0imm  LDIPL #IMM */
884bb16d227Schristos
885bb16d227Schristos  set_flags (0x700, imm*0x100);
886bb16d227Schristos
887bb16d227Schristos  /** 0111 010w 1100 dest  MOV.size:G #IMM,dest */
888bb16d227Schristos
889bb16d227Schristos  dc = decode_srcdest4 (dest, w);
890bb16d227Schristos  imm = IMM(w);
891bb16d227Schristos  v = imm;
892bb16d227Schristos  tprintf("%x = %x\n", v, v);
893bb16d227Schristos  set_sz(v, w+1);
894bb16d227Schristos  put_dest (dc, v);
895bb16d227Schristos
896bb16d227Schristos  /** 1101 100w immm dest  MOV.size:Q #IMM,dest */
897bb16d227Schristos
898bb16d227Schristos  dc = decode_srcdest4 (dest, w);
899bb16d227Schristos  v = sign_ext (immm, 4);
900bb16d227Schristos  tprintf ("%x = %x\n", v, v);
901bb16d227Schristos  set_sz (v, w+1);
902bb16d227Schristos  put_dest (dc, v);
903bb16d227Schristos
904bb16d227Schristos  /** 1100 0dst            MOV.B:S #IMM8,dest */
905bb16d227Schristos
906bb16d227Schristos  imm = IMM(0);
907bb16d227Schristos  dc = decode_dest3 (dst, 0);
908bb16d227Schristos  v = imm;
909bb16d227Schristos  tprintf("%x = %x\n", v, v);
910bb16d227Schristos  set_sz (v, 1);
911bb16d227Schristos  put_dest (dc, v);
912bb16d227Schristos
913bb16d227Schristos  /** 1w10 d010            MOV.size:S #IMM,dest */
914bb16d227Schristos
915bb16d227Schristos  /* Note that for w, 0=W and 1=B unlike the usual meaning.  */
916bb16d227Schristos  v = IMM(1-w);
917bb16d227Schristos  tprintf("%x = %x\n", v, v);
918bb16d227Schristos  set_sz (v, 2-w);
919bb16d227Schristos  put_reg (d ? a1 : a0, v);
920bb16d227Schristos
921bb16d227Schristos  /** 1011 0dst            MOV.B:Z #0,dest */
922bb16d227Schristos
923bb16d227Schristos  dc = decode_dest3 (dst, 0);
924bb16d227Schristos  v = 0;
925bb16d227Schristos  set_sz (v, 1);
926bb16d227Schristos  put_dest (dc, v);
927bb16d227Schristos
928bb16d227Schristos  /** 0111 001w srcx dest  MOV.size:G src,dest */
929bb16d227Schristos
930bb16d227Schristos  sc = decode_srcdest4 (srcx, w);
931bb16d227Schristos  dc = decode_srcdest4 (dest, w);
932bb16d227Schristos  v = get_src (sc);
933bb16d227Schristos  set_sz (v, w+1);
934bb16d227Schristos  put_dest (dc, v);
935bb16d227Schristos
936bb16d227Schristos  /** 0011 0d sr           MOV.B:S src,dest */
937bb16d227Schristos
938bb16d227Schristos  sc = decode_src2 (sr, 0, d);
939bb16d227Schristos  v = get_src (sc);
940bb16d227Schristos  set_sz (v, 1);
941bb16d227Schristos  put_reg (d ? a1 : a0, v);
942bb16d227Schristos
943bb16d227Schristos  /** 0000 0s ds           MOV.B:S R0L/R0H,dest */
944bb16d227Schristos
945bb16d227Schristos  if (ds == 0)
946bb16d227Schristos    UNSUPPORTED();
947bb16d227Schristos  dc = decode_src2 (ds, 0, s);
948bb16d227Schristos  v = get_reg (s ? r0h : r0l);
949bb16d227Schristos  set_sz (v, 1);
950bb16d227Schristos  put_dest (dc, v);
951bb16d227Schristos
952bb16d227Schristos  /** 0000 1d sr           MOV.B:S src,R0L/R0H */
953bb16d227Schristos
954bb16d227Schristos  sc = decode_src2 (sr, 0, d);
955bb16d227Schristos  v = get_src (sc);
956bb16d227Schristos  set_sz (v, 1);
957bb16d227Schristos  put_reg (d ? r0h : r0l, v);
958bb16d227Schristos
959bb16d227Schristos  /** 0111 010w 1011 dest  MOV.size:G dsp:8[SP], dest */
960bb16d227Schristos
961bb16d227Schristos  dc = decode_srcdest4 (dest, w);
962bb16d227Schristos  imm = IMM(0);
963bb16d227Schristos  a = get_reg (sp) + sign_ext (imm, 8);
964bb16d227Schristos  a &= addr_mask;
965bb16d227Schristos  if (w)
966bb16d227Schristos    v = mem_get_hi (a);
967bb16d227Schristos  else
968bb16d227Schristos    v = mem_get_qi (a);
969bb16d227Schristos  set_sz (v, w+1);
970bb16d227Schristos  put_dest (dc, v);
971bb16d227Schristos
972bb16d227Schristos  /** 0111 010w 0011 srcx  MOV.size:G src, disp8[SP] */
973bb16d227Schristos
974bb16d227Schristos  sc = decode_srcdest4 (srcx, w);
975bb16d227Schristos  imm = IMM(0);
976bb16d227Schristos  a = get_reg (sp) + sign_ext (imm, 8);
977bb16d227Schristos  a &= addr_mask;
978bb16d227Schristos  v = get_src (sc);
979bb16d227Schristos  if (w)
980bb16d227Schristos    mem_put_hi (a, v);
981bb16d227Schristos  else
982bb16d227Schristos    mem_put_qi (a, v);
983bb16d227Schristos  set_sz (v, w+1);
984bb16d227Schristos
985bb16d227Schristos  /** 1110 1011 0reg 1src  MOVA src,dest */
986bb16d227Schristos
987*8b657b07Schristos  {
988bb16d227Schristos  static reg_id map[] = { r0, r1, r2, r3, a0, a1, 0, 0 };
989bb16d227Schristos  sc = decode_srcdest4 (8 + src, 0);
990bb16d227Schristos  put_reg (map[reg], sc.u.addr);
991*8b657b07Schristos  }
992bb16d227Schristos
993bb16d227Schristos  /** 0111 1100 10hl dest  MOVdir R0L,dest */
994bb16d227Schristos
995bb16d227Schristos  if (dest == 0 || dest == 4 || dest == 5)
996bb16d227Schristos    UNSUPPORTED();
997bb16d227Schristos  dc = decode_srcdest4 (dest, 0);
998bb16d227Schristos  a = get_src (dc);
999bb16d227Schristos  b = get_reg (r0l);
1000bb16d227Schristos  switch (hl)
1001bb16d227Schristos    {
1002bb16d227Schristos    case 0: a = (a & 0xf0) | (b & 0x0f); break;
1003bb16d227Schristos    case 1: a = (a & 0xf0) | ((b>>4) & 0x0f); break;
1004bb16d227Schristos    case 2: a = (a & 0x0f) | ((b & 0x0f)<<4); break;
1005bb16d227Schristos    case 3: a = (a & 0x0f) | (b & 0xf0); break;
1006bb16d227Schristos    }
1007bb16d227Schristos  put_dest (dc, a);
1008bb16d227Schristos
1009bb16d227Schristos  /** 0111 1100 00hl srcx  MOVdir src,R0L */
1010bb16d227Schristos
1011bb16d227Schristos  if (srcx == 0 || srcx == 4 || srcx == 5)
1012bb16d227Schristos    UNSUPPORTED();
1013bb16d227Schristos  sc = decode_srcdest4 (srcx, 0);
1014bb16d227Schristos  a = get_reg (r0l);
1015bb16d227Schristos  b = get_src (sc);
1016bb16d227Schristos  switch (hl)
1017bb16d227Schristos    {
1018bb16d227Schristos    case 0: a = (a & 0xf0) | (b & 0x0f); break;
1019bb16d227Schristos    case 1: a = (a & 0xf0) | ((b>>4) & 0x0f); break;
1020bb16d227Schristos    case 2: a = (a & 0x0f) | ((b & 0x0f)<<4); break;
1021bb16d227Schristos    case 3: a = (a & 0x0f) | (b & 0xf0); break;
1022bb16d227Schristos    }
1023bb16d227Schristos  put_reg (r0l, a);
1024bb16d227Schristos
1025bb16d227Schristos  /** 0111 110w 0101 dest  MUL.size #IMM,dest */
1026bb16d227Schristos
1027bb16d227Schristos  UNARY_SOP;
1028bb16d227Schristos  imm = sign_ext (IMM(w), w?16:8);
1029bb16d227Schristos  tprintf("%d * %d = %d\n", v, imm, v*imm);
1030bb16d227Schristos  v *= imm;
1031bb16d227Schristos  dc = widen_sd (dc);
1032bb16d227Schristos  put_dest (dc, v);
1033bb16d227Schristos
1034bb16d227Schristos  /** 0111 100w srcx dest  MUL.size src,dest */
1035bb16d227Schristos
1036bb16d227Schristos  BINARY_SOP;
1037bb16d227Schristos  v = a * b;
1038bb16d227Schristos  tprintf("%d * %d = %d\n", a, b, v);
1039bb16d227Schristos  dc = widen_sd (dc);
1040bb16d227Schristos  put_dest (dc, v);
1041bb16d227Schristos
1042bb16d227Schristos  /** 0111 110w 0100 dest  MULU.size #IMM,dest */
1043bb16d227Schristos
1044bb16d227Schristos  UNARY_UOP;
1045bb16d227Schristos  imm = IMM(w);
1046bb16d227Schristos  tprintf("%u * %u = %u\n", v, imm, v*imm);
1047bb16d227Schristos  v *= imm;
1048bb16d227Schristos  dc = widen_sd (dc);
1049bb16d227Schristos  put_dest (dc, v);
1050bb16d227Schristos
1051bb16d227Schristos  /** 0111 000w srcx dest  MULU.size src,dest */
1052bb16d227Schristos
1053bb16d227Schristos  BINARY_UOP;
1054bb16d227Schristos  v = a * b;
1055bb16d227Schristos  tprintf("%u * %u = %u\n", a, b, v);
1056bb16d227Schristos  dc = widen_sd (dc);
1057bb16d227Schristos  put_dest (dc, v);
1058bb16d227Schristos
1059bb16d227Schristos  /** 0111 010w 0101 dest  NEG.size dest */
1060bb16d227Schristos
1061bb16d227Schristos  UNARY_SOP;
1062bb16d227Schristos  tprintf("%d * -1 = %d\n", v, -v);
1063bb16d227Schristos  v = -v;
1064bb16d227Schristos  set_oszc (v, w+1, v == 0);
1065bb16d227Schristos  put_dest (dc, v);
1066bb16d227Schristos
1067bb16d227Schristos  /** 0000 0100            NOP */
1068bb16d227Schristos
1069bb16d227Schristos  tprintf("nop\n");
1070bb16d227Schristos
1071bb16d227Schristos  /** 0111 010w 0111 dest  NOT.size:G */
1072bb16d227Schristos
1073bb16d227Schristos  UNARY_UOP;
1074bb16d227Schristos  tprintf("~ %x = %x\n", v, ~v);
1075bb16d227Schristos  v = ~v;
1076bb16d227Schristos  set_sz (v, w+1);
1077bb16d227Schristos  put_dest (dc, v);
1078bb16d227Schristos
1079bb16d227Schristos  /** 1011 1dst            NOT.B:S dest */
1080bb16d227Schristos
1081bb16d227Schristos  dc = decode_dest3 (dst, 0);
1082bb16d227Schristos  v = get_src (dc);
1083bb16d227Schristos  tprintf("~ %x = %x\n", v, ~v);
1084bb16d227Schristos  v = ~v;
1085bb16d227Schristos  set_sz (v, 1);
1086bb16d227Schristos  put_dest (dc, v);
1087bb16d227Schristos
1088bb16d227Schristos  /** 0111 011w 0011 dest  OR.size:G #IMM,dest */
1089bb16d227Schristos
1090bb16d227Schristos  UNARY_UOP;
1091bb16d227Schristos  imm = IMM(w);
1092bb16d227Schristos  tprintf ("%x | %x = %x\n", v, imm, v | imm);
1093bb16d227Schristos  v |= imm;
1094bb16d227Schristos  set_sz (v, w+1);
1095bb16d227Schristos  put_dest (dc, v);
1096bb16d227Schristos
1097bb16d227Schristos  /** 1001 1dst            OR.B:S #IMM8,dest */
1098bb16d227Schristos
1099bb16d227Schristos  imm = IMM(0);
1100bb16d227Schristos  dc = decode_dest3 (dst, 0);
1101bb16d227Schristos  v = get_src (dc);
1102bb16d227Schristos  tprintf("%x | %x = %x\n", v, imm, v|imm);
1103bb16d227Schristos  v |= imm;
1104bb16d227Schristos  set_sz (v, 1);
1105bb16d227Schristos  put_dest (dc, v);
1106bb16d227Schristos
1107bb16d227Schristos  /** 1001 100w srcx dest  OR.size:G src,dest */
1108bb16d227Schristos
1109bb16d227Schristos  BINARY_UOP;
1110bb16d227Schristos  tprintf ("%x | %x = %x\n", a, b, a | b);
1111bb16d227Schristos  v = a | b;
1112bb16d227Schristos  set_sz (v, w+1);
1113bb16d227Schristos  put_dest (dc, v);
1114bb16d227Schristos
1115bb16d227Schristos  /** 0001 1d sr           OR.B:S src,R0L/R0H */
1116bb16d227Schristos
1117bb16d227Schristos  sc = decode_src2 (sr, 0, d);
1118bb16d227Schristos  dc = decode_dest1 (d, 0);
1119bb16d227Schristos  a = get_src (sc);
1120bb16d227Schristos  b = get_src (dc);
1121bb16d227Schristos  v = a | b;
1122bb16d227Schristos  tprintf("%x | %x = %x\n", a, b, v);
1123bb16d227Schristos  set_sz (v, 1);
1124bb16d227Schristos  put_dest (dc, v);
1125bb16d227Schristos
1126bb16d227Schristos  /** 0111 010w 1101 dest  POP.size:G dest */
1127bb16d227Schristos
1128bb16d227Schristos  dc = decode_srcdest4 (dest, w);
1129bb16d227Schristos  if (w)
1130bb16d227Schristos    {
1131bb16d227Schristos      v = mem_get_hi (get_reg (sp));
1132bb16d227Schristos      put_reg (sp, get_reg (sp) + 2);
1133bb16d227Schristos      tprintf("pophi: %x\n", v);
1134bb16d227Schristos    }
1135bb16d227Schristos  else
1136bb16d227Schristos    {
1137bb16d227Schristos      v = mem_get_qi (get_reg (sp));
1138bb16d227Schristos      put_reg (sp, get_reg (sp) + 1);
1139bb16d227Schristos      tprintf("popqi: %x\n", v);
1140bb16d227Schristos    }
1141bb16d227Schristos  put_dest (dc, v);
1142bb16d227Schristos
1143bb16d227Schristos  /** 1001 d010            POP.B:S dest */
1144bb16d227Schristos
1145bb16d227Schristos  v = mem_get_qi (get_reg (sp));
1146bb16d227Schristos  put_reg (d ? r0h : r0l, v);
1147bb16d227Schristos  put_reg (sp, get_reg (sp) + 1);
1148bb16d227Schristos  tprintf("popqi: %x\n", v);
1149bb16d227Schristos
1150bb16d227Schristos  /** 1101 d010            POP.W:S dest */
1151bb16d227Schristos
1152bb16d227Schristos  v = mem_get_hi (get_reg (sp));
1153bb16d227Schristos  put_reg (d ? a1 : a0, v);
1154bb16d227Schristos  put_reg (sp, get_reg (sp) + 2);
1155bb16d227Schristos  tprintf("pophi: %x\n", v);
1156bb16d227Schristos
1157bb16d227Schristos  /** 1110 1011 0reg 0011  POPC dest */
1158bb16d227Schristos
1159bb16d227Schristos  dc = decode_cr (reg);
1160bb16d227Schristos  v = mem_get_hi (get_reg (sp));
1161bb16d227Schristos  put_dest (dc, v);
1162bb16d227Schristos  put_reg (sp, get_reg (sp) + 2);
1163bb16d227Schristos  tprintf("popc: %x\n", v);
1164bb16d227Schristos
1165bb16d227Schristos  /** 1110 1101            POPM dest */
1166bb16d227Schristos
1167*8b657b07Schristos  {
1168bb16d227Schristos  static int map[] = { r0, r1, r2, r3, a0, a1, sb, fb };
1169bb16d227Schristos  imm = IMM(0);
1170bb16d227Schristos  tprintf("popm: %x\n", imm);
1171bb16d227Schristos  for (a=0; a<8; a++)
1172bb16d227Schristos    if (imm & (1<<a))
1173bb16d227Schristos      {
1174bb16d227Schristos	v = mem_get_hi (get_reg (sp));
1175bb16d227Schristos	put_reg (map[a], v);
1176bb16d227Schristos	put_reg (sp, get_reg (sp) + 2);
1177bb16d227Schristos      }
1178*8b657b07Schristos  }
1179bb16d227Schristos
1180bb16d227Schristos  /** 0111 110w 1110 0010  PUSH.size:G #IMM */
1181bb16d227Schristos
1182bb16d227Schristos  imm = IMM(w);
1183bb16d227Schristos  if (w)
1184bb16d227Schristos    {
1185bb16d227Schristos      put_reg (sp, get_reg (sp) - 2);
1186bb16d227Schristos      mem_put_hi (get_reg (sp), imm);
1187bb16d227Schristos      tprintf("pushhi %04x\n", imm);
1188bb16d227Schristos    }
1189bb16d227Schristos  else
1190bb16d227Schristos    {
1191bb16d227Schristos      put_reg (sp, get_reg (sp) - 1);
1192bb16d227Schristos      mem_put_qi (get_reg (sp), imm);
1193bb16d227Schristos      tprintf("pushqi %02x\n", imm);
1194bb16d227Schristos    }
1195bb16d227Schristos
1196bb16d227Schristos  /** 0111 010w 0100 srcx  PUSH.size:G src */
1197bb16d227Schristos
1198bb16d227Schristos  sc = decode_srcdest4 (srcx, w);
1199bb16d227Schristos  v = get_src (sc);
1200bb16d227Schristos  if (w)
1201bb16d227Schristos    {
1202bb16d227Schristos      put_reg (sp, get_reg (sp) - 2);
1203bb16d227Schristos      mem_put_hi (get_reg (sp), v);
1204bb16d227Schristos      tprintf("pushhi: %x\n", v);
1205bb16d227Schristos    }
1206bb16d227Schristos  else
1207bb16d227Schristos    {
1208bb16d227Schristos      put_reg (sp, get_reg (sp) - 1);
1209bb16d227Schristos      mem_put_qi (get_reg (sp), v);
1210bb16d227Schristos      tprintf("pushqi: %x\n", v);
1211bb16d227Schristos    }
1212bb16d227Schristos
1213bb16d227Schristos  /** 1000 s010            PUSH.B:S src */
1214bb16d227Schristos
1215bb16d227Schristos  v = get_reg (s ? r0h : r0l);
1216bb16d227Schristos  put_reg (sp, get_reg (sp) - 1);
1217bb16d227Schristos  mem_put_qi (get_reg (sp), v);
1218bb16d227Schristos  tprintf("pushqi: %x\n", v);
1219bb16d227Schristos
1220bb16d227Schristos  /** 1100 s010            PUSH.W:S src */
1221bb16d227Schristos
1222bb16d227Schristos  v = get_reg (s ? a1 : a0);
1223bb16d227Schristos  put_reg (sp, get_reg (sp) - 2);
1224bb16d227Schristos  mem_put_hi (get_reg (sp), v);
1225bb16d227Schristos  tprintf("pushhi: %x\n", v);
1226bb16d227Schristos
1227bb16d227Schristos  /** 0111 1101 1001 srcx  PUSHA src */
1228bb16d227Schristos
1229bb16d227Schristos  sc = decode_srcdest4 (srcx, 0);
1230bb16d227Schristos  put_reg (sp, get_reg (sp) - 2);
1231bb16d227Schristos  mem_put_hi (get_reg (sp), sc.u.addr);
1232bb16d227Schristos  tprintf("pushhi: %x\n", sc.u.addr);
1233bb16d227Schristos
1234bb16d227Schristos  /** 1110 1011 0src 0010  PUSHC src */
1235bb16d227Schristos
1236bb16d227Schristos  sc = decode_cr (src);
1237bb16d227Schristos  put_reg (sp, get_reg (sp) - 2);
1238bb16d227Schristos  v = get_src (sc);
1239bb16d227Schristos  mem_put_hi (get_reg (sp), v);
1240bb16d227Schristos  tprintf("pushc: %x\n", v);
1241bb16d227Schristos
1242bb16d227Schristos  /** 1110 1100            PUSHM src */
1243bb16d227Schristos
1244*8b657b07Schristos  {
1245bb16d227Schristos  static int map[] = { fb, sb, a1, a0, r3, r2, r1, r0 };
1246bb16d227Schristos  imm = IMM(0);
1247bb16d227Schristos  tprintf("pushm: %x\n", imm);
1248bb16d227Schristos  for (a=0; a<8; a++)
1249bb16d227Schristos    if (imm & (1<<a))
1250bb16d227Schristos      {
1251bb16d227Schristos	put_reg (sp, get_reg (sp) - 2);
1252bb16d227Schristos	v = get_reg (map[a]);
1253bb16d227Schristos	mem_put_hi (get_reg (sp), v);
1254bb16d227Schristos      }
1255*8b657b07Schristos  }
1256bb16d227Schristos
1257bb16d227Schristos  /** 1111 1011            REIT */
1258bb16d227Schristos
1259bb16d227Schristos  a = get_reg (sp);
1260bb16d227Schristos  v = (mem_get_hi (a)
1261bb16d227Schristos       + 4096 * (mem_get_qi (a+3) & 0xf0));
1262bb16d227Schristos  b = (mem_get_qi (a+2)
1263bb16d227Schristos       + 256 * (mem_get_qi (a+3) & 0xff));
1264bb16d227Schristos  put_reg (pc, v);
1265bb16d227Schristos  put_reg (flags, b);
1266bb16d227Schristos  put_reg (sp, get_reg (sp) + 4);
1267bb16d227Schristos
1268bb16d227Schristos  /** 0111 110w 1111 0001  RMPA.size */
1269bb16d227Schristos
1270*8b657b07Schristos  {
1271bb16d227Schristos  int count = get_reg (r3);
1272bb16d227Schristos  int list1 = get_reg (a0);
1273bb16d227Schristos  int list2 = get_reg (a1);
1274bb16d227Schristos  int sum = get_reg (w ? r2r0 : r0);
1275bb16d227Schristos
1276bb16d227Schristos  while (count)
1277bb16d227Schristos    {
1278bb16d227Schristos      if (w)
1279bb16d227Schristos	{
1280bb16d227Schristos	  a = sign_ext (mem_get_hi (list1), 16);
1281bb16d227Schristos	  b = sign_ext (mem_get_hi (list2), 16);
1282bb16d227Schristos	}
1283bb16d227Schristos      else
1284bb16d227Schristos	{
1285bb16d227Schristos	  a = sign_ext (mem_get_qi (list1), 8);
1286bb16d227Schristos	  b = sign_ext (mem_get_qi (list2), 8);
1287bb16d227Schristos	}
1288bb16d227Schristos      tprintf("%d + %d * %d = ", sum, a, b);
1289bb16d227Schristos      sum += a * b;
1290bb16d227Schristos      tprintf("%d\n", sum);
1291bb16d227Schristos      list1 += w ? 2 : 1;
1292bb16d227Schristos      list2 += w ? 2 : 1;
1293bb16d227Schristos      count --;
1294bb16d227Schristos    }
1295bb16d227Schristos  put_reg (r3, count);
1296bb16d227Schristos  put_reg (a0, list1);
1297bb16d227Schristos  put_reg (a1, list2);
1298bb16d227Schristos  put_reg (w ? r2r0 : r0, sum);
1299*8b657b07Schristos  }
1300bb16d227Schristos
1301bb16d227Schristos  /** 0111 011w 1010 dest  ROLC.size dest */
1302bb16d227Schristos
1303bb16d227Schristos  dc = decode_srcdest4 (dest, w);
1304bb16d227Schristos  rot_op (dc, 1, 1);
1305bb16d227Schristos
1306bb16d227Schristos  /** 0111 011w 1011 dest  RORC.size dest */
1307bb16d227Schristos
1308bb16d227Schristos  dc = decode_srcdest4 (dest, w);
1309bb16d227Schristos  rot_op (dc, 1, -1);
1310bb16d227Schristos
1311bb16d227Schristos  /** 1110 000w immm dest  ROT.size #IMM,dest */
1312bb16d227Schristos
1313bb16d227Schristos  dc = decode_srcdest4 (dest, w);
1314bb16d227Schristos  rot_op (dc, 0, IMM4());
1315bb16d227Schristos
1316bb16d227Schristos  /** 0111 010w 0110 dest  ROT.size R1H,dest */
1317bb16d227Schristos
1318bb16d227Schristos  dc = decode_srcdest4 (dest, w);
1319bb16d227Schristos  rot_op (dc, 0, sign_ext (get_reg (r1h), 8));
1320bb16d227Schristos
1321bb16d227Schristos  /** 1111 0011            RTS */
1322bb16d227Schristos
1323bb16d227Schristos  put_reg (pc, mem_get_psi (get_reg (sp)));
1324bb16d227Schristos  put_reg (sp, get_reg (sp) + 3);
1325bb16d227Schristos
1326bb16d227Schristos  /** 0111 011w 0111 dest  SBB.size #IMM,dest */
1327bb16d227Schristos
1328bb16d227Schristos  dc = decode_srcdest4 (dest, w);
1329bb16d227Schristos  imm = IMM(w);
1330bb16d227Schristos  MATH_OP (dc, imm, !carry, -, >= 0);
1331bb16d227Schristos
1332bb16d227Schristos  /** 1011 100w srcx dest  SBB.size src,dest */
1333bb16d227Schristos
1334bb16d227Schristos  sc = decode_srcdest4(srcx, w);
1335bb16d227Schristos  dc = decode_srcdest4(dest, w);
1336bb16d227Schristos  b = get_src (sc);
1337bb16d227Schristos  MATH_OP (dc, b, !carry, -, >= 0);
1338bb16d227Schristos
1339bb16d227Schristos  /** 1111 000w immm dest  SHA.size #IMM, dest */
1340bb16d227Schristos
1341bb16d227Schristos  dc = decode_srcdest4(dest, w);
1342bb16d227Schristos  shift_op (dc, 1, IMM4());
1343bb16d227Schristos
1344bb16d227Schristos  /** 0111 010w 1111 dest  SHA.size R1H,dest */
1345bb16d227Schristos
1346bb16d227Schristos  dc = decode_srcdest4(dest, w);
1347bb16d227Schristos  a = sign_ext (get_reg (r1h), 8);
1348bb16d227Schristos  shift_op (dc, 1, a);
1349bb16d227Schristos
1350bb16d227Schristos  /** 1110 1011 101d immm  SHA.L #IMM, dest */
1351bb16d227Schristos
1352bb16d227Schristos  dc = reg_sd (d ? r3r1 : r2r0);
1353bb16d227Schristos  shift_op (dc, 1, IMM4());
1354bb16d227Schristos
1355bb16d227Schristos  /** 1110 1011 001d 0001  SHA.L R1H,dest */
1356bb16d227Schristos
1357bb16d227Schristos  dc = reg_sd (d ? r3r1 : r2r0);
1358bb16d227Schristos  a = sign_ext (get_reg (r1h), 8);
1359bb16d227Schristos  shift_op (dc, 1, a);
1360bb16d227Schristos
1361bb16d227Schristos  /** 1110 100w immm dest  SHL.size #IMM, dest */
1362bb16d227Schristos
1363bb16d227Schristos  dc = decode_srcdest4(dest, w);
1364bb16d227Schristos  shift_op (dc, 0, IMM4());
1365bb16d227Schristos
1366bb16d227Schristos  /** 0111 010w 1110 dest  SHL.size R1H,dest */
1367bb16d227Schristos
1368bb16d227Schristos  dc = decode_srcdest4(dest, w);
1369bb16d227Schristos  a = sign_ext (get_reg (r1h), 8);
1370bb16d227Schristos  shift_op (dc, 0, a);
1371bb16d227Schristos
1372bb16d227Schristos  /** 1110 1011 100d immm  SHL.L #IMM,dest */
1373bb16d227Schristos
1374bb16d227Schristos  dc = reg_sd (d ? r3r1 : r2r0);
1375bb16d227Schristos  shift_op (dc, 0, IMM4());
1376bb16d227Schristos
1377bb16d227Schristos  /** 1110 1011 000d 0001  SHL.L R1H,dest */
1378bb16d227Schristos
1379bb16d227Schristos  dc = reg_sd (d ? r3r1 : r2r0);
1380bb16d227Schristos  a = sign_ext (get_reg (r1h), 8);
1381bb16d227Schristos  shift_op (dc, 0, a);
1382bb16d227Schristos
1383bb16d227Schristos  /** 0111 110w 1110 100b  SMOVB.size */
1384bb16d227Schristos
1385*8b657b07Schristos  {
1386bb16d227Schristos  int count = get_reg (r3);
1387bb16d227Schristos  int s1 = get_reg (a0) + (get_reg (r1h) << 16);
1388bb16d227Schristos  int s2 = get_reg (a1);
1389bb16d227Schristos  int inc = (w ? 2 : 1) * (b ? -1 : 1);
1390bb16d227Schristos
1391bb16d227Schristos  while (count)
1392bb16d227Schristos    {
1393bb16d227Schristos      if (w)
1394bb16d227Schristos	{
1395bb16d227Schristos	  v = mem_get_hi (s1);
1396bb16d227Schristos	  mem_put_hi (s2, v);
1397bb16d227Schristos	}
1398bb16d227Schristos      else
1399bb16d227Schristos	{
1400bb16d227Schristos	  v = mem_get_qi (s1);
1401bb16d227Schristos	  mem_put_qi (s2, v);
1402bb16d227Schristos	}
1403bb16d227Schristos      s1 += inc;
1404bb16d227Schristos      s2 += inc;
1405bb16d227Schristos      count --;
1406bb16d227Schristos    }
1407bb16d227Schristos  put_reg (r3, count);
1408bb16d227Schristos  put_reg (a0, s1 & 0xffff);
1409bb16d227Schristos  put_reg (a1, s2);
1410bb16d227Schristos  put_reg (r1h, s1 >> 16);
1411*8b657b07Schristos  }
1412bb16d227Schristos
1413bb16d227Schristos  /** 0111 110w 1110 1010  SSTR.size */
1414bb16d227Schristos
1415*8b657b07Schristos  {
1416bb16d227Schristos  int count = get_reg (r3);
1417bb16d227Schristos  int s1 = get_reg (a1);
1418bb16d227Schristos  v = get_reg (w ? r0 : r0l);
1419bb16d227Schristos
1420bb16d227Schristos  while (count)
1421bb16d227Schristos    {
1422bb16d227Schristos      if (w)
1423bb16d227Schristos	{
1424bb16d227Schristos	  mem_put_hi (s1, v);
1425bb16d227Schristos	  s1 += 2;
1426bb16d227Schristos	}
1427bb16d227Schristos      else
1428bb16d227Schristos	{
1429bb16d227Schristos	  mem_put_qi (s1, v);
1430bb16d227Schristos	  s1 += 1;
1431bb16d227Schristos	}
1432bb16d227Schristos      count --;
1433bb16d227Schristos    }
1434bb16d227Schristos  put_reg (r3, count);
1435bb16d227Schristos  put_reg (a1, s1);
1436*8b657b07Schristos  }
1437bb16d227Schristos
1438bb16d227Schristos  /** 0111 1011 1src dest  STC src,dest */
1439bb16d227Schristos
1440bb16d227Schristos  dc = decode_srcdest4 (dest, 1);
1441bb16d227Schristos  sc = decode_cr (src);
1442bb16d227Schristos  put_dest (dc, get_src(sc));
1443bb16d227Schristos
1444bb16d227Schristos  /** 0111 1100 1100 dest  STC PC,dest */
1445bb16d227Schristos
1446bb16d227Schristos  dc = decode_srcdest4 (dest, 1);
1447bb16d227Schristos  dc.bytes = 3;
1448bb16d227Schristos  put_dest (dc, orig_pc);
1449bb16d227Schristos
1450bb16d227Schristos  /** 0111 1101 1111 0000  STCTX abs16,abs20 */
1451bb16d227Schristos
1452bb16d227Schristos  NOTYET();
1453bb16d227Schristos
1454bb16d227Schristos  /** 0111 010w 0000 srcx  STE.size src,abs20 */
1455bb16d227Schristos
1456bb16d227Schristos  sc = decode_srcdest4 (srcx, w);
1457bb16d227Schristos  a = IMM(2);
1458bb16d227Schristos  v = get_src (sc);
1459bb16d227Schristos  if (w)
1460bb16d227Schristos    mem_put_hi (a, v);
1461bb16d227Schristos  else
1462bb16d227Schristos    mem_put_qi (a, v);
1463bb16d227Schristos  if (srcx == 4 || srcx == 5)
1464bb16d227Schristos    {
1465bb16d227Schristos      v = get_reg (sc.u.reg);
1466bb16d227Schristos      set_sz (v, 2);
1467bb16d227Schristos    }
1468bb16d227Schristos  else
1469bb16d227Schristos    set_sz (v, w+1);
1470bb16d227Schristos
1471bb16d227Schristos  /** 0111 010w 0001 srcx  STE.size src,disp20[a0] */
1472bb16d227Schristos
1473bb16d227Schristos  sc = decode_srcdest4 (srcx, w);
1474bb16d227Schristos  a = get_reg(a0) + IMM(2);
1475bb16d227Schristos  v = get_src (sc);
1476bb16d227Schristos  if (w)
1477bb16d227Schristos    mem_put_hi (a, v);
1478bb16d227Schristos  else
1479bb16d227Schristos    mem_put_qi (a, v);
1480bb16d227Schristos  if (srcx == 4 || srcx == 5)
1481bb16d227Schristos    {
1482bb16d227Schristos      v = get_reg (sc.u.reg);
1483bb16d227Schristos      set_sz (v, 2);
1484bb16d227Schristos    }
1485bb16d227Schristos  else
1486bb16d227Schristos    set_sz (v, w+1);
1487bb16d227Schristos
1488bb16d227Schristos  /** 0111 010w 0010 srcx  STE.size src,[a1a0] */
1489bb16d227Schristos
1490bb16d227Schristos  sc = decode_srcdest4 (srcx, w);
1491bb16d227Schristos  a = get_reg(a1a0);
1492bb16d227Schristos  v = get_src (sc);
1493bb16d227Schristos  if (w)
1494bb16d227Schristos    mem_put_hi (a, v);
1495bb16d227Schristos  else
1496bb16d227Schristos    mem_put_qi (a, v);
1497bb16d227Schristos  if (srcx == 4 || srcx == 5)
1498bb16d227Schristos    {
1499bb16d227Schristos      v = get_reg (sc.u.reg);
1500bb16d227Schristos      set_sz (v, 2);
1501bb16d227Schristos    }
1502bb16d227Schristos  else
1503bb16d227Schristos    set_sz (v, w+1);
1504bb16d227Schristos
1505bb16d227Schristos  /** 1101 0dst            STNZ #IMM8,dest */
1506bb16d227Schristos
1507bb16d227Schristos  imm = IMM(0);
1508bb16d227Schristos  dc = decode_dest3(dst, 0);
1509bb16d227Schristos  if (!FLAG_Z)
1510bb16d227Schristos    put_dest (dc, imm);
1511bb16d227Schristos
1512bb16d227Schristos  /** 1100 1dst            STZ #IMM8,dest */
1513bb16d227Schristos
1514bb16d227Schristos  imm = IMM(0);
1515bb16d227Schristos  dc = decode_dest3(dst, 0);
1516bb16d227Schristos  if (FLAG_Z)
1517bb16d227Schristos    put_dest (dc, imm);
1518bb16d227Schristos
1519bb16d227Schristos  /** 1101 1dst            STZX #IMM81,#IMM82,dest */
1520bb16d227Schristos
1521bb16d227Schristos  a = IMM(0);
1522bb16d227Schristos  dc = decode_dest3(dst, 0);
1523bb16d227Schristos  b = IMM(0);
1524bb16d227Schristos  if (FLAG_Z)
1525bb16d227Schristos    put_dest (dc, a);
1526bb16d227Schristos  else
1527bb16d227Schristos    put_dest (dc, b);
1528bb16d227Schristos
1529bb16d227Schristos  /** 0111 011w 0101 dest  SUB.size:G #IMM,dest */
1530bb16d227Schristos
1531bb16d227Schristos  dc = decode_srcdest4 (dest, w);
1532bb16d227Schristos  imm = IMM(w);
1533bb16d227Schristos  MATH_OP (dc, imm, 0, -, >= 0);
1534bb16d227Schristos
1535bb16d227Schristos  /** 1000 1dst            SUB.B:S #IMM8,dest */
1536bb16d227Schristos
1537bb16d227Schristos  imm = IMM(0);
1538bb16d227Schristos  dc = decode_dest3 (dst, 0);
1539bb16d227Schristos  MATH_OP (dc, imm, 0, -, >= 0);
1540bb16d227Schristos
1541bb16d227Schristos  /** 1010 100w srcx dest  SUB.size:G src,dest */
1542bb16d227Schristos
1543bb16d227Schristos  sc = decode_srcdest4(srcx, w);
1544bb16d227Schristos  dc = decode_srcdest4(dest, w);
1545bb16d227Schristos  b = get_src (sc);
1546bb16d227Schristos  MATH_OP (dc, b, 0, -, >= 0);
1547bb16d227Schristos
1548bb16d227Schristos  /** 0010 1d sr           SUB.B:S src,R0L/R0H */
1549bb16d227Schristos
1550bb16d227Schristos  sc = decode_src2 (sr, 0, d);
1551bb16d227Schristos  dc = decode_dest1 (d, 0);
1552bb16d227Schristos  b = get_src (sc);
1553bb16d227Schristos  MATH_OP (dc, b, 0, -, >= 0);
1554bb16d227Schristos
1555bb16d227Schristos  /** 0111 011w 0000 dest  TST.size #IMM, dest */
1556bb16d227Schristos
1557bb16d227Schristos  UNARY_UOP;
1558bb16d227Schristos  imm = IMM(w);
1559bb16d227Schristos  tprintf ("%x & %x = %x\n", v, imm, v & imm);
1560bb16d227Schristos  v &= imm;
1561bb16d227Schristos  set_sz (v, w+1);
1562bb16d227Schristos
1563bb16d227Schristos  /** 1000 000w srcx dest  TST.size src,dest */
1564bb16d227Schristos
1565bb16d227Schristos  BINARY_UOP;
1566bb16d227Schristos  tprintf ("%x & %x = %x\n", a, b, a & b);
1567bb16d227Schristos  v = a & b;
1568bb16d227Schristos  set_sz (v, w+1);
1569bb16d227Schristos
1570bb16d227Schristos  /** 1111 1111            UND */
1571bb16d227Schristos
1572bb16d227Schristos  trigger_fixed_interrupt (0xffdc);
1573bb16d227Schristos
1574bb16d227Schristos  /** 0111 1101 1111 0011  WAIT */
1575bb16d227Schristos
1576bb16d227Schristos  tprintf("waiting...\n");
1577bb16d227Schristos
1578bb16d227Schristos  /** 0111 101w 00sr dest  XCHG.size src,dest */
1579bb16d227Schristos
1580bb16d227Schristos  sc = decode_srcdest4 (sr, w);
1581bb16d227Schristos  dc = decode_srcdest4 (dest, w);
1582bb16d227Schristos  a = get_src (sc);
1583bb16d227Schristos  b = get_src (dc);
1584bb16d227Schristos  put_dest (dc, a);
1585bb16d227Schristos  put_dest (sc, b);
1586bb16d227Schristos
1587bb16d227Schristos  /** 0111 011w 0001 dest  XOR.size #IMM,dest */
1588bb16d227Schristos
1589bb16d227Schristos  UNARY_UOP;
1590bb16d227Schristos  imm = IMM(w);
1591bb16d227Schristos  tprintf ("%x ^ %x = %x\n", v, imm, v ^ imm);
1592bb16d227Schristos  v ^= imm;
1593bb16d227Schristos  set_sz (v, w+1);
1594bb16d227Schristos  put_dest (dc, v);
1595bb16d227Schristos
1596bb16d227Schristos  /** 1000 100w srcx dest  XOR.size src,dest */
1597bb16d227Schristos
1598bb16d227Schristos  BINARY_UOP;
1599bb16d227Schristos  tprintf ("%x ^ %x = %x\n", a, b, a ^ b);
1600bb16d227Schristos  v = a ^ b;
1601bb16d227Schristos  set_sz (v, w+1);
1602bb16d227Schristos  put_dest (dc, v);
1603bb16d227Schristos
1604bb16d227Schristos  /**                      OP */
1605bb16d227Schristos/** */
1606bb16d227Schristos
1607bb16d227Schristos  return step_result;
1608bb16d227Schristos}
1609