1 /* support routines for interpreted instructions
2    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
3 
4 This file is part of Z8KSIM
5 
6 Z8KSIM is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 Z8KSIM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with Z8KZIM; if not, write to the Free Software
18 Foundation, 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>
39 #include "gdb/callback.h"
40 #include "gdb/remote-sim.h"
41 #include "syscall.h"
42 
43 static int get_now PARAMS ((void));
44 static int now_persec PARAMS ((void));
45 static int put_long PARAMS ((sim_state_type * context, int ptr, int value));
46 static int put_short PARAMS ((sim_state_type * context, int ptr, int value));
47 
48 int sim_z8001_mode;
49 
50 static int
get_now()51 get_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 
63 static int
now_persec()64 now_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 */
80 static sim_state_type the_state;
81 
82 int
fail(context,dummy)83 fail (context, dummy)
84      sim_state_type *context;
85      int dummy;
86 {
87   context->exception = SIM_BAD_INST;
88   return 1;
89 }
90 
91 void
sfop_bad1(context)92 sfop_bad1 (context)
93      sim_state_type *context;
94 {
95   context->exception
96     = SIM_BAD_INST;
97 }
98 
99 void
bfop_bad1(context)100 bfop_bad1 (context)
101      sim_state_type *context;
102 {
103   context->exception
104     = SIM_BAD_INST;
105 }
106 
107 void
fop_bad(context)108 fop_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 
117 char 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 
133 int read ();
134 int write ();
135 int open ();
136 int close ();
137 int open ();
138 int close ();
139 
140 int link ();
141 int fstat ();
142 
143 static int
put_short(context,ptr,value)144 put_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 
153 static int
put_long(context,ptr,value)154 put_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 
166 static int args[3];
167 static int arg_index;		/* Translate a z8k system call into a host system call */
168 void
support_call(context,sc)169 support_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 
272 int
get_word_mem_da(context,addr)273 get_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
282 int
get_word_reg(context,reg)283 get_word_reg (context, reg) sim_state_type
284 * context;
285      int reg;
286 {
287   return context->regs[reg].word;
288 }
289 
290 #ifdef LOG
291 int log[64 * 1024];
292 
293 #endif
294 
295 void
tm_store_register(regno,value)296 tm_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 
312 void
swap_long(buf,val)313 swap_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 
323 void
swap_word(buf,val)324 swap_word (buf, val)
325      char *buf;
326      int val;
327 {
328   buf[0] = val >> 8;
329   buf[1] = val >> 0;
330 }
331 
332 void
tm_fetch_register(regno,buf)333 tm_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 
388 void
tm_resume(step)389 tm_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 
443 int
tm_signal()444 tm_signal ()
445 {
446   return the_state.exception;
447 }
448 
449 void
tm_info_print(x)450 tm_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 
488 int
sim_trace(sd)489 sim_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 
533 void
tm_state(x)534 tm_state (x)
535      sim_state_type *x;
536 {
537   *x = the_state;
538 }
539 
540 void
tm_exception(x)541 tm_exception (x)
542      int x;
543 {
544   the_state.exception = x;
545 }
546 
547 int
tm_read_byte(x)548 tm_read_byte (x)
549      int x;
550 {
551   x &= 0x3f00ffff;
552   return sim_read_byte (&the_state, x);
553 }
554 
555 void
tm_write_byte(x,y)556 tm_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)
normal_flags_32(context,d,sa,sb,sub)564 normal_flags_32(context,d,sa,sb,sub)
565 sim_state_type *context;
566 unsigned int d;
567 unsigned int sa;
568 unsigned int sb;
569 unsigned 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 
normal_flags_16(context,d,sal,sbl,sub)587 normal_flags_16(context,d,sal,sbl,sub)
588 sim_state_type *context;
589 unsigned  int d;
590 unsigned  int sal;
591 unsigned  int sbl;
592 unsigned 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 
normal_flags_8(context,d,sa,sb,sub)613 normal_flags_8(context,d,sa,sb,sub)
614 sim_state_type *context;
615 unsigned char d;
616 unsigned char sa;
617 unsigned char sb;
618 unsigned 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 
636 static int
is_cond_true(context,c)637 is_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 
680 int
COND(context,c)681 COND (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 }
785