aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>1997-03-20 19:02:44 +0000
committerJeff Law <law@redhat.com>1997-03-20 19:02:44 +0000
commit65b784d8a5fca993bea9d5eb513282d47e1d1d13 (patch)
treeab20fa0eb6bae18fd0e9cc0bfc9f06d221240acd /sim
parent29bc322d8de5760d690d79a93a9a66f42a9d0ca0 (diff)
downloadgdb-65b784d8a5fca993bea9d5eb513282d47e1d1d13.zip
gdb-65b784d8a5fca993bea9d5eb513282d47e1d1d13.tar.gz
gdb-65b784d8a5fca993bea9d5eb513282d47e1d1d13.tar.bz2
* simops.c: Fix register extraction for a two "movbu" variants.
Somewhat simplify "sub" instructions. Correctly sign extend operands for "mul". Put the correct half of the result in MDR for "mul" and "mulu". Implement remaining instructions. Tweak opcode for "syscall".
Diffstat (limited to 'sim')
-rw-r--r--sim/mn10300/simops.c105
1 files changed, 75 insertions, 30 deletions
diff --git a/sim/mn10300/simops.c b/sim/mn10300/simops.c
index 550d3e1..de9241e 100644
--- a/sim/mn10300/simops.c
+++ b/sim/mn10300/simops.c
@@ -623,7 +623,7 @@ void OP_FA920000 (insn, extension)
unsigned long insn, extension;
{
store_mem (State.regs[REG_SP] + (insn & 0xffff), 2,
- State.regs[REG_D0 + REG1_8 (insn)]);
+ State.regs[REG_D0 + REG1_16 (insn)]);
}
/* movbu dm (d32,sp) */
@@ -631,7 +631,7 @@ void OP_FC920000 (insn, extension)
unsigned long insn, extension;
{
store_mem (State.regs[REG_SP] + (((insn & 0xffff) << 16) + extension), 2,
- State.regs[REG_D0 + REG1_8 (insn)]);
+ State.regs[REG_D0 + REG1_16 (insn)]);
}
/* movbu dm, (di,an) */
@@ -1282,6 +1282,7 @@ void OP_F100 (insn, extension)
reg1 = State.regs[REG_D0 + REG1 (insn)];
reg2 = State.regs[REG_D0 + REG0 (insn)];
value = reg2 - reg1;
+ State.regs[REG_D0 + REG0 (insn)] = value;
z = (value == 0);
n = (value & 0x80000000);
@@ -1292,7 +1293,6 @@ void OP_F100 (insn, extension)
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
- State.regs[REG_D0 + REG0 (insn)] = value;
}
/* sub dm, an */
@@ -1305,6 +1305,7 @@ void OP_F120 (insn, extension)
reg1 = State.regs[REG_D0 + REG1 (insn)];
reg2 = State.regs[REG_A0 + REG0 (insn)];
value = reg2 - reg1;
+ State.regs[REG_A0 + REG0 (insn)] = value;
z = (value == 0);
n = (value & 0x80000000);
@@ -1315,7 +1316,6 @@ void OP_F120 (insn, extension)
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
- State.regs[REG_A0 + REG0 (insn)] = value;
}
/* sub am, dn */
@@ -1328,6 +1328,7 @@ void OP_F110 (insn, extension)
reg1 = State.regs[REG_A0 + REG1 (insn)];
reg2 = State.regs[REG_D0 + REG0 (insn)];
value = reg2 - reg1;
+ State.regs[REG_D0 + REG0 (insn)] = value;
z = (value == 0);
n = (value & 0x80000000);
@@ -1338,7 +1339,6 @@ void OP_F110 (insn, extension)
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
- State.regs[REG_D0 + REG0 (insn)] = value;
}
/* sub am, an */
@@ -1351,6 +1351,7 @@ void OP_F130 (insn, extension)
reg1 = State.regs[REG_A0 + REG1 (insn)];
reg2 = State.regs[REG_A0 + REG0 (insn)];
value = reg2 - reg1;
+ State.regs[REG_A0 + REG0 (insn)] = value;
z = (value == 0);
n = (value & 0x80000000);
@@ -1361,7 +1362,6 @@ void OP_F130 (insn, extension)
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
- State.regs[REG_A0 + REG0 (insn)] = value;
}
/* sub imm32, dn */
@@ -1374,6 +1374,7 @@ void OP_FCC40000 (insn, extension)
reg1 = State.regs[REG_D0 + REG0_16 (insn)];
imm = ((insn & 0xffff) << 16) + extension;
value = reg1 - imm;
+ State.regs[REG_D0 + REG0_16 (insn)] = value;
z = (value == 0);
n = (value & 0x80000000);
@@ -1384,7 +1385,6 @@ void OP_FCC40000 (insn, extension)
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
- State.regs[REG_D0 + REG0_16 (insn)] = value;
}
/* sub imm32, an */
@@ -1397,6 +1397,7 @@ void OP_FCD40000 (insn, extension)
reg1 = State.regs[REG_A0 + REG0_16 (insn)];
imm = ((insn & 0xffff) << 16) + extension;
value = reg1 - imm;
+ State.regs[REG_A0 + REG0_16 (insn)] = value;
z = (value == 0);
n = (value & 0x80000000);
@@ -1407,7 +1408,6 @@ void OP_FCD40000 (insn, extension)
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
- State.regs[REG_A0 + REG0_16 (insn)] = value;
}
/* subc dm, dn */
@@ -1420,6 +1420,7 @@ void OP_F180 (insn, extension)
reg1 = State.regs[REG_D0 + REG1 (insn)];
reg2 = State.regs[REG_D0 + REG0 (insn)];
value = reg2 - reg1 - ((PSW & PSW_C) != 0);
+ State.regs[REG_D0 + REG0 (insn)] = value;
z = (value == 0);
n = (value & 0x80000000);
@@ -1430,7 +1431,6 @@ void OP_F180 (insn, extension)
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
- State.regs[REG_D0 + REG0 (insn)] = value;
}
/* mul dm, dn */
@@ -1440,10 +1440,10 @@ void OP_F240 (insn, extension)
unsigned long long temp;
int n, z;
- temp = (State.regs[REG_D0 + REG0 (insn)]
- * State.regs[REG_D0 + REG1 (insn)]);
+ temp = ((signed long)State.regs[REG_D0 + REG0 (insn)]
+ * (signed long)State.regs[REG_D0 + REG1 (insn)]);
State.regs[REG_D0 + REG0 (insn)] = temp & 0xffffffff;
- State.regs[REG_MDR] = temp & 0xffffffff00000000LL;
+ State.regs[REG_MDR] = (temp & 0xffffffff00000000LL) >> 32;;
z = (State.regs[REG_D0 + REG0 (insn)] == 0);
n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
@@ -1460,7 +1460,7 @@ void OP_F250 (insn, extension)
temp = (State.regs[REG_D0 + REG0 (insn)]
* State.regs[REG_D0 + REG1 (insn)]);
State.regs[REG_D0 + REG0 (insn)] = temp & 0xffffffff;
- State.regs[REG_MDR] = temp & 0xffffffff00000000LL;
+ State.regs[REG_MDR] = (temp & 0xffffffff00000000LL) >> 32;
z = (State.regs[REG_D0 + REG0 (insn)] == 0);
n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
@@ -1480,7 +1480,6 @@ void OP_F260 (insn, extension)
State.regs[REG_MDR] = temp % (long)State.regs[REG_D0 + REG1 (insn)];
temp /= (long)State.regs[REG_D0 + REG1 (insn)];
State.regs[REG_D0 + REG0 (insn)] = temp & 0xffffffff;
- State.regs[REG_MDR] = temp & 0xffffffff00000000LL;
z = (State.regs[REG_D0 + REG0 (insn)] == 0);
n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
@@ -1500,7 +1499,6 @@ void OP_F270 (insn, extension)
State.regs[REG_MDR] = temp % State.regs[REG_D0 + REG1 (insn)];
temp /= State.regs[REG_D0 + REG1 (insn)];
State.regs[REG_D0 + REG0 (insn)] = temp & 0xffffffff;
- State.regs[REG_MDR] = temp & 0xffffffff00000000LL;
z = (State.regs[REG_D0 + REG0 (insn)] == 0);
n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
@@ -1884,7 +1882,7 @@ void OP_FAFD0000 (insn, extension)
PSW |= (insn & 0xffff);
}
-/* xor dm, dn*/
+/* xor dm, dn */
void OP_F220 (insn, extension)
unsigned long insn, extension;
{
@@ -2403,84 +2401,117 @@ void OP_CA00 (insn, extension)
void OP_D8 (insn, extension)
unsigned long insn, extension;
{
- abort ();
+ /* The dispatching code will add 1 after we return, so
+ we subtract one here to make things right. */
+ if (PSW & PSW_Z)
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1;
}
/* lne */
void OP_D9 (insn, extension)
unsigned long insn, extension;
{
- abort ();
+ /* The dispatching code will add 1 after we return, so
+ we subtract one here to make things right. */
+ if (!(PSW & PSW_Z))
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1;
}
/* lgt */
void OP_D1 (insn, extension)
unsigned long insn, extension;
{
- abort ();
+ /* The dispatching code will add 1 after we return, so
+ we subtract one here to make things right. */
+ if (!((PSW & PSW_Z)
+ || (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0))))
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1;
}
/* lge */
void OP_D2 (insn, extension)
unsigned long insn, extension;
{
- abort ();
+ /* The dispatching code will add 1 after we return, so
+ we subtract one here to make things right. */
+ if (!(((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0)))
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1;
}
/* lle */
void OP_D3 (insn, extension)
unsigned long insn, extension;
{
- abort ();
+ /* The dispatching code will add 1 after we return, so
+ we subtract one here to make things right. */
+ if ((PSW & PSW_Z)
+ || (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0)))
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1;
}
/* llt */
void OP_D0 (insn, extension)
unsigned long insn, extension;
{
- abort ();
+ /* The dispatching code will add 1 after we return, so
+ we subtract one here to make things right. */
+ if (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0))
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1;
}
/* lhi */
void OP_D5 (insn, extension)
unsigned long insn, extension;
{
- abort ();
+ /* The dispatching code will add 1 after we return, so
+ we subtract one here to make things right. */
+ if (!(((PSW & PSW_C) != 0) || (PSW & PSW_Z) != 0))
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1;
}
/* lcc */
void OP_D6 (insn, extension)
unsigned long insn, extension;
{
- abort ();
+ /* The dispatching code will add 1 after we return, so
+ we subtract one here to make things right. */
+ if (!(PSW & PSW_C))
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1;
}
/* lls */
void OP_D7 (insn, extension)
unsigned long insn, extension;
{
- abort ();
+ /* The dispatching code will add 1 after we return, so
+ we subtract one here to make things right. */
+ if (((PSW & PSW_C) != 0) || (PSW & PSW_Z) != 0)
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1;
}
/* lcs */
void OP_D4 (insn, extension)
unsigned long insn, extension;
{
- abort ();
+ /* The dispatching code will add 1 after we return, so
+ we subtract one here to make things right. */
+ if (PSW & PSW_C)
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1;
}
/* lra */
void OP_DA (insn, extension)
unsigned long insn, extension;
{
- abort ();
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1;
}
/* setlb */
void OP_DB (insn, extension)
unsigned long insn, extension;
{
- abort ();
+ State.regs[REG_LIR] = load_mem_big (State.regs[REG_PC] + 1, 4);
+ State.regs[REG_LAR] = State.regs[REG_PC] + 5;
}
/* jmp (an) */
@@ -2826,18 +2857,32 @@ void OP_F0FC (insn, extension)
void OP_F0FD (insn, extension)
unsigned long insn, extension;
{
- abort ();
+ unsigned int sp, next_pc;
+
+ PSW = State.mem[sp] | (State.mem[sp + 1] << 8);
+ State.regs[REG_PC] = (State.mem[sp+4] | (State.mem[sp+5] << 8)
+ | (State.mem[sp+6] << 16) | (State.mem[sp+7] << 24));
+ State.regs[REG_SP] += 8;
}
/* trap */
void OP_F0FE (insn, extension)
unsigned long insn, extension;
{
+ unsigned int sp, next_pc;
+
+ sp = State.regs[REG_SP];
+ next_pc = State.regs[REG_PC] + 2;
+ State.mem[sp] = next_pc & 0xff;
+ State.mem[sp+1] = (next_pc & 0xff00) >> 8;
+ State.mem[sp+2] = (next_pc & 0xff0000) >> 16;
+ State.mem[sp+3] = (next_pc & 0xff000000) >> 24;
+ State.regs[REG_PC] = 0x40000010 - 2;
abort ();
}
/* syscall */
-void OP_F0FF (insn, extension)
+void OP_F020 (insn, extension)
unsigned long insn, extension;
{
/* We use this for simulated system calls; we may need to change