scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

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 }