xref: /netbsd-src/external/gpl3/gdb.old/dist/sim/m32c/srcdest.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1bb16d227Schristos /* srcdest.c --- decoding M32C addressing modes.
2bb16d227Schristos 
3*8b657b07Schristos Copyright (C) 2005-2023 Free Software Foundation, Inc.
4bb16d227Schristos Contributed by Red Hat, Inc.
5bb16d227Schristos 
6bb16d227Schristos This file is part of the GNU simulators.
7bb16d227Schristos 
8bb16d227Schristos This program is free software; you can redistribute it and/or modify
9bb16d227Schristos it under the terms of the GNU General Public License as published by
10bb16d227Schristos the Free Software Foundation; either version 3 of the License, or
11bb16d227Schristos (at your option) any later version.
12bb16d227Schristos 
13bb16d227Schristos This program is distributed in the hope that it will be useful,
14bb16d227Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
15bb16d227Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16bb16d227Schristos GNU General Public License for more details.
17bb16d227Schristos 
18bb16d227Schristos You should have received a copy of the GNU General Public License
19bb16d227Schristos along 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 
2799e23f81Schristos #include "libiberty.h"
28bb16d227Schristos #include "cpu.h"
29bb16d227Schristos #include "mem.h"
30bb16d227Schristos 
31bb16d227Schristos static int src_indirect = 0;
32bb16d227Schristos static int dest_indirect = 0;
33bb16d227Schristos static int src_addend = 0;
34bb16d227Schristos static int dest_addend = 0;
35bb16d227Schristos 
36bb16d227Schristos static int
37bb16d227Schristos disp8 (void)
38bb16d227Schristos {
39bb16d227Schristos   int rv;
40bb16d227Schristos   int tsave = trace;
41bb16d227Schristos 
42bb16d227Schristos   if (trace == 1)
43bb16d227Schristos     trace = 0;
44bb16d227Schristos   rv = mem_get_qi (get_reg (pc));
45bb16d227Schristos   regs.r_pc++;
46bb16d227Schristos   trace = tsave;
47bb16d227Schristos   return rv;
48bb16d227Schristos }
49bb16d227Schristos 
50bb16d227Schristos static int
51bb16d227Schristos disp16 (void)
52bb16d227Schristos {
53bb16d227Schristos   int rv;
54bb16d227Schristos   int tsave = trace;
55bb16d227Schristos 
56bb16d227Schristos   if (trace == 1)
57bb16d227Schristos     trace = 0;
58bb16d227Schristos   rv = mem_get_hi (get_reg (pc));
59bb16d227Schristos   regs.r_pc += 2;
60bb16d227Schristos   trace = tsave;
61bb16d227Schristos   return rv;
62bb16d227Schristos }
63bb16d227Schristos 
64bb16d227Schristos static int
65bb16d227Schristos disp24 (void)
66bb16d227Schristos {
67bb16d227Schristos   int rv;
68bb16d227Schristos   int tsave = trace;
69bb16d227Schristos 
70bb16d227Schristos   if (trace == 1)
71bb16d227Schristos     trace = 0;
72bb16d227Schristos   rv = mem_get_psi (get_reg (pc));
73bb16d227Schristos   regs.r_pc += 3;
74bb16d227Schristos   trace = tsave;
75bb16d227Schristos   return rv;
76bb16d227Schristos }
77bb16d227Schristos 
78bb16d227Schristos static int
79bb16d227Schristos disp20 (void)
80bb16d227Schristos {
81bb16d227Schristos   return disp24 () & 0x000fffff;
82bb16d227Schristos }
83bb16d227Schristos 
84bb16d227Schristos const char *
85bb16d227Schristos bits (int v, int b)
86bb16d227Schristos {
87bb16d227Schristos   static char buf[17];
88bb16d227Schristos   char *bp = buf + 16;
89bb16d227Schristos   *bp = 0;
90bb16d227Schristos   while (b)
91bb16d227Schristos     {
92bb16d227Schristos       *--bp = (v & 1) ? '1' : '0';
93bb16d227Schristos       v >>= 1;
94bb16d227Schristos       b--;
95bb16d227Schristos     }
96bb16d227Schristos   return bp;
97bb16d227Schristos }
98bb16d227Schristos 
99bb16d227Schristos static const char *the_bits = 0;
100bb16d227Schristos 
101bb16d227Schristos void
102bb16d227Schristos decode_indirect (int si, int di)
103bb16d227Schristos {
104bb16d227Schristos   src_indirect = si;
105bb16d227Schristos   dest_indirect = di;
106bb16d227Schristos   if (trace && (si || di))
107bb16d227Schristos     printf ("indirect: s:%d d:%d\n", si, di);
108bb16d227Schristos }
109bb16d227Schristos 
110bb16d227Schristos void
111bb16d227Schristos decode_index (int sa, int da)
112bb16d227Schristos {
113bb16d227Schristos   src_addend = sa;
114bb16d227Schristos   dest_addend = da;
115bb16d227Schristos   if (trace && (sa || da))
116bb16d227Schristos     printf ("index: s:%d d:%d\n", sa, da);
117bb16d227Schristos }
118bb16d227Schristos 
119bb16d227Schristos srcdest
120bb16d227Schristos decode_srcdest4 (int destcode, int bw)
121bb16d227Schristos {
122bb16d227Schristos   srcdest sd;
123bb16d227Schristos   static const char *dc_wnames[16] = { "r0", "r1", "r2", "r3",
124bb16d227Schristos     "a0", "a1", "[a0]", "[a1]",
125bb16d227Schristos     "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]",
126bb16d227Schristos     "disp16[a0]", "disp16[a1]", "disp16[sb]", "disp16"
127bb16d227Schristos   };
128bb16d227Schristos   static const char *dc_bnames[4] = { "r0l", "r0h", "r1l", "r1h" };;
129bb16d227Schristos 
130bb16d227Schristos   sd.bytes = bw ? 2 : 1;
131bb16d227Schristos   sd.mem = (destcode >= 6) ? 1 : 0;
132bb16d227Schristos 
133bb16d227Schristos   if (trace)
134bb16d227Schristos     {
135bb16d227Schristos       const char *n = dc_wnames[destcode];
136bb16d227Schristos       if (bw == 0 && destcode <= 3)
137bb16d227Schristos 	n = dc_bnames[destcode];
138bb16d227Schristos       if (!the_bits)
139bb16d227Schristos 	the_bits = bits (destcode, 4);
140bb16d227Schristos       printf ("decode: %s (%d) : %s\n", the_bits, destcode, n);
141bb16d227Schristos       the_bits = 0;
142bb16d227Schristos     }
143bb16d227Schristos 
144bb16d227Schristos   switch (destcode)
145bb16d227Schristos     {
146bb16d227Schristos     case 0x0:
147bb16d227Schristos       sd.u.reg = bw ? r0 : r0l;
148bb16d227Schristos       break;
149bb16d227Schristos     case 0x1:
150bb16d227Schristos       sd.u.reg = bw ? r1 : r0h;
151bb16d227Schristos       break;
152bb16d227Schristos     case 0x2:
153bb16d227Schristos       sd.u.reg = bw ? r2 : r1l;
154bb16d227Schristos       break;
155bb16d227Schristos     case 0x3:
156bb16d227Schristos       sd.u.reg = bw ? r3 : r1h;
157bb16d227Schristos       break;
158bb16d227Schristos     case 0x4:
159bb16d227Schristos       sd.u.reg = a0;
160bb16d227Schristos       break;
161bb16d227Schristos     case 0x5:
162bb16d227Schristos       sd.u.reg = a1;
163bb16d227Schristos       break;
164bb16d227Schristos     case 0x6:
165bb16d227Schristos       sd.u.addr = get_reg (a0);
166bb16d227Schristos       break;
167bb16d227Schristos     case 0x7:
168bb16d227Schristos       sd.u.addr = get_reg (a1);
169bb16d227Schristos       break;
170bb16d227Schristos     case 0x8:
171bb16d227Schristos       sd.u.addr = get_reg (a0) + disp8 ();
172bb16d227Schristos       break;
173bb16d227Schristos     case 0x9:
174bb16d227Schristos       sd.u.addr = get_reg (a1) + disp8 ();
175bb16d227Schristos       break;
176bb16d227Schristos     case 0xa:
177bb16d227Schristos       sd.u.addr = get_reg (sb) + disp8 ();
178bb16d227Schristos       break;
179bb16d227Schristos     case 0xb:
180bb16d227Schristos       sd.u.addr = get_reg (fb) + sign_ext (disp8 (), 8);
181bb16d227Schristos       break;
182bb16d227Schristos     case 0xc:
183bb16d227Schristos       sd.u.addr = get_reg (a0) + disp16 ();
184bb16d227Schristos       break;
185bb16d227Schristos     case 0xd:
186bb16d227Schristos       sd.u.addr = get_reg (a1) + disp16 ();
187bb16d227Schristos       break;
188bb16d227Schristos     case 0xe:
189bb16d227Schristos       sd.u.addr = get_reg (sb) + disp16 ();
190bb16d227Schristos       break;
191bb16d227Schristos     case 0xf:
192bb16d227Schristos       sd.u.addr = disp16 ();
193bb16d227Schristos       break;
194bb16d227Schristos     default:
195bb16d227Schristos       abort ();
196bb16d227Schristos     }
197bb16d227Schristos   if (sd.mem)
198bb16d227Schristos     sd.u.addr &= addr_mask;
199bb16d227Schristos   return sd;
200bb16d227Schristos }
201bb16d227Schristos 
202bb16d227Schristos srcdest
203bb16d227Schristos decode_jumpdest (int destcode, int w)
204bb16d227Schristos {
205bb16d227Schristos   srcdest sd;
206bb16d227Schristos   static const char *dc_wnames[16] = { "r0", "r1", "r2", "r3",
207bb16d227Schristos     "a0", "a1", "[a0]", "[a1]",
208bb16d227Schristos     "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]",
209bb16d227Schristos     "disp20[a0]", "disp20[a1]", "disp16[sb]", "abs16"
210bb16d227Schristos   };
211bb16d227Schristos   static const char *dc_anames[4] = { "r0l", "r0h", "r1l", "r1h" };
212bb16d227Schristos 
213bb16d227Schristos   sd.bytes = w ? 2 : 3;
214bb16d227Schristos   sd.mem = (destcode >= 6) ? 1 : 0;
215bb16d227Schristos 
216bb16d227Schristos   if (trace)
217bb16d227Schristos     {
218bb16d227Schristos       const char *n = dc_wnames[destcode];
219bb16d227Schristos       if (w == 0 && destcode <= 3)
220bb16d227Schristos 	n = dc_anames[destcode];
221bb16d227Schristos       if (!the_bits)
222bb16d227Schristos 	the_bits = bits (destcode, 4);
223bb16d227Schristos       printf ("decode: %s : %s\n", the_bits, n);
224bb16d227Schristos       the_bits = 0;
225bb16d227Schristos     }
226bb16d227Schristos 
227bb16d227Schristos   switch (destcode)
228bb16d227Schristos     {
229bb16d227Schristos     case 0x0:
230bb16d227Schristos       sd.u.reg = w ? r0 : r2r0;
231bb16d227Schristos       break;
232bb16d227Schristos     case 0x1:
233bb16d227Schristos       sd.u.reg = w ? r1 : r2r0;
234bb16d227Schristos       break;
235bb16d227Schristos     case 0x2:
236bb16d227Schristos       sd.u.reg = w ? r2 : r3r1;
237bb16d227Schristos       break;
238bb16d227Schristos     case 0x3:
239bb16d227Schristos       sd.u.reg = w ? r3 : r3r1;
240bb16d227Schristos       break;
241bb16d227Schristos     case 0x4:
242bb16d227Schristos       sd.u.reg = w ? a0 : a1a0;
243bb16d227Schristos       break;
244bb16d227Schristos     case 0x5:
245bb16d227Schristos       sd.u.reg = w ? a1 : a1a0;
246bb16d227Schristos       break;
247bb16d227Schristos     case 0x6:
248bb16d227Schristos       sd.u.addr = get_reg (a0);
249bb16d227Schristos       break;
250bb16d227Schristos     case 0x7:
251bb16d227Schristos       sd.u.addr = get_reg (a1);
252bb16d227Schristos       break;
253bb16d227Schristos     case 0x8:
254bb16d227Schristos       sd.u.addr = get_reg (a0) + disp8 ();
255bb16d227Schristos       break;
256bb16d227Schristos     case 0x9:
257bb16d227Schristos       sd.u.addr = get_reg (a1) + disp8 ();
258bb16d227Schristos       break;
259bb16d227Schristos     case 0xa:
260bb16d227Schristos       sd.u.addr = get_reg (sb) + disp8 ();
261bb16d227Schristos       break;
262bb16d227Schristos     case 0xb:
263bb16d227Schristos       sd.u.addr = get_reg (fb) + sign_ext (disp8 (), 8);
264bb16d227Schristos       break;
265bb16d227Schristos     case 0xc:
266bb16d227Schristos       sd.u.addr = get_reg (a0) + disp20 ();
267bb16d227Schristos       break;
268bb16d227Schristos     case 0xd:
269bb16d227Schristos       sd.u.addr = get_reg (a1) + disp20 ();
270bb16d227Schristos       break;
271bb16d227Schristos     case 0xe:
272bb16d227Schristos       sd.u.addr = get_reg (sb) + disp16 ();
273bb16d227Schristos       break;
274bb16d227Schristos     case 0xf:
275bb16d227Schristos       sd.u.addr = disp16 ();
276bb16d227Schristos       break;
277bb16d227Schristos     default:
278bb16d227Schristos       abort ();
279bb16d227Schristos     }
280bb16d227Schristos   if (sd.mem)
281bb16d227Schristos     sd.u.addr &= addr_mask;
282bb16d227Schristos   return sd;
283bb16d227Schristos }
284bb16d227Schristos 
285bb16d227Schristos srcdest
286bb16d227Schristos decode_dest3 (int destcode, int bw)
287bb16d227Schristos {
288bb16d227Schristos   static char map[8] = { -1, -1, -1, 1, 0, 10, 11, 15 };
289bb16d227Schristos 
290bb16d227Schristos   the_bits = bits (destcode, 3);
291bb16d227Schristos   return decode_srcdest4 (map[destcode], bw);
292bb16d227Schristos }
293bb16d227Schristos 
294bb16d227Schristos srcdest
295bb16d227Schristos decode_src2 (int srccode, int bw, int d)
296bb16d227Schristos {
297bb16d227Schristos   static char map[4] = { 0, 10, 11, 15 };
298bb16d227Schristos 
299bb16d227Schristos   the_bits = bits (srccode, 2);
300bb16d227Schristos   return decode_srcdest4 (srccode ? map[srccode] : 1 - d, bw);
301bb16d227Schristos }
302bb16d227Schristos 
303bb16d227Schristos static struct
304bb16d227Schristos {
305bb16d227Schristos   reg_id b_regno;
306bb16d227Schristos   reg_id w_regno;
307bb16d227Schristos   int is_memory;
308bb16d227Schristos   int disp_bytes;
309bb16d227Schristos   char *name;
310bb16d227Schristos } modes23[] =
311bb16d227Schristos {
312bb16d227Schristos   {
313bb16d227Schristos   a0, a0, 1, 0, "[A0]"},	/* 0 0 0 0 0 */
314bb16d227Schristos   {
315bb16d227Schristos   a1, a1, 1, 0, "[A1]"},	/* 0 0 0 0 1 */
316bb16d227Schristos   {
317bb16d227Schristos   a0, a0, 0, 0, "A0"},		/* 0 0 0 1 0 */
318bb16d227Schristos   {
319bb16d227Schristos   a1, a1, 0, 0, "A1"},		/* 0 0 0 1 1 */
320bb16d227Schristos   {
321bb16d227Schristos   a0, a0, 1, 1, "dsp:8[A0]"},	/* 0 0 1 0 0 */
322bb16d227Schristos   {
323bb16d227Schristos   a1, a1, 1, 1, "dsp:8[A1]"},	/* 0 0 1 0 1 */
324bb16d227Schristos   {
325bb16d227Schristos   sb, sb, 1, 1, "dsp:8[SB]"},	/* 0 0 1 1 0 */
326bb16d227Schristos   {
327bb16d227Schristos   fb, fb, 1, -1, "dsp:8[FB]"},	/* 0 0 1 1 1 */
328bb16d227Schristos   {
329bb16d227Schristos   a0, a0, 1, 2, "dsp:16[A0]"},	/* 0 1 0 0 0 */
330bb16d227Schristos   {
331bb16d227Schristos   a1, a1, 1, 2, "dsp:16[A1]"},	/* 0 1 0 0 1 */
332bb16d227Schristos   {
333bb16d227Schristos   sb, sb, 1, 2, "dsp:16[SB]"},	/* 0 1 0 1 0 */
334bb16d227Schristos   {
335bb16d227Schristos   fb, fb, 1, -2, "dsp:16[FB]"},	/* 0 1 0 1 1 */
336bb16d227Schristos   {
337bb16d227Schristos   a0, a0, 1, 3, "dsp:24[A0]"},	/* 0 1 1 0 0 */
338bb16d227Schristos   {
339bb16d227Schristos   a1, a1, 1, 3, "dsp:24[A1]"},	/* 0 1 1 0 1 */
340bb16d227Schristos   {
341bb16d227Schristos   mem, mem, 1, 3, "abs24"},	/* 0 1 1 1 0 */
342bb16d227Schristos   {
343bb16d227Schristos   mem, mem, 1, 2, "abs16"},	/* 0 1 1 1 1 */
344bb16d227Schristos   {
345bb16d227Schristos   r0h, r2, 0, 0, "R0H/R2"},	/* 1 0 0 0 0 */
346bb16d227Schristos   {
347bb16d227Schristos   r1h, r3, 0, 0, "R1H/R3"},	/* 1 0 0 0 1 */
348bb16d227Schristos   {
349bb16d227Schristos   r0l, r0, 0, 0, "R0L/R0"},	/* 1 0 0 1 0 */
350bb16d227Schristos   {
351bb16d227Schristos   r1l, r1, 0, 0, "R1L/R1"},	/* 1 0 0 1 1 */
352bb16d227Schristos };
353bb16d227Schristos 
354bb16d227Schristos static srcdest
355bb16d227Schristos decode_sd23 (int bbb, int bb, int bytes, int ind, int add)
356bb16d227Schristos {
357bb16d227Schristos   srcdest sd;
358bb16d227Schristos   int code = (bbb << 2) | bb;
359bb16d227Schristos 
36099e23f81Schristos   if (code >= ARRAY_SIZE (modes23))
361bb16d227Schristos     abort ();
362bb16d227Schristos 
363bb16d227Schristos   if (trace)
364bb16d227Schristos     {
365bb16d227Schristos       char *b1 = "";
366bb16d227Schristos       char *b2 = "";
367bb16d227Schristos       char ad[30];
368bb16d227Schristos       if (ind)
369bb16d227Schristos 	{
370bb16d227Schristos 	  b1 = "[";
371bb16d227Schristos 	  b2 = "]";
372bb16d227Schristos 	}
373bb16d227Schristos       if (add)
374bb16d227Schristos 	sprintf (ad, "%+d", add);
375bb16d227Schristos       else
376bb16d227Schristos 	ad[0] = 0;
377bb16d227Schristos       if (!the_bits)
378bb16d227Schristos 	the_bits = bits (code, 4);
379bb16d227Schristos       printf ("decode: %s (%d) : %s%s%s%s\n", the_bits, code, b1,
380bb16d227Schristos 	      modes23[code].name, ad, b2);
381bb16d227Schristos       the_bits = 0;
382bb16d227Schristos     }
383bb16d227Schristos 
384bb16d227Schristos   sd.bytes = bytes;
385bb16d227Schristos   sd.mem = modes23[code].is_memory;
386bb16d227Schristos   if (sd.mem)
387bb16d227Schristos     {
388bb16d227Schristos       if (modes23[code].w_regno == mem)
389bb16d227Schristos 	sd.u.addr = 0;
390bb16d227Schristos       else
391bb16d227Schristos 	sd.u.addr = get_reg (modes23[code].w_regno);
392bb16d227Schristos       switch (modes23[code].disp_bytes)
393bb16d227Schristos 	{
394bb16d227Schristos 	case 1:
395bb16d227Schristos 	  sd.u.addr += disp8 ();
396bb16d227Schristos 	  break;
397bb16d227Schristos 	case 2:
398bb16d227Schristos 	  sd.u.addr += disp16 ();
399bb16d227Schristos 	  break;
400bb16d227Schristos 	case -1:
401bb16d227Schristos 	  sd.u.addr += sign_ext (disp8 (), 8);
402bb16d227Schristos 	  break;
403bb16d227Schristos 	case -2:
404bb16d227Schristos 	  sd.u.addr += sign_ext (disp16 (), 16);
405bb16d227Schristos 	  break;
406bb16d227Schristos 	case 3:
407bb16d227Schristos 	  sd.u.addr += disp24 ();
408bb16d227Schristos 	  break;
409bb16d227Schristos 	default:
410bb16d227Schristos 	  break;
411bb16d227Schristos 	}
412bb16d227Schristos       if (add)
413bb16d227Schristos 	sd.u.addr += add;
414bb16d227Schristos       if (ind)
415bb16d227Schristos 	sd.u.addr = mem_get_si (sd.u.addr & membus_mask);
416bb16d227Schristos       sd.u.addr &= membus_mask;
417bb16d227Schristos     }
418bb16d227Schristos   else
419bb16d227Schristos     {
420bb16d227Schristos       sd.u.reg = (bytes > 1) ? modes23[code].w_regno : modes23[code].b_regno;
421bb16d227Schristos       if (bytes == 3 || bytes == 4)
422bb16d227Schristos 	{
423bb16d227Schristos 	  switch (sd.u.reg)
424bb16d227Schristos 	    {
425bb16d227Schristos 	    case r0:
426bb16d227Schristos 	      sd.u.reg = r2r0;
427bb16d227Schristos 	      break;
428bb16d227Schristos 	    case r1:
429bb16d227Schristos 	      sd.u.reg = r3r1;
430bb16d227Schristos 	      break;
431bb16d227Schristos 	    case r2:
432bb16d227Schristos 	      abort ();
433bb16d227Schristos 	    case r3:
434bb16d227Schristos 	      abort ();
435bb16d227Schristos 	    default:;
436bb16d227Schristos 	    }
437bb16d227Schristos 	}
438bb16d227Schristos 
439bb16d227Schristos     }
440bb16d227Schristos   return sd;
441bb16d227Schristos }
442bb16d227Schristos 
443bb16d227Schristos srcdest
444bb16d227Schristos decode_dest23 (int ddd, int dd, int bytes)
445bb16d227Schristos {
446bb16d227Schristos   return decode_sd23 (ddd, dd, bytes, dest_indirect, dest_addend);
447bb16d227Schristos }
448bb16d227Schristos 
449bb16d227Schristos srcdest
450bb16d227Schristos decode_src23 (int sss, int ss, int bytes)
451bb16d227Schristos {
452bb16d227Schristos   return decode_sd23 (sss, ss, bytes, src_indirect, src_addend);
453bb16d227Schristos }
454bb16d227Schristos 
455bb16d227Schristos srcdest
456bb16d227Schristos decode_dest2 (int dd, int bytes)
457bb16d227Schristos {
458bb16d227Schristos   /* r0l/r0, abs16, dsp:8[SB], dsp:8[FB] */
459bb16d227Schristos   static char map[4] = { 0x12, 0x0f, 0x06, 0x07 };
460bb16d227Schristos 
461bb16d227Schristos   the_bits = bits (dd, 2);
462bb16d227Schristos   return decode_sd23 (map[dd] >> 2, map[dd] & 3, bytes, dest_indirect,
463bb16d227Schristos 		      dest_addend);
464bb16d227Schristos }
465bb16d227Schristos 
466bb16d227Schristos srcdest
467bb16d227Schristos decode_src3 (int sss, int bytes)
468bb16d227Schristos {
469bb16d227Schristos   /* r0, r1, a0, a1, r2, r3, N/A, N/A */
470bb16d227Schristos   static char map[8] = { 0x12, 0x13, 0x02, 0x03, 0x10, 0x11, 0, 0 };
471bb16d227Schristos 
472bb16d227Schristos   the_bits = bits (sss, 3);
473bb16d227Schristos   return decode_sd23 (map[sss] >> 2, map[sss] & 3, bytes, src_indirect,
474bb16d227Schristos 		      src_addend);
475bb16d227Schristos }
476bb16d227Schristos 
477bb16d227Schristos srcdest
478bb16d227Schristos decode_dest1 (int destcode, int bw)
479bb16d227Schristos {
480bb16d227Schristos   the_bits = bits (destcode, 1);
481bb16d227Schristos   return decode_srcdest4 (destcode, bw);
482bb16d227Schristos }
483bb16d227Schristos 
484bb16d227Schristos srcdest
485bb16d227Schristos decode_cr (int crcode)
486bb16d227Schristos {
487bb16d227Schristos   static int regcode[] = { 0, intbl, intbh, flags, isp, sp, sb, fb };
488bb16d227Schristos   srcdest sd;
489bb16d227Schristos   sd.mem = 0;
490bb16d227Schristos   sd.bytes = 2;
491bb16d227Schristos   sd.u.reg = regcode[crcode & 7];
492bb16d227Schristos   return sd;
493bb16d227Schristos }
494bb16d227Schristos 
495bb16d227Schristos srcdest
496bb16d227Schristos decode_cr_b (int crcode, int bank)
497bb16d227Schristos {
498bb16d227Schristos   /* FIXME: intbl, intbh, isp */
499bb16d227Schristos   static int regcode[3][8] = {
500bb16d227Schristos     {0, 0, flags, 0, 0, 0, 0, 0},
501bb16d227Schristos     {intb, sp, sb, fb, 0, 0, 0, isp},
502bb16d227Schristos     {0, 0, 0, 0, 0, 0, 0, 0}
503bb16d227Schristos   };
504bb16d227Schristos   srcdest sd;
505bb16d227Schristos   sd.mem = 0;
506bb16d227Schristos   sd.bytes = bank ? 3 : 2;
507bb16d227Schristos   sd.u.reg = regcode[bank][crcode & 7];
508bb16d227Schristos   return sd;
509bb16d227Schristos }
510bb16d227Schristos 
511bb16d227Schristos srcdest
512bb16d227Schristos widen_sd (srcdest sd)
513bb16d227Schristos {
514bb16d227Schristos   sd.bytes *= 2;
515bb16d227Schristos   if (!sd.mem)
516bb16d227Schristos     switch (sd.u.reg)
517bb16d227Schristos       {
518bb16d227Schristos       case r0l:
519bb16d227Schristos 	sd.u.reg = r0;
520bb16d227Schristos 	break;
521bb16d227Schristos       case r0:
522bb16d227Schristos 	sd.u.reg = r2r0;
523bb16d227Schristos 	break;
524bb16d227Schristos       case r1l:
525bb16d227Schristos 	sd.u.reg = r1;
526bb16d227Schristos 	break;
527bb16d227Schristos       case r1:
528bb16d227Schristos 	sd.u.reg = r3r1;
529bb16d227Schristos 	break;
530bb16d227Schristos       case a0:
531bb16d227Schristos 	if (A16)
532bb16d227Schristos 	  sd.u.reg = a1a0;
533bb16d227Schristos 	break;
534bb16d227Schristos       default:
535bb16d227Schristos 	break;
536bb16d227Schristos       }
537bb16d227Schristos   return sd;
538bb16d227Schristos }
539bb16d227Schristos 
540bb16d227Schristos srcdest
541bb16d227Schristos reg_sd (reg_id reg)
542bb16d227Schristos {
543bb16d227Schristos   srcdest rv;
544bb16d227Schristos   rv.bytes = reg_bytes[reg];
545bb16d227Schristos   rv.mem = 0;
546bb16d227Schristos   rv.u.reg = reg;
547bb16d227Schristos   return rv;
548bb16d227Schristos }
549bb16d227Schristos 
550bb16d227Schristos int
551bb16d227Schristos get_src (srcdest sd)
552bb16d227Schristos {
553bb16d227Schristos   int v;
554bb16d227Schristos   if (sd.mem)
555bb16d227Schristos     {
556bb16d227Schristos       switch (sd.bytes)
557bb16d227Schristos 	{
558bb16d227Schristos 	case 1:
559bb16d227Schristos 	  v = mem_get_qi (sd.u.addr);
560bb16d227Schristos 	  break;
561bb16d227Schristos 	case 2:
562bb16d227Schristos 	  v = mem_get_hi (sd.u.addr);
563bb16d227Schristos 	  break;
564bb16d227Schristos 	case 3:
565bb16d227Schristos 	  v = mem_get_psi (sd.u.addr);
566bb16d227Schristos 	  break;
567bb16d227Schristos 	case 4:
568bb16d227Schristos 	  v = mem_get_si (sd.u.addr);
569bb16d227Schristos 	  break;
570bb16d227Schristos 	default:
571bb16d227Schristos 	  abort ();
572bb16d227Schristos 	}
573bb16d227Schristos     }
574bb16d227Schristos   else
575bb16d227Schristos     {
576bb16d227Schristos       v = get_reg (sd.u.reg);
577bb16d227Schristos       switch (sd.bytes)
578bb16d227Schristos 	{
579bb16d227Schristos 	case 1:
580bb16d227Schristos 	  v &= 0xff;
581bb16d227Schristos 	  break;
582bb16d227Schristos 	case 2:
583bb16d227Schristos 	  v &= 0xffff;
584bb16d227Schristos 	  break;
585bb16d227Schristos 	case 3:
586bb16d227Schristos 	  v &= 0xffffff;
587bb16d227Schristos 	  break;
588bb16d227Schristos 	}
589bb16d227Schristos     }
590bb16d227Schristos   return v;
591bb16d227Schristos }
592bb16d227Schristos 
593bb16d227Schristos void
594bb16d227Schristos put_dest (srcdest sd, int v)
595bb16d227Schristos {
596bb16d227Schristos   if (sd.mem)
597bb16d227Schristos     {
598bb16d227Schristos       switch (sd.bytes)
599bb16d227Schristos 	{
600bb16d227Schristos 	case 1:
601bb16d227Schristos 	  mem_put_qi (sd.u.addr, v);
602bb16d227Schristos 	  break;
603bb16d227Schristos 	case 2:
604bb16d227Schristos 	  mem_put_hi (sd.u.addr, v);
605bb16d227Schristos 	  break;
606bb16d227Schristos 	case 3:
607bb16d227Schristos 	  mem_put_psi (sd.u.addr, v);
608bb16d227Schristos 	  break;
609bb16d227Schristos 	case 4:
610bb16d227Schristos 	  mem_put_si (sd.u.addr, v);
611bb16d227Schristos 	  break;
612bb16d227Schristos 	}
613bb16d227Schristos     }
614bb16d227Schristos   else
615bb16d227Schristos     {
616bb16d227Schristos       switch (sd.bytes)
617bb16d227Schristos 	{
618bb16d227Schristos 	case 1:
619bb16d227Schristos 	  v &= 0xff;
620bb16d227Schristos 	  break;
621bb16d227Schristos 	case 2:
622bb16d227Schristos 	  v &= 0xffff;
623bb16d227Schristos 	  break;
624bb16d227Schristos 	case 3:
625bb16d227Schristos 	  v &= 0xffffff;
626bb16d227Schristos 	  break;
627bb16d227Schristos 	}
628bb16d227Schristos       put_reg (sd.u.reg, v);
629bb16d227Schristos     }
630bb16d227Schristos }
631bb16d227Schristos 
632bb16d227Schristos srcdest
633bb16d227Schristos decode_bit (int destcode)
634bb16d227Schristos {
635bb16d227Schristos   srcdest sd;
636bb16d227Schristos   int addr = 0;
637bb16d227Schristos   static const char *dc_names[] = { "r0", "r1", "r2", "r3",
638bb16d227Schristos     "a0", "a1", "[a0]", "[a1]",
639bb16d227Schristos     "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]",
640bb16d227Schristos     "disp16[a0]", "disp16[a1]", "disp16[sb]", "abs16"
641bb16d227Schristos   };
642bb16d227Schristos 
643bb16d227Schristos   if (trace)
644bb16d227Schristos     {
645bb16d227Schristos       const char *the_bits = bits (destcode, 4);
646bb16d227Schristos       printf ("decode: %s : %s\n", the_bits, dc_names[destcode]);
647bb16d227Schristos     }
648bb16d227Schristos 
649bb16d227Schristos   switch (destcode)
650bb16d227Schristos     {
651bb16d227Schristos     case 0:
652bb16d227Schristos       sd.u.reg = r0;
653bb16d227Schristos       break;
654bb16d227Schristos     case 1:
655bb16d227Schristos       sd.u.reg = r1;
656bb16d227Schristos       break;
657bb16d227Schristos     case 2:
658bb16d227Schristos       sd.u.reg = r2;
659bb16d227Schristos       break;
660bb16d227Schristos     case 3:
661bb16d227Schristos       sd.u.reg = r3;
662bb16d227Schristos       break;
663bb16d227Schristos     case 4:
664bb16d227Schristos       sd.u.reg = a0;
665bb16d227Schristos       break;
666bb16d227Schristos     case 5:
667bb16d227Schristos       sd.u.reg = a1;
668bb16d227Schristos       break;
669bb16d227Schristos     case 6:
670bb16d227Schristos       addr = get_reg (a0);
671bb16d227Schristos       break;
672bb16d227Schristos     case 7:
673bb16d227Schristos       addr = get_reg (a1);
674bb16d227Schristos       break;
675bb16d227Schristos     case 8:
676bb16d227Schristos       addr = get_reg (a0) + disp8 ();
677bb16d227Schristos       break;
678bb16d227Schristos     case 9:
679bb16d227Schristos       addr = get_reg (a1) + disp8 ();
680bb16d227Schristos       break;
681bb16d227Schristos     case 10:
682bb16d227Schristos       addr = get_reg (sb) * 8 + disp8 ();
683bb16d227Schristos       break;
684bb16d227Schristos     case 11:
685bb16d227Schristos       addr = get_reg (fb) * 8 + sign_ext (disp8 (), 8);
686bb16d227Schristos       break;
687bb16d227Schristos     case 12:
688bb16d227Schristos       addr = get_reg (a0) + disp16 ();
689bb16d227Schristos       break;
690bb16d227Schristos     case 13:
691bb16d227Schristos       addr = get_reg (a1) + disp16 ();
692bb16d227Schristos       break;
693bb16d227Schristos     case 14:
694bb16d227Schristos       addr = get_reg (sb) + disp16 ();
695bb16d227Schristos       break;
696bb16d227Schristos     case 15:
697bb16d227Schristos       addr = disp16 ();
698bb16d227Schristos       break;
699bb16d227Schristos     }
700bb16d227Schristos 
701bb16d227Schristos   if (destcode < 6)
702bb16d227Schristos     {
703bb16d227Schristos       int d = disp8 ();
704bb16d227Schristos       sd.mem = 0;
705bb16d227Schristos       sd.mask = 1 << (d & 0x0f);
706bb16d227Schristos     }
707bb16d227Schristos   else
708bb16d227Schristos     {
709bb16d227Schristos       addr &= addr_mask;
710bb16d227Schristos       sd.mem = 1;
711bb16d227Schristos       sd.mask = 1 << (addr & 7);
712bb16d227Schristos       sd.u.addr = addr >> 3;
713bb16d227Schristos     }
714bb16d227Schristos   return sd;
715bb16d227Schristos }
716bb16d227Schristos 
717bb16d227Schristos srcdest
718bb16d227Schristos decode_bit11 (int op0)
719bb16d227Schristos {
720bb16d227Schristos   srcdest sd;
721bb16d227Schristos   sd.mask = 1 << (op0 & 7);
722bb16d227Schristos   sd.mem = 1;
723bb16d227Schristos   sd.u.addr = get_reg (sb) + disp8 ();
724bb16d227Schristos   return sd;
725bb16d227Schristos }
726bb16d227Schristos 
727bb16d227Schristos int
728bb16d227Schristos get_bit (srcdest sd)
729bb16d227Schristos {
730bb16d227Schristos   int b;
731bb16d227Schristos   if (sd.mem)
732bb16d227Schristos     b = mem_get_qi (sd.u.addr) & sd.mask;
733bb16d227Schristos   else
734bb16d227Schristos     b = get_reg (sd.u.reg) & sd.mask;
735bb16d227Schristos   return b ? 1 : 0;
736bb16d227Schristos }
737bb16d227Schristos 
738bb16d227Schristos void
739bb16d227Schristos put_bit (srcdest sd, int val)
740bb16d227Schristos {
741bb16d227Schristos   int b;
742bb16d227Schristos   if (sd.mem)
743bb16d227Schristos     b = mem_get_qi (sd.u.addr);
744bb16d227Schristos   else
745bb16d227Schristos     b = get_reg (sd.u.reg);
746bb16d227Schristos   if (val)
747bb16d227Schristos     b |= sd.mask;
748bb16d227Schristos   else
749bb16d227Schristos     b &= ~sd.mask;
750bb16d227Schristos   if (sd.mem)
751bb16d227Schristos     mem_put_qi (sd.u.addr, b);
752bb16d227Schristos   else
753bb16d227Schristos     put_reg (sd.u.reg, b);
754bb16d227Schristos }
755bb16d227Schristos 
756bb16d227Schristos int
757bb16d227Schristos get_bit2 (srcdest sd, int bit)
758bb16d227Schristos {
759bb16d227Schristos   int b;
760bb16d227Schristos   if (sd.mem)
761bb16d227Schristos     b = mem_get_qi (sd.u.addr + (bit >> 3)) & (1 << (bit & 7));
762bb16d227Schristos   else
763bb16d227Schristos     b = get_reg (sd.u.reg) & (1 << bit);
764bb16d227Schristos   return b ? 1 : 0;
765bb16d227Schristos }
766bb16d227Schristos 
767bb16d227Schristos void
768bb16d227Schristos put_bit2 (srcdest sd, int bit, int val)
769bb16d227Schristos {
770bb16d227Schristos   int b;
771bb16d227Schristos   if (sd.mem)
772bb16d227Schristos     b = mem_get_qi (sd.u.addr + (bit >> 3));
773bb16d227Schristos   else
774bb16d227Schristos     b = get_reg (sd.u.reg);
775bb16d227Schristos   if (val)
776bb16d227Schristos     b |= (1 << (bit & 7));
777bb16d227Schristos   else
778bb16d227Schristos     b &= ~(1 << (bit & 7));
779bb16d227Schristos   if (sd.mem)
780bb16d227Schristos     mem_put_qi (sd.u.addr + (bit >> 3), b);
781bb16d227Schristos   else
782bb16d227Schristos     put_reg (sd.u.reg, b);
783bb16d227Schristos }
784