code.c (2999B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #include <scc/cstd.h> 5 #include <scc/scc.h> 6 7 #include "../cc2.h" 8 #include "arch.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 /* TODO: how are initialized offpar and offvar??? */ 159 160 void 161 defpar(Symbol *sym) 162 { 163 unsigned long align, size; 164 165 if (sym->kind != SREG && sym->kind != SAUTO) 166 return; 167 align = sym->type.align; 168 size = sym->type.size; 169 170 offpar -= align-1 & ~align; 171 sym->u.off = offpar; 172 offpar -= size; 173 sym->kind = SAUTO; 174 } 175 176 void 177 defvar(Symbol *sym) 178 { 179 unsigned long align, size; 180 181 if (sym->kind != SREG && sym->kind != SAUTO) 182 return; 183 align = sym->type.align; 184 size = sym->type.size; 185 186 offvar += align-1 & ~align; 187 sym->u.off = offvar; 188 offvar += size; 189 sym->kind = SAUTO; 190 } 191 192 void 193 deftype(Type *tp) 194 { 195 } 196 197 void 198 defglobal(Symbol *sym) 199 { 200 label(sym); 201 if (sym->kind == SEXTRN || (sym->type.flags & INITF)) 202 return; 203 size2asm(&sym->type); 204 puts("0"); 205 } 206 207 void 208 data(Node *np) 209 { 210 size2asm(&np->type); 211 emittree(np); 212 putchar('\n'); 213 } 214 215 void 216 writeout(void) 217 { 218 } 219 220 void 221 endinit(void) 222 { 223 }