Codewarrior for MCU 11.1 - inline assembler bug when zeroing DSC accumulator extension register

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Codewarrior for MCU 11.1 - inline assembler bug when zeroing DSC accumulator extension register

Jump to solution
763 Views
Lorenzo_Mch_IT
Contributor IV

The following source code exposes a bug in the inline assembler of DSC's compiler:

typedef unsigned long       UINT32;

inline void u64_SHR3(register UINT64 *RReg )
{
	register UINT32 AA;
	register UINT32 BB;
	__asm{
	move.l X:(RReg)+,AA
	move.l X:(RReg),BB
	move.w #0,BB.2
	asr BB
	ror.l AA
	asr BB
	ror.l AA
	asr BB
	ror.l AA
	move.l BB,X:(RReg)-
	move.l AA,X:(RReg)
	}
}

#define tick2mSec(tmp) {u64_SHR3(tmp);} // myRTC/8 --> time in mSec

 

It is an "optimized" triple right shift of a 64bit unsigned value, but when clearing the accumulator extension register, the generated code clears the whole 36bit accumulator:

 

;  100: 		tick2mSec(&tp); // 8Khz ticks to milliSeconds 
;
0x00000036  0x8AB4FFFB             adda        #-5,SP,R0
0x00000038  0x8121                 tfra        R0,R1
0x00000039  0xF021                 move.l      X:(R1)+,A
0x0000003A  0xF135                 move.l      X:(R1),B
0x0000003B  0xE180                 move.w      #0,B
0x0000003C  0x70EB                 asr         B
0x0000003D  0x7647                 ror.l       A
0x0000003E  0x70EB                 asr         B
0x0000003F  0x7647                 ror.l       A
0x00000040  0x70EB                 asr         B
0x00000041  0x7647                 ror.l       A
0x00000042  0xD131                 move.l      B10,X:(R1)-
0x00000043  0xD035                 move.l      A10,X:(R1)

 

Notice what happens at offset 0x0000003B:
instead of emitting an error because instruction move.w #0,B2 (clear upper 4bits of 36bit accumulator B ) DOES NOT EXIST, or replacing it with the functionally equivalent clr.w B2 ... 
the inline assembler emits move #0,B clearing the whole 36bit accumulator B.

The obvious workaround is to use clr.w, but NXP personell working on DSC's compiler should give a look at the root cause of this bug, maybe it's a symptom of worse bugs still lurking around in the inline assembler.

0 Kudos
1 Solution
727 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I am sorry for misunderstanding you, this is a bug of the compiler.

The assembly move.w #0,BB.2

should be translated as:

move.w #0,B2,

but it is translated as

move.w #0,B

I will report the issue to compiler team

Thank you for pointing out the bug.

BR

Xiangjun Rong

 

View solution in original post

3 Replies
730 Views
Lorenzo_Mch_IT
Contributor IV

Please excuse me, english is not my mother tongue; the issue is that the inline assembly instruction move.w #0,BB.2 is handled incorrectly by the compiler.

Instead of emitting move.w #0,B2, the inline assembler emits move.w #0,B and clears the whole accumulator B  (i.e. B2,B1 and B0).


I guess either there is a bug in inline assembler integrated in the compiler ( maybe related to how the inline assembler handles references to register variables declared in the same function? ).

0 Kudos
728 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I am sorry for misunderstanding you, this is a bug of the compiler.

The assembly move.w #0,BB.2

should be translated as:

move.w #0,B2,

but it is translated as

move.w #0,B

I will report the issue to compiler team

Thank you for pointing out the bug.

BR

Xiangjun Rong

 

747 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

You want to implement that  the B2(4 bits) is zero, while B1/B0 remain intact.

You can use the move.w #$0000, B2, it is okay.

Hope it can help you

BR

XiangJun Rong

xiangjun_rong_0-1692243732653.png

 

0 Kudos