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