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