Commit 9b761dfb authored by Lyude Paul's avatar Lyude Paul

wip: working fma/add encoding for simple add/fma src ops

parent 9b8c2dcc
......@@ -50,6 +50,13 @@ class OpParserBase:
self.opcode = opcode
self.srcs = srcs
def encode(self):
"""
Placeholder for encode(), this should be overridden in
subclasses!
"""
return [s.encode_src() for s in self.srcs]
def __repr__(self):
return '<%s at %s; srcs=%s>' % (self.name, hex(id(self)), self.srcs)
......@@ -57,17 +64,14 @@ class OpParserBase:
def __init__(self, expected, got):
super().__init__('Expected %d sources, got %d' % (expected, got))
def __init_subclass__(cls, src_cnt=None, **kwargs):
super().__init_subclass__(**kwargs)
if src_cnt:
def parse_op(self, reg_file, srcs):
if len(srcs) != src_cnt:
raise OpParserBase.SrcCountException(len(srcs), src_cnt)
def parse_op(self, reg_file, srcs):
if self.src_cnt and len(srcs) != self.src_cnt:
raise self.SrcCountException(self.src_cnt, len(srcs))
return self.Op(self.name, self.opcode, srcs)
cls.parse_op = parse_op
return self.Op(self.name, self.opcode, srcs)
def __init__(self, name, opcode):
def __init__(self, name, opcode, src_cnt=None):
self.src_cnt = src_cnt
self.name = name
self.opcode = opcode
......@@ -79,35 +83,48 @@ class fma:
NAME = 'FMA'
DST_MNEMONIC = 'T0'
class OneSrcOpParser(OpParserBase, src_cnt=1):
pass
@classmethod
def __repr__(cls):
return 'FMA'
class TwoSrcOpParser(OpParserBase, src_cnt=2):
pass
class ZeroSrc():
encoded = bitstring.pack('uint:3=3')
class ThreeSrcOpParser(OpParserBase, src_cnt=3):
pass
@classmethod
def encode_src(cls):
return cls.encoded
class FourSrcOpParser(OpParserBase, src_cnt=4):
pass
class SrcOpParser(OpParserBase):
class Op(OpParserBase.Op):
def encode(self):
bs = bitstring.BitStream()
bs += bitstring.pack('uint:%d' % (23 - len(bs)), self.opcode)
for src in self.srcs:
bs += src.encode_src()
return bs
def __init__(self, name, opcode, src_cnt=None):
self.src_cnt = src_cnt
opcode >>= (src_cnt - 1) * 3
super().__init__(name, opcode)
class TwoSrcFmodOpParser(OpParserBase, src_cnt=2):
pass
class TwoSrcFmodOpParser(OpParserBase):
src_cnt = 2
class ThreeSrcFmodOpParser(OpParserBase, src_cnt=3):
pass
class ThreeSrcFmodOpParser(OpParserBase):
src_cnt = 3
class TwoSrcFmod16OpParser(OpParserBase, src_cnt=2):
pass
class TwoSrcFmod16OpParser(OpParserBase):
src_cnt = 2
class ThreeSrcFmod16OpParser(OpParserBase, src_cnt=3):
pass
class ThreeSrcFmod16OpParser(OpParserBase):
src_cnt = 3
class FcmpOpParser(OpParserBase, src_cnt=2):
pass
class FcmpOpParser(OpParserBase):
src_cnt = 2
class Fcmp16OpParser(OpParserBase, src_cnt=2):
pass
class Fcmp16OpParser(OpParserBase):
src_cnt = 2
# s/{ \(0x[0-9a-f]\+\),\s\+\("[^"]\+"\),\s\+\%\(FMA\|ADD\)\([A-Za-z0-9]\+\)\s\+},/\2: \3Op(\2, \1),/g
OP_MAP = {
......@@ -116,128 +133,128 @@ class fma:
"MIN.f32" : TwoSrcFmodOpParser("MIN.f32", 0x44000),
"FCMP.GL" : FcmpOpParser("FCMP.GL", 0x48000),
"FCMP.D3D" : FcmpOpParser("FCMP.D3D", 0x4c000),
"ADD.i32" : TwoSrcOpParser("ADD.i32", 0x4ff98),
"SUB.i32" : TwoSrcOpParser("SUB.i32", 0x4ffd8),
"SUBB.i32" : TwoSrcOpParser("SUBB.i32", 0x4fff0),
"ADD.i32" : SrcOpParser("ADD.i32", 0x4ff98, 2),
"SUB.i32" : SrcOpParser("SUB.i32", 0x4ffd8, 2),
"SUBB.i32" : SrcOpParser("SUBB.i32", 0x4fff0, 2),
# compute FMA of first three sources, then set exponent to the fourth
# source (as an integer).
"FMA_RSCALE" : FourSrcOpParser("FMA_RSCALE", 0x50000),
"FMA_RSCALE" : SrcOpParser("FMA_RSCALE", 0x50000, 4),
# Seems to compute src2 - src0 * src1... why don't they just use FMA?
"FRCP_PT3" : ThreeSrcOpParser("FRCP_PT3", 0x528c0),
"FRCP_PT3" : SrcOpParser("FRCP_PT3", 0x528c0, 3),
# compute FMA of first three sources, then add the fourth argument to the
# scale (modify scale)
"FMA_MSCALE" : FourSrcOpParser("FMA_MSCALE", 0x54000),
"FMA_MSCALE" : SrcOpParser("FMA_MSCALE", 0x54000, 4),
"ADD.f32" : TwoSrcFmodOpParser("ADD.f32", 0x58000),
"CSEL.FEQ.f32" : FourSrcOpParser("CSEL.FEQ.f32", 0x5c000),
"CSEL.FGT.f32" : FourSrcOpParser("CSEL.FGT.f32", 0x5c200),
"CSEL.FGE.f32" : FourSrcOpParser("CSEL.FGE.f32", 0x5c400),
"CSEL.IEQ.f32" : FourSrcOpParser("CSEL.IEQ.f32", 0x5c600),
"CSEL.IGT.i32" : FourSrcOpParser("CSEL.IGT.i32", 0x5c800),
"CSEL.IGE.i32" : FourSrcOpParser("CSEL.IGE.i32", 0x5ca00),
"CSEL.UGT.i32" : FourSrcOpParser("CSEL.UGT.i32", 0x5cc00),
"CSEL.UGE.i32" : FourSrcOpParser("CSEL.UGE.i32", 0x5ce00),
"ICMP.D3D.GT.v2i16" : TwoSrcOpParser("ICMP.D3D.GT.v2i16", 0x5d8d0),
"UCMP.D3D.GT.v2i16" : TwoSrcOpParser("UCMP.D3D.GT.v2i16", 0x5d9d0),
"ICMP.D3D.GE.v2i16" : TwoSrcOpParser("ICMP.D3D.GE.v2i16", 0x5dad0),
"UCMP.D3D.GE.v2i16" : TwoSrcOpParser("UCMP.D3D.GE.v2i16", 0x5dbd0),
"ICMP.D3D.EQ.v2i16" : TwoSrcOpParser("ICMP.D3D.EQ.v2i16", 0x5dcd0),
"ICMP.GL.GT.i32" : TwoSrcOpParser("ICMP.GL.GT.i32", 0x5de40), # src0 > src1 ? 1 : 0
"ICMP.GL.GE.i32" : TwoSrcOpParser("ICMP.GL.GE.i32", 0x5de48),
"UCMP.GL.GT.i32" : TwoSrcOpParser("UCMP.GL.GT.i32", 0x5de50),
"UCMP.GL.GE.i32" : TwoSrcOpParser("UCMP.GL.GE.i32", 0x5de58),
"ICMP.GL.EQ.i32" : TwoSrcOpParser("ICMP.GL.EQ.i32", 0x5de60),
"ICMP.D3D.GT.i32" : TwoSrcOpParser("ICMP.D3D.GT.i32", 0x5dec0), # src0 > src1 ? ~0 : 0
"ICMP.D3D.GE.i32" : TwoSrcOpParser("ICMP.D3D.GE.i32", 0x5dec8),
"UCMP.D3D.GT.i32" : TwoSrcOpParser("UCMP.D3D.GT.i32", 0x5ded0),
"UCMP.D3D.GE.i32" : TwoSrcOpParser("UCMP.D3D.GE.i32", 0x5ded8),
"ICMP.D3D.EQ.i32" : TwoSrcOpParser("ICMP.D3D.EQ.i32", 0x5dee0),
"RSHIFT_NAND.i32" : ThreeSrcOpParser("RSHIFT_NAND.i32", 0x60200),
"RSHIFT_NAND.v2i16" : ThreeSrcOpParser("RSHIFT_NAND.v2i16", 0x603c0),
"RSHIFT_OR.i32" : ThreeSrcOpParser("RSHIFT_OR.i32", 0x60e00),
"RSHIFT_OR.v2i16" : ThreeSrcOpParser("RSHIFT_OR.v2i16", 0x60fc0),
"RSHIFT_AND.i32" : ThreeSrcOpParser("RSHIFT_AND.i32", 0x61200),
"RSHIFT_AND.v2i16" : ThreeSrcOpParser("RSHIFT_AND.v2i16", 0x613c0),
"RSHIFT_NOR.i32" : ThreeSrcOpParser("RSHIFT_NOR.i32", 0x61e00), # ~((src0 << src2) | src1)
"RSHIFT_NOR.v2i16" : ThreeSrcOpParser("RSHIFT_NOR.v2i16", 0x61fc0), # ~((src0 << src2) | src1)
"LSHIFT_NAND.i32" : ThreeSrcOpParser("LSHIFT_NAND.i32", 0x62200),
"LSHIFT_NAND.v2i16" : ThreeSrcOpParser("LSHIFT_NAND.v2i16", 0x623c0),
"LSHIFT_OR.i32" : ThreeSrcOpParser("LSHIFT_OR.i32", 0x62e00), # (src0 << src2) | src1
"LSHIFT_OR.v2i16" : ThreeSrcOpParser("LSHIFT_OR.v2i16", 0x62fc0), # (src0 << src2) | src1
"LSHIFT_AND.i32" : ThreeSrcOpParser("LSHIFT_AND.i32", 0x63200), # (src0 << src2) & src1
"LSHIFT_AND.v2i16" : ThreeSrcOpParser("LSHIFT_AND.v2i16", 0x633c0),
"LSHIFT_NOR.i32" : ThreeSrcOpParser("LSHIFT_NOR.i32", 0x63e00),
"LSHIFT_NOR.v2i16" : ThreeSrcOpParser("LSHIFT_NOR.v2i16", 0x63fc0),
"RSHIFT_XOR.i32" : ThreeSrcOpParser("RSHIFT_XOR.i32", 0x64200),
"RSHIFT_XOR.v2i16" : ThreeSrcOpParser("RSHIFT_XOR.v2i16", 0x643c0),
"RSHIFT_XNOR.i32" : ThreeSrcOpParser("RSHIFT_XNOR.i32", 0x64600), # ~((src0 >> src2) ^ src1)
"RSHIFT_XNOR.v2i16" : ThreeSrcOpParser("RSHIFT_XNOR.v2i16", 0x647c0), # ~((src0 >> src2) ^ src1)
"LSHIFT_XOR.i32" : ThreeSrcOpParser("LSHIFT_XOR.i32", 0x64a00),
"LSHIFT_XOR.v2i16" : ThreeSrcOpParser("LSHIFT_XOR.v2i16", 0x64bc0),
"LSHIFT_XNOR.i32" : ThreeSrcOpParser("LSHIFT_XNOR.i32", 0x64e00), # ~((src0 >> src2) ^ src1)
"LSHIFT_XNOR.v2i16" : ThreeSrcOpParser("LSHIFT_XNOR.v2i16", 0x64fc0), # ~((src0 >> src2) ^ src1)
"LSHIFT_ADD.i32" : ThreeSrcOpParser("LSHIFT_ADD.i32", 0x65200),
"LSHIFT_SUB.i32" : ThreeSrcOpParser("LSHIFT_SUB.i32", 0x65600), # (src0 << src2) - src1
"LSHIFT_RSUB.i32" : ThreeSrcOpParser("LSHIFT_RSUB.i32", 0x65a00), # src1 - (src0 << src2)
"RSHIFT_ADD.i32" : ThreeSrcOpParser("RSHIFT_ADD.i32", 0x65e00),
"RSHIFT_SUB.i32" : ThreeSrcOpParser("RSHIFT_SUB.i32", 0x66200),
"RSHIFT_RSUB.i32" : ThreeSrcOpParser("RSHIFT_RSUB.i32", 0x66600),
"ARSHIFT_ADD.i32" : ThreeSrcOpParser("ARSHIFT_ADD.i32", 0x66a00),
"ARSHIFT_SUB.i32" : ThreeSrcOpParser("ARSHIFT_SUB.i32", 0x66e00),
"ARSHIFT_RSUB.i32" : ThreeSrcOpParser("ARSHIFT_RSUB.i32", 0x67200),
"CSEL.FEQ.f32" : SrcOpParser("CSEL.FEQ.f32", 0x5c000, 4),
"CSEL.FGT.f32" : SrcOpParser("CSEL.FGT.f32", 0x5c200, 4),
"CSEL.FGE.f32" : SrcOpParser("CSEL.FGE.f32", 0x5c400, 4),
"CSEL.IEQ.f32" : SrcOpParser("CSEL.IEQ.f32", 0x5c600, 4),
"CSEL.IGT.i32" : SrcOpParser("CSEL.IGT.i32", 0x5c800, 4),
"CSEL.IGE.i32" : SrcOpParser("CSEL.IGE.i32", 0x5ca00, 4),
"CSEL.UGT.i32" : SrcOpParser("CSEL.UGT.i32", 0x5cc00, 4),
"CSEL.UGE.i32" : SrcOpParser("CSEL.UGE.i32", 0x5ce00, 4),
"ICMP.D3D.GT.v2i16" : SrcOpParser("ICMP.D3D.GT.v2i16", 0x5d8d0, 2),
"UCMP.D3D.GT.v2i16" : SrcOpParser("UCMP.D3D.GT.v2i16", 0x5d9d0, 2),
"ICMP.D3D.GE.v2i16" : SrcOpParser("ICMP.D3D.GE.v2i16", 0x5dad0, 2),
"UCMP.D3D.GE.v2i16" : SrcOpParser("UCMP.D3D.GE.v2i16", 0x5dbd0, 2),
"ICMP.D3D.EQ.v2i16" : SrcOpParser("ICMP.D3D.EQ.v2i16", 0x5dcd0, 2),
"ICMP.GL.GT.i32" : SrcOpParser("ICMP.GL.GT.i32", 0x5de40, 2), # src0 > src1 ? 1 : 0
"ICMP.GL.GE.i32" : SrcOpParser("ICMP.GL.GE.i32", 0x5de48, 2),
"UCMP.GL.GT.i32" : SrcOpParser("UCMP.GL.GT.i32", 0x5de50, 2),
"UCMP.GL.GE.i32" : SrcOpParser("UCMP.GL.GE.i32", 0x5de58, 2),
"ICMP.GL.EQ.i32" : SrcOpParser("ICMP.GL.EQ.i32", 0x5de60, 2),
"ICMP.D3D.GT.i32" : SrcOpParser("ICMP.D3D.GT.i32", 0x5dec0, 2), # src0 > src1 ? ~0 : 0
"ICMP.D3D.GE.i32" : SrcOpParser("ICMP.D3D.GE.i32", 0x5dec8, 2),
"UCMP.D3D.GT.i32" : SrcOpParser("UCMP.D3D.GT.i32", 0x5ded0, 2),
"UCMP.D3D.GE.i32" : SrcOpParser("UCMP.D3D.GE.i32", 0x5ded8, 2),
"ICMP.D3D.EQ.i32" : SrcOpParser("ICMP.D3D.EQ.i32", 0x5dee0, 2),
"RSHIFT_NAND.i32" : SrcOpParser("RSHIFT_NAND.i32", 0x60200, 3),
"RSHIFT_NAND.v2i16" : SrcOpParser("RSHIFT_NAND.v2i16", 0x603c0, 3),
"RSHIFT_OR.i32" : SrcOpParser("RSHIFT_OR.i32", 0x60e00, 3),
"RSHIFT_OR.v2i16" : SrcOpParser("RSHIFT_OR.v2i16", 0x60fc0, 3),
"RSHIFT_AND.i32" : SrcOpParser("RSHIFT_AND.i32", 0x61200, 3),
"RSHIFT_AND.v2i16" : SrcOpParser("RSHIFT_AND.v2i16", 0x613c0, 3),
"RSHIFT_NOR.i32" : SrcOpParser("RSHIFT_NOR.i32", 0x61e00, 3), # ~((src0 << src2) | src1)
"RSHIFT_NOR.v2i16" : SrcOpParser("RSHIFT_NOR.v2i16", 0x61fc0, 3), # ~((src0 << src2) | src1)
"LSHIFT_NAND.i32" : SrcOpParser("LSHIFT_NAND.i32", 0x62200, 3),
"LSHIFT_NAND.v2i16" : SrcOpParser("LSHIFT_NAND.v2i16", 0x623c0, 3),
"LSHIFT_OR.i32" : SrcOpParser("LSHIFT_OR.i32", 0x62e00, 3), # (src0 << src2) | src1
"LSHIFT_OR.v2i16" : SrcOpParser("LSHIFT_OR.v2i16", 0x62fc0, 3), # (src0 << src2) | src1
"LSHIFT_AND.i32" : SrcOpParser("LSHIFT_AND.i32", 0x63200, 3), # (src0 << src2) & src1
"LSHIFT_AND.v2i16" : SrcOpParser("LSHIFT_AND.v2i16", 0x633c0, 3),
"LSHIFT_NOR.i32" : SrcOpParser("LSHIFT_NOR.i32", 0x63e00, 3),
"LSHIFT_NOR.v2i16" : SrcOpParser("LSHIFT_NOR.v2i16", 0x63fc0, 3),
"RSHIFT_XOR.i32" : SrcOpParser("RSHIFT_XOR.i32", 0x64200, 3),
"RSHIFT_XOR.v2i16" : SrcOpParser("RSHIFT_XOR.v2i16", 0x643c0, 3),
"RSHIFT_XNOR.i32" : SrcOpParser("RSHIFT_XNOR.i32", 0x64600, 3), # ~((src0 >> src2) ^ src1)
"RSHIFT_XNOR.v2i16" : SrcOpParser("RSHIFT_XNOR.v2i16", 0x647c0, 3), # ~((src0 >> src2) ^ src1)
"LSHIFT_XOR.i32" : SrcOpParser("LSHIFT_XOR.i32", 0x64a00, 3),
"LSHIFT_XOR.v2i16" : SrcOpParser("LSHIFT_XOR.v2i16", 0x64bc0, 3),
"LSHIFT_XNOR.i32" : SrcOpParser("LSHIFT_XNOR.i32", 0x64e00, 3), # ~((src0 >> src2) ^ src1)
"LSHIFT_XNOR.v2i16" : SrcOpParser("LSHIFT_XNOR.v2i16", 0x64fc0, 3), # ~((src0 >> src2) ^ src1)
"LSHIFT_ADD.i32" : SrcOpParser("LSHIFT_ADD.i32", 0x65200, 3),
"LSHIFT_SUB.i32" : SrcOpParser("LSHIFT_SUB.i32", 0x65600, 3), # (src0 << src2) - src1
"LSHIFT_RSUB.i32" : SrcOpParser("LSHIFT_RSUB.i32", 0x65a00, 3), # src1 - (src0 << src2)
"RSHIFT_ADD.i32" : SrcOpParser("RSHIFT_ADD.i32", 0x65e00, 3),
"RSHIFT_SUB.i32" : SrcOpParser("RSHIFT_SUB.i32", 0x66200, 3),
"RSHIFT_RSUB.i32" : SrcOpParser("RSHIFT_RSUB.i32", 0x66600, 3),
"ARSHIFT_ADD.i32" : SrcOpParser("ARSHIFT_ADD.i32", 0x66a00, 3),
"ARSHIFT_SUB.i32" : SrcOpParser("ARSHIFT_SUB.i32", 0x66e00, 3),
"ARSHIFT_RSUB.i32" : SrcOpParser("ARSHIFT_RSUB.i32", 0x67200, 3),
"FMA.v2f16" : ThreeSrcFmod16OpParser("FMA.v2f16", 0x80000),
"MAX.v2f16" : TwoSrcFmod16OpParser("MAX.v2f16", 0xc0000),
"MIN.v2f16" : TwoSrcFmod16OpParser("MIN.v2f16", 0xc4000),
"FCMP.GL" : Fcmp16OpParser("FCMP.GL", 0xc8000),
"FCMP.D3D" : Fcmp16OpParser("FCMP.D3D", 0xcc000),
"ADD.v2i16" : TwoSrcOpParser("ADD.v2i16", 0xcf900),
"ADDC.i32" : TwoSrcOpParser("ADDC.i32", 0xcfc10),
"ADD.i32.i16.X" : TwoSrcOpParser("ADD.i32.i16.X", 0xcfd80),
"ADD.i32.u16.X" : TwoSrcOpParser("ADD.i32.u16.X", 0xcfd90),
"ADD.i32.i16.Y" : TwoSrcOpParser("ADD.i32.i16.Y", 0xcfdc0),
"ADD.i32.u16.Y" : TwoSrcOpParser("ADD.i32.u16.Y", 0xcfdd0),
"ADD.v2i16" : SrcOpParser("ADD.v2i16", 0xcf900, 2),
"ADDC.i32" : SrcOpParser("ADDC.i32", 0xcfc10, 2),
"ADD.i32.i16.X" : SrcOpParser("ADD.i32.i16.X", 0xcfd80, 2),
"ADD.i32.u16.X" : SrcOpParser("ADD.i32.u16.X", 0xcfd90, 2),
"ADD.i32.i16.Y" : SrcOpParser("ADD.i32.i16.Y", 0xcfdc0, 2),
"ADD.i32.u16.Y" : SrcOpParser("ADD.i32.u16.Y", 0xcfdd0, 2),
"ADD.v2f16" : TwoSrcFmod16OpParser("ADD.v2f16", 0xd8000),
"CSEL.FEQ.v2f16" : FourSrcOpParser("CSEL.FEQ.v2f16", 0xdc000),
"CSEL.FGT.v2f16" : FourSrcOpParser("CSEL.FGT.v2f16", 0xdc200),
"CSEL.FGE.v2f16" : FourSrcOpParser("CSEL.FGE.v2f16", 0xdc400),
"CSEL.IEQ.v2f16" : FourSrcOpParser("CSEL.IEQ.v2f16", 0xdc600),
"CSEL.IGT.v2i16" : FourSrcOpParser("CSEL.IGT.v2i16", 0xdc800),
"CSEL.IGE.v2i16" : FourSrcOpParser("CSEL.IGE.v2i16", 0xdca00),
"CSEL.UGT.v2i16" : FourSrcOpParser("CSEL.UGT.v2i16", 0xdcc00),
"CSEL.UGE.v2i16" : FourSrcOpParser("CSEL.UGE.v2i16", 0xdce00),
"F32_TO_F16" : TwoSrcOpParser("F32_TO_F16", 0xdd000),
"F16_TO_I16.XX" : OneSrcOpParser("F16_TO_I16.XX", 0xe0046),
"F16_TO_U16.XX" : OneSrcOpParser("F16_TO_U16.XX", 0xe0047),
"F16_TO_I16.YX" : OneSrcOpParser("F16_TO_I16.YX", 0xe004e),
"F16_TO_U16.YX" : OneSrcOpParser("F16_TO_U16.YX", 0xe004f),
"F16_TO_I16.XY" : OneSrcOpParser("F16_TO_I16.XY", 0xe0056),
"F16_TO_U16.XY" : OneSrcOpParser("F16_TO_U16.XY", 0xe0057),
"F16_TO_I16.YY" : OneSrcOpParser("F16_TO_I16.YY", 0xe005e),
"F16_TO_U16.YY" : OneSrcOpParser("F16_TO_U16.YY", 0xe005f),
"I16_TO_F16.XX" : OneSrcOpParser("I16_TO_F16.XX", 0xe00c0),
"U16_TO_F16.XX" : OneSrcOpParser("U16_TO_F16.XX", 0xe00c1),
"I16_TO_F16.YX" : OneSrcOpParser("I16_TO_F16.YX", 0xe00c8),
"U16_TO_F16.YX" : OneSrcOpParser("U16_TO_F16.YX", 0xe00c9),
"I16_TO_F16.XY" : OneSrcOpParser("I16_TO_F16.XY", 0xe00d0),
"U16_TO_F16.XY" : OneSrcOpParser("U16_TO_F16.XY", 0xe00d1),
"I16_TO_F16.YY" : OneSrcOpParser("I16_TO_F16.YY", 0xe00d8),
"U16_TO_F16.YY" : OneSrcOpParser("U16_TO_F16.YY", 0xe00d9),
"F32_TO_I32" : OneSrcOpParser("F32_TO_I32", 0xe0136),
"F32_TO_U32" : OneSrcOpParser("F32_TO_U32", 0xe0137),
"I32_TO_F32" : OneSrcOpParser("I32_TO_F32", 0xe0178),
"U32_TO_F32" : OneSrcOpParser("U32_TO_F32", 0xe0179),
"I16_TO_I32.X" : OneSrcOpParser("I16_TO_I32.X", 0xe0198),
"U16_TO_U32.X" : OneSrcOpParser("U16_TO_U32.X", 0xe0199),
"I16_TO_I32.Y" : OneSrcOpParser("I16_TO_I32.Y", 0xe019a),
"U16_TO_U32.Y" : OneSrcOpParser("U16_TO_U32.Y", 0xe019b),
"I16_TO_F32.X" : OneSrcOpParser("I16_TO_F32.X", 0xe019c),
"U16_TO_F32.X" : OneSrcOpParser("U16_TO_F32.X", 0xe019d),
"I16_TO_F32.Y" : OneSrcOpParser("I16_TO_F32.Y", 0xe019e),
"U16_TO_F32.Y" : OneSrcOpParser("U16_TO_F32.Y", 0xe019f),
"F16_TO_F32.X" : OneSrcOpParser("F16_TO_F32.X", 0xe01a2),
"F16_TO_F32.Y" : OneSrcOpParser("F16_TO_F32.Y", 0xe01a3),
"NOP" : OneSrcOpParser("NOP", 0xe032c),
"MOV" : OneSrcOpParser("MOV", 0xe032d),
"SWZ.YY.v2i16" : OneSrcOpParser("SWZ.YY.v2i16", 0xe032f),
"CSEL.FEQ.v2f16" : SrcOpParser("CSEL.FEQ.v2f16", 0xdc000, 4),
"CSEL.FGT.v2f16" : SrcOpParser("CSEL.FGT.v2f16", 0xdc200, 4),
"CSEL.FGE.v2f16" : SrcOpParser("CSEL.FGE.v2f16", 0xdc400, 4),
"CSEL.IEQ.v2f16" : SrcOpParser("CSEL.IEQ.v2f16", 0xdc600, 4),
"CSEL.IGT.v2i16" : SrcOpParser("CSEL.IGT.v2i16", 0xdc800, 4),
"CSEL.IGE.v2i16" : SrcOpParser("CSEL.IGE.v2i16", 0xdca00, 4),
"CSEL.UGT.v2i16" : SrcOpParser("CSEL.UGT.v2i16", 0xdcc00, 4),
"CSEL.UGE.v2i16" : SrcOpParser("CSEL.UGE.v2i16", 0xdce00, 4),
"F32_TO_F16" : SrcOpParser("F32_TO_F16", 0xdd000, 2),
"F16_TO_I16.XX" : SrcOpParser("F16_TO_I16.XX", 0xe0046, 1),
"F16_TO_U16.XX" : SrcOpParser("F16_TO_U16.XX", 0xe0047, 1),
"F16_TO_I16.YX" : SrcOpParser("F16_TO_I16.YX", 0xe004e, 1),
"F16_TO_U16.YX" : SrcOpParser("F16_TO_U16.YX", 0xe004f, 1),
"F16_TO_I16.XY" : SrcOpParser("F16_TO_I16.XY", 0xe0056, 1),
"F16_TO_U16.XY" : SrcOpParser("F16_TO_U16.XY", 0xe0057, 1),
"F16_TO_I16.YY" : SrcOpParser("F16_TO_I16.YY", 0xe005e, 1),
"F16_TO_U16.YY" : SrcOpParser("F16_TO_U16.YY", 0xe005f, 1),
"I16_TO_F16.XX" : SrcOpParser("I16_TO_F16.XX", 0xe00c0, 1),
"U16_TO_F16.XX" : SrcOpParser("U16_TO_F16.XX", 0xe00c1, 1),
"I16_TO_F16.YX" : SrcOpParser("I16_TO_F16.YX", 0xe00c8, 1),
"U16_TO_F16.YX" : SrcOpParser("U16_TO_F16.YX", 0xe00c9, 1),
"I16_TO_F16.XY" : SrcOpParser("I16_TO_F16.XY", 0xe00d0, 1),
"U16_TO_F16.XY" : SrcOpParser("U16_TO_F16.XY", 0xe00d1, 1),
"I16_TO_F16.YY" : SrcOpParser("I16_TO_F16.YY", 0xe00d8, 1),
"U16_TO_F16.YY" : SrcOpParser("U16_TO_F16.YY", 0xe00d9, 1),
"F32_TO_I32" : SrcOpParser("F32_TO_I32", 0xe0136, 1),
"F32_TO_U32" : SrcOpParser("F32_TO_U32", 0xe0137, 1),
"I32_TO_F32" : SrcOpParser("I32_TO_F32", 0xe0178, 1),
"U32_TO_F32" : SrcOpParser("U32_TO_F32", 0xe0179, 1),
"I16_TO_I32.X" : SrcOpParser("I16_TO_I32.X", 0xe0198, 1),
"U16_TO_U32.X" : SrcOpParser("U16_TO_U32.X", 0xe0199, 1),
"I16_TO_I32.Y" : SrcOpParser("I16_TO_I32.Y", 0xe019a, 1),
"U16_TO_U32.Y" : SrcOpParser("U16_TO_U32.Y", 0xe019b, 1),
"I16_TO_F32.X" : SrcOpParser("I16_TO_F32.X", 0xe019c, 1),
"U16_TO_F32.X" : SrcOpParser("U16_TO_F32.X", 0xe019d, 1),
"I16_TO_F32.Y" : SrcOpParser("I16_TO_F32.Y", 0xe019e, 1),
"U16_TO_F32.Y" : SrcOpParser("U16_TO_F32.Y", 0xe019f, 1),
"F16_TO_F32.X" : SrcOpParser("F16_TO_F32.X", 0xe01a2, 1),
"F16_TO_F32.Y" : SrcOpParser("F16_TO_F32.Y", 0xe01a3, 1),
"NOP" : SrcOpParser("NOP", 0xe032c, 1),
"MOV" : SrcOpParser("MOV", 0xe032d, 1),
"SWZ.YY.v2i16" : SrcOpParser("SWZ.YY.v2i16", 0xe032f, 1),
# From the ARM patent US20160364209A1:
# "Decompose v (the input) into numbers x1 and s such that v = x1 * 2^s,
# and x1 is a floating point value in a predetermined range where the
......@@ -245,33 +262,33 @@ class fma:
# choose a range where 1 is towards middle of range)."
#
# This computes x1.
"LOG_FREXPM" : OneSrcOpParser("LOG_FREXPM", 0xe0345),
"FRCP_TABLE" : OneSrcOpParser("FRCP_TABLE", 0xe0365),
"LOG_FREXPM" : SrcOpParser("LOG_FREXPM", 0xe0345, 1),
"FRCP_TABLE" : SrcOpParser("FRCP_TABLE", 0xe0365, 1),
# Compute required exponent for reciprocal (negate it, accounting for the offset.)
"FRCP_EXP" : OneSrcOpParser("FRCP_EXP", 0xe038d),
"LOG_FREXPE" : OneSrcOpParser("LOG_FREXPE", 0xe03c5),
"IMAX3" : ThreeSrcOpParser("IMAX3", 0xe0b80),
"UMAX3" : ThreeSrcOpParser("UMAX3", 0xe0bc0),
"IMIN3" : ThreeSrcOpParser("IMIN3", 0xe0c00),
"UMIN3" : ThreeSrcOpParser("UMIN3", 0xe0c40),
"CSEL" : ThreeSrcOpParser("CSEL", 0xe0f40), # src2 != 0 ? src1 : src0
"CEIL" : OneSrcOpParser("CEIL", 0xe1845),
"FLOOR" : OneSrcOpParser("FLOOR", 0xe1885),
"FRCP_EXP" : SrcOpParser("FRCP_EXP", 0xe038d, 1),
"LOG_FREXPE" : SrcOpParser("LOG_FREXPE", 0xe03c5, 1),
"IMAX3" : SrcOpParser("IMAX3", 0xe0b80, 3),
"UMAX3" : SrcOpParser("UMAX3", 0xe0bc0, 3),
"IMIN3" : SrcOpParser("IMIN3", 0xe0c00, 3),
"UMIN3" : SrcOpParser("UMIN3", 0xe0c40, 3),
"CSEL" : SrcOpParser("CSEL", 0xe0f40, 3), # src2 != 0 ? src1 : src0
"CEIL" : SrcOpParser("CEIL", 0xe1845, 1),
"FLOOR" : SrcOpParser("FLOOR", 0xe1885, 1),
# This acts like a normal 32-bit add, except that it sets a flag on
# overflow that gets listened to by load/store instructions in the ADD
# part of the instruction, and added appropriately to the upper 32 bits of
# the address. It lets you efficiently add a 32-bit offset to a 64-bit
# pointer when loading/storing.
"ADD_ADDR" : TwoSrcOpParser("ADD_ADDR", 0xe1c80),
"ADD_ADDR" : SrcOpParser("ADD_ADDR", 0xe1c80, 2),
# Similar to the above, but used for normal additions (paired with
# ADD_HIGH32 in the ADD slot to do 64-bit addition).
"ADD_LOW32" : TwoSrcOpParser("ADD_LOW32", 0xe1cc0),
"SEL.XX.i16" : TwoSrcOpParser("SEL.XX.i16", 0xe1e00),
"SEL.YX.i16" : TwoSrcOpParser("SEL.YX.i16", 0xe1e08),
"SEL.XY.i16" : TwoSrcOpParser("SEL.XY.i16", 0xe1e10),
"SEL.YY.i16" : TwoSrcOpParser("SEL.YY.i16", 0xe1e18),
"IMAD" : ThreeSrcOpParser("IMAD", 0xe7800),
"POPCNT" : OneSrcOpParser("POPCNT", 0xe78db),
"ADD_LOW32" : SrcOpParser("ADD_LOW32", 0xe1cc0, 2),
"SEL.XX.i16" : SrcOpParser("SEL.XX.i16", 0xe1e00, 2),
"SEL.YX.i16" : SrcOpParser("SEL.YX.i16", 0xe1e08, 2),
"SEL.XY.i16" : SrcOpParser("SEL.XY.i16", 0xe1e10, 2),
"SEL.YY.i16" : SrcOpParser("SEL.YY.i16", 0xe1e18, 2),
"IMAD" : SrcOpParser("IMAD", 0xe7800, 3),
"POPCNT" : SrcOpParser("POPCNT", 0xe78db, 1),
}
......@@ -291,29 +308,34 @@ class add:
self.has_data_reg = has_data_reg
super().__init__(name, opcode)
class OneSrcOpParser(AddOpParserBase, src_cnt=1):
pass
class SrcOpParser(AddOpParserBase):
class Op(OpParserBase.Op):
def encode(self):
bs = bitstring.BitStream()
bs += bitstring.pack('uint:%d' % (20 - len(bs)), self.opcode)
for src in self.srcs:
bs += src.encode_src()
return bs
class TwoSrcOpParser(AddOpParserBase, src_cnt=2):
pass
def __init__(self, name, opcode, src_cnt, has_data_reg=False):
self.src_cnt = src_cnt
opcode >>= (src_cnt - 1) * 3
super().__init__(name, opcode, has_data_reg)
class ThreeSrcOpParser(AddOpParserBase, src_cnt=3):
pass
class TwoSrcFmodOpParser(AddOpParserBase):
src_cnt = 2
class TwoSrcFmodOpParser(AddOpParserBase, src_cnt=2):
pass
class TwoSrcFmod16OpParser(AddOpParserBase):
src_cnt = 2
class TwoSrcFmod16OpParser(AddOpParserBase, src_cnt=2):
pass
class TwoSrcFmod16CommutativeOpParser(AddOpParserBase):
src_cnt = 2
class TwoSrcFmod16CommutativeOpParser(AddOpParserBase, src_cnt=2):
pass
class FcmpOpParser(AddOpParserBase):
src_cnt = 2
class FcmpOpParser(AddOpParserBase, src_cnt=2):
pass
class Fcmp16OpParser(AddOpParserBase, src_cnt=2):
pass
class Fcmp16OpParser(AddOpParserBase):
src_cnt = 2
class LoadAttrOpParser(AddOpParserBase):
pass
......@@ -362,40 +384,40 @@ class add:
"ADD.f32" : TwoSrcFmodOpParser("ADD.f32", 0x04000),
"FCMP.GL" : FcmpOpParser("FCMP.GL", 0x06000),
"FCMP.D3D" : FcmpOpParser("FCMP.D3D", 0x07000),
"F16_TO_I16" : OneSrcOpParser("F16_TO_I16", 0x07856),
"F16_TO_U16" : OneSrcOpParser("F16_TO_U16", 0x07857),
"I16_TO_F16.XX" : OneSrcOpParser("I16_TO_F16.XX", 0x078c0),
"U16_TO_F16.XX" : OneSrcOpParser("U16_TO_F16.XX", 0x078c1),
"I16_TO_F16.YX" : OneSrcOpParser("I16_TO_F16.YX", 0x078c8),
"U16_TO_F16.YX" : OneSrcOpParser("U16_TO_F16.YX", 0x078c9),
"I16_TO_F16.XY" : OneSrcOpParser("I16_TO_F16.XY", 0x078d0),
"U16_TO_F16.XY" : OneSrcOpParser("U16_TO_F16.XY", 0x078d1),
"I16_TO_F16.YY" : OneSrcOpParser("I16_TO_F16.YY", 0x078d8),
"U16_TO_F16.YY" : OneSrcOpParser("U16_TO_F16.YY", 0x078d9),
"F32_TO_I32" : OneSrcOpParser("F32_TO_I32", 0x07936),
"F32_TO_U32" : OneSrcOpParser("F32_TO_U32", 0x07937),
"I32_TO_F32" : OneSrcOpParser("I32_TO_F32", 0x07978),
"U32_TO_F32" : OneSrcOpParser("U32_TO_F32", 0x07979),
"I16_TO_I32.X" : OneSrcOpParser("I16_TO_I32.X", 0x07998),
"U16_TO_U32.X" : OneSrcOpParser("U16_TO_U32.X", 0x07999),
"I16_TO_I32.Y" : OneSrcOpParser("I16_TO_I32.Y", 0x0799a),
"U16_TO_U32.Y" : OneSrcOpParser("U16_TO_U32.Y", 0x0799b),
"I16_TO_F32.X" : OneSrcOpParser("I16_TO_F32.X", 0x0799c),
"U16_TO_F32.X" : OneSrcOpParser("U16_TO_F32.X", 0x0799d),
"I16_TO_F32.Y" : OneSrcOpParser("I16_TO_F32.Y", 0x0799e),
"U16_TO_F32.Y" : OneSrcOpParser("U16_TO_F32.Y", 0x0799f),
"F16_TO_I16" : SrcOpParser("F16_TO_I16", 0x07856, 1),
"F16_TO_U16" : SrcOpParser("F16_TO_U16", 0x07857, 1),
"I16_TO_F16.XX" : SrcOpParser("I16_TO_F16.XX", 0x078c0, 1),
"U16_TO_F16.XX" : SrcOpParser("U16_TO_F16.XX", 0x078c1, 1),
"I16_TO_F16.YX" : SrcOpParser("I16_TO_F16.YX", 0x078c8, 1),
"U16_TO_F16.YX" : SrcOpParser("U16_TO_F16.YX", 0x078c9, 1),
"I16_TO_F16.XY" : SrcOpParser("I16_TO_F16.XY", 0x078d0, 1),
"U16_TO_F16.XY" : SrcOpParser("U16_TO_F16.XY", 0x078d1, 1),
"I16_TO_F16.YY" : SrcOpParser("I16_TO_F16.YY", 0x078d8, 1),
"U16_TO_F16.YY" : SrcOpParser("U16_TO_F16.YY", 0x078d9, 1),
"F32_TO_I32" : SrcOpParser("F32_TO_I32", 0x07936, 1),
"F32_TO_U32" : SrcOpParser("F32_TO_U32", 0x07937, 1),
"I32_TO_F32" : SrcOpParser("I32_TO_F32", 0x07978, 1),
"U32_TO_F32" : SrcOpParser("U32_TO_F32", 0x07979, 1),
"I16_TO_I32.X" : SrcOpParser("I16_TO_I32.X", 0x07998, 1),
"U16_TO_U32.X" : SrcOpParser("U16_TO_U32.X", 0x07999, 1),
"I16_TO_I32.Y" : SrcOpParser("I16_TO_I32.Y", 0x0799a, 1),
"U16_TO_U32.Y" : SrcOpParser("U16_TO_U32.Y", 0x0799b, 1),
"I16_TO_F32.X" : SrcOpParser("I16_TO_F32.X", 0x0799c, 1),
"U16_TO_F32.X" : SrcOpParser("U16_TO_F32.X", 0x0799d, 1),
"I16_TO_F32.Y" : SrcOpParser("I16_TO_F32.Y", 0x0799e, 1),
"U16_TO_F32.Y" : SrcOpParser("U16_TO_F32.Y", 0x0799f, 1),
# take the low 16 bits, and expand it to a 32-bit float
"F16_TO_F32.X" : OneSrcOpParser("F16_TO_F32.X", 0x079a2),
"F16_TO_F32.X" : SrcOpParser("F16_TO_F32.X", 0x079a2, 1),
# take the high 16 bits, ...
"F16_TO_F32.Y" : OneSrcOpParser("F16_TO_F32.Y", 0x079a3),
"SWZ.YX.v2i16" : OneSrcOpParser("SWZ.YX.v2i16", 0x07b2b),
"NOP" : OneSrcOpParser("NOP", 0x07b2c),
"SWZ.XX.v2i16" : OneSrcOpParser("SWZ.XX.v2i16", 0x07b29),
"F16_TO_F32.Y" : SrcOpParser("F16_TO_F32.Y", 0x079a3, 1),
"SWZ.YX.v2i16" : SrcOpParser("SWZ.YX.v2i16", 0x07b2b, 1),
"NOP" : SrcOpParser("NOP", 0x07b2c, 1),
"SWZ.XX.v2i16" : SrcOpParser("SWZ.XX.v2i16", 0x07b29, 1),
# Logically, this should be SWZ.XY, but that's equivalent to a move, and
# this seems to be the canonical way the blob generates a MOV.
"MOV" : OneSrcOpParser("MOV", 0x07b2d),
"SWZ.YY.v2i16" : OneSrcOpParser("SWZ.YY.v2i16", 0x07b2f),
"FRCP_EXP" : OneSrcOpParser("FRCP_EXP", 0x07b8d),
"MOV" : SrcOpParser("MOV", 0x07b2d, 1),
"SWZ.YY.v2i16" : SrcOpParser("SWZ.YY.v2i16", 0x07b2f, 1),
"FRCP_EXP" : SrcOpParser("FRCP_EXP", 0x07b8d, 1),
# From the ARM patent US20160364209A1:
# "Decompose v (the input) into numbers x1 and s such that v = x1 * 2^s,
# and x1 is a floating point value in a predetermined range where the
......@@ -403,10 +425,10 @@ class add:
# choose a range where 1 is towards middle of range)."
#
# This computes s.
"FLOG_FREXPE" : OneSrcOpParser("FLOG_FREXPE", 0x07bc5),
"CEIL" : OneSrcOpParser("CEIL", 0x07d45),
"FLOOR" : OneSrcOpParser("FLOOR", 0x07d85),
"ADD_HIGH32" : TwoSrcOpParser("ADD_HIGH32", 0x07f18),
"FLOG_FREXPE" : SrcOpParser("FLOG_FREXPE", 0x07bc5, 1),
"CEIL" : SrcOpParser("CEIL", 0x07d45, 1),
"FLOOR" : SrcOpParser("FLOOR", 0x07d85, 1),
"ADD_HIGH32" : SrcOpParser("ADD_HIGH32", 0x07f18, 2),
"LD_ATTR.f16" : LoadAttrOpParser("LD_ATTR.f16", 0x08000, True),
"LD_ATTR.v2f16" : LoadAttrOpParser("LD_ATTR.v2f16", 0x08100, True),
"LD_ATTR.v3f16" : LoadAttrOpParser("LD_ATTR.v3f16", 0x08200, True),
......@@ -425,59 +447,59 @@ class add:
"LD_ATTR.v4u32" : LoadAttrOpParser("LD_ATTR.v4u32", 0x08f00, True),
"LD_VAR.32" : VaryingInterpOpParser("LD_VAR.32", 0x0a000, True),
"TEX" : TexCompactOpParser("TEX", 0x0b000, True),
"LOAD.i32" : TwoSrcOpParser("LOAD.i32", 0x0c188, True),
"LD_UBO.i32" : TwoSrcOpParser("LD_UBO.i32", 0x0c1a0, True),
"LOAD.v2i32" : TwoSrcOpParser("LOAD.v2i32", 0x0c1c8, True),
"LD_UBO.v2i32" : TwoSrcOpParser("LD_UBO.v2i32", 0x0c1e0, True),
"LOAD.v4i32" : TwoSrcOpParser("LOAD.v4i32", 0x0c208, True),
"LOAD.i32" : SrcOpParser("LOAD.i32", 0x0c188, 2, True),
"LD_UBO.i32" : SrcOpParser("LD_UBO.i32", 0x0c1a0, 2, True),
"LOAD.v2i32" : SrcOpParser("LOAD.v2i32", 0x0c1c8, 2, True),
"LD_UBO.v2i32" : SrcOpParser("LD_UBO.v2i32", 0x0c1e0, 2, True),
"LOAD.v4i32" : SrcOpParser("LOAD.v4i32", 0x0c208, 2, True),
# src0 = offset, src1 = binding
"LD_UBO.v4i32" : TwoSrcOpParser("LD_UBO.v4i32", 0x0c220, True),
"STORE.v4i32" : TwoSrcOpParser("STORE.v4i32", 0x0c248, True),
"STORE.i32" : TwoSrcOpParser("STORE.i32", 0x0c588, True),
"STORE.v2i32" : TwoSrcOpParser("STORE.v2i32", 0x0c5c8, True),
"LOAD.u16" : TwoSrcOpParser("LOAD.u16", 0x0c648, True), # zero-extends
"LOAD.v3i32" : TwoSrcOpParser("LOAD.v3i32", 0x0ca88, True),
"LD_UBO.v3i32" : TwoSrcOpParser("LD_UBO.v3i32", 0x0caa0, True),
"STORE.v3i32" : TwoSrcOpParser("STORE.v3i32", 0x0cb88, True),
"LD_UBO.v4i32" : SrcOpParser("LD_UBO.v4i32", 0x0c220, 2, True),
"STORE.v4i32" : SrcOpParser("STORE.v4i32", 0x0c248, 2, True),
"STORE.i32" : SrcOpParser("STORE.i32", 0x0c588, 2, True),
"STORE.v2i32" : SrcOpParser("STORE.v2i32", 0x0c5c8, 2, True),
"LOAD.u16" : SrcOpParser("LOAD.u16", 0x0c648, 2, True), # zero-extends
"LOAD.v3i32" : SrcOpParser("LOAD.v3i32", 0x0ca88, 2, True),
"LD_UBO.v3i32" : SrcOpParser("LD_UBO.v3i32", 0x0caa0, 2, True),
"STORE.v3i32" : SrcOpParser("STORE.v3i32", 0x0cb88, 2, True),
# Does not exist on G71 (added to G51, G72, and everything after)
"FRCP_FAST.f32" : OneSrcOpParser("FRCP_FAST.f32", 0x0cc00),
"FRCP_FAST.f32" : SrcOpParser("FRCP_FAST.f32", 0x0cc00, 1),
# Produce appropriate scale
"FRCP_SCALE" : OneSrcOpParser("FRCP_SCALE", 0x0ce00),
"FRCP_SCALE" : SrcOpParser("FRCP_SCALE", 0x0ce00, 1),
# Used in the argument reduction for log.
# See the ARM patent for more information.
"FRCP_APPROX" : OneSrcOpParser("FRCP_APPROX", 0x0ce60),
"SIN_TABLE" : OneSrcOpParser("SIN_TABLE", 0x0cf50),
"COS_TABLE" : OneSrcOpParser("COS_TABLE", 0x0cf51),
"FLOG2_TABLE" : OneSrcOpParser("FLOG2_TABLE", 0x0cf60),
"FLOGE_TABLE" : OneSrcOpParser("FLOGE_TABLE", 0x0cf64),
"FRCP_APPROX" : SrcOpParser("FRCP_APPROX", 0x0ce60, 1),
"SIN_TABLE" : SrcOpParser("SIN_TABLE", 0x0cf50, 1),
"COS_TABLE" : SrcOpParser("COS_TABLE", 0x0cf51, 1),
"FLOG2_TABLE" : SrcOpParser("FLOG2_TABLE", 0x0cf60, 1),
"FLOGE_TABLE" : SrcOpParser("FLOGE_TABLE", 0x0cf64, 1),
"BRANCH" : BranchOpParser("BRANCH", 0x0d000),
"SEL.XX.i16" : TwoSrcOpParser("SEL.XX.i16", 0x0ea60),
"SEL.XY.i16" : TwoSrcOpParser("SEL.XY.i16", 0x0ea70),
"SEL.YX.i16" : TwoSrcOpParser("SEL.YX.i16", 0x0ea68),
"SEL.YY.i16" : TwoSrcOpParser("SEL.YY.i16", 0x0ea78),
"F32_TO_F16" : TwoSrcOpParser("F32_TO_F16", 0x0ec00),
"ICMP.GL.GT" : TwoSrcOpParser("ICMP.GL.GT", 0x0f640), # src0 > src1 ? 1 : 0
"ICMP.GL.GE" : TwoSrcOpParser("ICMP.GL.GE", 0x0f648),
"UCMP.GL.GT" : TwoSrcOpParser("UCMP.GL.GT", 0x0f650),
"UCMP.GL.GE" : TwoSrcOpParser("UCMP.GL.GE", 0x0f658),
"ICMP.GL.EQ" : TwoSrcOpParser("ICMP.GL.EQ", 0x0f660),
"ICMP.D3D.GT" : TwoSrcOpParser("ICMP.D3D.GT", 0x0f6c0), # src0 > src1 ? ~0 : 0
"ICMP.D3D.GE" : TwoSrcOpParser("ICMP.D3D.GE", 0x0f6c8),
"UCMP.D3D.GT" : TwoSrcOpParser("UCMP.D3D.GT", 0x0f6d0),
"UCMP.D3D.GE" : TwoSrcOpParser("UCMP.D3D.GE", 0x0f6d8),
"ICMP.D3D.EQ" : TwoSrcOpParser("ICMP.D3D.EQ", 0x0f6e0),
"SEL.XX.i16" : SrcOpParser("SEL.XX.i16", 0x0ea60, 2),
"SEL.XY.i16" : SrcOpParser("SEL.XY.i16", 0x0ea70, 2),
"SEL.YX.i16" : SrcOpParser("SEL.YX.i16", 0x0ea68, 2),
"SEL.YY.i16" : SrcOpParser("SEL.YY.i16", 0x0ea78, 2),
"F32_TO_F16" : SrcOpParser("F32_TO_F16", 0x0ec00, 2),
"ICMP.GL.GT" : SrcOpParser("ICMP.GL.GT", 0x0f640, 2), # src0 > src1 ? 1 : 0
"ICMP.GL.GE" : SrcOpParser("ICMP.GL.GE", 0x0f648, 2),
"UCMP.GL.GT" : SrcOpParser("UCMP.GL.GT", 0x0f650, 2),
"UCMP.GL.GE" : SrcOpParser("UCMP.GL.GE", 0x0f658, 2),
"ICMP.GL.EQ" : SrcOpParser("ICMP.GL.EQ", 0x0f660, 2),
"ICMP.D3D.GT" : SrcOpParser("ICMP.D3D.GT", 0x0f6c0, 2), # src0 > src1 ? ~0 : 0
"ICMP.D3D.GE" : SrcOpParser("ICMP.D3D.GE", 0x0f6c8, 2),
"UCMP.D3D.GT" : SrcOpParser("UCMP.D3D.GT", 0x0f6d0, 2),
"UCMP.D3D.GE" : SrcOpParser("UCMP.D3D.GE", 0x0f6d8, 2),
"ICMP.D3D.EQ" : SrcOpParser("ICMP.D3D.EQ", 0x0f6e0, 2),
"MAX.v2f16" : TwoSrcFmod16CommutativeOpParser("MAX.v2f16", 0x10000),
"MIN.v2f16" : TwoSrcFmod16CommutativeOpParser("MIN.v2f16", 0x12000),
"ADD.v2f16" : TwoSrcFmod16OpParser("ADD.v2f16", 0x14000),
"FCMP.D3D" : Fcmp16OpParser("FCMP.D3D", 0x17000),
"ADD.i32" : TwoSrcOpParser("ADD.i32", 0x178c0),
"ADD.v2i16" : TwoSrcOpParser("ADD.v2i16", 0x17900),
"SUB.i32" : TwoSrcOpParser("SUB.i32", 0x17ac0),
"ADDC.i32" : TwoSrcOpParser("ADDC.i32", 0x17c10), # adds src0 to the bottom bit of src1
"ADD.i32.i16.X" : TwoSrcOpParser("ADD.i32.i16.X", 0x17d80),