scc

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

code.c (3052B)


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