scc

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

code.c (2999B)


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