FoxARMInstructionSet.Mod 122 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922
  1. MODULE FoxARMInstructionSet; (** AUTHOR ""; PURPOSE ""; *)
  2. IMPORT D := Debugging, Commands, Streams, Files, BinaryCode := FoxBinaryCode, Disassembler := FoxDisassembler, BitSets, Options, Strings, ObjectFile;
  3. CONST
  4. TraceDecode= FALSE;
  5. None*= -1;
  6. (* condition codes, values refer to encoding, do not modify *)
  7. conditionEQ*= 0;
  8. conditionNE*= 1;
  9. conditionCS*= 2;
  10. conditionHS*= 2;
  11. conditionCC*= 3;
  12. conditionLO*= 3;
  13. conditionMI*= 4;
  14. conditionPL*= 5;
  15. conditionVS*= 6;
  16. conditionVC*= 7;
  17. conditionHI*= 8;
  18. conditionLS*= 9;
  19. conditionGE*= 10;
  20. conditionLT*= 11;
  21. conditionGT*= 12;
  22. conditionLE*= 13;
  23. conditionAL*= 14;
  24. unconditional*= conditionAL;
  25. conditionNV*= 15;
  26. NumberConditionEntries*= 18;
  27. (* indexing flags, values have no meaning in encoding *)
  28. Increment*= 0;
  29. Decrement*= 1;
  30. PostIndexed*= 2;
  31. PreIndexed*= 3;
  32. (* mnemonics, values have no meaning for encoding
  33. FoxProgTools.Enum -l=4 opADC opADD opAND opB opBIC opBKPT opBL opBLX opBX opCDP opCDP2
  34. opCLZ opCMN opCMP opEOR
  35. opFABSD opFABSS opFADDD opFADDS opFCMPD
  36. opFCMPED opFCMPES opFCMPEZD opFCMPEZS
  37. opFCMPS opFCMPZD opFCMPZS opFCPYD opFCPYS opFCVTDS opFCVTSD
  38. opFDIVD opFDIVS opFLDD
  39. opFLDMIAD opFLDMIAS opFLDMIAX opFLDMDBD opFLDMDBS opFLDMDBX
  40. opFLDS
  41. opFMACD opFMACS opFMDHR opFMDLR opFMRDH opFMRDL opFMRS opFMRX
  42. opFMSCD opFMSCS opFMSR opFMSTAT opFMULD opFMULS opFMXR opFNEGD opFNEGS
  43. opFNMACD opFNMACS opFNMSCD opFNMSCS opFNMULD opFNMULS
  44. opFSITOD opFSITOS opFSQRTD opFSQRTS opFSTD opFSTMIAD opFSTMIAS opFSTMIAX opFSTMDBD opFSTMDBS opFSTMDBX
  45. opFSTS opFSUBD opFSUBS opFTOSID opFTOSIZD opFTOSIS opFTOSIZS opFTOUID opFTOUIZD opFTOUIS opFTOUIZS opFUITOD
  46. opFUITOS
  47. opLDC opLDC2 opLDM opLDR opMCR opMCR2
  48. opMCRR
  49. opMLA opMOV opMRC opMRC2 opMRRC
  50. opMRS opMSR opMUL opMVN opORR opPLD opQADD opQDADD opQDSUB opQSUB
  51. opRSB opRSC opSBC opSMLABB opSMLABT
  52. opSMLAL
  53. opSMLATB opSMLATT
  54. opSMLALBB opSMLALBT opSMLALTB opSMLALTT
  55. opSMLAWB opSMLAWT
  56. opSMULBB opSMULBT opSMULTB opSMULTT
  57. opSMULWB opSMULWT opSMULL
  58. opSTC opSTC2
  59. opSTM opSTR opSUB opSWI opSWP opTEQ opTST opUMLAL opUMULL
  60. NumberMnemonics ~
  61. *)
  62. opADC*= 0; opADD*= 1; opAND*= 2; opB*= 3;
  63. opBIC*= 4; opBKPT*= 5; opBL*= 6; opBLX*= 7;
  64. opBX*= 8; opCDP*= 9; opCDP2*= 10; opCLZ*= 11;
  65. opCMN*= 12; opCMP*= 13; opEOR*= 14; opFABSD*= 15;
  66. opFABSS*= 16; opFADDD*= 17; opFADDS*= 18; opFCMPD*= 19;
  67. opFCMPED*= 20; opFCMPES*= 21; opFCMPEZD*= 22; opFCMPEZS*= 23;
  68. opFCMPS*= 24; opFCMPZD*= 25; opFCMPZS*= 26; opFCPYD*= 27;
  69. opFCPYS*= 28; opFCVTDS*= 29; opFCVTSD*= 30; opFDIVD*= 31;
  70. opFDIVS*= 32; opFLDD*= 33; opFLDMIAD*= 34; opFLDMIAS*= 35;
  71. opFLDMIAX*= 36; opFLDMDBD*= 37; opFLDMDBS*= 38; opFLDMDBX*= 39;
  72. opFLDS*= 40; opFMACD*= 41; opFMACS*= 42; opFMDHR*= 43;
  73. opFMDLR*= 44; opFMRDH*= 45; opFMRDL*= 46; opFMRS*= 47;
  74. opFMRX*= 48; opFMSCD*= 49; opFMSCS*= 50; opFMSR*= 51;
  75. opFMSTAT*= 52; opFMULD*= 53; opFMULS*= 54; opFMXR*= 55;
  76. opFNEGD*= 56; opFNEGS*= 57; opFNMACD*= 58; opFNMACS*= 59;
  77. opFNMSCD*= 60; opFNMSCS*= 61; opFNMULD*= 62; opFNMULS*= 63;
  78. opFSITOD*= 64; opFSITOS*= 65; opFSQRTD*= 66; opFSQRTS*= 67;
  79. opFSTD*= 68; opFSTMIAD*= 69; opFSTMIAS*= 70; opFSTMIAX*= 71;
  80. opFSTMDBD*= 72; opFSTMDBS*= 73; opFSTMDBX*= 74; opFSTS*= 75;
  81. opFSUBD*= 76; opFSUBS*= 77; opFTOSID*= 78; opFTOSIZD*= 79;
  82. opFTOSIS*= 80; opFTOSIZS*= 81; opFTOUID*= 82; opFTOUIZD*= 83;
  83. opFTOUIS*= 84; opFTOUIZS*= 85; opFUITOD*= 86; opFUITOS*= 87;
  84. opLDC*= 88; opLDC2*= 89; opLDM*= 90; opLDR*= 91;
  85. opMCR*= 92; opMCR2*= 93; opMCRR*= 94; opMLA*= 95;
  86. opMOV*= 96; opMRC*= 97; opMRC2*= 98; opMRRC*= 99;
  87. opMRS*= 100; opMSR*= 101; opMUL*= 102; opMVN*= 103;
  88. opORR*= 104; opPLD*= 105; opQADD*= 106; opQDADD*= 107;
  89. opQDSUB*= 108; opQSUB*= 109; opRSB*= 110; opRSC*= 111;
  90. opSBC*= 112; opSMLABB*= 113; opSMLABT*= 114; opSMLAL*= 115;
  91. opSMLATB*= 116; opSMLATT*= 117; opSMLALBB*= 118; opSMLALBT*= 119;
  92. opSMLALTB*= 120; opSMLALTT*= 121; opSMLAWB*= 122; opSMLAWT*= 123;
  93. opSMULBB*= 124; opSMULBT*= 125; opSMULTB*= 126; opSMULTT*= 127;
  94. opSMULWB*= 128; opSMULWT*= 129; opSMULL*= 130; opSTC*= 131;
  95. opSTC2*= 132; opSTM*= 133; opSTR*= 134; opSUB*= 135;
  96. opSWI*= 136; opSWP*= 137; opTEQ*= 138; opTST*= 139;
  97. opUMLAL*= 140; opUMULL*= 141;
  98. (* Usual mnemonics, cont'd *)
  99. opISB* = 142;
  100. (* NEON mnemonics *)
  101. opVADD* = 143;
  102. opVADDL* = 144;
  103. opVADDW* = 145;
  104. opVMUL* = 146;
  105. opVMULL* = 147;
  106. opVMSR* = 148;
  107. opVMRS* = 149;
  108. opVLDR* = 150;
  109. opVSTR* = 151;
  110. opVDIV* = 152;
  111. opVMLA* = 153;
  112. opVMLS* = 154;
  113. opVMIN* = 155;
  114. opVMAX* = 156;
  115. opVSUB* = 157;
  116. opVABS* = 158;
  117. opVABD* = 159;
  118. (* Usual shifts *)
  119. opLSL* = 160;
  120. opLSR* = 161;
  121. (* More NEON *)
  122. opVLD1* = 162;
  123. opVST1* = 163;
  124. opVPADD* = 164;
  125. opVMOV* = 165;
  126. (* Non NEON Instructions *)
  127. opSEV* = 166;
  128. opDSB* = 167;
  129. opLDREX* = 168;
  130. opSTREX* = 169;
  131. opADR* = 170;
  132. opLDREXB* = 171;
  133. opSTREXB* = 172;
  134. opDMB* = 173;
  135. opCLREX* = 174;
  136. opREV* = 175;
  137. opREV16* = 176;
  138. opUXTH* = 177;
  139. opWFE* = 178;
  140. opWFI* = 179;
  141. NumberMnemonics*= 180;
  142. MaxOperands* = 6;
  143. (* flags values have no meaning for encoding
  144. FoxProgTools.Enum -l= 4
  145. flagB flagBT flagD flagDA flagDB flagH flagIA flagIB flagL flagS flagSB flagSH flagT
  146. NumberFlags flagCondition flagUserMode flagBaseRegisterUpdate ~
  147. *)
  148. flagB*= 0; flagBT*= 1; flagD*= 2; flagDA*= 3;
  149. flagDB*= 4; flagH*= 5; flagIA*= 6; flagIB*= 7;
  150. flagL*= 8; flagS*= 9; flagSB*= 10; flagSH*= 11;
  151. flagT*= 12;
  152. (*NumberFlags*= 13;*)
  153. (* NEON data type flags *)
  154. flagNEON8bits = 13; flagNEON16bits = 14; flagNEON32bits = 15; flagNEON64bits = 16;
  155. flagNEONInt = 17; flagNEONSigned = 18; flagNEONUnsigned = 19;
  156. flagNEONFloat = 20; flagNEONPoly = 21; flagNEONUndef = 22;
  157. NumberFlags* = 23;
  158. (* Flags not used *)
  159. flagCondition*= 23; flagUserMode*= 24;
  160. flagBaseRegisterUpdate*= 25;
  161. NumberInstructions= NumberMnemonics + 19;
  162. (* encoding types, values have no meaning for encoding
  163. FoxProgTools.Enum -l=4
  164. encodingR16 encodingR12 encodingR8 encodingR0
  165. encodingAddressingMode1
  166. encodingAddressingMode2
  167. encodingAddressingMode3
  168. encodingAddressingMode5
  169. encodingCoprocessor encodingCR0 encodingCR12 encodingCR16
  170. encodingOpcode20 encodingOpcode21 encodingOpcode5 encodingOpcode4 encodingSignedImm24 encodingImm24 encodingImm16 encodingRotImm8 encodingRegisterList
  171. encodingPSR encodingFields
  172. encodingDR0 encodingDR12 encodingDR16
  173. encodingFR0 encodingFR12 encodingFR16
  174. encodingDRegisterList encodingFRegisterList encodingAddressingMode5V
  175. ~
  176. *)
  177. encodingR16= 0; encodingR12= 1; encodingR8= 2; encodingR0= 3;
  178. encodingAddressingMode1= 4; encodingAddressingMode2= 5; encodingAddressingMode3= 6; encodingAddressingMode5= 7;
  179. encodingCoprocessor= 8; encodingCR0= 9; encodingCR12= 10; encodingCR16= 11;
  180. encodingOpcode20= 12; encodingOpcode21= 13; encodingOpcode5= 14; encodingOpcode4= 15;
  181. encodingSignedImm24= 16; encodingImm24= 17; encodingImm16= 18; encodingRotImm8= 19;
  182. encodingRegisterList= 20; encodingPSR= 21; encodingFields= 22; encodingDR0= 23;
  183. encodingDR12= 24; encodingDR16= 25; encodingFR0= 26; encodingFR12= 27;
  184. encodingFR16= 28; encodingDRegisterList= 29; encodingFRegisterList= 30; encodingAddressingMode5V= 31;
  185. (* NEON operand encoding. *)
  186. encodingNEONQd = 32; encodingNEONQn = 33; encodingNEONQm = 34;
  187. encodingNEONDd = 35; encodingNEONDn = 36; encodingNEONDm = 37;
  188. encodingNEONSd = 38; encodingNEONSn = 39; encodingNEONSm = 40;
  189. encodingNEONImmAndSize = 41; encodingNEON8bitImm = 42; (*at bit 0 *)
  190. encodingNEON3bitImm = 43;
  191. encodingNEONQorDd = 44; encodingNEONQorDn = 45; encodingNEONQorDm = 46;
  192. encodingNEONDorSd = 47; encodingNEONDorSn = 48; encodingNEONDorSm = 49;
  193. encodingNEONDRegList = 50; encodingNEONSysReg = 51; encodingNEONSigned8bitImm = 52;
  194. encodingImm7to11 = 53;
  195. (* NEON instruction mode encoding. These modes are used in EnterNEONInstruction. Values do not matter for encoding.
  196. The values mean (see the ARM manual):
  197. encodeNEON...
  198. ...3RegSame: 3 registers of the same type
  199. ...3RegDiff: 3 registers of different types
  200. ...2RegScalar: 2 registers and a scalar
  201. ...2RegShift: 2 registers and a shift
  202. ...2RegMisc: 2 registers miscellanous
  203. ...1RegImm: 1 register and an immediate
  204. ...VFP: VFP operation
  205. ...LS: load and stores
  206. ...Tx32: transfers up to 32bits
  207. ...Tx64: transfers of 64bits
  208. encodeNEON3RegSame = 0; encodeNEON3RegLong = 1; encodeNEON3RegNarrow = 2; encodeNEON3RegWide = 3;
  209. encodeNEON2RegScalar = 4; encodeNEON2RegScalarLong = 5;
  210. encodeNEON2RegShift = 6; encodeNEON2RegShiftNarrow = 7; encodeNEON2RegShiftLong = 8;
  211. encodeNEON2RegMisc = 9; encodeNEON2RegMiscNarrow = 10; encodeNEON2RegMiscLong = 11;
  212. encodeNEONVFP = 12; encodeNEONVFP2Reg = 13; encodeNEONVFP1Reg = 14;*)
  213. (* operand modes
  214. FoxProgTools.Enum -l= 4 modeImmediate modeRegister modeMemory modeOpcode modeCoprocessor
  215. modeRegisterList modeFields modeOption
  216. ~
  217. *)
  218. modeImmediate*= 0; modeRegister*= 1; modeMemory*= 2; modeOpcode*= 3;
  219. modeCoprocessor*= 4; modeRegisterList*= 5; modeRegisterWithFields*= 6; modeOption*= 7;
  220. (* registers, values have no meaning for encoding *)
  221. (* regular registers: *)
  222. R0*= 0; R1*= R0+1; R2*= R0+2; R3*= R0+3; R4*= R0+4; R5*= R0+5; R6*= R0+6; R7*= R0+7;
  223. R8*= R0+8; R9*= R0+9; R10*= R0+10; R11*= R0+11; R12*= R0+12; R13*= R0+13; R14*= R0+14; R15*= R0+15;
  224. (* coprocessor registers: *)
  225. CR0*= 16; CR1*= CR0+1; CR2*= CR0+2; CR3*= CR0+3; CR4*= CR0+4; CR5*= CR0+5; CR6*= CR0+6; CR7*= CR0+7;
  226. CR8*= CR0+8; CR9*= CR0+9; CR10*= CR0+10; CR11*= CR0+11; CR12*= CR0+12; CR13*= CR0+13; CR14*= CR0+14; CR15*= CR0+15;
  227. (* VFP double-precision registers: *)
  228. DR0*= 32; DR1*= DR0+1; DR2*= DR0+2; DR3*= DR0+3; DR4*= DR0+4; DR5*= DR0+5; DR6*= DR0+6; DR7*= DR0+7;
  229. DR8*= DR0+8; DR9*= DR0+9; DR10*= DR0+10; DR11*= DR0+11; DR12*= DR0+12; DR13*= DR0+13; DR14*= DR0+14; DR15*= DR0+15;
  230. (* Advanced SIMD doubleword registers *)
  231. DR16*= DR0+16; DR17*= DR0+17; DR18*= DR0+18; DR19*= DR0+19; DR20*= DR0+20; DR21*= DR0+21; DR22*= DR0+22;
  232. DR23*= DR0+23; DR24*= DR0+24; DR25*= DR0+25; DR26*= DR0+26; DR27*= DR0+27; DR28*= DR0+28; DR29*= DR0+29;
  233. DR30*= DR0+30; DR31*= DR0+31;
  234. (* VFP single-precision registers: *)
  235. SR0*= 64; SR1*= SR0+1; SR2*= SR0+2; SR3*= SR0+3; SR4*= SR0+4; SR5*= SR0+5; SR6*= SR0+6; SR7*= SR0+7;
  236. SR8*= SR0+8; SR9*= SR0+9; SR10*= SR0+10; SR11*= SR0+11; SR12*= SR0+12; SR13*= SR0+13; SR14*= SR0+14; SR15*= SR0+15;
  237. (* progran status registers *)
  238. CPSR*= 80; SPSR*= 81;
  239. (* Continue at 82 to skip CPSR and SPSR *)
  240. SR16*= 82; SR17*= SR0+17; SR18*= SR0+18; SR19*= SR0+19; SR20*= SR0+20; SR21*= SR0+21; SR22*= SR0+22; SR23*= SR0+23;
  241. SR24*= SR0+24; SR25*= SR0+25; SR26*= SR0+26; SR27*= SR0+27; SR28*= SR0+28; SR29*= SR0+29; SR30*= SR0+30; SR31*= SR0+31;
  242. (* NEON SIMD quadword registers *)
  243. QR0* = 98; QR1* = QR0 + 1; QR2* = QR0 + 2;QR3* = QR0 + 3; QR4* = QR0 + 4; QR5* = QR0 + 5; QR6* = QR0 + 6;
  244. QR7* = QR0 + 7; QR8* = QR0 + 8; QR9* = QR0 + 9; QR10* = QR0 + 10; QR11* = QR0 + 11; QR12* = QR0 + 12;
  245. QR13* = QR0 + 13; QR14* = QR0 + 14; QR15* = QR0 + 15;
  246. (* NEON System Registers *)
  247. FPSID* = 114; FPSCR* = 115; FPEXC* = 116;
  248. (* register aliases *)
  249. PC*= R15; LR*= R14; SP*= R13; FP*= R12; RESHI *= R1; RES *= R0; RESFS *= SR0; RESFD* = DR0;
  250. NumberRegisters*= 117; (* the number of physical registers *)
  251. NumberRegisterEntries*= 123; (* the number of register names *)
  252. (* shifts, do not modify: nunbers as in encoding*)
  253. shiftLSL*= 0;
  254. shiftLSR*= 1;
  255. shiftASR*= 2;
  256. shiftROR*= 3;
  257. shiftRRX*= 4;
  258. NumberShifts*= 5;
  259. (* coprocessors, do not modify: number as in encoding *)
  260. CP0* = 0; CP1* = 1; CP2* = 2; CP3* = 3; CP4* = 4; CP5* = 5; CP6* = 6; CP7* = 7;
  261. CP8* = 8; CP9* = 9; CP10* = 10; CP11* = 11; CP12* = 12; CP13* = 13; CP14* = 14; CP15* = 15;
  262. NumberCoprocessors* = 16;
  263. (* fields, do not modify: number order as in encoding *)
  264. fieldC* = 0;
  265. fieldX* = 1;
  266. fieldS* = 2;
  267. fieldF* = 3;
  268. Bits12*=4096;
  269. Bits10*=1024;
  270. Bits7*=128;
  271. Bits5*=32;
  272. (*
  273. ArmEncoding *= 0;
  274. ThumbEncoding *= 1;
  275. *)
  276. TYPE
  277. Name = ARRAY 10 OF CHAR;
  278. Entry = RECORD
  279. name: Name;
  280. number: LONGINT
  281. END;
  282. Mnemonic= RECORD
  283. name: Name;
  284. number: INTEGER;
  285. firstInstructionFormat, lastInstructionFormat: LONGINT; (* instructionFormats *)
  286. END;
  287. InstructionFormat= RECORD
  288. mnemonic: INTEGER;
  289. opcode, mask: SET;
  290. flags: SET;
  291. operands: ARRAY MaxOperands OF INTEGER;
  292. (* NEON specific *)
  293. isNEON: BOOLEAN;
  294. Unsigned, Quadword, Length, Float, Operation: SET;
  295. SizeH: INTEGER; (* The lower bit is SizeH - 1 *)
  296. END;
  297. Instruction*= RECORD
  298. format: LONGINT;
  299. condition: LONGINT;
  300. flags: SET;
  301. operands: ARRAY MaxOperands OF Operand;
  302. END;
  303. Operand*= RECORD
  304. mode*: INTEGER;
  305. register*: LONGINT;
  306. immediate*, shiftImmediate: LONGINT;
  307. shiftRegister: LONGINT;
  308. shiftMode: INTEGER;
  309. offsetImmediate: LONGINT;
  310. offsetRegister: LONGINT;
  311. indexing: SET; (* Increment, Decrement, PostIndexed PreIndexed*)
  312. registerList: SET;
  313. coprocessor: INTEGER;
  314. opcode: LONGINT;
  315. fields: SET;
  316. option: LONGINT;
  317. fixup-: BinaryCode.Fixup;
  318. END;
  319. VAR
  320. mnemonics: ARRAY NumberMnemonics OF Mnemonic;
  321. registerEntries: ARRAY NumberRegisterEntries OF Entry;
  322. conditionEntries: ARRAY NumberConditionEntries OF Entry;
  323. flagNames: ARRAY NumberFlags OF Name;
  324. shiftNames: ARRAY NumberShifts OF Name;
  325. coprocessorNames: ARRAY NumberCoprocessors OF Name;
  326. instructionFormats : ARRAY NumberInstructions OF InstructionFormat;
  327. (** get the number of a register by its name
  328. - 'None' is returned if no such register exists
  329. **)
  330. PROCEDURE RegisterNumberFromName*(registerName: ARRAY OF CHAR): LONGINT;
  331. VAR
  332. result, i: LONGINT;
  333. BEGIN
  334. Strings.UpperCase(registerName);
  335. result := None;
  336. (* go through all registers *)
  337. FOR i := 0 TO NumberRegisterEntries - 1 DO
  338. IF registerEntries[i].name = registerName THEN result := registerEntries[i].number END
  339. END;
  340. RETURN result
  341. END RegisterNumberFromName;
  342. (** get the number of a coprocessor by its name
  343. - 'None' is returned if no such mode exists
  344. **)
  345. PROCEDURE CoprocessorNumberFromName*(coprocessorName: ARRAY OF CHAR): LONGINT;
  346. VAR
  347. result, i: LONGINT;
  348. BEGIN
  349. Strings.UpperCase(coprocessorName);
  350. result := None;
  351. (* go through all coprocessors *)
  352. FOR i := 0 TO NumberCoprocessors - 1 DO
  353. IF coprocessorNames[i] = coprocessorName THEN result := i END
  354. END;
  355. RETURN result
  356. END CoprocessorNumberFromName;
  357. (** get the number of a shift mode by its name
  358. - 'None' is returned if no such mode exists
  359. **)
  360. PROCEDURE ShiftModeNumberFromName*(shiftModeName: ARRAY OF CHAR): LONGINT;
  361. VAR
  362. result, i: LONGINT;
  363. BEGIN
  364. Strings.UpperCase(shiftModeName);
  365. result := None;
  366. (* go through all shift modes *)
  367. FOR i := 0 TO NumberShifts - 1 DO
  368. IF shiftNames[i] = shiftModeName THEN result := i END
  369. END;
  370. RETURN result
  371. END ShiftModeNumberFromName;
  372. PROCEDURE FindMnemonic*(CONST name: ARRAY OF CHAR; VAR mnemonic, condition: LONGINT; VAR flags: SET): BOOLEAN;
  373. VAR i, pos, flagPos, format: LONGINT;
  374. PROCEDURE Contains(CONST this: ARRAY OF CHAR): BOOLEAN;
  375. VAR i: LONGINT;
  376. BEGIN
  377. ASSERT(this # "");
  378. i := 0;
  379. WHILE (name[pos+i] # 0X) & (this[i] # 0X) & (CAP(name[i+pos])= this[i]) DO INC(i) END;
  380. IF this[i]= 0X THEN
  381. INC(pos, i);
  382. RETURN TRUE
  383. ELSE
  384. RETURN FALSE
  385. END;
  386. END Contains;
  387. BEGIN
  388. ASSERT(name # "");
  389. mnemonic := NumberMnemonics;
  390. REPEAT
  391. DEC(mnemonic);
  392. flags := {};
  393. pos := 0;
  394. (* find matching mnemonic, not necessarily unique! *)
  395. WHILE (mnemonic >= 0) & ~Contains(mnemonics[mnemonic].name) DO DEC(mnemonic) END;
  396. IF mnemonic >= 0 THEN
  397. flagPos := pos;
  398. format := mnemonics[mnemonic].firstInstructionFormat;
  399. (* found mnemonic, check if flags match with at least one format *)
  400. REPEAT
  401. ASSERT(instructionFormats[format].mnemonic = mnemonic);
  402. pos := flagPos;
  403. (* conditions *)
  404. IF flagCondition IN instructionFormats[format].flags THEN
  405. (* read condition *)
  406. i := NumberConditionEntries-1;
  407. WHILE (i>= 0) &~Contains(conditionEntries[i].name) DO DEC(i) END;
  408. IF i # -1 THEN
  409. INCL(flags, flagCondition);
  410. condition := conditionEntries[i].number
  411. ELSE
  412. condition := conditionAL (* no condition: always execute *)
  413. END;
  414. ELSE
  415. condition := conditionAL
  416. END;
  417. (* read flags, have to go downward because of name inclusions *)
  418. i := NumberFlags-1;
  419. WHILE (i>=0) & (name[pos] # 0X) DO
  420. IF (i IN instructionFormats[format].flags) & Contains(flagNames[i]) THEN INCL(flags, i) END;
  421. DEC(i);
  422. END;
  423. INC(format);
  424. UNTIL (format > mnemonics[mnemonic].lastInstructionFormat) OR (name[pos] = 0X)
  425. END;
  426. UNTIL (mnemonic = None) OR (name[pos] = 0X);
  427. RETURN (mnemonic # None)
  428. END FindMnemonic;
  429. PROCEDURE InitInstruction*(VAR instruction: Instruction);
  430. VAR i : LONGINT;
  431. BEGIN
  432. instruction.format := None;
  433. instruction.condition := None;
  434. instruction.flags := {};
  435. FOR i := 0 TO LEN(instruction.operands)-1 DO
  436. InitOperand(instruction.operands[i]);
  437. END;
  438. END InitInstruction;
  439. (* generate immediate operand with fixup *)
  440. PROCEDURE InitFixup*(VAR operand: Operand; bits: SHORTINT; fixup: BinaryCode.Fixup (*symbol: Sections.Section; offset, displacement: LONGINT *));
  441. BEGIN
  442. operand.mode := modeImmediate;
  443. operand.immediate := 0;
  444. operand.fixup := fixup;
  445. (*
  446. operand.fixup := BinaryCode.NewFixup(BinaryCode.Absolute, 0, symbol, offset, displacement, 0, NIL);
  447. *)
  448. (*
  449. operand.symbol := symbol;
  450. operand.symbolOffset := offset;
  451. operand.displacement := displacement;
  452. *)
  453. END InitFixup;
  454. PROCEDURE AddFixup*(VAR operand: Operand; fixup: BinaryCode.Fixup);
  455. BEGIN
  456. ASSERT(operand.mode IN {modeImmediate, modeMemory});
  457. operand.fixup := fixup
  458. END AddFixup;
  459. PROCEDURE InitOperand*(VAR operand: Operand);
  460. BEGIN
  461. operand.mode := None;
  462. operand.register := None;
  463. operand.immediate := 0;
  464. operand.shiftImmediate := 0;
  465. operand.shiftRegister := None;
  466. operand.offsetRegister := None;
  467. operand.shiftMode := None;
  468. operand.offsetImmediate := 0;
  469. operand.indexing := {};
  470. operand.registerList := {};
  471. operand.coprocessor := None;
  472. operand.opcode := 0;
  473. operand.fields := {};
  474. operand.fixup := NIL;
  475. END InitOperand;
  476. PROCEDURE InitRegister*(VAR operand: Operand; registerNumber: LONGINT; shiftMode: LONGINT; shiftAmountRegisterNumber: LONGINT; shiftImmediate: LONGINT);
  477. BEGIN
  478. InitOperand(operand);
  479. operand.mode := modeRegister;
  480. operand.register := SHORT(registerNumber);
  481. operand.shiftMode := SHORT(shiftMode);
  482. operand.shiftRegister := SHORT(shiftAmountRegisterNumber);
  483. operand.shiftImmediate := shiftImmediate
  484. END InitRegister;
  485. PROCEDURE InitImmediate*(VAR operand: Operand; immediate: LONGINT);
  486. BEGIN
  487. InitOperand(operand); operand.mode := modeImmediate;
  488. operand.immediate := immediate;
  489. END InitImmediate;
  490. (* note that this is a memory operand to be used in a load/store instruction *)
  491. PROCEDURE InitImmediateOffsetMemory*(VAR operand: Operand; register: LONGINT; offset: LONGINT; indexing: SET);
  492. BEGIN
  493. InitOperand(operand); operand.mode := modeMemory;
  494. operand.register := SHORT(register);
  495. operand.offsetImmediate := offset;
  496. operand.indexing := indexing;
  497. END InitImmediateOffsetMemory;
  498. (* note that this is a memory operand to be used in a load/store instruction *)
  499. PROCEDURE InitRegisterOffsetMemory*(VAR operand: Operand; register, offsetRegister: LONGINT; shiftMode: LONGINT; shiftImmediate: LONGINT; indexing: SET);
  500. BEGIN
  501. InitOperand(operand); operand.mode := modeMemory;
  502. operand.register := SHORT(register);
  503. operand.offsetRegister := SHORT(offsetRegister);
  504. operand.indexing := indexing;
  505. IF operand.shiftImmediate < 0 THEN
  506. operand.shiftImmediate := -operand.shiftImmediate;
  507. INCL(operand.indexing, Decrement);
  508. EXCL(operand.indexing, Increment);
  509. END;
  510. operand.shiftMode := SHORT(shiftMode);
  511. operand.shiftImmediate := shiftImmediate;
  512. END InitRegisterOffsetMemory;
  513. PROCEDURE NewRegister*(registerNumber: LONGINT; shiftMode: LONGINT; shiftAmountRegisterNumber: LONGINT; shiftImmediate: LONGINT): Operand;
  514. VAR
  515. result: Operand;
  516. BEGIN
  517. InitRegister(result, registerNumber, shiftMode, shiftAmountRegisterNumber, shiftImmediate);
  518. RETURN result
  519. END NewRegister;
  520. PROCEDURE NewImmediate*(immediate: LONGINT): Operand;
  521. VAR
  522. result: Operand;
  523. BEGIN
  524. InitImmediate(result, immediate);
  525. RETURN result
  526. END NewImmediate;
  527. PROCEDURE NewImmediateOffsetMemory*(register: LONGINT; offset: LONGINT; indexing: SET): Operand;
  528. VAR
  529. result: Operand;
  530. BEGIN
  531. InitImmediateOffsetMemory(result, register, offset, indexing);
  532. RETURN result
  533. END NewImmediateOffsetMemory;
  534. PROCEDURE NewRegisterOffsetMemory*(register, offsetRegister: LONGINT; shiftMode: LONGINT; shiftImmediate: LONGINT; indexing: SET): Operand;
  535. VAR
  536. result: Operand;
  537. BEGIN
  538. InitRegisterOffsetMemory(result, register, offsetRegister, shiftMode, shiftImmediate, indexing);
  539. RETURN result
  540. END NewRegisterOffsetMemory;
  541. PROCEDURE NewRegisterList*(registerBase: LONGINT; registerList: SET): Operand;
  542. VAR
  543. result: Operand;
  544. BEGIN
  545. InitRegisterList(result, registerBase, registerList);
  546. RETURN result
  547. END NewRegisterList;
  548. PROCEDURE InitOption*(VAR operand: Operand; register: LONGINT; option: LONGINT);
  549. BEGIN
  550. InitOperand(operand); operand.mode := modeOption;
  551. operand.register := SHORT(register);
  552. operand.option := option;
  553. END InitOption;
  554. PROCEDURE InitCoprocessor*(VAR operand: Operand; coprocessor: LONGINT);
  555. BEGIN
  556. InitOperand(operand); operand.mode := modeCoprocessor;
  557. operand.coprocessor := SHORT(coprocessor);
  558. END InitCoprocessor;
  559. PROCEDURE InitOpcode*(VAR operand: Operand; opcode: LONGINT);
  560. BEGIN
  561. InitOperand(operand); operand.mode := modeOpcode;
  562. operand.opcode := opcode;
  563. END InitOpcode;
  564. PROCEDURE InitRegisterList*(VAR operand: Operand; registerBase: LONGINT; registerList: SET);
  565. BEGIN
  566. InitOperand(operand); operand.mode := modeRegisterList;
  567. operand.register := SHORT(registerBase); operand.registerList := registerList;
  568. END InitRegisterList;
  569. PROCEDURE InitRegisterWithFields*(VAR operand: Operand; registerNumber: LONGINT; fields: SET);
  570. BEGIN
  571. ASSERT((registerNumber = CPSR) OR (registerNumber = SPSR));
  572. InitOperand(operand);
  573. operand.mode := modeRegisterWithFields;
  574. operand.register := registerNumber;
  575. operand.fields := fields
  576. END InitRegisterWithFields;
  577. PROCEDURE NewRegisterWithFields*(registerNumber: LONGINT; fields: SET): Operand;
  578. VAR
  579. result: Operand;
  580. BEGIN
  581. InitRegisterWithFields(result, registerNumber, fields);
  582. RETURN result
  583. END NewRegisterWithFields;
  584. PROCEDURE MakeInstruction*(VAR instruction: Instruction; mnemonic, condition: LONGINT; flags: SET; CONST operands: ARRAY OF Operand): BOOLEAN;
  585. VAR
  586. format: InstructionFormat;
  587. i, dummyEncoding: LONGINT;
  588. result: BOOLEAN;
  589. PROCEDURE OperandMatches(encoding: LONGINT; CONST operand: Operand): BOOLEAN;
  590. BEGIN
  591. CASE encoding OF
  592. |None: RETURN operand.mode = None
  593. |encodingR16, encodingR12, encodingR8, encodingR0:
  594. RETURN (operand.mode = modeRegister) & (R0 <= operand.register) & (operand.register <= R15)
  595. |encodingFR0, encodingFR12, encodingFR16:
  596. RETURN (operand.mode = modeRegister) & (SR0 <= operand.register) & (operand.register <= SR31)
  597. |encodingDR0,encodingDR12, encodingDR16:
  598. RETURN (operand.mode = modeRegister) & (DR0 <= operand.register) & (operand.register <= DR15)
  599. |encodingCR0, encodingCR12, encodingCR16:
  600. RETURN (operand.mode = modeRegister) & (CR0 <= operand.register) & (operand.register <= CR15)
  601. |encodingAddressingMode1:
  602. RETURN (operand.mode = modeRegister) & (R0 <= operand.register) & (operand.register <= R15)
  603. OR (operand.mode = modeImmediate)
  604. |encodingAddressingMode2:
  605. RETURN (operand.mode = modeMemory)
  606. |encodingAddressingMode3:
  607. RETURN (operand.mode = modeMemory)
  608. |encodingAddressingMode5:
  609. RETURN (operand.mode = modeMemory) OR (operand.mode = modeOption)
  610. |encodingAddressingMode5V:
  611. RETURN (operand.mode = modeMemory)
  612. |encodingCoprocessor:
  613. RETURN (operand.mode = modeCoprocessor)
  614. |encodingFields:
  615. RETURN operand.mode = modeRegisterWithFields
  616. |encodingImm16,encodingSignedImm24,encodingImm24,encodingRotImm8, encodingImm7to11:
  617. RETURN operand.mode = modeImmediate
  618. |encodingOpcode20,encodingOpcode21,encodingOpcode5,encodingOpcode4:
  619. RETURN (operand.mode = modeOpcode) OR (operand.mode = None) (* note: missing opcode operand means opcode = 0 *)
  620. |encodingRegisterList, encodingDRegisterList, encodingFRegisterList:
  621. RETURN operand.mode = modeRegisterList
  622. |encodingPSR:
  623. RETURN (operand.mode = modeRegister) & ((operand.register = CPSR) OR (operand.register = SPSR))
  624. |encodingNEONQd, encodingNEONQm, encodingNEONQn:
  625. RETURN (operand.mode = modeRegister) & (QR0 <= operand.register) & (operand.register <= QR15)
  626. |encodingNEONDd, encodingNEONDm, encodingNEONDn:
  627. RETURN (operand.mode = modeRegister) & (DR0 <= operand.register) & (operand.register <= DR31)
  628. |encodingNEONSd, encodingNEONSm, encodingNEONSn:
  629. RETURN (operand.mode = modeRegister) & (SR0 <= operand.register) & (operand.register <= SR31)
  630. |encodingNEONQorDd, encodingNEONQorDm, encodingNEONQorDn:
  631. RETURN (operand.mode = modeRegister) & (((DR0 <= operand.register) & (operand.register <= DR31))
  632. OR ((QR0 <= operand.register) & (operand.register <= QR15)))
  633. |encodingNEONDorSd, encodingNEONDorSm, encodingNEONDorSn:
  634. RETURN (operand.mode = modeRegister) & (((DR0 <= operand.register) & (operand.register <= DR15))
  635. OR ((SR0 <= operand.register) & (operand.register <= SR31)))
  636. |encodingNEONImmAndSize, encodingNEON8bitImm, encodingNEON3bitImm, encodingNEONSigned8bitImm:
  637. RETURN operand.mode = modeImmediate
  638. |encodingNEONDRegList:
  639. RETURN operand.mode = modeRegisterList
  640. |encodingNEONSysReg:
  641. RETURN (operand.mode = modeRegister) & (FPSID <= operand.register) & (operand.register <= FPEXC)
  642. ELSE RETURN FALSE
  643. END;
  644. END OperandMatches;
  645. PROCEDURE Matches(CONST format: InstructionFormat): BOOLEAN;
  646. VAR i: LONGINT;
  647. BEGIN
  648. IF mnemonic # format.mnemonic THEN RETURN FALSE END; (* different mnemonic *)
  649. IF (instruction.condition # conditionAL) & (instruction.condition # None) & ~(flagCondition IN format.flags) THEN (* not always case for encoding problems of BLX which comes in two forms *)
  650. RETURN FALSE END; (* unpermitted condition *)
  651. IF instruction.flags * format.flags # instruction.flags THEN
  652. RETURN FALSE END; (* unpermitted flags*)
  653. i := 0;
  654. WHILE (i<MaxOperands) & OperandMatches(format.operands[i], instruction.operands[i]) DO
  655. INC(i);
  656. END;
  657. RETURN i= MaxOperands;
  658. END Matches;
  659. BEGIN
  660. instruction.condition := condition;
  661. instruction.flags := flags;
  662. FOR i := 0 TO LEN(operands)-1 DO
  663. instruction.operands[i] := operands[i]
  664. END;
  665. FOR i := LEN(operands) TO LEN(instruction.operands)-1 DO
  666. InitOperand(instruction.operands[i]);
  667. END;
  668. result := FALSE; i := mnemonics[mnemonic].firstInstructionFormat;
  669. WHILE (result = FALSE) & (i<=mnemonics[mnemonic].lastInstructionFormat) DO
  670. format := instructionFormats[i];
  671. IF Matches(format) THEN
  672. instruction.format := i;
  673. result := TRUE
  674. END;
  675. INC(i);
  676. END;
  677. (* TODO: remove later on: *)
  678. IF ~result THEN
  679. D.String("error: did not find matching instruction format for the following mnemonic and operands:"); D.Ln;
  680. D.String(mnemonics[mnemonic].name); D.Int(mnemonic, 0); D.Ln;
  681. FOR i := 0 TO LEN(operands) - 1 DO
  682. D.String(" operand #"); D.Int(i, 0); D.String(":"); D.Ln;
  683. D.String(" "); DumpOperand(D.Log, instruction.operands[i]); D.Ln; D.Ln
  684. END
  685. END;
  686. RETURN result
  687. END MakeInstruction;
  688. PROCEDURE NumberToSet(code: LONGINT): SET;
  689. VAR i: LONGINT; set: SET;
  690. BEGIN
  691. ASSERT(MAX(SET) >= 31);
  692. set := {};
  693. FOR i := 0 TO 31 DO
  694. IF ODD(code) THEN INCL(set, i) END;
  695. code := code DIV 2;
  696. END;
  697. RETURN set
  698. END NumberToSet;
  699. PROCEDURE SetToNumber(set: SET): LONGINT;
  700. VAR i, num: LONGINT;
  701. BEGIN
  702. ASSERT(MAX(SET) >= 31);
  703. num := 0;
  704. FOR i := 0 TO 31 DO
  705. IF i IN set THEN INC(num, ASH(1, i)) END;
  706. END;
  707. RETURN num
  708. END SetToNumber;
  709. PROCEDURE RotateRight(val, rot: LONGINT): LONGINT;
  710. VAR set: SET; i, dest: LONGINT;
  711. BEGIN
  712. set := NumberToSet(val);
  713. dest := 0;
  714. FOR i := 0 TO 31 DO
  715. IF i IN set THEN
  716. INC(dest, ASH(1, (i-rot) MOD 32));
  717. END;
  718. END;
  719. RETURN dest
  720. END RotateRight;
  721. PROCEDURE EncodeImmediate*(imm: LONGINT; VAR val,rot: LONGINT): BOOLEAN;
  722. VAR immSet: SET; i: LONGINT;
  723. PROCEDURE RotateLeft(set: SET; rot: LONGINT): SET;
  724. VAR i: LONGINT; result: SET;
  725. BEGIN
  726. result := {};
  727. FOR i := 0 TO 31 DO
  728. IF i IN set THEN INCL(result,(i+rot) MOD 32) END;
  729. END;
  730. RETURN result
  731. END RotateLeft;
  732. BEGIN
  733. immSet := NumberToSet(imm);
  734. rot := 0;
  735. WHILE (rot<16) & (immSet*{8..31} # {}) DO
  736. INC(rot,1); immSet := RotateLeft(immSet,2);
  737. END;
  738. val := 0;
  739. FOR i := 7 TO 0 BY -1 DO
  740. val := val*2;
  741. IF i IN immSet THEN INC(val) END;
  742. END;
  743. RETURN rot <16
  744. END EncodeImmediate;
  745. PROCEDURE Encode(CONST instruction: Instruction; VAR code: LONGINT): BOOLEAN;
  746. VAR
  747. format: InstructionFormat; codeSet: SET; i: LONGINT; error: BOOLEAN;
  748. flags: SET;
  749. CONST
  750. P=24; U=23; B=22; W=21; L=20; S=6; H=5;
  751. PROCEDURE Unsigned(val: LONGINT; from,to: LONGINT);
  752. VAR i: LONGINT;
  753. BEGIN
  754. FOR i := from TO to DO
  755. IF ODD(val) THEN INCL(codeSet,i) END;
  756. val := val DIV 2;
  757. END;
  758. IF val # 0 THEN error := TRUE END;
  759. IF error THEN D.TraceBack END
  760. END Unsigned;
  761. (* Encode an unsigned value on a non-contiguous set of bits, specifying the order.
  762. val: value to encode
  763. positions: array of bit positions, from the lowest to the highest.
  764. The end of the encoding region is signaled by:
  765. end of the array
  766. a position has value 32
  767. *)
  768. PROCEDURE SplittedUnsigned(val: LONGINT; positions: ARRAY OF INTEGER);
  769. VAR
  770. i, len: LONGINT;
  771. BEGIN
  772. ASSERT(LEN(positions) <= 32);
  773. FOR i := 0 TO LEN(positions) - 1 DO ASSERT(positions[i] <= 32); ASSERT(positions[i] >= 0) END;
  774. i := 0;
  775. WHILE (i < LEN(positions)) & (positions[i] # 32) DO INC(i) END;
  776. len := i;
  777. (*D.String("Splitted unsigned length: "); D.Int(i, 0); D.Ln;*)
  778. FOR i := 0 TO len - 1 DO
  779. IF ODD(val) THEN INCL(codeSet, positions[i]) END;
  780. val := val DIV 2;
  781. END;
  782. IF val # 0 THEN error := TRUE; D.TraceBack END
  783. END SplittedUnsigned;
  784. PROCEDURE Bits(val: SET; from,to: LONGINT);
  785. VAR i: LONGINT;
  786. BEGIN
  787. FOR i := from TO to DO
  788. IF i-from IN val THEN INCL(codeSet,i) END;
  789. END;
  790. IF val * {to-from+1..31} # {} THEN error := TRUE END;
  791. END Bits;
  792. PROCEDURE Signed(val: LONGINT; from,to: LONGINT);
  793. VAR i: LONGINT; negate: BOOLEAN;
  794. BEGIN
  795. negate := val < 0;
  796. IF negate THEN val := -val -1 END;
  797. FOR i := from TO to-1 DO
  798. IF ODD(val) THEN
  799. IF ~negate THEN INCL(codeSet,i) END;
  800. ELSIF negate THEN
  801. INCL(codeSet,i)
  802. END;
  803. val := val DIV 2;
  804. END;
  805. IF negate THEN INCL(codeSet, to) END;
  806. IF (val # 0) THEN error := TRUE END;
  807. END Signed;
  808. PROCEDURE Range(set: SET; VAR first, num: LONGINT): BOOLEAN;
  809. BEGIN
  810. i := 0;
  811. WHILE (i<32) & ~(i IN set) DO INC(i) END;
  812. first := i;
  813. WHILE (i<32) & (i IN set) DO INC(i) END;
  814. num := i-first;
  815. WHILE (i<32) & ~(i IN set) DO INC(i) END;
  816. IF i<32 THEN RETURN FALSE ELSE RETURN TRUE END;
  817. END Range;
  818. (** check immediate shifts and adopt special rules **)
  819. PROCEDURE CheckImmediateShifts(VAR shiftMode, shiftImmediate: LONGINT);
  820. BEGIN
  821. CASE shiftMode OF
  822. | None:
  823. (* no shift -> encode as LSL 0 *)
  824. shiftMode := shiftLSL;
  825. shiftImmediate := 0
  826. | shiftLSL:
  827. IF shiftImmediate < 0 THEN
  828. error := TRUE
  829. ELSIF shiftImmediate > 31 THEN
  830. D.String("LSL with more than 31 bits"); D.Ln; (* note that LSL 32 is disallowed *)
  831. error := TRUE
  832. END
  833. | shiftLSR, shiftASR:
  834. IF (shiftImmediate < 0) OR (shiftImmediate > 32) THEN
  835. error := TRUE
  836. ELSIF shiftImmediate = 0 THEN
  837. shiftMode := shiftLSL; (* note that LSR 0, ASR 0 are disallowed -> encode as LSL 0 *)
  838. shiftImmediate := 0
  839. ELSIF shiftImmediate = 32 THEN
  840. shiftImmediate := 0 (* 32 is encoded as 0 in this case! *)
  841. END
  842. | shiftROR:
  843. IF (shiftImmediate < 0) OR (shiftImmediate > 32) THEN
  844. error := TRUE
  845. ELSIF (shiftImmediate = 0) OR (shiftImmediate = 32) THEN
  846. shiftMode := shiftLSL; (* note that ROR 0 has a different meaning -> encode as LSL 0 *)
  847. shiftImmediate := 0
  848. END
  849. | shiftRRX:
  850. IF shiftImmediate = 1 THEN
  851. (* RRX is encoded as ROR 0 *)
  852. shiftMode := shiftROR;
  853. shiftImmediate := 0
  854. ELSE
  855. (* note that only shifts by 1 are allowed *)
  856. error := TRUE
  857. END
  858. ELSE
  859. HALT(100)
  860. END
  861. END CheckImmediateShifts;
  862. PROCEDURE EncodeOperand(operandEncoding: LONGINT; CONST operand: Operand);
  863. VAR
  864. imm, rot, firstRegister, num, shiftMode, shiftImmediate: LONGINT;
  865. NEONRegisterPos: ARRAY 5 OF INTEGER;
  866. PROCEDURE Fixup(from, to: LONGINT);
  867. VAR patterns: ObjectFile.FixupPatterns; displacement: LONGINT; mode: SHORTINT;
  868. BEGIN
  869. NEW(patterns, 1);
  870. patterns[0].offset := from; patterns[0].bits := to-from+1;
  871. (*ASSERT(format.mnemonic = opBL); currently only implemented for this case *)
  872. (*
  873. IF (opBL <= instructionFormat.mnemonic) & (instructionFormat.mnemonic <= opBF) THEN
  874. *)
  875. IF (format.mnemonic = opB) OR (format.mnemonic = opBL) THEN
  876. mode := BinaryCode.Relative;
  877. displacement := operand.fixup.displacement - 8;
  878. ELSE
  879. mode := BinaryCode.Relative;
  880. displacement := operand.fixup.displacement;
  881. END;
  882. (*
  883. ELSE
  884. mode := BinaryCode.Absolute;
  885. displacement := op.fixup.displacement;
  886. END;
  887. *)
  888. operand.fixup.InitFixup(mode, 0, operand.fixup.symbol, operand.fixup.symbolOffset, displacement, -2, patterns);
  889. END Fixup;
  890. BEGIN
  891. CASE operandEncoding OF
  892. |None: error := operand.mode # None;
  893. |encodingR16, encodingR12,encodingR8, encodingR0:
  894. IF operand.mode # modeRegister THEN error := TRUE
  895. ELSIF operand.shiftMode # None THEN error := TRUE
  896. ELSIF (operand.register < R0) OR (operand.register > R15) THEN error := TRUE
  897. END;
  898. CASE operandEncoding OF
  899. |encodingR16: Unsigned(operand.register-R0,16,19);
  900. |encodingR12: Unsigned(operand.register-R0,12,15);
  901. |encodingR8: Unsigned(operand.register-R0,8,11);
  902. |encodingR0: Unsigned(operand.register-R0,0,3);
  903. END;
  904. |encodingCR0, encodingCR12, encodingCR16:
  905. IF operand.mode # modeRegister THEN error := TRUE
  906. ELSIF operand.shiftMode # None THEN error := TRUE
  907. ELSIF (operand.register < CR0) OR (operand.register > CR15) THEN error := TRUE
  908. END;
  909. CASE operandEncoding OF
  910. |encodingCR16: Unsigned(operand.register - CR0,16,19);
  911. |encodingCR12: Unsigned(operand.register - CR0,12,15);
  912. |encodingCR0: Unsigned(operand.register - CR0,0,3);
  913. END;
  914. |encodingDR0, encodingDR12, encodingDR16:
  915. IF operand.mode # modeRegister THEN error := TRUE
  916. ELSIF operand.shiftMode # None THEN error := TRUE
  917. ELSIF (operand.register < DR0) OR (operand.register > DR15) THEN error := TRUE
  918. END;
  919. CASE operandEncoding OF
  920. |encodingDR16: Unsigned(operand.register-DR0,16,19);
  921. |encodingDR12: Unsigned(operand.register-DR0,12,15);
  922. |encodingDR0: Unsigned(operand.register-DR0,0,3);
  923. END;
  924. |encodingFR0, encodingFR12, encodingFR16:
  925. IF operand.mode # modeRegister THEN error := TRUE
  926. ELSIF operand.shiftMode # None THEN error := TRUE
  927. ELSIF (operand.register < SR0) OR (operand.register > SR31) THEN error := TRUE
  928. END;
  929. CASE operandEncoding OF
  930. |encodingFR16: Unsigned((operand.register-SR0) MOD 16,16,19); Unsigned((operand.register-SR0) DIV 16,7,7);
  931. |encodingFR12: Unsigned((operand.register-SR0) MOD 16,12,15); Unsigned((operand.register-SR0) DIV 16,22,22);
  932. |encodingFR0: Unsigned((operand.register-SR0) MOD 16,0,3);Unsigned((operand.register-SR0) DIV 16,5,5);
  933. END;
  934. |encodingAddressingMode1:
  935. IF operand.mode = modeImmediate THEN
  936. INCL(codeSet,25);
  937. IF ~EncodeImmediate(operand.immediate, imm,rot) THEN
  938. (*HALT(201);*)
  939. error := TRUE
  940. END;
  941. Unsigned(imm,0,7); Unsigned(rot,8,11);
  942. ELSIF (operand.mode = modeRegister) & (operand.shiftRegister # None) THEN
  943. INCL(codeSet,4);
  944. Unsigned(operand.register-R0,0,3);
  945. ASSERT(operand.shiftMode # None);
  946. Unsigned(operand.shiftMode,5,6);
  947. Unsigned(operand.shiftRegister-R0,8,11);
  948. ELSIF operand.mode = modeRegister THEN
  949. shiftMode := operand.shiftMode;
  950. shiftImmediate := operand.shiftImmediate;
  951. CheckImmediateShifts(shiftMode, shiftImmediate);
  952. Unsigned(shiftMode,5,6);
  953. Unsigned(shiftImmediate,7,11);
  954. Unsigned(operand.register-R0,0,3)
  955. ELSE error := TRUE
  956. END;
  957. |encodingAddressingMode2:
  958. IF operand.mode = modeMemory THEN
  959. IF Increment IN operand.indexing THEN INCL(codeSet,U) ELSE ASSERT(Decrement IN operand.indexing) END;
  960. IF PreIndexed IN operand.indexing THEN
  961. INCL(codeSet,W); INCL(codeSet,P)
  962. ELSIF PostIndexed IN operand.indexing THEN
  963. (* P bit remains cleared *)
  964. ELSE
  965. INCL(codeSet,P)
  966. END;
  967. Unsigned(operand.register-R0,16,19);
  968. IF operand.offsetRegister = None THEN
  969. Unsigned(operand.offsetImmediate,0,11);
  970. ELSE
  971. INCL(codeSet,25);
  972. shiftMode := operand.shiftMode;
  973. shiftImmediate := operand.shiftImmediate;
  974. CheckImmediateShifts(shiftMode, shiftImmediate);
  975. Unsigned(shiftMode,5,6);
  976. Unsigned(shiftImmediate,7,11);
  977. Unsigned(operand.offsetRegister-R0,0,3)
  978. END;
  979. ELSE
  980. error := TRUE
  981. END;
  982. |encodingAddressingMode3:
  983. IF Increment IN operand.indexing THEN INCL(codeSet,U) ELSE ASSERT(Decrement IN operand.indexing) END;
  984. IF PreIndexed IN operand.indexing THEN INCL(codeSet,W); INCL(codeSet,P)
  985. ELSIF PostIndexed IN operand.indexing THEN (* P = 0, W= 0 : post indexed addressing *)
  986. ELSE INCL(codeSet, P); (* P=1, W= 0: offset addressing *)
  987. END;
  988. Unsigned(operand.register-R0,16,19);
  989. IF operand.offsetRegister = None THEN
  990. INCL(codeSet,B);
  991. Unsigned(operand.offsetImmediate MOD 16,0,3); Unsigned(operand.offsetImmediate DIV 16,8,11);
  992. ELSE
  993. Unsigned(operand.offsetRegister-R0,0,3);
  994. END
  995. |encodingAddressingMode5:
  996. IF Increment IN operand.indexing THEN INCL(codeSet,U) ELSE ASSERT(Decrement IN operand.indexing) END;
  997. IF PreIndexed IN operand.indexing THEN
  998. INCL(codeSet,P); INCL(codeSet,W);
  999. ELSIF PostIndexed IN operand.indexing THEN
  1000. INCL(codeSet,W)
  1001. END;
  1002. IF operand.mode = modeMemory THEN
  1003. IF ~(W IN codeSet) THEN INCL(codeSet,U) END;
  1004. Unsigned(operand.register-R0,16,19);
  1005. Unsigned(operand.offsetImmediate DIV 4,0,7);
  1006. ELSIF operand.mode = modeOption THEN
  1007. Unsigned(operand.register-R0,16,18);
  1008. Unsigned(operand.mode,0,7);
  1009. ELSE error := TRUE
  1010. END;
  1011. |encodingAddressingMode5V:
  1012. IF Increment IN operand.indexing THEN INCL(codeSet,U) ELSE ASSERT(Decrement IN operand.indexing) END;
  1013. Unsigned(operand.register-R0,16,19);
  1014. Unsigned(operand.offsetImmediate DIV 4,0,7);
  1015. |encodingCoprocessor:
  1016. IF operand.mode # modeCoprocessor THEN
  1017. error := TRUE
  1018. END;
  1019. Unsigned(operand.coprocessor,8,11);
  1020. |encodingOpcode20, encodingOpcode21, encodingOpcode5, encodingOpcode4:
  1021. IF operand.mode # modeOpcode THEN
  1022. IF operand.mode = None THEN (* note: missing opcode operand means opcode = 0 *)
  1023. ASSERT(operand.opcode = 0)
  1024. ELSE
  1025. error := TRUE
  1026. END
  1027. END;
  1028. CASE operandEncoding OF
  1029. encodingOpcode20: Unsigned(operand.opcode,20,23);
  1030. |encodingOpcode21: Unsigned(operand.opcode,21,23);
  1031. |encodingOpcode5: Unsigned(operand.opcode,5,7);
  1032. |encodingOpcode4: Unsigned(operand.opcode,4,7);
  1033. END;
  1034. |encodingSignedImm24:
  1035. IF operand.mode # modeImmediate THEN
  1036. error := TRUE
  1037. END;
  1038. IF operand.immediate MOD 4 # 0 THEN error := TRUE END;
  1039. Signed(operand.immediate DIV 4,0,23);
  1040. IF operand.fixup # NIL THEN Fixup(0, 23) END;
  1041. |encodingImm24:
  1042. IF operand.mode # modeImmediate THEN
  1043. error := TRUE
  1044. END;
  1045. Unsigned(operand.immediate,0,23);
  1046. |encodingImm16:
  1047. IF operand.mode # modeImmediate THEN
  1048. error := TRUE
  1049. END;
  1050. Unsigned(operand.immediate MOD 16,0,3); Unsigned(operand.immediate DIV 16,9,19);
  1051. |encodingRotImm8:
  1052. IF operand.mode # modeImmediate THEN
  1053. error := TRUE
  1054. ELSIF ~EncodeImmediate(operand.immediate, imm,rot) THEN
  1055. error := TRUE
  1056. END;
  1057. Unsigned(imm,0,7); Unsigned(rot,8,11);
  1058. |encodingRegisterList:
  1059. IF operand.mode # modeRegisterList THEN
  1060. error := TRUE
  1061. ELSIF operand.register # R0 THEN error := TRUE
  1062. END;
  1063. Bits(operand.registerList,0,15);
  1064. |encodingPSR:
  1065. IF (operand.mode # modeRegister) THEN error := TRUE
  1066. ELSIF ~((operand.mode # CPSR) & (operand.mode # SPSR)) THEN error := TRUE
  1067. END;
  1068. IF operand.register = SPSR THEN
  1069. INCL(codeSet,22);
  1070. END;
  1071. |encodingFields:
  1072. IF operand.mode # modeRegisterWithFields THEN
  1073. error := TRUE
  1074. END;
  1075. IF operand.register = SPSR THEN INCL(codeSet,22)
  1076. ELSIF operand.register # CPSR THEN error := TRUE
  1077. END;
  1078. Bits(operand.fields,16,19);
  1079. |encodingDRegisterList:
  1080. IF operand.mode # modeRegisterList THEN error := TRUE
  1081. ELSIF operand.register # DR0 THEN error := TRUE
  1082. ELSIF ~Range(operand.registerList,firstRegister, num) THEN error := TRUE
  1083. END;
  1084. Unsigned(firstRegister,12,15); Unsigned(num*2,0,7);
  1085. |encodingFRegisterList:
  1086. IF operand.mode # modeRegisterList THEN error := TRUE
  1087. ELSIF operand.register # DR0 THEN error := TRUE
  1088. ELSIF ~Range(operand.registerList,firstRegister, num) THEN error := TRUE
  1089. END;
  1090. Unsigned(firstRegister MOD 2,22,22); Unsigned(num,0,7);
  1091. Unsigned(firstRegister DIV 2,12,15); Unsigned(num,0,7);
  1092. |encodingImm7to11:
  1093. IF operand.mode # modeImmediate THEN
  1094. error := TRUE
  1095. END;
  1096. Unsigned(operand.immediate, 7, 11);
  1097. (* NEON specific operand encodings *)
  1098. |encodingNEONQd, encodingNEONQm, encodingNEONQn:
  1099. IF operand.mode # modeRegister THEN error := TRUE
  1100. ELSIF operand.shiftMode # None THEN error := TRUE
  1101. (* Check register type for each subcase *)
  1102. ELSIF (operand.register < QR0) OR (operand.register > QR15) THEN error := TRUE
  1103. END;
  1104. CASE operandEncoding OF
  1105. encodingNEONQd:
  1106. NEONRegisterPos[0] := 13;
  1107. NEONRegisterPos[1] := 14;
  1108. NEONRegisterPos[2] := 15;
  1109. NEONRegisterPos[3] := 22;
  1110. |encodingNEONQm:
  1111. NEONRegisterPos[0] := 1;
  1112. NEONRegisterPos[1] := 2;
  1113. NEONRegisterPos[2] := 3;
  1114. NEONRegisterPos[3] := 5;
  1115. |encodingNEONQn:
  1116. NEONRegisterPos[0] := 17;
  1117. NEONRegisterPos[1] := 18;
  1118. NEONRegisterPos[2] := 19;
  1119. NEONRegisterPos[3] := 7;
  1120. END;
  1121. NEONRegisterPos[4] := 32; (* end of encoding *)
  1122. SplittedUnsigned(operand.register - QR0, NEONRegisterPos)
  1123. |encodingNEONDd, encodingNEONDm, encodingNEONDn:
  1124. IF operand.mode # modeRegister THEN error := TRUE
  1125. ELSIF operand.shiftMode # None THEN error := TRUE
  1126. ELSIF (operand.register < DR0) OR (operand.register > DR31) THEN error := TRUE
  1127. END;
  1128. CASE operandEncoding OF
  1129. encodingNEONDd:
  1130. NEONRegisterPos[0] := 12;
  1131. NEONRegisterPos[1] := 13;
  1132. NEONRegisterPos[2] := 14;
  1133. NEONRegisterPos[3] := 15;
  1134. NEONRegisterPos[4] := 22;
  1135. |encodingNEONDm:
  1136. NEONRegisterPos[0] := 0;
  1137. NEONRegisterPos[1] := 1;
  1138. NEONRegisterPos[2] := 2;
  1139. NEONRegisterPos[3] := 3;
  1140. NEONRegisterPos[4] := 5;
  1141. |encodingNEONDn:
  1142. NEONRegisterPos[0] := 16;
  1143. NEONRegisterPos[1] := 17;
  1144. NEONRegisterPos[2] := 18;
  1145. NEONRegisterPos[3] := 19;
  1146. NEONRegisterPos[4] := 7;
  1147. END;
  1148. SplittedUnsigned(operand.register - DR0, NEONRegisterPos)
  1149. |encodingNEONSd, encodingNEONSm, encodingNEONSn:
  1150. IF operand.mode # modeRegister THEN error := TRUE
  1151. ELSIF operand.shiftMode # None THEN error := TRUE
  1152. ELSIF (operand.register < SR0) OR (operand.register > SR31) THEN error := TRUE
  1153. END;
  1154. CASE operandEncoding OF
  1155. encodingNEONSd:
  1156. NEONRegisterPos[0] := 22;
  1157. NEONRegisterPos[1] := 12;
  1158. NEONRegisterPos[2] := 13;
  1159. NEONRegisterPos[3] := 14;
  1160. NEONRegisterPos[4] := 15;
  1161. |encodingNEONSm:
  1162. NEONRegisterPos[0] := 5;
  1163. NEONRegisterPos[1] := 0;
  1164. NEONRegisterPos[2] := 1;
  1165. NEONRegisterPos[3] := 2;
  1166. NEONRegisterPos[4] := 3;
  1167. |encodingNEONSn:
  1168. NEONRegisterPos[0] := 7;
  1169. NEONRegisterPos[1] := 16;
  1170. NEONRegisterPos[2] := 17;
  1171. NEONRegisterPos[3] := 18;
  1172. NEONRegisterPos[4] := 19;
  1173. END;
  1174. SplittedUnsigned(operand.register - SR0, NEONRegisterPos)
  1175. |encodingNEONQorDd, encodingNEONQorDm, encodingNEONQorDn:
  1176. IF operand.mode # modeRegister THEN error := TRUE
  1177. ELSIF operand.shiftMode # None THEN error := TRUE
  1178. ELSIF (DR0 <= operand.register) & (operand.register <= DR31) THEN
  1179. CASE operandEncoding OF
  1180. encodingNEONQorDd:
  1181. NEONRegisterPos[0] := 12;
  1182. NEONRegisterPos[1] := 13;
  1183. NEONRegisterPos[2] := 14;
  1184. NEONRegisterPos[3] := 15;
  1185. NEONRegisterPos[4] := 22;
  1186. |encodingNEONQorDm:
  1187. NEONRegisterPos[0] := 0;
  1188. NEONRegisterPos[1] := 1;
  1189. NEONRegisterPos[2] := 2;
  1190. NEONRegisterPos[3] := 3;
  1191. NEONRegisterPos[4] := 5;
  1192. |encodingNEONQorDn:
  1193. NEONRegisterPos[0] := 16;
  1194. NEONRegisterPos[1] := 17;
  1195. NEONRegisterPos[2] := 18;
  1196. NEONRegisterPos[3] := 19;
  1197. NEONRegisterPos[4] := 7;
  1198. END;
  1199. SplittedUnsigned(operand.register - DR0, NEONRegisterPos);
  1200. ELSIF (QR0 <= operand.register) & (operand.register <= QR15) THEN
  1201. CASE operandEncoding OF
  1202. encodingNEONQorDd:
  1203. NEONRegisterPos[0] := 13;
  1204. NEONRegisterPos[1] := 14;
  1205. NEONRegisterPos[2] := 15;
  1206. NEONRegisterPos[3] := 22;
  1207. |encodingNEONQorDm:
  1208. NEONRegisterPos[0] := 1;
  1209. NEONRegisterPos[1] := 2;
  1210. NEONRegisterPos[2] := 3;
  1211. NEONRegisterPos[3] := 5;
  1212. |encodingNEONQorDn:
  1213. NEONRegisterPos[0] := 17;
  1214. NEONRegisterPos[1] := 18;
  1215. NEONRegisterPos[2] := 19;
  1216. NEONRegisterPos[3] := 7;
  1217. END;
  1218. NEONRegisterPos[4] := 32;
  1219. SplittedUnsigned(operand.register - QR0, NEONRegisterPos);
  1220. ELSE error := TRUE
  1221. END
  1222. |encodingNEONDorSd, encodingNEONDorSm, encodingNEONDorSn:
  1223. IF operand.mode # modeRegister THEN error := TRUE
  1224. ELSIF operand.shiftMode # None THEN error := TRUE
  1225. ELSIF (DR0 <= operand.register) & (operand.register <= DR15) THEN
  1226. CASE operandEncoding OF
  1227. encodingNEONDorSd:
  1228. NEONRegisterPos[0] := 12;
  1229. NEONRegisterPos[1] := 13;
  1230. NEONRegisterPos[2] := 14;
  1231. NEONRegisterPos[3] := 15;
  1232. NEONRegisterPos[4] := 22;
  1233. |encodingNEONDorSm:
  1234. NEONRegisterPos[0] := 0;
  1235. NEONRegisterPos[1] := 1;
  1236. NEONRegisterPos[2] := 2;
  1237. NEONRegisterPos[3] := 3;
  1238. NEONRegisterPos[4] := 5;
  1239. |encodingNEONDorSn:
  1240. NEONRegisterPos[0] := 16;
  1241. NEONRegisterPos[1] := 17;
  1242. NEONRegisterPos[2] := 18;
  1243. NEONRegisterPos[3] := 19;
  1244. NEONRegisterPos[4] := 7;
  1245. END;
  1246. SplittedUnsigned(operand.register - DR0, NEONRegisterPos)
  1247. ELSIF (SR0 <= operand.register) & (operand.register <= SR31) THEN
  1248. CASE operandEncoding OF
  1249. encodingNEONDorSd:
  1250. NEONRegisterPos[0] := 22;
  1251. NEONRegisterPos[1] := 12;
  1252. NEONRegisterPos[2] := 13;
  1253. NEONRegisterPos[3] := 14;
  1254. NEONRegisterPos[4] := 15;
  1255. |encodingNEONDorSm:
  1256. NEONRegisterPos[0] := 5;
  1257. NEONRegisterPos[1] := 0;
  1258. NEONRegisterPos[2] := 1;
  1259. NEONRegisterPos[3] := 2;
  1260. NEONRegisterPos[4] := 3;
  1261. |encodingNEONDorSn:
  1262. NEONRegisterPos[0] := 7;
  1263. NEONRegisterPos[1] := 16;
  1264. NEONRegisterPos[2] := 17;
  1265. NEONRegisterPos[3] := 18;
  1266. NEONRegisterPos[4] := 19;
  1267. END;
  1268. SplittedUnsigned(operand.register - SR0, NEONRegisterPos)
  1269. ELSE error := TRUE
  1270. END
  1271. |encodingNEON8bitImm:
  1272. IF operand.mode # modeImmediate THEN error := TRUE END;
  1273. Unsigned(operand.immediate DIV 4, 0, 7);
  1274. |encodingNEONDRegList:
  1275. IF operand.mode # modeRegisterList THEN error := TRUE
  1276. ELSIF operand.register # DR0 THEN error := TRUE
  1277. ELSIF ~Range(operand.registerList, firstRegister, num) THEN error := TRUE
  1278. END;
  1279. (* First register is encoded as Dd *)
  1280. NEONRegisterPos[0] := 12;
  1281. NEONRegisterPos[1] := 13;
  1282. NEONRegisterPos[2] := 14;
  1283. NEONRegisterPos[3] := 15;
  1284. NEONRegisterPos[4] := 22;
  1285. SplittedUnsigned(DR0 + firstRegister, NEONRegisterPos);
  1286. (* bits 8 to 11 specify the length of the list *)
  1287. CASE num OF
  1288. 1: Unsigned(7H, 8, 11)
  1289. |2: Unsigned(0AH, 8, 11)
  1290. |3: Unsigned(6H, 8, 11)
  1291. |4: Unsigned(2H, 8, 11)
  1292. ELSE
  1293. D.String("Register list too long");
  1294. error := TRUE
  1295. END
  1296. |encodingNEONSysReg:
  1297. IF operand.mode # modeRegister THEN error := TRUE
  1298. ELSIF operand.shiftMode # None THEN error := TRUE
  1299. ELSIF (operand.register < FPSID) & (operand.register > FPEXC) THEN error := TRUE
  1300. END;
  1301. CASE operand.register OF
  1302. (* FPSID - 0b0; FPSCR - 0b1; FPEXC - 0b1000 at bits 19:16 *)
  1303. FPSCR: INCL(codeSet, 16)
  1304. |FPEXC: INCL(codeSet, 19)
  1305. END
  1306. |encodingNEONSigned8bitImm:
  1307. IF operand.mode # modeImmediate THEN
  1308. error := TRUE
  1309. END;
  1310. Unsigned(operand.immediate DIV 4,0,7)
  1311. END;
  1312. (* TODO: remove later on: *)
  1313. IF error THEN
  1314. D.String("cannot encode operand:"); D.Ln;
  1315. DumpOperand(D.Log, operand); D.Ln;
  1316. D.String("expected operand encoding: "); D.Int(operandEncoding, 0); D.Ln
  1317. END
  1318. END EncodeOperand;
  1319. (** Manages the encoding of the types and sizes of a NEON instruction. *)
  1320. PROCEDURE EncodeNEONTypes(format: InstructionFormat; instruction: Instruction);
  1321. VAR
  1322. normalSizeEncoding: BOOLEAN;
  1323. i, immOperand: INTEGER;
  1324. BEGIN
  1325. IF ~format.isNEON THEN RETURN END;
  1326. (* Set the Unsigned bit *)
  1327. IF flagNEONUnsigned IN instruction.flags THEN
  1328. codeSet := codeSet + format.Unsigned
  1329. END;
  1330. (* We also set the unsigned bit for positive immediates encoded by encodingNEONSigned8bitimm *)
  1331. FOR i := 0 TO MaxOperands -1 DO
  1332. IF (format.operands[i] = encodingNEONSigned8bitImm) & (instruction.operands[i].immediate >= 0) THEN
  1333. codeSet := codeSet + format.Unsigned
  1334. END
  1335. END;
  1336. (* Set the Float bit *)
  1337. IF flagNEONFloat IN instruction.flags THEN
  1338. codeSet := codeSet + format.Float
  1339. END;
  1340. (* Set the Q bit *)
  1341. FOR i := 0 TO MaxOperands - 1 DO
  1342. CASE format.operands[i] OF
  1343. encodingNEONQorDd, encodingNEONQorDm, encodingNEONQorDn:
  1344. IF (QR0 <= instruction.operands[i].register) & (instruction.operands[i].register <= QR15) THEN
  1345. codeSet := codeSet + format.Quadword
  1346. END
  1347. |encodingNEONDorSd, encodingNEONDorSm, encodingNEONDorSn:
  1348. IF (DR0 <= instruction.operands[i].register) & (instruction.operands[i].register <= DR15) THEN
  1349. codeSet := codeSet + format.Quadword
  1350. END
  1351. ELSE
  1352. END
  1353. END;
  1354. (* Check the type of size encoding *)
  1355. normalSizeEncoding := TRUE;
  1356. FOR i := 0 TO MaxOperands - 1 DO
  1357. IF (format.operands[i] = encodingNEONImmAndSize) THEN
  1358. immOperand := i;
  1359. normalSizeEncoding := FALSE
  1360. END
  1361. END;
  1362. IF normalSizeEncoding THEN
  1363. IF format.SizeH # 32 THEN
  1364. (* Set the size bit for usual encoding *)
  1365. IF flagNEON16bits IN instruction.flags THEN
  1366. INCL(codeSet, format.SizeH - 1)
  1367. ELSIF flagNEON32bits IN instruction.flags THEN
  1368. INCL(codeSet, format.SizeH)
  1369. ELSIF flagNEON64bits IN instruction.flags THEN
  1370. INCL(codeSet, format.SizeH);
  1371. INCL(codeSet, format.SizeH - 1);
  1372. (* for floating-points *)
  1373. codeSet := codeSet + format.Operation;
  1374. END
  1375. END
  1376. ELSE
  1377. (* size and imm encoding done here *)
  1378. IF flagNEON8bits IN instruction.flags THEN
  1379. INCL(codeSet, 19);
  1380. ELSIF flagNEON16bits IN instruction.flags THEN
  1381. INCL(codeSet, 18);
  1382. ELSIF flagNEON32bits IN instruction.flags THEN
  1383. INCL(codeSet, 17);
  1384. ELSIF flagNEON64bits IN instruction.flags THEN
  1385. codeSet := codeSet + format.Length
  1386. END
  1387. END;
  1388. END EncodeNEONTypes;
  1389. BEGIN
  1390. error := FALSE;
  1391. IF instruction.format = None THEN error := TRUE
  1392. ELSE
  1393. format := instructionFormats[instruction.format];
  1394. codeSet := format.opcode;
  1395. (*
  1396. D.String(mnemonics[format.mnemonic].name); D.Ln;
  1397. D.String("encoding "); D.Int(instruction.format,1); D.Ln;
  1398. D.Set(codeSet); D.Ln;
  1399. *)
  1400. EncodeNEONTypes(format, instruction);
  1401. IF flagCondition IN format.flags THEN
  1402. Unsigned(instruction.condition,28,31);
  1403. END;
  1404. flags := format.flags * instruction.flags;
  1405. IF flagB IN flags THEN INCL(codeSet,B) END;
  1406. IF flagBT IN flags THEN INCL(codeSet,B); INCL(codeSet,W) END;
  1407. IF flagD IN flags THEN INCL(codeSet,S) END;
  1408. IF flagDA IN flags THEN END;
  1409. IF flagDB IN flags THEN INCL(codeSet,P) END;
  1410. IF flagH IN flags THEN INCL(codeSet,H) END;
  1411. IF flagIA IN flags THEN INCL(codeSet,U) END;
  1412. IF flagIB IN flags THEN INCL(codeSet,U); INCL(codeSet,P) END;
  1413. IF flagL IN flags THEN INCL(codeSet,22) END;
  1414. IF flagS IN flags THEN INCL(codeSet,20) END;
  1415. IF flagSB IN flags THEN INCL(codeSet,S) END;
  1416. IF flagSH IN flags THEN INCL(codeSet,S); INCL(codeSet,H) END;
  1417. IF flagT IN flags THEN END;
  1418. IF flagUserMode IN flags THEN INCL(codeSet,22) END;
  1419. IF flagBaseRegisterUpdate IN flags THEN INCL(codeSet,21) END;
  1420. i := 0;
  1421. WHILE (i < LEN(instruction.operands)) & ~error DO
  1422. EncodeOperand(format.operands[i], instruction.operands[i]);
  1423. (* D.Set(codeSet); D.Ln; *)
  1424. INC(i);
  1425. END;
  1426. END;
  1427. code := SetToNumber(codeSet);
  1428. IF error THEN D.String("cannot encode instruction"); D.Ln END;
  1429. RETURN ~error
  1430. END Encode;
  1431. PROCEDURE Decode(code: LONGINT; VAR instruction: Instruction): BOOLEAN;
  1432. VAR
  1433. instrNr, operandNr: LONGINT; format: InstructionFormat; codeSet: SET;
  1434. P, U, B, W, L, S, H: BOOLEAN; done: BOOLEAN;
  1435. PROCEDURE Match(CONST format: InstructionFormat): BOOLEAN;
  1436. BEGIN
  1437. RETURN codeSet*format.mask= format.opcode*format.mask
  1438. END Match;
  1439. PROCEDURE Bits(from, to: LONGINT): SET;
  1440. VAR i: LONGINT; val: SET;
  1441. BEGIN
  1442. val := {};
  1443. FOR i := from TO to DO
  1444. IF i IN codeSet THEN INCL(val, i-from) END;
  1445. END;
  1446. RETURN val
  1447. END Bits;
  1448. PROCEDURE Unsigned(from, to: LONGINT): LONGINT;
  1449. VAR val, i: LONGINT;
  1450. BEGIN
  1451. val := 0;
  1452. FOR i := to TO from BY -1 DO
  1453. val := val*2;
  1454. IF i IN codeSet THEN INC(val) END;
  1455. END;
  1456. RETURN val
  1457. END Unsigned;
  1458. PROCEDURE Signed(from, to: LONGINT): LONGINT;
  1459. VAR val, i: LONGINT; negative:BOOLEAN;
  1460. BEGIN
  1461. val := 0;
  1462. negative := to IN codeSet; (* two's complement negate *)
  1463. FOR i := to-1 TO from BY -1 DO
  1464. val := val*2;
  1465. IF (i IN codeSet) THEN
  1466. IF ~negative THEN INC(val) END;
  1467. ELSIF negative THEN
  1468. INC(val)
  1469. END;
  1470. END;
  1471. IF negative THEN INC(val); val := -val; END;
  1472. RETURN val
  1473. END Signed;
  1474. PROCEDURE DecodeOperand(encoding: LONGINT; VAR operand: Operand): BOOLEAN;
  1475. VAR imm, rot, register, shift, shiftRegister, shiftImm, offsetRegister: LONGINT; indexing: SET; firstRegister, lastRegister: LONGINT;
  1476. BEGIN
  1477. CASE encoding OF
  1478. |None: InitOperand(operand);
  1479. |encodingR16: InitRegister(operand, R0+Unsigned(16, 19), None, None, 0);
  1480. |encodingR12: InitRegister(operand, R0+Unsigned(12, 15), None, None, 0);
  1481. |encodingR8: InitRegister(operand, R0+Unsigned(8, 11), None, None, 0);
  1482. |encodingR0: InitRegister(operand, R0+Unsigned(0, 3), None, None, 0);
  1483. |encodingFR0: InitRegister(operand, SR0+Unsigned(0, 3)+16*Unsigned(5,5), None, None, 0);
  1484. |encodingFR12: InitRegister(operand, SR0+Unsigned(12, 15)+16*Unsigned(22,22), None, None, 0);
  1485. |encodingFR16: InitRegister(operand, SR0+Unsigned(16, 19)+16*Unsigned(7,7), None, None, 0);
  1486. |encodingDR0: InitRegister(operand, DR0+Unsigned(0, 3), None, None, 0);
  1487. |encodingDR12: InitRegister(operand, DR0+Unsigned(12, 15), None, None, 0);
  1488. |encodingDR16: InitRegister(operand, DR0+Unsigned(16, 19), None, None, 0);
  1489. |encodingCR0: InitRegister(operand, CR0+Unsigned(0, 3), None, None, 0);
  1490. |encodingCR12: InitRegister(operand, CR0+Unsigned(12, 15), None, None, 0);
  1491. |encodingCR16: InitRegister(operand, CR0+Unsigned(16, 19), None, None, 0);
  1492. |encodingAddressingMode1:
  1493. IF 25 IN codeSet THEN (* rotate immediate *)
  1494. imm := Unsigned(0, 7); rot := Unsigned(8, 11); imm := RotateRight(imm, rot*2);
  1495. InitImmediate(operand, imm);
  1496. ELSIF 4 IN codeSet THEN (* register register shift *)
  1497. IF 7 IN codeSet THEN RETURN FALSE END;
  1498. (* ASSERT(~(7 IN codeSet)); *)
  1499. shift := Unsigned(5, 6);
  1500. register := Unsigned(0, 3);
  1501. shiftRegister := Unsigned(8, 11);
  1502. imm := 0;
  1503. InitRegister(operand, register, shift, shiftRegister, imm);
  1504. ELSE (* register immediate shift *)
  1505. shiftRegister := None;
  1506. shift := Unsigned(5, 6);
  1507. register := Unsigned(0, 3);
  1508. imm := Unsigned(7, 11);
  1509. IF (shift= 0) & (imm= 0) THEN shift := None END;
  1510. IF (shift= 3) & (imm= 0) THEN shift := shiftRRX END;
  1511. InitRegister(operand, register, shift, shiftRegister, imm);
  1512. END;
  1513. |encodingAddressingMode2:
  1514. IF TraceDecode THEN D.String("AddressMode2"); D.Ln; END;
  1515. indexing := {};
  1516. IF U THEN INCL(indexing, Increment) ELSE INCL(indexing, Decrement) END;
  1517. IF ~P THEN INCL(indexing, PostIndexed)
  1518. ELSIF W THEN INCL(indexing, PreIndexed)
  1519. END;
  1520. register := Unsigned(16, 19);
  1521. IF ~(25 IN codeSet) THEN (* immediate offset *)
  1522. IF TraceDecode THEN D.String("ImmediateOffset"); D.Ln; END;
  1523. imm := Unsigned(0, 11);
  1524. InitImmediateOffsetMemory(operand, register, imm, indexing);
  1525. ELSE (* register offset / scaled register offset *)
  1526. IF (4 IN codeSet) THEN RETURN FALSE END;
  1527. IF TraceDecode THEN D.String("RegisterOffset"); D.Ln; END;
  1528. offsetRegister := Unsigned(0, 3);
  1529. shift := Unsigned(5, 6);
  1530. shiftImm := Unsigned(7, 11);
  1531. IF (shift= 0) & (shiftImm= 0) THEN shift := None END;
  1532. IF (shiftImm = 0) & (shift IN {shiftLSR, shiftASR}) THEN shiftImm := 32 END;
  1533. IF (shift= shiftROR) & (shiftImm = 0) THEN shift := shiftRRX; shiftImm := 1 END;
  1534. InitRegisterOffsetMemory(operand, register, offsetRegister, shift, shiftImm, indexing);
  1535. END;
  1536. |encodingAddressingMode3:
  1537. indexing := {};
  1538. IF ~S & ~H THEN RETURN FALSE END;
  1539. IF S & ~L THEN RETURN FALSE END;
  1540. (* IF ~P & ~W THEN unpredictable instruction END; *)
  1541. IF U THEN INCL(indexing, Increment) ELSE INCL(indexing, Decrement) END;
  1542. IF ~P THEN INCL(indexing, PostIndexed)
  1543. ELSIF W THEN INCL(indexing, PreIndexed)
  1544. END;
  1545. register := Unsigned(16, 19);
  1546. IF B THEN (* immediate offset *)
  1547. imm := Unsigned(0, 3)+16*Unsigned(8, 11);
  1548. InitImmediateOffsetMemory(operand, register, imm, indexing);
  1549. ELSE (* register offset *)
  1550. offsetRegister := Unsigned(0, 3);
  1551. InitRegisterOffsetMemory(operand, register, offsetRegister, None, 0, indexing);
  1552. END;
  1553. |encodingAddressingMode5:
  1554. IF U THEN INCL(indexing, Increment) ELSE INCL(indexing, Decrement) END;
  1555. IF P THEN
  1556. IF W THEN INCL(indexing, PreIndexed) END;
  1557. ELSE
  1558. IF W THEN INCL(indexing, PostIndexed) END;
  1559. END;
  1560. IF U OR W THEN
  1561. InitImmediateOffsetMemory(operand, Unsigned(16, 19), Unsigned(0, 7)*4, indexing);
  1562. ELSE
  1563. InitOption(operand, Unsigned(16, 19), Unsigned(0, 7));
  1564. END;
  1565. |encodingAddressingMode5V:
  1566. IF U THEN INCL(indexing,Increment) ELSE INCL(indexing, Decrement) END;
  1567. InitImmediateOffsetMemory(operand,Unsigned(16,19),Unsigned(0,7)*4,indexing);
  1568. |encodingCoprocessor: InitCoprocessor(operand, Unsigned(8, 11));
  1569. |encodingFields: IF 22 IN codeSet THEN register := SPSR ELSE register := CPSR END; InitRegisterWithFields(operand, register,Bits(16, 19));
  1570. |encodingImm16: imm := Unsigned(0, 3)+Unsigned(8, 19)*16; InitImmediate(operand, imm);
  1571. |encodingSignedImm24: imm := Signed(0, 23); InitImmediate(operand, imm*4);
  1572. |encodingImm24: imm := Unsigned(0, 23); InitImmediate(operand, imm);
  1573. |encodingRotImm8: imm := Unsigned(0, 7); rot := Unsigned(8, 11); imm := RotateRight(imm, rot*2); InitImmediate(operand, imm);
  1574. |encodingOpcode20: InitOpcode(operand, Unsigned(20, 23));
  1575. |encodingOpcode21: InitOpcode(operand, Unsigned(21, 23));
  1576. |encodingOpcode5: InitOpcode(operand, Unsigned(5, 7));
  1577. |encodingOpcode4: InitOpcode(operand,Unsigned(4,6));
  1578. |encodingRegisterList: InitRegisterList(operand, R0, Bits(0, 15));
  1579. |encodingDRegisterList: firstRegister := Unsigned(12,15); lastRegister := firstRegister + Unsigned(0,7) DIV 2 -1;
  1580. InitRegisterList(operand, DR0, {firstRegister .. lastRegister});
  1581. |encodingFRegisterList: firstRegister := Unsigned(12,15)*2+Unsigned(22,22); lastRegister := firstRegister + Unsigned(0,7) -1;
  1582. IF lastRegister >= 32 THEN RETURN FALSE END;
  1583. InitRegisterList(operand, SR0, {firstRegister .. lastRegister});
  1584. |encodingPSR: InitRegister(operand, CPSR+Unsigned(22, 22), None, None, 0);
  1585. ELSE (*! should trap *)
  1586. RETURN FALSE
  1587. END;
  1588. RETURN TRUE
  1589. END DecodeOperand;
  1590. BEGIN
  1591. codeSet := NumberToSet(code);
  1592. IF TraceDecode THEN
  1593. D.String("decoding:"); D.Hex(code, -8); D.String(":"); D.Set(codeSet); D.Ln;
  1594. END;
  1595. P := 24 IN codeSet;
  1596. U := 23 IN codeSet;
  1597. B := 22 IN codeSet;
  1598. W := 21 IN codeSet;
  1599. L := 20 IN codeSet;
  1600. S := 6 IN codeSet;
  1601. H := 5 IN codeSet;
  1602. instrNr := 0; done := FALSE;
  1603. WHILE (instrNr<NumberInstructions) & ~done DO
  1604. done := Match(instructionFormats[instrNr]);
  1605. IF done THEN
  1606. InitInstruction(instruction);
  1607. IF TraceDecode THEN
  1608. D.String("format:"); D.Int(instrNr, 1); D.String(":"); D.String(mnemonics[instructionFormats[instrNr].mnemonic].name); D.Ln;
  1609. END;
  1610. instruction.format := instrNr;
  1611. format := instructionFormats[instrNr];
  1612. IF flagCondition IN format.flags THEN
  1613. instruction.condition := Unsigned(28, 31);
  1614. IF TraceDecode THEN
  1615. D.String("condition: "); D.Int(instruction.condition, 1); D.Ln;
  1616. END;
  1617. ELSE
  1618. instruction.condition := None;
  1619. END;
  1620. IF flagB IN format.flags THEN
  1621. IF B & ~P & ~W THEN INCL(instruction.flags, flagB) END;
  1622. END;
  1623. IF flagBT IN format.flags THEN
  1624. IF B & ~P & W THEN INCL(instruction.flags, flagBT) END;
  1625. END;
  1626. IF flagD IN format.flags THEN
  1627. IF S & ~H THEN INCL(instruction.flags, flagD) END;
  1628. END;
  1629. IF flagDA IN format.flags THEN
  1630. IF ~U & ~P THEN INCL(instruction.flags, flagDA) END;
  1631. END;
  1632. IF flagDB IN format.flags THEN
  1633. IF ~U & P THEN INCL(instruction.flags, flagDB) END;
  1634. END;
  1635. IF flagH IN format.flags THEN
  1636. IF ~S & H THEN INCL(instruction.flags, flagH) END;
  1637. END;
  1638. IF flagIA IN format.flags THEN
  1639. IF U & ~P THEN INCL(instruction.flags, flagIA) END;
  1640. END;
  1641. IF flagIB IN format.flags THEN
  1642. IF U & P THEN INCL(instruction.flags, flagDA) END;
  1643. END;
  1644. IF flagL IN format.flags THEN
  1645. IF 22 IN codeSet THEN INCL(instruction.flags, flagL) END;
  1646. END;
  1647. IF flagS IN format.flags THEN
  1648. IF 20 IN codeSet THEN INCL(instruction.flags, flagS) END;
  1649. END;
  1650. IF flagSB IN format.flags THEN
  1651. IF S & ~H THEN INCL(instruction.flags, flagSB) END;
  1652. END;
  1653. IF flagSH IN format.flags THEN
  1654. IF S & H THEN INCL(instruction.flags, flagSH) END;
  1655. END;
  1656. IF flagT IN format.flags THEN
  1657. IF ~B & ~P & ~W THEN INCL(instruction.flags, flagT) END;
  1658. END;
  1659. IF flagUserMode IN format.flags THEN
  1660. IF 22 IN codeSet THEN INCL(instruction.flags, flagUserMode) END
  1661. END;
  1662. IF flagBaseRegisterUpdate IN format.flags THEN
  1663. IF 21 IN codeSet THEN INCL(instruction.flags, flagBaseRegisterUpdate) END
  1664. END;
  1665. operandNr := 0;
  1666. WHILE (operandNr < MaxOperands) & done DO
  1667. done := done & DecodeOperand(format.operands[operandNr], instruction.operands[operandNr]);
  1668. INC(operandNr);
  1669. END;
  1670. END;
  1671. INC(instrNr);
  1672. END;
  1673. RETURN done
  1674. END Decode;
  1675. (* TODO: handle fixups *)
  1676. PROCEDURE EmitInstruction*(CONST instruction: Instruction; code: BinaryCode.Section): BOOLEAN;
  1677. VAR
  1678. encoding: LONGINT;
  1679. (*decoded: Instruction;*)
  1680. PROCEDURE PatchFixup(op: Operand);
  1681. BEGIN
  1682. IF op.fixup # NIL THEN
  1683. op.fixup.SetFixupOffset(code.pc);
  1684. code.fixupList.AddFixup(op.fixup);
  1685. END;
  1686. END PatchFixup;
  1687. PROCEDURE PatchFixups;
  1688. VAR i: LONGINT;
  1689. BEGIN
  1690. FOR i := 0 TO LEN(instruction.operands)-1 DO
  1691. PatchFixup(instruction.operands[i]);
  1692. END;
  1693. END PatchFixups;
  1694. BEGIN
  1695. IF (code.comments # NIL) THEN
  1696. DumpInstruction(code.comments, instruction);
  1697. code.comments.Ln;
  1698. code.comments.Update;
  1699. END;
  1700. IF ~Encode(instruction, encoding) THEN RETURN FALSE END;
  1701. PatchFixups();
  1702. (*
  1703. IF (code.comments # NIL) THEN
  1704. IF ~Decode(encoding, decoded) THEN HALT(100) END;
  1705. DumpInstruction(code.comments, decoded);
  1706. code.comments.String(" (decoding of encoding)");
  1707. code.comments.Ln;
  1708. code.comments.Update;
  1709. END;
  1710. *)
  1711. (* PatchFixups(); *)
  1712. code.PutBits(encoding, 32);
  1713. RETURN TRUE;
  1714. END EmitInstruction;
  1715. PROCEDURE Emit*(mnemonic, condition: LONGINT; flags: SET; CONST operands: ARRAY OF Operand; code: BinaryCode.Section);
  1716. VAR instruction: Instruction;
  1717. BEGIN
  1718. IF ~MakeInstruction(instruction, mnemonic, condition, flags, operands) THEN HALT(100) END;
  1719. ASSERT(EmitInstruction(instruction, code));
  1720. END Emit;
  1721. PROCEDURE Init*;
  1722. VAR
  1723. i, instructionCount, conditionEntryCount, registerEntryCount: LONGINT;
  1724. PROCEDURE EnterCoprocessor(number: INTEGER; CONST name: ARRAY OF CHAR);
  1725. BEGIN
  1726. COPY(name, coprocessorNames[number])
  1727. END EnterCoprocessor;
  1728. PROCEDURE EnterShift(number: INTEGER; CONST name: ARRAY OF CHAR);
  1729. BEGIN
  1730. COPY(name, shiftNames[number]);
  1731. END EnterShift;
  1732. PROCEDURE EnterRegister(number: INTEGER; CONST name: ARRAY OF CHAR);
  1733. VAR
  1734. registerEntry: Entry;
  1735. BEGIN
  1736. COPY(name, registerEntry.name);
  1737. registerEntry.number := number;
  1738. registerEntries[registerEntryCount] := registerEntry;
  1739. INC(registerEntryCount);
  1740. END EnterRegister;
  1741. PROCEDURE EnterMnemonic(number: INTEGER; CONST name: ARRAY OF CHAR);
  1742. VAR mnemonic: Mnemonic;
  1743. BEGIN
  1744. COPY(name, mnemonic.name);
  1745. mnemonic.number := number;
  1746. mnemonic.firstInstructionFormat := MAX(LONGINT); mnemonic.lastInstructionFormat := MIN(LONGINT);
  1747. mnemonics[number] := mnemonic;
  1748. END EnterMnemonic;
  1749. PROCEDURE EnterInstruction(mnemonic: INTEGER; opcode, mask: SET; flags: SET; op0, op1, op2, op3, op4, op5: INTEGER);
  1750. VAR format: InstructionFormat;
  1751. BEGIN
  1752. format.mnemonic := mnemonic;
  1753. format.opcode := opcode;
  1754. format.mask := mask;
  1755. format.flags := flags;
  1756. format.operands[0] := op0;
  1757. format.operands[1] := op1;
  1758. format.operands[2] := op2;
  1759. format.operands[3] := op3;
  1760. format.operands[4] := op4;
  1761. format.operands[5] := op5;
  1762. format.isNEON := FALSE;
  1763. instructionFormats[instructionCount] := format;
  1764. IF instructionCount < mnemonics[mnemonic].firstInstructionFormat THEN mnemonics[mnemonic].firstInstructionFormat := instructionCount END;
  1765. IF instructionCount > mnemonics[mnemonic].lastInstructionFormat THEN mnemonics[mnemonic].lastInstructionFormat := instructionCount END;
  1766. INC(instructionCount);
  1767. END EnterInstruction;
  1768. PROCEDURE EnterCondition(number: LONGINT; CONST name: ARRAY OF CHAR);
  1769. BEGIN
  1770. COPY(name, conditionEntries[conditionEntryCount].name);
  1771. conditionEntries[conditionEntryCount].number := number;
  1772. INC(conditionEntryCount);
  1773. END EnterCondition;
  1774. PROCEDURE EnterFlag(number: LONGINT; CONST name: ARRAY OF CHAR);
  1775. BEGIN
  1776. COPY(name, flagNames[number]);
  1777. END EnterFlag;
  1778. (** Parse an instruction format string. The format is a string representation of the encoding bits.
  1779. Each bit can be represented by 0, 1 or X:
  1780. - 0 means that the bit can be used to identify this instruction and it is not set
  1781. - 1 means that the bit can be used to identify this instruction and it is set
  1782. - X means that the bit cannot be used to identify the instruction.
  1783. - U, S, L, F, o for the corresponding bits
  1784. Whitespaces are ignored.
  1785. The output sets are filled according to the parsing results.
  1786. *)
  1787. PROCEDURE ParseInstructionFormat(CONST format: ARRAY OF CHAR; VAR setBits, diffBits, U, Q, S, L, F, o: SET);
  1788. VAR
  1789. curr, len, count: LONGINT;
  1790. BEGIN
  1791. len := Strings.Length(format) - 1;
  1792. count := 0;
  1793. setBits := {};
  1794. diffBits := {};
  1795. U := {}; Q :={}; S := {}; F := {}; L := {}; F := {}; o := {};
  1796. FOR curr := len TO 0 BY -1 DO
  1797. ASSERT((format[curr] = " ") OR (format[curr] = "1")
  1798. OR (format[curr] = "0") OR (format[curr] = "X")
  1799. OR (format[curr] = "U") OR (format[curr] = "Q")
  1800. OR (format[curr] = "F") OR (format[curr] = "L")
  1801. OR (format[curr] = "S") OR (format[curr] = "o"));
  1802. CASE format[curr] OF
  1803. " ":
  1804. |"0": INCL(diffBits, count); INC(count)
  1805. |"1": INCL(setBits, count); INCL(diffBits, count); INC(count)
  1806. |"X": INC(count)
  1807. |"U": INCL(U, count); INC(count)
  1808. |"Q": INCL(Q, count); INC(count)
  1809. |"S": INCL(S, count); INC(count)
  1810. |"L": INCL(L, count); INC(count)
  1811. |"F": INCL(F, count); INC(count)
  1812. |"o": INCL(o, count); INC(count)
  1813. END
  1814. END;
  1815. (* Only allow 32 elements wide formats *)
  1816. ASSERT(count = 32);
  1817. (* DEBUG *)
  1818. (*D.String("Parsing results:"); D.Ln;
  1819. D.String(" "); D.String(format); D.Ln;
  1820. D.String("opcode: "); D.Set(setBits); D.Ln;
  1821. D.String("mask: "); D.Set(diffBits); D.Ln;
  1822. D.String("U: "); D.Set(U); D.Ln;
  1823. D.String("Q: "); D.Set(Q); D.Ln;
  1824. D.String("S: "); D.Set(S); D.Ln;
  1825. D.String("F: "); D.Set(F); D.Ln;
  1826. D.String("L: "); D.Set(L); D.Ln;
  1827. D.String("o: "); D.Set(o); D.Ln;*)
  1828. END ParseInstructionFormat;
  1829. (** Adds the given sets to the corresponding record fields of the last entered instruction. Sets the instruction to be a NEON instruction. *)
  1830. PROCEDURE UpdateNEONInstruction(U, Q, S, L, F, O: SET);
  1831. VAR
  1832. last: LONGINT;
  1833. i: INTEGER;
  1834. BEGIN
  1835. (*ASSERT(instructionCount # 0);*)
  1836. last := instructionCount - 1;
  1837. instructionFormats[last].isNEON := TRUE;
  1838. instructionFormats[last].Unsigned := U;
  1839. instructionFormats[last].Quadword := Q;
  1840. (*instructionFormats[last].Size := S;*)
  1841. instructionFormats[last].Length := L;
  1842. instructionFormats[last].Float := F;
  1843. instructionFormats[last].Operation := O;
  1844. FOR i := 0 TO 31 DO
  1845. IF i IN S THEN
  1846. instructionFormats[last].SizeH := i
  1847. END
  1848. END
  1849. END UpdateNEONInstruction;
  1850. (** Enter a NEON Instruction, using a string format descriptor.
  1851. *)
  1852. PROCEDURE EnterNEONInstruction(mnemonic: INTEGER; CONST format: ARRAY OF CHAR; flags: SET; op0, op1, op2, op3, op4, op5: INTEGER);
  1853. VAR
  1854. opcode, mask, U, Q, S, L, F, o: SET;
  1855. last: LONGINT;
  1856. i: INTEGER;
  1857. BEGIN
  1858. (* Enter instruction *)
  1859. ParseInstructionFormat(format, opcode, mask, U, Q, S, L, F, o);
  1860. EnterInstruction(mnemonic, opcode, mask, flags, op0, op1, op2, op3, op4, op5);
  1861. (* Add NEON specific information *)
  1862. last := instructionCount - 1;
  1863. instructionFormats[last].isNEON := TRUE;
  1864. instructionFormats[last].Unsigned := U;
  1865. instructionFormats[last].Quadword := Q;
  1866. instructionFormats[last].Length := L;
  1867. instructionFormats[last].Float := F;
  1868. instructionFormats[last].Operation := o;
  1869. instructionFormats[last].SizeH := 32;
  1870. FOR i := 0 TO 31 DO
  1871. IF i IN S THEN
  1872. instructionFormats[last].SizeH := i
  1873. END
  1874. END
  1875. END EnterNEONInstruction;
  1876. BEGIN
  1877. EnterShift(shiftLSL, "LSL");
  1878. EnterShift(shiftLSR, "LSR");
  1879. EnterShift(shiftASR, "ASR");
  1880. EnterShift(shiftROR, "ROR");
  1881. EnterShift(shiftRRX, "RRX");
  1882. FOR i := 0 TO NumberShifts-1 DO ASSERT(shiftNames[i] # "") END;
  1883. EnterCoprocessor(CP0, "P0");
  1884. EnterCoprocessor(CP1, "P1");
  1885. EnterCoprocessor(CP2, "P2");
  1886. EnterCoprocessor(CP3, "P3");
  1887. EnterCoprocessor(CP4, "P4");
  1888. EnterCoprocessor(CP5, "P5");
  1889. EnterCoprocessor(CP6, "P6");
  1890. EnterCoprocessor(CP7, "P7");
  1891. EnterCoprocessor(CP8, "P8");
  1892. EnterCoprocessor(CP9, "P9");
  1893. EnterCoprocessor(CP10, "P10");
  1894. EnterCoprocessor(CP11, "P11");
  1895. EnterCoprocessor(CP12, "P12");
  1896. EnterCoprocessor(CP13, "P13");
  1897. EnterCoprocessor(CP14, "P14");
  1898. EnterCoprocessor(CP15, "P15");
  1899. FOR i := 0 TO NumberCoprocessors - 1 DO ASSERT(coprocessorNames[i] # "") END;
  1900. (* enter register names (note that the preferred name, i.e. alias, is entered after the other variants) *)
  1901. registerEntryCount := 0;
  1902. EnterRegister(R0, "RES"); EnterRegister(R0, "R0");
  1903. EnterRegister(R1, "RESHI"); EnterRegister(R1, "R1");
  1904. EnterRegister(R2, "R2");
  1905. EnterRegister(R3, "R3");
  1906. EnterRegister(R4, "R4");
  1907. EnterRegister(R5, "R5");
  1908. EnterRegister(R6, "R6");
  1909. EnterRegister(R7, "R7");
  1910. EnterRegister(R8, "R8");
  1911. EnterRegister(R9, "R9");
  1912. EnterRegister(R10, "R10");
  1913. EnterRegister(R11, "R11");
  1914. EnterRegister(R12, "R12"); EnterRegister(R12, "FP");
  1915. EnterRegister(R13, "R13"); EnterRegister(R13, "SP");
  1916. EnterRegister(R14, "R14"); EnterRegister(R14, "LR");
  1917. EnterRegister(R15, "R15"); EnterRegister(R15, "PC");
  1918. EnterRegister(CR0, "C0");
  1919. EnterRegister(CR1, "C1");
  1920. EnterRegister(CR2, "C2");
  1921. EnterRegister(CR3, "C3");
  1922. EnterRegister(CR4, "C4");
  1923. EnterRegister(CR5, "C5");
  1924. EnterRegister(CR6, "C6");
  1925. EnterRegister(CR7, "C7");
  1926. EnterRegister(CR8, "C8");
  1927. EnterRegister(CR9, "C9");
  1928. EnterRegister(CR10, "C10");
  1929. EnterRegister(CR11, "C11");
  1930. EnterRegister(CR12, "C12");
  1931. EnterRegister(CR13, "C13");
  1932. EnterRegister(CR14, "C14");
  1933. EnterRegister(CR15, "C15");
  1934. EnterRegister(DR0, "D0");
  1935. EnterRegister(DR1, "D1");
  1936. EnterRegister(DR2, "D2");
  1937. EnterRegister(DR3, "D3");
  1938. EnterRegister(DR4, "D4");
  1939. EnterRegister(DR5, "D5");
  1940. EnterRegister(DR6, "D6");
  1941. EnterRegister(DR7, "D7");
  1942. EnterRegister(DR8, "D8");
  1943. EnterRegister(DR9, "D9");
  1944. EnterRegister(DR10, "D10");
  1945. EnterRegister(DR11, "D11");
  1946. EnterRegister(DR12, "D12");
  1947. EnterRegister(DR13, "D13");
  1948. EnterRegister(DR14, "D14");
  1949. EnterRegister(DR15, "D15");
  1950. EnterRegister(SR0, "S0");
  1951. EnterRegister(SR1, "S1");
  1952. EnterRegister(SR2, "S2");
  1953. EnterRegister(SR3, "S3");
  1954. EnterRegister(SR4, "S4");
  1955. EnterRegister(SR5, "S5");
  1956. EnterRegister(SR6, "S6");
  1957. EnterRegister(SR7, "S7");
  1958. EnterRegister(SR8, "S8");
  1959. EnterRegister(SR9, "S9");
  1960. EnterRegister(SR10, "S10");
  1961. EnterRegister(SR11, "S11");
  1962. EnterRegister(SR12, "S12");
  1963. EnterRegister(SR13, "S13");
  1964. EnterRegister(SR14, "S14");
  1965. EnterRegister(SR15, "S15");
  1966. EnterRegister(SR16, "S16");
  1967. EnterRegister(SR17, "S17");
  1968. EnterRegister(SR18, "S18");
  1969. EnterRegister(SR19, "S19");
  1970. EnterRegister(SR20, "S20");
  1971. EnterRegister(SR21, "S21");
  1972. EnterRegister(SR22, "S22");
  1973. EnterRegister(SR23, "S23");
  1974. EnterRegister(SR24, "S24");
  1975. EnterRegister(SR25, "S25");
  1976. EnterRegister(SR26, "S26");
  1977. EnterRegister(SR27, "S27");
  1978. EnterRegister(SR28, "S28");
  1979. EnterRegister(SR29, "S29");
  1980. EnterRegister(SR30, "S30");
  1981. EnterRegister(SR31, "S31");
  1982. EnterRegister(CPSR, "CPSR");
  1983. EnterRegister(SPSR, "SPSR");
  1984. (* NEON Registers *)
  1985. EnterRegister(DR16, "D16");
  1986. EnterRegister(DR17, "D17");
  1987. EnterRegister(DR18, "D18");
  1988. EnterRegister(DR19, "D19");
  1989. EnterRegister(DR20, "D20");
  1990. EnterRegister(DR21, "D21");
  1991. EnterRegister(DR22, "D22");
  1992. EnterRegister(DR23, "D23");
  1993. EnterRegister(DR24, "D24");
  1994. EnterRegister(DR25, "D25");
  1995. EnterRegister(DR26, "D26");
  1996. EnterRegister(DR27, "D27");
  1997. EnterRegister(DR28, "D28");
  1998. EnterRegister(DR29, "D29");
  1999. EnterRegister(DR30, "D30");
  2000. EnterRegister(DR31, "D31");
  2001. EnterRegister(QR0, "Q0");
  2002. EnterRegister(QR1, "Q1");
  2003. EnterRegister(QR2, "Q2");
  2004. EnterRegister(QR3, "Q3");
  2005. EnterRegister(QR4, "Q4");
  2006. EnterRegister(QR5, "Q5");
  2007. EnterRegister(QR6, "Q6");
  2008. EnterRegister(QR7, "Q7");
  2009. EnterRegister(QR8, "Q8");
  2010. EnterRegister(QR9, "Q9");
  2011. EnterRegister(QR10, "Q10");
  2012. EnterRegister(QR11, "Q11");
  2013. EnterRegister(QR12, "Q12");
  2014. EnterRegister(QR13, "Q13");
  2015. EnterRegister(QR14, "Q14");
  2016. EnterRegister(QR15, "Q15");
  2017. EnterRegister(FPSID, "FPSID");
  2018. EnterRegister(FPSCR, "FPSCR");
  2019. EnterRegister(FPEXC, "FPEXC");
  2020. FOR i := 0 TO NumberRegisterEntries-1 DO ASSERT(registerEntries[i].name # "") END;
  2021. (* enter condition names (note that the preferred name, i.e. alias, is entered after the other variants) *)
  2022. conditionEntryCount := 0;
  2023. EnterCondition(conditionEQ, "EQ");
  2024. EnterCondition(conditionNE, "NE");
  2025. EnterCondition(conditionCS, "CS"); EnterCondition(conditionHS, "HS");
  2026. EnterCondition(conditionCC, "CC"); EnterCondition(conditionLO, "LO");
  2027. EnterCondition(conditionMI, "MI");
  2028. EnterCondition(conditionPL, "PL");
  2029. EnterCondition(conditionVS, "VS");
  2030. EnterCondition(conditionVC, "VC");
  2031. EnterCondition(conditionHI, "HI");
  2032. EnterCondition(conditionLS, "LS");
  2033. EnterCondition(conditionGE, "GE");
  2034. EnterCondition(conditionLT, "LT");
  2035. EnterCondition(conditionGT, "GT");
  2036. EnterCondition(conditionLE, "LE");
  2037. EnterCondition(conditionAL, "AL");
  2038. EnterCondition(conditionNV, "NV");
  2039. FOR i := 0 TO NumberConditionEntries-1 DO ASSERT(conditionEntries[i].name # "") END;
  2040. EnterFlag(flagB, "B");
  2041. EnterFlag(flagBT, "BT");
  2042. EnterFlag(flagD, "D");
  2043. EnterFlag(flagDA, "DA");
  2044. EnterFlag(flagDB, "DB");
  2045. EnterFlag(flagH, "H");
  2046. EnterFlag(flagIA, "IA");
  2047. EnterFlag(flagIB, "IB");
  2048. EnterFlag(flagL, "L");
  2049. EnterFlag(flagS, "S");
  2050. EnterFlag(flagSB, "SB");
  2051. EnterFlag(flagSH, "SH");
  2052. EnterFlag(flagT, "T");
  2053. (* NEON flags *)
  2054. EnterFlag(flagNEON8bits, "8");
  2055. EnterFlag(flagNEON16bits, "16");
  2056. EnterFlag(flagNEON32bits, "32");
  2057. EnterFlag(flagNEON64bits, "64");
  2058. EnterFlag(flagNEONInt, ".I");
  2059. EnterFlag(flagNEONSigned, ".S");
  2060. EnterFlag(flagNEONUnsigned, ".U");
  2061. EnterFlag(flagNEONFloat, ".F");
  2062. EnterFlag(flagNEONPoly, ".P");
  2063. EnterFlag(flagNEONUndef, ".X");
  2064. FOR i := 0 TO NumberFlags-1 DO ASSERT(flagNames[i] # "") END;
  2065. EnterMnemonic(opADC, "ADC");
  2066. EnterMnemonic(opADD, "ADD");
  2067. EnterMnemonic(opAND, "AND");
  2068. EnterMnemonic(opB, "B");
  2069. EnterMnemonic(opBIC, "BIC");
  2070. EnterMnemonic(opBKPT, "BKPT");
  2071. EnterMnemonic(opBL, "BL");
  2072. EnterMnemonic(opBLX, "BLX");
  2073. EnterMnemonic(opBX, "BX");
  2074. EnterMnemonic(opCDP, "CDP");
  2075. EnterMnemonic(opCDP2, "CDP2");
  2076. EnterMnemonic(opCLZ, "CLZ");
  2077. EnterMnemonic(opCMN, "CMN");
  2078. EnterMnemonic(opCMP, "CMP");
  2079. EnterMnemonic(opEOR, "EOR");
  2080. EnterMnemonic(opFABSD, "FABSD");
  2081. EnterMnemonic(opFABSS, "FABSS");
  2082. EnterMnemonic(opFADDD, "FADDD");
  2083. EnterMnemonic(opFADDS, "FADDS");
  2084. EnterMnemonic(opFCMPD, "FCMPD");
  2085. EnterMnemonic(opFCMPED, "FCMPED");
  2086. EnterMnemonic(opFCMPES, "FCMPED");
  2087. EnterMnemonic(opFCMPEZD, "FCMPEZD");
  2088. EnterMnemonic(opFCMPEZS, "FCMPEZS");
  2089. EnterMnemonic(opFCMPS, "FCMPDS");
  2090. EnterMnemonic(opFCMPZD, "FCMPZED");
  2091. EnterMnemonic(opFCMPZS, "FCMPZS");
  2092. EnterMnemonic(opFCPYD, "FCPYD");
  2093. EnterMnemonic(opFCPYS, "FCPYS");
  2094. EnterMnemonic(opFCVTDS, "FCVTDS");
  2095. EnterMnemonic(opFCVTSD, "FCVTSD");
  2096. EnterMnemonic(opFDIVD, "FDIVD");
  2097. EnterMnemonic(opFDIVS, "FDIVS");
  2098. EnterMnemonic(opFLDD, "FLDD");
  2099. EnterMnemonic(opFLDMIAD, "FLDMIAD");
  2100. EnterMnemonic(opFLDMIAS, "FLDMIAS");
  2101. EnterMnemonic(opFLDMIAX, "FLDMIAX");
  2102. EnterMnemonic(opFLDMDBD, "FLDMIAD");
  2103. EnterMnemonic(opFLDMDBS, "FLDMIAS");
  2104. EnterMnemonic(opFLDMDBX, "FLDMIAX");
  2105. EnterMnemonic(opFLDS, "FLDS");
  2106. EnterMnemonic(opFMACD, "FMACD");
  2107. EnterMnemonic(opFMACS, "FMACS");
  2108. EnterMnemonic(opFMDHR, "FMDHR");
  2109. EnterMnemonic(opFMDLR, "FMDLR");
  2110. EnterMnemonic(opFMRDH, "FMRDH");
  2111. EnterMnemonic(opFMRDL, "FMRDL");
  2112. EnterMnemonic(opFMRS, "FMRS");
  2113. EnterMnemonic(opFMRX, "FMRX");
  2114. EnterMnemonic(opFMSCD, "FMSCD");
  2115. EnterMnemonic(opFMSCS, "FMSCS");
  2116. EnterMnemonic(opFMSR, "FMSR");
  2117. EnterMnemonic(opFMSTAT, "FMSTAT");
  2118. EnterMnemonic(opFMULD, "FMULD");
  2119. EnterMnemonic(opFMULS, "FMULS");
  2120. EnterMnemonic(opFMXR, "FMXR");
  2121. EnterMnemonic(opFNEGD, "FNEGD");
  2122. EnterMnemonic(opFNEGS, "FNEGS");
  2123. EnterMnemonic(opFNMACD, "FNMACD");
  2124. EnterMnemonic(opFNMACS, "FNMACS");
  2125. EnterMnemonic(opFNMSCD, "FNMSCD");
  2126. EnterMnemonic(opFNMSCS, "FNMSCS");
  2127. EnterMnemonic(opFNMULD, "FNMULD");
  2128. EnterMnemonic(opFNMULS, "FNMULS");
  2129. EnterMnemonic(opFSITOD, "FSITOD");
  2130. EnterMnemonic(opFSITOS, "FSITOS");
  2131. EnterMnemonic(opFSQRTD, "FSQRTD");
  2132. EnterMnemonic(opFSQRTS, "FSQRTS");
  2133. EnterMnemonic(opFSTD, "FSTD");
  2134. EnterMnemonic(opFSTMIAD, "FSTMIAD");
  2135. EnterMnemonic(opFSTMIAS, "FSTMIAS");
  2136. EnterMnemonic(opFSTMIAX, "FSTMIAX");
  2137. EnterMnemonic(opFSTMDBD, "FSTMDBD");
  2138. EnterMnemonic(opFSTMDBS, "FSTMDBS");
  2139. EnterMnemonic(opFSTMDBX, "FSTMDBX");
  2140. EnterMnemonic(opFSTS, "FSTS");
  2141. EnterMnemonic(opFSUBD, "FSUBD");
  2142. EnterMnemonic(opFSUBS, "FSUBS");
  2143. EnterMnemonic(opFTOSID, "FTOSID");
  2144. EnterMnemonic(opFTOSIZD, "FTOSIZD");
  2145. EnterMnemonic(opFTOSIS, "FTOSIS");
  2146. EnterMnemonic(opFTOSIZS, "FTOSIZS");
  2147. EnterMnemonic(opFTOUID, "FTOUID");
  2148. EnterMnemonic(opFTOUIZD, "FTOUIZD");
  2149. EnterMnemonic(opFTOUIS, "FTOUIS");
  2150. EnterMnemonic(opFTOUIZS, "FTOUIZS");
  2151. EnterMnemonic(opFUITOD, "FUITOD");
  2152. EnterMnemonic(opFUITOS, "FUITOS");
  2153. EnterMnemonic(opLDC, "LDC");
  2154. EnterMnemonic(opLDC2, "LDC2");
  2155. EnterMnemonic(opLDM, "LDM");
  2156. EnterMnemonic(opLDR, "LDR");
  2157. EnterMnemonic(opMCR, "MCR");
  2158. EnterMnemonic(opMCR2, "MCR2");
  2159. EnterMnemonic(opMCRR, "MCRR");
  2160. EnterMnemonic(opMLA, "MLA");
  2161. EnterMnemonic(opMOV, "MOV");
  2162. EnterMnemonic(opMRC, "MRC");
  2163. EnterMnemonic(opMRC2, "MRC2");
  2164. EnterMnemonic(opMRRC, "MRRC");
  2165. EnterMnemonic(opMRS, "MRS");
  2166. EnterMnemonic(opMSR, "MSR");
  2167. EnterMnemonic(opMUL, "MUL");
  2168. EnterMnemonic(opMVN, "MVN");
  2169. EnterMnemonic(opORR, "ORR");
  2170. EnterMnemonic(opPLD, "PLD");
  2171. EnterMnemonic(opQADD, "QADD");
  2172. EnterMnemonic(opQDADD, "QDADD");
  2173. EnterMnemonic(opQDSUB, "QDSUB");
  2174. EnterMnemonic(opQSUB, "QSUB");
  2175. EnterMnemonic(opRSB, "RSB");
  2176. EnterMnemonic(opRSC, "RSC");
  2177. EnterMnemonic(opSBC, "SBC");
  2178. EnterMnemonic(opSMLABB, "SMLABB");
  2179. EnterMnemonic(opSMLABT, "SMLABT");
  2180. EnterMnemonic(opSMLATB, "SMLATB");
  2181. EnterMnemonic(opSMLATT, "SMLATT");
  2182. EnterMnemonic(opSMLAL, "SMLAL");
  2183. EnterMnemonic(opSMLALBB, "SMLALBB");
  2184. EnterMnemonic(opSMLALBT, "SMLALBT");
  2185. EnterMnemonic(opSMLALTB, "SMLALTB");
  2186. EnterMnemonic(opSMLALTT, "SMLALTT");
  2187. EnterMnemonic(opSMLAWB, "SMLAWB");
  2188. EnterMnemonic(opSMLAWT, "SMLAWT");
  2189. EnterMnemonic(opSMULBB, "SMULBB");
  2190. EnterMnemonic(opSMULBT, "SMULBT");
  2191. EnterMnemonic(opSMULTB, "SMULTB");
  2192. EnterMnemonic(opSMULTT, "SMULTT");
  2193. EnterMnemonic(opSMULWB, "SMULWB");
  2194. EnterMnemonic(opSMULWT, "SMULWT");
  2195. EnterMnemonic(opSMULL, "SMULL");
  2196. EnterMnemonic(opSTC, "STC");
  2197. EnterMnemonic(opSTC2, "STC2");
  2198. EnterMnemonic(opSTM, "STM");
  2199. EnterMnemonic(opSTR, "STR");
  2200. EnterMnemonic(opSUB, "SUB");
  2201. EnterMnemonic(opSWI, "SWI");
  2202. EnterMnemonic(opSWP, "SWP");
  2203. EnterMnemonic(opTEQ, "TEQ");
  2204. EnterMnemonic(opTST, "TST");
  2205. EnterMnemonic(opUMLAL, "UMLAL");
  2206. EnterMnemonic(opUMULL, "UMULL");
  2207. EnterMnemonic(opISB, "ISB");
  2208. EnterMnemonic(opLSL, "LSL");
  2209. EnterMnemonic(opLSR, "LSR");
  2210. EnterMnemonic(opSEV, "SEV");
  2211. EnterMnemonic(opDSB, "DSB");
  2212. EnterMnemonic(opLDREX, "LDREX");
  2213. EnterMnemonic(opSTREX, "STREX");
  2214. EnterMnemonic(opADR, "ADR");
  2215. EnterMnemonic(opLDREXB, "LDREXB");
  2216. EnterMnemonic(opSTREXB, "STREXB");
  2217. EnterMnemonic(opDMB, "DMB");
  2218. EnterMnemonic(opCLREX, "CLREX");
  2219. EnterMnemonic(opREV, "REV");
  2220. EnterMnemonic(opREV16, "REV16");
  2221. EnterMnemonic(opUXTH, "UXTH");
  2222. EnterMnemonic(opWFE, "WFE");
  2223. EnterMnemonic(opWFI, "WFI");
  2224. (* NEON mnemonics *)
  2225. EnterMnemonic(opVADD, "VADD");
  2226. EnterMnemonic(opVADDL, "VADDL");
  2227. EnterMnemonic(opVADDW, "VADDW");
  2228. EnterMnemonic(opVMUL, "VMUL");
  2229. EnterMnemonic(opVMULL, "VMULL");
  2230. EnterMnemonic(opVMSR, "VMSR");
  2231. EnterMnemonic(opVMRS, "VMRS");
  2232. EnterMnemonic(opVLDR, "VLDR");
  2233. EnterMnemonic(opVSTR, "VSTR");
  2234. EnterMnemonic(opVDIV, "VDIV");
  2235. EnterMnemonic(opVMLA, "VMLA");
  2236. EnterMnemonic(opVMLS, "VMLS");
  2237. EnterMnemonic(opVMIN, "VMIN");
  2238. EnterMnemonic(opVMAX, "VMAX");
  2239. EnterMnemonic(opVSUB, "VSUB");
  2240. EnterMnemonic(opVABS, "VABS");
  2241. EnterMnemonic(opVABD, "VABD");
  2242. EnterMnemonic(opVLD1, "VLD1");
  2243. EnterMnemonic(opVST1, "VST1");
  2244. EnterMnemonic(opVPADD, "VPADD");
  2245. EnterMnemonic(opVMOV, "VMOV");
  2246. FOR i := 0 TO NumberMnemonics-1 DO ASSERT(mnemonics[i].name # "") END;
  2247. instructionCount := 0;
  2248. (*! adapt number of instructions if you enter a new instruction here *)
  2249. FOR i := 0 TO NumberInstructions-1 DO instructionFormats[i].mnemonic := None END;
  2250. EnterInstruction(opADC, {21, 23}, {21..24, 26, 27}, {flagCondition, flagS}, encodingR12, encodingR16, encodingAddressingMode1, None, None, None);
  2251. EnterInstruction(opADD, {23}, {21..24, 26, 27}, {flagCondition, flagS}, encodingR12, encodingR16, encodingAddressingMode1, None, None, None);
  2252. EnterInstruction(opAND, {}, {21..24, 26, 27}, {flagCondition, flagS}, encodingR12, encodingR16, encodingAddressingMode1, None, None, None);
  2253. EnterInstruction(opB, {25, 27}, {24..27}, {flagCondition}, encodingSignedImm24, None, None, None, None, None);
  2254. EnterInstruction(opBIC, {22..24}, {21..24, 26, 27}, {flagCondition, flagS}, encodingR12, encodingR16, encodingAddressingMode1, None, None, None);
  2255. EnterInstruction(opBKPT, {4..6, 21, 24, 29..31}, {4..7, 20..31}, {}, encodingImm16, None, None, None, None, None);
  2256. EnterInstruction(opBL, {24, 25, 27}, {24..27}, {flagCondition}, encodingSignedImm24, None, None, None, None, None);
  2257. EnterInstruction(opBLX, {25, 27..31}, {25..31}, {}, encodingSignedImm24, None, None, None, None, None);
  2258. EnterInstruction(opBLX, {4, 5, 8..19 (* SBO *), 21, 24}, {4..7, 20..27}, {flagCondition}, encodingR0, None, None, None, None, None);
  2259. EnterInstruction(opBX, {4, 21, 8..19 (* SBO *), 24}, {4..7, 20..27}, {flagCondition}, encodingR0, None, None, None, None, None);
  2260. EnterInstruction(opCDP, {25..27}, {4, 24..27}, {flagCondition}, encodingCoprocessor, encodingOpcode20, encodingCR12, encodingCR16, encodingCR0, encodingOpcode5);
  2261. EnterInstruction(opCDP2, {25..27}, {4, 24..31}, {}, encodingCoprocessor, encodingOpcode20, encodingCR12, encodingCR16, encodingCR0, encodingOpcode5);
  2262. EnterInstruction(opCLZ, {4, 8..11 (* SBO *), 16..19 (* SBO *), 21, 22, 24}, {4..7, 20..27}, {flagCondition}, encodingR12, encodingR0, None, None, None, None);
  2263. EnterInstruction(opCMN, {20..22, 24}, {20..24, 26, 27}, {flagCondition}, encodingR16, encodingAddressingMode1, None, None, None, None);
  2264. EnterInstruction(opCMP, {20, 22, 24}, {20..24, 26, 27}, {flagCondition}, encodingR16, encodingAddressingMode1, None, None, None, None);
  2265. EnterInstruction(opEOR, {21}, {21..24, 26, 27}, {flagCondition, flagS}, encodingR12, encodingR16, encodingAddressingMode1, None, None, None);
  2266. EnterInstruction(opFABSD, {6,7,8,9,11,20,21,23,25,26,27}, {4..11,16..27}, {flagCondition}, encodingDR12, encodingDR0, None, None, None, None);
  2267. EnterInstruction(opFABSS, {4,6,7,9,11,20,21,23,25,26,27}, {4,6..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingFR0, None, None, None, None);
  2268. EnterInstruction(opFADDD, {8,9,11,20,21,25,26,27}, {4..11,20..27}, {flagCondition}, encodingDR12, encodingDR16, encodingDR0, None, None, None);
  2269. EnterInstruction(opFADDS, {9,11,20,21,25,26,27}, {4,6,8..11,20,21,23..27}, {flagCondition}, encodingFR12, encodingFR16, encodingFR0, None, None, None);
  2270. EnterInstruction(opFCMPD, {6,8,9,11,18,20,21,23,25,26,27}, {4..11,16..27}, {flagCondition}, encodingDR12, encodingDR0, None, None, None, None);
  2271. EnterInstruction(opFCMPED, {6,7,8,9,11,18,20,21,23,25,26,27}, {4..11,16..27}, {flagCondition}, encodingDR12, encodingDR0, None, None, None, None);
  2272. EnterInstruction(opFCMPES, {6,7,9,11,18,20,21,23,25,26,27}, {4,6..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingFR0, None, None, None, None);
  2273. EnterInstruction(opFCMPEZD,{6,7,8,9,11,16,17,20,21,23,25,26,27},{4..11,16..27}, {flagCondition}, encodingDR12, None, None, None, None, None);
  2274. EnterInstruction(opFCMPEZS,{6,7,9,11,16,18,20,21,23,25,26,27}, {4..11,16..21,23..27}, {flagCondition}, encodingFR12, None, None, None, None, None);
  2275. EnterInstruction(opFCMPS, {6,9,11,18,20,21,23,25,26,27}, {4,6..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingFR0, None, None, None, None);
  2276. EnterInstruction(opFCMPZD, {6,8,9,11,16,18,20,21,23,25,26,27}, {4..11,16..27}, {flagCondition}, encodingDR12, None, None, None, None, None);
  2277. EnterInstruction(opFCMPZS, {6,9,11,16,18,20,21,23,25,26,27}, {4..11,16..21,23..27}, {flagCondition}, encodingFR12, None, None, None, None, None);
  2278. EnterInstruction(opFCPYD, {6,8,9,11,20,21,23,25,26,27}, {4..11,16..27}, {flagCondition}, encodingDR12, encodingDR0, None, None, None, None);
  2279. EnterInstruction(opFCPYS, {6,9,11,20,21,23,25,26,27}, {4,6..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingFR0, None, None, None, None);
  2280. EnterInstruction(opFCVTDS, {6,7,9,11,16,17,18,20,21,23,25,26,27}, {4,6..11,16..27}, {flagCondition}, encodingDR12, encodingFR0, None, None, None, None);
  2281. EnterInstruction(opFCVTSD, {6,7,8,9,11,16,17,18,20,21,23,25,26,27}, {4..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingDR0, None, None, None, None);
  2282. EnterInstruction(opFDIVD, {8,9,11,23,25,26,27}, {4..11,20..27}, {flagCondition}, encodingDR12, encodingDR16, encodingDR0, None, None, None);
  2283. EnterInstruction(opFDIVS, {9,11,23,25,26,27}, {4,6,8..11,20..21,23..27}, {flagCondition}, encodingFR12, encodingFR16, encodingFR0, None, None, None);
  2284. EnterInstruction(opFLDD, {8,9,11,20,24,26,27}, {8..11,20..22,24..27}, {flagCondition}, encodingDR12, encodingAddressingMode5V, None, None, None, None);
  2285. EnterInstruction(opFLDMIAD, {8,9,11,20,23,26,27}, {8..11,20,22..27}, {flagCondition,flagBaseRegisterUpdate}, encodingR16, encodingDRegisterList, None, None, None, None);
  2286. EnterInstruction(opFLDMIAS, {9,11,20,23,26,27}, {8..11,20,23..27}, {flagCondition,flagBaseRegisterUpdate}, encodingR16, encodingFRegisterList, None, None, None, None);
  2287. EnterInstruction(opFLDMIAX, {8,9,11,20,23,26,27}, {8..11,20,22..27}, {flagCondition,flagBaseRegisterUpdate}, encodingR16, encodingDRegisterList, None, None, None, None);
  2288. EnterInstruction(opFLDMDBD, {8,9,11,20,24,26,27}, {8..11,20,22..27}, {flagCondition,flagBaseRegisterUpdate}, encodingR16, encodingDRegisterList, None, None, None, None);
  2289. EnterInstruction(opFLDMDBS, {9,11,20,24,26,27}, {8..11,20,23..27}, {flagCondition,flagBaseRegisterUpdate}, encodingR16, encodingFRegisterList, None, None, None, None);
  2290. EnterInstruction(opFLDMDBX, {8,9,11,20,24,26,27}, {8..11,20,22..27}, {flagCondition,flagBaseRegisterUpdate}, encodingR16, encodingDRegisterList, None, None, None, None);
  2291. EnterInstruction(opFLDS, {9,11,20,24,26,27}, {8..11,20..21,24..27}, {flagCondition}, encodingFR12, encodingAddressingMode5V, None, None, None, None);
  2292. EnterInstruction(opFMACD, {8,9,11,25,26,27}, {4..11,20..27}, {flagCondition}, encodingDR12, encodingDR16, encodingDR0, None, None, None);
  2293. EnterInstruction(opFMACS, {9,11,25..27}, {4,6,8..11,20..21,23..27}, {flagCondition}, encodingFR12, encodingFR16, encodingFR0, None, None, None);
  2294. EnterInstruction(opFMDHR, {4,8,9,11,21,25,26,27}, {4,7..11,20..27}, {flagCondition}, encodingDR16, encodingR12, None, None, None, None);
  2295. EnterInstruction(opFMDLR, {4,8,9,11,25,26,27}, {4,7..11,20..27}, {flagCondition}, encodingDR16, encodingR12, None, None, None, None);
  2296. EnterInstruction(opFMRDH, {4,8,9,11,20,21,25,26,27}, {4,7..11,20..27}, {flagCondition}, encodingR12, encodingDR16, None, None, None, None);
  2297. EnterInstruction(opFMRDL, {4,8,9,11,20,25,26,27}, {4,7..11,20..27}, {flagCondition}, encodingR12, encodingDR16, None, None, None, None);
  2298. EnterInstruction(opFMRS, {4,9,11,20,25,26,27}, {4,8..11,20..27}, {flagCondition}, encodingR12, encodingFR16, None, None, None, None);
  2299. EnterInstruction(opFMRX, {4,9,11,20..23,25..27}, {4,7..11,20..27}, {flagCondition}, (*!todo*)None, None, None, None, None, None);
  2300. EnterInstruction(opFMSCD, {8,9,11,20,25,26,27}, {4..11,20..27}, {flagCondition}, encodingDR12, encodingDR16, encodingDR0, None, None, None);
  2301. EnterInstruction(opFMSCS, {9,11,20,25,26,27}, {4,6,8..11,20..21,23..27}, {flagCondition}, encodingFR12, encodingFR16, encodingFR0, None, None, None);
  2302. EnterInstruction(opFMSR, {4,9,11,25,26,27}, {4,8..11,20..27}, {flagCondition}, encodingFR16, encodingR12, None, None, None, None);
  2303. EnterInstruction(opFMSTAT, {4,9,11,12..16,20..23,25..27}, {4,8..27}, {flagCondition}, None, None, None, None, None, None);
  2304. EnterInstruction(opFMULD, {8,9,11,21,25,26,27}, {4..11,20..27}, {flagCondition}, encodingDR12, encodingDR16, encodingDR0, None, None, None);
  2305. EnterInstruction(opFMULS, {9,11,21,25,26,27}, {4,6,8..11,20..21,23..27}, {flagCondition}, encodingFR12, encodingFR16, encodingFR0, None, None, None);
  2306. EnterInstruction(opFMXR, {4,9,11,21..23,25..27}, {4,7..11,20..27}, {flagCondition}, (*!todo*)None, None, None, None, None, None);
  2307. EnterInstruction(opFNEGD, {6,8,9,11,16,20,21,23,25,26,27}, {4..11,16..27}, {flagCondition}, encodingDR12, encodingDR0, None, None, None, None);
  2308. EnterInstruction(opFNEGS , {6,9,11,16,20,21,23,25,26,27}, {4,6..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingFR0, None, None, None, None);
  2309. EnterInstruction(opFNMACD, {6,8,9,11,25..27}, {4..11,20..27}, {flagCondition}, encodingDR12, encodingDR16, encodingDR0, None, None, None);
  2310. EnterInstruction(opFNMACS, {6,9,11,25,26,27}, {4,6,8..11,20,21,23..27}, {flagCondition}, encodingFR12, encodingFR16, encodingFR0, None, None, None);
  2311. EnterInstruction(opFNMSCD, {6,8,9,11,20,25,26,27}, {4..11,20..27}, {flagCondition}, encodingDR12, encodingDR16, encodingDR0, None, None, None);
  2312. EnterInstruction(opFNMSCS, {6,9,11,20,25,26,27}, {4..11,20..21,23..27}, {flagCondition}, encodingFR12, encodingFR16, encodingFR0, None, None, None);
  2313. EnterInstruction(opFNMULD, {6,8,9,11,21,25,26,27}, {4..11,20..27}, {flagCondition}, encodingDR12, encodingDR16, encodingDR0, None, None, None);
  2314. EnterInstruction(opFNMULS, {6,9,11,21,25,26,27}, {4,6,8..11,20..21,23..27}, {flagCondition}, encodingFR12, encodingFR16, encodingFR0, None, None, None);
  2315. EnterInstruction(opFSITOD, {6..9,11,19..21,23,25..27}, {4,6..11,16..27}, {flagCondition}, encodingDR12, encodingFR0, None, None, None, None);
  2316. EnterInstruction(opFSITOS, {6,7,9,11,19..21,23,25..27}, {4,6..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingFR0, None, None, None, None);
  2317. EnterInstruction(opFSQRTD, {6..9,11,16,20,21,23,25..27}, {4..11,16..27}, {flagCondition}, encodingDR12, encodingDR0, None, None, None, None);
  2318. EnterInstruction(opFSQRTS, {6,7,9,11,16,20,21,23,25..27}, {4,6..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingFR0, None, None, None, None);
  2319. EnterInstruction(opFSTD, {8,9,11,24,26,27}, {8..11,20..22,24..27}, {flagCondition}, encodingDR12, encodingAddressingMode5V, None, None, None, None);
  2320. EnterInstruction(opFSTMIAD, {8,9,11,23,26,27}, {8..11,20,22..27}, {flagCondition,flagBaseRegisterUpdate}, encodingR16, encodingDRegisterList, None, None, None, None);
  2321. EnterInstruction(opFSTMIAS, {9,11,23,26,27}, {8..11,20,23..27}, {flagCondition,flagBaseRegisterUpdate}, encodingR16, encodingFRegisterList, None, None, None, None);
  2322. EnterInstruction(opFSTMIAX, {8,9,11,23,26,27}, {8..11,20,22..27}, {flagCondition,flagBaseRegisterUpdate}, encodingR16, encodingDRegisterList, None, None, None, None);
  2323. EnterInstruction(opFSTMDBD, {8,9,11,24,26,27}, {8..11,20,22..27}, {flagCondition,flagBaseRegisterUpdate}, encodingR16, encodingDRegisterList, None, None, None, None);
  2324. EnterInstruction(opFSTMDBS, {9,11,24,26,27}, {8..11,20,23..27}, {flagCondition,flagBaseRegisterUpdate}, encodingR16,encodingFRegisterList, None, None, None, None);
  2325. EnterInstruction(opFSTMDBX, {8,9,11,24,26,27}, {8..11,20,22..27}, {flagCondition,flagBaseRegisterUpdate}, encodingR16, encodingDRegisterList, None, None, None, None);
  2326. EnterInstruction(opFSTS, {9,11,24,26,27}, {8..11,20,21, 24..27}, {flagCondition}, encodingFR12, encodingAddressingMode5V, None, None, None, None);
  2327. EnterInstruction(opFSUBD, {6,8,9,11,20,21,25..27}, {4..11,20..27}, {flagCondition}, encodingDR12, encodingDR16, encodingDR0, None, None, None);
  2328. EnterInstruction(opFSUBS, {6,9,11,20,21,25,26,27}, {4,6,8..11,20..21,23..27}, {flagCondition}, encodingFR12, encodingFR16, encodingFR0, None, None, None);
  2329. EnterInstruction(opFTOSID, {6,8,9,11,16,18..21,23,25..27}, {4..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingDR0, None, None, None, None);
  2330. EnterInstruction(opFTOSIZD, {6,7,8,9,11,16,18..21,23,25..27}, {4..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingDR0, None, None, None, None);
  2331. EnterInstruction(opFTOSIS, {6,9,11,16,18..21,23,25..27}, {4,6..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingFR0, None, None, None, None);
  2332. EnterInstruction(opFTOSIZS, {6,7,9,11,16,18..21,23,25..27}, {4,6..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingFR0, None, None, None, None);
  2333. EnterInstruction(opFTOUID, {6,8,9,11,18..21,23,25..27}, {4..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingDR0, None, None, None, None);
  2334. EnterInstruction(opFTOUIZD, {6,7,8,9,11,18..21,23,25..27}, {4..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingDR0, None, None, None, None);
  2335. EnterInstruction(opFTOUIS, {6,9,11,18..21,23,25..27}, {4,6..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingFR0, None, None, None, None);
  2336. EnterInstruction(opFTOUIZS, {6,7,9,11,18..21,23,25..27}, {4,6..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingFR0, None, None, None, None);
  2337. EnterInstruction(opFUITOD, {6,8,9,11,19..21,23,25..27}, {4,6..11,16..27}, {flagCondition}, encodingDR12, encodingFR0, None, None, None, None);
  2338. EnterInstruction(opFUITOS, {6,9,11,19..21,23,25..27}, {4,6..11,16..21,23..27}, {flagCondition}, encodingFR12, encodingFR0, None, None, None, None);
  2339. EnterInstruction(opLDC, {20, 26, 27}, {20, 25..27}, {flagCondition, flagL}, encodingCoprocessor, encodingCR12, encodingAddressingMode5, None, None, None);
  2340. EnterInstruction(opLDC2, {20, 26, 27, 28..31}, {20, 25..27, 28..31}, {flagL}, encodingCoprocessor, encodingCR12, encodingAddressingMode5, None, None, None);
  2341. (*EnterInstruction(opLDM, {20, 27}, {20, 25..27}, {flagCondition, flagIA, flagIB, flagDA, flagDB, flagUserMode, flagBaseRegisterUpdate}, encodingR16, encodingRegisterList, None, None, None, None);*)
  2342. EnterInstruction(opLDM, {20, 27}, {20, 25..27}, {flagCondition, flagIA, flagIB, flagDA, flagDB, flagBaseRegisterUpdate}, encodingR16, encodingRegisterList, None, None, None, None);
  2343. EnterInstruction(opLDR, {20, 26}, {20, 26..27}, {flagCondition, flagB, flagT, flagBT}, encodingR12, encodingAddressingMode2, None, None, None, None);
  2344. EnterInstruction(opLDR, {4, 7, 20}, {4, 7, 20, 25..27}, {flagCondition, flagH, flagSH, flagSB, flagD}, encodingR12, encodingAddressingMode3, None, None, None, None);
  2345. EnterInstruction(opMCR, {4, 25, 26, 27}, {4, 20, 24..27}, {flagCondition}, encodingCoprocessor, encodingOpcode21, encodingR12, encodingCR16, encodingCR0, encodingOpcode5);
  2346. EnterInstruction(opMCR2, {4, 25, 26, 27, 28..31}, {4, 20, 24..27, 28..31}, {}, encodingCoprocessor, encodingOpcode21, encodingCR12, encodingCR16, encodingCR0, encodingOpcode5);
  2347. EnterInstruction(opMCRR, {22, 26, 27}, {20..27}, {flagCondition}, encodingCoprocessor, encodingOpcode4, encodingR12, encodingR16, encodingCR0, None);
  2348. EnterInstruction(opMLA, {4, 7, 21}, {4..7, 21..27}, {flagCondition, flagS}, encodingR12, encodingR0, encodingR8, encodingR16, None, None);
  2349. EnterInstruction(opMOV, {21, 23, 24}, {21..24, 26, 27}, {flagCondition, flagS}, encodingR12, encodingAddressingMode1, None, None, None, None);
  2350. EnterInstruction(opMRC, {4, 20, 25, 26, 27}, {4, 20, 24..27}, {flagCondition}, encodingCoprocessor, encodingOpcode21, encodingR12, encodingCR16, encodingCR0, encodingOpcode5);
  2351. EnterInstruction(opMRC2, {4, 20, 25, 26, 27, 28..31}, {4, 20, 24..27, 28..31}, {}, encodingCoprocessor, encodingOpcode21, encodingR12, encodingCR16, encodingCR0, encodingOpcode5);
  2352. EnterInstruction(opMRRC, {20, 22, 26, 27}, {20..27}, {flagCondition}, encodingCoprocessor, encodingOpcode4, encodingR12, encodingR16, encodingCR0, None);
  2353. EnterInstruction(opMRS, {24, 16..19 (* SBO *)}, {20, 21, 23..27}, {flagCondition}, encodingR12, encodingPSR, None, None, None, None);
  2354. EnterInstruction(opMSR, {21, 24, 25, 12..15 (* SBO *)}, {20, 21, 23..27}, {flagCondition}, encodingFields, encodingRotImm8, None, None, None, None);
  2355. EnterInstruction(opMSR, {21, 24, 12..15 (* SBO *)}, {4..7, 20, 21, 23..27}, {flagCondition}, encodingFields, encodingR0, None, None, None, None);
  2356. EnterInstruction(opMUL, {4, 7}, {4..7, 21..27}, {flagCondition, flagS}, encodingR16, encodingR0, encodingR8, None, None, None);
  2357. EnterInstruction(opMVN, {21..24}, {21..24, 26, 27}, {flagCondition, flagS}, encodingR12, encodingAddressingMode1, None, None, None, None);
  2358. EnterInstruction(opORR, {23, 24}, {21..24, 26, 27}, {flagCondition, flagS}, encodingR12, encodingR16, encodingAddressingMode1, None, None, None);
  2359. EnterInstruction(opPLD, {28..31, 26, 24, 22, 20, 12..15}, {26..31, 24, 20..22, 12..15}, {flagCondition}, encodingAddressingMode2, None, None, None, None, None);
  2360. EnterInstruction(opQADD, {4, 6, 24}, {4..7, 20..27}, {flagCondition}, encodingR12, encodingR0, encodingR16, None, None, None);
  2361. EnterInstruction(opQDADD, {4, 6, 22, 24}, {4..7, 20..27}, {flagCondition}, encodingR12, encodingR0, encodingR16, None, None, None);
  2362. EnterInstruction(opQSUB, {4, 6, 21, 24}, {4..7, 20..27}, {flagCondition}, encodingR12, encodingR0, encodingR16, None, None, None);
  2363. EnterInstruction(opQDSUB, {4, 6, 21, 22, 24}, {4..7, 20..27}, {flagCondition}, encodingR12, encodingR0, encodingR16, None, None, None);
  2364. EnterInstruction(opRSB, {21, 22}, {21..24, 26, 27}, {flagCondition, flagS}, encodingR12, encodingR16, encodingAddressingMode1, None, None, None);
  2365. EnterInstruction(opRSC, {21, 22, 23}, {21..24, 26, 27}, {flagCondition, flagS}, encodingR12, encodingR16, encodingAddressingMode1, None, None, None);
  2366. EnterInstruction(opSBC, {22, 23}, {21..24, 26, 27}, {flagCondition, flagS}, encodingR12, encodingR16, encodingAddressingMode1, None, None, None);
  2367. EnterInstruction(opSMLAL, {4, 7, 21, 22, 23}, {4..7, 21..27}, {flagCondition, flagS}, encodingR12, encodingR16, encodingR0, encodingR8, None, None);
  2368. EnterInstruction(opSMULL, {4, 7, 22, 23}, {4..7, 21..27}, {flagCondition, flagS}, encodingR12, encodingR16, encodingR0, encodingR8, None, None);
  2369. EnterInstruction(opSMLABB, {7, 24}, {4..7, 20..27}, {flagCondition}, encodingR16, encodingR0, encodingR8, encodingR12, None, None);
  2370. EnterInstruction(opSMLABT, {5, 7, 24}, {4..7, 20..27}, {flagCondition}, encodingR16, encodingR0, encodingR8, encodingR12, None, None);
  2371. EnterInstruction(opSMLATB, {6, 7, 24}, {4..7, 20..27}, {flagCondition}, encodingR16, encodingR0, encodingR8, encodingR12, None, None);
  2372. EnterInstruction(opSMLATT, {5, 6, 7, 24}, {4..7, 20..27}, {flagCondition}, encodingR16, encodingR0, encodingR8, encodingR12, None, None);
  2373. EnterInstruction(opSMLALBB, {7, 22, 24}, {4..7, 20..27}, {flagCondition}, encodingR12, encodingR16, encodingR0, encodingR8, None, None);
  2374. EnterInstruction(opSMLALBT, {5, 7, 22, 24}, {4..7, 20..27}, {flagCondition}, encodingR12, encodingR16, encodingR0, encodingR8, None, None);
  2375. EnterInstruction(opSMLALTB, {6, 7, 22, 24}, {4..7, 20..27}, {flagCondition}, encodingR12, encodingR16, encodingR0, encodingR8, None, None);
  2376. EnterInstruction(opSMLALTT, {5, 6, 7, 22, 24}, {4..7, 20..27}, {flagCondition}, encodingR12, encodingR16, encodingR0, encodingR8, None, None);
  2377. EnterInstruction(opSMLAWB, {7, 21, 24}, {4..7, 20..27}, {flagCondition}, encodingR16, encodingR0, encodingR8, encodingR12, None, None);
  2378. EnterInstruction(opSMLAWT, {6, 7, 21, 24}, {4..7, 20..27}, {flagCondition}, encodingR16, encodingR0, encodingR8, encodingR12, None, None);
  2379. EnterInstruction(opSMULBB, {7, 21, 22, 24}, {4..7, 20..27}, {flagCondition}, encodingR16, encodingR0, encodingR8, None, None, None);
  2380. EnterInstruction(opSMULBT, {5, 21, 7, 22, 24}, {4..7, 20..27}, {flagCondition}, encodingR16, encodingR0, encodingR8, None, None, None);
  2381. EnterInstruction(opSMULTB, {6, 7, 21, 22, 24}, {4..7, 20..27}, {flagCondition}, encodingR16, encodingR0, encodingR8, None, None, None);
  2382. EnterInstruction(opSMULTT, {5, 6, 7, 21, 22, 24}, {4..7, 20..27}, {flagCondition}, encodingR16, encodingR0, encodingR8, None, None, None);
  2383. EnterInstruction(opSMULWB, {5, 7, 21, 24}, {4..7, 20..27}, {flagCondition}, encodingR16, encodingR0, encodingR8, None, None, None);
  2384. EnterInstruction(opSMULWT, {5, 6, 7, 21, 24}, {4..7, 20..27}, {flagCondition}, encodingR16, encodingR0, encodingR8, None, None, None);
  2385. EnterInstruction(opSTC, {26, 27}, {20, 25..27}, {flagCondition, flagL}, encodingCoprocessor, encodingCR12, encodingAddressingMode5, None, None, None);
  2386. EnterInstruction(opSTC2, {26, 27, 28..31}, {20, 25..27, 28..31}, {flagL}, encodingCoprocessor, encodingCR12, encodingAddressingMode5, None, None, None);
  2387. (*EnterInstruction(opSTM, {27}, {20, 25..27}, {flagCondition, flagIA, flagIB, flagDA, flagDB, flagUserMode, flagBaseRegisterUpdate}, encodingR16, encodingRegisterList, None, None, None, None);*)
  2388. EnterInstruction(opSTM, {27}, {20, 25..27}, {flagCondition, flagIA, flagIB, flagDA, flagDB, flagBaseRegisterUpdate}, encodingR16, encodingRegisterList, None, None, None, None);
  2389. EnterInstruction(opSTR, {26}, {20, 26, 27}, {flagCondition, flagB, flagT, flagBT}, encodingR12, encodingAddressingMode2, None, None, None, None);
  2390. EnterInstruction(opSTR, {4, 5, 7}, {4, 7, 20, 25..27}, {flagCondition, flagH, flagSH, flagSB, flagD}, encodingR12, encodingAddressingMode3, None, None, None, None);
  2391. EnterInstruction(opSUB, {22}, {21..24, 26, 27}, {flagCondition, flagS}, encodingR12, encodingR16, encodingAddressingMode1, None, None, None);
  2392. EnterInstruction(opSWI, {24..27}, {24..27}, {flagCondition}, encodingImm24, None, None, None, None, None);
  2393. EnterInstruction(opSWP, {4, 7, 24}, {4..7, 20..27}, {flagCondition}, encodingR12, encodingR0, encodingR16 (*! optional *), None, None, None);
  2394. EnterInstruction(opSWP, {4, 7, 22, 24}, {4..7, 20..27}, {flagCondition, flagB}, encodingR12, encodingR0, encodingR16 (*! optional *), None, None, None);
  2395. EnterInstruction(opTEQ, {20, 21, 24}, {20..24, 26, 27}, {flagCondition}, encodingR16, encodingAddressingMode1, None, None, None, None);
  2396. EnterInstruction(opTST, {20, 24}, {20..24, 26, 27}, {flagCondition}, encodingR16, encodingAddressingMode1, None, None, None, None);
  2397. EnterInstruction(opUMLAL, {4, 7, 21, 23}, {4..7, 21..27}, {flagCondition, flagS}, encodingR12, encodingR16, encodingR0, encodingR8, None, None);
  2398. EnterInstruction(opUMULL, {4, 7, 23}, {4..7, 21..27}, {flagCondition, flagS}, encodingR12, encodingR16, encodingR0, encodingR8, None, None);
  2399. EnterNEONInstruction(opLDM, "XXXX 100X X101 XXXX 0XXX XXXX XXXX XXXX", {flagCondition, flagIA, flagDA, flagIB, flagDB, flagUserMode}, encodingR16, encodingRegisterList, None, None, None, None);
  2400. EnterNEONInstruction(opSTM, "XXXX 100X X100 XXXX XXXX XXXX XXXX XXXX", {flagCondition, flagIA, flagDA, flagIB, flagDB, flagUserMode}, encodingR16, encodingRegisterList, None, None, None, None);
  2401. EnterNEONInstruction(opISB, "1111 0101 0111 1111 1111 0000 0110 1111", {}, None, None, None, None, None, None);
  2402. EnterNEONInstruction(opLSL, "XXXX 0001 1010 0000 XXXX XXXX X000 XXXX", {flagCondition, flagS}, encodingR12, encodingR0, encodingImm7to11, None, None, None);
  2403. EnterNEONInstruction(opLSL, "XXXX 0001 1010 0000 XXXX XXXX 0001 XXXX", {flagCondition, flagS}, encodingR12, encodingR0, encodingR8, None, None, None);
  2404. EnterNEONInstruction(opLSR, "XXXX 0001 1010 0000 XXXX XXXX X010 XXXX", {flagCondition, flagS}, encodingR12, encodingR0, encodingImm7to11, None, None, None);
  2405. EnterNEONInstruction(opSEV, "XXXX 0011 0010 0000 1111 0000 0000 0100", {flagCondition}, None, None, None, None, None, None);
  2406. EnterNEONInstruction(opDSB, "1111 0101 0111 1111 1111 0000 0100 1111", {}, None, None, None, None, None, None); (* Full System Reset only *)
  2407. EnterNEONInstruction(opLDREX, "XXXX 0001 1001 XXXX XXXX 1111 1001 1111", {flagCondition}, encodingR12, encodingR16, None, None, None, None);
  2408. EnterNEONInstruction(opSTREX, "XXXX 0001 1000 XXXX XXXX 1111 1001 XXXX", {flagCondition}, encodingR12, encodingR0, encodingR16, None, None, None);
  2409. (* Only for labels after current instruction *)
  2410. EnterNEONInstruction(opADR, "XXXX 0010 1000 1111 XXXX XXXX XXXX XXXX", {flagCondition}, encodingR12, encodingRotImm8, None, None, None, None);
  2411. EnterNEONInstruction(opLDREXB, "XXXX 0001 1101 XXXX XXXX 1111 1001 1111", {flagCondition}, encodingR12, encodingR16, None, None, None, None);
  2412. EnterNEONInstruction(opSTREXB, "XXXX 0001 1100 XXXX XXXX 1111 1001 XXXX", {flagCondition}, encodingR12, encodingR0, encodingR16, None, None, None);
  2413. EnterNEONInstruction(opDMB, "1111 0101 0111 1111 1111 0000 0101 1111", {}, None, None, None, None, None, None);
  2414. EnterNEONInstruction(opCLREX, "1111 0101 0111 1111 1111 0000 0001 1111", {}, None, None, None, None, None, None);
  2415. EnterNEONInstruction(opREV, "XXXX 0110 1011 1111 XXXX 1111 0011 XXXX", {flagCondition}, encodingR12, encodingR0, None, None, None, None);
  2416. EnterNEONInstruction(opREV16, "XXXX 0110 1011 1111 XXXX 1111 1011 XXXX", {flagCondition}, encodingR12, encodingR0, None, None, None, None);
  2417. EnterNEONInstruction(opUXTH, "XXXX 0110 1111 1111 XXXX XX00 0111 XXXX", {flagCondition}, encodingR12, encodingR0, None, None, None, None);
  2418. EnterNEONInstruction(opWFE, "XXXX 0011 0010 0000 1111 0000 0000 0010", {flagCondition}, None, None, None, None, None, None);
  2419. EnterNEONInstruction(opWFI, "XXXX 0011 0010 0000 1111 0000 0000 0011", {flagCondition}, None, None, None, None, None, None);
  2420. (* NEON instructions *)
  2421. EnterNEONInstruction(opVADD, "1111 0010 0XSS XXXX XXXX 1000 XQX0 XXXX", {flagNEONInt, flagNEON8bits, flagNEON16bits, flagNEON32bits, flagNEON64bits}, encodingNEONQorDd, encodingNEONQorDn, encodingNEONQorDm, None, None, None);
  2422. EnterNEONInstruction(opVADD, "1111 0010 0X00 XXXX XXXX 1101 XQX0 XXXX", {flagNEONFloat, flagNEON32bits}, encodingNEONQorDd, encodingNEONQorDn, encodingNEONQorDm, None, None, None);
  2423. EnterNEONInstruction(opVADD, "XXXX 1110 0X11 XXXX XXXX 101Q X0X0 XXXX", {flagCondition, flagNEONFloat, flagNEON64bits, flagNEON32bits}, encodingNEONDorSd, encodingNEONDorSn, encodingNEONDorSm, None, None, None);
  2424. EnterNEONInstruction(opVADDL, "1111 001U 1XSS XXXX XXXX 0000 X0X0 XXXX", {flagNEONSigned, flagNEONUnsigned, flagNEON8bits, flagNEON16bits, flagNEON32bits}, encodingNEONQd, encodingNEONDm, encodingNEONDn, None, None, None);
  2425. EnterNEONInstruction(opVADDW, "1111 001U 1XSS XXXX XXXX 0001 X0X0 XXXX", {flagNEONSigned, flagNEONUnsigned, flagNEON8bits, flagNEON16bits, flagNEON32bits}, encodingNEONQd, encodingNEONQm, encodingNEONDn, None, None, None);
  2426. EnterNEONInstruction(opVMUL, "1111 0010 0XSS XXXX XXXX 1001 XQX1 XXXX", {flagNEONInt, flagNEONUnsigned, flagNEONSigned, flagNEON8bits, flagNEON16bits, flagNEON32bits}, encodingNEONQorDd, encodingNEONQorDn, encodingNEONQorDm, None, None, None); (*! Does not support polynomail types yet *)
  2427. EnterNEONInstruction(opVMUL, "1111 0011 0X00 XXXX XXXX 1101 XQX1 XXXX", {flagNEONFloat, flagNEON32bits}, encodingNEONQorDd, encodingNEONQorDn, encodingNEONQorDm, None, None, None);
  2428. EnterNEONInstruction(opVMUL, "XXXX 1110 0X10 XXXX XXXX 101Q X0X0 XXXX", {flagNEONFloat, flagNEON32bits, flagNEON64bits, flagCondition}, encodingNEONDorSd, encodingNEONDorSm, encodingNEONDorSn, None, None, None);
  2429. EnterNEONInstruction(opVMULL, "1111 001U 1XSS XXXX XXXX 1010 X1X0 XXXX", {flagNEONSigned, flagNEONUnsigned, flagNEON16bits, flagNEON32bits}, encodingNEONQd, encodingNEONQm, encodingNEONDn, None, None, None);
  2430. EnterNEONInstruction(opVMSR, "XXXX 1110 1110 XXXX XXXX 1010 0001 0000", {flagCondition}, encodingNEONSysReg, encodingR12, None, None, None, None);
  2431. EnterNEONInstruction(opVMRS, "XXXX 1110 1111 XXXX XXXX 1010 0001 0000", {flagCondition}, encodingR12, encodingNEONSysReg, None, None, None, None);
  2432. EnterNEONInstruction(opVLDR, "XXXX 1101 UX01 XXXX XXXX 1011 XXXX XXXX", {flagCondition, flagNEON64bits}, encodingNEONDd, encodingR16, encodingNEONSigned8bitImm, None, None, None);
  2433. EnterNEONInstruction(opVLDR, "XXXX 1101 UX01 XXXX XXXX 1010 XXXX XXXX", {flagCondition, flagNEON32bits}, encodingNEONSd, encodingR16, encodingNEONSigned8bitImm, None, None, None);
  2434. EnterNEONInstruction(opVSTR, "XXXX 1101 UX00 XXXX XXXX 1011 XXXX XXXX", {flagCondition, flagNEON64bits}, encodingNEONDd, encodingR16, encodingNEONSigned8bitImm, None, None, None);
  2435. EnterNEONInstruction(opVSTR, "XXXX 1101 UX00 XXXX XXXX 1010 XXXX XXXX", {flagCondition, flagNEON32bits}, encodingNEONSd, encodingR16, encodingNEONSigned8bitImm, None, None, None);
  2436. EnterNEONInstruction(opVDIV, "XXXX 1110 1X00 XXXX XXXX 101Q X0X0 XXXX", {flagCondition, flagNEONFloat, flagNEON32bits, flagNEON64bits}, encodingNEONDorSd, encodingNEONDorSn, encodingNEONDorSm, None, None, None);
  2437. EnterNEONInstruction(opVMLA, "1111 0010 0XSS XXXX XXXX 1001 XQX0 XXXX", {flagNEONInt, flagNEONSigned, flagNEONUnsigned, flagNEON8bits, flagNEON16bits, flagNEON32bits}, encodingNEONQorDd, encodingNEONQorDn, encodingNEONQorDm, None, None, None);
  2438. EnterNEONInstruction(opVMLA, "1111 0010 0X00 XXXX XXXX 1101 XQX1 XXXX", {flagNEONFloat, flagNEON32bits}, encodingNEONQorDd, encodingNEONQorDn, encodingNEONQorDm, None, None, None);
  2439. EnterNEONInstruction(opVMLA, "XXXX 1110 0X00 XXXX XXXX 101Q X0X0 XXXX", {flagCondition, flagNEONFloat, flagNEON64bits, flagNEON32bits}, encodingNEONDorSd, encodingNEONDorSn, encodingNEONDorSm, None, None, None);
  2440. EnterNEONInstruction(opVMLS, "1111 0011 0XSS XXXX XXXX 1001 XQX0 XXXX", {flagNEONInt, flagNEONSigned, flagNEONUnsigned, flagNEON8bits, flagNEON16bits, flagNEON32bits}, encodingNEONQorDd, encodingNEONQorDn, encodingNEONQorDm, None, None, None);
  2441. EnterNEONInstruction(opVMLS, "1111 0010 0X10 XXXX XXXX 1101 XQX1 XXXX", {flagNEONFloat, flagNEON32bits}, encodingNEONQorDd, encodingNEONQorDn, encodingNEONQorDm, None, None, None);
  2442. EnterNEONInstruction(opVMLS, "XXXX 1110 0X00 XXXX XXXX 101Q X1X0 XXXX", {flagCondition, flagNEONFloat, flagNEON64bits, flagNEON32bits}, encodingNEONDorSd, encodingNEONDorSn, encodingNEONDorSm, None, None, None);
  2443. EnterNEONInstruction(opVMIN, "1111 001U 0XSS XXXX XXXX 0110 XQX1 XXXX", {flagNEONSigned, flagNEONUnsigned, flagNEON8bits, flagNEON16bits, flagNEON32bits}, encodingNEONQorDd, encodingNEONQorDn, encodingNEONQorDm, None, None, None);
  2444. EnterNEONInstruction(opVMAX, "1111 001U 0XSS XXXX XXXX 0110 XQX0 XXXX", {flagNEONSigned, flagNEONUnsigned, flagNEON8bits, flagNEON16bits, flagNEON32bits}, encodingNEONQorDd, encodingNEONQorDn, encodingNEONQorDm, None, None, None);
  2445. EnterNEONInstruction(opVSUB, "1111 0011 0XSS XXXX XXXX 1000 XQX0 XXXX", {flagNEONInt, flagNEON8bits, flagNEON16bits, flagNEON32bits, flagNEON64bits}, encodingNEONQorDd, encodingNEONQorDn, encodingNEONQorDm, None, None, None);
  2446. EnterNEONInstruction(opVABS, "1111 0011 1X11 SS01 XXXX 0o11 0QX0 XXXX", {flagNEONSigned, flagNEONFloat,flagNEON8bits, flagNEON16bits, flagNEON32bits}, encodingNEONQorDd, encodingNEONQorDm, None, None, None, None);
  2447. EnterNEONInstruction(opVABD, "1111 001U 0XSS XXXX XXXX 0111 XQX0 XXXX", {flagNEONSigned, flagNEONUnsigned, flagNEON8bits, flagNEON16bits, flagNEON32bits}, encodingNEONQorDd, encodingNEONQorDn, encodingNEONQorDm, None, None, None);
  2448. (* Fixed alignment and list size... not using [] or {} syntax *)
  2449. EnterNEONInstruction(opVLD1, "1111 0100 0X10 XXXX XXXX 1010 SS00 1111", {flagNEON8bits, flagNEON16bits, flagNEON32bits, flagNEON64bits}, encodingNEONDd, encodingR16, None, None, None, None);
  2450. EnterNEONInstruction(opVST1, "1111 0100 0X00 XXXX XXXX 1010 SS00 1111", {flagNEON8bits, flagNEON16bits, flagNEON32bits, flagNEON64bits}, encodingNEONDd, encodingR16, None, None, None, None);
  2451. EnterNEONInstruction(opVPADD, "1111 0011 0X00 XXXX XXXX 1101 X0X0 XXXX", {flagNEON32bits, flagNEONFloat}, encodingNEONDd, encodingNEONDn, encodingNEONDm, None, None, None);
  2452. EnterNEONInstruction(opVMOV, "XXXX 1110 0001 XXXX XXXX 1010 X001 0000", {flagCondition}, encodingR12, encodingNEONSn, None, None, None ,None);
  2453. EnterNEONInstruction(opVMOV, "XXXX 1110 0000 XXXX XXXX 1010 X001 0000", {flagCondition}, encodingNEONSn, encodingR12, None, None, None, None);
  2454. FOR i := 0 TO NumberInstructions-1 DO ASSERT(instructionFormats[i].mnemonic # None)
  2455. END;
  2456. END Init;
  2457. (** dump the name of a condition (the last name entered is preferred) **)
  2458. PROCEDURE DumpConditionName*(w: Streams.Writer; CONST conditionNumber: LONGINT);
  2459. VAR
  2460. i, foundIndex: LONGINT;
  2461. BEGIN
  2462. (* go through all condition names *)
  2463. foundIndex := None;
  2464. FOR i := 0 TO NumberConditionEntries - 1 DO
  2465. IF conditionEntries[i].number = conditionNumber THEN foundIndex := i END
  2466. END;
  2467. ASSERT(foundIndex # None);
  2468. w.String(conditionEntries[foundIndex].name);
  2469. END DumpConditionName;
  2470. (** dump the name of a register (the last name entered is preferred) **)
  2471. PROCEDURE DumpRegisterName*(w: Streams.Writer; registerNumber: LONGINT);
  2472. VAR
  2473. i, foundIndex: LONGINT;
  2474. BEGIN
  2475. (* go through all register names *)
  2476. foundIndex := None;
  2477. FOR i := 0 TO NumberRegisterEntries - 1 DO
  2478. IF registerEntries[i].number = registerNumber THEN foundIndex := i END
  2479. END;
  2480. ASSERT(foundIndex # None);
  2481. w.String(registerEntries[foundIndex].name);
  2482. END DumpRegisterName;
  2483. PROCEDURE DumpOperand*(w: Streams.Writer; CONST operand: Operand);
  2484. VAR i: LONGINT; first: BOOLEAN; mode: LONGINT;
  2485. BEGIN
  2486. mode := operand.mode; (* debugging *)
  2487. CASE operand.mode OF
  2488. | None: w.String("NONE!")
  2489. | modeCoprocessor: w.String("P"); w.Int(operand.coprocessor, 1)
  2490. | modeImmediate: w.String("#"); w.Int(operand.immediate, 1)
  2491. | modeMemory: w.String("[");
  2492. IF operand.register # None THEN
  2493. DumpRegisterName(w, operand.register)
  2494. END;
  2495. IF PostIndexed IN operand.indexing THEN
  2496. w.String("]")
  2497. END;
  2498. w.String(", ");
  2499. IF operand.offsetRegister= None THEN
  2500. w.String("#")
  2501. END;
  2502. IF Decrement IN operand.indexing THEN w.String("-");
  2503. ELSIF Increment IN operand.indexing THEN w.String("+");
  2504. ELSE HALT(100);
  2505. END;
  2506. IF operand.offsetRegister= None THEN
  2507. (*
  2508. w.Hex(operand.offsetImmediate, 1);w.String("H");
  2509. *)
  2510. w.Int(operand.offsetImmediate, 0)
  2511. ELSE
  2512. DumpRegisterName(w, operand.offsetRegister)
  2513. END;
  2514. IF operand.shiftMode # None THEN
  2515. w.String(", ");
  2516. w.String(shiftNames[operand.shiftMode]);
  2517. IF operand.shiftMode # shiftRRX THEN
  2518. w.String(" ");
  2519. IF operand.shiftRegister # None THEN
  2520. DumpRegisterName(w, operand.shiftRegister)
  2521. ELSE
  2522. w.String("#"); w.Int(operand.shiftImmediate, 1);
  2523. END;
  2524. END;
  2525. END;
  2526. IF ~(PostIndexed IN operand.indexing) THEN
  2527. w.String("]");
  2528. END;
  2529. IF PreIndexed IN operand.indexing THEN w.String("!") END
  2530. | modeOpcode: w.Int(operand.opcode, 0)
  2531. | modeRegister:
  2532. DumpRegisterName(w, operand.register);
  2533. IF (operand.shiftMode # None) THEN
  2534. w.String(", ");
  2535. w.String(shiftNames[operand.shiftMode]);
  2536. IF operand.shiftMode # shiftRRX THEN
  2537. w.String(" ");
  2538. IF operand.shiftRegister # None THEN
  2539. DumpRegisterName(w, operand.shiftRegister)
  2540. ELSE
  2541. w.String("#"); w.Int(operand.shiftImmediate, 1);
  2542. END;
  2543. END;
  2544. END
  2545. | modeRegisterList:
  2546. w.String("{");first := TRUE;
  2547. FOR i := 0 TO 31 DO
  2548. IF i IN operand.registerList THEN
  2549. IF ~first THEN w.String(", ") ELSE first := FALSE END;
  2550. DumpRegisterName(w, i + operand.register)
  2551. END;
  2552. END;
  2553. w.String("}");
  2554. | modeOption:
  2555. w.String("{"); w.Int(operand.option, 1); w.String("}")
  2556. | modeRegisterWithFields:
  2557. DumpRegisterName(w, operand.register);
  2558. w.String("_");
  2559. IF fieldF IN operand.fields THEN w.String("f") END;
  2560. IF fieldS IN operand.fields THEN w.String("s") END;
  2561. IF fieldX IN operand.fields THEN w.String("x") END;
  2562. IF fieldC IN operand.fields THEN w.String("c") END;
  2563. END;
  2564. END DumpOperand;
  2565. PROCEDURE DumpInstruction*(w: Streams.Writer; CONST instruction: Instruction);
  2566. VAR i: LONGINT;
  2567. BEGIN
  2568. IF instruction.format= None THEN
  2569. w.String("undefined format"); w.Ln;
  2570. ELSE
  2571. w.String(mnemonics[instructionFormats[instruction.format].mnemonic].name);
  2572. END;
  2573. IF (instruction.condition # None) & (instruction.condition # conditionAL) THEN
  2574. DumpConditionName(w, instruction.condition)
  2575. END;
  2576. FOR i := 0 TO NumberFlags-1 DO
  2577. IF i IN instruction.flags THEN
  2578. w.String(flagNames[i]);
  2579. END;
  2580. END;
  2581. i := 0;
  2582. WHILE (i<MaxOperands) & (instruction.operands[i].mode # None) DO
  2583. IF i > 0 THEN w.String(", ") ELSE w.String(" ") END;
  2584. DumpOperand(w, instruction.operands[i]);
  2585. IF (i= 0) & (flagBaseRegisterUpdate IN instruction.flags) THEN w.String("!")
  2586. ELSIF (i= 1) & (flagUserMode IN instruction.flags) THEN w.String("^");
  2587. END;
  2588. INC(i);
  2589. END;
  2590. END DumpInstruction;
  2591. PROCEDURE Test*(context: Commands.Context);
  2592. VAR str: ARRAY 32 OF CHAR; mnemonic: LONGINT; condition: LONGINT; flags: SET; i: LONGINT;
  2593. BEGIN
  2594. IF context.arg.GetString(str) THEN
  2595. IF FindMnemonic(str, mnemonic, condition, flags) THEN
  2596. context.out.String("found: "); context.out.String(mnemonics[mnemonic].name);
  2597. IF condition # None THEN
  2598. context.out.String(":");
  2599. context.out.String(conditionEntries[condition].name);
  2600. END;
  2601. FOR i := 0 TO NumberFlags DO
  2602. IF i IN flags THEN
  2603. context.out.String(":");
  2604. context.out.String(flagNames[i]);
  2605. END;
  2606. END;
  2607. END;
  2608. END;
  2609. END Test;
  2610. PROCEDURE Test2*(context: Commands.Context);
  2611. VAR operands: ARRAY 3 OF Operand; mnemonic: LONGINT; condition: LONGINT; flags: SET; instruction: Instruction;
  2612. BEGIN
  2613. InitRegister(operands[0], R0, None, None, 0);
  2614. InitRegister(operands[1], R1, None, None, 0);
  2615. InitRegister(operands[2], R1, shiftLSR, None, 8);
  2616. IF FindMnemonic("ADDEQ", mnemonic, condition, flags) THEN
  2617. IF MakeInstruction(instruction, mnemonic, condition, flags, operands) THEN
  2618. DumpInstruction(context.out, instruction);
  2619. ELSE
  2620. context.error.String("instruction not found");
  2621. END
  2622. ELSE
  2623. context.error.String("mnemonic not found");
  2624. END;
  2625. END Test2;
  2626. PROCEDURE ReadCode(file: Files.File): BitSets.BitSet;
  2627. VAR r: Files.Reader; val: LONGINT;bitSet: BitSets.BitSet; adr: LONGINT;
  2628. BEGIN
  2629. IF file = NIL THEN RETURN NIL END;
  2630. adr := 0;
  2631. NEW(r, file, 0);
  2632. NEW(bitSet,0);
  2633. WHILE r.Available()>0 DO
  2634. r.RawLInt(val);
  2635. INC(adr);
  2636. bitSet.Resize(adr*32);
  2637. bitSet.SetBits((adr-1)*32,32,val);
  2638. END;
  2639. RETURN bitSet
  2640. END ReadCode;
  2641. PROCEDURE Disassemble*(context: Commands.Context);
  2642. TYPE
  2643. Disasm = OBJECT (Disassembler.Disassembler)
  2644. PROCEDURE DisassembleInstruction(bitSet: BitSets.BitSet; VAR adr: LONGINT; maxInstructionSize: LONGINT; w:Streams.Writer);
  2645. VAR instruction: Instruction; value: LONGINT; mnemonic: LONGINT;
  2646. BEGIN
  2647. (* maxInstructionSize can be ignored here *)
  2648. value := bitSet.GetBits(adr*8,32);
  2649. IF Decode(value, instruction) THEN
  2650. DumpInstruction(w, instruction);
  2651. mnemonic := instructionFormats[instruction.format].mnemonic;
  2652. IF (mnemonic = opBL) OR (mnemonic = opB) THEN
  2653. WriteReference(instruction.operands[0].immediate+adr+8, TRUE (* points to code section *), w);
  2654. ELSIF (mnemonic = opLDR) OR (mnemonic = opSTR) THEN
  2655. (* LDR? ..., [PC, #...] or STR? ..., [PC, #...] *)
  2656. ASSERT(instruction.operands[1].mode = modeMemory);
  2657. IF (instruction.operands[1].register = PC) & (instruction.operands[1].offsetRegister = None) THEN
  2658. IF Decrement IN instruction.operands[1].indexing THEN
  2659. value := -instruction.operands[1].offsetImmediate + adr + 8;
  2660. ELSE
  2661. value := instruction.operands[1].offsetImmediate + adr + 8;
  2662. END;
  2663. WriteReference(value, TRUE, w);
  2664. IF (value>=0) & (value * 8 + 32 < bitSet.GetSize()) THEN
  2665. WriteReference(bitSet.GetBits(value * 8, 32) - codeDisplacement, TRUE, w); (* note that data references cannot be resolved like this *)
  2666. END
  2667. END
  2668. END;
  2669. ELSE
  2670. w.String("*** COULD NOT DECODE ***");
  2671. END;
  2672. INC(adr,4);
  2673. END DisassembleInstruction;
  2674. END Disasm;
  2675. VAR disassembler: Disasm; codeFileName, dataFileName, logFileName: Files.FileName; codeFile, logFile: Files.File;code: BitSets.BitSet; options: Options.Options;
  2676. address, offset: LONGINT;
  2677. BEGIN
  2678. IF context.arg.GetString(codeFileName) THEN
  2679. codeFile := Files.Old(codeFileName);
  2680. IF codeFile = NIL THEN context.out.String("file not found "); context.out.String(codeFileName); RETURN END;
  2681. NEW(options);
  2682. options.Add("l","logFile", Options.String);
  2683. options.Add("a","address",Options.Integer);
  2684. options.Add("o","offset",Options.Integer);
  2685. IF options.Parse(context.arg, context.out) THEN
  2686. IF ~options.GetInteger("a", address) THEN address := 0 END;
  2687. NEW(disassembler, context.out);
  2688. code := ReadCode(codeFile);
  2689. IF options.GetString("logFile",logFileName) THEN
  2690. logFile := Files.Old(logFileName);
  2691. ELSE
  2692. logFile := disassembler.GetLogFile(codeFileName)
  2693. END;
  2694. IF options.GetInteger("o",offset) THEN
  2695. disassembler.SetDisplacements(offset,offset)
  2696. END;
  2697. disassembler.Disassemble(code, code, 8,8 , logFile, address);
  2698. END;
  2699. END;
  2700. END Disassemble;
  2701. BEGIN Init;
  2702. END FoxARMInstructionSet.
  2703. SystemTools.FreeDownTo FoxARMInstructionSet ~
  2704. FoxARMInstructionSet.Test BLEQSB ~
  2705. FoxARMInstructionSet.Test2 ~
  2706. FoxARMInstructionSet.Test3 "E:/Systembau11/WinAos/Work/Minos.boot" ~