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