mirror of
https://github.com/tinygrad/tinygrad.git
synced 2026-08-29 10:16:07 +00:00
dual mov
This commit is contained in:
@@ -126,7 +126,7 @@ def disasm(inst: Inst) -> str:
|
||||
src0_str = fmt_src(src0)
|
||||
vsrc1_str = _vreg(vsrc1, 2) if is_64bit_vsrc1 else f"v{vsrc1 & 0x7f}.{'h' if vsrc1 >= 128 else 'l'}" if is_16bit else f"v{vsrc1}"
|
||||
if is_cmpx:
|
||||
return f"{op_name} {src0_str}, {vsrc1_str}"
|
||||
return f"{op_name}_e32 {src0_str}, {vsrc1_str}"
|
||||
return f"{op_name}_e32 vcc_lo, {src0_str}, {vsrc1_str}"
|
||||
|
||||
# SOPP
|
||||
@@ -644,7 +644,19 @@ def disasm(inst: Inst) -> str:
|
||||
if cls_name == 'SOPK':
|
||||
sdst, simm16 = unwrap(inst._values.get('sdst', 0)), unwrap(inst._values.get('simm16', 0))
|
||||
if op_name == 's_version': return f"{op_name} 0x{simm16:x}"
|
||||
if op_name == 's_setreg_b32': return f"{op_name} 0x{simm16:x}, {_fmt_sdst(sdst, 1)}"
|
||||
if op_name in ('s_setreg_b32', 's_getreg_b32'):
|
||||
# Decode hwreg: (size-1) << 11 | offset << 6 | id
|
||||
hwreg_id, hwreg_offset, hwreg_size = simm16 & 0x3f, (simm16 >> 6) & 0x1f, ((simm16 >> 11) & 0x1f) + 1
|
||||
hwreg_names = {1: 'HW_REG_MODE', 2: 'HW_REG_STATUS', 3: 'HW_REG_TRAPSTS', 4: 'HW_REG_HW_ID1', 5: 'HW_REG_HW_ID2',
|
||||
15: 'HW_REG_GPR_ALLOC', 16: 'HW_REG_LDS_ALLOC', 17: 'HW_REG_IB_STS', 18: 'HW_REG_IB_STS2',
|
||||
20: 'HW_REG_SH_MEM_BASES', 21: 'HW_REG_TBA_LO', 22: 'HW_REG_TBA_HI', 23: 'HW_REG_TMA_LO',
|
||||
24: 'HW_REG_TMA_HI', 25: 'HW_REG_FLAT_SCR_LO', 26: 'HW_REG_FLAT_SCR_HI', 27: 'HW_REG_XNACK_MASK',
|
||||
29: 'HW_REG_POPS_PACKER'}
|
||||
hwreg_name = hwreg_names.get(hwreg_id, str(hwreg_id))
|
||||
hwreg_str = f"hwreg({hwreg_name}, {hwreg_offset}, {hwreg_size})"
|
||||
if op_name == 's_setreg_b32':
|
||||
return f"{op_name} {hwreg_str}, {_fmt_sdst(sdst, 1)}"
|
||||
return f"{op_name} {_fmt_sdst(sdst, 1)}, {hwreg_str}"
|
||||
return f"{op_name} {_fmt_sdst(sdst, dst_cnt)}, 0x{simm16:x}"
|
||||
|
||||
# Generic fallback
|
||||
@@ -706,6 +718,18 @@ def asm(text: str) -> Inst:
|
||||
elif m := re.match(r'lgkmcnt\((\d+)\)', part): lgkmcnt = int(m.group(1))
|
||||
elif re.match(r'^0x[0-9a-f]+$|^\d+$', part): return autogen.s_waitcnt(simm16=int(part, 0))
|
||||
return autogen.s_waitcnt(simm16=waitcnt(vmcnt, expcnt, lgkmcnt))
|
||||
# Handle VOPD dual-issue instructions: opx dst, src :: opy dst, src
|
||||
if '::' in text:
|
||||
x_part, y_part = text.split('::')
|
||||
x_parts, y_parts = x_part.strip().replace(',', ' ').split(), y_part.strip().replace(',', ' ').split()
|
||||
opx_name, opy_name = x_parts[0].upper(), y_parts[0].upper()
|
||||
opx, opy = autogen.VOPDOp[opx_name], autogen.VOPDOp[opy_name]
|
||||
x_ops, y_ops = [parse_operand(p)[0] for p in x_parts[1:]], [parse_operand(p)[0] for p in y_parts[1:]]
|
||||
vdstx, srcx0 = x_ops[0], x_ops[1] if len(x_ops) > 1 else 0
|
||||
vsrcx1 = x_ops[2] if len(x_ops) > 2 else VGPR(0)
|
||||
vdsty, srcy0 = y_ops[0], y_ops[1] if len(y_ops) > 1 else 0
|
||||
vsrcy1 = y_ops[2] if len(y_ops) > 2 else VGPR(0)
|
||||
return autogen.VOPD(opx, opy, vdstx=vdstx, vdsty=vdsty, srcx0=srcx0, vsrcx1=vsrcx1, srcy0=srcy0, vsrcy1=vsrcy1)
|
||||
operands, current, depth, in_pipe = [], "", 0, False
|
||||
for ch in op_str:
|
||||
if ch == '[': depth += 1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# autogenerated from AMD RDNA3.5 ISA PDF by gen.py - do not edit
|
||||
from enum import IntEnum
|
||||
from extra.assembly.rdna3.lib import bits, Inst32, Inst64, SGPR, VGPR, TTMP as TTMP, s as s, v as v, SSrc, Src, SImm, Imm
|
||||
from extra.assembly.rdna3.lib import bits, Inst32, Inst64, SGPR, VGPR, TTMP as TTMP, s as s, v as v, SSrc, Src, SImm, Imm, VDSTYEnc
|
||||
import functools
|
||||
|
||||
class SrcEnum(IntEnum):
|
||||
@@ -1818,7 +1818,7 @@ class VOPD(Inst64):
|
||||
opx:VOPDOp = bits[25:22]
|
||||
opy:VOPDOp = bits[21:17]
|
||||
vdstx:VGPR = bits[63:56]
|
||||
vdsty:VGPR = bits[55:49]
|
||||
vdsty:VDSTYEnc = bits[55:49]
|
||||
srcx0:Src = bits[8:0]
|
||||
vsrcx1:VGPR = bits[16:9]
|
||||
srcy0:Src = bits[40:32]
|
||||
|
||||
@@ -37,6 +37,7 @@ class SSrc: pass
|
||||
class Src: pass
|
||||
class Imm: pass
|
||||
class SImm: pass
|
||||
class VDSTYEnc: pass # VOPD vdsty: encoded = actual >> 1, actual = (encoded << 1) | ((vdstx & 1) ^ 1)
|
||||
class RawImm:
|
||||
def __init__(self, val: int): self.val = val
|
||||
def __repr__(self): return f"RawImm({self.val})"
|
||||
@@ -47,7 +48,7 @@ def unwrap(val) -> int:
|
||||
|
||||
# Encoding helpers
|
||||
FLOAT_ENC = {0.5: 240, -0.5: 241, 1.0: 242, -1.0: 243, 2.0: 244, -2.0: 245, 4.0: 246, -4.0: 247}
|
||||
SRC_FIELDS = {'src0', 'src1', 'src2', 'ssrc0', 'ssrc1', 'soffset'}
|
||||
SRC_FIELDS = {'src0', 'src1', 'src2', 'ssrc0', 'ssrc1', 'soffset', 'srcx0', 'srcy0'}
|
||||
RAW_FIELDS = {'vdata', 'vdst', 'vaddr', 'addr', 'data', 'data0', 'data1', 'sdst', 'sdata'}
|
||||
|
||||
def encode_src(val) -> int:
|
||||
@@ -112,6 +113,9 @@ class Inst:
|
||||
self._values[name] = val.idx // 2
|
||||
elif name in {'srsrc', 'ssamp'} and isinstance(val, Reg):
|
||||
self._values[name] = val.idx // 4
|
||||
# VOPD vdsty: encode as actual >> 1 (constraint: vdsty parity must be opposite of vdstx)
|
||||
elif ann is VDSTYEnc and isinstance(val, VGPR):
|
||||
self._values[name] = val.idx >> 1
|
||||
|
||||
def _encode_field(self, name: str, val) -> int:
|
||||
if isinstance(val, RawImm): return val.val
|
||||
@@ -163,8 +167,9 @@ class Inst:
|
||||
|
||||
def __repr__(self):
|
||||
# Use _fields order and exclude fields that are 0/default (for consistent repr after roundtrip)
|
||||
def is_zero(v): return (isinstance(v, int) and v == 0) or (isinstance(v, VGPR) and v.idx == 0 and v.count == 1)
|
||||
items = [(k, self._values[k]) for k in self._fields if k in self._values and k != 'encoding'
|
||||
and not (isinstance(self._values[k], int) and self._values[k] == 0 and k not in {'op'})]
|
||||
and not (is_zero(self._values[k]) and k not in {'op'})]
|
||||
lit = f", literal={hex(self._literal)}" if self._literal is not None else ""
|
||||
return f"{self.__class__.__name__}({', '.join(f'{k}={v}' for k, v in items)}{lit})"
|
||||
|
||||
|
||||
+804
-1937
File diff suppressed because it is too large
Load Diff
@@ -76,5 +76,8 @@ class TestIntegration(unittest.TestCase):
|
||||
def test_large_imm(self):
|
||||
self.inst = v_mov_b32_e32(v[0], 0x1234)
|
||||
|
||||
def test_dual_mov(self):
|
||||
self.inst = VOPD(VOPDOp.V_DUAL_MOV_B32, VOPDOp.V_DUAL_MOV_B32, vdstx=v[0], vdsty=v[1], srcx0=v[2], srcy0=v[4])
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user