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