From: Meindert Sprang on 7 Jun 2010 05:17 Unbelievable..... I'm playing around with the Microchip C18 compiler after a hair-splitting experience with CCS. Apparently the optimizer of C18 is not that good. For instance: LATF = addr >> 16; where addr is an uint32, is compiled into a loop where 4 registers really get shifted 16 times in a loop. Any decent compiler should recognise that a shift by 16, stored to an 8 bit port could easily be done by simply accessing the 3rd byte.... sheesh.... Meindert
From: D Yuniskis on 7 Jun 2010 14:51 Hi Meindert, Meindert Sprang wrote: > Unbelievable..... > > I'm playing around with the Microchip C18 compiler after a hair-splitting > experience with CCS. Apparently the optimizer of C18 is not that good. For > instance: LATF = addr >> 16; where addr is an uint32, is compiled into a > loop where 4 registers really get shifted 16 times in a loop. Any decent > compiler should recognise that a shift by 16, stored to an 8 bit port could > easily be done by simply accessing the 3rd byte.... sheesh.... Is LATF *defined* as a uint8_t? (i.e., does the compiler *know* it can discard all but the lowest 8 bits?) Is uuint32_t *really* unsigned (and not a cheap hack to "long int")? I.e., can the compiler be confused (by the definition) to thinking it is signed and opting for a sign-preserving shift? How about: uint8_t pointer; pointer = (uint8_t *) &addr; LATF = pointer[2]; Clumsy, admittedly, but perhaps more obvious what's going on? (I would have added that this would be easy for an optimizer to reduce to an "addressing operation" but I also would have expected your shift to be recognized as an easy optimization!)
From: D Yuniskis on 7 Jun 2010 14:53 D Yuniskis wrote: > Hi Meindert, > > Meindert Sprang wrote: >> Unbelievable..... >> >> I'm playing around with the Microchip C18 compiler after a hair-splitting >> experience with CCS. Apparently the optimizer of C18 is not that good. >> For >> instance: LATF = addr >> 16; where addr is an uint32, is compiled into a >> loop where 4 registers really get shifted 16 times in a loop. Any decent >> compiler should recognise that a shift by 16, stored to an 8 bit port >> could >> easily be done by simply accessing the 3rd byte.... sheesh.... > > Is LATF *defined* as a uint8_t? (i.e., does the compiler *know* it > can discard all but the lowest 8 bits?) > > Is uuint32_t *really* unsigned (and not a cheap hack to "long int")? > I.e., can the compiler be confused (by the definition) to thinking > it is signed and opting for a sign-preserving shift? > > How about: > > uint8_t pointer; uint8_t *pointer; (sorry, too early in the morning to be writing code :> ) > pointer = (uint8_t *) &addr; > LATF = pointer[2]; > > Clumsy, admittedly, but perhaps more obvious what's going on? > (I would have added that this would be easy for an optimizer > to reduce to an "addressing operation" but I also would have > expected your shift to be recognized as an easy optimization!)
From: Joe Chisolm on 7 Jun 2010 15:35 On Mon, 07 Jun 2010 11:17:34 +0200, Meindert Sprang wrote: > Unbelievable..... > > I'm playing around with the Microchip C18 compiler after a > hair-splitting experience with CCS. Apparently the optimizer of C18 is > not that good. For instance: LATF = addr >> 16; where addr is an > uint32, is compiled into a loop where 4 registers really get shifted 16 > times in a loop. Any decent compiler should recognise that a shift by > 16, stored to an 8 bit port could easily be done by simply accessing the > 3rd byte.... sheesh.... > > Meindert From the Microchip supplied USB code POINTER addr; LATF = addr.bHigh; //simple and to the point If addr is static this will probably compile to a simple movff. If addr is on the stack it gets a little more complicated. #ifndef TYPEDEFS_H #define TYPEDEFS_H typedef unsigned char byte; // 8-bit typedef unsigned int word; // 16-bit typedef unsigned long dword; // 32-bit typedef union _BYTE { byte _byte; struct { unsigned b0:1; unsigned b1:1; unsigned b2:1; unsigned b3:1; unsigned b4:1; unsigned b5:1; unsigned b6:1; unsigned b7:1; }; } BYTE; typedef union _WORD { word _word; struct { byte byte0; byte byte1; }; struct { BYTE Byte0; BYTE Byte1; }; struct { BYTE LowB; BYTE HighB; }; struct { byte v[2]; }; } WORD; #define LSB(a) ((a).v[0]) #define MSB(a) ((a).v[1]) typedef union _DWORD { dword _dword; struct { byte byte0; byte byte1; byte byte2; byte byte3; }; struct { word word0; word word1; }; struct { BYTE Byte0; BYTE Byte1; BYTE Byte2; BYTE Byte3; }; struct { WORD Word0; WORD Word1; }; struct { byte v[4]; }; } DWORD; #define LOWER_LSB(a) ((a).v[0]) #define LOWER_MSB(a) ((a).v[1]) #define UPPER_LSB(a) ((a).v[2]) #define UPPER_MSB(a) ((a).v[3]) typedef void(*pFunc)(void); typedef union _POINTER { struct { byte bLow; byte bHigh; }; word _word; // bLow & bHigh byte* bRam; // Ram byte pointer: 2 bytes pointer pointing // to 1 byte of data word* wRam; // Ram word poitner: 2 bytes poitner pointing // to 2 bytes of data rom byte* bRom; // Size depends on compiler setting rom word* wRom; } POINTER; typedef enum _BOOL { FALSE = 0, TRUE } BOOL; #define OK TRUE #define FAIL FALSE #endif //TYPEDEFS_H -- Joe Chisolm Marble Falls, Tx.
From: George Neuner on 7 Jun 2010 15:36 On Mon, 7 Jun 2010 11:17:34 +0200, "Meindert Sprang" <ms(a)NOJUNKcustomORSPAMware.nl> wrote: >Unbelievable..... > >I'm playing around with the Microchip C18 compiler after a hair-splitting >experience with CCS. Apparently the optimizer of C18 is not that good. For >instance: LATF = addr >> 16; where addr is an uint32, is compiled into a >loop where 4 registers really get shifted 16 times in a loop. Any decent >compiler should recognise that a shift by 16, stored to an 8 bit port could >easily be done by simply accessing the 3rd byte.... sheesh.... > >Meindert You're asking a lot. I've been programming since 1977 and I have never seen any compiler turn a long word shift (and/or mask) into a corresponding short word or byte access. Every compiler I have ever worked with would perform the shift. That said, something is wrong if it takes 4 registers. I don't know the PIC18, but I never encountered any chip that required more than 2 registers to shift a value. Many chips have only a 1-bit shifter and require a loop to do larger shifts - but many such chips microcode the shift loop so the programmer sees only a simple instruction. But, occasionally, you do run into oddballs that need large shifts spelled out. Most likely you're somehow reading the (dis)assembly incorrectly: 4 temporaries that are really mapped into the same register. If the compiler (or chip) really does need 4 registers to do a shift, then it's a piece of sh*t. George
|
Next
|
Last
Pages: 1 2 3 4 5 6 7 Prev: Which is the better method to use "if else" statements Next: need advice on device design |