scc

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

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

  1#include <stdlib.h>
  2
  3#include <scc/mach.h>
  4#include <scc/scc.h>
  5
  6#include "../as.h"
  7#include "proc.h"
  8
  9/*
 10 * This code is derived from PowerISA_V2.06B_V2_PUBLIC document.
 11 * All the names used in the specification are preserved in
 12 * this code.
 13 */
 14
 15static int
 16getclass(Node *np)
 17{
 18	if (np->addr != AREG)
 19		return 0;
 20
 21	switch (np->sym->value) {
 22	case AREG_R0:
 23	case AREG_R1:
 24	case AREG_R2:
 25	case AREG_R3:
 26	case AREG_R4:
 27	case AREG_R5:
 28	case AREG_R6:
 29	case AREG_R7:
 30	case AREG_R8:
 31	case AREG_R9:
 32	case AREG_R10:
 33	case AREG_R11:
 34	case AREG_R12:
 35	case AREG_R13:
 36	case AREG_R14:
 37	case AREG_R15:
 38	case AREG_R16:
 39	case AREG_R17:
 40	case AREG_R18:
 41	case AREG_R19:
 42	case AREG_R20:
 43	case AREG_R21:
 44	case AREG_R22:
 45	case AREG_R23:
 46	case AREG_R24:
 47	case AREG_R25:
 48	case AREG_R26:
 49	case AREG_R27:
 50	case AREG_R29:
 51	case AREG_R30:
 52	case AREG_R31:
 53		return GPRSCLASS;
 54	default:
 55		abort();
 56	}
 57}
 58
 59int
 60match(Op *op, Node **args)
 61{
 62	unsigned char *p;
 63	int arg, class, rep, opt;
 64	Node *np;
 65
 66	if (!op->args)
 67		return args == NULL;
 68
 69	opt = rep = 0;
 70	for (p = op->args; arg = *p; ++p) {
 71		if (rep)
 72			--p;
 73		if ((np = *args++) == NULL)
 74			return (rep|opt) != 0;
 75
 76		switch (arg) {
 77		case AOPT:
 78			opt = 1;
 79			break;
 80		case AREP:
 81			rep = 1;
 82			break;
 83		case AREG_GPRSCLASS:
 84			class = GPRSCLASS;
 85		check_class:
 86			if ((getclass(np) & class) == 0)
 87				return 0;
 88			break;
 89		case AIMM2:
 90		case AIMM5:
 91		case AIMM8:
 92		case AIMM16:
 93		case AIMM32:
 94		case AIMM64:
 95			if (np->addr != AIMM)
 96				return 0;
 97			if (toobig(np, arg))
 98				error("overflow in immediate operand");
 99			break;
100		case ASYM:
101			if (np->op != IDEN)
102				return 0;
103			break;
104		case ADIRECT:
105		case ASTR:
106			if (np->addr != arg)
107				return 0;
108			break;
109		default:
110			abort();
111		}
112	}
113
114	return *args == NULL;
115}
116
117Node *
118moperand(void)
119{
120	abort();
121}
122
123static void
124emit_packed(unsigned long ins)
125{
126	unsigned char buff[4];
127
128	if (endian == BIG_ENDIAN) {
129		buff[0] = ins >> 24;
130		buff[1] = ins >> 16;
131		buff[2] = ins >> 8;
132		buff[3] = ins;
133	} else {
134		buff[0] = ins;
135		buff[1] = ins >> 8;
136		buff[2] = ins >> 16;
137		buff[3] = ins >> 24;
138	}
139
140	emit(buff, 4);
141}
142
143void
144i_form(Op *op, Node **args)
145{
146	unsigned long ins, opcd, li, aa, lk;
147	long long dst;
148	long long max = 1l << 23;
149	long long min = -(1l << 23);
150
151	opcd = op->bytes[0];
152	aa = op->bytes[1];
153	lk = op->bytes[2];
154
155	dst = args[0]->sym->value;
156	if (dst & 0x3)
157		error("unaligned branch");
158	if (aa)
159		dst -= getpc() - 4;
160	if (dst < min || dst > max)
161		error("out of range branch");
162
163	li = dst;
164	li >>= 2;
165	ins = opcd<<26 | li<<2 | aa<<1 | lk;
166	emit_packed(ins);
167}
168
169void
170b_form(Op *op, Node **args)
171{
172	unsigned long ins, opcd, bo, bi, bd, aa, lk;
173	long long dst;
174	long long max = 1l << 13;
175	long long min = -(1l << 13);
176
177	opcd = op->bytes[0];
178	aa = op->bytes[1];
179	lk = op->bytes[2];
180
181	bo = args[0]->sym->value;
182	bi = args[1]->sym->value;
183
184	dst = args[2]->sym->value;
185	if (dst & 0x3)
186		error("unaligned branch");
187	if (aa)
188		dst -= getpc() - 4;
189
190	if (dst < min || dst > max)
191		error("out of range branch");
192	bd = dst;
193	bd >>= 2;
194
195	ins = opcd<<26 | bo<<21 | bi<<16 | bd<<11 | aa<<1 | lk;
196	emit_packed(ins);
197}
198
199void
200sc_form(Op *op, Node **args)
201{
202	abort();
203}
204
205void
206d_form(Op *op, Node **args)
207{
208	abort();
209}
210
211void
212ds_form(Op *op, Node **args)
213{
214	abort();
215}
216
217void
218dq_form(Op *op, Node **args)
219{
220	abort();
221}
222
223void
224x_form(Op *op, Node **args)
225{
226	abort();
227}
228
229void
230xl_form(Op *op, Node **args)
231{
232	unsigned long ins, bo, bi, bh, lk;
233	unsigned long opcd1, opcd2;
234	long long dst;
235
236	opcd1 = op->bytes[0];
237	opcd2 = op->bytes[1]<<8 | op->bytes[2];
238	lk = op->bytes[3];
239
240	bo = args[0]->sym->value;
241	bi = args[1]->sym->value;
242	bh = args[2]->sym->value;
243
244	ins = opcd1<<26 | bo<<21 | bi<<16 | bh<<11 | opcd2<<1 | lk;
245	emit_packed(ins);
246}
247
248void
249xfx_form(Op *op, Node **args)
250{
251	abort();
252}
253
254void
255xlfdorm_form(Op *op, Node **args)
256{
257	abort();
258}
259
260void
261xx1_form(Op *op, Node **args)
262{
263	abort();
264}
265
266void
267xx2_form(Op *op, Node **args)
268{
269	abort();
270}
271
272void
273xx3_form(Op *op, Node **args)
274{
275	abort();
276}
277
278void
279xx4_form(Op *op, Node **args)
280{
281	abort();
282}
283
284void
285xs_form(Op *op, Node **args)
286{
287	abort();
288}
289
290void
291xo_form(Op *op, Node **args)
292{
293	abort();
294}
295
296void
297a_form(Op *op, Node **args)
298{
299	abort();
300}
301
302void
303m_form(Op *op, Node **args)
304{
305	abort();
306}
307
308void
309md_form(Op *op, Node **args)
310{
311	abort();
312}
313
314void
315mds_form(Op *op, Node **args)
316{
317	abort();
318}
319
320void
321va_form(Op *op, Node **args)
322{
323	abort();
324}
325
326void
327vc_form(Op *op, Node **args)
328{
329	abort();
330}
331
332void
333vx_form(Op *op, Node **args)
334{
335	abort();
336}
337
338void
339evs_form(Op *op, Node **args)
340{
341	abort();
342}
343
344void
345z22_form(Op *op, Node **args)
346{
347	abort();
348}
349
350void
351z23_form(Op *op, Node **args)
352{
353	abort();
354}