Teaching expression() to treat some operations specially
Alan Modra
amodra@gmail.com
Mon Jul 11 01:01:13 GMT 2022
On Sat, Jul 09, 2022 at 07:47:26PM +0300, Dmitry Selyutin wrote:
> Hi folks, I'm still working on SVP64 extension support[0]. I'm now
> checking the SVP64 predicates[1].
> Recently I stumbled upon the need to be able to resolve some complex
> expressions as a single entity.
> Here's the exhaustive list we're going to support: 1<<r3, r3, ~r3,
> r10, ~r10, r30, ~r30, lt, nl, ge, gt, ng, le, eq, ne, so, un, ns, nu.
> All of these can be represented as macros. For example, let's consider
> the instruction `sv.setb/dm=~r3/sm=1<<r3 5, 31`.
> When SVP64 parsing code sees dm= or sm=, it simply iterates over the
> possible arguments[2].
> However, we'd also like to have macros support here, like:
>
> .set DM, ~r3
> .set SM, 1<<r3
> sv.setb/dm=DM/sm=SM 5, 31
>
> The obvious candidate was expression() routine, which I already
> re-used for a simpler case when the value is always a constant[3].
> However, things like 1<<r3 and ~r3 are more tricky, and I'm not sure
> how to handle these.
> expression() would, as it seems, defer the calculation, since r3 is a symbol.
> Instead, I'd like to teach expression() the knowledge that 1<<r3
> combination is special.
>
> Two places I've been thinking of are ppc_parse_name() and register_name().
> The first one "hooks" the name lookup algorithm, but it unsurprizingly
> only gets "r3" from "1<<r3".
> The second one seems like a minor hack, substituting expression()
> logic (in fact, expression() is a fallback for it).
PowerPC register operands are normally just plain numbers, or
expressions that resolve to a number. "r3" is normally just a
symbol, in fact people often use a bunch of defines to have a
preprocessor replace "r3" with plain "3". That said, the assembler
does recognise "%r3" as a register via register_name(), and plain "r3"
if you pass -mregnames to gas. However, it only does that at the
start of an operand expression. There's a good reason for that: We
don't want to confuse the gas lexing code into smashing '%' into
following alphas. We'd like '%' to have its normal meaning in a
modulus expression.
ppc_parse_name is a hook as you say (translating a register name to an
O_register expression) but only for CR regs and condition expresions
like "4*cr7+so". It is only enabled in contexts where such an
expression is expected, again because gas lexing is simplistic.
> To be honest, I'm not sure how to achieve the goal. In fact, I must
> teach expression() to treat some operations specially in some
> contexts.
It seems to me you will firstly need to parse your example
"sv.setb/dm=~r3/sm=1<<r3" into "sv.setb", "dm=", "~r3", "sm=", and
"1<<r3". You should modify ppc_parse_name to handle the new
register expressions in this context only (see cr_operand), and call
expression() on "~r3" and "1<<r3". You may find it better to create
O_constant values instead of O_register in your modified
ppc_parse_name, if you want ~r3 to resolve to 0xff..fffc early.
> Could you, please, recommend me options to achieve the goal? I want to
> keep the logic clear to anyone potentially reading this code later.
>
> Thank you!
>
> [0] https://libre-soc.org/
> [1] https://libre-soc.org/openpower/sv/svp64/appendix/
> [2] https://git.libre-soc.org/?p=binutils-gdb.git;a=blob;f=gas/config/tc-ppc-svp64.c;h=9dfafa20347f5085653439f7bd4d70c1710a205d;hb=refs/heads/svp64-ng#l144
> [3] https://git.libre-soc.org/?p=binutils-gdb.git;a=blob;f=gas/config/tc-ppc-svp64.c;h=9dfafa20347f5085653439f7bd4d70c1710a205d;hb=refs/heads/svp64-ng#l349
>
> --
> Best regards,
> Dmitry Selyutin
--
Alan Modra
Australia Development Lab, IBM
More information about the Binutils
mailing list