scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

code.c (3056B)


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