11 #include "softfloat.h"
12 #include "platform.h" // softfloat isNaNF32UI, etc.
13 #include "internals.h" // ditto
15 processor_t::processor_t(sim_t
* _sim
, char* _mem
, size_t _memsz
)
16 : sim(_sim
), mmu(_mem
,_memsz
)
18 memset(XPR
,0,sizeof(XPR
));
19 memset(FPR
,0,sizeof(FPR
));
31 set_sr(SR_S
| SR_SX
); // SX ignored if 64b mode not supported
34 memset(counters
,0,sizeof(counters
));
44 for (int i
=0; i
<MAX_UTS
; i
++)
47 // a few assumptions about endianness, including freg_t union
48 static_assert(BYTE_ORDER
== LITTLE_ENDIAN
);
49 static_assert(sizeof(freg_t
) == 8);
50 static_assert(sizeof(reg_t
) == 8);
52 static_assert(sizeof(insn_t
) == 4);
53 static_assert(sizeof(uint128_t
) == 16 && sizeof(int128_t
) == 16);
61 processor_t::~processor_t()
68 itlbsim
->print_stats();
76 dtlbsim
->print_stats();
80 void processor_t::init(uint32_t _id
, icsim_t
* default_icache
,
81 icsim_t
* default_dcache
)
85 for (int i
=0; i
<MAX_UTS
; i
++)
87 uts
[i
] = new processor_t(sim
, mmu
.mem
, mmu
.memsz
);
89 uts
[i
]->set_sr(uts
[i
]->sr
| SR_EF
);
90 uts
[i
]->set_sr(uts
[i
]->sr
| SR_EV
);
94 #ifdef RISCV_ENABLE_ICSIM
95 icsim
= new icsim_t(*default_icache
);
97 itlbsim
= new icsim_t(1, 8, 4096, "ITLB");
98 mmu
.set_itlbsim(itlbsim
);
100 #ifdef RISCV_ENABLE_ICSIM
101 dcsim
= new icsim_t(*default_dcache
);
102 mmu
.set_dcsim(dcsim
);
103 dtlbsim
= new icsim_t(1, 8, 4096, "DTLB");
104 mmu
.set_dtlbsim(dtlbsim
);
108 void processor_t::set_sr(uint32_t val
)
111 #ifndef RISCV_ENABLE_64BIT
112 sr
&= ~(SR_SX
| SR_UX
);
114 #ifndef RISCV_ENABLE_FPU
117 #ifndef RISCV_ENABLE_RVC
120 #ifndef RISCV_ENABLE_VEC
124 xprlen
= ((sr
& SR_S
) ? (sr
& SR_SX
) : (sr
& SR_UX
)) ? 64 : 32;
127 void processor_t::set_fsr(uint32_t val
)
129 fsr
= val
& ~FSR_ZERO
;
132 void processor_t::vcfg()
134 if (nxpr_use
== 0 && nfpr_use
== 0)
136 else if (nfpr_use
== 0)
137 vlmax
= (nxpr_all
-1) / (nxpr_use
-1);
138 else if (nxpr_use
== 0)
139 vlmax
= (nfpr_all
-1) / (nfpr_use
-1);
141 vlmax
= std::min((nxpr_all
-1) / (nxpr_use
-1), (nfpr_all
-1) / (nfpr_use
-1));
143 vlmax
= std::min(vlmax
, MAX_UTS
);
146 void processor_t::setvl(int vlapp
)
148 vl
= std::min(vlmax
, vlapp
);
151 void processor_t::step(size_t n
, bool noisy
)
158 uint32_t interrupts
= (cause
& CAUSE_IP
) >> CAUSE_IP_SHIFT
;
159 interrupts
&= (sr
& SR_IM
) >> SR_IM_SHIFT
;
160 if(interrupts
&& (sr
& SR_ET
))
161 take_trap(trap_interrupt
,noisy
);
163 insn_t insn
= mmu
.load_insn(pc
, sr
& SR_EC
);
165 reg_t npc
= pc
+ insn_length(insn
);
175 if(count
++ == compare
)
176 cause
|= 1 << (TIMER_IRQ
+CAUSE_IP_SHIFT
);
185 catch(vt_command_t cmd
)
187 if (cmd
== vt_command_stop
)
192 void processor_t::take_trap(trap_t t
, bool noisy
)
194 demand(t
< NUM_TRAPS
, "internal error: bad trap number %d", int(t
));
195 demand(sr
& SR_ET
, "error mode on core %d!\ntrap %s, pc 0x%016llx",
196 id
, trap_name(t
), (unsigned long long)pc
);
198 printf("core %3d: trap %s, pc 0x%016llx\n",
199 id
, trap_name(t
), (unsigned long long)pc
);
201 set_sr((((sr
& ~SR_ET
) | SR_S
) & ~SR_PS
) | ((sr
& SR_S
) ? SR_PS
: 0));
202 cause
= (cause
& ~CAUSE_EXCCODE
) | (t
<< CAUSE_EXCCODE_SHIFT
);
205 badvaddr
= mmu
.get_badvaddr();
208 void processor_t::disasm(insn_t insn
, reg_t pc
)
210 printf("core %3d: 0x%016llx (0x%08x) ",id
,(unsigned long long)pc
,insn
.bits
);
212 #ifdef RISCV_HAVE_LIBOPCODES
213 disassemble_info info
;
214 INIT_DISASSEMBLE_INFO(info
, stdout
, fprintf
);
215 info
.flavour
= bfd_target_unknown_flavour
;
216 info
.arch
= bfd_arch_mips
;
217 info
.mach
= 101; // XXX bfd_mach_mips_riscv requires modified bfd.h
218 info
.endian
= BFD_ENDIAN_LITTLE
;
219 info
.buffer
= (bfd_byte
*)&insn
;
220 info
.buffer_length
= sizeof(insn
);
221 info
.buffer_vma
= pc
;
223 int ret
= print_insn_little_mips(pc
, &info
);
224 demand(ret
== (INSN_IS_RVC(insn
.bits
) ? 2 : 4), "disasm bug!");