29.10.2014 Views

ARM Compiler toolchain v4.1 for µVision Using the Compiler

ARM Compiler toolchain v4.1 for µVision Using the Compiler

ARM Compiler toolchain v4.1 for µVision Using the Compiler

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Compiler</strong> Coding Practices<br />

5.58 Identification of software floating-point division-by-zero errors<br />

The C library helper function _fp_trapveneer() is called whenever an exception occurs. On<br />

entry into this function, <strong>the</strong> state of <strong>the</strong> registers is unchanged from when <strong>the</strong> exception<br />

occurred. There<strong>for</strong>e, to find <strong>the</strong> address of <strong>the</strong> function in <strong>the</strong> application code that contains <strong>the</strong><br />

arithmetic operation that resulted in <strong>the</strong> exception, a breakpoint can be placed on <strong>the</strong> function<br />

_fp_trapveneer() and LR can be inspected.<br />

For example, suppose <strong>the</strong> C code of Example 5-7 is compiled from <strong>the</strong> command line using <strong>the</strong><br />

string:<br />

armcc --fpmode ieee_full<br />

When <strong>the</strong> assembly language code produced by <strong>the</strong> compiler is disassembled, <strong>the</strong> debugger<br />

produces <strong>the</strong> output shown in Example 5-8.<br />

Example 5-7 Trapped division-by-zero error<br />

#include <br />

#include <br />

int main(void)<br />

{ float a, b, c;<br />

// Trap <strong>the</strong> Invalid Operation exception and untrap all o<strong>the</strong>r exceptions:<br />

__ieee_status(FE_IEEE_MASK_ALL_EXCEPT, FE_IEEE_MASK_DIVBYZERO);<br />

c = 0;<br />

a = b / c;<br />

printf("b / c = %f, ", a); // trap division-by-zero error<br />

return 0;<br />

}<br />

Example 5-8 Disassembly of division by zero error<br />

main:<br />

00008080 E92D4010 PUSH {r4,lr}<br />

00008084 E3A01C02 MOV r1,#0x200<br />

00008088 E3A00C9F MOV r0,#0x9f00<br />

0000808C EB000F1A BL __ieee_status <br />

00008090 E59F0020 LDR r0,0x80b8<br />

00008094 E3A01000 MOV r1,#0<br />

00008098 EB000DEA BL _fdiv <br />

0000809C EB000DBD BL _f2d <br />

000080A0 E1A02000 MOV r2,r0<br />

000080A4 E1A03001 MOV r3,r1<br />

000080A8 E28F000C ADR r0,{pc}+0x14 ; 0x80bc<br />

000080AC EB000006 BL __0printf <br />

000080B0 E3A00000 MOV r0,#0<br />

000080B4 E8BD8010 POP {r4,pc}<br />

000080B8 40A00000 0x00 0x00 0xA0 '@'<br />

000080BC 202F2062 'b' ' ' '/' ' '<br />

000080C0 203D2063 'c' ' ' '=' ' '<br />

000080C4 202C6625 '%' 'f' ',' ' '<br />

000080C8 00000000 0x00 0x00 0x00 0x00<br />

Placing a breakpoint on _fp_trapveneer and executing <strong>the</strong> disassembly in <strong>the</strong> debug monitor<br />

produces:<br />

<strong>ARM</strong> DUI 0375C Copyright © 2007-2008, 2011 <strong>ARM</strong>. All rights reserved. 5-74<br />

ID061811<br />

Non-Confidential

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!