[xcc] argc/argv work for 32b programs
[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 | (support_64bit ? SR_KX : 0));
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 | SR_UX);
45
46 gprlen = ((sr & SR_S) ? (sr & SR_KX) : (sr & SR_UX)) ? 64 : 32;
47 }
48
49 void processor_t::set_fsr(uint32_t val)
50 {
51 fsr = val & ~FSR_ZERO;
52 }
53
54 void processor_t::step(size_t n, bool noisy)
55 {
56 size_t i = 0;
57 while(1) try
58 {
59 for( ; i < n; i++)
60 {
61 insn_t insn = mmu.load_insn(pc);
62
63 reg_t npc = pc+sizeof(insn);
64
65 if(noisy)
66 disasm(insn,pc);
67
68 #include "execute.h"
69
70 pc = npc;
71 R[0] = 0;
72
73 counters[0]++;
74 }
75 return;
76 }
77 catch(trap_t t)
78 {
79 i++;
80 take_trap(t,noisy);
81 }
82 }
83
84 void processor_t::take_trap(trap_t t, bool noisy)
85 {
86 demand(t < NUM_TRAPS, "internal error: bad trap number %d", int(t));
87 demand(sr & SR_ET, "error mode on core %d!\ntrap %s, pc 0x%016llx",
88 id, trap_name(t), (unsigned long long)pc);
89 if(noisy)
90 printf("core %3d: trap %s, pc 0x%016llx\n",
91 id, trap_name(t), (unsigned long long)pc);
92
93 set_sr((((sr & ~SR_ET) | SR_S) & ~SR_PS) | ((sr & SR_S) ? SR_PS : 0));
94 epc = pc;
95 pc = ebase + t*128;
96 badvaddr = mmu.get_badvaddr();
97 }
98
99 void processor_t::disasm(insn_t insn, reg_t pc)
100 {
101 printf("core %3d: 0x%016llx (0x%08x) ",id,(unsigned long long)pc,insn.bits);
102
103 #ifdef RISCV_HAVE_LIBOPCODES
104 disassemble_info info;
105 INIT_DISASSEMBLE_INFO(info, stdout, fprintf);
106 info.flavour = bfd_target_unknown_flavour;
107 info.arch = bfd_arch_mips;
108 info.mach = 101; // XXX bfd_mach_mips_riscv requires modified bfd.h
109 info.endian = BFD_ENDIAN_LITTLE;
110 info.buffer = (bfd_byte*)&insn;
111 info.buffer_length = sizeof(insn);
112 info.buffer_vma = pc;
113
114 demand(print_insn_little_mips(pc, &info) == sizeof(insn), "disasm bug!");
115 #else
116 printf("unknown");
117 #endif
118 printf("\n");
119 }