Hi,
I'm writing a parser for qbe, I have several questions about the spec:
1. There's no "load" instruction present but it is present in
test/tls.ssa file. How to interpret this instruction?
2. I haven't found the definition of VAL, is it true that
VAL := DYNCONST | %IDENT
3. Is it true that the return address for an instruction must be %IDENT?
Any hints would be appreciated.
4. Should this in test/mem3.ssa:
type :tags.2 = { { :type.3 1 } }
be interpreted same as:
type :tags.2 = { :type.3 1 }
5. In test/abi5.ssa:
type :un9 = { { b } { s } }
I see that in the test output it is same as
union { char c; float f; }
I suppose it is not in the latest spec currently?
Hi,
Thank you for your interest in qbe!
On Sun, Jun 25, 2023, at 08:03, Dmitry Matveyev wrote:
> 1. There's no "load" instruction present but it is present in> test/tls.ssa file. How to interpret this instruction?
load is currently interpreted as loadk where k is the
return type given to the load instruction. I am not sure
if existing frontends use it; if not, we can simply fix
the test to use a documented variant.
> 2. I haven't found the definition of VAL, is it true that> VAL := DYNCONST | %IDENT
Yes that's a valid definition I believe. VAL is what the
parseref() function parses.
See https://c9x.me/git/qbe.git/tree/parse.c#n402> 3. Is it true that the return address for an instruction must be %IDENT?
Yes, the LHS of = must always be a temporary.
> 4. Should this in test/mem3.ssa:> type :tags.2 = { { :type.3 1 } }> be interpreted same as:> type :tags.2 = { :type.3 1 }
No. This nested syntax indicates that the type is a union.
In this case, it's a union with one element only. Some
ABIs treat a union with a single element as if there was
no union at all, but others don't -- like the rv64 one.
See https://c9x.me/git/qbe.git/tree/rv64/abi.c#n97
and https://c9x.me/git/qbe.git/commit/?id=9060981c10c21834596d5677a2c9ccc56809eb64> 5. In test/abi5.ssa:> type :un9 = { { b } { s } }> I see that in the test output it is same as> union { char c; float f; }> I suppose it is not in the latest spec currently?
Looks like I forgot to document unions indeed.
> 6. How do I read this notation:> s_0x1.fffffe091ff3dp+127> It looks like unbiased exponent, fraction, bias?..> https://en.wikipedia.org/wiki/IEEE_754-1985
I guess I could figure it out but, basically, qbe piggybacks
float parsing on sscanf(). I'm not against tightening the
spec here; the only constraint is to accommodate for what
existing frontends are emitting.
See https://c9x.me/git/qbe.git/tree/parse.c#n245
Reasonable patches to the spec are of course welcome, but
please keep the spec to the point to avoid submerging
casual users under details they're unlikely to care about.
Just found this thread while writing my own QBE parser.
> > 2. I haven't found the definition of VAL, is it true that> > VAL := DYNCONST | %IDENT> > > Yes that's a valid definition I believe. VAL is what the> parseref() function parses.> > See https://c9x.me/git/qbe.git/tree/parse.c#n402
VAL could also be $IDENT, e.g. in function calls:
// CALL := [%IDENT '=' ABITY] 'call' VAL '(' (ARG), ')'
%r =w call $puts(l $str)
> > 5. In test/abi5.ssa:> > type :un9 = { { b } { s } }> > I see that in the test output it is same as> > union { char c; float f; }> > I suppose it is not in the latest spec currently?> > > Looks like I forgot to document unions indeed.
An update would be much appreciated! :)
> > 6. How do I read this notation:> > s_0x1.fffffe091ff3dp+127> > It looks like unbiased exponent, fraction, bias?..> > https://en.wikipedia.org/wiki/IEEE_754-1985
Not an expert on this, but you could read the literal as
(1 + 0.fffffe091ff3d)_16 * 2^127
where e.g.
(0.d)_16 == (0.1101)_2 == (0.5 + 0.25 + 0.0625)
I personally find https://evanw.github.io/float-toy/ helpful for
understanding binary encoding of floating point numbers. (Here your
example would actually be 47efffffe091ff3d for f64.)