scc

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

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 }