;//
;//	framdbl1.s
;//
;//	高速倍精度浮動小数点演算ライブラリ
;//
;//	CLiP - Common Library for P/ECE
;//	Copyright (C) 2001-2012 Naoyuki Sawa
;//
;//	* Thu Feb 02 23:34:18 JST 2012 Naoyuki Sawa
;//	- 1st リリース。
;//
		.code
		.align		1

;****************************************************************************
;	
;****************************************************************************

;//
;// [in]
;//		%r13:%r12	(double)  val
;// [out]
;//		%r11:%r10	(double) -val
;// [mod]
;//		%r13
;//
		.global		__negdf2
__negdf2:
		;// %r13:%r12 := val
		rl		%r13, 1				;// %r13   := eeeeeeee eeemmmmm mmmmmmmm mmmmmmms
		jreq.d		3				;// if(val != zero or denormal) 
		 ld.w		%r11, %r13			;// %r11   := eeeeeeee eeemmmmm mmmmmmmm mmmmmmms	*delay*
		 xor		%r11, 1				;//   %r11 := eeeeeeee eeemmmmm mmmmmmmm mmmmmmmS
		 rr		%r11, 1				;//   %r11 := Seeeeeee eeeemmmm mmmmmmmm mmmmmmmm
		ret.d
		ld.w		%r10, %r12			;// %r10   := mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm	*delay*

;****************************************************************************
;	
;****************************************************************************

;//
;// [in]
;//		%r13:%r12	(double) val1
;//		%r15:%r14	(double) val2
;// [out]
;//		%psr		(double) val1 - val2
;// [mod]
;//		%r12,%r13,%r14,%r15
;//
		.global		__fcmpd
__fcmpd:
		;// %r13:%r12 := val1
		;// %r15:%r14 := val2
		add		%r13, %r13			;// %r13 := eeeeeeee eeemmmmm mmmmmmmm mmmmmmm0, C = s
		jruge.d		6				;// if(C)
		 srl		%r13, 1				;// %r13 := 0eeeeeee eeeemmmm mmmmmmmm mmmmmmmm					*delay*
		 not		%r12, %r12			;//   %r13:%r12 := -(0eeeeeee eeeemmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm)
		 not		%r13, %r13
		 add		%r12, 1
		 adc		%r13, %r8
		;//
		add		%r15, %r15			;// %r15 := eeeeeeee eeemmmmm mmmmmmmm mmmmmmm0, C = s
		jruge.d		6				;// if(C)
		 srl		%r15, 1				;// %r15 := 0eeeeeee eeeemmmm mmmmmmmm mmmmmmmm					*delay*
		 not		%r14, %r14			;//   %r15:%r14 := -(0eeeeeee eeeemmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm)
		 not		%r15, %r15
		 add		%r14, 1
		 adc		%r15, %r8
		;//比較手順は以下のとおり：
		;//・上位ワードを符号付きで比較する。
		;//⇒一致しなければ、それが比較結果となる。⇒{lt/gt}
		;//⇒一致した場合は、下位ワードを符号無しで比較する。
		;//　ただし、比較結果が符号付き比較のフラグに反映されるよう、-(2^31)オフセットしておく。
		;//⇒⇒一致/不一致にかかわらず、それが比較結果となる。⇒{lt/eq/gt}
		cmp		%r13, %r15			;// %psr := 上位ワード比較結果{lt/eq/gt}
		jrne		6
		 ld.w		%r9, 1				;// %r9  := (2^31)
		 rr		%r9, 1
		 sub		%r12, %r9			;// %r12 -= (2^31)
		 sub		%r14, %r9			;// %r14 -= (2^31)
		 cmp		%r12, %r14			;// %psr := 下位ワード比較結果{lt/eq/gt}
		ret

;****************************************************************************
;	
;****************************************************************************

;//
;// [in]
;//		%r13:%r12	(double) val1
;//		%r15:%r14	(double) val2
;// [out]
;//		%r11:%r10	(double) val1 + val2
;//		%r11:%r10	(double) val1 - val2
;// [mod]
;//		%r4,%r5,%r6,%r7,%r12,%r13,%r14,%r15
;//
		.global		__adddf3
		.global		__subdf3
__subdf3:
		;// %r13:%r12 := val1
		;// %r15:%r14 := val2
		rl		%r15, 1				;// %r15 := eeeeeeee eeemmmmm mmmmmmmm mmmmmmms
		jreq		__adddf3_ret1			;// if(val2 == zero or denormal) return val1
		xor		%r15, 1				;// %r15 := eeeeeeee eeemmmmm mmmmmmmm mmmmmmmS
		rr		%r15, 1				;// %r15 := Seeeeeee eeeemmmm mmmmmmmm mmmmmmmm
__adddf3:
		;// %r13:%r12 := val1
		;// %r15:%r14 := val2
		ld.w		%r10, %r12			;// %r10 := mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm
		ld.w		%r11, %r13			;// %r11 := seeeeeee eeeemmmm mmmmmmmm mmmmmmmm
		;//
		add		%r11, %r11			;// %r11 := eeeeeeee eeemmmmm mmmmmmmm mmmmmmm0, C = sig1 ------+
		xrl		%r11, 11			;// %r11 := mmmmmmmm mmmmmmmm mmmm0eee eeeeeeee			|
		xand		%r4, %r11, 0x7FF		;// %r4  := 00000000 00000000 00000eee eeeeeeee = exp1		|
		jreq		__adddf3_ret2			;// if(val1 == zero or denormal) return val2			|
		or		%r11, 1				;// %r11 := mmmmmmmm mmmmmmmm mmmm0eee eeeeeee1			|
		rr		%r11, 1				;// %r11 := 1mmmmmmm mmmmmmmm mmmmm0ee eeeeeeee			|
		xsrl		%r11, 11			;// %r11 := 00000000 0001mmmm mmmmmmmm mmmmmmmm			|
		jruge.d		7				;// if(C) <-----------------------------------------------------+
		 ld.w		%r6, 0				;// %r6    :=  0 (man1 > 0)					*delay*
		 ld.w		%r6, -1				;//   %r6  := -1 (man1 < 0)
		 not		%r10, %r10			;//   %r11:%r10 := man1 = -man1
		 not		%r11, %r11
		 add		%r10, 1
		 adc		%r11, %r8
		;//
		add		%r15, %r15			;// %r15 := eeeeeeee eeemmmmm mmmmmmmm mmmmmmm0, C = sig2 ------+
		xrl		%r15, 11			;// %r15 := mmmmmmmm mmmmmmmm mmmm0eee eeeeeeee			|
		xand		%r5, %r15, 0x7FF		;// %r5  := 00000000 00000000 00000eee eeeeeeee = exp2		|
		jreq		__adddf3_ret1			;// if(val2 == zero or denormal) return val1			|
		or		%r15, 1				;// %r15 := mmmmmmmm mmmmmmmm mmmm0eee eeeeeee1			|
		rr		%r15, 1				;// %r15 := 1mmmmmmm mmmmmmmm mmmmm0ee eeeeeeee			|
		xsrl		%r15, 11			;// %r15 := 00000000 0001mmmm mmmmmmmm mmmmmmmm			|
		jruge.d		7				;// if(C) <-----------------------------------------------------+
		 ld.w		%r7, 0				;// %r7    :=  0 (man2 > 0)					*delay*
		 ld.w		%r7, -1				;//   %r7  := -1 (man2 < 0)
		 not		%r14, %r14			;//   %r15:%r14 := man2 = -man2
		 not		%r15, %r15
		 add		%r14, 1
		 adc		%r15, %r8
		;// %r4       := exp1 (min = 0x001, max = 0x7FF)
		;// %r5       := exp2 (min = 0x001, max = 0x7FF)
		;// %r6       := 0 (man1 > 0) or -1 (man1 < 0)
		;// %r7       := 0 (man2 > 0) or -1 (man2 < 0)
		;// %r11:%r10 := man1 (min = 0xFFE00000_00000001, max = 0x001FFFFF_FFFFFFFF)
		;// %r15:%r14 := man2 (min = 0xFFE00000_00000001, max = 0x001FFFFF_FFFFFFFF)
		sub		%r4, %r5			;// %r4  := exp1 - exp2 = expdiff
		jrlt		__adddf3_sft2
;//__adddf3_sft1:
		;//--- exp1 >= exp2 ---
		add		%r5, %r4			;// %r5  := exp2 + exp1 - exp2 = exp1 = exp
		;{{VARSHIFT
		cmp		%r4, 31				;// while(expdiff >= 32)
		jrle		5
		 ld.w		%r14, %r15			;//   %r15:%r14 := man2 >>= 32
		 ld.w		%r15, %r7
		 jp.d		-4
		 sub		%r4, 32				;//   %r4  := expdiff -= 32					*delay*
		;//
		ld.w		%r9, -1				;// %r9  := mask = -1
		cmp		%r4, 8				;// while(expdiff > 8)
		jrle		6
		 srl		%r9, 8				;//   %r9  := mask   >>= 8
		 srl		%r14, 8				;//   %r14 := man2L  >>= 8
		 rr		%r15, 8				;//   %r15 := man2H >>>= 8
		 jp.d		-5
		 sub		%r4, 8				;//   %r4  := expdiff -= 8					*delay*
		srl		%r9, %r4			;// %r9  := mask   >>= expdiff
		srl		%r14, %r4			;// %r14 := man2L  >>= expdiff
		rr		%r15, %r4			;// %r15 := man2H >>>= expdiff
		;//
		xor		%r14, %r15			;// %r14 := ((man2H >>> expdiff) ^ (man2L >> expdiff))
		and		%r15, %r9			;// %r15 :=                                              ((man2H >>> expdiff) & (mask >> expdiff))
		xor		%r14, %r15			;// %r14 := ((man2H >>> expdiff) ^ (man2L >> expdiff)) ^ ((man2H >>> expdiff) & (mask >> expdiff)) -> man2L
		not		%r9, %r9			;// %r9  :=              ~mask
		and		%r9, %r7			;// %r9  := ((0 (man2 > 0) or -1 (man2 < 0)) & ~mask)
;//		or		%r15, %r9			;// %r15 := ((0 (man2 > 0) or -1 (man2 < 0)) & ~mask)  | ((man2H >>> expdiff) & (mask >> expdiff)) -> man2H ----+
		;}}VARSHIFT					;//														|
		jp.d		__adddf3_add			;//														|
		or		%r15, %r9			;// <-----------------------------------------------------------------------------------------------------------+	*delay*
;//{{=== 末尾に置くと遠くて一命令でjr**できず、xjr**が必要になってしまう。一命令でjr**できるよう、中間に置くことにした ===
__adddf3_ret0:
		ld.w		%r10, 0				;// return 0
		ret.d
		ld.w		%r11, 0				;//								*delay*
__adddf3_ret1:
		ld.w		%r10, %r12			;// return val1
		ret.d
		ld.w		%r11, %r13			;//								*delay*
__adddf3_ret2:
		ld.w		%r10, %r14			;// return val2
		ret.d
		ld.w		%r11, %r15			;//								*delay*
;//}}=== 末尾に置くと遠くて一命令でjr**できず、xjr**が必要になってしまう。一命令でjr**できるよう、中間に置くことにした ===
__adddf3_sft2:
		;//--- exp2 > exp1 ---
		not		%r4, %r4			;// %r4  := -(exp1 - exp2) = exp2 - exp1 = expdiff, %r5  := exp2 = exp
		add		%r4, 1
		;{{VARSHIFT
		cmp		%r4, 31				;// while(expdiff >= 32)
		jrle		5
		 ld.w		%r10, %r11			;//   %r11:%r10 := man1 >>= 32
		 ld.w		%r11, %r6
		 jp.d		-4
		 sub		%r4, 32				;//   %r4  := expdiff -= 32					*delay*
		;//
		ld.w		%r9, -1				;// %r9  := mask = -1
		cmp		%r4, 8				;// while(expdiff > 8)
		jrle		6
		 srl		%r9, 8				;//   %r9  := mask   >>= 8
		 srl		%r10, 8				;//   %r10 := man1L  >>= 8
		 rr		%r11, 8				;//   %r11 := man1H >>>= 8
		 jp.d		-5
		 sub		%r4, 8				;//   %r4  := expdiff -= 8					*delay*
		srl		%r9, %r4			;// %r9  := mask   >>= expdiff
		srl		%r10, %r4			;// %r10 := man1L  >>= expdiff
		rr		%r11, %r4			;// %r11 := man1H >>>= expdiff
		;//
		xor		%r10, %r11			;// %r10 := ((man1H >>> expdiff) ^ (man1L >> expdiff))
		and		%r11, %r9			;// %r11 :=                                              ((man1H >>> expdiff) & (mask >> expdiff))
		xor		%r10, %r11			;// %r10 := ((man1H >>> expdiff) ^ (man1L >> expdiff)) ^ ((man1H >>> expdiff) & (mask >> expdiff)) -> man1L
		not		%r9, %r9			;// %r9  :=              ~mask
		and		%r9, %r6			;// %r9  := ((0 (man1 > 0) or -1 (man1 < 0)) & ~mask)
		or		%r11, %r9			;// %r11 := ((0 (man1 > 0) or -1 (man1 < 0)) & ~mask)  | ((man1H >>> expdiff) & (mask >> expdiff)) -> man1H
		;}}VARSHIFT
		;// %r5       := exp (min = 0x001, max = 0x7FF)
		;// %r11:%r10 := man1 (min = 0xFFE00000_00000001, max = 0x001FFFFF_FFFFFFFF)
		;// %r15:%r14 := man2 (min = 0xFFE00000_00000001, max = 0x001FFFFF_FFFFFFFF)
__adddf3_add:
		add		%r10, %r14			;// %r11:%r10 := man = man1 + man2
		jrne.d		3				;// if(manL == 0)
		 adc		%r11, %r15			;// ----------------------------+				*delay*
		 jreq		__adddf3_ret0			;//   if(manH == 0) return 0	|
		jrge.d		8				;// if(manH < 0) <--------------+
		 ld.w		%r4, 0				;//   %r4  := sig = 0x00000000 (plus or zero)			*delay*
		 ld.w		%r4, 1				;//   %r4  := sig = 0x80000000 (minus)
		 rr		%r4, 1
		 not		%r10, %r10			;//   %r11:%r10 := man = |man|
		 not		%r11, %r11
		 add		%r10, 1
		 adc		%r11, %r8
		;// %r4       := sig (plus or zero = 0x00000000, minus = 0x80000000)
		;// %r5       := exp (min = 0x001, max = 0x7FF)
		;// %r11:%r10 := man (min = 0x00000000_00000001, max = 0x003FFFFF_FFFFFFFE)
		ld.w		%r6, %r11			;// %r6  := tmp = manH
		cmp		%r11, 0				;// if(tmp == 0)
		jrne.d		4
		 ld.w		%r7, -11			;// %r7    := shift_count =   -11				*delay*
		 add		%r7, 32				;//   %r7  := shift_count = 32-11
		 ld.w		%r6, %r10			;//   %r6  := tmp = manL
		scan1		%r9, %r6			;//   ┐%r11:%r10の中で1が立っている最上位ビットを、
		sll		%r6, %r9			;//   │%r11のbit20(上から11bit目)にシフトするために
		jrult.d		-2				;//   │必要なシフト数を、%r7に求めます。
		add		%r7, %r9			;//   ┘%r7 の範囲は、-1～53 になります。			*delay*
		sub		%r5, %r7			;// %r5  := exp -= shift_count
		jrle		__adddf3_ret0			;// if(exp <= 0) return 0
		;// %r4       := sig (plus or zero = 0x00000000, minus = 0x80000000)
		;// %r5       := exp (min = 0x001, max = 0x7FF)
		;// %r7       := shift_count (min = -1, max = 53)
		;// %r11:%r10 := man (min = 0x00000000_00000001, max = 0x003FFFFF_FFFFFFFE)
		cmp		%r7, -1				;// if(shift_count == -1)
		jrne.d		__adddf3_sft4
		xor		%r5, 1				;// <-------------------------------------------------------------------------------------------------------------------+	*delay*
;//__adddf3_sft3:						;//															|
		;//--- shift_count == -1 ---			;//															|
		xand		%r9, %r11, 1			;//   %r9  :=                (manH &  1)										|
		and		%r10, ~1			;//   %r10 :=  (manL & ~1)												|
		or		%r10, %r9			;//   %r10 :=  (manL & ~1) | (manH &  1)										|
		rr		%r10, 1				;//   %r10 := ((manL & ~1) | (manH &  1)) >>> 1 -> manL									|
		jp.d		__adddf3_retn			;//															|
		srl		%r11, 1				;//   %r11 :=                (manH >> 1)        -> manH		*delay*							|
__adddf3_sft4:							;//															|
		;//--- shift_count >=  0 ---			;//															|
		cmp		%r7, 31				;// if(shift_count >= 32)												|
		jrle		4				;//															|
		 ld.w		%r11, %r10			;//   %r11:%r10 := man <<= 32												|
		 ld.w		%r10, 0				;//															|
		 sub		%r7, 32				;//   %r7  := shift_count -= 32												|
		ld.w		%r9, -1				;// %r9  := mask = -1													|
		cmp		%r7, 8				;// while(expdiff > 8)													|
		jrle		6				;//															|
		 sll		%r9, 8				;//   %r9  := mask  <<= 8												|
		 rl		%r10, 8				;//   %r10 := manL <<<= 8												|
		 sll		%r11, 8				;//   %r11 := manH  <<= 8												|
		 jp.d		-5				;//															|
		 sub		%r7, 8				;//   %r7  := shift_count -= 8					*delay*							|
		sll		%r9, %r7			;// %r9  := mask  <<= shift_count											|
		rl		%r10, %r7			;// %r10 := manL <<<= shift_count											|
		sll		%r11, %r7			;// %r11 := manH  <<= shift_count											|
		xor		%r11, %r10			;// %r11 := ((manH << shift_count) ^ (manL <<< shift_count))								|
		and		%r10, %r9			;// %r10 :=                                                    ((manL <<< shift_count) & (mask << shift_count)) -> manL	|
		xor		%r11, %r10			;// %r11 := ((manH << shift_count) ^ (manL <<< shift_count)) ^ ((manL <<< shift_count) & (mask << shift_count)) -> manH	|
__adddf3_retn:							;//															|
		;// %r4  := sig  = s0000000 00000000 00000000 00000000															|
		;// %r5  := exp  = 00000000 00000000 00000eee eeeeeeee															|
		;// %r10 := manL = mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm															|
		;// %r11 := manH = 00000000 0001mmmm mmmmmmmm mmmmmmmm															|
;//		xor		%r5, 1				;// %r5  := 00000000 00000000 00000eee eeeeeeeE ------------------------------------------------------------------------+
		xrr		%r5, 12				;// %r5  := 0eeeeeee eeeE0000 00000000 00000000
		xor		%r11, %r5			;// %r11 := 0eeeeeee eeeemmmm mmmmmmmm mmmmmmmm
		ret.d
		or		%r11, %r4			;// %r11 := seeeeeee eeeemmmm mmmmmmmm mmmmmmmm			*delay*

;****************************************************************************
;	
;****************************************************************************

;// [in]
;//		%r13:%r12	(double) val1
;//		%r15:%r14	(double) val2
;// [out]
;//		%r11:%r10	(double) val1 * val2
;// [mod]
;//		%r4,%r5,%r12,%r13,%r14,%r15
;//
		.global		__muldf3
__muldf3:
		;// %r13:%r12 := val1
		;// %r15:%r14 := val2
		xrl		%r13, 12			;// %r13 := mmmmmmmm mmmmmmmm mmmmseee eeeeeeee
		xand		%r4, %r13, 0x7FF		;// %r4  := 00000000 00000000 00000eee eeeeeeee
		jreq		__muldf3_ret0			;// if(val1 == zero or denormal) return 0
		sub		%r13, %r4			;// %r13 := mmmmmmmm mmmmmmmm mmmms000 00000000
		xand		%r5, %r13, 0x800		;// %r5  := 00000000 00000000 0000s000 00000000 = sig1
		sub		%r13, %r5			;// %r13 := mmmmmmmm mmmmmmmm mmmm0000 00000000
		or		%r13, 1				;// %r13 := mmmmmmmm mmmmmmmm mmmm0000 00000001
		rr		%r13, 1				;// %r13 := 1mmmmmmm mmmmmmmm mmmmm000 00000000
		xrl		%r12, 11			;// %r12 := nnnnnnnn nnnnnnnn nnnnnmmm mmmmmmmm
		xor		%r13, %r12			;// %r13 := ???????? ???????? ?????mmm mmmmmmmm
		xand		%r12, %r12, ~0x7FF		;// %r12 := nnnnnnnn nnnnnnnn nnnnn000 00000000 = man1L
		xor		%r13, %r12			;// %r13 := 1mmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm = man1H
		;//
		xrl		%r15, 12			;// %r15 := mmmmmmmm mmmmmmmm mmmmseee eeeeeeee
		xand		%r9, %r15, 0x7FF		;// %r9  := 00000000 00000000 00000eee eeeeeeee
		jreq		__muldf3_ret0			;// if(val2 == zero or denormal) return 0
		sub		%r15, %r9			;// %r15 := mmmmmmmm mmmmmmmm mmmms000 00000000
		add		%r4, %r9			;// %r4  := exp1 + exp2 = exp
		xand		%r9, %r15, 0x800		;// %r9  := 00000000 00000000 0000s000 00000000 = sig2
		sub		%r15, %r9			;// %r15 := mmmmmmmm mmmmmmmm mmmm0000 00000000
		xor		%r5, %r9			;// %r5  := 00000000 00000000 0000s000 00000000 = sig1 ^ sig2 = sig
		or		%r15, 1				;// %r15 := mmmmmmmm mmmmmmmm mmmm0000 00000001
		rr		%r15, 1				;// %r15 := 1mmmmmmm mmmmmmmm mmmmm000 00000000
		xrl		%r14, 11			;// %r14 := nnnnnnnn nnnnnnnn nnnnnmmm mmmmmmmm
		xor		%r15, %r14			;// %r15 := ???????? ???????? ?????mmm mmmmmmmm
		xand		%r14, %r14, ~0x7FF		;// %r14 := nnnnnnnn nnnnnnnn nnnnn000 00000000 = man2L
		xor		%r15, %r14			;// %r15 := 1mmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm = man2H
		;// %r4       := exp (min = 0x002, max = 0xFFE)
		;// %r5       := sig (00000000 00000000 0000s000 00000000)
		;// %r13:%r12 := man1 (min = 0x80000000_00000000, max = 0xFFFFFFFF_FFFFF800)
		;// %r15:%r14 := man2 (min = 0x80000000_00000000, max = 0xFFFFFFFF_FFFFF800)
		mltu.w		%r12, %r14			;// %ahr:%alr :=    man1L * man2L
		ld.w		%r9, %ahr			;// %r9       := HI(man1L * man2L)
		mltu.w		%r13, %r15			;// %ahr:%alr :=    man1H * man2H
		ld.w		%r10, %alr			;// %r10      := LO(man1H * man2H)
		ld.w		%r11, %ahr			;// %r11      := HI(man1H * man2H)
		mltu.w		%r12, %r15			;// %ahr:%alr :=    man1L * man2H
		ld.w		%r12, %alr			;// %r12      := LO(man1L * man2H)
		ld.w		%r15, %ahr			;// %r15      := HI(man1L * man2H)
		mltu.w		%r13, %r14			;// %ahr:%alr :=    man1H * man2L
		ld.w		%r13, %alr			;// %r13      := LO(man1H * man2L)
		ld.w		%r14, %ahr			;// %r14      := HI(man1H * man2L)
		;//
		add		%r9, %r12			;// %r9  := HI(man1L * man2L) + LO(man1L * man2H)                         -> C
		adc		%r10, %r14			;// %r10 := LO(man1H * man2H) + HI(man1H * man2L)                     + C -> C
		adc		%r11, %r8			;// %r11 := HI(man1H * man2H)                                         + C
		add		%r9, %r13			;// %r9  := HI(man1L * man2L) + LO(man1L * man2H) + LO(man1H * man2L)     -> C
		adc		%r10, %r15			;// %r10 := LO(man1H * man2H) + HI(man1H * man2L) + HI(man1L * man2H) + C -> C
		adc		%r11, %r8			;// %r11 := HI(man1H * man2H)                                         + C
		;// %r4       := exp (min = 0x002, max = 0xFFE)
		;// %r5       := sig (00000000 00000000 0000s000 00000000)
		;// %r11:%r10 := man (min = 0x40000000_00000000, max = 0xFFFFFFFF_FFFFFFFF)
		add		%r10, %r10			;// %r11:%r10 := man <<= 1, C <- man[63]
		adc		%r11, %r11
		jrult		4				;// if(!C)
		 add		%r10, %r10			;//   %r11:%r10 := man <<= 1
		 adc		%r11, %r11
		 sub		%r4, 1				;//   %r4  := exp--
		xsub		%r4, %r4, 1023-1		;// %r4  := exp -= bias - 1
		jrle		__muldf3_ret0			;// if(exp <= 0) return 0
		;// %r4       := exp (min = 0x001, max = 0xC00) (0x7FF超過時はオーバーフローだが稀なので未対応)
		;// %r5       := sig (00000000 00000000 0000s000 00000000)
		;// %r11:%r10 := man
		xsrl		%r10, 12			;// %r10 := 00000000 0000nnnn nnnnnnnn nnnnnnnn
		xrr		%r11, 12			;// %r11 := nnnnnnnn nnnnmmmm mmmmmmmm mmmmmmmm
		xor		%r10, %r11			;// %r10 := nnnnnnnn nnnn???? ???????? ????????
		xand		%r11, %r11, 0xFFFFF		;// %r11 := 00000000 0000mmmm mmmmmmmm mmmmmmmm
		xor		%r10, %r11			;// %r10 := nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn
		or		%r4, %r5			;// %r4  := 00000000 00000000 0000seee eeeeeeee
		xrr		%r4, 12				;// %r4  := seeeeeee eeee0000 00000000 00000000
		ret.d
		or		%r11, %r4			;// %r11 := seeeeeee eeeemmmm mmmmmmmm mmmmmmmm			*delay*
__muldf3_ret0:
		ld.w		%r10, 0				;// return 0
		ret.d
		ld.w		%r11, 0				;//								*delay*

;****************************************************************************
;	
;****************************************************************************

;// [in]
;//		%r13:%r12	(double) val1
;//		%r15:%r14	(double) val2
;// [out]
;//		%r11:%r10	(double) val1 / val2
;// [mod]
;//		%r4,%r5,%r12,%r13,%r14,%r15
;//
		.global		__divdf3
__divdf3:
		;// %r13:%r12 := val1
		;// %r15:%r14 := val2
		xrl		%r13, 12			;// %r13 := mmmmmmmm mmmmmmmm mmmmseee eeeeeeee
		xand		%r4, %r13, 0x7FF		;// %r4  := 00000000 00000000 00000eee eeeeeeee
		jreq		__divdf3_ret0			;// if(val1 == zero or denormal) return 0
		sub		%r13, %r4			;// %r13 := mmmmmmmm mmmmmmmm mmmms000 00000000
		xand		%r5, %r13, 0x800		;// %r5  := 00000000 00000000 0000s000 00000000 = sig1
		sub		%r13, %r5			;// %r13 := mmmmmmmm mmmmmmmm mmmm0000 00000000
		or		%r13, 1				;// %r13 := mmmmmmmm mmmmmmmm mmmm0000 00000001
		rr		%r13, 2				;// %r13 := 01mmmmmm mmmmmmmm mmmmmm00 00000000
		xrl		%r12, 10			;// %r12 := nnnnnnnn nnnnnnnn nnnnnnmm mmmmmmmm
		xor		%r13, %r12			;// %r13 := ???????? ???????? ??????mm mmmmmmmm
		xand		%r12, %r12, ~0x3FF		;// %r12 := nnnnnnnn nnnnnnnn nnnnnn00 00000000 = man1L
		xor		%r13, %r12			;// %r13 := 01mmmmmm mmmmmmmm mmmmmmmm mmmmmmmm = man1H
		;//
		xrl		%r15, 12			;// %r15 := mmmmmmmm mmmmmmmm mmmmseee eeeeeeee
		xand		%r9, %r15, 0x7FF		;// %r9  := 00000000 00000000 00000eee eeeeeeee
		jreq		__divdf3_ret0			;// if(val2 == zero or denormal) 0除算エラー (0を返すことにします)
		sub		%r15, %r9			;// %r15 := mmmmmmmm mmmmmmmm mmmms000 00000000
		sub		%r4, %r9			;// %r4  := exp1 - exp2 = exp
		xand		%r9, %r15, 0x800		;// %r9  := 00000000 00000000 0000s000 00000000 = sig2
		sub		%r15, %r9			;// %r15 := mmmmmmmm mmmmmmmm mmmm0000 00000000
		xor		%r5, %r9			;// %r5  := 00000000 00000000 0000s000 00000000 = sig1 ^ sig2 = sig
		or		%r15, 1				;// %r15 := mmmmmmmm mmmmmmmm mmmm0000 00000001
		rr		%r15, 2				;// %r15 := 01mmmmmm mmmmmmmm mmmmmm00 00000000
		xrl		%r14, 10			;// %r14 := nnnnnnnn nnnnnnnn nnnnnnmm mmmmmmmm
		xor		%r15, %r14			;// %r15 := ???????? ???????? ??????mm mmmmmmmm
		xand		%r14, %r14, ~0x3FF		;// %r14 := nnnnnnnn nnnnnnnn nnnnnn00 00000000 = man2L
		xor		%r15, %r14			;// %r15 := 01mmmmmm mmmmmmmm mmmmmmmm mmmmmmmm = man2H
		;// %r4       := exp (min = -0x7FE, max = 0x7FE)
		;// %r5       := sig (00000000 00000000 0000s000 00000000)
		;// %r13:%r12 := man1 (min = 0x40000000_00000000, max = 0x7FFFFFFF_FFFFFC00)
		;// %r15:%r14 := man2 (min = 0x40000000_00000000, max = 0x7FFFFFFF_FFFFFC00)
		;// 除算結果に暗黙の最上位ビットを含まないよう、結果の最上位ビットに相当する減算処理を行っておきます。
		sub		%r12, %r14
		sbc		%r13, %r15
		jruge		6
		 sub		%r4, 1
		 add		%r12, %r12
		 adc		%r13, %r13
		 add		%r12, %r14
		 adc		%r13, %r15
		xadd		%r4, %r4, 1023
		jrle		__divdf3_ret0
		;// %r4       := exp (min = 0x001, max = 0xBFD) (0x7FF超過時はオーバーフローだが稀なので未対応)
		;// %r5       := sig (00000000 00000000 0000s000 00000000)
		;// %r13:%r12 := man1
		;// %r15:%r14 := man2
		;// - 52ビットの結果を求めるループを、20ビットと32ビットに分けて、二回のループとした。
		;//   52ビットまとめて一回のループにすると、%r11:%r10の64ビットシフトが必要になるが、
		;//   20ビットと32ビットに分けると、各々 %r11(又は%r10)の32ビットシフトで済むため、高速化できる。
		;// - Cフラグの特性上、被序数から序数が引けたときに0、引けなかったときに1となる。
		;//   最終的に求めたい値とは0/1が逆であるが、ループ中は逆のままにしておき最後にまとめて反転する。
		;//   高速化のためである。上記の理由のため、この下では%r11を0でなく-1でクリアしていることに注意。
		add		%r12, %r12			;// <-----------------------------------+	(ループ末尾の遅延スロットを有効活用するため)
		;//--- man[51:32]を求めるループ ---		;//					|
		ld.w		%r11, -1			;// %r11 := -1				|	(シフトアウトしない部分をクリア)
		ld.w		%r9, (20-1)			;// %r9  := %r11にmanが入るビット数-1	|
__divdf3_loop1:							;// do {				|
;//		add		%r12, %r12			;// ->----------+-----------------------+	(ループ末尾の遅延スロットを有効活用するため)
		adc		%r13, %r13			;//   %r13:%r12 := man1 <<= 1		|
		sub		%r12, %r14			;//   %r13:%r12 := man1 -= man2		|
		sbc		%r13, %r15			;//					|
		jruge.d		4				;//   if(man1 < 0)			|
		 adc		%r11, %r11			;//   %r11 := man = (man << 1) | C	V	(0/1を逆のまま求めておく)			*delay*
		 add		%r12, %r14			;//     %r13:%r12 := man1 += man2	|
		 adc		%r13, %r15			;//					|
		sub		%r9, 1				;// } while(--%r9 >= 0)			|
		jrge.d		__divdf3_loop1			;//					|
		add		%r12, %r12			;// <-----------------------------------+	(ループ末尾の遅延スロットを有効活用するため)	*delay*
		not		%r11, %r11			;// %r11 := ~%r11			|	(0/1を本当の値に反転する)
		;//--- man[31: 0]を求めるループ ---		;//					|
		ld.w		%r10, -1			;// %r10 := -1				A	(全ビットシフトアウトするのでクリア不要)
		ld.w		%r9, (32-1)			;// %r9  := %r10にmanが入るビット数-1	|	(1命令で31までしか代入できないので31とし終了条件で吸収)
__divdf3_loop2:							;// do {				|
;//		add		%r12, %r12			;// ->----------------------------------+	(ループ末尾の遅延スロットを有効活用するため)
		adc		%r13, %r13			;//   %r13:%r12 := man1 <<= 1		|
		sub		%r12, %r14			;//   %r13:%r12 := man1 -= man2		|
		sbc		%r13, %r15			;//					|
		jruge.d		4				;//   if(man1 < 0)			|
		 adc		%r10, %r10			;//   %r10 := man = (man << 1) | C	V	(0/1を逆のまま求めておく)			*delay*
		 add		%r12, %r14			;//     %r13:%r12 := man1 += man2	|
		 adc		%r13, %r15			;//					|
		sub		%r9, 1				;// } while(--%r9 >= 0)			|
		jrge.d		__divdf3_loop2			;//					|
		add		%r12, %r12			;// <-----------------------------------+	(ループ末尾の遅延スロットを有効活用するため)	*delay*
		not		%r10, %r10			;// %r10 := ~%r10				(0/1を本当の値に反転する)
		;// %r4       := exp (min = 0x001, max = 0xBFD) (0x7FF超過時はオーバーフローだが稀なので未対応)
		;// %r5       := sig (00000000 00000000 0000s000 00000000)
		;// %r11:%r10 := man (00000000 0000mmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm)
		or		%r4, %r5			;// %r4  := 00000000 00000000 0000seee eeeeeeee
		xrr		%r4, 12				;// %r4  := seeeeeee eeee0000 00000000 00000000
		ret.d
		or		%r11, %r4			;// %r11 := seeeeeee eeeemmmm mmmmmmmm mmmmmmmm			*delay*
__divdf3_ret0:
		ld.w		%r10, 0				;// return 0
		ret.d
		ld.w		%r11, 0				;//								*delay*

;****************************************************************************
;	
;****************************************************************************

;//
;// [in]
;//		%r12		(int)    val
;// [out]
;//		%r11:%r10	(double) val
;// [mod]
;//		%r12
;// [note]
;//	- __floatdidf((long long)⇒(double)変換)は未対応です。
;//	- __fixdfsi,__fixunsdfsi,__fixdfdi,__fixunsdfdi は効率に大きな違いが無いので、一緒に対応しましたが、
;//	  __floatdidf((long long)⇒(double)変換)と__floatsidf((int)⇒(double)変換)は、効率がかなり違います。
;//	  使用頻度の低い__floatdidfを一緒に対応することで、使用頻度の高い__floatsidfの効率が落ちては良くないので、__floatdidfは未対応とすることにしました。
;//	  今後 (long long)⇒(double)変換が必要になった場合は、__floatsidfとは個別で__floatdidfを実装する予定です。
;//
		.global		__floatsidf
__floatsidf:
		;// %r12 := val
		cmp		%r12, 0				;// if(val <= 0)
		jrgt.d		__floatsidf_L10
		 ld.w		%r11, 0x000			;// %r11 := 00000000 00000000 0000s000 00000000, sig = 0						*delay*
		 jreq		__floatsidf_ret0		;//   if(val == 0) return 0
		 not		%r12, %r12			;//   %r12 := val = |val|
		 add		%r12, 1
		 xld.w		%r11, 0x800			;//   %r11 := 00000000 00000000 0000s000 00000000, sig = 1
__floatsidf_L10:
		xoor		%r11, %r11, 1023+31		;// %r11 := 00000000 00000000 0000seee eeeeeeee, exp = bias + 31
		 scan1		%r9, %r12
		 sll		%r12, %r9			;// %r12 := 1mmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm = man
		jrult.d		-2
		sub		%r11, %r9			;// %r11 := 00000000 00000000 0000seee eeeeeeee, exp = bias + 31 - shift count (min = 1023, max = 1054)	*delay*
		;// %r11 := 00000000 00000000 0000seee eeeeeeee
		;// %r12 := 1mmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm
		xand		%r10, %r12, 0x7FF		;// %r10 := 00000000 00000000 00000mmm mmmmmmmm
		sub		%r12, %r10			;// %r12 := 1mmmmmmm mmmmmmmm mmmmm000 00000000
		sll		%r12, 1				;// %r12 := mmmmmmmm mmmmmmmm mmmm0000 00000000
		or		%r11, %r12			;// %r11 := mmmmmmmm mmmmmmmm mmmmseee eeeeeeee
		xrr		%r11, 12			;// %r11 := seeeeeee eeeemmmm mmmmmmmm mmmmmmmm
		rr		%r10, 8				;// %r11 := mmmmmmmm 00000000 00000000 00000mmm
		ret.d
		rr		%r10, 3				;// %r11 := mmmmmmmm mmm00000 00000000 00000000								*delay*
__floatsidf_ret0:
		ret.d						;// return 0 (%r11は分岐元で既に0x000を代入済み)
		ld.w		%r10, 0				;//													*delay*

;****************************************************************************
;	
;****************************************************************************

;//
;// [in]
;//		%r13:%r12	(double)             val
;// [out]
;//		     %r10	(int)                val
;//		     %r10	(unsigned)           val
;//		%r11:%r10	(long long)          val
;//		%r11:%r10	(unsigned long long) val
;// [mod]
;//		%r11,%r14
;// [note]
;//		- (double)⇒(int)/(unsigned)変換(__fixdfsi,__fixunsdfsi)だけ対応するのも、
;//		  (double)⇒(long long)/(unsigned long long)変換(__fixdfsi,__fixunsdfsi)も一緒に対応するのも、
;//		  ほとんど効率が違わないと判断したため、両方一緒に対応することにしました。
;//		- 具体的には、(double)⇒(long long)/(unsigned long long)変換(__fixdfsi,__fixunsdfsi)の結果の、
;//		  上位値を無視すれば、(double)⇒(int)/(unsigned)変換(__fixdfsi,__fixunsdfsi)の結果になります。
;//
		.global		__fixdfsi
		.global		__fixunsdfsi
		.global		__fixdfdi
		.global		__fixunsdfdi
__fixdfsi:
__fixunsdfsi:
__fixdfdi:
__fixunsdfdi:
		;// %r13:%r12 := val
		ld.w		%r11, %r13			;// %r11 := seeeeeee eeeemmmm mmmmmmmm mmmmmmmm
		xrl		%r11, 12			;// %r11 := mmmmmmmm mmmmmmmm mmmmseee eeeeeeee
		xand		%r14, %r11, 0x7FF		;// %r14 := 00000000 00000000 00000eee eeeeeeee
		or		%r11, 1				;// %r11 := mmmmmmmm mmmmmmmm mmmmseee eeeeeee1
		rr		%r11, 1				;// %r11 := 1mmmmmmm mmmmmmmm mmmmmsee eeeeeeee
		xsrl		%r11, 11			;// %r11 := 00000000 0001mmmm mmmmmmmm mmmmmmmm
		;//
		xsub		%r14, %r14, 1023+52		;// %r14 := shift_count = exp - (bias + 52)
		jrlt.d		__fixdfdi_srl
		ld.w		%r10, %r12			;// %r10 := mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm			*delay*
;//__fixdfdi_sll:
		;{{VARSHIFT
		cmp		%r14, 31			;// while(shift_count >= 32)
		jrle		5
		 ld.w		%r11, %r10			;//   %r11:%r10 := man <<= 32
		 ld.w		%r10, 0
		 jp.d		-4
		 sub		%r14, 32			;//   %r14 := shift_count -= 32					*delay*
		ld.w		%r9, -1				;// %r9  := mask = -1
		cmp		%r14, 8				;// while(shift_count > 8)
		jrle		6
		 sll		%r9, 8				;//   %r9  := mask  <<= 8
		 rl		%r10, 8				;//   %r10 := manL <<<= 8
		 sll		%r11, 8				;//   %r11 := manH  <<= 8
		 jp.d		-5
		 sub		%r14, 8				;//   %r7  := shift_count -= 8					*delay*
		sll		%r9, %r14			;// %r9  := mask  <<= shift_count
		rl		%r10, %r14			;// %r10 := manL <<<= shift_count
		sll		%r11, %r14			;// %r11 := manH  <<= shift_count
		xor		%r11, %r10			;// %r11 := ((manH << shift_count) ^ (manL <<< shift_count))
		and		%r10, %r9			;// %r10 :=                                                    ((manL <<< shift_count) & (mask << shift_count)) -> manL
;//		xor		%r11, %r10			;// %r11 := ((manH << shift_count) ^ (manL <<< shift_count)) ^ ((manL <<< shift_count) & (mask << shift_count)) -> manH	--------+
		;}}VARSHIFT					;//																|
		jp.d		__fixdfdi_neg			;//																|
		xor		%r11, %r10			;// <---------------------------------------------------------------------------------------------------------------------------+	*delay*
__fixdfdi_srl:
		not		%r14, %r14			;// %r11 := shift_count = |shift_count|
		add		%r14, 1
		;{{VARSHIFT
		cmp		%r14, 31			;// while(shift_count >= 32)
		jrle		5
		 ld.w		%r10, %r11			;//   %r11:%r10 := man >>= 32
		 ld.w		%r11, 0
		 jp.d		-4
		 sub		%r14, 32			;//   %r14 := shift_count -= 32					*delay*
		ld.w		%r9, -1				;// %r9  := mask = -1
		cmp		%r14, 8				;// while(shift_count > 8)
		jrle		6
		 srl		%r9, 8				;//   %r9  := mask  >>= 8
		 srl		%r10, 8				;//   %r10 := manL  >>= 8
		 rr		%r11, 8				;//   %r11 := manH >>>= 8
		 jp.d		-5
		 sub		%r14, 8				;//   %r7  := shift_count -= 8					*delay*
		srl		%r9, %r14			;// %r9  := mask  >>= shift_count
		srl		%r10, %r14			;// %r10 := manL  >>= shift_count
		rr		%r11, %r14			;// %r11 := manH >>>= shift_count
		xor		%r10, %r11			;// %r10 := ((manH >>> shift_count) ^ (manL >> shift_count))
		and		%r11, %r9			;// %r11 :=                                                    ((manH >>> shift_count) & (mask >> shift_count)) -> manH
		xor		%r10, %r11			;// %r10 := ((manH >>> shift_count) ^ (manL >> shift_count)) ^ ((manH >>> shift_count) & (mask >> shift_count)) -> manL
		;}}VARSHIFT
__fixdfdi_neg:
		cmp		%r13, 0				;// if(val < 0) {
		jrge		5
		 not		%r10, %r10			;//   man = -man
		 not		%r11, %r11
		 add		%r10, 1
		 adc		%r11, %r8
		ret						;// }

;****************************************************************************
;	
;****************************************************************************
