scc

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

code.c (2088B)


      1 static char sccsid[] = "@(#) ./cc2/code.c";
      2 #include <stdlib.h>
      3 #include <string.h>
      4 
      5 #include "../inc/scc.h"
      6 #include "cc2.h"
      7 
      8 Inst *pc, *prog;
      9 
     10 static void
     11 nextpc(void)
     12 {
     13         Inst *new;
     14 
     15         new = xcalloc(1, sizeof(*new)); /* TODO: create an arena */
     16 
     17         if (!pc) {
     18                 prog = new;
     19         } else {
     20                 new->next = pc->next;
     21                 pc->next = new;
     22         }
     23 
     24 	/* SNONE being 0, calloc initialized {from1,from2,to}.kind for us */
     25         new->prev = pc;
     26         pc = new;
     27 }
     28 
     29 static void
     30 addr(Node *np, Addr *addr)
     31 {
     32 	Symbol *sym;
     33 
     34 	switch (np->op) {
     35 	case OREG:
     36 		/* TODO:
     37 		 * At this moment this op is used also for register variables
     38 		 */
     39 		addr->kind = SREG;
     40 		addr->u.reg = np->u.reg;
     41 		break;
     42 	case OCONST:
     43 		addr->kind = SCONST;
     44 		/* TODO: Add support for more type of constants */
     45 		addr->u.i = np->u.i;
     46 		break;
     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 Symbol *
     61 newlabel(void)
     62 {
     63 	Symbol *sym = getsym(TMPSYM);
     64 
     65 	sym->kind = SLABEL;
     66 	return sym;
     67 }
     68 
     69 Node *
     70 label2node(Node *np, Symbol *sym)
     71 {
     72 	if(!sym)
     73 		sym = newlabel();
     74 	if (!np)
     75 		np = node(OLABEL);
     76 	np->op = OLABEL;
     77 	np->u.sym = sym;
     78 
     79 	return np;
     80 }
     81 
     82 Node *
     83 constnode(Node *np, TUINT n, Type *tp)
     84 {
     85 	if (!np)
     86 		np = node(OCONST);
     87 	np->op = OCONST;
     88 	np->left = NULL;
     89 	np->right = NULL;
     90 	np->type = *tp;
     91 	np->u.i = n;
     92 	return np;
     93 }
     94 
     95 void
     96 setlabel(Symbol *sym)
     97 {
     98 	if (!sym)
     99 		return;
    100 	code(0, NULL, NULL, NULL);
    101 	pc->label = sym;
    102 	sym->u.inst = pc;
    103 }
    104 
    105 void
    106 code(int op, Node *to, Node *from1, Node *from2)
    107 {
    108 	nextpc();
    109 	if (from1)
    110 		addr(from1, &pc->from1);
    111 	if (from2)
    112 		addr(from2, &pc->from2);
    113 	if (to)
    114 		addr(to, &pc->to);
    115 	pc->op = op;
    116 }
    117 
    118 void
    119 delcode(void)
    120 {
    121         Inst *prev = pc->prev, *next = pc->next;
    122 
    123         free(pc);
    124         if (!prev) {
    125                 pc = next;
    126                 prog = NULL;
    127         } else {
    128                 pc = prev;
    129                 prev->next = next;
    130                 if (next)
    131                         next->prev = prev;
    132         }
    133 }