scc

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

code.c (3228B)


      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 '\a':
     86 			t = "\\a";
     87 			goto print_str;
     88 		case '\f':
     89 			t = "\\f";
     90 			goto print_str;
     91 		case '\r':
     92 			t = "\\r";
     93 			goto print_str;
     94 		case '"':
     95 			t = "\\\"";
     96 			goto print_str;
     97 		case '\'':
     98 			t = "\\'";
     99 			goto print_str;
    100 		case '\?':
    101 			t = "\\\?";
    102 			goto print_str;
    103 		case '\\':
    104 			putchar('\\');
    105 		default:
    106 			if (!isprint(c))
    107 				printf("\\x%x", c);
    108 			else
    109 				putchar(c);
    110 			break;
    111 		print_str:
    112 			fputs(t, stdout);
    113 			break;
    114 		}
    115 	}
    116 	putchar('"');
    117 }
    118 
    119 Symbol *
    120 newlabel(void)
    121 {
    122 	Symbol *sym = getsym(TMPSYM);
    123 
    124 	sym->kind = SLABEL;
    125 	return sym;
    126 }
    127 
    128 Node *
    129 label2node(Node *np, Symbol *sym)
    130 {
    131 	if(!sym)
    132 		sym = newlabel();
    133 	if (!np)
    134 		np = node(OLABEL);
    135 	np->op = OLABEL;
    136 	np->u.sym = sym;
    137 
    138 	return np;
    139 }
    140 
    141 Node *
    142 tmpnode(Type *tp)
    143 {
    144 	char flags;
    145 	Symbol *sym;
    146 	Node *np;
    147 
    148 	np = node(OTMP);
    149 	sym = getsym(TMPSYM);
    150 	sym->type = np->type = *tp;
    151 	flags = tp->flags & ~(PARF|INITF);
    152 	sym->type.flags = np->type.flags = flags;
    153 	sym->kind = STMP;
    154 	np->left = np->right = NULL;
    155 	np->u.sym = sym;
    156 	np->op = OTMP;
    157 	return np;
    158 }
    159 
    160 Node *
    161 idxnode(Node *np, long off)
    162 {
    163 	if (!np)
    164 		np = node(OINDEX);
    165 	np->op = OINDEX;
    166 	np->left = np->right = NULL;
    167 	np->type = ptrtype;
    168 	np->u.off = off;
    169 	return np;
    170 }
    171 
    172 Node *
    173 constnode(Node *np, TUINT n, Type *tp)
    174 {
    175 	if (!np)
    176 		np = node(OCONST);
    177 	np->op = OCONST;
    178 	np->left = np->right = NULL;
    179 	np->type = *tp;
    180 	np->u.i = n;
    181 	return np;
    182 }
    183 
    184 void
    185 setlabel(Symbol *sym)
    186 {
    187 	if (!sym)
    188 		return;
    189 	code(ASLABEL, NULL, NULL, NULL);
    190 	pc->label = sym;
    191 	sym->u.inst = pc;
    192 }
    193 
    194 void
    195 code(int op, Node *to, Node *from1, Node *from2)
    196 {
    197 	nextpc();
    198 	if (from1)
    199 		addr(from1, &pc->from1);
    200 	if (from2)
    201 		addr(from2, &pc->from2);
    202 	if (to)
    203 		addr(to, &pc->to);
    204 	pc->op = op;
    205 }
    206 
    207 void
    208 delcode(void)
    209 {
    210         Inst *prev = pc->prev, *next = pc->next;
    211 
    212         free(pc);
    213         if (!prev) {
    214                 pc = next;
    215                 prog = NULL;
    216         } else {
    217                 pc = prev;
    218                 prev->next = next;
    219                 if (next)
    220                         next->prev = prev;
    221         }
    222 }