code.c (2986B)
1 #include <ctype.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 6 #include <scc/scc.h> 7 8 #include "cc2.h" 9 10 Inst *pc, *prog; 11 12 static void 13 nextpc(void) 14 { 15 Inst *new; 16 17 new = xcalloc(1, sizeof(*new)); /* TODO: create an arena */ 18 19 if (!pc) { 20 prog = new; 21 } else { 22 new->next = pc->next; 23 pc->next = new; 24 } 25 26 /* SNONE being 0, calloc initialized {from1,from2,to}.kind for us */ 27 new->prev = pc; 28 pc = new; 29 } 30 31 static void 32 addr(Node *np, Addr *addr) 33 { 34 Symbol *sym; 35 36 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 OREG: 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 void 61 pprint(char *s) 62 { 63 int c; 64 char *t; 65 66 putchar('"'); 67 while ((c = *s++) != '\0') { 68 switch (c) { 69 case '\n': 70 t = "\\n"; 71 goto print_str; 72 case '\v': 73 t = "\\v"; 74 goto print_str; 75 case '\b': 76 t = "\\b"; 77 goto print_str; 78 case '\t': 79 t = "\\t"; 80 goto print_str; 81 case '\a': 82 t = "\\a"; 83 goto print_str; 84 case '\f': 85 t = "\\f"; 86 goto print_str; 87 case '\r': 88 t = "\\r"; 89 goto print_str; 90 case '"': 91 t = "\\\""; 92 goto print_str; 93 case '\'': 94 t = "\\'"; 95 goto print_str; 96 case '\?': 97 t = "\\\?"; 98 goto print_str; 99 case '\\': 100 putchar('\\'); 101 default: 102 if (!isprint(c)) 103 printf("\\x%x", c); 104 else 105 putchar(c); 106 break; 107 print_str: 108 fputs(t, stdout); 109 break; 110 } 111 } 112 putchar('"'); 113 } 114 115 Symbol * 116 newlabel(void) 117 { 118 Symbol *sym = getsym(TMPSYM); 119 120 sym->kind = SLABEL; 121 return sym; 122 } 123 124 Node * 125 label2node(Node *np, Symbol *sym) 126 { 127 if(!sym) 128 sym = newlabel(); 129 if (!np) 130 np = node(OLABEL); 131 np->op = OLABEL; 132 np->u.sym = sym; 133 134 return np; 135 } 136 137 Node * 138 tmpnode(Type *tp) 139 { 140 char flags; 141 Symbol *sym; 142 Node *np; 143 144 np = node(OTMP); 145 sym = getsym(TMPSYM); 146 sym->type = np->type = *tp; 147 flags = tp->flags & ~(PARF|INITF); 148 sym->type.flags = np->type.flags = flags; 149 sym->kind = STMP; 150 np->left = np->right = NULL; 151 np->u.sym = sym; 152 np->op = OTMP; 153 return np; 154 } 155 156 Node * 157 constnode(Node *np, TUINT n, Type *tp) 158 { 159 if (!np) 160 np = node(OCONST); 161 np->op = OCONST; 162 np->left = NULL; 163 np->right = NULL; 164 np->type = *tp; 165 np->u.i = n; 166 return np; 167 } 168 169 void 170 setlabel(Symbol *sym) 171 { 172 if (!sym) 173 return; 174 code(0, NULL, NULL, NULL); 175 pc->label = sym; 176 sym->u.inst = pc; 177 } 178 179 void 180 code(int op, Node *to, Node *from1, Node *from2) 181 { 182 nextpc(); 183 if (from1) 184 addr(from1, &pc->from1); 185 if (from2) 186 addr(from2, &pc->from2); 187 if (to) 188 addr(to, &pc->to); 189 pc->op = op; 190 } 191 192 void 193 delcode(void) 194 { 195 Inst *prev = pc->prev, *next = pc->next; 196 197 free(pc); 198 if (!prev) { 199 pc = next; 200 prog = NULL; 201 } else { 202 pc = prev; 203 prev->next = next; 204 if (next) 205 next->prev = prev; 206 } 207 }