2 # SPDX-License-Identifier: LGPL-2.1-or-later
3 # See Notices.txt for copyright information
5 from typing
import List
6 from soc
.decoder
.isa
.caller
import (SVP64PrefixFields
, SV64P_MAJOR_SIZE
,
7 SV64P_PID_SIZE
, SVP64RMFields
,
8 SVP64RM_EXTRA2_SPEC_SIZE
,
9 SVP64RM_EXTRA3_SPEC_SIZE
,
10 SVP64RM_MODE_SIZE
, SVP64RM_SMASK_SIZE
,
11 SVP64RM_MMODE_SIZE
, SVP64RM_MASK_SIZE
,
12 SVP64RM_SUBVL_SIZE
, SVP64RM_EWSRC_SIZE
,
14 from soc
.decoder
.pseudo
.pagereader
import ISA
15 from soc
.decoder
.power_svp64
import SVP64RM
, get_regtype
, decode_extra
16 from soc
.decoder
.power_fields
import DecodeFields
20 __slots__
= "start", "stop"
22 def __init__(self
, start
, stop
=None):
28 def __len__(self
) -> int:
32 def width(self
) -> int:
33 return self
.stop
- self
.start
+ 1
36 if self
.start
== self
.stop
:
37 return f
"InclusiveRange({self.start})"
38 return f
"InclusiveRange({self.start}, {self.stop})"
41 if self
.start
== self
.stop
:
42 return f
"{self.start}"
43 return f
"{self.start}:{self.stop}"
46 if v
== self
.stop
+ 1:
51 def endian_reversed(self
, word_length
) -> "InclusiveRange":
52 # note reversed stop/start
53 return InclusiveRange(word_length
- 1 - self
.stop
,
54 word_length
- 1 - self
.start
)
59 ranges
: List
[InclusiveRange
]
61 def __init__(self
, ranges
=None):
64 if isinstance(ranges
, InclusiveRange
):
75 if len(self
.ranges
) == 0:
76 return "RangesField()"
77 if len(self
.ranges
) == 1:
78 return f
"RangesField({self.ranges[0]})"
79 return f
"RangesField({self.ranges})"
82 if len(self
.ranges
) == 0:
84 return ",".join(map(str, self
.ranges
))
86 def __setitem__(self
, key
, value
):
87 assert isinstance(key
, int)
88 assert isinstance(value
, int)
89 assert key
== len(self
)
91 self
.ranges
[-1].append(value
)
97 self
.ranges
.append(InclusiveRange(value
))
99 def endian_reversed(self
, word_length
) -> "RangesField":
100 return RangesField([i
.endian_reversed(word_length
) for i
in reversed(self
.ranges
)])
103 def contiguous(self
) -> bool:
104 return len(self
.ranges
) == 1
107 def start(self
) -> int:
108 assert self
.contiguous
109 return self
.ranges
[0].start
112 def stop(self
) -> int:
113 assert self
.contiguous
114 return self
.ranges
[0].stop
117 def width(self
) -> int:
118 assert self
.contiguous
119 return self
.ranges
[0].width
124 decode_fields
= DecodeFields(bitkls
=RangesField
)
125 decode_fields
.create_specs()
126 PO_FIELD
: RangesField
= decode_fields
.PO
127 RT_FIELD
: RangesField
= decode_fields
.RT
128 RA_FIELD
: RangesField
= decode_fields
.RA
129 print(f
"PO_FIELD={PO_FIELD}")
130 print(f
"RT_FIELD={RT_FIELD}")
131 print(f
"RA_FIELD={RA_FIELD}")
134 PRIMARY_OPCODE_SHIFT
= PO_FIELD
.endian_reversed(WORD_LENGTH
).start
135 # unofficial value. see https://libre-soc.org/openpower/sv/setvl/
136 # FIXME: incorrect extended opcode value
137 SETVL_OPCODE
= (19 << PRIMARY_OPCODE_SHIFT
) |
(0 << 1)
138 SETVL_IMMEDIATE_SHIFT
= 32 - 7 - 16
140 RT_SHIFT
= RT_FIELD
.endian_reversed(WORD_LENGTH
).start
141 RA_SHIFT
= RA_FIELD
.endian_reversed(WORD_LENGTH
).start
143 print(f
"RT_SHIFT={RT_SHIFT}")
144 print(f
"RA_SHIFT={RA_SHIFT}")
145 print(f
"PRIMARY_OPCODE_SHIFT={PRIMARY_OPCODE_SHIFT}")
148 def is_power_of_2(i
):
149 assert isinstance(i
, int)
150 return (i
& (i
- 1)) == 0 and i
!= 0
153 with
open("include/simplev_cpp_generated.h", mode
="w", encoding
="utf-8") as o
:
154 o
.write("""// SPDX-License-Identifier: LGPL-2.1-or-later
155 // See Notices.txt for copyright information
159 #include <type_traits>
162 #define SIMPLEV_USE_NONPOT_VECTORS
165 // #undef SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS
169 template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL, typename = void>
170 struct VecTypeStruct;
172 template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL>
173 using VecType = typename VecTypeStruct<ElementType, SUB_VL, MAX_VL>::Type;
175 #define SIMPLEV_MAKE_VEC_TYPE(size) \\
176 template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL> \\
177 struct VecTypeStruct<ElementType, \\
180 std::enable_if_t<sizeof(ElementType) * SUB_VL * MAX_VL == (size)>> \\
183 typedef ElementType Type __attribute__((vector_size(size))); \\
186 #ifdef SIMPLEV_USE_NONPOT_VECTORS
187 #define SIMPLEV_MAKE_VEC_TYPE_NONPOT(size) SIMPLEV_MAKE_VEC_TYPE(size)
189 #define SIMPLEV_MAKE_VEC_TYPE_NONPOT(size)
193 for i
in range(1, 128 + 1):
195 o
.write(f
"SIMPLEV_MAKE_VEC_TYPE({i})\n")
197 o
.write(f
"SIMPLEV_MAKE_VEC_TYPE_NONPOT({i})\n")
199 o
.write("#ifdef SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS\n")
200 o
.write(f
"""#endif // SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS
202 template <std::size_t MAX_VL>
205 static_assert(MAX_VL > 0 && MAX_VL <= 64);
209 template <std::size_t MAX_VL>
210 inline __attribute__((always_inline)) VL<MAX_VL> setvl(std::size_t vl)
214 "# setvl %[retval], %[vl], MVL=%[max_vl]\\n\\t"
215 ".long %[instr] | (%[retval] << %[rt_shift]) | (%[vl] << %[ra_shift])"
216 : [retval] "=b"(retval.value)
217 : [vl] "b"(vl), [max_vl] "n"(MAX_VL), [instr] "n"({FIXME___FINISH}));
222 #undef SIMPLEV_MAKE_VEC_TYPE
223 #undef SIMPLEV_MAKE_VEC_TYPE_NONPOT
224 #undef SIMPLEV_USE_NONPOT_VECTORS
225 #undef SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS