tc-csky.c 210 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967
  1. /* tc-csky.c -- Assembler for C-SKY
  2. Copyright (C) 1989-2022 Free Software Foundation, Inc.
  3. Created by Lifang Xia (lifang_xia@c-sky.com)
  4. Contributed by C-SKY Microsystems and Mentor Graphics.
  5. This file is part of GAS, the GNU Assembler.
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 3, or (at your option)
  9. any later version.
  10. GAS is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with GAS; see the file COPYING. If not, write to the Free
  16. Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
  17. 02110-1301, USA. */
  18. #include "as.h"
  19. #include <limits.h>
  20. #include <stdint.h>
  21. #include <stdarg.h>
  22. #include <ctype.h>
  23. #include "safe-ctype.h"
  24. #include "subsegs.h"
  25. #include "obstack.h"
  26. #include "libiberty.h"
  27. #ifdef OBJ_ELF
  28. #include "elf/csky.h"
  29. #include "dw2gencfi.h"
  30. #endif
  31. #include "tc-csky.h"
  32. #include "dwarf2dbg.h"
  33. #define BUILD_AS 1
  34. #define OPCODE_MAX_LEN 20
  35. #define HAS_SUB_OPERAND 0xfffffffful
  36. /* This value is just for lrw to distinguish "[]" label. */
  37. #define NEED_OUTPUT_LITERAL 1
  38. #define IS_EXTERNAL_SYM(sym, sec) (S_GET_SEGMENT (sym) != sec)
  39. #define IS_SUPPORT_OPCODE16(opcode) (opcode->isa_flag16 | isa_flag)
  40. #define IS_SUPPORT_OPCODE32(opcode) (opcode->isa_flag32 | isa_flag)
  41. #define KB * 1024
  42. #define MB KB * 1024
  43. #define GB MB * 1024
  44. /* Define DSP version flags. For different CPU, the version of DSP
  45. instructions may be different. */
  46. #define CSKY_DSP_FLAG_V1 (1 << 0) /* Normal DSP instructions. */
  47. #define CSKY_DSP_FLAG_V2 (1 << 1) /* CK803S enhanced DSP. */
  48. /* Literal pool related macros. */
  49. /* 1024 - 1 entry - 2 byte rounding. */
  50. #define v1_SPANPANIC (998)
  51. #define v1_SPANCLOSE (900)
  52. #define v1_SPANEXIT (600)
  53. #define v2_SPANPANIC (1024 - 4)
  54. /* 1024 is flrw offset.
  55. 24 is the biggest size for single instruction.
  56. for lrw16 (3+7, 512 bytes). */
  57. #define v2_SPANCLOSE (512 - 24)
  58. /* For lrw16, 112 average size for a function. */
  59. #define v2_SPANEXIT (512 - 112)
  60. /* For lrw16 (3+7, 512 bytes). */
  61. #define v2_SPANCLOSE_ELRW (1016 - 24)
  62. /* For lrw16, 112 average size for a function. */
  63. #define v2_SPANEXIT_ELRW (1016 - 112)
  64. #define MAX_POOL_SIZE (1024 / 4)
  65. #define POOL_END_LABEL ".LE"
  66. #define POOL_START_LABEL ".LS"
  67. /* Used in v1_relax_table. */
  68. /* These are the two types of relaxable instruction. */
  69. #define COND_JUMP 1
  70. #define UNCD_JUMP 2
  71. #define COND_JUMP_PIC 3
  72. #define UNCD_JUMP_PIC 4
  73. #define UNDEF_DISP 0
  74. #define DISP12 1
  75. #define DISP32 2
  76. #define UNDEF_WORD_DISP 3
  77. #define C12_LEN 2
  78. /* Allow for align: bt/jmpi/.long + align. */
  79. #define C32_LEN 10
  80. /* Allow for align: bt/subi/stw/bsr/lrw/add/ld/addi/jmp/.long + align. */
  81. #define C32_LEN_PIC 24
  82. #define U12_LEN 2
  83. /* Allow for align: jmpi/.long + align. */
  84. #define U32_LEN 8
  85. /* Allow for align: subi/stw/bsr/lrw/add/ld/addi/jmp/.long + align. */
  86. #define U32_LEN_PIC 22
  87. #define C(what,length) (((what) << 2) + (length))
  88. #define UNCD_JUMP_S (do_pic ? UNCD_JUMP_PIC : UNCD_JUMP)
  89. #define COND_JUMP_S (do_pic ? COND_JUMP_PIC : COND_JUMP)
  90. #define U32_LEN_S (do_pic ? U32_LEN_PIC : U32_LEN)
  91. #define C32_LEN_S (do_pic ? C32_LEN_PIC : C32_LEN)
  92. /* Used in v2_relax_table. */
  93. #define COND_DISP10_LEN 2 /* bt/bf_16. */
  94. #define COND_DISP16_LEN 4 /* bt/bf_32. */
  95. #define SCOND_DISP10_LEN 2 /* bt/bf_16, for CK801 only. */
  96. #define SCOND_DISP16_LEN 6 /* !(bt/bf_16) + br_32. */
  97. #define UNCD_DISP10_LEN 2 /* br_16. */
  98. #define UNCD_DISP16_LEN 4 /* br_32. */
  99. #define UNCD_DISP26_LEN 4 /* br32_old. */
  100. #define JCOND_DISP10_LEN 2 /* bt/bf_16. */
  101. #define JCOND_DISP16_LEN 4 /* bt/bf_32. */
  102. #define JCOND_DISP32_LEN 12 /* !(bt/bf_16)/jmpi 32/.align 2/literal 4. */
  103. #define JCOND_DISP26_LEN 8 /* bt/bf_32/br_32 old. */
  104. #define JUNCD_DISP26_LEN 4 /* bt/bf_32 old. */
  105. #define JUNCD_DISP10_LEN 2 /* br_16. */
  106. #define JUNCD_DISP16_LEN 4 /* bt/bf_32. */
  107. #define JUNCD_DISP32_LEN 10 /* jmpi_32/.align 2/literal 4/ CHANGED!. */
  108. #define JCOMP_DISP26_LEN 8 /* bne_32/br_32 old. */
  109. #define JCOMP_DISP16_LEN 4 /* bne_32 old. */
  110. #define JCOMPZ_DISP16_LEN 4 /* bhlz_32. */
  111. #define JCOMPZ_DISP32_LEN 14 /* bsz_32/jmpi 32/.align 2/literal 4. */
  112. #define JCOMPZ_DISP26_LEN 8 /* bsz_32/br_32 old. */
  113. #define JCOMP_DISP32_LEN 14 /* be_32/jmpi_32/.align 2/literal old. */
  114. #define BSR_DISP10_LEN 2 /* bsr_16. */
  115. #define BSR_DISP26_LEN 4 /* bsr_32. */
  116. #define LRW_DISP7_LEN 2 /* lrw16. */
  117. #define LRW_DISP16_LEN 4 /* lrw32. */
  118. /* Declare worker functions. */
  119. bool v1_work_lrw (void);
  120. bool v1_work_jbsr (void);
  121. bool v1_work_fpu_fo (void);
  122. bool v1_work_fpu_fo_fc (void);
  123. bool v1_work_fpu_write (void);
  124. bool v1_work_fpu_read (void);
  125. bool v1_work_fpu_writed (void);
  126. bool v1_work_fpu_readd (void);
  127. bool v2_work_istack (void);
  128. bool v2_work_btsti (void);
  129. bool v2_work_addi (void);
  130. bool v2_work_subi (void);
  131. bool v2_work_add_sub (void);
  132. bool v2_work_rotlc (void);
  133. bool v2_work_bgeni (void);
  134. bool v2_work_not (void);
  135. bool v2_work_jbtf (void);
  136. bool v2_work_jbr (void);
  137. bool v2_work_lrw (void);
  138. bool v2_work_lrsrsw (void);
  139. bool v2_work_jbsr (void);
  140. bool v2_work_jsri (void);
  141. bool v2_work_movih (void);
  142. bool v2_work_ori (void);
  143. bool float_work_fmovi (void);
  144. bool dsp_work_bloop (void);
  145. bool float_work_fpuv3_fmovi (void);
  146. bool float_work_fpuv3_fstore (void);
  147. bool v2_work_addc (void);
  148. /* csky-opc.h must be included after workers are declared. */
  149. #include "opcodes/csky-opc.h"
  150. #include "opcode/csky.h"
  151. enum
  152. {
  153. RELAX_NONE = 0,
  154. RELAX_OVERFLOW,
  155. COND_DISP10 = 20, /* bt/bf_16. */
  156. COND_DISP16, /* bt/bf_32. */
  157. SCOND_DISP10, /* br_16 */
  158. SCOND_DISP16, /* !(bt/bf_32) + br_32. */
  159. UNCD_DISP10, /* br_16. */
  160. UNCD_DISP16, /* br_32. */
  161. JCOND_DISP10, /* bt/bf_16. */
  162. JCOND_DISP16, /* bt/bf_32. */
  163. JCOND_DISP32, /* !(bt/bf_32)/jmpi + literal. */
  164. JUNCD_DISP10, /* br_16. */
  165. JUNCD_DISP16, /* br_32. */
  166. JUNCD_DISP32, /* jmpi + literal. */
  167. JCOMPZ_DISP16, /* bez/bnez/bhz/blsz/blz/bhsz. */
  168. JCOMPZ_DISP32, /* !(jbez/jbnez/jblsz/jblz/jbhsz) + jmpi + literal. */
  169. BSR_DISP26, /* bsr_32. */
  170. LRW_DISP7, /* lrw16. */
  171. LRW2_DISP8, /* lrw16, -mno-bsr16,8 bit offset. */
  172. LRW_DISP16, /* lrw32. */
  173. };
  174. unsigned int mach_flag = 0;
  175. unsigned int arch_flag = 0;
  176. unsigned int other_flag = 0;
  177. BFD_HOST_U_64_BIT isa_flag = 0;
  178. unsigned int dsp_flag = 0;
  179. typedef struct stack_size_entry
  180. {
  181. struct stack_size_entry *next;
  182. symbolS *function;
  183. unsigned int stack_size;
  184. } stack_size_entry;
  185. struct csky_arch_info
  186. {
  187. const char *name;
  188. unsigned int arch_flag;
  189. unsigned int bfd_mach_flag;
  190. };
  191. typedef enum
  192. {
  193. INSN_OPCODE,
  194. INSN_OPCODE16F,
  195. INSN_OPCODE32F,
  196. } inst_flag;
  197. /* Macro information. */
  198. struct csky_macro_info
  199. {
  200. const char *name;
  201. /* How many operands : if operands == 5, all of 1,2,3,4 are ok. */
  202. long oprnd_num;
  203. BFD_HOST_U_64_BIT isa_flag;
  204. /* Do the work. */
  205. void (*handle_func)(void);
  206. };
  207. struct csky_insn_info
  208. {
  209. /* Name of the opcode. */
  210. char *name;
  211. /* Output instruction. */
  212. unsigned int inst;
  213. /* Pointer for frag. */
  214. char *output;
  215. /* End of instruction. */
  216. char *opcode_end;
  217. /* CPU infomations. */
  218. const struct csky_cpu_info *cpu;
  219. /* Flag for INSN_OPCODE16F, INSN_OPCODE32F, INSN_OPCODE, INSN_MACRO. */
  220. inst_flag flag_force;
  221. /* Operand number. */
  222. int number;
  223. struct csky_opcode *opcode;
  224. struct csky_macro_info *macro;
  225. /* Insn size for check_literal. */
  226. unsigned int isize;
  227. unsigned int last_isize;
  228. /* Max size of insn for relax frag_var. */
  229. unsigned int max;
  230. /* Indicates which element is in csky_opcode_info op[] array. */
  231. int opcode_idx;
  232. /* The value of each operand in instruction when layout. */
  233. int idx;
  234. int val[MAX_OPRND_NUM];
  235. struct relax_info
  236. {
  237. int max;
  238. int var;
  239. int subtype;
  240. } relax;
  241. /* The following are used for constant expressions. */
  242. expressionS e1;
  243. expressionS e2;
  244. };
  245. /* Literal pool data structures. */
  246. struct literal
  247. {
  248. unsigned short refcnt;
  249. unsigned int offset;
  250. unsigned char ispcrel;
  251. unsigned char unused;
  252. bfd_reloc_code_real_type r_type;
  253. expressionS e;
  254. struct tls_addend tls_addend;
  255. unsigned char isdouble;
  256. uint64_t dbnum;
  257. LITTLENUM_TYPE bignum[SIZE_OF_LARGE_NUMBER + 6];
  258. };
  259. static void csky_idly (void);
  260. static void csky_rolc (void);
  261. static void csky_sxtrb (void);
  262. static void csky_movtf (void);
  263. static void csky_addc64 (void);
  264. static void csky_subc64 (void);
  265. static void csky_or64 (void);
  266. static void csky_xor64 (void);
  267. static void csky_neg (void);
  268. static void csky_rsubi (void);
  269. static void csky_arith (void);
  270. static void csky_decne (void);
  271. static void csky_lrw (void);
  272. static enum bfd_reloc_code_real insn_reloc;
  273. /* Assembler operand parse errors use these identifiers. */
  274. enum error_number
  275. {
  276. /* The following are errors. */
  277. ERROR_CREG_ILLEGAL = 0,
  278. ERROR_REG_OVER_RANGE,
  279. ERROR_FREG_OVER_RANGE,
  280. ERROR_VREG_OVER_RANGE,
  281. ERROR_GREG_ILLEGAL,
  282. ERROR_802J_REG_OVER_RANGE,
  283. ERROR_REG_FORMAT,
  284. ERROR_REG_LIST,
  285. ERROR_IMM_ILLEGAL,
  286. ERROR_IMM_OVERFLOW, /* 5 */
  287. ERROR_IMM_POWER,
  288. ERROR_JMPIX_OVER_RANGE,
  289. ERROR_EXP_CREG,
  290. ERROR_EXP_GREG,
  291. ERROR_EXP_CONSTANT,
  292. ERROR_EXP_EVEN_FREG,
  293. ERROR_RELOC_ILLEGAL,
  294. ERROR_MISSING_OPERAND, /* 10 */
  295. ERROR_MISSING_COMMA,
  296. ERROR_MISSING_LBRACKET,
  297. ERROR_MISSING_RBRACKET,
  298. ERROR_MISSING_LSQUARE_BRACKETS,
  299. ERROR_MISSING_RSQUARE_BRACKETS, /* 15 */
  300. ERROR_MISSING_LANGLE_BRACKETS,
  301. ERROR_MISSING_RANGLE_BRACKETS,
  302. ERROR_OFFSET_UNALIGNED,
  303. ERROR_BAD_END,
  304. ERROR_UNDEFINE,
  305. ERROR_CPREG_ILLEGAL, /* 20 */
  306. ERROR_OPCODE_PSRBIT,
  307. ERROR_OPERANDS_ILLEGAL,
  308. ERROR_OPERANDS_NUMBER,
  309. ERROR_OPCODE_ILLEGAL,
  310. /* The following are warnings. */
  311. WARNING_OPTIONS,
  312. WARNING_IDLY,
  313. /* Error and warning end. */
  314. ERROR_NONE,
  315. };
  316. /* Global error state. ARG1 and ARG2 are opaque data interpreted
  317. as appropriate for the error code. */
  318. struct csky_error_state
  319. {
  320. enum error_number err_num;
  321. int opnum;
  322. int arg_int;
  323. const void *arg1;
  324. const void *arg2;
  325. } error_state;
  326. /* This macro is used to set error number and arg1 in the global state. */
  327. #define SET_ERROR_STRING(err, msg) \
  328. do { \
  329. if (error_state.err_num > err) \
  330. { \
  331. error_state.err_num = err; \
  332. error_state.arg1 = (void *)msg; \
  333. } \
  334. } while (0)
  335. #define SET_ERROR_INTEGER(err, integer) \
  336. do { \
  337. if (error_state.err_num > err) \
  338. { \
  339. error_state.err_num = err; \
  340. error_state.arg_int = integer; \
  341. } \
  342. } while (0)
  343. /* Map error identifiers onto a format string, which will use
  344. arg1 and arg2 from the global error state. */
  345. struct csky_error_format_map
  346. {
  347. enum error_number num;
  348. const char *fmt;
  349. };
  350. static const struct csky_error_format_map err_formats[] =
  351. {
  352. {ERROR_CREG_ILLEGAL, "Operand %d error: control register is illegal."},
  353. {ERROR_REG_OVER_RANGE, "Operand %d error: r%d register is over range."},
  354. {ERROR_FREG_OVER_RANGE, "Operand %d error: vr%d register is over range."},
  355. {ERROR_VREG_OVER_RANGE, "Operand %d error: vr%d register is out of range."},
  356. {ERROR_GREG_ILLEGAL, "Operand %d error: general register is illegal."},
  357. {ERROR_802J_REG_OVER_RANGE, "Operand %d register %s out of range (802j only has registers:0-15,23,24,25,30)"},
  358. {ERROR_REG_FORMAT, "Operand %d error: %s."},
  359. {ERROR_REG_LIST, "Register list format is illegal."},
  360. {ERROR_IMM_ILLEGAL, "Operand %d is not an immediate."},
  361. {ERROR_IMM_OVERFLOW, "Operand %d immediate is overflow."},
  362. {ERROR_IMM_POWER, "immediate %d is not a power of two"},
  363. {ERROR_JMPIX_OVER_RANGE, "The second operand must be 16/24/32/40"},
  364. {ERROR_EXP_CREG, "Operand %d error: control register is expected."},
  365. {ERROR_EXP_GREG, "Operand %d error: general register is expected."},
  366. {ERROR_EXP_CONSTANT, "Operand %d error: constant is expected."},
  367. {ERROR_EXP_EVEN_FREG, "Operand %d error: even float register is expected."},
  368. {ERROR_RELOC_ILLEGAL, "@%s reloc is not supported"},
  369. {ERROR_MISSING_OPERAND, "Operand %d is missing."},
  370. {ERROR_MISSING_COMMA, "Missing ','"},
  371. {ERROR_MISSING_LBRACKET, "Missing '('"},
  372. {ERROR_MISSING_RBRACKET, "Missing ')'"},
  373. {ERROR_MISSING_LSQUARE_BRACKETS, "Missing '['"},
  374. {ERROR_MISSING_RSQUARE_BRACKETS, "Missing ']'"},
  375. {ERROR_MISSING_LANGLE_BRACKETS, "Missing '<'"},
  376. {ERROR_MISSING_RANGLE_BRACKETS, "Missing '>'"},
  377. {ERROR_OFFSET_UNALIGNED, "Operand %d is unaligned. It must be %d aligned!"},
  378. {ERROR_BAD_END, "Operands mismatch, it has a bad end: %s"},
  379. {ERROR_UNDEFINE, NULL},
  380. {ERROR_CPREG_ILLEGAL, "Operand %d illegal, expect a cpreg(cpr0-cpr63)."},
  381. {ERROR_OPCODE_PSRBIT, "The operands must be 'ie'/'ee'/'fe'."},
  382. {ERROR_OPERANDS_ILLEGAL, "Operands mismatch: %s."},
  383. {ERROR_OPERANDS_NUMBER, "Operands number mismatch, %d operands expected."},
  384. {ERROR_OPCODE_ILLEGAL, "The instruction is not recognized."},
  385. {WARNING_OPTIONS, "Option %s is not support in %s."},
  386. {WARNING_IDLY, "idly %d is encoded to: idly 4 "},
  387. {ERROR_NONE, "There is no error."},
  388. };
  389. static int do_pic = 0; /* for jbr/jbf/jbt relax jmpi reloc. */
  390. static int do_pff = -1; /* for insert two br ahead of literals. */
  391. static int do_force2bsr = -1; /* for jbsr->bsr. */
  392. static int do_jsri2bsr = 1; /* for jsri->bsr. */
  393. static int do_nolrw = 0; /* lrw to movih & ori, only for V2. */
  394. static int do_long_jump = -1; /* control if jbf,jbt,jbr relax to jmpi. */
  395. static int do_extend_lrw = -1; /* delete bsr16 in both two options,
  396. add btesti16, lrw offset +1 in -melrw. */
  397. static int do_func_dump = 0; /* dump literals after every function. */
  398. static int do_br_dump = 1; /* work for -mabr/-mno-abr, control the literals dump. */
  399. static int do_intr_stack = -1; /* control interrupt stack module, 801&802&803
  400. default on, 807&810, default off. */
  401. static int float_abi = 0;
  402. #ifdef INCLUDE_BRANCH_STUB
  403. static int do_use_branchstub = -1;
  404. #else
  405. static int do_use_branchstub = 0;
  406. #endif
  407. /* These are only used for options parsing. Values are bitmasks and are
  408. OR'ed into the processor flag bits in md_begin. */
  409. static int do_opt_mmp = 0;
  410. static int do_opt_mcp = 0;
  411. static int do_opt_mcache = 0;
  412. static int do_opt_msecurity = 0;
  413. static int do_opt_mhard_float = 0;
  414. static int do_opt_mtrust = 0;
  415. static int do_opt_mdsp = 0;
  416. static int do_opt_medsp = 0;
  417. static int do_opt_mvdsp = 0;
  418. const relax_typeS *md_relax_table = NULL;
  419. struct literal *literal_insn_offset;
  420. static struct literal litpool[MAX_POOL_SIZE];
  421. static unsigned poolsize = 0;
  422. static unsigned poolnumber = 0;
  423. static unsigned long poolspan = 0;
  424. static unsigned int SPANPANIC;
  425. static unsigned int SPANCLOSE;
  426. static unsigned int SPANEXIT;
  427. static stack_size_entry *all_stack_size_data = NULL;
  428. static stack_size_entry **last_stack_size_data = &all_stack_size_data;
  429. /* Control by ".no_literal_dump N"
  430. * 1 : don't dump literal pool between insn1 and insnN+1
  431. * 0 : do nothing. */
  432. static int do_noliteraldump = 0;
  433. /* Label for current pool. */
  434. static symbolS * poolsym;
  435. static char poolname[8];
  436. static bool mov_r1_before;
  437. static bool mov_r1_after;
  438. const relax_typeS csky_relax_table [] =
  439. {
  440. /* C-SKY V1 relax table. */
  441. {0, 0, 0, 0}, /* RELAX_NONE */
  442. {0, 0, 0, 0}, /* RELAX_OVERFLOW */
  443. {0, 0, 0, 0},
  444. {0, 0, 0, 0},
  445. /* COND_JUMP */
  446. { 0, 0, 0, 0 }, /* UNDEF_DISP */
  447. { 2048, -2046, C12_LEN, C (COND_JUMP, DISP32) }, /* DISP12 */
  448. { 0, 0, C32_LEN, 0 }, /* DISP32 */
  449. { 0, 0, C32_LEN, 0 }, /* UNDEF_WORD_DISP */
  450. /* UNCD_JUMP */
  451. { 0, 0, 0, 0 }, /* UNDEF_DISP */
  452. { 2048, -2046, U12_LEN, C (UNCD_JUMP, DISP32) }, /* DISP12 */
  453. { 0, 0, U32_LEN, 0 }, /* DISP32 */
  454. { 0, 0, U32_LEN, 0 }, /* UNDEF_WORD_DISP */
  455. /* COND_JUMP_PIC */
  456. { 0, 0, 0, 0 }, /* UNDEF_DISP */
  457. { 2048, -2046, C12_LEN, C (COND_JUMP_PIC, DISP32) }, /* DISP12 */
  458. { 0, 0, C32_LEN_PIC, 0 }, /* DISP32 */
  459. { 0, 0, C32_LEN_PIC, 0 }, /* UNDEF_WORD_DISP */
  460. /* UNCD_JUMP_PIC */
  461. { 0, 0, 0, 0 }, /* UNDEF_DISP */
  462. { 2048, -2046, U12_LEN, C (UNCD_JUMP_PIC, DISP32) }, /* DISP12 */
  463. { 0, 0, U32_LEN_PIC, 0 }, /* DISP32 */
  464. { 0, 0, U32_LEN_PIC, 0 }, /* UNDEF_WORD_DISP */
  465. /* C-SKY V2 relax table. */
  466. /* forward backward length more */
  467. { 1 KB - 2, -1 KB, COND_DISP10_LEN, COND_DISP16 }, /* COND_DISP10 */
  468. { 64 KB - 2, -64 KB, COND_DISP16_LEN, RELAX_OVERFLOW }, /* COND_DISP16 */
  469. { 1 KB - 2, -1 KB, SCOND_DISP10_LEN, SCOND_DISP16 }, /* SCOND_DISP10 */
  470. { 64 KB - 2, -64 KB, SCOND_DISP16_LEN, RELAX_OVERFLOW }, /* SCOND_DISP16 */
  471. { 1 KB - 2, -1 KB, UNCD_DISP10_LEN, UNCD_DISP16 }, /* UNCD_DISP10 */
  472. { 64 KB - 2, -64 KB, UNCD_DISP16_LEN, RELAX_OVERFLOW }, /* UNCD_DISP16 */
  473. { 1 KB - 2, -1 KB, JCOND_DISP10_LEN, JCOND_DISP16 }, /* JCOND_DISP10 */
  474. { 64 KB - 2, -64 KB, JCOND_DISP16_LEN, JCOND_DISP32 }, /* JCOND_DISP16 */
  475. { 0, 0, JCOND_DISP32_LEN, RELAX_NONE }, /* JCOND_DISP32 */
  476. { 1 KB - 2, -1 KB, JUNCD_DISP10_LEN, JUNCD_DISP16 }, /* JUNCD_DISP10 */
  477. { 64 KB - 2, -64 KB, JUNCD_DISP16_LEN, JUNCD_DISP32 }, /* JUNCD_DISP16 */
  478. { 0, 0, JUNCD_DISP32_LEN, RELAX_NONE }, /* JUNCD_DISP32 */
  479. { 64 KB - 2, -64 KB, JCOMPZ_DISP16_LEN, JCOMPZ_DISP32 }, /* JCOMPZ_DISP16 */
  480. { 0, 0, JCOMPZ_DISP32_LEN, RELAX_NONE }, /* JCOMPZ_DISP32 */
  481. { 64 MB - 2, -64 MB, BSR_DISP26_LEN, RELAX_OVERFLOW }, /* BSR_DISP26 */
  482. { 508, 0, LRW_DISP7_LEN, LRW_DISP16 }, /* LRW_DISP7 */
  483. { 1016, 0, LRW_DISP7_LEN, LRW_DISP16 }, /* LRW2_DISP8 */
  484. { 64 KB, 0, LRW_DISP16_LEN, RELAX_OVERFLOW }, /* LRW_DISP16 */
  485. };
  486. static void csky_write_insn (char *ptr, valueT use, int nbytes);
  487. void md_number_to_chars (char * buf, valueT val, int n);
  488. long md_pcrel_from_section (fixS * fixP, segT seg);
  489. /* C-SKY architecture table. */
  490. const struct csky_arch_info csky_archs[] =
  491. {
  492. {"ck510", CSKY_ARCH_510, bfd_mach_ck510},
  493. {"ck610", CSKY_ARCH_610, bfd_mach_ck610},
  494. {"ck801", CSKY_ARCH_801, bfd_mach_ck801},
  495. {"ck802", CSKY_ARCH_802, bfd_mach_ck802},
  496. {"ck803", CSKY_ARCH_803, bfd_mach_ck803},
  497. {"ck807", CSKY_ARCH_807, bfd_mach_ck807},
  498. {"ck810", CSKY_ARCH_810, bfd_mach_ck810},
  499. {"ck860", CSKY_ARCH_860, bfd_mach_ck860},
  500. {NULL, 0, 0}
  501. };
  502. #define CSKY_ARCH_807_BASE CSKY_ARCH_807 | CSKY_ARCH_DSP
  503. #define CSKY_ARCH_810_BASE CSKY_ARCH_810 | CSKY_ARCH_DSP
  504. struct csky_cpu_feature
  505. {
  506. const char unique;
  507. unsigned int arch_flag;
  508. bfd_uint64_t isa_flag;
  509. };
  510. struct csky_cpu_version
  511. {
  512. int r;
  513. int p;
  514. bfd_uint64_t isa_flag;
  515. };
  516. #define CSKY_FEATURE_MAX 10
  517. #define CSKY_CPU_REVERISON_MAX 10
  518. struct csky_cpu_info
  519. {
  520. const char *name;
  521. unsigned int arch_flag;
  522. bfd_uint64_t isa_flag;
  523. struct csky_cpu_feature features[CSKY_FEATURE_MAX];
  524. struct csky_cpu_version ver[CSKY_CPU_REVERISON_MAX];
  525. };
  526. #define FEATURE_DSP_EXT(isa) \
  527. {'e', CSKY_ARCH_DSP, isa}
  528. #define FEATURE_DSP(isa) \
  529. {'d', CSKY_ARCH_DSP, isa}
  530. #define FEATURE_MMU() \
  531. {'m', 0, 0}
  532. #define FEATURE_VDSP(isa) \
  533. {'v', CSKY_ARCH_DSP, isa}
  534. #define FEATURE_FLOAT(isa) \
  535. {'f', CSKY_ARCH_FLOAT, isa}
  536. #define FEATURE_TRUST(isa) \
  537. {'t', 0, isa}
  538. #define FEATURE_JAVA(isa) \
  539. {'j', CSKY_ARCH_JAVA, isa}
  540. #define FEATURE_SHIELD(isa) \
  541. {'h', 0, isa}
  542. #define CSKY_FEATURES_DEF_NULL() \
  543. {{0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  544. #define CSKY_FEATURES_DEF_e(isa_e) \
  545. {FEATURE_DSP_EXT(isa_e), \
  546. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  547. #define CSKY_FEATURES_DEF_t(isa_t) \
  548. {FEATURE_TRUST(isa_t), \
  549. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  550. #define CSKY_FEATURES_DEF_f(isa_f) \
  551. {FEATURE_FLOAT(isa_f), \
  552. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  553. #define CSKY_FEATURES_DEF_v(isa_v) \
  554. {FEATURE_VDSP(isa_v), \
  555. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  556. #define CSKY_FEATURES_DEF_ef(isa_e, isa_f) \
  557. {FEATURE_DSP_EXT(isa_e), \
  558. FEATURE_FLOAT(isa_f), \
  559. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  560. #define CSKY_FEATURES_DEF_jt(isa_j, isa_t) \
  561. {FEATURE_JAVA(isa_j), \
  562. FEATURE_TRUST(isa_t), \
  563. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  564. #define CSKY_FEATURES_DEF_efht(isa_e, isa_f, isa_h, isa_t) \
  565. {FEATURE_DSP_EXT(isa_e), \
  566. FEATURE_FLOAT(isa_f), \
  567. FEATURE_SHIELD(isa_h), \
  568. FEATURE_TRUST(isa_t), \
  569. {0}, {0}, {0}, {0}, {0}, {0}}
  570. #define CSKY_FEATURES_DEF_efv(isa_e, isa_f, isa_v) \
  571. {FEATURE_DSP_EXT(isa_e), \
  572. FEATURE_FLOAT(isa_f), \
  573. FEATURE_VDSP(isa_v), \
  574. {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  575. #define CSKY_FEATURES_DEF_eft(isa_e, isa_f, isa_t) \
  576. {FEATURE_DSP_EXT(isa_e), \
  577. FEATURE_FLOAT(isa_f), \
  578. FEATURE_TRUST(isa_t), \
  579. {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  580. #define CSKY_FEATURES_DEF_d(isa_d) \
  581. {FEATURE_DSP(isa_d), \
  582. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  583. #define CSKY_FEATURES_DEF_df(isa_d, isa_f) \
  584. {FEATURE_DSP(isa_d), \
  585. FEATURE_FLOAT(isa_f), \
  586. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  587. #define CSKY_FEATURES_DEF_ft(isa_f, isa_t) \
  588. {FEATURE_FLOAT(isa_f), \
  589. FEATURE_TRUST(isa_t), \
  590. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  591. #define CSKY_FEATURES_DEF_tv(isa_t, isa_v) \
  592. {FEATURE_TRUST(isa_t), \
  593. FEATURE_VDSP(isa_v), \
  594. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  595. #define CSKY_FEATURES_DEF_fv(isa_f, isa_v) \
  596. {FEATURE_FLOAT(isa_f), \
  597. FEATURE_VDSP(isa_v), \
  598. {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  599. #define CSKY_FEATURES_DEF_dft(isa_d, isa_f, isa_t) \
  600. {FEATURE_DSP(isa_d), \
  601. FEATURE_FLOAT(isa_f), \
  602. FEATURE_TRUST(isa_t), \
  603. {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  604. #define CSKY_FEATURES_DEF_dfv(isa_d, isa_f, isa_v) \
  605. {FEATURE_DSP(isa_d), \
  606. FEATURE_FLOAT(isa_f), \
  607. FEATURE_VDSP(isa_v), \
  608. {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  609. #define CSKY_FEATURES_DEF_ftv(isa_f, isa_t, isa_v) \
  610. {FEATURE_FLOAT(isa_f), \
  611. FEATURE_TRUST(isa_t), \
  612. FEATURE_VDSP(isa_v), \
  613. {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  614. #define CSKY_FEATURES_DEF_eftv(isa_e, isa_f, isa_t, isa_v) \
  615. {FEATURE_DSP_EXT(isa_e), \
  616. FEATURE_FLOAT(isa_f), \
  617. FEATURE_TRUST(isa_t), \
  618. FEATURE_VDSP(isa_v), \
  619. {0}, {0}, {0}, {0}, {0}, {0}}
  620. #define CSKY_CPU_REVERISON_r0p0(isa) \
  621. {0, 0, 0}
  622. #define CSKY_CPU_REVERISON_r1p0(isa) \
  623. {1, 0, isa}
  624. #define CSKY_CPU_REVERISON_r2p0(isa) \
  625. {2, 0, isa}
  626. #define CSKY_CPU_REVERISON_r3p0(isa) \
  627. {3, 0, isa}
  628. #define CSKY_CPU_REVERISON_RESERVED() \
  629. {{0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  630. #define CSKY_CPU_REVERISON_R3(isa1, isa2, isa3) \
  631. {CSKY_CPU_REVERISON_r1p0(isa1), \
  632. CSKY_CPU_REVERISON_r2p0(isa2), \
  633. CSKY_CPU_REVERISON_r3p0(isa3), \
  634. {0}, {0}, {0}, {0}, {0}, {0}, {0}}
  635. /* CSKY cpus table. */
  636. const struct csky_cpu_info csky_cpus[] =
  637. {
  638. #define CSKYV1_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_MAC_DSP)
  639. #define CSKY_ISA_510 (CSKYV1_ISA_E1)
  640. #define CSKY_ISA_610 (CSKYV1_ISA_E1 | CSKY_ISA_CP)
  641. {"ck510",
  642. CSKY_ARCH_510,
  643. CSKY_ISA_510,
  644. CSKY_FEATURES_DEF_e(CSKYV1_ISA_DSP),
  645. CSKY_CPU_REVERISON_RESERVED()},
  646. {"ck520",
  647. CSKY_ARCH_510 | CSKY_ARCH_MAC,
  648. CSKY_ISA_510 | CSKY_ISA_MAC | CSKY_ISA_MAC_DSP,
  649. CSKY_FEATURES_DEF_NULL(),
  650. CSKY_CPU_REVERISON_RESERVED()},
  651. {"ck610", CSKY_ARCH_610, CSKY_ISA_610,
  652. CSKY_FEATURES_DEF_ef(CSKYV1_ISA_DSP, CSKY_ISA_FLOAT_E1),
  653. CSKY_CPU_REVERISON_RESERVED()},
  654. {"ck620",
  655. CSKY_ARCH_610 | CSKY_ARCH_MAC,
  656. CSKY_ISA_610 | CSKY_ISA_MAC | CSKY_ISA_MAC_DSP,
  657. CSKY_FEATURES_DEF_NULL(),
  658. CSKY_CPU_REVERISON_RESERVED()},
  659. #define CSKY_ISA_801 (CSKYV2_ISA_E1 | CSKY_ISA_TRUST)
  660. #define CSKYV2_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_DSP_1E2 | CSKY_ISA_DSPE60)
  661. {"ck801",
  662. CSKY_ARCH_801,
  663. CSKY_ISA_801,
  664. CSKY_FEATURES_DEF_t(0),
  665. CSKY_CPU_REVERISON_RESERVED()},
  666. #define CSKY_ISA_802 (CSKY_ISA_801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC)
  667. {"ck802",
  668. CSKY_ARCH_802,
  669. CSKY_ISA_802,
  670. CSKY_FEATURES_DEF_jt(CSKY_ISA_JAVA, 0),
  671. CSKY_CPU_REVERISON_RESERVED()},
  672. #define CSKY_ISA_803 (CSKY_ISA_802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP)
  673. #define CSKY_ISA_803R1 (CSKYV2_ISA_3E3R1)
  674. #define CSKY_ISA_803R2 (CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2)
  675. #define CSKY_ISA_803R3 (CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2 | CSKYV2_ISA_3E3R3)
  676. #define CSKY_ISA_FLOAT_803 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E3)
  677. #define CSKY_ISA_EDSP (CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R3 | CSKY_ISA_DSP_ENHANCE)
  678. {"ck803s",
  679. CSKY_ARCH_803,
  680. CSKY_ISA_803 | CSKY_ISA_803R1,
  681. CSKY_FEATURES_DEF_eft(CSKYV2_ISA_DSP, CSKY_ISA_FLOAT_803, 0),
  682. CSKY_CPU_REVERISON_RESERVED()},
  683. {"ck803",
  684. CSKY_ARCH_803,
  685. CSKY_ISA_803,
  686. CSKY_FEATURES_DEF_efht(CSKYV2_ISA_DSP, CSKY_ISA_FLOAT_803, 0, 0),
  687. CSKY_CPU_REVERISON_R3(CSKY_ISA_803R1, CSKY_ISA_803R2, CSKY_ISA_803R3)},
  688. #define CSKY_ISA_804 (CSKY_ISA_803 | CSKY_ISA_803R3)
  689. {"ck804",
  690. CSKY_ARCH_804,
  691. CSKY_ISA_804,
  692. CSKY_FEATURES_DEF_efht(CSKY_ISA_EDSP, CSKY_ISA_FLOAT_803, 0, 0),
  693. CSKY_CPU_REVERISON_RESERVED()},
  694. #define CSKY_ISA_805 (CSKY_ISA_804 | CSKY_ISA_VDSP_2)
  695. #define CSKY_ARCH_805V (CSKY_ARCH_805 | CSKY_ARCH_DSP)
  696. #define CSKY_ISA_FLOAT_805 CSKY_ISA_FLOAT_803
  697. {"ck805",
  698. CSKY_ARCH_805,
  699. CSKY_ISA_805,
  700. CSKY_FEATURES_DEF_eft(CSKY_ISA_EDSP, CSKY_ISA_FLOAT_805, 0),
  701. CSKY_CPU_REVERISON_RESERVED()},
  702. #define CSKY_ISA_807 (CSKY_ISA_803 | CSKYV2_ISA_3E7 | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE | CSKYV2_ISA_DSP)
  703. #define CSKY_ISA_FLOAT_807 (CSKY_ISA_FLOAT_803 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
  704. {"ck807",
  705. CSKY_ARCH_807,
  706. CSKY_ISA_807,
  707. CSKY_FEATURES_DEF_ef(CSKYV2_ISA_DSP, CSKY_ISA_FLOAT_807),
  708. CSKY_CPU_REVERISON_RESERVED()},
  709. #define CSKY_ISA_810 (CSKY_ISA_807 | CSKYV2_ISA_7E10)
  710. #define CSKY_ISA_FLOAT_810 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E2)
  711. {"ck810v",
  712. CSKY_ARCH_810 | CSKY_ARCH_DSP,
  713. CSKY_ISA_810 | CSKY_ISA_VDSP,
  714. CSKY_FEATURES_DEF_NULL (),
  715. CSKY_CPU_REVERISON_RESERVED()},
  716. {"ck810",
  717. CSKY_ARCH_810,
  718. CSKY_ISA_810,
  719. CSKY_FEATURES_DEF_eftv(0, CSKY_ISA_FLOAT_810, 0, CSKY_ISA_VDSP),
  720. CSKY_CPU_REVERISON_RESERVED()},
  721. #define CSKY_ISA_860 ((CSKY_ISA_810 & ~(CSKYV2_ISA_DSP)) | CSKYV2_ISA_10E60 | CSKY_ISA_803R3 | CSKY_ISA_DSPE60)
  722. #define CSKY_ISA_860F (CSKY_ISA_860 | CSKY_ISA_FLOAT_7E60)
  723. #define CSKY_ISA_VDSP_860 (CSKY_ISA_VDSP_2)
  724. {"ck860v",
  725. CSKY_ARCH_860 | CSKY_ARCH_DSP,
  726. CSKY_ISA_860 | CSKY_ISA_VDSP_860,
  727. CSKY_FEATURES_DEF_f(CSKY_ISA_FLOAT_7E60),
  728. CSKY_CPU_REVERISON_RESERVED()},
  729. {"ck860",
  730. CSKY_ARCH_860,
  731. CSKY_ISA_860,
  732. CSKY_FEATURES_DEF_fv(CSKY_ISA_FLOAT_7E60, CSKY_ISA_VDSP_860),
  733. CSKY_CPU_REVERISON_RESERVED()},
  734. /* It is a special cpu, support all instructions. */
  735. #define CSKY_ISA_800 (CSKY_ISA_860 | CSKY_ISA_810 | CSKY_ISA_807 | CSKY_ISA_803)
  736. {"ck800",
  737. CSKY_ARCH_800,
  738. CSKY_ISA_800,
  739. CSKY_FEATURES_DEF_NULL(),
  740. CSKY_CPU_REVERISON_RESERVED()},
  741. #define CSKY_ISA_E801 (CSKY_ISA_801)
  742. #define CSKY_ISA_E802 (CSKY_ISA_E801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC)
  743. #define CSKY_ISA_E803 (CSKY_ISA_E802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2 | CSKYV2_ISA_3E3R3)
  744. #define CSKY_ISA_E804 (CSKY_ISA_E803)
  745. #define CSKY_ISA_FLOAT_V1 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E3)
  746. {"e801",
  747. CSKY_ARCH_801,
  748. CSKY_ISA_E801,
  749. CSKY_FEATURES_DEF_NULL(),
  750. CSKY_CPU_REVERISON_RESERVED()},
  751. {"e802",
  752. CSKY_ARCH_802,
  753. CSKY_ISA_E802,
  754. CSKY_FEATURES_DEF_t(0),
  755. CSKY_CPU_REVERISON_RESERVED()},
  756. {"e803",
  757. CSKY_ARCH_803,
  758. CSKY_ISA_E803,
  759. CSKY_FEATURES_DEF_t(0),
  760. CSKY_CPU_REVERISON_RESERVED()},
  761. {"e804",
  762. CSKY_ARCH_804,
  763. CSKY_ISA_E804,
  764. CSKY_FEATURES_DEF_dft(CSKY_ISA_EDSP, CSKY_ISA_FLOAT_V1, 0),
  765. CSKY_CPU_REVERISON_RESERVED()},
  766. #define CSKY_ISA_S802 (CSKY_ISA_E801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC | CSKY_ISA_TRUST)
  767. #define CSKY_ISA_S803 (CSKY_ISA_S802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2 | CSKYV2_ISA_3E3R3)
  768. {"s802",
  769. CSKY_ARCH_802,
  770. CSKY_ISA_S802,
  771. CSKY_FEATURES_DEF_t(0),
  772. CSKY_CPU_REVERISON_RESERVED()},
  773. {"s803",
  774. CSKY_ARCH_803,
  775. CSKY_ISA_S803,
  776. CSKY_FEATURES_DEF_t(0),
  777. CSKY_CPU_REVERISON_RESERVED()},
  778. #define CSKY_ISA_I805 (CSKY_ISA_S803)
  779. {"i805",
  780. CSKY_ARCH_805 | CSKY_ARCH_DSP,
  781. CSKY_ISA_I805 | CSKY_ISA_VDSP_2,
  782. CSKY_FEATURES_DEF_ft(CSKY_ISA_FLOAT_V1, 0),
  783. CSKY_CPU_REVERISON_RESERVED()},
  784. #define CSKYV2_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_DSP_1E2 | CSKY_ISA_DSPE60)
  785. #define CSKY_ISA_C807 (CSKY_ISA_E802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E7 | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE | CSKYV2_ISA_DSP)
  786. #define CSKY_ISA_FLOAT_C807 (CSKY_ISA_FLOAT_V1 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
  787. #define CSKY_ISA_FLOAT_C810 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E2)
  788. #define CSKY_ARCH_C810 (CSKY_ARCH_810 | CSKY_ARCH_FLOAT)
  789. #define CSKY_ISA_C810 (CSKY_ISA_C807 | CSKYV2_ISA_7E10 | CSKY_ISA_FLOAT_C810)
  790. #define CSKY_ARCH_C860 (CSKY_ARCH_860 | CSKY_ARCH_FLOAT)
  791. #define CSKY_ISA_C860 (CSKY_ISA_860 | CSKY_ISA_FLOAT_7E60)
  792. {"c807",
  793. CSKY_ARCH_807,
  794. CSKY_ISA_C807,
  795. CSKY_FEATURES_DEF_fv(CSKY_ISA_FLOAT_C807, CSKY_ISA_VDSP),
  796. CSKY_CPU_REVERISON_RESERVED()},
  797. {"c810",
  798. CSKY_ARCH_C810,
  799. CSKY_ISA_C810,
  800. CSKY_FEATURES_DEF_tv(0, CSKY_ISA_VDSP),
  801. CSKY_CPU_REVERISON_RESERVED()},
  802. {"c860",
  803. CSKY_ARCH_C860,
  804. CSKY_ISA_C860,
  805. CSKY_FEATURES_DEF_v(CSKY_ISA_VDSP_2),
  806. CSKY_CPU_REVERISON_RESERVED()},
  807. #define CSKY_ISA_R807 (CSKY_ISA_E802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E7 | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE | CSKYV2_ISA_DSP)
  808. #define CSKY_ISA_FLOAT_R807 (CSKY_ISA_FLOAT_V1 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
  809. {"r807",
  810. CSKY_ARCH_807,
  811. CSKY_ISA_R807,
  812. CSKY_FEATURES_DEF_f(CSKY_ISA_FLOAT_R807),
  813. CSKY_CPU_REVERISON_RESERVED()},
  814. /* Start of private CPUs. */
  815. /* End of private CPUs. */
  816. {NULL},
  817. };
  818. int md_short_jump_size = 2;
  819. int md_long_jump_size = 4;
  820. /* This array holds the chars that always start a comment. If the
  821. pre-processor is disabled, these aren't very useful. */
  822. const char comment_chars[] = "#";
  823. /* This array holds the chars that only start a comment at the beginning of
  824. a line. If the line seems to have the form '# 123 filename'
  825. .line and .file directives will appear in the pre-processed output. */
  826. /* Note that input_file.c hand checks for '#' at the beginning of the
  827. first line of the input file. This is because the compiler outputs
  828. #NO_APP at the beginning of its output. */
  829. /* Also note that comments like this one will always work. */
  830. const char line_comment_chars[] = "#";
  831. const char line_separator_chars[] = ";";
  832. /* Chars that can be used to separate mant
  833. from exp in floating point numbers. */
  834. const char EXP_CHARS[] = "eE";
  835. /* Chars that mean this number is a floating point constant.
  836. As in 0f12.456
  837. or 0d1.2345e12 */
  838. const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
  839. const char *md_shortopts = "";
  840. struct option md_longopts[] = {
  841. #define OPTION_MARCH (OPTION_MD_BASE + 0)
  842. {"march", required_argument, NULL, OPTION_MARCH},
  843. #define OPTION_MCPU (OPTION_MD_BASE + 1)
  844. {"mcpu", required_argument, NULL, OPTION_MCPU},
  845. #define OPTION_FLOAT_ABI (OPTION_MD_BASE + 2)
  846. {"mfloat-abi", required_argument, NULL, OPTION_FLOAT_ABI},
  847. /* Remaining options just set boolean flags. */
  848. {"EL", no_argument, &target_big_endian, 0},
  849. {"mlittle-endian", no_argument, &target_big_endian, 0},
  850. {"EB", no_argument, &target_big_endian, 1},
  851. {"mbig-endian", no_argument, &target_big_endian, 1},
  852. {"fpic", no_argument, &do_pic, 1},
  853. {"pic", no_argument, &do_pic, 1},
  854. {"mljump", no_argument, &do_long_jump, 1},
  855. {"mno-ljump", no_argument, &do_long_jump, 0},
  856. {"force2bsr", no_argument, &do_force2bsr, 1},
  857. {"mforce2bsr", no_argument, &do_force2bsr, 1},
  858. {"no-force2bsr", no_argument, &do_force2bsr, 0},
  859. {"mno-force2bsr", no_argument, &do_force2bsr, 0},
  860. {"jsri2bsr", no_argument, &do_jsri2bsr, 1},
  861. {"mjsri2bsr", no_argument, &do_jsri2bsr, 1},
  862. {"no-jsri2bsr", no_argument, &do_jsri2bsr, 0},
  863. {"mno-jsri2bsr", no_argument, &do_jsri2bsr, 0},
  864. {"mnolrw", no_argument, &do_nolrw, 1},
  865. {"mno-lrw", no_argument, &do_nolrw, 1},
  866. {"melrw", no_argument, &do_extend_lrw, 1},
  867. {"mno-elrw", no_argument, &do_extend_lrw, 0},
  868. {"mlaf", no_argument, &do_func_dump, 1},
  869. {"mliterals-after-func", no_argument, &do_func_dump, 1},
  870. {"mno-laf", no_argument, &do_func_dump, 0},
  871. {"mno-literals-after-func", no_argument, &do_func_dump, 0},
  872. {"mlabr", no_argument, &do_br_dump, 1},
  873. {"mliterals-after-br", no_argument, &do_br_dump, 1},
  874. {"mno-labr", no_argument, &do_br_dump, 0},
  875. {"mnoliterals-after-br", no_argument, &do_br_dump, 0},
  876. {"mistack", no_argument, &do_intr_stack, 1},
  877. {"mno-istack", no_argument, &do_intr_stack, 0},
  878. #ifdef INCLUDE_BRANCH_STUB
  879. {"mbranch-stub", no_argument, &do_use_branchstub, 1},
  880. {"mno-branch-stub", no_argument, &do_use_branchstub, 0},
  881. #endif
  882. {"mhard-float", no_argument, &do_opt_mhard_float, CSKY_ARCH_FLOAT},
  883. {"mmp", no_argument, &do_opt_mmp, CSKY_ARCH_MP},
  884. {"mcp", no_argument, &do_opt_mcp, CSKY_ARCH_CP},
  885. {"mcache", no_argument, &do_opt_mcache, CSKY_ARCH_CACHE},
  886. {"msecurity", no_argument, &do_opt_msecurity, CSKY_ARCH_MAC},
  887. {"mtrust", no_argument, &do_opt_mtrust, CSKY_ISA_TRUST},
  888. {"mdsp", no_argument, &do_opt_mdsp, CSKY_DSP_FLAG_V1},
  889. {"medsp", no_argument, &do_opt_medsp, CSKY_DSP_FLAG_V2},
  890. {"mvdsp", no_argument, &do_opt_mvdsp, CSKY_ISA_VDSP},
  891. };
  892. size_t md_longopts_size = sizeof (md_longopts);
  893. static struct csky_insn_info csky_insn;
  894. static htab_t csky_opcodes_hash;
  895. static htab_t csky_macros_hash;
  896. static struct csky_macro_info v1_macros_table[] =
  897. {
  898. {"idly", 1, CSKYV1_ISA_E1, csky_idly},
  899. {"rolc", 2, CSKYV1_ISA_E1, csky_rolc},
  900. {"rotlc", 2, CSKYV1_ISA_E1, csky_rolc},
  901. {"sxtrb0", 2, CSKYV1_ISA_E1, csky_sxtrb},
  902. {"sxtrb1", 2, CSKYV1_ISA_E1, csky_sxtrb},
  903. {"sxtrb2", 2, CSKYV1_ISA_E1, csky_sxtrb},
  904. {"movtf", 3, CSKYV1_ISA_E1, csky_movtf},
  905. {"addc64", 3, CSKYV1_ISA_E1, csky_addc64},
  906. {"subc64", 3, CSKYV1_ISA_E1, csky_subc64},
  907. {"or64", 3, CSKYV1_ISA_E1, csky_or64},
  908. {"xor64", 3, CSKYV1_ISA_E1, csky_xor64},
  909. {NULL,0,0,0}
  910. };
  911. static struct csky_macro_info v2_macros_table[] =
  912. {
  913. {"neg", 1, CSKYV2_ISA_E1, csky_neg},
  914. {"rsubi", 2, CSKYV2_ISA_1E2, csky_rsubi},
  915. {"incf", 1, CSKYV2_ISA_1E2, csky_arith},
  916. {"inct", 1, CSKYV2_ISA_1E2, csky_arith},
  917. {"decf", 1, CSKYV2_ISA_2E3, csky_arith},
  918. {"decgt", 1, CSKYV2_ISA_2E3, csky_arith},
  919. {"declt", 1, CSKYV2_ISA_2E3, csky_arith},
  920. {"decne", 1, CSKYV2_ISA_1E2, csky_decne},
  921. {"dect", 1, CSKYV2_ISA_1E2, csky_arith},
  922. {"lslc", 1, CSKYV2_ISA_1E2, csky_arith},
  923. {"lsrc", 1, CSKYV2_ISA_1E2, csky_arith},
  924. {"xsr", 1, CSKYV2_ISA_1E2, csky_arith},
  925. {NULL,0,0,0}
  926. };
  927. /* For option -mnolrw, replace lrw by movih & ori. */
  928. static struct csky_macro_info v2_lrw_macro_opcode =
  929. {"lrw", 2, CSKYV2_ISA_1E2, csky_lrw};
  930. /* This function is used to show errors or warnings. */
  931. static void
  932. csky_show_error (enum error_number err, int idx, void *arg1, void *arg2)
  933. {
  934. if (err == ERROR_NONE)
  935. return;
  936. switch (err)
  937. {
  938. case ERROR_REG_LIST:
  939. case ERROR_OPCODE_PSRBIT:
  940. case ERROR_OPCODE_ILLEGAL:
  941. case ERROR_JMPIX_OVER_RANGE:
  942. case ERROR_MISSING_COMMA:
  943. case ERROR_MISSING_LBRACKET:
  944. case ERROR_MISSING_RBRACKET:
  945. case ERROR_MISSING_LSQUARE_BRACKETS:
  946. case ERROR_MISSING_RSQUARE_BRACKETS:
  947. case ERROR_MISSING_LANGLE_BRACKETS:
  948. case ERROR_MISSING_RANGLE_BRACKETS:
  949. /* Add NULL to fix warnings. */
  950. as_bad (_(err_formats[err].fmt), NULL);
  951. break;
  952. case ERROR_CREG_ILLEGAL:
  953. case ERROR_GREG_ILLEGAL:
  954. case ERROR_IMM_ILLEGAL:
  955. case ERROR_IMM_OVERFLOW:
  956. case ERROR_EXP_CREG:
  957. case ERROR_EXP_GREG:
  958. case ERROR_EXP_CONSTANT:
  959. case ERROR_EXP_EVEN_FREG:
  960. case ERROR_MISSING_OPERAND:
  961. case ERROR_CPREG_ILLEGAL:
  962. as_bad (_(err_formats[err].fmt), idx);
  963. break;
  964. case ERROR_OPERANDS_NUMBER:
  965. case ERROR_IMM_POWER:
  966. as_bad (_(err_formats[err].fmt), error_state.arg_int);
  967. break;
  968. case ERROR_OFFSET_UNALIGNED:
  969. as_bad (_(err_formats[err].fmt), idx, error_state.arg_int);
  970. break;
  971. case ERROR_RELOC_ILLEGAL:
  972. case ERROR_BAD_END:
  973. case ERROR_OPERANDS_ILLEGAL:
  974. as_bad (_(err_formats[err].fmt), (char *)arg1);
  975. break;
  976. case ERROR_REG_OVER_RANGE:
  977. case ERROR_FREG_OVER_RANGE:
  978. case ERROR_VREG_OVER_RANGE:
  979. as_bad (_(err_formats[err].fmt), idx, error_state.arg_int);
  980. break;
  981. case ERROR_802J_REG_OVER_RANGE:
  982. case ERROR_REG_FORMAT:
  983. as_bad (_(err_formats[err].fmt), idx, (char *)arg1);
  984. break;
  985. case ERROR_UNDEFINE:
  986. /* Add NULL to fix warnings. */
  987. as_bad ((char *)arg1, NULL);
  988. break;
  989. case WARNING_IDLY:
  990. as_warn (_(err_formats[err].fmt), (long)arg1);
  991. break;
  992. case WARNING_OPTIONS:
  993. as_warn (_(err_formats[err].fmt), (char *)arg1, (char *)arg2);
  994. break;
  995. default:
  996. break;
  997. }
  998. }
  999. /* Handle errors in branch relaxation. */
  1000. static void
  1001. csky_branch_report_error (const char* file, unsigned int line,
  1002. symbolS* sym, offsetT val)
  1003. {
  1004. as_bad_where (file ? file : _("unknown"),
  1005. line,
  1006. _("pcrel offset for branch to %s too far (0x%lx)"),
  1007. sym ? S_GET_NAME (sym) : _("<unknown>"),
  1008. (long) val);
  1009. }
  1010. /* Set appropriate flags for the cpu matching STR. */
  1011. static void
  1012. parse_cpu (const char *str)
  1013. {
  1014. int i = 0;
  1015. for (; csky_cpus[i].name != NULL; i++)
  1016. if (strncasecmp (str, csky_cpus[i].name, strlen (csky_cpus[i].name)) == 0)
  1017. {
  1018. csky_insn.cpu = &csky_cpus[i];
  1019. mach_flag |= csky_cpus[i].arch_flag;
  1020. isa_flag = csky_cpus[i].isa_flag;
  1021. const char *s = str + strlen (csky_cpus[i].name);
  1022. while (*s)
  1023. {
  1024. const struct csky_cpu_feature *feature = csky_cpus[i].features;
  1025. const struct csky_cpu_version *version = csky_cpus[i].ver;
  1026. char *next;
  1027. if (*s == 'r')
  1028. {
  1029. s++;
  1030. while (version->r)
  1031. {
  1032. if (version->r == strtol (s, &next, 10))
  1033. break;
  1034. version++;
  1035. }
  1036. if (version->r)
  1037. {
  1038. isa_flag |= version->isa_flag;
  1039. s = next;
  1040. }
  1041. else
  1042. goto unknown_cpu;
  1043. isa_flag = isa_flag & ~CSKYV2_ISA_DSP;
  1044. isa_flag |= CSKY_ISA_EDSP;
  1045. continue;
  1046. }
  1047. /* Parse csky features. */
  1048. while (feature->unique)
  1049. {
  1050. if (feature->unique == *s)
  1051. break;
  1052. feature++;
  1053. }
  1054. if (feature->unique)
  1055. {
  1056. isa_flag |= feature->isa_flag;
  1057. mach_flag |= feature->arch_flag;
  1058. }
  1059. else
  1060. goto unknown_cpu;
  1061. s++;
  1062. }
  1063. return;
  1064. }
  1065. unknown_cpu:
  1066. as_bad (_("unknown cpu `%s'"), str);
  1067. }
  1068. /* Set appropriate flags for the arch matching STR. */
  1069. static void
  1070. parse_arch (const char *str)
  1071. {
  1072. int i = 0;
  1073. for (; csky_cpus[i].name != NULL; i++)
  1074. if (strcasecmp (str, csky_cpus[i].name) == 0)
  1075. {
  1076. csky_insn.cpu = &csky_cpus[i];
  1077. arch_flag |= csky_cpus[i].arch_flag;
  1078. isa_flag |= csky_cpus[i].isa_flag;
  1079. return;
  1080. }
  1081. as_bad (_("unknown architecture `%s'"), str);
  1082. }
  1083. struct csky_option_value_table
  1084. {
  1085. const char *name;
  1086. long value;
  1087. };
  1088. static const struct csky_option_value_table csky_float_abis[] =
  1089. {
  1090. {"hard", VAL_CSKY_FPU_ABI_HARD},
  1091. {"softfp", VAL_CSKY_FPU_ABI_SOFTFP},
  1092. {"soft", VAL_CSKY_FPU_ABI_SOFT},
  1093. {NULL, 0}
  1094. };
  1095. static bool
  1096. parse_float_abi (const char *str)
  1097. {
  1098. const struct csky_option_value_table * opt;
  1099. for (opt = csky_float_abis; opt->name != NULL; opt++)
  1100. if (strcasecmp (opt->name, str) == 0)
  1101. {
  1102. float_abi = opt->value;
  1103. return true;
  1104. }
  1105. as_bad (_("unknown floating point abi `%s'\n"), str);
  1106. return false;
  1107. }
  1108. #ifdef OBJ_ELF
  1109. /* Implement the TARGET_FORMAT macro. */
  1110. const char *
  1111. elf32_csky_target_format (void)
  1112. {
  1113. return (target_big_endian
  1114. ? "elf32-csky-big"
  1115. : "elf32-csky-little");
  1116. }
  1117. #endif
  1118. /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
  1119. for use in the a.out file, and stores them in the array pointed to by buf.
  1120. This knows about the endian-ness of the target machine and does
  1121. THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
  1122. 2 (short) and 4 (long) Floating numbers are put out as a series of
  1123. LITTLENUMS (shorts, here at least). */
  1124. void
  1125. md_number_to_chars (char * buf, valueT val, int n)
  1126. {
  1127. if (target_big_endian)
  1128. number_to_chars_bigendian (buf, val, n);
  1129. else
  1130. number_to_chars_littleendian (buf, val, n);
  1131. }
  1132. /* Get a log2(val). */
  1133. static int
  1134. csky_log_2 (unsigned int val)
  1135. {
  1136. int log = -1;
  1137. if ((val & (val - 1)) == 0)
  1138. for (; val; val >>= 1)
  1139. log ++;
  1140. else
  1141. csky_show_error (ERROR_IMM_POWER, 0, (void *)(long)val, NULL);
  1142. return log;
  1143. }
  1144. /* Output one instruction to the buffer at PTR. */
  1145. static void
  1146. csky_write_insn (char *ptr, valueT use, int nbytes)
  1147. {
  1148. if (nbytes == 2)
  1149. md_number_to_chars (ptr, use, nbytes);
  1150. else /* 32-bit instruction. */
  1151. {
  1152. /* Significant figures are in low bits. */
  1153. md_number_to_chars (ptr, use >> 16, 2);
  1154. md_number_to_chars (ptr + 2, use & 0xFFFF, 2);
  1155. }
  1156. }
  1157. /* Read an NBYTES instruction from the buffer at PTR. NBYTES should
  1158. be either 2 or 4. This function is used in branch relaxation. */
  1159. static valueT
  1160. csky_read_insn (char *ptr, int nbytes)
  1161. {
  1162. unsigned char *uptr = (unsigned char *)ptr;
  1163. valueT v = 0;
  1164. int lo, hi; /* hi/lo byte index in binary stream. */
  1165. if (target_big_endian)
  1166. {
  1167. hi = 0;
  1168. lo = 1;
  1169. }
  1170. else
  1171. {
  1172. hi = 1;
  1173. lo = 0;
  1174. }
  1175. v = uptr[lo] | (uptr[hi] << 8);
  1176. if (nbytes == 4)
  1177. {
  1178. v <<= 16;
  1179. v |= uptr[lo + 2] | (uptr[hi + 2] << 8);
  1180. }
  1181. return v;
  1182. }
  1183. /* Construct a label name into S from the 3-character prefix P and
  1184. number N formatted as a 4-digit hex number. */
  1185. static void
  1186. make_internal_label (char *s, const char *p, int n)
  1187. {
  1188. static const char hex[] = "0123456789ABCDEF";
  1189. s[0] = p[0];
  1190. s[1] = p[1];
  1191. s[2] = p[2];
  1192. s[3] = hex[(n >> 12) & 0xF];
  1193. s[4] = hex[(n >> 8) & 0xF];
  1194. s[5] = hex[(n >> 4) & 0xF];
  1195. s[6] = hex[(n) & 0xF];
  1196. s[7] = 0;
  1197. }
  1198. /* md_operand is a no-op on C-SKY; we do everything elsewhere. */
  1199. void
  1200. md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
  1201. {
  1202. return;
  1203. }
  1204. /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
  1205. Otherwise we have no need to default values of symbols. */
  1206. symbolS *
  1207. md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
  1208. {
  1209. #ifdef OBJ_ELF
  1210. /* TODO: */
  1211. #endif
  1212. return NULL;
  1213. }
  1214. /* Use IEEE format for floating-point constants. */
  1215. const char *
  1216. md_atof (int type, char *litP, int *sizeP)
  1217. {
  1218. return ieee_md_atof (type, litP, sizeP, target_big_endian);
  1219. }
  1220. /* Print option help to FP. */
  1221. void
  1222. md_show_usage (FILE *fp)
  1223. {
  1224. int i, n;
  1225. const int margin = 48;
  1226. fprintf (fp, _("C-SKY assembler options:\n"));
  1227. fprintf (fp, _("\
  1228. -march=ARCH select architecture ARCH:"));
  1229. for (i = 0, n = margin; csky_archs[i].name != NULL; i++)
  1230. {
  1231. int l = strlen (csky_archs[i].name);
  1232. if (n + l >= margin)
  1233. {
  1234. fprintf (fp, "\n\t\t\t\t");
  1235. n = l;
  1236. }
  1237. else
  1238. {
  1239. fprintf (fp, " ");
  1240. n += l + 1;
  1241. }
  1242. fprintf (fp, "%s", csky_archs[i].name);
  1243. }
  1244. fprintf (fp, "\n");
  1245. fprintf (fp, _("\
  1246. -mcpu=CPU select processor CPU:"));
  1247. const struct csky_cpu_feature *feature = NULL;
  1248. const struct csky_cpu_version *version = NULL;
  1249. for (i = 0; csky_cpus[i].name != NULL; i++)
  1250. {
  1251. fprintf (fp, "\t\t\t\t%s", csky_cpus[i].name);
  1252. feature = csky_cpus[i].features;
  1253. version = csky_cpus[i].ver;
  1254. while (feature->unique)
  1255. {
  1256. if ((feature + 1)->unique)
  1257. fprintf (fp, "[%c]", feature->unique);
  1258. feature++;
  1259. }
  1260. while (version->r)
  1261. {
  1262. if (csky_cpus[i].name[0] == 'c'
  1263. && csky_cpus[i].name[1] == 'k')
  1264. fprintf (fp, "[r%d]", version->r);
  1265. else
  1266. fprintf (fp, "[-r%dp%d]", version->r, version->p);
  1267. version++;
  1268. }
  1269. }
  1270. fprintf (fp, "\n");
  1271. fprintf (fp, _("\
  1272. -mfloat-abi=ABI select float ABI:"));
  1273. for (i = 0, n = margin; csky_float_abis[i].name != NULL; i++)
  1274. {
  1275. int l = strlen (csky_float_abis[i].name);
  1276. if (n + l >= margin)
  1277. {
  1278. fprintf (fp, "\n\t\t\t\t");
  1279. n = l;
  1280. }
  1281. else
  1282. {
  1283. fprintf (fp, " ");
  1284. n += l + 1;
  1285. }
  1286. fprintf (fp, "%s", csky_float_abis[i].name);
  1287. }
  1288. fprintf (fp, "\n");
  1289. fprintf (fp, _("\
  1290. -EL -mlittle-endian generate little-endian output\n"));
  1291. fprintf (fp, _("\
  1292. -EB -mbig-endian generate big-endian output\n"));
  1293. fprintf (fp, _("\
  1294. -fpic -pic generate position-independent code\n"));
  1295. fprintf (fp, _("\
  1296. -mljump transform jbf, jbt, jbr to jmpi (CK800 only)\n"));
  1297. fprintf (fp, _("\
  1298. -mno-ljump\n"));
  1299. #ifdef INCLUDE_BRANCH_STUB
  1300. fprintf (fp, _("\
  1301. -mbranch-stub enable branch stubs for PC-relative calls\n"));
  1302. fprintf (fp, _("\
  1303. -mno-branch-stub\n"));
  1304. #endif
  1305. fprintf (fp, _("\
  1306. -force2bsr -mforce2bsr transform jbsr to bsr\n"));
  1307. fprintf (fp, _("\
  1308. -no-force2bsr -mno-force2bsr\n"));
  1309. fprintf (fp, _("\
  1310. -jsri2bsr -mjsri2bsr transform jsri to bsr\n"));
  1311. fprintf (fp, _("\
  1312. -no-jsri2bsr -mno-jsri2bsr\n"));
  1313. fprintf (fp, _("\
  1314. -mnolrw -mno-lrw implement lrw as movih + ori\n"));
  1315. fprintf (fp, _("\
  1316. -melrw enable extended lrw (CK800 only)\n"));
  1317. fprintf (fp, _("\
  1318. -mno-elrw\n"));
  1319. fprintf (fp, _("\
  1320. -mlaf -mliterals-after-func emit literals after each function\n"));
  1321. fprintf (fp, _("\
  1322. -mno-laf -mno-literals-after-func\n"));
  1323. fprintf (fp, _("\
  1324. -mlabr -mliterals-after-br emit literals after branch instructions\n"));
  1325. fprintf (fp, _("\
  1326. -mno-labr -mnoliterals-after-br\n"));
  1327. fprintf (fp, _("\
  1328. -mistack enable interrupt stack instructions\n"));
  1329. fprintf (fp, _("\
  1330. -mno-istack\n"));
  1331. fprintf (fp, _("\
  1332. -mhard-float enable hard float instructions\n"));
  1333. fprintf (fp, _("\
  1334. -mmp enable multiprocessor instructions\n"));
  1335. fprintf (fp, _("\
  1336. -mcp enable coprocessor instructions\n"));
  1337. fprintf (fp, _("\
  1338. -mcache enable cache prefetch instruction\n"));
  1339. fprintf (fp, _("\
  1340. -msecurity enable security instructions\n"));
  1341. fprintf (fp, _("\
  1342. -mtrust enable trust instructions\n"));
  1343. fprintf (fp, _("\
  1344. -mdsp enable DSP instructions\n"));
  1345. fprintf (fp, _("\
  1346. -medsp enable enhanced DSP instructions\n"));
  1347. fprintf (fp, _("\
  1348. -mvdsp enable vector DSP instructions\n"));
  1349. }
  1350. static void set_csky_attribute (void)
  1351. {
  1352. if (mach_flag & CSKY_ARCH_DSP)
  1353. {
  1354. if (dsp_flag & CSKY_DSP_FLAG_V2)
  1355. {
  1356. /* Set DSPV2. */
  1357. bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
  1358. Tag_CSKY_DSP_VERSION,
  1359. VAL_CSKY_DSP_VERSION_2);
  1360. }
  1361. else if (isa_flag & CSKY_ISA_DSP)
  1362. {
  1363. /* Set DSP extension. */
  1364. bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
  1365. Tag_CSKY_DSP_VERSION,
  1366. VAL_CSKY_DSP_VERSION_EXTENSION);
  1367. }
  1368. /* Set VDSP attribute. */
  1369. if (isa_flag & CSKY_ISA_VDSP)
  1370. bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
  1371. Tag_CSKY_VDSP_VERSION,
  1372. VAL_CSKY_VDSP_VERSION_1);
  1373. else if (isa_flag & CSKY_ISA_VDSP_2)
  1374. bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
  1375. Tag_CSKY_VDSP_VERSION,
  1376. VAL_CSKY_VDSP_VERSION_2);
  1377. }
  1378. if (mach_flag & CSKY_ARCH_FLOAT)
  1379. {
  1380. unsigned int val = VAL_CSKY_FPU_HARDFP_SINGLE;
  1381. if (IS_CSKY_ARCH_V1 (mach_flag)) {
  1382. bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
  1383. Tag_CSKY_FPU_VERSION,
  1384. VAL_CSKY_FPU_VERSION_1);
  1385. }
  1386. else
  1387. {
  1388. if (isa_flag & CSKY_ISA_FLOAT_3E4)
  1389. {
  1390. bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
  1391. Tag_CSKY_FPU_VERSION,
  1392. VAL_CSKY_FPU_VERSION_2);
  1393. val |= VAL_CSKY_FPU_HARDFP_DOUBLE;
  1394. }
  1395. else
  1396. {
  1397. bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
  1398. Tag_CSKY_FPU_VERSION,
  1399. VAL_CSKY_FPU_VERSION_2);
  1400. }
  1401. bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
  1402. Tag_CSKY_FPU_HARDFP,
  1403. val);
  1404. bfd_elf_add_obj_attr_string (stdoutput, OBJ_ATTR_PROC,
  1405. Tag_CSKY_FPU_NUMBER_MODULE,
  1406. "IEEE 754");
  1407. bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
  1408. Tag_CSKY_FPU_ABI,
  1409. float_abi);
  1410. }
  1411. }
  1412. bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
  1413. Tag_CSKY_ISA_FLAGS, isa_flag);
  1414. bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
  1415. Tag_CSKY_ISA_EXT_FLAGS, (isa_flag >> 32));
  1416. }
  1417. /* Target-specific initialization and option handling. */
  1418. void
  1419. md_begin (void)
  1420. {
  1421. unsigned int bfd_mach_flag = 0;
  1422. struct csky_opcode const *opcode;
  1423. struct csky_macro_info const *macro;
  1424. struct csky_arch_info const *p_arch;
  1425. struct csky_cpu_info const *p_cpu;
  1426. other_flag = (do_opt_mmp | do_opt_mcp | do_opt_mcache
  1427. | do_opt_msecurity | do_opt_mhard_float);
  1428. dsp_flag |= do_opt_mdsp | do_opt_medsp;
  1429. isa_flag |= do_opt_mtrust | do_opt_mvdsp;
  1430. if (dsp_flag)
  1431. other_flag |= CSKY_ARCH_DSP;
  1432. if (mach_flag != 0)
  1433. {
  1434. if (((mach_flag & CSKY_ARCH_MASK)
  1435. != (arch_flag & CSKY_ARCH_MASK))
  1436. && arch_flag != 0)
  1437. as_warn ("-mcpu conflict with -march option, actually use -mcpu");
  1438. }
  1439. else if (arch_flag != 0)
  1440. mach_flag |= arch_flag | other_flag;
  1441. else
  1442. {
  1443. #ifdef TARGET_WITH_CPU
  1444. parse_cpu (TARGET_WITH_CPU);
  1445. #else
  1446. #if _CSKY_ABI==1
  1447. parse_cpu ("ck610");
  1448. #else
  1449. parse_cpu ("ck810");
  1450. #endif
  1451. mach_flag |= other_flag;
  1452. #endif
  1453. }
  1454. if (IS_CSKY_ARCH_610 (mach_flag) || IS_CSKY_ARCH_510 (mach_flag))
  1455. {
  1456. if ((mach_flag & CSKY_ARCH_MP) && (mach_flag & CSKY_ARCH_MAC))
  1457. as_fatal ("520/620 conflicts with -mmp option");
  1458. else if ((mach_flag & CSKY_ARCH_MP) && (mach_flag & CSKY_ARCH_DSP))
  1459. as_fatal ("510e/610e conflicts with -mmp option");
  1460. else if ((mach_flag & CSKY_ARCH_DSP) && (mach_flag & CSKY_ARCH_MAC))
  1461. as_fatal ("520/620 conflicts with 510e/610e or -mdsp option");
  1462. }
  1463. if (IS_CSKY_ARCH_510 (mach_flag) && (mach_flag & CSKY_ARCH_FLOAT))
  1464. {
  1465. mach_flag = (mach_flag & (~CSKY_ARCH_MASK));
  1466. mach_flag |= CSKY_ARCH_610;
  1467. }
  1468. /* Find bfd_mach_flag, it will set to bfd backend data. */
  1469. for (p_arch = csky_archs; p_arch->arch_flag != 0; p_arch++)
  1470. if ((mach_flag & CSKY_ARCH_MASK) == (p_arch->arch_flag & CSKY_ARCH_MASK))
  1471. {
  1472. bfd_elf_add_obj_attr_string (stdoutput, OBJ_ATTR_PROC,
  1473. Tag_CSKY_ARCH_NAME, p_arch->name);
  1474. bfd_mach_flag = p_arch->bfd_mach_flag;
  1475. break;
  1476. }
  1477. /* Find isa_flag. */
  1478. for (p_cpu = csky_cpus; p_cpu->arch_flag != 0; p_cpu++)
  1479. if ((mach_flag & CPU_ARCH_MASK) == p_cpu->arch_flag)
  1480. {
  1481. bfd_elf_add_obj_attr_string (stdoutput, OBJ_ATTR_PROC,
  1482. Tag_CSKY_CPU_NAME, p_cpu->name);
  1483. isa_flag |= p_cpu->isa_flag;
  1484. break;
  1485. }
  1486. /* Check if -mdsp and -medsp conflict. If cpu is ck803, we will
  1487. use enhanced dsp instruction. Otherwise, we will use normal dsp. */
  1488. if (dsp_flag)
  1489. {
  1490. if (IS_CSKY_ARCH_803 (mach_flag))
  1491. {
  1492. if ((dsp_flag & CSKY_DSP_FLAG_V1))
  1493. {
  1494. if (isa_flag & CSKY_ISA_DSP_ENHANCE)
  1495. {
  1496. /* Option -mdsp conflicts with -mcpu=ck803ern,
  1497. CPU already indicates the dsp version. */
  1498. as_warn ("Option -mdsp conflicts with -mcpu=ck803ern which "
  1499. "has indicated DSP version, ignoring -mdsp.");
  1500. isa_flag &= ~(CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
  1501. isa_flag |= CSKY_ISA_DSP_ENHANCE;
  1502. }
  1503. else
  1504. {
  1505. isa_flag |= (CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
  1506. isa_flag &= ~CSKY_ISA_DSP_ENHANCE;
  1507. }
  1508. }
  1509. if ((dsp_flag & CSKY_DSP_FLAG_V2))
  1510. {
  1511. isa_flag &= ~(CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
  1512. isa_flag |= CSKY_ISA_DSP_ENHANCE;
  1513. }
  1514. if ((dsp_flag & CSKY_DSP_FLAG_V1)
  1515. && (dsp_flag & CSKY_DSP_FLAG_V2))
  1516. {
  1517. /* In 803, dspv1 is conflict with dspv2. We keep dspv2. */
  1518. as_warn ("option -mdsp conflicts with -medsp, only enabling -medsp");
  1519. dsp_flag &= ~CSKY_DSP_FLAG_V1;
  1520. isa_flag &= ~(CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
  1521. isa_flag |= CSKY_ISA_DSP_ENHANCE;
  1522. }
  1523. }
  1524. else
  1525. {
  1526. if (dsp_flag & CSKY_DSP_FLAG_V2)
  1527. {
  1528. dsp_flag &= ~CSKY_DSP_FLAG_V2;
  1529. isa_flag &= ~CSKY_ISA_DSP_ENHANCE;
  1530. as_warn ("-medsp option is only supported by ck803s, ignoring -medsp");
  1531. }
  1532. }
  1533. ;
  1534. }
  1535. if (do_use_branchstub == -1)
  1536. do_use_branchstub = !IS_CSKY_ARCH_V1 (mach_flag);
  1537. else if (do_use_branchstub == 1)
  1538. {
  1539. if (IS_CSKY_ARCH_V1 (mach_flag))
  1540. {
  1541. as_warn (_("C-SKY ABI v1 (ck510/ck610) does not support -mbranch-stub"));
  1542. do_use_branchstub = 0;
  1543. }
  1544. else if (do_force2bsr == 0)
  1545. {
  1546. as_warn (_("-mno-force2bsr is ignored with -mbranch-stub"));
  1547. do_force2bsr = 1;
  1548. }
  1549. }
  1550. if (IS_CSKY_ARCH_801 (mach_flag) || IS_CSKY_ARCH_802 (mach_flag))
  1551. {
  1552. if (!do_force2bsr)
  1553. as_warn (_("-mno-force2bsr is ignored for ck801/ck802"));
  1554. do_force2bsr = 1;
  1555. }
  1556. else if (do_force2bsr == -1)
  1557. do_force2bsr = do_use_branchstub;
  1558. if (do_pff == -1)
  1559. {
  1560. if (IS_CSKY_ARCH_V1 (mach_flag))
  1561. do_pff = 1;
  1562. else
  1563. do_pff = 0;
  1564. }
  1565. if (do_extend_lrw == -1)
  1566. {
  1567. if ((mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_801
  1568. || (mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_802
  1569. || (mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_803
  1570. || (mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_860)
  1571. do_extend_lrw = 1;
  1572. else
  1573. do_extend_lrw = 0;
  1574. }
  1575. if (IS_CSKY_ARCH_801 (mach_flag) || IS_CSKY_ARCH_802 (mach_flag))
  1576. {
  1577. if (do_long_jump > 0)
  1578. as_warn (_("-mljump is ignored for ck801/ck802"));
  1579. do_long_jump = 0;
  1580. }
  1581. else if (do_long_jump == -1)
  1582. do_long_jump = 1;
  1583. if (do_intr_stack == -1)
  1584. {
  1585. /* control interrupt stack module, 801&802&803 default on
  1586. 807&810, default off. */
  1587. if (IS_CSKY_ARCH_807 (mach_flag) || IS_CSKY_ARCH_810 (mach_flag))
  1588. do_intr_stack = 0;
  1589. else
  1590. do_intr_stack = 1;
  1591. }
  1592. /* Add isa_flag(SIMP/CACHE/APS). */
  1593. isa_flag |= (mach_flag & CSKY_ARCH_MAC) ? CSKY_ISA_MAC : 0;
  1594. isa_flag |= (mach_flag & CSKY_ARCH_MP) ? CSKY_ISA_MP : 0;
  1595. isa_flag |= (mach_flag & CSKY_ARCH_CP) ? CSKY_ISA_CP : 0;
  1596. /* Set abi flag and get table address. */
  1597. if (IS_CSKY_ARCH_V1 (mach_flag))
  1598. {
  1599. mach_flag = mach_flag | CSKY_ABI_V1;
  1600. opcode = csky_v1_opcodes;
  1601. macro = v1_macros_table;
  1602. SPANPANIC = v1_SPANPANIC;
  1603. SPANCLOSE = v1_SPANCLOSE;
  1604. SPANEXIT = v1_SPANEXIT;
  1605. md_relax_table = csky_relax_table;
  1606. }
  1607. else
  1608. {
  1609. mach_flag = mach_flag | CSKY_ABI_V2;
  1610. opcode = csky_v2_opcodes;
  1611. macro = v2_macros_table;
  1612. SPANPANIC = v2_SPANPANIC;
  1613. if (do_extend_lrw)
  1614. {
  1615. SPANCLOSE = v2_SPANCLOSE_ELRW;
  1616. SPANEXIT = v2_SPANEXIT_ELRW;
  1617. }
  1618. else
  1619. {
  1620. SPANCLOSE = v2_SPANCLOSE;
  1621. SPANEXIT = v2_SPANEXIT;
  1622. }
  1623. md_relax_table = csky_relax_table;
  1624. }
  1625. /* Establish hash table for opcodes and macros. */
  1626. csky_macros_hash = str_htab_create ();
  1627. csky_opcodes_hash = str_htab_create ();
  1628. for ( ; opcode->mnemonic != NULL; opcode++)
  1629. if ((isa_flag & (opcode->isa_flag16 | opcode->isa_flag32)) != 0)
  1630. str_hash_insert (csky_opcodes_hash, opcode->mnemonic, opcode, 0);
  1631. for ( ; macro->name != NULL; macro++)
  1632. if ((isa_flag & macro->isa_flag) != 0)
  1633. str_hash_insert (csky_macros_hash, macro->name, macro, 0);
  1634. if (do_nolrw && (isa_flag & CSKYV2_ISA_1E2) != 0)
  1635. str_hash_insert (csky_macros_hash,
  1636. v2_lrw_macro_opcode.name, &v2_lrw_macro_opcode, 0);
  1637. /* Set e_flag to ELF Head. */
  1638. bfd_set_private_flags (stdoutput, mach_flag | CSKY_VERSION_V1);
  1639. /* Set bfd_mach to bfd backend data. */
  1640. bfd_set_arch_mach (stdoutput, bfd_arch_csky, bfd_mach_flag);
  1641. set_csky_attribute ();
  1642. }
  1643. /* The C-SKY assembler emits mapping symbols $t and $d to mark the
  1644. beginning of a sequence of instructions and data (such as a constant pool),
  1645. respectively. This is similar to what ARM does. */
  1646. static void
  1647. make_mapping_symbol (map_state state, valueT value, fragS *frag)
  1648. {
  1649. symbolS * symbolP;
  1650. const char * symname;
  1651. int type;
  1652. switch (state)
  1653. {
  1654. case MAP_DATA:
  1655. symname = "$d";
  1656. type = BSF_NO_FLAGS;
  1657. break;
  1658. case MAP_TEXT:
  1659. symname = "$t";
  1660. type = BSF_NO_FLAGS;
  1661. break;
  1662. default:
  1663. abort ();
  1664. }
  1665. symbolP = symbol_new (symname, now_seg, frag, value);
  1666. symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
  1667. }
  1668. /* We need to keep track of whether we are emitting code or data; this
  1669. function switches state and emits a mapping symbol if necessary. */
  1670. static void
  1671. mapping_state (map_state state)
  1672. {
  1673. map_state current_state
  1674. = seg_info (now_seg)->tc_segment_info_data.current_state;
  1675. if (current_state == state)
  1676. return;
  1677. else if (current_state == MAP_UNDEFINED && state == MAP_DATA)
  1678. return;
  1679. else if (current_state == MAP_UNDEFINED && state == MAP_TEXT)
  1680. {
  1681. struct frag * const frag_first = seg_info (now_seg)->frchainP->frch_root;
  1682. if (frag_now != frag_first || frag_now_fix () > 0)
  1683. make_mapping_symbol (MAP_DATA, (valueT) 0, frag_first);
  1684. }
  1685. seg_info (now_seg)->tc_segment_info_data.current_state = state;
  1686. make_mapping_symbol (state, (valueT) frag_now_fix (), frag_now);
  1687. }
  1688. /* Dump the literal pool. */
  1689. static void
  1690. dump_literals (int isforce)
  1691. {
  1692. #define CSKYV1_BR_INSN 0xF000
  1693. #define CSKYV2_BR_INSN 0x0400
  1694. unsigned int i;
  1695. struct literal * p;
  1696. symbolS * brarsym = NULL;
  1697. /* V1 nop encoding: 0x1200 : mov r0, r0. */
  1698. static char v1_nop_insn_big[2] = {0x12, 0x00};
  1699. static char v1_nop_insn_little[2] = {0x00, 0x12};
  1700. if (poolsize == 0)
  1701. return;
  1702. /* Must we branch around the literal table? */
  1703. if (isforce)
  1704. {
  1705. char brarname[8];
  1706. make_internal_label (brarname, POOL_END_LABEL, poolnumber);
  1707. brarsym = symbol_make (brarname);
  1708. symbol_table_insert (brarsym);
  1709. mapping_state (MAP_TEXT);
  1710. if (IS_CSKY_ARCH_V1 (mach_flag))
  1711. {
  1712. csky_insn.output
  1713. = frag_var (rs_machine_dependent,
  1714. csky_relax_table[C (UNCD_JUMP_S, DISP32)].rlx_length,
  1715. csky_relax_table[C (UNCD_JUMP_S, DISP12)].rlx_length,
  1716. C (UNCD_JUMP_S, 0), brarsym, 0, 0);
  1717. md_number_to_chars (csky_insn.output, CSKYV1_BR_INSN, 2);
  1718. }
  1719. else
  1720. {
  1721. csky_insn.output
  1722. = frag_var (rs_machine_dependent,
  1723. UNCD_DISP16_LEN,
  1724. UNCD_DISP10_LEN,
  1725. UNCD_DISP10,
  1726. brarsym, 0, 0);
  1727. md_number_to_chars (csky_insn.output, CSKYV2_BR_INSN, 2);
  1728. }
  1729. }
  1730. /* Make sure that the section is sufficiently aligned and that
  1731. the literal table is aligned within it. */
  1732. if (do_pff)
  1733. {
  1734. valueT br_self;
  1735. csky_insn.output = frag_more (2);
  1736. /* .Lxx: br .Lxx */
  1737. if (IS_CSKY_V1 (mach_flag))
  1738. br_self = CSKYV1_BR_INSN | 0x7ff;
  1739. else
  1740. br_self = CSKYV2_BR_INSN;
  1741. md_number_to_chars (csky_insn.output, br_self, 2);
  1742. if (!isforce)
  1743. {
  1744. csky_insn.output = frag_more (2);
  1745. /* .Lxx: br .Lxx */
  1746. md_number_to_chars (csky_insn.output, br_self, 2);
  1747. }
  1748. }
  1749. mapping_state (MAP_DATA);
  1750. record_alignment (now_seg, 2);
  1751. if (IS_CSKY_ARCH_V1 (mach_flag))
  1752. frag_align_pattern (2,
  1753. (target_big_endian
  1754. ? v1_nop_insn_big : v1_nop_insn_little),
  1755. 2, 0);
  1756. else
  1757. frag_align (2, 0, 3);
  1758. colon (S_GET_NAME (poolsym));
  1759. for (i = 0, p = litpool; i < poolsize; p++)
  1760. {
  1761. insn_reloc = p->r_type;
  1762. if (insn_reloc == BFD_RELOC_CKCORE_TLS_IE32
  1763. || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
  1764. || insn_reloc == BFD_RELOC_CKCORE_TLS_GD32)
  1765. literal_insn_offset = p;
  1766. if (p->isdouble)
  1767. {
  1768. if (target_big_endian)
  1769. {
  1770. p->e.X_add_number = p->dbnum >> 32;
  1771. emit_expr (& p->e, 4);
  1772. p->e.X_add_number = p->dbnum & 0xffffffff;
  1773. emit_expr (& p->e, 4);
  1774. }
  1775. else
  1776. {
  1777. p->e.X_add_number = p->dbnum & 0xffffffff;
  1778. emit_expr (& p->e, 4);
  1779. p->e.X_add_number = p->dbnum >> 32;
  1780. emit_expr (& p->e, 4);
  1781. }
  1782. }
  1783. else if (p->e.X_op == O_big)
  1784. {
  1785. memcpy (generic_bignum, p->bignum, sizeof (p->bignum));
  1786. emit_expr (& p->e, p->e.X_add_number * CHARS_PER_LITTLENUM);
  1787. }
  1788. else
  1789. emit_expr (& p->e, 4);
  1790. if (p->e.X_op == O_big)
  1791. i += (p->e.X_add_number & 1) +
  1792. ((p->e.X_add_number * CHARS_PER_LITTLENUM) >> 2);
  1793. else
  1794. i += (p->isdouble ? 2 : 1);
  1795. }
  1796. if (isforce && IS_CSKY_ARCH_V2 (mach_flag))
  1797. {
  1798. /* Add one nop insn at end of literal for disassembler. */
  1799. mapping_state (MAP_TEXT);
  1800. csky_insn.output = frag_more (2);
  1801. md_number_to_chars (csky_insn.output, CSKYV2_INST_NOP, 2);
  1802. }
  1803. insn_reloc = BFD_RELOC_NONE;
  1804. if (brarsym != NULL)
  1805. colon (S_GET_NAME (brarsym));
  1806. poolsize = 0;
  1807. }
  1808. static struct literal *
  1809. enter_literal (expressionS *e,
  1810. int ispcrel,
  1811. unsigned char isdouble,
  1812. uint64_t dbnum)
  1813. {
  1814. unsigned int i;
  1815. struct literal * p;
  1816. if (poolsize >= MAX_POOL_SIZE - 2)
  1817. {
  1818. /* The literal pool is as full as we can handle. We have
  1819. to be 2 entries shy of the 1024/4=256 entries because we
  1820. have to allow for the branch (2 bytes) and the alignment
  1821. (2 bytes before the first insn referencing the pool and
  1822. 2 bytes before the pool itself) == 6 bytes, rounds up
  1823. to 2 entries. */
  1824. /* Save the parsed symbol's reloc. */
  1825. enum bfd_reloc_code_real last_reloc_before_dump = insn_reloc;
  1826. dump_literals (1);
  1827. insn_reloc = last_reloc_before_dump;
  1828. }
  1829. if (poolsize == 0)
  1830. {
  1831. /* Create new literal pool. */
  1832. if (++ poolnumber > 0xFFFF)
  1833. as_fatal (_("more than 65K literal pools"));
  1834. make_internal_label (poolname, POOL_START_LABEL, poolnumber);
  1835. poolsym = symbol_make (poolname);
  1836. symbol_table_insert (poolsym);
  1837. poolspan = 0;
  1838. }
  1839. /* Search pool for value so we don't have duplicates. */
  1840. for (p = litpool,i = 0; i < poolsize; p++)
  1841. {
  1842. if (e->X_op == p->e.X_op
  1843. && e->X_add_symbol == p->e.X_add_symbol
  1844. && e->X_add_number == p->e.X_add_number
  1845. && ispcrel == p->ispcrel
  1846. && insn_reloc == p->r_type
  1847. && isdouble == p->isdouble
  1848. && insn_reloc != BFD_RELOC_CKCORE_TLS_GD32
  1849. && insn_reloc != BFD_RELOC_CKCORE_TLS_LDM32
  1850. && insn_reloc != BFD_RELOC_CKCORE_TLS_LDO32
  1851. && insn_reloc != BFD_RELOC_CKCORE_TLS_IE32
  1852. && insn_reloc != BFD_RELOC_CKCORE_TLS_LE32
  1853. && (e->X_op != O_big
  1854. || (memcmp (generic_bignum, p->bignum,
  1855. p->e.X_add_number * sizeof (LITTLENUM_TYPE)) == 0)))
  1856. {
  1857. p->refcnt ++;
  1858. return p;
  1859. }
  1860. if (p->e.X_op == O_big)
  1861. {
  1862. i += (p->e.X_add_number >> 1);
  1863. i += (p->e.X_add_number & 0x1);
  1864. }
  1865. else
  1866. i += (p->isdouble ? 2 : 1);
  1867. }
  1868. p->refcnt = 1;
  1869. p->ispcrel = ispcrel;
  1870. p->e = *e;
  1871. p->r_type = insn_reloc;
  1872. p->isdouble = isdouble;
  1873. p->offset = i;
  1874. if (isdouble)
  1875. p->dbnum = dbnum;
  1876. if (e->X_op == O_big)
  1877. memcpy (p->bignum, generic_bignum, sizeof (p->bignum));
  1878. if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
  1879. || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
  1880. || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
  1881. {
  1882. p->tls_addend.frag = frag_now;
  1883. p->tls_addend.offset = csky_insn.output - frag_now->fr_literal;
  1884. literal_insn_offset = p;
  1885. }
  1886. if (p->e.X_op == O_big) {
  1887. poolsize += (p->e.X_add_number >> 1);
  1888. poolsize += (p->e.X_add_number & 0x1);
  1889. } else
  1890. poolsize += (p->isdouble ? 2 : 1);
  1891. return p;
  1892. }
  1893. /* Check whether we must dump the literal pool here.
  1894. kind == 0 is any old instruction.
  1895. kind > 0 means we just had a control transfer instruction.
  1896. kind == 1 means within a function.
  1897. kind == 2 means we just left a function.
  1898. OFFSET is the length of the insn being processed.
  1899. SPANCLOSE and SPANEXIT are smaller numbers than SPANPANIC.
  1900. SPANPANIC means that we must dump now.
  1901. The dump_literals (1) call inserts a branch around the table, so
  1902. we first look to see if its a situation where we won't have to
  1903. insert a branch (e.g., the previous instruction was an unconditional
  1904. branch).
  1905. SPANPANIC is the point where we must dump a single-entry pool.
  1906. it accounts for alignments and an inserted branch.
  1907. the 'poolsize*2' accounts for the scenario where we do:
  1908. lrw r1,lit1; lrw r2,lit2; lrw r3,lit3
  1909. Note that the 'lit2' reference is 2 bytes further along
  1910. but the literal it references will be 4 bytes further along,
  1911. so we must consider the poolsize into this equation.
  1912. This is slightly over-cautious, but guarantees that we won't
  1913. panic because a relocation is too distant. */
  1914. static void
  1915. check_literals (int kind, int offset)
  1916. {
  1917. poolspan += offset;
  1918. if ((poolspan > SPANEXIT || do_func_dump)
  1919. && kind > 1
  1920. && (do_br_dump || do_func_dump))
  1921. dump_literals (0);
  1922. else if (poolspan > SPANCLOSE && (kind > 0) && do_br_dump)
  1923. dump_literals (0);
  1924. else if (poolspan
  1925. >= (SPANPANIC - (IS_CSKY_ARCH_V1 (mach_flag) ? poolsize * 2 : 0)))
  1926. dump_literals (1);
  1927. /* We have not dumped literal pool before insn1,
  1928. and will not dump literal pool between insn1 and insnN+1,
  1929. so reset poolspan to original length. */
  1930. else if (do_noliteraldump == 1)
  1931. poolspan -= offset;
  1932. if (do_noliteraldump == 1)
  1933. do_noliteraldump = 0;
  1934. }
  1935. /* The next group of functions are helpers for parsing various kinds
  1936. of instruction operand syntax. */
  1937. /* Parse operands of the form
  1938. <symbol>@GOTOFF+<nnn>
  1939. and similar .plt or .got references.
  1940. If we find one, set up the correct relocation in RELOC and copy the
  1941. input string, minus the `@GOTOFF' into a malloc'd buffer for
  1942. parsing by the calling routine. Return this buffer, and if ADJUST
  1943. is non-null set it to the length of the string we removed from the
  1944. input line. Otherwise return NULL. */
  1945. static char *
  1946. lex_got (enum bfd_reloc_code_real *reloc,
  1947. int *adjust)
  1948. {
  1949. struct _gotrel
  1950. {
  1951. const char *str;
  1952. const enum bfd_reloc_code_real rel;
  1953. };
  1954. static const struct _gotrel gotrel[] =
  1955. {
  1956. { "GOTOFF", BFD_RELOC_CKCORE_GOTOFF },
  1957. { "GOTPC", BFD_RELOC_CKCORE_GOTPC },
  1958. { "GOTTPOFF", BFD_RELOC_CKCORE_TLS_IE32 },
  1959. { "GOT", BFD_RELOC_CKCORE_GOT32 },
  1960. { "PLT", BFD_RELOC_CKCORE_PLT32 },
  1961. { "BTEXT", BFD_RELOC_CKCORE_TOFFSET_LO16},
  1962. { "BDATA", BFD_RELOC_CKCORE_DOFFSET_LO16},
  1963. { "TLSGD32", BFD_RELOC_CKCORE_TLS_GD32 },
  1964. { "TLSLDM32", BFD_RELOC_CKCORE_TLS_LDM32 },
  1965. { "TLSLDO32", BFD_RELOC_CKCORE_TLS_LDO32 },
  1966. { "TPOFF", BFD_RELOC_CKCORE_TLS_LE32 }
  1967. };
  1968. char *cp;
  1969. unsigned int j;
  1970. for (cp = input_line_pointer; *cp != '@'; cp++)
  1971. if (is_end_of_line[(unsigned char) *cp])
  1972. return NULL;
  1973. for (j = 0; j < sizeof (gotrel) / sizeof (gotrel[0]); j++)
  1974. {
  1975. int len = strlen (gotrel[j].str);
  1976. if (strncasecmp (cp + 1, gotrel[j].str, len) == 0)
  1977. {
  1978. if (gotrel[j].rel != 0)
  1979. {
  1980. *reloc = gotrel[j].rel;
  1981. if (adjust)
  1982. *adjust = len;
  1983. /* input_line_pointer is the str pointer after relocation
  1984. token like @GOTOFF. */
  1985. input_line_pointer += len + 1;
  1986. return input_line_pointer;
  1987. }
  1988. csky_show_error (ERROR_RELOC_ILLEGAL, 0,
  1989. (void *)gotrel[j].str, NULL);
  1990. return NULL;
  1991. }
  1992. }
  1993. /* Might be a symbol version string. Don't as_bad here. */
  1994. return NULL;
  1995. }
  1996. /* Parse an expression, returning it in E. */
  1997. static char *
  1998. parse_exp (char *s, expressionS *e)
  1999. {
  2000. char *save;
  2001. char *new;
  2002. /* Skip whitespace. */
  2003. while (ISSPACE (*s))
  2004. ++s;
  2005. save = input_line_pointer;
  2006. input_line_pointer = s;
  2007. insn_reloc = BFD_RELOC_NONE;
  2008. expression (e);
  2009. lex_got (&insn_reloc, NULL);
  2010. if (e->X_op == O_absent)
  2011. SET_ERROR_STRING (ERROR_MISSING_OPERAND, NULL);
  2012. new = input_line_pointer;
  2013. input_line_pointer = save;
  2014. return new;
  2015. }
  2016. /* Parse a floating-point number from S into its target representation.
  2017. If ISDOUBLE is true, return the result in *DBNUM; otherwise
  2018. it's returned in E->X_add_number. Returns the result of advancing
  2019. S past the constant. */
  2020. static char *
  2021. parse_fexp (char *s, expressionS *e, unsigned char isdouble, uint64_t *dbnum)
  2022. {
  2023. int length; /* Number of chars in an object. */
  2024. const char *err = NULL; /* Error from scanning float literal. */
  2025. unsigned char temp[8];
  2026. /* input_line_pointer->1st char of a flonum (we hope!). */
  2027. input_line_pointer = s;
  2028. if (input_line_pointer[0] == '0'
  2029. && ISALPHA (input_line_pointer[1]))
  2030. input_line_pointer += 2;
  2031. if (isdouble)
  2032. err = md_atof ('d', (char *) temp, &length);
  2033. else
  2034. err = md_atof ('f', (char *) temp, &length);
  2035. know (length <= 8);
  2036. know (err != NULL || length > 0);
  2037. if (!is_end_of_line[(unsigned char) *input_line_pointer])
  2038. as_bad (_("immediate operand required"));
  2039. while (!is_end_of_line[(unsigned char) *input_line_pointer])
  2040. input_line_pointer++;
  2041. if (err)
  2042. {
  2043. as_bad (_("bad floating literal: %s"), err);
  2044. while (!is_end_of_line[(unsigned char) *input_line_pointer])
  2045. input_line_pointer++;
  2046. know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
  2047. return input_line_pointer;
  2048. }
  2049. e->X_add_symbol = 0x0;
  2050. e->X_op_symbol = 0x0;
  2051. e->X_op = O_constant;
  2052. e->X_unsigned = 1;
  2053. e->X_md = 0x0;
  2054. if (!isdouble)
  2055. {
  2056. uint32_t fnum;
  2057. if (target_big_endian)
  2058. fnum = (((uint32_t) temp[0] << 24)
  2059. | (temp[1] << 16)
  2060. | (temp[2] << 8)
  2061. | temp[3]);
  2062. else
  2063. fnum = (((uint32_t) temp[3] << 24)
  2064. | (temp[2] << 16)
  2065. | (temp[1] << 8)
  2066. | temp[0]);
  2067. e->X_add_number = fnum;
  2068. }
  2069. else
  2070. {
  2071. if (target_big_endian)
  2072. {
  2073. *dbnum = (((uint32_t) temp[0] << 24)
  2074. | (temp[1] << 16)
  2075. | (temp[2] << 8)
  2076. | temp[3]);
  2077. *dbnum <<= 32;
  2078. *dbnum |= (((uint32_t) temp[4] << 24)
  2079. | (temp[5] << 16)
  2080. | (temp[6] << 8)
  2081. | temp[7]);
  2082. }
  2083. else
  2084. {
  2085. *dbnum = (((uint32_t) temp[7] << 24)
  2086. | (temp[6] << 16)
  2087. | (temp[5] << 8)
  2088. | temp[4]);
  2089. *dbnum <<= 32;
  2090. *dbnum |= (((uint32_t) temp[3] << 24)
  2091. | (temp[2] << 16)
  2092. | (temp[1] << 8)
  2093. | temp[0]);
  2094. }
  2095. }
  2096. return input_line_pointer;
  2097. }
  2098. static char *
  2099. parse_rt (char *s,
  2100. int ispcrel,
  2101. expressionS *ep,
  2102. long reg ATTRIBUTE_UNUSED)
  2103. {
  2104. expressionS e;
  2105. if (ep)
  2106. /* Indicate nothing there. */
  2107. ep->X_op = O_absent;
  2108. if (*s == '[')
  2109. {
  2110. s = parse_exp (s + 1, &e);
  2111. if (*s == ']')
  2112. s++;
  2113. else
  2114. SET_ERROR_STRING (ERROR_MISSING_RSQUARE_BRACKETS, NULL);
  2115. if (ep)
  2116. *ep = e;
  2117. }
  2118. else
  2119. {
  2120. s = parse_exp (s, &e);
  2121. if (BFD_RELOC_CKCORE_DOFFSET_LO16 == insn_reloc
  2122. || BFD_RELOC_CKCORE_TOFFSET_LO16 == insn_reloc)
  2123. {
  2124. if (ep)
  2125. *ep = e;
  2126. return s;
  2127. }
  2128. if (ep)
  2129. *ep = e;
  2130. /* If the instruction has work, literal handling is in the work. */
  2131. if (!csky_insn.opcode->work)
  2132. {
  2133. struct literal *p = enter_literal (&e, ispcrel, 0, 0);
  2134. if (ep)
  2135. *ep = e;
  2136. /* Create a reference to pool entry. */
  2137. ep->X_op = O_symbol;
  2138. ep->X_add_symbol = poolsym;
  2139. ep->X_add_number = p->offset << 2;
  2140. }
  2141. }
  2142. return s;
  2143. }
  2144. static int float_to_half (void *f, void *h)
  2145. {
  2146. int imm_e;
  2147. int imm_f;
  2148. unsigned int value_f = *(unsigned int *)f;
  2149. unsigned short value_h;
  2150. imm_e = ((value_f >> 23) & 0xff);
  2151. imm_f = ((value_f & 0x7fffff));
  2152. imm_e = ((imm_e - 127 + 15) << 10);
  2153. imm_f = ((imm_f & 0x7fe000) >> 13);
  2154. value_h = (value_f & 0x80000000 ? 0x8000 : 0x0) | imm_e | imm_f;
  2155. if (h)
  2156. *(unsigned short *)h = value_h;
  2157. return value_h;
  2158. }
  2159. static char *
  2160. parse_rtf (char *s, int ispcrel, expressionS *ep)
  2161. {
  2162. expressionS e;
  2163. struct literal *p = NULL;
  2164. if (ep)
  2165. /* Indicate nothing there. */
  2166. ep->X_op = O_absent;
  2167. if (*s == '[')
  2168. {
  2169. s = parse_exp (s + 1, & e);
  2170. if (*s == ']')
  2171. s++;
  2172. else
  2173. as_bad (_("missing ']'"));
  2174. if (ep)
  2175. *ep = e;
  2176. }
  2177. else
  2178. {
  2179. uint64_t dbnum;
  2180. if (strstr(csky_insn.opcode->mnemonic, "flrws")
  2181. || strstr(csky_insn.opcode->mnemonic, "flrw.32"))
  2182. {
  2183. s = parse_fexp (s, &e, 0, &dbnum);
  2184. p = enter_literal (& e, ispcrel, 0, dbnum);
  2185. }
  2186. else if (strstr(csky_insn.opcode->mnemonic, "flrwd")
  2187. || strstr(csky_insn.opcode->mnemonic, "flrw.64"))
  2188. {
  2189. s = parse_fexp (s, &e, 1, &dbnum);
  2190. p = enter_literal (& e, ispcrel, 1, dbnum);
  2191. }
  2192. else if (strstr(csky_insn.opcode->mnemonic, "flrwh")
  2193. || strstr(csky_insn.opcode->mnemonic, "flrw.16"))
  2194. {
  2195. s = parse_fexp (s, &e, 0, NULL);
  2196. e.X_add_number = float_to_half (&e.X_add_number, &e.X_add_number);
  2197. p = enter_literal (& e, ispcrel, 0, 0);
  2198. }
  2199. else
  2200. as_bad (_("unrecognized opcode"));
  2201. if (ep)
  2202. *ep = e;
  2203. /* Create a reference to pool entry. */
  2204. ep->X_op = O_symbol;
  2205. ep->X_add_symbol = poolsym;
  2206. ep->X_add_number = p->offset << 2;
  2207. }
  2208. return s;
  2209. }
  2210. static bool
  2211. parse_type_ctrlreg (char** oper)
  2212. {
  2213. int i = -1;
  2214. int group = 0;
  2215. int crx;
  2216. int sel;
  2217. char *s = *oper;
  2218. expressionS e;
  2219. if (TOLOWER (*(*oper + 0)) == 'c'
  2220. && TOLOWER (*(*oper + 1)) == 'r'
  2221. && ISDIGIT (*(*oper + 2)))
  2222. {
  2223. /* The control registers are named crxx. */
  2224. s = *oper+2;
  2225. s = parse_exp (s, &e);
  2226. if (e.X_op == O_constant)
  2227. {
  2228. i = e.X_add_number;
  2229. *oper = s;
  2230. }
  2231. }
  2232. if (IS_CSKY_V2 (mach_flag))
  2233. {
  2234. s = *oper;
  2235. if (i != -1)
  2236. {
  2237. crx = i;
  2238. sel = group;
  2239. }
  2240. else if (TOLOWER (*(*oper + 0)) == 'c'
  2241. && TOLOWER (*(*oper + 1)) == 'r')
  2242. {
  2243. s += 2;
  2244. if (*s != '<')
  2245. {
  2246. SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
  2247. return false;
  2248. }
  2249. s++;
  2250. crx = strtol(s, &s, 10);
  2251. if (crx < 0 || crx > 31 || *s != ',')
  2252. {
  2253. SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
  2254. return false;
  2255. }
  2256. s++;
  2257. sel = strtol(s, &s, 10);
  2258. if (sel < 0 || sel > 31 || *s != '>')
  2259. {
  2260. SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
  2261. return false;
  2262. }
  2263. s++;
  2264. }
  2265. else
  2266. {
  2267. crx = csky_get_control_regno (mach_flag, s, &s, &sel);
  2268. if (crx < 0)
  2269. {
  2270. SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
  2271. return false;
  2272. }
  2273. }
  2274. i = (sel << 5) | crx;
  2275. }
  2276. else if (i == -1)
  2277. {
  2278. i = csky_get_control_regno (mach_flag, s, &s, &sel);
  2279. if (i < 0)
  2280. {
  2281. SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
  2282. return false;
  2283. }
  2284. }
  2285. *oper = s;
  2286. csky_insn.val[csky_insn.idx++] = i;
  2287. return true;
  2288. }
  2289. static int
  2290. csky_get_reg_val (char *str, int *len)
  2291. {
  2292. int regno = 0;
  2293. char *s = str;
  2294. regno = csky_get_general_regno (mach_flag, str, &s);
  2295. *len = (s - str);
  2296. return regno;
  2297. }
  2298. static bool
  2299. is_reg_sp_with_bracket (char **oper)
  2300. {
  2301. int reg;
  2302. int sp_idx;
  2303. int len;
  2304. if (IS_CSKY_V1 (mach_flag))
  2305. sp_idx = 0;
  2306. else
  2307. sp_idx = 14;
  2308. if (**oper != '(')
  2309. return false;
  2310. *oper += 1;
  2311. reg = csky_get_reg_val (*oper, &len);
  2312. *oper += len;
  2313. if (reg == sp_idx)
  2314. {
  2315. if (**oper != ')')
  2316. {
  2317. SET_ERROR_STRING (ERROR_UNDEFINE,
  2318. "Operand format is error. '(sp)' expected");
  2319. return false;
  2320. }
  2321. *oper += 1;
  2322. csky_insn.val[csky_insn.idx++] = sp_idx;
  2323. return true;
  2324. }
  2325. SET_ERROR_STRING (ERROR_UNDEFINE,
  2326. "Operand format is error. '(sp)' expected");
  2327. return false;
  2328. }
  2329. static bool
  2330. is_reg_sp (char **oper)
  2331. {
  2332. char sp_name[16];
  2333. int sp_idx;
  2334. int len;
  2335. if (IS_CSKY_V1 (mach_flag))
  2336. sp_idx = 0;
  2337. else
  2338. sp_idx = 14;
  2339. /* ABI names: "sp". */
  2340. if (memcmp (*oper, "sp", 2) == 0)
  2341. {
  2342. *oper += 2;
  2343. csky_insn.val[csky_insn.idx++] = sp_idx;
  2344. return true;
  2345. }
  2346. len = sprintf (sp_name, "r%d", sp_idx);
  2347. if (memcmp (*oper, sp_name, len) == 0)
  2348. {
  2349. *oper += len;
  2350. csky_insn.val[csky_insn.idx++] = sp_idx;
  2351. return true;
  2352. }
  2353. return false;
  2354. }
  2355. static int
  2356. csky_get_freg_val (char *str, int *len)
  2357. {
  2358. int reg = 0;
  2359. char *s = NULL;
  2360. if ((TOLOWER(str[0]) == 'v' || TOLOWER(str[0]) == 'f')
  2361. && (TOLOWER(str[1]) == 'r'))
  2362. {
  2363. /* It is fpu register. */
  2364. s = &str[2];
  2365. while (ISDIGIT (*s))
  2366. {
  2367. reg = reg * 10 + (*s) - '0';
  2368. s++;
  2369. }
  2370. if (reg > 31)
  2371. return -1;
  2372. }
  2373. else
  2374. return -1;
  2375. *len = s - str;
  2376. return reg;
  2377. }
  2378. static bool
  2379. is_reglist_legal (char **oper)
  2380. {
  2381. int reg1 = -1;
  2382. int reg2 = -1;
  2383. int len = 0;
  2384. reg1 = csky_get_reg_val (*oper, &len);
  2385. *oper += len;
  2386. if (reg1 == -1 || (IS_CSKY_V1 (mach_flag) && (reg1 == 0 || reg1 == 15)))
  2387. {
  2388. SET_ERROR_STRING (ERROR_REG_FORMAT,
  2389. "The first reg must not be r0/r15");
  2390. return false;
  2391. }
  2392. if (**oper != '-')
  2393. {
  2394. SET_ERROR_STRING (ERROR_REG_FORMAT,
  2395. "The operand format must be rx-ry");
  2396. return false;
  2397. }
  2398. *oper += 1;
  2399. reg2 = csky_get_reg_val (*oper, &len);
  2400. *oper += len;
  2401. if (reg2 == -1 || (IS_CSKY_V1 (mach_flag) && reg1 == 15))
  2402. {
  2403. SET_ERROR_STRING (ERROR_REG_FORMAT,
  2404. "The operand format must be r15 in C-SKY V1");
  2405. return false;
  2406. }
  2407. if (IS_CSKY_V2 (mach_flag))
  2408. {
  2409. if (reg2 < reg1)
  2410. {
  2411. SET_ERROR_STRING (ERROR_REG_FORMAT,
  2412. "The operand format must be rx-ry (rx < ry)");
  2413. return false;
  2414. }
  2415. reg2 = reg2 - reg1;
  2416. reg1 <<= 5;
  2417. reg1 |= reg2;
  2418. }
  2419. csky_insn.val[csky_insn.idx++] = reg1;
  2420. return true;
  2421. }
  2422. static bool
  2423. is_freglist_legal (char **oper)
  2424. {
  2425. int reg1 = -1;
  2426. int reg2 = -1;
  2427. int len = 0;
  2428. int shift = 0;
  2429. reg1 = csky_get_freg_val (*oper, &len);
  2430. *oper += len;
  2431. if (reg1 == -1)
  2432. {
  2433. SET_ERROR_STRING (ERROR_REG_FORMAT,
  2434. "The fpu register format is not recognized.");
  2435. return false;
  2436. }
  2437. if (**oper != '-')
  2438. {
  2439. SET_ERROR_STRING (ERROR_REG_FORMAT,
  2440. "The operand format must be vrx-vry/frx-fry.");
  2441. return false;
  2442. }
  2443. *oper += 1;
  2444. reg2 = csky_get_freg_val (*oper, &len);
  2445. *oper += len;
  2446. if (reg2 == -1)
  2447. {
  2448. SET_ERROR_STRING (ERROR_REG_FORMAT,
  2449. "The fpu register format is not recognized.");
  2450. return false;
  2451. }
  2452. if (reg2 < reg1)
  2453. {
  2454. SET_ERROR_STRING (ERROR_REG_FORMAT,
  2455. "The operand format must be rx-ry(rx < ry)");
  2456. return false;
  2457. }
  2458. reg2 = reg2 - reg1;
  2459. /* The fldm/fstm in CSKY_ISA_FLOAT_7E60 has 5 bits frz(reg1). */
  2460. shift = 4;
  2461. if (startswith (csky_insn.opcode->mnemonic, "fstm")
  2462. || startswith (csky_insn.opcode->mnemonic, "fldm"))
  2463. {
  2464. if ((!(isa_flag & CSKY_ISA_FLOAT_7E60)
  2465. && (reg2 > (int)15 || reg1 > 15))
  2466. || ((isa_flag & CSKY_ISA_FLOAT_7E60)
  2467. && (reg2 > (int)31 || reg1 > (int)31)))
  2468. {
  2469. /* ISA_FLOAT_E1 fstm/fldm fry-frx is within 15.
  2470. ISA_FLOAT_7E60 fstm(u)/fldm(u) frx-fry is within 31. */
  2471. SET_ERROR_STRING(ERROR_REG_FORMAT, (void *)"frx-fry is over range");
  2472. return false;
  2473. }
  2474. if ((mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_860)
  2475. {
  2476. shift = 5;
  2477. }
  2478. }
  2479. else
  2480. {
  2481. if (reg2 > (int)0x3) {
  2482. SET_ERROR_STRING(ERROR_REG_FORMAT, (void *)"vry-vrx is over range");
  2483. return false;
  2484. }
  2485. }
  2486. reg2 <<= shift;
  2487. reg1 |= reg2;
  2488. csky_insn.val[csky_insn.idx++] = reg1;
  2489. return true;
  2490. }
  2491. static bool
  2492. is_reglist_dash_comma_legal (char **oper, struct operand *oprnd)
  2493. {
  2494. int reg1 = -1;
  2495. int reg2 = -1;
  2496. int len = 0;
  2497. int list = 0;
  2498. int flag = 0;
  2499. int temp = 0;
  2500. while (**oper != '\n' && **oper != '\0')
  2501. {
  2502. reg1 = csky_get_reg_val (*oper, &len);
  2503. if (reg1 == -1)
  2504. {
  2505. SET_ERROR_STRING (ERROR_REG_LIST, NULL);
  2506. return false;
  2507. }
  2508. flag |= (1 << reg1);
  2509. *oper += len;
  2510. if (**oper == '-')
  2511. {
  2512. *oper += 1;
  2513. reg2 = csky_get_reg_val (*oper, &len);
  2514. if (reg2 == -1)
  2515. {
  2516. SET_ERROR_STRING (ERROR_REG_LIST, NULL);
  2517. return false;
  2518. }
  2519. *oper += len;
  2520. if (reg1 > reg2)
  2521. {
  2522. SET_ERROR_STRING (ERROR_REG_LIST, NULL);
  2523. return false;
  2524. }
  2525. while (reg2 >= reg1)
  2526. {
  2527. flag |= (1 << reg2);
  2528. reg2--;
  2529. }
  2530. }
  2531. if (**oper == ',')
  2532. *oper += 1;
  2533. }
  2534. /* The reglist: r4-r11, r15, r16-r17, r28. */
  2535. #define REGLIST_BITS 0x10038ff0
  2536. if (flag & ~(REGLIST_BITS))
  2537. {
  2538. SET_ERROR_STRING (ERROR_REG_LIST, NULL);
  2539. return false;
  2540. }
  2541. /* Check r4-r11. */
  2542. int i = 4;
  2543. while (i <= 11)
  2544. {
  2545. if (flag & (1 << i))
  2546. temp = i - 4 + 1;
  2547. i++;
  2548. }
  2549. list |= temp;
  2550. /* Check r15. */
  2551. if (flag & (1 << 15))
  2552. list |= (1 << 4);
  2553. /* Check r16-r17. */
  2554. i = 16;
  2555. temp = 0;
  2556. while (i <= 17)
  2557. {
  2558. if (flag & (1 << i))
  2559. temp = i - 16 + 1;
  2560. i++;
  2561. }
  2562. list |= (temp << 5);
  2563. /* Check r28. */
  2564. if (flag & (1 << 28))
  2565. list |= (1 << 8);
  2566. if (oprnd->mask == OPRND_MASK_0_4 && (list & ~OPRND_MASK_0_4))
  2567. {
  2568. SET_ERROR_STRING (ERROR_REG_LIST, NULL);
  2569. return false;
  2570. }
  2571. csky_insn.val[csky_insn.idx++] = list;
  2572. return true;
  2573. }
  2574. static bool
  2575. is_reg_lshift_illegal (char **oper, int is_float)
  2576. {
  2577. int value;
  2578. int len;
  2579. int reg;
  2580. reg = csky_get_reg_val (*oper, &len);
  2581. if (reg == -1)
  2582. {
  2583. SET_ERROR_STRING (ERROR_REG_FORMAT, "The register must be r0-r31.");
  2584. return false;
  2585. }
  2586. *oper += len;
  2587. if ((*oper)[0] != '<' || (*oper)[1] != '<')
  2588. {
  2589. SET_ERROR_STRING (ERROR_UNDEFINE,
  2590. "Operand format error; should be (rx, ry << n)");
  2591. return false;
  2592. }
  2593. *oper += 2;
  2594. expressionS e;
  2595. char *new_oper = parse_exp (*oper, &e);
  2596. if (e.X_op == O_constant)
  2597. {
  2598. *oper = new_oper;
  2599. /* The immediate must be in [0, 3]. */
  2600. if (e.X_add_number < 0 || e.X_add_number > 3)
  2601. {
  2602. SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
  2603. return false;
  2604. }
  2605. }
  2606. else
  2607. {
  2608. SET_ERROR_STRING (ERROR_EXP_CONSTANT, NULL);
  2609. return false;
  2610. }
  2611. if (is_float)
  2612. value = (reg << 2) | e.X_add_number;
  2613. else
  2614. value = (reg << 5) | (1 << e.X_add_number);
  2615. csky_insn.val[csky_insn.idx++] = value;
  2616. return true;
  2617. }
  2618. static bool
  2619. is_imm_within_range (char **oper, int min, int max)
  2620. {
  2621. expressionS e;
  2622. bool ret = false;
  2623. char *new_oper = parse_exp (*oper, &e);
  2624. if (e.X_op == O_constant)
  2625. {
  2626. ret = true;
  2627. *oper = new_oper;
  2628. if (e.X_add_number < min || e.X_add_number > max)
  2629. {
  2630. ret = false;
  2631. SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
  2632. }
  2633. if (!e.X_unsigned)
  2634. e.X_add_number |= 0x80000000;
  2635. csky_insn.val[csky_insn.idx++] = e.X_add_number;
  2636. }
  2637. else
  2638. SET_ERROR_STRING(ERROR_IMM_ILLEGAL, NULL);
  2639. return ret;
  2640. }
  2641. static bool
  2642. is_imm_within_range_ext (char **oper, int min, int max, int ext)
  2643. {
  2644. expressionS e;
  2645. bool ret = false;
  2646. char *new_oper = parse_exp (*oper, &e);
  2647. if (e.X_op == O_constant)
  2648. {
  2649. ret = true;
  2650. *oper = new_oper;
  2651. if ((int)e.X_add_number != ext
  2652. && (e.X_add_number < min || e.X_add_number > max))
  2653. {
  2654. ret = false;
  2655. SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
  2656. }
  2657. csky_insn.val[csky_insn.idx++] = e.X_add_number;
  2658. }
  2659. else
  2660. SET_ERROR_STRING(ERROR_IMM_ILLEGAL, NULL);
  2661. return ret;
  2662. }
  2663. static bool
  2664. is_oimm_within_range (char **oper, int min, int max)
  2665. {
  2666. expressionS e;
  2667. bool ret = false;
  2668. char *new_oper = parse_exp (*oper, &e);
  2669. if (e.X_op == O_constant)
  2670. {
  2671. ret = true;
  2672. *oper = new_oper;
  2673. if (e.X_add_number < min || e.X_add_number > max)
  2674. {
  2675. ret = false;
  2676. SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
  2677. }
  2678. csky_insn.val[csky_insn.idx++] = e.X_add_number - 1;
  2679. }
  2680. else
  2681. SET_ERROR_STRING (ERROR_IMM_ILLEGAL, NULL);
  2682. return ret;
  2683. }
  2684. static bool
  2685. is_psr_bit (char **oper)
  2686. {
  2687. const struct psrbit *bits;
  2688. int i = 0;
  2689. if (IS_CSKY_V1 (mach_flag))
  2690. bits = cskyv1_psr_bits;
  2691. else
  2692. bits = cskyv2_psr_bits;
  2693. while (bits[i].name != NULL)
  2694. {
  2695. if (bits[i].isa && !(bits[i].isa & isa_flag))
  2696. {
  2697. i++;
  2698. continue;
  2699. }
  2700. if (strncasecmp (*oper, bits[i].name, strlen (bits[i].name)) == 0)
  2701. {
  2702. *oper += strlen (bits[i].name);
  2703. csky_insn.val[csky_insn.idx] |= bits[i].value;
  2704. return true;
  2705. }
  2706. i++;
  2707. }
  2708. SET_ERROR_STRING (ERROR_OPCODE_PSRBIT, NULL);
  2709. return false;
  2710. }
  2711. static bool
  2712. parse_type_cpidx (char** oper)
  2713. {
  2714. char *s = *oper;
  2715. int idx;
  2716. if (s[0] == 'c' && s[1] == 'p')
  2717. {
  2718. if (ISDIGIT (s[2]) && ISDIGIT (s[3]) && ! ISDIGIT (s[4]))
  2719. {
  2720. idx = (s[2] - '0') * 10 + s[3] - '0';
  2721. *oper += 4;
  2722. }
  2723. else if (ISDIGIT (s[2]) && !ISDIGIT (s[3]))
  2724. {
  2725. idx = s[2] - '0';
  2726. *oper += 3;
  2727. }
  2728. else
  2729. return false;
  2730. }
  2731. else
  2732. {
  2733. expressionS e;
  2734. *oper = parse_exp (*oper, &e);
  2735. if (e.X_op != O_constant)
  2736. {
  2737. /* Can not recognize the operand. */
  2738. return false;
  2739. }
  2740. idx = e.X_add_number;
  2741. }
  2742. csky_insn.val[csky_insn.idx++] = idx;
  2743. return true;
  2744. }
  2745. static bool
  2746. parse_type_cpreg (char** oper)
  2747. {
  2748. expressionS e;
  2749. if (strncasecmp (*oper, "cpr", 3) != 0)
  2750. {
  2751. SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
  2752. return false;
  2753. }
  2754. *oper += 3;
  2755. *oper = parse_exp (*oper, &e);
  2756. if (e.X_op != O_constant)
  2757. {
  2758. SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
  2759. return false;
  2760. }
  2761. csky_insn.val[csky_insn.idx++] = e.X_add_number;
  2762. return true;
  2763. }
  2764. static bool
  2765. parse_type_cpcreg (char** oper)
  2766. {
  2767. expressionS e;
  2768. if (strncasecmp (*oper, "cpcr", 4) != 0)
  2769. {
  2770. SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
  2771. return false;
  2772. }
  2773. *oper += 4;
  2774. *oper = parse_exp (*oper, &e);
  2775. if (e.X_op != O_constant)
  2776. {
  2777. SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
  2778. return false;
  2779. }
  2780. csky_insn.val[csky_insn.idx++] = e.X_add_number;
  2781. return true;
  2782. }
  2783. static bool
  2784. parse_type_areg (char** oper)
  2785. {
  2786. int i = 0;
  2787. int len = 0;
  2788. i = csky_get_reg_val (*oper, &len);
  2789. if (i == -1)
  2790. {
  2791. SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
  2792. return false;
  2793. }
  2794. *oper += len;
  2795. csky_insn.val[csky_insn.idx++] = i;
  2796. return true;
  2797. }
  2798. static bool
  2799. parse_type_freg (char** oper, int even)
  2800. {
  2801. int reg;
  2802. int len;
  2803. reg = csky_get_freg_val (*oper, &len);
  2804. if (reg == -1)
  2805. {
  2806. SET_ERROR_STRING (ERROR_REG_FORMAT,
  2807. (void *)"The fpu register format is not recognized.");
  2808. return false;
  2809. }
  2810. *oper += len;
  2811. csky_insn.opcode_end = *oper;
  2812. if (even && reg & 0x1)
  2813. {
  2814. SET_ERROR_STRING (ERROR_EXP_EVEN_FREG, NULL);
  2815. return false;
  2816. }
  2817. if (IS_CSKY_V2 (mach_flag)
  2818. && ((csky_insn.opcode->isa_flag32 & CSKY_ISA_VDSP_2)
  2819. || !(csky_insn.opcode->isa_flag32 & CSKY_ISA_FLOAT_7E60))
  2820. && reg > 15)
  2821. {
  2822. if ((csky_insn.opcode->isa_flag32 & CSKY_ISA_VDSP_2))
  2823. {
  2824. SET_ERROR_INTEGER (ERROR_VREG_OVER_RANGE, reg);
  2825. }
  2826. else
  2827. {
  2828. SET_ERROR_INTEGER (ERROR_FREG_OVER_RANGE, reg);
  2829. }
  2830. return false;
  2831. }
  2832. /* TODO: recognize vreg or freg. */
  2833. if (reg > 31)
  2834. {
  2835. SET_ERROR_INTEGER (ERROR_VREG_OVER_RANGE, reg);
  2836. }
  2837. csky_insn.val[csky_insn.idx++] = reg;
  2838. return true;
  2839. }
  2840. static bool
  2841. parse_ldst_imm (char **oper, struct csky_opcode_info *op ATTRIBUTE_UNUSED,
  2842. struct operand *oprnd)
  2843. {
  2844. unsigned int mask = oprnd->mask;
  2845. int max = 1;
  2846. int shift = 0;
  2847. shift = oprnd->shift;
  2848. while (mask)
  2849. {
  2850. if (mask & 1)
  2851. max <<= 1;
  2852. mask >>= 1;
  2853. }
  2854. max = max << shift;
  2855. if (**oper == '\0' || **oper == ')')
  2856. {
  2857. csky_insn.val[csky_insn.idx++] = 0;
  2858. return true;
  2859. }
  2860. expressionS e;
  2861. *oper = parse_exp (*oper, &e);
  2862. if (e.X_op != O_constant)
  2863. {
  2864. /* Not a constant. */
  2865. SET_ERROR_STRING(ERROR_UNDEFINE, (void *)"Operand format is error. eg. \"ld rz, (rx, n)\"");
  2866. return false;
  2867. }
  2868. else if (e.X_add_number < 0 || e.X_add_number >= max)
  2869. {
  2870. /* Out of range. */
  2871. SET_ERROR_STRING(ERROR_IMM_OVERFLOW, NULL);
  2872. return false;
  2873. }
  2874. if ((e.X_add_number % (1 << shift)) != 0)
  2875. {
  2876. /* Not aligned. */
  2877. SET_ERROR_INTEGER (ERROR_OFFSET_UNALIGNED, ((unsigned long)1 << shift));
  2878. return false;
  2879. }
  2880. csky_insn.val[csky_insn.idx++] = e.X_add_number >> shift;
  2881. return true;
  2882. }
  2883. static unsigned int
  2884. csky_count_operands (char *str)
  2885. {
  2886. char *oper_end = str;
  2887. unsigned int oprnd_num;
  2888. int bracket_cnt = 0;
  2889. if (is_end_of_line[(unsigned char) *oper_end])
  2890. oprnd_num = 0;
  2891. else
  2892. oprnd_num = 1;
  2893. /* Count how many operands. */
  2894. if (oprnd_num)
  2895. while (!is_end_of_line[(unsigned char) *oper_end])
  2896. {
  2897. if (*oper_end == '(' || *oper_end == '<')
  2898. {
  2899. bracket_cnt++;
  2900. oper_end++;
  2901. continue;
  2902. }
  2903. if (*oper_end == ')' || *oper_end == '>')
  2904. {
  2905. bracket_cnt--;
  2906. oper_end++;
  2907. continue;
  2908. }
  2909. if (!bracket_cnt && *oper_end == ',')
  2910. oprnd_num++;
  2911. oper_end++;
  2912. }
  2913. return oprnd_num;
  2914. }
  2915. /* End of the operand parsing helper functions. */
  2916. /* Parse the opcode part of an instruction. Fill in the csky_insn
  2917. state and return true on success, false otherwise. */
  2918. static bool
  2919. parse_opcode (char *str)
  2920. {
  2921. #define IS_OPCODE32F(a) (*(a - 2) == '3' && *(a - 1) == '2')
  2922. #define IS_OPCODE16F(a) (*(a - 2) == '1' && *(a - 1) == '6')
  2923. /* TRUE if this opcode has a suffix, like 'lrw.h'. */
  2924. unsigned int has_suffix = false;
  2925. unsigned int nlen = 0;
  2926. char *opcode_end;
  2927. char name[OPCODE_MAX_LEN + 1];
  2928. char macro_name[OPCODE_MAX_LEN + 1];
  2929. /* Remove space ahead of string. */
  2930. while (ISSPACE (*str))
  2931. str++;
  2932. opcode_end = str;
  2933. /* Find the opcode end. */
  2934. while (nlen < OPCODE_MAX_LEN
  2935. && !is_end_of_line [(unsigned char) *opcode_end]
  2936. && *opcode_end != ' ')
  2937. {
  2938. /* Is csky force 32 or 16 instruction? */
  2939. if (IS_CSKY_V2 (mach_flag)
  2940. && *opcode_end == '.' && !has_suffix)
  2941. {
  2942. has_suffix = true;
  2943. if (IS_OPCODE32F (opcode_end))
  2944. {
  2945. csky_insn.flag_force = INSN_OPCODE32F;
  2946. nlen -= 2;
  2947. }
  2948. else if (IS_OPCODE16F (opcode_end))
  2949. {
  2950. csky_insn.flag_force = INSN_OPCODE16F;
  2951. nlen -= 2;
  2952. }
  2953. }
  2954. name[nlen] = *opcode_end;
  2955. nlen++;
  2956. opcode_end++;
  2957. }
  2958. /* Is csky force 32 or 16 instruction? */
  2959. if (!has_suffix)
  2960. {
  2961. if (IS_CSKY_V2 (mach_flag) && IS_OPCODE32F (opcode_end))
  2962. {
  2963. csky_insn.flag_force = INSN_OPCODE32F;
  2964. nlen -= 2;
  2965. }
  2966. else if (IS_OPCODE16F (opcode_end))
  2967. {
  2968. csky_insn.flag_force = INSN_OPCODE16F;
  2969. nlen -= 2;
  2970. }
  2971. }
  2972. name[nlen] = '\0';
  2973. /* Generate macro_name for finding hash in macro hash_table. */
  2974. if (has_suffix)
  2975. nlen += 2;
  2976. strncpy (macro_name, str, nlen);
  2977. macro_name[nlen] = '\0';
  2978. /* Get csky_insn.opcode_end. */
  2979. while (ISSPACE (*opcode_end))
  2980. opcode_end++;
  2981. csky_insn.opcode_end = opcode_end;
  2982. /* Count the operands. */
  2983. csky_insn.number = csky_count_operands (opcode_end);
  2984. /* Find hash by name in csky_macros_hash and csky_opcodes_hash. */
  2985. csky_insn.macro = (struct csky_macro_info *) str_hash_find (csky_macros_hash,
  2986. macro_name);
  2987. csky_insn.opcode = (struct csky_opcode *) str_hash_find (csky_opcodes_hash,
  2988. name);
  2989. if (csky_insn.macro == NULL && csky_insn.opcode == NULL)
  2990. return false;
  2991. return true;
  2992. }
  2993. /* Main dispatch routine to parse operand OPRND for opcode OP from string
  2994. *OPER. */
  2995. static bool
  2996. get_operand_value (struct csky_opcode_info *op,
  2997. char **oper, struct operand *oprnd)
  2998. {
  2999. struct soperand *soprnd = NULL;
  3000. if (oprnd->mask == HAS_SUB_OPERAND)
  3001. {
  3002. /* It has sub operand, it must be like:
  3003. (oprnd1, oprnd2)
  3004. or
  3005. <oprnd1, oprnd2>
  3006. We will check the format here. */
  3007. soprnd = (struct soperand *) oprnd;
  3008. char lc = 0;
  3009. char rc = 0;
  3010. char *s = *oper;
  3011. int bracket_cnt = 0;
  3012. if (oprnd->type == OPRND_TYPE_BRACKET)
  3013. {
  3014. lc = '(';
  3015. rc = ')';
  3016. }
  3017. else if (oprnd->type == OPRND_TYPE_ABRACKET)
  3018. {
  3019. lc = '<';
  3020. rc = '>';
  3021. }
  3022. if (**oper == lc)
  3023. {
  3024. *oper += 1;
  3025. s += 1;
  3026. }
  3027. else
  3028. {
  3029. SET_ERROR_STRING ((oprnd->type == OPRND_TYPE_BRACKET
  3030. ? ERROR_MISSING_LBRACKET
  3031. : ERROR_MISSING_LANGLE_BRACKETS), NULL);
  3032. return false;
  3033. }
  3034. /* If the oprnd2 is an immediate, it can not be parsed
  3035. that end with ')'/'>'. Modify ')'/'>' to '\0'. */
  3036. while ((*s != rc || bracket_cnt != 0) && (*s != '\n' && *s != '\0'))
  3037. {
  3038. if (*s == lc)
  3039. bracket_cnt++;
  3040. else if (*s == rc)
  3041. bracket_cnt--;
  3042. s++;
  3043. }
  3044. if (*s == rc)
  3045. *s = '\0';
  3046. else
  3047. {
  3048. SET_ERROR_STRING ((oprnd->type == OPRND_TYPE_BRACKET
  3049. ? ERROR_MISSING_RBRACKET
  3050. : ERROR_MISSING_RANGLE_BRACKETS), NULL);
  3051. return false;
  3052. }
  3053. if (!get_operand_value (op, oper, &soprnd->subs[0]))
  3054. {
  3055. *s = rc;
  3056. return false;
  3057. }
  3058. if (**oper == ',')
  3059. *oper += 1;
  3060. else if (**oper != '\0')
  3061. {
  3062. SET_ERROR_STRING (ERROR_MISSING_COMMA, NULL);
  3063. return false;
  3064. }
  3065. if (!get_operand_value (op, oper, &soprnd->subs[1]))
  3066. {
  3067. *s = rc;
  3068. return false;
  3069. }
  3070. *s = rc;
  3071. *oper += 1;
  3072. return true;
  3073. }
  3074. switch (oprnd->type)
  3075. {
  3076. /* TODO: add opcode type here, log errors in the function.
  3077. If REGLIST, then j = csky_insn.number - 1.
  3078. If there is needed to parse expressions, it will be
  3079. handled here. */
  3080. case OPRND_TYPE_CTRLREG:
  3081. /* some parse. */
  3082. return parse_type_ctrlreg (oper);
  3083. case OPRND_TYPE_AREG:
  3084. return parse_type_areg (oper);
  3085. case OPRND_TYPE_FREG:
  3086. case OPRND_TYPE_VREG:
  3087. return parse_type_freg (oper, 0);
  3088. case OPRND_TYPE_FEREG:
  3089. return parse_type_freg (oper, 1);
  3090. case OPRND_TYPE_CPCREG:
  3091. return parse_type_cpcreg (oper);
  3092. case OPRND_TYPE_CPREG:
  3093. return parse_type_cpreg (oper);
  3094. case OPRND_TYPE_CPIDX:
  3095. return parse_type_cpidx (oper);
  3096. case OPRND_TYPE_GREG0_7:
  3097. case OPRND_TYPE_GREG0_15:
  3098. {
  3099. int len;
  3100. long reg;
  3101. reg = csky_get_reg_val (*oper, &len);
  3102. if (reg == -1)
  3103. {
  3104. SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
  3105. return false;
  3106. }
  3107. else if ((oprnd->type == OPRND_TYPE_GREG0_7 && reg > 7)
  3108. || (oprnd->type == OPRND_TYPE_GREG0_15 && reg > 15))
  3109. {
  3110. SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, reg);
  3111. return false;
  3112. }
  3113. *oper += len;
  3114. csky_insn.val[csky_insn.idx++] = reg;
  3115. return true;
  3116. }
  3117. case OPRND_TYPE_REGnsplr:
  3118. {
  3119. int len;
  3120. long reg;
  3121. reg = csky_get_reg_val (*oper, &len);
  3122. if (reg == -1
  3123. || (IS_CSKY_V1 (mach_flag)
  3124. && (reg == V1_REG_SP || reg == V1_REG_LR)))
  3125. {
  3126. SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg);
  3127. return false;
  3128. }
  3129. csky_insn.val[csky_insn.idx++] = reg;
  3130. *oper += len;
  3131. return true;;
  3132. }
  3133. case OPRND_TYPE_REGnr4_r7:
  3134. {
  3135. int len;
  3136. int reg;
  3137. if (**oper == '(')
  3138. *oper += 1;
  3139. reg = csky_get_reg_val (*oper, &len);
  3140. if (reg == -1 || (reg <= 7 && reg >= 4))
  3141. return false;
  3142. csky_insn.val[csky_insn.idx++] = reg;
  3143. *oper += len;
  3144. if (**oper == ')')
  3145. *oper += 1;
  3146. return true;;
  3147. }
  3148. case OPRND_TYPE_REGr4_r7:
  3149. if (memcmp (*oper, "r4-r7", sizeof ("r4-r7") - 1) == 0)
  3150. {
  3151. *oper += sizeof ("r4-r7") - 1;
  3152. csky_insn.val[csky_insn.idx++] = 0;
  3153. return true;
  3154. }
  3155. SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL);
  3156. return false;
  3157. case OPRND_TYPE_IMM_LDST:
  3158. return parse_ldst_imm (oper, op, oprnd);
  3159. case OPRND_TYPE_IMM_FLDST:
  3160. return parse_ldst_imm (oper, op, oprnd);
  3161. case OPRND_TYPE_IMM1b:
  3162. return is_imm_within_range (oper, 0, 1);
  3163. case OPRND_TYPE_IMM2b:
  3164. return is_imm_within_range (oper, 0, 3);
  3165. case OPRND_TYPE_IMM2b_JMPIX:
  3166. /* ck802j support jmpix16, but not support jmpix32. */
  3167. if (IS_CSKY_ARCH_802 (mach_flag)
  3168. && (op->opcode & 0xffff0000) != 0)
  3169. {
  3170. SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL);
  3171. return false;
  3172. }
  3173. *oper = parse_exp (*oper, &csky_insn.e1);
  3174. if (csky_insn.e1.X_op == O_constant)
  3175. {
  3176. csky_insn.opcode_end = *oper;
  3177. if (csky_insn.e1.X_add_number & 0x7)
  3178. {
  3179. SET_ERROR_STRING (ERROR_JMPIX_OVER_RANGE, NULL);
  3180. return false;
  3181. }
  3182. csky_insn.val[csky_insn.idx++]
  3183. = (csky_insn.e1.X_add_number >> 3) - 2;
  3184. }
  3185. return true;
  3186. case OPRND_TYPE_IMM4b:
  3187. return is_imm_within_range (oper, 0, 15);
  3188. case OPRND_TYPE_IMM5b:
  3189. return is_imm_within_range (oper, 0, 31);
  3190. /* This type for "bgeni" in csky v1 ISA. */
  3191. case OPRND_TYPE_IMM5b_7_31:
  3192. if (is_imm_within_range (oper, 0, 31))
  3193. {
  3194. int val = csky_insn.val[csky_insn.idx - 1];
  3195. /* immediate values of 0 -> 6 translate to movi. */
  3196. if (val <= 6)
  3197. {
  3198. const char *name = "movi";
  3199. csky_insn.opcode = (struct csky_opcode *)
  3200. str_hash_find (csky_opcodes_hash, name);
  3201. csky_insn.val[csky_insn.idx - 1] = 1 << val;
  3202. }
  3203. return true;
  3204. }
  3205. else
  3206. return false;
  3207. case OPRND_TYPE_IMM5b_1_31:
  3208. return is_imm_within_range (oper, 1, 31);
  3209. case OPRND_TYPE_IMM5b_POWER:
  3210. if (is_imm_within_range_ext (oper, 1, (1u << 31) - 1, 1u << 31))
  3211. {
  3212. int log;
  3213. int val = csky_insn.val[csky_insn.idx - 1];
  3214. log = csky_log_2 (val);
  3215. csky_insn.val[csky_insn.idx - 1] = log;
  3216. return log != -1;
  3217. }
  3218. else
  3219. return false;
  3220. /* This type for "mgeni" in csky v1 ISA. */
  3221. case OPRND_TYPE_IMM5b_7_31_POWER:
  3222. if (is_imm_within_range_ext (oper, 1, (1u << 31) - 1, 1u << 31))
  3223. {
  3224. int log;
  3225. int val = csky_insn.val[csky_insn.idx - 1];
  3226. log = csky_log_2 (val);
  3227. /* Immediate values of 0 -> 6 translate to movi. */
  3228. if (log <= 6)
  3229. {
  3230. const char *name = "movi";
  3231. csky_insn.opcode = (struct csky_opcode *)
  3232. str_hash_find (csky_opcodes_hash, name);
  3233. as_warn (_("translating mgeni to movi"));
  3234. }
  3235. else
  3236. csky_insn.val[csky_insn.idx - 1] = log;
  3237. return log != -1;
  3238. }
  3239. else
  3240. return false;
  3241. case OPRND_TYPE_IMM5b_LS:
  3242. return is_imm_within_range (oper,
  3243. 0,
  3244. csky_insn.val[csky_insn.idx - 1]);
  3245. case OPRND_TYPE_IMM5b_RORI:
  3246. {
  3247. unsigned max_shift = IS_CSKY_V1 (mach_flag) ? 31 : 32;
  3248. if (is_imm_within_range (oper, 1, max_shift))
  3249. {
  3250. int i = csky_insn.idx - 1;
  3251. csky_insn.val[i] = 32 - csky_insn.val[i];
  3252. return true;
  3253. }
  3254. else
  3255. return false;
  3256. }
  3257. case OPRND_TYPE_IMM5b_BMASKI:
  3258. /* For csky v1 bmask inst. */
  3259. if (!is_imm_within_range_ext (oper, 8, 31, 0))
  3260. {
  3261. unsigned int mask_val = csky_insn.val[csky_insn.idx - 1];
  3262. if (mask_val > 0 && mask_val < 8)
  3263. {
  3264. const char *op_movi = "movi";
  3265. csky_insn.opcode = (struct csky_opcode *)
  3266. str_hash_find (csky_opcodes_hash, op_movi);
  3267. if (csky_insn.opcode == NULL)
  3268. return false;
  3269. csky_insn.val[csky_insn.idx - 1] = (1 << mask_val) - 1;
  3270. return true;
  3271. }
  3272. }
  3273. return true;
  3274. case OPRND_TYPE_IMM5b_VSH:
  3275. /* For vshri.T and vshli.T. */
  3276. if (is_imm_within_range (oper, 0, 31))
  3277. {
  3278. int val = csky_insn.val[csky_insn.idx - 1];
  3279. val = (val << 1) | (val >> 4);
  3280. val &= 0x1f;
  3281. csky_insn.val[csky_insn.idx - 1] = val;
  3282. return true;
  3283. }
  3284. return false;
  3285. case OPRND_TYPE_IMM8b_BMASKI:
  3286. /* For csky v2 bmask, which will transfer to 16bits movi. */
  3287. if (is_imm_within_range (oper, 1, 8))
  3288. {
  3289. unsigned int mask_val = csky_insn.val[csky_insn.idx - 1];
  3290. csky_insn.val[csky_insn.idx - 1] = (1 << mask_val) - 1;
  3291. return true;
  3292. }
  3293. return false;
  3294. case OPRND_TYPE_OIMM4b:
  3295. return is_oimm_within_range (oper, 1, 16);
  3296. case OPRND_TYPE_OIMM5b:
  3297. return is_oimm_within_range (oper, 1, 32);
  3298. case OPRND_TYPE_OIMM5b_IDLY:
  3299. if (is_imm_within_range (oper, 0, 32))
  3300. {
  3301. /* imm5b for idly n: 0<=n<4, imm5b=3; 4<=n<=32, imm5b=n-1. */
  3302. unsigned long imm = csky_insn.val[csky_insn.idx - 1];
  3303. if (imm < 4)
  3304. {
  3305. csky_show_error (WARNING_IDLY, 0, (void *)imm, NULL);
  3306. imm = 3;
  3307. }
  3308. else imm--;
  3309. csky_insn.val[csky_insn.idx - 1] = imm;
  3310. return true;
  3311. }
  3312. else
  3313. return false;
  3314. /* For csky v2 bmask inst. */
  3315. case OPRND_TYPE_OIMM5b_BMASKI:
  3316. if (!is_oimm_within_range (oper, 17, 32))
  3317. {
  3318. int mask_val = csky_insn.val[csky_insn.idx - 1];
  3319. if (mask_val + 1 == 0)
  3320. return true;
  3321. if (mask_val > 0 && mask_val < 16)
  3322. {
  3323. const char *op_movi = "movi";
  3324. csky_insn.opcode = (struct csky_opcode *)
  3325. str_hash_find (csky_opcodes_hash, op_movi);
  3326. if (csky_insn.opcode == NULL)
  3327. return false;
  3328. csky_insn.val[csky_insn.idx - 1] = (1 << (mask_val + 1)) - 1;
  3329. return true;
  3330. }
  3331. }
  3332. return true;
  3333. case OPRND_TYPE_IMM7b:
  3334. return is_imm_within_range (oper, 0, 127);
  3335. case OPRND_TYPE_IMM8b:
  3336. return is_imm_within_range (oper, 0, 255);
  3337. case OPRND_TYPE_IMM9b:
  3338. return is_imm_within_range (oper, -256, 255);
  3339. case OPRND_TYPE_IMM12b:
  3340. return is_imm_within_range (oper, 0, 4095);
  3341. case OPRND_TYPE_IMM15b:
  3342. return is_imm_within_range (oper, 0, 0xfffff);
  3343. case OPRND_TYPE_IMM16b:
  3344. return is_imm_within_range (oper, 0, 65535);
  3345. case OPRND_TYPE_OIMM16b:
  3346. return is_oimm_within_range (oper, 1, 65536);
  3347. case OPRND_TYPE_IMM32b:
  3348. {
  3349. expressionS e;
  3350. char *new_oper = parse_exp (*oper, &e);
  3351. if (e.X_op == O_constant)
  3352. {
  3353. *oper = new_oper;
  3354. csky_insn.val[csky_insn.idx++] = e.X_add_number;
  3355. return true;
  3356. }
  3357. return false;
  3358. }
  3359. case OPRND_TYPE_IMM16b_MOVIH:
  3360. case OPRND_TYPE_IMM16b_ORI:
  3361. {
  3362. bfd_reloc_code_real_type r = BFD_RELOC_NONE;
  3363. int len;
  3364. char *curr = *oper;
  3365. char * save = input_line_pointer;
  3366. /* get the reloc type, and set "@GOTxxx" as ' ' */
  3367. while (**oper != '@' && **oper != '\0')
  3368. *oper += 1;
  3369. if (**oper != '\0')
  3370. {
  3371. input_line_pointer = *oper;
  3372. lex_got (&r, &len);
  3373. while (*(*oper + len + 1) != '\0')
  3374. {
  3375. **oper = *(*oper + len + 1);
  3376. *(*oper + len + 1) = '\0';
  3377. *oper += 1;
  3378. }
  3379. **oper = '\0';
  3380. }
  3381. input_line_pointer = save;
  3382. *oper = parse_exp (curr, &csky_insn.e1);
  3383. return true;
  3384. }
  3385. case OPRND_TYPE_PSR_BITS_LIST:
  3386. {
  3387. int ret = true;
  3388. if (csky_insn.number == 0)
  3389. ret = false;
  3390. else
  3391. {
  3392. csky_insn.val[csky_insn.idx] = 0;
  3393. if (is_psr_bit (oper))
  3394. while (**oper == ',')
  3395. {
  3396. *oper += 1;
  3397. if (!is_psr_bit (oper))
  3398. {
  3399. ret = false;
  3400. break;
  3401. }
  3402. }
  3403. else
  3404. ret = false;
  3405. if (ret && IS_CSKY_V1 (mach_flag)
  3406. && csky_insn.val[csky_insn.idx] > 8)
  3407. ret = false;
  3408. }
  3409. if (!ret)
  3410. SET_ERROR_STRING (ERROR_OPERANDS_ILLEGAL, csky_insn.opcode_end);
  3411. return ret;
  3412. }
  3413. case OPRND_TYPE_RM:
  3414. {
  3415. /* FPU round mode. */
  3416. static const char *round_mode[] =
  3417. {
  3418. "rm_nearest",
  3419. "rm_zero",
  3420. "rm_posinf",
  3421. "rm_neginf",
  3422. NULL
  3423. };
  3424. int i;
  3425. for (i = 0; round_mode[i]; i++)
  3426. if (strncasecmp (*oper, round_mode[i], strlen (round_mode[i])) == 0)
  3427. {
  3428. *oper += strlen (round_mode[i]);
  3429. csky_insn.val[csky_insn.idx++] = i;
  3430. return true;
  3431. }
  3432. return false;
  3433. }
  3434. case OPRND_TYPE_REGLIST_COMMA:
  3435. case OPRND_TYPE_BRACKET:
  3436. /* TODO: using sub operand union. */
  3437. case OPRND_TYPE_ABRACKET:
  3438. /* TODO: using sub operand union. */
  3439. case OPRND_TYPE_REGLIST_DASH:
  3440. return is_reglist_legal (oper);
  3441. case OPRND_TYPE_FREGLIST_DASH:
  3442. return is_freglist_legal (oper);
  3443. case OPRND_TYPE_AREG_WITH_BRACKET:
  3444. {
  3445. int len;
  3446. int reg;
  3447. if (**oper != '(')
  3448. {
  3449. SET_ERROR_STRING (ERROR_MISSING_LBRACKET, NULL);
  3450. return false;
  3451. }
  3452. *oper += 1;
  3453. reg = csky_get_reg_val (*oper, &len);
  3454. if (reg == -1)
  3455. {
  3456. SET_ERROR_STRING (ERROR_EXP_GREG, NULL);
  3457. return false;
  3458. }
  3459. *oper += len;
  3460. if (**oper != ')')
  3461. {
  3462. SET_ERROR_STRING (ERROR_MISSING_RBRACKET, NULL);
  3463. return false;
  3464. }
  3465. *oper += 1;
  3466. csky_insn.val[csky_insn.idx++] = reg;
  3467. return true;
  3468. }
  3469. case OPRND_TYPE_REGsp:
  3470. return is_reg_sp (oper);
  3471. case OPRND_TYPE_REGbsp:
  3472. return is_reg_sp_with_bracket (oper);
  3473. /* For jmpi. */
  3474. case OPRND_TYPE_OFF8b:
  3475. case OPRND_TYPE_OFF16b:
  3476. *oper = parse_rt (*oper, 1, &csky_insn.e1, -1);
  3477. csky_insn.val[csky_insn.idx++] = 0;
  3478. return true;
  3479. case OPRND_TYPE_LABEL_WITH_BRACKET:
  3480. case OPRND_TYPE_CONSTANT:
  3481. case OPRND_TYPE_ELRW_CONSTANT:
  3482. if (**oper == '[')
  3483. csky_insn.val[csky_insn.idx++] = 0;
  3484. else
  3485. csky_insn.val[csky_insn.idx++] = NEED_OUTPUT_LITERAL;
  3486. *oper = parse_rt (*oper, 0, &csky_insn.e1, -1);
  3487. return true;
  3488. case OPRND_TYPE_FCONSTANT:
  3489. *oper = parse_rtf (*oper, 0, &csky_insn.e1);
  3490. return true;
  3491. case OPRND_TYPE_SFLOAT:
  3492. case OPRND_TYPE_DFLOAT:
  3493. /* For fmovis and fmovid, which accept a constant float with
  3494. a limited range. */
  3495. {
  3496. uint64_t dbnum;
  3497. int imm4, imm8;
  3498. *oper = parse_fexp (*oper, &csky_insn.e1, 1, &dbnum);
  3499. if (csky_insn.e1.X_op == O_absent)
  3500. return false;
  3501. /* Convert the representation from IEEE double to the 13-bit
  3502. encoding used internally for fmovis and fmovid. */
  3503. imm4 = 11 - (((dbnum & 0x7ff0000000000000ULL) >> 52) - 1023);
  3504. /* Check float range. */
  3505. if ((dbnum & 0x00000fffffffffffULL) || imm4 < 0 || imm4 > 15)
  3506. {
  3507. csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
  3508. return false;
  3509. }
  3510. imm8 = (dbnum & 0x000ff00000000000ULL) >> 44;
  3511. csky_insn.e1.X_add_number
  3512. = (((imm8 & 0xf) << 4)
  3513. | ((imm8 & 0xf0) << 17)
  3514. | ((imm4 & 0xf) << 16)
  3515. | ((dbnum & 0x8000000000000000ULL) >> 43));
  3516. return true;
  3517. }
  3518. case OPRND_TYPE_HFLOAT_FMOVI:
  3519. case OPRND_TYPE_SFLOAT_FMOVI:
  3520. case OPRND_TYPE_DFLOAT_FMOVI:
  3521. /* For fpuv3 fmovis and fmovid, which accept a constant
  3522. float with a limited range. */
  3523. {
  3524. uint64_t dbnum;
  3525. int imm4, imm8, sign;
  3526. *oper = parse_fexp (*oper, &csky_insn.e1, 1, &dbnum);
  3527. if (csky_insn.e1.X_op == O_absent)
  3528. return false;
  3529. /* Convert the representation from IEEE double to the 13-bit
  3530. encoding used internally for fmovis and fmovid. */
  3531. imm4 = 11 - (((dbnum & 0x7ff0000000000000ULL) >> 52) - 1023);
  3532. /* Check float range. */
  3533. if ((dbnum & 0x00000fffffffffffULL) || imm4 < 0 || imm4 > 15)
  3534. {
  3535. csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
  3536. return true;
  3537. }
  3538. imm8 = (dbnum & 0x000ff00000000000ULL) >> 44;
  3539. sign = (dbnum & 0x8000000000000000ULL) >> 58;
  3540. csky_insn.e1.X_add_number
  3541. = (((imm8 & 0x3) << 8)
  3542. | ((imm8 & 0xfc) << 18)
  3543. | ((imm4 & 0xf) << 16)
  3544. | sign);
  3545. return true;
  3546. }
  3547. /* For grs v2. */
  3548. case OPRND_TYPE_IMM_OFF18b:
  3549. *oper = parse_exp (*oper, &csky_insn.e1);
  3550. return true;
  3551. case OPRND_TYPE_BLOOP_OFF4b:
  3552. *oper = parse_exp (*oper, &csky_insn.e2);
  3553. if (csky_insn.e2.X_op == O_symbol)
  3554. {
  3555. csky_insn.opcode_end = *oper;
  3556. return true;
  3557. }
  3558. else
  3559. return false;
  3560. case OPRND_TYPE_BLOOP_OFF12b:
  3561. case OPRND_TYPE_OFF10b:
  3562. case OPRND_TYPE_OFF11b:
  3563. case OPRND_TYPE_OFF16b_LSL1:
  3564. case OPRND_TYPE_OFF26b:
  3565. *oper = parse_exp (*oper, &csky_insn.e1);
  3566. if (csky_insn.e1.X_op == O_symbol)
  3567. {
  3568. csky_insn.opcode_end = *oper;
  3569. return true;
  3570. }
  3571. else
  3572. return false;
  3573. /* For xtrb0(1)(2)(3) and div in csky v1 ISA. */
  3574. case OPRND_TYPE_REG_r1a:
  3575. {
  3576. int reg = 0;
  3577. int len = 0;
  3578. reg = csky_get_reg_val (*oper, &len);
  3579. if (reg == -1)
  3580. {
  3581. SET_ERROR_STRING (ERROR_REG_FORMAT,
  3582. "The first operand must be register r1.");
  3583. return false;
  3584. }
  3585. if (reg != 1)
  3586. mov_r1_after = true;
  3587. *oper += len;
  3588. csky_insn.opcode_end = *oper;
  3589. csky_insn.val[csky_insn.idx++] = reg;
  3590. return true;
  3591. }
  3592. case OPRND_TYPE_REG_r1b:
  3593. {
  3594. int reg = 0;
  3595. int len = 0;
  3596. reg = csky_get_reg_val (*oper, &len);
  3597. if (reg == -1)
  3598. {
  3599. SET_ERROR_STRING (ERROR_REG_FORMAT,
  3600. "The second operand must be register r1.");
  3601. return false;
  3602. }
  3603. if (reg != 1)
  3604. {
  3605. unsigned int mov_insn = CSKYV1_INST_MOV_R1_RX;
  3606. mov_insn |= reg << 4;
  3607. mov_r1_before = true;
  3608. csky_insn.output = frag_more (2);
  3609. dwarf2_emit_insn (0);
  3610. md_number_to_chars (csky_insn.output, mov_insn, 2);
  3611. }
  3612. *oper += len;
  3613. csky_insn.opcode_end = *oper;
  3614. csky_insn.val[csky_insn.idx++] = reg;
  3615. return true;
  3616. }
  3617. case OPRND_TYPE_DUMMY_REG:
  3618. {
  3619. int reg = 0;
  3620. int len = 0;
  3621. reg = csky_get_reg_val (*oper, &len);
  3622. if (reg == -1)
  3623. {
  3624. SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
  3625. return false;
  3626. }
  3627. if (reg != csky_insn.val[0])
  3628. {
  3629. SET_ERROR_STRING (ERROR_REG_FORMAT,
  3630. "The second register must be the same as the first.");
  3631. return false;
  3632. }
  3633. *oper += len;
  3634. csky_insn.opcode_end = *oper;
  3635. csky_insn.val[csky_insn.idx++] = reg;
  3636. return true;
  3637. }
  3638. case OPRND_TYPE_2IN1_DUMMY:
  3639. {
  3640. int reg = 0;
  3641. int len = 0;
  3642. int max = 0;
  3643. int min = 0;
  3644. reg = csky_get_reg_val (*oper, &len);
  3645. if (reg == -1)
  3646. {
  3647. SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
  3648. return false;
  3649. }
  3650. /* dummy reg's real type should be same with first operand. */
  3651. if (op->oprnd.oprnds[0].type == OPRND_TYPE_GREG0_15)
  3652. max = 15;
  3653. else if (op->oprnd.oprnds[0].type == OPRND_TYPE_GREG0_7)
  3654. max = 7;
  3655. else
  3656. return false;
  3657. if (reg < min || reg > max)
  3658. return false;
  3659. csky_insn.val[csky_insn.idx++] = reg;
  3660. /* if it is the last operands. */
  3661. if (csky_insn.idx > 2)
  3662. {
  3663. /* For "insn rz, rx, ry", if rx or ry is equal to rz,
  3664. we can output the insn like "insn rz, rx". */
  3665. if (csky_insn.val[0] == csky_insn.val[1])
  3666. csky_insn.val[1] = 0;
  3667. else if (csky_insn.val[0] == csky_insn.val[2])
  3668. csky_insn.val[2] = 0;
  3669. else
  3670. return false;
  3671. }
  3672. *oper += len;
  3673. csky_insn.opcode_end = *oper;
  3674. return true;
  3675. }
  3676. case OPRND_TYPE_DUP_GREG0_7:
  3677. case OPRND_TYPE_DUP_GREG0_15:
  3678. case OPRND_TYPE_DUP_AREG:
  3679. {
  3680. long reg = 0;
  3681. int len = 0;
  3682. long max_reg;
  3683. unsigned int shift_num;
  3684. if (oprnd->type == OPRND_TYPE_DUP_GREG0_7)
  3685. {
  3686. max_reg = 7;
  3687. shift_num = 3;
  3688. }
  3689. else if (oprnd->type == OPRND_TYPE_DUP_GREG0_15)
  3690. {
  3691. max_reg = 15;
  3692. shift_num = 4;
  3693. }
  3694. else
  3695. {
  3696. max_reg = 31;
  3697. shift_num = 5;
  3698. }
  3699. reg = csky_get_reg_val (*oper, &len);
  3700. if (reg == -1)
  3701. {
  3702. if (max_reg == 31)
  3703. SET_ERROR_STRING (ERROR_REG_FORMAT,
  3704. "The register must be r0-r31");
  3705. else
  3706. SET_ERROR_STRING (ERROR_REG_FORMAT,
  3707. "The register must be r0-r15");
  3708. return false;
  3709. }
  3710. if (reg > max_reg)
  3711. {
  3712. SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg);
  3713. return false;
  3714. }
  3715. reg |= reg << shift_num;
  3716. *oper += len;
  3717. csky_insn.opcode_end = *oper;
  3718. csky_insn.val[csky_insn.idx++] = reg;
  3719. return true;
  3720. }
  3721. case OPRND_TYPE_CONST1:
  3722. *oper = parse_exp (*oper, &csky_insn.e1);
  3723. if (csky_insn.e1.X_op == O_constant)
  3724. {
  3725. csky_insn.opcode_end = *oper;
  3726. if (csky_insn.e1.X_add_number != 1)
  3727. return false;
  3728. csky_insn.val[csky_insn.idx++] = 1;
  3729. return true;
  3730. }
  3731. return false;
  3732. case OPRND_TYPE_UNCOND10b:
  3733. case OPRND_TYPE_UNCOND16b:
  3734. *oper = parse_exp (*oper, &csky_insn.e1);
  3735. if (csky_insn.e1.X_op == O_constant)
  3736. return false;
  3737. input_line_pointer = *oper;
  3738. csky_insn.opcode_end = *oper;
  3739. csky_insn.relax.max = UNCD_DISP16_LEN;
  3740. csky_insn.relax.var = UNCD_DISP10_LEN;
  3741. csky_insn.relax.subtype = UNCD_DISP10;
  3742. csky_insn.val[csky_insn.idx++] = 0;
  3743. return true;
  3744. case OPRND_TYPE_COND10b:
  3745. case OPRND_TYPE_COND16b:
  3746. *oper = parse_exp (*oper, &csky_insn.e1);
  3747. if (csky_insn.e1.X_op == O_constant)
  3748. return false;
  3749. input_line_pointer = *oper;
  3750. csky_insn.opcode_end = *oper;
  3751. /* CK801 doesn't have 32-bit bt/bf insns; relax to a short
  3752. jump around a 32-bit unconditional branch instead. */
  3753. if (IS_CSKY_ARCH_801 (mach_flag))
  3754. {
  3755. csky_insn.relax.max = SCOND_DISP16_LEN;
  3756. csky_insn.relax.var = SCOND_DISP10_LEN;
  3757. csky_insn.relax.subtype = SCOND_DISP10;
  3758. }
  3759. else
  3760. {
  3761. csky_insn.relax.max = COND_DISP16_LEN;
  3762. csky_insn.relax.var = COND_DISP10_LEN;
  3763. csky_insn.relax.subtype = COND_DISP10;
  3764. }
  3765. csky_insn.val[csky_insn.idx++] = 0;
  3766. return true;
  3767. case OPRND_TYPE_JCOMPZ:
  3768. *oper = parse_exp (*oper, &csky_insn.e1);
  3769. if (csky_insn.e1.X_op == O_constant)
  3770. return false;
  3771. input_line_pointer = *oper;
  3772. csky_insn.opcode_end = *oper;
  3773. csky_insn.relax.max = JCOMPZ_DISP32_LEN;
  3774. csky_insn.relax.var = JCOMPZ_DISP16_LEN;
  3775. csky_insn.relax.subtype = JCOMPZ_DISP16;
  3776. csky_insn.max = JCOMPZ_DISP32_LEN;
  3777. csky_insn.val[csky_insn.idx++] = 0;
  3778. return true;
  3779. case OPRND_TYPE_JBTF:
  3780. *oper = parse_exp (*oper, &csky_insn.e1);
  3781. input_line_pointer = *oper;
  3782. csky_insn.opcode_end = *oper;
  3783. csky_insn.relax.max = csky_relax_table[C (COND_JUMP_S, DISP32)].rlx_length;
  3784. csky_insn.relax.var = csky_relax_table[C (COND_JUMP_S, DISP12)].rlx_length;
  3785. csky_insn.relax.subtype = C (COND_JUMP_S, 0);
  3786. csky_insn.val[csky_insn.idx++] = 0;
  3787. csky_insn.max = C32_LEN_S + 2;
  3788. return true;
  3789. case OPRND_TYPE_JBR:
  3790. *oper = parse_exp (*oper, &csky_insn.e1);
  3791. input_line_pointer = *oper;
  3792. csky_insn.opcode_end = *oper;
  3793. csky_insn.relax.max = csky_relax_table[C (UNCD_JUMP_S, DISP32)].rlx_length;
  3794. csky_insn.relax.var = csky_relax_table[C (UNCD_JUMP_S, DISP12)].rlx_length;
  3795. csky_insn.relax.subtype = C (UNCD_JUMP_S, 0);
  3796. csky_insn.val[csky_insn.idx++] = 0;
  3797. csky_insn.max = U32_LEN_S + 2;
  3798. return true;
  3799. case OPRND_TYPE_JBSR:
  3800. if (do_force2bsr)
  3801. *oper = parse_exp (*oper, &csky_insn.e1);
  3802. else
  3803. *oper = parse_rt (*oper, 1, &csky_insn.e1, -1);
  3804. input_line_pointer = *oper;
  3805. csky_insn.opcode_end = *oper;
  3806. csky_insn.val[csky_insn.idx++] = 0;
  3807. return true;
  3808. case OPRND_TYPE_REGLIST_DASH_COMMA:
  3809. return is_reglist_dash_comma_legal (oper, oprnd);
  3810. case OPRND_TYPE_MSB2SIZE:
  3811. case OPRND_TYPE_LSB2SIZE:
  3812. {
  3813. expressionS e;
  3814. char *new_oper = parse_exp (*oper, &e);
  3815. if (e.X_op == O_constant)
  3816. {
  3817. *oper = new_oper;
  3818. if (e.X_add_number > 31)
  3819. {
  3820. SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
  3821. return false;
  3822. }
  3823. csky_insn.val[csky_insn.idx++] = e.X_add_number;
  3824. if (oprnd->type == OPRND_TYPE_LSB2SIZE)
  3825. {
  3826. if (csky_insn.val[csky_insn.idx - 1] > csky_insn.val[csky_insn.idx - 2])
  3827. {
  3828. SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
  3829. return false;
  3830. }
  3831. csky_insn.val[csky_insn.idx - 2] -= e.X_add_number;
  3832. }
  3833. return true;
  3834. }
  3835. return false;
  3836. }
  3837. case OPRND_TYPE_AREG_WITH_LSHIFT:
  3838. return is_reg_lshift_illegal (oper, 0);
  3839. case OPRND_TYPE_AREG_WITH_LSHIFT_FPU:
  3840. return is_reg_lshift_illegal (oper, 1);
  3841. case OPRND_TYPE_FREG_WITH_INDEX:
  3842. case OPRND_TYPE_VREG_WITH_INDEX:
  3843. if (parse_type_freg (oper, 0))
  3844. {
  3845. if (**oper == '[')
  3846. {
  3847. (*oper)++;
  3848. if (is_imm_within_range (oper, 0, 0xf))
  3849. {
  3850. if (**oper == ']')
  3851. {
  3852. unsigned int idx = --csky_insn.idx;
  3853. unsigned int val = csky_insn.val[idx];
  3854. (*oper)++;
  3855. csky_insn.val[idx - 1] |= val << 4;
  3856. return true;
  3857. }
  3858. else
  3859. SET_ERROR_STRING (ERROR_MISSING_RSQUARE_BRACKETS, NULL);
  3860. }
  3861. }
  3862. else
  3863. SET_ERROR_STRING (ERROR_MISSING_LSQUARE_BRACKETS, NULL);
  3864. }
  3865. return false;
  3866. default:
  3867. break;
  3868. /* error code. */
  3869. }
  3870. return false;
  3871. }
  3872. /* Subroutine of parse_operands. */
  3873. static bool
  3874. parse_operands_op (char *str, struct csky_opcode_info *op)
  3875. {
  3876. int i;
  3877. int j;
  3878. char *oper = str;
  3879. int flag_pass;
  3880. for (i = 0; i < OP_TABLE_NUM && op[i].operand_num != -2; i++)
  3881. {
  3882. flag_pass = true;
  3883. csky_insn.idx = 0;
  3884. oper = str;
  3885. /* if operand_num = -1, it is a insn with a REGLIST type operand.i. */
  3886. if (!(op[i].operand_num == csky_insn.number
  3887. || (op[i].operand_num == -1 && csky_insn.number != 0)))
  3888. {
  3889. /* The smaller err_num is more serious. */
  3890. SET_ERROR_INTEGER (ERROR_OPERANDS_NUMBER, op[i].operand_num);
  3891. flag_pass = false;
  3892. continue;
  3893. }
  3894. for (j = 0; j < csky_insn.number; j++)
  3895. {
  3896. while (ISSPACE (*oper))
  3897. oper++;
  3898. flag_pass = get_operand_value (&op[i], &oper,
  3899. &op[i].oprnd.oprnds[j]);
  3900. if (!flag_pass)
  3901. break;
  3902. while (ISSPACE (*oper))
  3903. oper++;
  3904. /* Skip the ','. */
  3905. if (j < csky_insn.number - 1 && op[i].operand_num != -1)
  3906. {
  3907. if (*oper == ',')
  3908. oper++;
  3909. else
  3910. {
  3911. SET_ERROR_STRING (ERROR_MISSING_COMMA, NULL);
  3912. flag_pass = false;
  3913. break;
  3914. }
  3915. }
  3916. else if (!is_end_of_line[(unsigned char) *oper])
  3917. {
  3918. SET_ERROR_STRING (ERROR_BAD_END, NULL);
  3919. flag_pass = false;
  3920. break;
  3921. }
  3922. else
  3923. break;
  3924. }
  3925. /* Parse operands in one table end. */
  3926. if (flag_pass)
  3927. {
  3928. /* Parse operands success, set opcode_idx. */
  3929. csky_insn.opcode_idx = i;
  3930. return true;
  3931. }
  3932. else
  3933. error_state.opnum = j + 1;
  3934. }
  3935. /* Parse operands in ALL tables end. */
  3936. return false;
  3937. }
  3938. /* Parse the operands according to operand type. */
  3939. static bool
  3940. parse_operands (char *str)
  3941. {
  3942. char *oper = str;
  3943. /* Parse operands according to flag_force. */
  3944. if (csky_insn.flag_force == INSN_OPCODE16F
  3945. && (csky_insn.opcode->isa_flag16 & isa_flag) != 0)
  3946. {
  3947. if (parse_operands_op (oper, csky_insn.opcode->op16))
  3948. {
  3949. csky_insn.isize = 2;
  3950. return true;
  3951. }
  3952. return false;
  3953. }
  3954. else if (csky_insn.flag_force == INSN_OPCODE32F
  3955. && (csky_insn.opcode->isa_flag32 & isa_flag) != 0)
  3956. {
  3957. if (parse_operands_op (oper, csky_insn.opcode->op32))
  3958. {
  3959. csky_insn.isize = 4;
  3960. return true;
  3961. }
  3962. return false;
  3963. }
  3964. else
  3965. {
  3966. if ((csky_insn.opcode->isa_flag16 & isa_flag) != 0
  3967. && parse_operands_op (oper, csky_insn.opcode->op16))
  3968. {
  3969. csky_insn.isize = 2;
  3970. return true;
  3971. }
  3972. if ((csky_insn.opcode->isa_flag32 & isa_flag) != 0
  3973. && parse_operands_op (oper, csky_insn.opcode->op32))
  3974. {
  3975. csky_insn.isize = 4;
  3976. return true;
  3977. }
  3978. return false;
  3979. }
  3980. }
  3981. static bool
  3982. csky_generate_frags (void)
  3983. {
  3984. /* frag more relax reloc. */
  3985. if (csky_insn.flag_force == INSN_OPCODE16F
  3986. || !IS_SUPPORT_OPCODE32 (csky_insn.opcode))
  3987. {
  3988. csky_insn.output = frag_more (csky_insn.isize);
  3989. if (csky_insn.opcode->reloc16)
  3990. {
  3991. /* 16 bits opcode force, should generate fixup. */
  3992. reloc_howto_type *howto;
  3993. howto = bfd_reloc_type_lookup (stdoutput,
  3994. csky_insn.opcode->reloc16);
  3995. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  3996. 2, &csky_insn.e1, howto->pc_relative,
  3997. csky_insn.opcode->reloc16);
  3998. }
  3999. }
  4000. else if (csky_insn.flag_force == INSN_OPCODE32F)
  4001. {
  4002. csky_insn.output = frag_more (csky_insn.isize);
  4003. if (csky_insn.opcode->reloc32)
  4004. {
  4005. reloc_howto_type *howto;
  4006. howto = bfd_reloc_type_lookup (stdoutput,
  4007. csky_insn.opcode->reloc32);
  4008. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  4009. 4, &csky_insn.e1, howto->pc_relative,
  4010. csky_insn.opcode->reloc32);
  4011. }
  4012. }
  4013. else if (csky_insn.opcode->relax)
  4014. /* Generate the relax information. */
  4015. csky_insn.output = frag_var (rs_machine_dependent,
  4016. csky_insn.relax.max,
  4017. csky_insn.relax.var,
  4018. csky_insn.relax.subtype,
  4019. csky_insn.e1.X_add_symbol,
  4020. csky_insn.e1.X_add_number, 0);
  4021. else
  4022. {
  4023. csky_insn.output = frag_more (csky_insn.isize);
  4024. if (csky_insn.opcode->reloc16 && csky_insn.isize == 2)
  4025. {
  4026. reloc_howto_type *howto;
  4027. howto = bfd_reloc_type_lookup (stdoutput,
  4028. csky_insn.opcode->reloc16);
  4029. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  4030. 2, &csky_insn.e1, howto->pc_relative,
  4031. csky_insn.opcode->reloc16);
  4032. }
  4033. else if (csky_insn.opcode->reloc32 && csky_insn.isize == 4)
  4034. {
  4035. reloc_howto_type *howto;
  4036. howto = bfd_reloc_type_lookup (stdoutput,
  4037. csky_insn.opcode->reloc32);
  4038. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  4039. 4, &csky_insn.e1, howto->pc_relative,
  4040. csky_insn.opcode->reloc32);
  4041. }
  4042. }
  4043. return true;
  4044. }
  4045. /* Return the bits of VAL shifted according to MASK. The bits of MASK
  4046. need not be contiguous. */
  4047. static int
  4048. generate_masked_value (int mask, int val)
  4049. {
  4050. int ret = 0;
  4051. int bit;
  4052. for (bit = 1; mask; bit = bit << 1)
  4053. if (mask & bit)
  4054. {
  4055. if (val & 0x1)
  4056. ret |= bit;
  4057. val = val >> 1;
  4058. mask &= ~bit;
  4059. }
  4060. return ret;
  4061. }
  4062. /* Return the result of masking operand number OPRND_IDX into the
  4063. instruction word according to the information in OPRND. */
  4064. static int
  4065. generate_masked_operand (struct operand *oprnd, int *oprnd_idx)
  4066. {
  4067. struct soperand *soprnd = NULL;
  4068. int mask;
  4069. int val;
  4070. if ((unsigned int)oprnd->mask == HAS_SUB_OPERAND)
  4071. {
  4072. soprnd = (struct soperand *) oprnd;
  4073. generate_masked_operand (&soprnd->subs[0], oprnd_idx);
  4074. generate_masked_operand (&soprnd->subs[1], oprnd_idx);
  4075. return 0;
  4076. }
  4077. mask = oprnd->mask;
  4078. val = csky_insn.val[*oprnd_idx];
  4079. (*oprnd_idx)++;
  4080. val = generate_masked_value (mask, val);
  4081. csky_insn.inst |= val;
  4082. return 0;
  4083. }
  4084. static bool
  4085. csky_generate_insn (void)
  4086. {
  4087. int i = 0;
  4088. struct csky_opcode_info *opinfo = NULL;
  4089. if (csky_insn.isize == 4)
  4090. opinfo = &csky_insn.opcode->op32[csky_insn.opcode_idx];
  4091. else if (csky_insn.isize == 2)
  4092. opinfo = &csky_insn.opcode->op16[csky_insn.opcode_idx];
  4093. int sidx = 0;
  4094. csky_insn.inst = opinfo->opcode;
  4095. if (opinfo->operand_num == -1)
  4096. {
  4097. generate_masked_operand (&opinfo->oprnd.oprnds[i], &sidx);
  4098. return 0;
  4099. }
  4100. else
  4101. for (i = 0; i < opinfo->operand_num; i++)
  4102. generate_masked_operand (&opinfo->oprnd.oprnds[i], &sidx);
  4103. return 0;
  4104. }
  4105. /* Main entry point for assembling a single instruction. */
  4106. void
  4107. md_assemble (char *str)
  4108. {
  4109. bool must_check_literals = true;
  4110. csky_insn.isize = 0;
  4111. csky_insn.idx = 0;
  4112. csky_insn.max = 0;
  4113. csky_insn.flag_force = INSN_OPCODE;
  4114. csky_insn.macro = NULL;
  4115. csky_insn.opcode = NULL;
  4116. memset (csky_insn.val, 0, sizeof (int) * MAX_OPRND_NUM);
  4117. /* Initialize err_num. */
  4118. error_state.err_num = ERROR_NONE;
  4119. mov_r1_before = false;
  4120. mov_r1_after = false;
  4121. mapping_state (MAP_TEXT);
  4122. /* Tie dwarf2 debug info to every insn if set option --gdwarf2. */
  4123. dwarf2_emit_insn (0);
  4124. while (ISSPACE (* str))
  4125. str++;
  4126. /* Get opcode from str. */
  4127. if (!parse_opcode (str))
  4128. {
  4129. csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
  4130. return;
  4131. }
  4132. /* If it is a macro instruction, handle it. */
  4133. if (csky_insn.macro != NULL)
  4134. {
  4135. if (csky_insn.number == csky_insn.macro->oprnd_num)
  4136. {
  4137. csky_insn.macro->handle_func ();
  4138. return;
  4139. }
  4140. else if (error_state.err_num > ERROR_OPERANDS_NUMBER)
  4141. SET_ERROR_STRING (ERROR_OPERANDS_NUMBER, csky_insn.macro->oprnd_num);
  4142. }
  4143. if (csky_insn.opcode == NULL)
  4144. {
  4145. SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL);
  4146. csky_show_error (error_state.err_num, error_state.opnum,
  4147. (void *)error_state.arg1, (void *)error_state.arg1);
  4148. return;
  4149. }
  4150. /* Parse the operands according to operand type. */
  4151. if (!parse_operands (csky_insn.opcode_end))
  4152. {
  4153. csky_show_error (error_state.err_num, error_state.opnum,
  4154. (void *)error_state.arg1, (void *)error_state.arg1);
  4155. return;
  4156. }
  4157. error_state.err_num = ERROR_NONE;
  4158. /* if this insn has work in opcode table, then do it. */
  4159. if (csky_insn.opcode->work != NULL)
  4160. must_check_literals = csky_insn.opcode->work ();
  4161. else
  4162. {
  4163. /* Generate relax or reloc if necessary. */
  4164. csky_generate_frags ();
  4165. /* Generate the insn by mask. */
  4166. csky_generate_insn ();
  4167. /* Write inst to frag. */
  4168. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  4169. }
  4170. /* Adjust for xtrb0/xtrb1/xtrb2/xtrb3/divs/divu in csky v1 ISA. */
  4171. if (mov_r1_after)
  4172. {
  4173. unsigned int mov_insn = CSKYV1_INST_MOV_RX_R1;
  4174. mov_insn |= csky_insn.val[0];
  4175. mov_r1_before = true;
  4176. csky_insn.output = frag_more (2);
  4177. dwarf2_emit_insn (0);
  4178. md_number_to_chars (csky_insn.output, mov_insn, 2);
  4179. csky_insn.isize += 2;
  4180. }
  4181. if (mov_r1_before)
  4182. csky_insn.isize += 2;
  4183. /* Check literal. */
  4184. if (must_check_literals)
  4185. {
  4186. if (csky_insn.max == 0)
  4187. check_literals (csky_insn.opcode->transfer, csky_insn.isize);
  4188. else
  4189. check_literals (csky_insn.opcode->transfer, csky_insn.max);
  4190. }
  4191. csky_insn.last_isize = csky_insn.isize;
  4192. insn_reloc = BFD_RELOC_NONE;
  4193. }
  4194. /* Attempt to handle option with value C, returning non-zero on success. */
  4195. int
  4196. md_parse_option (int c, const char *arg)
  4197. {
  4198. switch (c)
  4199. {
  4200. case 0:
  4201. break;
  4202. case OPTION_MARCH:
  4203. parse_arch (arg);
  4204. break;
  4205. case OPTION_MCPU:
  4206. parse_cpu (arg);
  4207. break;
  4208. case OPTION_FLOAT_ABI:
  4209. parse_float_abi (arg);
  4210. break;
  4211. default:
  4212. return 0;
  4213. }
  4214. return 1;
  4215. }
  4216. /* Convert a machine dependent frag. */
  4217. #define PAD_LITERAL_LENGTH 6
  4218. #define opposite_of_stored_comp(insn) (insn ^ 0x04000000)
  4219. #define opposite_of_stored_compz(insn) (insn ^ 0x00200000)
  4220. #define make_insn(total_length, opcode, operand, operand_length) \
  4221. do { \
  4222. if (total_length > 0) \
  4223. { \
  4224. csky_write_insn (buf, \
  4225. opcode | (operand & ((1 << operand_length) - 1)), \
  4226. total_length); \
  4227. buf += total_length; \
  4228. fragp->fr_fix += total_length; \
  4229. } \
  4230. } while (0)
  4231. #define make_literal(fragp, literal_offset) \
  4232. do { \
  4233. make_insn (literal_offset, PAD_FILL_CONTENT, 0, 0); \
  4234. fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, \
  4235. fragp->fr_offset, 0, BFD_RELOC_CKCORE_ADDR32); \
  4236. make_insn (4, 0, 0, 0); \
  4237. make_insn (2 - literal_offset, PAD_FILL_CONTENT, 0, 0); \
  4238. } while (0)
  4239. void
  4240. md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
  4241. {
  4242. offsetT disp;
  4243. char *buf = fragp->fr_fix + &fragp->fr_literal[0];
  4244. gas_assert (fragp->fr_symbol);
  4245. if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
  4246. disp = 0;
  4247. else
  4248. disp = (S_GET_VALUE (fragp->fr_symbol)
  4249. + fragp->fr_offset
  4250. - fragp->fr_address
  4251. - fragp->fr_fix);
  4252. switch (fragp->fr_subtype)
  4253. {
  4254. /* generate new insn. */
  4255. case C (COND_JUMP, DISP12):
  4256. case C (UNCD_JUMP, DISP12):
  4257. case C (COND_JUMP_PIC, DISP12):
  4258. case C (UNCD_JUMP_PIC, DISP12):
  4259. {
  4260. #define CSKY_V1_B_MASK 0xf8
  4261. unsigned char t0;
  4262. disp -= 2;
  4263. if (disp & 1)
  4264. {
  4265. /* Error. odd displacement at %x, next_inst-2. */
  4266. ;
  4267. }
  4268. disp >>= 1;
  4269. if (!target_big_endian)
  4270. {
  4271. t0 = buf[1] & CSKY_V1_B_MASK;
  4272. md_number_to_chars (buf, disp, 2);
  4273. buf[1] = (buf[1] & ~CSKY_V1_B_MASK) | t0;
  4274. }
  4275. else
  4276. {
  4277. t0 = buf[0] & CSKY_V1_B_MASK;
  4278. md_number_to_chars (buf, disp, 2);
  4279. buf[0] = (buf[0] & ~CSKY_V1_B_MASK) | t0;
  4280. }
  4281. fragp->fr_fix += 2;
  4282. break;
  4283. }
  4284. case C (COND_JUMP, DISP32):
  4285. case C (COND_JUMP, UNDEF_WORD_DISP):
  4286. {
  4287. /* A conditional branch wont fit into 12 bits:
  4288. b!cond 1f
  4289. jmpi 0f
  4290. .align 2
  4291. 0: .long disp
  4292. 1:
  4293. */
  4294. int first_inst = fragp->fr_fix + fragp->fr_address;
  4295. int is_unaligned = (first_inst & 3);
  4296. if (!target_big_endian)
  4297. {
  4298. /* b!cond instruction. */
  4299. buf[1] ^= 0x08;
  4300. /* jmpi instruction. */
  4301. buf[2] = CSKYV1_INST_JMPI & 0xff;
  4302. buf[3] = CSKYV1_INST_JMPI >> 8;
  4303. }
  4304. else
  4305. {
  4306. /* b!cond instruction. */
  4307. buf[0] ^= 0x08;
  4308. /* jmpi instruction. */
  4309. buf[2] = CSKYV1_INST_JMPI >> 8;
  4310. buf[3] = CSKYV1_INST_JMPI & 0xff;
  4311. }
  4312. if (is_unaligned)
  4313. {
  4314. if (!target_big_endian)
  4315. {
  4316. /* bt/bf: jump to pc + 2 + (4 << 1). */
  4317. buf[0] = 4;
  4318. /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
  4319. buf[2] = 1;
  4320. }
  4321. else
  4322. {
  4323. /* bt/bf: jump to pc + 2 + (4 << 1). */
  4324. buf[1] = 4;
  4325. /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
  4326. buf[3] = 1;
  4327. }
  4328. /* Aligned 4 bytes. */
  4329. buf[4] = 0;
  4330. buf[5] = 0;
  4331. /* .long */
  4332. buf[6] = 0;
  4333. buf[7] = 0;
  4334. buf[8] = 0;
  4335. buf[9] = 0;
  4336. /* Make reloc for the long disp. */
  4337. fix_new (fragp, fragp->fr_fix + 6, 4,
  4338. fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
  4339. fragp->fr_fix += C32_LEN;
  4340. }
  4341. else
  4342. {
  4343. if (!target_big_endian)
  4344. {
  4345. /* bt/bf: jump to pc + 2 + (3 << 1). */
  4346. buf[0] = 3;
  4347. /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
  4348. buf[2] = 0;
  4349. }
  4350. else
  4351. {
  4352. /* bt/bf: jump to pc + 2 + (3 << 1). */
  4353. buf[1] = 3;
  4354. /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
  4355. buf[3] = 0;
  4356. }
  4357. /* .long */
  4358. buf[4] = 0;
  4359. buf[5] = 0;
  4360. buf[6] = 0;
  4361. buf[7] = 0;
  4362. /* Make reloc for the long disp. */
  4363. fix_new (fragp, fragp->fr_fix + 4, 4,
  4364. fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
  4365. fragp->fr_fix += C32_LEN;
  4366. /* Frag is actually shorter (see the other side of this ifdef)
  4367. but gas isn't prepared for that. We have to re-adjust
  4368. the branch displacement so that it goes beyond the
  4369. full length of the fragment, not just what we actually
  4370. filled in. */
  4371. if (!target_big_endian)
  4372. buf[0] = 4;
  4373. else
  4374. buf[1] = 4;
  4375. }
  4376. }
  4377. break;
  4378. case C (COND_JUMP_PIC, DISP32):
  4379. case C (COND_JUMP_PIC, UNDEF_WORD_DISP):
  4380. {
  4381. #define BYTE_1(a) (target_big_endian ? ((a) & 0xff) : ((a) >> 8))
  4382. #define BYTE_0(a) (target_big_endian ? ((a) >> 8) : ((a) & 0xff))
  4383. /* b!cond 1f
  4384. subi sp, 8
  4385. stw r15, (sp, 0)
  4386. bsr .L0
  4387. .L0:
  4388. lrw r1, 0f
  4389. add r1, r15
  4390. addi sp, 8
  4391. jmp r1
  4392. .align 2
  4393. 0: .long (tar_addr - pc)
  4394. 1:
  4395. */
  4396. int first_inst = fragp->fr_fix + fragp->fr_address;
  4397. int is_unaligned = (first_inst & 3);
  4398. disp -= 8;
  4399. /* Toggle T/F bit. */
  4400. if (! target_big_endian)
  4401. buf[1] ^= 0x08;
  4402. else
  4403. buf[0] ^= 0x08;
  4404. buf[2] = BYTE_0 (CSKYV1_INST_SUBI | (7 << 4)); /* subi r0, 8. */
  4405. buf[3] = BYTE_1 (CSKYV1_INST_SUBI | (7 << 4));
  4406. buf[4] = BYTE_0 (CSKYV1_INST_STW | (15 << 8)); /* stw r15, r0. */
  4407. buf[5] = BYTE_1 (CSKYV1_INST_STW | (15 << 8));
  4408. buf[6] = BYTE_0 (CSKYV1_INST_BSR); /* bsr pc + 2. */
  4409. buf[7] = BYTE_1 (CSKYV1_INST_BSR);
  4410. buf[8] = BYTE_0 (CSKYV1_INST_LRW | (1 << 8)); /* lrw r1, (tar_addr - pc). */
  4411. buf[9] = BYTE_1 (CSKYV1_INST_LRW | (1 << 8));
  4412. buf[10] = BYTE_0 (CSKYV1_INST_ADDU | (15 << 4) | 1); /* add r1, r15. */
  4413. buf[11] = BYTE_1 (CSKYV1_INST_ADDU | (15 << 4) | 1);
  4414. buf[12] = BYTE_0 (CSKYV1_INST_LDW | (15 << 8)); /* ldw r15, r0. */
  4415. buf[13] = BYTE_1 (CSKYV1_INST_LDW | (15 << 8));
  4416. buf[14] = BYTE_0 (CSKYV1_INST_ADDI | (7 << 4)); /* addi r0, 8. */
  4417. buf[15] = BYTE_1 (CSKYV1_INST_ADDI | (7 << 4));
  4418. buf[16] = BYTE_0 (CSKYV1_INST_JMP | 1); /* jmp r1. */
  4419. buf[17] = BYTE_1 (CSKYV1_INST_JMP | 1);
  4420. if (!is_unaligned)
  4421. {
  4422. if (!target_big_endian)
  4423. {
  4424. buf[0] = 11;
  4425. buf[8] = 3;
  4426. buf[20] = disp & 0xff;
  4427. buf[21] = (disp >> 8) & 0xff;
  4428. buf[22] = (disp >> 16) & 0xff;
  4429. buf[23] = (disp >> 24) & 0xff;
  4430. }
  4431. else /* if !target_big_endian. */
  4432. {
  4433. buf[1] = 11;
  4434. buf[9] = 3;
  4435. buf[20] = (disp >> 24) & 0xff;
  4436. buf[21] = (disp >> 16) & 0xff;
  4437. buf[22] = (disp >> 8) & 0xff;
  4438. buf[23] = disp & 0xff;
  4439. }
  4440. buf[18] = 0; /* alignment. */
  4441. buf[19] = 0;
  4442. fragp->fr_fix += C32_LEN_PIC;
  4443. }
  4444. else /* if !is_unaligned. */
  4445. {
  4446. if (!target_big_endian)
  4447. {
  4448. buf[0] = 11;
  4449. buf[8] = 2;
  4450. buf[18] = disp & 0xff;
  4451. buf[19] = (disp >> 8) & 0xff;
  4452. buf[20] = (disp >> 16) & 0xff;
  4453. buf[21] = (disp >> 24) & 0xff;
  4454. }
  4455. else /* if !target_big_endian. */
  4456. {
  4457. buf[1] = 11;
  4458. buf[9] = 2;
  4459. buf[18] = (disp >> 24) & 0xff;
  4460. buf[19] = (disp >> 16) & 0xff;
  4461. buf[20] = (disp >> 8) & 0xff;
  4462. buf[21] = disp & 0xff;
  4463. }
  4464. buf[22] = 0; /* initialise. */
  4465. buf[23] = 0;
  4466. fragp->fr_fix += C32_LEN_PIC;
  4467. } /* end if is_unaligned. */
  4468. } /* end case C (COND_JUMP_PIC, DISP32)/C (COND_JUMP_PIC, UNDEF_WORD_DISP). */
  4469. break;
  4470. case C (UNCD_JUMP, DISP32):
  4471. case C (UNCD_JUMP, UNDEF_WORD_DISP):
  4472. {
  4473. /* jmpi 0f
  4474. .align 2
  4475. 0: .long disp. */
  4476. int first_inst = fragp->fr_fix + fragp->fr_address;
  4477. int is_unaligned = (first_inst & 3);
  4478. /* Build jmpi. */
  4479. buf[0] = BYTE_0 (CSKYV1_INST_JMPI);
  4480. buf[1] = BYTE_1 (CSKYV1_INST_JMPI);
  4481. if (!is_unaligned)
  4482. {
  4483. if (!target_big_endian)
  4484. buf[0] = 1;
  4485. else
  4486. buf[1] = 1;
  4487. /* Alignment. */
  4488. buf[2] = 0;
  4489. buf[3] = 0;
  4490. /* .long */
  4491. buf[4] = 0;
  4492. buf[5] = 0;
  4493. buf[6] = 0;
  4494. buf[7] = 0;
  4495. fix_new (fragp, fragp->fr_fix + 4, 4,
  4496. fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
  4497. fragp->fr_fix += U32_LEN;
  4498. }
  4499. else /* if is_unaligned. */
  4500. {
  4501. if (!target_big_endian)
  4502. buf[0] = 0;
  4503. else
  4504. buf[1] = 0;
  4505. /* .long */
  4506. buf[2] = 0;
  4507. buf[3] = 0;
  4508. buf[4] = 0;
  4509. buf[5] = 0;
  4510. fix_new (fragp, fragp->fr_fix + 2, 4,
  4511. fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
  4512. fragp->fr_fix += U32_LEN;
  4513. }
  4514. }
  4515. break;
  4516. case C (UNCD_JUMP_PIC, DISP32):
  4517. case C (UNCD_JUMP_PIC, UNDEF_WORD_DISP):
  4518. {
  4519. /* subi sp, 8
  4520. stw r15, (sp)
  4521. bsr .L0
  4522. .L0:
  4523. lrw r1, 0f
  4524. add r1, r15
  4525. ldw r15, (sp)
  4526. addi sp, 8
  4527. jmp r1
  4528. .align 2
  4529. 0: .long (tar_add - pc)
  4530. 1:
  4531. */
  4532. /* If the b!cond is 4 byte aligned, the literal which would
  4533. go at x+4 will also be aligned. */
  4534. int first_inst = fragp->fr_fix + fragp->fr_address;
  4535. int is_unaligned = (first_inst & 3);
  4536. disp -= 6;
  4537. buf[0] = BYTE_0 (CSKYV1_INST_SUBI | (7 << 4)); /* subi r0, 8. */
  4538. buf[1] = BYTE_1 (CSKYV1_INST_SUBI | (7 << 4));
  4539. buf[2] = BYTE_0 (CSKYV1_INST_STW | (15 << 8)); /* stw r15, r0. */
  4540. buf[3] = BYTE_1 (CSKYV1_INST_STW | (15 << 8));
  4541. buf[4] = BYTE_0 (CSKYV1_INST_BSR); /* bsr pc + 2. */
  4542. buf[5] = BYTE_1 (CSKYV1_INST_BSR);
  4543. buf[6] = BYTE_0 (CSKYV1_INST_LRW | (1 << 8)); /* lrw r1, (tar_addr - pc). */
  4544. buf[7] = BYTE_1 (CSKYV1_INST_LRW | (1 << 8));
  4545. buf[8] = BYTE_0 (CSKYV1_INST_ADDU | (15 << 4) | 1); /* add r1, r15. */
  4546. buf[9] = BYTE_1 (CSKYV1_INST_ADDU | (15 << 4) | 1);
  4547. buf[10] = BYTE_0 (CSKYV1_INST_LDW | (15 << 8)); /* ldw r15, r0. */
  4548. buf[11] = BYTE_1 (CSKYV1_INST_LDW | (15 << 8));
  4549. buf[12] = BYTE_0 (CSKYV1_INST_ADDI | (7 << 4)); /* addi r0, 8. */
  4550. buf[13] = BYTE_1 (CSKYV1_INST_ADDI | (7 << 4));
  4551. buf[14] = BYTE_0 (CSKYV1_INST_JMP | 1); /* jmp r1. */
  4552. buf[15] = BYTE_1 (CSKYV1_INST_JMP | 1);
  4553. if (is_unaligned)
  4554. {
  4555. if (!target_big_endian)
  4556. {
  4557. buf[6] = 3;
  4558. buf[18] = disp & 0xff;
  4559. buf[19] = (disp >> 8) & 0xff;
  4560. buf[20] = (disp >> 16) & 0xff;
  4561. buf[21] = (disp >> 24) & 0xff;
  4562. }
  4563. else
  4564. {
  4565. buf[7] = 3;
  4566. buf[18] = (disp >> 24) & 0xff;
  4567. buf[19] = (disp >> 16) & 0xff;
  4568. buf[20] = (disp >> 8) & 0xff;
  4569. buf[21] = disp & 0xff;
  4570. }
  4571. buf[16] = 0;
  4572. buf[17] = 0;
  4573. fragp->fr_fix += U32_LEN_PIC;
  4574. }
  4575. else
  4576. {
  4577. if (!target_big_endian)
  4578. {
  4579. buf[6] = 2;
  4580. buf[16] = disp & 0xff;
  4581. buf[17] = (disp >> 8) & 0xff;
  4582. buf[18] = (disp >> 16) & 0xff;
  4583. buf[19] = (disp >> 24) & 0xff;
  4584. }
  4585. else
  4586. {
  4587. buf[7] = 2;
  4588. buf[16] = (disp >> 24) & 0xff;
  4589. buf[17] = (disp >> 16) & 0xff;
  4590. buf[18] = (disp >> 8) & 0xff;
  4591. buf[19] = disp & 0xff;
  4592. }
  4593. fragp->fr_fix += U32_LEN_PIC;
  4594. }
  4595. }
  4596. break;
  4597. case COND_DISP10:
  4598. case SCOND_DISP10:
  4599. case UNCD_DISP10:
  4600. case JCOND_DISP10:
  4601. case JUNCD_DISP10:
  4602. {
  4603. unsigned int inst = csky_read_insn (buf, 2);
  4604. inst |= (disp >> 1) & ((1 << 10) - 1);
  4605. csky_write_insn (buf, inst, 2);
  4606. fragp->fr_fix += 2;
  4607. break;
  4608. }
  4609. case SCOND_DISP16:
  4610. {
  4611. unsigned int inst = csky_read_insn (buf, 2);
  4612. if (inst == CSKYV2_INST_BT16)
  4613. inst = CSKYV2_INST_BF16;
  4614. else
  4615. inst = CSKYV2_INST_BT16;
  4616. make_insn (2, inst, (2 + 4) >> 1, 10);
  4617. if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
  4618. fix_new (fragp, fragp->fr_fix, 4,
  4619. fragp->fr_symbol, fragp->fr_offset, 1,
  4620. BFD_RELOC_CKCORE_PCREL_IMM16BY2);
  4621. disp -= 2;
  4622. inst = CSKYV2_INST_BR32 | ((disp >> 1) & ((1 << 16) - 1));
  4623. csky_write_insn (buf, inst, 4);
  4624. fragp->fr_fix += 4;
  4625. break;
  4626. }
  4627. case COND_DISP16:
  4628. case JCOND_DISP16:
  4629. {
  4630. unsigned int inst = csky_read_insn (buf, 2);
  4631. if (inst == CSKYV2_INST_BT16)
  4632. inst = CSKYV2_INST_BT32;
  4633. else
  4634. inst = CSKYV2_INST_BF32;
  4635. if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
  4636. fix_new (fragp, fragp->fr_fix, 4,
  4637. fragp->fr_symbol, fragp->fr_offset, 1,
  4638. BFD_RELOC_CKCORE_PCREL_IMM16BY2);
  4639. inst |= (disp >> 1) & ((1 << 16) - 1);
  4640. csky_write_insn (buf, inst, 4);
  4641. fragp->fr_fix += 4;
  4642. break;
  4643. }
  4644. case LRW_DISP7:
  4645. {
  4646. unsigned int inst = csky_read_insn (buf, 2);
  4647. int imm;
  4648. imm = (disp + 2) >> 2;
  4649. inst |= (imm >> 5) << 8;
  4650. make_insn (2, inst, (imm & 0x1f), 5);
  4651. break;
  4652. }
  4653. case LRW2_DISP8:
  4654. {
  4655. unsigned int inst = csky_read_insn (buf, 2);
  4656. int imm = (disp + 2) >> 2;
  4657. if (imm >= 0x80)
  4658. {
  4659. inst &= 0xe0;
  4660. inst |= (~((imm >> 5) << 8)) & 0x300;
  4661. make_insn (2, inst, (~imm & 0x1f), 5);
  4662. }
  4663. else
  4664. {
  4665. inst |= (imm >> 5) << 8;
  4666. make_insn (2, inst, (imm & 0x1f), 5);
  4667. }
  4668. break;
  4669. }
  4670. case LRW_DISP16:
  4671. {
  4672. unsigned int inst = csky_read_insn (buf, 2);
  4673. inst = CSKYV2_INST_LRW32 | (((inst & 0xe0) >> 5) << 16);
  4674. if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
  4675. fix_new (fragp, fragp->fr_fix, 4,
  4676. fragp->fr_symbol, fragp->fr_offset, 1,
  4677. BFD_RELOC_CKCORE_PCREL_IMM16BY4);
  4678. make_insn (4, inst, ((disp + 2) >> 2), 16);
  4679. break;
  4680. }
  4681. case JCOMPZ_DISP16:
  4682. {
  4683. unsigned int inst = csky_read_insn (buf, 4);
  4684. make_insn (4, inst, disp >> 1, 16);
  4685. }
  4686. break;
  4687. case JCOMPZ_DISP32:
  4688. {
  4689. unsigned int inst = csky_read_insn (buf, 4);
  4690. int literal_offset;
  4691. make_insn (4, opposite_of_stored_compz (inst),
  4692. (4 + 4 + PAD_LITERAL_LENGTH) >> 1, 16);
  4693. literal_offset = ((fragp->fr_address + fragp->fr_fix) % 4 == 0
  4694. ? 0 : 2);
  4695. make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
  4696. make_literal (fragp, literal_offset);
  4697. }
  4698. break;
  4699. case JUNCD_DISP16:
  4700. case UNCD_DISP16:
  4701. {
  4702. if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
  4703. fix_new (fragp, fragp->fr_fix, 4,
  4704. fragp->fr_symbol, fragp->fr_offset, 1,
  4705. BFD_RELOC_CKCORE_PCREL_IMM16BY2);
  4706. make_insn (4, CSKYV2_INST_BR32, disp >> 1, 16);
  4707. }
  4708. break;
  4709. case JCOND_DISP32:
  4710. {
  4711. /* 'jbt'/'jbf'-> <bf16/bt16>; jmpi32; [pad16]+literal32 */
  4712. unsigned int inst = csky_read_insn (buf, 2);
  4713. int literal_offset;
  4714. if (inst == CSKYV2_INST_BT16)
  4715. inst = CSKYV2_INST_BF16;
  4716. else
  4717. inst = CSKYV2_INST_BT16;
  4718. make_insn (2, inst, (2 + 4 + PAD_LITERAL_LENGTH) >> 1, 10);
  4719. literal_offset = ((fragp->fr_address + fragp->fr_fix) % 4 == 0
  4720. ? 0 : 2);
  4721. make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
  4722. make_literal (fragp, literal_offset);
  4723. break;
  4724. }
  4725. case JUNCD_DISP32:
  4726. {
  4727. int literal_offset;
  4728. literal_offset = ((fragp->fr_address + fragp->fr_fix) % 4 == 0
  4729. ? 0 : 2);
  4730. make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
  4731. make_literal (fragp, literal_offset);
  4732. }
  4733. break;
  4734. case RELAX_OVERFLOW:
  4735. csky_branch_report_error (fragp->fr_file, fragp->fr_line,
  4736. fragp->fr_symbol, disp);
  4737. break;
  4738. default:
  4739. abort ();
  4740. break;
  4741. }
  4742. }
  4743. /* Round up a section size to the appropriate boundary. */
  4744. valueT
  4745. md_section_align (segT segment ATTRIBUTE_UNUSED,
  4746. valueT size)
  4747. {
  4748. return size;
  4749. }
  4750. /* MD interface: Symbol and relocation handling. */
  4751. void md_csky_end (void)
  4752. {
  4753. dump_literals (0);
  4754. }
  4755. /* Return the address within the segment that a PC-relative fixup is
  4756. relative to. */
  4757. long
  4758. md_pcrel_from_section (fixS * fixP, segT seg)
  4759. {
  4760. /* If the symbol is undefined or defined in another section
  4761. we leave the add number alone for the linker to fix it later. */
  4762. if (fixP->fx_addsy != (symbolS *) NULL
  4763. && (! S_IS_DEFINED (fixP->fx_addsy)
  4764. || S_GET_SEGMENT (fixP->fx_addsy) != seg))
  4765. return fixP->fx_size;
  4766. /* The case where we are going to resolve things. */
  4767. return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
  4768. }
  4769. /* csky_cons_fix_new is called via the expression parsing code when a
  4770. reloc is needed. We use this hook to get the correct .got reloc. */
  4771. void
  4772. csky_cons_fix_new (fragS *frag,
  4773. unsigned int off,
  4774. unsigned int len,
  4775. expressionS *exp,
  4776. bfd_reloc_code_real_type reloc)
  4777. {
  4778. fixS *fixP;
  4779. if (BFD_RELOC_CKCORE_GOTOFF == insn_reloc
  4780. || BFD_RELOC_CKCORE_GOTPC == insn_reloc
  4781. || BFD_RELOC_CKCORE_GOT32 == insn_reloc
  4782. || BFD_RELOC_CKCORE_PLT32 == insn_reloc
  4783. || BFD_RELOC_CKCORE_TLS_LE32 == insn_reloc
  4784. || BFD_RELOC_CKCORE_TLS_GD32 == insn_reloc
  4785. || BFD_RELOC_CKCORE_TLS_LDM32 == insn_reloc
  4786. || BFD_RELOC_CKCORE_TLS_LDO32 == insn_reloc
  4787. || BFD_RELOC_CKCORE_TLS_IE32 == insn_reloc)
  4788. reloc = insn_reloc;
  4789. else
  4790. switch (len)
  4791. {
  4792. case 1:
  4793. reloc = BFD_RELOC_8;
  4794. break;
  4795. case 2:
  4796. reloc = BFD_RELOC_16;
  4797. break;
  4798. case 4:
  4799. reloc = BFD_RELOC_32;
  4800. break;
  4801. case 8:
  4802. reloc = BFD_RELOC_64;
  4803. break;
  4804. default:
  4805. as_bad (_("unsupported BFD relocation size %d"), len);
  4806. reloc = BFD_RELOC_32;
  4807. break;
  4808. }
  4809. fixP = fix_new_exp (frag, off, (int) len, exp, 0, reloc);
  4810. if (BFD_RELOC_CKCORE_TLS_IE32 == insn_reloc
  4811. || BFD_RELOC_CKCORE_TLS_GD32 == insn_reloc
  4812. || BFD_RELOC_CKCORE_TLS_LDM32 == insn_reloc)
  4813. {
  4814. fixP->tc_fix_data.frag = literal_insn_offset->tls_addend.frag;
  4815. fixP->tc_fix_data.offset = literal_insn_offset->tls_addend.offset;
  4816. }
  4817. }
  4818. /* See whether we need to force a relocation into the output file.
  4819. This is used to force out switch and PC relative relocations when
  4820. relaxing. */
  4821. int
  4822. csky_force_relocation (fixS * fix)
  4823. {
  4824. if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
  4825. || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY
  4826. || fix->fx_r_type == BFD_RELOC_RVA
  4827. || fix->fx_r_type == BFD_RELOC_CKCORE_ADDR_HI16
  4828. || fix->fx_r_type == BFD_RELOC_CKCORE_ADDR_LO16
  4829. || fix->fx_r_type == BFD_RELOC_CKCORE_TOFFSET_LO16
  4830. || fix->fx_r_type == BFD_RELOC_CKCORE_DOFFSET_LO16)
  4831. return 1;
  4832. if (fix->fx_addsy == NULL)
  4833. return 0;
  4834. if (do_use_branchstub
  4835. && fix->fx_r_type == BFD_RELOC_CKCORE_PCREL_IMM26BY2
  4836. && (symbol_get_bfdsym (fix->fx_addsy)->flags & BSF_FUNCTION))
  4837. return 1;
  4838. return S_FORCE_RELOC (fix->fx_addsy, fix->fx_subsy == NULL);
  4839. }
  4840. /* Return true if the fix can be handled by GAS, false if it must
  4841. be passed through to the linker. */
  4842. bool
  4843. csky_fix_adjustable (fixS * fixP)
  4844. {
  4845. if (fixP->fx_addsy == NULL)
  4846. return 1;
  4847. /* We need the symbol name for the VTABLE entries. */
  4848. if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
  4849. || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
  4850. || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT32
  4851. || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT32
  4852. || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT12
  4853. || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT12
  4854. || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT_HI16
  4855. || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT_LO16
  4856. || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT_HI16
  4857. || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT_LO16
  4858. || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF
  4859. || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF_HI16
  4860. || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF_LO16
  4861. || fixP->fx_r_type == BFD_RELOC_CKCORE_ADDR_HI16
  4862. || fixP->fx_r_type == BFD_RELOC_CKCORE_ADDR_LO16
  4863. || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT_IMM18BY4
  4864. || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT_IMM18BY4
  4865. || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF_IMM18
  4866. || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_LE32
  4867. || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_IE32
  4868. || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_GD32
  4869. || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_LDM32
  4870. || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_LDO32)
  4871. return 0;
  4872. if (do_use_branchstub
  4873. && fixP->fx_r_type == BFD_RELOC_CKCORE_PCREL_IMM26BY2
  4874. && (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_FUNCTION))
  4875. return 0;
  4876. return 1;
  4877. }
  4878. void
  4879. md_apply_fix (fixS *fixP,
  4880. valueT *valP,
  4881. segT seg)
  4882. {
  4883. reloc_howto_type *howto;
  4884. /* Note: use offsetT because it is signed, valueT is unsigned. */
  4885. offsetT val = *valP;
  4886. char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
  4887. /* if fx_done = 0, fixup will also be processed in
  4888. * tc_gen_reloc() after md_apply_fix(). */
  4889. fixP->fx_done = 0;
  4890. /* If the fix is relative to a symbol which is not defined, or not
  4891. in the same segment as the fix, we cannot resolve it here. */
  4892. if (IS_CSKY_V1 (mach_flag) && fixP->fx_addsy != NULL
  4893. && (! S_IS_DEFINED (fixP->fx_addsy)
  4894. || S_GET_SEGMENT (fixP->fx_addsy) != seg))
  4895. {
  4896. switch (fixP->fx_r_type)
  4897. {
  4898. /* Data fx_addnumber is greater than 16 bits,
  4899. so fx_addnumber is assigned zero. */
  4900. case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2:
  4901. *valP = 0;
  4902. break;
  4903. case BFD_RELOC_CKCORE_TLS_IE32:
  4904. case BFD_RELOC_CKCORE_TLS_LDM32:
  4905. case BFD_RELOC_CKCORE_TLS_GD32:
  4906. {
  4907. struct tls_addend *ta = &(fixP->tc_fix_data);
  4908. fixP->fx_offset = (fixP->fx_frag->fr_address + fixP->fx_where
  4909. - (ta->frag->fr_address + ta->offset));
  4910. *valP = fixP->fx_offset;
  4911. }
  4912. /* Fall through. */
  4913. case BFD_RELOC_CKCORE_TLS_LE32:
  4914. case BFD_RELOC_CKCORE_TLS_LDO32:
  4915. S_SET_THREAD_LOCAL (fixP->fx_addsy);
  4916. break;
  4917. default:
  4918. break;
  4919. }
  4920. #ifdef OBJ_ELF
  4921. /* For ELF we can just return and let the reloc that will be generated
  4922. take care of everything. For COFF we still have to insert 'val'
  4923. into the insn since the addend field will be ignored. */
  4924. return;
  4925. #endif
  4926. }
  4927. /* We can handle these relocs. */
  4928. switch (fixP->fx_r_type)
  4929. {
  4930. case BFD_RELOC_32_PCREL:
  4931. case BFD_RELOC_CKCORE_PCREL32:
  4932. fixP->fx_r_type = BFD_RELOC_CKCORE_PCREL32;
  4933. break;
  4934. case BFD_RELOC_VTABLE_INHERIT:
  4935. fixP->fx_r_type = BFD_RELOC_CKCORE_GNU_VTINHERIT;
  4936. if (fixP->fx_addsy && !S_IS_DEFINED (fixP->fx_addsy)
  4937. && !S_IS_WEAK (fixP->fx_addsy))
  4938. S_SET_WEAK (fixP->fx_addsy);
  4939. break;
  4940. case BFD_RELOC_VTABLE_ENTRY:
  4941. fixP->fx_r_type = BFD_RELOC_CKCORE_GNU_VTENTRY;
  4942. break;
  4943. case BFD_RELOC_CKCORE_GOT12:
  4944. case BFD_RELOC_CKCORE_PLT12:
  4945. case BFD_RELOC_CKCORE_ADDR_HI16:
  4946. case BFD_RELOC_CKCORE_ADDR_LO16:
  4947. case BFD_RELOC_CKCORE_TOFFSET_LO16:
  4948. case BFD_RELOC_CKCORE_DOFFSET_LO16:
  4949. case BFD_RELOC_CKCORE_GOT_HI16:
  4950. case BFD_RELOC_CKCORE_GOT_LO16:
  4951. case BFD_RELOC_CKCORE_PLT_HI16:
  4952. case BFD_RELOC_CKCORE_PLT_LO16:
  4953. case BFD_RELOC_CKCORE_GOTPC_HI16:
  4954. case BFD_RELOC_CKCORE_GOTPC_LO16:
  4955. case BFD_RELOC_CKCORE_GOTOFF_HI16:
  4956. case BFD_RELOC_CKCORE_GOTOFF_LO16:
  4957. case BFD_RELOC_CKCORE_DOFFSET_IMM18:
  4958. case BFD_RELOC_CKCORE_DOFFSET_IMM18BY2:
  4959. case BFD_RELOC_CKCORE_DOFFSET_IMM18BY4:
  4960. case BFD_RELOC_CKCORE_GOTOFF_IMM18:
  4961. case BFD_RELOC_CKCORE_GOT_IMM18BY4:
  4962. case BFD_RELOC_CKCORE_PLT_IMM18BY4:
  4963. break;
  4964. case BFD_RELOC_CKCORE_TLS_IE32:
  4965. case BFD_RELOC_CKCORE_TLS_LDM32:
  4966. case BFD_RELOC_CKCORE_TLS_GD32:
  4967. {
  4968. struct tls_addend *ta = &(fixP->tc_fix_data);
  4969. fixP->fx_offset = (fixP->fx_frag->fr_address + fixP->fx_where
  4970. - (ta->frag->fr_address + ta->offset));
  4971. *valP = fixP->fx_offset;
  4972. }
  4973. /* Fall through. */
  4974. case BFD_RELOC_CKCORE_TLS_LE32:
  4975. case BFD_RELOC_CKCORE_TLS_LDO32:
  4976. S_SET_THREAD_LOCAL (fixP->fx_addsy);
  4977. break;
  4978. case BFD_RELOC_32:
  4979. fixP->fx_r_type = BFD_RELOC_CKCORE_ADDR32;
  4980. /* Fall through. */
  4981. case BFD_RELOC_16:
  4982. case BFD_RELOC_8:
  4983. if (fixP->fx_addsy == NULL)
  4984. {
  4985. if (fixP->fx_size == 4)
  4986. ;
  4987. else if (fixP->fx_size == 2 && val >= -32768 && val <= 32767)
  4988. ;
  4989. else if (fixP->fx_size == 1 && val >= -256 && val <= 255)
  4990. ;
  4991. else
  4992. break;
  4993. md_number_to_chars (buf, val, fixP->fx_size);
  4994. fixP->fx_done = 1;
  4995. }
  4996. break;
  4997. case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2:
  4998. if (fixP->fx_addsy == 0 && val > -2 KB && val < 2 KB)
  4999. {
  5000. long nval = (val >> 1) & 0x7ff;
  5001. nval |= CSKYV1_INST_BSR;
  5002. csky_write_insn (buf, nval, 2);
  5003. fixP->fx_done = 1;
  5004. }
  5005. else
  5006. *valP = 0;
  5007. break;
  5008. case BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2:
  5009. if (fixP->fx_addsy == 0)
  5010. {
  5011. if (val >= -(1 << 26) && val < (1 << 26))
  5012. {
  5013. unsigned int nval = ((val + fixP->fx_size) >> 1) & 0x3ffffff;
  5014. nval |= CSKYV2_INST_BSR32;
  5015. csky_write_insn (buf, nval, 4);
  5016. }
  5017. /* If bsr32 cannot reach,
  5018. generate 'lrw r25,label;jsr r25' instead of 'jsri label'. */
  5019. else if (IS_CSKY_ARCH_810 (mach_flag))
  5020. {
  5021. howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
  5022. valueT opcode = csky_read_insn (buf, 4);
  5023. opcode = (opcode & howto->dst_mask) | CSKYV2_INST_JSRI_TO_LRW;
  5024. csky_write_insn (buf, opcode, 4);
  5025. opcode = CSKYV2_INST_JSR_R26;
  5026. csky_write_insn (buf + 4, opcode, 4);
  5027. }
  5028. fixP->fx_done = 1;
  5029. }
  5030. break;
  5031. default:
  5032. {
  5033. valueT opcode;
  5034. offsetT min, max;
  5035. unsigned int issigned = 0;
  5036. if (fixP->fx_addsy)
  5037. break;
  5038. howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
  5039. if (howto == NULL)
  5040. {
  5041. if (fixP->fx_size == 4
  5042. || (fixP->fx_size == 2 && val >= -32768 && val <= 32767)
  5043. || (fixP->fx_size == 1 && val >= -256 && val <= 255))
  5044. {
  5045. md_number_to_chars (buf, val, fixP->fx_size);
  5046. fixP->fx_done = 1;
  5047. break;
  5048. }
  5049. else
  5050. abort ();
  5051. }
  5052. if (IS_CSKY_V2 (mach_flag))
  5053. val += fixP->fx_size;
  5054. if (howto->rightshift == 2)
  5055. val += 2;
  5056. val >>= howto->rightshift;
  5057. switch (fixP->fx_r_type)
  5058. {
  5059. /* Offset is unsigned. */
  5060. case BFD_RELOC_CKCORE_PCREL_IMM8BY4:
  5061. case BFD_RELOC_CKCORE_PCREL_IMM10BY4:
  5062. case BFD_RELOC_CKCORE_PCREL_IMM16BY4:
  5063. max = (offsetT) howto->dst_mask;
  5064. min = 0;
  5065. break;
  5066. /* lrw16. */
  5067. case BFD_RELOC_CKCORE_PCREL_IMM7BY4:
  5068. if (do_extend_lrw)
  5069. max = (offsetT)((1 << (howto->bitsize + 1)) - 2);
  5070. else
  5071. max = (offsetT)((1 << howto->bitsize) - 1);
  5072. min = 0;
  5073. break;
  5074. /* flrws, flrwd: the offset bits are divided in two parts. */
  5075. case BFD_RELOC_CKCORE_PCREL_FLRW_IMM8BY4:
  5076. max = (offsetT)((1 << howto->bitsize) - 1);
  5077. min = 0;
  5078. break;
  5079. /* Offset is signed. */
  5080. default:
  5081. max = (offsetT)(howto->dst_mask >> 1);
  5082. min = - max - 1;
  5083. issigned = 1;
  5084. }
  5085. if (val < min || val > max)
  5086. {
  5087. csky_branch_report_error (fixP->fx_file, fixP->fx_line,
  5088. fixP->fx_addsy, val);
  5089. return;
  5090. }
  5091. opcode = csky_read_insn (buf, fixP->fx_size);
  5092. /* Clear redundant bits brought from the last
  5093. operation if there is any. */
  5094. if (do_extend_lrw && (opcode & 0xfc00) == CSKYV2_INST_LRW16)
  5095. val &= 0xff;
  5096. else
  5097. val &= issigned ? (offsetT)(howto->dst_mask) : max;
  5098. if (fixP->fx_r_type == BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4)
  5099. val = (val & 0xf) << 12;
  5100. if (fixP->fx_size == 2 && (opcode & 0xfc00) == CSKYV2_INST_LRW16)
  5101. {
  5102. /* 8 bit offset lrw16. */
  5103. if (val >= 0x80)
  5104. csky_write_insn (buf,
  5105. ((~val & 0x1f)
  5106. | ((~val & 0x60) << 3) | (opcode & 0xe0)),
  5107. fixP->fx_size);
  5108. /* 7 bit offset lrw16. */
  5109. else
  5110. csky_write_insn (buf,
  5111. (val & 0x1f) | ((val & 0x60) << 3) | opcode,
  5112. fixP->fx_size);
  5113. }
  5114. else if (fixP->fx_size == 4
  5115. && (opcode & 0xfe1ffe00) == CSKYV2_INST_FLRW)
  5116. csky_write_insn (buf,
  5117. ((val & 0xf) << 4) | ((val & 0xf0) << 17) | opcode,
  5118. fixP->fx_size);
  5119. else
  5120. csky_write_insn (buf, val | opcode, fixP->fx_size);
  5121. fixP->fx_done = 1;
  5122. break;
  5123. }
  5124. }
  5125. fixP->fx_addnumber = val;
  5126. }
  5127. /* Translate internal representation of relocation info to BFD target
  5128. format. */
  5129. arelent *
  5130. tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
  5131. {
  5132. arelent *rel;
  5133. if (fixP->fx_pcrel
  5134. && fixP->fx_r_type == BFD_RELOC_CKCORE_ADDR32)
  5135. fixP->fx_r_type = BFD_RELOC_CKCORE_PCREL32;
  5136. rel = xmalloc (sizeof (arelent));
  5137. rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
  5138. *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
  5139. rel->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
  5140. rel->addend = fixP->fx_offset;
  5141. if (rel->howto == NULL)
  5142. {
  5143. as_bad_where (fixP->fx_file, fixP->fx_line,
  5144. _("cannot represent `%s' relocation in object file"),
  5145. bfd_get_reloc_code_name (fixP->fx_r_type));
  5146. /* Set howto to a garbage value so that we can keep going. */
  5147. rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
  5148. }
  5149. gas_assert (rel->howto != NULL);
  5150. rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
  5151. return rel;
  5152. }
  5153. /* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
  5154. long
  5155. csky_relax_frag (segT segment, fragS *fragP, long stretch)
  5156. {
  5157. const relax_typeS *this_type;
  5158. const relax_typeS *start_type;
  5159. relax_substateT next_state;
  5160. relax_substateT this_state;
  5161. offsetT growth;
  5162. offsetT aim;
  5163. addressT target;
  5164. addressT address;
  5165. symbolS *symbolP;
  5166. const relax_typeS *table;
  5167. target = fragP->fr_offset;
  5168. address = fragP->fr_address;
  5169. table = TC_GENERIC_RELAX_TABLE;
  5170. this_state = fragP->fr_subtype;
  5171. start_type = this_type = table + this_state;
  5172. symbolP = fragP->fr_symbol;
  5173. if (symbolP)
  5174. {
  5175. fragS *sym_frag;
  5176. sym_frag = symbol_get_frag (symbolP);
  5177. #ifndef DIFF_EXPR_OK
  5178. know (sym_frag != NULL);
  5179. #endif
  5180. know (S_GET_SEGMENT (symbolP) != absolute_section
  5181. || sym_frag == &zero_address_frag);
  5182. target += S_GET_VALUE (symbolP);
  5183. /* If SYM_FRAG has yet to be reached on this pass, assume it
  5184. will move by STRETCH just as we did, unless there is an
  5185. alignment frag between here and SYM_FRAG. An alignment may
  5186. well absorb any STRETCH, and we don't want to choose a larger
  5187. branch insn by overestimating the needed reach of this
  5188. branch. It isn't critical to calculate TARGET exactly; We
  5189. know we'll be doing another pass if STRETCH is non-zero. */
  5190. if (stretch != 0
  5191. && sym_frag->relax_marker != fragP->relax_marker
  5192. && S_GET_SEGMENT (symbolP) == segment)
  5193. {
  5194. fragS *f;
  5195. /* Adjust stretch for any alignment frag. Note that if have
  5196. been expanding the earlier code, the symbol may be
  5197. defined in what appears to be an earlier frag. FIXME:
  5198. This doesn't handle the fr_subtype field, which specifies
  5199. a maximum number of bytes to skip when doing an
  5200. alignment. */
  5201. for (f = fragP; f != NULL && f != sym_frag; f = f->fr_next)
  5202. {
  5203. if (f->fr_type == rs_align || f->fr_type == rs_align_code)
  5204. {
  5205. if (stretch < 0)
  5206. stretch = -((-stretch)
  5207. & ~((1 << (int) f->fr_offset) - 1));
  5208. else
  5209. stretch &= ~((1 << (int) f->fr_offset) - 1);
  5210. }
  5211. if (stretch == 0)
  5212. break;
  5213. }
  5214. if (f != 0)
  5215. target += stretch;
  5216. }
  5217. }
  5218. aim = target - address - fragP->fr_fix;
  5219. /* If the fragP->fr_symbol is extern symbol, aim should be 0. */
  5220. if (fragP->fr_symbol && S_GET_SEGMENT (symbolP) != segment)
  5221. aim = 0;
  5222. if (aim < 0)
  5223. {
  5224. /* Look backwards. */
  5225. for (next_state = this_type->rlx_more; next_state;)
  5226. if (aim >= this_type->rlx_backward)
  5227. next_state = 0;
  5228. else
  5229. {
  5230. /* Grow to next state. */
  5231. this_state = next_state;
  5232. this_type = table + this_state;
  5233. next_state = this_type->rlx_more;
  5234. }
  5235. }
  5236. else
  5237. {
  5238. /* Look forwards. */
  5239. for (next_state = this_type->rlx_more; next_state;)
  5240. if (aim <= this_type->rlx_forward)
  5241. next_state = 0;
  5242. else
  5243. {
  5244. /* Grow to next state. */
  5245. this_state = next_state;
  5246. this_type = table + this_state;
  5247. next_state = this_type->rlx_more;
  5248. }
  5249. }
  5250. growth = this_type->rlx_length - start_type->rlx_length;
  5251. if (growth != 0)
  5252. fragP->fr_subtype = this_state;
  5253. return growth;
  5254. }
  5255. int
  5256. md_estimate_size_before_relax (fragS * fragp,
  5257. segT segtype)
  5258. {
  5259. switch (fragp->fr_subtype)
  5260. {
  5261. case COND_DISP10:
  5262. case COND_DISP16:
  5263. case SCOND_DISP10:
  5264. case SCOND_DISP16:
  5265. case UNCD_DISP10:
  5266. case UNCD_DISP16:
  5267. case JCOND_DISP10:
  5268. case JCOND_DISP16:
  5269. case JCOND_DISP32:
  5270. case JUNCD_DISP10:
  5271. case JUNCD_DISP16:
  5272. case JUNCD_DISP32:
  5273. case JCOMPZ_DISP16:
  5274. case JCOMPZ_DISP32:
  5275. case BSR_DISP26:
  5276. case LRW_DISP7:
  5277. case LRW2_DISP8:
  5278. case LRW_DISP16:
  5279. gas_assert (fragp->fr_symbol);
  5280. if (IS_EXTERNAL_SYM (fragp->fr_symbol, segtype))
  5281. while (csky_relax_table[fragp->fr_subtype].rlx_more > RELAX_OVERFLOW)
  5282. fragp->fr_subtype = csky_relax_table[fragp->fr_subtype].rlx_more;
  5283. return csky_relax_table[fragp->fr_subtype].rlx_length;
  5284. /* C-SKY V1 relaxes. */
  5285. case C (UNCD_JUMP, UNDEF_DISP):
  5286. case C (UNCD_JUMP_PIC, UNDEF_DISP):
  5287. if (!fragp->fr_symbol)
  5288. fragp->fr_subtype = C (UNCD_JUMP_S, DISP12);
  5289. else if (S_GET_SEGMENT (fragp->fr_symbol) == segtype)
  5290. fragp->fr_subtype = C (UNCD_JUMP_S, DISP12);
  5291. else
  5292. fragp->fr_subtype = C (UNCD_JUMP_S, UNDEF_WORD_DISP);
  5293. break;
  5294. case C (COND_JUMP, UNDEF_DISP):
  5295. case C (COND_JUMP_PIC, UNDEF_DISP):
  5296. if (fragp->fr_symbol
  5297. && S_GET_SEGMENT (fragp->fr_symbol) == segtype)
  5298. /* Got a symbol and it's defined in this segment, become byte
  5299. sized. Maybe it will fix up. */
  5300. fragp->fr_subtype = C (COND_JUMP_S, DISP12);
  5301. else if (fragp->fr_symbol)
  5302. /* It's got a segment, but it's not ours, so it will always be
  5303. long. */
  5304. fragp->fr_subtype = C (COND_JUMP_S, UNDEF_WORD_DISP);
  5305. else
  5306. /* We know the abs value. */
  5307. fragp->fr_subtype = C (COND_JUMP_S, DISP12);
  5308. break;
  5309. case C (UNCD_JUMP, DISP12):
  5310. case C (UNCD_JUMP, DISP32):
  5311. case C (UNCD_JUMP, UNDEF_WORD_DISP):
  5312. case C (COND_JUMP, DISP12):
  5313. case C (COND_JUMP, DISP32):
  5314. case C (COND_JUMP, UNDEF_WORD_DISP):
  5315. case C (UNCD_JUMP_PIC, DISP12):
  5316. case C (UNCD_JUMP_PIC, DISP32):
  5317. case C (UNCD_JUMP_PIC, UNDEF_WORD_DISP):
  5318. case C (COND_JUMP_PIC, DISP12):
  5319. case C (COND_JUMP_PIC, DISP32):
  5320. case C (COND_JUMP_PIC, UNDEF_WORD_DISP):
  5321. case RELAX_OVERFLOW:
  5322. break;
  5323. default:
  5324. abort ();
  5325. }
  5326. return csky_relax_table[fragp->fr_subtype].rlx_length;
  5327. }
  5328. /* Parse opcode like: "op oprnd1, oprnd2, oprnd3". */
  5329. static void
  5330. csky_macro_md_assemble (const char *op,
  5331. const char *oprnd1,
  5332. const char *oprnd2,
  5333. const char *oprnd3)
  5334. {
  5335. char str[80];
  5336. str[0] = '\0';
  5337. strcat (str, op);
  5338. if (oprnd1 != NULL)
  5339. {
  5340. strcat (str, " ");
  5341. strcat (str, oprnd1);
  5342. if (oprnd2 != NULL)
  5343. {
  5344. strcat (str, ",");
  5345. strcat (str, oprnd2);
  5346. if (oprnd3 != NULL)
  5347. {
  5348. strcat (str, ",");
  5349. strcat (str, oprnd3);
  5350. }
  5351. }
  5352. }
  5353. md_assemble (str);
  5354. return;
  5355. }
  5356. /* Get the string of operand. */
  5357. static int
  5358. csky_get_macro_operand (char *src_s, char *dst_s, char end_sym)
  5359. {
  5360. int nlen = 0;
  5361. while (ISSPACE (*src_s))
  5362. ++src_s;
  5363. while (*src_s != end_sym)
  5364. dst_s[nlen++] = *(src_s++);
  5365. dst_s[nlen] = '\0';
  5366. return nlen;
  5367. }
  5368. /* idly 4 -> idly4. */
  5369. static void
  5370. csky_idly (void)
  5371. {
  5372. char *s = csky_insn.opcode_end;
  5373. if (!is_imm_within_range (&s, 4, 4))
  5374. {
  5375. as_bad (_("second operand must be 4"));
  5376. return;
  5377. }
  5378. csky_macro_md_assemble ("idly4", NULL, NULL, NULL);
  5379. return;
  5380. }
  5381. /* rolc rd, 1 or roltc rd, 1 -> addc rd, rd. */
  5382. static void
  5383. csky_rolc (void)
  5384. {
  5385. char reg[10];
  5386. char *s = csky_insn.opcode_end;
  5387. s += csky_get_macro_operand (s, reg, ',');
  5388. ++s;
  5389. if (is_imm_within_range (&s, 1, 1))
  5390. {
  5391. csky_macro_md_assemble ("addc", reg, reg, NULL);
  5392. return;
  5393. }
  5394. else
  5395. as_bad (_("second operand must be 1"));
  5396. }
  5397. /* sxtrb0(1)(2) r1, rx -> xtbr0(1)(2) r1,rx; sextb r1. */
  5398. static void
  5399. csky_sxtrb (void)
  5400. {
  5401. char reg1[10];
  5402. char reg2[10];
  5403. char *s = csky_insn.opcode_end;
  5404. s += csky_get_macro_operand (s, reg1, ',');
  5405. ++s;
  5406. csky_get_macro_operand (s, reg2, '\0');
  5407. csky_macro_md_assemble (csky_insn.macro->name + 1, reg1, reg2, NULL);
  5408. csky_macro_md_assemble ("sextb", reg1, NULL, NULL);
  5409. return;
  5410. }
  5411. static void
  5412. csky_movtf (void)
  5413. {
  5414. char reg1[10];
  5415. char reg2[10];
  5416. char reg3[10];
  5417. char *s = csky_insn.opcode_end;
  5418. s += csky_get_macro_operand (s, reg1, ',');
  5419. ++s;
  5420. s += csky_get_macro_operand (s, reg2, ',');
  5421. ++s;
  5422. s += csky_get_macro_operand (s, reg3, '\0');
  5423. ++s;
  5424. csky_macro_md_assemble ("movt", reg1, reg2, NULL);
  5425. csky_macro_md_assemble ("movf", reg1, reg3, NULL);
  5426. return;
  5427. }
  5428. static bool
  5429. get_macro_reg_vals (int *reg1, int *reg2, int *reg3)
  5430. {
  5431. int nlen;
  5432. char *s = csky_insn.opcode_end;
  5433. *reg1 = csky_get_reg_val (s, &nlen);
  5434. s += nlen;
  5435. if (*s != ',')
  5436. {
  5437. csky_show_error (ERROR_MISSING_COMMA, 0, NULL, NULL);
  5438. return false;
  5439. }
  5440. s++;
  5441. *reg2 = csky_get_reg_val (s, &nlen);
  5442. s += nlen;
  5443. if (*s != ',')
  5444. {
  5445. csky_show_error (ERROR_MISSING_COMMA, 0, NULL, NULL);
  5446. return false;
  5447. }
  5448. s++;
  5449. *reg3 = csky_get_reg_val (s, &nlen);
  5450. s += nlen;
  5451. if (*s != '\0')
  5452. {
  5453. csky_show_error (ERROR_BAD_END, 0, s, NULL);
  5454. return false;
  5455. }
  5456. if (*reg1 == -1 || *reg2 == -1 || *reg3 == -1)
  5457. {
  5458. as_bad (_("register number out of range"));
  5459. return false;
  5460. }
  5461. if (*reg1 != *reg2)
  5462. {
  5463. as_bad (_("dest and source1 must be the same register"));
  5464. return false;
  5465. }
  5466. if (*reg1 >= 15 || *reg3 >= 15)
  5467. {
  5468. as_bad (_("64-bit operator src/dst register must be less than 15"));
  5469. return false;
  5470. }
  5471. return true;
  5472. }
  5473. /* addc64 rx, rx, ry -> cmplt rx, rx, addc rx, ry, addc rx+1, ry+1. */
  5474. static void
  5475. csky_addc64 (void)
  5476. {
  5477. int reg1;
  5478. int reg2;
  5479. int reg3;
  5480. char reg1_name[16] = {0};
  5481. char reg3_name[16] = {0};
  5482. if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
  5483. return;
  5484. sprintf (reg1_name, "r%d", reg1);
  5485. csky_macro_md_assemble ("cmplt", reg1_name, reg1_name, NULL);
  5486. if (error_state.err_num != ERROR_NONE)
  5487. return;
  5488. sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
  5489. sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
  5490. csky_macro_md_assemble ("addc", reg1_name, reg3_name, NULL);
  5491. if (error_state.err_num != ERROR_NONE)
  5492. return;
  5493. sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
  5494. sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
  5495. csky_macro_md_assemble ("addc", reg1_name, reg3_name, NULL);
  5496. return;
  5497. }
  5498. /* subc64 rx, rx, ry -> cmphs rx, rx, subc rx, ry, subc rx+1, ry+1. */
  5499. static void
  5500. csky_subc64 (void)
  5501. {
  5502. int reg1;
  5503. int reg2;
  5504. int reg3;
  5505. char reg1_name[16] = {0};
  5506. char reg3_name[16] = {0};
  5507. if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
  5508. return;
  5509. sprintf (reg1_name, "r%d", reg1);
  5510. csky_macro_md_assemble ("cmphs", reg1_name, reg1_name, NULL);
  5511. if (error_state.err_num != ERROR_NONE)
  5512. return;
  5513. sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
  5514. sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
  5515. csky_macro_md_assemble ("subc", reg1_name, reg3_name, NULL);
  5516. if (error_state.err_num != ERROR_NONE)
  5517. return;
  5518. sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
  5519. sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
  5520. csky_macro_md_assemble ("subc", reg1_name, reg3_name, NULL);
  5521. return;
  5522. }
  5523. /* or64 rx, rx, ry -> or rx, ry, or rx+1, ry+1. */
  5524. static void
  5525. csky_or64 (void)
  5526. {
  5527. int reg1;
  5528. int reg2;
  5529. int reg3;
  5530. char reg1_name[16] = {0};
  5531. char reg3_name[16] = {0};
  5532. if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
  5533. return;
  5534. sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
  5535. sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
  5536. csky_macro_md_assemble ("or", reg1_name, reg3_name, NULL);
  5537. if (error_state.err_num != ERROR_NONE)
  5538. return;
  5539. sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
  5540. sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
  5541. csky_macro_md_assemble ("or", reg1_name, reg3_name, NULL);
  5542. return;
  5543. }
  5544. /* xor64 rx, rx, ry -> xor rx, ry, xor rx+1, ry+1. */
  5545. static void
  5546. csky_xor64 (void)
  5547. {
  5548. int reg1;
  5549. int reg2;
  5550. int reg3;
  5551. char reg1_name[16] = {0};
  5552. char reg3_name[16] = {0};
  5553. if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
  5554. return;
  5555. sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
  5556. sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
  5557. csky_macro_md_assemble ("xor", reg1_name, reg3_name, NULL);
  5558. if (error_state.err_num != ERROR_NONE)
  5559. return;
  5560. sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
  5561. sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
  5562. csky_macro_md_assemble ("xor", reg1_name, reg3_name, NULL);
  5563. return;
  5564. }
  5565. /* The following are V2 macro instructions. */
  5566. /* neg rd -> not rd, rd; addi rd, 1. */
  5567. static void
  5568. csky_neg (void)
  5569. {
  5570. char reg1[10];
  5571. char *s = csky_insn.opcode_end;
  5572. s += csky_get_macro_operand (s, reg1, '\0');
  5573. ++s;
  5574. csky_macro_md_assemble ("not", reg1, reg1, NULL);
  5575. csky_macro_md_assemble ("addi", reg1, "1", NULL);
  5576. return;
  5577. }
  5578. /* rsubi rd, imm16 -> not rd; addi rd, imm16 + 1 */
  5579. static void
  5580. csky_rsubi (void)
  5581. {
  5582. char reg1[10];
  5583. char str_imm16[20];
  5584. unsigned int imm16 = 0;
  5585. expressionS e;
  5586. char *s = csky_insn.opcode_end;
  5587. s += csky_get_macro_operand (s, reg1, ',');
  5588. ++s;
  5589. s = parse_exp (s, &e);
  5590. if (e.X_op == O_constant)
  5591. imm16 = e.X_add_number;
  5592. else
  5593. csky_show_error (ERROR_IMM_ILLEGAL, 2, NULL, NULL);
  5594. sprintf (str_imm16, "%d", imm16 + 1);
  5595. csky_macro_md_assemble ("not", reg1, reg1, NULL);
  5596. csky_macro_md_assemble ("addi", reg1, str_imm16, NULL);
  5597. return;
  5598. }
  5599. /* Such as: asrc rd -> asrc rd, rd, 1. */
  5600. static void
  5601. csky_arith (void)
  5602. {
  5603. char reg1[10];
  5604. char *s = csky_insn.opcode_end;
  5605. s += csky_get_macro_operand (s, reg1, '\0');
  5606. ++s;
  5607. csky_macro_md_assemble (csky_insn.macro->name, reg1, reg1, "1");
  5608. return;
  5609. }
  5610. /* decne rd -> if ck802: subi rd, 1; cmpnei rd, 0.
  5611. else: decne rd, rd, 1 */
  5612. static void
  5613. csky_decne (void)
  5614. {
  5615. char reg1[10];
  5616. char *s = csky_insn.opcode_end;
  5617. s += csky_get_macro_operand (s, reg1, '\0');
  5618. ++s;
  5619. if (IS_CSKY_ARCH_802 (mach_flag))
  5620. {
  5621. csky_macro_md_assemble ("subi", reg1, "1", NULL);
  5622. csky_macro_md_assemble ("cmpnei", reg1, "0", NULL);
  5623. }
  5624. else
  5625. csky_macro_md_assemble ("decne", reg1, reg1, "1");
  5626. return;
  5627. }
  5628. /* If -mnolrw, lrw rd, imm -> movih rd, imm_hi16; ori rd, imm_lo16. */
  5629. static void
  5630. csky_lrw (void)
  5631. {
  5632. char reg1[10];
  5633. char imm[40];
  5634. char imm_hi16[40];
  5635. char imm_lo16[40];
  5636. char *s = csky_insn.opcode_end;
  5637. s += csky_get_macro_operand (s, reg1, ',');
  5638. ++s;
  5639. s += csky_get_macro_operand (s, imm, '\0');
  5640. ++s;
  5641. imm_hi16[0] = '\0';
  5642. strcat (imm_hi16, "(");
  5643. strcat (imm_hi16, imm);
  5644. strcat (imm_hi16, ") >> 16");
  5645. imm_lo16[0] = '\0';
  5646. strcat (imm_lo16, "(");
  5647. strcat (imm_lo16, imm);
  5648. strcat (imm_lo16, ") & 0xffff");
  5649. csky_macro_md_assemble ("movih", reg1, imm_hi16, NULL);
  5650. csky_macro_md_assemble ("ori", reg1, reg1, imm_lo16);
  5651. return;
  5652. }
  5653. /* The following are worker functions for C-SKY v1. */
  5654. bool
  5655. v1_work_lrw (void)
  5656. {
  5657. int reg;
  5658. int output_literal = csky_insn.val[1];
  5659. reg = csky_insn.val[0];
  5660. csky_insn.isize = 2;
  5661. csky_insn.output = frag_more (2);
  5662. if (csky_insn.e1.X_op == O_constant
  5663. && csky_insn.e1.X_add_number <= 0x7f
  5664. && csky_insn.e1.X_add_number >= 0)
  5665. /* lrw to movi. */
  5666. csky_insn.inst = 0x6000 | reg | (csky_insn.e1.X_add_number << 4);
  5667. else
  5668. {
  5669. csky_insn.inst = csky_insn.opcode->op16[0].opcode;
  5670. csky_insn.inst |= reg << 8;
  5671. if (output_literal)
  5672. {
  5673. struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
  5674. /* Create a reference to pool entry. */
  5675. csky_insn.e1.X_op = O_symbol;
  5676. csky_insn.e1.X_add_symbol = poolsym;
  5677. csky_insn.e1.X_add_number = p->offset << 2;
  5678. }
  5679. if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
  5680. || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
  5681. || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
  5682. {
  5683. literal_insn_offset->tls_addend.frag = frag_now;
  5684. literal_insn_offset->tls_addend.offset
  5685. = (csky_insn.output
  5686. - literal_insn_offset->tls_addend.frag->fr_literal);
  5687. }
  5688. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal, 2,
  5689. &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4);
  5690. }
  5691. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  5692. return true;
  5693. }
  5694. bool
  5695. v1_work_fpu_fo (void)
  5696. {
  5697. int i = 0;
  5698. int inst;
  5699. int greg = -1;
  5700. char buff[50];
  5701. struct csky_opcode_info *opinfo = NULL;
  5702. if (csky_insn.isize == 4)
  5703. opinfo = &csky_insn.opcode->op32[csky_insn.opcode_idx];
  5704. else if (csky_insn.isize == 2)
  5705. opinfo = &csky_insn.opcode->op16[csky_insn.opcode_idx];
  5706. /* Firstly, get general reg. */
  5707. for (i = 0;i < opinfo->operand_num; i++)
  5708. if (opinfo->oprnd.oprnds[i].type == OPRND_TYPE_GREG0_15)
  5709. greg = csky_insn.val[i];
  5710. gas_assert (greg != -1);
  5711. /* Secondly, get float inst. */
  5712. csky_generate_insn ();
  5713. inst = csky_insn.inst;
  5714. /* Now get greg and inst, we can write instruction to floating unit. */
  5715. sprintf (buff, "lrw r%d,0x%x", greg, inst);
  5716. md_assemble (buff);
  5717. sprintf (buff, "cpwir r%d", greg);
  5718. md_assemble (buff);
  5719. return false;
  5720. }
  5721. bool
  5722. v1_work_fpu_fo_fc (void)
  5723. {
  5724. int i = 0;
  5725. int inst;
  5726. int greg = -1;
  5727. char buff[50];
  5728. struct csky_opcode_info *opinfo = NULL;
  5729. if (csky_insn.isize == 4)
  5730. opinfo = &csky_insn.opcode->op32[csky_insn.opcode_idx];
  5731. else if (csky_insn.isize == 2)
  5732. opinfo = &csky_insn.opcode->op16[csky_insn.opcode_idx];
  5733. /* Firstly, get general reg. */
  5734. for (i = 0;i < opinfo->operand_num; i++)
  5735. if (opinfo->oprnd.oprnds[i].type == OPRND_TYPE_GREG0_15)
  5736. greg = csky_insn.val[i];
  5737. gas_assert (greg != -1);
  5738. /* Secondly, get float inst. */
  5739. csky_generate_insn ();
  5740. inst = csky_insn.inst;
  5741. /* Now get greg and inst, we can write instruction to floating unit. */
  5742. sprintf (buff, "lrw r%d,0x%x", greg, inst);
  5743. md_assemble (buff);
  5744. sprintf (buff, "cpwir r%d", greg);
  5745. md_assemble (buff);
  5746. sprintf (buff, "cprc");
  5747. md_assemble (buff);
  5748. return false;
  5749. }
  5750. bool
  5751. v1_work_fpu_write (void)
  5752. {
  5753. int greg;
  5754. int freg;
  5755. char buff[50];
  5756. greg = csky_insn.val[0];
  5757. freg = csky_insn.val[1];
  5758. /* Now get greg and freg, we can write instruction to floating unit. */
  5759. sprintf (buff, "cpwgr r%d,cpr%d", greg, freg);
  5760. md_assemble (buff);
  5761. return false;
  5762. }
  5763. bool
  5764. v1_work_fpu_read (void)
  5765. {
  5766. int greg;
  5767. int freg;
  5768. char buff[50];
  5769. greg = csky_insn.val[0];
  5770. freg = csky_insn.val[1];
  5771. /* Now get greg and freg, we can write instruction to floating unit. */
  5772. sprintf (buff, "cprgr r%d,cpr%d", greg, freg);
  5773. md_assemble (buff);
  5774. return false;
  5775. }
  5776. bool
  5777. v1_work_fpu_writed (void)
  5778. {
  5779. int greg;
  5780. int freg;
  5781. char buff[50];
  5782. greg = csky_insn.val[0];
  5783. freg = csky_insn.val[1];
  5784. if (greg & 0x1)
  5785. {
  5786. as_bad (_("even register number required"));
  5787. return false;
  5788. }
  5789. /* Now get greg and freg, we can write instruction to floating unit. */
  5790. if (target_big_endian)
  5791. sprintf (buff, "cpwgr r%d,cpr%d", greg + 1, freg);
  5792. else
  5793. sprintf (buff, "cpwgr r%d,cpr%d", greg, freg);
  5794. md_assemble (buff);
  5795. if (target_big_endian)
  5796. sprintf (buff, "cpwgr r%d,cpr%d", greg, freg + 1);
  5797. else
  5798. sprintf (buff, "cpwgr r%d,cpr%d", greg+1, freg + 1);
  5799. md_assemble (buff);
  5800. return false;
  5801. }
  5802. bool
  5803. v1_work_fpu_readd (void)
  5804. {
  5805. int greg;
  5806. int freg;
  5807. char buff[50];
  5808. greg = csky_insn.val[0];
  5809. freg = csky_insn.val[1];
  5810. if (greg & 0x1)
  5811. {
  5812. as_bad (_("even register number required"));
  5813. return false;
  5814. }
  5815. /* Now get greg and freg, we can write instruction to floating unit. */
  5816. if (target_big_endian)
  5817. sprintf (buff, "cprgr r%d,cpr%d", greg+1, freg);
  5818. else
  5819. sprintf (buff, "cprgr r%d,cpr%d", greg, freg);
  5820. md_assemble (buff);
  5821. if (target_big_endian)
  5822. sprintf (buff, "cprgr r%d,cpr%d", greg, freg + 1);
  5823. else
  5824. sprintf (buff, "cprgr r%d,cpr%d", greg+1, freg + 1);
  5825. md_assemble (buff);
  5826. return false;
  5827. }
  5828. /* The following are for csky pseudo handling. */
  5829. bool
  5830. v1_work_jbsr (void)
  5831. {
  5832. csky_insn.output = frag_more (2);
  5833. if (do_force2bsr)
  5834. /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM11BY2. */
  5835. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  5836. 2, & csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM11BY2);
  5837. else
  5838. {
  5839. /* Using jsri instruction. */
  5840. const char *name = "jsri";
  5841. csky_insn.opcode = (struct csky_opcode *)
  5842. str_hash_find (csky_opcodes_hash, name);
  5843. csky_insn.opcode_idx = 0;
  5844. csky_insn.isize = 2;
  5845. struct literal *p = enter_literal (&csky_insn.e1, 1, 0, 0);
  5846. /* Create a reference to pool entry. */
  5847. csky_insn.e1.X_op = O_symbol;
  5848. csky_insn.e1.X_add_symbol = poolsym;
  5849. csky_insn.e1.X_add_number = p->offset << 2;
  5850. /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM8BY4. */
  5851. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  5852. 2, & csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4);
  5853. if (csky_insn.e1.X_op != O_absent && do_jsri2bsr)
  5854. /* Generate fixup BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2. */
  5855. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  5856. 2, &p->e,
  5857. 1, BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2);
  5858. }
  5859. csky_generate_insn ();
  5860. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  5861. return true;
  5862. }
  5863. /* The following are worker functions for csky v2 instruction handling. */
  5864. /* For nie/nir/ipush/ipop. */
  5865. bool
  5866. v2_work_istack (void)
  5867. {
  5868. if (!do_intr_stack)
  5869. {
  5870. csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
  5871. return false;
  5872. }
  5873. csky_insn.output = frag_more (csky_insn.isize);
  5874. csky_insn.inst = csky_insn.opcode->op16[0].opcode;
  5875. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  5876. return true;
  5877. }
  5878. bool
  5879. v2_work_btsti (void)
  5880. {
  5881. if (!do_extend_lrw
  5882. && (csky_insn.flag_force == INSN_OPCODE16F
  5883. || IS_CSKY_ARCH_801 (mach_flag)))
  5884. {
  5885. csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
  5886. return false;
  5887. }
  5888. if (!do_extend_lrw && csky_insn.isize == 2)
  5889. csky_insn.isize = 4;
  5890. /* Generate relax or reloc if necessary. */
  5891. csky_generate_frags ();
  5892. /* Generate the insn by mask. */
  5893. csky_generate_insn ();
  5894. /* Write inst to frag. */
  5895. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  5896. return true;
  5897. }
  5898. bool
  5899. v2_work_addi (void)
  5900. {
  5901. csky_insn.isize = 2;
  5902. if (csky_insn.number == 2)
  5903. {
  5904. if (csky_insn.val[0] == 14
  5905. && csky_insn.val[1] >= 0 && csky_insn.val[1] <= 0x1fc
  5906. && (csky_insn.val[1] & 0x3) == 0
  5907. && csky_insn.flag_force != INSN_OPCODE32F)
  5908. {
  5909. /* addi sp, sp, imm. */
  5910. csky_insn.inst = 0x1400 | ((csky_insn.val[1] >> 2) & 0x1f);
  5911. csky_insn.inst |= (csky_insn.val[1] << 1) & 0x300;
  5912. csky_insn.output = frag_more (2);
  5913. }
  5914. else if (csky_insn.val[0] < 8
  5915. && csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x100
  5916. && csky_insn.flag_force != INSN_OPCODE32F)
  5917. {
  5918. csky_insn.inst = 0x2000 | (csky_insn.val[0] << 8);
  5919. csky_insn.inst |= (csky_insn.val[1] - 1);
  5920. csky_insn.output = frag_more (2);
  5921. }
  5922. else if (csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x10000
  5923. && csky_insn.flag_force != INSN_OPCODE16F
  5924. && !IS_CSKY_ARCH_801 (mach_flag))
  5925. {
  5926. csky_insn.inst = 0xe4000000 | (csky_insn.val[0] << 21);
  5927. csky_insn.inst |= csky_insn.val[0] << 16;
  5928. csky_insn.inst |= (csky_insn.val[1] - 1);
  5929. csky_insn.isize = 4;
  5930. csky_insn.output = frag_more (4);
  5931. }
  5932. else
  5933. {
  5934. csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
  5935. csky_insn.opcode_end, NULL);
  5936. return false;
  5937. }
  5938. }
  5939. else if (csky_insn.number == 3)
  5940. {
  5941. if (csky_insn.val[0] == 14
  5942. && csky_insn.val[1] == 14
  5943. && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x1fc
  5944. && (csky_insn.val[2] & 0x3) == 0
  5945. && csky_insn.flag_force != INSN_OPCODE32F)
  5946. {
  5947. csky_insn.inst = 0x1400 | ((csky_insn.val[2] >> 2) & 0x1f);
  5948. csky_insn.inst |= (csky_insn.val[2] << 1) & 0x300;
  5949. csky_insn.output = frag_more (2);
  5950. }
  5951. else if (csky_insn.val[0] < 8
  5952. && csky_insn.val[1] == 14
  5953. && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x3fc
  5954. && (csky_insn.val[2] & 0x3) == 0
  5955. && csky_insn.flag_force != INSN_OPCODE32F)
  5956. {
  5957. csky_insn.inst = 0x1800 | (csky_insn.val[0] << 8);
  5958. csky_insn.inst |= csky_insn.val[2] >> 2;
  5959. csky_insn.output = frag_more (2);
  5960. }
  5961. else if (csky_insn.val[0] < 8
  5962. && csky_insn.val[0] == csky_insn.val[1]
  5963. && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x100
  5964. && csky_insn.flag_force != INSN_OPCODE32F)
  5965. {
  5966. csky_insn.inst = 0x2000 | (csky_insn.val[0] << 8);
  5967. csky_insn.inst |= (csky_insn.val[2] - 1);
  5968. csky_insn.output = frag_more (2);
  5969. }
  5970. else if (csky_insn.val[0] < 8
  5971. && csky_insn.val[1] < 8
  5972. && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x8
  5973. && csky_insn.flag_force != INSN_OPCODE32F)
  5974. {
  5975. csky_insn.inst = 0x5802 | (csky_insn.val[0] << 5);
  5976. csky_insn.inst |= csky_insn.val[1] << 8;
  5977. csky_insn.inst |= (csky_insn.val[2] - 1) << 2;
  5978. csky_insn.output = frag_more (2);
  5979. }
  5980. else if (csky_insn.val[1] == 28
  5981. && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x40000
  5982. && csky_insn.flag_force != INSN_OPCODE16F
  5983. && !IS_CSKY_ARCH_801 (mach_flag))
  5984. {
  5985. csky_insn.inst = 0xcc1c0000 | (csky_insn.val[0] << 21);
  5986. csky_insn.isize = 4;
  5987. csky_insn.output = frag_more (4);
  5988. if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
  5989. {
  5990. fix_new_exp (frag_now, csky_insn.output-frag_now->fr_literal,
  5991. 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_GOTOFF_IMM18);
  5992. }
  5993. else
  5994. csky_insn.inst |= (csky_insn.val[2] - 1);
  5995. }
  5996. else if (csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x1000
  5997. && csky_insn.flag_force != INSN_OPCODE16F
  5998. && !IS_CSKY_ARCH_801 (mach_flag))
  5999. {
  6000. csky_insn.inst = 0xe4000000 | (csky_insn.val[0] << 21);
  6001. csky_insn.inst |= csky_insn.val[1] << 16;
  6002. csky_insn.inst |= (csky_insn.val[2] - 1);
  6003. csky_insn.isize = 4;
  6004. csky_insn.output = frag_more (4);
  6005. }
  6006. else
  6007. {
  6008. csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
  6009. (char *)csky_insn.opcode_end, NULL);
  6010. return false;
  6011. }
  6012. }
  6013. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6014. return true;
  6015. }
  6016. bool
  6017. v2_work_subi (void)
  6018. {
  6019. csky_insn.isize = 2;
  6020. if (csky_insn.number == 2)
  6021. {
  6022. if (csky_insn.val[0] == 14
  6023. && csky_insn.val[1] >= 0 && csky_insn.val[2] <= 0x1fc
  6024. && (csky_insn.val[1] & 0x3) == 0
  6025. && csky_insn.flag_force != INSN_OPCODE32F)
  6026. {
  6027. csky_insn.inst = 0x1420 | ((csky_insn.val[1] >> 2) & 0x1f);
  6028. csky_insn.inst |= (csky_insn.val[1] << 1) & 0x300;
  6029. }
  6030. else if (csky_insn.val[0] < 8
  6031. && csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x100
  6032. && csky_insn.flag_force != INSN_OPCODE32F)
  6033. {
  6034. csky_insn.inst = 0x2800 | (csky_insn.val[0] << 8);
  6035. csky_insn.inst |= (csky_insn.val[1] - 1);
  6036. }
  6037. else if (csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x10000
  6038. && csky_insn.flag_force != INSN_OPCODE16F
  6039. && !IS_CSKY_ARCH_801 (mach_flag))
  6040. {
  6041. csky_insn.inst = 0xe4001000 | (csky_insn.val[0] << 21);
  6042. csky_insn.inst |= csky_insn.val[0] << 16;
  6043. csky_insn.inst |= (csky_insn.val[1] - 1);
  6044. csky_insn.isize = 4;
  6045. }
  6046. else
  6047. {
  6048. csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
  6049. (char *)csky_insn.opcode_end, NULL);
  6050. return false;
  6051. }
  6052. }
  6053. else if (csky_insn.number == 3)
  6054. {
  6055. if (csky_insn.val[0] == 14
  6056. && csky_insn.val[1] == 14
  6057. && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x1fc
  6058. && (csky_insn.val[2] & 0x3) == 0
  6059. && csky_insn.flag_force != INSN_OPCODE32F)
  6060. {
  6061. csky_insn.inst = 0x1420 | ((csky_insn.val[2] >> 2) & 0x1f);
  6062. csky_insn.inst |= (csky_insn.val[2] << 1) & 0x300;
  6063. }
  6064. else if (csky_insn.val[0] < 8
  6065. && csky_insn.val[0] == csky_insn.val[1]
  6066. && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x100
  6067. && csky_insn.flag_force != INSN_OPCODE32F)
  6068. {
  6069. csky_insn.inst = 0x2800 | (csky_insn.val[0] << 8);
  6070. csky_insn.inst |= (csky_insn.val[2] - 1);
  6071. }
  6072. else if (csky_insn.val[0] < 8
  6073. && csky_insn.val[1] < 8
  6074. && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x8
  6075. && csky_insn.flag_force != INSN_OPCODE32F)
  6076. {
  6077. csky_insn.inst = 0x5803 | (csky_insn.val[0] << 5);
  6078. csky_insn.inst |= csky_insn.val[1] << 8;
  6079. csky_insn.inst |= (csky_insn.val[2] - 1) << 2;
  6080. }
  6081. else if (csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x1000
  6082. && csky_insn.flag_force != INSN_OPCODE16F
  6083. && !IS_CSKY_ARCH_801 (mach_flag))
  6084. {
  6085. csky_insn.inst = 0xe4001000 | (csky_insn.val[0] << 21);
  6086. csky_insn.inst |= csky_insn.val[1] << 16;
  6087. csky_insn.inst |= (csky_insn.val[2] - 1);
  6088. csky_insn.isize = 4;
  6089. }
  6090. else
  6091. {
  6092. csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
  6093. (char *)csky_insn.opcode_end, NULL);
  6094. return false;
  6095. }
  6096. }
  6097. csky_insn.output = frag_more (csky_insn.isize);
  6098. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6099. return true;
  6100. }
  6101. bool
  6102. v2_work_add_sub (void)
  6103. {
  6104. if (csky_insn.number == 3
  6105. && (csky_insn.val[0] == csky_insn.val[1]
  6106. || csky_insn.val[0] == csky_insn.val[2])
  6107. && csky_insn.val[0] <= 15
  6108. && csky_insn.val[1] <= 15
  6109. && csky_insn.val[2] <= 15)
  6110. {
  6111. if (!strstr (csky_insn.opcode->mnemonic, "sub")
  6112. || csky_insn.val[0] == csky_insn.val[1])
  6113. {
  6114. csky_insn.opcode_idx = 0;
  6115. csky_insn.isize = 2;
  6116. if (csky_insn.val[0] == csky_insn.val[1])
  6117. csky_insn.val[1] = csky_insn.val[2];
  6118. csky_insn.number = 2;
  6119. }
  6120. }
  6121. if (csky_insn.isize == 4
  6122. && IS_CSKY_ARCH_801 (mach_flag))
  6123. {
  6124. if (csky_insn.number == 3)
  6125. {
  6126. if (csky_insn.val[0] > 7)
  6127. {
  6128. SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[0]);
  6129. csky_show_error (ERROR_REG_OVER_RANGE, 1, NULL, NULL);
  6130. }
  6131. if (csky_insn.val[1] > 7)
  6132. {
  6133. SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[1]);
  6134. csky_show_error (ERROR_REG_OVER_RANGE, 2, NULL, NULL);
  6135. }
  6136. if (csky_insn.val[2] > 7)
  6137. {
  6138. SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[2]);
  6139. csky_show_error (ERROR_REG_OVER_RANGE, 3, NULL, NULL);
  6140. }
  6141. }
  6142. else
  6143. {
  6144. if (csky_insn.val[0] > 15)
  6145. {
  6146. SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[0]);
  6147. csky_show_error (ERROR_REG_OVER_RANGE, 1, NULL, NULL);
  6148. }
  6149. if (csky_insn.val[1] > 15)
  6150. {
  6151. SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[1]);
  6152. csky_show_error (ERROR_REG_OVER_RANGE, 2, NULL, NULL);
  6153. }
  6154. }
  6155. return false;
  6156. }
  6157. /* sub rz, rx. */
  6158. /* Generate relax or reloc if necessary. */
  6159. csky_generate_frags ();
  6160. /* Generate the insn by mask. */
  6161. csky_generate_insn ();
  6162. /* Write inst to frag. */
  6163. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6164. return true;
  6165. }
  6166. bool
  6167. v2_work_rotlc (void)
  6168. {
  6169. const char *name = "addc";
  6170. csky_insn.opcode
  6171. = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
  6172. csky_insn.opcode_idx = 0;
  6173. if (csky_insn.isize == 2)
  6174. {
  6175. /* addc rz, rx. */
  6176. csky_insn.number = 2;
  6177. csky_insn.val[1] = csky_insn.val[0];
  6178. }
  6179. else
  6180. {
  6181. csky_insn.number = 3;
  6182. /* addc rz, rx, ry. */
  6183. csky_insn.val[1] = csky_insn.val[0];
  6184. csky_insn.val[2] = csky_insn.val[0];
  6185. }
  6186. /* Generate relax or reloc if necessary. */
  6187. csky_generate_frags ();
  6188. /* Generate the insn by mask. */
  6189. csky_generate_insn ();
  6190. /* Write inst to frag. */
  6191. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6192. return true;
  6193. }
  6194. bool
  6195. v2_work_bgeni (void)
  6196. {
  6197. const char *name = NULL;
  6198. int imm = csky_insn.val[1];
  6199. int val = 1 << imm;
  6200. if (imm < 16)
  6201. name = "movi";
  6202. else
  6203. {
  6204. name = "movih";
  6205. val >>= 16;
  6206. }
  6207. csky_insn.opcode
  6208. = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
  6209. csky_insn.opcode_idx = 0;
  6210. csky_insn.val[1] = val;
  6211. /* Generate relax or reloc if necessary. */
  6212. csky_generate_frags ();
  6213. /* Generate the insn by mask. */
  6214. csky_generate_insn ();
  6215. /* Write inst to frag. */
  6216. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6217. return true;
  6218. }
  6219. bool
  6220. v2_work_not (void)
  6221. {
  6222. const char *name = "nor";
  6223. csky_insn.opcode
  6224. = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
  6225. csky_insn.opcode_idx = 0;
  6226. if (csky_insn.number == 1)
  6227. {
  6228. csky_insn.val[1] = csky_insn.val[0];
  6229. if (csky_insn.val[0] < 16)
  6230. {
  6231. /* 16 bits nor rz, rz. */
  6232. csky_insn.number = 2;
  6233. csky_insn.isize = 2;
  6234. }
  6235. else
  6236. {
  6237. csky_insn.val[2] = csky_insn.val[0];
  6238. csky_insn.number = 3;
  6239. csky_insn.isize = 4;
  6240. }
  6241. }
  6242. if (csky_insn.number == 2)
  6243. {
  6244. if (csky_insn.val[0] == csky_insn.val[1]
  6245. && csky_insn.val[0] < 16)
  6246. {
  6247. /* 16 bits nor rz, rz. */
  6248. csky_insn.number = 2;
  6249. csky_insn.isize = 2;
  6250. }
  6251. else
  6252. {
  6253. csky_insn.val[2] = csky_insn.val[1];
  6254. csky_insn.number = 3;
  6255. csky_insn.isize = 4;
  6256. }
  6257. }
  6258. /* Generate relax or reloc if necessary. */
  6259. csky_generate_frags ();
  6260. /* Generate the insn by mask. */
  6261. csky_generate_insn ();
  6262. /* Write inst to frag. */
  6263. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6264. return true;
  6265. }
  6266. bool
  6267. v2_work_jbtf (void)
  6268. {
  6269. if (csky_insn.e1.X_add_symbol == NULL || csky_insn.e1.X_op == O_constant)
  6270. {
  6271. csky_show_error (ERROR_UNDEFINE, 0, (void *)"operand is invalid", NULL);
  6272. return false;
  6273. }
  6274. if (IS_CSKY_ARCH_801 (mach_flag))
  6275. {
  6276. /* CK801 doesn't have 32-bit bt/bf insns or a jump insn with a
  6277. range larger than SCOND_DISP16. Relax to a short jump around
  6278. an unconditional branch, and give up if that overflows too. */
  6279. csky_insn.output = frag_var (rs_machine_dependent,
  6280. SCOND_DISP16_LEN,
  6281. SCOND_DISP10_LEN,
  6282. SCOND_DISP10,
  6283. csky_insn.e1.X_add_symbol,
  6284. csky_insn.e1.X_add_number,
  6285. 0);
  6286. csky_insn.isize = 2;
  6287. csky_insn.max = SCOND_DISP16_LEN;
  6288. csky_insn.inst = csky_insn.opcode->op16[0].opcode;
  6289. }
  6290. else if (do_long_jump && !IS_CSKY_ARCH_802 (mach_flag))
  6291. {
  6292. /* Generate relax with jcondition.
  6293. Note that CK802 doesn't support the JMPI instruction so
  6294. we cannot relax to a jump with a 32-bit offset. */
  6295. csky_insn.output = frag_var (rs_machine_dependent,
  6296. JCOND_DISP32_LEN,
  6297. JCOND_DISP10_LEN,
  6298. JCOND_DISP10,
  6299. csky_insn.e1.X_add_symbol,
  6300. csky_insn.e1.X_add_number,
  6301. 0);
  6302. csky_insn.isize = 2;
  6303. csky_insn.max = JCOND_DISP32_LEN;
  6304. csky_insn.inst = csky_insn.opcode->op16[0].opcode;
  6305. }
  6306. else
  6307. {
  6308. /* Generate relax with condition. */
  6309. csky_insn.output = frag_var (rs_machine_dependent,
  6310. COND_DISP16_LEN,
  6311. COND_DISP10_LEN,
  6312. COND_DISP10,
  6313. csky_insn.e1.X_add_symbol,
  6314. csky_insn.e1.X_add_number,
  6315. 0);
  6316. csky_insn.isize = 2;
  6317. csky_insn.max = COND_DISP16_LEN;
  6318. csky_insn.inst = csky_insn.opcode->op16[0].opcode;
  6319. }
  6320. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6321. return true;
  6322. }
  6323. bool
  6324. v2_work_jbr (void)
  6325. {
  6326. if (csky_insn.e1.X_add_symbol == NULL || csky_insn.e1.X_op == O_constant)
  6327. {
  6328. csky_show_error (ERROR_UNDEFINE, 0, (void *)"operand is invalid", NULL);
  6329. return false;
  6330. }
  6331. if (do_long_jump
  6332. && !IS_CSKY_ARCH_801 (mach_flag)
  6333. && !IS_CSKY_ARCH_802 (mach_flag))
  6334. {
  6335. csky_insn.output = frag_var (rs_machine_dependent,
  6336. JUNCD_DISP32_LEN,
  6337. JUNCD_DISP10_LEN,
  6338. JUNCD_DISP10,
  6339. csky_insn.e1.X_add_symbol,
  6340. csky_insn.e1.X_add_number,
  6341. 0);
  6342. csky_insn.inst = csky_insn.opcode->op16[0].opcode;
  6343. csky_insn.max = JUNCD_DISP32_LEN;
  6344. csky_insn.isize = 2;
  6345. }
  6346. else
  6347. {
  6348. /* Generate relax with condition. */
  6349. csky_insn.output = frag_var (rs_machine_dependent,
  6350. UNCD_DISP16_LEN,
  6351. UNCD_DISP10_LEN,
  6352. UNCD_DISP10,
  6353. csky_insn.e1.X_add_symbol,
  6354. csky_insn.e1.X_add_number,
  6355. 0);
  6356. csky_insn.isize = 2;
  6357. csky_insn.max = UNCD_DISP16_LEN;
  6358. csky_insn.inst = csky_insn.opcode->op16[0].opcode;
  6359. }
  6360. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6361. return true;
  6362. }
  6363. #define SIZE_V2_MOVI16(x) ((addressT)x <= 0xff)
  6364. #define SIZE_V2_MOVI32(x) ((addressT)x <= 0xffff)
  6365. #define SIZE_V2_MOVIH(x) ((addressT)x <= 0xffffffff && (((addressT)x & 0xffff) == 0))
  6366. bool
  6367. v2_work_lrw (void)
  6368. {
  6369. int reg = csky_insn.val[0];
  6370. int output_literal = csky_insn.val[1];
  6371. int is_done = 0;
  6372. /* If the second operand is O_constant, We can use movi/movih
  6373. instead of lrw. */
  6374. if (csky_insn.e1.X_op == O_constant)
  6375. {
  6376. /* 801 only has movi16. */
  6377. if (SIZE_V2_MOVI16 (csky_insn.e1.X_add_number) && reg < 8)
  6378. {
  6379. /* movi16 instead. */
  6380. csky_insn.output = frag_more (2);
  6381. csky_insn.inst = (CSKYV2_INST_MOVI16 | (reg << 8)
  6382. | (csky_insn.e1.X_add_number));
  6383. csky_insn.isize = 2;
  6384. is_done = 1;
  6385. }
  6386. else if (SIZE_V2_MOVI32 (csky_insn.e1.X_add_number)
  6387. && !IS_CSKY_ARCH_801 (mach_flag))
  6388. {
  6389. /* movi32 instead. */
  6390. csky_insn.output = frag_more (4);
  6391. csky_insn.inst = (CSKYV2_INST_MOVI32 | (reg << 16)
  6392. | (csky_insn.e1.X_add_number));
  6393. csky_insn.isize = 4;
  6394. is_done = 1;
  6395. }
  6396. else if (SIZE_V2_MOVIH (csky_insn.e1.X_add_number)
  6397. && !IS_CSKY_ARCH_801 (mach_flag))
  6398. {
  6399. /* movih instead. */
  6400. csky_insn.output = frag_more (4);
  6401. csky_insn.inst = (CSKYV2_INST_MOVIH | (reg << 16)
  6402. | ((csky_insn.e1.X_add_number >> 16) & 0xffff));
  6403. csky_insn.isize = 4;
  6404. is_done = 1;
  6405. }
  6406. }
  6407. if (is_done)
  6408. {
  6409. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6410. return true;
  6411. }
  6412. if (output_literal)
  6413. {
  6414. struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
  6415. /* Create a reference to pool entry. */
  6416. csky_insn.e1.X_op = O_symbol;
  6417. csky_insn.e1.X_add_symbol = poolsym;
  6418. csky_insn.e1.X_add_number = p->offset << 2;
  6419. }
  6420. /* If 16bit force. */
  6421. if (csky_insn.flag_force == INSN_OPCODE16F)
  6422. {
  6423. /* Generate fixup. */
  6424. if (reg > 7)
  6425. {
  6426. csky_show_error (ERROR_UNDEFINE, 0,
  6427. (void *)"The register is out of range.", NULL);
  6428. return false;
  6429. }
  6430. csky_insn.isize = 2;
  6431. csky_insn.output = frag_more (2);
  6432. if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
  6433. || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
  6434. || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
  6435. {
  6436. literal_insn_offset->tls_addend.frag = frag_now;
  6437. literal_insn_offset->tls_addend.offset
  6438. = csky_insn.output - frag_now->fr_literal;
  6439. }
  6440. csky_insn.inst = csky_insn.opcode->op16[0].opcode | (reg << 5);
  6441. csky_insn.max = 4;
  6442. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  6443. 2, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM7BY4);
  6444. }
  6445. else if (csky_insn.flag_force == INSN_OPCODE32F)
  6446. {
  6447. csky_insn.isize = 4;
  6448. csky_insn.output = frag_more (4);
  6449. if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
  6450. || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
  6451. || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
  6452. {
  6453. literal_insn_offset->tls_addend.frag = frag_now;
  6454. literal_insn_offset->tls_addend.offset
  6455. = csky_insn.output - frag_now->fr_literal;
  6456. }
  6457. csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
  6458. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  6459. 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
  6460. }
  6461. else if (!is_done)
  6462. {
  6463. if (reg < 8)
  6464. {
  6465. csky_insn.isize = 2;
  6466. if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
  6467. || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
  6468. || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
  6469. literal_insn_offset->tls_addend.frag = frag_now;
  6470. csky_insn.output = frag_var (rs_machine_dependent,
  6471. LRW_DISP16_LEN,
  6472. LRW_DISP7_LEN,
  6473. (do_extend_lrw
  6474. ? LRW2_DISP8 : LRW_DISP7),
  6475. csky_insn.e1.X_add_symbol,
  6476. csky_insn.e1.X_add_number, 0);
  6477. if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
  6478. || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
  6479. || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
  6480. {
  6481. if (literal_insn_offset->tls_addend.frag->fr_next != frag_now)
  6482. literal_insn_offset->tls_addend.frag
  6483. = literal_insn_offset->tls_addend.frag->fr_next;
  6484. literal_insn_offset->tls_addend.offset
  6485. = (csky_insn.output
  6486. - literal_insn_offset->tls_addend.frag->fr_literal);
  6487. }
  6488. csky_insn.inst = csky_insn.opcode->op16[0].opcode | (reg << 5);
  6489. csky_insn.max = LRW_DISP16_LEN;
  6490. csky_insn.isize = 2;
  6491. }
  6492. else
  6493. {
  6494. csky_insn.isize = 4;
  6495. csky_insn.output = frag_more (4);
  6496. if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
  6497. || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
  6498. || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
  6499. {
  6500. literal_insn_offset->tls_addend.frag = frag_now;
  6501. literal_insn_offset->tls_addend.offset
  6502. = csky_insn.output - frag_now->fr_literal;
  6503. }
  6504. csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
  6505. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  6506. 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
  6507. }
  6508. }
  6509. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6510. return true;
  6511. }
  6512. bool
  6513. v2_work_lrsrsw (void)
  6514. {
  6515. int reg = csky_insn.val[0];
  6516. csky_insn.output = frag_more (4);
  6517. csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 21);
  6518. csky_insn.isize = 4;
  6519. switch (insn_reloc)
  6520. {
  6521. case BFD_RELOC_CKCORE_GOT32:
  6522. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  6523. 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_GOT_IMM18BY4);
  6524. break;
  6525. case BFD_RELOC_CKCORE_PLT32:
  6526. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  6527. 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_PLT_IMM18BY4);
  6528. break;
  6529. default:
  6530. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  6531. 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_DOFFSET_IMM18BY4);
  6532. break;
  6533. }
  6534. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6535. return true;
  6536. }
  6537. bool
  6538. v2_work_jbsr (void)
  6539. {
  6540. if (do_force2bsr
  6541. || IS_CSKY_ARCH_801 (mach_flag)
  6542. || IS_CSKY_ARCH_802 (mach_flag))
  6543. {
  6544. csky_insn.output = frag_more (4);
  6545. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  6546. 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM26BY2);
  6547. csky_insn.isize = 4;
  6548. csky_insn.inst = CSKYV2_INST_BSR32;
  6549. }
  6550. else
  6551. {
  6552. struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
  6553. csky_insn.output = frag_more (4);
  6554. csky_insn.e1.X_op = O_symbol;
  6555. csky_insn.e1.X_add_symbol = poolsym;
  6556. csky_insn.e1.X_add_number = p->offset << 2;
  6557. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  6558. 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
  6559. if (do_jsri2bsr || IS_CSKY_ARCH_810 (mach_flag))
  6560. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  6561. 4,
  6562. &(litpool + (csky_insn.e1.X_add_number >> 2))->e,
  6563. 1,
  6564. BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2);
  6565. csky_insn.inst = CSKYV2_INST_JSRI32;
  6566. csky_insn.isize = 4;
  6567. if (IS_CSKY_ARCH_810 (mach_flag))
  6568. {
  6569. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6570. csky_insn.output = frag_more (4);
  6571. dwarf2_emit_insn (0);
  6572. /* Insert "mov r0, r0". */
  6573. csky_insn.inst = CSKYV2_INST_MOV_R0_R0;
  6574. csky_insn.max = 8;
  6575. }
  6576. }
  6577. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6578. return true;
  6579. }
  6580. bool
  6581. v2_work_jsri (void)
  6582. {
  6583. /* dump literal. */
  6584. struct literal *p = enter_literal (&csky_insn.e1, 1, 0, 0);
  6585. csky_insn.e1.X_op = O_symbol;
  6586. csky_insn.e1.X_add_symbol = poolsym;
  6587. csky_insn.e1.X_add_number = p->offset << 2;
  6588. /* Generate relax or reloc if necessary. */
  6589. csky_generate_frags ();
  6590. /* Generate the insn by mask. */
  6591. csky_generate_insn ();
  6592. /* Write inst to frag. */
  6593. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6594. /* Control 810 not to generate jsri. */
  6595. if (IS_CSKY_ARCH_810 (mach_flag))
  6596. {
  6597. /* Look at adding the R_PCREL_JSRIMM26BY2.
  6598. For 'jbsr .L1', this reloc type's symbol
  6599. is bound to '.L1', isn't bound to literal pool. */
  6600. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  6601. 4, &p->e, 1,
  6602. BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2);
  6603. csky_insn.output = frag_more (4);
  6604. dwarf2_emit_insn (0);
  6605. /* The opcode of "mov32 r0,r0". */
  6606. csky_insn.inst = CSKYV2_INST_MOV_R0_R0;
  6607. /* The effect of this value is to check literal. */
  6608. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6609. csky_insn.max = 8;
  6610. }
  6611. return true;
  6612. }
  6613. bool
  6614. v2_work_movih (void)
  6615. {
  6616. int rz = csky_insn.val[0];
  6617. csky_insn.output = frag_more (4);
  6618. csky_insn.inst = csky_insn.opcode->op32[0].opcode | (rz << 16);
  6619. if (csky_insn.e1.X_op == O_constant)
  6620. {
  6621. if (csky_insn.e1.X_unsigned == 1 && csky_insn.e1.X_add_number > 0xffff)
  6622. {
  6623. csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
  6624. return false;
  6625. }
  6626. else if (csky_insn.e1.X_unsigned == 0 && csky_insn.e1.X_add_number < 0)
  6627. {
  6628. csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
  6629. return false;
  6630. }
  6631. else
  6632. csky_insn.inst |= (csky_insn.e1.X_add_number & 0xffff);
  6633. }
  6634. else if (csky_insn.e1.X_op == O_right_shift
  6635. || (csky_insn.e1.X_op == O_symbol && insn_reloc != BFD_RELOC_NONE))
  6636. {
  6637. if (csky_insn.e1.X_op_symbol != 0
  6638. && symbol_constant_p (csky_insn.e1.X_op_symbol)
  6639. && S_GET_SEGMENT (csky_insn.e1.X_op_symbol) == absolute_section
  6640. && 16 == S_GET_VALUE (csky_insn.e1.X_op_symbol))
  6641. {
  6642. csky_insn.e1.X_op = O_symbol;
  6643. if (insn_reloc == BFD_RELOC_CKCORE_GOT32)
  6644. insn_reloc = BFD_RELOC_CKCORE_GOT_HI16;
  6645. else if (insn_reloc == BFD_RELOC_CKCORE_PLT32)
  6646. insn_reloc = BFD_RELOC_CKCORE_PLT_HI16;
  6647. else if (insn_reloc == BFD_RELOC_CKCORE_GOTPC)
  6648. insn_reloc = BFD_RELOC_CKCORE_GOTPC_HI16;
  6649. else if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
  6650. insn_reloc = BFD_RELOC_CKCORE_GOTOFF_HI16;
  6651. else
  6652. insn_reloc = BFD_RELOC_CKCORE_ADDR_HI16;
  6653. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  6654. 4, &csky_insn.e1, 0, insn_reloc);
  6655. }
  6656. else
  6657. {
  6658. void *arg = (void *)"the second operand must be \"SYMBOL >> 16\"";
  6659. csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
  6660. return false;
  6661. }
  6662. }
  6663. csky_insn.isize = 4;
  6664. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6665. return true;
  6666. }
  6667. bool
  6668. v2_work_ori (void)
  6669. {
  6670. int rz = csky_insn.val[0];
  6671. int rx = csky_insn.val[1];
  6672. csky_insn.output = frag_more (4);
  6673. csky_insn.inst = csky_insn.opcode->op32[0].opcode | (rz << 21) | (rx << 16);
  6674. if (csky_insn.e1.X_op == O_constant)
  6675. {
  6676. if (csky_insn.e1.X_add_number <= 0xffff
  6677. && csky_insn.e1.X_add_number >= 0)
  6678. csky_insn.inst |= csky_insn.e1.X_add_number;
  6679. else
  6680. {
  6681. csky_show_error (ERROR_IMM_OVERFLOW, 3, NULL, NULL);
  6682. return false;
  6683. }
  6684. }
  6685. else if (csky_insn.e1.X_op == O_bit_and)
  6686. {
  6687. if (symbol_constant_p (csky_insn.e1.X_op_symbol)
  6688. && S_GET_SEGMENT (csky_insn.e1.X_op_symbol) == absolute_section
  6689. && 0xffff == S_GET_VALUE (csky_insn.e1.X_op_symbol))
  6690. {
  6691. csky_insn.e1.X_op = O_symbol;
  6692. if (insn_reloc == BFD_RELOC_CKCORE_GOT32)
  6693. insn_reloc = BFD_RELOC_CKCORE_GOT_LO16;
  6694. else if (insn_reloc == BFD_RELOC_CKCORE_PLT32)
  6695. insn_reloc = BFD_RELOC_CKCORE_PLT_LO16;
  6696. else if (insn_reloc == BFD_RELOC_CKCORE_GOTPC)
  6697. insn_reloc = BFD_RELOC_CKCORE_GOTPC_LO16;
  6698. else if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
  6699. insn_reloc = BFD_RELOC_CKCORE_GOTOFF_LO16;
  6700. else
  6701. insn_reloc = BFD_RELOC_CKCORE_ADDR_LO16;
  6702. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  6703. 4, &csky_insn.e1, 0, insn_reloc);
  6704. }
  6705. else
  6706. {
  6707. void *arg = (void *)"the third operand must be \"SYMBOL & 0xffff\"";
  6708. csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
  6709. return false;
  6710. }
  6711. }
  6712. csky_insn.isize = 4;
  6713. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6714. return true;
  6715. }
  6716. /* Helper function to encode a single/double floating point constant
  6717. into the instruction word for fmovis and fmovid instructions.
  6718. The constant is in its IEEE single/double precision representation
  6719. and is repacked into the internal 13-bit representation for these
  6720. instructions with a diagnostic for overflow. Note that there is no
  6721. rounding when converting to the smaller format, just an error if there
  6722. is excess precision or the number is too small/large to be represented. */
  6723. bool
  6724. float_work_fmovi (void)
  6725. {
  6726. int rx = csky_insn.val[0];
  6727. /* We already converted the float constant to the internal 13-bit
  6728. representation so we just need to OR it in here. */
  6729. csky_insn.inst = csky_insn.opcode->op32[0].opcode | rx;
  6730. csky_insn.inst |= (uint32_t) csky_insn.e1.X_add_number;
  6731. csky_insn.output = frag_more (4);
  6732. csky_insn.isize = 4;
  6733. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6734. return true;
  6735. }
  6736. /* Like float_work_fmovi, but for FPUV3 fmovi.16, fmovi.32 and fmovi.64
  6737. instructions. */
  6738. bool
  6739. float_work_fpuv3_fmovi (void)
  6740. {
  6741. int rx = csky_insn.val[0];
  6742. int idx = csky_insn.opcode_idx;
  6743. int imm4 = 0;
  6744. int imm8 = 0;
  6745. int sign = 0;
  6746. csky_insn.inst = csky_insn.opcode->op32[idx].opcode | rx;
  6747. if (csky_insn.opcode->op32[idx].operand_num == 3)
  6748. {
  6749. /* fmovi.xx frz, imm9, imm4. */
  6750. imm8 = csky_insn.val[1];
  6751. imm4 = csky_insn.val[2];
  6752. if (imm8 < 0 || (imm8 & 0x80000000))
  6753. {
  6754. sign = (1 << 5);
  6755. imm8 = 0 - imm8;
  6756. }
  6757. if (imm8 > 255)
  6758. {
  6759. csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
  6760. return false;
  6761. }
  6762. /* imm8 store at bit [25:20] and [9:8]. */
  6763. /* imm4 store at bit [19:16]. */
  6764. /* sign store at bit [5]. */
  6765. csky_insn.inst = csky_insn.inst
  6766. | ((imm8 & 0x3) << 8)
  6767. | ((imm8 & 0xfc) << 18)
  6768. | ((imm4 & 0xf) << 16)
  6769. | sign;
  6770. }
  6771. else
  6772. {
  6773. csky_insn.inst |= (uint32_t) csky_insn.e1.X_add_number;
  6774. }
  6775. csky_insn.output = frag_more(4);
  6776. csky_insn.isize = 4;
  6777. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6778. return true;
  6779. }
  6780. bool
  6781. dsp_work_bloop (void)
  6782. {
  6783. int reg = csky_insn.val[0];
  6784. csky_insn.output = frag_more (4);
  6785. csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
  6786. csky_insn.isize = 4;
  6787. if (csky_insn.number == 3
  6788. && csky_insn.e1.X_op == O_symbol
  6789. && csky_insn.e2.X_op == O_symbol)
  6790. {
  6791. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  6792. 4, &csky_insn.e1, 1,
  6793. BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4);
  6794. fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
  6795. 4, &csky_insn.e2, 1,
  6796. BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4);
  6797. }
  6798. else if (csky_insn.number == 2
  6799. && csky_insn.e1.X_op == O_symbol)
  6800. {
  6801. fix_new_exp (frag_now, csky_insn.output-frag_now->fr_literal,
  6802. 4, &csky_insn.e1, 1,
  6803. BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4);
  6804. if (csky_insn.last_isize == 2)
  6805. csky_insn.inst |= (0xf << 12);
  6806. else if (csky_insn.last_isize != 0)
  6807. csky_insn.inst |= (0xe << 12);
  6808. else
  6809. {
  6810. void *arg = (void *)"bloop can not be the first instruction"\
  6811. "when the end label is not specified.\n";
  6812. csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
  6813. }
  6814. }
  6815. csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
  6816. return true;
  6817. }
  6818. bool
  6819. float_work_fpuv3_fstore(void)
  6820. {
  6821. /* Generate relax or reloc if necessary. */
  6822. csky_generate_frags ();
  6823. /* Generate the insn by mask. */
  6824. csky_generate_insn ();
  6825. /* Write inst to frag. */
  6826. csky_write_insn (csky_insn.output,
  6827. csky_insn.inst,
  6828. csky_insn.isize);
  6829. return true;
  6830. }
  6831. bool
  6832. v2_work_addc (void)
  6833. {
  6834. int reg1;
  6835. int reg2;
  6836. int reg3 = 0;
  6837. int is_16_bit = 0;
  6838. reg1 = csky_insn.val[0];
  6839. reg2 = csky_insn.val[1];
  6840. if (csky_insn.number == 2)
  6841. {
  6842. if (reg1 > 15 || reg2 > 15)
  6843. {
  6844. is_16_bit = 0;
  6845. reg3 = reg1;
  6846. }
  6847. else
  6848. is_16_bit = 1;
  6849. }
  6850. else
  6851. {
  6852. reg3 = csky_insn.val[2];
  6853. if (reg1 > 15 || reg2 > 15 || reg3 > 15)
  6854. is_16_bit = 0;
  6855. else if (reg1 == reg2 || reg1 == reg3)
  6856. {
  6857. is_16_bit = 1;
  6858. reg2 = (reg1 == reg2) ? reg3 : reg2;
  6859. }
  6860. else
  6861. is_16_bit = 0;
  6862. }
  6863. if (is_16_bit
  6864. && csky_insn.flag_force != INSN_OPCODE32F)
  6865. {
  6866. csky_insn.isize = 2;
  6867. csky_insn.inst = csky_insn.opcode->op16[0].opcode
  6868. | (reg1 << 6) | (reg2 << 2);
  6869. }
  6870. else if (csky_insn.flag_force != INSN_OPCODE16F)
  6871. {
  6872. csky_insn.isize = 4;
  6873. csky_insn.inst = csky_insn.opcode->op32[0].opcode
  6874. | (reg1 << 0) | (reg2 << 16) | (reg3 << 21);
  6875. }
  6876. else
  6877. {
  6878. SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, reg1 > 15 ? reg1 : reg2);
  6879. csky_show_error (ERROR_REG_OVER_RANGE, 0, 0, NULL);
  6880. }
  6881. /* Generate relax or reloc if necessary. */
  6882. csky_generate_frags ();
  6883. /* Write inst to frag. */
  6884. csky_write_insn (csky_insn.output,
  6885. csky_insn.inst,
  6886. csky_insn.isize);
  6887. return true;
  6888. }
  6889. /* The following are for assembler directive handling. */
  6890. /* Helper function to adjust constant pool counts when we emit a
  6891. data directive in the text section. FUNC is one of the standard
  6892. gas functions to handle these directives, like "stringer" for the
  6893. .string directive, and ARG is the argument to FUNC. csky_pool_count
  6894. essentially wraps the call with the constant pool magic. */
  6895. static void
  6896. csky_pool_count (void (*func) (int), int arg)
  6897. {
  6898. const fragS *curr_frag = frag_now;
  6899. offsetT added = -frag_now_fix_octets ();
  6900. (*func) (arg);
  6901. while (curr_frag != frag_now)
  6902. {
  6903. added += curr_frag->fr_fix;
  6904. curr_frag = curr_frag->fr_next;
  6905. }
  6906. added += frag_now_fix_octets ();
  6907. poolspan += added;
  6908. }
  6909. /* Support the .literals directive. */
  6910. static void
  6911. csky_s_literals (int ignore ATTRIBUTE_UNUSED)
  6912. {
  6913. dump_literals (0);
  6914. demand_empty_rest_of_line ();
  6915. }
  6916. /* Support the .string, etc directives. */
  6917. static void
  6918. csky_stringer (int append_zero)
  6919. {
  6920. if (now_seg == text_section)
  6921. csky_pool_count (stringer, append_zero);
  6922. else
  6923. stringer (append_zero);
  6924. /* We call check_literals here in case a large number of strings are
  6925. being placed into the text section with a sequence of stringer
  6926. directives. In theory we could be upsetting something if these
  6927. strings are actually in an indexed table instead of referenced by
  6928. individual labels. Let us hope that that never happens. */
  6929. check_literals (2, 0);
  6930. }
  6931. /* Support integer-mode constructors like .word, .byte, etc. */
  6932. static void
  6933. csky_cons (int nbytes)
  6934. {
  6935. mapping_state (MAP_DATA);
  6936. if (nbytes == 4) /* @GOT. */
  6937. {
  6938. do
  6939. {
  6940. bfd_reloc_code_real_type reloc;
  6941. expressionS exp;
  6942. reloc = BFD_RELOC_NONE;
  6943. expression (&exp);
  6944. lex_got (&reloc, NULL);
  6945. if (exp.X_op == O_symbol && reloc != BFD_RELOC_NONE)
  6946. {
  6947. reloc_howto_type *howto
  6948. = bfd_reloc_type_lookup (stdoutput, reloc);
  6949. int size = bfd_get_reloc_size (howto);
  6950. if (size > nbytes)
  6951. as_bad (ngettext ("%s relocations do not fit in %d byte",
  6952. "%s relocations do not fit in %d bytes",
  6953. nbytes),
  6954. howto->name, nbytes);
  6955. else
  6956. {
  6957. register char *p = frag_more ((int) nbytes);
  6958. int offset = nbytes - size;
  6959. fix_new_exp (frag_now,
  6960. p - frag_now->fr_literal + offset,
  6961. size, &exp, 0, reloc);
  6962. }
  6963. }
  6964. else
  6965. emit_expr (&exp, (unsigned int) nbytes);
  6966. if (now_seg == text_section)
  6967. poolspan += nbytes;
  6968. }
  6969. while (*input_line_pointer++ == ',');
  6970. /* Put terminator back into stream. */
  6971. input_line_pointer --;
  6972. demand_empty_rest_of_line ();
  6973. return;
  6974. }
  6975. if (now_seg == text_section)
  6976. csky_pool_count (cons, nbytes);
  6977. else
  6978. cons (nbytes);
  6979. /* In theory we ought to call check_literals (2,0) here in case
  6980. we need to dump the literal table. We cannot do this however,
  6981. as the directives that we are intercepting may be being used
  6982. to build a switch table, and we must not interfere with its
  6983. contents. Instead we cross our fingers and pray... */
  6984. }
  6985. /* Support floating-mode constant directives like .float and .double. */
  6986. static void
  6987. csky_float_cons (int float_type)
  6988. {
  6989. mapping_state (MAP_DATA);
  6990. if (now_seg == text_section)
  6991. csky_pool_count (float_cons, float_type);
  6992. else
  6993. float_cons (float_type);
  6994. /* See the comment in csky_cons () about calling check_literals.
  6995. It is unlikely that a switch table will be constructed using
  6996. floating point values, but it is still likely that an indexed
  6997. table of floating point constants is being created by these
  6998. directives, so again we must not interfere with their placement. */
  6999. }
  7000. /* Support the .fill directive. */
  7001. static void
  7002. csky_fill (int ignore)
  7003. {
  7004. if (now_seg == text_section)
  7005. csky_pool_count (s_fill, ignore);
  7006. else
  7007. s_fill (ignore);
  7008. check_literals (2, 0);
  7009. }
  7010. /* Handle the section changing pseudo-ops. These call through to the
  7011. normal implementations, but they dump the literal pool first. */
  7012. static void
  7013. csky_s_text (int ignore)
  7014. {
  7015. dump_literals (0);
  7016. #ifdef OBJ_ELF
  7017. obj_elf_text (ignore);
  7018. #else
  7019. s_text (ignore);
  7020. #endif
  7021. }
  7022. static void
  7023. csky_s_data (int ignore)
  7024. {
  7025. dump_literals (0);
  7026. #ifdef OBJ_ELF
  7027. obj_elf_data (ignore);
  7028. #else
  7029. s_data (ignore);
  7030. #endif
  7031. }
  7032. static void
  7033. csky_s_section (int ignore)
  7034. {
  7035. /* Scan forwards to find the name of the section. If the section
  7036. being switched to is ".line" then this is a DWARF1 debug section
  7037. which is arbitrarily placed inside generated code. In this case
  7038. do not dump the literal pool because it is a) inefficient and
  7039. b) would require the generation of extra code to jump around the
  7040. pool. */
  7041. char * ilp = input_line_pointer;
  7042. while (*ilp != 0 && ISSPACE (*ilp))
  7043. ++ ilp;
  7044. if (startswith (ilp, ".line")
  7045. && (ISSPACE (ilp[5]) || *ilp == '\n' || *ilp == '\r'))
  7046. ;
  7047. else
  7048. dump_literals (0);
  7049. #ifdef OBJ_ELF
  7050. obj_elf_section (ignore);
  7051. #endif
  7052. #ifdef OBJ_COFF
  7053. obj_coff_section (ignore);
  7054. #endif
  7055. }
  7056. static void
  7057. csky_s_bss (int needs_align)
  7058. {
  7059. dump_literals (0);
  7060. s_lcomm_bytes (needs_align);
  7061. }
  7062. #ifdef OBJ_ELF
  7063. static void
  7064. csky_s_comm (int needs_align)
  7065. {
  7066. dump_literals (0);
  7067. obj_elf_common (needs_align);
  7068. }
  7069. #endif
  7070. /* Handle the .no_literal_dump directive. */
  7071. static void
  7072. csky_noliteraldump (int ignore ATTRIBUTE_UNUSED)
  7073. {
  7074. do_noliteraldump = 1;
  7075. int insn_num = get_absolute_expression ();
  7076. /* The insn after '.no_literal_dump insn_num' is insn1,
  7077. Don't dump literal pool between insn1 and insn(insn_num+1)
  7078. The insn cannot be the insn generate literal, like lrw & jsri. */
  7079. check_literals (0, insn_num * 2);
  7080. }
  7081. /* Handle the .align directive.
  7082. We must check literals before doing alignment. For example, if
  7083. '.align n', add (2^n-1) to poolspan and check literals. */
  7084. static void
  7085. csky_s_align_ptwo (int arg)
  7086. {
  7087. /* Get the .align's first absolute number. */
  7088. char * temp_pointer = input_line_pointer;
  7089. int align = get_absolute_expression ();
  7090. check_literals (0, (1 << align) - 1);
  7091. input_line_pointer = temp_pointer;
  7092. /* Do alignment. */
  7093. s_align_ptwo (arg);
  7094. }
  7095. /* Handle the .stack_size directive. */
  7096. static void
  7097. csky_stack_size (int arg ATTRIBUTE_UNUSED)
  7098. {
  7099. expressionS exp;
  7100. stack_size_entry *sse
  7101. = (stack_size_entry *) xcalloc (1, sizeof (stack_size_entry));
  7102. expression (&exp);
  7103. if (exp.X_op == O_symbol)
  7104. sse->function = exp.X_add_symbol;
  7105. else
  7106. {
  7107. as_bad (_("the first operand must be a symbol"));
  7108. ignore_rest_of_line ();
  7109. free (sse);
  7110. return;
  7111. }
  7112. SKIP_WHITESPACE ();
  7113. if (*input_line_pointer != ',')
  7114. {
  7115. as_bad (_("missing stack size"));
  7116. ignore_rest_of_line ();
  7117. free (sse);
  7118. return;
  7119. }
  7120. ++input_line_pointer;
  7121. expression (&exp);
  7122. if (exp.X_op == O_constant)
  7123. {
  7124. if (exp.X_add_number < 0 || exp.X_add_number > (offsetT)0xffffffff)
  7125. {
  7126. as_bad (_("value not in range [0, 0xffffffff]"));
  7127. ignore_rest_of_line ();
  7128. free (sse);
  7129. return;
  7130. }
  7131. else
  7132. sse->stack_size = exp.X_add_number;
  7133. }
  7134. else
  7135. {
  7136. as_bad (_("operand must be a constant"));
  7137. ignore_rest_of_line ();
  7138. free (sse);
  7139. return;
  7140. }
  7141. if (*last_stack_size_data != NULL)
  7142. last_stack_size_data = &((*last_stack_size_data)->next);
  7143. *last_stack_size_data = sse;
  7144. }
  7145. /* This table describes all the machine specific pseudo-ops the assembler
  7146. has to support. The fields are:
  7147. pseudo-op name without dot
  7148. function to call to execute this pseudo-op
  7149. Integer arg to pass to the function. */
  7150. const pseudo_typeS md_pseudo_table[] =
  7151. {
  7152. { "export", s_globl, 0 },
  7153. { "import", s_ignore, 0 },
  7154. { "literals", csky_s_literals, 0 },
  7155. { "page", listing_eject, 0 },
  7156. /* The following are to intercept the placement of data into the text
  7157. section (eg addresses for a switch table), so that the space they
  7158. occupy can be taken into account when deciding whether or not to
  7159. dump the current literal pool.
  7160. XXX - currently we do not cope with the .space and .dcb.d directives. */
  7161. { "ascii", csky_stringer, 8 + 0 },
  7162. { "asciz", csky_stringer, 8 + 1 },
  7163. { "byte", csky_cons, 1 },
  7164. { "dc", csky_cons, 2 },
  7165. { "dc.b", csky_cons, 1 },
  7166. { "dc.d", csky_float_cons, 'd'},
  7167. { "dc.l", csky_cons, 4 },
  7168. { "dc.s", csky_float_cons, 'f'},
  7169. { "dc.w", csky_cons, 2 },
  7170. { "dc.x", csky_float_cons, 'x'},
  7171. { "double", csky_float_cons, 'd'},
  7172. { "float", csky_float_cons, 'f'},
  7173. { "hword", csky_cons, 2 },
  7174. { "int", csky_cons, 4 },
  7175. { "long", csky_cons, 4 },
  7176. { "octa", csky_cons, 16 },
  7177. { "quad", csky_cons, 8 },
  7178. { "short", csky_cons, 2 },
  7179. { "single", csky_float_cons, 'f'},
  7180. { "string", csky_stringer, 8 + 1 },
  7181. { "word", csky_cons, 4 },
  7182. { "fill", csky_fill, 0 },
  7183. /* Allow for the effect of section changes. */
  7184. { "text", csky_s_text, 0 },
  7185. { "data", csky_s_data, 0 },
  7186. { "bss", csky_s_bss, 1 },
  7187. #ifdef OBJ_ELF
  7188. { "comm", csky_s_comm, 0 },
  7189. #endif
  7190. { "section", csky_s_section, 0 },
  7191. { "section.s", csky_s_section, 0 },
  7192. { "sect", csky_s_section, 0 },
  7193. { "sect.s", csky_s_section, 0 },
  7194. /* When ".no_literal_dump N" is in front of insn1,
  7195. and instruction sequence is:
  7196. insn1
  7197. insn2
  7198. ......
  7199. insnN+1
  7200. it means literals will not dump between insn1 and insnN+1
  7201. The insn cannot itself generate literal, like lrw & jsri. */
  7202. { "no_literal_dump", csky_noliteraldump, 0 },
  7203. { "align", csky_s_align_ptwo, 0 },
  7204. { "stack_size", csky_stack_size, 0 },
  7205. {0, 0, 0}
  7206. };
  7207. /* Implement tc_cfi_frame_initial_instructions. */
  7208. void
  7209. csky_cfi_frame_initial_instructions (void)
  7210. {
  7211. int sp_reg = IS_CSKY_V1 (mach_flag) ? 0 : 14;
  7212. cfi_add_CFA_def_cfa_register (sp_reg);
  7213. }
  7214. /* Implement tc_regname_to_dw2regnum. */
  7215. int
  7216. tc_csky_regname_to_dw2regnum (char *regname)
  7217. {
  7218. int reg_num = -1;
  7219. int len;
  7220. /* FIXME the reg should be parsed according to
  7221. the abi version. */
  7222. reg_num = csky_get_reg_val (regname, &len);
  7223. return reg_num;
  7224. }