This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS570LC4357: Reporting Undef Instruction exception for divide by zero

Part Number: TMS570LC4357

Hi Team,
We are using TMS570LC4357 processor for our project. Our requirement is to create Undefined Instruction exception for 'Divide by zero' and report same.

To enable the Divide by zero, we have set DZ bit of SCTLR and getting Undefined Instruction exception for divide by zero.

But, while reporting the exception details to user, we are not able to confirm if exception is raised due to 'Divide by zero' occurrence as reading fpscr (DZC bit) returns zero (0).

As per ARM Cortex RM (Cortex-R5 and Cortex-R5F), section 11.5.3 "The exception enable bits in the FPSCR read-as-zero, and cannot be written.",

So is there any way to determine that Undefined Instruction exception is getting raised due to 'Divide by zero' condition ?

  • When DZ bit (19th) of SCTLR register is set, an Undefined Instruction Exception is generated. When DZ=0, it does not generate the exception. I don't see any indication to tell the undef is caused by "divide by zero".

  • But, while reporting the exception details to user, we are not able to confirm if exception is raised due to 'Divide by zero' occurrence as reading fpscr (DZC bit) returns zero (0).

    I had an initial attempt to test setting of the DZC bit in the FPSCR, starting with a program using the default of an Undefined Instruction not enabled for divide by zero.

    The code used was:

    /* USER CODE BEGIN (0) */
    /* USER CODE END */
    
    /* Include Files */
    
    #include "HL_sys_common.h"
    
    /* USER CODE BEGIN (1) */
    #include <stdio.h>
    /* USER CODE END */
    
    /** @fn void main(void)
    *   @brief Application main function
    *   @note This function is empty by default.
    *
    *   This function is called after startup.
    *   The user can use this function to implement the application.
    */
    
    /* USER CODE BEGIN (2) */
    #pragma diag_push
    #pragma diag_suppress 994 /* missing return statement at end of non-void function */
    uint32_t get_fpscr (void)
    {
        asm volatile (" VMRS r0, FPSCR");
    }
    #pragma diag_pop
    /* USER CODE END */
    
    int main(void)
    {
    /* USER CODE BEGIN (3) */
        const volatile double a = 1023.4567;
        const volatile double b = 0.0;
        const volatile uint32_t fpscr_before = get_fpscr ();
        const volatile double c = a / b;
        const volatile uint32_t fpscr_after = get_fpscr ();
    
        printf ("%g/%g=%g\n", a, b, c);
        printf ("FPSCR before=0x%08x after=0x%08x\n", fpscr_before, fpscr_after);
    /* USER CODE END */
    
        return 0;
    }
    

    The output reported was:

    [CortexR5] 1023.46/0=+inf
    FPSCR before=0x00000000 after=0x00000002
    

    This shows that when an Undefined Instruction isn't enabled, a floating point divide-by-zero:

    • Results in a Infinity result
    • Sets the DZC (bit 1) in the FPSCR. Single stepping in the debugger confirmed that it was the VDIV.F64 instruction which set DZC.

    Will try again with the Undefined Instruction enabled.

  • But, while reporting the exception details to user, we are not able to confirm if exception is raised due to 'Divide by zero' occurrence as reading fpscr (DZC bit) returns zero (0).

    When the first post mentioned reading the fpscr (Floating-Point Status and Control Register) I initially read that as a floating point divide by zero was being tested.

    Have tried setting the DZ bit in SCTLR, a floating point divide by zero (using a VDIV.F64 instruction) didn't cause an Undefined Instruction Exception.

    Reading the Cortex-R5 TRM again, the DZ bit in the SCTLR actually controls if the integer division UDIV or SDIV instructions generated an undefined instruction exception if they attempt a divide-by-zero.

    From the Cortex-R5 TRM I can't see any status bit which records if an integer divide-by-zero has occurred. Perhaps the Undefined Instruction exception handler could read the instruction which generated the exception, and see if a UDIV or SDIV instruction opcode.