summaryrefslogtreecommitdiff
path: root/tools/mpy-tool.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/mpy-tool.py')
-rwxr-xr-xtools/mpy-tool.py37
1 files changed, 34 insertions, 3 deletions
diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py
index df918e153..c68f17913 100755
--- a/tools/mpy-tool.py
+++ b/tools/mpy-tool.py
@@ -120,6 +120,8 @@ MP_BC_FORMAT_QSTR = 1
MP_BC_FORMAT_VAR_UINT = 2
MP_BC_FORMAT_OFFSET = 3
+MP_NATIVE_ARCH_FLAGS_PRESENT = 0x40
+
mp_unary_op_method_name = (
"__pos__",
"__neg__",
@@ -542,6 +544,7 @@ class CompiledModule:
mpy_source_file,
mpy_segments,
header,
+ arch_flags,
qstr_table,
obj_table,
raw_code,
@@ -554,6 +557,7 @@ class CompiledModule:
self.mpy_segments = mpy_segments
self.source_file = qstr_table[0]
self.header = header
+ self.arch_flags = arch_flags
self.qstr_table = qstr_table
self.obj_table = obj_table
self.raw_code = raw_code
@@ -1339,7 +1343,7 @@ def read_mpy(filename):
if header[1] != config.MPY_VERSION:
raise MPYReadError(filename, "incompatible .mpy version")
feature_byte = header[2]
- mpy_native_arch = feature_byte >> 2
+ mpy_native_arch = (feature_byte >> 2) & 0x2F
if mpy_native_arch != MP_NATIVE_ARCH_NONE:
mpy_sub_version = feature_byte & 3
if mpy_sub_version != config.MPY_SUB_VERSION:
@@ -1350,6 +1354,11 @@ def read_mpy(filename):
raise MPYReadError(filename, "native architecture mismatch")
config.mp_small_int_bits = header[3]
+ arch_flags = 0
+ # Read the architecture-specific flag bits if present.
+ if (feature_byte & MP_NATIVE_ARCH_FLAGS_PRESENT) != 0:
+ arch_flags = reader.read_uint()
+
# Read number of qstrs, and number of objects.
n_qstr = reader.read_uint()
n_obj = reader.read_uint()
@@ -1378,6 +1387,7 @@ def read_mpy(filename):
filename,
segments,
header,
+ arch_flags,
qstr_table,
obj_table,
raw_code,
@@ -1673,25 +1683,39 @@ def merge_mpy(compiled_modules, output_file):
merged_mpy.extend(f.read())
else:
main_cm_idx = None
+ arch_flags = 0
for idx, cm in enumerate(compiled_modules):
feature_byte = cm.header[2]
- mpy_native_arch = feature_byte >> 2
+ mpy_native_arch = (feature_byte >> 2) & 0x2F
if mpy_native_arch:
# Must use qstr_table and obj_table from this raw_code
if main_cm_idx is not None:
raise Exception("can't merge files when more than one contains native code")
main_cm_idx = idx
+ arch_flags = cm.arch_flags
if main_cm_idx is not None:
# Shift main_cm to front of list.
compiled_modules.insert(0, compiled_modules.pop(main_cm_idx))
+ if config.arch_flags is not None:
+ arch_flags = config.arch_flags
+
header = bytearray(4)
header[0] = ord("M")
header[1] = config.MPY_VERSION
- header[2] = config.native_arch << 2 | config.MPY_SUB_VERSION if config.native_arch else 0
+ header[2] = (
+ (MP_NATIVE_ARCH_FLAGS_PRESENT if arch_flags != 0 else 0)
+ | config.native_arch << 2
+ | config.MPY_SUB_VERSION
+ if config.native_arch
+ else 0
+ )
header[3] = config.mp_small_int_bits
merged_mpy.extend(header)
+ if arch_flags != 0:
+ merged_mpy.extend(mp_encode_uint(arch_flags))
+
n_qstr = 0
n_obj = 0
for cm in compiled_modules:
@@ -1823,6 +1847,12 @@ def main(args=None):
default=16,
help="mpz digit size used by target (default 16)",
)
+ cmd_parser.add_argument(
+ "-march-flags",
+ metavar="F",
+ type=int,
+ help="architecture flags value to set in the output file (strips existing flags if not present)",
+ )
cmd_parser.add_argument("-o", "--output", default=None, help="output file")
cmd_parser.add_argument("files", nargs="+", help="input .mpy files")
args = cmd_parser.parse_args(args)
@@ -1835,6 +1865,7 @@ def main(args=None):
}[args.mlongint_impl]
config.MPZ_DIG_SIZE = args.mmpz_dig_size
config.native_arch = MP_NATIVE_ARCH_NONE
+ config.arch_flags = args.march_flags
# set config values for qstrs, and get the existing base set of qstrs
# already in the firmware