OSDN Git Service

64/16 run-time optimized unsigned division, not fully tested master
authorJoel Matthew Rees <joel.rees@gmail.com>
Sun, 13 Aug 2023 15:09:44 +0000 (00:09 +0900)
committerJoel Matthew Rees <joel.rees@gmail.com>
Sun, 13 Aug 2023 15:09:44 +0000 (00:09 +0900)
FIG68KFL.S

index 37b41b4..eda4eb2 100644 (file)
@@ -1217,7 +1217,8 @@ MSLMW:
 *      BLO.S   MSLAMW          ; yes\r
 *      MOVE.L  D3,-(PSP)       ; no, bail to bit divide\r
 *      BRA.S   BSLASH+NATWID   \r
-MSLAMW AND.L   #$FFFF,D3       ; just to be safe\r
+MSLAMW:\r
+*      AND.L   #$FFFF,D3       ; Masking out bits doesn't make it more correct.\r
        CLR.L   D0              ; Clear working register\r
        CLR.L   D1              ; Clear result registers\r
        CLR.L   D2\r
@@ -1248,12 +1249,82 @@ MSLMWD  MOVE.W  NATWID*3/2(PSP),D0      ; lowest 16-bit
        MOVE.w  D0,D2           ; result in place\r
        CLR.W   D0              ; prepare remainder\r
        SWAP    D0              ; final remainder is 16-bit\r
-       MOVE.L  D0,NATWID*2(PSP)\r
-       MOVE.L  D2,-(PSP)       ; low word first\r
+       MOVE.L  D0,NATWID(PSP)  ; remainder\r
+       CLR.L   (PSP)\r
+       MOVE.L  D2,-(PSP)       ; quotient low word first\r
        MOVE.L  D1,-(PSP)       ; high word\r
        RTS\r
 *\r
-\r
+*\r
+*CSLAW:                ; No run-time optimizationm something like this\r
+*      MOVE.L  (PSP)+,D3       ; get divisor\r
+*      CLR.L   D0              ; first working register\r
+*      MOVE.W  (PSP),D0\r
+*      DIVU.W  D3,D0           ; column quotient in low half-word, remainder in high\r
+*      MOVE.L  D0,D1           ; save remainder\r
+*      SWAP    D0              ; shift column quotient\r
+*      MOVE.W  NATWID/2(PSP),D1        ; Next column in low half\r
+*      DIVU.W  D3,D1\r
+*      MOVE.W  D1,D0           ; record column quotient in D0 low half, remainder in D1 high\r
+*      MOVE.W  NATWID(PSP),D1  ; Next column in low half\r
+*      DIVU.W  D3,D1\r
+*      MOVE.L  D1,D2           ; save column remainder in D2 high\r
+*      SWAP    D1              ; shift column quotient into D1 high\r
+*      MOVE.W  NATWID*3/2(PSP),D2      ; final column\r
+*      DIVU.W  D3,D2\r
+*      MOVE.W  D2,D1           ; complete the quotient\r
+*      CLR.W   D2              ; get rid of the quotient\r
+*      SWAP    D2              ; put the remainder in place\r
+*      MOVE.L  D2,NATWID(PSP)  ; remainder\r
+*      CLR.L   (PSP)\r
+*      MOVE.L  D1,-(PSP)       ; quotient low word first\r
+*      MOVE.L  D0,-(PSP)       ; high word\r
+*      RTS                     ; about 100~ + 4*140~ , about 660=, linear\r
+*\r
+* Would be possible to add test before divide to the above, \r
+* to run-time optimize into range of 300~ to 720~\r
+* something like this:\r
+*OSLAW:                ; No run-time optimization\r
+*      MOVE.L  (PSP)+,D3       ; get divisor\r
+*      CLR.L   D0              ; first working register\r
+*      MOVE.W  (PSP),D0\r
+*      CMP.L   D0,D3           ; Anything to divide?\r
+*      BLS.S   OSLAW1\r
+*      SWAP    D0\r
+*      BRA.S   OSLAWD\r
+*OSLAW1        DIVU.W  D3,D0           ; column quotient in low half-word, remainder in high\r
+*OSLAWD        MOVE.L  D0,D1           ; save remainder\r
+*      SWAP    D0              ; shift column quotient\r
+*      MOVE.W  NATWID/2(PSP),D1        ; Next column in low half\r
+*      CMP.L   D1,D3           ; Anything to divide?\r
+*      BLS.S   OSLAW2\r
+*      SWAP    D1              ; works because divisor is 16-bit.\r
+*      BRA.S   OSLAWC\r
+*OSLAW2        DIVU.W  D3,D1\r
+*OSLAWC        MOVE.W  D1,D0           ; record column quotient in D0 low half, remainder in D1 high\r
+*      MOVE.W  NATWID(PSP),D1  ; Next column in low half\r
+*      CMP.L   D1,D3           ; Anything to divide?\r
+*      BLS.S   OSLAW3\r
+*      SWAP    D1              ; works because divisor is 16-bit.\r
+*      BRA.S   OSLAWB\r
+*OSLAW3        DIVU.W  D3,D1\r
+*OSLAWB        MOVE.L  D1,D2           ; save column remainder in D2 high\r
+*      SWAP    D1              ; shift column quotient into D1 high\r
+*      MOVE.W  NATWID*3/2(PSP),D2      ; final column\r
+*      CMP.L   D2,D3           ; Anything to divide?\r
+*      BLS.S   OSLAW4\r
+*      SWAP    D2              ; works because divisor is 16-bit.\r
+*      BRA.S   OSLAWA\r
+*OSLAW4        DIVU.W  D3,D2\r
+*OSLAWA        MOVE.W  D2,D1           ; complete the quotient\r
+*      CLR.W   D2              ; get rid of the quotient\r
+*      SWAP    D2              ; put the remainder in place\r
+*      MOVE.L  D2,NATWID(PSP)  ; remainder\r
+*      CLR.L   (PSP)\r
+*      MOVE.L  D1,-(PSP)       ; quotient low word first\r
+*      MOVE.L  D0,-(PSP)       ; high word\r
+*      RTS                     ; about 100~ + 4*140~ , about 660=, linear\r
+*\r
 *\r
 * ( ud u --- uremainder uquotient )\r
 * Divides the top unsigned integer\r
@@ -1326,40 +1397,13 @@ USLASH:
 USLA16 CMP.L   #$10000,D3      ; 16-bit divisor?\r
        BLO.S   USLAW           ; yes\r
        MOVE.L  D3,-(PSP)       ; no, put divisor back and bail to bit divide\r
-       BRA.S   BSLASH+NATWID   \r
+       BRA.s   BSLASH+NATWID   \r
 USLAW:\r
        BSR.W   MSLMWT\r
        MOVEM.L (PSP)+,D0/D1/D2 ; drop extra/high word of both remainder and quotient\r
        MOVE.L  D1,-(PSP)       \r
        RTS\r
 *\r
-\r
-*      CLR.L   D0              ; working register\r
-*      MOVE.W  (PSP),D0        ; Start from high word\r
-*      CMP.L   D3,D0           ; Anything to divide?\r
-*      BLO.S   USLAW3\r
-*      DIVU.W  D3,D0\r
-*\r
-*USLAW3        SWAP    D0              ; Shift the column\r
-*      MOVE.W  NATWID/2(PSP),D0        ; get the next column\r
-*      CMP.L   D3,D0           ; Anything to divide?\r
-*      BLO.S   USLAW2\r
-*      DIVU.W  D3,D0\r
-*\r
-*USLAW2        SWAP    D0              ; Shift the column\r
-*      MOVE.W  NATWID(PSP),D0  ; get the next column\r
-*      CMP.L   D3,D0           ; Anything to divide?\r
-*      BLO.S   USLAW1\r
-*      DIVU.W  D3,D0\r
-*\r
-*USLAW1        SWAP    D0              ; Shift the column\r
-*      MOVE.W  NATWID*3/2(PSP),D0      ; get the next column\r
-*      CMP.L   D3,D0           ; Anything to divide?\r
-*      BLO.S   USLAW0\r
-*      DIVU.W  D3,D0\r
-\r
-\r
-*\r
 * ( ud_dividend u_divisor --- u_remainder u_quotient )\r
 * Divides the top unsigned integer\r
 * into the second and third words on the stack\r