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