# Linux Kernel Module Cheat

### 29.11. x86 x87 FPU instructions

Intel 64 and IA-32 Architectures Software Developer’s Manuals Volume 1 5.2 "X87 FPU INSTRUCTIONS"

Old floating point unit that you should likely not use anymore, prefer instead the newer x86 SIMD instructions.

- FPU basic examples, start here

  - userland/arch/x86_64/fadd.S FADD. The x76 FPU works on a stack of floating point numbers.

  - userland/arch/x86_64/faddp.S FADDP. Instructions with the P suffix also Pop the stack. This is often what you want for most computations, where the intermediate results don’t matter.

  - userland/arch/x86_64/fldl_literal.S FLDL literal. It does not seem possible to either https://stackoverflow.com/questions/6514537/how-do-i-specify-immediate-floating-point-numbers-with-inline-assembly

    - load floating point immediates into x86 x87 FPU registers

    - encode floating point literals in x86 instructions, including MOV

- Bulk instructions

  - userland/arch/x86_64/fabs.S FABS: absolute value: `ST0 = |ST0|`

  - userland/arch/x86_64/fchs.S FCHS: change sign: `ST0 = -ST0`

  - userland/arch/x86_64/fild.S FILD: Integer Load. Convert integer to float.

  - userland/arch/x86_64/fld1.S FLD1: Push 1.0 to ST0. CISC!

  - userland/arch/x86_64/fldz.S FLDZ: Push 0.0 to ST0.

  - userland/arch/x86_64/fscale.S FSCALE: `ST0 = ST0 * 2 ^ RoundTowardZero(ST1)`

  - userland/arch/x86_64/fsqrt.S FSQRT: square root

  - userland/arch/x86_64/fxch.S FXCH: swap ST0 and another register

The ST0-ST7 x87 FPU registers are actually 80-bits wide, this can be seen from GDB with:

    i r st0 st1

By counting the number of hex digits, we have 20 digits instead of 16!

Instructions such as FLDL convert standard IEEE 754 64-bit values from memory into this custom 80-bit format.

- https://stackoverflow.com/questions/3206101/extended-80-bit-double-floating-point-in-x87-not-sse2-we-dont-miss-it

- https://en.wikipedia.org/wiki/Extended_precision#x86_extended_precision_format

- x86 x87 FPU vs SIMD