1#include <ctype.h>2#include <stdio.h>3#include <stdlib.h>4#include <string.h>56#include <scc/scc.h>78#include "cc2.h"910Inst *pc, *prog;1112static void13nextpc(void)14{15 Inst *new;1617 new = xcalloc(1, sizeof(*new)); /* TODO: create an arena */1819 if (!pc) {20 prog = new;21 } else {22 new->next = pc->next;23 pc->next = new;24 }2526 /* SNONE being 0, calloc initialized {from1,from2,to}.kind for us */27 new->prev = pc;28 pc = new;29}3031static void32addr(Node *np, Addr *addr)33{34 Symbol *sym;3536 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}6364void65pprint(char *s)66{67 int c;68 char *t;6970 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 '\f':86 t = "\\f";87 goto print_str;88 case '\r':89 t = "\\r";90 goto print_str;91 case '"':92 t = "\\\"";93 goto print_str;94 case '\\':95 putchar('\\');96 default:97 if (!isprint(c))98 printf("\\x%x", c);99 else100 putchar(c);101 break;102 print_str:103 fputs(t, stdout);104 break;105 }106 }107 putchar('"');108}109110Symbol *111newlabel(void)112{113 Symbol *sym = getsym(TMPSYM);114115 sym->kind = SLABEL;116 return sym;117}118119Node *120labelstmt(Node *np, Symbol *sym)121{122 if(!sym)123 sym = newlabel();124 if (!np)125 np = node(ONOP);126 np->label = sym;127 sym->u.stmt = np;128129 return np;130}131132Node *133label2node(Node *np, Symbol *sym)134{135 if(!sym)136 sym = newlabel();137 if (!np)138 np = node(OLABEL);139 np->op = OLABEL;140 np->u.sym = sym;141142 return np;143}144145Node *146tmpnode(Type *tp, Symbol *sym)147{148 unsigned short flags;149 Node *np;150151 np = node(OTMP);152 if (!sym) {153 sym = getsym(TMPSYM);154 sym->type = np->type = *tp;155 sym->kind = STMP;156 }157158 flags = tp->flags & ~(PARF|INITF);159 sym->type.flags = np->type.flags = flags;160 np->type = *tp;161 np->left = np->right = NULL;162 np->u.sym = sym;163 np->op = OTMP;164165 return np;166}167168Node *169idxnode(Node *np, long off)170{171 if (!np)172 np = node(OINDEX);173 np->op = OINDEX;174 np->left = np->right = NULL;175 np->type = ptrtype;176 np->u.off = off;177 return np;178}179180Node *181constnode(Node *np, unsigned long long n, Type *tp)182{183 if (!np)184 np = node(OCONST);185 np->op = OCONST;186 np->left = np->right = NULL;187 np->type = *tp;188 np->u.i = n;189 return np;190}191192void193setlabel(Symbol *sym)194{195 if (!sym)196 return;197 code(ASLABEL, NULL, NULL, NULL);198 pc->label = sym;199 sym->u.inst = pc;200}201202void203code(int op, Node *to, Node *from1, Node *from2)204{205 nextpc();206 if (from1)207 addr(from1, &pc->from1);208 if (from2)209 addr(from2, &pc->from2);210 if (to)211 addr(to, &pc->to);212 pc->op = op;213}214215void216delcode(void)217{218 Inst *prev = pc->prev, *next = pc->next;219220 free(pc);221 if (!prev) {222 prog = pc = next;223 } else {224 pc = prev;225 prev->next = next;226 if (next)227 next->prev = prev;228 }229}