Commit a4dac95e authored by Lyude Paul's avatar Lyude Paul

wip: slight cleanup + correct instruction encoding for simple instructions

This currently includes any N src instructions, along with ATEST and
BLEND instructions. The only value that should be slightly off now is
the constant port on clauses with a large number of immediates, due to a
difference with how the compiler assigns constants to slots
parent 9154d763
......@@ -93,16 +93,12 @@ class SrcOpParserBase(OpParserBase):
opcode >>= (src_cnt - 1) * 3
super().__init__(name, opcode, src_cnt)
# TODO: Redo most/all of this, make it more similar to how we dumped the
# instruction codes to begin with (map to strings with modifiers appended, don't
# parse modifiers seperately)
# Base Parsers/encoders for FMA operations
class fma:
NAME = 'FMA'
DST_MNEMONIC = 'T0'
class ZeroSrc():
encoded = bitstring.pack('uint:3=3')
encoded = Bits(length=3, uint=3)
@classmethod
def encode_src(cls):
......@@ -663,8 +659,9 @@ class RegisterToken:
class RegisterFile:
class Register:
def __init__(self, idx: int):
def __init__(self, idx, write_stage=None):
self.idx = idx
self.write_stage = write_stage
self.port = None
def encode_src(self):
......@@ -695,7 +692,7 @@ class RegisterFile:
NONE = 11
FIRST_READ_P3 = 12
FIRST_WRITE_ADD_P2 = 13
WRITE_FMA_P2_ADD_P3 = 15
WRITE_ADD_P2_FMA_P3 = 15
class NotEnoughPorts(ParsingException):
def __init__(self, type_, target):
......@@ -766,11 +763,11 @@ class RegisterFile:
return reg
def add_reg_write(self, idx):
def add_reg_write(self, idx, stage):
if idx in self.write_regs:
return self.write_regs[idx]
reg = self.Register(idx)
reg = self.Register(idx, stage)
self.write_regs[idx] = reg
if not self.port_assignment_possible():
raise self.NotEnoughPorts('write', reg)
......@@ -782,6 +779,8 @@ class RegisterFile:
# Remember: we can only disable ports 1 and 0 which are both read
raise self.NotEnoughPorts('read', reg)
assert self.ports[port] is None
reg.port = port
self.ports[port] = reg
......@@ -800,10 +799,14 @@ class RegisterFile:
if len(read_regs) == 3:
self._set_reg_port(3, read_regs.pop())
elif len(write_regs) == 2:
self._set_reg_port(3, write_regs.pop())
if write_regs:
self._set_reg_port(2, write_regs.pop())
for reg in write_regs:
if reg.write_stage is add:
port = 2
else:
port = 3
self._set_reg_port(port, reg)
elif len(write_regs) == 1:
self._set_reg_port(2, write_regs[0])
if len(read_regs) == 2:
if all(r.idx > 31 for r in read_regs):
......@@ -833,10 +836,8 @@ class RegisterFile:
# Figure out the value of the control field
if instruction.writes[fma]:
assert instruction.writes[fma].port == 2
if instruction.writes[add]:
control_field = self.ControlField.WRITE_FMA_P2_ADD_P3
control_field = self.ControlField.WRITE_ADD_P2_FMA_P3
elif self.ports[3]:
control_field = self.ControlField.WRITE_FMA_P2_READ_P3
elif instruction.first:
......@@ -904,12 +905,7 @@ class ConstantSrc:
self.high32 = high32
def encode_src(self):
if self.high32:
src = 5
else:
src = 4
return bitstring.pack('uint:3', src)
return Bits(length=3, uint=5 if self.high32 else 4)
def __repr__(self):
return '<ConstantSrc (%s) at 0x%x>' % (
......@@ -948,9 +944,6 @@ class ImmediateSlot:
return sum(Bits(length=t.bitlen, uint=t.value) for t in self.contents)
def encode_const_field(self):
# return bitstring.pack('bits:4, uint:3, uint:1=0',
# self.encode_contents()[60:64],
# self.IDX_MAP[self.idx])
return bitstring.pack('uint:1=0, uint:3, bits:4',
self.IDX_MAP[self.idx],
self.encode_contents()[60:64])
......@@ -1186,7 +1179,8 @@ class Clause:
# instruction that we have into our register file
for prev_stage, write in self.__pending_writes.items():
if write:
inst.writes[prev_stage] = inst.reg_file.add_reg_write(write.idx)
inst.writes[prev_stage] = \
inst.reg_file.add_reg_write(write.idx, prev_stage)
self.__pending_writes = {fma: None, add: None}
inst.fma = parser.parse_op(inst.reg_file, srcs)
......@@ -1266,7 +1260,8 @@ class Clause:
first_inst = self.instructions[0]
for stage, write in self.__pending_writes.items():
if write:
first_inst.writes[stage] = first_inst.reg_file.add_reg_write(write.idx)
first_inst.writes[stage] = \
first_inst.reg_file.add_reg_write(write.idx, stage)
del self.__pending_writes
for inst in self.instructions:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment