mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
[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.
This commit is contained in:
parent
f7181a09b4
commit
3587b13a40
3 changed files with 95 additions and 12 deletions
|
@ -31,7 +31,10 @@ pr_opcode_src = \
|
|||
${pr_opcode_hinc}
|
||||
libs/gamecode/pr_opcode.lo: libs/gamecode/pr_opcode.c ${pr_opcode_src}
|
||||
|
||||
BUILT_SOURCES += $(pr_opcode_cinc) $(pr_opcode_hinc)
|
||||
convert_py = $(srcdir)/libs/gamecode/convert.py
|
||||
pr_convert_cinc = $(top_builddir)/libs/gamecode/pr_convert.cinc
|
||||
|
||||
BUILT_SOURCES += $(pr_opcode_cinc) $(pr_opcode_hinc) $(pr_convert_cinc)
|
||||
|
||||
$(pr_opcode_cinc): $(opcodes_py)
|
||||
$(V_PY)$(PYTHON) $(opcodes_py) table > $(pr_opcode_cinc).t && \
|
||||
|
@ -41,3 +44,7 @@ $(pr_opcode_hinc): $(opcodes_py)
|
|||
$(V_PY) mkdir -p `dirname $(pr_opcode_hinc)` &&\
|
||||
$(PYTHON) $(opcodes_py) enum > $(pr_opcode_hinc).t && \
|
||||
$(am__mv) $(pr_opcode_hinc).t $(pr_opcode_hinc)
|
||||
|
||||
$(pr_convert_cinc): $(convert_py)
|
||||
$(V_PY)$(PYTHON) $(convert_py) table > $(pr_convert_cinc).t && \
|
||||
$(am__mv) $(pr_convert_cinc).t $(pr_convert_cinc)
|
||||
|
|
66
libs/gamecode/convert.py
Normal file
66
libs/gamecode/convert.py
Normal file
|
@ -0,0 +1,66 @@
|
|||
print("""// types are encoded as ubf where:
|
||||
// u = 0: signed, u = 1: unsigned
|
||||
// b = 0: 32-bit, b = 1: 64-bit
|
||||
// f = 0: int, f = 1: float/double
|
||||
// width is ww where:
|
||||
// ww = 00: 1 component
|
||||
// ww = 01: 2 components
|
||||
// ww = 10: 3 components
|
||||
// ww = 11: 4 components
|
||||
// full conversion code is wwsssddd where:
|
||||
// ww = width
|
||||
// sss = src type
|
||||
// ddd = dst type
|
||||
// case values are in octal
|
||||
""")
|
||||
types = [
|
||||
"int",
|
||||
"float",
|
||||
"long",
|
||||
"double",
|
||||
"uint",
|
||||
None, # no such thing as unsigned float
|
||||
"ulong",
|
||||
None, # no such thing as unsigned double
|
||||
]
|
||||
#does not include size (2 or 4, 3 is special)
|
||||
vec_types = [
|
||||
"ivec",
|
||||
"vec",
|
||||
"lvec",
|
||||
"dvec",
|
||||
"uivec",
|
||||
None, # no such thing as unsigned float
|
||||
"ulvec",
|
||||
None, # no such thing as unsigned double
|
||||
]
|
||||
skip_matrix = [
|
||||
#i f l d ui X ul X
|
||||
[1, 0, 0, 0, 1, 1, 0, 1], # i
|
||||
[0, 1, 0, 0, 0, 1, 0, 1], # f
|
||||
[0, 0, 1, 0, 0, 1, 1, 1], # l
|
||||
[0, 0, 0, 1, 0, 1, 0, 1], # d
|
||||
|
||||
[1, 0, 0, 0, 1, 1, 0, 1], # ui
|
||||
[1, 1, 1, 1, 1, 1, 1, 1], # X
|
||||
[0, 0, 1, 0, 0, 1, 1, 1], # ul
|
||||
[1, 1, 1, 1, 1, 1, 1, 1], # X
|
||||
]
|
||||
for width in range(4):
|
||||
for src_type in range(8):
|
||||
for dst_type in range(8):
|
||||
if skip_matrix[src_type][dst_type]:
|
||||
continue
|
||||
case = (width << 6) | (src_type << 3) | (dst_type)
|
||||
if width == 0:
|
||||
print(f"case {case:04o}: OPC({types[dst_type]}) = (pr_{types[dst_type]}_t) OPA({types[src_type]}); break;")
|
||||
elif width == 2:
|
||||
print(f"case {case:04o}: VectorCompUop(&OPC({types[dst_type]}), (pr_{types[dst_type]}_t), &OPA({types[src_type]})); break;")
|
||||
else:
|
||||
if (src_type & 2) == (dst_type & 2):
|
||||
print(f"case {case:04o}: OPC({vec_types[dst_type]}{width+1}) = (pr_{vec_types[dst_type]}{width+1}_t) OPA({vec_types[src_type]}{width+1}); break;")
|
||||
else:
|
||||
print(f"case {case:04o}:")
|
||||
for i in range(width + 1):
|
||||
print(f"\t(&OPC({types[dst_type]}))[{i}] = (pr_{types[dst_type]}_t) (&OPA({types[src_type]}))[{i}];")
|
||||
print(f"\tbreak;")
|
|
@ -2915,6 +2915,7 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
pr->pr_xstatement = pr_jump_mode (pr, st);
|
||||
st = pr->pr_statements + pr->pr_xstatement;
|
||||
break;
|
||||
// 0 0101
|
||||
case OP_IFNZ_A:
|
||||
case OP_IFNZ_B:
|
||||
case OP_IFNZ_C:
|
||||
|
@ -2972,9 +2973,17 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
PR_CallFunction (pr, function);
|
||||
st = pr->pr_statements + pr->pr_xstatement;
|
||||
break;
|
||||
// 0 0101
|
||||
// nnn spare
|
||||
//OP_CONV
|
||||
// 0 0110
|
||||
// 0nnn spare
|
||||
// 10nn spare
|
||||
case OP_CONV:
|
||||
switch (st->b) {
|
||||
#include "libs/gamecode/pr_convert.cinc"
|
||||
default:
|
||||
PR_RunError (pr, "invalid conversion code: %04o",
|
||||
st->b);
|
||||
}
|
||||
break;
|
||||
case OP_WITH:
|
||||
pr->pr_bases[st->c & 3] = pr_with (pr, st);
|
||||
break;
|
||||
|
@ -3002,7 +3011,6 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
pr->pr_edict_area[think].func_var = op_b->func_var;
|
||||
}
|
||||
break;
|
||||
// 0 0110
|
||||
// 0 0111
|
||||
case OP_CROSS_F:
|
||||
{
|
||||
|
@ -3121,14 +3129,16 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
// 0 1010
|
||||
OP_cmp(GT, >);
|
||||
// 0 1011
|
||||
// spare
|
||||
// 0 1100
|
||||
OP_cmp(NE, !=);
|
||||
// 0 1101
|
||||
OP_cmp(GE, >=);
|
||||
// 0 1110
|
||||
OP_cmp(LE, <=);
|
||||
// 0 1011
|
||||
//FIXME conversion 2
|
||||
|
||||
// 0 1111
|
||||
// spare
|
||||
|
||||
#define OP_op_1(OP, T, t, op) \
|
||||
case OP_##OP##_##T##_1: \
|
||||
|
@ -3311,9 +3321,9 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
//FIXME scale ops
|
||||
// 1 1010
|
||||
OP_cmp_T (GT, u, int, ivec2, ivec4, >, uint, uivec2, uivec4);
|
||||
//FIXME conversion ops
|
||||
// spare
|
||||
OP_cmp_T (GT, U, long, lvec2, lvec4, >, ulong, ulvec2, ulvec4);
|
||||
//FIXME conversion ops
|
||||
// spare
|
||||
// 1 1011
|
||||
case OP_LEA_A:
|
||||
case OP_LEA_B:
|
||||
|
@ -3447,14 +3457,14 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
case OP_V4QMUL_F:
|
||||
OPC(vec4) = vqmulf (OPA(vec4), OPB(vec4));
|
||||
break;
|
||||
|
||||
// spare
|
||||
OP_cmp_T (LE, U, long, lvec2, lvec4, <=, ulong, ulvec2, ulvec4);
|
||||
case OP_V4QMUL_D:
|
||||
OPC(dvec4) = vqmuld (OPA(dvec4), OPB(dvec4));
|
||||
break;
|
||||
|
||||
// spare
|
||||
// 1 1111
|
||||
|
||||
// spare
|
||||
default:
|
||||
PR_RunError (pr, "Bad opcode o%03o", st->op & OP_MASK);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue