I have the same code in 2 different projects, in the main loop of both. This section of code has a switch statement in it, but in one project, it works, and the other it doesn't(always goes to the first case). The code is identical except for some port changes due to outputs being different on the two chips. The one that works uses the void NEAR _CASE_CHECKED (void) routine, where the one that doesn't uses the void NEAR _CASE_CHECKED_BYTE (void) routine. See code below. Both are from the file rtshc12.c. The difference between the two projects is that one is for the s12dp256B, and the other is for the s12DJ128B. Why would this compile into two different types of checks, and what can I do to fix this issue? Any help you can give would be appreciated. Tim *----------------- CASE_CHECKED - ---------- Parameters: - unsigned jump-index in the D Register - table starting at the return address Result : - Y remains unchanged table starts at the return address 2 bytes: N ; number of entries 2 bytes: AddrD ; default label 2 bytes: Addr0 ; jump address for entry 0 2 bytes: Addr1 ; jump address for entry 1 .... 2 bytes: AddrN ; jump address for entry N */ /* * Works with this one * */ #ifdef __cplusplus extern "C" #endif #pragma NO_FRAME #pragma NO_ENTRY #pragma NO_EXIT void NEAR _CASE_CHECKED (void) { asm { PULX ; load address of search table CPD 4, X+ ; compare maximal entrie BLO def ; branch to a defined label LDD #-1 ; load offset of default label def: LSLD ; offset*=2 _SRET ; debug info only: This is the last instr of a function with a special return JMP [D, X] ; jump to selected label } } /* * Doesnt' work with this one * */ #ifdef __cplusplus extern "C" #endif #pragma NO_FRAME #pragma NO_ENTRY #pragma NO_EXIT void NEAR _CASE_CHECKED_BYTE (void) { asm { PULX ; load address PSHB #if DO_NOT_USE_TEST_BRANCHES LEAX 2, X TSTA BNE defa ; branch if value > 0xff CMPB 0, X ; compare low byte BLO jump ; branch if value < #entries #else CMPB 2, X+ ; compare low byte TBNE A, defa ; branch if value > 0xff BLO jump ; branch if value < #entries #endif defa: LDAB -1, X ; select default entry, address = X-1 BRA sum jump: LDAB B, X ; load branch offset sum: LEAX B, X PULB _SRET ; debug info only: This is the last instr of a function with a special return JMP 0, X ; jump to selected entry } } |
|
CodeWarrior and Switch statment compiling issue
Started by ●September 4, 2003
Reply by ●September 5, 20032003-09-05
There are various options in the compiler to control the code generated for switch tables: -CswMaxLF -CsWMinLB -CswMinLF -CsMinSLB My guess is that even with the same source code, the number and kind of labels for the switch are different in your code (e.g. controlled by preprocessor macros)? With different input, the compiler will generate different code/strategies for it. Erich > -----Original Message----- > From: Tim Raabe [mailto:] > Sent: Donnerstag, 4. September 2003 18:23 > To: > Subject: [68HC12] CodeWarrior and Switch statment compiling issue > I have the same code in 2 different projects, in the main loop of > both. This section of code has a switch statement in it, but in one > project, it works, and the other it doesn't(always goes to the first > case). The code is identical except for some port changes due to > outputs being different on the two chips. > > The one that works uses the void NEAR _CASE_CHECKED (void) routine, > where the one that doesn't uses the void NEAR _CASE_CHECKED_BYTE > (void) routine. See code below. Both are from the file rtshc12.c. > The difference between the two projects is that one is for the > s12dp256B, and the other is for the s12DJ128B. > > Why would this compile into two different types of checks, and what > can I do to fix this issue? Any help you can give would be > appreciated. > > Tim > > *----------------- CASE_CHECKED - > ---------- > Parameters: > - unsigned jump-index in the D Register > - table starting at the return address > > Result : > - Y remains unchanged > > table starts at the return address > 2 bytes: N ; number of entries > 2 bytes: AddrD ; default label > 2 bytes: Addr0 ; jump address for entry 0 > 2 bytes: Addr1 ; jump address for entry 1 > .... > 2 bytes: AddrN ; jump address for entry N > */ > > > /* > * Works with this one > * > */ > > #ifdef __cplusplus > extern "C" > #endif > #pragma NO_FRAME > #pragma NO_ENTRY > #pragma NO_EXIT > > void NEAR _CASE_CHECKED (void) { > asm { > PULX ; load address of search table > CPD 4, X+ ; compare maximal entrie > BLO def ; branch to a defined label > LDD #-1 ; load offset of default label > def: LSLD ; offset*=2 > _SRET ; debug info only: This is the last instr > of a function with a special return > JMP [D, X] ; jump to selected label > > } > } > /* > * Doesnt' work with this one > * > */ > #ifdef __cplusplus > extern "C" > #endif > #pragma NO_FRAME > #pragma NO_ENTRY > #pragma NO_EXIT > > void NEAR _CASE_CHECKED_BYTE (void) { > asm { > PULX ; load address > PSHB > #if DO_NOT_USE_TEST_BRANCHES > LEAX 2, X > TSTA > BNE defa ; branch if value > 0xff > CMPB 0, X ; compare low byte > BLO jump ; branch if value < #entries > #else > CMPB 2, X+ ; compare low byte > TBNE A, defa ; branch if value > 0xff > BLO jump ; branch if value < #entries > #endif > defa: LDAB -1, X ; select default entry, address = X-1 > BRA sum > jump: LDAB B, X ; load branch offset > sum: LEAX B, X > PULB > _SRET ; debug info only: This is the last instr > of a function with a special return > JMP 0, X ; jump to selected entry > } > } > > > -------------------- > > ">http://docs.yahoo.com/info/terms/ |
|
Reply by ●September 5, 20032003-09-05
Hi Tim, _CASE_CHECKED_BYTE is used if all the branch destinations (the cases) are within a 256 byte range. If the switch content generates more code, _CASE_CHECKED is used instead. I doubt a bit that the bug is inside of the _CASE_CHECKED_BYTE runtime support. Instead I would guess that the problem is on the calling side. Can you check what's in the D register when _CASE_CHECKED_BYTE is entered? Does it contain the right value? (Note the lowest case entry is 0, if you don't have a case 0, this is not directly the same value). Also you could send me off list an lst file generated by the compiler which contains the problematic _CASE_CHECKED_BYTE with a little description which value does not work so I can have a look. Bye Daniel > -----Original Message----- > From: Erich Styger [mailto:] > Sent: Friday, September 05, 2003 11:59 > To: > Subject: RE: [68HC12] CodeWarrior and Switch statment compiling issue > There are various options in the compiler to control > the code generated for switch tables: > -CswMaxLF > -CsWMinLB > -CswMinLF > -CsMinSLB > > My guess is that even with the same source code, the number > and kind of labels for the switch are different in your > code (e.g. controlled by preprocessor macros)? > With different input, the compiler will generate different > code/strategies for it. > > Erich > > > -----Original Message----- > > From: Tim Raabe [mailto:] > > Sent: Donnerstag, 4. September 2003 18:23 > > To: > > Subject: [68HC12] CodeWarrior and Switch statment compiling issue > > > > > > I have the same code in 2 different projects, in the main loop of > > both. This section of code has a switch statement in it, but in one > > project, it works, and the other it doesn't(always goes to the first > > case). The code is identical except for some port changes due to > > outputs being different on the two chips. > > > > The one that works uses the void NEAR _CASE_CHECKED (void) routine, > > where the one that doesn't uses the void NEAR _CASE_CHECKED_BYTE > > (void) routine. See code below. Both are from the file rtshc12.c. > > The difference between the two projects is that one is for the > > s12dp256B, and the other is for the s12DJ128B. > > > > Why would this compile into two different types of checks, and what > > can I do to fix this issue? Any help you can give would be > > appreciated. > > > > Tim > > > > *----------------- CASE_CHECKED - > > ---------- > > Parameters: > > - unsigned jump-index in the D Register > > - table starting at the return address > > > > Result : > > - Y remains unchanged > > > > table starts at the return address > > 2 bytes: N ; number of entries > > 2 bytes: AddrD ; default label > > 2 bytes: Addr0 ; jump address for entry 0 > > 2 bytes: Addr1 ; jump address for entry 1 > > .... > > 2 bytes: AddrN ; jump address for entry N > > */ > > > > > > > > > > /* > > * Works with this one > > * > > */ > > > > #ifdef __cplusplus > > extern "C" > > #endif > > #pragma NO_FRAME > > #pragma NO_ENTRY > > #pragma NO_EXIT > > > > void NEAR _CASE_CHECKED (void) { > > asm { > > PULX ; load address of search table > > CPD 4, X+ ; compare maximal entrie > > BLO def ; branch to a defined label > > LDD #-1 ; load offset of default label > > def: LSLD ; offset*=2 > > _SRET ; debug info only: This is the last instr > > of a function with a special return > > JMP [D, X] ; jump to selected label > > > > } > > } > > > > > > /* > > * Doesnt' work with this one > > * > > */ > > > > > > #ifdef __cplusplus > > extern "C" > > #endif > > #pragma NO_FRAME > > #pragma NO_ENTRY > > #pragma NO_EXIT > > > > void NEAR _CASE_CHECKED_BYTE (void) { > > asm { > > PULX ; load address > > PSHB > > #if DO_NOT_USE_TEST_BRANCHES > > LEAX 2, X > > TSTA > > BNE defa ; branch if value > 0xff > > CMPB 0, X ; compare low byte > > BLO jump ; branch if value < #entries > > #else > > CMPB 2, X+ ; compare low byte > > TBNE A, defa ; branch if value > 0xff > > BLO jump ; branch if value < #entries > > #endif > > defa: LDAB -1, X ; select default entry, address = X-1 > > BRA sum > > jump: LDAB B, X ; load branch offset > > sum: LEAX B, X > > PULB > > _SRET ; debug info only: This is the last instr > > of a function with a special return > > JMP 0, X ; jump to selected entry > > } > > } > > > > > > > > > > -------------------- > > > > > > > > ">http://docs.yahoo.com/info/terms/ > > > > > -------------------- > > ">http://docs.yahoo.com/info/terms/ |