-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
| Bugzilla Link | 6603 |
| Resolution | FIXED |
| Resolved on | May 01, 2010 07:29 |
| Version | 1.0 |
| OS | Linux |
| Attachments | Test case, asm at -O0, llvm bit code, binary |
| Reporter | LLVM Bugzilla Contributor |
| CC | @asl,@regehr |
Extended Description
Bug:
llvm assembly that contains the branch instruction 'br' uses the indexed addressing mode, instead of direct mode which is intended.
Description:
Let there be a branch from label A to label B. The code would be:
.L_A
br #.L_B
...
Some code that doesn't fit in the offset range of absolute jump. Hence branch instruction is used.
...
.L_B
mov #0, r15
ret
The msp430x1xx user guide specifies 7 addressing modes for 'br' instruction. The relevant ones are:
-
BR #EXEC
;Branch to label EXEC or direct branch (e.g. #0A4h)
; Core instruction MOV @PC+,PC -
BR EXEC
; Branch to the address contained in EXEC
; Core instruction MOV X(PC),PC
; Indirect address -
BR &EXEC
; Branch to the address contained in absolute
; address EXEC
; Core instruction MOV X(0),PC
; Indirect address
In the above example, we want to branch to a label (direct addressing mode) and hence we should use the first addressing mode (br #EXEC). For the same purpose, llvm generates code that uses second addressing mode (br EXEC).
Branch instructions are emulated as: br dst -> mov.w dst, pc
The llvm generated code gets translated to
mov.w $off(PC), PC
Here offset is an integer corresponding to the jump offset.
What actually happens: PC = mem[PC + offset]
Desired instruction: PC = PC + offset
Fix: Labels for branch instruction should be prefixed with '#' to make it direct addressing mode.
I am attaching all the relevant files. The test case is fairly big (55 lines) because 'br' instruction is generated only when the offset is huge. It shouldn't be a problem for this bug though.
Cmd line options:
pagariya@aleph:~/tmp$ clang -ccc-host-triple msp430-elf -I/home/pagariya/res-pagariya/llvm-msp430/msp430/include -nostdinc -v -O0 -S foo.c
clang version 1.1 (trunk 184)
Target: msp430-elf-
Thread model: posix
"/uusoc/facility/res/embed/users/pagariya/llvm-msp430/bin/clang" -cc1 -triple msp430-elf- -S -disable-free -main-file-name foo.c -mrelocation-model static -mdisable-fp-elim -mconstructor-aliases -v -nostdinc -resource-dir /uusoc/facility/res/embed/users/pagariya/llvm-msp430/lib/clang/1.1 -I/home/pagariya/res-pagariya/llvm-msp430/msp430/include -O0 -fmessage-length 102 -fgnu-runtime -fdiagnostics-show-option -fcolor-diagnostics -o foo.s -x c foo.c
clang -cc1 version 1.1 based upon llvm 2.7svn hosted on i386-pc-linux-gnu
#include "..." search starts here:
#include <...> search starts here:
/home/pagariya/res-pagariya/llvm-msp430/msp430/include
/uusoc/facility/res/embed/users/pagariya/llvm-msp430/lib/clang/1.1/include
End of search list.
pagariya@aleph:~/tmp$ clang -ccc-host-triple msp430-elf -L/home/pagariya/res-pagariya/llvm-msp430/lib/msp430 -L/home/pagariya/res-pagariya/llvm-msp430/msp430/lib -L/home/pagariya/res-pagariya/llvm-msp430/lib/gcc-lib/msp430/3.2.3 -Wl,-m,msp430x1611 -o foo.elf /home/pagariya/res-pagariya/llvm-msp430/msp430/lib/crt430x1611.o foo-asm.s -lgcc -v
clang version 1.1 (trunk 184)
Target: msp430-elf-
Thread model: posix
"/uusoc/facility/res/embed/users/pagariya/llvm-msp430/bin/msp430-as" -o /tmp/cc-tgCJbV.o foo-asm.s
"/uusoc/facility/res/embed/users/pagariya/llvm-msp430/bin/msp430-ld" -o foo.elf -L/home/pagariya/res-pagariya/llvm-msp430/lib/msp430 -L/home/pagariya/res-pagariya/llvm-msp430/msp430/lib -L/home/pagariya/res-pagariya/llvm-msp430/lib/gcc-lib/msp430/3.2.3 -m msp430x1611 /home/pagariya/res-pagariya/llvm-msp430/msp430/lib/crt430x1611.o /tmp/cc-tgCJbV.o -lgcc -L../lib/ -lcompiler_rt.Generic -lc
pagariya@aleph:~/tmp$ uname -a
Linux aleph 2.6.24-24-generic #1 SMP Fri Sep 18 16:49:39 UTC 2009 i686 GNU/Linux