Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ARM code examples

1,784 views
Skip to first unread message

Colin Ferris

unread,
Jun 28, 2008, 5:30:22 AM6/28/08
to

Seems my 2 replies to 'Why 32-bit?' have not arrived here! Has anyone here
seen then?

Has anyone else published any useful 'ARM' code Macros?

> > CMP R0,#<value>
> > BLLT less_than
> > BLEQ equal
> > BLGT greater_than
>
[snip]

>
> CMP R0, #<value>
> ADRLT R1, less_than
> ADREQ R1, equal
> ADRGT R1, greater_than
> MOV LR, PC
> MOV PC, R1
>

How about:

cmp r0,#<value>
adr r14,exit
adrlt pc, less_than
adreq pc, equal
adrgt pc, greater_than
.exit

--
Colin Ferris Cornwall UK

Terje Slettebø

unread,
Jun 30, 2008, 7:30:18 AM6/30/08
to
On 28 Jun, 11:30, Colin Ferris <cfer...@freeuk.com> wrote:
> Has anyone else published any useful 'ARM' code Macros?

Not exactly macros, but I included a text file with extASM (link given
at the start of the "Why 32-bit?" thread) with useful ARM techniques
that had been collected from various sources (such as the ARM PRMs)
and from my own experience, and it may be of interest, so I've
included it in this posting, as well:

--- Start ARM assembly techniques ---

Some tips and code examples for ARM assembly
--------------------------------------------

IF A=1 AND B=2 THEN
-------------------
CMP R1,#1
CMPEQ R2,#2
BEQ Routine

IF A=1 OR B=2 THEN
------------------
CMP R1,#1
CMPNE R2,#2
BEQ Routine

IF A>=0 AND A<=10 THEN
----------------------
Three ways
----------
MOV R2,#10
CMP R1,#0
CMPGE R2,R1
BGE Routine

CMP R1,#0
RSBGES R2,R1,#10
BGE Routine

CMP R1,#10
BLS Routine (!)

You can also string these compares together, e.g.
IF A=1 AND B=2 AND C=3 ... THEN
-------------------------------
CMP R1,#1
CMPEQ R2,#2
CMPEQ R3,#3
...
BEQ Routine

You can combine discrete tests and range tests, e.g.
IF A=10 OR B<=20 THEN
---------------------
CMP R1,#10
CMPNE R2,#20
BLE Routine

IF A=10 AND B<=20 THEN
----------------------
CMP R2,#20
CMPLE R1,#10
BEQ Routine


You can even combine AND and OR, like this
IF A=1 AND B=2 OR C=3 OR D=4 THEN
---------------------------------
CMP R1,#1
CMPEQ R2,#2
CMPNE R3,#3
CMPNE R4,#4
BEQ Routine

IF (A=1 OR B=2 OR C=3) AND D=4 AND E=5 OR F=6
---------------------------------------------
CMP R1,#1
CMPNE R2,#2
CMPNE R3,#3
CMPEQ R4,#4
CMPEQ R5,#5
CMPNE R6,#6

Isn't ARM assembly wonderful? Try to do this in 6 S cycles on an Intel
processor.


You can also combine calculations with compares, like
IF A=1 THEN
Var=1
IF B=2 THEN Var2=1
ENDIF
--------------------
CMP R1,#1
MOVEQ R10,#1
CMPEQ R2,#2
MOVEQ R11,#1


Jump tables
-----------
CASE A OF
WHEN 0: Routine0
WHEN 1: Routine1
...
OTHERWISE Error
ENDCASE
----------------
CMP R1,#Max_Value
ADDLS R15,R15,R1,LSL #2
B Error
B Routine0
B Routine1
...

Multiply by 2^n (i.e. 2,4,8,16,32...)
-------------------------------------
MOV R1,R1,LSL #n

Multiply by 2^n+1 (i.e. 3,5,9,17,33...)
---------------------------------------
ADD R1,R1,R1,LSL #n

Multiply by 2^n-1 (i.e. 3,7,15,31...)
-------------------------------------
RSB R1,R1,R1,LSL #n

Multiply by e.g. 10
-------------------
ADD R1,R1,R1,LSL #2 ; Multiply by 5
MOV R1,R1,LSL #1 ; Multiply by 2

Shifting down of a number with more than 32 bits
(for multi-precision arithmetics, like a 64 bit divide)
-------------------------------------------------------
128Bit_Number=128Bit_Number >> 1
--------------------------------
MOVS R3,R3,LSR #1
MOVS R2,R2,RRX
MOVS R1,R1,RRX
MOV R0,R0,RRX

Tricks to increase the speed
----------------------------
Unrolling the loop (this avoids having a lot of branches,
in proportion to the rest of the code)
---------------------------------------------------------
FOR I=1 TO 100
(Some calculation)
NEXT
------------------
MOV R1,#10 ; Count backwards to avoid an extra compare
.Loop
#rept 10
(Some calculation)
#endr
SUBS R1,R1,#1
BNE Loop

Jump-out method (for early termination of compare etc.)
-------------------------------------------------------
IF A$="T" AND B$="E" AND C$="S" D$="T" THEN
-------------------------------------------
CMP R1,#'T'
BNE No_Match
CMP R2,#'E'
BNE No_Match
CMP R3,#'S'
BNE No_Match
CMP R4,#'T'
BNE No_Match
.Match

Alternatively, if it is not that important to jump out quickly,
but that the routine is quick
---------------------------------------------------------------
CMP R1,#'T'
CMPEQ R2,#'E'
CMPEQ R3,#'S'
CMPEQ R4,#'T'
BEQ Match


Taking advantage of the conditional execution. If a branch is used,
then the pipeline has to be emptied, and instructions will be read
from the new location. If one can use condition execution, then the
pipeline doesn't have to be emptied.
-------------------------------------------------------------------
IF A=1 THEN B=1 ELSE B=2
------------------------
First attempt
-------------
CMP R1,#1
BNE Not_1
MOV R2,#1
B Done
.Not_1
MOV R2,#2
.Done

This takes 5 or 7 cycles, depending on A.

Using conditional execution
---------------------------
CMP R1,#1
MOVEQ R2,#1
MOVNE R2,#2

This takes just 3 cycles, no matter what.

Another example, making upper case letters (doesn't take into account
the letters above ASCII 127)
---------------------------------------------------------------------
CMP R1,#'a'
RSBGES R2,R1,#'z'
BICGE R1,R1,#32

You can also implement new instructions, for example the following
------------------------------------------------------------------
BL R0

This can be written as
----------------------
MOV R14,R15
MOV R15,R0

--- End ARM assembly techniques ---

Chris Terran

unread,
Jul 1, 2008, 6:33:12 AM7/1/08
to
In message <6778f10b-4356-43b6...@t54g2000hsg.googlegro
ups.com>
Terje Slettebø <tsle...@gmail.com> wrote:

> On 28 Jun, 11:30, Colin Ferris <cfer...@freeuk.com> wrote:
>> Has anyone else published any useful 'ARM' code Macros?

> Not exactly macros, but I included a text file with extASM (link given
> at the start of the "Why 32-bit?" thread) with useful ARM techniques
> that had been collected from various sources (such as the ARM PRMs)
> and from my own experience, and it may be of interest, so I've
> included it in this posting, as well:

> --- Start ARM assembly techniques ---

[snip]

> Multiply by e.g. 10
> -------------------
> ADD R1,R1,R1,LSL #2 ; Multiply by 5
> MOV R1,R1,LSL #1 ; Multiply by 2

Here's a fast division by 10 (with remainder), as a BASIC assembler
macro. Algorithm knicked from Knuth ;-)

Best, Chris

DEF FNfast_div10(Rv,Rt, Ru)
IF Rv=Ru OR Rv=Rt OR Ru=Rt ERROR 100,"Bad registers in fast_div10"
[opt opt
;; Macro. Fast unsigned 32-bit integer division/remainder by 10.
;; IN - Ru=integer
;; OUT - Rv=Ru DIV 10, Rt=Ru MOD 10
;; USES- Rt, flags
;; REF - Knuth ACP2 4.4 question 9, pg 311
;; TIME- 11 s-cycles (727272 per second @ 8MHz)
;; This method is only valid for 0 <= Ru < 2^34 so cannot be extended
;; to a multiple-precision division.
mov Rv, Ru, lsr#1 ; v=u>>1
add Rv, Rv, Rv, lsr#1 ; v+=v>>1
add Rv, Rv, Rv, lsr#4 ; v+=v>>4
add Rv, Rv, Rv, lsr#8 ; v+=v>>8
add Rv, Rv, Rv, lsr#16 ; v+=v>>16
mov Rv, Rv, lsr#3 ; v=v>>3
; Now Rv=[Ru div 10] or [Ru div 10 - 1]
; Correct by multiplying by 10 and comparing
add Rt, Rv, Rv, asl#2 ; *5
sub Rt, Ru, Rt, asl#1 ; Rt=Ru-10*Rv (ie. remainder)
cmp Rt, #10
addge Rv, Rv, #1
subge Rt, Rt, #10
]=0


--
*** Chris & Lee's Photodesk tutorials, tips and resources
*** http://www.photodesk.iconbar.com *** New tiles!
Latest: 32-bit XEarth at http://www.roast.iconbar.com

Terje Slettebø

unread,
Jul 1, 2008, 9:09:52 AM7/1/08
to
On 1 Jul, 12:33, Chris Terran <chris.terran...@ntlworld.com> wrote:
> In message <6778f10b-4356-43b6-9683-2aca85181...@t54g2000hsg.googlegro
> ups.com>

>           Terje Slettebø <tslett...@gmail.com> wrote:
>
> > On 28 Jun, 11:30, Colin Ferris <cfer...@freeuk.com> wrote:
> >> Has anyone else published any useful 'ARM' code Macros?
> > Not exactly macros, but I included a text file with extASM (link given
> > at the start of the "Why 32-bit?" thread) with useful ARM techniques
> > that had been collected from various sources (such as the ARM PRMs)
> > and from my own experience, and it may be of interest, so I've
> > included it in this posting, as well:
> > --- Start ARM assembly techniques ---
>
> [snip]
>
> > Multiply by e.g. 10
> > -------------------
> > ADD      R1,R1,R1,LSL #2     ; Multiply by 5
> > MOV      R1,R1,LSL #1        ; Multiply by 2
>
> Here's a fast division by 10 (with remainder), as a BASIC assembler
> macro. Algorithm knicked from Knuth ;-)

Nice. :)

Also, division by a constant x may also sometimes be done by
multiplying with 1/x (being pre-computed). :)

> Latest: 32-bit XEarth athttp://www.roast.iconbar.com

Cool. :) I have astronomy as a hobby as well, so I've been on the
lookout for RISC OS astronomy related software/sites. I'll check it
out.

0 new messages