.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 ; 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 ; 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 ; ; 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 ; ; 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 ; ; 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