I am using Code Warrior version 5.9.0, build 2836 for S12XE.
In my listing, below, I see the gnerated code needlessly reloading and resaving registers in the do loop that starts at source line 589.
I tried the -Or and -Ol options. -Or did not make a difference, but -Onr made things worse, so I assume -Or is a default.
-Ol3 helped, but the effect was equivalent to -Ol1. Only one of the 3 loop variables was "optimized".
Neither the presence nor absence of the "Register" qualifier made a difference. Nor did the location of the definitions of d and s.
Other observations: In source line 588, the compiler "remembers" that B was loaded with the needed value in line 581, but in line 590, it seems to have "forgotten".
Also, I noticed that the peephole optimizer removed the extranious "CPD #0" from source line 591, but not the extranious "LDD 0,SP"
(Just some observations.)
578: void DiagReadMemoryByAddress( uint32 address, uint16 len) 579: {Function: DiagReadMemoryByAddressSource : apdi.cOptions : -CPUHCS12XE -F2 -Lasm=%n.lst -LmCfg=ilmu -Mb -Ol3 -Onbf -OnPMNC -WmsgNu=abcet 0000 6ca9 [2] STD 5,-SP 580: /* Block reading code area */ 581: if ((uint8)(address >> 16) > 0x40) 0002 e689 [3] LDAB 9,SP 0004 c140 [1] CMPB #64 0006 2307 [3/1] BLS *+9 ;abs = 000f 582: { 583: DiagNRCInvalidKey(); // Closest error code to security violation 0008 c635 [1] LDAB #53 000a 7b0000 [3] STAB diagErrorCode 584: } 000d 201f [3] BRA *+33 ;abs = 002e 585: else 586: { 587: register uint8 * d = DiagBuffer + LengthServiceID + LengthAddressParameter; 000f fe0000 [3] LDX DiagBuffer 0012 1a05 [2] LEAX 5,X 588: register uint8 * __far s = (uint8 * __far)address; 0014 ed8a [3] LDY 10,SP 0016 6d83 [2] STY 3,SP 0018 6b82 [2] STAB 2,SP 589: do { 590: *d++ = *s++; 001a ed83 [3] LDY 3,SP 001c e682 [3] LDAB 2,SP 001e 5b10 [2] STAB /*GPAGE*/16 0020 18a670 [4] GLDAA 1,Y+ 0023 6a30 [2] STAA 1,X+ 0025 6d83 [2] STY 3,SP 591: } while (--len); 0027 186380 [4] DECW 0,SP 002a ec80 [3] LDD 0,SP 002c 26ec [3/1] BNE *-18 ;abs = 001a 592: } 593: DiagDataLength = len; 002e ecb4 [3] LDD 5,SP+ 0030 7c0000 [3] STD DiagDataLength 594: } 0033 0a [7] RTC
I don't know how to force loop variables to registers, it seems you know all required switches. But using
#pragma PAGE_UPDATE OFF // see Release_Notes_HC12.chm in Help folder
you could remove
001c e682 [3] LDAB 2,SP
001e 5b10 [2] STAB /*GPAGE*/16
from the loop. Of course GPAGE has to be setup before the loop.
Kef, thanks. Handy to know how to get at least the GPAGE update out of the loop.
That did give me the thought that the one pointer being a far pointer might have inhibited fully optimizing the loop variables, though I'd still expect the other pointer to have been optimized. Not sure if I can get anywhere with this thought, but I will reread the sections about the various page registers. tomorrow.
Maybe make service request on this here . If there's no answer how to optimize loop variables in you case, then maybe Freescale will accept your request to improve compiler regarding subject.