Fix shift/lmo insns; Subu does arithmetic unsigned
This commit is contained in:
parent
20b2f9bc83
commit
450be2349a
4 changed files with 88 additions and 24 deletions
|
@ -1,3 +1,17 @@
|
||||||
|
Sun May 11 10:25:14 1997 Michael Meissner <meissner@cygnus.com>
|
||||||
|
|
||||||
|
* 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 <meissner@cygnus.com>
|
Sat May 10 12:35:47 1997 Michael Meissner <meissner@cygnus.com>
|
||||||
|
|
||||||
* insns (and{.tt,.tf,.ft,.ff}): Immediate values are unsigned, not
|
* insns (and{.tt,.tf,.ft,.ff}): Immediate values are unsigned, not
|
||||||
|
|
|
@ -160,6 +160,7 @@ struct _sim_cpu {
|
||||||
#if defined(WITH_TRACE)
|
#if defined(WITH_TRACE)
|
||||||
extern char *tic80_trace_alu3 PARAMS ((int, unsigned32, unsigned32, unsigned32));
|
extern char *tic80_trace_alu3 PARAMS ((int, unsigned32, unsigned32, unsigned32));
|
||||||
extern char *tic80_trace_alu2 PARAMS ((int, 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,
|
extern void tic80_trace_fpu3 PARAMS ((SIM_DESC, sim_cpu *, sim_cia, int,
|
||||||
sim_fpu, sim_fpu, sim_fpu));
|
sim_fpu, sim_fpu, sim_fpu));
|
||||||
extern void tic80_trace_fpu2 PARAMS ((SIM_DESC, sim_cpu *, sim_cia, int,
|
extern void tic80_trace_fpu2 PARAMS ((SIM_DESC, sim_cpu *, sim_cia, int,
|
||||||
|
@ -192,6 +193,16 @@ do { \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} 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) \
|
#define TRACE_FPU3(indx, result, input1, input2) \
|
||||||
do { \
|
do { \
|
||||||
if (TRACE_FPU_P (CPU)) { \
|
if (TRACE_FPU_P (CPU)) { \
|
||||||
|
|
|
@ -706,7 +706,7 @@ void::function::do_ld_u:unsigned32 *rDest, unsigned32 Base, unsigned32 *rBase, i
|
||||||
|
|
||||||
|
|
||||||
// lmo
|
// lmo
|
||||||
31.Dest,26.Source,21.111111000,12.0,11./::::lmo
|
31.Dest,26.Source,21.0b111111000,12.0,11./::::lmo
|
||||||
int b;
|
int b;
|
||||||
for (b = 0; b < 32; b++)
|
for (b = 0; b < 32; b++)
|
||||||
if (rSource & BIT32 (31 - 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 */
|
/* form the end mask */
|
||||||
if (EndMask == 0)
|
if (EndMask == 0)
|
||||||
endmask = -1;
|
endmask = ~ (unsigned32)0;
|
||||||
else
|
else
|
||||||
endmask = (1 << EndMask) - 1;
|
endmask = (1 << EndMask) - 1;
|
||||||
if (i)
|
if (i)
|
||||||
|
@ -829,7 +829,7 @@ void::function::do_shift:int Dest, int Source, int Merge, int i, int n, int EndM
|
||||||
switch (Merge)
|
switch (Merge)
|
||||||
{
|
{
|
||||||
case 0: case 1: case 2:
|
case 0: case 1: case 2:
|
||||||
shiftmask = -1; /* disabled */
|
shiftmask = ~ (unsigned32)0; /* disabled */
|
||||||
break;
|
break;
|
||||||
case 3: case 4: case 5:
|
case 3: case 4: case 5:
|
||||||
shiftmask = ((1 << nRotate) - 1); /* enabled */
|
shiftmask = ((1 << nRotate) - 1); /* enabled */
|
||||||
|
@ -870,22 +870,11 @@ void::function::do_shift:int Dest, int Source, int Merge, int i, int n, int EndM
|
||||||
cia.ip, Source);
|
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
|
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);
|
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
|
31.Dest,26.Source,21.0b110001,15.Merge,12.0,11.i,10.n,9.EndMask,4.RotReg::::sl r
|
||||||
int endmask;
|
do_shift (_SD, Dest, Source, Merge, i, n, EndMask, GPR (RotReg) & 31);
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
// sli.{d|e|i}{m|s|z} - see shift
|
// sli.{d|e|i}{m|s|z} - see shift
|
||||||
|
@ -959,12 +948,12 @@ void::function::do_sub:signed32 *rDest, signed32 Source1, signed32 Source2
|
||||||
|
|
||||||
|
|
||||||
// subu
|
// 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;
|
unsigned32 result = Source1 - Source2;
|
||||||
TRACE_ALU3 (MY_INDEX, result, Source1, Source2);
|
TRACE_ALU3 (MY_INDEX, result, Source1, Source2);
|
||||||
*rDest = result;
|
*rDest = result;
|
||||||
// NOTE - the book has 15.1 which conflicts with subu.
|
// 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);
|
do_subu (_SD, rDest, vSource1, rSource2);
|
||||||
31.Dest,26.Source2,21.0b11101101,13.1,12.0,11./,4.Source1::::subu r
|
31.Dest,26.Source2,21.0b11101101,13.1,12.0,11./,4.Source1::::subu r
|
||||||
do_subu (_SD, rDest, rSource1, rSource2);
|
do_subu (_SD, rDest, rSource1, rSource2);
|
||||||
|
|
|
@ -168,7 +168,57 @@ tic80_trace_alu2 (int indx,
|
||||||
sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld %*s => 0x%.*lx/%*ld",
|
sprintf (tic80_trace_buffer, "%-*s 0x%.*lx/%*ld %*s => 0x%.*lx/%*ld",
|
||||||
tic80_size_name, itable[indx].name,
|
tic80_size_name, itable[indx].name,
|
||||||
SIZE_HEX, input, SIZE_DECIMAL, (long)(signed32)input,
|
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);
|
SIZE_HEX, result, SIZE_DECIMAL, (long)(signed32)result);
|
||||||
|
|
||||||
return tic80_trace_buffer;
|
return tic80_trace_buffer;
|
||||||
|
|
Loading…
Reference in a new issue