1# 2# Copyright (C) 2016 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16 17# Common global variables and helper methods for the in-memory python script. 18# The script starts with this file and is followed by the code generated form 19# the templated snippets. Those define all the helper functions used below. 20 21import sys, re 22from io import StringIO 23 24out = StringIO() # File-like in-memory buffer. 25handler_size_bytes = "NTERP_HANDLER_SIZE" 26handler_size_bits = "NTERP_HANDLER_SIZE_LOG2" 27opcode = "" 28opnum = "" 29 30def write_line(line): 31 out.write(line + "\n") 32 33def balign(): 34 write_line(" .balign {}".format(handler_size_bytes)) 35 36def write_opcode(num, name, write_method): 37 global opnum, opcode 38 opnum, opcode = str(num), name 39 write_line("/* ------------------------------ */") 40 balign() 41 write_line(".L_{1}: /* {0:#04x} */".format(num, name)) 42 opcode_start() 43 opcode_pre() 44 write_method() 45 opcode_end() 46 write_line("") 47 opnum, opcode = None, None 48 49slow_paths = {} 50 51# This method generates a slow path using the provided writer method and arguments. 52def add_slow_path(write_fn, *write_args, suffix="_slow_path"): 53 name = opcode_name_prefix() + (opcode or "common") + suffix 54 global out 55 # The output is temporarily redirected to in-memory buffer. 56 old_out = out 57 out = StringIO() 58 opcode_slow_path_start(name) 59 write_fn(*write_args) 60 opcode_slow_path_end(name) 61 out.seek(0) 62 code = out.read() 63 if name in slow_paths: 64 assert slow_paths[name] == code, "Non-matching redefinition of " + name 65 slow_paths[name] = code 66 out = old_out 67 return name 68 69def generate(output_filename): 70 out.seek(0) 71 out.truncate() 72 write_line("/* DO NOT EDIT: This file was generated by gen-mterp.py. */") 73 header() 74 entry() 75 76 instruction_start() 77 opcodes() 78 balign() 79 instruction_end() 80 81 for name, slow_path in sorted(slow_paths.items()): 82 out.write(slow_path) 83 84 footer() 85 86 out.seek(0) 87 # Squash consequtive empty lines. 88 text = re.sub(r"(\n\n)(\n)+", r"\1", out.read()) 89 with open(output_filename, 'w') as output_file: 90 output_file.write(text) 91 92