x86emu.c 179 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415
  1. /* $OpenBSD: x86emu.c,v 1.9 2014/06/15 11:04:49 pirofti Exp $ */
  2. /* $NetBSD: x86emu.c,v 1.7 2009/02/03 19:26:29 joerg Exp $ */
  3. /*
  4. *
  5. * Realmode X86 Emulator Library
  6. *
  7. * Copyright (C) 1996-1999 SciTech Software, Inc.
  8. * Copyright (C) David Mosberger-Tang
  9. * Copyright (C) 1999 Egbert Eich
  10. * Copyright (C) 2007 Joerg Sonnenberger
  11. *
  12. * ========================================================================
  13. *
  14. * Permission to use, copy, modify, distribute, and sell this software and
  15. * its documentation for any purpose is hereby granted without fee,
  16. * provided that the above copyright notice appear in all copies and that
  17. * both that copyright notice and this permission notice appear in
  18. * supporting documentation, and that the name of the authors not be used
  19. * in advertising or publicity pertaining to distribution of the software
  20. * without specific, written prior permission. The authors makes no
  21. * representations about the suitability of this software for any purpose.
  22. * It is provided "as is" without express or implied warranty.
  23. *
  24. * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  25. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  26. * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  27. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  28. * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  29. * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  30. * PERFORMANCE OF THIS SOFTWARE.
  31. *
  32. */
  33. #include <dev/x86emu/x86emu.h>
  34. #include <dev/x86emu/x86emu_regs.h>
  35. static void x86emu_intr_raise (struct x86emu *, uint8_t type);
  36. static void x86emu_exec_one_byte(struct x86emu *);
  37. static void x86emu_exec_two_byte(struct x86emu *);
  38. static void fetch_decode_modrm (struct x86emu *);
  39. static uint8_t fetch_byte_imm (struct x86emu *);
  40. static uint16_t fetch_word_imm (struct x86emu *);
  41. static uint32_t fetch_long_imm (struct x86emu *);
  42. static uint8_t fetch_data_byte (struct x86emu *, uint32_t offset);
  43. static uint8_t fetch_byte (struct x86emu *, uint segment, uint32_t offset);
  44. static uint16_t fetch_data_word (struct x86emu *, uint32_t offset);
  45. static uint16_t fetch_word (struct x86emu *, uint32_t segment, uint32_t offset);
  46. static uint32_t fetch_data_long (struct x86emu *, uint32_t offset);
  47. static uint32_t fetch_long (struct x86emu *, uint32_t segment, uint32_t offset);
  48. static void store_data_byte (struct x86emu *, uint32_t offset, uint8_t val);
  49. static void store_byte (struct x86emu *, uint32_t segment, uint32_t offset, uint8_t val);
  50. static void store_data_word (struct x86emu *, uint32_t offset, uint16_t val);
  51. static void store_word (struct x86emu *, uint32_t segment, uint32_t offset, uint16_t val);
  52. static void store_data_long (struct x86emu *, uint32_t offset, uint32_t val);
  53. static void store_long (struct x86emu *, uint32_t segment, uint32_t offset, uint32_t val);
  54. static uint8_t* decode_rl_byte_register(struct x86emu *);
  55. static uint16_t* decode_rl_word_register(struct x86emu *);
  56. static uint32_t* decode_rl_long_register(struct x86emu *);
  57. static uint8_t* decode_rh_byte_register(struct x86emu *);
  58. static uint16_t* decode_rh_word_register(struct x86emu *);
  59. static uint32_t* decode_rh_long_register(struct x86emu *);
  60. static uint16_t* decode_rh_seg_register(struct x86emu *);
  61. static uint32_t decode_rl_address(struct x86emu *);
  62. static uint8_t decode_and_fetch_byte(struct x86emu *);
  63. static uint16_t decode_and_fetch_word(struct x86emu *);
  64. static uint32_t decode_and_fetch_long(struct x86emu *);
  65. static uint8_t decode_and_fetch_byte_imm8(struct x86emu *, uint8_t *);
  66. static uint16_t decode_and_fetch_word_imm8(struct x86emu *, uint8_t *);
  67. static uint32_t decode_and_fetch_long_imm8(struct x86emu *, uint8_t *);
  68. static uint16_t decode_and_fetch_word_disp(struct x86emu *, int16_t);
  69. static uint32_t decode_and_fetch_long_disp(struct x86emu *, int16_t);
  70. static void write_back_byte(struct x86emu *, uint8_t);
  71. static void write_back_word(struct x86emu *, uint16_t);
  72. static void write_back_long(struct x86emu *, uint32_t);
  73. static uint16_t aaa_word (struct x86emu *, uint16_t d);
  74. static uint16_t aas_word (struct x86emu *, uint16_t d);
  75. static uint16_t aad_word (struct x86emu *, uint16_t d);
  76. static uint16_t aam_word (struct x86emu *, uint8_t d);
  77. static uint8_t adc_byte (struct x86emu *, uint8_t d, uint8_t s);
  78. static uint16_t adc_word (struct x86emu *, uint16_t d, uint16_t s);
  79. static uint32_t adc_long (struct x86emu *, uint32_t d, uint32_t s);
  80. static uint8_t add_byte (struct x86emu *, uint8_t d, uint8_t s);
  81. static uint16_t add_word (struct x86emu *, uint16_t d, uint16_t s);
  82. static uint32_t add_long (struct x86emu *, uint32_t d, uint32_t s);
  83. static uint8_t and_byte (struct x86emu *, uint8_t d, uint8_t s);
  84. static uint16_t and_word (struct x86emu *, uint16_t d, uint16_t s);
  85. static uint32_t and_long (struct x86emu *, uint32_t d, uint32_t s);
  86. static uint8_t cmp_byte (struct x86emu *, uint8_t d, uint8_t s);
  87. static uint16_t cmp_word (struct x86emu *, uint16_t d, uint16_t s);
  88. static uint32_t cmp_long (struct x86emu *, uint32_t d, uint32_t s);
  89. static void cmp_byte_no_return (struct x86emu *, uint8_t d, uint8_t s);
  90. static void cmp_word_no_return (struct x86emu *, uint16_t d, uint16_t s);
  91. static void cmp_long_no_return (struct x86emu *, uint32_t d, uint32_t s);
  92. static uint8_t daa_byte (struct x86emu *, uint8_t d);
  93. static uint8_t das_byte (struct x86emu *, uint8_t d);
  94. static uint8_t dec_byte (struct x86emu *, uint8_t d);
  95. static uint16_t dec_word (struct x86emu *, uint16_t d);
  96. static uint32_t dec_long (struct x86emu *, uint32_t d);
  97. static uint8_t inc_byte (struct x86emu *, uint8_t d);
  98. static uint16_t inc_word (struct x86emu *, uint16_t d);
  99. static uint32_t inc_long (struct x86emu *, uint32_t d);
  100. static uint8_t or_byte (struct x86emu *, uint8_t d, uint8_t s);
  101. static uint16_t or_word (struct x86emu *, uint16_t d, uint16_t s);
  102. static uint32_t or_long (struct x86emu *, uint32_t d, uint32_t s);
  103. static uint8_t neg_byte (struct x86emu *, uint8_t s);
  104. static uint16_t neg_word (struct x86emu *, uint16_t s);
  105. static uint32_t neg_long (struct x86emu *, uint32_t s);
  106. static uint8_t rcl_byte (struct x86emu *, uint8_t d, uint8_t s);
  107. static uint16_t rcl_word (struct x86emu *, uint16_t d, uint8_t s);
  108. static uint32_t rcl_long (struct x86emu *, uint32_t d, uint8_t s);
  109. static uint8_t rcr_byte (struct x86emu *, uint8_t d, uint8_t s);
  110. static uint16_t rcr_word (struct x86emu *, uint16_t d, uint8_t s);
  111. static uint32_t rcr_long (struct x86emu *, uint32_t d, uint8_t s);
  112. static uint8_t rol_byte (struct x86emu *, uint8_t d, uint8_t s);
  113. static uint16_t rol_word (struct x86emu *, uint16_t d, uint8_t s);
  114. static uint32_t rol_long (struct x86emu *, uint32_t d, uint8_t s);
  115. static uint8_t ror_byte (struct x86emu *, uint8_t d, uint8_t s);
  116. static uint16_t ror_word (struct x86emu *, uint16_t d, uint8_t s);
  117. static uint32_t ror_long (struct x86emu *, uint32_t d, uint8_t s);
  118. static uint8_t shl_byte (struct x86emu *, uint8_t d, uint8_t s);
  119. static uint16_t shl_word (struct x86emu *, uint16_t d, uint8_t s);
  120. static uint32_t shl_long (struct x86emu *, uint32_t d, uint8_t s);
  121. static uint8_t shr_byte (struct x86emu *, uint8_t d, uint8_t s);
  122. static uint16_t shr_word (struct x86emu *, uint16_t d, uint8_t s);
  123. static uint32_t shr_long (struct x86emu *, uint32_t d, uint8_t s);
  124. static uint8_t sar_byte (struct x86emu *, uint8_t d, uint8_t s);
  125. static uint16_t sar_word (struct x86emu *, uint16_t d, uint8_t s);
  126. static uint32_t sar_long (struct x86emu *, uint32_t d, uint8_t s);
  127. static uint16_t shld_word (struct x86emu *, uint16_t d, uint16_t fill, uint8_t s);
  128. static uint32_t shld_long (struct x86emu *, uint32_t d, uint32_t fill, uint8_t s);
  129. static uint16_t shrd_word (struct x86emu *, uint16_t d, uint16_t fill, uint8_t s);
  130. static uint32_t shrd_long (struct x86emu *, uint32_t d, uint32_t fill, uint8_t s);
  131. static uint8_t sbb_byte (struct x86emu *, uint8_t d, uint8_t s);
  132. static uint16_t sbb_word (struct x86emu *, uint16_t d, uint16_t s);
  133. static uint32_t sbb_long (struct x86emu *, uint32_t d, uint32_t s);
  134. static uint8_t sub_byte (struct x86emu *, uint8_t d, uint8_t s);
  135. static uint16_t sub_word (struct x86emu *, uint16_t d, uint16_t s);
  136. static uint32_t sub_long (struct x86emu *, uint32_t d, uint32_t s);
  137. static void test_byte (struct x86emu *, uint8_t d, uint8_t s);
  138. static void test_word (struct x86emu *, uint16_t d, uint16_t s);
  139. static void test_long (struct x86emu *, uint32_t d, uint32_t s);
  140. static uint8_t xor_byte (struct x86emu *, uint8_t d, uint8_t s);
  141. static uint16_t xor_word (struct x86emu *, uint16_t d, uint16_t s);
  142. static uint32_t xor_long (struct x86emu *, uint32_t d, uint32_t s);
  143. static void imul_byte (struct x86emu *, uint8_t s);
  144. static void imul_word (struct x86emu *, uint16_t s);
  145. static void imul_long (struct x86emu *, uint32_t s);
  146. static void mul_byte (struct x86emu *, uint8_t s);
  147. static void mul_word (struct x86emu *, uint16_t s);
  148. static void mul_long (struct x86emu *, uint32_t s);
  149. static void idiv_byte (struct x86emu *, uint8_t s);
  150. static void idiv_word (struct x86emu *, uint16_t s);
  151. static void idiv_long (struct x86emu *, uint32_t s);
  152. static void div_byte (struct x86emu *, uint8_t s);
  153. static void div_word (struct x86emu *, uint16_t s);
  154. static void div_long (struct x86emu *, uint32_t s);
  155. static void ins (struct x86emu *, int size);
  156. static void outs (struct x86emu *, int size);
  157. static void push_word (struct x86emu *, uint16_t w);
  158. static void push_long (struct x86emu *, uint32_t w);
  159. static uint16_t pop_word (struct x86emu *);
  160. static uint32_t pop_long (struct x86emu *);
  161. /*
  162. * REMARKS:
  163. * Handles any pending asychronous interrupts.
  164. */
  165. static void
  166. x86emu_intr_dispatch(struct x86emu *emu, uint8_t intno)
  167. {
  168. if (emu->_x86emu_intrTab[intno]) {
  169. (*emu->_x86emu_intrTab[intno]) (emu, intno);
  170. } else {
  171. push_word(emu, (uint16_t) emu->x86.R_FLG);
  172. CLEAR_FLAG(F_IF);
  173. CLEAR_FLAG(F_TF);
  174. push_word(emu, emu->x86.R_CS);
  175. emu->x86.R_CS = fetch_word(emu, 0, intno * 4 + 2);
  176. push_word(emu, emu->x86.R_IP);
  177. emu->x86.R_IP = fetch_word(emu, 0, intno * 4);
  178. }
  179. }
  180. static void
  181. x86emu_intr_handle(struct x86emu *emu)
  182. {
  183. uint8_t intno;
  184. if (emu->x86.intr & INTR_SYNCH) {
  185. intno = emu->x86.intno;
  186. emu->x86.intr = 0;
  187. x86emu_intr_dispatch(emu, intno);
  188. }
  189. }
  190. /*
  191. * PARAMETERS:
  192. * intrnum - Interrupt number to raise
  193. *
  194. * REMARKS:
  195. * Raise the specified interrupt to be handled before the execution of the
  196. * next instruction.
  197. */
  198. void
  199. x86emu_intr_raise(struct x86emu *emu, uint8_t intrnum)
  200. {
  201. emu->x86.intno = intrnum;
  202. emu->x86.intr |= INTR_SYNCH;
  203. }
  204. /*
  205. * REMARKS:
  206. * Main execution loop for the emulator. We return from here when the system
  207. * halts, which is normally caused by a stack fault when we return from the
  208. * original real mode call.
  209. */
  210. void
  211. x86emu_exec(struct x86emu *emu)
  212. {
  213. emu->x86.intr = 0;
  214. #ifdef _KERNEL
  215. if (setjmp(&emu->exec_state))
  216. return;
  217. #else
  218. if (setjmp(emu->exec_state))
  219. return;
  220. #endif
  221. for (;;) {
  222. if (emu->x86.intr) {
  223. if (((emu->x86.intr & INTR_SYNCH) &&
  224. (emu->x86.intno == 0 || emu->x86.intno == 2)) ||
  225. !ACCESS_FLAG(F_IF)) {
  226. x86emu_intr_handle(emu);
  227. }
  228. }
  229. if (emu->x86.R_CS == 0 && emu->x86.R_IP == 0)
  230. return;
  231. x86emu_exec_one_byte(emu);
  232. ++emu->cur_cycles;
  233. }
  234. }
  235. void
  236. x86emu_exec_call(struct x86emu *emu, uint16_t seg, uint16_t off)
  237. {
  238. push_word(emu, 0);
  239. push_word(emu, 0);
  240. emu->x86.R_CS = seg;
  241. emu->x86.R_IP = off;
  242. x86emu_exec(emu);
  243. }
  244. void
  245. x86emu_exec_intr(struct x86emu *emu, uint8_t intr)
  246. {
  247. push_word(emu, emu->x86.R_FLG);
  248. CLEAR_FLAG(F_IF);
  249. CLEAR_FLAG(F_TF);
  250. push_word(emu, 0);
  251. push_word(emu, 0);
  252. emu->x86.R_CS = (*emu->emu_rdw)(emu, intr * 4 + 2);
  253. emu->x86.R_IP = (*emu->emu_rdw)(emu, intr * 4);
  254. emu->x86.intr = 0;
  255. x86emu_exec(emu);
  256. }
  257. /*
  258. * REMARKS:
  259. * Halts the system by setting the halted system flag.
  260. */
  261. void
  262. x86emu_halt_sys(struct x86emu *emu)
  263. {
  264. #ifdef _KERNEL
  265. longjmp(&emu->exec_state);
  266. #else
  267. longjmp(emu->exec_state, 1);
  268. #endif
  269. }
  270. /*
  271. * PARAMETERS:
  272. * mod - Mod value from decoded byte
  273. * regh - Reg h value from decoded byte
  274. * regl - Reg l value from decoded byte
  275. *
  276. * REMARKS:
  277. * Raise the specified interrupt to be handled before the execution of the
  278. * next instruction.
  279. *
  280. * NOTE: Do not inline this function, as (*emu->emu_rdb) is already inline!
  281. */
  282. static void
  283. fetch_decode_modrm(struct x86emu *emu)
  284. {
  285. int fetched;
  286. fetched = fetch_byte_imm(emu);
  287. emu->cur_mod = (fetched >> 6) & 0x03;
  288. emu->cur_rh = (fetched >> 3) & 0x07;
  289. emu->cur_rl = (fetched >> 0) & 0x07;
  290. }
  291. /*
  292. * RETURNS:
  293. * Immediate byte value read from instruction queue
  294. *
  295. * REMARKS:
  296. * This function returns the immediate byte from the instruction queue, and
  297. * moves the instruction pointer to the next value.
  298. *
  299. * NOTE: Do not inline this function, as (*emu->emu_rdb) is already inline!
  300. */
  301. static uint8_t
  302. fetch_byte_imm(struct x86emu *emu)
  303. {
  304. uint8_t fetched;
  305. fetched = fetch_byte(emu, emu->x86.R_CS, emu->x86.R_IP);
  306. emu->x86.R_IP++;
  307. return fetched;
  308. }
  309. /*
  310. * RETURNS:
  311. * Immediate word value read from instruction queue
  312. *
  313. * REMARKS:
  314. * This function returns the immediate byte from the instruction queue, and
  315. * moves the instruction pointer to the next value.
  316. *
  317. * NOTE: Do not inline this function, as (*emu->emu_rdw) is already inline!
  318. */
  319. static uint16_t
  320. fetch_word_imm(struct x86emu *emu)
  321. {
  322. uint16_t fetched;
  323. fetched = fetch_word(emu, emu->x86.R_CS, emu->x86.R_IP);
  324. emu->x86.R_IP += 2;
  325. return fetched;
  326. }
  327. /*
  328. * RETURNS:
  329. * Immediate lone value read from instruction queue
  330. *
  331. * REMARKS:
  332. * This function returns the immediate byte from the instruction queue, and
  333. * moves the instruction pointer to the next value.
  334. *
  335. * NOTE: Do not inline this function, as (*emu->emu_rdw) is already inline!
  336. */
  337. static uint32_t
  338. fetch_long_imm(struct x86emu *emu)
  339. {
  340. uint32_t fetched;
  341. fetched = fetch_long(emu, emu->x86.R_CS, emu->x86.R_IP);
  342. emu->x86.R_IP += 4;
  343. return fetched;
  344. }
  345. /*
  346. * RETURNS:
  347. * Value of the default data segment
  348. *
  349. * REMARKS:
  350. * Inline function that returns the default data segment for the current
  351. * instruction.
  352. *
  353. * On the x86 processor, the default segment is not always DS if there is
  354. * no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to
  355. * addresses relative to SS (ie: on the stack). So, at the minimum, all
  356. * decodings of addressing modes would have to set/clear a bit describing
  357. * whether the access is relative to DS or SS. That is the function of the
  358. * cpu-state-varible emu->x86.mode. There are several potential states:
  359. *
  360. * repe prefix seen (handled elsewhere)
  361. * repne prefix seen (ditto)
  362. *
  363. * cs segment override
  364. * ds segment override
  365. * es segment override
  366. * fs segment override
  367. * gs segment override
  368. * ss segment override
  369. *
  370. * ds/ss select (in absense of override)
  371. *
  372. * Each of the above 7 items are handled with a bit in the mode field.
  373. */
  374. static uint32_t
  375. get_data_segment(struct x86emu *emu)
  376. {
  377. switch (emu->x86.mode & SYSMODE_SEGMASK) {
  378. case 0: /* default case: use ds register */
  379. case SYSMODE_SEGOVR_DS:
  380. case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS:
  381. return emu->x86.R_DS;
  382. case SYSMODE_SEG_DS_SS:/* non-overridden, use ss register */
  383. return emu->x86.R_SS;
  384. case SYSMODE_SEGOVR_CS:
  385. case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS:
  386. return emu->x86.R_CS;
  387. case SYSMODE_SEGOVR_ES:
  388. case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS:
  389. return emu->x86.R_ES;
  390. case SYSMODE_SEGOVR_FS:
  391. case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS:
  392. return emu->x86.R_FS;
  393. case SYSMODE_SEGOVR_GS:
  394. case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS:
  395. return emu->x86.R_GS;
  396. case SYSMODE_SEGOVR_SS:
  397. case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS:
  398. return emu->x86.R_SS;
  399. }
  400. x86emu_halt_sys(emu);
  401. }
  402. /*
  403. * PARAMETERS:
  404. * offset - Offset to load data from
  405. *
  406. * RETURNS:
  407. * Byte value read from the absolute memory location.
  408. *
  409. * NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
  410. */
  411. static uint8_t
  412. fetch_data_byte(struct x86emu *emu, uint32_t offset)
  413. {
  414. return fetch_byte(emu, get_data_segment(emu), offset);
  415. }
  416. /*
  417. * PARAMETERS:
  418. * offset - Offset to load data from
  419. *
  420. * RETURNS:
  421. * Word value read from the absolute memory location.
  422. *
  423. * NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
  424. */
  425. static uint16_t
  426. fetch_data_word(struct x86emu *emu, uint32_t offset)
  427. {
  428. return fetch_word(emu, get_data_segment(emu), offset);
  429. }
  430. /*
  431. * PARAMETERS:
  432. * offset - Offset to load data from
  433. *
  434. * RETURNS:
  435. * Long value read from the absolute memory location.
  436. *
  437. * NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
  438. */
  439. static uint32_t
  440. fetch_data_long(struct x86emu *emu, uint32_t offset)
  441. {
  442. return fetch_long(emu, get_data_segment(emu), offset);
  443. }
  444. /*
  445. * PARAMETERS:
  446. * segment - Segment to load data from
  447. * offset - Offset to load data from
  448. *
  449. * RETURNS:
  450. * Byte value read from the absolute memory location.
  451. *
  452. * NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
  453. */
  454. static uint8_t
  455. fetch_byte(struct x86emu *emu, uint32_t segment, uint32_t offset)
  456. {
  457. return (*emu->emu_rdb) (emu, ((uint32_t) segment << 4) + offset);
  458. }
  459. /*
  460. * PARAMETERS:
  461. * segment - Segment to load data from
  462. * offset - Offset to load data from
  463. *
  464. * RETURNS:
  465. * Word value read from the absolute memory location.
  466. *
  467. * NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
  468. */
  469. static uint16_t
  470. fetch_word(struct x86emu *emu, uint32_t segment, uint32_t offset)
  471. {
  472. return (*emu->emu_rdw) (emu, ((uint32_t) segment << 4) + offset);
  473. }
  474. /*
  475. * PARAMETERS:
  476. * segment - Segment to load data from
  477. * offset - Offset to load data from
  478. *
  479. * RETURNS:
  480. * Long value read from the absolute memory location.
  481. *
  482. * NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
  483. */
  484. static uint32_t
  485. fetch_long(struct x86emu *emu, uint32_t segment, uint32_t offset)
  486. {
  487. return (*emu->emu_rdl) (emu, ((uint32_t) segment << 4) + offset);
  488. }
  489. /*
  490. * PARAMETERS:
  491. * offset - Offset to store data at
  492. * val - Value to store
  493. *
  494. * REMARKS:
  495. * Writes a word value to an segmented memory location. The segment used is
  496. * the current 'default' segment, which may have been overridden.
  497. *
  498. * NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
  499. */
  500. static void
  501. store_data_byte(struct x86emu *emu, uint32_t offset, uint8_t val)
  502. {
  503. store_byte(emu, get_data_segment(emu), offset, val);
  504. }
  505. /*
  506. * PARAMETERS:
  507. * offset - Offset to store data at
  508. * val - Value to store
  509. *
  510. * REMARKS:
  511. * Writes a word value to an segmented memory location. The segment used is
  512. * the current 'default' segment, which may have been overridden.
  513. *
  514. * NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
  515. */
  516. static void
  517. store_data_word(struct x86emu *emu, uint32_t offset, uint16_t val)
  518. {
  519. store_word(emu, get_data_segment(emu), offset, val);
  520. }
  521. /*
  522. * PARAMETERS:
  523. * offset - Offset to store data at
  524. * val - Value to store
  525. *
  526. * REMARKS:
  527. * Writes a long value to an segmented memory location. The segment used is
  528. * the current 'default' segment, which may have been overridden.
  529. *
  530. * NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
  531. */
  532. static void
  533. store_data_long(struct x86emu *emu, uint32_t offset, uint32_t val)
  534. {
  535. store_long(emu, get_data_segment(emu), offset, val);
  536. }
  537. /*
  538. * PARAMETERS:
  539. * segment - Segment to store data at
  540. * offset - Offset to store data at
  541. * val - Value to store
  542. *
  543. * REMARKS:
  544. * Writes a byte value to an absolute memory location.
  545. *
  546. * NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
  547. */
  548. static void
  549. store_byte(struct x86emu *emu, uint32_t segment, uint32_t offset, uint8_t val)
  550. {
  551. (*emu->emu_wrb) (emu, ((uint32_t) segment << 4) + offset, val);
  552. }
  553. /*
  554. * PARAMETERS:
  555. * segment - Segment to store data at
  556. * offset - Offset to store data at
  557. * val - Value to store
  558. *
  559. * REMARKS:
  560. * Writes a word value to an absolute memory location.
  561. *
  562. * NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
  563. */
  564. static void
  565. store_word(struct x86emu *emu, uint32_t segment, uint32_t offset, uint16_t val)
  566. {
  567. (*emu->emu_wrw) (emu, ((uint32_t) segment << 4) + offset, val);
  568. }
  569. /*
  570. * PARAMETERS:
  571. * segment - Segment to store data at
  572. * offset - Offset to store data at
  573. * val - Value to store
  574. *
  575. * REMARKS:
  576. * Writes a long value to an absolute memory location.
  577. *
  578. * NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
  579. */
  580. static void
  581. store_long(struct x86emu *emu, uint32_t segment, uint32_t offset, uint32_t val)
  582. {
  583. (*emu->emu_wrl) (emu, ((uint32_t) segment << 4) + offset, val);
  584. }
  585. /*
  586. * PARAMETERS:
  587. * reg - Register to decode
  588. *
  589. * RETURNS:
  590. * Pointer to the appropriate register
  591. *
  592. * REMARKS:
  593. * Return a pointer to the register given by the R/RM field of the
  594. * modrm byte, for byte operands. Also enables the decoding of instructions.
  595. */
  596. static uint8_t *
  597. decode_rm_byte_register(struct x86emu *emu, int reg)
  598. {
  599. switch (reg) {
  600. case 0:
  601. return &emu->x86.R_AL;
  602. case 1:
  603. return &emu->x86.R_CL;
  604. case 2:
  605. return &emu->x86.R_DL;
  606. case 3:
  607. return &emu->x86.R_BL;
  608. case 4:
  609. return &emu->x86.R_AH;
  610. case 5:
  611. return &emu->x86.R_CH;
  612. case 6:
  613. return &emu->x86.R_DH;
  614. case 7:
  615. return &emu->x86.R_BH;
  616. default:
  617. x86emu_halt_sys(emu);
  618. }
  619. }
  620. static uint8_t *
  621. decode_rl_byte_register(struct x86emu *emu)
  622. {
  623. return decode_rm_byte_register(emu, emu->cur_rl);
  624. }
  625. static uint8_t *
  626. decode_rh_byte_register(struct x86emu *emu)
  627. {
  628. return decode_rm_byte_register(emu, emu->cur_rh);
  629. }
  630. /*
  631. * PARAMETERS:
  632. * reg - Register to decode
  633. *
  634. * RETURNS:
  635. * Pointer to the appropriate register
  636. *
  637. * REMARKS:
  638. * Return a pointer to the register given by the R/RM field of the
  639. * modrm byte, for word operands. Also enables the decoding of instructions.
  640. */
  641. static uint16_t *
  642. decode_rm_word_register(struct x86emu *emu, int reg)
  643. {
  644. switch (reg) {
  645. case 0:
  646. return &emu->x86.R_AX;
  647. case 1:
  648. return &emu->x86.R_CX;
  649. case 2:
  650. return &emu->x86.R_DX;
  651. case 3:
  652. return &emu->x86.R_BX;
  653. case 4:
  654. return &emu->x86.R_SP;
  655. case 5:
  656. return &emu->x86.R_BP;
  657. case 6:
  658. return &emu->x86.R_SI;
  659. case 7:
  660. return &emu->x86.R_DI;
  661. default:
  662. x86emu_halt_sys(emu);
  663. }
  664. }
  665. static uint16_t *
  666. decode_rl_word_register(struct x86emu *emu)
  667. {
  668. return decode_rm_word_register(emu, emu->cur_rl);
  669. }
  670. static uint16_t *
  671. decode_rh_word_register(struct x86emu *emu)
  672. {
  673. return decode_rm_word_register(emu, emu->cur_rh);
  674. }
  675. /*
  676. * PARAMETERS:
  677. * reg - Register to decode
  678. *
  679. * RETURNS:
  680. * Pointer to the appropriate register
  681. *
  682. * REMARKS:
  683. * Return a pointer to the register given by the R/RM field of the
  684. * modrm byte, for dword operands. Also enables the decoding of instructions.
  685. */
  686. static uint32_t *
  687. decode_rm_long_register(struct x86emu *emu, int reg)
  688. {
  689. switch (reg) {
  690. case 0:
  691. return &emu->x86.R_EAX;
  692. case 1:
  693. return &emu->x86.R_ECX;
  694. case 2:
  695. return &emu->x86.R_EDX;
  696. case 3:
  697. return &emu->x86.R_EBX;
  698. case 4:
  699. return &emu->x86.R_ESP;
  700. case 5:
  701. return &emu->x86.R_EBP;
  702. case 6:
  703. return &emu->x86.R_ESI;
  704. case 7:
  705. return &emu->x86.R_EDI;
  706. default:
  707. x86emu_halt_sys(emu);
  708. }
  709. }
  710. static uint32_t *
  711. decode_rl_long_register(struct x86emu *emu)
  712. {
  713. return decode_rm_long_register(emu, emu->cur_rl);
  714. }
  715. static uint32_t *
  716. decode_rh_long_register(struct x86emu *emu)
  717. {
  718. return decode_rm_long_register(emu, emu->cur_rh);
  719. }
  720. /*
  721. * PARAMETERS:
  722. * reg - Register to decode
  723. *
  724. * RETURNS:
  725. * Pointer to the appropriate register
  726. *
  727. * REMARKS:
  728. * Return a pointer to the register given by the R/RM field of the
  729. * modrm byte, for word operands, modified from above for the weirdo
  730. * special case of segreg operands. Also enables the decoding of instructions.
  731. */
  732. static uint16_t *
  733. decode_rh_seg_register(struct x86emu *emu)
  734. {
  735. switch (emu->cur_rh) {
  736. case 0:
  737. return &emu->x86.R_ES;
  738. case 1:
  739. return &emu->x86.R_CS;
  740. case 2:
  741. return &emu->x86.R_SS;
  742. case 3:
  743. return &emu->x86.R_DS;
  744. case 4:
  745. return &emu->x86.R_FS;
  746. case 5:
  747. return &emu->x86.R_GS;
  748. default:
  749. x86emu_halt_sys(emu);
  750. }
  751. }
  752. /*
  753. * Return offset from the SIB Byte.
  754. */
  755. static uint32_t
  756. decode_sib_address(struct x86emu *emu, int sib, int mod)
  757. {
  758. uint32_t base = 0, i = 0, scale = 1;
  759. switch (sib & 0x07) {
  760. case 0:
  761. base = emu->x86.R_EAX;
  762. break;
  763. case 1:
  764. base = emu->x86.R_ECX;
  765. break;
  766. case 2:
  767. base = emu->x86.R_EDX;
  768. break;
  769. case 3:
  770. base = emu->x86.R_EBX;
  771. break;
  772. case 4:
  773. base = emu->x86.R_ESP;
  774. emu->x86.mode |= SYSMODE_SEG_DS_SS;
  775. break;
  776. case 5:
  777. if (mod == 0) {
  778. base = fetch_long_imm(emu);
  779. } else {
  780. base = emu->x86.R_EBP;
  781. emu->x86.mode |= SYSMODE_SEG_DS_SS;
  782. }
  783. break;
  784. case 6:
  785. base = emu->x86.R_ESI;
  786. break;
  787. case 7:
  788. base = emu->x86.R_EDI;
  789. break;
  790. }
  791. switch ((sib >> 3) & 0x07) {
  792. case 0:
  793. i = emu->x86.R_EAX;
  794. break;
  795. case 1:
  796. i = emu->x86.R_ECX;
  797. break;
  798. case 2:
  799. i = emu->x86.R_EDX;
  800. break;
  801. case 3:
  802. i = emu->x86.R_EBX;
  803. break;
  804. case 4:
  805. i = 0;
  806. break;
  807. case 5:
  808. i = emu->x86.R_EBP;
  809. break;
  810. case 6:
  811. i = emu->x86.R_ESI;
  812. break;
  813. case 7:
  814. i = emu->x86.R_EDI;
  815. break;
  816. }
  817. scale = 1 << ((sib >> 6) & 0x03);
  818. return base + (i * scale);
  819. }
  820. /*
  821. * PARAMETERS:
  822. * rm - RM value to decode
  823. *
  824. * RETURNS:
  825. * Offset in memory for the address decoding
  826. *
  827. * REMARKS:
  828. * Return the offset given by mod=00, mod=01 or mod=10 addressing.
  829. * Also enables the decoding of instructions.
  830. */
  831. static uint32_t
  832. decode_rl_address(struct x86emu *emu)
  833. {
  834. if (emu->x86.mode & SYSMODE_PREFIX_ADDR) {
  835. uint32_t offset, sib;
  836. /* 32-bit addressing */
  837. switch (emu->cur_rl) {
  838. case 0:
  839. offset = emu->x86.R_EAX;
  840. break;
  841. case 1:
  842. offset = emu->x86.R_ECX;
  843. break;
  844. case 2:
  845. offset = emu->x86.R_EDX;
  846. break;
  847. case 3:
  848. offset = emu->x86.R_EBX;
  849. break;
  850. case 4:
  851. sib = fetch_byte_imm(emu);
  852. offset = decode_sib_address(emu, sib, 0);
  853. break;
  854. case 5:
  855. if (emu->cur_mod == 0) {
  856. offset = fetch_long_imm(emu);
  857. } else {
  858. emu->x86.mode |= SYSMODE_SEG_DS_SS;
  859. offset = emu->x86.R_EBP;
  860. }
  861. break;
  862. case 6:
  863. offset = emu->x86.R_ESI;
  864. break;
  865. case 7:
  866. offset = emu->x86.R_EDI;
  867. break;
  868. default:
  869. x86emu_halt_sys(emu);
  870. }
  871. if (emu->cur_mod == 1)
  872. offset += (int8_t)fetch_byte_imm(emu);
  873. else if (emu->cur_mod == 2)
  874. offset += fetch_long_imm(emu);
  875. return offset;
  876. } else {
  877. uint16_t offset;
  878. /* 16-bit addressing */
  879. switch (emu->cur_rl) {
  880. case 0:
  881. offset = emu->x86.R_BX + emu->x86.R_SI;
  882. break;
  883. case 1:
  884. offset = emu->x86.R_BX + emu->x86.R_DI;
  885. break;
  886. case 2:
  887. emu->x86.mode |= SYSMODE_SEG_DS_SS;
  888. offset = emu->x86.R_BP + emu->x86.R_SI;
  889. break;
  890. case 3:
  891. emu->x86.mode |= SYSMODE_SEG_DS_SS;
  892. offset = emu->x86.R_BP + emu->x86.R_DI;
  893. break;
  894. case 4:
  895. offset = emu->x86.R_SI;
  896. break;
  897. case 5:
  898. offset = emu->x86.R_DI;
  899. break;
  900. case 6:
  901. if (emu->cur_mod == 0) {
  902. offset = fetch_word_imm(emu);
  903. } else {
  904. emu->x86.mode |= SYSMODE_SEG_DS_SS;
  905. offset = emu->x86.R_BP;
  906. }
  907. break;
  908. case 7:
  909. offset = emu->x86.R_BX;
  910. break;
  911. default:
  912. x86emu_halt_sys(emu);
  913. }
  914. if (emu->cur_mod == 1)
  915. offset += (int8_t)fetch_byte_imm(emu);
  916. else if (emu->cur_mod == 2)
  917. offset += fetch_word_imm(emu);
  918. return offset;
  919. }
  920. }
  921. static uint8_t
  922. decode_and_fetch_byte(struct x86emu *emu)
  923. {
  924. if (emu->cur_mod != 3) {
  925. emu->cur_offset = decode_rl_address(emu);
  926. return fetch_data_byte(emu, emu->cur_offset);
  927. } else {
  928. return *decode_rl_byte_register(emu);
  929. }
  930. }
  931. static uint16_t
  932. decode_and_fetch_word_disp(struct x86emu *emu, int16_t disp)
  933. {
  934. if (emu->cur_mod != 3) {
  935. /* TODO: A20 gate emulation */
  936. emu->cur_offset = decode_rl_address(emu) + disp;
  937. if ((emu->x86.mode & SYSMODE_PREFIX_ADDR) == 0)
  938. emu->cur_offset &= 0xffff;
  939. return fetch_data_word(emu, emu->cur_offset);
  940. } else {
  941. return *decode_rl_word_register(emu);
  942. }
  943. }
  944. static uint32_t
  945. decode_and_fetch_long_disp(struct x86emu *emu, int16_t disp)
  946. {
  947. if (emu->cur_mod != 3) {
  948. /* TODO: A20 gate emulation */
  949. emu->cur_offset = decode_rl_address(emu) + disp;
  950. if ((emu->x86.mode & SYSMODE_PREFIX_ADDR) == 0)
  951. emu->cur_offset &= 0xffff;
  952. return fetch_data_long(emu, emu->cur_offset);
  953. } else {
  954. return *decode_rl_long_register(emu);
  955. }
  956. }
  957. uint16_t
  958. decode_and_fetch_word(struct x86emu *emu)
  959. {
  960. return decode_and_fetch_word_disp(emu, 0);
  961. }
  962. uint32_t
  963. decode_and_fetch_long(struct x86emu *emu)
  964. {
  965. return decode_and_fetch_long_disp(emu, 0);
  966. }
  967. uint8_t
  968. decode_and_fetch_byte_imm8(struct x86emu *emu, uint8_t *imm)
  969. {
  970. if (emu->cur_mod != 3) {
  971. emu->cur_offset = decode_rl_address(emu);
  972. *imm = fetch_byte_imm(emu);
  973. return fetch_data_byte(emu, emu->cur_offset);
  974. } else {
  975. *imm = fetch_byte_imm(emu);
  976. return *decode_rl_byte_register(emu);
  977. }
  978. }
  979. static uint16_t
  980. decode_and_fetch_word_imm8(struct x86emu *emu, uint8_t *imm)
  981. {
  982. if (emu->cur_mod != 3) {
  983. emu->cur_offset = decode_rl_address(emu);
  984. *imm = fetch_byte_imm(emu);
  985. return fetch_data_word(emu, emu->cur_offset);
  986. } else {
  987. *imm = fetch_byte_imm(emu);
  988. return *decode_rl_word_register(emu);
  989. }
  990. }
  991. static uint32_t
  992. decode_and_fetch_long_imm8(struct x86emu *emu, uint8_t *imm)
  993. {
  994. if (emu->cur_mod != 3) {
  995. emu->cur_offset = decode_rl_address(emu);
  996. *imm = fetch_byte_imm(emu);
  997. return fetch_data_long(emu, emu->cur_offset);
  998. } else {
  999. *imm = fetch_byte_imm(emu);
  1000. return *decode_rl_long_register(emu);
  1001. }
  1002. }
  1003. static void
  1004. write_back_byte(struct x86emu *emu, uint8_t val)
  1005. {
  1006. if (emu->cur_mod != 3)
  1007. store_data_byte(emu, emu->cur_offset, val);
  1008. else
  1009. *decode_rl_byte_register(emu) = val;
  1010. }
  1011. static void
  1012. write_back_word(struct x86emu *emu, uint16_t val)
  1013. {
  1014. if (emu->cur_mod != 3)
  1015. store_data_word(emu, emu->cur_offset, val);
  1016. else
  1017. *decode_rl_word_register(emu) = val;
  1018. }
  1019. static void
  1020. write_back_long(struct x86emu *emu, uint32_t val)
  1021. {
  1022. if (emu->cur_mod != 3)
  1023. store_data_long(emu, emu->cur_offset, val);
  1024. else
  1025. *decode_rl_long_register(emu) = val;
  1026. }
  1027. static void
  1028. common_inc_word_long(struct x86emu *emu, union x86emu_register *reg)
  1029. {
  1030. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  1031. reg->I32_reg.e_reg = inc_long(emu, reg->I32_reg.e_reg);
  1032. else
  1033. reg->I16_reg.x_reg = inc_word(emu, reg->I16_reg.x_reg);
  1034. }
  1035. static void
  1036. common_dec_word_long(struct x86emu *emu, union x86emu_register *reg)
  1037. {
  1038. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  1039. reg->I32_reg.e_reg = dec_long(emu, reg->I32_reg.e_reg);
  1040. else
  1041. reg->I16_reg.x_reg = dec_word(emu, reg->I16_reg.x_reg);
  1042. }
  1043. static void
  1044. common_binop_byte_rm_r(struct x86emu *emu,
  1045. uint8_t (*binop)(struct x86emu *, uint8_t, uint8_t))
  1046. {
  1047. uint32_t destoffset;
  1048. uint8_t *destreg, srcval;
  1049. uint8_t destval;
  1050. fetch_decode_modrm(emu);
  1051. srcval = *decode_rh_byte_register(emu);
  1052. if (emu->cur_mod != 3) {
  1053. destoffset = decode_rl_address(emu);
  1054. destval = fetch_data_byte(emu, destoffset);
  1055. destval = (*binop)(emu, destval, srcval);
  1056. store_data_byte(emu, destoffset, destval);
  1057. } else {
  1058. destreg = decode_rl_byte_register(emu);
  1059. *destreg = (*binop)(emu, *destreg, srcval);
  1060. }
  1061. }
  1062. static void
  1063. common_binop_ns_byte_rm_r(struct x86emu *emu,
  1064. void (*binop)(struct x86emu *, uint8_t, uint8_t))
  1065. {
  1066. uint32_t destoffset;
  1067. uint8_t destval, srcval;
  1068. fetch_decode_modrm(emu);
  1069. srcval = *decode_rh_byte_register(emu);
  1070. if (emu->cur_mod != 3) {
  1071. destoffset = decode_rl_address(emu);
  1072. destval = fetch_data_byte(emu, destoffset);
  1073. } else {
  1074. destval = *decode_rl_byte_register(emu);
  1075. }
  1076. (*binop)(emu, destval, srcval);
  1077. }
  1078. static void
  1079. common_binop_word_rm_r(struct x86emu *emu,
  1080. uint16_t (*binop)(struct x86emu *, uint16_t, uint16_t))
  1081. {
  1082. uint32_t destoffset;
  1083. uint16_t destval, *destreg, srcval;
  1084. fetch_decode_modrm(emu);
  1085. srcval = *decode_rh_word_register(emu);
  1086. if (emu->cur_mod != 3) {
  1087. destoffset = decode_rl_address(emu);
  1088. destval = fetch_data_word(emu, destoffset);
  1089. destval = (*binop)(emu, destval, srcval);
  1090. store_data_word(emu, destoffset, destval);
  1091. } else {
  1092. destreg = decode_rl_word_register(emu);
  1093. *destreg = (*binop)(emu, *destreg, srcval);
  1094. }
  1095. }
  1096. static void
  1097. common_binop_byte_r_rm(struct x86emu *emu,
  1098. uint8_t (*binop)(struct x86emu *, uint8_t, uint8_t))
  1099. {
  1100. uint8_t *destreg, srcval;
  1101. uint32_t srcoffset;
  1102. fetch_decode_modrm(emu);
  1103. destreg = decode_rh_byte_register(emu);
  1104. if (emu->cur_mod != 3) {
  1105. srcoffset = decode_rl_address(emu);
  1106. srcval = fetch_data_byte(emu, srcoffset);
  1107. } else {
  1108. srcval = *decode_rl_byte_register(emu);
  1109. }
  1110. *destreg = (*binop)(emu, *destreg, srcval);
  1111. }
  1112. static void
  1113. common_binop_long_rm_r(struct x86emu *emu,
  1114. uint32_t (*binop)(struct x86emu *, uint32_t, uint32_t))
  1115. {
  1116. uint32_t destoffset;
  1117. uint32_t destval, *destreg, srcval;
  1118. fetch_decode_modrm(emu);
  1119. srcval = *decode_rh_long_register(emu);
  1120. if (emu->cur_mod != 3) {
  1121. destoffset = decode_rl_address(emu);
  1122. destval = fetch_data_long(emu, destoffset);
  1123. destval = (*binop)(emu, destval, srcval);
  1124. store_data_long(emu, destoffset, destval);
  1125. } else {
  1126. destreg = decode_rl_long_register(emu);
  1127. *destreg = (*binop)(emu, *destreg, srcval);
  1128. }
  1129. }
  1130. static void
  1131. common_binop_word_long_rm_r(struct x86emu *emu,
  1132. uint16_t (*binop16)(struct x86emu *, uint16_t, uint16_t),
  1133. uint32_t (*binop32)(struct x86emu *, uint32_t, uint32_t))
  1134. {
  1135. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  1136. common_binop_long_rm_r(emu, binop32);
  1137. else
  1138. common_binop_word_rm_r(emu, binop16);
  1139. }
  1140. static void
  1141. common_binop_ns_word_rm_r(struct x86emu *emu,
  1142. void (*binop)(struct x86emu *, uint16_t, uint16_t))
  1143. {
  1144. uint32_t destoffset;
  1145. uint16_t destval, srcval;
  1146. fetch_decode_modrm(emu);
  1147. srcval = *decode_rh_word_register(emu);
  1148. if (emu->cur_mod != 3) {
  1149. destoffset = decode_rl_address(emu);
  1150. destval = fetch_data_word(emu, destoffset);
  1151. } else {
  1152. destval = *decode_rl_word_register(emu);
  1153. }
  1154. (*binop)(emu, destval, srcval);
  1155. }
  1156. static void
  1157. common_binop_ns_long_rm_r(struct x86emu *emu,
  1158. void (*binop)(struct x86emu *, uint32_t, uint32_t))
  1159. {
  1160. uint32_t destoffset;
  1161. uint32_t destval, srcval;
  1162. fetch_decode_modrm(emu);
  1163. srcval = *decode_rh_long_register(emu);
  1164. if (emu->cur_mod != 3) {
  1165. destoffset = decode_rl_address(emu);
  1166. destval = fetch_data_long(emu, destoffset);
  1167. } else {
  1168. destval = *decode_rl_long_register(emu);
  1169. }
  1170. (*binop)(emu, destval, srcval);
  1171. }
  1172. static void
  1173. common_binop_ns_word_long_rm_r(struct x86emu *emu,
  1174. void (*binop16)(struct x86emu *, uint16_t, uint16_t),
  1175. void (*binop32)(struct x86emu *, uint32_t, uint32_t))
  1176. {
  1177. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  1178. common_binop_ns_long_rm_r(emu, binop32);
  1179. else
  1180. common_binop_ns_word_rm_r(emu, binop16);
  1181. }
  1182. static void
  1183. common_binop_long_r_rm(struct x86emu *emu,
  1184. uint32_t (*binop)(struct x86emu *, uint32_t, uint32_t))
  1185. {
  1186. uint32_t srcoffset;
  1187. uint32_t *destreg, srcval;
  1188. fetch_decode_modrm(emu);
  1189. destreg = decode_rh_long_register(emu);
  1190. if (emu->cur_mod != 3) {
  1191. srcoffset = decode_rl_address(emu);
  1192. srcval = fetch_data_long(emu, srcoffset);
  1193. } else {
  1194. srcval = *decode_rl_long_register(emu);
  1195. }
  1196. *destreg = (*binop)(emu, *destreg, srcval);
  1197. }
  1198. static void
  1199. common_binop_word_r_rm(struct x86emu *emu,
  1200. uint16_t (*binop)(struct x86emu *, uint16_t, uint16_t))
  1201. {
  1202. uint32_t srcoffset;
  1203. uint16_t *destreg, srcval;
  1204. fetch_decode_modrm(emu);
  1205. destreg = decode_rh_word_register(emu);
  1206. if (emu->cur_mod != 3) {
  1207. srcoffset = decode_rl_address(emu);
  1208. srcval = fetch_data_word(emu, srcoffset);
  1209. } else {
  1210. srcval = *decode_rl_word_register(emu);
  1211. }
  1212. *destreg = (*binop)(emu, *destreg, srcval);
  1213. }
  1214. static void
  1215. common_binop_word_long_r_rm(struct x86emu *emu,
  1216. uint16_t (*binop16)(struct x86emu *, uint16_t, uint16_t),
  1217. uint32_t (*binop32)(struct x86emu *, uint32_t, uint32_t))
  1218. {
  1219. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  1220. common_binop_long_r_rm(emu, binop32);
  1221. else
  1222. common_binop_word_r_rm(emu, binop16);
  1223. }
  1224. static void
  1225. common_binop_byte_imm(struct x86emu *emu,
  1226. uint8_t (*binop)(struct x86emu *, uint8_t, uint8_t))
  1227. {
  1228. uint8_t srcval;
  1229. srcval = fetch_byte_imm(emu);
  1230. emu->x86.R_AL = (*binop)(emu, emu->x86.R_AL, srcval);
  1231. }
  1232. static void
  1233. common_binop_word_long_imm(struct x86emu *emu,
  1234. uint16_t (*binop16)(struct x86emu *, uint16_t, uint16_t),
  1235. uint32_t (*binop32)(struct x86emu *, uint32_t, uint32_t))
  1236. {
  1237. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  1238. uint32_t srcval;
  1239. srcval = fetch_long_imm(emu);
  1240. emu->x86.R_EAX = (*binop32)(emu, emu->x86.R_EAX, srcval);
  1241. } else {
  1242. uint16_t srcval;
  1243. srcval = fetch_word_imm(emu);
  1244. emu->x86.R_AX = (*binop16)(emu, emu->x86.R_AX, srcval);
  1245. }
  1246. }
  1247. static void
  1248. common_push_word_long(struct x86emu *emu, union x86emu_register *reg)
  1249. {
  1250. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  1251. push_long(emu, reg->I32_reg.e_reg);
  1252. else
  1253. push_word(emu, reg->I16_reg.x_reg);
  1254. }
  1255. static void
  1256. common_pop_word_long(struct x86emu *emu, union x86emu_register *reg)
  1257. {
  1258. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  1259. reg->I32_reg.e_reg = pop_long(emu);
  1260. else
  1261. reg->I16_reg.x_reg = pop_word(emu);
  1262. }
  1263. static void
  1264. common_imul_long_IMM(struct x86emu *emu, int byte_imm)
  1265. {
  1266. uint32_t srcoffset;
  1267. uint32_t *destreg, srcval;
  1268. int32_t imm;
  1269. uint64_t res;
  1270. fetch_decode_modrm(emu);
  1271. destreg = decode_rh_long_register(emu);
  1272. if (emu->cur_mod != 3) {
  1273. srcoffset = decode_rl_address(emu);
  1274. srcval = fetch_data_long(emu, srcoffset);
  1275. } else {
  1276. srcval = *decode_rl_long_register(emu);
  1277. }
  1278. if (byte_imm)
  1279. imm = (int8_t)fetch_byte_imm(emu);
  1280. else
  1281. imm = fetch_long_imm(emu);
  1282. res = (int32_t)srcval * imm;
  1283. if (res > 0xffffffff) {
  1284. SET_FLAG(F_CF);
  1285. SET_FLAG(F_OF);
  1286. } else {
  1287. CLEAR_FLAG(F_CF);
  1288. CLEAR_FLAG(F_OF);
  1289. }
  1290. *destreg = (uint32_t)res;
  1291. }
  1292. static void
  1293. common_imul_word_IMM(struct x86emu *emu, int byte_imm)
  1294. {
  1295. uint32_t srcoffset;
  1296. uint16_t *destreg, srcval;
  1297. int16_t imm;
  1298. uint32_t res;
  1299. fetch_decode_modrm(emu);
  1300. destreg = decode_rh_word_register(emu);
  1301. if (emu->cur_mod != 3) {
  1302. srcoffset = decode_rl_address(emu);
  1303. srcval = fetch_data_word(emu, srcoffset);
  1304. } else {
  1305. srcval = *decode_rl_word_register(emu);
  1306. }
  1307. if (byte_imm)
  1308. imm = (int8_t)fetch_byte_imm(emu);
  1309. else
  1310. imm = fetch_word_imm(emu);
  1311. res = (int16_t)srcval * imm;
  1312. if (res > 0xffff) {
  1313. SET_FLAG(F_CF);
  1314. SET_FLAG(F_OF);
  1315. } else {
  1316. CLEAR_FLAG(F_CF);
  1317. CLEAR_FLAG(F_OF);
  1318. }
  1319. *destreg = (uint16_t) res;
  1320. }
  1321. static void
  1322. common_imul_imm(struct x86emu *emu, int byte_imm)
  1323. {
  1324. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  1325. common_imul_long_IMM(emu, byte_imm);
  1326. else
  1327. common_imul_word_IMM(emu, byte_imm);
  1328. }
  1329. static void
  1330. common_jmp_near(struct x86emu *emu, int cond)
  1331. {
  1332. int8_t offset;
  1333. uint16_t target;
  1334. offset = (int8_t) fetch_byte_imm(emu);
  1335. target = (uint16_t) (emu->x86.R_IP + (int16_t) offset);
  1336. if (cond)
  1337. emu->x86.R_IP = target;
  1338. }
  1339. static void
  1340. common_load_far_pointer(struct x86emu *emu, uint16_t *seg)
  1341. {
  1342. uint16_t *dstreg;
  1343. uint32_t srcoffset;
  1344. fetch_decode_modrm(emu);
  1345. if (emu->cur_mod == 3)
  1346. x86emu_halt_sys(emu);
  1347. dstreg = decode_rh_word_register(emu);
  1348. srcoffset = decode_rl_address(emu);
  1349. *dstreg = fetch_data_word(emu, srcoffset);
  1350. *seg = fetch_data_word(emu, srcoffset + 2);
  1351. }
  1352. /* Implementation */
  1353. /*
  1354. * REMARKS:
  1355. * Handles opcode 0x3a
  1356. */
  1357. static void
  1358. x86emuOp_cmp_byte_R_RM(struct x86emu *emu)
  1359. {
  1360. uint8_t *destreg, srcval;
  1361. fetch_decode_modrm(emu);
  1362. destreg = decode_rh_byte_register(emu);
  1363. srcval = decode_and_fetch_byte(emu);
  1364. cmp_byte(emu, *destreg, srcval);
  1365. }
  1366. /*
  1367. * REMARKS:
  1368. *
  1369. * Handles opcode 0x3b
  1370. */
  1371. static void
  1372. x86emuOp32_cmp_word_R_RM(struct x86emu *emu)
  1373. {
  1374. uint32_t srcval, *destreg;
  1375. fetch_decode_modrm(emu);
  1376. destreg = decode_rh_long_register(emu);
  1377. srcval = decode_and_fetch_long(emu);
  1378. cmp_long(emu, *destreg, srcval);
  1379. }
  1380. static void
  1381. x86emuOp16_cmp_word_R_RM(struct x86emu *emu)
  1382. {
  1383. uint16_t srcval, *destreg;
  1384. fetch_decode_modrm(emu);
  1385. destreg = decode_rh_word_register(emu);
  1386. srcval = decode_and_fetch_word(emu);
  1387. cmp_word(emu, *destreg, srcval);
  1388. }
  1389. static void
  1390. x86emuOp_cmp_word_R_RM(struct x86emu *emu)
  1391. {
  1392. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  1393. x86emuOp32_cmp_word_R_RM(emu);
  1394. else
  1395. x86emuOp16_cmp_word_R_RM(emu);
  1396. }
  1397. /*
  1398. * REMARKS:
  1399. * Handles opcode 0x3c
  1400. */
  1401. static void
  1402. x86emuOp_cmp_byte_AL_IMM(struct x86emu *emu)
  1403. {
  1404. uint8_t srcval;
  1405. srcval = fetch_byte_imm(emu);
  1406. cmp_byte(emu, emu->x86.R_AL, srcval);
  1407. }
  1408. /*
  1409. * REMARKS:
  1410. * Handles opcode 0x3d
  1411. */
  1412. static void
  1413. x86emuOp32_cmp_word_AX_IMM(struct x86emu *emu)
  1414. {
  1415. uint32_t srcval;
  1416. srcval = fetch_long_imm(emu);
  1417. cmp_long(emu, emu->x86.R_EAX, srcval);
  1418. }
  1419. static void
  1420. x86emuOp16_cmp_word_AX_IMM(struct x86emu *emu)
  1421. {
  1422. uint16_t srcval;
  1423. srcval = fetch_word_imm(emu);
  1424. cmp_word(emu, emu->x86.R_AX, srcval);
  1425. }
  1426. static void
  1427. x86emuOp_cmp_word_AX_IMM(struct x86emu *emu)
  1428. {
  1429. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  1430. x86emuOp32_cmp_word_AX_IMM(emu);
  1431. else
  1432. x86emuOp16_cmp_word_AX_IMM(emu);
  1433. }
  1434. /*
  1435. * REMARKS:
  1436. * Handles opcode 0x60
  1437. */
  1438. static void
  1439. x86emuOp_push_all(struct x86emu *emu)
  1440. {
  1441. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  1442. uint32_t old_sp = emu->x86.R_ESP;
  1443. push_long(emu, emu->x86.R_EAX);
  1444. push_long(emu, emu->x86.R_ECX);
  1445. push_long(emu, emu->x86.R_EDX);
  1446. push_long(emu, emu->x86.R_EBX);
  1447. push_long(emu, old_sp);
  1448. push_long(emu, emu->x86.R_EBP);
  1449. push_long(emu, emu->x86.R_ESI);
  1450. push_long(emu, emu->x86.R_EDI);
  1451. } else {
  1452. uint16_t old_sp = emu->x86.R_SP;
  1453. push_word(emu, emu->x86.R_AX);
  1454. push_word(emu, emu->x86.R_CX);
  1455. push_word(emu, emu->x86.R_DX);
  1456. push_word(emu, emu->x86.R_BX);
  1457. push_word(emu, old_sp);
  1458. push_word(emu, emu->x86.R_BP);
  1459. push_word(emu, emu->x86.R_SI);
  1460. push_word(emu, emu->x86.R_DI);
  1461. }
  1462. }
  1463. /*
  1464. * REMARKS:
  1465. * Handles opcode 0x61
  1466. */
  1467. static void
  1468. x86emuOp_pop_all(struct x86emu *emu)
  1469. {
  1470. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  1471. emu->x86.R_EDI = pop_long(emu);
  1472. emu->x86.R_ESI = pop_long(emu);
  1473. emu->x86.R_EBP = pop_long(emu);
  1474. emu->x86.R_ESP += 4; /* skip ESP */
  1475. emu->x86.R_EBX = pop_long(emu);
  1476. emu->x86.R_EDX = pop_long(emu);
  1477. emu->x86.R_ECX = pop_long(emu);
  1478. emu->x86.R_EAX = pop_long(emu);
  1479. } else {
  1480. emu->x86.R_DI = pop_word(emu);
  1481. emu->x86.R_SI = pop_word(emu);
  1482. emu->x86.R_BP = pop_word(emu);
  1483. emu->x86.R_SP += 2;/* skip SP */
  1484. emu->x86.R_BX = pop_word(emu);
  1485. emu->x86.R_DX = pop_word(emu);
  1486. emu->x86.R_CX = pop_word(emu);
  1487. emu->x86.R_AX = pop_word(emu);
  1488. }
  1489. }
  1490. /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
  1491. /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
  1492. /*
  1493. * REMARKS:
  1494. * Handles opcode 0x68
  1495. */
  1496. static void
  1497. x86emuOp_push_word_IMM(struct x86emu *emu)
  1498. {
  1499. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  1500. uint32_t imm;
  1501. imm = fetch_long_imm(emu);
  1502. push_long(emu, imm);
  1503. } else {
  1504. uint16_t imm;
  1505. imm = fetch_word_imm(emu);
  1506. push_word(emu, imm);
  1507. }
  1508. }
  1509. /*
  1510. * REMARKS:
  1511. * Handles opcode 0x6a
  1512. */
  1513. static void
  1514. x86emuOp_push_byte_IMM(struct x86emu *emu)
  1515. {
  1516. int16_t imm;
  1517. imm = (int8_t) fetch_byte_imm(emu);
  1518. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  1519. push_long(emu, (int32_t) imm);
  1520. } else {
  1521. push_word(emu, imm);
  1522. }
  1523. }
  1524. /*
  1525. * REMARKS:
  1526. * Handles opcode 0x6c and 0x6d
  1527. */
  1528. static void
  1529. x86emuOp_ins_word(struct x86emu *emu)
  1530. {
  1531. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  1532. ins(emu, 4);
  1533. } else {
  1534. ins(emu, 2);
  1535. }
  1536. }
  1537. /*
  1538. * REMARKS:
  1539. * Handles opcode 0x6f
  1540. */
  1541. static void
  1542. x86emuOp_outs_word(struct x86emu *emu)
  1543. {
  1544. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  1545. outs(emu, 4);
  1546. } else {
  1547. outs(emu, 2);
  1548. }
  1549. }
  1550. /*
  1551. * REMARKS:
  1552. * Handles opcode 0x7c
  1553. */
  1554. static void
  1555. x86emuOp_jump_near_L(struct x86emu *emu)
  1556. {
  1557. int sf, of;
  1558. sf = ACCESS_FLAG(F_SF) != 0;
  1559. of = ACCESS_FLAG(F_OF) != 0;
  1560. common_jmp_near(emu, sf != of);
  1561. }
  1562. /*
  1563. * REMARKS:
  1564. * Handles opcode 0x7d
  1565. */
  1566. static void
  1567. x86emuOp_jump_near_NL(struct x86emu *emu)
  1568. {
  1569. int sf, of;
  1570. sf = ACCESS_FLAG(F_SF) != 0;
  1571. of = ACCESS_FLAG(F_OF) != 0;
  1572. common_jmp_near(emu, sf == of);
  1573. }
  1574. /*
  1575. * REMARKS:
  1576. * Handles opcode 0x7e
  1577. */
  1578. static void
  1579. x86emuOp_jump_near_LE(struct x86emu *emu)
  1580. {
  1581. int sf, of;
  1582. sf = ACCESS_FLAG(F_SF) != 0;
  1583. of = ACCESS_FLAG(F_OF) != 0;
  1584. common_jmp_near(emu, sf != of || ACCESS_FLAG(F_ZF));
  1585. }
  1586. /*
  1587. * REMARKS:
  1588. * Handles opcode 0x7f
  1589. */
  1590. static void
  1591. x86emuOp_jump_near_NLE(struct x86emu *emu)
  1592. {
  1593. int sf, of;
  1594. sf = ACCESS_FLAG(F_SF) != 0;
  1595. of = ACCESS_FLAG(F_OF) != 0;
  1596. common_jmp_near(emu, sf == of && !ACCESS_FLAG(F_ZF));
  1597. }
  1598. static
  1599. uint8_t(*const opc80_byte_operation[]) (struct x86emu *, uint8_t d, uint8_t s) =
  1600. {
  1601. add_byte, /* 00 */
  1602. or_byte, /* 01 */
  1603. adc_byte, /* 02 */
  1604. sbb_byte, /* 03 */
  1605. and_byte, /* 04 */
  1606. sub_byte, /* 05 */
  1607. xor_byte, /* 06 */
  1608. cmp_byte, /* 07 */
  1609. };
  1610. /*
  1611. * REMARKS:
  1612. * Handles opcode 0x80
  1613. */
  1614. static void
  1615. x86emuOp_opc80_byte_RM_IMM(struct x86emu *emu)
  1616. {
  1617. uint8_t imm, destval;
  1618. /*
  1619. * Weirdo special case instruction format. Part of the opcode
  1620. * held below in "RH". Doubly nested case would result, except
  1621. * that the decoded instruction
  1622. */
  1623. fetch_decode_modrm(emu);
  1624. destval = decode_and_fetch_byte(emu);
  1625. imm = fetch_byte_imm(emu);
  1626. destval = (*opc80_byte_operation[emu->cur_rh]) (emu, destval, imm);
  1627. if (emu->cur_rh != 7)
  1628. write_back_byte(emu, destval);
  1629. }
  1630. static
  1631. uint16_t(* const opc81_word_operation[])
  1632. (struct x86emu *, uint16_t d, uint16_t s) =
  1633. {
  1634. add_word, /* 00 */
  1635. or_word, /* 01 */
  1636. adc_word, /* 02 */
  1637. sbb_word, /* 03 */
  1638. and_word, /* 04 */
  1639. sub_word, /* 05 */
  1640. xor_word, /* 06 */
  1641. cmp_word, /* 07 */
  1642. };
  1643. static
  1644. uint32_t(* const opc81_long_operation[])
  1645. (struct x86emu *, uint32_t d, uint32_t s) =
  1646. {
  1647. add_long, /* 00 */
  1648. or_long, /* 01 */
  1649. adc_long, /* 02 */
  1650. sbb_long, /* 03 */
  1651. and_long, /* 04 */
  1652. sub_long, /* 05 */
  1653. xor_long, /* 06 */
  1654. cmp_long, /* 07 */
  1655. };
  1656. /*
  1657. * REMARKS:
  1658. * Handles opcode 0x81
  1659. */
  1660. static void
  1661. x86emuOp32_opc81_word_RM_IMM(struct x86emu *emu)
  1662. {
  1663. uint32_t destval, imm;
  1664. /*
  1665. * Weirdo special case instruction format. Part of the opcode
  1666. * held below in "RH". Doubly nested case would result, except
  1667. * that the decoded instruction
  1668. */
  1669. fetch_decode_modrm(emu);
  1670. destval = decode_and_fetch_long(emu);
  1671. imm = fetch_long_imm(emu);
  1672. destval = (*opc81_long_operation[emu->cur_rh]) (emu, destval, imm);
  1673. if (emu->cur_rh != 7)
  1674. write_back_long(emu, destval);
  1675. }
  1676. static void
  1677. x86emuOp16_opc81_word_RM_IMM(struct x86emu *emu)
  1678. {
  1679. uint16_t destval, imm;
  1680. /*
  1681. * Weirdo special case instruction format. Part of the opcode
  1682. * held below in "RH". Doubly nested case would result, except
  1683. * that the decoded instruction
  1684. */
  1685. fetch_decode_modrm(emu);
  1686. destval = decode_and_fetch_word(emu);
  1687. imm = fetch_word_imm(emu);
  1688. destval = (*opc81_word_operation[emu->cur_rh]) (emu, destval, imm);
  1689. if (emu->cur_rh != 7)
  1690. write_back_word(emu, destval);
  1691. }
  1692. static void
  1693. x86emuOp_opc81_word_RM_IMM(struct x86emu *emu)
  1694. {
  1695. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  1696. x86emuOp32_opc81_word_RM_IMM(emu);
  1697. else
  1698. x86emuOp16_opc81_word_RM_IMM(emu);
  1699. }
  1700. static
  1701. uint8_t(* const opc82_byte_operation[])
  1702. (struct x86emu *, uint8_t s, uint8_t d) =
  1703. {
  1704. add_byte, /* 00 */
  1705. or_byte, /* 01 *//* YYY UNUSED ???? */
  1706. adc_byte, /* 02 */
  1707. sbb_byte, /* 03 */
  1708. and_byte, /* 04 *//* YYY UNUSED ???? */
  1709. sub_byte, /* 05 */
  1710. xor_byte, /* 06 *//* YYY UNUSED ???? */
  1711. cmp_byte, /* 07 */
  1712. };
  1713. /*
  1714. * REMARKS:
  1715. * Handles opcode 0x82
  1716. */
  1717. static void
  1718. x86emuOp_opc82_byte_RM_IMM(struct x86emu *emu)
  1719. {
  1720. uint8_t imm, destval;
  1721. /*
  1722. * Weirdo special case instruction format. Part of the opcode
  1723. * held below in "RH". Doubly nested case would result, except
  1724. * that the decoded instruction Similar to opcode 81, except that
  1725. * the immediate byte is sign extended to a word length.
  1726. */
  1727. fetch_decode_modrm(emu);
  1728. destval = decode_and_fetch_byte(emu);
  1729. imm = fetch_byte_imm(emu);
  1730. destval = (*opc82_byte_operation[emu->cur_rh]) (emu, destval, imm);
  1731. if (emu->cur_rh != 7)
  1732. write_back_byte(emu, destval);
  1733. }
  1734. static
  1735. uint16_t(* const opc83_word_operation[])
  1736. (struct x86emu *, uint16_t s, uint16_t d) =
  1737. {
  1738. add_word, /* 00 */
  1739. or_word, /* 01 *//* YYY UNUSED ???? */
  1740. adc_word, /* 02 */
  1741. sbb_word, /* 03 */
  1742. and_word, /* 04 *//* YYY UNUSED ???? */
  1743. sub_word, /* 05 */
  1744. xor_word, /* 06 *//* YYY UNUSED ???? */
  1745. cmp_word, /* 07 */
  1746. };
  1747. static
  1748. uint32_t(* const opc83_long_operation[])
  1749. (struct x86emu *, uint32_t s, uint32_t d) =
  1750. {
  1751. add_long, /* 00 */
  1752. or_long, /* 01 *//* YYY UNUSED ???? */
  1753. adc_long, /* 02 */
  1754. sbb_long, /* 03 */
  1755. and_long, /* 04 *//* YYY UNUSED ???? */
  1756. sub_long, /* 05 */
  1757. xor_long, /* 06 *//* YYY UNUSED ???? */
  1758. cmp_long, /* 07 */
  1759. };
  1760. /*
  1761. * REMARKS:
  1762. * Handles opcode 0x83
  1763. */
  1764. static void
  1765. x86emuOp32_opc83_word_RM_IMM(struct x86emu *emu)
  1766. {
  1767. uint32_t destval, imm;
  1768. fetch_decode_modrm(emu);
  1769. destval = decode_and_fetch_long(emu);
  1770. imm = (int8_t) fetch_byte_imm(emu);
  1771. destval = (*opc83_long_operation[emu->cur_rh]) (emu, destval, imm);
  1772. if (emu->cur_rh != 7)
  1773. write_back_long(emu, destval);
  1774. }
  1775. static void
  1776. x86emuOp16_opc83_word_RM_IMM(struct x86emu *emu)
  1777. {
  1778. uint16_t destval, imm;
  1779. fetch_decode_modrm(emu);
  1780. destval = decode_and_fetch_word(emu);
  1781. imm = (int8_t) fetch_byte_imm(emu);
  1782. destval = (*opc83_word_operation[emu->cur_rh]) (emu, destval, imm);
  1783. if (emu->cur_rh != 7)
  1784. write_back_word(emu, destval);
  1785. }
  1786. static void
  1787. x86emuOp_opc83_word_RM_IMM(struct x86emu *emu)
  1788. {
  1789. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  1790. x86emuOp32_opc83_word_RM_IMM(emu);
  1791. else
  1792. x86emuOp16_opc83_word_RM_IMM(emu);
  1793. }
  1794. /*
  1795. * REMARKS:
  1796. * Handles opcode 0x86
  1797. */
  1798. static void
  1799. x86emuOp_xchg_byte_RM_R(struct x86emu *emu)
  1800. {
  1801. uint8_t *srcreg, destval, tmp;
  1802. fetch_decode_modrm(emu);
  1803. destval = decode_and_fetch_byte(emu);
  1804. srcreg = decode_rh_byte_register(emu);
  1805. tmp = destval;
  1806. destval = *srcreg;
  1807. *srcreg = tmp;
  1808. write_back_byte(emu, destval);
  1809. }
  1810. /*
  1811. * REMARKS:
  1812. * Handles opcode 0x87
  1813. */
  1814. static void
  1815. x86emuOp32_xchg_word_RM_R(struct x86emu *emu)
  1816. {
  1817. uint32_t *srcreg, destval, tmp;
  1818. fetch_decode_modrm(emu);
  1819. destval = decode_and_fetch_long(emu);
  1820. srcreg = decode_rh_long_register(emu);
  1821. tmp = destval;
  1822. destval = *srcreg;
  1823. *srcreg = tmp;
  1824. write_back_long(emu, destval);
  1825. }
  1826. static void
  1827. x86emuOp16_xchg_word_RM_R(struct x86emu *emu)
  1828. {
  1829. uint16_t *srcreg, destval, tmp;
  1830. fetch_decode_modrm(emu);
  1831. destval = decode_and_fetch_word(emu);
  1832. srcreg = decode_rh_word_register(emu);
  1833. tmp = destval;
  1834. destval = *srcreg;
  1835. *srcreg = tmp;
  1836. write_back_word(emu, destval);
  1837. }
  1838. static void
  1839. x86emuOp_xchg_word_RM_R(struct x86emu *emu)
  1840. {
  1841. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  1842. x86emuOp32_xchg_word_RM_R(emu);
  1843. else
  1844. x86emuOp16_xchg_word_RM_R(emu);
  1845. }
  1846. /*
  1847. * REMARKS:
  1848. * Handles opcode 0x88
  1849. */
  1850. static void
  1851. x86emuOp_mov_byte_RM_R(struct x86emu *emu)
  1852. {
  1853. uint8_t *destreg, *srcreg;
  1854. uint32_t destoffset;
  1855. fetch_decode_modrm(emu);
  1856. srcreg = decode_rh_byte_register(emu);
  1857. if (emu->cur_mod != 3) {
  1858. destoffset = decode_rl_address(emu);
  1859. store_data_byte(emu, destoffset, *srcreg);
  1860. } else {
  1861. destreg = decode_rl_byte_register(emu);
  1862. *destreg = *srcreg;
  1863. }
  1864. }
  1865. /*
  1866. * REMARKS:
  1867. * Handles opcode 0x89
  1868. */
  1869. static void
  1870. x86emuOp32_mov_word_RM_R(struct x86emu *emu)
  1871. {
  1872. uint32_t destoffset;
  1873. uint32_t *destreg, srcval;
  1874. fetch_decode_modrm(emu);
  1875. srcval = *decode_rh_long_register(emu);
  1876. if (emu->cur_mod != 3) {
  1877. destoffset = decode_rl_address(emu);
  1878. store_data_long(emu, destoffset, srcval);
  1879. } else {
  1880. destreg = decode_rl_long_register(emu);
  1881. *destreg = srcval;
  1882. }
  1883. }
  1884. static void
  1885. x86emuOp16_mov_word_RM_R(struct x86emu *emu)
  1886. {
  1887. uint32_t destoffset;
  1888. uint16_t *destreg, srcval;
  1889. fetch_decode_modrm(emu);
  1890. srcval = *decode_rh_word_register(emu);
  1891. if (emu->cur_mod != 3) {
  1892. destoffset = decode_rl_address(emu);
  1893. store_data_word(emu, destoffset, srcval);
  1894. } else {
  1895. destreg = decode_rl_word_register(emu);
  1896. *destreg = srcval;
  1897. }
  1898. }
  1899. static void
  1900. x86emuOp_mov_word_RM_R(struct x86emu *emu)
  1901. {
  1902. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  1903. x86emuOp32_mov_word_RM_R(emu);
  1904. else
  1905. x86emuOp16_mov_word_RM_R(emu);
  1906. }
  1907. /*
  1908. * REMARKS:
  1909. * Handles opcode 0x8a
  1910. */
  1911. static void
  1912. x86emuOp_mov_byte_R_RM(struct x86emu *emu)
  1913. {
  1914. uint8_t *destreg;
  1915. fetch_decode_modrm(emu);
  1916. destreg = decode_rh_byte_register(emu);
  1917. *destreg = decode_and_fetch_byte(emu);
  1918. }
  1919. /*
  1920. * REMARKS:
  1921. * Handles opcode 0x8b
  1922. */
  1923. static void
  1924. x86emuOp_mov_word_R_RM(struct x86emu *emu)
  1925. {
  1926. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  1927. uint32_t *destreg;
  1928. fetch_decode_modrm(emu);
  1929. destreg = decode_rh_long_register(emu);
  1930. *destreg = decode_and_fetch_long(emu);
  1931. } else {
  1932. uint16_t *destreg;
  1933. fetch_decode_modrm(emu);
  1934. destreg = decode_rh_word_register(emu);
  1935. *destreg = decode_and_fetch_word(emu);
  1936. }
  1937. }
  1938. /*
  1939. * REMARKS:
  1940. * Handles opcode 0x8c
  1941. */
  1942. static void
  1943. x86emuOp_mov_word_RM_SR(struct x86emu *emu)
  1944. {
  1945. uint16_t *destreg, srcval;
  1946. uint32_t destoffset;
  1947. fetch_decode_modrm(emu);
  1948. srcval = *decode_rh_seg_register(emu);
  1949. if (emu->cur_mod != 3) {
  1950. destoffset = decode_rl_address(emu);
  1951. store_data_word(emu, destoffset, srcval);
  1952. } else {
  1953. destreg = decode_rl_word_register(emu);
  1954. *destreg = srcval;
  1955. }
  1956. }
  1957. /*
  1958. * REMARKS:
  1959. * Handles opcode 0x8d
  1960. */
  1961. static void
  1962. x86emuOp_lea_word_R_M(struct x86emu *emu)
  1963. {
  1964. uint32_t destoffset;
  1965. fetch_decode_modrm(emu);
  1966. if (emu->cur_mod == 3)
  1967. x86emu_halt_sys(emu);
  1968. destoffset = decode_rl_address(emu);
  1969. if (emu->x86.mode & SYSMODE_PREFIX_ADDR) {
  1970. uint32_t *srcreg;
  1971. srcreg = decode_rh_long_register(emu);
  1972. *srcreg = (uint32_t) destoffset;
  1973. } else {
  1974. uint16_t *srcreg;
  1975. srcreg = decode_rh_word_register(emu);
  1976. *srcreg = (uint16_t) destoffset;
  1977. }
  1978. }
  1979. /*
  1980. * REMARKS:
  1981. * Handles opcode 0x8e
  1982. */
  1983. static void
  1984. x86emuOp_mov_word_SR_RM(struct x86emu *emu)
  1985. {
  1986. uint16_t *destreg;
  1987. fetch_decode_modrm(emu);
  1988. destreg = decode_rh_seg_register(emu);
  1989. *destreg = decode_and_fetch_word(emu);
  1990. /*
  1991. * Clean up, and reset all the R_xSP pointers to the correct
  1992. * locations. This is about 3x too much overhead (doing all the
  1993. * segreg ptrs when only one is needed, but this instruction
  1994. * *cannot* be that common, and this isn't too much work anyway.
  1995. */
  1996. }
  1997. /*
  1998. * REMARKS:
  1999. * Handles opcode 0x8f
  2000. */
  2001. static void
  2002. x86emuOp32_pop_RM(struct x86emu *emu)
  2003. {
  2004. uint32_t destoffset;
  2005. uint32_t destval, *destreg;
  2006. fetch_decode_modrm(emu);
  2007. if (emu->cur_mod != 3) {
  2008. destoffset = decode_rl_address(emu);
  2009. destval = pop_long(emu);
  2010. store_data_long(emu, destoffset, destval);
  2011. } else {
  2012. destreg = decode_rl_long_register(emu);
  2013. *destreg = pop_long(emu);
  2014. }
  2015. }
  2016. static void
  2017. x86emuOp16_pop_RM(struct x86emu *emu)
  2018. {
  2019. uint32_t destoffset;
  2020. uint16_t destval, *destreg;
  2021. fetch_decode_modrm(emu);
  2022. if (emu->cur_mod != 3) {
  2023. destoffset = decode_rl_address(emu);
  2024. destval = pop_word(emu);
  2025. store_data_word(emu, destoffset, destval);
  2026. } else {
  2027. destreg = decode_rl_word_register(emu);
  2028. *destreg = pop_word(emu);
  2029. }
  2030. }
  2031. static void
  2032. x86emuOp_pop_RM(struct x86emu *emu)
  2033. {
  2034. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  2035. x86emuOp32_pop_RM(emu);
  2036. else
  2037. x86emuOp16_pop_RM(emu);
  2038. }
  2039. /*
  2040. * REMARKS:
  2041. * Handles opcode 0x91
  2042. */
  2043. static void
  2044. x86emuOp_xchg_word_AX_CX(struct x86emu *emu)
  2045. {
  2046. uint32_t tmp;
  2047. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2048. tmp = emu->x86.R_EAX;
  2049. emu->x86.R_EAX = emu->x86.R_ECX;
  2050. emu->x86.R_ECX = tmp;
  2051. } else {
  2052. tmp = emu->x86.R_AX;
  2053. emu->x86.R_AX = emu->x86.R_CX;
  2054. emu->x86.R_CX = (uint16_t) tmp;
  2055. }
  2056. }
  2057. /*
  2058. * REMARKS:
  2059. * Handles opcode 0x92
  2060. */
  2061. static void
  2062. x86emuOp_xchg_word_AX_DX(struct x86emu *emu)
  2063. {
  2064. uint32_t tmp;
  2065. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2066. tmp = emu->x86.R_EAX;
  2067. emu->x86.R_EAX = emu->x86.R_EDX;
  2068. emu->x86.R_EDX = tmp;
  2069. } else {
  2070. tmp = emu->x86.R_AX;
  2071. emu->x86.R_AX = emu->x86.R_DX;
  2072. emu->x86.R_DX = (uint16_t) tmp;
  2073. }
  2074. }
  2075. /*
  2076. * REMARKS:
  2077. * Handles opcode 0x93
  2078. */
  2079. static void
  2080. x86emuOp_xchg_word_AX_BX(struct x86emu *emu)
  2081. {
  2082. uint32_t tmp;
  2083. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2084. tmp = emu->x86.R_EAX;
  2085. emu->x86.R_EAX = emu->x86.R_EBX;
  2086. emu->x86.R_EBX = tmp;
  2087. } else {
  2088. tmp = emu->x86.R_AX;
  2089. emu->x86.R_AX = emu->x86.R_BX;
  2090. emu->x86.R_BX = (uint16_t) tmp;
  2091. }
  2092. }
  2093. /*
  2094. * REMARKS:
  2095. * Handles opcode 0x94
  2096. */
  2097. static void
  2098. x86emuOp_xchg_word_AX_SP(struct x86emu *emu)
  2099. {
  2100. uint32_t tmp;
  2101. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2102. tmp = emu->x86.R_EAX;
  2103. emu->x86.R_EAX = emu->x86.R_ESP;
  2104. emu->x86.R_ESP = tmp;
  2105. } else {
  2106. tmp = emu->x86.R_AX;
  2107. emu->x86.R_AX = emu->x86.R_SP;
  2108. emu->x86.R_SP = (uint16_t) tmp;
  2109. }
  2110. }
  2111. /*
  2112. * REMARKS:
  2113. * Handles opcode 0x95
  2114. */
  2115. static void
  2116. x86emuOp_xchg_word_AX_BP(struct x86emu *emu)
  2117. {
  2118. uint32_t tmp;
  2119. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2120. tmp = emu->x86.R_EAX;
  2121. emu->x86.R_EAX = emu->x86.R_EBP;
  2122. emu->x86.R_EBP = tmp;
  2123. } else {
  2124. tmp = emu->x86.R_AX;
  2125. emu->x86.R_AX = emu->x86.R_BP;
  2126. emu->x86.R_BP = (uint16_t) tmp;
  2127. }
  2128. }
  2129. /*
  2130. * REMARKS:
  2131. * Handles opcode 0x96
  2132. */
  2133. static void
  2134. x86emuOp_xchg_word_AX_SI(struct x86emu *emu)
  2135. {
  2136. uint32_t tmp;
  2137. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2138. tmp = emu->x86.R_EAX;
  2139. emu->x86.R_EAX = emu->x86.R_ESI;
  2140. emu->x86.R_ESI = tmp;
  2141. } else {
  2142. tmp = emu->x86.R_AX;
  2143. emu->x86.R_AX = emu->x86.R_SI;
  2144. emu->x86.R_SI = (uint16_t) tmp;
  2145. }
  2146. }
  2147. /*
  2148. * REMARKS:
  2149. * Handles opcode 0x97
  2150. */
  2151. static void
  2152. x86emuOp_xchg_word_AX_DI(struct x86emu *emu)
  2153. {
  2154. uint32_t tmp;
  2155. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2156. tmp = emu->x86.R_EAX;
  2157. emu->x86.R_EAX = emu->x86.R_EDI;
  2158. emu->x86.R_EDI = tmp;
  2159. } else {
  2160. tmp = emu->x86.R_AX;
  2161. emu->x86.R_AX = emu->x86.R_DI;
  2162. emu->x86.R_DI = (uint16_t) tmp;
  2163. }
  2164. }
  2165. /*
  2166. * REMARKS:
  2167. * Handles opcode 0x98
  2168. */
  2169. static void
  2170. x86emuOp_cbw(struct x86emu *emu)
  2171. {
  2172. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2173. if (emu->x86.R_AX & 0x8000) {
  2174. emu->x86.R_EAX |= 0xffff0000;
  2175. } else {
  2176. emu->x86.R_EAX &= 0x0000ffff;
  2177. }
  2178. } else {
  2179. if (emu->x86.R_AL & 0x80) {
  2180. emu->x86.R_AH = 0xff;
  2181. } else {
  2182. emu->x86.R_AH = 0x0;
  2183. }
  2184. }
  2185. }
  2186. /*
  2187. * REMARKS:
  2188. * Handles opcode 0x99
  2189. */
  2190. static void
  2191. x86emuOp_cwd(struct x86emu *emu)
  2192. {
  2193. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2194. if (emu->x86.R_EAX & 0x80000000) {
  2195. emu->x86.R_EDX = 0xffffffff;
  2196. } else {
  2197. emu->x86.R_EDX = 0x0;
  2198. }
  2199. } else {
  2200. if (emu->x86.R_AX & 0x8000) {
  2201. emu->x86.R_DX = 0xffff;
  2202. } else {
  2203. emu->x86.R_DX = 0x0;
  2204. }
  2205. }
  2206. }
  2207. /*
  2208. * REMARKS:
  2209. * Handles opcode 0x9a
  2210. */
  2211. static void
  2212. x86emuOp_call_far_IMM(struct x86emu *emu)
  2213. {
  2214. uint16_t farseg, faroff;
  2215. faroff = fetch_word_imm(emu);
  2216. farseg = fetch_word_imm(emu);
  2217. /* XXX
  2218. *
  2219. * Hooked interrupt vectors calling into our "BIOS" will cause problems
  2220. * unless all intersegment stuff is checked for BIOS access. Check
  2221. * needed here. For moment, let it alone. */
  2222. push_word(emu, emu->x86.R_CS);
  2223. emu->x86.R_CS = farseg;
  2224. push_word(emu, emu->x86.R_IP);
  2225. emu->x86.R_IP = faroff;
  2226. }
  2227. /*
  2228. * REMARKS:
  2229. * Handles opcode 0x9c
  2230. */
  2231. static void
  2232. x86emuOp_pushf_word(struct x86emu *emu)
  2233. {
  2234. uint32_t flags;
  2235. /* clear out *all* bits not representing flags, and turn on real bits */
  2236. flags = (emu->x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
  2237. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2238. push_long(emu, flags);
  2239. } else {
  2240. push_word(emu, (uint16_t) flags);
  2241. }
  2242. }
  2243. /*
  2244. * REMARKS:
  2245. * Handles opcode 0x9d
  2246. */
  2247. static void
  2248. x86emuOp_popf_word(struct x86emu *emu)
  2249. {
  2250. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2251. emu->x86.R_EFLG = pop_long(emu);
  2252. } else {
  2253. emu->x86.R_FLG = pop_word(emu);
  2254. }
  2255. }
  2256. /*
  2257. * REMARKS:
  2258. * Handles opcode 0x9e
  2259. */
  2260. static void
  2261. x86emuOp_sahf(struct x86emu *emu)
  2262. {
  2263. /* clear the lower bits of the flag register */
  2264. emu->x86.R_FLG &= 0xffffff00;
  2265. /* or in the AH register into the flags register */
  2266. emu->x86.R_FLG |= emu->x86.R_AH;
  2267. }
  2268. /*
  2269. * REMARKS:
  2270. * Handles opcode 0x9f
  2271. */
  2272. static void
  2273. x86emuOp_lahf(struct x86emu *emu)
  2274. {
  2275. emu->x86.R_AH = (uint8_t) (emu->x86.R_FLG & 0xff);
  2276. /* undocumented TC++ behavior??? Nope. It's documented, but you have
  2277. * too look real hard to notice it. */
  2278. emu->x86.R_AH |= 0x2;
  2279. }
  2280. /*
  2281. * REMARKS:
  2282. * Handles opcode 0xa0
  2283. */
  2284. static void
  2285. x86emuOp_mov_AL_M_IMM(struct x86emu *emu)
  2286. {
  2287. uint16_t offset;
  2288. offset = fetch_word_imm(emu);
  2289. emu->x86.R_AL = fetch_data_byte(emu, offset);
  2290. }
  2291. /*
  2292. * REMARKS:
  2293. * Handles opcode 0xa1
  2294. */
  2295. static void
  2296. x86emuOp_mov_AX_M_IMM(struct x86emu *emu)
  2297. {
  2298. uint16_t offset;
  2299. offset = fetch_word_imm(emu);
  2300. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2301. emu->x86.R_EAX = fetch_data_long(emu, offset);
  2302. } else {
  2303. emu->x86.R_AX = fetch_data_word(emu, offset);
  2304. }
  2305. }
  2306. /*
  2307. * REMARKS:
  2308. * Handles opcode 0xa2
  2309. */
  2310. static void
  2311. x86emuOp_mov_M_AL_IMM(struct x86emu *emu)
  2312. {
  2313. uint16_t offset;
  2314. offset = fetch_word_imm(emu);
  2315. store_data_byte(emu, offset, emu->x86.R_AL);
  2316. }
  2317. /*
  2318. * REMARKS:
  2319. * Handles opcode 0xa3
  2320. */
  2321. static void
  2322. x86emuOp_mov_M_AX_IMM(struct x86emu *emu)
  2323. {
  2324. uint16_t offset;
  2325. offset = fetch_word_imm(emu);
  2326. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2327. store_data_long(emu, offset, emu->x86.R_EAX);
  2328. } else {
  2329. store_data_word(emu, offset, emu->x86.R_AX);
  2330. }
  2331. }
  2332. /*
  2333. * REMARKS:
  2334. * Handles opcode 0xa4
  2335. */
  2336. static void
  2337. x86emuOp_movs_byte(struct x86emu *emu)
  2338. {
  2339. uint8_t val;
  2340. uint32_t count;
  2341. int inc;
  2342. if (ACCESS_FLAG(F_DF)) /* down */
  2343. inc = -1;
  2344. else
  2345. inc = 1;
  2346. count = 1;
  2347. if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  2348. /* dont care whether REPE or REPNE */
  2349. /* move them until CX is ZERO. */
  2350. count = emu->x86.R_CX;
  2351. emu->x86.R_CX = 0;
  2352. emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  2353. }
  2354. while (count--) {
  2355. val = fetch_data_byte(emu, emu->x86.R_SI);
  2356. store_byte(emu, emu->x86.R_ES, emu->x86.R_DI, val);
  2357. emu->x86.R_SI += inc;
  2358. emu->x86.R_DI += inc;
  2359. }
  2360. }
  2361. /*
  2362. * REMARKS:
  2363. * Handles opcode 0xa5
  2364. */
  2365. static void
  2366. x86emuOp_movs_word(struct x86emu *emu)
  2367. {
  2368. uint32_t val;
  2369. int inc;
  2370. uint32_t count;
  2371. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  2372. inc = 4;
  2373. else
  2374. inc = 2;
  2375. if (ACCESS_FLAG(F_DF)) /* down */
  2376. inc = -inc;
  2377. count = 1;
  2378. if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  2379. /* dont care whether REPE or REPNE */
  2380. /* move them until CX is ZERO. */
  2381. count = emu->x86.R_CX;
  2382. emu->x86.R_CX = 0;
  2383. emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  2384. }
  2385. while (count--) {
  2386. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2387. val = fetch_data_long(emu, emu->x86.R_SI);
  2388. store_long(emu, emu->x86.R_ES, emu->x86.R_DI, val);
  2389. } else {
  2390. val = fetch_data_word(emu, emu->x86.R_SI);
  2391. store_word(emu, emu->x86.R_ES, emu->x86.R_DI,
  2392. (uint16_t) val);
  2393. }
  2394. emu->x86.R_SI += inc;
  2395. emu->x86.R_DI += inc;
  2396. }
  2397. }
  2398. /*
  2399. * REMARKS:
  2400. * Handles opcode 0xa6
  2401. */
  2402. static void
  2403. x86emuOp_cmps_byte(struct x86emu *emu)
  2404. {
  2405. int8_t val1, val2;
  2406. int inc;
  2407. if (ACCESS_FLAG(F_DF)) /* down */
  2408. inc = -1;
  2409. else
  2410. inc = 1;
  2411. if (emu->x86.mode & SYSMODE_PREFIX_REPE) {
  2412. /* REPE */
  2413. /* move them until CX is ZERO. */
  2414. while (emu->x86.R_CX != 0) {
  2415. val1 = fetch_data_byte(emu, emu->x86.R_SI);
  2416. val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
  2417. cmp_byte(emu, val1, val2);
  2418. emu->x86.R_CX -= 1;
  2419. emu->x86.R_SI += inc;
  2420. emu->x86.R_DI += inc;
  2421. if (ACCESS_FLAG(F_ZF) == 0)
  2422. break;
  2423. }
  2424. emu->x86.mode &= ~SYSMODE_PREFIX_REPE;
  2425. } else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) {
  2426. /* REPNE */
  2427. /* move them until CX is ZERO. */
  2428. while (emu->x86.R_CX != 0) {
  2429. val1 = fetch_data_byte(emu, emu->x86.R_SI);
  2430. val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
  2431. cmp_byte(emu, val1, val2);
  2432. emu->x86.R_CX -= 1;
  2433. emu->x86.R_SI += inc;
  2434. emu->x86.R_DI += inc;
  2435. if (ACCESS_FLAG(F_ZF))
  2436. break; /* zero flag set means equal */
  2437. }
  2438. emu->x86.mode &= ~SYSMODE_PREFIX_REPNE;
  2439. } else {
  2440. val1 = fetch_data_byte(emu, emu->x86.R_SI);
  2441. val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
  2442. cmp_byte(emu, val1, val2);
  2443. emu->x86.R_SI += inc;
  2444. emu->x86.R_DI += inc;
  2445. }
  2446. }
  2447. /*
  2448. * REMARKS:
  2449. * Handles opcode 0xa7
  2450. */
  2451. static void
  2452. x86emuOp_cmps_word(struct x86emu *emu)
  2453. {
  2454. uint32_t val1, val2;
  2455. int inc;
  2456. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2457. if (ACCESS_FLAG(F_DF)) /* down */
  2458. inc = -4;
  2459. else
  2460. inc = 4;
  2461. } else {
  2462. if (ACCESS_FLAG(F_DF)) /* down */
  2463. inc = -2;
  2464. else
  2465. inc = 2;
  2466. }
  2467. if (emu->x86.mode & SYSMODE_PREFIX_REPE) {
  2468. /* REPE */
  2469. /* move them until CX is ZERO. */
  2470. while (emu->x86.R_CX != 0) {
  2471. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2472. val1 = fetch_data_long(emu, emu->x86.R_SI);
  2473. val2 = fetch_long(emu, emu->x86.R_ES,
  2474. emu->x86.R_DI);
  2475. cmp_long(emu, val1, val2);
  2476. } else {
  2477. val1 = fetch_data_word(emu, emu->x86.R_SI);
  2478. val2 = fetch_word(emu, emu->x86.R_ES,
  2479. emu->x86.R_DI);
  2480. cmp_word(emu, (uint16_t) val1, (uint16_t) val2);
  2481. }
  2482. emu->x86.R_CX -= 1;
  2483. emu->x86.R_SI += inc;
  2484. emu->x86.R_DI += inc;
  2485. if (ACCESS_FLAG(F_ZF) == 0)
  2486. break;
  2487. }
  2488. emu->x86.mode &= ~SYSMODE_PREFIX_REPE;
  2489. } else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) {
  2490. /* REPNE */
  2491. /* move them until CX is ZERO. */
  2492. while (emu->x86.R_CX != 0) {
  2493. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2494. val1 = fetch_data_long(emu, emu->x86.R_SI);
  2495. val2 = fetch_long(emu, emu->x86.R_ES,
  2496. emu->x86.R_DI);
  2497. cmp_long(emu, val1, val2);
  2498. } else {
  2499. val1 = fetch_data_word(emu, emu->x86.R_SI);
  2500. val2 = fetch_word(emu, emu->x86.R_ES,
  2501. emu->x86.R_DI);
  2502. cmp_word(emu, (uint16_t) val1, (uint16_t) val2);
  2503. }
  2504. emu->x86.R_CX -= 1;
  2505. emu->x86.R_SI += inc;
  2506. emu->x86.R_DI += inc;
  2507. if (ACCESS_FLAG(F_ZF))
  2508. break; /* zero flag set means equal */
  2509. }
  2510. emu->x86.mode &= ~SYSMODE_PREFIX_REPNE;
  2511. } else {
  2512. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2513. val1 = fetch_data_long(emu, emu->x86.R_SI);
  2514. val2 = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
  2515. cmp_long(emu, val1, val2);
  2516. } else {
  2517. val1 = fetch_data_word(emu, emu->x86.R_SI);
  2518. val2 = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
  2519. cmp_word(emu, (uint16_t) val1, (uint16_t) val2);
  2520. }
  2521. emu->x86.R_SI += inc;
  2522. emu->x86.R_DI += inc;
  2523. }
  2524. }
  2525. /*
  2526. * REMARKS:
  2527. * Handles opcode 0xa9
  2528. */
  2529. static void
  2530. x86emuOp_test_AX_IMM(struct x86emu *emu)
  2531. {
  2532. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2533. test_long(emu, emu->x86.R_EAX, fetch_long_imm(emu));
  2534. } else {
  2535. test_word(emu, emu->x86.R_AX, fetch_word_imm(emu));
  2536. }
  2537. }
  2538. /*
  2539. * REMARKS:
  2540. * Handles opcode 0xaa
  2541. */
  2542. static void
  2543. x86emuOp_stos_byte(struct x86emu *emu)
  2544. {
  2545. int inc;
  2546. if (ACCESS_FLAG(F_DF)) /* down */
  2547. inc = -1;
  2548. else
  2549. inc = 1;
  2550. if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  2551. /* dont care whether REPE or REPNE */
  2552. /* move them until CX is ZERO. */
  2553. while (emu->x86.R_CX != 0) {
  2554. store_byte(emu, emu->x86.R_ES, emu->x86.R_DI,
  2555. emu->x86.R_AL);
  2556. emu->x86.R_CX -= 1;
  2557. emu->x86.R_DI += inc;
  2558. }
  2559. emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  2560. } else {
  2561. store_byte(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_AL);
  2562. emu->x86.R_DI += inc;
  2563. }
  2564. }
  2565. /*
  2566. * REMARKS:
  2567. * Handles opcode 0xab
  2568. */
  2569. static void
  2570. x86emuOp_stos_word(struct x86emu *emu)
  2571. {
  2572. int inc;
  2573. uint32_t count;
  2574. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  2575. inc = 4;
  2576. else
  2577. inc = 2;
  2578. if (ACCESS_FLAG(F_DF)) /* down */
  2579. inc = -inc;
  2580. count = 1;
  2581. if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  2582. /* dont care whether REPE or REPNE */
  2583. /* move them until CX is ZERO. */
  2584. count = emu->x86.R_CX;
  2585. emu->x86.R_CX = 0;
  2586. emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  2587. }
  2588. while (count--) {
  2589. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2590. store_long(emu, emu->x86.R_ES, emu->x86.R_DI,
  2591. emu->x86.R_EAX);
  2592. } else {
  2593. store_word(emu, emu->x86.R_ES, emu->x86.R_DI,
  2594. emu->x86.R_AX);
  2595. }
  2596. emu->x86.R_DI += inc;
  2597. }
  2598. }
  2599. /*
  2600. * REMARKS:
  2601. * Handles opcode 0xac
  2602. */
  2603. static void
  2604. x86emuOp_lods_byte(struct x86emu *emu)
  2605. {
  2606. int inc;
  2607. if (ACCESS_FLAG(F_DF)) /* down */
  2608. inc = -1;
  2609. else
  2610. inc = 1;
  2611. if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  2612. /* dont care whether REPE or REPNE */
  2613. /* move them until CX is ZERO. */
  2614. while (emu->x86.R_CX != 0) {
  2615. emu->x86.R_AL = fetch_data_byte(emu, emu->x86.R_SI);
  2616. emu->x86.R_CX -= 1;
  2617. emu->x86.R_SI += inc;
  2618. }
  2619. emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  2620. } else {
  2621. emu->x86.R_AL = fetch_data_byte(emu, emu->x86.R_SI);
  2622. emu->x86.R_SI += inc;
  2623. }
  2624. }
  2625. /*
  2626. * REMARKS:
  2627. * Handles opcode 0xad
  2628. */
  2629. static void
  2630. x86emuOp_lods_word(struct x86emu *emu)
  2631. {
  2632. int inc;
  2633. uint32_t count;
  2634. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  2635. inc = 4;
  2636. else
  2637. inc = 2;
  2638. if (ACCESS_FLAG(F_DF)) /* down */
  2639. inc = -inc;
  2640. count = 1;
  2641. if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  2642. /* dont care whether REPE or REPNE */
  2643. /* move them until CX is ZERO. */
  2644. count = emu->x86.R_CX;
  2645. emu->x86.R_CX = 0;
  2646. emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  2647. }
  2648. while (count--) {
  2649. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2650. emu->x86.R_EAX = fetch_data_long(emu, emu->x86.R_SI);
  2651. } else {
  2652. emu->x86.R_AX = fetch_data_word(emu, emu->x86.R_SI);
  2653. }
  2654. emu->x86.R_SI += inc;
  2655. }
  2656. }
  2657. /*
  2658. * REMARKS:
  2659. * Handles opcode 0xae
  2660. */
  2661. static void
  2662. x86emuOp_scas_byte(struct x86emu *emu)
  2663. {
  2664. int8_t val2;
  2665. int inc;
  2666. if (ACCESS_FLAG(F_DF)) /* down */
  2667. inc = -1;
  2668. else
  2669. inc = 1;
  2670. if (emu->x86.mode & SYSMODE_PREFIX_REPE) {
  2671. /* REPE */
  2672. /* move them until CX is ZERO. */
  2673. while (emu->x86.R_CX != 0) {
  2674. val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
  2675. cmp_byte(emu, emu->x86.R_AL, val2);
  2676. emu->x86.R_CX -= 1;
  2677. emu->x86.R_DI += inc;
  2678. if (ACCESS_FLAG(F_ZF) == 0)
  2679. break;
  2680. }
  2681. emu->x86.mode &= ~SYSMODE_PREFIX_REPE;
  2682. } else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) {
  2683. /* REPNE */
  2684. /* move them until CX is ZERO. */
  2685. while (emu->x86.R_CX != 0) {
  2686. val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
  2687. cmp_byte(emu, emu->x86.R_AL, val2);
  2688. emu->x86.R_CX -= 1;
  2689. emu->x86.R_DI += inc;
  2690. if (ACCESS_FLAG(F_ZF))
  2691. break; /* zero flag set means equal */
  2692. }
  2693. emu->x86.mode &= ~SYSMODE_PREFIX_REPNE;
  2694. } else {
  2695. val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
  2696. cmp_byte(emu, emu->x86.R_AL, val2);
  2697. emu->x86.R_DI += inc;
  2698. }
  2699. }
  2700. /*
  2701. * REMARKS:
  2702. * Handles opcode 0xaf
  2703. */
  2704. static void
  2705. x86emuOp_scas_word(struct x86emu *emu)
  2706. {
  2707. int inc;
  2708. uint32_t val;
  2709. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  2710. inc = 4;
  2711. else
  2712. inc = 2;
  2713. if (ACCESS_FLAG(F_DF)) /* down */
  2714. inc = -inc;
  2715. if (emu->x86.mode & SYSMODE_PREFIX_REPE) {
  2716. /* REPE */
  2717. /* move them until CX is ZERO. */
  2718. while (emu->x86.R_CX != 0) {
  2719. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2720. val = fetch_long(emu, emu->x86.R_ES,
  2721. emu->x86.R_DI);
  2722. cmp_long(emu, emu->x86.R_EAX, val);
  2723. } else {
  2724. val = fetch_word(emu, emu->x86.R_ES,
  2725. emu->x86.R_DI);
  2726. cmp_word(emu, emu->x86.R_AX, (uint16_t) val);
  2727. }
  2728. emu->x86.R_CX -= 1;
  2729. emu->x86.R_DI += inc;
  2730. if (ACCESS_FLAG(F_ZF) == 0)
  2731. break;
  2732. }
  2733. emu->x86.mode &= ~SYSMODE_PREFIX_REPE;
  2734. } else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) {
  2735. /* REPNE */
  2736. /* move them until CX is ZERO. */
  2737. while (emu->x86.R_CX != 0) {
  2738. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2739. val = fetch_long(emu, emu->x86.R_ES,
  2740. emu->x86.R_DI);
  2741. cmp_long(emu, emu->x86.R_EAX, val);
  2742. } else {
  2743. val = fetch_word(emu, emu->x86.R_ES,
  2744. emu->x86.R_DI);
  2745. cmp_word(emu, emu->x86.R_AX, (uint16_t) val);
  2746. }
  2747. emu->x86.R_CX -= 1;
  2748. emu->x86.R_DI += inc;
  2749. if (ACCESS_FLAG(F_ZF))
  2750. break; /* zero flag set means equal */
  2751. }
  2752. emu->x86.mode &= ~SYSMODE_PREFIX_REPNE;
  2753. } else {
  2754. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2755. val = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
  2756. cmp_long(emu, emu->x86.R_EAX, val);
  2757. } else {
  2758. val = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
  2759. cmp_word(emu, emu->x86.R_AX, (uint16_t) val);
  2760. }
  2761. emu->x86.R_DI += inc;
  2762. }
  2763. }
  2764. /*
  2765. * REMARKS:
  2766. * Handles opcode 0xb8
  2767. */
  2768. static void
  2769. x86emuOp_mov_word_AX_IMM(struct x86emu *emu)
  2770. {
  2771. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  2772. emu->x86.R_EAX = fetch_long_imm(emu);
  2773. else
  2774. emu->x86.R_AX = fetch_word_imm(emu);
  2775. }
  2776. /*
  2777. * REMARKS:
  2778. * Handles opcode 0xb9
  2779. */
  2780. static void
  2781. x86emuOp_mov_word_CX_IMM(struct x86emu *emu)
  2782. {
  2783. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  2784. emu->x86.R_ECX = fetch_long_imm(emu);
  2785. else
  2786. emu->x86.R_CX = fetch_word_imm(emu);
  2787. }
  2788. /*
  2789. * REMARKS:
  2790. * Handles opcode 0xba
  2791. */
  2792. static void
  2793. x86emuOp_mov_word_DX_IMM(struct x86emu *emu)
  2794. {
  2795. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  2796. emu->x86.R_EDX = fetch_long_imm(emu);
  2797. else
  2798. emu->x86.R_DX = fetch_word_imm(emu);
  2799. }
  2800. /*
  2801. * REMARKS:
  2802. * Handles opcode 0xbb
  2803. */
  2804. static void
  2805. x86emuOp_mov_word_BX_IMM(struct x86emu *emu)
  2806. {
  2807. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  2808. emu->x86.R_EBX = fetch_long_imm(emu);
  2809. else
  2810. emu->x86.R_BX = fetch_word_imm(emu);
  2811. }
  2812. /*
  2813. * REMARKS:
  2814. * Handles opcode 0xbc
  2815. */
  2816. static void
  2817. x86emuOp_mov_word_SP_IMM(struct x86emu *emu)
  2818. {
  2819. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  2820. emu->x86.R_ESP = fetch_long_imm(emu);
  2821. else
  2822. emu->x86.R_SP = fetch_word_imm(emu);
  2823. }
  2824. /*
  2825. * REMARKS:
  2826. * Handles opcode 0xbd
  2827. */
  2828. static void
  2829. x86emuOp_mov_word_BP_IMM(struct x86emu *emu)
  2830. {
  2831. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  2832. emu->x86.R_EBP = fetch_long_imm(emu);
  2833. else
  2834. emu->x86.R_BP = fetch_word_imm(emu);
  2835. }
  2836. /*
  2837. * REMARKS:
  2838. * Handles opcode 0xbe
  2839. */
  2840. static void
  2841. x86emuOp_mov_word_SI_IMM(struct x86emu *emu)
  2842. {
  2843. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  2844. emu->x86.R_ESI = fetch_long_imm(emu);
  2845. else
  2846. emu->x86.R_SI = fetch_word_imm(emu);
  2847. }
  2848. /*
  2849. * REMARKS:
  2850. * Handles opcode 0xbf
  2851. */
  2852. static void
  2853. x86emuOp_mov_word_DI_IMM(struct x86emu *emu)
  2854. {
  2855. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  2856. emu->x86.R_EDI = fetch_long_imm(emu);
  2857. else
  2858. emu->x86.R_DI = fetch_word_imm(emu);
  2859. }
  2860. /* used by opcodes c0, d0, and d2. */
  2861. static
  2862. uint8_t(* const opcD0_byte_operation[])
  2863. (struct x86emu *, uint8_t d, uint8_t s) =
  2864. {
  2865. rol_byte,
  2866. ror_byte,
  2867. rcl_byte,
  2868. rcr_byte,
  2869. shl_byte,
  2870. shr_byte,
  2871. shl_byte, /* sal_byte === shl_byte by definition */
  2872. sar_byte,
  2873. };
  2874. /*
  2875. * REMARKS:
  2876. * Handles opcode 0xc0
  2877. */
  2878. static void
  2879. x86emuOp_opcC0_byte_RM_MEM(struct x86emu *emu)
  2880. {
  2881. uint8_t destval, amt;
  2882. /*
  2883. * Yet another weirdo special case instruction format. Part of
  2884. * the opcode held below in "RH". Doubly nested case would
  2885. * result, except that the decoded instruction
  2886. */
  2887. fetch_decode_modrm(emu);
  2888. /* know operation, decode the mod byte to find the addressing mode. */
  2889. destval = decode_and_fetch_byte_imm8(emu, &amt);
  2890. destval = (*opcD0_byte_operation[emu->cur_rh]) (emu, destval, amt);
  2891. write_back_byte(emu, destval);
  2892. }
  2893. /* used by opcodes c1, d1, and d3. */
  2894. static
  2895. uint16_t(* const opcD1_word_operation[])
  2896. (struct x86emu *, uint16_t s, uint8_t d) =
  2897. {
  2898. rol_word,
  2899. ror_word,
  2900. rcl_word,
  2901. rcr_word,
  2902. shl_word,
  2903. shr_word,
  2904. shl_word, /* sal_byte === shl_byte by definition */
  2905. sar_word,
  2906. };
  2907. /* used by opcodes c1, d1, and d3. */
  2908. static
  2909. uint32_t(* const opcD1_long_operation[])
  2910. (struct x86emu *, uint32_t s, uint8_t d) =
  2911. {
  2912. rol_long,
  2913. ror_long,
  2914. rcl_long,
  2915. rcr_long,
  2916. shl_long,
  2917. shr_long,
  2918. shl_long, /* sal_byte === shl_byte by definition */
  2919. sar_long,
  2920. };
  2921. /*
  2922. * REMARKS:
  2923. * Handles opcode 0xc1
  2924. */
  2925. static void
  2926. x86emuOp_opcC1_word_RM_MEM(struct x86emu *emu)
  2927. {
  2928. uint8_t amt;
  2929. /*
  2930. * Yet another weirdo special case instruction format. Part of
  2931. * the opcode held below in "RH". Doubly nested case would
  2932. * result, except that the decoded instruction
  2933. */
  2934. fetch_decode_modrm(emu);
  2935. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  2936. uint32_t destval;
  2937. destval = decode_and_fetch_long_imm8(emu, &amt);
  2938. destval = (*opcD1_long_operation[emu->cur_rh])
  2939. (emu, destval, amt);
  2940. write_back_long(emu, destval);
  2941. } else {
  2942. uint16_t destval;
  2943. destval = decode_and_fetch_word_imm8(emu, &amt);
  2944. destval = (*opcD1_word_operation[emu->cur_rh])
  2945. (emu, destval, amt);
  2946. write_back_word(emu, destval);
  2947. }
  2948. }
  2949. /*
  2950. * REMARKS:
  2951. * Handles opcode 0xc2
  2952. */
  2953. static void
  2954. x86emuOp_ret_near_IMM(struct x86emu *emu)
  2955. {
  2956. uint16_t imm;
  2957. imm = fetch_word_imm(emu);
  2958. emu->x86.R_IP = pop_word(emu);
  2959. emu->x86.R_SP += imm;
  2960. }
  2961. /*
  2962. * REMARKS:
  2963. * Handles opcode 0xc6
  2964. */
  2965. static void
  2966. x86emuOp_mov_byte_RM_IMM(struct x86emu *emu)
  2967. {
  2968. uint8_t *destreg;
  2969. uint32_t destoffset;
  2970. uint8_t imm;
  2971. fetch_decode_modrm(emu);
  2972. if (emu->cur_rh != 0)
  2973. x86emu_halt_sys(emu);
  2974. if (emu->cur_mod != 3) {
  2975. destoffset = decode_rl_address(emu);
  2976. imm = fetch_byte_imm(emu);
  2977. store_data_byte(emu, destoffset, imm);
  2978. } else {
  2979. destreg = decode_rl_byte_register(emu);
  2980. imm = fetch_byte_imm(emu);
  2981. *destreg = imm;
  2982. }
  2983. }
  2984. /*
  2985. * REMARKS:
  2986. * Handles opcode 0xc7
  2987. */
  2988. static void
  2989. x86emuOp32_mov_word_RM_IMM(struct x86emu *emu)
  2990. {
  2991. uint32_t destoffset;
  2992. uint32_t imm, *destreg;
  2993. fetch_decode_modrm(emu);
  2994. if (emu->cur_rh != 0)
  2995. x86emu_halt_sys(emu);
  2996. if (emu->cur_mod != 3) {
  2997. destoffset = decode_rl_address(emu);
  2998. imm = fetch_long_imm(emu);
  2999. store_data_long(emu, destoffset, imm);
  3000. } else {
  3001. destreg = decode_rl_long_register(emu);
  3002. imm = fetch_long_imm(emu);
  3003. *destreg = imm;
  3004. }
  3005. }
  3006. static void
  3007. x86emuOp16_mov_word_RM_IMM(struct x86emu *emu)
  3008. {
  3009. uint32_t destoffset;
  3010. uint16_t imm, *destreg;
  3011. fetch_decode_modrm(emu);
  3012. if (emu->cur_rh != 0)
  3013. x86emu_halt_sys(emu);
  3014. if (emu->cur_mod != 3) {
  3015. destoffset = decode_rl_address(emu);
  3016. imm = fetch_word_imm(emu);
  3017. store_data_word(emu, destoffset, imm);
  3018. } else {
  3019. destreg = decode_rl_word_register(emu);
  3020. imm = fetch_word_imm(emu);
  3021. *destreg = imm;
  3022. }
  3023. }
  3024. static void
  3025. x86emuOp_mov_word_RM_IMM(struct x86emu *emu)
  3026. {
  3027. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  3028. x86emuOp32_mov_word_RM_IMM(emu);
  3029. else
  3030. x86emuOp16_mov_word_RM_IMM(emu);
  3031. }
  3032. /*
  3033. * REMARKS:
  3034. * Handles opcode 0xc8
  3035. */
  3036. static void
  3037. x86emuOp_enter(struct x86emu *emu)
  3038. {
  3039. uint16_t local, frame_pointer;
  3040. uint8_t nesting;
  3041. int i;
  3042. local = fetch_word_imm(emu);
  3043. nesting = fetch_byte_imm(emu);
  3044. push_word(emu, emu->x86.R_BP);
  3045. frame_pointer = emu->x86.R_SP;
  3046. if (nesting > 0) {
  3047. for (i = 1; i < nesting; i++) {
  3048. emu->x86.R_BP -= 2;
  3049. push_word(emu, fetch_word(emu, emu->x86.R_SS,
  3050. emu->x86.R_BP));
  3051. }
  3052. push_word(emu, frame_pointer);
  3053. }
  3054. emu->x86.R_BP = frame_pointer;
  3055. emu->x86.R_SP = (uint16_t) (emu->x86.R_SP - local);
  3056. }
  3057. /*
  3058. * REMARKS:
  3059. * Handles opcode 0xc9
  3060. */
  3061. static void
  3062. x86emuOp_leave(struct x86emu *emu)
  3063. {
  3064. emu->x86.R_SP = emu->x86.R_BP;
  3065. emu->x86.R_BP = pop_word(emu);
  3066. }
  3067. /*
  3068. * REMARKS:
  3069. * Handles opcode 0xca
  3070. */
  3071. static void
  3072. x86emuOp_ret_far_IMM(struct x86emu *emu)
  3073. {
  3074. uint16_t imm;
  3075. imm = fetch_word_imm(emu);
  3076. emu->x86.R_IP = pop_word(emu);
  3077. emu->x86.R_CS = pop_word(emu);
  3078. emu->x86.R_SP += imm;
  3079. }
  3080. /*
  3081. * REMARKS:
  3082. * Handles opcode 0xcb
  3083. */
  3084. static void
  3085. x86emuOp_ret_far(struct x86emu *emu)
  3086. {
  3087. emu->x86.R_IP = pop_word(emu);
  3088. emu->x86.R_CS = pop_word(emu);
  3089. }
  3090. /*
  3091. * REMARKS:
  3092. * Handles opcode 0xcc
  3093. */
  3094. static void
  3095. x86emuOp_int3(struct x86emu *emu)
  3096. {
  3097. x86emu_intr_dispatch(emu, 3);
  3098. }
  3099. /*
  3100. * REMARKS:
  3101. * Handles opcode 0xcd
  3102. */
  3103. static void
  3104. x86emuOp_int_IMM(struct x86emu *emu)
  3105. {
  3106. uint8_t intnum;
  3107. intnum = fetch_byte_imm(emu);
  3108. x86emu_intr_dispatch(emu, intnum);
  3109. }
  3110. /*
  3111. * REMARKS:
  3112. * Handles opcode 0xce
  3113. */
  3114. static void
  3115. x86emuOp_into(struct x86emu *emu)
  3116. {
  3117. if (ACCESS_FLAG(F_OF))
  3118. x86emu_intr_dispatch(emu, 4);
  3119. }
  3120. /*
  3121. * REMARKS:
  3122. * Handles opcode 0xcf
  3123. */
  3124. static void
  3125. x86emuOp_iret(struct x86emu *emu)
  3126. {
  3127. emu->x86.R_IP = pop_word(emu);
  3128. emu->x86.R_CS = pop_word(emu);
  3129. emu->x86.R_FLG = pop_word(emu);
  3130. }
  3131. /*
  3132. * REMARKS:
  3133. * Handles opcode 0xd0
  3134. */
  3135. static void
  3136. x86emuOp_opcD0_byte_RM_1(struct x86emu *emu)
  3137. {
  3138. uint8_t destval;
  3139. fetch_decode_modrm(emu);
  3140. destval = decode_and_fetch_byte(emu);
  3141. destval = (*opcD0_byte_operation[emu->cur_rh]) (emu, destval, 1);
  3142. write_back_byte(emu, destval);
  3143. }
  3144. /*
  3145. * REMARKS:
  3146. * Handles opcode 0xd1
  3147. */
  3148. static void
  3149. x86emuOp_opcD1_word_RM_1(struct x86emu *emu)
  3150. {
  3151. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  3152. uint32_t destval;
  3153. fetch_decode_modrm(emu);
  3154. destval = decode_and_fetch_long(emu);
  3155. destval = (*opcD1_long_operation[emu->cur_rh])(emu, destval, 1);
  3156. write_back_long(emu, destval);
  3157. } else {
  3158. uint16_t destval;
  3159. fetch_decode_modrm(emu);
  3160. destval = decode_and_fetch_word(emu);
  3161. destval = (*opcD1_word_operation[emu->cur_rh])(emu, destval, 1);
  3162. write_back_word(emu, destval);
  3163. }
  3164. }
  3165. /*
  3166. * REMARKS:
  3167. * Handles opcode 0xd2
  3168. */
  3169. static void
  3170. x86emuOp_opcD2_byte_RM_CL(struct x86emu *emu)
  3171. {
  3172. uint8_t destval;
  3173. fetch_decode_modrm(emu);
  3174. destval = decode_and_fetch_byte(emu);
  3175. destval = (*opcD0_byte_operation[emu->cur_rh])
  3176. (emu, destval, emu->x86.R_CL);
  3177. write_back_byte(emu, destval);
  3178. }
  3179. /*
  3180. * REMARKS:
  3181. * Handles opcode 0xd3
  3182. */
  3183. static void
  3184. x86emuOp_opcD3_word_RM_CL(struct x86emu *emu)
  3185. {
  3186. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  3187. uint32_t destval;
  3188. fetch_decode_modrm(emu);
  3189. destval = decode_and_fetch_long(emu);
  3190. destval = (*opcD1_long_operation[emu->cur_rh])
  3191. (emu, destval, emu->x86.R_CL);
  3192. write_back_long(emu, destval);
  3193. } else {
  3194. uint16_t destval;
  3195. fetch_decode_modrm(emu);
  3196. destval = decode_and_fetch_word(emu);
  3197. destval = (*opcD1_word_operation[emu->cur_rh])
  3198. (emu, destval, emu->x86.R_CL);
  3199. write_back_word(emu, destval);
  3200. }
  3201. }
  3202. /*
  3203. * REMARKS:
  3204. * Handles opcode 0xd4
  3205. */
  3206. static void
  3207. x86emuOp_aam(struct x86emu *emu)
  3208. {
  3209. uint8_t a;
  3210. a = fetch_byte_imm(emu); /* this is a stupid encoding. */
  3211. if (a != 10) {
  3212. /* fix: add base decoding aam_word(uint8_t val, int base a) */
  3213. x86emu_halt_sys(emu);
  3214. }
  3215. /* note the type change here --- returning AL and AH in AX. */
  3216. emu->x86.R_AX = aam_word(emu, emu->x86.R_AL);
  3217. }
  3218. /*
  3219. * REMARKS:
  3220. * Handles opcode 0xd5
  3221. */
  3222. static void
  3223. x86emuOp_aad(struct x86emu *emu)
  3224. {
  3225. uint8_t a;
  3226. a = fetch_byte_imm(emu);
  3227. if (a != 10) {
  3228. /* fix: add base decoding aad_word(uint16_t val, int base a) */
  3229. x86emu_halt_sys(emu);
  3230. }
  3231. emu->x86.R_AX = aad_word(emu, emu->x86.R_AX);
  3232. }
  3233. /* opcode 0xd6 ILLEGAL OPCODE */
  3234. /*
  3235. * REMARKS:
  3236. * Handles opcode 0xd7
  3237. */
  3238. static void
  3239. x86emuOp_xlat(struct x86emu *emu)
  3240. {
  3241. uint16_t addr;
  3242. addr = (uint16_t) (emu->x86.R_BX + (uint8_t) emu->x86.R_AL);
  3243. emu->x86.R_AL = fetch_data_byte(emu, addr);
  3244. }
  3245. /* opcode=0xd8 */
  3246. static void
  3247. x86emuOp_esc_coprocess_d8(struct x86emu *emu)
  3248. {
  3249. }
  3250. /* opcode=0xd9 */
  3251. static void
  3252. x86emuOp_esc_coprocess_d9(struct x86emu *emu)
  3253. {
  3254. fetch_decode_modrm(emu);
  3255. if (emu->cur_mod != 3)
  3256. decode_rl_address(emu);
  3257. }
  3258. /* opcode=0xda */
  3259. static void
  3260. x86emuOp_esc_coprocess_da(struct x86emu *emu)
  3261. {
  3262. fetch_decode_modrm(emu);
  3263. if (emu->cur_mod != 3)
  3264. decode_rl_address(emu);
  3265. }
  3266. /* opcode=0xdb */
  3267. static void
  3268. x86emuOp_esc_coprocess_db(struct x86emu *emu)
  3269. {
  3270. fetch_decode_modrm(emu);
  3271. if (emu->cur_mod != 3)
  3272. decode_rl_address(emu);
  3273. }
  3274. /* opcode=0xdc */
  3275. static void
  3276. x86emuOp_esc_coprocess_dc(struct x86emu *emu)
  3277. {
  3278. fetch_decode_modrm(emu);
  3279. if (emu->cur_mod != 3)
  3280. decode_rl_address(emu);
  3281. }
  3282. /* opcode=0xdd */
  3283. static void
  3284. x86emuOp_esc_coprocess_dd(struct x86emu *emu)
  3285. {
  3286. fetch_decode_modrm(emu);
  3287. if (emu->cur_mod != 3)
  3288. decode_rl_address(emu);
  3289. }
  3290. /* opcode=0xde */
  3291. static void
  3292. x86emuOp_esc_coprocess_de(struct x86emu *emu)
  3293. {
  3294. fetch_decode_modrm(emu);
  3295. if (emu->cur_mod != 3)
  3296. decode_rl_address(emu);
  3297. }
  3298. /* opcode=0xdf */
  3299. static void
  3300. x86emuOp_esc_coprocess_df(struct x86emu *emu)
  3301. {
  3302. fetch_decode_modrm(emu);
  3303. if (emu->cur_mod != 3)
  3304. decode_rl_address(emu);
  3305. }
  3306. /*
  3307. * REMARKS:
  3308. * Handles opcode 0xe0
  3309. */
  3310. static void
  3311. x86emuOp_loopne(struct x86emu *emu)
  3312. {
  3313. int16_t ip;
  3314. ip = (int8_t) fetch_byte_imm(emu);
  3315. ip += (int16_t) emu->x86.R_IP;
  3316. emu->x86.R_CX -= 1;
  3317. if (emu->x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
  3318. emu->x86.R_IP = ip;
  3319. }
  3320. /*
  3321. * REMARKS:
  3322. * Handles opcode 0xe1
  3323. */
  3324. static void
  3325. x86emuOp_loope(struct x86emu *emu)
  3326. {
  3327. int16_t ip;
  3328. ip = (int8_t) fetch_byte_imm(emu);
  3329. ip += (int16_t) emu->x86.R_IP;
  3330. emu->x86.R_CX -= 1;
  3331. if (emu->x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
  3332. emu->x86.R_IP = ip;
  3333. }
  3334. /*
  3335. * REMARKS:
  3336. * Handles opcode 0xe2
  3337. */
  3338. static void
  3339. x86emuOp_loop(struct x86emu *emu)
  3340. {
  3341. int16_t ip;
  3342. ip = (int8_t) fetch_byte_imm(emu);
  3343. ip += (int16_t) emu->x86.R_IP;
  3344. emu->x86.R_CX -= 1;
  3345. if (emu->x86.R_CX != 0)
  3346. emu->x86.R_IP = ip;
  3347. }
  3348. /*
  3349. * REMARKS:
  3350. * Handles opcode 0xe3
  3351. */
  3352. static void
  3353. x86emuOp_jcxz(struct x86emu *emu)
  3354. {
  3355. uint16_t target;
  3356. int8_t offset;
  3357. /* jump to byte offset if overflow flag is set */
  3358. offset = (int8_t) fetch_byte_imm(emu);
  3359. target = (uint16_t) (emu->x86.R_IP + offset);
  3360. if (emu->x86.R_CX == 0)
  3361. emu->x86.R_IP = target;
  3362. }
  3363. /*
  3364. * REMARKS:
  3365. * Handles opcode 0xe4
  3366. */
  3367. static void
  3368. x86emuOp_in_byte_AL_IMM(struct x86emu *emu)
  3369. {
  3370. uint8_t port;
  3371. port = (uint8_t) fetch_byte_imm(emu);
  3372. emu->x86.R_AL = (*emu->emu_inb) (emu, port);
  3373. }
  3374. /*
  3375. * REMARKS:
  3376. * Handles opcode 0xe5
  3377. */
  3378. static void
  3379. x86emuOp_in_word_AX_IMM(struct x86emu *emu)
  3380. {
  3381. uint8_t port;
  3382. port = (uint8_t) fetch_byte_imm(emu);
  3383. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  3384. emu->x86.R_EAX = (*emu->emu_inl) (emu, port);
  3385. } else {
  3386. emu->x86.R_AX = (*emu->emu_inw) (emu, port);
  3387. }
  3388. }
  3389. /*
  3390. * REMARKS:
  3391. * Handles opcode 0xe6
  3392. */
  3393. static void
  3394. x86emuOp_out_byte_IMM_AL(struct x86emu *emu)
  3395. {
  3396. uint8_t port;
  3397. port = (uint8_t) fetch_byte_imm(emu);
  3398. (*emu->emu_outb) (emu, port, emu->x86.R_AL);
  3399. }
  3400. /*
  3401. * REMARKS:
  3402. * Handles opcode 0xe7
  3403. */
  3404. static void
  3405. x86emuOp_out_word_IMM_AX(struct x86emu *emu)
  3406. {
  3407. uint8_t port;
  3408. port = (uint8_t) fetch_byte_imm(emu);
  3409. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  3410. (*emu->emu_outl) (emu, port, emu->x86.R_EAX);
  3411. } else {
  3412. (*emu->emu_outw) (emu, port, emu->x86.R_AX);
  3413. }
  3414. }
  3415. /*
  3416. * REMARKS:
  3417. * Handles opcode 0xe8
  3418. */
  3419. static void
  3420. x86emuOp_call_near_IMM(struct x86emu *emu)
  3421. {
  3422. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  3423. int32_t ip;
  3424. ip = (int32_t) fetch_long_imm(emu);
  3425. ip += (int32_t) emu->x86.R_EIP;
  3426. push_long(emu, emu->x86.R_EIP);
  3427. emu->x86.R_EIP = ip;
  3428. } else {
  3429. int16_t ip;
  3430. ip = (int16_t) fetch_word_imm(emu);
  3431. ip += (int16_t) emu->x86.R_IP; /* CHECK SIGN */
  3432. push_word(emu, emu->x86.R_IP);
  3433. emu->x86.R_IP = ip;
  3434. }
  3435. }
  3436. /*
  3437. * REMARKS:
  3438. * Handles opcode 0xe9
  3439. */
  3440. static void
  3441. x86emuOp_jump_near_IMM(struct x86emu *emu)
  3442. {
  3443. int ip;
  3444. ip = (int16_t) fetch_word_imm(emu);
  3445. ip += (int16_t) emu->x86.R_IP;
  3446. emu->x86.R_IP = (uint16_t) ip;
  3447. }
  3448. /*
  3449. * REMARKS:
  3450. * Handles opcode 0xea
  3451. */
  3452. static void
  3453. x86emuOp_jump_far_IMM(struct x86emu *emu)
  3454. {
  3455. uint16_t cs, ip;
  3456. ip = fetch_word_imm(emu);
  3457. cs = fetch_word_imm(emu);
  3458. emu->x86.R_IP = ip;
  3459. emu->x86.R_CS = cs;
  3460. }
  3461. /*
  3462. * REMARKS:
  3463. * Handles opcode 0xeb
  3464. */
  3465. static void
  3466. x86emuOp_jump_byte_IMM(struct x86emu *emu)
  3467. {
  3468. uint16_t target;
  3469. int8_t offset;
  3470. offset = (int8_t) fetch_byte_imm(emu);
  3471. target = (uint16_t) (emu->x86.R_IP + offset);
  3472. emu->x86.R_IP = target;
  3473. }
  3474. /*
  3475. * REMARKS:
  3476. * Handles opcode 0xec
  3477. */
  3478. static void
  3479. x86emuOp_in_byte_AL_DX(struct x86emu *emu)
  3480. {
  3481. emu->x86.R_AL = (*emu->emu_inb) (emu, emu->x86.R_DX);
  3482. }
  3483. /*
  3484. * REMARKS:
  3485. * Handles opcode 0xed
  3486. */
  3487. static void
  3488. x86emuOp_in_word_AX_DX(struct x86emu *emu)
  3489. {
  3490. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  3491. emu->x86.R_EAX = (*emu->emu_inl) (emu, emu->x86.R_DX);
  3492. } else {
  3493. emu->x86.R_AX = (*emu->emu_inw) (emu, emu->x86.R_DX);
  3494. }
  3495. }
  3496. /*
  3497. * REMARKS:
  3498. * Handles opcode 0xee
  3499. */
  3500. static void
  3501. x86emuOp_out_byte_DX_AL(struct x86emu *emu)
  3502. {
  3503. (*emu->emu_outb) (emu, emu->x86.R_DX, emu->x86.R_AL);
  3504. }
  3505. /*
  3506. * REMARKS:
  3507. * Handles opcode 0xef
  3508. */
  3509. static void
  3510. x86emuOp_out_word_DX_AX(struct x86emu *emu)
  3511. {
  3512. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  3513. (*emu->emu_outl) (emu, emu->x86.R_DX, emu->x86.R_EAX);
  3514. } else {
  3515. (*emu->emu_outw) (emu, emu->x86.R_DX, emu->x86.R_AX);
  3516. }
  3517. }
  3518. /*
  3519. * REMARKS:
  3520. * Handles opcode 0xf0
  3521. */
  3522. static void
  3523. x86emuOp_lock(struct x86emu *emu)
  3524. {
  3525. }
  3526. /*opcode 0xf1 ILLEGAL OPERATION */
  3527. /*
  3528. * REMARKS:
  3529. * Handles opcode 0xf5
  3530. */
  3531. static void
  3532. x86emuOp_cmc(struct x86emu *emu)
  3533. {
  3534. if (ACCESS_FLAG(F_CF))
  3535. CLEAR_FLAG(F_CF);
  3536. else
  3537. SET_FLAG(F_CF);
  3538. }
  3539. /*
  3540. * REMARKS:
  3541. * Handles opcode 0xf6
  3542. */
  3543. static void
  3544. x86emuOp_opcF6_byte_RM(struct x86emu *emu)
  3545. {
  3546. uint8_t destval, srcval;
  3547. /* long, drawn out code follows. Double switch for a total of 32
  3548. * cases. */
  3549. fetch_decode_modrm(emu);
  3550. if (emu->cur_rh == 1)
  3551. x86emu_halt_sys(emu);
  3552. if (emu->cur_rh == 0) {
  3553. destval = decode_and_fetch_byte_imm8(emu, &srcval);
  3554. test_byte(emu, destval, srcval);
  3555. return;
  3556. }
  3557. destval = decode_and_fetch_byte(emu);
  3558. switch (emu->cur_rh) {
  3559. case 2:
  3560. destval = ~destval;
  3561. write_back_byte(emu, destval);
  3562. break;
  3563. case 3:
  3564. destval = neg_byte(emu, destval);
  3565. write_back_byte(emu, destval);
  3566. break;
  3567. case 4:
  3568. mul_byte(emu, destval);
  3569. break;
  3570. case 5:
  3571. imul_byte(emu, destval);
  3572. break;
  3573. case 6:
  3574. div_byte(emu, destval);
  3575. break;
  3576. case 7:
  3577. idiv_byte(emu, destval);
  3578. break;
  3579. }
  3580. }
  3581. /*
  3582. * REMARKS:
  3583. * Handles opcode 0xf7
  3584. */
  3585. static void
  3586. x86emuOp32_opcF7_word_RM(struct x86emu *emu)
  3587. {
  3588. uint32_t destval, srcval;
  3589. /* long, drawn out code follows. Double switch for a total of 32
  3590. * cases. */
  3591. fetch_decode_modrm(emu);
  3592. if (emu->cur_rh == 1)
  3593. x86emu_halt_sys(emu);
  3594. if (emu->cur_rh == 0) {
  3595. if (emu->cur_mod != 3) {
  3596. uint32_t destoffset;
  3597. destoffset = decode_rl_address(emu);
  3598. srcval = fetch_long_imm(emu);
  3599. destval = fetch_data_long(emu, destoffset);
  3600. } else {
  3601. srcval = fetch_long_imm(emu);
  3602. destval = *decode_rl_long_register(emu);
  3603. }
  3604. test_long(emu, destval, srcval);
  3605. return;
  3606. }
  3607. destval = decode_and_fetch_long(emu);
  3608. switch (emu->cur_rh) {
  3609. case 2:
  3610. destval = ~destval;
  3611. write_back_long(emu, destval);
  3612. break;
  3613. case 3:
  3614. destval = neg_long(emu, destval);
  3615. write_back_long(emu, destval);
  3616. break;
  3617. case 4:
  3618. mul_long(emu, destval);
  3619. break;
  3620. case 5:
  3621. imul_long(emu, destval);
  3622. break;
  3623. case 6:
  3624. div_long(emu, destval);
  3625. break;
  3626. case 7:
  3627. idiv_long(emu, destval);
  3628. break;
  3629. }
  3630. }
  3631. static void
  3632. x86emuOp16_opcF7_word_RM(struct x86emu *emu)
  3633. {
  3634. uint16_t destval, srcval;
  3635. /* long, drawn out code follows. Double switch for a total of 32
  3636. * cases. */
  3637. fetch_decode_modrm(emu);
  3638. if (emu->cur_rh == 1)
  3639. x86emu_halt_sys(emu);
  3640. if (emu->cur_rh == 0) {
  3641. if (emu->cur_mod != 3) {
  3642. uint32_t destoffset;
  3643. destoffset = decode_rl_address(emu);
  3644. srcval = fetch_word_imm(emu);
  3645. destval = fetch_data_word(emu, destoffset);
  3646. } else {
  3647. srcval = fetch_word_imm(emu);
  3648. destval = *decode_rl_word_register(emu);
  3649. }
  3650. test_word(emu, destval, srcval);
  3651. return;
  3652. }
  3653. destval = decode_and_fetch_word(emu);
  3654. switch (emu->cur_rh) {
  3655. case 2:
  3656. destval = ~destval;
  3657. write_back_word(emu, destval);
  3658. break;
  3659. case 3:
  3660. destval = neg_word(emu, destval);
  3661. write_back_word(emu, destval);
  3662. break;
  3663. case 4:
  3664. mul_word(emu, destval);
  3665. break;
  3666. case 5:
  3667. imul_word(emu, destval);
  3668. break;
  3669. case 6:
  3670. div_word(emu, destval);
  3671. break;
  3672. case 7:
  3673. idiv_word(emu, destval);
  3674. break;
  3675. }
  3676. }
  3677. static void
  3678. x86emuOp_opcF7_word_RM(struct x86emu *emu)
  3679. {
  3680. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  3681. x86emuOp32_opcF7_word_RM(emu);
  3682. else
  3683. x86emuOp16_opcF7_word_RM(emu);
  3684. }
  3685. /*
  3686. * REMARKS:
  3687. * Handles opcode 0xfe
  3688. */
  3689. static void
  3690. x86emuOp_opcFE_byte_RM(struct x86emu *emu)
  3691. {
  3692. uint8_t destval;
  3693. uint32_t destoffset;
  3694. uint8_t *destreg;
  3695. /* Yet another special case instruction. */
  3696. fetch_decode_modrm(emu);
  3697. if (emu->cur_mod != 3) {
  3698. destoffset = decode_rl_address(emu);
  3699. switch (emu->cur_rh) {
  3700. case 0: /* inc word ptr ... */
  3701. destval = fetch_data_byte(emu, destoffset);
  3702. destval = inc_byte(emu, destval);
  3703. store_data_byte(emu, destoffset, destval);
  3704. break;
  3705. case 1: /* dec word ptr ... */
  3706. destval = fetch_data_byte(emu, destoffset);
  3707. destval = dec_byte(emu, destval);
  3708. store_data_byte(emu, destoffset, destval);
  3709. break;
  3710. }
  3711. } else {
  3712. destreg = decode_rl_byte_register(emu);
  3713. switch (emu->cur_rh) {
  3714. case 0:
  3715. *destreg = inc_byte(emu, *destreg);
  3716. break;
  3717. case 1:
  3718. *destreg = dec_byte(emu, *destreg);
  3719. break;
  3720. }
  3721. }
  3722. }
  3723. /*
  3724. * REMARKS:
  3725. * Handles opcode 0xff
  3726. */
  3727. static void
  3728. x86emuOp32_opcFF_word_RM(struct x86emu *emu)
  3729. {
  3730. uint32_t destoffset = 0;
  3731. uint32_t destval, *destreg;
  3732. if (emu->cur_mod != 3) {
  3733. destoffset = decode_rl_address(emu);
  3734. destval = fetch_data_long(emu, destoffset);
  3735. switch (emu->cur_rh) {
  3736. case 0: /* inc word ptr ... */
  3737. destval = inc_long(emu, destval);
  3738. store_data_long(emu, destoffset, destval);
  3739. break;
  3740. case 1: /* dec word ptr ... */
  3741. destval = dec_long(emu, destval);
  3742. store_data_long(emu, destoffset, destval);
  3743. break;
  3744. case 6: /* push word ptr ... */
  3745. push_long(emu, destval);
  3746. break;
  3747. }
  3748. } else {
  3749. destreg = decode_rl_long_register(emu);
  3750. switch (emu->cur_rh) {
  3751. case 0:
  3752. *destreg = inc_long(emu, *destreg);
  3753. break;
  3754. case 1:
  3755. *destreg = dec_long(emu, *destreg);
  3756. break;
  3757. case 6:
  3758. push_long(emu, *destreg);
  3759. break;
  3760. }
  3761. }
  3762. }
  3763. static void
  3764. x86emuOp16_opcFF_word_RM(struct x86emu *emu)
  3765. {
  3766. uint32_t destoffset = 0;
  3767. uint16_t *destreg;
  3768. uint16_t destval;
  3769. if (emu->cur_mod != 3) {
  3770. destoffset = decode_rl_address(emu);
  3771. destval = fetch_data_word(emu, destoffset);
  3772. switch (emu->cur_rh) {
  3773. case 0:
  3774. destval = inc_word(emu, destval);
  3775. store_data_word(emu, destoffset, destval);
  3776. break;
  3777. case 1: /* dec word ptr ... */
  3778. destval = dec_word(emu, destval);
  3779. store_data_word(emu, destoffset, destval);
  3780. break;
  3781. case 6: /* push word ptr ... */
  3782. push_word(emu, destval);
  3783. break;
  3784. }
  3785. } else {
  3786. destreg = decode_rl_word_register(emu);
  3787. switch (emu->cur_rh) {
  3788. case 0:
  3789. *destreg = inc_word(emu, *destreg);
  3790. break;
  3791. case 1:
  3792. *destreg = dec_word(emu, *destreg);
  3793. break;
  3794. case 6:
  3795. push_word(emu, *destreg);
  3796. break;
  3797. }
  3798. }
  3799. }
  3800. static void
  3801. x86emuOp_opcFF_word_RM(struct x86emu *emu)
  3802. {
  3803. uint32_t destoffset = 0;
  3804. uint16_t destval, destval2;
  3805. /* Yet another special case instruction. */
  3806. fetch_decode_modrm(emu);
  3807. if ((emu->cur_mod == 3 && (emu->cur_rh == 3 || emu->cur_rh == 5)) ||
  3808. emu->cur_rh == 7)
  3809. x86emu_halt_sys(emu);
  3810. if (emu->cur_rh == 0 || emu->cur_rh == 1 || emu->cur_rh == 6) {
  3811. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  3812. x86emuOp32_opcFF_word_RM(emu);
  3813. else
  3814. x86emuOp16_opcFF_word_RM(emu);
  3815. return;
  3816. }
  3817. if (emu->cur_mod != 3) {
  3818. destoffset = decode_rl_address(emu);
  3819. destval = fetch_data_word(emu, destoffset);
  3820. switch (emu->cur_rh) {
  3821. case 3: /* call far ptr ... */
  3822. destval2 = fetch_data_word(emu, destoffset + 2);
  3823. push_word(emu, emu->x86.R_CS);
  3824. emu->x86.R_CS = destval2;
  3825. push_word(emu, emu->x86.R_IP);
  3826. emu->x86.R_IP = destval;
  3827. break;
  3828. case 5: /* jmp far ptr ... */
  3829. destval2 = fetch_data_word(emu, destoffset + 2);
  3830. emu->x86.R_IP = destval;
  3831. emu->x86.R_CS = destval2;
  3832. break;
  3833. }
  3834. } else {
  3835. destval = *decode_rl_word_register(emu);
  3836. }
  3837. switch (emu->cur_rh) {
  3838. case 2: /* call word ptr */
  3839. push_word(emu, emu->x86.R_IP);
  3840. emu->x86.R_IP = destval;
  3841. break;
  3842. case 4: /* jmp */
  3843. emu->x86.R_IP = destval;
  3844. break;
  3845. }
  3846. }
  3847. /*
  3848. * * Single byte operation code table:
  3849. */
  3850. static void
  3851. x86emu_exec_one_byte(struct x86emu * emu)
  3852. {
  3853. uint8_t op1;
  3854. op1 = fetch_byte_imm(emu);
  3855. switch (op1) {
  3856. case 0x00:
  3857. common_binop_byte_rm_r(emu, add_byte);
  3858. break;
  3859. case 0x01:
  3860. common_binop_word_long_rm_r(emu, add_word, add_long);
  3861. break;
  3862. case 0x02:
  3863. common_binop_byte_r_rm(emu, add_byte);
  3864. break;
  3865. case 0x03:
  3866. common_binop_word_long_r_rm(emu, add_word, add_long);
  3867. break;
  3868. case 0x04:
  3869. common_binop_byte_imm(emu, add_byte);
  3870. break;
  3871. case 0x05:
  3872. common_binop_word_long_imm(emu, add_word, add_long);
  3873. break;
  3874. case 0x06:
  3875. push_word(emu, emu->x86.R_ES);
  3876. break;
  3877. case 0x07:
  3878. emu->x86.R_ES = pop_word(emu);
  3879. break;
  3880. case 0x08:
  3881. common_binop_byte_rm_r(emu, or_byte);
  3882. break;
  3883. case 0x09:
  3884. common_binop_word_long_rm_r(emu, or_word, or_long);
  3885. break;
  3886. case 0x0a:
  3887. common_binop_byte_r_rm(emu, or_byte);
  3888. break;
  3889. case 0x0b:
  3890. common_binop_word_long_r_rm(emu, or_word, or_long);
  3891. break;
  3892. case 0x0c:
  3893. common_binop_byte_imm(emu, or_byte);
  3894. break;
  3895. case 0x0d:
  3896. common_binop_word_long_imm(emu, or_word, or_long);
  3897. break;
  3898. case 0x0e:
  3899. push_word(emu, emu->x86.R_CS);
  3900. break;
  3901. case 0x0f:
  3902. x86emu_exec_two_byte(emu);
  3903. break;
  3904. case 0x10:
  3905. common_binop_byte_rm_r(emu, adc_byte);
  3906. break;
  3907. case 0x11:
  3908. common_binop_word_long_rm_r(emu, adc_word, adc_long);
  3909. break;
  3910. case 0x12:
  3911. common_binop_byte_r_rm(emu, adc_byte);
  3912. break;
  3913. case 0x13:
  3914. common_binop_word_long_r_rm(emu, adc_word, adc_long);
  3915. break;
  3916. case 0x14:
  3917. common_binop_byte_imm(emu, adc_byte);
  3918. break;
  3919. case 0x15:
  3920. common_binop_word_long_imm(emu, adc_word, adc_long);
  3921. break;
  3922. case 0x16:
  3923. push_word(emu, emu->x86.R_SS);
  3924. break;
  3925. case 0x17:
  3926. emu->x86.R_SS = pop_word(emu);
  3927. break;
  3928. case 0x18:
  3929. common_binop_byte_rm_r(emu, sbb_byte);
  3930. break;
  3931. case 0x19:
  3932. common_binop_word_long_rm_r(emu, sbb_word, sbb_long);
  3933. break;
  3934. case 0x1a:
  3935. common_binop_byte_r_rm(emu, sbb_byte);
  3936. break;
  3937. case 0x1b:
  3938. common_binop_word_long_r_rm(emu, sbb_word, sbb_long);
  3939. break;
  3940. case 0x1c:
  3941. common_binop_byte_imm(emu, sbb_byte);
  3942. break;
  3943. case 0x1d:
  3944. common_binop_word_long_imm(emu, sbb_word, sbb_long);
  3945. break;
  3946. case 0x1e:
  3947. push_word(emu, emu->x86.R_DS);
  3948. break;
  3949. case 0x1f:
  3950. emu->x86.R_DS = pop_word(emu);
  3951. break;
  3952. case 0x20:
  3953. common_binop_byte_rm_r(emu, and_byte);
  3954. break;
  3955. case 0x21:
  3956. common_binop_word_long_rm_r(emu, and_word, and_long);
  3957. break;
  3958. case 0x22:
  3959. common_binop_byte_r_rm(emu, and_byte);
  3960. break;
  3961. case 0x23:
  3962. common_binop_word_long_r_rm(emu, and_word, and_long);
  3963. break;
  3964. case 0x24:
  3965. common_binop_byte_imm(emu, and_byte);
  3966. break;
  3967. case 0x25:
  3968. common_binop_word_long_imm(emu, and_word, and_long);
  3969. break;
  3970. case 0x26:
  3971. emu->x86.mode |= SYSMODE_SEGOVR_ES;
  3972. break;
  3973. case 0x27:
  3974. emu->x86.R_AL = daa_byte(emu, emu->x86.R_AL);
  3975. break;
  3976. case 0x28:
  3977. common_binop_byte_rm_r(emu, sub_byte);
  3978. break;
  3979. case 0x29:
  3980. common_binop_word_long_rm_r(emu, sub_word, sub_long);
  3981. break;
  3982. case 0x2a:
  3983. common_binop_byte_r_rm(emu, sub_byte);
  3984. break;
  3985. case 0x2b:
  3986. common_binop_word_long_r_rm(emu, sub_word, sub_long);
  3987. break;
  3988. case 0x2c:
  3989. common_binop_byte_imm(emu, sub_byte);
  3990. break;
  3991. case 0x2d:
  3992. common_binop_word_long_imm(emu, sub_word, sub_long);
  3993. break;
  3994. case 0x2e:
  3995. emu->x86.mode |= SYSMODE_SEGOVR_CS;
  3996. break;
  3997. case 0x2f:
  3998. emu->x86.R_AL = das_byte(emu, emu->x86.R_AL);
  3999. break;
  4000. case 0x30:
  4001. common_binop_byte_rm_r(emu, xor_byte);
  4002. break;
  4003. case 0x31:
  4004. common_binop_word_long_rm_r(emu, xor_word, xor_long);
  4005. break;
  4006. case 0x32:
  4007. common_binop_byte_r_rm(emu, xor_byte);
  4008. break;
  4009. case 0x33:
  4010. common_binop_word_long_r_rm(emu, xor_word, xor_long);
  4011. break;
  4012. case 0x34:
  4013. common_binop_byte_imm(emu, xor_byte);
  4014. break;
  4015. case 0x35:
  4016. common_binop_word_long_imm(emu, xor_word, xor_long);
  4017. break;
  4018. case 0x36:
  4019. emu->x86.mode |= SYSMODE_SEGOVR_SS;
  4020. break;
  4021. case 0x37:
  4022. emu->x86.R_AX = aaa_word(emu, emu->x86.R_AX);
  4023. break;
  4024. case 0x38:
  4025. common_binop_ns_byte_rm_r(emu, cmp_byte_no_return);
  4026. break;
  4027. case 0x39:
  4028. common_binop_ns_word_long_rm_r(emu, cmp_word_no_return,
  4029. cmp_long_no_return);
  4030. break;
  4031. case 0x3a:
  4032. x86emuOp_cmp_byte_R_RM(emu);
  4033. break;
  4034. case 0x3b:
  4035. x86emuOp_cmp_word_R_RM(emu);
  4036. break;
  4037. case 0x3c:
  4038. x86emuOp_cmp_byte_AL_IMM(emu);
  4039. break;
  4040. case 0x3d:
  4041. x86emuOp_cmp_word_AX_IMM(emu);
  4042. break;
  4043. case 0x3e:
  4044. emu->x86.mode |= SYSMODE_SEGOVR_DS;
  4045. break;
  4046. case 0x3f:
  4047. emu->x86.R_AX = aas_word(emu, emu->x86.R_AX);
  4048. break;
  4049. case 0x40:
  4050. common_inc_word_long(emu, &emu->x86.register_a);
  4051. break;
  4052. case 0x41:
  4053. common_inc_word_long(emu, &emu->x86.register_c);
  4054. break;
  4055. case 0x42:
  4056. common_inc_word_long(emu, &emu->x86.register_d);
  4057. break;
  4058. case 0x43:
  4059. common_inc_word_long(emu, &emu->x86.register_b);
  4060. break;
  4061. case 0x44:
  4062. common_inc_word_long(emu, &emu->x86.register_sp);
  4063. break;
  4064. case 0x45:
  4065. common_inc_word_long(emu, &emu->x86.register_bp);
  4066. break;
  4067. case 0x46:
  4068. common_inc_word_long(emu, &emu->x86.register_si);
  4069. break;
  4070. case 0x47:
  4071. common_inc_word_long(emu, &emu->x86.register_di);
  4072. break;
  4073. case 0x48:
  4074. common_dec_word_long(emu, &emu->x86.register_a);
  4075. break;
  4076. case 0x49:
  4077. common_dec_word_long(emu, &emu->x86.register_c);
  4078. break;
  4079. case 0x4a:
  4080. common_dec_word_long(emu, &emu->x86.register_d);
  4081. break;
  4082. case 0x4b:
  4083. common_dec_word_long(emu, &emu->x86.register_b);
  4084. break;
  4085. case 0x4c:
  4086. common_dec_word_long(emu, &emu->x86.register_sp);
  4087. break;
  4088. case 0x4d:
  4089. common_dec_word_long(emu, &emu->x86.register_bp);
  4090. break;
  4091. case 0x4e:
  4092. common_dec_word_long(emu, &emu->x86.register_si);
  4093. break;
  4094. case 0x4f:
  4095. common_dec_word_long(emu, &emu->x86.register_di);
  4096. break;
  4097. case 0x50:
  4098. common_push_word_long(emu, &emu->x86.register_a);
  4099. break;
  4100. case 0x51:
  4101. common_push_word_long(emu, &emu->x86.register_c);
  4102. break;
  4103. case 0x52:
  4104. common_push_word_long(emu, &emu->x86.register_d);
  4105. break;
  4106. case 0x53:
  4107. common_push_word_long(emu, &emu->x86.register_b);
  4108. break;
  4109. case 0x54:
  4110. common_push_word_long(emu, &emu->x86.register_sp);
  4111. break;
  4112. case 0x55:
  4113. common_push_word_long(emu, &emu->x86.register_bp);
  4114. break;
  4115. case 0x56:
  4116. common_push_word_long(emu, &emu->x86.register_si);
  4117. break;
  4118. case 0x57:
  4119. common_push_word_long(emu, &emu->x86.register_di);
  4120. break;
  4121. case 0x58:
  4122. common_pop_word_long(emu, &emu->x86.register_a);
  4123. break;
  4124. case 0x59:
  4125. common_pop_word_long(emu, &emu->x86.register_c);
  4126. break;
  4127. case 0x5a:
  4128. common_pop_word_long(emu, &emu->x86.register_d);
  4129. break;
  4130. case 0x5b:
  4131. common_pop_word_long(emu, &emu->x86.register_b);
  4132. break;
  4133. case 0x5c:
  4134. common_pop_word_long(emu, &emu->x86.register_sp);
  4135. break;
  4136. case 0x5d:
  4137. common_pop_word_long(emu, &emu->x86.register_bp);
  4138. break;
  4139. case 0x5e:
  4140. common_pop_word_long(emu, &emu->x86.register_si);
  4141. break;
  4142. case 0x5f:
  4143. common_pop_word_long(emu, &emu->x86.register_di);
  4144. break;
  4145. case 0x60:
  4146. x86emuOp_push_all(emu);
  4147. break;
  4148. case 0x61:
  4149. x86emuOp_pop_all(emu);
  4150. break;
  4151. /* 0x62 bound */
  4152. /* 0x63 arpl */
  4153. case 0x64:
  4154. emu->x86.mode |= SYSMODE_SEGOVR_FS;
  4155. break;
  4156. case 0x65:
  4157. emu->x86.mode |= SYSMODE_SEGOVR_GS;
  4158. break;
  4159. case 0x66:
  4160. emu->x86.mode |= SYSMODE_PREFIX_DATA;
  4161. break;
  4162. case 0x67:
  4163. emu->x86.mode |= SYSMODE_PREFIX_ADDR;
  4164. break;
  4165. case 0x68:
  4166. x86emuOp_push_word_IMM(emu);
  4167. break;
  4168. case 0x69:
  4169. common_imul_imm(emu, 0);
  4170. break;
  4171. case 0x6a:
  4172. x86emuOp_push_byte_IMM(emu);
  4173. break;
  4174. case 0x6b:
  4175. common_imul_imm(emu, 1);
  4176. break;
  4177. case 0x6c:
  4178. ins(emu, 1);
  4179. break;
  4180. case 0x6d:
  4181. x86emuOp_ins_word(emu);
  4182. break;
  4183. case 0x6e:
  4184. outs(emu, 1);
  4185. break;
  4186. case 0x6f:
  4187. x86emuOp_outs_word(emu);
  4188. break;
  4189. case 0x70:
  4190. common_jmp_near(emu, ACCESS_FLAG(F_OF));
  4191. break;
  4192. case 0x71:
  4193. common_jmp_near(emu, !ACCESS_FLAG(F_OF));
  4194. break;
  4195. case 0x72:
  4196. common_jmp_near(emu, ACCESS_FLAG(F_CF));
  4197. break;
  4198. case 0x73:
  4199. common_jmp_near(emu, !ACCESS_FLAG(F_CF));
  4200. break;
  4201. case 0x74:
  4202. common_jmp_near(emu, ACCESS_FLAG(F_ZF));
  4203. break;
  4204. case 0x75:
  4205. common_jmp_near(emu, !ACCESS_FLAG(F_ZF));
  4206. break;
  4207. case 0x76:
  4208. common_jmp_near(emu, ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
  4209. break;
  4210. case 0x77:
  4211. common_jmp_near(emu, !ACCESS_FLAG(F_CF) && !ACCESS_FLAG(F_ZF));
  4212. break;
  4213. case 0x78:
  4214. common_jmp_near(emu, ACCESS_FLAG(F_SF));
  4215. break;
  4216. case 0x79:
  4217. common_jmp_near(emu, !ACCESS_FLAG(F_SF));
  4218. break;
  4219. case 0x7a:
  4220. common_jmp_near(emu, ACCESS_FLAG(F_PF));
  4221. break;
  4222. case 0x7b:
  4223. common_jmp_near(emu, !ACCESS_FLAG(F_PF));
  4224. break;
  4225. case 0x7c:
  4226. x86emuOp_jump_near_L(emu);
  4227. break;
  4228. case 0x7d:
  4229. x86emuOp_jump_near_NL(emu);
  4230. break;
  4231. case 0x7e:
  4232. x86emuOp_jump_near_LE(emu);
  4233. break;
  4234. case 0x7f:
  4235. x86emuOp_jump_near_NLE(emu);
  4236. break;
  4237. case 0x80:
  4238. x86emuOp_opc80_byte_RM_IMM(emu);
  4239. break;
  4240. case 0x81:
  4241. x86emuOp_opc81_word_RM_IMM(emu);
  4242. break;
  4243. case 0x82:
  4244. x86emuOp_opc82_byte_RM_IMM(emu);
  4245. break;
  4246. case 0x83:
  4247. x86emuOp_opc83_word_RM_IMM(emu);
  4248. break;
  4249. case 0x84:
  4250. common_binop_ns_byte_rm_r(emu, test_byte);
  4251. break;
  4252. case 0x85:
  4253. common_binop_ns_word_long_rm_r(emu, test_word, test_long);
  4254. break;
  4255. case 0x86:
  4256. x86emuOp_xchg_byte_RM_R(emu);
  4257. break;
  4258. case 0x87:
  4259. x86emuOp_xchg_word_RM_R(emu);
  4260. break;
  4261. case 0x88:
  4262. x86emuOp_mov_byte_RM_R(emu);
  4263. break;
  4264. case 0x89:
  4265. x86emuOp_mov_word_RM_R(emu);
  4266. break;
  4267. case 0x8a:
  4268. x86emuOp_mov_byte_R_RM(emu);
  4269. break;
  4270. case 0x8b:
  4271. x86emuOp_mov_word_R_RM(emu);
  4272. break;
  4273. case 0x8c:
  4274. x86emuOp_mov_word_RM_SR(emu);
  4275. break;
  4276. case 0x8d:
  4277. x86emuOp_lea_word_R_M(emu);
  4278. break;
  4279. case 0x8e:
  4280. x86emuOp_mov_word_SR_RM(emu);
  4281. break;
  4282. case 0x8f:
  4283. x86emuOp_pop_RM(emu);
  4284. break;
  4285. case 0x90:
  4286. /* nop */
  4287. break;
  4288. case 0x91:
  4289. x86emuOp_xchg_word_AX_CX(emu);
  4290. break;
  4291. case 0x92:
  4292. x86emuOp_xchg_word_AX_DX(emu);
  4293. break;
  4294. case 0x93:
  4295. x86emuOp_xchg_word_AX_BX(emu);
  4296. break;
  4297. case 0x94:
  4298. x86emuOp_xchg_word_AX_SP(emu);
  4299. break;
  4300. case 0x95:
  4301. x86emuOp_xchg_word_AX_BP(emu);
  4302. break;
  4303. case 0x96:
  4304. x86emuOp_xchg_word_AX_SI(emu);
  4305. break;
  4306. case 0x97:
  4307. x86emuOp_xchg_word_AX_DI(emu);
  4308. break;
  4309. case 0x98:
  4310. x86emuOp_cbw(emu);
  4311. break;
  4312. case 0x99:
  4313. x86emuOp_cwd(emu);
  4314. break;
  4315. case 0x9a:
  4316. x86emuOp_call_far_IMM(emu);
  4317. break;
  4318. case 0x9b:
  4319. /* wait */
  4320. break;
  4321. case 0x9c:
  4322. x86emuOp_pushf_word(emu);
  4323. break;
  4324. case 0x9d:
  4325. x86emuOp_popf_word(emu);
  4326. break;
  4327. case 0x9e:
  4328. x86emuOp_sahf(emu);
  4329. break;
  4330. case 0x9f:
  4331. x86emuOp_lahf(emu);
  4332. break;
  4333. case 0xa0:
  4334. x86emuOp_mov_AL_M_IMM(emu);
  4335. break;
  4336. case 0xa1:
  4337. x86emuOp_mov_AX_M_IMM(emu);
  4338. break;
  4339. case 0xa2:
  4340. x86emuOp_mov_M_AL_IMM(emu);
  4341. break;
  4342. case 0xa3:
  4343. x86emuOp_mov_M_AX_IMM(emu);
  4344. break;
  4345. case 0xa4:
  4346. x86emuOp_movs_byte(emu);
  4347. break;
  4348. case 0xa5:
  4349. x86emuOp_movs_word(emu);
  4350. break;
  4351. case 0xa6:
  4352. x86emuOp_cmps_byte(emu);
  4353. break;
  4354. case 0xa7:
  4355. x86emuOp_cmps_word(emu);
  4356. break;
  4357. case 0xa8:
  4358. test_byte(emu, emu->x86.R_AL, fetch_byte_imm(emu));
  4359. break;
  4360. case 0xa9:
  4361. x86emuOp_test_AX_IMM(emu);
  4362. break;
  4363. case 0xaa:
  4364. x86emuOp_stos_byte(emu);
  4365. break;
  4366. case 0xab:
  4367. x86emuOp_stos_word(emu);
  4368. break;
  4369. case 0xac:
  4370. x86emuOp_lods_byte(emu);
  4371. break;
  4372. case 0xad:
  4373. x86emuOp_lods_word(emu);
  4374. break;
  4375. case 0xae:
  4376. x86emuOp_scas_byte(emu);
  4377. break;
  4378. case 0xaf:
  4379. x86emuOp_scas_word(emu);
  4380. break;
  4381. case 0xb0:
  4382. emu->x86.R_AL = fetch_byte_imm(emu);
  4383. break;
  4384. case 0xb1:
  4385. emu->x86.R_CL = fetch_byte_imm(emu);
  4386. break;
  4387. case 0xb2:
  4388. emu->x86.R_DL = fetch_byte_imm(emu);
  4389. break;
  4390. case 0xb3:
  4391. emu->x86.R_BL = fetch_byte_imm(emu);
  4392. break;
  4393. case 0xb4:
  4394. emu->x86.R_AH = fetch_byte_imm(emu);
  4395. break;
  4396. case 0xb5:
  4397. emu->x86.R_CH = fetch_byte_imm(emu);
  4398. break;
  4399. case 0xb6:
  4400. emu->x86.R_DH = fetch_byte_imm(emu);
  4401. break;
  4402. case 0xb7:
  4403. emu->x86.R_BH = fetch_byte_imm(emu);
  4404. break;
  4405. case 0xb8:
  4406. x86emuOp_mov_word_AX_IMM(emu);
  4407. break;
  4408. case 0xb9:
  4409. x86emuOp_mov_word_CX_IMM(emu);
  4410. break;
  4411. case 0xba:
  4412. x86emuOp_mov_word_DX_IMM(emu);
  4413. break;
  4414. case 0xbb:
  4415. x86emuOp_mov_word_BX_IMM(emu);
  4416. break;
  4417. case 0xbc:
  4418. x86emuOp_mov_word_SP_IMM(emu);
  4419. break;
  4420. case 0xbd:
  4421. x86emuOp_mov_word_BP_IMM(emu);
  4422. break;
  4423. case 0xbe:
  4424. x86emuOp_mov_word_SI_IMM(emu);
  4425. break;
  4426. case 0xbf:
  4427. x86emuOp_mov_word_DI_IMM(emu);
  4428. break;
  4429. case 0xc0:
  4430. x86emuOp_opcC0_byte_RM_MEM(emu);
  4431. break;
  4432. case 0xc1:
  4433. x86emuOp_opcC1_word_RM_MEM(emu);
  4434. break;
  4435. case 0xc2:
  4436. x86emuOp_ret_near_IMM(emu);
  4437. break;
  4438. case 0xc3:
  4439. emu->x86.R_IP = pop_word(emu);
  4440. break;
  4441. case 0xc4:
  4442. common_load_far_pointer(emu, &emu->x86.R_ES);
  4443. break;
  4444. case 0xc5:
  4445. common_load_far_pointer(emu, &emu->x86.R_DS);
  4446. break;
  4447. case 0xc6:
  4448. x86emuOp_mov_byte_RM_IMM(emu);
  4449. break;
  4450. case 0xc7:
  4451. x86emuOp_mov_word_RM_IMM(emu);
  4452. break;
  4453. case 0xc8:
  4454. x86emuOp_enter(emu);
  4455. break;
  4456. case 0xc9:
  4457. x86emuOp_leave(emu);
  4458. break;
  4459. case 0xca:
  4460. x86emuOp_ret_far_IMM(emu);
  4461. break;
  4462. case 0xcb:
  4463. x86emuOp_ret_far(emu);
  4464. break;
  4465. case 0xcc:
  4466. x86emuOp_int3(emu);
  4467. break;
  4468. case 0xcd:
  4469. x86emuOp_int_IMM(emu);
  4470. break;
  4471. case 0xce:
  4472. x86emuOp_into(emu);
  4473. break;
  4474. case 0xcf:
  4475. x86emuOp_iret(emu);
  4476. break;
  4477. case 0xd0:
  4478. x86emuOp_opcD0_byte_RM_1(emu);
  4479. break;
  4480. case 0xd1:
  4481. x86emuOp_opcD1_word_RM_1(emu);
  4482. break;
  4483. case 0xd2:
  4484. x86emuOp_opcD2_byte_RM_CL(emu);
  4485. break;
  4486. case 0xd3:
  4487. x86emuOp_opcD3_word_RM_CL(emu);
  4488. break;
  4489. case 0xd4:
  4490. x86emuOp_aam(emu);
  4491. break;
  4492. case 0xd5:
  4493. x86emuOp_aad(emu);
  4494. break;
  4495. /* 0xd6 Undocumented SETALC instruction */
  4496. case 0xd7:
  4497. x86emuOp_xlat(emu);
  4498. break;
  4499. case 0xd8:
  4500. x86emuOp_esc_coprocess_d8(emu);
  4501. break;
  4502. case 0xd9:
  4503. x86emuOp_esc_coprocess_d9(emu);
  4504. break;
  4505. case 0xda:
  4506. x86emuOp_esc_coprocess_da(emu);
  4507. break;
  4508. case 0xdb:
  4509. x86emuOp_esc_coprocess_db(emu);
  4510. break;
  4511. case 0xdc:
  4512. x86emuOp_esc_coprocess_dc(emu);
  4513. break;
  4514. case 0xdd:
  4515. x86emuOp_esc_coprocess_dd(emu);
  4516. break;
  4517. case 0xde:
  4518. x86emuOp_esc_coprocess_de(emu);
  4519. break;
  4520. case 0xdf:
  4521. x86emuOp_esc_coprocess_df(emu);
  4522. break;
  4523. case 0xe0:
  4524. x86emuOp_loopne(emu);
  4525. break;
  4526. case 0xe1:
  4527. x86emuOp_loope(emu);
  4528. break;
  4529. case 0xe2:
  4530. x86emuOp_loop(emu);
  4531. break;
  4532. case 0xe3:
  4533. x86emuOp_jcxz(emu);
  4534. break;
  4535. case 0xe4:
  4536. x86emuOp_in_byte_AL_IMM(emu);
  4537. break;
  4538. case 0xe5:
  4539. x86emuOp_in_word_AX_IMM(emu);
  4540. break;
  4541. case 0xe6:
  4542. x86emuOp_out_byte_IMM_AL(emu);
  4543. break;
  4544. case 0xe7:
  4545. x86emuOp_out_word_IMM_AX(emu);
  4546. break;
  4547. case 0xe8:
  4548. x86emuOp_call_near_IMM(emu);
  4549. break;
  4550. case 0xe9:
  4551. x86emuOp_jump_near_IMM(emu);
  4552. break;
  4553. case 0xea:
  4554. x86emuOp_jump_far_IMM(emu);
  4555. break;
  4556. case 0xeb:
  4557. x86emuOp_jump_byte_IMM(emu);
  4558. break;
  4559. case 0xec:
  4560. x86emuOp_in_byte_AL_DX(emu);
  4561. break;
  4562. case 0xed:
  4563. x86emuOp_in_word_AX_DX(emu);
  4564. break;
  4565. case 0xee:
  4566. x86emuOp_out_byte_DX_AL(emu);
  4567. break;
  4568. case 0xef:
  4569. x86emuOp_out_word_DX_AX(emu);
  4570. break;
  4571. case 0xf0:
  4572. x86emuOp_lock(emu);
  4573. break;
  4574. case 0xf2:
  4575. emu->x86.mode |= SYSMODE_PREFIX_REPNE;
  4576. break;
  4577. case 0xf3:
  4578. emu->x86.mode |= SYSMODE_PREFIX_REPE;
  4579. break;
  4580. case 0xf4:
  4581. x86emu_halt_sys(emu);
  4582. break;
  4583. case 0xf5:
  4584. x86emuOp_cmc(emu);
  4585. break;
  4586. case 0xf6:
  4587. x86emuOp_opcF6_byte_RM(emu);
  4588. break;
  4589. case 0xf7:
  4590. x86emuOp_opcF7_word_RM(emu);
  4591. break;
  4592. case 0xf8:
  4593. CLEAR_FLAG(F_CF);
  4594. break;
  4595. case 0xf9:
  4596. SET_FLAG(F_CF);
  4597. break;
  4598. case 0xfa:
  4599. CLEAR_FLAG(F_IF);
  4600. break;
  4601. case 0xfb:
  4602. SET_FLAG(F_IF);
  4603. break;
  4604. case 0xfc:
  4605. CLEAR_FLAG(F_DF);
  4606. break;
  4607. case 0xfd:
  4608. SET_FLAG(F_DF);
  4609. break;
  4610. case 0xfe:
  4611. x86emuOp_opcFE_byte_RM(emu);
  4612. break;
  4613. case 0xff:
  4614. x86emuOp_opcFF_word_RM(emu);
  4615. break;
  4616. default:
  4617. x86emu_halt_sys(emu);
  4618. break;
  4619. }
  4620. if (op1 != 0x26 && op1 != 0x2e && op1 != 0x36 && op1 != 0x3e &&
  4621. (op1 | 3) != 0x67)
  4622. emu->x86.mode &= ~SYSMODE_CLRMASK;
  4623. }
  4624. static void
  4625. common_jmp_long(struct x86emu *emu, int cond)
  4626. {
  4627. int16_t target;
  4628. target = (int16_t) fetch_word_imm(emu);
  4629. target += (int16_t) emu->x86.R_IP;
  4630. if (cond)
  4631. emu->x86.R_IP = (uint16_t) target;
  4632. }
  4633. static void
  4634. common_set_byte(struct x86emu *emu, int cond)
  4635. {
  4636. uint32_t destoffset;
  4637. uint8_t *destreg, destval;
  4638. fetch_decode_modrm(emu);
  4639. destval = cond ? 0x01 : 0x00;
  4640. if (emu->cur_mod != 3) {
  4641. destoffset = decode_rl_address(emu);
  4642. store_data_byte(emu, destoffset, destval);
  4643. } else {
  4644. destreg = decode_rl_byte_register(emu);
  4645. *destreg = destval;
  4646. }
  4647. }
  4648. static void
  4649. common_bitstring32(struct x86emu *emu, int op)
  4650. {
  4651. int bit;
  4652. uint32_t srcval, *shiftreg, mask;
  4653. fetch_decode_modrm(emu);
  4654. shiftreg = decode_rh_long_register(emu);
  4655. srcval = decode_and_fetch_long_disp(emu, (int16_t) *shiftreg >> 5);
  4656. bit = *shiftreg & 0x1F;
  4657. mask = 0x1 << bit;
  4658. CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
  4659. switch (op) {
  4660. case 0:
  4661. break;
  4662. case 1:
  4663. write_back_long(emu, srcval | mask);
  4664. break;
  4665. case 2:
  4666. write_back_long(emu, srcval & ~mask);
  4667. break;
  4668. case 3:
  4669. write_back_long(emu, srcval ^ mask);
  4670. break;
  4671. }
  4672. }
  4673. static void
  4674. common_bitstring16(struct x86emu *emu, int op)
  4675. {
  4676. int bit;
  4677. uint16_t srcval, *shiftreg, mask;
  4678. fetch_decode_modrm(emu);
  4679. shiftreg = decode_rh_word_register(emu);
  4680. srcval = decode_and_fetch_word_disp(emu, (int16_t) *shiftreg >> 4);
  4681. bit = *shiftreg & 0xF;
  4682. mask = 0x1 << bit;
  4683. CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
  4684. switch (op) {
  4685. case 0:
  4686. break;
  4687. case 1:
  4688. write_back_word(emu, srcval | mask);
  4689. break;
  4690. case 2:
  4691. write_back_word(emu, srcval & ~mask);
  4692. break;
  4693. case 3:
  4694. write_back_word(emu, srcval ^ mask);
  4695. break;
  4696. }
  4697. }
  4698. static void
  4699. common_bitstring(struct x86emu *emu, int op)
  4700. {
  4701. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  4702. common_bitstring32(emu, op);
  4703. else
  4704. common_bitstring16(emu, op);
  4705. }
  4706. static void
  4707. common_bitsearch32(struct x86emu *emu, int diff)
  4708. {
  4709. uint32_t srcval, *dstreg;
  4710. fetch_decode_modrm(emu);
  4711. dstreg = decode_rh_long_register(emu);
  4712. srcval = decode_and_fetch_long(emu);
  4713. CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
  4714. for (*dstreg = 0; *dstreg < 32; *dstreg += diff) {
  4715. if ((srcval >> *dstreg) & 1)
  4716. break;
  4717. }
  4718. }
  4719. static void
  4720. common_bitsearch16(struct x86emu *emu, int diff)
  4721. {
  4722. uint16_t srcval, *dstreg;
  4723. fetch_decode_modrm(emu);
  4724. dstreg = decode_rh_word_register(emu);
  4725. srcval = decode_and_fetch_word(emu);
  4726. CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
  4727. for (*dstreg = 0; *dstreg < 16; *dstreg += diff) {
  4728. if ((srcval >> *dstreg) & 1)
  4729. break;
  4730. }
  4731. }
  4732. static void
  4733. common_bitsearch(struct x86emu *emu, int diff)
  4734. {
  4735. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  4736. common_bitsearch32(emu, diff);
  4737. else
  4738. common_bitsearch16(emu, diff);
  4739. }
  4740. static void
  4741. common_shift32(struct x86emu *emu, int shift_left, int use_cl)
  4742. {
  4743. uint8_t shift;
  4744. uint32_t destval, *shiftreg;
  4745. fetch_decode_modrm(emu);
  4746. shiftreg = decode_rh_long_register(emu);
  4747. if (use_cl) {
  4748. destval = decode_and_fetch_long(emu);
  4749. shift = emu->x86.R_CL;
  4750. } else {
  4751. destval = decode_and_fetch_long_imm8(emu, &shift);
  4752. }
  4753. if (shift_left)
  4754. destval = shld_long(emu, destval, *shiftreg, shift);
  4755. else
  4756. destval = shrd_long(emu, destval, *shiftreg, shift);
  4757. write_back_long(emu, destval);
  4758. }
  4759. static void
  4760. common_shift16(struct x86emu *emu, int shift_left, int use_cl)
  4761. {
  4762. uint8_t shift;
  4763. uint16_t destval, *shiftreg;
  4764. fetch_decode_modrm(emu);
  4765. shiftreg = decode_rh_word_register(emu);
  4766. if (use_cl) {
  4767. destval = decode_and_fetch_word(emu);
  4768. shift = emu->x86.R_CL;
  4769. } else {
  4770. destval = decode_and_fetch_word_imm8(emu, &shift);
  4771. }
  4772. if (shift_left)
  4773. destval = shld_word(emu, destval, *shiftreg, shift);
  4774. else
  4775. destval = shrd_word(emu, destval, *shiftreg, shift);
  4776. write_back_word(emu, destval);
  4777. }
  4778. static void
  4779. common_shift(struct x86emu *emu, int shift_left, int use_cl)
  4780. {
  4781. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  4782. common_shift32(emu, shift_left, use_cl);
  4783. else
  4784. common_shift16(emu, shift_left, use_cl);
  4785. }
  4786. /*
  4787. * Implementation
  4788. */
  4789. #define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
  4790. /*
  4791. * REMARKS:
  4792. * Handles opcode 0x0f,0x31
  4793. */
  4794. static void
  4795. x86emuOp2_rdtsc(struct x86emu *emu)
  4796. {
  4797. emu->x86.R_EAX = emu->cur_cycles & 0xffffffff;
  4798. emu->x86.R_EDX = emu->cur_cycles >> 32;
  4799. }
  4800. /*
  4801. * REMARKS:
  4802. * Handles opcode 0x0f,0xa0
  4803. */
  4804. static void
  4805. x86emuOp2_push_FS(struct x86emu *emu)
  4806. {
  4807. push_word(emu, emu->x86.R_FS);
  4808. }
  4809. /*
  4810. * REMARKS:
  4811. * Handles opcode 0x0f,0xa1
  4812. */
  4813. static void
  4814. x86emuOp2_pop_FS(struct x86emu *emu)
  4815. {
  4816. emu->x86.R_FS = pop_word(emu);
  4817. }
  4818. /*
  4819. * REMARKS:
  4820. * Handles opcode 0x0f,0xa1
  4821. */
  4822. #if defined(__i386__) || defined(__amd64__)
  4823. static void
  4824. hw_cpuid(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
  4825. {
  4826. __asm__ volatile("cpuid"
  4827. : "=a" (*a), "=b" (*b),
  4828. "=c" (*c), "=d" (*d)
  4829. : "a" (*a), "c" (*c)
  4830. : "cc");
  4831. }
  4832. #endif
  4833. static void
  4834. x86emuOp2_cpuid(struct x86emu *emu)
  4835. {
  4836. #if defined(__i386__) || defined(__amd64__)
  4837. hw_cpuid(&emu->x86.R_EAX, &emu->x86.R_EBX, &emu->x86.R_ECX,
  4838. &emu->x86.R_EDX);
  4839. #endif
  4840. switch (emu->x86.R_EAX) {
  4841. case 0:
  4842. emu->x86.R_EAX = 1;
  4843. #if !defined(__i386__) && !defined(__amd64__)
  4844. /* "GenuineIntel" */
  4845. emu->x86.R_EBX = 0x756e6547;
  4846. emu->x86.R_EDX = 0x49656e69;
  4847. emu->x86.R_ECX = 0x6c65746e;
  4848. #endif
  4849. break;
  4850. case 1:
  4851. #if !defined(__i386__) && !defined(__amd64__)
  4852. emu->x86.R_EAX = 0x00000480;
  4853. emu->x86.R_EBX = emu->x86.R_ECX = 0;
  4854. emu->x86.R_EDX = 0x00000002;
  4855. #else
  4856. emu->x86.R_EDX &= 0x00000012;
  4857. #endif
  4858. break;
  4859. default:
  4860. emu->x86.R_EAX = emu->x86.R_EBX = emu->x86.R_ECX =
  4861. emu->x86.R_EDX = 0;
  4862. break;
  4863. }
  4864. }
  4865. /*
  4866. * REMARKS:
  4867. * Handles opcode 0x0f,0xa3
  4868. */
  4869. static void
  4870. x86emuOp2_bt_R(struct x86emu *emu)
  4871. {
  4872. common_bitstring(emu, 0);
  4873. }
  4874. /*
  4875. * REMARKS:
  4876. * Handles opcode 0x0f,0xa4
  4877. */
  4878. static void
  4879. x86emuOp2_shld_IMM(struct x86emu *emu)
  4880. {
  4881. common_shift(emu, 1, 0);
  4882. }
  4883. /*
  4884. * REMARKS:
  4885. * Handles opcode 0x0f,0xa5
  4886. */
  4887. static void
  4888. x86emuOp2_shld_CL(struct x86emu *emu)
  4889. {
  4890. common_shift(emu, 1, 1);
  4891. }
  4892. /*
  4893. * REMARKS:
  4894. * Handles opcode 0x0f,0xa8
  4895. */
  4896. static void
  4897. x86emuOp2_push_GS(struct x86emu *emu)
  4898. {
  4899. push_word(emu, emu->x86.R_GS);
  4900. }
  4901. /*
  4902. * REMARKS:
  4903. * Handles opcode 0x0f,0xa9
  4904. */
  4905. static void
  4906. x86emuOp2_pop_GS(struct x86emu *emu)
  4907. {
  4908. emu->x86.R_GS = pop_word(emu);
  4909. }
  4910. /*
  4911. * REMARKS:
  4912. * Handles opcode 0x0f,0xab
  4913. */
  4914. static void
  4915. x86emuOp2_bts_R(struct x86emu *emu)
  4916. {
  4917. common_bitstring(emu, 1);
  4918. }
  4919. /*
  4920. * REMARKS:
  4921. * Handles opcode 0x0f,0xac
  4922. */
  4923. static void
  4924. x86emuOp2_shrd_IMM(struct x86emu *emu)
  4925. {
  4926. common_shift(emu, 0, 0);
  4927. }
  4928. /*
  4929. * REMARKS:
  4930. * Handles opcode 0x0f,0xad
  4931. */
  4932. static void
  4933. x86emuOp2_shrd_CL(struct x86emu *emu)
  4934. {
  4935. common_shift(emu, 0, 1);
  4936. }
  4937. /*
  4938. * REMARKS:
  4939. * Handles opcode 0x0f,0xaf
  4940. */
  4941. static void
  4942. x86emuOp2_32_imul_R_RM(struct x86emu *emu)
  4943. {
  4944. uint32_t *destreg, srcval;
  4945. uint64_t res;
  4946. fetch_decode_modrm(emu);
  4947. destreg = decode_rh_long_register(emu);
  4948. srcval = decode_and_fetch_long(emu);
  4949. res = (int32_t) *destreg * (int32_t)srcval;
  4950. if (res > 0xffffffff) {
  4951. SET_FLAG(F_CF);
  4952. SET_FLAG(F_OF);
  4953. } else {
  4954. CLEAR_FLAG(F_CF);
  4955. CLEAR_FLAG(F_OF);
  4956. }
  4957. *destreg = (uint32_t) res;
  4958. }
  4959. static void
  4960. x86emuOp2_16_imul_R_RM(struct x86emu *emu)
  4961. {
  4962. uint16_t *destreg, srcval;
  4963. uint32_t res;
  4964. fetch_decode_modrm(emu);
  4965. destreg = decode_rh_word_register(emu);
  4966. srcval = decode_and_fetch_word(emu);
  4967. res = (int16_t) * destreg * (int16_t)srcval;
  4968. if (res > 0xFFFF) {
  4969. SET_FLAG(F_CF);
  4970. SET_FLAG(F_OF);
  4971. } else {
  4972. CLEAR_FLAG(F_CF);
  4973. CLEAR_FLAG(F_OF);
  4974. }
  4975. *destreg = (uint16_t) res;
  4976. }
  4977. static void
  4978. x86emuOp2_imul_R_RM(struct x86emu *emu)
  4979. {
  4980. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  4981. x86emuOp2_32_imul_R_RM(emu);
  4982. else
  4983. x86emuOp2_16_imul_R_RM(emu);
  4984. }
  4985. /*
  4986. * REMARKS:
  4987. * Handles opcode 0x0f,0xb2
  4988. */
  4989. static void
  4990. x86emuOp2_lss_R_IMM(struct x86emu *emu)
  4991. {
  4992. common_load_far_pointer(emu, &emu->x86.R_SS);
  4993. }
  4994. /*
  4995. * REMARKS:
  4996. * Handles opcode 0x0f,0xb3
  4997. */
  4998. static void
  4999. x86emuOp2_btr_R(struct x86emu *emu)
  5000. {
  5001. common_bitstring(emu, 2);
  5002. }
  5003. /*
  5004. * REMARKS:
  5005. * Handles opcode 0x0f,0xb4
  5006. */
  5007. static void
  5008. x86emuOp2_lfs_R_IMM(struct x86emu *emu)
  5009. {
  5010. common_load_far_pointer(emu, &emu->x86.R_FS);
  5011. }
  5012. /*
  5013. * REMARKS:
  5014. * Handles opcode 0x0f,0xb5
  5015. */
  5016. static void
  5017. x86emuOp2_lgs_R_IMM(struct x86emu *emu)
  5018. {
  5019. common_load_far_pointer(emu, &emu->x86.R_GS);
  5020. }
  5021. /*
  5022. * REMARKS:
  5023. * Handles opcode 0x0f,0xb6
  5024. */
  5025. static void
  5026. x86emuOp2_32_movzx_byte_R_RM(struct x86emu *emu)
  5027. {
  5028. uint32_t *destreg;
  5029. fetch_decode_modrm(emu);
  5030. destreg = decode_rh_long_register(emu);
  5031. *destreg = decode_and_fetch_byte(emu);
  5032. }
  5033. static void
  5034. x86emuOp2_16_movzx_byte_R_RM(struct x86emu *emu)
  5035. {
  5036. uint16_t *destreg;
  5037. fetch_decode_modrm(emu);
  5038. destreg = decode_rh_word_register(emu);
  5039. *destreg = decode_and_fetch_byte(emu);
  5040. }
  5041. static void
  5042. x86emuOp2_movzx_byte_R_RM(struct x86emu *emu)
  5043. {
  5044. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  5045. x86emuOp2_32_movzx_byte_R_RM(emu);
  5046. else
  5047. x86emuOp2_16_movzx_byte_R_RM(emu);
  5048. }
  5049. /*
  5050. * REMARKS:
  5051. * Handles opcode 0x0f,0xb7
  5052. */
  5053. static void
  5054. x86emuOp2_movzx_word_R_RM(struct x86emu *emu)
  5055. {
  5056. uint32_t *destreg;
  5057. fetch_decode_modrm(emu);
  5058. destreg = decode_rh_long_register(emu);
  5059. *destreg = decode_and_fetch_word(emu);
  5060. }
  5061. /*
  5062. * REMARKS:
  5063. * Handles opcode 0x0f,0xba
  5064. */
  5065. static void
  5066. x86emuOp2_32_btX_I(struct x86emu *emu)
  5067. {
  5068. int bit;
  5069. uint32_t srcval, mask;
  5070. uint8_t shift;
  5071. fetch_decode_modrm(emu);
  5072. if (emu->cur_rh < 4)
  5073. x86emu_halt_sys(emu);
  5074. srcval = decode_and_fetch_long_imm8(emu, &shift);
  5075. bit = shift & 0x1F;
  5076. mask = (0x1 << bit);
  5077. switch (emu->cur_rh) {
  5078. case 5:
  5079. write_back_long(emu, srcval | mask);
  5080. break;
  5081. case 6:
  5082. write_back_long(emu, srcval & ~mask);
  5083. break;
  5084. case 7:
  5085. write_back_long(emu, srcval ^ mask);
  5086. break;
  5087. }
  5088. CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
  5089. }
  5090. static void
  5091. x86emuOp2_16_btX_I(struct x86emu *emu)
  5092. {
  5093. int bit;
  5094. uint16_t srcval, mask;
  5095. uint8_t shift;
  5096. fetch_decode_modrm(emu);
  5097. if (emu->cur_rh < 4)
  5098. x86emu_halt_sys(emu);
  5099. srcval = decode_and_fetch_word_imm8(emu, &shift);
  5100. bit = shift & 0xF;
  5101. mask = (0x1 << bit);
  5102. switch (emu->cur_rh) {
  5103. case 5:
  5104. write_back_word(emu, srcval | mask);
  5105. break;
  5106. case 6:
  5107. write_back_word(emu, srcval & ~mask);
  5108. break;
  5109. case 7:
  5110. write_back_word(emu, srcval ^ mask);
  5111. break;
  5112. }
  5113. CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
  5114. }
  5115. static void
  5116. x86emuOp2_btX_I(struct x86emu *emu)
  5117. {
  5118. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  5119. x86emuOp2_32_btX_I(emu);
  5120. else
  5121. x86emuOp2_16_btX_I(emu);
  5122. }
  5123. /*
  5124. * REMARKS:
  5125. * Handles opcode 0x0f,0xbb
  5126. */
  5127. static void
  5128. x86emuOp2_btc_R(struct x86emu *emu)
  5129. {
  5130. common_bitstring(emu, 3);
  5131. }
  5132. /*
  5133. * REMARKS:
  5134. * Handles opcode 0x0f,0xbc
  5135. */
  5136. static void
  5137. x86emuOp2_bsf(struct x86emu *emu)
  5138. {
  5139. common_bitsearch(emu, +1);
  5140. }
  5141. /*
  5142. * REMARKS:
  5143. * Handles opcode 0x0f,0xbd
  5144. */
  5145. static void
  5146. x86emuOp2_bsr(struct x86emu *emu)
  5147. {
  5148. common_bitsearch(emu, -1);
  5149. }
  5150. /*
  5151. * REMARKS:
  5152. * Handles opcode 0x0f,0xbe
  5153. */
  5154. static void
  5155. x86emuOp2_32_movsx_byte_R_RM(struct x86emu *emu)
  5156. {
  5157. uint32_t *destreg;
  5158. fetch_decode_modrm(emu);
  5159. destreg = decode_rh_long_register(emu);
  5160. *destreg = (int32_t)(int8_t)decode_and_fetch_byte(emu);
  5161. }
  5162. static void
  5163. x86emuOp2_16_movsx_byte_R_RM(struct x86emu *emu)
  5164. {
  5165. uint16_t *destreg;
  5166. fetch_decode_modrm(emu);
  5167. destreg = decode_rh_word_register(emu);
  5168. *destreg = (int16_t)(int8_t)decode_and_fetch_byte(emu);
  5169. }
  5170. static void
  5171. x86emuOp2_movsx_byte_R_RM(struct x86emu *emu)
  5172. {
  5173. if (emu->x86.mode & SYSMODE_PREFIX_DATA)
  5174. x86emuOp2_32_movsx_byte_R_RM(emu);
  5175. else
  5176. x86emuOp2_16_movsx_byte_R_RM(emu);
  5177. }
  5178. /*
  5179. * REMARKS:
  5180. * Handles opcode 0x0f,0xbf
  5181. */
  5182. static void
  5183. x86emuOp2_movsx_word_R_RM(struct x86emu *emu)
  5184. {
  5185. uint32_t *destreg;
  5186. fetch_decode_modrm(emu);
  5187. destreg = decode_rh_long_register(emu);
  5188. *destreg = (int32_t)(int16_t)decode_and_fetch_word(emu);
  5189. }
  5190. static void
  5191. x86emu_exec_two_byte(struct x86emu * emu)
  5192. {
  5193. uint8_t op2;
  5194. op2 = fetch_byte_imm(emu);
  5195. switch (op2) {
  5196. /* 0x00 Group F (ring 0 PM) */
  5197. /* 0x01 Group G (ring 0 PM) */
  5198. /* 0x02 lar (ring 0 PM) */
  5199. /* 0x03 lsl (ring 0 PM) */
  5200. /* 0x05 loadall (undocumented) */
  5201. /* 0x06 clts (ring 0 PM) */
  5202. /* 0x07 loadall (undocumented) */
  5203. /* 0x08 invd (ring 0 PM) */
  5204. /* 0x09 wbinvd (ring 0 PM) */
  5205. /* 0x20 mov reg32(op2); break;creg (ring 0 PM) */
  5206. /* 0x21 mov reg32(op2); break;dreg (ring 0 PM) */
  5207. /* 0x22 mov creg(op2); break;reg32 (ring 0 PM) */
  5208. /* 0x23 mov dreg(op2); break;reg32 (ring 0 PM) */
  5209. /* 0x24 mov reg32(op2); break;treg (ring 0 PM) */
  5210. /* 0x26 mov treg(op2); break;reg32 (ring 0 PM) */
  5211. case 0x31:
  5212. x86emuOp2_rdtsc(emu);
  5213. break;
  5214. case 0x80:
  5215. common_jmp_long(emu, ACCESS_FLAG(F_OF));
  5216. break;
  5217. case 0x81:
  5218. common_jmp_long(emu, !ACCESS_FLAG(F_OF));
  5219. break;
  5220. case 0x82:
  5221. common_jmp_long(emu, ACCESS_FLAG(F_CF));
  5222. break;
  5223. case 0x83:
  5224. common_jmp_long(emu, !ACCESS_FLAG(F_CF));
  5225. break;
  5226. case 0x84:
  5227. common_jmp_long(emu, ACCESS_FLAG(F_ZF));
  5228. break;
  5229. case 0x85:
  5230. common_jmp_long(emu, !ACCESS_FLAG(F_ZF));
  5231. break;
  5232. case 0x86:
  5233. common_jmp_long(emu, ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
  5234. break;
  5235. case 0x87:
  5236. common_jmp_long(emu, !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)));
  5237. break;
  5238. case 0x88:
  5239. common_jmp_long(emu, ACCESS_FLAG(F_SF));
  5240. break;
  5241. case 0x89:
  5242. common_jmp_long(emu, !ACCESS_FLAG(F_SF));
  5243. break;
  5244. case 0x8a:
  5245. common_jmp_long(emu, ACCESS_FLAG(F_PF));
  5246. break;
  5247. case 0x8b:
  5248. common_jmp_long(emu, !ACCESS_FLAG(F_PF));
  5249. break;
  5250. case 0x8c:
  5251. common_jmp_long(emu, xorl(ACCESS_FLAG(F_SF),
  5252. ACCESS_FLAG(F_OF)));
  5253. break;
  5254. case 0x8d:
  5255. common_jmp_long(emu, !(xorl(ACCESS_FLAG(F_SF),
  5256. ACCESS_FLAG(F_OF))));
  5257. break;
  5258. case 0x8e:
  5259. common_jmp_long(emu, (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF))
  5260. || ACCESS_FLAG(F_ZF)));
  5261. break;
  5262. case 0x8f:
  5263. common_jmp_long(emu,
  5264. !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
  5265. ACCESS_FLAG(F_ZF)));
  5266. break;
  5267. case 0x90:
  5268. common_set_byte(emu, ACCESS_FLAG(F_OF));
  5269. break;
  5270. case 0x91:
  5271. common_set_byte(emu, !ACCESS_FLAG(F_OF));
  5272. break;
  5273. case 0x92:
  5274. common_set_byte(emu, ACCESS_FLAG(F_CF));
  5275. break;
  5276. case 0x93:
  5277. common_set_byte(emu, !ACCESS_FLAG(F_CF));
  5278. break;
  5279. case 0x94:
  5280. common_set_byte(emu, ACCESS_FLAG(F_ZF));
  5281. break;
  5282. case 0x95:
  5283. common_set_byte(emu, !ACCESS_FLAG(F_ZF));
  5284. break;
  5285. case 0x96:
  5286. common_set_byte(emu, ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
  5287. break;
  5288. case 0x97:
  5289. common_set_byte(emu, !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)));
  5290. break;
  5291. case 0x98:
  5292. common_set_byte(emu, ACCESS_FLAG(F_SF));
  5293. break;
  5294. case 0x99:
  5295. common_set_byte(emu, !ACCESS_FLAG(F_SF));
  5296. break;
  5297. case 0x9a:
  5298. common_set_byte(emu, ACCESS_FLAG(F_PF));
  5299. break;
  5300. case 0x9b:
  5301. common_set_byte(emu, !ACCESS_FLAG(F_PF));
  5302. break;
  5303. case 0x9c:
  5304. common_set_byte(emu, xorl(ACCESS_FLAG(F_SF),
  5305. ACCESS_FLAG(F_OF)));
  5306. break;
  5307. case 0x9d:
  5308. common_set_byte(emu, xorl(ACCESS_FLAG(F_SF),
  5309. ACCESS_FLAG(F_OF)));
  5310. break;
  5311. case 0x9e:
  5312. common_set_byte(emu,
  5313. (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
  5314. ACCESS_FLAG(F_ZF)));
  5315. break;
  5316. case 0x9f:
  5317. common_set_byte(emu,
  5318. !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
  5319. ACCESS_FLAG(F_ZF)));
  5320. break;
  5321. case 0xa0:
  5322. x86emuOp2_push_FS(emu);
  5323. break;
  5324. case 0xa1:
  5325. x86emuOp2_pop_FS(emu);
  5326. break;
  5327. case 0xa2:
  5328. x86emuOp2_cpuid(emu);
  5329. break;
  5330. case 0xa3:
  5331. x86emuOp2_bt_R(emu);
  5332. break;
  5333. case 0xa4:
  5334. x86emuOp2_shld_IMM(emu);
  5335. break;
  5336. case 0xa5:
  5337. x86emuOp2_shld_CL(emu);
  5338. break;
  5339. case 0xa8:
  5340. x86emuOp2_push_GS(emu);
  5341. break;
  5342. case 0xa9:
  5343. x86emuOp2_pop_GS(emu);
  5344. break;
  5345. case 0xab:
  5346. x86emuOp2_bts_R(emu);
  5347. break;
  5348. case 0xac:
  5349. x86emuOp2_shrd_IMM(emu);
  5350. break;
  5351. case 0xad:
  5352. x86emuOp2_shrd_CL(emu);
  5353. break;
  5354. case 0xaf:
  5355. x86emuOp2_imul_R_RM(emu);
  5356. break;
  5357. /* 0xb0 TODO: cmpxchg */
  5358. /* 0xb1 TODO: cmpxchg */
  5359. case 0xb2:
  5360. x86emuOp2_lss_R_IMM(emu);
  5361. break;
  5362. case 0xb3:
  5363. x86emuOp2_btr_R(emu);
  5364. break;
  5365. case 0xb4:
  5366. x86emuOp2_lfs_R_IMM(emu);
  5367. break;
  5368. case 0xb5:
  5369. x86emuOp2_lgs_R_IMM(emu);
  5370. break;
  5371. case 0xb6:
  5372. x86emuOp2_movzx_byte_R_RM(emu);
  5373. break;
  5374. case 0xb7:
  5375. x86emuOp2_movzx_word_R_RM(emu);
  5376. break;
  5377. case 0xba:
  5378. x86emuOp2_btX_I(emu);
  5379. break;
  5380. case 0xbb:
  5381. x86emuOp2_btc_R(emu);
  5382. break;
  5383. case 0xbc:
  5384. x86emuOp2_bsf(emu);
  5385. break;
  5386. case 0xbd:
  5387. x86emuOp2_bsr(emu);
  5388. break;
  5389. case 0xbe:
  5390. x86emuOp2_movsx_byte_R_RM(emu);
  5391. break;
  5392. case 0xbf:
  5393. x86emuOp2_movsx_word_R_RM(emu);
  5394. break;
  5395. /* 0xc0 TODO: xadd */
  5396. /* 0xc1 TODO: xadd */
  5397. /* 0xc8 TODO: bswap */
  5398. /* 0xc9 TODO: bswap */
  5399. /* 0xca TODO: bswap */
  5400. /* 0xcb TODO: bswap */
  5401. /* 0xcc TODO: bswap */
  5402. /* 0xcd TODO: bswap */
  5403. /* 0xce TODO: bswap */
  5404. /* 0xcf TODO: bswap */
  5405. default:
  5406. x86emu_halt_sys(emu);
  5407. break;
  5408. }
  5409. }
  5410. /*
  5411. * Carry Chain Calculation
  5412. *
  5413. * This represents a somewhat expensive calculation which is
  5414. * apparently required to emulate the setting of the OF and AF flag.
  5415. * The latter is not so important, but the former is. The overflow
  5416. * flag is the XOR of the top two bits of the carry chain for an
  5417. * addition (similar for subtraction). Since we do not want to
  5418. * simulate the addition in a bitwise manner, we try to calculate the
  5419. * carry chain given the two operands and the result.
  5420. *
  5421. * So, given the following table, which represents the addition of two
  5422. * bits, we can derive a formula for the carry chain.
  5423. *
  5424. * a b cin r cout
  5425. * 0 0 0 0 0
  5426. * 0 0 1 1 0
  5427. * 0 1 0 1 0
  5428. * 0 1 1 0 1
  5429. * 1 0 0 1 0
  5430. * 1 0 1 0 1
  5431. * 1 1 0 0 1
  5432. * 1 1 1 1 1
  5433. *
  5434. * Construction of table for cout:
  5435. *
  5436. * ab
  5437. * r \ 00 01 11 10
  5438. * |------------------
  5439. * 0 | 0 1 1 1
  5440. * 1 | 0 0 1 0
  5441. *
  5442. * By inspection, one gets: cc = ab + r'(a + b)
  5443. *
  5444. * That represents alot of operations, but NO CHOICE....
  5445. *
  5446. * Borrow Chain Calculation.
  5447. *
  5448. * The following table represents the subtraction of two bits, from
  5449. * which we can derive a formula for the borrow chain.
  5450. *
  5451. * a b bin r bout
  5452. * 0 0 0 0 0
  5453. * 0 0 1 1 1
  5454. * 0 1 0 1 1
  5455. * 0 1 1 0 1
  5456. * 1 0 0 1 0
  5457. * 1 0 1 0 0
  5458. * 1 1 0 0 0
  5459. * 1 1 1 1 1
  5460. *
  5461. * Construction of table for cout:
  5462. *
  5463. * ab
  5464. * r \ 00 01 11 10
  5465. * |------------------
  5466. * 0 | 0 1 0 0
  5467. * 1 | 1 1 1 0
  5468. *
  5469. * By inspection, one gets: bc = a'b + r(a' + b)
  5470. *
  5471. */
  5472. /*
  5473. * Global Variables
  5474. */
  5475. static uint32_t x86emu_parity_tab[8] =
  5476. {
  5477. 0x96696996,
  5478. 0x69969669,
  5479. 0x69969669,
  5480. 0x96696996,
  5481. 0x69969669,
  5482. 0x96696996,
  5483. 0x96696996,
  5484. 0x69969669,
  5485. };
  5486. #define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
  5487. #define XOR2(x) (((x) ^ ((x)>>1)) & 0x1)
  5488. /*
  5489. * REMARKS:
  5490. * Implements the AAA instruction and side effects.
  5491. */
  5492. static uint16_t
  5493. aaa_word(struct x86emu *emu, uint16_t d)
  5494. {
  5495. uint16_t res;
  5496. if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
  5497. d += 0x6;
  5498. d += 0x100;
  5499. SET_FLAG(F_AF);
  5500. SET_FLAG(F_CF);
  5501. } else {
  5502. CLEAR_FLAG(F_CF);
  5503. CLEAR_FLAG(F_AF);
  5504. }
  5505. res = (uint16_t) (d & 0xFF0F);
  5506. CLEAR_FLAG(F_SF);
  5507. CONDITIONAL_SET_FLAG(res == 0, F_ZF);
  5508. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5509. return res;
  5510. }
  5511. /*
  5512. * REMARKS:
  5513. * Implements the AAA instruction and side effects.
  5514. */
  5515. static uint16_t
  5516. aas_word(struct x86emu *emu, uint16_t d)
  5517. {
  5518. uint16_t res;
  5519. if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
  5520. d -= 0x6;
  5521. d -= 0x100;
  5522. SET_FLAG(F_AF);
  5523. SET_FLAG(F_CF);
  5524. } else {
  5525. CLEAR_FLAG(F_CF);
  5526. CLEAR_FLAG(F_AF);
  5527. }
  5528. res = (uint16_t) (d & 0xFF0F);
  5529. CLEAR_FLAG(F_SF);
  5530. CONDITIONAL_SET_FLAG(res == 0, F_ZF);
  5531. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5532. return res;
  5533. }
  5534. /*
  5535. * REMARKS:
  5536. * Implements the AAD instruction and side effects.
  5537. */
  5538. static uint16_t
  5539. aad_word(struct x86emu *emu, uint16_t d)
  5540. {
  5541. uint16_t l;
  5542. uint8_t hb, lb;
  5543. hb = (uint8_t) ((d >> 8) & 0xff);
  5544. lb = (uint8_t) ((d & 0xff));
  5545. l = (uint16_t) ((lb + 10 * hb) & 0xFF);
  5546. CLEAR_FLAG(F_CF);
  5547. CLEAR_FLAG(F_AF);
  5548. CLEAR_FLAG(F_OF);
  5549. CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
  5550. CONDITIONAL_SET_FLAG(l == 0, F_ZF);
  5551. CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
  5552. return l;
  5553. }
  5554. /*
  5555. * REMARKS:
  5556. * Implements the AAM instruction and side effects.
  5557. */
  5558. static uint16_t
  5559. aam_word(struct x86emu *emu, uint8_t d)
  5560. {
  5561. uint16_t h, l;
  5562. h = (uint16_t) (d / 10);
  5563. l = (uint16_t) (d % 10);
  5564. l |= (uint16_t) (h << 8);
  5565. CLEAR_FLAG(F_CF);
  5566. CLEAR_FLAG(F_AF);
  5567. CLEAR_FLAG(F_OF);
  5568. CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
  5569. CONDITIONAL_SET_FLAG(l == 0, F_ZF);
  5570. CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
  5571. return l;
  5572. }
  5573. /*
  5574. * REMARKS:
  5575. * Implements the ADC instruction and side effects.
  5576. */
  5577. static uint8_t
  5578. adc_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  5579. {
  5580. uint32_t res; /* all operands in native machine order */
  5581. uint32_t cc;
  5582. if (ACCESS_FLAG(F_CF))
  5583. res = 1 + d + s;
  5584. else
  5585. res = d + s;
  5586. CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
  5587. CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
  5588. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  5589. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5590. /* calculate the carry chain SEE NOTE AT TOP. */
  5591. cc = (s & d) | ((~res) & (s | d));
  5592. CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
  5593. CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
  5594. return (uint8_t) res;
  5595. }
  5596. /*
  5597. * REMARKS:
  5598. * Implements the ADC instruction and side effects.
  5599. */
  5600. static uint16_t
  5601. adc_word(struct x86emu *emu, uint16_t d, uint16_t s)
  5602. {
  5603. uint32_t res; /* all operands in native machine order */
  5604. uint32_t cc;
  5605. if (ACCESS_FLAG(F_CF))
  5606. res = 1 + d + s;
  5607. else
  5608. res = d + s;
  5609. CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
  5610. CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
  5611. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  5612. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5613. /* calculate the carry chain SEE NOTE AT TOP. */
  5614. cc = (s & d) | ((~res) & (s | d));
  5615. CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
  5616. CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
  5617. return (uint16_t) res;
  5618. }
  5619. /*
  5620. * REMARKS:
  5621. * Implements the ADC instruction and side effects.
  5622. */
  5623. static uint32_t
  5624. adc_long(struct x86emu *emu, uint32_t d, uint32_t s)
  5625. {
  5626. uint32_t lo; /* all operands in native machine order */
  5627. uint32_t hi;
  5628. uint32_t res;
  5629. uint32_t cc;
  5630. if (ACCESS_FLAG(F_CF)) {
  5631. lo = 1 + (d & 0xFFFF) + (s & 0xFFFF);
  5632. res = 1 + d + s;
  5633. } else {
  5634. lo = (d & 0xFFFF) + (s & 0xFFFF);
  5635. res = d + s;
  5636. }
  5637. hi = (lo >> 16) + (d >> 16) + (s >> 16);
  5638. CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
  5639. CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
  5640. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  5641. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5642. /* calculate the carry chain SEE NOTE AT TOP. */
  5643. cc = (s & d) | ((~res) & (s | d));
  5644. CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
  5645. CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
  5646. return res;
  5647. }
  5648. /*
  5649. * REMARKS:
  5650. * Implements the ADD instruction and side effects.
  5651. */
  5652. static uint8_t
  5653. add_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  5654. {
  5655. uint32_t res; /* all operands in native machine order */
  5656. uint32_t cc;
  5657. res = d + s;
  5658. CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
  5659. CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
  5660. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  5661. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5662. /* calculate the carry chain SEE NOTE AT TOP. */
  5663. cc = (s & d) | ((~res) & (s | d));
  5664. CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
  5665. CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
  5666. return (uint8_t) res;
  5667. }
  5668. /*
  5669. * REMARKS:
  5670. * Implements the ADD instruction and side effects.
  5671. */
  5672. static uint16_t
  5673. add_word(struct x86emu *emu, uint16_t d, uint16_t s)
  5674. {
  5675. uint32_t res; /* all operands in native machine order */
  5676. uint32_t cc;
  5677. res = d + s;
  5678. CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
  5679. CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
  5680. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  5681. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5682. /* calculate the carry chain SEE NOTE AT TOP. */
  5683. cc = (s & d) | ((~res) & (s | d));
  5684. CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
  5685. CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
  5686. return (uint16_t) res;
  5687. }
  5688. /*
  5689. * REMARKS:
  5690. * Implements the ADD instruction and side effects.
  5691. */
  5692. static uint32_t
  5693. add_long(struct x86emu *emu, uint32_t d, uint32_t s)
  5694. {
  5695. uint32_t lo; /* all operands in native machine order */
  5696. uint32_t hi;
  5697. uint32_t res;
  5698. uint32_t cc;
  5699. lo = (d & 0xFFFF) + (s & 0xFFFF);
  5700. res = d + s;
  5701. hi = (lo >> 16) + (d >> 16) + (s >> 16);
  5702. CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
  5703. CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
  5704. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  5705. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5706. /* calculate the carry chain SEE NOTE AT TOP. */
  5707. cc = (s & d) | ((~res) & (s | d));
  5708. CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
  5709. CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
  5710. return res;
  5711. }
  5712. /*
  5713. * REMARKS:
  5714. * Implements the AND instruction and side effects.
  5715. */
  5716. static uint8_t
  5717. and_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  5718. {
  5719. uint8_t res; /* all operands in native machine order */
  5720. res = d & s;
  5721. /* set the flags */
  5722. CLEAR_FLAG(F_OF);
  5723. CLEAR_FLAG(F_CF);
  5724. CLEAR_FLAG(F_AF);
  5725. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  5726. CONDITIONAL_SET_FLAG(res == 0, F_ZF);
  5727. CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
  5728. return res;
  5729. }
  5730. /*
  5731. * REMARKS:
  5732. * Implements the AND instruction and side effects.
  5733. */
  5734. static uint16_t
  5735. and_word(struct x86emu *emu, uint16_t d, uint16_t s)
  5736. {
  5737. uint16_t res; /* all operands in native machine order */
  5738. res = d & s;
  5739. /* set the flags */
  5740. CLEAR_FLAG(F_OF);
  5741. CLEAR_FLAG(F_CF);
  5742. CLEAR_FLAG(F_AF);
  5743. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  5744. CONDITIONAL_SET_FLAG(res == 0, F_ZF);
  5745. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5746. return res;
  5747. }
  5748. /*
  5749. * REMARKS:
  5750. * Implements the AND instruction and side effects.
  5751. */
  5752. static uint32_t
  5753. and_long(struct x86emu *emu, uint32_t d, uint32_t s)
  5754. {
  5755. uint32_t res; /* all operands in native machine order */
  5756. res = d & s;
  5757. /* set the flags */
  5758. CLEAR_FLAG(F_OF);
  5759. CLEAR_FLAG(F_CF);
  5760. CLEAR_FLAG(F_AF);
  5761. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  5762. CONDITIONAL_SET_FLAG(res == 0, F_ZF);
  5763. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5764. return res;
  5765. }
  5766. /*
  5767. * REMARKS:
  5768. * Implements the CMP instruction and side effects.
  5769. */
  5770. static uint8_t
  5771. cmp_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  5772. {
  5773. uint32_t res; /* all operands in native machine order */
  5774. uint32_t bc;
  5775. res = d - s;
  5776. CLEAR_FLAG(F_CF);
  5777. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  5778. CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
  5779. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5780. /* calculate the borrow chain. See note at top */
  5781. bc = (res & (~d | s)) | (~d & s);
  5782. CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
  5783. CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
  5784. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  5785. return d;
  5786. }
  5787. static void
  5788. cmp_byte_no_return(struct x86emu *emu, uint8_t d, uint8_t s)
  5789. {
  5790. cmp_byte(emu, d, s);
  5791. }
  5792. /*
  5793. * REMARKS:
  5794. * Implements the CMP instruction and side effects.
  5795. */
  5796. static uint16_t
  5797. cmp_word(struct x86emu *emu, uint16_t d, uint16_t s)
  5798. {
  5799. uint32_t res; /* all operands in native machine order */
  5800. uint32_t bc;
  5801. res = d - s;
  5802. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  5803. CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
  5804. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5805. /* calculate the borrow chain. See note at top */
  5806. bc = (res & (~d | s)) | (~d & s);
  5807. CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
  5808. CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
  5809. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  5810. return d;
  5811. }
  5812. static void
  5813. cmp_word_no_return(struct x86emu *emu, uint16_t d, uint16_t s)
  5814. {
  5815. cmp_word(emu, d, s);
  5816. }
  5817. /*
  5818. * REMARKS:
  5819. * Implements the CMP instruction and side effects.
  5820. */
  5821. static uint32_t
  5822. cmp_long(struct x86emu *emu, uint32_t d, uint32_t s)
  5823. {
  5824. uint32_t res; /* all operands in native machine order */
  5825. uint32_t bc;
  5826. res = d - s;
  5827. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  5828. CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
  5829. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5830. /* calculate the borrow chain. See note at top */
  5831. bc = (res & (~d | s)) | (~d & s);
  5832. CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
  5833. CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
  5834. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  5835. return d;
  5836. }
  5837. static void
  5838. cmp_long_no_return(struct x86emu *emu, uint32_t d, uint32_t s)
  5839. {
  5840. cmp_long(emu, d, s);
  5841. }
  5842. /*
  5843. * REMARKS:
  5844. * Implements the DAA instruction and side effects.
  5845. */
  5846. static uint8_t
  5847. daa_byte(struct x86emu *emu, uint8_t d)
  5848. {
  5849. uint32_t res = d;
  5850. if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
  5851. res += 6;
  5852. SET_FLAG(F_AF);
  5853. }
  5854. if (res > 0x9F || ACCESS_FLAG(F_CF)) {
  5855. res += 0x60;
  5856. SET_FLAG(F_CF);
  5857. }
  5858. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  5859. CONDITIONAL_SET_FLAG((res & 0xFF) == 0, F_ZF);
  5860. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5861. return (uint8_t) res;
  5862. }
  5863. /*
  5864. * REMARKS:
  5865. * Implements the DAS instruction and side effects.
  5866. */
  5867. static uint8_t
  5868. das_byte(struct x86emu *emu, uint8_t d)
  5869. {
  5870. if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
  5871. d -= 6;
  5872. SET_FLAG(F_AF);
  5873. }
  5874. if (d > 0x9F || ACCESS_FLAG(F_CF)) {
  5875. d -= 0x60;
  5876. SET_FLAG(F_CF);
  5877. }
  5878. CONDITIONAL_SET_FLAG(d & 0x80, F_SF);
  5879. CONDITIONAL_SET_FLAG(d == 0, F_ZF);
  5880. CONDITIONAL_SET_FLAG(PARITY(d & 0xff), F_PF);
  5881. return d;
  5882. }
  5883. /*
  5884. * REMARKS:
  5885. * Implements the DEC instruction and side effects.
  5886. */
  5887. static uint8_t
  5888. dec_byte(struct x86emu *emu, uint8_t d)
  5889. {
  5890. uint32_t res; /* all operands in native machine order */
  5891. uint32_t bc;
  5892. res = d - 1;
  5893. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  5894. CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
  5895. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5896. /* calculate the borrow chain. See note at top */
  5897. /* based on sub_byte, uses s==1. */
  5898. bc = (res & (~d | 1)) | (~d & 1);
  5899. /* carry flag unchanged */
  5900. CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
  5901. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  5902. return (uint8_t) res;
  5903. }
  5904. /*
  5905. * REMARKS:
  5906. * Implements the DEC instruction and side effects.
  5907. */
  5908. static uint16_t
  5909. dec_word(struct x86emu *emu, uint16_t d)
  5910. {
  5911. uint32_t res; /* all operands in native machine order */
  5912. uint32_t bc;
  5913. res = d - 1;
  5914. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  5915. CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
  5916. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5917. /* calculate the borrow chain. See note at top */
  5918. /* based on the sub_byte routine, with s==1 */
  5919. bc = (res & (~d | 1)) | (~d & 1);
  5920. /* carry flag unchanged */
  5921. CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
  5922. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  5923. return (uint16_t) res;
  5924. }
  5925. /*
  5926. * REMARKS:
  5927. * Implements the DEC instruction and side effects.
  5928. */
  5929. static uint32_t
  5930. dec_long(struct x86emu *emu, uint32_t d)
  5931. {
  5932. uint32_t res; /* all operands in native machine order */
  5933. uint32_t bc;
  5934. res = d - 1;
  5935. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  5936. CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
  5937. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5938. /* calculate the borrow chain. See note at top */
  5939. bc = (res & (~d | 1)) | (~d & 1);
  5940. /* carry flag unchanged */
  5941. CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
  5942. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  5943. return res;
  5944. }
  5945. /*
  5946. * REMARKS:
  5947. * Implements the INC instruction and side effects.
  5948. */
  5949. static uint8_t
  5950. inc_byte(struct x86emu *emu, uint8_t d)
  5951. {
  5952. uint32_t res; /* all operands in native machine order */
  5953. uint32_t cc;
  5954. res = d + 1;
  5955. CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
  5956. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  5957. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5958. /* calculate the carry chain SEE NOTE AT TOP. */
  5959. cc = ((1 & d) | (~res)) & (1 | d);
  5960. CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
  5961. CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
  5962. return (uint8_t) res;
  5963. }
  5964. /*
  5965. * REMARKS:
  5966. * Implements the INC instruction and side effects.
  5967. */
  5968. static uint16_t
  5969. inc_word(struct x86emu *emu, uint16_t d)
  5970. {
  5971. uint32_t res; /* all operands in native machine order */
  5972. uint32_t cc;
  5973. res = d + 1;
  5974. CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
  5975. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  5976. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5977. /* calculate the carry chain SEE NOTE AT TOP. */
  5978. cc = (1 & d) | ((~res) & (1 | d));
  5979. CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
  5980. CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
  5981. return (uint16_t) res;
  5982. }
  5983. /*
  5984. * REMARKS:
  5985. * Implements the INC instruction and side effects.
  5986. */
  5987. static uint32_t
  5988. inc_long(struct x86emu *emu, uint32_t d)
  5989. {
  5990. uint32_t res; /* all operands in native machine order */
  5991. uint32_t cc;
  5992. res = d + 1;
  5993. CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
  5994. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  5995. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  5996. /* calculate the carry chain SEE NOTE AT TOP. */
  5997. cc = (1 & d) | ((~res) & (1 | d));
  5998. CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
  5999. CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
  6000. return res;
  6001. }
  6002. /*
  6003. * REMARKS:
  6004. * Implements the OR instruction and side effects.
  6005. */
  6006. static uint8_t
  6007. or_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  6008. {
  6009. uint8_t res; /* all operands in native machine order */
  6010. res = d | s;
  6011. CLEAR_FLAG(F_OF);
  6012. CLEAR_FLAG(F_CF);
  6013. CLEAR_FLAG(F_AF);
  6014. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  6015. CONDITIONAL_SET_FLAG(res == 0, F_ZF);
  6016. CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
  6017. return res;
  6018. }
  6019. /*
  6020. * REMARKS:
  6021. * Implements the OR instruction and side effects.
  6022. */
  6023. static uint16_t
  6024. or_word(struct x86emu *emu, uint16_t d, uint16_t s)
  6025. {
  6026. uint16_t res; /* all operands in native machine order */
  6027. res = d | s;
  6028. /* set the carry flag to be bit 8 */
  6029. CLEAR_FLAG(F_OF);
  6030. CLEAR_FLAG(F_CF);
  6031. CLEAR_FLAG(F_AF);
  6032. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  6033. CONDITIONAL_SET_FLAG(res == 0, F_ZF);
  6034. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6035. return res;
  6036. }
  6037. /*
  6038. * REMARKS:
  6039. * Implements the OR instruction and side effects.
  6040. */
  6041. static uint32_t
  6042. or_long(struct x86emu *emu, uint32_t d, uint32_t s)
  6043. {
  6044. uint32_t res; /* all operands in native machine order */
  6045. res = d | s;
  6046. /* set the carry flag to be bit 8 */
  6047. CLEAR_FLAG(F_OF);
  6048. CLEAR_FLAG(F_CF);
  6049. CLEAR_FLAG(F_AF);
  6050. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  6051. CONDITIONAL_SET_FLAG(res == 0, F_ZF);
  6052. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6053. return res;
  6054. }
  6055. /*
  6056. * REMARKS:
  6057. * Implements the OR instruction and side effects.
  6058. */
  6059. static uint8_t
  6060. neg_byte(struct x86emu *emu, uint8_t s)
  6061. {
  6062. uint8_t res;
  6063. uint8_t bc;
  6064. CONDITIONAL_SET_FLAG(s != 0, F_CF);
  6065. res = (uint8_t) - s;
  6066. CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
  6067. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  6068. CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
  6069. /* calculate the borrow chain --- modified such that d=0.
  6070. * substitutiing d=0 into bc= res&(~d|s)|(~d&s); (the one used for
  6071. * sub) and simplifying, since ~d=0xff..., ~d|s == 0xffff..., and
  6072. * res&0xfff... == res. Similarly ~d&s == s. So the simplified
  6073. * result is: */
  6074. bc = res | s;
  6075. CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
  6076. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  6077. return res;
  6078. }
  6079. /*
  6080. * REMARKS:
  6081. * Implements the OR instruction and side effects.
  6082. */
  6083. static uint16_t
  6084. neg_word(struct x86emu *emu, uint16_t s)
  6085. {
  6086. uint16_t res;
  6087. uint16_t bc;
  6088. CONDITIONAL_SET_FLAG(s != 0, F_CF);
  6089. res = (uint16_t) - s;
  6090. CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
  6091. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  6092. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6093. /* calculate the borrow chain --- modified such that d=0.
  6094. * substitutiing d=0 into bc= res&(~d|s)|(~d&s); (the one used for
  6095. * sub) and simplifying, since ~d=0xff..., ~d|s == 0xffff..., and
  6096. * res&0xfff... == res. Similarly ~d&s == s. So the simplified
  6097. * result is: */
  6098. bc = res | s;
  6099. CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
  6100. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  6101. return res;
  6102. }
  6103. /*
  6104. * REMARKS:
  6105. * Implements the OR instruction and side effects.
  6106. */
  6107. static uint32_t
  6108. neg_long(struct x86emu *emu, uint32_t s)
  6109. {
  6110. uint32_t res;
  6111. uint32_t bc;
  6112. CONDITIONAL_SET_FLAG(s != 0, F_CF);
  6113. res = (uint32_t) - s;
  6114. CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
  6115. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  6116. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6117. /* calculate the borrow chain --- modified such that d=0.
  6118. * substitutiing d=0 into bc= res&(~d|s)|(~d&s); (the one used for
  6119. * sub) and simplifying, since ~d=0xff..., ~d|s == 0xffff..., and
  6120. * res&0xfff... == res. Similarly ~d&s == s. So the simplified
  6121. * result is: */
  6122. bc = res | s;
  6123. CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
  6124. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  6125. return res;
  6126. }
  6127. /*
  6128. * REMARKS:
  6129. * Implements the RCL instruction and side effects.
  6130. */
  6131. static uint8_t
  6132. rcl_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  6133. {
  6134. unsigned int res, cnt, mask, cf;
  6135. /* s is the rotate distance. It varies from 0 - 8. */
  6136. /* have
  6137. *
  6138. * CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
  6139. *
  6140. * want to rotate through the carry by "s" bits. We could loop, but
  6141. * that's inefficient. So the width is 9, and we split into three
  6142. * parts:
  6143. *
  6144. * The new carry flag (was B_n) the stuff in B_n-1 .. B_0 the stuff
  6145. * in B_7 .. B_n+1
  6146. *
  6147. * The new rotate is done mod 9, and given this, for a rotation of n
  6148. * bits (mod 9) the new carry flag is then located n bits from the MSB.
  6149. * The low part is then shifted up cnt bits, and the high part is or'd
  6150. * in. Using CAPS for new values, and lowercase for the original
  6151. * values, this can be expressed as:
  6152. *
  6153. * IF n > 0 1) CF <- b_(8-n) 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0
  6154. * 3) B_(n-1) <- cf 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1))
  6155. */
  6156. res = d;
  6157. if ((cnt = s % 9) != 0) {
  6158. /* extract the new CARRY FLAG. */
  6159. /* CF <- b_(8-n) */
  6160. cf = (d >> (8 - cnt)) & 0x1;
  6161. /*
  6162. * Get the low stuff which rotated into the range B_7 .. B_cnt
  6163. * B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0
  6164. * note that the right hand side done by the mask.
  6165. */
  6166. res = (d << cnt) & 0xff;
  6167. /*
  6168. * now the high stuff which rotated around into the positions
  6169. * B_cnt-2 .. B_0
  6170. * B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1))
  6171. * shift it downward, 7-(n-2) = 9-n positions. and mask off
  6172. * the result before or'ing in.
  6173. */
  6174. mask = (1 << (cnt - 1)) - 1;
  6175. res |= (d >> (9 - cnt)) & mask;
  6176. /* if the carry flag was set, or it in. */
  6177. if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
  6178. /* B_(n-1) <- cf */
  6179. res |= 1 << (cnt - 1);
  6180. }
  6181. /* set the new carry flag, based on the variable "cf" */
  6182. CONDITIONAL_SET_FLAG(cf, F_CF);
  6183. /* OVERFLOW is set *IFF* cnt==1, then it is the xor of CF and
  6184. * the most significant bit. Blecck. */
  6185. /* parenthesized this expression since it appears to be
  6186. * causing OF to be misset */
  6187. CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)),
  6188. F_OF);
  6189. }
  6190. return (uint8_t) res;
  6191. }
  6192. /*
  6193. * REMARKS:
  6194. * Implements the RCL instruction and side effects.
  6195. */
  6196. static uint16_t
  6197. rcl_word(struct x86emu *emu, uint16_t d, uint8_t s)
  6198. {
  6199. unsigned int res, cnt, mask, cf;
  6200. res = d;
  6201. if ((cnt = s % 17) != 0) {
  6202. cf = (d >> (16 - cnt)) & 0x1;
  6203. res = (d << cnt) & 0xffff;
  6204. mask = (1 << (cnt - 1)) - 1;
  6205. res |= (d >> (17 - cnt)) & mask;
  6206. if (ACCESS_FLAG(F_CF)) {
  6207. res |= 1 << (cnt - 1);
  6208. }
  6209. CONDITIONAL_SET_FLAG(cf, F_CF);
  6210. CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)),
  6211. F_OF);
  6212. }
  6213. return (uint16_t) res;
  6214. }
  6215. /*
  6216. * REMARKS:
  6217. * Implements the RCL instruction and side effects.
  6218. */
  6219. static uint32_t
  6220. rcl_long(struct x86emu *emu, uint32_t d, uint8_t s)
  6221. {
  6222. uint32_t res, cnt, mask, cf;
  6223. res = d;
  6224. if ((cnt = s % 33) != 0) {
  6225. cf = (d >> (32 - cnt)) & 0x1;
  6226. res = (d << cnt) & 0xffffffff;
  6227. mask = (1 << (cnt - 1)) - 1;
  6228. res |= (d >> (33 - cnt)) & mask;
  6229. if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
  6230. res |= 1 << (cnt - 1);
  6231. }
  6232. CONDITIONAL_SET_FLAG(cf, F_CF);
  6233. CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)),
  6234. F_OF);
  6235. }
  6236. return res;
  6237. }
  6238. /*
  6239. * REMARKS:
  6240. * Implements the RCR instruction and side effects.
  6241. */
  6242. static uint8_t
  6243. rcr_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  6244. {
  6245. uint32_t res, cnt;
  6246. uint32_t mask, cf, ocf = 0;
  6247. /* rotate right through carry */
  6248. /* s is the rotate distance. It varies from 0 - 8. d is the byte
  6249. * object rotated.
  6250. *
  6251. * have
  6252. *
  6253. * CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
  6254. *
  6255. * The new rotate is done mod 9, and given this, for a rotation of n
  6256. * bits (mod 9) the new carry flag is then located n bits from the LSB.
  6257. * The low part is then shifted up cnt bits, and the high part is or'd
  6258. * in. Using CAPS for new values, and lowercase for the original
  6259. * values, this can be expressed as:
  6260. *
  6261. * IF n > 0
  6262. * 1) CF <- b_(n-1)
  6263. * 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
  6264. * 3) B_(8-n) <- cf 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0)
  6265. */
  6266. res = d;
  6267. if ((cnt = s % 9) != 0) {
  6268. /* extract the new CARRY FLAG. */
  6269. /* CF <- b_(n-1) */
  6270. if (cnt == 1) {
  6271. cf = d & 0x1;
  6272. /* note hackery here. Access_flag(..) evaluates to
  6273. * either 0 if flag not set non-zero if flag is set.
  6274. * doing access_flag(..) != 0 casts that into either
  6275. * 0..1 in any representation of the flags register
  6276. * (i.e. packed bit array or unpacked.) */
  6277. ocf = ACCESS_FLAG(F_CF) != 0;
  6278. } else
  6279. cf = (d >> (cnt - 1)) & 0x1;
  6280. /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */
  6281. /* note that the right hand side done by the mask This is
  6282. * effectively done by shifting the object to the right. The
  6283. * result must be masked, in case the object came in and was
  6284. * treated as a negative number. Needed??? */
  6285. mask = (1 << (8 - cnt)) - 1;
  6286. res = (d >> cnt) & mask;
  6287. /* now the high stuff which rotated around into the positions
  6288. * B_cnt-2 .. B_0 */
  6289. /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */
  6290. /* shift it downward, 7-(n-2) = 9-n positions. and mask off
  6291. * the result before or'ing in. */
  6292. res |= (d << (9 - cnt));
  6293. /* if the carry flag was set, or it in. */
  6294. if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
  6295. /* B_(8-n) <- cf */
  6296. res |= 1 << (8 - cnt);
  6297. }
  6298. /* set the new carry flag, based on the variable "cf" */
  6299. CONDITIONAL_SET_FLAG(cf, F_CF);
  6300. /* OVERFLOW is set *IFF* cnt==1, then it is the xor of CF and
  6301. * the most significant bit. Blecck. */
  6302. /* parenthesized... */
  6303. if (cnt == 1) {
  6304. CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)),
  6305. F_OF);
  6306. }
  6307. }
  6308. return (uint8_t) res;
  6309. }
  6310. /*
  6311. * REMARKS:
  6312. * Implements the RCR instruction and side effects.
  6313. */
  6314. static uint16_t
  6315. rcr_word(struct x86emu *emu, uint16_t d, uint8_t s)
  6316. {
  6317. uint32_t res, cnt;
  6318. uint32_t mask, cf, ocf = 0;
  6319. /* rotate right through carry */
  6320. res = d;
  6321. if ((cnt = s % 17) != 0) {
  6322. if (cnt == 1) {
  6323. cf = d & 0x1;
  6324. ocf = ACCESS_FLAG(F_CF) != 0;
  6325. } else
  6326. cf = (d >> (cnt - 1)) & 0x1;
  6327. mask = (1 << (16 - cnt)) - 1;
  6328. res = (d >> cnt) & mask;
  6329. res |= (d << (17 - cnt));
  6330. if (ACCESS_FLAG(F_CF)) {
  6331. res |= 1 << (16 - cnt);
  6332. }
  6333. CONDITIONAL_SET_FLAG(cf, F_CF);
  6334. if (cnt == 1) {
  6335. CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)),
  6336. F_OF);
  6337. }
  6338. }
  6339. return (uint16_t) res;
  6340. }
  6341. /*
  6342. * REMARKS:
  6343. * Implements the RCR instruction and side effects.
  6344. */
  6345. static uint32_t
  6346. rcr_long(struct x86emu *emu, uint32_t d, uint8_t s)
  6347. {
  6348. uint32_t res, cnt;
  6349. uint32_t mask, cf, ocf = 0;
  6350. /* rotate right through carry */
  6351. res = d;
  6352. if ((cnt = s % 33) != 0) {
  6353. if (cnt == 1) {
  6354. cf = d & 0x1;
  6355. ocf = ACCESS_FLAG(F_CF) != 0;
  6356. } else
  6357. cf = (d >> (cnt - 1)) & 0x1;
  6358. mask = (1 << (32 - cnt)) - 1;
  6359. res = (d >> cnt) & mask;
  6360. if (cnt != 1)
  6361. res |= (d << (33 - cnt));
  6362. if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
  6363. res |= 1 << (32 - cnt);
  6364. }
  6365. CONDITIONAL_SET_FLAG(cf, F_CF);
  6366. if (cnt == 1) {
  6367. CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)),
  6368. F_OF);
  6369. }
  6370. }
  6371. return res;
  6372. }
  6373. /*
  6374. * REMARKS:
  6375. * Implements the ROL instruction and side effects.
  6376. */
  6377. static uint8_t
  6378. rol_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  6379. {
  6380. unsigned int res, cnt, mask;
  6381. /* rotate left */
  6382. /* s is the rotate distance. It varies from 0 - 8. d is the byte
  6383. * object rotated.
  6384. *
  6385. * have
  6386. *
  6387. * CF B_7 ... B_0
  6388. *
  6389. * The new rotate is done mod 8. Much simpler than the "rcl" or "rcr"
  6390. * operations.
  6391. *
  6392. * IF n > 0 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) 2) B_(n-1) ..
  6393. * B_(0) <- b_(7) .. b_(8-n) */
  6394. res = d;
  6395. if ((cnt = s % 8) != 0) {
  6396. /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */
  6397. res = (d << cnt);
  6398. /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */
  6399. mask = (1 << cnt) - 1;
  6400. res |= (d >> (8 - cnt)) & mask;
  6401. /* set the new carry flag, Note that it is the low order bit
  6402. * of the result!!! */
  6403. CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
  6404. /* OVERFLOW is set *IFF* s==1, then it is the xor of CF and
  6405. * the most significant bit. Blecck. */
  6406. CONDITIONAL_SET_FLAG(s == 1 &&
  6407. XOR2((res & 0x1) + ((res >> 6) & 0x2)),
  6408. F_OF);
  6409. } if (s != 0) {
  6410. /* set the new carry flag, Note that it is the low order bit
  6411. * of the result!!! */
  6412. CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
  6413. }
  6414. return (uint8_t) res;
  6415. }
  6416. /*
  6417. * REMARKS:
  6418. * Implements the ROL instruction and side effects.
  6419. */
  6420. static uint16_t
  6421. rol_word(struct x86emu *emu, uint16_t d, uint8_t s)
  6422. {
  6423. unsigned int res, cnt, mask;
  6424. res = d;
  6425. if ((cnt = s % 16) != 0) {
  6426. res = (d << cnt);
  6427. mask = (1 << cnt) - 1;
  6428. res |= (d >> (16 - cnt)) & mask;
  6429. CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
  6430. CONDITIONAL_SET_FLAG(s == 1 &&
  6431. XOR2((res & 0x1) + ((res >> 14) & 0x2)),
  6432. F_OF);
  6433. } if (s != 0) {
  6434. /* set the new carry flag, Note that it is the low order bit
  6435. * of the result!!! */
  6436. CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
  6437. }
  6438. return (uint16_t) res;
  6439. }
  6440. /*
  6441. * REMARKS:
  6442. * Implements the ROL instruction and side effects.
  6443. */
  6444. static uint32_t
  6445. rol_long(struct x86emu *emu, uint32_t d, uint8_t s)
  6446. {
  6447. uint32_t res, cnt, mask;
  6448. res = d;
  6449. if ((cnt = s % 32) != 0) {
  6450. res = (d << cnt);
  6451. mask = (1 << cnt) - 1;
  6452. res |= (d >> (32 - cnt)) & mask;
  6453. CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
  6454. CONDITIONAL_SET_FLAG(s == 1 &&
  6455. XOR2((res & 0x1) + ((res >> 30) & 0x2)),
  6456. F_OF);
  6457. } if (s != 0) {
  6458. /* set the new carry flag, Note that it is the low order bit
  6459. * of the result!!! */
  6460. CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
  6461. }
  6462. return res;
  6463. }
  6464. /*
  6465. * REMARKS:
  6466. * Implements the ROR instruction and side effects.
  6467. */
  6468. static uint8_t
  6469. ror_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  6470. {
  6471. unsigned int res, cnt, mask;
  6472. /* rotate right */
  6473. /* s is the rotate distance. It varies from 0 - 8. d is the byte
  6474. * object rotated.
  6475. *
  6476. * have
  6477. *
  6478. * B_7 ... B_0
  6479. *
  6480. * The rotate is done mod 8.
  6481. *
  6482. * IF n > 0 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) 2) B_(7) ..
  6483. * B_(8-n) <- b_(n-1) .. b_(0) */
  6484. res = d;
  6485. if ((cnt = s % 8) != 0) { /* not a typo, do nada if cnt==0 */
  6486. /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */
  6487. res = (d << (8 - cnt));
  6488. /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */
  6489. mask = (1 << (8 - cnt)) - 1;
  6490. res |= (d >> (cnt)) & mask;
  6491. /* set the new carry flag, Note that it is the low order bit
  6492. * of the result!!! */
  6493. CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
  6494. /* OVERFLOW is set *IFF* s==1, then it is the xor of the two
  6495. * most significant bits. Blecck. */
  6496. CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF);
  6497. } else if (s != 0) {
  6498. /* set the new carry flag, Note that it is the low order bit
  6499. * of the result!!! */
  6500. CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
  6501. }
  6502. return (uint8_t) res;
  6503. }
  6504. /*
  6505. * REMARKS:
  6506. * Implements the ROR instruction and side effects.
  6507. */
  6508. static uint16_t
  6509. ror_word(struct x86emu *emu, uint16_t d, uint8_t s)
  6510. {
  6511. unsigned int res, cnt, mask;
  6512. res = d;
  6513. if ((cnt = s % 16) != 0) {
  6514. res = (d << (16 - cnt));
  6515. mask = (1 << (16 - cnt)) - 1;
  6516. res |= (d >> (cnt)) & mask;
  6517. CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
  6518. CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF);
  6519. } else if (s != 0) {
  6520. /* set the new carry flag, Note that it is the low order bit
  6521. * of the result!!! */
  6522. CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
  6523. }
  6524. return (uint16_t) res;
  6525. }
  6526. /*
  6527. * REMARKS:
  6528. * Implements the ROR instruction and side effects.
  6529. */
  6530. static uint32_t
  6531. ror_long(struct x86emu *emu, uint32_t d, uint8_t s)
  6532. {
  6533. uint32_t res, cnt, mask;
  6534. res = d;
  6535. if ((cnt = s % 32) != 0) {
  6536. res = (d << (32 - cnt));
  6537. mask = (1 << (32 - cnt)) - 1;
  6538. res |= (d >> (cnt)) & mask;
  6539. CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
  6540. CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF);
  6541. } else if (s != 0) {
  6542. /* set the new carry flag, Note that it is the low order bit
  6543. * of the result!!! */
  6544. CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
  6545. }
  6546. return res;
  6547. }
  6548. /*
  6549. * REMARKS:
  6550. * Implements the SHL instruction and side effects.
  6551. */
  6552. static uint8_t
  6553. shl_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  6554. {
  6555. unsigned int cnt, res, cf;
  6556. if (s < 8) {
  6557. cnt = s % 8;
  6558. /* last bit shifted out goes into carry flag */
  6559. if (cnt > 0) {
  6560. res = d << cnt;
  6561. cf = d & (1 << (8 - cnt));
  6562. CONDITIONAL_SET_FLAG(cf, F_CF);
  6563. CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
  6564. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  6565. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6566. } else {
  6567. res = (uint8_t) d;
  6568. }
  6569. if (cnt == 1) {
  6570. /* Needs simplification. */
  6571. CONDITIONAL_SET_FLAG(
  6572. (((res & 0x80) == 0x80) ^
  6573. (ACCESS_FLAG(F_CF) != 0)),
  6574. /* was (emu->x86.R_FLG&F_CF)==F_CF)), */
  6575. F_OF);
  6576. } else {
  6577. CLEAR_FLAG(F_OF);
  6578. }
  6579. } else {
  6580. res = 0;
  6581. CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80, F_CF);
  6582. CLEAR_FLAG(F_OF);
  6583. CLEAR_FLAG(F_SF);
  6584. SET_FLAG(F_PF);
  6585. SET_FLAG(F_ZF);
  6586. }
  6587. return (uint8_t) res;
  6588. }
  6589. /*
  6590. * REMARKS:
  6591. * Implements the SHL instruction and side effects.
  6592. */
  6593. static uint16_t
  6594. shl_word(struct x86emu *emu, uint16_t d, uint8_t s)
  6595. {
  6596. unsigned int cnt, res, cf;
  6597. if (s < 16) {
  6598. cnt = s % 16;
  6599. if (cnt > 0) {
  6600. res = d << cnt;
  6601. cf = d & (1 << (16 - cnt));
  6602. CONDITIONAL_SET_FLAG(cf, F_CF);
  6603. CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
  6604. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  6605. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6606. } else {
  6607. res = (uint16_t) d;
  6608. }
  6609. if (cnt == 1) {
  6610. CONDITIONAL_SET_FLAG(
  6611. (((res & 0x8000) == 0x8000) ^
  6612. (ACCESS_FLAG(F_CF) != 0)),
  6613. F_OF);
  6614. } else {
  6615. CLEAR_FLAG(F_OF);
  6616. }
  6617. } else {
  6618. res = 0;
  6619. CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF);
  6620. CLEAR_FLAG(F_OF);
  6621. CLEAR_FLAG(F_SF);
  6622. SET_FLAG(F_PF);
  6623. SET_FLAG(F_ZF);
  6624. }
  6625. return (uint16_t) res;
  6626. }
  6627. /*
  6628. * REMARKS:
  6629. * Implements the SHL instruction and side effects.
  6630. */
  6631. static uint32_t
  6632. shl_long(struct x86emu *emu, uint32_t d, uint8_t s)
  6633. {
  6634. unsigned int cnt, res, cf;
  6635. if (s < 32) {
  6636. cnt = s % 32;
  6637. if (cnt > 0) {
  6638. res = d << cnt;
  6639. cf = d & (1 << (32 - cnt));
  6640. CONDITIONAL_SET_FLAG(cf, F_CF);
  6641. CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
  6642. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  6643. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6644. } else {
  6645. res = d;
  6646. }
  6647. if (cnt == 1) {
  6648. CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000)
  6649. ^ (ACCESS_FLAG(F_CF) != 0)), F_OF);
  6650. } else {
  6651. CLEAR_FLAG(F_OF);
  6652. }
  6653. } else {
  6654. res = 0;
  6655. CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF);
  6656. CLEAR_FLAG(F_OF);
  6657. CLEAR_FLAG(F_SF);
  6658. SET_FLAG(F_PF);
  6659. SET_FLAG(F_ZF);
  6660. }
  6661. return res;
  6662. }
  6663. /*
  6664. * REMARKS:
  6665. * Implements the SHR instruction and side effects.
  6666. */
  6667. static uint8_t
  6668. shr_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  6669. {
  6670. unsigned int cnt, res, cf;
  6671. if (s < 8) {
  6672. cnt = s % 8;
  6673. if (cnt > 0) {
  6674. cf = d & (1 << (cnt - 1));
  6675. res = d >> cnt;
  6676. CONDITIONAL_SET_FLAG(cf, F_CF);
  6677. CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
  6678. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  6679. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6680. } else {
  6681. res = (uint8_t) d;
  6682. }
  6683. if (cnt == 1) {
  6684. CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
  6685. } else {
  6686. CLEAR_FLAG(F_OF);
  6687. }
  6688. } else {
  6689. res = 0;
  6690. CONDITIONAL_SET_FLAG((d >> (s - 1)) & 0x1, F_CF);
  6691. CLEAR_FLAG(F_OF);
  6692. CLEAR_FLAG(F_SF);
  6693. SET_FLAG(F_PF);
  6694. SET_FLAG(F_ZF);
  6695. }
  6696. return (uint8_t) res;
  6697. }
  6698. /*
  6699. * REMARKS:
  6700. * Implements the SHR instruction and side effects.
  6701. */
  6702. static uint16_t
  6703. shr_word(struct x86emu *emu, uint16_t d, uint8_t s)
  6704. {
  6705. unsigned int cnt, res, cf;
  6706. if (s < 16) {
  6707. cnt = s % 16;
  6708. if (cnt > 0) {
  6709. cf = d & (1 << (cnt - 1));
  6710. res = d >> cnt;
  6711. CONDITIONAL_SET_FLAG(cf, F_CF);
  6712. CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
  6713. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  6714. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6715. } else {
  6716. res = d;
  6717. }
  6718. if (cnt == 1) {
  6719. CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
  6720. } else {
  6721. CLEAR_FLAG(F_OF);
  6722. }
  6723. } else {
  6724. res = 0;
  6725. CLEAR_FLAG(F_CF);
  6726. CLEAR_FLAG(F_OF);
  6727. SET_FLAG(F_ZF);
  6728. CLEAR_FLAG(F_SF);
  6729. CLEAR_FLAG(F_PF);
  6730. }
  6731. return (uint16_t) res;
  6732. }
  6733. /*
  6734. * REMARKS:
  6735. * Implements the SHR instruction and side effects.
  6736. */
  6737. static uint32_t
  6738. shr_long(struct x86emu *emu, uint32_t d, uint8_t s)
  6739. {
  6740. unsigned int cnt, res, cf;
  6741. if (s < 32) {
  6742. cnt = s % 32;
  6743. if (cnt > 0) {
  6744. cf = d & (1 << (cnt - 1));
  6745. res = d >> cnt;
  6746. CONDITIONAL_SET_FLAG(cf, F_CF);
  6747. CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
  6748. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  6749. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6750. } else {
  6751. res = d;
  6752. }
  6753. if (cnt == 1) {
  6754. CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
  6755. } else {
  6756. CLEAR_FLAG(F_OF);
  6757. }
  6758. } else {
  6759. res = 0;
  6760. CLEAR_FLAG(F_CF);
  6761. CLEAR_FLAG(F_OF);
  6762. SET_FLAG(F_ZF);
  6763. CLEAR_FLAG(F_SF);
  6764. CLEAR_FLAG(F_PF);
  6765. }
  6766. return res;
  6767. }
  6768. /*
  6769. * REMARKS:
  6770. * Implements the SAR instruction and side effects.
  6771. */
  6772. static uint8_t
  6773. sar_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  6774. {
  6775. unsigned int cnt, res, cf, mask, sf;
  6776. res = d;
  6777. sf = d & 0x80;
  6778. cnt = s % 8;
  6779. if (cnt > 0 && cnt < 8) {
  6780. mask = (1 << (8 - cnt)) - 1;
  6781. cf = d & (1 << (cnt - 1));
  6782. res = (d >> cnt) & mask;
  6783. CONDITIONAL_SET_FLAG(cf, F_CF);
  6784. if (sf) {
  6785. res |= ~mask;
  6786. }
  6787. CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
  6788. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6789. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  6790. } else if (cnt >= 8) {
  6791. if (sf) {
  6792. res = 0xff;
  6793. SET_FLAG(F_CF);
  6794. CLEAR_FLAG(F_ZF);
  6795. SET_FLAG(F_SF);
  6796. SET_FLAG(F_PF);
  6797. } else {
  6798. res = 0;
  6799. CLEAR_FLAG(F_CF);
  6800. SET_FLAG(F_ZF);
  6801. CLEAR_FLAG(F_SF);
  6802. CLEAR_FLAG(F_PF);
  6803. }
  6804. }
  6805. return (uint8_t) res;
  6806. }
  6807. /*
  6808. * REMARKS:
  6809. * Implements the SAR instruction and side effects.
  6810. */
  6811. static uint16_t
  6812. sar_word(struct x86emu *emu, uint16_t d, uint8_t s)
  6813. {
  6814. unsigned int cnt, res, cf, mask, sf;
  6815. sf = d & 0x8000;
  6816. cnt = s % 16;
  6817. res = d;
  6818. if (cnt > 0 && cnt < 16) {
  6819. mask = (1 << (16 - cnt)) - 1;
  6820. cf = d & (1 << (cnt - 1));
  6821. res = (d >> cnt) & mask;
  6822. CONDITIONAL_SET_FLAG(cf, F_CF);
  6823. if (sf) {
  6824. res |= ~mask;
  6825. }
  6826. CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
  6827. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  6828. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6829. } else if (cnt >= 16) {
  6830. if (sf) {
  6831. res = 0xffff;
  6832. SET_FLAG(F_CF);
  6833. CLEAR_FLAG(F_ZF);
  6834. SET_FLAG(F_SF);
  6835. SET_FLAG(F_PF);
  6836. } else {
  6837. res = 0;
  6838. CLEAR_FLAG(F_CF);
  6839. SET_FLAG(F_ZF);
  6840. CLEAR_FLAG(F_SF);
  6841. CLEAR_FLAG(F_PF);
  6842. }
  6843. }
  6844. return (uint16_t) res;
  6845. }
  6846. /*
  6847. * REMARKS:
  6848. * Implements the SAR instruction and side effects.
  6849. */
  6850. static uint32_t
  6851. sar_long(struct x86emu *emu, uint32_t d, uint8_t s)
  6852. {
  6853. uint32_t cnt, res, cf, mask, sf;
  6854. sf = d & 0x80000000;
  6855. cnt = s % 32;
  6856. res = d;
  6857. if (cnt > 0 && cnt < 32) {
  6858. mask = (1 << (32 - cnt)) - 1;
  6859. cf = d & (1 << (cnt - 1));
  6860. res = (d >> cnt) & mask;
  6861. CONDITIONAL_SET_FLAG(cf, F_CF);
  6862. if (sf) {
  6863. res |= ~mask;
  6864. }
  6865. CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
  6866. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  6867. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6868. } else if (cnt >= 32) {
  6869. if (sf) {
  6870. res = 0xffffffff;
  6871. SET_FLAG(F_CF);
  6872. CLEAR_FLAG(F_ZF);
  6873. SET_FLAG(F_SF);
  6874. SET_FLAG(F_PF);
  6875. } else {
  6876. res = 0;
  6877. CLEAR_FLAG(F_CF);
  6878. SET_FLAG(F_ZF);
  6879. CLEAR_FLAG(F_SF);
  6880. CLEAR_FLAG(F_PF);
  6881. }
  6882. }
  6883. return res;
  6884. }
  6885. /*
  6886. * REMARKS:
  6887. * Implements the SHLD instruction and side effects.
  6888. */
  6889. static uint16_t
  6890. shld_word(struct x86emu *emu, uint16_t d, uint16_t fill, uint8_t s)
  6891. {
  6892. unsigned int cnt, res, cf;
  6893. if (s < 16) {
  6894. cnt = s % 16;
  6895. if (cnt > 0) {
  6896. res = (d << cnt) | (fill >> (16 - cnt));
  6897. cf = d & (1 << (16 - cnt));
  6898. CONDITIONAL_SET_FLAG(cf, F_CF);
  6899. CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
  6900. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  6901. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6902. } else {
  6903. res = d;
  6904. }
  6905. if (cnt == 1) {
  6906. CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
  6907. (ACCESS_FLAG(F_CF) != 0)), F_OF);
  6908. } else {
  6909. CLEAR_FLAG(F_OF);
  6910. }
  6911. } else {
  6912. res = 0;
  6913. CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF);
  6914. CLEAR_FLAG(F_OF);
  6915. CLEAR_FLAG(F_SF);
  6916. SET_FLAG(F_PF);
  6917. SET_FLAG(F_ZF);
  6918. }
  6919. return (uint16_t) res;
  6920. }
  6921. /*
  6922. * REMARKS:
  6923. * Implements the SHLD instruction and side effects.
  6924. */
  6925. static uint32_t
  6926. shld_long(struct x86emu *emu, uint32_t d, uint32_t fill, uint8_t s)
  6927. {
  6928. unsigned int cnt, res, cf;
  6929. if (s < 32) {
  6930. cnt = s % 32;
  6931. if (cnt > 0) {
  6932. res = (d << cnt) | (fill >> (32 - cnt));
  6933. cf = d & (1 << (32 - cnt));
  6934. CONDITIONAL_SET_FLAG(cf, F_CF);
  6935. CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
  6936. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  6937. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6938. } else {
  6939. res = d;
  6940. }
  6941. if (cnt == 1) {
  6942. CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000)
  6943. ^ (ACCESS_FLAG(F_CF) != 0)), F_OF);
  6944. } else {
  6945. CLEAR_FLAG(F_OF);
  6946. }
  6947. } else {
  6948. res = 0;
  6949. CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF);
  6950. CLEAR_FLAG(F_OF);
  6951. CLEAR_FLAG(F_SF);
  6952. SET_FLAG(F_PF);
  6953. SET_FLAG(F_ZF);
  6954. }
  6955. return res;
  6956. }
  6957. /*
  6958. * REMARKS:
  6959. * Implements the SHRD instruction and side effects.
  6960. */
  6961. static uint16_t
  6962. shrd_word(struct x86emu *emu, uint16_t d, uint16_t fill, uint8_t s)
  6963. {
  6964. unsigned int cnt, res, cf;
  6965. if (s < 16) {
  6966. cnt = s % 16;
  6967. if (cnt > 0) {
  6968. cf = d & (1 << (cnt - 1));
  6969. res = (d >> cnt) | (fill << (16 - cnt));
  6970. CONDITIONAL_SET_FLAG(cf, F_CF);
  6971. CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
  6972. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  6973. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  6974. } else {
  6975. res = d;
  6976. }
  6977. if (cnt == 1) {
  6978. CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
  6979. } else {
  6980. CLEAR_FLAG(F_OF);
  6981. }
  6982. } else {
  6983. res = 0;
  6984. CLEAR_FLAG(F_CF);
  6985. CLEAR_FLAG(F_OF);
  6986. SET_FLAG(F_ZF);
  6987. CLEAR_FLAG(F_SF);
  6988. CLEAR_FLAG(F_PF);
  6989. }
  6990. return (uint16_t) res;
  6991. }
  6992. /*
  6993. * REMARKS:
  6994. * Implements the SHRD instruction and side effects.
  6995. */
  6996. static uint32_t
  6997. shrd_long(struct x86emu *emu, uint32_t d, uint32_t fill, uint8_t s)
  6998. {
  6999. unsigned int cnt, res, cf;
  7000. if (s < 32) {
  7001. cnt = s % 32;
  7002. if (cnt > 0) {
  7003. cf = d & (1 << (cnt - 1));
  7004. res = (d >> cnt) | (fill << (32 - cnt));
  7005. CONDITIONAL_SET_FLAG(cf, F_CF);
  7006. CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
  7007. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  7008. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  7009. } else {
  7010. res = d;
  7011. }
  7012. if (cnt == 1) {
  7013. CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
  7014. } else {
  7015. CLEAR_FLAG(F_OF);
  7016. }
  7017. } else {
  7018. res = 0;
  7019. CLEAR_FLAG(F_CF);
  7020. CLEAR_FLAG(F_OF);
  7021. SET_FLAG(F_ZF);
  7022. CLEAR_FLAG(F_SF);
  7023. CLEAR_FLAG(F_PF);
  7024. }
  7025. return res;
  7026. }
  7027. /*
  7028. * REMARKS:
  7029. * Implements the SBB instruction and side effects.
  7030. */
  7031. static uint8_t
  7032. sbb_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  7033. {
  7034. uint32_t res; /* all operands in native machine order */
  7035. uint32_t bc;
  7036. if (ACCESS_FLAG(F_CF))
  7037. res = d - s - 1;
  7038. else
  7039. res = d - s;
  7040. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  7041. CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
  7042. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  7043. /* calculate the borrow chain. See note at top */
  7044. bc = (res & (~d | s)) | (~d & s);
  7045. CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
  7046. CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
  7047. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  7048. return (uint8_t) res;
  7049. }
  7050. /*
  7051. * REMARKS:
  7052. * Implements the SBB instruction and side effects.
  7053. */
  7054. static uint16_t
  7055. sbb_word(struct x86emu *emu, uint16_t d, uint16_t s)
  7056. {
  7057. uint32_t res; /* all operands in native machine order */
  7058. uint32_t bc;
  7059. if (ACCESS_FLAG(F_CF))
  7060. res = d - s - 1;
  7061. else
  7062. res = d - s;
  7063. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  7064. CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
  7065. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  7066. /* calculate the borrow chain. See note at top */
  7067. bc = (res & (~d | s)) | (~d & s);
  7068. CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
  7069. CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
  7070. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  7071. return (uint16_t) res;
  7072. }
  7073. /*
  7074. * REMARKS:
  7075. * Implements the SBB instruction and side effects.
  7076. */
  7077. static uint32_t
  7078. sbb_long(struct x86emu *emu, uint32_t d, uint32_t s)
  7079. {
  7080. uint32_t res; /* all operands in native machine order */
  7081. uint32_t bc;
  7082. if (ACCESS_FLAG(F_CF))
  7083. res = d - s - 1;
  7084. else
  7085. res = d - s;
  7086. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  7087. CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
  7088. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  7089. /* calculate the borrow chain. See note at top */
  7090. bc = (res & (~d | s)) | (~d & s);
  7091. CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
  7092. CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
  7093. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  7094. return res;
  7095. }
  7096. /*
  7097. * REMARKS:
  7098. * Implements the SUB instruction and side effects.
  7099. */
  7100. static uint8_t
  7101. sub_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  7102. {
  7103. uint32_t res; /* all operands in native machine order */
  7104. uint32_t bc;
  7105. res = d - s;
  7106. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  7107. CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
  7108. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  7109. /* calculate the borrow chain. See note at top */
  7110. bc = (res & (~d | s)) | (~d & s);
  7111. CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
  7112. CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
  7113. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  7114. return (uint8_t) res;
  7115. }
  7116. /*
  7117. * REMARKS:
  7118. * Implements the SUB instruction and side effects.
  7119. */
  7120. static uint16_t
  7121. sub_word(struct x86emu *emu, uint16_t d, uint16_t s)
  7122. {
  7123. uint32_t res; /* all operands in native machine order */
  7124. uint32_t bc;
  7125. res = d - s;
  7126. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  7127. CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
  7128. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  7129. /* calculate the borrow chain. See note at top */
  7130. bc = (res & (~d | s)) | (~d & s);
  7131. CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
  7132. CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
  7133. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  7134. return (uint16_t) res;
  7135. }
  7136. /*
  7137. * REMARKS:
  7138. * Implements the SUB instruction and side effects.
  7139. */
  7140. static uint32_t
  7141. sub_long(struct x86emu *emu, uint32_t d, uint32_t s)
  7142. {
  7143. uint32_t res; /* all operands in native machine order */
  7144. uint32_t bc;
  7145. res = d - s;
  7146. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  7147. CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
  7148. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  7149. /* calculate the borrow chain. See note at top */
  7150. bc = (res & (~d | s)) | (~d & s);
  7151. CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
  7152. CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
  7153. CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
  7154. return res;
  7155. }
  7156. /*
  7157. * REMARKS:
  7158. * Implements the TEST instruction and side effects.
  7159. */
  7160. static void
  7161. test_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  7162. {
  7163. uint32_t res; /* all operands in native machine order */
  7164. res = d & s;
  7165. CLEAR_FLAG(F_OF);
  7166. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  7167. CONDITIONAL_SET_FLAG(res == 0, F_ZF);
  7168. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  7169. /* AF == dont care */
  7170. CLEAR_FLAG(F_CF);
  7171. }
  7172. /*
  7173. * REMARKS:
  7174. * Implements the TEST instruction and side effects.
  7175. */
  7176. static void
  7177. test_word(struct x86emu *emu, uint16_t d, uint16_t s)
  7178. {
  7179. uint32_t res; /* all operands in native machine order */
  7180. res = d & s;
  7181. CLEAR_FLAG(F_OF);
  7182. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  7183. CONDITIONAL_SET_FLAG(res == 0, F_ZF);
  7184. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  7185. /* AF == dont care */
  7186. CLEAR_FLAG(F_CF);
  7187. }
  7188. /*
  7189. * REMARKS:
  7190. * Implements the TEST instruction and side effects.
  7191. */
  7192. static void
  7193. test_long(struct x86emu *emu, uint32_t d, uint32_t s)
  7194. {
  7195. uint32_t res; /* all operands in native machine order */
  7196. res = d & s;
  7197. CLEAR_FLAG(F_OF);
  7198. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  7199. CONDITIONAL_SET_FLAG(res == 0, F_ZF);
  7200. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  7201. /* AF == dont care */
  7202. CLEAR_FLAG(F_CF);
  7203. }
  7204. /*
  7205. * REMARKS:
  7206. * Implements the XOR instruction and side effects.
  7207. */
  7208. static uint8_t
  7209. xor_byte(struct x86emu *emu, uint8_t d, uint8_t s)
  7210. {
  7211. uint8_t res; /* all operands in native machine order */
  7212. res = d ^ s;
  7213. CLEAR_FLAG(F_OF);
  7214. CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
  7215. CONDITIONAL_SET_FLAG(res == 0, F_ZF);
  7216. CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
  7217. CLEAR_FLAG(F_CF);
  7218. CLEAR_FLAG(F_AF);
  7219. return res;
  7220. }
  7221. /*
  7222. * REMARKS:
  7223. * Implements the XOR instruction and side effects.
  7224. */
  7225. static uint16_t
  7226. xor_word(struct x86emu *emu, uint16_t d, uint16_t s)
  7227. {
  7228. uint16_t res; /* all operands in native machine order */
  7229. res = d ^ s;
  7230. CLEAR_FLAG(F_OF);
  7231. CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
  7232. CONDITIONAL_SET_FLAG(res == 0, F_ZF);
  7233. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  7234. CLEAR_FLAG(F_CF);
  7235. CLEAR_FLAG(F_AF);
  7236. return res;
  7237. }
  7238. /*
  7239. * REMARKS:
  7240. * Implements the XOR instruction and side effects.
  7241. */
  7242. static uint32_t
  7243. xor_long(struct x86emu *emu, uint32_t d, uint32_t s)
  7244. {
  7245. uint32_t res; /* all operands in native machine order */
  7246. res = d ^ s;
  7247. CLEAR_FLAG(F_OF);
  7248. CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
  7249. CONDITIONAL_SET_FLAG(res == 0, F_ZF);
  7250. CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
  7251. CLEAR_FLAG(F_CF);
  7252. CLEAR_FLAG(F_AF);
  7253. return res;
  7254. }
  7255. /*
  7256. * REMARKS:
  7257. * Implements the IMUL instruction and side effects.
  7258. */
  7259. static void
  7260. imul_byte(struct x86emu *emu, uint8_t s)
  7261. {
  7262. int16_t res = (int16_t) ((int8_t) emu->x86.R_AL * (int8_t) s);
  7263. emu->x86.R_AX = res;
  7264. if (((emu->x86.R_AL & 0x80) == 0 && emu->x86.R_AH == 0x00) ||
  7265. ((emu->x86.R_AL & 0x80) != 0 && emu->x86.R_AH == 0xFF)) {
  7266. CLEAR_FLAG(F_CF);
  7267. CLEAR_FLAG(F_OF);
  7268. } else {
  7269. SET_FLAG(F_CF);
  7270. SET_FLAG(F_OF);
  7271. }
  7272. }
  7273. /*
  7274. * REMARKS:
  7275. * Implements the IMUL instruction and side effects.
  7276. */
  7277. static void
  7278. imul_word(struct x86emu *emu, uint16_t s)
  7279. {
  7280. int32_t res = (int16_t) emu->x86.R_AX * (int16_t) s;
  7281. emu->x86.R_AX = (uint16_t) res;
  7282. emu->x86.R_DX = (uint16_t) (res >> 16);
  7283. if (((emu->x86.R_AX & 0x8000) == 0 && emu->x86.R_DX == 0x00) ||
  7284. ((emu->x86.R_AX & 0x8000) != 0 && emu->x86.R_DX == 0xFF)) {
  7285. CLEAR_FLAG(F_CF);
  7286. CLEAR_FLAG(F_OF);
  7287. } else {
  7288. SET_FLAG(F_CF);
  7289. SET_FLAG(F_OF);
  7290. }
  7291. }
  7292. /*
  7293. * REMARKS:
  7294. * Implements the IMUL instruction and side effects.
  7295. */
  7296. static void
  7297. imul_long(struct x86emu *emu, uint32_t s)
  7298. {
  7299. int64_t res;
  7300. res = (int64_t)(int32_t)emu->x86.R_EAX * (int32_t)s;
  7301. emu->x86.R_EAX = (uint32_t)res;
  7302. emu->x86.R_EDX = ((uint64_t)res) >> 32;
  7303. if (((emu->x86.R_EAX & 0x80000000) == 0 && emu->x86.R_EDX == 0x00) ||
  7304. ((emu->x86.R_EAX & 0x80000000) != 0 && emu->x86.R_EDX == 0xFF)) {
  7305. CLEAR_FLAG(F_CF);
  7306. CLEAR_FLAG(F_OF);
  7307. } else {
  7308. SET_FLAG(F_CF);
  7309. SET_FLAG(F_OF);
  7310. }
  7311. }
  7312. /*
  7313. * REMARKS:
  7314. * Implements the MUL instruction and side effects.
  7315. */
  7316. static void
  7317. mul_byte(struct x86emu *emu, uint8_t s)
  7318. {
  7319. uint16_t res = (uint16_t) (emu->x86.R_AL * s);
  7320. emu->x86.R_AX = res;
  7321. if (emu->x86.R_AH == 0) {
  7322. CLEAR_FLAG(F_CF);
  7323. CLEAR_FLAG(F_OF);
  7324. } else {
  7325. SET_FLAG(F_CF);
  7326. SET_FLAG(F_OF);
  7327. }
  7328. }
  7329. /*
  7330. * REMARKS:
  7331. * Implements the MUL instruction and side effects.
  7332. */
  7333. static void
  7334. mul_word(struct x86emu *emu, uint16_t s)
  7335. {
  7336. uint32_t res = emu->x86.R_AX * s;
  7337. emu->x86.R_AX = (uint16_t) res;
  7338. emu->x86.R_DX = (uint16_t) (res >> 16);
  7339. if (emu->x86.R_DX == 0) {
  7340. CLEAR_FLAG(F_CF);
  7341. CLEAR_FLAG(F_OF);
  7342. } else {
  7343. SET_FLAG(F_CF);
  7344. SET_FLAG(F_OF);
  7345. }
  7346. }
  7347. /*
  7348. * REMARKS:
  7349. * Implements the MUL instruction and side effects.
  7350. */
  7351. static void
  7352. mul_long(struct x86emu *emu, uint32_t s)
  7353. {
  7354. uint64_t res = (uint64_t) emu->x86.R_EAX * s;
  7355. emu->x86.R_EAX = (uint32_t) res;
  7356. emu->x86.R_EDX = (uint32_t) (res >> 32);
  7357. if (emu->x86.R_EDX == 0) {
  7358. CLEAR_FLAG(F_CF);
  7359. CLEAR_FLAG(F_OF);
  7360. } else {
  7361. SET_FLAG(F_CF);
  7362. SET_FLAG(F_OF);
  7363. }
  7364. }
  7365. /*
  7366. * REMARKS:
  7367. * Implements the IDIV instruction and side effects.
  7368. */
  7369. static void
  7370. idiv_byte(struct x86emu *emu, uint8_t s)
  7371. {
  7372. int32_t dvd, div, mod;
  7373. dvd = (int16_t) emu->x86.R_AX;
  7374. if (s == 0) {
  7375. x86emu_intr_raise(emu, 8);
  7376. return;
  7377. }
  7378. div = dvd / (int8_t) s;
  7379. mod = dvd % (int8_t) s;
  7380. if (div > 0x7f || div < -0x7f) {
  7381. x86emu_intr_raise(emu, 8);
  7382. return;
  7383. }
  7384. emu->x86.R_AL = (int8_t) div;
  7385. emu->x86.R_AH = (int8_t) mod;
  7386. }
  7387. /*
  7388. * REMARKS:
  7389. * Implements the IDIV instruction and side effects.
  7390. */
  7391. static void
  7392. idiv_word(struct x86emu *emu, uint16_t s)
  7393. {
  7394. int32_t dvd, div, mod;
  7395. dvd = (((int32_t) emu->x86.R_DX) << 16) | emu->x86.R_AX;
  7396. if (s == 0) {
  7397. x86emu_intr_raise(emu, 8);
  7398. return;
  7399. }
  7400. div = dvd / (int16_t) s;
  7401. mod = dvd % (int16_t) s;
  7402. if (div > 0x7fff || div < -0x7fff) {
  7403. x86emu_intr_raise(emu, 8);
  7404. return;
  7405. }
  7406. CLEAR_FLAG(F_CF);
  7407. CLEAR_FLAG(F_SF);
  7408. CONDITIONAL_SET_FLAG(div == 0, F_ZF);
  7409. CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
  7410. emu->x86.R_AX = (uint16_t) div;
  7411. emu->x86.R_DX = (uint16_t) mod;
  7412. }
  7413. /*
  7414. * REMARKS:
  7415. * Implements the IDIV instruction and side effects.
  7416. */
  7417. static void
  7418. idiv_long(struct x86emu *emu, uint32_t s)
  7419. {
  7420. int64_t dvd, div, mod;
  7421. dvd = (((int64_t) emu->x86.R_EDX) << 32) | emu->x86.R_EAX;
  7422. if (s == 0) {
  7423. x86emu_intr_raise(emu, 8);
  7424. return;
  7425. }
  7426. div = dvd / (int32_t) s;
  7427. mod = dvd % (int32_t) s;
  7428. if (div > 0x7fffffff || div < -0x7fffffff) {
  7429. x86emu_intr_raise(emu, 8);
  7430. return;
  7431. }
  7432. CLEAR_FLAG(F_CF);
  7433. CLEAR_FLAG(F_AF);
  7434. CLEAR_FLAG(F_SF);
  7435. SET_FLAG(F_ZF);
  7436. CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
  7437. emu->x86.R_EAX = (uint32_t) div;
  7438. emu->x86.R_EDX = (uint32_t) mod;
  7439. }
  7440. /*
  7441. * REMARKS:
  7442. * Implements the DIV instruction and side effects.
  7443. */
  7444. static void
  7445. div_byte(struct x86emu *emu, uint8_t s)
  7446. {
  7447. uint32_t dvd, div, mod;
  7448. dvd = emu->x86.R_AX;
  7449. if (s == 0) {
  7450. x86emu_intr_raise(emu, 8);
  7451. return;
  7452. }
  7453. div = dvd / (uint8_t) s;
  7454. mod = dvd % (uint8_t) s;
  7455. if (div > 0xff) {
  7456. x86emu_intr_raise(emu, 8);
  7457. return;
  7458. }
  7459. emu->x86.R_AL = (uint8_t) div;
  7460. emu->x86.R_AH = (uint8_t) mod;
  7461. }
  7462. /*
  7463. * REMARKS:
  7464. * Implements the DIV instruction and side effects.
  7465. */
  7466. static void
  7467. div_word(struct x86emu *emu, uint16_t s)
  7468. {
  7469. uint32_t dvd, div, mod;
  7470. dvd = (((uint32_t) emu->x86.R_DX) << 16) | emu->x86.R_AX;
  7471. if (s == 0) {
  7472. x86emu_intr_raise(emu, 8);
  7473. return;
  7474. }
  7475. div = dvd / (uint16_t) s;
  7476. mod = dvd % (uint16_t) s;
  7477. if (div > 0xffff) {
  7478. x86emu_intr_raise(emu, 8);
  7479. return;
  7480. }
  7481. CLEAR_FLAG(F_CF);
  7482. CLEAR_FLAG(F_SF);
  7483. CONDITIONAL_SET_FLAG(div == 0, F_ZF);
  7484. CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
  7485. emu->x86.R_AX = (uint16_t) div;
  7486. emu->x86.R_DX = (uint16_t) mod;
  7487. }
  7488. /*
  7489. * REMARKS:
  7490. * Implements the DIV instruction and side effects.
  7491. */
  7492. static void
  7493. div_long(struct x86emu *emu, uint32_t s)
  7494. {
  7495. uint64_t dvd, div, mod;
  7496. dvd = (((uint64_t) emu->x86.R_EDX) << 32) | emu->x86.R_EAX;
  7497. if (s == 0) {
  7498. x86emu_intr_raise(emu, 8);
  7499. return;
  7500. }
  7501. div = dvd / (uint32_t) s;
  7502. mod = dvd % (uint32_t) s;
  7503. if (div > 0xffffffff) {
  7504. x86emu_intr_raise(emu, 8);
  7505. return;
  7506. }
  7507. CLEAR_FLAG(F_CF);
  7508. CLEAR_FLAG(F_AF);
  7509. CLEAR_FLAG(F_SF);
  7510. SET_FLAG(F_ZF);
  7511. CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
  7512. emu->x86.R_EAX = (uint32_t) div;
  7513. emu->x86.R_EDX = (uint32_t) mod;
  7514. }
  7515. /*
  7516. * REMARKS:
  7517. * Implements the IN string instruction and side effects.
  7518. */
  7519. static void
  7520. ins(struct x86emu *emu, int size)
  7521. {
  7522. int inc = size;
  7523. if (ACCESS_FLAG(F_DF)) {
  7524. inc = -size;
  7525. }
  7526. if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  7527. /* dont care whether REPE or REPNE */
  7528. /* in until CX is ZERO. */
  7529. uint32_t count = ((emu->x86.mode & SYSMODE_PREFIX_DATA) ?
  7530. emu->x86.R_ECX : emu->x86.R_CX);
  7531. switch (size) {
  7532. case 1:
  7533. while (count--) {
  7534. store_byte(emu, emu->x86.R_ES, emu->x86.R_DI,
  7535. (*emu->emu_inb) (emu, emu->x86.R_DX));
  7536. emu->x86.R_DI += inc;
  7537. }
  7538. break;
  7539. case 2:
  7540. while (count--) {
  7541. store_word(emu, emu->x86.R_ES, emu->x86.R_DI,
  7542. (*emu->emu_inw) (emu, emu->x86.R_DX));
  7543. emu->x86.R_DI += inc;
  7544. }
  7545. break;
  7546. case 4:
  7547. while (count--) {
  7548. store_long(emu, emu->x86.R_ES, emu->x86.R_DI,
  7549. (*emu->emu_inl) (emu, emu->x86.R_DX));
  7550. emu->x86.R_DI += inc;
  7551. break;
  7552. }
  7553. }
  7554. emu->x86.R_CX = 0;
  7555. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  7556. emu->x86.R_ECX = 0;
  7557. }
  7558. emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  7559. } else {
  7560. switch (size) {
  7561. case 1:
  7562. store_byte(emu, emu->x86.R_ES, emu->x86.R_DI,
  7563. (*emu->emu_inb) (emu, emu->x86.R_DX));
  7564. break;
  7565. case 2:
  7566. store_word(emu, emu->x86.R_ES, emu->x86.R_DI,
  7567. (*emu->emu_inw) (emu, emu->x86.R_DX));
  7568. break;
  7569. case 4:
  7570. store_long(emu, emu->x86.R_ES, emu->x86.R_DI,
  7571. (*emu->emu_inl) (emu, emu->x86.R_DX));
  7572. break;
  7573. }
  7574. emu->x86.R_DI += inc;
  7575. }
  7576. }
  7577. /*
  7578. * REMARKS:
  7579. * Implements the OUT string instruction and side effects.
  7580. */
  7581. static void
  7582. outs(struct x86emu *emu, int size)
  7583. {
  7584. int inc = size;
  7585. if (ACCESS_FLAG(F_DF)) {
  7586. inc = -size;
  7587. }
  7588. if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
  7589. /* dont care whether REPE or REPNE */
  7590. /* out until CX is ZERO. */
  7591. uint32_t count = ((emu->x86.mode & SYSMODE_PREFIX_DATA) ?
  7592. emu->x86.R_ECX : emu->x86.R_CX);
  7593. switch (size) {
  7594. case 1:
  7595. while (count--) {
  7596. (*emu->emu_outb) (emu, emu->x86.R_DX,
  7597. fetch_byte(emu, emu->x86.R_ES,
  7598. emu->x86.R_SI));
  7599. emu->x86.R_SI += inc;
  7600. }
  7601. break;
  7602. case 2:
  7603. while (count--) {
  7604. (*emu->emu_outw) (emu, emu->x86.R_DX,
  7605. fetch_word(emu, emu->x86.R_ES,
  7606. emu->x86.R_SI));
  7607. emu->x86.R_SI += inc;
  7608. }
  7609. break;
  7610. case 4:
  7611. while (count--) {
  7612. (*emu->emu_outl) (emu, emu->x86.R_DX,
  7613. fetch_long(emu, emu->x86.R_ES,
  7614. emu->x86.R_SI));
  7615. emu->x86.R_SI += inc;
  7616. break;
  7617. }
  7618. }
  7619. emu->x86.R_CX = 0;
  7620. if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
  7621. emu->x86.R_ECX = 0;
  7622. }
  7623. emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
  7624. } else {
  7625. switch (size) {
  7626. case 1:
  7627. (*emu->emu_outb) (emu, emu->x86.R_DX,
  7628. fetch_byte(emu, emu->x86.R_ES, emu->x86.R_SI));
  7629. break;
  7630. case 2:
  7631. (*emu->emu_outw) (emu, emu->x86.R_DX,
  7632. fetch_word(emu, emu->x86.R_ES, emu->x86.R_SI));
  7633. break;
  7634. case 4:
  7635. (*emu->emu_outl) (emu, emu->x86.R_DX,
  7636. fetch_long(emu, emu->x86.R_ES, emu->x86.R_SI));
  7637. break;
  7638. }
  7639. emu->x86.R_SI += inc;
  7640. }
  7641. }
  7642. /*
  7643. * REMARKS:
  7644. * Pushes a word onto the stack.
  7645. *
  7646. * NOTE: Do not inline this, as (*emu->emu_wrX) is already inline!
  7647. */
  7648. static void
  7649. push_word(struct x86emu *emu, uint16_t w)
  7650. {
  7651. emu->x86.R_SP -= 2;
  7652. store_word(emu, emu->x86.R_SS, emu->x86.R_SP, w);
  7653. }
  7654. /*
  7655. * REMARKS:
  7656. * Pushes a long onto the stack.
  7657. *
  7658. * NOTE: Do not inline this, as (*emu->emu_wrX) is already inline!
  7659. */
  7660. static void
  7661. push_long(struct x86emu *emu, uint32_t w)
  7662. {
  7663. emu->x86.R_SP -= 4;
  7664. store_long(emu, emu->x86.R_SS, emu->x86.R_SP, w);
  7665. }
  7666. /*
  7667. * REMARKS:
  7668. * Pops a word from the stack.
  7669. *
  7670. * NOTE: Do not inline this, as (*emu->emu_rdX) is already inline!
  7671. */
  7672. static uint16_t
  7673. pop_word(struct x86emu *emu)
  7674. {
  7675. uint16_t res;
  7676. res = fetch_word(emu, emu->x86.R_SS, emu->x86.R_SP);
  7677. emu->x86.R_SP += 2;
  7678. return res;
  7679. }
  7680. /*
  7681. * REMARKS:
  7682. * Pops a long from the stack.
  7683. *
  7684. * NOTE: Do not inline this, as (*emu->emu_rdX) is already inline!
  7685. */
  7686. static uint32_t
  7687. pop_long(struct x86emu *emu)
  7688. {
  7689. uint32_t res;
  7690. res = fetch_long(emu, emu->x86.R_SS, emu->x86.R_SP);
  7691. emu->x86.R_SP += 4;
  7692. return res;
  7693. }