code: def _requantize_sums(
      num_outputs, requantize_shift, output_zero_point
  ) -> Iterator[str]:
      """Generates code to requantize the accumulator values.
  
      The generated code does not use floating point instructions, as it simulates floating point
      multiplication with an a int64 multiply + shift. The bias is added at the beginning, so we can
      skip doing it now. The shift is hard-coded, as this saves a few cycles without hurting accuracy
      in "most" cases.
  
      It's *possible* we could save one more cycle here by pre-multiplying the bias with the
      requantize multiplier, and then doing the bias addition and shift in the same cycle (via <op2>).
      However, it's complicated and only saves one cycle.
  
      It's also worth noting the SSAT16 operation doesn't help us here. The data isn't stored as two
      halfwords in a word, and rearrainging it would take at least one cycle. Two SSAT operations is
      just as good.
  
      Calling __ssat directly is a little bit gross, but GCC and Clang are unreliable about compiling
      other ways of writing this. Both the multiply + shift and shift + saturation combine to one
      instruction each.
      """
  
      yield "int32_t scale_val = *scale;"
      for i in range(num_outputs):
          yield f"int32_t requant_{i} = (sum_{i} * (int64_t) scale_val) >> {requantize_shift - 1};"
          yield f"requant_{i} = (requant_{i} + 1) >> 1;"
          yield f"requant_{i} = __ssat(requant_{i} + {output_zero_point}, 8);"
  
file_path: tvm/python/tvm/topi/arm_cpu/mprofile/dsp/micro_kernel/tensordot.py
imports: from dataclasses import dataclass
  from itertools import chain
  import textwrap
  from typing import Iterator, Optional, Tuple
label_desc: Use image node_id 11 for calling a global function with example usage: _requantize_sums(num_outputs, requantize_shift, output_zero_point) without return types