@@ -554,7 +554,7 @@ void Core::writeback(const struct dtMemory &dt) {
554
554
regs->write_gp (dt.rwrite , dt.towrite_val );
555
555
}
556
556
557
- bool Core::handle_pc (const struct dtDecode &dt, int32_t rel_adj ) {
557
+ bool Core::handle_pc (const struct dtDecode &dt) {
558
558
bool branch = false ;
559
559
emit instruction_program_counter (dt.inst , dt.inst_addr , EXCAUSE_NONE);
560
560
@@ -593,7 +593,7 @@ bool Core::handle_pc(const struct dtDecode &dt, int32_t rel_adj) {
593
593
std::int32_t rel_offset = dt.inst .immediate () << 2 ;
594
594
if (rel_offset & (1 << 17 ))
595
595
rel_offset -= 1 << 18 ;
596
- regs->pc_jmp ( rel_offset + rel_adj );
596
+ regs->pc_abs_jmp (dt. inst_addr + rel_offset + 4 );
597
597
} else {
598
598
regs->pc_inc ();
599
599
}
@@ -672,57 +672,66 @@ CoreSingle::CoreSingle(Registers *regs, MemoryAccess *mem_program, MemoryAccess
672
672
bool jmp_delay_slot, unsigned int min_cache_row_size, Cop0State *cop0state) :
673
673
Core(regs, mem_program, mem_data, min_cache_row_size, cop0state) {
674
674
if (jmp_delay_slot)
675
- jmp_delay_decode = new struct Core ::dtDecode ();
675
+ dt_f = new struct Core ::dtFetch ();
676
676
else
677
- jmp_delay_decode = nullptr ;
677
+ dt_f = nullptr ;
678
678
reset ();
679
679
}
680
680
681
681
CoreSingle::~CoreSingle () {
682
- if (jmp_delay_decode != nullptr )
683
- delete jmp_delay_decode ;
682
+ if (dt_f != nullptr )
683
+ delete dt_f ;
684
684
}
685
685
686
686
void CoreSingle::do_step (bool skip_break) {
687
- bool in_delay_slot = false ;
688
- std::uint32_t jump_branch_pc;
687
+ bool branch_taken = false ;
689
688
690
689
struct dtFetch f = fetch (skip_break);
690
+ if (dt_f != nullptr ) {
691
+ struct dtFetch f_swap = *dt_f;
692
+ *dt_f = f;
693
+ f = f_swap;
694
+ }
691
695
struct dtDecode d = decode (f);
696
+ struct dtExecute e = execute (d);
697
+ struct dtMemory m = memory (e);
698
+ writeback (m);
692
699
693
700
// Handle PC before instruction following jump leaves decode stage
694
- if (jmp_delay_decode != nullptr ) {
695
- in_delay_slot = handle_pc (*jmp_delay_decode);
696
- if (jmp_delay_decode->nb_skip_ds && !in_delay_slot) {
697
- // Discard processing of instruction in delay slot
698
- // for BEQL, BNEL, BLEZL, BGTZL, BLTZL, BGEZL, BLTZALL, BGEZALL
699
- dtDecodeInit (d);
700
- }
701
- jump_branch_pc = jmp_delay_decode->inst_addr ;
702
- *jmp_delay_decode = d; // Copy current decode
701
+
702
+ if ((m.stop_if || (m.excause != EXCAUSE_NONE)) && dt_f != nullptr ) {
703
+ dtFetchInit (*dt_f);
704
+ emit instruction_fetched (dt_f->inst , dt_f->inst_addr , dt_f->excause );
705
+ emit fetch_inst_addr_value (STAGEADDR_NONE);
703
706
} else {
704
- handle_pc (d, 4 );
705
- jump_branch_pc = d.inst_addr ;
707
+ branch_taken = handle_pc (d);
708
+ if (dt_f != nullptr ) {
709
+ dt_f->in_delay_slot = branch_taken;
710
+ if (d.nb_skip_ds && !branch_taken) {
711
+ // Discard processing of instruction in delay slot
712
+ // for BEQL, BNEL, BLEZL, BGTZL, BLTZL, BGEZL, BLTZALL, BGEZALL
713
+ dtFetchInit (*dt_f);
714
+ }
715
+ }
706
716
}
707
717
708
- struct dtExecute e = execute (d);
709
- struct dtMemory m = memory (e);
710
- writeback (m);
711
-
712
718
if (m.excause != EXCAUSE_NONE) {
713
- if (jmp_delay_decode != nullptr )
714
- dtDecodeInit (*jmp_delay_decode);
719
+ if (dt_f != nullptr ) {
720
+ regs->pc_abs_jmp (dt_f->inst_addr );
721
+ }
715
722
handle_exception (this , regs, m.excause , m.inst_addr , regs->read_pc (),
716
- jump_branch_pc, in_delay_slot, m.mem_addr );
723
+ prev_inst_addr, m. in_delay_slot , m.mem_addr );
717
724
return ;
718
725
}
726
+ prev_inst_addr = m.inst_addr ;
719
727
}
720
728
721
729
void CoreSingle::do_reset () {
722
- if (jmp_delay_decode != nullptr ) {
723
- Core::dtDecodeInit (*jmp_delay_decode );
724
- jmp_delay_decode ->inst_addr = 0 ;
730
+ if (dt_f != nullptr ) {
731
+ Core::dtFetchInit (*dt_f );
732
+ dt_f ->inst_addr = 0 ;
725
733
}
734
+ prev_inst_addr = 0 ;
726
735
}
727
736
728
737
CorePipelined::CorePipelined (Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data,
0 commit comments