[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).
This commit is contained in:
Bill Currie 2022-01-16 16:27:33 +09:00
parent 8050c7bd77
commit 7ea12b3ff9
3 changed files with 71 additions and 1 deletions

View file

@ -34,7 +34,14 @@ libs/gamecode/pr_opcode.lo: libs/gamecode/pr_opcode.c ${pr_opcode_src}
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)
hops_py = $(srcdir)/libs/gamecode/hops.py
pr_hops_cinc = $(top_builddir)/libs/gamecode/pr_hops.cinc
BUILT_SOURCES += \
$(pr_opcode_cinc) \
$(pr_opcode_hinc) \
$(pr_convert_cinc) \
$(pr_hops_cinc)
$(pr_opcode_cinc): $(opcodes_py)
$(V_PY)$(PYTHON) $(opcodes_py) table > $(pr_opcode_cinc).t && \
@ -48,3 +55,7 @@ $(pr_opcode_hinc): $(opcodes_py)
$(pr_convert_cinc): $(convert_py)
$(V_PY)$(PYTHON) $(convert_py) table > $(pr_convert_cinc).t && \
$(am__mv) $(pr_convert_cinc).t $(pr_convert_cinc)
$(pr_hops_cinc): $(hops_py)
$(V_PY)$(PYTHON) $(hops_py) table > $(pr_hops_cinc).t && \
$(am__mv) $(pr_hops_cinc).t $(pr_hops_cinc)

55
libs/gamecode/hops.py Normal file
View file

@ -0,0 +1,55 @@
print("""// encoding is tssooo
// t = 0: 32-bit, t = 1: 64-bit
// ss = 00: reserved
// ss = 01: 2 components
// ss = 10: 3 components
// ss = 11: 4 components
// ooo = 000: and
// ooo = 001: or
// ooo = 010: xor
// ooo = 011: add.i
// ooo = 100: nand
// ooo = 101: nor
// ooo = 110: xnor
// ooo = 111: add.f
""")
#for vec3
types = [
["int", "int", "int", "int", "int", "int", "int", "float"],
["long", "long", "long", "long", "long", "long", "long", "double"]
]
#does not include size (2 or 4, 3 is special)
vec_types = [
["ivec", "ivec", "ivec", "ivec", "ivec", "ivec", "ivec", "vec"],
["lvec", "lvec", "lvec", "lvec", "lvec", "lvec", "lvec", "dvec"]
]
operators = ["&", "|", "^", "+"]
def case_str(type, width, op):
case = (type << 5) | (width << 3) | (op)
return f"case {case:03o}:"
def src_str(type, width, op):
if width & 1:
return f"OPA({vec_types[type][op]}{width+1})"
else:
return f"OPA({types[type][op]})"
def dst_str(type, width, op):
return f"OPC({types[type][op]})"
def hop_str(type, width, op):
return f"OP_hop{width+1}"
for type in range(2):
for width in range(1, 4): # 0 is reserved
for opcode in range(8):
case = case_str(type, width, opcode)
src = src_str(type, width, opcode)
dst = dst_str(type, width, opcode)
hop = hop_str(type, width, opcode)
op = operators[opcode & 3]
if width == 2:
print(f"{case} {dst} = {hop} (&{src}, {op}); break;")
else:
print(f"{case} {dst} = {hop} ({src}, {op}); break;")

View file

@ -3387,8 +3387,12 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
// 1100 spare
// 1101 spare
// 1110 spare
#define OP_hop2(vec, op) ((vec)[0] op (vec)[1])
#define OP_hop3(vec, op) ((vec)[0] op (vec)[1] op (vec)[2])
#define OP_hop4(vec, op) ((vec)[0] op (vec)[1] op (vec)[2] op (vec)[3])
case OP_HOPS:
switch (st->b) {
#include "libs/gamecode/pr_hops.cinc"
default:
PR_RunError (pr, "invalid hops code: %04o",
st->b);