1## 2## Copyright(c) 2020-2024 Qualcomm Innovation Center, Inc. All Rights Reserved. 3## 4## This program is free software; you can redistribute it and/or modify 5## it under the terms of the GNU General Public License as published by 6## the Free Software Foundation; either version 2 of the License, or 7## (at your option) any later version. 8## 9## This program is distributed in the hope that it will be useful, 10## but WITHOUT ANY WARRANTY; without even the implied warranty of 11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12## GNU General Public License for more details. 13## 14## You should have received a copy of the GNU General Public License 15## along with this program; if not, see <http://www.gnu.org/licenses/>. 16## 17 18hexagon_ss = ss.source_set() 19 20hex_common_py = 'hex_common.py' 21gen_tcg_h = meson.current_source_dir() / 'gen_tcg.h' 22gen_tcg_hvx_h = meson.current_source_dir() / 'gen_tcg_hvx.h' 23idef_parser_dir = meson.current_source_dir() / 'idef-parser' 24 25# 26# Step 1 27# We use a C program to create semantics_generated.pyinc 28# 29gen_semantics = executable( 30 'gen_semantics', 31 'gen_semantics.c', 32 native: true, build_by_default: false) 33 34semantics_generated = custom_target( 35 'semantics_generated.pyinc', 36 output: 'semantics_generated.pyinc', 37 command: [gen_semantics, '@OUTPUT@'], 38) 39hexagon_ss.add(semantics_generated) 40 41# 42# Step 2 43# We use Python scripts to generate the following files 44# tcg_func_table_generated.c.inc 45# printinsn_generated.h.inc 46# op_attribs_generated.h.inc 47# opcodes_def_generated.h.inc 48# 49tcg_func_table_generated = custom_target( 50 'tcg_func_table_generated.c.inc', 51 output: 'tcg_func_table_generated.c.inc', 52 depends: [semantics_generated], 53 depend_files: [hex_common_py], 54 command: [python, files('gen_tcg_func_table.py'), semantics_generated, '@OUTPUT@'], 55) 56hexagon_ss.add(tcg_func_table_generated) 57 58printinsn_generated = custom_target( 59 'printinsn_generated.h.inc', 60 output: 'printinsn_generated.h.inc', 61 depends: [semantics_generated], 62 depend_files: [hex_common_py], 63 command: [python, files('gen_printinsn.py'), semantics_generated, '@OUTPUT@'], 64) 65hexagon_ss.add(printinsn_generated) 66 67op_attribs_generated = custom_target( 68 'op_attribs_generated.h.inc', 69 output: 'op_attribs_generated.h.inc', 70 depends: [semantics_generated], 71 depend_files: [hex_common_py], 72 command: [python, files('gen_op_attribs.py'), semantics_generated, '@OUTPUT@'], 73) 74hexagon_ss.add(op_attribs_generated) 75 76opcodes_def_generated = custom_target( 77 'opcodes_def_generated.h.inc', 78 output: 'opcodes_def_generated.h.inc', 79 depends: [semantics_generated], 80 depend_files: [hex_common_py], 81 command: [python, files('gen_opcodes_def.py'), semantics_generated, '@OUTPUT@'], 82) 83hexagon_ss.add(opcodes_def_generated) 84 85# 86# Step 3 87# We use a C program to create iset.py which is imported into dectree.py 88# to create the decode tree 89# 90gen_dectree_import = executable( 91 'gen_dectree_import', 92 'gen_dectree_import.c', opcodes_def_generated, 93 native: true, build_by_default: false) 94 95iset_py = custom_target( 96 'iset.py', 97 output: 'iset.py', 98 command: [gen_dectree_import, '@OUTPUT@'], 99) 100hexagon_ss.add(iset_py) 101 102# 103# Step 4 104# Generate the input to the QEMU decodetree.py script 105# 106normal_decode_generated = custom_target( 107 'normal_decode_generated', 108 output: 'normal_decode_generated', 109 depends: [iset_py, semantics_generated], 110 env: {'PYTHONPATH': meson.current_build_dir()}, 111 command: [python, files('gen_decodetree.py'), semantics_generated, 'NORMAL', '@OUTPUT@'], 112) 113hexagon_ss.add(normal_decode_generated) 114 115hvx_decode_generated = custom_target( 116 'hvx_decode_generated', 117 output: 'hvx_decode_generated', 118 depends: [iset_py, semantics_generated], 119 env: {'PYTHONPATH': meson.current_build_dir()}, 120 command: [python, files('gen_decodetree.py'), semantics_generated, 'EXT_mmvec', '@OUTPUT@'], 121) 122hexagon_ss.add(hvx_decode_generated) 123 124subinsn_a_decode_generated = custom_target( 125 'subinsn_a_decode_generated', 126 output: 'subinsn_a_decode_generated', 127 depends: [iset_py, semantics_generated], 128 env: {'PYTHONPATH': meson.current_build_dir()}, 129 command: [python, files('gen_decodetree.py'), semantics_generated, 'SUBINSN_A', '@OUTPUT@'], 130) 131hexagon_ss.add(subinsn_a_decode_generated) 132 133subinsn_l1_decode_generated = custom_target( 134 'subinsn_l1_decode_generated', 135 output: 'subinsn_l1_decode_generated', 136 depends: [iset_py, semantics_generated], 137 env: {'PYTHONPATH': meson.current_build_dir()}, 138 command: [python, files('gen_decodetree.py'), semantics_generated, 'SUBINSN_L1', '@OUTPUT@'], 139) 140hexagon_ss.add(subinsn_l1_decode_generated) 141 142subinsn_l2_decode_generated = custom_target( 143 'subinsn_l2_decode_generated', 144 output: 'subinsn_l2_decode_generated', 145 depends: [iset_py, semantics_generated], 146 env: {'PYTHONPATH': meson.current_build_dir()}, 147 command: [python, files('gen_decodetree.py'), semantics_generated, 'SUBINSN_L2', '@OUTPUT@'], 148) 149hexagon_ss.add(subinsn_l2_decode_generated) 150 151subinsn_s1_decode_generated = custom_target( 152 'subinsn_s1_decode_generated', 153 output: 'subinsn_s1_decode_generated', 154 depends: [iset_py, semantics_generated], 155 env: {'PYTHONPATH': meson.current_build_dir()}, 156 command: [python, files('gen_decodetree.py'), semantics_generated, 'SUBINSN_S1', '@OUTPUT@'], 157) 158hexagon_ss.add(subinsn_s1_decode_generated) 159 160subinsn_s2_decode_generated = custom_target( 161 'subinsn_s2_decode_generated', 162 output: 'subinsn_s2_decode_generated', 163 depends: [iset_py, semantics_generated], 164 env: {'PYTHONPATH': meson.current_build_dir()}, 165 command: [python, files('gen_decodetree.py'), semantics_generated, 'SUBINSN_S2', '@OUTPUT@'], 166) 167hexagon_ss.add(subinsn_s2_decode_generated) 168 169# 170# Run the QEMU decodetree.py script to produce the instruction decoder 171# 172decodetree_py = meson.current_source_dir() / '../../scripts/decodetree.py' 173decode_normal_generated = custom_target( 174 'decode_normal_generated.c.inc', 175 output: 'decode_normal_generated.c.inc', 176 input: normal_decode_generated, 177 env: {'PYTHONPATH': meson.current_build_dir()}, 178 command: [python, files(decodetree_py), normal_decode_generated, '--static-decode=decode_normal', '-o', '@OUTPUT@'], 179) 180hexagon_ss.add(decode_normal_generated) 181 182decode_hvx_generated = custom_target( 183 'decode_hvx_generated.c.inc', 184 output: 'decode_hvx_generated.c.inc', 185 input: hvx_decode_generated, 186 env: {'PYTHONPATH': meson.current_build_dir()}, 187 command: [python, files(decodetree_py), hvx_decode_generated, '--static-decode=decode_hvx', '-o', '@OUTPUT@'], 188) 189hexagon_ss.add(decode_hvx_generated) 190 191decode_subinsn_a_generated = custom_target( 192 'decode_subinsn_a_generated.c.inc', 193 output: 'decode_subinsn_a_generated.c.inc', 194 input: subinsn_a_decode_generated, 195 env: {'PYTHONPATH': meson.current_build_dir()}, 196 command: [python, files(decodetree_py), subinsn_a_decode_generated, ['--static-decode=decode_subinsn_a', '--insnwidth=16'], '-o', '@OUTPUT@'], 197) 198hexagon_ss.add(decode_subinsn_a_generated) 199 200decode_subinsn_l1_generated = custom_target( 201 'decode_subinsn_l1_generated.c.inc', 202 output: 'decode_subinsn_l1_generated.c.inc', 203 input: subinsn_l1_decode_generated, 204 env: {'PYTHONPATH': meson.current_build_dir()}, 205 command: [python, files(decodetree_py), subinsn_l1_decode_generated, ['--static-decode=decode_subinsn_l1', '--insnwidth=16'], '-o', '@OUTPUT@'], 206) 207hexagon_ss.add(decode_subinsn_l1_generated) 208 209decode_subinsn_l2_generated = custom_target( 210 'decode_subinsn_l2_generated.c.inc', 211 output: 'decode_subinsn_l2_generated.c.inc', 212 input: subinsn_l2_decode_generated, 213 env: {'PYTHONPATH': meson.current_build_dir()}, 214 command: [python, files(decodetree_py), subinsn_l2_decode_generated, ['--static-decode=decode_subinsn_l2', '--insnwidth=16'], '-o', '@OUTPUT@'], 215) 216hexagon_ss.add(decode_subinsn_l2_generated) 217 218decode_subinsn_s1_generated = custom_target( 219 'decode_subinsn_s1_generated.c.inc', 220 output: 'decode_subinsn_s1_generated.c.inc', 221 input: subinsn_s1_decode_generated, 222 env: {'PYTHONPATH': meson.current_build_dir()}, 223 command: [python, files(decodetree_py), subinsn_s1_decode_generated, ['--static-decode=decode_subinsn_s1', '--insnwidth=16'], '-o', '@OUTPUT@'], 224) 225hexagon_ss.add(decode_subinsn_s1_generated) 226 227decode_subinsn_s2_generated = custom_target( 228 'decode_subinsn_s2_generated.c.inc', 229 output: 'decode_subinsn_s2_generated.c.inc', 230 input: subinsn_s2_decode_generated, 231 env: {'PYTHONPATH': meson.current_build_dir()}, 232 command: [python, files(decodetree_py), subinsn_s2_decode_generated, ['--static-decode=decode_subinsn_s2', '--insnwidth=16'], '-o', '@OUTPUT@'], 233) 234hexagon_ss.add(decode_subinsn_s2_generated) 235 236# 237# Generate the trans_* functions that the decoder will use 238# 239decodetree_trans_funcs_generated = custom_target( 240 'decodetree_trans_funcs_generated.c.inc', 241 output: 'decodetree_trans_funcs_generated.c.inc', 242 depends: [iset_py, semantics_generated], 243 env: {'PYTHONPATH': meson.current_build_dir()}, 244 command: [python, files('gen_trans_funcs.py'), semantics_generated, '@OUTPUT@'], 245) 246hexagon_ss.add(decodetree_trans_funcs_generated) 247 248hexagon_ss.add(files( 249 'cpu.c', 250 'translate.c', 251 'op_helper.c', 252 'gdbstub.c', 253 'genptr.c', 254 'reg_fields.c', 255 'decode.c', 256 'iclass.c', 257 'opcodes.c', 258 'printinsn.c', 259 'arch.c', 260 'fma_emu.c', 261 'mmvec/decode_ext_mmvec.c', 262 'mmvec/system_ext_mmvec.c', 263)) 264 265# 266# Step 4.5 267# We use flex/bison based idef-parser to generate TCG code for a lot 268# of instructions. idef-parser outputs 269# idef-generated-emitter.c 270# idef-generated-emitter.h.inc 271# idef-generated-enabled-instructions 272# 273idef_parser_enabled = get_option('hexagon_idef_parser') 274if idef_parser_enabled and 'hexagon-linux-user' in target_dirs 275 idef_parser_input_generated = custom_target( 276 'idef_parser_input.h.inc', 277 output: 'idef_parser_input.h.inc', 278 depends: [semantics_generated], 279 depend_files: [hex_common_py], 280 command: [python, files('gen_idef_parser_funcs.py'), semantics_generated, '@OUTPUT@'], 281 ) 282 283 compiler = meson.get_compiler('c').get_id() 284 preprocessed_idef_parser_input_generated = custom_target( 285 'idef_parser_input.preprocessed.h.inc', 286 output: 'idef_parser_input.preprocessed.h.inc', 287 input: idef_parser_input_generated, 288 depend_files: [idef_parser_dir / 'macros.h.inc'], 289 command: [compiler, '-x', 'c', '-E', '-I', idef_parser_dir, '-o', '@OUTPUT@', '@INPUT@'], 290 ) 291 292 flex = generator( 293 find_program('flex'), 294 output: ['@BASENAME@.yy.c', '@BASENAME@.yy.h'], 295 arguments: ['-o', '@OUTPUT0@', '--header-file=@OUTPUT1@', '@INPUT@'] 296 ) 297 298 bison = generator( 299 find_program('bison', version: '>=3.0'), 300 output: ['@BASENAME@.tab.c', '@BASENAME@.tab.h'], 301 arguments: ['@INPUT@', '--defines=@OUTPUT1@', '--output=@OUTPUT0@'] 302 ) 303 304 glib_dep = dependency('glib-2.0', native: true, static: false) 305 306 idef_parser = executable( 307 'idef-parser', 308 [flex.process(idef_parser_dir / 'idef-parser.lex'), 309 bison.process(idef_parser_dir / 'idef-parser.y'), 310 idef_parser_dir / 'parser-helpers.c'], 311 include_directories: ['idef-parser', '../../include/'], 312 dependencies: [glib_dep], 313 native: true 314 ) 315 316 idef_generated_tcg = custom_target( 317 'idef-generated-tcg', 318 output: ['idef-generated-emitter.c', 319 'idef-generated-emitter.h.inc', 320 'idef-generated-enabled-instructions'], 321 input: preprocessed_idef_parser_input_generated, 322 depend_files: [hex_common_py], 323 command: [idef_parser, '@INPUT@', '@OUTPUT0@', '@OUTPUT1@', '@OUTPUT2@'] 324 ) 325 326 indent = find_program('indent', required: false) 327 if indent.found() and host_os == 'linux' 328 idef_generated_tcg_c = custom_target( 329 'indent', 330 input: idef_generated_tcg[0], 331 output: 'idef-generated-emitter.indented.c', 332 command: [indent, '-linux', '@INPUT@', '-o', '@OUTPUT@'] 333 ) 334 else 335 idef_generated_tcg_c = custom_target( 336 'copy', 337 input: idef_generated_tcg[0], 338 output: 'idef-generated-emitter.indented.c', 339 command: ['cp', '@INPUT@', '@OUTPUT@'] 340 ) 341 endif 342 343 idef_generated_list = idef_generated_tcg[2].full_path() 344 345 hexagon_ss.add(idef_generated_tcg_c) 346 347 # Setup input and dependencies for the next step, this depends on whether or 348 # not idef-parser is enabled 349 helper_dep = [semantics_generated, idef_generated_tcg_c, idef_generated_tcg] 350 helper_in = [semantics_generated, gen_tcg_h, gen_tcg_hvx_h, '--idef-parser', idef_generated_list] 351else 352 # Setup input and dependencies for the next step, this depends on whether or 353 # not idef-parser is enabled 354 helper_dep = [semantics_generated] 355 helper_in = [semantics_generated, gen_tcg_h, gen_tcg_hvx_h] 356endif 357 358# 359# Step 5 360# We use Python scripts to generate the following files 361# helper_protos_generated.h.inc 362# helper_funcs_generated.c.inc 363# tcg_funcs_generated.c.inc 364# 365helper_protos_generated = custom_target( 366 'helper_protos_generated.h.inc', 367 output: 'helper_protos_generated.h.inc', 368 depends: helper_dep, 369 depend_files: [hex_common_py, gen_tcg_h, gen_tcg_hvx_h], 370 command: [python, files('gen_helper_protos.py'), helper_in, '@OUTPUT@'], 371) 372hexagon_ss.add(helper_protos_generated) 373 374helper_funcs_generated = custom_target( 375 'helper_funcs_generated.c.inc', 376 output: 'helper_funcs_generated.c.inc', 377 depends: helper_dep, 378 depend_files: [hex_common_py, gen_tcg_h, gen_tcg_hvx_h], 379 command: [python, files('gen_helper_funcs.py'), helper_in, '@OUTPUT@'], 380) 381hexagon_ss.add(helper_funcs_generated) 382 383tcg_funcs_generated = custom_target( 384 'tcg_funcs_generated.c.inc', 385 output: 'tcg_funcs_generated.c.inc', 386 depends: helper_dep, 387 depend_files: [hex_common_py, gen_tcg_h, gen_tcg_hvx_h], 388 command: [python, files('gen_tcg_funcs.py'), helper_in, '@OUTPUT@'], 389) 390hexagon_ss.add(tcg_funcs_generated) 391 392analyze_funcs_generated = custom_target( 393 'analyze_funcs_generated.c.inc', 394 output: 'analyze_funcs_generated.c.inc', 395 depends: helper_dep, 396 depend_files: [hex_common_py, gen_tcg_h, gen_tcg_hvx_h], 397 command: [python, files('gen_analyze_funcs.py'), helper_in, '@OUTPUT@'], 398) 399hexagon_ss.add(analyze_funcs_generated) 400 401target_arch += {'hexagon': hexagon_ss} 402