// The following is called when ever an illegal instruction is encountered.
::internal::illegal
- engine_error (SD, CPU, cia, "illegal instruction at 0x%lx", cia.ip);
+ engine_error (SD, CPU, cia,
+ "illegal instruction at 0x%lx", cia.ip);
// The following is called when ever an FP op is attempted with FPU disabled.
::internal::fp_unavailable
- engine_error (SD, CPU, cia, "floating-point unavailable at 0x%lx", cia.ip);
+ engine_error (SD, CPU, cia,
+ "floating-point unavailable at 0x%lx", cia.ip);
+
+// Handle a branch instruction
+instruction_address::function::do_branch:int annul, address_word target, int rLink_p, unsigned32 *rLink
+ instruction_address nia;
+ if (annul)
+ {
+ if (rLink_p)
+ *rLink = cia.dp;
+ nia.ip = target;
+ nia.dp = target + 4;
+ }
+ else
+ {
+ if (rLink_p)
+ *rLink = cia.dp + sizeof (instruction_word);
+ nia.ip = cia.dp;
+ nia.dp = target;
+ }
+ return nia;
// Signed Integer Add - add source1, source2, dest
void::function::do_add:signed32 *rDest, signed32 Source1, signed32 Source2
// bbo.[a]
instruction_address::function::do_bbo:instruction_address nia, int bitnum, unsigned32 source, int annul, unsigned32 offset
int jump_p;
- unsigned32 target = cia.ip + 4 * offset;
+ address_word target = cia.ip + 4 * offset;
bitnum = (~ bitnum) & 0x1f;
if (MASKED32 (source, bitnum, bitnum))
{
- if (annul)
- nia.ip = -1;
- nia.dp = target;
+ nia = do_branch (_SD, annul, target, 0, NULL);
jump_p = 1;
}
else
// bbz[.a]
instruction_address::function::do_bbz:instruction_address nia, int bitnum, unsigned32 source, int annul, unsigned32 offset
int jump_p;
- unsigned32 target = cia.ip + 4 * offset;
+ address_word target = cia.ip + 4 * offset;
bitnum = (~ bitnum) & 0x1f;
if (!MASKED32 (source, bitnum, bitnum))
{
- if (annul)
- nia.ip = -1;
- nia.dp = target;
+ nia = do_branch (_SD, annul, target, 0, NULL);
jump_p = 1;
}
else
int size = EXTRACTED32 (Cond, 31 - 27, 30 - 27);
int code = EXTRACTED32 (Cond, 29 - 27, 27 - 27);
signed32 val = 0;
- unsigned32 target = cia.ip + 4 * offset;
+ address_word target = cia.ip + 4 * offset;
switch (size)
{
case 0: val = SEXT32 (source, 7); break;
}
if (condition)
{
- if (annul)
- nia.ip = -1;
- nia.dp = target;
+ nia = do_branch (_SD, annul, target, 0, NULL);
}
TRACE_COND_BR(MY_INDEX, condition, source, target);
return nia;
// bsr[.a]
instruction_address::function::do_bsr:instruction_address nia, signed32 *rLink, int annul, unsigned32 offset
- if (annul)
- {
- *rLink = nia.ip;
- nia.ip = -1;
- }
- else
- *rLink = nia.ip + sizeof (instruction_word);
- nia.dp = cia.ip + 4 * offset;
- TRACE_UCOND_BR (MY_INDEX, nia.dp);
+ address_word target = cia.ip + 4 * offset;
+ nia = do_branch (_SD, annul, target, 1, rLink);
+ TRACE_UCOND_BR (MY_INDEX, target);
return nia;
31.Link,26./,21.0b100000,15.A,14.SignedOffset::::bsr i
nia = do_bsr (_SD, nia, rLink, A, vSignedOffset);
// jsr[.a]
instruction_address::function::do_jsr:instruction_address nia, signed32 *rLink, int annul, unsigned32 offset, unsigned32 base
- TRACE_UCOND_BR (MY_INDEX, nia.ip);
- if (annul)
- {
- *rLink = nia.ip;
- nia.ip = -1;
- }
- else
- *rLink = nia.ip + sizeof (instruction_word);
- nia.dp = offset + base;
+ address_word target = offset + base;
+ TRACE_UCOND_BR (MY_INDEX, target);
+ nia = do_branch (_SD, annul, target, 1, rLink);
if (nia.dp & 0x3)
engine_error (SD, CPU, cia,
"0x%lx: destination address 0x%lx misaligned",
cia = cpu->cia;
do
{
- if (cia.ip == -1)
- {
- /* anulled instruction */
- cia.ip = cia.dp;
- cia.dp = cia.dp + sizeof (instruction_word);
- }
- else
- {
- instruction_word insn = IMEM (cia.ip);
- cia = idecode_issue (sd, insn, cia);
- }
+ instruction_word insn = IMEM (cia);
+ cia = idecode_issue (sd, insn, cia);
}
while (*keep_running);
engine_halt (sd, cpu, cia, sim_stopped, SIGINT);
if (!setjmp (sd->path_to_halt))
{
instruction_address cia;
+ instruction_word insn;
sim_cpu *cpu = STATE_CPU (sd, 0);
sd->halt_ok = 1;
setjmp (sd->path_to_restart);
sd->restart_ok = 1;
cia = cpu->cia;
- if (cia.ip == -1)
- {
- /* anulled instruction */
- cia.ip = cia.dp;
- cia.dp = cia.dp + sizeof (instruction_word);
- }
- else
- {
- instruction_word insn = IMEM (cia.ip);
- cia = idecode_issue (sd, insn, cia);
- }
+ insn = IMEM (cia);
+ cia = idecode_issue (sd, insn, cia);
engine_halt (sd, cpu, cia, sim_stopped, SIGTRAP);
}
}