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