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