Commit graph

803 commits

Author SHA1 Message Date
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
8cc6cbc157 [qfcc] Use a union to manage function attributes
Same idea as the specifiers, but makes checking function types are the
same much easier.
2022-02-05 19:30:08 +09:00
Bill Currie
f153e87daa [qfcc] Use a union to manage specifier bits
Having to remember to copy yet another specifier bit was getting
tedious, so use a union of a struct with the bitfields and an unsigned
int to access them in parallel. Makes for a tidier spec_merge, and one
less headache.
2022-02-05 18:45:54 +09:00
Bill Currie
f3770cc647 [qfcc] Add --ruamoko command line option and pragma
The command line option works the same way as
--advanced/traditional/extended, as does the pragma. As well, raumoko
(alternative spelling) can be used because both are legitimate and some
people may prefer one spelling over the other.

As always, use of the pragma is at one's own risk: its intended use is
forcing the target in the unit tests.
2022-02-04 09:27:07 +09:00
Bill Currie
52a399daeb [qfcc] Update sizes and alignments for dvec4 and friends
dvec4, lvec4 and ulvec4 need to be aligned to 8 words (32 bytes) in
order to avoid hardware exceptions. Rather than dealing with possibly
mixed alignment when a function has 8-word aligned locals but only
4-word aligned parameters, simply keep the stack frame 8-word aligned at
all times.

As for sizes, the temp def recycler was written before the Ruamoko ISA
was even a pipe dream and thus never expected temp def sizes over 4. At
least now any future adjustments can be done in one place.

My quick and dirty test program works :)

    dvec4 xy = {1d, 2d, 0d, 0.5};
    void printf(string fmt, ...) = #0;
    int main()
    {
	dvec4 u = {3, 4, 3.14};
	dvec4 v = {3, 4, 0, 1};
	dvec4 w = v * xy + u;
	printf ("[%g, %g, %g, %g]\n", w[0], w[1], w[2], w[3]);
	return 0;
    }
2022-02-04 08:46:58 +09:00
Bill Currie
1487fa6b50 [qfcc] Implement some basics for the vector types
They're now properly part of the type system and can be used for
declaring variables, initialized (using {} block initializers), operated
on (=, *, + tested) though much work needs to be done on binary
expressions, and indexed. So far, only ivec2 has been tested.
2022-02-04 00:25:31 +09:00
Bill Currie
b668759b7d [qfcc] Add a very basic attribute system
Ruamoko passes va_list (@args) through the ... parameter (as such), but
IMP uses ... to defeat parameter type and count checking and doesn't
want va_list. While possibly not the best solution, adding a no_va_list
flag to function types and skipping ex_args entirely does take care of
the problem without hard-coding anything specific to IMP.

The system currently just sets some bits in the type specifier (the
attribute list should probably be carried around with the specifier),
but it gets the job done for now, and at least gets things started.
2022-02-02 23:51:37 +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
3f389b602a [qfcc] Add support for horizontal vector ops
And reimplement vector comparison for Ruamoko.
2022-01-30 10:56:15 +09:00
Bill Currie
feb3be4e6b [qfcc] Add types for ivec3/4 and vec3/4
Needed to get quaternions and vectors going. I'll add more later.
2022-01-30 10:54:07 +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
0123e12304 [qfcc] Use locals and params_start to describe stack frame
This is necessary to get statement disassembly working, and likely
debugging in general. locals is the total size of the stack frame and
thus reaches above the function-entry stack pointer, and params_start is
the local space relative start of the parameters. Thus, knowing the
function-entry stack pointer, the bottom of the locals space can be
found by subtracting params_start, and the top of the locals space by
adding (locals - params_start).
2022-01-27 11:37:37 +09:00
Bill Currie
169b8cc398 [qfcc] Rewrite qfo_to_progs offset/size calculation
This gets all the sections of the progs file nicely aligned and the code
easier to read with the offset and size calculations not being spread
through the function. ivar-struct-return now works when compiled for
Ruamoko.
2022-01-26 23:18:15 +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
fc73cfc1e0 [qfcc] Rename pointer_expr to deref_pointer_expr
This reflects what it actually does (usually, "pointer_expr" type naming
is creating an expression that represents a pointer).
2022-01-25 12:28:53 +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
1f802716e1 [qfcc] Pass initialize_def the symtab to use as a parameter
This takes care of an old FIXME.
2022-01-24 12:48:02 +09:00
Bill Currie
0a5101f88c [qfcc] Specify base register index for local defs
While all base registers can be used for any purpose at any time (this
is why the with instruction has hard-absolute modes: you can never get
permanently lost), qfcc currently uses the convention of register 0 for
globals and register 1 for stack locals (params, locals, function args).
The register used to access a def is stored in the def and that is used
to set the register bits in the instruction opcode.

The def code actually doesn't know anything about any conventions: it
assumes all defs are global for non-temp defs (the function code updates
the defs before emitting code) and the current function provides the
register to use for any temp defs allocated while emitting code.

Seems to work well, but debug is utterly messed up (not surprised, that
will be tricky).
2022-01-21 20:34:43 +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
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
Bill Currie
b8b47aaf54 [qfcc] Give finish_function the finishing blow
It's been twitching for over ten years, time to put it out of its
misery.
2022-01-21 00:23:40 +09:00
Bill Currie
17dfd1492f [qfcc] Make virtual defspaces useful for highwater allocation
This seems to be the most reasonable approach to allocating space for
function call parameters without using push and pop (or adding to the
stack pointer), though it's probably good even when using push and pop
to help keep things aligned.
2022-01-20 20:54:12 +09:00
Bill Currie
54d776f243 [qfcc] Take operand width into account
Operand width is encoded in the instruction opcode, so the width needs
to be accounted for in order to select the correct instruction. With
this, my little test generates correct code for the ruamoko ISA (except
for return, still fails).
2022-01-20 16:49:07 +09:00
Bill Currie
19baae6969 [qfcc] Dump emitted statements when verbosity >= 2
I wish I had done this years (decades, even!) ago. It makes checking the
output so much easier.
2022-01-20 13:08:05 +09:00
Bill Currie
30008aeb13 [qfcc] Fix a missed address expression conversion
Found while testing operator renaming.
2022-01-20 00:42:29 +09:00
Bill Currie
df890432b7 [qfcc] Add support for unsigned, long, etc
long is ignored for double, and v6p progs are stuck with 32 bits for
longs (don't feel like extending v6p any further), but the basics are
there for Ruamoko.

short is ignored for ints because the minimum size is 32, and signed is
just noise for ints anyway (and no chars, so...).

unsigned, however, is finally implemented properly (or at least seems to
be working correctly: tests pass after getting things compiling again,
and lt.u is used where it should be :)
2022-01-19 18:08:58 +09:00
Bill Currie
e11fa77a34 [qfcc] Use pr_type_names to generate is_TYPE
This means basic types will always have a check function automatically.
2022-01-19 18:07:54 +09:00
Bill Currie
17add5e00f [qfcc] Use pr_type_names to create basic type defs
This takes care of the type structs and the ev_* to type map.
2022-01-18 22:59:53 +09:00
Bill Currie
068c04ece6 [gamecode] Add ev_ushort and partial support
Really, only just enough to get everything compiling (which does include
vkgen running correctly).
2022-01-18 22:08:37 +09:00
Bill Currie
e9e54d08c0 [gamecode] Rename func_t to pr_func_t
Even more consistency.
2022-01-18 15:36:58 +09:00
Bill Currie
cfe7c44df0 [gamecode] Rename ev_integer to ev_int
And other related fields so integer is now int (and uinteger is uint). I
really don't know why I went with integer in the first place, but this
will make using macros easier for dealing with types.
2022-01-18 13:27:19 +09:00
Bill Currie
2df64384c1 [gamecode] Clean up string_t and pointer_t
They are both gone, and pr_pointer_t is now pr_ptr_t (pointer may be a
little clearer than ptr, but ptr is consistent with things like intptr,
and keeps the type name short).
2022-01-18 12:11:14 +09:00
Bill Currie
66528e34fc [qfcc] Give return expressions their own type
Very simple for now (just the return value if not a void return), but
that's the last of the statements masquerading as expressions.
2022-01-09 16:28:08 +09:00
Bill Currie
563de20208 [qfcc] Give branch expressions their own type
This includes calls and unconditional jumps, relative and through a
table. The parameters are all lumped into the one object, with some
being unused by the different types (eg, args and ret_type used only by
call expressions). Just having nice names for the parameters (instead of
e1 and e2) makes it nice, even with all the sub-types lumped together.

No mysterious type aliasing bugs this time ;)
2022-01-09 14:02:16 +09:00
Bill Currie
4111d44dcc [gamecode] Move progs auxiliary headers into a subdirectory
Just another step along the road of tidying up the QF include directory
(and desirable for generated data).
2022-01-09 00:26:52 +09:00
Bill Currie
63795e790b [qfcc] Clean out some old code
The move operator names are definitely obsolete (due to dropping the
expressions a year or two ago) and the precedence checks seem to be
handled elsewhere. Memset and state expressions went away a while back
too.
2022-01-08 21:21:31 +09:00
Bill Currie
65b6c366c3 [qfcc] Give assignment expressions their own type
This is getting easier (know where to look, I guess). Nicely, I found
the source of those weird type aliasing bugs :)
2022-01-08 18:44:29 +09:00
Bill Currie
fa482e8ee5 [qfcc] Give address expressions their own type
Definitely a pain to get working after the switch, but definitely worth
the effort. Still exposing type aliasing bugs.
2022-01-08 16:52:24 +09:00
Bill Currie
cf8061c4d3 [qfcc] Mark opcode_get as pure
Because gcc told me to :P
2022-01-08 12:14:27 +09:00
Bill Currie
23c9a317f8 [qfcc] Give alias expressions their own type
While this was a pain to get working, that pain only went to prove the
value of using proper "types" (even if only an enum) for different
expression types: just finding all the places to edit was a chore, and
easy to make mistakes (forgetting bits here and there).

Strangely enough, this exposed a pile of *type* aliasing bugs (next
commit).
2022-01-08 12:06:52 +09:00
Bill Currie
f5be54b6d2 [qfcc] Sanitize expr type enum
Got tired of dealing with out of date string tables.
2022-01-07 23:12:20 +09:00
Bill Currie
7e303a1151 [qfcc] Hide details about instruction type
At this stage, I doubt emit.c will need to know the details of the
target (v6, v6p, ruamoko) since the instruction formats are identical,
just different meanings for the opcode itself.
2022-01-07 19:05:26 +09:00
Bill Currie
d9ccf3a394 [qfcc] Remove a pile of stale externs
Those opcode pointers haven't been used for years.
2022-01-07 18:54:59 +09:00
Bill Currie
fe153b5b22 [qfcc] Add progs version to qfo and check in linker
While qfcc dealing sensibly with mixed target VMs in the object files
has always been an outstanding issue, with the new instruction set it
has become a priority. Most importantly, this should allow QF to
continue building while I work on qfcc targeting the new IS.
2022-01-07 17:56:05 +09:00
Bill Currie
c96cb1f302 [qfcc] Fix some stale documentation comments
It does little good for documentation to refer to fields that don't
exist (because a certain someone forgot to change the docs when changing
the field names, I wonder who :P).
2022-01-07 15:59:06 +09:00
Bill Currie
c9b2a740a0 [gamecode] Add etypes for long and ulong
And partial implementations in qfcc (most places will generate an
internal error (not implemented) or segfault, but some low-hanging fruit
has already been implemented).
2022-01-05 22:32:07 +09:00
Bill Currie
0c17c6dc24 [gamecode] Rename the old opcodes
To reflect their basis on v6 progs instructions, they sport the v6p tag
where the p is for "plus" due to the QuakeForge extensions.
2022-01-02 21:30:02 +09:00
Bill Currie
365762b8a6 [gamecode] Switch to using indexed initializers
The opcode table is a nightmare to maintain, but this does clean it up
and speed up opcode lookups since they can now be indexed. Of course, it
turns out I had missed adding several instructions, so had to fix that,
and qfcc needed a bit of a re-jigger to get the opcode out of the table.
2021-12-31 19:16:02 +09:00