scc

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

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 }