FoxARMInstructionSet.Mod 123 KB

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