compile.c revision 1.1.1.2 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 int
1863 1.1 christos sim_stop (SIM_DESC sd)
1864 1.1 christos {
1865 1.1 christos /* FIXME: use a real signal value. */
1866 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGINT);
1867 1.1 christos return 1;
1868 1.1 christos }
1869 1.1 christos
1870 1.1 christos #define OBITOP(name, f, s, op) \
1871 1.1 christos case O (name, SB): \
1872 1.1 christos { \
1873 1.1 christos int m, tmp; \
1874 1.1 christos \
1875 1.1 christos if (f) \
1876 1.1 christos if (fetch (sd, &code->dst, &ea)) \
1877 1.1 christos goto end; \
1878 1.1 christos if (fetch (sd, &code->src, &tmp)) \
1879 1.1 christos goto end; \
1880 1.1 christos m = 1 << (tmp & 7); \
1881 1.1 christos op; \
1882 1.1 christos if (s) \
1883 1.1 christos if (store (sd, &code->dst,ea)) \
1884 1.1 christos goto end; \
1885 1.1 christos goto next; \
1886 1.1 christos }
1887 1.1 christos
1888 1.1 christos void
1889 1.1 christos sim_resume (SIM_DESC sd, int step, int siggnal)
1890 1.1 christos {
1891 1.1 christos static int init1;
1892 1.1 christos int cycles = 0;
1893 1.1 christos int insts = 0;
1894 1.1 christos int tick_start = get_now ();
1895 1.1 christos int poll_count = 0;
1896 1.1 christos int res;
1897 1.1 christos int tmp;
1898 1.1 christos int rd;
1899 1.1 christos int ea;
1900 1.1 christos int bit;
1901 1.1 christos int pc;
1902 1.1 christos int c, nz, v, n, u, h, ui, intMaskBit;
1903 1.1 christos int trace, intMask;
1904 1.1 christos int oldmask;
1905 1.1 christos enum sim_stop reason;
1906 1.1 christos int sigrc;
1907 1.1 christos
1908 1.1 christos init_pointers (sd);
1909 1.1 christos
1910 1.1 christos if (step)
1911 1.1 christos {
1912 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
1913 1.1 christos }
1914 1.1 christos else
1915 1.1 christos {
1916 1.1 christos sim_engine_set_run_state (sd, sim_running, 0);
1917 1.1 christos }
1918 1.1 christos
1919 1.1 christos pc = h8_get_pc (sd);
1920 1.1 christos
1921 1.1 christos /* The PC should never be odd. */
1922 1.1 christos if (pc & 0x1)
1923 1.1 christos {
1924 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGBUS);
1925 1.1 christos return;
1926 1.1 christos }
1927 1.1 christos
1928 1.1 christos /* Get Status Register (flags). */
1929 1.1 christos GETSR (sd);
1930 1.1 christos
1931 1.1 christos if (h8300smode) /* Get exr. */
1932 1.1 christos {
1933 1.1 christos trace = (h8_get_exr (sd) >> 7) & 1;
1934 1.1 christos intMask = h8_get_exr (sd) & 7;
1935 1.1 christos }
1936 1.1 christos
1937 1.1 christos oldmask = h8_get_mask (sd);
1938 1.1 christos if (!h8300hmode || h8300_normal_mode)
1939 1.1 christos h8_set_mask (sd, 0xffff);
1940 1.1 christos do
1941 1.1 christos {
1942 1.1 christos unsigned short cidx;
1943 1.1 christos decoded_inst *code;
1944 1.1 christos
1945 1.1 christos top:
1946 1.1 christos cidx = h8_get_cache_idx (sd, pc);
1947 1.1 christos if (cidx == (unsigned short) -1 ||
1948 1.1 christos cidx >= sd->sim_cache_size)
1949 1.1 christos goto illegal;
1950 1.1 christos
1951 1.1 christos code = sd->sim_cache + cidx;
1952 1.1 christos
1953 1.1 christos #if ADEBUG
1954 1.1 christos if (debug)
1955 1.1 christos {
1956 1.1 christos printf ("%x %d %s\n", pc, code->opcode,
1957 1.1 christos code->op ? code->op->name : "**");
1958 1.1 christos }
1959 1.1 christos h8_increment_stats (sd, code->opcode);
1960 1.1 christos #endif
1961 1.1 christos
1962 1.1 christos if (code->opcode)
1963 1.1 christos {
1964 1.1 christos cycles += code->cycles;
1965 1.1 christos insts++;
1966 1.1 christos }
1967 1.1 christos
1968 1.1 christos switch (code->opcode)
1969 1.1 christos {
1970 1.1 christos case 0:
1971 1.1 christos /*
1972 1.1 christos * This opcode is a fake for when we get to an
1973 1.1 christos * instruction which hasnt been compiled
1974 1.1 christos */
1975 1.1 christos compile (sd, pc);
1976 1.1 christos goto top;
1977 1.1 christos break;
1978 1.1 christos
1979 1.1 christos case O (O_MOVAB, SL):
1980 1.1 christos case O (O_MOVAW, SL):
1981 1.1 christos case O (O_MOVAL, SL):
1982 1.1 christos /* 1) Evaluate 2nd argument (dst).
1983 1.1 christos 2) Mask / zero extend according to whether 1st argument (src)
1984 1.1 christos is INDEXB, INDEXW, or INDEXL.
1985 1.1 christos 3) Left-shift the result by 0, 1 or 2, according to size of mova
1986 1.1 christos (mova/b, mova/w, mova/l).
1987 1.1 christos 4) Add literal value of 1st argument (src).
1988 1.1 christos 5) Store result in 3rd argument (op3).
1989 1.1 christos */
1990 1.1 christos
1991 1.1 christos /* Alas, since this is the only instruction with 3 arguments,
1992 1.1 christos decode doesn't handle them very well. Some fix-up is required.
1993 1.1 christos
1994 1.1 christos a) The size of dst is determined by whether src is
1995 1.1 christos INDEXB or INDEXW. */
1996 1.1 christos
1997 1.1 christos if (OP_KIND (code->src.type) == OP_INDEXB)
1998 1.1 christos code->dst.type = X (OP_KIND (code->dst.type), SB);
1999 1.1 christos else if (OP_KIND (code->src.type) == OP_INDEXW)
2000 1.1 christos code->dst.type = X (OP_KIND (code->dst.type), SW);
2001 1.1 christos
2002 1.1 christos /* b) If op3 == null, then this is the short form of the insn.
2003 1.1 christos Dst is the dispreg of src, and op3 is the 32-bit form
2004 1.1 christos of the same register.
2005 1.1 christos */
2006 1.1 christos
2007 1.1 christos if (code->op3.type == 0)
2008 1.1 christos {
2009 1.1 christos /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
2010 1.1 christos We get to compose dst and op3 as follows:
2011 1.1 christos
2012 1.1 christos op3 is a 32-bit register, ID == src.reg.
2013 1.1 christos dst is the same register, but 8 or 16 bits
2014 1.1 christos depending on whether src is INDEXB or INDEXW.
2015 1.1 christos */
2016 1.1 christos
2017 1.1 christos code->op3.type = X (OP_REG, SL);
2018 1.1 christos code->op3.reg = code->src.reg;
2019 1.1 christos code->op3.literal = 0;
2020 1.1 christos
2021 1.1 christos if (OP_KIND (code->src.type) == OP_INDEXB)
2022 1.1 christos {
2023 1.1 christos code->dst.type = X (OP_REG, SB);
2024 1.1 christos code->dst.reg = code->op3.reg + 8;
2025 1.1 christos }
2026 1.1 christos else
2027 1.1 christos code->dst.type = X (OP_REG, SW);
2028 1.1 christos }
2029 1.1 christos
2030 1.1 christos if (fetch (sd, &code->dst, &ea))
2031 1.1 christos goto end;
2032 1.1 christos
2033 1.1 christos switch (OP_KIND (code->src.type)) {
2034 1.1 christos case OP_INDEXB: ea = ea & 0xff; break;
2035 1.1 christos case OP_INDEXW: ea = ea & 0xffff; break;
2036 1.1 christos case OP_INDEXL: break;
2037 1.1 christos default: goto illegal;
2038 1.1 christos }
2039 1.1 christos
2040 1.1 christos switch (code->opcode) {
2041 1.1 christos case O (O_MOVAB, SL): break;
2042 1.1 christos case O (O_MOVAW, SL): ea = ea << 1; break;
2043 1.1 christos case O (O_MOVAL, SL): ea = ea << 2; break;
2044 1.1 christos default: goto illegal;
2045 1.1 christos }
2046 1.1 christos
2047 1.1 christos ea = ea + code->src.literal;
2048 1.1 christos
2049 1.1 christos if (store (sd, &code->op3, ea))
2050 1.1 christos goto end;
2051 1.1 christos
2052 1.1 christos goto next;
2053 1.1 christos
2054 1.1 christos case O (O_SUBX, SB): /* subx, extended sub */
2055 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2056 1.1 christos goto end;
2057 1.1 christos if (fetch (sd, &code->src, &ea))
2058 1.1 christos goto end;
2059 1.1 christos ea = -(ea + C);
2060 1.1 christos res = rd + ea;
2061 1.1 christos goto alu8;
2062 1.1 christos
2063 1.1 christos case O (O_SUBX, SW): /* subx, extended sub */
2064 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2065 1.1 christos goto end;
2066 1.1 christos if (fetch (sd, &code->src, &ea))
2067 1.1 christos goto end;
2068 1.1 christos ea = -(ea + C);
2069 1.1 christos res = rd + ea;
2070 1.1 christos goto alu16;
2071 1.1 christos
2072 1.1 christos case O (O_SUBX, SL): /* subx, extended sub */
2073 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2074 1.1 christos goto end;
2075 1.1 christos if (fetch (sd, &code->src, &ea))
2076 1.1 christos goto end;
2077 1.1 christos ea = -(ea + C);
2078 1.1 christos res = rd + ea;
2079 1.1 christos goto alu32;
2080 1.1 christos
2081 1.1 christos case O (O_ADDX, SB): /* addx, extended add */
2082 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2083 1.1 christos goto end;
2084 1.1 christos if (fetch (sd, &code->src, &ea))
2085 1.1 christos goto end;
2086 1.1 christos ea = ea + C;
2087 1.1 christos res = rd + ea;
2088 1.1 christos goto alu8;
2089 1.1 christos
2090 1.1 christos case O (O_ADDX, SW): /* addx, extended add */
2091 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2092 1.1 christos goto end;
2093 1.1 christos if (fetch (sd, &code->src, &ea))
2094 1.1 christos goto end;
2095 1.1 christos ea = ea + C;
2096 1.1 christos res = rd + ea;
2097 1.1 christos goto alu16;
2098 1.1 christos
2099 1.1 christos case O (O_ADDX, SL): /* addx, extended add */
2100 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2101 1.1 christos goto end;
2102 1.1 christos if (fetch (sd, &code->src, &ea))
2103 1.1 christos goto end;
2104 1.1 christos ea = ea + C;
2105 1.1 christos res = rd + ea;
2106 1.1 christos goto alu32;
2107 1.1 christos
2108 1.1 christos case O (O_SUB, SB): /* sub.b */
2109 1.1 christos /* Fetch rd and ea. */
2110 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2111 1.1 christos goto end;
2112 1.1 christos ea = -ea;
2113 1.1 christos res = rd + ea;
2114 1.1 christos goto alu8;
2115 1.1 christos
2116 1.1 christos case O (O_SUB, SW): /* sub.w */
2117 1.1 christos /* Fetch rd and ea. */
2118 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2119 1.1 christos goto end;
2120 1.1 christos ea = -ea;
2121 1.1 christos res = rd + ea;
2122 1.1 christos goto alu16;
2123 1.1 christos
2124 1.1 christos case O (O_SUB, SL): /* sub.l */
2125 1.1 christos /* Fetch rd and ea. */
2126 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2127 1.1 christos goto end;
2128 1.1 christos ea = -ea;
2129 1.1 christos res = rd + ea;
2130 1.1 christos goto alu32;
2131 1.1 christos
2132 1.1 christos case O (O_NEG, SB): /* neg.b */
2133 1.1 christos /* Fetch ea. */
2134 1.1 christos if (fetch2 (sd, &code->src, &ea))
2135 1.1 christos goto end;
2136 1.1 christos ea = -ea;
2137 1.1 christos rd = 0;
2138 1.1 christos res = rd + ea;
2139 1.1 christos goto alu8;
2140 1.1 christos
2141 1.1 christos case O (O_NEG, SW): /* neg.w */
2142 1.1 christos /* Fetch ea. */
2143 1.1 christos if (fetch2 (sd, &code->src, &ea))
2144 1.1 christos goto end;
2145 1.1 christos ea = -ea;
2146 1.1 christos rd = 0;
2147 1.1 christos res = rd + ea;
2148 1.1 christos goto alu16;
2149 1.1 christos
2150 1.1 christos case O (O_NEG, SL): /* neg.l */
2151 1.1 christos /* Fetch ea. */
2152 1.1 christos if (fetch2 (sd, &code->src, &ea))
2153 1.1 christos goto end;
2154 1.1 christos ea = -ea;
2155 1.1 christos rd = 0;
2156 1.1 christos res = rd + ea;
2157 1.1 christos goto alu32;
2158 1.1 christos
2159 1.1 christos case O (O_ADD, SB): /* add.b */
2160 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2161 1.1 christos goto end;
2162 1.1 christos if (fetch (sd, &code->src, &ea))
2163 1.1 christos goto end;
2164 1.1 christos res = rd + ea;
2165 1.1 christos goto alu8;
2166 1.1 christos
2167 1.1 christos case O (O_ADD, SW): /* add.w */
2168 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2169 1.1 christos goto end;
2170 1.1 christos if (fetch (sd, &code->src, &ea))
2171 1.1 christos goto end;
2172 1.1 christos res = rd + ea;
2173 1.1 christos goto alu16;
2174 1.1 christos
2175 1.1 christos case O (O_ADD, SL): /* add.l */
2176 1.1 christos if (fetch2 (sd, &code->dst, &rd))
2177 1.1 christos goto end;
2178 1.1 christos if (fetch (sd, &code->src, &ea))
2179 1.1 christos goto end;
2180 1.1 christos res = rd + ea;
2181 1.1 christos goto alu32;
2182 1.1 christos
2183 1.1 christos case O (O_AND, SB): /* and.b */
2184 1.1 christos /* Fetch rd and ea. */
2185 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2186 1.1 christos goto end;
2187 1.1 christos res = rd & ea;
2188 1.1 christos goto log8;
2189 1.1 christos
2190 1.1 christos case O (O_AND, SW): /* and.w */
2191 1.1 christos /* Fetch rd and ea. */
2192 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2193 1.1 christos goto end;
2194 1.1 christos res = rd & ea;
2195 1.1 christos goto log16;
2196 1.1 christos
2197 1.1 christos case O (O_AND, SL): /* and.l */
2198 1.1 christos /* Fetch rd and ea. */
2199 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2200 1.1 christos goto end;
2201 1.1 christos res = rd & ea;
2202 1.1 christos goto log32;
2203 1.1 christos
2204 1.1 christos case O (O_OR, SB): /* or.b */
2205 1.1 christos /* Fetch rd and ea. */
2206 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2207 1.1 christos goto end;
2208 1.1 christos res = rd | ea;
2209 1.1 christos goto log8;
2210 1.1 christos
2211 1.1 christos case O (O_OR, SW): /* or.w */
2212 1.1 christos /* Fetch rd and ea. */
2213 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2214 1.1 christos goto end;
2215 1.1 christos res = rd | ea;
2216 1.1 christos goto log16;
2217 1.1 christos
2218 1.1 christos case O (O_OR, SL): /* or.l */
2219 1.1 christos /* Fetch rd and ea. */
2220 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2221 1.1 christos goto end;
2222 1.1 christos res = rd | ea;
2223 1.1 christos goto log32;
2224 1.1 christos
2225 1.1 christos case O (O_XOR, SB): /* xor.b */
2226 1.1 christos /* Fetch rd and ea. */
2227 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2228 1.1 christos goto end;
2229 1.1 christos res = rd ^ ea;
2230 1.1 christos goto log8;
2231 1.1 christos
2232 1.1 christos case O (O_XOR, SW): /* xor.w */
2233 1.1 christos /* Fetch rd and ea. */
2234 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2235 1.1 christos goto end;
2236 1.1 christos res = rd ^ ea;
2237 1.1 christos goto log16;
2238 1.1 christos
2239 1.1 christos case O (O_XOR, SL): /* xor.l */
2240 1.1 christos /* Fetch rd and ea. */
2241 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2242 1.1 christos goto end;
2243 1.1 christos res = rd ^ ea;
2244 1.1 christos goto log32;
2245 1.1 christos
2246 1.1 christos case O (O_MOV, SB):
2247 1.1 christos if (fetch (sd, &code->src, &res))
2248 1.1 christos goto end;
2249 1.1 christos if (store (sd, &code->dst, res))
2250 1.1 christos goto end;
2251 1.1 christos goto just_flags_log8;
2252 1.1 christos case O (O_MOV, SW):
2253 1.1 christos if (fetch (sd, &code->src, &res))
2254 1.1 christos goto end;
2255 1.1 christos if (store (sd, &code->dst, res))
2256 1.1 christos goto end;
2257 1.1 christos goto just_flags_log16;
2258 1.1 christos case O (O_MOV, SL):
2259 1.1 christos if (fetch (sd, &code->src, &res))
2260 1.1 christos goto end;
2261 1.1 christos if (store (sd, &code->dst, res))
2262 1.1 christos goto end;
2263 1.1 christos goto just_flags_log32;
2264 1.1 christos
2265 1.1 christos case O (O_MOVMD, SB): /* movmd.b */
2266 1.1 christos ea = GET_W_REG (4);
2267 1.1 christos if (ea == 0)
2268 1.1 christos ea = 0x10000;
2269 1.1 christos
2270 1.1 christos while (ea--)
2271 1.1 christos {
2272 1.1 christos rd = GET_MEMORY_B (GET_L_REG (5));
2273 1.1 christos SET_MEMORY_B (GET_L_REG (6), rd);
2274 1.1 christos SET_L_REG (5, GET_L_REG (5) + 1);
2275 1.1 christos SET_L_REG (6, GET_L_REG (6) + 1);
2276 1.1 christos SET_W_REG (4, ea);
2277 1.1 christos }
2278 1.1 christos goto next;
2279 1.1 christos
2280 1.1 christos case O (O_MOVMD, SW): /* movmd.w */
2281 1.1 christos ea = GET_W_REG (4);
2282 1.1 christos if (ea == 0)
2283 1.1 christos ea = 0x10000;
2284 1.1 christos
2285 1.1 christos while (ea--)
2286 1.1 christos {
2287 1.1 christos rd = GET_MEMORY_W (GET_L_REG (5));
2288 1.1 christos SET_MEMORY_W (GET_L_REG (6), rd);
2289 1.1 christos SET_L_REG (5, GET_L_REG (5) + 2);
2290 1.1 christos SET_L_REG (6, GET_L_REG (6) + 2);
2291 1.1 christos SET_W_REG (4, ea);
2292 1.1 christos }
2293 1.1 christos goto next;
2294 1.1 christos
2295 1.1 christos case O (O_MOVMD, SL): /* movmd.l */
2296 1.1 christos ea = GET_W_REG (4);
2297 1.1 christos if (ea == 0)
2298 1.1 christos ea = 0x10000;
2299 1.1 christos
2300 1.1 christos while (ea--)
2301 1.1 christos {
2302 1.1 christos rd = GET_MEMORY_L (GET_L_REG (5));
2303 1.1 christos SET_MEMORY_L (GET_L_REG (6), rd);
2304 1.1 christos SET_L_REG (5, GET_L_REG (5) + 4);
2305 1.1 christos SET_L_REG (6, GET_L_REG (6) + 4);
2306 1.1 christos SET_W_REG (4, ea);
2307 1.1 christos }
2308 1.1 christos goto next;
2309 1.1 christos
2310 1.1 christos case O (O_MOVSD, SB): /* movsd.b */
2311 1.1 christos /* This instruction implements strncpy, with a conditional branch.
2312 1.1 christos r4 contains n, r5 contains src, and r6 contains dst.
2313 1.1 christos The 16-bit displacement operand is added to the pc
2314 1.1 christos if and only if the end of string is reached before
2315 1.1 christos n bytes are transferred. */
2316 1.1 christos
2317 1.1 christos ea = GET_L_REG (4) & 0xffff;
2318 1.1 christos if (ea == 0)
2319 1.1 christos ea = 0x10000;
2320 1.1 christos
2321 1.1 christos while (ea--)
2322 1.1 christos {
2323 1.1 christos rd = GET_MEMORY_B (GET_L_REG (5));
2324 1.1 christos SET_MEMORY_B (GET_L_REG (6), rd);
2325 1.1 christos SET_L_REG (5, GET_L_REG (5) + 1);
2326 1.1 christos SET_L_REG (6, GET_L_REG (6) + 1);
2327 1.1 christos SET_W_REG (4, ea);
2328 1.1 christos if (rd == 0)
2329 1.1 christos goto condtrue;
2330 1.1 christos }
2331 1.1 christos goto next;
2332 1.1 christos
2333 1.1 christos case O (O_EEPMOV, SB): /* eepmov.b */
2334 1.1 christos case O (O_EEPMOV, SW): /* eepmov.w */
2335 1.1 christos if (h8300hmode || h8300smode)
2336 1.1 christos {
2337 1.1 christos register unsigned char *_src, *_dst;
2338 1.1 christos unsigned int count = ((code->opcode == O (O_EEPMOV, SW))
2339 1.1 christos ? h8_get_reg (sd, R4_REGNUM) & 0xffff
2340 1.1 christos : h8_get_reg (sd, R4_REGNUM) & 0xff);
2341 1.1 christos
2342 1.1 christos _src = (h8_get_reg (sd, R5_REGNUM) < memory_size
2343 1.1 christos ? h8_get_memory_buf (sd) + h8_get_reg (sd, R5_REGNUM)
2344 1.1 christos : h8_get_eightbit_buf (sd) +
2345 1.1 christos (h8_get_reg (sd, R5_REGNUM) & 0xff));
2346 1.1 christos if ((_src + count) >= (h8_get_memory_buf (sd) + memory_size))
2347 1.1 christos {
2348 1.1 christos if ((_src + count) >= (h8_get_eightbit_buf (sd) + 0x100))
2349 1.1 christos goto illegal;
2350 1.1 christos }
2351 1.1 christos _dst = (h8_get_reg (sd, R6_REGNUM) < memory_size
2352 1.1 christos ? h8_get_memory_buf (sd) + h8_get_reg (sd, R6_REGNUM)
2353 1.1 christos : h8_get_eightbit_buf (sd) +
2354 1.1 christos (h8_get_reg (sd, R6_REGNUM) & 0xff));
2355 1.1 christos
2356 1.1 christos if ((_dst + count) >= (h8_get_memory_buf (sd) + memory_size))
2357 1.1 christos {
2358 1.1 christos if ((_dst + count) >= (h8_get_eightbit_buf (sd) + 0x100))
2359 1.1 christos goto illegal;
2360 1.1 christos }
2361 1.1 christos memcpy (_dst, _src, count);
2362 1.1 christos
2363 1.1 christos h8_set_reg (sd, R5_REGNUM, h8_get_reg (sd, R5_REGNUM) + count);
2364 1.1 christos h8_set_reg (sd, R6_REGNUM, h8_get_reg (sd, R6_REGNUM) + count);
2365 1.1 christos h8_set_reg (sd, R4_REGNUM, h8_get_reg (sd, R4_REGNUM) &
2366 1.1 christos ((code->opcode == O (O_EEPMOV, SW))
2367 1.1 christos ? (~0xffff) : (~0xff)));
2368 1.1 christos cycles += 2 * count;
2369 1.1 christos goto next;
2370 1.1 christos }
2371 1.1 christos goto illegal;
2372 1.1 christos
2373 1.1 christos case O (O_ADDS, SL): /* adds (.l) */
2374 1.1 christos /* FIXME fetch.
2375 1.1 christos * This insn only uses register operands, but still
2376 1.1 christos * it would be cleaner to use fetch and store... */
2377 1.1 christos SET_L_REG (code->dst.reg,
2378 1.1 christos GET_L_REG (code->dst.reg)
2379 1.1 christos + code->src.literal);
2380 1.1 christos
2381 1.1 christos goto next;
2382 1.1 christos
2383 1.1 christos case O (O_SUBS, SL): /* subs (.l) */
2384 1.1 christos /* FIXME fetch.
2385 1.1 christos * This insn only uses register operands, but still
2386 1.1 christos * it would be cleaner to use fetch and store... */
2387 1.1 christos SET_L_REG (code->dst.reg,
2388 1.1 christos GET_L_REG (code->dst.reg)
2389 1.1 christos - code->src.literal);
2390 1.1 christos goto next;
2391 1.1 christos
2392 1.1 christos case O (O_CMP, SB): /* cmp.b */
2393 1.1 christos if (fetch (sd, &code->dst, &rd))
2394 1.1 christos goto end;
2395 1.1 christos if (fetch (sd, &code->src, &ea))
2396 1.1 christos goto end;
2397 1.1 christos ea = -ea;
2398 1.1 christos res = rd + ea;
2399 1.1 christos goto just_flags_alu8;
2400 1.1 christos
2401 1.1 christos case O (O_CMP, SW): /* cmp.w */
2402 1.1 christos if (fetch (sd, &code->dst, &rd))
2403 1.1 christos goto end;
2404 1.1 christos if (fetch (sd, &code->src, &ea))
2405 1.1 christos goto end;
2406 1.1 christos ea = -ea;
2407 1.1 christos res = rd + ea;
2408 1.1 christos goto just_flags_alu16;
2409 1.1 christos
2410 1.1 christos case O (O_CMP, SL): /* cmp.l */
2411 1.1 christos if (fetch (sd, &code->dst, &rd))
2412 1.1 christos goto end;
2413 1.1 christos if (fetch (sd, &code->src, &ea))
2414 1.1 christos goto end;
2415 1.1 christos ea = -ea;
2416 1.1 christos res = rd + ea;
2417 1.1 christos goto just_flags_alu32;
2418 1.1 christos
2419 1.1 christos case O (O_DEC, SB): /* dec.b */
2420 1.1 christos /* FIXME fetch.
2421 1.1 christos * This insn only uses register operands, but still
2422 1.1 christos * it would be cleaner to use fetch and store... */
2423 1.1 christos rd = GET_B_REG (code->src.reg);
2424 1.1 christos ea = -1;
2425 1.1 christos res = rd + ea;
2426 1.1 christos SET_B_REG (code->src.reg, res);
2427 1.1 christos goto just_flags_inc8;
2428 1.1 christos
2429 1.1 christos case O (O_DEC, SW): /* dec.w */
2430 1.1 christos /* FIXME fetch.
2431 1.1 christos * This insn only uses register operands, but still
2432 1.1 christos * it would be cleaner to use fetch and store... */
2433 1.1 christos rd = GET_W_REG (code->dst.reg);
2434 1.1 christos ea = -code->src.literal;
2435 1.1 christos res = rd + ea;
2436 1.1 christos SET_W_REG (code->dst.reg, res);
2437 1.1 christos goto just_flags_inc16;
2438 1.1 christos
2439 1.1 christos case O (O_DEC, SL): /* dec.l */
2440 1.1 christos /* FIXME fetch.
2441 1.1 christos * This insn only uses register operands, but still
2442 1.1 christos * it would be cleaner to use fetch and store... */
2443 1.1 christos rd = GET_L_REG (code->dst.reg);
2444 1.1 christos ea = -code->src.literal;
2445 1.1 christos res = rd + ea;
2446 1.1 christos SET_L_REG (code->dst.reg, res);
2447 1.1 christos goto just_flags_inc32;
2448 1.1 christos
2449 1.1 christos case O (O_INC, SB): /* inc.b */
2450 1.1 christos /* FIXME fetch.
2451 1.1 christos * This insn only uses register operands, but still
2452 1.1 christos * it would be cleaner to use fetch and store... */
2453 1.1 christos rd = GET_B_REG (code->src.reg);
2454 1.1 christos ea = 1;
2455 1.1 christos res = rd + ea;
2456 1.1 christos SET_B_REG (code->src.reg, res);
2457 1.1 christos goto just_flags_inc8;
2458 1.1 christos
2459 1.1 christos case O (O_INC, SW): /* inc.w */
2460 1.1 christos /* FIXME fetch.
2461 1.1 christos * This insn only uses register operands, but still
2462 1.1 christos * it would be cleaner to use fetch and store... */
2463 1.1 christos rd = GET_W_REG (code->dst.reg);
2464 1.1 christos ea = code->src.literal;
2465 1.1 christos res = rd + ea;
2466 1.1 christos SET_W_REG (code->dst.reg, res);
2467 1.1 christos goto just_flags_inc16;
2468 1.1 christos
2469 1.1 christos case O (O_INC, SL): /* inc.l */
2470 1.1 christos /* FIXME fetch.
2471 1.1 christos * This insn only uses register operands, but still
2472 1.1 christos * it would be cleaner to use fetch and store... */
2473 1.1 christos rd = GET_L_REG (code->dst.reg);
2474 1.1 christos ea = code->src.literal;
2475 1.1 christos res = rd + ea;
2476 1.1 christos SET_L_REG (code->dst.reg, res);
2477 1.1 christos goto just_flags_inc32;
2478 1.1 christos
2479 1.1 christos case O (O_LDC, SB): /* ldc.b */
2480 1.1 christos if (fetch (sd, &code->src, &res))
2481 1.1 christos goto end;
2482 1.1 christos goto setc;
2483 1.1 christos
2484 1.1 christos case O (O_LDC, SW): /* ldc.w */
2485 1.1 christos if (fetch (sd, &code->src, &res))
2486 1.1 christos goto end;
2487 1.1 christos
2488 1.1 christos /* Word operand, value from MSB, must be shifted. */
2489 1.1 christos res >>= 8;
2490 1.1 christos goto setc;
2491 1.1 christos
2492 1.1 christos case O (O_LDC, SL): /* ldc.l */
2493 1.1 christos if (fetch (sd, &code->src, &res))
2494 1.1 christos goto end;
2495 1.1 christos switch (code->dst.type) {
2496 1.1 christos case X (OP_SBR, SL):
2497 1.1 christos h8_set_sbr (sd, res);
2498 1.1 christos break;
2499 1.1 christos case X (OP_VBR, SL):
2500 1.1 christos h8_set_vbr (sd, res);
2501 1.1 christos break;
2502 1.1 christos default:
2503 1.1 christos goto illegal;
2504 1.1 christos }
2505 1.1 christos goto next;
2506 1.1 christos
2507 1.1 christos case O (O_STC, SW): /* stc.w */
2508 1.1 christos case O (O_STC, SB): /* stc.b */
2509 1.1 christos if (code->src.type == X (OP_CCR, SB))
2510 1.1 christos {
2511 1.1 christos BUILDSR (sd);
2512 1.1 christos res = h8_get_ccr (sd);
2513 1.1 christos }
2514 1.1 christos else if (code->src.type == X (OP_EXR, SB) && h8300smode)
2515 1.1 christos {
2516 1.1 christos if (h8300smode)
2517 1.1 christos h8_set_exr (sd, (trace << 7) | intMask);
2518 1.1 christos res = h8_get_exr (sd);
2519 1.1 christos }
2520 1.1 christos else
2521 1.1 christos goto illegal;
2522 1.1 christos
2523 1.1 christos /* Word operand, value to MSB, must be shifted. */
2524 1.1 christos if (code->opcode == X (O_STC, SW))
2525 1.1 christos res <<= 8;
2526 1.1 christos if (store (sd, &code->dst, res))
2527 1.1 christos goto end;
2528 1.1 christos goto next;
2529 1.1 christos case O (O_STC, SL): /* stc.l */
2530 1.1 christos switch (code->src.type) {
2531 1.1 christos case X (OP_SBR, SL):
2532 1.1 christos res = h8_get_sbr (sd);
2533 1.1 christos break;
2534 1.1 christos case X (OP_VBR, SL):
2535 1.1 christos res = h8_get_vbr (sd);
2536 1.1 christos break;
2537 1.1 christos default:
2538 1.1 christos goto illegal;
2539 1.1 christos }
2540 1.1 christos if (store (sd, &code->dst, res))
2541 1.1 christos goto end;
2542 1.1 christos goto next;
2543 1.1 christos
2544 1.1 christos case O (O_ANDC, SB): /* andc.b */
2545 1.1 christos if (code->dst.type == X (OP_CCR, SB))
2546 1.1 christos {
2547 1.1 christos BUILDSR (sd);
2548 1.1 christos rd = h8_get_ccr (sd);
2549 1.1 christos }
2550 1.1 christos else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2551 1.1 christos {
2552 1.1 christos if (h8300smode)
2553 1.1 christos h8_set_exr (sd, (trace << 7) | intMask);
2554 1.1 christos rd = h8_get_exr (sd);
2555 1.1 christos }
2556 1.1 christos else
2557 1.1 christos goto illegal;
2558 1.1 christos ea = code->src.literal;
2559 1.1 christos res = rd & ea;
2560 1.1 christos goto setc;
2561 1.1 christos
2562 1.1 christos case O (O_ORC, SB): /* orc.b */
2563 1.1 christos if (code->dst.type == X (OP_CCR, SB))
2564 1.1 christos {
2565 1.1 christos BUILDSR (sd);
2566 1.1 christos rd = h8_get_ccr (sd);
2567 1.1 christos }
2568 1.1 christos else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2569 1.1 christos {
2570 1.1 christos if (h8300smode)
2571 1.1 christos h8_set_exr (sd, (trace << 7) | intMask);
2572 1.1 christos rd = h8_get_exr (sd);
2573 1.1 christos }
2574 1.1 christos else
2575 1.1 christos goto illegal;
2576 1.1 christos ea = code->src.literal;
2577 1.1 christos res = rd | ea;
2578 1.1 christos goto setc;
2579 1.1 christos
2580 1.1 christos case O (O_XORC, SB): /* xorc.b */
2581 1.1 christos if (code->dst.type == X (OP_CCR, SB))
2582 1.1 christos {
2583 1.1 christos BUILDSR (sd);
2584 1.1 christos rd = h8_get_ccr (sd);
2585 1.1 christos }
2586 1.1 christos else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2587 1.1 christos {
2588 1.1 christos if (h8300smode)
2589 1.1 christos h8_set_exr (sd, (trace << 7) | intMask);
2590 1.1 christos rd = h8_get_exr (sd);
2591 1.1 christos }
2592 1.1 christos else
2593 1.1 christos goto illegal;
2594 1.1 christos ea = code->src.literal;
2595 1.1 christos res = rd ^ ea;
2596 1.1 christos goto setc;
2597 1.1 christos
2598 1.1 christos case O (O_BRAS, SB): /* bra/s */
2599 1.1 christos /* This is basically an ordinary branch, with a delay slot. */
2600 1.1 christos if (fetch (sd, &code->src, &res))
2601 1.1 christos goto end;
2602 1.1 christos
2603 1.1 christos if ((res & 1) == 0)
2604 1.1 christos goto illegal;
2605 1.1 christos
2606 1.1 christos res -= 1;
2607 1.1 christos
2608 1.1 christos /* Execution continues at next instruction, but
2609 1.1 christos delayed_branch is set up for next cycle. */
2610 1.1 christos h8_set_delayed_branch (sd, code->next_pc + res);
2611 1.1 christos pc = code->next_pc;
2612 1.1 christos goto end;
2613 1.1 christos
2614 1.1 christos case O (O_BRAB, SB): /* bra rd.b */
2615 1.1 christos case O (O_BRAW, SW): /* bra rd.w */
2616 1.1 christos case O (O_BRAL, SL): /* bra erd.l */
2617 1.1 christos if (fetch (sd, &code->src, &rd))
2618 1.1 christos goto end;
2619 1.1 christos switch (OP_SIZE (code->opcode)) {
2620 1.1 christos case SB: rd &= 0xff; break;
2621 1.1 christos case SW: rd &= 0xffff; break;
2622 1.1 christos case SL: rd &= 0xffffffff; break;
2623 1.1 christos }
2624 1.1 christos pc = code->next_pc + rd;
2625 1.1 christos goto end;
2626 1.1 christos
2627 1.1 christos case O (O_BRABC, SB): /* bra/bc, branch if bit clear */
2628 1.1 christos case O (O_BRABS, SB): /* bra/bs, branch if bit set */
2629 1.1 christos case O (O_BSRBC, SB): /* bsr/bc, call if bit clear */
2630 1.1 christos case O (O_BSRBS, SB): /* bsr/bs, call if bit set */
2631 1.1 christos if (fetch (sd, &code->dst, &rd) ||
2632 1.1 christos fetch (sd, &code->src, &bit))
2633 1.1 christos goto end;
2634 1.1 christos
2635 1.1 christos if (code->opcode == O (O_BRABC, SB) || /* branch if clear */
2636 1.1 christos code->opcode == O (O_BSRBC, SB)) /* call if clear */
2637 1.1 christos {
2638 1.1 christos if ((rd & (1 << bit))) /* no branch */
2639 1.1 christos goto next;
2640 1.1 christos }
2641 1.1 christos else /* branch/call if set */
2642 1.1 christos {
2643 1.1 christos if (!(rd & (1 << bit))) /* no branch */
2644 1.1 christos goto next;
2645 1.1 christos }
2646 1.1 christos
2647 1.1 christos if (fetch (sd, &code->op3, &res)) /* branch */
2648 1.1 christos goto end;
2649 1.1 christos pc = code->next_pc + res;
2650 1.1 christos
2651 1.1 christos if (code->opcode == O (O_BRABC, SB) ||
2652 1.1 christos code->opcode == O (O_BRABS, SB)) /* branch */
2653 1.1 christos goto end;
2654 1.1 christos else /* call */
2655 1.1 christos goto call;
2656 1.1 christos
2657 1.1 christos case O (O_BRA, SN):
2658 1.1 christos case O (O_BRA, SL):
2659 1.1 christos case O (O_BRA, SW):
2660 1.1 christos case O (O_BRA, SB): /* bra, branch always */
2661 1.1 christos if (1)
2662 1.1 christos goto condtrue;
2663 1.1 christos goto next;
2664 1.1 christos
2665 1.1 christos case O (O_BRN, SB): /* brn, ;-/ branch never? */
2666 1.1 christos if (0)
2667 1.1 christos goto condtrue;
2668 1.1 christos goto next;
2669 1.1 christos
2670 1.1 christos case O (O_BHI, SB): /* bhi */
2671 1.1 christos if ((C || Z) == 0)
2672 1.1 christos goto condtrue;
2673 1.1 christos goto next;
2674 1.1 christos
2675 1.1 christos
2676 1.1 christos case O (O_BLS, SB): /* bls */
2677 1.1 christos if ((C || Z))
2678 1.1 christos goto condtrue;
2679 1.1 christos goto next;
2680 1.1 christos
2681 1.1 christos case O (O_BCS, SB): /* bcs, branch if carry set */
2682 1.1 christos if ((C == 1))
2683 1.1 christos goto condtrue;
2684 1.1 christos goto next;
2685 1.1 christos
2686 1.1 christos case O (O_BCC, SB): /* bcc, branch if carry clear */
2687 1.1 christos if ((C == 0))
2688 1.1 christos goto condtrue;
2689 1.1 christos goto next;
2690 1.1 christos
2691 1.1 christos case O (O_BEQ, SB): /* beq, branch if zero set */
2692 1.1 christos if (Z)
2693 1.1 christos goto condtrue;
2694 1.1 christos goto next;
2695 1.1 christos case O (O_BGT, SB): /* bgt */
2696 1.1 christos if (((Z || (N ^ V)) == 0))
2697 1.1 christos goto condtrue;
2698 1.1 christos goto next;
2699 1.1 christos
2700 1.1 christos case O (O_BLE, SB): /* ble */
2701 1.1 christos if (((Z || (N ^ V)) == 1))
2702 1.1 christos goto condtrue;
2703 1.1 christos goto next;
2704 1.1 christos
2705 1.1 christos case O (O_BGE, SB): /* bge */
2706 1.1 christos if ((N ^ V) == 0)
2707 1.1 christos goto condtrue;
2708 1.1 christos goto next;
2709 1.1 christos case O (O_BLT, SB): /* blt */
2710 1.1 christos if ((N ^ V))
2711 1.1 christos goto condtrue;
2712 1.1 christos goto next;
2713 1.1 christos case O (O_BMI, SB): /* bmi */
2714 1.1 christos if ((N))
2715 1.1 christos goto condtrue;
2716 1.1 christos goto next;
2717 1.1 christos case O (O_BNE, SB): /* bne, branch if zero clear */
2718 1.1 christos if ((Z == 0))
2719 1.1 christos goto condtrue;
2720 1.1 christos goto next;
2721 1.1 christos
2722 1.1 christos case O (O_BPL, SB): /* bpl */
2723 1.1 christos if (N == 0)
2724 1.1 christos goto condtrue;
2725 1.1 christos goto next;
2726 1.1 christos case O (O_BVC, SB): /* bvc */
2727 1.1 christos if ((V == 0))
2728 1.1 christos goto condtrue;
2729 1.1 christos goto next;
2730 1.1 christos case O (O_BVS, SB): /* bvs */
2731 1.1 christos if ((V == 1))
2732 1.1 christos goto condtrue;
2733 1.1 christos goto next;
2734 1.1 christos
2735 1.1 christos /* Trap for Command Line setup. */
2736 1.1 christos case O (O_SYS_CMDLINE, SB):
2737 1.1 christos {
2738 1.1 christos int i = 0; /* Loop counter. */
2739 1.1 christos int j = 0; /* Loop counter. */
2740 1.1 christos int ind_arg_len = 0; /* Length of each argument. */
2741 1.1 christos int no_of_args = 0; /* The no. or cmdline args. */
2742 1.1 christos int current_location = 0; /* Location of string. */
2743 1.1 christos int old_sp = 0; /* The Initial Stack Pointer. */
2744 1.1 christos int no_of_slots = 0; /* No. of slots required on the stack
2745 1.1 christos for storing cmdline args. */
2746 1.1 christos int sp_move = 0; /* No. of locations by which the stack needs
2747 1.1 christos to grow. */
2748 1.1 christos int new_sp = 0; /* The final stack pointer location passed
2749 1.1 christos back. */
2750 1.1 christos int *argv_ptrs; /* Pointers of argv strings to be stored. */
2751 1.1 christos int argv_ptrs_location = 0; /* Location of pointers to cmdline
2752 1.1 christos args on the stack. */
2753 1.1 christos int char_ptr_size = 0; /* Size of a character pointer on
2754 1.1 christos target machine. */
2755 1.1 christos int addr_cmdline = 0; /* Memory location where cmdline has
2756 1.1 christos to be stored. */
2757 1.1 christos int size_cmdline = 0; /* Size of cmdline. */
2758 1.1 christos
2759 1.1 christos /* Set the address of 256 free locations where command line is
2760 1.1 christos stored. */
2761 1.1 christos addr_cmdline = cmdline_location();
2762 1.1 christos h8_set_reg (sd, 0, addr_cmdline);
2763 1.1 christos
2764 1.1 christos /* Counting the no. of commandline arguments. */
2765 1.1 christos for (i = 0; h8_get_cmdline_arg (sd, i) != NULL; i++)
2766 1.1 christos continue;
2767 1.1 christos
2768 1.1 christos /* No. of arguments in the command line. */
2769 1.1 christos no_of_args = i;
2770 1.1 christos
2771 1.1 christos /* Current location is just a temporary variable,which we are
2772 1.1 christos setting to the point to the start of our commandline string. */
2773 1.1 christos current_location = addr_cmdline;
2774 1.1 christos
2775 1.1 christos /* Allocating space for storing pointers of the command line
2776 1.1 christos arguments. */
2777 1.1 christos argv_ptrs = (int *) malloc (sizeof (int) * no_of_args);
2778 1.1 christos
2779 1.1 christos /* Setting char_ptr_size to the sizeof (char *) on the different
2780 1.1 christos architectures. */
2781 1.1 christos if ((h8300hmode || h8300smode) && !h8300_normal_mode)
2782 1.1 christos {
2783 1.1 christos char_ptr_size = 4;
2784 1.1 christos }
2785 1.1 christos else
2786 1.1 christos {
2787 1.1 christos char_ptr_size = 2;
2788 1.1 christos }
2789 1.1 christos
2790 1.1 christos for (i = 0; i < no_of_args; i++)
2791 1.1 christos {
2792 1.1 christos ind_arg_len = 0;
2793 1.1 christos
2794 1.1 christos /* The size of the commandline argument. */
2795 1.1 christos ind_arg_len = strlen (h8_get_cmdline_arg (sd, i)) + 1;
2796 1.1 christos
2797 1.1 christos /* The total size of the command line string. */
2798 1.1 christos size_cmdline += ind_arg_len;
2799 1.1 christos
2800 1.1 christos /* As we have only 256 bytes, we need to provide a graceful
2801 1.1 christos exit. Anyways, a program using command line arguments
2802 1.1 christos where we cannot store all the command line arguments
2803 1.1 christos given may behave unpredictably. */
2804 1.1 christos if (size_cmdline >= 256)
2805 1.1 christos {
2806 1.1 christos h8_set_reg (sd, 0, 0);
2807 1.1 christos goto next;
2808 1.1 christos }
2809 1.1 christos else
2810 1.1 christos {
2811 1.1 christos /* current_location points to the memory where the next
2812 1.1 christos commandline argument is stored. */
2813 1.1 christos argv_ptrs[i] = current_location;
2814 1.1 christos for (j = 0; j < ind_arg_len; j++)
2815 1.1 christos {
2816 1.1 christos SET_MEMORY_B ((current_location +
2817 1.1 christos (sizeof (char) * j)),
2818 1.1 christos *(h8_get_cmdline_arg (sd, i) +
2819 1.1 christos sizeof (char) * j));
2820 1.1 christos }
2821 1.1 christos
2822 1.1 christos /* Setting current_location to the starting of next
2823 1.1 christos argument. */
2824 1.1 christos current_location += ind_arg_len;
2825 1.1 christos }
2826 1.1 christos }
2827 1.1 christos
2828 1.1 christos /* This is the original position of the stack pointer. */
2829 1.1 christos old_sp = h8_get_reg (sd, SP_REGNUM);
2830 1.1 christos
2831 1.1 christos /* We need space from the stack to store the pointers to argvs. */
2832 1.1 christos /* As we will infringe on the stack, we need to shift the stack
2833 1.1 christos pointer so that the data is not overwritten. We calculate how
2834 1.1 christos much space is required. */
2835 1.1 christos sp_move = (no_of_args) * (char_ptr_size);
2836 1.1 christos
2837 1.1 christos /* The final position of stack pointer, we have thus taken some
2838 1.1 christos space from the stack. */
2839 1.1 christos new_sp = old_sp - sp_move;
2840 1.1 christos
2841 1.1 christos /* Temporary variable holding value where the argv pointers need
2842 1.1 christos to be stored. */
2843 1.1 christos argv_ptrs_location = new_sp;
2844 1.1 christos
2845 1.1 christos /* The argv pointers are stored at sequential locations. As per
2846 1.1 christos the H8300 ABI. */
2847 1.1 christos for (i = 0; i < no_of_args; i++)
2848 1.1 christos {
2849 1.1 christos /* Saving the argv pointer. */
2850 1.1 christos if ((h8300hmode || h8300smode) && !h8300_normal_mode)
2851 1.1 christos {
2852 1.1 christos SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]);
2853 1.1 christos }
2854 1.1 christos else
2855 1.1 christos {
2856 1.1 christos SET_MEMORY_W (argv_ptrs_location, argv_ptrs[i]);
2857 1.1 christos }
2858 1.1 christos
2859 1.1 christos /* The next location where the pointer to the next argv
2860 1.1 christos string has to be stored. */
2861 1.1 christos argv_ptrs_location += char_ptr_size;
2862 1.1 christos }
2863 1.1 christos
2864 1.1 christos /* Required by POSIX, Setting 0x0 at the end of the list of argv
2865 1.1 christos pointers. */
2866 1.1 christos if ((h8300hmode || h8300smode) && !h8300_normal_mode)
2867 1.1 christos {
2868 1.1 christos SET_MEMORY_L (old_sp, 0x0);
2869 1.1 christos }
2870 1.1 christos else
2871 1.1 christos {
2872 1.1 christos SET_MEMORY_W (old_sp, 0x0);
2873 1.1 christos }
2874 1.1 christos
2875 1.1 christos /* Freeing allocated memory. */
2876 1.1 christos free (argv_ptrs);
2877 1.1 christos for (i = 0; i <= no_of_args; i++)
2878 1.1 christos {
2879 1.1 christos free (h8_get_cmdline_arg (sd, i));
2880 1.1 christos }
2881 1.1 christos free (h8_get_command_line (sd));
2882 1.1 christos
2883 1.1 christos /* The no. of argv arguments are returned in Reg 0. */
2884 1.1 christos h8_set_reg (sd, 0, no_of_args);
2885 1.1 christos /* The Pointer to argv in Register 1. */
2886 1.1 christos h8_set_reg (sd, 1, new_sp);
2887 1.1 christos /* Setting the stack pointer to the new value. */
2888 1.1 christos h8_set_reg (sd, SP_REGNUM, new_sp);
2889 1.1 christos }
2890 1.1 christos goto next;
2891 1.1 christos
2892 1.1 christos /* System call processing starts. */
2893 1.1 christos case O (O_SYS_OPEN, SB):
2894 1.1 christos {
2895 1.1 christos int len = 0; /* Length of filename. */
2896 1.1 christos char *filename; /* Filename would go here. */
2897 1.1 christos char temp_char; /* Temporary character */
2898 1.1 christos int mode = 0; /* Mode bits for the file. */
2899 1.1 christos int open_return; /* Return value of open, file descriptor. */
2900 1.1 christos int i; /* Loop counter */
2901 1.1 christos int filename_ptr; /* Pointer to filename in cpu memory. */
2902 1.1 christos
2903 1.1 christos /* Setting filename_ptr to first argument of open, */
2904 1.1 christos /* and trying to get mode. */
2905 1.1 christos if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode)
2906 1.1 christos {
2907 1.1 christos filename_ptr = GET_L_REG (0);
2908 1.1 christos mode = GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM) + 4);
2909 1.1 christos }
2910 1.1 christos else
2911 1.1 christos {
2912 1.1 christos filename_ptr = GET_W_REG (0);
2913 1.1 christos mode = GET_MEMORY_W (h8_get_reg (sd, SP_REGNUM) + 2);
2914 1.1 christos }
2915 1.1 christos
2916 1.1 christos /* Trying to find the length of the filename. */
2917 1.1 christos temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
2918 1.1 christos
2919 1.1 christos len = 1;
2920 1.1 christos while (temp_char != '\0')
2921 1.1 christos {
2922 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + len);
2923 1.1 christos len++;
2924 1.1 christos }
2925 1.1 christos
2926 1.1 christos /* Allocating space for the filename. */
2927 1.1 christos filename = (char *) malloc (sizeof (char) * len);
2928 1.1 christos
2929 1.1 christos /* String copying the filename from memory. */
2930 1.1 christos for (i = 0; i < len; i++)
2931 1.1 christos {
2932 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + i);
2933 1.1 christos filename[i] = temp_char;
2934 1.1 christos }
2935 1.1 christos
2936 1.1 christos /* Callback to open and return the file descriptor. */
2937 1.1 christos open_return = sim_callback->open (sim_callback, filename, mode);
2938 1.1 christos
2939 1.1 christos /* Return value in register 0. */
2940 1.1 christos h8_set_reg (sd, 0, open_return);
2941 1.1 christos
2942 1.1 christos /* Freeing memory used for filename. */
2943 1.1 christos free (filename);
2944 1.1 christos }
2945 1.1 christos goto next;
2946 1.1 christos
2947 1.1 christos case O (O_SYS_READ, SB):
2948 1.1 christos {
2949 1.1 christos char *char_ptr; /* Where characters read would be stored. */
2950 1.1 christos int fd; /* File descriptor */
2951 1.1 christos int buf_size; /* BUF_SIZE parameter in read. */
2952 1.1 christos int i = 0; /* Temporary Loop counter */
2953 1.1 christos int read_return = 0; /* Return value from callback to
2954 1.1 christos read. */
2955 1.1 christos
2956 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2957 1.1 christos buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
2958 1.1 christos
2959 1.1 christos char_ptr = (char *) malloc (sizeof (char) * buf_size);
2960 1.1 christos
2961 1.1 christos /* Callback to read and return the no. of characters read. */
2962 1.1 christos read_return =
2963 1.1 christos sim_callback->read (sim_callback, fd, char_ptr, buf_size);
2964 1.1 christos
2965 1.1 christos /* The characters read are stored in cpu memory. */
2966 1.1 christos for (i = 0; i < buf_size; i++)
2967 1.1 christos {
2968 1.1 christos SET_MEMORY_B ((h8_get_reg (sd, 1) + (sizeof (char) * i)),
2969 1.1 christos *(char_ptr + (sizeof (char) * i)));
2970 1.1 christos }
2971 1.1 christos
2972 1.1 christos /* Return value in Register 0. */
2973 1.1 christos h8_set_reg (sd, 0, read_return);
2974 1.1 christos
2975 1.1 christos /* Freeing memory used as buffer. */
2976 1.1 christos free (char_ptr);
2977 1.1 christos }
2978 1.1 christos goto next;
2979 1.1 christos
2980 1.1 christos case O (O_SYS_WRITE, SB):
2981 1.1 christos {
2982 1.1 christos int fd; /* File descriptor */
2983 1.1 christos char temp_char; /* Temporary character */
2984 1.1 christos int len; /* Length of write, Parameter II to write. */
2985 1.1 christos int char_ptr; /* Character Pointer, Parameter I of write. */
2986 1.1 christos char *ptr; /* Where characters to be written are stored.
2987 1.1 christos */
2988 1.1 christos int write_return; /* Return value from callback to write. */
2989 1.1 christos int i = 0; /* Loop counter */
2990 1.1 christos
2991 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2992 1.1 christos char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
2993 1.1 christos len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
2994 1.1 christos
2995 1.1 christos /* Allocating space for the characters to be written. */
2996 1.1 christos ptr = (char *) malloc (sizeof (char) * len);
2997 1.1 christos
2998 1.1 christos /* Fetching the characters from cpu memory. */
2999 1.1 christos for (i = 0; i < len; i++)
3000 1.1 christos {
3001 1.1 christos temp_char = GET_MEMORY_B (char_ptr + i);
3002 1.1 christos ptr[i] = temp_char;
3003 1.1 christos }
3004 1.1 christos
3005 1.1 christos /* Callback write and return the no. of characters written. */
3006 1.1 christos write_return = sim_callback->write (sim_callback, fd, ptr, len);
3007 1.1 christos
3008 1.1 christos /* Return value in Register 0. */
3009 1.1 christos h8_set_reg (sd, 0, write_return);
3010 1.1 christos
3011 1.1 christos /* Freeing memory used as buffer. */
3012 1.1 christos free (ptr);
3013 1.1 christos }
3014 1.1 christos goto next;
3015 1.1 christos
3016 1.1 christos case O (O_SYS_LSEEK, SB):
3017 1.1 christos {
3018 1.1 christos int fd; /* File descriptor */
3019 1.1 christos int offset; /* Offset */
3020 1.1 christos int origin; /* Origin */
3021 1.1 christos int lseek_return; /* Return value from callback to lseek. */
3022 1.1 christos
3023 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
3024 1.1 christos offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
3025 1.1 christos origin = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
3026 1.1 christos
3027 1.1 christos /* Callback lseek and return offset. */
3028 1.1 christos lseek_return =
3029 1.1 christos sim_callback->lseek (sim_callback, fd, offset, origin);
3030 1.1 christos
3031 1.1 christos /* Return value in register 0. */
3032 1.1 christos h8_set_reg (sd, 0, lseek_return);
3033 1.1 christos }
3034 1.1 christos goto next;
3035 1.1 christos
3036 1.1 christos case O (O_SYS_CLOSE, SB):
3037 1.1 christos {
3038 1.1 christos int fd; /* File descriptor */
3039 1.1 christos int close_return; /* Return value from callback to close. */
3040 1.1 christos
3041 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
3042 1.1 christos
3043 1.1 christos /* Callback close and return. */
3044 1.1 christos close_return = sim_callback->close (sim_callback, fd);
3045 1.1 christos
3046 1.1 christos /* Return value in register 0. */
3047 1.1 christos h8_set_reg (sd, 0, close_return);
3048 1.1 christos }
3049 1.1 christos goto next;
3050 1.1 christos
3051 1.1 christos case O (O_SYS_FSTAT, SB):
3052 1.1 christos {
3053 1.1 christos int fd; /* File descriptor */
3054 1.1 christos struct stat stat_rec; /* Stat record */
3055 1.1 christos int fstat_return; /* Return value from callback to stat. */
3056 1.1 christos int stat_ptr; /* Pointer to stat record. */
3057 1.1 christos char *temp_stat_ptr; /* Temporary stat_rec pointer. */
3058 1.1 christos
3059 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
3060 1.1 christos
3061 1.1 christos /* Setting stat_ptr to second argument of stat. */
3062 1.1 christos stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
3063 1.1 christos
3064 1.1 christos /* Callback stat and return. */
3065 1.1.1.2 christos fstat_return = sim_callback->to_fstat (sim_callback, fd,
3066 1.1.1.2 christos &stat_rec);
3067 1.1 christos
3068 1.1 christos /* Have stat_ptr point to starting of stat_rec. */
3069 1.1 christos temp_stat_ptr = (char *) (&stat_rec);
3070 1.1 christos
3071 1.1 christos /* Setting up the stat structure returned. */
3072 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
3073 1.1 christos stat_ptr += 2;
3074 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
3075 1.1 christos stat_ptr += 2;
3076 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
3077 1.1 christos stat_ptr += 4;
3078 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
3079 1.1 christos stat_ptr += 2;
3080 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
3081 1.1 christos stat_ptr += 2;
3082 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
3083 1.1 christos stat_ptr += 2;
3084 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
3085 1.1 christos stat_ptr += 2;
3086 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_size);
3087 1.1 christos stat_ptr += 4;
3088 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
3089 1.1 christos stat_ptr += 8;
3090 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
3091 1.1 christos stat_ptr += 8;
3092 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
3093 1.1 christos
3094 1.1 christos /* Return value in register 0. */
3095 1.1 christos h8_set_reg (sd, 0, fstat_return);
3096 1.1 christos }
3097 1.1 christos goto next;
3098 1.1 christos
3099 1.1 christos case O (O_SYS_STAT, SB):
3100 1.1 christos {
3101 1.1 christos int len = 0; /* Length of filename. */
3102 1.1 christos char *filename; /* Filename would go here. */
3103 1.1 christos char temp_char; /* Temporary character */
3104 1.1 christos int filename_ptr; /* Pointer to filename in cpu memory. */
3105 1.1 christos struct stat stat_rec; /* Stat record */
3106 1.1 christos int stat_return; /* Return value from callback to stat */
3107 1.1 christos int stat_ptr; /* Pointer to stat record. */
3108 1.1 christos char *temp_stat_ptr; /* Temporary stat_rec pointer. */
3109 1.1 christos int i = 0; /* Loop Counter */
3110 1.1 christos
3111 1.1 christos /* Setting filename_ptr to first argument of open. */
3112 1.1 christos filename_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
3113 1.1 christos
3114 1.1 christos /* Trying to find the length of the filename. */
3115 1.1 christos temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
3116 1.1 christos
3117 1.1 christos len = 1;
3118 1.1 christos while (temp_char != '\0')
3119 1.1 christos {
3120 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + len);
3121 1.1 christos len++;
3122 1.1 christos }
3123 1.1 christos
3124 1.1 christos /* Allocating space for the filename. */
3125 1.1 christos filename = (char *) malloc (sizeof (char) * len);
3126 1.1 christos
3127 1.1 christos /* String copying the filename from memory. */
3128 1.1 christos for (i = 0; i < len; i++)
3129 1.1 christos {
3130 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + i);
3131 1.1 christos filename[i] = temp_char;
3132 1.1 christos }
3133 1.1 christos
3134 1.1 christos /* Setting stat_ptr to second argument of stat. */
3135 1.1 christos /* stat_ptr = h8_get_reg (sd, 1); */
3136 1.1 christos stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
3137 1.1 christos
3138 1.1 christos /* Callback stat and return. */
3139 1.1 christos stat_return =
3140 1.1.1.2 christos sim_callback->to_stat (sim_callback, filename, &stat_rec);
3141 1.1 christos
3142 1.1 christos /* Have stat_ptr point to starting of stat_rec. */
3143 1.1 christos temp_stat_ptr = (char *) (&stat_rec);
3144 1.1 christos
3145 1.1 christos /* Freeing memory used for filename. */
3146 1.1 christos free (filename);
3147 1.1 christos
3148 1.1 christos /* Setting up the stat structure returned. */
3149 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
3150 1.1 christos stat_ptr += 2;
3151 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
3152 1.1 christos stat_ptr += 2;
3153 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
3154 1.1 christos stat_ptr += 4;
3155 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
3156 1.1 christos stat_ptr += 2;
3157 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
3158 1.1 christos stat_ptr += 2;
3159 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
3160 1.1 christos stat_ptr += 2;
3161 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
3162 1.1 christos stat_ptr += 2;
3163 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_size);
3164 1.1 christos stat_ptr += 4;
3165 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
3166 1.1 christos stat_ptr += 8;
3167 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
3168 1.1 christos stat_ptr += 8;
3169 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
3170 1.1 christos
3171 1.1 christos /* Return value in register 0. */
3172 1.1 christos h8_set_reg (sd, 0, stat_return);
3173 1.1 christos }
3174 1.1 christos goto next;
3175 1.1 christos /* End of system call processing. */
3176 1.1 christos
3177 1.1 christos case O (O_NOT, SB): /* not.b */
3178 1.1 christos if (fetch2 (sd, &code->src, &rd))
3179 1.1 christos goto end;
3180 1.1 christos rd = ~rd;
3181 1.1 christos v = 0;
3182 1.1 christos goto shift8;
3183 1.1 christos
3184 1.1 christos case O (O_NOT, SW): /* not.w */
3185 1.1 christos if (fetch2 (sd, &code->src, &rd))
3186 1.1 christos goto end;
3187 1.1 christos rd = ~rd;
3188 1.1 christos v = 0;
3189 1.1 christos goto shift16;
3190 1.1 christos
3191 1.1 christos case O (O_NOT, SL): /* not.l */
3192 1.1 christos if (fetch2 (sd, &code->src, &rd))
3193 1.1 christos goto end;
3194 1.1 christos rd = ~rd;
3195 1.1 christos v = 0;
3196 1.1 christos goto shift32;
3197 1.1 christos
3198 1.1 christos case O (O_SHLL, SB): /* shll.b */
3199 1.1 christos case O (O_SHLR, SB): /* shlr.b */
3200 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3201 1.1 christos goto end;
3202 1.1 christos
3203 1.1 christos if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3204 1.1 christos ea = 1; /* unary op */
3205 1.1 christos else /* binary op */
3206 1.1 christos fetch (sd, &code->src, &ea);
3207 1.1 christos
3208 1.1 christos if (code->opcode == O (O_SHLL, SB))
3209 1.1 christos {
3210 1.1 christos v = (ea > 8);
3211 1.1 christos c = rd & (0x80 >> (ea - 1));
3212 1.1 christos rd <<= ea;
3213 1.1 christos }
3214 1.1 christos else
3215 1.1 christos {
3216 1.1 christos v = 0;
3217 1.1 christos c = rd & (1 << (ea - 1));
3218 1.1 christos rd = (unsigned char) rd >> ea;
3219 1.1 christos }
3220 1.1 christos goto shift8;
3221 1.1 christos
3222 1.1 christos case O (O_SHLL, SW): /* shll.w */
3223 1.1 christos case O (O_SHLR, SW): /* shlr.w */
3224 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3225 1.1 christos goto end;
3226 1.1 christos
3227 1.1 christos if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3228 1.1 christos ea = 1; /* unary op */
3229 1.1 christos else
3230 1.1 christos fetch (sd, &code->src, &ea);
3231 1.1 christos
3232 1.1 christos if (code->opcode == O (O_SHLL, SW))
3233 1.1 christos {
3234 1.1 christos v = (ea > 16);
3235 1.1 christos c = rd & (0x8000 >> (ea - 1));
3236 1.1 christos rd <<= ea;
3237 1.1 christos }
3238 1.1 christos else
3239 1.1 christos {
3240 1.1 christos v = 0;
3241 1.1 christos c = rd & (1 << (ea - 1));
3242 1.1 christos rd = (unsigned short) rd >> ea;
3243 1.1 christos }
3244 1.1 christos goto shift16;
3245 1.1 christos
3246 1.1 christos case O (O_SHLL, SL): /* shll.l */
3247 1.1 christos case O (O_SHLR, SL): /* shlr.l */
3248 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3249 1.1 christos goto end;
3250 1.1 christos
3251 1.1 christos if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3252 1.1 christos ea = 1; /* unary op */
3253 1.1 christos else
3254 1.1 christos fetch (sd, &code->src, &ea);
3255 1.1 christos
3256 1.1 christos if (code->opcode == O (O_SHLL, SL))
3257 1.1 christos {
3258 1.1 christos v = (ea > 32);
3259 1.1 christos c = rd & (0x80000000 >> (ea - 1));
3260 1.1 christos rd <<= ea;
3261 1.1 christos }
3262 1.1 christos else
3263 1.1 christos {
3264 1.1 christos v = 0;
3265 1.1 christos c = rd & (1 << (ea - 1));
3266 1.1 christos rd = (unsigned int) rd >> ea;
3267 1.1 christos }
3268 1.1 christos goto shift32;
3269 1.1 christos
3270 1.1 christos case O (O_SHAL, SB):
3271 1.1 christos case O (O_SHAR, SB):
3272 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3273 1.1 christos goto end;
3274 1.1 christos
3275 1.1 christos if (code->src.type == X (OP_IMM, SB))
3276 1.1 christos fetch (sd, &code->src, &ea);
3277 1.1 christos else
3278 1.1 christos ea = 1;
3279 1.1 christos
3280 1.1 christos if (code->opcode == O (O_SHAL, SB))
3281 1.1 christos {
3282 1.1 christos c = rd & (0x80 >> (ea - 1));
3283 1.1 christos res = rd >> (7 - ea);
3284 1.1 christos v = ((res & 1) && !(res & 2))
3285 1.1 christos || (!(res & 1) && (res & 2));
3286 1.1 christos rd <<= ea;
3287 1.1 christos }
3288 1.1 christos else
3289 1.1 christos {
3290 1.1 christos c = rd & (1 << (ea - 1));
3291 1.1 christos v = 0;
3292 1.1 christos rd = ((signed char) rd) >> ea;
3293 1.1 christos }
3294 1.1 christos goto shift8;
3295 1.1 christos
3296 1.1 christos case O (O_SHAL, SW):
3297 1.1 christos case O (O_SHAR, SW):
3298 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3299 1.1 christos goto end;
3300 1.1 christos
3301 1.1 christos if (code->src.type == X (OP_IMM, SW))
3302 1.1 christos fetch (sd, &code->src, &ea);
3303 1.1 christos else
3304 1.1 christos ea = 1;
3305 1.1 christos
3306 1.1 christos if (code->opcode == O (O_SHAL, SW))
3307 1.1 christos {
3308 1.1 christos c = rd & (0x8000 >> (ea - 1));
3309 1.1 christos res = rd >> (15 - ea);
3310 1.1 christos v = ((res & 1) && !(res & 2))
3311 1.1 christos || (!(res & 1) && (res & 2));
3312 1.1 christos rd <<= ea;
3313 1.1 christos }
3314 1.1 christos else
3315 1.1 christos {
3316 1.1 christos c = rd & (1 << (ea - 1));
3317 1.1 christos v = 0;
3318 1.1 christos rd = ((signed short) rd) >> ea;
3319 1.1 christos }
3320 1.1 christos goto shift16;
3321 1.1 christos
3322 1.1 christos case O (O_SHAL, SL):
3323 1.1 christos case O (O_SHAR, SL):
3324 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3325 1.1 christos goto end;
3326 1.1 christos
3327 1.1 christos if (code->src.type == X (OP_IMM, SL))
3328 1.1 christos fetch (sd, &code->src, &ea);
3329 1.1 christos else
3330 1.1 christos ea = 1;
3331 1.1 christos
3332 1.1 christos if (code->opcode == O (O_SHAL, SL))
3333 1.1 christos {
3334 1.1 christos c = rd & (0x80000000 >> (ea - 1));
3335 1.1 christos res = rd >> (31 - ea);
3336 1.1 christos v = ((res & 1) && !(res & 2))
3337 1.1 christos || (!(res & 1) && (res & 2));
3338 1.1 christos rd <<= ea;
3339 1.1 christos }
3340 1.1 christos else
3341 1.1 christos {
3342 1.1 christos c = rd & (1 << (ea - 1));
3343 1.1 christos v = 0;
3344 1.1 christos rd = ((signed int) rd) >> ea;
3345 1.1 christos }
3346 1.1 christos goto shift32;
3347 1.1 christos
3348 1.1 christos case O (O_ROTL, SB):
3349 1.1 christos case O (O_ROTR, SB):
3350 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3351 1.1 christos goto end;
3352 1.1 christos
3353 1.1 christos if (code->src.type == X (OP_IMM, SB))
3354 1.1 christos fetch (sd, &code->src, &ea);
3355 1.1 christos else
3356 1.1 christos ea = 1;
3357 1.1 christos
3358 1.1 christos while (ea--)
3359 1.1 christos if (code->opcode == O (O_ROTL, SB))
3360 1.1 christos {
3361 1.1 christos c = rd & 0x80;
3362 1.1 christos rd <<= 1;
3363 1.1 christos if (c)
3364 1.1 christos rd |= 1;
3365 1.1 christos }
3366 1.1 christos else
3367 1.1 christos {
3368 1.1 christos c = rd & 1;
3369 1.1 christos rd = ((unsigned char) rd) >> 1;
3370 1.1 christos if (c)
3371 1.1 christos rd |= 0x80;
3372 1.1 christos }
3373 1.1 christos
3374 1.1 christos v = 0;
3375 1.1 christos goto shift8;
3376 1.1 christos
3377 1.1 christos case O (O_ROTL, SW):
3378 1.1 christos case O (O_ROTR, SW):
3379 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3380 1.1 christos goto end;
3381 1.1 christos
3382 1.1 christos if (code->src.type == X (OP_IMM, SW))
3383 1.1 christos fetch (sd, &code->src, &ea);
3384 1.1 christos else
3385 1.1 christos ea = 1;
3386 1.1 christos
3387 1.1 christos while (ea--)
3388 1.1 christos if (code->opcode == O (O_ROTL, SW))
3389 1.1 christos {
3390 1.1 christos c = rd & 0x8000;
3391 1.1 christos rd <<= 1;
3392 1.1 christos if (c)
3393 1.1 christos rd |= 1;
3394 1.1 christos }
3395 1.1 christos else
3396 1.1 christos {
3397 1.1 christos c = rd & 1;
3398 1.1 christos rd = ((unsigned short) rd) >> 1;
3399 1.1 christos if (c)
3400 1.1 christos rd |= 0x8000;
3401 1.1 christos }
3402 1.1 christos
3403 1.1 christos v = 0;
3404 1.1 christos goto shift16;
3405 1.1 christos
3406 1.1 christos case O (O_ROTL, SL):
3407 1.1 christos case O (O_ROTR, SL):
3408 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3409 1.1 christos goto end;
3410 1.1 christos
3411 1.1 christos if (code->src.type == X (OP_IMM, SL))
3412 1.1 christos fetch (sd, &code->src, &ea);
3413 1.1 christos else
3414 1.1 christos ea = 1;
3415 1.1 christos
3416 1.1 christos while (ea--)
3417 1.1 christos if (code->opcode == O (O_ROTL, SL))
3418 1.1 christos {
3419 1.1 christos c = rd & 0x80000000;
3420 1.1 christos rd <<= 1;
3421 1.1 christos if (c)
3422 1.1 christos rd |= 1;
3423 1.1 christos }
3424 1.1 christos else
3425 1.1 christos {
3426 1.1 christos c = rd & 1;
3427 1.1 christos rd = ((unsigned int) rd) >> 1;
3428 1.1 christos if (c)
3429 1.1 christos rd |= 0x80000000;
3430 1.1 christos }
3431 1.1 christos
3432 1.1 christos v = 0;
3433 1.1 christos goto shift32;
3434 1.1 christos
3435 1.1 christos case O (O_ROTXL, SB):
3436 1.1 christos case O (O_ROTXR, SB):
3437 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3438 1.1 christos goto end;
3439 1.1 christos
3440 1.1 christos if (code->src.type == X (OP_IMM, SB))
3441 1.1 christos fetch (sd, &code->src, &ea);
3442 1.1 christos else
3443 1.1 christos ea = 1;
3444 1.1 christos
3445 1.1 christos while (ea--)
3446 1.1 christos if (code->opcode == O (O_ROTXL, SB))
3447 1.1 christos {
3448 1.1 christos res = rd & 0x80;
3449 1.1 christos rd <<= 1;
3450 1.1 christos if (C)
3451 1.1 christos rd |= 1;
3452 1.1 christos c = res;
3453 1.1 christos }
3454 1.1 christos else
3455 1.1 christos {
3456 1.1 christos res = rd & 1;
3457 1.1 christos rd = ((unsigned char) rd) >> 1;
3458 1.1 christos if (C)
3459 1.1 christos rd |= 0x80;
3460 1.1 christos c = res;
3461 1.1 christos }
3462 1.1 christos
3463 1.1 christos v = 0;
3464 1.1 christos goto shift8;
3465 1.1 christos
3466 1.1 christos case O (O_ROTXL, SW):
3467 1.1 christos case O (O_ROTXR, SW):
3468 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3469 1.1 christos goto end;
3470 1.1 christos
3471 1.1 christos if (code->src.type == X (OP_IMM, SW))
3472 1.1 christos fetch (sd, &code->src, &ea);
3473 1.1 christos else
3474 1.1 christos ea = 1;
3475 1.1 christos
3476 1.1 christos while (ea--)
3477 1.1 christos if (code->opcode == O (O_ROTXL, SW))
3478 1.1 christos {
3479 1.1 christos res = rd & 0x8000;
3480 1.1 christos rd <<= 1;
3481 1.1 christos if (C)
3482 1.1 christos rd |= 1;
3483 1.1 christos c = res;
3484 1.1 christos }
3485 1.1 christos else
3486 1.1 christos {
3487 1.1 christos res = rd & 1;
3488 1.1 christos rd = ((unsigned short) rd) >> 1;
3489 1.1 christos if (C)
3490 1.1 christos rd |= 0x8000;
3491 1.1 christos c = res;
3492 1.1 christos }
3493 1.1 christos
3494 1.1 christos v = 0;
3495 1.1 christos goto shift16;
3496 1.1 christos
3497 1.1 christos case O (O_ROTXL, SL):
3498 1.1 christos case O (O_ROTXR, SL):
3499 1.1 christos if (fetch2 (sd, &code->dst, &rd))
3500 1.1 christos goto end;
3501 1.1 christos
3502 1.1 christos if (code->src.type == X (OP_IMM, SL))
3503 1.1 christos fetch (sd, &code->src, &ea);
3504 1.1 christos else
3505 1.1 christos ea = 1;
3506 1.1 christos
3507 1.1 christos while (ea--)
3508 1.1 christos if (code->opcode == O (O_ROTXL, SL))
3509 1.1 christos {
3510 1.1 christos res = rd & 0x80000000;
3511 1.1 christos rd <<= 1;
3512 1.1 christos if (C)
3513 1.1 christos rd |= 1;
3514 1.1 christos c = res;
3515 1.1 christos }
3516 1.1 christos else
3517 1.1 christos {
3518 1.1 christos res = rd & 1;
3519 1.1 christos rd = ((unsigned int) rd) >> 1;
3520 1.1 christos if (C)
3521 1.1 christos rd |= 0x80000000;
3522 1.1 christos c = res;
3523 1.1 christos }
3524 1.1 christos
3525 1.1 christos v = 0;
3526 1.1 christos goto shift32;
3527 1.1 christos
3528 1.1 christos case O (O_JMP, SN):
3529 1.1 christos case O (O_JMP, SL):
3530 1.1 christos case O (O_JMP, SB): /* jmp */
3531 1.1 christos case O (O_JMP, SW):
3532 1.1 christos fetch (sd, &code->src, &pc);
3533 1.1 christos goto end;
3534 1.1 christos
3535 1.1 christos case O (O_JSR, SN):
3536 1.1 christos case O (O_JSR, SL):
3537 1.1 christos case O (O_JSR, SB): /* jsr, jump to subroutine */
3538 1.1 christos case O (O_JSR, SW):
3539 1.1 christos if (fetch (sd, &code->src, &pc))
3540 1.1 christos goto end;
3541 1.1 christos call:
3542 1.1 christos tmp = h8_get_reg (sd, SP_REGNUM);
3543 1.1 christos
3544 1.1 christos if (h8300hmode && !h8300_normal_mode)
3545 1.1 christos {
3546 1.1 christos tmp -= 4;
3547 1.1 christos SET_MEMORY_L (tmp, code->next_pc);
3548 1.1 christos }
3549 1.1 christos else
3550 1.1 christos {
3551 1.1 christos tmp -= 2;
3552 1.1 christos SET_MEMORY_W (tmp, code->next_pc);
3553 1.1 christos }
3554 1.1 christos h8_set_reg (sd, SP_REGNUM, tmp);
3555 1.1 christos
3556 1.1 christos goto end;
3557 1.1 christos
3558 1.1 christos case O (O_BSR, SW):
3559 1.1 christos case O (O_BSR, SL):
3560 1.1 christos case O (O_BSR, SB): /* bsr, branch to subroutine */
3561 1.1 christos if (fetch (sd, &code->src, &res))
3562 1.1 christos goto end;
3563 1.1 christos pc = code->next_pc + res;
3564 1.1 christos goto call;
3565 1.1 christos
3566 1.1 christos case O (O_RTE, SN): /* rte, return from exception */
3567 1.1 christos rte:
3568 1.1 christos /* Pops exr and ccr before pc -- otherwise identical to rts. */
3569 1.1 christos tmp = h8_get_reg (sd, SP_REGNUM);
3570 1.1 christos
3571 1.1 christos if (h8300smode) /* pop exr */
3572 1.1 christos {
3573 1.1 christos h8_set_exr (sd, GET_MEMORY_L (tmp));
3574 1.1 christos tmp += 4;
3575 1.1 christos }
3576 1.1 christos if (h8300hmode && !h8300_normal_mode)
3577 1.1 christos {
3578 1.1 christos h8_set_ccr (sd, GET_MEMORY_L (tmp));
3579 1.1 christos tmp += 4;
3580 1.1 christos pc = GET_MEMORY_L (tmp);
3581 1.1 christos tmp += 4;
3582 1.1 christos }
3583 1.1 christos else
3584 1.1 christos {
3585 1.1 christos h8_set_ccr (sd, GET_MEMORY_W (tmp));
3586 1.1 christos tmp += 2;
3587 1.1 christos pc = GET_MEMORY_W (tmp);
3588 1.1 christos tmp += 2;
3589 1.1 christos }
3590 1.1 christos
3591 1.1 christos GETSR (sd);
3592 1.1 christos h8_set_reg (sd, SP_REGNUM, tmp);
3593 1.1 christos goto end;
3594 1.1 christos
3595 1.1 christos case O (O_RTS, SN): /* rts, return from subroutine */
3596 1.1 christos rts:
3597 1.1 christos tmp = h8_get_reg (sd, SP_REGNUM);
3598 1.1 christos
3599 1.1 christos if (h8300hmode && !h8300_normal_mode)
3600 1.1 christos {
3601 1.1 christos pc = GET_MEMORY_L (tmp);
3602 1.1 christos tmp += 4;
3603 1.1 christos }
3604 1.1 christos else
3605 1.1 christos {
3606 1.1 christos pc = GET_MEMORY_W (tmp);
3607 1.1 christos tmp += 2;
3608 1.1 christos }
3609 1.1 christos
3610 1.1 christos h8_set_reg (sd, SP_REGNUM, tmp);
3611 1.1 christos goto end;
3612 1.1 christos
3613 1.1 christos case O (O_ILL, SB): /* illegal */
3614 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGILL);
3615 1.1 christos goto end;
3616 1.1 christos
3617 1.1 christos case O (O_SLEEP, SN): /* sleep */
3618 1.1 christos /* Check for magic numbers in r1 and r2. */
3619 1.1 christos if ((h8_get_reg (sd, R1_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC1 &&
3620 1.1 christos (h8_get_reg (sd, R2_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC2 &&
3621 1.1 christos SIM_WIFEXITED (h8_get_reg (sd, 0)))
3622 1.1 christos {
3623 1.1 christos /* This trap comes from _exit, not from gdb. */
3624 1.1 christos sim_engine_set_run_state (sd, sim_exited,
3625 1.1 christos SIM_WEXITSTATUS (h8_get_reg (sd, 0)));
3626 1.1 christos }
3627 1.1 christos #if 0
3628 1.1 christos /* Unfortunately this won't really work, because
3629 1.1 christos when we take a breakpoint trap, R0 has a "random",
3630 1.1 christos user-defined value. Don't see any immediate solution. */
3631 1.1 christos else if (SIM_WIFSTOPPED (h8_get_reg (sd, 0)))
3632 1.1 christos {
3633 1.1 christos /* Pass the stop signal up to gdb. */
3634 1.1 christos sim_engine_set_run_state (sd, sim_stopped,
3635 1.1 christos SIM_WSTOPSIG (h8_get_reg (sd, 0)));
3636 1.1 christos }
3637 1.1 christos #endif
3638 1.1 christos else
3639 1.1 christos {
3640 1.1 christos /* Treat it as a sigtrap. */
3641 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
3642 1.1 christos }
3643 1.1 christos goto end;
3644 1.1 christos
3645 1.1 christos case O (O_TRAPA, SB): /* trapa */
3646 1.1 christos if (fetch (sd, &code->src, &res))
3647 1.1 christos goto end; /* res is vector number. */
3648 1.1 christos
3649 1.1 christos tmp = h8_get_reg (sd, SP_REGNUM);
3650 1.1 christos if(h8300_normal_mode)
3651 1.1 christos {
3652 1.1 christos tmp -= 2;
3653 1.1 christos SET_MEMORY_W (tmp, code->next_pc);
3654 1.1 christos tmp -= 2;
3655 1.1 christos SET_MEMORY_W (tmp, h8_get_ccr (sd));
3656 1.1 christos }
3657 1.1 christos else
3658 1.1 christos {
3659 1.1 christos tmp -= 4;
3660 1.1 christos SET_MEMORY_L (tmp, code->next_pc);
3661 1.1 christos tmp -= 4;
3662 1.1 christos SET_MEMORY_L (tmp, h8_get_ccr (sd));
3663 1.1 christos }
3664 1.1 christos intMaskBit = 1;
3665 1.1 christos BUILDSR (sd);
3666 1.1 christos
3667 1.1 christos if (h8300smode)
3668 1.1 christos {
3669 1.1 christos tmp -= 4;
3670 1.1 christos SET_MEMORY_L (tmp, h8_get_exr (sd));
3671 1.1 christos }
3672 1.1 christos
3673 1.1 christos h8_set_reg (sd, SP_REGNUM, tmp);
3674 1.1 christos
3675 1.1 christos if(h8300_normal_mode)
3676 1.1 christos pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */
3677 1.1 christos else
3678 1.1 christos pc = GET_MEMORY_L (0x20 + res * 4);
3679 1.1 christos goto end;
3680 1.1 christos
3681 1.1 christos case O (O_BPT, SN):
3682 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
3683 1.1 christos goto end;
3684 1.1 christos
3685 1.1 christos case O (O_BSETEQ, SB):
3686 1.1 christos if (Z)
3687 1.1 christos goto bset;
3688 1.1 christos goto next;
3689 1.1 christos
3690 1.1 christos case O (O_BSETNE, SB):
3691 1.1 christos if (!Z)
3692 1.1 christos goto bset;
3693 1.1 christos goto next;
3694 1.1 christos
3695 1.1 christos case O (O_BCLREQ, SB):
3696 1.1 christos if (Z)
3697 1.1 christos goto bclr;
3698 1.1 christos goto next;
3699 1.1 christos
3700 1.1 christos case O (O_BCLRNE, SB):
3701 1.1 christos if (!Z)
3702 1.1 christos goto bclr;
3703 1.1 christos goto next;
3704 1.1 christos
3705 1.1 christos OBITOP (O_BNOT, 1, 1, ea ^= m); /* bnot */
3706 1.1 christos OBITOP (O_BTST, 1, 0, nz = ea & m); /* btst */
3707 1.1 christos bset:
3708 1.1 christos OBITOP (O_BSET, 1, 1, ea |= m); /* bset */
3709 1.1 christos bclr:
3710 1.1 christos OBITOP (O_BCLR, 1, 1, ea &= ~m); /* bclr */
3711 1.1 christos OBITOP (O_BLD, 1, 0, c = ea & m); /* bld */
3712 1.1 christos OBITOP (O_BILD, 1, 0, c = !(ea & m)); /* bild */
3713 1.1 christos OBITOP (O_BST, 1, 1, ea &= ~m;
3714 1.1 christos if (C) ea |= m); /* bst */
3715 1.1 christos OBITOP (O_BIST, 1, 1, ea &= ~m;
3716 1.1 christos if (!C) ea |= m); /* bist */
3717 1.1 christos OBITOP (O_BSTZ, 1, 1, ea &= ~m;
3718 1.1 christos if (Z) ea |= m); /* bstz */
3719 1.1 christos OBITOP (O_BISTZ, 1, 1, ea &= ~m;
3720 1.1 christos if (!Z) ea |= m); /* bistz */
3721 1.1 christos OBITOP (O_BAND, 1, 0, c = (ea & m) && C); /* band */
3722 1.1 christos OBITOP (O_BIAND, 1, 0, c = !(ea & m) && C); /* biand */
3723 1.1 christos OBITOP (O_BOR, 1, 0, c = (ea & m) || C); /* bor */
3724 1.1 christos OBITOP (O_BIOR, 1, 0, c = !(ea & m) || C); /* bior */
3725 1.1 christos OBITOP (O_BXOR, 1, 0, c = ((ea & m) != 0)!= C); /* bxor */
3726 1.1 christos OBITOP (O_BIXOR, 1, 0, c = !(ea & m) != C); /* bixor */
3727 1.1 christos
3728 1.1 christos case O (O_BFLD, SB): /* bfld */
3729 1.1 christos /* bitfield load */
3730 1.1 christos ea = 0;
3731 1.1 christos if (fetch (sd, &code->src, &bit))
3732 1.1 christos goto end;
3733 1.1 christos
3734 1.1 christos if (bit != 0)
3735 1.1 christos {
3736 1.1 christos if (fetch (sd, &code->dst, &ea))
3737 1.1 christos goto end;
3738 1.1 christos
3739 1.1 christos ea &= bit;
3740 1.1 christos while (!(bit & 1))
3741 1.1 christos {
3742 1.1 christos ea >>= 1;
3743 1.1 christos bit >>= 1;
3744 1.1 christos }
3745 1.1 christos }
3746 1.1 christos if (store (sd, &code->op3, ea))
3747 1.1 christos goto end;
3748 1.1 christos
3749 1.1 christos goto next;
3750 1.1 christos
3751 1.1 christos case O(O_BFST, SB): /* bfst */
3752 1.1 christos /* bitfield store */
3753 1.1 christos /* NOTE: the imm8 value is in dst, and the ea value
3754 1.1 christos (which is actually the destination) is in op3.
3755 1.1 christos It has to be that way, to avoid breaking the assembler. */
3756 1.1 christos
3757 1.1 christos if (fetch (sd, &code->dst, &bit)) /* imm8 */
3758 1.1 christos goto end;
3759 1.1 christos if (bit == 0) /* noop -- nothing to do. */
3760 1.1 christos goto next;
3761 1.1 christos
3762 1.1 christos if (fetch (sd, &code->src, &rd)) /* reg8 src */
3763 1.1 christos goto end;
3764 1.1 christos
3765 1.1 christos if (fetch2 (sd, &code->op3, &ea)) /* ea dst */
3766 1.1 christos goto end;
3767 1.1 christos
3768 1.1 christos /* Left-shift the register data into position. */
3769 1.1 christos for (tmp = bit; !(tmp & 1); tmp >>= 1)
3770 1.1 christos rd <<= 1;
3771 1.1 christos
3772 1.1 christos /* Combine it with the neighboring bits. */
3773 1.1 christos ea = (ea & ~bit) | (rd & bit);
3774 1.1 christos
3775 1.1 christos /* Put it back. */
3776 1.1 christos if (store2 (sd, &code->op3, ea))
3777 1.1 christos goto end;
3778 1.1 christos goto next;
3779 1.1 christos
3780 1.1 christos case O (O_CLRMAC, SN): /* clrmac */
3781 1.1 christos h8_set_mach (sd, 0);
3782 1.1 christos h8_set_macl (sd, 0);
3783 1.1 christos h8_set_macZ (sd, 1);
3784 1.1 christos h8_set_macV (sd, 0);
3785 1.1 christos h8_set_macN (sd, 0);
3786 1.1 christos goto next;
3787 1.1 christos
3788 1.1 christos case O (O_STMAC, SL): /* stmac, 260 */
3789 1.1 christos switch (code->src.type) {
3790 1.1 christos case X (OP_MACH, SL):
3791 1.1 christos res = h8_get_mach (sd);
3792 1.1 christos if (res & 0x200) /* sign extend */
3793 1.1 christos res |= 0xfffffc00;
3794 1.1 christos break;
3795 1.1 christos case X (OP_MACL, SL):
3796 1.1 christos res = h8_get_macl (sd);
3797 1.1 christos break;
3798 1.1 christos default: goto illegal;
3799 1.1 christos }
3800 1.1 christos nz = !h8_get_macZ (sd);
3801 1.1 christos n = h8_get_macN (sd);
3802 1.1 christos v = h8_get_macV (sd);
3803 1.1 christos
3804 1.1 christos if (store (sd, &code->dst, res))
3805 1.1 christos goto end;
3806 1.1 christos
3807 1.1 christos goto next;
3808 1.1 christos
3809 1.1 christos case O (O_LDMAC, SL): /* ldmac, 179 */
3810 1.1 christos if (fetch (sd, &code->src, &rd))
3811 1.1 christos goto end;
3812 1.1 christos
3813 1.1 christos switch (code->dst.type) {
3814 1.1 christos case X (OP_MACH, SL):
3815 1.1 christos rd &= 0x3ff; /* Truncate to 10 bits */
3816 1.1 christos h8_set_mach (sd, rd);
3817 1.1 christos break;
3818 1.1 christos case X (OP_MACL, SL):
3819 1.1 christos h8_set_macl (sd, rd);
3820 1.1 christos break;
3821 1.1 christos default: goto illegal;
3822 1.1 christos }
3823 1.1 christos h8_set_macV (sd, 0);
3824 1.1 christos goto next;
3825 1.1 christos
3826 1.1 christos case O (O_MAC, SW):
3827 1.1 christos if (fetch (sd, &code->src, &rd) ||
3828 1.1 christos fetch (sd, &code->dst, &res))
3829 1.1 christos goto end;
3830 1.1 christos
3831 1.1 christos /* Ye gods, this is non-portable!
3832 1.1 christos However, the existing mul/div code is similar. */
3833 1.1 christos res = SEXTSHORT (res) * SEXTSHORT (rd);
3834 1.1 christos
3835 1.1 christos if (h8_get_macS (sd)) /* Saturating mode */
3836 1.1 christos {
3837 1.1 christos long long mac = h8_get_macl (sd);
3838 1.1 christos
3839 1.1 christos if (mac & 0x80000000) /* sign extend */
3840 1.1 christos mac |= 0xffffffff00000000LL;
3841 1.1 christos
3842 1.1 christos mac += res;
3843 1.1 christos if (mac > 0x7fffffff || mac < 0xffffffff80000000LL)
3844 1.1 christos h8_set_macV (sd, 1);
3845 1.1 christos h8_set_macZ (sd, (mac == 0));
3846 1.1 christos h8_set_macN (sd, (mac < 0));
3847 1.1 christos h8_set_macl (sd, (int) mac);
3848 1.1 christos }
3849 1.1 christos else /* "Less Saturating" mode */
3850 1.1 christos {
3851 1.1 christos long long mac = h8_get_mach (sd);
3852 1.1 christos mac <<= 32;
3853 1.1 christos mac += h8_get_macl (sd);
3854 1.1 christos
3855 1.1 christos if (mac & 0x20000000000LL) /* sign extend */
3856 1.1 christos mac |= 0xfffffc0000000000LL;
3857 1.1 christos
3858 1.1 christos mac += res;
3859 1.1 christos if (mac > 0x1ffffffffffLL ||
3860 1.1 christos mac < (long long) 0xfffffe0000000000LL)
3861 1.1 christos h8_set_macV (sd, 1);
3862 1.1 christos h8_set_macZ (sd, (mac == 0));
3863 1.1 christos h8_set_macN (sd, (mac < 0));
3864 1.1 christos h8_set_macl (sd, (int) mac);
3865 1.1 christos mac >>= 32;
3866 1.1 christos h8_set_mach (sd, (int) (mac & 0x3ff));
3867 1.1 christos }
3868 1.1 christos goto next;
3869 1.1 christos
3870 1.1 christos case O (O_MULS, SW): /* muls.w */
3871 1.1 christos if (fetch (sd, &code->src, &ea) ||
3872 1.1 christos fetch (sd, &code->dst, &rd))
3873 1.1 christos goto end;
3874 1.1 christos
3875 1.1 christos ea = SEXTSHORT (ea);
3876 1.1 christos res = SEXTSHORT (ea * SEXTSHORT (rd));
3877 1.1 christos
3878 1.1 christos n = res & 0x8000;
3879 1.1 christos nz = res & 0xffff;
3880 1.1 christos if (store (sd, &code->dst, res))
3881 1.1 christos goto end;
3882 1.1 christos
3883 1.1 christos goto next;
3884 1.1 christos
3885 1.1 christos case O (O_MULS, SL): /* muls.l */
3886 1.1 christos if (fetch (sd, &code->src, &ea) ||
3887 1.1 christos fetch (sd, &code->dst, &rd))
3888 1.1 christos goto end;
3889 1.1 christos
3890 1.1 christos res = ea * rd;
3891 1.1 christos
3892 1.1 christos n = res & 0x80000000;
3893 1.1 christos nz = res & 0xffffffff;
3894 1.1 christos if (store (sd, &code->dst, res))
3895 1.1 christos goto end;
3896 1.1 christos goto next;
3897 1.1 christos
3898 1.1 christos case O (O_MULSU, SL): /* muls/u.l */
3899 1.1 christos if (fetch (sd, &code->src, &ea) ||
3900 1.1 christos fetch (sd, &code->dst, &rd))
3901 1.1 christos goto end;
3902 1.1 christos
3903 1.1 christos /* Compute upper 32 bits of the 64-bit result. */
3904 1.1 christos res = (((long long) ea) * ((long long) rd)) >> 32;
3905 1.1 christos
3906 1.1 christos n = res & 0x80000000;
3907 1.1 christos nz = res & 0xffffffff;
3908 1.1 christos if (store (sd, &code->dst, res))
3909 1.1 christos goto end;
3910 1.1 christos goto next;
3911 1.1 christos
3912 1.1 christos case O (O_MULU, SW): /* mulu.w */
3913 1.1 christos if (fetch (sd, &code->src, &ea) ||
3914 1.1 christos fetch (sd, &code->dst, &rd))
3915 1.1 christos goto end;
3916 1.1 christos
3917 1.1 christos res = UEXTSHORT ((UEXTSHORT (ea) * UEXTSHORT (rd)));
3918 1.1 christos
3919 1.1 christos /* Don't set Z or N. */
3920 1.1 christos if (store (sd, &code->dst, res))
3921 1.1 christos goto end;
3922 1.1 christos
3923 1.1 christos goto next;
3924 1.1 christos
3925 1.1 christos case O (O_MULU, SL): /* mulu.l */
3926 1.1 christos if (fetch (sd, &code->src, &ea) ||
3927 1.1 christos fetch (sd, &code->dst, &rd))
3928 1.1 christos goto end;
3929 1.1 christos
3930 1.1 christos res = ea * rd;
3931 1.1 christos
3932 1.1 christos /* Don't set Z or N. */
3933 1.1 christos if (store (sd, &code->dst, res))
3934 1.1 christos goto end;
3935 1.1 christos
3936 1.1 christos goto next;
3937 1.1 christos
3938 1.1 christos case O (O_MULUU, SL): /* mulu/u.l */
3939 1.1 christos if (fetch (sd, &code->src, &ea) ||
3940 1.1 christos fetch (sd, &code->dst, &rd))
3941 1.1 christos goto end;
3942 1.1 christos
3943 1.1 christos /* Compute upper 32 bits of the 64-bit result. */
3944 1.1 christos res = (((unsigned long long) (unsigned) ea) *
3945 1.1 christos ((unsigned long long) (unsigned) rd)) >> 32;
3946 1.1 christos
3947 1.1 christos /* Don't set Z or N. */
3948 1.1 christos if (store (sd, &code->dst, res))
3949 1.1 christos goto end;
3950 1.1 christos
3951 1.1 christos goto next;
3952 1.1 christos
3953 1.1 christos case O (O_MULXS, SB): /* mulxs.b */
3954 1.1 christos if (fetch (sd, &code->src, &ea) ||
3955 1.1 christos fetch (sd, &code->dst, &rd))
3956 1.1 christos goto end;
3957 1.1 christos
3958 1.1 christos ea = SEXTCHAR (ea);
3959 1.1 christos res = ea * SEXTCHAR (rd);
3960 1.1 christos
3961 1.1 christos n = res & 0x8000;
3962 1.1 christos nz = res & 0xffff;
3963 1.1 christos if (store (sd, &code->dst, res))
3964 1.1 christos goto end;
3965 1.1 christos
3966 1.1 christos goto next;
3967 1.1 christos
3968 1.1 christos case O (O_MULXS, SW): /* mulxs.w */
3969 1.1 christos if (fetch (sd, &code->src, &ea) ||
3970 1.1 christos fetch (sd, &code->dst, &rd))
3971 1.1 christos goto end;
3972 1.1 christos
3973 1.1 christos ea = SEXTSHORT (ea);
3974 1.1 christos res = ea * SEXTSHORT (rd & 0xffff);
3975 1.1 christos
3976 1.1 christos n = res & 0x80000000;
3977 1.1 christos nz = res & 0xffffffff;
3978 1.1 christos if (store (sd, &code->dst, res))
3979 1.1 christos goto end;
3980 1.1 christos
3981 1.1 christos goto next;
3982 1.1 christos
3983 1.1 christos case O (O_MULXU, SB): /* mulxu.b */
3984 1.1 christos if (fetch (sd, &code->src, &ea) ||
3985 1.1 christos fetch (sd, &code->dst, &rd))
3986 1.1 christos goto end;
3987 1.1 christos
3988 1.1 christos res = UEXTCHAR (ea) * UEXTCHAR (rd);
3989 1.1 christos
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, SW): /* mulxu.w */
3996 1.1 christos if (fetch (sd, &code->src, &ea) ||
3997 1.1 christos fetch (sd, &code->dst, &rd))
3998 1.1 christos goto end;
3999 1.1 christos
4000 1.1 christos res = UEXTSHORT (ea) * UEXTSHORT (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_TAS, SB): /* tas (test and set) */
4008 1.1 christos if (!h8300sxmode) /* h8sx can use any register. */
4009 1.1 christos switch (code->src.reg)
4010 1.1 christos {
4011 1.1 christos case R0_REGNUM:
4012 1.1 christos case R1_REGNUM:
4013 1.1 christos case R4_REGNUM:
4014 1.1 christos case R5_REGNUM:
4015 1.1 christos break;
4016 1.1 christos default:
4017 1.1 christos goto illegal;
4018 1.1 christos }
4019 1.1 christos
4020 1.1 christos if (fetch (sd, &code->src, &res))
4021 1.1 christos goto end;
4022 1.1 christos if (store (sd, &code->src, res | 0x80))
4023 1.1 christos goto end;
4024 1.1 christos
4025 1.1 christos goto just_flags_log8;
4026 1.1 christos
4027 1.1 christos case O (O_DIVU, SW): /* divu.w */
4028 1.1 christos if (fetch (sd, &code->src, &ea) ||
4029 1.1 christos fetch (sd, &code->dst, &rd))
4030 1.1 christos goto end;
4031 1.1 christos
4032 1.1 christos n = ea & 0x8000;
4033 1.1 christos nz = ea & 0xffff;
4034 1.1 christos if (ea)
4035 1.1 christos res = (unsigned) (UEXTSHORT (rd) / UEXTSHORT (ea));
4036 1.1 christos else
4037 1.1 christos res = 0;
4038 1.1 christos
4039 1.1 christos if (store (sd, &code->dst, res))
4040 1.1 christos goto end;
4041 1.1 christos goto next;
4042 1.1 christos
4043 1.1 christos case O (O_DIVU, SL): /* divu.l */
4044 1.1 christos if (fetch (sd, &code->src, &ea) ||
4045 1.1 christos fetch (sd, &code->dst, &rd))
4046 1.1 christos goto end;
4047 1.1 christos
4048 1.1 christos n = ea & 0x80000000;
4049 1.1 christos nz = ea & 0xffffffff;
4050 1.1 christos if (ea)
4051 1.1 christos res = (unsigned) rd / ea;
4052 1.1 christos else
4053 1.1 christos res = 0;
4054 1.1 christos
4055 1.1 christos if (store (sd, &code->dst, res))
4056 1.1 christos goto end;
4057 1.1 christos goto next;
4058 1.1 christos
4059 1.1 christos case O (O_DIVS, SW): /* divs.w */
4060 1.1 christos if (fetch (sd, &code->src, &ea) ||
4061 1.1 christos fetch (sd, &code->dst, &rd))
4062 1.1 christos goto end;
4063 1.1 christos
4064 1.1 christos if (ea)
4065 1.1 christos {
4066 1.1 christos res = SEXTSHORT (rd) / SEXTSHORT (ea);
4067 1.1 christos nz = 1;
4068 1.1 christos }
4069 1.1 christos else
4070 1.1 christos {
4071 1.1 christos res = 0;
4072 1.1 christos nz = 0;
4073 1.1 christos }
4074 1.1 christos
4075 1.1 christos n = res & 0x8000;
4076 1.1 christos if (store (sd, &code->dst, res))
4077 1.1 christos goto end;
4078 1.1 christos goto next;
4079 1.1 christos
4080 1.1 christos case O (O_DIVS, SL): /* divs.l */
4081 1.1 christos if (fetch (sd, &code->src, &ea) ||
4082 1.1 christos fetch (sd, &code->dst, &rd))
4083 1.1 christos goto end;
4084 1.1 christos
4085 1.1 christos if (ea)
4086 1.1 christos {
4087 1.1 christos res = rd / ea;
4088 1.1 christos nz = 1;
4089 1.1 christos }
4090 1.1 christos else
4091 1.1 christos {
4092 1.1 christos res = 0;
4093 1.1 christos nz = 0;
4094 1.1 christos }
4095 1.1 christos
4096 1.1 christos n = res & 0x80000000;
4097 1.1 christos if (store (sd, &code->dst, res))
4098 1.1 christos goto end;
4099 1.1 christos goto next;
4100 1.1 christos
4101 1.1 christos case O (O_DIVXU, SB): /* divxu.b */
4102 1.1 christos if (fetch (sd, &code->src, &ea) ||
4103 1.1 christos fetch (sd, &code->dst, &rd))
4104 1.1 christos goto end;
4105 1.1 christos
4106 1.1 christos rd = UEXTSHORT (rd);
4107 1.1 christos ea = UEXTCHAR (ea);
4108 1.1 christos
4109 1.1 christos n = ea & 0x80;
4110 1.1 christos nz = ea & 0xff;
4111 1.1 christos if (ea)
4112 1.1 christos {
4113 1.1 christos tmp = (unsigned) rd % ea;
4114 1.1 christos res = (unsigned) rd / ea;
4115 1.1 christos }
4116 1.1 christos else
4117 1.1 christos {
4118 1.1 christos tmp = 0;
4119 1.1 christos res = 0;
4120 1.1 christos }
4121 1.1 christos
4122 1.1 christos if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
4123 1.1 christos goto end;
4124 1.1 christos goto next;
4125 1.1 christos
4126 1.1 christos case O (O_DIVXU, SW): /* divxu.w */
4127 1.1 christos if (fetch (sd, &code->src, &ea) ||
4128 1.1 christos fetch (sd, &code->dst, &rd))
4129 1.1 christos goto end;
4130 1.1 christos
4131 1.1 christos ea = UEXTSHORT (ea);
4132 1.1 christos
4133 1.1 christos n = ea & 0x8000;
4134 1.1 christos nz = ea & 0xffff;
4135 1.1 christos if (ea)
4136 1.1 christos {
4137 1.1 christos tmp = (unsigned) rd % ea;
4138 1.1 christos res = (unsigned) rd / ea;
4139 1.1 christos }
4140 1.1 christos else
4141 1.1 christos {
4142 1.1 christos tmp = 0;
4143 1.1 christos res = 0;
4144 1.1 christos }
4145 1.1 christos
4146 1.1 christos if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
4147 1.1 christos goto end;
4148 1.1 christos goto next;
4149 1.1 christos
4150 1.1 christos case O (O_DIVXS, SB): /* divxs.b */
4151 1.1 christos if (fetch (sd, &code->src, &ea) ||
4152 1.1 christos fetch (sd, &code->dst, &rd))
4153 1.1 christos goto end;
4154 1.1 christos
4155 1.1 christos rd = SEXTSHORT (rd);
4156 1.1 christos ea = SEXTCHAR (ea);
4157 1.1 christos
4158 1.1 christos if (ea)
4159 1.1 christos {
4160 1.1 christos tmp = (int) rd % (int) ea;
4161 1.1 christos res = (int) rd / (int) ea;
4162 1.1 christos nz = 1;
4163 1.1 christos }
4164 1.1 christos else
4165 1.1 christos {
4166 1.1 christos tmp = 0;
4167 1.1 christos res = 0;
4168 1.1 christos nz = 0;
4169 1.1 christos }
4170 1.1 christos
4171 1.1 christos n = res & 0x8000;
4172 1.1 christos if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
4173 1.1 christos goto end;
4174 1.1 christos goto next;
4175 1.1 christos
4176 1.1 christos case O (O_DIVXS, SW): /* divxs.w */
4177 1.1 christos if (fetch (sd, &code->src, &ea) ||
4178 1.1 christos fetch (sd, &code->dst, &rd))
4179 1.1 christos goto end;
4180 1.1 christos
4181 1.1 christos ea = SEXTSHORT (ea);
4182 1.1 christos
4183 1.1 christos if (ea)
4184 1.1 christos {
4185 1.1 christos tmp = (int) rd % (int) ea;
4186 1.1 christos res = (int) rd / (int) ea;
4187 1.1 christos nz = 1;
4188 1.1 christos }
4189 1.1 christos else
4190 1.1 christos {
4191 1.1 christos tmp = 0;
4192 1.1 christos res = 0;
4193 1.1 christos nz = 0;
4194 1.1 christos }
4195 1.1 christos
4196 1.1 christos n = res & 0x80000000;
4197 1.1 christos if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
4198 1.1 christos goto end;
4199 1.1 christos goto next;
4200 1.1 christos
4201 1.1 christos case O (O_EXTS, SW): /* exts.w, signed extend */
4202 1.1 christos if (fetch2 (sd, &code->dst, &rd))
4203 1.1 christos goto end;
4204 1.1 christos ea = rd & 0x80 ? -256 : 0;
4205 1.1 christos res = (rd & 0xff) + ea;
4206 1.1 christos goto log16;
4207 1.1 christos
4208 1.1 christos case O (O_EXTS, SL): /* exts.l, signed extend */
4209 1.1 christos if (fetch2 (sd, &code->dst, &rd))
4210 1.1 christos goto end;
4211 1.1 christos if (code->src.type == X (OP_IMM, SL))
4212 1.1 christos {
4213 1.1 christos if (fetch (sd, &code->src, &ea))
4214 1.1 christos goto end;
4215 1.1 christos
4216 1.1 christos if (ea == 2) /* exts.l #2, nn */
4217 1.1 christos {
4218 1.1 christos /* Sign-extend from 8-bit to 32-bit. */
4219 1.1 christos ea = rd & 0x80 ? -256 : 0;
4220 1.1 christos res = (rd & 0xff) + ea;
4221 1.1 christos goto log32;
4222 1.1 christos }
4223 1.1 christos }
4224 1.1 christos /* Sign-extend from 16-bit to 32-bit. */
4225 1.1 christos ea = rd & 0x8000 ? -65536 : 0;
4226 1.1 christos res = (rd & 0xffff) + ea;
4227 1.1 christos goto log32;
4228 1.1 christos
4229 1.1 christos case O (O_EXTU, SW): /* extu.w, unsigned extend */
4230 1.1 christos if (fetch2 (sd, &code->dst, &rd))
4231 1.1 christos goto end;
4232 1.1 christos ea = 0;
4233 1.1 christos res = (rd & 0xff) + ea;
4234 1.1 christos goto log16;
4235 1.1 christos
4236 1.1 christos case O (O_EXTU, SL): /* extu.l, unsigned extend */
4237 1.1 christos if (fetch2 (sd, &code->dst, &rd))
4238 1.1 christos goto end;
4239 1.1 christos if (code->src.type == X (OP_IMM, SL))
4240 1.1 christos {
4241 1.1 christos if (fetch (sd, &code->src, &ea))
4242 1.1 christos goto end;
4243 1.1 christos
4244 1.1 christos if (ea == 2) /* extu.l #2, nn */
4245 1.1 christos {
4246 1.1 christos /* Zero-extend from 8-bit to 32-bit. */
4247 1.1 christos ea = 0;
4248 1.1 christos res = (rd & 0xff) + ea;
4249 1.1 christos goto log32;
4250 1.1 christos }
4251 1.1 christos }
4252 1.1 christos /* Zero-extend from 16-bit to 32-bit. */
4253 1.1 christos ea = 0;
4254 1.1 christos res = (rd & 0xffff) + ea;
4255 1.1 christos goto log32;
4256 1.1 christos
4257 1.1 christos case O (O_NOP, SN): /* nop */
4258 1.1 christos goto next;
4259 1.1 christos
4260 1.1 christos case O (O_STM, SL): /* stm, store to memory */
4261 1.1 christos {
4262 1.1 christos int nregs, firstreg, i;
4263 1.1 christos
4264 1.1 christos nregs = GET_MEMORY_B (pc + 1);
4265 1.1 christos nregs >>= 4;
4266 1.1 christos nregs &= 0xf;
4267 1.1 christos firstreg = code->src.reg;
4268 1.1 christos firstreg &= 0xf;
4269 1.1 christos for (i = firstreg; i <= firstreg + nregs; i++)
4270 1.1 christos {
4271 1.1 christos h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) - 4);
4272 1.1 christos SET_MEMORY_L (h8_get_reg (sd, SP_REGNUM), h8_get_reg (sd, i));
4273 1.1 christos }
4274 1.1 christos }
4275 1.1 christos goto next;
4276 1.1 christos
4277 1.1 christos case O (O_LDM, SL): /* ldm, load from memory */
4278 1.1 christos case O (O_RTEL, SN): /* rte/l, ldm plus rte */
4279 1.1 christos case O (O_RTSL, SN): /* rts/l, ldm plus rts */
4280 1.1 christos {
4281 1.1 christos int nregs, firstreg, i;
4282 1.1 christos
4283 1.1 christos nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf);
4284 1.1 christos firstreg = code->dst.reg & 0xf;
4285 1.1 christos for (i = firstreg; i >= firstreg - nregs; i--)
4286 1.1 christos {
4287 1.1 christos h8_set_reg (sd, i, GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM)));
4288 1.1 christos h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) + 4);
4289 1.1 christos }
4290 1.1 christos }
4291 1.1 christos switch (code->opcode) {
4292 1.1 christos case O (O_RTEL, SN):
4293 1.1 christos goto rte;
4294 1.1 christos case O (O_RTSL, SN):
4295 1.1 christos goto rts;
4296 1.1 christos case O (O_LDM, SL):
4297 1.1 christos goto next;
4298 1.1 christos default:
4299 1.1 christos goto illegal;
4300 1.1 christos }
4301 1.1 christos
4302 1.1 christos case O (O_DAA, SB):
4303 1.1 christos /* Decimal Adjust Addition. This is for BCD arithmetic. */
4304 1.1 christos res = GET_B_REG (code->src.reg); /* FIXME fetch? */
4305 1.1 christos if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4306 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4307 1.1 christos res = res; /* Value added == 0. */
4308 1.1 christos else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) &&
4309 1.1 christos !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
4310 1.1 christos res = res + 0x6; /* Value added == 6. */
4311 1.1 christos else if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4312 1.1 christos h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
4313 1.1 christos res = res + 0x6; /* Value added == 6. */
4314 1.1 christos else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) &&
4315 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4316 1.1 christos res = res + 0x60; /* Value added == 60. */
4317 1.1 christos else if (!c && (9 <= (res >> 4) && (res >> 4) <= 15) &&
4318 1.1 christos !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
4319 1.1 christos res = res + 0x66; /* Value added == 66. */
4320 1.1 christos else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) &&
4321 1.1 christos h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
4322 1.1 christos res = res + 0x66; /* Value added == 66. */
4323 1.1 christos else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) &&
4324 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4325 1.1 christos res = res + 0x60; /* Value added == 60. */
4326 1.1 christos else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) &&
4327 1.1 christos !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
4328 1.1 christos res = res + 0x66; /* Value added == 66. */
4329 1.1 christos else if (c && (1 <= (res >> 4) && (res >> 4) <= 3) &&
4330 1.1 christos h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
4331 1.1 christos res = res + 0x66; /* Value added == 66. */
4332 1.1 christos
4333 1.1 christos goto alu8;
4334 1.1 christos
4335 1.1 christos case O (O_DAS, SB):
4336 1.1 christos /* Decimal Adjust Subtraction. This is for BCD arithmetic. */
4337 1.1 christos res = GET_B_REG (code->src.reg); /* FIXME fetch, fetch2... */
4338 1.1 christos if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4339 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4340 1.1 christos res = res; /* Value added == 0. */
4341 1.1 christos else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) &&
4342 1.1 christos h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
4343 1.1 christos res = res + 0xfa; /* Value added == 0xfa. */
4344 1.1 christos else if ( c && (7 <= (res >> 4) && (res >> 4) <= 15) &&
4345 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4346 1.1 christos res = res + 0xa0; /* Value added == 0xa0. */
4347 1.1 christos else if (c && (6 <= (res >> 4) && (res >> 4) <= 15) &&
4348 1.1 christos h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
4349 1.1 christos res = res + 0x9a; /* Value added == 0x9a. */
4350 1.1 christos
4351 1.1 christos goto alu8;
4352 1.1 christos
4353 1.1 christos default:
4354 1.1 christos illegal:
4355 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGILL);
4356 1.1 christos goto end;
4357 1.1 christos
4358 1.1 christos }
4359 1.1 christos
4360 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4361 1.1 christos "sim_resume: internal error.\n");
4362 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGILL);
4363 1.1 christos goto end;
4364 1.1 christos
4365 1.1 christos setc:
4366 1.1 christos if (code->dst.type == X (OP_CCR, SB) ||
4367 1.1 christos code->dst.type == X (OP_CCR, SW))
4368 1.1 christos {
4369 1.1 christos h8_set_ccr (sd, res);
4370 1.1 christos GETSR (sd);
4371 1.1 christos }
4372 1.1 christos else if (h8300smode &&
4373 1.1 christos (code->dst.type == X (OP_EXR, SB) ||
4374 1.1 christos code->dst.type == X (OP_EXR, SW)))
4375 1.1 christos {
4376 1.1 christos h8_set_exr (sd, res);
4377 1.1 christos if (h8300smode) /* Get exr. */
4378 1.1 christos {
4379 1.1 christos trace = (h8_get_exr (sd) >> 7) & 1;
4380 1.1 christos intMask = h8_get_exr (sd) & 7;
4381 1.1 christos }
4382 1.1 christos }
4383 1.1 christos else
4384 1.1 christos goto illegal;
4385 1.1 christos
4386 1.1 christos goto next;
4387 1.1 christos
4388 1.1 christos condtrue:
4389 1.1 christos /* When a branch works */
4390 1.1 christos if (fetch (sd, &code->src, &res))
4391 1.1 christos goto end;
4392 1.1 christos if (res & 1) /* bad address */
4393 1.1 christos goto illegal;
4394 1.1 christos pc = code->next_pc + res;
4395 1.1 christos goto end;
4396 1.1 christos
4397 1.1 christos /* Set the cond codes from res */
4398 1.1 christos bitop:
4399 1.1 christos
4400 1.1 christos /* Set the flags after an 8 bit inc/dec operation */
4401 1.1 christos just_flags_inc8:
4402 1.1 christos n = res & 0x80;
4403 1.1 christos nz = res & 0xff;
4404 1.1 christos v = (rd & 0x7f) == 0x7f;
4405 1.1 christos goto next;
4406 1.1 christos
4407 1.1 christos /* Set the flags after an 16 bit inc/dec operation */
4408 1.1 christos just_flags_inc16:
4409 1.1 christos n = res & 0x8000;
4410 1.1 christos nz = res & 0xffff;
4411 1.1 christos v = (rd & 0x7fff) == 0x7fff;
4412 1.1 christos goto next;
4413 1.1 christos
4414 1.1 christos /* Set the flags after an 32 bit inc/dec operation */
4415 1.1 christos just_flags_inc32:
4416 1.1 christos n = res & 0x80000000;
4417 1.1 christos nz = res & 0xffffffff;
4418 1.1 christos v = (rd & 0x7fffffff) == 0x7fffffff;
4419 1.1 christos goto next;
4420 1.1 christos
4421 1.1 christos shift8:
4422 1.1 christos /* Set flags after an 8 bit shift op, carry,overflow set in insn */
4423 1.1 christos n = (rd & 0x80);
4424 1.1 christos nz = rd & 0xff;
4425 1.1 christos if (store2 (sd, &code->dst, rd))
4426 1.1 christos goto end;
4427 1.1 christos goto next;
4428 1.1 christos
4429 1.1 christos shift16:
4430 1.1 christos /* Set flags after an 16 bit shift op, carry,overflow set in insn */
4431 1.1 christos n = (rd & 0x8000);
4432 1.1 christos nz = rd & 0xffff;
4433 1.1 christos if (store2 (sd, &code->dst, rd))
4434 1.1 christos goto end;
4435 1.1 christos goto next;
4436 1.1 christos
4437 1.1 christos shift32:
4438 1.1 christos /* Set flags after an 32 bit shift op, carry,overflow set in insn */
4439 1.1 christos n = (rd & 0x80000000);
4440 1.1 christos nz = rd & 0xffffffff;
4441 1.1 christos if (store2 (sd, &code->dst, rd))
4442 1.1 christos goto end;
4443 1.1 christos goto next;
4444 1.1 christos
4445 1.1 christos log32:
4446 1.1 christos if (store2 (sd, &code->dst, res))
4447 1.1 christos goto end;
4448 1.1 christos
4449 1.1 christos just_flags_log32:
4450 1.1 christos /* flags after a 32bit logical operation */
4451 1.1 christos n = res & 0x80000000;
4452 1.1 christos nz = res & 0xffffffff;
4453 1.1 christos v = 0;
4454 1.1 christos goto next;
4455 1.1 christos
4456 1.1 christos log16:
4457 1.1 christos if (store2 (sd, &code->dst, res))
4458 1.1 christos goto end;
4459 1.1 christos
4460 1.1 christos just_flags_log16:
4461 1.1 christos /* flags after a 16bit logical operation */
4462 1.1 christos n = res & 0x8000;
4463 1.1 christos nz = res & 0xffff;
4464 1.1 christos v = 0;
4465 1.1 christos goto next;
4466 1.1 christos
4467 1.1 christos log8:
4468 1.1 christos if (store2 (sd, &code->dst, res))
4469 1.1 christos goto end;
4470 1.1 christos
4471 1.1 christos just_flags_log8:
4472 1.1 christos n = res & 0x80;
4473 1.1 christos nz = res & 0xff;
4474 1.1 christos v = 0;
4475 1.1 christos goto next;
4476 1.1 christos
4477 1.1 christos alu8:
4478 1.1 christos if (store2 (sd, &code->dst, res))
4479 1.1 christos goto end;
4480 1.1 christos
4481 1.1 christos just_flags_alu8:
4482 1.1 christos n = res & 0x80;
4483 1.1 christos nz = res & 0xff;
4484 1.1 christos c = (res & 0x100);
4485 1.1 christos switch (code->opcode / 4)
4486 1.1 christos {
4487 1.1 christos case O_ADD:
4488 1.1 christos case O_ADDX:
4489 1.1 christos v = ((rd & 0x80) == (ea & 0x80)
4490 1.1 christos && (rd & 0x80) != (res & 0x80));
4491 1.1 christos break;
4492 1.1 christos case O_SUB:
4493 1.1 christos case O_SUBX:
4494 1.1 christos case O_CMP:
4495 1.1 christos v = ((rd & 0x80) != (-ea & 0x80)
4496 1.1 christos && (rd & 0x80) != (res & 0x80));
4497 1.1 christos break;
4498 1.1 christos case O_NEG:
4499 1.1 christos v = (rd == 0x80);
4500 1.1 christos break;
4501 1.1 christos case O_DAA:
4502 1.1 christos case O_DAS:
4503 1.1 christos break; /* No effect on v flag. */
4504 1.1 christos }
4505 1.1 christos goto next;
4506 1.1 christos
4507 1.1 christos alu16:
4508 1.1 christos if (store2 (sd, &code->dst, res))
4509 1.1 christos goto end;
4510 1.1 christos
4511 1.1 christos just_flags_alu16:
4512 1.1 christos n = res & 0x8000;
4513 1.1 christos nz = res & 0xffff;
4514 1.1 christos c = (res & 0x10000);
4515 1.1 christos switch (code->opcode / 4)
4516 1.1 christos {
4517 1.1 christos case O_ADD:
4518 1.1 christos case O_ADDX:
4519 1.1 christos v = ((rd & 0x8000) == (ea & 0x8000)
4520 1.1 christos && (rd & 0x8000) != (res & 0x8000));
4521 1.1 christos break;
4522 1.1 christos case O_SUB:
4523 1.1 christos case O_SUBX:
4524 1.1 christos case O_CMP:
4525 1.1 christos v = ((rd & 0x8000) != (-ea & 0x8000)
4526 1.1 christos && (rd & 0x8000) != (res & 0x8000));
4527 1.1 christos break;
4528 1.1 christos case O_NEG:
4529 1.1 christos v = (rd == 0x8000);
4530 1.1 christos break;
4531 1.1 christos }
4532 1.1 christos goto next;
4533 1.1 christos
4534 1.1 christos alu32:
4535 1.1 christos if (store2 (sd, &code->dst, res))
4536 1.1 christos goto end;
4537 1.1 christos
4538 1.1 christos just_flags_alu32:
4539 1.1 christos n = res & 0x80000000;
4540 1.1 christos nz = res & 0xffffffff;
4541 1.1 christos switch (code->opcode / 4)
4542 1.1 christos {
4543 1.1 christos case O_ADD:
4544 1.1 christos case O_ADDX:
4545 1.1 christos v = ((rd & 0x80000000) == (ea & 0x80000000)
4546 1.1 christos && (rd & 0x80000000) != (res & 0x80000000));
4547 1.1 christos c = ((unsigned) res < (unsigned) rd) ||
4548 1.1 christos ((unsigned) res < (unsigned) ea);
4549 1.1 christos break;
4550 1.1 christos case O_SUB:
4551 1.1 christos case O_SUBX:
4552 1.1 christos case O_CMP:
4553 1.1 christos v = ((rd & 0x80000000) != (-ea & 0x80000000)
4554 1.1 christos && (rd & 0x80000000) != (res & 0x80000000));
4555 1.1 christos c = (unsigned) rd < (unsigned) -ea;
4556 1.1 christos break;
4557 1.1 christos case O_NEG:
4558 1.1 christos v = (rd == 0x80000000);
4559 1.1 christos c = res != 0;
4560 1.1 christos break;
4561 1.1 christos }
4562 1.1 christos goto next;
4563 1.1 christos
4564 1.1 christos next:
4565 1.1 christos if ((res = h8_get_delayed_branch (sd)) != 0)
4566 1.1 christos {
4567 1.1 christos pc = res;
4568 1.1 christos h8_set_delayed_branch (sd, 0);
4569 1.1 christos }
4570 1.1 christos else
4571 1.1 christos pc = code->next_pc;
4572 1.1 christos
4573 1.1 christos end:
4574 1.1 christos
4575 1.1 christos if (--poll_count < 0)
4576 1.1 christos {
4577 1.1 christos poll_count = POLL_QUIT_INTERVAL;
4578 1.1 christos if ((*sim_callback->poll_quit) != NULL
4579 1.1 christos && (*sim_callback->poll_quit) (sim_callback))
4580 1.1 christos sim_engine_set_run_state (sd, sim_stopped, SIGINT);
4581 1.1 christos }
4582 1.1 christos sim_engine_get_run_state (sd, &reason, &sigrc);
4583 1.1 christos } while (reason == sim_running);
4584 1.1 christos
4585 1.1 christos h8_set_ticks (sd, h8_get_ticks (sd) + get_now () - tick_start);
4586 1.1 christos h8_set_cycles (sd, h8_get_cycles (sd) + cycles);
4587 1.1 christos h8_set_insts (sd, h8_get_insts (sd) + insts);
4588 1.1 christos h8_set_pc (sd, pc);
4589 1.1 christos BUILDSR (sd);
4590 1.1 christos
4591 1.1 christos if (h8300smode)
4592 1.1 christos h8_set_exr (sd, (trace<<7) | intMask);
4593 1.1 christos
4594 1.1 christos h8_set_mask (sd, oldmask);
4595 1.1 christos }
4596 1.1 christos
4597 1.1 christos int
4598 1.1 christos sim_trace (SIM_DESC sd)
4599 1.1 christos {
4600 1.1 christos /* FIXME: Unfinished. */
4601 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4602 1.1 christos "sim_trace: trace not supported.\n");
4603 1.1 christos return 1; /* Done. */
4604 1.1 christos }
4605 1.1 christos
4606 1.1 christos int
4607 1.1 christos sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
4608 1.1 christos {
4609 1.1 christos int i;
4610 1.1 christos
4611 1.1 christos init_pointers (sd);
4612 1.1 christos if (addr < 0)
4613 1.1 christos return 0;
4614 1.1 christos for (i = 0; i < size; i++)
4615 1.1 christos {
4616 1.1 christos if (addr < memory_size)
4617 1.1 christos {
4618 1.1 christos h8_set_memory (sd, addr + i, buffer[i]);
4619 1.1 christos h8_set_cache_idx (sd, addr + i, 0);
4620 1.1 christos }
4621 1.1 christos else
4622 1.1 christos {
4623 1.1 christos h8_set_eightbit (sd, (addr + i) & 0xff, buffer[i]);
4624 1.1 christos }
4625 1.1 christos }
4626 1.1 christos return size;
4627 1.1 christos }
4628 1.1 christos
4629 1.1 christos int
4630 1.1 christos sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
4631 1.1 christos {
4632 1.1 christos init_pointers (sd);
4633 1.1 christos if (addr < 0)
4634 1.1 christos return 0;
4635 1.1 christos if (addr < memory_size)
4636 1.1 christos memcpy (buffer, h8_get_memory_buf (sd) + addr, size);
4637 1.1 christos else
4638 1.1 christos memcpy (buffer, h8_get_eightbit_buf (sd) + (addr & 0xff), size);
4639 1.1 christos return size;
4640 1.1 christos }
4641 1.1 christos
4642 1.1 christos
4643 1.1 christos int
4644 1.1 christos sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
4645 1.1 christos {
4646 1.1 christos int longval;
4647 1.1 christos int shortval;
4648 1.1 christos int intval;
4649 1.1 christos longval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
4650 1.1 christos shortval = (value[0] << 8) | (value[1]);
4651 1.1 christos intval = h8300hmode ? longval : shortval;
4652 1.1 christos
4653 1.1 christos init_pointers (sd);
4654 1.1 christos switch (rn)
4655 1.1 christos {
4656 1.1 christos case PC_REGNUM:
4657 1.1 christos if(h8300_normal_mode)
4658 1.1 christos h8_set_pc (sd, shortval); /* PC for Normal mode is 2 bytes */
4659 1.1 christos else
4660 1.1 christos h8_set_pc (sd, intval);
4661 1.1 christos break;
4662 1.1 christos default:
4663 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4664 1.1 christos "sim_store_register: bad regnum %d.\n",
4665 1.1 christos rn);
4666 1.1 christos case R0_REGNUM:
4667 1.1 christos case R1_REGNUM:
4668 1.1 christos case R2_REGNUM:
4669 1.1 christos case R3_REGNUM:
4670 1.1 christos case R4_REGNUM:
4671 1.1 christos case R5_REGNUM:
4672 1.1 christos case R6_REGNUM:
4673 1.1 christos case R7_REGNUM:
4674 1.1 christos h8_set_reg (sd, rn, intval);
4675 1.1 christos break;
4676 1.1 christos case CCR_REGNUM:
4677 1.1 christos h8_set_ccr (sd, intval);
4678 1.1 christos break;
4679 1.1 christos case EXR_REGNUM:
4680 1.1 christos h8_set_exr (sd, intval);
4681 1.1 christos break;
4682 1.1 christos case SBR_REGNUM:
4683 1.1 christos h8_set_sbr (sd, intval);
4684 1.1 christos break;
4685 1.1 christos case VBR_REGNUM:
4686 1.1 christos h8_set_vbr (sd, intval);
4687 1.1 christos break;
4688 1.1 christos case MACH_REGNUM:
4689 1.1 christos h8_set_mach (sd, intval);
4690 1.1 christos break;
4691 1.1 christos case MACL_REGNUM:
4692 1.1 christos h8_set_macl (sd, intval);
4693 1.1 christos break;
4694 1.1 christos case CYCLE_REGNUM:
4695 1.1 christos h8_set_cycles (sd, longval);
4696 1.1 christos break;
4697 1.1 christos
4698 1.1 christos case INST_REGNUM:
4699 1.1 christos h8_set_insts (sd, longval);
4700 1.1 christos break;
4701 1.1 christos
4702 1.1 christos case TICK_REGNUM:
4703 1.1 christos h8_set_ticks (sd, longval);
4704 1.1 christos break;
4705 1.1 christos }
4706 1.1 christos return length;
4707 1.1 christos }
4708 1.1 christos
4709 1.1 christos int
4710 1.1 christos sim_fetch_register (SIM_DESC sd, int rn, unsigned char *buf, int length)
4711 1.1 christos {
4712 1.1 christos int v;
4713 1.1 christos int longreg = 0;
4714 1.1 christos
4715 1.1 christos init_pointers (sd);
4716 1.1 christos
4717 1.1 christos if (!h8300smode && rn >= EXR_REGNUM)
4718 1.1 christos rn++;
4719 1.1 christos switch (rn)
4720 1.1 christos {
4721 1.1 christos default:
4722 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4723 1.1 christos "sim_fetch_register: bad regnum %d.\n",
4724 1.1 christos rn);
4725 1.1 christos v = 0;
4726 1.1 christos break;
4727 1.1 christos case CCR_REGNUM:
4728 1.1 christos v = h8_get_ccr (sd);
4729 1.1 christos break;
4730 1.1 christos case EXR_REGNUM:
4731 1.1 christos v = h8_get_exr (sd);
4732 1.1 christos break;
4733 1.1 christos case PC_REGNUM:
4734 1.1 christos v = h8_get_pc (sd);
4735 1.1 christos break;
4736 1.1 christos case SBR_REGNUM:
4737 1.1 christos v = h8_get_sbr (sd);
4738 1.1 christos break;
4739 1.1 christos case VBR_REGNUM:
4740 1.1 christos v = h8_get_vbr (sd);
4741 1.1 christos break;
4742 1.1 christos case MACH_REGNUM:
4743 1.1 christos v = h8_get_mach (sd);
4744 1.1 christos break;
4745 1.1 christos case MACL_REGNUM:
4746 1.1 christos v = h8_get_macl (sd);
4747 1.1 christos break;
4748 1.1 christos case R0_REGNUM:
4749 1.1 christos case R1_REGNUM:
4750 1.1 christos case R2_REGNUM:
4751 1.1 christos case R3_REGNUM:
4752 1.1 christos case R4_REGNUM:
4753 1.1 christos case R5_REGNUM:
4754 1.1 christos case R6_REGNUM:
4755 1.1 christos case R7_REGNUM:
4756 1.1 christos v = h8_get_reg (sd, rn);
4757 1.1 christos break;
4758 1.1 christos case CYCLE_REGNUM:
4759 1.1 christos v = h8_get_cycles (sd);
4760 1.1 christos longreg = 1;
4761 1.1 christos break;
4762 1.1 christos case TICK_REGNUM:
4763 1.1 christos v = h8_get_ticks (sd);
4764 1.1 christos longreg = 1;
4765 1.1 christos break;
4766 1.1 christos case INST_REGNUM:
4767 1.1 christos v = h8_get_insts (sd);
4768 1.1 christos longreg = 1;
4769 1.1 christos break;
4770 1.1 christos }
4771 1.1 christos /* In Normal mode PC is 2 byte, but other registers are 4 byte */
4772 1.1 christos if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode))
4773 1.1 christos {
4774 1.1 christos buf[0] = v >> 24;
4775 1.1 christos buf[1] = v >> 16;
4776 1.1 christos buf[2] = v >> 8;
4777 1.1 christos buf[3] = v >> 0;
4778 1.1 christos }
4779 1.1 christos else
4780 1.1 christos {
4781 1.1 christos buf[0] = v >> 8;
4782 1.1 christos buf[1] = v;
4783 1.1 christos }
4784 1.1 christos return -1;
4785 1.1 christos }
4786 1.1 christos
4787 1.1 christos void
4788 1.1 christos sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
4789 1.1 christos {
4790 1.1 christos sim_engine_get_run_state (sd, reason, sigrc);
4791 1.1 christos }
4792 1.1 christos
4793 1.1 christos /* FIXME: Rename to sim_set_mem_size. */
4794 1.1 christos
4795 1.1 christos void
4796 1.1 christos sim_size (int n)
4797 1.1 christos {
4798 1.1 christos /* Memory size is fixed. */
4799 1.1 christos }
4800 1.1 christos
4801 1.1 christos static void
4802 1.1 christos set_simcache_size (SIM_DESC sd, int n)
4803 1.1 christos {
4804 1.1 christos if (sd->sim_cache)
4805 1.1 christos free (sd->sim_cache);
4806 1.1 christos if (n < 2)
4807 1.1 christos n = 2;
4808 1.1 christos sd->sim_cache = (decoded_inst *) malloc (sizeof (decoded_inst) * n);
4809 1.1 christos memset (sd->sim_cache, 0, sizeof (decoded_inst) * n);
4810 1.1 christos sd->sim_cache_size = n;
4811 1.1 christos }
4812 1.1 christos
4813 1.1 christos
4814 1.1 christos void
4815 1.1 christos sim_info (SIM_DESC sd, int verbose)
4816 1.1 christos {
4817 1.1 christos double timetaken = (double) h8_get_ticks (sd) / (double) now_persec ();
4818 1.1 christos double virttime = h8_get_cycles (sd) / 10.0e6;
4819 1.1 christos
4820 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4821 1.1 christos "\n\n#instructions executed %10d\n",
4822 1.1 christos h8_get_insts (sd));
4823 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4824 1.1 christos "#cycles (v approximate) %10d\n",
4825 1.1 christos h8_get_cycles (sd));
4826 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4827 1.1 christos "#real time taken %10.4f\n",
4828 1.1 christos timetaken);
4829 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4830 1.1 christos "#virtual time taken %10.4f\n",
4831 1.1 christos virttime);
4832 1.1 christos if (timetaken != 0.0)
4833 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4834 1.1 christos "#simulation ratio %10.4f\n",
4835 1.1 christos virttime / timetaken);
4836 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4837 1.1 christos "#compiles %10d\n",
4838 1.1 christos h8_get_compiles (sd));
4839 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
4840 1.1 christos "#cache size %10d\n",
4841 1.1 christos sd->sim_cache_size);
4842 1.1 christos
4843 1.1 christos #ifdef ADEBUG
4844 1.1 christos /* This to be conditional on `what' (aka `verbose'),
4845 1.1 christos however it was never passed as non-zero. */
4846 1.1 christos if (1)
4847 1.1 christos {
4848 1.1 christos int i;
4849 1.1 christos for (i = 0; i < O_LAST; i++)
4850 1.1 christos {
4851 1.1 christos if (h8_get_stats (sd, i))
4852 1.1 christos (*sim_callback->printf_filtered) (sim_callback, "%d: %d\n",
4853 1.1 christos i, h8_get_stats (sd, i));
4854 1.1 christos }
4855 1.1 christos }
4856 1.1 christos #endif
4857 1.1 christos }
4858 1.1 christos
4859 1.1 christos /* Indicate whether the cpu is an H8/300 or H8/300H.
4860 1.1 christos FLAG is non-zero for the H8/300H. */
4861 1.1 christos
4862 1.1 christos void
4863 1.1 christos set_h8300h (unsigned long machine)
4864 1.1 christos {
4865 1.1 christos /* FIXME: Much of the code in sim_load can be moved to sim_open.
4866 1.1 christos This function being replaced by a sim_open:ARGV configuration
4867 1.1 christos option. */
4868 1.1 christos
4869 1.1 christos h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0;
4870 1.1 christos
4871 1.1 christos if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
4872 1.1 christos h8300sxmode = 1;
4873 1.1 christos
4874 1.1 christos if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode)
4875 1.1 christos h8300smode = 1;
4876 1.1 christos
4877 1.1 christos if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode)
4878 1.1 christos h8300hmode = 1;
4879 1.1 christos
4880 1.1 christos if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn)
4881 1.1 christos h8300_normal_mode = 1;
4882 1.1 christos }
4883 1.1 christos
4884 1.1 christos /* Cover function of sim_state_free to free the cpu buffers as well. */
4885 1.1 christos
4886 1.1 christos static void
4887 1.1 christos free_state (SIM_DESC sd)
4888 1.1 christos {
4889 1.1 christos if (STATE_MODULES (sd) != NULL)
4890 1.1 christos sim_module_uninstall (sd);
4891 1.1 christos
4892 1.1 christos /* Fixme: free buffers in _sim_cpu. */
4893 1.1 christos sim_state_free (sd);
4894 1.1 christos }
4895 1.1 christos
4896 1.1 christos SIM_DESC
4897 1.1 christos sim_open (SIM_OPEN_KIND kind,
4898 1.1 christos struct host_callback_struct *callback,
4899 1.1 christos struct bfd *abfd,
4900 1.1 christos char **argv)
4901 1.1 christos {
4902 1.1 christos SIM_DESC sd;
4903 1.1 christos sim_cpu *cpu;
4904 1.1 christos
4905 1.1 christos sd = sim_state_alloc (kind, callback);
4906 1.1 christos sd->cpu = sim_cpu_alloc (sd, 0);
4907 1.1 christos cpu = STATE_CPU (sd, 0);
4908 1.1 christos SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
4909 1.1 christos sim_state_initialize (sd, cpu);
4910 1.1 christos /* sim_cpu object is new, so some initialization is needed. */
4911 1.1 christos init_pointers_needed = 1;
4912 1.1 christos
4913 1.1 christos /* For compatibility (FIXME: is this right?). */
4914 1.1 christos current_alignment = NONSTRICT_ALIGNMENT;
4915 1.1 christos current_target_byte_order = BIG_ENDIAN;
4916 1.1 christos
4917 1.1 christos if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
4918 1.1 christos {
4919 1.1 christos free_state (sd);
4920 1.1 christos return 0;
4921 1.1 christos }
4922 1.1 christos
4923 1.1 christos /* getopt will print the error message so we just have to exit if
4924 1.1 christos this fails. FIXME: Hmmm... in the case of gdb we need getopt
4925 1.1 christos to call print_filtered. */
4926 1.1 christos if (sim_parse_args (sd, argv) != SIM_RC_OK)
4927 1.1 christos {
4928 1.1 christos /* Uninstall the modules to avoid memory leaks,
4929 1.1 christos file descriptor leaks, etc. */
4930 1.1 christos free_state (sd);
4931 1.1 christos return 0;
4932 1.1 christos }
4933 1.1 christos
4934 1.1 christos /* Check for/establish the a reference program image. */
4935 1.1 christos if (sim_analyze_program (sd,
4936 1.1 christos (STATE_PROG_ARGV (sd) != NULL
4937 1.1 christos ? *STATE_PROG_ARGV (sd)
4938 1.1 christos : NULL), abfd) != SIM_RC_OK)
4939 1.1 christos {
4940 1.1 christos free_state (sd);
4941 1.1 christos return 0;
4942 1.1 christos }
4943 1.1 christos
4944 1.1 christos /* Establish any remaining configuration options. */
4945 1.1 christos if (sim_config (sd) != SIM_RC_OK)
4946 1.1 christos {
4947 1.1 christos free_state (sd);
4948 1.1 christos return 0;
4949 1.1 christos }
4950 1.1 christos
4951 1.1 christos if (sim_post_argv_init (sd) != SIM_RC_OK)
4952 1.1 christos {
4953 1.1 christos /* Uninstall the modules to avoid memory leaks,
4954 1.1 christos file descriptor leaks, etc. */
4955 1.1 christos free_state (sd);
4956 1.1 christos return 0;
4957 1.1 christos }
4958 1.1 christos
4959 1.1 christos /* sim_hw_configure (sd); */
4960 1.1 christos
4961 1.1 christos /* FIXME: Much of the code in sim_load can be moved here. */
4962 1.1 christos
4963 1.1 christos sim_kind = kind;
4964 1.1 christos myname = argv[0];
4965 1.1 christos sim_callback = callback;
4966 1.1 christos return sd;
4967 1.1 christos }
4968 1.1 christos
4969 1.1 christos void
4970 1.1 christos sim_close (SIM_DESC sd, int quitting)
4971 1.1 christos {
4972 1.1 christos /* Nothing to do. */
4973 1.1 christos }
4974 1.1 christos
4975 1.1 christos /* Called by gdb to load a program into memory. */
4976 1.1 christos
4977 1.1 christos SIM_RC
4978 1.1.1.2 christos sim_load (SIM_DESC sd, const char *prog, bfd *abfd, int from_tty)
4979 1.1 christos {
4980 1.1 christos bfd *prog_bfd;
4981 1.1 christos
4982 1.1 christos /* FIXME: The code below that sets a specific variant of the H8/300
4983 1.1 christos being simulated should be moved to sim_open(). */
4984 1.1 christos
4985 1.1 christos /* See if the file is for the H8/300 or H8/300H. */
4986 1.1 christos /* ??? This may not be the most efficient way. The z8k simulator
4987 1.1 christos does this via a different mechanism (INIT_EXTRA_SYMTAB_INFO). */
4988 1.1 christos if (abfd != NULL)
4989 1.1 christos prog_bfd = abfd;
4990 1.1 christos else
4991 1.1 christos prog_bfd = bfd_openr (prog, NULL);
4992 1.1 christos if (prog_bfd != NULL)
4993 1.1 christos {
4994 1.1 christos /* Set the cpu type. We ignore failure from bfd_check_format
4995 1.1 christos and bfd_openr as sim_load_file checks too. */
4996 1.1 christos if (bfd_check_format (prog_bfd, bfd_object))
4997 1.1 christos {
4998 1.1 christos set_h8300h (bfd_get_mach (prog_bfd));
4999 1.1 christos }
5000 1.1 christos }
5001 1.1 christos
5002 1.1 christos /* If we're using gdb attached to the simulator, then we have to
5003 1.1 christos reallocate memory for the simulator.
5004 1.1 christos
5005 1.1 christos When gdb first starts, it calls fetch_registers (among other
5006 1.1 christos functions), which in turn calls init_pointers, which allocates
5007 1.1 christos simulator memory.
5008 1.1 christos
5009 1.1 christos The problem is when we do that, we don't know whether we're
5010 1.1 christos debugging an H8/300 or H8/300H program.
5011 1.1 christos
5012 1.1 christos This is the first point at which we can make that determination,
5013 1.1 christos so we just reallocate memory now; this will also allow us to handle
5014 1.1 christos switching between H8/300 and H8/300H programs without exiting
5015 1.1 christos gdb. */
5016 1.1 christos
5017 1.1 christos if (h8300smode && !h8300_normal_mode)
5018 1.1 christos memory_size = H8300S_MSIZE;
5019 1.1 christos else if (h8300hmode && !h8300_normal_mode)
5020 1.1 christos memory_size = H8300H_MSIZE;
5021 1.1 christos else
5022 1.1 christos memory_size = H8300_MSIZE;
5023 1.1 christos
5024 1.1 christos if (h8_get_memory_buf (sd))
5025 1.1 christos free (h8_get_memory_buf (sd));
5026 1.1 christos if (h8_get_cache_idx_buf (sd))
5027 1.1 christos free (h8_get_cache_idx_buf (sd));
5028 1.1 christos if (h8_get_eightbit_buf (sd))
5029 1.1 christos free (h8_get_eightbit_buf (sd));
5030 1.1 christos
5031 1.1 christos h8_set_memory_buf (sd, (unsigned char *)
5032 1.1 christos calloc (sizeof (char), memory_size));
5033 1.1 christos h8_set_cache_idx_buf (sd, (unsigned short *)
5034 1.1 christos calloc (sizeof (short), memory_size));
5035 1.1 christos sd->memory_size = memory_size;
5036 1.1 christos h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
5037 1.1 christos
5038 1.1 christos /* `msize' must be a power of two. */
5039 1.1 christos if ((memory_size & (memory_size - 1)) != 0)
5040 1.1 christos {
5041 1.1 christos (*sim_callback->printf_filtered) (sim_callback,
5042 1.1 christos "sim_load: bad memory size.\n");
5043 1.1 christos return SIM_RC_FAIL;
5044 1.1 christos }
5045 1.1 christos h8_set_mask (sd, memory_size - 1);
5046 1.1 christos
5047 1.1 christos if (sim_load_file (sd, myname, sim_callback, prog, prog_bfd,
5048 1.1 christos sim_kind == SIM_OPEN_DEBUG,
5049 1.1 christos 0, sim_write)
5050 1.1 christos == NULL)
5051 1.1 christos {
5052 1.1 christos /* Close the bfd if we opened it. */
5053 1.1 christos if (abfd == NULL && prog_bfd != NULL)
5054 1.1 christos bfd_close (prog_bfd);
5055 1.1 christos return SIM_RC_FAIL;
5056 1.1 christos }
5057 1.1 christos
5058 1.1 christos /* Close the bfd if we opened it. */
5059 1.1 christos if (abfd == NULL && prog_bfd != NULL)
5060 1.1 christos bfd_close (prog_bfd);
5061 1.1 christos return SIM_RC_OK;
5062 1.1 christos }
5063 1.1 christos
5064 1.1 christos SIM_RC
5065 1.1 christos sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
5066 1.1 christos {
5067 1.1 christos int i = 0;
5068 1.1 christos int len_arg = 0;
5069 1.1 christos int no_of_args = 0;
5070 1.1 christos
5071 1.1 christos if (abfd != NULL)
5072 1.1 christos h8_set_pc (sd, bfd_get_start_address (abfd));
5073 1.1 christos else
5074 1.1 christos h8_set_pc (sd, 0);
5075 1.1 christos
5076 1.1 christos /* Command Line support. */
5077 1.1 christos if (argv != NULL)
5078 1.1 christos {
5079 1.1 christos /* Counting the no. of commandline arguments. */
5080 1.1 christos for (no_of_args = 0; argv[no_of_args] != NULL; no_of_args++)
5081 1.1 christos continue;
5082 1.1 christos
5083 1.1 christos /* Allocating memory for the argv pointers. */
5084 1.1 christos h8_set_command_line (sd, (char **) malloc ((sizeof (char *))
5085 1.1 christos * (no_of_args + 1)));
5086 1.1 christos
5087 1.1 christos for (i = 0; i < no_of_args; i++)
5088 1.1 christos {
5089 1.1 christos /* Copying the argument string. */
5090 1.1 christos h8_set_cmdline_arg (sd, i, (char *) strdup (argv[i]));
5091 1.1 christos }
5092 1.1 christos h8_set_cmdline_arg (sd, i, NULL);
5093 1.1 christos }
5094 1.1 christos
5095 1.1 christos return SIM_RC_OK;
5096 1.1 christos }
5097 1.1 christos
5098 1.1 christos void
5099 1.1 christos sim_set_callbacks (struct host_callback_struct *ptr)
5100 1.1 christos {
5101 1.1 christos sim_callback = ptr;
5102 1.1 christos }
5103