aboutsummaryrefslogtreecommitdiff
path: root/sim/mn10300
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>1996-11-27 05:29:49 +0000
committerJeff Law <law@redhat.com>1996-11-27 05:29:49 +0000
commit1f3bea21691b1a8461f9b44fbcf101c4a5ba124f (patch)
tree24aa99b0a6df4a5ee7e6ef4125583ed4845276c4 /sim/mn10300
parent7844472931bc55884b1ceadc094173384d491079 (diff)
downloadgdb-1f3bea21691b1a8461f9b44fbcf101c4a5ba124f.zip
gdb-1f3bea21691b1a8461f9b44fbcf101c4a5ba124f.tar.gz
gdb-1f3bea21691b1a8461f9b44fbcf101c4a5ba124f.tar.bz2
* simops.c: Implement "movm" and "bCC" insns.
Function calls and conditional branches work!
Diffstat (limited to 'sim/mn10300')
-rw-r--r--sim/mn10300/ChangeLog2
-rw-r--r--sim/mn10300/simops.c165
2 files changed, 160 insertions, 7 deletions
diff --git a/sim/mn10300/ChangeLog b/sim/mn10300/ChangeLog
index 7eae6fe..89524fd 100644
--- a/sim/mn10300/ChangeLog
+++ b/sim/mn10300/ChangeLog
@@ -1,5 +1,7 @@
Tue Nov 26 15:43:41 1996 Jeffrey A Law (law@cygnus.com)
+ * simops.c: Implement "movm" and "bCC" insns.
+
* mn10300_sim.h (_state): Add another register (MDR).
(REG_MDR): Define.
* simops.c: Implement "cmp", "calls", "rets", "jmp" and
diff --git a/sim/mn10300/simops.c b/sim/mn10300/simops.c
index 2229148..deeb22c 100644
--- a/sim/mn10300/simops.c
+++ b/sim/mn10300/simops.c
@@ -92,13 +92,13 @@ void OP_90 ()
{
}
-/* mov sp, an*/
+/* mov sp, an */
void OP_3C ()
{
State.regs[REG_A0 + (insn & 0x3)] = State.regs[REG_SP];
}
-/* mov am, sp*/
+/* mov am, sp */
void OP_F2F0 ()
{
State.regs[REG_SP] = State.regs[REG_A0 + ((insn & 0xc) >> 2)];
@@ -349,7 +349,7 @@ void OP_240000 ()
{
}
-/* mov imm32, an*/
+/* mov imm32, an */
void OP_FCDC0000 ()
{
unsigned long value;
@@ -585,14 +585,114 @@ void OP_1C ()
{
}
-/* movm */
+/* movm (sp), reg_list */
void OP_CE00 ()
{
-}
-
-/* movm */
+ unsigned long sp = State.regs[REG_SP];
+ unsigned long mask;
+
+ mask = insn & 0xff;
+
+ if (mask & 0x8)
+ {
+ sp += 4;
+ State.regs[REG_LAR] = load_mem (sp, 4);
+ sp += 4;
+ State.regs[REG_LIR] = load_mem (sp, 4);
+ sp += 4;
+ State.regs[REG_MDR] = load_mem (sp, 4);
+ sp += 4;
+ State.regs[REG_A0 + 1] = load_mem (sp, 4);
+ sp += 4;
+ State.regs[REG_A0] = load_mem (sp, 4);
+ sp += 4;
+ State.regs[REG_D0 + 1] = load_mem (sp, 4);
+ sp += 4;
+ State.regs[REG_D0] = load_mem (sp, 4);
+ sp += 4;
+ }
+
+ if (mask & 0x10)
+ {
+ State.regs[REG_A0 + 3] = load_mem (sp, 4);
+ sp += 4;
+ }
+
+ if (mask & 0x20)
+ {
+ State.regs[REG_A0 + 2] = load_mem (sp, 4);
+ sp += 4;
+ }
+
+ if (mask & 0x40)
+ {
+ State.regs[REG_D0 + 3] = load_mem (sp, 4);
+ sp += 4;
+ }
+
+ if (mask & 0x80)
+ {
+ State.regs[REG_D0 + 2] = load_mem (sp, 4);
+ sp += 4;
+ }
+
+ /* And make sure to update the stack pointer. */
+ State.regs[REG_SP] = sp;
+}
+
+/* movm reg_list, (sp) */
void OP_CF00 ()
{
+ unsigned long sp = State.regs[REG_SP];
+ unsigned long mask;
+
+ mask = insn & 0xff;
+
+ if (mask & 0x80)
+ {
+ sp -= 4;
+ store_mem (sp, 4, State.regs[REG_D0 + 2]);
+ }
+
+ if (mask & 0x40)
+ {
+ sp -= 4;
+ store_mem (sp, 4, State.regs[REG_D0 + 3]);
+ }
+
+ if (mask & 0x20)
+ {
+ sp -= 4;
+ store_mem (sp, 4, State.regs[REG_A0 + 2]);
+ }
+
+ if (mask & 0x10)
+ {
+ sp -= 4;
+ store_mem (sp, 4, State.regs[REG_A0 + 3]);
+ }
+
+ if (mask & 0x8)
+ {
+ sp -= 4;
+ store_mem (sp, 4, State.regs[REG_D0]);
+ sp -= 4;
+ store_mem (sp, 4, State.regs[REG_D0 + 1]);
+ sp -= 4;
+ store_mem (sp, 4, State.regs[REG_A0]);
+ sp -= 4;
+ store_mem (sp, 4, State.regs[REG_A0 + 1]);
+ sp -= 4;
+ store_mem (sp, 4, State.regs[REG_MDR]);
+ sp -= 4;
+ store_mem (sp, 4, State.regs[REG_LIR]);
+ sp -= 4;
+ store_mem (sp, 4, State.regs[REG_LAR]);
+ sp -= 4;
+ }
+
+ /* And make sure to update the stack pointer. */
+ State.regs[REG_SP] = sp;
}
/* clr dn */
@@ -1386,66 +1486,117 @@ void OP_C900 ()
/* bgt */
void OP_C100 ()
{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (!(((PSW & PSW_Z) != 0)
+ || (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0))))
+ State.pc += SEXT8 (insn & 0xff) - 2;
}
/* bge */
void OP_C200 ()
{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (!(((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0)))
+ State.pc += SEXT8 (insn & 0xff) - 2;
}
/* ble */
void OP_C300 ()
{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (((PSW & PSW_Z) != 0)
+ || (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0)))
+ State.pc += SEXT8 (insn & 0xff) - 2;
}
/* blt */
void OP_C000 ()
{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0))
+ State.pc += SEXT8 (insn & 0xff) - 2;
}
/* bhi */
void OP_C500 ()
{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (!(((PSW & PSW_C) != 0) || ((PSW & PSW_Z) != 0)))
+ State.pc += SEXT8 (insn & 0xff) - 2;
}
/* bcc */
void OP_C600 ()
{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (!((PSW & PSW_C) != 0))
+ State.pc += SEXT8 (insn & 0xff) - 2;
}
/* bls */
void OP_C700 ()
{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (((PSW & PSW_C) != 0) || ((PSW & PSW_Z) != 0))
+ State.pc += SEXT8 (insn & 0xff) - 2;
}
/* bcs */
void OP_C400 ()
{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if ((PSW & PSW_C) != 0)
+ State.pc += SEXT8 (insn & 0xff) - 2;
}
/* bvc */
void OP_F8E800 ()
{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (!((PSW & PSW_V) != 0))
+ State.pc += SEXT8 (insn & 0xff) - 3;
}
/* bvs */
void OP_F8E900 ()
{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if ((PSW & PSW_V) != 0)
+ State.pc += SEXT8 (insn & 0xff) - 3;
}
/* bnc */
void OP_F8EA00 ()
{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (!((PSW & PSW_C) != 0))
+ State.pc += SEXT8 (insn & 0xff) - 3;
}
/* bns */
void OP_F8EB00 ()
{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if ((PSW & PSW_N) != 0)
+ State.pc += SEXT8 (insn & 0xff) - 3;
}
/* bra */
void OP_CA00 ()
{
+ State.pc += SEXT8 (insn & 0xff) - 2;
}
/* leq */