;
; crts.s
;
; C run-time support functions for Sapphire
;
;  1995 Straylight
;

;----- Standard header ------------------------------------------------------

		GET	libs:header
;		GET	libs:swis

		GET	libs:stream

;----- External dependencies ------------------------------------------------

		GET	sapphire:divide
		IMPORT	div_byZero

;----- Main code ------------------------------------------------------------

		AREA	|Sapphire$$Code|,CODE,READONLY

; --- __rt_udiv10 ---
;
; On entry:	R0 == value to divide
;
; On exit:	R0 == value / 10
;		R1 == value % 10
;
; Use:		Divides an unsigned number by 10.

		EXPORT	|__rt_udiv10|
		EXPORT	|_kernel_udiv10|

|__rt_udiv10|	ROUT
|_kernel_udiv10|

		MOV	R1,R0
		ADD	R0,R0,R0,LSR #1
		ADD	R0,R0,R0,LSR #4
		ADD	R0,R0,R0,LSR #8
		ADD	R0,R0,R0,LSR #16
		MOV	R0,R0,LSR #4
		ADD	R2,R0,R0,LSL #2
		SUB	R1,R1,R2,LSL #1
		SUBS	R1,R1,#10
		ADDGE	R0,R0,#1
		ADDLT	R1,R1,#10
		MOVS	PC,R14

		LTORG

; --- __rt_sdiv10 ---
;
; On entry:	R0 == value to divide
;
; On exit:	R0 == value / 10
;		R1 == value % 10
;
; Use:		Divides a signed number by 10.

		EXPORT	|__rt_sdiv10|
		EXPORT	|_kernel_sdiv10|

|__rt_sdiv10|	ROUT
|_kernel_sdiv10|

		MOVS	R3,R0
		RSBMI	R0,R0,#0
		MOV	R1,R0
		ADD	R0,R0,R0,LSR #1
		ADD	R0,R0,R0,LSR #4
		ADD	R0,R0,R0,LSR #8
		ADD	R0,R0,R0,LSR #16
		MOV	R0,R0,LSR #4
		ADD	R2,R0,R0,LSL #2
		SUB	R1,R1,R2,LSL #1
		SUBS	R1,R1,#10
		ADDGE	R0,R0,#1
		ADDLT	R1,R1,#10
		CMP	R3,#0
		RSBMI	R0,R0,#0
		RSBMI	R1,R1,#0
		MOVS	PC,R14

		LTORG

; --- __rt_udiv ---
;
; On entry:	R0 == divisor
;		R1 == dividend
;
; On exit:	R0 == quotient
;		R1 == remainder
;
; Use:		Divides in an unsigned way.

		EXPORT	|__rt_udiv|
		EXPORT	|x$udivide|

|__rt_udiv|	ROUT
|x$udivide|

		EOR	R0,R1,R0
		EOR	R1,R1,R0
		EOR	R0,R1,R0
		B	div_unsigned

		LTORG

; --- __rt_sdiv ---
;
; On entry:	R0 == divisor
;		R1 == dividend
;
; On exit:	R0 == quotient
;		R1 == remainder
;
; Use:		Divides in a signed way.

		EXPORT	|__rt_sdiv|
		EXPORT	|x$divide|

|__rt_sdiv|	ROUT
|x$divide|

		EOR	R0,R1,R0
		EOR	R1,R1,R0
		EOR	R0,R1,R0
		B	divide

		LTORG

; --- __rt_divtest ---
;
; On entry:	R0 == a number
;
; On exit:	--
;
; Use:		If R0 is zero, a `divide by zero' error is raised.

		EXPORT	|__rt_divtest|
		EXPORT	|x$divtest|

|__rt_divtest|	ROUT
|x$divtest|

		CMP	R0,#0
		MOVNES	PC,R14
		B	div_byZero

		LTORG

;----- That's all, folks ----------------------------------------------------

		END
