Read-Only Author Bernhard Lechleitner Posted 21-Nov-2005 16:02 GMT Toolset C166 |  Bug in void* handling? (C166 V6.03) Bernhard Lechleitner Hello All!
I have a function which receives a void*:
static dword queue[QUEUE_CNT][QUEUE_LEN];
static byte widx[QUEUE_CNT];
byte PutQueueItem( byte queueId, void* pItem )
{
dword* pq = &queue[queueId][0];
byte* pw = &widx[queueId];
...
pq[*pw] = *(dword*)pItem;
...
The compiler generated code is:
37: byte PutQueueItem( byte queueId, void* pItem )
000446B6 ECFD PUSH R13
000446B8 ECFE PUSH R14
000446BA ECFF PUSH R15
...
pq[*pw] = *(dword*)pItem;
000445C8 DC5A EXTP R10,#2
000445CA D4990200 MOV R9,[R9+#0x0002]
000445CE A889 MOV R8,[R9]
000445D0 DC43 EXTP R3,#1
...
The generated code causes an illegal word access trap at 0x445CE because the statement at 0x445CA loads 0x0045 into R9. In my opinion the second and third line have to be swaped because R9 is no longer the offset of the void*. If I make the code like followed:
...
static dword* pdw;
...
pdw = (dword*)pItem;
pq[*pw] = *pdw;
I get the following result which is working:
46: pdw = (dword*)pItem;
000445C8 F6F93AB3 MOV DPP2:0x333A,R9
000445CC F6FA3CB3 MOV DPP2:0x333C,R10
47: pq[*pw] = *pdw;
000445D0 F2F53CB3 MOV R5,DPP2:0x333C
000445D4 F2F43AB3 MOV R4,DPP2:0x333A
000445D8 DC55 EXTP R5,#2
...
C166 V5.05 generates the followig code which works:
37: byte PutQueueItem( byte queueId, void* pItem )
000446B6 ECFD PUSH R13
000446B8 ECFE PUSH R14
000446BA ECFF PUSH R15
000446BC F0BA MOV R11,R10
000446BE F0A9 MOV R10,R9
....
48: pq[*pw] = *(dword*)pItem;
000446F8 DC5B EXTP R11,#2
000446FA A88A MOV R8,[R10]
000446FC D49A0200 MOV R9,[R10+#0x0002]
00044700 DC43 EXTP R3,#1
...
What does the specialists think? At the moment I have the feeling that the version 6 is not yet stable so I will switch back to 5.05 for the moment.
Best regards,
Bernhard Lechleitner |
Read-Only Author Mike Kleshov Posted 21-Nov-2005 16:48 GMT Toolset C166 |  RE: Bug in void* handling? (C166 V6.03) Mike Kleshov Hmm, interesting. In the release notes for C166 v6.0 it says:
Improved Register Variable Lifetime Analysis so that more optimal registers are used for automatic variables. This optimization improves execution speed and code density. On some functions, this optimization improves the code density and execution speed up to 20%.
Many times I saw unnecessary use of temporary storage registers in the code generated by C166. Looks like this new feature addresses that. When introducing this kind of major changes into a compiler, there is always a danger that it will start emitting incorrect code. Looks like that's what happened here.
It's pure speculation, so I could be completely wrong, of course.
- mike |