Since spir-v needs actual bools for its conditional instructions, the
time to do bool properly finally came. As expected, the changes caused
quite a mess, but Ruamoko now does bool/true/false.
The tags might have other uses thus the generic term, but this allows
spir-v variables to be declared with the correct pointer storage
classes. Now spirv-val is complaining about my interfaces, so progress :)
This required adding a `var` symbol type. For now, it holds just the
storage class, but it might be good for the initializer, too.
Also, clean up some pointer/reference inconsistencies.
The function parameter and argument types are a mess with respect to
references (and thus calls don't pass validation) but the generated code
seems to be otherwise correct.
I've long felt build_function_call was getting a bit big, and expr.c
especially so. This should make it easier to rewrite build_function_call
for dealing with target-specific code. As a bonus, the int through ...
warning is already cleaned up.
spir-v uses SSA, so temps cannot be assigned to directly, so instead use
the temp expression as a reference for the result id of the rhs of the
assignment. This would get function calls working if the they actually
emitted any code (right now, just a place-holder id so spirv-dis doesn't
fall over).
Also, fix some missing docs. Unfortunately, there are still some
problems (incorrect resolution for multiple files/functions with the
same name, and a bug with doxygen's verbatim/code blocks).
Ruamoko and v6(p) have their own copies despite being (currently) the
same, and spir-v's is currently empty, but now targeting spir-v doesn't
try to emit ruamoko code.
While a reference var can't be initialized yet, using them seems to work
in that they get dereferenced when the value needs to be read or written
(though I haven't seen any generated code for them yet).
Simple functions now get to the code-gen phase (where they fail since
it's the wrong for other reasons). Parameter types aren't right for
spir-v yet as non-const params need to be references.
I realized that spir-v pointers are essentially references (the way
they're used) since OpVariable requires a pointer type rather than the
base type. Thus, under the hood, references are just pointers with
automatic dereferencing. However, nothing uses references yet, and I
expect to run into issues with is_pointer vs is_reference vs is_ptr
(high-level pointer, reference, low-level pointer, respectively).
I'd gotten tired of all the convoluted progs version checks, and with
the addition of spirv, they're not even always relevant, and adding C
(when I get to it) will make things even worse. However, for now the
first victim is just the parameter/return value size check.
Now declarations can be deferred too, thus things like generic/template
and inline functions should be possible. However, the most important
thing is this is a step towards a cleaner middle layer for compilation,
separating front-end language from back-end code-gen.
I don't remember why I thought it was a good idea at the time, but I
decided that having the union was a bit iffy and making the list
"official" would be a good idea. In the end, it removed a nice chunk of
code (redundant list manipulations).
And they even pass validation (though it turns out there's a bug in
glslangValidator regarding specialization constants with expressions (or
possibly spirv-val, but it seems to be the former as my bug report shows
signs of activity in that direction)).
https://github.com/KhronosGroup/glslang/issues/3748
I want to use new_field_expr for specialized field expressions instead.
However, I don't particularly like new_deffield_expr as a name, but I
can't think of anything better just yet.
Now, ctor expressions are collected and emitted after all other code,
and the ctor function being created outside of class_finish_module means
it's no longer limited to just class related initialization.
I plan to do this eventually for Ruamoko, but I need it to keep working
for now; it's rather nice having multiple languages. I expect this will
open up a lot of options for inlining, generic/template function
instantiation, etc. Right now, it's helping with specialization
constants in glsl.
They're currently wrong since they're meant to be for specialization
constants (and that whole system is currently broken anyway) but are
instead raw code expressions, but progress is progress.
Result type and constant handling is now table-driven, resulting in the
removal of seven switch statements (and thus a lot less hassle when
extending types or expressions). Also, (u)long and (u)short are fully
implemented.
In addition, other than result type handing for boolean results, any
back-end specific implementation is now in the back-end.
It's nowhere near complete, but unary and binary expressions that are
marked as constant will not be subject to constant folding. This is
necessary for proper support of specialization constants.
The imports need their result id recorded somewhere (and the hard-coding
in qc-parse.y removed), but that's a little bit of progress getting
spir-v working.
I don't know why I thought it was a good idea to make sy_var context
dependent. Renaming sy_var to sy_def makes it a little easier to know to
use the def field, too.
While I'm not happy with the module "creation" (at least it's limited to
two places), setting it up with spir-v capabilities and memory model
seems quite nice and should play nicely with being set up from within
source code, though using uint constant expressions might be overkill.