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