2020-09-11 03:17 PM
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?
2020-09-11 03:26 PM
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
2020-09-11 03:29 PM
And also, this is the definition of MIN_ADC_COUNT
#define MIN_ADC_COUNT 32 // index for adc count 32 is 0
2020-09-11 03:36 PM
countOfs is however a u8
Try
#define MIN_ADC_COUNT ((u16)32)
2020-09-11 04:06 PM
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 ...
2020-09-11 06:24 PM
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.
2020-09-11 09:19 PM
Thanks. It's a long story. Works fine now.