-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrace.c
142 lines (120 loc) · 2.99 KB
/
trace.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/** Code by @author Wonsun Ahn
*
* Functions to read and write the trace file.
*/
#include <inttypes.h>
#include <assert.h>
#include "trace.h"
#include "CPU.h"
FILE *trace_fd;
static int trace_buf_ptr;
static int trace_buf_end;
static instruction *trace_buf;
static FILE *out_fd;
int is_big_endian(void)
{
union {
uint32_t i;
char c[4];
} bint = { 0x01020304 };
return bint.c[0] == 1;
}
uint32_t my_ntohl(uint32_t x)
{
unsigned char *s = (unsigned char *)&x;
return (uint32_t)(s[3] << 24 | s[2] << 16 | s[1] << 8 | s[0]);
}
void trace_init()
{
trace_buf = (instruction *) malloc(sizeof(instruction) * TRACE_BUFSIZE);
if (!trace_buf) {
fprintf(stdout, "** trace_buf not allocated\n");
exit(-1);
}
trace_buf_ptr = 0;
trace_buf_end = 0;
}
void trace_uninit()
{
free(trace_buf);
fclose(trace_fd);
}
int trace_get_item(instruction **item)
{
int n_items;
if (trace_buf_ptr == trace_buf_end) { /* if no more unprocessed items in the trace buffer, get new data */
n_items = fread(trace_buf, sizeof(instruction), TRACE_BUFSIZE, trace_fd);
if (!n_items) return 0; /* if no more items in the file, we are done */
trace_buf_ptr = 0;
trace_buf_end = n_items; /* n_items were read and placed in trace buffer */
}
*item = &trace_buf[trace_buf_ptr]; /* read a new trace item for processing */
trace_buf_ptr++;
if (is_big_endian()) {
(*item)->PC = my_ntohl((*item)->PC);
(*item)->Addr = my_ntohl((*item)->Addr);
}
return 1;
}
int write_trace(instruction item, char *fname)
{
out_fd = fopen(fname, "a");
int n_items;
if (is_big_endian()) {
(&item)->PC = my_ntohl((&item)->PC);
(&item)->Addr = my_ntohl((&item)->Addr);
}
n_items = fwrite(&item, sizeof(instruction), 1, out_fd);
fclose(out_fd);
if (!n_items) return 0; /* if no more items in the file, we are done */
return 1;
}
char* get_instruction_string(dynamic_inst dinst, Format format)
{
static char buffer[100];
instruction inst = dinst.inst;
const char *name;
switch(inst.type) {
case ti_NOP:
name = "NOP";
break;
case ti_RTYPE:
name = "RTYPE";
break;
case ti_ITYPE:
name = "ITYPE";
break;
case ti_LOAD:
name = "LOAD";
break;
case ti_STORE:
name = "STORE";
break;
case ti_BRANCH:
name = "BRANCH";
break;
case ti_JTYPE:
name = "JTYPE";
break;
case ti_SPECIAL:
name = "SPECIAL";
break;
case ti_JRTYPE:
name = "JRTYPE";
break;
default:
assert(0);
}
switch(format) {
case SHORT_FORM:
snprintf(buffer, 100, "%7s: (Seq: %8d)(Regs: %3d, %3d, %3d)", name, dinst.seq, inst.dReg, inst.sReg_a, inst.sReg_b);
break;
case LONG_FORM:
snprintf(buffer, 100, "%7s: (Seq: %8d)(Regs: %3d, %3d, %3d)(Addr: %u)(PC: %u)", name, dinst.seq, inst.dReg, inst.sReg_a, inst.sReg_b, inst.Addr, inst.PC);
break;
case ADDR_ONLY:
snprintf(buffer, 100, "%s: (Seq: %8d)(Addr: %u)(PC: %u)", name, dinst.seq, inst.Addr, inst.PC);
break;
}
return buffer;
}