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. :)

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.

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.

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:

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.

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.

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

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?

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.

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.

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".

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.

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.

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.

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