mirror of
https://github.com/pkivolowitz/asm_book.git
synced 2026-06-22 23:46:52 +08:00
added fmov chapter
This commit is contained in:
parent
39f5f600cd
commit
8859d306fe
2 changed files with 85 additions and 97 deletions
74
section_2/float/fmov.md
Normal file
74
section_2/float/fmov.md
Normal 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.
|
||||||
|
|
@ -1,99 +1,13 @@
|
||||||
.section __TEXT,__text,regular,pure_instructions
|
.text
|
||||||
.build_version macos, 13, 0 sdk_version 13, 1
|
.p2align 2
|
||||||
.globl _main ; -- Begin function main
|
.global test
|
||||||
.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
|
|
||||||
|
|
||||||
.globl _f ; @f
|
test: fmov d0, 1.0
|
||||||
.p2align 2
|
fmov d0, 1.5
|
||||||
_f:
|
fmov d0, 1.75
|
||||||
.long 0x3f8e38e3 ; float 1.11111104
|
fmov d0, 1.875
|
||||||
.long 0x400e38e3 ; float 2.22222209
|
fmov d0, 1.9375
|
||||||
.long 0x40555554 ; float 3.33333302
|
fmov d0, 1.96875
|
||||||
.long 0x408e38e3 ; float 4.44444418
|
ret
|
||||||
|
|
||||||
.section __TEXT,__cstring,cstring_literals
|
.end
|
||||||
l_.str: ; @.str
|
|
||||||
.asciz "index %ld double %f float %f\n"
|
|
||||||
|
|
||||||
.subsections_via_symbols
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue