o Implement generic halt/restart/abort module.
[deliverable/binutils-gdb.git] / sim / tic80 / misc.c
CommitLineData
381f42ef
AC
1/* TIc80 Simulator.
2 Copyright (C) 1997 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4
5This file is part of GDB, the GNU debugger.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License along
18with this program; if not, write to the Free Software Foundation, Inc.,
1959 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21
22#include "sim-main.h"
23
24#ifdef HAVE_STRING_H
25#include <string.h>
26#else
27#ifdef HAVE_STRINGS_H
28#include <strings.h>
29#endif
30#endif
31
32
33tic80_control_regs
34tic80_index2cr (int index)
35{
36 switch (index)
37 {
38 case 0x0000: return EPC_CR;
39 case 0x0001: return EIP_CR;
40 case 0x0002: return CONFIG_CR;
41 case 0x0004: return INTPEN_CR;
42 case 0x0006: return IE_CR;
43 case 0x0008: return FPST_CR;
44 case 0x000A: return PPERROR_CR;
45 case 0x000D: return PKTREQ_CR;
46 case 0x000E: return TCOUNT_CR;
47 case 0x000F: return TSCALE_CR;
48 case 0x0010: return FLTOP_CR;
49 case 0x0011: return FLTADR_CR;
50 case 0x0012: return FLTTAG_CR;
51 case 0x0013: return FLTDLT_CR;
52 case 0x0014: return FLTDTH_CR;
53 case 0x0015: return FLT005_CR;
54 case 0x0016: return FLT006_CR;
55 case 0x0017: return FLT007_CR;
56 case 0x0018: return FLT008_CR;
57 case 0x0019: return FLT009_CR;
58 case 0x001a: return FLT010_CR;
59 case 0x001b: return FLT011_CR;
60 case 0x001c: return FLT012_CR;
61 case 0x001d: return FLT013_CR;
62 case 0x001e: return FLT014_CR;
63 case 0x001f: return FLT015_CR;
64 case 0x0020: return SYSSTK_CR;
65 case 0x0021: return SYSTMP_CR;
66 case 0x0030: return MPC_CR;
67 case 0x0031: return MIP_CR;
68 case 0x0033: return ECOMCNTL_CR;
69 case 0x0034: return ANASTAT_CR;
70 case 0x0039: return BRK1_CR;
71 case 0x003A: return BRK2_CR;
72 case 0x0200: return ITAG0_CR;
73 case 0x0201: return ITAG1_CR;
74 case 0x0202: return ITAG2_CR;
75 case 0x0203: return ITAG3_CR;
76 case 0x0204: return ITAG4_CR;
77 case 0x0205: return ITAG5_CR;
78 case 0x0206: return ITAG6_CR;
79 case 0x0207: return ITAG7_CR;
80 case 0x0208: return ITAG8_CR;
81 case 0x0209: return ITAG9_CR;
82 case 0x020a: return ITAG10_CR;
83 case 0x020b: return ITAG11_CR;
84 case 0x020c: return ITAG12_CR;
85 case 0x020d: return ITAG13_CR;
86 case 0x020e: return ITAG14_CR;
87 case 0x020f: return ITAG15_CR;
88 case 0x0300: return ILRU_CR;
89 case 0x0400: return DTAG0_CR;
90 case 0x0401: return DTAG1_CR;
91 case 0x0402: return DTAG2_CR;
92 case 0x0403: return DTAG3_CR;
93 case 0x0404: return DTAG4_CR;
94 case 0x0405: return DTAG5_CR;
95 case 0x0406: return DTAG6_CR;
96 case 0x0407: return DTAG7_CR;
97 case 0x0408: return DTAG8_CR;
98 case 0x0409: return DTAG9_CR;
99 case 0x040a: return DTAG10_CR;
100 case 0x040b: return DTAG11_CR;
101 case 0x040c: return DTAG12_CR;
102 case 0x040d: return DTAG13_CR;
103 case 0x040e: return DTAG14_CR;
104 case 0x040f: return DTAG15_CR;
105 case 0x0500: return DLRU_CR;
106 case 0x4000: return IN0P_CR;
107 case 0x4001: return IN1P_CR;
108 case 0x4002: return OUTP_CR;
109 default: return SCRATCH_CR;
110 }
111}
112
113
114\f
115#if defined(WITH_TRACE)
116/* Tracing support routines */
117
118static char tic80_trace_buffer[1024];
119static int tic80_size_name;
120
121#define SIZE_HEX 8
8c3b5af1 122#define SIZE_DECIMAL 11
381f42ef
AC
123
124/* Initialize tracing by calculating the maximum name size */
125static void
126tic80_init_trace (void)
127{
128 int i;
129 int len, max_len = 0;
130
131 for (i = 0; i < (int)nr_itable_entries; i++) {
132 len = strlen (itable[i].name);
133 if (len > max_len)
134 max_len = len;
135 }
136
137 tic80_size_name = max_len + sizeof(":m") - 1 + sizeof (":s") - 1;
138}
139
140/* Trace the result of an ALU operation with 2 integer inputs and an integer output */
141char *
142tic80_trace_alu3 (int indx,
143 unsigned32 result,
144 unsigned32 input1,
145 unsigned32 input2)
146{
381f42ef
AC
147 if (!tic80_size_name)
148 tic80_init_trace ();
149
8c3b5af1 150 sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld 0x%.*lx/%*ld => 0x%.*lx/%*ld",
381f42ef 151 tic80_size_name, itable[indx].name,
8c3b5af1
MM
152 SIZE_HEX, input1, SIZE_DECIMAL, (long)(signed32)input1,
153 SIZE_HEX, input2, SIZE_DECIMAL, (long)(signed32)input2,
154 SIZE_HEX, result, SIZE_DECIMAL, (long)(signed32)result);
381f42ef
AC
155
156 return tic80_trace_buffer;
157}
158
159/* Trace the result of an ALU operation with 1 integer input and an integer output */
160char *
161tic80_trace_alu2 (int indx,
162 unsigned32 result,
163 unsigned32 input)
164{
381f42ef
AC
165 if (!tic80_size_name)
166 tic80_init_trace ();
167
8c3b5af1 168 sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld %*s => 0x%.*lx/%*ld",
381f42ef 169 tic80_size_name, itable[indx].name,
8c3b5af1 170 SIZE_HEX, input, SIZE_DECIMAL, (long)(signed32)input,
450be234 171 SIZE_HEX + SIZE_DECIMAL + 3, "",
8c3b5af1 172 SIZE_HEX, result, SIZE_DECIMAL, (long)(signed32)result);
381f42ef
AC
173
174 return tic80_trace_buffer;
175}
176
450be234
MM
177/* Trace the result of a shift instruction */
178char *
179tic80_trace_shift (int indx,
180 unsigned32 result,
181 unsigned32 input,
182 int i,
183 int n,
184 int merge,
185 int endmask,
186 int rotate)
187{
188 const char *merge_name;
189 char name[40];
190 char *p;
191
192 if (!tic80_size_name)
193 tic80_init_trace ();
194
195 switch (merge)
196 {
197 default: merge_name = ".??"; break;
198 case 0: merge_name = ".dz"; break;
199 case 1: merge_name = ".dm"; break;
200 case 2: merge_name = ".ds"; break;
201 case 3: merge_name = ".ez"; break;
202 case 4: merge_name = ".em"; break;
203 case 5: merge_name = ".es"; break;
204 case 6: merge_name = ".iz"; break;
205 case 7: merge_name = ".im"; break;
206 }
207
208 /* Don't use itable[indx].name, which is just sl {r,i}. Instead reconstruct
209 the name, using the i and n fields. */
210 p = strchr (itable[indx].name, ' ');
211 sprintf (name, "s%s%s%s%s",
212 (n) ? "r" : "l",
213 (i) ? "i" : "",
214 merge_name,
215 (p) ? p : "");
216
217 sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld %*s%2d,%2d => 0x%.*lx/%*ld",
218 tic80_size_name, name,
219 SIZE_HEX, input, SIZE_DECIMAL, (long)(signed32)input,
220 SIZE_HEX + SIZE_DECIMAL - 2, "",
221 rotate, endmask,
222 SIZE_HEX, result, SIZE_DECIMAL, (long)(signed32)result);
223
224 return tic80_trace_buffer;
225}
226
8c3b5af1 227/* Trace the result of an FPU operation with 2 floating point inputs and a floating point output */
381f42ef
AC
228void
229tic80_trace_fpu3 (SIM_DESC sd,
230 sim_cpu *cpu,
231 sim_cia cia,
232 int indx,
233 sim_fpu result,
234 sim_fpu input1,
235 sim_fpu input2)
236{
237 if (!tic80_size_name)
238 tic80_init_trace ();
239
240 trace_one_insn (sd, cpu, cia.ip, 1,
241 itable[indx].file, itable[indx].line_nr, "fpu",
93555c3b 242 "%-*s %*g %*g => %*g",
381f42ef 243 tic80_size_name, itable[indx].name,
93555c3b
MM
244 SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input1),
245 SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input2),
246 SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (result));
381f42ef
AC
247}
248
8c3b5af1 249/* Trace the result of an FPU operation with 1 floating point input and a floating point output */
381f42ef
AC
250void
251tic80_trace_fpu2 (SIM_DESC sd,
252 sim_cpu *cpu,
253 sim_cia cia,
254 int indx,
255 sim_fpu result,
256 sim_fpu input)
257{
258 if (!tic80_size_name)
259 tic80_init_trace ();
260
261 trace_one_insn (sd, cpu, cia.ip, 1,
262 itable[indx].file, itable[indx].line_nr, "fpu",
93555c3b 263 "%-*s %*g %-*s => %*g",
381f42ef 264 tic80_size_name, itable[indx].name,
93555c3b
MM
265 SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input),
266 SIZE_HEX + SIZE_DECIMAL + 3, "",
381f42ef
AC
267 SIZE_HEX + SIZE_DECIMAL, sim_fpu_2d (result));
268}
269
aa3a0447
AC
270/* Trace the result of an FPU operation with 1 floating point input and a floating point output */
271void
272tic80_trace_fpu1 (SIM_DESC sd,
273 sim_cpu *cpu,
274 sim_cia cia,
275 int indx,
276 sim_fpu result)
277{
278 if (!tic80_size_name)
279 tic80_init_trace ();
280
281 trace_one_insn (sd, cpu, cia.ip, 1,
282 itable[indx].file, itable[indx].line_nr, "fpu",
283 "%-*s %-*s %-*s => %*g",
284 tic80_size_name, itable[indx].name,
285 SIZE_HEX + SIZE_DECIMAL + 3, "",
286 SIZE_HEX + SIZE_DECIMAL + 3, "",
287 SIZE_HEX + SIZE_DECIMAL, sim_fpu_2d (result));
288}
289
381f42ef
AC
290/* Trace the result of an FPU operation with 1 integer input and an integer output */
291void
292tic80_trace_fpu2i (SIM_DESC sd,
293 sim_cpu *cpu,
294 sim_cia cia,
295 int indx,
296 unsigned32 result,
297 sim_fpu input1,
298 sim_fpu input2)
299{
381f42ef
AC
300 if (!tic80_size_name)
301 tic80_init_trace ();
302
381f42ef
AC
303 trace_one_insn (sd, cpu, cia.ip, 1,
304 itable[indx].file, itable[indx].line_nr, "fpu",
c445af5a 305 "%-*s %*f %*f => 0x%.*lx %-*ld",
381f42ef
AC
306 tic80_size_name, itable[indx].name,
307 SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input1),
308 SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input2),
8c3b5af1 309 SIZE_HEX, result, SIZE_DECIMAL, (long)(signed32)result);
381f42ef
AC
310}
311
312/* Trace the result of a NOP operation */
313char *
314tic80_trace_nop (int indx)
315{
316 if (!tic80_size_name)
317 tic80_init_trace ();
318
319 sprintf (tic80_trace_buffer, "%s", itable[indx].name);
320 return tic80_trace_buffer;
321}
322
323/* Trace the result of a data sink with one input */
324char *
325tic80_trace_sink1 (int indx, unsigned32 input)
326{
381f42ef
AC
327 if (!tic80_size_name)
328 tic80_init_trace ();
329
8c3b5af1 330 sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld",
381f42ef 331 tic80_size_name, itable[indx].name,
8c3b5af1 332 SIZE_HEX, input, SIZE_DECIMAL, (long)(signed32)input);
381f42ef
AC
333
334 return tic80_trace_buffer;
335}
336
337/* Trace the result of a data sink with two inputs */
338char *
339tic80_trace_sink2 (int indx, unsigned32 input1, unsigned32 input2)
340{
381f42ef
AC
341 if (!tic80_size_name)
342 tic80_init_trace ();
343
8c3b5af1 344 sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld 0x%.*lx/%*ld",
381f42ef 345 tic80_size_name, itable[indx].name,
8c3b5af1
MM
346 SIZE_HEX, input1, SIZE_DECIMAL, (long)(signed32)input1,
347 SIZE_HEX, input2, SIZE_DECIMAL, (long)(signed32)input2);
381f42ef
AC
348
349 return tic80_trace_buffer;
350}
351
8c3b5af1 352/* Trace the result of a data sink with three inputs */
381f42ef
AC
353char *
354tic80_trace_sink3 (int indx, unsigned32 input1, unsigned32 input2, unsigned32 input3)
355{
381f42ef
AC
356 if (!tic80_size_name)
357 tic80_init_trace ();
358
8c3b5af1 359 sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld 0x%.*lx/%*ld 0x%.*lx/%*ld",
381f42ef 360 tic80_size_name, itable[indx].name,
8c3b5af1
MM
361 SIZE_HEX, input1, SIZE_DECIMAL, (long)(signed32)input1,
362 SIZE_HEX, input2, SIZE_DECIMAL, (long)(signed32)input2,
363 SIZE_HEX, input3, SIZE_DECIMAL, (long)(signed32)input3);
381f42ef
AC
364
365 return tic80_trace_buffer;
366}
367
368/* Trace the result of a conditional branch operation */
369char *
370tic80_trace_cond_br (int indx,
371 int jump_p,
372 unsigned32 cond,
373 unsigned32 target)
374{
381f42ef
AC
375 if (!tic80_size_name)
376 tic80_init_trace ();
377
381f42ef
AC
378 if (jump_p)
379 sprintf (tic80_trace_buffer,
8c3b5af1 380 "%-*s 0x%.*lx %*s 0x%.*lx/%*ld => 0x%.*lx",
381f42ef
AC
381 tic80_size_name, itable[indx].name,
382 SIZE_HEX, target, SIZE_DECIMAL, "",
8c3b5af1 383 SIZE_HEX, cond, SIZE_DECIMAL, (long)(signed32)cond,
381f42ef
AC
384 SIZE_HEX, target);
385 else
386 sprintf (tic80_trace_buffer,
8c3b5af1 387 "%-*s 0x%.*lx %*s 0x%.*lx/%*ld => [fallthrough]",
381f42ef
AC
388 tic80_size_name, itable[indx].name,
389 SIZE_HEX, target, SIZE_DECIMAL, "",
8c3b5af1 390 SIZE_HEX, cond, SIZE_DECIMAL, (long)(signed32)cond);
381f42ef
AC
391
392 return tic80_trace_buffer;
393}
394
395/* Trace the result of a unconditional branch operation */
396char *
397tic80_trace_ucond_br (int indx,
398 unsigned32 target)
399{
400 if (!tic80_size_name)
401 tic80_init_trace ();
402
403 sprintf (tic80_trace_buffer,
404 "%-*s 0x%.*lx %*s => 0x%.*lx",
405 tic80_size_name, itable[indx].name,
406 SIZE_HEX, target, (SIZE_DECIMAL*2) + SIZE_HEX + 4, "",
407 SIZE_HEX, target);
408
409 return tic80_trace_buffer;
410}
411
412/* Trace the result of a load or store operation with 2 integer addresses
413 and an integer output or input */
414char *
415tic80_trace_ldst (int indx,
416 int st_p,
417 int m_p,
418 int s_p,
419 unsigned32 value,
420 unsigned32 input1,
421 unsigned32 input2)
422{
381f42ef
AC
423 char name[40];
424
425 if (!tic80_size_name)
426 tic80_init_trace ();
427
428 strcpy (name, itable[indx].name);
429 if (m_p)
430 strcat (name, ":m");
431
432 if (s_p)
433 strcat (name, ":s");
434
8c3b5af1 435 sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld 0x%.*lx/%*ld %s 0x%.*lx/%*ld",
381f42ef 436 tic80_size_name, name,
8c3b5af1
MM
437 SIZE_HEX, input1, SIZE_DECIMAL, (long)(signed32)input1,
438 SIZE_HEX, input2, SIZE_DECIMAL, (long)(signed32)input2,
381f42ef 439 (!st_p) ? "=>" : "<=",
8c3b5af1 440 SIZE_HEX, value, SIZE_DECIMAL, (long)(signed32)value);
381f42ef
AC
441
442 return tic80_trace_buffer;
443}
444
445#endif /* WITH_TRACE */
This page took 0.03938 seconds and 4 git commands to generate.