Copying a bit from one bitfield to antother. Weird compiler behaviour.

Go To Last Post
29 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

It's been years since last time I was here, so I'll need to figure out how to use this new interface... :-D

 

For some reason (looong story), I started to look at code efficiency, regarding copying of a bit from one bitfield to another.

In some existing code, I made this example:

struct tTestBitfield
{
  unsigned char Bit0:1;
  unsigned char Bit1:1;
  unsigned char Bit2:1;
  unsigned char Bit3:1;
  unsigned char Bit4:1;
  unsigned char Bit5:1;
  unsigned char Bit6:1;
  unsigned char Bit7:1;
};

struct tTestBitfield TestSource;
struct tTestBitfield TestDestination;

(blah-blah...

TestDestination.Bit3=TestSource.Bit0;

I'm programming an XMEGA, A1 series, using AtmelStudio 7 (version 7.0.1645). Optimization is set to -Os. (Changing the optimization level made no difference.)

TestSource is copied from another variable, so the compiler can "see" that it is being loaded with something. TestDestination is used as a data byte in a binary, serial transmission, so the compiler won't just skip it.

 

Now, what I expect to see, is the contents of bit 0 in TestSource being copied to bit 3 in TestDestination. And it works nicely.

However, when the source is one of the other bits, some seemingly superfluous instructions are added, taking additional time when running.

 

This is the compiled result from the original:

          TestDestination.Bit3=TestSource.Bit0;
    3e38:	80 91 02 2c 	lds	r24, 0x2C02	; 0x802c02 <TestSource>
    3e3c:	20 91 3e 2a 	lds	r18, 0x2A3E	; 0x802a3e <TestDestination>
    3e40:	80 fb       	bst	r24, 0
    3e42:	23 f9       	bld	r18, 3
    3e44:	20 93 3e 2a 	sts	0x2A3E, r18	; 0x802a3e <TestDestination>

This is pretty simple. Load both bytes into registers, grab bit 0 from the source, put it into bit 3 in the destination, store destination. I find it difficult to make a faster version myself.

 

But now...

          TestDestination.Bit3=TestSource.Bit1;
    3e38:	80 91 02 2c 	lds	r24, 0x2C02	; 0x802c02 <TestSource>
    3e3c:	86 95       	lsr	r24
    3e3e:	81 70       	andi	r24, 0x01	; 1
    3e40:	20 91 3e 2a 	lds	r18, 0x2A3E	; 0x802a3e <TestDestination>
    3e44:	80 fb       	bst	r24, 0
    3e46:	23 f9       	bld	r18, 3
    3e48:	20 93 3e 2a 	sts	0x2A3E, r18	; 0x802a3e <TestDestination>

Now, the source bit is bit 1.

The source byte is shifted right, even though bst r24,1 should work perfectly. And the andi r24, 0x01 instruction simply doesn't do anything useful. The seven bits that are masked out, aren't used anyway, so blanking them isn't necessary.

According to this site, bst (and bld) should work with all registers and all bits:  https://www.microchip.com/webdoc/avrassembler/avrassembler.wb_BST.html

 

It gets more weird:

          TestDestination.Bit3=TestSource.Bit2;
    3e38:	80 91 02 2c 	lds	r24, 0x2C02	; 0x802c02 <TestSource>
    3e3c:	82 fb       	bst	r24, 2
    3e3e:	88 27       	eor	r24, r24
    3e40:	80 f9       	bld	r24, 0
    3e42:	20 91 3e 2a 	lds	r18, 0x2A3E	; 0x802a3e <TestDestination>
    3e46:	80 fb       	bst	r24, 0
    3e48:	23 f9       	bld	r18, 3
    3e4a:	20 93 3e 2a 	sts	0x2A3E, r18	; 0x802a3e <TestDestination>

Here, bst and bld are used for moving bit 2 to bit 0, before copying it to the destination bit.

A similar approach is used for bits 3, 5, 6, and 7.

 

This one, I find particularly creative. It was also the first oddity I encountered:

          TestDestination.Bit3=TestSource.Bit4;
    3e38:	80 91 02 2c 	lds	r24, 0x2C02	; 0x802c02 <TestSource>
    3e3c:	82 95       	swap	r24
    3e3e:	81 70       	andi	r24, 0x01	; 1
    3e40:	20 91 3e 2a 	lds	r18, 0x2A3E	; 0x802a3e <TestDestination>
    3e44:	80 fb       	bst	r24, 0
    3e46:	23 f9       	bld	r18, 3
    3e48:	20 93 3e 2a 	sts	0x2A3E, r18	; 0x802a3e <TestDestination>

Here, swap is used, to move bit 4 to bit 0. As in the other examples (except the first with bit 0), the other bits are thoroughly cleared.

 

I can imagine only one reason for the compiler to build my code this way.

My guess is, that the compiler splits the statement into two parts. First, the program needs to isolate bit n, and keep it in a location where it can find it again. Apparently, this must always be in bit 0. Only after this is done, the compiler starts looking at the destination variable. This action is almost completely split from the first part, so the compiler must rely on the bit being bit 0.

 

Do you people have any other ideas about this? Is there something I've missed, or is this behaviour expected?

I've tried searching the site for other posts about it, but haven't found anything.

 

Br, ErikT

You're absolutely right. This member is stupid. Please help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Which version of avr-gcc? I think the devs will only be interested if this is repeatable on the latest v10.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's generally the case that bitfields can't be relied upon to be efficient.

 

frown

 

Although it can be really useful / important for us in the "small microcontrollers"  corner of the 'C' world, it's probably a bit esoteric in the general 'C' scheme of things - hence it may not get high priority in "generalist" compilers like GCC.

 

This tends to be the kind of thing where the specialists - like IAR - win.

 

And they charge you for it ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi CLawson :-)

 

That's a good point.

AVR GNU toolchain 3.6.1.1750. Is this the version number you are asking for, or should I search elsewhere?

You're absolutely right. This member is stupid. Please help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, awneil. Yes, bitfields seem like an afterthought in C.

 

Another place where bitfields can be important, is in binary communication between devices, where lots of information can be coded as single bits in bitfields. That is actually my case here. The issue could be the same in a computer, althoug the additional time would hardly be noticed...

 

It will work for me as it is, but the behaviour may be annoying in time critical applications.

You're absolutely right. This member is stupid. Please help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry, clawson. It's 5.4.0. The one installed with my installation of Atmel Studio 7.

You're absolutely right. This member is stupid. Please help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


ErikT wrote:
AVR GNU toolchain 3.6.1.1750. Is this the version number you are asking for, or should I search elsewhere?
I mean the number you get from -v when you invoke avr-gcc such as:

 

 

So that one is a 5.3.0. Another one I have is:

 

 

also:

 

That last one is the current one from my copy of AS7. It looks like the 3.6.2 "toolchain" I have there is possibly a little in advance of your 3.6.1 one but it could be 5.4 you have too.

 

Latest issued ones these days are up in the 9.x and 10.x realms (basically because GNU changed from small increments like 3.1. 3.2, ... 4.2, 4.4, 4.6 ... to wild increments like 5, 6, 7, 8, 9, 10 in recent years)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah, I found it. Just had to recall how to get the right number.

 

From 5.4.0 to 10... mentally, that's quite a leap!

You're absolutely right. This member is stupid. Please help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ErikT wrote:
bitfields seem like an afterthought in C.

 

K & R themselves wrote:

 

Almost everything about (bit) fields is implementation-dependent

 

So they[1] are ever going to be great for comms between devices!

 

 

EDIT

 

[1] that is, 'C' language (bit) fields

 

See #12

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Jan 13, 2020 - 05:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe not great – but certainly necessary. wink

 

I can live with it as it is now. Just wondered if I was doing something obviously wrong.

You're absolutely right. This member is stupid. Please help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not actually necessary - you could just use masks, shifts, etc.

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah – yes. I was thinking about bitfields in the actual communication, i.e. bytes full of bits, each with a different purpose. Not the bitfields in C. Sorry. My bad.

You're absolutely right. This member is stupid. Please help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ah - I see!

 

laugh

 

edited #9 to clarify

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Jan 13, 2020 - 05:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I find it difficult to make a faster version myself.

Well, even that is somewhat horrific, depending upon your needs....if critical values are kept in registers you only need 2 commands (bst & bld), eliminating 3 lds/STS commands...that's a rather large savings (>50%), and a big time impact , IF this is bit moving is being done extensively, (such as perhaps some graphics app).   If not, it's just a fraction of a microsend lost to the eons.

 

I might try to convince the compiler to use registers exclusively, & use ram only if those run out---but in that case, which of the too many have priority to reside in registers; you'd want the heavily accessed ones there.

And in many cases, it make no difference at all...if it takes 200 extra microseconds for the RPM gauge to update, nobody notices.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My guess is, that the compiler splits the statement into two parts. First, the program needs to isolate bit n, and keep it in a location where it can find it again. Apparently, this must always be in bit 0. Only after this is done, the compiler starts looking at the destination variable. This action is almost completely split from the first part, so the compiler must rely on the bit being bit 0.

 

That sounds about right:

 

  1. Load the bitfield.  That means load the storage containing the bitfield, shift its LSB down to bit 0, and remove other bits.  That's exactly what you'd need to do for "int i = testsource.bitf;"
  2. store the value (no longer a bitfield, really) into another bitfield.

 

Don't forget that bitfields are not always single bits.

It'd be nice if it optimized better, but it's not really surprising that it doesn't.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In protocol management, I have never had to shift a bit in a byte from one message to a different bit location in a different message. ax.25 is an example of a protocol that is just jammed full of headers with disparate bits. In a message destination, those bits might be interpreted. In an intermediary, the  header is generally copied, with a few bits that might be altered (such as "has been resent"). 

 

Thus, in every case I can think of, bit changes are handled with constant bit masks.

 

If you are dealing with a protocol that requires shifting the locations of individual bits, then you have my sympathy. But not much! Recommendation: find a different protocol!

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:
find a different protocol!

Sadly, that is often a hard constraint!

 

frown

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I totally agree. If you are working with ham packet radio, for example, ax.25 is almost the only one that is used. 

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Strange. I'm using this test code:

 

struct tTestBitfield
{
	unsigned char Bit0:1;
	unsigned char Bit1:1;
	unsigned char Bit2:1;
	unsigned char Bit3:1;
	unsigned char Bit4:1;
	unsigned char Bit5:1;
	unsigned char Bit6:1;
	unsigned char Bit7:1;
};

volatile struct tTestBitfield TestSource;
volatile struct tTestBitfield TestDestination;

int main() {
	TestDestination.Bit3=TestSource.Bit0;
}

and I'm getting the optimized version. I'm also using -Os and the native avr-gcc that comes with AS7 (5.4.0). I have newer versions of avr-gcc that also give the optimized version.

 

edit: oops, disregard. So the code changes with the bits that are moved. Yeah, it's weird.

 

edit #2: I've confirmed that this is a problem of v 5.4.0 and is fixed in newer versions, for example using 7.3.0, this

	TestDestination.Bit3=TestSource.Bit0;
	TestDestination.Bit3=TestSource.Bit1;
	TestDestination.Bit3=TestSource.Bit2;
	TestDestination.Bit3=TestSource.Bit4;

 

compiles to:

 10a:	90 91 01 02 	lds	r25, 0x0201	; 0x800201 <TestSource>
 10e:	80 91 00 02 	lds	r24, 0x0200	; 0x800200 <_edata>
 112:	90 fb       	bst	r25, 0
 114:	83 f9       	bld	r24, 3
 116:	80 93 00 02 	sts	0x0200, r24	; 0x800200 <_edata>
 11a:	90 91 01 02 	lds	r25, 0x0201	; 0x800201 <TestSource>
 11e:	80 91 00 02 	lds	r24, 0x0200	; 0x800200 <_edata>
 122:	91 fb       	bst	r25, 1
 124:	83 f9       	bld	r24, 3
 126:	80 93 00 02 	sts	0x0200, r24	; 0x800200 <_edata>
 12a:	90 91 01 02 	lds	r25, 0x0201	; 0x800201 <TestSource>
 12e:	80 91 00 02 	lds	r24, 0x0200	; 0x800200 <_edata>
 132:	92 fb       	bst	r25, 2
 134:	83 f9       	bld	r24, 3
 136:	80 93 00 02 	sts	0x0200, r24	; 0x800200 <_edata>
 13a:	90 91 01 02 	lds	r25, 0x0201	; 0x800201 <TestSource>
 13e:	80 91 00 02 	lds	r24, 0x0200	; 0x800200 <_edata>
 142:	94 fb       	bst	r25, 4
 144:	83 f9       	bld	r24, 3
 146:	80 93 00 02 	sts	0x0200, r24	; 0x800200 <_edata>

 

Last Edited: Tue. Jan 14, 2020 - 01:27 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So the code changes with the bits that are moved. Yeah, it's weird.

Compilers have gotten a lot better, but they aren't infallible yet.  I wonder if there is a learning compiler...where you can show it some code it should have made & it will adaptively lear.n that (like a learning chess program).  Of course maybe it will learn too much and  become like Dr. Daystrom's computer.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here's another take on this problem:

 

There is an avr builtin for this https://gcc.gnu.org/onlinedocs/gcc/AVR-Built-in-Functions.html#AVR-Built-in-Functions

uint8_t __builtin_avr_insert_bits (uint32_t map, uint8_t bits, uint8_t val)

Insert bits from bits into val and return the resulting value. The nibbles of map determine how the insertion is performed: Let X be the n-th nibble of map

  1. If X is 0xf, then the n-th bit of val is returned unaltered.
  2. If X is in the range 0…7, then the n-th result bit is set to the X-th bit of bits
  3. If X is in the range 8…0xe, then the n-th result bit is undefined.

One typical use case for this built-in is adjusting input and output values to non-contiguous port layouts. Some examples:

// same as val, bits is unused
__builtin_avr_insert_bits (0xffffffff, bits, val)
// same as bits, val is unused
__builtin_avr_insert_bits (0x76543210, bits, val)
// same as rotating bits by 4
__builtin_avr_insert_bits (0x32107654, bits, 0)
// high nibble of result is the high nibble of val
// low nibble of result is the low nibble of bits
__builtin_avr_insert_bits (0xffff3210, bits, val)
// reverse the bit order of bits
__builtin_avr_insert_bits (0x01234567, bits, 0)

It's a bit of an IQ Test to understand how to use it but here goes; using godbolt.org and avr-gcc-5.4.0 with -Os

 

#include <stdint.h>

extern uint8_t TestSrc;
extern uint8_t TestDst;

void foo () {
    TestDst = __builtin_avr_insert_bits (0xffff1fff, TestSrc, TestDst);
}

compiles to:

foo():
        lds r25,TestSrc
        lds r24,TestDst
        bst r25,1
        bld r24,3
        sts TestDst,r24
        ret

 

If you use it in production code (I never did) be sure to comment well your intentions because it's really hard to read.

 

Last Edited: Tue. Jan 14, 2020 - 08:55 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:
So the code changes with the bits that are moved. Yeah, it's weird.

Not sure that's weird at all?

 

As the particular bits are known at compile time, it doesn't seem unreasonable that the compiler would adjust its code to suit ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But the weird thing is why it would use a different pattern for 3=1 than 3=0. The T transfer thing should work very nicely for any n=m (or even n=n).

 

Of course this (like everything in the compiler) does not go direct from C to AVR asm. The C is reduced (as all other languages) to an internal representation (Gimple is it?) then that universal representation is passed to the AVR code generator so this probably isn't about AVR specifically but about the break down of C to internal representation and that behaving differently for different n=m

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
so this probably isn't about AVR specifically but about the break down of C to internal representation

Indeed.

 

Which brings us back to my point in #3 with GCC being a "generalist" compiler.

 

Having said that, I do wonder how IAR cope with so many different targets?

 

surprise

 

Perhaps they do have some kind of common  internal representation - but that is more focussed to common embedded requirements ... ?

 

Or maybe it's all just a myth.

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tried the following code with v10:

 

 

struct tTestBitfield
{
  unsigned char Bit0:1;
  unsigned char Bit1:1;
  unsigned char Bit2:1;
  unsigned char Bit3:1;
  unsigned char Bit4:1;
  unsigned char Bit5:1;
  unsigned char Bit6:1;
  unsigned char Bit7:1;
};

struct tTestBitfield TestSource;
struct tTestBitfield TestDestination;

void foo()
{
    TestDestination.Bit3 = TestSource.Bit1;
}

void foo2()
{
    TestDestination.Bit3 = !TestSource.Bit1;
}

and compiled with -Os -S the asm reads (snipped for brevity):

 

foo:
	lds r25,TestSource
	lds r24,TestDestination
	bst r25,1
	bld r24,3
	sts TestDestination,r24
	ret

foo2:
	lds r25,TestSource
	lds r24,TestDestination
	andi r24,~(1<<3)
	sbrs r25,1
	ori r24,1<<3
	sts TestDestination,r24
	ret

Looks good to me.

 

Apart from that:  If you want your problems to be reproducible, provide test cases that can be compiled (at least).  Code that's obfuscated by ... and similar is not helpful for others, and it might reduce the amount of helpful answers you are getting.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

awneil wrote:

 

Or maybe it's all just a myth.

 

 

A myth? That'th a young female moth, ithn't it?

 

Neil

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
So they are ever going to be great for comms between devices!

 

They were never intended for that. Bit-fields is an abstract data packaging feature (for space saving purposes), not a bit-mapping feature.

 

BTW, in C you have '[signed/unsigned] int' bit fields and '_Bool' bit fields. For any other type you are at the mercy of your compiler. 'unsigned char' bit fields in C is non-standard - it is a GCC extension.

Dessine-moi un mouton

Last Edited: Wed. Jan 15, 2020 - 12:12 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

GIMPLE is one of several intermediate languages involved in the gcc compiler.

I know we have a lot of hobbyist & students that haven't had a deep CS education, so for the curious:

 

Here's a brief overview of the compilation process:

https://en.wikibooks.org/wiki/GNU_C_Compiler_Internals/GNU_C_Compiler_Architecture

 

Here's a few videos that discuss intermediate languages and how compilers evolve:

https://www.youtube.com/watch?v=pP_zIJSp3WA
https://www.youtube.com/watch?v=TiJn9D6lZ-Y

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

balisong42 wrote:

Here's a brief overview of the compilation process:

https://en.wikibooks.org/wiki/GNU_C_Compiler_Internals/GNU_C_Compiler_Architecture

Where 99.9% of what the compiler is doing is in the "The ASTs are then converted into the SSA and eventually to the RTL representations."

 

The document is hopelessly outdated since decades: "GCC parser is written as a bison grammar."

 

clawson wrote:

 

so this probably isn't about AVR specifically but about the break down of C to internal representation

Nope.  As I wrote above, you are using an outdated compiler.  The respective change are here: http://gcc.gnu.org/r238587 Spoiler: It's in the avr backend.

 

It went upstream in 2016-07-21 and thus comes with v7+.

 

If you want to watch the compiler munching on the code, add option -da (or -fdump-rtl-all for that matter).  The effect of the change above will be visible in the .combine dump (and following passes, of course).

 

avrfreaks does not support Opera. Profile inactive.

Last Edited: Wed. Jan 15, 2020 - 09:24 AM