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