xref: /aosp_15_r20/art/runtime/interpreter/mterp/common/gen_setup.py (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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