code.c (2656B)
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 void 132 data(Node *np) 133 { 134 size2asm(&np->type); 135 emittree(np); 136 putchar('\n'); 137 } 138 139 static void 140 label(Symbol *sym) 141 { 142 int seg; 143 char *name = symname(sym); 144 Type *tp = &sym->type; 145 146 if (sym->type.flags & FUNF) 147 seg = CODESEG; 148 else if (sym->type.flags & INITF) 149 seg = DATASEG; 150 else 151 seg = BSSSEG; 152 segment(seg); 153 154 switch (sym->kind) { 155 case SEXTRN: 156 printf("\t.extern\t%s\n", name); 157 case SLOCAL: 158 return; 159 case SGLOB: 160 printf("\t.global\t%s\n", name); 161 if (seg == BSSSEG) 162 printf("\t.comm\t%s,%lu\n", name, tp->size); 163 break; 164 } 165 if (sym->type.align != 1) 166 printf("\t.align\t%d\n", sym->type.align); 167 printf("%s:\n", name); 168 } 169 170 void 171 defglobal(Symbol *sym) 172 { 173 label(sym); 174 if (sym->kind == SEXTRN || (sym->type.flags & INITF)) 175 return; 176 size2asm(&sym->type); 177 puts("0"); 178 } 179 180 void 181 deftype(Type *tp) 182 { 183 } 184 185 void 186 defpar(Symbol *sym) 187 { 188 } 189 190 void 191 defvar(Symbol *sym) 192 { 193 } 194 195 void 196 writeout(void) 197 { 198 } 199 200 void 201 endinit(void) 202 { 203 }