;//
;//	framfp1.s
;//
;//	高速単精度浮動小数点演算ライブラリ
;//
;//	CLiP - Common Library for P/ECE
;//	Copyright (C) 2001-2008 Naoyuki Sawa
;//
;//	* Thu Jun 05 21:54:59 JST 2008 Naoyuki Sawa
;//	- 1stリリース。
;//	- P/ECE開発環境付属の、EPSON製浮動小数点演算ライブラリ(fp.lib)中の、以下のモジュールを置き換えます。
;//		addsf3.o	__addsf3,__subsf3
;//		mulsf3.o	__mulsf3
;//		divsf3.o	__divsf3
;//		negsf2.o	__negsf2
;//		fixsfui.o	__fixsfsi,__fixunssfsi
;//		flosisf.o	__floatsisf
;//		trncdfsf.o	__truncdfsf2
;//		extsfdf.o	__extendsfdf2
;//		fcmps.o		__fcmps
;//	- 高速化のために、EPSON製浮動小数点演算ライブラリと較べて、以下の処理を省略しています。
;//	  - 入力値の扱い
;//	    - (-0)と非正規化数は、(+0)として扱います。
;//	      指数部のビットが全て0である入力値は、符号と仮数部の値にかかわらず(+0)として扱います。
;//	    - NaNと無限大は、考慮しません。
;//	      指数部のビットが全て1である入力値が与えられた場合、出力値は不定となります。
;//	  - 出力値の扱い
;//	    - (-0)と非正規化数は、(+0)として出力します。
;//	      非正規化数の範囲となる小さな演算結果や、アンダーフローが生じた場合は、(+0)を出力します。
;//	    - オーバーフローは、考慮しません。
;//	      演算の結果、オーバーフローが生じた場合、出力値は不定となります。
;//	  現実のアプリケーションでは、(-0)や非正規化数を、(+0)と区別すべきケースはほとんどありません。
;//	  オーバーフローが生じた場合に、NaNや無限大を判断して回復を行うアプリケーションもほとんど無いので、
;//	  事実上、ほぼ影響は無いと思います。
;//
		.code
		.align		1

;****************************************************************************
;	
;****************************************************************************

;//
;// [in]
;//		%r12		(float) val1
;//		%r13		(float) val2
;// [out]
;//		%r10		(float) val1 + val2
;//		%r10		(float) val1 - val2
;// [mod]
;//		%psr
;//		%r11,%r14,%r15
;//
		.global		__addsf3
		.global		__subsf3
__subsf3:
		xxor		%r13, %r13, 0x80000000		; %r13 := val2 = -val2
__addsf3:
		;// %r12 := val1
		;// %r13 := val2
		ld.w		%r10, %r12			; %r10 := seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
		add		%r10, %r10			; %r10 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmm0, C = sig1 -+
		rl		%r10, 8				; %r10 := mmmmmmmm mmmmmmmm mmmmmmm0 eeeeeeee            |
		xand		%r14, %r10, 255			; %r14 := 00000000 00000000 00000000 eeeeeeee = exp1     |
		jreq		__addsf3_ret2			; if(val1 == zero or denormal) return val2               |
		or		%r10, 1				; %r10 := mmmmmmmm mmmmmmmm mmmmmmm0 eeeeeee1            |
		rr		%r10, 1				; %r10 := 1mmmmmmm mmmmmmmm mmmmmmmm 0eeeeeee            |
		jruge.d		4				; if(C) { <----------------------------------------------+
		 srl		%r10, 8				; %r10 := 00000000 1mmmmmmm mmmmmmmm mmmmmmmm = man1		*delay*
		 not		%r10, %r10			;   %r10 := man1 = -man1
		 add		%r10, 1				; }
		;//
		ld.w		%r11, %r13			; %r11 := seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
		add		%r11, %r11			; %r11 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmm0, C = sig2 -+
		rl		%r11, 8				; %r11 := mmmmmmmm mmmmmmmm mmmmmmm0 eeeeeeee            |
		xand		%r15, %r11, 255			; %r15 := 00000000 00000000 00000000 eeeeeeee = exp2     |
		jreq		__addsf3_ret1			; if(val2 == zero or denormal) return val1               |
		or		%r11, 1				; %r11 := mmmmmmmm mmmmmmmm mmmmmmm0 eeeeeee1            |
		rr		%r11, 1				; %r11 := 1mmmmmmm mmmmmmmm mmmmmmmm 0eeeeeee            |
		jruge.d		4				; if(C) { <----------------------------------------------+
		 srl		%r11, 8				; %r11 := 00000000 1mmmmmmm mmmmmmmm mmmmmmmm = man2		*delay*
		 not		%r11, %r11			;   %r11 := man2 = -man2
		 add		%r11, 1				; }
		;// %r10 := man1 (min = 0xff000001, max = 0x00ffffff)
		;// %r11 := man2 (min = 0xff000001, max = 0x00ffffff)
		;// %r12 := val1
		;// %r13 := val2
		;// %r14 := exp1 (min = 1, max = 255)
		;// %r15 := exp2 (min = 1, max = 255)
		sub		%r14, %r15			; %r14 := exp1 - exp2
		jrlt		__addsf3_sft2
;__addsf3_sft1:
		;--- exp1 >= exp2 ---
		add		%r15, %r14			; %r15 := exp2 + exp1 - exp2 = exp1 = exp
;//{{このケースは少ないと思うので、判断を省略して処理継続。シフトに時間はかかるが、結果は同じになります。
;//		cmp		%r14, 24			; if(man2 -> 0)
;//		jrge		__addsf3_ret1			;   return val1
;//}}このケースは少ないと思うので、判断を省略して処理継続。シフトに時間はかかるが、結果は同じになります。
		;{{VARSHIFT
		cmp		%r14, 8				; %r11 := man2 >>= (exp1 - exp2)
		jrle		4
		sra		%r11, 8
		jp.d		-3
		sub		%r14, 8				;								*delay*
;//		sra		%r11, %r14			; --+
		;}}VARSHIFT					;   |
		jp.d		__addsf3_add			;   |
		sra		%r11, %r14			; <-+								*delay*
__addsf3_sft2:
		;--- exp2 > exp1 ---
		not		%r14, %r14			; %r14 := exp2 - exp1, %r15 := exp2 = exp
		add		%r14, 1
;//{{このケースは少ないと思うので、判断を省略して処理継続。シフトに時間はかかるが、結果は同じになります。
;//		cmp		%r14, 24			; if(man1 -> 0)
;//		jrge		__addsf3_ret2			;   return val2
;//}}このケースは少ないと思うので、判断を省略して処理継続。シフトに時間はかかるが、結果は同じになります。
		;{{VARSHIFT
		cmp		%r14, 8				; %r10 := man1 >>= (exp2 - exp1)
		jrle		4
		sra		%r10, 8
		jp.d		-3
		sub		%r14, 8				; *delay*
		sra		%r10, %r14
		;}}VARSHIFT
		;// %r10 := man1 (min = 0xff000001, max = 0x00ffffff)
		;// %r11 := man2 (min = 0xff000001, max = 0x00ffffff)
		;// %r15 := exp  (min = 1, max = 255)
__addsf3_add:
		add		%r10, %r11			; %r10 := man = man1 + man2
		jreq		__addsf3_ret0			; if(man == 0) return 0
		jrge.d		6				; if(man < 0) {
		 ld.w		%r11, 0				;   %r11 := sig = 0x00000000 (plus or zero)			*delay*
		 not		%r10, %r10			;   %r10 := man = |man|
		 add		%r10, 1
		 ld.w		%r11, 1				;   %r11 := sig = 0x80000000 (minus)
		 rr		%r11, 1				; }
		;// %r10 := man  (min = 0, max = 0x01fffffe)
		;// %r11 := sig  (plus or zero = 0x00000000, minus = 0x80000000)
		;// %r15 := exp  (min = 1, max = 255)
		scan1		%r14, %r10			; %r10 := 1??????? ???????? ???????? ?0000000
		sll		%r10, %r14
		jrult.d		-2
		 sub		%r15, %r14			; %r15 := exp - 8						*delay*
		sll		%r10, 1				; %r10 := mmmmmmmm mmmmmmmm mmmmmmm? 00000000
		add		%r15, 8				; %r15 := exp
		jrle		__addsf3_ret0			; if(exp <= 0) return 0
		;xcmp		%r15, 255			; ※オーバーフローはまず起きないので、検出処理を省略して高速化します。
		;jrge		overflow			; ※どうせ検出しても、アプリケーションで回復を行うのは(ほぼ)無理だし。
		or		%r10, %r15			; %r10 := mmmmmmmm mmmmmmmm mmmmmmm? eeeeeeee
		rr		%r10, 8				; %r10 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmm?
		srl		%r10, 1				; %r10 := 0eeeeeee emmmmmmm mmmmmmmm mmmmmmmm
		ret.d
		or		%r10, %r11			; %r10 := seeeeeee emmmmmmm mmmmmmmm mmmmmmmm			*delay*
__addsf3_ret0:
		ret.d
		ld.w		%r10, 0				;								*delay*
__addsf3_ret1:
		ret.d
		ld.w		%r10, %r12			;								*delay*
__addsf3_ret2:
		ret.d
		ld.w		%r10, %r13			;								*delay*

;****************************************************************************
;	
;****************************************************************************

;//
;// [in]
;//		%r12		(float) val1
;//		%r13		(float) val2
;// [out]
;//		%r10		(float) val1 * val2
;// [mod]
;//		%psr,%alr,%ahr
;//		%r12,%r13,%r14,%r15
;//
		.global		__mulsf3
__mulsf3:
		;// %r12 := val1
		;// %r13 := val2
		rl		%r12, 1				; %r12 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmms
		ld.w		%r10, %r12			; %r10 := ???????? ???????? ???????? ???????s = sig1
		and		%r12, 0xfffffffe		; %r12 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmm0
		rl		%r12, 8				; %r12 := mmmmmmmm mmmmmmmm mmmmmmm0 eeeeeeee
		xand		%r14, %r12, 255			; %r14 := 00000000 00000000 00000000 eeeeeeee = exp1
		jreq		__mulsf3_ret0			; if(val1 == zero or denormal) return 0
		sub		%r12, %r14			; %r12 := mmmmmmmm mmmmmmmm mmmmmmm0 00000000
		or		%r12, 1				; %r12 := mmmmmmmm mmmmmmmm mmmmmmm0 00000001
		rr		%r12, 1				; %r12 := 1mmmmmmm mmmmmmmm mmmmmmmm 00000000 = man1
		;//
		rl		%r13, 1				; %r13 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmms
		xor		%r10, %r13			; %r10 := ???????? ???????? ???????? ???????s = sig1 ^ sig2 = sig
		and		%r13, 0xfffffffe		; %r13 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmm0
		rl		%r13, 8				; %r13 := mmmmmmmm mmmmmmmm mmmmmmm0 eeeeeeee
		xand		%r15, %r13, 255			; %r15 := 00000000 00000000 00000000 eeeeeeee = exp2
		jreq		__mulsf3_ret0			; if(val2 == zero or denormal) return 0
		sub		%r13, %r15			; %r13 := mmmmmmmm mmmmmmmm mmmmmmm0 00000000
		or		%r13, 1				; %r13 := mmmmmmmm mmmmmmmm mmmmmmm0 00000001
		rr		%r13, 1				; %r13 := 1mmmmmmm mmmmmmmm mmmmmmmm 00000000 = man2
		;// %r10[0] := sig, %r10[31:1] = ?
		;// %r12    := man1
		;// %r13    := man2
		;// %r14    := exp1
		;// %r15    := exp2
		mltu.w		%r12, %r13			; %r12 := (man1 * man2)[63:32] = man (>= 0x40000000)
		ld.w		%r12, %ahr
		;// %r10[0] := sig, %r10[31:1] = ?
		;// %r12    := man
		;// %r14    := exp1
		;// %r15    := exp2
		add		%r12, %r12			; %r12 := man <<= 1, C = man[31]
		jrult.d		4				; if(!C)
		 add		%r14, %r15			; %r14 := exp1 + exp2 = exp					*delay*
		 add		%r12, %r12			;   %r12 := man <<= 1
		 sub		%r14, 1				;   %r14 := exp--
		xsub		%r14, %r14, 127-1		; %r14 := exp -= bias - 1
		jrle		__mulsf3_ret0			; if(exp <= 0) return 0
		;xcmp		%r14, 255			; ※オーバーフローはまず起きないので、検出処理を省略して高速化します。
		;jrge		overflow			; ※どうせ検出しても、アプリケーションで回復を行うのは(ほぼ)無理だし。
		;// %r10[0] := sig, %r10[31:1] = ?
		;// %r12    := man
		;// %r14    := exp
		xand		%r12, %r12, 0xfffffe00		; %r12 := mmmmmmmm mmmmmmmm mmmmmmm0 00000000
		or		%r12, %r14			; %r12 := mmmmmmmm mmmmmmmm mmmmmmm0 eeeeeeee
		rr		%r12, 8				; %r12 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmm0
		and		%r10, 1				; %r10 := 00000000 00000000 00000000 0000000s
		or		%r10, %r12			; %r10 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmms
		ret.d
		rr		%r10, 1				; %r10 := seeeeeee emmmmmmm mmmmmmmm mmmmmmmm			*delay*
__mulsf3_ret0:
		ret.d
		ld.w		%r10, 0				;								*delay*

;****************************************************************************
;	
;****************************************************************************

;//
;// [in]
;//		%r12		(float) val1
;//		%r13		(float) val2
;// [out]
;//		%r10		(float) val1 / val2
;// [mod]
;//		%psr,%alr,%ahr
;//		%r12,%r13,%r14,%r15
;//
		.global		__divsf3
__divsf3:
		;// %r12 := val1
		;// %r13 := val2
		rl		%r12, 1				; %r12 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmms
		ld.w		%r10, %r12			; %r10 := ???????? ???????? ???????? ???????s = sig1
		and		%r12, 0xfffffffe		; %r12 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmm0
		rl		%r12, 8				; %r12 := mmmmmmmm mmmmmmmm mmmmmmm0 eeeeeeee
		xand		%r14, %r12, 255			; %r14 := 00000000 00000000 00000000 eeeeeeee = exp1
		jreq		__divsf3_ret0			; if(val1 == zero or denormal) return 0
		sub		%r12, %r14			; %r12 := mmmmmmmm mmmmmmmm mmmmmmm0 00000000
		or		%r12, 1				; %r12 := mmmmmmmm mmmmmmmm mmmmmmm0 00000001
		rr		%r12, 2				; %r12 := 01mmmmmm mmmmmmmm mmmmmmmm m0000000 = man1
		;//
		rl		%r13, 1				; %r13 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmms
		xor		%r10, %r13			; %r10 := ???????? ???????? ???????? ???????s = sig1 ^ sig2 = sig
		and		%r13, 0xfffffffe		; %r13 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmm0
		rl		%r13, 8				; %r13 := mmmmmmmm mmmmmmmm mmmmmmm0 eeeeeeee
		xand		%r15, %r13, 255			; %r15 := 00000000 00000000 00000000 eeeeeeee = exp2
		jreq		__divsf3_ret0			; if(val2 == zero or denormal) 0除算エラー。(0を返すことにします)
		sub		%r13, %r15			; %r13 := mmmmmmmm mmmmmmmm mmmmmmm0 00000000
		or		%r13, 1				; %r13 := mmmmmmmm mmmmmmmm mmmmmmm0 00000001
		rr		%r13, 2				; %r13 := 01mmmmmm mmmmmmmm mmmmmmmm m0000000 = man2
		;// %r10[0] := sig, %r10[31:1] = ?
		;// %r12    := man1
		;// %r13    := man2
		;// %r14    := exp1
		;// %r15    := exp2
		; 除算結果に暗黙の最上位ビットを含まないよう、結果の最上位ビットに相当する減算処理を行っておきます。
		sub		%r12, %r13			; %r12 := man1 - man2
		jruge.d		6				; if(man1 < man2)
		 sub		%r14, %r15			; %r14 := exp1 - exp2 = exp					*delay*
		 sub		%r14, 1				;   %r14 := exp--
		 add		%r12, %r13			;   %r12 := man1
		 sll		%r12, 1				;   %r12 := 1mmmmmmm mmmmmmmm mmmmmmmm 00000000 = (man1 << 1)
		 sub		%r12, %r13			;   %r12 := ((man1 << 1) - man2)
		xadd		%r14, %r14, 127			; %r14 := exp -= bias
		jrle		__divsf3_ret0			; if(exp <= 0) return 0
		;xcmp		%r14, 255			; ※オーバーフローはまず起きないので、検出処理を省略して高速化します。
		;jrge		overflow			; ※どうせ検出しても、アプリケーションで回復を行うのは(ほぼ)無理だし。
		;// %r10[0] := sig, %r10[31:1] = ?
		;// %r12    := (man1 - man2) or ((man1 << 1) - man2)
		;// %r13    := man2
		;// %r14    := exp
		div0u		%r13				; %ahr := 0, DS = 0, N = 0
		ld.w		%alr, %r8			; %alr := 0
		ld.w		%ahr, %r12			; %ahr := (man1 - man2) or ((man1 << 1) - man2)
		div1		%r13				; %alr := 00000000 00000000 00000000 0000000m
		div1		%r13				; %alr := 00000000 00000000 00000000 000000mm
		div1		%r13				; %alr := 00000000 00000000 00000000 00000mmm
		div1		%r13				; %alr := 00000000 00000000 00000000 0000mmmm
		div1		%r13				; %alr := 00000000 00000000 00000000 000mmmmm
		div1		%r13				; %alr := 00000000 00000000 00000000 00mmmmmm
		div1		%r13				; %alr := 00000000 00000000 00000000 0mmmmmmm
		div1		%r13				; %alr := 00000000 00000000 00000000 mmmmmmmm
		div1		%r13				; %alr := 00000000 00000000 0000000m mmmmmmmm
		div1		%r13				; %alr := 00000000 00000000 000000mm mmmmmmmm
		div1		%r13				; %alr := 00000000 00000000 00000mmm mmmmmmmm
		div1		%r13				; %alr := 00000000 00000000 0000mmmm mmmmmmmm
		div1		%r13				; %alr := 00000000 00000000 000mmmmm mmmmmmmm
		div1		%r13				; %alr := 00000000 00000000 00mmmmmm mmmmmmmm
		div1		%r13				; %alr := 00000000 00000000 0mmmmmmm mmmmmmmm
		div1		%r13				; %alr := 00000000 00000000 mmmmmmmm mmmmmmmm
		div1		%r13				; %alr := 00000000 0000000m mmmmmmmm mmmmmmmm
		div1		%r13				; %alr := 00000000 000000mm mmmmmmmm mmmmmmmm
		div1		%r13				; %alr := 00000000 00000mmm mmmmmmmm mmmmmmmm
		div1		%r13				; %alr := 00000000 0000mmmm mmmmmmmm mmmmmmmm
		div1		%r13				; %alr := 00000000 000mmmmm mmmmmmmm mmmmmmmm
		div1		%r13				; %alr := 00000000 00mmmmmm mmmmmmmm mmmmmmmm
		div1		%r13				; %alr := 00000000 0mmmmmmm mmmmmmmm mmmmmmmm
		;// %r10[0] := sig, %r10[31:1] = ?
		;// %alr    := man
		;// %r14    := exp
		rr		%r14, 8				; %r14 := eeeeeeee 00000000 00000000 00000000
		and		%r10, 1				; %r10 := 00000000 00000000 00000000 0000000s
		or		%r10, %r14			; %r10 := eeeeeeee 00000000 00000000 0000000s
		rr		%r10, 1				; %r10 := seeeeeee e0000000 00000000 00000000
		ld.w		%r12, %alr			; %r12 := 00000000 0mmmmmmm mmmmmmmm mmmmmmmm
		ret.d
		or		%r10, %r12			; %r10 := seeeeeee emmmmmmm mmmmmmmm mmmmmmmm			*delay*
__divsf3_ret0:
		ret.d
		ld.w		%r10, 0

;****************************************************************************
;	
;****************************************************************************

;//
;// [in]
;//		%r12		(float) val
;// [out]
;//		%psr		(float) -val
;// [mod]
;//		%psr
;//		%r12
;//
		.global		__negsf2
__negsf2:
		;// %r12 := val
		rl		%r12, 1				; %r12 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmms
		xor		%r12, 1				; %r12 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmmS
		rr		%r12, 1				; %r10 := Seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
		ret.d
		ld.w		%r10, %r12			; %r10 := Seeeeeee emmmmmmm mmmmmmmm mmmmmmmm			*delay*

;****************************************************************************
;	
;****************************************************************************

;// 0方向へ丸めるために、仮数シフト→符号反転の順で処理を行います。
;// もし符号反転→仮数シフトの順で処理を行うと、負数の丸め方向が0方向にならないため不可です。
;// <例> 仮数シフト→符号反転の順で処理 : 1.1 → 1, -1.1 → -1 (正)
;//      符号反転→仮数シフトの順で処理 : 1.1 → 1, -1.1 → -2 (誤)

;//
;// [in]
;//		%r12		(float) val
;// [out]
;//		%r10		(int) val
;//		%r10		(unsigned) val
;// [mod]
;//		%psr
;//		%r11
;// [note]
;//		* 0方向へ丸めるために、仮数シフト→符号反転の順で処理を行います。
;//		  もし符号反転→仮数シフトの順で処理を行うと、負数の丸め方向が0方向にならないため、不可です。
;//		  <例>	仮数シフト→符号反転の順で処理 : 1.1 → 1, -1.1 → -1 (正)
;//			符号反転→仮数シフトの順で処理 : 1.1 → 1, -1.1 → -2 (誤)
;//
		.global		__fixsfsi
		.global		__fixunssfsi
__fixunssfsi:
__fixsfsi:
		;// %r12 := val
		ld.w		%r10, %r12			; %r10 := seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
		xrl		%r10, 9				; %r12 := mmmmmmmm mmmmmmmm mmmmmmms eeeeeeee
		ld.ub		%r11, %r10			; %r11 := 00000000 00000000 00000000 eeeeeeee
		or		%r10, 1				; %r10 := mmmmmmmm mmmmmmmm mmmmmmms eeeeeee1
		rr		%r10, 1				; %r10 := 1mmmmmmm mmmmmmmm mmmmmmmm seeeeeee
;//		srl		%r10, 8				; %r10 := 00000000 1mmmmmmm mmmmmmmm mmmmmmmm -+
		xsub		%r11, %r11, 127+23		; %r11 := exp -= bias + 23                     |
		jrlt.d		__fixsfsi_srl			;                                              |
		srl		%r10, 8				; <--------------------------------------------+		*delay*
;__fixsfsi_sll:
		;{{VARSHIFT
		cmp		%r11, 8				; %r10 := man << exp = retval
		jrle		4
		sll		%r10, 8
		jp.d		-3
		sub		%r11, 8				;								*delay*
;//		sll		%r10, %r11			; --+
		;}}VARSHIFT					;   |
		jp.d		__fixsfsi_neg			;   |
		sll		%r10, %r11			; <-+								*delay*
__fixsfsi_srl:
		not		%r11, %r11			; %r11 := exp = |exp|
		add		%r11, 1
		;{{VARSHIFT
		cmp		%r11, 8				; %r10 := man >> exp = retval
		jrle		4
		srl		%r10, 8
		jp.d		-3
		sub		%r11, 8				;								*delay*
		srl		%r10, %r11
		;}}VARSHIFT
__fixsfsi_neg:
		cmp		%r12, 0				; if(sig) {
		jrge		3
		 not		%r10, %r10			;   retval = -retval
		 add		%r10, 1
		ret						; }

;****************************************************************************
;	
;****************************************************************************

;//
;// [in]
;//		%r12		(int) val
;// [out]
;//		%r10		(float) val
;// [mod]
;//		%psr
;//		%r11,%r12,%r13
;//
		.global		__floatsisf
__floatsisf:
		;// %r12 := val
		cmp		%r12, 0				; if(val <= 0)
		jrgt.d		6
		 ld.w		%r10, 0				; %r10 := sig = 0						*delay*
		 jreq		__floatsisf_ret			;   if(val == 0) return 0 (最後の"rr %r10,1"は、ダミー動作になります。)
		 not		%r12, %r12			;   %r12 := val = -val
		 add		%r12, 1				;
		 ld.w		%r10, 1				;   %r10 := sig = 1
		;//						;
		xld.w		%r11, 127+31			; %r11 := exp = bias + 31
		 scan1		%r13, %r12			; %r12 := 1mmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm = man
		 sll		%r12, %r13			;
		jrult.d		-2
		sub		%r11, %r13			; %r11 := exp = bias + 31 - shift count (min = 127, max = 158)	*delay*
		;//
		xand		%r12, %r12, 0xffffff00		; %r12 := 1mmmmmmm mmmmmmmm mmmmmmmm 00000000
		sll		%r12, 1				; %r12 := mmmmmmmm mmmmmmmm mmmmmmm0 00000000
		or		%r12, %r11			; %r12 := mmmmmmmm mmmmmmmm mmmmmmm0 eeeeeeee
		rr		%r12, 8				; %r12 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmm0
		or		%r10, %r12			; %r10 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmms
__floatsisf_ret:
		ret.d
		rr		%r10, 1				; %r10 := seeeeeee emmmmmmm mmmmmmmm mmmmmmmm			*delay*

;****************************************************************************
;	
;****************************************************************************

;//
;// [in]
;//		%r12,%r13	(double) val
;// [out]
;//		%r10		(float) val
;// [mod]
;//		%psr
;//		%r12,%r13
;//
		.global		__truncdfsf2
__truncdfsf2:
		;// %r12 := LO(val)
		;// %r13 := HI(val)
		rl		%r12, 3				; %r12 := ???????? ???????? ???????? ?????nnn
		and		%r12, 7				; %r12 := 00000000 00000000 00000000 00000nnn
		;//
		add		%r13, %r13			; %r13 := eeeeeeee eeemmmmm mmmmmmmm mmmmmmm0, C = s
		adc		%r12, %r12			; %r12 := 00000000 00000000 00000000 0000nnns
		;//
		xrl		%r13, 11			; %r13 := mmmmmmmm mmmmmmmm mmmm0eee eeeeeeee
		xand		%r10, %r13, 0x7ff		; %r10 := 00000000 00000000 00000eee eeeeeeee
		xor		%r13, %r10			; %r13 := mmmmmmmm mmmmmmmm mmmm0000 00000000
		;//
		xsub		%r10, %r10, 1023-127		; %r10 := 00000000 00000000 00000000 eeeeeeee = exp -= bias64 - bias32
		jrle		__truncdfsf2_ret0		; if(exp <= 0) return 0
		;xcmp		%r10, 255			; ※オーバーフローはまず起きないので、検出処理を省略して高速化します。
		;jrge		overflow			; ※どうせ検出しても、アプリケーションで回復を行うのは(ほぼ)無理だし。
		;//
		or		%r10, %r13			; %r10 := mmmmmmmm mmmmmmmm mmmm0000 eeeeeeee
		rr		%r10, 8				; %r10 := eeeeeeee mmmmmmmm mmmmmmmm mmmm0000
		or		%r10, %r12			; %r10 := eeeeeeee mmmmmmmm mmmmmmmm mmmmnnns
		ret.d
		rr		%r10, 1				; %r10 := seeeeeee emmmmmmm mmmmmmmm mmmmmnnn			*delay*
__truncdfsf2_ret0:
		ret.d
		ld.w		%r10, 0				;								*delay*

;****************************************************************************
;	
;****************************************************************************

;//
;// [in]
;//		%r12		(float) val
;// [out]
;//		%r10,%r11	(double) val
;// [mod]
;//		%psr
;//		%r12,%r13
;//
		.global		__extendsfdf2
__extendsfdf2:
		;// %r12 := val
		xand		%r10, %r12, 7			; %r10 := 00000000 00000000 00000000 00000nnn
		rr		%r10, 3				; %r10 := nnn00000 00000000 00000000 00000000
		;//
		rl		%r12, 1				; %r12 := eeeeeeee mmmmmmmm mmmmmmmm mmmmnnns
		xand		%r11, %r12, 1			; %r11 := 00000000 00000000 00000000 0000000s
		;//
		rl		%r12, 8				; %r12 := mmmmmmmm mmmmmmmm mmmmnnns eeeeeeee
		xand		%r13, %r12, 255			; %r13 := 00000000 00000000 00000000 eeeeeeee
		jreq		__extendsfdf2_ret0
		xadd		%r13, %r13, 1023-127		; %r13 := 00000000 00000000 00000eee eeeeeeee = exp += bias64 - bias32
		;//
		xand		%r12, %r12, 0xfffff000		; %r12 := mmmmmmmm mmmmmmmm mmmm0000 00000000
		or		%r12, %r13			; %r12 := mmmmmmmm mmmmmmmm mmmm0eee eeeeeeee
		xrr		%r12, 11			; %r12 := eeeeeeee eeemmmmm mmmmmmmm mmmmmmm0
		or		%r11, %r12			; %r11 := eeeeeeee eeemmmmm mmmmmmmm mmmmmmms
		ret.d
		rr		%r11, 1				; %r11 := seeeeeee eeeemmmm mmmmmmmm mmmmmmmm			*delay*
__extendsfdf2_ret0:
		ret.d
		ld.w		%r10, 0				;								*delay*

;****************************************************************************
;	
;****************************************************************************

;//
;// [in]
;//		%r12		(float) val1
;//		%r13		(float) val2
;// [out]
;//		%psr		(float) val1 - val2
;// [mod]
;//		%r12,%r13
;//
		.global		__fcmps
__fcmps:
		;// %r12 := val1
		;// %r13 := val2
		add		%r12, %r12			; %r12 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmm0, C = s
		jruge.d		4				; if(C)
		 srl		%r12, 1				; %r12 := 0eeeeeee emmmmmmm mmmmmmmm mmmmmmmm			*delay*
		 not		%r12, %r12			;   %r12 := -(0eeeeeee emmmmmmm mmmmmmmm mmmmmmmm)
		 add		%r12, 1
		;//
		add		%r13, %r13			; %r13 := eeeeeeee mmmmmmmm mmmmmmmm mmmmmmm0, C = s
		jruge.d		4				; if(C)
		 srl		%r13, 1				; %r13 := 0eeeeeee emmmmmmm mmmmmmmm mmmmmmmm			*delay*
		 not		%r13, %r13			;   %r13 := -(0eeeeeee emmmmmmm mmmmmmmm mmmmmmmm)
		 add		%r13, 1
		;//
		ret.d
		cmp		%r12, %r13			; %psr := (sig1 * (exp1 | man1)) - (sig2 * (exp2 | man2))	*delay*

;****************************************************************************
;	
;****************************************************************************
