cancel
Showing results for 
Search instead for 
Did you mean: 

Cosmic compiler producing wrong asm

mchahn
Senior

I couldn't find a forum for the cosmic compiler. If anyone knows of one let me know and I'll ask there instead.

I have code that is compiling wrong. A function has a u16 parameter and that param is being referenced as u8. This is the declaration of the function ...

u16 getTempFromAdcCount(u16 count);

This is the function ...

u16 getTempFromAdcCount(u16 count) {
  u8 countOfs, lowIdx, idxOfs;
  u16 lowTemp, hiTemp, tempDiff;
  if(count  < MIN_ADC_COUNT) return 200*10;
  if(count >= MAX_ADC_COUNT) return 0;
  count -= MIN_ADC_COUNT;
  lowIdx   = countOfs >> DELTA_SHIFT;
  idxOfs   = countOfs  & DELTA_MASK;
  hiTemp   = tempTable[lowIdx];
  if(idxOfs == 0) 
    return hiTemp;
  lowTemp  = tempTable[lowIdx+1];
  tempDiff = hiTemp - lowTemp;
  return hiTemp - ((tempDiff * idxOfs) >> DELTA_SHIFT);
}

This is the call ...

  temp = getTempFromAdcCount(adjCount);

This is the asm for the call. Note that the param is correctly pushing u16 on the stack ...

 106                     ; 23   temp = getTempFromAdcCount(adjCount);
 108  0023 1e01          	ldw	x,(OFST-1,sp)
 109  0025 cd0000        	call	_getTempFromAdcCount
 111  0028 1f01          	ldw	(OFST-1,sp),x

And this is the incorrect asm for the function being called. Note that it is treating the param as u8 ...

 225  0000               _getTempFromAdcCount:
 227  0000 89            	pushw	x
 228  0001 5208          	subw	sp,#8
 229       00000008      OFST:	set	8
 232                     ; 147   if(count  < MIN_ADC_COUNT) return 200*10;
 234  0003 a30020        	cpw	x,#32
 235  0006 2405          	jruge	L75
 238  0008 ae07d0        	ldw	x,#2000
 240  000b 2008          	jra	L6
 241  000d               L75:
 242                     ; 148   if(count >= MAX_ADC_COUNT) return 0;
 244  000d 1e09          	ldw	x,(OFST+1,sp)
 245  000f a30388        	cpw	x,#904
 246  0012 2504          	jrult	L16
 249  0014 5f            	clrw	x
 251  0015               L6:
 253  0015 5b0a          	addw	sp,#10
 254  0017 81            	ret
 255  0018               L16:
 256                     ; 149   countOfs = count - MIN_ADC_COUNT;
 258  0018 7b0a          	ld	a,(OFST+2,sp)
 259  001a a020          	sub	a,#32
 260  001c 6b08          	ld	(OFST+0,sp),a
...snip...

Can anyone tell me what is going on?

6 REPLIES 6
mchahn
Senior

Correction. I showed asm for a different version of the code. Just note that this code in the function has the wrong asm ...

 256                     ; 149   countOfs = count - MIN_ADC_COUNT;
 258  0018 7b0a          	ld	a,(OFST+2,sp) <-- should be u16
 259  001a a020          	sub	a,#32
 260  001c 6b08          	ld	(OFST+0,sp),a

mchahn
Senior

And also, this is the definition of MIN_ADC_COUNT

#define MIN_ADC_COUNT    32 // index for adc count 32 is 0

countOfs is however a u8

Try

#define MIN_ADC_COUNT ((u16)32)

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mchahn
Senior

Yes, the left-side, countOfs, is a u8. But it should do the u16 arithmetic in 16-bit and then auto-convert the result to 8-bit to store in countOfs. I'll change countOfs to u16 but I still think the compiler is wrong. From a google search ...

  • All the data types of the variables are upgraded to the data type of the variable with largest data type.

Yeah, and you're probably using the optimizer.

The earlier code, does a min/max scoping, then masks and shifts.

Why on earth have an intermediate value that's not going to hold a number in the 32 .. 904 range, you're asking for some failure across the input number space.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thanks. It's a long story. Works fine now.