2
0

FoxARMInstructionSet.Mod 122 KB

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