-
Notifications
You must be signed in to change notification settings - Fork 4
/
pseudo_ops.cpp
121 lines (112 loc) · 2.75 KB
/
pseudo_ops.cpp
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
#include "pseudo_ops.hpp"
#include "assembler.hpp"
#include <unordered_map>
extern std::string load_file(const std::string&, const char*);
static PseudoOp DATA_128 {
.handler = [] (Assembler& a) {
auto& constant = a.next<TK_CONSTANT> ();
__uint128_t value = constant.u64;
a.align_with_labels(16);
a.add_output(OT_DATA, &value, sizeof(value));
}
};
static PseudoOp DATA_64 {
.handler = [] (Assembler& a) {
auto& constant = a.next<TK_CONSTANT> ();
a.align_with_labels(8);
a.add_output(OT_DATA, &constant.u64, sizeof(uint64_t));
}
};
static PseudoOp DATA_32 {
.handler = [] (Assembler& a) {
auto& constant = a.next<TK_CONSTANT> ();
a.align_with_labels(4);
uint32_t value = constant.u64;
a.add_output(OT_DATA, &value, sizeof(value));
}
};
static PseudoOp DATA_16 {
.handler = [] (Assembler& a) {
auto& constant = a.next<TK_CONSTANT> ();
a.align_with_labels(2);
uint16_t value = constant.u64;
a.add_output(OT_DATA, &value, sizeof(value));
}
};
static PseudoOp DATA_8 {
.handler = [] (Assembler& a) {
auto& constant = a.next<TK_CONSTANT> ();
uint8_t value = constant.u64;
a.add_output(OT_DATA, &value, sizeof(value));
}
};
static PseudoOp RESV_8 {
.handler = [] (Assembler& a) {
auto& times = a.next<TK_CONSTANT> ();
a.allocate(times.u64);
}
};
static PseudoOp RESV_16 {
.handler = [] (Assembler& a) {
auto& times = a.next<TK_CONSTANT> ();
a.align_with_labels(2);
a.allocate(times.u64 * sizeof(uint16_t));
}
};
static PseudoOp RESV_32 {
.handler = [] (Assembler& a) {
auto& times = a.next<TK_CONSTANT> ();
a.align_with_labels(4);
a.allocate(times.u64 * sizeof(uint32_t));
}
};
static PseudoOp RESV_64 {
.handler = [] (Assembler& a) {
auto& times = a.next<TK_CONSTANT> ();
a.align_with_labels(8);
a.allocate(times.u64 * sizeof(uint64_t));
}
};
static PseudoOp RESV_128 {
.handler = [] (Assembler& a) {
auto& times = a.next<TK_CONSTANT> ();
a.align_with_labels(16);
a.allocate(times.u64 * sizeof(__uint128_t));
}
};
static PseudoOp INCBIN {
.handler = [] (Assembler& a) {
auto& filename = a.next<TK_STRING> ();
auto contents = load_file(filename.value, a.realpath());
a.align_with_labels(1);
a.add_output(OT_DATA, contents.data(), contents.size());
}
};
static const std::unordered_map<std::string, PseudoOp> pseudo_list =
{
{"db", DATA_8},
{"dh", DATA_16},
{"dw", DATA_32},
{"dd", DATA_64},
{"dq", DATA_128},
{"resb", RESV_8},
{"resh", RESV_16},
{"resw", RESV_32},
{"resd", RESV_64},
{"resq", RESV_128},
{"incbin", INCBIN},
};
Token pseudo_op(const std::string& value)
{
Token tk;
tk.value = value;
auto it = pseudo_list.find(value);
if (it != pseudo_list.end())
{
tk.type = TK_PSEUDOOP;
tk.pseudoop = &it->second;
return tk;
}
tk.type = TK_SYMBOL;
return tk;
}