ins.c - scc - simple c99 compiler
(HTM) git clone git://git.simple-cc.org/scc
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
ins.c (3344B)
---
1 #include <string.h>
2
3 #include <scc/mach.h>
4 #include <scc/scc.h>
5
6 #include "as.h"
7
8 extern Section *sabs, *sbss, *sdata, *stext;
9
10 enum {
11 EQU,
12 COMMON,
13 SIZE,
14 XSTRING,
15 ASCII,
16 TYPE,
17 };
18
19 static void
20 reloc(Symbol *sym,
21 unsigned flags,
22 unsigned size,
23 unsigned nbits,
24 unsigned shift)
25 {
26 }
27
28 char *
29 tobytes(TUINT v, int nbytes, int inc)
30 {
31 static char buf[sizeof(TUINT)];
32 int idx;
33
34 idx = (inc < 0) ? nbytes-1 : 0;
35 while (nbytes--) {
36 buf[idx] = v;
37 idx += inc;
38 v >>= 8;
39 }
40
41 if (v)
42 error("overflow in immediate value");
43 return buf;
44 }
45
46 void
47 noargs(Op *op, Node **args)
48 {
49 emit(op->bytes, op->size);
50 }
51
52 static void
53 xstring(int which, Node **args)
54 {
55 Node *np;
56 char *s;
57 size_t len;
58
59 while (np = *args++) {
60 s = np->sym->name;
61 len = strlen(s);
62 len += which == XSTRING;
63 emit(s, len);
64 }
65 }
66
67 void
68 string(Op *op, Node **args)
69 {
70 xstring(STRING, args);
71 }
72
73 void
74 ascii(Op *op, Node **args)
75 {
76 xstring(STRING, args);
77 }
78
79 void
80 def(Node **args, int siz)
81 {
82 Node *np;
83
84 while (np = *args++) {
85 Symbol *sym = np->sym;
86
87 if ((sym->flags & FABS) == 0)
88 reloc(sym, 0, siz, siz * 8, 0);
89 emit(tobytes(sym->value, siz, endian), siz);
90 }
91 }
92
93 void
94 defb(Op *op, Node **args)
95 {
96 def(args, 1);
97 }
98
99 void
100 defw(Op *op, Node **args)
101 {
102 def(args, 2);
103 }
104
105 void
106 defd(Op *op, Node **args)
107 {
108 def(args, 4);
109 }
110
111 void
112 defq(Op *op, Node **args)
113 {
114 def(args, 8);
115 }
116
117 static void
118 symexp(int which, Op *op, Node **args)
119 {
120 Symbol *sym, *exp;
121 static char *cmds[] = {
122 [EQU] = "equ",
123 [COMMON] = "common",
124 [SIZE] = "size",
125 };
126 char *cmd = cmds[which];
127
128 if (args[1]) {
129 sym = args[0]->sym;
130 exp = args[1]->sym;
131 } else if (linesym) {
132 sym = linesym;
133 exp = args[0]->sym;
134 } else {
135 error("%s pseudo instruction lacks a label", cmd);
136 }
137
138 if ((exp->flags & FABS) == 0)
139 error("%s expression is not an absolute expression", cmd);
140
141 switch (which) {
142 case EQU:
143 if (pass == 1 && (sym->flags & FDEF))
144 error("redefinition of symbol '%s'", sym->name);
145 sym->value = exp->value;
146 sym->flags |= FDEF;
147 break;
148 case COMMON:
149 sym->flags |= FCOMMON;
150 case SIZE:
151 sym->size = exp->value;
152 break;
153 case TYPE:
154 sym->dtype = exp->value;
155 break;
156 }
157 }
158
159 void
160 equ(Op *op, Node **args)
161 {
162 symexp(EQU, op, args);
163 }
164
165 void
166 common(Op *op, Node **args)
167 {
168 symexp(COMMON, op, args);
169 }
170
171 void
172 size(Op *op, Node **args)
173 {
174 symexp(SIZE, op, args);
175 }
176
177 void
178 type(Op *op, Node **args)
179 {
180 symexp(TYPE, op, args);
181 }
182
183 void
184 section(Op *op, Node **args)
185 {
186 Symbol *sym = args[0]->sym;
187 char *attr = NULL;
188
189 if (args[1])
190 attr = args[1]->sym->name;
191
192 defsec(sym->name, attr);
193 }
194
195 void
196 text(Op *op, Node **args)
197 {
198 cursec = stext;
199 }
200
201 void
202 data(Op *op, Node **args)
203 {
204 cursec = sdata;
205 }
206
207 void
208 bss(Op *op, Node **args)
209 {
210 cursec = sbss;
211 }
212
213 void
214 extrn(Op *op, Node **args)
215 {
216 Symbol *sym = args[0]->sym;
217
218 sym->flags |= FEXTERN;
219 }
220
221 void
222 global(Op *op, Node **args)
223 {
224 Symbol *sym = args[0]->sym;
225
226 sym->flags |= FGLOBAL;
227 }
228
229 void
230 align(Op *op, Node **args)
231 {
232 Symbol *sym = args[0]->sym;
233 TUINT pcal, pc, al;
234
235 if ((sym->flags & FABS) == 0)
236 error("align expression is not an absolute expression");
237 if ((al = sym->value) == 0)
238 return;
239
240 al--;
241 pc = getpc();
242 pcal = pc+al & ~al;
243
244 for (al = pcal - pc; al > 0; --al)
245 emit((char []) {0}, 1);
246 }
247
248 void
249 end(Op *op, Node **args)
250 {
251 endpass = 1;
252 }
253
254 void
255 include(Op *op, Node **args)
256 {
257 addinput(args[0]->sym->name);
258 }