Reorganized directory structure
[riscv-isa-sim.git] / riscv / processor.cc
1 #include <bfd.h>
2 #include <dis-asm.h>
3 #include <cstdlib>
4 #include <iostream>
5 #include "processor.h"
6 #include "common.h"
7 #include "config.h"
8
9 processor_t::processor_t(int _id, char* _mem, size_t _memsz)
10 : id(_id), mmu(_mem,_memsz)
11 {
12 memset(R,0,sizeof(R));
13 pc = 0;
14 ebase = 0;
15 epc = 0;
16 badvaddr = 0;
17 set_sr(SR_S);
18
19 memset(counters,0,sizeof(counters));
20 }
21
22 void processor_t::set_sr(uint32_t val)
23 {
24 sr = val & ~SR_ZERO;
25 if(support_64bit)
26 sr |= SR_KX;
27 else
28 sr &= ~(SR_KX | SR_UX);
29
30 gprlen = ((sr & SR_S) ? (sr & SR_KX) : (sr & SR_UX)) ? 64 : 32;
31 }
32
33 void processor_t::step(size_t n, bool noisy)
34 {
35 size_t i = 0;
36 while(1) try
37 {
38 for( ; i < n; i++)
39 {
40 insn_t insn = mmu.load_insn(pc);
41
42 int opcode = insn.rtype.opcode;
43 int funct = insn.rtype.funct;
44 reg_t npc = pc+sizeof(insn);
45
46 if(noisy)
47 disasm(insn,pc);
48
49 #include "execute.h"
50
51 pc = npc;
52 R[0] = 0;
53
54 counters[0]++;
55 }
56 return;
57 }
58 catch(trap_t t)
59 {
60 i++;
61 take_trap(t);
62 }
63 }
64
65 void processor_t::take_trap(trap_t t)
66 {
67 demand(t < NUM_TRAPS, "internal error: bad trap number %d", int(t));
68 demand(sr & SR_ET, "error mode on core %d!\ntrap %s, pc 0x%016llx",
69 id, trap_name(t), (unsigned long long)pc);
70
71 set_sr((((sr & ~SR_ET) | SR_S) & ~SR_PS) | ((sr & SR_S) ? SR_PS : 0));
72 epc = pc;
73 pc = ebase + t*128;
74 badvaddr = mmu.get_badvaddr();
75 }
76
77 void processor_t::disasm(insn_t insn, reg_t pc)
78 {
79 printf("core %3d: 0x%016llx (0x%08x) ",id,(unsigned long long)pc,insn.bits);
80
81 #ifdef RISCV_HAVE_LIBOPCODES
82 disassemble_info info;
83 INIT_DISASSEMBLE_INFO(info, stdout, fprintf);
84 info.flavour = bfd_target_unknown_flavour;
85 info.arch = bfd_arch_mips;
86 info.mach = 101; // XXX bfd_mach_mips_riscv requires modified bfd.h
87 info.endian = BFD_ENDIAN_LITTLE;
88 info.buffer = (bfd_byte*)&insn;
89 info.buffer_length = sizeof(insn);
90 info.buffer_vma = pc;
91
92 demand(print_insn_little_mips(pc, &info) == sizeof(insn), "disasm bug!");
93 #else
94 printf("unknown");
95 #endif
96 printf("\n");
97 }