This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/MSP-CGT: Braindead __swap_bytes intrinsic/macro.

Part Number: MSP-CGT

Tool/software: TI C/C++ Compiler

Given the following function:

#include <msp430.h>

extern unsigned char a, b;

unsigned int func(void)
{
    return a | __swap_bytes(b);
}

The compiler produces the following output:

;*****************************************************************************
;* FUNCTION NAME: func                                                       *
;*                                                                           *
;*   Regs Modified     : SP,SR,r12,r15                                       *
;*   Regs Used         : SP,SR,r12,r15                                       *
;*   Local Frame Size  : 0 Args + 0 Auto + 0 Save = 0 byte                   *
;*****************************************************************************
func:
;* --------------------------------------------------------------------------*
	.dwcfi	cfa_offset, 4
	.dwcfi	save_reg_to_mem, 16, -4
;** 8	-----------------------    return (unsigned)a|(unsigned)b>>8|(unsigned)b<<8;
	.dwpsn	file "../src/swpb.c",line 8,column 5,is_stmt,isa 0
        MOV.B     &a+0,r15              ; [] |8| 
        MOV.B     &b+0,r12              ; [] |8| 
        SWPB      r12                   ; [] |8| 
        MOV.B     r12,r12               ; [] |8| 
        OR.W      r12,r15               ; [] |8| 
        MOV.B     &b+0,r12              ; [] |8| 
        RPT #8 || RLAX.W r12 ; [] |8| 
        OR.W      r15,r12               ; [] |8| 
$C$DW$4	.dwtag  DW_TAG_TI_branch
	.dwattr $C$DW$4, DW_AT_low_pc(0x00)
	.dwattr $C$DW$4, DW_AT_TI_return

        RETA      ; [] 
        ; [] 
	.dwattr $C$DW$3, DW_AT_TI_end_file("../src/swpb.c")
	.dwattr $C$DW$3, DW_AT_TI_end_line(0x09)
	.dwattr $C$DW$3, DW_AT_TI_end_column(0x01)
	.dwendentry
	.dwendtag $C$DW$3

Clearly this should just be something like `MOV.B &a, r12; MOV.B &b, r15; SWPB r15; OR.W r15,r12`.

  • Thank you for reporting this problem, and for supplying a concise test case.  I can reproduce the same result.  I filed the entry EXT_EP-9611 to have this investigated.  To track it, please search for it at this link.  Note the code generated by the compiler is correct, but inefficient.  Therefore, the entry filed is not a bug report, but requests an improvement in the compiler. 

    Thanks and regards,

    -George

  • I discovered that changing the `|` to a `+` seems to solve the problem and is functionally equivalent so serves as an acceptable workaround for now.  The output code is now as follows:

    ;*****************************************************************************
    ;* FUNCTION NAME: func                                                       *
    ;*                                                                           *
    ;*   Regs Modified     : SP,SR,r12,r15                                       *
    ;*   Regs Used         : SP,SR,r12,r15                                       *
    ;*   Local Frame Size  : 0 Args + 0 Auto + 0 Save = 0 byte                   *
    ;*****************************************************************************
    func:
    ;* --------------------------------------------------------------------------*
    	.dwcfi	cfa_offset, 4
    	.dwcfi	save_reg_to_mem, 16, -4
    ;** 8	-----------------------    return (unsigned)a+((unsigned)b>>8|(unsigned)b<<8);
    	.dwpsn	file "../src/swpb.c",line 8,column 5,is_stmt,isa 0
            MOV.B     &a+0,r15              ; [] |8| 
            MOV.B     &b+0,r12              ; [] |8| 
            SWPB      r12                   ; [] |8| 
            ADD.W     r15,r12               ; [] |8| 
    $C$DW$4	.dwtag  DW_TAG_TI_branch
    	.dwattr $C$DW$4, DW_AT_low_pc(0x00)
    	.dwattr $C$DW$4, DW_AT_TI_return
    
            RETA      ; [] 
            ; [] 
    	.dwattr $C$DW$3, DW_AT_TI_end_file("../src/swpb.c")
    	.dwattr $C$DW$3, DW_AT_TI_end_line(0x09)
    	.dwattr $C$DW$3, DW_AT_TI_end_column(0x01)
    	.dwendentry
    	.dwendtag $C$DW$3
    

    Maybe this can help in figuring out how to resolve the issue for the `|` operator.  It would still be nice to have it fixed if possible.

  • Thank you for letting us know about another workaround.  I added a note about it to the entry for this issue.

    Thanks and regards,

    -George