ARMv7-M assembly ITEE usage

时间:2016-08-31 17:01:37

标签: if-statement assembly arm branch lpc

  • Problem:

I'm trying to get the ITEE EQ ie 'If-Then-Else-Else Equal' block to work when R6==0, with THEN branching into the END label but the assembler called out an error on the line: BEQ END

  • Program info:

I'm doing a program that is in pertinence with Optimization. I'm using a Gradient Descent to converge to the point where gradient is 0 to find the solution x* that minimises some function f(x). I'm using C language to call an assembly function which is this program here.

Here is my program where the error is:

        CMP R6, #0          @ Compare f'(x) with 0
        ITEE EQ             @ If R6 == 0, Then-Else-Else
        BEQ END             @ Calls END label if equal
        SUBNE R0, R6        @ Change R0(x) in the opp direction of gradient to get lower value of f(x) if not equal
        BNE optimize        @ Branch to optimize if not equal

This is my first assembly program using the NXP LPC1769 for a school assignment. Do let me know what I'm missing or I have done wrong. Thank you!

Here is my whole program:

.syntax unified
.cpu cortex-m3
.thumb
.align 2
.global optimize
.thumb_func

optimize:
@  Write optimization function in assembly language here

        MOV R5, INLAMBDA    @ R5 holds value of inverse lambda(10) ie to eliminate floating point
        LDR R6, #2          @ Load R6 with value '2' ie constant of f'(x)
        MUL R6, R1, R6      @ Multiply R6(2) with R1(a) & store to R6(results)
        MLA R6, R6, R0, R2  @ Multiply R6(results) with R0(x) & sum with R2(b) to get f'(x). Store & update results to R6
        SDIV R6, R5         @ Divide R6(results) by R5(1/lambda) to get f'(x) * lambda

        CMP R6, #0          @ Compare f'(x) with 0
        ITEE EQ             @ If R6 == 0, Then-Else-Else
        BEQ END             @ Calls END label if equal
        SUBNE R0, R6        @ Change R0(x) in the opp direction of gradient to get lower value of f(x) if not equal
        BNE optimize        @ Branch to optimize if not equal

@  End label
END:

BX LR

@ Define constant values
CONST: .word 123
INLAMBDA: .word 10      @ Inverse lambda 1 / lambda(0.1) is 10

1 个答案:

答案 0 :(得分:2)

The problem is that BEQ END is in the middle of the IT block. To quote some documentation for IT:

A branch or any instruction that modifies the PC is only permitted in an IT block if it is the last instruction in the block.

That said, because it's a branch, the "else" is implicit anyway - if you take the branch, you won't be executing the following instructions on account of being elsewhere, and if you don't take it you've got no choice but to execute them, so there's no need for them to be explicitly conditional at all. In fact, you don't even need the IT either, since B<cond> has a proper Thumb instruction encoding in its own right. But then you also don't even need that, because you're doing a short forward branch based on a register being zero, and there's a specific Thumb-only compare-and-branch instruction for doing exactly that!

In other words, your initial 5-line snippet can be expressed simply as:

CBZ R6, END
SUB R0, R6
B optimize