diff --git a/src/layer/arm/arm_usability.h b/src/layer/arm/arm_usability.h index 9e123c957..6a2d01b25 100644 --- a/src/layer/arm/arm_usability.h +++ b/src/layer/arm/arm_usability.h @@ -15,6 +15,37 @@ #ifndef ARM_USABILITY_H #define ARM_USABILITY_H +class FPSCRGuard +{ +#if !__aarch64__ +public: + FPSCRGuard() + { + // set round mode to round to nearest for armv7 + // this impacts all vcvtr instructions in guarded scope + asm volatile( + "vmrs %0, FPSCR \n" + "bic r10, %0, #0x00c00000 \n" + "vmsr FPSCR, r10 \n" + : "=r"(FPSCR_value) + : + : "memory", "r10"); + } + + ~FPSCRGuard() + { + asm volatile( + "vmsr FPSCR, %0 \n" + : + : "r"(FPSCR_value) + : "memory"); + } + +private: + int FPSCR_value; +#endif // !__aarch64__ +}; + static inline signed char float2int8(float v) { int int32 = round(v); diff --git a/src/layer/arm/quantize_arm.cpp b/src/layer/arm/quantize_arm.cpp index a9b05872e..feddfbd0f 100644 --- a/src/layer/arm/quantize_arm.cpp +++ b/src/layer/arm/quantize_arm.cpp @@ -41,6 +41,8 @@ Quantize_arm::Quantize_arm() int Quantize_arm::forward(const Mat& bottom_blob, Mat& top_blob, const Option& opt) const { + FPSCRGuard fpscr_guard; + int elembits = bottom_blob.elembits(); #if __ARM_FEATURE_FP16_VECTOR_ARITHMETIC diff --git a/src/layer/arm/requantize_arm.cpp b/src/layer/arm/requantize_arm.cpp index 4d4531e94..4492ef913 100644 --- a/src/layer/arm/requantize_arm.cpp +++ b/src/layer/arm/requantize_arm.cpp @@ -42,6 +42,8 @@ Requantize_arm::Requantize_arm() int Requantize_arm::forward(const Mat& bottom_blob, Mat& top_blob, const Option& opt) const { + FPSCRGuard fpscr_guard; + int dims = bottom_blob.dims; int elempack = bottom_blob.elempack;