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
.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
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
.text
.p2align 2
.global test
.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
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
.section __TEXT,__cstring,cstring_literals
l_.str: ; @.str
.asciz "index %ld double %f float %f\n"
.subsections_via_symbols
.end