-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdis.c
91 lines (86 loc) · 1.31 KB
/
dis.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
#include "yo.h"
static int dismode[Aend] = {
/* Aimm */ AIMM,
/* Amp */ AMP,
/* Ampind */ AMP|AIND,
/* Afp */ AFP,
/* Afpind */ AFP|AIND,
/* Apc */ AIMM,
/* Adesc */ AIMM,
/* Aoff */ AIMM,
/* Anoff */ AIMM,
/* Aerr */ AXXX,
/* Anone */ AXXX,
/* Aldt */ AIMM,
};
static int disregmode[Aend] = {
/* Aimm */ AXIMM,
/* Amp */ AXINM,
/* Ampind */ AXNON,
/* Afp */ AXINF,
/* Afpind */ AXNON,
/* Apc */ AXIMM,
/* Adesc */ AXIMM,
/* Aoff */ AXIMM,
/* Anoff */ AXIMM,
/* Aerr */ AXNON,
/* Anone */ AXNON,
/* Aldt */ AXIMM,
};
void
wr1(FILE *f, u8 v)
{
fwrite(&v, 1, 1, f);
}
void
wr2(FILE *f, u16 v)
{
fwrite(&v, 1, 2, f);
}
void
wr4(FILE *f, i32 v)
{
fwrite(&v, 1, 4, f);
}
void
disaddr(FILE* f, i32 m, Addr *a)
{
i32 val = 0;
switch(m){
case Anone:
return;
case Aimm:
val = a->offset;
break;
case Afp:
val = a->reg;
break;
case Afpind:
wr2(f, a->reg);
wr2(f, a->offset);
return;
case Adesc:
val = a->offset+a->reg;
break;
case Apc:
val = a->offset;
break;
default:
assert(0);
}
wr4(f, val);
}
int
disinst(FILE *f, Inst *in)
{
int n = 0;
for(; in != nil; in = in->next){
n += 1;
wr1(f, in->op);
wr1(f, SRC(dismode[in->sm]) | DST(dismode[in->dm]) | disregmode[in->mm]);
disaddr(f, in->mm, &in->m);
disaddr(f, in->sm, &in->s);
disaddr(f, in->dm, &in->d);
}
return n;
}