code.c (3407B)
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 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 } 63 64 void 65 pprint(char *s) 66 { 67 int c; 68 char *t; 69 70 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 '\a': 86 t = "\\a"; 87 goto print_str; 88 case '\f': 89 t = "\\f"; 90 goto print_str; 91 case '\r': 92 t = "\\r"; 93 goto print_str; 94 case '"': 95 t = "\\\""; 96 goto print_str; 97 case '\'': 98 t = "\\'"; 99 goto print_str; 100 case '\?': 101 t = "\\\?"; 102 goto print_str; 103 case '\\': 104 putchar('\\'); 105 default: 106 if (!isprint(c)) 107 printf("\\x%x", c); 108 else 109 putchar(c); 110 break; 111 print_str: 112 fputs(t, stdout); 113 break; 114 } 115 } 116 putchar('"'); 117 } 118 119 Symbol * 120 newlabel(void) 121 { 122 Symbol *sym = getsym(TMPSYM); 123 124 sym->kind = SLABEL; 125 return sym; 126 } 127 128 Node * 129 labelstmt(Node *np, Symbol *sym) 130 { 131 if(!sym) 132 sym = newlabel(); 133 if (!np) 134 np = node(ONOP); 135 np->label = sym; 136 sym->u.stmt = np; 137 138 return np; 139 } 140 141 Node * 142 label2node(Node *np, Symbol *sym) 143 { 144 if(!sym) 145 sym = newlabel(); 146 if (!np) 147 np = node(OLABEL); 148 np->op = OLABEL; 149 np->u.sym = sym; 150 151 return np; 152 } 153 154 Node * 155 tmpnode(Type *tp, Symbol *sym) 156 { 157 unsigned short flags; 158 Node *np; 159 160 np = node(OTMP); 161 if (!sym) { 162 sym = getsym(TMPSYM); 163 sym->type = np->type = *tp; 164 sym->kind = STMP; 165 } 166 167 flags = tp->flags & ~(PARF|INITF); 168 sym->type.flags = np->type.flags = flags; 169 np->type = *tp; 170 np->left = np->right = NULL; 171 np->u.sym = sym; 172 np->op = OTMP; 173 174 return np; 175 } 176 177 Node * 178 idxnode(Node *np, long off) 179 { 180 if (!np) 181 np = node(OINDEX); 182 np->op = OINDEX; 183 np->left = np->right = NULL; 184 np->type = ptrtype; 185 np->u.off = off; 186 return np; 187 } 188 189 Node * 190 constnode(Node *np, TUINT n, Type *tp) 191 { 192 if (!np) 193 np = node(OCONST); 194 np->op = OCONST; 195 np->left = np->right = NULL; 196 np->type = *tp; 197 np->u.i = n; 198 return np; 199 } 200 201 void 202 setlabel(Symbol *sym) 203 { 204 if (!sym) 205 return; 206 code(ASLABEL, NULL, NULL, NULL); 207 pc->label = sym; 208 sym->u.inst = pc; 209 } 210 211 void 212 code(int op, Node *to, Node *from1, Node *from2) 213 { 214 nextpc(); 215 if (from1) 216 addr(from1, &pc->from1); 217 if (from2) 218 addr(from2, &pc->from2); 219 if (to) 220 addr(to, &pc->to); 221 pc->op = op; 222 } 223 224 void 225 delcode(void) 226 { 227 Inst *prev = pc->prev, *next = pc->next; 228 229 free(pc); 230 if (!prev) { 231 prog = pc = next; 232 } else { 233 pc = prev; 234 prev->next = next; 235 if (next) 236 next->prev = prev; 237 } 238 }