scc

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

cgen.c (2378B)


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