      .TITLE QUADMATH
;
;        SUBROUTINE SUBQUAD.MAR
;
;        FORTRAN CALLABLE ROUTINE TO SUBTRACT TWO QUAD WORD INTEGERS
;
;        CALL SUBQUAD (A,B,C)
;
;        RETURNS: A - B -> C
;
         .ENTRY          SUBQUAD ^M<R2>
;           note that you cannot enable integer overflow or this will fail.
;
;
A = 4
B = 8
C = 12
D = 16
         MOVQ    @A(AP),R0       ;GET FIRST PARAM FOR SUBTRACT
                                 ;NEED TO USE REGISTERS BECAUSE
                                 ;SUBWC IS ONLY 2 ADDRESS INSTR.
         MOVAQ   @B(AP),R2       ;GET ADDRESS OF SECOND PARAM.
         SUBL    (R2)+,R0        ;SUBTRACT FIRST HALF OF ARGUMENTS
         SBWC    (R2),R1                 ;THEN DO THE SECOND HALF
         MOVQ    R0,@C(AP)       ;STORE THE RESULT
         RET
;
;
;        SUBROUTINE ADDQUAD.MAR
;
;        FORTRAN CALLABLE ROUTINE TO ADD TWO QUAD WORD INTEGERS
;
;        CALL ADDQUAD (A,B,C)
;
;        RETURNS: A + B -> C
;
         .ENTRY          ADDQUAD ^M<R2>
;           note that you cannot enable integer overflow or this will fail.
;
;
A = 4
B = 8
C = 12
         MOVQ    @A(AP),R0       ;GET FIRST PARAM FOR SUBTRACT
                                 ;NEED TO USE REGISTERS BECAUSE
                                 ;SUBWC IS ONLY 2 ADDRESS INSTR.
         MOVAQ   @B(AP),R2       ;GET ADDRESS OF SECOND PARAM.
         ADDL    (R2)+,R0        ;SUBTRACT FIRST HALF OF ARGUMENTS
         ADWC    (R2),R1                 ;THEN DO THE SECOND HALF
         MOVQ    R0,@C(AP)       ;STORE THE RESULT
         RET
;
;
;
         .ENTRY          EDIV    ^M<R2,IV>
;
;        CALL EDIV (A,B,C)
;        RETURNS  A/B -> C
;
         MOVQ    @A(AP),R0       ;GET FIRST ARGUMENT
;        MOVAL   @B(AP),R2       ;GET LONGWORD DIVISOR ADDRESS
;        EDIV    (R2),R0,R0,R1   ;DO THE DIVISION
         MOVL    @B(AP),R2
         EDIV    R2,R0,R0,R1
         MOVL    R0,@C(AP)       ;STORE INTEGER QUOTIENT,IGNORE REM.
         RET
         .ENTRY          EMUL    ^M<R2,IV>
;
;        CALL EMUL (A,B,C,D)
;        RETURNS  D = A*B + C
;
         MOVAQ    @D(AP),R0      ;GET RESULT ADDRESS
         EMUL  @A(AP),@B(AP),@C(AP),(R0)  ;DO MULT AND STORE RESULT
         RET
         .ENTRY          QMUL    ^M<R2,R3,R4,R5,IV>
;
;        CALL QMUL (A,B,C)
;        RETURNS C = A * B
;        where A, B, & C are quadwords.
;
;        this code is copied from the VAX11 Architecture Handbook
;
         MOVAQ @A(AP),R2
         MOVAQ @B(AP),R3
         EMUL  (R2),(R3),#0,R4
         MULL3 4(R2),(R3),R0
         MULL3 (R2),4(R3),R1
         ADDL  R1,R0
         TSTL  (R2)
         BGEQ  10$
         ADDL  (R3),R0
10$:     TSTL  (R3)
         BGEQ  20$
         ADDL  (R2),R0
20$:     ADDL  R0,R5
         MOVQ  R4,@C(AP)
         RET
         .END
