code.c (2657B)
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 19 static void 20 segment(int seg) 21 { 22 static char *txt[] = { 23 [CODESEG] = "\t.text\n", 24 [DATASEG] = "\t.data\n", 25 [BSSSEG] = "\t.bss\n", 26 }; 27 28 if (seg == curseg) 29 return; 30 fputs(txt[seg], stdout); 31 curseg = seg; 32 } 33 34 static char * 35 symname(Symbol *sym) 36 { 37 static char name[INTIDENTSIZ+1]; 38 39 if (sym->name) { 40 switch (sym->kind) { 41 case SEXTRN: 42 case SGLOB: 43 case SPRIV: 44 return sym->name; 45 } 46 } 47 48 sprintf(name, ".L%d", sym->numid); 49 50 return name; 51 } 52 53 static void 54 emitconst(Node *np) 55 { 56 switch (np->type.size) { 57 case 1: 58 printf("%d", (int) np->u.i & 0xFF); 59 break; 60 case 2: 61 printf("%d", (int) np->u.i & 0xFFFF); 62 break; 63 case 4: 64 printf("%ld", (long) np->u.i & 0xFFFFFFFF); 65 break; 66 case 8: 67 printf("%lld", (long long) np->u.i & 0xFFFFFFFF); 68 break; 69 default: 70 abort(); 71 } 72 } 73 74 static void 75 emittree(Node *np) 76 { 77 if (!np) 78 return; 79 80 switch (np->op) { 81 case OSTRING: 82 pprint(np->u.s); 83 free(np->u.s); 84 np->u.s = NULL; 85 break; 86 case OCONST: 87 emitconst(np); 88 break; 89 case OADDR: 90 emittree(np->left); 91 break; 92 case OMEM: 93 fputs(symname(np->u.sym), stdout); 94 break; 95 default: 96 emittree(np->left); 97 printf(" %c ", np->op); 98 emittree(np->right); 99 break; 100 } 101 } 102 static void 103 size2asm(Type *tp) 104 { 105 char *s; 106 107 if (tp->flags & STRF) { 108 s = "\t.ascii\t"; 109 } else { 110 switch (tp->size) { 111 case 1: 112 s = "\t.byte\t"; 113 break; 114 case 2: 115 s = "\t.short\t"; 116 break; 117 case 4: 118 s = "\t.long\t"; 119 break; 120 case 8: 121 s = "\t.quad\t"; 122 break; 123 default: 124 s = "\t.space\t%lu,"; 125 break; 126 } 127 } 128 printf(s, tp->size); 129 } 130 131 132 void 133 data(Node *np) 134 { 135 size2asm(&np->type); 136 emittree(np); 137 putchar('\n'); 138 } 139 140 static void 141 label(Symbol *sym) 142 { 143 int seg; 144 char *name = symname(sym); 145 Type *tp = &sym->type; 146 147 if (sym->type.flags & FUNF) 148 seg = CODESEG; 149 else if (sym->type.flags & INITF) 150 seg = DATASEG; 151 else 152 seg = BSSSEG; 153 segment(seg); 154 155 switch (sym->kind) { 156 case SEXTRN: 157 printf("\t.extern\t%s\n", name); 158 case SLOCAL: 159 return; 160 case SGLOB: 161 printf("\t.global\t%s\n", name); 162 if (seg == BSSSEG) 163 printf("\t.comm\t%s,%lu\n", name, tp->size); 164 break; 165 } 166 if (sym->type.align != 1) 167 printf("\t.align\t%d\n", sym->type.align); 168 printf("%s:\n", name); 169 } 170 171 void 172 defglobal(Symbol *sym) 173 { 174 label(sym); 175 if (sym->kind == SEXTRN || (sym->type.flags & INITF)) 176 return; 177 size2asm(&sym->type); 178 puts("0"); 179 } 180 181 void 182 deftype(Type *tp) 183 { 184 } 185 186 void 187 defvar(Symbol *sym) 188 { 189 } 190 191 void 192 defpar(Symbol *sym) 193 { 194 } 195 196 void 197 writeout(void) 198 { 199 } 200 201 void 202 endinit(void) 203 { 204 }