.NLIST ; VAXMAC.MAR ; ========== ; ; The macros in this file attempt to expand VAX instructions which have no ; direct PDP equivalents. Note that there are many restrictions and partial ; implementations -- these macros are sufficient for our present needs, but ; NOT complete. In particular, "long" instructions are accepted without ; complaint, mapping to words, on the assumption that they are being used for ; addresses, even where this is unlikely to be the case, e.g. MOVZBL. ; ; No EIS instructions are generated by these macros. ; Equate R8-R13 to R0-R5, as FP equivalents. .MACRO FLOREG R8=R0 R9=R1 R10=R2 R11=R3 R12=R4 R13=R5 .ENDM ; This macro issues a warning if OP is not a simple register, as CALLER expects. .MACRO REQREG OP,CALLER,SRCDST .NTYPE $$$OP,OP .IIF GT $$$OP-7, .ERROR ; CALLER ONLY IMPLEMENTED FOR REGISTER-TYPE SRCDST .ENDM REQREG ; This macro issues a warning if OP is not immediate mode, as CALLER expects. .MACRO REQIMM OP,CALLER,SRCDST .NTYPE $$$OP,OP .IIF NE $$$OP-^O27, .ERROR ; CALLER ONLY IMPLEMENTED FOR IMMEDIATE-TYPE SRCDST .ENDM REQIMM ; Get actual value for immediate instruction to ...VAL, call as: IMMVAL ^#ddd#, ; where the first # is usually supplied by the passed argument and so not supplied ; in the call. Last 15 arguments are dummies for calls in PUSH and POP. .MACRO IMMVAL VAL,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P ...VAL=VAL .ENDM IMMVAL .MACRO MOVB SRC,DST .NTYPE $$$DST,DST .IF LE $$$DST-7 CLRB DST BISB SRC,DST .IFF CVTBB SRC,DST .ENDC .ENDM MOVB .MACRO AOBLSS LIMIT,INDEX,DEST INC INDEX CMP INDEX,LIMIT BLT DEST .ENDM AOBLSS .MACRO AOBLEQ LIMIT,INDEX,DEST INC INDEX CMP INDEX,LIMIT BLE DEST .ENDM AOBLEQ .MACRO SOBGTR INDEX,DEST DEC INDEX BGT DEST .ENDM SOBGTR .MACRO SOBGEQ INDEX,DEST DEC INDEX BGE DEST .ENDM SOBGEQ .MACRO ADDAB SRC,RES,BW .IF IDN SRC,#1 INC'BW RES .IFF .IF IDN SRC,#-1 DEC'BW RES .IFF .IIF DIF SRC,#0, ADD SRC,RES .ENDC .ENDC .ENDM ADDAB .MACRO SUBAB SRC,RES,BW .IF IDN SRC,#1 DEC'BW RES .IFF .IF IDN SRC,#-1 INC'BW RES .IFF .IIF DIF SRC,#0, SUB SRC,RES .ENDC .ENDC .ENDM SUBAB .MACRO SUBW3 MIN,SBTR,RES MOV SBTR,RES SUBAB MIN,RES, .ENDM SUBW3 .MACRO SUBL3 MIN,SBTR,RES MOV SBTR,RES SUBAB MIN,RES, .ENDM SUBL3 .MACRO ADDW3 SRC1,SRC2,RES MOV SRC1,RES ADDAB SRC2,RES, .ENDM ADDW3 .MACRO ADDL3 SRC1,SRC2,RES MOV SRC1,RES ADDAB SRC2,RES, .ENDM ADDL3 ; ADDB3 and SUBB3 assume that the first operand and RES are word-aligned, and ; that anything happening to the hi byte does not affect the result. .MACRO ADDB3 SRC1,SRC2,RES CVTBB SRC2,RES ADDAB SRC1,RES,B .ENDM ADDB3 .MACRO SUBB3 MIN,SBTR,RES CVTBB SBTR,RES SUBAB MIN,RES,B .ENDM SUBB3 .MACRO BICB3 SRC1,SRC2,RES MOVB SRC2,RES BICB SRC1,RES .ENDM BICB3 .MACRO BICW3 SRC1,SRC2,RES MOV SRC2,RES BIC SRC1,RES .ENDM BICW3 .MACRO BICL3 SRC1,SRC2,RES MOV SRC2,RES BIC SRC1,RES .ENDM BICL3 .MACRO BISB3 SRC1,SRC2,RES MOVB SRC2,RES BISB SRC1,RES .ENDM BISB3 .MACRO BISW3 SRC1,SRC2,RES MOV SRC2,RES BIS SRC1,RES .ENDM BISW3 .MACRO BISL3 SRC1,SRC2,RES MOV SRC2,RES BIS SRC1,RES .ENDM BISL3 .MACRO XORW3 SRC1,SRC2,RES MOV SRC2,RES XOR SRC1,RES .ENDM XORW3 .MACRO XORL3 SRC1,SRC2,RES MOV SRC2,RES XOR SRC1,RES .ENDM XORL3 .MACRO MULAB COUNT,ADDR,BW T.VAL= COUNT .IF EQ T.VAL CLR'BW ADDR .IFF .IF LT T.VAL T.VAL= -T.VAL NEG'BW ADDR .ENDC T.FLAG= 0 T.MASK= ^O040000 .REPT ^D14 .IF LE T.MASK-T.VAL .IF NE T.MASK&T.VAL .IF NE T.MASK-T.VAL .IF EQ T.FLAG MOV'BW ADDR,-(SP) T.FLAG= 1 .IFF .IF NE T.MASK-1&T.VAL ADD (SP),ADDR .IFF ADD (SP)+,ADDR T.FLAG= 0 .ENDC .ENDC .ENDC .ENDC ASL'BW ADDR .ENDC T.MASK= T.MASK/2 .ENDR .IF NE T.FLAG ADD (SP)+,ADDR .ENDC .ENDC .ENDM MULAB ; Perform simple multiplies. ; Only immediate mode multiplier is allowed. Multiple errors will result ; if it isn't immediate (or a MULBx requires an "ADDB"). .MACRO MULL2 TIMES,SRC REQIMM TIMES,MULL2,MULTIPLIER .IIF EQ $$$OP-^O27, MULAB ^TIMES#,SRC, .ENDM MULL2 .MACRO MULW2 TIMES,SRC REQIMM TIMES,MULW2,MULTIPLIER .IIF EQ $$$OP-^O27, MULAB ^TIMES#,SRC, .ENDM MULW2 .MACRO MULB2 TIMES,SRC REQIMM TIMES,MULB2,MULTIPLIER .IIF EQ $$$OP-^O27, MULAB ^TIMES#,SRC,B .ENDM MULB2 .MACRO MULL3 TIMES,SRC,DEST MOV SRC,DEST MULL2 TIMES,DEST .ENDM MULL3 .MACRO MULW3 TIMES,SRC,DEST MOV SRC,DEST MULW2 TIMES,DEST .ENDM MULW3 .MACRO MULB3 TIMES,SRC,DEST MOVB SRC,DEST MULB2 TIMES,DEST .ENDM MULB3 ; Perform divides, must be by power of 2. .MACRO DIVAB DIVSR,ADDR,BW T.CNT=DIVSR .IIF EQ T.CNT-1, .MEXIT .IF LT T.CNT NEG'BW' ADDR T.CNT=-T.CNT .ENDC T.CNT2=T.CNT .REPT 15 .IIF GT T.CNT, ASR'BW' ADDR T.CNT=T.CNT/2 .IIF LE T.CNT-1, .MEXIT .IIF NE T.CNT*2-T.CNT2, .ERROR ; DIVISOR MUST BE POWER OF 2 T.CNT2=T.CNT .ENDR .ENDM DIVAB .MACRO DIVL2 TIMES,SRC REQIMM TIMES,DIVL2,DIVISOR .IIF EQ $$$OP-^O27, DIVAB ^TIMES#,SRC .ENDM DIVL2 .MACRO DIVW2 TIMES,SRC REQIMM TIMES,DIVL2,DIVISOR .IIF EQ $$$OP-^O27, DIVAB ^TIMES#,SRC .ENDM DIVW2 .MACRO DIVB2 TIMES,SRC REQIMM TIMES,DIVL2,DIVISOR .IIF EQ $$$OP-^O27, DIVAB ^TIMES#,SRC,B .ENDM DIVB2 .MACRO DIVL3 TIMES,SRC,DEST MOV SRC,DEST DIVL2 TIMES,DEST .ENDM DIVL3 .MACRO DIVW3 TIMES,SRC,DEST MOV SRC,DEST DIVW2 TIMES,DEST .ENDM DIVW3 .MACRO DIVB3 TIMES,SRC,DEST MOVB SRC,DEST DIVB2 TIMES,DEST .ENDM DIVB3 ; Move negated and complemented. Don't do MOV if source=dest. If source is ; immediate, change to MOV #-src,dst. (This is used on a VAX to load small ; integers which are stored more efficiently in positive form.) .MACRO MNEG OP,VAL,DST OP #-,DST .ENDM MNEG .MACRO MNEGB SRC,DST .NTYPE $$$SRC,SRC .IF EQ $$$SRC-27 MNEG MOVB,^SRC#,DST .IFF .IIF DIF,SRC,DST, MOVB SRC,DST NEGB DST .ENDC .ENDM MNEGB .MACRO MNEGW SRC,DST .NTYPE $$$SRC,SRC .IF EQ $$$SRC-27 MNEG MOV,^SRC#,DST .IFF .IIF DIF,SRC,DST, MOV SRC,DST NEG DST .ENDC .ENDM MNEGW .MACRO MNEGL SRC,DST .NTYPE $$$SRC,SRC .IF EQ $$$SRC-27 MNEG MOV,^SRC#,DST .IFF .IIF DIF,SRC,DST, MOV SRC,DST NEG DST .ENDC .ENDM MNEGL .MACRO MCOM OP,VAL,DST OP #^C,DST .ENDM MCOM .MACRO MCOMB SRC,DST .NTYPE $$$SRC,SRC .IF EQ $$$SRC-27 MCOM MOVB,^SRC#,DST .IFF .IIF DIF,SRC,DST, MOVB SRC,DST COMB DST .ENDC .ENDM MCOMB .MACRO MCOMW SRC,DST .NTYPE $$$SRC,SRC .IF EQ $$$SRC-27 MCOM MOV,^SRC#,DST .IFF .IIF DIF,SRC,DST, MOV SRC,DST COM DST .ENDC .ENDM MCOMW .MACRO MCOML SRC,DST .NTYPE $$$SRC,SRC .IF EQ $$$SRC-27 MCOM MOV,^SRC#,DST .IFF .IIF DIF,SRC,DST, MOV SRC,DST COM DST .ENDC .ENDM MCOML .MACRO ADWC SRC,DST ADC DST ADDAB SRC,DST, .ENDM ADWC .MACRO SBWC SRC,DST SBC DST SUBAB SRC,DST, .ENDM SBWC .MACRO MOVZBW SRC,DST CLR DST BISB SRC,DST .ENDM MOVZBW .MACRO MOVZBL SRC,DST CLR DST BISB SRC,DST .ENDM MOVZBL .MACRO BBC BITNO,SRC,DST REQIMM BITNO,BBC, .IIF NE $$$OP-^O27, .MEXIT IMMVAL ^BITNO# .IF GT ...VAL-7 .IF EQ ...VAL-15 TST SRC BPL DST .IFF BIT #1@...VAL,SRC BEQ DST .ENDC .IFF .IF EQ ...VAL-7 TSTB SRC BPL DST .IFF BITB #1@...VAL,SRC BEQ DST .ENDC .ENDC .ENDM BBC .MACRO BBS BITNO,SRC,DST REQIMM BITNO,BBS, .IIF NE $$$OP-^O27, .MEXIT IMMVAL ^BITNO# .IF GT ...VAL-7 .IF EQ ...VAL-15 TST SRC BMI DST .IFF BIT #1@...VAL,SRC BNE DST .ENDC .IFF .IF EQ ...VAL-7 TSTB SRC BMI DST .IFF BITB #1@...VAL,SRC BNE DST .ENDC .ENDC .ENDM BBS .MACRO BBSS BITNO,SRC,DST REQIMM BITNO,BBSS, .IIF NE $$$OP-^O27, .MEXIT BBS BITNO,SRC,DST BIS #1@...VAL,SRC .ENDM BBSS .MACRO BBSSI BITNO,SRC,DST REQIMM BITNO,BBSSI, .IIF NE $$$OP-^O27, .MEXIT BBS BITNO,SRC,DST BIS #1@...VAL,SRC .ENDM BBSSI .MACRO BBCC BITNO,SRC,DST REQIMM BITNO,BBCC, .IIF NE $$$OP-^O27, .MEXIT BBC BITNO,SRC,DST BIC #1@...VAL,SRC .ENDM BBCC .MACRO BBCCI BITNO,SRC,DST REQIMM BITNO,BBCCI, .IIF NE $$$OP-^O27, .MEXIT BBC BITNO,SRC,DST BIC #1@...VAL,SRC .ENDM BBCCI .MACRO BBSC BITNO,SRC,DST,?CONT REQIMM BITNO,BBSC, .IIF NE $$$OP-^O27, .MEXIT BBC BITNO,SRC,CONT BIC #1@...VAL,SRC BR DST CONT: .ENDM BBSC .MACRO BBCS BITNO,SRC,DST,?CONT REQIMM BITNO,BBCS, .IIF NE $$$OP-^O27, .MEXIT BBS BITNO,SRC,CONT BIS #1@...VAL,SRC BR DST CONT: .ENDM BBCS .MACRO BLBS SRC,DEST BITB #1,SRC BNE DEST .ENDM BLBS .MACRO BLBC SRC,DEST BITB #1,SRC BEQ DEST .ENDM BLBC ; Macros involving register masks -- PUSHR, POPR, and .ENTRY ; PUSHF uses STF if REG is a register (assumed mapped to floating) else PUSHL .MACRO PUSHF OP .NTYPE $$$OP,OP .IF LE $$$OP-3 STF OP,-(SP) .IFF PUSHL OP .ENDC .ENDM PUSHF .MACRO PUSHRS MASK IMMVAL \MASK .IIF NE ...VAL&^O40000, PUSHL SP .IIF NE ...VAL&^O20000, PUSHL R13 .IIF NE ...VAL&^O10000, PUSHL R12 .IIF NE ...VAL&^O4000, PUSHF R11 .IIF NE ...VAL&^O2000, PUSHF R10 .IIF NE ...VAL&^O1000, PUSHF R9 .IIF NE ...VAL&^O400, PUSHF R8 .IIF NE ...VAL&^O200, PUSHL R7 .IIF NE ...VAL&^O100, PUSHL R6 .IIF NE ...VAL&^O40, PUSHL R5 .IIF NE ...VAL&^O20, PUSHL R4 .IIF NE ...VAL&^O10, PUSHL R3 .IIF NE ...VAL&^O4, PUSHL R2 .IIF NE ...VAL&^O2, PUSHL R1 .IIF NE ...VAL&1, PUSHL R0 .ENDM PUSHRS .MACRO PUSHR A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P PUSHRS ^A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P# .ENDM PUSHR .MACRO POPF OP .NTYPE $$$OP,OP .IF LE $$$OP-3 LDF (SP)+,OP .IFF POPL OP .ENDC .ENDM POPF .MACRO POPRS MASK IMMVAL \MASK .IIF NE ...VAL&1, POPL R0 .IIF NE ...VAL&^O2, POPL R1 .IIF NE ...VAL&^O4, POPL R2 .IIF NE ...VAL&^O10, POPL R3 .IIF NE ...VAL&^O20, POPL R4 .IIF NE ...VAL&^O40, POPL R5 .IIF NE ...VAL&^O100, POPL R6 .IIF NE ...VAL&^O200, POPL R7 .IIF NE ...VAL&^O400, POPF R8 .IIF NE ...VAL&^O1000, POPF R9 .IIF NE ...VAL&^O2000, POPF R10 .IIF NE ...VAL&^O4000, POPF R11 .IIF NE ...VAL&^O10000, POPL R12 .IIF NE ...VAL&^O20000, POPL R13 .IIF NE ...VAL&^O40000, POPL SP .ENDM POPRS .MACRO POPR A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P POPRS ^A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P# .ENDM POPR .MACRO .ENTRY SUBR,RMASK,?LAB .IF B,RMASK $$$RMK=0 .IFF $$$RMK=^M'RMASK .IIF NE $$$RMK&^B11 .ERROR ; CAN'T .ENTRY R0 OR R1 $$$RMK=$$$RMK&^C^B11 .ENDC .IF NE $$$RMK .IF EQ $$$RMK-^B111000 .GLOBL $SAVRG SUBR:: JSR R5,$SAVRG .IFF SUBR:: PUSHRS $$$RMK BSBB LAB POPRS $$$RMK RETURN LAB: .ENDC .IFF SUBR:: .ENDC .ENDM .ENTRY .LIST