added fmov chapter

This commit is contained in:
Perry Kivolowitz 2023-01-23 17:58:56 -06:00
parent 39f5f600cd
commit 8859d306fe
2 changed files with 85 additions and 97 deletions

74
section_2/float/fmov.md Normal file
View file

@ -0,0 +1,74 @@
# `fmov`
The `fmov` instruction is used to move floating point values in and out
of floating point registers and to some degree, moving data between
integer and floating point registers.
## Loading Floating Point Numbers as Immediate Values
Just as we saw with integer
registers, some values can be used as immediate values and some cannot.
For example, this works:
`mov x0, 65536`
but this does not:
`mov x0, 65537`
The reason is that all AARCH64 instructions must fit within a 32 bit
instruction that must hold the instruction's op code, its flags and
other bits and bobs plus any immediate value. In the above example we
can see that the `mov` instruction provides up to 16 bits for an
immediate value.
The constraints placed on immediate values for `fmov` are much tighter
because floating point numbers are far more complex than integers.
Make sure you have read and understand [this chapter](./what.md) before
proceeding.
Let's take a look at some code:
```text
fmov d0, 1.0 // works
fmov d0, 1.5 // works 2**-1
fmov d0, 1.75 // works 2**-1 + 2**-2
fmov d0, 1.875 // works 2**-1 + 2**-2 + 2**-3
fmov d0, 1.9375 // works the preceding + 2**-4
fmov d0, 1.96875 // Zoinks!
```
From this we can see that an immediate value for an `fmov` seems to have
4 bits available for the mantissa. In fact, the only values that work
as immediate values will be those floating point values whose fractional
values are combinations of:
* 1/2
* 1/4
* 1/8 and
* 1/16
As far as exponents go, `fmov` can accommodate 3 bits. So, exponents of
plus or minus 2**7 can be used.
## Loading / Storing Floating Point Numbers in General
When in doubt, load fixed floating point numbers from memory. This is
covered [in this chapter](./literals.md).
## SIMD
`fmov` can also deal with the more complicated special cases induced by
SIMD instruction.
## Movement To / From Integer Registers
`fmov` can *bits* between the integer and floating point registers. We
emphasize the *bits*. No conversions are done using `fmov`. There exist
other instructions for that. See [this chapter](./rounding.md) for more
information.

View file

@ -1,99 +1,13 @@
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 13, 0 sdk_version 13, 1
.globl _main ; -- Begin function main
.text
.p2align 2
_main: ; @main
.cfi_startproc
; %bb.0:
sub sp, sp, #80
stp x22, x21, [sp, #32] ; 16-byte Folded Spill
stp x20, x19, [sp, #48] ; 16-byte Folded Spill
stp x29, x30, [sp, #64] ; 16-byte Folded Spill
add x29, sp, #64
.cfi_def_cfa w29, 16
.cfi_offset w30, -8
.cfi_offset w29, -16
.cfi_offset w19, -24
.cfi_offset w20, -32
.cfi_offset w21, -40
.cfi_offset w22, -48
Lloh0:
adrp x20, _d@PAGE
Lloh1:
add x20, x20, _d@PAGEOFF
ldr d0, [x20]
Lloh2:
adrp x21, _f@PAGE
Lloh3:
add x21, x21, _f@PAGEOFF
ldr s1, [x21]
fcvt d1, s1
str d1, [sp, #16]
str d0, [sp, #8]
str xzr, [sp]
Lloh4:
adrp x19, l_.str@PAGE
Lloh5:
add x19, x19, l_.str@PAGEOFF
mov x0, x19
bl _printf
ldr d0, [x20, #8]
ldr s1, [x21, #4]
fcvt d1, s1
str d1, [sp, #16]
str d0, [sp, #8]
mov w8, #1
str x8, [sp]
mov x0, x19
bl _printf
ldr d0, [x20, #16]
ldr s1, [x21, #8]
fcvt d1, s1
str d1, [sp, #16]
str d0, [sp, #8]
mov w8, #2
str x8, [sp]
mov x0, x19
bl _printf
ldr d0, [x20, #24]
ldr s1, [x21, #12]
fcvt d1, s1
str d1, [sp, #16]
str d0, [sp, #8]
mov w8, #3
str x8, [sp]
mov x0, x19
bl _printf
mov w0, #0
ldp x29, x30, [sp, #64] ; 16-byte Folded Reload
ldp x20, x19, [sp, #48] ; 16-byte Folded Reload
ldp x22, x21, [sp, #32] ; 16-byte Folded Reload
add sp, sp, #80
.global test
test: fmov d0, 1.0
fmov d0, 1.5
fmov d0, 1.75
fmov d0, 1.875
fmov d0, 1.9375
fmov d0, 1.96875
ret
.loh AdrpAdd Lloh4, Lloh5
.loh AdrpAdd Lloh2, Lloh3
.loh AdrpAdd Lloh0, Lloh1
.cfi_endproc
; -- End function
.section __DATA,__data
.globl _d ; @d
.p2align 3
_d:
.quad 0x3ff8e38da3c21188 ; double 1.555555
.quad 0x40055554fbdad752 ; double 2.6666660000000002
.quad 0x400e38e325d4a5df ; double 3.7777769999999999
.quad 0x40138e38a7e73a36 ; double 4.8888879999999997
.globl _f ; @f
.p2align 2
_f:
.long 0x3f8e38e3 ; float 1.11111104
.long 0x400e38e3 ; float 2.22222209
.long 0x40555554 ; float 3.33333302
.long 0x408e38e3 ; float 4.44444418
.section __TEXT,__cstring,cstring_literals
l_.str: ; @.str
.asciz "index %ld double %f float %f\n"
.subsections_via_symbols
.end