code.c (3228B)
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 label2node(Node *np, Symbol *sym) 130 { 131 if(!sym) 132 sym = newlabel(); 133 if (!np) 134 np = node(OLABEL); 135 np->op = OLABEL; 136 np->u.sym = sym; 137 138 return np; 139 } 140 141 Node * 142 tmpnode(Type *tp) 143 { 144 char flags; 145 Symbol *sym; 146 Node *np; 147 148 np = node(OTMP); 149 sym = getsym(TMPSYM); 150 sym->type = np->type = *tp; 151 flags = tp->flags & ~(PARF|INITF); 152 sym->type.flags = np->type.flags = flags; 153 sym->kind = STMP; 154 np->left = np->right = NULL; 155 np->u.sym = sym; 156 np->op = OTMP; 157 return np; 158 } 159 160 Node * 161 idxnode(Node *np, long off) 162 { 163 if (!np) 164 np = node(OINDEX); 165 np->op = OINDEX; 166 np->left = np->right = NULL; 167 np->type = ptrtype; 168 np->u.off = off; 169 return np; 170 } 171 172 Node * 173 constnode(Node *np, TUINT n, Type *tp) 174 { 175 if (!np) 176 np = node(OCONST); 177 np->op = OCONST; 178 np->left = np->right = NULL; 179 np->type = *tp; 180 np->u.i = n; 181 return np; 182 } 183 184 void 185 setlabel(Symbol *sym) 186 { 187 if (!sym) 188 return; 189 code(ASLABEL, NULL, NULL, NULL); 190 pc->label = sym; 191 sym->u.inst = pc; 192 } 193 194 void 195 code(int op, Node *to, Node *from1, Node *from2) 196 { 197 nextpc(); 198 if (from1) 199 addr(from1, &pc->from1); 200 if (from2) 201 addr(from2, &pc->from2); 202 if (to) 203 addr(to, &pc->to); 204 pc->op = op; 205 } 206 207 void 208 delcode(void) 209 { 210 Inst *prev = pc->prev, *next = pc->next; 211 212 free(pc); 213 if (!prev) { 214 pc = next; 215 prog = NULL; 216 } else { 217 pc = prev; 218 prev->next = next; 219 if (next) 220 next->prev = prev; 221 } 222 }