2024ǯ07��05��
SoftFloat��̤���ư��Х���2��RISC-V��RV64I�Ǥ�unsigned��32bit¨�ͤǤ�64bit�쥸�����ξ��32bit��0�Ȥϸ¤�ʤ�
����ε����Ǥϴο��ʤ��Ȥ��˺�줿�ΤǤ�����libc �Ρ�fp ���եȥ��������ߥ�졼�����פȤϡ��Ĥޤ� libc �ǥ���ѥ����󥿥���饤�֥���GCC �� libgcc �� LLVM �� compiler-rt�ˤδؿ���������Ƥ���Ȥ������ȤǤ���FPU ��̵���������åȤǤϡ�����ѥ���� fp ̿�������ˤ��δؿ���ƤӽФ��ޤ���
�ʤ���������ݤʤ��Ȥ򤷤Ƥ��뤫�Ȥ����ȡ�libgcc �� compiler-rt �� fenv.h ���θ��������� FE_TONEAREST �� fp �黻��Ԥ�������Ȼפ��ޤ�������Ū�ˤ� FPU ��̵�� CPU �Ǵݤ������ι�θ��ɬ�פˤʤ�褦�ʥץ�������¹Ԥ��륱�����ϵ����Ȼפ��ޤ�����NetBSD �ˤϤ�����꤬����ΤǤ��礦�������Ҥ�Ǥ���¤����ƤΥ��ݡ��ȥ������åȤ�ɸ��˽�򤷤�ư���Ԥ�����ѥ���ġ�������������ʤ��ܻؤ��Ƥ��ޤ�����
���٤Ϥ���ߤĤ֤�����Ǥ���libc �� compiler-rt �δؿ���������Ƥ���Ȥ������Ȥϡ�compiler-rt ¦�μ������٤��Ƥ���Ȥ������ȤǤ������ҤǤ� objcopy �� --redefine-syms ���ץ�������Ѥ��ƥ���ܥ���͡��ह�뤳�ȤǤ����¸����Ƥ��ޤ���
������ž�����ơ��ޤ��� libc ¦�μ����������٤��ơ�compiler-rt �δؿ���Ȥ��褦�˥ġ����������������ޤ����������Ƥ��ξ��֤Ǿ��ѥƥ��ȥ������Ȥ� pass ���뤳�Ȥ��ǧ���ޤ�����
���θ����ƻ����ʬõ���Ǵؿ���ʤ����Ǥ������ǽ�Ū�� __gtsf2 �����ȿͤǤ��뤳�Ȥ��狼��ޤ����������� __gtsf2 �μ��������Τ� SoftFloat �� float32_lt �Ǥ������ʤ�ʤ����ޤ�����
�����ޤ��褿�� __gtsf2 �� printf ��Ź��ߡ�pass ������� fail ������ΰ���������ͤΥ������ä���Ӥ��ޤ��������� __gtsf2(0xc0000000, 0x00000000) �λ�������� -1 ���֤�Ϥ��ʤΤ� 1 ���֤äƤ��뤳�Ȥ��狼��ޤ�����
�����ޤ��褿�顢��ϴ�Ϣ����ؿ��������ڤ�Ф���ñ�Υƥ��Ȥ��äƤ��ä���ȸ��ƹԤ����ɤ������Ǥ���a �� b �ϰۤʤ�Τǡ�float32_eq ��̵�뤷�ơ�float32_lt �˹ʤ��ޤ���
#include <stdio.h>
/* ��ά */
flag __gesf2(float32 a, float32 b)
{
if (float32_eq(a, b)) return 0;
return float32_lt(b, a) ? 1 : -1;
}
flag __gtsf2(float32 a, float32 b)
{
return __gesf2(a, b);
}
int main() {
fprintf(stderr, "__gtsf2(0xc0000000, 0x00000000) = %d\n", __gtsf2(0xc0000000U, 0x00000000U));
return 0;
}
���������ʤ�ȺƸ����ޤ���Ǥ������Ƹ����뤳�Ȥ���ǧ�ѤߤΥ���ѥ���Ѥ� softfloat.o ���󥯤��Ƥ�Ʊ��������ˤϤ��ʤ���Ǥ��ޤ��������θ��ݤ����򤹤뤿��ˤϡ�CPU �Υ쥸������ľ�ܴ�¬�Ǥ���ǥХå����ɤ�ɬ�פ�����ޤ���������ͽ�۳��θ������ä��Τǡ������ɥ꡼�ǥ��󥰤� printf �ǥХå������Dz�褹��Τ�̵�����ä��Ȼפ��ޤ���
SoftFloat �Τ�Ȥ�ȤΥХ��ʥ�⡢ñ�Υƥ��Ȥ⡢�������줿������֥饳���ɤ�����Ʊ���Ǥ������ʲ�������� float32_lt �μ����Ǥ���
flag float32_lt( float32 a, float32 b )
{
flag aSign, bSign;
if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
|| ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
) {
float_raise( float_flag_invalid );
return 0;
}
aSign = extractFloat32Sign( a );
bSign = extractFloat32Sign( b );
if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
return ( a != b ) && ( aSign ^ ( a < b ) );
}
������Ⱦ��ʬ�� NaN �����å��ǡ������ a �� b �� NaN �Ǥ�̵���Τ�̵�뤷���ɤ��Ǥ�������ȡ��������Ƥ�ܤ��Ƥ⡢�ʲ������ˤʤ�ޤ���
INLINE flag extractFloat32Sign( float32 a )
{
return a>>31;
}
flag float32_lt( float32 a, float32 b )
{
flag aSign, bSign;
aSign = extractFloat32Sign( a );
bSign = extractFloat32Sign( b );
if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
return ( a != b ) && ( aSign ^ ( a < b ) );
}
������ 0xc0000000 �� -2 �ʤΤ� a �� b �����ϰۤʤ뤿�ᡢ�ǽ�Ū�ˤϰʲ��� 1 �Ԥ�������ư�����ɤ����Ȥˤʤ�ޤ�����̣�����Ρ���椬�ۤʤꡢ�ؿ����Ȳ��������󥼥��ʤ�С�a ����ξ�� a < b �Ͽ������ξ��ϵ��Ȥʤ�ޤ�������˺���� a ���󥼥��ʤΤǡ�������Ӥ������������ư���Ϥ��Ĥ����ޤǤ����ư���ʤ������Ի׵Ĥ˻פ��Ƥ��ޤ���
if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
�ºݤˤ��� C �����ɤ���Ф륢����֥饳���ɤϰʲ��Τ褦�ˤʤ�ޤ����ʥǥХå��β��̤Υ��ԥڤǤ����ˤ��ʤ��Ŭ�����줿�����ɤʤΤǤ狼��ˤ����Ǥ�����������Ӥ�Ԥ��ݤˤ虜�虜���եȤʤ�Ƥ��Ƥޤ���a��a0 �쥸�����ˤ� b��a1 �쥸�����ˤ� xor ���ä���椬 1 �ʤ��aSign == bSign �ʤΤǡ˼��˹Ԥ��Ȥ��������ɤˤʤäƤ��ޤ������졢����ѥ��餬 unsigned �Ǥ� 32 bit �ͤ� 31 bit �ܤ���Ӥ� bltz��if a2 < 0 branch 0x1c�ˤ�Ȥä����Ƚ����֤���������Ȥ����μ�����äƤ�äƤ��Ȥʤ�Ǥ����͡�ͽ�۳��Υ����ɤ��ä��ΤǶä��ޤ�����
softfloat.c:2161: if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); 0000000080005CD8 00A5C633 xor a2, a1, a0 0000000080005CDC 00064E63 bltz a2, 0x1c softfloat.c:2162: return ( a != b ) && ( aSign ^ ( a < b ) ); 0000000080005CE0 00C03633 snez a2, a2 0000000080005CE4 00B535B3 sltu a1, a0, a1 0000000080005CE8 00052513 slti a0, a0, 0 0000000080005CEC 00B54533 xor a0, a0, a1 0000000080005CF0 00A67533 and a0, a2, a0 softfloat.c:2164:} 0000000080005CF4 00008067 ret���ơ�������֥ꥳ���ɤ򸫤Ƥ����������Ǥ����������ºݤ˥ǥХå���ư������ư���ʤ����򸫤Ƥߤ�ȡ�
fail a0(x10) 0000000000000000 a1(x11) 00000000C0000000 pass a0(x10) 0000000000000000 a1(x11) FFFFFFFFC0000000����ǽ����̣���狼��ʤ��ä��ΤǤ�����Ĵ�٤Ƥߤ�� RISC-V �� 32 bit ¨�ͤϡ��ʲ��Τ褦�ˤ��� lui ̿��ǥ����ɤ���
00000000800003A8 C0000537 lui a0, 0xc0000����ĥ���줿ɽ���� 64 bit �쥸�����ǰ�����Τ����������ͤ������Ǥ����ǽ�ǥХå������ߥ�졼�����Х��äƤ�Τ��Ȼפ��ޤ����������� bltz �����Ƥ������ bit �� bit 31 �ǤϤʤ� bit 63 �ʤΤǡ�����ĥ����Ƥ��ʤ�����������ư���ʤ��Ȥ������ȤǤ�����
�ʻ��͡�https://lpha-z.hatenablog.com/entry/2020/01/12/231500 ��
�Ĥޤꡢ����ѥ���ΥХ����饤�֥��ΥХ����������Ǥ������ʤ�������ĥ����ʤ����֤� 32 bit ¨�ͤ��ϤäƤ���ѥ�����ȯ�����Ƥ��ơ�����ĥ 64 bit ɽ��������κ�Ŭ�������ɤ�������ư���ʤ��Ȥ����Τ�����Ǥ�����
�ɤ�������Τ�Ǻ�ߤޤ��������ǽ�Ū�ˡ�����Ū�ʲ�����ۤ˵��Ҥ��ơ���� bit ������ 0 �� 1 ���֤��ؿ��פȤ�����̣�����Τʡ��ʲ��Τ褦�ʷ��˽������ޤ�����
INLINE flag extractFloat32Sign( float32 a )
{
volatile uint32_t u = a & 0xffffffff;
return u>>31;
}
������̤���ư��Х��פȸƤ֤Τ�Ŭ�ڤʤΤ��ϼ���������ޤ��󤬡������餯�ץ�����ޤˤ� ��uint32_t �� 31 �ӥåȱ����եȤ�����硢bit 0 �ʳ������� 0 �ˤʤꡢ0x0 �� 0x1 �Τɤ��餫��ɬ���ʤ�פȤ������ۤβ��꤬���ä��ΤǤϤʤ����Ȼפ�졢�����Ȥϸ¤�ʤ��Ȥ�����̣��̤���ư��Х��Ȥ��ޤ�������C ������ͤΡ�̤���ư��פȤϤ����餯�ۤʤ�ޤ���������Υ����ȥ��·���뤳�Ȥ�ͥ�褷�ޤ�������