Annotation of researchv10no/cmd/spitbol/tokunx.spt, revision 1.1.1.1

1.1       root        1: -IN80
                      2: -TITLE TOKUNX: TRANSLATE FROM TOKENS TO UNIX ASSEMBLER
                      3: -STITL REVISION HISTORY
                      4: *
                      5: *  12-AUG-82 (REG):
                      6: *       Read tokenized input and remove EQUATES processing
                      7: * 09-MAR-82 (SGD):
                      8: *       CHK is back - better than ever...
                      9: *       Copy .INI file to start of .MAR file
                     10: * 10-SEP-81 (SGD):
                     11: *       Read in problem label table from filename.PLB
                     12: * 01-AUG-81 (SGD):
                     13: *       Better encoding of CTB,CTW,BTW and WTB
                     14: * 13-MAY-81 (SGD):
                     15: *       Added logic in XOP to put a longword type displacement on displacement
                     16: *       operands as VMS assembler assumes a word displacement. (Phhhhaaa - ed)
                     17: * 15-MAR-81 (SGD):
                     18: *       Made CHK a comment, as now handled as exception.
                     19: * 10-SEP-80 (SGD):
                     20: *       Made revisions to make XFER reflect VAX SBL capabilities.  Note that
                     21: *       this version of XFER is no longer capable of running on PDP-11, since
                     22: *       it will be too big.  [Major change was to substitute tables for LOOKUP
                     23: *       strings, and corresponding addition of TINIT].
                     24: * 02-AUG-80 (SGD):
                     25: *       Altered translation of conditional branches to emit conditional
                     26: *       branch directly.  Those which cause problems are listed in a
                     27: *       table that inhibits the direct translation.
                     28: * 18-MAY-80 (SGD):
                     29: *       Fixed translation of vertical tab (CH$VT) from ASCII 011 to ASCII 012
                     30: *       to conform to SOS Editor standard.
                     31: *
                     32: -STITL INTRODUCTION
                     33: *
                     34: *               ________________________________
                     35: *
                     36: *                        Coded by:
                     37: *                      Steven G. Duff
                     38: *                 1345-M16 Cabrillo Park Dr.
                     39: *                 Santa Ana, California 96701
                     40: *                      (714) 541-9619
                     41: *
                     42: *      This is a Macro Spitbol program for translation of the Macro
                     43: *      Spitbol Minimal Source to Vax 11/780 Macro Source.  The program
                     44: *      is fairly simple in order that it be able to run in the limited
                     45: *      address space of a PDP-11.  As a consequence, certain of the
                     46: *      Minimal Opcodes are left untranslated, to be expanded as macros
                     47: *      at assembly time.  These macros are:
                     48: *
                     49: *              AOV, BSW, CMC, CVD, CVM, ESW,
                     50: *              IFF, LSX, MCB, MFI, MVC, MVW, MWB, RMI, SEC, TRC.
                     51: *
                     52: *      There are two principal parts of Minimal that make translation
                     53: *      tricky vis-a-vis VAX MACRO-32:
                     54: *
                     55: *
                     56: *      Tricky #1: BSW,IFF and ESW normally require buffering, sorting
                     57: *              etc.  These can (and are) handled by macros though.  BSW
                     58: *              emits a CASEL and a word table containing the default
                     59: *              value.  IFF re-biases the location counter during assembly
                     60: *              and overwrites the default word.  ESW resets the location
                     61: *               counter back.  XFER is not capable of handling the needed
                     62: *               computation without more working store.
                     63: *
                     64: *       VVVVVVVVV  NOW HANDLED BY TOKENIZER
                     65: *       Tricky #2: Minimal operands of the form DLBL(X) must be translated
                     66: *               to 4*DLBL(X) as called for by the language spec.  This
                     67: *               requires that XFER be able to distinguish DLBLs from other
                     68: *               stuff.  This in turn means that a record of all EQU labels
                     69: *               must be kept.  This eats up a lot of working store, but
                     70: *               can't be helped.
                     71: *
                     72: *       The other macro-ops are simple enough, and are omitted purely to
                     73: *       avoid using up dynamic unnecessarily.
                     74: -EJECT
                     75: *       This program works with four files, with the same name, and
                     76: *       different extensions.  Name.MIN is used as the source input
                     77: *       file.  Name.MAR is created and becomes the source output file.
                     78: *       Name.ERR is created, and is where the ERR and ERB messages and
                     79: *       numbers are written.  Name.INI is a prefix (MACRO32) file
                     80: *       that is read as input and copied to Name.MAR before translation
                     81: *       begins.
                     82: *
                     83: *       The VAX assembler does not permit an equate to a register symbol
                     84: *       for the purpose of creating symbolic register names.
                     85: *       Thus this translator maps registers from Minimal to Vax thusly:
                     86: *
                     87: *                       RA  <=>  R2
                     88: *                       CP  <=>  R3
                     89: *                       IA  <=>  R5
                     90: *                      WA  <=>  R6
                     91: *                      WB  <=>  R7
                     92: *                      WC  <=>  R8
                     93: *                      XR  <=>  R9
                     94: *                      XL  <=>  R10  (XT ALSO)
                     95: *                      XS  <=>  SP   (R14)
                     96: *
                     97: *      Additionally, there are two other 'phantom' registers assumed
                     98: *      by the translator - a scratch register (SR) which is used by
                     99: *      a few instructions and by some of the character macros for
                    100: *      holding temps, and EXI for returns.  For remaindering,
                    101: *      a register (IA2) is presumed to be available immediately below IA.
                    102: *      The mappings of these registers are:
                    103: *
                    104: *                      IA2 <=>  R4
                    105: *                      SR  <=>  R11
                    106: *
                    107: *      Changes to this mapping are ill-advised and difficult.
                    108: *
                    109: *
                    110: *      XFER aint got much smarts (it cant afford them).  Except for cursory
                    111: *      syntax and opcode checks, almost anything will get through, so it
                    112: *      should be said that it expects valid Minimal Source.  Simple errors
                    113: *      are flagged on the listing (with a traceback) and a count given at
                    114: *      the end, so they should not be too hard to find.
                    115: -STITL INITIALIZATION
                    116: *                       WARNING - POST NO LABELS!!!!!
                    117: *                       -----------------------------
                    118: *       No labels should appear in this initializing code that would prevent
                    119: *       the code from being garbage-collected by SPITBOL.
                    120: -SPACE 3
                    121: *       Keyword initialization
                    122: *
                    123:         &ANCHOR = 1;    &TRIM = 1;      &STLIMIT = -1
                    124: *
                    125: *       Useful constants
                    126: *
                    127:         MINLETS = 'ABCDEFGHIJKLMNOPQRSTUVWXY$'
                    128:        ucase   = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
                    129:        lcase   = 'abcdefghijklmnopqrstuvwxyz'
                    130:         NOS     = '0123456789'
                    131:         TAB     = SUBSTR( &ALPHABET,10,1 )
                    132:         REGNAME = ('X' ANY('LSTR')) | ('W' ANY('ABC')) | 'IA' | 'RA' | 'CP'
                    133: *
                    134: *       Zero the counts
                    135: *
                    136:         LABCNT = NOUTLINES = NLINES = NSTMTS = NTARGET = NERRORS = 0
                    137: *
                    138: *       Get file name
                    139: *
                    140:         FILENAMI = INPUT
                    141:        TERMINAL = 'TOKEN file: ' FILENAMI
                    142:         TERMINAL =
                    143:         FILENAMP = INPUT
                    144:        TERMINAL = 'Problem label file: ' FILENAMP
                    145:         TERMINAL =
                    146:         FILENAMO = INPUT
                    147:        TERMINAL = 'ASSEMBLER file: ' FILENAMO
                    148:         TERMINAL =
                    149: 
                    150:         FLCFLAG  = REPLACE( INPUT,'y','Y' )
                    151:        TERMINAL = 'Full line comments passed? ' FLCFLAG
                    152: *
                    153: *       No page ejects without full line comments
                    154: *
                    155:         TERMINAL = DIFFER(FLCFLAG,'N')
                    156:         EJCFLAG  = REPLACE( (DIFFER(FLCFLAG,'N') INPUT, 'N'),'y','Y' )
                    157:        TERMINAL = 'EJCs passed? ' EJCFLAG
                    158: -STITL XFER FUNCTIONS
                    159: *       TINIT is used during initialization to take a string of the
                    160: *       form  "index1[value1]index2[value2]...indexn[valuen]" and
                    161: *       stuff the index/value pairs into a table which it returns.
                    162: *
                    163:        DEFINE('TINIT(STR)POS,CNT,INDEX,VAL,LASTVAL')
                    164: *      CRACK parses STMT into a STMT data plex and returns it.
                    165: *      It fails if there is a syntax error.
                    166: *
                    167:        DEFINE('CRACK(LINE)LABEL,OPCODE,OPERANDS,COMMENT,OPERAND,CHAR')
                    168: *
                    169: *      STMT is the common data plex used to hold the components of
                    170: *      a statement (either Minimal or VAX) during processing.
                    171: *
                    172:        DATA('STMT(LABEL,OPCODE,OP1,OP2,OP3,COMMENT)')
                    173: *
                    174: *      MINLABEL is a pattern matching a valid Minimal Source Label.
                    175: *
                    176:        MINLABEL = ANY(MINLETS) ANY(MINLETS) ANY(MINLETS NOS)
                    177: +                 ANY(MINLETS NOS) ANY(MINLETS NOS)
                    178: *
                    179: *      MINCOND is a pattern that matches Minimal Conditional assembly ops
                    180: *
                    181:        MINCOND = 'IF' | 'THEN' | 'ELSE' | 'FI' | 'DEF' | 'UNDEF'
                    182: *
                    183: -EJECT
                    184: *       DOSTMT is the driver routine that causes processing of the
                    185: *       statement plex in THISSTMT.
                    186: *
                    187:         DEFINE('DOSTMT()LABEL,OPCODE,OP1,OP2,OP3,COMMENT,T')
                    188: *
                    189: *       HANDLER is a table providing the name of the processing appendage
                    190: *       for every Minimal Op-Code.  The name in this table is prefixed with
                    191: *       "H_" to get the string name of the appendage.  Every op must be
                    192: *       in this string, including conditional ops.
                    193: *
                    194:         HANDLER = TINIT(
                    195: +               'ADD[H]ADI[ADD2]ADR[ADD2]ANB[ANB]'
                    196: +               'AOV[AOV]BCT[H]BEQ[BCMP]BGE[BCMP]'
                    197: +               'BGT[BCMP]BHI[BCMP]BLE[BCMP]BLO[BCMP]'
                    198: +               'BLT[BCMP]BNE[BCMP]BRN[H]BRI[BRI]'
                    199: +               'BNZ[BTST]'
                    200: +               'BSW[BSW]BTW[BTW]BZE[BTST]CEQ[BCMP]'
                    201: +               'CHK[SBCALL]CMB[CMB]CMC[CMC]CNE[BCMP]'
                    202: +               'CSC[NOOP]CTB[CTX]CTW[CTX]CVD[CVD]'
                    203: +               'CVM[CVM]DAC[H]DBC[H]DCA[NEW1]'
                    204: +               'DCV[H]DEF[ZZZ]DIC[DXC]DRC[DXC]'
                    205: +               'DTC[DTC]DVI[ADD2]DVR[ADD2]EJC[EJC]'
                    206: +               'ELSE[ZZZ]END[END]ENP[NOOP]ENT[ENT]'
                    207: +               'EQU[EQU]ERB[ERX]ERR[ERX]ESW[NOOP]'
                    208: +               'EXI[EXI]EXP[GBLS]FI[ZZZ]FLC[FLC]ICA[NEW1]'
                    209: +               'ICP[ICP]ICV[H]IEQ[ATST]IF[ZZZ]'
                    210: +               'IFF[IFF]IGE[ATST]IGT[ATST]ILE[ATST]'
                    211: +               'ILT[ATST]INE[ATST]INO[OVF]INP[GBLS]'
                    212: +               'INR[GBLS]IOV[OVF]ITR[ITR]JSR[H]'
                    213: +               'LCH[SWP12]LCT[LCT]LCP[ADD2]LCW[NEW1]'
                    214: +               'LDI[ADD2]LDR[ADD2]LEI[LEI]LSH[XSH]'
                    215: +               'LSX[H]MCB[SBCALL]MFI[MFI]MLI[ADD2]MLR[ADD2]'
                    216: +               'MNZ[NEW1]MOV[H]MTI[ADD2]MVC[SBCALL]'
                    217: +               'MVW[SBCALL]MWB[SBCALL]NGI[NGX]NGR[NGX]'
                    218: +               'NZB[BTST]ORB[H]PLC[PXC]PPM[PPM]'
                    219: +               'PRC[PRC]PSC[PXC]REQ[ATST]RGE[ATST]'
                    220: +               'RGT[ATST]RLE[ATST]RLT[ATST]RMI[RMI]'
                    221: +               'RNE[ATST]RNO[OVF]ROV[OVF]RSH[XSH]'
                    222: +               'RSX[H]RTI[RTI]RTN[NOOP]SBI[ADD2]'
                    223: +               'SBR[ADD2]SCH[H]SCP[NEW1]SEC[SEC]'
                    224: +               'SSL[NOOP]SSS[NOOP]STI[STX]STR[STX]'
                    225: +               'SUB[H]THEN[ZZZ]TRC[SBCALL]TTL[TTL]'
                    226: +               'ZZZ[UNDEF]WTB[WTB]XOB[H]'
                    227: +               'ZER[H]ZGB[NOOP]ZRB[BTST]')
                    228: *
                    229: *       H_ADD2.OPS is used by the H_ADD2 appendage to find
                    230: *       the operand it is to insert.
                    231: *
                    232:         H_ADD2.OPS = TINIT(
                    233: +               'ADI[R5]ADR[R2]DVI[R5]DVR[R2]LCP[R3]LDI[R5]'
                    234: +               'LDR[R2]MLI[R5]MLR[R2]MTI[R5]SBI[R5]SBR[R2]')
                    235: -EJECT
                    236: *       H_BNCH.OPCS provides opcode translations for branch-type
                    237: *       instructions.  Branches are emitted directly, unless they are
                    238: *       in the H_BNCH.PLAB problem label table, in which case an inverted
                    239: *       branch/jump combination is emitted.
                    240: *
                    241:         H_BNCH.OPCS = TINIT('BEQ[BEQLU]BGE[BGEQU]BGT[BGTRU]BHI[BGEQU]'
                    242: +               'BLE[BLEQU]BLO[BLEQU]BLT[BLSSU]BNE[BNEQU]'
                    243: +               'BNZ[BNEQU]BZE[BEQLU]CEQ[BEQLU]'
                    244: +               'CNE[BNEQU]IEQ[BEQL]IGE[BGEQ]IGT[BGTR]'
                    245: +               'ILE[BLEQ]ILT[BLSS]INE[BNEQ]INO[BVC]'
                    246: +               'IOV[BVS]NZB[BNEQU]'
                    247: +               'REQ[BEQL]RGE[BGEQ]RGT[BGTR]RLE[BLEQ]'
                    248: +               'RLT[BLSS]RNE[BNEQ]RNO[BVC]ROV[BVS]'
                    249: +               'ZRB[BEQLU]')
                    250: *
                    251: *       H_BNCH.PLAB is a list of problem labels which for which 'short'
                    252: *       conditional jumps cannot be issued, because one or more instructions
                    253: *       in the code cause range trouble.  Inverted branches are emitted
                    254: *       instead.
                    255: *
                    256:         H_BNCH.PLAB = TABLE(101)
                    257: *
                    258: *       H_BNCH.IOCS is a translate list for the inverted branches needed
                    259: *       for problem labels.
                    260: *
                    261:         H_BNCH.IOCS = TINIT('BEQ[BNEQU]BGE[BLSSU]BGT[BLEQU]BHI[BLSSU]'
                    262: +               'BLE[BGTRU]BLO[BGTRU]BLT[BGEQU]BNE[BEQLU]'
                    263: +               'BNZ[BEQLU]BZE[BNEQU]CEQ[BNEQU]'
                    264: +               'CNE[BEQLU]IEQ[BNEQ]IGE[BLSS]IGT[BLEQ]'
                    265: +               'ILE[BGTR]ILT[BGEQ]INE[BEQL]INO[BVS]'
                    266: +               'IOV[BVC]NZB[BEQLU]'
                    267: +               'REQ[BNEQ]RGE[BLSS]RGT[BLEQ]RLE[BGTR]'
                    268: +               'RLT[BGEQ]RNE[BEQL]RNO[BVS]ROV[BVC]'
                    269: +               'ZRB[BNEQU]')
                    270: *
                    271: *       H_EQU.DEFS is used by H_EQU to insert the fluid EQU
                    272: *       definitions (...EQU *).
                    273: *
                    274:         H_EQU.DEFS = TINIT(
                    275: +               'CFP$A[256]CFP$B[4]CFP$C[4]CFP$F[8]'
                    276: +               'CFP$I[1]CFP$M[0X7FFFFFFF]CFP$N[32]'
                    277: +              'NSTMX[10]CFP$R[1]CFP$S[6]CFP$X[2]'
                    278: +              'CFP$U[128]'
                    279: +              'E$SRS[50]E$STS[512]E$CBS[512]E$HNB[253]'
                    280: +              'E$HNW[3]E$FSP[20]'
                    281: +              'CH$LA[065]CH$LB[066]CH$LC[067]CH$LD[068]'
                    282: +               'CH$LE[069]CH$LF[070]CH$LG[071]CH$LH[072]'
                    283: +               'CH$LI[073]CH$LJ[074]CH$LK[075]CH$LL[076]'
                    284: +               'CH$LM[077]CH$LN[078]CH$LO[079]CH$LP[080]'
                    285: +               'CH$LQ[081]CH$LR[082]CH$LS[083]CH$LT[084]'
                    286: +               'CH$LU[085]CH$LV[086]CH$LW[087]CH$LX[088]'
                    287: +               'CH$LY[089]CH$L$[090]'
                    288: +               'CH$D0[048]CH$D1[049]CH$D2[050]CH$D3[051]'
                    289: +               'CH$D4[052]CH$D5[053]CH$D6[054]CH$D7[055]'
                    290: +               'CH$D8[056]CH$D9[057]'
                    291: +               'CH$$A[097]CH$$B[098]CH$$C[099]CH$$D[100]'
                    292: +               'CH$$E[101]CH$$F[102]CH$$G[103]CH$$H[104]'
                    293: +               'CH$$I[105]CH$$J[106]CH$$K[107]CH$$L[108]'
                    294: +               'CH$$M[109]CH$$N[110]CH$$O[111]CH$$P[112]'
                    295: +               'CH$$Q[113]CH$$R[114]CH$$S[115]CH$$T[116]'
                    296: +               'CH$$U[117]CH$$V[118]CH$$W[119]CH$$X[120]'
                    297: +               'CH$$Y[121]CH$$$[122]'
                    298: +               'CH$AM[038]CH$AS[042]CH$AT[064]CH$BB[060]'
                    299: +               'CH$BL[032]CH$BR[124]CH$CL[058]CH$CM[044]'
                    300: +               'CH$DL[036]CH$DT[046]CH$DQ[034]CH$EQ[061]'
                    301: +               'CH$EX[033]CH$MN[045]CH$NM[035]CH$NT[126]'
                    302: +               'CH$PC[037]CH$PL[043]CH$PP[040]CH$RB[062]'
                    303: +               'CH$RP[041]CH$QU[063]CH$SL[047]CH$SM[059]'
                    304: +               'CH$SQ[039]CH$UN[095]CH$OB[091]CH$CB[093]'
                    305: +               'CH$HT[009]CH$VT[012]IODEL[000]')
                    306: -EJECT
                    307: *       H_H.XOPS is a table that encodes opcode translation
                    308: *       for H_H.
                    309: *
                    310:         H_H.XOPS =  TINIT(
                    311: +               'ADD[ADDL2]ADI[ADDL2]ADR[ADDF2]ANB[BICL2]'
                    312: +               'BCT[SOBGTR]'
                    313: +               'BRN[JMP]'
                    314: +               'CMB[MCOML]'
                    315: +               'CTB[BICL2]CTW[ASHL]'
                    316: +               'DAC[.LONG]DBC[.LONG]'
                    317: +               'DCA[SUBL2]DCV[DECL]DIC[.LONG]DRC[.FLOAT]'
                    318: +               'DVI[DIVL2]DVR[DIVF2]EJC[#PAGE]'
                    319: +               'ERB[JMP]'
                    320: +               'ERR[.LONG]'
                    321: +               'ICA[ADDL2]ICP[TSTL]ICV[INCL]'
                    322: +               'ITR[CVTLF]JSR[JSB]'
                    323: +               'LCH[MOVZBL]LCT[MOVL]LCP[MOVL]LCW[MOVL]'
                    324: +               'LDI[MOVL]LDR[MOVF]LEI[MOVZWL]LSH[ASHL]'
                    325: +               'MLI[MULL2]MLR[MULF2]'
                    326: +               'MNZ[MOVL]MOV[MOVL]MTI[MOVL]'
                    327: +               'NGI[MNEGL]NGR[MNEGF]'
                    328: +               'ORB[BISL2]PPM[.LONG]'
                    329: +               'RSH[ASHL]'
                    330: +               'SBI[SUBL2]'
                    331: +               'SBR[SUBF2]SCH[MOVB]SCP[MOVL]'
                    332: +              'SEC[#SEC]'
                    333: +               'STI[MOVL]STR[MOVF]'
                    334: +               'SUB[SUBL2]'
                    335: +               'TTL[#TITLE]'
                    336: +               'XOB[XORL2]ZER[CLRL]')
                    337: *
                    338: *       H_NEW1.OPS is a table used by the H_NEW1 appendage to find
                    339: *       the operand to insert.  It is indexed by opcode.
                    340: *
                    341:         H_NEW1.OPS = TINIT(
                    342: +               'ICA[$4]DCA[$4]'
                    343: +               'LCW[(R3)+]MNZ[SP]SCP[R3]')
                    344: *
                    345: *       Associate file for ERB,ERR messages in H_ERX
                    346: *
                    347:         OUTPUT(.ERRFILE,4,(IDENT(FILENAMO) '',  'min.err'))
                    348: -EJECT
                    349: *       Error is used to report an error for THISSTMT
                    350: *
                    351:         DEFINE('ERROR(TEXT)')
                    352: -SPACE 3
                    353: *       OUTSTMT is used to send a target statement to the target code
                    354: *       output file (OUTFILE <=> LU2)
                    355: *
                    356:         DEFINE('OUTSTMT(LABEL,OPCODE,OP1,OP2,OP3,COMMENT)T,STMTOUT')
                    357: *
                    358: *       Associate output file
                    359: *
                    360:         OUTPUT(.OUTFILE,2,(IDENT(FILENAMO) '', FILENAMO))
                    361: *
                    362: *       OS.LLS is used by OUTSTMT to recognise local labels
                    363: *
                    364:         OS.LLS  = SPAN(NOS) '$' RPOS(0)
                    365: *
                    366: *       READLINE is called to return the next non-comment line from
                    367: *       the Minimal input file (INFILE <=> LU1).   Note that it will
                    368: *       not fail on EOF, but it will return a Minimal END statement
                    369: *
                    370:         DEFINE('READLINE()')
                    371: *
                    372: *       Associate input file to LU1
                    373: *
                    374:         INPUT(.INFILE,1,(IDENT(FILENAMI) '', FILENAMI))
                    375: -EJECT
                    376: *
                    377: *       XOP.REGS is a pattern to match out register names for translation.
                    378: *
                    379:         XOP.REGS = (*REGNAME . VAL  RPOS(0) . PREFIX)  |
                    380: +                  (BREAK('(') LEN(1)) . PREFIX   LEN(2) . VAL
                    381: *
                    382: *       XOP.XREGS is a table with register translations
                    383: *
                    384:         XOP.XREGS = TINIT('IA[R5]RA[R2]CP[R3]WA[R6]WB[R7]WC[R8]XR[R9]'
                    385: +                   'XL[R10]XT[R10]XS[SP]')
                    386: *
                    387: *       XPINTX is a pattern that will match the INT(X) type operand
                    388: *
                    389:         XPINTX  = SPAN(NOS) . VAL  '('
                    390: *
                    391: *       XPDLBLX is a pattern that will match the DLBL(X) type operand
                    392: *
                    393:         XPDLBLX = MINLABEL . VAL  '('
                    394: -STITL MAIN PROGRAM
                    395: *       Here follows the driver code for the "main" program.
                    396: -SPACE 3
                    397: *       Read the problem label table
                    398: *
                    399:         INPUT(.PLTAB,.PLTAB,DIFFER(FILENAMP) FILENAMP)  :F(MN02)
                    400: MN01    H_BNCH.PLAB[PLTAB] = 1                        :S(MN01)
                    401:         ENDFILE(.PLTAB)
                    402: MN02
                    403: *
                    404: *       Loop until program exits via H_END
                    405: *
                    406: MN04    DOSTMT()                                        :(MN04)
                    407: -STITL CRACK(LINE)
                    408: *       CRACK is called to create a STMT plex containing the various
                    409: *       entrails of the Minimal Source statement in LINE.  For
                    410: *       conditional assembly ops, the opcode is the op, and OP1
                    411: *       is the symbol.  Note that DTC is handled as a special case to
                    412: *       assure that the decomposition is correct.
                    413: *
                    414: *       CRACK will print an error and fail if a syntax error occurs.
                    415: *
                    416: CRACK   NSTMTS  = NSTMTS + 1
                    417:         LINE    '{' BREAK( '{' ) . LABEL
                    418: +               '{' BREAK( '{' ) . OPCODE
                    419: +               '{' BREAK( '{' ) . OP1
                    420: +               '{' BREAK( '{' ) . OP2
                    421: +               '{' BREAK( '{' ) . OP3
                    422: +               '{' REM          . COMMENT              :F(CS03)
                    423:         IDENT(OPCODE,'DTC')                             :S(CS00)
                    424:         OP1 ANY('@') = '*'
                    425:         OP1 ANY('#') = '$'
                    426:         OP2 ANY('@') = '*'
                    427:         OP2 ANY('#') = '$'
                    428: CS00    CRACK   = STMT(LABEL,OPCODE,OP1,OP2,OP3,COMMENT)
                    429: *
                    430: *       Operands all parsed out.  That's all folks.
                    431: *
                    432: CS01    :(RETURN)
                    433: *
                    434: *       Here on syntax error
                    435: *
                    436: CS03    ERROR('SOURCE LINE SYNTAX ERROR')               :(FRETURN)
                    437: -STITL DOSTMT()
                    438: *       DOSTMT is invoked to initiate processing of the next line from
                    439: *       READLINE.  For efficient access
                    440: *       DOSTMT puts name values corresponding to the components in
                    441: *       variables with the same names (LABEL, OPCODE, OP1,OP2,OP3 and
                    442: *       COMMENT) which allows the various handlers to $var to store/fetch
                    443: *       the values of the statment.
                    444: *
                    445: *       After doing this, DOSTMT branches to the handler routine indicated
                    446: *       for this opcode in the HANDLER table (there must be an entry or
                    447: *       an error results).  The handlers all have entry points beginning
                    448: *       with "H_", and can be considered a logical extension of the
                    449: *       DOSTMT routine.  The handlers have the choice of branching back
                    450: *       to DSGEN to cause the THISSTMT plex to be sent to OUTSTMT, or
                    451: *       of RETURNing themselves, in which case the handler must output
                    452: *       all needed code itself.
                    453: *
                    454: *       The handlers are listed in a separate section below.
                    455: *
                    456: DOSTMT  THISLINE = READLINE()
                    457:         THISSTMT = CRACK(THISLINE)              :F(DOSTMT)
                    458:         LABEL   = .LABEL(THISSTMT)
                    459:         OPCODE  = .OPCODE(THISSTMT)
                    460:        MINOP   = $OPCODE
                    461:        OP1     = .OP1(THISSTMT)
                    462:        OP2     = .OP2(THISSTMT)
                    463:        OP3     = .OP3(THISSTMT)
                    464:        COMMENT = .COMMENT(THISSTMT)
                    465: *
                    466: *      Get handler entry point (less "H_" prefix)
                    467: *
                    468:        DIFFER(T = HANDLER[$OPCODE])                    :F(DS01)
                    469: *
                    470: *      Jump to handler
                    471: *
                    472:        :($('H_' T))
                    473: *
                    474: *      Here if bad OpCode
                    475: *
                    476: DS01   ERROR('BAD OP-CODE')                            :(RETURN)
                    477: *
                    478: *      Handlers can come back here to cause code generation of THISSTMT
                    479: *
                    480: DSGEN  OUTSTMT($LABEL,$OPCODE,$OP1,$OP2,$OP3,$COMMENT) :(RETURN)
                    481: -STITL ERROR(TEXT)
                    482: *       This module handles reporting of errors with the offending
                    483: *       statement text in THISLINE.  Comments explaining
                    484: *       the error are written to the listing (including error chain), and
                    485: *       the appropriate counts are updated.
                    486: *
                    487: ERROR   OUTFILE = '# *???* ' THISLINE
                    488:         OUTFILE = '#       ' TEXT
                    489: +                 (IDENT(LASTERROR),'. LAST ERROR WAS LINE ' LASTERROR)
                    490:         LASTERROR = NOUTLINES
                    491:         NOUTLINES = NOUTLINES + 2
                    492:         NERRORS = NERRORS + 1
                    493: +                       :(RETURN)
                    494: -STITL OUTSTMT(LABEL,OPCODE,OP1,OP2,OP3,COMMENT)
                    495: *       This module writes the components of the VAX MACRO statement
                    496: *       passed in the argument list to the formatted .MAR file
                    497: *
                    498: OUTSTMT STMTOUT = (IDENT(LABEL) TAB,
                    499: +                       LABEL ':'  TAB)
                    500: +                 OPCODE  (GT(SIZE(OPCODE),7) ' ', TAB)
                    501: +                 (IDENT(OP1), OP1
                    502: +                       (IDENT(OP2), ',' OP2
                    503: +                               (IDENT(OP3), ',' OP3)))
                    504: +                 (IDENT(COMMENT),
                    505: +                       (GT(T = SIZE(OP1 OP2 OP3), 16) ' ',
                    506: +                               DUPL(TAB, (22 - T) / 8))
                    507: +                       '# ' COMMENT)
                    508: *
                    509: *      Translate everything but string constants to lower case.
                    510: *
                    511:        stmtout = differ( opcode,'.ASCII' )
                    512: +                replace( stmtout,ucase,lcase )
                    513:        stmtout  ident( opcode,'.ASCII' )
                    514: +               ( break(*tab) *tab break(*tab) ) $ t =
                    515: +               replace( t,ucase,lcase )
                    516: *
                    517: *       Send text to OUTFILE
                    518: *
                    519:         OUTFILE = STMTOUT
                    520:         NTARGET = NTARGET + 1
                    521:         NOUTLINES = NOUTLINES + 1
                    522: +                       :(RETURN)
                    523: -STITL READLINE()
                    524: *       This routine returns the next statement line in the input file
                    525: *       to the caller.  It never fails.  If there is no more input,
                    526: *       then a Minimal END statement is returned.
                    527: *       Comments are passed through to the output file directly.
                    528: *
                    529: *
                    530: READLINE READLINE = INFILE                      :F(RL02)
                    531:         NLINES  = NLINES + 1
                    532:         READLINE  ANY('*') = '#'                :F(RL01)
                    533: *
                    534: *       Only print comment if requested.
                    535: *
                    536:         OUTFILE = IDENT(FLCFLAG,'Y') READLINE   :F(READLINE)
                    537:         NOUTLINES = NOUTLINES + 1               :(READLINE)
                    538: *
                    539: *       Here if not a comment line
                    540: *
                    541: RL01    :(RETURN)
                    542: *
                    543: *       Here on EOF
                    544: *
                    545: RL02    READLINE = '       END'
                    546:                         :(RL01)
                    547: -STITL TINIT(STR)
                    548: *       This routine is called to initialize a table from a string of
                    549: *       index/value pairs.
                    550: *
                    551: TINIT   POS     = 0
                    552: *
                    553: *       Count the number of "[" symbols to get an assessment of the table
                    554: *       size we need.
                    555: *
                    556: TIN01   STR     (TAB(*POS) '[' BREAK(']') *?(CNT = CNT + 1) @POS)
                    557: +                                       :S(TIN01)
                    558: *
                    559: *       Allocate the table, and then fill it. Note that a small memory
                    560: *       optimisation is attempted here by trying to re-use the previous
                    561: *       value string if it is the same as the present one.
                    562: *
                    563:         TINIT   = TABLE(CNT)
                    564: TIN02   STR     (BREAK('[') $ INDEX LEN(1) BREAK(']') $ VAL LEN(1)) =
                    565: +                                       :F(RETURN)
                    566:         VAL     = CONVERT(VAL,'INTEGER')
                    567:         VAL     = IDENT(VAL,LASTVAL) LASTVAL
                    568:         LASTVAL = VAL
                    569:         TINIT[INDEX] = VAL              :(TIN02)
                    570: -STITL OPCODE HANDLER APPENDAGES
                    571: *       Ops that need a second operand (get from table).
                    572: *
                    573: H_ADD2  $OP2    = H_ADD2.OPS[$OPCODE]           :(H_H)
                    574: -SPACE 3
                    575: *       Do ANB opcode
                    576: *
                    577: H_ANB   OUTSTMT($LABEL,'MCOML',$OP1,'R11',,$COMMENT)
                    578:         $OP1    = 'R11'
                    579:         $LABEL  = $COMMENT =                    :(H_H)
                    580: -SPACE 3
                    581: *       DO AOV
                    582: *
                    583: H_AOV   OUTSTMT($LABEL,'ADDL2',$OP1,$OP2,,$COMMENT)
                    584:         OUTSTMT(,'BVC','0F')
                    585:         OUTSTMT(,'JMP',$OP3)
                    586:         OUTSTMT('0')                            :(RETURN)
                    587: -SPACE 3
                    588: *       Real and Integer Branch tests
                    589: *       CHANGE CALL OF XOP TO XOP.XREGS LOOKUP
                    590: *
                    591: H_ATST  OUTSTMT($LABEL,'TST' (IDENT(SUBSTR($OPCODE,1,1),'R') 'F', 'L'),
                    592: +               XOP.XREGS[SUBSTR($OPCODE,1,1) 'A'],,,$COMMENT)
                    593:         $OP2    = $OP1                          :(H_BNCH)
                    594: -SPACE 3
                    595: *       Comparison branches - emit a CMPL
                    596: *
                    597: H_BCMP  OUTSTMT($LABEL,'CMPL',$OP1,$OP2,,$COMMENT)
                    598:         $OP2    = $OP3                          :(H_BNCH)
                    599: -SPACE 3
                    600: *       Entered via various handlers to generate conditional branch code
                    601: *
                    602: H_BNCH  DIFFER(H_BNCH.PLAB[$OP2])       :S(H_BNCH01)
                    603:         OUTSTMT(,H_BNCH.OPCS[$OPCODE],$OP2)     :(RETURN)
                    604: H_BNCH01 OUTSTMT(,H_BNCH.IOCS[$OPCODE],'0F')
                    605:         OUTSTMT(,'JMP',$OP2)
                    606:         OUTSTMT('0')                            :(RETURN)
                    607: -SPACE 3
                    608: *       Handle BRI instruction with indirection
                    609: *
                    610: H_BRI   OUTSTMT($LABEL,'MOVL',$OP1,'R11',,$COMMENT)
                    611:         OUTSTMT(,'JMP','(R11)')                 :(RETURN)
                    612: -EJECT
                    613: *
                    614: *      BSW generates a CASEL and a label for .WORD references.
                    615: *
                    616: h_bsw  outstmt( $label,'CASEL',$OP1,'$0','$' $OP2,$COMMENT )
                    617:        outstmt( '5' )                          :(return)
                    618: -SPACE 3
                    619: *       Zero branch comparisons
                    620: *
                    621: H_BTST  OUTSTMT($LABEL,'TSTL',$OP1,,,$COMMENT)
                    622: +                                               :(H_BNCH)
                    623: -EJECT
                    624: *       BTW opcode
                    625: *
                    626: H_BTW   OUTSTMT($LABEL,'ASHL','$-2',$OP1,$OP1,$COMMENT) :(RETURN)
                    627: -SPACE 3
                    628: *       Do CMB instruction by duping operand for MCOML
                    629: *
                    630: H_CMB   $OP2    = $OP1                          :(H_H)
                    631: -SPACE 3
                    632: *       DO CMC INSTRUCTION BY SUBROUTINE CALL
                    633: *
                    634: H_CMC   OUTSTMT($LABEL,'JSB','SBCMC',,,$COMMENT)
                    635:         OUTSTMT(,'.LONG',$OP1)
                    636:         OUTSTMT(,'.LONG',$OP2)                  :(RETURN)
                    637: -SPACE 3
                    638: *       Do CTB and CTW
                    639: *
                    640: H_CTX   OUTSTMT($LABEL,'MOVAB','3+(4*' $OP2 ')(' $OP1 ')',$OP1,,$COMMENT)
                    641:         $LABEL  = $COMMENT =
                    642:         $OP2    = $OP1
                    643:         $OP1    = (IDENT($OPCODE,'CTB') '$3','$-2')
                    644:         $OP3    = IDENT($OPCODE,'CTW') $OP2             :(H_H)
                    645: -SPACE 3
                    646: *       DO CVD
                    647: *
                    648: H_CVD   OUTSTMT($LABEL,'ASHQ','$-32','R4','R4',$COMMENT)
                    649:         OUTSTMT(,'EDIV','$10','R4,R5,R6')
                    650:         OUTSTMT(,'MNEGL','R6','R6')
                    651:         OUTSTMT(,'BISB2','$0X30','R6')                  :(RETURN)
                    652: -SPACE 3
                    653: *       DO CVM
                    654: *
                    655: H_CVM   OUTSTMT($LABEL,'MULL2','$10','R5',,$COMMENT)
                    656:         OUTSTMT(,'BVC','0F')
                    657:         OUTSTMT(,'JMP',$OP1)
                    658:         OUTSTMT('0','BICL2','$0XFFFFFFF0','R7')
                    659:         OUTSTMT(,'SUBL2','R7','R5')
                    660:         OUTSTMT(,'BVC','1F')
                    661:         OUTSTMT(,'JMP',$OP1)
                    662:         OUTSTMT('1')                                   :(RETURN)
                    663: -SPACE 3
                    664: *      Handle DIC and DRC by stripping leading plus (UNIX as does not
                    665: *      support unary plus) and placing "0f" in front of single
                    666: *      precision floating point constants.
                    667: *
                    668: h_dxc  $op1 '+' =
                    669:        $op1 = ident( $opcode,'DRC' ) '0f' $op1 :(h_h)
                    670: -SPACE 3
                    671: *       Handle DTC by emitting .ASCII and then alignment order
                    672: *
                    673: H_DTC   $OP1    = '"' SUBSTR($OP1,2,SIZE($OP1) - 2) '"'
                    674:         OUTSTMT($LABEL,'.ASCII',$OP1,,,$COMMENT)
                    675:         OUTSTMT(,'.ALIGN','2',)                  :(RETURN)
                    676: -SPACE 3
                    677: *       EJC checks to see if page feeds are to be passed.
                    678: *
                    679: H_EJC   IDENT(EJCFLAG,'Y')                      :S(H_H)F(RETURN)
                    680: -SPACE 3
                    681: *       END prints statistics on terminal then exits program
                    682: *
                    683: H_END   OUTSTMT(,'#END',,,,$COMMENT)
                    684:         TERMINAL = '*** TRANSLATION COMPLETE ***'
                    685:         TERMINAL = NLINES ' LINES READ.'
                    686:         TERMINAL = NSTMTS ' STATEMENTS PROCESSED.'
                    687:         TERMINAL = NTARGET ' TARGET CODE LINES PRODUCED.'
                    688:         TERMINAL = NERRORS ' ERRORS OCCURRED.'
                    689:         TERMINAL = DIFFER(LASTERROR) 'THE LAST ERROR WAS IN LINE ' LASTERROR
                    690:         &CODE   = NE(NERRORS) 2001
                    691:         :(END)
                    692: -EJECT
                    693: *       ENT emits the word ID (if needed) and the entry label
                    694: *
                    695: H_ENT   IDENT($OP1)                     :S(H_ENT01)
                    696:         OUTSTMT(,'.ALIGN','2')
                    697:         OUTSTMT(,'.WORD',$OP1)
                    698: *
                    699: *       Merge here to emit label entry point
                    700: *
                    701: H_ENT01 OUTSTMT($LABEL,,,,,$COMMENT)    :(RETURN)
                    702: *       Handle EQU by substituting '*' operands from definitions table
                    703: *       if necessary
                    704: *
                    705: H_EQU   $OP2    = $OP1
                    706:         $OPCODE = '.SET'
                    707:         $OP1    = $LABEL
                    708:         $OP2    = IDENT($OP2,'*') H_EQU.DEFS[$LABEL]
                    709:         $LABEL  =                                       :(DSGEN)
                    710: -SPACE 3
                    711: *       Handle ERB and ERR in essentially the same way.  First, send
                    712: *       the message to the auxilliary .ERR file.  Then make sure to
                    713: *       note if this is the highest error # seen so far, so branch
                    714: *       table can be properly emitted (see SEC).  Then set OP1 to
                    715: *       be "ERROR_" concatenated with the error number.  This label
                    716: *       refers to a label in the jump table that will load this error
                    717: *       code in WA and jump to ERROR$.
                    718: *
                    719: H_ERX   ERRFILE = LPAD($OP1,3,0) ($COMMENT = (IDENT($OP2), $OP2 ' ')
                    720: +                       $COMMENT)
                    721:         MAXERR  = GT($OP1,MAXERR) $OP1
                    722:         $OP1    = 'ER_' LPAD($OP1,3,0)
                    723:         $OP2    =                               :(H_H)
                    724: -EJECT
                    725: *       There are 8 cases to EXI, partitioned along 3 binary dimensions.
                    726: *       These are: 1. OP1 given/not given,  2. PTYPE is R/E or N,
                    727: *       3. OP1=1 (or #Ppms=0 if OP1 not given).  Each possibility generates
                    728: *       slightly different code.
                    729: *
                    730: H_EXI   IDENT($OP1)                             :S(H_EXI00)
                    731:         T       = (IDENT(PTYPE,'N') PNAME '_S','(SP)+')
                    732:         (EQ($OP1,1) OUTSTMT($LABEL,'MOVL',T,'R11',,$COMMENT),
                    733: +                OUTSTMT($LABEL,'ADDL3','$4*' $OP1 - 1,T,'R11',$COMMENT))
                    734:         OUTSTMT(,'JMP','*(R11)+')               :(H_EXI04)
                    735: *
                    736: *       Here if EXI has no OP1 given (normal exit)
                    737: *
                    738: H_EXI00 EQ(PPMS,0)                              :S(H_EXI02)
                    739:         IDENT(PTYPE,'N')                        :S(H_EXI01)
                    740: *
                    741: *       No OP1, #PPMs>0 and R/E-type
                    742: *
                    743:         OUTSTMT($LABEL,'ADDL2','$4*' PPMS,'(SP)',,$COMMENT)
                    744:         OUTSTMT(,'RSB')                 :(H_EXI04)
                    745: *
                    746: *       Here if N-type PRC with no OP1 given & #PPMs > 0
                    747: *
                    748: H_EXI01 OUTSTMT($LABEL,'ADDL3','$4*' PPMS,PNAME '_S','R11',$COMMENT)
                    749:         OUTSTMT(,'JMP','(R11)')         :(H_EXI04)
                    750: *
                    751: *       Here if no OP1, & #PPMs = 0
                    752: *
                    753: H_EXI02 IDENT(PTYPE,'N')                        :S(H_EXI03)
                    754: *
                    755: *       No OP1, #PPMs=0 and R/E-type
                    756: *
                    757:         OUTSTMT($LABEL,'RSB',,,,$COMMENT)       :(H_EXI04)
                    758: *
                    759: *       No OP1, #PPMs=0 and N-type
                    760: *
                    761: H_EXI03 OUTSTMT($LABEL,'JMP','*' PNAME '_S',,,$COMMENT)
                    762: *
                    763: *       Merge to exit
                    764: *
                    765: H_EXI04 :(RETURN)
                    766: -EJECT
                    767: *      FLC folds a lower case character to upper case.
                    768: *
                    769: H_FLC  OUTSTMT( $LABEL,'BICL2','$CH$BL',$OP1,,$COMMENT )       :(RETURN)
                    770: *
                    771: *      GBLS is entered to produce global directives for important
                    772: *      routines internal and external to the compiler.
                    773: *
                    774: h_gbls outstmt( ,'.GLOBL',$LABEL,,,$COMMENT )          :(return)
                    775: -SPACE 3
                    776: *       H is entered directly by some opcodes, and eventually by
                    777: *       most others.  It performs an opcode translation if an entry exists
                    778: *       for it (non-null) in the H_H.XOPS table and then goes to DSGEN to
                    779: *       dump the statement.
                    780: *
                    781: H_H     $OPCODE = DIFFER(TEMP = H_H.XOPS[$OPCODE]) TEMP         :(DSGEN)
                    782: -SPACE 3
                    783: *       Handle ICP opcode with a TSTL on (CP)+
                    784: *
                    785: H_ICP   $OP1    = '(R3)+'                       :(H_H)
                    786: -SPACE 3
                    787: *      Handle IFF by generating a word with the proper offset.
                    788: *
                    789: h_iff  outstmt( ,'.WORD',$OP2 '-5B',,,$COMMENT )       :(return)
                    790: -SPACE 3
                    791: *       Handle ITR with a MOVLF on IA to RA
                    792: *
                    793: H_ITR   $OP1    = 'R5'
                    794:         $OP2    = 'R2'                          :(H_H)
                    795: -SPACE 3
                    796: *       LCT does not emit if both operands are the same
                    797: *
                    798: H_LCT   DIFFER($OP1,$OP2)                               :S(H_SWP12)
                    799:         OUTSTMT($LABEL,,,,,$COMMENT)                    :(RETURN)
                    800: -SPACE 3
                    801: *       LEI uses MOVZWL on the word just prior to the entry point
                    802: *
                    803: H_LEI   $OP2    = $OP1
                    804:         $OP1    = '-2(' $OP1 ')'                        :(H_H)
                    805: -EJECT
                    806: *       DO MFI
                    807: *
                    808: H_MFI   OUTSTMT($LABEL,'MOVL','R5',$OP1,,$COMMENT)
                    809:         IDENT($OP2)                                     :S(RETURN)
                    810:         OUTSTMT(,'BGEQ','0F')
                    811:         OUTSTMT(,'JMP',$OP2)
                    812:         OUTSTMT('0')                                    :(RETURN)
                    813: *       Make operand 1 operand 2, and put in a new operand 1 according
                    814: *       to the table.
                    815: *
                    816: H_NEW1  $OP2    = $OP1
                    817:         $OP1    = H_NEW1.OPS[$OPCODE]   :(H_H)
                    818: -SPACE 3
                    819: *       No-op instructions.  Comment out the opcode
                    820: *
                    821: H_NOOP  (IDENT($OPCODE,'INP'), IDENT($OPCODE,'INR'), IDENT($OPCODE,'EXP'))
                    822: +                                                       :S(RETURN)
                    823:         $OPCODE = '#' $OPCODE                           :(DSGEN)
                    824: -SPACE 3
                    825: *       Do arithmetic negate ops
                    826: *       CHANGE CALL OF XOP TO LOOKUP IN XOP.XREGS
                    827: *
                    828: H_NGX   $OP1    = $OP2 = XOP.XREGS[SUBSTR($OPCODE,3,1) 'A']
                    829: +                                                       :(H_H)
                    830: -SPACE 3
                    831: *       Handle arithmetic overflow tests [IOV,INO,ROV,RNO]
                    832: *
                    833: H_OVF   $OP2    = $OP1
                    834:         $OP1    =                                       :(H_BNCH)
                    835: -SPACE 3
                    836: *       Insert dummy PPM branch point if none given
                    837: *
                    838: H_PPM   $OP1    = IDENT($OP1) 'INVALID$'                :(H_H)
                    839: -SPACE 3
                    840: *       PRC notes the operands for later EXIs in global variables, and
                    841: *       emits save area code if N-type.
                    842: *
                    843: H_PRC   PTYPE   = $OP1
                    844:         PPMS    = $OP2
                    845:         PNAME   = $LABEL
                    846: *
                    847: *       If N-type, then we need a save area word
                    848: *
                    849:         DIFFER(PTYPE,'N')                       :S(H_PRC01)
                    850:         OUTSTMT(,'.DATA','1')
                    851:         OUTSTMT(PNAME '_S','.LONG','0')
                    852:         OUTSTMT(,'.TEXT','0')
                    853:         OUTSTMT($LABEL,'MOVL','(SP)+',PNAME '_S',,$COMMENT)
                    854:         :(H_PRC02)
                    855: *
                    856: *       Here if R/E type
                    857: *
                    858: H_PRC01 OUTSTMT($LABEL,'#PRC',,,,$COMMENT)
                    859: *
                    860: *       Merge to exit
                    861: *
                    862: H_PRC02 :(RETURN)
                    863: -EJECT
                    864: *       Do PLC, PSC ops
                    865: *
                    866: H_PXC   (IDENT($OP2) OUTSTMT($LABEL,'MOVAB','CFP$F(' $OP1 ')',$OP1,,$COMMENT))
                    867: +                                               :S(RETURN)
                    868:         $OP2 ((('R' ANY(NOS) (ANY(NOS) | '')) | 'SP') RPOS(0))  :S(H_PXC1)
                    869:         OUTSTMT($LABEL,'MOVL',$OP2,'R11',,'[GET IN SCRATCH REGISTER]')
                    870:         $LABEL  =
                    871:         $OP2    = 'R11'
                    872: H_PXC1  OUTSTMT($LABEL,'MOVAB','CFP$F(' $OP1 ')[' $OP2 ']',$OP1,,$COMMENT)
                    873: +                                               :(RETURN)
                    874: -SPACE 3
                    875: *       DO RMI
                    876: *
                    877: H_RMI   OUTSTMT($LABEL,'ASHQ','$-32','R4','R4',$COMMENT)
                    878:         OUTSTMT(,'EDIV',$OP1,'R4,R11,R5')       :(RETURN)
                    879: -SPACE 3
                    880: *       Handle RTI with CVTFL and then BVS if PLBL present
                    881: *
                    882: H_RTI   OUTSTMT($LABEL,'CVTFL','R2','R5',,$COMMENT)
                    883:         (DIFFER($OP1) OUTSTMT(,'BVS',$OP1))     :(RETURN)
                    884: -SPACE 3
                    885: *       SBCALL GENERATES A JSB TO THE LABEL 'SB' CONCATENTATED WITH
                    886: *       THE MINIMAL INSTRUCTION NAME.
                    887: *
                    888: H_SBCALL
                    889:         $OP1    = 'SB' $OPCODE
                    890:         $OPCODE = 'JSB'                         :(DSGEN)
                    891: *
                    892: *       SEC does various things depending on the current section
                    893: *
                    894: H_SEC   H_SEC.CNT = H_SEC.CNT + 1
                    895: *
                    896: *      Generate appropriate .text and .data directives:
                    897: *
                    898: *      all instructions        .text 0
                    899: *      all constants           .data 0
                    900: *      all working storage     .data 1
                    901: *
                    902: *      procedures sec          -------
                    903: *      definitions sec         -------
                    904: *      constants sec           .data 0
                    905: *      working storage sec     .data 1
                    906: *      program sec             .text 0
                    907: *      stack overflow sec      -------
                    908: *      error section           -------
                    909: *
                    910:        ( eq( h_sec.cnt,3 ) outstmt( ,'.DATA','0' ),
                    911: +        eq( h_sec.cnt,4 ) outstmt( ,'.DATA','1' ),
                    912: +        eq( h_sec.cnt,5 ) outstmt( ,'.TEXT','0' ),
                    913: +       )
                    914: *
                    915: *       Get rid of the extrinsic defs. if past defs. section (saves space)
                    916: *
                    917:         H_EQU.DEFS = EQ(H_SEC.CNT,3)
                    918: *
                    919: *      Be sure to generate label for program sec.
                    920: *
                    921:        eq( h_sec.cnt,5 )                               :f(h_sec00)
                    922:        outstmt( ,'.GLOBL','SEC04' )
                    923:        outstmt( 'SEC04' )                              :(h_sec02)
                    924: *
                    925: *       If we have reached the Stack Ovfl. sect. then dump the ERR list
                    926: *
                    927: H_SEC00  NE(H_SEC.CNT,6)                                 :S(H_SEC02)
                    928:         T       = 0
                    929: *
                    930: *       Loop here to emit code for saved up ERR objects.
                    931: *
                    932: H_SEC01 T       = LT(T,MAXERR) T + 1            :F(H_SEC01X)
                    933:         OUTSTMT('ER_' LPAD(T,3,'0'), 'MOVZWL', '$' T, 'R6')
                    934:         OUTSTMT(,'JMP','ERROR')             :(H_SEC01)
                    935: *
                    936: H_SEC01X
                    937:        outstmt( ,'.GLOBL','SEC05' )
                    938:        outstmt( 'SEC05' )
                    939: *
                    940: *       Merged when finished with ERRs list.
                    941: *
                    942: H_SEC02 :(H_H)
                    943: -EJECT
                    944: *       Arithmetic store ops (STI,STR)
                    945: *       CHANGE CALL OF XOP TO LOOKUP OF XOP.XREGS
                    946: *
                    947: H_STX   $OP2    = $OP1
                    948:         $OP1    = XOP.XREGS[SUBSTR($OPCODE,3,1) 'A']    :(H_H)
                    949: -SPACE 3
                    950: *       Ops that need to have op1 and op2 switched.
                    951: *
                    952: H_SWP12 T = $OP1
                    953:         $OP1    = $OP2
                    954:         $OP2    = T                                     :(H_H)
                    955: -SPACE 3
                    956: *
                    957: *       TTL restores the title text from OP1 and COMMENT
                    958: *
                    959: H_TTL   $OP1    = (IDENT($OP1), $OP1 ' ') $COMMENT
                    960:         $COMMENT =                                      :(H_H)
                    961: -SPACE 3
                    962: *       Immediate mode shifts
                    963: *
                    964: H_XSH   $OP3    = $OP1
                    965:         $OP1    = '$' (IDENT($OPCODE,'LSH'),'-') $OP2
                    966:         $OP2    = $OP3                                  :(H_H)
                    967: -SPACE 3
                    968: *       WTB opcode
                    969: H_WTB   OUTSTMT($LABEL,'MOVAL','0[' $OP1 ']',$OP1,,$COMMENT) :(RETURN)
                    970: -SPACE 3
                    971: *      come here if an opcode is found that should have been procesed
                    972: *      by a previous preprocessor.
                    973: *
                    974: h_zzz  terminal = 'Invalid opcode detected in line '
                    975: +                      lpad( nlines,5 ) ': ' $opcode   :(error)
                    976: -EJECT
                    977: END
                    978: spitv35.tok
                    979: spitv35.plb
                    980: spitv35.src
                    981: y
                    982: y

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.