Fix doco on enable-sim-inline.
[external/binutils.git] / sim / erc32 / func.c
1 /*
2  * func.c, misc simulator functions. This file is part of SIS.
3  * 
4  * SIS, SPARC instruction simulator V1.8 Copyright (C) 1995 Jiri Gaisler,
5  * European Space Agency
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  * 
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  * 
17  * You should have received a copy of the GNU General Public License along with
18  * this program; if not, write to the Free Software Foundation, Inc., 675
19  * Mass Ave, Cambridge, MA 02139, USA.
20  * 
21  */
22
23 #include <signal.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include "sis.h"
27 #include "end.h"
28 #include <dis-asm.h>
29
30
31 #define VAL(x)  strtol(x,(char *)NULL,0)
32
33 extern char    *readline(char *prompt); /* GNU readline function */
34
35 struct disassemble_info dinfo;
36 struct pstate   sregs;
37 extern struct estate ebase;
38 int             ctrl_c = 0;
39 int             sis_verbose = 0;
40 char           *sis_version = "2.1";
41 int             nfp = 0;
42 char            uart_dev1[128] = "/dev/ptypc";
43 char            uart_dev2[128] = "/dev/ptypd";
44
45 #ifdef IUREV0
46 int             iurev0 = 0;
47 #endif
48 #ifdef MECREV0
49 int             mecrev0 = 0;
50 #endif
51
52 int 
53 batch(sregs, fname)
54     struct pstate  *sregs;
55     char           *fname;
56 {
57     FILE           *fp;
58     char            lbuf[1024];
59
60     if ((fp = fopen(fname, "r")) == NULL) {
61         fprintf(stderr, "couldn't open batch file %s\n", fname);
62         return (0);
63     }
64     while (!feof(fp)) {
65         lbuf[0] = 0;
66         fgets(lbuf, 1023, fp);
67         if ((strlen(lbuf) > 0) && (lbuf[strlen(lbuf) - 1] == '\n'))
68             lbuf[strlen(lbuf) - 1] = 0;
69         printf("sis> %s\n", lbuf);
70         exec_cmd(sregs, lbuf);
71     }
72     fclose(fp);
73     return (1);
74 }
75
76 set_regi(sregs, reg, rval)
77     struct pstate  *sregs;
78     int32           reg;
79     uint32          rval;
80 {
81     uint32          cwp;
82     int32           err = 0;
83
84     cwp = ((sregs->psr & 0x7) << 4);
85     if ((reg > 0) && (reg < 8)) {
86         sregs->g[reg] = rval;
87     } else if ((reg >= 8) && (reg < 32)) {
88         sregs->r[(cwp + reg) & 0x7f] = rval;
89     } else if ((reg >= 32) && (reg < 64)) {
90         sregs->fsi[reg - 32] = rval;
91     } else {
92         switch (reg) {
93         case 64:
94             sregs->y = rval;
95             break;
96         case 65:
97             sregs->psr = rval;
98             break;
99         case 66:
100             sregs->wim = rval;
101             break;
102         case 67:
103             sregs->tbr = rval;
104             break;
105         case 68:
106             sregs->pc = rval;
107             break;
108         case 69:
109             sregs->npc = rval;
110             break;
111         case 70:
112             sregs->fsr = rval;
113             set_fsr(rval);
114             break;
115     defualt:break;
116         }
117     }
118 }
119
120 void
121 get_regi(struct pstate * sregs, int32 reg, char *buf)
122 {
123     uint32          cwp;
124     uint32          rval = 0;
125
126     cwp = ((sregs->psr & 0x7) << 4);
127     if ((reg >= 0) && (reg < 8)) {
128         rval = sregs->g[reg];
129     } else if ((reg >= 8) && (reg < 32)) {
130         rval = sregs->r[(cwp + reg) & 0x7f];
131     } else if ((reg >= 32) && (reg < 64)) {
132         rval = sregs->fsi[reg - 32];
133     } else {
134         switch (reg) {
135         case 64:
136             rval = sregs->y;
137             break;
138         case 65:
139             rval = sregs->psr;
140             break;
141         case 66:
142             rval = sregs->wim;
143             break;
144         case 67:
145             rval = sregs->tbr;
146             break;
147         case 68:
148             rval = sregs->pc;
149             break;
150         case 69:
151             rval = sregs->npc;
152             break;
153         case 70:
154             rval = sregs->fsr;
155             break;
156     defualt:break;
157         }
158     }
159     buf[0] = (rval >> 24) & 0x0ff;
160     buf[1] = (rval >> 16) & 0x0ff;
161     buf[2] = (rval >> 8) & 0x0ff;
162     buf[3] = rval & 0x0ff;
163 }
164
165
166 set_rega(sregs, reg, rval)
167     struct pstate  *sregs;
168     char           *reg;
169     uint32          rval;
170 {
171     uint32          cwp;
172     int32           err = 0;
173
174     cwp = ((sregs->psr & 0x7) << 4);
175     if (strcmp(reg, "psr") == 0)
176         sregs->psr = (rval = (rval & 0x00f03fff));
177     else if (strcmp(reg, "tbr") == 0)
178         sregs->tbr = (rval = (rval & 0xfffffff0));
179     else if (strcmp(reg, "wim") == 0)
180         sregs->wim = (rval = (rval & 0x0ff));
181     else if (strcmp(reg, "y") == 0)
182         sregs->y = rval;
183     else if (strcmp(reg, "pc") == 0)
184         sregs->pc = rval;
185     else if (strcmp(reg, "npc") == 0)
186         sregs->npc = rval;
187     else if (strcmp(reg, "fsr") == 0) {
188         sregs->fsr = rval;
189         set_fsr(rval);
190     } else if (strcmp(reg, "g0") == 0)
191         err = 2;
192     else if (strcmp(reg, "g1") == 0)
193         sregs->g[1] = rval;
194     else if (strcmp(reg, "g2") == 0)
195         sregs->g[2] = rval;
196     else if (strcmp(reg, "g3") == 0)
197         sregs->g[3] = rval;
198     else if (strcmp(reg, "g4") == 0)
199         sregs->g[4] = rval;
200     else if (strcmp(reg, "g5") == 0)
201         sregs->g[5] = rval;
202     else if (strcmp(reg, "g6") == 0)
203         sregs->g[6] = rval;
204     else if (strcmp(reg, "g7") == 0)
205         sregs->g[7] = rval;
206     else if (strcmp(reg, "o0") == 0)
207         sregs->r[(cwp + 8) & 0x7f] = rval;
208     else if (strcmp(reg, "o1") == 0)
209         sregs->r[(cwp + 9) & 0x7f] = rval;
210     else if (strcmp(reg, "o2") == 0)
211         sregs->r[(cwp + 10) & 0x7f] = rval;
212     else if (strcmp(reg, "o3") == 0)
213         sregs->r[(cwp + 11) & 0x7f] = rval;
214     else if (strcmp(reg, "o4") == 0)
215         sregs->r[(cwp + 12) & 0x7f] = rval;
216     else if (strcmp(reg, "o5") == 0)
217         sregs->r[(cwp + 13) & 0x7f] = rval;
218     else if (strcmp(reg, "o6") == 0)
219         sregs->r[(cwp + 14) & 0x7f] = rval;
220     else if (strcmp(reg, "o7") == 0)
221         sregs->r[(cwp + 15) & 0x7f] = rval;
222     else if (strcmp(reg, "l0") == 0)
223         sregs->r[(cwp + 16) & 0x7f] = rval;
224     else if (strcmp(reg, "l1") == 0)
225         sregs->r[(cwp + 17) & 0x7f] = rval;
226     else if (strcmp(reg, "l2") == 0)
227         sregs->r[(cwp + 18) & 0x7f] = rval;
228     else if (strcmp(reg, "l3") == 0)
229         sregs->r[(cwp + 19) & 0x7f] = rval;
230     else if (strcmp(reg, "l4") == 0)
231         sregs->r[(cwp + 20) & 0x7f] = rval;
232     else if (strcmp(reg, "l5") == 0)
233         sregs->r[(cwp + 21) & 0x7f] = rval;
234     else if (strcmp(reg, "l6") == 0)
235         sregs->r[(cwp + 22) & 0x7f] = rval;
236     else if (strcmp(reg, "l7") == 0)
237         sregs->r[(cwp + 23) & 0x7f] = rval;
238     else if (strcmp(reg, "i0") == 0)
239         sregs->r[(cwp + 24) & 0x7f] = rval;
240     else if (strcmp(reg, "i1") == 0)
241         sregs->r[(cwp + 25) & 0x7f] = rval;
242     else if (strcmp(reg, "i2") == 0)
243         sregs->r[(cwp + 26) & 0x7f] = rval;
244     else if (strcmp(reg, "i3") == 0)
245         sregs->r[(cwp + 27) & 0x7f] = rval;
246     else if (strcmp(reg, "i4") == 0)
247         sregs->r[(cwp + 28) & 0x7f] = rval;
248     else if (strcmp(reg, "i5") == 0)
249         sregs->r[(cwp + 29) & 0x7f] = rval;
250     else if (strcmp(reg, "i6") == 0)
251         sregs->r[(cwp + 30) & 0x7f] = rval;
252     else if (strcmp(reg, "i7") == 0)
253         sregs->r[(cwp + 31) & 0x7f] = rval;
254     else
255         err = 1;
256     switch (err) {
257     case 0:
258         printf("%s = %d (0x%08x)\n", reg, rval, rval);
259         break;
260     case 1:
261         printf("no such regiser: %s\n", reg);
262         break;
263     case 2:
264         printf("cannot set g0\n");
265         break;
266     default:
267         break;
268     }
269
270 }
271
272 disp_reg(sregs, reg)
273     struct pstate  *sregs;
274     char           *reg;
275 {
276     if (strncmp(reg, "w",1) == 0)
277         disp_regs(sregs, VAL(&reg[1]));
278 }
279
280 exec_cmd(sregs, cmd)
281     char           *cmd;
282     struct pstate  *sregs;
283 {
284     char           *cmd1, *cmd2;
285     int32           ws, stat;
286     int32           len, i, clen, j;
287     static          daddr = 0;
288     char           *cmdsave;
289
290     stat = OK;
291     cmdsave = strdup(cmd);
292     if ((cmd1 = strtok(cmd, " \t")) != NULL) {
293         clen = strlen(cmd1);
294         if (strncmp(cmd1, "bp", clen) == 0) {
295             for (i = 0; i < sregs->bptnum; i++) {
296                 printf("  %d : 0x%08x\n", i + 1, sregs->bpts[i]);
297             }
298         } else if (strncmp(cmd1, "+bp", clen) == 0) {
299             if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
300                 sregs->bpts[sregs->bptnum] = VAL(cmd1) & ~0x3;
301                 printf("added breakpoint %d at 0x%08x\n",
302                        sregs->bptnum + 1, sregs->bpts[sregs->bptnum]);
303                 sregs->bptnum += 1;
304             }
305         } else if (strncmp(cmd1, "-bp", clen) == 0) {
306             if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
307                 i = VAL(cmd1) - 1;
308                 if ((i >= 0) && (i < sregs->bptnum)) {
309                     printf("deleted breakpoint %d at 0x%08x\n", i + 1,
310                            sregs->bpts[i]);
311                     for (; i < sregs->bptnum - 1; i++) {
312                         sregs->bpts[i] = sregs->bpts[i + 1];
313                     }
314                     sregs->bptnum -= 1;
315                 }
316             }
317         } else if (strncmp(cmd1, "batch", clen) == 0) {
318             if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
319                 printf("no file specified\n");
320             } else {
321                 batch(sregs, cmd1);
322             }
323         } else if (strncmp(cmd1, "cont", clen) == 0) {
324             if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
325                 stat = run_sim(sregs, 1, 0, 0);
326             } else {
327                 stat = run_sim(sregs, 0, VAL(cmd1), 0);
328             }
329             daddr = sregs->pc;
330             sim_stop();
331         } else if (strncmp(cmd1, "dis", clen) == 0) {
332             if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
333                 daddr = VAL(cmd1);
334             }
335             if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
336                 len = VAL(cmd2);
337             } else
338                 len = 16;
339             printf("\n");
340             dis_mem(daddr, len, &dinfo);
341             printf("\n");
342             daddr += len * 4;
343         } else if (strncmp(cmd1, "echo", clen) == 0) {
344             if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
345                 printf("%s\n", (&cmdsave[clen+1]));
346             }
347         } else if (strncmp(cmd1, "float", clen) == 0) {
348             stat = disp_fpu(sregs);
349         } else if (strncmp(cmd1, "go", clen) == 0) {
350             if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
351                 printf("wrong syntax: go <address> [inst_count]\n");
352             } else {
353                 len = VAL(cmd1);
354                 sregs->pc = len & ~3;
355                 sregs->npc = sregs->pc + 4;
356                 if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
357                     stat = run_sim(sregs, 0, VAL(cmd2), 0);
358                 } else {
359                     stat = run_sim(sregs, 1, 0, 0);
360                 }
361             }
362             daddr = sregs->pc;
363             sim_stop();
364         } else if (strncmp(cmd1, "help", clen) == 0) {
365             gen_help();
366         } else if (strncmp(cmd1, "history", clen) == 0) {
367             if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
368                 sregs->histlen = VAL(cmd1);
369                 if (sregs->histbuf != NULL)
370                     free(sregs->histbuf);
371                 sregs->histbuf = (struct histype *) calloc(sregs->histlen, sizeof(struct histype));
372                 printf("trace history length = %d\n\r", sregs->histlen);
373                 sregs->histind = 0;
374
375             } else {
376                 j = sregs->histind;
377                 for (i = 0; i < sregs->histlen; i++) {
378                     if (j >= sregs->histlen)
379                         j = 0;
380                     printf(" %8d ", sregs->histbuf[j].time);
381                     dis_mem(sregs->histbuf[j].addr, 1, &dinfo);
382                     j++;
383                 }
384             }
385
386         } else if (strncmp(cmd1, "load", clen) == 0) {
387             if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
388                 bfd_load(cmd1);
389             } else {
390                 printf("load: no file specified\n");
391             }
392         } else if (strncmp(cmd1, "mem", clen) == 0) {
393             if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL)
394                 daddr = VAL(cmd1);
395             if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL)
396                 len = VAL(cmd2);
397             else
398                 len = 64;
399             disp_mem(daddr, len);
400             daddr += len;
401         } else if (strncmp(cmd1, "perf", clen) == 0) {
402             cmd1 = strtok(NULL, " \t\n\r");
403             if ((cmd1 != NULL) &&
404                 (strncmp(cmd1, "reset", strlen(cmd1)) == 0)) {
405                 reset_stat(sregs);
406             } else
407                 show_stat(sregs);
408         } else if (strncmp(cmd1, "quit", clen) == 0) {
409             exit(0);
410         } else if (strncmp(cmd1, "reg", clen) == 0) {
411             cmd1 = strtok(NULL, " \t\n\r");
412             cmd2 = strtok(NULL, " \t\n\r");
413             if (cmd2 != NULL)
414                 set_rega(sregs, cmd1, VAL(cmd2));
415             else if (cmd1 != NULL)
416                 disp_reg(sregs, cmd1);
417             else {
418                 disp_regs(sregs,sregs->psr);
419                 disp_ctrl(sregs);
420             }
421         } else if (strncmp(cmd1, "reset", clen) == 0) {
422             ebase.simtime = 0;
423             reset_all();
424             reset_stat(sregs);
425         } else if (strncmp(cmd1, "run", clen) == 0) {
426             ebase.simtime = 0;
427             reset_all();
428             reset_stat(sregs);
429             if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
430                 stat = run_sim(sregs, 1, 0, 0);
431             } else {
432                 stat = run_sim(sregs, 0, VAL(cmd1), 0);
433             }
434             daddr = sregs->pc;
435             sim_stop();
436         } else if (strncmp(cmd1, "shell", clen) == 0) {
437             if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
438                 system(&cmdsave[clen]);
439             }
440         } else if (strncmp(cmd1, "step", clen) == 0) {
441             stat = run_sim(sregs, 0, 1, 1);
442             daddr = sregs->pc;
443             sim_stop();
444         } else if (strncmp(cmd1, "tra", clen) == 0) {
445             if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
446                 stat = run_sim(sregs, 1, 0, 1);
447             } else {
448                 stat = run_sim(sregs, 0, VAL(cmd1), 1);
449             }
450             printf("\n");
451             daddr = sregs->pc;
452             sim_stop();
453         } else
454             printf("syntax error\n");
455     }
456     if (cmdsave != NULL)
457         free(cmdsave);
458     return (stat);
459 }
460
461
462 reset_stat(sregs)
463     struct pstate  *sregs;
464 {
465     sregs->tottime = 0;
466     sregs->pwdtime = 0;
467     sregs->ninst = 0;
468     sregs->fholdt = 0;
469     sregs->holdt = 0;
470     sregs->icntt = 0;
471     sregs->finst = 0;
472     sregs->nstore = 0;
473     sregs->nload = 0;
474     sregs->nbranch = 0;
475     sregs->simstart = ebase.simtime;
476
477 }
478
479 show_stat(sregs)
480     struct pstate  *sregs;
481 {
482     int32           simperf = 0;
483     uint32          iinst;
484     uint32          stime;
485
486     stime = ebase.simtime - sregs->simstart;    /* Total simulated time */
487 #ifdef STAT
488
489     iinst = sregs->ninst - sregs->finst - sregs->nload - sregs->nstore -
490         sregs->nbranch;
491 #endif
492
493     printf("\n Cycles       : %9d\n\r", ebase.simtime - sregs->simstart);
494     printf(" Instructions : %9d\n", sregs->ninst);
495
496 #ifdef STAT
497     printf("   integer    : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst);
498     printf("   load       : %9.2f %%\n",
499            100.0 * (float) sregs->nload / (float) sregs->ninst);
500     printf("   store      : %9.2f %%\n",
501            100.0 * (float) sregs->nstore / (float) sregs->ninst);
502     printf("   branch     : %9.2f %%\n",
503            100.0 * (float) sregs->nbranch / (float) sregs->ninst);
504     printf("   float      : %9.2f %%\n",
505            100.0 * (float) sregs->finst / (float) sregs->ninst);
506     printf(" Integer CPI  : %9.2f\n",
507            ((float) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst))
508            /
509            (float) (sregs->ninst - sregs->finst));
510     printf(" Float CPI    : %9.2f\n",
511            ((float) sregs->fholdt / (float) sregs->finst) + 1.0);
512 #endif
513     printf(" Overall CPI  : %9.2f\n",
514            (float) (stime - sregs->pwdtime) / (float) sregs->ninst);
515     printf("\n ERC32 performance (%4.1f MHz): %5.2f MOPS (%5.2f MIPS, %5.2f MFLOPS)\n",
516            sregs->freq, sregs->freq * (float) sregs->ninst / (float) (stime - sregs->pwdtime),
517            sregs->freq * (float) (sregs->ninst - sregs->finst) /
518            (float) (stime - sregs->pwdtime),
519      sregs->freq * (float) sregs->finst / (float) (stime - sregs->pwdtime));
520     printf(" Simulated ERC32 time        : %5.2f ms\n", (float) (ebase.simtime - sregs->simstart) / 1000.0 / sregs->freq);
521     printf(" Processor utilisation       : %5.2f %%\n", 100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime)));
522     printf(" Real-time / simulator-time  : %5.2f \n",
523       ((float) sregs->tottime) / ((float) (stime) / (sregs->freq * 1.0E6)));
524     printf(" Used time (sys + user)      : %3d s\n\n", sregs->tottime);
525 }
526
527
528
529 init_bpt(sregs)
530     struct pstate  *sregs;
531 {
532     sregs->bptnum = 0;
533     sregs->histlen = 0;
534     sregs->histind = 0;
535     sregs->histbuf = NULL;
536
537 }
538
539 void
540 int_handler(sig)
541     int32           sig;
542 {
543     if (sig != 2)
544         printf("\n\n Signal handler error  (%d)\n\n", sig);
545     ctrl_c = 1;
546 }
547
548 init_signals()
549 {
550     typedef void    (*PFI) ();
551     static PFI      int_tab[2];
552
553     int_tab[0] = signal(SIGTERM, int_handler);
554     int_tab[1] = signal(SIGINT, int_handler);
555 }
556
557
558 extern struct disassemble_info dinfo;
559
560 struct estate   ebase;
561 struct evcell   evbuf[EVENT_MAX];
562 struct irqcell  irqarr[16];
563 int32           irqpend, ext_irl = 0;
564
565 disp_fpu(sregs)
566     struct pstate  *sregs;
567 {
568
569     int           i, j;
570     float       t;
571
572     printf("\n fsr: %08X\n\n", sregs->fsr);
573
574 #ifdef HOST_LITTLE_ENDIAN_FLOAT
575     for (i = 0; i < 32; i++) {
576         sregs->fdp[i ^ 1] = sregs->fs[i];
577     }
578 #endif
579
580     for (i = 0; i < 32; i++) {
581         t = sregs->fs[i];
582         printf(" f%02d  %08x  %14e  ", i, sregs->fsi[i], sregs->fs[i]);
583         if (!(i & 1))
584             printf("%14e\n", sregs->fd[i >> 1]);
585         else
586             printf("\n");
587     }
588     printf("\n");
589     return (OK);
590 }
591
592 disp_regs(sregs,cwp)
593     struct pstate  *sregs;
594     int cwp;
595 {
596
597     int           i;
598
599     cwp = ((cwp & 0x7) << 4);
600     printf("\n\t  INS       LOCALS      OUTS     GLOBALS\n");
601     for (i = 0; i < 8; i++) {
602         printf("   %d:  %08X   %08X   %08X   %08X\n", i,
603                sregs->r[(cwp + i + 24) & 0x7f],
604             sregs->r[(cwp + i + 16) & 0x7f], sregs->r[(cwp + i + 8) & 0x7f],
605                sregs->g[i]);
606     }
607 }
608
609 disp_ctrl(sregs)
610     struct pstate  *sregs;
611 {
612
613     uint32           i;
614
615     printf("\n psr: %08X   wim: %08X   tbr: %08X   y: %08X\n",
616            sregs->psr, sregs->wim, sregs->tbr, sregs->y);
617     sis_memory_read(sregs->pc, &i, 4);
618     printf("\n  pc: %08X = %08X    ", sregs->pc, i);
619     print_insn_sparc(sregs->pc, &dinfo);
620     sis_memory_read(sregs->npc, &i, 4);
621     printf("\n npc: %08X = %08X    ", sregs->npc, i);
622     print_insn_sparc(sregs->npc, &dinfo);
623     if (sregs->err_mode)
624         printf("\n IU in error mode");
625     printf("\n\n");
626 }
627
628 disp_mem(addr, len)
629     uint32          addr;
630     uint32          len;
631 {
632
633     int32           i, data, ws;
634     int32           mem[4], j;
635     char           *p;
636
637     for (i = addr & ~3; i < ((addr + len) & ~3); i += 16) {
638         printf("\n %8X  ", i);
639         for (j = 0; j < 4; j++) {
640             sis_memory_read((i + (j * 4)), &data, 4);
641             printf("%08x  ", data);
642             mem[j] = data;
643         }
644         printf("  ");
645         p = (char *) mem;
646         for (j = 0; j < 16; j++) {
647             if (isprint(p[j]))
648                 putchar(p[j]);
649             else
650                 putchar('.');
651         }
652     }
653     printf("\n\n");
654 }
655 dis_mem(addr, len, info)
656     uint32          addr;
657     uint32          len;
658     struct disassemble_info *info;
659 {
660     int32           i, data, ws;
661
662     for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) {
663         sis_memory_read(i, &data, 4);
664         printf(" %08x  %08x  ", i, data);
665         print_insn_sparc(i, info);
666         printf("\n");
667     }
668     return (OK);
669 }
670
671 int
672 buffer_read_memory(addr, buffer, size, info)
673     bfd_vma         addr;
674     bfd_byte       *buffer;
675     int32           size;
676     struct disassemble_info *info;
677 {
678     if (size == sis_memory_read(addr, buffer, size))
679         return (0);
680     else
681         return (1);
682 }
683
684 void
685 perror_memory(status, addr, info)
686     int32           status;
687     bfd_vma         addr;
688     struct disassemble_info *info;
689 {
690
691     printf("Could not read address 0x%08x\n", addr);
692 }
693
694 void
695 generic_print_address(addr, info)
696     bfd_vma         addr;
697     struct disassemble_info *info;
698 {
699
700     printf("0x%x", addr);
701 }
702
703 /* Add event to event queue */
704
705 event(cfunc, arg, delta)
706     void            (*cfunc) ();
707     int32           arg;
708     uint32          delta;
709 {
710     struct evcell  *ev1, *evins;
711
712     if (ebase.freeq == NULL) {
713         printf("Error, too many events in event queue\n");
714         return (0);
715     }
716     ev1 = &ebase.eq;
717     delta += ebase.simtime;
718     while ((ev1->nxt != NULL) && (ev1->nxt->time <= delta)) {
719         ev1 = ev1->nxt;
720     }
721     if (ev1->nxt == NULL) {
722         ev1->nxt = ebase.freeq;
723         ebase.freeq = ebase.freeq->nxt;
724         ev1->nxt->nxt = NULL;
725     } else {
726         evins = ebase.freeq;
727         ebase.freeq = ebase.freeq->nxt;
728         evins->nxt = ev1->nxt;
729         ev1->nxt = evins;
730     }
731     ev1->nxt->time = delta;
732     ev1->nxt->cfunc = cfunc;
733     ev1->nxt->arg = arg;
734 }
735
736 stop_event()
737 {
738 }
739
740 init_event()
741 {
742     int32           i;
743
744     ebase.eq.nxt = NULL;
745     ebase.freeq = evbuf;
746     for (i = 0; i < EVENT_MAX; i++) {
747         evbuf[i].nxt = &evbuf[i + 1];
748     }
749     evbuf[EVENT_MAX - 1].nxt = NULL;
750 }
751
752 set_int(level, callback, arg)
753     int32           level;
754     void            (*callback) ();
755     int32           arg;
756 {
757     irqarr[level & 0x0f].callback = callback;
758     irqarr[level & 0x0f].arg = arg;
759     irqpend |= (1 << level);
760     if (level > ext_irl)
761         ext_irl = level;
762
763 }
764
765 clear_int(level)
766     int32           level;
767 {
768     int32           tmpirq = irqpend;
769
770     irqpend &= ~(1 << level);
771     ext_irl = 0;
772     if (irqpend) {
773         tmpirq >>= 1;
774         while (tmpirq) {
775             ext_irl++;
776             tmpirq >>= 1;
777         }
778     }
779 }
780
781 /* Advance simulator time */
782
783 advance_time(sregs)
784     struct pstate  *sregs;
785 {
786
787     struct evcell  *evrem;
788     void            (*cfunc) ();
789     uint32          arg, endtime, ws;
790
791     ws = sregs->icnt + sregs->hold + sregs->fhold;
792
793 #ifdef STAT
794     sregs->fholdt += sregs->fhold;
795     sregs->holdt += sregs->hold;
796     sregs->icntt += sregs->icnt;
797 #endif
798
799     endtime = ebase.simtime += ws;
800     while ((ebase.eq.nxt != NULL) && (ebase.eq.nxt->time <= (endtime))) {
801         ebase.simtime = ebase.eq.nxt->time;
802         cfunc = ebase.eq.nxt->cfunc;
803         arg = ebase.eq.nxt->arg;
804         evrem = ebase.eq.nxt;
805         ebase.eq.nxt = ebase.eq.nxt->nxt;
806         evrem->nxt = ebase.freeq;
807         ebase.freeq = evrem;
808         cfunc(arg);
809     }
810     ebase.simtime = endtime;
811
812 }
813
814 /* Advance time until an external interrupt is seen */
815
816 int
817 wait_for_irq()
818 {
819     struct evcell  *evrem;
820     void            (*cfunc) ();
821     int32           arg, endtime;
822
823     if (ebase.eq.nxt == NULL)
824         printf("Warning: event queue empty - power-down mode not entered\n");
825     endtime = ebase.simtime;
826     while (!ext_irl && (ebase.eq.nxt != NULL)) {
827         ebase.simtime = ebase.eq.nxt->time;
828         cfunc = ebase.eq.nxt->cfunc;
829         arg = ebase.eq.nxt->arg;
830         evrem = ebase.eq.nxt;
831         ebase.eq.nxt = ebase.eq.nxt->nxt;
832         evrem->nxt = ebase.freeq;
833         ebase.freeq = evrem;
834         cfunc(arg);
835         if (ctrl_c) {
836             printf("\bwarning: power-down mode interrupted\n");
837             break;
838         }
839     }
840     sregs.pwdtime += ebase.simtime - endtime;
841     return (ebase.simtime - endtime);
842 }
843
844 int
845 check_bpt(sregs)
846     struct pstate  *sregs;
847 {
848     int32           i;
849
850     if ((sregs->bphit) || (sregs->annul))
851         return (0);
852     for (i = 0; i < sregs->bptnum; i++) {
853         if (sregs->pc == sregs->bpts[i])
854             return (BPT_HIT);
855     }
856     return (0);
857 }
858
859 reset_all()
860 {
861     init_event();               /* Clear event queue */
862     init_regs(&sregs);
863     reset();
864 }
865
866 sys_reset()
867 {
868     reset_all();
869     sregs.trap = 256;           /* Force fake reset trap */
870 }
871
872 #include "ansidecl.h"
873
874 #ifdef ANSI_PROTOTYPES
875 #include <stdarg.h>
876 #else
877 #include <varargs.h>
878 #endif
879
880 #include "libiberty.h"
881 #include "bfd.h"
882
883 #define min(A, B) (((A) < (B)) ? (A) : (B))
884 #define LOAD_ADDRESS 0
885
886 int
887 bfd_load(fname)
888     char           *fname;
889 {
890     int             cc, c;
891     unsigned char   buf[10];
892     asection       *section;
893     bfd            *pbfd;
894     unsigned long   entry;
895
896     pbfd = bfd_openr(fname, 0);
897
898     if (pbfd == NULL) {
899         printf("open of %s failed\n", fname);
900         return (0);
901     }
902     if (!bfd_check_format(pbfd, bfd_object)) {
903         printf("file %s  doesn't seem to be an object file\n", fname);
904         return (0);
905     }
906     printf("loading %s:", fname);
907     for (section = pbfd->sections; section; section = section->next) {
908         if (bfd_get_section_flags(pbfd, section) & SEC_ALLOC) {
909             bfd_vma         section_address;
910             unsigned long   section_size;
911             const char     *section_name;
912
913             section_name = bfd_get_section_name(pbfd, section);
914
915             section_address = bfd_get_section_vma(pbfd, section);
916             /*
917              * Adjust sections from a.out files, since they don't carry their
918              * addresses with.
919              */
920             if (bfd_get_flavour(pbfd) == bfd_target_aout_flavour)
921                 section_address += bfd_get_start_address (pbfd);
922             section_size = bfd_section_size(pbfd, section);
923
924             printf("\nsection %s at 0x%08lx (%ld bytes)",
925                    section_name, section_address, section_size);
926
927             /* Text, data or lit */
928             if (bfd_get_section_flags(pbfd, section) & SEC_LOAD) {
929                 file_ptr        fptr;
930
931                 fptr = 0;
932
933                 while (section_size > 0) {
934                     char            buffer[1024];
935                     int             count;
936
937                     count = min(section_size, 1024);
938
939                     bfd_get_section_contents(pbfd, section, buffer, fptr, count);
940
941                     sis_memory_write(section_address, buffer, count);
942
943                     section_address += count;
944                     fptr += count;
945                     section_size -= count;
946                 }
947             } else              /* BSS */
948                 printf("(not loaded)");
949         }
950     }
951     printf("\n");
952
953     /*
954      * entry = bfd_get_start_address (pbfd);
955      * 
956      * printf ("[Starting %s at 0x%lx]\n", fname, entry);
957      */
958
959     return (1);
960 }
961
962 void
963 sim_set_callbacks (ptr)
964 struct host_callback_struct *ptr;
965 {
966
967 }
968