scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

code.c (3281B)


      1 #include <ctype.h>
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 
      6 #include <scc/scc.h>
      7 
      8 #include "cc2.h"
      9 
     10 Inst *pc, *prog;
     11 
     12 static void
     13 nextpc(void)
     14 {
     15 	Inst *new;
     16 
     17 	new = xcalloc(1, sizeof(*new)); /* TODO: create an arena */
     18 
     19 	if (!pc) {
     20 		prog = new;
     21 	} else {
     22 		new->next = pc->next;
     23 		pc->next = new;
     24 	}
     25 
     26 	/* SNONE being 0, calloc initialized {from1,from2,to}.kind for us */
     27 	new->prev = pc;
     28 	pc = new;
     29 }
     30 
     31 static void
     32 addr(Node *np, Addr *addr)
     33 {
     34 	Symbol *sym;
     35 
     36 	switch (np->op) {
     37 	case OMREG:
     38 		addr->kind = SREG;
     39 		addr->u.reg = np->u.reg;
     40 		break;
     41 	case OCONST:
     42 		addr->kind = SCONST;
     43 		/* TODO: Add support for more type of constants */
     44 		addr->u.i = np->u.i;
     45 		break;
     46 	case OINDEX:
     47 		addr->kind = SINDEX;
     48 		addr->u.off = np->u.off;
     49 		break;
     50 	case OREG:
     51 	case OTMP:
     52 	case OLABEL:
     53 	case OAUTO:
     54 	case OMEM:
     55 		sym = np->u.sym;
     56 		addr->kind = sym->kind;
     57 		addr->u.sym = sym;
     58 		break;
     59 	default:
     60 		abort();
     61 	}
     62 }
     63 
     64 void
     65 pprint(char *s)
     66 {
     67 	int c;
     68 	char *t;
     69 
     70 	putchar('"');
     71 	while ((c = *s++) != '\0') {
     72 		switch (c) {
     73 		case '\n':
     74 			t = "\\n";
     75 			goto print_str;
     76 		case '\v':
     77 			t = "\\v";
     78 			goto print_str;
     79 		case '\b':
     80 			t = "\\b";
     81 			goto print_str;
     82 		case '\t':
     83 			t = "\\t";
     84 			goto print_str;
     85 		case '\f':
     86 			t = "\\f";
     87 			goto print_str;
     88 		case '\r':
     89 			t = "\\r";
     90 			goto print_str;
     91 		case '"':
     92 			t = "\\\"";
     93 			goto print_str;
     94 		case '\\':
     95 			putchar('\\');
     96 		default:
     97 			if (!isprint(c))
     98 				printf("\\x%x", c);
     99 			else
    100 				putchar(c);
    101 			break;
    102 		print_str:
    103 			fputs(t, stdout);
    104 			break;
    105 		}
    106 	}
    107 	putchar('"');
    108 }
    109 
    110 Symbol *
    111 newlabel(void)
    112 {
    113 	Symbol *sym = getsym(TMPSYM);
    114 
    115 	sym->kind = SLABEL;
    116 	return sym;
    117 }
    118 
    119 Node *
    120 labelstmt(Node *np, Symbol *sym)
    121 {
    122 	if(!sym)
    123 		sym = newlabel();
    124 	if (!np)
    125 		np = node(ONOP);
    126 	np->label = sym;
    127 	sym->u.stmt = np;
    128 
    129 	return np;
    130 }
    131 
    132 Node *
    133 label2node(Node *np, Symbol *sym)
    134 {
    135 	if(!sym)
    136 		sym = newlabel();
    137 	if (!np)
    138 		np = node(OLABEL);
    139 	np->op = OLABEL;
    140 	np->u.sym = sym;
    141 
    142 	return np;
    143 }
    144 
    145 Node *
    146 tmpnode(Type *tp, Symbol *sym)
    147 {
    148 	unsigned short flags;
    149 	Node *np;
    150 
    151 	np = node(OTMP);
    152 	if (!sym) {
    153 		sym = getsym(TMPSYM);
    154 		sym->type = np->type = *tp;
    155 		sym->kind = STMP;
    156 	}
    157 
    158 	flags = tp->flags & ~(PARF|INITF);
    159 	sym->type.flags = np->type.flags = flags;
    160 	np->type = *tp;
    161 	np->left = np->right = NULL;
    162 	np->u.sym = sym;
    163 	np->op = OTMP;
    164 
    165 	return np;
    166 }
    167 
    168 Node *
    169 idxnode(Node *np, long off)
    170 {
    171 	if (!np)
    172 		np = node(OINDEX);
    173 	np->op = OINDEX;
    174 	np->left = np->right = NULL;
    175 	np->type = ptrtype;
    176 	np->u.off = off;
    177 	return np;
    178 }
    179 
    180 Node *
    181 constnode(Node *np, unsigned long long n, Type *tp)
    182 {
    183 	if (!np)
    184 		np = node(OCONST);
    185 	np->op = OCONST;
    186 	np->left = np->right = NULL;
    187 	np->type = *tp;
    188 	np->u.i = n;
    189 	return np;
    190 }
    191 
    192 void
    193 setlabel(Symbol *sym)
    194 {
    195 	if (!sym)
    196 		return;
    197 	code(ASLABEL, NULL, NULL, NULL);
    198 	pc->label = sym;
    199 	sym->u.inst = pc;
    200 }
    201 
    202 void
    203 code(int op, Node *to, Node *from1, Node *from2)
    204 {
    205 	nextpc();
    206 	if (from1)
    207 		addr(from1, &pc->from1);
    208 	if (from2)
    209 		addr(from2, &pc->from2);
    210 	if (to)
    211 		addr(to, &pc->to);
    212 	pc->op = op;
    213 }
    214 
    215 void
    216 delcode(void)
    217 {
    218         Inst *prev = pc->prev, *next = pc->next;
    219 
    220         free(pc);
    221         if (!prev) {
    222                 prog = pc = next;
    223         } else {
    224                 pc = prev;
    225                 prev->next = next;
    226                 if (next)
    227                         next->prev = prev;
    228         }
    229 }