laag-nasm 2.13.03.2

Sign up to get free protection for your applications and to get access to all the features.
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
+ }