요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=============
Current State
=============
The following describes the current state of the NetWinder's floating point
emulator.
In the following nomenclature is used to describe the floating point
instructions. It follows the conventions in the ARM manual.
::
<S|D|E> = <single|double|extended>, no default
{P|M|Z} = {round to +infinity,round to -infinity,round to zero},
default = round to nearest
Note: items enclosed in {} are optional.
Floating Point Coprocessor Data Transfer Instructions (CPDT)
------------------------------------------------------------
LDF/STF - load and store floating
<LDF|STF>{cond}<S|D|E> Fd, Rn
<LDF|STF>{cond}<S|D|E> Fd, [Rn, #<expression>]{!}
<LDF|STF>{cond}<S|D|E> Fd, [Rn], #<expression>
These instructions are fully implemented.
LFM/SFM - load and store multiple floating
Form 1 syntax:
<LFM|SFM>{cond}<S|D|E> Fd, <count>, [Rn]
<LFM|SFM>{cond}<S|D|E> Fd, <count>, [Rn, #<expression>]{!}
<LFM|SFM>{cond}<S|D|E> Fd, <count>, [Rn], #<expression>
Form 2 syntax:
<LFM|SFM>{cond}<FD,EA> Fd, <count>, [Rn]{!}
These instructions are fully implemented. They store/load three words
for each floating point register into the memory location given in the
instruction. The format in memory is unlikely to be compatible with
other implementations, in particular the actual hardware. Specific
mention of this is made in the ARM manuals.
Floating Point Coprocessor Register Transfer Instructions (CPRT)
----------------------------------------------------------------
Conversions, read/write status/control register instructions
FLT{cond}<S,D,E>{P,M,Z} Fn, Rd Convert integer to floating point
FIX{cond}{P,M,Z} Rd, Fn Convert floating point to integer
WFS{cond} Rd Write floating point status register
RFS{cond} Rd Read floating point status register
WFC{cond} Rd Write floating point control register
RFC{cond} Rd Read floating point control register
FLT/FIX are fully implemented.
RFS/WFS are fully implemented.
RFC/WFC are fully implemented. RFC/WFC are supervisor only instructions, and
presently check the CPU mode, and do an invalid instruction trap if not called
from supervisor mode.
Compare instructions
CMF{cond} Fn, Fm Compare floating
CMFE{cond} Fn, Fm Compare floating with exception
CNF{cond} Fn, Fm Compare negated floating
CNFE{cond} Fn, Fm Compare negated floating with exception
These are fully implemented.
Floating Point Coprocessor Data Instructions (CPDT)
---------------------------------------------------
Dyadic operations:
ADF{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - add
SUF{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - subtract
RSF{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - reverse subtract
MUF{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - multiply
DVF{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - divide
RDV{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - reverse divide
These are fully implemented.
FML{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - fast multiply
FDV{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - fast divide
FRD{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - fast reverse divide
These are fully implemented as well. They use the same algorithm as the
non-fast versions. Hence, in this implementation their performance is
equivalent to the MUF/DVF/RDV instructions. This is acceptable according
to the ARM manual. The manual notes these are defined only for single
operands, on the actual FPA11 hardware they do not work for double or
extended precision operands. The emulator currently does not check
the requested permissions conditions, and performs the requested operation.
RMF{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - IEEE remainder
This is fully implemented.
Monadic operations:
MVF{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - move
MNF{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - move negated
These are fully implemented.
ABS{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - absolute value
SQT{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - square root
RND{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - round
These are fully implemented.
URD{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - unnormalized round
NRM{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - normalize
These are implemented. URD is implemented using the same code as the RND
instruction. Since URD cannot return a unnormalized number, NRM becomes
a NOP.
Library calls:
POW{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - power
RPW{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - reverse power
POL{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - polar angle (arctan2)
LOG{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - logarithm to base 10
LGN{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - logarithm to base e
EXP{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - exponent
SIN{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - sine
COS{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - cosine
TAN{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - tangent
ASN{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - arcsine
ACS{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - arccosine
ATN{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - arctangent
These are not implemented. They are not currently issued by the compiler,
and are handled by routines in libc. These are not implemented by the FPA11
hardware, but are handled by the floating point support code. They should
be implemented in future versions.
Signalling:
Signals are implemented. However current ELF kernels produced by Rebel.com
have a bug in them that prevents the module from generating a SIGFPE. This
is caused by a failure to alias fp_current to the kernel variable
current_set[0] correctly.
The kernel provided with this distribution (vmlinux-nwfpe-0.93) contains
a fix for this problem and also incorporates the current version of the
emulator directly. It is possible to run with no floating point module
loaded with this kernel. It is provided as a demonstration of the
technology and for those who want to do floating point work that depends
on signals. It is not strictly necessary to use the module.
A module (either the one provided by Russell King, or the one in this
distribution) can be loaded to replace the functionality of the emulator
built into the kernel.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Current State
1-18NetWinder floating-point emulator의 현재 구현 상태를 설명합니다. instruction 표기법은 ARM manual convention을 따릅니다.
<S|D|E> = <single|double|extended>, no default
{P|M|Z} = {round to +infinity,round to -infinity,round to zero},
default = round to nearest
`S`, `D`, `E`는 각각 single, double, extended precision이며 기본값이 없습니다. optional `P`, `M`, `Z`는 각각 +infinity, -infinity, zero 방향 rounding이고 지정하지 않으면 nearest로 round합니다. 중괄호 `{}` 안 항목은 선택 사항입니다.
Floating Point Coprocessor Data Transfer Instructions
19-45`LDF`/`STF`는 floating-point 값을 load/store합니다.
<LDF|STF>{cond}<S|D|E> Fd, Rn
<LDF|STF>{cond}<S|D|E> Fd, [Rn, #<expression>]{!}
<LDF|STF>{cond}<S|D|E> Fd, [Rn], #<expression>
세 syntax 모두 완전히 구현되어 있습니다.
`LFM`/`SFM`은 여러 floating-point register를 load/store합니다.
<LFM|SFM>{cond}<S|D|E> Fd, <count>, [Rn]
<LFM|SFM>{cond}<S|D|E> Fd, <count>, [Rn, #<expression>]{!}
<LFM|SFM>{cond}<S|D|E> Fd, <count>, [Rn], #<expression>
두 번째 syntax form은 다음과 같습니다.
<LFM|SFM>{cond}<FD,EA> Fd, <count>, [Rn]{!}
`LFM`/`SFM`도 완전히 구현되어 있습니다. instruction이 지정한 memory location에 floating-point register 하나당 word 세 개를 store/load합니다. 이 memory format은 다른 구현, 특히 실제 hardware와 호환되지 않을 가능성이 크며 ARM manual도 이를 명시합니다.
Floating Point Coprocessor Register Transfer Instructions
46-74conversion과 status/control register read/write instruction은 다음과 같습니다.
FLT{cond}<S,D,E>{P,M,Z} Fn, Rd Convert integer to floating point
FIX{cond}{P,M,Z} Rd, Fn Convert floating point to integer
WFS{cond} Rd Write floating point status register
RFS{cond} Rd Read floating point status register
WFC{cond} Rd Write floating point control register
RFC{cond} Rd Read floating point control register
| instruction group | 구현 상태·제약 |
|---|---|
| `FLT` / `FIX` | 완전 구현 |
| `RFS` / `WFS` | 완전 구현 |
| `RFC` / `WFC` | 완전 구현. supervisor-only이며 CPU mode를 검사해 supervisor mode가 아니면 invalid-instruction trap 발생 |
floating-point compare instruction은 다음과 같습니다.
CMF{cond} Fn, Fm Compare floating
CMFE{cond} Fn, Fm Compare floating with exception
CNF{cond} Fn, Fm Compare negated floating
CNFE{cond} Fn, Fm Compare negated floating with exception
`CMF`, `CMFE`, `CNF`, `CNFE`는 모두 완전히 구현되어 있습니다.
Floating Point Coprocessor Data Instructions: dyadic
75-104두 operand를 사용하는 기본 산술 operation은 다음과 같습니다.
ADF{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - add
SUF{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - subtract
RSF{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - reverse subtract
MUF{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - multiply
DVF{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - divide
RDV{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - reverse divide
add, subtract, reverse subtract, multiply, divide, reverse divide가 모두 완전 구현되었습니다.
fast variant syntax는 다음과 같습니다.
FML{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - fast multiply
FDV{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - fast divide
FRD{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - fast reverse divide
`FML`, `FDV`, `FRD`도 완전히 구현되지만 non-fast version과 같은 algorithm을 쓰므로 이 구현에서 성능은 `MUF`/`DVF`/`RDV`와 같습니다. ARM manual은 이를 허용합니다. 실제 FPA11 hardware에서 fast instruction은 single operand만 정의되고 double·extended operand에는 동작하지 않지만, emulator는 현재 요청 precision 조건을 검사하지 않고 operation을 수행합니다.
IEEE remainder instruction은 다음과 같습니다.
RMF{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - IEEE remainder
`RMF`는 완전히 구현되어 있습니다.
Monadic operations
105-124move와 negated move는 다음과 같으며 모두 완전히 구현되어 있습니다.
MVF{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - move
MNF{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - move negated
absolute value, square root, round도 완전히 구현되어 있습니다.
ABS{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - absolute value
SQT{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - square root
RND{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - round
unnormalized round와 normalize instruction은 다음과 같습니다.
URD{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - unnormalized round
NRM{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - normalize
`URD`는 `RND`와 같은 code로 구현됩니다. `URD`가 unnormalized number를 반환할 수 없으므로 `NRM`은 NOP가 됩니다.
Library calls
125-145power, logarithm, trigonometric library-call instruction은 다음과 같습니다.
POW{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - power
RPW{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - reverse power
POL{cond}<S|D|E>{P,M,Z} Fd, Fn, <Fm,#value> - polar angle (arctan2)
LOG{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - logarithm to base 10
LGN{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - logarithm to base e
EXP{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - exponent
SIN{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - sine
COS{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - cosine
TAN{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - tangent
ASN{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - arcsine
ACS{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - arccosine
ATN{cond}<S|D|E>{P,M,Z} Fd, <Fm,#value> - arctangent
이 instruction들은 구현되어 있지 않습니다. 현재 compiler가 emit하지 않고 libc routine이 처리합니다. FPA11 hardware에도 구현되지 않았으며 floating-point support code가 맡습니다. 향후 version에서 구현할 대상으로 기록되어 있습니다.
Signalling
146-162signal 처리는 구현되어 있습니다. 다만 당시 Rebel.com이 만든 ELF kernel에는 `fp_current`를 kernel variable `current_set[0]`에 올바르게 alias하지 못해 module이 `SIGFPE`를 만들지 못하는 bug가 있습니다.
배포 kernel `vmlinux-nwfpe-0.93`은 이 문제를 고치고 현재 emulator를 kernel에 직접 포함합니다. 이 kernel은 floating-point module 없이도 실행할 수 있으며 signal에 의존하는 floating-point 작업을 위한 demonstration입니다. module 사용이 반드시 필요한 것은 아닙니다.
Russell King이 제공한 module이나 이 배포본의 module을 load하면 kernel에 내장된 emulator 기능을 대체할 수 있습니다.
요약과 해설
netwinder-fpe.rst:1-162emulator는 compiler가 실제로 emit하는 load/store, conversion, compare, 기본 산술 instruction을 우선 완성했습니다. transcendental library-call instruction은 compiler가 내지 않고 libc가 처리하므로 미구현으로 남았습니다.
register transfer와 기본 arithmetic은 emulator가 직접 처리하고 transcendental operation은 software library 경로에 남습니다.
문서에 기록된 instruction group별 상태입니다.