I386Decoder.Mod 86 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342
  1. (** AUTHOR "rg"; PURPOSE "IA32 decoder for binary executable code"; *)
  2. MODULE I386Decoder;
  3. IMPORT Decoder, Streams, Strings, KernelLog;
  4. CONST
  5. objFileSuffix = "Obx";
  6. (* prefix *)
  7. pCS = 2EX; pDS = 3EX; pES = 26X; pFS = 64X; pGS = 65X; pSS = 36X; pREP = 0F3X;
  8. AdrSize = 67X; OpSize = 66X; none = -1;
  9. (* fp sizes *)
  10. FPSizeNone = 0;
  11. FPSizeSingle = 1;
  12. FPSizeDouble = 2;
  13. FPSizeExtended = 3;
  14. FPSizeWord = 4;
  15. FPSizeShort = 5;
  16. FPSizeLong = 6;
  17. FPSizeSmall = 7;
  18. FPSizeBig = 9;
  19. FPSizeBCD = 10;
  20. (* representations *)
  21. RepInt = 0;
  22. RepHex = 1;
  23. RepBoth = 2;
  24. RepRelJmp = 3;
  25. (* argument structure *)
  26. ArgNone = -2;
  27. ArgImm = 0;
  28. ArgReg = 1;
  29. ArgMem = 2;
  30. ArgRegReg = 3; (* must be the first constant for a 2 arguments structure *)
  31. ArgRegImm = 4;
  32. ArgRegMem = 5;
  33. ArgMemReg = 6;
  34. ArgMemImm = 7;
  35. ArgImmReg = 8;
  36. ArgImmImm = 9;
  37. ArgRegRegImm = 10;
  38. ArgRegMemImm = 11;
  39. ArgMemRegImm = 12;
  40. ArgRegRegReg = 13;
  41. ArgMemRegReg = 14;
  42. (* i386 Register *)
  43. EAX = 0; ECX = 1; EDX = 2; EBX = 3; ESP = 4; EBP = 5; ESI = 6; EDI = 7; (* 32 bit register *)
  44. AX = 0; CX = 1; DX = 2; BX = 3; SP = 4; BP = 5; SI = 6; DI = 7; (* 16 bit register *)
  45. AL = 0; CL = 1; DL = 2; BL = 3; AH = 4; CH = 5; DH = 6; BH = 7; (* 8 bit register *)
  46. ES = 20; CS = 21; SS = 22; DS = 23; FS = 24; GS = 25; (* 6, 7 reserved *) (* Segment register *)
  47. CR = 0; DR = 8; TR = 16;
  48. (* special registers *)
  49. SRegTR = 0;
  50. SRegDR = 1;
  51. SRegCR = 2;
  52. SRegFP = 3;
  53. (* i386 Instructions *)
  54. opAAA = 1;
  55. opAAD = 2;
  56. opAAM = 3;
  57. opAAS = 4;
  58. opADC = 5;
  59. opADD = 6;
  60. opADDPD = 7;
  61. opADDPS = 8;
  62. opADDSD = 9;
  63. opADDSS = 10;
  64. opAND = 11;
  65. opANDPD = 12;
  66. opANDPS = 13;
  67. opANDNPD = 14;
  68. opANDNPS = 15;
  69. opARPL = 16;
  70. opBOUND = 17;
  71. opBSF = 18;
  72. opBSR = 19;
  73. opBSWAP = 20;
  74. opBT = 21;
  75. opBTC = 22;
  76. opBTR = 23;
  77. opBTS = 24;
  78. opCALL = 25;
  79. opCALLFAR = 26;
  80. opCBW = 27;
  81. opCDQ = 28;
  82. opCLC = 29;
  83. opCLD = 30;
  84. opCLFLUSH = 31;
  85. opCLI = 32;
  86. opCLTS = 33;
  87. opCMC = 34;
  88. opCMOVcc = 35;
  89. opCMOVO = 36;
  90. opCMOVNO = 37;
  91. opCMOVB = 38;
  92. opCMOVNB = 39;
  93. opCMOVZ = 40;
  94. opCMOVNZ = 41;
  95. opCMOVBE = 42;
  96. opCMOVNBE = 43;
  97. opCMOVS = 44;
  98. opCMOVNS = 45;
  99. opCMOVP = 46;
  100. opCMOVNP = 47;
  101. opCMOVL = 48;
  102. opCMOVNL = 49;
  103. opCMOVLE = 50;
  104. opCMOVNLE = 51;
  105. opCMP = 52;
  106. opCMPPD = 53;
  107. opCMPPS = 54;
  108. opCMPS = 55;
  109. opCMPSB = 56;
  110. opCMPSW = 57;
  111. opCMPSD = 58;
  112. opCMPSS = 59;
  113. opCMPXCHG = 60;
  114. opCMPXCHG8B = 61;
  115. opCOMISD = 62;
  116. opCOMISS = 63;
  117. opCPUID = 64;
  118. opCVTDQ2PD = 65;
  119. opCVTD12PS = 66;
  120. opCVTD2DQ = 67;
  121. opCVTPD2PI = 68;
  122. opCVTPD2PS = 69;
  123. opCVTPI2PD = 70;
  124. opCVTPI2PS = 71;
  125. opCVTPS2DQ = 72;
  126. opCVTPS2PD = 73;
  127. opCVTPS2PI = 74;
  128. opCVTSD2SI = 75;
  129. opCVTSD2SS = 76;
  130. opCVTSI2SD = 77;
  131. opCVTSI2SS = 78;
  132. opCVTSS2SD = 79;
  133. opCVTSS2SI = 80;
  134. opCVTTPD2PI = 81;
  135. opCVTTPD2DQ = 82;
  136. opCVTTPS2DQ = 83;
  137. opCVTTPS2PI = 84;
  138. opCVTTDS2SI = 85;
  139. opCVTTSS2SI = 86;
  140. opCWD = 87;
  141. opCWDE = 88;
  142. opDAA = 89;
  143. opDAS = 90;
  144. opDEC = 91;
  145. opDIV = 92;
  146. opDIVPD = 93;
  147. opDIVPS = 94;
  148. opDIVSD = 95;
  149. opDIVSS = 96;
  150. opEMMS = 97;
  151. opENTER = 98;
  152. opF2XM1 = 99;
  153. opFABS = 100;
  154. opFADD = 101;
  155. opFADDP = 102;
  156. opFIADD = 103;
  157. opFBLD = 104;
  158. opFBSTP = 105;
  159. opFCHS = 106;
  160. opFCLEX = 107;
  161. opFNCLEX = 108;
  162. opFCMOVcc = 109;
  163. opFCOM = 111;
  164. opFCOMP = 112;
  165. opFCOMPP = 113;
  166. opFCOMI = 114;
  167. opFCOMIP = 115;
  168. opFUCOMI = 116;
  169. opFUCOMIP = 117;
  170. opFCOS = 118;
  171. opFDECSTP = 119;
  172. opFDIV = 120;
  173. opFDIVP = 121;
  174. opFIDIV = 122;
  175. opFDIVR = 123;
  176. opFDIVRP = 124;
  177. opFIDIVR = 125;
  178. opFFREE = 126;
  179. opFICOM = 127;
  180. opFICOMP = 128;
  181. opFILD = 129;
  182. opFINCSTP = 130;
  183. opFINIT = 131;
  184. opFNINIT = 132;
  185. opFIST = 133;
  186. opFISTP = 134;
  187. opFLD = 135;
  188. opFLD1 = 136;
  189. opFLDL2T = 137;
  190. opFLDL2E = 138;
  191. opFLDPI = 139;
  192. opFLDLG2 = 140;
  193. opFLDLN2 = 141;
  194. opFLDZ = 142;
  195. opFLDCW = 143;
  196. opFLDENV = 144;
  197. opFMUL = 145;
  198. opFMULP = 146;
  199. opFIMUL = 147;
  200. opFNOP = 148;
  201. opFPATAN = 149;
  202. opFPREM = 150;
  203. opFPREM1 = 151;
  204. opFPTAN = 152;
  205. opFRNDINT = 153;
  206. opFRSTOR = 154;
  207. opFSAVE = 155;
  208. opFNSAVE = 156;
  209. opFSCALE = 157;
  210. opFSIN = 158;
  211. opFSINCOS = 159;
  212. opFSQRT = 160;
  213. opFST = 161;
  214. opFSTP = 162;
  215. opFSTCW = 163;
  216. opFNSTCW = 164;
  217. opFSTENV = 165;
  218. opFNSTENV = 166;
  219. opFSTSW = 167;
  220. opFNSTSW = 168;
  221. opFSUB = 169;
  222. opFSUBP = 170;
  223. opFISUB = 171;
  224. opFSUBR = 172;
  225. opFSUBRP = 173;
  226. opFISUBR = 174;
  227. opFTST = 175;
  228. opFUCOM = 176;
  229. opFUCOMP = 177;
  230. opFUCOMPP = 178;
  231. opFWAIT = 179;
  232. opFXAM = 180;
  233. opFXCH = 181;
  234. opFXRSTOR = 182;
  235. opFXSAVE = 183;
  236. opFXTRACT = 184;
  237. opFYL2X = 185;
  238. opFYL2XP1 = 186;
  239. opHLT = 187;
  240. opIDIV = 188;
  241. opIMUL = 189;
  242. opIN = 190;
  243. opINC = 191;
  244. opINS = 192;
  245. opINSB = 193;
  246. opINSW = 194;
  247. opINSD = 195;
  248. opINT = 196;
  249. opINTO = 197;
  250. opINVD = 198;
  251. opINVLPG = 199;
  252. opIRET = 200;
  253. opIRETD = 201;
  254. opJcc = 202;
  255. opJO = 203;
  256. opJNO = 204;
  257. opJB = 205;
  258. opJNB = 206;
  259. opJZ = 207;
  260. opJNZ = 208;
  261. opJBE = 209;
  262. opJNBE = 210;
  263. opJS = 211;
  264. opJNS = 212;
  265. opJP = 213;
  266. opJNP = 214;
  267. opJL = 215;
  268. opJNL = 216;
  269. opJLE = 217;
  270. opJNLE = 218;
  271. opJCXZ = 219;
  272. opJECXZ = 220;
  273. opJMP = 221;
  274. opJMPFAR = 222;
  275. opLAHF = 223;
  276. opLAR = 224;
  277. opLDMXCSR = 225;
  278. opLDS = 226;
  279. opLEA = 227;
  280. opLEAVE = 228;
  281. opLES = 229;
  282. opLFENCE = 230;
  283. opLFS = 231;
  284. opLGDT = 232;
  285. opLGS = 233;
  286. opLLDT = 234;
  287. opLIDT = 235;
  288. opLMSW = 236;
  289. opLOCK = 237;
  290. opLODS = 238;
  291. opLODSB = 239;
  292. opLODSW = 240;
  293. opLODSD = 241;
  294. opLOOP = 242;
  295. opLOOPE = 243;
  296. opLOOPNE = 244;
  297. opLOOPcc = 245;
  298. opLSL = 246;
  299. opLSS = 247;
  300. opLTR = 248;
  301. opMASKMOVDQU = 249;
  302. opMASKMOVQ = 250;
  303. opMAXPD = 251;
  304. opMAXPS = 252;
  305. opMAXSD = 253;
  306. opMAXSS = 254;
  307. opMFENCE = 255;
  308. opMINPD = 256;
  309. opMINPS = 257;
  310. opMINSD = 258;
  311. opMINSS = 259;
  312. opMOV = 260;
  313. opMOVAPD = 261;
  314. opMOVAPS = 262;
  315. opMOVD = 263;
  316. opMOVDQA = 264;
  317. opMOVDQU = 265;
  318. opMOVDQ2Q = 266;
  319. opMOVHLPS = 267;
  320. opMOVHPD = 268;
  321. opMOVHPS = 269;
  322. opMOVLHPS = 270;
  323. opMOVLPD = 271;
  324. opMOVLPS = 272;
  325. opMOVMSKPD = 273;
  326. opMOVMSKPS = 274;
  327. opMOVNTDQ = 275;
  328. opMOVNTI = 276;
  329. opMOVNTPD = 277;
  330. opMOVNTPS = 278;
  331. opMOVNTQ = 279;
  332. opMOVQ = 280;
  333. opMOVQ2DQ = 281;
  334. opMOVS = 282;
  335. opMOVSB = 283;
  336. opMOVSW = 284;
  337. opMOVSD = 285;
  338. opMOVSS = 286;
  339. opMOVSX = 287;
  340. opMOVUPD = 288;
  341. opMOVUPS = 289;
  342. opMOVZX = 290;
  343. opMUL = 292;
  344. opMULPD = 293;
  345. opMULPS = 294;
  346. opMULSD = 295;
  347. opMULSS = 296;
  348. opNEG = 297;
  349. opNOP = 298;
  350. opNOT = 299;
  351. opOR = 300;
  352. opORPD = 301;
  353. opORPS = 302;
  354. opOUT = 303;
  355. opOUTS = 304;
  356. opOUTSB = 305;
  357. opOUTSW = 306;
  358. opOUTSD = 307;
  359. opPACKSSWB = 308;
  360. opPACKSSDW = 309;
  361. opPACKUSWB = 310;
  362. opPADDB = 311;
  363. opPADDW = 312;
  364. opPADDD = 313;
  365. opPADDQ = 314;
  366. opPADDSB = 315;
  367. opPADDSW = 316;
  368. opPADDUSB = 317;
  369. opPADDUSW = 318;
  370. opPAND = 319;
  371. opPANDN = 320;
  372. opPAUSE = 321;
  373. opPAVGB = 322;
  374. opPAVGW = 323;
  375. opPCMPEQB = 324;
  376. opPCMPEQW = 325;
  377. opPCMPEQD = 326;
  378. opPCMPGTB = 327;
  379. opPCMPGTW = 328;
  380. opPCMPGTD = 329;
  381. opPEXTRW = 330;
  382. opPINSRW = 331;
  383. opPMADDWD = 332;
  384. opPMAXSW = 333;
  385. opPMINSW = 334;
  386. opPMINUB = 335;
  387. opPMOVMSKB = 336;
  388. opPMULHUW = 337;
  389. opPMULHW = 338;
  390. opPMULLW = 339;
  391. opPMULUDQ = 340;
  392. opPOP = 342;
  393. opPOPWPTR = 343;
  394. opPOPDWPTR = 344;
  395. opPOPA = 345;
  396. opPOPAD = 346;
  397. opPOPF = 347;
  398. opPOPFD = 348;
  399. opPOR = 349;
  400. opPREFETCHh = 350;
  401. opPSADBW = 351;
  402. opPSHUFD = 352;
  403. opPSHUFHW = 353;
  404. opPOSHUFLW = 354;
  405. opPSHUFW = 355;
  406. opPSLLDQ = 356;
  407. opPSLLW = 357;
  408. opPSLLD = 358;
  409. opPSLLQ = 359;
  410. opPSRAW = 360;
  411. opPSRAD = 361;
  412. opPSRLDQ = 362;
  413. opPSRLW = 363;
  414. opPSRLD = 364;
  415. opPSRLQ = 365;
  416. opPSUBB = 366;
  417. opPSUBW = 367;
  418. opPSUBD = 368;
  419. opPSUBQ = 369;
  420. opPSUBSB = 370;
  421. opPSUBSW = 371;
  422. opPSUBUSB = 372;
  423. opPSUBUSW = 373;
  424. opPUNPCKHBW = 374;
  425. opPUNPCKHWD = 375;
  426. opPUNPCKHDQ = 376;
  427. opPUNPCKHQDQ = 377;
  428. opPUNPCKLBW = 378;
  429. opPUNPCKLWD = 379;
  430. opPUNPCKLDQ = 380;
  431. opPUNPCKLQDQ = 381;
  432. opPUSH = 382;
  433. opPUSHA = 383;
  434. opPUSHAD = 384;
  435. opPUSHF = 385;
  436. opPUSHFD = 386;
  437. opPXOR = 387;
  438. opRCL = 388;
  439. opRCR = 389;
  440. opROL = 390;
  441. opROR = 391;
  442. opRCPPS = 392;
  443. opRCPSS = 393;
  444. opRDMSR = 394;
  445. opRDPMC = 395;
  446. opRDTSC = 396;
  447. opREP = 398;
  448. opREPE = 399;
  449. opREPZ = 400;
  450. opREPNE = 401;
  451. opREPNZ = 402;
  452. opRET = 403;
  453. opRETFAR = 404;
  454. opRSM = 405;
  455. opRSQRTPS = 406;
  456. opRSQRTSS = 407;
  457. opSAHF = 408;
  458. opSAL = 409;
  459. opSAR = 410;
  460. opSHL = 411;
  461. opSHR = 412;
  462. opSBB = 413;
  463. opSCAS = 414;
  464. opSCASB = 415;
  465. opSCASW = 416;
  466. opSCASD = 417;
  467. opSETcc = 418;
  468. opSETO = 419;
  469. opSETNO = 420;
  470. opSETB = 421;
  471. opSETNB = 422;
  472. opSETZ = 423;
  473. opSETNZ = 424;
  474. opSETBE = 425;
  475. opSETNBE = 426;
  476. opSETS = 427;
  477. opSETNS = 428;
  478. opSETP = 429;
  479. opSETNP = 430;
  480. opSETL = 431;
  481. opSETNL = 432;
  482. opSETLE = 433;
  483. opSETNLE = 434;
  484. opSFENCE = 435;
  485. opSGDT = 436;
  486. opSHLD = 437;
  487. opSHRD = 438;
  488. opSHUFPD = 439;
  489. opSHUFPS = 440;
  490. opSIDT = 441;
  491. opSLDT = 442;
  492. opSMSW = 443;
  493. opSQRTPD = 444;
  494. opSWRTSD = 445;
  495. opSQRTSS = 446;
  496. opSTC = 447;
  497. opSTD = 448;
  498. opSTI = 450;
  499. opSTMXCSR = 451;
  500. opSTOS = 452;
  501. opSTOSB = 453;
  502. opSTOSW = 454;
  503. opSTOSD = 455;
  504. opSTR = 456;
  505. opSUB = 457;
  506. opSUBPD = 458;
  507. opSUBPS = 459;
  508. opSUBSD = 460;
  509. opSUBSS = 461;
  510. opSYSENTER = 462;
  511. opSYSEXIT = 463;
  512. opTEST = 464;
  513. opUCOMISD = 465;
  514. opUCOMISS = 466;
  515. opUD2 = 467;
  516. opUNPCKHPD = 468;
  517. opUNPCKHPS = 469;
  518. opUNPCKLPD = 470;
  519. opUNPCKLPS = 471;
  520. opVERR = 472;
  521. opVERW = 473;
  522. opWAIT = 474;
  523. opWBINVD = 475;
  524. opWRMSR = 476;
  525. opXADD = 477;
  526. opXCHG = 478;
  527. opXLAT = 479;
  528. opXLATB = 480;
  529. opXOR = 481;
  530. opXORPD = 482;
  531. opXORPS= 483;
  532. TYPE
  533. IA32Arg = OBJECT
  534. END IA32Arg;
  535. IA32ImmArg = OBJECT (IA32Arg)
  536. VAR
  537. imm : LONGINT;
  538. rep : LONGINT;
  539. width : LONGINT;
  540. PROCEDURE &New*(imm: LONGINT; rep, width : LONGINT);
  541. BEGIN
  542. SELF.imm := imm;
  543. SELF.rep:= rep;
  544. SELF.width := width
  545. END New;
  546. END IA32ImmArg;
  547. IA32RegArg = OBJECT (IA32Arg)
  548. VAR
  549. reg, width : LONGINT;
  550. PROCEDURE &New*(reg: LONGINT);
  551. BEGIN
  552. width := 4;
  553. SELF.reg := reg
  554. END New;
  555. END IA32RegArg;
  556. IA32SpecialRegArg = OBJECT (IA32RegArg)
  557. VAR
  558. specialKind : LONGINT;
  559. PROCEDURE GetRepresentation (w : Streams.Writer);
  560. BEGIN
  561. CASE specialKind OF
  562. SRegCR : w.String("CR");
  563. | SRegDR : w.String("DR");
  564. | SRegTR : w.String("TR");
  565. | SRegFP : w.String("ST(");
  566. ELSE
  567. END;
  568. w.Char(CHR(48+reg));
  569. IF specialKind = SRegFP THEN w.Char(')') END
  570. END GetRepresentation;
  571. END IA32SpecialRegArg;
  572. IA32MemArg = OBJECT (IA32Arg)
  573. VAR
  574. base, index, scale, disp, fpSize : LONGINT;
  575. bytePtr, wordPtr : BOOLEAN;
  576. PROCEDURE &New*(b, i, s, d: LONGINT);
  577. BEGIN
  578. fpSize := 0;
  579. base := b; index := i; scale := s; disp := d;
  580. bytePtr := FALSE; wordPtr := FALSE
  581. END New;
  582. END IA32MemArg;
  583. IA32Opcode = OBJECT (Decoder.Opcode)
  584. VAR
  585. op : LONGINT; (* first-byte-value of opcode *)
  586. prefixes : LONGINT; (* Number of prefixes *)
  587. prefix : ARRAY 4 OF CHAR;
  588. adrPrefix, opPrefix : BOOLEAN;
  589. opcodeBytes : LONGINT;
  590. opcodeByte : ARRAY 3 OF CHAR;
  591. argStructure : LONGINT;
  592. width : LONGINT;
  593. arg1, arg2, arg3 : IA32Arg;
  594. PROCEDURE &New*(proc : Decoder.ProcedureInfo; stream : Streams.Writer);
  595. BEGIN
  596. New^(proc, stream);
  597. prefixes := 0;
  598. opcodeBytes := 0;
  599. instr := -1;
  600. argStructure := none
  601. END New;
  602. PROCEDURE AddOpcodeByte(b : CHAR);
  603. BEGIN
  604. ASSERT(opcodeBytes < 3);
  605. opcodeByte[opcodeBytes] := b;
  606. INC(opcodeBytes)
  607. END AddOpcodeByte;
  608. PROCEDURE AddPrefixByte(b : CHAR);
  609. BEGIN
  610. ASSERT(prefixes < 4);
  611. prefix[prefixes] := b;
  612. INC(prefixes);
  613. IF b = AdrSize THEN adrPrefix := TRUE
  614. ELSIF b = OpSize THEN opPrefix := TRUE END
  615. END AddPrefixByte;
  616. PROCEDURE PrintOpcodeBytes(w : Streams.Writer);
  617. VAR
  618. string : ARRAY 100 OF CHAR;
  619. hexStr : ARRAY 3 OF CHAR;
  620. i : LONGINT;
  621. BEGIN
  622. string := "";
  623. FOR i := 0 TO prefixes-1 DO
  624. IntToHex(ORD(prefix[i]), 2, hexStr);
  625. w.String(hexStr); w.String(" | ")
  626. END;
  627. FOR i := prefixes TO LEN(code)-1 DO
  628. IntToHex(ORD(code[i]), 2, hexStr);
  629. w.String(hexStr); w.String(" ");
  630. END
  631. END PrintOpcodeBytes;
  632. PROCEDURE PrintInstruction(w : Streams.Writer);
  633. VAR
  634. i : LONGINT;
  635. opStr : ARRAY 20 OF CHAR;
  636. BEGIN
  637. (* print prefixes *)
  638. FOR i := 0 TO prefixes-1 DO
  639. CASE prefix[i] OF
  640. | pREP : w.String("REP ");
  641. ELSE
  642. END
  643. END;
  644. CASE instr OF
  645. opAAA: opStr := "AAA"
  646. | opAAD: opStr := "AAD"
  647. | opAAM: opStr := "AAM"
  648. | opAAS: opStr := "AAS"
  649. | opADC: opStr := "ADC"
  650. | opADD: opStr := "ADD"
  651. | opADDPD: opStr := "ADDPD"
  652. | opADDPS: opStr := "ADDPS"
  653. | opADDSD: opStr := "ADDSD"
  654. | opADDSS: opStr := "ADDSS"
  655. | opAND: opStr := "AND"
  656. | opANDPD: opStr := "ANDPD"
  657. | opANDPS: opStr := "ANDPS"
  658. | opANDNPD: opStr := "ANDNPD"
  659. | opANDNPS: opStr := "ANDNPS"
  660. | opARPL: opStr := "ARPL"
  661. | opBOUND: opStr := "BOUND"
  662. | opBSF: opStr := "BSF"
  663. | opBSR: opStr := "BSR"
  664. | opBSWAP: opStr := "BSWAP"
  665. | opBT: opStr := "BT"
  666. | opBTC: opStr := "BTC"
  667. | opBTR: opStr := "BTR"
  668. | opBTS: opStr := "BTS"
  669. | opCALL: opStr := "CALL"
  670. | opCALLFAR: opStr := "CALLFAR"
  671. | opCBW: opStr := "CBW"
  672. | opCDQ: opStr := "CDQ"
  673. | opCLC: opStr := "CLC"
  674. | opCLD: opStr := "CLD"
  675. | opCLFLUSH: opStr := "CLFLUSH"
  676. | opCLI: opStr := "CLI"
  677. | opCLTS: opStr := "CLTS"
  678. | opCMC: opStr := "CMC"
  679. | opCMOVcc: opStr := "CMOVcc"
  680. | opCMOVO: opStr := "CMOVO"
  681. | opCMOVNO: opStr := "CMOVNO"
  682. | opCMOVB: opStr := "CMOVB"
  683. | opCMOVNB: opStr := "CMOVNB"
  684. | opCMOVZ: opStr := "CMOVZ"
  685. | opCMOVNZ: opStr := "CMOVNZ"
  686. | opCMOVBE: opStr := "CMOVBE"
  687. | opCMOVNBE: opStr := "CMOVNBE"
  688. | opCMOVS: opStr := "CMOVS"
  689. | opCMOVNS: opStr := "CMOVNS"
  690. | opCMOVP: opStr := "CMOVP"
  691. | opCMOVNP: opStr := "CMOVNP"
  692. | opCMOVL: opStr := "CMOVL"
  693. | opCMOVNL: opStr := "CMOVNL"
  694. | opCMOVLE: opStr := "CMOVLE"
  695. | opCMOVNLE: opStr := "CMOVNLE"
  696. | opCMP: opStr := "CMP"
  697. | opCMPPD: opStr := "CMPPD"
  698. | opCMPPS: opStr := "CMPPS"
  699. | opCMPS: opStr := "CMPS"
  700. | opCMPSB: opStr := "CMPSB"
  701. | opCMPSW: opStr := "CMPSW"
  702. | opCMPSD: opStr := "CMPSD"
  703. | opCMPSS: opStr := "CMPSS"
  704. | opCMPXCHG: opStr := "CMPXCHG"
  705. | opCMPXCHG8B: opStr := "CMPXCHG8B"
  706. | opCOMISD: opStr := "COMISD"
  707. | opCOMISS: opStr := "COMISS"
  708. | opCPUID: opStr := "CPUID"
  709. | opCVTDQ2PD: opStr := "CVTDQ2PD"
  710. | opCVTD12PS: opStr := "CVTD12PS"
  711. | opCVTD2DQ: opStr := "CVTD2DQ"
  712. | opCVTPD2PI: opStr := "CVTPD2PI"
  713. | opCVTPD2PS: opStr := "CVTPD2PS"
  714. | opCVTPI2PD: opStr := "CVTPI2PD"
  715. | opCVTPI2PS: opStr := "CVTPI2PS"
  716. | opCVTPS2DQ: opStr := "CVTPS2DQ"
  717. | opCVTPS2PD: opStr := "CVTPS2PD"
  718. | opCVTPS2PI: opStr := "CVTPS2PI"
  719. | opCVTSD2SI: opStr := "CVTSD2SI"
  720. | opCVTSD2SS: opStr := "CVTSD2SS"
  721. | opCVTSI2SD: opStr := "CVTSI2SD"
  722. | opCVTSI2SS: opStr := "CVTSI2SS"
  723. | opCVTSS2SD: opStr := "CVTSS2SD"
  724. | opCVTSS2SI: opStr := "CVTSS2SI"
  725. | opCVTTPD2PI: opStr := "CVTTPD2PI"
  726. | opCVTTPD2DQ: opStr := "CVTTPD2DQ"
  727. | opCVTTPS2DQ: opStr := "CVTTPS2DQ"
  728. | opCVTTPS2PI: opStr := "CVTTPS2PI"
  729. | opCVTTDS2SI: opStr := "CVTTDS2SI"
  730. | opCVTTSS2SI: opStr := "CVTTSS2SI"
  731. | opCWD: opStr := "CWD"
  732. | opCWDE: opStr := "CWDE"
  733. | opDAA: opStr := "DAA"
  734. | opDAS: opStr := "DAS"
  735. | opDEC: opStr := "DEC"
  736. | opDIV: opStr := "DIV"
  737. | opDIVPD: opStr := "DIVPD"
  738. | opDIVPS: opStr := "DIVPS"
  739. | opDIVSD: opStr := "DIVSD"
  740. | opDIVSS: opStr := "DIVSS"
  741. | opEMMS: opStr := "EMMS"
  742. | opENTER: opStr := "ENTER"
  743. | opF2XM1: opStr := "F2XM1"
  744. | opFABS: opStr := "FABS"
  745. | opFADD: opStr := "FADD"
  746. | opFADDP: opStr := "FADDP"
  747. | opFIADD: opStr := "FIADD"
  748. | opFBLD: opStr := "FBLD"
  749. | opFBSTP: opStr := "FBSTP"
  750. | opFCHS: opStr := "FCHS"
  751. | opFCLEX: opStr := "FCLEX"
  752. | opFNCLEX: opStr := "FNCLEX"
  753. | opFCMOVcc: opStr := "FCMOVcc"
  754. | opFCOM: opStr := "FCOM"
  755. | opFCOMP: opStr := "FCOMP"
  756. | opFCOMPP: opStr := "FCOMPP"
  757. | opFCOMI: opStr := "FCOMI"
  758. | opFCOMIP: opStr := "FCOMIP"
  759. | opFUCOMI: opStr := "FUCOMI"
  760. | opFUCOMIP: opStr := "FUCOMIP"
  761. | opFCOS: opStr := "FCOS"
  762. | opFDECSTP: opStr := "FDECSTP"
  763. | opFDIV: opStr := "FDIV"
  764. | opFDIVP: opStr := "FDIVP"
  765. | opFIDIV: opStr := "FIDIV"
  766. | opFDIVR: opStr := "FDIVR"
  767. | opFDIVRP: opStr := "FDIVRP"
  768. | opFIDIVR: opStr := "FIDIVR"
  769. | opFFREE: opStr := "FFREE"
  770. | opFICOM: opStr := "FICOM"
  771. | opFICOMP: opStr := "FICOMP"
  772. | opFILD: opStr := "FILD"
  773. | opFINCSTP: opStr := "FINCSTP"
  774. | opFINIT: opStr := "FINIT"
  775. | opFNINIT: opStr := "FNINIT"
  776. | opFIST: opStr := "FIST"
  777. | opFISTP: opStr := "FISTP"
  778. | opFLD: opStr := "FLD"
  779. | opFLD1: opStr := "FLD1"
  780. | opFLDL2T: opStr := "FLDL2T"
  781. | opFLDL2E: opStr := "FLDL2E"
  782. | opFLDPI: opStr := "FLDPI"
  783. | opFLDLG2: opStr := "FLDLG2"
  784. | opFLDLN2: opStr := "FLDLN2"
  785. | opFLDZ: opStr := "FLDZ"
  786. | opFLDCW: opStr := "FLDCW"
  787. | opFLDENV: opStr := "FLDENV"
  788. | opFMUL: opStr := "FMUL"
  789. | opFMULP: opStr := "FMULP"
  790. | opFIMUL: opStr := "FIMUL"
  791. | opFNOP: opStr := "FNOP"
  792. | opFPATAN: opStr := "FPATAN"
  793. | opFPREM: opStr := "FPREM"
  794. | opFPREM1: opStr := "FPREM1"
  795. | opFPTAN: opStr := "FPTAN"
  796. | opFRNDINT: opStr := "FRNDINT"
  797. | opFRSTOR: opStr := "FRSTOR"
  798. | opFSAVE: opStr := "FSAVE"
  799. | opFNSAVE: opStr := "FNSAVE"
  800. | opFSCALE: opStr := "FSCALE"
  801. | opFSIN: opStr := "FSIN"
  802. | opFSINCOS: opStr := "FSINCOS"
  803. | opFSQRT: opStr := "FSQRT"
  804. | opFST: opStr := "FST"
  805. | opFSTP: opStr := "FSTP"
  806. | opFSTCW: opStr := "FSTCW"
  807. | opFNSTCW: opStr := "FNSTCW"
  808. | opFSTENV: opStr := "FSTENV"
  809. | opFNSTENV: opStr := "FNSTENV"
  810. | opFSTSW: opStr := "FSTSW"
  811. | opFNSTSW: opStr := "FNSTSW"
  812. | opFSUB: opStr := "FSUB"
  813. | opFSUBP: opStr := "FSUBP"
  814. | opFISUB: opStr := "FISUB"
  815. | opFSUBR: opStr := "FSUBR"
  816. | opFSUBRP: opStr := "FSUBRP"
  817. | opFISUBR: opStr := "FISUBR"
  818. | opFTST: opStr := "FTST"
  819. | opFUCOM: opStr := "FUCOM"
  820. | opFUCOMP: opStr := "FUCOMP"
  821. | opFUCOMPP: opStr := "FUCOMPP"
  822. | opFWAIT: opStr := "FWAIT"
  823. | opFXAM: opStr := "FXAM"
  824. | opFXCH: opStr := "FXCH"
  825. | opFXRSTOR: opStr := "FXRSTOR"
  826. | opFXSAVE: opStr := "FXSAVE"
  827. | opFXTRACT: opStr := "FXTRACT"
  828. | opFYL2X: opStr := "FYL2X"
  829. | opFYL2XP1: opStr := "FYL2XP1"
  830. | opHLT: opStr := "HLT"
  831. | opIDIV: opStr := "IDIV"
  832. | opIMUL: opStr := "IMUL"
  833. | opIN: opStr := "IN"
  834. | opINC: opStr := "INC"
  835. | opINS: opStr := "INS"
  836. | opINSB: opStr := "INSB"
  837. | opINSW: opStr := "INSW"
  838. | opINSD: opStr := "INSD"
  839. | opINT: opStr := "INT"
  840. | opINTO: opStr := "INTO"
  841. | opINVD: opStr := "INVD"
  842. | opINVLPG: opStr := "INVLPG"
  843. | opIRET: opStr := "IRET"
  844. | opIRETD: opStr := "IRETD"
  845. | opJcc: opStr := "Jcc"
  846. | opJO: opStr := "JO"
  847. | opJNO: opStr := "JNO"
  848. | opJB: opStr := "JB"
  849. | opJNB: opStr := "JNB"
  850. | opJZ: opStr := "JZ"
  851. | opJNZ: opStr := "JNZ"
  852. | opJBE: opStr := "JBE"
  853. | opJNBE: opStr := "JNBE"
  854. | opJS: opStr := "JS"
  855. | opJNS: opStr := "JNS"
  856. | opJP: opStr := "JP"
  857. | opJNP: opStr := "JNP"
  858. | opJL: opStr := "JL"
  859. | opJNL: opStr := "JNL"
  860. | opJLE: opStr := "JLE"
  861. | opJNLE: opStr := "JNLE"
  862. | opJCXZ: opStr := "JCXZ"
  863. | opJECXZ: opStr := "JECXZ"
  864. | opJMP: opStr := "JMP"
  865. | opJMPFAR: opStr := "JMPFAR"
  866. | opLAHF: opStr := "LAHF"
  867. | opLAR: opStr := "LAR"
  868. | opLDMXCSR: opStr := "LDMXCSR"
  869. | opLDS: opStr := "LDS"
  870. | opLEA: opStr := "LEA"
  871. | opLEAVE: opStr := "LEAVE"
  872. | opLES: opStr := "LES"
  873. | opLFENCE: opStr := "LFENCE"
  874. | opLFS: opStr := "LFS"
  875. | opLGDT: opStr := "LGDT"
  876. | opLGS: opStr := "LGS"
  877. | opLLDT: opStr := "LLDT"
  878. | opLIDT: opStr := "LIDT"
  879. | opLMSW: opStr := "LMSW"
  880. | opLOCK: opStr := "LOCK"
  881. | opLODS: opStr := "LODS"
  882. | opLODSB: opStr := "LODSB"
  883. | opLODSW: opStr := "LODSW"
  884. | opLODSD: opStr := "LODSD"
  885. | opLOOP: opStr := "LOOP"
  886. | opLOOPE: opStr := "LOOPE"
  887. | opLOOPNE: opStr := "LOOPNE"
  888. | opLOOPcc: opStr := "LOOPcc"
  889. | opLSL: opStr := "LSL"
  890. | opLSS: opStr := "LSS"
  891. | opLTR: opStr := "LTR"
  892. | opMASKMOVDQU: opStr := "MASKMOVDQU"
  893. | opMASKMOVQ: opStr := "MASKMOVQ"
  894. | opMAXPD: opStr := "MAXPD"
  895. | opMAXPS: opStr := "MAXPS"
  896. | opMAXSD: opStr := "MAXSD"
  897. | opMAXSS: opStr := "MAXSS"
  898. | opMFENCE: opStr := "MFENCE"
  899. | opMINPD: opStr := "MINPD"
  900. | opMINPS: opStr := "MINPS"
  901. | opMINSD: opStr := "MINSD"
  902. | opMINSS: opStr := "MINSS"
  903. | opMOV: opStr := "MOV"
  904. | opMOVAPD: opStr := "MOVAPD"
  905. | opMOVAPS: opStr := "MOVAPS"
  906. | opMOVD: opStr := "MOVD"
  907. | opMOVDQA: opStr := "MOVDQA"
  908. | opMOVDQU: opStr := "MOVDQU"
  909. | opMOVDQ2Q: opStr := "MOVDQ2Q"
  910. | opMOVHLPS: opStr := "MOVHLPS"
  911. | opMOVHPD: opStr := "MOVHPD"
  912. | opMOVHPS: opStr := "MOVHPS"
  913. | opMOVLHPS: opStr := "MOVLHPS"
  914. | opMOVLPD: opStr := "MOVLPD"
  915. | opMOVLPS: opStr := "MOVLPS"
  916. | opMOVMSKPD: opStr := "MOVMSKPD"
  917. | opMOVMSKPS: opStr := "MOVMSKPS"
  918. | opMOVNTDQ: opStr := "MOVNTDQ"
  919. | opMOVNTI: opStr := "MOVNTI"
  920. | opMOVNTPD: opStr := "MOVNTPD"
  921. | opMOVNTPS: opStr := "MOVNTPS"
  922. | opMOVNTQ: opStr := "MOVNTQ"
  923. | opMOVQ: opStr := "MOVQ"
  924. | opMOVQ2DQ: opStr := "MOVQ2DQ"
  925. | opMOVS: opStr := "MOVS"
  926. | opMOVSB: opStr := "MOVSB"
  927. | opMOVSW: opStr := "MOVSW"
  928. | opMOVSD: opStr := "MOVSD"
  929. | opMOVSS: opStr := "MOVSS"
  930. | opMOVSX: opStr := "MOVSX"
  931. | opMOVUPD: opStr := "MOVUPD"
  932. | opMOVUPS: opStr := "MOVUPS"
  933. | opMOVZX: opStr := "MOVZX"
  934. | opMUL: opStr := "MUL"
  935. | opMULPD: opStr := "MULPD"
  936. | opMULPS: opStr := "MULPS"
  937. | opMULSD: opStr := "MULSD"
  938. | opMULSS: opStr := "MULSS"
  939. | opNEG: opStr := "NEG"
  940. | opNOP: opStr := "NOP"
  941. | opNOT: opStr := "NOT"
  942. | opOR: opStr := "OR"
  943. | opORPD: opStr := "ORPD"
  944. | opORPS: opStr := "ORPS"
  945. | opOUT: opStr := "OUT"
  946. | opOUTS: opStr := "OUTS"
  947. | opOUTSB: opStr := "OUTSB"
  948. | opOUTSW: opStr := "OUTSW"
  949. | opOUTSD: opStr := "OUTSD"
  950. | opPACKSSWB: opStr := "PACKSSWB"
  951. | opPACKSSDW: opStr := "PACKSSDW"
  952. | opPACKUSWB: opStr := "PACKUSWB"
  953. | opPADDB: opStr := "PADDB"
  954. | opPADDW: opStr := "PADDW"
  955. | opPADDD: opStr := "PADDD"
  956. | opPADDQ: opStr := "PADDQ"
  957. | opPADDSB: opStr := "PADDSB"
  958. | opPADDSW: opStr := "PADDSW"
  959. | opPADDUSB: opStr := "PADDUSB"
  960. | opPADDUSW: opStr := "PADDUSW"
  961. | opPAND: opStr := "PAND"
  962. | opPANDN: opStr := "PANDN"
  963. | opPAUSE: opStr := "PAUSE"
  964. | opPAVGB: opStr := "PAVGB"
  965. | opPAVGW: opStr := "PAVGW"
  966. | opPCMPEQB: opStr := "PCMPEQB"
  967. | opPCMPEQW: opStr := "PCMPEQW"
  968. | opPCMPEQD: opStr := "PCMPEQD"
  969. | opPCMPGTB: opStr := "PCMPGTB"
  970. | opPCMPGTW: opStr := "PCMPGTW"
  971. | opPCMPGTD: opStr := "PCMPGTD"
  972. | opPEXTRW: opStr := "PEXTRW"
  973. | opPINSRW: opStr := "PINSRW"
  974. | opPMADDWD: opStr := "PMADDWD"
  975. | opPMAXSW: opStr := "PMAXSW"
  976. | opPMINSW: opStr := "PMINSW"
  977. | opPMINUB: opStr := "PMINUB"
  978. | opPMOVMSKB: opStr := "PMOVMSKB"
  979. | opPMULHUW: opStr := "PMULHUW"
  980. | opPMULHW: opStr := "PMULHW"
  981. | opPMULLW: opStr := "PMULLW"
  982. | opPMULUDQ: opStr := "PMULUDQ"
  983. | opPOP: opStr := "POP"
  984. | opPOPWPTR: opStr := "POPWPTR"
  985. | opPOPDWPTR: opStr := "POPDWPTR"
  986. | opPOPA: opStr := "POPA"
  987. | opPOPAD: opStr := "POPAD"
  988. | opPOPF: opStr := "POPF"
  989. | opPOPFD: opStr := "POPFD"
  990. | opPOR: opStr := "POR"
  991. | opPREFETCHh: opStr := "PREFETCHh"
  992. | opPSADBW: opStr := "PSADBW"
  993. | opPSHUFD: opStr := "PSHUFD"
  994. | opPSHUFHW: opStr := "PSHUFHW"
  995. | opPOSHUFLW: opStr := "POSHUFLW"
  996. | opPSHUFW: opStr := "PSHUFW"
  997. | opPSLLDQ: opStr := "PSLLDQ"
  998. | opPSLLW: opStr := "PSLLW"
  999. | opPSLLD: opStr := "PSLLD"
  1000. | opPSLLQ: opStr := "PSLLQ"
  1001. | opPSRAW: opStr := "PSRAW"
  1002. | opPSRAD: opStr := "PSRAD"
  1003. | opPSRLDQ: opStr := "PSRLDQ"
  1004. | opPSRLW: opStr := "PSRLW"
  1005. | opPSRLD: opStr := "PSRLD"
  1006. | opPSRLQ: opStr := "PSRLQ"
  1007. | opPSUBB: opStr := "PSUBB"
  1008. | opPSUBW: opStr := "PSUBW"
  1009. | opPSUBD: opStr := "PSUBD"
  1010. | opPSUBQ: opStr := "PSUBQ"
  1011. | opPSUBSB: opStr := "PSUBSB"
  1012. | opPSUBSW: opStr := "PSUBSW"
  1013. | opPSUBUSB: opStr := "PSUBUSB"
  1014. | opPSUBUSW: opStr := "PSUBUSW"
  1015. | opPUNPCKHBW: opStr := "PUNPCKHBW"
  1016. | opPUNPCKHWD: opStr := "PUNPCKHWD"
  1017. | opPUNPCKHDQ: opStr := "PUNPCKHDQ"
  1018. | opPUNPCKHQDQ: opStr := "PUNPCKHQDQ"
  1019. | opPUNPCKLBW: opStr := "PUNPCKLBW"
  1020. | opPUNPCKLWD: opStr := "PUNPCKLWD"
  1021. | opPUNPCKLDQ: opStr := "PUNPCKLDQ"
  1022. | opPUNPCKLQDQ: opStr := "PUNPCKLQDQ"
  1023. | opPUSH: opStr := "PUSH"
  1024. | opPUSHA: opStr := "PUSHA"
  1025. | opPUSHAD: opStr := "PUSHAD"
  1026. | opPUSHF: opStr := "PUSHF"
  1027. | opPUSHFD: opStr := "PUSHFD"
  1028. | opPXOR: opStr := "PXOR"
  1029. | opRCL: opStr := "RCL"
  1030. | opRCR: opStr := "RCR"
  1031. | opROL: opStr := "ROL"
  1032. | opROR: opStr := "ROR"
  1033. | opRCPPS: opStr := "RCPPS"
  1034. | opRCPSS: opStr := "RCPSS"
  1035. | opRDMSR: opStr := "RDMSR"
  1036. | opRDPMC: opStr := "RDPMC"
  1037. | opRDTSC: opStr := "RDTSC"
  1038. | opREP: opStr := "REP"
  1039. | opREPE: opStr := "REPE"
  1040. | opREPZ: opStr := "REPZ"
  1041. | opREPNE: opStr := "REPNE"
  1042. | opREPNZ: opStr := "REPNZ"
  1043. | opRET: opStr := "RET"
  1044. | opRETFAR: opStr := "RETFAR"
  1045. | opRSM: opStr := "RSM"
  1046. | opRSQRTPS: opStr := "RSQRTPS"
  1047. | opRSQRTSS: opStr := "RSQRTSS"
  1048. | opSAHF: opStr := "SAHF"
  1049. | opSAL: opStr := "SAL"
  1050. | opSAR: opStr := "SAR"
  1051. | opSHL: opStr := "SHL"
  1052. | opSHR: opStr := "SHR"
  1053. | opSBB: opStr := "SBB"
  1054. | opSCAS: opStr := "SCAS"
  1055. | opSCASB: opStr := "SCASB"
  1056. | opSCASW: opStr := "SCASW"
  1057. | opSCASD: opStr := "SCASD"
  1058. | opSETcc: opStr := "SETcc"
  1059. | opSETO: opStr := "SETO"
  1060. | opSETNO: opStr := "SETNO"
  1061. | opSETB: opStr := "SETB"
  1062. | opSETNB: opStr := "SETNB"
  1063. | opSETZ: opStr := "SETZ"
  1064. | opSETNZ: opStr := "SETNZ"
  1065. | opSETBE: opStr := "SETBE"
  1066. | opSETNBE: opStr := "SETNBE"
  1067. | opSETS: opStr := "SETS"
  1068. | opSETNS: opStr := "SETNS"
  1069. | opSETP: opStr := "SETP"
  1070. | opSETNP: opStr := "SETNP"
  1071. | opSETL: opStr := "SETL"
  1072. | opSETNL: opStr := "SETNL"
  1073. | opSETLE: opStr := "SETLE"
  1074. | opSETNLE: opStr := "SETNLE"
  1075. | opSFENCE: opStr := "SFENCE"
  1076. | opSGDT: opStr := "SGDT"
  1077. | opSHLD: opStr := "SHLD"
  1078. | opSHRD: opStr := "SHRD"
  1079. | opSHUFPD: opStr := "SHUFPD"
  1080. | opSHUFPS: opStr := "SHUFPS"
  1081. | opSIDT: opStr := "SIDT"
  1082. | opSLDT: opStr := "SLDT"
  1083. | opSMSW: opStr := "SMSW"
  1084. | opSQRTPD: opStr := "SQRTPD"
  1085. | opSWRTSD: opStr := "SWRTSD"
  1086. | opSQRTSS: opStr := "SQRTSS"
  1087. | opSTC: opStr := "STC"
  1088. | opSTD: opStr := "STD"
  1089. | opSTI: opStr := "STI"
  1090. | opSTMXCSR: opStr := "STMXCSR"
  1091. | opSTOS: opStr := "STOS"
  1092. | opSTOSB: opStr := "STOSB"
  1093. | opSTOSW: opStr := "STOSW"
  1094. | opSTOSD: opStr := "STOSD"
  1095. | opSTR: opStr := "STR"
  1096. | opSUB: opStr := "SUB"
  1097. | opSUBPD: opStr := "SUBPD"
  1098. | opSUBPS: opStr := "SUBPS"
  1099. | opSUBSD: opStr := "SUBSD"
  1100. | opSUBSS: opStr := "SUBSS"
  1101. | opSYSENTER: opStr := "SYSENTER"
  1102. | opSYSEXIT: opStr := "SYSEXIT"
  1103. | opTEST: opStr := "TEST"
  1104. | opUCOMISD: opStr := "UCOMISD"
  1105. | opUCOMISS: opStr := "UCOMISS"
  1106. | opUD2: opStr := "UD2"
  1107. | opUNPCKHPD: opStr := "UNPCKHPD"
  1108. | opUNPCKHPS: opStr := "UNPCKHPS"
  1109. | opUNPCKLPD: opStr := "UNPCKLPD"
  1110. | opUNPCKLPS: opStr := "UNPCKLPS"
  1111. | opVERR: opStr := "VERR"
  1112. | opVERW: opStr := "VERW"
  1113. | opWAIT: opStr := "FWAIT"
  1114. | opWBINVD: opStr := "WBINVD"
  1115. | opWRMSR: opStr := "WRMSR"
  1116. | opXADD: opStr := "XADD"
  1117. | opXCHG: opStr := "XCHG"
  1118. | opXLAT: opStr := "XLAT"
  1119. | opXLATB: opStr := "XLATB"
  1120. | opXOR: opStr := "XOR"
  1121. | opXORPD: opStr := "XORPD"
  1122. | opXORPS: opStr := "XORPS"
  1123. ELSE
  1124. KernelLog.String("Unknown instr = "); KernelLog.Int(instr, 0); KernelLog.String(", op = "); KernelLog.Hex(op, -1); KernelLog.Ln;
  1125. opStr := "[unknown]"
  1126. END;
  1127. w.String(opStr)
  1128. END PrintInstruction;
  1129. PROCEDURE PrintArguments(w : Streams.Writer);
  1130. BEGIN
  1131. IF (argStructure >=0) & (arg1 = NIL) THEN w.String("{too little arguments}");RETURN
  1132. ELSIF (argStructure >= ArgRegReg) & (arg2=NIL) THEN w.String("{too little arguments}");RETURN
  1133. END;
  1134. ASSERT((argStructure < 0) OR (arg1 # NIL)); (* if instr has arguments, arg1 must not be NIL *)
  1135. ASSERT((argStructure < ArgRegReg) OR (arg2 # NIL)); (* if there are 2 args, the second one must not be NIL *)
  1136. (*
  1137. KernelLog.String("Decode opcode: "); KernelLog.String("op = "); KernelLog.Hex(op, 0);
  1138. KernelLog.String(", argStructure = "); KernelLog.Int(argStructure, 0); KernelLog.Ln;
  1139. *)
  1140. CASE argStructure OF
  1141. ArgReg : WriteReg(arg1(IA32RegArg), w)
  1142. | ArgImm : WriteImm(arg1(IA32ImmArg), w)
  1143. | ArgMem : WriteMem(arg1(IA32MemArg), w)
  1144. | ArgRegMem : WriteReg(arg1(IA32RegArg), w); w.String(", "); WriteMem(arg2(IA32MemArg), w)
  1145. | ArgMemReg : WriteMem(arg1(IA32MemArg), w); w.String(", "); WriteReg(arg2(IA32RegArg), w)
  1146. | ArgRegReg: WriteReg(arg1(IA32RegArg), w); w.String(", "); WriteReg(arg2(IA32RegArg), w)
  1147. | ArgRegImm: WriteReg(arg1(IA32RegArg), w); w.String(", "); WriteImm(arg2(IA32ImmArg), w)
  1148. | ArgMemImm: WriteMem(arg1(IA32MemArg), w); w.String(", "); WriteImm(arg2(IA32ImmArg), w)
  1149. | ArgImmReg: WriteImm(arg1(IA32ImmArg), w); w.String(", "); WriteReg(arg2(IA32RegArg), w)
  1150. | ArgImmImm: WriteImm(arg1(IA32ImmArg), w); w.String(", "); WriteImm(arg2(IA32ImmArg), w)
  1151. | ArgRegRegImm: WriteReg(arg1(IA32RegArg), w); w.String(", "); WriteReg(arg2(IA32RegArg), w); w.String(", "); WriteImm(arg3(IA32ImmArg), w)
  1152. | ArgRegMemImm: WriteReg(arg1(IA32RegArg), w); w.String(", "); WriteMem(arg2(IA32MemArg), w); w.String(", "); WriteImm(arg3(IA32ImmArg), w)
  1153. | ArgMemRegImm: WriteMem(arg1(IA32MemArg), w); w.String(", "); WriteReg(arg2(IA32RegArg), w); w.String(", "); WriteImm(arg3(IA32ImmArg), w)
  1154. | ArgRegRegReg: WriteReg(arg1(IA32RegArg), w); w.String(", "); WriteReg(arg2(IA32RegArg), w); w.String(", "); WriteReg(arg3(IA32RegArg), w)
  1155. | ArgMemRegReg: WriteMem(arg1(IA32MemArg), w); w.String(", "); WriteReg(arg2(IA32RegArg), w); w.String(", "); WriteReg(arg3(IA32RegArg), w)
  1156. | ArgNone:
  1157. ELSE
  1158. w.String("{argStructure not specified!}")
  1159. END
  1160. END PrintArguments;
  1161. PROCEDURE PrintVariables(w : Streams.Writer);
  1162. VAR
  1163. numPrints : LONGINT;
  1164. PROCEDURE DetectVar (memArg : IA32MemArg);
  1165. VAR
  1166. field : Decoder.FieldInfo;
  1167. BEGIN
  1168. IF memArg.base = EBP THEN
  1169. field := proc.GetFieldAtOffset(memArg.disp);
  1170. IF field # NIL THEN
  1171. field.AddMarkerPosition(w.Pos());
  1172. IF numPrints > 0 THEN
  1173. w.String(", ")
  1174. END;
  1175. w.String(field.name);
  1176. w.String(": ");
  1177. WriteMem(memArg, w);
  1178. INC(numPrints)
  1179. END
  1180. END
  1181. END DetectVar;
  1182. BEGIN
  1183. numPrints := 0;
  1184. IF arg1 # NIL THEN
  1185. IF arg1 IS IA32MemArg THEN
  1186. DetectVar(arg1(IA32MemArg))
  1187. END;
  1188. IF arg2 # NIL THEN
  1189. IF arg2 IS IA32MemArg THEN
  1190. DetectVar(arg2(IA32MemArg))
  1191. END;
  1192. IF arg3 # NIL THEN
  1193. IF arg3 IS IA32MemArg THEN
  1194. DetectVar(arg3(IA32MemArg))
  1195. END
  1196. END
  1197. END
  1198. END
  1199. END PrintVariables;
  1200. PROCEDURE ToString () : Strings.String;
  1201. VAR
  1202. str : ARRAY 255 OF CHAR;
  1203. temp : ARRAY 10 OF CHAR;
  1204. BEGIN
  1205. Strings.IntToHexStr(op, 0, temp);
  1206. Strings.Append(str, "Opcode: op = "); Strings.Append(str, temp);
  1207. Strings.IntToStr(instr, temp);
  1208. Strings.Append(str, ", instr = "); Strings.Append(str, temp);
  1209. Strings.IntToHexStr(offset, 0, temp);
  1210. Strings.Append(str, ", offset = "); Strings.Append(str, temp);
  1211. RETURN Strings.NewString(str)
  1212. END ToString;
  1213. PROCEDURE WriteImm(immArg : IA32ImmArg; w : Streams.Writer);
  1214. VAR
  1215. PROCEDURE WriteHex;
  1216. VAR absImm : SIZE;
  1217. BEGIN
  1218. absImm := immArg.imm;
  1219. IF immArg.rep = RepRelJmp THEN
  1220. (* add opcode position and length of full opcode to immediate argument value *)
  1221. INC(absImm, offset + length)
  1222. END;
  1223. WriteHex32(LONGINT(absImm), w)
  1224. END WriteHex;
  1225. BEGIN
  1226. IF immArg.rep = RepInt THEN
  1227. w.Int(immArg.imm, 0)
  1228. ELSIF immArg.rep = RepHex THEN
  1229. WriteHex;
  1230. w.Char('H')
  1231. ELSE
  1232. w.Int(immArg.imm, 0);
  1233. w.String(" (");
  1234. WriteHex;
  1235. w.String("H)")
  1236. END
  1237. END WriteImm;
  1238. PROCEDURE WriteAdrReg(regNr : LONGINT; w : Streams.Writer);
  1239. BEGIN
  1240. IF adrPrefix THEN
  1241. IF regNr = 0 THEN w.String("AX")
  1242. ELSIF regNr = 1 THEN w.String("CX")
  1243. ELSIF regNr = 2 THEN w.String("DX")
  1244. ELSIF regNr = 3 THEN w.String("BX")
  1245. ELSIF regNr = 4 THEN w.String("SP")
  1246. ELSIF regNr = 5 THEN w.String("BP")
  1247. ELSIF regNr = 6 THEN w.String("SI")
  1248. ELSIF regNr = 7 THEN w.String("DI")
  1249. ELSE HALT(99)
  1250. END
  1251. ELSE
  1252. IF regNr = 0 THEN w.String("EAX")
  1253. ELSIF regNr = 1 THEN w.String("ECX")
  1254. ELSIF regNr = 2 THEN w.String("EDX")
  1255. ELSIF regNr = 3 THEN w.String("EBX")
  1256. ELSIF regNr = 4 THEN w.String("ESP")
  1257. ELSIF regNr = 5 THEN w.String("EBP")
  1258. ELSIF regNr = 6 THEN w.String("ESI")
  1259. ELSIF regNr = 7 THEN w.String("EDI")
  1260. ELSE HALT(99)
  1261. END
  1262. END
  1263. END WriteAdrReg;
  1264. PROCEDURE WriteReg (regArg : IA32RegArg; writer : Streams.Writer);
  1265. VAR
  1266. reg, w : LONGINT;
  1267. oP : BOOLEAN;
  1268. BEGIN
  1269. IF regArg IS IA32SpecialRegArg THEN
  1270. regArg(IA32SpecialRegArg).GetRepresentation(writer); RETURN
  1271. END;
  1272. w := width;
  1273. oP := opPrefix;
  1274. IF ((instr = opIN) & (regArg = arg2)) OR ((instr = opOUT) & (regArg = arg1)) THEN
  1275. (* port in/out uses 16-bit register for port address only *)
  1276. w := 1; oP := TRUE
  1277. END;
  1278. reg := regArg.reg;
  1279. IF reg >= ES (*DS*) THEN (* <<<< MH 15.3.1994 *)
  1280. IF reg = CS THEN writer.String("CS")
  1281. ELSIF reg = DS THEN writer.String("DS")
  1282. ELSIF reg = ES THEN writer.String("ES")
  1283. ELSIF reg = SS THEN writer.String("SS")
  1284. ELSIF reg = FS THEN writer.String("FS")
  1285. ELSIF reg = GS THEN writer.String("GS")
  1286. ELSE HALT(99)
  1287. END
  1288. ELSIF (w = 0) OR (regArg.width = 1) THEN
  1289. IF reg = 0 THEN writer.String("AL")
  1290. ELSIF reg = 1 THEN writer.String("CL")
  1291. ELSIF reg = 2 THEN writer.String("DL")
  1292. ELSIF reg = 3 THEN writer.String("BL")
  1293. ELSIF reg = 4 THEN writer.String("AH")
  1294. ELSIF reg = 5 THEN writer.String("CH")
  1295. ELSIF reg = 6 THEN writer.String("DH")
  1296. ELSIF reg = 7 THEN writer.String("BH")
  1297. ELSE HALT(99)
  1298. END
  1299. ELSIF oP OR (regArg.width = 2) THEN
  1300. IF reg = 0 THEN writer.String("AX")
  1301. ELSIF reg = 1 THEN writer.String("CX")
  1302. ELSIF reg = 2 THEN writer.String("DX")
  1303. ELSIF reg = 3 THEN writer.String("BX")
  1304. ELSIF reg = 4 THEN writer.String("SP")
  1305. ELSIF reg = 5 THEN writer.String("BP")
  1306. ELSIF reg = 6 THEN writer.String("SI")
  1307. ELSIF reg = 7 THEN writer.String("DI")
  1308. ELSE HALT(99)
  1309. END
  1310. ELSE
  1311. IF reg = 0 THEN writer.String("EAX")
  1312. ELSIF reg = 1 THEN writer.String("ECX")
  1313. ELSIF reg = 2 THEN writer.String("EDX")
  1314. ELSIF reg = 3 THEN writer.String("EBX")
  1315. ELSIF reg = 4 THEN writer.String("ESP")
  1316. ELSIF reg = 5 THEN writer.String("EBP")
  1317. ELSIF reg = 6 THEN writer.String("ESI")
  1318. ELSIF reg = 7 THEN writer.String("EDI")
  1319. ELSE HALT(99)
  1320. END
  1321. END
  1322. END WriteReg;
  1323. PROCEDURE WriteMem(memArg : IA32MemArg; w : Streams.Writer);
  1324. VAR
  1325. intStr : ARRAY 20 OF CHAR;
  1326. i : LONGINT;
  1327. BEGIN
  1328. CASE memArg.fpSize OF
  1329. FPSizeSingle : w.String("SINGLE ")
  1330. | FPSizeDouble : w.String("DOUBLE ")
  1331. | FPSizeExtended : w.String("EXTENDED ")
  1332. | FPSizeWord : w.String("WORD ")
  1333. | FPSizeShort : w.String("SHORT ")
  1334. | FPSizeLong : w.String("LONG ")
  1335. | FPSizeSmall : w.String("SMALL ")
  1336. | FPSizeBig : w.String("BIG ")
  1337. | FPSizeBCD : w.String("BCD ")
  1338. ELSE
  1339. END;
  1340. IF memArg.bytePtr THEN
  1341. w.String("BYTE PTR ")
  1342. ELSIF memArg.wordPtr THEN
  1343. w.String("WORD PTR ")
  1344. END;
  1345. (* write segment prefixes *)
  1346. FOR i := 0 TO prefixes-1 DO
  1347. CASE prefix[i] OF
  1348. pCS : w.String("CS:")
  1349. | pDS : w.String("DS:")
  1350. | pES : w.String("ES:")
  1351. | pFS : w.String("FS:")
  1352. | pGS : w.String("GS:")
  1353. | pSS : w.String("SS:")
  1354. ELSE
  1355. END
  1356. END;
  1357. IF memArg.base # none THEN (* register relative *)
  1358. Strings.IntToStr(memArg.disp, intStr);
  1359. w.String(intStr);
  1360. w.String("[");
  1361. WriteAdrReg(memArg.base, w)
  1362. ELSE (* absolute *)
  1363. w.String("[");
  1364. w.Int(memArg.disp, 0)
  1365. END;
  1366. IF (memArg.index # none) & ~((memArg.index = ESP) & (memArg.base = ESP)) (* !! 15.4.93 Bug? & (base # ESP) *) THEN (* indexed *)
  1367. w.String(" + ");
  1368. WriteAdrReg(memArg.index, w);
  1369. IF memArg.scale = 0 THEN w.String(" * 1")
  1370. ELSIF memArg.scale = 1 THEN w.String(" * 2")
  1371. ELSIF memArg.scale = 2 THEN w.String(" * 4")
  1372. ELSE w.String(" * 8")
  1373. END;
  1374. END;
  1375. w.String("]")
  1376. END WriteMem;
  1377. END IA32Opcode;
  1378. IA32Decoder = OBJECT (Decoder.Decoder)
  1379. VAR
  1380. (* hack to recognize a WAIT in the previous opcode *)
  1381. previousOpcode, opcodeBeforeWait : IA32Opcode;
  1382. PROCEDURE DoPrefixes (VAR opcode : IA32Opcode);
  1383. VAR
  1384. op : CHAR;
  1385. inPrefixSequence : BOOLEAN;
  1386. (* reads all prefixes, store them in the prefix array and store the first real opcode in the opcode array *)
  1387. BEGIN
  1388. inPrefixSequence := TRUE;
  1389. WHILE inPrefixSequence DO
  1390. op := ReadChar();
  1391. IF (op = pCS) OR (op = pDS) OR (op = pES) OR (op = pFS) OR (op = pGS) OR (op = pSS)
  1392. OR (op = AdrSize) OR (op = OpSize) OR (op = pREP) THEN
  1393. opcode.AddPrefixByte(op);
  1394. ELSE
  1395. inPrefixSequence := FALSE;
  1396. opcode.AddOpcodeByte(op)
  1397. END
  1398. END
  1399. END DoPrefixes;
  1400. PROCEDURE GetImm (bytes: LONGINT) : LONGINT;
  1401. VAR ch: CHAR; byte: INTEGER;
  1402. BEGIN
  1403. IF bytes = 1 THEN (* 8 bit *)
  1404. ch := ReadChar();
  1405. IF ORD(ch) >= 128 THEN byte := ORD(ch) - 256 ELSE byte := ORD(ch) END;
  1406. RETURN byte
  1407. ELSIF bytes = 2 THEN (* 16 bit *)
  1408. RETURN ReadInt()
  1409. ELSE (* 32 bit *)
  1410. RETURN ReadLInt()
  1411. END
  1412. END GetImm;
  1413. PROCEDURE ModRm (VAR regArg: IA32RegArg; VAR memOrRegArg: IA32Arg);
  1414. VAR
  1415. byte, mod, base, index, scale, disp : LONGINT;
  1416. newRegArg : IA32RegArg; newMemArg : IA32MemArg;
  1417. BEGIN
  1418. byte := ORD(ReadChar());
  1419. mod := byte DIV 40H;
  1420. NEW(regArg, (byte DIV 8) MOD 8);
  1421. base := byte MOD 8;
  1422. IF mod = 3 THEN (* reg *)
  1423. NEW(newRegArg, base); memOrRegArg := newRegArg
  1424. ELSE
  1425. IF base = 4 THEN (* escape to two bytes *)
  1426. byte := ORD(ReadChar());
  1427. base := byte MOD 8;
  1428. index := (byte DIV 8) MOD 8;
  1429. scale := byte DIV 40H;
  1430. ELSE (* one byte addressing mode *)
  1431. index := none
  1432. END;
  1433. IF mod = 0 THEN (* no displ, or 32 bit address *)
  1434. IF base = 5 THEN (* disp32 *)
  1435. base := none;
  1436. disp := ReadLInt();
  1437. ELSE disp:= 0
  1438. END
  1439. ELSIF mod = 1 THEN (* 8 bit displ *)
  1440. disp := GetImm(1)
  1441. ELSE (* 32 bit displacement *)
  1442. disp := ReadLInt()
  1443. END;
  1444. NEW(newMemArg, base, index, scale, disp); memOrRegArg := newMemArg
  1445. END
  1446. END ModRm;
  1447. PROCEDURE Type1 (opcode: IA32Opcode; baseOp : LONGINT);
  1448. (* type 1: add, or, adc, sbb, and, sub, xor, cmp *)
  1449. VAR
  1450. kind, immWidth : LONGINT;
  1451. regArg : IA32RegArg;
  1452. immArg : IA32ImmArg;
  1453. secondArg : IA32Arg;
  1454. BEGIN
  1455. kind := ORD(opcode.opcodeByte[0]) - baseOp;
  1456. IF kind = 4 THEN
  1457. opcode.argStructure := ArgRegImm; opcode.width:= 0;
  1458. NEW(regArg, AL); opcode.arg1 := regArg;
  1459. NEW(immArg, GetImm(1), RepHex, 1); opcode.arg2 := immArg
  1460. ELSIF kind = 5 THEN
  1461. opcode.argStructure := ArgRegImm; opcode.width := 1;
  1462. NEW(regArg, AX); opcode.arg1 := regArg;
  1463. IF opcode.opPrefix THEN immWidth := 2 ELSE immWidth := 4 END;
  1464. NEW(immArg, GetImm(immWidth), RepHex, immWidth); opcode.arg2 := immArg
  1465. ELSE
  1466. ModRm(regArg, secondArg);
  1467. CASE kind OF
  1468. 0: opcode.width := 0; opcode.argStructure := ArgMemReg; opcode.arg1 := secondArg; opcode.arg2 := regArg
  1469. | 1: opcode.width := 1; opcode.argStructure := ArgMemReg; opcode.arg1 := secondArg; opcode.arg2 := regArg
  1470. | 2: opcode.width := 0; opcode.argStructure := ArgRegMem; opcode.arg1 := regArg; opcode.arg2 := secondArg
  1471. | 3: opcode.width := 1; opcode.argStructure := ArgRegMem; opcode.arg1 := regArg; opcode.arg2 := secondArg
  1472. ELSE HALT(99)
  1473. END;
  1474. IF secondArg IS IA32RegArg THEN opcode.argStructure := ArgRegReg END
  1475. END
  1476. END Type1;
  1477. (* PROCEDURE Add(opcode : IA32Opcode);
  1478. VAR reg, base, inx, d: INTEGER; scale, mode: SHORTINT; disp, imm: LONGINT;
  1479. BEGIN
  1480. Type1(opcode, mode, d, reg, base, inx, scale, disp, imm);
  1481. opcode.instr := opADD
  1482. END Add;
  1483. *)
  1484. PROCEDURE Push (opcode: IA32Opcode);
  1485. VAR immArg : IA32ImmArg; regArg : IA32RegArg;
  1486. BEGIN
  1487. opcode.width:= 1;
  1488. IF opcode.op = 60H THEN
  1489. IF opcode.opPrefix THEN opcode.instr := opPUSHA ELSE opcode.instr := opPUSHAD END;
  1490. ELSIF opcode.op = 68H THEN
  1491. opcode.instr := opPUSH;
  1492. opcode.argStructure := ArgImm;
  1493. IF opcode.opPrefix THEN
  1494. NEW(immArg, ReadInt(), RepInt, 2); HALT(99)
  1495. ELSE
  1496. NEW(immArg, ReadLInt(), RepInt, 4)
  1497. END;
  1498. opcode.arg1 := immArg
  1499. ELSIF opcode.op = 6AH THEN
  1500. opcode.instr := opPUSH;
  1501. opcode.argStructure := ArgImm;
  1502. NEW(immArg, GetImm(1), RepInt, 1);
  1503. opcode.arg1 := immArg
  1504. ELSIF opcode.op = 9CH THEN
  1505. opcode.argStructure := ArgNone;
  1506. IF opcode.opPrefix THEN opcode.instr := opPUSHF ELSE opcode.instr := opPUSHFD END;
  1507. ELSE
  1508. opcode.instr := opPUSH;
  1509. opcode.argStructure := ArgReg;
  1510. CASE opcode.op OF
  1511. 6: NEW(regArg, ES)
  1512. | 0EH: NEW(regArg, CS)
  1513. | 16H: NEW(regArg, SS)
  1514. | 1EH: NEW(regArg, DS)
  1515. | 50H..57H: NEW(regArg, opcode.op - 50H)
  1516. ELSE Bug(opcode.op, 0)
  1517. END;
  1518. opcode.arg1 := regArg
  1519. END
  1520. END Push;
  1521. PROCEDURE Mov (opcode: IA32Opcode);
  1522. VAR
  1523. op, disp, immWidth : LONGINT;
  1524. regArg : IA32RegArg;
  1525. immArg : IA32ImmArg;
  1526. memArg : IA32MemArg;
  1527. secondArg : IA32Arg;
  1528. PROCEDURE CalcImmWidth;
  1529. BEGIN
  1530. IF opcode.width = 0 THEN immWidth := 1
  1531. ELSIF opcode.opPrefix THEN immWidth := 2
  1532. ELSE immWidth := 4
  1533. END
  1534. END CalcImmWidth;
  1535. BEGIN
  1536. op := opcode.op;
  1537. IF (op >= 88H) & (op <= 8BH) THEN
  1538. Type1(opcode, 88H)
  1539. ELSIF (op >= 0B0H) & (op <= 0B7H) THEN
  1540. opcode.argStructure := ArgRegImm; opcode.width := 0;
  1541. NEW(regArg, op - 0B0H); opcode.arg1 := regArg;
  1542. CalcImmWidth;
  1543. NEW(immArg, GetImm(immWidth), RepInt, immWidth); opcode.arg2 := immArg
  1544. ELSIF (op >= 0B8H) & (op <= 0BFH) THEN
  1545. opcode.argStructure := ArgRegImm; opcode.width := 1;
  1546. NEW(regArg, op - 0B8H); opcode.arg1 := regArg;
  1547. CalcImmWidth;
  1548. NEW(immArg, GetImm(immWidth), RepInt, immWidth); opcode.arg2 := immArg
  1549. ELSIF (op >= 0A0H) & (op <= 0A3H) THEN
  1550. IF opcode.adrPrefix THEN
  1551. disp := ReadInt()
  1552. ELSE
  1553. disp := ReadLInt()
  1554. END;
  1555. NEW(memArg, none, none, 1, disp);
  1556. CASE op OF
  1557. 0A0H: opcode.width := 0; opcode.argStructure := ArgRegMem; NEW(regArg, AL); opcode.arg1 := regArg; opcode.arg2 := memArg
  1558. | 0A1H: opcode.width := 1; opcode.argStructure := ArgRegMem; NEW(regArg, AX); opcode.arg1 := regArg; opcode.arg2 := memArg
  1559. | 0A2H: opcode.width := 0; opcode.argStructure := ArgMemReg; NEW(regArg, AL); opcode.arg1 := memArg; opcode.arg2 := regArg
  1560. | 0A3H: opcode.width := 1; opcode.argStructure := ArgMemReg; NEW(regArg, AX); opcode.arg1 := memArg; opcode.arg2 := regArg
  1561. END;
  1562. ELSIF op = 8CH THEN (* mov mem, seg *)
  1563. opcode.width := 1;
  1564. opcode.opPrefix:= TRUE;
  1565. ModRm(regArg, secondArg);
  1566. (* change order according to ModRm output *)
  1567. opcode.arg2 := regArg;
  1568. opcode.arg1 := secondArg;
  1569. IF secondArg IS IA32RegArg THEN
  1570. opcode.argStructure := ArgRegReg
  1571. ELSE
  1572. opcode.argStructure := ArgMemReg
  1573. END;
  1574. INC(opcode.arg2(IA32RegArg).reg, ES) (* reg is a segment register *)
  1575. ELSIF op = 8EH THEN (* mov seg, mem *)
  1576. opcode.width := 1;
  1577. opcode.opPrefix:= TRUE;
  1578. ModRm(regArg, secondArg);
  1579. opcode.arg1 := regArg;
  1580. opcode.arg2 := secondArg;
  1581. IF secondArg IS IA32RegArg THEN
  1582. opcode.argStructure := ArgRegReg
  1583. ELSE
  1584. opcode.argStructure := ArgRegMem
  1585. END;
  1586. INC(opcode.arg1(IA32RegArg).reg, ES) (* reg is segment register *)
  1587. ELSIF (op = 0C6H) OR (op = 0C7H) THEN
  1588. IF op = 0C6H THEN opcode.width := 0; immWidth := 1;
  1589. ELSE
  1590. opcode.width := 1;
  1591. IF opcode.opPrefix THEN immWidth := 2; ELSE immWidth := 4 END
  1592. END;
  1593. ModRm(regArg, secondArg);
  1594. IF secondArg = NIL THEN
  1595. opcode.argStructure := ArgRegImm;
  1596. opcode.arg1 := regArg;
  1597. ELSE
  1598. opcode.argStructure := ArgMemImm;
  1599. opcode.arg1 := secondArg;
  1600. END;
  1601. NEW(immArg, GetImm(immWidth), RepInt, immWidth); opcode.arg2 := immArg
  1602. END;
  1603. opcode.instr := opMOV
  1604. END Mov;
  1605. PROCEDURE Mov2 (opcode : IA32Opcode);
  1606. VAR
  1607. regArg : IA32RegArg;
  1608. secondArg : IA32Arg;
  1609. specialRegArg : IA32SpecialRegArg;
  1610. BEGIN (* Mov2 op codes contains special registers (debug/test/controll) *)
  1611. opcode.instr := opMOV;
  1612. ModRm(regArg, secondArg);
  1613. NEW(specialRegArg, regArg.reg);
  1614. opcode.width := 1;
  1615. CASE opcode.op OF
  1616. 20H: opcode.argStructure := ArgRegReg; specialRegArg.specialKind := SRegCR; opcode.arg1 := secondArg; opcode.arg2 := specialRegArg
  1617. | 21H: opcode.argStructure := ArgRegReg; specialRegArg.specialKind := SRegDR; opcode.arg1 := secondArg; opcode.arg2 := specialRegArg
  1618. | 22H: opcode.argStructure := ArgRegReg; specialRegArg.specialKind := SRegCR; opcode.arg1 := specialRegArg; opcode.arg2 := secondArg
  1619. | 23H: opcode.argStructure := ArgRegReg; specialRegArg.specialKind := SRegDR; opcode.arg1 := specialRegArg; opcode.arg2 := secondArg
  1620. | 24H: opcode.argStructure := ArgRegReg; specialRegArg.specialKind := SRegTR; opcode.arg1 := secondArg; opcode.arg2 := specialRegArg
  1621. | 26H: opcode.argStructure := ArgRegReg; specialRegArg.specialKind := SRegTR; opcode.arg1 := specialRegArg; opcode.arg2 := secondArg
  1622. ELSE Bug(opcode.op, 24)
  1623. END
  1624. END Mov2;
  1625. PROCEDURE Call (opcode : IA32Opcode);
  1626. VAR immArg : IA32ImmArg;
  1627. BEGIN
  1628. IF opcode.op = 0E8H THEN
  1629. opcode.argStructure := ArgImm;
  1630. IF opcode.adrPrefix THEN
  1631. NEW(immArg, GetImm(2), RepRelJmp, 2); opcode.arg1 := immArg
  1632. ELSE
  1633. NEW(immArg, GetImm(4), RepRelJmp, 4); opcode.arg1 := immArg
  1634. END
  1635. END;
  1636. IF opcode.op = 09AH THEN
  1637. HALT(99)
  1638. END;
  1639. opcode.instr := opCALL
  1640. END Call;
  1641. PROCEDURE Pop(opcode : IA32Opcode);
  1642. VAR
  1643. regArg : IA32RegArg;
  1644. secondArg : IA32Arg;
  1645. BEGIN
  1646. IF opcode.op = 61H THEN
  1647. opcode.argStructure := ArgNone;
  1648. IF opcode.opPrefix THEN opcode.instr := opPOPA ELSE opcode.instr := opPOPAD END
  1649. ELSIF opcode.op = 8FH THEN
  1650. IF opcode.opPrefix THEN
  1651. opcode.instr := opPOPWPTR
  1652. ELSE
  1653. opcode.instr := opPOPDWPTR
  1654. END;
  1655. ModRm(regArg, secondArg); opcode.arg1 := regArg; opcode.arg2 := secondArg;
  1656. IF secondArg = NIL THEN opcode.argStructure := ArgReg
  1657. ELSE
  1658. (* ASSERT(secondArg IS IA32MemArg);*)
  1659. IF secondArg IS IA32MemArg THEN
  1660. opcode.argStructure := ArgRegMem
  1661. ELSIF secondArg IS IA32RegArg THEN
  1662. opcode.argStructure := ArgReg
  1663. END;
  1664. END
  1665. ELSIF opcode.op = 9DH THEN
  1666. IF opcode.opPrefix THEN opcode.instr := opPOPF ELSE opcode.instr := opPOPFD END;
  1667. opcode.argStructure := ArgNone
  1668. ELSE
  1669. opcode.instr := opPOP;
  1670. opcode.argStructure := ArgReg;
  1671. opcode.width := 1; (* pop takes only 16 or 32 bit ops *)
  1672. CASE opcode.op OF
  1673. 7: NEW(regArg, ES)
  1674. | 17H: NEW(regArg, SS)
  1675. | 1FH: NEW(regArg, DS)
  1676. | 58H..5FH: NEW(regArg, opcode.op-58H)
  1677. ELSE Bug(opcode.op, 1)
  1678. END;
  1679. opcode.arg1 := regArg
  1680. END
  1681. END Pop;
  1682. PROCEDURE Ret (opcode : IA32Opcode);
  1683. VAR
  1684. immArg : IA32ImmArg;
  1685. BEGIN
  1686. IF (opcode.op = 0C2H) OR (opcode.op = 0CAH) THEN
  1687. NEW(immArg, GetImm(2), RepInt, 2);
  1688. opcode.argStructure := ArgImm; opcode.arg1 := immArg; opcode.instr := opRET
  1689. ELSIF (opcode.op = 0CAH) OR (opcode.op = 0CBH) THEN
  1690. opcode.argStructure := ArgNone; opcode.instr := opRETFAR
  1691. ELSE
  1692. opcode.argStructure := ArgNone; opcode.instr := opRET
  1693. END;
  1694. END Ret;
  1695. PROCEDURE Bound (opcode : IA32Opcode);
  1696. VAR
  1697. regArg : IA32RegArg;
  1698. secondArg : IA32Arg;
  1699. BEGIN
  1700. opcode.width := 1;
  1701. ModRm(regArg, secondArg);
  1702. ASSERT(secondArg IS IA32MemArg);
  1703. opcode.instr := opBOUND;
  1704. opcode.argStructure := ArgRegMem;
  1705. opcode.arg1 := regArg;
  1706. opcode.arg2 := secondArg
  1707. END Bound;
  1708. PROCEDURE Add (opcode : IA32Opcode);
  1709. BEGIN
  1710. Type1(opcode, 0H);
  1711. opcode.instr := opADD
  1712. END Add;
  1713. PROCEDURE Adc (opcode: IA32Opcode);
  1714. BEGIN
  1715. Type1(opcode, 10H);
  1716. opcode.instr := opADC
  1717. END Adc;
  1718. PROCEDURE Sbb (opcode: IA32Opcode);
  1719. BEGIN
  1720. Type1(opcode, 18H);
  1721. opcode.instr := opSBB
  1722. END Sbb;
  1723. PROCEDURE And (opcode: IA32Opcode);
  1724. BEGIN
  1725. Type1(opcode, 20H);
  1726. opcode.instr := opAND
  1727. END And;
  1728. PROCEDURE Or (opcode: IA32Opcode);
  1729. BEGIN
  1730. Type1(opcode, 8H);
  1731. opcode.instr := opOR
  1732. END Or;
  1733. PROCEDURE Sub (opcode: IA32Opcode);
  1734. BEGIN
  1735. Type1(opcode, 28H);
  1736. opcode.instr := opSUB
  1737. END Sub;
  1738. PROCEDURE Xor (opcode: IA32Opcode);
  1739. BEGIN
  1740. Type1(opcode, 30H);
  1741. opcode.instr := opXOR
  1742. END Xor;
  1743. PROCEDURE Cmp (opcode: IA32Opcode);
  1744. BEGIN
  1745. Type1(opcode, 38H);
  1746. opcode.instr := opCMP
  1747. END Cmp ;
  1748. PROCEDURE Inc (opcode: IA32Opcode);
  1749. VAR
  1750. regArg : IA32RegArg;
  1751. BEGIN
  1752. opcode.argStructure := ArgReg;
  1753. NEW(regArg, opcode.op-40H);
  1754. opcode.arg1 := regArg;
  1755. opcode.instr := opINC;
  1756. opcode.width := 1 (* set width to 16/32 bits, bug2 *)
  1757. END Inc;
  1758. PROCEDURE Dec (opcode: IA32Opcode);
  1759. VAR
  1760. regArg : IA32RegArg;
  1761. BEGIN
  1762. opcode.argStructure := ArgReg;
  1763. NEW(regArg, opcode.op-48H);
  1764. opcode.arg1 := regArg;
  1765. opcode.instr := opDEC;
  1766. opcode.width := 1;
  1767. END Dec;
  1768. PROCEDURE Test (opcode : IA32Opcode);
  1769. VAR
  1770. regArg : IA32RegArg;
  1771. secondArg : IA32Arg;
  1772. immArg : IA32ImmArg;
  1773. BEGIN
  1774. IF (opcode.op = 0A8H) OR (opcode.op = 0A9H) THEN
  1775. opcode.argStructure := ArgRegImm;
  1776. IF opcode.op = 0A8H THEN
  1777. opcode.width := 0;
  1778. NEW(regArg, AL)
  1779. ELSE
  1780. opcode.width := 1;
  1781. NEW(regArg, AX)
  1782. END;
  1783. opcode.arg1 := regArg;
  1784. IF opcode.width = 0 THEN NEW(immArg, GetImm(1), RepInt, 1)
  1785. ELSE
  1786. IF opcode.opPrefix THEN NEW(immArg, GetImm(2), RepInt, 2)
  1787. ELSE NEW(immArg, GetImm(4), RepInt, 4)
  1788. END
  1789. END;
  1790. opcode.arg2 := immArg
  1791. ELSE
  1792. ModRm(regArg, secondArg);
  1793. IF secondArg IS IA32MemArg THEN
  1794. opcode.argStructure := ArgMemReg;
  1795. opcode.arg1 := secondArg;
  1796. opcode.arg2 := regArg
  1797. ELSE
  1798. opcode.argStructure := ArgRegReg;
  1799. opcode.arg1 := secondArg;
  1800. opcode.arg2 := regArg
  1801. END;
  1802. IF opcode.op = 84H THEN opcode.width := 0
  1803. ELSE opcode.width := 1
  1804. END
  1805. END;
  1806. opcode.instr := opTEST
  1807. END Test;
  1808. PROCEDURE Lea (opcode: IA32Opcode);
  1809. VAR
  1810. regArg : IA32RegArg;
  1811. secondArg : IA32Arg;
  1812. BEGIN
  1813. opcode.width := 1;
  1814. opcode.instr := opLEA;
  1815. ModRm(regArg, secondArg);
  1816. ASSERT(secondArg IS IA32MemArg);
  1817. opcode.argStructure := ArgRegMem;
  1818. opcode.arg1 := regArg;
  1819. opcode.arg2 := secondArg;
  1820. END Lea;
  1821. PROCEDURE Les (opcode : IA32Opcode);
  1822. VAR
  1823. regArg : IA32RegArg;
  1824. secondArg : IA32Arg;
  1825. BEGIN
  1826. opcode.width := 1;
  1827. opcode.instr := opLES;
  1828. ModRm(regArg, secondArg);
  1829. ASSERT(secondArg IS IA32MemArg);
  1830. opcode.argStructure := ArgRegMem;
  1831. opcode.arg1 := regArg;
  1832. opcode.arg2 := secondArg;
  1833. END Les;
  1834. PROCEDURE Lds (opcode : IA32Opcode);
  1835. VAR
  1836. regArg : IA32RegArg;
  1837. secondArg : IA32Arg;
  1838. BEGIN
  1839. opcode.width := 1;
  1840. opcode.instr := opLDS;
  1841. ModRm(regArg, secondArg);
  1842. ASSERT(secondArg IS IA32MemArg);
  1843. opcode.argStructure := ArgRegMem;
  1844. opcode.arg1 := regArg;
  1845. opcode.arg2 := secondArg;
  1846. END Lds;
  1847. PROCEDURE Bit (opcode: IA32Opcode);
  1848. VAR
  1849. regArg : IA32RegArg;
  1850. secondArg : IA32Arg;
  1851. isReg : BOOLEAN;
  1852. BEGIN
  1853. opcode.width := 1;
  1854. ModRm(regArg, secondArg);
  1855. IF secondArg IS IA32RegArg THEN isReg := TRUE ELSE isReg := FALSE END;
  1856. CASE opcode.op OF
  1857. 0A3H: opcode.instr := opBT
  1858. | 0ABH: opcode.instr := opBTS
  1859. | 0B3H: opcode.instr := opBTR
  1860. | 0BBH: opcode.instr := opBTC
  1861. | 0BCH: opcode.instr := opBSF
  1862. | 0BDH: opcode.instr := opBSR
  1863. END;
  1864. IF (opcode.op = 0BCH) OR (opcode.op = 0BDH) THEN
  1865. (* change direction *)
  1866. opcode.arg2 := secondArg;
  1867. opcode.arg1 := regArg;
  1868. IF isReg THEN opcode.argStructure := ArgRegReg
  1869. ELSE opcode.argStructure := ArgRegMem
  1870. END
  1871. ELSE
  1872. opcode.arg2 := regArg;
  1873. opcode.arg1 := secondArg;
  1874. IF isReg THEN opcode.argStructure := ArgRegReg
  1875. ELSE opcode.argStructure := ArgMemReg
  1876. END
  1877. END
  1878. END Bit;
  1879. PROCEDURE Shift (opcode: IA32Opcode);
  1880. VAR
  1881. regArg : IA32RegArg;
  1882. secondArg : IA32Arg;
  1883. immArg : IA32ImmArg;
  1884. BEGIN
  1885. ModRm(regArg, secondArg);
  1886. opcode.arg1 := secondArg;
  1887. opcode.arg2 := regArg;
  1888. IF (opcode.op = 0A4H) OR (opcode.op = 0ACH) THEN (* immediate byte *)
  1889. NEW(immArg, GetImm(1), RepInt, 1);
  1890. opcode.arg3 := immArg;
  1891. IF secondArg IS IA32RegArg THEN opcode.argStructure := ArgRegRegImm
  1892. ELSE opcode.argStructure := ArgMemRegImm
  1893. END
  1894. ELSE
  1895. NEW(regArg, CL);
  1896. regArg.width := 1;
  1897. opcode.arg3 := regArg;
  1898. IF secondArg IS IA32RegArg THEN opcode.argStructure := ArgRegRegReg
  1899. ELSE opcode.argStructure := ArgMemRegReg
  1900. END
  1901. END;
  1902. IF (opcode.op = 0A4H) OR (opcode.op = 0A5H) THEN opcode.instr := opSHLD
  1903. ELSIF (opcode.op = 0ACH) OR (opcode.op = 0ADH) THEN opcode.instr := opSHRD
  1904. ELSE Bug(opcode.op, 20)
  1905. END;
  1906. opcode.width := 1
  1907. END Shift;
  1908. PROCEDURE Enter (opcode : IA32Opcode);
  1909. VAR
  1910. immArg : IA32ImmArg;
  1911. BEGIN
  1912. opcode.instr := opENTER;
  1913. opcode.argStructure := ArgImmImm;
  1914. NEW(immArg, GetImm(2), RepInt, 2);
  1915. opcode.arg1 := immArg;
  1916. NEW(immArg, GetImm(1), RepInt, 1);
  1917. opcode.arg2 := immArg
  1918. END Enter;
  1919. PROCEDURE Jmp (opcode : IA32Opcode);
  1920. VAR
  1921. immArg : IA32ImmArg;
  1922. BEGIN
  1923. IF (opcode.op = 0E9H) OR (opcode.op = 0EAH) THEN
  1924. NEW(immArg, GetImm(4), RepRelJmp, 4)
  1925. ELSE
  1926. NEW(immArg, GetImm(1), RepRelJmp, 1)
  1927. END;
  1928. IF opcode.op = 0EAH THEN opcode.instr := opJMPFAR ELSE opcode.instr := opJMP END;
  1929. opcode.argStructure := ArgImm;
  1930. opcode.arg1 := immArg
  1931. END Jmp;
  1932. PROCEDURE InOut (opcode : IA32Opcode);
  1933. VAR
  1934. port: LONGINT;
  1935. in, dx: BOOLEAN;
  1936. dataRegArg, portRegArg : IA32RegArg;
  1937. portImmArg : IA32ImmArg;
  1938. BEGIN
  1939. in := opcode.op MOD 4 < 2;
  1940. dx := opcode.op MOD 16 >= 8;
  1941. NEW(dataRegArg, EAX);
  1942. IF ~dx THEN
  1943. port := ORD(ReadChar());
  1944. NEW(portImmArg, port, RepInt, 1)
  1945. ELSE
  1946. NEW(portRegArg, DX)
  1947. END;
  1948. IF in THEN opcode.instr := opIN
  1949. ELSE opcode.instr := opOUT
  1950. END;
  1951. IF ODD(opcode.op) THEN opcode.width := 1 ELSE opcode.width := 0 END;
  1952. IF in THEN
  1953. opcode.arg1 := dataRegArg;
  1954. IF dx THEN
  1955. opcode.argStructure := ArgRegReg;
  1956. opcode.arg2 := portRegArg
  1957. ELSE
  1958. opcode.argStructure := ArgRegImm;
  1959. opcode.arg2 := portImmArg
  1960. END
  1961. ELSE
  1962. opcode.arg2 := dataRegArg;
  1963. IF dx THEN
  1964. opcode.argStructure := ArgRegReg;
  1965. opcode.arg1 := portRegArg
  1966. ELSE
  1967. opcode.argStructure := ArgImmReg;
  1968. opcode.arg1 := portImmArg
  1969. END
  1970. END
  1971. END InOut;
  1972. PROCEDURE Jcc (opcode : IA32Opcode);
  1973. VAR
  1974. immArg : IA32ImmArg;
  1975. BEGIN
  1976. NEW(immArg, GetImm(1), RepRelJmp, 1);
  1977. IF immArg.imm >= 128 THEN immArg.imm := immArg.imm - 256 END;
  1978. opcode.argStructure := ArgImm;
  1979. opcode.arg1 := immArg;
  1980. CASE opcode.op OF
  1981. 70H: opcode.instr := opJO
  1982. | 71H: opcode.instr := opJNO
  1983. | 72H: opcode.instr := opJB
  1984. | 73H: opcode.instr := opJNB
  1985. | 74H: opcode.instr := opJZ
  1986. | 75H: opcode.instr := opJNZ
  1987. | 76H: opcode.instr := opJBE
  1988. | 77H: opcode.instr := opJNBE
  1989. | 78H: opcode.instr := opJS
  1990. | 79H: opcode.instr := opJNS
  1991. | 7AH: opcode.instr := opJP
  1992. | 7BH: opcode.instr := opJNP
  1993. | 7CH: opcode.instr := opJL
  1994. | 7DH: opcode.instr := opJNL
  1995. | 7EH: opcode.instr := opJLE
  1996. | 7FH: opcode.instr := opJNLE
  1997. ELSE Bug(opcode.op, 2)
  1998. END
  1999. END Jcc;
  2000. PROCEDURE Jcc2 (opcode : IA32Opcode);
  2001. VAR
  2002. immArg : IA32ImmArg;
  2003. BEGIN
  2004. IF opcode.adrPrefix THEN
  2005. NEW(immArg, GetImm(2), RepRelJmp, 2);
  2006. ELSE
  2007. NEW(immArg, GetImm(4), RepRelJmp, 4);
  2008. END;
  2009. opcode.argStructure := ArgImm;
  2010. opcode.arg1 := immArg;
  2011. CASE opcode.op OF
  2012. 80H: opcode.instr := opJO
  2013. | 81H: opcode.instr := opJNO
  2014. | 82H: opcode.instr := opJB
  2015. | 83H: opcode.instr := opJNB
  2016. | 84H: opcode.instr := opJZ
  2017. | 85H: opcode.instr := opJNZ
  2018. | 86H: opcode.instr := opJBE
  2019. | 87H: opcode.instr := opJNBE
  2020. | 88H: opcode.instr := opJS
  2021. | 89H: opcode.instr := opJNS
  2022. | 8AH: opcode.instr := opJP
  2023. | 8BH: opcode.instr := opJNP
  2024. | 8CH: opcode.instr := opJL
  2025. | 8DH: opcode.instr := opJNL
  2026. | 8EH: opcode.instr := opJLE
  2027. | 8FH: opcode.instr := opJNLE
  2028. ELSE Bug(opcode.op, 3)
  2029. END
  2030. END Jcc2;
  2031. PROCEDURE Loop (opcode : IA32Opcode);
  2032. VAR immArg: IA32ImmArg;
  2033. BEGIN
  2034. NEW(immArg, GetImm(1), RepInt, 1);
  2035. opcode.argStructure := ArgImm;
  2036. opcode.arg1 := immArg;
  2037. CASE opcode.op OF
  2038. 0E0H: opcode.instr := opLOOPNE
  2039. | 0E1H: opcode.instr := opLOOPE
  2040. | 0E2H: opcode.instr := opLOOP
  2041. | 0E3H: IF opcode.adrPrefix THEN opcode.instr := opJCXZ ELSE opcode.instr := opJECXZ END
  2042. ELSE Bug(opcode.op, 4)
  2043. END
  2044. END Loop;
  2045. PROCEDURE Lar (opcode : IA32Opcode);
  2046. VAR
  2047. regArg : IA32RegArg;
  2048. secondArg : IA32Arg;
  2049. BEGIN
  2050. ModRm(regArg, secondArg); opcode.arg1 := secondArg;
  2051. ASSERT(secondArg IS IA32MemArg);
  2052. opcode.instr := opLAR
  2053. END Lar;
  2054. PROCEDURE Lsl (opcode : IA32Opcode);
  2055. VAR
  2056. regArg : IA32RegArg;
  2057. secondArg : IA32Arg;
  2058. BEGIN
  2059. ModRm(regArg, secondArg); opcode.arg1 := secondArg;
  2060. ASSERT(secondArg IS IA32MemArg);
  2061. opcode.instr := opLSL
  2062. END Lsl;
  2063. PROCEDURE Setcc (opcode : IA32Opcode);
  2064. VAR
  2065. regArg : IA32RegArg;
  2066. secondArg : IA32Arg;
  2067. BEGIN
  2068. opcode.width := 0; (* always 8 bit wide *)
  2069. ModRm(regArg, secondArg);
  2070. opcode.arg1 := secondArg;
  2071. CASE opcode.op OF
  2072. 90H: opcode.instr := opSETO
  2073. | 91H: opcode.instr := opSETNO
  2074. | 92H: opcode.instr := opSETB
  2075. | 93H: opcode.instr := opSETNB
  2076. | 94H: opcode.instr := opSETZ
  2077. | 95H: opcode.instr := opSETNZ
  2078. | 96H: opcode.instr := opSETBE
  2079. | 97H: opcode.instr := opSETNBE
  2080. | 98H: opcode.instr := opSETS
  2081. | 99H: opcode.instr := opSETNS
  2082. | 9AH: opcode.instr := opSETP
  2083. | 9BH: opcode.instr := opSETNP
  2084. | 9CH: opcode.instr := opSETL
  2085. | 9DH: opcode.instr := opSETNL
  2086. | 9EH: opcode.instr := opSETLE
  2087. | 9FH: opcode.instr := opSETNLE
  2088. ELSE Bug(opcode.op, 5)
  2089. END;
  2090. IF secondArg IS IA32RegArg THEN
  2091. opcode.argStructure := ArgReg
  2092. ELSE
  2093. opcode.argStructure := ArgReg
  2094. END
  2095. END Setcc;
  2096. PROCEDURE Int (opcode : IA32Opcode);
  2097. VAR immArg : IA32ImmArg;
  2098. BEGIN
  2099. IF opcode.op = 0CDH THEN
  2100. NEW(immArg, GetImm(1), RepInt, 1)
  2101. ELSE NEW(immArg, 3, RepInt, 1)
  2102. END;
  2103. opcode.argStructure := ArgImm;
  2104. opcode.arg1 := immArg;
  2105. opcode.instr := opINT
  2106. END Int;
  2107. PROCEDURE Movs (opcode : IA32Opcode);
  2108. BEGIN
  2109. opcode.argStructure := ArgNone;
  2110. IF opcode.op = 0A4H THEN opcode.instr := opMOVSB
  2111. ELSIF (opcode.op = 0A5H) & opcode.opPrefix THEN opcode.instr := opMOVSW
  2112. ELSIF opcode.op = 0A5H THEN opcode.instr := opMOVSD
  2113. ELSE Bug(opcode.op, 6)
  2114. END
  2115. END Movs;
  2116. PROCEDURE Movx(opcode: IA32Opcode);
  2117. VAR
  2118. regArg : IA32RegArg;
  2119. secondArg : IA32Arg;
  2120. byteArg : BOOLEAN;
  2121. BEGIN
  2122. byteArg := (opcode.op = 0B6H) OR (opcode.op = 0BEH);
  2123. ModRm(regArg, secondArg);
  2124. opcode.arg1 := regArg; opcode.arg2 := secondArg;
  2125. IF (opcode.op = 0B6H) OR (opcode.op = 0B7H) THEN opcode.instr := opMOVZX;
  2126. ELSE opcode.instr := opMOVSX;
  2127. END;
  2128. opcode.width := 1;
  2129. IF secondArg IS IA32RegArg THEN
  2130. opcode.argStructure := ArgRegReg;
  2131. IF byteArg THEN
  2132. opcode.width := 0
  2133. ELSE
  2134. secondArg(IA32RegArg).width := 2
  2135. END
  2136. ELSE
  2137. opcode.argStructure := ArgRegMem;
  2138. ASSERT(secondArg IS IA32MemArg);
  2139. IF byteArg THEN secondArg(IA32MemArg).bytePtr := TRUE
  2140. ELSE secondArg(IA32MemArg).wordPtr := TRUE
  2141. END
  2142. END
  2143. END Movx;
  2144. PROCEDURE Cmps (opcode : IA32Opcode);
  2145. BEGIN
  2146. opcode.argStructure := ArgNone;
  2147. IF opcode.op = 0A6H THEN opcode.instr := opCMPSB
  2148. ELSIF (opcode.op = 0A7H) & opcode.opPrefix THEN opcode.instr := opCMPSB
  2149. ELSIF opcode.op = 0A7H THEN opcode.instr := opCMPSW
  2150. ELSE Bug(opcode.op, 7)
  2151. END
  2152. END Cmps;
  2153. PROCEDURE Stos (opcode : IA32Opcode);
  2154. BEGIN
  2155. opcode.argStructure := ArgNone;
  2156. IF opcode.op = 0AAH THEN opcode.instr := opSTOSB;
  2157. ELSIF (opcode.op = 0ABH) & opcode.opPrefix THEN opcode.instr := opSTOSW
  2158. ELSIF opcode.op = 0ABH THEN opcode.instr := opSTOSD
  2159. ELSE Bug(opcode.op, 8)
  2160. END
  2161. END Stos;
  2162. PROCEDURE Lods (opcode : IA32Opcode);
  2163. BEGIN
  2164. opcode.argStructure := ArgNone;
  2165. IF opcode.op = 0ACH THEN opcode.instr := opLODSB
  2166. ELSIF opcode.op = 0ADH THEN
  2167. IF opcode.opPrefix THEN opcode.instr := opLODSW ELSE opcode.instr := opLODSD END
  2168. ELSE Bug(opcode.op, 9)
  2169. END
  2170. END Lods;
  2171. PROCEDURE Scas (opcode : IA32Opcode);
  2172. BEGIN
  2173. opcode.argStructure := ArgNone;
  2174. IF opcode.op = 0AEH THEN opcode.instr := opSCASB
  2175. ELSIF (opcode.op = 0AFH) & opcode.opPrefix THEN opcode.instr := opSCASW
  2176. ELSIF opcode.op = 0AFH THEN opcode.instr := opSCASD
  2177. ELSE Bug(opcode.op, 10)
  2178. END
  2179. END Scas;
  2180. PROCEDURE Imul (opcode : IA32Opcode);
  2181. VAR
  2182. regArg : IA32RegArg;
  2183. secondArg : IA32Arg;
  2184. immArg : IA32ImmArg;
  2185. BEGIN
  2186. opcode.width := 1;
  2187. ModRm(regArg, secondArg);
  2188. opcode.instr := opIMUL;
  2189. opcode.arg1 := regArg;
  2190. opcode.arg2 := secondArg;
  2191. IF opcode.op = 69H THEN
  2192. NEW(immArg, GetImm(4), RepInt, 4);
  2193. ELSIF opcode.op = 6BH THEN NEW(immArg, GetImm(1), RepInt, 2) (* sign extended *)
  2194. END;
  2195. IF opcode.op = 0AFH THEN
  2196. IF secondArg IS IA32RegArg THEN
  2197. opcode.argStructure := ArgRegReg
  2198. ELSIF secondArg IS IA32MemArg THEN
  2199. opcode.argStructure := ArgRegMem
  2200. END
  2201. ELSE
  2202. IF secondArg IS IA32RegArg THEN
  2203. opcode.argStructure := ArgRegRegImm
  2204. ELSE
  2205. ASSERT(secondArg IS IA32MemArg);
  2206. opcode.argStructure := ArgRegMemImm
  2207. END;
  2208. opcode.arg3 := immArg
  2209. END
  2210. END Imul;
  2211. PROCEDURE Ins (opcode : IA32Opcode);
  2212. BEGIN
  2213. opcode.argStructure := ArgNone;
  2214. IF opcode.op = 6CH THEN opcode.instr := opINSB
  2215. ELSIF opcode.opPrefix THEN opcode.instr := opINSW
  2216. ELSE opcode.instr := opINSD
  2217. END
  2218. END Ins;
  2219. PROCEDURE Outs (opcode : IA32Opcode);
  2220. BEGIN
  2221. opcode.argStructure := ArgNone;
  2222. IF opcode.op = 6EH THEN opcode.instr := opOUTSB
  2223. ELSIF opcode.opPrefix THEN opcode.instr := opOUTSW
  2224. ELSE opcode.instr := opOUTSD
  2225. END
  2226. END Outs;
  2227. PROCEDURE Xchg (opcode : IA32Opcode);
  2228. VAR
  2229. regArg : IA32RegArg;
  2230. secondArg : IA32Arg;
  2231. BEGIN
  2232. opcode.instr := opXCHG;
  2233. IF (opcode.op >= 91H) & (opcode.op <= 97H) THEN (* xchg .ax, reg *)
  2234. opcode.width := 1;
  2235. opcode.argStructure := ArgRegReg;
  2236. NEW(regArg, EAX);
  2237. opcode.arg1 := regArg;
  2238. NEW(regArg, opcode.op MOD 8);
  2239. opcode.arg2 := regArg;
  2240. ELSE
  2241. ModRm(regArg, secondArg);
  2242. IF opcode.op = 86H THEN opcode.width := 0
  2243. ELSE opcode.width := 1
  2244. END;
  2245. opcode.arg1 := regArg;
  2246. opcode.arg2 := secondArg;
  2247. IF secondArg IS IA32RegArg THEN
  2248. opcode.argStructure := ArgRegReg
  2249. ELSE
  2250. opcode.argStructure := ArgRegMem
  2251. END
  2252. END
  2253. END Xchg;
  2254. PROCEDURE MP (opcode : IA32Opcode);
  2255. VAR
  2256. regArg : IA32RegArg;
  2257. arg : IA32Arg;
  2258. BEGIN
  2259. ModRm(regArg, arg);
  2260. CASE regArg.reg OF
  2261. 0 : opcode.instr := opFXSAVE
  2262. | 1 : opcode.instr := opFXRSTOR
  2263. | 2 : opcode.instr := opLDMXCSR
  2264. | 3 : opcode.instr := opSTMXCSR
  2265. | 5 : opcode.instr := opLFENCE
  2266. | 6 : opcode.instr := opMFENCE
  2267. | 7 : opcode.instr := opSFENCE
  2268. END;
  2269. IF arg IS IA32RegArg THEN
  2270. opcode.argStructure := ArgNone
  2271. ELSE
  2272. opcode.argStructure := ArgMem;
  2273. opcode.arg1 := arg;
  2274. IF regArg.reg = 7 THEN opcode.instr := opCLFLUSH END
  2275. END
  2276. END MP;
  2277. PROCEDURE Grp1 (opcode : IA32Opcode);
  2278. VAR
  2279. regArg : IA32RegArg;
  2280. secondArg : IA32Arg;
  2281. immArg : IA32ImmArg;
  2282. BEGIN
  2283. ModRm(regArg, secondArg);
  2284. IF opcode.op = 80H THEN
  2285. opcode.width := 0;
  2286. NEW(immArg, GetImm(1), RepInt, 1);
  2287. ELSIF opcode.op = 81H THEN
  2288. opcode.width := 1;
  2289. IF opcode.opPrefix THEN NEW(immArg, GetImm(2), RepInt, 2) ELSE NEW(immArg, GetImm(4), RepInt, 4) END
  2290. ELSE (* opcode.op = 83H, signed extends *)
  2291. opcode.width := 1;
  2292. NEW(immArg, GetImm(1), RepInt, 1);
  2293. END;
  2294. CASE regArg.reg OF
  2295. 0: opcode.instr := opADD
  2296. | 1: opcode.instr := opOR
  2297. | 2: opcode.instr := opADC
  2298. | 3: opcode.instr := opSBB
  2299. | 4: opcode.instr := opAND
  2300. | 5: opcode.instr := opSUB
  2301. | 6: opcode.instr := opXOR
  2302. | 7: opcode.instr := opCMP
  2303. ELSE Bug(opcode.op, 11)
  2304. END;
  2305. IF secondArg IS IA32RegArg THEN
  2306. opcode.argStructure := ArgRegImm
  2307. ELSIF secondArg IS IA32MemArg THEN
  2308. opcode.argStructure := ArgMemImm
  2309. END;
  2310. opcode.arg1 := secondArg;
  2311. opcode.arg2 := immArg;
  2312. IF (regArg.reg = 1) OR (regArg.reg = 4) OR (regArg.reg = 6) THEN immArg.rep := RepHex END
  2313. END Grp1;
  2314. PROCEDURE Grp2 (opcode : IA32Opcode);
  2315. VAR
  2316. regArg, newRegArg : IA32RegArg;
  2317. arg: IA32Arg;
  2318. immArg : IA32ImmArg;
  2319. BEGIN
  2320. ModRm(regArg, arg); opcode.arg1 := arg;
  2321. CASE opcode.op OF
  2322. 0D0H : opcode.width := 0
  2323. | 0D1H : opcode.width := 1
  2324. | 0D2H : opcode.width := 0
  2325. | 0D3H : opcode.width := 1
  2326. | 0C0H : opcode.width := 0
  2327. | 0C1H : opcode.width := 1
  2328. END;
  2329. IF (opcode.op = 0C0H) OR (opcode.op = 0C1H) THEN
  2330. NEW(immArg, GetImm(1), RepInt, 1); (* only 8 bit possible *)
  2331. IF arg IS IA32RegArg THEN opcode.argStructure := ArgRegImm
  2332. ELSE opcode.argStructure := ArgMemImm
  2333. END;
  2334. opcode.arg2 := immArg
  2335. ELSE
  2336. IF (opcode.op = 0D0H) OR (opcode.op = 0D1H) THEN
  2337. IF arg IS IA32RegArg THEN opcode.argStructure := ArgRegImm
  2338. ELSE opcode.argStructure := ArgMemImm END;
  2339. NEW(immArg, 1, RepInt, 1);
  2340. opcode.arg2 := immArg;
  2341. ELSIF (opcode.op = 0D2H) OR (opcode.op = 0D3H) THEN
  2342. IF arg IS IA32RegArg THEN opcode.argStructure := ArgRegReg
  2343. ELSE opcode.argStructure := ArgMemReg END;
  2344. NEW(newRegArg, CL);
  2345. newRegArg.width := 1;
  2346. opcode.arg2 := newRegArg
  2347. END
  2348. END;
  2349. CASE regArg.reg OF
  2350. 0: opcode.instr := opROL
  2351. | 1: opcode.instr := opROR
  2352. | 2: opcode.instr := opRCL
  2353. | 3: opcode.instr := opRCR
  2354. | 4: opcode.instr := opSHL
  2355. | 5: opcode.instr := opSHR
  2356. | 7: opcode.instr := opSAR
  2357. ELSE Bug(opcode.op, 12)
  2358. END
  2359. END Grp2;
  2360. PROCEDURE Grp3 (opcode : IA32Opcode);
  2361. VAR
  2362. regArg : IA32RegArg;
  2363. secondArg : IA32Arg;
  2364. immArg : IA32ImmArg;
  2365. BEGIN
  2366. ModRm(regArg, secondArg); opcode.arg1 := secondArg;
  2367. IF opcode.op = 0F6H THEN opcode.width := 0
  2368. ELSE opcode.width := 1
  2369. END;
  2370. IF regArg.reg = 0 (* test *) THEN
  2371. IF opcode.width = 0 THEN NEW(immArg, GetImm(1), RepInt, 1)
  2372. ELSE
  2373. IF opcode.opPrefix THEN NEW(immArg, GetImm(2), RepInt, 2)
  2374. ELSE NEW(immArg, GetImm(4), RepInt, 4)
  2375. END
  2376. END;
  2377. opcode.arg2 := immArg;
  2378. IF secondArg IS IA32RegArg THEN opcode.argStructure := ArgRegImm
  2379. ELSE opcode.argStructure := ArgMemImm
  2380. END
  2381. ELSE
  2382. IF secondArg IS IA32RegArg THEN opcode.argStructure := ArgReg
  2383. ELSE opcode.argStructure := ArgMem
  2384. END
  2385. END;
  2386. CASE regArg.reg OF
  2387. 0: opcode.instr := opTEST
  2388. | 2: opcode.instr := opNOT
  2389. | 3: opcode.instr := opNEG
  2390. | 4: opcode.instr := opMUL
  2391. | 5: opcode.instr := opIMUL
  2392. | 6: opcode.instr := opDIV
  2393. | 7: opcode.instr := opIDIV
  2394. ELSE Bug(opcode.op, 13)
  2395. END;
  2396. END Grp3;
  2397. PROCEDURE Grp4 (opcode : IA32Opcode);
  2398. VAR
  2399. regArg : IA32RegArg;
  2400. secondArg : IA32Arg;
  2401. BEGIN
  2402. opcode.width := 0;
  2403. ModRm(regArg, secondArg); opcode.arg1 := secondArg;
  2404. IF regArg.reg = 0 THEN opcode.instr := opINC
  2405. ELSE opcode.instr := opDEC
  2406. END;
  2407. IF secondArg IS IA32MemArg THEN
  2408. opcode.argStructure := ArgMem;
  2409. secondArg(IA32MemArg).bytePtr := TRUE
  2410. ELSE
  2411. opcode.argStructure := ArgReg
  2412. END
  2413. END Grp4;
  2414. PROCEDURE Grp5 (opcode: IA32Opcode);
  2415. VAR
  2416. regArg : IA32RegArg;
  2417. arg : IA32Arg;
  2418. BEGIN
  2419. opcode.width := 1;
  2420. ModRm(regArg, arg); opcode.arg1 := arg;
  2421. IF regArg.reg = 0 THEN opcode.instr := opINC
  2422. ELSIF regArg.reg = 1 THEN opcode.instr := opDEC
  2423. ELSIF regArg.reg = 2 THEN opcode.instr := opCALL
  2424. ELSIF regArg.reg = 3 THEN opcode.instr := opCALLFAR
  2425. ELSIF regArg.reg = 4 THEN opcode.instr := opJMP
  2426. ELSIF regArg.reg = 5 THEN opcode.instr := opJMPFAR
  2427. ELSIF regArg.reg = 6 THEN opcode.instr := opPUSH
  2428. ELSE Bug(regArg.reg, 14)
  2429. END;
  2430. IF arg IS IA32MemArg THEN
  2431. opcode.argStructure := ArgMem
  2432. ELSE
  2433. opcode.argStructure := ArgReg
  2434. END
  2435. END Grp5;
  2436. PROCEDURE Grp6 (opcode: IA32Opcode);
  2437. VAR
  2438. regArg : IA32RegArg;
  2439. secondArg : IA32Arg;
  2440. BEGIN
  2441. opcode.width := 1;
  2442. ModRm(regArg, secondArg); opcode.arg1 := secondArg;
  2443. CASE regArg.reg OF
  2444. | 0: opcode.instr := opSLDT
  2445. | 1: opcode.instr := opSTR
  2446. | 2: opcode.instr := opLLDT
  2447. | 3: opcode.instr := opLTR
  2448. | 4: opcode.instr := opVERR
  2449. | 6: opcode.instr := opVERW
  2450. ELSE Bug(opcode.op, 15)
  2451. END;
  2452. IF secondArg IS IA32RegArg THEN opcode.argStructure := ArgReg
  2453. ELSE opcode.argStructure := ArgMem
  2454. END
  2455. END Grp6;
  2456. PROCEDURE Grp7 (opcode: IA32Opcode);
  2457. VAR
  2458. regArg : IA32RegArg;
  2459. secondArg : IA32Arg;
  2460. BEGIN
  2461. opcode.width := 1;
  2462. ModRm(regArg, secondArg); opcode.arg1 := secondArg;
  2463. CASE regArg.reg OF
  2464. | 0: opcode.instr := opSGDT
  2465. | 1: opcode.instr := opSIDT
  2466. | 2: opcode.instr := opLGDT
  2467. | 3: opcode.instr := opLIDT
  2468. | 4: opcode.instr := opSMSW
  2469. | 6: opcode.instr := opLMSW
  2470. | 7: opcode.instr := opINVLPG
  2471. ELSE Bug(opcode.op, 16)
  2472. END;
  2473. IF secondArg IS IA32RegArg THEN opcode.argStructure := ArgReg
  2474. ELSE opcode.argStructure := ArgMem
  2475. END
  2476. END Grp7;
  2477. PROCEDURE Grp8 (opcode: IA32Opcode);
  2478. VAR
  2479. regArg : IA32RegArg;
  2480. secondArg : IA32Arg;
  2481. immArg : IA32ImmArg;
  2482. BEGIN
  2483. opcode.width := 1;
  2484. ModRm(regArg, secondArg); opcode.arg1 := secondArg;
  2485. NEW(immArg, GetImm(1), RepInt, 1); opcode.arg2 := immArg;
  2486. CASE regArg.reg OF
  2487. 4: opcode.instr := opBT
  2488. | 5: opcode.instr := opBTS
  2489. | 6: opcode.instr := opBTR
  2490. | 7: opcode.instr := opBTC
  2491. ELSE Bug(opcode.op, 17)
  2492. END;
  2493. IF secondArg IS IA32RegArg THEN opcode.argStructure := ArgRegImm
  2494. ELSE opcode.argStructure := ArgMemImm
  2495. END
  2496. END Grp8;
  2497. PROCEDURE Grp9 (opcode: IA32Opcode);
  2498. VAR
  2499. regArg : IA32RegArg;
  2500. secondArg : IA32Arg;
  2501. BEGIN
  2502. opcode.width := 1;
  2503. ModRm(regArg, secondArg); opcode.arg1 := secondArg;
  2504. ASSERT(secondArg IS IA32MemArg);
  2505. CASE regArg.reg OF
  2506. 1: opcode.instr := opCMPXCHG8B
  2507. ELSE Bug(opcode.op, 18)
  2508. END;
  2509. opcode.argStructure := ArgMem
  2510. END Grp9;
  2511. PROCEDURE Float0 (opcode: IA32Opcode); (* op is 0D8H *)
  2512. VAR
  2513. statArg : IA32RegArg;
  2514. secondArg : IA32Arg;
  2515. fpReg : IA32SpecialRegArg;
  2516. BEGIN
  2517. ModRm(statArg, secondArg);
  2518. IF secondArg IS IA32MemArg THEN (* memory *)
  2519. opcode.argStructure := ArgMem;
  2520. opcode.arg1 := secondArg;
  2521. secondArg(IA32MemArg).fpSize := FPSizeSingle;
  2522. CASE statArg.reg OF
  2523. 0: opcode.instr := opFADD
  2524. | 1: opcode.instr := opFMUL
  2525. | 2: opcode.instr := opFCOM
  2526. | 3: opcode.instr := opFCOMP
  2527. | 4: opcode.instr := opFSUB
  2528. | 5: opcode.instr := opFSUBR
  2529. | 6: opcode.instr := opFDIV
  2530. | 7: opcode.instr := opFDIVR
  2531. ELSE Bug(statArg.reg, 25)
  2532. END
  2533. ELSE
  2534. opcode.argStructure := ArgReg;
  2535. NEW(fpReg, secondArg(IA32RegArg).reg);
  2536. fpReg.specialKind := SRegFP;
  2537. CASE statArg.reg OF
  2538. 0: opcode.instr := opFADD
  2539. | 1: opcode.instr := opFMUL
  2540. | 2: opcode.instr := opFCOM
  2541. | 3: opcode.instr := opFCOMP
  2542. | 4: opcode.instr := opFSUB
  2543. | 5: opcode.instr := opFSUBR
  2544. | 6: opcode.instr := opFDIV
  2545. | 7: opcode.instr := opFDIVR
  2546. ELSE Bug(statArg.reg, 26)
  2547. END
  2548. END
  2549. END Float0;
  2550. PROCEDURE Float1 (opcode : IA32Opcode); (* op is 0D9H *)
  2551. VAR
  2552. statArg : IA32RegArg;
  2553. secondArg : IA32Arg;
  2554. stat : LONGINT;
  2555. BEGIN
  2556. ModRm(statArg, secondArg);
  2557. IF secondArg IS IA32MemArg THEN
  2558. opcode.argStructure := ArgMem;
  2559. opcode.arg1 := secondArg;
  2560. CASE statArg.reg OF
  2561. 0: opcode.instr := opFLD
  2562. | 2: opcode.instr := opFST
  2563. | 3: opcode.instr := opFSTP
  2564. | 4: opcode.instr := opFLDENV
  2565. | 5: opcode.instr := opFLDCW
  2566. | 6: opcode.instr := opFNSTENV
  2567. | 7: opcode.instr := opFNSTCW
  2568. ELSE Bug(statArg.reg, 23)
  2569. END
  2570. ELSIF statArg.reg = 0 THEN
  2571. opcode.argStructure := ArgReg;
  2572. opcode.arg1 := secondArg;
  2573. opcode.instr := opFLD
  2574. ELSIF statArg.reg = 1 THEN
  2575. opcode.argStructure := ArgReg;
  2576. opcode.arg1 := secondArg;
  2577. opcode.instr := opFXCH
  2578. ELSE
  2579. stat:= statArg.reg * 8 + secondArg(IA32RegArg).reg;
  2580. IF stat = 10H THEN opcode.instr := opFNOP
  2581. ELSE
  2582. CASE stat OF
  2583. 20H: opcode.instr := opFCHS
  2584. | 21H: opcode.instr := opFABS
  2585. | 24H: opcode.instr := opFTST
  2586. | 25H: opcode.instr := opFXAM
  2587. | 28H: opcode.instr := opFLD1
  2588. | 29H: opcode.instr := opFLDL2T
  2589. | 2AH: opcode.instr := opFLDL2E
  2590. | 2BH: opcode.instr := opFLDPI
  2591. | 2CH: opcode.instr := opFLDLG2
  2592. | 2DH: opcode.instr := opFLDLN2
  2593. | 2EH: opcode.instr := opFLDZ
  2594. | 30H: opcode.instr := opF2XM1
  2595. | 31H: opcode.instr := opFYL2X
  2596. | 32H: opcode.instr := opFPTAN
  2597. | 33H: opcode.instr := opFPATAN
  2598. | 34H: opcode.instr := opFXTRACT
  2599. | 35H: opcode.instr := opFPREM1
  2600. | 36H: opcode.instr := opFDECSTP
  2601. | 37H: opcode.instr := opFINCSTP
  2602. | 38H: opcode.instr := opFPREM
  2603. | 39H: opcode.instr := opFYL2XP1
  2604. | 3AH: opcode.instr := opFSQRT
  2605. | 3BH: opcode.instr := opFSINCOS
  2606. | 3CH: opcode.instr := opFRNDINT
  2607. | 3DH: opcode.instr := opFSCALE
  2608. | 3EH: opcode.instr := opFSIN
  2609. | 3FH: opcode.instr := opFCOS
  2610. ELSE Bug(stat, 23)
  2611. END
  2612. END
  2613. END
  2614. END Float1;
  2615. PROCEDURE Float2 (opcode : IA32Opcode); (* op is 0DAH *)
  2616. VAR setting : IA32RegArg;
  2617. arg : IA32Arg;
  2618. BEGIN
  2619. ModRm(setting, arg);
  2620. IF arg IS IA32MemArg THEN
  2621. opcode.argStructure := ArgMem;
  2622. opcode.arg1 := arg;
  2623. CASE setting.reg OF
  2624. 0: opcode.instr := opFIADD
  2625. | 1: opcode.instr := opFIMUL
  2626. | 2: opcode.instr := opFICOM
  2627. | 3: opcode.instr := opFICOMP
  2628. | 4: opcode.instr := opFISUB
  2629. | 5: opcode.instr := opFISUBR
  2630. | 6: opcode.instr := opFIDIV
  2631. | 7: opcode.instr := opFIDIVR
  2632. ELSE Bug(setting.reg, 27)
  2633. END
  2634. ELSIF setting.reg = 5 THEN
  2635. opcode.argStructure := ArgNone;
  2636. opcode.instr := opFUCOMPP
  2637. ELSE Bug(setting.reg, 27)
  2638. END
  2639. END Float2;
  2640. PROCEDURE Float3 (opcode : IA32Opcode); (* op is 0DBH *)
  2641. VAR
  2642. setting : IA32RegArg;
  2643. arg : IA32Arg;
  2644. BEGIN
  2645. ModRm(setting, arg);
  2646. IF arg IS IA32MemArg THEN
  2647. opcode.argStructure := ArgMem;
  2648. opcode.arg1 := arg;
  2649. CASE setting.reg OF
  2650. 0: opcode.instr := opFILD
  2651. | 2: opcode.instr := opFIST
  2652. | 3: opcode.instr := opFISTP
  2653. | 5: opcode.instr := opFLD
  2654. | 7: opcode.instr := opFSTP
  2655. ELSE Bug(setting.reg, 21)
  2656. END
  2657. ELSE
  2658. opcode.argStructure := ArgNone;
  2659. IF arg(IA32RegArg).reg = 2 THEN opcode.instr := opFNCLEX
  2660. ELSIF arg(IA32RegArg).reg = 3 THEN opcode.instr := opFNINIT
  2661. ELSE Bug(arg(IA32RegArg).reg, 22)
  2662. END
  2663. END
  2664. END Float3;
  2665. PROCEDURE Float4 (opcode : IA32Opcode); (* op is 0DCH *)
  2666. VAR
  2667. setting : IA32RegArg;
  2668. arg : IA32Arg;
  2669. BEGIN
  2670. ModRm(setting, arg);
  2671. opcode.arg1 := arg;
  2672. IF arg IS IA32MemArg THEN
  2673. opcode.argStructure := ArgMem;
  2674. CASE setting.reg OF
  2675. 0: opcode.instr := opFADD
  2676. | 1: opcode.instr := opFMUL
  2677. | 2: opcode.instr := opFCOM
  2678. | 3: opcode.instr := opFCOMP
  2679. | 4: opcode.instr := opFSUB
  2680. | 5: opcode.instr := opFSUBR
  2681. | 6: opcode.instr := opFDIV
  2682. | 7: opcode.instr := opFDIVR
  2683. ELSE Bug(setting.reg, 34)
  2684. END
  2685. ELSE
  2686. opcode.argStructure := ArgReg;
  2687. CASE setting.reg OF
  2688. 0: opcode.instr := opFADD
  2689. | 1: opcode.instr := opFMUL
  2690. | 4: opcode.instr := opFSUBR
  2691. | 5: opcode.instr := opFSUB
  2692. | 6: opcode.instr := opFDIVR
  2693. | 7: opcode.instr := opFDIV
  2694. ELSE Bug(setting.reg, 35)
  2695. END
  2696. END
  2697. END Float4;
  2698. PROCEDURE Float5 (opcode : IA32Opcode); (* op is 0DDH *)
  2699. VAR
  2700. setting : IA32RegArg;
  2701. arg : IA32Arg;
  2702. BEGIN
  2703. ModRm(setting, arg);
  2704. opcode.arg1:= arg;
  2705. IF arg IS IA32MemArg THEN
  2706. opcode.argStructure := ArgMem;
  2707. CASE setting.reg OF
  2708. 0: opcode.instr := opFLD
  2709. | 2: opcode.instr := opFST
  2710. | 3: opcode.instr := opFSTP
  2711. | 4: opcode.instr := opFRSTOR
  2712. | 6: opcode.instr := opFNSAVE
  2713. | 7: opcode.instr := opFNSTSW
  2714. ELSE Bug(setting.reg, 29)
  2715. END
  2716. ELSE
  2717. opcode.argStructure := ArgReg;
  2718. CASE setting.reg OF
  2719. 0: opcode.instr := opFFREE
  2720. | 2: opcode.instr := opFST
  2721. | 3: opcode.instr := opFSTP
  2722. | 4: opcode.instr := opFUCOM
  2723. | 5: opcode.instr := opFUCOMP
  2724. ELSE Bug(setting.reg, 30)
  2725. END
  2726. END
  2727. END Float5;
  2728. PROCEDURE Float6(opcode : IA32Opcode); (* op is 0DEH *)
  2729. VAR
  2730. setting : IA32RegArg;
  2731. arg : IA32Arg;
  2732. BEGIN
  2733. ModRm(setting, arg);
  2734. opcode.arg1 := arg;
  2735. IF arg IS IA32MemArg THEN
  2736. opcode.argStructure := ArgMem;
  2737. CASE setting.reg OF
  2738. 0: opcode.instr := opFIADD
  2739. | 1: opcode.instr := opFIMUL
  2740. | 2: opcode.instr := opFICOM
  2741. | 3: opcode.instr := opFICOMP
  2742. | 4: opcode.instr := opFISUB
  2743. | 5: opcode.instr := opFISUBR
  2744. | 6: opcode.instr := opFIDIV
  2745. | 7: opcode.instr := opFIDIVR
  2746. ELSE Bug(setting.reg, 31)
  2747. END
  2748. ELSE
  2749. opcode.argStructure := ArgReg;
  2750. CASE setting.reg OF
  2751. 0: opcode.instr := opFADDP
  2752. | 1: opcode.instr := opFMULP
  2753. | 3: opcode.instr := opFCOMPP
  2754. | 4: opcode.instr := opFSUBRP
  2755. | 5: opcode.instr := opFSUBP
  2756. | 6: opcode.instr := opFDIVRP
  2757. | 7: opcode.instr := opFDIVP
  2758. ELSE Bug(setting.reg, 32)
  2759. END;
  2760. END
  2761. END Float6;
  2762. PROCEDURE Float7(opcode : IA32Opcode); (* op is 0DFH *)
  2763. VAR
  2764. setting : IA32RegArg;
  2765. arg : IA32Arg;
  2766. BEGIN
  2767. ModRm(setting, arg);
  2768. opcode.arg1 := arg;
  2769. IF arg IS IA32MemArg THEN
  2770. opcode.argStructure := ArgMem;
  2771. CASE setting.reg OF
  2772. 0, 5: opcode.instr := opFILD
  2773. | 2: opcode.instr := opFIST
  2774. | 3, 7: opcode.instr := opFISTP
  2775. | 4: opcode.instr := opFBLD
  2776. | 6: opcode.instr := opFBSTP
  2777. ELSE Bug(setting.reg, 33)
  2778. END
  2779. ELSIF setting.reg = 4 THEN
  2780. opcode.argStructure := ArgReg;
  2781. opcode.arg1(IA32RegArg).reg := AX;
  2782. opcode.arg1(IA32RegArg).width := 2;
  2783. opcode.instr := opFNSTSW
  2784. ELSE Bug(setting.reg, 33)
  2785. END
  2786. END Float7;
  2787. PROCEDURE Cmov (opcode : IA32Opcode);
  2788. VAR
  2789. regArg : IA32RegArg;
  2790. secondArg : IA32Arg;
  2791. BEGIN
  2792. ModRm(regArg, secondArg);
  2793. opcode.arg1 := regArg;
  2794. opcode.arg2 := secondArg;
  2795. opcode.width := 1;
  2796. IF secondArg IS IA32RegArg THEN opcode.argStructure := ArgRegReg
  2797. ELSE opcode.argStructure := ArgRegMem
  2798. END;
  2799. CASE opcode.op OF
  2800. 40H: opcode.instr := opCMOVO
  2801. | 41H: opcode.instr := opCMOVNO
  2802. | 42H: opcode.instr := opCMOVB
  2803. | 43H: opcode.instr := opCMOVNB
  2804. | 44H: opcode.instr := opCMOVZ
  2805. | 45H: opcode.instr := opCMOVNZ
  2806. | 46H: opcode.instr := opCMOVBE
  2807. | 47H: opcode.instr := opCMOVNBE
  2808. | 48H: opcode.instr := opCMOVS
  2809. | 49H: opcode.instr := opCMOVNS
  2810. | 4AH: opcode.instr := opCMOVP
  2811. | 4BH: opcode.instr := opCMOVNP
  2812. | 4CH: opcode.instr := opCMOVL
  2813. | 4DH: opcode.instr := opCMOVNL
  2814. | 4EH: opcode.instr := opCMOVLE
  2815. | 4FH: opcode.instr := opCMOVNLE
  2816. ELSE Bug(opcode.op, 28)
  2817. END
  2818. END Cmov;
  2819. PROCEDURE PushPop2 (opcode : IA32Opcode);
  2820. VAR regArg : IA32RegArg; reg : LONGINT;
  2821. BEGIN
  2822. CASE opcode.op OF
  2823. 0A0H: opcode.instr := opPUSH; reg := FS
  2824. | 0A1H: opcode.instr := opPOP; reg := FS
  2825. | 0A8H: opcode.instr := opPUSH; reg := GS
  2826. | 0A9H: opcode.instr := opPOP; reg := GS
  2827. ELSE Bug(opcode.op, 35)
  2828. END;
  2829. NEW(regArg, reg);
  2830. opcode.argStructure := ArgReg;
  2831. opcode.arg1 := regArg
  2832. END PushPop2;
  2833. PROCEDURE Cmpxchg (opcode : IA32Opcode);
  2834. VAR
  2835. regArg : IA32RegArg;
  2836. arg : IA32Arg;
  2837. BEGIN
  2838. opcode.instr := opCMPXCHG;
  2839. ModRm(regArg, arg);
  2840. opcode.arg1 := arg;
  2841. opcode.arg2 := regArg;
  2842. IF opcode.op = 0B1H THEN opcode.width := 1
  2843. ELSE opcode.width := 0
  2844. END;
  2845. IF arg IS IA32RegArg THEN
  2846. opcode.argStructure := ArgRegReg
  2847. ELSE
  2848. opcode.argStructure := ArgMemReg
  2849. END
  2850. END Cmpxchg;
  2851. PROCEDURE Ldseg (opcode : IA32Opcode);
  2852. VAR
  2853. regArg : IA32RegArg;
  2854. arg2 : IA32Arg;
  2855. BEGIN
  2856. ModRm(regArg, arg2);
  2857. IF opcode.op = 0B2H THEN opcode.instr := opLSS
  2858. ELSIF opcode.op = 0B4H THEN opcode.instr := opLFS
  2859. ELSE opcode.instr := opLGS
  2860. END;
  2861. opcode.argStructure := ArgRegMem;
  2862. opcode.arg1 := regArg;
  2863. opcode.arg2 := arg2;
  2864. END Ldseg;
  2865. PROCEDURE Xadd (opcode : IA32Opcode);
  2866. VAR
  2867. regArg : IA32RegArg;
  2868. arg : IA32Arg;
  2869. BEGIN
  2870. ModRm(regArg, arg);
  2871. opcode.instr := opXADD;
  2872. opcode.arg1 := arg;
  2873. opcode.arg2 := regArg;
  2874. IF opcode.op = 0C1H THEN opcode.width := 1
  2875. ELSE opcode.width := 0
  2876. END;
  2877. IF arg IS IA32RegArg THEN
  2878. opcode.argStructure := ArgRegReg
  2879. ELSE
  2880. opcode.argStructure := ArgMemReg
  2881. END
  2882. END Xadd;
  2883. PROCEDURE Bswap (opcode : IA32Opcode);
  2884. VAR regArg : IA32RegArg;
  2885. BEGIN
  2886. opcode.instr := opBSWAP;
  2887. NEW(regArg, opcode.op-0C8H);
  2888. opcode.argStructure := ArgReg;
  2889. opcode.arg1 := regArg
  2890. END Bswap;
  2891. PROCEDURE Escape (opcode : IA32Opcode);
  2892. BEGIN
  2893. opcode.op := ORD(ReadChar());
  2894. CASE opcode.op OF
  2895. 0:
  2896. Grp6(opcode)
  2897. | 1:
  2898. Grp7(opcode)
  2899. | 2:
  2900. Lar(opcode)
  2901. | 3:
  2902. Lsl(opcode)
  2903. | 6:
  2904. opcode.argStructure := ArgNone;
  2905. opcode.instr := opCLTS
  2906. | 8:
  2907. opcode.argStructure := ArgNone;
  2908. opcode.instr := opINVD
  2909. | 9:
  2910. opcode.instr := opWBINVD
  2911. | 20H..24H, 26H:
  2912. Mov2(opcode)
  2913. | 30H:
  2914. opcode.argStructure := ArgNone;
  2915. opcode.instr := opWRMSR
  2916. | 31H:
  2917. opcode.argStructure := ArgNone;
  2918. opcode.instr := opRDTSC
  2919. | 32H:
  2920. opcode.argStructure := ArgNone;
  2921. opcode.instr := opRDMSR
  2922. | 33H:
  2923. opcode.argStructure := ArgNone;
  2924. opcode.instr := opRDPMC
  2925. | 40H..4FH:
  2926. Cmov(opcode)
  2927. | 80H..8FH:
  2928. Jcc2(opcode)
  2929. | 90H..9FH:
  2930. Setcc(opcode)
  2931. | 0A0H, 0A1H, 0A8H, 0A9H:
  2932. PushPop2(opcode)
  2933. | 0A2H:
  2934. opcode.argStructure := ArgNone;
  2935. opcode.instr := opCPUID
  2936. | 0A3H, 0ABH, 0B3H, 0BBH..0BDH:
  2937. Bit(opcode)
  2938. | 0A4H, 0A5H, 0ACH, 0ADH:
  2939. Shift(opcode)
  2940. | 0AEH:
  2941. MP(opcode)
  2942. | 0AFH:
  2943. Imul(opcode)
  2944. | 0B0H,0B1H:
  2945. Cmpxchg(opcode)
  2946. | 0B2H, 0B4H, 0B5H:
  2947. Ldseg(opcode)
  2948. | 0B6H, 0B7H, 0BEH, 0BFH:
  2949. Movx(opcode)
  2950. | 0BAH:
  2951. Grp8(opcode)
  2952. | 0C0H,0C1H:
  2953. Xadd(opcode)
  2954. | 0C7H:
  2955. Grp9(opcode)
  2956. | 0C8H..0CFH:
  2957. Bswap(opcode)
  2958. ELSE Bug(opcode.op, 19)
  2959. END
  2960. END Escape;
  2961. PROCEDURE DecodeThis(opcode : Decoder.Opcode);
  2962. VAR
  2963. op : IA32Opcode;
  2964. BEGIN
  2965. op := opcode(IA32Opcode);
  2966. DoPrefixes(op);
  2967. op.op := ORD(op.opcodeByte[0]);
  2968. (*
  2969. KernelLog.String("op.op = "); KernelLog.Hex(op.op, 0); KernelLog.Ln;
  2970. *)
  2971. CASE op.op OF
  2972. 0..5:
  2973. Add(op);
  2974. | 6, 0EH, 16H, 1EH:
  2975. Push(op)
  2976. | 7, 17H, 1FH:
  2977. Pop(op)
  2978. | 8..0DH:
  2979. Or(op)
  2980. | 0FH:
  2981. Escape(op)
  2982. | 10H..15H:
  2983. Adc(op)
  2984. | 18H..1DH:
  2985. Sbb(op)
  2986. | 20H..25H:
  2987. And(op)
  2988. | 27H:
  2989. op.argStructure := ArgNone;
  2990. op.instr := opDAA;
  2991. | 28H..2DH:
  2992. Sub(op)
  2993. | 2FH:
  2994. op.argStructure := ArgNone;
  2995. op.instr := opDAS;
  2996. | 30H..35H:
  2997. Xor(op)
  2998. | 37H:
  2999. op.argStructure := ArgNone;
  3000. op.instr := opAAA;
  3001. | 38H..3DH:
  3002. Cmp(op)
  3003. | 3FH:
  3004. op.argStructure := ArgNone;
  3005. op.instr := opAAS;
  3006. | 40H..47H:
  3007. Inc(op)
  3008. | 48H..4FH:
  3009. Dec(op)
  3010. | 50H..57H, 60H, 68H, 6AH:
  3011. Push(op)
  3012. | 58H..5FH, 61H:
  3013. Pop(op)
  3014. | 62H:
  3015. Bound(op)
  3016. | 69H, 6BH:
  3017. Imul(op)
  3018. | 6CH, 6DH:
  3019. Ins(op)
  3020. | 6EH, 06FH:
  3021. Outs(op)
  3022. | 70H..7FH:
  3023. Jcc(op)
  3024. | 80H..81H, 83H:
  3025. Grp1(op)
  3026. | 84H..85H:
  3027. Test(op)
  3028. | 86H..87H, 91H..97H:
  3029. Xchg(op)
  3030. | 88H..8CH, 8EH, 0A0H..0A3H, 0B0H..0BFH:
  3031. Mov(op)
  3032. | 8DH:
  3033. Lea(op)
  3034. | 8FH, 9DH:
  3035. Pop(op)
  3036. | 90H:
  3037. op.argStructure := ArgNone;
  3038. op.instr := opNOP;
  3039. | 98H:
  3040. op.argStructure := ArgNone;
  3041. IF op.opPrefix THEN op.instr := opCBW ELSE op.instr := opCWDE END
  3042. | 99H:
  3043. op.argStructure := ArgNone;
  3044. IF op.opPrefix THEN op.instr := opCWD ELSE op.instr := opCDQ END
  3045. | 9AH:
  3046. Call(op)
  3047. | 9BH:
  3048. op.argStructure := ArgNone;
  3049. op.instr := opWAIT;
  3050. opcodeBeforeWait := previousOpcode (* WAIT hack *)
  3051. | 9CH:
  3052. Push(op)
  3053. | 9EH:
  3054. op.argStructure := ArgNone;
  3055. op.instr := opSAHF;
  3056. | 9FH:
  3057. op.argStructure := ArgNone;
  3058. op.instr := opLAHF;
  3059. | 0A4H..0A5H:
  3060. Movs(op)
  3061. | 0A6H..0A7H:
  3062. Cmps(op)
  3063. | 0A8H..0A9H:
  3064. Test(op)
  3065. | 0AAH..0ABH:
  3066. Stos(op)
  3067. | 0ACH..0ADH:
  3068. Lods(op)
  3069. | 0AEH..0AFH:
  3070. Scas(op)
  3071. | 0C0H..0C1H:
  3072. Grp2(op)
  3073. | 0C2H..0C3H, 0CAH, 0CBH:
  3074. Ret(op)
  3075. | 0C4H:
  3076. Les(op)
  3077. | 0C5H:
  3078. Lds(op)
  3079. | 0C6H..0C7H:
  3080. Mov(op)
  3081. | 0C8H:
  3082. Enter(op)
  3083. | 0C9H:
  3084. op.argStructure := ArgNone;
  3085. op.instr := opLEAVE;
  3086. | 0CCH..0CDH:
  3087. Int(op)
  3088. | 0CEH:
  3089. op.argStructure := ArgNone;
  3090. op.instr := opINTO;
  3091. | 0CFH:
  3092. op.argStructure := ArgNone;
  3093. op.instr := opIRET;
  3094. | 0D0H..0D3H:
  3095. Grp2(op)
  3096. | 0D4H:
  3097. op.argStructure := ArgNone;
  3098. opcode.instr := opAAM;
  3099. | 0D5H:
  3100. op.argStructure := ArgNone;
  3101. opcode.instr := opAAD;
  3102. | 0D7H:
  3103. op.argStructure := ArgNone;
  3104. op.instr := opXLAT;
  3105. | 0D8H:
  3106. Float0(op)
  3107. | 0D9H, 0D6H:
  3108. Float1(op)
  3109. | 0DAH:
  3110. Float2(op)
  3111. | 0DBH:
  3112. Float3(op)
  3113. | 0DCH:
  3114. Float4(op)
  3115. | 0DDH:
  3116. Float5(op)
  3117. | 0DEH:
  3118. Float6(op)
  3119. | 0DFH:
  3120. Float7(op)
  3121. | 0E0H..0E3H:
  3122. Loop(op) (* and jcxz *)
  3123. | 0E4H..0E7H, 0ECH..0EFH:
  3124. InOut(op)
  3125. | 0E8H:
  3126. Call(op)
  3127. | 0E9H..0EBH:
  3128. Jmp(op)
  3129. | 0F0H:
  3130. op.argStructure := ArgNone;
  3131. op.instr := opLOCK
  3132. | 0F2H:
  3133. op.argStructure := ArgNone;
  3134. op.instr := opREPNE
  3135. | 0F4H:
  3136. op.argStructure := ArgNone;
  3137. op.instr := opHLT
  3138. | 0F5H:
  3139. op.argStructure := ArgNone;
  3140. op.instr := opCMC
  3141. | 0F6H..0F7H:
  3142. Grp3(op)
  3143. | 0F8H:
  3144. op.argStructure := ArgNone;
  3145. op.instr := opCLC
  3146. | 0F9H:
  3147. op.argStructure := ArgNone;
  3148. op.instr := opSTC
  3149. | 0FAH:
  3150. op.argStructure := ArgNone;
  3151. op.instr := opCLI
  3152. | 0FBH:
  3153. op.argStructure := ArgNone;
  3154. op.instr := opSTI
  3155. | 0FCH:
  3156. op.argStructure := ArgNone;
  3157. op.instr := opCLD
  3158. | 0FDH:
  3159. op.argStructure := ArgNone;
  3160. op.instr := opSTD
  3161. | 0FEH:
  3162. Grp4(op)
  3163. | 0FFH:
  3164. Grp5(op)
  3165. ELSE
  3166. KernelLog.String("Opcode not recognized: "); KernelLog.Hex(ORD(op.opcodeByte[0]), -1); KernelLog.Ln;
  3167. Bug (op.op, 37);
  3168. END;
  3169. (* WAIT hack *)
  3170. IF (op.instr # opWAIT) & (opcodeBeforeWait # NIL) THEN
  3171. IF (op.instr = opFNCLEX) OR (op.instr = opFNSTSW) OR (op.instr = opFNSTENV) OR
  3172. (op.instr = opFNSTCW) OR (op.instr = opFNSAVE) OR (op.instr = opFNINIT) THEN
  3173. opcodeBeforeWait.next := op; (* remove WAIT opcode *)
  3174. InsertBytesAtBufferHead(previousOpcode.code); (* insert WAIT opcode bytes into this opcode *)
  3175. DEC(op.instr) (* set opFxxx to opFNxxx instead *)
  3176. END;
  3177. opcodeBeforeWait := NIL
  3178. END;
  3179. previousOpcode := op
  3180. (* end of WAIT hack *)
  3181. END DecodeThis;
  3182. PROCEDURE NewOpcode() :Decoder. Opcode;
  3183. VAR
  3184. opcode : IA32Opcode;
  3185. BEGIN
  3186. NEW(opcode, currentProc, outputStreamWriter);
  3187. opcode.decoder := SELF;
  3188. RETURN opcode
  3189. END NewOpcode;
  3190. END IA32Decoder;
  3191. VAR
  3192. PROCEDURE IntToHex(h, width: LONGINT; VAR s: ARRAY OF CHAR);
  3193. VAR c: CHAR;
  3194. BEGIN
  3195. IF (width <= 0) THEN width := 8 END;
  3196. ASSERT(LEN(s) > width);
  3197. s[width] := 0X;
  3198. DEC(width);
  3199. WHILE (width >= 0) DO
  3200. c := CHR(h MOD 10H + ORD("0"));
  3201. IF (c > "9") THEN c := CHR((h MOD 10H - 10) + ORD("A")) END;
  3202. s[width] := c; h := h DIV 10H; DEC(width)
  3203. END
  3204. END IntToHex;
  3205. PROCEDURE IA32DecoderFactory (reader : Streams.Reader) : Decoder.Decoder;
  3206. VAR
  3207. ia32Decoder : IA32Decoder;
  3208. BEGIN
  3209. KernelLog.String("IA32DecoderFactory"); KernelLog.Ln;
  3210. NEW(ia32Decoder, reader);
  3211. RETURN ia32Decoder
  3212. END IA32DecoderFactory;
  3213. PROCEDURE Init*;
  3214. BEGIN
  3215. Decoder.RegisterDecoder(objFileSuffix, IA32DecoderFactory, NIL);
  3216. Decoder.RegisterDecoder("Obw", IA32DecoderFactory, NIL);
  3217. Decoder.RegisterDecoder("Obj", IA32DecoderFactory, NIL); (* fld for UnixAos *)
  3218. END Init;
  3219. END I386Decoder.
  3220. I386Decoder.Open TV.Obx~
  3221. SystemTools.Free I386Decoder ~