Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

"If that makes any sense to you, you have a big problem." -- C. Durance, Computer Science 234


devel / comp.arch / Re: Using vector registers to stack return addresses

SubjectAuthor
* Using vector registers to stack return addressesrobf...@gmail.com
+- Re: Using vector registers to stack return addressesMitchAlsup
`* Re: Using vector registers to stack return addressesEricP
 `* Re: Using vector registers to stack return addressesrobf...@gmail.com
  +* Re: Using vector registers to stack return addressesBGB
  |`* Re: Using vector registers to stack return addressesMitchAlsup
  | `- Re: Using vector registers to stack return addressesBGB
  `- Re: Using vector registers to stack return addressesMitchAlsup

1
Using vector registers to stack return addresses

<27269b16-7d65-45a6-bd4a-b00d4b50b9d5n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=27710&group=comp.arch#27710

  copy link   Newsgroups: comp.arch
X-Received: by 2002:a05:620a:424c:b0:6be:78d5:ec73 with SMTP id w12-20020a05620a424c00b006be78d5ec73mr12367623qko.579.1662793458107;
Sat, 10 Sep 2022 00:04:18 -0700 (PDT)
X-Received: by 2002:a05:620a:1b8e:b0:6bb:f85e:6de0 with SMTP id
dv14-20020a05620a1b8e00b006bbf85e6de0mr12757853qkb.618.1662793457942; Sat, 10
Sep 2022 00:04:17 -0700 (PDT)
Path: i2pn2.org!i2pn.org!aioe.org!news.mixmin.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.arch
Date: Sat, 10 Sep 2022 00:04:17 -0700 (PDT)
Injection-Info: google-groups.googlegroups.com; posting-host=99.251.79.92; posting-account=QId4bgoAAABV4s50talpu-qMcPp519Eb
NNTP-Posting-Host: 99.251.79.92
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <27269b16-7d65-45a6-bd4a-b00d4b50b9d5n@googlegroups.com>
Subject: Using vector registers to stack return addresses
From: robfi...@gmail.com (robf...@gmail.com)
Injection-Date: Sat, 10 Sep 2022 07:04:18 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
 by: robf...@gmail.com - Sat, 10 Sep 2022 07:04 UTC

I got to thinking looking at the Phoenix ISA that it would be trimming only one
bit from the target address of a call instruction to allow storing the return
address in a vector register. Since instructions are 40-bit that left 27 bits for
the target which is more than enough. (Targets can be extended further with
postfix constants). The vector register could then be used as a return address
stack if the function call depth were known to be limited. A vector slide
operation in the function prologue / epilogue could take care of being able to
call other functions.

I was looking for more information on the use of vector registers for function
calls. And is this sort of thing supported by compilers?

Call v63,,My_rout

My_rout:
VSLLVI v63,v63,1 # stack return address in vector register

Call SomeFn # better not go more than 12 deep

VSRLVI v63,v63,1 # restore return address
RET

Re: Using vector registers to stack return addresses

<2de69772-2d18-4fd3-8133-7661596a9d11n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=27718&group=comp.arch#27718

  copy link   Newsgroups: comp.arch
X-Received: by 2002:ae9:ef4f:0:b0:6cb:d294:3333 with SMTP id d76-20020ae9ef4f000000b006cbd2943333mr9140876qkg.511.1662830906167;
Sat, 10 Sep 2022 10:28:26 -0700 (PDT)
X-Received: by 2002:a05:620a:278d:b0:6bb:1435:c0bd with SMTP id
g13-20020a05620a278d00b006bb1435c0bdmr14107505qkp.291.1662830906033; Sat, 10
Sep 2022 10:28:26 -0700 (PDT)
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!feed1.usenet.blueworldhosting.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.arch
Date: Sat, 10 Sep 2022 10:28:25 -0700 (PDT)
In-Reply-To: <27269b16-7d65-45a6-bd4a-b00d4b50b9d5n@googlegroups.com>
Injection-Info: google-groups.googlegroups.com; posting-host=2600:1700:291:29f0:99c4:d26d:63cc:d1ca;
posting-account=H_G_JQkAAADS6onOMb-dqvUozKse7mcM
NNTP-Posting-Host: 2600:1700:291:29f0:99c4:d26d:63cc:d1ca
References: <27269b16-7d65-45a6-bd4a-b00d4b50b9d5n@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <2de69772-2d18-4fd3-8133-7661596a9d11n@googlegroups.com>
Subject: Re: Using vector registers to stack return addresses
From: MitchAl...@aol.com (MitchAlsup)
Injection-Date: Sat, 10 Sep 2022 17:28:26 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Received-Bytes: 2799
 by: MitchAlsup - Sat, 10 Sep 2022 17:28 UTC

On Saturday, September 10, 2022 at 2:04:19 AM UTC-5, robf...@gmail.com wrote:
> I got to thinking looking at the Phoenix ISA that it would be trimming only one
> bit from the target address of a call instruction to allow storing the return
> address in a vector register. Since instructions are 40-bit that left 27 bits for
> the target which is more than enough. (Targets can be extended further with
> postfix constants). The vector register could then be used as a return address
> stack if the function call depth were known to be limited. A vector slide
> operation in the function prologue / epilogue could take care of being able to
> call other functions.
>
> I was looking for more information on the use of vector registers for function
> calls. And is this sort of thing supported by compilers?
>
> Call v63,,My_rout
> …
> My_rout:
> VSLLVI v63,v63,1 # stack return address in vector register
> …
> Call SomeFn # better not go more than 12 deep
> …
> VSRLVI v63,v63,1 # restore return address
> RET
<
I went the other way:: When safe stack is in use, the return address is not
placed in R0, but on a stack where LD and ST instructions will take Faults,
but ENTER and EXIT work as desired. That is secure from ROP, and buffer
overrun attack strategies.
<
Other than "there are a crap load of individual containers" in CRAY-like vector
machines, I can't see how the boundary cases are handled with aplomb.

Re: Using vector registers to stack return addresses

<Oy4TK.337081$6Il8.301108@fx14.iad>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=27722&group=comp.arch#27722

  copy link   Newsgroups: comp.arch
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!feed1.usenet.blueworldhosting.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!fx14.iad.POSTED!not-for-mail
From: ThatWoul...@thevillage.com (EricP)
User-Agent: Thunderbird 2.0.0.24 (Windows/20100228)
MIME-Version: 1.0
Newsgroups: comp.arch
Subject: Re: Using vector registers to stack return addresses
References: <27269b16-7d65-45a6-bd4a-b00d4b50b9d5n@googlegroups.com>
In-Reply-To: <27269b16-7d65-45a6-bd4a-b00d4b50b9d5n@googlegroups.com>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Lines: 32
Message-ID: <Oy4TK.337081$6Il8.301108@fx14.iad>
X-Complaints-To: abuse@UsenetServer.com
NNTP-Posting-Date: Sat, 10 Sep 2022 18:19:26 UTC
Date: Sat, 10 Sep 2022 14:18:57 -0400
X-Received-Bytes: 2076
 by: EricP - Sat, 10 Sep 2022 18:18 UTC

robf...@gmail.com wrote:
> I got to thinking looking at the Phoenix ISA that it would be trimming only one
> bit from the target address of a call instruction to allow storing the return
> address in a vector register. Since instructions are 40-bit that left 27 bits for
> the target which is more than enough. (Targets can be extended further with
> postfix constants). The vector register could then be used as a return address
> stack if the function call depth were known to be limited. A vector slide
> operation in the function prologue / epilogue could take care of being able to
> call other functions.
>
> I was looking for more information on the use of vector registers for function
> calls. And is this sort of thing supported by compilers?
>
> Call v63,,My_rout
> …
> My_rout:
> VSLLVI v63,v63,1 # stack return address in vector register
> …
> Call SomeFn # better not go more than 12 deep
> …
> VSRLVI v63,v63,1 # restore return address
> RET

Sounds like a variation on register windows which had good cache-hit
performance but also some clunky parts for particular implementations.
Dealing with asynchronous non-coherence is in part what makes it clunky.

My guess is you would probably find similar performance stats to
register windows, and similar clunky parts like dealing with
overflows, underflows, setjmp and exceptions.

Re: Using vector registers to stack return addresses

<ea9e86dd-72ca-4a44-9aec-9eb433125974n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=27732&group=comp.arch#27732

  copy link   Newsgroups: comp.arch
X-Received: by 2002:a0c:aa19:0:b0:4ac:fb0:8a75 with SMTP id d25-20020a0caa19000000b004ac0fb08a75mr16405549qvb.36.1662878881175;
Sat, 10 Sep 2022 23:48:01 -0700 (PDT)
X-Received: by 2002:a05:622a:214:b0:342:f97c:1706 with SMTP id
b20-20020a05622a021400b00342f97c1706mr18592240qtx.291.1662878881041; Sat, 10
Sep 2022 23:48:01 -0700 (PDT)
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!news.misty.com!border-2.nntp.ord.giganews.com!nntp.giganews.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.arch
Date: Sat, 10 Sep 2022 23:48:00 -0700 (PDT)
In-Reply-To: <Oy4TK.337081$6Il8.301108@fx14.iad>
Injection-Info: google-groups.googlegroups.com; posting-host=99.251.79.92; posting-account=QId4bgoAAABV4s50talpu-qMcPp519Eb
NNTP-Posting-Host: 99.251.79.92
References: <27269b16-7d65-45a6-bd4a-b00d4b50b9d5n@googlegroups.com> <Oy4TK.337081$6Il8.301108@fx14.iad>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <ea9e86dd-72ca-4a44-9aec-9eb433125974n@googlegroups.com>
Subject: Re: Using vector registers to stack return addresses
From: robfi...@gmail.com (robf...@gmail.com)
Injection-Date: Sun, 11 Sep 2022 06:48:01 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Lines: 56
 by: robf...@gmail.com - Sun, 11 Sep 2022 06:48 UTC

On Saturday, September 10, 2022 at 2:19:29 PM UTC-4, EricP wrote:
> robf...@gmail.com wrote:
> > I got to thinking looking at the Phoenix ISA that it would be trimming only one
> > bit from the target address of a call instruction to allow storing the return
> > address in a vector register. Since instructions are 40-bit that left 27 bits for
> > the target which is more than enough. (Targets can be extended further with
> > postfix constants). The vector register could then be used as a return address
> > stack if the function call depth were known to be limited. A vector slide
> > operation in the function prologue / epilogue could take care of being able to
> > call other functions.
> >
> > I was looking for more information on the use of vector registers for function
> > calls. And is this sort of thing supported by compilers?
> >
> > Call v63,,My_rout
> > …
> > My_rout:
> > VSLLVI v63,v63,1 # stack return address in vector register
> > …
> > Call SomeFn # better not go more than 12 deep
> > …
> > VSRLVI v63,v63,1 # restore return address
> > RET
> Sounds like a variation on register windows which had good cache-hit
> performance but also some clunky parts for particular implementations.
> Dealing with asynchronous non-coherence is in part what makes it clunky.
>
> My guess is you would probably find similar performance stats to
> register windows, and similar clunky parts like dealing with
> overflows, underflows, setjmp and exceptions.

Back to the drawing board. It was another late-night idea. Next idea is to use a
small stack of regs with lazy writes to memory. Other than leaf function the
return address ends up on the stack anyway, therefore it may be better to go
without a dedicated return address register.

I like the ENTER / EXIT approach. It makes things simple. But I do not want to
add micro-code to the current project. So, some assembler macros could be
used to implement ENTER and EXIT.

For safe stack, do return addresses have their own stack independent of
function arguments within a memory page that does not allow LD / ST?

Re: Using vector registers to stack return addresses

<tfk3iv$1rsg2$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=27733&group=comp.arch#27733

  copy link   Newsgroups: comp.arch
Path: i2pn2.org!i2pn.org!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: cr88...@gmail.com (BGB)
Newsgroups: comp.arch
Subject: Re: Using vector registers to stack return addresses
Date: Sun, 11 Sep 2022 02:43:15 -0500
Organization: A noiseless patient Spider
Lines: 113
Message-ID: <tfk3iv$1rsg2$1@dont-email.me>
References: <27269b16-7d65-45a6-bd4a-b00d4b50b9d5n@googlegroups.com>
<Oy4TK.337081$6Il8.301108@fx14.iad>
<ea9e86dd-72ca-4a44-9aec-9eb433125974n@googlegroups.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Sun, 11 Sep 2022 07:43:27 -0000 (UTC)
Injection-Info: reader01.eternal-september.org; posting-host="31e7b1c25fa2b32bd98cb63416abc0d6";
logging-data="1962498"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/sTrEXZV6ET/XtWpdTEgeF"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101
Thunderbird/91.13.0
Cancel-Lock: sha1:JjlDfjyZETG9Esj6igRlK4DbisA=
Content-Language: en-US
In-Reply-To: <ea9e86dd-72ca-4a44-9aec-9eb433125974n@googlegroups.com>
 by: BGB - Sun, 11 Sep 2022 07:43 UTC

On 9/11/2022 1:48 AM, robf...@gmail.com wrote:
> On Saturday, September 10, 2022 at 2:19:29 PM UTC-4, EricP wrote:
>> robf...@gmail.com wrote:
>>> I got to thinking looking at the Phoenix ISA that it would be trimming only one
>>> bit from the target address of a call instruction to allow storing the return
>>> address in a vector register. Since instructions are 40-bit that left 27 bits for
>>> the target which is more than enough. (Targets can be extended further with
>>> postfix constants). The vector register could then be used as a return address
>>> stack if the function call depth were known to be limited. A vector slide
>>> operation in the function prologue / epilogue could take care of being able to
>>> call other functions.
>>>
>>> I was looking for more information on the use of vector registers for function
>>> calls. And is this sort of thing supported by compilers?
>>>
>>> Call v63,,My_rout
>>> …
>>> My_rout:
>>> VSLLVI v63,v63,1 # stack return address in vector register
>>> …
>>> Call SomeFn # better not go more than 12 deep
>>> …
>>> VSRLVI v63,v63,1 # restore return address
>>> RET
>> Sounds like a variation on register windows which had good cache-hit
>> performance but also some clunky parts for particular implementations.
>> Dealing with asynchronous non-coherence is in part what makes it clunky.
>>
>> My guess is you would probably find similar performance stats to
>> register windows, and similar clunky parts like dealing with
>> overflows, underflows, setjmp and exceptions.
>
> Back to the drawing board. It was another late-night idea. Next idea is to use a
> small stack of regs with lazy writes to memory. Other than leaf function the
> return address ends up on the stack anyway, therefore it may be better to go
> without a dedicated return address register.
>
> I like the ENTER / EXIT approach. It makes things simple. But I do not want to
> add micro-code to the current project. So, some assembler macros could be
> used to implement ENTER and EXIT.
>
> For safe stack, do return addresses have their own stack independent of
> function arguments within a memory page that does not allow LD / ST?
>
>

FWIW: In my case, I just use normal memory for the stack frames (though
this does not allow for "safe stack").

Much of the time though, the compiler does add "stack canaries" which
will trigger a breakpoint if trying to return from a function which does
not have these values intact (no real way to disable these at present;
but they are skipped for small leaf functions and similar).

Well, I could also probably consider adding an option to skip on adding
exception-unwinding cruft, since this is detrimental to code density,
and generally C does not use try/catch exception (but, if exceptions
could potentially occur anywhere, this unwinding cruft is needed along
pretty much the entire call stack).

Some things, like the Boot ROM though, are not going to use try/catch
exceptions (ever), so it is basically a pure overhead in this case.

But, they are still less overhead than would be needed to support things
like "call with current continuation" or fine-grained "async"; which
would effectively also require non-trivial ABI modifications. Currently
BGBCC still uses a more traditional ABI design which by itself could not
natively support call/cc or async. Assuming both are implemented
internally on top of continuations; which in turn effectively also imply
the using heap allocation for parts of the call frames and similar. Note
that at present, VLAs, lambdas, and "alloca()", are already implemented
via heap-allocating this stuff, but lambda capture rules are restricted
in a way that they are still compatible with a traditional C style ABI
(they are not quite as generalized as in Common Lisp or Scheme, but
these semantics would also require ABI tweaks and would have a non-zero
performance impact).

Not really sure if more mainstream compilers have better options for a
lot of this.

Though, I did come up with a trick that (usually) allows
branch-predicting the return:
The return link register is loaded into a register before reloading the
other registers.

So, the idea here is that by the time it reaches the final return
instruction (usually encoded as "JMP R1" in this case), the load has
already finished, and the branch predictor (with side-channel inputs for
LR and R1) can special-case the branch instruction (if the load has not
finished, it falls back to the slower "generic" case used for most other
registers).

Early on, there was a "RET" instruction which would pop a value from the
stack and then branch to it, but it was dropped around the same time I
dropped the PUSH/POP instructions in favor of normal memory Load/Store.

Similarly:
Reload original LR into R1;
Reload other registers;
Adjust Stack;
Jump to R1.

Is also generally faster than the original RET instruction would have
been (roughly 12 clock cycles).

Partial issue would have also existed with PUSH/POP, which would have
been slower on average than plain Load/Store (as well as also needing
special internal plumbing for the SP adjustments).

Re: Using vector registers to stack return addresses

<168a6e7a-3217-4eaa-81f5-fd76f464f9een@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=27741&group=comp.arch#27741

  copy link   Newsgroups: comp.arch
X-Received: by 2002:a05:6214:27e2:b0:4ac:97ba:57b5 with SMTP id jt2-20020a05621427e200b004ac97ba57b5mr6935529qvb.130.1662914839773;
Sun, 11 Sep 2022 09:47:19 -0700 (PDT)
X-Received: by 2002:a05:622a:214:b0:342:f97c:1706 with SMTP id
b20-20020a05622a021400b00342f97c1706mr20089805qtx.291.1662914839613; Sun, 11
Sep 2022 09:47:19 -0700 (PDT)
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!feed1.usenet.blueworldhosting.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.arch
Date: Sun, 11 Sep 2022 09:47:19 -0700 (PDT)
In-Reply-To: <ea9e86dd-72ca-4a44-9aec-9eb433125974n@googlegroups.com>
Injection-Info: google-groups.googlegroups.com; posting-host=2600:1700:291:29f0:25a1:8cc0:ef77:159d;
posting-account=H_G_JQkAAADS6onOMb-dqvUozKse7mcM
NNTP-Posting-Host: 2600:1700:291:29f0:25a1:8cc0:ef77:159d
References: <27269b16-7d65-45a6-bd4a-b00d4b50b9d5n@googlegroups.com>
<Oy4TK.337081$6Il8.301108@fx14.iad> <ea9e86dd-72ca-4a44-9aec-9eb433125974n@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <168a6e7a-3217-4eaa-81f5-fd76f464f9een@googlegroups.com>
Subject: Re: Using vector registers to stack return addresses
From: MitchAl...@aol.com (MitchAlsup)
Injection-Date: Sun, 11 Sep 2022 16:47:19 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Received-Bytes: 3938
 by: MitchAlsup - Sun, 11 Sep 2022 16:47 UTC

On Sunday, September 11, 2022 at 1:48:02 AM UTC-5, robf...@gmail.com wrote:
> On Saturday, September 10, 2022 at 2:19:29 PM UTC-4, EricP wrote:
> > robf...@gmail.com wrote:
> > > I got to thinking looking at the Phoenix ISA that it would be trimming only one
> > > bit from the target address of a call instruction to allow storing the return
> > > address in a vector register. Since instructions are 40-bit that left 27 bits for
> > > the target which is more than enough. (Targets can be extended further with
> > > postfix constants). The vector register could then be used as a return address
> > > stack if the function call depth were known to be limited. A vector slide
> > > operation in the function prologue / epilogue could take care of being able to
> > > call other functions.
> > >
> > > I was looking for more information on the use of vector registers for function
> > > calls. And is this sort of thing supported by compilers?
> > >
> > > Call v63,,My_rout
> > > …
> > > My_rout:
> > > VSLLVI v63,v63,1 # stack return address in vector register
> > > …
> > > Call SomeFn # better not go more than 12 deep
> > > …
> > > VSRLVI v63,v63,1 # restore return address
> > > RET
> > Sounds like a variation on register windows which had good cache-hit
> > performance but also some clunky parts for particular implementations.
> > Dealing with asynchronous non-coherence is in part what makes it clunky..
> >
> > My guess is you would probably find similar performance stats to
> > register windows, and similar clunky parts like dealing with
> > overflows, underflows, setjmp and exceptions.
> Back to the drawing board. It was another late-night idea. Next idea is to use a
> small stack of regs with lazy writes to memory. Other than leaf function the
> return address ends up on the stack anyway, therefore it may be better to go
> without a dedicated return address register.
>
> I like the ENTER / EXIT approach. It makes things simple. But I do not want to
> add micro-code to the current project. So, some assembler macros could be
> used to implement ENTER and EXIT.
>
> For safe stack, do return addresses have their own stack independent of
> function arguments within a memory page that does not allow LD / ST?
<
Return address and the preserved registers go on the safe-stack, anything
else goes on the normal stack (varargs arguments, for example.)

Re: Using vector registers to stack return addresses

<0086320d-c292-454c-974e-e67efa37279cn@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=27743&group=comp.arch#27743

  copy link   Newsgroups: comp.arch
X-Received: by 2002:a05:6214:19c2:b0:4aa:9e70:cff3 with SMTP id j2-20020a05621419c200b004aa9e70cff3mr19985605qvc.49.1662915335740;
Sun, 11 Sep 2022 09:55:35 -0700 (PDT)
X-Received: by 2002:a05:620a:2547:b0:6cb:b18c:dba7 with SMTP id
s7-20020a05620a254700b006cbb18cdba7mr14932667qko.441.1662915335601; Sun, 11
Sep 2022 09:55:35 -0700 (PDT)
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!news.misty.com!border-2.nntp.ord.giganews.com!nntp.giganews.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.arch
Date: Sun, 11 Sep 2022 09:55:35 -0700 (PDT)
In-Reply-To: <tfk3iv$1rsg2$1@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=2600:1700:291:29f0:25a1:8cc0:ef77:159d;
posting-account=H_G_JQkAAADS6onOMb-dqvUozKse7mcM
NNTP-Posting-Host: 2600:1700:291:29f0:25a1:8cc0:ef77:159d
References: <27269b16-7d65-45a6-bd4a-b00d4b50b9d5n@googlegroups.com>
<Oy4TK.337081$6Il8.301108@fx14.iad> <ea9e86dd-72ca-4a44-9aec-9eb433125974n@googlegroups.com>
<tfk3iv$1rsg2$1@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <0086320d-c292-454c-974e-e67efa37279cn@googlegroups.com>
Subject: Re: Using vector registers to stack return addresses
From: MitchAl...@aol.com (MitchAlsup)
Injection-Date: Sun, 11 Sep 2022 16:55:35 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Lines: 155
 by: MitchAlsup - Sun, 11 Sep 2022 16:55 UTC

On Sunday, September 11, 2022 at 2:43:30 AM UTC-5, BGB wrote:
> On 9/11/2022 1:48 AM, robf...@gmail.com wrote:
> > On Saturday, September 10, 2022 at 2:19:29 PM UTC-4, EricP wrote:
> >> robf...@gmail.com wrote:
> >>> I got to thinking looking at the Phoenix ISA that it would be trimming only one
> >>> bit from the target address of a call instruction to allow storing the return
> >>> address in a vector register. Since instructions are 40-bit that left 27 bits for
> >>> the target which is more than enough. (Targets can be extended further with
> >>> postfix constants). The vector register could then be used as a return address
> >>> stack if the function call depth were known to be limited. A vector slide
> >>> operation in the function prologue / epilogue could take care of being able to
> >>> call other functions.
> >>>
> >>> I was looking for more information on the use of vector registers for function
> >>> calls. And is this sort of thing supported by compilers?
> >>>
> >>> Call v63,,My_rout
> >>> …
> >>> My_rout:
> >>> VSLLVI v63,v63,1 # stack return address in vector register
> >>> …
> >>> Call SomeFn # better not go more than 12 deep
> >>> …
> >>> VSRLVI v63,v63,1 # restore return address
> >>> RET
> >> Sounds like a variation on register windows which had good cache-hit
> >> performance but also some clunky parts for particular implementations.
> >> Dealing with asynchronous non-coherence is in part what makes it clunky.
> >>
> >> My guess is you would probably find similar performance stats to
> >> register windows, and similar clunky parts like dealing with
> >> overflows, underflows, setjmp and exceptions.
> >
> > Back to the drawing board. It was another late-night idea. Next idea is to use a
> > small stack of regs with lazy writes to memory. Other than leaf function the
> > return address ends up on the stack anyway, therefore it may be better to go
> > without a dedicated return address register.
> >
> > I like the ENTER / EXIT approach. It makes things simple. But I do not want to
> > add micro-code to the current project. So, some assembler macros could be
> > used to implement ENTER and EXIT.
> >
> > For safe stack, do return addresses have their own stack independent of
> > function arguments within a memory page that does not allow LD / ST?
> >
> >
> FWIW: In my case, I just use normal memory for the stack frames (though
> this does not allow for "safe stack").
>
>
> Much of the time though, the compiler does add "stack canaries" which
> will trigger a breakpoint if trying to return from a function which does
> not have these values intact (no real way to disable these at present;
> but they are skipped for small leaf functions and similar).
>
> Well, I could also probably consider adding an option to skip on adding
> exception-unwinding cruft, since this is detrimental to code density,
> and generally C does not use try/catch exception (but, if exceptions
> could potentially occur anywhere, this unwinding cruft is needed along
> pretty much the entire call stack).
>
> Some things, like the Boot ROM though, are not going to use try/catch
> exceptions (ever), so it is basically a pure overhead in this case.
>
> But, they are still less overhead than would be needed to support things
> like "call with current continuation" or fine-grained "async"; which
> would effectively also require non-trivial ABI modifications. Currently
> BGBCC still uses a more traditional ABI design which by itself could not
> natively support call/cc or async. Assuming both are implemented
> internally on top of continuations; which in turn effectively also imply
> the using heap allocation for parts of the call frames and similar. Note
> that at present, VLAs, lambdas, and "alloca()", are already implemented
> via heap-allocating this stuff, but lambda capture rules are restricted
> in a way that they are still compatible with a traditional C style ABI
> (they are not quite as generalized as in Common Lisp or Scheme, but
> these semantics would also require ABI tweaks and would have a non-zero
> performance impact).
>
> Not really sure if more mainstream compilers have better options for a
> lot of this.
>
>
>
> Though, I did come up with a trick that (usually) allows
> branch-predicting the return:
> The return link register is loaded into a register before reloading the
> other registers.
<
EXIT does this:: EXIT reads the return address first, and then proceeds
to reload the preserved registers, so instructions at return target are
available when all the registers have been reloaded. As long as the
first instructions at return target are not memory-references, those
instructions can be performed while register reload is in progress.
<
Due to typical semantics of RET, compilers cannot do this with
code scheduling (movement). Also note: return address does not
pass through (and thereby wasting) a register.
>
> So, the idea here is that by the time it reaches the final return
> instruction (usually encoded as "JMP R1" in this case), the load has
> already finished, and the branch predictor (with side-channel inputs for
> LR and R1) can special-case the branch instruction (if the load has not
> finished, it falls back to the slower "generic" case used for most other
> registers).
>
>
> Early on, there was a "RET" instruction which would pop a value from the
> stack and then branch to it, but it was dropped around the same time I
> dropped the PUSH/POP instructions in favor of normal memory Load/Store.
>
> Similarly:
> Reload original LR into R1;
> Reload other registers;
> Adjust Stack;
> Jump to R1.
>
> Is also generally faster than the original RET instruction would have
> been (roughly 12 clock cycles).
>
> Partial issue would have also existed with PUSH/POP, which would have
> been slower on average than plain Load/Store (as well as also needing
> special internal plumbing for the SP adjustments).

Re: Using vector registers to stack return addresses

<tfllpf$21tfp$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=27752&group=comp.arch#27752

  copy link   Newsgroups: comp.arch
Path: i2pn2.org!i2pn.org!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: cr88...@gmail.com (BGB)
Newsgroups: comp.arch
Subject: Re: Using vector registers to stack return addresses
Date: Sun, 11 Sep 2022 17:00:04 -0500
Organization: A noiseless patient Spider
Lines: 460
Message-ID: <tfllpf$21tfp$1@dont-email.me>
References: <27269b16-7d65-45a6-bd4a-b00d4b50b9d5n@googlegroups.com>
<Oy4TK.337081$6Il8.301108@fx14.iad>
<ea9e86dd-72ca-4a44-9aec-9eb433125974n@googlegroups.com>
<tfk3iv$1rsg2$1@dont-email.me>
<0086320d-c292-454c-974e-e67efa37279cn@googlegroups.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Sun, 11 Sep 2022 22:00:15 -0000 (UTC)
Injection-Info: reader01.eternal-september.org; posting-host="9220780c576cbb768b11b80b6a759fe4";
logging-data="2160121"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+OrewyFigvHVv7fB89oSnW"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101
Thunderbird/91.13.0
Cancel-Lock: sha1:zWDEcNTJXbaySB1iMz6w4w5nFYg=
In-Reply-To: <0086320d-c292-454c-974e-e67efa37279cn@googlegroups.com>
Content-Language: en-US
 by: BGB - Sun, 11 Sep 2022 22:00 UTC

On 9/11/2022 11:55 AM, MitchAlsup wrote:
> On Sunday, September 11, 2022 at 2:43:30 AM UTC-5, BGB wrote:
>> On 9/11/2022 1:48 AM, robf...@gmail.com wrote:
>>> On Saturday, September 10, 2022 at 2:19:29 PM UTC-4, EricP wrote:
>>>> robf...@gmail.com wrote:
>>>>> I got to thinking looking at the Phoenix ISA that it would be trimming only one
>>>>> bit from the target address of a call instruction to allow storing the return
>>>>> address in a vector register. Since instructions are 40-bit that left 27 bits for
>>>>> the target which is more than enough. (Targets can be extended further with
>>>>> postfix constants). The vector register could then be used as a return address
>>>>> stack if the function call depth were known to be limited. A vector slide
>>>>> operation in the function prologue / epilogue could take care of being able to
>>>>> call other functions.
>>>>>
>>>>> I was looking for more information on the use of vector registers for function
>>>>> calls. And is this sort of thing supported by compilers?
>>>>>
>>>>> Call v63,,My_rout
>>>>> …
>>>>> My_rout:
>>>>> VSLLVI v63,v63,1 # stack return address in vector register
>>>>> …
>>>>> Call SomeFn # better not go more than 12 deep
>>>>> …
>>>>> VSRLVI v63,v63,1 # restore return address
>>>>> RET
>>>> Sounds like a variation on register windows which had good cache-hit
>>>> performance but also some clunky parts for particular implementations.
>>>> Dealing with asynchronous non-coherence is in part what makes it clunky.
>>>>
>>>> My guess is you would probably find similar performance stats to
>>>> register windows, and similar clunky parts like dealing with
>>>> overflows, underflows, setjmp and exceptions.
>>>
>>> Back to the drawing board. It was another late-night idea. Next idea is to use a
>>> small stack of regs with lazy writes to memory. Other than leaf function the
>>> return address ends up on the stack anyway, therefore it may be better to go
>>> without a dedicated return address register.
>>>
>>> I like the ENTER / EXIT approach. It makes things simple. But I do not want to
>>> add micro-code to the current project. So, some assembler macros could be
>>> used to implement ENTER and EXIT.
>>>
>>> For safe stack, do return addresses have their own stack independent of
>>> function arguments within a memory page that does not allow LD / ST?
>>>
>>>
>> FWIW: In my case, I just use normal memory for the stack frames (though
>> this does not allow for "safe stack").
>>
>>
>> Much of the time though, the compiler does add "stack canaries" which
>> will trigger a breakpoint if trying to return from a function which does
>> not have these values intact (no real way to disable these at present;
>> but they are skipped for small leaf functions and similar).
>>
>> Well, I could also probably consider adding an option to skip on adding
>> exception-unwinding cruft, since this is detrimental to code density,
>> and generally C does not use try/catch exception (but, if exceptions
>> could potentially occur anywhere, this unwinding cruft is needed along
>> pretty much the entire call stack).
>>
>> Some things, like the Boot ROM though, are not going to use try/catch
>> exceptions (ever), so it is basically a pure overhead in this case.
>>
>> But, they are still less overhead than would be needed to support things
>> like "call with current continuation" or fine-grained "async"; which
>> would effectively also require non-trivial ABI modifications. Currently
>> BGBCC still uses a more traditional ABI design which by itself could not
>> natively support call/cc or async. Assuming both are implemented
>> internally on top of continuations; which in turn effectively also imply
>> the using heap allocation for parts of the call frames and similar. Note
>> that at present, VLAs, lambdas, and "alloca()", are already implemented
>> via heap-allocating this stuff, but lambda capture rules are restricted
>> in a way that they are still compatible with a traditional C style ABI
>> (they are not quite as generalized as in Common Lisp or Scheme, but
>> these semantics would also require ABI tweaks and would have a non-zero
>> performance impact).
>>
>> Not really sure if more mainstream compilers have better options for a
>> lot of this.
>>
>>
>>
>> Though, I did come up with a trick that (usually) allows
>> branch-predicting the return:
>> The return link register is loaded into a register before reloading the
>> other registers.
> <
> EXIT does this:: EXIT reads the return address first, and then proceeds
> to reload the preserved registers, so instructions at return target are
> available when all the registers have been reloaded. As long as the
> first instructions at return target are not memory-references, those
> instructions can be performed while register reload is in progress.
> <
> Due to typical semantics of RET, compilers cannot do this with
> code scheduling (movement). Also note: return address does not
> pass through (and thereby wasting) a register.

There are partial reasons I eliminated things like POP and RET.

Say:
POP.X Rn // 3 cycles every time.
MOV.X (SP, disp), Rn // 1 cycle on average

RET: ~ 12 cycles

And:
MOV.Q (SP, disp), R1 // 1 cycle
...
JMP R1 // 2 cycles

Though, this uses R1 because the MOV.C instruction is not part of the
core ISA, and R1 has ended being defined as a de-facto "secondary link
register".

Prolog:
ADD -xxx, SP
MOV LR, R1 //1c
MOV.Q R1, (SP, disp) //1c

For prolog compression, it is usually copied to R18.
In the 128-bit ABI, R19:R18 is used for the "this" pointer (in C++ and
BS2 modes), where in the 64-bit ABI, R3 is used for "this".

Stack canary checks will add some cases like:
LDIZ xxxx, R16 // 1c
MOV.Q R16, (SP, disp) // 1c
...
MOV.Q (SP, disp), R16 // 2c
LDIZ xxxx, R17 // 1c
CMPQEQ R16, R17 // 1c
BREAK?F // 1c

So, adds around 7 cycles to each function call/return when used, with
xxxx as a combination of pseudo-random and hash number.

Generally, it is used to protect the saved register area of the stack
from potential damage due to buffer overruns.

OTOH:

The exception handling mechanism was derived from a similar design to
that used in WinCE and Win64 (and by MSVC++). It does not add any
(explicit) run-time overhead, but does add code space overhead.
Typically a small blob of instructions after the epilog which interacts
with the exception-winding mechanism, and would be where one would put
any code for dispatching into "catch" blocks.

This is combined with a table that basically encodes ranges of ".text"
addresses used to locate the corresponding unwind/catch handlers for a
given PC address (with some bit-twiddly and trickery used to try to keep
this table reasonably compact, *).

This has a non-zero space overhead.

*: For Doom, this table is ~ 3% of the total binary size, with an
additional ~ 7% overhead due to the per-function unwind handling logic,
adding around 10% to the size of the binary.

The alternative would be do have done it more like Win32 SEH, which
would have less average code-footprint overhead for C, but would have a
more significant cost overhead for each try/catch block (which would now
need to do something akin to a "setjmp" along with adding an exception
handler to a linked list).

Say, Pseudocode for such a mechanism:
jmp_buf_ex_t t_eh;
jmp_buf_ex_t *eh, *old_eh;
taskinfo_t *tki;

eh = &t_eh;
if(__setjmp_ex(eh))
{
... catch handling ...
}else
{
tki = __arch_tbr;
old_eh = tki->seh_prr;
eh->next = old_eh;
tki->seh_ptr = eh;
... try block ...
tki->seh_ptr = old_eh;
}

The argument though, is that this would makes the average case cost of
each "try" block significantly higher in the "no exception was thrown"
case. Similarly, it would also (significantly) increase the cost of
things like RAII destructors (if throwing an exception is assumed to
also call any destructors along the call graph).

But, the (current) vectored mechanism sort of deals with this by making
everything more expensive whether it uses exceptions or not (where it
can be argued that C code has no use for exceptions, and ideally C code
can just use "signal" or similar as a fallback; where an uncaught
exception and/or unwind failure would turn it into a "signal").


Click here to read the complete article
1
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor