sim/erc32: Fix incorrect simulator performance report
[external/binutils.git] / sim / erc32 / sis.c
1 /*
2  * This file is part of SIS.
3  * 
4  * SIS, SPARC instruction simulator. Copyright (C) 1995 Jiri Gaisler, European
5  * 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 3 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, see <http://www.gnu.org/licenses/>.
19  * 
20  */
21
22 #include "config.h"
23 #include <signal.h>
24 #include <string.h>
25 #ifdef HAVE_STDLIB_H
26 #include <stdlib.h>
27 #endif
28 #include <stdio.h>
29 #include <sys/fcntl.h>
30 #include "sis.h"
31 #include <dis-asm.h>
32 #include "sim-config.h"
33
34 #define VAL(x)  strtol(x,(char **)NULL,0)
35
36 /* Structures and functions from readline library */
37
38 typedef struct {
39   char *line;
40   char *data;
41 } HIST_ENTRY;
42
43 extern char *   readline (char *prompt);
44 extern void     using_history (void);
45 extern void     add_history (char *string);
46 extern HIST_ENTRY *remove_history (int which);
47
48
49
50 /* Command history buffer length - MUST be binary */
51 #define HIST_LEN        64
52
53 extern struct disassemble_info dinfo;
54 extern struct pstate sregs;
55 extern struct estate ebase;
56
57 extern int      ctrl_c;
58 extern int      nfp;
59 extern int      ift;
60 extern int      wrp;
61 extern int      rom8;
62 extern int      uben;
63 extern int      sis_verbose;
64 extern char    *sis_version;
65 extern struct estate ebase;
66 extern struct evcell evbuf[];
67 extern struct irqcell irqarr[];
68 extern int      irqpend, ext_irl;
69 extern int      termsave;
70 extern int      sparclite;
71 extern int      dumbio;
72 extern char     uart_dev1[];
73 extern char     uart_dev2[];
74 extern uint32   last_load_addr;
75
76 #ifdef ERA
77 extern int era;
78 #endif
79
80 int
81 run_sim(sregs, icount, dis)
82     struct pstate  *sregs;
83     uint64          icount;
84     int             dis;
85 {
86     int             irq, mexc, deb, asi;
87
88     sregs->starttime = get_time();
89     init_stdio();
90     if (sregs->err_mode) icount = 0;
91     deb = dis || sregs->histlen || sregs->bptnum;
92     irq = 0;
93     while (icount > 0) {
94
95         if (sregs->psr & 0x080)
96             asi = 9;
97         else
98             asi = 8;
99         mexc = memory_read(asi, sregs->pc, &sregs->inst, 2, &sregs->hold);
100         sregs->icnt = 1;
101         if (sregs->annul) {
102             sregs->annul = 0;
103             sregs->pc = sregs->npc;
104             sregs->npc = sregs->npc + 4;
105         } else {
106             sregs->fhold = 0;
107             if (ext_irl) irq = check_interrupts(sregs);
108             if (!irq) {
109                 if (mexc) {
110                     sregs->trap = I_ACC_EXC;
111                 } else {
112                     if (deb) {
113                         if ((sregs->bphit = check_bpt(sregs)) != 0) {
114                             restore_stdio();
115                             return (BPT_HIT);
116                         }
117                         if (sregs->histlen) {
118                             sregs->histbuf[sregs->histind].addr = sregs->pc;
119                             sregs->histbuf[sregs->histind].time = ebase.simtime;
120                             sregs->histind++;
121                             if (sregs->histind >= sregs->histlen)
122                                 sregs->histind = 0;
123                         }
124                         if (dis) {
125                             printf(" %8u ", ebase.simtime);
126                             dis_mem(sregs->pc, 1, &dinfo);
127                         }
128                     }
129                     dispatch_instruction(sregs);
130                     icount--;
131                 }
132             }
133             if (sregs->trap) {
134                 irq = 0;
135                 sregs->err_mode = execute_trap(sregs);
136                 if (sregs->err_mode) {
137                     error_mode(sregs->pc);
138                     icount = 0;
139                 }
140             }
141         }
142         advance_time(sregs);
143         if (ctrl_c || (sregs->tlimit <= ebase.simtime)) {
144             icount = 0;
145             if (sregs->tlimit <= ebase.simtime) sregs->tlimit = -1;
146         }
147     }
148     sregs->tottime += get_time() - sregs->starttime;
149     restore_stdio();
150     if (sregs->err_mode)
151         return (ERROR);
152     if (ctrl_c) {
153         ctrl_c = 0;
154         return (CTRL_C);
155     }
156     return (TIME_OUT);
157 }
158
159 int
160 main(argc, argv)
161     int             argc;
162     char          **argv;
163 {
164
165     int             cont = 1;
166     int             stat = 1;
167     int             freq = 14;
168     int             copt = 0;
169
170     char           *cfile, *bacmd;
171     char           *cmdq[HIST_LEN];
172     int             cmdi = 0;
173     int             i;
174
175     cfile = 0;
176     for (i = 0; i < 64; i++)
177         cmdq[i] = 0;
178     printf("\n SIS - SPARC instruction simulator %s,  copyright Jiri Gaisler 1995\n", sis_version);
179     printf(" Bug-reports to jgais@wd.estec.esa.nl\n\n");
180     while (stat < argc) {
181         if (argv[stat][0] == '-') {
182             if (strcmp(argv[stat], "-v") == 0) {
183                 sis_verbose = 1;
184             } else if (strcmp(argv[stat], "-c") == 0) {
185                 if ((stat + 1) < argc) {
186                     copt = 1;
187                     cfile = argv[++stat];
188                 }
189             } else if (strcmp(argv[stat], "-nfp") == 0)
190                 nfp = 1;
191             else if (strcmp(argv[stat], "-ift") == 0)
192                 ift = 1;
193             else if (strcmp(argv[stat], "-wrp") == 0)
194                 wrp = 1;
195             else if (strcmp(argv[stat], "-rom8") == 0)
196                 rom8 = 1;
197             else if (strcmp(argv[stat], "-uben") == 0)
198                 uben = 1;
199             else if (strcmp(argv[stat], "-uart1") == 0) {
200                 if ((stat + 1) < argc)
201                     strcpy(uart_dev1, argv[++stat]);
202             } else if (strcmp(argv[stat], "-uart2") == 0) {
203                 if ((stat + 1) < argc)
204                     strcpy(uart_dev2, argv[++stat]);
205             } else if (strcmp(argv[stat], "-freq") == 0) {
206                 if ((stat + 1) < argc)
207                     freq = VAL(argv[++stat]);
208             } else if (strcmp(argv[stat], "-sparclite") == 0) {
209                 sparclite = 1;
210 #ifdef ERA
211             } else if (strcmp(argv[stat], "-era") == 0) {
212                 era = 1;
213 #endif
214             } else if (strcmp(argv[stat], "-dumbio") == 0) {
215                 dumbio = 1;
216             } else {
217                 printf("unknown option %s\n", argv[stat]);
218                 usage();
219                 exit(1);
220             }
221         } else {
222             last_load_addr = bfd_load(argv[stat]);
223         }
224         stat++;
225     }
226     if (nfp)
227         printf("FPU disabled\n");
228 #ifdef ERA
229     if (era)
230         printf("ERA ECC emulation enabled\n");
231 #endif
232     sregs.freq = freq;
233
234     INIT_DISASSEMBLE_INFO(dinfo, stdout, (fprintf_ftype) fprintf);
235     dinfo.endian = BFD_ENDIAN_BIG;
236
237     termsave = fcntl(0, F_GETFL, 0);
238     using_history();
239     init_signals();
240     ebase.simtime = 0;
241     reset_all();
242     init_bpt(&sregs);
243     init_sim();
244 #ifdef STAT
245     reset_stat(&sregs);
246 #endif
247
248     if (copt) {
249         bacmd = (char *) malloc(256);
250         strcpy(bacmd, "batch ");
251         strcat(bacmd, cfile);
252         exec_cmd(&sregs, bacmd);
253     }
254     while (cont) {
255
256         if (cmdq[cmdi] != 0) {
257 #if 0
258             remove_history(cmdq[cmdi]);
259 #else
260             remove_history(cmdi);
261 #endif
262             free(cmdq[cmdi]);
263             cmdq[cmdi] = 0;
264         }
265         cmdq[cmdi] = readline("sis> ");
266         if (cmdq[cmdi] && *cmdq[cmdi])
267             add_history(cmdq[cmdi]);
268         if (cmdq[cmdi])
269             stat = exec_cmd(&sregs, cmdq[cmdi]);
270         else {
271             puts("\n");
272             exit(0);
273         }
274         switch (stat) {
275         case OK:
276             break;
277         case CTRL_C:
278             printf("\b\bInterrupt!\n");
279         case TIME_OUT:
280             printf(" Stopped at time %d (%.3f ms)\n", ebase.simtime, 
281               ((double) ebase.simtime / (double) sregs.freq) / 1000.0);
282             break;
283         case BPT_HIT:
284             printf("breakpoint at 0x%08x reached\n", sregs.pc);
285             sregs.bphit = 1;
286             break;
287         case ERROR:
288             printf("IU in error mode (%d)\n", sregs.trap);
289             stat = 0;
290             printf(" %8d ", ebase.simtime);
291             dis_mem(sregs.pc, 1, &dinfo);
292             break;
293         default:
294             break;
295         }
296         ctrl_c = 0;
297         stat = OK;
298
299         cmdi = (cmdi + 1) & (HIST_LEN - 1);
300
301     }
302     return 0;
303 }
304