Open Access
Application Note
Writing Efficient C for ARM
Document number: ARM DAI 0034A
Issued: January 1998
Copyright Advanced RISC Machines Ltd (ARM) 1998
ENGLAND
Advanced RISC Machines Limited
Fulbourn Road
Cherry Hinton
Cambridge CB1 4JN
UK
Telephone: +44 1223 400400
Facsimile: +44 1223 400410
Email: info@arm.com
GERMANY
Advanced RISC Machines Limited
Otto-Hahn Str. 13b
85521 Ottobrunn-Riemerling
Munich
Germany
Telephone: +49 89 608 75545
Facsimile: +49 89 608 75599
Email: info@arm.com
JAPAN
Advanced RISC Machines K.K.
KSP West Bldg, 3F 300D, 3-2-1 Sakado
Takatsu-ku, Kawasaki-shi
Kanagawa
213 Japan
Telephone: +81 44 850 1301
Facsimile: +81 44 850 1308
Email: info@arm.com
USA
ARM USA Incorporated
Suite 5
985 University Avenue
Los Gatos
CA 95030 USA
Telephone: +1 408 399 5199
Facsimile: +1 408 399 8854
Email: info@arm.com
World Wide Web address: http://www.arm.com
34
Application Note 34
ii ARM DAI 0034A
Open Access
Proprietary Notice
ARM and the ARM Powered logo are trademarks of Advanced RISC Machines Ltd.
Neither the whole nor any part of the information contained in, or the product described in, this document may be adapted or reproduced in
any material form except with the prior written permission of the copyright holder.
The product described in this document is subject to continuous developments and improvements. All particulars of the product and its use
contained in this document are given by ARM in good faith. However, all warranties implied or expressed, including but not limited to implied
warranties or merchantability, or fitness for purpose, are excluded.
This document is intended only to assist the reader in the use of the product. ARM Ltd shall not be liable for any loss or damage arising from
the use of any information in this document, or any error or omission in such information, or any incorrect use of the product.
Key
Document Number
This document has a number which identifies it uniquely. The number is displayed on the front page and at the foot of each subsequent page.
ARM
XXX 0000 X - 00
Document Status
The document’s status is displayed in a banner at the bottom of each page. This describes the document’s confidentiality and its information
status.
Confidentiality status is one of:
ARM Confidential Distributable to ARM staff and NDA signatories only
Named Partner Confidential Distributable to the above and to the staff of named partner companies only
Partner Confidential Distributable within ARM and to staff of all partner companies
Open Access No restriction on distribution
Information status is one of:
Advance Information on a potential product
Preliminary Current information on a product under development
Final Complete information on a developed product
Change Log
Issue Date By Change
A January 1998 SKW Released
(On review drafts only) Two-digit draft number
Release code in the range A-Z
Unique four-digit number
Document type
Table of Contents
Application Note 34
ARM DAI 0034A 1
Open Access
Table of Contents
1 Introduction 2
2 Setting Compiler Options 3
2.1 Selecting processor/architecture 3
2.2 Debugging options 3
2.3 Optimization options 4
2.4 APCS options 4
3 Division and Remainder 6
3.1 Combining division and remainder 6
3.2 Division and remainder by powers of two 7
3.3 Alternatives to remainder for modulo arithmetic 7
3.4 Division by a constant 8
3.5 Using lookup tables 8
4 Conditional Execution 9
5 Boolean Expressions 10
5.1 Range checking 10
5.2 Compares with zero 11
6 Loops 12
6.1 Loop termination 12
6.2 Loop unrolling 13
7 Switch Statement 14
7.1 Switch statement vs. lookup tables 14
8 Register Allocation 16
8.1 Register allocatable variables 16
8.2 Aliasing 16
8.3 Live variables and spilling 20
9 Variable Types 21
9.1 Local variables 21
9.2 Use of shorts/signed bytes on ARM 22
9.3 Space occupied by global data 22
10 Function Design 23
10.1 Function call overhead 23
10.2 Leaf functions 25
10.3 Tail continued functions 26
10.4 Pure functions 27
10.5 Inline functions 28
10.6 Function definitions 29
11 Using Lookup Tables 30
12 Floating-Point Arithmetic 31
13 Cross Jump Optimization 32
14 Portability of C Code 33
15 Further Information 34
Introduction
Application Note 34
2 ARM DAI 0034A
Open Access
1 Introduction
The ARM and Thumb C compilers are mature, industrial-strength ANSI C compilers which
are capable of producing high quality machine code. However, when writing source code,
it is always worthwhile to use programming techniques which work well on RISC
processors such as ARM. This Application Note describes some of the techniques that
can be useful. It also explains to some extent how the ARM compiler works, and how to
use the C language efficiently. These techniques and knowledge will enable programmers
to increase execution speed and/or lower code density.
Note
Most of the techniques discussed in this Application Note are equally applicable to both
armcc
and
tcc
. If a technique is only applicable to ARM or Thumb, this is highlighted. In
principle, many of the described techniques are also applicable to other languages and
other compilers.
Note
The code examples given in this Application Note have been compiled and disassembled
using tools supplied with ARM Software Development Toolkit version 2.11. If you are using
another version of the toolkit, your output may differ slightly, though the principles
highlighted should still hold, and should continue to hold in future releases.
Setting Compiler Options
Application Note 34
ARM DAI 0034A 3
Open Access
2 Setting Compiler Options
2.1 Selecting processor/architecture
You must select the correct processor, as this enables the compiler to make full use of
instructions which are supported by the processor, and also perform processor-specific
optimizations. If the processor is not directly supported, use the most appropriate base
processor in a family. For example, use
-proc ARM7
for the ARM7 derivatives ARM710,
ARM7100, and use
-proc StrongARM1
for the SA-1100. Note that when an ARM7
processor is selected you must specify whether the processor supports the Thumb
instruction set (for example,
proc ARM7T
). This enables the compiler to use halfword
instructions, making 16-bit accesses more efficient.
Alternatively, when a program is compiled to run on different ARM processors, choose the
most appropriate architecture using
-arch N
. If possible, choose architecture 4 or 4T, as
this enables the halfword instructions.
2.2 Debugging options
When setting the debugging options, it is important to know that enabling any of them will
affect both codesize and performance
significantly
. The reason is that for debugging a
varying level of optimizations is disabled. This is necessary because some optimizations
produce code that cannot be described in debugging tables (so, for example, variables
may be displayed incorrectly, or it becomes impossible to set breakpoints at certain
places). Therefore, it is best to switch off all debugging when codesize and/or performance
are important.
The compiler supports the following debugging options:
•
-g
high-level debugging, all optimizations disabled, simple register allocation
•
-gr
high-level debugging, some optimizations enabled, simple register allocation
•
-go
high-level debugging, most optimizations enabled, full register allocation
The following sections indicate which optimizations are disabled for debugging.
The option
-go
is the best option to use if debug information is really needed, as it
enables the most important optimizations. It typically increases codesize by 7−15%, and
decreases performance even more.
Debugging table size can be reduced by using ASD format in combination with
-gtp
. This
provides the same level of debug information as Dwarf 1.0.