xref: /aosp_15_r20/external/XNNPACK/scripts/convert-assembly-to-jit.py (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
1*4bdc9457SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*4bdc9457SAndroid Build Coastguard Worker# Copyright 2021 Google LLC
3*4bdc9457SAndroid Build Coastguard Worker#
4*4bdc9457SAndroid Build Coastguard Worker# This source code is licensed under the BSD-style license found in the
5*4bdc9457SAndroid Build Coastguard Worker# LICENSE file in the root directory of this source tree.
6*4bdc9457SAndroid Build Coastguard Worker"""Converts hand written assembly (.S files) to C++ files using the JIT.
7*4bdc9457SAndroid Build Coastguard Worker
8*4bdc9457SAndroid Build Coastguard WorkerTakes a single argument, an assembly file, and prints converted output to stdout.
9*4bdc9457SAndroid Build Coastguard Worker"""
10*4bdc9457SAndroid Build Coastguard Worker
11*4bdc9457SAndroid Build Coastguard Workerimport argparse
12*4bdc9457SAndroid Build Coastguard Workerimport datetime
13*4bdc9457SAndroid Build Coastguard Workerimport re
14*4bdc9457SAndroid Build Coastguard Workerimport sys
15*4bdc9457SAndroid Build Coastguard Worker
16*4bdc9457SAndroid Build Coastguard WorkerSPACES = r'\s*'
17*4bdc9457SAndroid Build Coastguard WorkerCOMMA = r',' + SPACES
18*4bdc9457SAndroid Build Coastguard WorkerCOMMENTS = SPACES + '((//\s+.+)|)$'
19*4bdc9457SAndroid Build Coastguard WorkerWB = r'!'
20*4bdc9457SAndroid Build Coastguard Worker
21*4bdc9457SAndroid Build Coastguard WorkerREG_NO_GROUP = r'r\d+|s\d+|d\d+|q\d+|sp|lr|pc|x\d+|(?:v\d+\.(?:\d+)?(?:d|s|h|b))'
22*4bdc9457SAndroid Build Coastguard WorkerREG = r'(' + REG_NO_GROUP + ')'
23*4bdc9457SAndroid Build Coastguard WorkerIMM_NO_GROUP = r'\d+'
24*4bdc9457SAndroid Build Coastguard WorkerIMM = r'(' + IMM_NO_GROUP + ')'
25*4bdc9457SAndroid Build Coastguard WorkerREG_LANE_NO_GROUP = r'(?:' + REG_NO_GROUP + r')\[' + IMM_NO_GROUP + r'\]'
26*4bdc9457SAndroid Build Coastguard WorkerREG_OR_IMM = r'(' + REG_LANE_NO_GROUP + '|' + REG_NO_GROUP + '|' + IMM_NO_GROUP + ')'
27*4bdc9457SAndroid Build Coastguard Worker
28*4bdc9457SAndroid Build Coastguard WorkerREGLIST_CONSEC = r'\{(\w+)-(\w+)\}' + SPACES
29*4bdc9457SAndroid Build Coastguard WorkerREGLIST_INDIV = r'\{([\w.]+(?:,\s+[\w.]+)*)\}' + SPACES
30*4bdc9457SAndroid Build Coastguard WorkerREGLIST_INDIV_REPLICATE = r'\{(\w+(?:\[\])(,\s*\w+(?:\[\]))*)\}' + SPACES
31*4bdc9457SAndroid Build Coastguard WorkerREGLIST_INDEX = r'\{(' + REG_LANE_NO_GROUP + ')\}' + SPACES
32*4bdc9457SAndroid Build Coastguard Worker
33*4bdc9457SAndroid Build Coastguard WorkerAPSR = 'APSR_nzcv'
34*4bdc9457SAndroid Build Coastguard WorkerFPSCR = '(FPSCR)'
35*4bdc9457SAndroid Build Coastguard Worker
36*4bdc9457SAndroid Build Coastguard WorkerMEMOP = r'\[' + SPACES + REG + '\]' + SPACES
37*4bdc9457SAndroid Build Coastguard WorkerMEMOP_MAYBE_WB = r'\[' + SPACES + REG + '\]' + f'({WB})?'
38*4bdc9457SAndroid Build Coastguard WorkerMEMOP_OFFSET = r'\[' + REG + COMMA + '(-?\d+)\]' + SPACES
39*4bdc9457SAndroid Build Coastguard WorkerMEMOP_OFFSET_MAYBE_WB = r'\[' + REG + COMMA + '(-?\d+)\]' + f'({WB})?' + SPACES
40*4bdc9457SAndroid Build Coastguard Worker
41*4bdc9457SAndroid Build Coastguard WorkerB_IMM = r'(\d+)(f|b)'
42*4bdc9457SAndroid Build Coastguard Worker
43*4bdc9457SAndroid Build Coastguard WorkerINSTR = SPACES + r'([A-Z0-9.]+)' + SPACES
44*4bdc9457SAndroid Build Coastguard Worker
45*4bdc9457SAndroid Build Coastguard Worker# e.g. #ifndef __APPLE__
46*4bdc9457SAndroid Build Coastguard WorkerIFDEF_RE = re.compile(r'\s*#(ifndef|endif|ifdef).*')
47*4bdc9457SAndroid Build Coastguard Worker# e.g. # Push 96 bytes
48*4bdc9457SAndroid Build Coastguard WorkerCOMMENT_RE = re.compile(SPACES + r'((//|#)\s*.+)')
49*4bdc9457SAndroid Build Coastguard Worker# e.g. 0:
50*4bdc9457SAndroid Build Coastguard WorkerLABEL = re.compile(r'(\w+):')
51*4bdc9457SAndroid Build Coastguard Worker# e.g. NOP
52*4bdc9457SAndroid Build Coastguard WorkerINSTR_RE = re.compile(INSTR + COMMENTS)
53*4bdc9457SAndroid Build Coastguard Worker# e.g. VPUSH {d8-d15}
54*4bdc9457SAndroid Build Coastguard WorkerINSTR_REGLIST_CONSEC_RE = re.compile(INSTR + REGLIST_CONSEC + COMMENTS)
55*4bdc9457SAndroid Build Coastguard Worker# e.g. PUSH {r4, r5}
56*4bdc9457SAndroid Build Coastguard WorkerINSTR_REGLIST_LIST_RE = re.compile(INSTR + REGLIST_INDIV + COMMENTS)
57*4bdc9457SAndroid Build Coastguard Worker# e.g. BX lr
58*4bdc9457SAndroid Build Coastguard WorkerINSTR_OP_RE = re.compile(INSTR + REG + COMMENTS)
59*4bdc9457SAndroid Build Coastguard Worker# e.g. BLO 2f
60*4bdc9457SAndroid Build Coastguard WorkerINSTR_B_IMM = re.compile(INSTR + B_IMM + COMMENTS)
61*4bdc9457SAndroid Build Coastguard Worker# e.g. TBNZ x0, 4, 5f
62*4bdc9457SAndroid Build Coastguard WorkerINSTR_B_REG_IMM_IMM = re.compile(INSTR + REG + COMMA + IMM + COMMA + B_IMM + COMMENTS)
63*4bdc9457SAndroid Build Coastguard Worker# e.g. .p2align 3
64*4bdc9457SAndroid Build Coastguard WorkerP2ALIGN_RE = re.compile(SPACES + r'\.p2align\s+(\d+)')
65*4bdc9457SAndroid Build Coastguard Worker# e.g. CMP r0, 2
66*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_IMM_RE = re.compile(INSTR + REG + COMMA + IMM + COMMENTS)
67*4bdc9457SAndroid Build Coastguard Worker# e.g. LDR r0, [r12]
68*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_MEMOP_RE = re.compile(INSTR + REG + COMMA + MEMOP + COMMENTS)
69*4bdc9457SAndroid Build Coastguard Worker# e.g. LDR q0, [x4], 16
70*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_MEMOP_IMM_RE = re.compile(INSTR + REG + COMMA + MEMOP + COMMA + IMM + COMMENTS)
71*4bdc9457SAndroid Build Coastguard Worker# e.g. LDR r0, [sp, 112], STR x20, [sp, -80]!
72*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_MEMOP_OFFSET_RE = re.compile(INSTR + REG + COMMA + MEMOP_OFFSET_MAYBE_WB +
73*4bdc9457SAndroid Build Coastguard Worker                                       COMMENTS)
74*4bdc9457SAndroid Build Coastguard Worker# e.g. LDRD r6, r7, [sp]
75*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_REG_MEMOP_RE = re.compile(INSTR + REG + COMMA + REG + COMMA +
76*4bdc9457SAndroid Build Coastguard Worker                                           MEMOP + COMMENTS)
77*4bdc9457SAndroid Build Coastguard Worker# e.g. LDRD r6, r7, [sp, 104], STP d8, d9, [sp, -64]!
78*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_REG_MEMOP_OFFSET_RE = re.compile(INSTR + REG + COMMA + REG + COMMA +
79*4bdc9457SAndroid Build Coastguard Worker                                           MEMOP_OFFSET_MAYBE_WB + COMMENTS)
80*4bdc9457SAndroid Build Coastguard Worker# e.g. LDP q20, q21, [x5], 32
81*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_REG_MEMOP_IMM_RE = re.compile(INSTR + REG + COMMA + REG + COMMA +
82*4bdc9457SAndroid Build Coastguard Worker                                           MEMOP + COMMA + IMM + COMMENTS)
83*4bdc9457SAndroid Build Coastguard Worker# e.g. PLD [r4, 64]
84*4bdc9457SAndroid Build Coastguard WorkerINSTR_MEMOP_OFFSET_RE = re.compile(INSTR + MEMOP_OFFSET + COMMENTS)
85*4bdc9457SAndroid Build Coastguard Worker# e.g. movlo r12, r3, vdup.32 q0, d14[0]
86*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_REG_RE = re.compile(INSTR + REG + COMMA + REG_OR_IMM + COMMENTS)
87*4bdc9457SAndroid Build Coastguard Worker# e.g. SUBS r5, r2, 16 or SUBS r5, r2, r10 or VMLFA.F32 q8, q4, d0[0]
88*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_REG_REG_RE = re.compile(INSTR + REG + COMMA + REG + COMMA +
89*4bdc9457SAndroid Build Coastguard Worker                                  REG_OR_IMM + COMMENTS)
90*4bdc9457SAndroid Build Coastguard Worker# e.g. VEXT.8  q0, q0, q0, 4
91*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_REG_REG_IMM_RE = re.compile(INSTR + REG + COMMA + REG + COMMA + REG +
92*4bdc9457SAndroid Build Coastguard Worker                                      COMMA + IMM + COMMENTS)
93*4bdc9457SAndroid Build Coastguard Worker# e.g. VST1.32 {d16}, [r11], r0
94*4bdc9457SAndroid Build Coastguard WorkerINSTR_REGLIST_INDIV_MEMOP_REG = re.compile(INSTR + REGLIST_INDIV + COMMA +
95*4bdc9457SAndroid Build Coastguard Worker                                           MEMOP + COMMA + REG + COMMENTS)
96*4bdc9457SAndroid Build Coastguard Worker# e.g. VST1.32 {d16-d19}, [r11], r0
97*4bdc9457SAndroid Build Coastguard WorkerINSTR_REGLIST_CONSEC_MEMOP_REG = re.compile(INSTR + REGLIST_CONSEC + COMMA +
98*4bdc9457SAndroid Build Coastguard Worker                                            MEMOP + COMMA + REG + COMMENTS)
99*4bdc9457SAndroid Build Coastguard Worker# e.g. VLDM r9, {d16-d19}
100*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_REGLIST_CONSECT = re.compile(INSTR + REG + COMMA + REGLIST_CONSEC +
101*4bdc9457SAndroid Build Coastguard Worker                                       COMMENTS)
102*4bdc9457SAndroid Build Coastguard Worker# e.g. VLDM r9!, {d16-d19}
103*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_REGLIST_CONSECT_WB = re.compile(INSTR + REG + WB + COMMA +
104*4bdc9457SAndroid Build Coastguard Worker                                          REGLIST_CONSEC + COMMENTS)
105*4bdc9457SAndroid Build Coastguard Worker# e.g. VLDM r9!, {d16}
106*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_REGLIST_INDIV_WB = re.compile(INSTR + REG + WB + COMMA +
107*4bdc9457SAndroid Build Coastguard Worker                                        REGLIST_INDIV + COMMENTS)
108*4bdc9457SAndroid Build Coastguard Worker# e.g. VLD1.32 {d0}, [r3]{!}
109*4bdc9457SAndroid Build Coastguard WorkerINSTR_REGLIST_INDIV_MEMOP = re.compile(INSTR + REGLIST_INDIV + COMMA +
110*4bdc9457SAndroid Build Coastguard Worker                                       MEMOP_MAYBE_WB + COMMENTS)
111*4bdc9457SAndroid Build Coastguard Worker# e.g. LD1 {v16.16b, v17.16b, v18.16b}, [x5], 48
112*4bdc9457SAndroid Build Coastguard WorkerINSTR_REGLIST_INDIV_MEMOP_IMM = re.compile(INSTR + REGLIST_INDIV + COMMA +
113*4bdc9457SAndroid Build Coastguard Worker                                       MEMOP + COMMA + IMM + COMMENTS)
114*4bdc9457SAndroid Build Coastguard Worker# e.g. VST1.32 {d24-d25}, [r11]{!}
115*4bdc9457SAndroid Build Coastguard WorkerINSTR_REGLIST_CONSEC_MEMOP = re.compile(INSTR + REGLIST_CONSEC + COMMA +
116*4bdc9457SAndroid Build Coastguard Worker                                        MEMOP_MAYBE_WB + COMMENTS)
117*4bdc9457SAndroid Build Coastguard Worker# e.g. VLD1.32 {d0[]}, [r3]!
118*4bdc9457SAndroid Build Coastguard WorkerINSTR_REGLIST_REPLICATE_MEMOP = re.compile(INSTR + REGLIST_INDIV_REPLICATE +
119*4bdc9457SAndroid Build Coastguard Worker                                           COMMA + MEMOP + r'(!)?' + COMMENTS)
120*4bdc9457SAndroid Build Coastguard Worker# e.g. VST1.32 {d16[0]}, [r11]{!}
121*4bdc9457SAndroid Build Coastguard WorkerINSTR_REGLIST_INDEX_MEMOP = re.compile(INSTR + REGLIST_INDEX + COMMA +
122*4bdc9457SAndroid Build Coastguard Worker                                       MEMOP_MAYBE_WB + COMMENTS)
123*4bdc9457SAndroid Build Coastguard Worker# e.g. VMRS APSR_nzcv, FPSCR
124*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_FPSCR = re.compile(INSTR + f'({APSR}|{REG_NO_GROUP})' + COMMA +
125*4bdc9457SAndroid Build Coastguard Worker                             FPSCR + COMMENTS)
126*4bdc9457SAndroid Build Coastguard Worker
127*4bdc9457SAndroid Build Coastguard Worker# e.g. PRFM PLDL1KEEP, [x5]
128*4bdc9457SAndroid Build Coastguard WorkerINSTR_PLD_MEMOP = re.compile(INSTR + f'(PLDL1KEEP)' + COMMA + MEMOP + COMMENTS)
129*4bdc9457SAndroid Build Coastguard Worker# e.g. PRFM PLDL1KEEP, [x5, 64]
130*4bdc9457SAndroid Build Coastguard WorkerINSTR_PLD_MEMOP_OFFSET = re.compile(INSTR + f'(PLDL1KEEP)' + COMMA + MEMOP_OFFSET + COMMENTS)
131*4bdc9457SAndroid Build Coastguard Worker
132*4bdc9457SAndroid Build Coastguard WorkerCOND = r'([A-Z]+)'
133*4bdc9457SAndroid Build Coastguard Worker# e.g. CSEL x9, x3, x9, LO
134*4bdc9457SAndroid Build Coastguard WorkerINSTR_REG_REG_REG_COND_RE = re.compile(INSTR + REG + COMMA + REG + COMMA + REG + COMMA + COND + COMMENTS)
135*4bdc9457SAndroid Build Coastguard Worker
136*4bdc9457SAndroid Build Coastguard Worker
137*4bdc9457SAndroid Build Coastguard Workerdef remove_brackets(s):
138*4bdc9457SAndroid Build Coastguard Worker  return s.replace('[', '').replace(']', '')
139*4bdc9457SAndroid Build Coastguard Worker
140*4bdc9457SAndroid Build Coastguard Worker
141*4bdc9457SAndroid Build Coastguard Workerdef fix_replicate_instruction(s):
142*4bdc9457SAndroid Build Coastguard Worker  return re.sub(r'_(\d+)', r'r_\1', s, 1)
143*4bdc9457SAndroid Build Coastguard Worker
144*4bdc9457SAndroid Build Coastguard Worker
145*4bdc9457SAndroid Build Coastguard Workerdef fix_instr_name(s):
146*4bdc9457SAndroid Build Coastguard Worker  return s.lower().replace('.', '_', 2).replace('and', 'and_', 1)
147*4bdc9457SAndroid Build Coastguard Worker
148*4bdc9457SAndroid Build Coastguard Worker
149*4bdc9457SAndroid Build Coastguard Workerdef fix_comments(s):
150*4bdc9457SAndroid Build Coastguard Worker  return s.replace('#', '//', 1)
151*4bdc9457SAndroid Build Coastguard Worker
152*4bdc9457SAndroid Build Coastguard Worker
153*4bdc9457SAndroid Build Coastguard Workerdef maybe_wb(wb):
154*4bdc9457SAndroid Build Coastguard Worker  return '++' if wb else ''
155*4bdc9457SAndroid Build Coastguard Worker
156*4bdc9457SAndroid Build Coastguard Worker
157*4bdc9457SAndroid Build Coastguard Workerdef fix_fn_name(name):
158*4bdc9457SAndroid Build Coastguard Worker  if name.startswith('xnn_'):
159*4bdc9457SAndroid Build Coastguard Worker    name = name[len('xnn_'):]
160*4bdc9457SAndroid Build Coastguard Worker  # remove any type of activations from name
161*4bdc9457SAndroid Build Coastguard Worker  if 'minmax' in name:
162*4bdc9457SAndroid Build Coastguard Worker    name = name.replace('minmax_', '')
163*4bdc9457SAndroid Build Coastguard Worker  return f'xnn_generate_{name}'
164*4bdc9457SAndroid Build Coastguard Worker
165*4bdc9457SAndroid Build Coastguard Worker
166*4bdc9457SAndroid Build Coastguard Workerdef remove_prfm_from_fn_name(name):
167*4bdc9457SAndroid Build Coastguard Worker  assert('_prfm_' in name)
168*4bdc9457SAndroid Build Coastguard Worker  return name.replace('prfm_', '')
169*4bdc9457SAndroid Build Coastguard Worker
170*4bdc9457SAndroid Build Coastguard Worker
171*4bdc9457SAndroid Build Coastguard Workerdef fix_regs(regs):
172*4bdc9457SAndroid Build Coastguard Worker  # Vector registers with datatype need to be method calls.
173*4bdc9457SAndroid Build Coastguard Worker  # e.g. v2.4s -> v2.v4s(), v2.s -> v2.s()
174*4bdc9457SAndroid Build Coastguard Worker  def repl(m):
175*4bdc9457SAndroid Build Coastguard Worker    if m.group(2):
176*4bdc9457SAndroid Build Coastguard Worker      return f'{m[1]}v{m[2]}{m[3]}()'
177*4bdc9457SAndroid Build Coastguard Worker    else:
178*4bdc9457SAndroid Build Coastguard Worker      return f'{m[1]}{m[3]}()'
179*4bdc9457SAndroid Build Coastguard Worker  return re.sub(r'(\w+\.)(\d+)?(\w+)', repl, regs)
180*4bdc9457SAndroid Build Coastguard Worker
181*4bdc9457SAndroid Build Coastguard Worker
182*4bdc9457SAndroid Build Coastguard WorkerIGNORE_LINES = [r'\s*\.\w+']
183*4bdc9457SAndroid Build Coastguard Worker
184*4bdc9457SAndroid Build Coastguard WorkerAARCH32 = 'aarch32'
185*4bdc9457SAndroid Build Coastguard WorkerAARCH64 = 'aarch64'
186*4bdc9457SAndroid Build Coastguard WorkerGEMM = 'GEMM'
187*4bdc9457SAndroid Build Coastguard WorkerIGEMM = 'IGEMM'
188*4bdc9457SAndroid Build Coastguard Worker
189*4bdc9457SAndroid Build Coastguard Workerdef main(input_file):
190*4bdc9457SAndroid Build Coastguard Worker  arch = None
191*4bdc9457SAndroid Build Coastguard Worker  kernel_type = GEMM
192*4bdc9457SAndroid Build Coastguard Worker  minmax = False
193*4bdc9457SAndroid Build Coastguard Worker  prfm = False
194*4bdc9457SAndroid Build Coastguard Worker  datatype = 'f32'
195*4bdc9457SAndroid Build Coastguard Worker  ctype = 'float'
196*4bdc9457SAndroid Build Coastguard Worker
197*4bdc9457SAndroid Build Coastguard Worker  if 'aarch32' in input_file:
198*4bdc9457SAndroid Build Coastguard Worker    arch = AARCH32
199*4bdc9457SAndroid Build Coastguard Worker  elif 'aarch64' in input_file:
200*4bdc9457SAndroid Build Coastguard Worker    arch = AARCH64
201*4bdc9457SAndroid Build Coastguard Worker  else:
202*4bdc9457SAndroid Build Coastguard Worker    print('ERROR: unknown architecture')
203*4bdc9457SAndroid Build Coastguard Worker    sys.exit(1)
204*4bdc9457SAndroid Build Coastguard Worker
205*4bdc9457SAndroid Build Coastguard Worker  if 'igemm' in input_file:
206*4bdc9457SAndroid Build Coastguard Worker    kernel_type = IGEMM
207*4bdc9457SAndroid Build Coastguard Worker  if 'minmax' in input_file:
208*4bdc9457SAndroid Build Coastguard Worker    minmax = True
209*4bdc9457SAndroid Build Coastguard Worker  if 'prfm' in input_file:
210*4bdc9457SAndroid Build Coastguard Worker    prfm = True
211*4bdc9457SAndroid Build Coastguard Worker
212*4bdc9457SAndroid Build Coastguard Worker  # Whether we are in the copyright section.
213*4bdc9457SAndroid Build Coastguard Worker  in_copyright = False
214*4bdc9457SAndroid Build Coastguard Worker  # Whether we are in the microkernel function.
215*4bdc9457SAndroid Build Coastguard Worker  in_function = False
216*4bdc9457SAndroid Build Coastguard Worker  # Instructions that make up the microkernel.
217*4bdc9457SAndroid Build Coastguard Worker  instructions = []
218*4bdc9457SAndroid Build Coastguard Worker  # Lines of code or comments before the actual function body.
219*4bdc9457SAndroid Build Coastguard Worker  prologue = []
220*4bdc9457SAndroid Build Coastguard Worker  # All labels need to be declared first, collect them and output them after
221*4bdc9457SAndroid Build Coastguard Worker  # function signature.
222*4bdc9457SAndroid Build Coastguard Worker  labels = []
223*4bdc9457SAndroid Build Coastguard Worker  # Name of the microkernel function.
224*4bdc9457SAndroid Build Coastguard Worker  fn_name = ''
225*4bdc9457SAndroid Build Coastguard Worker  sc = ';'
226*4bdc9457SAndroid Build Coastguard Worker  # Whether we are in the auto-generated comment.
227*4bdc9457SAndroid Build Coastguard Worker  in_autogen = False
228*4bdc9457SAndroid Build Coastguard Worker
229*4bdc9457SAndroid Build Coastguard Worker  with open(input_file, 'r', encoding='utf-8') as f:
230*4bdc9457SAndroid Build Coastguard Worker    for line in f:
231*4bdc9457SAndroid Build Coastguard Worker      line = line.rstrip()
232*4bdc9457SAndroid Build Coastguard Worker
233*4bdc9457SAndroid Build Coastguard Worker      # Handle all lines before the microkernel instructions begin.
234*4bdc9457SAndroid Build Coastguard Worker      if not in_function:
235*4bdc9457SAndroid Build Coastguard Worker        if 'Auto-generated file' in line:
236*4bdc9457SAndroid Build Coastguard Worker          in_autogen = True
237*4bdc9457SAndroid Build Coastguard Worker          continue
238*4bdc9457SAndroid Build Coastguard Worker        elif 'BEGIN_FUNCTION' in line:
239*4bdc9457SAndroid Build Coastguard Worker          in_function = True
240*4bdc9457SAndroid Build Coastguard Worker          fn_name = line.split()[1]
241*4bdc9457SAndroid Build Coastguard Worker          prologue.append(f'// Converted from: {input_file[20:]}')
242*4bdc9457SAndroid Build Coastguard Worker          params = 'float min, float max' if minmax else 'void* params'
243*4bdc9457SAndroid Build Coastguard Worker          prefetch = 'bool prefetch, ' if prfm else ''
244*4bdc9457SAndroid Build Coastguard Worker          if kernel_type == GEMM:
245*4bdc9457SAndroid Build Coastguard Worker            prologue.append(f'void Generator::generate({prefetch}size_t max_mr, size_t nc_mod_nr, size_t kc, {params}) {{')
246*4bdc9457SAndroid Build Coastguard Worker          else:
247*4bdc9457SAndroid Build Coastguard Worker            prologue.append(f'void Generator::generate({prefetch}size_t max_mr, size_t nc_mod_nr, size_t kc, size_t ks, {params}) {{')
248*4bdc9457SAndroid Build Coastguard Worker          continue
249*4bdc9457SAndroid Build Coastguard Worker        elif 'Copyright ' in line:
250*4bdc9457SAndroid Build Coastguard Worker          in_autogen = False
251*4bdc9457SAndroid Build Coastguard Worker          # replace year
252*4bdc9457SAndroid Build Coastguard Worker          prologue.append(
253*4bdc9457SAndroid Build Coastguard Worker              re.sub('\d{4}', str(datetime.date.today().year), line,
254*4bdc9457SAndroid Build Coastguard Worker                     1).rstrip())
255*4bdc9457SAndroid Build Coastguard Worker          continue
256*4bdc9457SAndroid Build Coastguard Worker        elif '#include <xnnpack/assembly.h>' in line:
257*4bdc9457SAndroid Build Coastguard Worker          prologue.append(f'#include <cassert>')
258*4bdc9457SAndroid Build Coastguard Worker          prologue.append(f'#include <cstddef>')
259*4bdc9457SAndroid Build Coastguard Worker          prologue.append(f'#include <limits>')
260*4bdc9457SAndroid Build Coastguard Worker          prologue.append('')
261*4bdc9457SAndroid Build Coastguard Worker          prologue.append(f'#include <xnnpack/{arch}-assembler.h>')
262*4bdc9457SAndroid Build Coastguard Worker          prologue.append('#include <xnnpack/allocator.h>')
263*4bdc9457SAndroid Build Coastguard Worker          if kernel_type == GEMM:
264*4bdc9457SAndroid Build Coastguard Worker            prologue.append('#include <xnnpack/gemm.h>')
265*4bdc9457SAndroid Build Coastguard Worker          else:
266*4bdc9457SAndroid Build Coastguard Worker            prologue.append('#include <xnnpack/igemm.h>')
267*4bdc9457SAndroid Build Coastguard Worker          prologue.append('')
268*4bdc9457SAndroid Build Coastguard Worker          prologue.append('namespace xnnpack {')
269*4bdc9457SAndroid Build Coastguard Worker          prologue.append(f'namespace {arch} {{')
270*4bdc9457SAndroid Build Coastguard Worker          prologue.append('namespace {')
271*4bdc9457SAndroid Build Coastguard Worker          prologue.append('class Generator : public Assembler {')
272*4bdc9457SAndroid Build Coastguard Worker          prologue.append('  using Assembler::Assembler;')
273*4bdc9457SAndroid Build Coastguard Worker          prologue.append(' public:')
274*4bdc9457SAndroid Build Coastguard Worker          params = 'float min, float max' if minmax else 'void* params'
275*4bdc9457SAndroid Build Coastguard Worker          prefetch = 'bool prefetch, ' if prfm else ''
276*4bdc9457SAndroid Build Coastguard Worker          if kernel_type == GEMM:
277*4bdc9457SAndroid Build Coastguard Worker            prologue.append(f'  void generate({prefetch}size_t max_mr, size_t nc_mod_nr, size_t kc, {params});')
278*4bdc9457SAndroid Build Coastguard Worker          else:
279*4bdc9457SAndroid Build Coastguard Worker            prologue.append(f'  void generate({prefetch}size_t max_mr, size_t nc_mod_nr, size_t kc, size_t ks, {params});')
280*4bdc9457SAndroid Build Coastguard Worker          prologue.append('};')
281*4bdc9457SAndroid Build Coastguard Worker          continue
282*4bdc9457SAndroid Build Coastguard Worker        elif any(re.fullmatch(p, line) for p in IGNORE_LINES):
283*4bdc9457SAndroid Build Coastguard Worker          continue
284*4bdc9457SAndroid Build Coastguard Worker        elif in_autogen:
285*4bdc9457SAndroid Build Coastguard Worker          continue
286*4bdc9457SAndroid Build Coastguard Worker        else:
287*4bdc9457SAndroid Build Coastguard Worker          prologue.append(fix_comments(line.rstrip()))
288*4bdc9457SAndroid Build Coastguard Worker          continue
289*4bdc9457SAndroid Build Coastguard Worker      # end if not in_function
290*4bdc9457SAndroid Build Coastguard Worker
291*4bdc9457SAndroid Build Coastguard Worker      # We are now in the microkernel function body.
292*4bdc9457SAndroid Build Coastguard Worker      # Don't keep the ifdefs.
293*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(IFDEF_RE, line)
294*4bdc9457SAndroid Build Coastguard Worker      if m:
295*4bdc9457SAndroid Build Coastguard Worker        continue
296*4bdc9457SAndroid Build Coastguard Worker      # But keep other comments.
297*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(COMMENT_RE, line)
298*4bdc9457SAndroid Build Coastguard Worker      if m:
299*4bdc9457SAndroid Build Coastguard Worker        instructions.append(m[1])
300*4bdc9457SAndroid Build Coastguard Worker        continue
301*4bdc9457SAndroid Build Coastguard Worker
302*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(LABEL, line)
303*4bdc9457SAndroid Build Coastguard Worker      if m:
304*4bdc9457SAndroid Build Coastguard Worker        labels.append(m[1])
305*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'bind(l{m[1]}){sc}')
306*4bdc9457SAndroid Build Coastguard Worker        continue
307*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_RE, line)
308*4bdc9457SAndroid Build Coastguard Worker      if m:
309*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}(){sc} {m[2]}')
310*4bdc9457SAndroid Build Coastguard Worker        continue
311*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_OP_RE, line)
312*4bdc9457SAndroid Build Coastguard Worker      if m:
313*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}({m[2]}){sc} {m[3]}')
314*4bdc9457SAndroid Build Coastguard Worker        continue
315*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REGLIST_CONSEC_MEMOP_REG, line)
316*4bdc9457SAndroid Build Coastguard Worker      if m:
317*4bdc9457SAndroid Build Coastguard Worker        instructions.append(
318*4bdc9457SAndroid Build Coastguard Worker            f'{fix_instr_name(m[1])}({{{m[2]}-{m[3]}}}, mem[{m[4]}], {m[5]}){sc} {m[6]}'
319*4bdc9457SAndroid Build Coastguard Worker        )
320*4bdc9457SAndroid Build Coastguard Worker        continue
321*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REGLIST_INDIV_MEMOP_REG, line)
322*4bdc9457SAndroid Build Coastguard Worker      if m:
323*4bdc9457SAndroid Build Coastguard Worker        instructions.append(
324*4bdc9457SAndroid Build Coastguard Worker            f'{fix_instr_name(m[1])}({{{fix_regs(m[2])}}}, mem[{m[3]}], {m[4]}){sc} {m[5]}')
325*4bdc9457SAndroid Build Coastguard Worker        continue
326*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REGLIST_CONSEC_RE, line)
327*4bdc9457SAndroid Build Coastguard Worker      if m:
328*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}({{{m[2]}-{m[3]}}}){sc} {m[4]}')
329*4bdc9457SAndroid Build Coastguard Worker        continue
330*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REGLIST_LIST_RE, line)
331*4bdc9457SAndroid Build Coastguard Worker      if m:
332*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}({{{m[2]}}}){sc} {m[3]}')
333*4bdc9457SAndroid Build Coastguard Worker        continue
334*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_MEMOP_OFFSET_RE, line)
335*4bdc9457SAndroid Build Coastguard Worker      if m:
336*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}(mem[{m[2]}, {m[3]}]){sc} {m[4]}')
337*4bdc9457SAndroid Build Coastguard Worker        continue
338*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_MEMOP_RE, line)
339*4bdc9457SAndroid Build Coastguard Worker      if m:
340*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}({m[2]}, mem[{m[3]}]){sc} {m[4]}')
341*4bdc9457SAndroid Build Coastguard Worker        continue
342*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_MEMOP_IMM_RE , line)
343*4bdc9457SAndroid Build Coastguard Worker      if m:
344*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}({m[2]}, mem[{m[3]}], {m[4]}){sc} {m[5]}')
345*4bdc9457SAndroid Build Coastguard Worker        continue
346*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_MEMOP_OFFSET_RE, line)
347*4bdc9457SAndroid Build Coastguard Worker      if m:
348*4bdc9457SAndroid Build Coastguard Worker        if m[5]: # wb
349*4bdc9457SAndroid Build Coastguard Worker          instructions.append(
350*4bdc9457SAndroid Build Coastguard Worker              f'{fix_instr_name(m[1])}({m[2]}, mem[{m[3]}, {m[4]}]++){sc} {m[6]}')
351*4bdc9457SAndroid Build Coastguard Worker        else: # no wb
352*4bdc9457SAndroid Build Coastguard Worker          instructions.append(
353*4bdc9457SAndroid Build Coastguard Worker              f'{fix_instr_name(m[1])}({m[2]}, mem[{m[3]}, {m[4]}]){sc} {m[6]}')
354*4bdc9457SAndroid Build Coastguard Worker        continue
355*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_REG_MEMOP_RE, line)
356*4bdc9457SAndroid Build Coastguard Worker      if m:
357*4bdc9457SAndroid Build Coastguard Worker        instructions.append(
358*4bdc9457SAndroid Build Coastguard Worker            f'{fix_instr_name(m[1])}({m[2]}, {m[3]}, mem[{m[4]}]){sc} {m[5]}')
359*4bdc9457SAndroid Build Coastguard Worker        continue
360*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_REG_MEMOP_OFFSET_RE, line)
361*4bdc9457SAndroid Build Coastguard Worker      if m:
362*4bdc9457SAndroid Build Coastguard Worker        if m[6]: # wb
363*4bdc9457SAndroid Build Coastguard Worker          instructions.append(
364*4bdc9457SAndroid Build Coastguard Worker              f'{fix_instr_name(m[1])}({m[2]}, {m[3]}, mem[{m[4]}, {m[5]}]++){sc} {m[7]}')
365*4bdc9457SAndroid Build Coastguard Worker        else: #no wb
366*4bdc9457SAndroid Build Coastguard Worker          instructions.append(
367*4bdc9457SAndroid Build Coastguard Worker              f'{fix_instr_name(m[1])}({m[2]}, {m[3]}, mem[{m[4]}, {m[5]}]){sc} {m[7]}')
368*4bdc9457SAndroid Build Coastguard Worker        continue
369*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_REG_MEMOP_IMM_RE , line)
370*4bdc9457SAndroid Build Coastguard Worker      if m:
371*4bdc9457SAndroid Build Coastguard Worker        instructions.append(
372*4bdc9457SAndroid Build Coastguard Worker            f'{fix_instr_name(m[1])}({m[2]}, {m[3]}, mem[{m[4]}], {m[5]}){sc} {m[6]}')
373*4bdc9457SAndroid Build Coastguard Worker        continue
374*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_IMM_RE, line)
375*4bdc9457SAndroid Build Coastguard Worker      if m:
376*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}({fix_regs(m[2])}, {m[3]}){sc} {m[4]}')
377*4bdc9457SAndroid Build Coastguard Worker        continue
378*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_REG_REG_RE, line)
379*4bdc9457SAndroid Build Coastguard Worker      if m:
380*4bdc9457SAndroid Build Coastguard Worker        instructions.append(
381*4bdc9457SAndroid Build Coastguard Worker            f'{fix_instr_name(m[1])}({fix_regs(m[2])}, {fix_regs(m[3])}, {fix_regs(m[4])}){sc} {m[5]}')
382*4bdc9457SAndroid Build Coastguard Worker        continue
383*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_REG_REG_IMM_RE, line)
384*4bdc9457SAndroid Build Coastguard Worker      if m:
385*4bdc9457SAndroid Build Coastguard Worker        instructions.append(
386*4bdc9457SAndroid Build Coastguard Worker            f'{fix_instr_name(m[1])}({m[2]}, {m[3]}, {m[4]}, {m[5]}){sc} {m[6]}')
387*4bdc9457SAndroid Build Coastguard Worker        continue
388*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_REG_RE, line)
389*4bdc9457SAndroid Build Coastguard Worker      if m:
390*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}({fix_regs(m[2])}, {fix_regs(m[3])}){sc} {m[4]}')
391*4bdc9457SAndroid Build Coastguard Worker        continue
392*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_REGLIST_CONSECT, line)
393*4bdc9457SAndroid Build Coastguard Worker      if m:
394*4bdc9457SAndroid Build Coastguard Worker        instructions.append(
395*4bdc9457SAndroid Build Coastguard Worker            f'{fix_instr_name(m[1])}(mem[{m[2]}], {{{m[3]}-{m[4]}}}){sc} {m[5]}')
396*4bdc9457SAndroid Build Coastguard Worker        continue
397*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_REGLIST_CONSECT_WB, line)
398*4bdc9457SAndroid Build Coastguard Worker      if m:
399*4bdc9457SAndroid Build Coastguard Worker        instructions.append(
400*4bdc9457SAndroid Build Coastguard Worker            f'{fix_instr_name(m[1])}(mem[{m[2]}]++, {{{m[3]}-{m[4]}}}){sc} {m[5]}')
401*4bdc9457SAndroid Build Coastguard Worker        continue
402*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_REGLIST_INDIV_WB, line)
403*4bdc9457SAndroid Build Coastguard Worker      if m:
404*4bdc9457SAndroid Build Coastguard Worker        instructions.append(
405*4bdc9457SAndroid Build Coastguard Worker            f'{fix_instr_name(m[1])}(mem[{m[2]}]++, {{{m[3]}}}){sc} {m[4]}')
406*4bdc9457SAndroid Build Coastguard Worker        continue
407*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_B_IMM, line)
408*4bdc9457SAndroid Build Coastguard Worker      if m:
409*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}(l{m[2]}){sc} {m[4]}')
410*4bdc9457SAndroid Build Coastguard Worker        continue
411*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_B_REG_IMM_IMM , line)
412*4bdc9457SAndroid Build Coastguard Worker      if m:
413*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}({m[2]}, {m[3]}, l{m[4]}){sc} {m[6]}')
414*4bdc9457SAndroid Build Coastguard Worker        continue
415*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REGLIST_INDIV_MEMOP, line)
416*4bdc9457SAndroid Build Coastguard Worker      if m:
417*4bdc9457SAndroid Build Coastguard Worker        instructions.append(
418*4bdc9457SAndroid Build Coastguard Worker            f'{fix_instr_name(m[1])}({{{fix_regs(m[2])}}}, mem[{m[3]}]{maybe_wb(m[4])}){sc} {m[5]}'
419*4bdc9457SAndroid Build Coastguard Worker        )
420*4bdc9457SAndroid Build Coastguard Worker        continue
421*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REGLIST_INDIV_MEMOP_IMM, line)
422*4bdc9457SAndroid Build Coastguard Worker      if m:
423*4bdc9457SAndroid Build Coastguard Worker        instructions.append(
424*4bdc9457SAndroid Build Coastguard Worker            f'{fix_instr_name(m[1])}({{{fix_regs(m[2])}}}, mem[{m[3]}], {m[4]}){sc} {m[5]}'
425*4bdc9457SAndroid Build Coastguard Worker        )
426*4bdc9457SAndroid Build Coastguard Worker        continue
427*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REGLIST_CONSEC_MEMOP, line)
428*4bdc9457SAndroid Build Coastguard Worker      if m:
429*4bdc9457SAndroid Build Coastguard Worker        instructions.append(
430*4bdc9457SAndroid Build Coastguard Worker            f'{fix_instr_name(m[1])}({{{m[2]}-{m[3]}}}, mem[{m[4]}]{maybe_wb(m[5])}){sc} {m[6]}'
431*4bdc9457SAndroid Build Coastguard Worker        )
432*4bdc9457SAndroid Build Coastguard Worker        continue
433*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REGLIST_REPLICATE_MEMOP, line)
434*4bdc9457SAndroid Build Coastguard Worker      if m:
435*4bdc9457SAndroid Build Coastguard Worker        if m[5]:
436*4bdc9457SAndroid Build Coastguard Worker          instructions.append(
437*4bdc9457SAndroid Build Coastguard Worker              f'{fix_replicate_instruction(fix_instr_name(m[1]))}({{{remove_brackets(m[2])}}}, mem[{m[4]}]++){sc} {m[6]}'
438*4bdc9457SAndroid Build Coastguard Worker          )
439*4bdc9457SAndroid Build Coastguard Worker        else:
440*4bdc9457SAndroid Build Coastguard Worker          instructions.append(
441*4bdc9457SAndroid Build Coastguard Worker              f'{fix_replicate_instruction(fix_instr_name(m[1]))}({{{remove_brackets(m[2])}}}, mem[{m[4]}]){sc} {m[6]}'
442*4bdc9457SAndroid Build Coastguard Worker          )
443*4bdc9457SAndroid Build Coastguard Worker        continue
444*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REGLIST_INDEX_MEMOP, line)
445*4bdc9457SAndroid Build Coastguard Worker      if m:
446*4bdc9457SAndroid Build Coastguard Worker        instructions.append(
447*4bdc9457SAndroid Build Coastguard Worker            f'{fix_instr_name(m[1])}({{{m[2]}}}, mem[{m[3]}]{maybe_wb(m[4])}){sc} {m[5]}'
448*4bdc9457SAndroid Build Coastguard Worker        )
449*4bdc9457SAndroid Build Coastguard Worker        continue
450*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(P2ALIGN_RE, line)
451*4bdc9457SAndroid Build Coastguard Worker      if m:
452*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'align({1 << int(m[1])}){sc}')
453*4bdc9457SAndroid Build Coastguard Worker        continue
454*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_FPSCR, line)
455*4bdc9457SAndroid Build Coastguard Worker      if m:
456*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}({m[2]}, {m[3]}){sc} {m[4]}')
457*4bdc9457SAndroid Build Coastguard Worker        continue
458*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_PLD_MEMOP, line)
459*4bdc9457SAndroid Build Coastguard Worker      if m:
460*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}(k{m[2]}, mem[{m[3]}]){sc} {m[4]}')
461*4bdc9457SAndroid Build Coastguard Worker        continue
462*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_PLD_MEMOP_OFFSET, line)
463*4bdc9457SAndroid Build Coastguard Worker      if m:
464*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}(k{m[2]}, mem[{m[3]}, {m[4]}]){sc} {m[5]}')
465*4bdc9457SAndroid Build Coastguard Worker        continue
466*4bdc9457SAndroid Build Coastguard Worker      m = re.fullmatch(INSTR_REG_REG_REG_COND_RE, line)
467*4bdc9457SAndroid Build Coastguard Worker      if m:
468*4bdc9457SAndroid Build Coastguard Worker        instructions.append(f'{fix_instr_name(m[1])}({m[2]}, {m[3]}, {m[4]}, k{m[5]}){sc} {m[6]}')
469*4bdc9457SAndroid Build Coastguard Worker        continue
470*4bdc9457SAndroid Build Coastguard Worker
471*4bdc9457SAndroid Build Coastguard Worker      # Keep empty lines for formatting
472*4bdc9457SAndroid Build Coastguard Worker      if line.strip() == '':
473*4bdc9457SAndroid Build Coastguard Worker        instructions.append('')
474*4bdc9457SAndroid Build Coastguard Worker        continue
475*4bdc9457SAndroid Build Coastguard Worker
476*4bdc9457SAndroid Build Coastguard Worker      # Assembly directives that we don't are about.
477*4bdc9457SAndroid Build Coastguard Worker      if line.strip().startswith('.'):
478*4bdc9457SAndroid Build Coastguard Worker        continue
479*4bdc9457SAndroid Build Coastguard Worker
480*4bdc9457SAndroid Build Coastguard Worker      if line.startswith('END_FUNCTION'):
481*4bdc9457SAndroid Build Coastguard Worker        break
482*4bdc9457SAndroid Build Coastguard Worker
483*4bdc9457SAndroid Build Coastguard Worker      # All other lines are error.
484*4bdc9457SAndroid Build Coastguard Worker      print(f'ERROR: {line}', file=sys.stderr)
485*4bdc9457SAndroid Build Coastguard Worker      sys.exit(1)
486*4bdc9457SAndroid Build Coastguard Worker
487*4bdc9457SAndroid Build Coastguard Worker  # Actually emit the JIT codegen (to stdout).
488*4bdc9457SAndroid Build Coastguard Worker  for p in prologue:
489*4bdc9457SAndroid Build Coastguard Worker    print(p)
490*4bdc9457SAndroid Build Coastguard Worker
491*4bdc9457SAndroid Build Coastguard Worker
492*4bdc9457SAndroid Build Coastguard Worker  m = re.search('(\d+)x(\d+)', input_file)
493*4bdc9457SAndroid Build Coastguard Worker  mr = 0
494*4bdc9457SAndroid Build Coastguard Worker  nr = 0
495*4bdc9457SAndroid Build Coastguard Worker  if m:
496*4bdc9457SAndroid Build Coastguard Worker    mr = m[1]
497*4bdc9457SAndroid Build Coastguard Worker    nr = m[2]
498*4bdc9457SAndroid Build Coastguard Worker  labels_str = ', '.join(f'l{l}' for l in labels)
499*4bdc9457SAndroid Build Coastguard Worker  print(f'  assert(max_mr <= {mr});')
500*4bdc9457SAndroid Build Coastguard Worker  print(f'  assert(nc_mod_nr < {nr});')
501*4bdc9457SAndroid Build Coastguard Worker  print('  assert(kc != 0);')
502*4bdc9457SAndroid Build Coastguard Worker  print(f'  assert(kc % sizeof({ctype}) == 0);')
503*4bdc9457SAndroid Build Coastguard Worker  print()
504*4bdc9457SAndroid Build Coastguard Worker  print(f'  Label {labels_str};')
505*4bdc9457SAndroid Build Coastguard Worker  print()
506*4bdc9457SAndroid Build Coastguard Worker  if minmax:
507*4bdc9457SAndroid Build Coastguard Worker    print('  // const bool clamp_min = min != -std::numeric_limits<float>::infinity();')
508*4bdc9457SAndroid Build Coastguard Worker    print('  // const bool clamp_max = max != +std::numeric_limits<float>::infinity();')
509*4bdc9457SAndroid Build Coastguard Worker
510*4bdc9457SAndroid Build Coastguard Worker  indent = '  '
511*4bdc9457SAndroid Build Coastguard Worker  for i in instructions:
512*4bdc9457SAndroid Build Coastguard Worker    if i.strip().startswith('#'):
513*4bdc9457SAndroid Build Coastguard Worker      print(indent + fix_comments(i))
514*4bdc9457SAndroid Build Coastguard Worker    elif i.strip().startswith('//'):
515*4bdc9457SAndroid Build Coastguard Worker      print(indent + i)
516*4bdc9457SAndroid Build Coastguard Worker    elif i.strip() == '':
517*4bdc9457SAndroid Build Coastguard Worker      print()
518*4bdc9457SAndroid Build Coastguard Worker    else:
519*4bdc9457SAndroid Build Coastguard Worker      print(indent + (i).rstrip())
520*4bdc9457SAndroid Build Coastguard Worker  print(indent + 'align(16, AlignInstruction::kHlt);')
521*4bdc9457SAndroid Build Coastguard Worker
522*4bdc9457SAndroid Build Coastguard Worker  print('}')
523*4bdc9457SAndroid Build Coastguard Worker  print('}  // namespace')
524*4bdc9457SAndroid Build Coastguard Worker  print(f'}}  // {arch}')
525*4bdc9457SAndroid Build Coastguard Worker  print('}  // xnnpack')
526*4bdc9457SAndroid Build Coastguard Worker  print('')
527*4bdc9457SAndroid Build Coastguard Worker  if prfm:
528*4bdc9457SAndroid Build Coastguard Worker    print_generator_definition(kernel_type, remove_prfm_from_fn_name(fn_name), arch, minmax, prefetch='false, ')
529*4bdc9457SAndroid Build Coastguard Worker    print()
530*4bdc9457SAndroid Build Coastguard Worker    print_generator_definition(kernel_type, fn_name, arch, minmax, prefetch='true, ')
531*4bdc9457SAndroid Build Coastguard Worker  else:
532*4bdc9457SAndroid Build Coastguard Worker    print_generator_definition(kernel_type, fn_name, arch, minmax)
533*4bdc9457SAndroid Build Coastguard Worker
534*4bdc9457SAndroid Build Coastguard Worker
535*4bdc9457SAndroid Build Coastguard Workerdef print_generator_definition(kernel_type, fn_name, arch, minmax, prefetch=''):
536*4bdc9457SAndroid Build Coastguard Worker  if kernel_type == GEMM:
537*4bdc9457SAndroid Build Coastguard Worker    print(f'xnn_status {fix_fn_name(fn_name)}(xnn_code_buffer* code, size_t max_mr, size_t nc_mod_nr, size_t kc, const void* params) {{')
538*4bdc9457SAndroid Build Coastguard Worker  else:
539*4bdc9457SAndroid Build Coastguard Worker    print(f'xnn_status {fix_fn_name(fn_name)}(xnn_code_buffer* code, size_t max_mr, size_t nc_mod_nr, size_t kc, size_t ks, const void* params) {{')
540*4bdc9457SAndroid Build Coastguard Worker  print(f'  using namespace xnnpack::{arch};')
541*4bdc9457SAndroid Build Coastguard Worker  print('  Generator g(code);')
542*4bdc9457SAndroid Build Coastguard Worker  if minmax:
543*4bdc9457SAndroid Build Coastguard Worker    print('  assert(params != nullptr);')
544*4bdc9457SAndroid Build Coastguard Worker    print('  const jit_gemm_params* gemm_params = static_cast<const jit_gemm_params*>(params);')
545*4bdc9457SAndroid Build Coastguard Worker  if kernel_type == GEMM:
546*4bdc9457SAndroid Build Coastguard Worker    if minmax:
547*4bdc9457SAndroid Build Coastguard Worker      print(f'  g.generate({prefetch}max_mr, nc_mod_nr, kc, gemm_params->f32_minmax.min, gemm_params->f32_minmax.max);')
548*4bdc9457SAndroid Build Coastguard Worker    else:
549*4bdc9457SAndroid Build Coastguard Worker      print(f'  g.generate({prefetch}max_mr, nc_mod_nr, kc, nullptr);')
550*4bdc9457SAndroid Build Coastguard Worker  else:
551*4bdc9457SAndroid Build Coastguard Worker    if minmax:
552*4bdc9457SAndroid Build Coastguard Worker      print(f'  g.generate({prefetch}max_mr, nc_mod_nr, kc, ks, gemm_params->f32_minmax.min, gemm_params->f32_minmax.max);')
553*4bdc9457SAndroid Build Coastguard Worker    else:
554*4bdc9457SAndroid Build Coastguard Worker      print(f'  g.generate({prefetch}max_mr, nc_mod_nr, kc, ks, nullptr);')
555*4bdc9457SAndroid Build Coastguard Worker  print('  g.finalize();')
556*4bdc9457SAndroid Build Coastguard Worker  print('  if (g.error() != xnnpack::Error::kNoError) {')
557*4bdc9457SAndroid Build Coastguard Worker  print('    return xnn_status_invalid_state;')
558*4bdc9457SAndroid Build Coastguard Worker  print('  }')
559*4bdc9457SAndroid Build Coastguard Worker  print('  return xnn_status_success;')
560*4bdc9457SAndroid Build Coastguard Worker  print('}')
561*4bdc9457SAndroid Build Coastguard Worker
562*4bdc9457SAndroid Build Coastguard Worker
563*4bdc9457SAndroid Build Coastguard Workerif __name__ == '__main__':
564*4bdc9457SAndroid Build Coastguard Worker  parser = argparse.ArgumentParser(description='Convert assembly to to JIT C++, writes to stdout.')
565*4bdc9457SAndroid Build Coastguard Worker  parser.add_argument('input_file', help='Input assembly filename')
566*4bdc9457SAndroid Build Coastguard Worker  args = parser.parse_args()
567*4bdc9457SAndroid Build Coastguard Worker  main(args.input_file)
568