Commit 46303864 authored by Lyude Paul's avatar Lyude Paul

wip: almost working full clause encoding

parent 28b33fa0
...@@ -956,18 +956,19 @@ class ImmediateSlot: ...@@ -956,18 +956,19 @@ class ImmediateSlot:
return ConstantSrc(token.read_type == ImmediateToken.ReadType.HIGH64) return ConstantSrc(token.read_type == ImmediateToken.ReadType.HIGH64)
def encode_contents(self): def encode_contents(self):
return sum(Bits(length=t.bitlen, uint=t.value) for t in self.contents) return sum(Bits(length=t.bitlen, uint=t.value) for t in
reversed(self.contents))
def encode_const_field(self): def encode_const_field(self):
return bitstring.pack('uint:1=0, uint:3, bits:4', encoded = BitArray(8)
self.IDX_MAP[self.idx], encoded[1:4] = self.IDX_MAP[self.idx]
self.encode_contents()[60:64]) encoded[4:8] = self.encode_contents()[60:64]
return encoded
def __repr__(self): def __repr__(self):
return "<ImmediateSlot #%d at 0x%x; contents=%s>" % ( return "<ImmediateSlot #%d at 0x%x; contents=%s>" % (
self.idx, id(self), self.contents) self.idx, id(self), self.contents)
class Uniform: class Uniform:
def __init__(self, idx): def __init__(self, idx):
self.idx = idx self.idx = idx
...@@ -1110,6 +1111,24 @@ class Clause: ...@@ -1110,6 +1111,24 @@ class Clause:
MAX_CONSTS_ALLOWED = 5 # FIXME: maybe make this 6 later? MAX_CONSTS_ALLOWED = 5 # FIXME: maybe make this 6 later?
QUADWORD_FORMATS = {
# (instructions, constants): pos
(1,0): 0x0,
(2,0): 0x1,
(4,0): 0x2,
(3,1): 0x3,
(5,1): 0x4,
(4,2): 0x5,
(7,0): 0x6,
(6,1): 0x7,
(5,3): 0x8,
(8,1): 0x9,
(7,2): 0xa,
(6,3): 0xb,
(8,3): 0xc,
(7,4): 0xd
}
def _header_flag(func): def _header_flag(func):
old_func = func old_func = func
def func(self, value): def func(self, value):
...@@ -1426,6 +1445,11 @@ class Clause: ...@@ -1426,6 +1445,11 @@ class Clause:
# immediate zero slot. # immediate zero slot.
if inst.has_pending_immediates(): if inst.has_pending_immediates():
pending = inst.reg_file.const_port pending = inst.reg_file.const_port
# FIXME: it looks like the compiler makes some interesting
# decisions regarding where it puts dummy clauses, for some
# reason consts 8/9 are swapped with consts 10/11 when the
# last instruction is the one reusing the same constant twice
# (and thus only requiring that half the slot be filled)
if all(t.value == 0 for t in pending): if all(t.value == 0 for t in pending):
inst.resolve_immediates(self, ImmediateZeroSlot) inst.resolve_immediates(self, ImmediateZeroSlot)
elif pending.bitlen == 64: elif pending.bitlen == 64:
...@@ -1451,6 +1475,7 @@ class Clause: ...@@ -1451,6 +1475,7 @@ class Clause:
first_inst.reg_file.add_reg_write(write.idx, stage) first_inst.reg_file.add_reg_write(write.idx, stage)
del self.__pending_writes del self.__pending_writes
# Resolve any pending state in our instructions
for inst in self.instructions: for inst in self.instructions:
inst.reg_file.assign_reg_ports() inst.reg_file.assign_reg_ports()
...@@ -1468,10 +1493,8 @@ class Clause: ...@@ -1468,10 +1493,8 @@ class Clause:
inst.resolve_immediates(self, slot) inst.resolve_immediates(self, slot)
self.immediate_slots.append(slot) self.immediate_slots.append(slot)
# TODO: Make sure we return whether or not the last format we used
# contained an inline immediate
@staticmethod @staticmethod
def _next_immediate_to_encode(cls, immediates): def _next_immediate_to_encode(immediates):
if immediates: if immediates:
return immediates.pop(0) return immediates.pop(0)
else: else:
...@@ -1524,7 +1547,6 @@ class Clause: ...@@ -1524,7 +1547,6 @@ class Clause:
# Format 3 # Format 3
quadword = BitArray(128) quadword = BitArray(128)
i3 = instructions.pop(0) if instructions else None i3 = instructions.pop(0) if instructions else None
used_fmt_3_2 = False
if not i3: if not i3:
# Format 3.1 # Format 3.1
...@@ -1538,9 +1560,8 @@ class Clause: ...@@ -1538,9 +1560,8 @@ class Clause:
quadword[15:45] = i2[3:33] quadword[15:45] = i2[3:33]
quadword[60:120] = next_immediate[0:60] quadword[60:120] = next_immediate[0:60]
quadword[120:128] = tag quadword[120:128] = tag
elif instructions: elif len(instructions) == 1:
# Format 3.2 # Format 3.2
used_fmt_3_2 = True
next_immediate = self._next_immediate_to_encode(immediates) next_immediate = self._next_immediate_to_encode(immediates)
tag = 0b10 tag = 0b10
...@@ -1552,7 +1573,9 @@ class Clause: ...@@ -1552,7 +1573,9 @@ class Clause:
quadword[125:128] = i2[0:3] quadword[125:128] = i2[0:3]
else: else:
# Format 3.3 # Format 3.3
if immediates: if instructions:
tag = 0b00000001
elif immediates:
tag = 0b00000101 tag = 0b00000101
else: else:
tag = 0b01000101 tag = 0b01000101
...@@ -1565,14 +1588,14 @@ class Clause: ...@@ -1565,14 +1588,14 @@ class Clause:
encoded.append(quadword) encoded.append(quadword)
if not instructions: if not instructions:
return encoded, packed_immediate return encoded
# Format 4 # Format 4
quadword = BitArray(128) quadword = BitArray(128)
i4 = instructions.pop(0) i4 = instructions.pop(0)
i5 = instructions.pop(0) if instructions else None i5 = instructions.pop(0) if instructions else None
if used_fmt_3_2: if not i5:
# Format 4.1 # Format 4.1
if immediates: if immediates:
tag = 0b00010 tag = 0b00010
...@@ -1657,11 +1680,40 @@ class Clause: ...@@ -1657,11 +1680,40 @@ class Clause:
return encoded return encoded
def encode(self): def encode(self):
encoded = BitString()
immediates = [s.encode_contents() for s in self.immediate_slots] immediates = [s.encode_contents() for s in self.immediate_slots]
# TODO: FINISH IT. encoded = BitStream()
return self._encode_quadwords(immediates) instructions = self._encode_quadwords(immediates)
encoded.append(instructions)
# We may have managed to pack one of the constants into the previous
# quadword
if len(immediates) < len(self.immediate_slots):
immediate_count = 1
else:
immediate_count = 0
instruction_count = len(self.instructions)
while immediates:
quadword = BitArray(128)
if len(immediates) > 2:
# More constants follow
tag = 0b0011
else:
tag = 0b0111
quadword[60:120] = immediates.pop(0)[0:60]
if immediates:
quadword[0:60] = immediates.pop(0)[0:60]
quadword[120:124] = tag
quadword[124:128] = self.QUADWORD_FORMATS[instruction_count,
immediate_count]
encoded.append(quadword)
immediate_count += 2
return encoded
def dump(self): def dump(self):
print('Clause #%d' % self.idx) print('Clause #%d' % self.idx)
......
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