2 # SPDX-License-Identifier: LGPL-2.1-or-later
3 # See Notices.txt for copyright information
6 from io
import StringIO
7 from typing
import List
8 from soc
.decoder
.pseudo
.pagereader
import ISA
9 from soc
.decoder
.power_svp64
import SVP64RM
10 from soc
.decoder
.power_fields
import DecodeFields
11 from soc
.decoder
.power_decoder
import create_pdecode
15 __slots__
= "start", "stop"
17 def __init__(self
, start
, stop
=None):
23 def __len__(self
) -> int:
27 def width(self
) -> int:
28 return self
.stop
- self
.start
+ 1
31 if self
.start
== self
.stop
:
32 return f
"InclusiveRange({self.start})"
33 return f
"InclusiveRange({self.start}, {self.stop})"
36 if self
.start
== self
.stop
:
37 return f
"{self.start}"
38 return f
"{self.start}:{self.stop}"
41 if v
== self
.stop
+ 1:
46 def endian_reversed(self
, word_length
) -> "InclusiveRange":
47 # note reversed stop/start
48 return InclusiveRange(word_length
- 1 - self
.stop
,
49 word_length
- 1 - self
.start
)
54 ranges
: List
[InclusiveRange
]
56 def __init__(self
, ranges
=None):
59 if isinstance(ranges
, InclusiveRange
):
70 if len(self
.ranges
) == 0:
71 return "RangesField()"
72 if len(self
.ranges
) == 1:
73 return f
"RangesField({self.ranges[0]})"
74 return f
"RangesField({self.ranges})"
77 if len(self
.ranges
) == 0:
79 return ",".join(map(str, self
.ranges
))
81 def __setitem__(self
, key
, value
):
82 assert isinstance(key
, int)
83 assert isinstance(value
, int)
84 assert key
== len(self
)
86 self
.ranges
[-1].append(value
)
92 self
.ranges
.append(InclusiveRange(value
))
94 def endian_reversed(self
, word_length
) -> "RangesField":
95 return RangesField([i
.endian_reversed(word_length
)
96 for i
in reversed(self
.ranges
)])
99 def contiguous(self
) -> bool:
100 return len(self
.ranges
) == 1
103 def start(self
) -> int:
104 assert self
.contiguous
105 return self
.ranges
[0].start
108 def stop(self
) -> int:
109 assert self
.contiguous
110 return self
.ranges
[0].stop
113 def width(self
) -> int:
114 assert self
.contiguous
115 return self
.ranges
[0].width
119 # shut-up excessive printing
120 old_stdout
= sys
.stdout
121 new_stdout
= StringIO()
122 sys
.stdout
= new_stdout
125 decode_fields
= DecodeFields(bitkls
=RangesField
)
126 decode_fields
.create_specs()
127 decoder
= create_pdecode()
128 sys
.stdout
= old_stdout
130 sys
.stdout
= old_stdout
131 print(new_stdout
.getvalue())
136 if isinstance(v
, list):
138 yield from flatten(i
)
143 def find_opcode(internal_op
):
145 for primary_subdecoder
in decoder
.dec
:
146 for extended_subdecoder
in flatten(primary_subdecoder
.subdecoders
):
147 for opcode
in extended_subdecoder
.opcodes
:
148 if opcode
['internal op'] == internal_op
:
149 if retval
is not None:
150 raise ValueError(f
"internal_op={internal_op!r} "
151 "found more than once")
152 retval
= extended_subdecoder
.pattern
, \
153 int(opcode
['opcode'], base
=0)
155 raise ValueError(f
"internal_op={internal_op!r} not found")
159 SETVL_PO
, SETVL_XO
= find_opcode("OP_SETVL")
160 PO_FIELD
: RangesField
= decode_fields
.PO
161 RT_FIELD
: RangesField
= decode_fields
.RT
162 RA_FIELD
: RangesField
= decode_fields
.RA
163 SVL_SVi_FIELD
: RangesField
= decode_fields
.FormSVL
.SVi
164 SVL_vs_FIELD
: RangesField
= decode_fields
.FormSVL
.vs
165 SVL_ms_FIELD
: RangesField
= decode_fields
.FormSVL
.ms
166 SVL_XO_FIELD
: RangesField
= decode_fields
.FormSVL
.XO
167 SVL_Rc_FIELD
: RangesField
= decode_fields
.FormSVL
.Rc
168 print(f
"SETVL_PO={SETVL_PO}")
169 print(f
"SETVL_XO={SETVL_XO}")
170 print(f
"PO_FIELD={PO_FIELD}")
171 print(f
"RT_FIELD={RT_FIELD}")
172 print(f
"RA_FIELD={RA_FIELD}")
173 print(f
"SVL_SVi_FIELD={SVL_SVi_FIELD}")
174 print(f
"SVL_vs_FIELD={SVL_vs_FIELD}")
175 print(f
"SVL_ms_FIELD={SVL_ms_FIELD}")
176 print(f
"SVL_XO_FIELD={SVL_XO_FIELD}")
177 print(f
"SVL_Rc_FIELD={SVL_Rc_FIELD}")
180 PO_SHIFT
= PO_FIELD
.endian_reversed(WORD_LENGTH
).start
181 RT_SHIFT
= RT_FIELD
.endian_reversed(WORD_LENGTH
).start
182 RA_SHIFT
= RA_FIELD
.endian_reversed(WORD_LENGTH
).start
183 SVL_SVi_SHIFT
= SVL_SVi_FIELD
.endian_reversed(WORD_LENGTH
).start
184 SVL_vs_SHIFT
= SVL_vs_FIELD
.endian_reversed(WORD_LENGTH
).start
185 SVL_ms_SHIFT
= SVL_ms_FIELD
.endian_reversed(WORD_LENGTH
).start
186 SVL_XO_SHIFT
= SVL_XO_FIELD
.endian_reversed(WORD_LENGTH
).start
187 SVL_Rc_SHIFT
= SVL_Rc_FIELD
.endian_reversed(WORD_LENGTH
).start
189 print(f
"RT_SHIFT={RT_SHIFT}")
190 print(f
"RA_SHIFT={RA_SHIFT}")
191 print(f
"PO_SHIFT={PO_SHIFT}")
192 print(f
"SVL_SVi_SHIFT={SVL_SVi_SHIFT}")
193 print(f
"SVL_vs_SHIFT={SVL_vs_SHIFT}")
194 print(f
"SVL_ms_SHIFT={SVL_ms_SHIFT}")
195 print(f
"SVL_XO_SHIFT={SVL_XO_SHIFT}")
196 print(f
"SVL_Rc_SHIFT={SVL_Rc_SHIFT}")
199 def is_power_of_2(i
):
200 assert isinstance(i
, int)
201 return (i
& (i
- 1)) == 0 and i
!= 0
204 with
open("include/simplev_cpp_generated.h", mode
="w", encoding
="utf-8") as o
:
205 o
.write("""// SPDX-License-Identifier: LGPL-2.1-or-later
206 // See Notices.txt for copyright information
207 // This file is automatically generated by generate_headers.py,
208 // do not edit by hand
212 #include <type_traits>
215 #define SIMPLEV_USE_NONPOT_VECTORS
218 // #undef SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS
222 template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL, typename = void>
223 struct VecTypeStruct;
225 template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL>
226 using VecType = typename VecTypeStruct<ElementType, SUB_VL, MAX_VL>::Type;
228 #define SIMPLEV_MAKE_VEC_TYPE(size) \\
229 template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL> \\
230 struct VecTypeStruct<ElementType, \\
233 std::enable_if_t<sizeof(ElementType) * SUB_VL * MAX_VL == (size)>> \\
236 typedef ElementType Type __attribute__((vector_size(size))); \\
239 #ifdef SIMPLEV_USE_NONPOT_VECTORS
240 #define SIMPLEV_MAKE_VEC_TYPE_NONPOT(size) SIMPLEV_MAKE_VEC_TYPE(size)
242 #define SIMPLEV_MAKE_VEC_TYPE_NONPOT(size)
246 for i
in range(1, 128 + 1):
248 o
.write(f
"SIMPLEV_MAKE_VEC_TYPE({i})\n")
250 o
.write(f
"SIMPLEV_MAKE_VEC_TYPE_NONPOT({i})\n")
252 o
.write("#ifdef SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS\n")
253 o
.write(f
"""#endif // SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS
255 template <std::size_t MAX_VL>
258 static_assert(MAX_VL > 0 && MAX_VL <= 64);
262 template <std::size_t MAX_VL>
263 inline __attribute__((always_inline)) VL<MAX_VL> setvl(std::size_t vl)
267 "# setvl %[retval], %[vl], MVL=%[max_vl]\\n\\t"
268 ".long %[instr] | (%[retval] << %[rt_shift]) | (%[vl] << %[ra_shift])"
269 : [retval] "=b"(retval.value)
271 [max_vl] "n"(MAX_VL),
272 [instr] "n"(((MAX_VL - 1) << {SVL_SVi_SHIFT}) | {hex(
274 | (1 << SVL_ms_SHIFT)
275 | (SETVL_XO << SVL_XO_SHIFT)
276 | (SETVL_PO << PO_SHIFT))}),
277 [rt_shift] "n"({RT_SHIFT}),
278 [ra_shift] "n"({RA_SHIFT})
284 #undef SIMPLEV_MAKE_VEC_TYPE
285 #undef SIMPLEV_MAKE_VEC_TYPE_NONPOT
286 #undef SIMPLEV_USE_NONPOT_VECTORS
287 #undef SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS