Jon, > >Some compilers can *reorder* a structure to better use > memory *without* > >a compromise in code quality. So, for instance: > > > >struct { char x; int y; char z; } > > > >would be reordered to > > > >struct { char x, z; int y; } > > > >removing two padding bytes, but having no size increase on compiled > >code size. > > But it cannot change it to: > > struct { char z, x; int y; } > > can it? > > My memory may be wrong about this. I do believe I know that > padding may not be inserted at the beginning of a structure, > under 6.7.2.1 (13). But is it possible to move the first > item from being the "first?" The reason I ask this is: If > no padding is allowed at the beginning and if it is also true > that the first item named in a structure declaration must > remain the logically first in terms of memory addressing, > then it follows that a pointer to the structure will compare > equal to a pointer to the first member of the structure, > suitably cast. > > Just curious if you recall the chapter and verse on this. I believe MIX C used to be able to do this. You are, however, correct that it is beyond the scope of the ANSI standard. Well, MIX C was never ANSI anyway, but it's one of those features ("extensions") that get bulleted as a "we do this, the competition doesn't". Section 6.2.7.1 para 13 of the C99 standard describes allocation order for structures. Bit OT, but in the spirit of C99, I like the restrict qualifier, but I fear it'll be used indiscriminantly. Electricity & water don't mix and, when a compiler does something the user doesn't expect, the compiler is declared "broken". It happens all the time--"My program compiles and runs correctly on hardware X with compiler Y but doesn't run on hardware Z with your compiler! My code is correct by example!" A compiler that ignores restrict will generate correct code given a restrict-broken program, but a compiler that doesn't ignore restrict when fed with that same program may generate code the user sees as wrong. C'est la vie. Give a user a sharp tool and he's bound to cut himself and blame the tool maker. -- Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk CrossWorks for MSP430 and ARM processors
C language tools to use with MSP430 or ...
Started by ●December 1, 2003
Reply by ●December 5, 20032003-12-05
Reply by ●December 5, 20032003-12-05
Seems Micro$oft is on the money grab again http://www.microsoft.com/mscorp/ip/tech/fat.asp It seems they want to now start charging for use of their FAT file system. Not good news... Matthew
Reply by ●December 5, 20032003-12-05
"...the ANSI standard is not clear at that point..." I disagree. The standard >>is<< clear; it is up to the compiler. To one of your further points: the packing may produce slower code, as has been pointed out. Someone else could crusade that packing makes it slower and the compiler is not providing proper value. Two sides of the coin. Lee --- In msp430@msp4..., r f <nobodyo@w...> wrote: > Hi, > > > The rationale is that the ANSI standard *only* specifies bit packing > > with unsigned int and signed int types, nothing else. > > Ok, the ANSI standard is not clear at that point and does not specifies > things like little endian or IEEE 754 format or the radix in which > numbers are represented but usually the same C source code is used on > PCs and MCs and therefore you usually expect that you can read/write > data produced from a MC with a PC. From a high price compiler like the > icc430 i do expect the same behaivior or a warning! Why else should > someone pay so much money? > > Maybe some other Compiler are not better at that point but the icc430 > has some other bugs which are showing that he is no ANSI compiler. One > of these bugs is than in sprintf the conversion specifier u does not > work; the compiled code simply prints the specifier (and the preceding > %) insted of the number although the conversion specifier u is in the > ANSI C standard! > As a working workaroung i use the specifier d insted of u. > > I#039;m sure i would find dozens of other bugs with a compiler test suite. > > Rolf F.
Reply by ●December 5, 20032003-12-05
"...Some compilers can *reorder* a structure to better use memory *without* a compromise in code quality. ..." ... and thus violate the ANSI requirement that structure fields be allocated in order. Lee --- In msp430@msp4..., "Paul Curtis" <plc@r...> wrote: > Jon, > > I'll cut the agreed bits; Anders has covered this more than a little. > Perhaps he's cursing the day he decided to join or stop trolling... ;-) > > > > >Thus, you could argue that a structure is allocated like this: > > > > > >struct { > > > TUINT8 lP; // byte 0 > > > TUINT8 lW; // byte 1 > > > TUINT8 lT; // byte 2 > > > TUINT16 te:5; // bits 7-3 of byte 3 > > > TUINT16 de:3; // bits 2-0 of byte 3 > > > TUINT16 ct; // bytes 4 and 5 > > >}; > > > > Yes, except my query wasn't about that. It was about > > aligning on even address boundaries, as in the VAX where you > > often found 4-byte objects aligned on 4-byte boundaries, > > 2-byte objects aligned on 2-byte boundaries, 8-byte objects > > aligned on 8-byte boundaries, and so on. So I was wondering > > about the possibility that the 8 bytes arrived from: > > > > >// structure assumed to always start on even addresses, as it's // > > >largest atom is a 2-byte object.... struct { > > > TUINT8 lP; // byte 0 1-byte alignment rule > > > TUINT8 lW; // byte 1 1-byte alignment rule > > > TUINT8 lT; // byte 2 1-byte alignment rule > > > // byte 3 "pad" forced '.even' alignment > > > TUINT16 te:5; // part of byte 4..5 > > > TUINT16 de:3; // part of byte 4..5 > > > TUINT16 ct; // byte 6..7 > > >}; > > > > I'd considered a smaller packing, too, as you seem to be > > addressing... but that wasn't my question. I was only > > curious if it were possible that the compiler in question was > > using some kind of VAX-like alignment rules and, if so, if > > there was logic to that. > > Hmm, I thought the VAX didn't require alignment but would benefit from > alignment if aligned at runtime. > > > In other words, I was only trying to explain the 8-byte > > finding in my own mind. Not trying to argue that it should > > have been 6. > > Most (if not all) compilers by default allocate fields read > top-to-bottom (lexical order) as low-to-high data in memory order. > Anders correctly points out that a field that requires alignment may > lead to padding if not aligned at the point it's seen. On the MSP430 an > int requires word alignment (even address). In the example, the int > fields aren't word aligned hence the forced alignment and consequent > padding bytes. Anders also points out the possibility of "rounding" the > structure by adding extra padding bytes *after* the last member as the > alignment of the structure as a whole is equal to the maximal alignment > required by any of its members. This neatly deals with allocating array > elements correctly so their members are all aligned correctly. > > Some compilers can *reorder* a structure to better use memory *without* > a compromise in code quality. So, for instance: > > struct { char x; int y; char z; } > > would be reordered to > > struct { char x, z; int y; } > > removing two padding bytes, but having no size increase on compiled code > size. > > Some compilers implement packing (ahh, the infamous PACKED structures of > Pascal, the bane of my life) which will reduce the overall data size for > a program by packing data and disregarding its natural alignment > requirement, but this forces the compiler to generate much more code to > access the packed structures. The 68020 have BFEXTU and BFEXTS to do > bitfield extraction, which helped, but many other processors use > shifting and masking. The MSP430 isn't well endowed in the shift and > rotate department, rather unlike the 68K. I wish the MSP430 had a > barrel shifter and instructions to use it. > > -- > Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk > CrossWorks for MSP430 and ARM processors
Reply by ●December 5, 20032003-12-05
Clyde, > On Fri, Dec 05, 2003 at 02:39:32PM -0800, Jonathan Kirwan wrote: > > On Fri, 5 Dec 2003 21:29:15 -0000, Paul wrote: > > >would be reordered to > > > > > >struct { char x, z; int y; } > > > > > >removing two padding bytes, but having no size increase on > compiled > > >code size. > > > > But it cannot change it to: > > > > struct { char z, x; int y; } > > > > can it? > > Quite right Jon, the ordering of structure members is > guaranteed by the standard to be the same as the lexical > order. Not so with scalar variables, whose memory address > need bear no relationship with order in the source file. The fact remains that some compilers can reorder (MIX C); but these are not ANSI compilers. IAR's packed structures pretty much go against the grain of the ANSI/ISO standard, yet are a useful addition in a RAM-limited, FLASH-rich micro (such as the MSP430) where an app teeters on the edge of available RAM memory. -- Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk CrossWorks for MSP430 and ARM processors
Reply by ●December 5, 20032003-12-05
microbit wrote: > Hi Paul, > > I have noticed such behaviour, but I am talking specifically reading/writing processed > 16/32 bit stuff from/into char based arrays, which then can be written to another buffer > yet again (eg. for RF transfer). > This is totally dynamic, and depending on the user's program input can land in even > or odd addresses after tokenising. > Once it's done it's not so bad, but the initial "trapping" at various points in runtime > is woeful... ! I have no other choice there, not does the compiler/linker used. > > Cheers, > Kris > > ASM makes life easy in these circumstances, I do it all the time, mixing types, and taking advantage of the ability to do this. Could you not handle these difficult areas in asm? Al >>Actually, the linker *can* know whether an access will be to a >>word-aligned address or not in some cases. >> >>Consider the absolute, symbolic, and register-offset addressing mode on >>the stack using word addressing: >> >>(a) Absolute, coded as x(R0). x must be divisible by 2 to maintain word >>alignment of data. The linker can check this. >> >>(b) Symbolic, coded as x(PC). The PC is always word aligned, so x must >>be divisible by two to maintain word alignment. The linker can check >>this. >> >>(c) Stack-relative, coded as x(SP). The SP is always word aligned, so x >>must be divisible by two to maintain word alignment. The linker can >>check this. >> >>In many cases the linker can't check for problems as it doesn't know, at >>any given instance, whether a register value will be aligned correctly >>or not. >> >>Regards, >> >>-- >>Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk >>CrossWorks for MSP430 and ARM processors >> >> >> >> >> >> >>. >> >> >> >>">http://docs.yahoo.com/info/terms/ > > >
Reply by ●December 5, 20032003-12-05
Lee, > "...Some compilers can *reorder* a structure to better use memory > *without* a compromise in code quality. ..." > > ... and thus violate the ANSI requirement that structure fields be > allocated in order. Just to reiterate, I did not state that this behaviour was found in an ANSI compiler. However, an ANSI compiler might just consider a remark or note when compiling that reordering will bring down the size of the structure... -- Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk CrossWorks for MSP430 and ARM processors
Reply by ●December 5, 20032003-12-05
Al wrote :
> ASM makes life easy in these circumstances, I do
it all the time, mixing
> types, and taking advantage of the ability to do this. Could you not
> handle these difficult areas in asm?
Hi Al,
Ouch !
There comes the dreaded thorn.
Strangely, no, not in _my_ particular application because I'm already
"breaching"
ISO anyway, by giving a char array datatypes that are larger (int, long,
float), thus
I'm left high and dry.
But there is simply __no other__ way around it given the byte-based token
scheme.
Storing 16/32 bits anywhere in MSP430 memory incurs this problem.
ASM will not help, *maybe* if it is painstakingly optimised to run faster
with 8 bit operations
than the C 16-bit LIB code (which will run much faster anyway, and is also
ASM hand written)
BUT, I'll go on a limb here, and volunteer that in fact the whole project
would be
slightly more RAM efficient in ASM, but it was specifically intended to be
very portable.
(where actually 60% of the work was :-)
It must be stressed though that is a very _unusual_ exception.
(the RAM savings are only 30-40 bytes though !)
So, basically this is finally "the exception to the rule", and in fact
I
will admit that if
you started the full scope of the task in ASM while I started in C,
you'd probably finish it 3 times faster than me !!
___BUT___ after that it will take me 30 seconds to land it on any 8 bit MCU,
it will take
you much longer than that on a new MCU ....
I hope I haven't started up another Pandora's box, but actually have
closed
one
vis-a-vis ASM vs. C ....
But I'm forthcoming too, and will grant you your _salient_ point Al !!!
Best regards,
Kris
Reply by ●December 5, 20032003-12-05
On Sat, 6 Dec 2003 08:58:27 +1000, Clyde wrote: >On Fri, Dec 05, 2003 at 02:39:32PM -0800, Jonathan Kirwan wrote: >> On Fri, 5 Dec 2003 21:29:15 -0000, Paul wrote: >> >would be reordered to >> > >> >struct { char x, z; int y; } >> > >> >removing two padding bytes, but having no size increase on compiled code >> >size. >> >> But it cannot change it to: >> >> struct { char z, x; int y; } >> >> can it? > >Quite right Jon, the ordering of structure members is guaranteed >by the standard to be the same as the lexical order. Not so with >scalar variables, whose memory address need bear no relationship >with order in the source file. Yes, or even function parameter values which do not have to be placed in some specific packing on the stack. If this weren't the case, then (granting me a little room here): void xy0 (int a, int b, int c) { auto int* c= &a; /* ... */ } void xy1 (int a, int b, int c) { auto int c= a; /* ... */ } If the compiler chooses to implement function calls like this with register passing, then xy0() code will need to "spill" the 'a' parameter value into the local stack frame so that an address can be taken. But no way will this address likely be next to the address of 'b' which is still in a register and not in memory at all. Also, my reading of 6.7.2.1 (13): "Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning." Says to me that a pointer to the structure also points to its initial member, precluding the possibility of moving the first element anywhere else. Also, that members have addresses which are in increasing magnitude (as regards >, I suppose) in the order in which they were declared, adding yet another restriction on what a compiler can do with a structure. So all this together tells me that a structure must not start with padding, must order the members with increasing addresses in cases where taking an address of them is valid at all, and that the address of the first member of a structure must also be the address of the structure itself. I think. >As far as padding goes, it may be inserted anywhere except at >the beginning. On the msp430 it is *necessary* to word-align >structure members, and to pad structure sizes to even numbers >of bytes. > >Trust me on this, I've been doing it for 25 years. Just curious, and it's probably "unspecified" behavior in C, but what happens when you cast a char* to an int* and then use it? I'm guessing that no MSP430 compiler even attempts to deal with this as forcing a pointer adjustment to an even address would seem problematic and so would causing the code generator to decide to generate byte-mode access code for accessing the integers. It's just left as a "bad thing to do." It would be interesting to see if there could be a valid combination of union and struct which could cause problems, while at the same time having _specified_ behavior under the C standards. Nothing comes immediately to mind, though. >Anyone who expects to be able to transfer data from one >architecture to another just by copying structures is in for >a nasty surprise, sooner or later. Yup. Jon
Reply by ●December 5, 20032003-12-05
On Fri, 5 Dec 2003 23:17:44 -0000, Paul wrote:
>Jon,
>
>> >Some compilers can *reorder* a structure to better use
>> memory *without*
>> >a compromise in code quality. So, for instance:
>> >
>> >struct { char x; int y; char z; }
>> >
>> >would be reordered to
>> >
>> >struct { char x, z; int y; }
>> >
>> >removing two padding bytes, but having no size increase on compiled
>> >code size.
>>
>> But it cannot change it to:
>>
>> struct { char z, x; int y; }
>>
>> can it?
>>
>> My memory may be wrong about this. I do believe I know that
>> padding may not be inserted at the beginning of a structure,
>> under 6.7.2.1 (13). But is it possible to move the first
>> item from being the "first?" The reason I ask this is: If
>> no padding is allowed at the beginning and if it is also true
>> that the first item named in a structure declaration must
>> remain the logically first in terms of memory addressing,
>> then it follows that a pointer to the structure will compare
>> equal to a pointer to the first member of the structure,
>> suitably cast.
>>
>> Just curious if you recall the chapter and verse on this.
>
>I believe MIX C used to be able to do this. You are, however, correct
>that it is beyond the scope of the ANSI standard. Well, MIX C was never
>ANSI anyway, but it's one of those features ("extensions")
that get
>bulleted as a "we do this, the competition doesn't". Section
6.2.7.1
>para 13 of the C99 standard describes allocation order for structures.
>
>Bit OT, but in the spirit of C99, I like the restrict qualifier, but I
>fear it'll be used indiscriminantly. Electricity & water
don't mix and,
>when a compiler does something the user doesn't expect, the compiler is
>declared "broken". It happens all the time--"My program
compiles and
>runs correctly on hardware X with compiler Y but doesn't run on
hardware
>Z with your compiler! My code is correct by example!" A compiler that
>ignores restrict will generate correct code given a restrict-broken
>program, but a compiler that doesn't ignore restrict when fed with that
>same program may generate code the user sees as wrong. C'est la vie.
>Give a user a sharp tool and he's bound to cut himself and blame the
>tool maker.
Well, it would be nice if you could require all your customers
to be well-trained and knowledgeable. But then, you'd probably
not be happy with the size of your customer base. So, if you
write for the common denominator of least skill I imagine you'll
write "blunt" tools where it's hard for your customers to hurt
themselves.
Meanwhile... do you think you could make good use of restrict on
an embedded target like the MSP430? If so, can you provide an
example?
Jon