ops.c 141 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438
  1. /****************************************************************************
  2. * Realmode X86 Emulator Library
  3. *
  4. * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
  5. * Jason Jin <Jason.jin@freescale.com>
  6. *
  7. * Copyright (C) 1991-2004 SciTech Software, Inc.
  8. * Copyright (C) David Mosberger-Tang
  9. * Copyright (C) 1999 Egbert Eich
  10. *
  11. * ========================================================================
  12. *
  13. * Permission to use, copy, modify, distribute, and sell this software and
  14. * its documentation for any purpose is hereby granted without fee,
  15. * provided that the above copyright notice appear in all copies and that
  16. * both that copyright notice and this permission notice appear in
  17. * supporting documentation, and that the name of the authors not be used
  18. * in advertising or publicity pertaining to distribution of the software
  19. * without specific, written prior permission. The authors makes no
  20. * representations about the suitability of this software for any purpose.
  21. * It is provided "as is" without express or implied warranty.
  22. *
  23. * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  24. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  25. * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  26. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  27. * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  28. * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  29. * PERFORMANCE OF THIS SOFTWARE.
  30. *
  31. * ========================================================================
  32. *
  33. * Language: ANSI C
  34. * Environment: Any
  35. * Developer: Kendall Bennett
  36. *
  37. * Description: This file includes subroutines to implement the decoding
  38. * and emulation of all the x86 processor instructions.
  39. *
  40. * There are approximately 250 subroutines in here, which correspond
  41. * to the 256 byte-"opcodes" found on the 8086. The table which
  42. * dispatches this is found in the files optab.[ch].
  43. *
  44. * Each opcode proc has a comment preceeding it which gives it's table
  45. * address. Several opcodes are missing (undefined) in the table.
  46. *
  47. * Each proc includes information for decoding (DECODE_PRINTF and
  48. * DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
  49. * functions (START_OF_INSTR, END_OF_INSTR).
  50. *
  51. * Many of the procedures are *VERY* similar in coding. This has
  52. * allowed for a very large amount of code to be generated in a fairly
  53. * short amount of time (i.e. cut, paste, and modify). The result is
  54. * that much of the code below could have been folded into subroutines
  55. * for a large reduction in size of this file. The downside would be
  56. * that there would be a penalty in execution speed. The file could
  57. * also have been *MUCH* larger by inlining certain functions which
  58. * were called. This could have resulted even faster execution. The
  59. * prime directive I used to decide whether to inline the code or to
  60. * modularize it, was basically: 1) no unnecessary subroutine calls,
  61. * 2) no routines more than about 200 lines in size, and 3) modularize
  62. * any code that I might not get right the first time. The fetch_*
  63. * subroutines fall into the latter category. The The decode_* fall
  64. * into the second category. The coding of the "switch(mod){ .... }"
  65. * in many of the subroutines below falls into the first category.
  66. * Especially, the coding of {add,and,or,sub,...}_{byte,word}
  67. * subroutines are an especially glaring case of the third guideline.
  68. * Since so much of the code is cloned from other modules (compare
  69. * opcode #00 to opcode #01), making the basic operations subroutine
  70. * calls is especially important; otherwise mistakes in coding an
  71. * "add" would represent a nightmare in maintenance.
  72. *
  73. * Jason ported this file to u-boot. place all the function pointer in
  74. * the got2 sector. Removed some opcode.
  75. *
  76. ****************************************************************************/
  77. #include <common.h>
  78. #if defined(CONFIG_BIOSEMU)
  79. #include "x86emu/x86emui.h"
  80. /*----------------------------- Implementation ----------------------------*/
  81. /* constant arrays to do several instructions in just one function */
  82. #ifdef DEBUG
  83. static char *x86emu_GenOpName[8] = {
  84. "ADD", "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP"};
  85. #endif
  86. /* used by several opcodes */
  87. static u8 (*genop_byte_operation[])(u8 d, u8 s) __attribute__ ((section(GOT2_TYPE))) =
  88. {
  89. add_byte, /* 00 */
  90. or_byte, /* 01 */
  91. adc_byte, /* 02 */
  92. sbb_byte, /* 03 */
  93. and_byte, /* 04 */
  94. sub_byte, /* 05 */
  95. xor_byte, /* 06 */
  96. cmp_byte, /* 07 */
  97. };
  98. static u16 (*genop_word_operation[])(u16 d, u16 s) __attribute__ ((section(GOT2_TYPE))) =
  99. {
  100. add_word, /*00 */
  101. or_word, /*01 */
  102. adc_word, /*02 */
  103. sbb_word, /*03 */
  104. and_word, /*04 */
  105. sub_word, /*05 */
  106. xor_word, /*06 */
  107. cmp_word, /*07 */
  108. };
  109. static u32 (*genop_long_operation[])(u32 d, u32 s) __attribute__ ((section(GOT2_TYPE))) =
  110. {
  111. add_long, /*00 */
  112. or_long, /*01 */
  113. adc_long, /*02 */
  114. sbb_long, /*03 */
  115. and_long, /*04 */
  116. sub_long, /*05 */
  117. xor_long, /*06 */
  118. cmp_long, /*07 */
  119. };
  120. /* used by opcodes 80, c0, d0, and d2. */
  121. static u8(*opcD0_byte_operation[])(u8 d, u8 s) __attribute__ ((section(GOT2_TYPE))) =
  122. {
  123. rol_byte,
  124. ror_byte,
  125. rcl_byte,
  126. rcr_byte,
  127. shl_byte,
  128. shr_byte,
  129. shl_byte, /* sal_byte === shl_byte by definition */
  130. sar_byte,
  131. };
  132. /* used by opcodes c1, d1, and d3. */
  133. static u16(*opcD1_word_operation[])(u16 s, u8 d) __attribute__ ((section(GOT2_TYPE))) =
  134. {
  135. rol_word,
  136. ror_word,
  137. rcl_word,
  138. rcr_word,
  139. shl_word,
  140. shr_word,
  141. shl_word, /* sal_byte === shl_byte by definition */
  142. sar_word,
  143. };
  144. /* used by opcodes c1, d1, and d3. */
  145. static u32 (*opcD1_long_operation[])(u32 s, u8 d) __attribute__ ((section(GOT2_TYPE))) =
  146. {
  147. rol_long,
  148. ror_long,
  149. rcl_long,
  150. rcr_long,
  151. shl_long,
  152. shr_long,
  153. shl_long, /* sal_byte === shl_byte by definition */
  154. sar_long,
  155. };
  156. #ifdef DEBUG
  157. static char *opF6_names[8] =
  158. { "TEST\t", "", "NOT\t", "NEG\t", "MUL\t", "IMUL\t", "DIV\t", "IDIV\t" };
  159. #endif
  160. /****************************************************************************
  161. PARAMETERS:
  162. op1 - Instruction op code
  163. REMARKS:
  164. Handles illegal opcodes.
  165. ****************************************************************************/
  166. void x86emuOp_illegal_op(
  167. u8 op1)
  168. {
  169. START_OF_INSTR();
  170. if (M.x86.R_SP != 0) {
  171. DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
  172. TRACE_REGS();
  173. DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
  174. M.x86.R_CS, M.x86.R_IP-1,op1));
  175. HALT_SYS();
  176. }
  177. else {
  178. /* If we get here, it means the stack pointer is back to zero
  179. * so we are just returning from an emulator service call
  180. * so therte is no need to display an error message. We trap
  181. * the emulator with an 0xF1 opcode to finish the service
  182. * call.
  183. */
  184. X86EMU_halt_sys();
  185. }
  186. END_OF_INSTR();
  187. }
  188. /****************************************************************************
  189. REMARKS:
  190. Handles opcodes 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
  191. ****************************************************************************/
  192. void x86emuOp_genop_byte_RM_R(u8 op1)
  193. {
  194. int mod, rl, rh;
  195. uint destoffset;
  196. u8 *destreg, *srcreg;
  197. u8 destval;
  198. op1 = (op1 >> 3) & 0x7;
  199. START_OF_INSTR();
  200. DECODE_PRINTF(x86emu_GenOpName[op1]);
  201. DECODE_PRINTF("\t");
  202. FETCH_DECODE_MODRM(mod, rh, rl);
  203. if(mod<3)
  204. { destoffset = decode_rmXX_address(mod,rl);
  205. DECODE_PRINTF(",");
  206. destval = fetch_data_byte(destoffset);
  207. srcreg = DECODE_RM_BYTE_REGISTER(rh);
  208. DECODE_PRINTF("\n");
  209. TRACE_AND_STEP();
  210. destval = genop_byte_operation[op1](destval, *srcreg);
  211. store_data_byte(destoffset, destval);
  212. }
  213. else
  214. { /* register to register */
  215. destreg = DECODE_RM_BYTE_REGISTER(rl);
  216. DECODE_PRINTF(",");
  217. srcreg = DECODE_RM_BYTE_REGISTER(rh);
  218. DECODE_PRINTF("\n");
  219. TRACE_AND_STEP();
  220. *destreg = genop_byte_operation[op1](*destreg, *srcreg);
  221. }
  222. DECODE_CLEAR_SEGOVR();
  223. END_OF_INSTR();
  224. }
  225. /****************************************************************************
  226. REMARKS:
  227. Handles opcodes 0x01, 0x09, 0x11, 0x19, 0x21, 0x29, 0x31, 0x39
  228. ****************************************************************************/
  229. void x86emuOp_genop_word_RM_R(u8 op1)
  230. {
  231. int mod, rl, rh;
  232. uint destoffset;
  233. op1 = (op1 >> 3) & 0x7;
  234. START_OF_INSTR();
  235. DECODE_PRINTF(x86emu_GenOpName[op1]);
  236. DECODE_PRINTF("\t");
  237. FETCH_DECODE_MODRM(mod, rh, rl);
  238. if(mod<3) {
  239. destoffset = decode_rmXX_address(mod,rl);
  240. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  241. u32 destval;
  242. u32 *srcreg;
  243. DECODE_PRINTF(",");
  244. destval = fetch_data_long(destoffset);
  245. srcreg = DECODE_RM_LONG_REGISTER(rh);
  246. DECODE_PRINTF("\n");
  247. TRACE_AND_STEP();
  248. destval = genop_long_operation[op1](destval, *srcreg);
  249. store_data_long(destoffset, destval);
  250. } else {
  251. u16 destval;
  252. u16 *srcreg;
  253. DECODE_PRINTF(",");
  254. destval = fetch_data_word(destoffset);
  255. srcreg = DECODE_RM_WORD_REGISTER(rh);
  256. DECODE_PRINTF("\n");
  257. TRACE_AND_STEP();
  258. destval = genop_word_operation[op1](destval, *srcreg);
  259. store_data_word(destoffset, destval);
  260. }
  261. } else { /* register to register */
  262. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  263. u32 *destreg,*srcreg;
  264. destreg = DECODE_RM_LONG_REGISTER(rl);
  265. DECODE_PRINTF(",");
  266. srcreg = DECODE_RM_LONG_REGISTER(rh);
  267. DECODE_PRINTF("\n");
  268. TRACE_AND_STEP();
  269. *destreg = genop_long_operation[op1](*destreg, *srcreg);
  270. } else {
  271. u16 *destreg,*srcreg;
  272. destreg = DECODE_RM_WORD_REGISTER(rl);
  273. DECODE_PRINTF(",");
  274. srcreg = DECODE_RM_WORD_REGISTER(rh);
  275. DECODE_PRINTF("\n");
  276. TRACE_AND_STEP();
  277. *destreg = genop_word_operation[op1](*destreg, *srcreg);
  278. }
  279. }
  280. DECODE_CLEAR_SEGOVR();
  281. END_OF_INSTR();
  282. }
  283. /****************************************************************************
  284. REMARKS:
  285. Handles opcodes 0x02, 0x0a, 0x12, 0x1a, 0x22, 0x2a, 0x32, 0x3a
  286. ****************************************************************************/
  287. void x86emuOp_genop_byte_R_RM(u8 op1)
  288. {
  289. int mod, rl, rh;
  290. u8 *destreg, *srcreg;
  291. uint srcoffset;
  292. u8 srcval;
  293. op1 = (op1 >> 3) & 0x7;
  294. START_OF_INSTR();
  295. DECODE_PRINTF(x86emu_GenOpName[op1]);
  296. DECODE_PRINTF("\t");
  297. FETCH_DECODE_MODRM(mod, rh, rl);
  298. if (mod < 3) {
  299. destreg = DECODE_RM_BYTE_REGISTER(rh);
  300. DECODE_PRINTF(",");
  301. srcoffset = decode_rmXX_address(mod,rl);
  302. srcval = fetch_data_byte(srcoffset);
  303. } else { /* register to register */
  304. destreg = DECODE_RM_BYTE_REGISTER(rh);
  305. DECODE_PRINTF(",");
  306. srcreg = DECODE_RM_BYTE_REGISTER(rl);
  307. srcval = *srcreg;
  308. }
  309. DECODE_PRINTF("\n");
  310. TRACE_AND_STEP();
  311. *destreg = genop_byte_operation[op1](*destreg, srcval);
  312. DECODE_CLEAR_SEGOVR();
  313. END_OF_INSTR();
  314. }
  315. /****************************************************************************
  316. REMARKS:
  317. Handles opcodes 0x03, 0x0b, 0x13, 0x1b, 0x23, 0x2b, 0x33, 0x3b
  318. ****************************************************************************/
  319. void x86emuOp_genop_word_R_RM(u8 op1)
  320. {
  321. int mod, rl, rh;
  322. uint srcoffset;
  323. u32 *destreg32, srcval;
  324. u16 *destreg;
  325. op1 = (op1 >> 3) & 0x7;
  326. START_OF_INSTR();
  327. DECODE_PRINTF(x86emu_GenOpName[op1]);
  328. DECODE_PRINTF("\t");
  329. FETCH_DECODE_MODRM(mod, rh, rl);
  330. if (mod < 3) {
  331. srcoffset = decode_rmXX_address(mod,rl);
  332. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  333. destreg32 = DECODE_RM_LONG_REGISTER(rh);
  334. DECODE_PRINTF(",");
  335. srcval = fetch_data_long(srcoffset);
  336. DECODE_PRINTF("\n");
  337. TRACE_AND_STEP();
  338. *destreg32 = genop_long_operation[op1](*destreg32, srcval);
  339. } else {
  340. destreg = DECODE_RM_WORD_REGISTER(rh);
  341. DECODE_PRINTF(",");
  342. srcval = fetch_data_word(srcoffset);
  343. DECODE_PRINTF("\n");
  344. TRACE_AND_STEP();
  345. *destreg = genop_word_operation[op1](*destreg, srcval);
  346. }
  347. } else { /* register to register */
  348. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  349. u32 *srcreg;
  350. destreg32 = DECODE_RM_LONG_REGISTER(rh);
  351. DECODE_PRINTF(",");
  352. srcreg = DECODE_RM_LONG_REGISTER(rl);
  353. DECODE_PRINTF("\n");
  354. TRACE_AND_STEP();
  355. *destreg32 = genop_long_operation[op1](*destreg32, *srcreg);
  356. } else {
  357. u16 *srcreg;
  358. destreg = DECODE_RM_WORD_REGISTER(rh);
  359. DECODE_PRINTF(",");
  360. srcreg = DECODE_RM_WORD_REGISTER(rl);
  361. DECODE_PRINTF("\n");
  362. TRACE_AND_STEP();
  363. *destreg = genop_word_operation[op1](*destreg, *srcreg);
  364. }
  365. }
  366. DECODE_CLEAR_SEGOVR();
  367. END_OF_INSTR();
  368. }
  369. /****************************************************************************
  370. REMARKS:
  371. Handles opcodes 0x04, 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c
  372. ****************************************************************************/
  373. void x86emuOp_genop_byte_AL_IMM(u8 op1)
  374. {
  375. u8 srcval;
  376. op1 = (op1 >> 3) & 0x7;
  377. START_OF_INSTR();
  378. DECODE_PRINTF(x86emu_GenOpName[op1]);
  379. DECODE_PRINTF("\tAL,");
  380. srcval = fetch_byte_imm();
  381. DECODE_PRINTF2("%x\n", srcval);
  382. TRACE_AND_STEP();
  383. M.x86.R_AL = genop_byte_operation[op1](M.x86.R_AL, srcval);
  384. DECODE_CLEAR_SEGOVR();
  385. END_OF_INSTR();
  386. }
  387. /****************************************************************************
  388. REMARKS:
  389. Handles opcodes 0x05, 0x0d, 0x15, 0x1d, 0x25, 0x2d, 0x35, 0x3d
  390. ****************************************************************************/
  391. void x86emuOp_genop_word_AX_IMM(u8 op1)
  392. {
  393. u32 srcval;
  394. op1 = (op1 >> 3) & 0x7;
  395. START_OF_INSTR();
  396. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  397. DECODE_PRINTF(x86emu_GenOpName[op1]);
  398. DECODE_PRINTF("\tEAX,");
  399. srcval = fetch_long_imm();
  400. } else {
  401. DECODE_PRINTF(x86emu_GenOpName[op1]);
  402. DECODE_PRINTF("\tAX,");
  403. srcval = fetch_word_imm();
  404. }
  405. DECODE_PRINTF2("%x\n", srcval);
  406. TRACE_AND_STEP();
  407. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  408. M.x86.R_EAX = genop_long_operation[op1](M.x86.R_EAX, srcval);
  409. } else {
  410. M.x86.R_AX = genop_word_operation[op1](M.x86.R_AX, (u16)srcval);
  411. }
  412. DECODE_CLEAR_SEGOVR();
  413. END_OF_INSTR();
  414. }
  415. /****************************************************************************
  416. REMARKS:
  417. Handles opcode 0x06
  418. ****************************************************************************/
  419. void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
  420. {
  421. START_OF_INSTR();
  422. DECODE_PRINTF("PUSH\tES\n");
  423. TRACE_AND_STEP();
  424. push_word(M.x86.R_ES);
  425. DECODE_CLEAR_SEGOVR();
  426. END_OF_INSTR();
  427. }
  428. /****************************************************************************
  429. REMARKS:
  430. Handles opcode 0x07
  431. ****************************************************************************/
  432. void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
  433. {
  434. START_OF_INSTR();
  435. DECODE_PRINTF("POP\tES\n");
  436. TRACE_AND_STEP();
  437. M.x86.R_ES = pop_word();
  438. DECODE_CLEAR_SEGOVR();
  439. END_OF_INSTR();
  440. }
  441. /****************************************************************************
  442. REMARKS:
  443. Handles opcode 0x0e
  444. ****************************************************************************/
  445. void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
  446. {
  447. START_OF_INSTR();
  448. DECODE_PRINTF("PUSH\tCS\n");
  449. TRACE_AND_STEP();
  450. push_word(M.x86.R_CS);
  451. DECODE_CLEAR_SEGOVR();
  452. END_OF_INSTR();
  453. }
  454. /****************************************************************************
  455. REMARKS:
  456. Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
  457. ****************************************************************************/
  458. void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
  459. {
  460. u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
  461. INC_DECODED_INST_LEN(1);
  462. (*x86emu_optab2[op2])(op2);
  463. }
  464. /****************************************************************************
  465. REMARKS:
  466. Handles opcode 0x16
  467. ****************************************************************************/
  468. void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
  469. {
  470. START_OF_INSTR();
  471. DECODE_PRINTF("PUSH\tSS\n");
  472. TRACE_AND_STEP();
  473. push_word(M.x86.R_SS);
  474. DECODE_CLEAR_SEGOVR();
  475. END_OF_INSTR();
  476. }
  477. /****************************************************************************
  478. REMARKS:
  479. Handles opcode 0x17
  480. ****************************************************************************/
  481. void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
  482. {
  483. START_OF_INSTR();
  484. DECODE_PRINTF("POP\tSS\n");
  485. TRACE_AND_STEP();
  486. M.x86.R_SS = pop_word();
  487. DECODE_CLEAR_SEGOVR();
  488. END_OF_INSTR();
  489. }
  490. /****************************************************************************
  491. REMARKS:
  492. Handles opcode 0x1e
  493. ****************************************************************************/
  494. void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
  495. {
  496. START_OF_INSTR();
  497. DECODE_PRINTF("PUSH\tDS\n");
  498. TRACE_AND_STEP();
  499. push_word(M.x86.R_DS);
  500. DECODE_CLEAR_SEGOVR();
  501. END_OF_INSTR();
  502. }
  503. /****************************************************************************
  504. REMARKS:
  505. Handles opcode 0x1f
  506. ****************************************************************************/
  507. void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
  508. {
  509. START_OF_INSTR();
  510. DECODE_PRINTF("POP\tDS\n");
  511. TRACE_AND_STEP();
  512. M.x86.R_DS = pop_word();
  513. DECODE_CLEAR_SEGOVR();
  514. END_OF_INSTR();
  515. }
  516. /****************************************************************************
  517. REMARKS:
  518. Handles opcode 0x26
  519. ****************************************************************************/
  520. void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
  521. {
  522. START_OF_INSTR();
  523. DECODE_PRINTF("ES:\n");
  524. TRACE_AND_STEP();
  525. M.x86.mode |= SYSMODE_SEGOVR_ES;
  526. /*
  527. * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
  528. * opcode subroutines we do not want to do this.
  529. */
  530. END_OF_INSTR();
  531. }
  532. /****************************************************************************
  533. REMARKS:
  534. Handles opcode 0x27
  535. ****************************************************************************/
  536. void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
  537. {
  538. START_OF_INSTR();
  539. DECODE_PRINTF("DAA\n");
  540. TRACE_AND_STEP();
  541. M.x86.R_AL = daa_byte(M.x86.R_AL);
  542. DECODE_CLEAR_SEGOVR();
  543. END_OF_INSTR();
  544. }
  545. /****************************************************************************
  546. REMARKS:
  547. Handles opcode 0x2e
  548. ****************************************************************************/
  549. void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
  550. {
  551. START_OF_INSTR();
  552. DECODE_PRINTF("CS:\n");
  553. TRACE_AND_STEP();
  554. M.x86.mode |= SYSMODE_SEGOVR_CS;
  555. /* note no DECODE_CLEAR_SEGOVR here. */
  556. END_OF_INSTR();
  557. }
  558. /****************************************************************************
  559. REMARKS:
  560. Handles opcode 0x2f
  561. ****************************************************************************/
  562. void x86emuOp_das(u8 X86EMU_UNUSED(op1))
  563. {
  564. START_OF_INSTR();
  565. DECODE_PRINTF("DAS\n");
  566. TRACE_AND_STEP();
  567. M.x86.R_AL = das_byte(M.x86.R_AL);
  568. DECODE_CLEAR_SEGOVR();
  569. END_OF_INSTR();
  570. }
  571. /****************************************************************************
  572. REMARKS:
  573. Handles opcode 0x36
  574. ****************************************************************************/
  575. void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
  576. {
  577. START_OF_INSTR();
  578. DECODE_PRINTF("SS:\n");
  579. TRACE_AND_STEP();
  580. M.x86.mode |= SYSMODE_SEGOVR_SS;
  581. /* no DECODE_CLEAR_SEGOVR ! */
  582. END_OF_INSTR();
  583. }
  584. /****************************************************************************
  585. REMARKS:
  586. Handles opcode 0x37
  587. ****************************************************************************/
  588. void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
  589. {
  590. START_OF_INSTR();
  591. DECODE_PRINTF("AAA\n");
  592. TRACE_AND_STEP();
  593. M.x86.R_AX = aaa_word(M.x86.R_AX);
  594. DECODE_CLEAR_SEGOVR();
  595. END_OF_INSTR();
  596. }
  597. /****************************************************************************
  598. REMARKS:
  599. Handles opcode 0x3e
  600. ****************************************************************************/
  601. void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
  602. {
  603. START_OF_INSTR();
  604. DECODE_PRINTF("DS:\n");
  605. TRACE_AND_STEP();
  606. M.x86.mode |= SYSMODE_SEGOVR_DS;
  607. /* NO DECODE_CLEAR_SEGOVR! */
  608. END_OF_INSTR();
  609. }
  610. /****************************************************************************
  611. REMARKS:
  612. Handles opcode 0x3f
  613. ****************************************************************************/
  614. void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
  615. {
  616. START_OF_INSTR();
  617. DECODE_PRINTF("AAS\n");
  618. TRACE_AND_STEP();
  619. M.x86.R_AX = aas_word(M.x86.R_AX);
  620. DECODE_CLEAR_SEGOVR();
  621. END_OF_INSTR();
  622. }
  623. /****************************************************************************
  624. REMARKS:
  625. Handles opcode 0x40 - 0x47
  626. ****************************************************************************/
  627. void x86emuOp_inc_register(u8 op1)
  628. {
  629. START_OF_INSTR();
  630. op1 &= 0x7;
  631. DECODE_PRINTF("INC\t");
  632. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  633. u32 *reg;
  634. reg = DECODE_RM_LONG_REGISTER(op1);
  635. DECODE_PRINTF("\n");
  636. TRACE_AND_STEP();
  637. *reg = inc_long(*reg);
  638. } else {
  639. u16 *reg;
  640. reg = DECODE_RM_WORD_REGISTER(op1);
  641. DECODE_PRINTF("\n");
  642. TRACE_AND_STEP();
  643. *reg = inc_word(*reg);
  644. }
  645. DECODE_CLEAR_SEGOVR();
  646. END_OF_INSTR();
  647. }
  648. /****************************************************************************
  649. REMARKS:
  650. Handles opcode 0x48 - 0x4F
  651. ****************************************************************************/
  652. void x86emuOp_dec_register(u8 op1)
  653. {
  654. START_OF_INSTR();
  655. op1 &= 0x7;
  656. DECODE_PRINTF("DEC\t");
  657. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  658. u32 *reg;
  659. reg = DECODE_RM_LONG_REGISTER(op1);
  660. DECODE_PRINTF("\n");
  661. TRACE_AND_STEP();
  662. *reg = dec_long(*reg);
  663. } else {
  664. u16 *reg;
  665. reg = DECODE_RM_WORD_REGISTER(op1);
  666. DECODE_PRINTF("\n");
  667. TRACE_AND_STEP();
  668. *reg = dec_word(*reg);
  669. }
  670. DECODE_CLEAR_SEGOVR();
  671. END_OF_INSTR();
  672. }
  673. /****************************************************************************
  674. REMARKS:
  675. Handles opcode 0x50 - 0x57
  676. ****************************************************************************/
  677. void x86emuOp_push_register(u8 op1)
  678. {
  679. START_OF_INSTR();
  680. op1 &= 0x7;
  681. DECODE_PRINTF("PUSH\t");
  682. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  683. u32 *reg;
  684. reg = DECODE_RM_LONG_REGISTER(op1);
  685. DECODE_PRINTF("\n");
  686. TRACE_AND_STEP();
  687. push_long(*reg);
  688. } else {
  689. u16 *reg;
  690. reg = DECODE_RM_WORD_REGISTER(op1);
  691. DECODE_PRINTF("\n");
  692. TRACE_AND_STEP();
  693. push_word(*reg);
  694. }
  695. DECODE_CLEAR_SEGOVR();
  696. END_OF_INSTR();
  697. }
  698. /****************************************************************************
  699. REMARKS:
  700. Handles opcode 0x58 - 0x5F
  701. ****************************************************************************/
  702. void x86emuOp_pop_register(u8 op1)
  703. {
  704. START_OF_INSTR();
  705. op1 &= 0x7;
  706. DECODE_PRINTF("POP\t");
  707. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  708. u32 *reg;
  709. reg = DECODE_RM_LONG_REGISTER(op1);
  710. DECODE_PRINTF("\n");
  711. TRACE_AND_STEP();
  712. *reg = pop_long();
  713. } else {
  714. u16 *reg;
  715. reg = DECODE_RM_WORD_REGISTER(op1);
  716. DECODE_PRINTF("\n");
  717. TRACE_AND_STEP();
  718. *reg = pop_word();
  719. }
  720. DECODE_CLEAR_SEGOVR();
  721. END_OF_INSTR();
  722. }
  723. /****************************************************************************
  724. REMARKS:
  725. Handles opcode 0x60
  726. ****************************************************************************/
  727. void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
  728. {
  729. START_OF_INSTR();
  730. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  731. DECODE_PRINTF("PUSHAD\n");
  732. } else {
  733. DECODE_PRINTF("PUSHA\n");
  734. }
  735. TRACE_AND_STEP();
  736. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  737. u32 old_sp = M.x86.R_ESP;
  738. push_long(M.x86.R_EAX);
  739. push_long(M.x86.R_ECX);
  740. push_long(M.x86.R_EDX);
  741. push_long(M.x86.R_EBX);
  742. push_long(old_sp);
  743. push_long(M.x86.R_EBP);
  744. push_long(M.x86.R_ESI);
  745. push_long(M.x86.R_EDI);
  746. } else {
  747. u16 old_sp = M.x86.R_SP;
  748. push_word(M.x86.R_AX);
  749. push_word(M.x86.R_CX);
  750. push_word(M.x86.R_DX);
  751. push_word(M.x86.R_BX);
  752. push_word(old_sp);
  753. push_word(M.x86.R_BP);
  754. push_word(M.x86.R_SI);
  755. push_word(M.x86.R_DI);
  756. }
  757. DECODE_CLEAR_SEGOVR();
  758. END_OF_INSTR();
  759. }
  760. /****************************************************************************
  761. REMARKS:
  762. Handles opcode 0x61
  763. ****************************************************************************/
  764. void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
  765. {
  766. START_OF_INSTR();
  767. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  768. DECODE_PRINTF("POPAD\n");
  769. } else {
  770. DECODE_PRINTF("POPA\n");
  771. }
  772. TRACE_AND_STEP();
  773. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  774. M.x86.R_EDI = pop_long();
  775. M.x86.R_ESI = pop_long();
  776. M.x86.R_EBP = pop_long();
  777. M.x86.R_ESP += 4; /* skip ESP */
  778. M.x86.R_EBX = pop_long();
  779. M.x86.R_EDX = pop_long();
  780. M.x86.R_ECX = pop_long();
  781. M.x86.R_EAX = pop_long();
  782. } else {
  783. M.x86.R_DI = pop_word();
  784. M.x86.R_SI = pop_word();
  785. M.x86.R_BP = pop_word();
  786. M.x86.R_SP += 2; /* skip SP */
  787. M.x86.R_BX = pop_word();
  788. M.x86.R_DX = pop_word();
  789. M.x86.R_CX = pop_word();
  790. M.x86.R_AX = pop_word();
  791. }
  792. DECODE_CLEAR_SEGOVR();
  793. END_OF_INSTR();
  794. }
  795. /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
  796. /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
  797. /****************************************************************************
  798. REMARKS:
  799. Handles opcode 0x64
  800. ****************************************************************************/
  801. void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
  802. {
  803. START_OF_INSTR();
  804. DECODE_PRINTF("FS:\n");
  805. TRACE_AND_STEP();
  806. M.x86.mode |= SYSMODE_SEGOVR_FS;
  807. /*
  808. * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
  809. * opcode subroutines we do not want to do this.
  810. */
  811. END_OF_INSTR();
  812. }
  813. /****************************************************************************
  814. REMARKS:
  815. Handles opcode 0x65
  816. ****************************************************************************/
  817. void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
  818. {
  819. START_OF_INSTR();
  820. DECODE_PRINTF("GS:\n");
  821. TRACE_AND_STEP();
  822. M.x86.mode |= SYSMODE_SEGOVR_GS;
  823. /*
  824. * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
  825. * opcode subroutines we do not want to do this.
  826. */
  827. END_OF_INSTR();
  828. }
  829. /****************************************************************************
  830. REMARKS:
  831. Handles opcode 0x66 - prefix for 32-bit register
  832. ****************************************************************************/
  833. void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
  834. {
  835. START_OF_INSTR();
  836. DECODE_PRINTF("DATA:\n");
  837. TRACE_AND_STEP();
  838. M.x86.mode |= SYSMODE_PREFIX_DATA;
  839. /* note no DECODE_CLEAR_SEGOVR here. */
  840. END_OF_INSTR();
  841. }
  842. /****************************************************************************
  843. REMARKS:
  844. Handles opcode 0x67 - prefix for 32-bit address
  845. ****************************************************************************/
  846. void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
  847. {
  848. START_OF_INSTR();
  849. DECODE_PRINTF("ADDR:\n");
  850. TRACE_AND_STEP();
  851. M.x86.mode |= SYSMODE_PREFIX_ADDR;
  852. /* note no DECODE_CLEAR_SEGOVR here. */
  853. END_OF_INSTR();
  854. }
  855. /****************************************************************************
  856. REMARKS:
  857. Handles opcode 0x68
  858. ****************************************************************************/
  859. void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
  860. {
  861. u32 imm;
  862. START_OF_INSTR();
  863. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  864. imm = fetch_long_imm();
  865. } else {
  866. imm = fetch_word_imm();
  867. }
  868. DECODE_PRINTF2("PUSH\t%x\n", imm);
  869. TRACE_AND_STEP();
  870. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  871. push_long(imm);
  872. } else {
  873. push_word((u16)imm);
  874. }
  875. DECODE_CLEAR_SEGOVR();
  876. END_OF_INSTR();
  877. }
  878. /****************************************************************************
  879. REMARKS:
  880. Handles opcode 0x69
  881. ****************************************************************************/
  882. void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
  883. {
  884. int mod, rl, rh;
  885. uint srcoffset;
  886. START_OF_INSTR();
  887. DECODE_PRINTF("IMUL\t");
  888. FETCH_DECODE_MODRM(mod, rh, rl);
  889. if (mod < 3) {
  890. srcoffset = decode_rmXX_address(mod, rl);
  891. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  892. u32 *destreg;
  893. u32 srcval;
  894. u32 res_lo,res_hi;
  895. s32 imm;
  896. destreg = DECODE_RM_LONG_REGISTER(rh);
  897. DECODE_PRINTF(",");
  898. srcval = fetch_data_long(srcoffset);
  899. imm = fetch_long_imm();
  900. DECODE_PRINTF2(",%d\n", (s32)imm);
  901. TRACE_AND_STEP();
  902. imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
  903. if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
  904. (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
  905. CLEAR_FLAG(F_CF);
  906. CLEAR_FLAG(F_OF);
  907. } else {
  908. SET_FLAG(F_CF);
  909. SET_FLAG(F_OF);
  910. }
  911. *destreg = (u32)res_lo;
  912. } else {
  913. u16 *destreg;
  914. u16 srcval;
  915. u32 res;
  916. s16 imm;
  917. destreg = DECODE_RM_WORD_REGISTER(rh);
  918. DECODE_PRINTF(",");
  919. srcval = fetch_data_word(srcoffset);
  920. imm = fetch_word_imm();
  921. DECODE_PRINTF2(",%d\n", (s32)imm);
  922. TRACE_AND_STEP();
  923. res = (s16)srcval * (s16)imm;
  924. if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
  925. (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
  926. CLEAR_FLAG(F_CF);
  927. CLEAR_FLAG(F_OF);
  928. } else {
  929. SET_FLAG(F_CF);
  930. SET_FLAG(F_OF);
  931. }
  932. *destreg = (u16)res;
  933. }
  934. } else { /* register to register */
  935. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  936. u32 *destreg,*srcreg;
  937. u32 res_lo,res_hi;
  938. s32 imm;
  939. destreg = DECODE_RM_LONG_REGISTER(rh);
  940. DECODE_PRINTF(",");
  941. srcreg = DECODE_RM_LONG_REGISTER(rl);
  942. imm = fetch_long_imm();
  943. DECODE_PRINTF2(",%d\n", (s32)imm);
  944. TRACE_AND_STEP();
  945. imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
  946. if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
  947. (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
  948. CLEAR_FLAG(F_CF);
  949. CLEAR_FLAG(F_OF);
  950. } else {
  951. SET_FLAG(F_CF);
  952. SET_FLAG(F_OF);
  953. }
  954. *destreg = (u32)res_lo;
  955. } else {
  956. u16 *destreg,*srcreg;
  957. u32 res;
  958. s16 imm;
  959. destreg = DECODE_RM_WORD_REGISTER(rh);
  960. DECODE_PRINTF(",");
  961. srcreg = DECODE_RM_WORD_REGISTER(rl);
  962. imm = fetch_word_imm();
  963. DECODE_PRINTF2(",%d\n", (s32)imm);
  964. res = (s16)*srcreg * (s16)imm;
  965. if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
  966. (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
  967. CLEAR_FLAG(F_CF);
  968. CLEAR_FLAG(F_OF);
  969. } else {
  970. SET_FLAG(F_CF);
  971. SET_FLAG(F_OF);
  972. }
  973. *destreg = (u16)res;
  974. }
  975. }
  976. DECODE_CLEAR_SEGOVR();
  977. END_OF_INSTR();
  978. }
  979. /****************************************************************************
  980. REMARKS:
  981. Handles opcode 0x6a
  982. ****************************************************************************/
  983. void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
  984. {
  985. s16 imm;
  986. START_OF_INSTR();
  987. imm = (s8)fetch_byte_imm();
  988. DECODE_PRINTF2("PUSH\t%d\n", imm);
  989. TRACE_AND_STEP();
  990. push_word(imm);
  991. DECODE_CLEAR_SEGOVR();
  992. END_OF_INSTR();
  993. }
  994. /****************************************************************************
  995. REMARKS:
  996. Handles opcode 0x6b
  997. ****************************************************************************/
  998. void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
  999. {
  1000. int mod, rl, rh;
  1001. uint srcoffset;
  1002. s8 imm;
  1003. START_OF_INSTR();
  1004. DECODE_PRINTF("IMUL\t");
  1005. FETCH_DECODE_MODRM(mod, rh, rl);
  1006. if (mod < 3) {
  1007. srcoffset = decode_rmXX_address(mod, rl);
  1008. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1009. u32 *destreg;
  1010. u32 srcval;
  1011. u32 res_lo,res_hi;
  1012. destreg = DECODE_RM_LONG_REGISTER(rh);
  1013. DECODE_PRINTF(",");
  1014. srcval = fetch_data_long(srcoffset);
  1015. imm = fetch_byte_imm();
  1016. DECODE_PRINTF2(",%d\n", (s32)imm);
  1017. TRACE_AND_STEP();
  1018. imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
  1019. if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
  1020. (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
  1021. CLEAR_FLAG(F_CF);
  1022. CLEAR_FLAG(F_OF);
  1023. } else {
  1024. SET_FLAG(F_CF);
  1025. SET_FLAG(F_OF);
  1026. }
  1027. *destreg = (u32)res_lo;
  1028. } else {
  1029. u16 *destreg;
  1030. u16 srcval;
  1031. u32 res;
  1032. destreg = DECODE_RM_WORD_REGISTER(rh);
  1033. DECODE_PRINTF(",");
  1034. srcval = fetch_data_word(srcoffset);
  1035. imm = fetch_byte_imm();
  1036. DECODE_PRINTF2(",%d\n", (s32)imm);
  1037. TRACE_AND_STEP();
  1038. res = (s16)srcval * (s16)imm;
  1039. if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
  1040. (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
  1041. CLEAR_FLAG(F_CF);
  1042. CLEAR_FLAG(F_OF);
  1043. } else {
  1044. SET_FLAG(F_CF);
  1045. SET_FLAG(F_OF);
  1046. }
  1047. *destreg = (u16)res;
  1048. }
  1049. } else { /* register to register */
  1050. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1051. u32 *destreg,*srcreg;
  1052. u32 res_lo,res_hi;
  1053. destreg = DECODE_RM_LONG_REGISTER(rh);
  1054. DECODE_PRINTF(",");
  1055. srcreg = DECODE_RM_LONG_REGISTER(rl);
  1056. imm = fetch_byte_imm();
  1057. DECODE_PRINTF2(",%d\n", (s32)imm);
  1058. TRACE_AND_STEP();
  1059. imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
  1060. if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
  1061. (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
  1062. CLEAR_FLAG(F_CF);
  1063. CLEAR_FLAG(F_OF);
  1064. } else {
  1065. SET_FLAG(F_CF);
  1066. SET_FLAG(F_OF);
  1067. }
  1068. *destreg = (u32)res_lo;
  1069. } else {
  1070. u16 *destreg,*srcreg;
  1071. u32 res;
  1072. destreg = DECODE_RM_WORD_REGISTER(rh);
  1073. DECODE_PRINTF(",");
  1074. srcreg = DECODE_RM_WORD_REGISTER(rl);
  1075. imm = fetch_byte_imm();
  1076. DECODE_PRINTF2(",%d\n", (s32)imm);
  1077. TRACE_AND_STEP();
  1078. res = (s16)*srcreg * (s16)imm;
  1079. if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
  1080. (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
  1081. CLEAR_FLAG(F_CF);
  1082. CLEAR_FLAG(F_OF);
  1083. } else {
  1084. SET_FLAG(F_CF);
  1085. SET_FLAG(F_OF);
  1086. }
  1087. *destreg = (u16)res;
  1088. }
  1089. }
  1090. DECODE_CLEAR_SEGOVR();
  1091. END_OF_INSTR();
  1092. }
  1093. /****************************************************************************
  1094. REMARKS:
  1095. Handles opcode 0x6c
  1096. ****************************************************************************/
  1097. void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
  1098. {
  1099. START_OF_INSTR();
  1100. DECODE_PRINTF("INSB\n");
  1101. ins(1);
  1102. TRACE_AND_STEP();
  1103. DECODE_CLEAR_SEGOVR();
  1104. END_OF_INSTR();
  1105. }
  1106. /****************************************************************************
  1107. REMARKS:
  1108. Handles opcode 0x6d
  1109. ****************************************************************************/
  1110. void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
  1111. {
  1112. START_OF_INSTR();
  1113. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1114. DECODE_PRINTF("INSD\n");
  1115. ins(4);
  1116. } else {
  1117. DECODE_PRINTF("INSW\n");
  1118. ins(2);
  1119. }
  1120. TRACE_AND_STEP();
  1121. DECODE_CLEAR_SEGOVR();
  1122. END_OF_INSTR();
  1123. }
  1124. /****************************************************************************
  1125. REMARKS:
  1126. Handles opcode 0x6e
  1127. ****************************************************************************/
  1128. void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
  1129. {
  1130. START_OF_INSTR();
  1131. DECODE_PRINTF("OUTSB\n");
  1132. outs(1);
  1133. TRACE_AND_STEP();
  1134. DECODE_CLEAR_SEGOVR();
  1135. END_OF_INSTR();
  1136. }
  1137. /****************************************************************************
  1138. REMARKS:
  1139. Handles opcode 0x6f
  1140. ****************************************************************************/
  1141. void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
  1142. {
  1143. START_OF_INSTR();
  1144. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1145. DECODE_PRINTF("OUTSD\n");
  1146. outs(4);
  1147. } else {
  1148. DECODE_PRINTF("OUTSW\n");
  1149. outs(2);
  1150. }
  1151. TRACE_AND_STEP();
  1152. DECODE_CLEAR_SEGOVR();
  1153. END_OF_INSTR();
  1154. }
  1155. /****************************************************************************
  1156. REMARKS:
  1157. Handles opcode 0x70 - 0x7F
  1158. ****************************************************************************/
  1159. int x86emu_check_jump_condition(u8 op);
  1160. void x86emuOp_jump_near_cond(u8 op1)
  1161. {
  1162. s8 offset;
  1163. u16 target;
  1164. int cond;
  1165. /* jump to byte offset if overflow flag is set */
  1166. START_OF_INSTR();
  1167. cond = x86emu_check_jump_condition(op1 & 0xF);
  1168. offset = (s8)fetch_byte_imm();
  1169. target = (u16)(M.x86.R_IP + (s16)offset);
  1170. DECODE_PRINTF2("%x\n", target);
  1171. TRACE_AND_STEP();
  1172. if (cond)
  1173. M.x86.R_IP = target;
  1174. DECODE_CLEAR_SEGOVR();
  1175. END_OF_INSTR();
  1176. }
  1177. /****************************************************************************
  1178. REMARKS:
  1179. Handles opcode 0x80
  1180. ****************************************************************************/
  1181. void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
  1182. {
  1183. int mod, rl, rh;
  1184. u8 *destreg;
  1185. uint destoffset;
  1186. u8 imm;
  1187. u8 destval;
  1188. /*
  1189. * Weirdo special case instruction format. Part of the opcode
  1190. * held below in "RH". Doubly nested case would result, except
  1191. * that the decoded instruction
  1192. */
  1193. START_OF_INSTR();
  1194. FETCH_DECODE_MODRM(mod, rh, rl);
  1195. #ifdef DEBUG
  1196. if (DEBUG_DECODE()) {
  1197. /* XXX DECODE_PRINTF may be changed to something more
  1198. general, so that it is important to leave the strings
  1199. in the same format, even though the result is that the
  1200. above test is done twice. */
  1201. switch (rh) {
  1202. case 0:
  1203. DECODE_PRINTF("ADD\t");
  1204. break;
  1205. case 1:
  1206. DECODE_PRINTF("OR\t");
  1207. break;
  1208. case 2:
  1209. DECODE_PRINTF("ADC\t");
  1210. break;
  1211. case 3:
  1212. DECODE_PRINTF("SBB\t");
  1213. break;
  1214. case 4:
  1215. DECODE_PRINTF("AND\t");
  1216. break;
  1217. case 5:
  1218. DECODE_PRINTF("SUB\t");
  1219. break;
  1220. case 6:
  1221. DECODE_PRINTF("XOR\t");
  1222. break;
  1223. case 7:
  1224. DECODE_PRINTF("CMP\t");
  1225. break;
  1226. }
  1227. }
  1228. #endif
  1229. /* know operation, decode the mod byte to find the addressing
  1230. mode. */
  1231. if (mod < 3) {
  1232. DECODE_PRINTF("BYTE PTR ");
  1233. destoffset = decode_rmXX_address(mod, rl);
  1234. DECODE_PRINTF(",");
  1235. destval = fetch_data_byte(destoffset);
  1236. imm = fetch_byte_imm();
  1237. DECODE_PRINTF2("%x\n", imm);
  1238. TRACE_AND_STEP();
  1239. destval = (*genop_byte_operation[rh]) (destval, imm);
  1240. if (rh != 7)
  1241. store_data_byte(destoffset, destval);
  1242. } else { /* register to register */
  1243. destreg = DECODE_RM_BYTE_REGISTER(rl);
  1244. DECODE_PRINTF(",");
  1245. imm = fetch_byte_imm();
  1246. DECODE_PRINTF2("%x\n", imm);
  1247. TRACE_AND_STEP();
  1248. destval = (*genop_byte_operation[rh]) (*destreg, imm);
  1249. if (rh != 7)
  1250. *destreg = destval;
  1251. }
  1252. DECODE_CLEAR_SEGOVR();
  1253. END_OF_INSTR();
  1254. }
  1255. /****************************************************************************
  1256. REMARKS:
  1257. Handles opcode 0x81
  1258. ****************************************************************************/
  1259. void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
  1260. {
  1261. int mod, rl, rh;
  1262. uint destoffset;
  1263. /*
  1264. * Weirdo special case instruction format. Part of the opcode
  1265. * held below in "RH". Doubly nested case would result, except
  1266. * that the decoded instruction
  1267. */
  1268. START_OF_INSTR();
  1269. FETCH_DECODE_MODRM(mod, rh, rl);
  1270. #ifdef DEBUG
  1271. if (DEBUG_DECODE()) {
  1272. /* XXX DECODE_PRINTF may be changed to something more
  1273. general, so that it is important to leave the strings
  1274. in the same format, even though the result is that the
  1275. above test is done twice. */
  1276. switch (rh) {
  1277. case 0:
  1278. DECODE_PRINTF("ADD\t");
  1279. break;
  1280. case 1:
  1281. DECODE_PRINTF("OR\t");
  1282. break;
  1283. case 2:
  1284. DECODE_PRINTF("ADC\t");
  1285. break;
  1286. case 3:
  1287. DECODE_PRINTF("SBB\t");
  1288. break;
  1289. case 4:
  1290. DECODE_PRINTF("AND\t");
  1291. break;
  1292. case 5:
  1293. DECODE_PRINTF("SUB\t");
  1294. break;
  1295. case 6:
  1296. DECODE_PRINTF("XOR\t");
  1297. break;
  1298. case 7:
  1299. DECODE_PRINTF("CMP\t");
  1300. break;
  1301. }
  1302. }
  1303. #endif
  1304. /*
  1305. * Know operation, decode the mod byte to find the addressing
  1306. * mode.
  1307. */
  1308. if (mod < 3) {
  1309. DECODE_PRINTF("DWORD PTR ");
  1310. destoffset = decode_rmXX_address(mod, rl);
  1311. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1312. u32 destval,imm;
  1313. DECODE_PRINTF(",");
  1314. destval = fetch_data_long(destoffset);
  1315. imm = fetch_long_imm();
  1316. DECODE_PRINTF2("%x\n", imm);
  1317. TRACE_AND_STEP();
  1318. destval = (*genop_long_operation[rh]) (destval, imm);
  1319. if (rh != 7)
  1320. store_data_long(destoffset, destval);
  1321. } else {
  1322. u16 destval,imm;
  1323. DECODE_PRINTF(",");
  1324. destval = fetch_data_word(destoffset);
  1325. imm = fetch_word_imm();
  1326. DECODE_PRINTF2("%x\n", imm);
  1327. TRACE_AND_STEP();
  1328. destval = (*genop_word_operation[rh]) (destval, imm);
  1329. if (rh != 7)
  1330. store_data_word(destoffset, destval);
  1331. }
  1332. } else { /* register to register */
  1333. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1334. u32 *destreg;
  1335. u32 destval,imm;
  1336. destreg = DECODE_RM_LONG_REGISTER(rl);
  1337. DECODE_PRINTF(",");
  1338. imm = fetch_long_imm();
  1339. DECODE_PRINTF2("%x\n", imm);
  1340. TRACE_AND_STEP();
  1341. destval = (*genop_long_operation[rh]) (*destreg, imm);
  1342. if (rh != 7)
  1343. *destreg = destval;
  1344. } else {
  1345. u16 *destreg;
  1346. u16 destval,imm;
  1347. destreg = DECODE_RM_WORD_REGISTER(rl);
  1348. DECODE_PRINTF(",");
  1349. imm = fetch_word_imm();
  1350. DECODE_PRINTF2("%x\n", imm);
  1351. TRACE_AND_STEP();
  1352. destval = (*genop_word_operation[rh]) (*destreg, imm);
  1353. if (rh != 7)
  1354. *destreg = destval;
  1355. }
  1356. }
  1357. DECODE_CLEAR_SEGOVR();
  1358. END_OF_INSTR();
  1359. }
  1360. /****************************************************************************
  1361. REMARKS:
  1362. Handles opcode 0x82
  1363. ****************************************************************************/
  1364. void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
  1365. {
  1366. int mod, rl, rh;
  1367. u8 *destreg;
  1368. uint destoffset;
  1369. u8 imm;
  1370. u8 destval;
  1371. /*
  1372. * Weirdo special case instruction format. Part of the opcode
  1373. * held below in "RH". Doubly nested case would result, except
  1374. * that the decoded instruction Similar to opcode 81, except that
  1375. * the immediate byte is sign extended to a word length.
  1376. */
  1377. START_OF_INSTR();
  1378. FETCH_DECODE_MODRM(mod, rh, rl);
  1379. #ifdef DEBUG
  1380. if (DEBUG_DECODE()) {
  1381. /* XXX DECODE_PRINTF may be changed to something more
  1382. general, so that it is important to leave the strings
  1383. in the same format, even though the result is that the
  1384. above test is done twice. */
  1385. switch (rh) {
  1386. case 0:
  1387. DECODE_PRINTF("ADD\t");
  1388. break;
  1389. case 1:
  1390. DECODE_PRINTF("OR\t");
  1391. break;
  1392. case 2:
  1393. DECODE_PRINTF("ADC\t");
  1394. break;
  1395. case 3:
  1396. DECODE_PRINTF("SBB\t");
  1397. break;
  1398. case 4:
  1399. DECODE_PRINTF("AND\t");
  1400. break;
  1401. case 5:
  1402. DECODE_PRINTF("SUB\t");
  1403. break;
  1404. case 6:
  1405. DECODE_PRINTF("XOR\t");
  1406. break;
  1407. case 7:
  1408. DECODE_PRINTF("CMP\t");
  1409. break;
  1410. }
  1411. }
  1412. #endif
  1413. /* know operation, decode the mod byte to find the addressing
  1414. mode. */
  1415. if (mod < 3) {
  1416. DECODE_PRINTF("BYTE PTR ");
  1417. destoffset = decode_rmXX_address(mod, rl);
  1418. destval = fetch_data_byte(destoffset);
  1419. imm = fetch_byte_imm();
  1420. DECODE_PRINTF2(",%x\n", imm);
  1421. TRACE_AND_STEP();
  1422. destval = (*genop_byte_operation[rh]) (destval, imm);
  1423. if (rh != 7)
  1424. store_data_byte(destoffset, destval);
  1425. } else { /* register to register */
  1426. destreg = DECODE_RM_BYTE_REGISTER(rl);
  1427. imm = fetch_byte_imm();
  1428. DECODE_PRINTF2(",%x\n", imm);
  1429. TRACE_AND_STEP();
  1430. destval = (*genop_byte_operation[rh]) (*destreg, imm);
  1431. if (rh != 7)
  1432. *destreg = destval;
  1433. }
  1434. DECODE_CLEAR_SEGOVR();
  1435. END_OF_INSTR();
  1436. }
  1437. /****************************************************************************
  1438. REMARKS:
  1439. Handles opcode 0x83
  1440. ****************************************************************************/
  1441. void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
  1442. {
  1443. int mod, rl, rh;
  1444. uint destoffset;
  1445. /*
  1446. * Weirdo special case instruction format. Part of the opcode
  1447. * held below in "RH". Doubly nested case would result, except
  1448. * that the decoded instruction Similar to opcode 81, except that
  1449. * the immediate byte is sign extended to a word length.
  1450. */
  1451. START_OF_INSTR();
  1452. FETCH_DECODE_MODRM(mod, rh, rl);
  1453. #ifdef DEBUG
  1454. if (DEBUG_DECODE()) {
  1455. /* XXX DECODE_PRINTF may be changed to something more
  1456. general, so that it is important to leave the strings
  1457. in the same format, even though the result is that the
  1458. above test is done twice. */
  1459. switch (rh) {
  1460. case 0:
  1461. DECODE_PRINTF("ADD\t");
  1462. break;
  1463. case 1:
  1464. DECODE_PRINTF("OR\t");
  1465. break;
  1466. case 2:
  1467. DECODE_PRINTF("ADC\t");
  1468. break;
  1469. case 3:
  1470. DECODE_PRINTF("SBB\t");
  1471. break;
  1472. case 4:
  1473. DECODE_PRINTF("AND\t");
  1474. break;
  1475. case 5:
  1476. DECODE_PRINTF("SUB\t");
  1477. break;
  1478. case 6:
  1479. DECODE_PRINTF("XOR\t");
  1480. break;
  1481. case 7:
  1482. DECODE_PRINTF("CMP\t");
  1483. break;
  1484. }
  1485. }
  1486. #endif
  1487. /* know operation, decode the mod byte to find the addressing
  1488. mode. */
  1489. if (mod < 3) {
  1490. DECODE_PRINTF("DWORD PTR ");
  1491. destoffset = decode_rmXX_address(mod,rl);
  1492. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1493. u32 destval,imm;
  1494. destval = fetch_data_long(destoffset);
  1495. imm = (s8) fetch_byte_imm();
  1496. DECODE_PRINTF2(",%x\n", imm);
  1497. TRACE_AND_STEP();
  1498. destval = (*genop_long_operation[rh]) (destval, imm);
  1499. if (rh != 7)
  1500. store_data_long(destoffset, destval);
  1501. } else {
  1502. u16 destval,imm;
  1503. destval = fetch_data_word(destoffset);
  1504. imm = (s8) fetch_byte_imm();
  1505. DECODE_PRINTF2(",%x\n", imm);
  1506. TRACE_AND_STEP();
  1507. destval = (*genop_word_operation[rh]) (destval, imm);
  1508. if (rh != 7)
  1509. store_data_word(destoffset, destval);
  1510. }
  1511. } else { /* register to register */
  1512. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1513. u32 *destreg;
  1514. u32 destval,imm;
  1515. destreg = DECODE_RM_LONG_REGISTER(rl);
  1516. imm = (s8) fetch_byte_imm();
  1517. DECODE_PRINTF2(",%x\n", imm);
  1518. TRACE_AND_STEP();
  1519. destval = (*genop_long_operation[rh]) (*destreg, imm);
  1520. if (rh != 7)
  1521. *destreg = destval;
  1522. } else {
  1523. u16 *destreg;
  1524. u16 destval,imm;
  1525. destreg = DECODE_RM_WORD_REGISTER(rl);
  1526. imm = (s8) fetch_byte_imm();
  1527. DECODE_PRINTF2(",%x\n", imm);
  1528. TRACE_AND_STEP();
  1529. destval = (*genop_word_operation[rh]) (*destreg, imm);
  1530. if (rh != 7)
  1531. *destreg = destval;
  1532. }
  1533. }
  1534. DECODE_CLEAR_SEGOVR();
  1535. END_OF_INSTR();
  1536. }
  1537. /****************************************************************************
  1538. REMARKS:
  1539. Handles opcode 0x84
  1540. ****************************************************************************/
  1541. void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
  1542. {
  1543. int mod, rl, rh;
  1544. u8 *destreg, *srcreg;
  1545. uint destoffset;
  1546. u8 destval;
  1547. START_OF_INSTR();
  1548. DECODE_PRINTF("TEST\t");
  1549. FETCH_DECODE_MODRM(mod, rh, rl);
  1550. if (mod < 3) {
  1551. destoffset = decode_rmXX_address(mod, rl);
  1552. DECODE_PRINTF(",");
  1553. destval = fetch_data_byte(destoffset);
  1554. srcreg = DECODE_RM_BYTE_REGISTER(rh);
  1555. DECODE_PRINTF("\n");
  1556. TRACE_AND_STEP();
  1557. test_byte(destval, *srcreg);
  1558. } else { /* register to register */
  1559. destreg = DECODE_RM_BYTE_REGISTER(rl);
  1560. DECODE_PRINTF(",");
  1561. srcreg = DECODE_RM_BYTE_REGISTER(rh);
  1562. DECODE_PRINTF("\n");
  1563. TRACE_AND_STEP();
  1564. test_byte(*destreg, *srcreg);
  1565. }
  1566. DECODE_CLEAR_SEGOVR();
  1567. END_OF_INSTR();
  1568. }
  1569. /****************************************************************************
  1570. REMARKS:
  1571. Handles opcode 0x85
  1572. ****************************************************************************/
  1573. void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
  1574. {
  1575. int mod, rl, rh;
  1576. uint destoffset;
  1577. START_OF_INSTR();
  1578. DECODE_PRINTF("TEST\t");
  1579. FETCH_DECODE_MODRM(mod, rh, rl);
  1580. if (mod < 3) {
  1581. destoffset = decode_rmXX_address(mod, rl);
  1582. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1583. u32 destval;
  1584. u32 *srcreg;
  1585. DECODE_PRINTF(",");
  1586. destval = fetch_data_long(destoffset);
  1587. srcreg = DECODE_RM_LONG_REGISTER(rh);
  1588. DECODE_PRINTF("\n");
  1589. TRACE_AND_STEP();
  1590. test_long(destval, *srcreg);
  1591. } else {
  1592. u16 destval;
  1593. u16 *srcreg;
  1594. DECODE_PRINTF(",");
  1595. destval = fetch_data_word(destoffset);
  1596. srcreg = DECODE_RM_WORD_REGISTER(rh);
  1597. DECODE_PRINTF("\n");
  1598. TRACE_AND_STEP();
  1599. test_word(destval, *srcreg);
  1600. }
  1601. } else { /* register to register */
  1602. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1603. u32 *destreg,*srcreg;
  1604. destreg = DECODE_RM_LONG_REGISTER(rl);
  1605. DECODE_PRINTF(",");
  1606. srcreg = DECODE_RM_LONG_REGISTER(rh);
  1607. DECODE_PRINTF("\n");
  1608. TRACE_AND_STEP();
  1609. test_long(*destreg, *srcreg);
  1610. } else {
  1611. u16 *destreg,*srcreg;
  1612. destreg = DECODE_RM_WORD_REGISTER(rl);
  1613. DECODE_PRINTF(",");
  1614. srcreg = DECODE_RM_WORD_REGISTER(rh);
  1615. DECODE_PRINTF("\n");
  1616. TRACE_AND_STEP();
  1617. test_word(*destreg, *srcreg);
  1618. }
  1619. }
  1620. DECODE_CLEAR_SEGOVR();
  1621. END_OF_INSTR();
  1622. }
  1623. /****************************************************************************
  1624. REMARKS:
  1625. Handles opcode 0x86
  1626. ****************************************************************************/
  1627. void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
  1628. {
  1629. int mod, rl, rh;
  1630. u8 *destreg, *srcreg;
  1631. uint destoffset;
  1632. u8 destval;
  1633. u8 tmp;
  1634. START_OF_INSTR();
  1635. DECODE_PRINTF("XCHG\t");
  1636. FETCH_DECODE_MODRM(mod, rh, rl);
  1637. if (mod < 3) {
  1638. destoffset = decode_rmXX_address(mod, rl);
  1639. DECODE_PRINTF(",");
  1640. destval = fetch_data_byte(destoffset);
  1641. srcreg = DECODE_RM_BYTE_REGISTER(rh);
  1642. DECODE_PRINTF("\n");
  1643. TRACE_AND_STEP();
  1644. tmp = *srcreg;
  1645. *srcreg = destval;
  1646. destval = tmp;
  1647. store_data_byte(destoffset, destval);
  1648. } else { /* register to register */
  1649. destreg = DECODE_RM_BYTE_REGISTER(rl);
  1650. DECODE_PRINTF(",");
  1651. srcreg = DECODE_RM_BYTE_REGISTER(rh);
  1652. DECODE_PRINTF("\n");
  1653. TRACE_AND_STEP();
  1654. tmp = *srcreg;
  1655. *srcreg = *destreg;
  1656. *destreg = tmp;
  1657. }
  1658. DECODE_CLEAR_SEGOVR();
  1659. END_OF_INSTR();
  1660. }
  1661. /****************************************************************************
  1662. REMARKS:
  1663. Handles opcode 0x87
  1664. ****************************************************************************/
  1665. void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
  1666. {
  1667. int mod, rl, rh;
  1668. uint destoffset;
  1669. START_OF_INSTR();
  1670. DECODE_PRINTF("XCHG\t");
  1671. FETCH_DECODE_MODRM(mod, rh, rl);
  1672. if (mod < 3) {
  1673. destoffset = decode_rmXX_address(mod, rl);
  1674. DECODE_PRINTF(",");
  1675. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1676. u32 *srcreg;
  1677. u32 destval,tmp;
  1678. destval = fetch_data_long(destoffset);
  1679. srcreg = DECODE_RM_LONG_REGISTER(rh);
  1680. DECODE_PRINTF("\n");
  1681. TRACE_AND_STEP();
  1682. tmp = *srcreg;
  1683. *srcreg = destval;
  1684. destval = tmp;
  1685. store_data_long(destoffset, destval);
  1686. } else {
  1687. u16 *srcreg;
  1688. u16 destval,tmp;
  1689. destval = fetch_data_word(destoffset);
  1690. srcreg = DECODE_RM_WORD_REGISTER(rh);
  1691. DECODE_PRINTF("\n");
  1692. TRACE_AND_STEP();
  1693. tmp = *srcreg;
  1694. *srcreg = destval;
  1695. destval = tmp;
  1696. store_data_word(destoffset, destval);
  1697. }
  1698. } else { /* register to register */
  1699. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1700. u32 *destreg,*srcreg;
  1701. u32 tmp;
  1702. destreg = DECODE_RM_LONG_REGISTER(rl);
  1703. DECODE_PRINTF(",");
  1704. srcreg = DECODE_RM_LONG_REGISTER(rh);
  1705. DECODE_PRINTF("\n");
  1706. TRACE_AND_STEP();
  1707. tmp = *srcreg;
  1708. *srcreg = *destreg;
  1709. *destreg = tmp;
  1710. } else {
  1711. u16 *destreg,*srcreg;
  1712. u16 tmp;
  1713. destreg = DECODE_RM_WORD_REGISTER(rl);
  1714. DECODE_PRINTF(",");
  1715. srcreg = DECODE_RM_WORD_REGISTER(rh);
  1716. DECODE_PRINTF("\n");
  1717. TRACE_AND_STEP();
  1718. tmp = *srcreg;
  1719. *srcreg = *destreg;
  1720. *destreg = tmp;
  1721. }
  1722. }
  1723. DECODE_CLEAR_SEGOVR();
  1724. END_OF_INSTR();
  1725. }
  1726. /****************************************************************************
  1727. REMARKS:
  1728. Handles opcode 0x88
  1729. ****************************************************************************/
  1730. void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
  1731. {
  1732. int mod, rl, rh;
  1733. u8 *destreg, *srcreg;
  1734. uint destoffset;
  1735. START_OF_INSTR();
  1736. DECODE_PRINTF("MOV\t");
  1737. FETCH_DECODE_MODRM(mod, rh, rl);
  1738. if (mod < 3) {
  1739. destoffset = decode_rmXX_address(mod, rl);
  1740. DECODE_PRINTF(",");
  1741. srcreg = DECODE_RM_BYTE_REGISTER(rh);
  1742. DECODE_PRINTF("\n");
  1743. TRACE_AND_STEP();
  1744. store_data_byte(destoffset, *srcreg);
  1745. } else { /* register to register */
  1746. destreg = DECODE_RM_BYTE_REGISTER(rl);
  1747. DECODE_PRINTF(",");
  1748. srcreg = DECODE_RM_BYTE_REGISTER(rh);
  1749. DECODE_PRINTF("\n");
  1750. TRACE_AND_STEP();
  1751. *destreg = *srcreg;
  1752. }
  1753. DECODE_CLEAR_SEGOVR();
  1754. END_OF_INSTR();
  1755. }
  1756. /****************************************************************************
  1757. REMARKS:
  1758. Handles opcode 0x89
  1759. ****************************************************************************/
  1760. void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
  1761. {
  1762. int mod, rl, rh;
  1763. uint destoffset;
  1764. START_OF_INSTR();
  1765. DECODE_PRINTF("MOV\t");
  1766. FETCH_DECODE_MODRM(mod, rh, rl);
  1767. if (mod < 3) {
  1768. destoffset = decode_rmXX_address(mod, rl);
  1769. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1770. u32 *srcreg;
  1771. DECODE_PRINTF(",");
  1772. srcreg = DECODE_RM_LONG_REGISTER(rh);
  1773. DECODE_PRINTF("\n");
  1774. TRACE_AND_STEP();
  1775. store_data_long(destoffset, *srcreg);
  1776. } else {
  1777. u16 *srcreg;
  1778. DECODE_PRINTF(",");
  1779. srcreg = DECODE_RM_WORD_REGISTER(rh);
  1780. DECODE_PRINTF("\n");
  1781. TRACE_AND_STEP();
  1782. store_data_word(destoffset, *srcreg);
  1783. }
  1784. } else { /* register to register */
  1785. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1786. u32 *destreg,*srcreg;
  1787. destreg = DECODE_RM_LONG_REGISTER(rl);
  1788. DECODE_PRINTF(",");
  1789. srcreg = DECODE_RM_LONG_REGISTER(rh);
  1790. DECODE_PRINTF("\n");
  1791. TRACE_AND_STEP();
  1792. *destreg = *srcreg;
  1793. } else {
  1794. u16 *destreg,*srcreg;
  1795. destreg = DECODE_RM_WORD_REGISTER(rl);
  1796. DECODE_PRINTF(",");
  1797. srcreg = DECODE_RM_WORD_REGISTER(rh);
  1798. DECODE_PRINTF("\n");
  1799. TRACE_AND_STEP();
  1800. *destreg = *srcreg;
  1801. }
  1802. }
  1803. DECODE_CLEAR_SEGOVR();
  1804. END_OF_INSTR();
  1805. }
  1806. /****************************************************************************
  1807. REMARKS:
  1808. Handles opcode 0x8a
  1809. ****************************************************************************/
  1810. void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
  1811. {
  1812. int mod, rl, rh;
  1813. u8 *destreg, *srcreg;
  1814. uint srcoffset;
  1815. u8 srcval;
  1816. START_OF_INSTR();
  1817. DECODE_PRINTF("MOV\t");
  1818. FETCH_DECODE_MODRM(mod, rh, rl);
  1819. if (mod < 3) {
  1820. destreg = DECODE_RM_BYTE_REGISTER(rh);
  1821. DECODE_PRINTF(",");
  1822. srcoffset = decode_rmXX_address(mod, rl);
  1823. srcval = fetch_data_byte(srcoffset);
  1824. DECODE_PRINTF("\n");
  1825. TRACE_AND_STEP();
  1826. *destreg = srcval;
  1827. } else { /* register to register */
  1828. destreg = DECODE_RM_BYTE_REGISTER(rh);
  1829. DECODE_PRINTF(",");
  1830. srcreg = DECODE_RM_BYTE_REGISTER(rl);
  1831. DECODE_PRINTF("\n");
  1832. TRACE_AND_STEP();
  1833. *destreg = *srcreg;
  1834. }
  1835. DECODE_CLEAR_SEGOVR();
  1836. END_OF_INSTR();
  1837. }
  1838. /****************************************************************************
  1839. REMARKS:
  1840. Handles opcode 0x8b
  1841. ****************************************************************************/
  1842. void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
  1843. {
  1844. int mod, rl, rh;
  1845. uint srcoffset;
  1846. START_OF_INSTR();
  1847. DECODE_PRINTF("MOV\t");
  1848. FETCH_DECODE_MODRM(mod, rh, rl);
  1849. if (mod < 3) {
  1850. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1851. u32 *destreg;
  1852. u32 srcval;
  1853. destreg = DECODE_RM_LONG_REGISTER(rh);
  1854. DECODE_PRINTF(",");
  1855. srcoffset = decode_rmXX_address(mod, rl);
  1856. srcval = fetch_data_long(srcoffset);
  1857. DECODE_PRINTF("\n");
  1858. TRACE_AND_STEP();
  1859. *destreg = srcval;
  1860. } else {
  1861. u16 *destreg;
  1862. u16 srcval;
  1863. destreg = DECODE_RM_WORD_REGISTER(rh);
  1864. DECODE_PRINTF(",");
  1865. srcoffset = decode_rmXX_address(mod, rl);
  1866. srcval = fetch_data_word(srcoffset);
  1867. DECODE_PRINTF("\n");
  1868. TRACE_AND_STEP();
  1869. *destreg = srcval;
  1870. }
  1871. } else { /* register to register */
  1872. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  1873. u32 *destreg, *srcreg;
  1874. destreg = DECODE_RM_LONG_REGISTER(rh);
  1875. DECODE_PRINTF(",");
  1876. srcreg = DECODE_RM_LONG_REGISTER(rl);
  1877. DECODE_PRINTF("\n");
  1878. TRACE_AND_STEP();
  1879. *destreg = *srcreg;
  1880. } else {
  1881. u16 *destreg, *srcreg;
  1882. destreg = DECODE_RM_WORD_REGISTER(rh);
  1883. DECODE_PRINTF(",");
  1884. srcreg = DECODE_RM_WORD_REGISTER(rl);
  1885. DECODE_PRINTF("\n");
  1886. TRACE_AND_STEP();
  1887. *destreg = *srcreg;
  1888. }
  1889. }
  1890. DECODE_CLEAR_SEGOVR();
  1891. END_OF_INSTR();
  1892. }
  1893. /****************************************************************************
  1894. REMARKS:
  1895. Handles opcode 0x8c
  1896. ****************************************************************************/
  1897. void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
  1898. {
  1899. int mod, rl, rh;
  1900. u16 *destreg, *srcreg;
  1901. uint destoffset;
  1902. u16 destval;
  1903. START_OF_INSTR();
  1904. DECODE_PRINTF("MOV\t");
  1905. FETCH_DECODE_MODRM(mod, rh, rl);
  1906. if (mod < 3) {
  1907. destoffset = decode_rmXX_address(mod, rl);
  1908. DECODE_PRINTF(",");
  1909. srcreg = decode_rm_seg_register(rh);
  1910. DECODE_PRINTF("\n");
  1911. TRACE_AND_STEP();
  1912. destval = *srcreg;
  1913. store_data_word(destoffset, destval);
  1914. } else { /* register to register */
  1915. destreg = DECODE_RM_WORD_REGISTER(rl);
  1916. DECODE_PRINTF(",");
  1917. srcreg = decode_rm_seg_register(rh);
  1918. DECODE_PRINTF("\n");
  1919. TRACE_AND_STEP();
  1920. *destreg = *srcreg;
  1921. }
  1922. DECODE_CLEAR_SEGOVR();
  1923. END_OF_INSTR();
  1924. }
  1925. /****************************************************************************
  1926. REMARKS:
  1927. Handles opcode 0x8d
  1928. ****************************************************************************/
  1929. void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
  1930. {
  1931. int mod, rl, rh;
  1932. u16 *srcreg;
  1933. uint destoffset;
  1934. /*
  1935. * TODO: Need to handle address size prefix!
  1936. *
  1937. * lea eax,[eax+ebx*2] ??
  1938. */
  1939. START_OF_INSTR();
  1940. DECODE_PRINTF("LEA\t");
  1941. FETCH_DECODE_MODRM(mod, rh, rl);
  1942. if (mod < 3) {
  1943. srcreg = DECODE_RM_WORD_REGISTER(rh);
  1944. DECODE_PRINTF(",");
  1945. destoffset = decode_rmXX_address(mod, rl);
  1946. DECODE_PRINTF("\n");
  1947. TRACE_AND_STEP();
  1948. *srcreg = (u16)destoffset;
  1949. }
  1950. /* } else { undefined. Do nothing. } */
  1951. DECODE_CLEAR_SEGOVR();
  1952. END_OF_INSTR();
  1953. }
  1954. /****************************************************************************
  1955. REMARKS:
  1956. Handles opcode 0x8e
  1957. ****************************************************************************/
  1958. void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
  1959. {
  1960. int mod, rl, rh;
  1961. u16 *destreg, *srcreg;
  1962. uint srcoffset;
  1963. u16 srcval;
  1964. START_OF_INSTR();
  1965. DECODE_PRINTF("MOV\t");
  1966. FETCH_DECODE_MODRM(mod, rh, rl);
  1967. if (mod < 3) {
  1968. destreg = decode_rm_seg_register(rh);
  1969. DECODE_PRINTF(",");
  1970. srcoffset = decode_rmXX_address(mod, rl);
  1971. srcval = fetch_data_word(srcoffset);
  1972. DECODE_PRINTF("\n");
  1973. TRACE_AND_STEP();
  1974. *destreg = srcval;
  1975. } else { /* register to register */
  1976. destreg = decode_rm_seg_register(rh);
  1977. DECODE_PRINTF(",");
  1978. srcreg = DECODE_RM_WORD_REGISTER(rl);
  1979. DECODE_PRINTF("\n");
  1980. TRACE_AND_STEP();
  1981. *destreg = *srcreg;
  1982. }
  1983. /*
  1984. * Clean up, and reset all the R_xSP pointers to the correct
  1985. * locations. This is about 3x too much overhead (doing all the
  1986. * segreg ptrs when only one is needed, but this instruction
  1987. * *cannot* be that common, and this isn't too much work anyway.
  1988. */
  1989. DECODE_CLEAR_SEGOVR();
  1990. END_OF_INSTR();
  1991. }
  1992. /****************************************************************************
  1993. REMARKS:
  1994. Handles opcode 0x8f
  1995. ****************************************************************************/
  1996. void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
  1997. {
  1998. int mod, rl, rh;
  1999. uint destoffset;
  2000. START_OF_INSTR();
  2001. DECODE_PRINTF("POP\t");
  2002. FETCH_DECODE_MODRM(mod, rh, rl);
  2003. if (rh != 0) {
  2004. DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
  2005. HALT_SYS();
  2006. }
  2007. if (mod < 3) {
  2008. destoffset = decode_rmXX_address(mod, rl);
  2009. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2010. u32 destval;
  2011. DECODE_PRINTF("\n");
  2012. TRACE_AND_STEP();
  2013. destval = pop_long();
  2014. store_data_long(destoffset, destval);
  2015. } else {
  2016. u16 destval;
  2017. DECODE_PRINTF("\n");
  2018. TRACE_AND_STEP();
  2019. destval = pop_word();
  2020. store_data_word(destoffset, destval);
  2021. }
  2022. } else { /* register to register */
  2023. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2024. u32 *destreg;
  2025. destreg = DECODE_RM_LONG_REGISTER(rl);
  2026. DECODE_PRINTF("\n");
  2027. TRACE_AND_STEP();
  2028. *destreg = pop_long();
  2029. } else {
  2030. u16 *destreg;
  2031. destreg = DECODE_RM_WORD_REGISTER(rl);
  2032. DECODE_PRINTF("\n");
  2033. TRACE_AND_STEP();
  2034. *destreg = pop_word();
  2035. }
  2036. }
  2037. DECODE_CLEAR_SEGOVR();
  2038. END_OF_INSTR();
  2039. }
  2040. /****************************************************************************
  2041. REMARKS:
  2042. Handles opcode 0x90
  2043. ****************************************************************************/
  2044. void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
  2045. {
  2046. START_OF_INSTR();
  2047. DECODE_PRINTF("NOP\n");
  2048. TRACE_AND_STEP();
  2049. DECODE_CLEAR_SEGOVR();
  2050. END_OF_INSTR();
  2051. }
  2052. /****************************************************************************
  2053. REMARKS:
  2054. Handles opcode 0x91-0x97
  2055. ****************************************************************************/
  2056. void x86emuOp_xchg_word_AX_register(u8 X86EMU_UNUSED(op1))
  2057. {
  2058. u32 tmp;
  2059. op1 &= 0x7;
  2060. START_OF_INSTR();
  2061. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2062. u32 *reg32;
  2063. DECODE_PRINTF("XCHG\tEAX,");
  2064. reg32 = DECODE_RM_LONG_REGISTER(op1);
  2065. DECODE_PRINTF("\n");
  2066. TRACE_AND_STEP();
  2067. tmp = M.x86.R_EAX;
  2068. M.x86.R_EAX = *reg32;
  2069. *reg32 = tmp;
  2070. } else {
  2071. u16 *reg16;
  2072. DECODE_PRINTF("XCHG\tAX,");
  2073. reg16 = DECODE_RM_WORD_REGISTER(op1);
  2074. DECODE_PRINTF("\n");
  2075. TRACE_AND_STEP();
  2076. tmp = M.x86.R_AX;
  2077. M.x86.R_EAX = *reg16;
  2078. *reg16 = (u16)tmp;
  2079. }
  2080. DECODE_CLEAR_SEGOVR();
  2081. END_OF_INSTR();
  2082. }
  2083. /****************************************************************************
  2084. REMARKS:
  2085. Handles opcode 0x98
  2086. ****************************************************************************/
  2087. void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
  2088. {
  2089. START_OF_INSTR();
  2090. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2091. DECODE_PRINTF("CWDE\n");
  2092. } else {
  2093. DECODE_PRINTF("CBW\n");
  2094. }
  2095. TRACE_AND_STEP();
  2096. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2097. if (M.x86.R_AX & 0x8000) {
  2098. M.x86.R_EAX |= 0xffff0000;
  2099. } else {
  2100. M.x86.R_EAX &= 0x0000ffff;
  2101. }
  2102. } else {
  2103. if (M.x86.R_AL & 0x80) {
  2104. M.x86.R_AH = 0xff;
  2105. } else {
  2106. M.x86.R_AH = 0x0;
  2107. }
  2108. }
  2109. DECODE_CLEAR_SEGOVR();
  2110. END_OF_INSTR();
  2111. }
  2112. /****************************************************************************
  2113. REMARKS:
  2114. Handles opcode 0x99
  2115. ****************************************************************************/
  2116. void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
  2117. {
  2118. START_OF_INSTR();
  2119. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2120. DECODE_PRINTF("CDQ\n");
  2121. } else {
  2122. DECODE_PRINTF("CWD\n");
  2123. }
  2124. DECODE_PRINTF("CWD\n");
  2125. TRACE_AND_STEP();
  2126. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2127. if (M.x86.R_EAX & 0x80000000) {
  2128. M.x86.R_EDX = 0xffffffff;
  2129. } else {
  2130. M.x86.R_EDX = 0x0;
  2131. }
  2132. } else {
  2133. if (M.x86.R_AX & 0x8000) {
  2134. M.x86.R_DX = 0xffff;
  2135. } else {
  2136. M.x86.R_DX = 0x0;
  2137. }
  2138. }
  2139. DECODE_CLEAR_SEGOVR();
  2140. END_OF_INSTR();
  2141. }
  2142. /****************************************************************************
  2143. REMARKS:
  2144. Handles opcode 0x9a
  2145. ****************************************************************************/
  2146. void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
  2147. {
  2148. u16 farseg, faroff;
  2149. START_OF_INSTR();
  2150. DECODE_PRINTF("CALL\t");
  2151. faroff = fetch_word_imm();
  2152. farseg = fetch_word_imm();
  2153. DECODE_PRINTF2("%04x:", farseg);
  2154. DECODE_PRINTF2("%04x\n", faroff);
  2155. CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
  2156. /* XXX
  2157. *
  2158. * Hooked interrupt vectors calling into our "BIOS" will cause
  2159. * problems unless all intersegment stuff is checked for BIOS
  2160. * access. Check needed here. For moment, let it alone.
  2161. */
  2162. TRACE_AND_STEP();
  2163. push_word(M.x86.R_CS);
  2164. M.x86.R_CS = farseg;
  2165. push_word(M.x86.R_IP);
  2166. M.x86.R_IP = faroff;
  2167. DECODE_CLEAR_SEGOVR();
  2168. END_OF_INSTR();
  2169. }
  2170. /****************************************************************************
  2171. REMARKS:
  2172. Handles opcode 0x9b
  2173. ****************************************************************************/
  2174. void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
  2175. {
  2176. START_OF_INSTR();
  2177. DECODE_PRINTF("WAIT");
  2178. TRACE_AND_STEP();
  2179. /* NADA. */
  2180. DECODE_CLEAR_SEGOVR();
  2181. END_OF_INSTR();
  2182. }
  2183. /****************************************************************************
  2184. REMARKS:
  2185. Handles opcode 0x9c
  2186. ****************************************************************************/
  2187. void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
  2188. {
  2189. u32 flags;
  2190. START_OF_INSTR();
  2191. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2192. DECODE_PRINTF("PUSHFD\n");
  2193. } else {
  2194. DECODE_PRINTF("PUSHF\n");
  2195. }
  2196. TRACE_AND_STEP();
  2197. /* clear out *all* bits not representing flags, and turn on real bits */
  2198. flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
  2199. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2200. push_long(flags);
  2201. } else {
  2202. push_word((u16)flags);
  2203. }
  2204. DECODE_CLEAR_SEGOVR();
  2205. END_OF_INSTR();
  2206. }
  2207. /****************************************************************************
  2208. REMARKS:
  2209. Handles opcode 0x9d
  2210. ****************************************************************************/
  2211. void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
  2212. {
  2213. START_OF_INSTR();
  2214. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2215. DECODE_PRINTF("POPFD\n");
  2216. } else {
  2217. DECODE_PRINTF("POPF\n");
  2218. }
  2219. TRACE_AND_STEP();
  2220. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2221. M.x86.R_EFLG = pop_long();
  2222. } else {
  2223. M.x86.R_FLG = pop_word();
  2224. }
  2225. DECODE_CLEAR_SEGOVR();
  2226. END_OF_INSTR();
  2227. }
  2228. /****************************************************************************
  2229. REMARKS:
  2230. Handles opcode 0x9e
  2231. ****************************************************************************/
  2232. void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
  2233. {
  2234. START_OF_INSTR();
  2235. DECODE_PRINTF("SAHF\n");
  2236. TRACE_AND_STEP();
  2237. /* clear the lower bits of the flag register */
  2238. M.x86.R_FLG &= 0xffffff00;
  2239. /* or in the AH register into the flags register */
  2240. M.x86.R_FLG |= M.x86.R_AH;
  2241. DECODE_CLEAR_SEGOVR();
  2242. END_OF_INSTR();
  2243. }
  2244. /****************************************************************************
  2245. REMARKS:
  2246. Handles opcode 0x9f
  2247. ****************************************************************************/
  2248. void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
  2249. {
  2250. START_OF_INSTR();
  2251. DECODE_PRINTF("LAHF\n");
  2252. TRACE_AND_STEP();
  2253. M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
  2254. /*undocumented TC++ behavior??? Nope. It's documented, but
  2255. you have too look real hard to notice it. */
  2256. M.x86.R_AH |= 0x2;
  2257. DECODE_CLEAR_SEGOVR();
  2258. END_OF_INSTR();
  2259. }
  2260. /****************************************************************************
  2261. REMARKS:
  2262. Handles opcode 0xa0
  2263. ****************************************************************************/
  2264. void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
  2265. {
  2266. u16 offset;
  2267. START_OF_INSTR();
  2268. DECODE_PRINTF("MOV\tAL,");
  2269. offset = fetch_word_imm();
  2270. DECODE_PRINTF2("[%04x]\n", offset);
  2271. TRACE_AND_STEP();
  2272. M.x86.R_AL = fetch_data_byte(offset);
  2273. DECODE_CLEAR_SEGOVR();
  2274. END_OF_INSTR();
  2275. }
  2276. /****************************************************************************
  2277. REMARKS:
  2278. Handles opcode 0xa1
  2279. ****************************************************************************/
  2280. void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
  2281. {
  2282. u16 offset;
  2283. START_OF_INSTR();
  2284. offset = fetch_word_imm();
  2285. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2286. DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
  2287. } else {
  2288. DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
  2289. }
  2290. TRACE_AND_STEP();
  2291. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2292. M.x86.R_EAX = fetch_data_long(offset);
  2293. } else {
  2294. M.x86.R_AX = fetch_data_word(offset);
  2295. }
  2296. DECODE_CLEAR_SEGOVR();
  2297. END_OF_INSTR();
  2298. }
  2299. /****************************************************************************
  2300. REMARKS:
  2301. Handles opcode 0xa2
  2302. ****************************************************************************/
  2303. void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
  2304. {
  2305. u16 offset;
  2306. START_OF_INSTR();
  2307. DECODE_PRINTF("MOV\t");
  2308. offset = fetch_word_imm();
  2309. DECODE_PRINTF2("[%04x],AL\n", offset);
  2310. TRACE_AND_STEP();
  2311. store_data_byte(offset, M.x86.R_AL);
  2312. DECODE_CLEAR_SEGOVR();
  2313. END_OF_INSTR();
  2314. }
  2315. /****************************************************************************
  2316. REMARKS:
  2317. Handles opcode 0xa3
  2318. ****************************************************************************/
  2319. void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
  2320. {
  2321. u16 offset;
  2322. START_OF_INSTR();
  2323. offset = fetch_word_imm();
  2324. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2325. DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
  2326. } else {
  2327. DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
  2328. }
  2329. TRACE_AND_STEP();
  2330. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2331. store_data_long(offset, M.x86.R_EAX);
  2332. } else {
  2333. store_data_word(offset, M.x86.R_AX);
  2334. }
  2335. DECODE_CLEAR_SEGOVR();
  2336. END_OF_INSTR();
  2337. }
  2338. /****************************************************************************
  2339. REMARKS:
  2340. Handles opcode 0xa4
  2341. ****************************************************************************/
  2342. void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
  2343. {
  2344. u8 val;
  2345. u32 count;
  2346. int inc;
  2347. START_OF_INSTR();
  2348. DECODE_PRINTF("MOVS\tBYTE\n");
  2349. if (ACCESS_FLAG(F_DF)) /* down */
  2350. inc = -1;
  2351. else
  2352. inc = 1;
  2353. TRACE_AND_STEP();
  2354. count = 1;
  2355. if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  2356. /* dont care whether REPE or REPNE */
  2357. /* move them until CX is ZERO. */
  2358. count = M.x86.R_CX;
  2359. M.x86.R_CX = 0;
  2360. M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  2361. }
  2362. while (count--) {
  2363. val = fetch_data_byte(M.x86.R_SI);
  2364. store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
  2365. M.x86.R_SI += inc;
  2366. M.x86.R_DI += inc;
  2367. }
  2368. DECODE_CLEAR_SEGOVR();
  2369. END_OF_INSTR();
  2370. }
  2371. /****************************************************************************
  2372. REMARKS:
  2373. Handles opcode 0xa5
  2374. ****************************************************************************/
  2375. void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
  2376. {
  2377. u32 val;
  2378. int inc;
  2379. u32 count;
  2380. START_OF_INSTR();
  2381. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2382. DECODE_PRINTF("MOVS\tDWORD\n");
  2383. if (ACCESS_FLAG(F_DF)) /* down */
  2384. inc = -4;
  2385. else
  2386. inc = 4;
  2387. } else {
  2388. DECODE_PRINTF("MOVS\tWORD\n");
  2389. if (ACCESS_FLAG(F_DF)) /* down */
  2390. inc = -2;
  2391. else
  2392. inc = 2;
  2393. }
  2394. TRACE_AND_STEP();
  2395. count = 1;
  2396. if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  2397. /* dont care whether REPE or REPNE */
  2398. /* move them until CX is ZERO. */
  2399. count = M.x86.R_CX;
  2400. M.x86.R_CX = 0;
  2401. M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  2402. }
  2403. while (count--) {
  2404. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2405. val = fetch_data_long(M.x86.R_SI);
  2406. store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
  2407. } else {
  2408. val = fetch_data_word(M.x86.R_SI);
  2409. store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
  2410. }
  2411. M.x86.R_SI += inc;
  2412. M.x86.R_DI += inc;
  2413. }
  2414. DECODE_CLEAR_SEGOVR();
  2415. END_OF_INSTR();
  2416. }
  2417. /****************************************************************************
  2418. REMARKS:
  2419. Handles opcode 0xa6
  2420. ****************************************************************************/
  2421. void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
  2422. {
  2423. s8 val1, val2;
  2424. int inc;
  2425. START_OF_INSTR();
  2426. DECODE_PRINTF("CMPS\tBYTE\n");
  2427. TRACE_AND_STEP();
  2428. if (ACCESS_FLAG(F_DF)) /* down */
  2429. inc = -1;
  2430. else
  2431. inc = 1;
  2432. if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  2433. /* REPE */
  2434. /* move them until CX is ZERO. */
  2435. while (M.x86.R_CX != 0) {
  2436. val1 = fetch_data_byte(M.x86.R_SI);
  2437. val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
  2438. cmp_byte(val1, val2);
  2439. M.x86.R_CX -= 1;
  2440. M.x86.R_SI += inc;
  2441. M.x86.R_DI += inc;
  2442. if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && (ACCESS_FLAG(F_ZF) == 0) ) break;
  2443. if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break;
  2444. }
  2445. M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  2446. } else {
  2447. val1 = fetch_data_byte(M.x86.R_SI);
  2448. val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
  2449. cmp_byte(val1, val2);
  2450. M.x86.R_SI += inc;
  2451. M.x86.R_DI += inc;
  2452. }
  2453. DECODE_CLEAR_SEGOVR();
  2454. END_OF_INSTR();
  2455. }
  2456. /****************************************************************************
  2457. REMARKS:
  2458. Handles opcode 0xa7
  2459. ****************************************************************************/
  2460. void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
  2461. {
  2462. u32 val1,val2;
  2463. int inc;
  2464. START_OF_INSTR();
  2465. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2466. DECODE_PRINTF("CMPS\tDWORD\n");
  2467. inc = 4;
  2468. } else {
  2469. DECODE_PRINTF("CMPS\tWORD\n");
  2470. inc = 2;
  2471. }
  2472. if (ACCESS_FLAG(F_DF)) /* down */
  2473. inc = -inc;
  2474. TRACE_AND_STEP();
  2475. if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  2476. /* REPE */
  2477. /* move them until CX is ZERO. */
  2478. while (M.x86.R_CX != 0) {
  2479. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2480. val1 = fetch_data_long(M.x86.R_SI);
  2481. val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
  2482. cmp_long(val1, val2);
  2483. } else {
  2484. val1 = fetch_data_word(M.x86.R_SI);
  2485. val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
  2486. cmp_word((u16)val1, (u16)val2);
  2487. }
  2488. M.x86.R_CX -= 1;
  2489. M.x86.R_SI += inc;
  2490. M.x86.R_DI += inc;
  2491. if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && ACCESS_FLAG(F_ZF) == 0 ) break;
  2492. if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break;
  2493. }
  2494. M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  2495. } else {
  2496. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2497. val1 = fetch_data_long(M.x86.R_SI);
  2498. val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
  2499. cmp_long(val1, val2);
  2500. } else {
  2501. val1 = fetch_data_word(M.x86.R_SI);
  2502. val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
  2503. cmp_word((u16)val1, (u16)val2);
  2504. }
  2505. M.x86.R_SI += inc;
  2506. M.x86.R_DI += inc;
  2507. }
  2508. DECODE_CLEAR_SEGOVR();
  2509. END_OF_INSTR();
  2510. }
  2511. /****************************************************************************
  2512. REMARKS:
  2513. Handles opcode 0xa8
  2514. ****************************************************************************/
  2515. void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
  2516. {
  2517. int imm;
  2518. START_OF_INSTR();
  2519. DECODE_PRINTF("TEST\tAL,");
  2520. imm = fetch_byte_imm();
  2521. DECODE_PRINTF2("%04x\n", imm);
  2522. TRACE_AND_STEP();
  2523. test_byte(M.x86.R_AL, (u8)imm);
  2524. DECODE_CLEAR_SEGOVR();
  2525. END_OF_INSTR();
  2526. }
  2527. /****************************************************************************
  2528. REMARKS:
  2529. Handles opcode 0xa9
  2530. ****************************************************************************/
  2531. void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
  2532. {
  2533. u32 srcval;
  2534. START_OF_INSTR();
  2535. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2536. DECODE_PRINTF("TEST\tEAX,");
  2537. srcval = fetch_long_imm();
  2538. } else {
  2539. DECODE_PRINTF("TEST\tAX,");
  2540. srcval = fetch_word_imm();
  2541. }
  2542. DECODE_PRINTF2("%x\n", srcval);
  2543. TRACE_AND_STEP();
  2544. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2545. test_long(M.x86.R_EAX, srcval);
  2546. } else {
  2547. test_word(M.x86.R_AX, (u16)srcval);
  2548. }
  2549. DECODE_CLEAR_SEGOVR();
  2550. END_OF_INSTR();
  2551. }
  2552. /****************************************************************************
  2553. REMARKS:
  2554. Handles opcode 0xaa
  2555. ****************************************************************************/
  2556. void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
  2557. {
  2558. int inc;
  2559. START_OF_INSTR();
  2560. DECODE_PRINTF("STOS\tBYTE\n");
  2561. if (ACCESS_FLAG(F_DF)) /* down */
  2562. inc = -1;
  2563. else
  2564. inc = 1;
  2565. TRACE_AND_STEP();
  2566. if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  2567. /* dont care whether REPE or REPNE */
  2568. /* move them until CX is ZERO. */
  2569. while (M.x86.R_CX != 0) {
  2570. store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
  2571. M.x86.R_CX -= 1;
  2572. M.x86.R_DI += inc;
  2573. }
  2574. M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  2575. } else {
  2576. store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
  2577. M.x86.R_DI += inc;
  2578. }
  2579. DECODE_CLEAR_SEGOVR();
  2580. END_OF_INSTR();
  2581. }
  2582. /****************************************************************************
  2583. REMARKS:
  2584. Handles opcode 0xab
  2585. ****************************************************************************/
  2586. void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
  2587. {
  2588. int inc;
  2589. u32 count;
  2590. START_OF_INSTR();
  2591. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2592. DECODE_PRINTF("STOS\tDWORD\n");
  2593. if (ACCESS_FLAG(F_DF)) /* down */
  2594. inc = -4;
  2595. else
  2596. inc = 4;
  2597. } else {
  2598. DECODE_PRINTF("STOS\tWORD\n");
  2599. if (ACCESS_FLAG(F_DF)) /* down */
  2600. inc = -2;
  2601. else
  2602. inc = 2;
  2603. }
  2604. TRACE_AND_STEP();
  2605. count = 1;
  2606. if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  2607. /* dont care whether REPE or REPNE */
  2608. /* move them until CX is ZERO. */
  2609. count = M.x86.R_CX;
  2610. M.x86.R_CX = 0;
  2611. M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  2612. }
  2613. while (count--) {
  2614. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2615. store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
  2616. } else {
  2617. store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
  2618. }
  2619. M.x86.R_DI += inc;
  2620. }
  2621. DECODE_CLEAR_SEGOVR();
  2622. END_OF_INSTR();
  2623. }
  2624. /****************************************************************************
  2625. REMARKS:
  2626. Handles opcode 0xac
  2627. ****************************************************************************/
  2628. void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
  2629. {
  2630. int inc;
  2631. START_OF_INSTR();
  2632. DECODE_PRINTF("LODS\tBYTE\n");
  2633. TRACE_AND_STEP();
  2634. if (ACCESS_FLAG(F_DF)) /* down */
  2635. inc = -1;
  2636. else
  2637. inc = 1;
  2638. if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  2639. /* dont care whether REPE or REPNE */
  2640. /* move them until CX is ZERO. */
  2641. while (M.x86.R_CX != 0) {
  2642. M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
  2643. M.x86.R_CX -= 1;
  2644. M.x86.R_SI += inc;
  2645. }
  2646. M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  2647. } else {
  2648. M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
  2649. M.x86.R_SI += inc;
  2650. }
  2651. DECODE_CLEAR_SEGOVR();
  2652. END_OF_INSTR();
  2653. }
  2654. /****************************************************************************
  2655. REMARKS:
  2656. Handles opcode 0xad
  2657. ****************************************************************************/
  2658. void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
  2659. {
  2660. int inc;
  2661. u32 count;
  2662. START_OF_INSTR();
  2663. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2664. DECODE_PRINTF("LODS\tDWORD\n");
  2665. if (ACCESS_FLAG(F_DF)) /* down */
  2666. inc = -4;
  2667. else
  2668. inc = 4;
  2669. } else {
  2670. DECODE_PRINTF("LODS\tWORD\n");
  2671. if (ACCESS_FLAG(F_DF)) /* down */
  2672. inc = -2;
  2673. else
  2674. inc = 2;
  2675. }
  2676. TRACE_AND_STEP();
  2677. count = 1;
  2678. if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  2679. /* dont care whether REPE or REPNE */
  2680. /* move them until CX is ZERO. */
  2681. count = M.x86.R_CX;
  2682. M.x86.R_CX = 0;
  2683. M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  2684. }
  2685. while (count--) {
  2686. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2687. M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
  2688. } else {
  2689. M.x86.R_AX = fetch_data_word(M.x86.R_SI);
  2690. }
  2691. M.x86.R_SI += inc;
  2692. }
  2693. DECODE_CLEAR_SEGOVR();
  2694. END_OF_INSTR();
  2695. }
  2696. /****************************************************************************
  2697. REMARKS:
  2698. Handles opcode 0xae
  2699. ****************************************************************************/
  2700. void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
  2701. {
  2702. s8 val2;
  2703. int inc;
  2704. START_OF_INSTR();
  2705. DECODE_PRINTF("SCAS\tBYTE\n");
  2706. TRACE_AND_STEP();
  2707. if (ACCESS_FLAG(F_DF)) /* down */
  2708. inc = -1;
  2709. else
  2710. inc = 1;
  2711. if (M.x86.mode & SYSMODE_PREFIX_REPE) {
  2712. /* REPE */
  2713. /* move them until CX is ZERO. */
  2714. while (M.x86.R_CX != 0) {
  2715. val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
  2716. cmp_byte(M.x86.R_AL, val2);
  2717. M.x86.R_CX -= 1;
  2718. M.x86.R_DI += inc;
  2719. if (ACCESS_FLAG(F_ZF) == 0)
  2720. break;
  2721. }
  2722. M.x86.mode &= ~SYSMODE_PREFIX_REPE;
  2723. } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
  2724. /* REPNE */
  2725. /* move them until CX is ZERO. */
  2726. while (M.x86.R_CX != 0) {
  2727. val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
  2728. cmp_byte(M.x86.R_AL, val2);
  2729. M.x86.R_CX -= 1;
  2730. M.x86.R_DI += inc;
  2731. if (ACCESS_FLAG(F_ZF))
  2732. break; /* zero flag set means equal */
  2733. }
  2734. M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
  2735. } else {
  2736. val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
  2737. cmp_byte(M.x86.R_AL, val2);
  2738. M.x86.R_DI += inc;
  2739. }
  2740. DECODE_CLEAR_SEGOVR();
  2741. END_OF_INSTR();
  2742. }
  2743. /****************************************************************************
  2744. REMARKS:
  2745. Handles opcode 0xaf
  2746. ****************************************************************************/
  2747. void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
  2748. {
  2749. int inc;
  2750. u32 val;
  2751. START_OF_INSTR();
  2752. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2753. DECODE_PRINTF("SCAS\tDWORD\n");
  2754. if (ACCESS_FLAG(F_DF)) /* down */
  2755. inc = -4;
  2756. else
  2757. inc = 4;
  2758. } else {
  2759. DECODE_PRINTF("SCAS\tWORD\n");
  2760. if (ACCESS_FLAG(F_DF)) /* down */
  2761. inc = -2;
  2762. else
  2763. inc = 2;
  2764. }
  2765. TRACE_AND_STEP();
  2766. if (M.x86.mode & SYSMODE_PREFIX_REPE) {
  2767. /* REPE */
  2768. /* move them until CX is ZERO. */
  2769. while (M.x86.R_CX != 0) {
  2770. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2771. val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
  2772. cmp_long(M.x86.R_EAX, val);
  2773. } else {
  2774. val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
  2775. cmp_word(M.x86.R_AX, (u16)val);
  2776. }
  2777. M.x86.R_CX -= 1;
  2778. M.x86.R_DI += inc;
  2779. if (ACCESS_FLAG(F_ZF) == 0)
  2780. break;
  2781. }
  2782. M.x86.mode &= ~SYSMODE_PREFIX_REPE;
  2783. } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
  2784. /* REPNE */
  2785. /* move them until CX is ZERO. */
  2786. while (M.x86.R_CX != 0) {
  2787. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2788. val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
  2789. cmp_long(M.x86.R_EAX, val);
  2790. } else {
  2791. val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
  2792. cmp_word(M.x86.R_AX, (u16)val);
  2793. }
  2794. M.x86.R_CX -= 1;
  2795. M.x86.R_DI += inc;
  2796. if (ACCESS_FLAG(F_ZF))
  2797. break; /* zero flag set means equal */
  2798. }
  2799. M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
  2800. } else {
  2801. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2802. val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
  2803. cmp_long(M.x86.R_EAX, val);
  2804. } else {
  2805. val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
  2806. cmp_word(M.x86.R_AX, (u16)val);
  2807. }
  2808. M.x86.R_DI += inc;
  2809. }
  2810. DECODE_CLEAR_SEGOVR();
  2811. END_OF_INSTR();
  2812. }
  2813. /****************************************************************************
  2814. REMARKS:
  2815. Handles opcode 0xb0 - 0xb7
  2816. ****************************************************************************/
  2817. void x86emuOp_mov_byte_register_IMM(u8 op1)
  2818. {
  2819. u8 imm, *ptr;
  2820. START_OF_INSTR();
  2821. DECODE_PRINTF("MOV\t");
  2822. ptr = DECODE_RM_BYTE_REGISTER(op1 & 0x7);
  2823. DECODE_PRINTF(",");
  2824. imm = fetch_byte_imm();
  2825. DECODE_PRINTF2("%x\n", imm);
  2826. TRACE_AND_STEP();
  2827. *ptr = imm;
  2828. DECODE_CLEAR_SEGOVR();
  2829. END_OF_INSTR();
  2830. }
  2831. /****************************************************************************
  2832. REMARKS:
  2833. Handles opcode 0xb8 - 0xbf
  2834. ****************************************************************************/
  2835. void x86emuOp_mov_word_register_IMM(u8 X86EMU_UNUSED(op1))
  2836. {
  2837. u32 srcval;
  2838. op1 &= 0x7;
  2839. START_OF_INSTR();
  2840. DECODE_PRINTF("MOV\t");
  2841. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2842. u32 *reg32;
  2843. reg32 = DECODE_RM_LONG_REGISTER(op1);
  2844. srcval = fetch_long_imm();
  2845. DECODE_PRINTF2(",%x\n", srcval);
  2846. TRACE_AND_STEP();
  2847. *reg32 = srcval;
  2848. } else {
  2849. u16 *reg16;
  2850. reg16 = DECODE_RM_WORD_REGISTER(op1);
  2851. srcval = fetch_word_imm();
  2852. DECODE_PRINTF2(",%x\n", srcval);
  2853. TRACE_AND_STEP();
  2854. *reg16 = (u16)srcval;
  2855. }
  2856. DECODE_CLEAR_SEGOVR();
  2857. END_OF_INSTR();
  2858. }
  2859. /****************************************************************************
  2860. REMARKS:
  2861. Handles opcode 0xc0
  2862. ****************************************************************************/
  2863. void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
  2864. {
  2865. int mod, rl, rh;
  2866. u8 *destreg;
  2867. uint destoffset;
  2868. u8 destval;
  2869. u8 amt;
  2870. /*
  2871. * Yet another weirdo special case instruction format. Part of
  2872. * the opcode held below in "RH". Doubly nested case would
  2873. * result, except that the decoded instruction
  2874. */
  2875. START_OF_INSTR();
  2876. FETCH_DECODE_MODRM(mod, rh, rl);
  2877. #ifdef DEBUG
  2878. if (DEBUG_DECODE()) {
  2879. /* XXX DECODE_PRINTF may be changed to something more
  2880. general, so that it is important to leave the strings
  2881. in the same format, even though the result is that the
  2882. above test is done twice. */
  2883. switch (rh) {
  2884. case 0:
  2885. DECODE_PRINTF("ROL\t");
  2886. break;
  2887. case 1:
  2888. DECODE_PRINTF("ROR\t");
  2889. break;
  2890. case 2:
  2891. DECODE_PRINTF("RCL\t");
  2892. break;
  2893. case 3:
  2894. DECODE_PRINTF("RCR\t");
  2895. break;
  2896. case 4:
  2897. DECODE_PRINTF("SHL\t");
  2898. break;
  2899. case 5:
  2900. DECODE_PRINTF("SHR\t");
  2901. break;
  2902. case 6:
  2903. DECODE_PRINTF("SAL\t");
  2904. break;
  2905. case 7:
  2906. DECODE_PRINTF("SAR\t");
  2907. break;
  2908. }
  2909. }
  2910. #endif
  2911. /* know operation, decode the mod byte to find the addressing
  2912. mode. */
  2913. if (mod < 3) {
  2914. DECODE_PRINTF("BYTE PTR ");
  2915. destoffset = decode_rmXX_address(mod, rl);
  2916. amt = fetch_byte_imm();
  2917. DECODE_PRINTF2(",%x\n", amt);
  2918. destval = fetch_data_byte(destoffset);
  2919. TRACE_AND_STEP();
  2920. destval = (*opcD0_byte_operation[rh]) (destval, amt);
  2921. store_data_byte(destoffset, destval);
  2922. } else { /* register to register */
  2923. destreg = DECODE_RM_BYTE_REGISTER(rl);
  2924. amt = fetch_byte_imm();
  2925. DECODE_PRINTF2(",%x\n", amt);
  2926. TRACE_AND_STEP();
  2927. destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
  2928. *destreg = destval;
  2929. }
  2930. DECODE_CLEAR_SEGOVR();
  2931. END_OF_INSTR();
  2932. }
  2933. /****************************************************************************
  2934. REMARKS:
  2935. Handles opcode 0xc1
  2936. ****************************************************************************/
  2937. void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
  2938. {
  2939. int mod, rl, rh;
  2940. uint destoffset;
  2941. u8 amt;
  2942. /*
  2943. * Yet another weirdo special case instruction format. Part of
  2944. * the opcode held below in "RH". Doubly nested case would
  2945. * result, except that the decoded instruction
  2946. */
  2947. START_OF_INSTR();
  2948. FETCH_DECODE_MODRM(mod, rh, rl);
  2949. #ifdef DEBUG
  2950. if (DEBUG_DECODE()) {
  2951. /* XXX DECODE_PRINTF may be changed to something more
  2952. general, so that it is important to leave the strings
  2953. in the same format, even though the result is that the
  2954. above test is done twice. */
  2955. switch (rh) {
  2956. case 0:
  2957. DECODE_PRINTF("ROL\t");
  2958. break;
  2959. case 1:
  2960. DECODE_PRINTF("ROR\t");
  2961. break;
  2962. case 2:
  2963. DECODE_PRINTF("RCL\t");
  2964. break;
  2965. case 3:
  2966. DECODE_PRINTF("RCR\t");
  2967. break;
  2968. case 4:
  2969. DECODE_PRINTF("SHL\t");
  2970. break;
  2971. case 5:
  2972. DECODE_PRINTF("SHR\t");
  2973. break;
  2974. case 6:
  2975. DECODE_PRINTF("SAL\t");
  2976. break;
  2977. case 7:
  2978. DECODE_PRINTF("SAR\t");
  2979. break;
  2980. }
  2981. }
  2982. #endif
  2983. /* know operation, decode the mod byte to find the addressing
  2984. mode. */
  2985. if (mod < 3) {
  2986. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  2987. u32 destval;
  2988. DECODE_PRINTF("DWORD PTR ");
  2989. destoffset = decode_rmXX_address(mod, rl);
  2990. amt = fetch_byte_imm();
  2991. DECODE_PRINTF2(",%x\n", amt);
  2992. destval = fetch_data_long(destoffset);
  2993. TRACE_AND_STEP();
  2994. destval = (*opcD1_long_operation[rh]) (destval, amt);
  2995. store_data_long(destoffset, destval);
  2996. } else {
  2997. u16 destval;
  2998. DECODE_PRINTF("WORD PTR ");
  2999. destoffset = decode_rmXX_address(mod, rl);
  3000. amt = fetch_byte_imm();
  3001. DECODE_PRINTF2(",%x\n", amt);
  3002. destval = fetch_data_word(destoffset);
  3003. TRACE_AND_STEP();
  3004. destval = (*opcD1_word_operation[rh]) (destval, amt);
  3005. store_data_word(destoffset, destval);
  3006. }
  3007. } else { /* register to register */
  3008. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  3009. u32 *destreg;
  3010. destreg = DECODE_RM_LONG_REGISTER(rl);
  3011. amt = fetch_byte_imm();
  3012. DECODE_PRINTF2(",%x\n", amt);
  3013. TRACE_AND_STEP();
  3014. *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
  3015. } else {
  3016. u16 *destreg;
  3017. destreg = DECODE_RM_WORD_REGISTER(rl);
  3018. amt = fetch_byte_imm();
  3019. DECODE_PRINTF2(",%x\n", amt);
  3020. TRACE_AND_STEP();
  3021. *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
  3022. }
  3023. }
  3024. DECODE_CLEAR_SEGOVR();
  3025. END_OF_INSTR();
  3026. }
  3027. /****************************************************************************
  3028. REMARKS:
  3029. Handles opcode 0xc2
  3030. ****************************************************************************/
  3031. void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
  3032. {
  3033. u16 imm;
  3034. START_OF_INSTR();
  3035. DECODE_PRINTF("RET\t");
  3036. imm = fetch_word_imm();
  3037. DECODE_PRINTF2("%x\n", imm);
  3038. RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
  3039. TRACE_AND_STEP();
  3040. M.x86.R_IP = pop_word();
  3041. M.x86.R_SP += imm;
  3042. DECODE_CLEAR_SEGOVR();
  3043. END_OF_INSTR();
  3044. }
  3045. /****************************************************************************
  3046. REMARKS:
  3047. Handles opcode 0xc3
  3048. ****************************************************************************/
  3049. void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
  3050. {
  3051. START_OF_INSTR();
  3052. DECODE_PRINTF("RET\n");
  3053. RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
  3054. TRACE_AND_STEP();
  3055. M.x86.R_IP = pop_word();
  3056. DECODE_CLEAR_SEGOVR();
  3057. END_OF_INSTR();
  3058. }
  3059. /****************************************************************************
  3060. REMARKS:
  3061. Handles opcode 0xc4
  3062. ****************************************************************************/
  3063. void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
  3064. {
  3065. int mod, rh, rl;
  3066. u16 *dstreg;
  3067. uint srcoffset;
  3068. START_OF_INSTR();
  3069. DECODE_PRINTF("LES\t");
  3070. FETCH_DECODE_MODRM(mod, rh, rl);
  3071. if (mod < 3) {
  3072. dstreg = DECODE_RM_WORD_REGISTER(rh);
  3073. DECODE_PRINTF(",");
  3074. srcoffset = decode_rmXX_address(mod, rl);
  3075. DECODE_PRINTF("\n");
  3076. TRACE_AND_STEP();
  3077. *dstreg = fetch_data_word(srcoffset);
  3078. M.x86.R_ES = fetch_data_word(srcoffset + 2);
  3079. }
  3080. /* else UNDEFINED! register to register */
  3081. DECODE_CLEAR_SEGOVR();
  3082. END_OF_INSTR();
  3083. }
  3084. /****************************************************************************
  3085. REMARKS:
  3086. Handles opcode 0xc5
  3087. ****************************************************************************/
  3088. void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
  3089. {
  3090. int mod, rh, rl;
  3091. u16 *dstreg;
  3092. uint srcoffset;
  3093. START_OF_INSTR();
  3094. DECODE_PRINTF("LDS\t");
  3095. FETCH_DECODE_MODRM(mod, rh, rl);
  3096. if (mod < 3) {
  3097. dstreg = DECODE_RM_WORD_REGISTER(rh);
  3098. DECODE_PRINTF(",");
  3099. srcoffset = decode_rmXX_address(mod, rl);
  3100. DECODE_PRINTF("\n");
  3101. TRACE_AND_STEP();
  3102. *dstreg = fetch_data_word(srcoffset);
  3103. M.x86.R_DS = fetch_data_word(srcoffset + 2);
  3104. }
  3105. /* else UNDEFINED! */
  3106. DECODE_CLEAR_SEGOVR();
  3107. END_OF_INSTR();
  3108. }
  3109. /****************************************************************************
  3110. REMARKS:
  3111. Handles opcode 0xc6
  3112. ****************************************************************************/
  3113. void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
  3114. {
  3115. int mod, rl, rh;
  3116. u8 *destreg;
  3117. uint destoffset;
  3118. u8 imm;
  3119. START_OF_INSTR();
  3120. DECODE_PRINTF("MOV\t");
  3121. FETCH_DECODE_MODRM(mod, rh, rl);
  3122. if (rh != 0) {
  3123. DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
  3124. HALT_SYS();
  3125. }
  3126. if (mod < 3) {
  3127. DECODE_PRINTF("BYTE PTR ");
  3128. destoffset = decode_rmXX_address(mod, rl);
  3129. imm = fetch_byte_imm();
  3130. DECODE_PRINTF2(",%2x\n", imm);
  3131. TRACE_AND_STEP();
  3132. store_data_byte(destoffset, imm);
  3133. } else { /* register to register */
  3134. destreg = DECODE_RM_BYTE_REGISTER(rl);
  3135. imm = fetch_byte_imm();
  3136. DECODE_PRINTF2(",%2x\n", imm);
  3137. TRACE_AND_STEP();
  3138. *destreg = imm;
  3139. }
  3140. DECODE_CLEAR_SEGOVR();
  3141. END_OF_INSTR();
  3142. }
  3143. /****************************************************************************
  3144. REMARKS:
  3145. Handles opcode 0xc7
  3146. ****************************************************************************/
  3147. void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
  3148. {
  3149. int mod, rl, rh;
  3150. uint destoffset;
  3151. START_OF_INSTR();
  3152. DECODE_PRINTF("MOV\t");
  3153. FETCH_DECODE_MODRM(mod, rh, rl);
  3154. if (rh != 0) {
  3155. DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
  3156. HALT_SYS();
  3157. }
  3158. if (mod < 3) {
  3159. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  3160. u32 imm;
  3161. DECODE_PRINTF("DWORD PTR ");
  3162. destoffset = decode_rmXX_address(mod, rl);
  3163. imm = fetch_long_imm();
  3164. DECODE_PRINTF2(",%x\n", imm);
  3165. TRACE_AND_STEP();
  3166. store_data_long(destoffset, imm);
  3167. } else {
  3168. u16 imm;
  3169. DECODE_PRINTF("WORD PTR ");
  3170. destoffset = decode_rmXX_address(mod, rl);
  3171. imm = fetch_word_imm();
  3172. DECODE_PRINTF2(",%x\n", imm);
  3173. TRACE_AND_STEP();
  3174. store_data_word(destoffset, imm);
  3175. }
  3176. } else { /* register to register */
  3177. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  3178. u32 *destreg;
  3179. u32 imm;
  3180. destreg = DECODE_RM_LONG_REGISTER(rl);
  3181. imm = fetch_long_imm();
  3182. DECODE_PRINTF2(",%x\n", imm);
  3183. TRACE_AND_STEP();
  3184. *destreg = imm;
  3185. } else {
  3186. u16 *destreg;
  3187. u16 imm;
  3188. destreg = DECODE_RM_WORD_REGISTER(rl);
  3189. imm = fetch_word_imm();
  3190. DECODE_PRINTF2(",%x\n", imm);
  3191. TRACE_AND_STEP();
  3192. *destreg = imm;
  3193. }
  3194. }
  3195. DECODE_CLEAR_SEGOVR();
  3196. END_OF_INSTR();
  3197. }
  3198. /****************************************************************************
  3199. REMARKS:
  3200. Handles opcode 0xc8
  3201. ****************************************************************************/
  3202. void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
  3203. {
  3204. u16 local,frame_pointer;
  3205. u8 nesting;
  3206. int i;
  3207. START_OF_INSTR();
  3208. local = fetch_word_imm();
  3209. nesting = fetch_byte_imm();
  3210. DECODE_PRINTF2("ENTER %x\n", local);
  3211. DECODE_PRINTF2(",%x\n", nesting);
  3212. TRACE_AND_STEP();
  3213. push_word(M.x86.R_BP);
  3214. frame_pointer = M.x86.R_SP;
  3215. if (nesting > 0) {
  3216. for (i = 1; i < nesting; i++) {
  3217. M.x86.R_BP -= 2;
  3218. push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
  3219. }
  3220. push_word(frame_pointer);
  3221. }
  3222. M.x86.R_BP = frame_pointer;
  3223. M.x86.R_SP = (u16)(M.x86.R_SP - local);
  3224. DECODE_CLEAR_SEGOVR();
  3225. END_OF_INSTR();
  3226. }
  3227. /****************************************************************************
  3228. REMARKS:
  3229. Handles opcode 0xc9
  3230. ****************************************************************************/
  3231. void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
  3232. {
  3233. START_OF_INSTR();
  3234. DECODE_PRINTF("LEAVE\n");
  3235. TRACE_AND_STEP();
  3236. M.x86.R_SP = M.x86.R_BP;
  3237. M.x86.R_BP = pop_word();
  3238. DECODE_CLEAR_SEGOVR();
  3239. END_OF_INSTR();
  3240. }
  3241. /****************************************************************************
  3242. REMARKS:
  3243. Handles opcode 0xca
  3244. ****************************************************************************/
  3245. void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
  3246. {
  3247. u16 imm;
  3248. START_OF_INSTR();
  3249. DECODE_PRINTF("RETF\t");
  3250. imm = fetch_word_imm();
  3251. DECODE_PRINTF2("%x\n", imm);
  3252. RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
  3253. TRACE_AND_STEP();
  3254. M.x86.R_IP = pop_word();
  3255. M.x86.R_CS = pop_word();
  3256. M.x86.R_SP += imm;
  3257. DECODE_CLEAR_SEGOVR();
  3258. END_OF_INSTR();
  3259. }
  3260. /****************************************************************************
  3261. REMARKS:
  3262. Handles opcode 0xcb
  3263. ****************************************************************************/
  3264. void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
  3265. {
  3266. START_OF_INSTR();
  3267. DECODE_PRINTF("RETF\n");
  3268. RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
  3269. TRACE_AND_STEP();
  3270. M.x86.R_IP = pop_word();
  3271. M.x86.R_CS = pop_word();
  3272. DECODE_CLEAR_SEGOVR();
  3273. END_OF_INSTR();
  3274. }
  3275. /****************************************************************************
  3276. REMARKS:
  3277. Handles opcode 0xcc
  3278. ****************************************************************************/
  3279. void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
  3280. {
  3281. u16 tmp;
  3282. START_OF_INSTR();
  3283. DECODE_PRINTF("INT 3\n");
  3284. tmp = (u16) mem_access_word(3 * 4 + 2);
  3285. /* access the segment register */
  3286. TRACE_AND_STEP();
  3287. if (_X86EMU_intrTab[3]) {
  3288. (*_X86EMU_intrTab[3])(3);
  3289. } else {
  3290. push_word((u16)M.x86.R_FLG);
  3291. CLEAR_FLAG(F_IF);
  3292. CLEAR_FLAG(F_TF);
  3293. push_word(M.x86.R_CS);
  3294. M.x86.R_CS = mem_access_word(3 * 4 + 2);
  3295. push_word(M.x86.R_IP);
  3296. M.x86.R_IP = mem_access_word(3 * 4);
  3297. }
  3298. DECODE_CLEAR_SEGOVR();
  3299. END_OF_INSTR();
  3300. }
  3301. /****************************************************************************
  3302. REMARKS:
  3303. Handles opcode 0xcd
  3304. ****************************************************************************/
  3305. void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
  3306. {
  3307. u16 tmp;
  3308. u8 intnum;
  3309. START_OF_INSTR();
  3310. DECODE_PRINTF("INT\t");
  3311. intnum = fetch_byte_imm();
  3312. DECODE_PRINTF2("%x\n", intnum);
  3313. tmp = mem_access_word(intnum * 4 + 2);
  3314. TRACE_AND_STEP();
  3315. if (_X86EMU_intrTab[intnum]) {
  3316. (*_X86EMU_intrTab[intnum])(intnum);
  3317. } else {
  3318. push_word((u16)M.x86.R_FLG);
  3319. CLEAR_FLAG(F_IF);
  3320. CLEAR_FLAG(F_TF);
  3321. push_word(M.x86.R_CS);
  3322. M.x86.R_CS = mem_access_word(intnum * 4 + 2);
  3323. push_word(M.x86.R_IP);
  3324. M.x86.R_IP = mem_access_word(intnum * 4);
  3325. }
  3326. DECODE_CLEAR_SEGOVR();
  3327. END_OF_INSTR();
  3328. }
  3329. /****************************************************************************
  3330. REMARKS:
  3331. Handles opcode 0xce
  3332. ****************************************************************************/
  3333. void x86emuOp_into(u8 X86EMU_UNUSED(op1))
  3334. {
  3335. u16 tmp;
  3336. START_OF_INSTR();
  3337. DECODE_PRINTF("INTO\n");
  3338. TRACE_AND_STEP();
  3339. if (ACCESS_FLAG(F_OF)) {
  3340. tmp = mem_access_word(4 * 4 + 2);
  3341. if (_X86EMU_intrTab[4]) {
  3342. (*_X86EMU_intrTab[4])(4);
  3343. } else {
  3344. push_word((u16)M.x86.R_FLG);
  3345. CLEAR_FLAG(F_IF);
  3346. CLEAR_FLAG(F_TF);
  3347. push_word(M.x86.R_CS);
  3348. M.x86.R_CS = mem_access_word(4 * 4 + 2);
  3349. push_word(M.x86.R_IP);
  3350. M.x86.R_IP = mem_access_word(4 * 4);
  3351. }
  3352. }
  3353. DECODE_CLEAR_SEGOVR();
  3354. END_OF_INSTR();
  3355. }
  3356. /****************************************************************************
  3357. REMARKS:
  3358. Handles opcode 0xcf
  3359. ****************************************************************************/
  3360. void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
  3361. {
  3362. START_OF_INSTR();
  3363. DECODE_PRINTF("IRET\n");
  3364. TRACE_AND_STEP();
  3365. M.x86.R_IP = pop_word();
  3366. M.x86.R_CS = pop_word();
  3367. M.x86.R_FLG = pop_word();
  3368. DECODE_CLEAR_SEGOVR();
  3369. END_OF_INSTR();
  3370. }
  3371. /****************************************************************************
  3372. REMARKS:
  3373. Handles opcode 0xd0
  3374. ****************************************************************************/
  3375. void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
  3376. {
  3377. int mod, rl, rh;
  3378. u8 *destreg;
  3379. uint destoffset;
  3380. u8 destval;
  3381. /*
  3382. * Yet another weirdo special case instruction format. Part of
  3383. * the opcode held below in "RH". Doubly nested case would
  3384. * result, except that the decoded instruction
  3385. */
  3386. START_OF_INSTR();
  3387. FETCH_DECODE_MODRM(mod, rh, rl);
  3388. #ifdef DEBUG
  3389. if (DEBUG_DECODE()) {
  3390. /* XXX DECODE_PRINTF may be changed to something more
  3391. general, so that it is important to leave the strings
  3392. in the same format, even though the result is that the
  3393. above test is done twice. */
  3394. switch (rh) {
  3395. case 0:
  3396. DECODE_PRINTF("ROL\t");
  3397. break;
  3398. case 1:
  3399. DECODE_PRINTF("ROR\t");
  3400. break;
  3401. case 2:
  3402. DECODE_PRINTF("RCL\t");
  3403. break;
  3404. case 3:
  3405. DECODE_PRINTF("RCR\t");
  3406. break;
  3407. case 4:
  3408. DECODE_PRINTF("SHL\t");
  3409. break;
  3410. case 5:
  3411. DECODE_PRINTF("SHR\t");
  3412. break;
  3413. case 6:
  3414. DECODE_PRINTF("SAL\t");
  3415. break;
  3416. case 7:
  3417. DECODE_PRINTF("SAR\t");
  3418. break;
  3419. }
  3420. }
  3421. #endif
  3422. /* know operation, decode the mod byte to find the addressing
  3423. mode. */
  3424. if (mod < 3) {
  3425. DECODE_PRINTF("BYTE PTR ");
  3426. destoffset = decode_rmXX_address(mod, rl);
  3427. DECODE_PRINTF(",1\n");
  3428. destval = fetch_data_byte(destoffset);
  3429. TRACE_AND_STEP();
  3430. destval = (*opcD0_byte_operation[rh]) (destval, 1);
  3431. store_data_byte(destoffset, destval);
  3432. } else { /* register to register */
  3433. destreg = DECODE_RM_BYTE_REGISTER(rl);
  3434. DECODE_PRINTF(",1\n");
  3435. TRACE_AND_STEP();
  3436. destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
  3437. *destreg = destval;
  3438. }
  3439. DECODE_CLEAR_SEGOVR();
  3440. END_OF_INSTR();
  3441. }
  3442. /****************************************************************************
  3443. REMARKS:
  3444. Handles opcode 0xd1
  3445. ****************************************************************************/
  3446. void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
  3447. {
  3448. int mod, rl, rh;
  3449. uint destoffset;
  3450. /*
  3451. * Yet another weirdo special case instruction format. Part of
  3452. * the opcode held below in "RH". Doubly nested case would
  3453. * result, except that the decoded instruction
  3454. */
  3455. START_OF_INSTR();
  3456. FETCH_DECODE_MODRM(mod, rh, rl);
  3457. #ifdef DEBUG
  3458. if (DEBUG_DECODE()) {
  3459. /* XXX DECODE_PRINTF may be changed to something more
  3460. general, so that it is important to leave the strings
  3461. in the same format, even though the result is that the
  3462. above test is done twice. */
  3463. switch (rh) {
  3464. case 0:
  3465. DECODE_PRINTF("ROL\t");
  3466. break;
  3467. case 1:
  3468. DECODE_PRINTF("ROR\t");
  3469. break;
  3470. case 2:
  3471. DECODE_PRINTF("RCL\t");
  3472. break;
  3473. case 3:
  3474. DECODE_PRINTF("RCR\t");
  3475. break;
  3476. case 4:
  3477. DECODE_PRINTF("SHL\t");
  3478. break;
  3479. case 5:
  3480. DECODE_PRINTF("SHR\t");
  3481. break;
  3482. case 6:
  3483. DECODE_PRINTF("SAL\t");
  3484. break;
  3485. case 7:
  3486. DECODE_PRINTF("SAR\t");
  3487. break;
  3488. }
  3489. }
  3490. #endif
  3491. /* know operation, decode the mod byte to find the addressing
  3492. mode. */
  3493. if (mod < 3) {
  3494. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  3495. u32 destval;
  3496. DECODE_PRINTF("DWORD PTR ");
  3497. destoffset = decode_rmXX_address(mod, rl);
  3498. DECODE_PRINTF(",1\n");
  3499. destval = fetch_data_long(destoffset);
  3500. TRACE_AND_STEP();
  3501. destval = (*opcD1_long_operation[rh]) (destval, 1);
  3502. store_data_long(destoffset, destval);
  3503. } else {
  3504. u16 destval;
  3505. DECODE_PRINTF("WORD PTR ");
  3506. destoffset = decode_rmXX_address(mod, rl);
  3507. DECODE_PRINTF(",1\n");
  3508. destval = fetch_data_word(destoffset);
  3509. TRACE_AND_STEP();
  3510. destval = (*opcD1_word_operation[rh]) (destval, 1);
  3511. store_data_word(destoffset, destval);
  3512. }
  3513. } else { /* register to register */
  3514. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  3515. u32 destval;
  3516. u32 *destreg;
  3517. destreg = DECODE_RM_LONG_REGISTER(rl);
  3518. DECODE_PRINTF(",1\n");
  3519. TRACE_AND_STEP();
  3520. destval = (*opcD1_long_operation[rh]) (*destreg, 1);
  3521. *destreg = destval;
  3522. } else {
  3523. u16 destval;
  3524. u16 *destreg;
  3525. destreg = DECODE_RM_WORD_REGISTER(rl);
  3526. DECODE_PRINTF(",1\n");
  3527. TRACE_AND_STEP();
  3528. destval = (*opcD1_word_operation[rh]) (*destreg, 1);
  3529. *destreg = destval;
  3530. }
  3531. }
  3532. DECODE_CLEAR_SEGOVR();
  3533. END_OF_INSTR();
  3534. }
  3535. /****************************************************************************
  3536. REMARKS:
  3537. Handles opcode 0xd2
  3538. ****************************************************************************/
  3539. void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
  3540. {
  3541. int mod, rl, rh;
  3542. u8 *destreg;
  3543. uint destoffset;
  3544. u8 destval;
  3545. u8 amt;
  3546. /*
  3547. * Yet another weirdo special case instruction format. Part of
  3548. * the opcode held below in "RH". Doubly nested case would
  3549. * result, except that the decoded instruction
  3550. */
  3551. START_OF_INSTR();
  3552. FETCH_DECODE_MODRM(mod, rh, rl);
  3553. #ifdef DEBUG
  3554. if (DEBUG_DECODE()) {
  3555. /* XXX DECODE_PRINTF may be changed to something more
  3556. general, so that it is important to leave the strings
  3557. in the same format, even though the result is that the
  3558. above test is done twice. */
  3559. switch (rh) {
  3560. case 0:
  3561. DECODE_PRINTF("ROL\t");
  3562. break;
  3563. case 1:
  3564. DECODE_PRINTF("ROR\t");
  3565. break;
  3566. case 2:
  3567. DECODE_PRINTF("RCL\t");
  3568. break;
  3569. case 3:
  3570. DECODE_PRINTF("RCR\t");
  3571. break;
  3572. case 4:
  3573. DECODE_PRINTF("SHL\t");
  3574. break;
  3575. case 5:
  3576. DECODE_PRINTF("SHR\t");
  3577. break;
  3578. case 6:
  3579. DECODE_PRINTF("SAL\t");
  3580. break;
  3581. case 7:
  3582. DECODE_PRINTF("SAR\t");
  3583. break;
  3584. }
  3585. }
  3586. #endif
  3587. /* know operation, decode the mod byte to find the addressing
  3588. mode. */
  3589. amt = M.x86.R_CL;
  3590. if (mod < 3) {
  3591. DECODE_PRINTF("BYTE PTR ");
  3592. destoffset = decode_rmXX_address(mod, rl);
  3593. DECODE_PRINTF(",CL\n");
  3594. destval = fetch_data_byte(destoffset);
  3595. TRACE_AND_STEP();
  3596. destval = (*opcD0_byte_operation[rh]) (destval, amt);
  3597. store_data_byte(destoffset, destval);
  3598. } else { /* register to register */
  3599. destreg = DECODE_RM_BYTE_REGISTER(rl);
  3600. DECODE_PRINTF(",CL\n");
  3601. TRACE_AND_STEP();
  3602. destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
  3603. *destreg = destval;
  3604. }
  3605. DECODE_CLEAR_SEGOVR();
  3606. END_OF_INSTR();
  3607. }
  3608. /****************************************************************************
  3609. REMARKS:
  3610. Handles opcode 0xd3
  3611. ****************************************************************************/
  3612. void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
  3613. {
  3614. int mod, rl, rh;
  3615. uint destoffset;
  3616. u8 amt;
  3617. /*
  3618. * Yet another weirdo special case instruction format. Part of
  3619. * the opcode held below in "RH". Doubly nested case would
  3620. * result, except that the decoded instruction
  3621. */
  3622. START_OF_INSTR();
  3623. FETCH_DECODE_MODRM(mod, rh, rl);
  3624. #ifdef DEBUG
  3625. if (DEBUG_DECODE()) {
  3626. /* XXX DECODE_PRINTF may be changed to something more
  3627. general, so that it is important to leave the strings
  3628. in the same format, even though the result is that the
  3629. above test is done twice. */
  3630. switch (rh) {
  3631. case 0:
  3632. DECODE_PRINTF("ROL\t");
  3633. break;
  3634. case 1:
  3635. DECODE_PRINTF("ROR\t");
  3636. break;
  3637. case 2:
  3638. DECODE_PRINTF("RCL\t");
  3639. break;
  3640. case 3:
  3641. DECODE_PRINTF("RCR\t");
  3642. break;
  3643. case 4:
  3644. DECODE_PRINTF("SHL\t");
  3645. break;
  3646. case 5:
  3647. DECODE_PRINTF("SHR\t");
  3648. break;
  3649. case 6:
  3650. DECODE_PRINTF("SAL\t");
  3651. break;
  3652. case 7:
  3653. DECODE_PRINTF("SAR\t");
  3654. break;
  3655. }
  3656. }
  3657. #endif
  3658. /* know operation, decode the mod byte to find the addressing
  3659. mode. */
  3660. amt = M.x86.R_CL;
  3661. if (mod < 3) {
  3662. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  3663. u32 destval;
  3664. DECODE_PRINTF("DWORD PTR ");
  3665. destoffset = decode_rmXX_address(mod, rl);
  3666. DECODE_PRINTF(",CL\n");
  3667. destval = fetch_data_long(destoffset);
  3668. TRACE_AND_STEP();
  3669. destval = (*opcD1_long_operation[rh]) (destval, amt);
  3670. store_data_long(destoffset, destval);
  3671. } else {
  3672. u16 destval;
  3673. DECODE_PRINTF("WORD PTR ");
  3674. destoffset = decode_rmXX_address(mod, rl);
  3675. DECODE_PRINTF(",CL\n");
  3676. destval = fetch_data_word(destoffset);
  3677. TRACE_AND_STEP();
  3678. destval = (*opcD1_word_operation[rh]) (destval, amt);
  3679. store_data_word(destoffset, destval);
  3680. }
  3681. } else { /* register to register */
  3682. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  3683. u32 *destreg;
  3684. destreg = DECODE_RM_LONG_REGISTER(rl);
  3685. DECODE_PRINTF(",CL\n");
  3686. TRACE_AND_STEP();
  3687. *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
  3688. } else {
  3689. u16 *destreg;
  3690. destreg = DECODE_RM_WORD_REGISTER(rl);
  3691. DECODE_PRINTF(",CL\n");
  3692. TRACE_AND_STEP();
  3693. *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
  3694. }
  3695. }
  3696. DECODE_CLEAR_SEGOVR();
  3697. END_OF_INSTR();
  3698. }
  3699. /****************************************************************************
  3700. REMARKS:
  3701. Handles opcode 0xd4
  3702. ****************************************************************************/
  3703. void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
  3704. {
  3705. u8 a;
  3706. START_OF_INSTR();
  3707. DECODE_PRINTF("AAM\n");
  3708. a = fetch_byte_imm(); /* this is a stupid encoding. */
  3709. if (a != 10) {
  3710. DECODE_PRINTF("ERROR DECODING AAM\n");
  3711. TRACE_REGS();
  3712. HALT_SYS();
  3713. }
  3714. TRACE_AND_STEP();
  3715. /* note the type change here --- returning AL and AH in AX. */
  3716. M.x86.R_AX = aam_word(M.x86.R_AL);
  3717. DECODE_CLEAR_SEGOVR();
  3718. END_OF_INSTR();
  3719. }
  3720. /****************************************************************************
  3721. REMARKS:
  3722. Handles opcode 0xd5
  3723. ****************************************************************************/
  3724. void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
  3725. {
  3726. u8 a;
  3727. START_OF_INSTR();
  3728. DECODE_PRINTF("AAD\n");
  3729. a = fetch_byte_imm();
  3730. TRACE_AND_STEP();
  3731. M.x86.R_AX = aad_word(M.x86.R_AX);
  3732. DECODE_CLEAR_SEGOVR();
  3733. END_OF_INSTR();
  3734. }
  3735. /* opcode 0xd6 ILLEGAL OPCODE */
  3736. /****************************************************************************
  3737. REMARKS:
  3738. Handles opcode 0xd7
  3739. ****************************************************************************/
  3740. void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
  3741. {
  3742. u16 addr;
  3743. START_OF_INSTR();
  3744. DECODE_PRINTF("XLAT\n");
  3745. TRACE_AND_STEP();
  3746. addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
  3747. M.x86.R_AL = fetch_data_byte(addr);
  3748. DECODE_CLEAR_SEGOVR();
  3749. END_OF_INSTR();
  3750. }
  3751. /* instuctions D8 .. DF are in i87_ops.c */
  3752. /****************************************************************************
  3753. REMARKS:
  3754. Handles opcode 0xe0
  3755. ****************************************************************************/
  3756. void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
  3757. {
  3758. s16 ip;
  3759. START_OF_INSTR();
  3760. DECODE_PRINTF("LOOPNE\t");
  3761. ip = (s8) fetch_byte_imm();
  3762. ip += (s16) M.x86.R_IP;
  3763. DECODE_PRINTF2("%04x\n", ip);
  3764. TRACE_AND_STEP();
  3765. M.x86.R_CX -= 1;
  3766. if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
  3767. M.x86.R_IP = ip;
  3768. DECODE_CLEAR_SEGOVR();
  3769. END_OF_INSTR();
  3770. }
  3771. /****************************************************************************
  3772. REMARKS:
  3773. Handles opcode 0xe1
  3774. ****************************************************************************/
  3775. void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
  3776. {
  3777. s16 ip;
  3778. START_OF_INSTR();
  3779. DECODE_PRINTF("LOOPE\t");
  3780. ip = (s8) fetch_byte_imm();
  3781. ip += (s16) M.x86.R_IP;
  3782. DECODE_PRINTF2("%04x\n", ip);
  3783. TRACE_AND_STEP();
  3784. M.x86.R_CX -= 1;
  3785. if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
  3786. M.x86.R_IP = ip;
  3787. DECODE_CLEAR_SEGOVR();
  3788. END_OF_INSTR();
  3789. }
  3790. /****************************************************************************
  3791. REMARKS:
  3792. Handles opcode 0xe2
  3793. ****************************************************************************/
  3794. void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
  3795. {
  3796. s16 ip;
  3797. START_OF_INSTR();
  3798. DECODE_PRINTF("LOOP\t");
  3799. ip = (s8) fetch_byte_imm();
  3800. ip += (s16) M.x86.R_IP;
  3801. DECODE_PRINTF2("%04x\n", ip);
  3802. TRACE_AND_STEP();
  3803. M.x86.R_CX -= 1;
  3804. if (M.x86.R_CX != 0)
  3805. M.x86.R_IP = ip;
  3806. DECODE_CLEAR_SEGOVR();
  3807. END_OF_INSTR();
  3808. }
  3809. /****************************************************************************
  3810. REMARKS:
  3811. Handles opcode 0xe3
  3812. ****************************************************************************/
  3813. void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
  3814. {
  3815. u16 target;
  3816. s8 offset;
  3817. /* jump to byte offset if overflow flag is set */
  3818. START_OF_INSTR();
  3819. DECODE_PRINTF("JCXZ\t");
  3820. offset = (s8)fetch_byte_imm();
  3821. target = (u16)(M.x86.R_IP + offset);
  3822. DECODE_PRINTF2("%x\n", target);
  3823. TRACE_AND_STEP();
  3824. if (M.x86.R_CX == 0)
  3825. M.x86.R_IP = target;
  3826. DECODE_CLEAR_SEGOVR();
  3827. END_OF_INSTR();
  3828. }
  3829. /****************************************************************************
  3830. REMARKS:
  3831. Handles opcode 0xe4
  3832. ****************************************************************************/
  3833. void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
  3834. {
  3835. u8 port;
  3836. START_OF_INSTR();
  3837. DECODE_PRINTF("IN\t");
  3838. port = (u8) fetch_byte_imm();
  3839. DECODE_PRINTF2("%x,AL\n", port);
  3840. TRACE_AND_STEP();
  3841. M.x86.R_AL = (*sys_inb)(port);
  3842. DECODE_CLEAR_SEGOVR();
  3843. END_OF_INSTR();
  3844. }
  3845. /****************************************************************************
  3846. REMARKS:
  3847. Handles opcode 0xe5
  3848. ****************************************************************************/
  3849. void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
  3850. {
  3851. u8 port;
  3852. START_OF_INSTR();
  3853. DECODE_PRINTF("IN\t");
  3854. port = (u8) fetch_byte_imm();
  3855. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  3856. DECODE_PRINTF2("EAX,%x\n", port);
  3857. } else {
  3858. DECODE_PRINTF2("AX,%x\n", port);
  3859. }
  3860. TRACE_AND_STEP();
  3861. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  3862. M.x86.R_EAX = (*sys_inl)(port);
  3863. } else {
  3864. M.x86.R_AX = (*sys_inw)(port);
  3865. }
  3866. DECODE_CLEAR_SEGOVR();
  3867. END_OF_INSTR();
  3868. }
  3869. /****************************************************************************
  3870. REMARKS:
  3871. Handles opcode 0xe6
  3872. ****************************************************************************/
  3873. void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
  3874. {
  3875. u8 port;
  3876. START_OF_INSTR();
  3877. DECODE_PRINTF("OUT\t");
  3878. port = (u8) fetch_byte_imm();
  3879. DECODE_PRINTF2("%x,AL\n", port);
  3880. TRACE_AND_STEP();
  3881. (*sys_outb)(port, M.x86.R_AL);
  3882. DECODE_CLEAR_SEGOVR();
  3883. END_OF_INSTR();
  3884. }
  3885. /****************************************************************************
  3886. REMARKS:
  3887. Handles opcode 0xe7
  3888. ****************************************************************************/
  3889. void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
  3890. {
  3891. u8 port;
  3892. START_OF_INSTR();
  3893. DECODE_PRINTF("OUT\t");
  3894. port = (u8) fetch_byte_imm();
  3895. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  3896. DECODE_PRINTF2("%x,EAX\n", port);
  3897. } else {
  3898. DECODE_PRINTF2("%x,AX\n", port);
  3899. }
  3900. TRACE_AND_STEP();
  3901. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  3902. (*sys_outl)(port, M.x86.R_EAX);
  3903. } else {
  3904. (*sys_outw)(port, M.x86.R_AX);
  3905. }
  3906. DECODE_CLEAR_SEGOVR();
  3907. END_OF_INSTR();
  3908. }
  3909. /****************************************************************************
  3910. REMARKS:
  3911. Handles opcode 0xe8
  3912. ****************************************************************************/
  3913. void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
  3914. {
  3915. s16 ip;
  3916. START_OF_INSTR();
  3917. DECODE_PRINTF("CALL\t");
  3918. ip = (s16) fetch_word_imm();
  3919. ip += (s16) M.x86.R_IP; /* CHECK SIGN */
  3920. DECODE_PRINTF2("%04x\n", ip);
  3921. CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
  3922. TRACE_AND_STEP();
  3923. push_word(M.x86.R_IP);
  3924. M.x86.R_IP = ip;
  3925. DECODE_CLEAR_SEGOVR();
  3926. END_OF_INSTR();
  3927. }
  3928. /****************************************************************************
  3929. REMARKS:
  3930. Handles opcode 0xe9
  3931. ****************************************************************************/
  3932. void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
  3933. {
  3934. int ip;
  3935. START_OF_INSTR();
  3936. DECODE_PRINTF("JMP\t");
  3937. ip = (s16)fetch_word_imm();
  3938. ip += (s16)M.x86.R_IP;
  3939. DECODE_PRINTF2("%04x\n", ip);
  3940. TRACE_AND_STEP();
  3941. M.x86.R_IP = (u16)ip;
  3942. DECODE_CLEAR_SEGOVR();
  3943. END_OF_INSTR();
  3944. }
  3945. /****************************************************************************
  3946. REMARKS:
  3947. Handles opcode 0xea
  3948. ****************************************************************************/
  3949. void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
  3950. {
  3951. u16 cs, ip;
  3952. START_OF_INSTR();
  3953. DECODE_PRINTF("JMP\tFAR ");
  3954. ip = fetch_word_imm();
  3955. cs = fetch_word_imm();
  3956. DECODE_PRINTF2("%04x:", cs);
  3957. DECODE_PRINTF2("%04x\n", ip);
  3958. TRACE_AND_STEP();
  3959. M.x86.R_IP = ip;
  3960. M.x86.R_CS = cs;
  3961. DECODE_CLEAR_SEGOVR();
  3962. END_OF_INSTR();
  3963. }
  3964. /****************************************************************************
  3965. REMARKS:
  3966. Handles opcode 0xeb
  3967. ****************************************************************************/
  3968. void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
  3969. {
  3970. u16 target;
  3971. s8 offset;
  3972. START_OF_INSTR();
  3973. DECODE_PRINTF("JMP\t");
  3974. offset = (s8)fetch_byte_imm();
  3975. target = (u16)(M.x86.R_IP + offset);
  3976. DECODE_PRINTF2("%x\n", target);
  3977. TRACE_AND_STEP();
  3978. M.x86.R_IP = target;
  3979. DECODE_CLEAR_SEGOVR();
  3980. END_OF_INSTR();
  3981. }
  3982. /****************************************************************************
  3983. REMARKS:
  3984. Handles opcode 0xec
  3985. ****************************************************************************/
  3986. void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
  3987. {
  3988. START_OF_INSTR();
  3989. DECODE_PRINTF("IN\tAL,DX\n");
  3990. TRACE_AND_STEP();
  3991. M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
  3992. DECODE_CLEAR_SEGOVR();
  3993. END_OF_INSTR();
  3994. }
  3995. /****************************************************************************
  3996. REMARKS:
  3997. Handles opcode 0xed
  3998. ****************************************************************************/
  3999. void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
  4000. {
  4001. START_OF_INSTR();
  4002. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  4003. DECODE_PRINTF("IN\tEAX,DX\n");
  4004. } else {
  4005. DECODE_PRINTF("IN\tAX,DX\n");
  4006. }
  4007. TRACE_AND_STEP();
  4008. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  4009. M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
  4010. } else {
  4011. M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
  4012. }
  4013. DECODE_CLEAR_SEGOVR();
  4014. END_OF_INSTR();
  4015. }
  4016. /****************************************************************************
  4017. REMARKS:
  4018. Handles opcode 0xee
  4019. ****************************************************************************/
  4020. void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
  4021. {
  4022. START_OF_INSTR();
  4023. DECODE_PRINTF("OUT\tDX,AL\n");
  4024. TRACE_AND_STEP();
  4025. (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
  4026. DECODE_CLEAR_SEGOVR();
  4027. END_OF_INSTR();
  4028. }
  4029. /****************************************************************************
  4030. REMARKS:
  4031. Handles opcode 0xef
  4032. ****************************************************************************/
  4033. void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
  4034. {
  4035. START_OF_INSTR();
  4036. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  4037. DECODE_PRINTF("OUT\tDX,EAX\n");
  4038. } else {
  4039. DECODE_PRINTF("OUT\tDX,AX\n");
  4040. }
  4041. TRACE_AND_STEP();
  4042. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  4043. (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
  4044. } else {
  4045. (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
  4046. }
  4047. DECODE_CLEAR_SEGOVR();
  4048. END_OF_INSTR();
  4049. }
  4050. /****************************************************************************
  4051. REMARKS:
  4052. Handles opcode 0xf0
  4053. ****************************************************************************/
  4054. void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
  4055. {
  4056. START_OF_INSTR();
  4057. DECODE_PRINTF("LOCK:\n");
  4058. TRACE_AND_STEP();
  4059. DECODE_CLEAR_SEGOVR();
  4060. END_OF_INSTR();
  4061. }
  4062. /*opcode 0xf1 ILLEGAL OPERATION */
  4063. /****************************************************************************
  4064. REMARKS:
  4065. Handles opcode 0xf2
  4066. ****************************************************************************/
  4067. void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
  4068. {
  4069. START_OF_INSTR();
  4070. DECODE_PRINTF("REPNE\n");
  4071. TRACE_AND_STEP();
  4072. M.x86.mode |= SYSMODE_PREFIX_REPNE;
  4073. DECODE_CLEAR_SEGOVR();
  4074. END_OF_INSTR();
  4075. }
  4076. /****************************************************************************
  4077. REMARKS:
  4078. Handles opcode 0xf3
  4079. ****************************************************************************/
  4080. void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
  4081. {
  4082. START_OF_INSTR();
  4083. DECODE_PRINTF("REPE\n");
  4084. TRACE_AND_STEP();
  4085. M.x86.mode |= SYSMODE_PREFIX_REPE;
  4086. DECODE_CLEAR_SEGOVR();
  4087. END_OF_INSTR();
  4088. }
  4089. /****************************************************************************
  4090. REMARKS:
  4091. Handles opcode 0xf4
  4092. ****************************************************************************/
  4093. void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
  4094. {
  4095. START_OF_INSTR();
  4096. DECODE_PRINTF("HALT\n");
  4097. TRACE_AND_STEP();
  4098. HALT_SYS();
  4099. DECODE_CLEAR_SEGOVR();
  4100. END_OF_INSTR();
  4101. }
  4102. /****************************************************************************
  4103. REMARKS:
  4104. Handles opcode 0xf5
  4105. ****************************************************************************/
  4106. void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
  4107. {
  4108. /* complement the carry flag. */
  4109. START_OF_INSTR();
  4110. DECODE_PRINTF("CMC\n");
  4111. TRACE_AND_STEP();
  4112. TOGGLE_FLAG(F_CF);
  4113. DECODE_CLEAR_SEGOVR();
  4114. END_OF_INSTR();
  4115. }
  4116. /****************************************************************************
  4117. REMARKS:
  4118. Handles opcode 0xf6
  4119. ****************************************************************************/
  4120. void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
  4121. {
  4122. int mod, rl, rh;
  4123. u8 *destreg;
  4124. uint destoffset;
  4125. u8 destval, srcval;
  4126. /* long, drawn out code follows. Double switch for a total
  4127. of 32 cases. */
  4128. START_OF_INSTR();
  4129. FETCH_DECODE_MODRM(mod, rh, rl);
  4130. DECODE_PRINTF(opF6_names[rh]);
  4131. if (mod < 3) {
  4132. DECODE_PRINTF("BYTE PTR ");
  4133. destoffset = decode_rmXX_address(mod, rl);
  4134. destval = fetch_data_byte(destoffset);
  4135. switch (rh) {
  4136. case 0: /* test byte imm */
  4137. DECODE_PRINTF(",");
  4138. srcval = fetch_byte_imm();
  4139. DECODE_PRINTF2("%02x\n", srcval);
  4140. TRACE_AND_STEP();
  4141. test_byte(destval, srcval);
  4142. break;
  4143. case 1:
  4144. DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
  4145. HALT_SYS();
  4146. break;
  4147. case 2:
  4148. DECODE_PRINTF("\n");
  4149. TRACE_AND_STEP();
  4150. destval = not_byte(destval);
  4151. store_data_byte(destoffset, destval);
  4152. break;
  4153. case 3:
  4154. DECODE_PRINTF("\n");
  4155. TRACE_AND_STEP();
  4156. destval = neg_byte(destval);
  4157. store_data_byte(destoffset, destval);
  4158. break;
  4159. case 4:
  4160. DECODE_PRINTF("\n");
  4161. TRACE_AND_STEP();
  4162. mul_byte(destval);
  4163. break;
  4164. case 5:
  4165. DECODE_PRINTF("\n");
  4166. TRACE_AND_STEP();
  4167. imul_byte(destval);
  4168. break;
  4169. case 6:
  4170. DECODE_PRINTF("\n");
  4171. TRACE_AND_STEP();
  4172. div_byte(destval);
  4173. break;
  4174. default:
  4175. DECODE_PRINTF("\n");
  4176. TRACE_AND_STEP();
  4177. idiv_byte(destval);
  4178. break;
  4179. }
  4180. } else { /* mod=11 */
  4181. destreg = DECODE_RM_BYTE_REGISTER(rl);
  4182. switch (rh) {
  4183. case 0: /* test byte imm */
  4184. DECODE_PRINTF(",");
  4185. srcval = fetch_byte_imm();
  4186. DECODE_PRINTF2("%02x\n", srcval);
  4187. TRACE_AND_STEP();
  4188. test_byte(*destreg, srcval);
  4189. break;
  4190. case 1:
  4191. DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
  4192. HALT_SYS();
  4193. break;
  4194. case 2:
  4195. DECODE_PRINTF("\n");
  4196. TRACE_AND_STEP();
  4197. *destreg = not_byte(*destreg);
  4198. break;
  4199. case 3:
  4200. DECODE_PRINTF("\n");
  4201. TRACE_AND_STEP();
  4202. *destreg = neg_byte(*destreg);
  4203. break;
  4204. case 4:
  4205. DECODE_PRINTF("\n");
  4206. TRACE_AND_STEP();
  4207. mul_byte(*destreg); /*!!! */
  4208. break;
  4209. case 5:
  4210. DECODE_PRINTF("\n");
  4211. TRACE_AND_STEP();
  4212. imul_byte(*destreg);
  4213. break;
  4214. case 6:
  4215. DECODE_PRINTF("\n");
  4216. TRACE_AND_STEP();
  4217. div_byte(*destreg);
  4218. break;
  4219. default:
  4220. DECODE_PRINTF("\n");
  4221. TRACE_AND_STEP();
  4222. idiv_byte(*destreg);
  4223. break;
  4224. }
  4225. }
  4226. DECODE_CLEAR_SEGOVR();
  4227. END_OF_INSTR();
  4228. }
  4229. /****************************************************************************
  4230. REMARKS:
  4231. Handles opcode 0xf7
  4232. ****************************************************************************/
  4233. void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
  4234. {
  4235. int mod, rl, rh;
  4236. uint destoffset;
  4237. START_OF_INSTR();
  4238. FETCH_DECODE_MODRM(mod, rh, rl);
  4239. DECODE_PRINTF(opF6_names[rh]);
  4240. if (mod < 3) {
  4241. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  4242. u32 destval, srcval;
  4243. DECODE_PRINTF("DWORD PTR ");
  4244. destoffset = decode_rmXX_address(mod, rl);
  4245. destval = fetch_data_long(destoffset);
  4246. switch (rh) {
  4247. case 0:
  4248. DECODE_PRINTF(",");
  4249. srcval = fetch_long_imm();
  4250. DECODE_PRINTF2("%x\n", srcval);
  4251. TRACE_AND_STEP();
  4252. test_long(destval, srcval);
  4253. break;
  4254. case 1:
  4255. DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
  4256. HALT_SYS();
  4257. break;
  4258. case 2:
  4259. DECODE_PRINTF("\n");
  4260. TRACE_AND_STEP();
  4261. destval = not_long(destval);
  4262. store_data_long(destoffset, destval);
  4263. break;
  4264. case 3:
  4265. DECODE_PRINTF("\n");
  4266. TRACE_AND_STEP();
  4267. destval = neg_long(destval);
  4268. store_data_long(destoffset, destval);
  4269. break;
  4270. case 4:
  4271. DECODE_PRINTF("\n");
  4272. TRACE_AND_STEP();
  4273. mul_long(destval);
  4274. break;
  4275. case 5:
  4276. DECODE_PRINTF("\n");
  4277. TRACE_AND_STEP();
  4278. imul_long(destval);
  4279. break;
  4280. case 6:
  4281. DECODE_PRINTF("\n");
  4282. TRACE_AND_STEP();
  4283. div_long(destval);
  4284. break;
  4285. case 7:
  4286. DECODE_PRINTF("\n");
  4287. TRACE_AND_STEP();
  4288. idiv_long(destval);
  4289. break;
  4290. }
  4291. } else {
  4292. u16 destval, srcval;
  4293. DECODE_PRINTF("WORD PTR ");
  4294. destoffset = decode_rmXX_address(mod, rl);
  4295. destval = fetch_data_word(destoffset);
  4296. switch (rh) {
  4297. case 0: /* test word imm */
  4298. DECODE_PRINTF(",");
  4299. srcval = fetch_word_imm();
  4300. DECODE_PRINTF2("%x\n", srcval);
  4301. TRACE_AND_STEP();
  4302. test_word(destval, srcval);
  4303. break;
  4304. case 1:
  4305. DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
  4306. HALT_SYS();
  4307. break;
  4308. case 2:
  4309. DECODE_PRINTF("\n");
  4310. TRACE_AND_STEP();
  4311. destval = not_word(destval);
  4312. store_data_word(destoffset, destval);
  4313. break;
  4314. case 3:
  4315. DECODE_PRINTF("\n");
  4316. TRACE_AND_STEP();
  4317. destval = neg_word(destval);
  4318. store_data_word(destoffset, destval);
  4319. break;
  4320. case 4:
  4321. DECODE_PRINTF("\n");
  4322. TRACE_AND_STEP();
  4323. mul_word(destval);
  4324. break;
  4325. case 5:
  4326. DECODE_PRINTF("\n");
  4327. TRACE_AND_STEP();
  4328. imul_word(destval);
  4329. break;
  4330. case 6:
  4331. DECODE_PRINTF("\n");
  4332. TRACE_AND_STEP();
  4333. div_word(destval);
  4334. break;
  4335. case 7:
  4336. DECODE_PRINTF("\n");
  4337. TRACE_AND_STEP();
  4338. idiv_word(destval);
  4339. break;
  4340. }
  4341. }
  4342. } else { /* mod=11 */
  4343. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  4344. u32 *destreg;
  4345. u32 srcval;
  4346. destreg = DECODE_RM_LONG_REGISTER(rl);
  4347. switch (rh) {
  4348. case 0: /* test word imm */
  4349. DECODE_PRINTF(",");
  4350. srcval = fetch_long_imm();
  4351. DECODE_PRINTF2("%x\n", srcval);
  4352. TRACE_AND_STEP();
  4353. test_long(*destreg, srcval);
  4354. break;
  4355. case 1:
  4356. DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
  4357. HALT_SYS();
  4358. break;
  4359. case 2:
  4360. DECODE_PRINTF("\n");
  4361. TRACE_AND_STEP();
  4362. *destreg = not_long(*destreg);
  4363. break;
  4364. case 3:
  4365. DECODE_PRINTF("\n");
  4366. TRACE_AND_STEP();
  4367. *destreg = neg_long(*destreg);
  4368. break;
  4369. case 4:
  4370. DECODE_PRINTF("\n");
  4371. TRACE_AND_STEP();
  4372. mul_long(*destreg); /*!!! */
  4373. break;
  4374. case 5:
  4375. DECODE_PRINTF("\n");
  4376. TRACE_AND_STEP();
  4377. imul_long(*destreg);
  4378. break;
  4379. case 6:
  4380. DECODE_PRINTF("\n");
  4381. TRACE_AND_STEP();
  4382. div_long(*destreg);
  4383. break;
  4384. case 7:
  4385. DECODE_PRINTF("\n");
  4386. TRACE_AND_STEP();
  4387. idiv_long(*destreg);
  4388. break;
  4389. }
  4390. } else {
  4391. u16 *destreg;
  4392. u16 srcval;
  4393. destreg = DECODE_RM_WORD_REGISTER(rl);
  4394. switch (rh) {
  4395. case 0: /* test word imm */
  4396. DECODE_PRINTF(",");
  4397. srcval = fetch_word_imm();
  4398. DECODE_PRINTF2("%x\n", srcval);
  4399. TRACE_AND_STEP();
  4400. test_word(*destreg, srcval);
  4401. break;
  4402. case 1:
  4403. DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
  4404. HALT_SYS();
  4405. break;
  4406. case 2:
  4407. DECODE_PRINTF("\n");
  4408. TRACE_AND_STEP();
  4409. *destreg = not_word(*destreg);
  4410. break;
  4411. case 3:
  4412. DECODE_PRINTF("\n");
  4413. TRACE_AND_STEP();
  4414. *destreg = neg_word(*destreg);
  4415. break;
  4416. case 4:
  4417. DECODE_PRINTF("\n");
  4418. TRACE_AND_STEP();
  4419. mul_word(*destreg); /*!!! */
  4420. break;
  4421. case 5:
  4422. DECODE_PRINTF("\n");
  4423. TRACE_AND_STEP();
  4424. imul_word(*destreg);
  4425. break;
  4426. case 6:
  4427. DECODE_PRINTF("\n");
  4428. TRACE_AND_STEP();
  4429. div_word(*destreg);
  4430. break;
  4431. case 7:
  4432. DECODE_PRINTF("\n");
  4433. TRACE_AND_STEP();
  4434. idiv_word(*destreg);
  4435. break;
  4436. }
  4437. }
  4438. }
  4439. DECODE_CLEAR_SEGOVR();
  4440. END_OF_INSTR();
  4441. }
  4442. /****************************************************************************
  4443. REMARKS:
  4444. Handles opcode 0xf8
  4445. ****************************************************************************/
  4446. void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
  4447. {
  4448. /* clear the carry flag. */
  4449. START_OF_INSTR();
  4450. DECODE_PRINTF("CLC\n");
  4451. TRACE_AND_STEP();
  4452. CLEAR_FLAG(F_CF);
  4453. DECODE_CLEAR_SEGOVR();
  4454. END_OF_INSTR();
  4455. }
  4456. /****************************************************************************
  4457. REMARKS:
  4458. Handles opcode 0xf9
  4459. ****************************************************************************/
  4460. void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
  4461. {
  4462. /* set the carry flag. */
  4463. START_OF_INSTR();
  4464. DECODE_PRINTF("STC\n");
  4465. TRACE_AND_STEP();
  4466. SET_FLAG(F_CF);
  4467. DECODE_CLEAR_SEGOVR();
  4468. END_OF_INSTR();
  4469. }
  4470. /****************************************************************************
  4471. REMARKS:
  4472. Handles opcode 0xfa
  4473. ****************************************************************************/
  4474. void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
  4475. {
  4476. /* clear interrupts. */
  4477. START_OF_INSTR();
  4478. DECODE_PRINTF("CLI\n");
  4479. TRACE_AND_STEP();
  4480. CLEAR_FLAG(F_IF);
  4481. DECODE_CLEAR_SEGOVR();
  4482. END_OF_INSTR();
  4483. }
  4484. /****************************************************************************
  4485. REMARKS:
  4486. Handles opcode 0xfb
  4487. ****************************************************************************/
  4488. void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
  4489. {
  4490. /* enable interrupts. */
  4491. START_OF_INSTR();
  4492. DECODE_PRINTF("STI\n");
  4493. TRACE_AND_STEP();
  4494. SET_FLAG(F_IF);
  4495. DECODE_CLEAR_SEGOVR();
  4496. END_OF_INSTR();
  4497. }
  4498. /****************************************************************************
  4499. REMARKS:
  4500. Handles opcode 0xfc
  4501. ****************************************************************************/
  4502. void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
  4503. {
  4504. /* clear interrupts. */
  4505. START_OF_INSTR();
  4506. DECODE_PRINTF("CLD\n");
  4507. TRACE_AND_STEP();
  4508. CLEAR_FLAG(F_DF);
  4509. DECODE_CLEAR_SEGOVR();
  4510. END_OF_INSTR();
  4511. }
  4512. /****************************************************************************
  4513. REMARKS:
  4514. Handles opcode 0xfd
  4515. ****************************************************************************/
  4516. void x86emuOp_std(u8 X86EMU_UNUSED(op1))
  4517. {
  4518. /* clear interrupts. */
  4519. START_OF_INSTR();
  4520. DECODE_PRINTF("STD\n");
  4521. TRACE_AND_STEP();
  4522. SET_FLAG(F_DF);
  4523. DECODE_CLEAR_SEGOVR();
  4524. END_OF_INSTR();
  4525. }
  4526. /****************************************************************************
  4527. REMARKS:
  4528. Handles opcode 0xfe
  4529. ****************************************************************************/
  4530. void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
  4531. {
  4532. int mod, rh, rl;
  4533. u8 destval;
  4534. uint destoffset;
  4535. u8 *destreg;
  4536. /* Yet another special case instruction. */
  4537. START_OF_INSTR();
  4538. FETCH_DECODE_MODRM(mod, rh, rl);
  4539. #ifdef DEBUG
  4540. if (DEBUG_DECODE()) {
  4541. /* XXX DECODE_PRINTF may be changed to something more
  4542. general, so that it is important to leave the strings
  4543. in the same format, even though the result is that the
  4544. above test is done twice. */
  4545. switch (rh) {
  4546. case 0:
  4547. DECODE_PRINTF("INC\t");
  4548. break;
  4549. case 1:
  4550. DECODE_PRINTF("DEC\t");
  4551. break;
  4552. case 2:
  4553. case 3:
  4554. case 4:
  4555. case 5:
  4556. case 6:
  4557. case 7:
  4558. DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
  4559. HALT_SYS();
  4560. break;
  4561. }
  4562. }
  4563. #endif
  4564. if (mod < 3) {
  4565. DECODE_PRINTF("BYTE PTR ");
  4566. destoffset = decode_rmXX_address(mod, rl);
  4567. DECODE_PRINTF("\n");
  4568. destval = fetch_data_byte(destoffset);
  4569. TRACE_AND_STEP();
  4570. if (rh == 0)
  4571. destval = inc_byte(destval);
  4572. else
  4573. destval = dec_byte(destval);
  4574. store_data_byte(destoffset, destval);
  4575. } else {
  4576. destreg = DECODE_RM_BYTE_REGISTER(rl);
  4577. DECODE_PRINTF("\n");
  4578. TRACE_AND_STEP();
  4579. if (rh == 0)
  4580. *destreg = inc_byte(*destreg);
  4581. else
  4582. *destreg = dec_byte(*destreg);
  4583. }
  4584. DECODE_CLEAR_SEGOVR();
  4585. END_OF_INSTR();
  4586. }
  4587. /****************************************************************************
  4588. REMARKS:
  4589. Handles opcode 0xff
  4590. ****************************************************************************/
  4591. void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
  4592. {
  4593. int mod, rh, rl;
  4594. uint destoffset = 0;
  4595. u16 *destreg;
  4596. u16 destval,destval2;
  4597. /* Yet another special case instruction. */
  4598. START_OF_INSTR();
  4599. FETCH_DECODE_MODRM(mod, rh, rl);
  4600. #ifdef DEBUG
  4601. if (DEBUG_DECODE()) {
  4602. /* XXX DECODE_PRINTF may be changed to something more
  4603. general, so that it is important to leave the strings
  4604. in the same format, even though the result is that the
  4605. above test is done twice. */
  4606. switch (rh) {
  4607. case 0:
  4608. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  4609. DECODE_PRINTF("INC\tDWORD PTR ");
  4610. } else {
  4611. DECODE_PRINTF("INC\tWORD PTR ");
  4612. }
  4613. break;
  4614. case 1:
  4615. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  4616. DECODE_PRINTF("DEC\tDWORD PTR ");
  4617. } else {
  4618. DECODE_PRINTF("DEC\tWORD PTR ");
  4619. }
  4620. break;
  4621. case 2:
  4622. DECODE_PRINTF("CALL\t ");
  4623. break;
  4624. case 3:
  4625. DECODE_PRINTF("CALL\tFAR ");
  4626. break;
  4627. case 4:
  4628. DECODE_PRINTF("JMP\t");
  4629. break;
  4630. case 5:
  4631. DECODE_PRINTF("JMP\tFAR ");
  4632. break;
  4633. case 6:
  4634. DECODE_PRINTF("PUSH\t");
  4635. break;
  4636. case 7:
  4637. DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
  4638. HALT_SYS();
  4639. break;
  4640. }
  4641. }
  4642. #endif
  4643. if (mod < 3) {
  4644. destoffset = decode_rmXX_address(mod, rl);
  4645. DECODE_PRINTF("\n");
  4646. switch (rh) {
  4647. case 0: /* inc word ptr ... */
  4648. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  4649. u32 destval;
  4650. destval = fetch_data_long(destoffset);
  4651. TRACE_AND_STEP();
  4652. destval = inc_long(destval);
  4653. store_data_long(destoffset, destval);
  4654. } else {
  4655. u16 destval;
  4656. destval = fetch_data_word(destoffset);
  4657. TRACE_AND_STEP();
  4658. destval = inc_word(destval);
  4659. store_data_word(destoffset, destval);
  4660. }
  4661. break;
  4662. case 1: /* dec word ptr ... */
  4663. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  4664. u32 destval;
  4665. destval = fetch_data_long(destoffset);
  4666. TRACE_AND_STEP();
  4667. destval = dec_long(destval);
  4668. store_data_long(destoffset, destval);
  4669. } else {
  4670. u16 destval;
  4671. destval = fetch_data_word(destoffset);
  4672. TRACE_AND_STEP();
  4673. destval = dec_word(destval);
  4674. store_data_word(destoffset, destval);
  4675. }
  4676. break;
  4677. case 2: /* call word ptr ... */
  4678. destval = fetch_data_word(destoffset);
  4679. TRACE_AND_STEP();
  4680. push_word(M.x86.R_IP);
  4681. M.x86.R_IP = destval;
  4682. break;
  4683. case 3: /* call far ptr ... */
  4684. destval = fetch_data_word(destoffset);
  4685. destval2 = fetch_data_word(destoffset + 2);
  4686. TRACE_AND_STEP();
  4687. push_word(M.x86.R_CS);
  4688. M.x86.R_CS = destval2;
  4689. push_word(M.x86.R_IP);
  4690. M.x86.R_IP = destval;
  4691. break;
  4692. case 4: /* jmp word ptr ... */
  4693. destval = fetch_data_word(destoffset);
  4694. TRACE_AND_STEP();
  4695. M.x86.R_IP = destval;
  4696. break;
  4697. case 5: /* jmp far ptr ... */
  4698. destval = fetch_data_word(destoffset);
  4699. destval2 = fetch_data_word(destoffset + 2);
  4700. TRACE_AND_STEP();
  4701. M.x86.R_IP = destval;
  4702. M.x86.R_CS = destval2;
  4703. break;
  4704. case 6: /* push word ptr ... */
  4705. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  4706. u32 destval;
  4707. destval = fetch_data_long(destoffset);
  4708. TRACE_AND_STEP();
  4709. push_long(destval);
  4710. } else {
  4711. u16 destval;
  4712. destval = fetch_data_word(destoffset);
  4713. TRACE_AND_STEP();
  4714. push_word(destval);
  4715. }
  4716. break;
  4717. }
  4718. } else {
  4719. switch (rh) {
  4720. case 0:
  4721. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  4722. u32 *destreg;
  4723. destreg = DECODE_RM_LONG_REGISTER(rl);
  4724. DECODE_PRINTF("\n");
  4725. TRACE_AND_STEP();
  4726. *destreg = inc_long(*destreg);
  4727. } else {
  4728. u16 *destreg;
  4729. destreg = DECODE_RM_WORD_REGISTER(rl);
  4730. DECODE_PRINTF("\n");
  4731. TRACE_AND_STEP();
  4732. *destreg = inc_word(*destreg);
  4733. }
  4734. break;
  4735. case 1:
  4736. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  4737. u32 *destreg;
  4738. destreg = DECODE_RM_LONG_REGISTER(rl);
  4739. DECODE_PRINTF("\n");
  4740. TRACE_AND_STEP();
  4741. *destreg = dec_long(*destreg);
  4742. } else {
  4743. u16 *destreg;
  4744. destreg = DECODE_RM_WORD_REGISTER(rl);
  4745. DECODE_PRINTF("\n");
  4746. TRACE_AND_STEP();
  4747. *destreg = dec_word(*destreg);
  4748. }
  4749. break;
  4750. case 2: /* call word ptr ... */
  4751. destreg = DECODE_RM_WORD_REGISTER(rl);
  4752. DECODE_PRINTF("\n");
  4753. TRACE_AND_STEP();
  4754. push_word(M.x86.R_IP);
  4755. M.x86.R_IP = *destreg;
  4756. break;
  4757. case 3: /* jmp far ptr ... */
  4758. DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
  4759. TRACE_AND_STEP();
  4760. HALT_SYS();
  4761. break;
  4762. case 4: /* jmp ... */
  4763. destreg = DECODE_RM_WORD_REGISTER(rl);
  4764. DECODE_PRINTF("\n");
  4765. TRACE_AND_STEP();
  4766. M.x86.R_IP = (u16) (*destreg);
  4767. break;
  4768. case 5: /* jmp far ptr ... */
  4769. DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
  4770. TRACE_AND_STEP();
  4771. HALT_SYS();
  4772. break;
  4773. case 6:
  4774. if (M.x86.mode & SYSMODE_PREFIX_DATA) {
  4775. u32 *destreg;
  4776. destreg = DECODE_RM_LONG_REGISTER(rl);
  4777. DECODE_PRINTF("\n");
  4778. TRACE_AND_STEP();
  4779. push_long(*destreg);
  4780. } else {
  4781. u16 *destreg;
  4782. destreg = DECODE_RM_WORD_REGISTER(rl);
  4783. DECODE_PRINTF("\n");
  4784. TRACE_AND_STEP();
  4785. push_word(*destreg);
  4786. }
  4787. break;
  4788. }
  4789. }
  4790. DECODE_CLEAR_SEGOVR();
  4791. END_OF_INSTR();
  4792. }
  4793. /***************************************************************************
  4794. * Single byte operation code table:
  4795. **************************************************************************/
  4796. void (*x86emu_optab[256])(u8) __attribute__ ((section(GOT2_TYPE))) =
  4797. {
  4798. /* 0x00 */ x86emuOp_genop_byte_RM_R,
  4799. /* 0x01 */ x86emuOp_genop_word_RM_R,
  4800. /* 0x02 */ x86emuOp_genop_byte_R_RM,
  4801. /* 0x03 */ x86emuOp_genop_word_R_RM,
  4802. /* 0x04 */ x86emuOp_genop_byte_AL_IMM,
  4803. /* 0x05 */ x86emuOp_genop_word_AX_IMM,
  4804. /* 0x06 */ x86emuOp_push_ES,
  4805. /* 0x07 */ x86emuOp_pop_ES,
  4806. /* 0x08 */ x86emuOp_genop_byte_RM_R,
  4807. /* 0x09 */ x86emuOp_genop_word_RM_R,
  4808. /* 0x0a */ x86emuOp_genop_byte_R_RM,
  4809. /* 0x0b */ x86emuOp_genop_word_R_RM,
  4810. /* 0x0c */ x86emuOp_genop_byte_AL_IMM,
  4811. /* 0x0d */ x86emuOp_genop_word_AX_IMM,
  4812. /* 0x0e */ x86emuOp_push_CS,
  4813. /* 0x0f */ x86emuOp_two_byte,
  4814. /* 0x10 */ x86emuOp_genop_byte_RM_R,
  4815. /* 0x11 */ x86emuOp_genop_word_RM_R,
  4816. /* 0x12 */ x86emuOp_genop_byte_R_RM,
  4817. /* 0x13 */ x86emuOp_genop_word_R_RM,
  4818. /* 0x14 */ x86emuOp_genop_byte_AL_IMM,
  4819. /* 0x15 */ x86emuOp_genop_word_AX_IMM,
  4820. /* 0x16 */ x86emuOp_push_SS,
  4821. /* 0x17 */ x86emuOp_pop_SS,
  4822. /* 0x18 */ x86emuOp_genop_byte_RM_R,
  4823. /* 0x19 */ x86emuOp_genop_word_RM_R,
  4824. /* 0x1a */ x86emuOp_genop_byte_R_RM,
  4825. /* 0x1b */ x86emuOp_genop_word_R_RM,
  4826. /* 0x1c */ x86emuOp_genop_byte_AL_IMM,
  4827. /* 0x1d */ x86emuOp_genop_word_AX_IMM,
  4828. /* 0x1e */ x86emuOp_push_DS,
  4829. /* 0x1f */ x86emuOp_pop_DS,
  4830. /* 0x20 */ x86emuOp_genop_byte_RM_R,
  4831. /* 0x21 */ x86emuOp_genop_word_RM_R,
  4832. /* 0x22 */ x86emuOp_genop_byte_R_RM,
  4833. /* 0x23 */ x86emuOp_genop_word_R_RM,
  4834. /* 0x24 */ x86emuOp_genop_byte_AL_IMM,
  4835. /* 0x25 */ x86emuOp_genop_word_AX_IMM,
  4836. /* 0x26 */ x86emuOp_segovr_ES,
  4837. /* 0x27 */ x86emuOp_daa,
  4838. /* 0x28 */ x86emuOp_genop_byte_RM_R,
  4839. /* 0x29 */ x86emuOp_genop_word_RM_R,
  4840. /* 0x2a */ x86emuOp_genop_byte_R_RM,
  4841. /* 0x2b */ x86emuOp_genop_word_R_RM,
  4842. /* 0x2c */ x86emuOp_genop_byte_AL_IMM,
  4843. /* 0x2d */ x86emuOp_genop_word_AX_IMM,
  4844. /* 0x2e */ x86emuOp_segovr_CS,
  4845. /* 0x2f */ x86emuOp_das,
  4846. /* 0x30 */ x86emuOp_genop_byte_RM_R,
  4847. /* 0x31 */ x86emuOp_genop_word_RM_R,
  4848. /* 0x32 */ x86emuOp_genop_byte_R_RM,
  4849. /* 0x33 */ x86emuOp_genop_word_R_RM,
  4850. /* 0x34 */ x86emuOp_genop_byte_AL_IMM,
  4851. /* 0x35 */ x86emuOp_genop_word_AX_IMM,
  4852. /* 0x36 */ x86emuOp_segovr_SS,
  4853. /* 0x37 */ x86emuOp_aaa,
  4854. /* 0x38 */ x86emuOp_genop_byte_RM_R,
  4855. /* 0x39 */ x86emuOp_genop_word_RM_R,
  4856. /* 0x3a */ x86emuOp_genop_byte_R_RM,
  4857. /* 0x3b */ x86emuOp_genop_word_R_RM,
  4858. /* 0x3c */ x86emuOp_genop_byte_AL_IMM,
  4859. /* 0x3d */ x86emuOp_genop_word_AX_IMM,
  4860. /* 0x3e */ x86emuOp_segovr_DS,
  4861. /* 0x3f */ x86emuOp_aas,
  4862. /* 0x40 */ x86emuOp_inc_register,
  4863. /* 0x41 */ x86emuOp_inc_register,
  4864. /* 0x42 */ x86emuOp_inc_register,
  4865. /* 0x43 */ x86emuOp_inc_register,
  4866. /* 0x44 */ x86emuOp_inc_register,
  4867. /* 0x45 */ x86emuOp_inc_register,
  4868. /* 0x46 */ x86emuOp_inc_register,
  4869. /* 0x47 */ x86emuOp_inc_register,
  4870. /* 0x48 */ x86emuOp_dec_register,
  4871. /* 0x49 */ x86emuOp_dec_register,
  4872. /* 0x4a */ x86emuOp_dec_register,
  4873. /* 0x4b */ x86emuOp_dec_register,
  4874. /* 0x4c */ x86emuOp_dec_register,
  4875. /* 0x4d */ x86emuOp_dec_register,
  4876. /* 0x4e */ x86emuOp_dec_register,
  4877. /* 0x4f */ x86emuOp_dec_register,
  4878. /* 0x50 */ x86emuOp_push_register,
  4879. /* 0x51 */ x86emuOp_push_register,
  4880. /* 0x52 */ x86emuOp_push_register,
  4881. /* 0x53 */ x86emuOp_push_register,
  4882. /* 0x54 */ x86emuOp_push_register,
  4883. /* 0x55 */ x86emuOp_push_register,
  4884. /* 0x56 */ x86emuOp_push_register,
  4885. /* 0x57 */ x86emuOp_push_register,
  4886. /* 0x58 */ x86emuOp_pop_register,
  4887. /* 0x59 */ x86emuOp_pop_register,
  4888. /* 0x5a */ x86emuOp_pop_register,
  4889. /* 0x5b */ x86emuOp_pop_register,
  4890. /* 0x5c */ x86emuOp_pop_register,
  4891. /* 0x5d */ x86emuOp_pop_register,
  4892. /* 0x5e */ x86emuOp_pop_register,
  4893. /* 0x5f */ x86emuOp_pop_register,
  4894. /* 0x60 */ x86emuOp_push_all,
  4895. /* 0x61 */ x86emuOp_pop_all,
  4896. /* 0x62 */ x86emuOp_illegal_op, /* bound */
  4897. /* 0x63 */ x86emuOp_illegal_op, /* arpl */
  4898. /* 0x64 */ x86emuOp_segovr_FS,
  4899. /* 0x65 */ x86emuOp_segovr_GS,
  4900. /* 0x66 */ x86emuOp_prefix_data,
  4901. /* 0x67 */ x86emuOp_prefix_addr,
  4902. /* 0x68 */ x86emuOp_push_word_IMM,
  4903. /* 0x69 */ x86emuOp_imul_word_IMM,
  4904. /* 0x6a */ x86emuOp_push_byte_IMM,
  4905. /* 0x6b */ x86emuOp_imul_byte_IMM,
  4906. /* 0x6c */ x86emuOp_ins_byte,
  4907. /* 0x6d */ x86emuOp_ins_word,
  4908. /* 0x6e */ x86emuOp_outs_byte,
  4909. /* 0x6f */ x86emuOp_outs_word,
  4910. /* 0x70 */ x86emuOp_jump_near_cond,
  4911. /* 0x71 */ x86emuOp_jump_near_cond,
  4912. /* 0x72 */ x86emuOp_jump_near_cond,
  4913. /* 0x73 */ x86emuOp_jump_near_cond,
  4914. /* 0x74 */ x86emuOp_jump_near_cond,
  4915. /* 0x75 */ x86emuOp_jump_near_cond,
  4916. /* 0x76 */ x86emuOp_jump_near_cond,
  4917. /* 0x77 */ x86emuOp_jump_near_cond,
  4918. /* 0x78 */ x86emuOp_jump_near_cond,
  4919. /* 0x79 */ x86emuOp_jump_near_cond,
  4920. /* 0x7a */ x86emuOp_jump_near_cond,
  4921. /* 0x7b */ x86emuOp_jump_near_cond,
  4922. /* 0x7c */ x86emuOp_jump_near_cond,
  4923. /* 0x7d */ x86emuOp_jump_near_cond,
  4924. /* 0x7e */ x86emuOp_jump_near_cond,
  4925. /* 0x7f */ x86emuOp_jump_near_cond,
  4926. /* 0x80 */ x86emuOp_opc80_byte_RM_IMM,
  4927. /* 0x81 */ x86emuOp_opc81_word_RM_IMM,
  4928. /* 0x82 */ x86emuOp_opc82_byte_RM_IMM,
  4929. /* 0x83 */ x86emuOp_opc83_word_RM_IMM,
  4930. /* 0x84 */ x86emuOp_test_byte_RM_R,
  4931. /* 0x85 */ x86emuOp_test_word_RM_R,
  4932. /* 0x86 */ x86emuOp_xchg_byte_RM_R,
  4933. /* 0x87 */ x86emuOp_xchg_word_RM_R,
  4934. /* 0x88 */ x86emuOp_mov_byte_RM_R,
  4935. /* 0x89 */ x86emuOp_mov_word_RM_R,
  4936. /* 0x8a */ x86emuOp_mov_byte_R_RM,
  4937. /* 0x8b */ x86emuOp_mov_word_R_RM,
  4938. /* 0x8c */ x86emuOp_mov_word_RM_SR,
  4939. /* 0x8d */ x86emuOp_lea_word_R_M,
  4940. /* 0x8e */ x86emuOp_mov_word_SR_RM,
  4941. /* 0x8f */ x86emuOp_pop_RM,
  4942. /* 0x90 */ x86emuOp_nop,
  4943. /* 0x91 */ x86emuOp_xchg_word_AX_register,
  4944. /* 0x92 */ x86emuOp_xchg_word_AX_register,
  4945. /* 0x93 */ x86emuOp_xchg_word_AX_register,
  4946. /* 0x94 */ x86emuOp_xchg_word_AX_register,
  4947. /* 0x95 */ x86emuOp_xchg_word_AX_register,
  4948. /* 0x96 */ x86emuOp_xchg_word_AX_register,
  4949. /* 0x97 */ x86emuOp_xchg_word_AX_register,
  4950. /* 0x98 */ x86emuOp_cbw,
  4951. /* 0x99 */ x86emuOp_cwd,
  4952. /* 0x9a */ x86emuOp_call_far_IMM,
  4953. /* 0x9b */ x86emuOp_wait,
  4954. /* 0x9c */ x86emuOp_pushf_word,
  4955. /* 0x9d */ x86emuOp_popf_word,
  4956. /* 0x9e */ x86emuOp_sahf,
  4957. /* 0x9f */ x86emuOp_lahf,
  4958. /* 0xa0 */ x86emuOp_mov_AL_M_IMM,
  4959. /* 0xa1 */ x86emuOp_mov_AX_M_IMM,
  4960. /* 0xa2 */ x86emuOp_mov_M_AL_IMM,
  4961. /* 0xa3 */ x86emuOp_mov_M_AX_IMM,
  4962. /* 0xa4 */ x86emuOp_movs_byte,
  4963. /* 0xa5 */ x86emuOp_movs_word,
  4964. /* 0xa6 */ x86emuOp_cmps_byte,
  4965. /* 0xa7 */ x86emuOp_cmps_word,
  4966. /* 0xa8 */ x86emuOp_test_AL_IMM,
  4967. /* 0xa9 */ x86emuOp_test_AX_IMM,
  4968. /* 0xaa */ x86emuOp_stos_byte,
  4969. /* 0xab */ x86emuOp_stos_word,
  4970. /* 0xac */ x86emuOp_lods_byte,
  4971. /* 0xad */ x86emuOp_lods_word,
  4972. /* 0xac */ x86emuOp_scas_byte,
  4973. /* 0xad */ x86emuOp_scas_word,
  4974. /* 0xb0 */ x86emuOp_mov_byte_register_IMM,
  4975. /* 0xb1 */ x86emuOp_mov_byte_register_IMM,
  4976. /* 0xb2 */ x86emuOp_mov_byte_register_IMM,
  4977. /* 0xb3 */ x86emuOp_mov_byte_register_IMM,
  4978. /* 0xb4 */ x86emuOp_mov_byte_register_IMM,
  4979. /* 0xb5 */ x86emuOp_mov_byte_register_IMM,
  4980. /* 0xb6 */ x86emuOp_mov_byte_register_IMM,
  4981. /* 0xb7 */ x86emuOp_mov_byte_register_IMM,
  4982. /* 0xb8 */ x86emuOp_mov_word_register_IMM,
  4983. /* 0xb9 */ x86emuOp_mov_word_register_IMM,
  4984. /* 0xba */ x86emuOp_mov_word_register_IMM,
  4985. /* 0xbb */ x86emuOp_mov_word_register_IMM,
  4986. /* 0xbc */ x86emuOp_mov_word_register_IMM,
  4987. /* 0xbd */ x86emuOp_mov_word_register_IMM,
  4988. /* 0xbe */ x86emuOp_mov_word_register_IMM,
  4989. /* 0xbf */ x86emuOp_mov_word_register_IMM,
  4990. /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
  4991. /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM,
  4992. /* 0xc2 */ x86emuOp_ret_near_IMM,
  4993. /* 0xc3 */ x86emuOp_ret_near,
  4994. /* 0xc4 */ x86emuOp_les_R_IMM,
  4995. /* 0xc5 */ x86emuOp_lds_R_IMM,
  4996. /* 0xc6 */ x86emuOp_mov_byte_RM_IMM,
  4997. /* 0xc7 */ x86emuOp_mov_word_RM_IMM,
  4998. /* 0xc8 */ x86emuOp_enter,
  4999. /* 0xc9 */ x86emuOp_leave,
  5000. /* 0xca */ x86emuOp_ret_far_IMM,
  5001. /* 0xcb */ x86emuOp_ret_far,
  5002. /* 0xcc */ x86emuOp_int3,
  5003. /* 0xcd */ x86emuOp_int_IMM,
  5004. /* 0xce */ x86emuOp_into,
  5005. /* 0xcf */ x86emuOp_iret,
  5006. /* 0xd0 */ x86emuOp_opcD0_byte_RM_1,
  5007. /* 0xd1 */ x86emuOp_opcD1_word_RM_1,
  5008. /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL,
  5009. /* 0xd3 */ x86emuOp_opcD3_word_RM_CL,
  5010. /* 0xd4 */ x86emuOp_aam,
  5011. /* 0xd5 */ x86emuOp_aad,
  5012. /* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */
  5013. /* 0xd7 */ x86emuOp_xlat,
  5014. /* 0xd8 */ NULL, /*x86emuOp_esc_coprocess_d8,*/
  5015. /* 0xd9 */ NULL, /*x86emuOp_esc_coprocess_d9,*/
  5016. /* 0xda */ NULL, /*x86emuOp_esc_coprocess_da,*/
  5017. /* 0xdb */ NULL, /*x86emuOp_esc_coprocess_db,*/
  5018. /* 0xdc */ NULL, /*x86emuOp_esc_coprocess_dc,*/
  5019. /* 0xdd */ NULL, /*x86emuOp_esc_coprocess_dd,*/
  5020. /* 0xde */ NULL, /*x86emuOp_esc_coprocess_de,*/
  5021. /* 0xdf */ NULL, /*x86emuOp_esc_coprocess_df,*/
  5022. /* 0xe0 */ x86emuOp_loopne,
  5023. /* 0xe1 */ x86emuOp_loope,
  5024. /* 0xe2 */ x86emuOp_loop,
  5025. /* 0xe3 */ x86emuOp_jcxz,
  5026. /* 0xe4 */ x86emuOp_in_byte_AL_IMM,
  5027. /* 0xe5 */ x86emuOp_in_word_AX_IMM,
  5028. /* 0xe6 */ x86emuOp_out_byte_IMM_AL,
  5029. /* 0xe7 */ x86emuOp_out_word_IMM_AX,
  5030. /* 0xe8 */ x86emuOp_call_near_IMM,
  5031. /* 0xe9 */ x86emuOp_jump_near_IMM,
  5032. /* 0xea */ x86emuOp_jump_far_IMM,
  5033. /* 0xeb */ x86emuOp_jump_byte_IMM,
  5034. /* 0xec */ x86emuOp_in_byte_AL_DX,
  5035. /* 0xed */ x86emuOp_in_word_AX_DX,
  5036. /* 0xee */ x86emuOp_out_byte_DX_AL,
  5037. /* 0xef */ x86emuOp_out_word_DX_AX,
  5038. /* 0xf0 */ x86emuOp_lock,
  5039. /* 0xf1 */ x86emuOp_illegal_op,
  5040. /* 0xf2 */ x86emuOp_repne,
  5041. /* 0xf3 */ x86emuOp_repe,
  5042. /* 0xf4 */ x86emuOp_halt,
  5043. /* 0xf5 */ x86emuOp_cmc,
  5044. /* 0xf6 */ x86emuOp_opcF6_byte_RM,
  5045. /* 0xf7 */ x86emuOp_opcF7_word_RM,
  5046. /* 0xf8 */ x86emuOp_clc,
  5047. /* 0xf9 */ x86emuOp_stc,
  5048. /* 0xfa */ x86emuOp_cli,
  5049. /* 0xfb */ x86emuOp_sti,
  5050. /* 0xfc */ x86emuOp_cld,
  5051. /* 0xfd */ x86emuOp_std,
  5052. /* 0xfe */ x86emuOp_opcFE_byte_RM,
  5053. /* 0xff */ x86emuOp_opcFF_word_RM,
  5054. };
  5055. #endif