AVR GCC and register usage

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

Howdy all,

From the FAQ

Quote:
Arguments - allocated left to right, r25 to r8. All arguments are aligned to start in even-numbered registers (odd-sized arguments, including char, have one free register above them).

So if I have a function that only passed a char/uint8

void Blah(uint8_t X);

X will be passed in R24 with R25 being "free"

Does "Free" mean I can clobber it in ASM?

I know if I was calling a routine

void Blah(void);

I would be allowed to clobber R25

But from much google-ing I can't see if I am allowed to do it in the char/uint8_t case above.

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

Quote:
Does "Free" mean I can clobber it in ASM?
Not necessarily, the compiler may not use it but there is nothing stopping a library function using all registers. (as I found out the hard way...)

R24 and R25 are usually the main temp registers for the compiler, R1 is usually zero for faster zeroing of variables etc.

So I guess if you save all the registers you use in ASM (including the status register) and then restore them on exiting it MAY be ok, unless of coure an ISR can happen while your ASM code is running.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

I only need to save and restore SREG in an ISR don't I?

Nothing would ever call a subroutine and expect SREG to be the same on return would it?

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

You can use r25 freely in such a case, and the Compiler will preserve it if it's being used before the call.

Quote:
I only need to save and restore SREG in an ISR don't I?
If you need to do an atomic op and you have ISR()s in your code,like RWM a multibyte var. in main() that's also used in an ISR, you would need to :

  preserve SREG;
  cli;
  do stuff;
  SREG = preserved_sreg_var; // this way, whatever value SREG had, it will end up with the same value, whether I-bit was set or not.

andrewm1973 wrote:
Nothing would ever call a subroutine and expect SREG to be the same on return would it?
Of course it would, that's the point of needing to preserve registers before and after a function call/ISR.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

indianajones11 wrote:
You can use r25 freely in such a case, and the Compiler will preserve it if it's being used before the call.

Thank you. FAQs did not answer this one. They said I needed to leave R24 unaltered but not R25.

indianajones11 wrote:
If you need to do an atomic op and you have ISR()s in your code,like RWM a multibyte var. in main() that's also used in an ISR, you would need to :

  preserve SREG;
  cli;
  do stuff;
  SREG = preserved_sreg_var; // this way, whatever value SREG had, it will end up with the same value, whether I-bit was set or not.

Won't need anything like that. I know what the state I is :D

indianajones11 wrote:

andrewm1973 wrote:
Nothing would ever call a subroutine and expect SREG to be the same on return would it?
Of course it would, that's the point of needing to preserve registers before and after a function call/ISR.

Isn't it the "caller" that is responsible for saving it?

The "caller" would never expect the called function to leave SREG unaltered would it?

I have read elsewhere (not in the FAQ) that SREG is "call-used" which makes sense.

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

Quote:
Isn't it the "caller" that is responsible for saving it?
Caller is what expects it to be the same when returning. Caller wants its SREG state preserved on ANY function call ( whether it's compiler or programmer doing it ), period, don't complicate it. SREG = "call-used"...it's not on the list, so I wouldn't call it that, but treat it like it needs to be treated and you can call it whatever you want. :)

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

Well in ASM I would never

tst   R16
rcall Blah
breq  R16_Was_Clear

Something like that doesn't make sense in any naive case I can think of.

Also in my last few weeks of looking at the disassembly of C that GCC has made I have not seen a (non-ISR) subroutine save SREG.

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

But it's your topic and you were asking about C- interfacing with asm, so yes pure asm is a different thing.

For your last point, it's the same thing...all about the C-asm I/F, and therefore, you better take care of the SREG, if it gets altered by your asm. C code without any asm/ISR in it wouldn't need to push/pop it as the compiler takes an "it is what it is" type attitude to the SREG changing. IOW, for such code, a section gets done, sreg is whatever value, and it's off to next section of code and if it's altered, oh well and so what ( the next, next section may do the same thing, etc ). This makes sense for linear, synchronous code at the level that the compiler-level toolchain cares about in its job of producing correct code.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

Last Edited: Tue. Apr 9, 2013 - 06:14 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Caller wants its SREG state preserved on ANY function call

That seems extremely unlikely...
For instance, I don't think I've ever seen SREG saved by any function that was produced by the C compiler (except ISRs.)

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

westfw wrote:
Quote:
Caller wants its SREG state preserved on ANY function call

That seems extremely unlikely...
For instance, I don't think I've ever seen SREG saved by any function that was produced by the C compiler (except ISRs.)
Yeah, I was wrong to say 'any', just C-asm and ISRs, which I did in my last post.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

None of the three "mixing C and ASM" guides I have read (including Atmels own AT1886) have mentioned you have to save SREG.

Expecting SREG to be unaltered after doing an RCALL (regardless of being in C or ASM) would be far too optimistic.

Several weeks of looking at disassembly of C code has not shown that SREG is saved in pure C. Which makes sense.

Looking at dozens on projects on the web from people who are publishing source that mixes .c and .S files has not shown anyone saving SREG.

I am suspecting that SREG is "Call-Used"

Now I have to go back and find someone to tell me if I can really use R25.

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

Of course you can, these are some of the registers I used in a mixed C and ASM project.

/Registers assignment

#define	temp1 R25					//Second Temp register
#define	temp R24					//Temp register

//High registers used by DISA-5S07_driver

#define	temp4 R22
#define	temp3 R21
#define	temp2 R20

#define	Display_status R16			//Status of message being displayed	
//DISA-5S07_driver high registers end

//Low registers used by DISA-5S07_driver
#define	row R6						//This is the row bit holder
#define	rownum R5					//Row number
#define	reform_cntr R4				//Reform counter
//DISA-5S07_driver low registers end

and this is the code being called every 2.5ms by the ISR in C

	.global	out_1_row
	.func out_1_row

out_1_row:
	sbi		_SFR_IO_ADDR(PORTB), test_bit	//To check routine time
	push	XL
	push	XH
	push	YL
	push	YH
	push	ZL
	push	ZH
	push	temp
	push	temp1
	push	temp2
	push	temp3
	push	temp4
	push	r1
	push	r0

	rcall	reform						//Gets data from char gen and formats it
	rcall	shift_rows					//Shift data to display(s)
	clc
	ror		row							//Next row down
	dec		rownum						//Decrement row number
	brpl	x_do_reform
reset_rownum:
	ldi		temp,0x40					//If rownum negative start 	
	mov		row,temp					//at bottom row again
	ldi		temp,6
	mov		rownum,temp
x_do_reform:
	pop		r0
	pop		r1
	pop		temp4
	pop		temp3
	pop		temp2
	pop		temp1
	pop		temp
	pop		ZH
	pop		ZL
	pop		YH
	pop		YL
	pop		XH
	pop		XL
	cbi		_SFR_IO_ADDR(PORTB), test_bit
	ret

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Last Edited: Tue. Apr 9, 2013 - 06:51 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

andrewm1973 wrote:
I am suspecting that SREG is "Call-Used"
Yes it is. You only need to save it in ISR's.
Quote:
Now I have to go back and find someone to tell me if I can really use R25.
You can use any "Call-used" register freely in the called function, including r25.

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

Snigelen,

That is even if R24 was used to pass in a char?

It isn't just "call-used" registers below the last passed in register? R23 down if R24 was used?

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

Yes, r25 is free to be used by the called function. I can't find it explicitly stated anywhere but looking at code generated by avr-gcc it's using r25 in situations like this, without restoring (or clearing) the value on function exit. You don't need to preserve r24 either.

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

SREG isn't call-used, if it were for example, the asm code in wdt.h wouldn't need to preserve it, the compiler would. So if anything it's call-saved-ish.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

indianajones11 wrote:
Yeah, I was wrong to say 'any', just C-asm and ISRs, which I did in my last post.
If by C-asm you mean inline assembly, I think that instead of preserving SREG, one can put cc in the clobber list.

On that subject, does avr-gcc understand the relationship between SREG and test results?
For example, does it understand that SREG=fred will destroy the result of the last comparison?

"Demons after money.
Whatever happened to the still beating heart of a virgin?
No one has any standards anymore." -- Giles

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

indianajones11 wrote:
SREG isn't call-used,
No, that's why I said "Call-used". But that isn't really correct (it isn't even in the ABI, except for the T-bit).

What I mean is that you don't need to preserve it, unless you touch the I-bit of course. I have never seen a library function that preserves it because, for example, the C-bit may be changed.

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

Quote:
SREG isn't call-used, if it were for example, the asm code in wdt.h wouldn't need to preserve it, the compiler would.
Inline assembly macros are not function calls.

Regards,
Steve A.

The Board helps those that help themselves.

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

Koshchi wrote:
Quote:
SREG isn't call-used, if it were for example, the asm code in wdt.h wouldn't need to preserve it, the compiler would.
Inline assembly macros are not function calls.
Calls to a subroutine in a *.S aren't function calls either are they ? That one has to manually preserve SREG( so then not call-used as the manual uses the term ), in their asm code were my main points, as the compiler won't do it.

Skeeve wrote:
For example, does it understand that SREG=fred will destroy the result of the last comparison?
Nope, if you access SREG directly like that, you have to preserve its value. The toolchain in its code analysis won't generate any code to protect it.

I should've taken my own advice on

Quote:
Apr 08, 2013 - 11:05 PM
when I wrote that C code goes from section to section not caring about preserving SREG value, then I would not have said "ANY function", including asm code ( which is just another synchronous code section. Unless you need something like what's in wdt.h ) .
:mrgreen:

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

Last Edited: Tue. Apr 9, 2013 - 07:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Calls to a subroutine in a *.S aren't function calls either are they ?
Yes they are, why wouldn't they be? The C code calling it has no idea how the function was created, but it does expect that the callee follows the conventions as if it was created in C.

Regards,
Steve A.

The Board helps those that help themselves.

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

snigelen wrote:
Yes, r25 is free to be used by the called function. I can't find it explicitly stated anywhere but looking at code generated by avr-gcc it's using r25 in situations like this, without restoring (or clearing) the value on function exit. You don't need to preserve r24 either.

Thank you Snigilen.

I was under the mistaken impression I needed to leave the values passed into a function untouched.

uint8_t i;

i=10;

Blah(i); // passed in r24

Wibble(i); // r24 not reloaded here 'cause the
           // compiler expects it's still 10

That bit of news will make my life much easier and give me back six more registers to play with and not having to push/pop so much.

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

Quote:
Blah(i); // passed in r24
If Blah was 16 bits then it would use R24 AND R25.

And what are you doing in front of the computer at this ungodly hour? :lol:

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

js wrote:
Quote:
Blah(i); // passed in r24
If Blah was 16 bits then it would use R24 AND R25.

Well the code block has uint8_t i; just 2 lines above :)

The important point is that I can trash R24 (and R25) according to snigilen.

js wrote:
And what are you doing in front of the computer at this ungodly hour? :lol:

Just getting ready for my 23km pushbike ride to work in Brisbane.

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

andrewm1973 wrote:
I was under the mistaken impression I needed to leave the values passed into a function untouched.
Where did you get that impression? The section of the AVR FAQ dealing with register usage doesn't say anything about preserving registers in which parameters were passed except in the "call saved" section where it explicitly says that you must preserve such registers even if parameters were passed in them.

http://www.nongnu.org/avr-libc/u...

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

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

Can't remember exactly where I picked that one up. I think it was a forum post somewhere.

But it is what lead me to wondering if he "free" register was up for grabs in the first place.

Maybe I should recommend adding to the FAQ under the call-used section "You may clobber these even those used to pass in values"

I guess seeing as other people had confusion about SREG maybe adding to the FAQ a bit about I being the only thing you have to preserve might be a good idea as well.

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

andrewm1973 wrote:
I guess seeing as other people had confusion about SREG maybe adding to the FAQ a bit about I being the only thing you have to preserve might be a good idea as well.
In a function call, one does not need to preserve SREG.

"Demons after money.
Whatever happened to the still beating heart of a virgin?
No one has any standards anymore." -- Giles

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

Skeeve - did you not read the whole thread?

We have already ascertained that the I Bit is the only thing you have to preserve.

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

andrewm1973 wrote:
We have already ascertained that the I Bit is the only thing you have to preserve.
There is no such requirement. None of the SREG bits need be preserved across normal function calls. In contrast, an ISR must preserve all SREG bits and the content of all GP registers (r0-r31).

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

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

andrewm1973 wrote:
Skeeve - did you not read the whole thread?

We have already ascertained that the I Bit is the only thing you have to preserve.

Actually, I just didn't read what I quoted very well.

"Demons after money.
Whatever happened to the still beating heart of a virgin?
No one has any standards anymore." -- Giles

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

indianajones11 wrote:
Skeeve wrote:
For example, does it understand that SREG=fred will destroy the result of the last comparison?
Nope, if you access SREG directly like that, you have to preserve its value. The toolchain in its code analysis won't generate any code to protect it.
That could have consequences for Dean's ATOMIC_BLOCK.
The compiler could try to use the last condition code from inside the atomic block after said code has been destroyed by SREG restore.
I think adding something like asm ("" ::: cc) in the right place would fix it.

"Demons after money.
Whatever happened to the still beating heart of a virgin?
No one has any standards anymore." -- Giles

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

dkinzer wrote:
andrewm1973 wrote:
We have already ascertained that the I Bit is the only thing you have to preserve.
There is no such requirement. None of the SREG bits need be preserved across normal function calls. In contrast, an ISR must preserve all SREG bits and the content of all GP registers (r0-r31).

Don,

Maybe you want to re-read this and think a bit harder.

I am pretty certain everyone should leave the I bit the way the found it. (unless it is their job to change it)

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

But that would simply be a bug in the code, not something to do with function calling protocols.

Regards,
Steve A.

The Board helps those that help themselves.

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

> "You may clobber these even those used to pass in values"

As r24:r25 are also used to pass function return values back, I think
it should be pretty obvious the called function is allowed to change
them.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

"As r24:r25 CAN also be used"

There is a difference between can and are.

A void function (as in the OP) does not use them.

I know now that it is not the case. However the compiler could have expected the value to be the same at the end of the function. This is without having to defy any laws of logic and is an arbitrary decision of the compiler implementers.

I don't know. Maybe updating FAQs to be as clear and precise as possible is a bad idea?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
uint8_t i;

i=10;

Blah(i); // passed in r24

Wibble(i); // r24 not reloaded here 'cause the
           // compiler expects it's still 10 

Compiler says:

.L__stack_usage = 0
.LVL0:
	.loc 1 11 0
	ldi r24,lo8(10)	 ; ,
	call Blah	 ; 
.LVL1:
	.loc 1 13 0
	ldi r24,lo8(10)	 ; ,
	call Wibble	 ; 

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

> Maybe updating FAQs to be as clear and precise as possible is a bad idea?

Just submit a patch that demonstrates how you think it's going to be
clearer.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

andrewm1973 wrote:
I am pretty certain everyone should leave the I bit the way the found it. (unless it is their job to change it)
Generally speaking, yes. My point was that there is no ABI requirement for a subroutine to preserve SREG.

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

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

Quote:
However the compiler could have expected the value to be the same at the end of the function.
No, the compiler would never expect it to be the same. For a function that returns no value the compiler will assume that it was thrashed.
Quote:
This is without having to defy any laws of logic and is an arbitrary decision of the compiler implementers.
It is not arbitrary. It would mean that there would be different rules depending on whether or not the function returns a value, which is not logical. When a value is passed into a function it is logical to assume the function will change that value. Also, when a function does return a value, it does not represent the same variable that was passed in. So no, your assumption does in fact defy logic.

Regards,
Steve A.

The Board helps those that help themselves.

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

Quote:
No, the compiler would never expect it to be the same. For a function that returns no value the compiler will assume that it was thrashed.

I have already said I know is NOT THE CASE now.

Everything I was saying was theoretical "could" if the compiler implementors CHOSE to do it that way. I was justifying the reason for the question in my original post.

It WAS an arbitrary decision of them to make r18:27 call-used and R2:17 call saved. The same as it was an arbitrary decision to make R1=ZERO (for what ever silly reason they decided to use the result of MUL as a constant).

They COULD have chosen to ask you to keep R24:25 the same to save a reload by the caller. AGAIN for your clarity Koschi I am saying "could have in some other parallel universe - not this one in which they didn't"

And Yes having a different rule for R24:25 on a void function than a non void one would be a different rule. Doesn't defy logic though (look at Clawsons code above and you can see how that "different rule" on a void function could save one clock for an aggressive optimiser)

I already had my answer in post 22. Everything from there down has just been "me too's" trying to get their post count up.

I have honestly never seen anywhere on the interweb with a lower signal to noise ratio than this forum.

I've had people ask me to break with standard conventions of "smallest code to reproduce a bug". Tell me you can't use a MOV instruction with registers below R16. Tell me I have to preserve SREG across a function call.

Sorry to rant at you Koshchi. Generally your, Cliffs and of course Deans posts are what I would read to know the truth when clicking in from google. I just have never HAD to ask a question in here because I normally can find answers myself in google. Now I am here I am a bit fed up with the people who think they know and want to get their "post/day" numbers up.

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

andrewm1973 wrote:
The same as it was an arbitrary decision to make R1=ZERO (for what ever silly reason they decided to use the result of MUL as a constant).
There was simply no MUL opcode at the time that decision was made.

Stefan Ernst

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

I am not simply trying to up my post count, I am trying to correct a misconception that you have.

While what registers are used by the compiler to pass parameters (or for that matter to use registers at all) is arbitrary, the decision as to whether or not the value should be preserved is >>NOT<< arbitrary. It is a logical consequence of the C language. Parameters passed to a function are >>NEVER<< preserved. When calling a function, the parameters of a function are variables that are local to that function and belong to it, not the caller. The caller passes a value to the callee, not a variable.

Your point of optimization is also not logical. The occasional savings for the caller would be greatly outweighed by the severe penalties this would impose on the callee. If the callee wanted to change the value passed in, then it would be forced to copy that value to somewhere else and return that value before returning, which is in itself more expensive than any savings that could be realized by the caller. And even if the callee doesn't change the value, they now have a restricted number of registers for their use, which will often necessitate moving and restoring the value anyways.

So no, a decision to force those values to be preserved is not at all "logical".

Regards,
Steve A.

The Board helps those that help themselves.

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

sternst wrote:
andrewm1973 wrote:
The same as it was an arbitrary decision to make R1=ZERO (for what ever silly reason they decided to use the result of MUL as a constant).
There was simply no MUL opcode at the time that decision was made.

Why don't they change it?

They have shown they have no moral objection to breaking old code.

A Quote from "the FAQ"

Quote:
Warning:
There was no such alignment before 2000-07-01, including the old patches for gcc-2.95.2. Check your old assembler subroutines, and adjust them accordingly.

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

Quote:
the decision as to whether or not the value should be preserved is >>NOT<< arbitrary. It is a logical consequence of the C language.

Is different reason from your first reason for not being logical.

Quote:
It would mean that there would be different rules depending on whether or not the function returns a value, which is not logical.

I answered your first statement about logic.

Now your new statement about it being "A consequence of the C language" is a lot more sound. I can't and won't argue with that. Maybe you should have said the second statement first rather than being glib.

Quote:
Your point of optimization is also not logical.

Your rebuttal of this is flawed and is making the assumption that the caller will always be less complex than the callee. Granted maybe there is "consequence of the C language" I am not familiar with. Though from a marginally competent ASM programmer - on the AVR architecture what you said there is outright wrong.

In fact in a good many cases where the parameter passed in is not changed at all, no copy ever needed to be made (by caller or callee). Oh except for in the case you pointed out that there already is a "full deck". Though in that case someone has to push/store and everyone is a looser.

If there is going to be a copy made why is it more expensive for the callee?

AVRs don't do out of order, have shadows, predictive branching etc. 1 instruction = 1 instruction. That is why I as just an average human can beat the compiler hands down at simple tasks.

Quote:
severe penalties

Quote:
occasional savings

You're starting to use emotive language there to back your arguments. Maybe take a few deep breaths before replying again.

Quote:
I am trying to correct a misconception that you have.

You are NOT just trying to clear up a misconception. In post 22 I had already been set straight by Snigilen. I made it quite clear I understood how it DOES work. Way later in post 39 you where replying about how I said it could have worked if many moons ago the compiler designers had a different idea? Maybe you just didn't bother reading in your haste to hit submit. I don't know.

Oh and now I am just trying to wind you up about post 33 :)

Quote:
But that would simply be a bug in the code, not something to do with function calling protocols.

Could no one ever have a function called?

void Compare_Flubomator_with_X_and_enable_interrupts_if_equal(uint8_t X);
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Is different reason from your first reason for not being logical.
No it is not. You simply did not understand that that was the reason. This was just a clarification.
Quote:
Your rebuttal of this is flawed and is making the assumption that the caller will always be less complex than the callee.
I never said always. But it will be far more likely. It is rare to send the same variable into two functions in a row. It is extremely common for a function to change the value of that variable, and extremely common for a function to need multiple registers for local use.
Quote:
Granted maybe there is "consequence of the C language" I am not familiar with. Though from a marginally competent ASM programmer - on the AVR architecture what you said there is outright wrong.
And how much assembly generated from C code have you examined?
Quote:
Could no one ever have a function called?
void Compare_Flubomator_with_X_and_enable_interrupts_if_equal(uint8_t X);

I never said that you couldn't intentionally change the I bit. But if the I bit is changed unintentionally, it is a bug introduced by the programmer, not the compiler. Nor is the preservation of the I bit some rule of the compiler witters. The C language knows nothing about the I bit. The only real place that the compiler pays any attention to anything concerning the I bit is that it puts RETI and the end of ISRs instead of RET.

Regards,
Steve A.

The Board helps those that help themselves.

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

Quote:
No it is not. You simply did not understand that that was the reason. This was just a clarification.

Post half an argument to someone ignorant you can't complain about them missing the hidden point.

Quote:
I never said that you couldn't intentionally change the I bit. But if the I bit is changed unintentionally

First time the word "unintentional" has been mentioned. You just started talking about bugs after I said you might want to change it. Thats akin to me saying now that "unintentionally clearing EEPROM location 0x17" is a bug :S

I'm still waiting to hear how a move is less efficient after an RCALL than before it? I can see how it can make life easier for the compiler/optimiser but I can't see how it can always make the target code faster. (Unless a lot of the code you write a variable is discarded straight after being used by the caller as is the case in the simple example program with blah and wibble)

Quote:
And how much assembly generated from C code have you examined?

Only a few weeks on the AVR-8 arch. Still enough to see that although C is powerful, it can not hope to replace ASM for things speed critical.

We should be able to get you up to 14K posts by the end of the week no worries :D

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

I don't believe this thread is going anywhere useful so I'll lock it. No one really needs or wants to up their post counts.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

> The same as it was an arbitrary decision to make R1=ZERO (for
> what ever silly reason they decided to use the result of MUL as a constant).

The MUL instruction simply did not exist at all when this decision had
been made.

> They have shown they have no moral objection to breaking old code.

So far, AVR-GCC tried very hard to not completely break
the existing interfaces (and moving the zero reg to
something else would be a complete break).

Your citation for the transition between GCC 2.95 and GCC 3+
predates the days of the AVR target port.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

Topic locked