2 # SPDX-License-Identifier: LGPL-2.1-or-later
3 # See Notices.txt for copyright information
6 from pprint
import pprint
7 from io
import StringIO
8 from typing
import List
9 from soc
.decoder
.pseudo
.pagereader
import ISA
10 from soc
.decoder
.power_svp64
import SVP64RM
11 from soc
.decoder
.power_fields
import DecodeFields
12 from soc
.decoder
.power_decoder
import create_pdecode
16 __slots__
= "start", "stop"
18 def __init__(self
, start
, stop
=None):
24 def __len__(self
) -> int:
28 def width(self
) -> int:
29 return self
.stop
- self
.start
+ 1
32 if self
.start
== self
.stop
:
33 return f
"InclusiveRange({self.start})"
34 return f
"InclusiveRange({self.start}, {self.stop})"
37 if self
.start
== self
.stop
:
38 return f
"{self.start}"
39 return f
"{self.start}:{self.stop}"
42 if v
== self
.stop
+ 1:
47 def endian_reversed(self
, word_length
) -> "InclusiveRange":
48 # note reversed stop/start
49 return InclusiveRange(word_length
- 1 - self
.stop
,
50 word_length
- 1 - self
.start
)
55 ranges
: List
[InclusiveRange
]
57 def __init__(self
, ranges
=None):
60 if isinstance(ranges
, InclusiveRange
):
71 if len(self
.ranges
) == 0:
72 return "RangesField()"
73 if len(self
.ranges
) == 1:
74 return f
"RangesField({self.ranges[0]})"
75 return f
"RangesField({self.ranges})"
78 if len(self
.ranges
) == 0:
80 return ",".join(map(str, self
.ranges
))
82 def __setitem__(self
, key
, value
):
83 assert isinstance(key
, int)
84 assert isinstance(value
, int)
85 assert key
== len(self
)
87 self
.ranges
[-1].append(value
)
93 self
.ranges
.append(InclusiveRange(value
))
95 def endian_reversed(self
, word_length
) -> "RangesField":
96 return RangesField([i
.endian_reversed(word_length
)
97 for i
in reversed(self
.ranges
)])
100 def contiguous(self
) -> bool:
101 return len(self
.ranges
) == 1
104 def start(self
) -> int:
105 assert self
.contiguous
106 return self
.ranges
[0].start
109 def stop(self
) -> int:
110 assert self
.contiguous
111 return self
.ranges
[0].stop
114 def width(self
) -> int:
115 assert self
.contiguous
116 return self
.ranges
[0].width
120 # shut-up excessive printing
121 old_stdout
= sys
.stdout
122 new_stdout
= StringIO()
123 sys
.stdout
= new_stdout
126 decode_fields
= DecodeFields(bitkls
=RangesField
)
127 decode_fields
.create_specs()
128 decoder
= create_pdecode()
129 sys
.stdout
= old_stdout
131 sys
.stdout
= old_stdout
132 print(new_stdout
.getvalue())
137 if isinstance(v
, list):
139 yield from flatten(i
)
145 def visit_subdecoders(subdecoders
):
146 for subdecoder
in flatten(subdecoders
):
148 yield from visit_subdecoders(subdecoder
.subdecoders
)
149 yield from visit_subdecoders(decoder
.dec
)
152 def make_opcodes_dict():
154 for subdecoder
in subdecoders():
155 for opcode
in subdecoder
.opcodes
:
156 opcode
= dict(opcode
)
157 opcode
['subdecoder'] = subdecoder
158 comment
= opcode
['comment']
159 if comment
not in retval
:
160 retval
[comment
] = opcode
164 OPCODES_DICT
= make_opcodes_dict()
167 def find_opcode(comment
):
168 opcode
= OPCODES_DICT
[comment
]
169 return opcode
['subdecoder'].pattern
, int(opcode
['opcode'], base
=0)
172 SETVL_PO
, SETVL_XO
= find_opcode("setvl")
173 PO_FIELD
: RangesField
= decode_fields
.PO
174 RT_FIELD
: RangesField
= decode_fields
.RT
175 RA_FIELD
: RangesField
= decode_fields
.RA
176 SVL_SVi_FIELD
: RangesField
= decode_fields
.FormSVL
.SVi
177 SVL_vs_FIELD
: RangesField
= decode_fields
.FormSVL
.vs
178 SVL_ms_FIELD
: RangesField
= decode_fields
.FormSVL
.ms
179 SVL_XO_FIELD
: RangesField
= decode_fields
.FormSVL
.XO
180 SVL_Rc_FIELD
: RangesField
= decode_fields
.FormSVL
.Rc
181 print(f
"SETVL_PO={SETVL_PO}")
182 print(f
"SETVL_XO={SETVL_XO}")
183 print(f
"PO_FIELD={PO_FIELD}")
184 print(f
"RT_FIELD={RT_FIELD}")
185 print(f
"RA_FIELD={RA_FIELD}")
186 print(f
"SVL_SVi_FIELD={SVL_SVi_FIELD}")
187 print(f
"SVL_vs_FIELD={SVL_vs_FIELD}")
188 print(f
"SVL_ms_FIELD={SVL_ms_FIELD}")
189 print(f
"SVL_XO_FIELD={SVL_XO_FIELD}")
190 print(f
"SVL_Rc_FIELD={SVL_Rc_FIELD}")
193 PO_SHIFT
= PO_FIELD
.endian_reversed(WORD_LENGTH
).start
194 RT_SHIFT
= RT_FIELD
.endian_reversed(WORD_LENGTH
).start
195 RA_SHIFT
= RA_FIELD
.endian_reversed(WORD_LENGTH
).start
196 SVL_SVi_SHIFT
= SVL_SVi_FIELD
.endian_reversed(WORD_LENGTH
).start
197 SVL_vs_SHIFT
= SVL_vs_FIELD
.endian_reversed(WORD_LENGTH
).start
198 SVL_ms_SHIFT
= SVL_ms_FIELD
.endian_reversed(WORD_LENGTH
).start
199 SVL_XO_SHIFT
= SVL_XO_FIELD
.endian_reversed(WORD_LENGTH
).start
200 SVL_Rc_SHIFT
= SVL_Rc_FIELD
.endian_reversed(WORD_LENGTH
).start
202 print(f
"RT_SHIFT={RT_SHIFT}")
203 print(f
"RA_SHIFT={RA_SHIFT}")
204 print(f
"PO_SHIFT={PO_SHIFT}")
205 print(f
"SVL_SVi_SHIFT={SVL_SVi_SHIFT}")
206 print(f
"SVL_vs_SHIFT={SVL_vs_SHIFT}")
207 print(f
"SVL_ms_SHIFT={SVL_ms_SHIFT}")
208 print(f
"SVL_XO_SHIFT={SVL_XO_SHIFT}")
209 print(f
"SVL_Rc_SHIFT={SVL_Rc_SHIFT}")
212 def is_power_of_2(i
):
213 assert isinstance(i
, int)
214 return (i
& (i
- 1)) == 0 and i
!= 0
217 with
open("include/simplev_cpp_generated.h", mode
="w", encoding
="utf-8") as o
:
218 o
.write("""// SPDX-License-Identifier: LGPL-2.1-or-later
219 // See Notices.txt for copyright information
220 // This file is automatically generated by generate_headers.py,
221 // do not edit by hand
225 #include <type_traits>
228 #define SIMPLEV_USE_NONPOT_VECTORS
231 // #undef SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS
235 template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL, typename = void>
236 struct VecTypeStruct;
238 template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL>
239 using VecType = typename VecTypeStruct<ElementType, SUB_VL, MAX_VL>::Type;
241 #define SIMPLEV_MAKE_VEC_TYPE(size, underlying_size) \\
242 template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL> \\
243 struct VecTypeStruct<ElementType, \\
246 std::enable_if_t<sizeof(ElementType) * SUB_VL * MAX_VL == (size)>> \\
249 typedef ElementType Type __attribute__((vector_size(underlying_size))); \\
252 template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL>
255 static_assert(MAX_VL > 0 && MAX_VL <= 64);
256 static_assert(SUB_VL >= 1 && SUB_VL <= 4);
257 using Type = VecType<ElementType, SUB_VL, MAX_VL>;
262 #define SIMPLEV_MAKE_VEC_TYPE_POT(size) SIMPLEV_MAKE_VEC_TYPE(size, size)
265 #ifdef SIMPLEV_USE_NONPOT_VECTORS
266 #define SIMPLEV_MAKE_VEC_TYPE_NONPOT(size, rounded_up_size) SIMPLEV_MAKE_VEC_TYPE(size)
268 #define SIMPLEV_MAKE_VEC_TYPE_NONPOT(size, rounded_up_size) \\
269 SIMPLEV_MAKE_VEC_TYPE(size, rounded_up_size)
273 for i
in range(64 * 4):
276 o
.write(f
"SIMPLEV_MAKE_VEC_TYPE_POT({i})\n")
278 rounded_up_size
= 1 << i
.bit_length()
279 o
.write(f
"SIMPLEV_MAKE_VEC_TYPE_NONPOT({i}, {rounded_up_size})\n")
281 o
.write("#ifdef SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS\n")
282 o
.write(f
"""#endif // SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS
284 template <std::size_t MAX_VL>
287 static_assert(MAX_VL > 0 && MAX_VL <= 64);
291 template <std::size_t MAX_VL>
292 inline __attribute__((always_inline)) VL<MAX_VL> setvl(std::size_t vl)
296 "# setvl %[retval], %[vl], MVL=%[max_vl]\\n\\t"
297 ".long %[instr] | (%[retval] << %[rt_shift]) | (%[vl] << %[ra_shift])"
298 : [retval] "=b"(retval.value)
300 [max_vl] "n"(MAX_VL),
301 [instr] "n"(((MAX_VL - 1) << {SVL_SVi_SHIFT}) | {hex(
303 | (1 << SVL_ms_SHIFT)
304 | (SETVL_XO << SVL_XO_SHIFT)
305 | (SETVL_PO << PO_SHIFT))}),
306 [rt_shift] "n"({RT_SHIFT}),
307 [ra_shift] "n"({RA_SHIFT})
312 for opcode
in {i
: None for i
in svp64rm
.instrs
}:
314 instr
= OPCODES_DICT
[opcode
]
315 except KeyError as e
:
316 print(repr(e
), file=sys
.stderr
)
317 o
.write(f
"\n// skipped invalid opcode: {opcode!r}\n")
319 o
.write(f
"\n/// {opcode}\n")
320 function_name
= "sv_" + opcode
.split('/')[0].replace('.', '_')
321 SV_Ptype
= instr
['SV_Ptype']
326 assert SV_Ptype
== 'P1'
328 o
.write(f
"""/// (not yet implemented)
329 template <typename... Args>
330 void {function_name}(Args &&...) = delete;
332 o
.write(f
"""}} // namespace sv
334 #undef SIMPLEV_MAKE_VEC_TYPE
335 #undef SIMPLEV_MAKE_VEC_TYPE_NONPOT
336 #undef SIMPLEV_MAKE_VEC_TYPE_POT
337 #undef SIMPLEV_USE_NONPOT_VECTORS
338 #undef SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS