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