92 lines
2.5 KiB
Python
92 lines
2.5 KiB
Python
#
|
|
# Copyright (C) 2016 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
|
|
# Common global variables and helper methods for the in-memory python script.
|
|
# The script starts with this file and is followed by the code generated form
|
|
# the templated snippets. Those define all the helper functions used below.
|
|
|
|
import sys, re
|
|
from io import StringIO
|
|
|
|
out = StringIO() # File-like in-memory buffer.
|
|
handler_size_bytes = "NTERP_HANDLER_SIZE"
|
|
handler_size_bits = "NTERP_HANDLER_SIZE_LOG2"
|
|
opcode = ""
|
|
opnum = ""
|
|
|
|
def write_line(line):
|
|
out.write(line + "\n")
|
|
|
|
def balign():
|
|
write_line(" .balign {}".format(handler_size_bytes))
|
|
|
|
def write_opcode(num, name, write_method):
|
|
global opnum, opcode
|
|
opnum, opcode = str(num), name
|
|
write_line("/* ------------------------------ */")
|
|
balign()
|
|
write_line(".L_{1}: /* {0:#04x} */".format(num, name))
|
|
opcode_start()
|
|
opcode_pre()
|
|
write_method()
|
|
opcode_end()
|
|
write_line("")
|
|
opnum, opcode = None, None
|
|
|
|
slow_paths = {}
|
|
|
|
# This method generates a slow path using the provided writer method and arguments.
|
|
def add_slow_path(write_fn, *write_args, suffix="_slow_path"):
|
|
name = opcode_name_prefix() + (opcode or "common") + suffix
|
|
global out
|
|
# The output is temporarily redirected to in-memory buffer.
|
|
old_out = out
|
|
out = StringIO()
|
|
opcode_slow_path_start(name)
|
|
write_fn(*write_args)
|
|
opcode_slow_path_end(name)
|
|
out.seek(0)
|
|
code = out.read()
|
|
if name in slow_paths:
|
|
assert slow_paths[name] == code, "Non-matching redefinition of " + name
|
|
slow_paths[name] = code
|
|
out = old_out
|
|
return name
|
|
|
|
def generate(output_filename):
|
|
out.seek(0)
|
|
out.truncate()
|
|
write_line("/* DO NOT EDIT: This file was generated by gen-mterp.py. */")
|
|
header()
|
|
entry()
|
|
|
|
instruction_start()
|
|
opcodes()
|
|
balign()
|
|
instruction_end()
|
|
|
|
for name, slow_path in sorted(slow_paths.items()):
|
|
out.write(slow_path)
|
|
|
|
footer()
|
|
|
|
out.seek(0)
|
|
# Squash consequtive empty lines.
|
|
text = re.sub(r"(\n\n)(\n)+", r"\1", out.read())
|
|
with open(output_filename, 'w') as output_file:
|
|
output_file.write(text)
|
|
|