* mn10300_sim.h (_state): Add another register (MDR).
authorJeff Law <law@redhat.com>
Wed, 27 Nov 1996 00:53:25 +0000 (00:53 +0000)
committerJeff Law <law@redhat.com>
Wed, 27 Nov 1996 00:53:25 +0000 (00:53 +0000)
        (REG_MDR): Define.
        * simops.c: Implement "cmp", "calls", "rets", "jmp" and
        a few additional random insns.
We can now function calls.  We get out of crt0 into main now, then lose
when calls are nested (because don't handle movm yet).

sim/mn10300/ChangeLog
sim/mn10300/mn10300_sim.h
sim/mn10300/simops.c

index 128889eb4aea739586ef0b26f35395af1b14e1a0..7eae6fec5f51ef3e96fdb6ab4cefd8002ae6d858 100644 (file)
@@ -1,5 +1,10 @@
 Tue Nov 26 15:43:41 1996  Jeffrey A Law  (law@cygnus.com)
 
+       * mn10300_sim.h (_state): Add another register (MDR).
+       (REG_MDR): Define.
+       * simops.c: Implement "cmp", "calls", "rets", "jmp" and
+       a few additional random insns.
+
        * mn10300_sim.h (PSW_*): Define for CC status tracking.
        (REG_D0, REG_A0, REG_SP): Define.
        * simops.c: Implement "add", "addc" and a few other random
index 245e8bd5c421d9870c4a8f2fc9d37e27fad5eeff..8c6a216e4743593aa16ca11de856ccc28b1259da 100644 (file)
@@ -59,7 +59,7 @@ struct simops
 
 struct _state
 {
-  reg_t regs[9];               /* registers, d0-d3, a0-a3, sp */
+  reg_t regs[10];              /* registers, d0-d3, a0-a3, sp, mdr */
   reg_t sregs[8];              /* system registers, including psw */
   reg_t pc;
   uint8 *mem;                  /* main memory */
@@ -81,6 +81,7 @@ extern unsigned long insn, extension;
 #define REG_D0 0
 #define REG_A0 4
 #define REG_SP 8
+#define REG_MDR 9
 
 #define SEXT3(x)       ((((x)&0x7)^(~0x3))+0x4)        
 
index 8468293646676b4ea215b2a1abf4c3ac2749bf0e..22291489fb57c302d1bdc7c34b6fdf1bed126f7e 100644 (file)
@@ -92,15 +92,16 @@ void OP_90 ()
 {
 }
 
-/* mov */
+/* mov sp, an*/
 void OP_3C ()
 {
+  State.regs[REG_A0 + (insn & 0x3)] = State.regs[REG_SP];
 }
 
 /* mov am, sp*/
 void OP_F2F0 ()
 {
-  State.regs[REG_SP] = State.regs[REG_A0 + (insn & 0x3)];
+  State.regs[REG_SP] = State.regs[REG_A0 + ((insn & 0xc) >> 2)];
 }
 
 /* mov */
@@ -978,35 +979,115 @@ void OP_41 ()
   State.regs[REG_A0 + ((insn & 0xc) >> 2)] += 1;
 }
 
-/* inc4 */
+/* inc4 an */
 void OP_50 ()
 {
   State.regs[REG_A0 + (insn & 0x3)] += 4;
 }
 
-/* cmp */
+/* cmp imm8, dn */
 void OP_A000 ()
 {
+  int z, c, n, v;
+  unsigned long reg1, imm, value;
+
+  reg1 = State.regs[REG_D0 + ((insn & 0x300) >> 8)];
+  imm = SEXT8 (insn & 0xff);
+  value = reg1 - imm;
+
+  z = (value == 0);
+  n = (value & 0x80000000);
+  c = (reg1 < imm);
+  v = ((imm & 0x8000000) != (reg1 & 0x80000000)
+       && (imm & 0x8000000) != (value & 0x80000000));
+
+  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));
 }
 
-/* cmp */
+/* cmp dm, dn */
 void OP_A0 ()
 {
+  int z, c, n, v;
+  unsigned long reg1, reg2, value;
+
+  reg1 = State.regs[REG_D0 + ((insn & 0xc) >> 2)];
+  reg2 = State.regs[REG_D0 + (insn & 0x3)];
+  value = reg1 - reg2;
+
+  z = (value == 0);
+  n = (value & 0x80000000);
+  c = (reg1 < reg2);
+  v = ((reg2 & 0x8000000) != (reg1 & 0x80000000)
+       && (reg2 & 0x8000000) != (value & 0x80000000));
+
+  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));
 }
 
-/* cmp */
+/* cmp dm, an */
 void OP_F1A0 ()
 {
+  int z, c, n, v;
+  unsigned long reg1, reg2, value;
+
+  reg1 = State.regs[REG_D0 + ((insn & 0xc) >> 2)];
+  reg2 = State.regs[REG_A0 + (insn & 0x3)];
+  value = reg1 - reg2;
+
+  z = (value == 0);
+  n = (value & 0x80000000);
+  c = (reg1 < reg2);
+  v = ((reg2 & 0x8000000) != (reg1 & 0x80000000)
+       && (reg2 & 0x8000000) != (value & 0x80000000));
+
+  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));
 }
 
-/* cmp */
+/* cmp am, dn */
 void OP_F190 ()
 {
+  int z, c, n, v;
+  unsigned long reg1, reg2, value;
+
+  reg1 = State.regs[REG_A0 + ((insn & 0xc) >> 2)];
+  reg2 = State.regs[REG_D0 + (insn & 0x3)];
+  value = reg1 - reg2;
+
+  z = (value == 0);
+  n = (value & 0x80000000);
+  c = (reg1 < reg2);
+  v = ((reg2 & 0x8000000) != (reg1 & 0x80000000)
+       && (reg2 & 0x8000000) != (value & 0x80000000));
+
+  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));
 }
 
-/* cmp */
+/* cmp imm8, an */
 void OP_B000 ()
 {
+  int z, c, n, v;
+  unsigned long reg1, imm, value;
+
+  reg1 = State.regs[REG_A0 + ((insn & 0x300) >> 8)];
+  imm = insn & 0xff;
+  value = reg1 - imm;
+
+  z = (value == 0);
+  n = (value & 0x80000000);
+  c = (reg1 < imm);
+  v = ((imm & 0x8000000) != (reg1 & 0x80000000)
+       && (imm & 0x8000000) != (value & 0x80000000));
+
+  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));
 }
 
 /* cmp am,an */
@@ -1033,21 +1114,85 @@ void OP_B0 ()
 /* cmp */
 void OP_FAC80000 ()
 {
+  int z, c, n, v;
+  unsigned long reg1, imm, value;
+
+  reg1 = State.regs[REG_D0 + ((insn & 0x300) >> 16)];
+  imm = SEXT16 (insn & 0xffff);
+  value = reg1 - imm;
+
+  z = (value == 0);
+  n = (value & 0x80000000);
+  c = (reg1 < imm);
+  v = ((imm & 0x8000000) != (reg1 & 0x80000000)
+       && (imm & 0x8000000) != (value & 0x80000000));
+
+  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));
 }
 
 /* cmp */
 void OP_FCC80000 ()
 {
+  int z, c, n, v;
+  unsigned long reg1, imm, value;
+
+  reg1 = State.regs[REG_D0 + ((insn & 0x300) >> 16)];
+  imm = ((insn & 0xffff) << 16) | extension;
+  value = reg1 - imm;
+
+  z = (value == 0);
+  n = (value & 0x80000000);
+  c = (reg1 < imm);
+  v = ((imm & 0x8000000) != (reg1 & 0x80000000)
+       && (imm & 0x8000000) != (value & 0x80000000));
+
+  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));
 }
 
 /* cmp */
 void OP_FAD80000 ()
 {
+  int z, c, n, v;
+  unsigned long reg1, imm, value;
+
+  reg1 = State.regs[REG_A0 + ((insn & 0x300) >> 16)];
+  imm = insn & 0xffff;
+  value = reg1 - imm;
+
+  z = (value == 0);
+  n = (value & 0x80000000);
+  c = (reg1 < imm);
+  v = ((imm & 0x8000000) != (reg1 & 0x80000000)
+       && (imm & 0x8000000) != (value & 0x80000000));
+
+  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));
 }
 
 /* cmp */
 void OP_FCD80000 ()
 {
+  int z, c, n, v;
+  unsigned long reg1, imm, value;
+
+  reg1 = State.regs[REG_A0 + ((insn & 0x300) >> 16)];
+  imm = ((insn & 0xffff) << 16) | extension;
+  value = reg1 - imm;
+
+  z = (value == 0);
+  n = (value & 0x80000000);
+  c = (reg1 < imm);
+  v = ((imm & 0x8000000) != (reg1 & 0x80000000)
+       && (imm & 0x8000000) != (value & 0x80000000));
+
+  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));
 }
 
 /* and */
@@ -1366,16 +1511,19 @@ void OP_DB ()
 /* jmp */
 void OP_F0F4 ()
 {
+  State.pc = State.regs[REG_A0 + (insn & 0x3)] - 2;
 }
 
 /* jmp */
 void OP_CC0000 ()
 {
+  State.pc += SEXT16 (insn & 0xffff) - 3;
 }
 
 /* jmp */
 void OP_DC000000 ()
 {
+  State.pc += (((insn & 0xffffff) << 8) | extension) - 5;
 }
 
 /* call */
@@ -1391,16 +1539,46 @@ void OP_DD000000 ()
 /* calls */
 void OP_F0F0 ()
 {
+  unsigned int next_pc, sp;
+
+  sp = State.regs[REG_SP];
+  next_pc = State.pc + 2;
+  State.mem[sp] = next_pc & 0xff;
+  State.mem[sp+1] = next_pc & 0xff00;
+  State.mem[sp+2] = next_pc & 0xff0000;
+  State.mem[sp+3] = next_pc & 0xff000000;
+  State.regs[REG_MDR] = next_pc;
+  State.pc = State.regs[REG_A0 + (insn & 0x3)] - 2;
 }
 
 /* calls */
 void OP_FAFF0000 ()
 {
+  unsigned int next_pc, sp;
+
+  sp = State.regs[REG_SP];
+  next_pc = State.pc + 4;
+  State.mem[sp] = next_pc & 0xff;
+  State.mem[sp+1] = next_pc & 0xff00;
+  State.mem[sp+2] = next_pc & 0xff0000;
+  State.mem[sp+3] = next_pc & 0xff000000;
+  State.regs[REG_MDR] = next_pc;
+  State.pc += SEXT16 (insn & 0xffff) - 4;
 }
 
 /* calls */
 void OP_FCFF0000 ()
 {
+  unsigned int next_pc, sp;
+
+  sp = State.regs[REG_SP];
+  next_pc = State.pc + 6;
+  State.mem[sp] = next_pc & 0xff;
+  State.mem[sp+1] = next_pc & 0xff00;
+  State.mem[sp+2] = next_pc & 0xff0000;
+  State.mem[sp+3] = next_pc & 0xff000000;
+  State.regs[REG_MDR] = next_pc;
+  State.pc += (((insn & 0xffff) << 16) | extension) - 6;
 }
 
 /* ret */
@@ -1416,6 +1594,12 @@ void OP_DE0000 ()
 /* rets */
 void OP_F0FC ()
 {
+  unsigned int sp;
+
+  sp = State.regs[REG_SP];
+  State.pc = (State.mem[sp] | (State.mem[sp+1] << 8)
+             | (State.mem[sp+2] << 16) | (State.mem[sp+3] << 24));
+  State.pc -= 2;
 }
 
 /* rti */