add code to iterate through list of svp64 instructions
authorJacob Lifshay <programmerjake@gmail.com>
Tue, 16 Mar 2021 03:13:20 +0000 (20:13 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Tue, 16 Mar 2021 03:13:20 +0000 (20:13 -0700)
generate_headers.py

index 633683c72e0552d7d581fdc4cbba53f1e3a6065d..0163c2fafbfa816b990333806e24ed063ad0a4e5 100755 (executable)
@@ -3,6 +3,7 @@
 # See Notices.txt for copyright information
 
 import sys
+from pprint import pprint
 from io import StringIO
 from typing import List
 from soc.decoder.pseudo.pagereader import ISA
@@ -140,23 +141,35 @@ def flatten(v):
         yield v
 
 
-def find_opcode(internal_op):
-    retval = None
-    for primary_subdecoder in decoder.dec:
-        for extended_subdecoder in flatten(primary_subdecoder.subdecoders):
-            for opcode in extended_subdecoder.opcodes:
-                if opcode['internal op'] == internal_op:
-                    if retval is not None:
-                        raise ValueError(f"internal_op={internal_op!r} "
-                                         "found more than once")
-                    retval = extended_subdecoder.pattern, \
-                        int(opcode['opcode'], base=0)
-    if retval is None:
-        raise ValueError(f"internal_op={internal_op!r} not found")
+def subdecoders():
+    def visit_subdecoders(subdecoders):
+        for subdecoder in flatten(subdecoders):
+            yield subdecoder
+            yield from visit_subdecoders(subdecoder.subdecoders)
+    yield from visit_subdecoders(decoder.dec)
+
+
+def make_opcodes_dict():
+    retval = {}
+    for subdecoder in subdecoders():
+        for opcode in subdecoder.opcodes:
+            opcode = dict(opcode)
+            opcode['subdecoder'] = subdecoder
+            comment = opcode['comment']
+            if comment not in retval:
+                retval[comment] = opcode
     return retval
 
 
-SETVL_PO, SETVL_XO = find_opcode("OP_SETVL")
+OPCODES_DICT = make_opcodes_dict()
+
+
+def find_opcode(comment):
+    opcode = OPCODES_DICT[comment]
+    return opcode['subdecoder'].pattern, int(opcode['opcode'], base=0)
+
+
+SETVL_PO, SETVL_XO = find_opcode("setvl")
 PO_FIELD: RangesField = decode_fields.PO
 RT_FIELD: RangesField = decode_fields.RT
 RA_FIELD: RangesField = decode_fields.RA
@@ -225,7 +238,7 @@ struct VecTypeStruct;
 template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL>
 using VecType = typename VecTypeStruct<ElementType, SUB_VL, MAX_VL>::Type;
 
-#define SIMPLEV_MAKE_VEC_TYPE(size)                                                         \\
+#define SIMPLEV_MAKE_VEC_TYPE(size, underlying_size)                                        \\
     template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL>                 \\
     struct VecTypeStruct<ElementType,                                                       \\
                          SUB_VL,                                                            \\
@@ -233,21 +246,37 @@ using VecType = typename VecTypeStruct<ElementType, SUB_VL, MAX_VL>::Type;
                          std::enable_if_t<sizeof(ElementType) * SUB_VL * MAX_VL == (size)>> \\
         final                                                                               \\
     {                                                                                       \\
-        typedef ElementType Type __attribute__((vector_size(size)));                        \\
+        typedef ElementType Type __attribute__((vector_size(underlying_size)));             \\
     };
 
+template <typename ElementType, std::size_t SUB_VL, std::size_t MAX_VL>
+struct Vec final
+{
+    static_assert(MAX_VL > 0 && MAX_VL <= 64);
+    static_assert(SUB_VL >= 1 && SUB_VL <= 4);
+    using Type = VecType<ElementType, SUB_VL, MAX_VL>;
+    Type value;
+};
+
+// power-of-2
+#define SIMPLEV_MAKE_VEC_TYPE_POT(size) SIMPLEV_MAKE_VEC_TYPE(size, size)
+
+// non-power-of-2
 #ifdef SIMPLEV_USE_NONPOT_VECTORS
-#define SIMPLEV_MAKE_VEC_TYPE_NONPOT(size) SIMPLEV_MAKE_VEC_TYPE(size)
+#define SIMPLEV_MAKE_VEC_TYPE_NONPOT(size, rounded_up_size) SIMPLEV_MAKE_VEC_TYPE(size)
 #else
-#define SIMPLEV_MAKE_VEC_TYPE_NONPOT(size)
+#define SIMPLEV_MAKE_VEC_TYPE_NONPOT(size, rounded_up_size) \\
+    SIMPLEV_MAKE_VEC_TYPE(size, rounded_up_size)
 #endif
 
 """)
-    for i in range(1, 128 + 1):
+    for i in range(64 * 4):
+        i += 1
         if is_power_of_2(i):
-            o.write(f"SIMPLEV_MAKE_VEC_TYPE({i})\n")
+            o.write(f"SIMPLEV_MAKE_VEC_TYPE_POT({i})\n")
         else:
-            o.write(f"SIMPLEV_MAKE_VEC_TYPE_NONPOT({i})\n")
+            rounded_up_size = 1 << i.bit_length()
+            o.write(f"SIMPLEV_MAKE_VEC_TYPE_NONPOT({i}, {rounded_up_size})\n")
         if i == 8:
             o.write("#ifdef SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS\n")
     o.write(f"""#endif // SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS
@@ -279,10 +308,32 @@ inline __attribute__((always_inline)) VL<MAX_VL> setvl(std::size_t vl)
         : "memory");
     return retval;
 }}
-}} // namespace sv
+""")
+    for opcode in {i: None for i in svp64rm.instrs}:
+        try:
+            instr = OPCODES_DICT[opcode]
+        except KeyError as e:
+            print(repr(e), file=sys.stderr)
+            o.write(f"\n// skipped invalid opcode: {opcode!r}\n")
+            continue
+        o.write(f"\n/// {opcode}\n")
+        function_name = "sv_" + opcode.split('/')[0].replace('.', '_')
+        SV_Ptype = instr['SV_Ptype']
+        if SV_Ptype == 'P2':
+            pass
+            # TODO
+        else:
+            assert SV_Ptype == 'P1'
+            # TODO
+        o.write(f"""/// (not yet implemented)
+template <typename... Args>
+void {function_name}(Args &&...) = delete;
+""")
+    o.write(f"""}} // namespace sv
 
 #undef SIMPLEV_MAKE_VEC_TYPE
 #undef SIMPLEV_MAKE_VEC_TYPE_NONPOT
+#undef SIMPLEV_MAKE_VEC_TYPE_POT
 #undef SIMPLEV_USE_NONPOT_VECTORS
 #undef SIMPLEV_USE_BIGGER_THAN_8_BYTE_VECTORS
 """)