| // Inferno utils/8a/lex.c |
| // http://code.google.com/p/inferno-os/source/browse/utils/8a/lex.c |
| // |
| // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. |
| // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) |
| // Portions Copyright © 1997-1999 Vita Nuova Limited |
| // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) |
| // Portions Copyright © 2004,2006 Bruce Ellis |
| // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) |
| // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others |
| // Portions Copyright © 2009 The Go Authors. All rights reserved. |
| // |
| // Permission is hereby granted, free of charge, to any person obtaining a copy |
| // of this software and associated documentation files (the "Software"), to deal |
| // in the Software without restriction, including without limitation the rights |
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| // copies of the Software, and to permit persons to whom the Software is |
| // furnished to do so, subject to the following conditions: |
| // |
| // The above copyright notice and this permission notice shall be included in |
| // all copies or substantial portions of the Software. |
| // |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| // THE SOFTWARE. |
| |
| #define EXTERN |
| #include <u.h> |
| #include <libc.h> |
| #include "a.h" |
| #include "y.tab.h" |
| |
| enum |
| { |
| Plan9 = 1<<0, |
| Unix = 1<<1, |
| Windows = 1<<2, |
| }; |
| |
| int |
| systemtype(int sys) |
| { |
| return sys&Plan9; |
| } |
| |
| int |
| pathchar(void) |
| { |
| return '/'; |
| } |
| |
| void |
| main(int argc, char *argv[]) |
| { |
| char *p; |
| int c; |
| |
| thechar = '8'; |
| thestring = "386"; |
| |
| ensuresymb(NSYMB); |
| memset(debug, 0, sizeof(debug)); |
| cinit(); |
| outfile = 0; |
| setinclude("."); |
| ARGBEGIN { |
| default: |
| c = ARGC(); |
| if(c >= 0 || c < sizeof(debug)) |
| debug[c] = 1; |
| break; |
| |
| case 'o': |
| outfile = ARGF(); |
| break; |
| |
| case 'D': |
| p = ARGF(); |
| if(p) { |
| if (nDlist%8 == 0) |
| Dlist = allocn(Dlist, nDlist*sizeof(char *), |
| 8*sizeof(char *)); |
| Dlist[nDlist++] = p; |
| } |
| break; |
| |
| case 'I': |
| p = ARGF(); |
| setinclude(p); |
| break; |
| } ARGEND |
| if(*argv == 0) { |
| print("usage: %ca [-options] file.s\n", thechar); |
| errorexit(); |
| } |
| if(argc > 1){ |
| print("can't assemble multiple files\n"); |
| errorexit(); |
| } |
| if(assemble(argv[0])) |
| errorexit(); |
| exits(0); |
| } |
| |
| int |
| assemble(char *file) |
| { |
| char *ofile, *p; |
| int i, of; |
| |
| ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar) |
| strcpy(ofile, file); |
| p = utfrrune(ofile, pathchar()); |
| if(p) { |
| include[0] = ofile; |
| *p++ = 0; |
| } else |
| p = ofile; |
| if(outfile == 0) { |
| outfile = p; |
| if(outfile){ |
| p = utfrrune(outfile, '.'); |
| if(p) |
| if(p[1] == 's' && p[2] == 0) |
| p[0] = 0; |
| p = utfrune(outfile, 0); |
| p[0] = '.'; |
| p[1] = thechar; |
| p[2] = 0; |
| } else |
| outfile = "/dev/null"; |
| } |
| |
| of = create(outfile, OWRITE, 0664); |
| if(of < 0) { |
| yyerror("%ca: cannot create %s", thechar, outfile); |
| errorexit(); |
| } |
| Binit(&obuf, of, OWRITE); |
| |
| pass = 1; |
| pinit(file); |
| |
| Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); |
| |
| for(i=0; i<nDlist; i++) |
| dodefine(Dlist[i]); |
| yyparse(); |
| if(nerrors) { |
| cclean(); |
| return nerrors; |
| } |
| |
| Bprint(&obuf, "\n!\n"); |
| |
| pass = 2; |
| outhist(); |
| pinit(file); |
| for(i=0; i<nDlist; i++) |
| dodefine(Dlist[i]); |
| yyparse(); |
| cclean(); |
| return nerrors; |
| } |
| |
| struct |
| { |
| char *name; |
| ushort type; |
| ushort value; |
| } itab[] = |
| { |
| "SP", LSP, D_AUTO, |
| "SB", LSB, D_EXTERN, |
| "FP", LFP, D_PARAM, |
| "PC", LPC, D_BRANCH, |
| |
| "AL", LBREG, D_AL, |
| "CL", LBREG, D_CL, |
| "DL", LBREG, D_DL, |
| "BL", LBREG, D_BL, |
| "AH", LBREG, D_AH, |
| "CH", LBREG, D_CH, |
| "DH", LBREG, D_DH, |
| "BH", LBREG, D_BH, |
| |
| "AX", LLREG, D_AX, |
| "CX", LLREG, D_CX, |
| "DX", LLREG, D_DX, |
| "BX", LLREG, D_BX, |
| /* "SP", LLREG, D_SP, */ |
| "BP", LLREG, D_BP, |
| "SI", LLREG, D_SI, |
| "DI", LLREG, D_DI, |
| |
| "F0", LFREG, D_F0+0, |
| "F1", LFREG, D_F0+1, |
| "F2", LFREG, D_F0+2, |
| "F3", LFREG, D_F0+3, |
| "F4", LFREG, D_F0+4, |
| "F5", LFREG, D_F0+5, |
| "F6", LFREG, D_F0+6, |
| "F7", LFREG, D_F0+7, |
| |
| "CS", LSREG, D_CS, |
| "SS", LSREG, D_SS, |
| "DS", LSREG, D_DS, |
| "ES", LSREG, D_ES, |
| "FS", LSREG, D_FS, |
| "GS", LSREG, D_GS, |
| |
| "GDTR", LBREG, D_GDTR, |
| "IDTR", LBREG, D_IDTR, |
| "LDTR", LBREG, D_LDTR, |
| "MSW", LBREG, D_MSW, |
| "TASK", LBREG, D_TASK, |
| |
| "CR0", LBREG, D_CR+0, |
| "CR1", LBREG, D_CR+1, |
| "CR2", LBREG, D_CR+2, |
| "CR3", LBREG, D_CR+3, |
| "CR4", LBREG, D_CR+4, |
| "CR5", LBREG, D_CR+5, |
| "CR6", LBREG, D_CR+6, |
| "CR7", LBREG, D_CR+7, |
| |
| "DR0", LBREG, D_DR+0, |
| "DR1", LBREG, D_DR+1, |
| "DR2", LBREG, D_DR+2, |
| "DR3", LBREG, D_DR+3, |
| "DR4", LBREG, D_DR+4, |
| "DR5", LBREG, D_DR+5, |
| "DR6", LBREG, D_DR+6, |
| "DR7", LBREG, D_DR+7, |
| |
| "TR0", LBREG, D_TR+0, |
| "TR1", LBREG, D_TR+1, |
| "TR2", LBREG, D_TR+2, |
| "TR3", LBREG, D_TR+3, |
| "TR4", LBREG, D_TR+4, |
| "TR5", LBREG, D_TR+5, |
| "TR6", LBREG, D_TR+6, |
| "TR7", LBREG, D_TR+7, |
| |
| "AAA", LTYPE0, AAAA, |
| "AAD", LTYPE0, AAAD, |
| "AAM", LTYPE0, AAAM, |
| "AAS", LTYPE0, AAAS, |
| "ADCB", LTYPE3, AADCB, |
| "ADCL", LTYPE3, AADCL, |
| "ADCW", LTYPE3, AADCW, |
| "ADDB", LTYPE3, AADDB, |
| "ADDL", LTYPE3, AADDL, |
| "ADDW", LTYPE3, AADDW, |
| "ADJSP", LTYPE2, AADJSP, |
| "ANDB", LTYPE3, AANDB, |
| "ANDL", LTYPE3, AANDL, |
| "ANDW", LTYPE3, AANDW, |
| "ARPL", LTYPE3, AARPL, |
| "BOUNDL", LTYPE3, ABOUNDL, |
| "BOUNDW", LTYPE3, ABOUNDW, |
| "BSFL", LTYPE3, ABSFL, |
| "BSFW", LTYPE3, ABSFW, |
| "BSRL", LTYPE3, ABSRL, |
| "BSRW", LTYPE3, ABSRW, |
| "BTCL", LTYPE3, ABTCL, |
| "BTCW", LTYPE3, ABTCW, |
| "BTL", LTYPE3, ABTL, |
| "BTRL", LTYPE3, ABTRL, |
| "BTRW", LTYPE3, ABTRW, |
| "BTSL", LTYPE3, ABTSL, |
| "BTSW", LTYPE3, ABTSW, |
| "BTW", LTYPE3, ABTW, |
| "BYTE", LTYPE2, ABYTE, |
| "CALL", LTYPEC, ACALL, |
| "CLC", LTYPE0, ACLC, |
| "CLD", LTYPE0, ACLD, |
| "CLI", LTYPE0, ACLI, |
| "CLTS", LTYPE0, ACLTS, |
| "CMC", LTYPE0, ACMC, |
| "CMPB", LTYPE4, ACMPB, |
| "CMPL", LTYPE4, ACMPL, |
| "CMPW", LTYPE4, ACMPW, |
| "CMPSB", LTYPE0, ACMPSB, |
| "CMPSL", LTYPE0, ACMPSL, |
| "CMPSW", LTYPE0, ACMPSW, |
| "CMPXCHG8B", LTYPE1, ACMPXCHG8B, |
| "CMPXCHGB", LTYPE3, ACMPXCHGB, |
| "CMPXCHGL", LTYPE3, ACMPXCHGL, |
| "CMPXCHGW", LTYPE3, ACMPXCHGW, |
| "DAA", LTYPE0, ADAA, |
| "DAS", LTYPE0, ADAS, |
| "DATA", LTYPED, ADATA, |
| "DECB", LTYPE1, ADECB, |
| "DECL", LTYPE1, ADECL, |
| "DECW", LTYPE1, ADECW, |
| "DIVB", LTYPE2, ADIVB, |
| "DIVL", LTYPE2, ADIVL, |
| "DIVW", LTYPE2, ADIVW, |
| "END", LTYPE0, AEND, |
| "ENTER", LTYPE2, AENTER, |
| "GLOBL", LTYPEG, AGLOBL, |
| "HLT", LTYPE0, AHLT, |
| "IDIVB", LTYPE2, AIDIVB, |
| "IDIVL", LTYPE2, AIDIVL, |
| "IDIVW", LTYPE2, AIDIVW, |
| "IMULB", LTYPE2, AIMULB, |
| "IMULL", LTYPE2, AIMULL, |
| "IMULW", LTYPE2, AIMULW, |
| "INB", LTYPE0, AINB, |
| "INL", LTYPE0, AINL, |
| "INW", LTYPE0, AINW, |
| "INCB", LTYPE1, AINCB, |
| "INCL", LTYPE1, AINCL, |
| "INCW", LTYPE1, AINCW, |
| "INSB", LTYPE0, AINSB, |
| "INSL", LTYPE0, AINSL, |
| "INSW", LTYPE0, AINSW, |
| "INT", LTYPE2, AINT, |
| "INTO", LTYPE0, AINTO, |
| "IRETL", LTYPE0, AIRETL, |
| "IRETW", LTYPE0, AIRETW, |
| |
| "JOS", LTYPER, AJOS, |
| "JO", LTYPER, AJOS, /* alternate */ |
| "JOC", LTYPER, AJOC, |
| "JNO", LTYPER, AJOC, /* alternate */ |
| "JCS", LTYPER, AJCS, |
| "JB", LTYPER, AJCS, /* alternate */ |
| "JC", LTYPER, AJCS, /* alternate */ |
| "JNAE", LTYPER, AJCS, /* alternate */ |
| "JLO", LTYPER, AJCS, /* alternate */ |
| "JCC", LTYPER, AJCC, |
| "JAE", LTYPER, AJCC, /* alternate */ |
| "JNB", LTYPER, AJCC, /* alternate */ |
| "JNC", LTYPER, AJCC, /* alternate */ |
| "JHS", LTYPER, AJCC, /* alternate */ |
| "JEQ", LTYPER, AJEQ, |
| "JE", LTYPER, AJEQ, /* alternate */ |
| "JZ", LTYPER, AJEQ, /* alternate */ |
| "JNE", LTYPER, AJNE, |
| "JNZ", LTYPER, AJNE, /* alternate */ |
| "JLS", LTYPER, AJLS, |
| "JBE", LTYPER, AJLS, /* alternate */ |
| "JNA", LTYPER, AJLS, /* alternate */ |
| "JHI", LTYPER, AJHI, |
| "JA", LTYPER, AJHI, /* alternate */ |
| "JNBE", LTYPER, AJHI, /* alternate */ |
| "JMI", LTYPER, AJMI, |
| "JS", LTYPER, AJMI, /* alternate */ |
| "JPL", LTYPER, AJPL, |
| "JNS", LTYPER, AJPL, /* alternate */ |
| "JPS", LTYPER, AJPS, |
| "JP", LTYPER, AJPS, /* alternate */ |
| "JPE", LTYPER, AJPS, /* alternate */ |
| "JPC", LTYPER, AJPC, |
| "JNP", LTYPER, AJPC, /* alternate */ |
| "JPO", LTYPER, AJPC, /* alternate */ |
| "JLT", LTYPER, AJLT, |
| "JL", LTYPER, AJLT, /* alternate */ |
| "JNGE", LTYPER, AJLT, /* alternate */ |
| "JGE", LTYPER, AJGE, |
| "JNL", LTYPER, AJGE, /* alternate */ |
| "JLE", LTYPER, AJLE, |
| "JNG", LTYPER, AJLE, /* alternate */ |
| "JGT", LTYPER, AJGT, |
| "JG", LTYPER, AJGT, /* alternate */ |
| "JNLE", LTYPER, AJGT, /* alternate */ |
| |
| "JCXZ", LTYPER, AJCXZ, |
| "JMP", LTYPEC, AJMP, |
| "LAHF", LTYPE0, ALAHF, |
| "LARL", LTYPE3, ALARL, |
| "LARW", LTYPE3, ALARW, |
| "LEAL", LTYPE3, ALEAL, |
| "LEAW", LTYPE3, ALEAW, |
| "LEAVEL", LTYPE0, ALEAVEL, |
| "LEAVEW", LTYPE0, ALEAVEW, |
| "LOCK", LTYPE0, ALOCK, |
| "LODSB", LTYPE0, ALODSB, |
| "LODSL", LTYPE0, ALODSL, |
| "LODSW", LTYPE0, ALODSW, |
| "LONG", LTYPE2, ALONG, |
| "LOOP", LTYPER, ALOOP, |
| "LOOPEQ", LTYPER, ALOOPEQ, |
| "LOOPNE", LTYPER, ALOOPNE, |
| "LSLL", LTYPE3, ALSLL, |
| "LSLW", LTYPE3, ALSLW, |
| "MOVB", LTYPE3, AMOVB, |
| "MOVL", LTYPEM, AMOVL, |
| "MOVW", LTYPEM, AMOVW, |
| "MOVBLSX", LTYPE3, AMOVBLSX, |
| "MOVBLZX", LTYPE3, AMOVBLZX, |
| "MOVBWSX", LTYPE3, AMOVBWSX, |
| "MOVBWZX", LTYPE3, AMOVBWZX, |
| "MOVWLSX", LTYPE3, AMOVWLSX, |
| "MOVWLZX", LTYPE3, AMOVWLZX, |
| "MOVSB", LTYPE0, AMOVSB, |
| "MOVSL", LTYPE0, AMOVSL, |
| "MOVSW", LTYPE0, AMOVSW, |
| "MULB", LTYPE2, AMULB, |
| "MULL", LTYPE2, AMULL, |
| "MULW", LTYPE2, AMULW, |
| "NEGB", LTYPE1, ANEGB, |
| "NEGL", LTYPE1, ANEGL, |
| "NEGW", LTYPE1, ANEGW, |
| "NOP", LTYPEN, ANOP, |
| "NOTB", LTYPE1, ANOTB, |
| "NOTL", LTYPE1, ANOTL, |
| "NOTW", LTYPE1, ANOTW, |
| "ORB", LTYPE3, AORB, |
| "ORL", LTYPE3, AORL, |
| "ORW", LTYPE3, AORW, |
| "OUTB", LTYPE0, AOUTB, |
| "OUTL", LTYPE0, AOUTL, |
| "OUTW", LTYPE0, AOUTW, |
| "OUTSB", LTYPE0, AOUTSB, |
| "OUTSL", LTYPE0, AOUTSL, |
| "OUTSW", LTYPE0, AOUTSW, |
| "PAUSE", LTYPEN, APAUSE, |
| "POPAL", LTYPE0, APOPAL, |
| "POPAW", LTYPE0, APOPAW, |
| "POPFL", LTYPE0, APOPFL, |
| "POPFW", LTYPE0, APOPFW, |
| "POPL", LTYPE1, APOPL, |
| "POPW", LTYPE1, APOPW, |
| "PUSHAL", LTYPE0, APUSHAL, |
| "PUSHAW", LTYPE0, APUSHAW, |
| "PUSHFL", LTYPE0, APUSHFL, |
| "PUSHFW", LTYPE0, APUSHFW, |
| "PUSHL", LTYPE2, APUSHL, |
| "PUSHW", LTYPE2, APUSHW, |
| "RCLB", LTYPE3, ARCLB, |
| "RCLL", LTYPE3, ARCLL, |
| "RCLW", LTYPE3, ARCLW, |
| "RCRB", LTYPE3, ARCRB, |
| "RCRL", LTYPE3, ARCRL, |
| "RCRW", LTYPE3, ARCRW, |
| "REP", LTYPE0, AREP, |
| "REPN", LTYPE0, AREPN, |
| "RET", LTYPE0, ARET, |
| "ROLB", LTYPE3, AROLB, |
| "ROLL", LTYPE3, AROLL, |
| "ROLW", LTYPE3, AROLW, |
| "RORB", LTYPE3, ARORB, |
| "RORL", LTYPE3, ARORL, |
| "RORW", LTYPE3, ARORW, |
| "SAHF", LTYPE0, ASAHF, |
| "SALB", LTYPE3, ASALB, |
| "SALL", LTYPE3, ASALL, |
| "SALW", LTYPE3, ASALW, |
| "SARB", LTYPE3, ASARB, |
| "SARL", LTYPE3, ASARL, |
| "SARW", LTYPE3, ASARW, |
| "SBBB", LTYPE3, ASBBB, |
| "SBBL", LTYPE3, ASBBL, |
| "SBBW", LTYPE3, ASBBW, |
| "SCASB", LTYPE0, ASCASB, |
| "SCASL", LTYPE0, ASCASL, |
| "SCASW", LTYPE0, ASCASW, |
| "SETCC", LTYPE1, ASETCC, |
| "SETCS", LTYPE1, ASETCS, |
| "SETEQ", LTYPE1, ASETEQ, |
| "SETGE", LTYPE1, ASETGE, |
| "SETGT", LTYPE1, ASETGT, |
| "SETHI", LTYPE1, ASETHI, |
| "SETLE", LTYPE1, ASETLE, |
| "SETLS", LTYPE1, ASETLS, |
| "SETLT", LTYPE1, ASETLT, |
| "SETMI", LTYPE1, ASETMI, |
| "SETNE", LTYPE1, ASETNE, |
| "SETOC", LTYPE1, ASETOC, |
| "SETOS", LTYPE1, ASETOS, |
| "SETPC", LTYPE1, ASETPC, |
| "SETPL", LTYPE1, ASETPL, |
| "SETPS", LTYPE1, ASETPS, |
| "CDQ", LTYPE0, ACDQ, |
| "CWD", LTYPE0, ACWD, |
| "SHLB", LTYPE3, ASHLB, |
| "SHLL", LTYPES, ASHLL, |
| "SHLW", LTYPES, ASHLW, |
| "SHRB", LTYPE3, ASHRB, |
| "SHRL", LTYPES, ASHRL, |
| "SHRW", LTYPES, ASHRW, |
| "STC", LTYPE0, ASTC, |
| "STD", LTYPE0, ASTD, |
| "STI", LTYPE0, ASTI, |
| "STOSB", LTYPE0, ASTOSB, |
| "STOSL", LTYPE0, ASTOSL, |
| "STOSW", LTYPE0, ASTOSW, |
| "SUBB", LTYPE3, ASUBB, |
| "SUBL", LTYPE3, ASUBL, |
| "SUBW", LTYPE3, ASUBW, |
| "SYSCALL", LTYPE0, ASYSCALL, |
| "TESTB", LTYPE3, ATESTB, |
| "TESTL", LTYPE3, ATESTL, |
| "TESTW", LTYPE3, ATESTW, |
| "TEXT", LTYPET, ATEXT, |
| "VERR", LTYPE2, AVERR, |
| "VERW", LTYPE2, AVERW, |
| "WAIT", LTYPE0, AWAIT, |
| "WORD", LTYPE2, AWORD, |
| "XADDB", LTYPE3, AXADDB, |
| "XADDL", LTYPE3, AXADDL, |
| "XADDW", LTYPE3, AXADDW, |
| "XCHGB", LTYPE3, AXCHGB, |
| "XCHGL", LTYPE3, AXCHGL, |
| "XCHGW", LTYPE3, AXCHGW, |
| "XLAT", LTYPE2, AXLAT, |
| "XORB", LTYPE3, AXORB, |
| "XORL", LTYPE3, AXORL, |
| "XORW", LTYPE3, AXORW, |
| |
| "CMOVLCC", LTYPE3, ACMOVLCC, |
| "CMOVLCS", LTYPE3, ACMOVLCS, |
| "CMOVLEQ", LTYPE3, ACMOVLEQ, |
| "CMOVLGE", LTYPE3, ACMOVLGE, |
| "CMOVLGT", LTYPE3, ACMOVLGT, |
| "CMOVLHI", LTYPE3, ACMOVLHI, |
| "CMOVLLE", LTYPE3, ACMOVLLE, |
| "CMOVLLS", LTYPE3, ACMOVLLS, |
| "CMOVLLT", LTYPE3, ACMOVLLT, |
| "CMOVLMI", LTYPE3, ACMOVLMI, |
| "CMOVLNE", LTYPE3, ACMOVLNE, |
| "CMOVLOC", LTYPE3, ACMOVLOC, |
| "CMOVLOS", LTYPE3, ACMOVLOS, |
| "CMOVLPC", LTYPE3, ACMOVLPC, |
| "CMOVLPL", LTYPE3, ACMOVLPL, |
| "CMOVLPS", LTYPE3, ACMOVLPS, |
| "CMOVWCC", LTYPE3, ACMOVWCC, |
| "CMOVWCS", LTYPE3, ACMOVWCS, |
| "CMOVWEQ", LTYPE3, ACMOVWEQ, |
| "CMOVWGE", LTYPE3, ACMOVWGE, |
| "CMOVWGT", LTYPE3, ACMOVWGT, |
| "CMOVWHI", LTYPE3, ACMOVWHI, |
| "CMOVWLE", LTYPE3, ACMOVWLE, |
| "CMOVWLS", LTYPE3, ACMOVWLS, |
| "CMOVWLT", LTYPE3, ACMOVWLT, |
| "CMOVWMI", LTYPE3, ACMOVWMI, |
| "CMOVWNE", LTYPE3, ACMOVWNE, |
| "CMOVWOC", LTYPE3, ACMOVWOC, |
| "CMOVWOS", LTYPE3, ACMOVWOS, |
| "CMOVWPC", LTYPE3, ACMOVWPC, |
| "CMOVWPL", LTYPE3, ACMOVWPL, |
| "CMOVWPS", LTYPE3, ACMOVWPS, |
| |
| "FMOVB", LTYPE3, AFMOVB, |
| "FMOVBP", LTYPE3, AFMOVBP, |
| "FMOVD", LTYPE3, AFMOVD, |
| "FMOVDP", LTYPE3, AFMOVDP, |
| "FMOVF", LTYPE3, AFMOVF, |
| "FMOVFP", LTYPE3, AFMOVFP, |
| "FMOVL", LTYPE3, AFMOVL, |
| "FMOVLP", LTYPE3, AFMOVLP, |
| "FMOVV", LTYPE3, AFMOVV, |
| "FMOVVP", LTYPE3, AFMOVVP, |
| "FMOVW", LTYPE3, AFMOVW, |
| "FMOVWP", LTYPE3, AFMOVWP, |
| "FMOVX", LTYPE3, AFMOVX, |
| "FMOVXP", LTYPE3, AFMOVXP, |
| "FCMOVCC", LTYPE3, AFCMOVCC, |
| "FCMOVCS", LTYPE3, AFCMOVCS, |
| "FCMOVEQ", LTYPE3, AFCMOVEQ, |
| "FCMOVHI", LTYPE3, AFCMOVHI, |
| "FCMOVLS", LTYPE3, AFCMOVLS, |
| "FCMOVNE", LTYPE3, AFCMOVNE, |
| "FCMOVNU", LTYPE3, AFCMOVNU, |
| "FCMOVUN", LTYPE3, AFCMOVUN, |
| "FCOMB", LTYPE3, AFCOMB, |
| "FCOMBP", LTYPE3, AFCOMBP, |
| "FCOMD", LTYPE3, AFCOMD, |
| "FCOMDP", LTYPE3, AFCOMDP, |
| "FCOMDPP", LTYPE3, AFCOMDPP, |
| "FCOMF", LTYPE3, AFCOMF, |
| "FCOMFP", LTYPE3, AFCOMFP, |
| "FCOMI", LTYPE3, AFCOMI, |
| "FCOMIP", LTYPE3, AFCOMIP, |
| "FCOML", LTYPE3, AFCOML, |
| "FCOMLP", LTYPE3, AFCOMLP, |
| "FCOMW", LTYPE3, AFCOMW, |
| "FCOMWP", LTYPE3, AFCOMWP, |
| "FUCOM", LTYPE3, AFUCOM, |
| "FUCOMI", LTYPE3, AFUCOMI, |
| "FUCOMIP", LTYPE3, AFUCOMIP, |
| "FUCOMP", LTYPE3, AFUCOMP, |
| "FUCOMPP", LTYPE3, AFUCOMPP, |
| "FADDW", LTYPE3, AFADDW, |
| "FADDL", LTYPE3, AFADDL, |
| "FADDF", LTYPE3, AFADDF, |
| "FADDD", LTYPE3, AFADDD, |
| "FADDDP", LTYPE3, AFADDDP, |
| "FSUBDP", LTYPE3, AFSUBDP, |
| "FSUBW", LTYPE3, AFSUBW, |
| "FSUBL", LTYPE3, AFSUBL, |
| "FSUBF", LTYPE3, AFSUBF, |
| "FSUBD", LTYPE3, AFSUBD, |
| "FSUBRDP", LTYPE3, AFSUBRDP, |
| "FSUBRW", LTYPE3, AFSUBRW, |
| "FSUBRL", LTYPE3, AFSUBRL, |
| "FSUBRF", LTYPE3, AFSUBRF, |
| "FSUBRD", LTYPE3, AFSUBRD, |
| "FMULDP", LTYPE3, AFMULDP, |
| "FMULW", LTYPE3, AFMULW, |
| "FMULL", LTYPE3, AFMULL, |
| "FMULF", LTYPE3, AFMULF, |
| "FMULD", LTYPE3, AFMULD, |
| "FDIVDP", LTYPE3, AFDIVDP, |
| "FDIVW", LTYPE3, AFDIVW, |
| "FDIVL", LTYPE3, AFDIVL, |
| "FDIVF", LTYPE3, AFDIVF, |
| "FDIVD", LTYPE3, AFDIVD, |
| "FDIVRDP", LTYPE3, AFDIVRDP, |
| "FDIVRW", LTYPE3, AFDIVRW, |
| "FDIVRL", LTYPE3, AFDIVRL, |
| "FDIVRF", LTYPE3, AFDIVRF, |
| "FDIVRD", LTYPE3, AFDIVRD, |
| "FXCHD", LTYPE3, AFXCHD, |
| "FFREE", LTYPE1, AFFREE, |
| "FLDCW", LTYPE2, AFLDCW, |
| "FLDENV", LTYPE1, AFLDENV, |
| "FRSTOR", LTYPE2, AFRSTOR, |
| "FSAVE", LTYPE1, AFSAVE, |
| "FSTCW", LTYPE1, AFSTCW, |
| "FSTENV", LTYPE1, AFSTENV, |
| "FSTSW", LTYPE1, AFSTSW, |
| "F2XM1", LTYPE0, AF2XM1, |
| "FABS", LTYPE0, AFABS, |
| "FCHS", LTYPE0, AFCHS, |
| "FCLEX", LTYPE0, AFCLEX, |
| "FCOS", LTYPE0, AFCOS, |
| "FDECSTP", LTYPE0, AFDECSTP, |
| "FINCSTP", LTYPE0, AFINCSTP, |
| "FINIT", LTYPE0, AFINIT, |
| "FLD1", LTYPE0, AFLD1, |
| "FLDL2E", LTYPE0, AFLDL2E, |
| "FLDL2T", LTYPE0, AFLDL2T, |
| "FLDLG2", LTYPE0, AFLDLG2, |
| "FLDLN2", LTYPE0, AFLDLN2, |
| "FLDPI", LTYPE0, AFLDPI, |
| "FLDZ", LTYPE0, AFLDZ, |
| "FNOP", LTYPE0, AFNOP, |
| "FPATAN", LTYPE0, AFPATAN, |
| "FPREM", LTYPE0, AFPREM, |
| "FPREM1", LTYPE0, AFPREM1, |
| "FPTAN", LTYPE0, AFPTAN, |
| "FRNDINT", LTYPE0, AFRNDINT, |
| "FSCALE", LTYPE0, AFSCALE, |
| "FSIN", LTYPE0, AFSIN, |
| "FSINCOS", LTYPE0, AFSINCOS, |
| "FSQRT", LTYPE0, AFSQRT, |
| "FTST", LTYPE0, AFTST, |
| "FXAM", LTYPE0, AFXAM, |
| "FXTRACT", LTYPE0, AFXTRACT, |
| "FYL2X", LTYPE0, AFYL2X, |
| "FYL2XP1", LTYPE0, AFYL2XP1, |
| |
| 0 |
| }; |
| |
| void |
| cinit(void) |
| { |
| Sym *s; |
| int i; |
| |
| nullgen.sym = S; |
| nullgen.offset = 0; |
| if(FPCHIP) |
| nullgen.dval = 0; |
| for(i=0; i<sizeof(nullgen.sval); i++) |
| nullgen.sval[i] = 0; |
| nullgen.type = D_NONE; |
| nullgen.index = D_NONE; |
| nullgen.scale = 0; |
| |
| nerrors = 0; |
| iostack = I; |
| iofree = I; |
| peekc = IGN; |
| nhunk = 0; |
| for(i=0; i<NHASH; i++) |
| hash[i] = S; |
| for(i=0; itab[i].name; i++) { |
| s = slookup(itab[i].name); |
| if(s->type != LNAME) |
| yyerror("double initialization %s", itab[i].name); |
| s->type = itab[i].type; |
| s->value = itab[i].value; |
| } |
| |
| pathname = allocn(pathname, 0, 100); |
| if(getwd(pathname, 99) == 0) { |
| pathname = allocn(pathname, 100, 900); |
| if(getwd(pathname, 999) == 0) |
| strcpy(pathname, "/???"); |
| } |
| } |
| |
| void |
| checkscale(int scale) |
| { |
| |
| switch(scale) { |
| case 1: |
| case 2: |
| case 4: |
| case 8: |
| return; |
| } |
| yyerror("scale must be 1248: %d", scale); |
| } |
| |
| void |
| syminit(Sym *s) |
| { |
| |
| s->type = LNAME; |
| s->value = 0; |
| } |
| |
| void |
| cclean(void) |
| { |
| Gen2 g2; |
| |
| g2.from = nullgen; |
| g2.to = nullgen; |
| outcode(AEND, &g2); |
| Bflush(&obuf); |
| } |
| |
| void |
| zname(char *n, int t, int s) |
| { |
| |
| Bputc(&obuf, ANAME); /* as(2) */ |
| Bputc(&obuf, ANAME>>8); |
| Bputc(&obuf, t); /* type */ |
| Bputc(&obuf, s); /* sym */ |
| while(*n) { |
| Bputc(&obuf, *n); |
| n++; |
| } |
| Bputc(&obuf, 0); |
| } |
| |
| void |
| zaddr(Gen *a, int s) |
| { |
| int32 l; |
| int i, t; |
| char *n; |
| Ieee e; |
| |
| t = 0; |
| if(a->index != D_NONE || a->scale != 0) |
| t |= T_INDEX; |
| if(a->offset != 0) |
| t |= T_OFFSET; |
| if(s != 0) |
| t |= T_SYM; |
| |
| switch(a->type) { |
| default: |
| t |= T_TYPE; |
| break; |
| case D_FCONST: |
| t |= T_FCONST; |
| break; |
| case D_CONST2: |
| t |= T_OFFSET|T_OFFSET2; |
| break; |
| case D_SCONST: |
| t |= T_SCONST; |
| break; |
| case D_NONE: |
| break; |
| } |
| Bputc(&obuf, t); |
| |
| if(t & T_INDEX) { /* implies index, scale */ |
| Bputc(&obuf, a->index); |
| Bputc(&obuf, a->scale); |
| } |
| if(t & T_OFFSET) { /* implies offset */ |
| l = a->offset; |
| Bputc(&obuf, l); |
| Bputc(&obuf, l>>8); |
| Bputc(&obuf, l>>16); |
| Bputc(&obuf, l>>24); |
| } |
| if(t & T_OFFSET2) { |
| l = a->offset2; |
| Bputc(&obuf, l); |
| Bputc(&obuf, l>>8); |
| Bputc(&obuf, l>>16); |
| Bputc(&obuf, l>>24); |
| } |
| if(t & T_SYM) /* implies sym */ |
| Bputc(&obuf, s); |
| if(t & T_FCONST) { |
| ieeedtod(&e, a->dval); |
| l = e.l; |
| Bputc(&obuf, l); |
| Bputc(&obuf, l>>8); |
| Bputc(&obuf, l>>16); |
| Bputc(&obuf, l>>24); |
| l = e.h; |
| Bputc(&obuf, l); |
| Bputc(&obuf, l>>8); |
| Bputc(&obuf, l>>16); |
| Bputc(&obuf, l>>24); |
| return; |
| } |
| if(t & T_SCONST) { |
| n = a->sval; |
| for(i=0; i<NSNAME; i++) { |
| Bputc(&obuf, *n); |
| n++; |
| } |
| return; |
| } |
| if(t & T_TYPE) |
| Bputc(&obuf, a->type); |
| } |
| |
| void |
| outcode(int a, Gen2 *g2) |
| { |
| int sf, st, t; |
| Sym *s; |
| |
| if(pass == 1) |
| goto out; |
| |
| jackpot: |
| sf = 0; |
| s = g2->from.sym; |
| while(s != S) { |
| sf = s->sym; |
| if(sf < 0 || sf >= NSYM) |
| sf = 0; |
| t = g2->from.type; |
| if(t == D_ADDR) |
| t = g2->from.index; |
| if(h[sf].type == t) |
| if(h[sf].sym == s) |
| break; |
| zname(s->name, t, sym); |
| s->sym = sym; |
| h[sym].sym = s; |
| h[sym].type = t; |
| sf = sym; |
| sym++; |
| if(sym >= NSYM) |
| sym = 1; |
| break; |
| } |
| st = 0; |
| s = g2->to.sym; |
| while(s != S) { |
| st = s->sym; |
| if(st < 0 || st >= NSYM) |
| st = 0; |
| t = g2->to.type; |
| if(t == D_ADDR) |
| t = g2->to.index; |
| if(h[st].type == t) |
| if(h[st].sym == s) |
| break; |
| zname(s->name, t, sym); |
| s->sym = sym; |
| h[sym].sym = s; |
| h[sym].type = t; |
| st = sym; |
| sym++; |
| if(sym >= NSYM) |
| sym = 1; |
| if(st == sf) |
| goto jackpot; |
| break; |
| } |
| Bputc(&obuf, a); |
| Bputc(&obuf, a>>8); |
| Bputc(&obuf, stmtline); |
| Bputc(&obuf, stmtline>>8); |
| Bputc(&obuf, stmtline>>16); |
| Bputc(&obuf, stmtline>>24); |
| zaddr(&g2->from, sf); |
| zaddr(&g2->to, st); |
| |
| out: |
| if(a != AGLOBL && a != ADATA) |
| pc++; |
| } |
| |
| void |
| outhist(void) |
| { |
| Gen g; |
| Hist *h; |
| char *p, *q, *op, c; |
| int n; |
| |
| g = nullgen; |
| c = pathchar(); |
| for(h = hist; h != H; h = h->link) { |
| p = h->name; |
| op = 0; |
| /* on windows skip drive specifier in pathname */ |
| if(systemtype(Windows) && p && p[1] == ':'){ |
| p += 2; |
| c = *p; |
| } |
| if(p && p[0] != c && h->offset == 0 && pathname){ |
| /* on windows skip drive specifier in pathname */ |
| if(systemtype(Windows) && pathname[1] == ':') { |
| op = p; |
| p = pathname+2; |
| c = *p; |
| } else if(pathname[0] == c){ |
| op = p; |
| p = pathname; |
| } |
| } |
| while(p) { |
| q = strchr(p, c); |
| if(q) { |
| n = q-p; |
| if(n == 0){ |
| n = 1; /* leading "/" */ |
| *p = '/'; /* don't emit "\" on windows */ |
| } |
| q++; |
| } else { |
| n = strlen(p); |
| q = 0; |
| } |
| if(n) { |
| Bputc(&obuf, ANAME); |
| Bputc(&obuf, ANAME>>8); |
| Bputc(&obuf, D_FILE); /* type */ |
| Bputc(&obuf, 1); /* sym */ |
| Bputc(&obuf, '<'); |
| Bwrite(&obuf, p, n); |
| Bputc(&obuf, 0); |
| } |
| p = q; |
| if(p == 0 && op) { |
| p = op; |
| op = 0; |
| } |
| } |
| g.offset = h->offset; |
| |
| Bputc(&obuf, AHISTORY); |
| Bputc(&obuf, AHISTORY>>8); |
| Bputc(&obuf, h->line); |
| Bputc(&obuf, h->line>>8); |
| Bputc(&obuf, h->line>>16); |
| Bputc(&obuf, h->line>>24); |
| zaddr(&nullgen, 0); |
| zaddr(&g, 0); |
| } |
| } |
| |
| #include "../cc/lexbody" |
| #include "../cc/macbody" |