Home
       code.c - scc - simple c99 compiler
  HTML git clone git://git.simple-cc.org/scc
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR 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 }