laag-nasm 2.13.03.2

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 (455) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +57 -0
  3. data/LICENSE.txt +29 -0
  4. data/README.org +34 -0
  5. data/ext/laag/nasm/extconf.rb +16 -0
  6. data/laag-nasm.gemspec +20 -0
  7. data/lib/laag/nasm.rb +29 -0
  8. data/patches/Makefile.in.patch +13 -0
  9. data/vendor/repo.or.cz/nasm/.gitignore +102 -0
  10. data/vendor/repo.or.cz/nasm/AUTHORS +137 -0
  11. data/vendor/repo.or.cz/nasm/CHANGES +2 -0
  12. data/vendor/repo.or.cz/nasm/ChangeLog +2905 -0
  13. data/vendor/repo.or.cz/nasm/INSTALL +102 -0
  14. data/vendor/repo.or.cz/nasm/LICENSE +29 -0
  15. data/vendor/repo.or.cz/nasm/Makefile.in +855 -0
  16. data/vendor/repo.or.cz/nasm/Mkfiles/README +46 -0
  17. data/vendor/repo.or.cz/nasm/Mkfiles/msvc.mak +732 -0
  18. data/vendor/repo.or.cz/nasm/Mkfiles/openwcom.mak +706 -0
  19. data/vendor/repo.or.cz/nasm/README +23 -0
  20. data/vendor/repo.or.cz/nasm/SubmittingPatches +116 -0
  21. data/vendor/repo.or.cz/nasm/TODO +376 -0
  22. data/vendor/repo.or.cz/nasm/aclocal.m4 +139 -0
  23. data/vendor/repo.or.cz/nasm/asm/assemble.c +2957 -0
  24. data/vendor/repo.or.cz/nasm/asm/assemble.h +54 -0
  25. data/vendor/repo.or.cz/nasm/asm/directiv.c +566 -0
  26. data/vendor/repo.or.cz/nasm/asm/directiv.dat +92 -0
  27. data/vendor/repo.or.cz/nasm/asm/error.c +202 -0
  28. data/vendor/repo.or.cz/nasm/asm/eval.c +1014 -0
  29. data/vendor/repo.or.cz/nasm/asm/eval.h +49 -0
  30. data/vendor/repo.or.cz/nasm/asm/exprdump.c +79 -0
  31. data/vendor/repo.or.cz/nasm/asm/exprlib.c +200 -0
  32. data/vendor/repo.or.cz/nasm/asm/float.c +952 -0
  33. data/vendor/repo.or.cz/nasm/asm/float.h +54 -0
  34. data/vendor/repo.or.cz/nasm/asm/labels.c +540 -0
  35. data/vendor/repo.or.cz/nasm/asm/listing.c +346 -0
  36. data/vendor/repo.or.cz/nasm/asm/listing.h +113 -0
  37. data/vendor/repo.or.cz/nasm/asm/nasm.c +1855 -0
  38. data/vendor/repo.or.cz/nasm/asm/parser.c +1167 -0
  39. data/vendor/repo.or.cz/nasm/asm/parser.h +45 -0
  40. data/vendor/repo.or.cz/nasm/asm/phash.pl +109 -0
  41. data/vendor/repo.or.cz/nasm/asm/pptok.dat +96 -0
  42. data/vendor/repo.or.cz/nasm/asm/pptok.pl +271 -0
  43. data/vendor/repo.or.cz/nasm/asm/pragma.c +218 -0
  44. data/vendor/repo.or.cz/nasm/asm/preproc-nop.c +188 -0
  45. data/vendor/repo.or.cz/nasm/asm/preproc.c +5459 -0
  46. data/vendor/repo.or.cz/nasm/asm/preproc.h +55 -0
  47. data/vendor/repo.or.cz/nasm/asm/quote.c +479 -0
  48. data/vendor/repo.or.cz/nasm/asm/quote.h +44 -0
  49. data/vendor/repo.or.cz/nasm/asm/rdstrnum.c +68 -0
  50. data/vendor/repo.or.cz/nasm/asm/segalloc.c +51 -0
  51. data/vendor/repo.or.cz/nasm/asm/stdscan.c +345 -0
  52. data/vendor/repo.or.cz/nasm/asm/stdscan.h +49 -0
  53. data/vendor/repo.or.cz/nasm/asm/strfunc.c +359 -0
  54. data/vendor/repo.or.cz/nasm/asm/tokens.dat +135 -0
  55. data/vendor/repo.or.cz/nasm/asm/tokhash.pl +284 -0
  56. data/vendor/repo.or.cz/nasm/autogen.sh +9 -0
  57. data/vendor/repo.or.cz/nasm/common/common.c +122 -0
  58. data/vendor/repo.or.cz/nasm/config/msvc.h +192 -0
  59. data/vendor/repo.or.cz/nasm/config/unknown.h +51 -0
  60. data/vendor/repo.or.cz/nasm/config/watcom.h +74 -0
  61. data/vendor/repo.or.cz/nasm/configure.ac +253 -0
  62. data/vendor/repo.or.cz/nasm/contrib/MSVC6.txt +25 -0
  63. data/vendor/repo.or.cz/nasm/contrib/VSrules/nasm.README +16 -0
  64. data/vendor/repo.or.cz/nasm/contrib/VSrules/nasm.rules +79 -0
  65. data/vendor/repo.or.cz/nasm/disasm/disasm.c +1735 -0
  66. data/vendor/repo.or.cz/nasm/disasm/disasm.h +49 -0
  67. data/vendor/repo.or.cz/nasm/disasm/ndisasm.c +397 -0
  68. data/vendor/repo.or.cz/nasm/disasm/sync.c +132 -0
  69. data/vendor/repo.or.cz/nasm/disasm/sync.h +45 -0
  70. data/vendor/repo.or.cz/nasm/doc/Makefile.in +86 -0
  71. data/vendor/repo.or.cz/nasm/doc/README +20 -0
  72. data/vendor/repo.or.cz/nasm/doc/afmmetrics.ph +102 -0
  73. data/vendor/repo.or.cz/nasm/doc/changes.src +2588 -0
  74. data/vendor/repo.or.cz/nasm/doc/findfont.ph +180 -0
  75. data/vendor/repo.or.cz/nasm/doc/genps.pl +1294 -0
  76. data/vendor/repo.or.cz/nasm/doc/inslist.pl +108 -0
  77. data/vendor/repo.or.cz/nasm/doc/internal.doc +290 -0
  78. data/vendor/repo.or.cz/nasm/doc/local.css +1 -0
  79. data/vendor/repo.or.cz/nasm/doc/nasmdoc.css +150 -0
  80. data/vendor/repo.or.cz/nasm/doc/nasmdoc.src +8309 -0
  81. data/vendor/repo.or.cz/nasm/doc/nasmlogo.eps +212 -0
  82. data/vendor/repo.or.cz/nasm/doc/nasmlogw.png +0 -0
  83. data/vendor/repo.or.cz/nasm/doc/psfonts.ph +53 -0
  84. data/vendor/repo.or.cz/nasm/doc/pspdf.pl +98 -0
  85. data/vendor/repo.or.cz/nasm/doc/pswidth.ph +25 -0
  86. data/vendor/repo.or.cz/nasm/doc/rdsrc.pl +1111 -0
  87. data/vendor/repo.or.cz/nasm/doc/ttfmetrics.ph +63 -0
  88. data/vendor/repo.or.cz/nasm/headers/c +33 -0
  89. data/vendor/repo.or.cz/nasm/headers/doc +33 -0
  90. data/vendor/repo.or.cz/nasm/headers/mac +33 -0
  91. data/vendor/repo.or.cz/nasm/headers/perl +33 -0
  92. data/vendor/repo.or.cz/nasm/include/compiler.h +277 -0
  93. data/vendor/repo.or.cz/nasm/include/disp8.h +45 -0
  94. data/vendor/repo.or.cz/nasm/include/error.h +135 -0
  95. data/vendor/repo.or.cz/nasm/include/hashtbl.h +85 -0
  96. data/vendor/repo.or.cz/nasm/include/iflag.h +173 -0
  97. data/vendor/repo.or.cz/nasm/include/insns.h +76 -0
  98. data/vendor/repo.or.cz/nasm/include/labels.h +60 -0
  99. data/vendor/repo.or.cz/nasm/include/md5.h +21 -0
  100. data/vendor/repo.or.cz/nasm/include/nasm.h +1246 -0
  101. data/vendor/repo.or.cz/nasm/include/nasmint.h +219 -0
  102. data/vendor/repo.or.cz/nasm/include/nasmlib.h +524 -0
  103. data/vendor/repo.or.cz/nasm/include/opflags.h +271 -0
  104. data/vendor/repo.or.cz/nasm/include/perfhash.h +52 -0
  105. data/vendor/repo.or.cz/nasm/include/raa.h +46 -0
  106. data/vendor/repo.or.cz/nasm/include/rbtree.h +51 -0
  107. data/vendor/repo.or.cz/nasm/include/rdoff.h +169 -0
  108. data/vendor/repo.or.cz/nasm/include/saa.h +94 -0
  109. data/vendor/repo.or.cz/nasm/include/strlist.h +55 -0
  110. data/vendor/repo.or.cz/nasm/include/tables.h +70 -0
  111. data/vendor/repo.or.cz/nasm/include/ver.h +47 -0
  112. data/vendor/repo.or.cz/nasm/install-sh +250 -0
  113. data/vendor/repo.or.cz/nasm/macros/altreg.mac +107 -0
  114. data/vendor/repo.or.cz/nasm/macros/fp.mac +54 -0
  115. data/vendor/repo.or.cz/nasm/macros/ifunc.mac +48 -0
  116. data/vendor/repo.or.cz/nasm/macros/macros.pl +294 -0
  117. data/vendor/repo.or.cz/nasm/macros/smartalign.mac +189 -0
  118. data/vendor/repo.or.cz/nasm/macros/standard.mac +226 -0
  119. data/vendor/repo.or.cz/nasm/misc/Doxyfile +752 -0
  120. data/vendor/repo.or.cz/nasm/misc/Nindent +18 -0
  121. data/vendor/repo.or.cz/nasm/misc/README +2 -0
  122. data/vendor/repo.or.cz/nasm/misc/c16.mac +82 -0
  123. data/vendor/repo.or.cz/nasm/misc/c32.mac +52 -0
  124. data/vendor/repo.or.cz/nasm/misc/crcgen.c +44 -0
  125. data/vendor/repo.or.cz/nasm/misc/exebin.mac +57 -0
  126. data/vendor/repo.or.cz/nasm/misc/exebin2.mac +114 -0
  127. data/vendor/repo.or.cz/nasm/misc/fmtinsns.pl +40 -0
  128. data/vendor/repo.or.cz/nasm/misc/genfma.pl +63 -0
  129. data/vendor/repo.or.cz/nasm/misc/hints.txt +26 -0
  130. data/vendor/repo.or.cz/nasm/misc/magic +6 -0
  131. data/vendor/repo.or.cz/nasm/misc/myC32.mac +121 -0
  132. data/vendor/repo.or.cz/nasm/misc/nasm.sl +320 -0
  133. data/vendor/repo.or.cz/nasm/misc/nasmstab +296 -0
  134. data/vendor/repo.or.cz/nasm/misc/omfdump.c +517 -0
  135. data/vendor/repo.or.cz/nasm/misc/pmw.bat +9 -0
  136. data/vendor/repo.or.cz/nasm/misc/proc32.ash +441 -0
  137. data/vendor/repo.or.cz/nasm/misc/scitech.mac +1223 -0
  138. data/vendor/repo.or.cz/nasm/misc/xcrcgen.c +80 -0
  139. data/vendor/repo.or.cz/nasm/nasm.spec.in +83 -0
  140. data/vendor/repo.or.cz/nasm/nasm.spec.sed +3 -0
  141. data/vendor/repo.or.cz/nasm/nasm.txt +306 -0
  142. data/vendor/repo.or.cz/nasm/nasmlib/badenum.c +43 -0
  143. data/vendor/repo.or.cz/nasm/nasmlib/bsi.c +77 -0
  144. data/vendor/repo.or.cz/nasm/nasmlib/crc64.c +189 -0
  145. data/vendor/repo.or.cz/nasm/nasmlib/file.c +259 -0
  146. data/vendor/repo.or.cz/nasm/nasmlib/file.h +128 -0
  147. data/vendor/repo.or.cz/nasm/nasmlib/filename.c +69 -0
  148. data/vendor/repo.or.cz/nasm/nasmlib/hashtbl.c +232 -0
  149. data/vendor/repo.or.cz/nasm/nasmlib/ilog2.c +168 -0
  150. data/vendor/repo.or.cz/nasm/nasmlib/malloc.c +108 -0
  151. data/vendor/repo.or.cz/nasm/nasmlib/md5c.c +247 -0
  152. data/vendor/repo.or.cz/nasm/nasmlib/mmap.c +139 -0
  153. data/vendor/repo.or.cz/nasm/nasmlib/path.c +186 -0
  154. data/vendor/repo.or.cz/nasm/nasmlib/perfhash.c +55 -0
  155. data/vendor/repo.or.cz/nasm/nasmlib/perfhash.pl +362 -0
  156. data/vendor/repo.or.cz/nasm/nasmlib/raa.c +173 -0
  157. data/vendor/repo.or.cz/nasm/nasmlib/rbtree.c +119 -0
  158. data/vendor/repo.or.cz/nasm/nasmlib/readnum.c +172 -0
  159. data/vendor/repo.or.cz/nasm/nasmlib/realpath.c +135 -0
  160. data/vendor/repo.or.cz/nasm/nasmlib/saa.c +431 -0
  161. data/vendor/repo.or.cz/nasm/nasmlib/srcfile.c +128 -0
  162. data/vendor/repo.or.cz/nasm/nasmlib/string.c +242 -0
  163. data/vendor/repo.or.cz/nasm/nasmlib/strlist.c +100 -0
  164. data/vendor/repo.or.cz/nasm/nasmlib/ver.c +51 -0
  165. data/vendor/repo.or.cz/nasm/nasmlib/zerobuf.c +42 -0
  166. data/vendor/repo.or.cz/nasm/ndisasm.txt +94 -0
  167. data/vendor/repo.or.cz/nasm/nsis/NASMMultiUser.nsh +478 -0
  168. data/vendor/repo.or.cz/nasm/nsis/getpearch.pl +76 -0
  169. data/vendor/repo.or.cz/nasm/nsis/nasm-un.ico +0 -0
  170. data/vendor/repo.or.cz/nasm/nsis/nasm.ico +0 -0
  171. data/vendor/repo.or.cz/nasm/nsis/nasm.nsi +241 -0
  172. data/vendor/repo.or.cz/nasm/output/codeview.c +814 -0
  173. data/vendor/repo.or.cz/nasm/output/dwarf.h +566 -0
  174. data/vendor/repo.or.cz/nasm/output/elf.h +537 -0
  175. data/vendor/repo.or.cz/nasm/output/legacy.c +112 -0
  176. data/vendor/repo.or.cz/nasm/output/nulldbg.c +93 -0
  177. data/vendor/repo.or.cz/nasm/output/nullout.c +51 -0
  178. data/vendor/repo.or.cz/nasm/output/outaout.c +954 -0
  179. data/vendor/repo.or.cz/nasm/output/outaout.mac +37 -0
  180. data/vendor/repo.or.cz/nasm/output/outas86.c +650 -0
  181. data/vendor/repo.or.cz/nasm/output/outas86.mac +37 -0
  182. data/vendor/repo.or.cz/nasm/output/outbin.c +1713 -0
  183. data/vendor/repo.or.cz/nasm/output/outbin.mac +40 -0
  184. data/vendor/repo.or.cz/nasm/output/outcoff.c +1242 -0
  185. data/vendor/repo.or.cz/nasm/output/outcoff.mac +43 -0
  186. data/vendor/repo.or.cz/nasm/output/outdbg.c +425 -0
  187. data/vendor/repo.or.cz/nasm/output/outelf.c +3370 -0
  188. data/vendor/repo.or.cz/nasm/output/outelf.h +156 -0
  189. data/vendor/repo.or.cz/nasm/output/outelf.mac +41 -0
  190. data/vendor/repo.or.cz/nasm/output/outform.c +120 -0
  191. data/vendor/repo.or.cz/nasm/output/outform.h +379 -0
  192. data/vendor/repo.or.cz/nasm/output/outieee.c +1528 -0
  193. data/vendor/repo.or.cz/nasm/output/outlib.c +58 -0
  194. data/vendor/repo.or.cz/nasm/output/outlib.h +63 -0
  195. data/vendor/repo.or.cz/nasm/output/outmacho.c +2387 -0
  196. data/vendor/repo.or.cz/nasm/output/outmacho.mac +49 -0
  197. data/vendor/repo.or.cz/nasm/output/outobj.c +2725 -0
  198. data/vendor/repo.or.cz/nasm/output/outobj.mac +49 -0
  199. data/vendor/repo.or.cz/nasm/output/outrdf.mac +40 -0
  200. data/vendor/repo.or.cz/nasm/output/outrdf2.c +791 -0
  201. data/vendor/repo.or.cz/nasm/output/outrdf2.mac +43 -0
  202. data/vendor/repo.or.cz/nasm/output/pecoff.h +532 -0
  203. data/vendor/repo.or.cz/nasm/output/stabs.h +144 -0
  204. data/vendor/repo.or.cz/nasm/perllib/crc64.ph +158 -0
  205. data/vendor/repo.or.cz/nasm/perllib/gensv.pl +34 -0
  206. data/vendor/repo.or.cz/nasm/perllib/phash.ph +200 -0
  207. data/vendor/repo.or.cz/nasm/perllib/random_sv_vectors.ph +67 -0
  208. data/vendor/repo.or.cz/nasm/rdoff/README +185 -0
  209. data/vendor/repo.or.cz/nasm/rdoff/collectn.c +44 -0
  210. data/vendor/repo.or.cz/nasm/rdoff/collectn.h +22 -0
  211. data/vendor/repo.or.cz/nasm/rdoff/doc/Makefile +37 -0
  212. data/vendor/repo.or.cz/nasm/rdoff/doc/rdoff.texi +137 -0
  213. data/vendor/repo.or.cz/nasm/rdoff/doc/v1-v2.txt +62 -0
  214. data/vendor/repo.or.cz/nasm/rdoff/hash.c +122 -0
  215. data/vendor/repo.or.cz/nasm/rdoff/hash.h +17 -0
  216. data/vendor/repo.or.cz/nasm/rdoff/ldrdf.1 +41 -0
  217. data/vendor/repo.or.cz/nasm/rdoff/ldrdf.c +1395 -0
  218. data/vendor/repo.or.cz/nasm/rdoff/ldsegs.h +59 -0
  219. data/vendor/repo.or.cz/nasm/rdoff/rdf2bin.1 +65 -0
  220. data/vendor/repo.or.cz/nasm/rdoff/rdf2bin.c +431 -0
  221. data/vendor/repo.or.cz/nasm/rdoff/rdf2com.1 +1 -0
  222. data/vendor/repo.or.cz/nasm/rdoff/rdf2ihx.1 +1 -0
  223. data/vendor/repo.or.cz/nasm/rdoff/rdf2ith.1 +1 -0
  224. data/vendor/repo.or.cz/nasm/rdoff/rdf2srec.1 +1 -0
  225. data/vendor/repo.or.cz/nasm/rdoff/rdfdump.1 +24 -0
  226. data/vendor/repo.or.cz/nasm/rdoff/rdfdump.c +347 -0
  227. data/vendor/repo.or.cz/nasm/rdoff/rdflib.1 +39 -0
  228. data/vendor/repo.or.cz/nasm/rdoff/rdflib.c +434 -0
  229. data/vendor/repo.or.cz/nasm/rdoff/rdfload.c +213 -0
  230. data/vendor/repo.or.cz/nasm/rdoff/rdfload.h +29 -0
  231. data/vendor/repo.or.cz/nasm/rdoff/rdfutils.h +165 -0
  232. data/vendor/repo.or.cz/nasm/rdoff/rdlar.c +492 -0
  233. data/vendor/repo.or.cz/nasm/rdoff/rdlar.h +34 -0
  234. data/vendor/repo.or.cz/nasm/rdoff/rdlib.c +290 -0
  235. data/vendor/repo.or.cz/nasm/rdoff/rdlib.h +62 -0
  236. data/vendor/repo.or.cz/nasm/rdoff/rdoff.c +621 -0
  237. data/vendor/repo.or.cz/nasm/rdoff/rdx.1 +21 -0
  238. data/vendor/repo.or.cz/nasm/rdoff/rdx.c +90 -0
  239. data/vendor/repo.or.cz/nasm/rdoff/segtab.c +172 -0
  240. data/vendor/repo.or.cz/nasm/rdoff/segtab.h +45 -0
  241. data/vendor/repo.or.cz/nasm/rdoff/symtab.c +159 -0
  242. data/vendor/repo.or.cz/nasm/rdoff/symtab.h +55 -0
  243. data/vendor/repo.or.cz/nasm/rdoff/test/Makefile +10 -0
  244. data/vendor/repo.or.cz/nasm/rdoff/test/makelib.sh +14 -0
  245. data/vendor/repo.or.cz/nasm/rdoff/test/rdfseg.asm +20 -0
  246. data/vendor/repo.or.cz/nasm/rdoff/test/rdfseg2.asm +12 -0
  247. data/vendor/repo.or.cz/nasm/rdoff/test/rdftest1.asm +54 -0
  248. data/vendor/repo.or.cz/nasm/rdoff/test/rdftest2.asm +33 -0
  249. data/vendor/repo.or.cz/nasm/rdoff/test/rdtlib.asm +48 -0
  250. data/vendor/repo.or.cz/nasm/rdoff/test/rdtmain.asm +47 -0
  251. data/vendor/repo.or.cz/nasm/rdoff/test/testlib.asm +18 -0
  252. data/vendor/repo.or.cz/nasm/stdlib/snprintf.c +29 -0
  253. data/vendor/repo.or.cz/nasm/stdlib/strlcpy.c +51 -0
  254. data/vendor/repo.or.cz/nasm/stdlib/strnlen.c +46 -0
  255. data/vendor/repo.or.cz/nasm/stdlib/vsnprintf.c +51 -0
  256. data/vendor/repo.or.cz/nasm/test/Makefile +106 -0
  257. data/vendor/repo.or.cz/nasm/test/_file_.asm +5 -0
  258. data/vendor/repo.or.cz/nasm/test/_version.asm +2 -0
  259. data/vendor/repo.or.cz/nasm/test/a32offs.asm +9 -0
  260. data/vendor/repo.or.cz/nasm/test/absolute.asm +40 -0
  261. data/vendor/repo.or.cz/nasm/test/addr64x.asm +18 -0
  262. data/vendor/repo.or.cz/nasm/test/align13.asm +19 -0
  263. data/vendor/repo.or.cz/nasm/test/align13s.asm +20 -0
  264. data/vendor/repo.or.cz/nasm/test/alonesym-obj.asm +166 -0
  265. data/vendor/repo.or.cz/nasm/test/andbyte.asm +15 -0
  266. data/vendor/repo.or.cz/nasm/test/aoutso.asm +99 -0
  267. data/vendor/repo.or.cz/nasm/test/aouttest.asm +86 -0
  268. data/vendor/repo.or.cz/nasm/test/aouttest.c +36 -0
  269. data/vendor/repo.or.cz/nasm/test/avx.asm +46 -0
  270. data/vendor/repo.or.cz/nasm/test/avx005.asm +529 -0
  271. data/vendor/repo.or.cz/nasm/test/avx2.asm +1608 -0
  272. data/vendor/repo.or.cz/nasm/test/avx512cd.asm +106 -0
  273. data/vendor/repo.or.cz/nasm/test/avx512er.asm +144 -0
  274. data/vendor/repo.or.cz/nasm/test/avx512f.asm +7000 -0
  275. data/vendor/repo.or.cz/nasm/test/avx512pf.asm +88 -0
  276. data/vendor/repo.or.cz/nasm/test/bcd.asm +23 -0
  277. data/vendor/repo.or.cz/nasm/test/binexe.asm +35 -0
  278. data/vendor/repo.or.cz/nasm/test/bintest.asm +59 -0
  279. data/vendor/repo.or.cz/nasm/test/bisect.sh +22 -0
  280. data/vendor/repo.or.cz/nasm/test/br1879590.asm +25 -0
  281. data/vendor/repo.or.cz/nasm/test/br2003451.asm +17 -0
  282. data/vendor/repo.or.cz/nasm/test/br2030823.asm +7 -0
  283. data/vendor/repo.or.cz/nasm/test/br2148476.asm +221 -0
  284. data/vendor/repo.or.cz/nasm/test/br2222615.asm +19 -0
  285. data/vendor/repo.or.cz/nasm/test/br2496848.asm +42 -0
  286. data/vendor/repo.or.cz/nasm/test/br3005117.asm +26 -0
  287. data/vendor/repo.or.cz/nasm/test/br3026808.asm +20 -0
  288. data/vendor/repo.or.cz/nasm/test/br3028880.asm +8 -0
  289. data/vendor/repo.or.cz/nasm/test/br3041451.asm +59 -0
  290. data/vendor/repo.or.cz/nasm/test/br3058845.asm +14 -0
  291. data/vendor/repo.or.cz/nasm/test/br3066383.asm +70 -0
  292. data/vendor/repo.or.cz/nasm/test/br3074517.asm +12 -0
  293. data/vendor/repo.or.cz/nasm/test/br3092924.asm +25 -0
  294. data/vendor/repo.or.cz/nasm/test/br3104312.asm +11 -0
  295. data/vendor/repo.or.cz/nasm/test/br3109604.asm +9 -0
  296. data/vendor/repo.or.cz/nasm/test/br3174983.asm +9 -0
  297. data/vendor/repo.or.cz/nasm/test/br3187743.asm +7 -0
  298. data/vendor/repo.or.cz/nasm/test/br3189064.asm +7 -0
  299. data/vendor/repo.or.cz/nasm/test/br3200749.asm +9 -0
  300. data/vendor/repo.or.cz/nasm/test/br3385573.asm +11 -0
  301. data/vendor/repo.or.cz/nasm/test/br3392252.asm +43 -0
  302. data/vendor/repo.or.cz/nasm/test/br3392259.asm +8 -0
  303. data/vendor/repo.or.cz/nasm/test/br3392363.asm +4 -0
  304. data/vendor/repo.or.cz/nasm/test/br3392392.asm +16 -0
  305. data/vendor/repo.or.cz/nasm/test/br3392396.asm +5 -0
  306. data/vendor/repo.or.cz/nasm/test/br3392411.asm +22 -0
  307. data/vendor/repo.or.cz/nasm/test/br3392418.asm +3 -0
  308. data/vendor/repo.or.cz/nasm/test/br3392439.asm +25 -0
  309. data/vendor/repo.or.cz/nasm/test/br3392442.asm +6 -0
  310. data/vendor/repo.or.cz/nasm/test/br560575.asm +17 -0
  311. data/vendor/repo.or.cz/nasm/test/br560873.asm +27 -0
  312. data/vendor/repo.or.cz/nasm/test/br890790.asm +7 -0
  313. data/vendor/repo.or.cz/nasm/test/br890790_i.asm +1 -0
  314. data/vendor/repo.or.cz/nasm/test/br978756.asm +7 -0
  315. data/vendor/repo.or.cz/nasm/test/changed.asm +383 -0
  316. data/vendor/repo.or.cz/nasm/test/cofftest.asm +85 -0
  317. data/vendor/repo.or.cz/nasm/test/cofftest.c +35 -0
  318. data/vendor/repo.or.cz/nasm/test/crc32.asm +37 -0
  319. data/vendor/repo.or.cz/nasm/test/cv8struc.asm +14 -0
  320. data/vendor/repo.or.cz/nasm/test/dtbcd.asm +72 -0
  321. data/vendor/repo.or.cz/nasm/test/elf64so.asm +118 -0
  322. data/vendor/repo.or.cz/nasm/test/elfso.asm +100 -0
  323. data/vendor/repo.or.cz/nasm/test/elftest.asm +87 -0
  324. data/vendor/repo.or.cz/nasm/test/elftest.c +38 -0
  325. data/vendor/repo.or.cz/nasm/test/elftest64.c +43 -0
  326. data/vendor/repo.or.cz/nasm/test/elif.asm +39 -0
  327. data/vendor/repo.or.cz/nasm/test/expimp.asm +90 -0
  328. data/vendor/repo.or.cz/nasm/test/far64.asm +10 -0
  329. data/vendor/repo.or.cz/nasm/test/float.asm +186 -0
  330. data/vendor/repo.or.cz/nasm/test/float8.asm +135 -0
  331. data/vendor/repo.or.cz/nasm/test/floatb.asm +35 -0
  332. data/vendor/repo.or.cz/nasm/test/floatexp.asm +382 -0
  333. data/vendor/repo.or.cz/nasm/test/floatize.asm +19 -0
  334. data/vendor/repo.or.cz/nasm/test/floattest.asm +28 -0
  335. data/vendor/repo.or.cz/nasm/test/floatx.asm +525 -0
  336. data/vendor/repo.or.cz/nasm/test/fpu.asm +127 -0
  337. data/vendor/repo.or.cz/nasm/test/fwdopt.asm +133 -0
  338. data/vendor/repo.or.cz/nasm/test/fwdoptpp.asm +150 -0
  339. data/vendor/repo.or.cz/nasm/test/gas2nasm.py +104 -0
  340. data/vendor/repo.or.cz/nasm/test/gather.asm +11 -0
  341. data/vendor/repo.or.cz/nasm/test/gotoff64.asm +25 -0
  342. data/vendor/repo.or.cz/nasm/test/hexfp.asm +25 -0
  343. data/vendor/repo.or.cz/nasm/test/hle.asm +19 -0
  344. data/vendor/repo.or.cz/nasm/test/ifelse.asm +46 -0
  345. data/vendor/repo.or.cz/nasm/test/ifenv.asm +31 -0
  346. data/vendor/repo.or.cz/nasm/test/ifmacro.asm +413 -0
  347. data/vendor/repo.or.cz/nasm/test/iftoken.asm +317 -0
  348. data/vendor/repo.or.cz/nasm/test/iftoken.pl +32 -0
  349. data/vendor/repo.or.cz/nasm/test/ilog2.asm +271 -0
  350. data/vendor/repo.or.cz/nasm/test/imacro.asm +8 -0
  351. data/vendor/repo.or.cz/nasm/test/imm.asm +23 -0
  352. data/vendor/repo.or.cz/nasm/test/imm64.asm +61 -0
  353. data/vendor/repo.or.cz/nasm/test/immwarn.asm +91 -0
  354. data/vendor/repo.or.cz/nasm/test/imul.asm +117 -0
  355. data/vendor/repo.or.cz/nasm/test/inc1.asm +6 -0
  356. data/vendor/repo.or.cz/nasm/test/inc2.asm +8 -0
  357. data/vendor/repo.or.cz/nasm/test/incbin.asm +7 -0
  358. data/vendor/repo.or.cz/nasm/test/incbin.data +2 -0
  359. data/vendor/repo.or.cz/nasm/test/inctest.asm +15 -0
  360. data/vendor/repo.or.cz/nasm/test/insnlbl.asm +12 -0
  361. data/vendor/repo.or.cz/nasm/test/invlpga.asm +11 -0
  362. data/vendor/repo.or.cz/nasm/test/jmp64.asm +19 -0
  363. data/vendor/repo.or.cz/nasm/test/lar_lsl.asm +124 -0
  364. data/vendor/repo.or.cz/nasm/test/larlsl.asm +23 -0
  365. data/vendor/repo.or.cz/nasm/test/lnxhello.asm +54 -0
  366. data/vendor/repo.or.cz/nasm/test/local.asm +19 -0
  367. data/vendor/repo.or.cz/nasm/test/loopoffs.asm +12 -0
  368. data/vendor/repo.or.cz/nasm/test/lwp.asm +213 -0
  369. data/vendor/repo.or.cz/nasm/test/macro-defaults.asm +64 -0
  370. data/vendor/repo.or.cz/nasm/test/macroerr.asm +12 -0
  371. data/vendor/repo.or.cz/nasm/test/macroerr.inc +3 -0
  372. data/vendor/repo.or.cz/nasm/test/mmxsize.asm +38 -0
  373. data/vendor/repo.or.cz/nasm/test/movd.asm +12 -0
  374. data/vendor/repo.or.cz/nasm/test/movd64.asm +15 -0
  375. data/vendor/repo.or.cz/nasm/test/movimm.asm +28 -0
  376. data/vendor/repo.or.cz/nasm/test/movnti.asm +10 -0
  377. data/vendor/repo.or.cz/nasm/test/mpx-64.asm +120 -0
  378. data/vendor/repo.or.cz/nasm/test/mpx.asm +89 -0
  379. data/vendor/repo.or.cz/nasm/test/multisection.asm +96 -0
  380. data/vendor/repo.or.cz/nasm/test/nasmformat.asm +17 -0
  381. data/vendor/repo.or.cz/nasm/test/new +9 -0
  382. data/vendor/repo.or.cz/nasm/test/newrdwr.asm +24 -0
  383. data/vendor/repo.or.cz/nasm/test/nop.asm +17 -0
  384. data/vendor/repo.or.cz/nasm/test/nullfile.asm +4 -0
  385. data/vendor/repo.or.cz/nasm/test/objexe.asm +30 -0
  386. data/vendor/repo.or.cz/nasm/test/objlink.c +33 -0
  387. data/vendor/repo.or.cz/nasm/test/objtest.asm +85 -0
  388. data/vendor/repo.or.cz/nasm/test/optimization.asm +104 -0
  389. data/vendor/repo.or.cz/nasm/test/org.asm +18 -0
  390. data/vendor/repo.or.cz/nasm/test/paste.asm +12 -0
  391. data/vendor/repo.or.cz/nasm/test/pcrel.asm +52 -0
  392. data/vendor/repo.or.cz/nasm/test/perf/label.pl +18 -0
  393. data/vendor/repo.or.cz/nasm/test/perf/macro.pl +18 -0
  394. data/vendor/repo.or.cz/nasm/test/perf/token.pl +23 -0
  395. data/vendor/repo.or.cz/nasm/test/performtest.pl +192 -0
  396. data/vendor/repo.or.cz/nasm/test/pextrw.asm +3 -0
  397. data/vendor/repo.or.cz/nasm/test/pinsr16.asm +53 -0
  398. data/vendor/repo.or.cz/nasm/test/pinsr32.asm +53 -0
  399. data/vendor/repo.or.cz/nasm/test/pinsr64.asm +68 -0
  400. data/vendor/repo.or.cz/nasm/test/popcnt.asm +32 -0
  401. data/vendor/repo.or.cz/nasm/test/ppindirect.asm +42 -0
  402. data/vendor/repo.or.cz/nasm/test/pragma.asm +12 -0
  403. data/vendor/repo.or.cz/nasm/test/prefix66.asm +28 -0
  404. data/vendor/repo.or.cz/nasm/test/ptr.asm +4 -0
  405. data/vendor/repo.or.cz/nasm/test/pushseg.asm +17 -0
  406. data/vendor/repo.or.cz/nasm/test/r13.asm +15 -0
  407. data/vendor/repo.or.cz/nasm/test/radix.asm +54 -0
  408. data/vendor/repo.or.cz/nasm/test/rdpid.asm +21 -0
  409. data/vendor/repo.or.cz/nasm/test/reldef.asm +57 -0
  410. data/vendor/repo.or.cz/nasm/test/relocs.asm +20 -0
  411. data/vendor/repo.or.cz/nasm/test/riprel.asm +5357 -0
  412. data/vendor/repo.or.cz/nasm/test/riprel.pl +29 -0
  413. data/vendor/repo.or.cz/nasm/test/riprel2.asm +11 -0
  414. data/vendor/repo.or.cz/nasm/test/sha-64.asm +30 -0
  415. data/vendor/repo.or.cz/nasm/test/sha.asm +31 -0
  416. data/vendor/repo.or.cz/nasm/test/smartalign16.asm +36 -0
  417. data/vendor/repo.or.cz/nasm/test/smartalign32.asm +36 -0
  418. data/vendor/repo.or.cz/nasm/test/smartalign64.asm +36 -0
  419. data/vendor/repo.or.cz/nasm/test/splitea.asm +11 -0
  420. data/vendor/repo.or.cz/nasm/test/sreg.asm +65 -0
  421. data/vendor/repo.or.cz/nasm/test/strlen.asm +5 -0
  422. data/vendor/repo.or.cz/nasm/test/struc.asm +33 -0
  423. data/vendor/repo.or.cz/nasm/test/test67.asm +38 -0
  424. data/vendor/repo.or.cz/nasm/test/testdos.asm +13 -0
  425. data/vendor/repo.or.cz/nasm/test/testnos3.asm +973 -0
  426. data/vendor/repo.or.cz/nasm/test/time.asm +11 -0
  427. data/vendor/repo.or.cz/nasm/test/times.asm +21 -0
  428. data/vendor/repo.or.cz/nasm/test/timesneg.asm +3 -0
  429. data/vendor/repo.or.cz/nasm/test/tmap.nas +1447 -0
  430. data/vendor/repo.or.cz/nasm/test/uscore.asm +15 -0
  431. data/vendor/repo.or.cz/nasm/test/utf.asm +82 -0
  432. data/vendor/repo.or.cz/nasm/test/vaesenc.asm +22 -0
  433. data/vendor/repo.or.cz/nasm/test/vex.asm +9 -0
  434. data/vendor/repo.or.cz/nasm/test/vgather.asm +76 -0
  435. data/vendor/repo.or.cz/nasm/test/vmread.asm +26 -0
  436. data/vendor/repo.or.cz/nasm/test/weirdpaste.asm +29 -0
  437. data/vendor/repo.or.cz/nasm/test/xchg.asm +96 -0
  438. data/vendor/repo.or.cz/nasm/test/xcrypt.asm +24 -0
  439. data/vendor/repo.or.cz/nasm/test/xmm0.asm +12 -0
  440. data/vendor/repo.or.cz/nasm/test/zerobyte.asm +22 -0
  441. data/vendor/repo.or.cz/nasm/tools/cleanfile +176 -0
  442. data/vendor/repo.or.cz/nasm/tools/cleanpatch +258 -0
  443. data/vendor/repo.or.cz/nasm/tools/mkdep.pl +261 -0
  444. data/vendor/repo.or.cz/nasm/tools/release +105 -0
  445. data/vendor/repo.or.cz/nasm/tools/syncfiles.pl +137 -0
  446. data/vendor/repo.or.cz/nasm/tools/tag-release +58 -0
  447. data/vendor/repo.or.cz/nasm/version +1 -0
  448. data/vendor/repo.or.cz/nasm/version.pl +189 -0
  449. data/vendor/repo.or.cz/nasm/x86/disp8.c +131 -0
  450. data/vendor/repo.or.cz/nasm/x86/insns-iflags.ph +280 -0
  451. data/vendor/repo.or.cz/nasm/x86/insns.dat +5371 -0
  452. data/vendor/repo.or.cz/nasm/x86/insns.pl +1043 -0
  453. data/vendor/repo.or.cz/nasm/x86/regs.dat +138 -0
  454. data/vendor/repo.or.cz/nasm/x86/regs.pl +204 -0
  455. metadata +520 -0
@@ -0,0 +1,139 @@
1
+ dnl --------------------------------------------------------------------------
2
+ dnl PA_ADD_CFLAGS()
3
+ dnl
4
+ dnl Attempt to add the given option to CFLAGS, if it doesn't break compilation
5
+ dnl --------------------------------------------------------------------------
6
+ AC_DEFUN(PA_ADD_CFLAGS,
7
+ [AC_MSG_CHECKING([if $CC accepts $1])
8
+ pa_add_cflags__old_cflags="$CFLAGS"
9
+ CFLAGS="$CFLAGS $1"
10
+ AC_TRY_LINK(AC_INCLUDES_DEFAULT,
11
+ [printf("Hello, World!\n");],
12
+ [AC_MSG_RESULT([yes])
13
+ CFLAGS="$pa_add_cflags__old_cflags ifelse([$2],[],[$1],[$2])"],
14
+ [AC_MSG_RESULT([no])
15
+ CFLAGS="$pa_add_cflags__old_cflags"])])
16
+
17
+ dnl --------------------------------------------------------------------------
18
+ dnl PA_ADD_CLDFLAGS()
19
+ dnl
20
+ dnl Attempt to add the given option to CFLAGS and LDFLAGS,
21
+ dnl if it doesn't break compilation
22
+ dnl --------------------------------------------------------------------------
23
+ AC_DEFUN(PA_ADD_CLDFLAGS,
24
+ [AC_MSG_CHECKING([if $CC accepts $1])
25
+ pa_add_cldflags__old_cflags="$CFLAGS"
26
+ CFLAGS="$CFLAGS $1"
27
+ pa_add_cldflags__old_ldflags="$LDFLAGS"
28
+ LDFLAGS="$LDFLAGS $1"
29
+ AC_TRY_LINK(AC_INCLUDES_DEFAULT,
30
+ [printf("Hello, World!\n");],
31
+ [AC_MSG_RESULT([yes])
32
+ CFLAGS="$pa_add_cldflags__old_cflags ifelse([$2],[],[$1],[$2])"
33
+ LDFLAGS="$pa_add_cldflags__old_ldflags ifelse([$2],[],[$1],[$2])"],
34
+ [AC_MSG_RESULT([no])
35
+ CFLAGS="$pa_add_cldflags__old_cflags"
36
+ LDFLAGS="$pa_add_cldflags__old_ldflags"])])
37
+
38
+ dnl --------------------------------------------------------------------------
39
+ dnl PA_HAVE_FUNC
40
+ dnl
41
+ dnl Look for a function with the specified arguments which could be
42
+ dnl a builtin/intrinsic function.
43
+ dnl --------------------------------------------------------------------------
44
+ AC_DEFUN(PA_HAVE_FUNC,
45
+ [AC_MSG_CHECKING([for $1])
46
+ AC_TRY_LINK([], [(void)$1$2;],
47
+ AC_MSG_RESULT([yes])
48
+ AC_DEFINE(m4_toupper([HAVE_$1]), [1],
49
+ [Define to 1 if you have the `$1' intrinsic function.]),
50
+ AC_MSG_RESULT([no]))])
51
+
52
+ dnl --------------------------------------------------------------------------
53
+ dnl PA_LIBEXT
54
+ dnl
55
+ dnl Guess the library extension based on the object extension
56
+ dnl --------------------------------------------------------------------------
57
+ AC_DEFUN(PA_LIBEXT,
58
+ [AC_MSG_CHECKING([for suffix of library files])
59
+ if test x"$LIBEXT" = x; then
60
+ case "$OBJEXT" in
61
+ obj )
62
+ LIBEXT=lib
63
+ ;;
64
+ *)
65
+ LIBEXT=a
66
+ ;;
67
+ esac
68
+ fi
69
+ AC_MSG_RESULT([$LIBEXT])
70
+ AC_SUBST([LIBEXT])])
71
+
72
+ dnl --------------------------------------------------------------------------
73
+ dnl PA_FUNC_ATTRIBUTE
74
+ dnl
75
+ dnl See if this compiler supports the equivalent of a specific gcc
76
+ dnl attribute on a function, using the __attribute__(()) syntax.
77
+ dnl All arguments except the attribute name are optional.
78
+ dnl PA_FUNC_ATTRIBUTE(attribute, attribute_opts, return_type,
79
+ dnl prototype_args, call_args)
80
+ dnl --------------------------------------------------------------------------
81
+ AC_DEFUN(PA_FUNC_ATTRIBUTE,
82
+ [AC_MSG_CHECKING([if $CC supports the $1 function attribute])
83
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
84
+ #include <stdarg.h>
85
+ extern ifelse([$3],[],[void *],[$3]) __attribute__(($1$2))
86
+ bar(ifelse([$4],[],[int],[$4]));
87
+ void *foo(void);
88
+ void *foo(void)
89
+ {
90
+ return bar(ifelse([$5],[],[1],[$5]));
91
+ }
92
+ ])],
93
+ [AC_MSG_RESULT([yes])
94
+ AC_DEFINE(m4_toupper([HAVE_FUNC_ATTRIBUTE_$1]), 1,
95
+ [Define to 1 if your compiler supports __attribute__(($1)) on functions])],
96
+ [AC_MSG_RESULT([no])])
97
+ ])
98
+
99
+ dnl --------------------------------------------------------------------------
100
+ dnl PA_FUNC_ATTRIBUTE_ERROR
101
+ dnl
102
+ dnl See if this compiler supports __attribute__((error("foo")))
103
+ dnl The generic version of this doesn't work as it makes the compiler
104
+ dnl throw an error by design.
105
+ dnl --------------------------------------------------------------------------
106
+ AC_DEFUN(PA_FUNC_ATTRIBUTE_ERROR,
107
+ [AC_MSG_CHECKING([if $CC supports the error function attribute])
108
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
109
+ #include <stdarg.h>
110
+ extern void __attribute__((error("message"))) barf(void);
111
+ void foo(void);
112
+ void foo(void)
113
+ {
114
+ if (0)
115
+ barf();
116
+ }
117
+ ])],
118
+ [AC_MSG_RESULT([yes])
119
+ AC_DEFINE(m4_toupper([HAVE_FUNC_ATTRIBUTE_ERROR]), 1,
120
+ [Define to 1 if your compiler supports __attribute__((error)) on functions])],
121
+ [AC_MSG_RESULT([no])])
122
+ ])
123
+
124
+ dnl --------------------------------------------------------------------------
125
+ dnl PA_ARG_ENABLED
126
+ dnl PA_ARG_DISABLED
127
+ dnl
128
+ dnl Simpler-to-use versions of AC_ARG_ENABLED, that include the
129
+ dnl test for $enableval and the AS_HELP_STRING definition
130
+ dnl --------------------------------------------------------------------------
131
+ AC_DEFUN(PA_ARG_ENABLED,
132
+ [AC_ARG_ENABLE([$1], [AS_HELP_STRING([--enable-$1],[$2])], [], [enableval=no])
133
+ AS_IF([test x"$enableval" != xno], [$3], [$4])
134
+ ])
135
+
136
+ AC_DEFUN(PA_ARG_DISABLED,
137
+ [AC_ARG_ENABLE([$1],[AS_HELP_STRING([--disable-$1],[$2])], [], [enableval=yes])
138
+ AS_IF([test x"$enableval" = xno], [$3], [$4])
139
+ ])
@@ -0,0 +1,2957 @@
1
+ /* ----------------------------------------------------------------------- *
2
+ *
3
+ * Copyright 1996-2018 The NASM Authors - All Rights Reserved
4
+ * See the file AUTHORS included with the NASM distribution for
5
+ * the specific copyright holders.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following
9
+ * conditions are met:
10
+ *
11
+ * * Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ * * Redistributions in binary form must reproduce the above
14
+ * copyright notice, this list of conditions and the following
15
+ * disclaimer in the documentation and/or other materials provided
16
+ * with the distribution.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ * ----------------------------------------------------------------------- */
33
+
34
+ /*
35
+ * assemble.c code generation for the Netwide Assembler
36
+ *
37
+ * Bytecode specification
38
+ * ----------------------
39
+ *
40
+ *
41
+ * Codes Mnemonic Explanation
42
+ *
43
+ * \0 terminates the code. (Unless it's a literal of course.)
44
+ * \1..\4 that many literal bytes follow in the code stream
45
+ * \5 add 4 to the primary operand number (b, low octdigit)
46
+ * \6 add 4 to the secondary operand number (a, middle octdigit)
47
+ * \7 add 4 to both the primary and the secondary operand number
48
+ * \10..\13 a literal byte follows in the code stream, to be added
49
+ * to the register value of operand 0..3
50
+ * \14..\17 the position of index register operand in MIB (BND insns)
51
+ * \20..\23 ib a byte immediate operand, from operand 0..3
52
+ * \24..\27 ib,u a zero-extended byte immediate operand, from operand 0..3
53
+ * \30..\33 iw a word immediate operand, from operand 0..3
54
+ * \34..\37 iwd select between \3[0-3] and \4[0-3] depending on 16/32 bit
55
+ * assembly mode or the operand-size override on the operand
56
+ * \40..\43 id a long immediate operand, from operand 0..3
57
+ * \44..\47 iwdq select between \3[0-3], \4[0-3] and \5[4-7]
58
+ * depending on the address size of the instruction.
59
+ * \50..\53 rel8 a byte relative operand, from operand 0..3
60
+ * \54..\57 iq a qword immediate operand, from operand 0..3
61
+ * \60..\63 rel16 a word relative operand, from operand 0..3
62
+ * \64..\67 rel select between \6[0-3] and \7[0-3] depending on 16/32 bit
63
+ * assembly mode or the operand-size override on the operand
64
+ * \70..\73 rel32 a long relative operand, from operand 0..3
65
+ * \74..\77 seg a word constant, from the _segment_ part of operand 0..3
66
+ * \1ab a ModRM, calculated on EA in operand a, with the spare
67
+ * field the register value of operand b.
68
+ * \172\ab the register number from operand a in bits 7..4, with
69
+ * the 4-bit immediate from operand b in bits 3..0.
70
+ * \173\xab the register number from operand a in bits 7..4, with
71
+ * the value b in bits 3..0.
72
+ * \174..\177 the register number from operand 0..3 in bits 7..4, and
73
+ * an arbitrary value in bits 3..0 (assembled as zero.)
74
+ * \2ab a ModRM, calculated on EA in operand a, with the spare
75
+ * field equal to digit b.
76
+ *
77
+ * \240..\243 this instruction uses EVEX rather than REX or VEX/XOP, with the
78
+ * V field taken from operand 0..3.
79
+ * \250 this instruction uses EVEX rather than REX or VEX/XOP, with the
80
+ * V field set to 1111b.
81
+ *
82
+ * EVEX prefixes are followed by the sequence:
83
+ * \cm\wlp\tup where cm is:
84
+ * cc 00m mmm
85
+ * c = 2 for EVEX and mmmm is the M field (EVEX.P0[3:0])
86
+ * and wlp is:
87
+ * 00 wwl lpp
88
+ * [l0] ll = 0 (.128, .lz)
89
+ * [l1] ll = 1 (.256)
90
+ * [l2] ll = 2 (.512)
91
+ * [lig] ll = 3 for EVEX.L'L don't care (always assembled as 0)
92
+ *
93
+ * [w0] ww = 0 for W = 0
94
+ * [w1] ww = 1 for W = 1
95
+ * [wig] ww = 2 for W don't care (always assembled as 0)
96
+ * [ww] ww = 3 for W used as REX.W
97
+ *
98
+ * [p0] pp = 0 for no prefix
99
+ * [60] pp = 1 for legacy prefix 60
100
+ * [f3] pp = 2
101
+ * [f2] pp = 3
102
+ *
103
+ * tup is tuple type for Disp8*N from %tuple_codes in insns.pl
104
+ * (compressed displacement encoding)
105
+ *
106
+ * \254..\257 id,s a signed 32-bit operand to be extended to 64 bits.
107
+ * \260..\263 this instruction uses VEX/XOP rather than REX, with the
108
+ * V field taken from operand 0..3.
109
+ * \270 this instruction uses VEX/XOP rather than REX, with the
110
+ * V field set to 1111b.
111
+ *
112
+ * VEX/XOP prefixes are followed by the sequence:
113
+ * \tmm\wlp where mm is the M field; and wlp is:
114
+ * 00 wwl lpp
115
+ * [l0] ll = 0 for L = 0 (.128, .lz)
116
+ * [l1] ll = 1 for L = 1 (.256)
117
+ * [lig] ll = 2 for L don't care (always assembled as 0)
118
+ *
119
+ * [w0] ww = 0 for W = 0
120
+ * [w1 ] ww = 1 for W = 1
121
+ * [wig] ww = 2 for W don't care (always assembled as 0)
122
+ * [ww] ww = 3 for W used as REX.W
123
+ *
124
+ * t = 0 for VEX (C4/C5), t = 1 for XOP (8F).
125
+ *
126
+ * \271 hlexr instruction takes XRELEASE (F3) with or without lock
127
+ * \272 hlenl instruction takes XACQUIRE/XRELEASE with or without lock
128
+ * \273 hle instruction takes XACQUIRE/XRELEASE with lock only
129
+ * \274..\277 ib,s a byte immediate operand, from operand 0..3, sign-extended
130
+ * to the operand size (if o16/o32/o64 present) or the bit size
131
+ * \310 a16 indicates fixed 16-bit address size, i.e. optional 0x67.
132
+ * \311 a32 indicates fixed 32-bit address size, i.e. optional 0x67.
133
+ * \312 adf (disassembler only) invalid with non-default address size.
134
+ * \313 a64 indicates fixed 64-bit address size, 0x67 invalid.
135
+ * \314 norexb (disassembler only) invalid with REX.B
136
+ * \315 norexx (disassembler only) invalid with REX.X
137
+ * \316 norexr (disassembler only) invalid with REX.R
138
+ * \317 norexw (disassembler only) invalid with REX.W
139
+ * \320 o16 indicates fixed 16-bit operand size, i.e. optional 0x66.
140
+ * \321 o32 indicates fixed 32-bit operand size, i.e. optional 0x66.
141
+ * \322 odf indicates that this instruction is only valid when the
142
+ * operand size is the default (instruction to disassembler,
143
+ * generates no code in the assembler)
144
+ * \323 o64nw indicates fixed 64-bit operand size, REX on extensions only.
145
+ * \324 o64 indicates 64-bit operand size requiring REX prefix.
146
+ * \325 nohi instruction which always uses spl/bpl/sil/dil
147
+ * \326 nof3 instruction not valid with 0xF3 REP prefix. Hint for
148
+ disassembler only; for SSE instructions.
149
+ * \330 a literal byte follows in the code stream, to be added
150
+ * to the condition code value of the instruction.
151
+ * \331 norep instruction not valid with REP prefix. Hint for
152
+ * disassembler only; for SSE instructions.
153
+ * \332 f2i REP prefix (0xF2 byte) used as opcode extension.
154
+ * \333 f3i REP prefix (0xF3 byte) used as opcode extension.
155
+ * \334 rex.l LOCK prefix used as REX.R (used in non-64-bit mode)
156
+ * \335 repe disassemble a rep (0xF3 byte) prefix as repe not rep.
157
+ * \336 mustrep force a REP(E) prefix (0xF3) even if not specified.
158
+ * \337 mustrepne force a REPNE prefix (0xF2) even if not specified.
159
+ * \336-\337 are still listed as prefixes in the disassembler.
160
+ * \340 resb reserve <operand 0> bytes of uninitialized storage.
161
+ * Operand 0 had better be a segmentless constant.
162
+ * \341 wait this instruction needs a WAIT "prefix"
163
+ * \360 np no SSE prefix (== \364\331)
164
+ * \361 66 SSE prefix (== \366\331)
165
+ * \364 !osp operand-size prefix (0x66) not permitted
166
+ * \365 !asp address-size prefix (0x67) not permitted
167
+ * \366 operand-size prefix (0x66) used as opcode extension
168
+ * \367 address-size prefix (0x67) used as opcode extension
169
+ * \370,\371 jcc8 match only if operand 0 meets byte jump criteria.
170
+ * jmp8 370 is used for Jcc, 371 is used for JMP.
171
+ * \373 jlen assemble 0x03 if bits==16, 0x05 if bits==32;
172
+ * used for conditional jump over longer jump
173
+ * \374 vsibx|vm32x|vm64x this instruction takes an XMM VSIB memory EA
174
+ * \375 vsiby|vm32y|vm64y this instruction takes an YMM VSIB memory EA
175
+ * \376 vsibz|vm32z|vm64z this instruction takes an ZMM VSIB memory EA
176
+ */
177
+
178
+ #include "compiler.h"
179
+
180
+ #include <stdio.h>
181
+ #include <string.h>
182
+ #include <stdlib.h>
183
+
184
+ #include "nasm.h"
185
+ #include "nasmlib.h"
186
+ #include "error.h"
187
+ #include "assemble.h"
188
+ #include "insns.h"
189
+ #include "tables.h"
190
+ #include "disp8.h"
191
+ #include "listing.h"
192
+
193
+ enum match_result {
194
+ /*
195
+ * Matching errors. These should be sorted so that more specific
196
+ * errors come later in the sequence.
197
+ */
198
+ MERR_INVALOP,
199
+ MERR_OPSIZEMISSING,
200
+ MERR_OPSIZEMISMATCH,
201
+ MERR_BRNOTHERE,
202
+ MERR_BRNUMMISMATCH,
203
+ MERR_MASKNOTHERE,
204
+ MERR_DECONOTHERE,
205
+ MERR_BADCPU,
206
+ MERR_BADMODE,
207
+ MERR_BADHLE,
208
+ MERR_ENCMISMATCH,
209
+ MERR_BADBND,
210
+ MERR_BADREPNE,
211
+ /*
212
+ * Matching success; the conditional ones first
213
+ */
214
+ MOK_JUMP, /* Matching OK but needs jmp_match() */
215
+ MOK_GOOD /* Matching unconditionally OK */
216
+ };
217
+
218
+ typedef struct {
219
+ enum ea_type type; /* what kind of EA is this? */
220
+ int sib_present; /* is a SIB byte necessary? */
221
+ int bytes; /* # of bytes of offset needed */
222
+ int size; /* lazy - this is sib+bytes+1 */
223
+ uint8_t modrm, sib, rex, rip; /* the bytes themselves */
224
+ int8_t disp8; /* compressed displacement for EVEX */
225
+ } ea;
226
+
227
+ #define GEN_SIB(scale, index, base) \
228
+ (((scale) << 6) | ((index) << 3) | ((base)))
229
+
230
+ #define GEN_MODRM(mod, reg, rm) \
231
+ (((mod) << 6) | (((reg) & 7) << 3) | ((rm) & 7))
232
+
233
+ static int64_t calcsize(int32_t, int64_t, int, insn *,
234
+ const struct itemplate *);
235
+ static int emit_prefix(struct out_data *data, const int bits, insn *ins);
236
+ static void gencode(struct out_data *data, insn *ins);
237
+ static enum match_result find_match(const struct itemplate **tempp,
238
+ insn *instruction,
239
+ int32_t segment, int64_t offset, int bits);
240
+ static enum match_result matches(const struct itemplate *, insn *, int bits);
241
+ static opflags_t regflag(const operand *);
242
+ static int32_t regval(const operand *);
243
+ static int rexflags(int, opflags_t, int);
244
+ static int op_rexflags(const operand *, int);
245
+ static int op_evexflags(const operand *, int, uint8_t);
246
+ static void add_asp(insn *, int);
247
+
248
+ static enum ea_type process_ea(operand *, ea *, int, int,
249
+ opflags_t, insn *, const char **);
250
+
251
+ static inline bool absolute_op(const struct operand *o)
252
+ {
253
+ return o->segment == NO_SEG && o->wrt == NO_SEG &&
254
+ !(o->opflags & OPFLAG_RELATIVE);
255
+ }
256
+
257
+ static int has_prefix(insn * ins, enum prefix_pos pos, int prefix)
258
+ {
259
+ return ins->prefixes[pos] == prefix;
260
+ }
261
+
262
+ static void assert_no_prefix(insn * ins, enum prefix_pos pos)
263
+ {
264
+ if (ins->prefixes[pos])
265
+ nasm_error(ERR_NONFATAL, "invalid %s prefix",
266
+ prefix_name(ins->prefixes[pos]));
267
+ }
268
+
269
+ static const char *size_name(int size)
270
+ {
271
+ switch (size) {
272
+ case 1:
273
+ return "byte";
274
+ case 2:
275
+ return "word";
276
+ case 4:
277
+ return "dword";
278
+ case 8:
279
+ return "qword";
280
+ case 10:
281
+ return "tword";
282
+ case 16:
283
+ return "oword";
284
+ case 32:
285
+ return "yword";
286
+ case 64:
287
+ return "zword";
288
+ default:
289
+ return "???";
290
+ }
291
+ }
292
+
293
+ static void warn_overflow(int size)
294
+ {
295
+ nasm_error(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
296
+ "%s data exceeds bounds", size_name(size));
297
+ }
298
+
299
+ static void warn_overflow_const(int64_t data, int size)
300
+ {
301
+ if (overflow_general(data, size))
302
+ warn_overflow(size);
303
+ }
304
+
305
+ static void warn_overflow_out(int64_t data, int size, enum out_sign sign)
306
+ {
307
+ bool err;
308
+
309
+ switch (sign) {
310
+ case OUT_WRAP:
311
+ err = overflow_general(data, size);
312
+ break;
313
+ case OUT_SIGNED:
314
+ err = overflow_signed(data, size);
315
+ break;
316
+ case OUT_UNSIGNED:
317
+ err = overflow_unsigned(data, size);
318
+ break;
319
+ default:
320
+ panic();
321
+ break;
322
+ }
323
+
324
+ if (err)
325
+ warn_overflow(size);
326
+ }
327
+
328
+ /*
329
+ * This routine wrappers the real output format's output routine,
330
+ * in order to pass a copy of the data off to the listing file
331
+ * generator at the same time, flatten unnecessary relocations,
332
+ * and verify backend compatibility.
333
+ */
334
+ static void out(struct out_data *data)
335
+ {
336
+ static int32_t lineno = 0; /* static!!! */
337
+ static const char *lnfname = NULL;
338
+ int asize;
339
+ const int amax = ofmt->maxbits >> 3; /* Maximum address size in bytes */
340
+ union {
341
+ uint8_t b[8];
342
+ uint64_t q;
343
+ } xdata;
344
+ uint64_t size = data->size;
345
+ int64_t addrval;
346
+ int32_t fixseg; /* Segment for which to produce fixed data */
347
+
348
+ if (!data->size)
349
+ return; /* Nothing to do */
350
+
351
+ /*
352
+ * Convert addresses to RAWDATA if possible
353
+ * XXX: not all backends want this for global symbols!!!!
354
+ */
355
+ switch (data->type) {
356
+ case OUT_ADDRESS:
357
+ addrval = data->toffset;
358
+ fixseg = NO_SEG; /* Absolute address is fixed data */
359
+ goto address;
360
+
361
+ case OUT_RELADDR:
362
+ addrval = data->toffset - data->relbase;
363
+ fixseg = data->segment; /* Our own segment is fixed data */
364
+ goto address;
365
+
366
+ address:
367
+ asize = data->size;
368
+ nasm_assert(asize <= 8);
369
+ if (data->tsegment == fixseg && data->twrt == NO_SEG) {
370
+ uint8_t *q = xdata.b;
371
+
372
+ warn_overflow_out(addrval, asize, data->sign);
373
+
374
+ WRITEADDR(q, addrval, asize);
375
+ data->data = xdata.b;
376
+ data->type = OUT_RAWDATA;
377
+ asize = 0; /* No longer an address */
378
+ }
379
+ break;
380
+
381
+ default:
382
+ asize = 0; /* Not an address */
383
+ break;
384
+ }
385
+
386
+ lfmt->output(data);
387
+
388
+ /*
389
+ * this call to src_get determines when we call the
390
+ * debug-format-specific "linenum" function
391
+ * it updates lineno and lnfname to the current values
392
+ * returning 0 if "same as last time", -2 if lnfname
393
+ * changed, and the amount by which lineno changed,
394
+ * if it did. thus, these variables must be static
395
+ */
396
+
397
+ if (src_get(&lineno, &lnfname))
398
+ dfmt->linenum(lnfname, lineno, data->segment);
399
+
400
+ if (asize && asize > amax) {
401
+ if (data->type != OUT_ADDRESS || data->sign == OUT_SIGNED) {
402
+ nasm_error(ERR_NONFATAL,
403
+ "%d-bit signed relocation unsupported by output format %s\n",
404
+ asize << 3, ofmt->shortname);
405
+ } else {
406
+ nasm_error(ERR_WARNING | ERR_WARN_ZEXTRELOC,
407
+ "%d-bit unsigned relocation zero-extended from %d bits\n",
408
+ asize << 3, ofmt->maxbits);
409
+ data->size = amax;
410
+ ofmt->output(data);
411
+ data->insoffs += amax;
412
+ data->offset += amax;
413
+ data->size = size = asize - amax;
414
+ }
415
+ data->data = zero_buffer;
416
+ data->type = OUT_RAWDATA;
417
+ }
418
+
419
+ ofmt->output(data);
420
+ data->offset += size;
421
+ data->insoffs += size;
422
+ }
423
+
424
+ static inline void out_rawdata(struct out_data *data, const void *rawdata,
425
+ size_t size)
426
+ {
427
+ data->type = OUT_RAWDATA;
428
+ data->data = rawdata;
429
+ data->size = size;
430
+ out(data);
431
+ }
432
+
433
+ static void out_rawbyte(struct out_data *data, uint8_t byte)
434
+ {
435
+ data->type = OUT_RAWDATA;
436
+ data->data = &byte;
437
+ data->size = 1;
438
+ out(data);
439
+ }
440
+
441
+ static inline void out_reserve(struct out_data *data, uint64_t size)
442
+ {
443
+ data->type = OUT_RESERVE;
444
+ data->size = size;
445
+ out(data);
446
+ }
447
+
448
+ static inline void out_imm(struct out_data *data, const struct operand *opx,
449
+ int size, enum out_sign sign)
450
+ {
451
+ data->type =
452
+ (opx->opflags & OPFLAG_RELATIVE) ? OUT_RELADDR : OUT_ADDRESS;
453
+ data->sign = sign;
454
+ data->size = size;
455
+ data->toffset = opx->offset;
456
+ data->tsegment = opx->segment;
457
+ data->twrt = opx->wrt;
458
+ /*
459
+ * XXX: improve this if at some point in the future we can
460
+ * distinguish the subtrahend in expressions like [foo - bar]
461
+ * where bar is a symbol in the current segment. However, at the
462
+ * current point, if OPFLAG_RELATIVE is set that subtraction has
463
+ * already occurred.
464
+ */
465
+ data->relbase = 0;
466
+ out(data);
467
+ }
468
+
469
+ static void out_reladdr(struct out_data *data, const struct operand *opx,
470
+ int size)
471
+ {
472
+ if (opx->opflags & OPFLAG_RELATIVE)
473
+ nasm_error(ERR_NONFATAL, "invalid use of self-relative expression");
474
+
475
+ data->type = OUT_RELADDR;
476
+ data->sign = OUT_SIGNED;
477
+ data->size = size;
478
+ data->toffset = opx->offset;
479
+ data->tsegment = opx->segment;
480
+ data->twrt = opx->wrt;
481
+ data->relbase = data->offset + (data->inslen - data->insoffs);
482
+ out(data);
483
+ }
484
+
485
+ static inline void out_segment(struct out_data *data,
486
+ const struct operand *opx)
487
+ {
488
+ data->type = OUT_SEGMENT;
489
+ data->sign = OUT_UNSIGNED;
490
+ data->size = 2;
491
+ data->toffset = opx->offset; /* Is this really needed/wanted? */
492
+ data->tsegment = ofmt->segbase(opx->segment + 1);
493
+ data->twrt = opx->wrt;
494
+ out(data);
495
+ }
496
+
497
+ static bool jmp_match(int32_t segment, int64_t offset, int bits,
498
+ insn * ins, const struct itemplate *temp)
499
+ {
500
+ int64_t isize;
501
+ const uint8_t *code = temp->code;
502
+ uint8_t c = code[0];
503
+ bool is_byte;
504
+
505
+ if (((c & ~1) != 0370) || (ins->oprs[0].type & STRICT))
506
+ return false;
507
+ if (!optimizing)
508
+ return false;
509
+ if (optimizing < 0 && c == 0371)
510
+ return false;
511
+
512
+ isize = calcsize(segment, offset, bits, ins, temp);
513
+
514
+ if (ins->oprs[0].opflags & OPFLAG_UNKNOWN)
515
+ /* Be optimistic in pass 1 */
516
+ return true;
517
+
518
+ if (ins->oprs[0].segment != segment)
519
+ return false;
520
+
521
+ isize = ins->oprs[0].offset - offset - isize; /* isize is delta */
522
+ is_byte = (isize >= -128 && isize <= 127); /* is it byte size? */
523
+
524
+ if (is_byte && c == 0371 && ins->prefixes[PPS_REP] == P_BND) {
525
+ /* jmp short (opcode eb) cannot be used with bnd prefix. */
526
+ ins->prefixes[PPS_REP] = P_none;
527
+ nasm_error(ERR_WARNING | ERR_WARN_BND | ERR_PASS2 ,
528
+ "jmp short does not init bnd regs - bnd prefix dropped.");
529
+ }
530
+
531
+ return is_byte;
532
+ }
533
+
534
+ /* This is totally just a wild guess what is reasonable... */
535
+ #define INCBIN_MAX_BUF (ZERO_BUF_SIZE * 16)
536
+
537
+ int64_t assemble(int32_t segment, int64_t start, int bits, insn *instruction)
538
+ {
539
+ struct out_data data;
540
+ const struct itemplate *temp;
541
+ enum match_result m;
542
+ int64_t wsize; /* size for DB etc. */
543
+
544
+ nasm_zero(data);
545
+ data.offset = start;
546
+ data.segment = segment;
547
+ data.itemp = NULL;
548
+ data.sign = OUT_WRAP;
549
+ data.bits = bits;
550
+
551
+ wsize = idata_bytes(instruction->opcode);
552
+ if (wsize == -1)
553
+ return 0;
554
+
555
+ if (wsize) {
556
+ extop *e;
557
+
558
+ list_for_each(e, instruction->eops) {
559
+ if (e->type == EOT_DB_NUMBER) {
560
+ if (wsize > 8) {
561
+ nasm_error(ERR_NONFATAL,
562
+ "integer supplied to a DT, DO, DY or DZ"
563
+ " instruction");
564
+ } else {
565
+ data.insoffs = 0;
566
+ data.type = e->relative ? OUT_RELADDR : OUT_ADDRESS;
567
+ data.inslen = data.size = wsize;
568
+ data.toffset = e->offset;
569
+ data.tsegment = e->segment;
570
+ data.twrt = e->wrt;
571
+ data.relbase = 0;
572
+ out(&data);
573
+ }
574
+ } else if (e->type == EOT_DB_STRING ||
575
+ e->type == EOT_DB_STRING_FREE) {
576
+ int align = e->stringlen % wsize;
577
+ if (align)
578
+ align = wsize - align;
579
+
580
+ data.insoffs = 0;
581
+ data.inslen = e->stringlen + align;
582
+
583
+ out_rawdata(&data, e->stringval, e->stringlen);
584
+ out_rawdata(&data, zero_buffer, align);
585
+ }
586
+ }
587
+ } else if (instruction->opcode == I_INCBIN) {
588
+ const char *fname = instruction->eops->stringval;
589
+ FILE *fp;
590
+ size_t t = instruction->times; /* INCBIN handles TIMES by itself */
591
+ off_t base = 0;
592
+ off_t len;
593
+ const void *map = NULL;
594
+ char *buf = NULL;
595
+ size_t blk = 0; /* Buffered I/O block size */
596
+ size_t m = 0; /* Bytes last read */
597
+
598
+ if (!t)
599
+ goto done;
600
+
601
+ fp = nasm_open_read(fname, NF_BINARY|NF_FORMAP);
602
+ if (!fp) {
603
+ nasm_error(ERR_NONFATAL, "`incbin': unable to open file `%s'",
604
+ fname);
605
+ goto done;
606
+ }
607
+
608
+ len = nasm_file_size(fp);
609
+
610
+ if (len == (off_t)-1) {
611
+ nasm_error(ERR_NONFATAL, "`incbin': unable to get length of file `%s'",
612
+ fname);
613
+ goto close_done;
614
+ }
615
+
616
+ if (instruction->eops->next) {
617
+ base = instruction->eops->next->offset;
618
+ if (base >= len) {
619
+ len = 0;
620
+ } else {
621
+ len -= base;
622
+ if (instruction->eops->next->next &&
623
+ len > (off_t)instruction->eops->next->next->offset)
624
+ len = (off_t)instruction->eops->next->next->offset;
625
+ }
626
+ }
627
+
628
+ lfmt->set_offset(data.offset);
629
+ lfmt->uplevel(LIST_INCBIN);
630
+
631
+ if (!len)
632
+ goto end_incbin;
633
+
634
+ /* Try to map file data */
635
+ map = nasm_map_file(fp, base, len);
636
+ if (!map) {
637
+ blk = len < (off_t)INCBIN_MAX_BUF ? (size_t)len : INCBIN_MAX_BUF;
638
+ buf = nasm_malloc(blk);
639
+ }
640
+
641
+ while (t--) {
642
+ /*
643
+ * Consider these irrelevant for INCBIN, since it is fully
644
+ * possible that these might be (way) bigger than an int
645
+ * can hold; there is, however, no reason to widen these
646
+ * types just for INCBIN. data.inslen == 0 signals to the
647
+ * backend that these fields are meaningless, if at all
648
+ * needed.
649
+ */
650
+ data.insoffs = 0;
651
+ data.inslen = 0;
652
+
653
+ if (map) {
654
+ out_rawdata(&data, map, len);
655
+ } else if ((off_t)m == len) {
656
+ out_rawdata(&data, buf, len);
657
+ } else {
658
+ off_t l = len;
659
+
660
+ if (fseeko(fp, base, SEEK_SET) < 0 || ferror(fp)) {
661
+ nasm_error(ERR_NONFATAL,
662
+ "`incbin': unable to seek on file `%s'",
663
+ fname);
664
+ goto end_incbin;
665
+ }
666
+ while (l > 0) {
667
+ m = fread(buf, 1, l < (off_t)blk ? (size_t)l : blk, fp);
668
+ if (!m || feof(fp)) {
669
+ /*
670
+ * This shouldn't happen unless the file
671
+ * actually changes while we are reading
672
+ * it.
673
+ */
674
+ nasm_error(ERR_NONFATAL,
675
+ "`incbin': unexpected EOF while"
676
+ " reading file `%s'", fname);
677
+ goto end_incbin;
678
+ }
679
+ out_rawdata(&data, buf, m);
680
+ l -= m;
681
+ }
682
+ }
683
+ }
684
+ end_incbin:
685
+ lfmt->downlevel(LIST_INCBIN);
686
+ if (instruction->times > 1) {
687
+ lfmt->set_offset(start);
688
+ lfmt->uplevel(LIST_TIMES);
689
+ lfmt->downlevel(LIST_TIMES);
690
+ }
691
+ if (ferror(fp)) {
692
+ nasm_error(ERR_NONFATAL,
693
+ "`incbin': error while"
694
+ " reading file `%s'", fname);
695
+ }
696
+ close_done:
697
+ if (buf)
698
+ nasm_free(buf);
699
+ if (map)
700
+ nasm_unmap_file(map, len);
701
+ fclose(fp);
702
+ done:
703
+ instruction->times = 1; /* Tell the upper layer not to iterate */
704
+ ;
705
+ } else {
706
+ /* "Real" instruction */
707
+
708
+ /* Check to see if we need an address-size prefix */
709
+ add_asp(instruction, bits);
710
+
711
+ m = find_match(&temp, instruction, data.segment, data.offset, bits);
712
+
713
+ if (m == MOK_GOOD) {
714
+ /* Matches! */
715
+ int64_t insn_size = calcsize(data.segment, data.offset,
716
+ bits, instruction, temp);
717
+ nasm_assert(insn_size >= 0);
718
+
719
+ data.itemp = temp;
720
+ data.bits = bits;
721
+ data.insoffs = 0;
722
+ data.inslen = insn_size;
723
+
724
+ gencode(&data, instruction);
725
+ nasm_assert(data.insoffs == insn_size);
726
+ } else {
727
+ /* No match */
728
+ switch (m) {
729
+ case MERR_OPSIZEMISSING:
730
+ nasm_error(ERR_NONFATAL, "operation size not specified");
731
+ break;
732
+ case MERR_OPSIZEMISMATCH:
733
+ nasm_error(ERR_NONFATAL, "mismatch in operand sizes");
734
+ break;
735
+ case MERR_BRNOTHERE:
736
+ nasm_error(ERR_NONFATAL,
737
+ "broadcast not permitted on this operand");
738
+ break;
739
+ case MERR_BRNUMMISMATCH:
740
+ nasm_error(ERR_NONFATAL,
741
+ "mismatch in the number of broadcasting elements");
742
+ break;
743
+ case MERR_MASKNOTHERE:
744
+ nasm_error(ERR_NONFATAL,
745
+ "mask not permitted on this operand");
746
+ break;
747
+ case MERR_DECONOTHERE:
748
+ nasm_error(ERR_NONFATAL, "unsupported mode decorator for instruction");
749
+ break;
750
+ case MERR_BADCPU:
751
+ nasm_error(ERR_NONFATAL, "no instruction for this cpu level");
752
+ break;
753
+ case MERR_BADMODE:
754
+ nasm_error(ERR_NONFATAL, "instruction not supported in %d-bit mode",
755
+ bits);
756
+ break;
757
+ case MERR_ENCMISMATCH:
758
+ nasm_error(ERR_NONFATAL, "specific encoding scheme not available");
759
+ break;
760
+ case MERR_BADBND:
761
+ nasm_error(ERR_NONFATAL, "bnd prefix is not allowed");
762
+ break;
763
+ case MERR_BADREPNE:
764
+ nasm_error(ERR_NONFATAL, "%s prefix is not allowed",
765
+ (has_prefix(instruction, PPS_REP, P_REPNE) ?
766
+ "repne" : "repnz"));
767
+ break;
768
+ default:
769
+ nasm_error(ERR_NONFATAL,
770
+ "invalid combination of opcode and operands");
771
+ break;
772
+ }
773
+
774
+ instruction->times = 1; /* Avoid repeated error messages */
775
+ }
776
+ }
777
+ return data.offset - start;
778
+ }
779
+
780
+ int64_t insn_size(int32_t segment, int64_t offset, int bits, insn *instruction)
781
+ {
782
+ const struct itemplate *temp;
783
+ enum match_result m;
784
+
785
+ if (instruction->opcode == I_none)
786
+ return 0;
787
+
788
+ if (opcode_is_db(instruction->opcode)) {
789
+ extop *e;
790
+ int32_t isize, osize, wsize;
791
+
792
+ isize = 0;
793
+ wsize = idata_bytes(instruction->opcode);
794
+ nasm_assert(wsize > 0);
795
+
796
+ list_for_each(e, instruction->eops) {
797
+ int32_t align;
798
+
799
+ osize = 0;
800
+ if (e->type == EOT_DB_NUMBER) {
801
+ osize = 1;
802
+ warn_overflow_const(e->offset, wsize);
803
+ } else if (e->type == EOT_DB_STRING ||
804
+ e->type == EOT_DB_STRING_FREE)
805
+ osize = e->stringlen;
806
+
807
+ align = (-osize) % wsize;
808
+ if (align < 0)
809
+ align += wsize;
810
+ isize += osize + align;
811
+ }
812
+ return isize;
813
+ }
814
+
815
+ if (instruction->opcode == I_INCBIN) {
816
+ const char *fname = instruction->eops->stringval;
817
+ off_t len;
818
+
819
+ len = nasm_file_size_by_path(fname);
820
+ if (len == (off_t)-1) {
821
+ nasm_error(ERR_NONFATAL, "`incbin': unable to get length of file `%s'",
822
+ fname);
823
+ return 0;
824
+ }
825
+
826
+ if (instruction->eops->next) {
827
+ if (len <= (off_t)instruction->eops->next->offset) {
828
+ len = 0;
829
+ } else {
830
+ len -= instruction->eops->next->offset;
831
+ if (instruction->eops->next->next &&
832
+ len > (off_t)instruction->eops->next->next->offset) {
833
+ len = (off_t)instruction->eops->next->next->offset;
834
+ }
835
+ }
836
+ }
837
+
838
+ len *= instruction->times;
839
+ instruction->times = 1; /* Tell the upper layer to not iterate */
840
+
841
+ return len;
842
+ }
843
+
844
+ /* Check to see if we need an address-size prefix */
845
+ add_asp(instruction, bits);
846
+
847
+ m = find_match(&temp, instruction, segment, offset, bits);
848
+ if (m == MOK_GOOD) {
849
+ /* we've matched an instruction. */
850
+ return calcsize(segment, offset, bits, instruction, temp);
851
+ } else {
852
+ return -1; /* didn't match any instruction */
853
+ }
854
+ }
855
+
856
+ static void bad_hle_warn(const insn * ins, uint8_t hleok)
857
+ {
858
+ enum prefixes rep_pfx = ins->prefixes[PPS_REP];
859
+ enum whatwarn { w_none, w_lock, w_inval } ww;
860
+ static const enum whatwarn warn[2][4] =
861
+ {
862
+ { w_inval, w_inval, w_none, w_lock }, /* XACQUIRE */
863
+ { w_inval, w_none, w_none, w_lock }, /* XRELEASE */
864
+ };
865
+ unsigned int n;
866
+
867
+ n = (unsigned int)rep_pfx - P_XACQUIRE;
868
+ if (n > 1)
869
+ return; /* Not XACQUIRE/XRELEASE */
870
+
871
+ ww = warn[n][hleok];
872
+ if (!is_class(MEMORY, ins->oprs[0].type))
873
+ ww = w_inval; /* HLE requires operand 0 to be memory */
874
+
875
+ switch (ww) {
876
+ case w_none:
877
+ break;
878
+
879
+ case w_lock:
880
+ if (ins->prefixes[PPS_LOCK] != P_LOCK) {
881
+ nasm_error(ERR_WARNING | ERR_WARN_HLE | ERR_PASS2,
882
+ "%s with this instruction requires lock",
883
+ prefix_name(rep_pfx));
884
+ }
885
+ break;
886
+
887
+ case w_inval:
888
+ nasm_error(ERR_WARNING | ERR_WARN_HLE | ERR_PASS2,
889
+ "%s invalid with this instruction",
890
+ prefix_name(rep_pfx));
891
+ break;
892
+ }
893
+ }
894
+
895
+ /* Common construct */
896
+ #define case3(x) case (x): case (x)+1: case (x)+2
897
+ #define case4(x) case3(x): case (x)+3
898
+
899
+ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
900
+ insn * ins, const struct itemplate *temp)
901
+ {
902
+ const uint8_t *codes = temp->code;
903
+ int64_t length = 0;
904
+ uint8_t c;
905
+ int rex_mask = ~0;
906
+ int op1, op2;
907
+ struct operand *opx;
908
+ uint8_t opex = 0;
909
+ enum ea_type eat;
910
+ uint8_t hleok = 0;
911
+ bool lockcheck = true;
912
+ enum reg_enum mib_index = R_none; /* For a separate index MIB reg form */
913
+ const char *errmsg;
914
+
915
+ ins->rex = 0; /* Ensure REX is reset */
916
+ eat = EA_SCALAR; /* Expect a scalar EA */
917
+ memset(ins->evex_p, 0, 3); /* Ensure EVEX is reset */
918
+
919
+ if (ins->prefixes[PPS_OSIZE] == P_O64)
920
+ ins->rex |= REX_W;
921
+
922
+ (void)segment; /* Don't warn that this parameter is unused */
923
+ (void)offset; /* Don't warn that this parameter is unused */
924
+
925
+ while (*codes) {
926
+ c = *codes++;
927
+ op1 = (c & 3) + ((opex & 1) << 2);
928
+ op2 = ((c >> 3) & 3) + ((opex & 2) << 1);
929
+ opx = &ins->oprs[op1];
930
+ opex = 0; /* For the next iteration */
931
+
932
+ switch (c) {
933
+ case4(01):
934
+ codes += c, length += c;
935
+ break;
936
+
937
+ case3(05):
938
+ opex = c;
939
+ break;
940
+
941
+ case4(010):
942
+ ins->rex |=
943
+ op_rexflags(opx, REX_B|REX_H|REX_P|REX_W);
944
+ codes++, length++;
945
+ break;
946
+
947
+ case4(014):
948
+ /* this is an index reg of MIB operand */
949
+ mib_index = opx->basereg;
950
+ break;
951
+
952
+ case4(020):
953
+ case4(024):
954
+ length++;
955
+ break;
956
+
957
+ case4(030):
958
+ length += 2;
959
+ break;
960
+
961
+ case4(034):
962
+ if (opx->type & (BITS16 | BITS32 | BITS64))
963
+ length += (opx->type & BITS16) ? 2 : 4;
964
+ else
965
+ length += (bits == 16) ? 2 : 4;
966
+ break;
967
+
968
+ case4(040):
969
+ length += 4;
970
+ break;
971
+
972
+ case4(044):
973
+ length += ins->addr_size >> 3;
974
+ break;
975
+
976
+ case4(050):
977
+ length++;
978
+ break;
979
+
980
+ case4(054):
981
+ length += 8; /* MOV reg64/imm */
982
+ break;
983
+
984
+ case4(060):
985
+ length += 2;
986
+ break;
987
+
988
+ case4(064):
989
+ if (opx->type & (BITS16 | BITS32 | BITS64))
990
+ length += (opx->type & BITS16) ? 2 : 4;
991
+ else
992
+ length += (bits == 16) ? 2 : 4;
993
+ break;
994
+
995
+ case4(070):
996
+ length += 4;
997
+ break;
998
+
999
+ case4(074):
1000
+ length += 2;
1001
+ break;
1002
+
1003
+ case 0172:
1004
+ case 0173:
1005
+ codes++;
1006
+ length++;
1007
+ break;
1008
+
1009
+ case4(0174):
1010
+ length++;
1011
+ break;
1012
+
1013
+ case4(0240):
1014
+ ins->rex |= REX_EV;
1015
+ ins->vexreg = regval(opx);
1016
+ ins->evex_p[2] |= op_evexflags(opx, EVEX_P2VP, 2); /* High-16 NDS */
1017
+ ins->vex_cm = *codes++;
1018
+ ins->vex_wlp = *codes++;
1019
+ ins->evex_tuple = (*codes++ - 0300);
1020
+ break;
1021
+
1022
+ case 0250:
1023
+ ins->rex |= REX_EV;
1024
+ ins->vexreg = 0;
1025
+ ins->vex_cm = *codes++;
1026
+ ins->vex_wlp = *codes++;
1027
+ ins->evex_tuple = (*codes++ - 0300);
1028
+ break;
1029
+
1030
+ case4(0254):
1031
+ length += 4;
1032
+ break;
1033
+
1034
+ case4(0260):
1035
+ ins->rex |= REX_V;
1036
+ ins->vexreg = regval(opx);
1037
+ ins->vex_cm = *codes++;
1038
+ ins->vex_wlp = *codes++;
1039
+ break;
1040
+
1041
+ case 0270:
1042
+ ins->rex |= REX_V;
1043
+ ins->vexreg = 0;
1044
+ ins->vex_cm = *codes++;
1045
+ ins->vex_wlp = *codes++;
1046
+ break;
1047
+
1048
+ case3(0271):
1049
+ hleok = c & 3;
1050
+ break;
1051
+
1052
+ case4(0274):
1053
+ length++;
1054
+ break;
1055
+
1056
+ case4(0300):
1057
+ break;
1058
+
1059
+ case 0310:
1060
+ if (bits == 64)
1061
+ return -1;
1062
+ length += (bits != 16) && !has_prefix(ins, PPS_ASIZE, P_A16);
1063
+ break;
1064
+
1065
+ case 0311:
1066
+ length += (bits != 32) && !has_prefix(ins, PPS_ASIZE, P_A32);
1067
+ break;
1068
+
1069
+ case 0312:
1070
+ break;
1071
+
1072
+ case 0313:
1073
+ if (bits != 64 || has_prefix(ins, PPS_ASIZE, P_A16) ||
1074
+ has_prefix(ins, PPS_ASIZE, P_A32))
1075
+ return -1;
1076
+ break;
1077
+
1078
+ case4(0314):
1079
+ break;
1080
+
1081
+ case 0320:
1082
+ {
1083
+ enum prefixes pfx = ins->prefixes[PPS_OSIZE];
1084
+ if (pfx == P_O16)
1085
+ break;
1086
+ if (pfx != P_none)
1087
+ nasm_error(ERR_WARNING | ERR_PASS2, "invalid operand size prefix");
1088
+ else
1089
+ ins->prefixes[PPS_OSIZE] = P_O16;
1090
+ break;
1091
+ }
1092
+
1093
+ case 0321:
1094
+ {
1095
+ enum prefixes pfx = ins->prefixes[PPS_OSIZE];
1096
+ if (pfx == P_O32)
1097
+ break;
1098
+ if (pfx != P_none)
1099
+ nasm_error(ERR_WARNING | ERR_PASS2, "invalid operand size prefix");
1100
+ else
1101
+ ins->prefixes[PPS_OSIZE] = P_O32;
1102
+ break;
1103
+ }
1104
+
1105
+ case 0322:
1106
+ break;
1107
+
1108
+ case 0323:
1109
+ rex_mask &= ~REX_W;
1110
+ break;
1111
+
1112
+ case 0324:
1113
+ ins->rex |= REX_W;
1114
+ break;
1115
+
1116
+ case 0325:
1117
+ ins->rex |= REX_NH;
1118
+ break;
1119
+
1120
+ case 0326:
1121
+ break;
1122
+
1123
+ case 0330:
1124
+ codes++, length++;
1125
+ break;
1126
+
1127
+ case 0331:
1128
+ break;
1129
+
1130
+ case 0332:
1131
+ case 0333:
1132
+ length++;
1133
+ break;
1134
+
1135
+ case 0334:
1136
+ ins->rex |= REX_L;
1137
+ break;
1138
+
1139
+ case 0335:
1140
+ break;
1141
+
1142
+ case 0336:
1143
+ if (!ins->prefixes[PPS_REP])
1144
+ ins->prefixes[PPS_REP] = P_REP;
1145
+ break;
1146
+
1147
+ case 0337:
1148
+ if (!ins->prefixes[PPS_REP])
1149
+ ins->prefixes[PPS_REP] = P_REPNE;
1150
+ break;
1151
+
1152
+ case 0340:
1153
+ if (!absolute_op(&ins->oprs[0]))
1154
+ nasm_error(ERR_NONFATAL, "attempt to reserve non-constant"
1155
+ " quantity of BSS space");
1156
+ else if (ins->oprs[0].opflags & OPFLAG_FORWARD)
1157
+ nasm_error(ERR_WARNING | ERR_PASS1,
1158
+ "forward reference in RESx can have unpredictable results");
1159
+ else
1160
+ length += ins->oprs[0].offset;
1161
+ break;
1162
+
1163
+ case 0341:
1164
+ if (!ins->prefixes[PPS_WAIT])
1165
+ ins->prefixes[PPS_WAIT] = P_WAIT;
1166
+ break;
1167
+
1168
+ case 0360:
1169
+ break;
1170
+
1171
+ case 0361:
1172
+ length++;
1173
+ break;
1174
+
1175
+ case 0364:
1176
+ case 0365:
1177
+ break;
1178
+
1179
+ case 0366:
1180
+ case 0367:
1181
+ length++;
1182
+ break;
1183
+
1184
+ case 0370:
1185
+ case 0371:
1186
+ break;
1187
+
1188
+ case 0373:
1189
+ length++;
1190
+ break;
1191
+
1192
+ case 0374:
1193
+ eat = EA_XMMVSIB;
1194
+ break;
1195
+
1196
+ case 0375:
1197
+ eat = EA_YMMVSIB;
1198
+ break;
1199
+
1200
+ case 0376:
1201
+ eat = EA_ZMMVSIB;
1202
+ break;
1203
+
1204
+ case4(0100):
1205
+ case4(0110):
1206
+ case4(0120):
1207
+ case4(0130):
1208
+ case4(0200):
1209
+ case4(0204):
1210
+ case4(0210):
1211
+ case4(0214):
1212
+ case4(0220):
1213
+ case4(0224):
1214
+ case4(0230):
1215
+ case4(0234):
1216
+ {
1217
+ ea ea_data;
1218
+ int rfield;
1219
+ opflags_t rflags;
1220
+ struct operand *opy = &ins->oprs[op2];
1221
+ struct operand *op_er_sae;
1222
+
1223
+ ea_data.rex = 0; /* Ensure ea.REX is initially 0 */
1224
+
1225
+ if (c <= 0177) {
1226
+ /* pick rfield from operand b (opx) */
1227
+ rflags = regflag(opx);
1228
+ rfield = nasm_regvals[opx->basereg];
1229
+ } else {
1230
+ rflags = 0;
1231
+ rfield = c & 7;
1232
+ }
1233
+
1234
+ /* EVEX.b1 : evex_brerop contains the operand position */
1235
+ op_er_sae = (ins->evex_brerop >= 0 ?
1236
+ &ins->oprs[ins->evex_brerop] : NULL);
1237
+
1238
+ if (op_er_sae && (op_er_sae->decoflags & (ER | SAE))) {
1239
+ /* set EVEX.b */
1240
+ ins->evex_p[2] |= EVEX_P2B;
1241
+ if (op_er_sae->decoflags & ER) {
1242
+ /* set EVEX.RC (rounding control) */
1243
+ ins->evex_p[2] |= ((ins->evex_rm - BRC_RN) << 5)
1244
+ & EVEX_P2RC;
1245
+ }
1246
+ } else {
1247
+ /* set EVEX.L'L (vector length) */
1248
+ ins->evex_p[2] |= ((ins->vex_wlp << (5 - 2)) & EVEX_P2LL);
1249
+ ins->evex_p[1] |= ((ins->vex_wlp << (7 - 4)) & EVEX_P1W);
1250
+ if (opy->decoflags & BRDCAST_MASK) {
1251
+ /* set EVEX.b */
1252
+ ins->evex_p[2] |= EVEX_P2B;
1253
+ }
1254
+ }
1255
+
1256
+ if (itemp_has(temp, IF_MIB)) {
1257
+ opy->eaflags |= EAF_MIB;
1258
+ /*
1259
+ * if a separate form of MIB (ICC style) is used,
1260
+ * the index reg info is merged into mem operand
1261
+ */
1262
+ if (mib_index != R_none) {
1263
+ opy->indexreg = mib_index;
1264
+ opy->scale = 1;
1265
+ opy->hintbase = mib_index;
1266
+ opy->hinttype = EAH_NOTBASE;
1267
+ }
1268
+ }
1269
+
1270
+ if (process_ea(opy, &ea_data, bits,
1271
+ rfield, rflags, ins, &errmsg) != eat) {
1272
+ nasm_error(ERR_NONFATAL, "%s", errmsg);
1273
+ return -1;
1274
+ } else {
1275
+ ins->rex |= ea_data.rex;
1276
+ length += ea_data.size;
1277
+ }
1278
+ }
1279
+ break;
1280
+
1281
+ default:
1282
+ nasm_panic(0, "internal instruction table corrupt"
1283
+ ": instruction code \\%o (0x%02X) given", c, c);
1284
+ break;
1285
+ }
1286
+ }
1287
+
1288
+ ins->rex &= rex_mask;
1289
+
1290
+ if (ins->rex & REX_NH) {
1291
+ if (ins->rex & REX_H) {
1292
+ nasm_error(ERR_NONFATAL, "instruction cannot use high registers");
1293
+ return -1;
1294
+ }
1295
+ ins->rex &= ~REX_P; /* Don't force REX prefix due to high reg */
1296
+ }
1297
+
1298
+ switch (ins->prefixes[PPS_VEX]) {
1299
+ case P_EVEX:
1300
+ if (!(ins->rex & REX_EV))
1301
+ return -1;
1302
+ break;
1303
+ case P_VEX3:
1304
+ case P_VEX2:
1305
+ if (!(ins->rex & REX_V))
1306
+ return -1;
1307
+ break;
1308
+ default:
1309
+ break;
1310
+ }
1311
+
1312
+ if (ins->rex & (REX_V | REX_EV)) {
1313
+ int bad32 = REX_R|REX_W|REX_X|REX_B;
1314
+
1315
+ if (ins->rex & REX_H) {
1316
+ nasm_error(ERR_NONFATAL, "cannot use high register in AVX instruction");
1317
+ return -1;
1318
+ }
1319
+ switch (ins->vex_wlp & 060) {
1320
+ case 000:
1321
+ case 040:
1322
+ ins->rex &= ~REX_W;
1323
+ break;
1324
+ case 020:
1325
+ ins->rex |= REX_W;
1326
+ bad32 &= ~REX_W;
1327
+ break;
1328
+ case 060:
1329
+ /* Follow REX_W */
1330
+ break;
1331
+ }
1332
+
1333
+ if (bits != 64 && ((ins->rex & bad32) || ins->vexreg > 7)) {
1334
+ nasm_error(ERR_NONFATAL, "invalid operands in non-64-bit mode");
1335
+ return -1;
1336
+ } else if (!(ins->rex & REX_EV) &&
1337
+ ((ins->vexreg > 15) || (ins->evex_p[0] & 0xf0))) {
1338
+ nasm_error(ERR_NONFATAL, "invalid high-16 register in non-AVX-512");
1339
+ return -1;
1340
+ }
1341
+ if (ins->rex & REX_EV)
1342
+ length += 4;
1343
+ else if (ins->vex_cm != 1 || (ins->rex & (REX_W|REX_X|REX_B)) ||
1344
+ ins->prefixes[PPS_VEX] == P_VEX3)
1345
+ length += 3;
1346
+ else
1347
+ length += 2;
1348
+ } else if (ins->rex & REX_MASK) {
1349
+ if (ins->rex & REX_H) {
1350
+ nasm_error(ERR_NONFATAL, "cannot use high register in rex instruction");
1351
+ return -1;
1352
+ } else if (bits == 64) {
1353
+ length++;
1354
+ } else if ((ins->rex & REX_L) &&
1355
+ !(ins->rex & (REX_P|REX_W|REX_X|REX_B)) &&
1356
+ iflag_cpu_level_ok(&cpu, IF_X86_64)) {
1357
+ /* LOCK-as-REX.R */
1358
+ assert_no_prefix(ins, PPS_LOCK);
1359
+ lockcheck = false; /* Already errored, no need for warning */
1360
+ length++;
1361
+ } else {
1362
+ nasm_error(ERR_NONFATAL, "invalid operands in non-64-bit mode");
1363
+ return -1;
1364
+ }
1365
+ }
1366
+
1367
+ if (has_prefix(ins, PPS_LOCK, P_LOCK) && lockcheck &&
1368
+ (!itemp_has(temp,IF_LOCK) || !is_class(MEMORY, ins->oprs[0].type))) {
1369
+ nasm_error(ERR_WARNING | ERR_WARN_LOCK | ERR_PASS2 ,
1370
+ "instruction is not lockable");
1371
+ }
1372
+
1373
+ bad_hle_warn(ins, hleok);
1374
+
1375
+ /*
1376
+ * when BND prefix is set by DEFAULT directive,
1377
+ * BND prefix is added to every appropriate instruction line
1378
+ * unless it is overridden by NOBND prefix.
1379
+ */
1380
+ if (globalbnd &&
1381
+ (itemp_has(temp, IF_BND) && !has_prefix(ins, PPS_REP, P_NOBND)))
1382
+ ins->prefixes[PPS_REP] = P_BND;
1383
+
1384
+ /*
1385
+ * Add length of legacy prefixes
1386
+ */
1387
+ length += emit_prefix(NULL, bits, ins);
1388
+
1389
+ return length;
1390
+ }
1391
+
1392
+ static inline void emit_rex(struct out_data *data, insn *ins)
1393
+ {
1394
+ if (data->bits == 64) {
1395
+ if ((ins->rex & REX_MASK) &&
1396
+ !(ins->rex & (REX_V | REX_EV)) &&
1397
+ !ins->rex_done) {
1398
+ uint8_t rex = (ins->rex & REX_MASK) | REX_P;
1399
+ out_rawbyte(data, rex);
1400
+ ins->rex_done = true;
1401
+ }
1402
+ }
1403
+ }
1404
+
1405
+ static int emit_prefix(struct out_data *data, const int bits, insn *ins)
1406
+ {
1407
+ int bytes = 0;
1408
+ int j;
1409
+
1410
+ for (j = 0; j < MAXPREFIX; j++) {
1411
+ uint8_t c = 0;
1412
+ switch (ins->prefixes[j]) {
1413
+ case P_WAIT:
1414
+ c = 0x9B;
1415
+ break;
1416
+ case P_LOCK:
1417
+ c = 0xF0;
1418
+ break;
1419
+ case P_REPNE:
1420
+ case P_REPNZ:
1421
+ case P_XACQUIRE:
1422
+ case P_BND:
1423
+ c = 0xF2;
1424
+ break;
1425
+ case P_REPE:
1426
+ case P_REPZ:
1427
+ case P_REP:
1428
+ case P_XRELEASE:
1429
+ c = 0xF3;
1430
+ break;
1431
+ case R_CS:
1432
+ if (bits == 64) {
1433
+ nasm_error(ERR_WARNING | ERR_PASS2,
1434
+ "cs segment base generated, but will be ignored in 64-bit mode");
1435
+ }
1436
+ c = 0x2E;
1437
+ break;
1438
+ case R_DS:
1439
+ if (bits == 64) {
1440
+ nasm_error(ERR_WARNING | ERR_PASS2,
1441
+ "ds segment base generated, but will be ignored in 64-bit mode");
1442
+ }
1443
+ c = 0x3E;
1444
+ break;
1445
+ case R_ES:
1446
+ if (bits == 64) {
1447
+ nasm_error(ERR_WARNING | ERR_PASS2,
1448
+ "es segment base generated, but will be ignored in 64-bit mode");
1449
+ }
1450
+ c = 0x26;
1451
+ break;
1452
+ case R_FS:
1453
+ c = 0x64;
1454
+ break;
1455
+ case R_GS:
1456
+ c = 0x65;
1457
+ break;
1458
+ case R_SS:
1459
+ if (bits == 64) {
1460
+ nasm_error(ERR_WARNING | ERR_PASS2,
1461
+ "ss segment base generated, but will be ignored in 64-bit mode");
1462
+ }
1463
+ c = 0x36;
1464
+ break;
1465
+ case R_SEGR6:
1466
+ case R_SEGR7:
1467
+ nasm_error(ERR_NONFATAL,
1468
+ "segr6 and segr7 cannot be used as prefixes");
1469
+ break;
1470
+ case P_A16:
1471
+ if (bits == 64) {
1472
+ nasm_error(ERR_NONFATAL,
1473
+ "16-bit addressing is not supported "
1474
+ "in 64-bit mode");
1475
+ } else if (bits != 16)
1476
+ c = 0x67;
1477
+ break;
1478
+ case P_A32:
1479
+ if (bits != 32)
1480
+ c = 0x67;
1481
+ break;
1482
+ case P_A64:
1483
+ if (bits != 64) {
1484
+ nasm_error(ERR_NONFATAL,
1485
+ "64-bit addressing is only supported "
1486
+ "in 64-bit mode");
1487
+ }
1488
+ break;
1489
+ case P_ASP:
1490
+ c = 0x67;
1491
+ break;
1492
+ case P_O16:
1493
+ if (bits != 16)
1494
+ c = 0x66;
1495
+ break;
1496
+ case P_O32:
1497
+ if (bits == 16)
1498
+ c = 0x66;
1499
+ break;
1500
+ case P_O64:
1501
+ /* REX.W */
1502
+ break;
1503
+ case P_OSP:
1504
+ c = 0x66;
1505
+ break;
1506
+ case P_EVEX:
1507
+ case P_VEX3:
1508
+ case P_VEX2:
1509
+ case P_NOBND:
1510
+ case P_none:
1511
+ break;
1512
+ default:
1513
+ nasm_panic(0, "invalid instruction prefix");
1514
+ }
1515
+ if (c) {
1516
+ if (data)
1517
+ out_rawbyte(data, c);
1518
+ bytes++;
1519
+ }
1520
+ }
1521
+ return bytes;
1522
+ }
1523
+
1524
+ static void gencode(struct out_data *data, insn *ins)
1525
+ {
1526
+ uint8_t c;
1527
+ uint8_t bytes[4];
1528
+ int64_t size;
1529
+ int op1, op2;
1530
+ struct operand *opx;
1531
+ const uint8_t *codes = data->itemp->code;
1532
+ uint8_t opex = 0;
1533
+ enum ea_type eat = EA_SCALAR;
1534
+ int r;
1535
+ const int bits = data->bits;
1536
+ const char *errmsg;
1537
+
1538
+ ins->rex_done = false;
1539
+
1540
+ emit_prefix(data, bits, ins);
1541
+
1542
+ while (*codes) {
1543
+ c = *codes++;
1544
+ op1 = (c & 3) + ((opex & 1) << 2);
1545
+ op2 = ((c >> 3) & 3) + ((opex & 2) << 1);
1546
+ opx = &ins->oprs[op1];
1547
+ opex = 0; /* For the next iteration */
1548
+
1549
+
1550
+ switch (c) {
1551
+ case 01:
1552
+ case 02:
1553
+ case 03:
1554
+ case 04:
1555
+ emit_rex(data, ins);
1556
+ out_rawdata(data, codes, c);
1557
+ codes += c;
1558
+ break;
1559
+
1560
+ case 05:
1561
+ case 06:
1562
+ case 07:
1563
+ opex = c;
1564
+ break;
1565
+
1566
+ case4(010):
1567
+ emit_rex(data, ins);
1568
+ out_rawbyte(data, *codes++ + (regval(opx) & 7));
1569
+ break;
1570
+
1571
+ case4(014):
1572
+ break;
1573
+
1574
+ case4(020):
1575
+ out_imm(data, opx, 1, OUT_WRAP);
1576
+ break;
1577
+
1578
+ case4(024):
1579
+ out_imm(data, opx, 1, OUT_UNSIGNED);
1580
+ break;
1581
+
1582
+ case4(030):
1583
+ out_imm(data, opx, 2, OUT_WRAP);
1584
+ break;
1585
+
1586
+ case4(034):
1587
+ if (opx->type & (BITS16 | BITS32))
1588
+ size = (opx->type & BITS16) ? 2 : 4;
1589
+ else
1590
+ size = (bits == 16) ? 2 : 4;
1591
+ out_imm(data, opx, size, OUT_WRAP);
1592
+ break;
1593
+
1594
+ case4(040):
1595
+ out_imm(data, opx, 4, OUT_WRAP);
1596
+ break;
1597
+
1598
+ case4(044):
1599
+ size = ins->addr_size >> 3;
1600
+ out_imm(data, opx, size, OUT_WRAP);
1601
+ break;
1602
+
1603
+ case4(050):
1604
+ if (opx->segment == data->segment) {
1605
+ int64_t delta = opx->offset - data->offset
1606
+ - (data->inslen - data->insoffs);
1607
+ if (delta > 127 || delta < -128)
1608
+ nasm_error(ERR_NONFATAL, "short jump is out of range");
1609
+ }
1610
+ out_reladdr(data, opx, 1);
1611
+ break;
1612
+
1613
+ case4(054):
1614
+ out_imm(data, opx, 8, OUT_WRAP);
1615
+ break;
1616
+
1617
+ case4(060):
1618
+ out_reladdr(data, opx, 2);
1619
+ break;
1620
+
1621
+ case4(064):
1622
+ if (opx->type & (BITS16 | BITS32 | BITS64))
1623
+ size = (opx->type & BITS16) ? 2 : 4;
1624
+ else
1625
+ size = (bits == 16) ? 2 : 4;
1626
+
1627
+ out_reladdr(data, opx, size);
1628
+ break;
1629
+
1630
+ case4(070):
1631
+ out_reladdr(data, opx, 4);
1632
+ break;
1633
+
1634
+ case4(074):
1635
+ if (opx->segment == NO_SEG)
1636
+ nasm_error(ERR_NONFATAL, "value referenced by FAR is not"
1637
+ " relocatable");
1638
+ out_segment(data, opx);
1639
+ break;
1640
+
1641
+ case 0172:
1642
+ {
1643
+ int mask = ins->prefixes[PPS_VEX] == P_EVEX ? 7 : 15;
1644
+ const struct operand *opy;
1645
+
1646
+ c = *codes++;
1647
+ opx = &ins->oprs[c >> 3];
1648
+ opy = &ins->oprs[c & 7];
1649
+ if (!absolute_op(opy)) {
1650
+ nasm_error(ERR_NONFATAL,
1651
+ "non-absolute expression not permitted as argument %d",
1652
+ c & 7);
1653
+ } else if (opy->offset & ~mask) {
1654
+ nasm_error(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
1655
+ "is4 argument exceeds bounds");
1656
+ }
1657
+ c = opy->offset & mask;
1658
+ goto emit_is4;
1659
+ }
1660
+
1661
+ case 0173:
1662
+ c = *codes++;
1663
+ opx = &ins->oprs[c >> 4];
1664
+ c &= 15;
1665
+ goto emit_is4;
1666
+
1667
+ case4(0174):
1668
+ c = 0;
1669
+ emit_is4:
1670
+ r = nasm_regvals[opx->basereg];
1671
+ out_rawbyte(data, (r << 4) | ((r & 0x10) >> 1) | c);
1672
+ break;
1673
+
1674
+ case4(0254):
1675
+ if (absolute_op(opx) &&
1676
+ (int32_t)opx->offset != (int64_t)opx->offset) {
1677
+ nasm_error(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
1678
+ "signed dword immediate exceeds bounds");
1679
+ }
1680
+ out_imm(data, opx, 4, OUT_SIGNED);
1681
+ break;
1682
+
1683
+ case4(0240):
1684
+ case 0250:
1685
+ codes += 3;
1686
+ ins->evex_p[2] |= op_evexflags(&ins->oprs[0],
1687
+ EVEX_P2Z | EVEX_P2AAA, 2);
1688
+ ins->evex_p[2] ^= EVEX_P2VP; /* 1's complement */
1689
+ bytes[0] = 0x62;
1690
+ /* EVEX.X can be set by either REX or EVEX for different reasons */
1691
+ bytes[1] = ((((ins->rex & 7) << 5) |
1692
+ (ins->evex_p[0] & (EVEX_P0X | EVEX_P0RP))) ^ 0xf0) |
1693
+ (ins->vex_cm & EVEX_P0MM);
1694
+ bytes[2] = ((ins->rex & REX_W) << (7 - 3)) |
1695
+ ((~ins->vexreg & 15) << 3) |
1696
+ (1 << 2) | (ins->vex_wlp & 3);
1697
+ bytes[3] = ins->evex_p[2];
1698
+ out_rawdata(data, bytes, 4);
1699
+ break;
1700
+
1701
+ case4(0260):
1702
+ case 0270:
1703
+ codes += 2;
1704
+ if (ins->vex_cm != 1 || (ins->rex & (REX_W|REX_X|REX_B)) ||
1705
+ ins->prefixes[PPS_VEX] == P_VEX3) {
1706
+ bytes[0] = (ins->vex_cm >> 6) ? 0x8f : 0xc4;
1707
+ bytes[1] = (ins->vex_cm & 31) | ((~ins->rex & 7) << 5);
1708
+ bytes[2] = ((ins->rex & REX_W) << (7-3)) |
1709
+ ((~ins->vexreg & 15)<< 3) | (ins->vex_wlp & 07);
1710
+ out_rawdata(data, bytes, 3);
1711
+ } else {
1712
+ bytes[0] = 0xc5;
1713
+ bytes[1] = ((~ins->rex & REX_R) << (7-2)) |
1714
+ ((~ins->vexreg & 15) << 3) | (ins->vex_wlp & 07);
1715
+ out_rawdata(data, bytes, 2);
1716
+ }
1717
+ break;
1718
+
1719
+ case 0271:
1720
+ case 0272:
1721
+ case 0273:
1722
+ break;
1723
+
1724
+ case4(0274):
1725
+ {
1726
+ uint64_t uv, um;
1727
+ int s;
1728
+
1729
+ if (absolute_op(opx)) {
1730
+ if (ins->rex & REX_W)
1731
+ s = 64;
1732
+ else if (ins->prefixes[PPS_OSIZE] == P_O16)
1733
+ s = 16;
1734
+ else if (ins->prefixes[PPS_OSIZE] == P_O32)
1735
+ s = 32;
1736
+ else
1737
+ s = bits;
1738
+
1739
+ um = (uint64_t)2 << (s-1);
1740
+ uv = opx->offset;
1741
+
1742
+ if (uv > 127 && uv < (uint64_t)-128 &&
1743
+ (uv < um-128 || uv > um-1)) {
1744
+ /* If this wasn't explicitly byte-sized, warn as though we
1745
+ * had fallen through to the imm16/32/64 case.
1746
+ */
1747
+ nasm_error(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
1748
+ "%s value exceeds bounds",
1749
+ (opx->type & BITS8) ? "signed byte" :
1750
+ s == 16 ? "word" :
1751
+ s == 32 ? "dword" :
1752
+ "signed dword");
1753
+ }
1754
+
1755
+ /* Output as a raw byte to avoid byte overflow check */
1756
+ out_rawbyte(data, (uint8_t)uv);
1757
+ } else {
1758
+ out_imm(data, opx, 1, OUT_WRAP); /* XXX: OUT_SIGNED? */
1759
+ }
1760
+ break;
1761
+ }
1762
+
1763
+ case4(0300):
1764
+ break;
1765
+
1766
+ case 0310:
1767
+ if (bits == 32 && !has_prefix(ins, PPS_ASIZE, P_A16))
1768
+ out_rawbyte(data, 0x67);
1769
+ break;
1770
+
1771
+ case 0311:
1772
+ if (bits != 32 && !has_prefix(ins, PPS_ASIZE, P_A32))
1773
+ out_rawbyte(data, 0x67);
1774
+ break;
1775
+
1776
+ case 0312:
1777
+ break;
1778
+
1779
+ case 0313:
1780
+ ins->rex = 0;
1781
+ break;
1782
+
1783
+ case4(0314):
1784
+ break;
1785
+
1786
+ case 0320:
1787
+ case 0321:
1788
+ break;
1789
+
1790
+ case 0322:
1791
+ case 0323:
1792
+ break;
1793
+
1794
+ case 0324:
1795
+ ins->rex |= REX_W;
1796
+ break;
1797
+
1798
+ case 0325:
1799
+ break;
1800
+
1801
+ case 0326:
1802
+ break;
1803
+
1804
+ case 0330:
1805
+ out_rawbyte(data, *codes++ ^ get_cond_opcode(ins->condition));
1806
+ break;
1807
+
1808
+ case 0331:
1809
+ break;
1810
+
1811
+ case 0332:
1812
+ case 0333:
1813
+ out_rawbyte(data, c - 0332 + 0xF2);
1814
+ break;
1815
+
1816
+ case 0334:
1817
+ if (ins->rex & REX_R)
1818
+ out_rawbyte(data, 0xF0);
1819
+ ins->rex &= ~(REX_L|REX_R);
1820
+ break;
1821
+
1822
+ case 0335:
1823
+ break;
1824
+
1825
+ case 0336:
1826
+ case 0337:
1827
+ break;
1828
+
1829
+ case 0340:
1830
+ if (ins->oprs[0].segment != NO_SEG)
1831
+ nasm_panic(0, "non-constant BSS size in pass two");
1832
+
1833
+ out_reserve(data, ins->oprs[0].offset);
1834
+ break;
1835
+
1836
+ case 0341:
1837
+ break;
1838
+
1839
+ case 0360:
1840
+ break;
1841
+
1842
+ case 0361:
1843
+ out_rawbyte(data, 0x66);
1844
+ break;
1845
+
1846
+ case 0364:
1847
+ case 0365:
1848
+ break;
1849
+
1850
+ case 0366:
1851
+ case 0367:
1852
+ out_rawbyte(data, c - 0366 + 0x66);
1853
+ break;
1854
+
1855
+ case3(0370):
1856
+ break;
1857
+
1858
+ case 0373:
1859
+ out_rawbyte(data, bits == 16 ? 3 : 5);
1860
+ break;
1861
+
1862
+ case 0374:
1863
+ eat = EA_XMMVSIB;
1864
+ break;
1865
+
1866
+ case 0375:
1867
+ eat = EA_YMMVSIB;
1868
+ break;
1869
+
1870
+ case 0376:
1871
+ eat = EA_ZMMVSIB;
1872
+ break;
1873
+
1874
+ case4(0100):
1875
+ case4(0110):
1876
+ case4(0120):
1877
+ case4(0130):
1878
+ case4(0200):
1879
+ case4(0204):
1880
+ case4(0210):
1881
+ case4(0214):
1882
+ case4(0220):
1883
+ case4(0224):
1884
+ case4(0230):
1885
+ case4(0234):
1886
+ {
1887
+ ea ea_data;
1888
+ int rfield;
1889
+ opflags_t rflags;
1890
+ uint8_t *p;
1891
+ struct operand *opy = &ins->oprs[op2];
1892
+
1893
+ if (c <= 0177) {
1894
+ /* pick rfield from operand b (opx) */
1895
+ rflags = regflag(opx);
1896
+ rfield = nasm_regvals[opx->basereg];
1897
+ } else {
1898
+ /* rfield is constant */
1899
+ rflags = 0;
1900
+ rfield = c & 7;
1901
+ }
1902
+
1903
+ if (process_ea(opy, &ea_data, bits,
1904
+ rfield, rflags, ins, &errmsg) != eat)
1905
+ nasm_error(ERR_NONFATAL, "%s", errmsg);
1906
+
1907
+ p = bytes;
1908
+ *p++ = ea_data.modrm;
1909
+ if (ea_data.sib_present)
1910
+ *p++ = ea_data.sib;
1911
+ out_rawdata(data, bytes, p - bytes);
1912
+
1913
+ /*
1914
+ * Make sure the address gets the right offset in case
1915
+ * the line breaks in the .lst file (BR 1197827)
1916
+ */
1917
+
1918
+ if (ea_data.bytes) {
1919
+ /* use compressed displacement, if available */
1920
+ if (ea_data.disp8) {
1921
+ out_rawbyte(data, ea_data.disp8);
1922
+ } else if (ea_data.rip) {
1923
+ out_reladdr(data, opy, ea_data.bytes);
1924
+ } else {
1925
+ int asize = ins->addr_size >> 3;
1926
+
1927
+ if (overflow_general(opy->offset, asize) ||
1928
+ signed_bits(opy->offset, ins->addr_size) !=
1929
+ signed_bits(opy->offset, ea_data.bytes << 3))
1930
+ warn_overflow(ea_data.bytes);
1931
+
1932
+ out_imm(data, opy, ea_data.bytes,
1933
+ (asize > ea_data.bytes)
1934
+ ? OUT_SIGNED : OUT_WRAP);
1935
+ }
1936
+ }
1937
+ }
1938
+ break;
1939
+
1940
+ default:
1941
+ nasm_panic(0, "internal instruction table corrupt"
1942
+ ": instruction code \\%o (0x%02X) given", c, c);
1943
+ break;
1944
+ }
1945
+ }
1946
+ }
1947
+
1948
+ static opflags_t regflag(const operand * o)
1949
+ {
1950
+ if (!is_register(o->basereg))
1951
+ nasm_panic(0, "invalid operand passed to regflag()");
1952
+ return nasm_reg_flags[o->basereg];
1953
+ }
1954
+
1955
+ static int32_t regval(const operand * o)
1956
+ {
1957
+ if (!is_register(o->basereg))
1958
+ nasm_panic(0, "invalid operand passed to regval()");
1959
+ return nasm_regvals[o->basereg];
1960
+ }
1961
+
1962
+ static int op_rexflags(const operand * o, int mask)
1963
+ {
1964
+ opflags_t flags;
1965
+ int val;
1966
+
1967
+ if (!is_register(o->basereg))
1968
+ nasm_panic(0, "invalid operand passed to op_rexflags()");
1969
+
1970
+ flags = nasm_reg_flags[o->basereg];
1971
+ val = nasm_regvals[o->basereg];
1972
+
1973
+ return rexflags(val, flags, mask);
1974
+ }
1975
+
1976
+ static int rexflags(int val, opflags_t flags, int mask)
1977
+ {
1978
+ int rex = 0;
1979
+
1980
+ if (val >= 0 && (val & 8))
1981
+ rex |= REX_B|REX_X|REX_R;
1982
+ if (flags & BITS64)
1983
+ rex |= REX_W;
1984
+ if (!(REG_HIGH & ~flags)) /* AH, CH, DH, BH */
1985
+ rex |= REX_H;
1986
+ else if (!(REG8 & ~flags) && val >= 4) /* SPL, BPL, SIL, DIL */
1987
+ rex |= REX_P;
1988
+
1989
+ return rex & mask;
1990
+ }
1991
+
1992
+ static int evexflags(int val, decoflags_t deco,
1993
+ int mask, uint8_t byte)
1994
+ {
1995
+ int evex = 0;
1996
+
1997
+ switch (byte) {
1998
+ case 0:
1999
+ if (val >= 0 && (val & 16))
2000
+ evex |= (EVEX_P0RP | EVEX_P0X);
2001
+ break;
2002
+ case 2:
2003
+ if (val >= 0 && (val & 16))
2004
+ evex |= EVEX_P2VP;
2005
+ if (deco & Z)
2006
+ evex |= EVEX_P2Z;
2007
+ if (deco & OPMASK_MASK)
2008
+ evex |= deco & EVEX_P2AAA;
2009
+ break;
2010
+ }
2011
+ return evex & mask;
2012
+ }
2013
+
2014
+ static int op_evexflags(const operand * o, int mask, uint8_t byte)
2015
+ {
2016
+ int val;
2017
+
2018
+ val = nasm_regvals[o->basereg];
2019
+
2020
+ return evexflags(val, o->decoflags, mask, byte);
2021
+ }
2022
+
2023
+ static enum match_result find_match(const struct itemplate **tempp,
2024
+ insn *instruction,
2025
+ int32_t segment, int64_t offset, int bits)
2026
+ {
2027
+ const struct itemplate *temp;
2028
+ enum match_result m, merr;
2029
+ opflags_t xsizeflags[MAX_OPERANDS];
2030
+ bool opsizemissing = false;
2031
+ int8_t broadcast = instruction->evex_brerop;
2032
+ int i;
2033
+
2034
+ /* broadcasting uses a different data element size */
2035
+ for (i = 0; i < instruction->operands; i++)
2036
+ if (i == broadcast)
2037
+ xsizeflags[i] = instruction->oprs[i].decoflags & BRSIZE_MASK;
2038
+ else
2039
+ xsizeflags[i] = instruction->oprs[i].type & SIZE_MASK;
2040
+
2041
+ merr = MERR_INVALOP;
2042
+
2043
+ for (temp = nasm_instructions[instruction->opcode];
2044
+ temp->opcode != I_none; temp++) {
2045
+ m = matches(temp, instruction, bits);
2046
+ if (m == MOK_JUMP) {
2047
+ if (jmp_match(segment, offset, bits, instruction, temp))
2048
+ m = MOK_GOOD;
2049
+ else
2050
+ m = MERR_INVALOP;
2051
+ } else if (m == MERR_OPSIZEMISSING && !itemp_has(temp, IF_SX)) {
2052
+ /*
2053
+ * Missing operand size and a candidate for fuzzy matching...
2054
+ */
2055
+ for (i = 0; i < temp->operands; i++)
2056
+ if (i == broadcast)
2057
+ xsizeflags[i] |= temp->deco[i] & BRSIZE_MASK;
2058
+ else
2059
+ xsizeflags[i] |= temp->opd[i] & SIZE_MASK;
2060
+ opsizemissing = true;
2061
+ }
2062
+ if (m > merr)
2063
+ merr = m;
2064
+ if (merr == MOK_GOOD)
2065
+ goto done;
2066
+ }
2067
+
2068
+ /* No match, but see if we can get a fuzzy operand size match... */
2069
+ if (!opsizemissing)
2070
+ goto done;
2071
+
2072
+ for (i = 0; i < instruction->operands; i++) {
2073
+ /*
2074
+ * We ignore extrinsic operand sizes on registers, so we should
2075
+ * never try to fuzzy-match on them. This also resolves the case
2076
+ * when we have e.g. "xmmrm128" in two different positions.
2077
+ */
2078
+ if (is_class(REGISTER, instruction->oprs[i].type))
2079
+ continue;
2080
+
2081
+ /* This tests if xsizeflags[i] has more than one bit set */
2082
+ if ((xsizeflags[i] & (xsizeflags[i]-1)))
2083
+ goto done; /* No luck */
2084
+
2085
+ if (i == broadcast) {
2086
+ instruction->oprs[i].decoflags |= xsizeflags[i];
2087
+ instruction->oprs[i].type |= (xsizeflags[i] == BR_BITS32 ?
2088
+ BITS32 : BITS64);
2089
+ } else {
2090
+ instruction->oprs[i].type |= xsizeflags[i]; /* Set the size */
2091
+ }
2092
+ }
2093
+
2094
+ /* Try matching again... */
2095
+ for (temp = nasm_instructions[instruction->opcode];
2096
+ temp->opcode != I_none; temp++) {
2097
+ m = matches(temp, instruction, bits);
2098
+ if (m == MOK_JUMP) {
2099
+ if (jmp_match(segment, offset, bits, instruction, temp))
2100
+ m = MOK_GOOD;
2101
+ else
2102
+ m = MERR_INVALOP;
2103
+ }
2104
+ if (m > merr)
2105
+ merr = m;
2106
+ if (merr == MOK_GOOD)
2107
+ goto done;
2108
+ }
2109
+
2110
+ done:
2111
+ *tempp = temp;
2112
+ return merr;
2113
+ }
2114
+
2115
+ static uint8_t get_broadcast_num(opflags_t opflags, opflags_t brsize)
2116
+ {
2117
+ unsigned int opsize = (opflags & SIZE_MASK) >> SIZE_SHIFT;
2118
+ uint8_t brcast_num;
2119
+
2120
+ if (brsize > BITS64)
2121
+ nasm_error(ERR_FATAL,
2122
+ "size of broadcasting element is greater than 64 bits");
2123
+
2124
+ /*
2125
+ * The shift term is to take care of the extra BITS80 inserted
2126
+ * between BITS64 and BITS128.
2127
+ */
2128
+ brcast_num = ((opsize / (BITS64 >> SIZE_SHIFT)) * (BITS64 / brsize))
2129
+ >> (opsize > (BITS64 >> SIZE_SHIFT));
2130
+
2131
+ return brcast_num;
2132
+ }
2133
+
2134
+ static enum match_result matches(const struct itemplate *itemp,
2135
+ insn *instruction, int bits)
2136
+ {
2137
+ opflags_t size[MAX_OPERANDS], asize;
2138
+ bool opsizemissing = false;
2139
+ int i, oprs;
2140
+
2141
+ /*
2142
+ * Check the opcode
2143
+ */
2144
+ if (itemp->opcode != instruction->opcode)
2145
+ return MERR_INVALOP;
2146
+
2147
+ /*
2148
+ * Count the operands
2149
+ */
2150
+ if (itemp->operands != instruction->operands)
2151
+ return MERR_INVALOP;
2152
+
2153
+ /*
2154
+ * Is it legal?
2155
+ */
2156
+ if (!(optimizing > 0) && itemp_has(itemp, IF_OPT))
2157
+ return MERR_INVALOP;
2158
+
2159
+ /*
2160
+ * {evex} available?
2161
+ */
2162
+ switch (instruction->prefixes[PPS_VEX]) {
2163
+ case P_EVEX:
2164
+ if (!itemp_has(itemp, IF_EVEX))
2165
+ return MERR_ENCMISMATCH;
2166
+ break;
2167
+ case P_VEX3:
2168
+ case P_VEX2:
2169
+ if (!itemp_has(itemp, IF_VEX))
2170
+ return MERR_ENCMISMATCH;
2171
+ break;
2172
+ default:
2173
+ break;
2174
+ }
2175
+
2176
+ /*
2177
+ * Check that no spurious colons or TOs are present
2178
+ */
2179
+ for (i = 0; i < itemp->operands; i++)
2180
+ if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON | TO))
2181
+ return MERR_INVALOP;
2182
+
2183
+ /*
2184
+ * Process size flags
2185
+ */
2186
+ switch (itemp_smask(itemp)) {
2187
+ case IF_GENBIT(IF_SB):
2188
+ asize = BITS8;
2189
+ break;
2190
+ case IF_GENBIT(IF_SW):
2191
+ asize = BITS16;
2192
+ break;
2193
+ case IF_GENBIT(IF_SD):
2194
+ asize = BITS32;
2195
+ break;
2196
+ case IF_GENBIT(IF_SQ):
2197
+ asize = BITS64;
2198
+ break;
2199
+ case IF_GENBIT(IF_SO):
2200
+ asize = BITS128;
2201
+ break;
2202
+ case IF_GENBIT(IF_SY):
2203
+ asize = BITS256;
2204
+ break;
2205
+ case IF_GENBIT(IF_SZ):
2206
+ asize = BITS512;
2207
+ break;
2208
+ case IF_GENBIT(IF_SIZE):
2209
+ switch (bits) {
2210
+ case 16:
2211
+ asize = BITS16;
2212
+ break;
2213
+ case 32:
2214
+ asize = BITS32;
2215
+ break;
2216
+ case 64:
2217
+ asize = BITS64;
2218
+ break;
2219
+ default:
2220
+ asize = 0;
2221
+ break;
2222
+ }
2223
+ break;
2224
+ default:
2225
+ asize = 0;
2226
+ break;
2227
+ }
2228
+
2229
+ if (itemp_armask(itemp)) {
2230
+ /* S- flags only apply to a specific operand */
2231
+ i = itemp_arg(itemp);
2232
+ memset(size, 0, sizeof size);
2233
+ size[i] = asize;
2234
+ } else {
2235
+ /* S- flags apply to all operands */
2236
+ for (i = 0; i < MAX_OPERANDS; i++)
2237
+ size[i] = asize;
2238
+ }
2239
+
2240
+ /*
2241
+ * Check that the operand flags all match up,
2242
+ * it's a bit tricky so lets be verbose:
2243
+ *
2244
+ * 1) Find out the size of operand. If instruction
2245
+ * doesn't have one specified -- we're trying to
2246
+ * guess it either from template (IF_S* flag) or
2247
+ * from code bits.
2248
+ *
2249
+ * 2) If template operand do not match the instruction OR
2250
+ * template has an operand size specified AND this size differ
2251
+ * from which instruction has (perhaps we got it from code bits)
2252
+ * we are:
2253
+ * a) Check that only size of instruction and operand is differ
2254
+ * other characteristics do match
2255
+ * b) Perhaps it's a register specified in instruction so
2256
+ * for such a case we just mark that operand as "size
2257
+ * missing" and this will turn on fuzzy operand size
2258
+ * logic facility (handled by a caller)
2259
+ */
2260
+ for (i = 0; i < itemp->operands; i++) {
2261
+ opflags_t type = instruction->oprs[i].type;
2262
+ decoflags_t deco = instruction->oprs[i].decoflags;
2263
+ decoflags_t ideco = itemp->deco[i];
2264
+ bool is_broadcast = deco & BRDCAST_MASK;
2265
+ uint8_t brcast_num = 0;
2266
+ opflags_t template_opsize, insn_opsize;
2267
+
2268
+ if (!(type & SIZE_MASK))
2269
+ type |= size[i];
2270
+
2271
+ insn_opsize = type & SIZE_MASK;
2272
+ if (!is_broadcast) {
2273
+ template_opsize = itemp->opd[i] & SIZE_MASK;
2274
+ } else {
2275
+ decoflags_t deco_brsize = ideco & BRSIZE_MASK;
2276
+
2277
+ if (~ideco & BRDCAST_MASK)
2278
+ return MERR_BRNOTHERE;
2279
+
2280
+ /*
2281
+ * when broadcasting, the element size depends on
2282
+ * the instruction type. decorator flag should match.
2283
+ */
2284
+ if (deco_brsize) {
2285
+ template_opsize = (deco_brsize == BR_BITS32 ? BITS32 : BITS64);
2286
+ /* calculate the proper number : {1to<brcast_num>} */
2287
+ brcast_num = get_broadcast_num(itemp->opd[i], template_opsize);
2288
+ } else {
2289
+ template_opsize = 0;
2290
+ }
2291
+ }
2292
+
2293
+ if (~ideco & deco & OPMASK_MASK)
2294
+ return MERR_MASKNOTHERE;
2295
+
2296
+ if (~ideco & deco & (Z_MASK|STATICRND_MASK|SAE_MASK))
2297
+ return MERR_DECONOTHERE;
2298
+
2299
+ if (itemp->opd[i] & ~type & ~SIZE_MASK) {
2300
+ return MERR_INVALOP;
2301
+ } else if (template_opsize) {
2302
+ if (template_opsize != insn_opsize) {
2303
+ if (insn_opsize) {
2304
+ return MERR_INVALOP;
2305
+ } else if (!is_class(REGISTER, type)) {
2306
+ /*
2307
+ * Note: we don't honor extrinsic operand sizes for registers,
2308
+ * so "missing operand size" for a register should be
2309
+ * considered a wildcard match rather than an error.
2310
+ */
2311
+ opsizemissing = true;
2312
+ }
2313
+ } else if (is_broadcast &&
2314
+ (brcast_num !=
2315
+ (2U << ((deco & BRNUM_MASK) >> BRNUM_SHIFT)))) {
2316
+ /*
2317
+ * broadcasting opsize matches but the number of repeated memory
2318
+ * element does not match.
2319
+ * if 64b double precision float is broadcasted to ymm (256b),
2320
+ * broadcasting decorator must be {1to4}.
2321
+ */
2322
+ return MERR_BRNUMMISMATCH;
2323
+ }
2324
+ }
2325
+ }
2326
+
2327
+ if (opsizemissing)
2328
+ return MERR_OPSIZEMISSING;
2329
+
2330
+ /*
2331
+ * Check operand sizes
2332
+ */
2333
+ if (itemp_has(itemp, IF_SM) || itemp_has(itemp, IF_SM2)) {
2334
+ oprs = (itemp_has(itemp, IF_SM2) ? 2 : itemp->operands);
2335
+ for (i = 0; i < oprs; i++) {
2336
+ asize = itemp->opd[i] & SIZE_MASK;
2337
+ if (asize) {
2338
+ for (i = 0; i < oprs; i++)
2339
+ size[i] = asize;
2340
+ break;
2341
+ }
2342
+ }
2343
+ } else {
2344
+ oprs = itemp->operands;
2345
+ }
2346
+
2347
+ for (i = 0; i < itemp->operands; i++) {
2348
+ if (!(itemp->opd[i] & SIZE_MASK) &&
2349
+ (instruction->oprs[i].type & SIZE_MASK & ~size[i]))
2350
+ return MERR_OPSIZEMISMATCH;
2351
+ }
2352
+
2353
+ /*
2354
+ * Check template is okay at the set cpu level
2355
+ */
2356
+ if (iflag_cmp_cpu_level(&insns_flags[itemp->iflag_idx], &cpu) > 0)
2357
+ return MERR_BADCPU;
2358
+
2359
+ /*
2360
+ * Verify the appropriate long mode flag.
2361
+ */
2362
+ if (itemp_has(itemp, (bits == 64 ? IF_NOLONG : IF_LONG)))
2363
+ return MERR_BADMODE;
2364
+
2365
+ /*
2366
+ * If we have a HLE prefix, look for the NOHLE flag
2367
+ */
2368
+ if (itemp_has(itemp, IF_NOHLE) &&
2369
+ (has_prefix(instruction, PPS_REP, P_XACQUIRE) ||
2370
+ has_prefix(instruction, PPS_REP, P_XRELEASE)))
2371
+ return MERR_BADHLE;
2372
+
2373
+ /*
2374
+ * Check if special handling needed for Jumps
2375
+ */
2376
+ if ((itemp->code[0] & ~1) == 0370)
2377
+ return MOK_JUMP;
2378
+
2379
+ /*
2380
+ * Check if BND prefix is allowed.
2381
+ * Other 0xF2 (REPNE/REPNZ) prefix is prohibited.
2382
+ */
2383
+ if (!itemp_has(itemp, IF_BND) &&
2384
+ (has_prefix(instruction, PPS_REP, P_BND) ||
2385
+ has_prefix(instruction, PPS_REP, P_NOBND)))
2386
+ return MERR_BADBND;
2387
+ else if (itemp_has(itemp, IF_BND) &&
2388
+ (has_prefix(instruction, PPS_REP, P_REPNE) ||
2389
+ has_prefix(instruction, PPS_REP, P_REPNZ)))
2390
+ return MERR_BADREPNE;
2391
+
2392
+ return MOK_GOOD;
2393
+ }
2394
+
2395
+ /*
2396
+ * Check if ModR/M.mod should/can be 01.
2397
+ * - EAF_BYTEOFFS is set
2398
+ * - offset can fit in a byte when EVEX is not used
2399
+ * - offset can be compressed when EVEX is used
2400
+ */
2401
+ #define IS_MOD_01() (!(input->eaflags & EAF_WORDOFFS) && \
2402
+ (ins->rex & REX_EV ? seg == NO_SEG && !forw_ref && \
2403
+ is_disp8n(input, ins, &output->disp8) : \
2404
+ input->eaflags & EAF_BYTEOFFS || (o >= -128 && \
2405
+ o <= 127 && seg == NO_SEG && !forw_ref)))
2406
+
2407
+ static enum ea_type process_ea(operand *input, ea *output, int bits,
2408
+ int rfield, opflags_t rflags, insn *ins,
2409
+ const char **errmsg)
2410
+ {
2411
+ bool forw_ref = !!(input->opflags & OPFLAG_UNKNOWN);
2412
+ int addrbits = ins->addr_size;
2413
+ int eaflags = input->eaflags;
2414
+
2415
+ *errmsg = "invalid effective address"; /* Default error message */
2416
+
2417
+ output->type = EA_SCALAR;
2418
+ output->rip = false;
2419
+ output->disp8 = 0;
2420
+
2421
+ /* REX flags for the rfield operand */
2422
+ output->rex |= rexflags(rfield, rflags, REX_R | REX_P | REX_W | REX_H);
2423
+ /* EVEX.R' flag for the REG operand */
2424
+ ins->evex_p[0] |= evexflags(rfield, 0, EVEX_P0RP, 0);
2425
+
2426
+ if (is_class(REGISTER, input->type)) {
2427
+ /*
2428
+ * It's a direct register.
2429
+ */
2430
+ if (!is_register(input->basereg))
2431
+ goto err;
2432
+
2433
+ if (!is_reg_class(REG_EA, input->basereg))
2434
+ goto err;
2435
+
2436
+ /* broadcasting is not available with a direct register operand. */
2437
+ if (input->decoflags & BRDCAST_MASK) {
2438
+ *errmsg = "broadcast not allowed with register operand";
2439
+ goto err;
2440
+ }
2441
+
2442
+ output->rex |= op_rexflags(input, REX_B | REX_P | REX_W | REX_H);
2443
+ ins->evex_p[0] |= op_evexflags(input, EVEX_P0X, 0);
2444
+ output->sib_present = false; /* no SIB necessary */
2445
+ output->bytes = 0; /* no offset necessary either */
2446
+ output->modrm = GEN_MODRM(3, rfield, nasm_regvals[input->basereg]);
2447
+ } else {
2448
+ /*
2449
+ * It's a memory reference.
2450
+ */
2451
+
2452
+ /* Embedded rounding or SAE is not available with a mem ref operand. */
2453
+ if (input->decoflags & (ER | SAE)) {
2454
+ *errmsg = "embedded rounding is available only with "
2455
+ "register-register operations";
2456
+ goto err;
2457
+ }
2458
+
2459
+ if (input->basereg == -1 &&
2460
+ (input->indexreg == -1 || input->scale == 0)) {
2461
+ /*
2462
+ * It's a pure offset.
2463
+ */
2464
+ if (bits == 64 && ((input->type & IP_REL) == IP_REL)) {
2465
+ if (input->segment == NO_SEG ||
2466
+ (input->opflags & OPFLAG_RELATIVE)) {
2467
+ nasm_error(ERR_WARNING | ERR_PASS2,
2468
+ "absolute address can not be RIP-relative");
2469
+ input->type &= ~IP_REL;
2470
+ input->type |= MEMORY;
2471
+ }
2472
+ }
2473
+
2474
+ if (bits == 64 &&
2475
+ !(IP_REL & ~input->type) && (eaflags & EAF_MIB)) {
2476
+ *errmsg = "RIP-relative addressing is prohibited for MIB";
2477
+ goto err;
2478
+ }
2479
+
2480
+ if (eaflags & EAF_BYTEOFFS ||
2481
+ (eaflags & EAF_WORDOFFS &&
2482
+ input->disp_size != (addrbits != 16 ? 32 : 16))) {
2483
+ nasm_error(ERR_WARNING | ERR_PASS1,
2484
+ "displacement size ignored on absolute address");
2485
+ }
2486
+
2487
+ if (bits == 64 && (~input->type & IP_REL)) {
2488
+ output->sib_present = true;
2489
+ output->sib = GEN_SIB(0, 4, 5);
2490
+ output->bytes = 4;
2491
+ output->modrm = GEN_MODRM(0, rfield, 4);
2492
+ output->rip = false;
2493
+ } else {
2494
+ output->sib_present = false;
2495
+ output->bytes = (addrbits != 16 ? 4 : 2);
2496
+ output->modrm = GEN_MODRM(0, rfield,
2497
+ (addrbits != 16 ? 5 : 6));
2498
+ output->rip = bits == 64;
2499
+ }
2500
+ } else {
2501
+ /*
2502
+ * It's an indirection.
2503
+ */
2504
+ int i = input->indexreg, b = input->basereg, s = input->scale;
2505
+ int32_t seg = input->segment;
2506
+ int hb = input->hintbase, ht = input->hinttype;
2507
+ int t, it, bt; /* register numbers */
2508
+ opflags_t x, ix, bx; /* register flags */
2509
+
2510
+ if (s == 0)
2511
+ i = -1; /* make this easy, at least */
2512
+
2513
+ if (is_register(i)) {
2514
+ it = nasm_regvals[i];
2515
+ ix = nasm_reg_flags[i];
2516
+ } else {
2517
+ it = -1;
2518
+ ix = 0;
2519
+ }
2520
+
2521
+ if (is_register(b)) {
2522
+ bt = nasm_regvals[b];
2523
+ bx = nasm_reg_flags[b];
2524
+ } else {
2525
+ bt = -1;
2526
+ bx = 0;
2527
+ }
2528
+
2529
+ /* if either one are a vector register... */
2530
+ if ((ix|bx) & (XMMREG|YMMREG|ZMMREG) & ~REG_EA) {
2531
+ opflags_t sok = BITS32 | BITS64;
2532
+ int32_t o = input->offset;
2533
+ int mod, scale, index, base;
2534
+
2535
+ /*
2536
+ * For a vector SIB, one has to be a vector and the other,
2537
+ * if present, a GPR. The vector must be the index operand.
2538
+ */
2539
+ if (it == -1 || (bx & (XMMREG|YMMREG|ZMMREG) & ~REG_EA)) {
2540
+ if (s == 0)
2541
+ s = 1;
2542
+ else if (s != 1)
2543
+ goto err;
2544
+
2545
+ t = bt, bt = it, it = t;
2546
+ x = bx, bx = ix, ix = x;
2547
+ }
2548
+
2549
+ if (bt != -1) {
2550
+ if (REG_GPR & ~bx)
2551
+ goto err;
2552
+ if (!(REG64 & ~bx) || !(REG32 & ~bx))
2553
+ sok &= bx;
2554
+ else
2555
+ goto err;
2556
+ }
2557
+
2558
+ /*
2559
+ * While we're here, ensure the user didn't specify
2560
+ * WORD or QWORD
2561
+ */
2562
+ if (input->disp_size == 16 || input->disp_size == 64)
2563
+ goto err;
2564
+
2565
+ if (addrbits == 16 ||
2566
+ (addrbits == 32 && !(sok & BITS32)) ||
2567
+ (addrbits == 64 && !(sok & BITS64)))
2568
+ goto err;
2569
+
2570
+ output->type = ((ix & ZMMREG & ~REG_EA) ? EA_ZMMVSIB
2571
+ : ((ix & YMMREG & ~REG_EA)
2572
+ ? EA_YMMVSIB : EA_XMMVSIB));
2573
+
2574
+ output->rex |= rexflags(it, ix, REX_X);
2575
+ output->rex |= rexflags(bt, bx, REX_B);
2576
+ ins->evex_p[2] |= evexflags(it, 0, EVEX_P2VP, 2);
2577
+
2578
+ index = it & 7; /* it is known to be != -1 */
2579
+
2580
+ switch (s) {
2581
+ case 1:
2582
+ scale = 0;
2583
+ break;
2584
+ case 2:
2585
+ scale = 1;
2586
+ break;
2587
+ case 4:
2588
+ scale = 2;
2589
+ break;
2590
+ case 8:
2591
+ scale = 3;
2592
+ break;
2593
+ default: /* then what the smeg is it? */
2594
+ goto err; /* panic */
2595
+ }
2596
+
2597
+ if (bt == -1) {
2598
+ base = 5;
2599
+ mod = 0;
2600
+ } else {
2601
+ base = (bt & 7);
2602
+ if (base != REG_NUM_EBP && o == 0 &&
2603
+ seg == NO_SEG && !forw_ref &&
2604
+ !(eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS)))
2605
+ mod = 0;
2606
+ else if (IS_MOD_01())
2607
+ mod = 1;
2608
+ else
2609
+ mod = 2;
2610
+ }
2611
+
2612
+ output->sib_present = true;
2613
+ output->bytes = (bt == -1 || mod == 2 ? 4 : mod);
2614
+ output->modrm = GEN_MODRM(mod, rfield, 4);
2615
+ output->sib = GEN_SIB(scale, index, base);
2616
+ } else if ((ix|bx) & (BITS32|BITS64)) {
2617
+ /*
2618
+ * it must be a 32/64-bit memory reference. Firstly we have
2619
+ * to check that all registers involved are type E/Rxx.
2620
+ */
2621
+ opflags_t sok = BITS32 | BITS64;
2622
+ int32_t o = input->offset;
2623
+
2624
+ if (it != -1) {
2625
+ if (!(REG64 & ~ix) || !(REG32 & ~ix))
2626
+ sok &= ix;
2627
+ else
2628
+ goto err;
2629
+ }
2630
+
2631
+ if (bt != -1) {
2632
+ if (REG_GPR & ~bx)
2633
+ goto err; /* Invalid register */
2634
+ if (~sok & bx & SIZE_MASK)
2635
+ goto err; /* Invalid size */
2636
+ sok &= bx;
2637
+ }
2638
+
2639
+ /*
2640
+ * While we're here, ensure the user didn't specify
2641
+ * WORD or QWORD
2642
+ */
2643
+ if (input->disp_size == 16 || input->disp_size == 64)
2644
+ goto err;
2645
+
2646
+ if (addrbits == 16 ||
2647
+ (addrbits == 32 && !(sok & BITS32)) ||
2648
+ (addrbits == 64 && !(sok & BITS64)))
2649
+ goto err;
2650
+
2651
+ /* now reorganize base/index */
2652
+ if (s == 1 && bt != it && bt != -1 && it != -1 &&
2653
+ ((hb == b && ht == EAH_NOTBASE) ||
2654
+ (hb == i && ht == EAH_MAKEBASE))) {
2655
+ /* swap if hints say so */
2656
+ t = bt, bt = it, it = t;
2657
+ x = bx, bx = ix, ix = x;
2658
+ }
2659
+
2660
+ if (bt == -1 && s == 1 && !(hb == i && ht == EAH_NOTBASE)) {
2661
+ /* make single reg base, unless hint */
2662
+ bt = it, bx = ix, it = -1, ix = 0;
2663
+ }
2664
+ if (eaflags & EAF_MIB) {
2665
+ /* only for mib operands */
2666
+ if (it == -1 && (hb == b && ht == EAH_NOTBASE)) {
2667
+ /*
2668
+ * make a single reg index [reg*1].
2669
+ * gas uses this form for an explicit index register.
2670
+ */
2671
+ it = bt, ix = bx, bt = -1, bx = 0, s = 1;
2672
+ }
2673
+ if ((ht == EAH_SUMMED) && bt == -1) {
2674
+ /* separate once summed index into [base, index] */
2675
+ bt = it, bx = ix, s--;
2676
+ }
2677
+ } else {
2678
+ if (((s == 2 && it != REG_NUM_ESP &&
2679
+ (!(eaflags & EAF_TIMESTWO) || (ht == EAH_SUMMED))) ||
2680
+ s == 3 || s == 5 || s == 9) && bt == -1) {
2681
+ /* convert 3*EAX to EAX+2*EAX */
2682
+ bt = it, bx = ix, s--;
2683
+ }
2684
+ if (it == -1 && (bt & 7) != REG_NUM_ESP &&
2685
+ (eaflags & EAF_TIMESTWO) &&
2686
+ (hb == b && ht == EAH_NOTBASE)) {
2687
+ /*
2688
+ * convert [NOSPLIT EAX*1]
2689
+ * to sib format with 0x0 displacement - [EAX*1+0].
2690
+ */
2691
+ it = bt, ix = bx, bt = -1, bx = 0, s = 1;
2692
+ }
2693
+ }
2694
+ if (s == 1 && it == REG_NUM_ESP) {
2695
+ /* swap ESP into base if scale is 1 */
2696
+ t = it, it = bt, bt = t;
2697
+ x = ix, ix = bx, bx = x;
2698
+ }
2699
+ if (it == REG_NUM_ESP ||
2700
+ (s != 1 && s != 2 && s != 4 && s != 8 && it != -1))
2701
+ goto err; /* wrong, for various reasons */
2702
+
2703
+ output->rex |= rexflags(it, ix, REX_X);
2704
+ output->rex |= rexflags(bt, bx, REX_B);
2705
+
2706
+ if (it == -1 && (bt & 7) != REG_NUM_ESP) {
2707
+ /* no SIB needed */
2708
+ int mod, rm;
2709
+
2710
+ if (bt == -1) {
2711
+ rm = 5;
2712
+ mod = 0;
2713
+ } else {
2714
+ rm = (bt & 7);
2715
+ if (rm != REG_NUM_EBP && o == 0 &&
2716
+ seg == NO_SEG && !forw_ref &&
2717
+ !(eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS)))
2718
+ mod = 0;
2719
+ else if (IS_MOD_01())
2720
+ mod = 1;
2721
+ else
2722
+ mod = 2;
2723
+ }
2724
+
2725
+ output->sib_present = false;
2726
+ output->bytes = (bt == -1 || mod == 2 ? 4 : mod);
2727
+ output->modrm = GEN_MODRM(mod, rfield, rm);
2728
+ } else {
2729
+ /* we need a SIB */
2730
+ int mod, scale, index, base;
2731
+
2732
+ if (it == -1)
2733
+ index = 4, s = 1;
2734
+ else
2735
+ index = (it & 7);
2736
+
2737
+ switch (s) {
2738
+ case 1:
2739
+ scale = 0;
2740
+ break;
2741
+ case 2:
2742
+ scale = 1;
2743
+ break;
2744
+ case 4:
2745
+ scale = 2;
2746
+ break;
2747
+ case 8:
2748
+ scale = 3;
2749
+ break;
2750
+ default: /* then what the smeg is it? */
2751
+ goto err; /* panic */
2752
+ }
2753
+
2754
+ if (bt == -1) {
2755
+ base = 5;
2756
+ mod = 0;
2757
+ } else {
2758
+ base = (bt & 7);
2759
+ if (base != REG_NUM_EBP && o == 0 &&
2760
+ seg == NO_SEG && !forw_ref &&
2761
+ !(eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS)))
2762
+ mod = 0;
2763
+ else if (IS_MOD_01())
2764
+ mod = 1;
2765
+ else
2766
+ mod = 2;
2767
+ }
2768
+
2769
+ output->sib_present = true;
2770
+ output->bytes = (bt == -1 || mod == 2 ? 4 : mod);
2771
+ output->modrm = GEN_MODRM(mod, rfield, 4);
2772
+ output->sib = GEN_SIB(scale, index, base);
2773
+ }
2774
+ } else { /* it's 16-bit */
2775
+ int mod, rm;
2776
+ int16_t o = input->offset;
2777
+
2778
+ /* check for 64-bit long mode */
2779
+ if (addrbits == 64)
2780
+ goto err;
2781
+
2782
+ /* check all registers are BX, BP, SI or DI */
2783
+ if ((b != -1 && b != R_BP && b != R_BX && b != R_SI && b != R_DI) ||
2784
+ (i != -1 && i != R_BP && i != R_BX && i != R_SI && i != R_DI))
2785
+ goto err;
2786
+
2787
+ /* ensure the user didn't specify DWORD/QWORD */
2788
+ if (input->disp_size == 32 || input->disp_size == 64)
2789
+ goto err;
2790
+
2791
+ if (s != 1 && i != -1)
2792
+ goto err; /* no can do, in 16-bit EA */
2793
+ if (b == -1 && i != -1) {
2794
+ int tmp = b;
2795
+ b = i;
2796
+ i = tmp;
2797
+ } /* swap */
2798
+ if ((b == R_SI || b == R_DI) && i != -1) {
2799
+ int tmp = b;
2800
+ b = i;
2801
+ i = tmp;
2802
+ }
2803
+ /* have BX/BP as base, SI/DI index */
2804
+ if (b == i)
2805
+ goto err; /* shouldn't ever happen, in theory */
2806
+ if (i != -1 && b != -1 &&
2807
+ (i == R_BP || i == R_BX || b == R_SI || b == R_DI))
2808
+ goto err; /* invalid combinations */
2809
+ if (b == -1) /* pure offset: handled above */
2810
+ goto err; /* so if it gets to here, panic! */
2811
+
2812
+ rm = -1;
2813
+ if (i != -1)
2814
+ switch (i * 256 + b) {
2815
+ case R_SI * 256 + R_BX:
2816
+ rm = 0;
2817
+ break;
2818
+ case R_DI * 256 + R_BX:
2819
+ rm = 1;
2820
+ break;
2821
+ case R_SI * 256 + R_BP:
2822
+ rm = 2;
2823
+ break;
2824
+ case R_DI * 256 + R_BP:
2825
+ rm = 3;
2826
+ break;
2827
+ } else
2828
+ switch (b) {
2829
+ case R_SI:
2830
+ rm = 4;
2831
+ break;
2832
+ case R_DI:
2833
+ rm = 5;
2834
+ break;
2835
+ case R_BP:
2836
+ rm = 6;
2837
+ break;
2838
+ case R_BX:
2839
+ rm = 7;
2840
+ break;
2841
+ }
2842
+ if (rm == -1) /* can't happen, in theory */
2843
+ goto err; /* so panic if it does */
2844
+
2845
+ if (o == 0 && seg == NO_SEG && !forw_ref && rm != 6 &&
2846
+ !(eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS)))
2847
+ mod = 0;
2848
+ else if (IS_MOD_01())
2849
+ mod = 1;
2850
+ else
2851
+ mod = 2;
2852
+
2853
+ output->sib_present = false; /* no SIB - it's 16-bit */
2854
+ output->bytes = mod; /* bytes of offset needed */
2855
+ output->modrm = GEN_MODRM(mod, rfield, rm);
2856
+ }
2857
+ }
2858
+ }
2859
+
2860
+ output->size = 1 + output->sib_present + output->bytes;
2861
+ return output->type;
2862
+
2863
+ err:
2864
+ return output->type = EA_INVALID;
2865
+ }
2866
+
2867
+ static void add_asp(insn *ins, int addrbits)
2868
+ {
2869
+ int j, valid;
2870
+ int defdisp;
2871
+
2872
+ valid = (addrbits == 64) ? 64|32 : 32|16;
2873
+
2874
+ switch (ins->prefixes[PPS_ASIZE]) {
2875
+ case P_A16:
2876
+ valid &= 16;
2877
+ break;
2878
+ case P_A32:
2879
+ valid &= 32;
2880
+ break;
2881
+ case P_A64:
2882
+ valid &= 64;
2883
+ break;
2884
+ case P_ASP:
2885
+ valid &= (addrbits == 32) ? 16 : 32;
2886
+ break;
2887
+ default:
2888
+ break;
2889
+ }
2890
+
2891
+ for (j = 0; j < ins->operands; j++) {
2892
+ if (is_class(MEMORY, ins->oprs[j].type)) {
2893
+ opflags_t i, b;
2894
+
2895
+ /* Verify as Register */
2896
+ if (!is_register(ins->oprs[j].indexreg))
2897
+ i = 0;
2898
+ else
2899
+ i = nasm_reg_flags[ins->oprs[j].indexreg];
2900
+
2901
+ /* Verify as Register */
2902
+ if (!is_register(ins->oprs[j].basereg))
2903
+ b = 0;
2904
+ else
2905
+ b = nasm_reg_flags[ins->oprs[j].basereg];
2906
+
2907
+ if (ins->oprs[j].scale == 0)
2908
+ i = 0;
2909
+
2910
+ if (!i && !b) {
2911
+ int ds = ins->oprs[j].disp_size;
2912
+ if ((addrbits != 64 && ds > 8) ||
2913
+ (addrbits == 64 && ds == 16))
2914
+ valid &= ds;
2915
+ } else {
2916
+ if (!(REG16 & ~b))
2917
+ valid &= 16;
2918
+ if (!(REG32 & ~b))
2919
+ valid &= 32;
2920
+ if (!(REG64 & ~b))
2921
+ valid &= 64;
2922
+
2923
+ if (!(REG16 & ~i))
2924
+ valid &= 16;
2925
+ if (!(REG32 & ~i))
2926
+ valid &= 32;
2927
+ if (!(REG64 & ~i))
2928
+ valid &= 64;
2929
+ }
2930
+ }
2931
+ }
2932
+
2933
+ if (valid & addrbits) {
2934
+ ins->addr_size = addrbits;
2935
+ } else if (valid & ((addrbits == 32) ? 16 : 32)) {
2936
+ /* Add an address size prefix */
2937
+ ins->prefixes[PPS_ASIZE] = (addrbits == 32) ? P_A16 : P_A32;;
2938
+ ins->addr_size = (addrbits == 32) ? 16 : 32;
2939
+ } else {
2940
+ /* Impossible... */
2941
+ nasm_error(ERR_NONFATAL, "impossible combination of address sizes");
2942
+ ins->addr_size = addrbits; /* Error recovery */
2943
+ }
2944
+
2945
+ defdisp = ins->addr_size == 16 ? 16 : 32;
2946
+
2947
+ for (j = 0; j < ins->operands; j++) {
2948
+ if (!(MEM_OFFS & ~ins->oprs[j].type) &&
2949
+ (ins->oprs[j].disp_size ? ins->oprs[j].disp_size : defdisp) != ins->addr_size) {
2950
+ /*
2951
+ * mem_offs sizes must match the address size; if not,
2952
+ * strip the MEM_OFFS bit and match only EA instructions
2953
+ */
2954
+ ins->oprs[j].type &= ~(MEM_OFFS & ~MEMORY);
2955
+ }
2956
+ }
2957
+ }