summaryrefslogtreecommitdiff
path: root/sim/tic80/misc.c
blob: fc7fbec12b7665e28a1a7f7ca5524c90e6b85862 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
/* TIc80 Simulator.
   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
   Contributed by Cygnus Support.

This file is part of GDB, the GNU debugger.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */


#include "sim-main.h"

#ifdef HAVE_STRING_H
#include <string.h>
#else
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#endif


tic80_control_regs
tic80_index2cr (int index)
{
  switch (index)
    {
    case 0x0000: return EPC_CR;
    case 0x0001: return EIP_CR;
    case 0x0002: return CONFIG_CR;
    case 0x0004: return INTPEN_CR;
    case 0x0006: return IE_CR;
    case 0x0008: return FPST_CR;
    case 0x000A: return PPERROR_CR;
    case 0x000D: return PKTREQ_CR;
    case 0x000E: return TCOUNT_CR;
    case 0x000F: return TSCALE_CR;
    case 0x0010: return FLTOP_CR;
    case 0x0011: return FLTADR_CR;
    case 0x0012: return FLTTAG_CR;
    case 0x0013: return FLTDLT_CR;
    case 0x0014: return FLTDTH_CR;
    case 0x0015: return FLT005_CR;
    case 0x0016: return FLT006_CR;
    case 0x0017: return FLT007_CR;
    case 0x0018: return FLT008_CR;
    case 0x0019: return FLT009_CR;
    case 0x001a: return FLT010_CR;
    case 0x001b: return FLT011_CR;
    case 0x001c: return FLT012_CR;
    case 0x001d: return FLT013_CR;
    case 0x001e: return FLT014_CR;
    case 0x001f: return FLT015_CR;
    case 0x0020: return SYSSTK_CR;
    case 0x0021: return SYSTMP_CR;
    case 0x0030: return MPC_CR;
    case 0x0031: return MIP_CR;
    case 0x0033: return ECOMCNTL_CR;
    case 0x0034: return ANASTAT_CR;
    case 0x0039: return BRK1_CR;
    case 0x003A: return BRK2_CR;
    case 0x0200: return ITAG0_CR;
    case 0x0201: return ITAG1_CR;
    case 0x0202: return ITAG2_CR;
    case 0x0203: return ITAG3_CR;
    case 0x0204: return ITAG4_CR;
    case 0x0205: return ITAG5_CR;
    case 0x0206: return ITAG6_CR;
    case 0x0207: return ITAG7_CR;
    case 0x0208: return ITAG8_CR;
    case 0x0209: return ITAG9_CR;
    case 0x020a: return ITAG10_CR;
    case 0x020b: return ITAG11_CR;
    case 0x020c: return ITAG12_CR;
    case 0x020d: return ITAG13_CR;
    case 0x020e: return ITAG14_CR;
    case 0x020f: return ITAG15_CR;
    case 0x0300: return ILRU_CR;
    case 0x0400: return DTAG0_CR;
    case 0x0401: return DTAG1_CR;
    case 0x0402: return DTAG2_CR;
    case 0x0403: return DTAG3_CR;
    case 0x0404: return DTAG4_CR;
    case 0x0405: return DTAG5_CR;
    case 0x0406: return DTAG6_CR;
    case 0x0407: return DTAG7_CR;
    case 0x0408: return DTAG8_CR;
    case 0x0409: return DTAG9_CR;
    case 0x040a: return DTAG10_CR;
    case 0x040b: return DTAG11_CR;
    case 0x040c: return DTAG12_CR;
    case 0x040d: return DTAG13_CR;
    case 0x040e: return DTAG14_CR;
    case 0x040f: return DTAG15_CR;
    case 0x0500: return DLRU_CR;
    case 0x4000: return IN0P_CR;
    case 0x4001: return IN1P_CR;
    case 0x4002: return OUTP_CR;
    default: return SCRATCH_CR;
    }
}



#if defined(WITH_TRACE)
/* Tracing support routines */

static char tic80_trace_buffer[1024];
static int  tic80_size_name;

#define SIZE_HEX	8
#define SIZE_DECIMAL	11

/* Initialize tracing by calculating the maximum name size */
static void
tic80_init_trace (void)
{
  int i;
  int len, max_len = 0;

  for (i = 0; i < (int)nr_itable_entries; i++) {
    len = strlen (itable[i].name);
    if (len > max_len)
      max_len = len;
  }

  tic80_size_name = max_len + sizeof(":m") - 1 + sizeof (":s") - 1;
}

/* Given an integer which is the result of a comparison, return a string
   giving which bits are set.  */

static char *
tic80_trace_cmp_internal (unsigned32 flag)
{
  struct cmp_bits { unsigned32 bit; char *string; };
  static char buffer[32*8];
  static struct cmp_bits bits[] =
  {
    { BIT32(29), "hs" },
    { BIT32(28), "lo" },
    { BIT32(27), "ls" },
    { BIT32(26), "hi" },
    { BIT32(25), "ge" },
    { BIT32(24), "lt" },
    { BIT32(23), "le" },
    { BIT32(22), "gt" },
    { BIT32(21), "ne" },
    { BIT32(20), "eq" },

    { BIT32(19), "hs.h" },
    { BIT32(18), "lo.h" },
    { BIT32(17), "ls.h" },
    { BIT32(16), "hi.h" },
    { BIT32(15), "ge.h" },
    { BIT32(14), "lt.h" },
    { BIT32(13), "le.h" },
    { BIT32(12), "gt.h" },
    { BIT32(11), "ne.h" },
    { BIT32(10), "eq.h" },

    { BIT32( 9), "hs.b" },
    { BIT32( 8), "lo.b" },
    { BIT32( 7), "ls.b" },
    { BIT32( 6), "hi.b" },
    { BIT32( 5), "ge.b" },
    { BIT32( 4), "lt.b" },
    { BIT32( 3), "le.b" },
    { BIT32( 2), "gt.b" },
    { BIT32( 1), "ne.b" },
    { BIT32( 0), "eq.b" },
    { 0,	 (char *)0 },
  };

  int i;
  char *p = buffer;

  for (i = 0; bits[i].bit != 0; i++)
    {
      if ((flag & bits[i].bit) != 0)
	{
	  if (p != buffer)
	    *p++ = ' ';

	  strcpy (p, bits[i].string);
	  p += strlen (p);
	}
    }

  *p = '\0';
  return buffer;
}

/* Trace the result of an ALU operation with 2 integer inputs and an integer output */
char *
tic80_trace_alu3 (int indx,
		  unsigned32 result,
		  unsigned32 input1,
		  unsigned32 input2)
{
  if (!tic80_size_name)
    tic80_init_trace ();

  sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld 0x%.*lx/%*ld => 0x%.*lx/%*ld",
	   tic80_size_name, itable[indx].name,
	   SIZE_HEX, input1, SIZE_DECIMAL, (long)(signed32)input1,
	   SIZE_HEX, input2, SIZE_DECIMAL, (long)(signed32)input2,
	   SIZE_HEX, result, SIZE_DECIMAL, (long)(signed32)result);

  return tic80_trace_buffer;
}

/* Trace the result of an ALU operation with 2 integer inputs and an integer output
   that sets the bits from a compare instruction.  */
char *
tic80_trace_cmp (int indx,
		 unsigned32 result,
		 unsigned32 input1,
		 unsigned32 input2)
{
  if (!tic80_size_name)
    tic80_init_trace ();

  sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld 0x%.*lx/%*ld => 0x%.*lx %s",
	   tic80_size_name, itable[indx].name,
	   SIZE_HEX, input1, SIZE_DECIMAL, (long)(signed32)input1,
	   SIZE_HEX, input2, SIZE_DECIMAL, (long)(signed32)input2,
	   SIZE_HEX, result, tic80_trace_cmp_internal (result));

  return tic80_trace_buffer;
}

/* Trace the result of an ALU operation with 1 integer input and an integer output */
char *
tic80_trace_alu2 (int indx,
		  unsigned32 result,
		  unsigned32 input)
{
  if (!tic80_size_name)
    tic80_init_trace ();

  sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld %*s => 0x%.*lx/%*ld",
	   tic80_size_name, itable[indx].name,
	   SIZE_HEX, input, SIZE_DECIMAL, (long)(signed32)input,
	   SIZE_HEX + SIZE_DECIMAL + 3, "",
	   SIZE_HEX, result, SIZE_DECIMAL, (long)(signed32)result);

  return tic80_trace_buffer;
}

/* Trace the result of a shift instruction */
char *
tic80_trace_shift (int indx,
		   unsigned32 result,
		   unsigned32 input,
		   int i,
		   int n,
		   int merge,
		   int endmask,
		   int rotate)
{
  const char *merge_name;
  char name[40];
  char *p;

  if (!tic80_size_name)
    tic80_init_trace ();

  switch (merge)
    {
    default:	merge_name = ".??"; break;
    case 0:	merge_name = ".dz"; break;
    case 1:	merge_name = ".dm"; break;
    case 2:	merge_name = ".ds"; break;
    case 3:	merge_name = ".ez"; break;
    case 4:	merge_name = ".em"; break;
    case 5:	merge_name = ".es"; break;
    case 6:	merge_name = ".iz"; break;
    case 7:	merge_name = ".im"; break;
    }

  /* Don't use itable[indx].name, which is just sl {r,i}.  Instead reconstruct
     the name, using the i and n fields.  */
  p = strchr (itable[indx].name, ' ');
  sprintf (name, "s%s%s%s%s",
	   (n) ? "r" : "l",
	   (i) ? "i" : "",
	   merge_name,
	   (p) ? p : "");

  sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld %*s%2d,%2d => 0x%.*lx/%*ld",
	   tic80_size_name, name,
	   SIZE_HEX, input, SIZE_DECIMAL, (long)(signed32)input,
	   SIZE_HEX + SIZE_DECIMAL - 2, "",
	   rotate, endmask,
	   SIZE_HEX, result, SIZE_DECIMAL, (long)(signed32)result);

  return tic80_trace_buffer;
}

/* Trace the result of an FPU operation with 2 floating point inputs and a floating point output */
void
tic80_trace_fpu3 (SIM_DESC sd,
		  sim_cpu *cpu,
		  sim_cia cia,
		  int indx,
		  sim_fpu *result,
		  sim_fpu *input1,
		  sim_fpu *input2)
{
  if (!tic80_size_name)
    tic80_init_trace ();

  trace_one_insn (sd, cpu, cia.ip, 1,
		  itable[indx].file, itable[indx].line_nr, "fpu",
		  "%-*s %*g %*g => %*g",
		  tic80_size_name, itable[indx].name,
		  SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input1),
		  SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input2),
		  SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (result));
}

/* Trace the result of an FPU operation with 1 floating point input and a floating point output */
void
tic80_trace_fpu2 (SIM_DESC sd,
		  sim_cpu *cpu,
		  sim_cia cia,
		  int indx,
		  sim_fpu *result,
		  sim_fpu *input)
{
  if (!tic80_size_name)
    tic80_init_trace ();

  trace_one_insn (sd, cpu, cia.ip, 1,
		  itable[indx].file, itable[indx].line_nr, "fpu",
		  "%-*s %*g %-*s => %*g",
		  tic80_size_name, itable[indx].name,
		  SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input),
		  SIZE_HEX + SIZE_DECIMAL + 3, "",
		  SIZE_HEX + SIZE_DECIMAL, sim_fpu_2d (result));
}

/* Trace the result of an FPU operation with 1 floating point input and a floating point output */
void
tic80_trace_fpu1 (SIM_DESC sd,
		  sim_cpu *cpu,
		  sim_cia cia,
		  int indx,
		  sim_fpu *result)
{
  if (!tic80_size_name)
    tic80_init_trace ();

  trace_one_insn (sd, cpu, cia.ip, 1,
		  itable[indx].file, itable[indx].line_nr, "fpu",
		  "%-*s %-*s %-*s => %*g",
		  tic80_size_name, itable[indx].name,
		  SIZE_HEX + SIZE_DECIMAL + 3, "",
		  SIZE_HEX + SIZE_DECIMAL + 3, "",
		  SIZE_HEX + SIZE_DECIMAL, sim_fpu_2d (result));
}

/* Trace the result of an FPU operation with 2 floating point inputs and an integer output */
void
tic80_trace_fpu2i (SIM_DESC sd,
		   sim_cpu *cpu,
		   sim_cia cia,
		   int indx,
		   unsigned32 result,
		   sim_fpu *input1,
		   sim_fpu *input2)
{
  if (!tic80_size_name)
    tic80_init_trace ();

  trace_one_insn (sd, cpu, cia.ip, 1,
		  itable[indx].file, itable[indx].line_nr, "fpu",
		  "%-*s %*g %*g => 0x%.*lx %-*ld",
		  tic80_size_name, itable[indx].name,
		  SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input1),
		  SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input2),
		  SIZE_HEX, result, SIZE_DECIMAL, (long)(signed32)result);
}

/* Trace the result of an FPU operation with 2 floating point inputs and an integer output
   that is the result of a comparison.  */
void
tic80_trace_fpu2cmp (SIM_DESC sd,
		     sim_cpu *cpu,
		     sim_cia cia,
		     int indx,
		     unsigned32 result,
		     sim_fpu *input1,
		     sim_fpu *input2)
{
  if (!tic80_size_name)
    tic80_init_trace ();

  trace_one_insn (sd, cpu, cia.ip, 1,
		  itable[indx].file, itable[indx].line_nr, "fpu",
		  "%-*s %*g %*g => 0x%.*lx %s",
		  tic80_size_name, itable[indx].name,
		  SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input1),
		  SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input2),
		  SIZE_HEX, result, tic80_trace_cmp_internal (result));
}

/* Trace the result of a NOP operation */
char *
tic80_trace_nop (int indx)
{
  if (!tic80_size_name)
    tic80_init_trace ();

  sprintf (tic80_trace_buffer, "%s", itable[indx].name);
  return tic80_trace_buffer;
}

/* Trace the result of a data sink with one input */
char *
tic80_trace_sink1 (int indx, unsigned32 input)
{
  if (!tic80_size_name)
    tic80_init_trace ();

  sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld",
	   tic80_size_name, itable[indx].name,
	   SIZE_HEX, input, SIZE_DECIMAL, (long)(signed32)input);

  return tic80_trace_buffer;
}

/* Trace the result of a data sink with two inputs */
char *
tic80_trace_sink2 (int indx, unsigned32 input1, unsigned32 input2)
{
  if (!tic80_size_name)
    tic80_init_trace ();

  sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld 0x%.*lx/%*ld",
	   tic80_size_name, itable[indx].name,
	   SIZE_HEX, input1, SIZE_DECIMAL, (long)(signed32)input1,
	   SIZE_HEX, input2, SIZE_DECIMAL, (long)(signed32)input2);

  return tic80_trace_buffer;
}

/* Trace the result of a data sink with three inputs */
char *
tic80_trace_sink3 (int indx, unsigned32 input1, unsigned32 input2, unsigned32 input3)
{
  if (!tic80_size_name)
    tic80_init_trace ();

  sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld 0x%.*lx/%*ld    0x%.*lx/%*ld",
	   tic80_size_name, itable[indx].name,
	   SIZE_HEX, input1, SIZE_DECIMAL, (long)(signed32)input1,
	   SIZE_HEX, input2, SIZE_DECIMAL, (long)(signed32)input2,
	   SIZE_HEX, input3, SIZE_DECIMAL, (long)(signed32)input3);

  return tic80_trace_buffer;
}

/* Trace the result of a conditional branch operation */
char *
tic80_trace_cond_br (int indx,
		     int jump_p,
		     unsigned32 cond,
		     unsigned32 target,
		     int size,
		     int code)
{
  char *suffix1, *suffix2;

  if (!tic80_size_name)
    tic80_init_trace ();

  if (size >= 0 && code >= 0)
    {				/* BCND */
      switch (code)
	{
	default: suffix1 = "???"; break;
	case 0:  suffix1 = "nev"; break;
	case 1:  suffix1 = "gt0"; break;
	case 2:  suffix1 = "eq0"; break;
	case 3:  suffix1 = "ge0"; break;
	case 4:  suffix1 = "lt0"; break;
	case 5:  suffix1 = "ne0"; break;
	case 6:  suffix1 = "le0"; break;
	case 7:  suffix1 = "alw"; break;
	}

      switch (size)
	{
	default: suffix2 = ".?"; break;
	case 0:  suffix2 = ".b"; break;
	case 1:  suffix2 = ".h"; break;
	case 2:  suffix2 = ".w"; break;
	}

    } else {			/* BBO/BBZ */

      suffix2 = "";
      switch (cond)
	{
	default: suffix1 = "??.?"; break;
	case 29: suffix1 = "hs.w"; break;
	case 28: suffix1 = "lo.w"; break;
	case 27: suffix1 = "ls.w"; break;
	case 26: suffix1 = "hi.w"; break;
	case 25: suffix1 = "ge.w"; break;
	case 24: suffix1 = "lt.w"; break;
	case 23: suffix1 = "le.w"; break;
	case 22: suffix1 = "gt.w"; break;
	case 21: suffix1 = "ne.w"; break;
	case 20: suffix1 = "eq.w"; break;
	case 19: suffix1 = "hs.h"; break;
	case 18: suffix1 = "lo.h"; break;
	case 17: suffix1 = "ls.h"; break;
	case 16: suffix1 = "hi.h"; break;
	case 15: suffix1 = "ge.h"; break;
	case 14: suffix1 = "lt.h"; break;
	case 13: suffix1 = "le.h"; break;
	case 12: suffix1 = "gt.h"; break;
	case 11: suffix1 = "ne.h"; break;
	case 10: suffix1 = "eq.h"; break;
	case  9: suffix1 = "hs.b"; break;
	case  8: suffix1 = "lo.b"; break;
	case  7: suffix1 = "ls.b"; break;
	case  6: suffix1 = "hi.b"; break;
	case  5: suffix1 = "ge.b"; break;
	case  4: suffix1 = "lt.b"; break;
	case  3: suffix1 = "le.b"; break;
	case  2: suffix1 = "gt.b"; break;
	case  1: suffix1 = "ne.b"; break;
	case  0: suffix1 = "eq.b"; break;
	}
    }

  if (jump_p)
    sprintf (tic80_trace_buffer,
	     "%-*s 0x%.*lx %*s 0x%.*lx/%*ld => 0x%.*lx %s%s",
	     tic80_size_name, itable[indx].name,
	     SIZE_HEX, target, SIZE_DECIMAL, "",
	     SIZE_HEX, cond, SIZE_DECIMAL, (long)(signed32)cond,
	     SIZE_HEX, target,
	     suffix1, suffix2);
  else
    sprintf (tic80_trace_buffer,
	     "%-*s 0x%.*lx %*s 0x%.*lx/%*ld => %-*s %s%s",
	     tic80_size_name, itable[indx].name,
	     SIZE_HEX, target, SIZE_DECIMAL, "",
	     SIZE_HEX, cond, SIZE_DECIMAL, (long)(signed32)cond,
	     SIZE_HEX + 2, "[no jump]",
	     suffix1, suffix2);

  return tic80_trace_buffer;
}

/* Trace the result of a unconditional branch operation */
char *
tic80_trace_ucond_br (int indx,
		      unsigned32 target)
{
  if (!tic80_size_name)
    tic80_init_trace ();

  sprintf (tic80_trace_buffer,
	     "%-*s 0x%.*lx %*s => 0x%.*lx",
	     tic80_size_name, itable[indx].name,
	     SIZE_HEX, target, (SIZE_DECIMAL*2) + SIZE_HEX + 4, "",
	     SIZE_HEX, target);

  return tic80_trace_buffer;
}

/* Trace the result of a load or store operation with 2 integer addresses
   and an integer output or input */
void
tic80_trace_ldst (SIM_DESC sd,
		  sim_cpu *cpu,
		  sim_cia cia,
		  int indx,
		  int st_p,
		  int m_p,
		  int s_p,
		  unsigned32 value,
		  unsigned32 input1,
		  unsigned32 input2)
{
  char name[40];

  if (!tic80_size_name)
    tic80_init_trace ();

  strcpy (name, itable[indx].name);
  if (m_p)
    strcat (name, ":m");

  if (s_p)
    strcat (name, ":s");

  trace_one_insn (sd, cpu, cia.ip, 1,
		  itable[indx].file, itable[indx].line_nr, "memory",
		  "%-*s 0x%.*lx/%*ld 0x%.*lx/%*ld %s 0x%.*lx/%*ld",
		  tic80_size_name, name,
		  SIZE_HEX, input1, SIZE_DECIMAL, (long)(signed32)input1,
		  SIZE_HEX, input2, SIZE_DECIMAL, (long)(signed32)input2,
		  (!st_p) ? "=>" : "<=",
		  SIZE_HEX, value, SIZE_DECIMAL, (long)(signed32)value);
}

#endif /* WITH_TRACE */