This commit was generated by cvs2svn to track changes on a CVS vendor
[deliverable/binutils-gdb.git] / sim / z8k / support.c
CommitLineData
c906108c
SS
1/* support routines for interpreted instructions
2 Copyright (C) 1992, 1993 Free Software Foundation, Inc.
3
4This file is part of Z8KSIM
5
6Z8KSIM is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11Z8KSIM is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with Z8KZIM; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20#include "config.h"
21
22#include <ansidecl.h>
23#include <signal.h>
24#include <errno.h>
25
26#include "tm.h"
27#include "sim.h"
28#include "mem.h"
29#include <stdio.h>
30#ifdef HAVE_TIME_H
31#include <time.h>
32#endif
33#ifdef HAVE_SYS_TIMES_H
34#include <sys/times.h>
35#endif
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <sys/param.h>
3c25f8c7
AC
39#include "gdb/callback.h"
40#include "gdb/remote-sim.h"
c906108c
SS
41#include "syscall.h"
42
43static int get_now PARAMS ((void));
44static int now_persec PARAMS ((void));
45static int put_long PARAMS ((sim_state_type * context, int ptr, int value));
46static int put_short PARAMS ((sim_state_type * context, int ptr, int value));
47
48int sim_z8001_mode;
49
50static int
51get_now ()
52{
53#ifdef HAVE_SYS_TIMES_H
54 struct tms b;
55
56 times (&b);
57 return b.tms_utime + b.tms_stime;
58#else
59 return time (0);
60#endif
61}
62
63static int
64now_persec ()
65{
66 return 50;
67}
68
69
70/* #define LOG /* define this to print instruction use counts */
71
72#ifdef __GNUC__
73#define INLINE __inline__
74#include "inlines.h"
75#else
76#include "inlines.h"
77#endif
78
79/* This holds the entire cpu context */
80static sim_state_type the_state;
81
82int
83fail (context, dummy)
84 sim_state_type *context;
85 int dummy;
86{
87 context->exception = SIM_BAD_INST;
88 return 1;
89}
90
91void
92sfop_bad1 (context)
93 sim_state_type *context;
94{
95 context->exception
96 = SIM_BAD_INST;
97}
98
99void
100bfop_bad1 (context)
101 sim_state_type *context;
102{
103 context->exception
104 = SIM_BAD_INST;
105}
106
107void
108fop_bad (context)
109 sim_state_type *context;
110{
111 context->exception =
112 SIM_BAD_INST;
113}
114
115/* Table of bit counts for all byte values */
116
117char the_parity[256] =
118{
119 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3,
120 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4,
121 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2,
122 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5,
123 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4,
124 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3,
125 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2,
126 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
127 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
128 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5,
129 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6,
130 7, 7, 8};
131
132
133int read ();
134int write ();
135int open ();
136int close ();
137int open ();
138int close ();
139
140int link ();
141int fstat ();
142
143static int
144put_short (context, ptr, value)
145 sim_state_type *context;
146 int ptr;
147 int value;
148{
149 put_word_mem_da (context, ptr, value);
150 return ptr + 2;
151}
152
153static int
154put_long (context, ptr, value)
155 sim_state_type *context;
156 int
157 ptr;
158 int value;
159{
160 put_long_mem_da (context, ptr, value);
161 return ptr + 4;
162}
163
164#define aptr(x) ((sitoptr(x)) + (char *)(context->memory))
165
166static int args[3];
167static int arg_index; /* Translate a z8k system call into a host system call */
168void
169support_call (context, sc)
170 sim_state_type *context;
171 int sc;
172{
173 extern int errno;
174 int ret;
175 int retnext = 0;
176 int fd;
177
178 int olderrno = errno;
179 errno = 0;
180 switch (sc)
181 {
182 case SYS_ARG:
183 args[arg_index++] = context->regs[0].word << 16 | context->regs[1].word;
184 break;
185 case SYS_exit:
186 context->exception = SIM_DONE;
187 ret = args[0];
188 arg_index = 0;
189 break;
190 case SYS_close:
191 ret = close ((int) (args[0]));
192 arg_index = 0;
193 break;
194 case SYS_creat:
195 ret = creat (aptr (args[0]), args[1]);
196 arg_index = 0;
197 break;
198 case SYS_isatty:
199 ret = isatty (args[0]);
200 arg_index = 0;
201 break;
202 case SYS_open:
203 ret = open (aptr (args[0]), args[1], args[2]);
204 arg_index = 0;
205 break;
206 case SYS_lseek:
207 ret = lseek (args[0], (off_t) args[1], args[2]);
208 arg_index = 0;
209 break;
210 case SYS_read:
211 ret = read (args[0], aptr (args[1]), args[2]);
212 arg_index = 0;
213 break;
214 case SYS_write:
215 ret = write (args[0],aptr (args[1]), args[2]);
216 arg_index = 0;
217 break;
218 case SYS_time:
219 {
220 int dst = args[0];
221
222 ret = time (0);
223 if (dst)
224 {
225 put_long_mem_da (context,
226 sitoptr (dst), ret);
227 }
228 retnext = ret;
229 ret = retnext >> 16;
230 arg_index = 0;
231 }
232 break;
233 case SYS_fstat:
234 {
235 int buf;
236 struct stat host_stat;
237 fd = args[0];
238 buf = sitoptr (args[1]);
239 ret = fstat (fd, &host_stat);
240 buf = put_short (context, buf, host_stat.st_dev);
241 buf = put_short (context, buf, host_stat.st_ino);
242 /* FIXME: Isn't mode_t 4 bytes? */
243 buf = put_short (context, buf, host_stat.st_mode);
244 buf = put_short (context, buf, host_stat.st_nlink);
245 buf = put_short (context, buf, host_stat.st_uid);
246 buf = put_short (context, buf, host_stat.st_uid);
247 buf = put_short (context, buf, host_stat.st_rdev);
248 buf = put_long (context, buf, host_stat.st_size);
249 buf = put_long (context, buf, host_stat.st_atime);
250 arg_index = 0;
251 } break;
252 default:
253 case SYS_link:
254 context->exception = SIM_BAD_SYSCALL;
255 arg_index = 0;
256 break;
257 }
258 context->regs[2].word = ret;
259 context->regs[3].word = retnext;
260 context->regs[5].word = errno;
261
262
263 /* support for the stdcall calling convention */
264 context->regs[6].word = retnext;
265 context->regs[7].word = ret;
266
267 errno = olderrno;
268}
269
270#undef get_word_mem_da
271
272int
273get_word_mem_da (context, addr)
274 sim_state_type *context;
275 int addr;
276{
277 return (get_byte_mem_da (context, addr) << 8) | (get_byte_mem_da (context, addr + 1));
278
279}
280
281#undef get_word_reg
282int
283get_word_reg (context, reg) sim_state_type
284* context;
285 int reg;
286{
287 return context->regs[reg].word;
288}
289
290#ifdef LOG
291int log[64 * 1024];
292
293#endif
294
295void
296tm_store_register (regno, value)
297 int regno;
298 int value;
299{
300 switch
301 (regno)
302 {
303 case REG_PC:
304 the_state.sometimes_pc = value;
305 break;
306
307 default:
308 put_word_reg (&the_state, regno, value);
309 }
310}
311
312void
313swap_long (buf, val)
314 char *buf;
315 int val;
316{
317 buf[0] = val >> 24;
318 buf[1] = val >> 16;
319 buf[2] = val >> 8;
320 buf[3] = val >> 0;
321}
322
323void
324swap_word (buf, val)
325 char *buf;
326 int val;
327{
328 buf[0] = val >> 8;
329 buf[1] = val >> 0;
330}
331
332void
333tm_fetch_register (regno, buf)
334 int regno;
335 char *buf;
336{
337 switch
338 (regno)
339 {
340 case REG_CYCLES:
341 swap_long (buf, the_state.cycles);
342 break;
343 case REG_INSTS:
344 swap_long (buf, the_state.insts);
345 break;
346 case
347 REG_TIME:
348 swap_long (buf, the_state.ticks);
349 break;
350 case REG_PC:
351 swap_long (buf, the_state.sometimes_pc);
352 break;
353 case REG_SP:
354 {
355 if (sim_z8001_mode)
356 {
357 swap_long (buf, get_long_reg (&the_state, 14));
358 }
359 else
360 {
361 swap_long (buf, get_word_reg (&the_state, 15));
362 }
363 }
364 break;
365 case
366 REG_FP:
367 {
368 if (sim_z8001_mode)
369 {
370 swap_long (buf, get_long_reg
371 (&the_state, 10));
372 }
373 else
374 {
375 swap_long (buf,
376 get_word_reg (&the_state, 10));
377 }
378 }
379 break;
380 default:
381 {
382 swap_word (buf,
383 get_word_reg (&the_state, regno));
384 }
385 }
386}
387
388void
389tm_resume (step)
390 int step;
391{
392 int now = get_now ();
393 struct op_info
394 *p;
395 int word;
396 int pc;
397 extern int (*(sfop_table[])) ();
398 extern int (*(bfop_table[])) ();
399 int (*((*table))) ();
400 sim_state_type *context = &the_state;
401
402 if (step)
403 {
404 context->exception = SIM_SINGLE_STEP;
405 }
406 else
407 {
408 context->exception = 0;
409 }
410
411 pc = context->sometimes_pc;
412 if (sim_z8001_mode)
413 {
414 table = bfop_table;
415 pc = MAP_PHYSICAL_TO_LOGICAL (pc);
416 }
417 else
418 {
419 table = sfop_table;
420 }
421
422
423 do
424 {
425 word = get_word_mem_da (context, pc);
426 p = op_info_table + word;
427
428#ifdef LOG
429 log[word]++;
430#endif
431 pc = table[p->exec] (context, pc, word);
432 context->insts++;
433
434 }
435 while (!context->exception);
436
437
438
439 context->sometimes_pc = MAP_LOGICAL_TO_PHYSICAL (pc);
440 context->ticks += get_now () - now;
441}
442
443int
444tm_signal ()
445{
446 return the_state.exception;
447}
448
449void
450tm_info_print (x)
451 sim_state_type *x;
452{
453 double timetaken = (double) x->ticks / (double) now_persec ();
454 double virttime = x->cycles / 4.0e6;
455
456 printf ("instructions executed : %9d\n", x->insts);
457 printf ("cycles counted : %9d \n", x->cycles);
458 printf ("cycles / inst : %9.1f \n", (double) x->cycles / (double) x->insts);
459 printf ("virtual time taked (at 4 Mhz) : %9.1f \n", virttime);
460 printf ("real time taken : %9.1f \n", timetaken);
461
462 if (timetaken)
463 {
464 printf ("virtual instructions per second : %9.1f\n", x->insts / timetaken);
465 printf ("emulation speed : %9.1f%%\n", virttime / timetaken * 100.0);
466 }
467#ifdef LOG
468 {
469 extern int quick[];
470
471 for (i = 0; quick[i]; i++)
472 {
473 log[quick[i]] += 100000;
474 }
475 }
476
477 for (i = 0; i < 64 * 1024; i++)
478 {
479 if (log[i])
480 {
481 printf (" /*%7d*/ 0x%x,\n", log[i], i);
482 }
483 }
484#endif
485
486}
487
488int
489sim_trace (sd)
490 SIM_DESC sd;
491{
492 int i;
493 char buffer[10];
494 int r;
495
496 printf ("\n");
497 for (r = 0; r < 16; r++)
498 {
499 int m;
500
501 printf ("r%2d", r);
502 printf ("=%04x ", get_word_reg (&the_state,
503 r));
504 for (m = -4; m < 8; m++)
505 {
506 if (m == 0)
507 printf (">");
508 printf ("%04x ",
509 get_word_mem_da (&the_state, (0xfffe & get_word_reg (&the_state, r)) + m * 2));
510 }
511 printf ("\n");
512 }
513
514 printf ("\n");
515 printf ("%9d %9d %08x ", the_state.cycles,
516 the_state.insts, the_state.sometimes_pc);
517
518 for (i = 0; i < 6; i++)
519 {
520 buffer[i] = get_byte_mem_da (&the_state,
521 the_state.sometimes_pc + i);
522 }
523
524 print_insn_z8001 (the_state.sometimes_pc, buffer, stdout);
525 printf
526 ("\n");
527 tm_resume (1);
528 if (the_state.exception != SIM_SINGLE_STEP)
529 return 1;
530 return 0;
531}
532
533void
534tm_state (x)
535 sim_state_type *x;
536{
537 *x = the_state;
538}
539
540void
541tm_exception (x)
542 int x;
543{
544 the_state.exception = x;
545}
546
547int
548tm_read_byte (x)
549 int x;
550{
551 x &= 0x3f00ffff;
552 return sim_read_byte (&the_state, x);
553}
554
555void
556tm_write_byte (x, y)
557 int x, y;
558{
559 x &= 0x3f00ffff;
560 sim_write_byte (&the_state, x, y);
561}
562
563#define SIGN(x) ((x) & MASK)
564normal_flags_32(context,d,sa,sb,sub)
565sim_state_type *context;
566unsigned int d;
567unsigned int sa;
568unsigned int sb;
569unsigned int sub;
570{
571#undef MASK
572#define MASK (1<<31)
573 context->broken_flags = 0;
574 if (sub)
575 PSW_CARRY = sa < sb;
576 else
577 PSW_CARRY = d < sa;
578 if (sub)
579 PSW_OVERFLOW = (SIGN(sa) != SIGN(sb)) && (SIGN(d) == SIGN(sb));
580 else
581 PSW_OVERFLOW = (SIGN(sa) == SIGN(sb)) && (SIGN(d) != SIGN(sb));
582
583 PSW_SIGN = ((int)d) <0;
584 PSW_ZERO = d == 0;
585}
586
587normal_flags_16(context,d,sal,sbl,sub)
588sim_state_type *context;
589unsigned int d;
590unsigned int sal;
591unsigned int sbl;
592unsigned short int sub;
593{
594 unsigned short sa = sal;
595 unsigned short sb = sbl;
596#undef MASK
597#define MASK (1<<15)
598 context->broken_flags = 0;
599 if (sub)
600 PSW_CARRY = sal < sbl;
601 else
602 PSW_CARRY = (d & 0x10000) != 0;
603
604 if (sub)
605 PSW_OVERFLOW = (SIGN(sa) != SIGN(sb)) && (SIGN(d) == SIGN(sb));
606 else
607 PSW_OVERFLOW = (SIGN(sa) == SIGN(sb)) && (SIGN(d) != SIGN(sb));
608
609 PSW_SIGN = ((short int)d) <0;
610 PSW_ZERO = ((short)d) == 0;
611}
612
613normal_flags_8(context,d,sa,sb,sub)
614sim_state_type *context;
615unsigned char d;
616unsigned char sa;
617unsigned char sb;
618unsigned char sub;
619{
620#undef MASK
621#define MASK (1<<7)
622 context->broken_flags = 0;
623 if (sub)
624 PSW_CARRY = sa < sb;
625 else
626 PSW_CARRY = d < sa;
627 if (sub)
628 PSW_OVERFLOW = (SIGN(sa) != SIGN(sb)) && (SIGN(d) == SIGN(sb));
629 else
630 PSW_OVERFLOW = (SIGN(sa) == SIGN(sb)) && (SIGN(d) != SIGN(sb));
631 PSW_SIGN = ((char)d) <0;
632 PSW_ZERO = d == 0;
633}
634
635
636static int
637is_cond_true (context, c)
638 sim_state_type *context;
639 int c;
640{
641 switch (c)
642 {
643 case T:
644 return 1;
645 case F:
646 return 0; /* F */
647 case LE:
648 return (PSW_ZERO | (PSW_SIGN ^ PSW_OVERFLOW)) & 1; /*LE */
649 case GT:
650 return (~(PSW_ZERO | (PSW_SIGN ^ PSW_OVERFLOW))) & 1; /*GT */
651 case 0x5:
652 return (PSW_SIGN & 1); /* sign */
653 case 0xd:
654 return (~(PSW_SIGN)) & 1; /* not sign */
655 case 0x3:
656 return ((PSW_CARRY | PSW_ZERO) & 1); /* ule*/
657 case UGT:
658 return ((~(PSW_CARRY | PSW_ZERO)) & 1); /* ugt */
659 case 0x4:
660 return (PSW_OVERFLOW & 1);/* overflow */
661 case 0xc:
662 return (~(PSW_OVERFLOW)) & 1; /* not overflow */
663 case LT:
664 return (PSW_SIGN ^ PSW_OVERFLOW) & 1; /* LT */
665 case GE:
666 return (~(PSW_SIGN ^ PSW_OVERFLOW)) & 1; /* GE */
667 case EQ:
668 return (PSW_ZERO) & 1; /* zero */
669 case NE:
670 return ((~PSW_ZERO) & 1); /* not zero */
671 case 0x7:
672 return (PSW_CARRY) & 1; /* carry */
673 case 0xf:
674 return (~PSW_CARRY) & 1; /* not carry */
675 default:
676 abort ();
677 }
678}
679
680int
681COND (context, c)
682 sim_state_type *context;
683 int c;
684{
685 if (c == 8)
686 return 1;
687
688 /* We can calculate what the flags would have been by
689 looking at the src and dst and size of the operation */
690
691 if (context->broken_flags)
692 {
693 int slow = 0;
694 int size;
695 int dst;
696 int srca;
697 int srcb;
698 int mask;
699 int ans;
700
701 /* see if we can short-cut the nasty flag calcs */
702
703 switch (size = context->size)
704 {
705 default:
706 abort();
707 return 0;
708 case 8:
709 srca = (char) (context->srca);
710 srcb = (char) (context->srcb);
711 dst = (char) (context->dst);
712 mask = 0xff;
713 break;
714 case 16:
715 srca = (short) (context->srca);
716 srcb = (short) (context->srcb);
717 dst = (short) (context->dst);
718 mask = 0xffff;
719 break;
720 case 32:
721 srca = (long) (context->srca);
722 srcb = (long) (context->srcb);
723 dst = (long) (context->dst);
724 mask = 0xffffffff;
725 break;
726 }
727
728 switch (c)
729 {
730 case T:
731 return 1;
732 case F:
733 return 0;
734 case EQ:
735 return !dst;
736 case NE:
737 return dst;
738 case GT:
739 ans = ((dst)) > 0;
740 if (slow)
741 {
742 if (is_cond_true (context, c) != ans)
743 abort ();
744 }
745 return ans;
746 case LE:
747 ans = ((dst)) <= 0;
748 if (slow)
749 {
750 if (is_cond_true (context, c) != ans)
751 abort ();
752 }
753 return ans;
754 case GE:
755 ans = ((dst)) >= 0;
756 if (slow)
757 {
758 if (is_cond_true (context, c) != ans)
759 abort ();
760 }
761 return ans;
762 case LT:
763 ans = ((dst)) < 0;
764 if (slow)
765 {
766 if (is_cond_true (context, c) != ans)
767 abort ();
768 }
769 return ans;
770 default:
771 break;
772 }
773
774 /* Can't fake it, we'll have to work out the flags the
775 hard way */
776
777 makeflags (context, mask);
778 }
779
780 /* don't know how to fake a test, inspect the flags
781 the hard way */
782
783 return is_cond_true (context, c);
784}
This page took 0.174267 seconds and 4 git commands to generate.