Commit graph

285 commits

Author SHA1 Message Date
Bill Currie
deb03ca27a [qfcc] Set correct statement type for memset
Explicit memset expressions were becoming move instructions when
optimizing, which would generally not result in correct values.
2023-08-23 15:38:32 +09:00
Bill Currie
dfb7862419 [qfcc] Use the progs VM to help with constant folding
Due to joys of pointers and the like, it's a bit of a bolt-on for now,
but it works nicely for basic math ops which is what I wanted, and the
code is generated from the expression.
2023-08-21 17:47:55 +09:00
Bill Currie
dbd3d6502a Nuke qboolean from orbit
I never liked it, but with C2x coming out, it's best to handle bools
properly. I haven't gone through all the uses of int as bool (I'll leave
that for fixing when I encounter them), but this gets QF working with
both c2x (really, gnu2x because of raw strings).
2023-06-13 18:06:11 +09:00
Bill Currie
38fd09573f [qfcc] Avoid defining whole temp via alias
Like defs, a partial write should not define the whole temp. Thus, copy
the "don't visit main" behavior recently added to def_visit_all. Fixes
missing ud-chains for component-by-component assignments to temporary
vectors.
2023-06-05 09:42:33 +09:00
Bill Currie
8f6e145257 [qfcc] Don't add target def for store statements
Store statements dereference the pointer in target and thus don't modify
target itself.
2023-06-04 11:45:35 +09:00
Bill Currie
d001473536 [qfcc] Make is_struct struct-only
And add is_union to handle unions. Sometimes it's necessary to check
between the two.
2023-05-25 21:23:27 +09:00
Bill Currie
a5943c8a3b [qfcc] Use statement use chain for v6 calls
Def and kill are still handled in flow_analyze_statement, but this makes
call meta data more consistent between v6 and ruamoko progs, allowing
the statement use chain to be used for call argument analysis. It even
found a bug in the extraction of param counts from the call instruction.
2023-05-21 10:23:03 +09:00
Bill Currie
b5a57cd15c [qfcc] Use assign_statement for v6p call arguments
I had written assign_statement a while after the call handling code and
didn't think to modify the call code. This makes for more consistent
code.
2023-05-20 13:52:24 +09:00
Bill Currie
4b3b6d516a [qfcc] Use available functions for dealloc use/def
I had written those use/def sets before creating the functions, and it
turns out I had goofed slightly with the def chaining.
2023-05-19 19:41:34 +09:00
Bill Currie
4435db0329 [qfcc] Support pointer arithmetic on arrays
That is, `array + offset`. This actually works around the bug
highlighted by arraylife.r (because the array is explicitly used), but
is not a proper solution, so that test still fails of course. However,
with this, it's no longer necessary to use `&array[index]` instead of
`array + index`.
2023-05-14 12:45:08 +09:00
Bill Currie
795021e229 [util] Record allocated blocs for ALLOC
Recording the blocks makes it possible to free them later. As a
convenience, ALLOC_STATE declares the freelist and blocks vars needed by
ALLOC.
2023-03-05 18:31:30 +09:00
Bill Currie
694c3ad5f5 [qfcc] Ensure params and arguments have unique flow addresses
This fixes the false-negative in the dealloc-warn4.r test (and thus what
I found in vkgen), and should stave off a few other issues.
2023-02-26 20:43:52 +09:00
Bill Currie
f323401c10 [qfcc] Add an explicit hadamard operator
While the option to make '*' mean dot product for vectors is important,
it breaks vector scaling in ruamoko progs as the resultant vector op
becomes a dot product instead of the indented hadamard product (ie,
component-wise).
2022-11-16 00:06:21 +09:00
Bill Currie
47ac7b924f [qfcc] Skip recording defs for binary expressions
For now, anyway, as the generated code looks good. There might be
problems with actual pointer expressions, but it allows entity.field to
work as expected rather than generate an ICE.
2022-09-13 21:31:54 +09:00
Bill Currie
95b8424ddf [qfcc] Use new extend instruction instead of swizzle
While swizzle does work, it requires the source to be properly aligned
and thus is not really the best choice. The extend instruction has no
alignment requirements (at all) and thus is much better suited to
converting a scalar to a vector type.

Fixes #30
2022-08-18 18:18:19 +09:00
Bill Currie
2c8bec27c7 Fix a pile of warnings for gcc 12
Most were pretty easy and fairly logical, but gib's regex was a bit of a
pain until I figured out the real problem was the conditional
assignments.

However, libs/gamecode/test/test-conv4 fails when optimizing due to gcc
using vcvttps2dq (which is nice, actually) for vector forms, but not the
single equivalent other times. I haven't decided what to do with the
test (I might abandon it as it does seem to be UD).
2022-07-31 17:13:26 +09:00
Bill Currie
cdd8739577 [qfcc] Improve debug printing of statements and operands
Makes it easier to check operand base indices and temporary variable
addresses when known.
2022-05-01 14:35:24 +09:00
Bill Currie
ef9960c6f9 [qfcc] Implement support for the swizzle operator
The destination operand must be a full four component vector, but the
source can be smaller and small sources do not need to be aligned: the
offset of the source operand and the swizzle indices are adjusted. The
adjustments are done during final statement emission in order to avoid
confusing the data flow analyser (and that's when def offsets are known).
2022-05-01 14:35:24 +09:00
Bill Currie
719fe5a935 [qfcc] Support dot product for all (float) vector types
While the code would handle int vector types, there aren't any such
instructions, and the expression code shouldn't generate them, but all
float (32 and 64 bit) vector types do have a dot product instruction, so
check width rather than just vector/quaternion.
2022-04-29 20:46:33 +09:00
Bill Currie
14545c37cf [qfcc] Merge printing of values into the one place
Having three very similar sets of code for outputting values (just for
debug purposes even) got to be a tad annoying. Now there's only one, and
in the right place, too (with the other value code).
2022-04-29 16:59:55 +09:00
Bill Currie
04f60e5ff1 [qfcc] Rework vector expression handling
Use with quaternions and vectors is a little broken in that
vec4/quaternion and vec3/vector are not the same types (by design) and
thus a cast is needed (not what I want, though). However, creating
vectors (that happen to be int due to int constants) does seem to be
working nicely otherwise.
2022-04-29 16:59:55 +09:00
Bill Currie
ae0b3a5870 [qfcc] Add some utility functions for working with vector types
Finding vector types from base type and width, and getting the base type
for a vector type, as well as basic promotion rules for math types.
2022-04-29 16:59:15 +09:00
Bill Currie
2f117dd12e [qfcc] Record referenced def in pointer dereferences
When the def can be found. This fixes direct assignments to arrays (and
probably structs) getting lost when the array is later read using a
variable index.
2022-02-11 19:29:33 +09:00
Bill Currie
1ce026d168 [qfcc] Implement bounced return pointer calls
This is achieved by marking a void function with the void_return
attribute and then calling that function in an @return expression.
@return can be used only inside a void function and only with void
functions marked with the void_return attribute. As this is intended for
Objective-QC message forwarding, it is deliberately "difficult" to use
as returning a larger than expected value is unlikely to end well for
the calling function.

However, as a convenience, "@return nil" is allowed (in a void
function). It always returns an integer (which, of course,can be
interpreted as a pointer). This is safe because if the return value is
ignored, it will go into the progs return buffer, and if it is not
ignored, it is the smallest value that can be returned.
2022-02-05 19:30:08 +09:00
Bill Currie
6988752dea [qfcc] Clean up line numbers in varargs setup
It's never nice getting the end-of-function line in the middle of some
code.
2022-02-04 22:02:05 +09:00
Bill Currie
a3c37201b2 [qfcc] Emit constant pointers as direct def references
When possible, of course. However, this tightens up struct and constant
index array accesses, and avoids issues with flow analysis losing track
of the def (such trucking is something I want to do, but haven't decided
out to get the information out to the right statements).
2022-02-03 14:41:46 +09:00
Bill Currie
80c6431544 [qfcc] Clear up a FIXME
The FIXME was there because I couldn't remember why the test was
type_compatible but the internal error complains about the types being
the same size. The compatibility check is to see if the op can be used
directly or whether a temp is required. The offset check is because
types that are the same size (which they must be if they are
compatible) is because it is not possible to create an offset alias def
that escapes the bounds of the real def, which any non-zero offset will
do if the types are the same size.
2022-02-03 14:15:20 +09:00
Bill Currie
a64f91129f [qfcc] Give lea its own statement type
This makes it much easier to check (and more robust to name changes),
allowing for effectively killing the node to which the variable being
addressed is attached. This fixes the incorrect address being used for
va_list, which is what caused double-alias to fail.
2022-02-02 18:55:01 +09:00
Bill Currie
4ec3486a4b [qfcc] Make lea generate a pointer operand
I really need to come up with a better way to get the result type into
the flow analyser. However, this fixes the aliasing ICE when optimizing
Ruamoko code that uses struct assignment.
2022-02-01 20:01:13 +09:00
Bill Currie
fc56d1c6e2 [qfcc] Use dynamic addressing for Ruamoko move source
This fixes the incorrect pointer being used in movep instructions in
Ruamoko progs, as well as 3 of the test cases.
2022-02-01 14:57:16 +09:00
Bill Currie
8dc4a0ea80 [qfcc] Change v6p's jumpb opname to jump
More ease of searching, since the operand types help greatly.
2022-01-30 22:39:21 +09:00
Bill Currie
4b8fdf3696 [qfcc] Implement vector scaling for Ruamoko
With this, qfcc-tests builds (can't run yet due to unsigned not having
any tests and thus the rest the Ruamoko code in QF not building yet).
2022-01-30 14:48:49 +09:00
Bill Currie
d8f6a9445e [qfcc] Implement dot and cross product for Ruamoko
With explicit operators, even. While they're a tad verbose, they're at
least unambiguous and most importantly have the right precedence (or at
least adjustable precedence if I got it wrong, but vector ops having
high precedence than scalar or component seems reasonable to me).
2022-01-30 14:14:15 +09:00
Bill Currie
3f389b602a [qfcc] Add support for horizontal vector ops
And reimplement vector comparison for Ruamoko.
2022-01-30 10:56:15 +09:00
Bill Currie
fbaf1456fe [qfcc] Use auxiliary operands for move instructions
Since Ruamoko progs must use lea to get the address of a local variable,
add use/def/kill references to the move instruction in order to inform
flow analysis of the variable since it is otherwise lost via the
resulting pointer (not an issue when direct var reference move can be
used).

The test and digging for the def can probably do with being more
aggressive, but this did nicely as a proof of concept.
2022-01-29 18:26:54 +09:00
Bill Currie
7e9cf76cfe [qfcc] Change ne to cmp for v6 string inequality check
Since it's really strcmp in disguise (makes the instruction consistent
across all targets).
2022-01-29 18:18:33 +09:00
Bill Currie
baca7cbb4c [qfcc] Do not reverse function args in ruamoko call
It messed up the later check for calls to i[super dealloc].
2022-01-29 17:07:19 +09:00
Bill Currie
d61e906cb9 [qfcc] Don't use v6p store for assinging to entity.field
Ruamoko has a native addressing mode just for entities.
2022-01-29 17:05:50 +09:00
Bill Currie
284fcd312d [qfcc] Rewrite assignment destination addressing
It now addressing_mode cleaning up store instructions to use ptr+offset
instead of lea;store ptr...

Entity.field addressing has been impelmented as well.

Move instructions still generate sub-optimal code in that they use an
add instruction instead of lea.
2022-01-28 15:50:46 +09:00
Bill Currie
d3764c108a [qfcc] Rewrite expr_deref to use addressing_mode
This cleans up the generation of load instructions such that they use
ptr+offset addressing instead of lea;load ptr.
2022-01-28 15:42:06 +09:00
Bill Currie
e298f0d993 [qfcc] Break out pointer addressing
This allows the code handling simple pointer dereferences to recurse
along an alias chain that resulted from casting between different
pointer types (such chains could probably be eliminated by replacing the
type in the original pointer expression, but it wasn't worth it at this
stage).
2022-01-28 15:37:08 +09:00
Bill Currie
f57aa82c4b [qfcc] Use an alias op for return_operand
This is what using new_ret_expr would result in, but new_ret_expr is no
longer used for referencing .return (except in pascal, but I haven't
gotten around to sorting that out) due to the recent changes for Ruamoko
progs. Fixes an ICE when compiling (with optimization) something like
the following (dir is a vector):

    dir /= sqrt (dir * dir);
    return dir * speed;
2022-01-27 23:24:43 +09:00
Bill Currie
0b9b6955aa [qfcc] Implement addressing modes for return
There's still entity.field to go, but basic def and ptr + const offset
seem to work.
2022-01-26 15:48:08 +09:00
Bill Currie
06d70a32db [qfcc] Rework the functionality of address expressions
The goal was to get lea being used for locals in ruamoko progs because
lea takes the base registers into account while the constant pointer
defs used by v6p cannot. Pointer defs are still used for gobals as they
may be out of reach of 16-bit addressing.

address_expr() has been simplified in that it no longer takes an offset:
the vast majority of the callers never passed one, and the few that did
have been reworked to use other mechanisms. In particular,
offset_pointer_expr does the manipulations needed to add an offset
(unscaled by type size) to a pointer. High-level pointer offsets still
apply a scale, though.

Alias expressions now do a better job of hanling aliasing of aliases by
simply replacing the target type when possible.
2022-01-25 23:39:17 +09:00
Bill Currie
37f08f9d4f [qfcc] Build the Ruamoko function parameters
The parameter defs are allocated from the parameter space using a
minimum alignment of 4, and varargs functions get a va_list struct in
place of the ...

An "args" expression is unconditionally injected into the call arguments
list at the place where ... is in the list, with arguments passed
through ... coming after the ...

Arguments get through to functions now, but there's problems with taking
the address of local variables: currently done using constant pointer
defs, which can't work for the base register addressing used in Ruamoko
progs.

With the update to test-bi's printf (and a hack to qfcc for lea),
triangle.r actually works, printing the expected results (but -1 instead
of 1 for equality, though that too is actually expected). qfcc will take
a bit longer because it seems there are some design issues in address
expressions (ambiguity, and a few other things) that have pretty much
always been there.
2022-01-24 23:44:48 +09:00
Bill Currie
79bd4dd724 [qfcc] Set up the function stack frame
Still need to get the base register index into the instructions, but I
think this is it for basic code generation. I should be able to start
testing Ruamoko properly fairly soon :)
2022-01-21 20:00:38 +09:00
Bill Currie
616a52efb5 [qfcc] Implement flow analysis for Ruamoko calls
Thanks to the use/def/kill lists attached to statements for pseudo-ops,
it turned out to be a lot easier to implement flow analysis (and thus
dags processing) than I expected. I suspect I should go back and make
the old call code use them too, and probably several other places, as
that will greatly simplify the edge setting.
2022-01-21 17:14:10 +09:00
Bill Currie
c53127707b [qfcc] Set the return of Ruamoko calls
Of course, I had the width of opc wrong :P. But with this, it seems that
unoptimized calls should work once I get the stack frame working.
2022-01-21 13:50:21 +09:00
Bill Currie
33a3f92503 [qfcc] Move .return handling into statements.c
The means that the actual call expression is not in the statement lint
of the enclosing block expression, but just its result, whether the call
is void or not. This actually simplifies several things, but most
importantly will make Ruamoko calls easier to implement.

The test is because I had some trouble with double-calls, and is how I
found the return-postop issue :P
2022-01-21 13:09:23 +09:00
Bill Currie
7bc1396358 [qfcc] Split the function defspace into three spaces
Since Ruamoko now uses the stack for parameters and locals, parameters
need to come after locals in the address space (instead of before, as in
v6 progs). Thus use separate spaces for parameters and locals regardless
of the target, then stitch them together appropriately for the target.
The third space is used for allocating stack space for arguments to
called functions. It us not used for v6 progs, and comes before locals
in Ruamoko progs.

Other than the return value, and optimization (ice, not implemented)
calls in Ruamoko look like they'll work.
2022-01-21 10:20:02 +09:00