7 main(int argc, char *argv[])
10 int nout, nproc, status, i, c;
14 memset(debug, 0, sizeof(debug));
17 include[ninclude++] = ".";
21 if(c >= 0 || c < sizeof(debug))
41 print("usage: %Ca [-options] file.s\n", thechar);
44 if(argc > 1 && systemtype(Windows)){
45 print("can't assemble multiple files on windows\n");
50 if(p = getenv("NPROC"))
55 while(nout < nproc && argc > 0) {
67 print("%s:\n", *argv);
99 p = utfrrune(ofile, pathchar());
108 p = utfrrune(outfile, '.');
110 if(p[1] == 's' && p[2] == 0)
112 outfile = smprint("%s.%C", outfile, thechar);
114 outfile = "/dev/null";
116 p = getenv("INCLUDE");
120 if(systemtype(Plan9))
121 setinclude(smprint("/%s/include", thestring));
124 of = mycreat(outfile, 0664);
126 yyerror("%Ca: cannot create %s", thechar, outfile);
129 Binit(&obuf, of, OWRITE);
134 for(i=0; i<nDlist; i++)
146 for(i=0; i<nDlist; i++)
168 "XER", LSPREG, D_XER,
170 "FPSCR", LFPSCR, D_FPSCR,
254 "CREQV", LCROP, ACREQV,
255 "CRXOR", LCROP, ACRXOR,
256 "CRAND", LCROP, ACRAND,
257 "CROR", LCROP, ACROR,
258 "CRANDN", LCROP, ACRANDN,
259 "CRORN", LCROP, ACRORN,
260 "CRNAND", LCROP, ACRNAND,
261 "CRNOR", LCROP, ACRNOR,
264 "ADDV", LADDW, AADDV,
265 "ADDCC", LADDW, AADDCC,
266 "ADDVCC", LADDW, AADDVCC,
267 "ADDC", LADDW, AADDC,
268 "ADDCV", LADDW, AADDCV,
269 "ADDCCC", LADDW, AADDCCC,
270 "ADDCVCC", LADDW, AADDCVCC,
271 "ADDE", LLOGW, AADDE,
272 "ADDEV", LLOGW, AADDEV,
273 "ADDECC", LLOGW, AADDECC,
274 "ADDEVCC", LLOGW, AADDEVCC,
276 "ADDME", LABS, AADDME,
277 "ADDMEV", LABS, AADDMEV,
278 "ADDMECC", LABS, AADDMECC,
279 "ADDMEVCC", LABS, AADDMEVCC,
280 "ADDZE", LABS, AADDZE,
281 "ADDZEV", LABS, AADDZEV,
282 "ADDZECC", LABS, AADDZECC,
283 "ADDZEVCC", LABS, AADDZEVCC,
286 "SUBV", LADDW, ASUBV,
287 "SUBCC", LADDW, ASUBCC,
288 "SUBVCC", LADDW, ASUBVCC,
289 "SUBE", LLOGW, ASUBE,
290 "SUBECC", LLOGW, ASUBECC,
291 "SUBEV", LLOGW, ASUBEV,
292 "SUBEVCC", LLOGW, ASUBEVCC,
293 "SUBC", LADDW, ASUBC,
294 "SUBCCC", LADDW, ASUBCCC,
295 "SUBCV", LADDW, ASUBCV,
296 "SUBCVCC", LADDW, ASUBCVCC,
298 "SUBME", LABS, ASUBME,
299 "SUBMEV", LABS, ASUBMEV,
300 "SUBMECC", LABS, ASUBMECC,
301 "SUBMEVCC", LABS, ASUBMEVCC,
302 "SUBZE", LABS, ASUBZE,
303 "SUBZEV", LABS, ASUBZEV,
304 "SUBZECC", LABS, ASUBZECC,
305 "SUBZEVCC", LABS, ASUBZEVCC,
308 "ANDCC", LADDW, AANDCC, /* includes andil & andiu */
309 "ANDN", LLOGW, AANDN,
310 "ANDNCC", LLOGW, AANDNCC,
312 "EQVCC", LLOGW, AEQVCC,
313 "NAND", LLOGW, ANAND,
314 "NANDCC", LLOGW, ANANDCC,
316 "NORCC", LLOGW, ANORCC,
317 "OR", LADDW, AOR, /* includes oril & oriu */
318 "ORCC", LADDW, AORCC,
320 "ORNCC", LLOGW, AORNCC,
321 "XOR", LADDW, AXOR, /* includes xoril & xoriu */
322 "XORCC", LLOGW, AXORCC,
324 "EXTSB", LABS, AEXTSB,
325 "EXTSBCC", LABS, AEXTSBCC,
326 "EXTSH", LABS, AEXTSH,
327 "EXTSHCC", LABS, AEXTSHCC,
329 "CNTLZW", LABS, ACNTLZW,
330 "CNTLZWCC", LABS, ACNTLZWCC,
332 "RLWMI", LRLWM, ARLWMI,
333 "RLWMICC", LRLWM, ARLWMICC,
334 "RLWNM", LRLWM, ARLWNM,
335 "RLWNMCC", LRLWM, ARLWNMCC,
338 "SLWCC", LSHW, ASLWCC,
340 "SRWCC", LSHW, ASRWCC,
342 "SRAWCC", LSHW, ASRAWCC,
360 "DIVW", LLOGW, ADIVW,
361 "DIVWV", LLOGW, ADIVWV,
362 "DIVWCC", LLOGW, ADIVWCC,
363 "DIVWVCC", LLOGW, ADIVWVCC,
364 "DIVWU", LLOGW, ADIVWU,
365 "DIVWUV", LLOGW, ADIVWUV,
366 "DIVWUCC", LLOGW, ADIVWUCC,
367 "DIVWUVCC", LLOGW, ADIVWUVCC,
369 "FABS", LFCONV, AFABS,
370 "FABSCC", LFCONV, AFABSCC,
371 "FNEG", LFCONV, AFNEG,
372 "FNEGCC", LFCONV, AFNEGCC,
373 "FNABS", LFCONV, AFNABS,
374 "FNABSCC", LFCONV, AFNABSCC,
376 "FADD", LFADD, AFADD,
377 "FADDCC", LFADD, AFADDCC,
378 "FSUB", LFADD, AFSUB,
379 "FSUBCC", LFADD, AFSUBCC,
380 "FMUL", LFADD, AFMUL,
381 "FMULCC", LFADD, AFMULCC,
382 "FDIV", LFADD, AFDIV,
383 "FDIVCC", LFADD, AFDIVCC,
384 "FRSP", LFCONV, AFRSP,
385 "FRSPCC", LFCONV, AFRSPCC,
387 "FMADD", LFMA, AFMADD,
388 "FMADDCC", LFMA, AFMADDCC,
389 "FMSUB", LFMA, AFMSUB,
390 "FMSUBCC", LFMA, AFMSUBCC,
391 "FNMADD", LFMA, AFNMADD,
392 "FNMADDCC", LFMA, AFNMADDCC,
393 "FNMSUB", LFMA, AFNMSUB,
394 "FNMSUBCC", LFMA, AFNMSUBCC,
395 "FMADDS", LFMA, AFMADDS,
396 "FMADDSCC", LFMA, AFMADDSCC,
397 "FMSUBS", LFMA, AFMSUBS,
398 "FMSUBSCC", LFMA, AFMSUBSCC,
399 "FNMADDS", LFMA, AFNMADDS,
400 "FNMADDSCC", LFMA, AFNMADDSCC,
401 "FNMSUBS", LFMA, AFNMSUBS,
402 "FNMSUBSCC", LFMA, AFNMSUBSCC,
404 "FCMPU", LFCMP, AFCMPU,
405 "FCMPO", LFCMP, AFCMPO,
406 "MTFSB0", LMTFSB, AMTFSB0,
407 "MTFSB1", LMTFSB, AMTFSB1,
409 "FMOVD", LFMOV, AFMOVD,
410 "FMOVS", LFMOV, AFMOVS,
411 "FMOVDCC", LFCONV, AFMOVDCC, /* fmr. */
413 "GLOBL", LTEXT, AGLOBL,
415 "MOVB", LMOVB, AMOVB,
416 "MOVBZ", LMOVB, AMOVBZ,
417 "MOVBU", LMOVB, AMOVBU,
418 "MOVBZU", LMOVB, AMOVBZU,
419 "MOVH", LMOVB, AMOVH,
420 "MOVHZ", LMOVB, AMOVHZ,
421 "MOVHU", LMOVB, AMOVHU,
422 "MOVHZU", LMOVB, AMOVHZU,
423 "MOVHBR", LXMV, AMOVHBR,
424 "MOVWBR", LXMV, AMOVWBR,
425 "MOVW", LMOVW, AMOVW,
426 "MOVWU", LMOVW, AMOVWU,
427 "MOVMW", LMOVMW, AMOVMW,
428 "MOVFL", LMOVW, AMOVFL,
430 "MULLW", LADDW, AMULLW, /* includes multiply immediate 10-139 */
431 "MULLWV", LLOGW, AMULLWV,
432 "MULLWCC", LLOGW, AMULLWCC,
433 "MULLWVCC", LLOGW, AMULLWVCC,
435 "MULHW", LLOGW, AMULHW,
436 "MULHWCC", LLOGW, AMULHWCC,
437 "MULHWU", LLOGW, AMULHWU,
438 "MULHWUCC", LLOGW, AMULHWUCC,
442 "NEGCC", LABS, ANEGCC,
443 "NEGVCC", LABS, ANEGVCC,
445 "NOP", LNOP, ANOP, /* ori 0,0,0 */
446 "SYSCALL", LNOP, ASYSCALL,
448 "RETURN", LRETRN, ARETURN,
450 "RFCI", LRETRN, ARFCI,
452 "DATA", LDATA, ADATA,
454 "TEXT", LTEXT, ATEXT,
456 /* IBM powerpc embedded */
457 "MACCHW", LMA, AMACCHW,
458 "MACCHWCC", LMA, AMACCHWCC,
459 "MACCHWS", LMA, AMACCHWS,
460 "MACCHWSCC", LMA, AMACCHWSCC,
461 "MACCHWSU", LMA, AMACCHWSU,
462 "MACCHWSUCC", LMA, AMACCHWSUCC,
463 "MACCHWSUV", LMA, AMACCHWSUV,
464 "MACCHWSUVCC", LMA, AMACCHWSUVCC,
465 "MACCHWSV", LMA, AMACCHWSV,
466 "MACCHWSVCC", LMA, AMACCHWSVCC,
467 "MACCHWU", LMA, AMACCHWU,
468 "MACCHWUCC", LMA, AMACCHWUCC,
469 "MACCHWUV", LMA, AMACCHWUV,
470 "MACCHWUVCC", LMA, AMACCHWUVCC,
471 "MACCHWV", LMA, AMACCHWV,
472 "MACCHWVCC", LMA, AMACCHWVCC,
473 "MACHHW", LMA, AMACHHW,
474 "MACHHWCC", LMA, AMACHHWCC,
475 "MACHHWS", LMA, AMACHHWS,
476 "MACHHWSCC", LMA, AMACHHWSCC,
477 "MACHHWSU", LMA, AMACHHWSU,
478 "MACHHWSUCC", LMA, AMACHHWSUCC,
479 "MACHHWSUV", LMA, AMACHHWSUV,
480 "MACHHWSUVCC", LMA, AMACHHWSUVCC,
481 "MACHHWSV", LMA, AMACHHWSV,
482 "MACHHWSVCC", LMA, AMACHHWSVCC,
483 "MACHHWU", LMA, AMACHHWU,
484 "MACHHWUCC", LMA, AMACHHWUCC,
485 "MACHHWUV", LMA, AMACHHWUV,
486 "MACHHWUVCC", LMA, AMACHHWUVCC,
487 "MACHHWV", LMA, AMACHHWV,
488 "MACHHWVCC", LMA, AMACHHWVCC,
489 "MACLHW", LMA, AMACLHW,
490 "MACLHWCC", LMA, AMACLHWCC,
491 "MACLHWS", LMA, AMACLHWS,
492 "MACLHWSCC", LMA, AMACLHWSCC,
493 "MACLHWSU", LMA, AMACLHWSU,
494 "MACLHWSUCC", LMA, AMACLHWSUCC,
495 "MACLHWSUV", LMA, AMACLHWSUV,
496 "MACLHWSUVCC", LMA, AMACLHWSUVCC,
497 "MACLHWSV", LMA, AMACLHWSV,
498 "MACLHWSVCC", LMA, AMACLHWSVCC,
499 "MACLHWU", LMA, AMACLHWU,
500 "MACLHWUCC", LMA, AMACLHWUCC,
501 "MACLHWUV", LMA, AMACLHWUV,
502 "MACLHWUVCC", LMA, AMACLHWUVCC,
503 "MACLHWV", LMA, AMACLHWV,
504 "MACLHWVCC", LMA, AMACLHWVCC,
505 "MULCHW", LLOGW, AMULCHW,
506 "MULCHWCC", LLOGW, AMULCHWCC,
507 "MULCHWU", LLOGW, AMULCHWU,
508 "MULCHWUCC", LLOGW, AMULCHWUCC,
509 "MULHHW", LLOGW, AMULHHW,
510 "MULHHWCC", LLOGW, AMULHHWCC,
511 "MULHHWU", LLOGW, AMULHHWU,
512 "MULHHWUCC", LLOGW, AMULHHWUCC,
513 "MULLHW", LLOGW, AMULLHW,
514 "MULLHWCC", LLOGW, AMULLHWCC,
515 "MULLHWU", LLOGW, AMULLHWU,
516 "MULLHWUCC", LLOGW, AMULLHWUCC,
517 "NMACCHW", LMA, ANMACCHW,
518 "NMACCHWCC", LMA, ANMACCHWCC,
519 "NMACCHWS", LMA, ANMACCHWS,
520 "NMACCHWSCC", LMA, ANMACCHWSCC,
521 "NMACCHWSV", LMA, ANMACCHWSV,
522 "NMACCHWSVCC", LMA, ANMACCHWSVCC,
523 "NMACCHWV", LMA, ANMACCHWV,
524 "NMACCHWVCC", LMA, ANMACCHWVCC,
525 "NMACHHW", LMA, ANMACHHW,
526 "NMACHHWCC", LMA, ANMACHHWCC,
527 "NMACHHWS", LMA, ANMACHHWS,
528 "NMACHHWSCC", LMA, ANMACHHWSCC,
529 "NMACHHWSV", LMA, ANMACHHWSV,
530 "NMACHHWSVCC", LMA, ANMACHHWSVCC,
531 "NMACHHWV", LMA, ANMACHHWV,
532 "NMACHHWVCC", LMA, ANMACHHWVCC,
533 "NMACLHW", LMA, ANMACLHW,
534 "NMACLHWCC", LMA, ANMACLHWCC,
535 "NMACLHWS", LMA, ANMACLHWS,
536 "NMACLHWSCC", LMA, ANMACLHWSCC,
537 "NMACLHWSV", LMA, ANMACLHWSV,
538 "NMACLHWSVCC", LMA, ANMACLHWSVCC,
539 "NMACLHWV", LMA, ANMACLHWV,
540 "NMACLHWVCC", LMA, ANMACLHWVCC,
542 /* optional on 32-bit */
543 "FRES", LFCONV, AFRES,
544 "FRESCC", LFCONV, AFRESCC,
545 "FRSQRTE", LFCONV, AFRSQRTE,
546 "FRSQRTECC", LFCONV, AFRSQRTECC,
548 "FSELCC", LFMA, AFSELCC,
549 "FSQRT", LFCONV, AFSQRT,
550 "FSQRTCC", LFCONV, AFSQRTCC,
551 "FSQRTS", LFCONV, AFSQRTS,
552 "FSQRTSCC", LFCONV, AFSQRTSCC,
554 /* parallel, cross, and secondary (fp2) */
555 "FPSEL", LFMA, AFPSEL,
556 "FPMUL", LFADD, AFPMUL,
557 "FXMUL", LFADD, AFXMUL,
558 "FXPMUL", LFADD, AFXPMUL,
559 "FXSMUL", LFADD, AFXSMUL,
560 "FPADD", LFADD, AFPADD,
561 "FPSUB", LFADD, AFPSUB,
562 "FPRE", LFCONV, AFPRE,
563 "FPRSQRTE", LFCONV, AFPRSQRTE,
564 "FPMADD", LFMA, AFPMADD,
565 "FXMADD", LFMA, AFXMADD,
566 "FXCPMADD", LFMA, AFXCPMADD,
567 "FXCSMADD", LFMA, AFXCSMADD,
568 "FPNMADD", LFMA, AFPNMADD,
569 "FXNMADD", LFMA, AFXNMADD,
570 "FXCPNMADD", LFMA, AFXCPNMADD,
571 "FXCSNMADD", LFMA, AFXCSNMADD,
572 "FPMSUB", LFMA, AFPMSUB,
573 "FXMSUB", LFMA, AFXMSUB,
574 "FXCPMSUB", LFMA, AFXCPMSUB,
575 "FXCSMSUB", LFMA, AFXCSMSUB,
576 "FPNMSUB", LFMA, AFPNMSUB,
577 "FXNMSUB", LFMA, AFXNMSUB,
578 "FXCPNMSUB", LFMA, AFXCPNMSUB,
579 "FXCSNMSUB", LFMA, AFXCSNMSUB,
580 "FPABS", LFCONV, AFPABS,
581 "FPNEG", LFCONV, AFPNEG,
582 "FPRSP", LFCONV, AFPRSP,
583 "FPNABS", LFCONV, AFPNABS,
584 "FSMOVD", LFMOV, AFSMOVD,
585 "FSCMP", LFCMP, AFSCMP,
586 "FSABS", LFCONV, AFSABS,
587 "FSNEG", LFCONV, AFSNEG,
588 "FSNABS", LFCONV, AFSNABS,
589 "FPCTIW", LFCONV, AFPCTIW,
590 "FPCTIWZ", LFCONV, AFPCTIWZ,
591 "FMOVSPD", LFCONV, AFMOVSPD,
592 "FMOVPSD", LFCONV, AFMOVPSD,
593 "FXCPNPMA", LFMA, AFXCPNPMA,
594 "FXCSNPMA", LFMA, AFXCSNPMA,
595 "FXCPNSMA", LFMA, AFXCPNSMA,
596 "FXCSNSMA", LFMA, AFXCSNSMA,
597 "FXCXNPMA", LFMA, AFXCXNPMA,
598 "FXCXNSMA", LFMA, AFXCXNSMA,
599 "FXCXMA", LFMA, AFXCXMA,
600 "FXCXNMS", LFMA, AFXCXNMS,
602 /* parallel, cross, and secondary load and store (fp2) */
603 "FSMOVS", LFMOVX, AFSMOVS,
604 "FSMOVSU", LFMOVX, AFSMOVSU,
605 "FSMOVD", LFMOVX, AFSMOVD,
606 "FSMOVDU", LFMOVX, AFSMOVDU,
607 "FXMOVS", LFMOVX, AFXMOVS,
608 "FXMOVSU", LFMOVX, AFXMOVSU,
609 "FXMOVD", LFMOVX, AFXMOVD,
610 "FXMOVDU", LFMOVX, AFXMOVDU,
611 "FPMOVS", LFMOVX, AFPMOVS,
612 "FPMOVSU", LFMOVX, AFPMOVSU,
613 "FPMOVD", LFMOVX, AFPMOVD,
614 "FPMOVDU", LFMOVX, AFPMOVDU,
615 "FPMOVIW", LFMOVX, AFPMOVIW,
617 "AFMOVSPD", LFMOV, AFMOVSPD,
618 "AFMOVPSD", LFMOV, AFMOVPSD,
620 /* special instructions */
623 "DCBST", LXOP, ADCBST,
625 "DCBTST", LXOP, ADCBTST,
629 "ECIWX", LXLD, AECIWX,
630 "ECOWX", LXST, AECOWX,
632 "STWCCC", LXST, ASTWCCC,
633 "EIEIO", LRETRN, AEIEIO,
634 "TLBIE", LNOP, ATLBIE,
638 "ISYNC", LRETRN, AISYNC,
639 "SYNC", LRETRN, ASYNC,
640 /* "TW", LADDW, ATW,*/
642 "WORD", LWORD, AWORD,
644 "NOSCHED", LSCHED, 0x80,
657 nullgen.type = D_NONE;
658 nullgen.name = D_NONE;
663 for(i=0; i<sizeof(nullgen.sval); i++)
671 for(i=0; i<NHASH; i++)
673 for(i=0; itab[i].name; i++) {
674 s = slookup(itab[i].name);
675 s->type = itab[i].type;
676 s->value = itab[i].value;
678 pathname = allocn(pathname, 0, 100);
679 if(mygetwd(pathname, 99) == 0) {
680 pathname = allocn(pathname, 100, 900);
681 if(mygetwd(pathname, 999) == 0)
682 strcpy(pathname, "/???");
698 outcode(AEND, &nullgen, NREG, &nullgen);
703 zname(char *n, int t, int s)
707 Bputc(&obuf, ANAME>>8);
708 Bputc(&obuf, t); /* type */
709 Bputc(&obuf, s); /* sym */
725 Bputc(&obuf, a->type);
726 Bputc(&obuf, a->reg);
728 Bputc(&obuf, a->name);
731 print("unknown type %d\n", a->type);
758 for(i=0; i<NSNAME; i++) {
765 ieeedtod(&e, a->dval);
767 Bputc(&obuf, e.l>>8);
768 Bputc(&obuf, e.l>>16);
769 Bputc(&obuf, e.l>>24);
771 Bputc(&obuf, e.h>>8);
772 Bputc(&obuf, e.h>>16);
773 Bputc(&obuf, e.h>>24);
788 if(sno < 0 || sno >= NSYM)
791 if(h[sno].type == t && h[sno].sym == s)
793 zname(s->name, t, sym);
805 outcode(int a, Gen *g1, int reg, Gen *g2)
809 if(a != AGLOBL && a != ADATA)
813 if(g1->xreg != NREG) {
814 if(reg != NREG || g2->xreg != NREG)
815 yyerror("bad addressing modes");
818 if(g2->xreg != NREG) {
820 yyerror("bad addressing modes");
826 } while(sf != 0 && st == sf);
829 Bputc(&obuf, reg|nosched);
830 Bputc(&obuf, lineno);
831 Bputc(&obuf, lineno>>8);
832 Bputc(&obuf, lineno>>16);
833 Bputc(&obuf, lineno>>24);
839 outgcode(int a, Gen *g1, int reg, Gen *g2, Gen *g3)
841 int s1, s2, s3, flag;
843 if(a != AGLOBL && a != ADATA)
851 } while(s1 && (s2 && s1 == s2 || s3 && s1 == s3) || s2 && (s3 && s2 == s3));
853 if(g2->type != D_NONE)
854 flag = 0x40; /* flags extra operand */
857 Bputc(&obuf, reg | nosched | flag);
858 Bputc(&obuf, lineno);
859 Bputc(&obuf, lineno>>8);
860 Bputc(&obuf, lineno>>16);
861 Bputc(&obuf, lineno>>24);
878 for(h = hist; h != H; h = h->link) {
881 /* on windows skip drive specifier in pathname */
882 if(systemtype(Windows) && p && p[1] == ':'){
886 if(p && p[0] != c && h->offset == 0 && pathname){
887 /* on windows skip drive specifier in pathname */
888 if(systemtype(Windows) && pathname[1] == ':') {
892 } else if(pathname[0] == c){
902 n = 1; /* leading "/" */
903 *p = '/'; /* don't emit "\" on windows */
912 Bputc(&obuf, ANAME>>8);
913 Bputc(&obuf, D_FILE); /* type */
914 Bputc(&obuf, 1); /* sym */
925 g.offset = h->offset;
927 Bputc(&obuf, AHISTORY);
928 Bputc(&obuf, AHISTORY>>8);
930 Bputc(&obuf, h->line);
931 Bputc(&obuf, h->line>>8);
932 Bputc(&obuf, h->line>>16);
933 Bputc(&obuf, h->line>>24);
939 #include "../cc/lexbody"
940 #include "../cc/macbody"
941 #include "../cc/compat"