No exception when divided by zero.

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

No exception when divided by zero.

3,084 次查看
fffengzia
Contributor II

Hello.

I am working on imx8mmevk, with linux image built from Yocto. And I found that there will be no exception raised when a number divide zero at runtime. Below is an example in C:

 

int a=2/0;
float b=1.2/0;

// the result is: a=0, b=inf
printf("a=%d, b=%f", a, b);

 

 As I know, registers FPCR (floating-point control register) with DZE bit and FPSR (floating-point status register) with DZC bit were designed to handle the situation for armv8. But referring to reference documents from i.MX 8M Mini | Arm Cortex A53 | Cortex M4 | NXP Semiconductors,  I found that there is no DZE bit in a53, and it seems no way to get the exception.

I don't know if I got some mistakes, and I wonder how to handle the problem.

Could someone give me a hand?

=============================================

Edit at 2023.11.24.

Further ask.

Can I write my own ISR to handle division by zero (especially for floating-point)? May someone could give me advise.

=============================================

 

Thanks.

fffengzia

标记 (2)
0 项奖励
回复
10 回复数

2,637 次查看
mbitsnbites
Contributor I

As far as I can tell, no ARM cores (not even the Cortex-X1) support trapping floating-point exceptions. Actually, in most systems (CPU:s and operating systems) trapping floating-point exceptions are either turned off by default or not supported at all, usually for good reasons (floating-point exceptions hurt performance, are largely misunderstood and are usually unnecessary).

I recommend that you find other ways of dealing with the problem.

First of all, it should be noted that division by zero is a well defined operation in IEEE 754 floating-point arithmetic. It returns +/-infinity, which is a valid input to other operations (e.g. 42/infinity = 0, 42+infinity=infinity, and so on). In fact, many algorithms actually work out perfectly fine even when division by zero is involved.

Second, if you really need to prevent division by zero in your code (be sure to figure out why it is not allowed), the canonical way to do that is to check the value of the denominator before the division, and handle it appropriately (e.g. throw a C++ exception if the denominator is zero). Another way is to use isfinite() to check the result of the division.

Also, as others have pointed out your examples will be calculated at compile time. In order to really trigger division by zero at runtime, you need to put the division in a function in a separate compilation unit (e.g. main() in main.c calls divide() in division.c), so that the compiler does not know the input values to the division at compile time.

0 项奖励
回复

2,608 次查看
kef2
Senior Contributor V

Some ARM's indeed do support FPU exceptions.

FPSCR

Bits[15, 12:8] Floating-point exception trap enable bits. These bits are supported only in VFPv2, VFPv3U, and VFPv4U. They are reserved, RAZ/WI, on a system that implements VFPv3 or VFPv4.

  • Actually, in most systems (CPU:s and operating systems) trapping floating-point exceptions are either turned off by default or not supported at all, usually for good reasons (floating-point exceptions hurt performance, are largely misunderstood and are usually unnecessary).

Yeah. Though this ARM FPU exception (they are configurable to enable /0, imprecise, etc) could be kept enabled without affecting performance of any decent code:

  IOE, bit[8] Invalid Operation exception trap enable.

 

  • First of all, it should be noted that division by zero is a well defined operation in IEEE 754 floating-point arithmetic. It returns +/-infinity

Yeah, but 0/0 is invalid operation, not a number, Nan. As well invalid is Inf/Inf or any operation with NaN. 

0 项奖励
回复

3,036 次查看
kef2
Senior Contributor V
int a=2/0;
float b=1.2/0;

These ^^ are compile time constants in most of compilers, which just can't raise any exception at run time. Did your compiler emit any warnings?

0 项奖励
回复

3,040 次查看
Harvey021
NXP TechSupport
NXP TechSupport

Have you tried to write a kernel module to test? It is possible that the compiler will handle it if write it this way. 

 

Regards

Harvey

0 项奖励
回复

3,010 次查看
kimease
Contributor II

Harvey,

Please note!

It is a question about armv8 instruction.

Related no to any OS.

Far away from kernel.

 

0 项奖励
回复

3,029 次查看
fffengzia
Contributor II

I am sorry that I haven't express it clearly.

I need the exception at runtime, for the real situation is that the dividend is a variable and it becomes 0 accidently and then got into calculation.

I wrote an example code in my reply to Harvey, may that would explain my problem clearly.

Regards

fffengzia

0 项奖励
回复

3,033 次查看
fffengzia
Contributor II

Maybe I haven't expressed my situation clearly. There is nothing to do with compiler because what I need is to get an exception at runtime. 

If I wrote it "1/0" or "1.2/0" explicitly, the compile does through an error or warning. But what if the zero is a variable, and it becomes 0 accidently (or carelessly)?

$ cat main.c
#include <stdio.h>

int main(int argc, char* argv[])
{
        int a = 1, b = 1;
        float c = 1.2;

        int iRes;
        float fRes;


        // Accidently or Carelessly
        a -= 1;


        iRes = b/a;
        fRes = c/a;

        printf("1/0=%d, 1.2/0=%f\n", iRes, fRes);

        return 0;
}
$ gcc -Wall main.c #No warning or error here
$ ./a.out
1/0=0, 1.2/0=inf

 

0 项奖励
回复

3,011 次查看
kimease
Contributor II


Arm® Architecture Reference Manual
Armv8, for A-profile architecture
Copyright © 2013-2021 Arm Limited or its affiliates. All rights reserved.
ARM DDI 0487G.b (ID072021)

No indication of this overflow is produced

A division by zero results in a zero being written to the destination register, without any indication that the division by zero occurred.

(that is why you find a = 0)

ssssss.png

 


Please search fdiv to find information. floating divide has too many informati1, can not paste everything here.
It is also related to IEEE 754


a=0, b=inf inf=infinity

When you compile, compiler will give warning. You can change warning as error to stop compiling.
aarch64-linux-gnu-gcc -static -o div0 div0.c
div0.c: In function ‘main’:
div0.c:7:9: warning: division by zero [-Wdiv-by-zero]
int a=2/0;
^
div0.c:8:13: warning: division by zero [-Wdiv-by-zero]
float b=1.2/0;
^

 

Here is the assembly code for
int a=2/0;
float b=1.2/0;

.arch armv8-a
.file "div0.c"
.text
.section .rodata
.align 3
.LC0:
.string "a=%d, b=%f"
.text
.align 2
.global main
.type main, %function
main:
stp x29, x30, [sp, -48]!
add x29, sp, 0
str w0, [x29, 28]
str x1, [x29, 16]
mov w0, 2
mov w1, 0
sdiv w0, w0, w1
str w0, [x29, 44]
movi d0, #0
mov x0, 3689348814741910323
movk x0, 0x3ff3, lsl 48
fmov d1, x0
fdiv d0, d1, d0
fcvt s0, d0
str s0, [x29, 40]
ldr s0, [x29, 40]
fcvt d0, s0
adrp x0, .LC0
add x0, x0, :lo12:.LC0
ldr w1, [x29, 44]
bl printf
mov w0, 0
ldp x29, x30, [sp], 48
ret

3,000 次查看
fffengzia
Contributor II

I am so glad that you got my point :-).

The problem of integer division by zero could get its answer now. 

From the Architecture Reference Manual:

fdiv.png

And from A1.5.7:

dze.png About the FPCR:

FPCR.png

 

However, it seems that this register is not forced to be used in every armv8 core, at least for a53:

ARM® Cortex®-A53 MPCore Processor
Advanced SIMD and Floating-point

Copyright © 2013-2016 ARM. All rights reserved.
ARM DDI 0502G (ID041316)

a53fpcr.png

 

But not all a53 cores don't raise exception if floating-point division by zero. I have ever used another board from other manufacturer, which raise an exception if floating-point division happens. And I need to know if the a53 on imx8mmevk does able or not able to act like it.

I have referred to documents about imx8mmevk and could not found some useful. 

0 项奖励
回复

3,026 次查看
kef2
Senior Contributor V

This again may be optimized out to avoid /0 and use compile time constants. Try making your "a" global scope and volatile, so that -=1 and further /=0 can't be optimized out.

0 项奖励
回复