Commit graph

133 commits

Author SHA1 Message Date
Bill Currie
2c52e26d1a [gamecode] Be more consistent with access types
Eg, pointers via ptr, entities via entity, etc.
2022-01-18 17:05:12 +09:00
Bill Currie
cd30408675 [gamecode] Rename ev_quat to ev_quaternion
I much prefer the full name, though the short version is easier to type.
2022-01-18 17:05:12 +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
9348f7b89c [gamecode] Preserve the return pointer across calls
This required delaying the setting of the return pointer by call until
after the current pointer had been saved, and thus passing the desired
pointer into PR_CallFunction (which does have some advantages for C
functions calling progs functions, but some dangers too (should ensure a
128 byte (32 word) buffer when calling untrusted code (which is any,
really)).
2022-01-17 19:12:28 +09:00
Bill Currie
89e120ba34 [gamecode] Make return support 32 words
This took interpreting the lower 5 bits of operand c as size - 1, and
0xffff as void (0 words).
2022-01-17 16:54:27 +09:00
Bill Currie
736387bc88 [gamecode] Preserve base registers across calls
With this, functions can call other functions without having to worry
about whether the base registers they set up are still valid.
2022-01-17 15:08:58 +09:00
Bill Currie
213434b705 [gamecode] Save and restore data stack in call stack
This fixes the issue of the data stack not being restored properly
because the returning function needs to return a value from its local
variables (stored on the stack) and accessing stack data below the stack
pointer is a bad idea (sure, no interrupts yet, but who knows...).
2022-01-17 14:45:14 +09:00
Bill Currie
cf3106ce28 [gamecode] Correct call's mode selection
Call's operand c is used to specify where the return value of the
function is to be stored. This gets both the correct function being
called, and the value being returned correctly. Test still fails due to
the stack restoration issue.
2022-01-17 14:29:14 +09:00
Bill Currie
2b82533526 [gamecode] Add double time state instructions
This has been a long-held wishlist item, really, and I thought I might
as well take the opportunity to add the instructions. The double
versions of STATE require both the nextthink field and time global to be
double (but they're not resolved properly yet: marked with
"FIXME double time" comments).

Also, the frame number for double time state is integer rather than
float.
2022-01-16 21:27:49 +09:00
Bill Currie
7ea12b3ff9 [gamecode] Implement the HOPS sub-instructions
In the end, I decided any/all/none should be separate from the other
horizontal ops, if I even do them (can be implemented by first
converting to bool, then using the appropriate horizontal operation (& |
etc).
2022-01-16 16:28:48 +09:00
Bill Currie
8050c7bd77 [gamecode] Rearrange several instructions
ANY/ALL/NONE have been temporarily removed until I implement the HOPS
(horizontal operations) sub-instructions, which will all both 32-bit and
64-bit operands and several other operations (eg, horizontal add).

All the fancy addressing modes for the conditional branch instructions
have been permanently removed: I decided the gain was too little for the
cost (24 instructions vs 6). JUMP and CALL retain their addressing
modes, though.

Other instructions have been shuffled around a little to fill most of
the holes in the upper block of 256 instructions: just a single small
7-instruction hole.

Rearrangements in the actual engine are mostly just to keep the code
organized. The only real changes were the various IF statements and
dealing with the resulting changes in their addressing.
2022-01-16 14:22:04 +09:00
Bill Currie
49dcd5ef40 [gamecode] Add tests for the with instruction(s)
While mode 4 was tested a lot, none of the rest were. Also added a full
reset instruction.
2022-01-15 18:44:11 +09:00
Bill Currie
38ab0f0243 [gamecode] Move pushregs and popregs into with
This frees up another two instructions.
2022-01-15 16:51:59 +09:00
Bill Currie
a14b9f8252 [gamecode] Move the lea block
It just feels better with it being close the load/store etc
2022-01-15 16:39:52 +09:00
Bill Currie
e133de8c89 [gamecode] Drop B addressing for lea
When creating the tests for lea, I noticed that B was yet another simple
assign, so I decided it was best to drop it and move E into its place
(freeing up another instruction).
2022-01-15 16:27:46 +09:00
Bill Currie
1aa4844bf6 [gamecode] Make string ops mostly conform with bools
The compare/ne operator returns "random" -ve, 0, +ve values (really,
just the numerical difference between the chars of the strings), but all
the rest return -1 for true and 0 for false, as with the rest of the
comparison operators.
2022-01-14 22:44:08 +09:00
Bill Currie
6f6f47e27e [gamecode] Drop bool ops in favor of long bit ops
I realized that being able to do bit-wise operations with 64-bit values
(and 256-bit vectors) is far more important than some convenient boolean
logic operators. The logic ops can be handled via the bit-wise ops so
long as the values are all properly boolean, and I plan on adding some
boolean conversion ope, so no real loss.
2022-01-13 14:24:11 +09:00
Bill Currie
424bdcbf96 [gamecode] Implement the scale instructions
Both float 2,3,4 vectors and double 2,3,4 vectors (1 would be just a
copy of the mul instructions).

This completes the currently planned instructions. Now for testing.
2022-01-13 13:53:07 +09:00
Bill Currie
3587b13a40 [gamecode] Implement the conversion instructions
Not all possibilities are supported because converting between int and
uint, and long and ulong is essentially a no-op. However, thanks to
Deek's suggestion, not only are all reasonable conversions available,
conversions for all widths are available, so vector conversions are
supported.

The code for the conversions is generated.
2022-01-13 13:51:24 +09:00
Bill Currie
6229ae8ecc [gamecode] Add tests for unsigned comparisons
And fix the implementation: I had used the wrong macro.
2022-01-11 13:00:54 +09:00
Bill Currie
b9e32ee2f5 [gamecode] Rework call and return instructions
The call1-8 instructions have been removed as they are really not needed
(they were put in when I had plans of simple translation of v6p progs to
ruamoko, but they joined the dinosaurs).

The call instruction lost mode A (that is now return) and its mode B is
just the regular function access. The important thing is op_c (with
support for with-bases) specifies the location of the return def.

The return instruction packs both its addressing mode and return value
size into st->c as a 3.5 value: 3 bits for the mode (it supports all
five addressing modes with entity.field being mode 4) and 5 for the
size, limiting return sizes to 32 words, which is enough for one 4x4
double matrix.

This, especially with the following convert patch, frees up a lot of
instructions.
2022-01-10 11:53:14 +09:00
Bill Currie
ba29be3f82 [gamecode] Rename ifnot and if to be less confusing
I think :) anyway, now they're ifz and ifnz, making them consistent with
the rest of the if instructions.
2022-01-10 11:27:57 +09:00
Bill Currie
db7a67e5b7 [gamecode] Rearrange vector instructions
This allows the dot products to be consistent with their sizes: cdot is
really dot_2, vdot dot_3, and qdot dot_4.
2022-01-10 11:16:55 +09:00
Bill Currie
0d9294d541 [gamesource] Work around a windows gcc bug
The bug (alignment issues with AVX on windows) seems to have in gcc from
the 4.x days, and is still present in 11.2: it does not ensure stack
parameters that need 32 byte alignment are aligned. Telling gcc to use
the sysv abi (safe on a static function) lets gcc do what it does for
linux (usually pass the parameters in registers, which it seems to have
done).
2022-01-06 22:21:24 +09:00
Bill Currie
c3317f8e5e [gamecode] use INT64_C instead of l-suffix
Once again, I had forgotten that long is not always 64-bits.
2022-01-06 22:20:16 +09:00
Bill Currie
0b674f5ed4 [gamecode] Clean up some opcode names
While working on the new opcode table, I decided a lot of the names were
not to my liking.  Part of the problem was the earlier clash with the
v6p opcode names, but that has been resolved via the v6p tag.
2022-01-05 19:04:43 +09:00
Bill Currie
35387b5450 [gamecode] Fix a pile of incorrect base register refs
The problem with copying code is it's all to easy to forget to make all
necessary edits.
2022-01-04 19:01:05 +09:00
Bill Currie
59292393e6 [gamecode] Fix up MOD (%%) for integral types
Use the new "1" versions of loadvec3 to get a 1 in w to avoid
divide-by-zero errors, and use the correct type for longs (forgot to
change i to l on the vector types).
2022-01-04 18:36:13 +09:00
Bill Currie
2f09ece65b [gamecode] Add more modes to WITH
It turned out I had no way of using a pointer or field as the value to
load, so all 4 modes are duplicated with loads from where operand b
points, but the loaded value interpreted the same way. Also, fixed an
error in the calculation of op-b offsets.
2022-01-04 17:55:20 +09:00
Bill Currie
f2b258ba76 [gamecode] Add statement bounds checking
Statements can be bounds checked in the one place (jump calculation),
but memory accesses cannot as they can be used in lea instructions which
should never cause an exception (unless one of lea's operands is OOB).
2022-01-04 17:53:10 +09:00
Bill Currie
5de4c21557 [gamecode] Fix relative offset jumps
Yet another missed sign extension.
2022-01-04 14:30:20 +09:00
Bill Currie
6de1ba6901 [gamecode] Clean up the conversion instructions
Float bit-ops as well.

Also, add q*v4 and v4*q instructions. There are currently 48 free
opcodes, and I might remove the scale instructions, but they could be
useful as expanding a single float to a vector would take 3 instructions
(copy to temp, swizzle-expand temp, multiply, vs just scale).
2022-01-03 23:27:01 +09:00
Bill Currie
b6f9b68434 [gamecode] Implement 64-bit swizzles
See commit for 32-bit swizzles.
2022-01-03 23:27:01 +09:00
Bill Currie
bebc811f11 [gamecode] Implement 4-component 32-bit swizzle
The swizzle instruction is very powerful in that in can do any of the
256 permutations of xyzw, optionally negate any combination of the
resulting components, and zero any combination of the result components
(even all). This means the one instruction can take care of any actual
swizzles, conjugation for complex and quaternion values, zeroing vectors
(not that it's the only way), and probably other weird things.

The python file was used to generate the jump table and actual swizzle
code.
2022-01-03 23:27:01 +09:00
Bill Currie
fd298f3601 [gamecode] Create a mask for extracting the opcode
Got tired of copying the full thing around.
2022-01-03 23:27:01 +09:00
Bill Currie
28df32eb0d [gamecode] Use pr_memset instead of memset
This keeps things inline and matches the quakec exec loop. Also removes
the need to calculate the size.
2022-01-03 23:27:01 +09:00
Bill Currie
bf604b99b3 [gamecode] Add automated tests for store ops
They even found a bug in the addressing mode functions :) (I'd forgotten
that I wanted signed offsets from the pointer and thus forgot to cast
st->b to short in order to get the sign extension)
2022-01-03 23:27:01 +09:00
Bill Currie
920c5fd99b [gamecode] Add debug event name strings
Makes it easier to print nice debug event messages.
2022-01-03 23:26:50 +09:00
Bill Currie
8a2788c267 [gamecode] Add PROG_V6P_VERSION and bump PROG_VERSION
This allows the VM to select the right execution loop and qfcc currently
still produces only the old IS (it doesn't know how to deal with the new
IS yet)
2022-01-03 13:56:43 +09:00
Bill Currie
925797b1d4 [gamecode] Add a new Ruamoko instruction set
When it's finalized (most of the conversion operations will go, probably
the float bit ops, maybe (very undecided) the 3-component vector ops,
and likely the CALLN ops), this will be the actual instruction set for
Ruamoko.

Main features:
 - Significant reduction in redundant instructions: no more multiple
   opcodes to move the one operand size.
 - load, store, push, and pop share unified addressing mode encoding
   (with the exception of mode 0 for load as that is redundant with mode
   0 for store, thus load mode 0 gives quick access to entity.field).
 - Full support for both 32 and 64 bit signed integer, unsigned integer,
   and floating point values.
 - SIMD for 1, 2, (currently) 3, and 4 components. Transfers support up
   to 128-bit wide operations (need two operations to transfer a full
   4-component double/long vector), but all math operations support both
   128-bit (32-bit components) and 256-bit (64-bit components) vectors.
 - "Interpreted" operations for the various vector sizes: complex dot
   and multiplication, 3d vector dot and cross product, quaternion dot
   and multiplication, along with qv and vq shortcuts.
 - 4-component swizzles for both sizes (not yet implemented, but the
   instructions are allocated), with the option to zero or negate (thus
   conjugates for complex and quaternion values) individual components.
 - "Based offsets": all relevant instructions include base register
   indices for all three operands allowing for direct access to any of
   four areas (eg, current entity, current stack frame, Objective-QC
   self, ...) instructions to set a register and push/pop the four
   registers to/from the stack.

Remaining work:
 - Implement swizzle operations and a few other stragglers.
 = Make a decision about conversion operations (if any instructions
   remain, they'll be just single-component (at 14 meaningful pairs,
   that's a lot of instructions to waste on SIMD versions).
 - Decide whether to keep CALL1-CALL8: probably little point in
   supporting two different calling conventions, and it would free up
   another eight instructions.
 - Unit tests for the instructions.
 - Teach qfcc to generate code for the new instruction set (hah, biggest
   job, I'm sure, though hopefully not as crazy as the rewrite eleven
   years ago).
2022-01-03 00:49:49 +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
bc0a09f452 [gamecode] Switch to using type parameter op macros
I wish I'd done it this way years ago (but maybe gcc 2.95 couldn't hack
the casts, I do know there were aliasing problems in the past). Anyway,
this makes operand access much more consistent for variable sized
operands (eg float vs double vs vec4), and is a big part of the new
instruction set implementation.
2022-01-02 20:46:32 +09:00
Bill Currie
7b0eceda32 [gamecode] Split out the old quake c execution loop
There is no reasonable way (due to hardware-enforced alignment issues)
to simply convert old bytecode to new (probably best done with an
off-line tool, preferably just recompiling when I get qfcc up to the
job), so both loops will need to be present. This just moves the
original loop into its own function in order to make it easy to bring in
the new (and iron out integration issues).
2022-01-02 20:16:45 +09:00
Bill Currie
be474d9937 [gamecode] Remove the wart from def and function names
I never liked the leading s_ (though I guess it means one is supposed to
interpret the int as a string pointer, but meh).
2021-12-31 15:02:31 +09:00
Bill Currie
3ef89583af [gamecode] Correct pop implementations
Had src and dst swapped (yay for not testing :P (boo for not having an
easy way to test (yay for working on it))).
2021-07-19 22:31:22 +09:00
Bill Currie
6b38a17cf1 [gamecode] Clean up state imlementations
This makes the code easier to read. Also, yay for automated tests:
caught a mistyped time :)
2021-07-15 16:55:02 +09:00
Bill Currie
c9f1d770e0 Merge master into csqc-improvements
That was a mess
2021-03-25 22:01:31 +09:00
Bill Currie
66fda1fddb Rewrite edict access.
The server edict arrays are now stored outside of progs memory, only the
entity data itself (ie data accessible to progs via ent.fld) is stored in
progs memory. Many of the changes were due to code accessing edicts and
entity fields directly rather than through the provided macros.
2021-03-25 18:13:48 +09:00