scc

A fork of https://git.simple-cc.org/scc/ for Qute

git clone https://git.8pit.net/scc.git

  1#include <string.h>
  2
  3#include <scc/mach.h>
  4#include <scc/scc.h>
  5
  6#include "as.h"
  7
  8extern Section *sabs, *sbss, *sdata, *stext;
  9
 10enum {
 11	EQU,
 12	COMMON,
 13	SIZE,
 14	XSTRING,
 15	ASCII,
 16	TYPE,
 17};
 18
 19static void
 20reloc(Symbol *sym,
 21       unsigned flags,
 22       unsigned size,
 23       unsigned nbits,
 24       unsigned shift)
 25{
 26}
 27
 28unsigned char *
 29tobytes(unsigned long long v, int nbytes, int inc)
 30{
 31	static unsigned char buf[sizeof(unsigned long long)];
 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
 46void
 47noargs(Op *op, Node **args)
 48{
 49	emit(op->bytes, op->size);
 50}
 51
 52static void
 53xstring(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((unsigned char *)s, len);
 64	}
 65}
 66
 67void
 68string(Op *op, Node **args)
 69{
 70	xstring(STRING, args);
 71}
 72
 73void
 74ascii(Op *op, Node **args)
 75{
 76	xstring(STRING, args);
 77}
 78
 79void
 80def(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
 93void
 94defb(Op *op, Node **args)
 95{
 96	def(args, 1);
 97}
 98
 99void
100defw(Op *op, Node **args)
101{
102	def(args, 2);
103}
104
105void
106defd(Op *op, Node **args)
107{
108	def(args, 4);
109}
110
111void
112defq(Op *op, Node **args)
113{
114	def(args, 8);
115}
116
117static void
118symexp(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
159void
160equ(Op *op, Node **args)
161{
162	symexp(EQU, op, args);
163}
164
165void
166common(Op *op, Node **args)
167{
168	symexp(COMMON, op, args);
169}
170
171void
172size(Op *op, Node **args)
173{
174	symexp(SIZE, op, args);
175}
176
177void
178type(Op *op, Node **args)
179{
180	symexp(TYPE, op, args);
181}
182
183void
184section(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
195void
196text(Op *op, Node **args)
197{
198	cursec = stext;
199}
200
201void
202data(Op *op, Node **args)
203{
204	cursec = sdata;
205}
206
207void
208bss(Op *op, Node **args)
209{
210	cursec = sbss;
211}
212
213void
214extrn(Op *op, Node **args)
215{
216	Symbol *sym = args[0]->sym;
217
218	sym->flags |= FEXTERN;
219}
220
221void
222global(Op *op, Node **args)
223{
224	Symbol *sym = args[0]->sym;
225
226	sym->flags |= FGLOBAL;
227}
228
229void
230align(Op *op, Node **args)
231{
232	Symbol *sym = args[0]->sym;
233	unsigned long long 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((unsigned char []) {0}, 1);
246}
247
248void
249end(Op *op, Node **args)
250{
251	endpass = 1;
252}
253
254void
255include(Op *op, Node **args)
256{
257	addinput(args[0]->sym->name);
258}