# SPDX-License-Identifier: LGPL-2.1-or-later
# See Notices.txt for copyright information
+from typing import List
from soc.decoder.isa.caller import (SVP64PrefixFields, SV64P_MAJOR_SIZE,
SV64P_PID_SIZE, SVP64RMFields,
SVP64RM_EXTRA2_SPEC_SIZE,
from soc.decoder.power_fields import DecodeFields
-class RangeField:
- def __init__(self):
- self.start = None
- self.last = None
- # TODO: finish
+class InclusiveRange:
+ __slots__ = "start", "stop"
+
+ def __init__(self, start, stop=None):
+ if stop is None:
+ stop = start
+ self.start = start
+ self.stop = stop
+
+ def __len__(self) -> int:
+ return self.width
+
+ @property
+ def width(self) -> int:
+ return self.stop - self.start + 1
+
+ def __repr__(self):
+ if self.start == self.stop:
+ return f"InclusiveRange({self.start})"
+ return f"InclusiveRange({self.start}, {self.stop})"
+
+ def __str__(self):
+ if self.start == self.stop:
+ return f"{self.start}"
+ return f"{self.start}:{self.stop}"
+
+ def append(self, v):
+ if v == self.stop + 1:
+ self.stop = v
+ else:
+ raise ValueError()
+
+ def endian_reversed(self, word_length) -> "InclusiveRange":
+ # note reversed stop/start
+ return InclusiveRange(word_length - 1 - self.stop,
+ word_length - 1 - self.start)
+
+
+class RangesField:
+ __slots__ = "ranges",
+ ranges: List[InclusiveRange]
+
+ def __init__(self, ranges=None):
+ if ranges is None:
+ ranges = []
+ if isinstance(ranges, InclusiveRange):
+ ranges = [ranges]
+ self.ranges = ranges
+
+ def __len__(self):
+ retval = 0
+ for i in self.ranges:
+ retval += len(i)
+ return retval
+
+ def __repr__(self):
+ if len(self.ranges) == 0:
+ return "RangesField()"
+ if len(self.ranges) == 1:
+ return f"RangesField({self.ranges[0]})"
+ return f"RangesField({self.ranges})"
+
+ def __str__(self):
+ if len(self.ranges) == 0:
+ return "none"
+ return ",".join(map(str, self.ranges))
+
+ def __setitem__(self, key, value):
+ assert isinstance(key, int)
+ assert isinstance(value, int)
+ assert key == len(self)
+ try:
+ self.ranges[-1].append(value)
+ return
+ except IndexError:
+ pass
+ except ValueError:
+ pass
+ self.ranges.append(InclusiveRange(value))
+
+ def endian_reversed(self, word_length) -> "RangesField":
+ return RangesField([i.endian_reversed(word_length) for i in reversed(self.ranges)])
+
+ @property
+ def contiguous(self) -> bool:
+ return len(self.ranges) == 1
+
+ @property
+ def start(self) -> int:
+ assert self.contiguous
+ return self.ranges[0].start
+
+ @property
+ def stop(self) -> int:
+ assert self.contiguous
+ return self.ranges[0].stop
+
+ @property
+ def width(self) -> int:
+ assert self.contiguous
+ return self.ranges[0].width
isa = ISA()
svp64rm = SVP64RM()
-decode_fields = DecodeFields()
+decode_fields = DecodeFields(bitkls=RangesField)
decode_fields.create_specs()
-
-decode_fields.forms
-PRIMARY_OPCODE_SHIFT = 32 - 6
+PO_FIELD: RangesField = decode_fields.PO
+RT_FIELD: RangesField = decode_fields.RT
+RA_FIELD: RangesField = decode_fields.RA
+print(f"PO_FIELD={PO_FIELD}")
+print(f"RT_FIELD={RT_FIELD}")
+print(f"RA_FIELD={RA_FIELD}")
+
+WORD_LENGTH = 32
+PRIMARY_OPCODE_SHIFT = PO_FIELD.endian_reversed(WORD_LENGTH).start
# unofficial value. see https://libre-soc.org/openpower/sv/setvl/
# FIXME: incorrect extended opcode value
SETVL_OPCODE = (19 << PRIMARY_OPCODE_SHIFT) | (0 << 1)
SETVL_IMMEDIATE_SHIFT = 32 - 7 - 16
REG_FIELD_WIDTH = 5
-XL_FORM_RT_SHIFT = 32 - REG_FIELD_WIDTH - 6
-XL_FORM_RA_SHIFT = 32 - REG_FIELD_WIDTH - 11
+RT_SHIFT = RT_FIELD.endian_reversed(WORD_LENGTH).start
+RA_SHIFT = RA_FIELD.endian_reversed(WORD_LENGTH).start
+
+print(f"RT_SHIFT={RT_SHIFT}")
+print(f"RA_SHIFT={RA_SHIFT}")
+print(f"PRIMARY_OPCODE_SHIFT={PRIMARY_OPCODE_SHIFT}")
def is_power_of_2(i):
"# setvl %[retval], %[vl], MVL=%[max_vl]\\n\\t"
".long %[instr] | (%[retval] << %[rt_shift]) | (%[vl] << %[ra_shift])"
: [retval] "=b"(retval.value)
- : [vl] "b"(vl), [max_vl] "n"(MAX_VL), [instr] "n"({FIXME@@@FINISH}));
+ : [vl] "b"(vl), [max_vl] "n"(MAX_VL), [instr] "n"({FIXME___FINISH}));
return retval;
}}
}} // namespace sv