src/gnu/dist/gcc4/gcc/config/sh/lib1funcs.asm:__set_fpscr()
読み難かったので #ifdef やらを取り除いてみた。
/* * FPSCR_PR: 精度モード: 0=単精度モード, 1=倍精度モード * FPSCR_SZ: fmov の転送サイズモード: 0=32bit, 1=32bit ペア(64bit) */ .global __set_fpscr __set_fpscr: lds r4, fpscr /* fpscr = r4(arg0) */ mov.l 1f, r1 /* r1 = &__fpscr_values */ swap.w r4, r0 /* fpscr の上下 16bit の値を入れ替える */ or #24, r0 /* 24=0x18 -> 0x80000=FPSCR_PR, 0x100000=FPSCR_SZ */ /* ---> fpscr |= (FPSCR_PR | FPSCR_SZ) */ xor #16, r0 /* 16=0x10 -> 0x100000=FPSCR_SZ */ /* fpscr ^= FPSCR_SZ -> fpscr &= ~FPSCR_SZ */ swap.w r0, r3 mov.l r3, @(4, r1) /* @(4, r1): __fpscr_vaues[1] = fpscr */ xor #8, r0 /* fpscr &= ~FPSCR_PR */ swap.w r0, r2 rts mov.l r2, @r1 /* @r1: __fpscr_vaues[0] = fpscr */ .align 2 1: .long __fpscr_values
で、C 言語で書き直してみた。
void __set_fpscr(int fpscr) { __asm volatile ("lds %0, fpscr" :: "r"(fpscr)); __fpscr_values[0] = fpscr & ~(FPSCR_PR | FPSCR_SZ); /* float */ __fpscr_values[1] = (fpscr | FPSCR_PR) & ~FPSCR_SZ; /* double */ }
ふむ、__fpscr_values[0] には単精度用、__fpscr_values[1] には倍精度用の fpscr が設定されるのか。
で、これは何のために使われるんだ?