code.c (3281B)
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 '\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 else 100 putchar(c); 101 break; 102 print_str: 103 fputs(t, stdout); 104 break; 105 } 106 } 107 putchar('"'); 108 } 109 110 Symbol * 111 newlabel(void) 112 { 113 Symbol *sym = getsym(TMPSYM); 114 115 sym->kind = SLABEL; 116 return sym; 117 } 118 119 Node * 120 labelstmt(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; 128 129 return np; 130 } 131 132 Node * 133 label2node(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; 141 142 return np; 143 } 144 145 Node * 146 tmpnode(Type *tp, Symbol *sym) 147 { 148 unsigned short flags; 149 Node *np; 150 151 np = node(OTMP); 152 if (!sym) { 153 sym = getsym(TMPSYM); 154 sym->type = np->type = *tp; 155 sym->kind = STMP; 156 } 157 158 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; 164 165 return np; 166 } 167 168 Node * 169 idxnode(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 } 179 180 Node * 181 constnode(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 } 191 192 void 193 setlabel(Symbol *sym) 194 { 195 if (!sym) 196 return; 197 code(ASLABEL, NULL, NULL, NULL); 198 pc->label = sym; 199 sym->u.inst = pc; 200 } 201 202 void 203 code(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 } 214 215 void 216 delcode(void) 217 { 218 Inst *prev = pc->prev, *next = pc->next; 219 220 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 }