1.19. FLOATING-POINT UNIT
POP {R3-R7,PC}
loc_1C0
MOVS R0, R4
MOVS R1, R5
POP {R3-R7,PC}
Keil doesn’t generate FPU-instructions since it cannot rely on them being supported on the target CPU,
and it cannot be done by straightforward bitwise comparing. So it calls an external library function to do
the comparison:__aeabi_cdrcmple.
N.B. The result of the comparison is to be left in the flags by this function, so the followingBCS(Carry
set—Greater than or equal) instruction can work without any additional code.
ARM64
Optimizing GCC (Linaro) 4.9
d_max:
; D0 - a, D1 - b
fcmpe d0, d1
fcsel d0, d0, d1, gt
; now result in D0
ret
The ARM64ISAhas FPU-instructions which setAPSRthe CPU flags instead ofFPSCRfor convenience.
TheFPUis not a separate device here anymore (at least, logically). Here we seeFCMPE. It compares the
two values passed inD0andD1(which are the first and second arguments of the function) and setsAPSR
flags (N, Z, C, V).
FCSEL(Floating Conditional Select) copies the value ofD0orD1intoD0depending on the condition (GT—
Greater Than), and again, it uses flags inAPSRregister instead ofFPSCR.
This is much more convenient, compared to the instruction set in older CPUs.
If the condition is true (GT), then the value ofD0is copied intoD0(i.e., nothing happens). If the condition
is not true, the value ofD1is copied intoD0.
Non-optimizing GCC (Linaro) 4.9
d_max:
; save input arguments in "Register Save Area"
sub sp, sp, #16
str d0, [sp,8]
str d1, [sp]
; reload values
ldr x1, [sp,8]
ldr x0, [sp]
fmov d0, x1
fmov d1, x0
; D0 - a, D1 - b
fcmpe d0, d1
ble .L76
; a>b; load D0 (a) into X0
ldr x0, [sp,8]
b .L74
.L76:
; a<=b; load D1 (b) into X0
ldr x0, [sp]
.L74:
; result in X0
fmov d0, x0
; result in D0
add sp, sp, 16
ret