EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Call for Compiler Samples

Started by Travis Goodspeed July 24, 2008
Howdy Y'all,

Sitting here in Knoxville, and I find myself pondering the question of
which MSP430 compiler was used to generate a particular piece of object
code that sits before me. As this is a common question for me, I'd like
to automate the process.

To that end, I'd be ever so grateful if a few of you would send me a
compiled binary of the following C program from your favorite compiler.
This will give me examples of the integer calling convention and a
switch(){}.

http://pastebin.com/f3643b46

Samples should be sent in the ihex format, with compiler version
information, to t...@utk.edu. Target any chip you like, and make any
changes necessary to get this to compile. Extra credit if I've not
heard of the compiler you use.

Personal observations of the differences in compiler output are also
welcome.

Cheers,
--Travis
short foo(short a, short b, short c){
return a+c;
}

short bar(short a){
switch(a){
case 0:
return abs(5);
case 1:
break;
case 2:
case 3:
return 256;
}
return 32;
}

void main(){
short a;
foo(1,2,3);
bar(a);
while(1);
}

Beginning Microcontrollers with the MSP430

I am pretending to be a c-compiler ;-)
My compiled object code consists of a single instruction:
JMP $
--- In m..., Travis Goodspeed wrote:
>
> Howdy Y'all,
>
> Sitting here in Knoxville, and I find myself pondering the question of
> which MSP430 compiler was used to generate a particular piece of object
> code that sits before me. As this is a common question for me, I'd like
> to automate the process.
>
> To that end, I'd be ever so grateful if a few of you would send me a
> compiled binary of the following C program from your favorite compiler.
> This will give me examples of the integer calling convention and a
> switch(){}.
>
> http://pastebin.com/f3643b46
>
> Samples should be sent in the ihex format, with compiler version
> information, to travis@... Target any chip you like, and make any
> changes necessary to get this to compile. Extra credit if I've not
> heard of the compiler you use.
>
> Personal observations of the differences in compiler output are also
> welcome.
>
> Cheers,
> --Travis
> short foo(short a, short b, short c){
> return a+c;
> }
>
> short bar(short a){
> switch(a){
> case 0:
> return abs(5);
> case 1:
> break;
> case 2:
> case 3:
> return 256;
> }
> return 32;
> }
>
> void main(){
> short a;
> foo(1,2,3);
> bar(a);
> while(1);
> }
>

Crosstudio 1.4 Build 1:
CODE SECTION CODE [LOAD=YES]

___begin_CODE

short foo(short a, short b, short c){

.ALIGN BYTE[2]
_foo
@20

return a+c;

0c4d MOV.W R13, R12
0c5f ADD.W R15, R12
0f4c MOV.W R12, R15
@21
@22
3041 RET
@23

short bar(short a){

_bar
LOCAL a @ R11
LOCAL a @ R11
0b12 PUSH.W R11
0b4f MOV.W R15, R11
@24

switch(a){

0f4b MOV.W R11, R15
2f92 CMP.W #4, R15
102c JC @25 ; = 1132
0f5f ADD.W R15, R15
104f1811 BR @26(R15)
@26
2011 DW @27
2a11 DW @28
2c11 DW @29
2c11 DW @29
@30
@27

return abs(5);

3f400500 MOV.W #5, R15
b0129e11 CALL #_abs
063c JMP @31 ; = 1136
@28

break;

033c JMP @25 ; = 1132
@29

return 256;

3f400001 MOV.W #0x100, R15
023c JMP @31 ; = 1136
@32
@25

return 32;

3f402000 MOV.W #0x20, R15
@33
@31
3b41 POP.W R11
3041 RET
@34

void main(void){

.ALIGN BYTE[2]
_main
LOCAL a @ R11
@35

foo(1,2,3);

1f43 MOV.W #1, R15
2e43 MOV.W #2, R14
3d400300 MOV.W #3, R13
b0120011 CALL #_foo

bar(a);

0f4b MOV.W R11, R15
b0120811 CALL #_bar
@36

while(1);

ff3f JMP @36 ; = 114C
@37
@38
3041 RET
@39

__reset proc

__reset

__reset proc

@40

mov.w #0x5a80, &0x120

b240805a2001 MOV.W #0x5a80, &0x120

mov.w #RAM_Start_Address+RAM_Size, sp

3140000a MOV.W #RAM_Start_Address + RAM_Size, SP

mov.w #SFB(IDATA0), r15

3f400000 MOV.W #___begin_IDATA0, R15

mov.w #data_init_begin, r14

3e40ae11 MOV.W #data_init_begin, R14

mov.w #data_init_end-data_init_begin, r13

3d400000 MOV.W #data_init_end - data_init_begin, R13

call #_memcpy

b0127e11 CALL #_memcpy

mov.w #SFB(UDATA0), r15

3f400000 MOV.W #___begin_UDATA0, R15

mov.w #0, r14

0e43 MOV.W #0, R14

mov.w #SFE(UDATA0)-SFB(UDATA0), r13

3d400000 MOV.W #___end_UDATA0 - ___begin_UDATA0, R13

call #_memset

b0128e11 CALL #_memset

call #_main

b0123a11 CALL #_main

jmp __reset

e93f JMP __reset ; = 1150

endproc

@41
_memcpy
0c4f MOV.W R15, R12
033c JMP L$1 ; = 1188
L$0
fc4e0000 MOV.B @R14+, 0(R12)
1c53 ADD.W #1, R12
L$1
1d83 SUB.W #1, R13
fb2f JC L$0 ; = 1182
3041 RET
_memset
0c4f MOV.W R15, R12
033c JMP L$1 ; = 1198
L$0
cc4e0000 MOV.B R14, 0(R12)
1c53 ADD.W #1, R12
L$1
1d83 SUB.W #1, R13
fb2f JC L$0 ; = 1192
3041 RET
_abs
0f93 CMP.W #0, R15
0534 JGE @42 ; = 11AC
0e4f MOV.W R15, R14
3ee3 XOR.W #-1, R14
1e53 ADD.W #1, R14
0f4e MOV.W R14, R15
3041 RET
@42
@43
3041 RET
___end_CODE

CONST SECTION CONST [LOAD=YES]

___begin_CONST
data_init_begin

.init "IDATA0"

.INIT "IDATA0"
data_init_end
___end_CONST

CODE SECTION INTVEC [LOAD=YES]

___begin_INTVEC

org 0x1e

ORG 30

dw __reset

5011 DW __reset
___end_INTVEC
Travis Goodspeed :

> Howdy Y'all,
>
> Sitting here in Knoxville, and I find myself pondering the question of
> which MSP430 compiler was used to generate a particular piece of object
> code that sits before me. As this is a common question for me, I'd like
> to automate the process.
>
> To that end, I'd be ever so grateful if a few of you would send me a
> compiled binary of the following C program from your favorite compiler.
> This will give me examples of the integer calling convention and a
> switch(){}.
>
> http://pastebin.com/f3643b46
>
> Samples should be sent in the ihex format, with compiler version
> information, to t...@utk.edu. Target any chip you like, and make any
> changes necessary to get this to compile. Extra credit if I've not
> heard of the compiler you use.
>
> Personal observations of the differences in compiler output are also
> welcome.
>
> Cheers,
> --Travis
> short foo(short a, short b, short c){
> return a+c;
> }
>
> short bar(short a){
> switch(a){
> case 0:
> return abs(5);
> case 1:
> break;
> case 2:
> case 3:
> return 256;
> }
> return 32;
> }
>
> void main(){
> short a;
> foo(1,2,3);
> bar(a);
> while(1);
> }
>
AQ430 C 2008/06/30:
; Archelon URCC C 3.27 2008/06/30
; MSP430 CIF 2008/01/07
; Compiled "travis.c" Sat Jul 26 00:00:47 2008
;
; short foo(short a, short b, short c){
.pseg travis_code
.global _foo
_foo:
; ENTRY
; a at argloc 0 (0x0) in reg size 2
; c at argloc 0 (0x0) in reg size 2
; return a+c;
add r14,r12
; EXIT
ret
; }
; ****** Warning: Symbol ``b'' (function foo) was defined, but not used

; short bar(short a){
.iseg travis_data_const
.align 0x2
.align 0x2
bar_LL4:
.data bar_L3
.data bar_L4
.data bar_L5
.data bar_L6
.pseg travis_code
.global _bar
_bar:
; ENTRY
; a at argloc 0 (0x0) in reg size 2
; switch(a){
jmp bar_L2
; case 0:
bar_L3:
; return abs(5);
mov #0x5,r12
call #_abs
jmp bar_LL2
; case 1:
bar_L4:
; break;
jmp bar_L1
; case 2:
bar_L5:
; case 3:
bar_L6:
; return 256;
mov #0x100,r12
jmp bar_LL2
bar_L2:
; swcode: switch has 4 cases - min 0 max 3
mov #0x3,r13
cmp r12,r13
jnc bar_LL3
rla r12
br bar_LL4(r12)
bar_LL3:
bar_L1:
; }
; return 32;
mov #0x20,r12
bar_LL2:
; EXIT
ret
; }
; void main(){
.global _main
_main:
; ENTRY
; a in reg size 2
; short a;
; foo(1,2,3);
mov #0x3,r14
mov #0x2,r13
mov #0x1,r12
call #_foo
; bar(a);
; }
; ****** Warning: Uninitialized variable "a" in main()
mov r4,r12
call #_bar
; while(1);
main_L1:
jmp main_L1
; EXIT
; .temp0 at stkloc 0 (0x0) size 2
ret
.extern _abs
> Sitting here in Knoxville, and I find myself pondering the question of
> which MSP430 compiler was used to generate a particular piece of object
> code that sits before me. As this is a common question for me, I'd like
> to automate the process.
>
> To that end, I'd be ever so grateful if a few of you would send me a
> compiled binary of the following C program from your favorite compiler.
> This will give me examples of the integer calling convention and a
> switch(){}.
>
> http://pastebin.com/f3643b46 Samples should be sent in the ihex format, with compiler version
> information, to t...@utk.edu . Target any
> chip you like, and make any
> changes necessary to get this to compile. Extra credit if I've not
> heard of the compiler you use.
>
> Personal observations of the differences in compiler output are also
> welcome.
>
> Cheers,
> --Travis
>
> short foo(short a, short b, short c){
> return a+c;
> }
>
> short bar(short a){
> switch(a){
> case 0:
> return abs(5);
> case 1:
> break;
> case 2:
> case 3:
> return 256;
> }
> return 32;
> }
>
> void main(){
> short a;
> foo(1,2,3);
> bar(a);
> while(1);
> }

Hi Travis!

Ok, here comes the IAR compiler, I just compiled this with the
--discard_unused_publics flag, and ended up with:

main:
MOV.W #0x5, R12
CALL #abs
??main_0:
JMP ??main_0
Clearly, this is not optimal since we all know that "abs" does not have
side effects. So I took the liberty of adding the line "#include
" and ended up with the following:

main:
??main_0:
JMP ??main_0

OK, ok -- using the --discard_unused_publics option is a bit like
cheating, I know, so here comes the real result:
3 short foo(short a, short b, short c){
\ foo:
4 return a+c;
\ 000000 0C5E ADD.W R14, R12
\ 000002 3041 RET
5 }
6

\ In segment CODE, align 2
7 short bar(short a){
\ bar:
8 switch(a){
\ 000000 0C83 SUB.W #0x0, R12
\ 000002 0524 JEQ ??bar_0
\ 000004 2C83 SUB.W #0x2, R12
\ 000006 0724 JEQ ??bar_1
\ 000008 1C83 SUB.W #0x1, R12
\ 00000A 0524 JEQ ??bar_1
\ 00000C 073C JMP ??bar_2
9 case 0:
10 return abs(5);
^
Warning[Pe223]: function "abs" declared implicitly
\ ??bar_0:
\ 00000E 3C400500 MOV.W #0x5, R12
\ 000012 3040.... BR #abs
11 case 1:
12 break;
13 case 2:
14 case 3:
15 return 256;
\ ??bar_1:
\ 000016 3C400001 MOV.W #0x100, R12
\ 00001A 3041 RET
16 }
17 return 32;
\ ??bar_2:
\ 00001C 3C402000 MOV.W #0x20, R12
\ 000020 3041 RET
18 }
19

\ In segment CODE, align 2
20 void main(){
\ main:
21 short a;
22 foo(1,2,3);
23 bar(a);
^
Warning[Pe549]: variable "a" is used before its value is set
\ 000000 3C400500 MOV.W #0x5, R12
\ 000004 B012.... CALL #abs
24 while(1);
\ ??main_0:
\ 000008 FF3F JMP ??main_0
25 }
Please note that the call to "bar" from main has been optimized away, so
the linker would not include "foo" and "bar" in case no other part of
your application used them.

Again, you could get rid of the calls to "abs" by including the right
header file...

-- Anders Lindgren, IAR Systems
--
Disclaimer: Opinions expressed in this posting are strictly my own and
not necessarily those of my employer.


The 2024 Embedded Online Conference