summaryrefslogtreecommitdiffstats
path: root/Tools/cases_generator/tier2_generator.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/cases_generator/tier2_generator.py')
-rw-r--r--Tools/cases_generator/tier2_generator.py197
1 files changed, 96 insertions, 101 deletions
diff --git a/Tools/cases_generator/tier2_generator.py b/Tools/cases_generator/tier2_generator.py
index 18bab2c..8c212f7 100644
--- a/Tools/cases_generator/tier2_generator.py
+++ b/Tools/cases_generator/tier2_generator.py
@@ -16,11 +16,10 @@ from analyzer import (
from generators_common import (
DEFAULT_INPUT,
ROOT,
- write_header,
- emit_tokens,
emit_to,
- REPLACEMENT_FUNCTIONS,
+ write_header,
type_and_null,
+ Emitter
)
from cwriter import CWriter
from typing import TextIO, Iterator
@@ -61,117 +60,112 @@ def declare_variables(uop: Uop, out: CWriter) -> None:
for var in uop.stack.outputs:
declare_variable(var, uop, required, out)
-def tier2_replace_error(
- out: CWriter,
- tkn: Token,
- tkn_iter: Iterator[Token],
- uop: Uop,
- stack: Stack,
- inst: Instruction | None,
-) -> None:
- out.emit_at("if ", tkn)
- out.emit(next(tkn_iter))
- emit_to(out, tkn_iter, "COMMA")
- label = next(tkn_iter).text
- next(tkn_iter) # RPAREN
- next(tkn_iter) # Semi colon
- out.emit(") JUMP_TO_ERROR();\n")
+class Tier2Emitter(Emitter):
-def tier2_replace_error_no_pop(
- out: CWriter,
- tkn: Token,
- tkn_iter: Iterator[Token],
- uop: Uop,
- stack: Stack,
- inst: Instruction | None,
-) -> None:
- next(tkn_iter) # LPAREN
- next(tkn_iter) # RPAREN
- next(tkn_iter) # Semi colon
- out.emit_at("JUMP_TO_ERROR();", tkn)
+ def __init__(self, out: CWriter):
+ super().__init__(out)
+ self._replacers["oparg"] = self.oparg
-def tier2_replace_deopt(
- out: CWriter,
- tkn: Token,
- tkn_iter: Iterator[Token],
- uop: Uop,
- unused: Stack,
- inst: Instruction | None,
-) -> None:
- out.emit_at("if ", tkn)
- out.emit(next(tkn_iter))
- emit_to(out, tkn_iter, "RPAREN")
- next(tkn_iter) # Semi colon
- out.emit(") {\n")
- out.emit("UOP_STAT_INC(uopcode, miss);\n")
- out.emit("JUMP_TO_JUMP_TARGET();\n");
- out.emit("}\n")
+ def error_if(
+ self,
+ tkn: Token,
+ tkn_iter: Iterator[Token],
+ uop: Uop,
+ stack: Stack,
+ inst: Instruction | None,
+ ) -> None:
+ self.out.emit_at("if ", tkn)
+ self.emit(next(tkn_iter))
+ emit_to(self.out, tkn_iter, "COMMA")
+ label = next(tkn_iter).text
+ next(tkn_iter) # RPAREN
+ next(tkn_iter) # Semi colon
+ self.emit(") JUMP_TO_ERROR();\n")
+ def error_no_pop(
+ self,
+ tkn: Token,
+ tkn_iter: Iterator[Token],
+ uop: Uop,
+ stack: Stack,
+ inst: Instruction | None,
+ ) -> None:
+ next(tkn_iter) # LPAREN
+ next(tkn_iter) # RPAREN
+ next(tkn_iter) # Semi colon
+ self.out.emit_at("JUMP_TO_ERROR();", tkn)
-def tier2_replace_exit_if(
- out: CWriter,
- tkn: Token,
- tkn_iter: Iterator[Token],
- uop: Uop,
- unused: Stack,
- inst: Instruction | None,
-) -> None:
- out.emit_at("if ", tkn)
- out.emit(next(tkn_iter))
- emit_to(out, tkn_iter, "RPAREN")
- next(tkn_iter) # Semi colon
- out.emit(") {\n")
- out.emit("UOP_STAT_INC(uopcode, miss);\n")
- out.emit("JUMP_TO_JUMP_TARGET();\n")
- out.emit("}\n")
+ def deopt_if(
+ self,
+ tkn: Token,
+ tkn_iter: Iterator[Token],
+ uop: Uop,
+ unused: Stack,
+ inst: Instruction | None,
+ ) -> None:
+ self.out.emit_at("if ", tkn)
+ self.emit(next(tkn_iter))
+ emit_to(self.out, tkn_iter, "RPAREN")
+ next(tkn_iter) # Semi colon
+ self.emit(") {\n")
+ self.emit("UOP_STAT_INC(uopcode, miss);\n")
+ self.emit("JUMP_TO_JUMP_TARGET();\n");
+ self.emit("}\n")
+ def exit_if( # type: ignore[override]
+ self,
+ tkn: Token,
+ tkn_iter: Iterator[Token],
+ uop: Uop,
+ unused: Stack,
+ inst: Instruction | None,
+ ) -> None:
+ self.out.emit_at("if ", tkn)
+ self.emit(next(tkn_iter))
+ emit_to(self.out, tkn_iter, "RPAREN")
+ next(tkn_iter) # Semi colon
+ self.emit(") {\n")
+ self.emit("UOP_STAT_INC(uopcode, miss);\n")
+ self.emit("JUMP_TO_JUMP_TARGET();\n")
+ self.emit("}\n")
-def tier2_replace_oparg(
- out: CWriter,
- tkn: Token,
- tkn_iter: Iterator[Token],
- uop: Uop,
- unused: Stack,
- inst: Instruction | None,
-) -> None:
- if not uop.name.endswith("_0") and not uop.name.endswith("_1"):
- out.emit(tkn)
- return
- amp = next(tkn_iter)
- if amp.text != "&":
- out.emit(tkn)
- out.emit(amp)
- return
- one = next(tkn_iter)
- assert one.text == "1"
- out.emit_at(uop.name[-1], tkn)
-
+ def oparg(
+ self,
+ tkn: Token,
+ tkn_iter: Iterator[Token],
+ uop: Uop,
+ unused: Stack,
+ inst: Instruction | None,
+ ) -> None:
+ if not uop.name.endswith("_0") and not uop.name.endswith("_1"):
+ self.emit(tkn)
+ return
+ amp = next(tkn_iter)
+ if amp.text != "&":
+ self.emit(tkn)
+ self.emit(amp)
+ return
+ one = next(tkn_iter)
+ assert one.text == "1"
+ self.out.emit_at(uop.name[-1], tkn)
-TIER2_REPLACEMENT_FUNCTIONS = REPLACEMENT_FUNCTIONS.copy()
-TIER2_REPLACEMENT_FUNCTIONS["ERROR_IF"] = tier2_replace_error
-TIER2_REPLACEMENT_FUNCTIONS["ERROR_NO_POP"] = tier2_replace_error_no_pop
-TIER2_REPLACEMENT_FUNCTIONS["DEOPT_IF"] = tier2_replace_deopt
-TIER2_REPLACEMENT_FUNCTIONS["oparg"] = tier2_replace_oparg
-TIER2_REPLACEMENT_FUNCTIONS["EXIT_IF"] = tier2_replace_exit_if
-
-
-def write_uop(uop: Uop, out: CWriter, stack: Stack) -> None:
+def write_uop(uop: Uop, emitter: Emitter, stack: Stack) -> None:
locals: dict[str, Local] = {}
try:
- out.start_line()
+ emitter.out.start_line()
if uop.properties.oparg:
- out.emit("oparg = CURRENT_OPARG();\n")
+ emitter.emit("oparg = CURRENT_OPARG();\n")
assert uop.properties.const_oparg < 0
elif uop.properties.const_oparg >= 0:
- out.emit(f"oparg = {uop.properties.const_oparg};\n")
- out.emit(f"assert(oparg == CURRENT_OPARG());\n")
+ emitter.emit(f"oparg = {uop.properties.const_oparg};\n")
+ emitter.emit(f"assert(oparg == CURRENT_OPARG());\n")
for var in reversed(uop.stack.inputs):
code, local = stack.pop(var)
- out.emit(code)
+ emitter.emit(code)
if local.defined:
locals[local.name] = local
- out.emit(stack.define_output_arrays(uop.stack.outputs))
+ emitter.emit(stack.define_output_arrays(uop.stack.outputs))
for cache in uop.caches:
if cache.name != "unused":
if cache.size == 4:
@@ -179,14 +173,14 @@ def write_uop(uop: Uop, out: CWriter, stack: Stack) -> None:
else:
type = f"uint{cache.size*16}_t "
cast = f"uint{cache.size*16}_t"
- out.emit(f"{type}{cache.name} = ({cast})CURRENT_OPERAND();\n")
- emit_tokens(out, uop, stack, None, TIER2_REPLACEMENT_FUNCTIONS)
+ emitter.emit(f"{type}{cache.name} = ({cast})CURRENT_OPERAND();\n")
+ emitter.emit_tokens(uop, stack, None)
for i, var in enumerate(uop.stack.outputs):
if var.name in locals:
local = locals[var.name]
else:
local = Local.local(var)
- out.emit(stack.push(local))
+ emitter.emit(stack.push(local))
except StackError as ex:
raise analysis_error(ex.args[0], uop.body[0]) from None
@@ -207,6 +201,7 @@ def generate_tier2(
"""
)
out = CWriter(outfile, 2, lines)
+ emitter = Tier2Emitter(out)
out.emit("\n")
for name, uop in analysis.uops.items():
if uop.properties.tier == 1:
@@ -223,7 +218,7 @@ def generate_tier2(
out.emit(f"case {uop.name}: {{\n")
declare_variables(uop, out)
stack = Stack()
- write_uop(uop, out, stack)
+ write_uop(uop, emitter, stack)
out.start_line()
if not uop.properties.always_exits:
stack.flush(out)