compile.c revision 1.8 1 1.1 christos /*
2 1.1 christos * Simulator for the Renesas (formerly Hitachi) H8/300 architecture.
3 1.1 christos *
4 1.1 christos * Written by Steve Chamberlain of Cygnus Support. sac (at) cygnus.com
5 1.1 christos *
6 1.1 christos * This file is part of H8/300 sim
7 1.1 christos *
8 1.1 christos *
9 1.1 christos * THIS SOFTWARE IS NOT COPYRIGHTED
10 1.1 christos *
11 1.1 christos * Cygnus offers the following for use in the public domain. Cygnus makes no
12 1.1 christos * warranty with regard to the software or its performance and the user
13 1.1 christos * accepts the software "AS IS" with all faults.
14 1.1 christos *
15 1.1 christos * CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS
16 1.1 christos * SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
17 1.1 christos * AND FITNESS FOR A PARTICULAR PURPOSE.
18 1.1 christos */
19 1.1 christos
20 1.7 christos /* This must come before any other includes. */
21 1.7 christos #include "defs.h"
22 1.7 christos
23 1.1 christos #include <signal.h>
24 1.1 christos #include <time.h>
25 1.1 christos #include <stdlib.h>
26 1.1 christos #ifdef HAVE_SYS_PARAM_H
27 1.1 christos #include <sys/param.h>
28 1.1 christos #endif
29 1.8 christos #include <sys/stat.h>
30 1.1 christos
31 1.1 christos #include "bfd.h"
32 1.1 christos #include "sim-main.h"
33 1.8 christos #include "sim/sim-h8300.h"
34 1.1 christos #include "sys/types.h"
35 1.5 christos #include "sim-options.h"
36 1.7 christos #include "sim-signal.h"
37 1.7 christos #include "sim/callback.h"
38 1.1 christos
39 1.8 christos #include "h8300-sim.h"
40 1.8 christos
41 1.1 christos #ifndef SIGTRAP
42 1.1 christos # define SIGTRAP 5
43 1.1 christos #endif
44 1.1 christos
45 1.1 christos int debug;
46 1.1 christos
47 1.8 christos /* Each entry in this array is an index into the main opcode
48 1.8 christos array for the first instruction starting with the given
49 1.8 christos 4 bit nibble. */
50 1.8 christos static int nib_indices[16];
51 1.8 christos
52 1.7 christos static int memory_size;
53 1.1 christos
54 1.1 christos #define X(op, size) (op * 4 + size)
55 1.1 christos
56 1.1 christos #define SP (h8300hmode && !h8300_normal_mode ? SL : SW)
57 1.1 christos
58 1.1 christos #define h8_opcodes ops
59 1.1 christos #define DEFINE_TABLE
60 1.1 christos #include "opcode/h8300.h"
61 1.1 christos
62 1.1 christos /* CPU data object: */
63 1.1 christos
64 1.1 christos static unsigned int
65 1.7 christos h8_get_reg (sim_cpu *cpu, int regnum)
66 1.1 christos {
67 1.8 christos return H8300_SIM_CPU (cpu)->regs[regnum];
68 1.1 christos }
69 1.1 christos
70 1.1 christos static void
71 1.7 christos h8_set_reg (sim_cpu *cpu, int regnum, int val)
72 1.1 christos {
73 1.8 christos H8300_SIM_CPU (cpu)->regs[regnum] = val;
74 1.1 christos }
75 1.1 christos
76 1.7 christos #define h8_get_ccr(cpu) h8_get_reg (cpu, CCR_REGNUM)
77 1.7 christos #define h8_set_ccr(cpu, val) h8_set_reg (cpu, CCR_REGNUM, val)
78 1.7 christos #define h8_get_exr(cpu) h8_get_reg (cpu, EXR_REGNUM)
79 1.7 christos #define h8_set_exr(cpu, val) h8_set_reg (cpu, EXR_REGNUM, val)
80 1.7 christos #define h8_get_sbr(cpu) h8_get_reg (cpu, SBR_REGNUM)
81 1.7 christos #define h8_set_sbr(cpu, val) h8_set_reg (cpu, SBR_REGNUM, val)
82 1.7 christos #define h8_get_vbr(cpu) h8_get_reg (cpu, VBR_REGNUM)
83 1.7 christos #define h8_set_vbr(cpu, val) h8_set_reg (cpu, VBR_REGNUM, val)
84 1.7 christos #define h8_get_cycles(cpu) h8_get_reg (cpu, CYCLE_REGNUM)
85 1.7 christos #define h8_set_cycles(cpu, val) h8_set_reg (cpu, CYCLE_REGNUM, val)
86 1.7 christos #define h8_get_insts(cpu) h8_get_reg (cpu, INST_REGNUM)
87 1.7 christos #define h8_set_insts(cpu, val) h8_set_reg (cpu, INST_REGNUM, val)
88 1.7 christos #define h8_get_ticks(cpu) h8_get_reg (cpu, TICK_REGNUM)
89 1.7 christos #define h8_set_ticks(cpu, val) h8_set_reg (cpu, TICK_REGNUM, val)
90 1.7 christos #define h8_get_mach(cpu) h8_get_reg (cpu, MACH_REGNUM)
91 1.7 christos #define h8_set_mach(cpu, val) h8_set_reg (cpu, MACH_REGNUM, val)
92 1.7 christos #define h8_get_macl(cpu) h8_get_reg (cpu, MACL_REGNUM)
93 1.7 christos #define h8_set_macl(cpu, val) h8_set_reg (cpu, MACL_REGNUM, val)
94 1.1 christos
95 1.1 christos static int
96 1.7 christos h8_get_mask (sim_cpu *cpu)
97 1.1 christos {
98 1.8 christos return H8300_SIM_CPU (cpu)->mask;
99 1.1 christos }
100 1.1 christos
101 1.1 christos static void
102 1.7 christos h8_set_mask (sim_cpu *cpu, int val)
103 1.1 christos {
104 1.8 christos H8300_SIM_CPU (cpu)->mask = val;
105 1.1 christos }
106 1.1 christos #if 0
107 1.1 christos static int
108 1.7 christos h8_get_exception (sim_cpu *cpu)
109 1.1 christos {
110 1.8 christos return H8300_SIM_CPU (cpu)->exception;
111 1.1 christos }
112 1.1 christos
113 1.1 christos static void
114 1.7 christos h8_set_exception (sim_cpu *cpu, int val)
115 1.1 christos {
116 1.8 christos H8300_SIM_CPU (cpu)->exception = val;
117 1.1 christos }
118 1.1 christos
119 1.1 christos static enum h8300_sim_state
120 1.1 christos h8_get_state (SIM_DESC sd)
121 1.1 christos {
122 1.7 christos return H8300_SIM_STATE (sd)->state;
123 1.1 christos }
124 1.1 christos
125 1.1 christos static void
126 1.1 christos h8_set_state (SIM_DESC sd, enum h8300_sim_state val)
127 1.1 christos {
128 1.7 christos H8300_SIM_STATE (sd)->state = val;
129 1.1 christos }
130 1.1 christos #endif
131 1.1 christos
132 1.1 christos static unsigned int *
133 1.7 christos h8_get_reg_buf (sim_cpu *cpu)
134 1.1 christos {
135 1.8 christos return &H8300_SIM_CPU (cpu)->regs[0];
136 1.1 christos }
137 1.1 christos
138 1.1 christos #ifdef ADEBUG
139 1.1 christos static int
140 1.1 christos h8_get_stats (SIM_DESC sd, int idx)
141 1.1 christos {
142 1.7 christos return H8300_SIM_STATE (sd)->stats[idx];
143 1.1 christos }
144 1.1 christos
145 1.1 christos static void
146 1.1 christos h8_increment_stats (SIM_DESC sd, int idx)
147 1.1 christos {
148 1.7 christos H8300_SIM_STATE (sd)->stats[idx] ++;
149 1.1 christos }
150 1.1 christos #endif /* ADEBUG */
151 1.1 christos
152 1.1 christos static unsigned char *
153 1.7 christos h8_get_memory_buf (sim_cpu *cpu)
154 1.1 christos {
155 1.8 christos return H8300_SIM_CPU (cpu)->memory;
156 1.1 christos }
157 1.1 christos
158 1.1 christos static void
159 1.7 christos h8_set_memory_buf (sim_cpu *cpu, unsigned char *ptr)
160 1.1 christos {
161 1.8 christos H8300_SIM_CPU (cpu)->memory = ptr;
162 1.1 christos }
163 1.1 christos
164 1.1 christos static unsigned char
165 1.7 christos h8_get_memory (sim_cpu *cpu, int idx)
166 1.1 christos {
167 1.7 christos ASSERT (idx < memory_size);
168 1.8 christos return H8300_SIM_CPU (cpu)->memory[idx];
169 1.1 christos }
170 1.1 christos
171 1.1 christos static void
172 1.7 christos h8_set_memory (sim_cpu *cpu, int idx, unsigned int val)
173 1.1 christos {
174 1.7 christos ASSERT (idx < memory_size);
175 1.8 christos H8300_SIM_CPU (cpu)->memory[idx] = (unsigned char) val;
176 1.1 christos }
177 1.1 christos
178 1.1 christos static unsigned int
179 1.7 christos h8_get_delayed_branch (sim_cpu *cpu)
180 1.1 christos {
181 1.8 christos return H8300_SIM_CPU (cpu)->delayed_branch;
182 1.1 christos }
183 1.1 christos
184 1.1 christos static void
185 1.7 christos h8_set_delayed_branch (sim_cpu *cpu, unsigned int dest)
186 1.1 christos {
187 1.8 christos H8300_SIM_CPU (cpu)->delayed_branch = dest;
188 1.1 christos }
189 1.1 christos
190 1.1 christos static char **
191 1.7 christos h8_get_command_line (sim_cpu *cpu)
192 1.1 christos {
193 1.8 christos return H8300_SIM_CPU (cpu)->command_line;
194 1.1 christos }
195 1.1 christos
196 1.1 christos static void
197 1.7 christos h8_set_command_line (sim_cpu *cpu, char ** val)
198 1.1 christos {
199 1.8 christos H8300_SIM_CPU (cpu)->command_line = val;
200 1.1 christos }
201 1.1 christos
202 1.1 christos static char *
203 1.7 christos h8_get_cmdline_arg (sim_cpu *cpu, int index)
204 1.1 christos {
205 1.8 christos return H8300_SIM_CPU (cpu)->command_line[index];
206 1.1 christos }
207 1.1 christos
208 1.1 christos static void
209 1.7 christos h8_set_cmdline_arg (sim_cpu *cpu, int index, char * val)
210 1.1 christos {
211 1.8 christos H8300_SIM_CPU (cpu)->command_line[index] = val;
212 1.1 christos }
213 1.1 christos
214 1.1 christos /* MAC Saturation Mode */
215 1.1 christos static int
216 1.7 christos h8_get_macS (sim_cpu *cpu)
217 1.1 christos {
218 1.8 christos return H8300_SIM_CPU (cpu)->macS;
219 1.1 christos }
220 1.1 christos
221 1.7 christos #if 0
222 1.1 christos static void
223 1.7 christos h8_set_macS (sim_cpu *cpu, int val)
224 1.1 christos {
225 1.8 christos H8300_SIM_CPU (cpu)->macS = (val != 0);
226 1.1 christos }
227 1.7 christos #endif
228 1.1 christos
229 1.1 christos /* MAC Zero Flag */
230 1.1 christos static int
231 1.7 christos h8_get_macZ (sim_cpu *cpu)
232 1.1 christos {
233 1.8 christos return H8300_SIM_CPU (cpu)->macZ;
234 1.1 christos }
235 1.1 christos
236 1.1 christos static void
237 1.7 christos h8_set_macZ (sim_cpu *cpu, int val)
238 1.1 christos {
239 1.8 christos H8300_SIM_CPU (cpu)->macZ = (val != 0);
240 1.1 christos }
241 1.1 christos
242 1.1 christos /* MAC Negative Flag */
243 1.1 christos static int
244 1.7 christos h8_get_macN (sim_cpu *cpu)
245 1.1 christos {
246 1.8 christos return H8300_SIM_CPU (cpu)->macN;
247 1.1 christos }
248 1.1 christos
249 1.1 christos static void
250 1.7 christos h8_set_macN (sim_cpu *cpu, int val)
251 1.1 christos {
252 1.8 christos H8300_SIM_CPU (cpu)->macN = (val != 0);
253 1.1 christos }
254 1.1 christos
255 1.1 christos /* MAC Overflow Flag */
256 1.1 christos static int
257 1.7 christos h8_get_macV (sim_cpu *cpu)
258 1.1 christos {
259 1.8 christos return H8300_SIM_CPU (cpu)->macV;
260 1.1 christos }
261 1.1 christos
262 1.1 christos static void
263 1.7 christos h8_set_macV (sim_cpu *cpu, int val)
264 1.1 christos {
265 1.8 christos H8300_SIM_CPU (cpu)->macV = (val != 0);
266 1.1 christos }
267 1.1 christos
268 1.1 christos /* End CPU data object. */
269 1.1 christos
270 1.1 christos /* The rate at which to call the host's poll_quit callback. */
271 1.1 christos
272 1.1 christos enum { POLL_QUIT_INTERVAL = 0x80000 };
273 1.1 christos
274 1.1 christos #define LOW_BYTE(x) ((x) & 0xff)
275 1.1 christos #define HIGH_BYTE(x) (((x) >> 8) & 0xff)
276 1.1 christos #define P(X, Y) ((X << 8) | Y)
277 1.1 christos
278 1.1 christos #define C (c != 0)
279 1.1 christos #define Z (nz == 0)
280 1.1 christos #define V (v != 0)
281 1.1 christos #define N (n != 0)
282 1.1 christos #define U (u != 0)
283 1.1 christos #define H (h != 0)
284 1.1 christos #define UI (ui != 0)
285 1.1 christos #define I (intMaskBit != 0)
286 1.1 christos
287 1.7 christos #define BUILDSR(cpu) \
288 1.7 christos h8_set_ccr (cpu, (I << 7) | (UI << 6) | (H << 5) | (U << 4) \
289 1.1 christos | (N << 3) | (Z << 2) | (V << 1) | C)
290 1.1 christos
291 1.7 christos #define GETSR(cpu) \
292 1.1 christos /* Get Status Register (flags). */ \
293 1.7 christos c = (h8_get_ccr (cpu) >> 0) & 1; \
294 1.7 christos v = (h8_get_ccr (cpu) >> 1) & 1; \
295 1.7 christos nz = !((h8_get_ccr (cpu) >> 2) & 1); \
296 1.7 christos n = (h8_get_ccr (cpu) >> 3) & 1; \
297 1.7 christos u = (h8_get_ccr (cpu) >> 4) & 1; \
298 1.7 christos h = (h8_get_ccr (cpu) >> 5) & 1; \
299 1.7 christos ui = ((h8_get_ccr (cpu) >> 6) & 1); \
300 1.7 christos intMaskBit = (h8_get_ccr (cpu) >> 7) & 1
301 1.1 christos
302 1.1 christos
303 1.1 christos #ifdef __CHAR_IS_SIGNED__
304 1.1 christos #define SEXTCHAR(x) ((char) (x))
305 1.1 christos #endif
306 1.1 christos
307 1.1 christos #ifndef SEXTCHAR
308 1.1 christos #define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff) : x & 0xff)
309 1.1 christos #endif
310 1.1 christos
311 1.1 christos #define UEXTCHAR(x) ((x) & 0xff)
312 1.1 christos #define UEXTSHORT(x) ((x) & 0xffff)
313 1.1 christos #define SEXTSHORT(x) ((short) (x))
314 1.1 christos
315 1.1 christos int h8300hmode = 0;
316 1.1 christos int h8300smode = 0;
317 1.1 christos int h8300_normal_mode = 0;
318 1.1 christos int h8300sxmode = 0;
319 1.1 christos
320 1.1 christos static int
321 1.1 christos get_now (void)
322 1.1 christos {
323 1.1 christos return time (0); /* WinXX HAS UNIX like 'time', so why not use it? */
324 1.1 christos }
325 1.1 christos
326 1.1 christos static int
327 1.1 christos now_persec (void)
328 1.1 christos {
329 1.1 christos return 1;
330 1.1 christos }
331 1.1 christos
332 1.1 christos static int
333 1.1 christos bitfrom (int x)
334 1.1 christos {
335 1.1 christos switch (x & SIZE)
336 1.1 christos {
337 1.1 christos case L_8:
338 1.1 christos return SB;
339 1.1 christos case L_16:
340 1.1 christos case L_16U:
341 1.1 christos return SW;
342 1.1 christos case L_32:
343 1.1 christos return SL;
344 1.1 christos case L_P:
345 1.1 christos return (h8300hmode && !h8300_normal_mode)? SL : SW;
346 1.1 christos }
347 1.1 christos return 0;
348 1.1 christos }
349 1.1 christos
350 1.1 christos /* Simulate an indirection / dereference.
351 1.1 christos return 0 for success, -1 for failure.
352 1.1 christos */
353 1.1 christos
354 1.1 christos static unsigned int
355 1.7 christos lvalue (SIM_DESC sd, sim_cpu *cpu, int x, int rn, unsigned int *val)
356 1.1 christos {
357 1.1 christos if (val == NULL) /* Paranoia. */
358 1.1 christos return -1;
359 1.1 christos
360 1.1 christos switch (x / 4)
361 1.1 christos {
362 1.1 christos case OP_DISP:
363 1.1 christos if (rn == ZERO_REGNUM)
364 1.1 christos *val = X (OP_IMM, SP);
365 1.1 christos else
366 1.1 christos *val = X (OP_REG, SP);
367 1.1 christos break;
368 1.1 christos case OP_MEM:
369 1.1 christos *val = X (OP_MEM, SP);
370 1.1 christos break;
371 1.1 christos default:
372 1.6 christos sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
373 1.1 christos return -1;
374 1.1 christos }
375 1.1 christos return 0;
376 1.1 christos }
377 1.1 christos
378 1.1 christos static int
379 1.7 christos cmdline_location(void)
380 1.1 christos {
381 1.1 christos if (h8300smode && !h8300_normal_mode)
382 1.1 christos return 0xffff00L;
383 1.1 christos else if (h8300hmode && !h8300_normal_mode)
384 1.1 christos return 0x2ff00L;
385 1.1 christos else
386 1.1 christos return 0xff00L;
387 1.1 christos }
388 1.1 christos
389 1.1 christos static void
390 1.7 christos decode (SIM_DESC sd, sim_cpu *cpu, int addr, unsigned char *data, decoded_inst *dst)
391 1.1 christos {
392 1.1 christos int cst[3] = {0, 0, 0};
393 1.1 christos int reg[3] = {0, 0, 0};
394 1.1 christos int rdisp[3] = {0, 0, 0};
395 1.1 christos int opnum;
396 1.8 christos int index;
397 1.1 christos const struct h8_opcode *q;
398 1.1 christos
399 1.1 christos dst->dst.type = -1;
400 1.1 christos dst->src.type = -1;
401 1.7 christos dst->op3.type = -1;
402 1.1 christos
403 1.8 christos /* We speed up instruction decoding by caching an index into
404 1.8 christos the main opcode array for the first instruction with the
405 1.8 christos given 4 bit nibble. */
406 1.8 christos index = nib_indices[(data[0] & 0xf0) >> 4];
407 1.8 christos
408 1.8 christos /* Find the exact opcode/arg combo, starting with the precomputed
409 1.8 christos index. Note this loop is performance sensitive. */
410 1.8 christos for (q = &h8_opcodes[index]; q->name; q++)
411 1.1 christos {
412 1.1 christos const op_type *nib = q->data.nib;
413 1.1 christos unsigned int len = 0;
414 1.1 christos
415 1.1 christos if ((q->available == AV_H8SX && !h8300sxmode) ||
416 1.1 christos (q->available == AV_H8S && !h8300smode) ||
417 1.1 christos (q->available == AV_H8H && !h8300hmode))
418 1.1 christos continue;
419 1.1 christos
420 1.1 christos cst[0] = cst[1] = cst[2] = 0;
421 1.1 christos reg[0] = reg[1] = reg[2] = 0;
422 1.1 christos rdisp[0] = rdisp[1] = rdisp[2] = 0;
423 1.1 christos
424 1.1 christos while (1)
425 1.1 christos {
426 1.1 christos op_type looking_for = *nib;
427 1.1 christos int thisnib = data[len / 2];
428 1.1 christos
429 1.1 christos thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
430 1.1 christos opnum = ((looking_for & OP3) ? 2 :
431 1.1 christos (looking_for & DST) ? 1 : 0);
432 1.1 christos
433 1.1 christos if (looking_for < 16 && looking_for >= 0)
434 1.1 christos {
435 1.1 christos if (looking_for != thisnib)
436 1.1 christos goto fail;
437 1.1 christos }
438 1.1 christos else
439 1.1 christos {
440 1.1 christos if (looking_for & B31)
441 1.1 christos {
442 1.1 christos if (!((thisnib & 0x8) != 0))
443 1.1 christos goto fail;
444 1.1 christos
445 1.1 christos looking_for = (op_type) (looking_for & ~B31);
446 1.1 christos thisnib &= 0x7;
447 1.1 christos }
448 1.1 christos else if (looking_for & B30)
449 1.1 christos {
450 1.1 christos if (!((thisnib & 0x8) == 0))
451 1.1 christos goto fail;
452 1.1 christos
453 1.1 christos looking_for = (op_type) (looking_for & ~B30);
454 1.1 christos }
455 1.1 christos
456 1.1 christos if (looking_for & B21)
457 1.1 christos {
458 1.1 christos if (!((thisnib & 0x4) != 0))
459 1.1 christos goto fail;
460 1.1 christos
461 1.1 christos looking_for = (op_type) (looking_for & ~B21);
462 1.1 christos thisnib &= 0xb;
463 1.1 christos }
464 1.1 christos else if (looking_for & B20)
465 1.1 christos {
466 1.1 christos if (!((thisnib & 0x4) == 0))
467 1.1 christos goto fail;
468 1.1 christos
469 1.1 christos looking_for = (op_type) (looking_for & ~B20);
470 1.1 christos }
471 1.1 christos
472 1.1 christos if (looking_for & B11)
473 1.1 christos {
474 1.1 christos if (!((thisnib & 0x2) != 0))
475 1.1 christos goto fail;
476 1.1 christos
477 1.1 christos looking_for = (op_type) (looking_for & ~B11);
478 1.1 christos thisnib &= 0xd;
479 1.1 christos }
480 1.1 christos else if (looking_for & B10)
481 1.1 christos {
482 1.1 christos if (!((thisnib & 0x2) == 0))
483 1.1 christos goto fail;
484 1.1 christos
485 1.1 christos looking_for = (op_type) (looking_for & ~B10);
486 1.1 christos }
487 1.1 christos
488 1.1 christos if (looking_for & B01)
489 1.1 christos {
490 1.1 christos if (!((thisnib & 0x1) != 0))
491 1.1 christos goto fail;
492 1.1 christos
493 1.1 christos looking_for = (op_type) (looking_for & ~B01);
494 1.1 christos thisnib &= 0xe;
495 1.1 christos }
496 1.1 christos else if (looking_for & B00)
497 1.1 christos {
498 1.1 christos if (!((thisnib & 0x1) == 0))
499 1.1 christos goto fail;
500 1.1 christos
501 1.1 christos looking_for = (op_type) (looking_for & ~B00);
502 1.1 christos }
503 1.1 christos
504 1.1 christos if (looking_for & IGNORE)
505 1.1 christos {
506 1.1 christos /* Hitachi has declared that IGNORE must be zero. */
507 1.1 christos if (thisnib != 0)
508 1.1 christos goto fail;
509 1.1 christos }
510 1.1 christos else if ((looking_for & MODE) == DATA)
511 1.1 christos {
512 1.1 christos ; /* Skip embedded data. */
513 1.1 christos }
514 1.1 christos else if ((looking_for & MODE) == DBIT)
515 1.1 christos {
516 1.1 christos /* Exclude adds/subs by looking at bit 0 and 2, and
517 1.1 christos make sure the operand size, either w or l,
518 1.1 christos matches by looking at bit 1. */
519 1.1 christos if ((looking_for & 7) != (thisnib & 7))
520 1.1 christos goto fail;
521 1.1 christos
522 1.1 christos cst[opnum] = (thisnib & 0x8) ? 2 : 1;
523 1.1 christos }
524 1.1 christos else if ((looking_for & MODE) == REG ||
525 1.1 christos (looking_for & MODE) == LOWREG ||
526 1.1 christos (looking_for & MODE) == IND ||
527 1.1 christos (looking_for & MODE) == PREINC ||
528 1.1 christos (looking_for & MODE) == POSTINC ||
529 1.1 christos (looking_for & MODE) == PREDEC ||
530 1.1 christos (looking_for & MODE) == POSTDEC)
531 1.1 christos {
532 1.1 christos reg[opnum] = thisnib;
533 1.1 christos }
534 1.1 christos else if (looking_for & CTRL)
535 1.1 christos {
536 1.1 christos thisnib &= 7;
537 1.1 christos if (((looking_for & MODE) == CCR && (thisnib != C_CCR)) ||
538 1.1 christos ((looking_for & MODE) == EXR && (thisnib != C_EXR)) ||
539 1.1 christos ((looking_for & MODE) == MACH && (thisnib != C_MACH)) ||
540 1.1 christos ((looking_for & MODE) == MACL && (thisnib != C_MACL)) ||
541 1.1 christos ((looking_for & MODE) == VBR && (thisnib != C_VBR)) ||
542 1.1 christos ((looking_for & MODE) == SBR && (thisnib != C_SBR)))
543 1.1 christos goto fail;
544 1.1 christos if (((looking_for & MODE) == CCR_EXR &&
545 1.1 christos (thisnib != C_CCR && thisnib != C_EXR)) ||
546 1.1 christos ((looking_for & MODE) == VBR_SBR &&
547 1.1 christos (thisnib != C_VBR && thisnib != C_SBR)) ||
548 1.1 christos ((looking_for & MODE) == MACREG &&
549 1.1 christos (thisnib != C_MACH && thisnib != C_MACL)))
550 1.1 christos goto fail;
551 1.1 christos if (((looking_for & MODE) == CC_EX_VB_SB &&
552 1.1 christos (thisnib != C_CCR && thisnib != C_EXR &&
553 1.1 christos thisnib != C_VBR && thisnib != C_SBR)))
554 1.1 christos goto fail;
555 1.1 christos
556 1.1 christos reg[opnum] = thisnib;
557 1.1 christos }
558 1.1 christos else if ((looking_for & MODE) == ABS)
559 1.1 christos {
560 1.1 christos /* Absolute addresses are unsigned. */
561 1.1 christos switch (looking_for & SIZE)
562 1.1 christos {
563 1.1 christos case L_8:
564 1.1 christos cst[opnum] = UEXTCHAR (data[len / 2]);
565 1.1 christos break;
566 1.1 christos case L_16:
567 1.1 christos case L_16U:
568 1.1 christos cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
569 1.1 christos break;
570 1.1 christos case L_32:
571 1.1 christos cst[opnum] =
572 1.1 christos (data[len / 2 + 0] << 24) +
573 1.1 christos (data[len / 2 + 1] << 16) +
574 1.1 christos (data[len / 2 + 2] << 8) +
575 1.1 christos (data[len / 2 + 3]);
576 1.1 christos break;
577 1.1 christos default:
578 1.1 christos printf ("decode: bad size ABS: %d\n",
579 1.1 christos (looking_for & SIZE));
580 1.1 christos goto end;
581 1.1 christos }
582 1.1 christos }
583 1.1 christos else if ((looking_for & MODE) == DISP ||
584 1.1 christos (looking_for & MODE) == PCREL ||
585 1.1 christos (looking_for & MODE) == INDEXB ||
586 1.1 christos (looking_for & MODE) == INDEXW ||
587 1.1 christos (looking_for & MODE) == INDEXL)
588 1.1 christos {
589 1.1 christos switch (looking_for & SIZE)
590 1.1 christos {
591 1.1 christos case L_2:
592 1.1 christos cst[opnum] = thisnib & 3;
593 1.1 christos break;
594 1.1 christos case L_8:
595 1.1 christos cst[opnum] = SEXTCHAR (data[len / 2]);
596 1.1 christos break;
597 1.1 christos case L_16:
598 1.1 christos cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
599 1.1 christos cst[opnum] = (short) cst[opnum]; /* Sign extend. */
600 1.1 christos break;
601 1.1 christos case L_16U:
602 1.1 christos cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
603 1.1 christos break;
604 1.1 christos case L_32:
605 1.1 christos cst[opnum] =
606 1.1 christos (data[len / 2 + 0] << 24) +
607 1.1 christos (data[len / 2 + 1] << 16) +
608 1.1 christos (data[len / 2 + 2] << 8) +
609 1.1 christos (data[len / 2 + 3]);
610 1.1 christos break;
611 1.1 christos default:
612 1.1 christos printf ("decode: bad size DISP/PCREL/INDEX: %d\n",
613 1.1 christos (looking_for & SIZE));
614 1.1 christos goto end;
615 1.1 christos }
616 1.1 christos }
617 1.1 christos else if ((looking_for & SIZE) == L_16 ||
618 1.1 christos (looking_for & SIZE) == L_16U)
619 1.1 christos {
620 1.1 christos cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
621 1.1 christos /* Immediates are always unsigned. */
622 1.1 christos if ((looking_for & SIZE) != L_16U &&
623 1.1 christos (looking_for & MODE) != IMM)
624 1.1 christos cst[opnum] = (short) cst[opnum]; /* Sign extend. */
625 1.1 christos }
626 1.1 christos else if (looking_for & ABSJMP)
627 1.1 christos {
628 1.1 christos switch (looking_for & SIZE) {
629 1.1 christos case L_24:
630 1.1 christos cst[opnum] = (data[1] << 16) | (data[2] << 8) | (data[3]);
631 1.1 christos break;
632 1.1 christos case L_32:
633 1.1 christos cst[opnum] =
634 1.1 christos (data[len / 2 + 0] << 24) +
635 1.1 christos (data[len / 2 + 1] << 16) +
636 1.1 christos (data[len / 2 + 2] << 8) +
637 1.1 christos (data[len / 2 + 3]);
638 1.1 christos break;
639 1.1 christos default:
640 1.1 christos printf ("decode: bad size ABSJMP: %d\n",
641 1.1 christos (looking_for & SIZE));
642 1.1 christos goto end;
643 1.1 christos }
644 1.1 christos }
645 1.1 christos else if ((looking_for & MODE) == MEMIND)
646 1.1 christos {
647 1.1 christos cst[opnum] = data[1];
648 1.1 christos }
649 1.1 christos else if ((looking_for & MODE) == VECIND)
650 1.1 christos {
651 1.1 christos if(h8300_normal_mode)
652 1.1 christos cst[opnum] = ((data[1] & 0x7f) + 0x80) * 2;
653 1.1 christos else
654 1.1 christos cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4;
655 1.7 christos cst[opnum] += h8_get_vbr (cpu); /* Add vector base reg. */
656 1.1 christos }
657 1.1 christos else if ((looking_for & SIZE) == L_32)
658 1.1 christos {
659 1.1 christos int i = len / 2;
660 1.1 christos
661 1.1 christos cst[opnum] =
662 1.1 christos (data[i + 0] << 24) |
663 1.1 christos (data[i + 1] << 16) |
664 1.1 christos (data[i + 2] << 8) |
665 1.1 christos (data[i + 3]);
666 1.1 christos }
667 1.1 christos else if ((looking_for & SIZE) == L_24)
668 1.1 christos {
669 1.1 christos int i = len / 2;
670 1.1 christos
671 1.1 christos cst[opnum] =
672 1.1 christos (data[i + 0] << 16) |
673 1.1 christos (data[i + 1] << 8) |
674 1.1 christos (data[i + 2]);
675 1.1 christos }
676 1.1 christos else if (looking_for & DISPREG)
677 1.1 christos {
678 1.1 christos rdisp[opnum] = thisnib & 0x7;
679 1.1 christos }
680 1.1 christos else if ((looking_for & MODE) == KBIT)
681 1.1 christos {
682 1.1 christos switch (thisnib)
683 1.1 christos {
684 1.1 christos case 9:
685 1.1 christos cst[opnum] = 4;
686 1.1 christos break;
687 1.1 christos case 8:
688 1.1 christos cst[opnum] = 2;
689 1.1 christos break;
690 1.1 christos case 0:
691 1.1 christos cst[opnum] = 1;
692 1.1 christos break;
693 1.1 christos default:
694 1.1 christos goto fail;
695 1.1 christos }
696 1.1 christos }
697 1.1 christos else if ((looking_for & SIZE) == L_8)
698 1.1 christos {
699 1.1 christos if ((looking_for & MODE) == ABS)
700 1.1 christos {
701 1.1 christos /* Will be combined with contents of SBR_REGNUM
702 1.1 christos by fetch (). For all modes except h8sx, this
703 1.1 christos will always contain the value 0xFFFFFF00. */
704 1.1 christos cst[opnum] = data[len / 2] & 0xff;
705 1.1 christos }
706 1.1 christos else
707 1.1 christos {
708 1.1 christos cst[opnum] = data[len / 2] & 0xff;
709 1.1 christos }
710 1.1 christos }
711 1.1 christos else if ((looking_for & SIZE) == L_2)
712 1.1 christos {
713 1.1 christos cst[opnum] = thisnib & 3;
714 1.1 christos }
715 1.1 christos else if ((looking_for & SIZE) == L_3 ||
716 1.1 christos (looking_for & SIZE) == L_3NZ)
717 1.1 christos {
718 1.1 christos cst[opnum] = thisnib & 7;
719 1.1 christos if (cst[opnum] == 0 && (looking_for & SIZE) == L_3NZ)
720 1.1 christos goto fail;
721 1.1 christos }
722 1.1 christos else if ((looking_for & SIZE) == L_4)
723 1.1 christos {
724 1.1 christos cst[opnum] = thisnib & 15;
725 1.1 christos }
726 1.1 christos else if ((looking_for & SIZE) == L_5)
727 1.1 christos {
728 1.1 christos cst[opnum] = data[len / 2] & 0x1f;
729 1.1 christos }
730 1.1 christos else if (looking_for == E)
731 1.1 christos {
732 1.1 christos #ifdef ADEBUG
733 1.1 christos dst->op = q;
734 1.1 christos #endif
735 1.1 christos /* Fill in the args. */
736 1.1 christos {
737 1.1 christos const op_type *args = q->args.nib;
738 1.1 christos int nargs;
739 1.1 christos
740 1.1 christos for (nargs = 0;
741 1.1 christos nargs < 3 && *args != E;
742 1.1 christos nargs++)
743 1.1 christos {
744 1.1 christos int x = *args;
745 1.1 christos ea_type *p;
746 1.1 christos
747 1.1 christos opnum = ((x & OP3) ? 2 :
748 1.1 christos (x & DST) ? 1 : 0);
749 1.1 christos if (x & DST)
750 1.1 christos p = &dst->dst;
751 1.1 christos else if (x & OP3)
752 1.1 christos p = &dst->op3;
753 1.1 christos else
754 1.1 christos p = &dst->src;
755 1.1 christos
756 1.1 christos if ((x & MODE) == IMM ||
757 1.1 christos (x & MODE) == KBIT ||
758 1.1 christos (x & MODE) == DBIT)
759 1.1 christos {
760 1.1 christos /* Use the instruction to determine
761 1.1 christos the operand size. */
762 1.1 christos p->type = X (OP_IMM, OP_SIZE (q->how));
763 1.1 christos p->literal = cst[opnum];
764 1.1 christos }
765 1.1 christos else if ((x & MODE) == CONST_2 ||
766 1.1 christos (x & MODE) == CONST_4 ||
767 1.1 christos (x & MODE) == CONST_8 ||
768 1.1 christos (x & MODE) == CONST_16)
769 1.1 christos {
770 1.1 christos /* Use the instruction to determine
771 1.1 christos the operand size. */
772 1.1 christos p->type = X (OP_IMM, OP_SIZE (q->how));
773 1.1 christos switch (x & MODE) {
774 1.1 christos case CONST_2: p->literal = 2; break;
775 1.1 christos case CONST_4: p->literal = 4; break;
776 1.1 christos case CONST_8: p->literal = 8; break;
777 1.1 christos case CONST_16: p->literal = 16; break;
778 1.1 christos }
779 1.1 christos }
780 1.1 christos else if ((x & MODE) == REG)
781 1.1 christos {
782 1.1 christos p->type = X (OP_REG, bitfrom (x));
783 1.1 christos p->reg = reg[opnum];
784 1.1 christos }
785 1.1 christos else if ((x & MODE) == LOWREG)
786 1.1 christos {
787 1.1 christos p->type = X (OP_LOWREG, bitfrom (x));
788 1.1 christos p->reg = reg[opnum];
789 1.1 christos }
790 1.1 christos else if ((x & MODE) == PREINC)
791 1.1 christos {
792 1.1 christos /* Use the instruction to determine
793 1.1 christos the operand size. */
794 1.1 christos p->type = X (OP_PREINC, OP_SIZE (q->how));
795 1.1 christos p->reg = reg[opnum] & 0x7;
796 1.1 christos }
797 1.1 christos else if ((x & MODE) == POSTINC)
798 1.1 christos {
799 1.1 christos /* Use the instruction to determine
800 1.1 christos the operand size. */
801 1.1 christos p->type = X (OP_POSTINC, OP_SIZE (q->how));
802 1.1 christos p->reg = reg[opnum] & 0x7;
803 1.1 christos }
804 1.1 christos else if ((x & MODE) == PREDEC)
805 1.1 christos {
806 1.1 christos /* Use the instruction to determine
807 1.1 christos the operand size. */
808 1.1 christos p->type = X (OP_PREDEC, OP_SIZE (q->how));
809 1.1 christos p->reg = reg[opnum] & 0x7;
810 1.1 christos }
811 1.1 christos else if ((x & MODE) == POSTDEC)
812 1.1 christos {
813 1.1 christos /* Use the instruction to determine
814 1.1 christos the operand size. */
815 1.1 christos p->type = X (OP_POSTDEC, OP_SIZE (q->how));
816 1.1 christos p->reg = reg[opnum] & 0x7;
817 1.1 christos }
818 1.1 christos else if ((x & MODE) == IND)
819 1.1 christos {
820 1.1 christos /* Note: an indirect is transformed into
821 1.1 christos a displacement of zero.
822 1.1 christos */
823 1.1 christos /* Use the instruction to determine
824 1.1 christos the operand size. */
825 1.1 christos p->type = X (OP_DISP, OP_SIZE (q->how));
826 1.1 christos p->reg = reg[opnum] & 0x7;
827 1.1 christos p->literal = 0;
828 1.1 christos if (OP_KIND (q->how) == O_JSR ||
829 1.1 christos OP_KIND (q->how) == O_JMP)
830 1.7 christos if (lvalue (sd, cpu, p->type, p->reg, (unsigned int *)&p->type))
831 1.1 christos goto end;
832 1.1 christos }
833 1.1 christos else if ((x & MODE) == ABS)
834 1.1 christos {
835 1.1 christos /* Note: a 16 or 32 bit ABS is transformed into a
836 1.1 christos displacement from pseudo-register ZERO_REGNUM,
837 1.1 christos which is always zero. An 8 bit ABS becomes
838 1.1 christos a displacement from SBR_REGNUM.
839 1.1 christos */
840 1.1 christos /* Use the instruction to determine
841 1.1 christos the operand size. */
842 1.1 christos p->type = X (OP_DISP, OP_SIZE (q->how));
843 1.1 christos p->literal = cst[opnum];
844 1.1 christos
845 1.1 christos /* 8-bit ABS is displacement from SBR.
846 1.1 christos 16 and 32-bit ABS are displacement from ZERO.
847 1.1 christos (SBR will always be zero except for h8/sx)
848 1.1 christos */
849 1.1 christos if ((x & SIZE) == L_8)
850 1.1 christos p->reg = SBR_REGNUM;
851 1.1 christos else
852 1.1 christos p->reg = ZERO_REGNUM;;
853 1.1 christos }
854 1.1 christos else if ((x & MODE) == MEMIND ||
855 1.1 christos (x & MODE) == VECIND)
856 1.1 christos {
857 1.1 christos /* Size doesn't matter. */
858 1.1 christos p->type = X (OP_MEM, SB);
859 1.1 christos p->literal = cst[opnum];
860 1.1 christos if (OP_KIND (q->how) == O_JSR ||
861 1.1 christos OP_KIND (q->how) == O_JMP)
862 1.7 christos if (lvalue (sd, cpu, p->type, p->reg, (unsigned int *)&p->type))
863 1.1 christos goto end;
864 1.1 christos }
865 1.1 christos else if ((x & MODE) == PCREL)
866 1.1 christos {
867 1.1 christos /* Size doesn't matter. */
868 1.1 christos p->type = X (OP_PCREL, SB);
869 1.1 christos p->literal = cst[opnum];
870 1.1 christos }
871 1.1 christos else if (x & ABSJMP)
872 1.1 christos {
873 1.1 christos p->type = X (OP_IMM, SP);
874 1.1 christos p->literal = cst[opnum];
875 1.1 christos }
876 1.1 christos else if ((x & MODE) == INDEXB)
877 1.1 christos {
878 1.1 christos p->type = X (OP_INDEXB, OP_SIZE (q->how));
879 1.1 christos p->literal = cst[opnum];
880 1.1 christos p->reg = rdisp[opnum];
881 1.1 christos }
882 1.1 christos else if ((x & MODE) == INDEXW)
883 1.1 christos {
884 1.1 christos p->type = X (OP_INDEXW, OP_SIZE (q->how));
885 1.1 christos p->literal = cst[opnum];
886 1.1 christos p->reg = rdisp[opnum];
887 1.1 christos }
888 1.1 christos else if ((x & MODE) == INDEXL)
889 1.1 christos {
890 1.1 christos p->type = X (OP_INDEXL, OP_SIZE (q->how));
891 1.1 christos p->literal = cst[opnum];
892 1.1 christos p->reg = rdisp[opnum];
893 1.1 christos }
894 1.1 christos else if ((x & MODE) == DISP)
895 1.1 christos {
896 1.1 christos /* Yuck -- special for mova args. */
897 1.1 christos if (strncmp (q->name, "mova", 4) == 0 &&
898 1.1 christos (x & SIZE) == L_2)
899 1.1 christos {
900 1.1 christos /* Mova can have a DISP2 dest, with an
901 1.1 christos INDEXB or INDEXW src. The multiplier
902 1.1 christos for the displacement value is determined
903 1.1 christos by the src operand, not by the insn. */
904 1.1 christos
905 1.1 christos switch (OP_KIND (dst->src.type))
906 1.1 christos {
907 1.1 christos case OP_INDEXB:
908 1.1 christos p->type = X (OP_DISP, SB);
909 1.1 christos p->literal = cst[opnum];
910 1.1 christos break;
911 1.1 christos case OP_INDEXW:
912 1.1 christos p->type = X (OP_DISP, SW);
913 1.1 christos p->literal = cst[opnum] * 2;
914 1.1 christos break;
915 1.1 christos default:
916 1.1 christos goto fail;
917 1.1 christos }
918 1.1 christos }
919 1.1 christos else
920 1.1 christos {
921 1.1 christos p->type = X (OP_DISP, OP_SIZE (q->how));
922 1.1 christos p->literal = cst[opnum];
923 1.1 christos /* DISP2 is special. */
924 1.1 christos if ((x & SIZE) == L_2)
925 1.1 christos switch (OP_SIZE (q->how))
926 1.1 christos {
927 1.1 christos case SB: break;
928 1.1 christos case SW: p->literal *= 2; break;
929 1.1 christos case SL: p->literal *= 4; break;
930 1.1 christos }
931 1.1 christos }
932 1.1 christos p->reg = rdisp[opnum];
933 1.1 christos }
934 1.1 christos else if (x & CTRL)
935 1.1 christos {
936 1.1 christos switch (reg[opnum])
937 1.1 christos {
938 1.1 christos case C_CCR:
939 1.1 christos p->type = X (OP_CCR, SB);
940 1.1 christos break;
941 1.1 christos case C_EXR:
942 1.1 christos p->type = X (OP_EXR, SB);
943 1.1 christos break;
944 1.1 christos case C_MACH:
945 1.1 christos p->type = X (OP_MACH, SL);
946 1.1 christos break;
947 1.1 christos case C_MACL:
948 1.1 christos p->type = X (OP_MACL, SL);
949 1.1 christos break;
950 1.1 christos case C_VBR:
951 1.1 christos p->type = X (OP_VBR, SL);
952 1.1 christos break;
953 1.1 christos case C_SBR:
954 1.1 christos p->type = X (OP_SBR, SL);
955 1.1 christos break;
956 1.1 christos }
957 1.1 christos }
958 1.1 christos else if ((x & MODE) == CCR)
959 1.1 christos {
960 1.1 christos p->type = OP_CCR;
961 1.1 christos }
962 1.1 christos else if ((x & MODE) == EXR)
963 1.1 christos {
964 1.1 christos p->type = OP_EXR;
965 1.1 christos }
966 1.1 christos else
967 1.1 christos printf ("Hmmmm 0x%x...\n", x);
968 1.1 christos
969 1.1 christos args++;
970 1.1 christos }
971 1.1 christos }
972 1.1 christos
973 1.1 christos /* Unary operators: treat src and dst as equivalent. */
974 1.1 christos if (dst->dst.type == -1)
975 1.1 christos dst->dst = dst->src;
976 1.1 christos if (dst->src.type == -1)
977 1.1 christos dst->src = dst->dst;
978 1.1 christos
979 1.1 christos dst->opcode = q->how;
980 1.1 christos dst->cycles = q->time;
981 1.1 christos
982 1.1 christos /* And jsr's to these locations are turned into
983 1.1 christos magic traps. */
984 1.1 christos
985 1.1 christos if (OP_KIND (dst->opcode) == O_JSR)
986 1.1 christos {
987 1.1 christos switch (dst->src.literal)
988 1.1 christos {
989 1.1 christos case 0xc5:
990 1.1 christos dst->opcode = O (O_SYS_OPEN, SB);
991 1.1 christos break;
992 1.1 christos case 0xc6:
993 1.1 christos dst->opcode = O (O_SYS_READ, SB);
994 1.1 christos break;
995 1.1 christos case 0xc7:
996 1.1 christos dst->opcode = O (O_SYS_WRITE, SB);
997 1.1 christos break;
998 1.1 christos case 0xc8:
999 1.1 christos dst->opcode = O (O_SYS_LSEEK, SB);
1000 1.1 christos break;
1001 1.1 christos case 0xc9:
1002 1.1 christos dst->opcode = O (O_SYS_CLOSE, SB);
1003 1.1 christos break;
1004 1.1 christos case 0xca:
1005 1.1 christos dst->opcode = O (O_SYS_STAT, SB);
1006 1.1 christos break;
1007 1.1 christos case 0xcb:
1008 1.1 christos dst->opcode = O (O_SYS_FSTAT, SB);
1009 1.1 christos break;
1010 1.1 christos case 0xcc:
1011 1.1 christos dst->opcode = O (O_SYS_CMDLINE, SB);
1012 1.1 christos break;
1013 1.1 christos }
1014 1.1 christos /* End of Processing for system calls. */
1015 1.1 christos }
1016 1.1 christos
1017 1.7 christos /* Use same register is specified for source
1018 1.7 christos and destination.
1019 1.7 christos The value of source will be the value after
1020 1.7 christos address calculation. */
1021 1.7 christos if (OP_KIND (dst->opcode) != O_CMP &&
1022 1.7 christos OP_KIND (dst->src.type) == OP_REG &&
1023 1.7 christos (dst->src.reg & 7) == dst->dst.reg) {
1024 1.7 christos switch (OP_KIND (dst->dst.type))
1025 1.7 christos {
1026 1.7 christos case OP_POSTDEC:
1027 1.7 christos dst->src.type = X (OP_REG_DEC,
1028 1.7 christos OP_SIZE (dst->dst.type));
1029 1.7 christos break;
1030 1.7 christos case OP_POSTINC:
1031 1.7 christos dst->src.type = X (OP_REG_INC,
1032 1.7 christos OP_SIZE (dst->dst.type));
1033 1.7 christos break;
1034 1.7 christos case OP_PREINC:
1035 1.7 christos if (OP_KIND (dst->opcode) == O_MOV)
1036 1.7 christos dst->src.type = X (OP_REG_INC,
1037 1.7 christos OP_SIZE (dst->dst.type));
1038 1.7 christos break;
1039 1.7 christos case OP_PREDEC:
1040 1.7 christos if (OP_KIND (dst->opcode) == O_MOV)
1041 1.7 christos dst->src.type = X (OP_REG_DEC,
1042 1.7 christos OP_SIZE (dst->dst.type));
1043 1.7 christos break;
1044 1.7 christos }
1045 1.7 christos }
1046 1.1 christos dst->next_pc = addr + len / 2;
1047 1.1 christos return;
1048 1.1 christos }
1049 1.1 christos else
1050 1.1 christos printf ("Don't understand 0x%x \n", looking_for);
1051 1.1 christos }
1052 1.1 christos
1053 1.1 christos len++;
1054 1.1 christos nib++;
1055 1.1 christos }
1056 1.1 christos
1057 1.1 christos fail:
1058 1.1 christos ;
1059 1.1 christos }
1060 1.1 christos end:
1061 1.1 christos /* Fell off the end. */
1062 1.1 christos dst->opcode = O (O_ILL, SB);
1063 1.1 christos }
1064 1.1 christos
1065 1.1 christos static unsigned char *breg[32];
1066 1.1 christos static unsigned short *wreg[16];
1067 1.1 christos
1068 1.1 christos #define GET_B_REG(X) *(breg[X])
1069 1.1 christos #define SET_B_REG(X, Y) (*(breg[X])) = (Y)
1070 1.1 christos #define GET_W_REG(X) *(wreg[X])
1071 1.1 christos #define SET_W_REG(X, Y) (*(wreg[X])) = (Y)
1072 1.7 christos #define GET_L_REG(X) h8_get_reg (cpu, X)
1073 1.7 christos #define SET_L_REG(X, Y) h8_set_reg (cpu, X, Y)
1074 1.1 christos
1075 1.1 christos #define GET_MEMORY_L(X) \
1076 1.1 christos ((X) < memory_size \
1077 1.7 christos ? ((h8_get_memory (cpu, (X)+0) << 24) | (h8_get_memory (cpu, (X)+1) << 16) \
1078 1.7 christos | (h8_get_memory (cpu, (X)+2) << 8) | (h8_get_memory (cpu, (X)+3) << 0)) \
1079 1.7 christos : 0)
1080 1.1 christos
1081 1.1 christos #define GET_MEMORY_W(X) \
1082 1.1 christos ((X) < memory_size \
1083 1.7 christos ? ((h8_get_memory (cpu, (X)+0) << 8) | (h8_get_memory (cpu, (X)+1) << 0)) \
1084 1.7 christos : 0)
1085 1.1 christos
1086 1.1 christos #define GET_MEMORY_B(X) \
1087 1.7 christos ((X) < memory_size ? h8_get_memory (cpu, (X)) : 0)
1088 1.1 christos
1089 1.1 christos #define SET_MEMORY_L(X, Y) \
1090 1.1 christos { register unsigned char *_p; register int __y = (Y); \
1091 1.7 christos _p = ((X) < memory_size ? h8_get_memory_buf (cpu) + (X) : 0); \
1092 1.1 christos _p[0] = __y >> 24; _p[1] = __y >> 16; \
1093 1.1 christos _p[2] = __y >> 8; _p[3] = __y >> 0; \
1094 1.1 christos }
1095 1.1 christos
1096 1.1 christos #define SET_MEMORY_W(X, Y) \
1097 1.1 christos { register unsigned char *_p; register int __y = (Y); \
1098 1.7 christos _p = ((X) < memory_size ? h8_get_memory_buf (cpu) + (X) : 0); \
1099 1.1 christos _p[0] = __y >> 8; _p[1] = __y; \
1100 1.1 christos }
1101 1.1 christos
1102 1.1 christos #define SET_MEMORY_B(X, Y) \
1103 1.7 christos ((X) < memory_size ? h8_set_memory (cpu, (X), (Y)) : 0)
1104 1.1 christos
1105 1.1 christos /* Simulate a memory fetch.
1106 1.1 christos Return 0 for success, -1 for failure.
1107 1.1 christos */
1108 1.1 christos
1109 1.1 christos static int
1110 1.1 christos fetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice)
1111 1.1 christos {
1112 1.6 christos SIM_CPU *cpu = STATE_CPU (sd, 0);
1113 1.1 christos int rn = arg->reg;
1114 1.1 christos int abs = arg->literal;
1115 1.1 christos int r;
1116 1.1 christos int t;
1117 1.1 christos
1118 1.1 christos if (val == NULL)
1119 1.1 christos return -1; /* Paranoia. */
1120 1.1 christos
1121 1.1 christos switch (arg->type)
1122 1.1 christos {
1123 1.1 christos /* Indexed register plus displacement mode:
1124 1.1 christos
1125 1.1 christos This new family of addressing modes are similar to OP_DISP
1126 1.1 christos (register plus displacement), with two differences:
1127 1.1 christos 1) INDEXB uses only the least significant byte of the register,
1128 1.1 christos INDEXW uses only the least significant word, and
1129 1.1 christos INDEXL uses the entire register (just like OP_DISP).
1130 1.1 christos and
1131 1.1 christos 2) The displacement value in abs is multiplied by two
1132 1.1 christos for SW-sized operations, and by four for SL-size.
1133 1.1 christos
1134 1.1 christos This gives nine possible variations.
1135 1.1 christos */
1136 1.1 christos
1137 1.1 christos case X (OP_INDEXB, SB):
1138 1.1 christos case X (OP_INDEXB, SW):
1139 1.1 christos case X (OP_INDEXB, SL):
1140 1.1 christos case X (OP_INDEXW, SB):
1141 1.1 christos case X (OP_INDEXW, SW):
1142 1.1 christos case X (OP_INDEXW, SL):
1143 1.1 christos case X (OP_INDEXL, SB):
1144 1.1 christos case X (OP_INDEXL, SW):
1145 1.1 christos case X (OP_INDEXL, SL):
1146 1.1 christos t = GET_L_REG (rn);
1147 1.1 christos switch (OP_KIND (arg->type)) {
1148 1.1 christos case OP_INDEXB: t &= 0xff; break;
1149 1.1 christos case OP_INDEXW: t &= 0xffff; break;
1150 1.1 christos case OP_INDEXL:
1151 1.1 christos default: break;
1152 1.1 christos }
1153 1.1 christos switch (OP_SIZE (arg->type)) {
1154 1.1 christos case SB:
1155 1.7 christos *val = GET_MEMORY_B ((t * 1 + abs) & h8_get_mask (cpu));
1156 1.1 christos break;
1157 1.1 christos case SW:
1158 1.7 christos *val = GET_MEMORY_W ((t * 2 + abs) & h8_get_mask (cpu));
1159 1.1 christos break;
1160 1.1 christos case SL:
1161 1.7 christos *val = GET_MEMORY_L ((t * 4 + abs) & h8_get_mask (cpu));
1162 1.1 christos break;
1163 1.1 christos }
1164 1.1 christos break;
1165 1.1 christos
1166 1.1 christos case X (OP_LOWREG, SB):
1167 1.1 christos *val = GET_L_REG (rn) & 0xff;
1168 1.1 christos break;
1169 1.1 christos case X (OP_LOWREG, SW):
1170 1.1 christos *val = GET_L_REG (rn) & 0xffff;
1171 1.1 christos break;
1172 1.1 christos
1173 1.1 christos case X (OP_REG, SB): /* Register direct, byte. */
1174 1.1 christos *val = GET_B_REG (rn);
1175 1.1 christos break;
1176 1.1 christos case X (OP_REG, SW): /* Register direct, word. */
1177 1.1 christos *val = GET_W_REG (rn);
1178 1.1 christos break;
1179 1.1 christos case X (OP_REG, SL): /* Register direct, long. */
1180 1.1 christos *val = GET_L_REG (rn);
1181 1.1 christos break;
1182 1.1 christos case X (OP_IMM, SB): /* Immediate, byte. */
1183 1.1 christos case X (OP_IMM, SW): /* Immediate, word. */
1184 1.1 christos case X (OP_IMM, SL): /* Immediate, long. */
1185 1.1 christos *val = abs;
1186 1.1 christos break;
1187 1.1 christos case X (OP_POSTINC, SB): /* Register indirect w/post-incr: byte. */
1188 1.1 christos t = GET_L_REG (rn);
1189 1.7 christos r = GET_MEMORY_B (t & h8_get_mask (cpu));
1190 1.1 christos if (!twice)
1191 1.1 christos t += 1;
1192 1.1 christos SET_L_REG (rn, t);
1193 1.1 christos *val = r;
1194 1.1 christos break;
1195 1.1 christos case X (OP_POSTINC, SW): /* Register indirect w/post-incr: word. */
1196 1.1 christos t = GET_L_REG (rn);
1197 1.7 christos r = GET_MEMORY_W (t & h8_get_mask (cpu));
1198 1.1 christos if (!twice)
1199 1.1 christos t += 2;
1200 1.1 christos SET_L_REG (rn, t);
1201 1.1 christos *val = r;
1202 1.1 christos break;
1203 1.1 christos case X (OP_POSTINC, SL): /* Register indirect w/post-incr: long. */
1204 1.1 christos t = GET_L_REG (rn);
1205 1.7 christos r = GET_MEMORY_L (t & h8_get_mask (cpu));
1206 1.1 christos if (!twice)
1207 1.1 christos t += 4;
1208 1.1 christos SET_L_REG (rn, t);
1209 1.1 christos *val = r;
1210 1.1 christos break;
1211 1.1 christos
1212 1.1 christos case X (OP_POSTDEC, SB): /* Register indirect w/post-decr: byte. */
1213 1.1 christos t = GET_L_REG (rn);
1214 1.7 christos r = GET_MEMORY_B (t & h8_get_mask (cpu));
1215 1.1 christos if (!twice)
1216 1.1 christos t -= 1;
1217 1.1 christos SET_L_REG (rn, t);
1218 1.1 christos *val = r;
1219 1.1 christos break;
1220 1.1 christos case X (OP_POSTDEC, SW): /* Register indirect w/post-decr: word. */
1221 1.1 christos t = GET_L_REG (rn);
1222 1.7 christos r = GET_MEMORY_W (t & h8_get_mask (cpu));
1223 1.1 christos if (!twice)
1224 1.1 christos t -= 2;
1225 1.1 christos SET_L_REG (rn, t);
1226 1.1 christos *val = r;
1227 1.1 christos break;
1228 1.1 christos case X (OP_POSTDEC, SL): /* Register indirect w/post-decr: long. */
1229 1.1 christos t = GET_L_REG (rn);
1230 1.7 christos r = GET_MEMORY_L (t & h8_get_mask (cpu));
1231 1.1 christos if (!twice)
1232 1.1 christos t -= 4;
1233 1.1 christos SET_L_REG (rn, t);
1234 1.1 christos *val = r;
1235 1.1 christos break;
1236 1.1 christos
1237 1.1 christos case X (OP_PREDEC, SB): /* Register indirect w/pre-decr: byte. */
1238 1.1 christos t = GET_L_REG (rn) - 1;
1239 1.1 christos SET_L_REG (rn, t);
1240 1.7 christos t &= h8_get_mask (cpu);
1241 1.1 christos *val = GET_MEMORY_B (t);
1242 1.1 christos break;
1243 1.1 christos
1244 1.1 christos case X (OP_PREDEC, SW): /* Register indirect w/pre-decr: word. */
1245 1.1 christos t = GET_L_REG (rn) - 2;
1246 1.1 christos SET_L_REG (rn, t);
1247 1.7 christos t &= h8_get_mask (cpu);
1248 1.1 christos *val = GET_MEMORY_W (t);
1249 1.1 christos break;
1250 1.1 christos
1251 1.1 christos case X (OP_PREDEC, SL): /* Register indirect w/pre-decr: long. */
1252 1.1 christos t = GET_L_REG (rn) - 4;
1253 1.1 christos SET_L_REG (rn, t);
1254 1.7 christos t &= h8_get_mask (cpu);
1255 1.1 christos *val = GET_MEMORY_L (t);
1256 1.1 christos break;
1257 1.1 christos
1258 1.1 christos case X (OP_PREINC, SB): /* Register indirect w/pre-incr: byte. */
1259 1.1 christos t = GET_L_REG (rn) + 1;
1260 1.1 christos SET_L_REG (rn, t);
1261 1.7 christos t &= h8_get_mask (cpu);
1262 1.1 christos *val = GET_MEMORY_B (t);
1263 1.1 christos break;
1264 1.1 christos
1265 1.1 christos case X (OP_PREINC, SW): /* Register indirect w/pre-incr: long. */
1266 1.1 christos t = GET_L_REG (rn) + 2;
1267 1.1 christos SET_L_REG (rn, t);
1268 1.7 christos t &= h8_get_mask (cpu);
1269 1.1 christos *val = GET_MEMORY_W (t);
1270 1.1 christos break;
1271 1.1 christos
1272 1.1 christos case X (OP_PREINC, SL): /* Register indirect w/pre-incr: long. */
1273 1.1 christos t = GET_L_REG (rn) + 4;
1274 1.1 christos SET_L_REG (rn, t);
1275 1.7 christos t &= h8_get_mask (cpu);
1276 1.1 christos *val = GET_MEMORY_L (t);
1277 1.1 christos break;
1278 1.1 christos
1279 1.1 christos case X (OP_DISP, SB): /* Register indirect w/displacement: byte. */
1280 1.1 christos t = GET_L_REG (rn) + abs;
1281 1.7 christos t &= h8_get_mask (cpu);
1282 1.1 christos *val = GET_MEMORY_B (t);
1283 1.1 christos break;
1284 1.1 christos
1285 1.1 christos case X (OP_DISP, SW): /* Register indirect w/displacement: word. */
1286 1.1 christos t = GET_L_REG (rn) + abs;
1287 1.7 christos t &= h8_get_mask (cpu);
1288 1.1 christos *val = GET_MEMORY_W (t);
1289 1.1 christos break;
1290 1.1 christos
1291 1.1 christos case X (OP_DISP, SL): /* Register indirect w/displacement: long. */
1292 1.1 christos t = GET_L_REG (rn) + abs;
1293 1.7 christos t &= h8_get_mask (cpu);
1294 1.1 christos *val =GET_MEMORY_L (t);
1295 1.1 christos break;
1296 1.1 christos
1297 1.1 christos case X (OP_MEM, SL): /* Absolute memory address, long. */
1298 1.1 christos t = GET_MEMORY_L (abs);
1299 1.7 christos t &= h8_get_mask (cpu);
1300 1.1 christos *val = t;
1301 1.1 christos break;
1302 1.1 christos
1303 1.1 christos case X (OP_MEM, SW): /* Absolute memory address, word. */
1304 1.1 christos t = GET_MEMORY_W (abs);
1305 1.7 christos t &= h8_get_mask (cpu);
1306 1.1 christos *val = t;
1307 1.1 christos break;
1308 1.1 christos
1309 1.1 christos case X (OP_PCREL, SB): /* PC relative (for jump, branch etc). */
1310 1.1 christos case X (OP_PCREL, SW):
1311 1.1 christos case X (OP_PCREL, SL):
1312 1.1 christos case X (OP_PCREL, SN):
1313 1.1 christos *val = abs;
1314 1.1 christos break;
1315 1.1 christos
1316 1.7 christos case X (OP_REG_DEC, SB): /* Register direct, affected decrement byte. */
1317 1.7 christos *val = GET_B_REG (rn) - 1;
1318 1.7 christos break;
1319 1.7 christos case X (OP_REG_DEC, SW): /* Register direct, affected decrement word. */
1320 1.7 christos *val = GET_W_REG (rn) - 2;
1321 1.7 christos break;
1322 1.7 christos case X (OP_REG_DEC, SL): /* Register direct, affected decrement long. */
1323 1.7 christos *val = GET_L_REG (rn) - 4;
1324 1.7 christos break;
1325 1.7 christos case X (OP_REG_INC, SB): /* Register direct, affected increment byte. */
1326 1.7 christos *val = GET_B_REG (rn) + 1;
1327 1.7 christos break;
1328 1.7 christos case X (OP_REG_INC, SW): /* Register direct, affected increment word. */
1329 1.7 christos *val = GET_W_REG (rn) + 2;
1330 1.7 christos break;
1331 1.7 christos case X (OP_REG_INC, SL): /* Register direct, affected increment long. */
1332 1.7 christos *val = GET_L_REG (rn) + 4;
1333 1.7 christos break;
1334 1.7 christos
1335 1.1 christos case X (OP_MEM, SB): /* Why isn't this implemented? */
1336 1.1 christos default:
1337 1.6 christos sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
1338 1.1 christos return -1;
1339 1.1 christos }
1340 1.1 christos return 0; /* Success. */
1341 1.1 christos }
1342 1.1 christos
1343 1.1 christos /* Normal fetch. */
1344 1.1 christos
1345 1.1 christos static int
1346 1.1 christos fetch (SIM_DESC sd, ea_type *arg, int *val)
1347 1.1 christos {
1348 1.1 christos return fetch_1 (sd, arg, val, 0);
1349 1.1 christos }
1350 1.1 christos
1351 1.1 christos /* Fetch which will be followed by a store to the same location.
1352 1.1 christos The difference being that we don't want to do a post-increment
1353 1.1 christos or post-decrement at this time: we'll do it when we store. */
1354 1.1 christos
1355 1.1 christos static int
1356 1.1 christos fetch2 (SIM_DESC sd, ea_type *arg, int *val)
1357 1.1 christos {
1358 1.1 christos return fetch_1 (sd, arg, val, 1);
1359 1.1 christos }
1360 1.1 christos
1361 1.1 christos /* Simulate a memory store.
1362 1.1 christos Return 0 for success, -1 for failure.
1363 1.1 christos */
1364 1.1 christos
1365 1.1 christos static int
1366 1.1 christos store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
1367 1.1 christos {
1368 1.6 christos SIM_CPU *cpu = STATE_CPU (sd, 0);
1369 1.1 christos int rn = arg->reg;
1370 1.1 christos int abs = arg->literal;
1371 1.1 christos int t;
1372 1.1 christos
1373 1.1 christos switch (arg->type)
1374 1.1 christos {
1375 1.1 christos /* Indexed register plus displacement mode:
1376 1.1 christos
1377 1.1 christos This new family of addressing modes are similar to OP_DISP
1378 1.1 christos (register plus displacement), with two differences:
1379 1.1 christos 1) INDEXB uses only the least significant byte of the register,
1380 1.1 christos INDEXW uses only the least significant word, and
1381 1.1 christos INDEXL uses the entire register (just like OP_DISP).
1382 1.1 christos and
1383 1.1 christos 2) The displacement value in abs is multiplied by two
1384 1.1 christos for SW-sized operations, and by four for SL-size.
1385 1.1 christos
1386 1.1 christos This gives nine possible variations.
1387 1.1 christos */
1388 1.1 christos
1389 1.1 christos case X (OP_INDEXB, SB):
1390 1.1 christos case X (OP_INDEXB, SW):
1391 1.1 christos case X (OP_INDEXB, SL):
1392 1.1 christos case X (OP_INDEXW, SB):
1393 1.1 christos case X (OP_INDEXW, SW):
1394 1.1 christos case X (OP_INDEXW, SL):
1395 1.1 christos case X (OP_INDEXL, SB):
1396 1.1 christos case X (OP_INDEXL, SW):
1397 1.1 christos case X (OP_INDEXL, SL):
1398 1.1 christos t = GET_L_REG (rn);
1399 1.1 christos switch (OP_KIND (arg->type)) {
1400 1.1 christos case OP_INDEXB: t &= 0xff; break;
1401 1.1 christos case OP_INDEXW: t &= 0xffff; break;
1402 1.1 christos case OP_INDEXL:
1403 1.1 christos default: break;
1404 1.1 christos }
1405 1.1 christos switch (OP_SIZE (arg->type)) {
1406 1.1 christos case SB:
1407 1.7 christos SET_MEMORY_B ((t * 1 + abs) & h8_get_mask (cpu), n);
1408 1.1 christos break;
1409 1.1 christos case SW:
1410 1.7 christos SET_MEMORY_W ((t * 2 + abs) & h8_get_mask (cpu), n);
1411 1.1 christos break;
1412 1.1 christos case SL:
1413 1.7 christos SET_MEMORY_L ((t * 4 + abs) & h8_get_mask (cpu), n);
1414 1.1 christos break;
1415 1.1 christos }
1416 1.1 christos break;
1417 1.1 christos
1418 1.1 christos case X (OP_REG, SB): /* Register direct, byte. */
1419 1.1 christos SET_B_REG (rn, n);
1420 1.1 christos break;
1421 1.1 christos case X (OP_REG, SW): /* Register direct, word. */
1422 1.1 christos SET_W_REG (rn, n);
1423 1.1 christos break;
1424 1.1 christos case X (OP_REG, SL): /* Register direct, long. */
1425 1.1 christos SET_L_REG (rn, n);
1426 1.1 christos break;
1427 1.1 christos
1428 1.1 christos case X (OP_PREDEC, SB): /* Register indirect w/pre-decr, byte. */
1429 1.1 christos t = GET_L_REG (rn);
1430 1.1 christos if (!twice)
1431 1.1 christos t -= 1;
1432 1.1 christos SET_L_REG (rn, t);
1433 1.7 christos t &= h8_get_mask (cpu);
1434 1.1 christos SET_MEMORY_B (t, n);
1435 1.1 christos
1436 1.1 christos break;
1437 1.1 christos case X (OP_PREDEC, SW): /* Register indirect w/pre-decr, word. */
1438 1.1 christos t = GET_L_REG (rn);
1439 1.1 christos if (!twice)
1440 1.1 christos t -= 2;
1441 1.1 christos SET_L_REG (rn, t);
1442 1.7 christos t &= h8_get_mask (cpu);
1443 1.1 christos SET_MEMORY_W (t, n);
1444 1.1 christos break;
1445 1.1 christos
1446 1.1 christos case X (OP_PREDEC, SL): /* Register indirect w/pre-decr, long. */
1447 1.1 christos t = GET_L_REG (rn);
1448 1.1 christos if (!twice)
1449 1.1 christos t -= 4;
1450 1.1 christos SET_L_REG (rn, t);
1451 1.7 christos t &= h8_get_mask (cpu);
1452 1.1 christos SET_MEMORY_L (t, n);
1453 1.1 christos break;
1454 1.1 christos
1455 1.1 christos case X (OP_PREINC, SB): /* Register indirect w/pre-incr, byte. */
1456 1.1 christos t = GET_L_REG (rn);
1457 1.1 christos if (!twice)
1458 1.1 christos t += 1;
1459 1.1 christos SET_L_REG (rn, t);
1460 1.7 christos t &= h8_get_mask (cpu);
1461 1.1 christos SET_MEMORY_B (t, n);
1462 1.1 christos
1463 1.1 christos break;
1464 1.1 christos case X (OP_PREINC, SW): /* Register indirect w/pre-incr, word. */
1465 1.1 christos t = GET_L_REG (rn);
1466 1.1 christos if (!twice)
1467 1.1 christos t += 2;
1468 1.1 christos SET_L_REG (rn, t);
1469 1.7 christos t &= h8_get_mask (cpu);
1470 1.1 christos SET_MEMORY_W (t, n);
1471 1.1 christos break;
1472 1.1 christos
1473 1.1 christos case X (OP_PREINC, SL): /* Register indirect w/pre-incr, long. */
1474 1.1 christos t = GET_L_REG (rn);
1475 1.1 christos if (!twice)
1476 1.1 christos t += 4;
1477 1.1 christos SET_L_REG (rn, t);
1478 1.7 christos t &= h8_get_mask (cpu);
1479 1.1 christos SET_MEMORY_L (t, n);
1480 1.1 christos break;
1481 1.1 christos
1482 1.1 christos case X (OP_POSTDEC, SB): /* Register indirect w/post-decr, byte. */
1483 1.1 christos t = GET_L_REG (rn);
1484 1.1 christos SET_L_REG (rn, t - 1);
1485 1.7 christos t &= h8_get_mask (cpu);
1486 1.1 christos SET_MEMORY_B (t, n);
1487 1.1 christos break;
1488 1.1 christos
1489 1.1 christos case X (OP_POSTDEC, SW): /* Register indirect w/post-decr, word. */
1490 1.1 christos t = GET_L_REG (rn);
1491 1.1 christos SET_L_REG (rn, t - 2);
1492 1.7 christos t &= h8_get_mask (cpu);
1493 1.1 christos SET_MEMORY_W (t, n);
1494 1.1 christos break;
1495 1.1 christos
1496 1.1 christos case X (OP_POSTDEC, SL): /* Register indirect w/post-decr, long. */
1497 1.1 christos t = GET_L_REG (rn);
1498 1.1 christos SET_L_REG (rn, t - 4);
1499 1.7 christos t &= h8_get_mask (cpu);
1500 1.1 christos SET_MEMORY_L (t, n);
1501 1.1 christos break;
1502 1.1 christos
1503 1.1 christos case X (OP_POSTINC, SB): /* Register indirect w/post-incr, byte. */
1504 1.1 christos t = GET_L_REG (rn);
1505 1.1 christos SET_L_REG (rn, t + 1);
1506 1.7 christos t &= h8_get_mask (cpu);
1507 1.1 christos SET_MEMORY_B (t, n);
1508 1.1 christos break;
1509 1.1 christos
1510 1.1 christos case X (OP_POSTINC, SW): /* Register indirect w/post-incr, word. */
1511 1.1 christos t = GET_L_REG (rn);
1512 1.1 christos SET_L_REG (rn, t + 2);
1513 1.7 christos t &= h8_get_mask (cpu);
1514 1.1 christos SET_MEMORY_W (t, n);
1515 1.1 christos break;
1516 1.1 christos
1517 1.1 christos case X (OP_POSTINC, SL): /* Register indirect w/post-incr, long. */
1518 1.1 christos t = GET_L_REG (rn);
1519 1.1 christos SET_L_REG (rn, t + 4);
1520 1.7 christos t &= h8_get_mask (cpu);
1521 1.1 christos SET_MEMORY_L (t, n);
1522 1.1 christos break;
1523 1.1 christos
1524 1.1 christos case X (OP_DISP, SB): /* Register indirect w/displacement, byte. */
1525 1.1 christos t = GET_L_REG (rn) + abs;
1526 1.7 christos t &= h8_get_mask (cpu);
1527 1.1 christos SET_MEMORY_B (t, n);
1528 1.1 christos break;
1529 1.1 christos
1530 1.1 christos case X (OP_DISP, SW): /* Register indirect w/displacement, word. */
1531 1.1 christos t = GET_L_REG (rn) + abs;
1532 1.7 christos t &= h8_get_mask (cpu);
1533 1.1 christos SET_MEMORY_W (t, n);
1534 1.1 christos break;
1535 1.1 christos
1536 1.1 christos case X (OP_DISP, SL): /* Register indirect w/displacement, long. */
1537 1.1 christos t = GET_L_REG (rn) + abs;
1538 1.7 christos t &= h8_get_mask (cpu);
1539 1.1 christos SET_MEMORY_L (t, n);
1540 1.1 christos break;
1541 1.1 christos
1542 1.1 christos
1543 1.1 christos case X (OP_MEM, SB): /* Why isn't this implemented? */
1544 1.1 christos case X (OP_MEM, SW): /* Why isn't this implemented? */
1545 1.1 christos case X (OP_MEM, SL): /* Why isn't this implemented? */
1546 1.1 christos default:
1547 1.6 christos sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
1548 1.1 christos return -1;
1549 1.1 christos }
1550 1.1 christos return 0;
1551 1.1 christos }
1552 1.1 christos
1553 1.1 christos /* Normal store. */
1554 1.1 christos
1555 1.1 christos static int
1556 1.1 christos store (SIM_DESC sd, ea_type *arg, int n)
1557 1.1 christos {
1558 1.1 christos return store_1 (sd, arg, n, 0);
1559 1.1 christos }
1560 1.1 christos
1561 1.1 christos /* Store which follows a fetch from the same location.
1562 1.1 christos The difference being that we don't want to do a pre-increment
1563 1.1 christos or pre-decrement at this time: it was already done when we fetched. */
1564 1.1 christos
1565 1.1 christos static int
1566 1.1 christos store2 (SIM_DESC sd, ea_type *arg, int n)
1567 1.1 christos {
1568 1.1 christos return store_1 (sd, arg, n, 1);
1569 1.1 christos }
1570 1.1 christos
1571 1.8 christos /* Callback for qsort. We sort first based on availablity
1572 1.8 christos (available instructions sort lower). When availability state
1573 1.8 christos is the same, then we use the first 4 bit nibble as a secondary
1574 1.8 christos sort key.
1575 1.8 christos
1576 1.8 christos We don't really care about 100% stability here, just that the
1577 1.8 christos available instructions come first and all instrutions with
1578 1.8 christos the same starting nibble are consecutive.
1579 1.8 christos
1580 1.8 christos We could do even better by recording frequency information into the
1581 1.8 christos main table and using that to sort within a nibble's group with the
1582 1.8 christos highest frequency instructions appearing first. */
1583 1.8 christos
1584 1.8 christos static int
1585 1.8 christos instruction_comparator (const void *p1_, const void *p2_)
1586 1.8 christos {
1587 1.8 christos struct h8_opcode *p1 = (struct h8_opcode *)p1_;
1588 1.8 christos struct h8_opcode *p2 = (struct h8_opcode *)p2_;
1589 1.8 christos
1590 1.8 christos /* The 1st sort key is based on whether or not the
1591 1.8 christos instruction is even available. This reduces the
1592 1.8 christos number of entries we have to look at in the common
1593 1.8 christos case. */
1594 1.8 christos bool p1_available = !((p1->available == AV_H8SX && !h8300sxmode)
1595 1.8 christos || (p1->available == AV_H8S && !h8300smode)
1596 1.8 christos || (p1->available == AV_H8H && !h8300hmode));
1597 1.8 christos
1598 1.8 christos bool p2_available = !((p2->available == AV_H8SX && !h8300sxmode)
1599 1.8 christos || (p2->available == AV_H8S && !h8300smode)
1600 1.8 christos || (p2->available == AV_H8H && !h8300hmode));
1601 1.8 christos
1602 1.8 christos /* Sort so that available instructions come before unavailable
1603 1.8 christos instructions. */
1604 1.8 christos if (p1_available != p2_available)
1605 1.8 christos return p2_available - p1_available;
1606 1.8 christos
1607 1.8 christos /* Secondarily sort based on the first opcode nibble. */
1608 1.8 christos return p1->data.nib[0] - p2->data.nib[0];
1609 1.8 christos }
1610 1.8 christos
1611 1.8 christos
1612 1.8 christos /* OPS is the opcode array, which is initially sorted by mnenomic.
1613 1.8 christos
1614 1.8 christos Sort the array so that the instructions for the sub-architecture
1615 1.8 christos are at the start and unavailable instructions are at the end.
1616 1.8 christos
1617 1.8 christos Within the set of available instructions, further sort them based
1618 1.8 christos on the first 4 bit nibble.
1619 1.8 christos
1620 1.8 christos Then find the first index into OPS for each of the 16 possible
1621 1.8 christos nibbles and record that into NIB_INDICES to speed up decoding. */
1622 1.8 christos
1623 1.8 christos static void
1624 1.8 christos sort_opcodes_and_setup_nibble_indices (struct h8_opcode *ops)
1625 1.8 christos {
1626 1.8 christos const struct h8_opcode *q;
1627 1.8 christos int i;
1628 1.8 christos
1629 1.8 christos /* First sort the OPS array. */
1630 1.8 christos for (i = 0, q = ops; q->name; q++, i++)
1631 1.8 christos ;
1632 1.8 christos qsort (ops, i, sizeof (struct h8_opcode), instruction_comparator);
1633 1.8 christos
1634 1.8 christos /* Now walk the array caching the index of the first
1635 1.8 christos occurrence of each 4 bit nibble. */
1636 1.8 christos memset (nib_indices, -1, sizeof (nib_indices));
1637 1.8 christos for (i = 0, q = ops; q->name; q++, i++)
1638 1.8 christos {
1639 1.8 christos int nib = q->data.nib[0];
1640 1.8 christos
1641 1.8 christos /* Record the location of the first entry with the right
1642 1.8 christos nibble count. */
1643 1.8 christos if (nib_indices[nib] == -1)
1644 1.8 christos nib_indices[nib] = i;
1645 1.8 christos }
1646 1.8 christos }
1647 1.8 christos
1648 1.8 christos
1649 1.1 christos /* Flag to be set whenever a new SIM_DESC object is created. */
1650 1.1 christos static int init_pointers_needed = 1;
1651 1.1 christos
1652 1.1 christos static void
1653 1.1 christos init_pointers (SIM_DESC sd)
1654 1.1 christos {
1655 1.7 christos sim_cpu *cpu = STATE_CPU (sd, 0);
1656 1.7 christos struct h8300_sim_state *state = H8300_SIM_STATE (sd);
1657 1.7 christos
1658 1.1 christos if (init_pointers_needed)
1659 1.1 christos {
1660 1.1 christos int i;
1661 1.1 christos
1662 1.1 christos if (h8300smode && !h8300_normal_mode)
1663 1.1 christos memory_size = H8300S_MSIZE;
1664 1.1 christos else if (h8300hmode && !h8300_normal_mode)
1665 1.1 christos memory_size = H8300H_MSIZE;
1666 1.1 christos else
1667 1.1 christos memory_size = H8300_MSIZE;
1668 1.1 christos /* `msize' must be a power of two. */
1669 1.1 christos if ((memory_size & (memory_size - 1)) != 0)
1670 1.1 christos {
1671 1.6 christos sim_io_printf
1672 1.6 christos (sd,
1673 1.1 christos "init_pointers: bad memory size %d, defaulting to %d.\n",
1674 1.7 christos memory_size, H8300S_MSIZE);
1675 1.7 christos memory_size = H8300S_MSIZE;
1676 1.1 christos }
1677 1.1 christos
1678 1.7 christos if (h8_get_memory_buf (cpu))
1679 1.7 christos free (h8_get_memory_buf (cpu));
1680 1.1 christos
1681 1.7 christos h8_set_memory_buf (cpu, (unsigned char *)
1682 1.1 christos calloc (sizeof (char), memory_size));
1683 1.7 christos state->memory_size = memory_size;
1684 1.1 christos
1685 1.7 christos h8_set_mask (cpu, memory_size - 1);
1686 1.1 christos
1687 1.8 christos memset (h8_get_reg_buf (cpu), 0, sizeof (H8300_SIM_CPU (cpu)->regs));
1688 1.1 christos
1689 1.1 christos for (i = 0; i < 8; i++)
1690 1.1 christos {
1691 1.1 christos /* FIXME: rewrite using local buffer. */
1692 1.7 christos unsigned char *p = (unsigned char *) (h8_get_reg_buf (cpu) + i);
1693 1.7 christos unsigned char *e = (unsigned char *) (h8_get_reg_buf (cpu) + i + 1);
1694 1.7 christos unsigned short *q = (unsigned short *) (h8_get_reg_buf (cpu) + i);
1695 1.7 christos unsigned short *u = (unsigned short *) (h8_get_reg_buf (cpu) + i + 1);
1696 1.7 christos h8_set_reg (cpu, i, 0x00112233);
1697 1.1 christos
1698 1.1 christos while (p < e)
1699 1.1 christos {
1700 1.1 christos if (*p == 0x22)
1701 1.1 christos breg[i] = p;
1702 1.1 christos if (*p == 0x33)
1703 1.1 christos breg[i + 8] = p;
1704 1.1 christos if (*p == 0x11)
1705 1.1 christos breg[i + 16] = p;
1706 1.1 christos if (*p == 0x00)
1707 1.1 christos breg[i + 24] = p;
1708 1.1 christos p++;
1709 1.1 christos }
1710 1.1 christos
1711 1.1 christos wreg[i] = wreg[i + 8] = 0;
1712 1.1 christos while (q < u)
1713 1.1 christos {
1714 1.1 christos if (*q == 0x2233)
1715 1.1 christos {
1716 1.1 christos wreg[i] = q;
1717 1.1 christos }
1718 1.1 christos if (*q == 0x0011)
1719 1.1 christos {
1720 1.1 christos wreg[i + 8] = q;
1721 1.1 christos }
1722 1.1 christos q++;
1723 1.1 christos }
1724 1.1 christos
1725 1.1 christos if (wreg[i] == 0 || wreg[i + 8] == 0)
1726 1.6 christos sim_io_printf (sd, "init_pointers: internal error.\n");
1727 1.1 christos
1728 1.7 christos h8_set_reg (cpu, i, 0);
1729 1.1 christos }
1730 1.1 christos
1731 1.8 christos /* Sort the opcode table and create indices to speed up decode. */
1732 1.8 christos sort_opcodes_and_setup_nibble_indices (ops);
1733 1.8 christos
1734 1.1 christos init_pointers_needed = 0;
1735 1.1 christos }
1736 1.1 christos }
1737 1.1 christos
1738 1.1 christos #define OBITOP(name, f, s, op) \
1739 1.1 christos case O (name, SB): \
1740 1.1 christos { \
1741 1.8 christos int m; \
1742 1.1 christos \
1743 1.1 christos if (f) \
1744 1.1 christos if (fetch (sd, &code->dst, &ea)) \
1745 1.1 christos goto end; \
1746 1.1 christos if (fetch (sd, &code->src, &tmp)) \
1747 1.1 christos goto end; \
1748 1.1 christos m = 1 << (tmp & 7); \
1749 1.1 christos op; \
1750 1.1 christos if (s) \
1751 1.1 christos if (store (sd, &code->dst,ea)) \
1752 1.1 christos goto end; \
1753 1.1 christos goto next; \
1754 1.1 christos }
1755 1.1 christos
1756 1.6 christos static void
1757 1.6 christos step_once (SIM_DESC sd, SIM_CPU *cpu)
1758 1.1 christos {
1759 1.1 christos int cycles = 0;
1760 1.1 christos int insts = 0;
1761 1.1 christos int tick_start = get_now ();
1762 1.1 christos int res;
1763 1.1 christos int tmp;
1764 1.1 christos int rd;
1765 1.1 christos int ea;
1766 1.1 christos int bit;
1767 1.1 christos int pc;
1768 1.1 christos int c, nz, v, n, u, h, ui, intMaskBit;
1769 1.7 christos int trace = 0;
1770 1.7 christos int intMask = 0;
1771 1.1 christos int oldmask;
1772 1.6 christos host_callback *sim_callback = STATE_CALLBACK (sd);
1773 1.1 christos
1774 1.1 christos init_pointers (sd);
1775 1.1 christos
1776 1.7 christos pc = cpu_get_pc (cpu);
1777 1.1 christos
1778 1.1 christos /* The PC should never be odd. */
1779 1.1 christos if (pc & 0x1)
1780 1.1 christos {
1781 1.6 christos sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGBUS);
1782 1.1 christos return;
1783 1.1 christos }
1784 1.1 christos
1785 1.1 christos /* Get Status Register (flags). */
1786 1.7 christos GETSR (cpu);
1787 1.1 christos
1788 1.1 christos if (h8300smode) /* Get exr. */
1789 1.1 christos {
1790 1.7 christos trace = (h8_get_exr (cpu) >> 7) & 1;
1791 1.7 christos intMask = h8_get_exr (cpu) & 7;
1792 1.1 christos }
1793 1.1 christos
1794 1.7 christos oldmask = h8_get_mask (cpu);
1795 1.1 christos if (!h8300hmode || h8300_normal_mode)
1796 1.7 christos h8_set_mask (cpu, 0xffff);
1797 1.1 christos do
1798 1.1 christos {
1799 1.7 christos decoded_inst _code, *code = &_code;
1800 1.7 christos memset (code, 0, sizeof (*code));
1801 1.7 christos decode (sd, cpu, pc, h8_get_memory_buf (cpu) + pc, code);
1802 1.7 christos code->oldpc = pc;
1803 1.1 christos
1804 1.1 christos #if ADEBUG
1805 1.1 christos if (debug)
1806 1.1 christos {
1807 1.1 christos printf ("%x %d %s\n", pc, code->opcode,
1808 1.1 christos code->op ? code->op->name : "**");
1809 1.1 christos }
1810 1.1 christos h8_increment_stats (sd, code->opcode);
1811 1.1 christos #endif
1812 1.1 christos
1813 1.1 christos if (code->opcode)
1814 1.1 christos {
1815 1.1 christos cycles += code->cycles;
1816 1.1 christos insts++;
1817 1.1 christos }
1818 1.1 christos
1819 1.1 christos switch (code->opcode)
1820 1.1 christos {
1821 1.1 christos case O (O_MOVAB, SL):
1822 1.1 christos case O (O_MOVAW, SL):
1823 1.1 christos case O (O_MOVAL, SL):
1824 1.1 christos /* 1) Evaluate 2nd argument (dst).
1825 1.1 christos 2) Mask / zero extend according to whether 1st argument (src)
1826 1.1 christos is INDEXB, INDEXW, or INDEXL.
1827 1.1 christos 3) Left-shift the result by 0, 1 or 2, according to size of mova
1828 1.1 christos (mova/b, mova/w, mova/l).
1829 1.1 christos 4) Add literal value of 1st argument (src).
1830 1.1 christos 5) Store result in 3rd argument (op3).
1831 1.1 christos */
1832 1.1 christos
1833 1.1 christos /* Alas, since this is the only instruction with 3 arguments,
1834 1.1 christos decode doesn't handle them very well. Some fix-up is required.
1835 1.1 christos
1836 1.1 christos a) The size of dst is determined by whether src is
1837 1.1 christos INDEXB or INDEXW. */
1838 1.1 christos
1839 1.1 christos if (OP_KIND (code->src.type) == OP_INDEXB)
1840 1.1 christos code->dst.type = X (OP_KIND (code->dst.type), SB);
1841 1.1 christos else if (OP_KIND (code->src.type) == OP_INDEXW)
1842 1.1 christos code->dst.type = X (OP_KIND (code->dst.type), SW);
1843 1.1 christos
1844 1.1 christos /* b) If op3 == null, then this is the short form of the insn.
1845 1.1 christos Dst is the dispreg of src, and op3 is the 32-bit form
1846 1.1 christos of the same register.
1847 1.1 christos */
1848 1.1 christos
1849 1.7 christos if (code->op3.type == -1)
1850 1.1 christos {
1851 1.1 christos /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
1852 1.1 christos We get to compose dst and op3 as follows:
1853 1.1 christos
1854 1.1 christos op3 is a 32-bit register, ID == src.reg.
1855 1.1 christos dst is the same register, but 8 or 16 bits
1856 1.1 christos depending on whether src is INDEXB or INDEXW.
1857 1.1 christos */
1858 1.1 christos
1859 1.1 christos code->op3.type = X (OP_REG, SL);
1860 1.1 christos code->op3.reg = code->src.reg;
1861 1.1 christos code->op3.literal = 0;
1862 1.1 christos
1863 1.1 christos if (OP_KIND (code->src.type) == OP_INDEXB)
1864 1.1 christos {
1865 1.1 christos code->dst.type = X (OP_REG, SB);
1866 1.1 christos code->dst.reg = code->op3.reg + 8;
1867 1.1 christos }
1868 1.1 christos else
1869 1.1 christos code->dst.type = X (OP_REG, SW);
1870 1.1 christos }
1871 1.1 christos
1872 1.1 christos if (fetch (sd, &code->dst, &ea))
1873 1.1 christos goto end;
1874 1.1 christos
1875 1.1 christos switch (OP_KIND (code->src.type)) {
1876 1.1 christos case OP_INDEXB: ea = ea & 0xff; break;
1877 1.1 christos case OP_INDEXW: ea = ea & 0xffff; break;
1878 1.1 christos case OP_INDEXL: break;
1879 1.1 christos default: goto illegal;
1880 1.1 christos }
1881 1.1 christos
1882 1.1 christos switch (code->opcode) {
1883 1.1 christos case O (O_MOVAB, SL): break;
1884 1.1 christos case O (O_MOVAW, SL): ea = ea << 1; break;
1885 1.1 christos case O (O_MOVAL, SL): ea = ea << 2; break;
1886 1.1 christos default: goto illegal;
1887 1.1 christos }
1888 1.1 christos
1889 1.1 christos ea = ea + code->src.literal;
1890 1.1 christos
1891 1.1 christos if (store (sd, &code->op3, ea))
1892 1.1 christos goto end;
1893 1.1 christos
1894 1.1 christos goto next;
1895 1.1 christos
1896 1.1 christos case O (O_SUBX, SB): /* subx, extended sub */
1897 1.1 christos if (fetch2 (sd, &code->dst, &rd))
1898 1.1 christos goto end;
1899 1.1 christos if (fetch (sd, &code->src, &ea))
1900 1.1 christos goto end;
1901 1.1 christos ea = -(ea + C);
1902 1.1 christos res = rd + ea;
1903 1.1 christos goto alu8;
1904 1.1 christos
1905 1.1 christos case O (O_SUBX, SW): /* subx, extended sub */
1906 1.1 christos if (fetch2 (sd, &code->dst, &rd))
1907 1.1 christos goto end;
1908 1.1 christos if (fetch (sd, &code->src, &ea))
1909 1.1 christos goto end;
1910 1.1 christos ea = -(ea + C);
1911 1.1 christos res = rd + ea;
1912 1.1 christos goto alu16;
1913 1.1 christos
1914 1.1 christos case O (O_SUBX, SL): /* subx, extended sub */
1915 1.1 christos if (fetch2 (sd, &code->dst, &rd))
1916 1.1 christos goto end;
1917 1.1 christos if (fetch (sd, &code->src, &ea))
1918 1.1 christos goto end;
1919 1.1 christos ea = -(ea + C);
1920 1.1 christos res = rd + ea;
1921 1.1 christos goto alu32;
1922 1.1 christos
1923 1.1 christos case O (O_ADDX, SB): /* addx, extended add */
1924 1.1 christos if (fetch2 (sd, &code->dst, &rd))
1925 1.1 christos goto end;
1926 1.1 christos if (fetch (sd, &code->src, &ea))
1927 1.1 christos goto end;
1928 1.1 christos ea = ea + C;
1929 1.1 christos res = rd + ea;
1930 1.1 christos goto alu8;
1931 1.1 christos
1932 1.1 christos case O (O_ADDX, SW): /* addx, extended add */
1933 1.1 christos if (fetch2 (sd, &code->dst, &rd))
1934 1.1 christos goto end;
1935 1.1 christos if (fetch (sd, &code->src, &ea))
1936 1.1 christos goto end;
1937 1.1 christos ea = ea + C;
1938 1.1 christos res = rd + ea;
1939 1.1 christos goto alu16;
1940 1.1 christos
1941 1.1 christos case O (O_ADDX, SL): /* addx, extended add */
1942 1.1 christos if (fetch2 (sd, &code->dst, &rd))
1943 1.1 christos goto end;
1944 1.1 christos if (fetch (sd, &code->src, &ea))
1945 1.1 christos goto end;
1946 1.1 christos ea = ea + C;
1947 1.1 christos res = rd + ea;
1948 1.1 christos goto alu32;
1949 1.1 christos
1950 1.1 christos case O (O_SUB, SB): /* sub.b */
1951 1.1 christos /* Fetch rd and ea. */
1952 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
1953 1.1 christos goto end;
1954 1.1 christos ea = -ea;
1955 1.1 christos res = rd + ea;
1956 1.1 christos goto alu8;
1957 1.1 christos
1958 1.1 christos case O (O_SUB, SW): /* sub.w */
1959 1.1 christos /* Fetch rd and ea. */
1960 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
1961 1.1 christos goto end;
1962 1.1 christos ea = -ea;
1963 1.1 christos res = rd + ea;
1964 1.1 christos goto alu16;
1965 1.1 christos
1966 1.1 christos case O (O_SUB, SL): /* sub.l */
1967 1.1 christos /* Fetch rd and ea. */
1968 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
1969 1.1 christos goto end;
1970 1.1 christos ea = -ea;
1971 1.1 christos res = rd + ea;
1972 1.1 christos goto alu32;
1973 1.1 christos
1974 1.1 christos case O (O_NEG, SB): /* neg.b */
1975 1.1 christos /* Fetch ea. */
1976 1.1 christos if (fetch2 (sd, &code->src, &ea))
1977 1.1 christos goto end;
1978 1.1 christos ea = -ea;
1979 1.1 christos rd = 0;
1980 1.1 christos res = rd + ea;
1981 1.1 christos goto alu8;
1982 1.1 christos
1983 1.1 christos case O (O_NEG, SW): /* neg.w */
1984 1.1 christos /* Fetch ea. */
1985 1.1 christos if (fetch2 (sd, &code->src, &ea))
1986 1.1 christos goto end;
1987 1.1 christos ea = -ea;
1988 1.1 christos rd = 0;
1989 1.1 christos res = rd + ea;
1990 1.1 christos goto alu16;
1991 1.1 christos
1992 1.1 christos case O (O_NEG, SL): /* neg.l */
1993 1.1 christos /* Fetch ea. */
1994 1.1 christos if (fetch2 (sd, &code->src, &ea))
1995 1.1 christos goto end;
1996 1.1 christos ea = -ea;
1997 1.1 christos rd = 0;
1998 1.1 christos res = rd + ea;
1999 1.1 christos goto alu32;
2000 1.1 christos
2001 1.1 christos case O (O_ADD, SB): /* add.b */
2002 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2003 1.1 christos goto end;
2004 1.1 christos if (fetch (sd, &code->src, &ea))
2005 1.1 christos goto end;
2006 1.1 christos res = rd + ea;
2007 1.1 christos goto alu8;
2008 1.1 christos
2009 1.1 christos case O (O_ADD, SW): /* add.w */
2010 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2011 1.1 christos goto end;
2012 1.1 christos if (fetch (sd, &code->src, &ea))
2013 1.1 christos goto end;
2014 1.1 christos res = rd + ea;
2015 1.1 christos goto alu16;
2016 1.1 christos
2017 1.1 christos case O (O_ADD, SL): /* add.l */
2018 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2019 1.1 christos goto end;
2020 1.1 christos if (fetch (sd, &code->src, &ea))
2021 1.1 christos goto end;
2022 1.1 christos res = rd + ea;
2023 1.1 christos goto alu32;
2024 1.1 christos
2025 1.1 christos case O (O_AND, SB): /* and.b */
2026 1.1 christos /* Fetch rd and ea. */
2027 1.7 christos if (fetch2 (sd, &code->dst, &rd) || fetch (sd, &code->src, &ea))
2028 1.1 christos goto end;
2029 1.1 christos res = rd & ea;
2030 1.1 christos goto log8;
2031 1.1 christos
2032 1.1 christos case O (O_AND, SW): /* and.w */
2033 1.1 christos /* Fetch rd and ea. */
2034 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2035 1.1 christos goto end;
2036 1.1 christos res = rd & ea;
2037 1.1 christos goto log16;
2038 1.1 christos
2039 1.1 christos case O (O_AND, SL): /* and.l */
2040 1.1 christos /* Fetch rd and ea. */
2041 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2042 1.1 christos goto end;
2043 1.1 christos res = rd & ea;
2044 1.1 christos goto log32;
2045 1.1 christos
2046 1.1 christos case O (O_OR, SB): /* or.b */
2047 1.1 christos /* Fetch rd and ea. */
2048 1.7 christos if (fetch2 (sd, &code->dst, &rd) || fetch (sd, &code->src, &ea))
2049 1.1 christos goto end;
2050 1.1 christos res = rd | ea;
2051 1.1 christos goto log8;
2052 1.1 christos
2053 1.1 christos case O (O_OR, SW): /* or.w */
2054 1.1 christos /* Fetch rd and ea. */
2055 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2056 1.1 christos goto end;
2057 1.1 christos res = rd | ea;
2058 1.1 christos goto log16;
2059 1.1 christos
2060 1.1 christos case O (O_OR, SL): /* or.l */
2061 1.1 christos /* Fetch rd and ea. */
2062 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2063 1.1 christos goto end;
2064 1.1 christos res = rd | ea;
2065 1.1 christos goto log32;
2066 1.1 christos
2067 1.1 christos case O (O_XOR, SB): /* xor.b */
2068 1.1 christos /* Fetch rd and ea. */
2069 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2070 1.1 christos goto end;
2071 1.1 christos res = rd ^ ea;
2072 1.1 christos goto log8;
2073 1.1 christos
2074 1.1 christos case O (O_XOR, SW): /* xor.w */
2075 1.1 christos /* Fetch rd and ea. */
2076 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2077 1.1 christos goto end;
2078 1.1 christos res = rd ^ ea;
2079 1.1 christos goto log16;
2080 1.1 christos
2081 1.1 christos case O (O_XOR, SL): /* xor.l */
2082 1.1 christos /* Fetch rd and ea. */
2083 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2084 1.1 christos goto end;
2085 1.1 christos res = rd ^ ea;
2086 1.1 christos goto log32;
2087 1.1 christos
2088 1.1 christos case O (O_MOV, SB):
2089 1.1 christos if (fetch (sd, &code->src, &res))
2090 1.1 christos goto end;
2091 1.1 christos if (store (sd, &code->dst, res))
2092 1.1 christos goto end;
2093 1.1 christos goto just_flags_log8;
2094 1.1 christos case O (O_MOV, SW):
2095 1.1 christos if (fetch (sd, &code->src, &res))
2096 1.1 christos goto end;
2097 1.1 christos if (store (sd, &code->dst, res))
2098 1.1 christos goto end;
2099 1.1 christos goto just_flags_log16;
2100 1.1 christos case O (O_MOV, SL):
2101 1.1 christos if (fetch (sd, &code->src, &res))
2102 1.1 christos goto end;
2103 1.1 christos if (store (sd, &code->dst, res))
2104 1.1 christos goto end;
2105 1.1 christos goto just_flags_log32;
2106 1.1 christos
2107 1.1 christos case O (O_MOVMD, SB): /* movmd.b */
2108 1.1 christos ea = GET_W_REG (4);
2109 1.1 christos if (ea == 0)
2110 1.1 christos ea = 0x10000;
2111 1.1 christos
2112 1.1 christos while (ea--)
2113 1.1 christos {
2114 1.1 christos rd = GET_MEMORY_B (GET_L_REG (5));
2115 1.1 christos SET_MEMORY_B (GET_L_REG (6), rd);
2116 1.1 christos SET_L_REG (5, GET_L_REG (5) + 1);
2117 1.1 christos SET_L_REG (6, GET_L_REG (6) + 1);
2118 1.1 christos SET_W_REG (4, ea);
2119 1.1 christos }
2120 1.1 christos goto next;
2121 1.1 christos
2122 1.1 christos case O (O_MOVMD, SW): /* movmd.w */
2123 1.1 christos ea = GET_W_REG (4);
2124 1.1 christos if (ea == 0)
2125 1.1 christos ea = 0x10000;
2126 1.1 christos
2127 1.1 christos while (ea--)
2128 1.1 christos {
2129 1.1 christos rd = GET_MEMORY_W (GET_L_REG (5));
2130 1.1 christos SET_MEMORY_W (GET_L_REG (6), rd);
2131 1.1 christos SET_L_REG (5, GET_L_REG (5) + 2);
2132 1.1 christos SET_L_REG (6, GET_L_REG (6) + 2);
2133 1.1 christos SET_W_REG (4, ea);
2134 1.1 christos }
2135 1.1 christos goto next;
2136 1.1 christos
2137 1.1 christos case O (O_MOVMD, SL): /* movmd.l */
2138 1.1 christos ea = GET_W_REG (4);
2139 1.1 christos if (ea == 0)
2140 1.1 christos ea = 0x10000;
2141 1.1 christos
2142 1.1 christos while (ea--)
2143 1.1 christos {
2144 1.1 christos rd = GET_MEMORY_L (GET_L_REG (5));
2145 1.1 christos SET_MEMORY_L (GET_L_REG (6), rd);
2146 1.1 christos SET_L_REG (5, GET_L_REG (5) + 4);
2147 1.1 christos SET_L_REG (6, GET_L_REG (6) + 4);
2148 1.1 christos SET_W_REG (4, ea);
2149 1.1 christos }
2150 1.1 christos goto next;
2151 1.1 christos
2152 1.1 christos case O (O_MOVSD, SB): /* movsd.b */
2153 1.1 christos /* This instruction implements strncpy, with a conditional branch.
2154 1.1 christos r4 contains n, r5 contains src, and r6 contains dst.
2155 1.1 christos The 16-bit displacement operand is added to the pc
2156 1.1 christos if and only if the end of string is reached before
2157 1.1 christos n bytes are transferred. */
2158 1.1 christos
2159 1.1 christos ea = GET_L_REG (4) & 0xffff;
2160 1.1 christos if (ea == 0)
2161 1.1 christos ea = 0x10000;
2162 1.1 christos
2163 1.1 christos while (ea--)
2164 1.1 christos {
2165 1.1 christos rd = GET_MEMORY_B (GET_L_REG (5));
2166 1.1 christos SET_MEMORY_B (GET_L_REG (6), rd);
2167 1.1 christos SET_L_REG (5, GET_L_REG (5) + 1);
2168 1.1 christos SET_L_REG (6, GET_L_REG (6) + 1);
2169 1.1 christos SET_W_REG (4, ea);
2170 1.1 christos if (rd == 0)
2171 1.1 christos goto condtrue;
2172 1.1 christos }
2173 1.1 christos goto next;
2174 1.1 christos
2175 1.1 christos case O (O_EEPMOV, SB): /* eepmov.b */
2176 1.1 christos case O (O_EEPMOV, SW): /* eepmov.w */
2177 1.1 christos if (h8300hmode || h8300smode)
2178 1.1 christos {
2179 1.1 christos register unsigned char *_src, *_dst;
2180 1.1 christos unsigned int count = ((code->opcode == O (O_EEPMOV, SW))
2181 1.7 christos ? h8_get_reg (cpu, R4_REGNUM) & 0xffff
2182 1.7 christos : h8_get_reg (cpu, R4_REGNUM) & 0xff);
2183 1.1 christos
2184 1.7 christos _src = h8_get_memory_buf (cpu) + h8_get_reg (cpu, R5_REGNUM);
2185 1.7 christos if ((_src + count) >= (h8_get_memory_buf (cpu) + memory_size))
2186 1.7 christos goto illegal;
2187 1.7 christos _dst = h8_get_memory_buf (cpu) + h8_get_reg (cpu, R6_REGNUM);
2188 1.7 christos if ((_dst + count) >= (h8_get_memory_buf (cpu) + memory_size))
2189 1.7 christos goto illegal;
2190 1.1 christos memcpy (_dst, _src, count);
2191 1.1 christos
2192 1.7 christos h8_set_reg (cpu, R5_REGNUM, h8_get_reg (cpu, R5_REGNUM) + count);
2193 1.7 christos h8_set_reg (cpu, R6_REGNUM, h8_get_reg (cpu, R6_REGNUM) + count);
2194 1.7 christos h8_set_reg (cpu, R4_REGNUM, h8_get_reg (cpu, R4_REGNUM) &
2195 1.1 christos ((code->opcode == O (O_EEPMOV, SW))
2196 1.1 christos ? (~0xffff) : (~0xff)));
2197 1.1 christos cycles += 2 * count;
2198 1.1 christos goto next;
2199 1.1 christos }
2200 1.1 christos goto illegal;
2201 1.1 christos
2202 1.1 christos case O (O_ADDS, SL): /* adds (.l) */
2203 1.1 christos /* FIXME fetch.
2204 1.1 christos * This insn only uses register operands, but still
2205 1.1 christos * it would be cleaner to use fetch and store... */
2206 1.1 christos SET_L_REG (code->dst.reg,
2207 1.1 christos GET_L_REG (code->dst.reg)
2208 1.1 christos + code->src.literal);
2209 1.1 christos
2210 1.1 christos goto next;
2211 1.1 christos
2212 1.1 christos case O (O_SUBS, SL): /* subs (.l) */
2213 1.1 christos /* FIXME fetch.
2214 1.1 christos * This insn only uses register operands, but still
2215 1.1 christos * it would be cleaner to use fetch and store... */
2216 1.1 christos SET_L_REG (code->dst.reg,
2217 1.1 christos GET_L_REG (code->dst.reg)
2218 1.1 christos - code->src.literal);
2219 1.1 christos goto next;
2220 1.1 christos
2221 1.1 christos case O (O_CMP, SB): /* cmp.b */
2222 1.1 christos if (fetch (sd, &code->dst, &rd))
2223 1.1 christos goto end;
2224 1.1 christos if (fetch (sd, &code->src, &ea))
2225 1.1 christos goto end;
2226 1.1 christos ea = -ea;
2227 1.1 christos res = rd + ea;
2228 1.1 christos goto just_flags_alu8;
2229 1.1 christos
2230 1.1 christos case O (O_CMP, SW): /* cmp.w */
2231 1.1 christos if (fetch (sd, &code->dst, &rd))
2232 1.1 christos goto end;
2233 1.1 christos if (fetch (sd, &code->src, &ea))
2234 1.1 christos goto end;
2235 1.1 christos ea = -ea;
2236 1.1 christos res = rd + ea;
2237 1.1 christos goto just_flags_alu16;
2238 1.1 christos
2239 1.1 christos case O (O_CMP, SL): /* cmp.l */
2240 1.1 christos if (fetch (sd, &code->dst, &rd))
2241 1.1 christos goto end;
2242 1.1 christos if (fetch (sd, &code->src, &ea))
2243 1.1 christos goto end;
2244 1.1 christos ea = -ea;
2245 1.1 christos res = rd + ea;
2246 1.1 christos goto just_flags_alu32;
2247 1.1 christos
2248 1.1 christos case O (O_DEC, SB): /* dec.b */
2249 1.1 christos /* FIXME fetch.
2250 1.1 christos * This insn only uses register operands, but still
2251 1.1 christos * it would be cleaner to use fetch and store... */
2252 1.1 christos rd = GET_B_REG (code->src.reg);
2253 1.1 christos ea = -1;
2254 1.1 christos res = rd + ea;
2255 1.1 christos SET_B_REG (code->src.reg, res);
2256 1.1 christos goto just_flags_inc8;
2257 1.1 christos
2258 1.1 christos case O (O_DEC, SW): /* dec.w */
2259 1.1 christos /* FIXME fetch.
2260 1.1 christos * This insn only uses register operands, but still
2261 1.1 christos * it would be cleaner to use fetch and store... */
2262 1.1 christos rd = GET_W_REG (code->dst.reg);
2263 1.1 christos ea = -code->src.literal;
2264 1.1 christos res = rd + ea;
2265 1.1 christos SET_W_REG (code->dst.reg, res);
2266 1.1 christos goto just_flags_inc16;
2267 1.1 christos
2268 1.1 christos case O (O_DEC, SL): /* dec.l */
2269 1.1 christos /* FIXME fetch.
2270 1.1 christos * This insn only uses register operands, but still
2271 1.1 christos * it would be cleaner to use fetch and store... */
2272 1.1 christos rd = GET_L_REG (code->dst.reg);
2273 1.1 christos ea = -code->src.literal;
2274 1.1 christos res = rd + ea;
2275 1.1 christos SET_L_REG (code->dst.reg, res);
2276 1.1 christos goto just_flags_inc32;
2277 1.1 christos
2278 1.1 christos case O (O_INC, SB): /* inc.b */
2279 1.1 christos /* FIXME fetch.
2280 1.1 christos * This insn only uses register operands, but still
2281 1.1 christos * it would be cleaner to use fetch and store... */
2282 1.1 christos rd = GET_B_REG (code->src.reg);
2283 1.1 christos ea = 1;
2284 1.1 christos res = rd + ea;
2285 1.1 christos SET_B_REG (code->src.reg, res);
2286 1.1 christos goto just_flags_inc8;
2287 1.1 christos
2288 1.1 christos case O (O_INC, SW): /* inc.w */
2289 1.1 christos /* FIXME fetch.
2290 1.1 christos * This insn only uses register operands, but still
2291 1.1 christos * it would be cleaner to use fetch and store... */
2292 1.1 christos rd = GET_W_REG (code->dst.reg);
2293 1.1 christos ea = code->src.literal;
2294 1.1 christos res = rd + ea;
2295 1.1 christos SET_W_REG (code->dst.reg, res);
2296 1.1 christos goto just_flags_inc16;
2297 1.1 christos
2298 1.1 christos case O (O_INC, SL): /* inc.l */
2299 1.1 christos /* FIXME fetch.
2300 1.1 christos * This insn only uses register operands, but still
2301 1.1 christos * it would be cleaner to use fetch and store... */
2302 1.1 christos rd = GET_L_REG (code->dst.reg);
2303 1.1 christos ea = code->src.literal;
2304 1.1 christos res = rd + ea;
2305 1.1 christos SET_L_REG (code->dst.reg, res);
2306 1.1 christos goto just_flags_inc32;
2307 1.1 christos
2308 1.1 christos case O (O_LDC, SB): /* ldc.b */
2309 1.1 christos if (fetch (sd, &code->src, &res))
2310 1.1 christos goto end;
2311 1.1 christos goto setc;
2312 1.1 christos
2313 1.1 christos case O (O_LDC, SW): /* ldc.w */
2314 1.1 christos if (fetch (sd, &code->src, &res))
2315 1.1 christos goto end;
2316 1.1 christos
2317 1.1 christos /* Word operand, value from MSB, must be shifted. */
2318 1.1 christos res >>= 8;
2319 1.1 christos goto setc;
2320 1.1 christos
2321 1.1 christos case O (O_LDC, SL): /* ldc.l */
2322 1.1 christos if (fetch (sd, &code->src, &res))
2323 1.1 christos goto end;
2324 1.1 christos switch (code->dst.type) {
2325 1.1 christos case X (OP_SBR, SL):
2326 1.7 christos h8_set_sbr (cpu, res);
2327 1.1 christos break;
2328 1.1 christos case X (OP_VBR, SL):
2329 1.7 christos h8_set_vbr (cpu, res);
2330 1.1 christos break;
2331 1.1 christos default:
2332 1.1 christos goto illegal;
2333 1.1 christos }
2334 1.1 christos goto next;
2335 1.1 christos
2336 1.1 christos case O (O_STC, SW): /* stc.w */
2337 1.1 christos case O (O_STC, SB): /* stc.b */
2338 1.1 christos if (code->src.type == X (OP_CCR, SB))
2339 1.1 christos {
2340 1.7 christos BUILDSR (cpu);
2341 1.7 christos res = h8_get_ccr (cpu);
2342 1.1 christos }
2343 1.1 christos else if (code->src.type == X (OP_EXR, SB) && h8300smode)
2344 1.1 christos {
2345 1.1 christos if (h8300smode)
2346 1.7 christos h8_set_exr (cpu, (trace << 7) | intMask);
2347 1.7 christos res = h8_get_exr (cpu);
2348 1.1 christos }
2349 1.1 christos else
2350 1.1 christos goto illegal;
2351 1.1 christos
2352 1.1 christos /* Word operand, value to MSB, must be shifted. */
2353 1.1 christos if (code->opcode == X (O_STC, SW))
2354 1.1 christos res <<= 8;
2355 1.1 christos if (store (sd, &code->dst, res))
2356 1.1 christos goto end;
2357 1.1 christos goto next;
2358 1.1 christos case O (O_STC, SL): /* stc.l */
2359 1.1 christos switch (code->src.type) {
2360 1.1 christos case X (OP_SBR, SL):
2361 1.7 christos res = h8_get_sbr (cpu);
2362 1.1 christos break;
2363 1.1 christos case X (OP_VBR, SL):
2364 1.7 christos res = h8_get_vbr (cpu);
2365 1.1 christos break;
2366 1.1 christos default:
2367 1.1 christos goto illegal;
2368 1.1 christos }
2369 1.1 christos if (store (sd, &code->dst, res))
2370 1.1 christos goto end;
2371 1.1 christos goto next;
2372 1.1 christos
2373 1.1 christos case O (O_ANDC, SB): /* andc.b */
2374 1.1 christos if (code->dst.type == X (OP_CCR, SB))
2375 1.1 christos {
2376 1.7 christos BUILDSR (cpu);
2377 1.7 christos rd = h8_get_ccr (cpu);
2378 1.1 christos }
2379 1.1 christos else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2380 1.1 christos {
2381 1.1 christos if (h8300smode)
2382 1.7 christos h8_set_exr (cpu, (trace << 7) | intMask);
2383 1.7 christos rd = h8_get_exr (cpu);
2384 1.1 christos }
2385 1.1 christos else
2386 1.1 christos goto illegal;
2387 1.1 christos ea = code->src.literal;
2388 1.1 christos res = rd & ea;
2389 1.1 christos goto setc;
2390 1.1 christos
2391 1.1 christos case O (O_ORC, SB): /* orc.b */
2392 1.1 christos if (code->dst.type == X (OP_CCR, SB))
2393 1.1 christos {
2394 1.7 christos BUILDSR (cpu);
2395 1.7 christos rd = h8_get_ccr (cpu);
2396 1.1 christos }
2397 1.1 christos else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2398 1.1 christos {
2399 1.1 christos if (h8300smode)
2400 1.7 christos h8_set_exr (cpu, (trace << 7) | intMask);
2401 1.7 christos rd = h8_get_exr (cpu);
2402 1.1 christos }
2403 1.1 christos else
2404 1.1 christos goto illegal;
2405 1.1 christos ea = code->src.literal;
2406 1.1 christos res = rd | ea;
2407 1.1 christos goto setc;
2408 1.1 christos
2409 1.1 christos case O (O_XORC, SB): /* xorc.b */
2410 1.1 christos if (code->dst.type == X (OP_CCR, SB))
2411 1.1 christos {
2412 1.7 christos BUILDSR (cpu);
2413 1.7 christos rd = h8_get_ccr (cpu);
2414 1.1 christos }
2415 1.1 christos else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2416 1.1 christos {
2417 1.1 christos if (h8300smode)
2418 1.7 christos h8_set_exr (cpu, (trace << 7) | intMask);
2419 1.7 christos rd = h8_get_exr (cpu);
2420 1.1 christos }
2421 1.1 christos else
2422 1.1 christos goto illegal;
2423 1.1 christos ea = code->src.literal;
2424 1.1 christos res = rd ^ ea;
2425 1.1 christos goto setc;
2426 1.1 christos
2427 1.1 christos case O (O_BRAS, SB): /* bra/s */
2428 1.1 christos /* This is basically an ordinary branch, with a delay slot. */
2429 1.1 christos if (fetch (sd, &code->src, &res))
2430 1.1 christos goto end;
2431 1.1 christos
2432 1.1 christos if ((res & 1) == 0)
2433 1.1 christos goto illegal;
2434 1.1 christos
2435 1.1 christos res -= 1;
2436 1.1 christos
2437 1.1 christos /* Execution continues at next instruction, but
2438 1.1 christos delayed_branch is set up for next cycle. */
2439 1.7 christos h8_set_delayed_branch (cpu, code->next_pc + res);
2440 1.1 christos pc = code->next_pc;
2441 1.1 christos goto end;
2442 1.1 christos
2443 1.1 christos case O (O_BRAB, SB): /* bra rd.b */
2444 1.1 christos case O (O_BRAW, SW): /* bra rd.w */
2445 1.1 christos case O (O_BRAL, SL): /* bra erd.l */
2446 1.1 christos if (fetch (sd, &code->src, &rd))
2447 1.1 christos goto end;
2448 1.1 christos switch (OP_SIZE (code->opcode)) {
2449 1.1 christos case SB: rd &= 0xff; break;
2450 1.1 christos case SW: rd &= 0xffff; break;
2451 1.1 christos case SL: rd &= 0xffffffff; break;
2452 1.1 christos }
2453 1.1 christos pc = code->next_pc + rd;
2454 1.1 christos goto end;
2455 1.1 christos
2456 1.1 christos case O (O_BRABC, SB): /* bra/bc, branch if bit clear */
2457 1.1 christos case O (O_BRABS, SB): /* bra/bs, branch if bit set */
2458 1.1 christos case O (O_BSRBC, SB): /* bsr/bc, call if bit clear */
2459 1.1 christos case O (O_BSRBS, SB): /* bsr/bs, call if bit set */
2460 1.1 christos if (fetch (sd, &code->dst, &rd) ||
2461 1.1 christos fetch (sd, &code->src, &bit))
2462 1.1 christos goto end;
2463 1.1 christos
2464 1.1 christos if (code->opcode == O (O_BRABC, SB) || /* branch if clear */
2465 1.1 christos code->opcode == O (O_BSRBC, SB)) /* call if clear */
2466 1.1 christos {
2467 1.1 christos if ((rd & (1 << bit))) /* no branch */
2468 1.1 christos goto next;
2469 1.1 christos }
2470 1.1 christos else /* branch/call if set */
2471 1.1 christos {
2472 1.1 christos if (!(rd & (1 << bit))) /* no branch */
2473 1.1 christos goto next;
2474 1.1 christos }
2475 1.1 christos
2476 1.1 christos if (fetch (sd, &code->op3, &res)) /* branch */
2477 1.1 christos goto end;
2478 1.1 christos pc = code->next_pc + res;
2479 1.1 christos
2480 1.1 christos if (code->opcode == O (O_BRABC, SB) ||
2481 1.1 christos code->opcode == O (O_BRABS, SB)) /* branch */
2482 1.1 christos goto end;
2483 1.1 christos else /* call */
2484 1.1 christos goto call;
2485 1.1 christos
2486 1.1 christos case O (O_BRA, SN):
2487 1.1 christos case O (O_BRA, SL):
2488 1.1 christos case O (O_BRA, SW):
2489 1.1 christos case O (O_BRA, SB): /* bra, branch always */
2490 1.1 christos if (1)
2491 1.1 christos goto condtrue;
2492 1.1 christos goto next;
2493 1.1 christos
2494 1.1 christos case O (O_BRN, SB): /* brn, ;-/ branch never? */
2495 1.1 christos if (0)
2496 1.1 christos goto condtrue;
2497 1.1 christos goto next;
2498 1.1 christos
2499 1.1 christos case O (O_BHI, SB): /* bhi */
2500 1.1 christos if ((C || Z) == 0)
2501 1.1 christos goto condtrue;
2502 1.1 christos goto next;
2503 1.1 christos
2504 1.1 christos
2505 1.1 christos case O (O_BLS, SB): /* bls */
2506 1.1 christos if ((C || Z))
2507 1.1 christos goto condtrue;
2508 1.1 christos goto next;
2509 1.1 christos
2510 1.1 christos case O (O_BCS, SB): /* bcs, branch if carry set */
2511 1.1 christos if ((C == 1))
2512 1.1 christos goto condtrue;
2513 1.1 christos goto next;
2514 1.1 christos
2515 1.1 christos case O (O_BCC, SB): /* bcc, branch if carry clear */
2516 1.1 christos if ((C == 0))
2517 1.1 christos goto condtrue;
2518 1.1 christos goto next;
2519 1.1 christos
2520 1.1 christos case O (O_BEQ, SB): /* beq, branch if zero set */
2521 1.1 christos if (Z)
2522 1.1 christos goto condtrue;
2523 1.1 christos goto next;
2524 1.1 christos case O (O_BGT, SB): /* bgt */
2525 1.1 christos if (((Z || (N ^ V)) == 0))
2526 1.1 christos goto condtrue;
2527 1.1 christos goto next;
2528 1.1 christos
2529 1.1 christos case O (O_BLE, SB): /* ble */
2530 1.1 christos if (((Z || (N ^ V)) == 1))
2531 1.1 christos goto condtrue;
2532 1.1 christos goto next;
2533 1.1 christos
2534 1.1 christos case O (O_BGE, SB): /* bge */
2535 1.1 christos if ((N ^ V) == 0)
2536 1.1 christos goto condtrue;
2537 1.1 christos goto next;
2538 1.1 christos case O (O_BLT, SB): /* blt */
2539 1.1 christos if ((N ^ V))
2540 1.1 christos goto condtrue;
2541 1.1 christos goto next;
2542 1.1 christos case O (O_BMI, SB): /* bmi */
2543 1.1 christos if ((N))
2544 1.1 christos goto condtrue;
2545 1.1 christos goto next;
2546 1.1 christos case O (O_BNE, SB): /* bne, branch if zero clear */
2547 1.1 christos if ((Z == 0))
2548 1.1 christos goto condtrue;
2549 1.1 christos goto next;
2550 1.1 christos
2551 1.1 christos case O (O_BPL, SB): /* bpl */
2552 1.1 christos if (N == 0)
2553 1.1 christos goto condtrue;
2554 1.1 christos goto next;
2555 1.1 christos case O (O_BVC, SB): /* bvc */
2556 1.1 christos if ((V == 0))
2557 1.1 christos goto condtrue;
2558 1.1 christos goto next;
2559 1.1 christos case O (O_BVS, SB): /* bvs */
2560 1.1 christos if ((V == 1))
2561 1.1 christos goto condtrue;
2562 1.1 christos goto next;
2563 1.1 christos
2564 1.1 christos /* Trap for Command Line setup. */
2565 1.1 christos case O (O_SYS_CMDLINE, SB):
2566 1.1 christos {
2567 1.1 christos int i = 0; /* Loop counter. */
2568 1.1 christos int j = 0; /* Loop counter. */
2569 1.1 christos int ind_arg_len = 0; /* Length of each argument. */
2570 1.1 christos int no_of_args = 0; /* The no. or cmdline args. */
2571 1.1 christos int current_location = 0; /* Location of string. */
2572 1.1 christos int old_sp = 0; /* The Initial Stack Pointer. */
2573 1.1 christos int sp_move = 0; /* No. of locations by which the stack needs
2574 1.1 christos to grow. */
2575 1.1 christos int new_sp = 0; /* The final stack pointer location passed
2576 1.1 christos back. */
2577 1.1 christos int *argv_ptrs; /* Pointers of argv strings to be stored. */
2578 1.1 christos int argv_ptrs_location = 0; /* Location of pointers to cmdline
2579 1.1 christos args on the stack. */
2580 1.1 christos int char_ptr_size = 0; /* Size of a character pointer on
2581 1.1 christos target machine. */
2582 1.1 christos int addr_cmdline = 0; /* Memory location where cmdline has
2583 1.1 christos to be stored. */
2584 1.1 christos int size_cmdline = 0; /* Size of cmdline. */
2585 1.1 christos
2586 1.1 christos /* Set the address of 256 free locations where command line is
2587 1.1 christos stored. */
2588 1.1 christos addr_cmdline = cmdline_location();
2589 1.7 christos h8_set_reg (cpu, 0, addr_cmdline);
2590 1.1 christos
2591 1.1 christos /* Counting the no. of commandline arguments. */
2592 1.7 christos for (i = 0; h8_get_cmdline_arg (cpu, i) != NULL; i++)
2593 1.1 christos continue;
2594 1.1 christos
2595 1.1 christos /* No. of arguments in the command line. */
2596 1.1 christos no_of_args = i;
2597 1.1 christos
2598 1.1 christos /* Current location is just a temporary variable,which we are
2599 1.1 christos setting to the point to the start of our commandline string. */
2600 1.1 christos current_location = addr_cmdline;
2601 1.1 christos
2602 1.1 christos /* Allocating space for storing pointers of the command line
2603 1.1 christos arguments. */
2604 1.1 christos argv_ptrs = (int *) malloc (sizeof (int) * no_of_args);
2605 1.1 christos
2606 1.1 christos /* Setting char_ptr_size to the sizeof (char *) on the different
2607 1.1 christos architectures. */
2608 1.1 christos if ((h8300hmode || h8300smode) && !h8300_normal_mode)
2609 1.1 christos {
2610 1.1 christos char_ptr_size = 4;
2611 1.1 christos }
2612 1.1 christos else
2613 1.1 christos {
2614 1.1 christos char_ptr_size = 2;
2615 1.1 christos }
2616 1.1 christos
2617 1.1 christos for (i = 0; i < no_of_args; i++)
2618 1.1 christos {
2619 1.1 christos ind_arg_len = 0;
2620 1.1 christos
2621 1.1 christos /* The size of the commandline argument. */
2622 1.7 christos ind_arg_len = strlen (h8_get_cmdline_arg (cpu, i)) + 1;
2623 1.1 christos
2624 1.1 christos /* The total size of the command line string. */
2625 1.1 christos size_cmdline += ind_arg_len;
2626 1.1 christos
2627 1.1 christos /* As we have only 256 bytes, we need to provide a graceful
2628 1.1 christos exit. Anyways, a program using command line arguments
2629 1.1 christos where we cannot store all the command line arguments
2630 1.1 christos given may behave unpredictably. */
2631 1.1 christos if (size_cmdline >= 256)
2632 1.1 christos {
2633 1.7 christos h8_set_reg (cpu, 0, 0);
2634 1.1 christos goto next;
2635 1.1 christos }
2636 1.1 christos else
2637 1.1 christos {
2638 1.1 christos /* current_location points to the memory where the next
2639 1.1 christos commandline argument is stored. */
2640 1.1 christos argv_ptrs[i] = current_location;
2641 1.1 christos for (j = 0; j < ind_arg_len; j++)
2642 1.1 christos {
2643 1.1 christos SET_MEMORY_B ((current_location +
2644 1.1 christos (sizeof (char) * j)),
2645 1.7 christos *(h8_get_cmdline_arg (cpu, i) +
2646 1.1 christos sizeof (char) * j));
2647 1.1 christos }
2648 1.1 christos
2649 1.1 christos /* Setting current_location to the starting of next
2650 1.1 christos argument. */
2651 1.1 christos current_location += ind_arg_len;
2652 1.1 christos }
2653 1.1 christos }
2654 1.1 christos
2655 1.1 christos /* This is the original position of the stack pointer. */
2656 1.7 christos old_sp = h8_get_reg (cpu, SP_REGNUM);
2657 1.1 christos
2658 1.1 christos /* We need space from the stack to store the pointers to argvs. */
2659 1.1 christos /* As we will infringe on the stack, we need to shift the stack
2660 1.1 christos pointer so that the data is not overwritten. We calculate how
2661 1.1 christos much space is required. */
2662 1.1 christos sp_move = (no_of_args) * (char_ptr_size);
2663 1.1 christos
2664 1.1 christos /* The final position of stack pointer, we have thus taken some
2665 1.1 christos space from the stack. */
2666 1.1 christos new_sp = old_sp - sp_move;
2667 1.1 christos
2668 1.1 christos /* Temporary variable holding value where the argv pointers need
2669 1.1 christos to be stored. */
2670 1.1 christos argv_ptrs_location = new_sp;
2671 1.1 christos
2672 1.1 christos /* The argv pointers are stored at sequential locations. As per
2673 1.1 christos the H8300 ABI. */
2674 1.1 christos for (i = 0; i < no_of_args; i++)
2675 1.1 christos {
2676 1.1 christos /* Saving the argv pointer. */
2677 1.1 christos if ((h8300hmode || h8300smode) && !h8300_normal_mode)
2678 1.1 christos {
2679 1.1 christos SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]);
2680 1.1 christos }
2681 1.1 christos else
2682 1.1 christos {
2683 1.1 christos SET_MEMORY_W (argv_ptrs_location, argv_ptrs[i]);
2684 1.1 christos }
2685 1.1 christos
2686 1.1 christos /* The next location where the pointer to the next argv
2687 1.1 christos string has to be stored. */
2688 1.1 christos argv_ptrs_location += char_ptr_size;
2689 1.1 christos }
2690 1.1 christos
2691 1.1 christos /* Required by POSIX, Setting 0x0 at the end of the list of argv
2692 1.1 christos pointers. */
2693 1.1 christos if ((h8300hmode || h8300smode) && !h8300_normal_mode)
2694 1.1 christos {
2695 1.1 christos SET_MEMORY_L (old_sp, 0x0);
2696 1.1 christos }
2697 1.1 christos else
2698 1.1 christos {
2699 1.1 christos SET_MEMORY_W (old_sp, 0x0);
2700 1.1 christos }
2701 1.1 christos
2702 1.1 christos /* Freeing allocated memory. */
2703 1.1 christos free (argv_ptrs);
2704 1.1 christos for (i = 0; i <= no_of_args; i++)
2705 1.1 christos {
2706 1.7 christos free (h8_get_cmdline_arg (cpu, i));
2707 1.1 christos }
2708 1.7 christos free (h8_get_command_line (cpu));
2709 1.1 christos
2710 1.1 christos /* The no. of argv arguments are returned in Reg 0. */
2711 1.7 christos h8_set_reg (cpu, 0, no_of_args);
2712 1.1 christos /* The Pointer to argv in Register 1. */
2713 1.7 christos h8_set_reg (cpu, 1, new_sp);
2714 1.1 christos /* Setting the stack pointer to the new value. */
2715 1.7 christos h8_set_reg (cpu, SP_REGNUM, new_sp);
2716 1.1 christos }
2717 1.1 christos goto next;
2718 1.1 christos
2719 1.1 christos /* System call processing starts. */
2720 1.1 christos case O (O_SYS_OPEN, SB):
2721 1.1 christos {
2722 1.1 christos int len = 0; /* Length of filename. */
2723 1.1 christos char *filename; /* Filename would go here. */
2724 1.1 christos char temp_char; /* Temporary character */
2725 1.1 christos int mode = 0; /* Mode bits for the file. */
2726 1.1 christos int open_return; /* Return value of open, file descriptor. */
2727 1.1 christos int i; /* Loop counter */
2728 1.1 christos int filename_ptr; /* Pointer to filename in cpu memory. */
2729 1.1 christos
2730 1.1 christos /* Setting filename_ptr to first argument of open, */
2731 1.1 christos /* and trying to get mode. */
2732 1.1 christos if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode)
2733 1.1 christos {
2734 1.1 christos filename_ptr = GET_L_REG (0);
2735 1.7 christos mode = GET_MEMORY_L (h8_get_reg (cpu, SP_REGNUM) + 4);
2736 1.1 christos }
2737 1.1 christos else
2738 1.1 christos {
2739 1.1 christos filename_ptr = GET_W_REG (0);
2740 1.7 christos mode = GET_MEMORY_W (h8_get_reg (cpu, SP_REGNUM) + 2);
2741 1.1 christos }
2742 1.1 christos
2743 1.1 christos /* Trying to find the length of the filename. */
2744 1.7 christos temp_char = GET_MEMORY_B (h8_get_reg (cpu, 0));
2745 1.1 christos
2746 1.1 christos len = 1;
2747 1.1 christos while (temp_char != '\0')
2748 1.1 christos {
2749 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + len);
2750 1.1 christos len++;
2751 1.1 christos }
2752 1.1 christos
2753 1.1 christos /* Allocating space for the filename. */
2754 1.1 christos filename = (char *) malloc (sizeof (char) * len);
2755 1.1 christos
2756 1.1 christos /* String copying the filename from memory. */
2757 1.1 christos for (i = 0; i < len; i++)
2758 1.1 christos {
2759 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + i);
2760 1.1 christos filename[i] = temp_char;
2761 1.1 christos }
2762 1.1 christos
2763 1.1 christos /* Callback to open and return the file descriptor. */
2764 1.1 christos open_return = sim_callback->open (sim_callback, filename, mode);
2765 1.1 christos
2766 1.1 christos /* Return value in register 0. */
2767 1.7 christos h8_set_reg (cpu, 0, open_return);
2768 1.1 christos
2769 1.1 christos /* Freeing memory used for filename. */
2770 1.1 christos free (filename);
2771 1.1 christos }
2772 1.1 christos goto next;
2773 1.1 christos
2774 1.1 christos case O (O_SYS_READ, SB):
2775 1.1 christos {
2776 1.1 christos char *char_ptr; /* Where characters read would be stored. */
2777 1.1 christos int fd; /* File descriptor */
2778 1.1 christos int buf_size; /* BUF_SIZE parameter in read. */
2779 1.1 christos int i = 0; /* Temporary Loop counter */
2780 1.1 christos int read_return = 0; /* Return value from callback to
2781 1.1 christos read. */
2782 1.1 christos
2783 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2784 1.1 christos buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
2785 1.1 christos
2786 1.1 christos char_ptr = (char *) malloc (sizeof (char) * buf_size);
2787 1.1 christos
2788 1.1 christos /* Callback to read and return the no. of characters read. */
2789 1.1 christos read_return =
2790 1.1 christos sim_callback->read (sim_callback, fd, char_ptr, buf_size);
2791 1.1 christos
2792 1.1 christos /* The characters read are stored in cpu memory. */
2793 1.1 christos for (i = 0; i < buf_size; i++)
2794 1.1 christos {
2795 1.7 christos SET_MEMORY_B ((h8_get_reg (cpu, 1) + (sizeof (char) * i)),
2796 1.1 christos *(char_ptr + (sizeof (char) * i)));
2797 1.1 christos }
2798 1.1 christos
2799 1.1 christos /* Return value in Register 0. */
2800 1.7 christos h8_set_reg (cpu, 0, read_return);
2801 1.1 christos
2802 1.1 christos /* Freeing memory used as buffer. */
2803 1.1 christos free (char_ptr);
2804 1.1 christos }
2805 1.1 christos goto next;
2806 1.1 christos
2807 1.1 christos case O (O_SYS_WRITE, SB):
2808 1.1 christos {
2809 1.1 christos int fd; /* File descriptor */
2810 1.1 christos char temp_char; /* Temporary character */
2811 1.1 christos int len; /* Length of write, Parameter II to write. */
2812 1.1 christos int char_ptr; /* Character Pointer, Parameter I of write. */
2813 1.1 christos char *ptr; /* Where characters to be written are stored.
2814 1.1 christos */
2815 1.1 christos int write_return; /* Return value from callback to write. */
2816 1.1 christos int i = 0; /* Loop counter */
2817 1.1 christos
2818 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2819 1.1 christos char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
2820 1.1 christos len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
2821 1.1 christos
2822 1.1 christos /* Allocating space for the characters to be written. */
2823 1.1 christos ptr = (char *) malloc (sizeof (char) * len);
2824 1.1 christos
2825 1.1 christos /* Fetching the characters from cpu memory. */
2826 1.1 christos for (i = 0; i < len; i++)
2827 1.1 christos {
2828 1.1 christos temp_char = GET_MEMORY_B (char_ptr + i);
2829 1.1 christos ptr[i] = temp_char;
2830 1.1 christos }
2831 1.1 christos
2832 1.1 christos /* Callback write and return the no. of characters written. */
2833 1.1 christos write_return = sim_callback->write (sim_callback, fd, ptr, len);
2834 1.1 christos
2835 1.1 christos /* Return value in Register 0. */
2836 1.7 christos h8_set_reg (cpu, 0, write_return);
2837 1.1 christos
2838 1.1 christos /* Freeing memory used as buffer. */
2839 1.1 christos free (ptr);
2840 1.1 christos }
2841 1.1 christos goto next;
2842 1.1 christos
2843 1.1 christos case O (O_SYS_LSEEK, SB):
2844 1.1 christos {
2845 1.1 christos int fd; /* File descriptor */
2846 1.1 christos int offset; /* Offset */
2847 1.1 christos int origin; /* Origin */
2848 1.1 christos int lseek_return; /* Return value from callback to lseek. */
2849 1.1 christos
2850 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2851 1.1 christos offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
2852 1.1 christos origin = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
2853 1.1 christos
2854 1.1 christos /* Callback lseek and return offset. */
2855 1.1 christos lseek_return =
2856 1.1 christos sim_callback->lseek (sim_callback, fd, offset, origin);
2857 1.1 christos
2858 1.1 christos /* Return value in register 0. */
2859 1.7 christos h8_set_reg (cpu, 0, lseek_return);
2860 1.1 christos }
2861 1.1 christos goto next;
2862 1.1 christos
2863 1.1 christos case O (O_SYS_CLOSE, SB):
2864 1.1 christos {
2865 1.1 christos int fd; /* File descriptor */
2866 1.1 christos int close_return; /* Return value from callback to close. */
2867 1.1 christos
2868 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2869 1.1 christos
2870 1.1 christos /* Callback close and return. */
2871 1.1 christos close_return = sim_callback->close (sim_callback, fd);
2872 1.1 christos
2873 1.1 christos /* Return value in register 0. */
2874 1.7 christos h8_set_reg (cpu, 0, close_return);
2875 1.1 christos }
2876 1.1 christos goto next;
2877 1.1 christos
2878 1.1 christos case O (O_SYS_FSTAT, SB):
2879 1.1 christos {
2880 1.1 christos int fd; /* File descriptor */
2881 1.1 christos struct stat stat_rec; /* Stat record */
2882 1.1 christos int fstat_return; /* Return value from callback to stat. */
2883 1.1 christos int stat_ptr; /* Pointer to stat record. */
2884 1.1 christos
2885 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2886 1.1 christos
2887 1.1 christos /* Setting stat_ptr to second argument of stat. */
2888 1.1 christos stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
2889 1.1 christos
2890 1.1 christos /* Callback stat and return. */
2891 1.3 christos fstat_return = sim_callback->to_fstat (sim_callback, fd,
2892 1.3 christos &stat_rec);
2893 1.1 christos
2894 1.1 christos /* Setting up the stat structure returned. */
2895 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
2896 1.1 christos stat_ptr += 2;
2897 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
2898 1.1 christos stat_ptr += 2;
2899 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
2900 1.1 christos stat_ptr += 4;
2901 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
2902 1.1 christos stat_ptr += 2;
2903 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
2904 1.1 christos stat_ptr += 2;
2905 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
2906 1.1 christos stat_ptr += 2;
2907 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
2908 1.1 christos stat_ptr += 2;
2909 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_size);
2910 1.1 christos stat_ptr += 4;
2911 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
2912 1.1 christos stat_ptr += 8;
2913 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
2914 1.1 christos stat_ptr += 8;
2915 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
2916 1.1 christos
2917 1.1 christos /* Return value in register 0. */
2918 1.7 christos h8_set_reg (cpu, 0, fstat_return);
2919 1.1 christos }
2920 1.1 christos goto next;
2921 1.1 christos
2922 1.1 christos case O (O_SYS_STAT, SB):
2923 1.1 christos {
2924 1.1 christos int len = 0; /* Length of filename. */
2925 1.1 christos char *filename; /* Filename would go here. */
2926 1.1 christos char temp_char; /* Temporary character */
2927 1.1 christos int filename_ptr; /* Pointer to filename in cpu memory. */
2928 1.1 christos struct stat stat_rec; /* Stat record */
2929 1.1 christos int stat_return; /* Return value from callback to stat */
2930 1.1 christos int stat_ptr; /* Pointer to stat record. */
2931 1.1 christos int i = 0; /* Loop Counter */
2932 1.1 christos
2933 1.1 christos /* Setting filename_ptr to first argument of open. */
2934 1.1 christos filename_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2935 1.1 christos
2936 1.1 christos /* Trying to find the length of the filename. */
2937 1.7 christos temp_char = GET_MEMORY_B (h8_get_reg (cpu, 0));
2938 1.1 christos
2939 1.1 christos len = 1;
2940 1.1 christos while (temp_char != '\0')
2941 1.1 christos {
2942 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + len);
2943 1.1 christos len++;
2944 1.1 christos }
2945 1.1 christos
2946 1.1 christos /* Allocating space for the filename. */
2947 1.1 christos filename = (char *) malloc (sizeof (char) * len);
2948 1.1 christos
2949 1.1 christos /* String copying the filename from memory. */
2950 1.1 christos for (i = 0; i < len; i++)
2951 1.1 christos {
2952 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + i);
2953 1.1 christos filename[i] = temp_char;
2954 1.1 christos }
2955 1.1 christos
2956 1.1 christos /* Setting stat_ptr to second argument of stat. */
2957 1.7 christos /* stat_ptr = h8_get_reg (cpu, 1); */
2958 1.1 christos stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
2959 1.1 christos
2960 1.1 christos /* Callback stat and return. */
2961 1.1 christos stat_return =
2962 1.3 christos sim_callback->to_stat (sim_callback, filename, &stat_rec);
2963 1.1 christos
2964 1.1 christos /* Freeing memory used for filename. */
2965 1.1 christos free (filename);
2966 1.1 christos
2967 1.1 christos /* Setting up the stat structure returned. */
2968 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
2969 1.1 christos stat_ptr += 2;
2970 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
2971 1.1 christos stat_ptr += 2;
2972 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
2973 1.1 christos stat_ptr += 4;
2974 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
2975 1.1 christos stat_ptr += 2;
2976 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
2977 1.1 christos stat_ptr += 2;
2978 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
2979 1.1 christos stat_ptr += 2;
2980 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
2981 1.1 christos stat_ptr += 2;
2982 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_size);
2983 1.1 christos stat_ptr += 4;
2984 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
2985 1.1 christos stat_ptr += 8;
2986 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
2987 1.1 christos stat_ptr += 8;
2988 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
2989 1.1 christos
2990 1.1 christos /* Return value in register 0. */
2991 1.7 christos h8_set_reg (cpu, 0, stat_return);
2992 1.1 christos }
2993 1.1 christos goto next;
2994 1.1 christos /* End of system call processing. */
2995 1.1 christos
2996 1.1 christos case O (O_NOT, SB): /* not.b */
2997 1.1 christos if (fetch2 (sd, &code->src, &rd))
2998 1.1 christos goto end;
2999 1.1 christos rd = ~rd;
3000 1.1 christos v = 0;
3001 1.1 christos goto shift8;
3002 1.1 christos
3003 1.1 christos case O (O_NOT, SW): /* not.w */
3004 1.1 christos if (fetch2 (sd, &code->src, &rd))
3005 1.1 christos goto end;
3006 1.1 christos rd = ~rd;
3007 1.1 christos v = 0;
3008 1.1 christos goto shift16;
3009 1.1 christos
3010 1.1 christos case O (O_NOT, SL): /* not.l */
3011 1.1 christos if (fetch2 (sd, &code->src, &rd))
3012 1.1 christos goto end;
3013 1.1 christos rd = ~rd;
3014 1.1 christos v = 0;
3015 1.1 christos goto shift32;
3016 1.1 christos
3017 1.1 christos case O (O_SHLL, SB): /* shll.b */
3018 1.1 christos case O (O_SHLR, SB): /* shlr.b */
3019 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3020 1.1 christos goto end;
3021 1.1 christos
3022 1.1 christos if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3023 1.1 christos ea = 1; /* unary op */
3024 1.1 christos else /* binary op */
3025 1.1 christos fetch (sd, &code->src, &ea);
3026 1.1 christos
3027 1.1 christos if (code->opcode == O (O_SHLL, SB))
3028 1.1 christos {
3029 1.1 christos v = (ea > 8);
3030 1.1 christos c = rd & (0x80 >> (ea - 1));
3031 1.1 christos rd <<= ea;
3032 1.1 christos }
3033 1.1 christos else
3034 1.1 christos {
3035 1.1 christos v = 0;
3036 1.1 christos c = rd & (1 << (ea - 1));
3037 1.1 christos rd = (unsigned char) rd >> ea;
3038 1.1 christos }
3039 1.1 christos goto shift8;
3040 1.1 christos
3041 1.1 christos case O (O_SHLL, SW): /* shll.w */
3042 1.1 christos case O (O_SHLR, SW): /* shlr.w */
3043 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3044 1.1 christos goto end;
3045 1.1 christos
3046 1.1 christos if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3047 1.1 christos ea = 1; /* unary op */
3048 1.1 christos else
3049 1.1 christos fetch (sd, &code->src, &ea);
3050 1.1 christos
3051 1.1 christos if (code->opcode == O (O_SHLL, SW))
3052 1.1 christos {
3053 1.1 christos v = (ea > 16);
3054 1.1 christos c = rd & (0x8000 >> (ea - 1));
3055 1.1 christos rd <<= ea;
3056 1.1 christos }
3057 1.1 christos else
3058 1.1 christos {
3059 1.1 christos v = 0;
3060 1.1 christos c = rd & (1 << (ea - 1));
3061 1.1 christos rd = (unsigned short) rd >> ea;
3062 1.1 christos }
3063 1.1 christos goto shift16;
3064 1.1 christos
3065 1.1 christos case O (O_SHLL, SL): /* shll.l */
3066 1.1 christos case O (O_SHLR, SL): /* shlr.l */
3067 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3068 1.1 christos goto end;
3069 1.1 christos
3070 1.1 christos if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3071 1.1 christos ea = 1; /* unary op */
3072 1.1 christos else
3073 1.1 christos fetch (sd, &code->src, &ea);
3074 1.1 christos
3075 1.1 christos if (code->opcode == O (O_SHLL, SL))
3076 1.1 christos {
3077 1.1 christos v = (ea > 32);
3078 1.1 christos c = rd & (0x80000000 >> (ea - 1));
3079 1.1 christos rd <<= ea;
3080 1.1 christos }
3081 1.1 christos else
3082 1.1 christos {
3083 1.1 christos v = 0;
3084 1.1 christos c = rd & (1 << (ea - 1));
3085 1.1 christos rd = (unsigned int) rd >> ea;
3086 1.1 christos }
3087 1.1 christos goto shift32;
3088 1.1 christos
3089 1.1 christos case O (O_SHAL, SB):
3090 1.1 christos case O (O_SHAR, SB):
3091 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3092 1.1 christos goto end;
3093 1.1 christos
3094 1.1 christos if (code->src.type == X (OP_IMM, SB))
3095 1.1 christos fetch (sd, &code->src, &ea);
3096 1.1 christos else
3097 1.1 christos ea = 1;
3098 1.1 christos
3099 1.1 christos if (code->opcode == O (O_SHAL, SB))
3100 1.1 christos {
3101 1.1 christos c = rd & (0x80 >> (ea - 1));
3102 1.1 christos res = rd >> (7 - ea);
3103 1.1 christos v = ((res & 1) && !(res & 2))
3104 1.1 christos || (!(res & 1) && (res & 2));
3105 1.1 christos rd <<= ea;
3106 1.1 christos }
3107 1.1 christos else
3108 1.1 christos {
3109 1.1 christos c = rd & (1 << (ea - 1));
3110 1.1 christos v = 0;
3111 1.1 christos rd = ((signed char) rd) >> ea;
3112 1.1 christos }
3113 1.1 christos goto shift8;
3114 1.1 christos
3115 1.1 christos case O (O_SHAL, SW):
3116 1.1 christos case O (O_SHAR, SW):
3117 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3118 1.1 christos goto end;
3119 1.1 christos
3120 1.1 christos if (code->src.type == X (OP_IMM, SW))
3121 1.1 christos fetch (sd, &code->src, &ea);
3122 1.1 christos else
3123 1.1 christos ea = 1;
3124 1.1 christos
3125 1.1 christos if (code->opcode == O (O_SHAL, SW))
3126 1.1 christos {
3127 1.1 christos c = rd & (0x8000 >> (ea - 1));
3128 1.1 christos res = rd >> (15 - ea);
3129 1.1 christos v = ((res & 1) && !(res & 2))
3130 1.1 christos || (!(res & 1) && (res & 2));
3131 1.1 christos rd <<= ea;
3132 1.1 christos }
3133 1.1 christos else
3134 1.1 christos {
3135 1.1 christos c = rd & (1 << (ea - 1));
3136 1.1 christos v = 0;
3137 1.1 christos rd = ((signed short) rd) >> ea;
3138 1.1 christos }
3139 1.1 christos goto shift16;
3140 1.1 christos
3141 1.1 christos case O (O_SHAL, SL):
3142 1.1 christos case O (O_SHAR, SL):
3143 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3144 1.1 christos goto end;
3145 1.1 christos
3146 1.1 christos if (code->src.type == X (OP_IMM, SL))
3147 1.1 christos fetch (sd, &code->src, &ea);
3148 1.1 christos else
3149 1.1 christos ea = 1;
3150 1.1 christos
3151 1.1 christos if (code->opcode == O (O_SHAL, SL))
3152 1.1 christos {
3153 1.1 christos c = rd & (0x80000000 >> (ea - 1));
3154 1.1 christos res = rd >> (31 - ea);
3155 1.1 christos v = ((res & 1) && !(res & 2))
3156 1.1 christos || (!(res & 1) && (res & 2));
3157 1.1 christos rd <<= ea;
3158 1.1 christos }
3159 1.1 christos else
3160 1.1 christos {
3161 1.1 christos c = rd & (1 << (ea - 1));
3162 1.1 christos v = 0;
3163 1.1 christos rd = ((signed int) rd) >> ea;
3164 1.1 christos }
3165 1.1 christos goto shift32;
3166 1.1 christos
3167 1.1 christos case O (O_ROTL, SB):
3168 1.1 christos case O (O_ROTR, SB):
3169 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3170 1.1 christos goto end;
3171 1.1 christos
3172 1.1 christos if (code->src.type == X (OP_IMM, SB))
3173 1.1 christos fetch (sd, &code->src, &ea);
3174 1.1 christos else
3175 1.1 christos ea = 1;
3176 1.1 christos
3177 1.1 christos while (ea--)
3178 1.1 christos if (code->opcode == O (O_ROTL, SB))
3179 1.1 christos {
3180 1.1 christos c = rd & 0x80;
3181 1.1 christos rd <<= 1;
3182 1.1 christos if (c)
3183 1.1 christos rd |= 1;
3184 1.1 christos }
3185 1.1 christos else
3186 1.1 christos {
3187 1.1 christos c = rd & 1;
3188 1.1 christos rd = ((unsigned char) rd) >> 1;
3189 1.1 christos if (c)
3190 1.1 christos rd |= 0x80;
3191 1.1 christos }
3192 1.1 christos
3193 1.1 christos v = 0;
3194 1.1 christos goto shift8;
3195 1.1 christos
3196 1.1 christos case O (O_ROTL, SW):
3197 1.1 christos case O (O_ROTR, SW):
3198 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3199 1.1 christos goto end;
3200 1.1 christos
3201 1.1 christos if (code->src.type == X (OP_IMM, SW))
3202 1.1 christos fetch (sd, &code->src, &ea);
3203 1.1 christos else
3204 1.1 christos ea = 1;
3205 1.1 christos
3206 1.1 christos while (ea--)
3207 1.1 christos if (code->opcode == O (O_ROTL, SW))
3208 1.1 christos {
3209 1.1 christos c = rd & 0x8000;
3210 1.1 christos rd <<= 1;
3211 1.1 christos if (c)
3212 1.1 christos rd |= 1;
3213 1.1 christos }
3214 1.1 christos else
3215 1.1 christos {
3216 1.1 christos c = rd & 1;
3217 1.1 christos rd = ((unsigned short) rd) >> 1;
3218 1.1 christos if (c)
3219 1.1 christos rd |= 0x8000;
3220 1.1 christos }
3221 1.1 christos
3222 1.1 christos v = 0;
3223 1.1 christos goto shift16;
3224 1.1 christos
3225 1.1 christos case O (O_ROTL, SL):
3226 1.1 christos case O (O_ROTR, SL):
3227 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3228 1.1 christos goto end;
3229 1.1 christos
3230 1.1 christos if (code->src.type == X (OP_IMM, SL))
3231 1.1 christos fetch (sd, &code->src, &ea);
3232 1.1 christos else
3233 1.1 christos ea = 1;
3234 1.1 christos
3235 1.1 christos while (ea--)
3236 1.1 christos if (code->opcode == O (O_ROTL, SL))
3237 1.1 christos {
3238 1.1 christos c = rd & 0x80000000;
3239 1.1 christos rd <<= 1;
3240 1.1 christos if (c)
3241 1.1 christos rd |= 1;
3242 1.1 christos }
3243 1.1 christos else
3244 1.1 christos {
3245 1.1 christos c = rd & 1;
3246 1.1 christos rd = ((unsigned int) rd) >> 1;
3247 1.1 christos if (c)
3248 1.1 christos rd |= 0x80000000;
3249 1.1 christos }
3250 1.1 christos
3251 1.1 christos v = 0;
3252 1.1 christos goto shift32;
3253 1.1 christos
3254 1.1 christos case O (O_ROTXL, SB):
3255 1.1 christos case O (O_ROTXR, SB):
3256 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3257 1.1 christos goto end;
3258 1.1 christos
3259 1.1 christos if (code->src.type == X (OP_IMM, SB))
3260 1.1 christos fetch (sd, &code->src, &ea);
3261 1.1 christos else
3262 1.1 christos ea = 1;
3263 1.1 christos
3264 1.1 christos while (ea--)
3265 1.1 christos if (code->opcode == O (O_ROTXL, SB))
3266 1.1 christos {
3267 1.1 christos res = rd & 0x80;
3268 1.1 christos rd <<= 1;
3269 1.1 christos if (C)
3270 1.1 christos rd |= 1;
3271 1.1 christos c = res;
3272 1.1 christos }
3273 1.1 christos else
3274 1.1 christos {
3275 1.1 christos res = rd & 1;
3276 1.1 christos rd = ((unsigned char) rd) >> 1;
3277 1.1 christos if (C)
3278 1.1 christos rd |= 0x80;
3279 1.1 christos c = res;
3280 1.1 christos }
3281 1.1 christos
3282 1.1 christos v = 0;
3283 1.1 christos goto shift8;
3284 1.1 christos
3285 1.1 christos case O (O_ROTXL, SW):
3286 1.1 christos case O (O_ROTXR, SW):
3287 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3288 1.1 christos goto end;
3289 1.1 christos
3290 1.1 christos if (code->src.type == X (OP_IMM, SW))
3291 1.1 christos fetch (sd, &code->src, &ea);
3292 1.1 christos else
3293 1.1 christos ea = 1;
3294 1.1 christos
3295 1.1 christos while (ea--)
3296 1.1 christos if (code->opcode == O (O_ROTXL, SW))
3297 1.1 christos {
3298 1.1 christos res = rd & 0x8000;
3299 1.1 christos rd <<= 1;
3300 1.1 christos if (C)
3301 1.1 christos rd |= 1;
3302 1.1 christos c = res;
3303 1.1 christos }
3304 1.1 christos else
3305 1.1 christos {
3306 1.1 christos res = rd & 1;
3307 1.1 christos rd = ((unsigned short) rd) >> 1;
3308 1.1 christos if (C)
3309 1.1 christos rd |= 0x8000;
3310 1.1 christos c = res;
3311 1.1 christos }
3312 1.1 christos
3313 1.1 christos v = 0;
3314 1.1 christos goto shift16;
3315 1.1 christos
3316 1.1 christos case O (O_ROTXL, SL):
3317 1.1 christos case O (O_ROTXR, SL):
3318 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3319 1.1 christos goto end;
3320 1.1 christos
3321 1.1 christos if (code->src.type == X (OP_IMM, SL))
3322 1.1 christos fetch (sd, &code->src, &ea);
3323 1.1 christos else
3324 1.1 christos ea = 1;
3325 1.1 christos
3326 1.1 christos while (ea--)
3327 1.1 christos if (code->opcode == O (O_ROTXL, SL))
3328 1.1 christos {
3329 1.1 christos res = rd & 0x80000000;
3330 1.1 christos rd <<= 1;
3331 1.1 christos if (C)
3332 1.1 christos rd |= 1;
3333 1.1 christos c = res;
3334 1.1 christos }
3335 1.1 christos else
3336 1.1 christos {
3337 1.1 christos res = rd & 1;
3338 1.1 christos rd = ((unsigned int) rd) >> 1;
3339 1.1 christos if (C)
3340 1.1 christos rd |= 0x80000000;
3341 1.1 christos c = res;
3342 1.1 christos }
3343 1.1 christos
3344 1.1 christos v = 0;
3345 1.1 christos goto shift32;
3346 1.1 christos
3347 1.1 christos case O (O_JMP, SN):
3348 1.1 christos case O (O_JMP, SL):
3349 1.1 christos case O (O_JMP, SB): /* jmp */
3350 1.1 christos case O (O_JMP, SW):
3351 1.1 christos fetch (sd, &code->src, &pc);
3352 1.1 christos goto end;
3353 1.1 christos
3354 1.1 christos case O (O_JSR, SN):
3355 1.1 christos case O (O_JSR, SL):
3356 1.1 christos case O (O_JSR, SB): /* jsr, jump to subroutine */
3357 1.1 christos case O (O_JSR, SW):
3358 1.1 christos if (fetch (sd, &code->src, &pc))
3359 1.1 christos goto end;
3360 1.1 christos call:
3361 1.7 christos tmp = h8_get_reg (cpu, SP_REGNUM);
3362 1.1 christos
3363 1.1 christos if (h8300hmode && !h8300_normal_mode)
3364 1.1 christos {
3365 1.1 christos tmp -= 4;
3366 1.1 christos SET_MEMORY_L (tmp, code->next_pc);
3367 1.1 christos }
3368 1.1 christos else
3369 1.1 christos {
3370 1.1 christos tmp -= 2;
3371 1.1 christos SET_MEMORY_W (tmp, code->next_pc);
3372 1.1 christos }
3373 1.7 christos h8_set_reg (cpu, SP_REGNUM, tmp);
3374 1.1 christos
3375 1.1 christos goto end;
3376 1.1 christos
3377 1.1 christos case O (O_BSR, SW):
3378 1.1 christos case O (O_BSR, SL):
3379 1.1 christos case O (O_BSR, SB): /* bsr, branch to subroutine */
3380 1.1 christos if (fetch (sd, &code->src, &res))
3381 1.1 christos goto end;
3382 1.1 christos pc = code->next_pc + res;
3383 1.1 christos goto call;
3384 1.1 christos
3385 1.1 christos case O (O_RTE, SN): /* rte, return from exception */
3386 1.1 christos rte:
3387 1.1 christos /* Pops exr and ccr before pc -- otherwise identical to rts. */
3388 1.7 christos tmp = h8_get_reg (cpu, SP_REGNUM);
3389 1.1 christos
3390 1.1 christos if (h8300smode) /* pop exr */
3391 1.1 christos {
3392 1.7 christos h8_set_exr (cpu, GET_MEMORY_L (tmp));
3393 1.1 christos tmp += 4;
3394 1.1 christos }
3395 1.1 christos if (h8300hmode && !h8300_normal_mode)
3396 1.1 christos {
3397 1.7 christos h8_set_ccr (cpu, GET_MEMORY_L (tmp));
3398 1.1 christos tmp += 4;
3399 1.1 christos pc = GET_MEMORY_L (tmp);
3400 1.1 christos tmp += 4;
3401 1.1 christos }
3402 1.1 christos else
3403 1.1 christos {
3404 1.7 christos h8_set_ccr (cpu, GET_MEMORY_W (tmp));
3405 1.1 christos tmp += 2;
3406 1.1 christos pc = GET_MEMORY_W (tmp);
3407 1.1 christos tmp += 2;
3408 1.1 christos }
3409 1.1 christos
3410 1.7 christos GETSR (cpu);
3411 1.7 christos h8_set_reg (cpu, SP_REGNUM, tmp);
3412 1.1 christos goto end;
3413 1.1 christos
3414 1.1 christos case O (O_RTS, SN): /* rts, return from subroutine */
3415 1.1 christos rts:
3416 1.7 christos tmp = h8_get_reg (cpu, SP_REGNUM);
3417 1.1 christos
3418 1.1 christos if (h8300hmode && !h8300_normal_mode)
3419 1.1 christos {
3420 1.1 christos pc = GET_MEMORY_L (tmp);
3421 1.1 christos tmp += 4;
3422 1.1 christos }
3423 1.1 christos else
3424 1.1 christos {
3425 1.1 christos pc = GET_MEMORY_W (tmp);
3426 1.1 christos tmp += 2;
3427 1.1 christos }
3428 1.1 christos
3429 1.7 christos h8_set_reg (cpu, SP_REGNUM, tmp);
3430 1.1 christos goto end;
3431 1.1 christos
3432 1.1 christos case O (O_ILL, SB): /* illegal */
3433 1.6 christos sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
3434 1.1 christos goto end;
3435 1.1 christos
3436 1.1 christos case O (O_SLEEP, SN): /* sleep */
3437 1.1 christos /* Check for magic numbers in r1 and r2. */
3438 1.7 christos if ((h8_get_reg (cpu, R1_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC1 &&
3439 1.7 christos (h8_get_reg (cpu, R2_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC2 &&
3440 1.7 christos SIM_WIFEXITED (h8_get_reg (cpu, 0)))
3441 1.1 christos {
3442 1.1 christos /* This trap comes from _exit, not from gdb. */
3443 1.6 christos sim_engine_halt (sd, cpu, NULL, pc, sim_exited,
3444 1.7 christos SIM_WEXITSTATUS (h8_get_reg (cpu, 0)));
3445 1.1 christos }
3446 1.1 christos #if 0
3447 1.1 christos /* Unfortunately this won't really work, because
3448 1.1 christos when we take a breakpoint trap, R0 has a "random",
3449 1.1 christos user-defined value. Don't see any immediate solution. */
3450 1.7 christos else if (SIM_WIFSTOPPED (h8_get_reg (cpu, 0)))
3451 1.1 christos {
3452 1.1 christos /* Pass the stop signal up to gdb. */
3453 1.6 christos sim_engine_halt (sd, cpu, NULL, pc, sim_stopped,
3454 1.7 christos SIM_WSTOPSIG (h8_get_reg (cpu, 0)));
3455 1.1 christos }
3456 1.1 christos #endif
3457 1.1 christos else
3458 1.1 christos {
3459 1.1 christos /* Treat it as a sigtrap. */
3460 1.6 christos sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
3461 1.1 christos }
3462 1.1 christos goto end;
3463 1.1 christos
3464 1.1 christos case O (O_TRAPA, SB): /* trapa */
3465 1.1 christos if (fetch (sd, &code->src, &res))
3466 1.1 christos goto end; /* res is vector number. */
3467 1.1 christos
3468 1.7 christos tmp = h8_get_reg (cpu, SP_REGNUM);
3469 1.1 christos if(h8300_normal_mode)
3470 1.1 christos {
3471 1.1 christos tmp -= 2;
3472 1.1 christos SET_MEMORY_W (tmp, code->next_pc);
3473 1.1 christos tmp -= 2;
3474 1.7 christos SET_MEMORY_W (tmp, h8_get_ccr (cpu));
3475 1.1 christos }
3476 1.1 christos else
3477 1.1 christos {
3478 1.1 christos tmp -= 4;
3479 1.1 christos SET_MEMORY_L (tmp, code->next_pc);
3480 1.1 christos tmp -= 4;
3481 1.7 christos SET_MEMORY_L (tmp, h8_get_ccr (cpu));
3482 1.1 christos }
3483 1.1 christos intMaskBit = 1;
3484 1.7 christos BUILDSR (cpu);
3485 1.1 christos
3486 1.1 christos if (h8300smode)
3487 1.1 christos {
3488 1.1 christos tmp -= 4;
3489 1.7 christos SET_MEMORY_L (tmp, h8_get_exr (cpu));
3490 1.1 christos }
3491 1.1 christos
3492 1.7 christos h8_set_reg (cpu, SP_REGNUM, tmp);
3493 1.1 christos
3494 1.1 christos if(h8300_normal_mode)
3495 1.1 christos pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */
3496 1.1 christos else
3497 1.1 christos pc = GET_MEMORY_L (0x20 + res * 4);
3498 1.1 christos goto end;
3499 1.1 christos
3500 1.1 christos case O (O_BPT, SN):
3501 1.6 christos sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
3502 1.1 christos goto end;
3503 1.1 christos
3504 1.1 christos case O (O_BSETEQ, SB):
3505 1.1 christos if (Z)
3506 1.1 christos goto bset;
3507 1.1 christos goto next;
3508 1.1 christos
3509 1.1 christos case O (O_BSETNE, SB):
3510 1.1 christos if (!Z)
3511 1.1 christos goto bset;
3512 1.1 christos goto next;
3513 1.1 christos
3514 1.1 christos case O (O_BCLREQ, SB):
3515 1.1 christos if (Z)
3516 1.1 christos goto bclr;
3517 1.1 christos goto next;
3518 1.1 christos
3519 1.1 christos case O (O_BCLRNE, SB):
3520 1.1 christos if (!Z)
3521 1.1 christos goto bclr;
3522 1.1 christos goto next;
3523 1.1 christos
3524 1.1 christos OBITOP (O_BNOT, 1, 1, ea ^= m); /* bnot */
3525 1.1 christos OBITOP (O_BTST, 1, 0, nz = ea & m); /* btst */
3526 1.1 christos bset:
3527 1.1 christos OBITOP (O_BSET, 1, 1, ea |= m); /* bset */
3528 1.1 christos bclr:
3529 1.1 christos OBITOP (O_BCLR, 1, 1, ea &= ~m); /* bclr */
3530 1.1 christos OBITOP (O_BLD, 1, 0, c = ea & m); /* bld */
3531 1.1 christos OBITOP (O_BILD, 1, 0, c = !(ea & m)); /* bild */
3532 1.1 christos OBITOP (O_BST, 1, 1, ea &= ~m;
3533 1.1 christos if (C) ea |= m); /* bst */
3534 1.1 christos OBITOP (O_BIST, 1, 1, ea &= ~m;
3535 1.1 christos if (!C) ea |= m); /* bist */
3536 1.1 christos OBITOP (O_BSTZ, 1, 1, ea &= ~m;
3537 1.1 christos if (Z) ea |= m); /* bstz */
3538 1.1 christos OBITOP (O_BISTZ, 1, 1, ea &= ~m;
3539 1.1 christos if (!Z) ea |= m); /* bistz */
3540 1.1 christos OBITOP (O_BAND, 1, 0, c = (ea & m) && C); /* band */
3541 1.1 christos OBITOP (O_BIAND, 1, 0, c = !(ea & m) && C); /* biand */
3542 1.1 christos OBITOP (O_BOR, 1, 0, c = (ea & m) || C); /* bor */
3543 1.1 christos OBITOP (O_BIOR, 1, 0, c = !(ea & m) || C); /* bior */
3544 1.1 christos OBITOP (O_BXOR, 1, 0, c = ((ea & m) != 0)!= C); /* bxor */
3545 1.1 christos OBITOP (O_BIXOR, 1, 0, c = !(ea & m) != C); /* bixor */
3546 1.1 christos
3547 1.1 christos case O (O_BFLD, SB): /* bfld */
3548 1.1 christos /* bitfield load */
3549 1.1 christos ea = 0;
3550 1.1 christos if (fetch (sd, &code->src, &bit))
3551 1.1 christos goto end;
3552 1.1 christos
3553 1.1 christos if (bit != 0)
3554 1.1 christos {
3555 1.1 christos if (fetch (sd, &code->dst, &ea))
3556 1.1 christos goto end;
3557 1.1 christos
3558 1.1 christos ea &= bit;
3559 1.1 christos while (!(bit & 1))
3560 1.1 christos {
3561 1.1 christos ea >>= 1;
3562 1.1 christos bit >>= 1;
3563 1.1 christos }
3564 1.1 christos }
3565 1.1 christos if (store (sd, &code->op3, ea))
3566 1.1 christos goto end;
3567 1.1 christos
3568 1.1 christos goto next;
3569 1.1 christos
3570 1.1 christos case O(O_BFST, SB): /* bfst */
3571 1.1 christos /* bitfield store */
3572 1.1 christos /* NOTE: the imm8 value is in dst, and the ea value
3573 1.1 christos (which is actually the destination) is in op3.
3574 1.1 christos It has to be that way, to avoid breaking the assembler. */
3575 1.1 christos
3576 1.1 christos if (fetch (sd, &code->dst, &bit)) /* imm8 */
3577 1.1 christos goto end;
3578 1.1 christos if (bit == 0) /* noop -- nothing to do. */
3579 1.1 christos goto next;
3580 1.1 christos
3581 1.1 christos if (fetch (sd, &code->src, &rd)) /* reg8 src */
3582 1.1 christos goto end;
3583 1.1 christos
3584 1.1 christos if (fetch2 (sd, &code->op3, &ea)) /* ea dst */
3585 1.1 christos goto end;
3586 1.1 christos
3587 1.1 christos /* Left-shift the register data into position. */
3588 1.1 christos for (tmp = bit; !(tmp & 1); tmp >>= 1)
3589 1.1 christos rd <<= 1;
3590 1.1 christos
3591 1.1 christos /* Combine it with the neighboring bits. */
3592 1.1 christos ea = (ea & ~bit) | (rd & bit);
3593 1.1 christos
3594 1.1 christos /* Put it back. */
3595 1.1 christos if (store2 (sd, &code->op3, ea))
3596 1.1 christos goto end;
3597 1.1 christos goto next;
3598 1.1 christos
3599 1.1 christos case O (O_CLRMAC, SN): /* clrmac */
3600 1.7 christos h8_set_mach (cpu, 0);
3601 1.7 christos h8_set_macl (cpu, 0);
3602 1.7 christos h8_set_macZ (cpu, 1);
3603 1.7 christos h8_set_macV (cpu, 0);
3604 1.7 christos h8_set_macN (cpu, 0);
3605 1.1 christos goto next;
3606 1.1 christos
3607 1.1 christos case O (O_STMAC, SL): /* stmac, 260 */
3608 1.1 christos switch (code->src.type) {
3609 1.1 christos case X (OP_MACH, SL):
3610 1.7 christos res = h8_get_mach (cpu);
3611 1.1 christos if (res & 0x200) /* sign extend */
3612 1.1 christos res |= 0xfffffc00;
3613 1.1 christos break;
3614 1.1 christos case X (OP_MACL, SL):
3615 1.7 christos res = h8_get_macl (cpu);
3616 1.1 christos break;
3617 1.1 christos default: goto illegal;
3618 1.1 christos }
3619 1.7 christos nz = !h8_get_macZ (cpu);
3620 1.7 christos n = h8_get_macN (cpu);
3621 1.7 christos v = h8_get_macV (cpu);
3622 1.1 christos
3623 1.1 christos if (store (sd, &code->dst, res))
3624 1.1 christos goto end;
3625 1.1 christos
3626 1.1 christos goto next;
3627 1.1 christos
3628 1.1 christos case O (O_LDMAC, SL): /* ldmac, 179 */
3629 1.1 christos if (fetch (sd, &code->src, &rd))
3630 1.1 christos goto end;
3631 1.1 christos
3632 1.1 christos switch (code->dst.type) {
3633 1.1 christos case X (OP_MACH, SL):
3634 1.1 christos rd &= 0x3ff; /* Truncate to 10 bits */
3635 1.7 christos h8_set_mach (cpu, rd);
3636 1.1 christos break;
3637 1.1 christos case X (OP_MACL, SL):
3638 1.7 christos h8_set_macl (cpu, rd);
3639 1.1 christos break;
3640 1.1 christos default: goto illegal;
3641 1.1 christos }
3642 1.7 christos h8_set_macV (cpu, 0);
3643 1.1 christos goto next;
3644 1.1 christos
3645 1.1 christos case O (O_MAC, SW):
3646 1.1 christos if (fetch (sd, &code->src, &rd) ||
3647 1.1 christos fetch (sd, &code->dst, &res))
3648 1.1 christos goto end;
3649 1.1 christos
3650 1.1 christos /* Ye gods, this is non-portable!
3651 1.1 christos However, the existing mul/div code is similar. */
3652 1.1 christos res = SEXTSHORT (res) * SEXTSHORT (rd);
3653 1.1 christos
3654 1.7 christos if (h8_get_macS (cpu)) /* Saturating mode */
3655 1.1 christos {
3656 1.7 christos long long mac = h8_get_macl (cpu);
3657 1.1 christos
3658 1.1 christos if (mac & 0x80000000) /* sign extend */
3659 1.1 christos mac |= 0xffffffff00000000LL;
3660 1.1 christos
3661 1.1 christos mac += res;
3662 1.1 christos if (mac > 0x7fffffff || mac < 0xffffffff80000000LL)
3663 1.7 christos h8_set_macV (cpu, 1);
3664 1.7 christos h8_set_macZ (cpu, (mac == 0));
3665 1.7 christos h8_set_macN (cpu, (mac < 0));
3666 1.7 christos h8_set_macl (cpu, (int) mac);
3667 1.1 christos }
3668 1.1 christos else /* "Less Saturating" mode */
3669 1.1 christos {
3670 1.7 christos long long mac = h8_get_mach (cpu);
3671 1.1 christos mac <<= 32;
3672 1.7 christos mac += h8_get_macl (cpu);
3673 1.1 christos
3674 1.1 christos if (mac & 0x20000000000LL) /* sign extend */
3675 1.1 christos mac |= 0xfffffc0000000000LL;
3676 1.1 christos
3677 1.1 christos mac += res;
3678 1.1 christos if (mac > 0x1ffffffffffLL ||
3679 1.1 christos mac < (long long) 0xfffffe0000000000LL)
3680 1.7 christos h8_set_macV (cpu, 1);
3681 1.7 christos h8_set_macZ (cpu, (mac == 0));
3682 1.7 christos h8_set_macN (cpu, (mac < 0));
3683 1.7 christos h8_set_macl (cpu, (int) mac);
3684 1.1 christos mac >>= 32;
3685 1.7 christos h8_set_mach (cpu, (int) (mac & 0x3ff));
3686 1.1 christos }
3687 1.1 christos goto next;
3688 1.1 christos
3689 1.1 christos case O (O_MULS, SW): /* muls.w */
3690 1.1 christos if (fetch (sd, &code->src, &ea) ||
3691 1.1 christos fetch (sd, &code->dst, &rd))
3692 1.1 christos goto end;
3693 1.1 christos
3694 1.1 christos ea = SEXTSHORT (ea);
3695 1.1 christos res = SEXTSHORT (ea * SEXTSHORT (rd));
3696 1.1 christos
3697 1.1 christos n = res & 0x8000;
3698 1.1 christos nz = res & 0xffff;
3699 1.1 christos if (store (sd, &code->dst, res))
3700 1.1 christos goto end;
3701 1.1 christos
3702 1.1 christos goto next;
3703 1.1 christos
3704 1.1 christos case O (O_MULS, SL): /* muls.l */
3705 1.1 christos if (fetch (sd, &code->src, &ea) ||
3706 1.1 christos fetch (sd, &code->dst, &rd))
3707 1.1 christos goto end;
3708 1.1 christos
3709 1.1 christos res = ea * rd;
3710 1.1 christos
3711 1.1 christos n = res & 0x80000000;
3712 1.1 christos nz = res & 0xffffffff;
3713 1.1 christos if (store (sd, &code->dst, res))
3714 1.1 christos goto end;
3715 1.1 christos goto next;
3716 1.1 christos
3717 1.1 christos case O (O_MULSU, SL): /* muls/u.l */
3718 1.1 christos if (fetch (sd, &code->src, &ea) ||
3719 1.1 christos fetch (sd, &code->dst, &rd))
3720 1.1 christos goto end;
3721 1.1 christos
3722 1.1 christos /* Compute upper 32 bits of the 64-bit result. */
3723 1.1 christos res = (((long long) ea) * ((long long) rd)) >> 32;
3724 1.1 christos
3725 1.1 christos n = res & 0x80000000;
3726 1.1 christos nz = res & 0xffffffff;
3727 1.1 christos if (store (sd, &code->dst, res))
3728 1.1 christos goto end;
3729 1.1 christos goto next;
3730 1.1 christos
3731 1.1 christos case O (O_MULU, SW): /* mulu.w */
3732 1.1 christos if (fetch (sd, &code->src, &ea) ||
3733 1.1 christos fetch (sd, &code->dst, &rd))
3734 1.1 christos goto end;
3735 1.1 christos
3736 1.1 christos res = UEXTSHORT ((UEXTSHORT (ea) * UEXTSHORT (rd)));
3737 1.1 christos
3738 1.1 christos /* Don't set Z or N. */
3739 1.1 christos if (store (sd, &code->dst, res))
3740 1.1 christos goto end;
3741 1.1 christos
3742 1.1 christos goto next;
3743 1.1 christos
3744 1.1 christos case O (O_MULU, SL): /* mulu.l */
3745 1.1 christos if (fetch (sd, &code->src, &ea) ||
3746 1.1 christos fetch (sd, &code->dst, &rd))
3747 1.1 christos goto end;
3748 1.1 christos
3749 1.1 christos res = ea * rd;
3750 1.1 christos
3751 1.1 christos /* Don't set Z or N. */
3752 1.1 christos if (store (sd, &code->dst, res))
3753 1.1 christos goto end;
3754 1.1 christos
3755 1.1 christos goto next;
3756 1.1 christos
3757 1.1 christos case O (O_MULUU, SL): /* mulu/u.l */
3758 1.1 christos if (fetch (sd, &code->src, &ea) ||
3759 1.1 christos fetch (sd, &code->dst, &rd))
3760 1.1 christos goto end;
3761 1.1 christos
3762 1.1 christos /* Compute upper 32 bits of the 64-bit result. */
3763 1.1 christos res = (((unsigned long long) (unsigned) ea) *
3764 1.1 christos ((unsigned long long) (unsigned) rd)) >> 32;
3765 1.1 christos
3766 1.1 christos /* Don't set Z or N. */
3767 1.1 christos if (store (sd, &code->dst, res))
3768 1.1 christos goto end;
3769 1.1 christos
3770 1.1 christos goto next;
3771 1.1 christos
3772 1.1 christos case O (O_MULXS, SB): /* mulxs.b */
3773 1.1 christos if (fetch (sd, &code->src, &ea) ||
3774 1.1 christos fetch (sd, &code->dst, &rd))
3775 1.1 christos goto end;
3776 1.1 christos
3777 1.1 christos ea = SEXTCHAR (ea);
3778 1.1 christos res = ea * SEXTCHAR (rd);
3779 1.1 christos
3780 1.1 christos n = res & 0x8000;
3781 1.1 christos nz = res & 0xffff;
3782 1.1 christos if (store (sd, &code->dst, res))
3783 1.1 christos goto end;
3784 1.1 christos
3785 1.1 christos goto next;
3786 1.1 christos
3787 1.1 christos case O (O_MULXS, SW): /* mulxs.w */
3788 1.1 christos if (fetch (sd, &code->src, &ea) ||
3789 1.1 christos fetch (sd, &code->dst, &rd))
3790 1.1 christos goto end;
3791 1.1 christos
3792 1.1 christos ea = SEXTSHORT (ea);
3793 1.1 christos res = ea * SEXTSHORT (rd & 0xffff);
3794 1.1 christos
3795 1.1 christos n = res & 0x80000000;
3796 1.1 christos nz = res & 0xffffffff;
3797 1.1 christos if (store (sd, &code->dst, res))
3798 1.1 christos goto end;
3799 1.1 christos
3800 1.1 christos goto next;
3801 1.1 christos
3802 1.1 christos case O (O_MULXU, SB): /* mulxu.b */
3803 1.1 christos if (fetch (sd, &code->src, &ea) ||
3804 1.1 christos fetch (sd, &code->dst, &rd))
3805 1.1 christos goto end;
3806 1.1 christos
3807 1.1 christos res = UEXTCHAR (ea) * UEXTCHAR (rd);
3808 1.1 christos
3809 1.1 christos if (store (sd, &code->dst, res))
3810 1.1 christos goto end;
3811 1.1 christos
3812 1.1 christos goto next;
3813 1.1 christos
3814 1.1 christos case O (O_MULXU, SW): /* mulxu.w */
3815 1.1 christos if (fetch (sd, &code->src, &ea) ||
3816 1.1 christos fetch (sd, &code->dst, &rd))
3817 1.1 christos goto end;
3818 1.1 christos
3819 1.1 christos res = UEXTSHORT (ea) * UEXTSHORT (rd);
3820 1.1 christos
3821 1.1 christos if (store (sd, &code->dst, res))
3822 1.1 christos goto end;
3823 1.1 christos
3824 1.1 christos goto next;
3825 1.1 christos
3826 1.1 christos case O (O_TAS, SB): /* tas (test and set) */
3827 1.1 christos if (!h8300sxmode) /* h8sx can use any register. */
3828 1.1 christos switch (code->src.reg)
3829 1.1 christos {
3830 1.1 christos case R0_REGNUM:
3831 1.1 christos case R1_REGNUM:
3832 1.1 christos case R4_REGNUM:
3833 1.1 christos case R5_REGNUM:
3834 1.1 christos break;
3835 1.1 christos default:
3836 1.1 christos goto illegal;
3837 1.1 christos }
3838 1.1 christos
3839 1.1 christos if (fetch (sd, &code->src, &res))
3840 1.1 christos goto end;
3841 1.1 christos if (store (sd, &code->src, res | 0x80))
3842 1.1 christos goto end;
3843 1.1 christos
3844 1.1 christos goto just_flags_log8;
3845 1.1 christos
3846 1.1 christos case O (O_DIVU, SW): /* divu.w */
3847 1.1 christos if (fetch (sd, &code->src, &ea) ||
3848 1.1 christos fetch (sd, &code->dst, &rd))
3849 1.1 christos goto end;
3850 1.1 christos
3851 1.1 christos n = ea & 0x8000;
3852 1.1 christos nz = ea & 0xffff;
3853 1.1 christos if (ea)
3854 1.1 christos res = (unsigned) (UEXTSHORT (rd) / UEXTSHORT (ea));
3855 1.1 christos else
3856 1.1 christos res = 0;
3857 1.1 christos
3858 1.1 christos if (store (sd, &code->dst, res))
3859 1.1 christos goto end;
3860 1.1 christos goto next;
3861 1.1 christos
3862 1.1 christos case O (O_DIVU, SL): /* divu.l */
3863 1.1 christos if (fetch (sd, &code->src, &ea) ||
3864 1.1 christos fetch (sd, &code->dst, &rd))
3865 1.1 christos goto end;
3866 1.1 christos
3867 1.1 christos n = ea & 0x80000000;
3868 1.1 christos nz = ea & 0xffffffff;
3869 1.1 christos if (ea)
3870 1.1 christos res = (unsigned) rd / ea;
3871 1.1 christos else
3872 1.1 christos res = 0;
3873 1.1 christos
3874 1.1 christos if (store (sd, &code->dst, res))
3875 1.1 christos goto end;
3876 1.1 christos goto next;
3877 1.1 christos
3878 1.1 christos case O (O_DIVS, SW): /* divs.w */
3879 1.1 christos if (fetch (sd, &code->src, &ea) ||
3880 1.1 christos fetch (sd, &code->dst, &rd))
3881 1.1 christos goto end;
3882 1.1 christos
3883 1.1 christos if (ea)
3884 1.1 christos {
3885 1.1 christos res = SEXTSHORT (rd) / SEXTSHORT (ea);
3886 1.1 christos nz = 1;
3887 1.1 christos }
3888 1.1 christos else
3889 1.1 christos {
3890 1.1 christos res = 0;
3891 1.1 christos nz = 0;
3892 1.1 christos }
3893 1.1 christos
3894 1.1 christos n = res & 0x8000;
3895 1.1 christos if (store (sd, &code->dst, res))
3896 1.1 christos goto end;
3897 1.1 christos goto next;
3898 1.1 christos
3899 1.1 christos case O (O_DIVS, SL): /* divs.l */
3900 1.1 christos if (fetch (sd, &code->src, &ea) ||
3901 1.1 christos fetch (sd, &code->dst, &rd))
3902 1.1 christos goto end;
3903 1.1 christos
3904 1.1 christos if (ea)
3905 1.1 christos {
3906 1.1 christos res = rd / ea;
3907 1.1 christos nz = 1;
3908 1.1 christos }
3909 1.1 christos else
3910 1.1 christos {
3911 1.1 christos res = 0;
3912 1.1 christos nz = 0;
3913 1.1 christos }
3914 1.1 christos
3915 1.1 christos n = res & 0x80000000;
3916 1.1 christos if (store (sd, &code->dst, res))
3917 1.1 christos goto end;
3918 1.1 christos goto next;
3919 1.1 christos
3920 1.1 christos case O (O_DIVXU, SB): /* divxu.b */
3921 1.1 christos if (fetch (sd, &code->src, &ea) ||
3922 1.1 christos fetch (sd, &code->dst, &rd))
3923 1.1 christos goto end;
3924 1.1 christos
3925 1.1 christos rd = UEXTSHORT (rd);
3926 1.1 christos ea = UEXTCHAR (ea);
3927 1.1 christos
3928 1.1 christos n = ea & 0x80;
3929 1.1 christos nz = ea & 0xff;
3930 1.1 christos if (ea)
3931 1.1 christos {
3932 1.1 christos tmp = (unsigned) rd % ea;
3933 1.1 christos res = (unsigned) rd / ea;
3934 1.1 christos }
3935 1.1 christos else
3936 1.1 christos {
3937 1.1 christos tmp = 0;
3938 1.1 christos res = 0;
3939 1.1 christos }
3940 1.1 christos
3941 1.1 christos if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
3942 1.1 christos goto end;
3943 1.1 christos goto next;
3944 1.1 christos
3945 1.1 christos case O (O_DIVXU, SW): /* divxu.w */
3946 1.1 christos if (fetch (sd, &code->src, &ea) ||
3947 1.1 christos fetch (sd, &code->dst, &rd))
3948 1.1 christos goto end;
3949 1.1 christos
3950 1.1 christos ea = UEXTSHORT (ea);
3951 1.1 christos
3952 1.1 christos n = ea & 0x8000;
3953 1.1 christos nz = ea & 0xffff;
3954 1.1 christos if (ea)
3955 1.1 christos {
3956 1.1 christos tmp = (unsigned) rd % ea;
3957 1.1 christos res = (unsigned) rd / ea;
3958 1.1 christos }
3959 1.1 christos else
3960 1.1 christos {
3961 1.1 christos tmp = 0;
3962 1.1 christos res = 0;
3963 1.1 christos }
3964 1.1 christos
3965 1.1 christos if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
3966 1.1 christos goto end;
3967 1.1 christos goto next;
3968 1.1 christos
3969 1.1 christos case O (O_DIVXS, SB): /* divxs.b */
3970 1.1 christos if (fetch (sd, &code->src, &ea) ||
3971 1.1 christos fetch (sd, &code->dst, &rd))
3972 1.1 christos goto end;
3973 1.1 christos
3974 1.1 christos rd = SEXTSHORT (rd);
3975 1.1 christos ea = SEXTCHAR (ea);
3976 1.1 christos
3977 1.1 christos if (ea)
3978 1.1 christos {
3979 1.1 christos tmp = (int) rd % (int) ea;
3980 1.1 christos res = (int) rd / (int) ea;
3981 1.1 christos nz = 1;
3982 1.1 christos }
3983 1.1 christos else
3984 1.1 christos {
3985 1.1 christos tmp = 0;
3986 1.1 christos res = 0;
3987 1.1 christos nz = 0;
3988 1.1 christos }
3989 1.1 christos
3990 1.1 christos n = res & 0x8000;
3991 1.1 christos if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
3992 1.1 christos goto end;
3993 1.1 christos goto next;
3994 1.1 christos
3995 1.1 christos case O (O_DIVXS, SW): /* divxs.w */
3996 1.1 christos if (fetch (sd, &code->src, &ea) ||
3997 1.1 christos fetch (sd, &code->dst, &rd))
3998 1.1 christos goto end;
3999 1.1 christos
4000 1.1 christos ea = SEXTSHORT (ea);
4001 1.1 christos
4002 1.1 christos if (ea)
4003 1.1 christos {
4004 1.1 christos tmp = (int) rd % (int) ea;
4005 1.1 christos res = (int) rd / (int) ea;
4006 1.1 christos nz = 1;
4007 1.1 christos }
4008 1.1 christos else
4009 1.1 christos {
4010 1.1 christos tmp = 0;
4011 1.1 christos res = 0;
4012 1.1 christos nz = 0;
4013 1.1 christos }
4014 1.1 christos
4015 1.1 christos n = res & 0x80000000;
4016 1.1 christos if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
4017 1.1 christos goto end;
4018 1.1 christos goto next;
4019 1.1 christos
4020 1.1 christos case O (O_EXTS, SW): /* exts.w, signed extend */
4021 1.1 christos if (fetch2 (sd, &code->dst, &rd))
4022 1.1 christos goto end;
4023 1.1 christos ea = rd & 0x80 ? -256 : 0;
4024 1.1 christos res = (rd & 0xff) + ea;
4025 1.1 christos goto log16;
4026 1.1 christos
4027 1.1 christos case O (O_EXTS, SL): /* exts.l, signed extend */
4028 1.1 christos if (fetch2 (sd, &code->dst, &rd))
4029 1.1 christos goto end;
4030 1.1 christos if (code->src.type == X (OP_IMM, SL))
4031 1.1 christos {
4032 1.1 christos if (fetch (sd, &code->src, &ea))
4033 1.1 christos goto end;
4034 1.1 christos
4035 1.1 christos if (ea == 2) /* exts.l #2, nn */
4036 1.1 christos {
4037 1.1 christos /* Sign-extend from 8-bit to 32-bit. */
4038 1.1 christos ea = rd & 0x80 ? -256 : 0;
4039 1.1 christos res = (rd & 0xff) + ea;
4040 1.1 christos goto log32;
4041 1.1 christos }
4042 1.1 christos }
4043 1.1 christos /* Sign-extend from 16-bit to 32-bit. */
4044 1.1 christos ea = rd & 0x8000 ? -65536 : 0;
4045 1.1 christos res = (rd & 0xffff) + ea;
4046 1.1 christos goto log32;
4047 1.1 christos
4048 1.1 christos case O (O_EXTU, SW): /* extu.w, unsigned extend */
4049 1.1 christos if (fetch2 (sd, &code->dst, &rd))
4050 1.1 christos goto end;
4051 1.1 christos ea = 0;
4052 1.1 christos res = (rd & 0xff) + ea;
4053 1.1 christos goto log16;
4054 1.1 christos
4055 1.1 christos case O (O_EXTU, SL): /* extu.l, unsigned extend */
4056 1.1 christos if (fetch2 (sd, &code->dst, &rd))
4057 1.1 christos goto end;
4058 1.1 christos if (code->src.type == X (OP_IMM, SL))
4059 1.1 christos {
4060 1.1 christos if (fetch (sd, &code->src, &ea))
4061 1.1 christos goto end;
4062 1.1 christos
4063 1.1 christos if (ea == 2) /* extu.l #2, nn */
4064 1.1 christos {
4065 1.1 christos /* Zero-extend from 8-bit to 32-bit. */
4066 1.1 christos ea = 0;
4067 1.1 christos res = (rd & 0xff) + ea;
4068 1.1 christos goto log32;
4069 1.1 christos }
4070 1.1 christos }
4071 1.1 christos /* Zero-extend from 16-bit to 32-bit. */
4072 1.1 christos ea = 0;
4073 1.1 christos res = (rd & 0xffff) + ea;
4074 1.1 christos goto log32;
4075 1.1 christos
4076 1.1 christos case O (O_NOP, SN): /* nop */
4077 1.1 christos goto next;
4078 1.1 christos
4079 1.1 christos case O (O_STM, SL): /* stm, store to memory */
4080 1.1 christos {
4081 1.1 christos int nregs, firstreg, i;
4082 1.1 christos
4083 1.1 christos nregs = GET_MEMORY_B (pc + 1);
4084 1.1 christos nregs >>= 4;
4085 1.1 christos nregs &= 0xf;
4086 1.1 christos firstreg = code->src.reg;
4087 1.1 christos firstreg &= 0xf;
4088 1.1 christos for (i = firstreg; i <= firstreg + nregs; i++)
4089 1.1 christos {
4090 1.7 christos h8_set_reg (cpu, SP_REGNUM, h8_get_reg (cpu, SP_REGNUM) - 4);
4091 1.7 christos SET_MEMORY_L (h8_get_reg (cpu, SP_REGNUM), h8_get_reg (cpu, i));
4092 1.1 christos }
4093 1.1 christos }
4094 1.1 christos goto next;
4095 1.1 christos
4096 1.1 christos case O (O_LDM, SL): /* ldm, load from memory */
4097 1.1 christos case O (O_RTEL, SN): /* rte/l, ldm plus rte */
4098 1.1 christos case O (O_RTSL, SN): /* rts/l, ldm plus rts */
4099 1.1 christos {
4100 1.1 christos int nregs, firstreg, i;
4101 1.1 christos
4102 1.1 christos nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf);
4103 1.1 christos firstreg = code->dst.reg & 0xf;
4104 1.1 christos for (i = firstreg; i >= firstreg - nregs; i--)
4105 1.1 christos {
4106 1.7 christos h8_set_reg (cpu, i, GET_MEMORY_L (h8_get_reg (cpu, SP_REGNUM)));
4107 1.7 christos h8_set_reg (cpu, SP_REGNUM, h8_get_reg (cpu, SP_REGNUM) + 4);
4108 1.1 christos }
4109 1.1 christos }
4110 1.1 christos switch (code->opcode) {
4111 1.1 christos case O (O_RTEL, SN):
4112 1.1 christos goto rte;
4113 1.1 christos case O (O_RTSL, SN):
4114 1.1 christos goto rts;
4115 1.1 christos case O (O_LDM, SL):
4116 1.1 christos goto next;
4117 1.1 christos default:
4118 1.1 christos goto illegal;
4119 1.1 christos }
4120 1.1 christos
4121 1.1 christos case O (O_DAA, SB):
4122 1.1 christos /* Decimal Adjust Addition. This is for BCD arithmetic. */
4123 1.1 christos res = GET_B_REG (code->src.reg); /* FIXME fetch? */
4124 1.1 christos if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4125 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4126 1.7 christos /* Nothing. */; /* Value added == 0. */
4127 1.1 christos else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) &&
4128 1.1 christos !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
4129 1.1 christos res = res + 0x6; /* Value added == 6. */
4130 1.1 christos else if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4131 1.1 christos h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
4132 1.1 christos res = res + 0x6; /* Value added == 6. */
4133 1.1 christos else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) &&
4134 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4135 1.1 christos res = res + 0x60; /* Value added == 60. */
4136 1.1 christos else if (!c && (9 <= (res >> 4) && (res >> 4) <= 15) &&
4137 1.1 christos !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
4138 1.1 christos res = res + 0x66; /* Value added == 66. */
4139 1.1 christos else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) &&
4140 1.1 christos h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
4141 1.1 christos res = res + 0x66; /* Value added == 66. */
4142 1.1 christos else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) &&
4143 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4144 1.1 christos res = res + 0x60; /* Value added == 60. */
4145 1.1 christos else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) &&
4146 1.1 christos !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
4147 1.1 christos res = res + 0x66; /* Value added == 66. */
4148 1.1 christos else if (c && (1 <= (res >> 4) && (res >> 4) <= 3) &&
4149 1.1 christos h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
4150 1.1 christos res = res + 0x66; /* Value added == 66. */
4151 1.1 christos
4152 1.1 christos goto alu8;
4153 1.1 christos
4154 1.1 christos case O (O_DAS, SB):
4155 1.1 christos /* Decimal Adjust Subtraction. This is for BCD arithmetic. */
4156 1.1 christos res = GET_B_REG (code->src.reg); /* FIXME fetch, fetch2... */
4157 1.1 christos if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4158 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4159 1.7 christos /* Nothing. */; /* Value added == 0. */
4160 1.1 christos else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) &&
4161 1.1 christos h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
4162 1.1 christos res = res + 0xfa; /* Value added == 0xfa. */
4163 1.1 christos else if ( c && (7 <= (res >> 4) && (res >> 4) <= 15) &&
4164 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4165 1.1 christos res = res + 0xa0; /* Value added == 0xa0. */
4166 1.1 christos else if (c && (6 <= (res >> 4) && (res >> 4) <= 15) &&
4167 1.1 christos h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
4168 1.1 christos res = res + 0x9a; /* Value added == 0x9a. */
4169 1.1 christos
4170 1.1 christos goto alu8;
4171 1.1 christos
4172 1.1 christos default:
4173 1.1 christos illegal:
4174 1.6 christos sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
4175 1.1 christos goto end;
4176 1.1 christos
4177 1.1 christos }
4178 1.1 christos
4179 1.6 christos sim_io_printf (sd, "sim_resume: internal error.\n");
4180 1.6 christos sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
4181 1.1 christos goto end;
4182 1.1 christos
4183 1.1 christos setc:
4184 1.1 christos if (code->dst.type == X (OP_CCR, SB) ||
4185 1.1 christos code->dst.type == X (OP_CCR, SW))
4186 1.1 christos {
4187 1.7 christos h8_set_ccr (cpu, res);
4188 1.7 christos GETSR (cpu);
4189 1.1 christos }
4190 1.1 christos else if (h8300smode &&
4191 1.1 christos (code->dst.type == X (OP_EXR, SB) ||
4192 1.1 christos code->dst.type == X (OP_EXR, SW)))
4193 1.1 christos {
4194 1.7 christos h8_set_exr (cpu, res);
4195 1.1 christos if (h8300smode) /* Get exr. */
4196 1.1 christos {
4197 1.7 christos trace = (h8_get_exr (cpu) >> 7) & 1;
4198 1.7 christos intMask = h8_get_exr (cpu) & 7;
4199 1.1 christos }
4200 1.1 christos }
4201 1.1 christos else
4202 1.1 christos goto illegal;
4203 1.1 christos
4204 1.1 christos goto next;
4205 1.1 christos
4206 1.1 christos condtrue:
4207 1.1 christos /* When a branch works */
4208 1.1 christos if (fetch (sd, &code->src, &res))
4209 1.1 christos goto end;
4210 1.1 christos if (res & 1) /* bad address */
4211 1.1 christos goto illegal;
4212 1.1 christos pc = code->next_pc + res;
4213 1.1 christos goto end;
4214 1.1 christos
4215 1.1 christos /* Set the cond codes from res */
4216 1.1 christos bitop:
4217 1.1 christos
4218 1.1 christos /* Set the flags after an 8 bit inc/dec operation */
4219 1.1 christos just_flags_inc8:
4220 1.1 christos n = res & 0x80;
4221 1.1 christos nz = res & 0xff;
4222 1.1 christos v = (rd & 0x7f) == 0x7f;
4223 1.1 christos goto next;
4224 1.1 christos
4225 1.1 christos /* Set the flags after an 16 bit inc/dec operation */
4226 1.1 christos just_flags_inc16:
4227 1.1 christos n = res & 0x8000;
4228 1.1 christos nz = res & 0xffff;
4229 1.1 christos v = (rd & 0x7fff) == 0x7fff;
4230 1.1 christos goto next;
4231 1.1 christos
4232 1.1 christos /* Set the flags after an 32 bit inc/dec operation */
4233 1.1 christos just_flags_inc32:
4234 1.1 christos n = res & 0x80000000;
4235 1.1 christos nz = res & 0xffffffff;
4236 1.1 christos v = (rd & 0x7fffffff) == 0x7fffffff;
4237 1.1 christos goto next;
4238 1.1 christos
4239 1.1 christos shift8:
4240 1.1 christos /* Set flags after an 8 bit shift op, carry,overflow set in insn */
4241 1.1 christos n = (rd & 0x80);
4242 1.1 christos nz = rd & 0xff;
4243 1.1 christos if (store2 (sd, &code->dst, rd))
4244 1.1 christos goto end;
4245 1.1 christos goto next;
4246 1.1 christos
4247 1.1 christos shift16:
4248 1.1 christos /* Set flags after an 16 bit shift op, carry,overflow set in insn */
4249 1.1 christos n = (rd & 0x8000);
4250 1.1 christos nz = rd & 0xffff;
4251 1.1 christos if (store2 (sd, &code->dst, rd))
4252 1.1 christos goto end;
4253 1.1 christos goto next;
4254 1.1 christos
4255 1.1 christos shift32:
4256 1.1 christos /* Set flags after an 32 bit shift op, carry,overflow set in insn */
4257 1.1 christos n = (rd & 0x80000000);
4258 1.1 christos nz = rd & 0xffffffff;
4259 1.1 christos if (store2 (sd, &code->dst, rd))
4260 1.1 christos goto end;
4261 1.1 christos goto next;
4262 1.1 christos
4263 1.1 christos log32:
4264 1.1 christos if (store2 (sd, &code->dst, res))
4265 1.1 christos goto end;
4266 1.1 christos
4267 1.1 christos just_flags_log32:
4268 1.1 christos /* flags after a 32bit logical operation */
4269 1.1 christos n = res & 0x80000000;
4270 1.1 christos nz = res & 0xffffffff;
4271 1.1 christos v = 0;
4272 1.1 christos goto next;
4273 1.1 christos
4274 1.1 christos log16:
4275 1.1 christos if (store2 (sd, &code->dst, res))
4276 1.1 christos goto end;
4277 1.1 christos
4278 1.1 christos just_flags_log16:
4279 1.1 christos /* flags after a 16bit logical operation */
4280 1.1 christos n = res & 0x8000;
4281 1.1 christos nz = res & 0xffff;
4282 1.1 christos v = 0;
4283 1.1 christos goto next;
4284 1.1 christos
4285 1.1 christos log8:
4286 1.1 christos if (store2 (sd, &code->dst, res))
4287 1.1 christos goto end;
4288 1.1 christos
4289 1.1 christos just_flags_log8:
4290 1.1 christos n = res & 0x80;
4291 1.1 christos nz = res & 0xff;
4292 1.1 christos v = 0;
4293 1.1 christos goto next;
4294 1.1 christos
4295 1.1 christos alu8:
4296 1.1 christos if (store2 (sd, &code->dst, res))
4297 1.1 christos goto end;
4298 1.1 christos
4299 1.1 christos just_flags_alu8:
4300 1.1 christos n = res & 0x80;
4301 1.1 christos nz = res & 0xff;
4302 1.1 christos c = (res & 0x100);
4303 1.1 christos switch (code->opcode / 4)
4304 1.1 christos {
4305 1.1 christos case O_ADD:
4306 1.1 christos case O_ADDX:
4307 1.1 christos v = ((rd & 0x80) == (ea & 0x80)
4308 1.1 christos && (rd & 0x80) != (res & 0x80));
4309 1.1 christos break;
4310 1.1 christos case O_SUB:
4311 1.1 christos case O_SUBX:
4312 1.1 christos case O_CMP:
4313 1.1 christos v = ((rd & 0x80) != (-ea & 0x80)
4314 1.1 christos && (rd & 0x80) != (res & 0x80));
4315 1.1 christos break;
4316 1.1 christos case O_NEG:
4317 1.1 christos v = (rd == 0x80);
4318 1.1 christos break;
4319 1.1 christos case O_DAA:
4320 1.1 christos case O_DAS:
4321 1.1 christos break; /* No effect on v flag. */
4322 1.1 christos }
4323 1.1 christos goto next;
4324 1.1 christos
4325 1.1 christos alu16:
4326 1.1 christos if (store2 (sd, &code->dst, res))
4327 1.1 christos goto end;
4328 1.1 christos
4329 1.1 christos just_flags_alu16:
4330 1.1 christos n = res & 0x8000;
4331 1.1 christos nz = res & 0xffff;
4332 1.1 christos c = (res & 0x10000);
4333 1.1 christos switch (code->opcode / 4)
4334 1.1 christos {
4335 1.1 christos case O_ADD:
4336 1.1 christos case O_ADDX:
4337 1.1 christos v = ((rd & 0x8000) == (ea & 0x8000)
4338 1.1 christos && (rd & 0x8000) != (res & 0x8000));
4339 1.1 christos break;
4340 1.1 christos case O_SUB:
4341 1.1 christos case O_SUBX:
4342 1.1 christos case O_CMP:
4343 1.1 christos v = ((rd & 0x8000) != (-ea & 0x8000)
4344 1.1 christos && (rd & 0x8000) != (res & 0x8000));
4345 1.1 christos break;
4346 1.1 christos case O_NEG:
4347 1.1 christos v = (rd == 0x8000);
4348 1.1 christos break;
4349 1.1 christos }
4350 1.1 christos goto next;
4351 1.1 christos
4352 1.1 christos alu32:
4353 1.1 christos if (store2 (sd, &code->dst, res))
4354 1.1 christos goto end;
4355 1.1 christos
4356 1.1 christos just_flags_alu32:
4357 1.1 christos n = res & 0x80000000;
4358 1.1 christos nz = res & 0xffffffff;
4359 1.1 christos switch (code->opcode / 4)
4360 1.1 christos {
4361 1.1 christos case O_ADD:
4362 1.1 christos case O_ADDX:
4363 1.1 christos v = ((rd & 0x80000000) == (ea & 0x80000000)
4364 1.1 christos && (rd & 0x80000000) != (res & 0x80000000));
4365 1.1 christos c = ((unsigned) res < (unsigned) rd) ||
4366 1.1 christos ((unsigned) res < (unsigned) ea);
4367 1.1 christos break;
4368 1.1 christos case O_SUB:
4369 1.1 christos case O_SUBX:
4370 1.1 christos case O_CMP:
4371 1.1 christos v = ((rd & 0x80000000) != (-ea & 0x80000000)
4372 1.1 christos && (rd & 0x80000000) != (res & 0x80000000));
4373 1.1 christos c = (unsigned) rd < (unsigned) -ea;
4374 1.1 christos break;
4375 1.1 christos case O_NEG:
4376 1.1 christos v = (rd == 0x80000000);
4377 1.1 christos c = res != 0;
4378 1.1 christos break;
4379 1.1 christos }
4380 1.1 christos goto next;
4381 1.1 christos
4382 1.1 christos next:
4383 1.7 christos if ((res = h8_get_delayed_branch (cpu)) != 0)
4384 1.1 christos {
4385 1.1 christos pc = res;
4386 1.7 christos h8_set_delayed_branch (cpu, 0);
4387 1.1 christos }
4388 1.1 christos else
4389 1.1 christos pc = code->next_pc;
4390 1.1 christos
4391 1.6 christos } while (0);
4392 1.1 christos
4393 1.6 christos end:
4394 1.7 christos h8_set_ticks (cpu, h8_get_ticks (cpu) + get_now () - tick_start);
4395 1.7 christos h8_set_cycles (cpu, h8_get_cycles (cpu) + cycles);
4396 1.7 christos h8_set_insts (cpu, h8_get_insts (cpu) + insts);
4397 1.7 christos cpu_set_pc (cpu, pc);
4398 1.7 christos BUILDSR (cpu);
4399 1.1 christos
4400 1.1 christos if (h8300smode)
4401 1.7 christos h8_set_exr (cpu, (trace<<7) | intMask);
4402 1.1 christos
4403 1.7 christos h8_set_mask (cpu, oldmask);
4404 1.1 christos }
4405 1.1 christos
4406 1.6 christos void
4407 1.6 christos sim_engine_run (SIM_DESC sd,
4408 1.6 christos int next_cpu_nr, /* ignore */
4409 1.6 christos int nr_cpus, /* ignore */
4410 1.6 christos int siggnal)
4411 1.6 christos {
4412 1.6 christos sim_cpu *cpu;
4413 1.6 christos
4414 1.6 christos SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
4415 1.6 christos
4416 1.6 christos cpu = STATE_CPU (sd, 0);
4417 1.6 christos
4418 1.6 christos while (1)
4419 1.6 christos {
4420 1.6 christos step_once (sd, cpu);
4421 1.6 christos if (sim_events_tick (sd))
4422 1.6 christos sim_events_process (sd);
4423 1.6 christos }
4424 1.6 christos }
4425 1.6 christos
4426 1.8 christos uint64_t
4427 1.8 christos sim_write (SIM_DESC sd, uint64_t addr, const void *buffer, uint64_t size)
4428 1.1 christos {
4429 1.7 christos sim_cpu *cpu = STATE_CPU (sd, 0);
4430 1.1 christos int i;
4431 1.7 christos const unsigned char *data = buffer;
4432 1.1 christos
4433 1.1 christos init_pointers (sd);
4434 1.1 christos if (addr < 0)
4435 1.1 christos return 0;
4436 1.1 christos for (i = 0; i < size; i++)
4437 1.1 christos {
4438 1.1 christos if (addr < memory_size)
4439 1.1 christos {
4440 1.7 christos h8_set_memory (cpu, addr + i, data[i]);
4441 1.1 christos }
4442 1.1 christos else
4443 1.7 christos break;
4444 1.1 christos }
4445 1.7 christos return i;
4446 1.1 christos }
4447 1.1 christos
4448 1.8 christos uint64_t
4449 1.8 christos sim_read (SIM_DESC sd, uint64_t addr, void *buffer, uint64_t size)
4450 1.1 christos {
4451 1.7 christos sim_cpu *cpu = STATE_CPU (sd, 0);
4452 1.7 christos
4453 1.1 christos init_pointers (sd);
4454 1.1 christos if (addr < 0)
4455 1.1 christos return 0;
4456 1.7 christos if (addr + size < memory_size)
4457 1.7 christos memcpy (buffer, h8_get_memory_buf (cpu) + addr, size);
4458 1.1 christos else
4459 1.7 christos return 0;
4460 1.1 christos return size;
4461 1.1 christos }
4462 1.1 christos
4463 1.6 christos static int
4464 1.7 christos h8300_reg_store (SIM_CPU *cpu, int rn, const void *buf, int length)
4465 1.1 christos {
4466 1.7 christos const unsigned char *value = buf;
4467 1.1 christos int longval;
4468 1.1 christos int shortval;
4469 1.1 christos int intval;
4470 1.7 christos
4471 1.1 christos longval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
4472 1.1 christos shortval = (value[0] << 8) | (value[1]);
4473 1.1 christos intval = h8300hmode ? longval : shortval;
4474 1.1 christos
4475 1.6 christos init_pointers (CPU_STATE (cpu));
4476 1.1 christos switch (rn)
4477 1.1 christos {
4478 1.1 christos case PC_REGNUM:
4479 1.1 christos if(h8300_normal_mode)
4480 1.7 christos cpu_set_pc (cpu, shortval); /* PC for Normal mode is 2 bytes */
4481 1.1 christos else
4482 1.7 christos cpu_set_pc (cpu, intval);
4483 1.1 christos break;
4484 1.1 christos default:
4485 1.6 christos return -1;
4486 1.1 christos case R0_REGNUM:
4487 1.1 christos case R1_REGNUM:
4488 1.1 christos case R2_REGNUM:
4489 1.1 christos case R3_REGNUM:
4490 1.1 christos case R4_REGNUM:
4491 1.1 christos case R5_REGNUM:
4492 1.1 christos case R6_REGNUM:
4493 1.1 christos case R7_REGNUM:
4494 1.1 christos case CCR_REGNUM:
4495 1.1 christos case EXR_REGNUM:
4496 1.1 christos case SBR_REGNUM:
4497 1.1 christos case VBR_REGNUM:
4498 1.1 christos case MACH_REGNUM:
4499 1.1 christos case MACL_REGNUM:
4500 1.7 christos h8_set_reg (cpu, rn, intval);
4501 1.1 christos break;
4502 1.1 christos case CYCLE_REGNUM:
4503 1.1 christos case INST_REGNUM:
4504 1.1 christos case TICK_REGNUM:
4505 1.7 christos h8_set_reg (cpu, rn, longval);
4506 1.1 christos break;
4507 1.1 christos }
4508 1.1 christos return length;
4509 1.1 christos }
4510 1.1 christos
4511 1.6 christos static int
4512 1.7 christos h8300_reg_fetch (SIM_CPU *cpu, int rn, void *buf, int length)
4513 1.1 christos {
4514 1.7 christos unsigned char *value = buf;
4515 1.1 christos int v;
4516 1.1 christos int longreg = 0;
4517 1.1 christos
4518 1.6 christos init_pointers (CPU_STATE (cpu));
4519 1.1 christos
4520 1.1 christos if (!h8300smode && rn >= EXR_REGNUM)
4521 1.1 christos rn++;
4522 1.1 christos switch (rn)
4523 1.1 christos {
4524 1.1 christos default:
4525 1.6 christos return -1;
4526 1.6 christos case PC_REGNUM:
4527 1.7 christos v = cpu_get_pc (cpu);
4528 1.1 christos break;
4529 1.1 christos case CCR_REGNUM:
4530 1.1 christos case EXR_REGNUM:
4531 1.1 christos case SBR_REGNUM:
4532 1.1 christos case VBR_REGNUM:
4533 1.1 christos case MACH_REGNUM:
4534 1.1 christos case MACL_REGNUM:
4535 1.1 christos case R0_REGNUM:
4536 1.1 christos case R1_REGNUM:
4537 1.1 christos case R2_REGNUM:
4538 1.1 christos case R3_REGNUM:
4539 1.1 christos case R4_REGNUM:
4540 1.1 christos case R5_REGNUM:
4541 1.1 christos case R6_REGNUM:
4542 1.1 christos case R7_REGNUM:
4543 1.7 christos v = h8_get_reg (cpu, rn);
4544 1.1 christos break;
4545 1.1 christos case CYCLE_REGNUM:
4546 1.1 christos case TICK_REGNUM:
4547 1.6 christos case INST_REGNUM:
4548 1.7 christos v = h8_get_reg (cpu, rn);
4549 1.1 christos longreg = 1;
4550 1.1 christos break;
4551 1.6 christos case ZERO_REGNUM:
4552 1.6 christos v = 0;
4553 1.1 christos break;
4554 1.1 christos }
4555 1.1 christos /* In Normal mode PC is 2 byte, but other registers are 4 byte */
4556 1.1 christos if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode))
4557 1.1 christos {
4558 1.7 christos value[0] = v >> 24;
4559 1.7 christos value[1] = v >> 16;
4560 1.7 christos value[2] = v >> 8;
4561 1.7 christos value[3] = v >> 0;
4562 1.6 christos return 4;
4563 1.1 christos }
4564 1.1 christos else
4565 1.1 christos {
4566 1.7 christos value[0] = v >> 8;
4567 1.7 christos value[1] = v;
4568 1.6 christos return 2;
4569 1.1 christos }
4570 1.1 christos }
4571 1.1 christos
4572 1.1 christos void
4573 1.8 christos sim_info (SIM_DESC sd, bool verbose)
4574 1.1 christos {
4575 1.7 christos sim_cpu *cpu = STATE_CPU (sd, 0);
4576 1.7 christos double timetaken = (double) h8_get_ticks (cpu) / (double) now_persec ();
4577 1.7 christos double virttime = h8_get_cycles (cpu) / 10.0e6;
4578 1.1 christos
4579 1.7 christos sim_io_printf (sd, "\n\n#instructions executed %10d\n", h8_get_insts (cpu));
4580 1.7 christos sim_io_printf (sd, "#cycles (v approximate) %10d\n", h8_get_cycles (cpu));
4581 1.6 christos sim_io_printf (sd, "#real time taken %10.4f\n", timetaken);
4582 1.6 christos sim_io_printf (sd, "#virtual time taken %10.4f\n", virttime);
4583 1.1 christos if (timetaken != 0.0)
4584 1.6 christos sim_io_printf (sd, "#simulation ratio %10.4f\n", virttime / timetaken);
4585 1.1 christos
4586 1.1 christos #ifdef ADEBUG
4587 1.1 christos /* This to be conditional on `what' (aka `verbose'),
4588 1.1 christos however it was never passed as non-zero. */
4589 1.1 christos if (1)
4590 1.1 christos {
4591 1.1 christos int i;
4592 1.1 christos for (i = 0; i < O_LAST; i++)
4593 1.1 christos {
4594 1.1 christos if (h8_get_stats (sd, i))
4595 1.6 christos sim_io_printf (sd, "%d: %d\n", i, h8_get_stats (sd, i));
4596 1.1 christos }
4597 1.1 christos }
4598 1.1 christos #endif
4599 1.1 christos }
4600 1.1 christos
4601 1.1 christos /* Indicate whether the cpu is an H8/300 or H8/300H.
4602 1.1 christos FLAG is non-zero for the H8/300H. */
4603 1.1 christos
4604 1.7 christos static void
4605 1.1 christos set_h8300h (unsigned long machine)
4606 1.1 christos {
4607 1.1 christos /* FIXME: Much of the code in sim_load can be moved to sim_open.
4608 1.1 christos This function being replaced by a sim_open:ARGV configuration
4609 1.1 christos option. */
4610 1.1 christos
4611 1.1 christos h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0;
4612 1.1 christos
4613 1.1 christos if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
4614 1.1 christos h8300sxmode = 1;
4615 1.1 christos
4616 1.1 christos if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode)
4617 1.1 christos h8300smode = 1;
4618 1.1 christos
4619 1.1 christos if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode)
4620 1.1 christos h8300hmode = 1;
4621 1.1 christos
4622 1.1 christos if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn)
4623 1.1 christos h8300_normal_mode = 1;
4624 1.1 christos }
4625 1.1 christos
4626 1.6 christos /* H8300-specific options.
4627 1.6 christos TODO: These really should be merged into the common model modules. */
4628 1.6 christos typedef enum {
4629 1.6 christos OPTION_H8300H,
4630 1.6 christos OPTION_H8300S,
4631 1.6 christos OPTION_H8300SX
4632 1.6 christos } H8300_OPTIONS;
4633 1.6 christos
4634 1.6 christos static SIM_RC
4635 1.6 christos h8300_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
4636 1.6 christos char *arg, int is_command ATTRIBUTE_UNUSED)
4637 1.6 christos {
4638 1.6 christos switch ((H8300_OPTIONS) opt)
4639 1.6 christos {
4640 1.6 christos case OPTION_H8300H:
4641 1.6 christos set_h8300h (bfd_mach_h8300h);
4642 1.6 christos break;
4643 1.6 christos case OPTION_H8300S:
4644 1.6 christos set_h8300h (bfd_mach_h8300s);
4645 1.6 christos break;
4646 1.6 christos case OPTION_H8300SX:
4647 1.6 christos set_h8300h (bfd_mach_h8300sx);
4648 1.6 christos break;
4649 1.6 christos
4650 1.6 christos default:
4651 1.6 christos /* We'll actually never get here; the caller handles the error
4652 1.6 christos case. */
4653 1.6 christos sim_io_eprintf (sd, "Unknown option `%s'\n", arg);
4654 1.6 christos return SIM_RC_FAIL;
4655 1.6 christos }
4656 1.6 christos
4657 1.6 christos return SIM_RC_OK;
4658 1.6 christos }
4659 1.6 christos
4660 1.6 christos static const OPTION h8300_options[] =
4661 1.6 christos {
4662 1.6 christos { {"h8300h", no_argument, NULL, OPTION_H8300H},
4663 1.6 christos 'h', NULL, "Indicate the CPU is H8/300H",
4664 1.6 christos h8300_option_handler },
4665 1.6 christos { {"h8300s", no_argument, NULL, OPTION_H8300S},
4666 1.6 christos 'S', NULL, "Indicate the CPU is H8S",
4667 1.6 christos h8300_option_handler },
4668 1.6 christos { {"h8300sx", no_argument, NULL, OPTION_H8300SX},
4669 1.6 christos 'x', NULL, "Indicate the CPU is H8SX",
4670 1.6 christos h8300_option_handler },
4671 1.6 christos { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
4672 1.6 christos };
4673 1.6 christos
4674 1.5 christos static sim_cia
4675 1.5 christos h8300_pc_get (sim_cpu *cpu)
4676 1.5 christos {
4677 1.8 christos return H8300_SIM_CPU (cpu)->pc;
4678 1.5 christos }
4679 1.5 christos
4680 1.5 christos static void
4681 1.5 christos h8300_pc_set (sim_cpu *cpu, sim_cia pc)
4682 1.5 christos {
4683 1.8 christos H8300_SIM_CPU (cpu)->pc = pc;
4684 1.5 christos }
4685 1.5 christos
4686 1.1 christos /* Cover function of sim_state_free to free the cpu buffers as well. */
4687 1.1 christos
4688 1.1 christos static void
4689 1.1 christos free_state (SIM_DESC sd)
4690 1.1 christos {
4691 1.1 christos if (STATE_MODULES (sd) != NULL)
4692 1.1 christos sim_module_uninstall (sd);
4693 1.1 christos
4694 1.1 christos /* Fixme: free buffers in _sim_cpu. */
4695 1.1 christos sim_state_free (sd);
4696 1.1 christos }
4697 1.1 christos
4698 1.1 christos SIM_DESC
4699 1.1 christos sim_open (SIM_OPEN_KIND kind,
4700 1.1 christos struct host_callback_struct *callback,
4701 1.1 christos struct bfd *abfd,
4702 1.6 christos char * const *argv)
4703 1.1 christos {
4704 1.5 christos int i;
4705 1.1 christos SIM_DESC sd;
4706 1.1 christos sim_cpu *cpu;
4707 1.1 christos
4708 1.7 christos sd = sim_state_alloc_extra (kind, callback, sizeof (struct h8300_sim_state));
4709 1.7 christos
4710 1.7 christos /* Set default options before parsing user options. */
4711 1.7 christos current_target_byte_order = BFD_ENDIAN_BIG;
4712 1.5 christos
4713 1.5 christos /* The cpu data is kept in a separately allocated chunk of memory. */
4714 1.8 christos if (sim_cpu_alloc_all_extra (sd, 0, sizeof (struct h8300_sim_cpu))
4715 1.8 christos != SIM_RC_OK)
4716 1.5 christos {
4717 1.5 christos free_state (sd);
4718 1.5 christos return 0;
4719 1.5 christos }
4720 1.5 christos
4721 1.1 christos cpu = STATE_CPU (sd, 0);
4722 1.1 christos SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
4723 1.7 christos h8_set_reg (cpu, SBR_REGNUM, 0xFFFFFF00);
4724 1.1 christos /* sim_cpu object is new, so some initialization is needed. */
4725 1.1 christos init_pointers_needed = 1;
4726 1.1 christos
4727 1.6 christos if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
4728 1.6 christos {
4729 1.6 christos free_state (sd);
4730 1.6 christos return 0;
4731 1.6 christos }
4732 1.1 christos
4733 1.6 christos if (sim_add_option_table (sd, NULL, h8300_options) != SIM_RC_OK)
4734 1.1 christos {
4735 1.1 christos free_state (sd);
4736 1.1 christos return 0;
4737 1.1 christos }
4738 1.1 christos
4739 1.6 christos /* The parser will print an error message for us, so we silently return. */
4740 1.1 christos if (sim_parse_args (sd, argv) != SIM_RC_OK)
4741 1.1 christos {
4742 1.1 christos /* Uninstall the modules to avoid memory leaks,
4743 1.1 christos file descriptor leaks, etc. */
4744 1.1 christos free_state (sd);
4745 1.1 christos return 0;
4746 1.1 christos }
4747 1.1 christos
4748 1.1 christos /* Check for/establish the a reference program image. */
4749 1.7 christos if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
4750 1.1 christos {
4751 1.1 christos free_state (sd);
4752 1.1 christos return 0;
4753 1.1 christos }
4754 1.1 christos
4755 1.1 christos /* Establish any remaining configuration options. */
4756 1.1 christos if (sim_config (sd) != SIM_RC_OK)
4757 1.1 christos {
4758 1.1 christos free_state (sd);
4759 1.1 christos return 0;
4760 1.1 christos }
4761 1.1 christos
4762 1.1 christos if (sim_post_argv_init (sd) != SIM_RC_OK)
4763 1.1 christos {
4764 1.1 christos /* Uninstall the modules to avoid memory leaks,
4765 1.1 christos file descriptor leaks, etc. */
4766 1.1 christos free_state (sd);
4767 1.1 christos return 0;
4768 1.1 christos }
4769 1.1 christos
4770 1.5 christos /* CPU specific initialization. */
4771 1.5 christos for (i = 0; i < MAX_NR_PROCESSORS; ++i)
4772 1.5 christos {
4773 1.8 christos cpu = STATE_CPU (sd, i);
4774 1.5 christos
4775 1.6 christos CPU_REG_FETCH (cpu) = h8300_reg_fetch;
4776 1.6 christos CPU_REG_STORE (cpu) = h8300_reg_store;
4777 1.5 christos CPU_PC_FETCH (cpu) = h8300_pc_get;
4778 1.5 christos CPU_PC_STORE (cpu) = h8300_pc_set;
4779 1.5 christos }
4780 1.5 christos
4781 1.1 christos /* sim_hw_configure (sd); */
4782 1.1 christos
4783 1.1 christos /* FIXME: Much of the code in sim_load can be moved here. */
4784 1.1 christos
4785 1.1 christos return sd;
4786 1.1 christos }
4787 1.1 christos
4788 1.1 christos /* Called by gdb to load a program into memory. */
4789 1.1 christos
4790 1.1 christos SIM_RC
4791 1.3 christos sim_load (SIM_DESC sd, const char *prog, bfd *abfd, int from_tty)
4792 1.1 christos {
4793 1.7 christos sim_cpu *cpu = STATE_CPU (sd, 0);
4794 1.7 christos struct h8300_sim_state *state = H8300_SIM_STATE (sd);
4795 1.1 christos bfd *prog_bfd;
4796 1.1 christos
4797 1.1 christos /* FIXME: The code below that sets a specific variant of the H8/300
4798 1.1 christos being simulated should be moved to sim_open(). */
4799 1.1 christos
4800 1.1 christos /* See if the file is for the H8/300 or H8/300H. */
4801 1.1 christos /* ??? This may not be the most efficient way. The z8k simulator
4802 1.1 christos does this via a different mechanism (INIT_EXTRA_SYMTAB_INFO). */
4803 1.1 christos if (abfd != NULL)
4804 1.1 christos prog_bfd = abfd;
4805 1.1 christos else
4806 1.1 christos prog_bfd = bfd_openr (prog, NULL);
4807 1.1 christos if (prog_bfd != NULL)
4808 1.1 christos {
4809 1.1 christos /* Set the cpu type. We ignore failure from bfd_check_format
4810 1.1 christos and bfd_openr as sim_load_file checks too. */
4811 1.1 christos if (bfd_check_format (prog_bfd, bfd_object))
4812 1.1 christos {
4813 1.1 christos set_h8300h (bfd_get_mach (prog_bfd));
4814 1.1 christos }
4815 1.1 christos }
4816 1.1 christos
4817 1.1 christos /* If we're using gdb attached to the simulator, then we have to
4818 1.1 christos reallocate memory for the simulator.
4819 1.1 christos
4820 1.1 christos When gdb first starts, it calls fetch_registers (among other
4821 1.1 christos functions), which in turn calls init_pointers, which allocates
4822 1.1 christos simulator memory.
4823 1.1 christos
4824 1.1 christos The problem is when we do that, we don't know whether we're
4825 1.1 christos debugging an H8/300 or H8/300H program.
4826 1.1 christos
4827 1.1 christos This is the first point at which we can make that determination,
4828 1.1 christos so we just reallocate memory now; this will also allow us to handle
4829 1.1 christos switching between H8/300 and H8/300H programs without exiting
4830 1.1 christos gdb. */
4831 1.1 christos
4832 1.1 christos if (h8300smode && !h8300_normal_mode)
4833 1.1 christos memory_size = H8300S_MSIZE;
4834 1.1 christos else if (h8300hmode && !h8300_normal_mode)
4835 1.1 christos memory_size = H8300H_MSIZE;
4836 1.1 christos else
4837 1.1 christos memory_size = H8300_MSIZE;
4838 1.1 christos
4839 1.7 christos if (h8_get_memory_buf (cpu))
4840 1.7 christos free (h8_get_memory_buf (cpu));
4841 1.1 christos
4842 1.7 christos h8_set_memory_buf (cpu, (unsigned char *)
4843 1.1 christos calloc (sizeof (char), memory_size));
4844 1.7 christos state->memory_size = memory_size;
4845 1.1 christos
4846 1.1 christos /* `msize' must be a power of two. */
4847 1.1 christos if ((memory_size & (memory_size - 1)) != 0)
4848 1.1 christos {
4849 1.6 christos sim_io_printf (sd, "sim_load: bad memory size.\n");
4850 1.1 christos return SIM_RC_FAIL;
4851 1.1 christos }
4852 1.7 christos h8_set_mask (cpu, memory_size - 1);
4853 1.1 christos
4854 1.6 christos if (sim_load_file (sd, STATE_MY_NAME (sd), STATE_CALLBACK (sd), prog,
4855 1.6 christos prog_bfd, STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG,
4856 1.1 christos 0, sim_write)
4857 1.1 christos == NULL)
4858 1.1 christos {
4859 1.1 christos /* Close the bfd if we opened it. */
4860 1.1 christos if (abfd == NULL && prog_bfd != NULL)
4861 1.1 christos bfd_close (prog_bfd);
4862 1.1 christos return SIM_RC_FAIL;
4863 1.1 christos }
4864 1.1 christos
4865 1.1 christos /* Close the bfd if we opened it. */
4866 1.1 christos if (abfd == NULL && prog_bfd != NULL)
4867 1.1 christos bfd_close (prog_bfd);
4868 1.1 christos return SIM_RC_OK;
4869 1.1 christos }
4870 1.1 christos
4871 1.1 christos SIM_RC
4872 1.6 christos sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
4873 1.6 christos char * const *argv, char * const *env)
4874 1.1 christos {
4875 1.7 christos SIM_CPU *cpu = STATE_CPU (sd, 0);
4876 1.1 christos int i = 0;
4877 1.1 christos int no_of_args = 0;
4878 1.1 christos
4879 1.1 christos if (abfd != NULL)
4880 1.7 christos cpu_set_pc (cpu, bfd_get_start_address (abfd));
4881 1.1 christos else
4882 1.7 christos cpu_set_pc (cpu, 0);
4883 1.1 christos
4884 1.1 christos /* Command Line support. */
4885 1.1 christos if (argv != NULL)
4886 1.1 christos {
4887 1.1 christos /* Counting the no. of commandline arguments. */
4888 1.1 christos for (no_of_args = 0; argv[no_of_args] != NULL; no_of_args++)
4889 1.1 christos continue;
4890 1.1 christos
4891 1.1 christos /* Allocating memory for the argv pointers. */
4892 1.7 christos h8_set_command_line (cpu, (char **) malloc ((sizeof (char *))
4893 1.1 christos * (no_of_args + 1)));
4894 1.1 christos
4895 1.1 christos for (i = 0; i < no_of_args; i++)
4896 1.1 christos {
4897 1.1 christos /* Copying the argument string. */
4898 1.7 christos h8_set_cmdline_arg (cpu, i, (char *) strdup (argv[i]));
4899 1.1 christos }
4900 1.7 christos h8_set_cmdline_arg (cpu, i, NULL);
4901 1.1 christos }
4902 1.1 christos
4903 1.1 christos return SIM_RC_OK;
4904 1.1 christos }
4905