2 Copyright (c) 2020 Peter Hsu. All Rights Reserved. See LICENCE file for details.
19 struct insnAttr_t insnAttr
[] = {
20 #include "opcodes_attr.h"
23 struct insnSpace_t insnSpace
;
25 const char* regName
[] = {
26 "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2",
27 "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5",
28 "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7",
29 "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6",
30 "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7",
31 "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5",
32 "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
33 "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11",
40 dieif(insnSpace
.base
==0, "insnSpace_init() base, bound not initialized");
41 assert(insnSpace
.base
< insnSpace
.bound
);
43 long nelts
= (insnSpace
.bound
- insnSpace
.base
) / 2;
44 insnSpace
.insn_array
= (struct insn_t
*)mmap(0, nelts
*sizeof(struct insn_t
), PROT_READ
|PROT_WRITE
, MAP_PRIVATE
|MAP_ANONYMOUS
, -1, 0);
45 assert(insnSpace
.insn_array
);
46 memset(insnSpace
.insn_array
, 0, nelts
*sizeof(struct insn_t
));
47 for (Addr_t pc
=insnSpace
.base
; pc
<insnSpace
.bound
; pc
+=2)
48 decode_instruction(&insnSpace
.insn_array
[(pc
-insnSpace
.base
)/2], pc
);
52 static inline struct insn_t
fmtC(enum Opcode_t op
, signed char rd
, signed char rs1
, int constant
)
58 i
.op_constant
= constant
;
62 static inline struct insn_t
fmtR(enum Opcode_t op
, signed char rd
, signed char rs1
, signed char rs2
, signed char rs3
, short immed
)
74 void decode_instruction( const struct insn_t
* cp
, Addr_t PC
)
76 struct insn_t
* p
= (struct insn_t
*)cp
;
77 int ir
= *((int*)(PC
));
78 #include "decode_insn.h"
79 p
->op_code
= Op_illegal
; // no match
84 int format_pc(char* buf
, int width
, Addr_t pc
)
89 if (find_pc(pc
, &func
, &offset
)) {
90 snprintf(buf
, width
, "%21s", func
);
91 snprintf(buf
+21, width
, "+%-5ld ", offset
);
94 snprintf(buf
, width
, "%21s %5s ", "UNKNOWN", "");
97 snprintf(buf
, width
, "%21s %-5s ", "INVALID", "");
101 void print_pc( long pc
, FILE* f
)
104 format_pc(buf
, 29, pc
);
105 fprintf(f
, "%-28s", buf
);
110 int format_insn(char* buf
, const struct insn_t
* p
, Addr_t pc
, unsigned int image
)
113 if (shortOp(p
->op_code
))
114 n
= sprintf(buf
, "%8lx %04x %-16s", pc
, image
&0xffff, insnAttr
[p
->op_code
].name
);
116 n
= sprintf(buf
, "%8lx %08x %-16s", pc
, image
, insnAttr
[p
->op_code
].name
);
118 switch (p
->op_code
) {
119 #include "disasm_insn.h"
124 void print_insn(Addr_t pc
, FILE* f
)
127 format_insn(buf
, insn(pc
), pc
, *((unsigned int*)pc
));
128 fprintf(f
, "%s\n", buf
);
133 void print_registers(struct reg_t reg
[], FILE* f
)
136 for (int i
=0; i
<64; i
++) {
137 fprintf(f
, "%-4s: 0x%016lx ", regName
[i
], reg
[i
].ul
);
144 static struct options_t
* opt_ptr
;
145 static const char* usage_ptr
;
149 fprintf(stderr
, "Usage : %s\n", usage
);
150 for (int i
=0; opt
[i
].name
; ++i
) {
151 int len
= strlen(opt
[i
].name
);
152 fprintf(stderr
, " %-14s %s ", opt
[i
].name
, opt
[i
].h
);
153 if (opt
[i
].name
[len
-2] == '=')
154 switch (opt
[i
].name
[len
-1]) {
157 fprintf(stderr
, "[%s]\n", opt
[i
].ds
);
159 fprintf(stderr
, "[none]\n");
162 fprintf(stderr
, "[%ld]\n", opt
[i
].di
);
165 fprintf(stderr
, "Bad option %s\n", opt
[i
].name
);
169 fprintf(stderr
, "\n");
175 int parse_options(const char** argv
)
177 /* initialize default values */
178 for (int i
=0; opt
[i
].name
; ++i
) {
179 int len
= strlen(opt
[i
].name
) - 1;
180 if (opt
[i
].name
[len
-1] == '=')
181 switch (opt
[i
].name
[len
]) {
182 case 's': *opt
[i
].s
= opt
[i
].ds
; break;
183 case 'i': *opt
[i
].i
= opt
[i
].di
; break;
184 default: fprintf(stderr
, "Bad option %s\n", opt
[i
].name
); exit(0);
187 *opt
[i
].b
= 0; /* flag not given */
191 while (argv
[numargs
] && argv
[numargs
][0]=='-') {
192 const char* arg
= argv
[numargs
++];
193 if (strcmp(arg
, "--help") == 0)
195 for (int i
=0; opt
[i
].name
; ++i
) {
196 int len
= strlen(opt
[i
].name
) - 1;
197 if (opt
[i
].name
[len
-1] == '=') {
198 if (strncmp(opt
[i
].name
, arg
, len
-1) == 0) {
199 switch (opt
[i
].name
[len
]) {
200 case 's': *opt
[i
].s
= (arg
+len
); break;
201 case 'i': *opt
[i
].i
= atoi(arg
+len
); break;
206 else if (strcmp(arg
, opt
[i
].name
) == 0) {
207 *opt
[i
].b
= opt
[i
].bv
;
211 fprintf(stderr
, "Illegal option %s\n", arg
);