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