scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

code.c (2755B)


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