scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

proc.c (1750B)


      1 static char sccsid[] = "@(#) ./as/target/i386/proc.c";
      2 
      3 #include <stdlib.h>
      4 
      5 #include "../../../inc/scc.h"
      6 #include "../../as.h"
      7 #include "../x80/proc.h"
      8 
      9 void
     10 iarch(void)
     11 {
     12 	static struct {
     13 		char *name;
     14 		char type;
     15 	} regs[] = {
     16 		"AF", AREG_AF,
     17 		"A", AREG_A,
     18 		"F", AREG_F,
     19 
     20 		"BC", AREG_BC,
     21 		"B", AREG_B,
     22 		"C", AREG_C,
     23 
     24 		"HL", AREG_HL,
     25 		"H", AREG_H,
     26 		"L", AREG_L,
     27 
     28 		"DE", AREG_DE,
     29 		"D", AREG_D,
     30 		"E", AREG_E,
     31 
     32 		"IX", AREG_IX,
     33 		"IXL", AREG_IXL,
     34 		"IXH", AREG_IXH,
     35 
     36 		"IY", AREG_IY,
     37 		"IYL", AREG_IYL,
     38 		"IYH", AREG_IYH,
     39 
     40 		"R", AREG_R,
     41 		"I", AREG_I,
     42 		"AF_", AREG_AF_,
     43 
     44 		NULL,
     45 	}, *bp;
     46 
     47 	for (bp = regs; bp->name; ++bp) {
     48 		Symbol *sym = lookup(bp->name, TREG);
     49 		sym->argtype = bp->type;
     50 	}
     51 }
     52 
     53 int
     54 match(Op *op, Node **args)
     55 {
     56 	unsigned char *p;
     57 	int arg;
     58 	Node *np;
     59 
     60 	if (!op->args)
     61 		return args == NULL;
     62 
     63 	for (p = op->args; (arg = *p) && *args; ++p) {
     64 		if (arg & AREP)
     65 			--p;
     66 		np = *args++;
     67 		switch (arg & ~AREP) {
     68 		case AINDER_HL:
     69 			if (np->op != AINDIR)
     70 				return 0;
     71 			if (np->left->sym->argtype != AREG_HL)
     72 				return 0;
     73 			break;
     74 		case AREG_A:
     75 			if (np->op != AREG || np->sym->argtype != AREG_A)
     76 				return 0;
     77 			break;
     78 		case AREG_RCLASS:
     79 			if (np->op != AREG)
     80 				return 0;
     81 			if (!rclass(np->sym->argtype))
     82 				return 0;
     83 			break;
     84 		case AREG_PCLASS:
     85 			if (np->op != AREG)
     86 				return 0;
     87 			if (!pclass(np->sym->argtype))
     88 				return 0;
     89 			break;
     90 		case AREG_QCLASS:
     91 			if (np->op != AREG)
     92 				return 0;
     93 			if (!qclass(np->sym->argtype))
     94 				return 0;
     95 			break;
     96 		case AIMM8:
     97 		case AIMM16:
     98 		case AIMM32:
     99 		case AIMM64:
    100 			if (np->addr != AIMM)
    101 				return 0;
    102 			if (toobig(np, arg))
    103 				error("overflow in immediate operand");
    104 			break;
    105 		default:
    106 			abort();
    107 		}
    108 	}
    109 
    110 	return (!arg || arg & AREP) && !*args;
    111 }