code.c - scc - simple c99 compiler
 (HTM) git clone git://git.simple-cc.org/scc
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) LICENSE
       ---
       code.c (15519B)
       ---
            1 #include <stdio.h>
            2 #include <stdlib.h>
            3 #include <string.h>
            4 
            5 #include <scc/cstd.h>
            6 #include <scc/scc.h>
            7 
            8 #include "../cc2.h"
            9 #include "arch.h"
           10 
           11 #define ADDR_LEN (INTIDENTSIZ+64)
           12 
           13 static void binary(void), unary(void), store(void), jmp(void), ret(void),
           14             branch(void), call(void), ecall(void), param(void),
           15             asalloc(void), form2local(void), blit(void), vastart(void),
           16             vaarg(void);
           17 
           18 static struct opdata {
           19         void (*fun)(void);
           20         char *txt;
           21         char letter;
           22 } optbl [] = {
           23         [ASLDSB]  =  {.fun = unary,  .txt = "loadsb", .letter = 'w'},
           24         [ASLDUB]  =  {.fun = unary,  .txt = "loadub", .letter = 'w'},
           25         [ASLDSH]  =  {.fun = unary,  .txt = "loadsh", .letter = 'w'},
           26         [ASLDUH]  =  {.fun = unary,  .txt = "loaduh", .letter = 'w'},
           27         [ASLDSW]  =  {.fun = unary,  .txt = "loadsw", .letter = 'w'},
           28         [ASLDUW]  =  {.fun = unary,  .txt = "loaduw", .letter = 'w'},
           29         [ASLDL]   =  {.fun = unary,  .txt = "loadl", .letter = 'l'},
           30         [ASLDS]   =  {.fun = unary,  .txt = "loads", .letter = 's'},
           31         [ASLDD]   =  {.fun = unary,  .txt = "loadd", .letter = 'd'},
           32 
           33         [ASCOPYB] =  {.fun = unary,  .txt = "copy", .letter = 'b'},
           34         [ASCOPYH] =  {.fun = unary,  .txt = "copy", .letter = 'h'},
           35         [ASCOPYW] =  {.fun = unary,  .txt = "copy", .letter = 'w'},
           36         [ASCOPYL] =  {.fun = unary,  .txt = "copy", .letter = 'l'},
           37         [ASCOPYS] =  {.fun = unary,  .txt = "copy", .letter = 's'},
           38         [ASCOPYD] =  {.fun = unary,  .txt = "copy", .letter = 'd'},
           39 
           40         [ASSTB]   =  {.fun = store,  .txt = "store", .letter = 'b'},
           41         [ASSTH]   =  {.fun = store,  .txt = "store", .letter = 'h'},
           42         [ASSTW]   =  {.fun = store,  .txt = "store", .letter = 'w'},
           43         [ASSTL]   =  {.fun = store,  .txt = "store", .letter = 'l'},
           44         [ASSTM]   =  {.fun = blit},
           45         [ASSTS]   =  {.fun = store,  .txt = "store", .letter = 's'},
           46         [ASSTD]   =  {.fun = store,  .txt = "store", .letter = 'd'},
           47 
           48         [ASADDW]  =  {.fun = binary, .txt = "add", .letter = 'w'},
           49         [ASSUBW]  =  {.fun = binary, .txt = "sub", .letter = 'w'},
           50         [ASMULW]  =  {.fun = binary, .txt = "mul", .letter = 'w'},
           51         [ASMODW]  =  {.fun = binary, .txt = "rem", .letter = 'w'},
           52         [ASUMODW] =  {.fun = binary, .txt = "urem", .letter = 'w'},
           53         [ASDIVW]  =  {.fun = binary, .txt = "div", .letter = 'w'},
           54         [ASUDIVW] =  {.fun = binary, .txt = "udiv", .letter = 'w'},
           55         [ASSHLW]  =  {.fun = binary, .txt = "shl", .letter = 'w'},
           56         [ASSHRW]  =  {.fun = binary, .txt = "sar", .letter = 'w'},
           57         [ASUSHRW] =  {.fun = binary, .txt = "shr", .letter = 'w'},
           58         [ASLTW]   =  {.fun = binary, .txt = "csltw", .letter = 'w'},
           59         [ASULTW]  =  {.fun = binary, .txt = "cultw", .letter = 'w'},
           60         [ASGTW]   =  {.fun = binary, .txt = "csgtw", .letter = 'w'},
           61         [ASUGTW]  =  {.fun = binary, .txt = "cugtw", .letter = 'w'},
           62         [ASLEW]   =  {.fun = binary, .txt = "cslew", .letter = 'w'},
           63         [ASULEW]  =  {.fun = binary, .txt = "culew", .letter = 'w'},
           64         [ASGEW]   =  {.fun = binary, .txt = "csgew", .letter = 'w'},
           65         [ASUGEW]  =  {.fun = binary, .txt = "cugew", .letter = 'w'},
           66         [ASEQW]   =  {.fun = binary, .txt = "ceqw", .letter = 'w'},
           67         [ASNEW]   =  {.fun = binary, .txt = "cnew", .letter = 'w'},
           68         [ASBANDW] =  {.fun = binary, .txt = "and", .letter = 'w'},
           69         [ASBORW]  =  {.fun = binary, .txt = "or", .letter = 'w'},
           70         [ASBXORW] =  {.fun = binary, .txt = "xor", .letter = 'w'},
           71 
           72         [ASADDL]  =  {.fun = binary, .txt = "add", .letter = 'l'},
           73         [ASSUBL]  =  {.fun = binary, .txt = "sub", .letter = 'l'},
           74         [ASMULL]  =  {.fun = binary, .txt = "mul", .letter = 'l'},
           75         [ASMODL]  =  {.fun = binary, .txt = "rem", .letter = 'l'},
           76         [ASUMODL] =  {.fun = binary, .txt = "urem", .letter = 'l'},
           77         [ASDIVL]  =  {.fun = binary, .txt = "div", .letter = 'l'},
           78         [ASUDIVL] =  {.fun = binary, .txt = "udiv", .letter = 'l'},
           79         [ASSHLL]  =  {.fun = binary, .txt = "shl", .letter = 'l'},
           80         [ASSHRL]  =  {.fun = binary, .txt = "sar", .letter = 'l'},
           81         [ASUSHRL] =  {.fun = binary, .txt = "shr", .letter = 'l'},
           82         [ASLTL]   =  {.fun = binary, .txt = "csltl", .letter = 'w'},
           83         [ASULTL]  =  {.fun = binary, .txt = "cultl", .letter = 'w'},
           84         [ASGTL]   =  {.fun = binary, .txt = "csgtl", .letter = 'w'},
           85         [ASUGTL]  =  {.fun = binary, .txt = "cugtl", .letter = 'w'},
           86         [ASLEL]   =  {.fun = binary, .txt = "cslel", .letter = 'w'},
           87         [ASULEL]  =  {.fun = binary, .txt = "culel", .letter = 'w'},
           88         [ASGEL]   =  {.fun = binary, .txt = "csgel", .letter = 'w'},
           89         [ASUGEL]  =  {.fun = binary, .txt = "cugel", .letter = 'w'},
           90         [ASEQL]   =  {.fun = binary, .txt = "ceql", .letter = 'w'},
           91         [ASNEL]   =  {.fun = binary, .txt = "cnel", .letter = 'w'},
           92         [ASBANDL] =  {.fun = binary, .txt = "and", .letter = 'l'},
           93         [ASBORL]  =  {.fun = binary, .txt = "or", .letter = 'l'},
           94         [ASBXORL] =  {.fun = binary, .txt = "xor", .letter = 'l'},
           95 
           96         [ASADDS]  =  {.fun = binary, .txt = "add", .letter = 's'},
           97         [ASSUBS]  =  {.fun = binary, .txt = "sub", .letter = 's'},
           98         [ASMULS]  =  {.fun = binary, .txt = "mul", .letter = 's'},
           99         [ASDIVS]  =  {.fun = binary, .txt = "div", .letter = 's'},
          100         [ASLTS]   =  {.fun = binary, .txt = "clts", .letter = 'w'},
          101         [ASGTS]   =  {.fun = binary, .txt = "cgts", .letter = 'w'},
          102         [ASLES]   =  {.fun = binary, .txt = "cles", .letter = 'w'},
          103         [ASGES]   =  {.fun = binary, .txt = "cges", .letter = 'w'},
          104         [ASEQS]   =  {.fun = binary, .txt = "ceqs", .letter = 'w'},
          105         [ASNES]   =  {.fun = binary, .txt = "cnes", .letter = 'w'},
          106 
          107         [ASADDD]  =  {.fun = binary, .txt = "add", .letter = 'd'},
          108         [ASSUBD]  =  {.fun = binary, .txt = "sub", .letter = 'd'},
          109         [ASMULD]  =  {.fun = binary, .txt = "mul", .letter = 'd'},
          110         [ASDIVD]  =  {.fun = binary, .txt = "div", .letter = 'd'},
          111         [ASLTD]   =  {.fun = binary, .txt = "cltd", .letter = 'w'},
          112         [ASGTD]   =  {.fun = binary, .txt = "cgtd", .letter = 'w'},
          113         [ASLED]   =  {.fun = binary, .txt = "cled", .letter = 'w'},
          114         [ASGED]   =  {.fun = binary, .txt = "cged", .letter = 'w'},
          115         [ASEQD]   =  {.fun = binary, .txt = "ceqd", .letter = 'w'},
          116         [ASNED]   =  {.fun = binary, .txt = "cned", .letter = 'w'},
          117 
          118         [ASEXTBW] =  {.fun = unary, .txt = "extsb", .letter = 'w'},
          119         [ASUEXTBW]=  {.fun = unary, .txt = "extub", .letter = 'w'},
          120         [ASEXTBL] =  {.fun = unary, .txt = "extsb", .letter = 'l'},
          121         [ASUEXTBL]=  {.fun = unary, .txt = "extub", .letter = 'l'},
          122         [ASEXTHW] =  {.fun = unary, .txt = "extsh", .letter = 'w'},
          123         [ASUEXTHW]=  {.fun = unary, .txt = "extuh", .letter = 'w'},
          124         [ASEXTHL] =  {.fun = unary, .txt = "extsh", .letter = 'l'},
          125         [ASUEXTHL]=  {.fun = unary, .txt = "extuh", .letter = 'l'},
          126         [ASEXTWL] =  {.fun = unary, .txt = "extsw", .letter = 'l'},
          127         [ASUEXTWL]=  {.fun = unary, .txt = "extuw", .letter = 'l'},
          128 
          129         [ASSTOL] = {.fun = unary, .txt = "stosi", .letter = 'l'},
          130         [ASSTOUL] = {.fun = unary, .txt = "stoui", .letter = 'l'},
          131         [ASSTOW] = {.fun = unary, .txt = "stosi", .letter = 'w'},
          132         [ASSTOUW] = {.fun = unary, .txt = "stoui", .letter = 'w'},
          133         [ASDTOL] = {.fun = unary, .txt = "dtosi", .letter = 'l'},
          134         [ASDTOUL] = {.fun = unary, .txt = "dtoui", .letter = 'l'},
          135         [ASDTOW] = {.fun = unary, .txt = "dtosi", .letter = 'w'},
          136         [ASDTOUW] = {.fun = unary, .txt = "dtoui", .letter = 'w'},
          137 
          138         [ASSWTOD] = {.fun = unary, .txt = "swtof", .letter = 'd'},
          139         [ASUWTOD] = {.fun = unary, .txt = "uwtof", .letter = 'd'},
          140         [ASSWTOS] = {.fun = unary, .txt = "swtof", .letter = 's'},
          141         [ASUWTOS] = {.fun = unary, .txt = "uwtof", .letter = 's'},
          142         [ASSLTOD] = {.fun = unary, .txt = "sltof", .letter = 'd'},
          143         [ASULTOD] = {.fun = unary, .txt = "ultof", .letter = 'd'},
          144         [ASSLTOS] = {.fun = unary, .txt = "sltof", .letter = 's'},
          145         [ASULTOS] = {.fun = unary, .txt = "ultof", .letter = 's'},
          146 
          147         [ASEXTS] = {.fun = unary, .txt = "exts", .letter = 'd'},
          148         [ASTRUNCD] = {.fun = unary, .txt = "truncd", .letter = 's'},
          149 
          150         [ASNEGL] = {.fun = unary, .txt = "neg", .letter ='l'},
          151         [ASNEGW] = {.fun = unary, .txt = "neg", .letter ='w'},
          152         [ASNEGS] = {.fun = unary, .txt = "neg", .letter ='s'},
          153         [ASNEGD] = {.fun = unary, .txt = "neg", .letter ='d'},
          154 
          155         [ASBRANCH] = {.fun = branch},
          156         [ASJMP]  = {.fun = jmp},
          157         [ASRET]  = {.fun = ret},
          158         [ASCALL] = {.fun = call},
          159         [ASCALLE] = {.fun = ecall, .txt = ")"},
          160         [ASCALLEX] = {.fun = ecall, .txt = ", ...)"},
          161         [ASPAR] = {.fun = param, .txt = "%s %s, "},
          162         [ASPARE] = {.fun = param, .txt = "%s %s"},
          163         [ASALLOC] = {.fun = asalloc},
          164         [ASFORM] = {.fun = form2local},
          165 
          166         [ASVSTAR] = {.fun = vastart},
          167         [ASVARG] = {.fun = vaarg},
          168 };
          169 
          170 static char buff[ADDR_LEN];
          171 /*
          172  * : is for user-defined Aggregate Types
          173  * $ is for globals (represented by a pointer)
          174  * % is for function-scope temporaries
          175  * @ is for block labels
          176  */
          177 static char
          178 sigil(Symbol *sym)
          179 {
          180         switch (sym->kind) {
          181         case SEXTRN:
          182         case SGLOB:
          183         case SPRIV:
          184         case SLOCAL:
          185                 return '$';
          186         case SAUTO:
          187         case STMP:
          188                 return '%';
          189         case SLABEL:
          190                 return '@';
          191         default:
          192                 abort();
          193         }
          194 }
          195 
          196 static char *
          197 symname(Symbol *sym)
          198 {
          199         char c = sigil(sym);
          200 
          201         if (sym->name) {
          202                 switch (sym->kind) {
          203                 case SEXTRN:
          204                 case SGLOB:
          205                         sprintf(buff, "%c%s", c, sym->name);
          206                         return buff;
          207                 case SLOCAL:
          208                 case SPRIV:
          209                 case SAUTO:
          210                         sprintf(buff, "%c%s.L%u", c, sym->name, sym->id);
          211                         return buff;
          212                 default:
          213                         abort();
          214                 }
          215         }
          216         sprintf(buff, "%c.L%u", c, sym->numid);
          217 
          218         return buff;
          219 }
          220 
          221 static void
          222 emitconst(Node *np)
          223 {
          224         switch (np->type.size) {
          225         case 1:
          226                 printf("%d", (int) np->u.i & 0xFF);
          227                 break;
          228         case 2:
          229                 printf("%d", (int) np->u.i & 0xFFFF);
          230                 break;
          231         case 4:
          232                 printf("%ld", (long) np->u.i & 0xFFFFFFFF);
          233                 break;
          234         case 8:
          235                 printf("%lld", (long long) np->u.i);
          236                 break;
          237         default:
          238                 abort();
          239         }
          240 }
          241 
          242 static void
          243 emittree(Node *np)
          244 {
          245         if (!np)
          246                 return;
          247 
          248         switch (np->op) {
          249         case OSTRING:
          250                 pprint(np->u.s);
          251                 free(np->u.s);
          252                 np->u.s = NULL;
          253                 break;
          254         case OCONST:
          255                 emitconst(np);
          256                 break;
          257         case OADDR:
          258                 emittree(np->left);
          259                 break;
          260         case OMEM:
          261                 fputs(symname(np->u.sym), stdout);
          262                 break;
          263         default:
          264                 emittree(np->left);
          265                 printf(" %c ", np->op);
          266                 emittree(np->right);
          267                 break;
          268         }
          269 }
          270 
          271 static char *
          272 size2asm(Type *tp)
          273 {
          274         static char spec[ADDR_LEN];
          275 
          276         if (tp->flags & STRF) {
          277                 return "b";
          278         } else if (tp->flags & INTF) {
          279                 switch (tp->size) {
          280                 case 1:
          281                         return "b";
          282                 case 2:
          283                         return "h";
          284                 case 4:
          285                         return "w";
          286                 case 8:
          287                         return "l";
          288                 }
          289         } else if (tp->flags & FLOATF) {
          290                 if (tp->size == 4)
          291                         return "s";
          292                 else if (tp->size == 8)
          293                         return "d";
          294         }
          295 
          296         abort();
          297 }
          298 
          299 void
          300 defglobal(Symbol *sym)
          301 {
          302         Type *tp = &sym->type;
          303 
          304         if (sym->kind == SEXTRN)
          305                 return;
          306         if (sym->kind == SGLOB)
          307                 fputs("export ", stdout);
          308         if ((tp->flags & INITF) == 0)
          309                 fputs("common ", stdout);
          310 
          311         printf("data %s = align %d {\n",
          312                symname(sym),
          313                tp->align);
          314         if ((tp->flags & INITF) == 0)
          315                 printf("\tz\t%lu\n}\n", tp->size);
          316 }
          317 
          318 void
          319 defpar(Symbol *sym)
          320 {
          321         if (sym->kind == SREG)
          322                 sym->kind = SAUTO;
          323         sym->type.flags |= PARF;
          324 }
          325 
          326 void
          327 defvar(Symbol *sym)
          328 {
          329         if (sym->kind == SREG)
          330                 sym->kind = SAUTO;
          331 }
          332 
          333 void
          334 data(Node *np)
          335 {
          336         printf("\t%s\t", size2asm(&np->type));
          337         emittree(np);
          338         putchar(',');
          339         putchar('\n');
          340 }
          341 
          342 static char *
          343 size2stack(Type *tp)
          344 {
          345         static char spec[ADDR_LEN];
          346 
          347         if (tp->flags & INTF) {
          348                 switch (tp->size) {
          349                 case 1:
          350                 case 2:
          351                 case 4:
          352                         return "w";
          353                 case 8:
          354                         return "l";
          355                 }
          356         } else if (tp->flags & FLOATF) {
          357                 if (tp->size == 4)
          358                         return "s";
          359                 else if (tp->size == 8)
          360                         return "d";
          361         } else if (tp->flags & (ARRF|AGGRF)) {
          362                 sprintf(spec, ":.%u", tp->id);
          363                 return spec;
          364         } else if (tp->size == 0) {
          365                 return "w";
          366         }
          367         abort();
          368 }
          369 
          370 void
          371 deftype(Type *tp)
          372 {
          373         printf("type :.%u = align %d { %lu }\n",
          374                tp->id, tp->align, tp->size);
          375 }
          376 
          377 static void
          378 getbblocks(void)
          379 {
          380         Inst *i;
          381 
          382         if (!prog)
          383                 return;
          384 
          385         prog->flags |= BBENTRY;
          386         for (pc = prog; pc; pc = pc->next) {
          387                 switch (pc->op) {
          388                 case ASBRANCH:
          389                         i = pc->from2.u.sym->u.inst;
          390                         i->flags |= BBENTRY;
          391                 case ASJMP:
          392                         i = pc->from1.u.sym->u.inst;
          393                         i->flags |= BBENTRY;
          394                 case ASRET:
          395                         if (pc->next)
          396                                 pc->next->flags |= BBENTRY;
          397                         break;
          398                 }
          399         }
          400 }
          401 
          402 void
          403 writeout(void)
          404 {
          405         Symbol *p;
          406         Type *tp;
          407         char *sep;
          408         int haslabel = 0;
          409 
          410         getbblocks();
          411 
          412         if (curfun->kind == SGLOB)
          413                 fputs("export ", stdout);
          414         printf("function %s %s(", size2stack(&curfun->rtype), symname(curfun));
          415 
          416         /* declare formal parameters */
          417         sep = "";
          418         for (p = locals; p; p = p->next) {
          419                 if ((p->type.flags & PARF) == 0)
          420                         continue;
          421                 printf("%s%s %s%s",
          422                        sep, size2stack(&p->type),
          423                        symname(p),
          424                        (p->type.flags & AGGRF) ? "" : ".val");
          425                 sep = ",";
          426         }
          427         printf("%s)\n{\n", (curfun->type.flags&ELLIPS) ? ", ..." : "");
          428 
          429         /* emit assembler instructions */
          430         for (pc = prog; pc; pc = pc->next) {
          431                 if (pc->label) {
          432                         haslabel = 1;
          433                         printf("%s\n", symname(pc->label));
          434                 }
          435                 if (pc->op == ASLABEL)
          436                         continue;
          437                 if (pc->flags&BBENTRY && !haslabel)
          438                         printf("%s\n", symname(newlabel()));
          439                 (*optbl[pc->op].fun)();
          440                 if (!pc->label)
          441                         haslabel = 0;
          442         }
          443 
          444         puts("}");
          445 }
          446 
          447 static char *
          448 addr2txt(Addr *a)
          449 {
          450         switch (a->kind) {
          451         case SCONST:
          452                 sprintf(buff, "%llu", (unsigned long long) a->u.i);
          453                 return buff;
          454         case SAUTO:
          455         case SLABEL:
          456         case STMP:
          457         case SGLOB:
          458         case SEXTRN:
          459         case SPRIV:
          460         case SLOCAL:
          461                 return symname(a->u.sym);
          462         default:
          463                 abort();
          464         }
          465 }
          466 
          467 static void
          468 binary(void)
          469 {
          470         struct opdata *p = &optbl[pc->op];
          471         char to[ADDR_LEN], from1[ADDR_LEN], from2[ADDR_LEN];
          472 
          473         strcpy(to, addr2txt(&pc->to));
          474         strcpy(from1, addr2txt(&pc->from1));
          475         strcpy(from2, addr2txt(&pc->from2));
          476         printf("\t%s =%c\t%s\t%s,%s\n", to, p->letter, p->txt, from1, from2);
          477 }
          478 
          479 static void
          480 blit(void)
          481 {
          482         Type *tp = &pc->to.u.sym->type;
          483         char to[ADDR_LEN], from[ADDR_LEN];
          484 
          485         strcpy(to, addr2txt(&pc->to));
          486         strcpy(from, addr2txt(&pc->from1));
          487         printf("\t\tblit\t%s,%s,%lu\n", from, to, tp->size);
          488 }
          489 
          490 static void
          491 store(void)
          492 {
          493         struct opdata *p = &optbl[pc->op];
          494         char to[ADDR_LEN], from[ADDR_LEN];
          495 
          496         strcpy(to, addr2txt(&pc->to));
          497         strcpy(from, addr2txt(&pc->from1));
          498         printf("\t\t%s%c\t%s,%s\n", p->txt, p->letter, from, to);
          499 }
          500 
          501 static void
          502 unary(void)
          503 {
          504         struct opdata *p = &optbl[pc->op];
          505         char to[ADDR_LEN], from[ADDR_LEN];
          506 
          507         strcpy(to, addr2txt(&pc->to));
          508         strcpy(from, addr2txt(&pc->from1));
          509         printf("\t%s =%c\t%s\t%s\n", to, p->letter, p->txt, from);
          510 }
          511 
          512 static void
          513 call(void)
          514 {
          515         char to[ADDR_LEN], from[ADDR_LEN];
          516         Symbol *sym = pc->to.u.sym;
          517 
          518         strcpy(to, addr2txt(&pc->to));
          519         strcpy(from, addr2txt(&pc->from1));
          520         printf("\t%s =%s\tcall\t%s(",
          521                to, size2stack(&sym->type), from);
          522 }
          523 
          524 static void
          525 param(void)
          526 {
          527         Symbol *sym = pc->from2.u.sym;
          528 
          529         printf(optbl[pc->op].txt,
          530                size2stack(&sym->type), addr2txt(&pc->from1));
          531 }
          532 
          533 static void
          534 ecall(void)
          535 {
          536         struct opdata *p = &optbl[pc->op];
          537 
          538         puts(p->txt);
          539 }
          540 
          541 static void
          542 ret(void)
          543 {
          544         if (pc->from1.kind == SNONE)
          545                 puts("\t\tret");
          546         else
          547                 printf("\t\tret\t%s\n", addr2txt(&pc->from1));
          548 }
          549 
          550 static void
          551 jmp(void)
          552 {
          553         printf("\t\tjmp\t%s\n", addr2txt(&pc->from1));
          554 }
          555 
          556 static void
          557 branch(void)
          558 {
          559         char to[ADDR_LEN], from1[ADDR_LEN], from2[ADDR_LEN];
          560 
          561         strcpy(to, addr2txt(&pc->to));
          562         strcpy(from1, addr2txt(&pc->from1));
          563         strcpy(from2, addr2txt(&pc->from2));
          564         printf("\t\tjnz\t%s,%s,%s\n", to, from1, from2);
          565 }
          566 
          567 static void
          568 vastart(void)
          569 {
          570         printf("\t\tvastart %s\n", addr2txt(&pc->from1));
          571 }
          572 
          573 static void
          574 vaarg(void)
          575 {
          576         Symbol *sym = pc->to.u.sym;
          577         Type *tp = &sym->type;
          578         char to[ADDR_LEN], from[ADDR_LEN];
          579 
          580         strcpy(to, addr2txt(&pc->to));
          581         strcpy(from, addr2txt(&pc->from1));
          582         printf("\t\t%s =%s vaarg %s\n", to, size2asm(tp), from);
          583 }
          584 
          585 static void
          586 asalloc(void)
          587 {
          588         Symbol *sym = pc->to.u.sym;
          589         Type *tp = &sym->type;
          590         extern Type ptrtype;
          591 
          592         printf("\t%s =%s\talloc%d\t%lu\n",
          593                symname(sym), size2asm(&ptrtype), tp->align+3 & ~3, tp->size);
          594 }
          595 
          596 static void
          597 form2local(void)
          598 {
          599         Symbol *sym = pc->to.u.sym;
          600         Type *tp = &sym->type;
          601         char *name = symname(sym);
          602 
          603         printf("\t\tstore%s\t%s.val,%s\n", size2asm(tp), name, name);
          604 }
          605 
          606 void
          607 endinit(void)
          608 {
          609         puts("}");
          610 }