public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* RFC: New mechanism for hard reg operands to inline asm
@ 2021-06-04 18:02 Andreas Krebbel
  2021-06-04 18:18 ` Paul Koning
  0 siblings, 1 reply; 4+ messages in thread
From: Andreas Krebbel @ 2021-06-04 18:02 UTC (permalink / raw)
  To: gcc

Hi,

I wonder if we could replace the register asm construct for
inline assemblies with something a bit nicer and more obvious.
E.g. turning this (real world example from IBM Z kernel code):

int diag8_response(int cmdlen, char *response, int *rlen)
{
        register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
        register unsigned long reg3 asm ("3") = (addr_t) response;
        register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L;
        register unsigned long reg5 asm ("5") = *rlen; /* <-- */
        asm volatile(
                "       diag    %2,%0,0x8\n"
                "       brc     8,1f\n"
                "       agr     %1,%4\n"
                "1:\n"
                : "+d" (reg4), "+d" (reg5)
                : "d" (reg2), "d" (reg3), "d" (*rlen): "cc");
        *rlen = reg5;
        return reg4;
}

into this:

int diag8_response(int cmdlen, char *response, int *rlen)
{
        unsigned long len = cmdlen | 0x40000000L;

        asm volatile(
                "       diag    %2,%0,0x8\n"
                "       brc     8,1f\n"
                "       agr     %1,%4\n"
                "1:\n"
                : "+{r4}" (len), "+{r5}" (*rlen)
                : "{r2}" ((addr_t)cpcmd_buf), "{r3}" ((addr_t)response), "d" (*rlen): "cc");
        return len;
}

Apart from being much easier to read because the hard regs become part
of the inline assembly it solves also a couple of other issues:

- function calls might clobber register asm variables see BZ100908
- the constraints for the register asm operands are superfluous
- one register asm variable cannot be used for 2 different inline
  assemblies if the value is expected in different hard regs

I've started with a hackish implementation for IBM Z using the
TARGET_MD_ASM_ADJUST hook and let all the places parsing constraints
skip over the {} parts.  But perhaps it would be useful to make this a
generic mechanism for all targets?!

Andreas

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: RFC: New mechanism for hard reg operands to inline asm
  2021-06-04 18:02 RFC: New mechanism for hard reg operands to inline asm Andreas Krebbel
@ 2021-06-04 18:18 ` Paul Koning
  2021-06-04 19:01   ` Andreas Krebbel
  2021-06-07 10:37   ` Richard Sandiford
  0 siblings, 2 replies; 4+ messages in thread
From: Paul Koning @ 2021-06-04 18:18 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: gcc



> On Jun 4, 2021, at 2:02 PM, Andreas Krebbel via Gcc <gcc@gcc.gnu.org> wrote:
> 
> Hi,
> 
> I wonder if we could replace the register asm construct for
> inline assemblies with something a bit nicer and more obvious.
> E.g. turning this (real world example from IBM Z kernel code):
> 
> int diag8_response(int cmdlen, char *response, int *rlen)
> {
>        register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
>        register unsigned long reg3 asm ("3") = (addr_t) response;
>        register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L;
>        register unsigned long reg5 asm ("5") = *rlen; /* <-- */
>        asm volatile(
>                "       diag    %2,%0,0x8\n"
>                "       brc     8,1f\n"
>                "       agr     %1,%4\n"
>                "1:\n"
>                : "+d" (reg4), "+d" (reg5)
>                : "d" (reg2), "d" (reg3), "d" (*rlen): "cc");
>        *rlen = reg5;
>        return reg4;
> }
> 
> into this:
> 
> int diag8_response(int cmdlen, char *response, int *rlen)
> {
>        unsigned long len = cmdlen | 0x40000000L;
> 
>        asm volatile(
>                "       diag    %2,%0,0x8\n"
>                "       brc     8,1f\n"
>                "       agr     %1,%4\n"
>                "1:\n"
>                : "+{r4}" (len), "+{r5}" (*rlen)
>                : "{r2}" ((addr_t)cpcmd_buf), "{r3}" ((addr_t)response), "d" (*rlen): "cc");
>        return len;
> }
> 
> Apart from being much easier to read because the hard regs become part
> of the inline assembly it solves also a couple of other issues:
> 
> - function calls might clobber register asm variables see BZ100908
> - the constraints for the register asm operands are superfluous
> - one register asm variable cannot be used for 2 different inline
>  assemblies if the value is expected in different hard regs
> 
> I've started with a hackish implementation for IBM Z using the
> TARGET_MD_ASM_ADJUST hook and let all the places parsing constraints
> skip over the {} parts.  But perhaps it would be useful to make this a
> generic mechanism for all targets?!
> 
> Andreas

Yes, I would think this should be made a general mechanism that any target could use.

I wonder if instead of creating a new mechanism you could do this simply by creating new constraint names, where each name matches exactly one hard register.  That's roughly what this amounts to, isn't it? 

	paul


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: RFC: New mechanism for hard reg operands to inline asm
  2021-06-04 18:18 ` Paul Koning
@ 2021-06-04 19:01   ` Andreas Krebbel
  2021-06-07 10:37   ` Richard Sandiford
  1 sibling, 0 replies; 4+ messages in thread
From: Andreas Krebbel @ 2021-06-04 19:01 UTC (permalink / raw)
  To: Paul Koning; +Cc: gcc

On 6/4/21 8:18 PM, Paul Koning wrote:
...
> Yes, I would think this should be made a general mechanism that any target could use.
> 
> I wonder if instead of creating a new mechanism you could do this simply by creating new constraint names, where each name matches exactly one hard register.  That's roughly what this amounts to, isn't it? 

I thought about this as well but I'm not sure this would work well without changing LRA. It would
mean to introduce many register classes with single registers. The presence of many "sparse"
register classes to my understanding would affect register allocation.

Perhaps it would work to just emit all the moves into or out of hard regs at expand time.

Andreas

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: RFC: New mechanism for hard reg operands to inline asm
  2021-06-04 18:18 ` Paul Koning
  2021-06-04 19:01   ` Andreas Krebbel
@ 2021-06-07 10:37   ` Richard Sandiford
  1 sibling, 0 replies; 4+ messages in thread
From: Richard Sandiford @ 2021-06-07 10:37 UTC (permalink / raw)
  To: Paul Koning via Gcc; +Cc: Andreas Krebbel, Paul Koning

Paul Koning via Gcc <gcc@gcc.gnu.org> writes:
>> On Jun 4, 2021, at 2:02 PM, Andreas Krebbel via Gcc <gcc@gcc.gnu.org> wrote:
>> 
>> Hi,
>> 
>> I wonder if we could replace the register asm construct for
>> inline assemblies with something a bit nicer and more obvious.
>> E.g. turning this (real world example from IBM Z kernel code):
>> 
>> int diag8_response(int cmdlen, char *response, int *rlen)
>> {
>>        register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
>>        register unsigned long reg3 asm ("3") = (addr_t) response;
>>        register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L;
>>        register unsigned long reg5 asm ("5") = *rlen; /* <-- */
>>        asm volatile(
>>                "       diag    %2,%0,0x8\n"
>>                "       brc     8,1f\n"
>>                "       agr     %1,%4\n"
>>                "1:\n"
>>                : "+d" (reg4), "+d" (reg5)
>>                : "d" (reg2), "d" (reg3), "d" (*rlen): "cc");
>>        *rlen = reg5;
>>        return reg4;
>> }
>> 
>> into this:
>> 
>> int diag8_response(int cmdlen, char *response, int *rlen)
>> {
>>        unsigned long len = cmdlen | 0x40000000L;
>> 
>>        asm volatile(
>>                "       diag    %2,%0,0x8\n"
>>                "       brc     8,1f\n"
>>                "       agr     %1,%4\n"
>>                "1:\n"
>>                : "+{r4}" (len), "+{r5}" (*rlen)
>>                : "{r2}" ((addr_t)cpcmd_buf), "{r3}" ((addr_t)response), "d" (*rlen): "cc");
>>        return len;
>> }
>> 
>> Apart from being much easier to read because the hard regs become part
>> of the inline assembly it solves also a couple of other issues:
>> 
>> - function calls might clobber register asm variables see BZ100908
>> - the constraints for the register asm operands are superfluous
>> - one register asm variable cannot be used for 2 different inline
>>  assemblies if the value is expected in different hard regs
>> 
>> I've started with a hackish implementation for IBM Z using the
>> TARGET_MD_ASM_ADJUST hook and let all the places parsing constraints
>> skip over the {} parts.  But perhaps it would be useful to make this a
>> generic mechanism for all targets?!
>> 
>> Andreas
>
> Yes, I would think this should be made a general mechanism that any target could use.

+1 FWIW.  I think this would also avoid the common confusion around
the semantics of register asms.

We would need to check whether { is used as a constraint string by
any target (hepefully not).

Richard

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-06-07 10:37 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-04 18:02 RFC: New mechanism for hard reg operands to inline asm Andreas Krebbel
2021-06-04 18:18 ` Paul Koning
2021-06-04 19:01   ` Andreas Krebbel
2021-06-07 10:37   ` Richard Sandiford

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).