aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
authorMartin Hunt <hunt@redhat.com>1996-08-27 01:32:48 +0000
committerMartin Hunt <hunt@redhat.com>1996-08-27 01:32:48 +0000
commit4f425a32032b0a61bed1994afaacbb3cbd82f544 (patch)
treec321f9782c0cd6b8844b48f1764c1f19a276b0f2 /sim
parent67f0d0ea4ce159e13786d6cdd4990754e702eb82 (diff)
downloadgdb-4f425a32032b0a61bed1994afaacbb3cbd82f544.zip
gdb-4f425a32032b0a61bed1994afaacbb3cbd82f544.tar.gz
gdb-4f425a32032b0a61bed1994afaacbb3cbd82f544.tar.bz2
Mon Aug 26 18:30:28 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
* d10v_sim.h (SEXT32): Added. * interp.c: Commented out printfs. * simops.c: Fixed error in sb and st2w.
Diffstat (limited to 'sim')
-rw-r--r--sim/d10v/d10v_sim.h9
-rw-r--r--sim/d10v/simops.c350
2 files changed, 275 insertions, 84 deletions
diff --git a/sim/d10v/d10v_sim.h b/sim/d10v/d10v_sim.h
index cc81d6a..a2b4b2b 100644
--- a/sim/d10v/d10v_sim.h
+++ b/sim/d10v/d10v_sim.h
@@ -31,7 +31,7 @@ struct simops
struct _state
{
reg_t regs[16]; /* general-purpose registers */
- reg_t cregs[15]; /* control registers */
+ reg_t cregs[16]; /* control registers */
int64 a[2]; /* accumulators */
uint8 SM;
uint8 EA;
@@ -47,6 +47,7 @@ struct _state
uint8 exe;
uint8 *imem;
uint8 *dmem;
+ int exception;
} State;
extern uint16 OP[4];
@@ -74,6 +75,9 @@ extern struct simops Simops[];
/* sign-extend a 16-bit number */
#define SEXT16(x) ((((x)&0xffff)^(~0x7fff))+0x8000)
+/* sign-extend a 32-bit number */
+#define SEXT32(x) ((((x)&0xffffffffLL)^(~0x7fffffffLL))+0x80000000LL)
+
/* sign extend a 40 bit number */
#define SEXT40(x) ((((x)&0xffffffffffLL)^(~0x7fffffffffLL))+0x8000000000LL)
@@ -82,6 +86,8 @@ extern struct simops Simops[];
#define MASK32 0xffffffffLL
#define MASK40 0xffffffffffLL
+#define INC_ADDR(x,i) x = ((State.MD && x == MOD_E) ? MOD_S : (x)+(i))
+
#define RB(x) (*((uint8 *)((x)+State.imem)))
#define SB(addr,data) ( RB(addr) = (data & 0xff))
@@ -96,7 +102,6 @@ extern struct simops Simops[];
uint32 get_longword_swap PARAMS ((uint16 x));
uint16 get_word_swap PARAMS ((uint16 x));
void write_word_swap PARAMS ((uint16 addr, uint16 data));
-
#define SW(addr,data) write_word_swap(addr,data)
#define RW(x) get_word_swap(x)
#define RLW(x) get_longword_swap(x)
diff --git a/sim/d10v/simops.c b/sim/d10v/simops.c
index 071a7ce..1081639 100644
--- a/sim/d10v/simops.c
+++ b/sim/d10v/simops.c
@@ -1,3 +1,4 @@
+#include <signal.h>
#include "d10v_sim.h"
#include "simops.h"
@@ -29,7 +30,9 @@ OP_5607 ()
#ifdef DEBUG
printf(" abs\ta%d\n",OP[0]);
#endif
- State.F1 = State.F0;
+ State.F1 = State.F0;
+ State.a[OP[0]] = SEXT40(State.a[OP[0]]);
+
if (State.a[OP[0]] < 0 )
{
tmp = -State.a[OP[0]];
@@ -40,10 +43,10 @@ OP_5607 ()
else if (tmp < MIN32)
State.a[OP[0]] = MIN32;
else
- State.a[OP[0]] = tmp;
+ State.a[OP[0]] = tmp & MASK40;
}
else
- State.a[OP[0]] = tmp;
+ State.a[OP[0]] = tmp & MASK40;
State.F0 = 1;
}
else
@@ -73,7 +76,7 @@ OP_1201 ()
#ifdef DEBUG
printf(" add\ta%d,r%d\n",OP[0],OP[1]);
#endif
- tmp = State.a[OP[0]] + (SEXT16 (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1]);
+ tmp = SEXT40(State.a[OP[0]]) + (SEXT16 (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1]);
if (State.ST)
{
if ( tmp > MAX32)
@@ -81,10 +84,10 @@ OP_1201 ()
else if ( tmp < MIN32)
State.a[OP[0]] = MIN32;
else
- State.a[OP[0]] = tmp;
+ State.a[OP[0]] = tmp & MASK40;
}
else
- State.a[OP[0]] = tmp;
+ State.a[OP[0]] = tmp & MASK40;
}
/* add */
@@ -95,7 +98,7 @@ OP_1203 ()
#ifdef DEBUG
printf(" add\ta%d,a%d\n",OP[0],OP[1]);
#endif
- tmp = State.a[OP[0]] + State.a[OP[1]];
+ tmp = SEXT40(State.a[OP[0]]) + SEXT40(State.a[OP[1]]);
if (State.ST)
{
if (tmp > MAX32)
@@ -103,10 +106,10 @@ OP_1203 ()
else if ( tmp < MIN32)
State.a[OP[0]] = MIN32;
else
- State.a[OP[0]] = tmp;
+ State.a[OP[0]] = tmp & MASK40;
}
else
- State.a[OP[0]] = tmp;
+ State.a[OP[0]] = tmp & MASK40;
}
/* add2w */
@@ -151,7 +154,7 @@ OP_17000200 ()
#ifdef DEBUG
printf(" addac3\tr%d,r%d,a%d\n",OP[0],OP[1],OP[2]);
#endif
- tmp = State.a[OP[2]] + (SEXT16 (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1]);
+ tmp = SEXT40(State.a[OP[2]]) + SEXT40 ((State.regs[OP[1]] << 16) | State.regs[OP[1]+1]);
State.regs[OP[0]] = (tmp >> 16) & 0xffff;
State.regs[OP[0]+1] = tmp & 0xffff;
}
@@ -164,7 +167,7 @@ OP_17000202 ()
#ifdef DEBUG
printf(" addac3\tr%d,a%d,a%d\n",OP[0],OP[1],OP[2]);
#endif
- tmp = State.a[OP[1]] + State.a[OP[2]];
+ tmp = SEXT40(State.a[OP[1]]) + SEXT40(State.a[OP[2]]);
State.regs[OP[0]] = (tmp >> 16) & 0xffff;
State.regs[OP[0]+1] = tmp & 0xffff;
}
@@ -178,7 +181,7 @@ OP_17001200 ()
printf(" addac3s\tr%d,r%d,a%d\n",OP[0],OP[1],OP[2]);
#endif
State.F1 = State.F0;
- tmp = State.a[OP[2]] + (SEXT16 (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1]);
+ tmp = SEXT40(State.a[OP[2]]) + SEXT40 ((State.regs[OP[1]] << 16) | State.regs[OP[1]+1]);
if ( tmp > MAX32)
{
State.regs[OP[0]] = 0x7fff;
@@ -208,7 +211,7 @@ OP_17001202 ()
printf(" addac3s\tr%d,a%d,a%d\n",OP[0],OP[1],OP[2]);
#endif
State.F1 = State.F0;
- tmp = State.a[OP[1]] + State.a[OP[2]];
+ tmp = SEXT40(State.a[OP[1]]) + SEXT40(State.a[OP[2]]);
if ( tmp > MAX32)
{
State.regs[OP[0]] = 0x7fff;
@@ -233,6 +236,8 @@ OP_17001202 ()
void
OP_201 ()
{
+ if (OP[1] == 0)
+ OP[1] = 16;
#ifdef DEBUG
printf(" addi\tr%d,0x%x\n",OP[0],OP[1]);
#endif
@@ -415,7 +420,7 @@ OP_1603 ()
printf(" cmp\ta%d,a%d\n",OP[0],OP[1]);
#endif
State.F1 = State.F0;
- State.F0 = (State.a[OP[0]] < State.a[OP[1]]) ? 1 : 0;
+ State.F0 = (SEXT40(State.a[OP[0]]) < SEXT40(State.a[OP[1]])) ? 1 : 0;
}
/* cmpeq */
@@ -534,7 +539,8 @@ OP_4E09 ()
void
OP_5F20 ()
{
- printf(" dbt - NOT IMPLEMENTED\n");
+ printf("***** DBT ***** PC=%x\n",PC);
+ State.exception = SIGTRAP;
}
/* divs */
@@ -669,7 +675,7 @@ OP_15002A02 ()
#ifdef DEBUG
printf(" exp\tr%d,a%d\n",OP[0],OP[1]);
#endif
- if (State.a[OP[1]] >= 0)
+ if (SEXT40(State.a[OP[1]]) >= 0)
tmp = State.a[OP[1]];
else
tmp = ~(State.a[OP[1]]);
@@ -726,7 +732,7 @@ OP_6401 ()
printf(" ld\tr%d,@r%d-\n",OP[0],OP[1]);
#endif
State.regs[OP[0]] = RW (State.regs[OP[1]]);
- State.regs[OP[1]] -= 2;
+ INC_ADDR(State.regs[OP[1]],-2);
}
/* ld */
@@ -737,7 +743,7 @@ OP_6001 ()
printf(" ld\tr%d,@r%d+\n",OP[0],OP[1]);
#endif
State.regs[OP[0]] = RW (State.regs[OP[1]]);
- State.regs[OP[1]] += 2;
+ INC_ADDR(State.regs[OP[1]],2);
}
/* ld */
@@ -770,7 +776,7 @@ OP_6601 ()
#endif
State.regs[OP[0]] = RW (State.regs[OP[1]]);
State.regs[OP[0]+1] = RW (State.regs[OP[1]]+2);
- State.regs[OP[1]] -= 4;
+ INC_ADDR(State.regs[OP[1]],-4);
}
/* ld2w */
@@ -782,7 +788,7 @@ OP_6201 ()
#endif
State.regs[OP[0]] = RW (State.regs[OP[1]]);
State.regs[OP[0]+1] = RW (State.regs[OP[1]]+2);
- State.regs[OP[1]] += 4;
+ INC_ADDR(State.regs[OP[1]],4);
}
/* ld2w */
@@ -866,15 +872,15 @@ OP_2A00 ()
#ifdef DEBUG
printf(" mac\ta%d,r%d,r%d\n",OP[0],OP[1],OP[2]);
#endif
- tmp = (int16)(State.regs[OP[1]]) * (int16)(State.regs[OP[2]]);
+ tmp = SEXT40 ((int16)(State.regs[OP[1]]) * (int16)(State.regs[OP[2]]));
if (State.FX)
- tmp <<= 1;
+ tmp = SEXT40( (tmp << 1) & MASK40);
if (State.ST && tmp > MAX32)
tmp = MAX32;
- tmp += State.a[OP[0]];
+ tmp += SEXT40(State.a[OP[0]]);
if (State.ST)
{
if (tmp > MAX32)
@@ -882,28 +888,39 @@ OP_2A00 ()
else if (tmp < MIN32)
State.a[OP[0]] = MIN32;
else
- State.a[OP[0]] = tmp;
+ State.a[OP[0]] = tmp & MASK40;
}
else
- State.a[OP[0]] = tmp;
+ State.a[OP[0]] = tmp & MASK40;
}
/* macsu */
void
OP_1A00 ()
{
+ int64 tmp;
#ifdef DEBUG
-printf(" macsu\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+ printf(" macsu\ta%d,r%d,r%d\n",OP[0],OP[1],OP[2]);
#endif
+ tmp = SEXT40 ((int16)State.regs[OP[1]] * State.regs[OP[2]]);
+ if (State.FX)
+ tmp = SEXT40( (tmp << 1) & MASK40);
+
+ State.a[OP[0]] = (SEXT40 (State.a[OP[0]]) + tmp) & MASK40;
}
/* macu */
void
OP_3A00 ()
{
+ int64 tmp;
#ifdef DEBUG
-printf(" macu\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+ printf(" macu\ta%d,r%d,r%d\n",OP[0],OP[1],OP[2]);
#endif
+ tmp = SEXT40 (State.regs[OP[1]] * State.regs[OP[2]]);
+ if (State.FX)
+ tmp = SEXT40( (tmp << 1) & MASK40);
+ State.a[OP[0]] = (SEXT40 (State.a[OP[0]]) + tmp) & MASK40;
}
/* max */
@@ -927,9 +944,19 @@ OP_2600 ()
void
OP_3600 ()
{
+ int64 tmp;
#ifdef DEBUG
-printf(" max\t%x,%x\n",OP[0],OP[1]);
+ printf(" max\ta%d,r%d\n",OP[0],OP[1]);
#endif
+ State.F1 = State.F0;
+ tmp = SEXT16 (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1];
+ if (tmp > SEXT40(State.a[OP[0]]))
+ {
+ State.a[OP[0]] = tmp & MASK40;
+ State.F0 = 1;
+ }
+ else
+ State.F0 = 0;
}
/* max */
@@ -937,10 +964,19 @@ void
OP_3602 ()
{
#ifdef DEBUG
-printf(" max\t%x,%x\n",OP[0],OP[1]);
+ printf(" max\ta%d,a%d\n",OP[0],OP[1]);
#endif
+ State.F1 = State.F0;
+ if (SEXT40(State.a[OP[1]]) > SEXT40(State.a[OP[0]]))
+ {
+ State.a[OP[0]] = State.a[OP[1]];
+ State.F0 = 1;
+ }
+ else
+ State.F0 = 0;
}
+
/* min */
void
OP_2601 ()
@@ -962,9 +998,19 @@ OP_2601 ()
void
OP_3601 ()
{
+ int64 tmp;
#ifdef DEBUG
-printf(" min\t%x,%x\n",OP[0],OP[1]);
+ printf(" min\ta%d,r%d\n",OP[0],OP[1]);
#endif
+ State.F1 = State.F0;
+ tmp = SEXT16 (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1];
+ if (tmp < SEXT40(State.a[OP[0]]))
+ {
+ State.a[OP[0]] = tmp & MASK40;
+ State.F0 = 1;
+ }
+ else
+ State.F0 = 0;
}
/* min */
@@ -972,35 +1018,76 @@ void
OP_3603 ()
{
#ifdef DEBUG
-printf(" min\t%x,%x\n",OP[0],OP[1]);
+ printf(" min\ta%d,a%d\n",OP[0],OP[1]);
#endif
+ State.F1 = State.F0;
+ if (SEXT40(State.a[OP[1]]) < SEXT40(State.a[OP[0]]))
+ {
+ State.a[OP[0]] = State.a[OP[1]];
+ State.F0 = 1;
+ }
+ else
+ State.F0 = 0;
}
/* msb */
void
OP_2800 ()
{
+ int64 tmp;
#ifdef DEBUG
-printf(" msb\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+ printf(" msb\ta%d,r%d,r%d\n",OP[0],OP[1],OP[2]);
#endif
+ tmp = SEXT40 ((int16)(State.regs[OP[1]]) * (int16)(State.regs[OP[2]]));
+
+ if (State.FX)
+ tmp = SEXT40 ((tmp << 1) & MASK40);
+
+ if (State.ST && tmp > MAX32)
+ tmp = MAX32;
+
+ tmp = SEXT40(State.a[OP[0]]) - tmp;
+ if (State.ST)
+ {
+ if (tmp > MAX32)
+ State.a[OP[0]] = MAX32;
+ else if (tmp < MIN32)
+ State.a[OP[0]] = MIN32;
+ else
+ State.a[OP[0]] = tmp & MASK40;
+ }
+ else
+ State.a[OP[0]] = tmp & MASK40;
}
/* msbsu */
void
OP_1800 ()
{
+ int64 tmp;
#ifdef DEBUG
-printf(" msbsu\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+ printf(" msbsu\ta%d,r%d,r%d\n",OP[0],OP[1],OP[2]);
#endif
+ tmp = SEXT40 ((int16)State.regs[OP[1]] * State.regs[OP[2]]);
+ if (State.FX)
+ tmp = SEXT40( (tmp << 1) & MASK40);
+
+ State.a[OP[0]] = (SEXT40 (State.a[OP[0]]) - tmp) & MASK40;
}
/* msbu */
void
OP_3800 ()
{
+ int64 tmp;
#ifdef DEBUG
-printf(" msbu\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+ printf(" msbu\ta%d,r%d,r%d\n",OP[0],OP[1],OP[2]);
#endif
+ tmp = SEXT40 (State.regs[OP[1]] * State.regs[OP[2]]);
+ if (State.FX)
+ tmp = SEXT40( (tmp << 1) & MASK40);
+
+ State.a[OP[0]] = (SEXT40 (State.a[OP[0]]) - tmp) & MASK40;
}
/* mul */
@@ -1017,27 +1104,51 @@ OP_2E00 ()
void
OP_2C00 ()
{
+ int64 tmp;
#ifdef DEBUG
-printf(" mulx\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+ printf(" mulx\ta%d,r%d,r%d\n",OP[0],OP[1],OP[2]);
#endif
+ tmp = SEXT40 ((int16)(State.regs[OP[1]]) * (int16)(State.regs[OP[2]]));
+
+ if (State.FX)
+ tmp = SEXT40 ((tmp << 1) & MASK40);
+
+ if (State.ST && tmp > MAX32)
+ State.a[OP[0]] = MAX32;
+ else
+ State.a[OP[0]] = tmp & MASK40;
}
/* mulxsu */
void
OP_1C00 ()
{
+ int64 tmp;
#ifdef DEBUG
-printf(" mulxsu\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+ printf(" mulxsu\ta%d,r%d,r%d\n",OP[0],OP[1],OP[2]);
#endif
+ tmp = SEXT40 ((int16)(State.regs[OP[1]]) * State.regs[OP[2]]);
+
+ if (State.FX)
+ tmp <<= 1;
+
+ State.a[OP[0]] = tmp & MASK40;
}
/* mulxu */
void
OP_3C00 ()
{
+ int64 tmp;
#ifdef DEBUG
-printf(" mulxu\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+ printf(" mulxu\ta%d,r%d,r%d\n",OP[0],OP[1],OP[2]);
#endif
+ tmp = SEXT40 (State.regs[OP[1]] * State.regs[OP[2]]);
+
+ if (State.FX)
+ tmp <<= 1;
+
+ State.a[OP[0]] = tmp & MASK40;
}
/* mv */
@@ -1079,7 +1190,7 @@ OP_3E01 ()
#ifdef DEBUG
printf(" mv2wtac\tr%d,a%d\n",OP[0],OP[1]);
#endif
- State.a[OP[1]] = SEXT16 (State.regs[OP[0]]) << 16 | State.regs[OP[0]+1];
+ State.a[OP[1]] = (SEXT16 (State.regs[OP[0]]) << 16 | State.regs[OP[0]+1]) & MASK40;
}
/* mvac */
@@ -1200,8 +1311,7 @@ OP_1E01 ()
printf(" mvtachi\tr%d,a%d\n",OP[0],OP[1]);
#endif
tmp = State.a[OP[1]] & 0xffff;
- State.a[OP[1]] = SEXT16 (State.regs[OP[0]]) << 16 | tmp;
- printf("put 0x%llx\n",State.a[OP[1]]);
+ State.a[OP[1]] = (SEXT16 (State.regs[OP[0]]) << 16 | tmp) & MASK40;
}
/* mvtaclo */
@@ -1211,7 +1321,7 @@ OP_1E21 ()
#ifdef DEBUG
printf(" mvtaclo\tr%d,a%d\n",OP[0],OP[1]);
#endif
- State.a[OP[1]] = SEXT16 (State.regs[OP[0]]);
+ State.a[OP[1]] = (SEXT16 (State.regs[OP[0]])) & MASK40;
}
/* mvtc */
@@ -1239,7 +1349,7 @@ OP_5600 ()
if (State.ST && !State.FX)
{
fprintf (stderr,"ERROR at PC 0x%x: ST can only be set when FX is set.\n",PC<<2);
- exit (1);
+ State.exception = SIGILL;
}
}
}
@@ -1272,7 +1382,7 @@ OP_5605 ()
#ifdef DEBUG
printf(" neg\ta%d\n",OP[0]);
#endif
- tmp = -State.a[OP[0]];
+ tmp = -SEXT40(State.a[OP[0]]);
if (State.ST)
{
if ( tmp > MAX32)
@@ -1280,10 +1390,10 @@ OP_5605 ()
else if (tmp < MIN32)
State.a[OP[0]] = MIN32;
else
- State.a[OP[0]] = tmp;
+ State.a[OP[0]] = tmp & MASK40;
}
else
- State.a[OP[0]] = tmp;
+ State.a[OP[0]] = tmp & MASK40;
}
@@ -1405,12 +1515,12 @@ OP_27000000 ()
if (RPT_C == 0)
{
fprintf (stderr, "ERROR: rep with count=0 is illegal.\n");
- exit(1);
+ State.exception = SIGILL;
}
if (OP[1] < 4)
{
fprintf (stderr, "ERROR: rep must include at least 4 instructions.\n");
- exit(1);
+ State.exception = SIGILL;
}
}
@@ -1428,12 +1538,12 @@ OP_2F000000 ()
if (RPT_C == 0)
{
fprintf (stderr, "ERROR: repi with count=0 is illegal.\n");
- exit(1);
+ State.exception = SIGILL;
}
if (OP[1] < 4)
{
fprintf (stderr, "ERROR: repi must include at least 4 instructions.\n");
- exit(1);
+ State.exception = SIGILL;
}
}
@@ -1463,7 +1573,7 @@ OP_1223 ()
#ifdef DEBUG
printf(" sadd\ta%d,a%d\n",OP[0],OP[1]);
#endif
- tmp = State.a[OP[0]] + (State.a[OP[1]] >> 16);
+ tmp = SEXT40(State.a[OP[0]]) + (SEXT40(State.a[OP[1]]) >> 16);
if (State.ST)
{
if (tmp > MAX32)
@@ -1471,10 +1581,10 @@ OP_1223 ()
else if (tmp < MIN32)
State.a[OP[0]] = MIN32;
else
- State.a[OP[0]] = tmp;
+ State.a[OP[0]] = tmp & MASK40;
}
else
- State.a[OP[0]] = tmp;
+ State.a[OP[0]] = tmp & MASK40;
}
/* setf0f */
@@ -1556,13 +1666,14 @@ void
OP_3201 ()
{
int64 tmp;
+
+ if (OP[1] == 0)
+ OP[1] = 16;
#ifdef DEBUG
printf(" slli\ta%d,%d\n",OP[0],OP[1]);
#endif
- if (OP[1] == 0)
- tmp = SEXT40(State.a[OP[0]]) << 16;
- else
- tmp = SEXT40(State.a[OP[0]]) << OP[2];
+
+ tmp = SEXT40(State.a[OP[0]]) << OP[1];
if (State.ST)
{
@@ -1623,12 +1734,11 @@ OP_2401 ()
void
OP_3401 ()
{
+ if (OP[1] == 0)
+ OP[1] = 16;
#ifdef DEBUG
printf(" srai\ta%d,%d\n",OP[0],OP[1]);
#endif
- if (OP[1] == 0)
- State.a[OP[0]] >>= 16;
- else
State.a[OP[0]] >>= OP[1];
}
@@ -1667,12 +1777,11 @@ printf(" srli\tr%d,%d\n",OP[0],OP[1]);
void
OP_3001 ()
{
+ if (OP[1] == 0)
+ OP[1] = 16;
#ifdef DEBUG
printf(" srli\ta%d,%d\n",OP[0],OP[1]);
#endif
- if (OP[1] == 0)
- State.a[OP[0]] >>= 16;
- else
State.a[OP[0]] >>= OP[1];
}
@@ -1718,7 +1827,8 @@ OP_6C1F ()
if ( OP[1] != 15 )
{
fprintf (stderr,"ERROR: cannot pre-decrement any registers but r15 (SP).\n");
- exit(1);
+ State.exception = SIGILL;
+ return;
}
State.regs[OP[1]] -= 2;
SW (State.regs[OP[1]], State.regs[OP[0]]);
@@ -1732,7 +1842,7 @@ OP_6801 ()
printf(" st\tr%d,@r%d+\n",OP[0],OP[1]);
#endif
SW (State.regs[OP[1]], State.regs[OP[0]]);
- State.regs[OP[1]] += 2;
+ INC_ADDR (State.regs[OP[1]],2);
}
/* st */
@@ -1743,7 +1853,7 @@ OP_6C01 ()
printf(" st\tr%d,@r%d-\n",OP[0],OP[1]);
#endif
SW (State.regs[OP[1]], State.regs[OP[0]]);
- State.regs[OP[1]] -= 2;
+ INC_ADDR (State.regs[OP[1]],-2);
}
/* st2w */
@@ -1753,8 +1863,8 @@ OP_35000000 ()
#ifdef DEBUG
printf(" st2w\tr%d,@(0x%x,r%d)\n",OP[0],OP[1],OP[2]);
#endif
- SW (State.regs[OP[1]]+OP[2], State.regs[OP[0]]);
- SW (State.regs[OP[1]]+OP[2]+2, State.regs[OP[0]+1]);
+ SW (State.regs[OP[2]]+OP[1], State.regs[OP[0]]);
+ SW (State.regs[OP[2]]+OP[1]+2, State.regs[OP[0]+1]);
}
/* st2w */
@@ -1778,7 +1888,8 @@ OP_6E1F ()
if ( OP[1] != 15 )
{
fprintf (stderr,"ERROR: cannot pre-decrement any registers but r15 (SP).\n");
- exit(1);
+ State.exception = SIGILL;
+ return;
}
State.regs[OP[1]] -= 4;
SW (State.regs[OP[1]], State.regs[OP[0]]);
@@ -1794,7 +1905,7 @@ OP_6A01 ()
#endif
SW (State.regs[OP[1]], State.regs[OP[0]]);
SW (State.regs[OP[1]]+2, State.regs[OP[0]+1]);
- State.regs[OP[1]] += 4;
+ INC_ADDR (State.regs[OP[1]],4);
}
/* st2w */
@@ -1806,7 +1917,7 @@ OP_6E01 ()
#endif
SW (State.regs[OP[1]], State.regs[OP[0]]);
SW (State.regs[OP[1]]+2, State.regs[OP[0]+1]);
- State.regs[OP[1]] -= 4;
+ INC_ADDR (State.regs[OP[1]],-4);
}
/* stb */
@@ -1816,7 +1927,7 @@ OP_3C000000 ()
#ifdef DEBUG
printf(" stb\tr%d,@(0x%x,r%d)\n",OP[0],OP[1],OP[2]);
#endif
- SB (State.regs[OP[1]]+OP[2], State.regs[OP[0]]);
+ SB (State.regs[OP[2]]+OP[1], State.regs[OP[0]]);
}
/* stb */
@@ -1836,7 +1947,7 @@ OP_5FE0 ()
#ifdef DEBUG
printf(" stop\n");
#endif
- exit(1);
+ State.exception = SIGQUIT;
}
/* sub */
@@ -1856,9 +1967,22 @@ OP_0 ()
void
OP_1001 ()
{
+ int64 tmp;
#ifdef DEBUG
printf(" sub\ta%d,r%d\n",OP[0],OP[1]);
#endif
+ tmp = SEXT40(State.a[OP[0]]) - (SEXT16 (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1]);
+ if (State.ST)
+ {
+ if ( tmp > MAX32)
+ State.a[OP[0]] = MAX32;
+ else if ( tmp < MIN32)
+ State.a[OP[0]] = MIN32;
+ else
+ State.a[OP[0]] = tmp & MASK40;
+ }
+ else
+ State.a[OP[0]] = tmp & MASK40;
}
/* sub */
@@ -1866,10 +1990,22 @@ OP_1001 ()
void
OP_1003 ()
{
+ int64 tmp;
#ifdef DEBUG
printf(" sub\ta%d,a%d\n",OP[0],OP[1]);
#endif
-
+ tmp = SEXT40(State.a[OP[0]]) - SEXT40(State.a[OP[1]]);
+ if (State.ST)
+ {
+ if (tmp > MAX32)
+ State.a[OP[0]] = MAX32;
+ else if ( tmp < MIN32)
+ State.a[OP[0]] = MIN32;
+ else
+ State.a[OP[0]] = tmp & MASK40;
+ }
+ else
+ State.a[OP[0]] = tmp & MASK40;
}
/* sub2w */
@@ -1894,36 +2030,86 @@ OP_1000 ()
void
OP_17000000 ()
{
+ int64 tmp;
#ifdef DEBUG
-printf(" subac3\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+ printf(" subac3\tr%d,r%d,a%d\n",OP[0],OP[1],OP[2]);
#endif
+ tmp = SEXT40 ((State.regs[OP[1]] << 16) | State.regs[OP[1]+1]) - SEXT40 (State.a[OP[2]]);
+ State.regs[OP[0]] = (tmp >> 16) & 0xffff;
+ State.regs[OP[0]+1] = tmp & 0xffff;
}
/* subac3 */
void
OP_17000002 ()
{
+ int64 tmp;
#ifdef DEBUG
-printf(" subac3\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+ printf(" subac3\tr%d,a%d,a%d\n",OP[0],OP[1],OP[2]);
#endif
+ tmp = SEXT40(State.a[OP[1]]) - SEXT40(State.a[OP[2]]);
+ State.regs[OP[0]] = (tmp >> 16) & 0xffff;
+ State.regs[OP[0]+1] = tmp & 0xffff;
}
/* subac3s */
void
OP_17001000 ()
{
+ int64 tmp;
#ifdef DEBUG
-printf(" subac3s\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+ printf(" subac3s\tr%d,r%d,a%d\n",OP[0],OP[1],OP[2]);
#endif
+ State.F1 = State.F0;
+ tmp = SEXT40 ((State.regs[OP[1]] << 16) | State.regs[OP[1]+1]) - SEXT40(State.a[OP[2]]);
+ if ( tmp > MAX32)
+ {
+ State.regs[OP[0]] = 0x7fff;
+ State.regs[OP[0]+1] = 0xffff;
+ State.F0 = 1;
+ }
+ else if (tmp < MIN32)
+ {
+ State.regs[OP[0]] = 0x8000;
+ State.regs[OP[0]+1] = 0;
+ State.F0 = 1;
+ }
+ else
+ {
+ State.regs[OP[0]] = (tmp >> 16) & 0xffff;
+ State.regs[OP[0]+1] = tmp & 0xffff;
+ State.F0 = 0;
+ }
}
/* subac3s */
void
OP_17001002 ()
{
+ int64 tmp;
#ifdef DEBUG
-printf(" subac3s\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+ printf(" subac3s\tr%d,a%d,a%d\n",OP[0],OP[1],OP[2]);
#endif
+ State.F1 = State.F0;
+ tmp = SEXT40(State.a[OP[1]]) - SEXT40(State.a[OP[2]]);
+ if ( tmp > MAX32)
+ {
+ State.regs[OP[0]] = 0x7fff;
+ State.regs[OP[0]+1] = 0xffff;
+ State.F0 = 1;
+ }
+ else if (tmp < MIN32)
+ {
+ State.regs[OP[0]] = 0x8000;
+ State.regs[OP[0]+1] = 0;
+ State.F0 = 1;
+ }
+ else
+ {
+ State.regs[OP[0]] = (tmp >> 16) & 0xffff;
+ State.regs[OP[0]+1] = tmp & 0xffff;
+ State.F0 = 0;
+ }
}
/* subi */
@@ -1931,11 +2117,11 @@ void
OP_1 ()
{
int32 tmp;
+ if (OP[1] == 0)
+ OP[1] = 16;
#ifdef DEBUG
printf(" subi\tr%d,%d\n",OP[0],OP[1]);
#endif
- if (OP[1] == 0)
- OP[1] = 16;
tmp = (int16)State.regs[OP[0]] - OP[1];
State.C = (tmp & 0xffff0000) ? 1 : 0;
State.regs[OP[0]] = tmp & 0xffff;
@@ -1949,7 +2135,7 @@ OP_5F00 ()
printf(" trap\t%d\n",OP[0]);
#endif
- /* for now, trap 0 is used for simulating IO */
+ /* for now, trap is used for simulating IO */
if (OP[0] == 0)
{
@@ -1971,7 +2157,7 @@ OP_7000000 ()
printf(" tst0i\tr%d,0x%x\n",OP[0],OP[1]);
#endif
State.F1 = State.F0;
- State.F0 = (State.regs[OP[0]] & OP[2]) ? 1 : 0;
+ State.F0 = (State.regs[OP[0]] & OP[1]) ? 1 : 0;
}
/* tst1i */
@@ -1982,7 +2168,7 @@ OP_F000000 ()
printf(" tst1i\tr%d,0x%x\n",OP[0],OP[1]);
#endif
State.F1 = State.F0;
- State.F0 = (~(State.regs[OP[0]]) & OP[2]) ? 1 : 0;
+ State.F0 = (~(State.regs[OP[0]]) & OP[1]) ? 1 : 0;
}
/* wait */