featuregen.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import subprocess
  2. import tempfile
  3. import os
  4. import sys
  5. archs = [
  6. ("amd64", "linux_amd64", "x86_64-pc-linux-gnu", [], []),
  7. ("i386", "linux_i386", "i386-pc-linux-gnu", [], []),
  8. ("arm32", "linux_arm32", "arm-linux-gnu", [], []),
  9. ("arm64", "linux_arm64", "aarch64-linux-elf", [], []),
  10. ("wasm32", "js_wasm32", "wasm32-js-js", [], []),
  11. ("wasm64p32", "js_wasm64p32", "wasm32-js-js", [], []),
  12. ("riscv64", "linux_riscv64", "riscv64-linux-gnu", [], []),
  13. ];
  14. SEEKING_CPUS = 0
  15. PARSING_CPUS = 1
  16. PARSING_FEATURES = 2
  17. with tempfile.NamedTemporaryFile(suffix=".odin", delete=True) as temp_file:
  18. temp_file.write(b"package main\n")
  19. for arch, target, triple, cpus, features in archs:
  20. cmd = ["odin", "build", temp_file.name, "-file", "-build-mode:llvm", "-out:temp", "-target-features:\"help\"", f"-target:\"{target}\""]
  21. process = subprocess.Popen(cmd, stderr=subprocess.PIPE, text=True)
  22. state = SEEKING_CPUS
  23. for line in process.stderr:
  24. if state == SEEKING_CPUS:
  25. if line == "Available CPUs for this target:\n":
  26. state = PARSING_CPUS
  27. elif state == PARSING_CPUS:
  28. if line == "Available features for this target:\n":
  29. state = PARSING_FEATURES
  30. continue
  31. parts = line.split(" -", maxsplit=1)
  32. if len(parts) < 2:
  33. continue
  34. cpu = parts[0].strip()
  35. cpus.append(cpu)
  36. elif state == PARSING_FEATURES:
  37. if line == "\n" and len(features) > 0:
  38. break
  39. parts = line.split(" -", maxsplit=1)
  40. if len(parts) < 2:
  41. continue
  42. feature = parts[0].strip()
  43. features.append(feature)
  44. process.wait()
  45. if process.returncode != 0:
  46. print(f"odin build returned with non-zero exit code {process.returncode}")
  47. sys.exit(1)
  48. os.remove("temp.ll")
  49. def print_default_features(triple, microarch):
  50. cmd = ["./featuregen", triple, microarch]
  51. process = subprocess.Popen(cmd, stdout=subprocess.PIPE, text=True)
  52. first = True
  53. for line in process.stdout:
  54. print("" if first else ",", line.strip(), sep="", end="")
  55. first = False
  56. process.wait()
  57. if process.returncode != 0:
  58. print(f"featuregen returned with non-zero exit code {process.returncode}")
  59. sys.exit(1)
  60. print("// Generated with the featuregen script in `misc/featuregen`")
  61. print("gb_global String target_microarch_list[TargetArch_COUNT] = {")
  62. print("\t// TargetArch_Invalid:")
  63. print('\tstr_lit(""),')
  64. for arch, target, triple, cpus, features in archs:
  65. print(f"\t// TargetArch_{arch}:")
  66. cpus_str = ','.join(cpus)
  67. print(f'\tstr_lit("{cpus_str}"),')
  68. print("};")
  69. print("")
  70. print("// Generated with the featuregen script in `misc/featuregen`")
  71. print("gb_global String target_features_list[TargetArch_COUNT] = {")
  72. print("\t// TargetArch_Invalid:")
  73. print('\tstr_lit(""),')
  74. for arch, target, triple, cpus, features in archs:
  75. print(f"\t// TargetArch_{arch}:")
  76. features_str = ','.join(features)
  77. print(f'\tstr_lit("{features_str}"),')
  78. print("};")
  79. print("")
  80. print("// Generated with the featuregen script in `misc/featuregen`")
  81. print("gb_global int target_microarch_counts[TargetArch_COUNT] = {")
  82. print("\t// TargetArch_Invalid:")
  83. print("\t0,")
  84. for arch, target, triple, cpus, feature in archs:
  85. print(f"\t// TargetArch_{arch}:")
  86. print(f"\t{len(cpus)},")
  87. print("};")
  88. print("")
  89. print("// Generated with the featuregen script in `misc/featuregen`")
  90. print("gb_global MicroarchFeatureList microarch_features_list[] = {")
  91. for arch, target, triple, cpus, features in archs:
  92. print(f"\t// TargetArch_{arch}:")
  93. for cpu in cpus:
  94. print(f'\t{{ str_lit("{cpu}"), str_lit("', end="")
  95. print_default_features(triple, cpu)
  96. print('") },')
  97. print("};")