scc

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

code.c (2986B)


      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 OREG:
     47 	case OTMP:
     48 	case OLABEL:
     49 	case OAUTO:
     50 	case OMEM:
     51 		sym = np->u.sym;
     52 		addr->kind = sym->kind;
     53 		addr->u.sym = sym;
     54 		break;
     55 	default:
     56 		abort();
     57 	}
     58 }
     59 
     60 void
     61 pprint(char *s)
     62 {
     63 	int c;
     64 	char *t;
     65 
     66 	putchar('"');
     67 	while ((c = *s++) != '\0') {
     68 		switch (c) {
     69 		case '\n':
     70 			t = "\\n";
     71 			goto print_str;
     72 		case '\v':
     73 			t = "\\v";
     74 			goto print_str;
     75 		case '\b':
     76 			t = "\\b";
     77 			goto print_str;
     78 		case '\t':
     79 			t = "\\t";
     80 			goto print_str;
     81 		case '\a':
     82 			t = "\\a";
     83 			goto print_str;
     84 		case '\f':
     85 			t = "\\f";
     86 			goto print_str;
     87 		case '\r':
     88 			t = "\\r";
     89 			goto print_str;
     90 		case '"':
     91 			t = "\\\"";
     92 			goto print_str;
     93 		case '\'':
     94 			t = "\\'";
     95 			goto print_str;
     96 		case '\?':
     97 			t = "\\\?";
     98 			goto print_str;
     99 		case '\\':
    100 			putchar('\\');
    101 		default:
    102 			if (!isprint(c))
    103 				printf("\\x%x", c);
    104 			else
    105 				putchar(c);
    106 			break;
    107 		print_str:
    108 			fputs(t, stdout);
    109 			break;
    110 		}
    111 	}
    112 	putchar('"');
    113 }
    114 
    115 Symbol *
    116 newlabel(void)
    117 {
    118 	Symbol *sym = getsym(TMPSYM);
    119 
    120 	sym->kind = SLABEL;
    121 	return sym;
    122 }
    123 
    124 Node *
    125 label2node(Node *np, Symbol *sym)
    126 {
    127 	if(!sym)
    128 		sym = newlabel();
    129 	if (!np)
    130 		np = node(OLABEL);
    131 	np->op = OLABEL;
    132 	np->u.sym = sym;
    133 
    134 	return np;
    135 }
    136 
    137 Node *
    138 tmpnode(Type *tp)
    139 {
    140 	char flags;
    141 	Symbol *sym;
    142 	Node *np;
    143 
    144 	np = node(OTMP);
    145 	sym = getsym(TMPSYM);
    146 	sym->type = np->type = *tp;
    147 	flags = tp->flags & ~(PARF|INITF);
    148 	sym->type.flags = np->type.flags = flags;
    149 	sym->kind = STMP;
    150 	np->left = np->right = NULL;
    151 	np->u.sym = sym;
    152 	np->op = OTMP;
    153 	return np;
    154 }
    155 
    156 Node *
    157 constnode(Node *np, TUINT n, Type *tp)
    158 {
    159 	if (!np)
    160 		np = node(OCONST);
    161 	np->op = OCONST;
    162 	np->left = NULL;
    163 	np->right = NULL;
    164 	np->type = *tp;
    165 	np->u.i = n;
    166 	return np;
    167 }
    168 
    169 void
    170 setlabel(Symbol *sym)
    171 {
    172 	if (!sym)
    173 		return;
    174 	code(0, NULL, NULL, NULL);
    175 	pc->label = sym;
    176 	sym->u.inst = pc;
    177 }
    178 
    179 void
    180 code(int op, Node *to, Node *from1, Node *from2)
    181 {
    182 	nextpc();
    183 	if (from1)
    184 		addr(from1, &pc->from1);
    185 	if (from2)
    186 		addr(from2, &pc->from2);
    187 	if (to)
    188 		addr(to, &pc->to);
    189 	pc->op = op;
    190 }
    191 
    192 void
    193 delcode(void)
    194 {
    195         Inst *prev = pc->prev, *next = pc->next;
    196 
    197         free(pc);
    198         if (!prev) {
    199                 pc = next;
    200                 prog = NULL;
    201         } else {
    202                 pc = prev;
    203                 prev->next = next;
    204                 if (next)
    205                         next->prev = prev;
    206         }
    207 }