Commit | Line | Data |
---|---|---|
6c29acca AC |
1 | /* TIc80 Simulator. |
2 | Copyright (C) 1997, 1998 Free Software Foundation, Inc. | |
3 | Contributed by Cygnus Support. | |
4 | ||
5 | This file is part of GDB, the GNU debugger. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 2, or (at your option) | |
10 | any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License along | |
18 | with this program; if not, write to the Free Software Foundation, Inc., | |
19 | 59 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 | ||
33 | tic80_control_regs | |
34 | tic80_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 | ||
118 | static char tic80_trace_buffer[1024]; | |
119 | static int tic80_size_name; | |
120 | ||
121 | #define SIZE_HEX 8 | |
122 | #define SIZE_DECIMAL 11 | |
123 | ||
124 | /* Initialize tracing by calculating the maximum name size */ | |
125 | static void | |
126 | tic80_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 | /* Given an integer which is the result of a comparison, return a string | |
141 | giving which bits are set. */ | |
142 | ||
143 | static char * | |
144 | tic80_trace_cmp_internal (unsigned32 flag) | |
145 | { | |
146 | struct cmp_bits { unsigned32 bit; char *string; }; | |
147 | static char buffer[32*8]; | |
148 | static struct cmp_bits bits[] = | |
149 | { | |
150 | { BIT32(29), "hs" }, | |
151 | { BIT32(28), "lo" }, | |
152 | { BIT32(27), "ls" }, | |
153 | { BIT32(26), "hi" }, | |
154 | { BIT32(25), "ge" }, | |
155 | { BIT32(24), "lt" }, | |
156 | { BIT32(23), "le" }, | |
157 | { BIT32(22), "gt" }, | |
158 | { BIT32(21), "ne" }, | |
159 | { BIT32(20), "eq" }, | |
160 | ||
161 | { BIT32(19), "hs.h" }, | |
162 | { BIT32(18), "lo.h" }, | |
163 | { BIT32(17), "ls.h" }, | |
164 | { BIT32(16), "hi.h" }, | |
165 | { BIT32(15), "ge.h" }, | |
166 | { BIT32(14), "lt.h" }, | |
167 | { BIT32(13), "le.h" }, | |
168 | { BIT32(12), "gt.h" }, | |
169 | { BIT32(11), "ne.h" }, | |
170 | { BIT32(10), "eq.h" }, | |
171 | ||
172 | { BIT32( 9), "hs.b" }, | |
173 | { BIT32( 8), "lo.b" }, | |
174 | { BIT32( 7), "ls.b" }, | |
175 | { BIT32( 6), "hi.b" }, | |
176 | { BIT32( 5), "ge.b" }, | |
177 | { BIT32( 4), "lt.b" }, | |
178 | { BIT32( 3), "le.b" }, | |
179 | { BIT32( 2), "gt.b" }, | |
180 | { BIT32( 1), "ne.b" }, | |
181 | { BIT32( 0), "eq.b" }, | |
182 | { 0, (char *)0 }, | |
183 | }; | |
184 | ||
185 | int i; | |
186 | char *p = buffer; | |
187 | ||
188 | for (i = 0; bits[i].bit != 0; i++) | |
189 | { | |
190 | if ((flag & bits[i].bit) != 0) | |
191 | { | |
192 | if (p != buffer) | |
193 | *p++ = ' '; | |
194 | ||
195 | strcpy (p, bits[i].string); | |
196 | p += strlen (p); | |
197 | } | |
198 | } | |
199 | ||
200 | *p = '\0'; | |
201 | return buffer; | |
202 | } | |
203 | ||
204 | /* Trace the result of an ALU operation with 2 integer inputs and an integer output */ | |
205 | char * | |
206 | tic80_trace_alu3 (int indx, | |
207 | unsigned32 result, | |
208 | unsigned32 input1, | |
209 | unsigned32 input2) | |
210 | { | |
211 | if (!tic80_size_name) | |
212 | tic80_init_trace (); | |
213 | ||
214 | sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld 0x%.*lx/%*ld => 0x%.*lx/%*ld", | |
215 | tic80_size_name, itable[indx].name, | |
216 | SIZE_HEX, input1, SIZE_DECIMAL, (long)(signed32)input1, | |
217 | SIZE_HEX, input2, SIZE_DECIMAL, (long)(signed32)input2, | |
218 | SIZE_HEX, result, SIZE_DECIMAL, (long)(signed32)result); | |
219 | ||
220 | return tic80_trace_buffer; | |
221 | } | |
222 | ||
223 | /* Trace the result of an ALU operation with 2 integer inputs and an integer output | |
224 | that sets the bits from a compare instruction. */ | |
225 | char * | |
226 | tic80_trace_cmp (int indx, | |
227 | unsigned32 result, | |
228 | unsigned32 input1, | |
229 | unsigned32 input2) | |
230 | { | |
231 | if (!tic80_size_name) | |
232 | tic80_init_trace (); | |
233 | ||
234 | sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld 0x%.*lx/%*ld => 0x%.*lx %s", | |
235 | tic80_size_name, itable[indx].name, | |
236 | SIZE_HEX, input1, SIZE_DECIMAL, (long)(signed32)input1, | |
237 | SIZE_HEX, input2, SIZE_DECIMAL, (long)(signed32)input2, | |
238 | SIZE_HEX, result, tic80_trace_cmp_internal (result)); | |
239 | ||
240 | return tic80_trace_buffer; | |
241 | } | |
242 | ||
243 | /* Trace the result of an ALU operation with 1 integer input and an integer output */ | |
244 | char * | |
245 | tic80_trace_alu2 (int indx, | |
246 | unsigned32 result, | |
247 | unsigned32 input) | |
248 | { | |
249 | if (!tic80_size_name) | |
250 | tic80_init_trace (); | |
251 | ||
252 | sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld %*s => 0x%.*lx/%*ld", | |
253 | tic80_size_name, itable[indx].name, | |
254 | SIZE_HEX, input, SIZE_DECIMAL, (long)(signed32)input, | |
255 | SIZE_HEX + SIZE_DECIMAL + 3, "", | |
256 | SIZE_HEX, result, SIZE_DECIMAL, (long)(signed32)result); | |
257 | ||
258 | return tic80_trace_buffer; | |
259 | } | |
260 | ||
261 | /* Trace the result of a shift instruction */ | |
262 | char * | |
263 | tic80_trace_shift (int indx, | |
264 | unsigned32 result, | |
265 | unsigned32 input, | |
266 | int i, | |
267 | int n, | |
268 | int merge, | |
269 | int endmask, | |
270 | int rotate) | |
271 | { | |
272 | const char *merge_name; | |
273 | char name[40]; | |
274 | char *p; | |
275 | ||
276 | if (!tic80_size_name) | |
277 | tic80_init_trace (); | |
278 | ||
279 | switch (merge) | |
280 | { | |
281 | default: merge_name = ".??"; break; | |
282 | case 0: merge_name = ".dz"; break; | |
283 | case 1: merge_name = ".dm"; break; | |
284 | case 2: merge_name = ".ds"; break; | |
285 | case 3: merge_name = ".ez"; break; | |
286 | case 4: merge_name = ".em"; break; | |
287 | case 5: merge_name = ".es"; break; | |
288 | case 6: merge_name = ".iz"; break; | |
289 | case 7: merge_name = ".im"; break; | |
290 | } | |
291 | ||
292 | /* Don't use itable[indx].name, which is just sl {r,i}. Instead reconstruct | |
293 | the name, using the i and n fields. */ | |
294 | p = strchr (itable[indx].name, ' '); | |
295 | sprintf (name, "s%s%s%s%s", | |
296 | (n) ? "r" : "l", | |
297 | (i) ? "i" : "", | |
298 | merge_name, | |
299 | (p) ? p : ""); | |
300 | ||
301 | sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld %*s%2d,%2d => 0x%.*lx/%*ld", | |
302 | tic80_size_name, name, | |
303 | SIZE_HEX, input, SIZE_DECIMAL, (long)(signed32)input, | |
304 | SIZE_HEX + SIZE_DECIMAL - 2, "", | |
305 | rotate, endmask, | |
306 | SIZE_HEX, result, SIZE_DECIMAL, (long)(signed32)result); | |
307 | ||
308 | return tic80_trace_buffer; | |
309 | } | |
310 | ||
311 | /* Trace the result of an FPU operation with 2 floating point inputs and a floating point output */ | |
312 | void | |
313 | tic80_trace_fpu3 (SIM_DESC sd, | |
314 | sim_cpu *cpu, | |
315 | sim_cia cia, | |
316 | int indx, | |
317 | sim_fpu *result, | |
318 | sim_fpu *input1, | |
319 | sim_fpu *input2) | |
320 | { | |
321 | if (!tic80_size_name) | |
322 | tic80_init_trace (); | |
323 | ||
324 | trace_one_insn (sd, cpu, cia.ip, 1, | |
325 | itable[indx].file, itable[indx].line_nr, "fpu", | |
326 | "%-*s %*g %*g => %*g", | |
327 | tic80_size_name, itable[indx].name, | |
328 | SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input1), | |
329 | SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input2), | |
330 | SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (result)); | |
331 | } | |
332 | ||
333 | /* Trace the result of an FPU operation with 1 floating point input and a floating point output */ | |
334 | void | |
335 | tic80_trace_fpu2 (SIM_DESC sd, | |
336 | sim_cpu *cpu, | |
337 | sim_cia cia, | |
338 | int indx, | |
339 | sim_fpu *result, | |
340 | sim_fpu *input) | |
341 | { | |
342 | if (!tic80_size_name) | |
343 | tic80_init_trace (); | |
344 | ||
345 | trace_one_insn (sd, cpu, cia.ip, 1, | |
346 | itable[indx].file, itable[indx].line_nr, "fpu", | |
347 | "%-*s %*g %-*s => %*g", | |
348 | tic80_size_name, itable[indx].name, | |
349 | SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input), | |
350 | SIZE_HEX + SIZE_DECIMAL + 3, "", | |
351 | SIZE_HEX + SIZE_DECIMAL, sim_fpu_2d (result)); | |
352 | } | |
353 | ||
354 | /* Trace the result of an FPU operation with 1 floating point input and a floating point output */ | |
355 | void | |
356 | tic80_trace_fpu1 (SIM_DESC sd, | |
357 | sim_cpu *cpu, | |
358 | sim_cia cia, | |
359 | int indx, | |
360 | sim_fpu *result) | |
361 | { | |
362 | if (!tic80_size_name) | |
363 | tic80_init_trace (); | |
364 | ||
365 | trace_one_insn (sd, cpu, cia.ip, 1, | |
366 | itable[indx].file, itable[indx].line_nr, "fpu", | |
367 | "%-*s %-*s %-*s => %*g", | |
368 | tic80_size_name, itable[indx].name, | |
369 | SIZE_HEX + SIZE_DECIMAL + 3, "", | |
370 | SIZE_HEX + SIZE_DECIMAL + 3, "", | |
371 | SIZE_HEX + SIZE_DECIMAL, sim_fpu_2d (result)); | |
372 | } | |
373 | ||
374 | /* Trace the result of an FPU operation with 2 floating point inputs and an integer output */ | |
375 | void | |
376 | tic80_trace_fpu2i (SIM_DESC sd, | |
377 | sim_cpu *cpu, | |
378 | sim_cia cia, | |
379 | int indx, | |
380 | unsigned32 result, | |
381 | sim_fpu *input1, | |
382 | sim_fpu *input2) | |
383 | { | |
384 | if (!tic80_size_name) | |
385 | tic80_init_trace (); | |
386 | ||
387 | trace_one_insn (sd, cpu, cia.ip, 1, | |
388 | itable[indx].file, itable[indx].line_nr, "fpu", | |
389 | "%-*s %*g %*g => 0x%.*lx %-*ld", | |
390 | tic80_size_name, itable[indx].name, | |
391 | SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input1), | |
392 | SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input2), | |
393 | SIZE_HEX, result, SIZE_DECIMAL, (long)(signed32)result); | |
394 | } | |
395 | ||
396 | /* Trace the result of an FPU operation with 2 floating point inputs and an integer output | |
397 | that is the result of a comparison. */ | |
398 | void | |
399 | tic80_trace_fpu2cmp (SIM_DESC sd, | |
400 | sim_cpu *cpu, | |
401 | sim_cia cia, | |
402 | int indx, | |
403 | unsigned32 result, | |
404 | sim_fpu *input1, | |
405 | sim_fpu *input2) | |
406 | { | |
407 | if (!tic80_size_name) | |
408 | tic80_init_trace (); | |
409 | ||
410 | trace_one_insn (sd, cpu, cia.ip, 1, | |
411 | itable[indx].file, itable[indx].line_nr, "fpu", | |
412 | "%-*s %*g %*g => 0x%.*lx %s", | |
413 | tic80_size_name, itable[indx].name, | |
414 | SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input1), | |
415 | SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input2), | |
416 | SIZE_HEX, result, tic80_trace_cmp_internal (result)); | |
417 | } | |
418 | ||
419 | /* Trace the result of a NOP operation */ | |
420 | char * | |
421 | tic80_trace_nop (int indx) | |
422 | { | |
423 | if (!tic80_size_name) | |
424 | tic80_init_trace (); | |
425 | ||
426 | sprintf (tic80_trace_buffer, "%s", itable[indx].name); | |
427 | return tic80_trace_buffer; | |
428 | } | |
429 | ||
430 | /* Trace the result of a data sink with one input */ | |
431 | char * | |
432 | tic80_trace_sink1 (int indx, unsigned32 input) | |
433 | { | |
434 | if (!tic80_size_name) | |
435 | tic80_init_trace (); | |
436 | ||
437 | sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld", | |
438 | tic80_size_name, itable[indx].name, | |
439 | SIZE_HEX, input, SIZE_DECIMAL, (long)(signed32)input); | |
440 | ||
441 | return tic80_trace_buffer; | |
442 | } | |
443 | ||
444 | /* Trace the result of a data sink with two inputs */ | |
445 | char * | |
446 | tic80_trace_sink2 (int indx, unsigned32 input1, unsigned32 input2) | |
447 | { | |
448 | if (!tic80_size_name) | |
449 | tic80_init_trace (); | |
450 | ||
451 | sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld 0x%.*lx/%*ld", | |
452 | tic80_size_name, itable[indx].name, | |
453 | SIZE_HEX, input1, SIZE_DECIMAL, (long)(signed32)input1, | |
454 | SIZE_HEX, input2, SIZE_DECIMAL, (long)(signed32)input2); | |
455 | ||
456 | return tic80_trace_buffer; | |
457 | } | |
458 | ||
459 | /* Trace the result of a data sink with three inputs */ | |
460 | char * | |
461 | tic80_trace_sink3 (int indx, unsigned32 input1, unsigned32 input2, unsigned32 input3) | |
462 | { | |
463 | if (!tic80_size_name) | |
464 | tic80_init_trace (); | |
465 | ||
466 | sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld 0x%.*lx/%*ld 0x%.*lx/%*ld", | |
467 | tic80_size_name, itable[indx].name, | |
468 | SIZE_HEX, input1, SIZE_DECIMAL, (long)(signed32)input1, | |
469 | SIZE_HEX, input2, SIZE_DECIMAL, (long)(signed32)input2, | |
470 | SIZE_HEX, input3, SIZE_DECIMAL, (long)(signed32)input3); | |
471 | ||
472 | return tic80_trace_buffer; | |
473 | } | |
474 | ||
475 | /* Trace the result of a conditional branch operation */ | |
476 | char * | |
477 | tic80_trace_cond_br (int indx, | |
478 | int jump_p, | |
479 | unsigned32 cond, | |
480 | unsigned32 target, | |
481 | int size, | |
482 | int code) | |
483 | { | |
484 | char *suffix1, *suffix2; | |
485 | ||
486 | if (!tic80_size_name) | |
487 | tic80_init_trace (); | |
488 | ||
489 | if (size >= 0 && code >= 0) | |
490 | { /* BCND */ | |
491 | switch (code) | |
492 | { | |
493 | default: suffix1 = "???"; break; | |
494 | case 0: suffix1 = "nev"; break; | |
495 | case 1: suffix1 = "gt0"; break; | |
496 | case 2: suffix1 = "eq0"; break; | |
497 | case 3: suffix1 = "ge0"; break; | |
498 | case 4: suffix1 = "lt0"; break; | |
499 | case 5: suffix1 = "ne0"; break; | |
500 | case 6: suffix1 = "le0"; break; | |
501 | case 7: suffix1 = "alw"; break; | |
502 | } | |
503 | ||
504 | switch (size) | |
505 | { | |
506 | default: suffix2 = ".?"; break; | |
507 | case 0: suffix2 = ".b"; break; | |
508 | case 1: suffix2 = ".h"; break; | |
509 | case 2: suffix2 = ".w"; break; | |
510 | } | |
511 | ||
512 | } else { /* BBO/BBZ */ | |
513 | ||
514 | suffix2 = ""; | |
515 | switch (cond) | |
516 | { | |
517 | default: suffix1 = "??.?"; break; | |
518 | case 29: suffix1 = "hs.w"; break; | |
519 | case 28: suffix1 = "lo.w"; break; | |
520 | case 27: suffix1 = "ls.w"; break; | |
521 | case 26: suffix1 = "hi.w"; break; | |
522 | case 25: suffix1 = "ge.w"; break; | |
523 | case 24: suffix1 = "lt.w"; break; | |
524 | case 23: suffix1 = "le.w"; break; | |
525 | case 22: suffix1 = "gt.w"; break; | |
526 | case 21: suffix1 = "ne.w"; break; | |
527 | case 20: suffix1 = "eq.w"; break; | |
528 | case 19: suffix1 = "hs.h"; break; | |
529 | case 18: suffix1 = "lo.h"; break; | |
530 | case 17: suffix1 = "ls.h"; break; | |
531 | case 16: suffix1 = "hi.h"; break; | |
532 | case 15: suffix1 = "ge.h"; break; | |
533 | case 14: suffix1 = "lt.h"; break; | |
534 | case 13: suffix1 = "le.h"; break; | |
535 | case 12: suffix1 = "gt.h"; break; | |
536 | case 11: suffix1 = "ne.h"; break; | |
537 | case 10: suffix1 = "eq.h"; break; | |
538 | case 9: suffix1 = "hs.b"; break; | |
539 | case 8: suffix1 = "lo.b"; break; | |
540 | case 7: suffix1 = "ls.b"; break; | |
541 | case 6: suffix1 = "hi.b"; break; | |
542 | case 5: suffix1 = "ge.b"; break; | |
543 | case 4: suffix1 = "lt.b"; break; | |
544 | case 3: suffix1 = "le.b"; break; | |
545 | case 2: suffix1 = "gt.b"; break; | |
546 | case 1: suffix1 = "ne.b"; break; | |
547 | case 0: suffix1 = "eq.b"; break; | |
548 | } | |
549 | } | |
550 | ||
551 | if (jump_p) | |
552 | sprintf (tic80_trace_buffer, | |
553 | "%-*s 0x%.*lx %*s 0x%.*lx/%*ld => 0x%.*lx %s%s", | |
554 | tic80_size_name, itable[indx].name, | |
555 | SIZE_HEX, target, SIZE_DECIMAL, "", | |
556 | SIZE_HEX, cond, SIZE_DECIMAL, (long)(signed32)cond, | |
557 | SIZE_HEX, target, | |
558 | suffix1, suffix2); | |
559 | else | |
560 | sprintf (tic80_trace_buffer, | |
561 | "%-*s 0x%.*lx %*s 0x%.*lx/%*ld => %-*s %s%s", | |
562 | tic80_size_name, itable[indx].name, | |
563 | SIZE_HEX, target, SIZE_DECIMAL, "", | |
564 | SIZE_HEX, cond, SIZE_DECIMAL, (long)(signed32)cond, | |
565 | SIZE_HEX + 2, "[no jump]", | |
566 | suffix1, suffix2); | |
567 | ||
568 | return tic80_trace_buffer; | |
569 | } | |
570 | ||
571 | /* Trace the result of a unconditional branch operation */ | |
572 | char * | |
573 | tic80_trace_ucond_br (int indx, | |
574 | unsigned32 target) | |
575 | { | |
576 | if (!tic80_size_name) | |
577 | tic80_init_trace (); | |
578 | ||
579 | sprintf (tic80_trace_buffer, | |
580 | "%-*s 0x%.*lx %*s => 0x%.*lx", | |
581 | tic80_size_name, itable[indx].name, | |
582 | SIZE_HEX, target, (SIZE_DECIMAL*2) + SIZE_HEX + 4, "", | |
583 | SIZE_HEX, target); | |
584 | ||
585 | return tic80_trace_buffer; | |
586 | } | |
587 | ||
588 | /* Trace the result of a load or store operation with 2 integer addresses | |
589 | and an integer output or input */ | |
590 | void | |
591 | tic80_trace_ldst (SIM_DESC sd, | |
592 | sim_cpu *cpu, | |
593 | sim_cia cia, | |
594 | int indx, | |
595 | int st_p, | |
596 | int m_p, | |
597 | int s_p, | |
598 | unsigned32 value, | |
599 | unsigned32 input1, | |
600 | unsigned32 input2) | |
601 | { | |
602 | char name[40]; | |
603 | ||
604 | if (!tic80_size_name) | |
605 | tic80_init_trace (); | |
606 | ||
607 | strcpy (name, itable[indx].name); | |
608 | if (m_p) | |
609 | strcat (name, ":m"); | |
610 | ||
611 | if (s_p) | |
612 | strcat (name, ":s"); | |
613 | ||
614 | trace_one_insn (sd, cpu, cia.ip, 1, | |
615 | itable[indx].file, itable[indx].line_nr, "memory", | |
616 | "%-*s 0x%.*lx/%*ld 0x%.*lx/%*ld %s 0x%.*lx/%*ld", | |
617 | tic80_size_name, name, | |
618 | SIZE_HEX, input1, SIZE_DECIMAL, (long)(signed32)input1, | |
619 | SIZE_HEX, input2, SIZE_DECIMAL, (long)(signed32)input2, | |
620 | (!st_p) ? "=>" : "<=", | |
621 | SIZE_HEX, value, SIZE_DECIMAL, (long)(signed32)value); | |
622 | } | |
623 | ||
624 | #endif /* WITH_TRACE */ |