Files
2019-07-07 00:00:01 +00:00

91 lines
2.5 KiB
ArmAsm

/* https://cirosantilli.com/linux-kernel-module-cheat#arm-vcvt-instruction */
#include <lkmc.h>
LKMC_PROLOGUE
/* SIMD positive. */
.data
vcvt_positive_0: .float 1.25, 2.5, 3.75, 4.0
vcvt_positive_expect: .word 1, 2, 3, 4
.bss
vcvt_positive_result: .skip 0x10
.text
ldr r0, =vcvt_positive_0
vld1.32 {q0}, [r0]
vcvt.u32.f32 q1, q0
ldr r0, =vcvt_positive_result
vst1.32 {q1}, [r0]
LKMC_ASSERT_MEMCMP(vcvt_positive_result, vcvt_positive_expect, =0x10)
/* SIMD negative. */
.data
vcvt_negative_0: .float -1.25, -2.5, -3.75, -4.0
vcvt_negative_expect: .word -1, -2, -3, -4
.bss
vcvt_negative_result: .skip 0x10
.text
ldr r0, =vcvt_negative_0
vld1.32 {q0}, [r0]
vcvt.s32.f32 q1, q0
ldr r0, =vcvt_negative_result
vst1.32 {q1}, [r0]
LKMC_ASSERT_MEMCMP(vcvt_negative_result, vcvt_negative_expect, =0x10)
/* Floating point. */
.data
vcvt_positive_float_0: .float 1.5, 2.5
vcvt_positive_float_expect: .word 1
.float 2.5
.bss
vcvt_positive_float_result: .skip 0x8
.text
ldr r0, =vcvt_positive_float_0
vld1.32 {d0}, [r0]
vcvt.u32.f32 s0, s0
ldr r0, =vcvt_positive_float_result
vst1.32 {d0}, [r0]
LKMC_ASSERT_MEMCMP(vcvt_positive_float_result, vcvt_positive_float_expect, =0x8)
/* Floating point but with immediates.
*
* You have to worry of course about representability of
* the immediate in 4 bytes, which is even more fun for
* floating point numbers :-)
*
* Doing this mostly to illustrate the joys of vmov.i32.
*
* For some reason, there is no vmov.i32 sn, only dn.
* If you try to use sn, it does the same as .f32 and
* stores a float instead. Horrible!
*/
vmov.f32 d0, 1.5
vcvt.u32.f32 s0, s0
vmov.i32 d1, 1
vcmp.f32 s0, s2
vmrs apsr_nzcv, fpscr
LKMC_ASSERT(beq)
/* Check that s1 wasn't modified by vcvt. */
vmov.f32 s2, 1.5
vcmp.f32 s1, s2
vmrs apsr_nzcv, fpscr
LKMC_ASSERT(beq)
/* Floating point double precision. */
.data
vcvt_positive_double_0: .double 1.5
vcvt_positive_double_expect: .word 1
.bss
vcvt_positive_double_result: .skip 0x8
.text
ldr r0, =vcvt_positive_double_0
vld1.64 {d0}, [r0]
vcvt.u32.f64 s0, d0
ldr r0, =vcvt_positive_double_result
vst1.32 {d0}, [r0]
LKMC_ASSERT_MEMCMP(
vcvt_positive_double_result,
vcvt_positive_double_expect,
=0x4
)
LKMC_EPILOGUE