tcc 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +35 -0
  3. data/README.md +196 -0
  4. data/ext/tcc/extconf.rb +25 -0
  5. data/ext/tcc/tcc-0.9.26.patch +30 -0
  6. data/ext/tcc/tcc-0.9.26/COPYING +504 -0
  7. data/ext/tcc/tcc-0.9.26/Changelog +396 -0
  8. data/ext/tcc/tcc-0.9.26/Makefile +349 -0
  9. data/ext/tcc/tcc-0.9.26/README +101 -0
  10. data/ext/tcc/tcc-0.9.26/TODO +93 -0
  11. data/ext/tcc/tcc-0.9.26/VERSION +1 -0
  12. data/ext/tcc/tcc-0.9.26/arm-gen.c +2005 -0
  13. data/ext/tcc/tcc-0.9.26/c67-gen.c +2560 -0
  14. data/ext/tcc/tcc-0.9.26/coff.h +446 -0
  15. data/ext/tcc/tcc-0.9.26/config.h +8 -0
  16. data/ext/tcc/tcc-0.9.26/config.mak +28 -0
  17. data/ext/tcc/tcc-0.9.26/config.texi +1 -0
  18. data/ext/tcc/tcc-0.9.26/configure +540 -0
  19. data/ext/tcc/tcc-0.9.26/conftest.c +71 -0
  20. data/ext/tcc/tcc-0.9.26/elf.h +1731 -0
  21. data/ext/tcc/tcc-0.9.26/examples/ex1.c +8 -0
  22. data/ext/tcc/tcc-0.9.26/examples/ex2.c +98 -0
  23. data/ext/tcc/tcc-0.9.26/examples/ex3.c +24 -0
  24. data/ext/tcc/tcc-0.9.26/examples/ex4.c +26 -0
  25. data/ext/tcc/tcc-0.9.26/examples/ex5.c +8 -0
  26. data/ext/tcc/tcc-0.9.26/i386-asm.c +1498 -0
  27. data/ext/tcc/tcc-0.9.26/i386-asm.h +473 -0
  28. data/ext/tcc/tcc-0.9.26/i386-gen.c +1096 -0
  29. data/ext/tcc/tcc-0.9.26/i386-tok.h +243 -0
  30. data/ext/tcc/tcc-0.9.26/il-gen.c +667 -0
  31. data/ext/tcc/tcc-0.9.26/il-opcodes.h +251 -0
  32. data/ext/tcc/tcc-0.9.26/include/float.h +57 -0
  33. data/ext/tcc/tcc-0.9.26/include/stdarg.h +41 -0
  34. data/ext/tcc/tcc-0.9.26/include/stdbool.h +10 -0
  35. data/ext/tcc/tcc-0.9.26/include/stddef.h +28 -0
  36. data/ext/tcc/tcc-0.9.26/include/tcclib.h +78 -0
  37. data/ext/tcc/tcc-0.9.26/include/varargs.h +12 -0
  38. data/ext/tcc/tcc-0.9.26/lib/Makefile +102 -0
  39. data/ext/tcc/tcc-0.9.26/lib/alloca86-bt.S +47 -0
  40. data/ext/tcc/tcc-0.9.26/lib/alloca86.S +35 -0
  41. data/ext/tcc/tcc-0.9.26/lib/alloca86_64.S +42 -0
  42. data/ext/tcc/tcc-0.9.26/lib/bcheck.c +875 -0
  43. data/ext/tcc/tcc-0.9.26/lib/libtcc1.c +691 -0
  44. data/ext/tcc/tcc-0.9.26/libtcc.c +1941 -0
  45. data/ext/tcc/tcc-0.9.26/libtcc.h +103 -0
  46. data/ext/tcc/tcc-0.9.26/stab.def +234 -0
  47. data/ext/tcc/tcc-0.9.26/stab.h +17 -0
  48. data/ext/tcc/tcc-0.9.26/tcc-doc.html +2332 -0
  49. data/ext/tcc/tcc-0.9.26/tcc-doc.info +1151 -0
  50. data/ext/tcc/tcc-0.9.26/tcc-doc.texi +1268 -0
  51. data/ext/tcc/tcc-0.9.26/tcc.1 +415 -0
  52. data/ext/tcc/tcc-0.9.26/tcc.c +352 -0
  53. data/ext/tcc/tcc-0.9.26/tcc.h +1379 -0
  54. data/ext/tcc/tcc-0.9.26/tccasm.c +1118 -0
  55. data/ext/tcc/tcc-0.9.26/tcccoff.c +948 -0
  56. data/ext/tcc/tcc-0.9.26/tccelf.c +3129 -0
  57. data/ext/tcc/tcc-0.9.26/tccgen.c +5841 -0
  58. data/ext/tcc/tcc-0.9.26/tccpe.c +1887 -0
  59. data/ext/tcc/tcc-0.9.26/tccpp.c +3128 -0
  60. data/ext/tcc/tcc-0.9.26/tccrun.c +737 -0
  61. data/ext/tcc/tcc-0.9.26/tcctok.h +278 -0
  62. data/ext/tcc/tcc-0.9.26/tests/Makefile +199 -0
  63. data/ext/tcc/tcc-0.9.26/tests/asmtest.S +609 -0
  64. data/ext/tcc/tcc-0.9.26/tests/boundtest.c +233 -0
  65. data/ext/tcc/tcc-0.9.26/tests/gcctestsuite.sh +33 -0
  66. data/ext/tcc/tcc-0.9.26/tests/libtcc_test.c +76 -0
  67. data/ext/tcc/tcc-0.9.26/tests/tcctest.c +2713 -0
  68. data/ext/tcc/tcc-0.9.26/tests/tests2/00_assignment.c +18 -0
  69. data/ext/tcc/tcc-0.9.26/tests/tests2/00_assignment.expect +3 -0
  70. data/ext/tcc/tcc-0.9.26/tests/tests2/01_comment.c +14 -0
  71. data/ext/tcc/tcc-0.9.26/tests/tests2/01_comment.expect +5 -0
  72. data/ext/tcc/tcc-0.9.26/tests/tests2/02_printf.c +18 -0
  73. data/ext/tcc/tcc-0.9.26/tests/tests2/02_printf.expect +15 -0
  74. data/ext/tcc/tcc-0.9.26/tests/tests2/03_struct.c +31 -0
  75. data/ext/tcc/tcc-0.9.26/tests/tests2/03_struct.expect +6 -0
  76. data/ext/tcc/tcc-0.9.26/tests/tests2/04_for.c +15 -0
  77. data/ext/tcc/tcc-0.9.26/tests/tests2/04_for.expect +10 -0
  78. data/ext/tcc/tcc-0.9.26/tests/tests2/05_array.c +21 -0
  79. data/ext/tcc/tcc-0.9.26/tests/tests2/05_array.expect +10 -0
  80. data/ext/tcc/tcc-0.9.26/tests/tests2/06_case.c +29 -0
  81. data/ext/tcc/tcc-0.9.26/tests/tests2/06_case.expect +8 -0
  82. data/ext/tcc/tcc-0.9.26/tests/tests2/07_function.c +30 -0
  83. data/ext/tcc/tcc-0.9.26/tests/tests2/07_function.expect +4 -0
  84. data/ext/tcc/tcc-0.9.26/tests/tests2/08_while.c +24 -0
  85. data/ext/tcc/tcc-0.9.26/tests/tests2/08_while.expect +11 -0
  86. data/ext/tcc/tcc-0.9.26/tests/tests2/09_do_while.c +24 -0
  87. data/ext/tcc/tcc-0.9.26/tests/tests2/09_do_while.expect +11 -0
  88. data/ext/tcc/tcc-0.9.26/tests/tests2/10_pointer.c +40 -0
  89. data/ext/tcc/tcc-0.9.26/tests/tests2/10_pointer.expect +8 -0
  90. data/ext/tcc/tcc-0.9.26/tests/tests2/11_precedence.c +40 -0
  91. data/ext/tcc/tcc-0.9.26/tests/tests2/11_precedence.expect +15 -0
  92. data/ext/tcc/tcc-0.9.26/tests/tests2/12_hashdefine.c +14 -0
  93. data/ext/tcc/tcc-0.9.26/tests/tests2/12_hashdefine.expect +2 -0
  94. data/ext/tcc/tcc-0.9.26/tests/tests2/13_integer_literals.c +20 -0
  95. data/ext/tcc/tcc-0.9.26/tests/tests2/13_integer_literals.expect +5 -0
  96. data/ext/tcc/tcc-0.9.26/tests/tests2/14_if.c +21 -0
  97. data/ext/tcc/tcc-0.9.26/tests/tests2/14_if.expect +2 -0
  98. data/ext/tcc/tcc-0.9.26/tests/tests2/15_recursion.c +21 -0
  99. data/ext/tcc/tcc-0.9.26/tests/tests2/15_recursion.expect +10 -0
  100. data/ext/tcc/tcc-0.9.26/tests/tests2/16_nesting.c +21 -0
  101. data/ext/tcc/tcc-0.9.26/tests/tests2/16_nesting.expect +18 -0
  102. data/ext/tcc/tcc-0.9.26/tests/tests2/17_enum.c +29 -0
  103. data/ext/tcc/tcc-0.9.26/tests/tests2/17_enum.expect +3 -0
  104. data/ext/tcc/tcc-0.9.26/tests/tests2/18_include.c +12 -0
  105. data/ext/tcc/tcc-0.9.26/tests/tests2/18_include.expect +3 -0
  106. data/ext/tcc/tcc-0.9.26/tests/tests2/18_include.h +1 -0
  107. data/ext/tcc/tcc-0.9.26/tests/tests2/19_pointer_arithmetic.c +28 -0
  108. data/ext/tcc/tcc-0.9.26/tests/tests2/19_pointer_arithmetic.expect +3 -0
  109. data/ext/tcc/tcc-0.9.26/tests/tests2/20_pointer_comparison.c +24 -0
  110. data/ext/tcc/tcc-0.9.26/tests/tests2/20_pointer_comparison.expect +6 -0
  111. data/ext/tcc/tcc-0.9.26/tests/tests2/21_char_array.c +33 -0
  112. data/ext/tcc/tcc-0.9.26/tests/tests2/21_char_array.expect +7 -0
  113. data/ext/tcc/tcc-0.9.26/tests/tests2/22_floating_point.c +50 -0
  114. data/ext/tcc/tcc-0.9.26/tests/tests2/22_floating_point.expect +16 -0
  115. data/ext/tcc/tcc-0.9.26/tests/tests2/23_type_coercion.c +54 -0
  116. data/ext/tcc/tcc-0.9.26/tests/tests2/23_type_coercion.expect +12 -0
  117. data/ext/tcc/tcc-0.9.26/tests/tests2/24_math_library.c +28 -0
  118. data/ext/tcc/tcc-0.9.26/tests/tests2/24_math_library.expect +18 -0
  119. data/ext/tcc/tcc-0.9.26/tests/tests2/25_quicksort.c +83 -0
  120. data/ext/tcc/tcc-0.9.26/tests/tests2/25_quicksort.expect +2 -0
  121. data/ext/tcc/tcc-0.9.26/tests/tests2/26_character_constants.c +17 -0
  122. data/ext/tcc/tcc-0.9.26/tests/tests2/26_character_constants.expect +8 -0
  123. data/ext/tcc/tcc-0.9.26/tests/tests2/27_sizeof.c +16 -0
  124. data/ext/tcc/tcc-0.9.26/tests/tests2/27_sizeof.expect +3 -0
  125. data/ext/tcc/tcc-0.9.26/tests/tests2/28_strings.c +46 -0
  126. data/ext/tcc/tcc-0.9.26/tests/tests2/28_strings.expect +19 -0
  127. data/ext/tcc/tcc-0.9.26/tests/tests2/29_array_address.c +13 -0
  128. data/ext/tcc/tcc-0.9.26/tests/tests2/29_array_address.expect +1 -0
  129. data/ext/tcc/tcc-0.9.26/tests/tests2/30_hanoi.c +122 -0
  130. data/ext/tcc/tcc-0.9.26/tests/tests2/30_hanoi.expect +71 -0
  131. data/ext/tcc/tcc-0.9.26/tests/tests2/31_args.c +14 -0
  132. data/ext/tcc/tcc-0.9.26/tests/tests2/31_args.expect +7 -0
  133. data/ext/tcc/tcc-0.9.26/tests/tests2/32_led.c +266 -0
  134. data/ext/tcc/tcc-0.9.26/tests/tests2/32_led.expect +4 -0
  135. data/ext/tcc/tcc-0.9.26/tests/tests2/33_ternary_op.c +15 -0
  136. data/ext/tcc/tcc-0.9.26/tests/tests2/33_ternary_op.expect +10 -0
  137. data/ext/tcc/tcc-0.9.26/tests/tests2/34_array_assignment.c +23 -0
  138. data/ext/tcc/tcc-0.9.26/tests/tests2/34_array_assignment.expect +2 -0
  139. data/ext/tcc/tcc-0.9.26/tests/tests2/35_sizeof.c +14 -0
  140. data/ext/tcc/tcc-0.9.26/tests/tests2/35_sizeof.expect +2 -0
  141. data/ext/tcc/tcc-0.9.26/tests/tests2/36_array_initialisers.c +21 -0
  142. data/ext/tcc/tcc-0.9.26/tests/tests2/36_array_initialisers.expect +20 -0
  143. data/ext/tcc/tcc-0.9.26/tests/tests2/37_sprintf.c +17 -0
  144. data/ext/tcc/tcc-0.9.26/tests/tests2/37_sprintf.expect +20 -0
  145. data/ext/tcc/tcc-0.9.26/tests/tests2/38_multiple_array_index.c +32 -0
  146. data/ext/tcc/tcc-0.9.26/tests/tests2/38_multiple_array_index.expect +4 -0
  147. data/ext/tcc/tcc-0.9.26/tests/tests2/39_typedef.c +31 -0
  148. data/ext/tcc/tcc-0.9.26/tests/tests2/39_typedef.expect +3 -0
  149. data/ext/tcc/tcc-0.9.26/tests/tests2/40_stdio.c +52 -0
  150. data/ext/tcc/tcc-0.9.26/tests/tests2/40_stdio.expect +27 -0
  151. data/ext/tcc/tcc-0.9.26/tests/tests2/41_hashif.c +85 -0
  152. data/ext/tcc/tcc-0.9.26/tests/tests2/41_hashif.expect +6 -0
  153. data/ext/tcc/tcc-0.9.26/tests/tests2/42_function_pointer.c +18 -0
  154. data/ext/tcc/tcc-0.9.26/tests/tests2/42_function_pointer.expect +2 -0
  155. data/ext/tcc/tcc-0.9.26/tests/tests2/43_void_param.c +15 -0
  156. data/ext/tcc/tcc-0.9.26/tests/tests2/43_void_param.expect +1 -0
  157. data/ext/tcc/tcc-0.9.26/tests/tests2/44_scoped_declarations.c +17 -0
  158. data/ext/tcc/tcc-0.9.26/tests/tests2/44_scoped_declarations.expect +1 -0
  159. data/ext/tcc/tcc-0.9.26/tests/tests2/45_empty_for.c +18 -0
  160. data/ext/tcc/tcc-0.9.26/tests/tests2/45_empty_for.expect +10 -0
  161. data/ext/tcc/tcc-0.9.26/tests/tests2/46_grep.c +564 -0
  162. data/ext/tcc/tcc-0.9.26/tests/tests2/47_switch_return.c +24 -0
  163. data/ext/tcc/tcc-0.9.26/tests/tests2/47_switch_return.expect +4 -0
  164. data/ext/tcc/tcc-0.9.26/tests/tests2/48_nested_break.c +26 -0
  165. data/ext/tcc/tcc-0.9.26/tests/tests2/48_nested_break.expect +1 -0
  166. data/ext/tcc/tcc-0.9.26/tests/tests2/49_bracket_evaluation.c +23 -0
  167. data/ext/tcc/tcc-0.9.26/tests/tests2/49_bracket_evaluation.expect +1 -0
  168. data/ext/tcc/tcc-0.9.26/tests/tests2/50_logical_second_arg.c +29 -0
  169. data/ext/tcc/tcc-0.9.26/tests/tests2/50_logical_second_arg.expect +20 -0
  170. data/ext/tcc/tcc-0.9.26/tests/tests2/51_static.c +30 -0
  171. data/ext/tcc/tcc-0.9.26/tests/tests2/51_static.expect +8 -0
  172. data/ext/tcc/tcc-0.9.26/tests/tests2/52_unnamed_enum.c +27 -0
  173. data/ext/tcc/tcc-0.9.26/tests/tests2/52_unnamed_enum.expect +9 -0
  174. data/ext/tcc/tcc-0.9.26/tests/tests2/54_goto.c +56 -0
  175. data/ext/tcc/tcc-0.9.26/tests/tests2/54_goto.expect +8 -0
  176. data/ext/tcc/tcc-0.9.26/tests/tests2/55_lshift_type.c +52 -0
  177. data/ext/tcc/tcc-0.9.26/tests/tests2/55_lshift_type.expect +1 -0
  178. data/ext/tcc/tcc-0.9.26/tests/tests2/LICENSE +37 -0
  179. data/ext/tcc/tcc-0.9.26/tests/tests2/Makefile +98 -0
  180. data/ext/tcc/tcc-0.9.26/texi2pod.pl +427 -0
  181. data/ext/tcc/tcc-0.9.26/win32/build-tcc.bat +60 -0
  182. data/ext/tcc/tcc-0.9.26/win32/examples/dll.c +12 -0
  183. data/ext/tcc/tcc-0.9.26/win32/examples/fib.c +23 -0
  184. data/ext/tcc/tcc-0.9.26/win32/examples/hello_dll.c +19 -0
  185. data/ext/tcc/tcc-0.9.26/win32/examples/hello_win.c +163 -0
  186. data/ext/tcc/tcc-0.9.26/win32/include/_mingw.h +139 -0
  187. data/ext/tcc/tcc-0.9.26/win32/include/assert.h +54 -0
  188. data/ext/tcc/tcc-0.9.26/win32/include/conio.h +409 -0
  189. data/ext/tcc/tcc-0.9.26/win32/include/ctype.h +281 -0
  190. data/ext/tcc/tcc-0.9.26/win32/include/dir.h +31 -0
  191. data/ext/tcc/tcc-0.9.26/win32/include/direct.h +68 -0
  192. data/ext/tcc/tcc-0.9.26/win32/include/dirent.h +135 -0
  193. data/ext/tcc/tcc-0.9.26/win32/include/dos.h +55 -0
  194. data/ext/tcc/tcc-0.9.26/win32/include/errno.h +75 -0
  195. data/ext/tcc/tcc-0.9.26/win32/include/excpt.h +123 -0
  196. data/ext/tcc/tcc-0.9.26/win32/include/fcntl.h +52 -0
  197. data/ext/tcc/tcc-0.9.26/win32/include/fenv.h +108 -0
  198. data/ext/tcc/tcc-0.9.26/win32/include/inttypes.h +297 -0
  199. data/ext/tcc/tcc-0.9.26/win32/include/io.h +418 -0
  200. data/ext/tcc/tcc-0.9.26/win32/include/limits.h +111 -0
  201. data/ext/tcc/tcc-0.9.26/win32/include/locale.h +91 -0
  202. data/ext/tcc/tcc-0.9.26/win32/include/malloc.h +175 -0
  203. data/ext/tcc/tcc-0.9.26/win32/include/math.h +777 -0
  204. data/ext/tcc/tcc-0.9.26/win32/include/mem.h +13 -0
  205. data/ext/tcc/tcc-0.9.26/win32/include/memory.h +40 -0
  206. data/ext/tcc/tcc-0.9.26/win32/include/process.h +176 -0
  207. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/conio_s.h +42 -0
  208. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/crtdbg_s.h +19 -0
  209. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/io_s.h +33 -0
  210. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/mbstring_s.h +52 -0
  211. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/search_s.h +25 -0
  212. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/stdio_s.h +145 -0
  213. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/stdlib_s.h +67 -0
  214. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/stralign_s.h +30 -0
  215. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/string_s.h +41 -0
  216. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/sys/timeb_s.h +34 -0
  217. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/tchar_s.h +266 -0
  218. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/time_s.h +61 -0
  219. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/wchar_s.h +128 -0
  220. data/ext/tcc/tcc-0.9.26/win32/include/setjmp.h +160 -0
  221. data/ext/tcc/tcc-0.9.26/win32/include/share.h +28 -0
  222. data/ext/tcc/tcc-0.9.26/win32/include/signal.h +63 -0
  223. data/ext/tcc/tcc-0.9.26/win32/include/stdint.h +209 -0
  224. data/ext/tcc/tcc-0.9.26/win32/include/stdio.h +429 -0
  225. data/ext/tcc/tcc-0.9.26/win32/include/stdlib.h +580 -0
  226. data/ext/tcc/tcc-0.9.26/win32/include/string.h +164 -0
  227. data/ext/tcc/tcc-0.9.26/win32/include/sys/fcntl.h +13 -0
  228. data/ext/tcc/tcc-0.9.26/win32/include/sys/file.h +14 -0
  229. data/ext/tcc/tcc-0.9.26/win32/include/sys/locking.h +30 -0
  230. data/ext/tcc/tcc-0.9.26/win32/include/sys/stat.h +290 -0
  231. data/ext/tcc/tcc-0.9.26/win32/include/sys/time.h +69 -0
  232. data/ext/tcc/tcc-0.9.26/win32/include/sys/timeb.h +133 -0
  233. data/ext/tcc/tcc-0.9.26/win32/include/sys/types.h +118 -0
  234. data/ext/tcc/tcc-0.9.26/win32/include/sys/unistd.h +14 -0
  235. data/ext/tcc/tcc-0.9.26/win32/include/sys/utime.h +146 -0
  236. data/ext/tcc/tcc-0.9.26/win32/include/tchar.h +1102 -0
  237. data/ext/tcc/tcc-0.9.26/win32/include/time.h +287 -0
  238. data/ext/tcc/tcc-0.9.26/win32/include/vadefs.h +11 -0
  239. data/ext/tcc/tcc-0.9.26/win32/include/values.h +4 -0
  240. data/ext/tcc/tcc-0.9.26/win32/include/wchar.h +871 -0
  241. data/ext/tcc/tcc-0.9.26/win32/include/wctype.h +172 -0
  242. data/ext/tcc/tcc-0.9.26/win32/include/winapi/basetsd.h +149 -0
  243. data/ext/tcc/tcc-0.9.26/win32/include/winapi/basetyps.h +85 -0
  244. data/ext/tcc/tcc-0.9.26/win32/include/winapi/guiddef.h +151 -0
  245. data/ext/tcc/tcc-0.9.26/win32/include/winapi/intrin.h +11 -0
  246. data/ext/tcc/tcc-0.9.26/win32/include/winapi/poppack.h +8 -0
  247. data/ext/tcc/tcc-0.9.26/win32/include/winapi/pshpack1.h +8 -0
  248. data/ext/tcc/tcc-0.9.26/win32/include/winapi/pshpack2.h +8 -0
  249. data/ext/tcc/tcc-0.9.26/win32/include/winapi/pshpack4.h +8 -0
  250. data/ext/tcc/tcc-0.9.26/win32/include/winapi/pshpack8.h +8 -0
  251. data/ext/tcc/tcc-0.9.26/win32/include/winapi/reason.h +80 -0
  252. data/ext/tcc/tcc-0.9.26/win32/include/winapi/specstrings.h +7 -0
  253. data/ext/tcc/tcc-0.9.26/win32/include/winapi/stralign.h +154 -0
  254. data/ext/tcc/tcc-0.9.26/win32/include/winapi/tvout.h +79 -0
  255. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winbase.h +2951 -0
  256. data/ext/tcc/tcc-0.9.26/win32/include/winapi/wincon.h +301 -0
  257. data/ext/tcc/tcc-0.9.26/win32/include/winapi/windef.h +293 -0
  258. data/ext/tcc/tcc-0.9.26/win32/include/winapi/windows.h +123 -0
  259. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winerror.h +3166 -0
  260. data/ext/tcc/tcc-0.9.26/win32/include/winapi/wingdi.h +4080 -0
  261. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winnetwk.h +476 -0
  262. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winnls.h +765 -0
  263. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winnt.h +5770 -0
  264. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winreg.h +272 -0
  265. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winuser.h +5651 -0
  266. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winver.h +160 -0
  267. data/ext/tcc/tcc-0.9.26/win32/lib/chkstk.S +191 -0
  268. data/ext/tcc/tcc-0.9.26/win32/lib/crt1.c +34 -0
  269. data/ext/tcc/tcc-0.9.26/win32/lib/dllcrt1.c +13 -0
  270. data/ext/tcc/tcc-0.9.26/win32/lib/dllmain.c +9 -0
  271. data/ext/tcc/tcc-0.9.26/win32/lib/gdi32.def +337 -0
  272. data/ext/tcc/tcc-0.9.26/win32/lib/kernel32.def +765 -0
  273. data/ext/tcc/tcc-0.9.26/win32/lib/msvcrt.def +1399 -0
  274. data/ext/tcc/tcc-0.9.26/win32/lib/user32.def +654 -0
  275. data/ext/tcc/tcc-0.9.26/win32/lib/wincrt1.c +64 -0
  276. data/ext/tcc/tcc-0.9.26/win32/tcc-win32.txt +156 -0
  277. data/ext/tcc/tcc-0.9.26/win32/tools/tiny_impdef.c +243 -0
  278. data/ext/tcc/tcc-0.9.26/win32/tools/tiny_libmaker.c +258 -0
  279. data/ext/tcc/tcc-0.9.26/x86_64-asm.h +448 -0
  280. data/ext/tcc/tcc-0.9.26/x86_64-gen.c +1701 -0
  281. data/lib/tcc.rb +291 -0
  282. data/tcc.gemspec +15 -0
  283. metadata +343 -0
@@ -0,0 +1,1118 @@
1
+ /*
2
+ * GAS like assembler for TCC
3
+ *
4
+ * Copyright (c) 2001-2004 Fabrice Bellard
5
+ *
6
+ * This library is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2 of the License, or (at your option) any later version.
10
+ *
11
+ * This library is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with this library; if not, write to the Free Software
18
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ */
20
+
21
+ #include "tcc.h"
22
+ #ifdef CONFIG_TCC_ASM
23
+
24
+ ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
25
+ {
26
+ char buf[64];
27
+ TokenSym *ts;
28
+
29
+ snprintf(buf, sizeof(buf), "L..%u", n);
30
+ ts = tok_alloc(buf, strlen(buf));
31
+ return ts->tok;
32
+ }
33
+
34
+ ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
35
+
36
+ /* We do not use the C expression parser to handle symbols. Maybe the
37
+ C expression parser could be tweaked to do so. */
38
+
39
+ static void asm_expr_unary(TCCState *s1, ExprValue *pe)
40
+ {
41
+ Sym *sym;
42
+ int op, n, label;
43
+ const char *p;
44
+
45
+ switch(tok) {
46
+ case TOK_PPNUM:
47
+ p = tokc.cstr->data;
48
+ n = strtoul(p, (char **)&p, 0);
49
+ if (*p == 'b' || *p == 'f') {
50
+ /* backward or forward label */
51
+ label = asm_get_local_label_name(s1, n);
52
+ sym = label_find(label);
53
+ if (*p == 'b') {
54
+ /* backward : find the last corresponding defined label */
55
+ if (sym && sym->r == 0)
56
+ sym = sym->prev_tok;
57
+ if (!sym)
58
+ tcc_error("local label '%d' not found backward", n);
59
+ } else {
60
+ /* forward */
61
+ if (!sym || sym->r) {
62
+ /* if the last label is defined, then define a new one */
63
+ sym = label_push(&s1->asm_labels, label, 0);
64
+ sym->type.t = VT_STATIC | VT_VOID;
65
+ }
66
+ }
67
+ pe->v = 0;
68
+ pe->sym = sym;
69
+ } else if (*p == '\0') {
70
+ pe->v = n;
71
+ pe->sym = NULL;
72
+ } else {
73
+ tcc_error("invalid number syntax");
74
+ }
75
+ next();
76
+ break;
77
+ case '+':
78
+ next();
79
+ asm_expr_unary(s1, pe);
80
+ break;
81
+ case '-':
82
+ case '~':
83
+ op = tok;
84
+ next();
85
+ asm_expr_unary(s1, pe);
86
+ if (pe->sym)
87
+ tcc_error("invalid operation with label");
88
+ if (op == '-')
89
+ pe->v = -pe->v;
90
+ else
91
+ pe->v = ~pe->v;
92
+ break;
93
+ case TOK_CCHAR:
94
+ case TOK_LCHAR:
95
+ pe->v = tokc.i;
96
+ pe->sym = NULL;
97
+ next();
98
+ break;
99
+ case '(':
100
+ next();
101
+ asm_expr(s1, pe);
102
+ skip(')');
103
+ break;
104
+ default:
105
+ if (tok >= TOK_IDENT) {
106
+ /* label case : if the label was not found, add one */
107
+ sym = label_find(tok);
108
+ if (!sym) {
109
+ sym = label_push(&s1->asm_labels, tok, 0);
110
+ /* NOTE: by default, the symbol is global */
111
+ sym->type.t = VT_VOID;
112
+ }
113
+ if (sym->r == SHN_ABS) {
114
+ /* if absolute symbol, no need to put a symbol value */
115
+ pe->v = sym->jnext;
116
+ pe->sym = NULL;
117
+ } else {
118
+ pe->v = 0;
119
+ pe->sym = sym;
120
+ }
121
+ next();
122
+ } else {
123
+ tcc_error("bad expression syntax [%s]", get_tok_str(tok, &tokc));
124
+ }
125
+ break;
126
+ }
127
+ }
128
+
129
+ static void asm_expr_prod(TCCState *s1, ExprValue *pe)
130
+ {
131
+ int op;
132
+ ExprValue e2;
133
+
134
+ asm_expr_unary(s1, pe);
135
+ for(;;) {
136
+ op = tok;
137
+ if (op != '*' && op != '/' && op != '%' &&
138
+ op != TOK_SHL && op != TOK_SAR)
139
+ break;
140
+ next();
141
+ asm_expr_unary(s1, &e2);
142
+ if (pe->sym || e2.sym)
143
+ tcc_error("invalid operation with label");
144
+ switch(op) {
145
+ case '*':
146
+ pe->v *= e2.v;
147
+ break;
148
+ case '/':
149
+ if (e2.v == 0) {
150
+ div_error:
151
+ tcc_error("division by zero");
152
+ }
153
+ pe->v /= e2.v;
154
+ break;
155
+ case '%':
156
+ if (e2.v == 0)
157
+ goto div_error;
158
+ pe->v %= e2.v;
159
+ break;
160
+ case TOK_SHL:
161
+ pe->v <<= e2.v;
162
+ break;
163
+ default:
164
+ case TOK_SAR:
165
+ pe->v >>= e2.v;
166
+ break;
167
+ }
168
+ }
169
+ }
170
+
171
+ static void asm_expr_logic(TCCState *s1, ExprValue *pe)
172
+ {
173
+ int op;
174
+ ExprValue e2;
175
+
176
+ asm_expr_prod(s1, pe);
177
+ for(;;) {
178
+ op = tok;
179
+ if (op != '&' && op != '|' && op != '^')
180
+ break;
181
+ next();
182
+ asm_expr_prod(s1, &e2);
183
+ if (pe->sym || e2.sym)
184
+ tcc_error("invalid operation with label");
185
+ switch(op) {
186
+ case '&':
187
+ pe->v &= e2.v;
188
+ break;
189
+ case '|':
190
+ pe->v |= e2.v;
191
+ break;
192
+ default:
193
+ case '^':
194
+ pe->v ^= e2.v;
195
+ break;
196
+ }
197
+ }
198
+ }
199
+
200
+ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
201
+ {
202
+ int op;
203
+ ExprValue e2;
204
+
205
+ asm_expr_logic(s1, pe);
206
+ for(;;) {
207
+ op = tok;
208
+ if (op != '+' && op != '-')
209
+ break;
210
+ next();
211
+ asm_expr_logic(s1, &e2);
212
+ if (op == '+') {
213
+ if (pe->sym != NULL && e2.sym != NULL)
214
+ goto cannot_relocate;
215
+ pe->v += e2.v;
216
+ if (pe->sym == NULL && e2.sym != NULL)
217
+ pe->sym = e2.sym;
218
+ } else {
219
+ pe->v -= e2.v;
220
+ /* NOTE: we are less powerful than gas in that case
221
+ because we store only one symbol in the expression */
222
+ if (!pe->sym && !e2.sym) {
223
+ /* OK */
224
+ } else if (pe->sym && !e2.sym) {
225
+ /* OK */
226
+ } else if (pe->sym && e2.sym) {
227
+ if (pe->sym == e2.sym) {
228
+ /* OK */
229
+ } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
230
+ /* we also accept defined symbols in the same section */
231
+ pe->v += pe->sym->jnext - e2.sym->jnext;
232
+ } else {
233
+ goto cannot_relocate;
234
+ }
235
+ pe->sym = NULL; /* same symbols can be substracted to NULL */
236
+ } else {
237
+ cannot_relocate:
238
+ tcc_error("invalid operation with label");
239
+ }
240
+ }
241
+ }
242
+ }
243
+
244
+ ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe)
245
+ {
246
+ asm_expr_sum(s1, pe);
247
+ }
248
+
249
+ ST_FUNC int asm_int_expr(TCCState *s1)
250
+ {
251
+ ExprValue e;
252
+ asm_expr(s1, &e);
253
+ if (e.sym)
254
+ expect("constant");
255
+ return e.v;
256
+ }
257
+
258
+ /* NOTE: the same name space as C labels is used to avoid using too
259
+ much memory when storing labels in TokenStrings */
260
+ static void asm_new_label1(TCCState *s1, int label, int is_local,
261
+ int sh_num, int value)
262
+ {
263
+ Sym *sym;
264
+
265
+ sym = label_find(label);
266
+ if (sym) {
267
+ if (sym->r) {
268
+ /* the label is already defined */
269
+ if (!is_local) {
270
+ tcc_error("assembler label '%s' already defined",
271
+ get_tok_str(label, NULL));
272
+ } else {
273
+ /* redefinition of local labels is possible */
274
+ goto new_label;
275
+ }
276
+ }
277
+ } else {
278
+ new_label:
279
+ sym = label_push(&s1->asm_labels, label, 0);
280
+ sym->type.t = VT_STATIC | VT_VOID;
281
+ }
282
+ sym->r = sh_num;
283
+ sym->jnext = value;
284
+ }
285
+
286
+ static void asm_new_label(TCCState *s1, int label, int is_local)
287
+ {
288
+ asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
289
+ }
290
+
291
+ static void asm_free_labels(TCCState *st)
292
+ {
293
+ Sym *s, *s1;
294
+ Section *sec;
295
+
296
+ for(s = st->asm_labels; s != NULL; s = s1) {
297
+ s1 = s->prev;
298
+ /* define symbol value in object file */
299
+ if (s->r) {
300
+ if (s->r == SHN_ABS)
301
+ sec = SECTION_ABS;
302
+ else
303
+ sec = st->sections[s->r];
304
+ put_extern_sym2(s, sec, s->jnext, 0, 0);
305
+ }
306
+ /* remove label */
307
+ table_ident[s->v - TOK_IDENT]->sym_label = NULL;
308
+ sym_free(s);
309
+ }
310
+ st->asm_labels = NULL;
311
+ }
312
+
313
+ static void use_section1(TCCState *s1, Section *sec)
314
+ {
315
+ cur_text_section->data_offset = ind;
316
+ cur_text_section = sec;
317
+ ind = cur_text_section->data_offset;
318
+ }
319
+
320
+ static void use_section(TCCState *s1, const char *name)
321
+ {
322
+ Section *sec;
323
+ sec = find_section(s1, name);
324
+ use_section1(s1, sec);
325
+ }
326
+
327
+ static void asm_parse_directive(TCCState *s1)
328
+ {
329
+ int n, offset, v, size, tok1;
330
+ Section *sec;
331
+ uint8_t *ptr;
332
+
333
+ /* assembler directive */
334
+ next();
335
+ sec = cur_text_section;
336
+ switch(tok) {
337
+ case TOK_ASM_align:
338
+ case TOK_ASM_skip:
339
+ case TOK_ASM_space:
340
+ tok1 = tok;
341
+ next();
342
+ n = asm_int_expr(s1);
343
+ if (tok1 == TOK_ASM_align) {
344
+ if (n < 0 || (n & (n-1)) != 0)
345
+ tcc_error("alignment must be a positive power of two");
346
+ offset = (ind + n - 1) & -n;
347
+ size = offset - ind;
348
+ /* the section must have a compatible alignment */
349
+ if (sec->sh_addralign < n)
350
+ sec->sh_addralign = n;
351
+ } else {
352
+ size = n;
353
+ }
354
+ v = 0;
355
+ if (tok == ',') {
356
+ next();
357
+ v = asm_int_expr(s1);
358
+ }
359
+ zero_pad:
360
+ if (sec->sh_type != SHT_NOBITS) {
361
+ sec->data_offset = ind;
362
+ ptr = section_ptr_add(sec, size);
363
+ memset(ptr, v, size);
364
+ }
365
+ ind += size;
366
+ break;
367
+ case TOK_ASM_quad:
368
+ next();
369
+ for(;;) {
370
+ uint64_t vl;
371
+ const char *p;
372
+
373
+ p = tokc.cstr->data;
374
+ if (tok != TOK_PPNUM) {
375
+ error_constant:
376
+ tcc_error("64 bit constant");
377
+ }
378
+ vl = strtoll(p, (char **)&p, 0);
379
+ if (*p != '\0')
380
+ goto error_constant;
381
+ next();
382
+ if (sec->sh_type != SHT_NOBITS) {
383
+ /* XXX: endianness */
384
+ gen_le32(vl);
385
+ gen_le32(vl >> 32);
386
+ } else {
387
+ ind += 8;
388
+ }
389
+ if (tok != ',')
390
+ break;
391
+ next();
392
+ }
393
+ break;
394
+ case TOK_ASM_byte:
395
+ size = 1;
396
+ goto asm_data;
397
+ case TOK_ASM_word:
398
+ case TOK_SHORT:
399
+ size = 2;
400
+ goto asm_data;
401
+ case TOK_LONG:
402
+ case TOK_INT:
403
+ size = 4;
404
+ asm_data:
405
+ next();
406
+ for(;;) {
407
+ ExprValue e;
408
+ asm_expr(s1, &e);
409
+ if (sec->sh_type != SHT_NOBITS) {
410
+ if (size == 4) {
411
+ gen_expr32(&e);
412
+ } else {
413
+ if (e.sym)
414
+ expect("constant");
415
+ if (size == 1)
416
+ g(e.v);
417
+ else
418
+ gen_le16(e.v);
419
+ }
420
+ } else {
421
+ ind += size;
422
+ }
423
+ if (tok != ',')
424
+ break;
425
+ next();
426
+ }
427
+ break;
428
+ case TOK_ASM_fill:
429
+ {
430
+ int repeat, size, val, i, j;
431
+ uint8_t repeat_buf[8];
432
+ next();
433
+ repeat = asm_int_expr(s1);
434
+ if (repeat < 0) {
435
+ tcc_error("repeat < 0; .fill ignored");
436
+ break;
437
+ }
438
+ size = 1;
439
+ val = 0;
440
+ if (tok == ',') {
441
+ next();
442
+ size = asm_int_expr(s1);
443
+ if (size < 0) {
444
+ tcc_error("size < 0; .fill ignored");
445
+ break;
446
+ }
447
+ if (size > 8)
448
+ size = 8;
449
+ if (tok == ',') {
450
+ next();
451
+ val = asm_int_expr(s1);
452
+ }
453
+ }
454
+ /* XXX: endianness */
455
+ repeat_buf[0] = val;
456
+ repeat_buf[1] = val >> 8;
457
+ repeat_buf[2] = val >> 16;
458
+ repeat_buf[3] = val >> 24;
459
+ repeat_buf[4] = 0;
460
+ repeat_buf[5] = 0;
461
+ repeat_buf[6] = 0;
462
+ repeat_buf[7] = 0;
463
+ for(i = 0; i < repeat; i++) {
464
+ for(j = 0; j < size; j++) {
465
+ g(repeat_buf[j]);
466
+ }
467
+ }
468
+ }
469
+ break;
470
+ case TOK_ASM_org:
471
+ {
472
+ unsigned long n;
473
+ next();
474
+ /* XXX: handle section symbols too */
475
+ n = asm_int_expr(s1);
476
+ if (n < ind)
477
+ tcc_error("attempt to .org backwards");
478
+ v = 0;
479
+ size = n - ind;
480
+ goto zero_pad;
481
+ }
482
+ break;
483
+ case TOK_ASM_globl:
484
+ case TOK_ASM_global:
485
+ case TOK_ASM_weak:
486
+ tok1 = tok;
487
+ do {
488
+ Sym *sym;
489
+
490
+ next();
491
+ sym = label_find(tok);
492
+ if (!sym) {
493
+ sym = label_push(&s1->asm_labels, tok, 0);
494
+ sym->type.t = VT_VOID;
495
+ }
496
+ sym->type.t &= ~VT_STATIC;
497
+ if (tok1 == TOK_ASM_weak)
498
+ sym->type.t |= VT_WEAK;
499
+ next();
500
+ } while (tok == ',');
501
+ break;
502
+ case TOK_ASM_string:
503
+ case TOK_ASM_ascii:
504
+ case TOK_ASM_asciz:
505
+ {
506
+ const uint8_t *p;
507
+ int i, size, t;
508
+
509
+ t = tok;
510
+ next();
511
+ for(;;) {
512
+ if (tok != TOK_STR)
513
+ expect("string constant");
514
+ p = tokc.cstr->data;
515
+ size = tokc.cstr->size;
516
+ if (t == TOK_ASM_ascii && size > 0)
517
+ size--;
518
+ for(i = 0; i < size; i++)
519
+ g(p[i]);
520
+ next();
521
+ if (tok == ',') {
522
+ next();
523
+ } else if (tok != TOK_STR) {
524
+ break;
525
+ }
526
+ }
527
+ }
528
+ break;
529
+ case TOK_ASM_text:
530
+ case TOK_ASM_data:
531
+ case TOK_ASM_bss:
532
+ {
533
+ char sname[64];
534
+ tok1 = tok;
535
+ n = 0;
536
+ next();
537
+ if (tok != ';' && tok != TOK_LINEFEED) {
538
+ n = asm_int_expr(s1);
539
+ next();
540
+ }
541
+ sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
542
+ use_section(s1, sname);
543
+ }
544
+ break;
545
+ case TOK_ASM_file:
546
+ {
547
+ char filename[512];
548
+
549
+ filename[0] = '\0';
550
+ next();
551
+
552
+ if (tok == TOK_STR)
553
+ pstrcat(filename, sizeof(filename), tokc.cstr->data);
554
+ else
555
+ pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));
556
+
557
+ if (s1->warn_unsupported)
558
+ tcc_warning("ignoring .file %s", filename);
559
+
560
+ next();
561
+ }
562
+ break;
563
+ case TOK_ASM_ident:
564
+ {
565
+ char ident[256];
566
+
567
+ ident[0] = '\0';
568
+ next();
569
+
570
+ if (tok == TOK_STR)
571
+ pstrcat(ident, sizeof(ident), tokc.cstr->data);
572
+ else
573
+ pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));
574
+
575
+ if (s1->warn_unsupported)
576
+ tcc_warning("ignoring .ident %s", ident);
577
+
578
+ next();
579
+ }
580
+ break;
581
+ case TOK_ASM_size:
582
+ {
583
+ Sym *sym;
584
+
585
+ next();
586
+ sym = label_find(tok);
587
+ if (!sym) {
588
+ tcc_error("label not found: %s", get_tok_str(tok, NULL));
589
+ }
590
+
591
+ next();
592
+ skip(',');
593
+ /* XXX .size name,label2-label1 */
594
+ if (s1->warn_unsupported)
595
+ tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL));
596
+
597
+ while (tok != '\n' && tok != CH_EOF) {
598
+ next();
599
+ }
600
+ }
601
+ break;
602
+ case TOK_ASM_type:
603
+ {
604
+ Sym *sym;
605
+ const char *newtype;
606
+
607
+ next();
608
+ sym = label_find(tok);
609
+ if (!sym) {
610
+ sym = label_push(&s1->asm_labels, tok, 0);
611
+ sym->type.t = VT_VOID;
612
+ }
613
+
614
+ next();
615
+ skip(',');
616
+ if (tok == TOK_STR) {
617
+ newtype = tokc.cstr->data;
618
+ } else {
619
+ if (tok == '@' || tok == '%')
620
+ skip(tok);
621
+ newtype = get_tok_str(tok, NULL);
622
+ }
623
+
624
+ if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
625
+ sym->type.t = VT_FUNC;
626
+ }
627
+ else if (s1->warn_unsupported)
628
+ tcc_warning("change type of '%s' from 0x%x to '%s' ignored",
629
+ get_tok_str(sym->v, NULL), sym->type.t, newtype);
630
+
631
+ next();
632
+ }
633
+ break;
634
+ case TOK_SECTION1:
635
+ {
636
+ char sname[256];
637
+
638
+ /* XXX: support more options */
639
+ next();
640
+ sname[0] = '\0';
641
+ while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {
642
+ if (tok == TOK_STR)
643
+ pstrcat(sname, sizeof(sname), tokc.cstr->data);
644
+ else
645
+ pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));
646
+ next();
647
+ }
648
+ if (tok == ',') {
649
+ /* skip section options */
650
+ next();
651
+ if (tok != TOK_STR)
652
+ expect("string constant");
653
+ next();
654
+ }
655
+ last_text_section = cur_text_section;
656
+ use_section(s1, sname);
657
+ }
658
+ break;
659
+ case TOK_ASM_previous:
660
+ {
661
+ Section *sec;
662
+ next();
663
+ if (!last_text_section)
664
+ tcc_error("no previous section referenced");
665
+ sec = cur_text_section;
666
+ use_section1(s1, last_text_section);
667
+ last_text_section = sec;
668
+ }
669
+ break;
670
+ #ifdef TCC_TARGET_I386
671
+ case TOK_ASM_code16:
672
+ {
673
+ next();
674
+ s1->seg_size = 16;
675
+ }
676
+ break;
677
+ case TOK_ASM_code32:
678
+ {
679
+ next();
680
+ s1->seg_size = 32;
681
+ }
682
+ break;
683
+ #endif
684
+ #ifdef TCC_TARGET_X86_64
685
+ /* added for compatibility with GAS */
686
+ case TOK_ASM_code64:
687
+ next();
688
+ break;
689
+ #endif
690
+ default:
691
+ tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));
692
+ break;
693
+ }
694
+ }
695
+
696
+
697
+ /* assemble a file */
698
+ static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
699
+ {
700
+ int opcode;
701
+
702
+ #if 0
703
+ /* print stats about opcodes */
704
+ {
705
+ const ASMInstr *pa;
706
+ int freq[4];
707
+ int op_vals[500];
708
+ int nb_op_vals, i, j;
709
+
710
+ nb_op_vals = 0;
711
+ memset(freq, 0, sizeof(freq));
712
+ for(pa = asm_instrs; pa->sym != 0; pa++) {
713
+ freq[pa->nb_ops]++;
714
+ for(i=0;i<pa->nb_ops;i++) {
715
+ for(j=0;j<nb_op_vals;j++) {
716
+ if (pa->op_type[i] == op_vals[j])
717
+ goto found;
718
+ }
719
+ op_vals[nb_op_vals++] = pa->op_type[i];
720
+ found: ;
721
+ }
722
+ }
723
+ for(i=0;i<nb_op_vals;i++) {
724
+ int v = op_vals[i];
725
+ if ((v & (v - 1)) != 0)
726
+ printf("%3d: %08x\n", i, v);
727
+ }
728
+ printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
729
+ sizeof(asm_instrs), sizeof(asm_instrs) / sizeof(ASMInstr),
730
+ freq[0], freq[1], freq[2], freq[3]);
731
+ }
732
+ #endif
733
+
734
+ /* XXX: undefine C labels */
735
+
736
+ ch = file->buf_ptr[0];
737
+ tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
738
+ parse_flags = PARSE_FLAG_ASM_COMMENTS;
739
+ if (do_preprocess)
740
+ parse_flags |= PARSE_FLAG_PREPROCESS;
741
+ next();
742
+ for(;;) {
743
+ if (tok == TOK_EOF)
744
+ break;
745
+ parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
746
+ redo:
747
+ if (tok == '#') {
748
+ /* horrible gas comment */
749
+ while (tok != TOK_LINEFEED)
750
+ next();
751
+ } else if (tok == '.') {
752
+ asm_parse_directive(s1);
753
+ } else if (tok == TOK_PPNUM) {
754
+ const char *p;
755
+ int n;
756
+ p = tokc.cstr->data;
757
+ n = strtoul(p, (char **)&p, 10);
758
+ if (*p != '\0')
759
+ expect("':'");
760
+ /* new local label */
761
+ asm_new_label(s1, asm_get_local_label_name(s1, n), 1);
762
+ next();
763
+ skip(':');
764
+ goto redo;
765
+ } else if (tok >= TOK_IDENT) {
766
+ /* instruction or label */
767
+ opcode = tok;
768
+ next();
769
+ if (tok == ':') {
770
+ /* new label */
771
+ asm_new_label(s1, opcode, 0);
772
+ next();
773
+ goto redo;
774
+ } else if (tok == '=') {
775
+ int n;
776
+ next();
777
+ n = asm_int_expr(s1);
778
+ asm_new_label1(s1, opcode, 0, SHN_ABS, n);
779
+ goto redo;
780
+ } else {
781
+ asm_opcode(s1, opcode);
782
+ }
783
+ }
784
+ /* end of line */
785
+ if (tok != ';' && tok != TOK_LINEFEED){
786
+ expect("end of line");
787
+ }
788
+ parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
789
+ next();
790
+ }
791
+
792
+ asm_free_labels(s1);
793
+
794
+ return 0;
795
+ }
796
+
797
+ /* Assemble the current file */
798
+ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
799
+ {
800
+ Sym *define_start;
801
+ int ret;
802
+
803
+ preprocess_init(s1);
804
+
805
+ /* default section is text */
806
+ cur_text_section = text_section;
807
+ ind = cur_text_section->data_offset;
808
+
809
+ define_start = define_stack;
810
+
811
+ /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
812
+ symbols can be safely used */
813
+ put_elf_sym(symtab_section, 0, 0,
814
+ ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
815
+ SHN_ABS, file->filename);
816
+
817
+ ret = tcc_assemble_internal(s1, do_preprocess);
818
+
819
+ cur_text_section->data_offset = ind;
820
+
821
+ free_defines(define_start);
822
+
823
+ return ret;
824
+ }
825
+
826
+ /********************************************************************/
827
+ /* GCC inline asm support */
828
+
829
+ /* assemble the string 'str' in the current C compilation unit without
830
+ C preprocessing. NOTE: str is modified by modifying the '\0' at the
831
+ end */
832
+ static void tcc_assemble_inline(TCCState *s1, char *str, int len)
833
+ {
834
+ int saved_parse_flags;
835
+ const int *saved_macro_ptr;
836
+
837
+ saved_parse_flags = parse_flags;
838
+ saved_macro_ptr = macro_ptr;
839
+
840
+ tcc_open_bf(s1, ":asm:", len);
841
+ memcpy(file->buffer, str, len);
842
+
843
+ macro_ptr = NULL;
844
+ tcc_assemble_internal(s1, 0);
845
+ tcc_close();
846
+
847
+ parse_flags = saved_parse_flags;
848
+ macro_ptr = saved_macro_ptr;
849
+ }
850
+
851
+ /* find a constraint by its number or id (gcc 3 extended
852
+ syntax). return -1 if not found. Return in *pp in char after the
853
+ constraint */
854
+ ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands,
855
+ const char *name, const char **pp)
856
+ {
857
+ int index;
858
+ TokenSym *ts;
859
+ const char *p;
860
+
861
+ if (isnum(*name)) {
862
+ index = 0;
863
+ while (isnum(*name)) {
864
+ index = (index * 10) + (*name) - '0';
865
+ name++;
866
+ }
867
+ if ((unsigned)index >= nb_operands)
868
+ index = -1;
869
+ } else if (*name == '[') {
870
+ name++;
871
+ p = strchr(name, ']');
872
+ if (p) {
873
+ ts = tok_alloc(name, p - name);
874
+ for(index = 0; index < nb_operands; index++) {
875
+ if (operands[index].id == ts->tok)
876
+ goto found;
877
+ }
878
+ index = -1;
879
+ found:
880
+ name = p + 1;
881
+ } else {
882
+ index = -1;
883
+ }
884
+ } else {
885
+ index = -1;
886
+ }
887
+ if (pp)
888
+ *pp = name;
889
+ return index;
890
+ }
891
+
892
+ static void subst_asm_operands(ASMOperand *operands, int nb_operands,
893
+ int nb_outputs,
894
+ CString *out_str, CString *in_str)
895
+ {
896
+ int c, index, modifier;
897
+ const char *str;
898
+ ASMOperand *op;
899
+ SValue sv;
900
+
901
+ cstr_new(out_str);
902
+ str = in_str->data;
903
+ for(;;) {
904
+ c = *str++;
905
+ if (c == '%') {
906
+ if (*str == '%') {
907
+ str++;
908
+ goto add_char;
909
+ }
910
+ modifier = 0;
911
+ if (*str == 'c' || *str == 'n' ||
912
+ *str == 'b' || *str == 'w' || *str == 'h')
913
+ modifier = *str++;
914
+ index = find_constraint(operands, nb_operands, str, &str);
915
+ if (index < 0)
916
+ tcc_error("invalid operand reference after %%");
917
+ op = &operands[index];
918
+ sv = *op->vt;
919
+ if (op->reg >= 0) {
920
+ sv.r = op->reg;
921
+ if ((op->vt->r & VT_VALMASK) == VT_LLOCAL && op->is_memory)
922
+ sv.r |= VT_LVAL;
923
+ }
924
+ subst_asm_operand(out_str, &sv, modifier);
925
+ } else {
926
+ add_char:
927
+ cstr_ccat(out_str, c);
928
+ if (c == '\0')
929
+ break;
930
+ }
931
+ }
932
+ }
933
+
934
+
935
+ static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
936
+ int is_output)
937
+ {
938
+ ASMOperand *op;
939
+ int nb_operands;
940
+
941
+ if (tok != ':') {
942
+ nb_operands = *nb_operands_ptr;
943
+ for(;;) {
944
+ if (nb_operands >= MAX_ASM_OPERANDS)
945
+ tcc_error("too many asm operands");
946
+ op = &operands[nb_operands++];
947
+ op->id = 0;
948
+ if (tok == '[') {
949
+ next();
950
+ if (tok < TOK_IDENT)
951
+ expect("identifier");
952
+ op->id = tok;
953
+ next();
954
+ skip(']');
955
+ }
956
+ if (tok != TOK_STR)
957
+ expect("string constant");
958
+ op->constraint = tcc_malloc(tokc.cstr->size);
959
+ strcpy(op->constraint, tokc.cstr->data);
960
+ next();
961
+ skip('(');
962
+ gexpr();
963
+ if (is_output) {
964
+ test_lvalue();
965
+ } else {
966
+ /* we want to avoid LLOCAL case, except when the 'm'
967
+ constraint is used. Note that it may come from
968
+ register storage, so we need to convert (reg)
969
+ case */
970
+ if ((vtop->r & VT_LVAL) &&
971
+ ((vtop->r & VT_VALMASK) == VT_LLOCAL ||
972
+ (vtop->r & VT_VALMASK) < VT_CONST) &&
973
+ !strchr(op->constraint, 'm')) {
974
+ gv(RC_INT);
975
+ }
976
+ }
977
+ op->vt = vtop;
978
+ skip(')');
979
+ if (tok == ',') {
980
+ next();
981
+ } else {
982
+ break;
983
+ }
984
+ }
985
+ *nb_operands_ptr = nb_operands;
986
+ }
987
+ }
988
+
989
+ /* parse the GCC asm() instruction */
990
+ ST_FUNC void asm_instr(void)
991
+ {
992
+ CString astr, astr1;
993
+ ASMOperand operands[MAX_ASM_OPERANDS];
994
+ int nb_outputs, nb_operands, i, must_subst, out_reg;
995
+ uint8_t clobber_regs[NB_ASM_REGS];
996
+
997
+ next();
998
+ /* since we always generate the asm() instruction, we can ignore
999
+ volatile */
1000
+ if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) {
1001
+ next();
1002
+ }
1003
+ parse_asm_str(&astr);
1004
+ nb_operands = 0;
1005
+ nb_outputs = 0;
1006
+ must_subst = 0;
1007
+ memset(clobber_regs, 0, sizeof(clobber_regs));
1008
+ if (tok == ':') {
1009
+ next();
1010
+ must_subst = 1;
1011
+ /* output args */
1012
+ parse_asm_operands(operands, &nb_operands, 1);
1013
+ nb_outputs = nb_operands;
1014
+ if (tok == ':') {
1015
+ next();
1016
+ if (tok != ')') {
1017
+ /* input args */
1018
+ parse_asm_operands(operands, &nb_operands, 0);
1019
+ if (tok == ':') {
1020
+ /* clobber list */
1021
+ /* XXX: handle registers */
1022
+ next();
1023
+ for(;;) {
1024
+ if (tok != TOK_STR)
1025
+ expect("string constant");
1026
+ asm_clobber(clobber_regs, tokc.cstr->data);
1027
+ next();
1028
+ if (tok == ',') {
1029
+ next();
1030
+ } else {
1031
+ break;
1032
+ }
1033
+ }
1034
+ }
1035
+ }
1036
+ }
1037
+ }
1038
+ skip(')');
1039
+ /* NOTE: we do not eat the ';' so that we can restore the current
1040
+ token after the assembler parsing */
1041
+ if (tok != ';')
1042
+ expect("';'");
1043
+
1044
+ /* save all values in the memory */
1045
+ save_regs(0);
1046
+
1047
+ /* compute constraints */
1048
+ asm_compute_constraints(operands, nb_operands, nb_outputs,
1049
+ clobber_regs, &out_reg);
1050
+
1051
+ /* substitute the operands in the asm string. No substitution is
1052
+ done if no operands (GCC behaviour) */
1053
+ #ifdef ASM_DEBUG
1054
+ printf("asm: \"%s\"\n", (char *)astr.data);
1055
+ #endif
1056
+ if (must_subst) {
1057
+ subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr);
1058
+ cstr_free(&astr);
1059
+ } else {
1060
+ astr1 = astr;
1061
+ }
1062
+ #ifdef ASM_DEBUG
1063
+ printf("subst_asm: \"%s\"\n", (char *)astr1.data);
1064
+ #endif
1065
+
1066
+ /* generate loads */
1067
+ asm_gen_code(operands, nb_operands, nb_outputs, 0,
1068
+ clobber_regs, out_reg);
1069
+
1070
+ /* assemble the string with tcc internal assembler */
1071
+ tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
1072
+
1073
+ /* restore the current C token */
1074
+ next();
1075
+
1076
+ /* store the output values if needed */
1077
+ asm_gen_code(operands, nb_operands, nb_outputs, 1,
1078
+ clobber_regs, out_reg);
1079
+
1080
+ /* free everything */
1081
+ for(i=0;i<nb_operands;i++) {
1082
+ ASMOperand *op;
1083
+ op = &operands[i];
1084
+ tcc_free(op->constraint);
1085
+ vpop();
1086
+ }
1087
+ cstr_free(&astr1);
1088
+ }
1089
+
1090
+ ST_FUNC void asm_global_instr(void)
1091
+ {
1092
+ CString astr;
1093
+
1094
+ next();
1095
+ parse_asm_str(&astr);
1096
+ skip(')');
1097
+ /* NOTE: we do not eat the ';' so that we can restore the current
1098
+ token after the assembler parsing */
1099
+ if (tok != ';')
1100
+ expect("';'");
1101
+
1102
+ #ifdef ASM_DEBUG
1103
+ printf("asm_global: \"%s\"\n", (char *)astr.data);
1104
+ #endif
1105
+ cur_text_section = text_section;
1106
+ ind = cur_text_section->data_offset;
1107
+
1108
+ /* assemble the string with tcc internal assembler */
1109
+ tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
1110
+
1111
+ cur_text_section->data_offset = ind;
1112
+
1113
+ /* restore the current C token */
1114
+ next();
1115
+
1116
+ cstr_free(&astr);
1117
+ }
1118
+ #endif /* CONFIG_TCC_ASM */