db_disasm64.c 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670
  1. /*-
  2. * Mach Operating System
  3. * Copyright (c) 1991,1990 Carnegie Mellon University
  4. * All Rights Reserved.
  5. *
  6. * Permission to use, copy, modify and distribute this software and its
  7. * documentation is hereby granted, provided that both the copyright
  8. * notice and this permission notice appear in all copies of the
  9. * software, derivative works or modified versions, and any portions
  10. * thereof, and that both notices appear in supporting documentation.
  11. *
  12. * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
  13. * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14. * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15. *
  16. * Carnegie Mellon requests users of this software to return to
  17. *
  18. * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
  19. * School of Computer Science
  20. * Carnegie Mellon University
  21. * Pittsburgh PA 15213-3890
  22. *
  23. * any improvements or extensions that they make and grant Carnegie the
  24. * rights to redistribute these changes.
  25. */
  26. /*
  27. * Instruction disassembler.
  28. */
  29. /* <Wine specific wrappers> */
  30. #include <stdio.h>
  31. #include "debugger.h"
  32. #if defined(__GNUC__) && (__GNUC__ >= 3)
  33. static int WINAPIV (*db_printf)(const char* format, ...) __attribute__((format (printf,1,2)));
  34. #else
  35. static int WINAPIV (*db_printf)(const char* format, ...);
  36. #endif
  37. static int WINAPIV no_printf(const char* format, ...) {return 0;}
  38. typedef DWORD_PTR db_addr_t;
  39. typedef BOOL boolean_t;
  40. static ULONG64 db_get_value(db_addr_t addr, int size, int is_signed)
  41. {
  42. ULONG64 result = 0;
  43. char buffer[8];
  44. if (size != 1 && size != 2 && size != 4 && size != 8)
  45. {
  46. db_printf("Illegal size specified\n");
  47. }
  48. else if (dbg_read_memory((void*)addr, buffer, size))
  49. {
  50. switch (size)
  51. {
  52. case 8:
  53. if (is_signed) result = (ULONG64)*(LONG64*)buffer;
  54. else result = *(ULONG64*)buffer;
  55. break;
  56. case 4:
  57. if (is_signed) result = (ULONG) *(LONG*)buffer;
  58. else result = *(ULONG64*)buffer;
  59. break;
  60. case 2:
  61. if (is_signed) result = (unsigned int) *(short int *)buffer;
  62. else result = *(unsigned short int *)buffer;
  63. break;
  64. case 1:
  65. if (is_signed) result = (unsigned int) *(char *)buffer;
  66. else result = *(unsigned char *)buffer;
  67. break;
  68. }
  69. }
  70. return result;
  71. }
  72. #define DB_STGY_ANY 0
  73. #define DB_STGY_XTRN 0
  74. static void db_printsym(db_addr_t addr, unsigned unused)
  75. {
  76. if (db_printf != no_printf)
  77. {
  78. ADDRESS64 a;
  79. a.Mode = AddrModeFlat;
  80. a.Offset = addr;
  81. print_address(&a, FALSE);
  82. }
  83. }
  84. /* </Wine specific wrappers> */
  85. /*
  86. * Size attributes
  87. */
  88. #define BYTE 0
  89. #define WORD 1
  90. #define LONG 2
  91. #define QUAD 3
  92. #define SNGL 4
  93. #define DBLR 5
  94. #define EXTR 6
  95. #define SDEP 7
  96. #define NONE 8
  97. /*
  98. * REX prefix and bits
  99. */
  100. #define REX_B 1
  101. #define REX_X 2
  102. #define REX_R 4
  103. #define REX_W 8
  104. #define REX 0x40
  105. /*
  106. * Addressing modes
  107. */
  108. #define E 1 /* general effective address */
  109. #define Eind 2 /* indirect address (jump, call) */
  110. #define Ew 3 /* address, word size */
  111. #define Eb 4 /* address, byte size */
  112. #define R 5 /* register, in 'reg' field */
  113. #define Rw 6 /* word register, in 'reg' field */
  114. #define Ri 7 /* register in instruction */
  115. #define S 8 /* segment reg, in 'reg' field */
  116. #define Si 9 /* segment reg, in instruction */
  117. #define A 10 /* accumulator */
  118. #define BX 11 /* (bx) */
  119. #define CL 12 /* cl, for shifts */
  120. #define DX 13 /* dx, for IO */
  121. #define SI 14 /* si */
  122. #define DI 15 /* di */
  123. #define CR 16 /* control register */
  124. #define DR 17 /* debug register */
  125. #define TR 18 /* test register */
  126. #define I 19 /* immediate, unsigned */
  127. #define Is 20 /* immediate, signed */
  128. #define Ib 21 /* byte immediate, unsigned */
  129. #define Ibs 22 /* byte immediate, signed */
  130. #define Iw 23 /* word immediate, unsigned */
  131. #define Ilq 24 /* long/quad immediate, unsigned */
  132. #define O 25 /* direct address */
  133. #define Db 26 /* byte displacement from EIP */
  134. #define Dl 27 /* long displacement from EIP */
  135. #define o1 28 /* constant 1 */
  136. #define o3 29 /* constant 3 */
  137. #define OS 30 /* immediate offset/segment */
  138. #define ST 31 /* FP stack top */
  139. #define STI 32 /* FP stack */
  140. #define X 33 /* extended FP op */
  141. #define XA 34 /* for 'fstcw %ax' */
  142. #define El 35 /* address, long/quad size */
  143. #define Ril 36 /* long register in instruction */
  144. #define Iba 37 /* byte immediate, don't print if 0xa */
  145. #define EL 38 /* address, explicitly long size */
  146. /* Wine extensions */
  147. #define MX 39 /* special register (MMX reg %mm0-7) */
  148. #define EMX 40 /* special register (MMX reg %mm0-7) */
  149. #define XMM 41 /* special register (floating point reg %xmm0-7) */
  150. #define EXMM 42 /* special register (floating point reg %xmm0-7) */
  151. struct inst {
  152. const char * i_name; /* name */
  153. short i_has_modrm; /* has regmodrm byte */
  154. short i_size; /* operand size */
  155. int i_mode; /* addressing modes */
  156. const void * i_extra; /* pointer to extra opcode table */
  157. };
  158. #define op1(x) (x)
  159. #define op2(x,y) ((x)|((y)<<8))
  160. #define op3(x,y,z) ((x)|((y)<<8)|((z)<<16))
  161. struct finst {
  162. const char * f_name; /* name for memory instruction */
  163. int f_size; /* size for memory instruction */
  164. int f_rrmode; /* mode for rr instruction */
  165. const void * f_rrname; /* name for rr instruction
  166. (or pointer to table) */
  167. };
  168. static const char * const db_Grp6[] = {
  169. "sldt",
  170. "str",
  171. "lldt",
  172. "ltr",
  173. "verr",
  174. "verw",
  175. "",
  176. ""
  177. };
  178. static const char * const db_Grp7[] = {
  179. "sgdt",
  180. "sidt",
  181. "lgdt",
  182. "lidt",
  183. "smsw",
  184. "",
  185. "lmsw",
  186. "invlpg"
  187. };
  188. static const char * const db_Grp8[] = {
  189. "",
  190. "",
  191. "",
  192. "",
  193. "bt",
  194. "bts",
  195. "btr",
  196. "btc"
  197. };
  198. static const char * const db_Grp9[] = {
  199. "",
  200. "cmpxchg8b",
  201. "",
  202. "",
  203. "",
  204. "",
  205. "",
  206. ""
  207. };
  208. static const char * const db_Grp15[] = {
  209. "fxsave",
  210. "fxrstor",
  211. "ldmxcsr",
  212. "stmxcsr",
  213. "",
  214. "",
  215. "",
  216. "clflush"
  217. };
  218. static const char * const db_Grp15b[] = {
  219. "",
  220. "",
  221. "",
  222. "",
  223. "",
  224. "lfence",
  225. "mfence",
  226. "sfence"
  227. };
  228. static const struct inst db_inst_0f0x[] = {
  229. /*00*/ { "", TRUE, NONE, op1(Ew), db_Grp6 },
  230. /*01*/ { "", TRUE, NONE, op1(Ew), db_Grp7 },
  231. /*02*/ { "lar", TRUE, LONG, op2(E,R), 0 },
  232. /*03*/ { "lsl", TRUE, LONG, op2(E,R), 0 },
  233. /*04*/ { "", FALSE, NONE, 0, 0 },
  234. /*05*/ { "syscall",FALSE,NONE, 0, 0 },
  235. /*06*/ { "clts", FALSE, NONE, 0, 0 },
  236. /*07*/ { "sysret",FALSE, NONE, 0, 0 },
  237. /*08*/ { "invd", FALSE, NONE, 0, 0 },
  238. /*09*/ { "wbinvd",FALSE, NONE, 0, 0 },
  239. /*0a*/ { "", FALSE, NONE, 0, 0 },
  240. /*0b*/ { "", FALSE, NONE, 0, 0 },
  241. /*0c*/ { "", FALSE, NONE, 0, 0 },
  242. /*0d*/ { "", FALSE, NONE, 0, 0 },
  243. /*0e*/ { "", FALSE, NONE, 0, 0 },
  244. /*0f*/ { "", FALSE, NONE, 0, 0 },
  245. };
  246. static const struct inst db_inst_0f1x[] = {
  247. /*10*/ { "movups",TRUE, NONE, op2(E, XMM), 0 },
  248. /*11*/ { "movups",TRUE, NONE, op2(XMM, E), 0 },
  249. /*12*/ { "", FALSE, NONE, 0, 0 },
  250. /*13*/ { "", FALSE, NONE, 0, 0 },
  251. /*14*/ { "", FALSE, NONE, 0, 0 },
  252. /*15*/ { "", FALSE, NONE, 0, 0 },
  253. /*16*/ { "", FALSE, NONE, 0, 0 },
  254. /*17*/ { "", FALSE, NONE, 0, 0 },
  255. /*18*/ { "", FALSE, NONE, 0, 0 },
  256. /*19*/ { "", FALSE, NONE, 0, 0 },
  257. /*1a*/ { "", FALSE, NONE, 0, 0 },
  258. /*1b*/ { "", FALSE, NONE, 0, 0 },
  259. /*1c*/ { "", FALSE, NONE, 0, 0 },
  260. /*1d*/ { "", FALSE, NONE, 0, 0 },
  261. /*1e*/ { "", FALSE, NONE, 0, 0 },
  262. /*1f*/ { "", FALSE, NONE, 0, 0 },
  263. };
  264. static const struct inst db_inst_0f2x[] = {
  265. /*20*/ { "mov", TRUE, LONG, op2(CR,El), 0 },
  266. /*21*/ { "mov", TRUE, LONG, op2(DR,El), 0 },
  267. /*22*/ { "mov", TRUE, LONG, op2(El,CR), 0 },
  268. /*23*/ { "mov", TRUE, LONG, op2(El,DR), 0 },
  269. /*24*/ { "mov", TRUE, LONG, op2(TR,El), 0 },
  270. /*25*/ { "", FALSE, NONE, 0, 0 },
  271. /*26*/ { "mov", TRUE, LONG, op2(El,TR), 0 },
  272. /*27*/ { "", FALSE, NONE, 0, 0 },
  273. /*28*/ { "movaps",TRUE, NONE, op2(E, XMM), 0 },
  274. /*29*/ { "movaps",TRUE, NONE, op2(XMM, E), 0 },
  275. /*2a*/ { "", FALSE, NONE, 0, 0 },
  276. /*2b*/ { "", FALSE, NONE, 0, 0 },
  277. /*2c*/ { "", FALSE, NONE, 0, 0 },
  278. /*2d*/ { "", FALSE, NONE, 0, 0 },
  279. /*2e*/ { "", FALSE, NONE, 0, 0 },
  280. /*2f*/ { "", FALSE, NONE, 0, 0 },
  281. };
  282. static const struct inst db_inst_0f3x[] = {
  283. /*30*/ { "wrmsr", FALSE, NONE, 0, 0 },
  284. /*31*/ { "rdtsc", FALSE, NONE, 0, 0 },
  285. /*32*/ { "rdmsr", FALSE, NONE, 0, 0 },
  286. /*33*/ { "rdpmc", FALSE, NONE, 0, 0 },
  287. /*34*/ { "sysenter",FALSE,NONE, 0, 0 },
  288. /*35*/ { "sysexit",FALSE,NONE, 0, 0 },
  289. /*36*/ { "", FALSE, NONE, 0, 0 },
  290. /*37*/ { "getsec",FALSE, NONE, 0, 0 },
  291. /*38*/ { "", FALSE, NONE, 0, 0 },
  292. /*39*/ { "", FALSE, NONE, 0, 0 },
  293. /*3a*/ { "", FALSE, NONE, 0, 0 },
  294. /*3b*/ { "", FALSE, NONE, 0, 0 },
  295. /*3c*/ { "", FALSE, NONE, 0, 0 },
  296. /*3d*/ { "", FALSE, NONE, 0, 0 },
  297. /*3e*/ { "", FALSE, NONE, 0, 0 },
  298. /*3f*/ { "", FALSE, NONE, 0, 0 },
  299. };
  300. static const struct inst db_inst_0f4x[] = {
  301. /*40*/ { "cmovo", TRUE, NONE, op2(E, R), 0 },
  302. /*41*/ { "cmovno", TRUE, NONE, op2(E, R), 0 },
  303. /*42*/ { "cmovb", TRUE, NONE, op2(E, R), 0 },
  304. /*43*/ { "cmovnb", TRUE, NONE, op2(E, R), 0 },
  305. /*44*/ { "cmovz", TRUE, NONE, op2(E, R), 0 },
  306. /*45*/ { "cmovnz", TRUE, NONE, op2(E, R), 0 },
  307. /*46*/ { "cmovbe", TRUE, NONE, op2(E, R), 0 },
  308. /*47*/ { "cmovnbe",TRUE, NONE, op2(E, R), 0 },
  309. /*48*/ { "cmovs", TRUE, NONE, op2(E, R), 0 },
  310. /*49*/ { "cmovns", TRUE, NONE, op2(E, R), 0 },
  311. /*4a*/ { "cmovp", TRUE, NONE, op2(E, R), 0 },
  312. /*4b*/ { "cmovnp", TRUE, NONE, op2(E, R), 0 },
  313. /*4c*/ { "cmovl", TRUE, NONE, op2(E, R), 0 },
  314. /*4d*/ { "cmovnl", TRUE, NONE, op2(E, R), 0 },
  315. /*4e*/ { "cmovle", TRUE, NONE, op2(E, R), 0 },
  316. /*4f*/ { "cmovnle",TRUE, NONE, op2(E, R), 0 },
  317. };
  318. static const struct inst db_inst_0f5x[] = {
  319. /*50*/ { "movmskps",TRUE, NONE, op2(EXMM, R), 0 },
  320. /*51*/ { "sqrtps", TRUE, NONE, op2(EXMM, XMM), 0 },
  321. /*52*/ { "rsqrtps", TRUE, NONE, op2(EXMM, XMM), 0 },
  322. /*53*/ { "rcpps", TRUE, NONE, op2(EXMM, XMM), 0 },
  323. /*54*/ { "andps", TRUE, NONE, op2(EXMM, XMM), 0 },
  324. /*55*/ { "andnps", TRUE, NONE, op2(EXMM, XMM), 0 },
  325. /*56*/ { "orps", TRUE, NONE, op2(EXMM, XMM), 0 },
  326. /*57*/ { "xorps", TRUE, NONE, op2(EXMM, XMM), 0 },
  327. /*58*/ { "addps", TRUE, NONE, op2(EXMM, XMM), 0 },
  328. /*59*/ { "mulps", TRUE, NONE, op2(EXMM, XMM), 0 },
  329. /*5a*/ { "cvtps2pd",TRUE, NONE, op2(EXMM, XMM), 0 },
  330. /*5b*/ { "cvtdq2ps",TRUE, NONE, op2(EXMM, XMM), 0 },
  331. /*5c*/ { "subps", TRUE, NONE, op2(EXMM, XMM), 0 },
  332. /*5d*/ { "minps", TRUE, NONE, op2(EXMM, XMM), 0 },
  333. /*5e*/ { "divps", TRUE, NONE, op2(EXMM, XMM), 0 },
  334. /*5f*/ { "maxps", TRUE, NONE, op2(EXMM, XMM), 0 },
  335. };
  336. static const struct inst db_inst_0f6x[] = {
  337. /*60*/ { "punpcklbw", TRUE, NONE, op2(E, MX), 0 },
  338. /*61*/ { "punpcklwd", TRUE, NONE, op2(E, MX), 0 },
  339. /*62*/ { "punpckldq", TRUE, NONE, op2(E, MX), 0 },
  340. /*63*/ { "packsswb", TRUE, NONE, op2(E, MX), 0 },
  341. /*64*/ { "pcmpgtb", TRUE, NONE, op2(E, MX), 0 },
  342. /*65*/ { "pcmpgtw", TRUE, NONE, op2(E, MX), 0 },
  343. /*66*/ { "pcmpgtd", TRUE, NONE, op2(E, MX), 0 },
  344. /*67*/ { "packuswb", TRUE, NONE, op2(E, MX), 0 },
  345. /*68*/ { "punpckhbw", TRUE, NONE, op2(E, MX), 0 },
  346. /*69*/ { "punpckhwd", TRUE, NONE, op2(E, MX), 0 },
  347. /*6a*/ { "punpckhdq", TRUE, NONE, op2(E, MX), 0 },
  348. /*6b*/ { "packssdw", TRUE, NONE, op2(E, MX), 0 },
  349. /*6c*/ { "(bad)", TRUE, NONE, 0, 0 },
  350. /*6d*/ { "(bad)", TRUE, NONE, 0, 0 },
  351. /*6e*/ { "movd", TRUE, NONE, op2(E, MX), 0 },
  352. /*6f*/ { "movq", TRUE, NONE, op2(E, MX), 0 },
  353. };
  354. static const struct inst db_inst_0f7x[] = {
  355. /*70*/ { "pshufw", TRUE, NONE, op2(MX, EMX), 0 },
  356. /*71*/ { "(bad)", TRUE, NONE, 0, 0 }, /* FIXME: grp 12 */
  357. /*72*/ { "(bad)", TRUE, NONE, 0, 0 }, /* FIXME: grp 13 */
  358. /*73*/ { "(bad)", TRUE, NONE, 0, 0 }, /* FIXME: grp 14 */
  359. /*74*/ { "pcmpeqb", TRUE, NONE, op2(E, MX), 0 },
  360. /*75*/ { "pcmpeqw", TRUE, NONE, op2(E, MX), 0 },
  361. /*76*/ { "pcmpeqd", TRUE, NONE, op2(E, MX), 0 },
  362. /*77*/ { "emms", FALSE,NONE, 0, 0 },
  363. /*78*/ { "(bad)", TRUE, NONE, 0, 0 },
  364. /*79*/ { "(bad)", TRUE, NONE, 0, 0 },
  365. /*7a*/ { "(bad)", TRUE, NONE, 0, 0 },
  366. /*7b*/ { "(bad)", TRUE, NONE, 0, 0 },
  367. /*7c*/ { "(bad)", TRUE, NONE, 0, 0 },
  368. /*7d*/ { "(bad)", TRUE, NONE, 0, 0 },
  369. /*7e*/ { "movd", TRUE, NONE, op2(E, MX), 0 },
  370. /*7f*/ { "movq", TRUE, NONE, op2(EMX, MX), 0 },
  371. };
  372. static const struct inst db_inst_0f8x[] = {
  373. /*80*/ { "jo", FALSE, NONE, op1(Dl), 0 },
  374. /*81*/ { "jno", FALSE, NONE, op1(Dl), 0 },
  375. /*82*/ { "jb", FALSE, NONE, op1(Dl), 0 },
  376. /*83*/ { "jnb", FALSE, NONE, op1(Dl), 0 },
  377. /*84*/ { "jz", FALSE, NONE, op1(Dl), 0 },
  378. /*85*/ { "jnz", FALSE, NONE, op1(Dl), 0 },
  379. /*86*/ { "jbe", FALSE, NONE, op1(Dl), 0 },
  380. /*87*/ { "jnbe", FALSE, NONE, op1(Dl), 0 },
  381. /*88*/ { "js", FALSE, NONE, op1(Dl), 0 },
  382. /*89*/ { "jns", FALSE, NONE, op1(Dl), 0 },
  383. /*8a*/ { "jp", FALSE, NONE, op1(Dl), 0 },
  384. /*8b*/ { "jnp", FALSE, NONE, op1(Dl), 0 },
  385. /*8c*/ { "jl", FALSE, NONE, op1(Dl), 0 },
  386. /*8d*/ { "jnl", FALSE, NONE, op1(Dl), 0 },
  387. /*8e*/ { "jle", FALSE, NONE, op1(Dl), 0 },
  388. /*8f*/ { "jnle", FALSE, NONE, op1(Dl), 0 },
  389. };
  390. static const struct inst db_inst_0f9x[] = {
  391. /*90*/ { "seto", TRUE, NONE, op1(Eb), 0 },
  392. /*91*/ { "setno", TRUE, NONE, op1(Eb), 0 },
  393. /*92*/ { "setb", TRUE, NONE, op1(Eb), 0 },
  394. /*93*/ { "setnb", TRUE, NONE, op1(Eb), 0 },
  395. /*94*/ { "setz", TRUE, NONE, op1(Eb), 0 },
  396. /*95*/ { "setnz", TRUE, NONE, op1(Eb), 0 },
  397. /*96*/ { "setbe", TRUE, NONE, op1(Eb), 0 },
  398. /*97*/ { "setnbe",TRUE, NONE, op1(Eb), 0 },
  399. /*98*/ { "sets", TRUE, NONE, op1(Eb), 0 },
  400. /*99*/ { "setns", TRUE, NONE, op1(Eb), 0 },
  401. /*9a*/ { "setp", TRUE, NONE, op1(Eb), 0 },
  402. /*9b*/ { "setnp", TRUE, NONE, op1(Eb), 0 },
  403. /*9c*/ { "setl", TRUE, NONE, op1(Eb), 0 },
  404. /*9d*/ { "setnl", TRUE, NONE, op1(Eb), 0 },
  405. /*9e*/ { "setle", TRUE, NONE, op1(Eb), 0 },
  406. /*9f*/ { "setnle",TRUE, NONE, op1(Eb), 0 },
  407. };
  408. static const struct inst db_inst_0fax[] = {
  409. /*a0*/ { "push", FALSE, NONE, op1(Si), 0 },
  410. /*a1*/ { "pop", FALSE, NONE, op1(Si), 0 },
  411. /*a2*/ { "cpuid", FALSE, NONE, 0, 0 },
  412. /*a3*/ { "bt", TRUE, LONG, op2(R,E), 0 },
  413. /*a4*/ { "shld", TRUE, LONG, op3(Ib,R,E), 0 },
  414. /*a5*/ { "shld", TRUE, LONG, op3(CL,R,E), 0 },
  415. /*a6*/ { "", FALSE, NONE, 0, 0 },
  416. /*a7*/ { "", FALSE, NONE, 0, 0 },
  417. /*a8*/ { "push", FALSE, NONE, op1(Si), 0 },
  418. /*a9*/ { "pop", FALSE, NONE, op1(Si), 0 },
  419. /*aa*/ { "rsm", FALSE, NONE, 0, 0 },
  420. /*ab*/ { "bts", TRUE, LONG, op2(R,E), 0 },
  421. /*ac*/ { "shrd", TRUE, LONG, op3(Ib,R,E), 0 },
  422. /*ad*/ { "shrd", TRUE, LONG, op3(CL,R,E), 0 },
  423. /*ae*/ { "", TRUE, LONG, op1(E), db_Grp15 },
  424. /*af*/ { "imul", TRUE, LONG, op2(E,R), 0 },
  425. };
  426. static const struct inst db_inst_0fbx[] = {
  427. /*b0*/ { "cmpxchg",TRUE, BYTE, op2(R, E), 0 },
  428. /*b0*/ { "cmpxchg",TRUE, LONG, op2(R, E), 0 },
  429. /*b2*/ { "lss", TRUE, LONG, op2(E, R), 0 },
  430. /*b3*/ { "btr", TRUE, LONG, op2(R, E), 0 },
  431. /*b4*/ { "lfs", TRUE, LONG, op2(E, R), 0 },
  432. /*b5*/ { "lgs", TRUE, LONG, op2(E, R), 0 },
  433. /*b6*/ { "movzb", TRUE, LONG, op2(Eb, R), 0 },
  434. /*b7*/ { "movzw", TRUE, LONG, op2(Ew, R), 0 },
  435. /*b8*/ { "", FALSE, NONE, 0, 0 },
  436. /*b9*/ { "", FALSE, NONE, 0, 0 },
  437. /*ba*/ { "", TRUE, LONG, op2(Ib, E), db_Grp8 },
  438. /*bb*/ { "btc", TRUE, LONG, op2(R, E), 0 },
  439. /*bc*/ { "bsf", TRUE, LONG, op2(E, R), 0 },
  440. /*bd*/ { "bsr", TRUE, LONG, op2(E, R), 0 },
  441. /*be*/ { "movsb", TRUE, LONG, op2(Eb, R), 0 },
  442. /*bf*/ { "movsw", TRUE, LONG, op2(Ew, R), 0 },
  443. };
  444. static const struct inst db_inst_0fcx[] = {
  445. /*c0*/ { "xadd", TRUE, BYTE, op2(R, E), 0 },
  446. /*c1*/ { "xadd", TRUE, LONG, op2(R, E), 0 },
  447. /*c2*/ { "", FALSE, NONE, 0, 0 },
  448. /*c3*/ { "", FALSE, NONE, 0, 0 },
  449. /*c4*/ { "", FALSE, NONE, 0, 0 },
  450. /*c5*/ { "", FALSE, NONE, 0, 0 },
  451. /*c6*/ { "", FALSE, NONE, 0, 0 },
  452. /*c7*/ { "", TRUE, NONE, op1(E), db_Grp9 },
  453. /*c8*/ { "bswap", FALSE, LONG, op1(Ril), 0 },
  454. /*c9*/ { "bswap", FALSE, LONG, op1(Ril), 0 },
  455. /*ca*/ { "bswap", FALSE, LONG, op1(Ril), 0 },
  456. /*cb*/ { "bswap", FALSE, LONG, op1(Ril), 0 },
  457. /*cc*/ { "bswap", FALSE, LONG, op1(Ril), 0 },
  458. /*cd*/ { "bswap", FALSE, LONG, op1(Ril), 0 },
  459. /*ce*/ { "bswap", FALSE, LONG, op1(Ril), 0 },
  460. /*cf*/ { "bswap", FALSE, LONG, op1(Ril), 0 },
  461. };
  462. static const struct inst * const db_inst_0f[] = {
  463. db_inst_0f0x,
  464. db_inst_0f1x,
  465. db_inst_0f2x,
  466. db_inst_0f3x,
  467. db_inst_0f4x,
  468. db_inst_0f5x,
  469. db_inst_0f6x,
  470. db_inst_0f7x,
  471. db_inst_0f8x,
  472. db_inst_0f9x,
  473. db_inst_0fax,
  474. db_inst_0fbx,
  475. db_inst_0fcx,
  476. 0,
  477. 0,
  478. 0
  479. };
  480. static const char * const db_Esc92[] = {
  481. "fnop", "", "", "", "", "", "", ""
  482. };
  483. static const char * const db_Esc94[] = {
  484. "fchs", "fabs", "", "", "ftst", "fxam", "", ""
  485. };
  486. static const char * const db_Esc95[] = {
  487. "fld1", "fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz",""
  488. };
  489. static const char * const db_Esc96[] = {
  490. "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp",
  491. "fincstp"
  492. };
  493. static const char * const db_Esc97[] = {
  494. "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"
  495. };
  496. static const char * const db_Esca5[] = {
  497. "", "fucompp","", "", "", "", "", ""
  498. };
  499. static const char * const db_Escb4[] = {
  500. "fneni","fndisi", "fnclex","fninit","fsetpm", "", "", ""
  501. };
  502. static const char * const db_Esce3[] = {
  503. "", "fcompp","", "", "", "", "", ""
  504. };
  505. static const char * const db_Escf4[] = {
  506. "fnstsw","", "", "", "", "", "", ""
  507. };
  508. static const struct finst db_Esc8[] = {
  509. /*0*/ { "fadd", SNGL, op2(STI,ST), 0 },
  510. /*1*/ { "fmul", SNGL, op2(STI,ST), 0 },
  511. /*2*/ { "fcom", SNGL, op2(STI,ST), 0 },
  512. /*3*/ { "fcomp", SNGL, op2(STI,ST), 0 },
  513. /*4*/ { "fsub", SNGL, op2(STI,ST), 0 },
  514. /*5*/ { "fsubr", SNGL, op2(STI,ST), 0 },
  515. /*6*/ { "fdiv", SNGL, op2(STI,ST), 0 },
  516. /*7*/ { "fdivr", SNGL, op2(STI,ST), 0 },
  517. };
  518. static const struct finst db_Esc9[] = {
  519. /*0*/ { "fld", SNGL, op1(STI), 0 },
  520. /*1*/ { "", NONE, op1(STI), "fxch" },
  521. /*2*/ { "fst", SNGL, op1(X), db_Esc92 },
  522. /*3*/ { "fstp", SNGL, 0, 0 },
  523. /*4*/ { "fldenv", NONE, op1(X), db_Esc94 },
  524. /*5*/ { "fldcw", NONE, op1(X), db_Esc95 },
  525. /*6*/ { "fnstenv",NONE, op1(X), db_Esc96 },
  526. /*7*/ { "fnstcw", NONE, op1(X), db_Esc97 },
  527. };
  528. static const struct finst db_Esca[] = {
  529. /*0*/ { "fiadd", LONG, 0, 0 },
  530. /*1*/ { "fimul", LONG, 0, 0 },
  531. /*2*/ { "ficom", LONG, 0, 0 },
  532. /*3*/ { "ficomp", LONG, 0, 0 },
  533. /*4*/ { "fisub", LONG, 0, 0 },
  534. /*5*/ { "fisubr", LONG, op1(X), db_Esca5 },
  535. /*6*/ { "fidiv", LONG, 0, 0 },
  536. /*7*/ { "fidivr", LONG, 0, 0 }
  537. };
  538. static const struct finst db_Escb[] = {
  539. /*0*/ { "fild", LONG, 0, 0 },
  540. /*1*/ { "", NONE, 0, 0 },
  541. /*2*/ { "fist", LONG, 0, 0 },
  542. /*3*/ { "fistp", LONG, 0, 0 },
  543. /*4*/ { "", WORD, op1(X), db_Escb4 },
  544. /*5*/ { "fld", EXTR, 0, 0 },
  545. /*6*/ { "", WORD, 0, 0 },
  546. /*7*/ { "fstp", EXTR, 0, 0 },
  547. };
  548. static const struct finst db_Escc[] = {
  549. /*0*/ { "fadd", DBLR, op2(ST,STI), 0 },
  550. /*1*/ { "fmul", DBLR, op2(ST,STI), 0 },
  551. /*2*/ { "fcom", DBLR, 0, 0 },
  552. /*3*/ { "fcomp", DBLR, 0, 0 },
  553. /*4*/ { "fsub", DBLR, op2(ST,STI), "fsubr" },
  554. /*5*/ { "fsubr", DBLR, op2(ST,STI), "fsub" },
  555. /*6*/ { "fdiv", DBLR, op2(ST,STI), "fdivr" },
  556. /*7*/ { "fdivr", DBLR, op2(ST,STI), "fdiv" },
  557. };
  558. static const struct finst db_Escd[] = {
  559. /*0*/ { "fld", DBLR, op1(STI), "ffree" },
  560. /*1*/ { "", NONE, 0, 0 },
  561. /*2*/ { "fst", DBLR, op1(STI), 0 },
  562. /*3*/ { "fstp", DBLR, op1(STI), 0 },
  563. /*4*/ { "frstor", NONE, op1(STI), "fucom" },
  564. /*5*/ { "", NONE, op1(STI), "fucomp" },
  565. /*6*/ { "fnsave", NONE, 0, 0 },
  566. /*7*/ { "fnstsw", NONE, 0, 0 },
  567. };
  568. static const struct finst db_Esce[] = {
  569. /*0*/ { "fiadd", WORD, op2(ST,STI), "faddp" },
  570. /*1*/ { "fimul", WORD, op2(ST,STI), "fmulp" },
  571. /*2*/ { "ficom", WORD, 0, 0 },
  572. /*3*/ { "ficomp", WORD, op1(X), db_Esce3 },
  573. /*4*/ { "fisub", WORD, op2(ST,STI), "fsubrp" },
  574. /*5*/ { "fisubr", WORD, op2(ST,STI), "fsubp" },
  575. /*6*/ { "fidiv", WORD, op2(ST,STI), "fdivrp" },
  576. /*7*/ { "fidivr", WORD, op2(ST,STI), "fdivp" },
  577. };
  578. static const struct finst db_Escf[] = {
  579. /*0*/ { "fild", WORD, 0, 0 },
  580. /*1*/ { "", NONE, 0, 0 },
  581. /*2*/ { "fist", WORD, 0, 0 },
  582. /*3*/ { "fistp", WORD, 0, 0 },
  583. /*4*/ { "fbld", NONE, op1(XA), db_Escf4 },
  584. /*5*/ { "fild", QUAD, 0, 0 },
  585. /*6*/ { "fbstp", NONE, 0, 0 },
  586. /*7*/ { "fistp", QUAD, 0, 0 },
  587. };
  588. static const struct finst * const db_Esc_inst[] = {
  589. db_Esc8, db_Esc9, db_Esca, db_Escb,
  590. db_Escc, db_Escd, db_Esce, db_Escf
  591. };
  592. static const char * const db_Grp1[] = {
  593. "add",
  594. "or",
  595. "adc",
  596. "sbb",
  597. "and",
  598. "sub",
  599. "xor",
  600. "cmp"
  601. };
  602. static const char * const db_Grp2[] = {
  603. "rol",
  604. "ror",
  605. "rcl",
  606. "rcr",
  607. "shl",
  608. "shr",
  609. "shl",
  610. "sar"
  611. };
  612. static const struct inst db_Grp3[] = {
  613. { "test", TRUE, NONE, op2(I,E), 0 },
  614. { "test", TRUE, NONE, op2(I,E), 0 },
  615. { "not", TRUE, NONE, op1(E), 0 },
  616. { "neg", TRUE, NONE, op1(E), 0 },
  617. { "mul", TRUE, NONE, op2(E,A), 0 },
  618. { "imul", TRUE, NONE, op2(E,A), 0 },
  619. { "div", TRUE, NONE, op2(E,A), 0 },
  620. { "idiv", TRUE, NONE, op2(E,A), 0 },
  621. };
  622. static const struct inst db_Grp4[] = {
  623. { "inc", TRUE, BYTE, op1(E), 0 },
  624. { "dec", TRUE, BYTE, op1(E), 0 },
  625. { "", TRUE, NONE, 0, 0 },
  626. { "", TRUE, NONE, 0, 0 },
  627. { "", TRUE, NONE, 0, 0 },
  628. { "", TRUE, NONE, 0, 0 },
  629. { "", TRUE, NONE, 0, 0 },
  630. { "", TRUE, NONE, 0, 0 }
  631. };
  632. static const struct inst db_Grp5[] = {
  633. { "inc", TRUE, LONG, op1(E), 0 },
  634. { "dec", TRUE, LONG, op1(E), 0 },
  635. { "call", TRUE, LONG, op1(Eind),0 },
  636. { "lcall", TRUE, LONG, op1(Eind),0 },
  637. { "jmp", TRUE, LONG, op1(Eind),0 },
  638. { "ljmp", TRUE, LONG, op1(Eind),0 },
  639. { "push", TRUE, LONG, op1(E), 0 },
  640. { "", TRUE, NONE, 0, 0 }
  641. };
  642. static const struct inst db_inst_table[256] = {
  643. /*00*/ { "add", TRUE, BYTE, op2(R, E), 0 },
  644. /*01*/ { "add", TRUE, LONG, op2(R, E), 0 },
  645. /*02*/ { "add", TRUE, BYTE, op2(E, R), 0 },
  646. /*03*/ { "add", TRUE, LONG, op2(E, R), 0 },
  647. /*04*/ { "add", FALSE, BYTE, op2(I, A), 0 },
  648. /*05*/ { "add", FALSE, LONG, op2(Is, A), 0 },
  649. /*06*/ { "push", FALSE, NONE, op1(Si), 0 },
  650. /*07*/ { "pop", FALSE, NONE, op1(Si), 0 },
  651. /*08*/ { "or", TRUE, BYTE, op2(R, E), 0 },
  652. /*09*/ { "or", TRUE, LONG, op2(R, E), 0 },
  653. /*0a*/ { "or", TRUE, BYTE, op2(E, R), 0 },
  654. /*0b*/ { "or", TRUE, LONG, op2(E, R), 0 },
  655. /*0c*/ { "or", FALSE, BYTE, op2(I, A), 0 },
  656. /*0d*/ { "or", FALSE, LONG, op2(I, A), 0 },
  657. /*0e*/ { "push", FALSE, NONE, op1(Si), 0 },
  658. /*0f*/ { "", FALSE, NONE, 0, 0 },
  659. /*10*/ { "adc", TRUE, BYTE, op2(R, E), 0 },
  660. /*11*/ { "adc", TRUE, LONG, op2(R, E), 0 },
  661. /*12*/ { "adc", TRUE, BYTE, op2(E, R), 0 },
  662. /*13*/ { "adc", TRUE, LONG, op2(E, R), 0 },
  663. /*14*/ { "adc", FALSE, BYTE, op2(I, A), 0 },
  664. /*15*/ { "adc", FALSE, LONG, op2(Is, A), 0 },
  665. /*16*/ { "push", FALSE, NONE, op1(Si), 0 },
  666. /*17*/ { "pop", FALSE, NONE, op1(Si), 0 },
  667. /*18*/ { "sbb", TRUE, BYTE, op2(R, E), 0 },
  668. /*19*/ { "sbb", TRUE, LONG, op2(R, E), 0 },
  669. /*1a*/ { "sbb", TRUE, BYTE, op2(E, R), 0 },
  670. /*1b*/ { "sbb", TRUE, LONG, op2(E, R), 0 },
  671. /*1c*/ { "sbb", FALSE, BYTE, op2(I, A), 0 },
  672. /*1d*/ { "sbb", FALSE, LONG, op2(Is, A), 0 },
  673. /*1e*/ { "push", FALSE, NONE, op1(Si), 0 },
  674. /*1f*/ { "pop", FALSE, NONE, op1(Si), 0 },
  675. /*20*/ { "and", TRUE, BYTE, op2(R, E), 0 },
  676. /*21*/ { "and", TRUE, LONG, op2(R, E), 0 },
  677. /*22*/ { "and", TRUE, BYTE, op2(E, R), 0 },
  678. /*23*/ { "and", TRUE, LONG, op2(E, R), 0 },
  679. /*24*/ { "and", FALSE, BYTE, op2(I, A), 0 },
  680. /*25*/ { "and", FALSE, LONG, op2(I, A), 0 },
  681. /*26*/ { "", FALSE, NONE, 0, 0 },
  682. /*27*/ { "daa", FALSE, NONE, 0, 0 },
  683. /*28*/ { "sub", TRUE, BYTE, op2(R, E), 0 },
  684. /*29*/ { "sub", TRUE, LONG, op2(R, E), 0 },
  685. /*2a*/ { "sub", TRUE, BYTE, op2(E, R), 0 },
  686. /*2b*/ { "sub", TRUE, LONG, op2(E, R), 0 },
  687. /*2c*/ { "sub", FALSE, BYTE, op2(I, A), 0 },
  688. /*2d*/ { "sub", FALSE, LONG, op2(Is, A), 0 },
  689. /*2e*/ { "", FALSE, NONE, 0, 0 },
  690. /*2f*/ { "das", FALSE, NONE, 0, 0 },
  691. /*30*/ { "xor", TRUE, BYTE, op2(R, E), 0 },
  692. /*31*/ { "xor", TRUE, LONG, op2(R, E), 0 },
  693. /*32*/ { "xor", TRUE, BYTE, op2(E, R), 0 },
  694. /*33*/ { "xor", TRUE, LONG, op2(E, R), 0 },
  695. /*34*/ { "xor", FALSE, BYTE, op2(I, A), 0 },
  696. /*35*/ { "xor", FALSE, LONG, op2(I, A), 0 },
  697. /*36*/ { "", FALSE, NONE, 0, 0 },
  698. /*37*/ { "aaa", FALSE, NONE, 0, 0 },
  699. /*38*/ { "cmp", TRUE, BYTE, op2(R, E), 0 },
  700. /*39*/ { "cmp", TRUE, LONG, op2(R, E), 0 },
  701. /*3a*/ { "cmp", TRUE, BYTE, op2(E, R), 0 },
  702. /*3b*/ { "cmp", TRUE, LONG, op2(E, R), 0 },
  703. /*3c*/ { "cmp", FALSE, BYTE, op2(I, A), 0 },
  704. /*3d*/ { "cmp", FALSE, LONG, op2(Is, A), 0 },
  705. /*3e*/ { "", FALSE, NONE, 0, 0 },
  706. /*3f*/ { "aas", FALSE, NONE, 0, 0 },
  707. /*40*/ { "rex", FALSE, NONE, 0, 0 },
  708. /*41*/ { "rex.b", FALSE, NONE, 0, 0 },
  709. /*42*/ { "rex.x", FALSE, NONE, 0, 0 },
  710. /*43*/ { "rex.xb", FALSE, NONE, 0, 0 },
  711. /*44*/ { "rex.r", FALSE, NONE, 0, 0 },
  712. /*45*/ { "rex.rb", FALSE, NONE, 0, 0 },
  713. /*46*/ { "rex.rx", FALSE, NONE, 0, 0 },
  714. /*47*/ { "rex.rxb", FALSE, NONE, 0, 0 },
  715. /*48*/ { "rex.w", FALSE, NONE, 0, 0 },
  716. /*49*/ { "rex.wb", FALSE, NONE, 0, 0 },
  717. /*4a*/ { "rex.wx", FALSE, NONE, 0, 0 },
  718. /*4b*/ { "rex.wxb", FALSE, NONE, 0, 0 },
  719. /*4c*/ { "rex.wr", FALSE, NONE, 0, 0 },
  720. /*4d*/ { "rex.wrb", FALSE, NONE, 0, 0 },
  721. /*4e*/ { "rex.wrx", FALSE, NONE, 0, 0 },
  722. /*4f*/ { "rex.wrxb", FALSE, NONE, 0, 0 },
  723. /*50*/ { "push", FALSE, LONG, op1(Ri), 0 },
  724. /*51*/ { "push", FALSE, LONG, op1(Ri), 0 },
  725. /*52*/ { "push", FALSE, LONG, op1(Ri), 0 },
  726. /*53*/ { "push", FALSE, LONG, op1(Ri), 0 },
  727. /*54*/ { "push", FALSE, LONG, op1(Ri), 0 },
  728. /*55*/ { "push", FALSE, LONG, op1(Ri), 0 },
  729. /*56*/ { "push", FALSE, LONG, op1(Ri), 0 },
  730. /*57*/ { "push", FALSE, LONG, op1(Ri), 0 },
  731. /*58*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  732. /*59*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  733. /*5a*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  734. /*5b*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  735. /*5c*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  736. /*5d*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  737. /*5e*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  738. /*5f*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  739. /*60*/ { "pusha", FALSE, LONG, 0, 0 },
  740. /*61*/ { "popa", FALSE, LONG, 0, 0 },
  741. /*62*/ { "bound", TRUE, LONG, op2(E, R), 0 },
  742. /*63*/ { "movslq", TRUE, NONE, op2(EL,R), 0 },
  743. /*64*/ { "", FALSE, NONE, 0, 0 },
  744. /*65*/ { "", FALSE, NONE, 0, 0 },
  745. /*66*/ { "", FALSE, NONE, 0, 0 },
  746. /*67*/ { "", FALSE, NONE, 0, 0 },
  747. /*68*/ { "push", FALSE, LONG, op1(I), 0 },
  748. /*69*/ { "imul", TRUE, LONG, op3(I,E,R), 0 },
  749. /*6a*/ { "push", FALSE, LONG, op1(Ibs), 0 },
  750. /*6b*/ { "imul", TRUE, LONG, op3(Ibs,E,R),0 },
  751. /*6c*/ { "ins", FALSE, BYTE, op2(DX, DI), 0 },
  752. /*6d*/ { "ins", FALSE, LONG, op2(DX, DI), 0 },
  753. /*6e*/ { "outs", FALSE, BYTE, op2(SI, DX), 0 },
  754. /*6f*/ { "outs", FALSE, LONG, op2(SI, DX), 0 },
  755. /*70*/ { "jo", FALSE, NONE, op1(Db), 0 },
  756. /*71*/ { "jno", FALSE, NONE, op1(Db), 0 },
  757. /*72*/ { "jb", FALSE, NONE, op1(Db), 0 },
  758. /*73*/ { "jnb", FALSE, NONE, op1(Db), 0 },
  759. /*74*/ { "jz", FALSE, NONE, op1(Db), 0 },
  760. /*75*/ { "jnz", FALSE, NONE, op1(Db), 0 },
  761. /*76*/ { "jbe", FALSE, NONE, op1(Db), 0 },
  762. /*77*/ { "jnbe", FALSE, NONE, op1(Db), 0 },
  763. /*78*/ { "js", FALSE, NONE, op1(Db), 0 },
  764. /*79*/ { "jns", FALSE, NONE, op1(Db), 0 },
  765. /*7a*/ { "jp", FALSE, NONE, op1(Db), 0 },
  766. /*7b*/ { "jnp", FALSE, NONE, op1(Db), 0 },
  767. /*7c*/ { "jl", FALSE, NONE, op1(Db), 0 },
  768. /*7d*/ { "jnl", FALSE, NONE, op1(Db), 0 },
  769. /*7e*/ { "jle", FALSE, NONE, op1(Db), 0 },
  770. /*7f*/ { "jnle", FALSE, NONE, op1(Db), 0 },
  771. /*80*/ { "", TRUE, BYTE, op2(I, E), db_Grp1 },
  772. /*81*/ { "", TRUE, LONG, op2(I, E), db_Grp1 },
  773. /*82*/ { "", TRUE, BYTE, op2(I, E), db_Grp1 },
  774. /*83*/ { "", TRUE, LONG, op2(Ibs,E), db_Grp1 },
  775. /*84*/ { "test", TRUE, BYTE, op2(R, E), 0 },
  776. /*85*/ { "test", TRUE, LONG, op2(R, E), 0 },
  777. /*86*/ { "xchg", TRUE, BYTE, op2(R, E), 0 },
  778. /*87*/ { "xchg", TRUE, LONG, op2(R, E), 0 },
  779. /*88*/ { "mov", TRUE, BYTE, op2(R, E), 0 },
  780. /*89*/ { "mov", TRUE, LONG, op2(R, E), 0 },
  781. /*8a*/ { "mov", TRUE, BYTE, op2(E, R), 0 },
  782. /*8b*/ { "mov", TRUE, LONG, op2(E, R), 0 },
  783. /*8c*/ { "mov", TRUE, NONE, op2(S, Ew), 0 },
  784. /*8d*/ { "lea", TRUE, LONG, op2(E, R), 0 },
  785. /*8e*/ { "mov", TRUE, NONE, op2(Ew, S), 0 },
  786. /*8f*/ { "pop", TRUE, LONG, op1(E), 0 },
  787. /*90*/ { "nop", FALSE, NONE, 0, 0 },
  788. /*91*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
  789. /*92*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
  790. /*93*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
  791. /*94*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
  792. /*95*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
  793. /*96*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
  794. /*97*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
  795. /*98*/ { "cbw", FALSE, SDEP, 0, "cwde" }, /* cbw/cwde */
  796. /*99*/ { "cwd", FALSE, SDEP, 0, "cdq" }, /* cwd/cdq */
  797. /*9a*/ { "lcall", FALSE, NONE, op1(OS), 0 },
  798. /*9b*/ { "wait", FALSE, NONE, 0, 0 },
  799. /*9c*/ { "pushf", FALSE, LONG, 0, 0 },
  800. /*9d*/ { "popf", FALSE, LONG, 0, 0 },
  801. /*9e*/ { "sahf", FALSE, NONE, 0, 0 },
  802. /*9f*/ { "lahf", FALSE, NONE, 0, 0 },
  803. /*a0*/ { "mov", FALSE, BYTE, op2(O, A), 0 },
  804. /*a1*/ { "mov", FALSE, LONG, op2(O, A), 0 },
  805. /*a2*/ { "mov", FALSE, BYTE, op2(A, O), 0 },
  806. /*a3*/ { "mov", FALSE, LONG, op2(A, O), 0 },
  807. /*a4*/ { "movs", FALSE, BYTE, op2(SI,DI), 0 },
  808. /*a5*/ { "movs", FALSE, LONG, op2(SI,DI), 0 },
  809. /*a6*/ { "cmps", FALSE, BYTE, op2(SI,DI), 0 },
  810. /*a7*/ { "cmps", FALSE, LONG, op2(SI,DI), 0 },
  811. /*a8*/ { "test", FALSE, BYTE, op2(I, A), 0 },
  812. /*a9*/ { "test", FALSE, LONG, op2(I, A), 0 },
  813. /*aa*/ { "stos", FALSE, BYTE, op1(DI), 0 },
  814. /*ab*/ { "stos", FALSE, LONG, op1(DI), 0 },
  815. /*ac*/ { "lods", FALSE, BYTE, op1(SI), 0 },
  816. /*ad*/ { "lods", FALSE, LONG, op1(SI), 0 },
  817. /*ae*/ { "scas", FALSE, BYTE, op1(SI), 0 },
  818. /*af*/ { "scas", FALSE, LONG, op1(SI), 0 },
  819. /*b0*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  820. /*b1*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  821. /*b2*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  822. /*b3*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  823. /*b4*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  824. /*b5*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  825. /*b6*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  826. /*b7*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  827. /*b8*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
  828. /*b9*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
  829. /*ba*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
  830. /*bb*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
  831. /*bc*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
  832. /*bd*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
  833. /*be*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
  834. /*bf*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
  835. /*c0*/ { "", TRUE, BYTE, op2(Ib, E), db_Grp2 },
  836. /*c1*/ { "", TRUE, LONG, op2(Ib, E), db_Grp2 },
  837. /*c2*/ { "ret", FALSE, NONE, op1(Iw), 0 },
  838. /*c3*/ { "ret", FALSE, NONE, 0, 0 },
  839. /*c4*/ { "les", TRUE, LONG, op2(E, R), 0 },
  840. /*c5*/ { "lds", TRUE, LONG, op2(E, R), 0 },
  841. /*c6*/ { "mov", TRUE, BYTE, op2(I, E), 0 },
  842. /*c7*/ { "mov", TRUE, LONG, op2(I, E), 0 },
  843. /*c8*/ { "enter", FALSE, NONE, op2(Iw, Ib), 0 },
  844. /*c9*/ { "leave", FALSE, NONE, 0, 0 },
  845. /*ca*/ { "lret", FALSE, NONE, op1(Iw), 0 },
  846. /*cb*/ { "lret", FALSE, NONE, 0, 0 },
  847. /*cc*/ { "int", FALSE, NONE, op1(o3), 0 },
  848. /*cd*/ { "int", FALSE, NONE, op1(Ib), 0 },
  849. /*ce*/ { "into", FALSE, NONE, 0, 0 },
  850. /*cf*/ { "iret", FALSE, NONE, 0, 0 },
  851. /*d0*/ { "", TRUE, BYTE, op2(o1, E), db_Grp2 },
  852. /*d1*/ { "", TRUE, LONG, op2(o1, E), db_Grp2 },
  853. /*d2*/ { "", TRUE, BYTE, op2(CL, E), db_Grp2 },
  854. /*d3*/ { "", TRUE, LONG, op2(CL, E), db_Grp2 },
  855. /*d4*/ { "aam", FALSE, NONE, op1(Iba), 0 },
  856. /*d5*/ { "aad", FALSE, NONE, op1(Iba), 0 },
  857. /*d6*/ { ".byte\t0xd6", FALSE, NONE, 0, 0 },
  858. /*d7*/ { "xlat", FALSE, BYTE, op1(BX), 0 },
  859. /*d8*/ { "", TRUE, NONE, 0, db_Esc8 },
  860. /*d9*/ { "", TRUE, NONE, 0, db_Esc9 },
  861. /*da*/ { "", TRUE, NONE, 0, db_Esca },
  862. /*db*/ { "", TRUE, NONE, 0, db_Escb },
  863. /*dc*/ { "", TRUE, NONE, 0, db_Escc },
  864. /*dd*/ { "", TRUE, NONE, 0, db_Escd },
  865. /*de*/ { "", TRUE, NONE, 0, db_Esce },
  866. /*df*/ { "", TRUE, NONE, 0, db_Escf },
  867. /*e0*/ { "loopne",FALSE, NONE, op1(Db), 0 },
  868. /*e1*/ { "loope", FALSE, NONE, op1(Db), 0 },
  869. /*e2*/ { "loop", FALSE, NONE, op1(Db), 0 },
  870. /*e3*/ { "jcxz", FALSE, SDEP, op1(Db), "jecxz" },
  871. /*e4*/ { "in", FALSE, BYTE, op2(Ib, A), 0 },
  872. /*e5*/ { "in", FALSE, LONG, op2(Ib, A) , 0 },
  873. /*e6*/ { "out", FALSE, BYTE, op2(A, Ib), 0 },
  874. /*e7*/ { "out", FALSE, LONG, op2(A, Ib) , 0 },
  875. /*e8*/ { "call", FALSE, NONE, op1(Dl), 0 },
  876. /*e9*/ { "jmp", FALSE, NONE, op1(Dl), 0 },
  877. /*ea*/ { "ljmp", FALSE, NONE, op1(OS), 0 },
  878. /*eb*/ { "jmp", FALSE, NONE, op1(Db), 0 },
  879. /*ec*/ { "in", FALSE, BYTE, op2(DX, A), 0 },
  880. /*ed*/ { "in", FALSE, LONG, op2(DX, A) , 0 },
  881. /*ee*/ { "out", FALSE, BYTE, op2(A, DX), 0 },
  882. /*ef*/ { "out", FALSE, LONG, op2(A, DX) , 0 },
  883. /*f0*/ { "", FALSE, NONE, 0, 0 },
  884. /*f1*/ { ".byte\t0xf1", FALSE, NONE, 0, 0 },
  885. /*f2*/ { "", FALSE, NONE, 0, 0 },
  886. /*f3*/ { "", FALSE, NONE, 0, 0 },
  887. /*f4*/ { "hlt", FALSE, NONE, 0, 0 },
  888. /*f5*/ { "cmc", FALSE, NONE, 0, 0 },
  889. /*f6*/ { "", TRUE, BYTE, 0, db_Grp3 },
  890. /*f7*/ { "", TRUE, LONG, 0, db_Grp3 },
  891. /*f8*/ { "clc", FALSE, NONE, 0, 0 },
  892. /*f9*/ { "stc", FALSE, NONE, 0, 0 },
  893. /*fa*/ { "cli", FALSE, NONE, 0, 0 },
  894. /*fb*/ { "sti", FALSE, NONE, 0, 0 },
  895. /*fc*/ { "cld", FALSE, NONE, 0, 0 },
  896. /*fd*/ { "std", FALSE, NONE, 0, 0 },
  897. /*fe*/ { "", TRUE, NONE, 0, db_Grp4 },
  898. /*ff*/ { "", TRUE, NONE, 0, db_Grp5 },
  899. };
  900. static const struct inst db_bad_inst =
  901. { "???", FALSE, NONE, 0, 0 }
  902. ;
  903. #define f_mod(rex, byte) ((byte)>>6)
  904. #define f_reg(rex, byte) ((((byte)>>3)&0x7) | (rex & REX_R ? 0x8 : 0x0))
  905. #define f_rm(rex, byte) (((byte)&0x7) | (rex & REX_B ? 0x8 : 0x0))
  906. #define sib_ss(rex, byte) ((byte)>>6)
  907. #define sib_index(rex, byte) ((((byte)>>3)&0x7) | (rex & REX_X ? 0x8 : 0x0))
  908. #define sib_base(rex, byte) (((byte)&0x7) | (rex & REX_B ? 0x8 : 0x0))
  909. struct i_addr {
  910. int is_reg; /* if reg, reg number is in 'disp' */
  911. int disp;
  912. const char * base;
  913. const char * index;
  914. int ss;
  915. };
  916. static const char * const db_reg[2][4][16] = {
  917. {{"%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
  918. "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b" },
  919. { "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
  920. "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w" },
  921. { "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
  922. "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d" },
  923. { "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
  924. "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" }},
  925. {{"%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
  926. "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b" },
  927. { "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
  928. "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w" },
  929. { "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
  930. "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d" },
  931. { "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
  932. "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" }}
  933. };
  934. static const char * const db_seg_reg[8] = {
  935. "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "", ""
  936. };
  937. /*
  938. * lengths for size attributes
  939. */
  940. static const int db_lengths[] = {
  941. 1, /* BYTE */
  942. 2, /* WORD */
  943. 4, /* LONG */
  944. 8, /* QUAD */
  945. 4, /* SNGL */
  946. 8, /* DBLR */
  947. 10, /* EXTR */
  948. };
  949. #define get_value_inc(result, loc, size, is_signed) \
  950. result = db_get_value((loc), (size), (is_signed)); \
  951. (loc) += (size);
  952. static db_addr_t
  953. db_disasm_esc(db_addr_t loc, int inst, int rex, int short_addr,
  954. int size, const char *seg);
  955. static void db_print_address(const char *seg, int size, int rex,
  956. struct i_addr *addrp);
  957. static db_addr_t
  958. db_read_address(db_addr_t loc, int short_addr, int rex, int regmodrm,
  959. struct i_addr *addrp);
  960. /*
  961. * Read address at location and return updated location.
  962. */
  963. static db_addr_t
  964. db_read_address(loc, short_addr, rex, regmodrm, addrp)
  965. db_addr_t loc;
  966. int short_addr;
  967. int rex;
  968. int regmodrm;
  969. struct i_addr * addrp; /* out */
  970. {
  971. int mod, rm, sib, index, disp, size, have_sib;
  972. mod = f_mod(rex, regmodrm);
  973. rm = f_rm(rex, regmodrm);
  974. if (mod == 3) {
  975. addrp->is_reg = TRUE;
  976. addrp->disp = rm;
  977. return (loc);
  978. }
  979. addrp->is_reg = FALSE;
  980. addrp->index = 0;
  981. if (short_addr)
  982. size = LONG;
  983. else
  984. size = QUAD;
  985. if ((rm & 0x7) == 4) {
  986. get_value_inc(sib, loc, 1, FALSE);
  987. rm = sib_base(rex, sib);
  988. index = sib_index(rex, sib);
  989. if (index != 4)
  990. addrp->index = db_reg[1][size][index];
  991. addrp->ss = sib_ss(rex, sib);
  992. have_sib = 1;
  993. } else
  994. have_sib = 0;
  995. switch (mod) {
  996. case 0:
  997. if (rm == 5) {
  998. get_value_inc(addrp->disp, loc, 4, FALSE);
  999. if (have_sib)
  1000. addrp->base = 0;
  1001. else if (short_addr)
  1002. addrp->base = "%eip";
  1003. else
  1004. addrp->base = "%rip";
  1005. } else {
  1006. addrp->disp = 0;
  1007. addrp->base = db_reg[1][size][rm];
  1008. }
  1009. break;
  1010. case 1:
  1011. get_value_inc(disp, loc, 1, TRUE);
  1012. addrp->disp = disp;
  1013. addrp->base = db_reg[1][size][rm];
  1014. break;
  1015. case 2:
  1016. get_value_inc(disp, loc, 4, FALSE);
  1017. addrp->disp = disp;
  1018. addrp->base = db_reg[1][size][rm];
  1019. break;
  1020. }
  1021. return (loc);
  1022. }
  1023. static void
  1024. db_print_address(seg, size, rex, addrp)
  1025. const char * seg;
  1026. int size;
  1027. int rex;
  1028. struct i_addr * addrp;
  1029. {
  1030. if (addrp->is_reg) {
  1031. db_printf("%s", db_reg[rex != 0 ? 1 : 0][(size == LONG && (rex & REX_W)) ? QUAD : size][addrp->disp]);
  1032. return;
  1033. }
  1034. if (seg) {
  1035. db_printf("%s:", seg);
  1036. }
  1037. if (addrp->disp != 0 || (addrp->base == 0 && addrp->index == 0))
  1038. db_printsym((db_addr_t)addrp->disp, DB_STGY_ANY);
  1039. if (addrp->base != 0 || addrp->index != 0) {
  1040. db_printf("(");
  1041. if (addrp->base)
  1042. db_printf("%s", addrp->base);
  1043. if (addrp->index)
  1044. db_printf(",%s,%d", addrp->index, 1<<addrp->ss);
  1045. db_printf(")");
  1046. }
  1047. }
  1048. /*
  1049. * Disassemble floating-point ("escape") instruction
  1050. * and return updated location.
  1051. */
  1052. static db_addr_t
  1053. db_disasm_esc(loc, inst, rex, short_addr, size, seg)
  1054. db_addr_t loc;
  1055. int inst;
  1056. int rex;
  1057. int short_addr;
  1058. int size;
  1059. const char * seg;
  1060. {
  1061. int regmodrm;
  1062. const struct finst * fp;
  1063. int mod;
  1064. struct i_addr address;
  1065. const char * name;
  1066. get_value_inc(regmodrm, loc, 1, FALSE);
  1067. fp = &db_Esc_inst[inst - 0xd8][f_reg(rex, regmodrm)];
  1068. mod = f_mod(rex, regmodrm);
  1069. if (mod != 3) {
  1070. if (*fp->f_name == '\0') {
  1071. db_printf("<bad instruction>");
  1072. return (loc);
  1073. }
  1074. /*
  1075. * Normal address modes.
  1076. */
  1077. loc = db_read_address(loc, short_addr, rex, regmodrm, &address);
  1078. db_printf("%s", fp->f_name);
  1079. switch(fp->f_size) {
  1080. case SNGL:
  1081. db_printf("s");
  1082. break;
  1083. case DBLR:
  1084. db_printf("l");
  1085. break;
  1086. case EXTR:
  1087. db_printf("t");
  1088. break;
  1089. case WORD:
  1090. db_printf("s");
  1091. break;
  1092. case LONG:
  1093. db_printf("l");
  1094. break;
  1095. case QUAD:
  1096. db_printf("q");
  1097. break;
  1098. default:
  1099. break;
  1100. }
  1101. db_printf("\t");
  1102. db_print_address(seg, BYTE, rex, &address);
  1103. }
  1104. else {
  1105. /*
  1106. * 'reg-reg' - special formats
  1107. */
  1108. switch (fp->f_rrmode) {
  1109. case op2(ST,STI):
  1110. name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
  1111. db_printf("%s\t%%st,%%st(%d)",name,f_rm(rex, regmodrm));
  1112. break;
  1113. case op2(STI,ST):
  1114. name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
  1115. db_printf("%s\t%%st(%d),%%st",name, f_rm(rex, regmodrm));
  1116. break;
  1117. case op1(STI):
  1118. name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
  1119. db_printf("%s\t%%st(%d)",name, f_rm(rex, regmodrm));
  1120. break;
  1121. case op1(X):
  1122. name = ((const char * const *)fp->f_rrname)[f_rm(rex, regmodrm)];
  1123. if (*name == '\0')
  1124. goto bad;
  1125. db_printf("%s", name);
  1126. break;
  1127. case op1(XA):
  1128. name = ((const char * const *)fp->f_rrname)[f_rm(rex, regmodrm)];
  1129. if (*name == '\0')
  1130. goto bad;
  1131. db_printf("%s\t%%ax", name);
  1132. break;
  1133. default:
  1134. bad:
  1135. db_printf("<bad instruction>");
  1136. break;
  1137. }
  1138. }
  1139. return (loc);
  1140. }
  1141. /*
  1142. * Disassemble instruction at 'loc'. 'altfmt' specifies an
  1143. * (optional) alternate format. Return address of start of
  1144. * next instruction.
  1145. */
  1146. static db_addr_t
  1147. db_disasm(db_addr_t loc, boolean_t altfmt)
  1148. {
  1149. int inst;
  1150. int size;
  1151. int short_addr;
  1152. const char * seg;
  1153. const struct inst * ip;
  1154. const char * i_name;
  1155. int i_size;
  1156. int i_mode;
  1157. int rex = 0;
  1158. int regmodrm = 0;
  1159. boolean_t first;
  1160. int displ;
  1161. int prefix;
  1162. int rep;
  1163. int imm;
  1164. int imm2;
  1165. LONG64 imm64;
  1166. int len;
  1167. struct i_addr address;
  1168. db_addr_t addr;
  1169. get_value_inc(inst, loc, 1, FALSE);
  1170. short_addr = FALSE;
  1171. size = LONG;
  1172. seg = 0;
  1173. /*
  1174. * Get prefixes
  1175. */
  1176. rep = FALSE;
  1177. prefix = TRUE;
  1178. do {
  1179. switch (inst) {
  1180. case 0x66: /* data16 */
  1181. size = WORD;
  1182. break;
  1183. case 0x67:
  1184. short_addr = TRUE;
  1185. break;
  1186. case 0x26:
  1187. seg = "%es";
  1188. break;
  1189. case 0x36:
  1190. seg = "%ss";
  1191. break;
  1192. case 0x2e:
  1193. seg = "%cs";
  1194. break;
  1195. case 0x3e:
  1196. seg = "%ds";
  1197. break;
  1198. case 0x64:
  1199. seg = "%fs";
  1200. break;
  1201. case 0x65:
  1202. seg = "%gs";
  1203. break;
  1204. case 0xf0:
  1205. db_printf("lock ");
  1206. break;
  1207. case 0xf2:
  1208. db_printf("repne ");
  1209. break;
  1210. case 0xf3:
  1211. rep = TRUE;
  1212. break;
  1213. default:
  1214. prefix = FALSE;
  1215. break;
  1216. }
  1217. if (inst >= 0x40 && inst < 0x50) {
  1218. rex = inst;
  1219. prefix = TRUE;
  1220. }
  1221. if (prefix) {
  1222. get_value_inc(inst, loc, 1, FALSE);
  1223. }
  1224. if (rep == TRUE) {
  1225. if (inst == 0x90) {
  1226. db_printf("pause\n");
  1227. return (loc);
  1228. }
  1229. db_printf("repe "); /* XXX repe VS rep */
  1230. rep = FALSE;
  1231. }
  1232. } while (prefix);
  1233. if (inst >= 0xd8 && inst <= 0xdf) {
  1234. loc = db_disasm_esc(loc, inst, rex, short_addr, size, seg);
  1235. db_printf("\n");
  1236. return (loc);
  1237. }
  1238. if (inst == 0x0f) {
  1239. get_value_inc(inst, loc, 1, FALSE);
  1240. ip = db_inst_0f[inst>>4];
  1241. if (ip == 0) {
  1242. ip = &db_bad_inst;
  1243. }
  1244. else {
  1245. ip = &ip[inst&0xf];
  1246. }
  1247. }
  1248. else
  1249. ip = &db_inst_table[inst];
  1250. if (ip->i_has_modrm) {
  1251. get_value_inc(regmodrm, loc, 1, FALSE);
  1252. loc = db_read_address(loc, short_addr, rex, regmodrm, &address);
  1253. }
  1254. i_name = ip->i_name;
  1255. i_size = ip->i_size;
  1256. i_mode = ip->i_mode;
  1257. if (ip->i_extra == db_Grp1 || ip->i_extra == db_Grp2 ||
  1258. ip->i_extra == db_Grp6 || ip->i_extra == db_Grp7 ||
  1259. ip->i_extra == db_Grp8 || ip->i_extra == db_Grp9 ||
  1260. ip->i_extra == db_Grp15) {
  1261. i_name = ((const char * const *)ip->i_extra)[f_reg(rex, regmodrm)];
  1262. }
  1263. else if (ip->i_extra == db_Grp3) {
  1264. ip = ip->i_extra;
  1265. ip = &ip[f_reg(rex, regmodrm)];
  1266. i_name = ip->i_name;
  1267. i_mode = ip->i_mode;
  1268. }
  1269. else if (ip->i_extra == db_Grp4 || ip->i_extra == db_Grp5) {
  1270. ip = ip->i_extra;
  1271. ip = &ip[f_reg(rex, regmodrm)];
  1272. i_name = ip->i_name;
  1273. i_mode = ip->i_mode;
  1274. i_size = ip->i_size;
  1275. }
  1276. /* Special cases that don't fit well in the tables. */
  1277. if (ip->i_extra == db_Grp7 && f_mod(rex, regmodrm) == 3) {
  1278. switch (regmodrm) {
  1279. case 0xc8:
  1280. i_name = "monitor";
  1281. i_size = NONE;
  1282. i_mode = 0;
  1283. break;
  1284. case 0xc9:
  1285. i_name = "mwait";
  1286. i_size = NONE;
  1287. i_mode = 0;
  1288. break;
  1289. case 0xf8:
  1290. i_name = "swapgs";
  1291. i_size = NONE;
  1292. i_mode = 0;
  1293. break;
  1294. }
  1295. }
  1296. if (ip->i_extra == db_Grp15 && f_mod(0, regmodrm) == 3) {
  1297. i_name = db_Grp15b[f_reg(0, regmodrm)];
  1298. i_size = NONE;
  1299. i_mode = 0;
  1300. }
  1301. if (i_size == SDEP) {
  1302. if (size == WORD)
  1303. db_printf("%s", i_name);
  1304. else
  1305. db_printf("%s", (const char *)ip->i_extra);
  1306. }
  1307. else {
  1308. db_printf("%s", i_name);
  1309. if ((inst >= 0x50 && inst <= 0x5f) || inst == 0x68 || inst == 0x6a) {
  1310. i_size = NONE;
  1311. db_printf("q");
  1312. }
  1313. if (i_size != NONE) {
  1314. if (i_size == BYTE) {
  1315. db_printf("b");
  1316. size = BYTE;
  1317. }
  1318. else if (i_size == WORD) {
  1319. db_printf("w");
  1320. size = WORD;
  1321. }
  1322. else if (size == WORD)
  1323. db_printf("w");
  1324. else {
  1325. if (rex & REX_W)
  1326. db_printf("q");
  1327. else
  1328. db_printf("l");
  1329. }
  1330. }
  1331. }
  1332. db_printf("\t");
  1333. for (first = TRUE;
  1334. i_mode != 0;
  1335. i_mode >>= 8, first = FALSE)
  1336. {
  1337. if (!first)
  1338. db_printf(",");
  1339. switch (i_mode & 0xFF) {
  1340. case E:
  1341. db_print_address(seg, size, rex, &address);
  1342. break;
  1343. case Eind:
  1344. db_printf("*");
  1345. db_print_address(seg, size, rex, &address);
  1346. break;
  1347. case El:
  1348. db_print_address(seg, (rex & REX_W) ? QUAD : LONG, rex, &address);
  1349. break;
  1350. case EL:
  1351. db_print_address(seg, LONG, 0, &address);
  1352. break;
  1353. case Ew:
  1354. db_print_address(seg, WORD, rex, &address);
  1355. break;
  1356. case Eb:
  1357. db_print_address(seg, BYTE, rex, &address);
  1358. break;
  1359. case R:
  1360. db_printf("%s", db_reg[rex != 0 ? 1 : 0][(size == LONG && (rex & REX_W)) ? QUAD : size][f_reg(rex, regmodrm)]);
  1361. break;
  1362. case Rw:
  1363. db_printf("%s", db_reg[rex != 0 ? 1 : 0][WORD][f_reg(rex, regmodrm)]);
  1364. break;
  1365. case Ri:
  1366. db_printf("%s", db_reg[0][QUAD][f_rm(rex, inst)]);
  1367. break;
  1368. case Ril:
  1369. db_printf("%s", db_reg[rex != 0 ? 1 : 0][(rex & REX_R) ? QUAD : LONG][f_rm(rex, inst)]);
  1370. break;
  1371. case S:
  1372. db_printf("%s", db_seg_reg[f_reg(0, regmodrm)]);
  1373. break;
  1374. case Si:
  1375. db_printf("%s", db_seg_reg[f_reg(0, inst)]);
  1376. break;
  1377. case A:
  1378. db_printf("%s", db_reg[rex != 0 ? 1 : 0][size][0]); /* acc */
  1379. break;
  1380. case BX:
  1381. if (seg)
  1382. db_printf("%s:", seg);
  1383. db_printf("(%s)", short_addr ? "%bx" : "%ebx");
  1384. break;
  1385. case CL:
  1386. db_printf("%%cl");
  1387. break;
  1388. case DX:
  1389. db_printf("%%dx");
  1390. break;
  1391. case SI:
  1392. if (seg)
  1393. db_printf("%s:", seg);
  1394. db_printf("(%s)", short_addr ? "%si" : "%rsi");
  1395. break;
  1396. case DI:
  1397. db_printf("%%es:(%s)", short_addr ? "%di" : "%rdi");
  1398. break;
  1399. case CR:
  1400. db_printf("%%cr%d", f_reg(rex, regmodrm));
  1401. break;
  1402. case DR:
  1403. db_printf("%%dr%d", f_reg(rex, regmodrm));
  1404. break;
  1405. case TR:
  1406. db_printf("%%tr%d", f_reg(rex, regmodrm));
  1407. break;
  1408. case I:
  1409. len = db_lengths[size];
  1410. get_value_inc(imm, loc, len, FALSE);
  1411. db_printf("$%#x", imm);
  1412. break;
  1413. case Is:
  1414. len = db_lengths[(size == LONG && (rex & REX_W)) ? QUAD : size];
  1415. get_value_inc(imm, loc, len, FALSE);
  1416. db_printf("$%x", imm);
  1417. break;
  1418. case Ib:
  1419. get_value_inc(imm, loc, 1, FALSE);
  1420. db_printf("$%#x", imm);
  1421. break;
  1422. case Iba:
  1423. get_value_inc(imm, loc, 1, FALSE);
  1424. if (imm != 0x0a)
  1425. db_printf("$%#x", imm);
  1426. break;
  1427. case Ibs:
  1428. get_value_inc(imm, loc, 1, TRUE);
  1429. if (size == WORD)
  1430. imm &= 0xFFFF;
  1431. db_printf("$%x", imm);
  1432. break;
  1433. case Iw:
  1434. get_value_inc(imm, loc, 2, FALSE);
  1435. db_printf("$%#x", imm);
  1436. break;
  1437. case Ilq:
  1438. len = db_lengths[rex & REX_W ? QUAD : LONG];
  1439. get_value_inc(imm64, loc, len, FALSE);
  1440. db_printf("$%#I64x", imm64);
  1441. break;
  1442. case O:
  1443. len = (short_addr ? 2 : 4);
  1444. get_value_inc(displ, loc, len, FALSE);
  1445. if (seg)
  1446. db_printf("%s:%x",seg, displ);
  1447. else
  1448. db_printsym((db_addr_t)displ, DB_STGY_ANY);
  1449. break;
  1450. case Db:
  1451. get_value_inc(displ, loc, 1, TRUE);
  1452. addr = loc + (LONG64)displ;
  1453. if (size == WORD)
  1454. addr &= 0xFFFF;
  1455. db_printsym(addr, DB_STGY_XTRN);
  1456. break;
  1457. case Dl:
  1458. len = db_lengths[(size == LONG && (rex & REX_W)) ? QUAD : size];
  1459. get_value_inc(displ, loc, len, FALSE);
  1460. addr = loc + (LONG64)displ;
  1461. if (size == WORD)
  1462. addr &= 0xFFFF;
  1463. db_printsym(addr, DB_STGY_XTRN);
  1464. break;
  1465. case o1:
  1466. db_printf("$1");
  1467. break;
  1468. case o3:
  1469. db_printf("$3");
  1470. break;
  1471. case OS:
  1472. len = db_lengths[size];
  1473. get_value_inc(imm, loc, len, FALSE); /* offset */
  1474. get_value_inc(imm2, loc, 2, FALSE); /* segment */
  1475. db_printf("$%#x,%#x", imm2, imm);
  1476. break;
  1477. case MX:
  1478. db_printf("%%mm%d", f_reg(rex, regmodrm));
  1479. break;
  1480. case EMX:
  1481. db_printf("%%mm%d", f_rm(rex, regmodrm));
  1482. break;
  1483. case XMM:
  1484. db_printf("%%xmm%d", f_reg(rex, regmodrm));
  1485. break;
  1486. case EXMM:
  1487. db_printf("%%xmm%d", f_rm(rex, regmodrm));
  1488. break;
  1489. }
  1490. }
  1491. return (loc);
  1492. }
  1493. void be_x86_64_disasm_one_insn(ADDRESS64 *addr, int display)
  1494. {
  1495. db_printf = display ? dbg_printf : no_printf;
  1496. addr->Offset = db_disasm(addr->Offset, TRUE);
  1497. }