scc

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

code.c (3016B)


      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 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 void
    159 newfun()
    160 {
    161 	offpar = offvar = 0;
    162 }
    163 
    164 void
    165 defpar(Symbol *sym)
    166 {
    167 	unsigned long align, size;
    168 
    169 	if (sym->kind != SREG && sym->kind != SAUTO)
    170 		return;
    171 	align = sym->type.align;
    172 	size = sym->type.size;
    173 
    174 	offpar -= align-1 & ~align;
    175 	sym->u.off = offpar;
    176 	offpar -= size;
    177 	sym->kind = SAUTO;
    178 }
    179 
    180 void
    181 defvar(Symbol *sym)
    182 {
    183 	unsigned long align, size;
    184 
    185 	if (sym->kind != SREG && sym->kind != SAUTO)
    186 		return;
    187 	align = sym->type.align;
    188 	size = sym->type.size;
    189 
    190 	offvar += align-1 & ~align;
    191 	sym->u.off = offvar;
    192 	offvar += size;
    193 	sym->kind = SAUTO;
    194 }
    195 
    196 void
    197 deftype(Type *tp)
    198 {
    199 }
    200 
    201 void
    202 defglobal(Symbol *sym)
    203 {
    204 	label(sym);
    205 	if (sym->kind == SEXTRN || (sym->type.flags & INITF))
    206 		return;
    207 	size2asm(&sym->type);
    208 	puts("0");
    209 }
    210 
    211 void
    212 data(Node *np)
    213 {
    214 	size2asm(&np->type);
    215 	emittree(np);
    216 	putchar('\n');
    217 }
    218 
    219 void
    220 writeout(void)
    221 {
    222 }
    223 
    224 void
    225 endinit(void)
    226 {
    227 }
    228 
    229 void
    230 getbblocks(void)
    231 {
    232 }