]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/h8300/compile.c
2003-06-03 Michael Snyder <msnyder@redhat.com>
[thirdparty/binutils-gdb.git] / sim / h8300 / compile.c
CommitLineData
c906108c
SS
1/*
2 * Simulator for the Hitachi H8/300 architecture.
3 *
4 * Written by Steve Chamberlain of Cygnus Support. sac@cygnus.com
5 *
6 * This file is part of H8/300 sim
7 *
8 *
9 * THIS SOFTWARE IS NOT COPYRIGHTED
10 *
11 * Cygnus offers the following for use in the public domain. Cygnus makes no
12 * warranty with regard to the software or its performance and the user
13 * accepts the software "AS IS" with all faults.
14 *
15 * CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS
16 * SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE.
18 */
19
20#include "config.h"
21
22#include <stdio.h>
23#include <signal.h>
24#ifdef HAVE_TIME_H
25#include <time.h>
26#endif
27#ifdef HAVE_STDLIB_H
28#include <stdlib.h>
29#endif
30#ifdef HAVE_SYS_PARAM_H
31#include <sys/param.h>
32#endif
c906108c
SS
33#include "ansidecl.h"
34#include "bfd.h"
3c25f8c7
AC
35#include "gdb/callback.h"
36#include "gdb/remote-sim.h"
a64bfde3 37#include "gdb/sim-h8300.h"
bf174226
V
38#include "sys/stat.h"
39#include "sys/types.h"
c906108c
SS
40
41#ifndef SIGTRAP
42# define SIGTRAP 5
43#endif
44
45int debug;
46
47host_callback *sim_callback;
48
49static SIM_OPEN_KIND sim_kind;
50static char *myname;
51
52/* FIXME: Needs to live in header file.
53 This header should also include the things in remote-sim.h.
54 One could move this to remote-sim.h but this function isn't needed
55 by gdb. */
56void sim_set_simcache_size PARAMS ((int));
57
de9b1892 58#define X(op, size) op * 4 + size
c906108c 59
de9b1892 60#define SP (h8300hmode ? SL : SW)
c906108c
SS
61#define SB 0
62#define SW 1
63#define SL 2
64#define OP_REG 1
65#define OP_DEC 2
66#define OP_DISP 3
67#define OP_INC 4
68#define OP_PCREL 5
69#define OP_MEM 6
70#define OP_CCR 7
71#define OP_IMM 8
72#define OP_ABS 10
fc974602 73#define OP_EXR 11
c906108c
SS
74#define h8_opcodes ops
75#define DEFINE_TABLE
76#include "opcode/h8300.h"
77
78#include "inst.h"
79
0ef9643e 80/* The rate at which to call the host's poll_quit callback. */
7a292a7a
SS
81
82#define POLL_QUIT_INTERVAL 0x80000
83
c906108c 84#define LOW_BYTE(x) ((x) & 0xff)
de9b1892
KH
85#define HIGH_BYTE(x) (((x) >> 8) & 0xff)
86#define P(X,Y) ((X << 8) | Y)
c906108c 87
d0fe2f7e
KH
88#define BUILDSR() \
89 cpu.ccr = ((I << 7) | (UI << 6) | (H << 5) | (U << 4) \
90 | (N << 3) | (Z << 2) | (V << 1) | C);
c906108c 91
fc974602 92#define BUILDEXR() \
d1335144 93 if (h8300smode) cpu.exr = (trace<<7) | intMask;
fc974602 94
c906108c
SS
95#define GETSR() \
96 c = (cpu.ccr >> 0) & 1;\
97 v = (cpu.ccr >> 1) & 1;\
98 nz = !((cpu.ccr >> 2) & 1);\
f6225c96
AV
99 n = (cpu.ccr >> 3) & 1;\
100 u = (cpu.ccr >> 4) & 1;\
101 h = (cpu.ccr >> 5) & 1;\
102 ui = ((cpu.ccr >> 6) & 1);\
103 intMaskBit = (cpu.ccr >> 7) & 1;
c906108c 104
d0fe2f7e
KH
105#define GETEXR() \
106 if (h8300smode) \
107 { \
108 trace = (cpu.exr >> 7) & 1; \
109 intMask = cpu.exr & 7; \
110 }
fc974602 111
c906108c 112#ifdef __CHAR_IS_SIGNED__
de9b1892 113#define SEXTCHAR(x) ((char) (x))
c906108c
SS
114#endif
115
116#ifndef SEXTCHAR
d0fe2f7e 117#define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff) : x & 0xff)
c906108c
SS
118#endif
119
120#define UEXTCHAR(x) ((x) & 0xff)
121#define UEXTSHORT(x) ((x) & 0xffff)
de9b1892 122#define SEXTSHORT(x) ((short) (x))
c906108c
SS
123
124static cpu_state_type cpu;
125
126int h8300hmode = 0;
127int h8300smode = 0;
128
129static int memory_size;
130
c906108c 131static int
a4f27e3e 132get_now (void)
c906108c 133{
3b02cf92 134 return time (0); /* WinXX HAS UNIX like 'time', so why not using it? */
c906108c
SS
135}
136
137static int
a4f27e3e 138now_persec (void)
c906108c
SS
139{
140 return 1;
141}
142
c906108c 143static int
a4f27e3e 144bitfrom (int x)
c906108c
SS
145{
146 switch (x & SIZE)
147 {
148 case L_8:
149 return SB;
150 case L_16:
151 return SW;
152 case L_32:
153 return SL;
154 case L_P:
155 return h8300hmode ? SL : SW;
156 }
157}
158
0ef9643e 159static unsigned int
a4f27e3e 160lvalue (int x, int rn)
c906108c
SS
161{
162 switch (x / 4)
163 {
164 case OP_DISP:
165 if (rn == 8)
166 {
167 return X (OP_IMM, SP);
168 }
169 return X (OP_REG, SP);
170
171 case OP_MEM:
c906108c 172 return X (OP_MEM, SP);
0ef9643e 173
c906108c 174 default:
3b02cf92 175 abort (); /* ?? May be something more usefull? */
c906108c
SS
176 }
177}
178
d1360fb0
V
179static int
180cmdline_location()
181{
182 if (h8300smode)
183 return 0xffff00L;
184 else if (h8300hmode)
185 return 0x2ff00L;
186 else
187 return 0xff00L;
188}
189
c906108c 190static unsigned int
a4f27e3e 191decode (int addr, unsigned char *data, decoded_inst *dst)
c906108c
SS
192{
193 int rs = 0;
194 int rd = 0;
195 int rdisp = 0;
196 int abs = 0;
c906108c 197 int bit = 0;
0ef9643e 198 int plen = 0;
6d028502 199 struct h8_opcode *q;
c906108c 200 int size = 0;
0ef9643e 201
c906108c
SS
202 dst->dst.type = -1;
203 dst->src.type = -1;
0ef9643e
JL
204
205 /* Find the exact opcode/arg combo. */
6d028502 206 for (q = h8_opcodes; q->name; q++)
c906108c 207 {
6d028502 208 op_type *nib = q->data.nib;
c906108c
SS
209 unsigned int len = 0;
210
c906108c
SS
211 while (1)
212 {
213 op_type looking_for = *nib;
214 int thisnib = data[len >> 1];
215
216 thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
217
218 if (looking_for < 16 && looking_for >= 0)
219 {
220 if (looking_for != thisnib)
221 goto fail;
222 }
223 else
224 {
225 if ((int) looking_for & (int) B31)
226 {
227 if (!(((int) thisnib & 0x8) != 0))
228 goto fail;
0ef9643e
JL
229
230 looking_for = (op_type) ((int) looking_for & ~(int) B31);
c906108c
SS
231 thisnib &= 0x7;
232 }
0ef9643e 233
c906108c
SS
234 if ((int) looking_for & (int) B30)
235 {
236 if (!(((int) thisnib & 0x8) == 0))
237 goto fail;
0ef9643e 238
c906108c
SS
239 looking_for = (op_type) ((int) looking_for & ~(int) B30);
240 }
0ef9643e 241
c906108c
SS
242 if (looking_for & DBIT)
243 {
0a17cd59
AC
244 /* Exclude adds/subs by looking at bit 0 and 2, and
245 make sure the operand size, either w or l,
246 matches by looking at bit 1. */
247 if ((looking_for & 7) != (thisnib & 7))
c906108c 248 goto fail;
0ef9643e 249
c906108c
SS
250 abs = (thisnib & 0x8) ? 2 : 1;
251 }
252 else if (looking_for & (REG | IND | INC | DEC))
253 {
254 if (looking_for & REG)
255 {
0ef9643e 256 /* Can work out size from the register. */
c906108c
SS
257 size = bitfrom (looking_for);
258 }
259 if (looking_for & SRC)
0ef9643e 260 rs = thisnib;
c906108c 261 else
0ef9643e 262 rd = thisnib;
c906108c
SS
263 }
264 else if (looking_for & L_16)
265 {
266 abs = (data[len >> 1]) * 256 + data[(len + 2) >> 1];
267 plen = 16;
268 if (looking_for & (PCREL | DISP))
269 {
270 abs = (short) (abs);
271 }
272 }
273 else if (looking_for & ABSJMP)
274 {
0ef9643e 275 abs = (data[1] << 16) | (data[2] << 8) | (data[3]);
c906108c
SS
276 }
277 else if (looking_for & MEMIND)
278 {
279 abs = data[1];
280 }
281 else if (looking_for & L_32)
282 {
283 int i = len >> 1;
0ef9643e 284
c906108c
SS
285 abs = (data[i] << 24)
286 | (data[i + 1] << 16)
287 | (data[i + 2] << 8)
288 | (data[i + 3]);
289
290 plen = 32;
291 }
292 else if (looking_for & L_24)
293 {
294 int i = len >> 1;
0ef9643e 295
c906108c
SS
296 abs = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
297 plen = 24;
298 }
299 else if (looking_for & IGNORE)
300 {
0ef9643e 301 ;
c906108c
SS
302 }
303 else if (looking_for & DISPREG)
304 {
305 rdisp = thisnib & 0x7;
306 }
307 else if (looking_for & KBIT)
308 {
309 switch (thisnib)
310 {
311 case 9:
312 abs = 4;
313 break;
314 case 8:
315 abs = 2;
316 break;
317 case 0:
318 abs = 1;
319 break;
0a17cd59
AC
320 default:
321 goto fail;
c906108c
SS
322 }
323 }
324 else if (looking_for & L_8)
325 {
326 plen = 8;
327
328 if (looking_for & PCREL)
329 {
330 abs = SEXTCHAR (data[len >> 1]);
331 }
332 else if (looking_for & ABS8MEM)
333 {
334 plen = 8;
335 abs = h8300hmode ? ~0xff0000ff : ~0xffff00ff;
0ef9643e 336 abs |= data[len >> 1] & 0xff;
c906108c 337 }
0ef9643e 338 else
c906108c
SS
339 {
340 abs = data[len >> 1] & 0xff;
341 }
342 }
343 else if (looking_for & L_3)
344 {
345 plen = 3;
346
347 bit = thisnib;
348 }
349 else if (looking_for == E)
350 {
351 dst->op = q;
352
0ef9643e 353 /* Fill in the args. */
c906108c
SS
354 {
355 op_type *args = q->args.nib;
356 int hadone = 0;
357
358 while (*args != E)
359 {
360 int x = *args;
361 int rn = (x & DST) ? rd : rs;
362 ea_type *p;
363
364 if (x & DST)
0ef9643e 365 p = &(dst->dst);
c906108c 366 else
0ef9643e 367 p = &(dst->src);
c906108c 368
0ef9643e 369 if (x & L_3)
c906108c
SS
370 {
371 p->type = X (OP_IMM, size);
372 p->literal = bit;
373 }
374 else if (x & (IMM | KBIT | DBIT))
375 {
376 p->type = X (OP_IMM, size);
377 p->literal = abs;
378 }
379 else if (x & REG)
380 {
6d028502
KH
381 /* Reset the size.
382 Some ops (like mul) have two sizes. */
c906108c
SS
383
384 size = bitfrom (x);
385 p->type = X (OP_REG, size);
386 p->reg = rn;
387 }
388 else if (x & INC)
389 {
390 p->type = X (OP_INC, size);
391 p->reg = rn & 0x7;
392 }
393 else if (x & DEC)
394 {
395 p->type = X (OP_DEC, size);
396 p->reg = rn & 0x7;
397 }
398 else if (x & IND)
399 {
400 p->type = X (OP_DISP, size);
401 p->reg = rn & 0x7;
402 p->literal = 0;
403 }
404 else if (x & (ABS | ABSJMP | ABS8MEM))
405 {
406 p->type = X (OP_DISP, size);
407 p->literal = abs;
408 p->reg = 8;
409 }
410 else if (x & MEMIND)
411 {
412 p->type = X (OP_MEM, size);
413 p->literal = abs;
414 }
415 else if (x & PCREL)
416 {
417 p->type = X (OP_PCREL, size);
418 p->literal = abs + addr + 2;
419 if (x & L_16)
420 p->literal += 2;
421 }
422 else if (x & ABSJMP)
423 {
424 p->type = X (OP_IMM, SP);
425 p->literal = abs;
426 }
427 else if (x & DISP)
428 {
429 p->type = X (OP_DISP, size);
430 p->literal = abs;
431 p->reg = rdisp & 0x7;
432 }
433 else if (x & CCR)
434 {
435 p->type = OP_CCR;
436 }
fc974602
AV
437 else if (x & EXR)
438 {
439 p->type = OP_EXR;
440 }
c906108c
SS
441 else
442 printf ("Hmmmm %x", x);
443
444 args++;
445 }
446 }
447
0ef9643e
JL
448 /* But a jmp or a jsr gets automagically lvalued,
449 since we branch to their address not their
450 contents. */
c906108c
SS
451 if (q->how == O (O_JSR, SB)
452 || q->how == O (O_JMP, SB))
453 {
454 dst->src.type = lvalue (dst->src.type, dst->src.reg);
455 }
456
457 if (dst->dst.type == -1)
458 dst->dst = dst->src;
459
460 dst->opcode = q->how;
461 dst->cycles = q->time;
462
bf174226
V
463 /* And a jsr to these locations are turned into magic
464 traps. */
c906108c
SS
465
466 if (dst->opcode == O (O_JSR, SB))
467 {
bf174226 468 switch (dst->src.literal)
c906108c 469 {
bf174226
V
470 case 0xc5:
471 dst->opcode = O (O_SYS_OPEN, SB);
472 break;
473 case 0xc6:
474 dst->opcode = O (O_SYS_READ, SB);
475 break;
476 case 0xc7:
477 dst->opcode = O (O_SYS_WRITE, SB);
478 break;
479 case 0xc8:
480 dst->opcode = O (O_SYS_LSEEK, SB);
481 break;
482 case 0xc9:
483 dst->opcode = O (O_SYS_CLOSE, SB);
484 break;
485 case 0xca:
486 dst->opcode = O (O_SYS_STAT, SB);
487 break;
488 case 0xcb:
489 dst->opcode = O (O_SYS_FSTAT, SB);
490 break;
d1360fb0
V
491 case 0xcc:
492 dst->opcode = O (O_SYS_CMDLINE, SB);
493 break;
c906108c 494 }
bf174226 495 /* End of Processing for system calls. */
c906108c
SS
496 }
497
498 dst->next_pc = addr + len / 2;
499 return;
500 }
501 else
98ecb0a7 502 printf ("Don't understand %x \n", looking_for);
c906108c
SS
503 }
504
505 len++;
506 nib++;
507 }
508
509 fail:
6d028502 510 ;
c906108c
SS
511 }
512
0ef9643e 513 /* Fell off the end. */
c906108c
SS
514 dst->opcode = O (O_ILL, SB);
515}
516
c906108c 517static void
a4f27e3e 518compile (int pc)
c906108c
SS
519{
520 int idx;
521
2ea716f6 522 /* Find the next cache entry to use. */
c906108c
SS
523 idx = cpu.cache_top + 1;
524 cpu.compiles++;
525 if (idx >= cpu.csize)
526 {
527 idx = 1;
528 }
529 cpu.cache_top = idx;
530
2ea716f6 531 /* Throw away its old meaning. */
c906108c
SS
532 cpu.cache_idx[cpu.cache[idx].oldpc] = 0;
533
2ea716f6 534 /* Set to new address. */
c906108c
SS
535 cpu.cache[idx].oldpc = pc;
536
2ea716f6 537 /* Fill in instruction info. */
c906108c
SS
538 decode (pc, cpu.memory + pc, cpu.cache + idx);
539
2ea716f6 540 /* Point to new cache entry. */
c906108c
SS
541 cpu.cache_idx[pc] = idx;
542}
543
544
545static unsigned char *breg[18];
546static unsigned short *wreg[18];
547static unsigned int *lreg[18];
548
549#define GET_B_REG(x) *(breg[x])
550#define SET_B_REG(x,y) (*(breg[x])) = (y)
551#define GET_W_REG(x) *(wreg[x])
552#define SET_W_REG(x,y) (*(wreg[x])) = (y)
553
554#define GET_L_REG(x) *(lreg[x])
555#define SET_L_REG(x,y) (*(lreg[x])) = (y)
556
557#define GET_MEMORY_L(x) \
558 (x < memory_size \
559 ? ((cpu.memory[x+0] << 24) | (cpu.memory[x+1] << 16) \
560 | (cpu.memory[x+2] << 8) | cpu.memory[x+3]) \
561 : ((cpu.eightbit[(x+0) & 0xff] << 24) | (cpu.eightbit[(x+1) & 0xff] << 16) \
562 | (cpu.eightbit[(x+2) & 0xff] << 8) | cpu.eightbit[(x+3) & 0xff]))
563
564#define GET_MEMORY_W(x) \
565 (x < memory_size \
566 ? ((cpu.memory[x+0] << 8) | (cpu.memory[x+1] << 0)) \
567 : ((cpu.eightbit[(x+0) & 0xff] << 8) | (cpu.eightbit[(x+1) & 0xff] << 0)))
568
569
570#define GET_MEMORY_B(x) \
571 (x < memory_size ? (cpu.memory[x]) : (cpu.eightbit[x & 0xff]))
572
573#define SET_MEMORY_L(x,y) \
574{ register unsigned char *_p; register int __y = y; \
575 _p = (x < memory_size ? cpu.memory+x : cpu.eightbit + (x & 0xff)); \
576 _p[0] = (__y)>>24; _p[1] = (__y)>>16; \
577 _p[2] = (__y)>>8; _p[3] = (__y)>>0;}
578
579#define SET_MEMORY_W(x,y) \
580{ register unsigned char *_p; register int __y = y; \
581 _p = (x < memory_size ? cpu.memory+x : cpu.eightbit + (x & 0xff)); \
582 _p[0] = (__y)>>8; _p[1] =(__y);}
583
584#define SET_MEMORY_B(x,y) \
585 (x < memory_size ? (cpu.memory[(x)] = y) : (cpu.eightbit[x & 0xff] = y))
586
a4f27e3e
MS
587static int
588fetch (ea_type *arg)
c906108c
SS
589{
590 int rn = arg->reg;
591 int abs = arg->literal;
592 int r;
593 int t;
594
595 switch (arg->type)
596 {
597 case X (OP_REG, SB):
598 return GET_B_REG (rn);
599 case X (OP_REG, SW):
600 return GET_W_REG (rn);
601 case X (OP_REG, SL):
602 return GET_L_REG (rn);
603 case X (OP_IMM, SB):
604 case X (OP_IMM, SW):
605 case X (OP_IMM, SL):
606 return abs;
607 case X (OP_DEC, SB):
608 abort ();
609
610 case X (OP_INC, SB):
611 t = GET_L_REG (rn);
612 t &= cpu.mask;
613 r = GET_MEMORY_B (t);
614 t++;
615 t = t & cpu.mask;
616 SET_L_REG (rn, t);
617 return r;
618 break;
619 case X (OP_INC, SW):
620 t = GET_L_REG (rn);
621 t &= cpu.mask;
622 r = GET_MEMORY_W (t);
623 t += 2;
624 t = t & cpu.mask;
625 SET_L_REG (rn, t);
626 return r;
627 case X (OP_INC, SL):
628 t = GET_L_REG (rn);
629 t &= cpu.mask;
630 r = GET_MEMORY_L (t);
631
632 t += 4;
633 t = t & cpu.mask;
634 SET_L_REG (rn, t);
635 return r;
636
637 case X (OP_DISP, SB):
638 t = GET_L_REG (rn) + abs;
639 t &= cpu.mask;
640 return GET_MEMORY_B (t);
641
642 case X (OP_DISP, SW):
643 t = GET_L_REG (rn) + abs;
644 t &= cpu.mask;
645 return GET_MEMORY_W (t);
646
647 case X (OP_DISP, SL):
648 t = GET_L_REG (rn) + abs;
649 t &= cpu.mask;
650 return GET_MEMORY_L (t);
651
652 case X (OP_MEM, SL):
653 t = GET_MEMORY_L (abs);
654 t &= cpu.mask;
655 return t;
656
657 case X (OP_MEM, SW):
658 t = GET_MEMORY_W (abs);
659 t &= cpu.mask;
660 return t;
661
662 default:
3b02cf92 663 abort (); /* ?? May be something more usefull? */
c906108c
SS
664
665 }
666}
667
668
de9b1892 669static void
a4f27e3e 670store (ea_type *arg, int n)
c906108c
SS
671{
672 int rn = arg->reg;
673 int abs = arg->literal;
674 int t;
675
676 switch (arg->type)
677 {
678 case X (OP_REG, SB):
679 SET_B_REG (rn, n);
680 break;
681 case X (OP_REG, SW):
682 SET_W_REG (rn, n);
683 break;
684 case X (OP_REG, SL):
685 SET_L_REG (rn, n);
686 break;
687
688 case X (OP_DEC, SB):
689 t = GET_L_REG (rn) - 1;
690 t &= cpu.mask;
691 SET_L_REG (rn, t);
692 SET_MEMORY_B (t, n);
693
694 break;
695 case X (OP_DEC, SW):
696 t = (GET_L_REG (rn) - 2) & cpu.mask;
697 SET_L_REG (rn, t);
698 SET_MEMORY_W (t, n);
699 break;
700
701 case X (OP_DEC, SL):
702 t = (GET_L_REG (rn) - 4) & cpu.mask;
703 SET_L_REG (rn, t);
704 SET_MEMORY_L (t, n);
705 break;
706
707 case X (OP_DISP, SB):
708 t = GET_L_REG (rn) + abs;
709 t &= cpu.mask;
710 SET_MEMORY_B (t, n);
711 break;
712
713 case X (OP_DISP, SW):
714 t = GET_L_REG (rn) + abs;
715 t &= cpu.mask;
716 SET_MEMORY_W (t, n);
717 break;
718
719 case X (OP_DISP, SL):
720 t = GET_L_REG (rn) + abs;
721 t &= cpu.mask;
722 SET_MEMORY_L (t, n);
723 break;
724 default:
725 abort ();
726 }
727}
728
729
730static union
731{
732 short int i;
733 struct
734 {
735 char low;
736 char high;
737 }
738 u;
739}
740
741littleendian;
742
de9b1892 743static void
a4f27e3e 744init_pointers (void)
c906108c
SS
745{
746 static int init;
747
748 if (!init)
749 {
750 int i;
751
752 init = 1;
753 littleendian.i = 1;
754
a8cdafbd
AV
755 if (h8300smode)
756 memory_size = H8300S_MSIZE;
757 else if (h8300hmode)
c906108c
SS
758 memory_size = H8300H_MSIZE;
759 else
760 memory_size = H8300_MSIZE;
761 cpu.memory = (unsigned char *) calloc (sizeof (char), memory_size);
762 cpu.cache_idx = (unsigned short *) calloc (sizeof (short), memory_size);
763 cpu.eightbit = (unsigned char *) calloc (sizeof (char), 256);
764
2ea716f6 765 /* `msize' must be a power of two. */
c906108c
SS
766 if ((memory_size & (memory_size - 1)) != 0)
767 abort ();
768 cpu.mask = memory_size - 1;
769
770 for (i = 0; i < 9; i++)
771 {
772 cpu.regs[i] = 0;
773 }
774
775 for (i = 0; i < 8; i++)
776 {
777 unsigned char *p = (unsigned char *) (cpu.regs + i);
778 unsigned char *e = (unsigned char *) (cpu.regs + i + 1);
779 unsigned short *q = (unsigned short *) (cpu.regs + i);
780 unsigned short *u = (unsigned short *) (cpu.regs + i + 1);
781 cpu.regs[i] = 0x00112233;
782 while (p < e)
783 {
784 if (*p == 0x22)
785 {
786 breg[i] = p;
787 }
788 if (*p == 0x33)
789 {
790 breg[i + 8] = p;
791 }
792 p++;
793 }
ec38ce99 794 wreg[i] = wreg[i + 8] = 0;
c906108c
SS
795 while (q < u)
796 {
797 if (*q == 0x2233)
798 {
799 wreg[i] = q;
800 }
801 if (*q == 0x0011)
802 {
803 wreg[i + 8] = q;
804 }
805 q++;
806 }
ec38ce99
KH
807 if (wreg[i] == 0 || wreg[i + 8] == 0)
808 abort ();
c906108c
SS
809 cpu.regs[i] = 0;
810 lreg[i] = &cpu.regs[i];
811 }
812
813 lreg[8] = &cpu.regs[8];
814
2ea716f6 815 /* Initialize the seg registers. */
c906108c
SS
816 if (!cpu.cache)
817 sim_set_simcache_size (CSIZE);
818 }
819}
820
821static void
a4f27e3e 822control_c (int sig)
c906108c
SS
823{
824 cpu.state = SIM_STATE_STOPPED;
825 cpu.exception = SIGINT;
826}
827
828#define C (c != 0)
829#define Z (nz == 0)
830#define V (v != 0)
831#define N (n != 0)
f6225c96
AV
832#define U (u != 0)
833#define H (h != 0)
834#define UI (ui != 0)
835#define I (intMaskBit != 0)
c906108c
SS
836
837static int
a4f27e3e 838mop (decoded_inst *code, int bsize, int sign)
c906108c
SS
839{
840 int multiplier;
841 int multiplicand;
842 int result;
843 int n, nz;
844
845 if (sign)
846 {
847 multiplicand =
848 bsize ? SEXTCHAR (GET_W_REG (code->dst.reg)) :
849 SEXTSHORT (GET_W_REG (code->dst.reg));
850 multiplier =
851 bsize ? SEXTCHAR (GET_B_REG (code->src.reg)) :
852 SEXTSHORT (GET_W_REG (code->src.reg));
853 }
854 else
855 {
856 multiplicand = bsize ? UEXTCHAR (GET_W_REG (code->dst.reg)) :
857 UEXTSHORT (GET_W_REG (code->dst.reg));
858 multiplier =
859 bsize ? UEXTCHAR (GET_B_REG (code->src.reg)) :
860 UEXTSHORT (GET_W_REG (code->src.reg));
861
862 }
863 result = multiplier * multiplicand;
864
865 if (sign)
866 {
867 n = result & (bsize ? 0x8000 : 0x80000000);
868 nz = result & (bsize ? 0xffff : 0xffffffff);
869 }
870 if (bsize)
871 {
872 SET_W_REG (code->dst.reg, result);
873 }
874 else
875 {
876 SET_L_REG (code->dst.reg, result);
877 }
de9b1892
KH
878#if 0
879 return ((n == 1) << 1) | (nz == 1);
880#endif
c906108c
SS
881}
882
883#define ONOT(name, how) \
d1335144 884case O (name, SB): \
c906108c
SS
885{ \
886 int t; \
887 int hm = 0x80; \
888 rd = GET_B_REG (code->src.reg); \
889 how; \
890 goto shift8; \
891} \
d1335144 892case O (name, SW): \
c906108c
SS
893{ \
894 int t; \
895 int hm = 0x8000; \
896 rd = GET_W_REG (code->src.reg); \
897 how; \
898 goto shift16; \
899} \
d1335144 900case O (name, SL): \
c906108c
SS
901{ \
902 int t; \
903 int hm = 0x80000000; \
904 rd = GET_L_REG (code->src.reg); \
905 how; \
906 goto shift32; \
907}
908
909#define OSHIFTS(name, how1, how2) \
d1335144 910case O (name, SB): \
c906108c
SS
911{ \
912 int t; \
913 int hm = 0x80; \
914 rd = GET_B_REG (code->src.reg); \
915 if ((GET_MEMORY_B (pc + 1) & 0x40) == 0) \
916 { \
917 how1; \
918 } \
919 else \
920 { \
921 how2; \
922 } \
923 goto shift8; \
924} \
d1335144 925case O (name, SW): \
c906108c
SS
926{ \
927 int t; \
928 int hm = 0x8000; \
929 rd = GET_W_REG (code->src.reg); \
930 if ((GET_MEMORY_B (pc + 1) & 0x40) == 0) \
931 { \
932 how1; \
933 } \
934 else \
935 { \
936 how2; \
937 } \
938 goto shift16; \
939} \
d1335144 940case O (name, SL): \
c906108c
SS
941{ \
942 int t; \
943 int hm = 0x80000000; \
944 rd = GET_L_REG (code->src.reg); \
945 if ((GET_MEMORY_B (pc + 1) & 0x40) == 0) \
946 { \
947 how1; \
948 } \
949 else \
950 { \
951 how2; \
952 } \
953 goto shift32; \
954}
955
956#define OBITOP(name,f, s, op) \
d1335144 957case O (name, SB): \
c906108c
SS
958{ \
959 int m; \
960 int b; \
961 if (f) ea = fetch (&code->dst); \
d1335144 962 m=1<< fetch (&code->src); \
c906108c 963 op; \
d1335144 964 if (s) store (&code->dst,ea); goto next; \
c906108c
SS
965}
966
967int
837fd61c 968sim_stop (SIM_DESC sd)
c906108c
SS
969{
970 cpu.state = SIM_STATE_STOPPED;
971 cpu.exception = SIGINT;
972 return 1;
973}
974
6147b1f6
AV
975#define R0_REGNUM 0
976#define R1_REGNUM 1
977#define R2_REGNUM 2
978#define R3_REGNUM 3
979#define R4_REGNUM 4
980#define R5_REGNUM 5
981#define R6_REGNUM 6
982#define R7_REGNUM 7
983
984#define SP_REGNUM R7_REGNUM /* Contains address of top of stack */
985#define FP_REGNUM R6_REGNUM /* Contains address of executing
986 * stack frame */
987
988#define CCR_REGNUM 8 /* Contains processor status */
989#define PC_REGNUM 9 /* Contains program counter */
990
991#define CYCLE_REGNUM 10
992
993#define EXR_REGNUM 11
994#define INST_REGNUM 12
995#define TICK_REGNUM 13
996
c906108c 997void
a4f27e3e 998sim_resume (SIM_DESC sd, int step, int siggnal)
c906108c
SS
999{
1000 static int init1;
1001 int cycles = 0;
1002 int insts = 0;
1003 int tick_start = get_now ();
1004 void (*prev) ();
1005 int poll_count = 0;
1006 int res;
1007 int tmp;
1008 int rd;
1009 int ea;
1010 int bit;
1011 int pc;
f6225c96 1012 int c, nz, v, n, u, h, ui, intMaskBit;
fc974602 1013 int trace, intMask;
c906108c
SS
1014 int oldmask;
1015 init_pointers ();
1016
1017 prev = signal (SIGINT, control_c);
1018
1019 if (step)
1020 {
1021 cpu.state = SIM_STATE_STOPPED;
1022 cpu.exception = SIGTRAP;
1023 }
1024 else
1025 {
1026 cpu.state = SIM_STATE_RUNNING;
1027 cpu.exception = 0;
1028 }
1029
1030 pc = cpu.pc;
1031
1032 /* The PC should never be odd. */
1033 if (pc & 0x1)
1034 abort ();
1035
1036 GETSR ();
fc974602
AV
1037 GETEXR ();
1038
c906108c
SS
1039 oldmask = cpu.mask;
1040 if (!h8300hmode)
1041 cpu.mask = 0xffff;
1042 do
1043 {
1044 int cidx;
1045 decoded_inst *code;
1046
1047 top:
1048 cidx = cpu.cache_idx[pc];
1049 code = cpu.cache + cidx;
1050
1051
1052#define ALUOP(STORE, NAME, HOW) \
d0fe2f7e
KH
1053 case O (NAME, SB): HOW; if (STORE) goto alu8; else goto just_flags_alu8; \
1054 case O (NAME, SW): HOW; if (STORE) goto alu16; else goto just_flags_alu16; \
1055 case O (NAME, SL): HOW; if (STORE) goto alu32; else goto just_flags_alu32;
c906108c
SS
1056
1057
d0fe2f7e
KH
1058#define LOGOP(NAME, HOW) \
1059 case O (NAME, SB): HOW; goto log8; \
1060 case O (NAME, SW): HOW; goto log16; \
1061 case O (NAME, SL): HOW; goto log32;
c906108c
SS
1062
1063
1064
1065#if ADEBUG
1066 if (debug)
1067 {
1068 printf ("%x %d %s\n", pc, code->opcode,
1069 code->op ? code->op->name : "**");
1070 }
1071 cpu.stats[code->opcode]++;
1072
1073#endif
1074
3b02cf92 1075 if (code->opcode)
c3f4437e
KH
1076 {
1077 cycles += code->cycles;
1078 insts++;
1079 }
3b02cf92 1080
c906108c
SS
1081 switch (code->opcode)
1082 {
1083 case 0:
1084 /*
1085 * This opcode is a fake for when we get to an
1086 * instruction which hasnt been compiled
1087 */
1088 compile (pc);
1089 goto top;
1090 break;
1091
1092
1093 case O (O_SUBX, SB):
1094 rd = fetch (&code->dst);
1095 ea = fetch (&code->src);
1096 ea = -(ea + C);
1097 res = rd + ea;
1098 goto alu8;
1099
1100 case O (O_ADDX, SB):
1101 rd = fetch (&code->dst);
1102 ea = fetch (&code->src);
1103 ea = C + ea;
1104 res = rd + ea;
1105 goto alu8;
1106
d1335144
KH
1107#define EA ea = fetch (&code->src);
1108#define RD_EA ea = fetch (&code->src); rd = fetch (&code->dst);
c906108c
SS
1109
1110 ALUOP (1, O_SUB, RD_EA;
1111 ea = -ea;
1112 res = rd + ea);
1113 ALUOP (1, O_NEG, EA;
1114 ea = -ea;
1115 rd = 0;
1116 res = rd + ea);
1117
1118 case O (O_ADD, SB):
1119 rd = GET_B_REG (code->dst.reg);
1120 ea = fetch (&code->src);
1121 res = rd + ea;
1122 goto alu8;
1123 case O (O_ADD, SW):
1124 rd = GET_W_REG (code->dst.reg);
1125 ea = fetch (&code->src);
1126 res = rd + ea;
1127 goto alu16;
1128 case O (O_ADD, SL):
1129 rd = GET_L_REG (code->dst.reg);
1130 ea = fetch (&code->src);
1131 res = rd + ea;
1132 goto alu32;
1133
1134
1135 LOGOP (O_AND, RD_EA;
1136 res = rd & ea);
1137
1138 LOGOP (O_OR, RD_EA;
1139 res = rd | ea);
1140
1141 LOGOP (O_XOR, RD_EA;
1142 res = rd ^ ea);
1143
1144
1145 case O (O_MOV_TO_MEM, SB):
1146 res = GET_B_REG (code->src.reg);
1147 goto log8;
1148 case O (O_MOV_TO_MEM, SW):
1149 res = GET_W_REG (code->src.reg);
1150 goto log16;
1151 case O (O_MOV_TO_MEM, SL):
1152 res = GET_L_REG (code->src.reg);
1153 goto log32;
1154
1155
1156 case O (O_MOV_TO_REG, SB):
1157 res = fetch (&code->src);
1158 SET_B_REG (code->dst.reg, res);
1159 goto just_flags_log8;
1160 case O (O_MOV_TO_REG, SW):
1161 res = fetch (&code->src);
1162 SET_W_REG (code->dst.reg, res);
1163 goto just_flags_log16;
1164 case O (O_MOV_TO_REG, SL):
1165 res = fetch (&code->src);
1166 SET_L_REG (code->dst.reg, res);
1167 goto just_flags_log32;
1168
6147b1f6
AV
1169 case O (O_EEPMOV, SB):
1170 case O (O_EEPMOV, SW):
d0fe2f7e 1171 if (h8300hmode || h8300smode)
c3f4437e 1172 {
d0fe2f7e
KH
1173 register unsigned char *_src, *_dst;
1174 unsigned int count = ((code->opcode == O (O_EEPMOV, SW))
1175 ? cpu.regs[R4_REGNUM] & 0xffff
1176 : cpu.regs[R4_REGNUM] & 0xff);
1177
1178 _src = (cpu.regs[R5_REGNUM] < memory_size
1179 ? cpu.memory + cpu.regs[R5_REGNUM]
1180 : cpu.eightbit + (cpu.regs[R5_REGNUM] & 0xff));
1181 if ((_src + count) >= (cpu.memory + memory_size))
c3f4437e 1182 {
d0fe2f7e 1183 if ((_src + count) >= (cpu.eightbit + 0x100))
c3f4437e
KH
1184 goto illegal;
1185 }
d0fe2f7e
KH
1186 _dst = (cpu.regs[R6_REGNUM] < memory_size
1187 ? cpu.memory + cpu.regs[R6_REGNUM]
1188 : cpu.eightbit + (cpu.regs[R6_REGNUM] & 0xff));
1189 if ((_dst + count) >= (cpu.memory + memory_size))
c3f4437e 1190 {
d0fe2f7e 1191 if ((_dst + count) >= (cpu.eightbit + 0x100))
c3f4437e
KH
1192 goto illegal;
1193 }
d0fe2f7e 1194 memcpy (_dst, _src, count);
c3f4437e 1195
d0fe2f7e
KH
1196 cpu.regs[R5_REGNUM] += count;
1197 cpu.regs[R6_REGNUM] += count;
1198 cpu.regs[R4_REGNUM] &= ((code->opcode == O (O_EEPMOV, SW))
1199 ? (~0xffff) : (~0xff));
1200 cycles += 2 * count;
c3f4437e
KH
1201 goto next;
1202 }
1203 goto illegal;
c906108c
SS
1204
1205 case O (O_ADDS, SL):
1206 SET_L_REG (code->dst.reg,
1207 GET_L_REG (code->dst.reg)
1208 + code->src.literal);
1209
1210 goto next;
1211
1212 case O (O_SUBS, SL):
1213 SET_L_REG (code->dst.reg,
1214 GET_L_REG (code->dst.reg)
1215 - code->src.literal);
1216 goto next;
1217
1218 case O (O_CMP, SB):
1219 rd = fetch (&code->dst);
1220 ea = fetch (&code->src);
1221 ea = -ea;
1222 res = rd + ea;
1223 goto just_flags_alu8;
1224
1225 case O (O_CMP, SW):
1226 rd = fetch (&code->dst);
1227 ea = fetch (&code->src);
1228 ea = -ea;
1229 res = rd + ea;
1230 goto just_flags_alu16;
1231
1232 case O (O_CMP, SL):
1233 rd = fetch (&code->dst);
1234 ea = fetch (&code->src);
1235 ea = -ea;
1236 res = rd + ea;
1237 goto just_flags_alu32;
1238
1239
1240 case O (O_DEC, SB):
1241 rd = GET_B_REG (code->src.reg);
1242 ea = -1;
1243 res = rd + ea;
1244 SET_B_REG (code->src.reg, res);
1245 goto just_flags_inc8;
1246
1247 case O (O_DEC, SW):
1248 rd = GET_W_REG (code->dst.reg);
1249 ea = -code->src.literal;
1250 res = rd + ea;
1251 SET_W_REG (code->dst.reg, res);
1252 goto just_flags_inc16;
1253
1254 case O (O_DEC, SL):
1255 rd = GET_L_REG (code->dst.reg);
1256 ea = -code->src.literal;
1257 res = rd + ea;
1258 SET_L_REG (code->dst.reg, res);
1259 goto just_flags_inc32;
1260
1261
1262 case O (O_INC, SB):
1263 rd = GET_B_REG (code->src.reg);
1264 ea = 1;
1265 res = rd + ea;
1266 SET_B_REG (code->src.reg, res);
1267 goto just_flags_inc8;
1268
1269 case O (O_INC, SW):
1270 rd = GET_W_REG (code->dst.reg);
1271 ea = code->src.literal;
1272 res = rd + ea;
1273 SET_W_REG (code->dst.reg, res);
1274 goto just_flags_inc16;
1275
1276 case O (O_INC, SL):
1277 rd = GET_L_REG (code->dst.reg);
1278 ea = code->src.literal;
1279 res = rd + ea;
1280 SET_L_REG (code->dst.reg, res);
1281 goto just_flags_inc32;
1282
c906108c 1283#define GET_CCR(x) BUILDSR();x = cpu.ccr
d1335144 1284#define GET_EXR(x) BUILDEXR ();x = cpu.exr
c906108c 1285
6147b1f6
AV
1286 case O (O_LDC, SB):
1287 case O (O_LDC, SW):
d1335144 1288 res = fetch (&code->src);
6147b1f6
AV
1289 goto setc;
1290 case O (O_STC, SB):
1291 case O (O_STC, SW):
d1335144 1292 if (code->src.type == OP_CCR)
c3f4437e 1293 {
d1335144 1294 GET_CCR (res);
c3f4437e 1295 }
d1335144 1296 else if (code->src.type == OP_EXR && h8300smode)
c3f4437e 1297 {
d1335144 1298 GET_EXR (res);
c3f4437e
KH
1299 }
1300 else
6147b1f6
AV
1301 goto illegal;
1302 store (&code->dst, res);
1303 goto next;
1304
c906108c 1305 case O (O_ANDC, SB):
d1335144 1306 if (code->dst.type == OP_CCR)
c3f4437e
KH
1307 {
1308 GET_CCR (rd);
1309 }
d1335144 1310 else if (code->dst.type == OP_EXR && h8300smode)
c3f4437e
KH
1311 {
1312 GET_EXR (rd);
1313 }
1314 else
fc974602 1315 goto illegal;
c906108c
SS
1316 ea = code->src.literal;
1317 res = rd & ea;
1318 goto setc;
1319
1320 case O (O_ORC, SB):
d1335144 1321 if (code->dst.type == OP_CCR)
c3f4437e
KH
1322 {
1323 GET_CCR (rd);
1324 }
d1335144 1325 else if (code->dst.type == OP_EXR && h8300smode)
c3f4437e
KH
1326 {
1327 GET_EXR (rd);
1328 }
1329 else
fc974602 1330 goto illegal;
c906108c
SS
1331 ea = code->src.literal;
1332 res = rd | ea;
1333 goto setc;
1334
1335 case O (O_XORC, SB):
d1335144 1336 if (code->dst.type == OP_CCR)
c3f4437e
KH
1337 {
1338 GET_CCR (rd);
1339 }
d1335144 1340 else if (code->dst.type == OP_EXR && h8300smode)
c3f4437e
KH
1341 {
1342 GET_EXR (rd);
1343 }
1344 else
fc974602 1345 goto illegal;
c906108c
SS
1346 ea = code->src.literal;
1347 res = rd ^ ea;
1348 goto setc;
1349
1350
1351 case O (O_BRA, SB):
1352 if (1)
1353 goto condtrue;
1354 goto next;
1355
1356 case O (O_BRN, SB):
1357 if (0)
1358 goto condtrue;
1359 goto next;
1360
1361 case O (O_BHI, SB):
1362 if ((C || Z) == 0)
1363 goto condtrue;
1364 goto next;
1365
1366
1367 case O (O_BLS, SB):
1368 if ((C || Z))
1369 goto condtrue;
1370 goto next;
1371
1372 case O (O_BCS, SB):
1373 if ((C == 1))
1374 goto condtrue;
1375 goto next;
1376
1377 case O (O_BCC, SB):
1378 if ((C == 0))
1379 goto condtrue;
1380 goto next;
1381
1382 case O (O_BEQ, SB):
1383 if (Z)
1384 goto condtrue;
1385 goto next;
1386 case O (O_BGT, SB):
1387 if (((Z || (N ^ V)) == 0))
1388 goto condtrue;
1389 goto next;
1390
1391
1392 case O (O_BLE, SB):
1393 if (((Z || (N ^ V)) == 1))
1394 goto condtrue;
1395 goto next;
1396
1397 case O (O_BGE, SB):
1398 if ((N ^ V) == 0)
1399 goto condtrue;
1400 goto next;
1401 case O (O_BLT, SB):
1402 if ((N ^ V))
1403 goto condtrue;
1404 goto next;
1405 case O (O_BMI, SB):
1406 if ((N))
1407 goto condtrue;
1408 goto next;
1409 case O (O_BNE, SB):
1410 if ((Z == 0))
1411 goto condtrue;
1412 goto next;
1413
1414 case O (O_BPL, SB):
1415 if (N == 0)
1416 goto condtrue;
1417 goto next;
1418 case O (O_BVC, SB):
1419 if ((V == 0))
1420 goto condtrue;
1421 goto next;
1422 case O (O_BVS, SB):
1423 if ((V == 1))
1424 goto condtrue;
1425 goto next;
1426
d1360fb0
V
1427 /* Trap for Command Line setup. */
1428 case O (O_SYS_CMDLINE, SB):
1429 {
1430 int i = 0; /* Loop counter. */
1431 int j = 0; /* Loop counter. */
1432 int ind_arg_len = 0; /* Length of each argument. */
1433 int no_of_args = 0; /* The no. or cmdline args. */
1434 int current_location = 0; /* Location of string. */
1435 int old_sp = 0; /* The Initial Stack Pointer. */
1436 int no_of_slots = 0; /* No. of slots required on the stack
1437 for storing cmdline args. */
1438 int sp_move = 0; /* No. of locations by which the stack needs
1439 to grow. */
1440 int new_sp = 0; /* The final stack pointer location passed
1441 back. */
1442 int *argv_ptrs; /* Pointers of argv strings to be stored. */
1443 int argv_ptrs_location = 0; /* Location of pointers to cmdline
1444 args on the stack. */
1445 int char_ptr_size = 0; /* Size of a character pointer on
1446 target machine. */
1447 int addr_cmdline = 0; /* Memory location where cmdline has
1448 to be stored. */
1449 int size_cmdline = 0; /* Size of cmdline. */
1450
1451 /* Set the address of 256 free locations where command line is
1452 stored. */
1453 addr_cmdline = cmdline_location();
1454 cpu.regs[0] = addr_cmdline;
1455
1456 /* Counting the no. of commandline arguments. */
1457 for (i = 0; ptr_command_line[i] != NULL; i++)
1458 continue;
1459
1460 /* No. of arguments in the command line. */
1461 no_of_args = i;
1462
1463 /* Current location is just a temporary variable,which we are
1464 setting to the point to the start of our commandline string. */
1465 current_location = addr_cmdline;
1466
1467 /* Allocating space for storing pointers of the command line
1468 arguments. */
1469 argv_ptrs = (int *) malloc (sizeof (int) * no_of_args);
1470
1471 /* Setting char_ptr_size to the sizeof (char *) on the different
1472 architectures. */
1473 if (h8300hmode || h8300smode)
1474 {
1475 char_ptr_size = 4;
1476 }
1477 else
1478 {
1479 char_ptr_size = 2;
1480 }
1481
1482 for (i = 0; i < no_of_args; i++)
1483 {
1484 ind_arg_len = 0;
1485
1486 /* The size of the commandline argument. */
1487 ind_arg_len = (strlen (ptr_command_line[i]) + 1);
1488
1489 /* The total size of the command line string. */
1490 size_cmdline += ind_arg_len;
1491
1492 /* As we have only 256 bytes, we need to provide a graceful
1493 exit. Anyways, a program using command line arguments
1494 where we cannot store all the command line arguments
1495 given may behave unpredictably. */
1496 if (size_cmdline >= 256)
1497 {
1498 cpu.regs[0] = 0;
1499 goto next;
1500 }
1501 else
1502 {
1503 /* current_location points to the memory where the next
1504 commandline argument is stored. */
1505 argv_ptrs[i] = current_location;
1506 for (j = 0; j < ind_arg_len; j++)
1507 {
1508 SET_MEMORY_B ((current_location +
1509 (sizeof (char) * j)),
1510 *(ptr_command_line[i] +
1511 sizeof (char) * j));
1512 }
1513
1514 /* Setting current_location to the starting of next
1515 argument. */
1516 current_location += ind_arg_len;
1517 }
1518 }
1519
1520 /* This is the original position of the stack pointer. */
1521 old_sp = cpu.regs[7];
1522
1523 /* We need space from the stack to store the pointers to argvs. */
1524 /* As we will infringe on the stack, we need to shift the stack
1525 pointer so that the data is not overwritten. We calculate how
1526 much space is required. */
1527 sp_move = (no_of_args) * (char_ptr_size);
1528
1529 /* The final position of stack pointer, we have thus taken some
1530 space from the stack. */
1531 new_sp = old_sp - sp_move;
1532
1533 /* Temporary variable holding value where the argv pointers need
1534 to be stored. */
1535 argv_ptrs_location = new_sp;
1536
1537 /* The argv pointers are stored at sequential locations. As per
1538 the H8300 ABI. */
1539 for (i = 0; i < no_of_args; i++)
1540 {
1541 /* Saving the argv pointer. */
1542 if (h8300hmode || h8300smode)
1543 {
1544 SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]);
1545 }
1546 else
1547 {
1548 SET_MEMORY_W (argv_ptrs_location, argv_ptrs[i]);
1549 }
1550
1551 /* The next location where the pointer to the next argv
1552 string has to be stored. */
1553 argv_ptrs_location += char_ptr_size;
1554 }
1555
1556 /* Required by POSIX, Setting 0x0 at the end of the list of argv
1557 pointers. */
1558 if (h8300hmode || h8300smode)
1559 {
1560 SET_MEMORY_L (old_sp, 0x0);
1561 }
1562 else
1563 {
1564 SET_MEMORY_W (old_sp, 0x0);
1565 }
1566
1567 /* Freeing allocated memory. */
1568 free (argv_ptrs);
1569 for (i = 0; i <= no_of_args; i++)
1570 {
1571 free (ptr_command_line[i]);
1572 }
1573 free (ptr_command_line);
1574
1575 /* The no. of argv arguments are returned in Reg 0. */
1576 cpu.regs[0] = no_of_args;
1577 /* The Pointer to argv in Register 1. */
1578 cpu.regs[1] = new_sp;
1579 /* Setting the stack pointer to the new value. */
1580 cpu.regs[7] = new_sp;
1581 }
1582 goto next;
1583
bf174226
V
1584 /* System call processing starts. */
1585 case O (O_SYS_OPEN, SB):
c906108c 1586 {
bf174226
V
1587 int len = 0; /* Length of filename. */
1588 char *filename; /* Filename would go here. */
1589 char temp_char; /* Temporary character */
1590 int mode = 0; /* Mode bits for the file. */
1591 int open_return; /* Return value of open, file descriptor. */
1592 int i; /* Loop counter */
1593 int filename_ptr; /* Pointer to filename in cpu memory. */
1594
1595 /* Setting filename_ptr to first argument of open. */
1596 filename_ptr = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
1597
1598 /* Trying to get mode. */
1599 if (h8300hmode || h8300smode)
1600 {
1601 mode = GET_MEMORY_L (cpu.regs[7] + 4);
1602 }
1603 else
1604 {
1605 mode = GET_MEMORY_W (cpu.regs[7] + 2);
1606 }
1607
1608 /* Trying to find the length of the filename. */
1609 temp_char = GET_MEMORY_B (cpu.regs[0]);
1610
1611 len = 1;
1612 while (temp_char != '\0')
1613 {
1614 temp_char = GET_MEMORY_B (filename_ptr + len);
1615 len++;
1616 }
1617
1618 /* Allocating space for the filename. */
1619 filename = (char *) malloc (sizeof (char) * len);
1620
1621 /* String copying the filename from memory. */
1622 for (i = 0; i < len; i++)
1623 {
1624 temp_char = GET_MEMORY_B (filename_ptr + i);
1625 filename[i] = temp_char;
1626 }
1627
1628 /* Callback to open and return the file descriptor. */
1629 open_return = sim_callback->open (sim_callback, filename, mode);
1630
1631 /* Return value in register 0. */
1632 cpu.regs[0] = open_return;
1633
1634 /* Freeing memory used for filename. */
1635 free (filename);
c906108c
SS
1636 }
1637 goto next;
1638
bf174226
V
1639 case O (O_SYS_READ, SB):
1640 {
1641 char *char_ptr; /* Where characters read would be stored. */
1642 int fd; /* File descriptor */
1643 int buf_size; /* BUF_SIZE parameter in read. */
1644 int i = 0; /* Temporary Loop counter */
1645 int read_return = 0; /* Return value from callback to
1646 read. */
1647
1648 fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
1649 buf_size = h8300hmode ? GET_L_REG (2) : GET_W_REG (2);
1650
1651 char_ptr = (char *) malloc (sizeof (char) * buf_size);
1652
1653 /* Callback to read and return the no. of characters read. */
1654 read_return =
1655 sim_callback->read (sim_callback, fd, char_ptr, buf_size);
1656
1657 /* The characters read are stored in cpu memory. */
1658 for (i = 0; i < buf_size; i++)
1659 {
1660 SET_MEMORY_B ((cpu.regs[1] + (sizeof (char) * i)),
1661 *(char_ptr + (sizeof (char) * i)));
1662 }
1663
1664 /* Return value in Register 0. */
1665 cpu.regs[0] = read_return;
1666
1667 /* Freeing memory used as buffer. */
1668 free (char_ptr);
1669 }
1670 goto next;
1671
1672 case O (O_SYS_WRITE, SB):
1673 {
1674 int fd; /* File descriptor */
1675 char temp_char; /* Temporary character */
1676 int len; /* Length of write, Parameter II to write. */
1677 int char_ptr; /* Character Pointer, Parameter I of write. */
1678 char *ptr; /* Where characters to be written are stored.
1679 */
1680 int write_return; /* Return value from callback to write. */
1681 int i = 0; /* Loop counter */
1682
1683 fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
1684 char_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
1685 len = h8300hmode ? GET_L_REG (2) : GET_W_REG (2);
1686
1687 /* Allocating space for the characters to be written. */
1688 ptr = (char *) malloc (sizeof (char) * len);
1689
1690 /* Fetching the characters from cpu memory. */
1691 for (i = 0; i < len; i++)
1692 {
1693 temp_char = GET_MEMORY_B (char_ptr + i);
1694 ptr[i] = temp_char;
1695 }
1696
1697 /* Callback write and return the no. of characters written. */
1698 write_return = sim_callback->write (sim_callback, fd, ptr, len);
1699
1700 /* Return value in Register 0. */
1701 cpu.regs[0] = write_return;
1702
1703 /* Freeing memory used as buffer. */
1704 free (ptr);
1705 }
1706 goto next;
1707
1708 case O (O_SYS_LSEEK, SB):
1709 {
1710 int fd; /* File descriptor */
1711 int offset; /* Offset */
1712 int origin; /* Origin */
1713 int lseek_return; /* Return value from callback to lseek. */
1714
1715 fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
1716 offset = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
1717 origin = h8300hmode ? GET_L_REG (2) : GET_W_REG (2);
1718
1719 /* Callback lseek and return offset. */
1720 lseek_return =
1721 sim_callback->lseek (sim_callback, fd, offset, origin);
1722
1723 /* Return value in register 0. */
1724 cpu.regs[0] = lseek_return;
1725 }
1726 goto next;
1727
1728 case O (O_SYS_CLOSE, SB):
1729 {
1730 int fd; /* File descriptor */
1731 int close_return; /* Return value from callback to close. */
1732
1733 fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
1734
1735 /* Callback close and return. */
1736 close_return = sim_callback->close (sim_callback, fd);
1737
1738 /* Return value in register 0. */
1739 cpu.regs[0] = close_return;
1740 }
1741 goto next;
1742
1743 case O (O_SYS_FSTAT, SB):
1744 {
1745 int fd; /* File descriptor */
1746 struct stat stat_rec; /* Stat record */
1747 int fstat_return; /* Return value from callback to stat. */
1748 int stat_ptr; /* Pointer to stat record. */
1749 char *temp_stat_ptr; /* Temporary stat_rec pointer. */
1750
1751 fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
1752
1753 /* Setting stat_ptr to second argument of stat. */
1754 stat_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
1755
1756 /* Callback stat and return. */
1757 fstat_return = sim_callback->fstat (sim_callback, fd, &stat_rec);
1758
1759 /* Have stat_ptr point to starting of stat_rec. */
1760 temp_stat_ptr = (char *) (&stat_rec);
1761
1762 /* Setting up the stat structure returned. */
1763 SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
1764 stat_ptr += 2;
1765 SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
1766 stat_ptr += 2;
1767 SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
1768 stat_ptr += 4;
1769 SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
1770 stat_ptr += 2;
1771 SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
1772 stat_ptr += 2;
1773 SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
1774 stat_ptr += 2;
1775 SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
1776 stat_ptr += 2;
1777 SET_MEMORY_L (stat_ptr, stat_rec.st_size);
1778 stat_ptr += 4;
1779 SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
1780 stat_ptr += 8;
1781 SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
1782 stat_ptr += 8;
1783 SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
1784
1785 /* Return value in register 0. */
1786 cpu.regs[0] = fstat_return;
1787 }
1788 goto next;
1789
1790 case O (O_SYS_STAT, SB):
1791 {
1792 int len = 0; /* Length of filename. */
1793 char *filename; /* Filename would go here. */
1794 char temp_char; /* Temporary character */
1795 int filename_ptr; /* Pointer to filename in cpu memory. */
1796 struct stat stat_rec; /* Stat record */
1797 int stat_return; /* Return value from callback to stat */
1798 int stat_ptr; /* Pointer to stat record. */
1799 char *temp_stat_ptr; /* Temporary stat_rec pointer. */
1800 int i = 0; /* Loop Counter */
1801
1802 /* Setting filename_ptr to first argument of open. */
1803 filename_ptr = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
1804
1805 /* Trying to find the length of the filename. */
1806 temp_char = GET_MEMORY_B (cpu.regs[0]);
1807
1808 len = 1;
1809 while (temp_char != '\0')
1810 {
1811 temp_char = GET_MEMORY_B (filename_ptr + len);
1812 len++;
1813 }
1814
1815 /* Allocating space for the filename. */
1816 filename = (char *) malloc (sizeof (char) * len);
1817
1818 /* String copying the filename from memory. */
1819 for (i = 0; i < len; i++)
1820 {
1821 temp_char = GET_MEMORY_B (filename_ptr + i);
1822 filename[i] = temp_char;
1823 }
1824
1825 /* Setting stat_ptr to second argument of stat. */
1826 /* stat_ptr = cpu.regs[1]; */
1827 stat_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
1828
1829 /* Callback stat and return. */
1830 stat_return =
1831 sim_callback->stat (sim_callback, filename, &stat_rec);
1832
1833 /* Have stat_ptr point to starting of stat_rec. */
1834 temp_stat_ptr = (char *) (&stat_rec);
1835
1836 /* Freeing memory used for filename. */
1837 free (filename);
1838
1839 /* Setting up the stat structure returned. */
1840 SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
1841 stat_ptr += 2;
1842 SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
1843 stat_ptr += 2;
1844 SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
1845 stat_ptr += 4;
1846 SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
1847 stat_ptr += 2;
1848 SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
1849 stat_ptr += 2;
1850 SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
1851 stat_ptr += 2;
1852 SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
1853 stat_ptr += 2;
1854 SET_MEMORY_L (stat_ptr, stat_rec.st_size);
1855 stat_ptr += 4;
1856 SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
1857 stat_ptr += 8;
1858 SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
1859 stat_ptr += 8;
1860 SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
1861
1862 /* Return value in register 0. */
1863 cpu.regs[0] = stat_return;
1864 }
1865 goto next;
1866 /* End of system call processing. */
1867
c906108c
SS
1868 ONOT (O_NOT, rd = ~rd; v = 0;);
1869 OSHIFTS (O_SHLL,
1870 c = rd & hm; v = 0; rd <<= 1,
1871 c = rd & (hm >> 1); v = 0; rd <<= 2);
1872 OSHIFTS (O_SHLR,
1873 c = rd & 1; v = 0; rd = (unsigned int) rd >> 1,
1874 c = rd & 2; v = 0; rd = (unsigned int) rd >> 2);
1875 OSHIFTS (O_SHAL,
1876 c = rd & hm; v = (rd & hm) != ((rd & (hm >> 1)) << 1); rd <<= 1,
1877 c = rd & (hm >> 1); v = (rd & (hm >> 1)) != ((rd & (hm >> 2)) << 2); rd <<= 2);
1878 OSHIFTS (O_SHAR,
1879 t = rd & hm; c = rd & 1; v = 0; rd >>= 1; rd |= t,
d1335144 1880 t = rd & hm; c = rd & 2; v = 0; rd >>= 2; rd |= t | t >> 1);
c906108c
SS
1881 OSHIFTS (O_ROTL,
1882 c = rd & hm; v = 0; rd <<= 1; rd |= C,
1883 c = rd & hm; v = 0; rd <<= 1; rd |= C; c = rd & hm; rd <<= 1; rd |= C);
1884 OSHIFTS (O_ROTR,
1885 c = rd & 1; v = 0; rd = (unsigned int) rd >> 1; if (c) rd |= hm,
1886 c = rd & 1; v = 0; rd = (unsigned int) rd >> 1; if (c) rd |= hm; c = rd & 1; rd = (unsigned int) rd >> 1; if (c) rd |= hm);
1887 OSHIFTS (O_ROTXL,
1888 t = rd & hm; rd <<= 1; rd |= C; c = t; v = 0,
1889 t = rd & hm; rd <<= 1; rd |= C; c = t; v = 0; t = rd & hm; rd <<= 1; rd |= C; c = t);
1890 OSHIFTS (O_ROTXR,
1891 t = rd & 1; rd = (unsigned int) rd >> 1; if (C) rd |= hm; c = t; v = 0,
1892 t = rd & 1; rd = (unsigned int) rd >> 1; if (C) rd |= hm; c = t; v = 0; t = rd & 1; rd = (unsigned int) rd >> 1; if (C) rd |= hm; c = t);
1893
1894 case O (O_JMP, SB):
1895 {
1896 pc = fetch (&code->src);
1897 goto end;
1898
1899 }
1900
1901 case O (O_JSR, SB):
1902 {
1903 int tmp;
1904 pc = fetch (&code->src);
1905 call:
1906 tmp = cpu.regs[7];
1907
1908 if (h8300hmode)
1909 {
1910 tmp -= 4;
1911 SET_MEMORY_L (tmp, code->next_pc);
1912 }
1913 else
1914 {
1915 tmp -= 2;
1916 SET_MEMORY_W (tmp, code->next_pc);
1917 }
1918 cpu.regs[7] = tmp;
1919
1920 goto end;
1921 }
1922 case O (O_BSR, SB):
1923 pc = code->src.literal;
1924 goto call;
1925
1926 case O (O_RTS, SN):
1927 {
1928 int tmp;
1929
1930 tmp = cpu.regs[7];
1931
1932 if (h8300hmode)
1933 {
1934 pc = GET_MEMORY_L (tmp);
1935 tmp += 4;
1936 }
1937 else
1938 {
1939 pc = GET_MEMORY_W (tmp);
1940 tmp += 2;
1941 }
1942
1943 cpu.regs[7] = tmp;
1944 goto end;
1945 }
1946
1947 case O (O_ILL, SB):
1948 cpu.state = SIM_STATE_STOPPED;
1949 cpu.exception = SIGILL;
1950 goto end;
1951 case O (O_SLEEP, SN):
c906108c
SS
1952 /* FIXME: Doesn't this break for breakpoints when r0
1953 contains just the right (er, wrong) value? */
1954 cpu.state = SIM_STATE_STOPPED;
97ee9e5a
FCE
1955 /* The format of r0 is defined by target newlib. Expand
1956 the macros here instead of looking for .../sys/wait.h. */
1957#define SIM_WIFEXITED(v) (((v) & 0xff) == 0)
1958#define SIM_WIFSIGNALED(v) (((v) & 0x7f) > 0 && (((v) & 0x7f) < 0x7f))
c3f4437e 1959 if (! SIM_WIFEXITED (cpu.regs[0]) && SIM_WIFSIGNALED (cpu.regs[0]))
c906108c
SS
1960 cpu.exception = SIGILL;
1961 else
1962 cpu.exception = SIGTRAP;
c906108c
SS
1963 goto end;
1964 case O (O_BPT, SN):
1965 cpu.state = SIM_STATE_STOPPED;
1966 cpu.exception = SIGTRAP;
1967 goto end;
1968
1969 OBITOP (O_BNOT, 1, 1, ea ^= m);
1970 OBITOP (O_BTST, 1, 0, nz = ea & m);
1971 OBITOP (O_BCLR, 1, 1, ea &= ~m);
c3f4437e 1972 OBITOP (O_BSET, 1, 1, ea |= m);
c906108c
SS
1973 OBITOP (O_BLD, 1, 0, c = ea & m);
1974 OBITOP (O_BILD, 1, 0, c = !(ea & m));
1975 OBITOP (O_BST, 1, 1, ea &= ~m;
1976 if (C) ea |= m);
1977 OBITOP (O_BIST, 1, 1, ea &= ~m;
1978 if (!C) ea |= m);
1979 OBITOP (O_BAND, 1, 0, c = (ea & m) && C);
1980 OBITOP (O_BIAND, 1, 0, c = !(ea & m) && C);
1981 OBITOP (O_BOR, 1, 0, c = (ea & m) || C);
1982 OBITOP (O_BIOR, 1, 0, c = !(ea & m) || C);
ad4cda16 1983 OBITOP (O_BXOR, 1, 0, c = ((ea & m) != 0) != C);
c906108c
SS
1984 OBITOP (O_BIXOR, 1, 0, c = !(ea & m) != C);
1985
de9b1892
KH
1986#define MOP(bsize, signed) \
1987 mop (code, bsize, signed); \
1988 goto next;
c906108c
SS
1989
1990 case O (O_MULS, SB):
1991 MOP (1, 1);
1992 break;
1993 case O (O_MULS, SW):
1994 MOP (0, 1);
1995 break;
1996 case O (O_MULU, SB):
1997 MOP (1, 0);
1998 break;
1999 case O (O_MULU, SW):
2000 MOP (0, 0);
2001 break;
2002
6147b1f6 2003 case O (O_TAS, SB):
d1335144 2004 if (!h8300smode || code->src.type != X (OP_REG, SL))
c3f4437e 2005 goto illegal;
d1335144 2006 switch (code->src.reg)
c3f4437e
KH
2007 {
2008 case R0_REGNUM:
2009 case R1_REGNUM:
2010 case R4_REGNUM:
2011 case R5_REGNUM:
2012 break;
2013 default:
2014 goto illegal;
2015 }
2016 res = fetch (&code->src);
d0fe2f7e 2017 store (&code->src, res | 0x80);
6147b1f6 2018 goto just_flags_log8;
c906108c
SS
2019
2020 case O (O_DIVU, SB):
2021 {
2022 rd = GET_W_REG (code->dst.reg);
2023 ea = GET_B_REG (code->src.reg);
2024 if (ea)
2025 {
de9b1892
KH
2026 tmp = (unsigned) rd % ea;
2027 rd = (unsigned) rd / ea;
c906108c
SS
2028 }
2029 SET_W_REG (code->dst.reg, (rd & 0xff) | (tmp << 8));
2030 n = ea & 0x80;
2031 nz = ea & 0xff;
2032
2033 goto next;
2034 }
2035 case O (O_DIVU, SW):
2036 {
2037 rd = GET_L_REG (code->dst.reg);
2038 ea = GET_W_REG (code->src.reg);
2039 n = ea & 0x8000;
2040 nz = ea & 0xffff;
2041 if (ea)
2042 {
de9b1892
KH
2043 tmp = (unsigned) rd % ea;
2044 rd = (unsigned) rd / ea;
c906108c
SS
2045 }
2046 SET_L_REG (code->dst.reg, (rd & 0xffff) | (tmp << 16));
2047 goto next;
2048 }
2049
2050 case O (O_DIVS, SB):
2051 {
2052
2053 rd = SEXTSHORT (GET_W_REG (code->dst.reg));
2054 ea = SEXTCHAR (GET_B_REG (code->src.reg));
2055 if (ea)
2056 {
2057 tmp = (int) rd % (int) ea;
2058 rd = (int) rd / (int) ea;
2059 n = rd & 0x8000;
2060 nz = 1;
2061 }
2062 else
2063 nz = 0;
2064 SET_W_REG (code->dst.reg, (rd & 0xff) | (tmp << 8));
2065 goto next;
2066 }
2067 case O (O_DIVS, SW):
2068 {
2069 rd = GET_L_REG (code->dst.reg);
2070 ea = SEXTSHORT (GET_W_REG (code->src.reg));
2071 if (ea)
2072 {
2073 tmp = (int) rd % (int) ea;
2074 rd = (int) rd / (int) ea;
2075 n = rd & 0x80000000;
2076 nz = 1;
2077 }
2078 else
2079 nz = 0;
2080 SET_L_REG (code->dst.reg, (rd & 0xffff) | (tmp << 16));
2081 goto next;
2082 }
2083 case O (O_EXTS, SW):
ec38ce99 2084 rd = GET_W_REG (code->src.reg) & 0xff; /* Yes, src, not dst. */
c906108c
SS
2085 ea = rd & 0x80 ? -256 : 0;
2086 res = rd + ea;
2087 goto log16;
2088 case O (O_EXTS, SL):
2089 rd = GET_W_REG (code->src.reg) & 0xffff;
2090 ea = rd & 0x8000 ? -65536 : 0;
2091 res = rd + ea;
2092 goto log32;
2093 case O (O_EXTU, SW):
ec38ce99 2094 rd = GET_W_REG (code->src.reg) & 0xff;
c906108c
SS
2095 ea = 0;
2096 res = rd + ea;
2097 goto log16;
2098 case O (O_EXTU, SL):
2099 rd = GET_W_REG (code->src.reg) & 0xffff;
2100 ea = 0;
2101 res = rd + ea;
2102 goto log32;
2103
2104 case O (O_NOP, SN):
2105 goto next;
2106
2107 case O (O_STM, SL):
2108 {
2109 int nregs, firstreg, i;
2110
2111 nregs = GET_MEMORY_B (pc + 1);
2112 nregs >>= 4;
2113 nregs &= 0xf;
2114 firstreg = GET_MEMORY_B (pc + 3);
2115 firstreg &= 0xf;
2116 for (i = firstreg; i <= firstreg + nregs; i++)
2117 {
2118 cpu.regs[7] -= 4;
2119 SET_MEMORY_L (cpu.regs[7], cpu.regs[i]);
2120 }
2121 }
2122 goto next;
2123
2124 case O (O_LDM, SL):
2125 {
2126 int nregs, firstreg, i;
2127
2128 nregs = GET_MEMORY_B (pc + 1);
2129 nregs >>= 4;
2130 nregs &= 0xf;
2131 firstreg = GET_MEMORY_B (pc + 3);
2132 firstreg &= 0xf;
2133 for (i = firstreg; i >= firstreg - nregs; i--)
2134 {
2135 cpu.regs[i] = GET_MEMORY_L (cpu.regs[7]);
2136 cpu.regs[7] += 4;
2137 }
2138 }
2139 goto next;
2140
b7f97e9c
MS
2141 case O (O_DAA, SB):
2142 /* Decimal Adjust Addition. This is for BCD arithmetic. */
2143 res = GET_B_REG (code->src.reg);
2144 if (!c && (0 <= (res >> 4) && (res >> 4) <= 9)
2145 && !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
2146 res = res; /* Value added == 0. */
2147 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8)
2148 && !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
2149 res = res + 0x6; /* Value added == 6. */
2150 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 9)
2151 && h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
2152 res = res + 0x6; /* Value added == 6. */
2153 else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15)
2154 && !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
2155 res = res + 0x60; /* Value added == 60. */
2156 else if (!c && (9 <= (res >> 4) && (res >> 4) <= 15)
2157 && !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
2158 res = res + 0x66; /* Value added == 66. */
2159 else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15)
2160 && h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
2161 res = res + 0x66; /* Value added == 66. */
2162 else if (c && (1 <= (res >> 4) && (res >> 4) <= 2)
2163 && !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
2164 res = res + 0x160; /* Value added == 60, plus 'carry'. */
2165 else if (c && (1 <= (res >> 4) && (res >> 4) <= 2)
2166 && !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
2167 res = res + 0x166; /* Value added == 66, plus 'carry'. */
2168 else if (c && (1 <= (res >> 4) && (res >> 4) <= 3)
2169 && h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
2170 res = res + 0x166; /* Value added == 66, plus 'carry'. */
2171
2172 goto alu8;
2173
2174 case O (O_DAS, SB):
2175 /* Decimal Adjust Subtraction. This is for BCD arithmetic. */
2176 res = GET_B_REG (code->src.reg); /* FIXME fetch, fetch2... */
2177 if (!c && (0 <= (res >> 4) && (res >> 4) <= 9)
2178 && !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
2179 res = res; /* Value added == 0. */
2180 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8)
2181 && h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
2182 res = res + 0xfa; /* Value added == 0xfa. */
2183 else if (c && (7 <= (res >> 4) && (res >> 4) <= 15)
2184 && !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
2185 res = res + 0xa0; /* Value added == 0xa0. */
2186 else if (c && (6 <= (res >> 4) && (res >> 4) <= 15)
2187 && h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
2188 res = res + 0x9a; /* Value added == 0x9a. */
2189
2190 goto alu8;
2191
c906108c 2192 default:
d0fe2f7e 2193 illegal:
c906108c
SS
2194 cpu.state = SIM_STATE_STOPPED;
2195 cpu.exception = SIGILL;
2196 goto end;
2197
2198 }
2199 abort ();
2200
2201 setc:
d1335144 2202 if (code->dst.type == OP_CCR)
c3f4437e
KH
2203 {
2204 cpu.ccr = res;
2205 GETSR ();
2206 }
d1335144 2207 else if (code->dst.type == OP_EXR && h8300smode)
c3f4437e
KH
2208 {
2209 cpu.exr = res;
2210 GETEXR ();
2211 }
fc974602 2212 else
c3f4437e 2213 goto illegal;
fc974602 2214
c906108c
SS
2215 goto next;
2216
2217 condtrue:
2218 /* When a branch works */
2219 pc = code->src.literal;
2220 goto end;
2221
2222 /* Set the cond codes from res */
2223 bitop:
2224
2225 /* Set the flags after an 8 bit inc/dec operation */
2226 just_flags_inc8:
2227 n = res & 0x80;
2228 nz = res & 0xff;
2229 v = (rd & 0x7f) == 0x7f;
2230 goto next;
2231
2232
2233 /* Set the flags after an 16 bit inc/dec operation */
2234 just_flags_inc16:
2235 n = res & 0x8000;
2236 nz = res & 0xffff;
2237 v = (rd & 0x7fff) == 0x7fff;
2238 goto next;
2239
2240
2241 /* Set the flags after an 32 bit inc/dec operation */
2242 just_flags_inc32:
2243 n = res & 0x80000000;
2244 nz = res & 0xffffffff;
2245 v = (rd & 0x7fffffff) == 0x7fffffff;
2246 goto next;
2247
2248
2249 shift8:
2250 /* Set flags after an 8 bit shift op, carry,overflow set in insn */
2251 n = (rd & 0x80);
2252 nz = rd & 0xff;
2253 SET_B_REG (code->src.reg, rd);
2254 goto next;
2255
2256 shift16:
2257 /* Set flags after an 16 bit shift op, carry,overflow set in insn */
2258 n = (rd & 0x8000);
2259 nz = rd & 0xffff;
2260 SET_W_REG (code->src.reg, rd);
2261 goto next;
2262
2263 shift32:
2264 /* Set flags after an 32 bit shift op, carry,overflow set in insn */
2265 n = (rd & 0x80000000);
2266 nz = rd & 0xffffffff;
2267 SET_L_REG (code->src.reg, rd);
2268 goto next;
2269
2270 log32:
2271 store (&code->dst, res);
2272 just_flags_log32:
2273 /* flags after a 32bit logical operation */
2274 n = res & 0x80000000;
2275 nz = res & 0xffffffff;
2276 v = 0;
2277 goto next;
2278
2279 log16:
2280 store (&code->dst, res);
2281 just_flags_log16:
2282 /* flags after a 16bit logical operation */
2283 n = res & 0x8000;
2284 nz = res & 0xffff;
2285 v = 0;
2286 goto next;
2287
2288
2289 log8:
2290 store (&code->dst, res);
2291 just_flags_log8:
2292 n = res & 0x80;
2293 nz = res & 0xff;
2294 v = 0;
2295 goto next;
2296
2297 alu8:
2298 SET_B_REG (code->dst.reg, res);
2299 just_flags_alu8:
2300 n = res & 0x80;
2301 nz = res & 0xff;
2302 c = (res & 0x100);
2303 switch (code->opcode / 4)
2304 {
2305 case O_ADD:
2306 v = ((rd & 0x80) == (ea & 0x80)
2307 && (rd & 0x80) != (res & 0x80));
2308 break;
2309 case O_SUB:
2310 case O_CMP:
2311 v = ((rd & 0x80) != (-ea & 0x80)
2312 && (rd & 0x80) != (res & 0x80));
2313 break;
2314 case O_NEG:
2315 v = (rd == 0x80);
2316 break;
2317 }
2318 goto next;
2319
2320 alu16:
2321 SET_W_REG (code->dst.reg, res);
2322 just_flags_alu16:
2323 n = res & 0x8000;
2324 nz = res & 0xffff;
2325 c = (res & 0x10000);
2326 switch (code->opcode / 4)
2327 {
2328 case O_ADD:
2329 v = ((rd & 0x8000) == (ea & 0x8000)
2330 && (rd & 0x8000) != (res & 0x8000));
2331 break;
2332 case O_SUB:
2333 case O_CMP:
2334 v = ((rd & 0x8000) != (-ea & 0x8000)
2335 && (rd & 0x8000) != (res & 0x8000));
2336 break;
2337 case O_NEG:
2338 v = (rd == 0x8000);
2339 break;
2340 }
2341 goto next;
2342
2343 alu32:
2344 SET_L_REG (code->dst.reg, res);
2345 just_flags_alu32:
2346 n = res & 0x80000000;
2347 nz = res & 0xffffffff;
2348 switch (code->opcode / 4)
2349 {
2350 case O_ADD:
2351 v = ((rd & 0x80000000) == (ea & 0x80000000)
2352 && (rd & 0x80000000) != (res & 0x80000000));
2353 c = ((unsigned) res < (unsigned) rd) || ((unsigned) res < (unsigned) ea);
2354 break;
2355 case O_SUB:
2356 case O_CMP:
2357 v = ((rd & 0x80000000) != (-ea & 0x80000000)
2358 && (rd & 0x80000000) != (res & 0x80000000));
2359 c = (unsigned) rd < (unsigned) -ea;
2360 break;
2361 case O_NEG:
2362 v = (rd == 0x80000000);
2363 c = res != 0;
2364 break;
2365 }
2366 goto next;
2367
2368 next:;
2369 pc = code->next_pc;
2370
2371 end:
2372 ;
de9b1892
KH
2373#if 0
2374 if (cpu.regs[8])
2375 abort ();
2376#endif
c906108c
SS
2377
2378 if (--poll_count < 0)
2379 {
7a292a7a 2380 poll_count = POLL_QUIT_INTERVAL;
c906108c
SS
2381 if ((*sim_callback->poll_quit) != NULL
2382 && (*sim_callback->poll_quit) (sim_callback))
2383 sim_stop (sd);
2384 }
2385
2386 }
2387 while (cpu.state == SIM_STATE_RUNNING);
2388 cpu.ticks += get_now () - tick_start;
2389 cpu.cycles += cycles;
2390 cpu.insts += insts;
de9b1892 2391
c906108c
SS
2392 cpu.pc = pc;
2393 BUILDSR ();
d1335144 2394 BUILDEXR ();
c906108c
SS
2395 cpu.mask = oldmask;
2396 signal (SIGINT, prev);
2397}
2398
2399int
a4f27e3e 2400sim_trace (SIM_DESC sd)
c906108c 2401{
2ea716f6 2402 /* FIXME: Unfinished. */
c906108c
SS
2403 abort ();
2404}
2405
2406int
a4f27e3e 2407sim_write (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
c906108c
SS
2408{
2409 int i;
2410
2411 init_pointers ();
2412 if (addr < 0)
2413 return 0;
2414 for (i = 0; i < size; i++)
2415 {
2416 if (addr < memory_size)
2417 {
2418 cpu.memory[addr + i] = buffer[i];
2419 cpu.cache_idx[addr + i] = 0;
2420 }
2421 else
2422 cpu.eightbit[(addr + i) & 0xff] = buffer[i];
2423 }
2424 return size;
2425}
2426
2427int
a4f27e3e 2428sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
c906108c
SS
2429{
2430 init_pointers ();
2431 if (addr < 0)
2432 return 0;
2433 if (addr < memory_size)
2434 memcpy (buffer, cpu.memory + addr, size);
2435 else
2436 memcpy (buffer, cpu.eightbit + (addr & 0xff), size);
2437 return size;
2438}
2439
2440
c906108c 2441int
a4f27e3e 2442sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
c906108c
SS
2443{
2444 int longval;
2445 int shortval;
2446 int intval;
2447 longval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
2448 shortval = (value[0] << 8) | (value[1]);
2449 intval = h8300hmode ? longval : shortval;
2450
2451 init_pointers ();
2452 switch (rn)
2453 {
2454 case PC_REGNUM:
2455 cpu.pc = intval;
2456 break;
2457 default:
2458 abort ();
2459 case R0_REGNUM:
2460 case R1_REGNUM:
2461 case R2_REGNUM:
2462 case R3_REGNUM:
2463 case R4_REGNUM:
2464 case R5_REGNUM:
2465 case R6_REGNUM:
2466 case R7_REGNUM:
2467 cpu.regs[rn] = intval;
2468 break;
2469 case CCR_REGNUM:
2470 cpu.ccr = intval;
2471 break;
fc974602
AV
2472 case EXR_REGNUM:
2473 cpu.exr = intval;
2474 break;
c906108c
SS
2475 case CYCLE_REGNUM:
2476 cpu.cycles = longval;
2477 break;
2478
2479 case INST_REGNUM:
2480 cpu.insts = longval;
2481 break;
2482
2483 case TICK_REGNUM:
2484 cpu.ticks = longval;
2485 break;
2486 }
2487 return -1;
2488}
2489
2490int
a4f27e3e 2491sim_fetch_register (SIM_DESC sd, int rn, unsigned char *buf, int length)
c906108c
SS
2492{
2493 int v;
2494 int longreg = 0;
2495
2496 init_pointers ();
2497
d0fe2f7e 2498 if (!h8300smode && rn >= EXR_REGNUM)
c3f4437e 2499 rn++;
c906108c
SS
2500 switch (rn)
2501 {
2502 default:
2503 abort ();
3b02cf92 2504 case CCR_REGNUM:
c906108c
SS
2505 v = cpu.ccr;
2506 break;
fc974602
AV
2507 case EXR_REGNUM:
2508 v = cpu.exr;
2509 break;
3b02cf92 2510 case PC_REGNUM:
c906108c
SS
2511 v = cpu.pc;
2512 break;
2513 case R0_REGNUM:
2514 case R1_REGNUM:
2515 case R2_REGNUM:
2516 case R3_REGNUM:
2517 case R4_REGNUM:
2518 case R5_REGNUM:
2519 case R6_REGNUM:
2520 case R7_REGNUM:
2521 v = cpu.regs[rn];
2522 break;
3b02cf92 2523 case CYCLE_REGNUM:
c906108c
SS
2524 v = cpu.cycles;
2525 longreg = 1;
2526 break;
3b02cf92 2527 case TICK_REGNUM:
c906108c
SS
2528 v = cpu.ticks;
2529 longreg = 1;
2530 break;
3b02cf92 2531 case INST_REGNUM:
c906108c
SS
2532 v = cpu.insts;
2533 longreg = 1;
2534 break;
2535 }
2536 if (h8300hmode || longreg)
2537 {
2538 buf[0] = v >> 24;
2539 buf[1] = v >> 16;
2540 buf[2] = v >> 8;
2541 buf[3] = v >> 0;
2542 }
2543 else
2544 {
2545 buf[0] = v >> 8;
2546 buf[1] = v;
2547 }
2548 return -1;
2549}
2550
2551void
a4f27e3e 2552sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
c906108c
SS
2553{
2554#if 0 /* FIXME: This should work but we can't use it.
2555 grep for SLEEP above. */
2556 switch (cpu.state)
2557 {
2558 case SIM_STATE_EXITED : *reason = sim_exited; break;
2559 case SIM_STATE_SIGNALLED : *reason = sim_signalled; break;
2560 case SIM_STATE_STOPPED : *reason = sim_stopped; break;
2561 default : abort ();
2562 }
2563#else
2564 *reason = sim_stopped;
2565#endif
2566 *sigrc = cpu.exception;
2567}
2568
2569/* FIXME: Rename to sim_set_mem_size. */
2570
2571void
a4f27e3e 2572sim_size (int n)
c906108c
SS
2573{
2574 /* Memory size is fixed. */
2575}
2576
2577void
a4f27e3e 2578sim_set_simcache_size (int n)
c906108c
SS
2579{
2580 if (cpu.cache)
2581 free (cpu.cache);
2582 if (n < 2)
2583 n = 2;
2584 cpu.cache = (decoded_inst *) malloc (sizeof (decoded_inst) * n);
2585 memset (cpu.cache, 0, sizeof (decoded_inst) * n);
2586 cpu.csize = n;
2587}
2588
2589
2590void
a4f27e3e 2591sim_info (SIM_DESC sd, int verbose)
c906108c
SS
2592{
2593 double timetaken = (double) cpu.ticks / (double) now_persec ();
2594 double virttime = cpu.cycles / 10.0e6;
2595
2596 (*sim_callback->printf_filtered) (sim_callback,
2597 "\n\n#instructions executed %10d\n",
2598 cpu.insts);
2599 (*sim_callback->printf_filtered) (sim_callback,
2600 "#cycles (v approximate) %10d\n",
2601 cpu.cycles);
2602 (*sim_callback->printf_filtered) (sim_callback,
2603 "#real time taken %10.4f\n",
2604 timetaken);
2605 (*sim_callback->printf_filtered) (sim_callback,
2606 "#virtual time taked %10.4f\n",
2607 virttime);
2608 if (timetaken != 0.0)
2609 (*sim_callback->printf_filtered) (sim_callback,
2610 "#simulation ratio %10.4f\n",
2611 virttime / timetaken);
2612 (*sim_callback->printf_filtered) (sim_callback,
2613 "#compiles %10d\n",
2614 cpu.compiles);
2615 (*sim_callback->printf_filtered) (sim_callback,
2616 "#cache size %10d\n",
2617 cpu.csize);
2618
2619#ifdef ADEBUG
2620 /* This to be conditional on `what' (aka `verbose'),
2621 however it was never passed as non-zero. */
2622 if (1)
2623 {
2624 int i;
2625 for (i = 0; i < O_LAST; i++)
2626 {
2627 if (cpu.stats[i])
2628 (*sim_callback->printf_filtered) (sim_callback,
2629 "%d: %d\n", i, cpu.stats[i]);
2630 }
2631 }
2632#endif
2633}
2634
2ea716f6
KH
2635/* Indicate whether the cpu is an H8/300 or H8/300H.
2636 FLAG is non-zero for the H8/300H. */
c906108c
SS
2637
2638void
a4f27e3e 2639set_h8300h (int h_flag, int s_flag)
c906108c
SS
2640{
2641 /* FIXME: Much of the code in sim_load can be moved to sim_open.
2642 This function being replaced by a sim_open:ARGV configuration
2ea716f6 2643 option. */
a8cdafbd
AV
2644 h8300hmode = h_flag;
2645 h8300smode = s_flag;
c906108c
SS
2646}
2647
2648SIM_DESC
a4f27e3e
MS
2649sim_open (SIM_OPEN_KIND kind,
2650 struct host_callback_struct *ptr,
6b4a8935 2651 struct bfd *abfd,
a4f27e3e 2652 char **argv)
c906108c 2653{
2ea716f6 2654 /* FIXME: Much of the code in sim_load can be moved here. */
c906108c
SS
2655
2656 sim_kind = kind;
2657 myname = argv[0];
2658 sim_callback = ptr;
2ea716f6 2659 /* Fudge our descriptor. */
c906108c
SS
2660 return (SIM_DESC) 1;
2661}
2662
2663void
a4f27e3e 2664sim_close (SIM_DESC sd, int quitting)
c906108c 2665{
2ea716f6 2666 /* Nothing to do. */
c906108c
SS
2667}
2668
2669/* Called by gdb to load a program into memory. */
2670
2671SIM_RC
a4f27e3e 2672sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
c906108c
SS
2673{
2674 bfd *prog_bfd;
2675
2ea716f6
KH
2676 /* FIXME: The code below that sets a specific variant of the H8/300
2677 being simulated should be moved to sim_open(). */
c906108c 2678
2ea716f6 2679 /* See if the file is for the H8/300 or H8/300H. */
c906108c
SS
2680 /* ??? This may not be the most efficient way. The z8k simulator
2681 does this via a different mechanism (INIT_EXTRA_SYMTAB_INFO). */
2682 if (abfd != NULL)
2683 prog_bfd = abfd;
2684 else
2685 prog_bfd = bfd_openr (prog, "coff-h8300");
2686 if (prog_bfd != NULL)
2687 {
2688 /* Set the cpu type. We ignore failure from bfd_check_format
2689 and bfd_openr as sim_load_file checks too. */
de9b1892 2690 if (bfd_check_format (prog_bfd, bfd_object))
c906108c
SS
2691 {
2692 unsigned long mach = bfd_get_mach (prog_bfd);
a8cdafbd
AV
2693 set_h8300h (mach == bfd_mach_h8300h || mach == bfd_mach_h8300s,
2694 mach == bfd_mach_h8300s);
c906108c
SS
2695 }
2696 }
2697
2698 /* If we're using gdb attached to the simulator, then we have to
2699 reallocate memory for the simulator.
2700
2701 When gdb first starts, it calls fetch_registers (among other
2702 functions), which in turn calls init_pointers, which allocates
2703 simulator memory.
2704
2705 The problem is when we do that, we don't know whether we're
2ea716f6 2706 debugging an H8/300 or H8/300H program.
c906108c
SS
2707
2708 This is the first point at which we can make that determination,
2709 so we just reallocate memory now; this will also allow us to handle
2ea716f6 2710 switching between H8/300 and H8/300H programs without exiting
c906108c 2711 gdb. */
a8cdafbd
AV
2712
2713 if (h8300smode)
2714 memory_size = H8300S_MSIZE;
2715 else if (h8300hmode)
c906108c
SS
2716 memory_size = H8300H_MSIZE;
2717 else
2718 memory_size = H8300_MSIZE;
2719
2720 if (cpu.memory)
2721 free (cpu.memory);
2722 if (cpu.cache_idx)
2723 free (cpu.cache_idx);
2724 if (cpu.eightbit)
2725 free (cpu.eightbit);
2726
2727 cpu.memory = (unsigned char *) calloc (sizeof (char), memory_size);
2728 cpu.cache_idx = (unsigned short *) calloc (sizeof (short), memory_size);
2729 cpu.eightbit = (unsigned char *) calloc (sizeof (char), 256);
2730
2ea716f6 2731 /* `msize' must be a power of two. */
c906108c
SS
2732 if ((memory_size & (memory_size - 1)) != 0)
2733 abort ();
2734 cpu.mask = memory_size - 1;
2735
2736 if (sim_load_file (sd, myname, sim_callback, prog, prog_bfd,
2737 sim_kind == SIM_OPEN_DEBUG,
2738 0, sim_write)
2739 == NULL)
2740 {
2741 /* Close the bfd if we opened it. */
2742 if (abfd == NULL && prog_bfd != NULL)
2743 bfd_close (prog_bfd);
2744 return SIM_RC_FAIL;
2745 }
2746
2747 /* Close the bfd if we opened it. */
2748 if (abfd == NULL && prog_bfd != NULL)
2749 bfd_close (prog_bfd);
2750 return SIM_RC_OK;
2751}
2752
2753SIM_RC
6b4a8935 2754sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
c906108c 2755{
d1360fb0
V
2756 int i = 0;
2757 int len_arg = 0;
2758 int no_of_args = 0;
2759
c906108c
SS
2760 if (abfd != NULL)
2761 cpu.pc = bfd_get_start_address (abfd);
2762 else
2763 cpu.pc = 0;
d1360fb0
V
2764
2765 /* Command Line support. */
2766 if (argv != NULL)
2767 {
2768 /* Counting the no. of commandline arguments. */
2769 for (no_of_args = 0; argv[no_of_args] != NULL; no_of_args++)
2770 continue;
2771
2772 /* Allocating memory for the argv pointers. */
2773 ptr_command_line = (char **) malloc ((sizeof (char *))
2774 * (no_of_args + 1));
2775
2776 for (i = 0; i < no_of_args; i++)
2777 {
2778 /* Calculating the length of argument for allocating memory. */
2779 len_arg = strlen (argv[i] + 1);
2780 ptr_command_line[i] = (char *) malloc (sizeof (char) * len_arg);
2781 /* Copying the argument string. */
2782 ptr_command_line[i] = (char *) strdup (argv[i]);
2783 }
2784 ptr_command_line[i] = NULL;
2785 }
2786
c906108c
SS
2787 return SIM_RC_OK;
2788}
2789
2790void
a4f27e3e 2791sim_do_command (SIM_DESC sd, char *cmd)
c906108c
SS
2792{
2793 (*sim_callback->printf_filtered) (sim_callback,
2794 "This simulator does not accept any commands.\n");
2795}
2796
2797void
a4f27e3e 2798sim_set_callbacks (struct host_callback_struct *ptr)
c906108c
SS
2799{
2800 sim_callback = ptr;
2801}