diff options
Diffstat (limited to 'Tools/cases_generator/tier2_generator.py')
-rw-r--r-- | Tools/cases_generator/tier2_generator.py | 197 |
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) |