scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

code.c (2745B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 
      5 #include "arch.h"
      6 #include "../../cc2.h"
      7 #include "../../../inc/sizes.h"
      8 
      9 enum segment {
     10 	CODESEG,
     11 	DATASEG,
     12 	BSSSEG,
     13 	NOSEG
     14 };
     15 
     16 static int curseg = NOSEG;
     17 
     18 static void
     19 segment(int seg)
     20 {
     21 	static char *txt[] = {
     22 		[CODESEG] = "\t.text\n",
     23 		[DATASEG] = "\t.data\n",
     24 		[BSSSEG] = "\t.bss\n",
     25 	};
     26 
     27 	if (seg == curseg)
     28 		return;
     29 	fputs(txt[seg], stdout);
     30 	curseg = seg;
     31 }
     32 
     33 static char *
     34 symname(Symbol *sym)
     35 {
     36 	static char name[INTIDENTSIZ+1];
     37 
     38 	if (sym->name) {
     39 		switch (sym->kind) {
     40 		case SEXTRN:
     41 		case SGLOB:
     42 		case SPRIV:
     43 			return sym->name;
     44 		}
     45 	}
     46 
     47 	sprintf(name, ".L%d", sym->numid);
     48 
     49 	return name;
     50 }
     51 
     52 static void
     53 emitconst(Node *np)
     54 {
     55 	switch (np->type.size) {
     56 	case 1:
     57 		printf("%d", (int) np->u.i & 0xFF);
     58 		break;
     59 	case 2:
     60 		printf("%d", (int) np->u.i & 0xFFFF);
     61 		break;
     62 	case 4:
     63 		printf("%ld", (long) np->u.i & 0xFFFFFFFF);
     64 		break;
     65 	case 8:
     66 		printf("%lld", (long long) np->u.i & 0xFFFFFFFF);
     67 		break;
     68 	default:
     69 		abort();
     70 	}
     71 }
     72 
     73 static void
     74 emittree(Node *np)
     75 {
     76 	if (!np)
     77 		return;
     78 
     79 	switch (np->op) {
     80 	case OSTRING:
     81 		printf("\"%s\"", np->u.s);
     82 		free(np->u.s);
     83 		np->u.s = NULL;
     84 		break;
     85 	case OCONST:
     86 		emitconst(np);
     87 		break;
     88 	case OADDR:
     89 		emittree(np->left);
     90 		break;
     91 	case OMEM:
     92 		fputs(symname(np->u.sym), stdout);
     93 		break;
     94 	default:
     95 		emittree(np->left);
     96 		printf(" %c ", np->op);
     97 		emittree(np->right);
     98 		break;
     99 	}
    100 }
    101 static void
    102 size2asm(Type *tp)
    103 {
    104 	char *s;
    105 
    106 	if (tp->flags & STRF) {
    107 		s = "\t.ascii\t";
    108 	} else {
    109 		switch (tp->size) {
    110 		case 1:
    111 			s = "\t.byte\t";
    112 			break;
    113 		case 2:
    114 			s = "\t.short\t";
    115 			break;
    116 		case 4:
    117 			s = "\t.long\t";
    118 			break;
    119 		case 8:
    120 			s = "\t.quad\t";
    121 			break;
    122 		default:
    123 			s = "\t.space\t%lu,";
    124 			break;
    125 		}
    126 	}
    127 	printf(s, tp->size);
    128 }
    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, flags = sym->type.flags;
    143 	char *name = symname(sym);
    144 	Type *tp = &sym->type;
    145 
    146 	if (flags & FUNF)
    147 		seg = CODESEG;
    148 	else if (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%lu\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 defvar(Symbol *sym)
    182 {
    183 }
    184 
    185 void
    186 defpar(Symbol *sym)
    187 {
    188 }
    189 
    190 void
    191 newfun(void)
    192 {
    193 }
    194 
    195 void
    196 writeout(void)
    197 {
    198 }
    199 
    200 void
    201 endinit(void)
    202 {
    203 }
    204 
    205 void
    206 getbblocks(void)
    207 {
    208 }