ref: 09065798bf0445de3ec4a34ef714bdae3502f198
dir: /src/cmd/cc/cc2/code.c/
#include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <scc/scc.h> #include "cc2.h" Inst *pc, *prog; static void nextpc(void) { Inst *new; new = xcalloc(1, sizeof(*new)); /* TODO: create an arena */ if (!pc) { prog = new; } else { new->next = pc->next; pc->next = new; } /* SNONE being 0, calloc initialized {from1,from2,to}.kind for us */ new->prev = pc; pc = new; } static void addr(Node *np, Addr *addr) { Symbol *sym; switch (np->op) { case OMREG: addr->kind = SREG; addr->u.reg = np->u.reg; break; case OCONST: addr->kind = SCONST; /* TODO: Add support for more type of constants */ addr->u.i = np->u.i; break; case OREG: case OTMP: case OLABEL: case OAUTO: case OMEM: sym = np->u.sym; addr->kind = sym->kind; addr->u.sym = sym; break; default: abort(); } } void pprint(char *s) { int c; char *t; putchar('"'); while ((c = *s++) != '\0') { switch (c) { case '\n': t = "\\n"; goto print_str; case '\v': t = "\\v"; goto print_str; case '\b': t = "\\b"; goto print_str; case '\t': t = "\\t"; goto print_str; case '\a': t = "\\a"; goto print_str; case '\f': t = "\\f"; goto print_str; case '\r': t = "\\r"; goto print_str; case '"': t = "\\\""; goto print_str; case '\'': t = "\\'"; goto print_str; case '\?': t = "\\\?"; goto print_str; case '\\': putchar('\\'); default: if (!isprint(c)) printf("\\x%x", c); else putchar(c); break; print_str: fputs(t, stdout); break; } } putchar('"'); } Symbol * newlabel(void) { Symbol *sym = getsym(TMPSYM); sym->kind = SLABEL; return sym; } Node * label2node(Node *np, Symbol *sym) { if(!sym) sym = newlabel(); if (!np) np = node(OLABEL); np->op = OLABEL; np->u.sym = sym; return np; } Node * tmpnode(Node *np, Type *tp) { char flags; Symbol *sym; if (!np) np = node(OTMP); sym = getsym(TMPSYM); sym->type = np->type = *tp; flags = tp->flags & ~(PARF|INITF); sym->type.flags = np->type.flags = flags; sym->kind = STMP; np->left = np->right = NULL; np->u.sym = sym; np->op = OTMP; return np; } Node * constnode(Node *np, TUINT n, Type *tp) { if (!np) np = node(OCONST); np->op = OCONST; np->left = NULL; np->right = NULL; np->type = *tp; np->u.i = n; return np; } void setlabel(Symbol *sym) { if (!sym) return; code(0, NULL, NULL, NULL); pc->label = sym; sym->u.inst = pc; } void code(int op, Node *to, Node *from1, Node *from2) { nextpc(); if (from1) addr(from1, &pc->from1); if (from2) addr(from2, &pc->from2); if (to) addr(to, &pc->to); pc->op = op; } void delcode(void) { Inst *prev = pc->prev, *next = pc->next; free(pc); if (!prev) { pc = next; prog = NULL; } else { pc = prev; prev->next = next; if (next) next->prev = prev; } }