code.c (3016B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #include <scc/cstd.h> 5 #include <scc/scc.h> 6 7 #include "arch.h" 8 #include "../../cc2.h" 9 10 enum segment { 11 CODESEG, 12 DATASEG, 13 BSSSEG, 14 NOSEG 15 }; 16 17 static int curseg = NOSEG; 18 static unsigned long offpar, offvar; 19 20 static void 21 segment(int seg) 22 { 23 static char *txt[] = { 24 [CODESEG] = "\tCSEG\n", 25 [DATASEG] = "\tDSEG\n", 26 [BSSSEG] = "\tASEG\n", 27 }; 28 29 if (seg == curseg) 30 return; 31 fputs(txt[seg], stdout); 32 curseg = seg; 33 } 34 35 static char * 36 symname(Symbol *sym) 37 { 38 static char name[INTIDENTSIZ+1]; 39 40 if (sym->name) { 41 switch (sym->kind) { 42 case SGLOB: 43 case SEXTRN: 44 snprintf(name, sizeof(name), "_%s", sym->name); 45 return name; 46 case SPRIV: 47 return sym->name; 48 } 49 } 50 51 sprintf(name, ".%d", sym->numid); 52 53 return name; 54 } 55 56 static void 57 label(Symbol *sym) 58 { 59 int seg; 60 char *name = symname(sym); 61 62 if (sym->type.flags & FUNF) 63 seg = CODESEG; 64 else if (sym->type.flags & INITF) 65 seg = DATASEG; 66 else 67 seg = BSSSEG; 68 segment(seg); 69 70 switch (sym->kind) { 71 case SEXTRN: 72 printf("\tEXTRN\t%s\n", name); 73 return; 74 case SGLOB: 75 printf("\tPUBLIC\t%s\n", name); 76 break; 77 } 78 79 printf("%s:\n", name); 80 } 81 82 static void 83 emitconst(Node *np) 84 { 85 switch (np->type.size) { 86 case 1: 87 printf("%d", (int) np->u.i & 0xFF); 88 break; 89 case 2: 90 printf("%d", (int) np->u.i & 0xFFFF); 91 break; 92 case 4: 93 printf("%ld", (long) np->u.i & 0xFFFFFFFF); 94 break; 95 default: 96 abort(); 97 } 98 } 99 100 static void 101 emittree(Node *np) 102 { 103 if (!np) 104 return; 105 106 switch (np->op) { 107 case OSTRING: 108 pprint(np->u.s); 109 free(np->u.s); 110 np->u.s = NULL; 111 break; 112 case OCONST: 113 emitconst(np); 114 break; 115 case OADDR: 116 emittree(np->left); 117 break; 118 case OMEM: 119 fputs(symname(np->u.sym), stdout); 120 break; 121 default: 122 emittree(np->left); 123 printf(" %c ", np->op); 124 emittree(np->right); 125 break; 126 } 127 } 128 129 static void 130 size2asm(Type *tp) 131 { 132 char *s; 133 134 /* 135 * In z80 we can ignore the alignment 136 */ 137 if (tp->flags & STRF) { 138 s = "\tDB\t"; 139 } else { 140 switch (tp->size) { 141 case 1: 142 s = "\tDB\t"; 143 break; 144 case 2: 145 s = "\tDW\t"; 146 break; 147 case 4: 148 s = "\tDD\t"; 149 break; 150 default: 151 s = "\tDS\t%lu,"; 152 break; 153 } 154 } 155 printf(s, tp->size); 156 } 157 158 void 159 newfun() 160 { 161 offpar = offvar = 0; 162 } 163 164 void 165 defpar(Symbol *sym) 166 { 167 unsigned long align, size; 168 169 if (sym->kind != SREG && sym->kind != SAUTO) 170 return; 171 align = sym->type.align; 172 size = sym->type.size; 173 174 offpar -= align-1 & ~align; 175 sym->u.off = offpar; 176 offpar -= size; 177 sym->kind = SAUTO; 178 } 179 180 void 181 defvar(Symbol *sym) 182 { 183 unsigned long align, size; 184 185 if (sym->kind != SREG && sym->kind != SAUTO) 186 return; 187 align = sym->type.align; 188 size = sym->type.size; 189 190 offvar += align-1 & ~align; 191 sym->u.off = offvar; 192 offvar += size; 193 sym->kind = SAUTO; 194 } 195 196 void 197 deftype(Type *tp) 198 { 199 } 200 201 void 202 defglobal(Symbol *sym) 203 { 204 label(sym); 205 if (sym->kind == SEXTRN || (sym->type.flags & INITF)) 206 return; 207 size2asm(&sym->type); 208 puts("0"); 209 } 210 211 void 212 data(Node *np) 213 { 214 size2asm(&np->type); 215 emittree(np); 216 putchar('\n'); 217 } 218 219 void 220 writeout(void) 221 { 222 } 223 224 void 225 endinit(void) 226 { 227 } 228 229 void 230 getbblocks(void) 231 { 232 }