From 450be2349aa1beda81274be407713657f457ef50 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Sun, 11 May 1997 14:32:32 +0000 Subject: [PATCH] Fix shift/lmo insns; Subu does arithmetic unsigned --- sim/tic80/ChangeLog | 14 ++++++++++++ sim/tic80/cpu.h | 11 ++++++++++ sim/tic80/insns | 35 +++++++++++------------------- sim/tic80/misc.c | 52 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 88 insertions(+), 24 deletions(-) diff --git a/sim/tic80/ChangeLog b/sim/tic80/ChangeLog index 382fa79ef76..b22b9d38bae 100644 --- a/sim/tic80/ChangeLog +++ b/sim/tic80/ChangeLog @@ -1,3 +1,17 @@ +Sun May 11 10:25:14 1997 Michael Meissner + + * cpu.h (tic80_trace_shift): Add declaration. + (TRACE_SHIFT): New macro to trace shift instructions. + + * misc.c (tic80_trace_alu2): Align spacing. + (tic80_trace_shift): New function to trace shifts. + + * insns (lmo): Add missing 0b prefix to bits. + (do_shift): Use ~ (unsigned32)0, instead of -1. Use TRACE_SHIFT + instead of TRACE_ALU2. + (sl r): Use EndMask as is, instead of using Source+1 register. + (subu): Operands are unsigned, not signed. + Sat May 10 12:35:47 1997 Michael Meissner * insns (and{.tt,.tf,.ft,.ff}): Immediate values are unsigned, not diff --git a/sim/tic80/cpu.h b/sim/tic80/cpu.h index 3a4b04284bc..a770192aa5b 100644 --- a/sim/tic80/cpu.h +++ b/sim/tic80/cpu.h @@ -160,6 +160,7 @@ struct _sim_cpu { #if defined(WITH_TRACE) extern char *tic80_trace_alu3 PARAMS ((int, unsigned32, unsigned32, unsigned32)); extern char *tic80_trace_alu2 PARAMS ((int, unsigned32, unsigned32)); +extern char *tic80_trace_shift PARAMS ((int, unsigned32, unsigned32, int, int, int, int, int)); extern void tic80_trace_fpu3 PARAMS ((SIM_DESC, sim_cpu *, sim_cia, int, sim_fpu, sim_fpu, sim_fpu)); extern void tic80_trace_fpu2 PARAMS ((SIM_DESC, sim_cpu *, sim_cia, int, @@ -192,6 +193,16 @@ do { \ } \ } while (0) +#define TRACE_SHIFT(indx, result, input, i, n, merge, endmask, rotate) \ +do { \ + if (TRACE_ALU_P (CPU)) { \ + trace_one_insn (SD, CPU, cia.ip, 1, itable[indx].file, \ + itable[indx].line_nr, "shift", \ + tic80_trace_shift (indx, result, input, i, n, \ + merge, endmask, rotate)); \ + } \ +} while (0) + #define TRACE_FPU3(indx, result, input1, input2) \ do { \ if (TRACE_FPU_P (CPU)) { \ diff --git a/sim/tic80/insns b/sim/tic80/insns index a78edc11fa5..396dcd6ed91 100644 --- a/sim/tic80/insns +++ b/sim/tic80/insns @@ -706,7 +706,7 @@ void::function::do_ld_u:unsigned32 *rDest, unsigned32 Base, unsigned32 *rBase, i // lmo -31.Dest,26.Source,21.111111000,12.0,11./::::lmo +31.Dest,26.Source,21.0b111111000,12.0,11./::::lmo int b; for (b = 0; b < 32; b++) if (rSource & BIT32 (31 - b)) @@ -820,7 +820,7 @@ void::function::do_shift:int Dest, int Source, int Merge, int i, int n, int EndM } /* form the end mask */ if (EndMask == 0) - endmask = -1; + endmask = ~ (unsigned32)0; else endmask = (1 << EndMask) - 1; if (i) @@ -829,13 +829,13 @@ void::function::do_shift:int Dest, int Source, int Merge, int i, int n, int EndM switch (Merge) { case 0: case 1: case 2: - shiftmask = -1; /* disabled */ + shiftmask = ~ (unsigned32)0; /* disabled */ break; case 3: case 4: case 5: - shiftmask = ((1 << nRotate) - 1); /* enabled */ + shiftmask = ((1 << nRotate) - 1); /* enabled */ break; case 6: case 7: - shiftmask = ~((1 << nRotate) - 1); /* inverted */ + shiftmask = ~((1 << nRotate) - 1); /* inverted */ break; default: engine_error (SD, CPU, cia, @@ -848,13 +848,13 @@ void::function::do_shift:int Dest, int Source, int Merge, int i, int n, int EndM /* and merge */ switch (Merge) { - case 0: case 3: case 6: /* zero */ + case 0: case 3: case 6: /* zero */ GPR (Dest) = rotated & cm; break; - case 1: case 4: case 7: /* merge */ + case 1: case 4: case 7: /* merge */ GPR (Dest) = (rotated & cm) | (GPR (Dest) & ~cm); break; - case 2: case 5: /* sign */ + case 2: case 5: /* sign */ { int b; GPR (Dest) = rotated & cm; @@ -870,22 +870,11 @@ void::function::do_shift:int Dest, int Source, int Merge, int i, int n, int EndM cia.ip, Source); } - TRACE_ALU2 (MY_INDEX, GPR (Dest), input); + TRACE_SHIFT (MY_INDEX, GPR (Dest), input, i, n, Merge, EndMask, Rotate); 31.Dest,26.Source,21.0b0001,17.Merge,14./,11.i,10.n,9.EndMask,4.Rotate::::sl i do_shift (_SD, Dest, Source, Merge, i, n, EndMask, Rotate); 31.Dest,26.Source,21.0b110001,15.Merge,12.0,11.i,10.n,9.EndMask,4.RotReg::::sl r - int endmask; - if (EndMask == 0) - endmask = EndMask; - else - { - if (Source & 1) - engine_error (SD, CPU, cia, - "0x%lx: Invalid source (%d) for shift", - cia.ip, Source); - endmask = GPR (Source + 1) & 31; - } - do_shift (_SD, Dest, Source, Merge, i, n, endmask, GPR (RotReg) & 31); + do_shift (_SD, Dest, Source, Merge, i, n, EndMask, GPR (RotReg) & 31); // sli.{d|e|i}{m|s|z} - see shift @@ -959,12 +948,12 @@ void::function::do_sub:signed32 *rDest, signed32 Source1, signed32 Source2 // subu -void::function::do_subu:signed32 *rDest, signed32 Source1, signed32 Source2 +void::function::do_subu:unsigned32 *rDest, unsigned32 Source1, signed32 Source2 unsigned32 result = Source1 - Source2; TRACE_ALU3 (MY_INDEX, result, Source1, Source2); *rDest = result; // NOTE - the book has 15.1 which conflicts with subu. -31.Dest,26.Source2,21.0b101101,15.1,14.SignedImmediate::::subu i +31.Dest,26.Source2,21.0b101101,15.1,14.UnsignedImmediate::::subu i do_subu (_SD, rDest, vSource1, rSource2); 31.Dest,26.Source2,21.0b11101101,13.1,12.0,11./,4.Source1::::subu r do_subu (_SD, rDest, rSource1, rSource2); diff --git a/sim/tic80/misc.c b/sim/tic80/misc.c index 9359fe2679d..b9af1b88957 100644 --- a/sim/tic80/misc.c +++ b/sim/tic80/misc.c @@ -168,12 +168,62 @@ tic80_trace_alu2 (int indx, 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 + 2, "", + 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, -- 2.30.2