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