scc

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

cgen.c (2432B)


      1 #include <stdlib.h>
      2 
      3 #include <scc/scc.h>
      4 
      5 #include "arch.h"
      6 #include "../../cc2.h"
      7 
      8 static void
      9 swtch(Node *idx)
     10 {
     11 }
     12 
     13 static Node *
     14 rhs(Node *np, Node *ret)
     15 {
     16 }
     17 
     18 static Node *
     19 field(Node *np, Node *ret, int islhs)
     20 {
     21 }
     22 
     23 static Node *
     24 lhs(Node *np, Node *new)
     25 {
     26 	switch (np->op) {
     27 	case OMEM:
     28 	case OAUTO:
     29 		*new = *np;
     30 		return new;
     31 	case OPTR:
     32 		return rhs(np->left, new);
     33 	case OFIELD:
     34 		return field(np, new, 1);
     35 	default:
     36 		abort();
     37 	}
     38 }
     39 
     40 static void
     41 bool(Node *np, Symbol *true, Symbol *false)
     42 {
     43 	Node *l = np->left, *r = np->right;
     44 	Node ret, ifyes, ifno;
     45 	Symbol *label;
     46 
     47 	switch (np->op) {
     48 	case ONEG:
     49 		bool(l, false, true);
     50 		break;
     51 	case OAND:
     52 		label = newlabel();
     53 		bool(l, label, false);
     54 		setlabel(label);
     55 		bool(r, true, false);
     56 		break;
     57 	case OOR:
     58 		label = newlabel();
     59 		bool(l, true, label);
     60 		setlabel(label);
     61 		bool(r, true, false);
     62 		break;
     63 	default:
     64 		label2node(&ifyes, true);
     65 		label2node(&ifno, false);
     66 		code(ASBRANCH, rhs(np, &ret), &ifyes, &ifno);
     67 		break;
     68 	}
     69 }
     70 
     71 Node *
     72 cgen(Node *np)
     73 {
     74 	Node aux, *p, *next;
     75 
     76 	setlabel(np->label);
     77 	switch (np->op) {
     78 	case OJMP:
     79 		label2node(&aux, np->u.sym);
     80 		code(ASJMP, NULL, &aux, NULL);
     81 		break;
     82 	case OBRANCH:
     83 		next = np->next;
     84 		if (!next->label)
     85 			next->label = newlabel();
     86 		bool(np->left, np->u.sym, next->label);
     87 		break;
     88 	case ORET:
     89 		p = np->left;
     90 		if (p)
     91 			p = rhs(np->left, &aux);
     92 		code(ASRET, NULL, p, NULL);
     93 		break;
     94 	case OBSWITCH:
     95 		swtch(rhs(np->left, &aux));
     96 		break;
     97 	default:
     98 		rhs(np, &aux);
     99 		break;
    100 	}
    101 	return NULL;
    102 }
    103 
    104 /*
    105  * This is strongly influenced by
    106  * http://plan9.bell-labs.com/sys/doc/compiler.ps (/sys/doc/compiler.ps)
    107  * calculate addresability as follows
    108  *     AUTO => 11          value+fp
    109  *     REG => 13           reg
    110  *     STATIC => 12        (value)
    111  *     CONST => 20         $value
    112  */
    113 Node *
    114 sethi(Node *np)
    115 {
    116 	Node *lp, *rp;
    117 
    118 	if (!np)
    119 		return np;
    120 
    121 	np->complex = 0;
    122 	np->address = 0;
    123 	lp = np->left;
    124 	rp = np->right;
    125 	switch (np->op) {
    126 	case OAUTO:
    127 		np->address = 11;
    128 		break;
    129 	case OREG:
    130 		np->address = 13;
    131 		break;
    132 	case OMEM:
    133 		np->address = 12;
    134 		break;
    135 	case OCONST:
    136 		np->address = 20;
    137 		break;
    138 	default:
    139 		sethi(lp);
    140 		sethi(rp);
    141 		break;
    142 	}
    143 
    144 	if (np->address > 10)
    145 		return np;
    146 	if (lp)
    147 		np->complex = lp->complex;
    148 	if (rp) {
    149 		int d = np->complex - rp->complex;
    150 
    151 		if (d == 0)
    152 			++np->complex;
    153 		else if (d < 0)
    154 			np->complex = rp->complex;
    155 	}
    156 	if (np->complex == 0)
    157 		++np->complex;
    158 	return np;
    159 }