x86regtmod.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /* ANSI-C code produced by genperf */
  2. #include <util.h>
  3. #include <ctype.h>
  4. #include <libyasm.h>
  5. #include <libyasm/phash.h>
  6. #include "modules/arch/x86/x86arch.h"
  7. enum regtmod_type {
  8. REG = 1,
  9. REGGROUP,
  10. SEGREG,
  11. TARGETMOD
  12. };
  13. struct regtmod_parse_data {
  14. const char *name;
  15. unsigned int type:8; /* regtmod_type */
  16. /* REG: register size
  17. * SEGREG: prefix encoding
  18. * Others: 0
  19. */
  20. unsigned int size_prefix:8;
  21. /* REG: register index
  22. * REGGROUP: register group type
  23. * SEGREG: register encoding
  24. * TARGETMOD: target modifier
  25. */
  26. unsigned int data:8;
  27. /* REG: required bits setting
  28. * SEGREG: BITS in which the segment is ignored
  29. * Others: 0
  30. */
  31. unsigned int bits:8;
  32. };
  33. static const struct regtmod_parse_data *
  34. regtmod_find(const char *key, size_t len)
  35. {
  36. static const struct regtmod_parse_data pd[152] = {
  37. {"st6", REG, X86_FPUREG, 6, 0},
  38. {"ymm1", REG, X86_YMMREG, 1, 0},
  39. {"rsp", REG, X86_REG64, 4, 64},
  40. {"r10", REG, X86_REG64, 10, 64},
  41. {"bp", REG, X86_REG16, 5, 0},
  42. {"r10b", REG, X86_REG8, 10, 64},
  43. {"mm2", REG, X86_MMXREG, 2, 0},
  44. {"rdi", REG, X86_REG64, 7, 64},
  45. {"ymm12", REG, X86_YMMREG, 12, 64},
  46. {"r8", REG, X86_REG64, 8, 64},
  47. {"gs", SEGREG, 0x65, 0x05, 0},
  48. {"r10d", REG, X86_REG32, 10, 64},
  49. {"rsi", REG, X86_REG64, 6, 64},
  50. {"eax", REG, X86_REG32, 0, 0},
  51. {"mm3", REG, X86_MMXREG, 3, 0},
  52. {"tr6", REG, X86_TRREG, 6, 0},
  53. {"tr0", REG, X86_TRREG, 0, 0},
  54. {"ah", REG, X86_REG8, 4, 0},
  55. {"xmm6", REG, X86_XMMREG, 6, 0},
  56. {"dr6", REG, X86_DRREG, 6, 0},
  57. {"esp", REG, X86_REG32, 4, 0},
  58. {"bpl", REG, X86_REG8X, 5, 64},
  59. {"tr5", REG, X86_TRREG, 5, 0},
  60. {"ax", REG, X86_REG16, 0, 0},
  61. {"sp", REG, X86_REG16, 4, 0},
  62. {"r15b", REG, X86_REG8, 15, 64},
  63. {"xmm14", REG, X86_XMMREG, 14, 64},
  64. {"xmm12", REG, X86_XMMREG, 12, 64},
  65. {"r11", REG, X86_REG64, 11, 64},
  66. {"xmm", REGGROUP, 0, X86_XMMREG, 0},
  67. {"ymm2", REG, X86_YMMREG, 2, 0},
  68. {"ebp", REG, X86_REG32, 5, 0},
  69. {"xmm8", REG, X86_XMMREG, 8, 64},
  70. {"r12d", REG, X86_REG32, 12, 64},
  71. {"ymm4", REG, X86_YMMREG, 4, 0},
  72. {"ymm3", REG, X86_YMMREG, 3, 0},
  73. {"rax", REG, X86_REG64, 0, 64},
  74. {"xmm3", REG, X86_XMMREG, 3, 0},
  75. {"xmm0", REG, X86_XMMREG, 0, 0},
  76. {"dr7", REG, X86_DRREG, 7, 0},
  77. {"r14w", REG, X86_REG16, 14, 64},
  78. {"mm1", REG, X86_MMXREG, 1, 0},
  79. {"bl", REG, X86_REG8, 3, 0},
  80. {"r9w", REG, X86_REG16, 9, 64},
  81. {"ymm13", REG, X86_YMMREG, 13, 64},
  82. {"r9b", REG, X86_REG8, 9, 64},
  83. {"ymm8", REG, X86_YMMREG, 8, 64},
  84. {"dx", REG, X86_REG16, 2, 0},
  85. {"r12", REG, X86_REG64, 12, 64},
  86. {"r12w", REG, X86_REG16, 12, 64},
  87. {"r9", REG, X86_REG64, 9, 64},
  88. {"r15w", REG, X86_REG16, 15, 64},
  89. {"sil", REG, X86_REG8X, 6, 64},
  90. {"r10w", REG, X86_REG16, 10, 64},
  91. {"ymm6", REG, X86_YMMREG, 6, 0},
  92. {"ss", SEGREG, 0x36, 0x02, 64},
  93. {"tr4", REG, X86_TRREG, 4, 0},
  94. {"cr3", REG, X86_CRREG, 3, 0},
  95. {"r11w", REG, X86_REG16, 11, 64},
  96. {"xmm4", REG, X86_XMMREG, 4, 0},
  97. {"st0", REG, X86_FPUREG, 0, 0},
  98. {"dil", REG, X86_REG8X, 7, 64},
  99. {"tr3", REG, X86_TRREG, 3, 0},
  100. {"r13d", REG, X86_REG32, 13, 64},
  101. {"r8w", REG, X86_REG16, 8, 64},
  102. {"xmm13", REG, X86_XMMREG, 13, 64},
  103. {"st3", REG, X86_FPUREG, 3, 0},
  104. {"xmm15", REG, X86_XMMREG, 15, 64},
  105. {"xmm10", REG, X86_XMMREG, 10, 64},
  106. {"es", SEGREG, 0x26, 0x00, 64},
  107. {"cr8", REG, X86_CRREG, 8, 64},
  108. {"xmm7", REG, X86_XMMREG, 7, 0},
  109. {"spl", REG, X86_REG8X, 4, 64},
  110. {"r15", REG, X86_REG64, 15, 64},
  111. {"cr4", REG, X86_CRREG, 4, 0},
  112. {"fs", SEGREG, 0x64, 0x04, 0},
  113. {"rcx", REG, X86_REG64, 1, 64},
  114. {"mm0", REG, X86_MMXREG, 0, 0},
  115. {"mm", REGGROUP, 0, X86_MMXREG, 0},
  116. {"tr1", REG, X86_TRREG, 1, 0},
  117. {"short", TARGETMOD, 0, X86_SHORT, 0},
  118. {"st4", REG, X86_FPUREG, 4, 0},
  119. {"cr0", REG, X86_CRREG, 0, 0},
  120. {"xmm11", REG, X86_XMMREG, 11, 64},
  121. {"mm4", REG, X86_MMXREG, 4, 0},
  122. {"bh", REG, X86_REG8, 7, 0},
  123. {"r15d", REG, X86_REG32, 15, 64},
  124. {"dr2", REG, X86_DRREG, 2, 0},
  125. {"r8d", REG, X86_REG32, 8, 64},
  126. {"ymm7", REG, X86_YMMREG, 7, 0},
  127. {"xmm9", REG, X86_XMMREG, 9, 64},
  128. {"r12b", REG, X86_REG8, 12, 64},
  129. {"st2", REG, X86_FPUREG, 2, 0},
  130. {"ymm9", REG, X86_YMMREG, 9, 64},
  131. {"st7", REG, X86_FPUREG, 7, 0},
  132. {"bx", REG, X86_REG16, 3, 0},
  133. {"ymm11", REG, X86_YMMREG, 11, 64},
  134. {"ymm5", REG, X86_YMMREG, 5, 0},
  135. {"ymm15", REG, X86_YMMREG, 15, 64},
  136. {"rbp", REG, X86_REG64, 5, 64},
  137. {"r13", REG, X86_REG64, 13, 64},
  138. {"mm5", REG, X86_MMXREG, 5, 0},
  139. {"si", REG, X86_REG16, 6, 0},
  140. {"dl", REG, X86_REG8, 2, 0},
  141. {"di", REG, X86_REG16, 7, 0},
  142. {"cr2", REG, X86_CRREG, 2, 0},
  143. {"r14d", REG, X86_REG32, 14, 64},
  144. {"ymm14", REG, X86_YMMREG, 14, 64},
  145. {"tr7", REG, X86_TRREG, 7, 0},
  146. {"ds", SEGREG, 0x3e, 0x03, 64},
  147. {"cx", REG, X86_REG16, 1, 0},
  148. {"st", REGGROUP, 0, X86_FPUREG, 0},
  149. {"edi", REG, X86_REG32, 7, 0},
  150. {"al", REG, X86_REG8, 0, 0},
  151. {"mm7", REG, X86_MMXREG, 7, 0},
  152. {"ebx", REG, X86_REG32, 3, 0},
  153. {"xmm2", REG, X86_XMMREG, 2, 0},
  154. {"st5", REG, X86_FPUREG, 5, 0},
  155. {"rip", REG, X86_RIP, 0, 64},
  156. {"rbx", REG, X86_REG64, 3, 64},
  157. {"to", TARGETMOD, 0, X86_TO, 0},
  158. {"r11d", REG, X86_REG32, 11, 64},
  159. {"dr5", REG, X86_DRREG, 5, 0},
  160. {"dr1", REG, X86_DRREG, 1, 0},
  161. {"near", TARGETMOD, 0, X86_NEAR, 0},
  162. {"r14", REG, X86_REG64, 14, 64},
  163. {"dh", REG, X86_REG8, 6, 0},
  164. {"cl", REG, X86_REG8, 1, 0},
  165. {"dr4", REG, X86_DRREG, 4, 0},
  166. {"ymm10", REG, X86_YMMREG, 10, 64},
  167. {"dr3", REG, X86_DRREG, 3, 0},
  168. {"xmm5", REG, X86_XMMREG, 5, 0},
  169. {"mm6", REG, X86_MMXREG, 6, 0},
  170. {"r13w", REG, X86_REG16, 13, 64},
  171. {"far", TARGETMOD, 0, X86_FAR, 0},
  172. {"ymm0", REG, X86_YMMREG, 0, 0},
  173. {"ymm", REGGROUP, 0, X86_YMMREG, 0},
  174. {"ch", REG, X86_REG8, 5, 0},
  175. {"xmm1", REG, X86_XMMREG, 1, 0},
  176. {"esi", REG, X86_REG32, 6, 0},
  177. {"r14b", REG, X86_REG8, 14, 64},
  178. {"st1", REG, X86_FPUREG, 1, 0},
  179. {"r8b", REG, X86_REG8, 8, 64},
  180. {"r11b", REG, X86_REG8, 11, 64},
  181. {"r13b", REG, X86_REG8, 13, 64},
  182. {"ecx", REG, X86_REG32, 1, 0},
  183. {"tr2", REG, X86_TRREG, 2, 0},
  184. {"rdx", REG, X86_REG64, 2, 64},
  185. {"r9d", REG, X86_REG32, 9, 64},
  186. {"cs", SEGREG, 0x2e, 0x01, 0},
  187. {"dr0", REG, X86_DRREG, 0, 0},
  188. {"edx", REG, X86_REG32, 2, 0}
  189. };
  190. static const unsigned char tab[] = {
  191. 0,0,125,22,0,0,85,0,85,168,0,0,0,7,113,0,
  192. 0,0,0,22,183,0,0,11,42,55,0,0,82,0,88,235,
  193. 0,0,0,0,0,0,183,85,0,0,145,113,220,125,22,0,
  194. 88,183,0,7,0,0,0,7,0,125,113,87,131,116,7,0,
  195. 113,7,0,113,0,87,87,7,7,7,113,40,85,125,113,85,
  196. 0,0,22,235,0,131,125,113,0,22,0,220,0,220,0,120,
  197. 116,0,124,184,0,0,0,183,92,125,0,92,125,0,0,177,
  198. 7,0,0,7,0,45,0,214,180,113,211,163,142,0,88,173,
  199. };
  200. const struct regtmod_parse_data *ret;
  201. unsigned long rsl, val = phash_lookup(key, len, 0x9e3779b9UL);
  202. rsl = ((val>>25)^tab[val&0x7f]);
  203. if (rsl >= 152) return NULL;
  204. ret = &pd[rsl];
  205. if (strcmp(key, ret->name) != 0) return NULL;
  206. return ret;
  207. }
  208. yasm_arch_regtmod
  209. yasm_x86__parse_check_regtmod(yasm_arch *arch, const char *id, size_t id_len,
  210. uintptr_t *data)
  211. {
  212. yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
  213. /*@null@*/ const struct regtmod_parse_data *pdata;
  214. size_t i;
  215. static char lcaseid[8];
  216. unsigned int bits;
  217. yasm_arch_regtmod type;
  218. if (id_len > 7)
  219. return YASM_ARCH_NOTREGTMOD;
  220. for (i=0; i<id_len; i++)
  221. lcaseid[i] = tolower(id[i]);
  222. lcaseid[id_len] = '\0';
  223. pdata = regtmod_find(lcaseid, id_len);
  224. if (!pdata)
  225. return YASM_ARCH_NOTREGTMOD;
  226. type = (yasm_arch_regtmod)pdata->type;
  227. bits = pdata->bits;
  228. if (type == YASM_ARCH_REG && bits != 0 && arch_x86->mode_bits != bits) {
  229. yasm_warn_set(YASM_WARN_GENERAL,
  230. N_("`%s' is a register in %u-bit mode"), id, bits);
  231. return YASM_ARCH_NOTREGTMOD;
  232. }
  233. if (type == YASM_ARCH_SEGREG && bits != 0 && arch_x86->mode_bits == bits) {
  234. yasm_warn_set(YASM_WARN_GENERAL,
  235. N_("`%s' segment register ignored in %u-bit mode"), id,
  236. bits);
  237. }
  238. if (type == YASM_ARCH_SEGREG)
  239. *data = (pdata->size_prefix<<8) | pdata->data;
  240. else
  241. *data = pdata->size_prefix | pdata->data;
  242. return type;
  243. }