Few questions about stack frame and calling conventions implementation in a backend

Hi all,
I’ve been working for some time now on a backend for our CPU. However I couldn’t figure out how to implement some stuff.
I’d appreciate your help with these.

First thing is return address

Hi all
Ups, I’m really sorry for that previous message, I’ve sent it by mistake.

So let me write it once more.

I’ve been working for some time now on a backend for our CPU. However I couldn’t figure out how to implement some stuff.
I’d appreciate your help with these.

First thing is return address saving. To do that, first I have to copy it to a general purpose register. I have no idea how to find an unused gpr register in emitPrologue/emitEpilogue. I’ve noticed that in other backends RegScavenger is used for that purpose, but not from inside of those methods. So my question is how could I get an unused register from inside of these methods?

And my second problem is with returning structures by value. ABI says that aggregates up to 32bytes should be returned directly in register. Any advice how this could be done?

Thanks
Artur

Hi all
Ups, I'm really sorry for that previous message, I've sent it by mistake.

So let me write it once more.

I've been working for some time now on a backend for our CPU. However I
couldn't figure out how to implement some stuff.
I'd appreciate your help with these.

First thing is return address saving. To do that, first I have to copy it to
a general purpose register. I have no idea how to find an unused gpr
register in emitPrologue/emitEpilogue. I've noticed that in other backends
RegScavenger is used for that purpose, but not from inside of those methods.
So my question is how could I get an unused register from inside of these
methods?

Do you have an API specified register where the variable is passed?
If so, it is a matter of copying it to a virtual register in the
prologue which is then a live in to the first basic block. If you
must have it in a specific register, you can make your ret inst take
it as a use and copy the virtual register back to the physical one for
the ret.

And my second problem is with returning structures by value. ABI says that
aggregates up to 32bytes should be returned directly in register. Any advice
how this could be done?

This has to be done in the front end, I think.

Andrew

Hi Andrew,
thanks for answering

Hi all
Ups, I’m really sorry for that previous message, I’ve sent it by mistake.

So let me write it once more.

I’ve been working for some time now on a backend for our CPU. However I
couldn’t figure out how to implement some stuff.
I’d appreciate your help with these.

First thing is return address saving. To do that, first I have to copy it to
a general purpose register. I have no idea how to find an unused gpr
register in emitPrologue/emitEpilogue. I’ve noticed that in other backends
RegScavenger is used for that purpose, but not from inside of those methods.
So my question is how could I get an unused register from inside of these
methods?

Do you have an API specified register where the variable is passed?
If so, it is a matter of copying it to a virtual register in the
prologue which is then a live in to the first basic block. If you
must have it in a specific register, you can make your ret inst take
it as a use and copy the virtual register back to the physical one for
the ret.

There is no specific register needed here. It’s just dedicated RA register is a special register that could be read/set via a GPR using get/set instructions only. So this is why I need a GPR register in prologue/epilogue.
Aren’t prologue/epilogue run after register allocation? If I copy to a virtual register, wouldn’t I have to rerun the RA pass?

And my second problem is with returning structures by value. ABI says that
aggregates up to 32bytes should be returned directly in register. Any advice
how this could be done?

This has to be done in the front end, I think.

There is no way of doing that in the backend?

Andrew

Thanks,
Artur

Hi Andrew,
thanks for answering

> Hi all
> Ups, I'm really sorry for that previous message, I've sent it by
> mistake.
>
> So let me write it once more.
>
> I've been working for some time now on a backend for our CPU. However I
> couldn't figure out how to implement some stuff.
> I'd appreciate your help with these.
>
> First thing is return address saving. To do that, first I have to copy
> it to
> a general purpose register. I have no idea how to find an unused gpr
> register in emitPrologue/emitEpilogue. I've noticed that in other
> backends
> RegScavenger is used for that purpose, but not from inside of those
> methods.
> So my question is how could I get an unused register from inside of
> these
> methods?

Do you have an API specified register where the variable is passed?
If so, it is a matter of copying it to a virtual register in the
prologue which is then a live in to the first basic block. If you
must have it in a specific register, you can make your ret inst take
it as a use and copy the virtual register back to the physical one for
the ret.

There is no specific register needed here. It's just dedicated RA register
is a special register that could be read/set via a GPR using get/set
instructions only. So this is why I need a GPR register in
prologue/epilogue.
Aren't prologue/epilogue run after register allocation? If I copy to a
virtual register, wouldn't I have to rerun the RA pass?

I think I was suggesting that you could reserve a specific physical
register for this purpose. By copying into a virtual you free the
register during the body to be used for other stuff. But you always
have the physical register for prologue/epilogue (by ensuring the RA
wouldn't use it in the prologue/epilogue).

> And my second problem is with returning structures by value. ABI says
> that
> aggregates up to 32bytes should be returned directly in register. Any
> advice
> how this could be done?

This has to be done in the front end, I think.

There is no way of doing that in the backend?

The problem is that is is the C ABI that says this, which is currently
handled in the front end. You can have the front end pass structs
directly (if I remember correctly) and do this yourself, but
specifying it in the front end is all of a line or two of code (this
is a standard ABI thing that the front end handles on several
platforms).

Andrew