0% found this document useful (0 votes)
12 views25 pages

12 - Floating Point Instructions

Uploaded by

ranbir singh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views25 pages

12 - Floating Point Instructions

Uploaded by

ranbir singh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

Floating-Point Instructions

1
Readings and Exercises
• ARMv8 Instruction Set Overview:
▪ Section 5.7
• ARM Procedure Call Standard
▪ Section 5.1.2

2
Objective
At the end of this section, you will
1. Work with single-precision and double-precision
ARM instructions

3
Floating-Point Numbers

REGISTERS AND INSTRUCTIONS

4
Floating-Point Numbers
• Are real numbers
▪ 16.889, 1.11e-13, -0.001

• Require different set of registers


• Require more specialized instructions

5
Floating-Point Registers
• ARMv8 has 32 128-bit FP registers
▪ S registers use the low-order 32 bits to hold single-
precision FP numbers
• s0 - s31
▪ D registers use the low-order 64 bits to hold double-
precision FP numbers
• d0 - d31
▪ The high-order 64 bits are only used when using
SIMD instructions
• Not covered in this course
6
Floating-Point Registers (cont’d)
• These registers are loaded or stored like the
general-purpose registers
▪ Eg: ldr s0, [base_r, offset_r] // read 4 bytes

▪ Eg: str d1, [x29, 16] // write 8 bytes

• Use the .single or .double pseudo-ops to


allocate and initialize memory for a FP number
▪ Use the prefix 0r to specify a “real” value
▪ Can specify exponents using E notation

7
Floating-Point Registers (cont’d)
▪ Eg:
.data
a_m: .single 0r5.0
b_m: .double 0r5.33e-18
array_m: .single 0r2.5, 0r3.5, 0r4.5

• In gdb:
▪ Use p/f to print the contents of a FP register
• Eg: p/f $d0
• Eg: p/f $s30

8
Floating-Point Registers (cont’d)
▪ Use x/wf to examine a single in memory
• Eg: x/wf <a_m address> shows 5
• x/wx shows the hex representation
▪ Eg: shows 0x40a00000
▪ Use x/gf or x/gx to examine a double in memory
• Eg: x/gf <b_m address> shows
5.3300000000000001e-18

9
Basic Floating-Point Instructions
• Arithmetic instructions
▪ Use registers only (no immediates)
▪ Have two versions:
• Single precision: use S registers
• Double precision: use D registers
▪ Addition
• fadd Sd, Sn, Sm
▪ Sd = Sn + Sm
• fadd Dd, Dn, Dm
▪ Dd = Dn + Dm
10
Basic Floating-Point Instructions
(cont’d)
▪ Subtraction
• fsub Sd, Sn, Sm
▪ Sd = Sn - Sm
• fsub Dd, Dn, Dm
▪ Dd = Dn - Dm
▪ Multiplication
• fmul Sd, Sn, Sm
▪ Sd = Sn * Sm
• fmul Dd, Dn, Dm
▪ Dd = Dn * Dm

11
Basic Floating-Point Instructions
(cont’d)
▪ Multiply-negate
• fnmul Sd, Sn, Sm
▪ Sd = -(Sn * Sm)
• fnmul Dd, Dn, Dm
▪ Dd = -(Dn * Dm)
▪ Division
• fdiv Sd, Sn, Sm
▪ Sd = Sn / Sm
• fdiv Dd, Dn, Dm
▪ Dd = Dn / Dm

12
Basic Floating-Point Instructions
(cont’d)
▪ Multiply-add
• fmadd Sd, Sn, Sm, Sa
▪ Sd = Sa + (Sn * Sm)
• fmadd Dd, Dn, Dm, Da
▪ Dd = Da + (Dn * Dm)
▪ Multiply-subtract
• fmsub Sd, Sn, Sm, Sa
▪ Sd = Sa - (Sn * Sm)
• fmsub Dd, Dn, Dm, Da
▪ Dd = Da - (Dn * Dm)

13
Basic Floating-Point Instructions
(cont’d)
▪ Absolute value
• fabs Sd, Sn
▪ Sd = abs(Sn)
• fabs Dd, Dn
▪ Dd = abs(Dn)
▪ Negation
• fneg Sd, Sn
▪ Sd = -Sn
• fneg Dd, Dn
▪ Dd = -Dn

14
Basic Floating-Point Instructions
(cont’d)
• Move instructions
▪ Register
• fmov Sd, Sn
▪ Moves 32 bits from Sn to Sd
• fmov Dd, Dn
▪ Moves 64 bits from Dn to Dd
• Variants exist for moving data between general-purpose
and FP registers

15
Basic Floating-Point Instructions
(cont’d)
▪ Immediate
• Can move a limited set of FP numbers into a register
• Form:
▪ fmov Sd, #fpimm
▪ fmov Dd, #fpimm
• #fpimm:
▪ Encoded with 1 sign bit, 4 bits of fraction, and a 3-bit exponent
▪ Must be expressible as: ±n / 16 × 2r
• n in range: 16 to 31
• r in range: -3 to +4
• Eg: fmov s0, 0.25

16
Basic Floating-Point Instructions
(cont’d)
• Conversion instructions
▪ fcvt Dd, Sn
• Converts single-precision FP in Sn to double-precision FP
in Dd
▪ fcvt Sd, Dn
• Converts double in Dn to single in Sd, rounding as
necessary
• Precision may be lost since we use fewer bits to encode Sd

17
Basic Floating-Point Instructions
(cont’d)
▪ fcvtns Wd, Sn
▪ fcvtns Xd, Sn
• Converts single in Sn to nearest signed 32-bit or 64-bit
signed integer in Wd or Xd
▪ fcvtns Wd, Dn
▪ fcvtns Xd, Dn
• Converts double to nearest signed 32-bit or 64-bit signed
integer
▪ fcvtnu converts to unsigned integers

18
Basic Floating-Point Instructions
(cont’d)
▪ scvtf Sd, Wn
▪ scvtf Sd, Xn
• Converts signed 32-bit or 64-bit signed integer in Wn or Xn
to a single
▪ scvtf Dd, Wn
▪ scvtf Dd, Xn
• Converts signed integer to a double
▪ ucvtf converts unsigned integers to floats

19
Basic Floating-Point Instructions
(cont’d)
• Compare instructions
▪ Forms:
• fcmp Sn, Sm
• fcmp Sn, 0.0
• fcmp Dn, Dm
• fcmp Dn, 0.0
▪ Like the integer cmp instruction, these set the
condition flags (NZCV)
• Normally followed by a conditional branch

20
Basic Floating-Point Instructions
(cont’d)
• Eg: assembly code to divide 7.5 by 2.0
.data
x_m: .double 0r7.5
y_m: .double 0r2.0
z_m: .double 0r0.0

.text
.balign 4
.global main
main: stp x29, x30, [sp, -16]!
mov x29, sp

adrp x19, x_m // get address of x


add x19, x19, :lo12:x_m
ldr d0, [x19] // load x into d0

21
Basic Floating-Point Instructions
(cont’d)
adrp x19, y_m // get address of y
add x19, x19, :lo12:y_m
ldr d1, [x19] // load y into d1

fdiv d2, d0, d1 // x / y

adrp x19, z_m // get address of z


add x19, x19, :lo12:z_m
str d2, [x19] // store result in z

end: nop // breakpoint

ldp x29, x30, [sp], 16


ret

22
Floating-Point Arguments
• Are passed into a subroutine using registers d0 –
d7 (for doubles) and/or s0 – s7 (for singles)
▪ Are in addition to the x (w) registers used to pass in
integers or pointers
▪ Stack memory is used if there are more than 8 FP
arguments
▪ The subroutine is free to overwrite these registers

23
Floating-Point Arguments (cont’d)
• Registers d8 - d15 are callee-saved registers
▪ If used in a subroutine, the subroutine must save and
restore their values on the stack
▪ Only the bottom 64-bits of the 128-bit register need to
be preserved
• Registers d0 - d7 and d16 - d31 can be
overwritten by a subroutine
▪ The caller is responsible for saving/restoring these if
they need to be preserved over a subroutine call
24
Floating-Point Return Values
• A double FP number is returned from a
subroutine in d0
• A single is returned in s0

25

You might also like