+
+\f
+;;;; Division.
+
+
+(define-assembly-routine (positive-fixnum-truncate
+ (:note "unsigned fixnum truncate")
+ (:cost 45)
+ (:translate truncate)
+ (:policy :fast-safe)
+ (:arg-types positive-fixnum positive-fixnum)
+ (:result-types positive-fixnum positive-fixnum))
+ ((:arg dividend any-reg nl0-offset)
+ (:arg divisor any-reg nl1-offset)
+
+ (:res quo any-reg nl2-offset)
+ (:res rem any-reg nl3-offset))
+ (let ((error (generate-error-code nil division-by-zero-error
+ dividend divisor)))
+ (inst beq divisor error)
+ (inst nop))
+
+ (inst divu dividend divisor)
+ (inst mflo quo)
+ (inst mfhi rem)
+ (inst sll quo 2))
+
+
+(define-assembly-routine (fixnum-truncate
+ (:note "fixnum truncate")
+ (:cost 50)
+ (:policy :fast-safe)
+ (:translate truncate)
+ (:arg-types tagged-num tagged-num)
+ (:result-types tagged-num tagged-num))
+ ((:arg dividend any-reg nl0-offset)
+ (:arg divisor any-reg nl1-offset)
+
+ (:res quo any-reg nl2-offset)
+ (:res rem any-reg nl3-offset))
+ (let ((error (generate-error-code nil division-by-zero-error
+ dividend divisor)))
+ (inst beq divisor error)
+ (inst nop))
+
+ (inst div dividend divisor)
+ (inst mflo quo)
+ (inst mfhi rem)
+ (inst sll quo 2))
+
+
+(define-assembly-routine (signed-truncate
+ (:note "(signed-byte 32) truncate")
+ (:cost 60)
+ (:policy :fast-safe)
+ (:translate truncate)
+ (:arg-types signed-num signed-num)
+ (:result-types signed-num signed-num))
+
+ ((:arg dividend signed-reg nl0-offset)
+ (:arg divisor signed-reg nl1-offset)
+
+ (:res quo signed-reg nl2-offset)
+ (:res rem signed-reg nl3-offset))
+ (let ((error (generate-error-code nil division-by-zero-error
+ dividend divisor)))
+ (inst beq divisor error)
+ (inst nop))
+
+ (inst div dividend divisor)
+ (inst mflo quo)
+ (inst mfhi rem))