Building a simple loop using Blackfin assembly code

Building a simple loop using
Blackfin assembly code
If you can handle the while-loop correctly in
assembly code on any processor, then most of the
other code is easy to complete.
M. Smith,
Electrical and Computer Engineering,
University of Calgary, Canada
Tackled today



Bring Blackfin Instruction Reference Manual
Determine the differences / advantages and
disadvantages between
for-loops, while-loops, do-while-loops and
do-while-loops with initial tests
Demonstrate ability to turn functioning “C++”
into Blackfin assembly code
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
2 / 27
C++ version of code -- “for-loop”
int SimpleForLoopCPP(void) {
int counter = 0;
int sum = 0;
for (counter = 0; count <= 15; count++) {
sum += counter;
} – Most processors have to “fake” for-loops
return sum;
}
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
3 / 27
Standard assembly stub code for
int SimpleForLoopASM (void)
#include <blackfin.h>
.section program;
.global _SimpleForLoopASM;
.align 4;
// void SimpleForLoopASM (void) {
_SimpleForLoopASM:
// Code for loop goes here
_SimpleForLoopASM.end:
4/9/2015
RTS;
// }
A “stub” is NOT
designed to “work
properly”.
It is designed to have
just enough information
so that you can compile
or assembly, build and
run the project without
crashing the system.
If you can’t get the stub
to “run”, then the “real”
code will not either.
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
4 / 27
Translation problems with
“for-loop” into assembly code

Most processors don’t any capability to directly
perform real “for-loops” in assembly code.




Blackfin has “limited” capability
MIPS has ?
68000 has ?
Time spent in loop depends on capabilities of
compiler and processor



4/9/2015
An optimizing compiler may recognize that “nothing useful”
is happening in the loop and remove it from the function
Loop speed depends on processor speed – improve the
processor means code speed is faster
Original “Invaders” game on Atari processor used this as a
“feature” and not a bug.
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
5 / 27
C++ version of code
while-loop and do-while loop
Could be constructed using “while” and “do while” constructs
WHILE
int counter = 0;
while (counter <= 15) {
sum += counter;
counter++;
}
NOTES ON ISSUES WITH
WHILE AND DO- WHILE
CONSTRUCTS
DO_WHILE
int counter = 0;
do {
sum += counter;
counter++;
} while (counter <= 15) ;
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
6 / 27
Can now develop / test a
“C++” prototype function
WHILE
int counter = 0;
while (counter <= 15) {
sum += counter;
counter++;
}
CHANGE CODE FORMAT TO
PREPARE FOR ASSEMBLY CODE TRANSLATION – 1 ACTION PER LINE
int counter = 0;
WHILE: IF (counter > 15)
then JUMP to ENDWHILE label
ELSE {
sum += counter;
counter++;
JUMP to WHILE label  THIS LINE IS OFTEN MISSED
}
// Since missing that last jump line wastes so much time in the laboratory
ENDWHILE:
// then missing that last jump line in quizzes and exams is marked hard
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
7 / 27
Knowledge we need to have in
order to be able to continue
What register is suitable to store the counter variable value?
What register is suitable to store the sum variable value?
How do you do a conditional jump?
How do you do a test such as counter > 2?
How do you do a test such as counter > 15? -- There IS a difference
int counter = 0;
WHILE: IF (counter > 15)
then JUMP to ENDWHILE label
ELSE {
sum += counter;
counter++;
JUMP to WHILE label
}
ENDWHILE:
4/9/2015
while (counter <= 15) {
sum += counter;
counter++;
}
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
8 / 27
How do you do a
conditional jump on a Blackfin?


Key reference material
Blackfin Instruction Manual
Chapter 7 Program Flow Control

Instruction Summary






4/9/2015
Setting the CC register on page ?????
“Jump” on page 7-2
“IF CC JUMP” on page 7-5
Call” on page 7-8
“RTS, RTI, RTX, RTN, RTE (Return)”
on page 7-10
“LSETUP, LOOP” on page 7-13
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
9 / 27
The condition code register CC

This is the Blackfin Boolean condition code
or flag register

CC can take the value TRUE = 1
CC can take the value FALSE = 0



CC register can be set in a number of
different ways
Blackfin processor can actually do “IF”
instructions in assembly code
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
10 / 27
The condition code register CC used to
conditionally move register values

Are these legal conditional MOVE instructions?
IF NOT LEGAL WHY NOT? CONDITIONAL MOVE
CHECK THEM OUT BY LOOKING IN CHAPTER 9-8!!

IF CC R4 = R5; // If CC TRUE then set R4 = R5

Meaning MOVE the value in R5 into R4 (leaves R5 unchanged)

IF !CC R6 = R7; // If CC FALSE then set R4 = R5

IF CC P0 = R5; // Move a value from a data register
IF !CC P2 = P7; //
into a pointer register



IF CC R0 = R7.L; // Move a 16 bit value into a 32 bit register
IF !CC R0.L = R4.L // Move a 16-bit value into a 16 bit register
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
11 / 27
How to we set the CC register?
Reference Blackfin Instruction Manual
Chapter 6, Condition Code Bit Management










CC = Dreg == Dreg ; /* equal, register, signed (a) */
CC = Dreg < Dreg ; /* less than, register, signed (a) */
CC = Dreg <= Dreg ; /* less than or equal, register, signed (a) */
CC = Dreg == imm3 ; /* equal, immediate, signed (a) */
imm3 is -4 to +3
CC = Dreg < imm3 ; /* less than, immediate, signed (a) */
CC = Dreg <= imm3 ; /* less than or equal, immediate, signed (a) */
CC = Dreg < Dreg (IU) ; /* less than, register, unsigned (a) */
CC = Dreg <= Dreg (IU) ; /* less than or equal, register, unsigned (a)
CC = Dreg < uimm3 (IU) ; /* less than, immediate, unsigned (a) */ uimm3 is 0 to +7
CC = Dreg <= uimm3 (IU) ; /* less than or equal, immediate unsigned
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
12 / 27
How do you do a conditional jump
to instruction labelled
END_WHILE?

Add the answer

First set condition code flag (CC) to be
true or false

IF CC JUMP END_WHILE
(if true jump)
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
13 / 27
Important to know what
you CAN’T DO when setting CC!!




YOU CAN DO
YOU CAN’T DO
CC = R1 == R2
CC = (R1 == R2);
YOU CAN DO
YOU CAN’T DO
CC = R1 < 3;
CC = R1 < 15; (too big)
only 3-bits available in “this” signed CC instruction – test -4 to +3



BUT YOU CAN DO
the two instruction operation
(I always do this one)
R2 = 15;
CC = R1 < R2;
YOU CAN DO
YOU CAN’T DO
CC = R1 < -3;
CC = R1 < -3 (IU);
only 3-bits available in “this” unsigned CC instruction – test 0 to +7
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
14 / 27
WHAT ARE WE TRYING TO DO?
IS IT LEGAL SYNTAX OR NOT?




CC = R1 < 2;
CC = R1 < 9 ;
CC = R1.L < 2 ;
CC = R1.L < 9 ;
// Attempting to test 32-bit DATA register
// Attempting to test 32-bit register
// Attempting to test 16-bit register
// Attempting to test 16-bit register
CC = P3 <= P4;
CC = P3 < 0x44;
// Attempting to test 32-bit POINTER register
// Attempting to test 32-bit POINTER register

R3 = 1;
CC = R3;
// Putting TRUE value into R3?

R4 = R5 – R6; // Math operations – sets the Arithmetic Zero flag


CC = AZ;
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
15 / 27
Now you have enough information to
code “while” operations in Blackfin
Translate line-by-line
sum_R0 = 0;
counter_R1 = 0;
max_count_R2 = 15;
WHILE: CC = counter_R1 <=
max_count_R2;
IF !CC JUMP ENDWHILE:
// Loop body
sum_R0 = sum_R0 + counter_R1;
counter_R1 = counter_R1 + 1;
JUMP WHILE;
int counter = 0;
WHILE: IF (counter <= 15)
then JUMP to ENDWHILE label
ELSE {
sum += counter;
counter++;
JUMP to WHILE label
}
ENDWHILE:
END_WHILE: // First instruction past loop
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
16 / 27
Code the do-while loop
sum_R0 = 0;
counter_R1 = 0;
max_count_R2 = 15;
DO_WHILE:
DO_WHILE
int counter = 0;
do {
sum += counter;
counter++;
} while (counter <= 15);
}
// Loop body
sum_R0 = sum_R0 + counter_R1;
counter_R1 = counter_R1 + 1;
CC = counter_R1 <=
max_count_R2;
IF CC JUMP DO_WHILE:
END_DO_WHILE:
// First instruction past loop
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
17 / 27
Are there advantages for a Dowhile loop with an initial test?
WHILE
int counter = 0;
while (counter <= 15) {
sum += counter;
counter++;
}
JUMPS NEEDED IN RED
DO_WHILE
int counter = 0;
do {
sum += counter;
counter++;
} while (counter <= 15)
4/9/2015
FASTEST LOOP
DO_WHILE WITH INITIAL TEST
int counter = 0;
// Unknown value in “avalue”
if (counter > avalue) {
do {
sum += counter;
counter++;
} while (counter <= avalue)
}
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
18 / 27
Code the do-while loop with
initial test
DO_WHILE WITH INITIAL TEST
unsigned short int counter = 0;
if (counter > timeToUse) {
do {
counter++;
} while (counter <= timeToUse)
}
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
19 / 27
Questions to answer at a later time
Speed -- timing issues




Number of instructions in do-while loop
function
Number of instructions in while loop function
Number of jump operations (each time
round the loop) with do-while loop function
Number of jump operations (each time
round the loop) with while loop function
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
20 / 27
Major problem

A major problem with any form of loop
is the “one-off” problem



You go round the loop one time too many
You go round the loop one time too few
Do any of the code examples in this
lecture suffer from this problem?
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
21 / 27
Blackfin “real” for-loops
Needed in Assignment 1
#define MAX_LOOP 26
int array[MAX_LOOP];
int sum = 0;
for (counter = 0;
count <= MAX_LOOP;
count++) {
sum += array[counter];
}

Chapter 7
Form 1 – big loops
LOOP loop_name loop_counter
LOOP_BEGIN loop_name
LOOP_END loop_name
Form 2 – small loops
LSETUP (Begin_Loop, End_Loop) loop_counter
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
22 / 27
Blackfin “real” for-loops
Needed in Assignment 1
#define MAX_LOOP 26
int array[MAX_LOOP];
int sum = 0;
for (counter = 0;
count <= MAX_LOOP;
count++) {
sum += array[counter];
}

Chapter 7
Form 1 – big loops
LOOP loop_name loop_counter
LOOP_BEGIN loop_name
LOOP_END loop_name
Form 2 – small loops
LSETUP (Begin_Loop, End_Loop) loop_counter
Special loop control hardware registers
Loop_Top
LT1 and LT0 (address)
Loop_Bottom LB1 and LB0 (address)
Loop_Count LC1 and LC0 (number)
“Real” assembly language loops not found on all processors
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
23 / 27
Code the “big loop” format
#define MAX_LOOP 26
int array[MAX_LOOP];
int sum = 0;
for (counter = 0;
count <= MAX_LOOP;
count++) {
sum += array[counter];
}
4/9/2015
Form 1 – big loops
LOOP loop_name loop_counter
LOOP_BEGIN loop_name
LOOP_END loop_name
MORE DETAILS LATER
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
24 / 27
Code the “small loop” format
#define MAX_LOOP 26
int array[MAX_LOOP];
int sum = 0;
for (counter = 0;
count <= MAX_LOOP;
count++) {
sum += array[counter];
}
4/9/2015
Form 2 – small loops
LSETUP (Begin_Loop, End_Loop) loop_counter
MORE DETAILS LATER
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
25 / 27
Tackled Today



Differences in behaviour between
for-loops, while-loops, do-while-loops,
do-while loops with initial test
Conditional JUMP and
Conditional MOVE instructions
Setting the CC condition code register


4/9/2015
What you would like to do, and can
What you would like to do, but can’t
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
26 / 27

Information taken from Analog Devices On-line
Manuals with permission
http://www.analog.com/processors/resources/technicalLibrary/manuals/

Information furnished by Analog Devices is believed to
be accurate and reliable. However, Analog Devices
assumes no responsibility for its use or for any
infringement of any patent other rights of any third party
which may result from its use. No license is granted by
implication or otherwise under any patent or patent right
of Analog Devices. Copyright  Analog Devices, Inc. All
rights reserved.
4/9/2015
Building a simple loop using Blackfin assembly code
Copyright M. Smith, University of Calgary, Canada
27 / 27