tc-nds32.c 185 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721
  1. /* tc-nds32.c -- Assemble for the nds32
  2. Copyright (C) 2012-2015 Free Software Foundation, Inc.
  3. Contributed by Andes Technology Corporation.
  4. This file is part of GAS, the GNU Assembler.
  5. GAS is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3, or (at your option)
  8. any later version.
  9. GAS is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GAS; see the file COPYING. If not, write to the Free
  15. Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
  16. 02110-1301, USA. */
  17. #include "as.h"
  18. #include "safe-ctype.h"
  19. #include "subsegs.h"
  20. #include "symcat.h"
  21. #include "dwarf2dbg.h"
  22. #include "dw2gencfi.h"
  23. #include "opcodes/nds32-asm.h"
  24. #include "elf/nds32.h"
  25. #include "bfd/elf32-nds32.h"
  26. #include "hash.h"
  27. #include "sb.h"
  28. #include "macro.h"
  29. #include "struc-symbol.h"
  30. #include "opcode/nds32.h"
  31. #include <stdio.h>
  32. /* GAS definitions. */
  33. /* Characters which start a comment. */
  34. const char comment_chars[] = "!";
  35. /* Characters which start a comment when they appear at the start of a line. */
  36. const char line_comment_chars[] = "#!";
  37. /* Characters which separate lines (null and newline are by default). */
  38. const char line_separator_chars[] = ";";
  39. /* Characters which may be used as the exponent character
  40. in a floating point number. */
  41. const char EXP_CHARS[] = "eE";
  42. /* Characters which may be used to indicate a floating point constant. */
  43. const char FLT_CHARS[] = "dDfF";
  44. static int enable_16bit = 1;
  45. /* Save for md_assemble to distinguish if this instruction is
  46. expanded from the pseudo instruction. */
  47. static bfd_boolean pseudo_opcode = FALSE;
  48. static struct nds32_relocs_pattern *relocs_list = NULL;
  49. /* Save instruction relation to inserting relaxation relocation. */
  50. struct nds32_relocs_pattern
  51. {
  52. segT seg;
  53. fragS *frag;
  54. frchainS *frchain;
  55. symbolS *sym;
  56. fixS* fixP;
  57. struct nds32_opcode *opcode;
  58. char *where;
  59. struct nds32_relocs_pattern *next;
  60. };
  61. /* Suffix name and relocation. */
  62. struct suffix_name
  63. {
  64. char *suffix;
  65. short unsigned int reloc;
  66. int pic;
  67. };
  68. static int vec_size = 0;
  69. /* If the assembly code is generated by compiler, it is supposed to have
  70. ".flag verbatim" at beginning of the content. We have
  71. 'nds32_flag' to parse it and set this field to be non-zero. */
  72. static int verbatim = 0;
  73. static struct hash_control *nds32_gprs_hash;
  74. static struct hash_control *nds32_hint_hash;
  75. #define TLS_REG "$r27"
  76. #define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
  77. /* Generate relocation for relax or not, and the default is true. */
  78. static int enable_relax_relocs = 1;
  79. /* The value will be used in RELAX_ENTRY. */
  80. static int enable_relax_ex9 = 0;
  81. /* The value will be used in RELAX_ENTRY. */
  82. static int enable_relax_ifc = 0;
  83. /* Save option -O for perfomance. */
  84. static int optimize = 0;
  85. /* Save option -Os for code size. */
  86. static int optimize_for_space = 0;
  87. /* Flag to save label exist. */
  88. static int label_exist = 0;
  89. /* Flag to save state in omit_fp region. */
  90. static int in_omit_fp = 0;
  91. extern struct nds32_keyword keyword_gpr[];
  92. /* Tag there is relax relocation having to link. */
  93. static bfd_boolean relaxing = FALSE;
  94. static struct hash_control *nds32_relax_info_hash;
  95. static relax_info_t relax_table[] =
  96. {
  97. {
  98. "jal", /* opcode */
  99. BR_RANGE_S16M, /* br_range */
  100. {{0, 0, 0, FALSE}}, /* cond_field */
  101. {
  102. {
  103. INSN_JAL /* jal label */
  104. }, /* BR_RANGE_S256 */
  105. {
  106. INSN_JAL /* jal label */
  107. }, /* BR_RANGE_S16K */
  108. {
  109. INSN_JAL /* jal label */
  110. }, /* BR_RANGE_S64K */
  111. {
  112. INSN_JAL /* jal label */
  113. }, /* BR_RANGE_S16M */
  114. {
  115. INSN_SETHI_TA, /* sethi $ta, label */
  116. INSN_ORI_TA, /* ori $ta, $ta, label */
  117. INSN_JRAL_TA
  118. }, /* BR_RANGE_U4G */
  119. }, /* relax_code_seq */
  120. {
  121. {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
  122. {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
  123. {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
  124. {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
  125. {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
  126. }, /* relax_code_condition */
  127. {4, 4, 4, 4, 12}, /* relax_code_size */
  128. {4, 4, 4, 4, 4}, /* relax_branch_isize */
  129. {
  130. {
  131. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  132. {0, 0, 0, 0}
  133. }, /* BR_RANGE_S256 */
  134. {
  135. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  136. {0, 0, 0, 0}
  137. }, /* BR_RANGE_S16K */
  138. {
  139. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  140. {0, 0, 0, 0}
  141. }, /* BR_RANGE_S64K */
  142. {
  143. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  144. {0, 0, 0, 0}
  145. }, /* BR_RANGE_S16M */
  146. {
  147. {0, 4, 0, BFD_RELOC_NDS32_HI20},
  148. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL4},
  149. {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
  150. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  151. {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  152. {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  153. {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  154. {0, 0, 0, 0}
  155. } /* BR_RANGE_U4G */
  156. } /* relax_fixup */
  157. },
  158. {
  159. "bltzal", /* opcode */
  160. BR_RANGE_S64K, /* br_range */
  161. {
  162. {0, 20, 0x1F, FALSE},
  163. {0, 0, 0, FALSE}
  164. }, /* cond_field */
  165. {
  166. {
  167. INSN_BLTZAL /* bltzal $rt, label */
  168. }, /* BR_RANGE_S256 */
  169. {
  170. INSN_BLTZAL /* bltzal $rt, label */
  171. }, /* BR_RANGE_S16K */
  172. {
  173. INSN_BLTZAL /* bltzal $rt, label */
  174. }, /* BR_RANGE_S64K */
  175. {
  176. INSN_BGEZ, /* bgez $rt, $1 */
  177. INSN_JAL /* jal label */
  178. }, /* BR_RANGE_S16M */
  179. {
  180. INSN_BGEZ, /* bgez $rt, $1 */
  181. INSN_SETHI_TA, /* sethi $ta, label */
  182. INSN_ORI_TA, /* ori $ta, $ta, label */
  183. INSN_JRAL_TA /* jral $ta */
  184. } /* BR_RANGE_U4G */
  185. }, /* relax_code_seq */
  186. {
  187. {
  188. {0, 20, 0x1F, FALSE},
  189. {0, 0, 0, FALSE}
  190. }, /* BR_RANGE_S256 */
  191. {
  192. {0, 20, 0x1F, FALSE},
  193. {0, 0, 0, FALSE}
  194. }, /* BR_RANGE_S16K */
  195. {
  196. {0, 20, 0x1F, FALSE},
  197. {0, 0, 0, FALSE}
  198. }, /* BR_RANGE_S64K */
  199. {
  200. {0, 20, 0x1F, FALSE},
  201. {0, 0, 0, FALSE}
  202. }, /* BR_RANGE_S16M */
  203. {
  204. {0, 20, 0x1F, FALSE},
  205. {0, 0, 0, FALSE}
  206. } /* BR_RANGE_U4G */
  207. }, /* relax_code_condition */
  208. {4, 4, 4, 8, 16}, /* relax_code_size */
  209. {4, 4, 4, 4, 4}, /* relax_branch_isize */
  210. {
  211. {
  212. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  213. {0, 0, 0, 0}
  214. }, /* BR_RANGE_S256 */
  215. {
  216. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  217. {0, 0, 0, 0}
  218. }, /* BR_RANGE_S16K */
  219. {
  220. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  221. {0, 0, 0, 0}
  222. }, /* BR_RANGE_S64K */
  223. {
  224. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  225. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
  226. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  227. {0, 0, 0, 0}
  228. }, /* BR_RANGE_S16M */
  229. {
  230. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  231. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
  232. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  233. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  234. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  235. {8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  236. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  237. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  238. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  239. {0, 0, 0, 0}
  240. } /* BR_RANGE_U4G */
  241. } /* relax_fixup */
  242. },
  243. {
  244. "bgezal", /* opcode */
  245. BR_RANGE_S64K, /* br_range */
  246. {
  247. {0, 20, 0x1F, FALSE},
  248. {0, 0, 0, FALSE}
  249. }, /* cond_field */
  250. {
  251. {
  252. INSN_BGEZAL /* bgezal $rt, label */
  253. }, /* BR_RANGE_S256 */
  254. {
  255. INSN_BGEZAL /* bgezal $rt, label */
  256. }, /* BR_RANGE_S16K */
  257. {
  258. INSN_BGEZAL /* bgezal $rt, label */
  259. }, /* BR_RANGE_S64K */
  260. {
  261. INSN_BLTZ, /* bltz $rt, $1 */
  262. INSN_JAL /* jal label */
  263. }, /* BR_RANGE_S16M */
  264. {
  265. INSN_BLTZ, /* bltz $rt, $1 */
  266. INSN_SETHI_TA, /* sethi $ta, label */
  267. INSN_ORI_TA, /* ori $ta, $ta, label */
  268. INSN_JRAL_TA /* jral $ta */
  269. } /* BR_RANGE_U4G */
  270. }, /* relax_code_seq */
  271. {
  272. {
  273. {0, 20, 0x1F, FALSE},
  274. {0, 0, 0, FALSE}
  275. }, /* BR_RANGE_S256 */
  276. {
  277. {0, 20, 0x1F, FALSE},
  278. {0, 0, 0, FALSE}
  279. }, /* BR_RANGE_S16K */
  280. {
  281. {0, 20, 0x1F, FALSE},
  282. {0, 0, 0, FALSE}
  283. }, /* BR_RANGE_S64K */
  284. {
  285. {0, 20, 0x1F, FALSE},
  286. {0, 0, 0, FALSE}
  287. }, /* BR_RANGE_S16M */
  288. {
  289. {0, 20, 0x1F, FALSE},
  290. {0, 0, 0, FALSE}
  291. } /* BR_RANGE_U4G */
  292. }, /* relax_code_condition */
  293. {4, 4, 4, 8, 16}, /* relax_code_size */
  294. {4, 4, 4, 4, 4}, /* relax_branch_isize */
  295. {
  296. {
  297. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  298. {0, 0, 0, 0}
  299. }, /* BR_RANGE_S256 */
  300. {
  301. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  302. {0, 0, 0, 0}
  303. }, /* BR_RANGE_S16K */
  304. {
  305. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  306. {0, 0, 0, 0}
  307. }, /* BR_RANGE_S64K */
  308. {
  309. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  310. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
  311. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  312. {0, 0, 0, 0}
  313. }, /* BR_RANGE_S16M */
  314. {
  315. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  316. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
  317. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  318. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  319. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  320. {8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  321. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  322. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  323. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  324. {0, 0, 0, 0}
  325. } /* BR_RANGE_U4G */
  326. } /* relax_fixup */
  327. },
  328. {
  329. "j", /* opcode */
  330. BR_RANGE_S16M, /* br_range */
  331. {{0, 0, 0, FALSE}}, /* cond_field */
  332. {
  333. {
  334. (INSN_J8 << 16) /* j8 label */
  335. }, /* BR_RANGE_S256 */
  336. {
  337. INSN_J /* j label */
  338. }, /* BR_RANGE_S16K */
  339. {
  340. INSN_J /* j label */
  341. }, /* BR_RANGE_S64K */
  342. {
  343. INSN_J /* j label */
  344. }, /* BR_RANGE_S16M */
  345. {
  346. INSN_SETHI_TA, /* sethi $ta, label */
  347. INSN_ORI_TA, /* ori $ta, $ta, label */
  348. INSN_JR_TA /* jr $ta */
  349. }, /* BR_RANGE_U4G */
  350. }, /* relax_code_seq */
  351. {
  352. {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
  353. {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
  354. {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
  355. {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
  356. {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
  357. }, /* relax_code_condition */
  358. {2, 4, 4, 4, 12}, /* relax_code_size */
  359. {2, 4, 4, 4, 4}, /* relax_branch_isize */
  360. {
  361. {
  362. {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
  363. {0, 0, 0, 0}
  364. }, /* BR_RANGE_S256 */
  365. {
  366. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  367. {0, 0, 0, 0}
  368. }, /* BR_RANGE_S16K */
  369. {
  370. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  371. {0, 0, 0, 0}
  372. }, /* BR_RANGE_S64K */
  373. {
  374. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  375. {0, 0, 0, 0}
  376. }, /* BR_RANGE_S16M */
  377. {
  378. {0, 4, 0, BFD_RELOC_NDS32_HI20},
  379. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
  380. {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
  381. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  382. {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  383. {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  384. {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  385. {0, 0, 0, 0}
  386. } /* BR_RANGE_U4G */
  387. } /* relax_fixup */
  388. },
  389. {
  390. "j8", /* opcode */
  391. BR_RANGE_S256, /* br_range */
  392. {{0, 0, 0, FALSE}}, /* cond_field */
  393. {
  394. {
  395. (INSN_J8 << 16) /* j8 label */
  396. }, /* BR_RANGE_S256 */
  397. {
  398. INSN_J /* j label */
  399. }, /* BR_RANGE_S16K */
  400. {
  401. INSN_J /* j label */
  402. }, /* BR_RANGE_S64K */
  403. {
  404. INSN_J /* j label */
  405. }, /* BR_RANGE_S16M */
  406. {
  407. INSN_SETHI_TA, /* sethi $ta, label */
  408. INSN_ORI_TA, /* ori $ta, $ta, label */
  409. INSN_JR_TA /* jr $ta */
  410. }, /* BR_RANGE_U4G */
  411. }, /* relax_code_seq */
  412. {
  413. {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
  414. {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
  415. {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
  416. {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
  417. {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
  418. }, /* relax_code_condition */
  419. {2, 4, 4, 4, 12}, /* relax_code_size */
  420. {2, 4, 4, 4, 4}, /* relax_branch_isize */
  421. {
  422. {
  423. {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
  424. {0, 0, 0, 0}
  425. }, /* BR_RANGE_S256 */
  426. {
  427. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  428. {0, 0, 0, 0}
  429. }, /* BR_RANGE_S16K */
  430. {
  431. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  432. {0, 0, 0, 0}
  433. }, /* BR_RANGE_S64K */
  434. {
  435. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  436. {0, 0, 0, 0}
  437. }, /* BR_RANGE_S16M */
  438. {
  439. {0, 4, 0, BFD_RELOC_NDS32_HI20},
  440. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
  441. {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
  442. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  443. {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  444. {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  445. {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  446. {0, 0, 0, 0}
  447. } /* BR_RANGE_U4G */
  448. } /* relax_fixup */
  449. },
  450. {
  451. "beqz", /* opcode */
  452. BR_RANGE_S64K, /* br_range */
  453. {
  454. {0, 20, 0x1F, FALSE},
  455. {0, 0, 0, FALSE}
  456. }, /* cond_field */
  457. {
  458. {
  459. INSN_BEQZ /* beqz $rt, label */
  460. }, /* BR_RANGE_S256 */
  461. {
  462. INSN_BEQZ /* beqz $rt, label */
  463. }, /* BR_RANGE_S16K */
  464. {
  465. INSN_BEQZ /* beqz $rt, label */
  466. }, /* BR_RANGE_S64K */
  467. {
  468. INSN_BNEZ, /* bnez $rt, $1 */
  469. INSN_J /* j label */
  470. }, /* BR_RANGE_S16M */
  471. {
  472. INSN_BNEZ, /* bnez $rt, $1 */
  473. INSN_SETHI_TA, /* sethi $ta, label */
  474. INSN_ORI_TA, /* ori $ta, $ta, label */
  475. INSN_JR_TA /* jr $ta */
  476. } /* BR_RANGE_U4G */
  477. }, /* relax_code_seq */
  478. {
  479. {
  480. {0, 20, 0x1F, FALSE},
  481. {0, 0, 0, FALSE}
  482. }, /* BR_RANGE_S256 */
  483. {
  484. {0, 20, 0x1F, FALSE},
  485. {0, 0, 0, FALSE}
  486. }, /* BR_RANGE_S16K */
  487. {
  488. {0, 20, 0x1F, FALSE},
  489. {0, 0, 0, FALSE}
  490. }, /* BR_RANGE_S64K */
  491. {
  492. {0, 20, 0x1F, FALSE},
  493. {0, 0, 0, FALSE}
  494. }, /* BR_RANGE_S16M */
  495. {
  496. {0, 20, 0x1F, FALSE},
  497. {0, 0, 0, FALSE}
  498. } /* BR_RANGE_U4G */
  499. }, /* relax_code_condition */
  500. {4, 4, 4, 8, 16}, /* relax_code_size */
  501. {4, 4, 4, 4, 4}, /* relax_branch_isize */
  502. {
  503. {
  504. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  505. {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
  506. {0, 0, 0, 0}
  507. }, /* BR_RANGE_S256 */
  508. {
  509. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  510. {0, 0, 0, 0}
  511. }, /* BR_RANGE_S16K */
  512. {
  513. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  514. {0, 0, 0, 0}
  515. }, /* BR_RANGE_S64K */
  516. {
  517. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  518. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  519. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  520. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  521. {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  522. {0, 0, 0, 0}
  523. }, /* BR_RANGE_S16M */
  524. {
  525. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  526. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  527. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
  528. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  529. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  530. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  531. {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
  532. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  533. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  534. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  535. {0, 0, 0, 0}
  536. } /* BR_RANGE_U4G */
  537. } /* relax_fixup */
  538. },
  539. {
  540. "bgez", /* opcode */
  541. BR_RANGE_S64K, /* br_range */
  542. {
  543. {0, 20, 0x1F, FALSE},
  544. {0, 0, 0, FALSE}
  545. }, /* cond_field */
  546. {
  547. {
  548. INSN_BGEZ /* bgez $rt, label */
  549. }, /* BR_RANGE_S256 */
  550. {
  551. INSN_BGEZ /* bgez $rt, label */
  552. }, /* BR_RANGE_S16K */
  553. {
  554. INSN_BGEZ /* bgez $rt, label */
  555. }, /* BR_RANGE_S64K */
  556. {
  557. INSN_BLTZ, /* bltz $rt, $1 */
  558. INSN_J /* j label */
  559. }, /* BR_RANGE_S16M */
  560. {
  561. INSN_BLTZ, /* bltz $rt, $1 */
  562. INSN_SETHI_TA, /* sethi $ta, label */
  563. INSN_ORI_TA, /* ori $ta, $ta, label */
  564. INSN_JR_TA /* jr $ta */
  565. } /* BR_RANGE_U4G */
  566. }, /* relax_code_seq */
  567. {
  568. {
  569. {0, 20, 0x1F, FALSE},
  570. {0, 0, 0, FALSE}
  571. }, /* BR_RANGE_S256 */
  572. {
  573. {0, 20, 0x1F, FALSE},
  574. {0, 0, 0, FALSE}
  575. }, /* BR_RANGE_S16K */
  576. {
  577. {0, 20, 0x1F, FALSE},
  578. {0, 0, 0, FALSE}
  579. }, /* BR_RANGE_S64K */
  580. {
  581. {0, 20, 0x1F, FALSE},
  582. {0, 0, 0, FALSE}
  583. }, /* BR_RANGE_S16M */
  584. {
  585. {0, 20, 0x1F, FALSE},
  586. {0, 0, 0, FALSE}
  587. } /* BR_RANGE_U4G */
  588. }, /* relax_code_condition */
  589. {4, 4, 4, 8, 16}, /* relax_code_size */
  590. {4, 4, 4, 4, 4}, /* relax_branch_isize */
  591. {
  592. {
  593. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  594. {0, 0, 0, 0}
  595. }, /* BR_RANGE_S256 */
  596. {
  597. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  598. {0, 0, 0, 0}
  599. }, /* BR_RANGE_S16K */
  600. {
  601. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  602. {0, 0, 0, 0}
  603. }, /* BR_RANGE_S64K */
  604. {
  605. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  606. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  607. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  608. {0, 0, 0, 0}
  609. }, /* BR_RANGE_S16M */
  610. {
  611. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  612. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
  613. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  614. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  615. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  616. {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
  617. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  618. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  619. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  620. {0, 0, 0, 0}
  621. } /* BR_RANGE_U4G */
  622. } /* relax_fixup */
  623. },
  624. {
  625. "bnez", /* opcode */
  626. BR_RANGE_S64K, /* br_range */
  627. {
  628. {0, 20, 0x1F, FALSE},
  629. {0, 0, 0, FALSE}
  630. }, /* cond_field */
  631. {
  632. {
  633. INSN_BNEZ /* bnez $rt, label */
  634. }, /* BR_RANGE_S256 */
  635. {
  636. INSN_BNEZ /* bnez $rt, label */
  637. }, /* BR_RANGE_S16K */
  638. {
  639. INSN_BNEZ /* bnez $rt, label */
  640. }, /* BR_RANGE_S64K */
  641. {
  642. INSN_BEQZ, /* beqz $rt, $1 */
  643. INSN_J /* j label */
  644. }, /* BR_RANGE_S16M */
  645. {
  646. INSN_BEQZ, /* beqz $rt, $1 */
  647. INSN_SETHI_TA, /* sethi $ta, label */
  648. INSN_ORI_TA, /* ori $ta, $ta, label */
  649. INSN_JR_TA /* jr $ta */
  650. } /* BR_RANGE_U4G */
  651. }, /* relax_code_seq */
  652. {
  653. {
  654. {0, 20, 0x1F, FALSE},
  655. {0, 0, 0, FALSE}
  656. }, /* BR_RANGE_S256 */
  657. {
  658. {0, 20, 0x1F, FALSE},
  659. {0, 0, 0, FALSE}
  660. }, /* BR_RANGE_S16K */
  661. {
  662. {0, 20, 0x1F, FALSE},
  663. {0, 0, 0, FALSE}
  664. }, /* BR_RANGE_S64K */
  665. {
  666. {0, 20, 0x1F, FALSE},
  667. {0, 0, 0, FALSE}
  668. }, /* BR_RANGE_S16M */
  669. {
  670. {0, 20, 0x1F, FALSE},
  671. {0, 0, 0, FALSE}
  672. } /* BR_RANGE_U4G */
  673. }, /* relax_code_condition */
  674. {4, 4, 4, 8, 16}, /* relax_code_size */
  675. {4, 4, 4, 4, 4}, /* relax_branch_isize */
  676. {
  677. {
  678. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  679. {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
  680. {0, 0, 0, 0}
  681. }, /* BR_RANGE_S256 */
  682. {
  683. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  684. {0, 0, 0, 0}
  685. }, /* BR_RANGE_S16K */
  686. {
  687. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  688. {0, 0, 0, 0}
  689. }, /* BR_RANGE_S64K */
  690. {
  691. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  692. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  693. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  694. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  695. {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  696. {0, 0, 0, 0}
  697. }, /* BR_RANGE_S16M */
  698. {
  699. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  700. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  701. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
  702. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  703. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  704. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  705. {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
  706. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  707. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  708. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  709. {0, 0, 0, 0}
  710. } /* BR_RANGE_U4G */
  711. } /* relax_fixup */
  712. },
  713. {
  714. "bgtz", /* opcode */
  715. BR_RANGE_S64K, /* br_range */
  716. {
  717. {0, 20, 0x1F, FALSE},
  718. {0, 0, 0, FALSE}
  719. }, /* cond_field */
  720. {
  721. {
  722. INSN_BGTZ /* bgtz $rt, label */
  723. }, /* BR_RANGE_S256 */
  724. {
  725. INSN_BGTZ /* bgtz $rt, label */
  726. }, /* BR_RANGE_S16K */
  727. {
  728. INSN_BGTZ /* bgtz $rt, label */
  729. }, /* BR_RANGE_S64K */
  730. {
  731. INSN_BLEZ, /* blez $rt, $1 */
  732. INSN_J /* j label */
  733. }, /* BR_RANGE_S16M */
  734. {
  735. INSN_BLEZ, /* blez $rt, $1 */
  736. INSN_SETHI_TA, /* sethi $ta, label */
  737. INSN_ORI_TA, /* ori $ta, $ta, label */
  738. INSN_JR_TA /* jr $ta */
  739. } /* BR_RANGE_U4G */
  740. }, /* relax_code_seq */
  741. {
  742. {
  743. {0, 20, 0x1F, FALSE},
  744. {0, 0, 0, FALSE}
  745. }, /* BR_RANGE_S256 */
  746. {
  747. {0, 20, 0x1F, FALSE},
  748. {0, 0, 0, FALSE}
  749. }, /* BR_RANGE_S16K */
  750. {
  751. {0, 20, 0x1F, FALSE},
  752. {0, 0, 0, FALSE}
  753. }, /* BR_RANGE_S64K */
  754. {
  755. {0, 20, 0x1F, FALSE},
  756. {0, 0, 0, FALSE}
  757. }, /* BR_RANGE_S16M */
  758. {
  759. {0, 20, 0x1F, FALSE},
  760. {0, 0, 0, FALSE}
  761. } /* BR_RANGE_U4G */
  762. }, /* relax_code_condition */
  763. {4, 4, 4, 8, 16}, /* relax_code_size */
  764. {4, 4, 4, 4, 4}, /* relax_branch_isize */
  765. {
  766. {
  767. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  768. {0, 0, 0, 0}
  769. }, /* BR_RANGE_S256 */
  770. {
  771. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  772. {0, 0, 0, 0}
  773. }, /* BR_RANGE_S16K */
  774. {
  775. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  776. {0, 0, 0, 0}
  777. }, /* BR_RANGE_S64K */
  778. {
  779. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  780. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  781. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  782. {0, 0, 0, 0}
  783. }, /* BR_RANGE_S16M */
  784. {
  785. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  786. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
  787. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  788. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  789. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  790. {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
  791. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  792. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  793. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  794. {0, 0, 0, 0}
  795. } /* BR_RANGE_U4G */
  796. } /* relax_fixup */
  797. },
  798. {
  799. "blez", /* opcode */
  800. BR_RANGE_S64K, /* br_range */
  801. {
  802. {0, 20, 0x1F, FALSE},
  803. {0, 0, 0, FALSE}
  804. }, /* cond_field */
  805. {
  806. {
  807. INSN_BLEZ /* blez $rt, label */
  808. }, /* BR_RANGE_S256 */
  809. {
  810. INSN_BLEZ /* blez $rt, label */
  811. }, /* BR_RANGE_S16K */
  812. {
  813. INSN_BLEZ /* blez $rt, label */
  814. }, /* BR_RANGE_S64K */
  815. {
  816. INSN_BGTZ, /* bgtz $rt, $1 */
  817. INSN_J /* j label */
  818. }, /* BR_RANGE_S16M */
  819. {
  820. INSN_BGTZ, /* bgtz $rt, $1 */
  821. INSN_SETHI_TA, /* sethi $ta, label */
  822. INSN_ORI_TA, /* ori $ta, $ta, label */
  823. INSN_JR_TA /* jr $ta */
  824. } /* BR_RANGE_U4G */
  825. }, /* relax_code_seq */
  826. {
  827. {
  828. {0, 20, 0x1F, FALSE},
  829. {0, 0, 0, FALSE}
  830. }, /* BR_RANGE_S256 */
  831. {
  832. {0, 20, 0x1F, FALSE},
  833. {0, 0, 0, FALSE}
  834. }, /* BR_RANGE_S16K */
  835. {
  836. {0, 20, 0x1F, FALSE},
  837. {0, 0, 0, FALSE}
  838. }, /* BR_RANGE_S64K */
  839. {
  840. {0, 20, 0x1F, FALSE},
  841. {0, 0, 0, FALSE}
  842. }, /* BR_RANGE_S16M */
  843. {
  844. {0, 20, 0x1F, FALSE},
  845. {0, 0, 0, FALSE}
  846. } /* BR_RANGE_U4G */
  847. }, /* relax_code_condition */
  848. {4, 4, 4, 8, 16}, /* relax_code_size */
  849. {4, 4, 4, 4, 4}, /* relax_branch_isize */
  850. {
  851. {
  852. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  853. {0, 0, 0, 0}
  854. }, /* BR_RANGE_S256 */
  855. {
  856. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  857. {0, 0, 0, 0}
  858. }, /* BR_RANGE_S16K */
  859. {
  860. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  861. {0, 0, 0, 0}
  862. }, /* BR_RANGE_S64K */
  863. {
  864. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  865. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  866. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  867. {0, 0, 0, 0}
  868. }, /* BR_RANGE_S16M */
  869. {
  870. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  871. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
  872. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  873. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  874. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  875. {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
  876. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  877. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  878. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  879. {0, 0, 0, 0}
  880. } /* BR_RANGE_U4G */
  881. } /* relax_fixup */
  882. },
  883. {
  884. "bltz", /* opcode */
  885. BR_RANGE_S64K, /* br_range */
  886. {
  887. {0, 20, 0x1F, FALSE},
  888. {0, 0, 0, FALSE}
  889. }, /* cond_field */
  890. {
  891. {
  892. INSN_BLTZ /* bltz $rt, label */
  893. }, /* BR_RANGE_S256 */
  894. {
  895. INSN_BLTZ /* bltz $rt, label */
  896. }, /* BR_RANGE_S16K */
  897. {
  898. INSN_BLTZ /* bltz $rt, label */
  899. }, /* BR_RANGE_S64K */
  900. {
  901. INSN_BGEZ, /* bgez $rt, $1 */
  902. INSN_J /* j label */
  903. }, /* BR_RANGE_S16M */
  904. {
  905. INSN_BGEZ, /* bgez $rt, $1 */
  906. INSN_SETHI_TA, /* sethi $ta, label */
  907. INSN_ORI_TA, /* ori $ta, $ta, label */
  908. INSN_JR_TA /* jr $ta */
  909. } /* BR_RANGE_U4G */
  910. }, /* relax_code_seq */
  911. {
  912. {
  913. {0, 20, 0x1F, FALSE},
  914. {0, 0, 0, FALSE}
  915. }, /* BR_RANGE_S256 */
  916. {
  917. {0, 20, 0x1F, FALSE},
  918. {0, 0, 0, FALSE}
  919. }, /* BR_RANGE_S16K */
  920. {
  921. {0, 20, 0x1F, FALSE},
  922. {0, 0, 0, FALSE}
  923. }, /* BR_RANGE_S64K */
  924. {
  925. {0, 20, 0x1F, FALSE},
  926. {0, 0, 0, FALSE}
  927. }, /* BR_RANGE_S16M */
  928. {
  929. {0, 20, 0x1F, FALSE},
  930. {0, 0, 0, FALSE}
  931. } /* BR_RANGE_U4G */
  932. }, /* relax_code_condition */
  933. {4, 4, 4, 8, 16}, /* relax_code_size */
  934. {4, 4, 4, 4, 4}, /* relax_branch_isize */
  935. {
  936. {
  937. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  938. {0, 0, 0, 0}
  939. }, /* BR_RANGE_S256 */
  940. {
  941. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  942. {0, 0, 0, 0}
  943. }, /* BR_RANGE_S16K */
  944. {
  945. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  946. {0, 0, 0, 0}
  947. }, /* BR_RANGE_S64K */
  948. {
  949. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  950. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  951. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  952. {0, 0, 0, 0}
  953. }, /* BR_RANGE_S16M */
  954. {
  955. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  956. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
  957. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  958. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  959. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  960. {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
  961. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  962. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  963. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  964. {0, 0, 0, 0}
  965. } /* BR_RANGE_U4G */
  966. } /* relax_fixup */
  967. },
  968. {
  969. "beq", /* opcode */
  970. BR_RANGE_S16K, /* br_range */
  971. {
  972. {0, 20, 0x1F, FALSE},
  973. {0, 15, 0x1F, FALSE},
  974. {0, 0, 0, FALSE}
  975. }, /* cond_field */
  976. {
  977. {
  978. INSN_BEQ /* beq $rt, $ra, label */
  979. }, /* BR_RANGE_S256 */
  980. {
  981. INSN_BEQ /* beq $rt, $ra, label */
  982. }, /* BR_RANGE_S16K */
  983. {
  984. INSN_BNE, /* bne $rt, $ra, $1 */
  985. INSN_J /* j label */
  986. }, /* BR_RANGE_S64K */
  987. {
  988. INSN_BNE, /* bne $rt, $ra, $1 */
  989. INSN_J /* j label */
  990. }, /* BR_RANGE_S16M */
  991. {
  992. INSN_BNE, /* bne $rt, $ra, $1 */
  993. INSN_SETHI_TA, /* sethi $ta, label */
  994. INSN_ORI_TA, /* ori $ta, $ta, label */
  995. INSN_JR_TA /* jr $ta */
  996. } /* BR_RANGE_U4G */
  997. }, /* relax_code_seq */
  998. {
  999. {
  1000. {0, 20, 0x1F, FALSE},
  1001. {0, 15, 0x1F, FALSE},
  1002. {0, 0, 0, FALSE}
  1003. }, /* BR_RANGE_S256 */
  1004. {
  1005. {0, 20, 0x1F, FALSE},
  1006. {0, 15, 0x1F, FALSE},
  1007. {0, 0, 0, FALSE}
  1008. }, /* BR_RANGE_S16K */
  1009. {
  1010. {0, 20, 0x1F, FALSE},
  1011. {0, 15, 0x1F, FALSE},
  1012. {0, 0, 0, FALSE}
  1013. }, /* BR_RANGE_S64K */
  1014. {
  1015. {0, 20, 0x1F, FALSE},
  1016. {0, 15, 0x1F, FALSE},
  1017. {0, 0, 0, FALSE}
  1018. }, /* BR_RANGE_S16M */
  1019. {
  1020. {0, 20, 0x1F, FALSE},
  1021. {0, 15, 0x1F, FALSE},
  1022. {0, 0, 0, FALSE}
  1023. } /* BR_RANGE_U4G */
  1024. }, /* relax_code_condition */
  1025. {4, 4, 8, 8, 16}, /* relax_code_size */
  1026. {4, 4, 4, 4, 4}, /* relax_branch_isize */
  1027. {
  1028. {
  1029. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1030. {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
  1031. {0, 0, 0, 0}
  1032. }, /* BR_RANGE_S256 */
  1033. {
  1034. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1035. {0, 0, 0, 0}
  1036. }, /* BR_RANGE_S16K */
  1037. {
  1038. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1039. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1040. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  1041. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1042. {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1043. {0, 0, 0, 0}
  1044. }, /* BR_RANGE_S64K */
  1045. {
  1046. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1047. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1048. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  1049. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1050. {4, 4, NDS32_ABS, BFD_RELOC_NDS32_EMPTY},
  1051. {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1052. {0, 0, 0, 0}
  1053. }, /* BR_RANGE_S16M */
  1054. {
  1055. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1056. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1057. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
  1058. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  1059. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1060. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  1061. {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1062. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  1063. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  1064. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1065. {0, 0, 0, 0}
  1066. } /* BR_RANGE_U4G */
  1067. } /* relax_fixup */
  1068. },
  1069. {
  1070. "bne", /* opcode */
  1071. BR_RANGE_S16K, /* br_range */
  1072. {
  1073. {0, 20, 0x1F, FALSE},
  1074. {0, 15, 0x1F, FALSE},
  1075. {0, 0, 0, FALSE}
  1076. }, /* cond_field */
  1077. {
  1078. {
  1079. INSN_BNE /* bne $rt, $ra, label */
  1080. }, /* BR_RANGE_S256 */
  1081. {
  1082. INSN_BNE /* bne $rt, $ra, label */
  1083. }, /* BR_RANGE_S16K */
  1084. {
  1085. INSN_BEQ, /* beq $rt, $ra, $1 */
  1086. INSN_J /* j label */
  1087. }, /* BR_RANGE_S64K */
  1088. {
  1089. INSN_BEQ, /* beq $rt, $ra, $1 */
  1090. INSN_J /* j label */
  1091. }, /* BR_RANGE_S16M */
  1092. {
  1093. INSN_BEQ, /* beq $rt, $ra, $1 */
  1094. INSN_SETHI_TA, /* sethi $ta, label */
  1095. INSN_ORI_TA, /* ori $ta, $ta, label */
  1096. INSN_JR_TA /* jr $ta */
  1097. } /* BR_RANGE_U4G */
  1098. }, /* relax_code_seq */
  1099. {
  1100. {
  1101. {0, 20, 0x1F, FALSE},
  1102. {0, 15, 0x1F, FALSE},
  1103. {0, 0, 0, FALSE}
  1104. }, /* BR_RANGE_S256 */
  1105. {
  1106. {0, 20, 0x1F, FALSE},
  1107. {0, 15, 0x1F, FALSE},
  1108. {0, 0, 0, FALSE}
  1109. }, /* BR_RANGE_S16K */
  1110. {
  1111. {0, 20, 0x1F, FALSE},
  1112. {0, 15, 0x1F, FALSE},
  1113. {0, 0, 0, FALSE}
  1114. }, /* BR_RANGE_S64K */
  1115. {
  1116. {0, 20, 0x1F, FALSE},
  1117. {0, 15, 0x1F, FALSE},
  1118. {0, 0, 0, FALSE}
  1119. }, /* BR_RANGE_S16M */
  1120. {
  1121. {0, 20, 0x1F, FALSE},
  1122. {0, 15, 0x1F, FALSE},
  1123. {0, 0, 0, FALSE}
  1124. } /* BR_RANGE_U4G */
  1125. }, /* relax_code_condition */
  1126. {4, 4, 8, 8, 16}, /* relax_code_size */
  1127. {4, 4, 4, 4, 4}, /* relax_branch_isize */
  1128. {
  1129. {
  1130. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1131. {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
  1132. {0, 0, 0, 0}
  1133. }, /* BR_RANGE_S256 */
  1134. {
  1135. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1136. {0, 0, 0, 0}
  1137. }, /* BR_RANGE_S16K */
  1138. {
  1139. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1140. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1141. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  1142. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1143. {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1144. {0, 0, 0, 0}
  1145. }, /* BR_RANGE_S64K */
  1146. {
  1147. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1148. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1149. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  1150. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1151. {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1152. {0, 0, 0, 0}
  1153. }, /* BR_RANGE_S16M */
  1154. {
  1155. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1156. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1157. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
  1158. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  1159. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1160. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  1161. {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1162. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  1163. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  1164. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1165. {0, 0, 0, 0}
  1166. } /* BR_RANGE_U4G */
  1167. } /* relax_fixup */
  1168. },
  1169. {
  1170. "beqz38", /* opcode */
  1171. BR_RANGE_S256, /* br_range */
  1172. {
  1173. {0, 8, 0x7, FALSE},
  1174. {0, 0, 0, FALSE}
  1175. }, /* cond_field */
  1176. {
  1177. {
  1178. INSN_BEQZ38 << 16 /* beqz $rt, label */
  1179. }, /* BR_RANGE_S256 */
  1180. {
  1181. INSN_BEQZ /* beqz $rt, label */
  1182. }, /* BR_RANGE_S16K */
  1183. {
  1184. INSN_BEQZ /* beqz $rt, label */
  1185. }, /* BR_RANGE_S64K */
  1186. {
  1187. INSN_BNEZ, /* bnez $rt, $1 */
  1188. INSN_J /* j label */
  1189. }, /* BR_RANGE_S16M */
  1190. {
  1191. INSN_BNEZ, /* bnez $rt, $1 */
  1192. INSN_SETHI_TA, /* sethi $ta, label */
  1193. INSN_ORI_TA, /* ori $ta, $ta, label */
  1194. INSN_JR_TA /* jr $ta */
  1195. } /* BR_RANGE_U4G */
  1196. }, /* relax_code_seq */
  1197. {
  1198. {
  1199. {0, 8, 0x7, FALSE},
  1200. {0, 0, 0, FALSE}
  1201. }, /* BR_RANGE_S256 */
  1202. {
  1203. {0, 20, 0x1F, FALSE},
  1204. {0, 0, 0, FALSE}
  1205. }, /* BR_RANGE_S16K */
  1206. {
  1207. {0, 20, 0x1F, FALSE},
  1208. {0, 0, 0, FALSE}
  1209. }, /* BR_RANGE_S64K */
  1210. {
  1211. {0, 20, 0x1F, FALSE},
  1212. {0, 0, 0, FALSE}
  1213. }, /* BR_RANGE_S16M */
  1214. {
  1215. {0, 20, 0x1F, FALSE},
  1216. {0, 0, 0, FALSE}
  1217. } /* BR_RANGE_U4G */
  1218. }, /* relax_code_condition */
  1219. {2, 4, 4, 8, 16}, /* relax_code_size */
  1220. {2, 4, 4, 4, 4}, /* relax_branch_isize */
  1221. {
  1222. {
  1223. {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
  1224. {0, 0, 0, 0}
  1225. }, /* BR_RANGE_S256 */
  1226. {
  1227. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  1228. {0, 0, 0, 0}
  1229. }, /* BR_RANGE_S16K */
  1230. {
  1231. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  1232. {0, 0, 0, 0}
  1233. }, /* BR_RANGE_S64K */
  1234. {
  1235. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1236. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1237. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  1238. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1239. {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1240. {0, 0, 0, 0}
  1241. }, /* BR_RANGE_S16M */
  1242. {
  1243. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1244. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1245. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
  1246. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  1247. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1248. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  1249. {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1250. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  1251. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  1252. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1253. {0, 0, 0, 0}
  1254. } /* BR_RANGE_U4G */
  1255. } /* relax_fixup */
  1256. },
  1257. {
  1258. "bnez38", /* opcode */
  1259. BR_RANGE_S256, /* br_range */
  1260. {
  1261. {0, 8, 0x7, FALSE},
  1262. {0, 0, 0, FALSE}
  1263. }, /* cond_field */
  1264. {
  1265. {
  1266. INSN_BNEZ38 << 16 /* bnez $rt, label */
  1267. }, /* BR_RANGE_S256 */
  1268. {
  1269. INSN_BNEZ /* bnez $rt, label */
  1270. }, /* BR_RANGE_S16K */
  1271. {
  1272. INSN_BNEZ /* bnez $rt, label */
  1273. }, /* BR_RANGE_S64K */
  1274. {
  1275. INSN_BEQZ, /* beqz $rt, $1 */
  1276. INSN_J /* j label */
  1277. }, /* BR_RANGE_S16M */
  1278. {
  1279. INSN_BEQZ, /* beqz $rt, $1 */
  1280. INSN_SETHI_TA, /* sethi $ta, label */
  1281. INSN_ORI_TA, /* ori $ta, $ta, label */
  1282. INSN_JR_TA /* jr $ta */
  1283. } /* BR_RANGE_U4G */
  1284. }, /* relax_code_seq */
  1285. {
  1286. {
  1287. {0, 8, 0x7, FALSE},
  1288. {0, 0, 0, FALSE}
  1289. }, /* BR_RANGE_S256 */
  1290. {
  1291. {0, 20, 0x1F, FALSE},
  1292. {0, 0, 0, FALSE}
  1293. }, /* BR_RANGE_S16K */
  1294. {
  1295. {0, 20, 0x1F, FALSE},
  1296. {0, 0, 0, FALSE}
  1297. }, /* BR_RANGE_S64K */
  1298. {
  1299. {0, 20, 0x1F, FALSE},
  1300. {0, 0, 0, FALSE}
  1301. }, /* BR_RANGE_S16M */
  1302. {
  1303. {0, 20, 0x1F, FALSE},
  1304. {0, 0, 0, FALSE}
  1305. } /* BR_RANGE_U4G */
  1306. }, /* relax_code_condition */
  1307. {2, 4, 4, 8, 16}, /* relax_code_size */
  1308. {2, 4, 4, 4, 4}, /* relax_branch_isize */
  1309. {
  1310. {
  1311. {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
  1312. {0, 0, 0, 0}
  1313. }, /* BR_RANGE_S256 */
  1314. {
  1315. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  1316. {0, 0, 0, 0}
  1317. }, /* BR_RANGE_S16K */
  1318. {
  1319. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  1320. {0, 0, 0, 0}
  1321. }, /* BR_RANGE_S64K */
  1322. {
  1323. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1324. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1325. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  1326. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1327. {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1328. {0, 0, 0, 0}
  1329. }, /* BR_RANGE_S16M */
  1330. {
  1331. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1332. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1333. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
  1334. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  1335. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1336. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  1337. {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1338. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  1339. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  1340. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1341. {0, 0, 0, 0}
  1342. } /* BR_RANGE_U4G */
  1343. } /* relax_fixup */
  1344. },
  1345. {
  1346. "beqzs8", /* opcode */
  1347. BR_RANGE_S256, /* br_range */
  1348. {{0, 0, 0, FALSE}}, /* cond_field */
  1349. {
  1350. {
  1351. INSN_BEQZS8 << 16 /* beqz $r15, label */
  1352. }, /* BR_RANGE_S256 */
  1353. {
  1354. INSN_BEQZ_TA /* bnez $rt, label */
  1355. }, /* BR_RANGE_S16K */
  1356. {
  1357. INSN_BEQZ_TA /* bnez $rt, label */
  1358. }, /* BR_RANGE_S64K */
  1359. {
  1360. INSN_BNEZ_TA, /* bnez $r15, $1 */
  1361. INSN_J /* j label */
  1362. }, /* BR_RANGE_S16M */
  1363. {
  1364. INSN_BNEZ_TA, /* bnez $r15, $1 */
  1365. INSN_SETHI_TA, /* sethi $ta, label */
  1366. INSN_ORI_TA, /* ori $ta, $ta, label */
  1367. INSN_JR_TA /* jr $ta */
  1368. } /* BR_RANGE_U4G */
  1369. }, /* relax_code_seq */
  1370. {
  1371. {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
  1372. {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
  1373. {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
  1374. {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
  1375. {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
  1376. }, /* relax_code_condition */
  1377. {2, 4, 4, 8, 16}, /* relax_code_size */
  1378. {2, 4, 4, 4, 4}, /* relax_branch_isize */
  1379. {
  1380. {
  1381. {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
  1382. {0, 0, 0, 0}
  1383. }, /* BR_RANGE_S256 */
  1384. {
  1385. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  1386. {0, 0, 0, 0}
  1387. }, /* BR_RANGE_S16K */
  1388. {
  1389. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  1390. {0, 0, 0, 0}
  1391. }, /* BR_RANGE_S64K */
  1392. {
  1393. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1394. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1395. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  1396. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1397. {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1398. {0, 0, 0, 0}
  1399. }, /* BR_RANGE_S16M */
  1400. {
  1401. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1402. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1403. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
  1404. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  1405. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1406. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  1407. {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1408. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  1409. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  1410. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1411. {0, 0, 0, 0}
  1412. } /* BR_RANGE_U4G */
  1413. } /* relax_fixup */
  1414. },
  1415. {
  1416. "bnezs8", /* opcode */
  1417. BR_RANGE_S256, /* br_range */
  1418. {{0, 0, 0, FALSE}}, /* cond_field */
  1419. {
  1420. {
  1421. INSN_BNEZS8 << 16 /* bnez $r15, label */
  1422. }, /* BR_RANGE_S256 */
  1423. {
  1424. INSN_BNEZ_TA /* bnez $r15, label */
  1425. }, /* BR_RANGE_S16K */
  1426. {
  1427. INSN_BNEZ_TA /* bnez $r15, label */
  1428. }, /* BR_RANGE_S64K */
  1429. {
  1430. INSN_BEQZ_TA, /* beqz $r15, $1 */
  1431. INSN_J /* j label */
  1432. }, /* BR_RANGE_S16M */
  1433. {
  1434. INSN_BEQZ_TA, /* beqz $r15, $1 */
  1435. INSN_SETHI_TA, /* sethi $ta, label */
  1436. INSN_ORI_TA, /* ori $ta, $ta, label */
  1437. INSN_JR_TA /* jr $ta */
  1438. } /* BR_RANGE_U4G */
  1439. }, /* relax_code_seq */
  1440. {
  1441. {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
  1442. {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
  1443. {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
  1444. {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
  1445. {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
  1446. }, /* relax_code_condition */
  1447. {2, 4, 4, 8, 16}, /* relax_code_size */
  1448. {2, 4, 4, 4, 4}, /* relax_branch_isize */
  1449. {
  1450. {
  1451. {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
  1452. {0, 0, 0, 0}
  1453. }, /* BR_RANGE_S256 */
  1454. {
  1455. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  1456. {0, 0, 0, 0}
  1457. }, /* BR_RANGE_S16K */
  1458. {
  1459. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
  1460. {0, 0, 0, 0}
  1461. }, /* BR_RANGE_S64K */
  1462. {
  1463. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1464. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1465. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  1466. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1467. {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1468. {0, 0, 0, 0}
  1469. }, /* BR_RANGE_S16M */
  1470. {
  1471. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1472. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1473. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
  1474. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  1475. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1476. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  1477. {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1478. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  1479. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  1480. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1481. {0, 0, 0, 0}
  1482. } /* BR_RANGE_U4G */
  1483. } /* relax_fixup */
  1484. },
  1485. {
  1486. "bnes38", /* opcode */
  1487. BR_RANGE_S256, /* br_range */
  1488. {
  1489. {0, 8, 0x7, FALSE},
  1490. {0, 0, 0, FALSE}
  1491. }, /* cond_field */
  1492. {
  1493. {
  1494. INSN_BNES38 << 16 /* bne $rt, $R5, label */
  1495. }, /* BR_RANGE_S256 */
  1496. {
  1497. INSN_BNE_R5 /* bne $rt, $R5, label */
  1498. }, /* BR_RANGE_S16K */
  1499. {
  1500. INSN_BEQ_R5, /* beq $rt, $R5, $1 */
  1501. INSN_J /* j label */
  1502. }, /* BR_RANGE_S64K */
  1503. {
  1504. INSN_BEQ_R5, /* beq $rt, $R5, $1 */
  1505. INSN_J /* j label */
  1506. }, /* BR_RANGE_S16M */
  1507. {
  1508. INSN_BEQ_R5, /* beq $rt, $R5, $1 */
  1509. INSN_SETHI_TA, /* sethi $ta, label */
  1510. INSN_ORI_TA, /* ori $ta, $ta, label */
  1511. INSN_JR_TA /* jr $ta */
  1512. } /* BR_RANGE_U4G */
  1513. }, /* relax_code_seq */
  1514. {
  1515. {
  1516. {0, 8, 0x7, FALSE},
  1517. {0, 0, 0, FALSE}
  1518. }, /* BR_RANGE_S256 */
  1519. {
  1520. {0, 20, 0x1F, FALSE},
  1521. {0, 0, 0, FALSE}
  1522. }, /* BR_RANGE_S16K */
  1523. {
  1524. {0, 20, 0x1F, FALSE},
  1525. {0, 0, 0, FALSE}
  1526. }, /* BR_RANGE_S64K */
  1527. {
  1528. {0, 20, 0x1F, FALSE},
  1529. {0, 0, 0, FALSE}
  1530. }, /* BR_RANGE_S16M */
  1531. {
  1532. {0, 20, 0x1F, FALSE},
  1533. {0, 0, 0, FALSE}
  1534. } /* BR_RANGE_U4G */
  1535. }, /* relax_code_condition */
  1536. {2, 4, 8, 8, 16}, /* relax_code_size */
  1537. {2, 4, 4, 4, 4}, /* relax_branch_isize */
  1538. {
  1539. {
  1540. {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
  1541. {0, 0, 0, 0}
  1542. }, /* BR_RANGE_S256 */
  1543. {
  1544. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1545. {0, 0, 0, 0}
  1546. }, /* BR_RANGE_S16K */
  1547. {
  1548. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1549. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1550. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  1551. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1552. {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1553. {0, 0, 0, 0}
  1554. }, /* BR_RANGE_S64K */
  1555. {
  1556. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1557. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1558. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  1559. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1560. {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1561. {0, 0, 0, 0}
  1562. }, /* BR_RANGE_S16M */
  1563. {
  1564. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1565. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1566. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
  1567. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  1568. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1569. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  1570. {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1571. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  1572. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  1573. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1574. {0, 0, 0, 0}
  1575. } /* BR_RANGE_U4G */
  1576. } /* relax_fixup */
  1577. },
  1578. {
  1579. "beqs38", /* opcode */
  1580. BR_RANGE_S256, /* br_range */
  1581. {
  1582. {0, 8, 0x7, FALSE},
  1583. {0, 0, 0, FALSE}
  1584. }, /* cond_field */
  1585. {
  1586. {
  1587. INSN_BEQS38 << 16 /* beq $rt, $R5, label */
  1588. }, /* BR_RANGE_S256 */
  1589. {
  1590. INSN_BEQ_R5 /* beq $rt, $R5, label */
  1591. }, /* BR_RANGE_S16K */
  1592. {
  1593. INSN_BNE_R5, /* bne $rt, $R5, $1 */
  1594. INSN_J /* j label */
  1595. }, /* BR_RANGE_S64K */
  1596. {
  1597. INSN_BNE_R5, /* bne $rt, $R5, $1 */
  1598. INSN_J /* j label */
  1599. }, /* BR_RANGE_S16M */
  1600. {
  1601. INSN_BNE_R5, /* bne $rt, $R5, $1 */
  1602. INSN_SETHI_TA, /* sethi $ta, label */
  1603. INSN_ORI_TA, /* ori $ta, $ta, label */
  1604. INSN_JR_TA /* jr $ta */
  1605. } /* BR_RANGE_U4G */
  1606. }, /* relax_code_seq */
  1607. {
  1608. {
  1609. {0, 8, 0x7, FALSE},
  1610. {0, 0, 0, FALSE}
  1611. }, /* BR_RANGE_S256 */
  1612. {
  1613. {0, 20, 0x1F, FALSE},
  1614. {0, 0, 0, FALSE}
  1615. }, /* BR_RANGE_S16K */
  1616. {
  1617. {0, 20, 0x1F, FALSE},
  1618. {0, 0, 0, FALSE}
  1619. }, /* BR_RANGE_S64K */
  1620. {
  1621. {0, 20, 0x1F, FALSE},
  1622. {0, 0, 0, FALSE}
  1623. }, /* BR_RANGE_S16M */
  1624. {
  1625. {0, 20, 0x1F, FALSE},
  1626. {0, 0, 0, FALSE}
  1627. } /* BR_RANGE_U4G */
  1628. }, /* relax_code_condition */
  1629. {2, 4, 8, 8, 16}, /* relax_code_size */
  1630. {2, 4, 4, 4, 4}, /* relax_branch_isize */
  1631. {
  1632. {
  1633. {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
  1634. {0, 0, 0, 0}
  1635. }, /* BR_RANGE_S256 */
  1636. {
  1637. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1638. {0, 0, 0, 0}
  1639. }, /* BR_RANGE_S16K */
  1640. {
  1641. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1642. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1643. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  1644. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1645. {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1646. {0, 0, 0, 0}
  1647. }, /* BR_RANGE_S64K */
  1648. {
  1649. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1650. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1651. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
  1652. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1653. {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1654. {0, 0, 0, 0}
  1655. }, /* BR_RANGE_S16M */
  1656. {
  1657. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1658. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1659. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
  1660. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  1661. {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1662. {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
  1663. {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
  1664. {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
  1665. {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
  1666. {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1667. {0, 0, 0, 0}
  1668. } /* BR_RANGE_U4G */
  1669. } /* relax_fixup */
  1670. },
  1671. {
  1672. "beqc", /* opcode */
  1673. BR_RANGE_S256, /* br_range */
  1674. {
  1675. {0, 8, 0x7FF, TRUE},
  1676. {0, 20, 0x1F, FALSE},
  1677. {0, 0, 0, FALSE}
  1678. }, /* cond_field */
  1679. {
  1680. {
  1681. INSN_BEQC /* beqc $rt, imm11s, label */
  1682. }, /* BR_RANGE_S256 */
  1683. {
  1684. INSN_MOVI_TA, /* movi $ta, imm11s */
  1685. INSN_BEQ_TA /* beq $rt, $ta, label */
  1686. }, /* BR_RANGE_S16K */
  1687. {
  1688. INSN_BNEC, /* bnec $rt, imm11s, $1 */
  1689. INSN_J /* j label */
  1690. }, /* BR_RANGE_S64K */
  1691. {
  1692. INSN_BNEC, /* bnec $rt, imm11s, $1 */
  1693. INSN_J /* j label */
  1694. }, /* BR_RANGE_S16M */
  1695. {
  1696. INSN_BNEC, /* bnec $rt, imm11s, $1 */
  1697. INSN_SETHI_TA, /* sethi $ta, label */
  1698. INSN_ORI_TA, /* ori $ta, $ta, label */
  1699. INSN_JR_TA /* jr $ta */
  1700. } /* BR_RANGE_U4G */
  1701. }, /* relax_code_seq */
  1702. {
  1703. {
  1704. {0, 8, 0x7FF, TRUE},
  1705. {0, 20, 0x1F, FALSE},
  1706. {0, 0, 0, FALSE}
  1707. }, /* BR_RANGE_S256 */
  1708. {
  1709. {0, 0, 0xFFFFF, FALSE},
  1710. {4, 20, 0x1F, FALSE},
  1711. {0, 0, 0, FALSE}
  1712. }, /* BR_RANGE_S16K */
  1713. {
  1714. {0, 8, 0x7FF, FALSE},
  1715. {0, 20, 0x1F, FALSE},
  1716. {0, 0, 0, FALSE}
  1717. }, /* BR_RANGE_S64K */
  1718. {
  1719. {0, 8, 0x7FF, FALSE},
  1720. {0, 20, 0x1F, FALSE},
  1721. {0, 0, 0, FALSE}
  1722. }, /* BR_RANGE_S16M */
  1723. {
  1724. {0, 8, 0x7FF, FALSE},
  1725. {0, 20, 0x1F, FALSE},
  1726. {0, 0, 0, FALSE}
  1727. } /* BR_RANGE_U4G */
  1728. }, /* relax_code_condition */
  1729. {4, 8, 8, 8, 16}, /* relax_code_size */
  1730. {4, 4, 4, 4, 4}, /* relax_branch_isize */
  1731. {
  1732. {
  1733. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
  1734. {0, 0, 0, 0}
  1735. }, /* BR_RANGE_S256 */
  1736. {
  1737. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1738. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
  1739. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1740. {0, 0, 0, 0}
  1741. }, /* BR_RANGE_S16K */
  1742. {
  1743. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
  1744. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1745. {0, 0, 0, 0}
  1746. }, /* BR_RANGE_S64K */
  1747. {
  1748. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
  1749. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1750. {0, 0, 0, 0}
  1751. }, /* BR_RANGE_S16M */
  1752. {
  1753. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
  1754. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  1755. {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
  1756. {12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
  1757. {0, 0, 0, 0}
  1758. } /* BR_RANGE_U4G */
  1759. } /* relax_fixup */
  1760. },
  1761. {
  1762. "bnec", /* opcode */
  1763. BR_RANGE_S256, /* br_range */
  1764. {
  1765. {0, 8, 0x7FF, TRUE},
  1766. {0, 20, 0x1F, FALSE},
  1767. {0, 0, 0, FALSE}
  1768. }, /* cond_field */
  1769. {
  1770. {
  1771. INSN_BNEC /* bnec $rt, imm11s, label */
  1772. }, /* BR_RANGE_S256 */
  1773. {
  1774. INSN_MOVI_TA, /* movi $ta, imm11s */
  1775. INSN_BNE_TA /* bne $rt, $ta, label */
  1776. }, /* BR_RANGE_S16K */
  1777. {
  1778. INSN_BEQC, /* beqc $rt, imm11s, $1 */
  1779. INSN_J /* j label */
  1780. }, /* BR_RANGE_S64K */
  1781. {
  1782. INSN_BEQC, /* beqc $rt, imm11s, $1 */
  1783. INSN_J /* j label */
  1784. }, /* BR_RANGE_S16M */
  1785. {
  1786. INSN_BEQC, /* beqc $rt, imm11s, $1 */
  1787. INSN_SETHI_TA, /* sethi $ta, label */
  1788. INSN_ORI_TA, /* ori $ta, $ta, label */
  1789. INSN_JR_TA /* jr $ta */
  1790. } /* BR_RANGE_U4G */
  1791. }, /* relax_code_seq */
  1792. {
  1793. {
  1794. {0, 8, 0x7FF, TRUE},
  1795. {0, 20, 0x1F, FALSE},
  1796. {0, 0, 0, FALSE}
  1797. }, /* BR_RANGE_S256 */
  1798. {
  1799. {0, 0, 0xFFFFF, FALSE},
  1800. {4, 20, 0x1F, FALSE},
  1801. {0, 0, 0, FALSE}
  1802. }, /* BR_RANGE_S16K */
  1803. {
  1804. {0, 8, 0x7FF, FALSE},
  1805. {0, 20, 0x1F, FALSE},
  1806. {0, 0, 0, FALSE}
  1807. }, /* BR_RANGE_S64K */
  1808. {
  1809. {0, 8, 0x7FF, FALSE},
  1810. {0, 20, 0x1F, FALSE},
  1811. {0, 0, 0, FALSE}
  1812. }, /* BR_RANGE_S16M */
  1813. {
  1814. {0, 8, 0x7FF, FALSE},
  1815. {0, 20, 0x1F, FALSE},
  1816. {0, 0, 0, FALSE}
  1817. } /* BR_RANGE_U4G */
  1818. }, /* relax_code_condition */
  1819. {4, 8, 8, 8, 16}, /* relax_code_size */
  1820. {4, 4, 4, 4, 4}, /* relax_branch_isize */
  1821. {
  1822. {
  1823. {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
  1824. {0, 0, 0, 0}
  1825. }, /* BR_RANGE_S256 */
  1826. {
  1827. {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
  1828. {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
  1829. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
  1830. {0, 0, 0, 0}
  1831. }, /* BR_RANGE_S16K */
  1832. {
  1833. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
  1834. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1835. {0, 0, 0, 0}
  1836. }, /* BR_RANGE_S64K */
  1837. {
  1838. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
  1839. {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
  1840. {0, 0, 0, 0}
  1841. }, /* BR_RANGE_S16M */
  1842. {
  1843. {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
  1844. {4, 4, 0, BFD_RELOC_NDS32_HI20},
  1845. {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
  1846. {12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
  1847. {0, 0, 0, 0}
  1848. } /* BR_RANGE_U4G */
  1849. } /* relax_fixup */
  1850. },
  1851. {
  1852. NULL, /* opcode */
  1853. 0, /* br_range */
  1854. {{0, 0, 0, FALSE}}, /* cond_field */
  1855. {{0}}, /* relax_code_seq */
  1856. {{{0, 0, 0, FALSE}}}, /* relax_code_condition */
  1857. {0}, /* relax_code_size */
  1858. {0}, /* relax_branch_isize */
  1859. {{{0, 0, 0, 0}}}, /* relax_fixup */
  1860. },
  1861. };
  1862. /* GAS definitions for command-line options. */
  1863. enum options
  1864. {
  1865. OPTION_BIG = OPTION_MD_BASE,
  1866. OPTION_LITTLE,
  1867. OPTION_TURBO,
  1868. OPTION_PIC,
  1869. OPTION_RELAX_FP_AS_GP_OFF,
  1870. OPTION_RELAX_B2BB_ON,
  1871. OPTION_RELAX_ALL_OFF,
  1872. OPTION_OPTIMIZE,
  1873. OPTION_OPTIMIZE_SPACE
  1874. };
  1875. const char *md_shortopts = "m:O:";
  1876. struct option md_longopts[] =
  1877. {
  1878. {"O1", no_argument, NULL, OPTION_OPTIMIZE},
  1879. {"Os", no_argument, NULL, OPTION_OPTIMIZE_SPACE},
  1880. {"big", no_argument, NULL, OPTION_BIG},
  1881. {"little", no_argument, NULL, OPTION_LITTLE},
  1882. {"EB", no_argument, NULL, OPTION_BIG},
  1883. {"EL", no_argument, NULL, OPTION_LITTLE},
  1884. {"meb", no_argument, NULL, OPTION_BIG},
  1885. {"mel", no_argument, NULL, OPTION_LITTLE},
  1886. {"mall-ext", no_argument, NULL, OPTION_TURBO},
  1887. {"mext-all", no_argument, NULL, OPTION_TURBO},
  1888. {"mpic", no_argument, NULL, OPTION_PIC},
  1889. /* Relaxation related options. */
  1890. {"mno-fp-as-gp-relax", no_argument, NULL, OPTION_RELAX_FP_AS_GP_OFF},
  1891. {"mb2bb", no_argument, NULL, OPTION_RELAX_B2BB_ON},
  1892. {"mno-all-relax", no_argument, NULL, OPTION_RELAX_ALL_OFF},
  1893. {NULL, no_argument, NULL, 0}
  1894. };
  1895. size_t md_longopts_size = sizeof (md_longopts);
  1896. struct nds32_parse_option_table
  1897. {
  1898. const char *name; /* Option string. */
  1899. char *help; /* Help description. */
  1900. int (*func) (char *arg); /* How to parse it. */
  1901. };
  1902. /* The value `-1' represents this option has *NOT* been set. */
  1903. #ifdef NDS32_DEFAULT_ARCH_NAME
  1904. static char* nds32_arch_name = NDS32_DEFAULT_ARCH_NAME;
  1905. #else
  1906. static char* nds32_arch_name = "v3";
  1907. #endif
  1908. static int nds32_baseline = -1;
  1909. static int nds32_gpr16 = -1;
  1910. static int nds32_fpu_sp_ext = -1;
  1911. static int nds32_fpu_dp_ext = -1;
  1912. static int nds32_freg = -1;
  1913. static int nds32_abi = -1;
  1914. /* Record ELF flags */
  1915. static int nds32_elf_flags = 0;
  1916. static int nds32_fpu_com = 0;
  1917. static int nds32_parse_arch (char *str);
  1918. static int nds32_parse_baseline (char *str);
  1919. static int nds32_parse_freg (char *str);
  1920. static int nds32_parse_abi (char *str);
  1921. static struct nds32_parse_option_table parse_opts [] =
  1922. {
  1923. {"arch=", N_("<arch name>\t Assemble for architecture <arch name>\n\
  1924. <arch name> could be\n\
  1925. v3, v3j, v3m, v3f, v3s, "\
  1926. "v2, v2j, v2f, v2s"), nds32_parse_arch},
  1927. {"baseline=", N_("<baseline>\t Assemble for baseline <baseline>\n\
  1928. <baseline> could be v2, v3, v3m"),
  1929. nds32_parse_baseline},
  1930. {"fpu-freg=", N_("<freg>\t Specify a FPU configuration\n\
  1931. <freg>\n\
  1932. 0: 8 SP / 4 DP registers\n\
  1933. 1: 16 SP / 8 DP registers\n\
  1934. 2: 32 SP / 16 DP registers\n\
  1935. 3: 32 SP / 32 DP registers"), nds32_parse_freg},
  1936. {"abi=", N_("<abi>\t Specify a abi version\n\
  1937. <abi> could be v1, v2, v2fp, v2fpp"), nds32_parse_abi},
  1938. {NULL, NULL, NULL}
  1939. };
  1940. static int nds32_mac = 1;
  1941. static int nds32_div = 1;
  1942. static int nds32_16bit_ext = 1;
  1943. static int nds32_dx_regs = 1;
  1944. static int nds32_perf_ext = 1;
  1945. static int nds32_perf_ext2 = 1;
  1946. static int nds32_string_ext = 1;
  1947. static int nds32_audio_ext = 1;
  1948. static int nds32_fpu_fma = 0;
  1949. static int nds32_pic = 0;
  1950. static int nds32_relax_fp_as_gp = 1;
  1951. static int nds32_relax_b2bb = 0;
  1952. static int nds32_relax_all = 1;
  1953. struct nds32_set_option_table
  1954. {
  1955. const char *name; /* Option string. */
  1956. char *help; /* Help description. */
  1957. int *var; /* Variable to be set. */
  1958. int value; /* Value to set. */
  1959. };
  1960. /* The option in this group has both Enable/Disable settings.
  1961. Just list on here. */
  1962. static struct nds32_set_option_table toggle_opts [] =
  1963. {
  1964. {"mac", N_("Multiply instructions support"), &nds32_mac, 1},
  1965. {"div", N_("Divide instructions support"), &nds32_div, 1},
  1966. {"16bit-ext", N_("16-bit extension"), &nds32_16bit_ext, 1},
  1967. {"dx-regs", N_("d0/d1 registers"), &nds32_dx_regs, 1},
  1968. {"perf-ext", N_("Performance extension"), &nds32_perf_ext, 1},
  1969. {"perf2-ext", N_("Performance extension 2"), &nds32_perf_ext2, 1},
  1970. {"string-ext", N_("String extension"), &nds32_string_ext, 1},
  1971. {"reduced-regs", N_("Reduced Register configuration (GPR16) option"), &nds32_gpr16, 1},
  1972. {"audio-isa-ext", N_("AUDIO ISA extension"), &nds32_audio_ext, 1},
  1973. {"fpu-sp-ext", N_("FPU SP extension"), &nds32_fpu_sp_ext, 1},
  1974. {"fpu-dp-ext", N_("FPU DP extension"), &nds32_fpu_dp_ext, 1},
  1975. {"fpu-fma", N_("FPU fused-multiply-add instructions"), &nds32_fpu_fma, 1},
  1976. {NULL, NULL, NULL, 0}
  1977. };
  1978. /* GAS declarations. */
  1979. /* This is the callback for nds32-asm.c to parse operands. */
  1980. int
  1981. nds32_asm_parse_operand (struct nds32_asm_desc *pdesc,
  1982. struct nds32_asm_insn *pinsn,
  1983. char **pstr, int64_t *value);
  1984. struct nds32_asm_desc asm_desc;
  1985. /* md_after_parse_args ()
  1986. GAS will call md_after_parse_args whenever it is defined.
  1987. This function checks any conflicting options specified. */
  1988. void
  1989. nds32_after_parse_args (void)
  1990. {
  1991. /* If -march option is not used in command-line, set the value of option
  1992. variable according to NDS32_DEFAULT_ARCH_NAME. */
  1993. nds32_parse_arch (nds32_arch_name);
  1994. }
  1995. /* This function is called when printing usage message (--help). */
  1996. void
  1997. md_show_usage (FILE *stream)
  1998. {
  1999. struct nds32_parse_option_table *coarse_tune;
  2000. struct nds32_set_option_table *fine_tune;
  2001. fprintf (stream, _("\n NDS32-specific assembler options:\n"));
  2002. fprintf (stream, _("\
  2003. -O1, Optimize for performance\n\
  2004. -Os Optimize for space\n"));
  2005. fprintf (stream, _("\
  2006. -EL, -mel or -little Produce little endian output\n\
  2007. -EB, -meb or -big Produce big endian output\n\
  2008. -mpic Generate PIC\n\
  2009. -mno-fp-as-gp-relax Suppress fp-as-gp relaxation for this file\n\
  2010. -mb2bb-relax Back-to-back branch optimization\n\
  2011. -mno-all-relax Suppress all relaxation for this file\n"));
  2012. for (coarse_tune = parse_opts; coarse_tune->name != NULL; coarse_tune++)
  2013. {
  2014. if (coarse_tune->help != NULL)
  2015. fprintf (stream, _(" -m%s%s\n"),
  2016. coarse_tune->name, _(coarse_tune->help));
  2017. }
  2018. for (fine_tune = toggle_opts; fine_tune->name != NULL; fine_tune++)
  2019. {
  2020. if (fine_tune->help != NULL)
  2021. fprintf (stream, _(" -m[no-]%-17sEnable/Disable %s\n"),
  2022. fine_tune->name, _(fine_tune->help));
  2023. }
  2024. fprintf (stream, _("\
  2025. -mall-ext Turn on all extensions and instructions support\n"));
  2026. }
  2027. void
  2028. nds32_frag_init (fragS *fragp)
  2029. {
  2030. fragp->tc_frag_data.flag = 0;
  2031. fragp->tc_frag_data.opcode = NULL;
  2032. fragp->tc_frag_data.fixup = NULL;
  2033. }
  2034. /* This function reads an expression from a C string and returns a pointer past
  2035. the end of the expression. */
  2036. static char *
  2037. parse_expression (char *str, expressionS *exp)
  2038. {
  2039. char *s;
  2040. char *tmp;
  2041. tmp = input_line_pointer; /* Save line pointer. */
  2042. input_line_pointer = str;
  2043. expression (exp);
  2044. s = input_line_pointer;
  2045. input_line_pointer = tmp; /* Restore line pointer. */
  2046. return s; /* Return pointer to where parsing stopped. */
  2047. }
  2048. void
  2049. nds32_start_line_hook (void)
  2050. {
  2051. }
  2052. /*
  2053. * Pseudo opcodes
  2054. */
  2055. typedef void (*nds32_pseudo_opcode_func) (int argc, char *argv[], int pv);
  2056. struct nds32_pseudo_opcode
  2057. {
  2058. const char *opcode;
  2059. int argc;
  2060. nds32_pseudo_opcode_func proc;
  2061. int pseudo_val;
  2062. /* Some instructions are not pseudo opcode, but they might still be
  2063. expanded or changed with other instruction combination for some
  2064. conditions. We also apply this structure to assist such work.
  2065. For example, if the distance of branch target '.L0' is larger than
  2066. imm8s<<1 range,
  2067. the instruction:
  2068. beqzs8 .L0
  2069. will be transformed into:
  2070. bnezs8 .LCB0
  2071. j .L0
  2072. .LCB0:
  2073. However, sometimes we do not want assembler to do such changes
  2074. because compiler knows how to generate corresponding instruction sequence.
  2075. Use this field to indicate that this opcode is also a physical instruction.
  2076. If the flag 'verbatim' is nozero and this opcode
  2077. is a physical instruction, we should not expand it. */
  2078. int physical_op;
  2079. };
  2080. #define PV_DONT_CARE 0
  2081. static struct hash_control *nds32_pseudo_opcode_hash = NULL;
  2082. static int
  2083. builtin_isreg (const char *s, const char *x ATTRIBUTE_UNUSED)
  2084. {
  2085. if (s [0] == '$' && hash_find (nds32_gprs_hash, (s + 1)))
  2086. return 1;
  2087. return 0;
  2088. }
  2089. static int
  2090. builtin_regnum (const char *s, const char *x ATTRIBUTE_UNUSED)
  2091. {
  2092. struct nds32_keyword *k;
  2093. if (*s != '$')
  2094. return -1;
  2095. s++;
  2096. k = hash_find (nds32_gprs_hash, s);
  2097. if (k == NULL)
  2098. return -1;
  2099. return k->value;
  2100. }
  2101. static int
  2102. builtin_addend (const char *s, char *x ATTRIBUTE_UNUSED)
  2103. {
  2104. const char *ptr = s;
  2105. while (*ptr != '+' && *ptr != '-' && *ptr)
  2106. ++ptr;
  2107. if (*ptr == 0)
  2108. return 0;
  2109. else
  2110. return strtol (ptr, NULL, 0);
  2111. }
  2112. static void
  2113. md_assemblef (char *format, ...)
  2114. {
  2115. /* FIXME: hope this is long enough. */
  2116. char line[1024];
  2117. va_list ap;
  2118. unsigned int r;
  2119. va_start (ap, format);
  2120. r = vsnprintf (line, sizeof (line), format, ap);
  2121. md_assemble (line);
  2122. gas_assert (r < sizeof (line));
  2123. }
  2124. /* Some prototypes here, since some op may use another op. */
  2125. static void do_pseudo_li_internal (char *rt, int imm32s);
  2126. static void do_pseudo_move_reg_internal (char *dst, char *src);
  2127. static void
  2128. do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2129. {
  2130. char *arg_label = argv[0];
  2131. relaxing = TRUE;
  2132. /* b label */
  2133. if (nds32_pic && strstr (arg_label, "@PLT"))
  2134. {
  2135. md_assemblef ("sethi $ta,hi20(%s)", arg_label);
  2136. md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
  2137. md_assemble ("add $ta,$ta,$gp");
  2138. md_assemble ("jr $ta");
  2139. }
  2140. else
  2141. {
  2142. md_assemblef ("j %s", arg_label);
  2143. }
  2144. relaxing = FALSE;
  2145. }
  2146. static void
  2147. do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2148. {
  2149. char *arg_label = argv[0];
  2150. relaxing = TRUE;
  2151. /* bal|call label */
  2152. if (nds32_pic
  2153. && (strstr (arg_label, "@GOT") || strstr (arg_label, "@PLT")))
  2154. {
  2155. md_assemblef ("sethi $ta,hi20(%s)", arg_label);
  2156. md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
  2157. md_assemble ("add $ta,$ta,$gp");
  2158. md_assemble ("jral $ta");
  2159. }
  2160. else
  2161. {
  2162. md_assemblef ("jal %s", arg_label);
  2163. }
  2164. relaxing = FALSE;
  2165. }
  2166. static void
  2167. do_pseudo_bge (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2168. {
  2169. /* rt5, ra5, label */
  2170. md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
  2171. md_assemblef ("beqz $ta,%s", argv[2]);
  2172. }
  2173. static void
  2174. do_pseudo_bges (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2175. {
  2176. /* rt5, ra5, label */
  2177. md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
  2178. md_assemblef ("beqz $ta,%s", argv[2]);
  2179. }
  2180. static void
  2181. do_pseudo_bgt (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2182. {
  2183. /* bgt rt5, ra5, label */
  2184. md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
  2185. md_assemblef ("bnez $ta,%s", argv[2]);
  2186. }
  2187. static void
  2188. do_pseudo_bgts (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2189. {
  2190. /* bgt rt5, ra5, label */
  2191. md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
  2192. md_assemblef ("bnez $ta,%s", argv[2]);
  2193. }
  2194. static void
  2195. do_pseudo_ble (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2196. {
  2197. /* bgt rt5, ra5, label */
  2198. md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
  2199. md_assemblef ("beqz $ta,%s", argv[2]);
  2200. }
  2201. static void
  2202. do_pseudo_bles (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2203. {
  2204. /* bgt rt5, ra5, label */
  2205. md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
  2206. md_assemblef ("beqz $ta,%s", argv[2]);
  2207. }
  2208. static void
  2209. do_pseudo_blt (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2210. {
  2211. /* rt5, ra5, label */
  2212. md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
  2213. md_assemblef ("bnez $ta,%s", argv[2]);
  2214. }
  2215. static void
  2216. do_pseudo_blts (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2217. {
  2218. /* rt5, ra5, label */
  2219. md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
  2220. md_assemblef ("bnez $ta,%s", argv[2]);
  2221. }
  2222. static void
  2223. do_pseudo_br (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2224. {
  2225. md_assemblef ("jr %s", argv[0]);
  2226. }
  2227. static void
  2228. do_pseudo_bral (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
  2229. {
  2230. if (argc == 1)
  2231. md_assemblef ("jral $lp,%s", argv[0]);
  2232. else
  2233. md_assemblef ("jral %s,%s", argv[0], argv[1]);
  2234. }
  2235. static void
  2236. do_pseudo_la_internal (const char *arg_reg, char *arg_label,
  2237. const char *line)
  2238. {
  2239. expressionS exp;
  2240. parse_expression (arg_label, &exp);
  2241. if (exp.X_op != O_symbol)
  2242. {
  2243. as_bad (_("la must use with symbol. '%s'"), line);
  2244. return;
  2245. }
  2246. relaxing = TRUE;
  2247. /* rt, label */
  2248. if (!nds32_pic && !strstr(arg_label, "@"))
  2249. {
  2250. md_assemblef ("sethi %s,hi20(%s)", arg_reg, arg_label);
  2251. md_assemblef ("ori %s,%s,lo12(%s)", arg_reg, arg_reg, arg_label);
  2252. }
  2253. else if (strstr (arg_label, "@TPOFF"))
  2254. {
  2255. /* la $rt, sym@TPOFF */
  2256. md_assemblef ("sethi $ta,hi20(%s)", arg_label);
  2257. md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
  2258. md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
  2259. }
  2260. else if (strstr(arg_label, "@GOTTPOFF"))
  2261. {
  2262. /* la $rt, sym@GOTTPOFF*/
  2263. md_assemblef ("sethi $ta,hi20(%s)", arg_label);
  2264. md_assemblef ("lwi $ta,[$ta+lo12(%s)]", arg_label);
  2265. md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
  2266. }
  2267. else if (nds32_pic && ((strstr (arg_label, "@PLT")
  2268. || strstr (arg_label, "@GOTOFF"))))
  2269. {
  2270. md_assemblef ("sethi $ta,hi20(%s)", arg_label);
  2271. md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
  2272. md_assemblef ("add %s,$ta,$gp", arg_reg);
  2273. }
  2274. else if (nds32_pic && strstr (arg_label, "@GOT"))
  2275. {
  2276. long addend = builtin_addend (arg_label, NULL);
  2277. md_assemblef ("sethi $ta,hi20(%s)", arg_label);
  2278. md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
  2279. md_assemblef ("lw %s,[$gp+$ta]", arg_reg);
  2280. if (addend != 0)
  2281. {
  2282. if (addend < 0x4000 && addend >= -0x4000)
  2283. {
  2284. md_assemblef ("addi %s,%s,%d", arg_reg, arg_reg, addend);
  2285. }
  2286. else
  2287. {
  2288. do_pseudo_li_internal ("$ta", addend);
  2289. md_assemblef ("add %s,$ta,%s", arg_reg, arg_reg);
  2290. }
  2291. }
  2292. }
  2293. else
  2294. as_bad (_("need PIC qualifier with symbol. '%s'"), line);
  2295. relaxing = FALSE;
  2296. }
  2297. static void
  2298. do_pseudo_la (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2299. {
  2300. do_pseudo_la_internal (argv[0], argv[1], argv[argc]);
  2301. }
  2302. static void
  2303. do_pseudo_li_internal (char *rt, int imm32s)
  2304. {
  2305. if (enable_16bit && imm32s <= 0xf && imm32s >= -0x10)
  2306. md_assemblef ("movi55 %s,%d", rt, imm32s);
  2307. else if (imm32s <= 0x7ffff && imm32s >= -0x80000)
  2308. md_assemblef ("movi %s,%d", rt, imm32s);
  2309. else if ((imm32s & 0xfff) == 0)
  2310. md_assemblef ("sethi %s,hi20(%d)", rt, imm32s);
  2311. else
  2312. {
  2313. md_assemblef ("sethi %s,hi20(%d)", rt, imm32s);
  2314. md_assemblef ("ori %s,%s,lo12(%d)", rt, rt, imm32s);
  2315. }
  2316. }
  2317. static void
  2318. do_pseudo_li (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2319. {
  2320. /* Validate argv[1] for constant expression. */
  2321. expressionS exp;
  2322. parse_expression (argv[1], &exp);
  2323. if (exp.X_op != O_constant)
  2324. {
  2325. as_bad (_("Operand is not a constant. `%s'"), argv[argc]);
  2326. return;
  2327. }
  2328. do_pseudo_li_internal (argv[0], exp.X_add_number);
  2329. }
  2330. static void
  2331. do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
  2332. {
  2333. char ls = 'r';
  2334. char size = 'x';
  2335. const char *sign = "";
  2336. /* Prepare arguments for various load/store. */
  2337. sign = (pv & 0x10) ? "s" : "";
  2338. ls = (pv & 0x80000000) ? 's' : 'l';
  2339. switch (pv & 0x3)
  2340. {
  2341. case 0: size = 'b'; break;
  2342. case 1: size = 'h'; break;
  2343. case 2: size = 'w'; break;
  2344. }
  2345. if (ls == 's' || size == 'w')
  2346. sign = "";
  2347. if (builtin_isreg (argv[1], NULL))
  2348. {
  2349. /* lwi */
  2350. md_assemblef ("%c%ci %s,[%s]", ls, size, argv[0], argv[1]);
  2351. }
  2352. else if (!nds32_pic)
  2353. {
  2354. relaxing = TRUE;
  2355. if (strstr (argv[1], "@TPOFF"))
  2356. {
  2357. /* ls.w $rt, sym@TPOFF */
  2358. md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
  2359. md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
  2360. md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
  2361. }
  2362. else if (strstr (argv[1], "@GOTTPOFF"))
  2363. {
  2364. /* ls.w $rt, sym@GOTTPOFF */
  2365. md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
  2366. md_assemblef ("lwi $ta,[$ta+lo12(%s)]", argv[1]);
  2367. md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
  2368. }
  2369. else
  2370. {
  2371. /* lwi */
  2372. md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
  2373. md_assemblef ("%c%c%si %s,[$ta+lo12(%s)]", ls, size, sign, argv[0], argv[1]);
  2374. }
  2375. relaxing = FALSE;
  2376. }
  2377. else
  2378. {
  2379. relaxing = TRUE;
  2380. /* PIC code. */
  2381. if (strstr (argv[1], "@GOTOFF"))
  2382. {
  2383. /* lw */
  2384. md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
  2385. md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
  2386. md_assemblef ("%c%c%s %s,[$ta+$gp]", ls, size, sign, argv[0]);
  2387. }
  2388. else if (strstr (argv[1], "@GOT"))
  2389. {
  2390. long addend = builtin_addend (argv[1], NULL);
  2391. /* lw */
  2392. md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
  2393. md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
  2394. md_assemble ("lw $ta,[$gp+$ta]"); /* Load address word. */
  2395. if (addend < 0x10000 && addend >= -0x10000)
  2396. {
  2397. md_assemblef ("%c%c%si %s,[$ta+(%d)]", ls, size, sign, argv[0], addend);
  2398. }
  2399. else
  2400. {
  2401. /* lw */
  2402. do_pseudo_li_internal (argv[0], addend);
  2403. md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], argv[0]);
  2404. }
  2405. }
  2406. else
  2407. {
  2408. as_bad (_("needs @GOT or @GOTOFF. %s"), argv[argc]);
  2409. }
  2410. relaxing = FALSE;
  2411. }
  2412. }
  2413. static void
  2414. do_pseudo_ls_bhwp (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
  2415. {
  2416. char *arg_rt = argv[0];
  2417. char *arg_label = argv[1];
  2418. char *arg_inc = argv[2];
  2419. char ls = 'r';
  2420. char size = 'x';
  2421. const char *sign = "";
  2422. /* Prepare arguments for various load/store. */
  2423. sign = (pv & 0x10) ? "s" : "";
  2424. ls = (pv & 0x80000000) ? 's' : 'l';
  2425. switch (pv & 0x3)
  2426. {
  2427. case 0: size = 'b'; break;
  2428. case 1: size = 'h'; break;
  2429. case 2: size = 'w'; break;
  2430. }
  2431. if (ls == 's' || size == 'w')
  2432. sign = "";
  2433. do_pseudo_la_internal ("$ta", arg_label, argv[argc]);
  2434. md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls, size, sign, arg_rt, arg_inc);
  2435. }
  2436. static void
  2437. do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
  2438. {
  2439. char *arg_rt = argv[0];
  2440. char *arg_inc = argv[1];
  2441. char ls = 'r';
  2442. char size = 'x';
  2443. const char *sign = "";
  2444. /* Prepare arguments for various load/store. */
  2445. sign = (pv & 0x10) ? "s" : "";
  2446. ls = (pv & 0x80000000) ? 's' : 'l';
  2447. switch (pv & 0x3)
  2448. {
  2449. case 0: size = 'b'; break;
  2450. case 1: size = 'h'; break;
  2451. case 2: size = 'w'; break;
  2452. }
  2453. if (ls == 's' || size == 'w')
  2454. sign = "";
  2455. md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls, size, sign, arg_rt, arg_inc);
  2456. }
  2457. static void
  2458. do_pseudo_ls_bhwi (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
  2459. {
  2460. char ls = 'r';
  2461. char size = 'x';
  2462. const char *sign = "";
  2463. /* Prepare arguments for various load/store. */
  2464. sign = (pv & 0x10) ? "s" : "";
  2465. ls = (pv & 0x80000000) ? 's' : 'l';
  2466. switch (pv & 0x3)
  2467. {
  2468. case 0: size = 'b'; break;
  2469. case 1: size = 'h'; break;
  2470. case 2: size = 'w'; break;
  2471. }
  2472. if (ls == 's' || size == 'w')
  2473. sign = "";
  2474. md_assemblef ("%c%c%si.bi %s,%s,%s",
  2475. ls, size, sign, argv[0], argv[1], argv[2]);
  2476. }
  2477. static void
  2478. do_pseudo_move_reg_internal (char *dst, char *src)
  2479. {
  2480. if (enable_16bit)
  2481. md_assemblef ("mov55 %s,%s", dst, src);
  2482. else
  2483. md_assemblef ("ori %s,%s,0", dst, src);
  2484. }
  2485. static void
  2486. do_pseudo_move (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2487. {
  2488. expressionS exp;
  2489. if (builtin_isreg (argv[1], NULL))
  2490. do_pseudo_move_reg_internal (argv[0], argv[1]);
  2491. else
  2492. {
  2493. parse_expression (argv[1], &exp);
  2494. if (exp.X_op == O_constant)
  2495. /* move $rt, imm -> li $rt, imm */
  2496. do_pseudo_li_internal (argv[0], exp.X_add_number);
  2497. else
  2498. /* l.w $rt, var -> l.w $rt, var */
  2499. do_pseudo_ls_bhw (argc, argv, 2);
  2500. }
  2501. }
  2502. static void
  2503. do_pseudo_neg (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2504. {
  2505. /* Instead of "subri". */
  2506. md_assemblef ("subri %s,%s,0", argv[0], argv[1]);
  2507. }
  2508. static void
  2509. do_pseudo_not (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2510. {
  2511. md_assemblef ("nor %s,%s,%s", argv[0], argv[1], argv[1]);
  2512. }
  2513. static void
  2514. do_pseudo_pushpopm (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
  2515. {
  2516. /* posh/pop $ra, $rb */
  2517. /* SMW.{b | a}{i | d}{m?} Rb, [Ra], Re, Enable4 */
  2518. int rb, re, ra, en4;
  2519. int i;
  2520. char *opc = "pushpopm";
  2521. if (argc == 3)
  2522. as_bad ("'pushm/popm $ra5, $rb5, $label' is deprecated. "
  2523. "Only 'pushm/popm $ra5' is supported now. %s", argv[argc]);
  2524. else if (argc == 1)
  2525. as_bad ("'pushm/popm $ra5, $rb5'. %s\n", argv[argc]);
  2526. if (strstr (argv[argc], "pop") == argv[argc])
  2527. opc = "lmw.bim";
  2528. else if (strstr (argv[argc], "push") == argv[argc])
  2529. opc = "smw.adm";
  2530. else
  2531. as_fatal ("nds32-as internal error. %s", argv[argc]);
  2532. rb = builtin_regnum (argv[0], NULL);
  2533. re = builtin_regnum (argv[1], NULL);
  2534. if (re < rb)
  2535. {
  2536. as_warn ("$rb should not be smaller than $ra. %s", argv[argc]);
  2537. /* Swap to right order. */
  2538. ra = re;
  2539. re = rb;
  2540. rb = ra;
  2541. }
  2542. /* Build enable4 mask. */
  2543. en4 = 0;
  2544. if (re >= 28 || rb >= 28)
  2545. {
  2546. for (i = (rb >= 28? rb: 28); i <= re; i++)
  2547. en4 |= 1 << (3 - (i - 28));
  2548. }
  2549. /* Adjust $re, $rb. */
  2550. if (rb >= 28)
  2551. rb = re = 31;
  2552. else if (nds32_gpr16 != 1 && re >= 28)
  2553. re = 27;
  2554. /* Reduce register. */
  2555. if (nds32_gpr16 && re > 10 && !(rb == 31 && re == 31))
  2556. {
  2557. if (re >= 15 && strstr(opc, "smw") != NULL)
  2558. md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
  2559. if (rb <= 10)
  2560. md_assemblef ("%s $r%d,[$sp],$r10, 0x0", opc, rb);
  2561. if (re >= 15 && strstr(opc, "lmw") != NULL)
  2562. md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
  2563. }
  2564. else
  2565. md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc, rb, re, en4);
  2566. }
  2567. static void
  2568. do_pseudo_pushpop (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
  2569. {
  2570. /* push/pop $ra5, $label=$sp */
  2571. char *argvm[3];
  2572. if (argc == 2)
  2573. as_bad ("'push/pop $ra5, rb5' is deprecated. "
  2574. "Only 'push/pop $ra5' is supported now. %s", argv[argc]);
  2575. argvm[0] = argv[0];
  2576. argvm[1] = argv[0];
  2577. argvm[2] = argv[argc];
  2578. do_pseudo_pushpopm (2, argvm, PV_DONT_CARE);
  2579. }
  2580. static void
  2581. do_pseudo_v3push (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2582. {
  2583. md_assemblef ("push25 %s,%s", argv[0], argv[1]);
  2584. }
  2585. static void
  2586. do_pseudo_v3pop (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2587. {
  2588. md_assemblef ("pop25 %s,%s", argv[0], argv[1]);
  2589. }
  2590. /* pv == 0, parsing "push.s" pseudo instruction operands.
  2591. pv != 0, parsing "pop.s" pseudo instruction operands. */
  2592. static void
  2593. do_pseudo_pushpop_stack (int argc, char *argv[], int pv)
  2594. {
  2595. /* push.s Rb,Re,{$fp $gp $lp $sp} ==> smw.adm Rb,[$sp],Re,Eable4 */
  2596. /* pop.s Rb,Re,{$fp $gp $lp $sp} ==> lmw.bim Rb,[$sp],Re,Eable4 */
  2597. int rb, re;
  2598. int en4;
  2599. int last_arg_index;
  2600. char *opc = (pv == 0) ? "smw.adm" : "lmw.bim";
  2601. rb = re = 0;
  2602. if (argc == 1)
  2603. {
  2604. /* argc=1, operands pattern: { $fp $gp $lp $sp } */
  2605. /* Set register number Rb = Re = $sp = $r31. */
  2606. rb = re = 31;
  2607. }
  2608. else if (argc == 2 || argc == 3)
  2609. {
  2610. /* argc=2, operands pattern: Rb, Re */
  2611. /* argc=3, operands pattern: Rb, Re, { $fp $gp $lp $sp } */
  2612. /* Get register number in integer. */
  2613. rb = builtin_regnum (argv[0], NULL);
  2614. re = builtin_regnum (argv[1], NULL);
  2615. /* Rb should be equal/less than Re. */
  2616. if (rb > re)
  2617. as_bad ("The first operand (%s) should be equal to or smaller than "
  2618. "second operand (%s).", argv[0], argv[1]);
  2619. /* forbid using $fp|$gp|$lp|$sp in Rb or Re
  2620. r28 r29 r30 r31 */
  2621. if (rb >= 28)
  2622. as_bad ("Cannot use $fp, $gp, $lp, or $sp at first operand !!");
  2623. if (re >= 28)
  2624. as_bad ("Cannot use $fp, $gp, $lp, or $sp at second operand !!");
  2625. }
  2626. else
  2627. {
  2628. as_bad ("Invalid operands pattern !!");
  2629. }
  2630. /* Build Enable4 mask. */
  2631. /* Using last_arg_index for argc=1|2|3 is safe, because $fp, $gp, $lp,
  2632. and $sp only appear in argc=1 or argc=3 if argc=2, en4 remains 0,
  2633. which is also valid for code generation. */
  2634. en4 = 0;
  2635. last_arg_index = argc - 1;
  2636. if (strstr (argv[last_arg_index], "$fp"))
  2637. en4 |= 8;
  2638. if (strstr (argv[last_arg_index], "$gp"))
  2639. en4 |= 4;
  2640. if (strstr (argv[last_arg_index], "$lp"))
  2641. en4 |= 2;
  2642. if (strstr (argv[last_arg_index], "$sp"))
  2643. en4 |= 1;
  2644. md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc, rb, re, en4);
  2645. }
  2646. static void
  2647. do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2648. {
  2649. char size = 'x';
  2650. /* If users omit push location, use $sp as default value. */
  2651. char location[8] = "$sp"; /* 8 is enough for register name. */
  2652. switch (pv & 0x3)
  2653. {
  2654. case 0: size = 'b'; break;
  2655. case 1: size = 'h'; break;
  2656. case 2: size = 'w'; break;
  2657. case 3: size = 'w'; break;
  2658. }
  2659. if (argc == 2)
  2660. {
  2661. strncpy (location, argv[1], 8);
  2662. location[7] = '\0';
  2663. }
  2664. md_assemblef ("l.%c $ta,%s", size, argv[0]);
  2665. md_assemblef ("smw.adm $ta,[%s],$ta", location);
  2666. if ((pv & 0x3) == 0x3) /* double-word */
  2667. {
  2668. md_assemblef ("l.w $ta,%s+4", argv[0]);
  2669. md_assemblef ("smw.adm $ta,[%s],$ta", location);
  2670. }
  2671. }
  2672. static void
  2673. do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2674. {
  2675. char size = 'x';
  2676. /* If users omit pop location, use $sp as default value. */
  2677. char location[8] = "$sp"; /* 8 is enough for register name. */
  2678. switch (pv & 0x3)
  2679. {
  2680. case 0: size = 'b'; break;
  2681. case 1: size = 'h'; break;
  2682. case 2: size = 'w'; break;
  2683. case 3: size = 'w'; break;
  2684. }
  2685. if (argc == 3)
  2686. {
  2687. strncpy (location, argv[2], 8);
  2688. location[7] = '\0';
  2689. }
  2690. if ((pv & 0x3) == 0x3) /* double-word */
  2691. {
  2692. md_assemblef ("lmw.bim %s,[%s],%s", argv[1], location, argv[1]);
  2693. md_assemblef ("s.w %s,%s+4", argv[1], argv[0]);
  2694. }
  2695. md_assemblef ("lmw.bim %s,[%s],%s", argv[1], location, argv[1]);
  2696. md_assemblef ("s.%c %s,%s", size, argv[1], argv[0]);
  2697. }
  2698. static void
  2699. do_pseudo_pusha (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2700. {
  2701. /* If users omit push location, use $sp as default value. */
  2702. char location[8] = "$sp"; /* 8 is enough for register name. */
  2703. if (argc == 2)
  2704. {
  2705. strncpy (location, argv[1], 8);
  2706. location[7] = '\0';
  2707. }
  2708. md_assemblef ("la $ta,%s", argv[0]);
  2709. md_assemblef ("smw.adm $ta,[%s],$ta", location);
  2710. }
  2711. static void
  2712. do_pseudo_pushi (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
  2713. {
  2714. /* If users omit push location, use $sp as default value. */
  2715. char location[8] = "$sp"; /* 8 is enough for register name. */
  2716. if (argc == 2)
  2717. {
  2718. strncpy (location, argv[1], 8);
  2719. location[7] = '\0';
  2720. }
  2721. md_assemblef ("li $ta,%s", argv[0]);
  2722. md_assemblef ("smw.adm $ta,[%s],$ta", location);
  2723. }
  2724. struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] =
  2725. {
  2726. {"b", 1, do_pseudo_b, 0, 0},
  2727. {"bal", 1, do_pseudo_bal, 0, 0},
  2728. {"bge", 3, do_pseudo_bge, 0, 0},
  2729. {"bges", 3, do_pseudo_bges, 0, 0},
  2730. {"bgt", 3, do_pseudo_bgt, 0, 0},
  2731. {"bgts", 3, do_pseudo_bgts, 0, 0},
  2732. {"ble", 3, do_pseudo_ble, 0, 0},
  2733. {"bles", 3, do_pseudo_bles, 0, 0},
  2734. {"blt", 3, do_pseudo_blt, 0, 0},
  2735. {"blts", 3, do_pseudo_blts, 0, 0},
  2736. {"br", 1, do_pseudo_br, 0, 0},
  2737. {"bral", 1, do_pseudo_bral, 0, 0},
  2738. {"call", 1, do_pseudo_bal, 0, 0},
  2739. {"la", 2, do_pseudo_la, 0, 0},
  2740. {"li", 2, do_pseudo_li, 0, 0},
  2741. {"l.b", 2, do_pseudo_ls_bhw, 0, 0},
  2742. {"l.h", 2, do_pseudo_ls_bhw, 1, 0},
  2743. {"l.w", 2, do_pseudo_ls_bhw, 2, 0},
  2744. {"l.bs", 2, do_pseudo_ls_bhw, 0 | 0x10, 0},
  2745. {"l.hs", 2, do_pseudo_ls_bhw, 1 | 0x10, 0},
  2746. {"s.b", 2, do_pseudo_ls_bhw, 0 | 0x80000000, 0},
  2747. {"s.h", 2, do_pseudo_ls_bhw, 1 | 0x80000000, 0},
  2748. {"s.w", 2, do_pseudo_ls_bhw, 2 | 0x80000000, 0},
  2749. {"l.bp", 3, do_pseudo_ls_bhwp, 0, 0},
  2750. {"l.bpc", 3, do_pseudo_ls_bhwpc, 0, 0},
  2751. {"l.hp", 3, do_pseudo_ls_bhwp, 1, 0},
  2752. {"l.hpc", 3, do_pseudo_ls_bhwpc, 1, 0},
  2753. {"l.wp", 3, do_pseudo_ls_bhwp, 2, 0},
  2754. {"l.wpc", 3, do_pseudo_ls_bhwpc, 2, 0},
  2755. {"l.bsp", 3, do_pseudo_ls_bhwp, 0 | 0x10, 0},
  2756. {"l.bspc", 3, do_pseudo_ls_bhwpc, 0 | 0x10, 0},
  2757. {"l.hsp", 3, do_pseudo_ls_bhwp, 1 | 0x10, 0},
  2758. {"l.hspc", 3, do_pseudo_ls_bhwpc, 1 | 0x10, 0},
  2759. {"s.bp", 3, do_pseudo_ls_bhwp, 0 | 0x80000000, 0},
  2760. {"s.bpc", 3, do_pseudo_ls_bhwpc, 0 | 0x80000000, 0},
  2761. {"s.hp", 3, do_pseudo_ls_bhwp, 1 | 0x80000000, 0},
  2762. {"s.hpc", 3, do_pseudo_ls_bhwpc, 1 | 0x80000000, 0},
  2763. {"s.wp", 3, do_pseudo_ls_bhwp, 2 | 0x80000000, 0},
  2764. {"s.wpc", 3, do_pseudo_ls_bhwpc, 2 | 0x80000000, 0},
  2765. {"s.bsp", 3, do_pseudo_ls_bhwp, 0 | 0x80000000 | 0x10, 0},
  2766. {"s.hsp", 3, do_pseudo_ls_bhwp, 1 | 0x80000000 | 0x10, 0},
  2767. {"lbi.p", 3, do_pseudo_ls_bhwi, 0, 0},
  2768. {"lhi.p", 3, do_pseudo_ls_bhwi, 1, 0},
  2769. {"lwi.p", 3, do_pseudo_ls_bhwi, 2, 0},
  2770. {"sbi.p", 3, do_pseudo_ls_bhwi, 0 | 0x80000000, 0},
  2771. {"shi.p", 3, do_pseudo_ls_bhwi, 1 | 0x80000000, 0},
  2772. {"swi.p", 3, do_pseudo_ls_bhwi, 2 | 0x80000000, 0},
  2773. {"lbsi.p", 3, do_pseudo_ls_bhwi, 0 | 0x10, 0},
  2774. {"lhsi.p", 3, do_pseudo_ls_bhwi, 1 | 0x10, 0},
  2775. {"lwsi.p", 3, do_pseudo_ls_bhwi, 2 | 0x10, 0},
  2776. {"move", 2, do_pseudo_move, 0, 0},
  2777. {"neg", 2, do_pseudo_neg, 0, 0},
  2778. {"not", 2, do_pseudo_not, 0, 0},
  2779. {"pop", 2, do_pseudo_pushpop, 0, 0},
  2780. {"push", 2, do_pseudo_pushpop, 0, 0},
  2781. {"popm", 2, do_pseudo_pushpopm, 0, 0},
  2782. {"pushm", 3, do_pseudo_pushpopm, 0, 0},
  2783. {"v3push", 2, do_pseudo_v3push, 0, 0},
  2784. {"v3pop", 2, do_pseudo_v3pop, 0, 0},
  2785. /* Support pseudo instructions of pushing/poping registers into/from stack
  2786. push.s Rb, Re, { $fp $gp $lp $sp } ==> smw.adm Rb,[$sp],Re,Enable4
  2787. pop.s Rb, Re, { $fp $gp $lp $sp } ==> lmw.bim Rb,[$sp],Re,Enable4 */
  2788. { "push.s", 3, do_pseudo_pushpop_stack, 0, 0 },
  2789. { "pop.s", 3, do_pseudo_pushpop_stack, 1, 0 },
  2790. { "push.b", 2, do_pseudo_push_bhwd, 0, 0 },
  2791. { "push.h", 2, do_pseudo_push_bhwd, 1, 0 },
  2792. { "push.w", 2, do_pseudo_push_bhwd, 2, 0 },
  2793. { "push.d", 2, do_pseudo_push_bhwd, 3, 0 },
  2794. { "pop.b", 3, do_pseudo_pop_bhwd, 0, 0 },
  2795. { "pop.h", 3, do_pseudo_pop_bhwd, 1, 0 },
  2796. { "pop.w", 3, do_pseudo_pop_bhwd, 2, 0 },
  2797. { "pop.d", 3, do_pseudo_pop_bhwd, 3, 0 },
  2798. { "pusha", 2, do_pseudo_pusha, 0, 0 },
  2799. { "pushi", 2, do_pseudo_pushi, 0, 0 },
  2800. {NULL, 0, NULL, 0, 0}
  2801. };
  2802. static void
  2803. nds32_init_nds32_pseudo_opcodes (void)
  2804. {
  2805. struct nds32_pseudo_opcode *opcode = nds32_pseudo_opcode_table;
  2806. nds32_pseudo_opcode_hash = hash_new ();
  2807. for ( ; opcode->opcode; opcode++)
  2808. {
  2809. void *op;
  2810. op = hash_find (nds32_pseudo_opcode_hash, opcode->opcode);
  2811. if (op != NULL)
  2812. {
  2813. as_warn (_("Duplicated pseudo-opcode %s."), opcode->opcode);
  2814. continue;
  2815. }
  2816. hash_insert (nds32_pseudo_opcode_hash, opcode->opcode, opcode);
  2817. }
  2818. }
  2819. static struct nds32_pseudo_opcode *
  2820. nds32_lookup_pseudo_opcode (char *str)
  2821. {
  2822. int i = 0;
  2823. /* Assume pseudo-opcode are less than 16-char in length. */
  2824. char op[16] = {0};
  2825. for (i = 0; i < (int)ARRAY_SIZE (op); i++)
  2826. {
  2827. if (ISSPACE (op[i] = str[i]))
  2828. break;
  2829. }
  2830. if (i >= (int)ARRAY_SIZE (op))
  2831. return NULL;
  2832. op[i] = '\0';
  2833. return hash_find (nds32_pseudo_opcode_hash, op);
  2834. }
  2835. static void
  2836. nds32_pseudo_opcode_wrapper (char *line, struct nds32_pseudo_opcode *opcode)
  2837. {
  2838. int argc = 0;
  2839. char *argv[8] = {NULL};
  2840. char *s;
  2841. char *str = xstrdup (line);
  2842. /* Parse arguments for opcode. */
  2843. s = str + strlen (opcode->opcode);
  2844. if (!s[0])
  2845. goto end;
  2846. /* Dummy comma to ease separate arguments as below. */
  2847. s[0] = ',';
  2848. do
  2849. {
  2850. if (s[0] == ',')
  2851. {
  2852. if (argc >= opcode->argc
  2853. || (argc >= (int)ARRAY_SIZE (argv) - 1))
  2854. as_bad (_("Too many argument. `%s'"), line);
  2855. argv[argc] = s + 1;
  2856. argc ++;
  2857. s[0] = '\0';
  2858. }
  2859. ++s;
  2860. } while (s[0] != '\0');
  2861. end:
  2862. /* Put the origin line for debugging. */
  2863. argv[argc] = line;
  2864. opcode->proc (argc, argv, opcode->pseudo_val);
  2865. free (str);
  2866. }
  2867. /* This function will be invoked from function `nds32_after_parse_args'.
  2868. Thus, if the value of option has been set, keep the value the way it is. */
  2869. static int
  2870. nds32_parse_arch (char *str)
  2871. {
  2872. static const struct nds32_arch
  2873. {
  2874. const char *name;
  2875. int baseline;
  2876. int reduced_reg;
  2877. int fpu_sp_ext;
  2878. int fpu_dp_ext;
  2879. int fpu_freg;
  2880. int abi;
  2881. } archs[] =
  2882. {
  2883. {"v3m", ISA_V3M, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
  2884. {"v3j", ISA_V3, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
  2885. {"v3s", ISA_V3, 0, 1, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
  2886. {"v3f", ISA_V3, 0, 1, 1, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
  2887. {"v3", ISA_V3, 0, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
  2888. {"v2j", ISA_V2, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
  2889. {"v2s", ISA_V2, 0, 1, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
  2890. {"v2f", ISA_V2, 0, 1, 1, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
  2891. {"v2", ISA_V2, 0, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
  2892. };
  2893. size_t i;
  2894. for (i = 0; i < ARRAY_SIZE (archs); i++)
  2895. {
  2896. if (strcmp (str, archs[i].name) != 0)
  2897. continue;
  2898. /* The value `-1' represents this option has *NOT* been set. */
  2899. nds32_baseline = (-1 != nds32_baseline) ? nds32_baseline : archs[i].baseline;
  2900. nds32_gpr16 = (-1 != nds32_gpr16) ? nds32_gpr16 : archs[i].reduced_reg;
  2901. nds32_fpu_sp_ext = (-1 != nds32_fpu_sp_ext) ? nds32_fpu_sp_ext : archs[i].fpu_sp_ext;
  2902. nds32_fpu_dp_ext = (-1 != nds32_fpu_dp_ext) ? nds32_fpu_dp_ext : archs[i].fpu_dp_ext;
  2903. nds32_freg = (-1 != nds32_freg) ? nds32_freg : archs[i].fpu_freg;
  2904. nds32_abi = (-1 != nds32_abi) ? nds32_abi : archs[i].abi;
  2905. return 1;
  2906. }
  2907. /* Logic here rejects the input arch name. */
  2908. as_bad (_("unknown arch name `%s'\n"), str);
  2909. return 1;
  2910. }
  2911. /* This function parses "baseline" specified. */
  2912. static int
  2913. nds32_parse_baseline (char *str)
  2914. {
  2915. if (strcmp (str, "v3") == 0)
  2916. nds32_baseline = ISA_V3;
  2917. else if (strcmp (str, "v3m") == 0)
  2918. nds32_baseline = ISA_V3M;
  2919. else if (strcmp (str, "v2") == 0)
  2920. nds32_baseline = ISA_V2;
  2921. else
  2922. {
  2923. /* Logic here rejects the input baseline. */
  2924. as_bad (_("unknown baseline `%s'\n"), str);
  2925. return 0;
  2926. }
  2927. return 1;
  2928. }
  2929. /* This function parses "fpu-freg" specified. */
  2930. static int
  2931. nds32_parse_freg (char *str)
  2932. {
  2933. if (strcmp (str, "2") == 0)
  2934. nds32_freg = E_NDS32_FPU_REG_32SP_16DP;
  2935. else if (strcmp (str, "3") == 0)
  2936. nds32_freg = E_NDS32_FPU_REG_32SP_32DP;
  2937. else if (strcmp (str, "1") == 0)
  2938. nds32_freg = E_NDS32_FPU_REG_16SP_8DP;
  2939. else if (strcmp (str, "0") == 0)
  2940. nds32_freg = E_NDS32_FPU_REG_8SP_4DP;
  2941. else
  2942. {
  2943. /* Logic here rejects the input FPU configuration. */
  2944. as_bad (_("unknown FPU configuration `%s'\n"), str);
  2945. return 0;
  2946. }
  2947. return 1;
  2948. }
  2949. /* This function parse "abi=" specified. */
  2950. static int
  2951. nds32_parse_abi (char *str)
  2952. {
  2953. if (strcmp (str, "v2") == 0)
  2954. nds32_abi = E_NDS_ABI_AABI;
  2955. /* Obsolete. */
  2956. else if (strcmp (str, "v2fp") == 0)
  2957. nds32_abi = E_NDS_ABI_V2FP;
  2958. else if (strcmp (str, "v1") == 0)
  2959. nds32_abi = E_NDS_ABI_V1;
  2960. else if (strcmp (str,"v2fpp") == 0)
  2961. nds32_abi = E_NDS_ABI_V2FP_PLUS;
  2962. else
  2963. {
  2964. /* Logic here rejects the input abi version. */
  2965. as_bad (_("unknown ABI version`%s'\n"), str);
  2966. return 0;
  2967. }
  2968. return 1;
  2969. }
  2970. /* This function turn on all extensions and instructions support. */
  2971. static int
  2972. nds32_all_ext (void)
  2973. {
  2974. nds32_mac = 1;
  2975. nds32_div = 1;
  2976. nds32_dx_regs = 1;
  2977. nds32_16bit_ext = 1;
  2978. nds32_perf_ext = 1;
  2979. nds32_perf_ext2 = 1;
  2980. nds32_string_ext = 1;
  2981. nds32_audio_ext = 1;
  2982. nds32_fpu_fma = 1;
  2983. nds32_fpu_sp_ext = 1;
  2984. nds32_fpu_dp_ext = 1;
  2985. return 1;
  2986. }
  2987. /* GAS will call md_parse_option whenever getopt returns an unrecognized code,
  2988. presumably indicating a special code value which appears in md_longopts.
  2989. This function should return non-zero if it handled the option and zero
  2990. otherwise. There is no need to print a message about an option not being
  2991. recognized. This will be handled by the generic code. */
  2992. int
  2993. nds32_parse_option (int c, char *arg)
  2994. {
  2995. struct nds32_parse_option_table *coarse_tune;
  2996. struct nds32_set_option_table *fine_tune;
  2997. char *ptr_arg = NULL;
  2998. switch (c)
  2999. {
  3000. case OPTION_OPTIMIZE:
  3001. optimize = 1;
  3002. optimize_for_space = 0;
  3003. break;
  3004. case OPTION_OPTIMIZE_SPACE:
  3005. optimize = 0;
  3006. optimize_for_space = 1;
  3007. break;
  3008. case OPTION_BIG:
  3009. target_big_endian = 1;
  3010. break;
  3011. case OPTION_LITTLE:
  3012. target_big_endian = 0;
  3013. break;
  3014. case OPTION_TURBO:
  3015. nds32_all_ext ();
  3016. break;
  3017. case OPTION_PIC:
  3018. nds32_pic = 1;
  3019. break;
  3020. case OPTION_RELAX_FP_AS_GP_OFF:
  3021. nds32_relax_fp_as_gp = 0;
  3022. break;
  3023. case OPTION_RELAX_B2BB_ON:
  3024. nds32_relax_b2bb = 1;
  3025. break;
  3026. case OPTION_RELAX_ALL_OFF:
  3027. nds32_relax_all = 0;
  3028. break;
  3029. default:
  3030. /* Determination of which option table to search for to save time. */
  3031. if (!arg)
  3032. return 0;
  3033. ptr_arg = strchr (arg, '=');
  3034. if (ptr_arg)
  3035. {
  3036. /* Find the value after '='. */
  3037. if (ptr_arg != NULL)
  3038. ptr_arg++;
  3039. for (coarse_tune = parse_opts; coarse_tune->name != NULL; coarse_tune++)
  3040. {
  3041. if (strncmp (arg, coarse_tune->name, (ptr_arg - arg)) == 0)
  3042. {
  3043. coarse_tune->func (ptr_arg);
  3044. return 1;
  3045. }
  3046. }
  3047. }
  3048. else
  3049. {
  3050. int disable = 0;
  3051. /* Filter out the Disable option first. */
  3052. if (strncmp (arg, "no-", 3) == 0)
  3053. {
  3054. disable = 1;
  3055. arg += 3;
  3056. }
  3057. for (fine_tune = toggle_opts; fine_tune->name != NULL; fine_tune++)
  3058. {
  3059. if (strcmp (arg, fine_tune->name) == 0)
  3060. {
  3061. if (fine_tune->var != NULL)
  3062. *fine_tune->var = (disable) ? 0 : 1;
  3063. return 1;
  3064. }
  3065. }
  3066. }
  3067. /* Nothing match. */
  3068. return 0;
  3069. }
  3070. return 1;
  3071. }
  3072. /* tc_check_label */
  3073. void
  3074. nds32_check_label (symbolS *label ATTRIBUTE_UNUSED)
  3075. {
  3076. /* The code used to create BB is move to frob_label.
  3077. They should go there. */
  3078. }
  3079. static void
  3080. set_endian_little (int on)
  3081. {
  3082. target_big_endian = !on;
  3083. }
  3084. /* These functions toggles the generation of 16-bit. First encounter signals
  3085. the beginning of not generating 16-bit instructions and next encounter
  3086. signals the restoring back to default behavior. */
  3087. static void
  3088. trigger_16bit (int trigger)
  3089. {
  3090. enable_16bit = trigger;
  3091. }
  3092. static int backup_16bit_mode;
  3093. static void
  3094. restore_16bit (int no_use ATTRIBUTE_UNUSED)
  3095. {
  3096. enable_16bit = backup_16bit_mode;
  3097. }
  3098. static void
  3099. off_16bit (int no_use ATTRIBUTE_UNUSED)
  3100. {
  3101. backup_16bit_mode = enable_16bit;
  3102. enable_16bit = 0;
  3103. }
  3104. /* Built-in segments for small object. */
  3105. typedef struct nds32_seg_entryT
  3106. {
  3107. segT s;
  3108. const char *name;
  3109. flagword flags;
  3110. } nds32_seg_entry;
  3111. nds32_seg_entry nds32_seg_table[] =
  3112. {
  3113. {NULL, ".sdata_f", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
  3114. | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
  3115. {NULL, ".sdata_b", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
  3116. | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
  3117. {NULL, ".sdata_h", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
  3118. | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
  3119. {NULL, ".sdata_w", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
  3120. | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
  3121. {NULL, ".sdata_d", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
  3122. | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
  3123. {NULL, ".sbss_f", SEC_ALLOC | SEC_SMALL_DATA},
  3124. {NULL, ".sbss_b", SEC_ALLOC | SEC_SMALL_DATA},
  3125. {NULL, ".sbss_h", SEC_ALLOC | SEC_SMALL_DATA},
  3126. {NULL, ".sbss_w", SEC_ALLOC | SEC_SMALL_DATA},
  3127. {NULL, ".sbss_d", SEC_ALLOC | SEC_SMALL_DATA}
  3128. };
  3129. /* Indexes to nds32_seg_table[]. */
  3130. enum NDS32_SECTIONS_ENUM
  3131. {
  3132. SDATA_F_SECTION = 0,
  3133. SDATA_B_SECTION = 1,
  3134. SDATA_H_SECTION = 2,
  3135. SDATA_W_SECTION = 3,
  3136. SDATA_D_SECTION = 4,
  3137. SBSS_F_SECTION = 5,
  3138. SBSS_B_SECTION = 6,
  3139. SBSS_H_SECTION = 7,
  3140. SBSS_W_SECTION = 8,
  3141. SBSS_D_SECTION = 9
  3142. };
  3143. /* The following code is borrowed from v850_seg. Revise this is needed. */
  3144. static void
  3145. do_nds32_seg (int i, subsegT sub)
  3146. {
  3147. nds32_seg_entry *seg = nds32_seg_table + i;
  3148. obj_elf_section_change_hook ();
  3149. if (seg->s != NULL)
  3150. subseg_set (seg->s, sub);
  3151. else
  3152. {
  3153. seg->s = subseg_new (seg->name, sub);
  3154. if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
  3155. {
  3156. bfd_set_section_flags (stdoutput, seg->s, seg->flags);
  3157. if ((seg->flags & SEC_LOAD) == 0)
  3158. seg_info (seg->s)->bss = 1;
  3159. }
  3160. }
  3161. }
  3162. static void
  3163. nds32_seg (int i)
  3164. {
  3165. subsegT sub = get_absolute_expression ();
  3166. do_nds32_seg (i, sub);
  3167. demand_empty_rest_of_line ();
  3168. }
  3169. /* Set if label adjustment is needed. I should not adjust .xbyte in dwarf. */
  3170. static symbolS *nds32_last_label; /* Last label for aligment. */
  3171. /* This code is referred from D30V for adjust label to be with pedning
  3172. aligment. For example,
  3173. LBYTE: .byte 0x12
  3174. LHALF: .half 0x12
  3175. LWORD: .word 0x12
  3176. Without this, the above label will not attatch to incoming data. */
  3177. static void
  3178. nds32_adjust_label (int n)
  3179. {
  3180. /* FIXME: I think adjust lable and alignment is
  3181. the programmer's obligation. Saddly, VLSI team doesn't
  3182. properly use .align for their test cases.
  3183. So I re-implement cons_align and auto adjust labels, again.
  3184. I think d30v's implmentation is simple and good enough. */
  3185. symbolS *label = nds32_last_label;
  3186. nds32_last_label = NULL;
  3187. /* SEC_ALLOC is used to eliminate .debug_ sections.
  3188. SEC_CODE is used to include section for ILM. */
  3189. if (((now_seg->flags & SEC_ALLOC) == 0 && (now_seg->flags & SEC_CODE) == 0)
  3190. || strcmp (now_seg->name, ".eh_frame") == 0
  3191. || strcmp (now_seg->name, ".gcc_except_table") == 0)
  3192. return;
  3193. /* Only frag by alignment when needed.
  3194. Otherwise, it will fail to optimize labels on 4-byte boundary. (bug8454)
  3195. See md_convert_frag () and RELAX_SET_RELAXABLE (frag) for details. */
  3196. if (frag_now_fix () & ((1 << n) -1 ))
  3197. {
  3198. if (subseg_text_p (now_seg))
  3199. frag_align_code (n, 0);
  3200. else
  3201. frag_align (n, 0, 0);
  3202. /* Record the minimum alignment for this segment. */
  3203. record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);
  3204. }
  3205. if (label != NULL)
  3206. {
  3207. symbolS *sym;
  3208. int label_seen = FALSE;
  3209. struct frag *old_frag;
  3210. valueT old_value, new_value;
  3211. gas_assert (S_GET_SEGMENT (label) == now_seg);
  3212. old_frag = symbol_get_frag (label);
  3213. old_value = S_GET_VALUE (label);
  3214. new_value = (valueT) frag_now_fix ();
  3215. /* Multiple labels may be on the same address. And the last symbol
  3216. may not be a label at all, e.g., register name, external function names,
  3217. so I have to track the last label in tc_frob_label instead of
  3218. just using symbol_lastP. */
  3219. for (sym = symbol_lastP; sym != NULL; sym = symbol_previous (sym))
  3220. {
  3221. if (symbol_get_frag (sym) == old_frag
  3222. && S_GET_VALUE (sym) == old_value)
  3223. {
  3224. /* Warning HERE! */
  3225. label_seen = TRUE;
  3226. symbol_set_frag (sym, frag_now);
  3227. S_SET_VALUE (sym, new_value);
  3228. }
  3229. else if (label_seen && symbol_get_frag (sym) != old_frag)
  3230. break;
  3231. }
  3232. }
  3233. }
  3234. void
  3235. nds32_cons_align (int size ATTRIBUTE_UNUSED)
  3236. {
  3237. /* Do nothing here.
  3238. This is called before `md_flush_pending_output' is called by `cons'.
  3239. There are two things should be done for auto-adjust-label.
  3240. 1. Align data/instructions and adjust label to be attached to them.
  3241. 2. Clear auto-adjust state, so incommng data/instructions will not
  3242. adjust the label.
  3243. For example,
  3244. .byte 0x1
  3245. .L0:
  3246. .word 0x2
  3247. .word 0x3
  3248. in this case, '.word 0x2' will adjust the label, .L0, but '.word 0x3' should not.
  3249. I think `md_flush_pending_output' is a good place to clear the auto-adjust state,
  3250. but it is also called by `cons' before this function.
  3251. To simplify the code, instead of overriding .zero, .fill, .space, etc,
  3252. I think we should just adjust label in `nds32_aligned_X_cons' instead of here. */
  3253. }
  3254. static void
  3255. nds32_aligned_cons (int idx)
  3256. {
  3257. nds32_adjust_label (idx);
  3258. /* Call default handler. */
  3259. cons (1 << idx);
  3260. if (now_seg->flags & SEC_CODE
  3261. && now_seg->flags & SEC_ALLOC && now_seg->flags & SEC_RELOC)
  3262. {
  3263. /* Use BFD_RELOC_NDS32_DATA to avoid EX9 optimization replacing data. */
  3264. expressionS exp;
  3265. exp.X_add_number = 0;
  3266. exp.X_op = O_constant;
  3267. fix_new_exp (frag_now, frag_now_fix () - (1 << idx), 1 << idx,
  3268. &exp, 0, BFD_RELOC_NDS32_DATA);
  3269. }
  3270. }
  3271. /* `.double' directive. */
  3272. static void
  3273. nds32_aligned_float_cons (int type)
  3274. {
  3275. switch (type)
  3276. {
  3277. case 'f':
  3278. case 'F':
  3279. case 's':
  3280. case 'S':
  3281. nds32_adjust_label (2);
  3282. break;
  3283. case 'd':
  3284. case 'D':
  3285. case 'r':
  3286. case 'R':
  3287. nds32_adjust_label (4);
  3288. break;
  3289. default:
  3290. as_bad ("Unrecognized float type, %c\n", (char)type);
  3291. }
  3292. /* Call default handler. */
  3293. float_cons (type);
  3294. }
  3295. static void
  3296. nds32_enable_pic (int ignore ATTRIBUTE_UNUSED)
  3297. {
  3298. /* Another way to do -mpic.
  3299. This is for GCC internal use and should always be first line
  3300. of code, otherwise, the effect is not determined. */
  3301. nds32_pic = 1;
  3302. }
  3303. static void
  3304. nds32_set_abi (int ver)
  3305. {
  3306. nds32_abi = ver;
  3307. }
  3308. /* Relax directive to set relocation R_NDS32_RELAX_ENTRY value. */
  3309. static void
  3310. nds32_relax_relocs (int relax)
  3311. {
  3312. char saved_char;
  3313. char *name;
  3314. int i;
  3315. char *subtype_relax[] =
  3316. {"", "", "ex9", "ifc"};
  3317. name = input_line_pointer;
  3318. while (*input_line_pointer && !ISSPACE (*input_line_pointer))
  3319. input_line_pointer++;
  3320. saved_char = *input_line_pointer;
  3321. *input_line_pointer = 0;
  3322. for (i = 0; i < (int) ARRAY_SIZE (subtype_relax); i++)
  3323. {
  3324. if (strcmp (name, subtype_relax[i]) == 0)
  3325. {
  3326. switch (i)
  3327. {
  3328. case 0:
  3329. case 1:
  3330. enable_relax_relocs = relax & enable_relax_relocs;
  3331. enable_relax_ex9 = relax & enable_relax_ex9;
  3332. enable_relax_ifc = relax & enable_relax_ifc;
  3333. break;
  3334. case 2:
  3335. enable_relax_ex9 = relax;
  3336. break;
  3337. case 3:
  3338. enable_relax_ifc = relax;
  3339. break;
  3340. default:
  3341. break;
  3342. }
  3343. break;
  3344. }
  3345. }
  3346. *input_line_pointer = saved_char;
  3347. ignore_rest_of_line ();
  3348. }
  3349. /* Record which arguments register($r0 ~ $r5) is not used in callee.
  3350. bit[i] for $ri */
  3351. static void
  3352. nds32_set_hint_func_args (int ignore ATTRIBUTE_UNUSED)
  3353. {
  3354. ignore_rest_of_line ();
  3355. }
  3356. /* Insert relocations to mark the begin and end of a fp-omitted function,
  3357. for further relaxation use.
  3358. bit[i] for $ri */
  3359. static void
  3360. nds32_omit_fp_begin (int mode)
  3361. {
  3362. expressionS exp;
  3363. if (nds32_relax_fp_as_gp == 0)
  3364. return;
  3365. exp.X_op = O_symbol;
  3366. exp.X_add_symbol = abs_section_sym;
  3367. if (mode == 1)
  3368. {
  3369. in_omit_fp = 1;
  3370. exp.X_add_number = R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
  3371. fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
  3372. BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
  3373. }
  3374. else
  3375. {
  3376. in_omit_fp = 0;
  3377. exp.X_add_number = R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
  3378. fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
  3379. BFD_RELOC_NDS32_RELAX_REGION_END);
  3380. }
  3381. }
  3382. /* Insert relocations to mark the begin and end of ex9 region,
  3383. for further relaxation use.
  3384. bit[i] for $ri */
  3385. static void
  3386. nds32_no_ex9_begin (int mode)
  3387. {
  3388. expressionS exp;
  3389. exp.X_op = O_symbol;
  3390. exp.X_add_symbol = abs_section_sym;
  3391. if (mode == 1)
  3392. {
  3393. exp.X_add_number = R_NDS32_RELAX_REGION_NO_EX9_FLAG;
  3394. fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
  3395. BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
  3396. }
  3397. else
  3398. {
  3399. exp.X_add_number = R_NDS32_RELAX_REGION_NO_EX9_FLAG;
  3400. fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
  3401. BFD_RELOC_NDS32_RELAX_REGION_END);
  3402. }
  3403. }
  3404. static void
  3405. nds32_loop_begin (int mode)
  3406. {
  3407. /* Insert loop region relocation here. */
  3408. expressionS exp;
  3409. exp.X_op = O_symbol;
  3410. exp.X_add_symbol = abs_section_sym;
  3411. if (mode == 1)
  3412. {
  3413. exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
  3414. fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
  3415. BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
  3416. }
  3417. else
  3418. {
  3419. exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
  3420. fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
  3421. BFD_RELOC_NDS32_RELAX_REGION_END);
  3422. }
  3423. }
  3424. struct nds32_relocs_group
  3425. {
  3426. struct nds32_relocs_pattern *pattern;
  3427. struct nds32_relocs_group *next;
  3428. };
  3429. static struct nds32_relocs_group *nds32_relax_hint_current = NULL;
  3430. /* Insert a relax hint. */
  3431. static void
  3432. nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
  3433. {
  3434. char *name;
  3435. char saved_char;
  3436. struct nds32_relocs_pattern *relocs = NULL;
  3437. struct nds32_relocs_group *group, *new;
  3438. name = input_line_pointer;
  3439. while (*input_line_pointer && !ISSPACE (*input_line_pointer))
  3440. input_line_pointer++;
  3441. saved_char = *input_line_pointer;
  3442. *input_line_pointer = 0;
  3443. name = strdup (name);
  3444. /* Find relax hint entry for next instruction, and all member will be
  3445. initialized at that time. */
  3446. relocs = hash_find (nds32_hint_hash, name);
  3447. if (relocs == NULL)
  3448. {
  3449. relocs = malloc (sizeof (struct nds32_relocs_pattern));
  3450. hash_insert (nds32_hint_hash, name, relocs);
  3451. }
  3452. else
  3453. {
  3454. while (relocs->next)
  3455. relocs=relocs->next;
  3456. relocs->next = malloc (sizeof (struct nds32_relocs_pattern));
  3457. relocs = relocs->next;
  3458. }
  3459. relocs->next = NULL;
  3460. *input_line_pointer = saved_char;
  3461. ignore_rest_of_line ();
  3462. /* Get the final one of relax hint series. */
  3463. /* It has to build this list because there are maybe more than one
  3464. instructions relative to the same instruction. It to connect to
  3465. next instruction after md_assemble. */
  3466. new = malloc (sizeof (struct nds32_relocs_group));
  3467. new->pattern = relocs;
  3468. new->next = NULL;
  3469. group = nds32_relax_hint_current;
  3470. if (!group)
  3471. nds32_relax_hint_current = new;
  3472. else
  3473. {
  3474. while (group->next != NULL)
  3475. group = group->next;
  3476. group->next = new;
  3477. }
  3478. relaxing = TRUE;
  3479. }
  3480. /* Decide the size of vector entries, only accepts 4 or 16 now. */
  3481. static void
  3482. nds32_vec_size (int ignore ATTRIBUTE_UNUSED)
  3483. {
  3484. expressionS exp;
  3485. expression (&exp);
  3486. if (exp.X_op == O_constant)
  3487. {
  3488. if (exp.X_add_number == 4 || exp.X_add_number == 16)
  3489. {
  3490. if (vec_size == 0)
  3491. vec_size = exp.X_add_number;
  3492. else if (vec_size != exp.X_add_number)
  3493. as_warn (_("Different arguments of .vec_size are found, "
  3494. "previous %d, current %d"),
  3495. (int) vec_size, (int) exp.X_add_number);
  3496. }
  3497. else
  3498. as_warn (_("Argument of .vec_size is expected 4 or 16, actual: %d."),
  3499. (int) exp.X_add_number);
  3500. }
  3501. else
  3502. as_warn (_("Argument of .vec_size is not a constant."));
  3503. }
  3504. /* The behavior of ".flag" directive varies depending on the target.
  3505. In nds32 target, we use it to recognize whether this assembly content is
  3506. generated by compiler. Other features can also be added in this function
  3507. in the future. */
  3508. static void
  3509. nds32_flag (int ignore ATTRIBUTE_UNUSED)
  3510. {
  3511. char *name;
  3512. char saved_char;
  3513. int i;
  3514. char *possible_flags[] = { "verbatim" };
  3515. /* Skip whitespaces. */
  3516. name = input_line_pointer;
  3517. while (*input_line_pointer && !ISSPACE (*input_line_pointer))
  3518. input_line_pointer++;
  3519. saved_char = *input_line_pointer;
  3520. *input_line_pointer = 0;
  3521. for (i = 0; i < (int) ARRAY_SIZE (possible_flags); i++)
  3522. {
  3523. if (strcmp (name, possible_flags[i]) == 0)
  3524. {
  3525. switch (i)
  3526. {
  3527. case 0:
  3528. /* flag: verbatim */
  3529. verbatim = 1;
  3530. break;
  3531. default:
  3532. break;
  3533. }
  3534. /* Already found the flag, no need to continue next loop. */
  3535. break;
  3536. }
  3537. }
  3538. *input_line_pointer = saved_char;
  3539. ignore_rest_of_line ();
  3540. }
  3541. static void
  3542. nds32_n12hc (int ignore ATTRIBUTE_UNUSED)
  3543. {
  3544. /* N1213HC core is used. */
  3545. }
  3546. /* The target specific pseudo-ops which we support. */
  3547. const pseudo_typeS md_pseudo_table[] =
  3548. {
  3549. /* Forced alignment if declared these ways. */
  3550. {"ascii", stringer, 8 + 0},
  3551. {"asciz", stringer, 8 + 1},
  3552. {"double", nds32_aligned_float_cons, 'd'},
  3553. {"dword", nds32_aligned_cons, 3},
  3554. {"float", nds32_aligned_float_cons, 'f'},
  3555. {"half", nds32_aligned_cons, 1},
  3556. {"hword", nds32_aligned_cons, 1},
  3557. {"int", nds32_aligned_cons, 2},
  3558. {"long", nds32_aligned_cons, 2},
  3559. {"octa", nds32_aligned_cons, 4},
  3560. {"quad", nds32_aligned_cons, 3},
  3561. {"qword", nds32_aligned_cons, 4},
  3562. {"short", nds32_aligned_cons, 1},
  3563. {"byte", nds32_aligned_cons, 0},
  3564. {"single", nds32_aligned_float_cons, 'f'},
  3565. {"string", stringer, 8 + 1},
  3566. {"word", nds32_aligned_cons, 2},
  3567. {"little", set_endian_little, 1},
  3568. {"big", set_endian_little, 0},
  3569. {"16bit_on", trigger_16bit, 1},
  3570. {"16bit_off", trigger_16bit, 0},
  3571. {"restore_16bit", restore_16bit, 0},
  3572. {"off_16bit", off_16bit, 0},
  3573. {"sdata_d", nds32_seg, SDATA_D_SECTION},
  3574. {"sdata_w", nds32_seg, SDATA_W_SECTION},
  3575. {"sdata_h", nds32_seg, SDATA_H_SECTION},
  3576. {"sdata_b", nds32_seg, SDATA_B_SECTION},
  3577. {"sdata_f", nds32_seg, SDATA_F_SECTION},
  3578. {"sbss_d", nds32_seg, SBSS_D_SECTION},
  3579. {"sbss_w", nds32_seg, SBSS_W_SECTION},
  3580. {"sbss_h", nds32_seg, SBSS_H_SECTION},
  3581. {"sbss_b", nds32_seg, SBSS_B_SECTION},
  3582. {"sbss_f", nds32_seg, SBSS_F_SECTION},
  3583. {"pic", nds32_enable_pic, 0},
  3584. {"n12_hc", nds32_n12hc, 0},
  3585. {"abi_1", nds32_set_abi, E_NDS_ABI_V1},
  3586. {"abi_2", nds32_set_abi, E_NDS_ABI_AABI},
  3587. /* Obsolete. */
  3588. {"abi_2fp", nds32_set_abi, E_NDS_ABI_V2FP},
  3589. {"abi_2fp_plus", nds32_set_abi, E_NDS_ABI_V2FP_PLUS},
  3590. {"relax", nds32_relax_relocs, 1},
  3591. {"no_relax", nds32_relax_relocs, 0},
  3592. {"hint_func_args", nds32_set_hint_func_args, 0}, /* Abandon?? */
  3593. {"omit_fp_begin", nds32_omit_fp_begin, 1},
  3594. {"omit_fp_end", nds32_omit_fp_begin, 0},
  3595. {"no_ex9_begin", nds32_no_ex9_begin, 1},
  3596. {"no_ex9_end", nds32_no_ex9_begin, 0},
  3597. {"vec_size", nds32_vec_size, 0},
  3598. {"flag", nds32_flag, 0},
  3599. {"innermost_loop_begin", nds32_loop_begin, 1},
  3600. {"innermost_loop_end", nds32_loop_begin, 0},
  3601. {"relax_hint", nds32_relax_hint, 0},
  3602. {NULL, NULL, 0}
  3603. };
  3604. void
  3605. nds32_pre_do_align (int n, char *fill, int len, int max)
  3606. {
  3607. /* Only make a frag if we HAVE to... */
  3608. fragS *fragP;
  3609. if (n != 0 && !need_pass_2)
  3610. {
  3611. if (fill == NULL)
  3612. {
  3613. if (subseg_text_p (now_seg))
  3614. {
  3615. dwarf2_emit_insn (0);
  3616. fragP = frag_now;
  3617. frag_align_code (n, max);
  3618. /* Tag this alignment when there is a lable before it. */
  3619. if (label_exist)
  3620. {
  3621. fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
  3622. label_exist = 0;
  3623. }
  3624. }
  3625. else
  3626. frag_align (n, 0, max);
  3627. }
  3628. else if (len <= 1)
  3629. frag_align (n, *fill, max);
  3630. else
  3631. frag_align_pattern (n, fill, len, max);
  3632. }
  3633. }
  3634. void
  3635. nds32_do_align (int n)
  3636. {
  3637. /* Optimize for space and label exists. */
  3638. expressionS exp;
  3639. /* FIXME:I think this will break debug info sections and except_table. */
  3640. if (!enable_relax_relocs || !subseg_text_p (now_seg))
  3641. return;
  3642. /* Create and attach a BFD_RELOC_NDS32_LABEL fixup
  3643. the size of instruction may not be correct because
  3644. it could be relaxable. */
  3645. exp.X_op = O_symbol;
  3646. exp.X_add_symbol = section_symbol (now_seg);
  3647. exp.X_add_number = n;
  3648. fix_new_exp (frag_now,
  3649. frag_now_fix (), 0, &exp, 0, BFD_RELOC_NDS32_LABEL);
  3650. }
  3651. /* Supported Andes machines. */
  3652. struct nds32_machs
  3653. {
  3654. enum bfd_architecture bfd_mach;
  3655. int mach_flags;
  3656. };
  3657. /* This is the callback for nds32-asm.c to parse operands. */
  3658. int
  3659. nds32_asm_parse_operand (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
  3660. struct nds32_asm_insn *pinsn,
  3661. char **pstr, int64_t *value)
  3662. {
  3663. char *hold;
  3664. expressionS *pexp = pinsn->info;
  3665. hold = input_line_pointer;
  3666. input_line_pointer = *pstr;
  3667. expression (pexp);
  3668. *pstr = input_line_pointer;
  3669. input_line_pointer = hold;
  3670. switch (pexp->X_op)
  3671. {
  3672. case O_symbol:
  3673. *value = 0;
  3674. return NASM_R_SYMBOL;
  3675. case O_constant:
  3676. *value = pexp->X_add_number;
  3677. return NASM_R_CONST;
  3678. case O_illegal:
  3679. case O_absent:
  3680. case O_register:
  3681. default:
  3682. return NASM_R_ILLEGAL;
  3683. }
  3684. }
  3685. /* GAS will call this function at the start of the assembly, after the command
  3686. line arguments have been parsed and all the machine independent
  3687. initializations have been completed. */
  3688. void
  3689. md_begin (void)
  3690. {
  3691. struct nds32_keyword *k;
  3692. relax_info_t *relax_info;
  3693. bfd_set_arch_mach (stdoutput, TARGET_ARCH, nds32_baseline);
  3694. nds32_init_nds32_pseudo_opcodes ();
  3695. asm_desc.parse_operand = nds32_asm_parse_operand;
  3696. nds32_asm_init (&asm_desc, 0);
  3697. /* Initial general pupose registers hash table. */
  3698. nds32_gprs_hash = hash_new ();
  3699. for (k = keyword_gpr; k->name; k++)
  3700. hash_insert (nds32_gprs_hash, k->name, k);
  3701. /* Initial branch hash table. */
  3702. nds32_relax_info_hash = hash_new ();
  3703. for (relax_info = relax_table; relax_info->opcode; relax_info++)
  3704. hash_insert (nds32_relax_info_hash, relax_info->opcode, relax_info);
  3705. /* Initial relax hint hash table. */
  3706. nds32_hint_hash = hash_new ();
  3707. enable_16bit = nds32_16bit_ext;
  3708. }
  3709. /* HANDLE_ALIGN in write.c. */
  3710. void
  3711. nds32_handle_align (fragS *fragp)
  3712. {
  3713. static const unsigned char nop16[] = { 0x92, 0x00 };
  3714. static const unsigned char nop32[] = { 0x40, 0x00, 0x00, 0x09 };
  3715. int bytes;
  3716. char *p;
  3717. if (fragp->fr_type != rs_align_code)
  3718. return;
  3719. bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
  3720. p = fragp->fr_literal + fragp->fr_fix;
  3721. if (bytes & 1)
  3722. {
  3723. *p++ = 0;
  3724. bytes--;
  3725. }
  3726. if (bytes & 2)
  3727. {
  3728. expressionS exp_t;
  3729. exp_t.X_op = O_symbol;
  3730. exp_t.X_add_symbol = abs_section_sym;
  3731. exp_t.X_add_number = R_NDS32_INSN16_CONVERT_FLAG;
  3732. fix_new_exp (fragp, fragp->fr_fix, 2, &exp_t, 0,
  3733. BFD_RELOC_NDS32_INSN16);
  3734. memcpy (p, nop16, 2);
  3735. p += 2;
  3736. bytes -= 2;
  3737. }
  3738. while (bytes >= 4)
  3739. {
  3740. memcpy (p, nop32, 4);
  3741. p += 4;
  3742. bytes -= 4;
  3743. }
  3744. bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
  3745. fragp->fr_fix += bytes;
  3746. }
  3747. /* md_flush_pending_output */
  3748. void
  3749. nds32_flush_pending_output (void)
  3750. {
  3751. nds32_last_label = NULL;
  3752. }
  3753. void
  3754. nds32_frob_label (symbolS *label)
  3755. {
  3756. dwarf2_emit_label (label);
  3757. }
  3758. /* TC_START_LABEL */
  3759. int
  3760. nds32_start_label (int asmdone ATTRIBUTE_UNUSED, int secdone ATTRIBUTE_UNUSED)
  3761. {
  3762. if (optimize && subseg_text_p (now_seg))
  3763. label_exist = 1;
  3764. return 1;
  3765. }
  3766. /* TARGET_FORMAT */
  3767. const char *
  3768. nds32_target_format (void)
  3769. {
  3770. #ifdef TE_LINUX
  3771. if (target_big_endian)
  3772. return "elf32-nds32be-linux";
  3773. else
  3774. return "elf32-nds32le-linux";
  3775. #else
  3776. if (target_big_endian)
  3777. return "elf32-nds32be";
  3778. else
  3779. return "elf32-nds32le";
  3780. #endif
  3781. }
  3782. static enum nds32_br_range
  3783. get_range_type (const struct nds32_field *field)
  3784. {
  3785. gas_assert (field != NULL);
  3786. if (field->bitpos != 0)
  3787. return BR_RANGE_U4G;
  3788. if (field->bitsize == 24 && field->shift == 1)
  3789. return BR_RANGE_S16M;
  3790. else if (field->bitsize == 16 && field->shift == 1)
  3791. return BR_RANGE_S64K;
  3792. else if (field->bitsize == 14 && field->shift == 1)
  3793. return BR_RANGE_S16K;
  3794. else if (field->bitsize == 8 && field->shift == 1)
  3795. return BR_RANGE_S256;
  3796. else
  3797. return BR_RANGE_U4G;
  3798. }
  3799. /* Save pseudo instruction relocation list. */
  3800. static struct nds32_relocs_pattern*
  3801. nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_opcode *opcode,
  3802. char *out, symbolS *sym,
  3803. struct nds32_relocs_pattern *reloc_ptr,
  3804. fragS *fragP)
  3805. {
  3806. if (!reloc_ptr)
  3807. reloc_ptr = malloc (sizeof (struct nds32_relocs_pattern));
  3808. reloc_ptr->seg = now_seg;
  3809. reloc_ptr->sym = sym;
  3810. reloc_ptr->frag = fragP;
  3811. reloc_ptr->frchain = frchain_now;
  3812. reloc_ptr->fixP = fixP;
  3813. reloc_ptr->opcode = opcode;
  3814. reloc_ptr->where = out;
  3815. reloc_ptr->next = NULL;
  3816. return reloc_ptr;
  3817. }
  3818. /* Check X_md to transform relocation. */
  3819. static fixS*
  3820. nds32_elf_record_fixup_exp (fragS *fragP, char *str,
  3821. const struct nds32_field *fld,
  3822. expressionS *pexp, char* out,
  3823. struct nds32_asm_insn *insn)
  3824. {
  3825. int reloc = -1;
  3826. expressionS exp;
  3827. fixS *fixP = NULL;
  3828. /* Handle instruction relocation. */
  3829. if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_HI20))
  3830. {
  3831. /* Relocation for hi20 modifier. */
  3832. switch (pexp->X_md)
  3833. {
  3834. case BFD_RELOC_NDS32_GOTOFF: /* @GOTOFF */
  3835. reloc = BFD_RELOC_NDS32_GOTOFF_HI20;
  3836. break;
  3837. case BFD_RELOC_NDS32_GOT20: /* @GOT */
  3838. reloc = BFD_RELOC_NDS32_GOT_HI20;
  3839. break;
  3840. case BFD_RELOC_NDS32_25_PLTREL: /* @PLT */
  3841. if (!nds32_pic)
  3842. as_bad (_("Invalid PIC expression."));
  3843. else
  3844. reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20;
  3845. break;
  3846. case BFD_RELOC_NDS32_GOTPC20: /* _GLOBAL_OFFSET_TABLE_ */
  3847. reloc = BFD_RELOC_NDS32_GOTPC_HI20;
  3848. break;
  3849. case BFD_RELOC_NDS32_TPOFF: /* @TPOFF */
  3850. reloc = BFD_RELOC_NDS32_TLS_LE_HI20;
  3851. break;
  3852. case BFD_RELOC_NDS32_GOTTPOFF: /* @GOTTPOFF */
  3853. reloc = BFD_RELOC_NDS32_TLS_IE_HI20;
  3854. break;
  3855. default: /* No suffix. */
  3856. reloc = BFD_RELOC_NDS32_HI20;
  3857. break;
  3858. }
  3859. fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
  3860. insn->info, 0 /* pcrel */, reloc);
  3861. }
  3862. else if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_LO12))
  3863. {
  3864. /* Relocation for lo12 modifier. */
  3865. if (fld->bitsize == 15 && fld->shift == 0)
  3866. {
  3867. /* [ls]bi || ori */
  3868. switch (pexp->X_md)
  3869. {
  3870. case BFD_RELOC_NDS32_GOTOFF: /* @GOTOFF */
  3871. reloc = BFD_RELOC_NDS32_GOTOFF_LO12;
  3872. break;
  3873. case BFD_RELOC_NDS32_GOT20: /* @GOT */
  3874. reloc = BFD_RELOC_NDS32_GOT_LO12;
  3875. break;
  3876. case BFD_RELOC_NDS32_25_PLTREL: /* @PLT */
  3877. if (!nds32_pic)
  3878. as_bad (_("Invalid PIC expression."));
  3879. else
  3880. reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12;
  3881. break;
  3882. case BFD_RELOC_NDS32_GOTPC20: /* _GLOBAL_OFFSET_TABLE_ */
  3883. reloc = BFD_RELOC_NDS32_GOTPC_LO12;
  3884. break;
  3885. case BFD_RELOC_NDS32_TPOFF: /* @TPOFF */
  3886. reloc = BFD_RELOC_NDS32_TLS_LE_LO12;
  3887. break;
  3888. default: /* No suffix. */
  3889. reloc = BFD_RELOC_NDS32_LO12S0;
  3890. break;
  3891. }
  3892. }
  3893. else if (fld->bitsize == 15 && fld->shift == 1)
  3894. reloc = BFD_RELOC_NDS32_LO12S1; /* [ls]hi */
  3895. else if (fld->bitsize == 15 && fld->shift == 2)
  3896. {
  3897. /* [ls]wi */
  3898. switch (pexp->X_md)
  3899. {
  3900. case BFD_RELOC_NDS32_GOTTPOFF: /* @GOTTPOFF */
  3901. reloc = BFD_RELOC_NDS32_TLS_IE_LO12S2;
  3902. break;
  3903. default: /* No suffix. */
  3904. reloc = BFD_RELOC_NDS32_LO12S2;
  3905. break;
  3906. }
  3907. }
  3908. else if (fld->bitsize == 15 && fld->shift == 3)
  3909. reloc = BFD_RELOC_NDS32_LO12S3; /* [ls]di */
  3910. else if (fld->bitsize == 12 && fld->shift == 2)
  3911. reloc = R_NDS32_LO12S2_SP_RELA; /* f[ls][sd]i */
  3912. fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
  3913. insn->info, 0 /* pcrel */, reloc);
  3914. }
  3915. else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
  3916. && (insn->attr & NASM_ATTR_PCREL))
  3917. {
  3918. /* Relocation for 32-bit branch instructions. */
  3919. if (fld->bitsize == 24 && fld->shift == 1)
  3920. reloc = BFD_RELOC_NDS32_25_PCREL;
  3921. else if (fld->bitsize == 16 && fld->shift == 1)
  3922. reloc = BFD_RELOC_NDS32_17_PCREL;
  3923. else if (fld->bitsize == 14 && fld->shift == 1)
  3924. reloc = BFD_RELOC_NDS32_15_PCREL;
  3925. else if (fld->bitsize == 8 && fld->shift == 1)
  3926. reloc = BFD_RELOC_NDS32_WORD_9_PCREL;
  3927. else
  3928. abort ();
  3929. fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
  3930. insn->info, 1 /* pcrel */, reloc);
  3931. }
  3932. else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
  3933. && (insn->attr & NASM_ATTR_GPREL))
  3934. {
  3935. /* Relocation for 32-bit gp-relative instructions. */
  3936. if (fld->bitsize == 19 && fld->shift == 0)
  3937. reloc = BFD_RELOC_NDS32_SDA19S0;
  3938. else if (fld->bitsize == 18 && fld->shift == 1)
  3939. reloc = BFD_RELOC_NDS32_SDA18S1;
  3940. else if (fld->bitsize == 17 && fld->shift == 2)
  3941. reloc = BFD_RELOC_NDS32_SDA17S2;
  3942. else
  3943. abort ();
  3944. fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
  3945. insn->info, 0 /* pcrel */, reloc);
  3946. /* Insert INSN16 for converting fp_as_gp. */
  3947. exp.X_op = O_symbol;
  3948. exp.X_add_symbol = abs_section_sym;
  3949. exp.X_add_number = 0;
  3950. if (in_omit_fp && reloc == BFD_RELOC_NDS32_SDA17S2)
  3951. fix_new_exp (fragP, out - fragP->fr_literal,
  3952. insn->opcode->isize, &exp, 0 /* pcrel */,
  3953. BFD_RELOC_NDS32_INSN16);
  3954. }
  3955. else if (fld && fld->bitpos == 0 && insn->opcode->isize == 2
  3956. && (insn->attr & NASM_ATTR_PCREL))
  3957. {
  3958. /* Relocation for 16-bit branch instructions. */
  3959. if (fld->bitsize == 8 && fld->shift == 1)
  3960. reloc = BFD_RELOC_NDS32_9_PCREL;
  3961. else
  3962. abort ();
  3963. fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
  3964. insn->info, 1 /* pcrel */, reloc);
  3965. }
  3966. else if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_IFC_EXT))
  3967. {
  3968. /* Relocation for ifcall instruction. */
  3969. if (insn->opcode->isize == 2 && fld->bitsize == 9 && fld->shift == 1)
  3970. reloc = BFD_RELOC_NDS32_10IFCU_PCREL;
  3971. else if (insn->opcode->isize == 4 && fld->bitsize == 16
  3972. && fld->shift == 1)
  3973. reloc = BFD_RELOC_NDS32_17IFC_PCREL;
  3974. else
  3975. abort ();
  3976. fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
  3977. insn->info, 1 /* pcrel */, reloc);
  3978. }
  3979. else if (fld)
  3980. as_bad (_("Don't know how to handle this field. %s"), str);
  3981. return fixP;
  3982. }
  3983. /* Build instruction pattern to relax. There are two type group pattern
  3984. including pseudo instruction and relax hint. */
  3985. static void
  3986. nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
  3987. struct nds32_opcode *opcode, fragS *fragP,
  3988. const struct nds32_field *fld)
  3989. {
  3990. struct nds32_relocs_pattern *reloc_ptr;
  3991. struct nds32_relocs_group *group;
  3992. symbolS *sym = NULL;
  3993. /* The expression may be used uninitialized. */
  3994. if (fld)
  3995. sym = pexp->X_add_symbol;
  3996. if (pseudo_opcode)
  3997. {
  3998. /* Save instruction relation for pseudo instruction expanding pattern. */
  3999. reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
  4000. NULL, fragP);
  4001. if (!relocs_list)
  4002. relocs_list = reloc_ptr;
  4003. else
  4004. {
  4005. struct nds32_relocs_pattern *temp = relocs_list;
  4006. while (temp->next)
  4007. temp = temp->next;
  4008. temp->next = reloc_ptr;
  4009. }
  4010. }
  4011. else if (nds32_relax_hint_current)
  4012. {
  4013. /* Save instruction relation by relax hint. */
  4014. group = nds32_relax_hint_current;
  4015. while (group)
  4016. {
  4017. nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
  4018. group->pattern, fragP);
  4019. group = group->next;
  4020. free (nds32_relax_hint_current);
  4021. nds32_relax_hint_current = group;
  4022. }
  4023. }
  4024. /* Set relaxing false only for relax_hint trigger it. */
  4025. if (!pseudo_opcode)
  4026. relaxing = FALSE;
  4027. }
  4028. #define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn)
  4029. /* Relax pattern for link time relaxation. */
  4030. static struct nds32_relax_hint_table relax_ls_table[] =
  4031. {
  4032. {
  4033. /* Set address: la -> sethi ori. */
  4034. NDS32_RELAX_HINT_LA, /* main_type */
  4035. 8, /* relax_code_size */
  4036. {
  4037. OP6 (SETHI),
  4038. OP6 (ORI),
  4039. }, /* relax_code_seq */
  4040. {
  4041. {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
  4042. {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
  4043. } /* relax_fixup */
  4044. },
  4045. {
  4046. /* Set address: l.w -> sethi ori. */
  4047. NDS32_RELAX_HINT_LS, /* main_type */
  4048. 8, /* relax_code_size */
  4049. {
  4050. OP6 (SETHI),
  4051. OP6 (LBI),
  4052. }, /* relax_code_seq */
  4053. {
  4054. {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
  4055. {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
  4056. } /* relax_fixup */
  4057. },
  4058. {
  4059. 0,
  4060. 0,
  4061. {0},
  4062. {{0, 0 , 0, 0}}
  4063. }
  4064. };
  4065. /* Since sethi loadstore relocation has to using next instruction to determine
  4066. elimination itself or not, we have to return the next instruction range. */
  4067. static int
  4068. nds32_elf_sethi_range (struct nds32_relocs_pattern *pattern)
  4069. {
  4070. int range = 0;
  4071. while (pattern)
  4072. {
  4073. switch (pattern->opcode->value)
  4074. {
  4075. case INSN_LBI:
  4076. case INSN_SBI:
  4077. case INSN_LBSI:
  4078. case N32_MEM_EXT (N32_MEM_LB):
  4079. case N32_MEM_EXT (N32_MEM_LBS):
  4080. case N32_MEM_EXT (N32_MEM_SB):
  4081. range = NDS32_LOADSTORE_BYTE;
  4082. break;
  4083. case INSN_LHI:
  4084. case INSN_SHI:
  4085. case INSN_LHSI:
  4086. case N32_MEM_EXT (N32_MEM_LH):
  4087. case N32_MEM_EXT (N32_MEM_LHS):
  4088. case N32_MEM_EXT (N32_MEM_SH):
  4089. range = NDS32_LOADSTORE_HALF;
  4090. break;
  4091. case INSN_LWI:
  4092. case INSN_SWI:
  4093. case N32_MEM_EXT (N32_MEM_LW):
  4094. case N32_MEM_EXT (N32_MEM_SW):
  4095. range = NDS32_LOADSTORE_WORD;
  4096. break;
  4097. case INSN_FLSI:
  4098. case INSN_FSSI:
  4099. range = NDS32_LOADSTORE_FLOAT_S;
  4100. break;
  4101. case INSN_FLDI:
  4102. case INSN_FSDI:
  4103. range = NDS32_LOADSTORE_FLOAT_D;
  4104. break;
  4105. case INSN_ORI:
  4106. range = NDS32_LOADSTORE_IMM;
  4107. break;
  4108. default:
  4109. range = NDS32_LOADSTORE_NONE;
  4110. break;
  4111. }
  4112. if (range != NDS32_LOADSTORE_NONE)
  4113. break;
  4114. pattern = pattern->next;
  4115. }
  4116. return range;
  4117. }
  4118. /* The args means: instruction size, the 1st instruction is converted to 16 or
  4119. not, optimize option, 16 bit instruction is enable. */
  4120. #define SET_ADDEND(size, convertible, optimize, insn16_on) \
  4121. (((size) & 0xff) | ((convertible) ? 1 << 31 : 0) \
  4122. | ((optimize) ? 1<< 30 : 0) | (insn16_on ? 1 << 29 : 0))
  4123. static void
  4124. nds32_set_elf_flags_by_insn (struct nds32_asm_insn * insn)
  4125. {
  4126. /* Set E_NDS32_HAS_EXT_INST. */
  4127. if (insn->opcode->attr & NASM_ATTR_PERF_EXT)
  4128. {
  4129. if (nds32_perf_ext)
  4130. nds32_elf_flags |= E_NDS32_HAS_EXT_INST;
  4131. else
  4132. as_bad (_("instruction %s requires enabling performance extension"),
  4133. insn->opcode->opcode);
  4134. }
  4135. else if (insn->opcode->attr & NASM_ATTR_PERF2_EXT)
  4136. {
  4137. if (nds32_perf_ext2)
  4138. nds32_elf_flags |= E_NDS32_HAS_EXT2_INST;
  4139. else
  4140. as_bad (_("instruction %s requires enabling performance extension II"),
  4141. insn->opcode->opcode);
  4142. }
  4143. else if (insn->opcode->attr & NASM_ATTR_AUDIO_ISAEXT)
  4144. {
  4145. if (nds32_audio_ext)
  4146. nds32_elf_flags |= E_NDS32_HAS_AUDIO_INST;
  4147. else
  4148. as_bad (_("instruction %s requires enabling AUDIO extension"),
  4149. insn->opcode->opcode);
  4150. }
  4151. else if (insn->opcode->attr & NASM_ATTR_STR_EXT)
  4152. {
  4153. if (nds32_string_ext)
  4154. nds32_elf_flags |= E_NDS32_HAS_STRING_INST;
  4155. else
  4156. as_bad (_("instruction %s requires enabling STRING extension"),
  4157. insn->opcode->opcode);
  4158. }
  4159. else if ((insn->opcode->attr & NASM_ATTR_DIV)
  4160. && (insn->opcode->attr & NASM_ATTR_DXREG))
  4161. {
  4162. if (nds32_div && nds32_dx_regs)
  4163. nds32_elf_flags |= E_NDS32_HAS_DIV_DX_INST;
  4164. else
  4165. as_bad (_("instruction %s requires enabling DIV & DX_REGS extension"),
  4166. insn->opcode->opcode);
  4167. }
  4168. else if (insn->opcode->attr & NASM_ATTR_FPU)
  4169. {
  4170. if (nds32_fpu_sp_ext || nds32_fpu_dp_ext)
  4171. {
  4172. if (!(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
  4173. nds32_fpu_com = 1;
  4174. }
  4175. else
  4176. as_bad (_("instruction %s requires enabling FPU extension"),
  4177. insn->opcode->opcode);
  4178. }
  4179. else if (insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
  4180. {
  4181. if (nds32_fpu_sp_ext)
  4182. nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
  4183. else
  4184. as_bad (_("instruction %s requires enabling FPU_SP extension"),
  4185. insn->opcode->opcode);
  4186. }
  4187. else if ((insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
  4188. && (insn->opcode->attr & NASM_ATTR_MAC))
  4189. {
  4190. if (nds32_fpu_sp_ext && nds32_mac)
  4191. {
  4192. nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
  4193. nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
  4194. }
  4195. else
  4196. as_bad (_("instruction %s requires enabling FPU_MAC extension"),
  4197. insn->opcode->opcode);
  4198. }
  4199. else if (insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
  4200. {
  4201. if (nds32_fpu_dp_ext)
  4202. nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
  4203. else
  4204. as_bad (_("instruction %s requires enabling FPU_DP extension"),
  4205. insn->opcode->opcode);
  4206. }
  4207. else if ((insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
  4208. && (insn->opcode->attr & NASM_ATTR_MAC))
  4209. {
  4210. if (nds32_fpu_dp_ext && nds32_mac)
  4211. {
  4212. nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
  4213. nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
  4214. }
  4215. else
  4216. as_bad (_("instruction %s requires enabling FPU_MAC extension"),
  4217. insn->opcode->opcode);
  4218. }
  4219. /* TODO: FPU_BOTH */
  4220. else if ((insn->opcode->attr & NASM_ATTR_MAC)
  4221. && (insn->opcode->attr & NASM_ATTR_DXREG))
  4222. {
  4223. if (nds32_mac && nds32_dx_regs)
  4224. nds32_elf_flags |= E_NDS32_HAS_MAC_DX_INST;
  4225. else
  4226. as_bad (_("instruction %s requires enabling DX_REGS extension"),
  4227. insn->opcode->opcode);
  4228. }
  4229. /* TODO: for DX_REG set but not for MAC, DIV, AUDIO */
  4230. else if (insn->opcode->attr & NASM_ATTR_IFC_EXT)
  4231. {
  4232. nds32_elf_flags |= E_NDS32_HAS_IFC_INST;
  4233. }
  4234. /* TODO: E_NDS32_HAS_SATURATION_INST */
  4235. }
  4236. /* Flag for analysis relaxation type. */
  4237. enum nds32_insn_type
  4238. {
  4239. N32_RELAX_SETHI = 1,
  4240. N32_RELAX_BR = (1 << 1),
  4241. N32_RELAX_LSI = (1 << 2),
  4242. N32_RELAX_JUMP = (1 << 3),
  4243. N32_RELAX_CALL = (1 << 4),
  4244. N32_RELAX_ORI = (1 << 5),
  4245. N32_RELAX_MEM = (1 << 6),
  4246. N32_RELAX_MOVI = (1 << 7),
  4247. };
  4248. struct nds32_hint_map
  4249. {
  4250. bfd_reloc_code_real_type hi_type;
  4251. char *opc;
  4252. enum nds32_relax_hint_type hint_type;
  4253. enum nds32_br_range range;
  4254. enum nds32_insn_type insn_list;
  4255. };
  4256. /* Table to match instructions with hint and relax pattern. */
  4257. static struct nds32_hint_map hint_map [] =
  4258. {
  4259. {
  4260. /* LONGCALL4. */
  4261. BFD_RELOC_NDS32_HI20,
  4262. "jal",
  4263. NDS32_RELAX_HINT_NONE,
  4264. BR_RANGE_U4G,
  4265. N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL
  4266. },
  4267. {
  4268. /* LONGCALL5. */
  4269. _dummy_first_bfd_reloc_code_real,
  4270. "bgezal",
  4271. NDS32_RELAX_HINT_NONE,
  4272. BR_RANGE_S16M,
  4273. N32_RELAX_BR | N32_RELAX_CALL
  4274. },
  4275. {
  4276. /* LONGCALL6. */
  4277. BFD_RELOC_NDS32_HI20,
  4278. "bgezal",
  4279. NDS32_RELAX_HINT_NONE,
  4280. BR_RANGE_U4G,
  4281. N32_RELAX_BR | N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL
  4282. },
  4283. {
  4284. /* LONGJUMP4. */
  4285. BFD_RELOC_NDS32_HI20,
  4286. "j",
  4287. NDS32_RELAX_HINT_NONE,
  4288. BR_RANGE_U4G,
  4289. N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_JUMP
  4290. },
  4291. {
  4292. /* LONGJUMP5. */
  4293. /* There is two kinds of veriation of LONGJUMP5. One of them
  4294. generate EMPTY relocation for converted INSN16 if needed.
  4295. But we don't distinguish them here. */
  4296. _dummy_first_bfd_reloc_code_real,
  4297. "beq",
  4298. NDS32_RELAX_HINT_NONE,
  4299. BR_RANGE_S16M,
  4300. N32_RELAX_BR | N32_RELAX_JUMP
  4301. },
  4302. {
  4303. /* LONGJUMP6. */
  4304. BFD_RELOC_NDS32_HI20,
  4305. "beq",
  4306. NDS32_RELAX_HINT_NONE,
  4307. BR_RANGE_U4G,
  4308. N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_BR | N32_RELAX_JUMP
  4309. },
  4310. {
  4311. /* LONGJUMP7. */
  4312. _dummy_first_bfd_reloc_code_real,
  4313. "beqc",
  4314. NDS32_RELAX_HINT_NONE,
  4315. BR_RANGE_S16K,
  4316. N32_RELAX_MOVI | N32_RELAX_BR
  4317. },
  4318. {
  4319. /* LOADSTORE ADDRESS. */
  4320. BFD_RELOC_NDS32_HI20,
  4321. NULL,
  4322. NDS32_RELAX_HINT_LA,
  4323. BR_RANGE_U4G,
  4324. N32_RELAX_SETHI | N32_RELAX_ORI
  4325. },
  4326. {
  4327. /* LOADSTORE ADDRESS. */
  4328. BFD_RELOC_NDS32_HI20,
  4329. NULL,
  4330. NDS32_RELAX_HINT_LS,
  4331. BR_RANGE_U4G,
  4332. N32_RELAX_SETHI | N32_RELAX_LSI
  4333. },
  4334. {0, NULL, 0, 0 ,0}
  4335. };
  4336. /* Find the relaxation pattern according to instructions. */
  4337. static bfd_boolean
  4338. nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
  4339. struct nds32_relax_hint_table *hint_info)
  4340. {
  4341. unsigned int opcode, seq_size;
  4342. enum nds32_br_range range;
  4343. struct nds32_relocs_pattern *pattern, *hi_pattern = NULL;
  4344. char *opc = NULL;
  4345. relax_info_t *relax_info = NULL;
  4346. nds32_relax_fixup_info_t *fixup_info, *hint_fixup;
  4347. enum nds32_relax_hint_type hint_type = NDS32_RELAX_HINT_NONE;
  4348. struct nds32_relax_hint_table *table_ptr;
  4349. uint32_t *code_seq, *hint_code;
  4350. enum nds32_insn_type relax_type = 0;
  4351. struct nds32_hint_map *map_ptr = hint_map;
  4352. unsigned int i;
  4353. char *check_insn[] =
  4354. { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
  4355. /* TODO: PLT GOT. */
  4356. /* Traverse all pattern instruction and set flag. */
  4357. pattern = relocs_pattern;
  4358. while (pattern)
  4359. {
  4360. if (pattern->opcode->isize == 4)
  4361. {
  4362. /* 4 byte instruction. */
  4363. opcode = N32_OP6 (pattern->opcode->value);
  4364. switch (opcode)
  4365. {
  4366. case N32_OP6_SETHI:
  4367. hi_pattern = pattern;
  4368. relax_type |= N32_RELAX_SETHI;
  4369. break;
  4370. case N32_OP6_MEM:
  4371. relax_type |= N32_RELAX_MEM;
  4372. break;
  4373. case N32_OP6_ORI:
  4374. relax_type |= N32_RELAX_ORI;
  4375. break;
  4376. case N32_OP6_BR1:
  4377. case N32_OP6_BR2:
  4378. case N32_OP6_BR3:
  4379. relax_type |= N32_RELAX_BR;
  4380. break;
  4381. case N32_OP6_MOVI:
  4382. relax_type |= N32_RELAX_MOVI;
  4383. break;
  4384. case N32_OP6_LBI:
  4385. case N32_OP6_SBI:
  4386. case N32_OP6_LBSI:
  4387. case N32_OP6_LHI:
  4388. case N32_OP6_SHI:
  4389. case N32_OP6_LHSI:
  4390. case N32_OP6_LWI:
  4391. case N32_OP6_SWI:
  4392. case N32_OP6_LWC:
  4393. case N32_OP6_SWC:
  4394. relax_type |= N32_RELAX_LSI;
  4395. break;
  4396. case N32_OP6_JREG:
  4397. if (__GF (pattern->opcode->value, 0, 1) == 1)
  4398. relax_type |= N32_RELAX_CALL;
  4399. else
  4400. relax_type |= N32_RELAX_JUMP;
  4401. break;
  4402. case N32_OP6_JI:
  4403. if (__GF (pattern->opcode->value, 24, 1) == 1)
  4404. relax_type |= N32_RELAX_CALL;
  4405. else
  4406. relax_type |= N32_RELAX_JUMP;
  4407. break;
  4408. default:
  4409. as_warn (_("relax hint unrecognized instruction: line %d."),
  4410. pattern->frag->fr_line);
  4411. return FALSE;
  4412. }
  4413. }
  4414. else
  4415. {
  4416. /* 2 byte instruction. Compare by opcode name because the opcode of
  4417. 2byte instruction is not regular. */
  4418. for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
  4419. {
  4420. if (strcmp (pattern->opcode->opcode, check_insn[i]) == 0)
  4421. {
  4422. relax_type |= N32_RELAX_BR;
  4423. break;
  4424. }
  4425. }
  4426. if (strcmp (pattern->opcode->opcode, "movi55") == 0)
  4427. relax_type |= N32_RELAX_MOVI;
  4428. }
  4429. pattern = pattern->next;
  4430. }
  4431. /* Analysis instruction flag to choose relaxation table. */
  4432. while (map_ptr->insn_list != 0)
  4433. {
  4434. if (map_ptr->insn_list == relax_type
  4435. && (!hi_pattern
  4436. || (hi_pattern->fixP
  4437. && hi_pattern->fixP->fx_r_type == map_ptr->hi_type)))
  4438. {
  4439. opc = map_ptr->opc;
  4440. hint_type = map_ptr->hint_type;
  4441. range = map_ptr->range;
  4442. break;
  4443. }
  4444. map_ptr++;
  4445. }
  4446. if (map_ptr->insn_list == 0)
  4447. {
  4448. as_warn (_("Can not find match relax hint. line : %d"),
  4449. relocs_pattern->frag->fr_line);
  4450. return FALSE;
  4451. }
  4452. /* Get the match table. */
  4453. if (opc)
  4454. {
  4455. /* Branch relax pattern. */
  4456. relax_info = hash_find (nds32_relax_info_hash, opc);
  4457. if (!relax_info)
  4458. return FALSE;
  4459. fixup_info = relax_info->relax_fixup[range];
  4460. code_seq = relax_info->relax_code_seq[range];
  4461. seq_size = relax_info->relax_code_size[range];
  4462. }
  4463. else if (hint_type)
  4464. {
  4465. /* Load-store relax pattern. */
  4466. table_ptr = relax_ls_table;
  4467. while (table_ptr->main_type != 0)
  4468. {
  4469. if (table_ptr->main_type == hint_type)
  4470. {
  4471. fixup_info = table_ptr->relax_fixup;
  4472. code_seq = table_ptr->relax_code_seq;
  4473. seq_size = table_ptr->relax_code_size;
  4474. break;
  4475. }
  4476. table_ptr++;
  4477. }
  4478. if (table_ptr->main_type == 0)
  4479. return FALSE;
  4480. }
  4481. else
  4482. return FALSE;
  4483. hint_fixup = hint_info->relax_fixup;
  4484. hint_code = hint_info->relax_code_seq;
  4485. hint_info->relax_code_size = seq_size;
  4486. while (fixup_info->size != 0)
  4487. {
  4488. if (fixup_info->ramp & NDS32_HINT)
  4489. {
  4490. memcpy (hint_fixup, fixup_info, sizeof (nds32_relax_fixup_info_t));
  4491. hint_fixup++;
  4492. }
  4493. fixup_info++;
  4494. }
  4495. /* Clear final relocation. */
  4496. memset (hint_fixup, 0, sizeof (nds32_relax_fixup_info_t));
  4497. /* Copy code sequance. */
  4498. memcpy (hint_code, code_seq, seq_size);
  4499. return TRUE;
  4500. }
  4501. /* Because there are a lot of variant of load-store, check
  4502. all these type here. */
  4503. #define CLEAN_REG(insn) ((insn) & 0xff0003ff)
  4504. static bfd_boolean
  4505. nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
  4506. {
  4507. char *check_insn[] =
  4508. { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
  4509. uint32_t insn = opcode->value;
  4510. unsigned int i;
  4511. insn = CLEAN_REG (opcode->value);
  4512. if (insn == seq)
  4513. return TRUE;
  4514. switch (seq)
  4515. {
  4516. case OP6 (LBI):
  4517. /* In relocation_table, it regards instruction LBI as representation
  4518. of all the NDS32_RELAX_HINT_LS pattern. */
  4519. if (insn == OP6 (LBI) || insn == OP6 (SBI) || insn == OP6 (LBSI)
  4520. || insn == OP6 (LHI) || insn == OP6 (SHI) || insn == OP6 (LHSI)
  4521. || insn == OP6 (LWI) || insn == OP6 (SWI)
  4522. || insn == OP6 (LWC) || insn == OP6 (SWC))
  4523. return TRUE;
  4524. break;
  4525. case OP6 (BR2):
  4526. /* This is for LONGCALL5 and LONGCALL6. */
  4527. if (insn == OP6 (BR2))
  4528. return TRUE;
  4529. break;
  4530. case OP6 (BR1):
  4531. /* This is for LONGJUMP5 and LONGJUMP6. */
  4532. if (opcode->isize == 4
  4533. && (insn == OP6 (BR1) || insn == OP6 (BR2) || insn == OP6 (BR3)))
  4534. return TRUE;
  4535. else if (opcode->isize == 2)
  4536. {
  4537. for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
  4538. if (strcmp (opcode->opcode, check_insn[i]) == 0)
  4539. return TRUE;
  4540. }
  4541. break;
  4542. case OP6 (MOVI):
  4543. /* This is for LONGJUMP7. */
  4544. if (opcode->isize == 2 && strcmp (opcode->opcode, "movi55") == 0)
  4545. return TRUE;
  4546. break;
  4547. }
  4548. return FALSE;
  4549. }
  4550. /* Append relax relocation for link time relaxing. */
  4551. static void
  4552. nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
  4553. {
  4554. struct nds32_relocs_pattern *relocs_pattern =
  4555. (struct nds32_relocs_pattern *) value;
  4556. struct nds32_relocs_pattern *pattern_temp, *pattern_now;
  4557. symbolS *sym, *hi_sym = NULL;
  4558. expressionS exp;
  4559. fragS *fragP;
  4560. segT seg_bak = now_seg;
  4561. frchainS *frchain_bak = frchain_now;
  4562. struct nds32_relax_hint_table hint_info;
  4563. nds32_relax_fixup_info_t *hint_fixup, *fixup_now;
  4564. size_t fixup_size;
  4565. offsetT branch_offset;
  4566. fixS *fixP;
  4567. int range, offset;
  4568. unsigned int ptr_offset, hint_count, relax_code_size, count = 0;
  4569. uint32_t *code_seq, code_insn;
  4570. char *where;
  4571. int pcrel;
  4572. if (!relocs_pattern)
  4573. return;
  4574. if (!nds32_find_reloc_table (relocs_pattern, &hint_info))
  4575. return;
  4576. /* Save symbol for some EMPTY relocation using. */
  4577. pattern_now = relocs_pattern;
  4578. while (pattern_now)
  4579. {
  4580. if (pattern_now->opcode->value == OP6 (SETHI))
  4581. {
  4582. hi_sym = pattern_now->sym;
  4583. break;
  4584. }
  4585. pattern_now = pattern_now->next;
  4586. }
  4587. /* Inserting fix up must specify now_seg or frchain_now. */
  4588. now_seg = relocs_pattern->seg;
  4589. frchain_now = relocs_pattern->frchain;
  4590. fragP = relocs_pattern->frag;
  4591. branch_offset = fragP->fr_offset;
  4592. hint_fixup = hint_info.relax_fixup;
  4593. code_seq = hint_info.relax_code_seq;
  4594. relax_code_size = hint_info.relax_code_size;
  4595. pattern_now = relocs_pattern;
  4596. /* Insert relaxation. */
  4597. exp.X_op = O_symbol;
  4598. while (pattern_now)
  4599. {
  4600. /* Choose the match fixup by instruction. */
  4601. code_insn = CLEAN_REG (*(code_seq + count));
  4602. if (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
  4603. {
  4604. count = 0;
  4605. code_insn = CLEAN_REG (*(code_seq + count));
  4606. while (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
  4607. {
  4608. count++;
  4609. if (count >= relax_code_size / 4)
  4610. {
  4611. as_bad (_("Internal error: Relax hint error. %s: %x"),
  4612. now_seg->name, pattern_now->opcode->value);
  4613. goto restore;
  4614. }
  4615. code_insn = CLEAN_REG (*(code_seq + count));
  4616. }
  4617. }
  4618. fragP = pattern_now->frag;
  4619. sym = pattern_now->sym;
  4620. branch_offset = fragP->fr_offset;
  4621. offset = count * 4;
  4622. where = pattern_now->where;
  4623. /* Find the instruction map fix. */
  4624. fixup_now = hint_fixup;
  4625. while (fixup_now->offset != offset)
  4626. {
  4627. fixup_now++;
  4628. if (fixup_now->size == 0)
  4629. break;
  4630. }
  4631. /* This element is without relaxation relocation. */
  4632. if (fixup_now->size == 0)
  4633. {
  4634. pattern_now = pattern_now->next;
  4635. continue;
  4636. }
  4637. fixup_size = fixup_now->size;
  4638. /* Insert all fixup. */
  4639. while (fixup_size != 0 && fixup_now->offset == offset)
  4640. {
  4641. /* Set the real instruction size in element. */
  4642. fixup_size = pattern_now->opcode->isize;
  4643. pcrel = ((fixup_now->ramp & NDS32_PCREL) != 0) ? 1 : 0;
  4644. if (fixup_now->ramp & NDS32_FIX)
  4645. {
  4646. /* Convert original relocation. */
  4647. pattern_now->fixP->fx_r_type = fixup_now->r_type ;
  4648. fixup_size = 0;
  4649. }
  4650. else if ((fixup_now->ramp & NDS32_PTR) != 0)
  4651. {
  4652. /* This relocation has to point to another instruction. Make
  4653. sure each resolved relocation has to be pointed. */
  4654. pattern_temp = relocs_pattern;
  4655. /* All instruction in relax_table should be 32-bit. */
  4656. hint_count = hint_info.relax_code_size / 4;
  4657. code_insn = CLEAN_REG (*(code_seq + hint_count - 1));
  4658. while (pattern_temp)
  4659. {
  4660. /* Point to every resolved relocation. */
  4661. if (nds32_match_hint_insn (pattern_temp->opcode, code_insn))
  4662. {
  4663. ptr_offset =
  4664. pattern_temp->where - pattern_temp->frag->fr_literal;
  4665. exp.X_add_symbol = symbol_temp_new (now_seg, ptr_offset,
  4666. pattern_temp->frag);
  4667. exp.X_add_number = 0;
  4668. fixP =
  4669. fix_new_exp (fragP, where - fragP->fr_literal,
  4670. fixup_size, &exp, 0, fixup_now->r_type);
  4671. fixP->fx_addnumber = fixP->fx_offset;
  4672. }
  4673. pattern_temp = pattern_temp->next;
  4674. }
  4675. fixup_size = 0;
  4676. }
  4677. else if (fixup_now->ramp & NDS32_ADDEND)
  4678. {
  4679. range = nds32_elf_sethi_range (relocs_pattern);
  4680. if (range == NDS32_LOADSTORE_NONE)
  4681. {
  4682. as_bad (_("Internal error: Range error. %s"), now_seg->name);
  4683. return;
  4684. }
  4685. exp.X_add_symbol = abs_section_sym;
  4686. exp.X_add_number = SET_ADDEND (4, 0, optimize, enable_16bit);
  4687. exp.X_add_number |= ((range & 0x3f) << 8);
  4688. }
  4689. else if ((fixup_now->ramp & NDS32_ABS) != 0)
  4690. {
  4691. /* This is a tag relocation. */
  4692. exp.X_add_symbol = abs_section_sym;
  4693. exp.X_add_number = 0;
  4694. }
  4695. else if ((fixup_now->ramp & NDS32_INSN16) != 0)
  4696. {
  4697. if (!enable_16bit)
  4698. fixup_size = 0;
  4699. /* This is a tag relocation. */
  4700. exp.X_add_symbol = abs_section_sym;
  4701. exp.X_add_number = 0;
  4702. }
  4703. else if ((fixup_now->ramp & NDS32_SYM) != 0)
  4704. {
  4705. /* For EMPTY relocation save the true symbol. */
  4706. exp.X_add_symbol = hi_sym;
  4707. exp.X_add_number = branch_offset;
  4708. }
  4709. else
  4710. {
  4711. exp.X_add_symbol = sym;
  4712. exp.X_add_number = branch_offset;
  4713. }
  4714. if (fixup_size != 0)
  4715. {
  4716. fixP = fix_new_exp (fragP, where - fragP->fr_literal, fixup_size,
  4717. &exp, pcrel, fixup_now->r_type);
  4718. fixP->fx_addnumber = fixP->fx_offset;
  4719. }
  4720. fixup_now++;
  4721. fixup_size = fixup_now->size;
  4722. }
  4723. if (count < relax_code_size / 4)
  4724. count++;
  4725. pattern_now = pattern_now->next;
  4726. }
  4727. restore:
  4728. now_seg = seg_bak;
  4729. frchain_now = frchain_bak;
  4730. }
  4731. /* Check instruction if it can be used for the baseline. */
  4732. static bfd_boolean
  4733. nds32_check_insn_available (struct nds32_asm_insn insn, char *str)
  4734. {
  4735. int attr = insn.attr & ATTR_ALL;
  4736. static int baseline_isa = 0;
  4737. /* No isa setting or all isa can use. */
  4738. if (attr == 0 || attr == ATTR_ALL)
  4739. return TRUE;
  4740. if (baseline_isa == 0)
  4741. {
  4742. /* Map option baseline and instruction attribute. */
  4743. switch (nds32_baseline)
  4744. {
  4745. case ISA_V2:
  4746. baseline_isa = ATTR (ISA_V2);
  4747. break;
  4748. case ISA_V3:
  4749. baseline_isa = ATTR (ISA_V3);
  4750. break;
  4751. case ISA_V3M:
  4752. baseline_isa = ATTR (ISA_V3M);
  4753. break;
  4754. }
  4755. }
  4756. if ((baseline_isa & attr) == 0)
  4757. {
  4758. as_bad (_("Not support instrcution %s in the baseline."), str);
  4759. return FALSE;
  4760. }
  4761. return TRUE;
  4762. }
  4763. /* Stub of machine dependent. */
  4764. void
  4765. md_assemble (char *str)
  4766. {
  4767. struct nds32_asm_insn insn;
  4768. char *out;
  4769. struct nds32_pseudo_opcode *popcode;
  4770. const struct nds32_field *fld = NULL;
  4771. fixS *fixP;
  4772. uint16_t insn_16;
  4773. struct nds32_relocs_pattern *relocs_temp;
  4774. expressionS *pexp;
  4775. fragS *fragP;
  4776. int label = label_exist;
  4777. popcode = nds32_lookup_pseudo_opcode (str);
  4778. /* Note that we need to check 'verbatim' and
  4779. 'opcode->physical_op'. If the assembly content is generated by
  4780. compiler and this opcode is a physical instruction, there is no
  4781. need to perform pseudo instruction expansion/transformation. */
  4782. if (popcode && !(verbatim && popcode->physical_op))
  4783. {
  4784. pseudo_opcode = TRUE;
  4785. nds32_pseudo_opcode_wrapper (str, popcode);
  4786. pseudo_opcode = FALSE;
  4787. nds32_elf_append_relax_relocs (NULL, relocs_list);
  4788. /* Free pseudo list. */
  4789. relocs_temp = relocs_list;
  4790. while (relocs_temp)
  4791. {
  4792. relocs_list = relocs_list->next;
  4793. free (relocs_temp);
  4794. relocs_temp = relocs_list;
  4795. }
  4796. return;
  4797. }
  4798. label_exist = 0;
  4799. insn.info = (expressionS *) alloca (sizeof (expressionS));
  4800. asm_desc.result = NASM_OK;
  4801. nds32_assemble (&asm_desc, &insn, str);
  4802. switch (asm_desc.result)
  4803. {
  4804. case NASM_ERR_UNKNOWN_OP:
  4805. as_bad (_("Unrecognized opcode, %s."), str);
  4806. return;
  4807. case NASM_ERR_SYNTAX:
  4808. as_bad (_("Incorrect syntax, %s."), str);
  4809. return;
  4810. case NASM_ERR_OPERAND:
  4811. as_bad (_("Unrecognized operand/register, %s."), str);
  4812. return;
  4813. case NASM_ERR_OUT_OF_RANGE:
  4814. as_bad (_("Operand out of range, %s."), str);
  4815. return;
  4816. case NASM_ERR_REG_REDUCED:
  4817. as_bad (_("Prohibited register used for reduced-register, %s."), str);
  4818. return;
  4819. case NASM_ERR_JUNK_EOL:
  4820. as_bad (_("Junk at end of line, %s."), str);
  4821. return;
  4822. }
  4823. gas_assert (insn.opcode);
  4824. nds32_set_elf_flags_by_insn (&insn);
  4825. gas_assert (insn.opcode->isize == 4 || insn.opcode->isize == 2);
  4826. if (!nds32_check_insn_available (insn, str))
  4827. return;
  4828. /* Make sure the begining of text being 2-byte align. */
  4829. nds32_adjust_label (1);
  4830. fld = insn.field;
  4831. /* Try to allocate the max size to guarantee relaxable same branch
  4832. instructions in the same fragment. */
  4833. frag_grow (NDS32_MAXCHAR);
  4834. fragP = frag_now;
  4835. if (fld && (insn.attr & NASM_ATTR_BRANCH)
  4836. && (pseudo_opcode || (insn.opcode->value != INSN_JAL
  4837. && insn.opcode->value != INSN_J))
  4838. && (!verbatim || pseudo_opcode))
  4839. {
  4840. /* User assembly code branch relax for it. */
  4841. /* If fld is not NULL, it is a symbol. */
  4842. /* Branch msut relax to proper pattern in user assembly code exclude
  4843. J and JAL. Keep these two in original type for users which wants
  4844. to keep their size be fixed. In general, assembler does not convert
  4845. instruction generated by compiler. But jump instruction may be
  4846. truncated in text virtual model. For workaround, compiler generate
  4847. pseudo jump to fix this issue currently. */
  4848. /* Get branch range type. */
  4849. dwarf2_emit_insn (0);
  4850. enum nds32_br_range range_type;
  4851. pexp = insn.info;
  4852. range_type = get_range_type (fld);
  4853. out = frag_var (rs_machine_dependent, NDS32_MAXCHAR,
  4854. 0, /* VAR is un-used. */
  4855. range_type, /* SUBTYPE is used as range type. */
  4856. pexp->X_add_symbol, pexp->X_add_number, 0);
  4857. fragP->fr_fix += insn.opcode->isize;
  4858. fragP->tc_frag_data.opcode = insn.opcode;
  4859. fragP->tc_frag_data.insn = insn.insn;
  4860. if (insn.opcode->isize == 4)
  4861. bfd_putb32 (insn.insn, out);
  4862. else if (insn.opcode->isize == 2)
  4863. bfd_putb16 (insn.insn, out);
  4864. fragP->tc_frag_data.flag |= NDS32_FRAG_BRANCH;
  4865. return;
  4866. /* md_convert_frag will insert relocations. */
  4867. }
  4868. else if (!relaxing && enable_16bit && (optimize || optimize_for_space)
  4869. && ((!fld && !verbatim && insn.opcode->isize == 4
  4870. && nds32_convert_32_to_16 (stdoutput, insn.insn, &insn_16, NULL))
  4871. || (insn.opcode->isize == 2
  4872. && nds32_convert_16_to_32 (stdoutput, insn.insn, NULL))))
  4873. {
  4874. /* Record this one is relaxable. */
  4875. pexp = insn.info;
  4876. dwarf2_emit_insn (0);
  4877. if (fld)
  4878. {
  4879. out = frag_var (rs_machine_dependent,
  4880. 4, /* Max size is 32-bit instruction. */
  4881. 0, /* VAR is un-used. */
  4882. 0, pexp->X_add_symbol, pexp->X_add_number, 0);
  4883. fragP->tc_frag_data.flag |= NDS32_FRAG_RELAXABLE_BRANCH;
  4884. }
  4885. else
  4886. out = frag_var (rs_machine_dependent,
  4887. 4, /* Max size is 32-bit instruction. */
  4888. 0, /* VAR is un-used. */
  4889. 0, NULL, 0, NULL);
  4890. fragP->tc_frag_data.flag |= NDS32_FRAG_RELAXABLE;
  4891. fragP->tc_frag_data.opcode = insn.opcode;
  4892. fragP->tc_frag_data.insn = insn.insn;
  4893. fragP->fr_fix += 2;
  4894. /* In original, we don't relax the instrucion with label on it,
  4895. but this may cause some redundant nop16. Therefore, tag this
  4896. relaxable instruction and relax it carefully. */
  4897. if (label)
  4898. fragP->tc_frag_data.flag |= NDS32_FRAG_LABEL;
  4899. if (insn.opcode->isize == 4)
  4900. bfd_putb16 (insn_16, out);
  4901. else if (insn.opcode->isize == 2)
  4902. bfd_putb16 (insn.insn, out);
  4903. return;
  4904. }
  4905. else if ((verbatim || !relaxing) && optimize && label)
  4906. {
  4907. /* This instruction is with label. */
  4908. expressionS exp;
  4909. out = frag_var (rs_machine_dependent, insn.opcode->isize,
  4910. 0, 0, NULL, 0, NULL);
  4911. /* If this insturction is branch target, it is not relaxable. */
  4912. fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
  4913. fragP->tc_frag_data.opcode = insn.opcode;
  4914. fragP->tc_frag_data.insn = insn.insn;
  4915. fragP->fr_fix += insn.opcode->isize;
  4916. if (insn.opcode->isize == 4)
  4917. {
  4918. exp.X_op = O_symbol;
  4919. exp.X_add_symbol = abs_section_sym;
  4920. exp.X_add_number = 0;
  4921. fixP = fix_new_exp (fragP, fragP->fr_fix - 4, 0, &exp,
  4922. 0, BFD_RELOC_NDS32_LABEL);
  4923. if (!verbatim)
  4924. fragP->tc_frag_data.flag = NDS32_FRAG_ALIGN;
  4925. }
  4926. }
  4927. else
  4928. out = frag_more (insn.opcode->isize);
  4929. if (insn.opcode->isize == 4)
  4930. bfd_putb32 (insn.insn, out);
  4931. if (insn.opcode->isize == 2)
  4932. bfd_putb16 (insn.insn, out);
  4933. dwarf2_emit_insn (insn.opcode->isize);
  4934. /* Compiler generating code and user assembly pseudo load-store, insert
  4935. fixup here. */
  4936. pexp = insn.info;
  4937. fixP = nds32_elf_record_fixup_exp (fragP, str, fld, pexp, out, &insn);
  4938. /* Build relaxation pattern when relaxing is enable. */
  4939. if (relaxing)
  4940. nds32_elf_build_relax_relation (fixP, pexp, out, insn.opcode, fragP, fld);
  4941. }
  4942. /* md_macro_start */
  4943. void
  4944. nds32_macro_start (void)
  4945. {
  4946. }
  4947. /* md_macro_info */
  4948. void
  4949. nds32_macro_info (void *info ATTRIBUTE_UNUSED)
  4950. {
  4951. }
  4952. /* md_macro_end */
  4953. void
  4954. nds32_macro_end (void)
  4955. {
  4956. }
  4957. /* GAS will call this function with one argument, an expressionS pointer, for
  4958. any expression that can not be recognized. When the function is called,
  4959. input_line_pointer will point to the start of the expression. */
  4960. void
  4961. md_operand (expressionS *expressionP)
  4962. {
  4963. if (*input_line_pointer == '#')
  4964. {
  4965. input_line_pointer++;
  4966. expression (expressionP);
  4967. }
  4968. }
  4969. /* GAS will call this function for each section at the end of the assembly, to
  4970. permit the CPU back end to adjust the alignment of a section. The function
  4971. must take two arguments, a segT for the section and a valueT for the size of
  4972. the section, and return a valueT for the rounded size. */
  4973. valueT
  4974. md_section_align (segT segment, valueT size)
  4975. {
  4976. int align = bfd_get_section_alignment (stdoutput, segment);
  4977. return ((size + (1 << align) - 1) & (-1 << align));
  4978. }
  4979. /* GAS will call this function when a symbol table lookup fails, before it
  4980. creates a new symbol. Typically this would be used to supply symbols whose
  4981. name or value changes dynamically, possibly in a context sensitive way.
  4982. Predefined symbols with fixed values, such as register names or condition
  4983. codes, are typically entered directly into the symbol table when md_begin
  4984. is called. One argument is passed, a char * for the symbol. */
  4985. symbolS *
  4986. md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
  4987. {
  4988. return NULL;
  4989. }
  4990. static long
  4991. nds32_calc_branch_offset (segT segment, fragS *fragP,
  4992. long stretch ATTRIBUTE_UNUSED,
  4993. relax_info_t *relax_info,
  4994. enum nds32_br_range branch_range_type)
  4995. {
  4996. struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
  4997. symbolS *branch_symbol = fragP->fr_symbol;
  4998. offsetT branch_offset = fragP->fr_offset;
  4999. offsetT branch_target_address;
  5000. offsetT branch_insn_address;
  5001. long offset = 0;
  5002. if ((S_GET_SEGMENT (branch_symbol) != segment)
  5003. || S_IS_WEAK (branch_symbol))
  5004. {
  5005. /* The symbol is not in the SEGMENT. It could be far far away. */
  5006. offset = 0x80000000;
  5007. }
  5008. else
  5009. {
  5010. /* Calculate symbol-to-instruction offset. */
  5011. branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
  5012. /* If the destination symbol is beyond current frag address,
  5013. STRETCH will take effect to symbol's position. */
  5014. if (S_GET_VALUE (branch_symbol) > fragP->fr_address)
  5015. branch_target_address += stretch;
  5016. branch_insn_address = fragP->fr_address + fragP->fr_fix;
  5017. branch_insn_address -= opcode->isize;
  5018. /* Update BRANCH_INSN_ADDRESS to relaxed position. */
  5019. branch_insn_address += (relax_info->relax_code_size[branch_range_type]
  5020. - relax_info->relax_branch_isize[branch_range_type]);
  5021. offset = branch_target_address - branch_insn_address;
  5022. }
  5023. return offset;
  5024. }
  5025. static enum nds32_br_range
  5026. nds32_convert_to_range_type (long offset)
  5027. {
  5028. enum nds32_br_range range_type;
  5029. if (-(0x100) <= offset && offset < 0x100) /* 256 bytes */
  5030. range_type = BR_RANGE_S256;
  5031. else if (-(0x4000) <= offset && offset < 0x4000) /* 16K bytes */
  5032. range_type = BR_RANGE_S16K;
  5033. else if (-(0x10000) <= offset && offset < 0x10000) /* 64K bytes */
  5034. range_type = BR_RANGE_S64K;
  5035. else if (-(0x1000000) <= offset && offset < 0x1000000) /* 16M bytes */
  5036. range_type = BR_RANGE_S16M;
  5037. else /* 4G bytes */
  5038. range_type = BR_RANGE_U4G;
  5039. return range_type;
  5040. }
  5041. /* Set insntruction register mask. */
  5042. static void
  5043. nds32_elf_get_set_cond (relax_info_t *relax_info, int offset, uint32_t *insn,
  5044. uint32_t ori_insn, int range)
  5045. {
  5046. nds32_cond_field_t *cond_fields = relax_info->cond_field;
  5047. nds32_cond_field_t *code_seq_cond = relax_info->relax_code_condition[range];
  5048. uint32_t mask;
  5049. int i = 0;
  5050. /* The instruction has conditions. Collect condition values. */
  5051. while (code_seq_cond[i].bitmask != 0)
  5052. {
  5053. if (offset == code_seq_cond[i].offset)
  5054. {
  5055. mask = (ori_insn >> cond_fields[i].bitpos) & cond_fields[i].bitmask;
  5056. /* Sign extend. */
  5057. if (cond_fields[i].signed_extend)
  5058. mask = (mask ^ ((cond_fields[i].bitmask + 1) >> 1)) -
  5059. ((cond_fields[i].bitmask + 1) >> 1);
  5060. *insn |= (mask & code_seq_cond[i].bitmask) << code_seq_cond[i].bitpos;
  5061. }
  5062. i++;
  5063. }
  5064. }
  5065. static int
  5066. nds32_relax_branch_instructions (segT segment, fragS *fragP,
  5067. long stretch ATTRIBUTE_UNUSED,
  5068. int init)
  5069. {
  5070. enum nds32_br_range branch_range_type;
  5071. struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
  5072. long offset = 0;
  5073. enum nds32_br_range real_range_type;
  5074. int adjust = 0;
  5075. relax_info_t *relax_info;
  5076. int diff = 0;
  5077. int i, j, k;
  5078. int code_seq_size;
  5079. uint32_t *code_seq;
  5080. uint32_t insn;
  5081. int insn_size;
  5082. int code_seq_offset;
  5083. /* Replace with gas_assert (fragP->fr_symbol != NULL); */
  5084. if (fragP->fr_symbol == NULL)
  5085. return adjust;
  5086. /* If frag_var is not enough room, the previos frag is fr_full and with
  5087. opcode. The new one is rs_dependent but without opcode. */
  5088. if (opcode == NULL)
  5089. return adjust;
  5090. relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
  5091. if (relax_info == NULL)
  5092. return adjust;
  5093. if (init)
  5094. branch_range_type = relax_info->br_range;
  5095. else
  5096. branch_range_type = fragP->fr_subtype;
  5097. offset = nds32_calc_branch_offset (segment, fragP, stretch,
  5098. relax_info, branch_range_type);
  5099. real_range_type = nds32_convert_to_range_type (offset);
  5100. /* If actual range is equal to instruction jump range, do nothing. */
  5101. if (real_range_type == branch_range_type)
  5102. return adjust;
  5103. /* Find out proper relaxation code sequence. */
  5104. for (i = BR_RANGE_S256; i < BR_RANGE_NUM; i++)
  5105. {
  5106. if (real_range_type <= (unsigned int) i)
  5107. {
  5108. if (init)
  5109. diff = relax_info->relax_code_size[i] - opcode->isize;
  5110. else
  5111. diff = relax_info->relax_code_size[i]
  5112. - relax_info->relax_code_size[branch_range_type];
  5113. /* If the instruction could be converted to 16-bits,
  5114. minus the difference. */
  5115. code_seq_offset = 0;
  5116. j = 0;
  5117. k = 0;
  5118. code_seq_size = relax_info->relax_code_size[i];
  5119. code_seq = relax_info->relax_code_seq[i];
  5120. while (code_seq_offset < code_seq_size)
  5121. {
  5122. insn = code_seq[j];
  5123. if (insn & 0x80000000) /* 16-bits instruction. */
  5124. {
  5125. insn_size = 2;
  5126. }
  5127. else /* 32-bits instruction. */
  5128. {
  5129. insn_size = 4;
  5130. while (relax_info->relax_fixup[i][k].size !=0
  5131. && relax_info->relax_fixup[i][k].offset < code_seq_offset)
  5132. k++;
  5133. }
  5134. code_seq_offset += insn_size;
  5135. j++;
  5136. }
  5137. /* Update fr_subtype to new NDS32_BR_RANGE. */
  5138. fragP->fr_subtype = i;
  5139. break;
  5140. }
  5141. }
  5142. return diff + adjust;
  5143. }
  5144. /* Adjust relaxable frag till current frag. */
  5145. static int
  5146. nds32_adjust_relaxable_frag (fragS *startP, fragS *fragP)
  5147. {
  5148. int adj;
  5149. if (startP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
  5150. adj = -2;
  5151. else
  5152. adj = 2;
  5153. startP->tc_frag_data.flag ^= NDS32_FRAG_RELAXED;
  5154. while (startP)
  5155. {
  5156. startP = startP->fr_next;
  5157. if (startP)
  5158. {
  5159. startP->fr_address += adj;
  5160. if (startP == fragP)
  5161. break;
  5162. }
  5163. }
  5164. return adj;
  5165. }
  5166. static addressT
  5167. nds32_get_align (addressT address, int align)
  5168. {
  5169. addressT mask, new_address;
  5170. mask = ~((~0) << align);
  5171. new_address = (address + mask) & (~mask);
  5172. return (new_address - address);
  5173. }
  5174. /* Check the prev_frag is legal. */
  5175. static void
  5176. invalid_prev_frag (fragS * fragP, fragS **prev_frag)
  5177. {
  5178. addressT address;
  5179. fragS *frag_start = *prev_frag;
  5180. if (!frag_start)
  5181. return;
  5182. if (frag_start->last_fr_address >= fragP->last_fr_address)
  5183. {
  5184. *prev_frag = NULL;
  5185. return;
  5186. }
  5187. fragS *frag_t = *prev_frag;
  5188. while (frag_t != fragP)
  5189. {
  5190. if (frag_t->fr_type == rs_align
  5191. || frag_t->fr_type == rs_align_code
  5192. || frag_t->fr_type == rs_align_test)
  5193. {
  5194. /* Relax instruction can not walk across lable. */
  5195. if (frag_t->tc_frag_data.flag & NDS32_FRAG_LABEL)
  5196. {
  5197. prev_frag = NULL;
  5198. return;
  5199. }
  5200. /* Relax previos relaxable to align rs_align frag. */
  5201. address = frag_t->fr_address + frag_t->fr_fix;
  5202. addressT offset = nds32_get_align (address, (int) frag_t->fr_offset);
  5203. if (offset & 0x2)
  5204. {
  5205. /* If there is label on the prev_frag, check if it is aligned. */
  5206. if (!((*prev_frag)->tc_frag_data.flag & NDS32_FRAG_LABEL)
  5207. || (((*prev_frag)->fr_address + (*prev_frag)->fr_fix - 2 )
  5208. & 0x2) == 0)
  5209. nds32_adjust_relaxable_frag (*prev_frag, frag_t);
  5210. }
  5211. *prev_frag = NULL;
  5212. return;
  5213. }
  5214. frag_t = frag_t->fr_next;
  5215. }
  5216. if (fragP->tc_frag_data.flag & NDS32_FRAG_ALIGN)
  5217. {
  5218. address = fragP->fr_address;
  5219. addressT offset = nds32_get_align (address, 2);
  5220. if (offset & 0x2)
  5221. {
  5222. /* If there is label on the prev_frag, check if it is aligned. */
  5223. if (!((*prev_frag)->tc_frag_data.flag & NDS32_FRAG_LABEL)
  5224. || (((*prev_frag)->fr_address + (*prev_frag)->fr_fix - 2 )
  5225. & 0x2) == 0)
  5226. nds32_adjust_relaxable_frag (*prev_frag, fragP);
  5227. }
  5228. *prev_frag = NULL;
  5229. return;
  5230. }
  5231. }
  5232. /* md_relax_frag */
  5233. int
  5234. nds32_relax_frag (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED)
  5235. {
  5236. /* Currently, there are two kinds of relaxation in nds32 assembler.
  5237. 1. relax for branch
  5238. 2. relax for 32-bits to 16-bits */
  5239. static fragS *prev_frag = NULL;
  5240. int adjust = 0;
  5241. invalid_prev_frag (fragP, &prev_frag);
  5242. if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
  5243. adjust = nds32_relax_branch_instructions (segment, fragP, stretch, 0);
  5244. if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
  5245. prev_frag = NULL;
  5246. if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE
  5247. && (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED) == 0)
  5248. /* Here is considered relaxed case originally. But it may cause
  5249. unendless loop when relaxing. Once the instruction is relaxed,
  5250. it can not be undo. */
  5251. prev_frag = fragP;
  5252. return adjust;
  5253. }
  5254. /* This function returns an initial guess of the length by which a fragment
  5255. must grow to hold a branch to reach its destination. Also updates
  5256. fr_type/fr_subtype as necessary.
  5257. It is called just before doing relaxation. Any symbol that is now undefined
  5258. will not become defined. The guess for fr_var is ACTUALLY the growth beyond
  5259. fr_fix. Whatever we do to grow fr_fix or fr_var contributes to our returned
  5260. value. Although it may not be explicit in the frag, pretend fr_var starts
  5261. with a 0 value. */
  5262. int
  5263. md_estimate_size_before_relax (fragS *fragP, segT segment)
  5264. {
  5265. /* Currently, there are two kinds of relaxation in nds32 assembler.
  5266. 1. relax for branch
  5267. 2. relax for 32-bits to 16-bits */
  5268. /* Save previos relaxable frag. */
  5269. static fragS *prev_frag = NULL;
  5270. int adjust = 0;
  5271. invalid_prev_frag (fragP, &prev_frag);
  5272. if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
  5273. adjust = nds32_relax_branch_instructions (segment, fragP, 0, 1);
  5274. if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
  5275. prev_frag = NULL;
  5276. if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
  5277. adjust = 2;
  5278. else if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE)
  5279. prev_frag = fragP;
  5280. return adjust;
  5281. }
  5282. /* GAS will call this for each rs_machine_dependent fragment. The instruction
  5283. is completed using the data from the relaxation pass. It may also create any
  5284. necessary relocations.
  5285. *FRAGP has been relaxed to its final size, and now needs to have the bytes
  5286. inside it modified to conform to the new size. It is called after relaxation
  5287. is finished.
  5288. fragP->fr_type == rs_machine_dependent.
  5289. fragP->fr_subtype is the subtype of what the address relaxed to. */
  5290. void
  5291. md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
  5292. {
  5293. /* Convert branch relaxation instructions. */
  5294. symbolS *branch_symbol = fragP->fr_symbol;
  5295. offsetT branch_offset = fragP->fr_offset;
  5296. enum nds32_br_range branch_range_type = fragP->fr_subtype;
  5297. struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
  5298. uint32_t origin_insn = fragP->tc_frag_data.insn;
  5299. relax_info_t *relax_info;
  5300. char *fr_buffer;
  5301. int fr_where;
  5302. int addend ATTRIBUTE_UNUSED;
  5303. offsetT branch_target_address, branch_insn_address;
  5304. expressionS exp;
  5305. fixS *fixP;
  5306. uint32_t *code_seq;
  5307. uint32_t insn;
  5308. int code_size, insn_size, offset, fixup_size;
  5309. int buf_offset, pcrel;
  5310. int i, k;
  5311. uint16_t insn_16;
  5312. nds32_relax_fixup_info_t fixup_info[MAX_RELAX_FIX];
  5313. /* Save the 1st instruction is converted to 16 bit or not. */
  5314. unsigned int branch_size;
  5315. /* Replace with gas_assert (branch_symbol != NULL); */
  5316. if (branch_symbol == NULL && !(fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED))
  5317. return;
  5318. /* If frag_var is not enough room, the previos frag is fr_full and with
  5319. opcode. The new one is rs_dependent but without opcode. */
  5320. if (opcode == NULL)
  5321. return;
  5322. if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE_BRANCH)
  5323. {
  5324. relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
  5325. if (relax_info == NULL)
  5326. return;
  5327. i = BR_RANGE_S256;
  5328. while (i < BR_RANGE_NUM
  5329. && relax_info->relax_code_size[i]
  5330. != (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED ? 4 : 2))
  5331. i++;
  5332. if (i >= BR_RANGE_NUM)
  5333. as_bad ("Internal error: Cannot find relocation of"
  5334. "relaxable branch.");
  5335. exp.X_op = O_symbol;
  5336. exp.X_add_symbol = branch_symbol;
  5337. exp.X_add_number = branch_offset;
  5338. pcrel = ((relax_info->relax_fixup[i][0].ramp & NDS32_PCREL) != 0) ? 1 : 0;
  5339. fr_where = fragP->fr_fix - 2;
  5340. fixP = fix_new_exp (fragP, fr_where, relax_info->relax_fixup[i][0].size,
  5341. &exp, pcrel, relax_info->relax_fixup[i][0].r_type);
  5342. fixP->fx_addnumber = fixP->fx_offset;
  5343. if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
  5344. {
  5345. insn_16 = fragP->tc_frag_data.insn;
  5346. nds32_convert_16_to_32 (stdoutput, insn_16, &insn);
  5347. fr_buffer = fragP->fr_literal + fr_where;
  5348. fragP->fr_fix += 2;
  5349. exp.X_op = O_symbol;
  5350. exp.X_add_symbol = abs_section_sym;
  5351. exp.X_add_number = 0;
  5352. fix_new_exp (fragP, fr_where, 4,
  5353. &exp, 0, BFD_RELOC_NDS32_INSN16);
  5354. number_to_chars_bigendian (fr_buffer, insn, 4);
  5355. }
  5356. }
  5357. else if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
  5358. {
  5359. if (fragP->tc_frag_data.opcode->isize == 2)
  5360. {
  5361. insn_16 = fragP->tc_frag_data.insn;
  5362. nds32_convert_16_to_32 (stdoutput, insn_16, &insn);
  5363. }
  5364. else
  5365. insn = fragP->tc_frag_data.insn;
  5366. fragP->fr_fix += 2;
  5367. fr_where = fragP->fr_fix - 4;
  5368. fr_buffer = fragP->fr_literal + fr_where;
  5369. exp.X_op = O_symbol;
  5370. exp.X_add_symbol = abs_section_sym;
  5371. exp.X_add_number = 0;
  5372. fix_new_exp (fragP, fr_where, 4, &exp, 0,
  5373. BFD_RELOC_NDS32_INSN16);
  5374. number_to_chars_bigendian (fr_buffer, insn, 4);
  5375. }
  5376. else if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
  5377. {
  5378. /* Branch instruction adjust and append relocations. */
  5379. relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
  5380. if (relax_info == NULL)
  5381. return;
  5382. fr_where = fragP->fr_fix - opcode->isize;
  5383. fr_buffer = fragP->fr_literal + fr_where;
  5384. if ((S_GET_SEGMENT (branch_symbol) != sec)
  5385. || S_IS_WEAK (branch_symbol))
  5386. {
  5387. if (fragP->fr_offset & 3)
  5388. as_warn (_("Addend to unresolved symbol is not on word boundary."));
  5389. addend = 0;
  5390. }
  5391. else
  5392. {
  5393. /* Calculate symbol-to-instruction offset. */
  5394. branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
  5395. branch_insn_address = fragP->fr_address + fr_where;
  5396. addend = (branch_target_address - branch_insn_address) >> 1;
  5397. }
  5398. code_size = relax_info->relax_code_size[branch_range_type];
  5399. code_seq = relax_info->relax_code_seq[branch_range_type];
  5400. memcpy (fixup_info, relax_info->relax_fixup[branch_range_type],
  5401. sizeof (fixup_info));
  5402. /* Fill in frag. */
  5403. i = 0;
  5404. k = 0;
  5405. offset = 0; /* code_seq offset */
  5406. buf_offset = 0; /* fr_buffer offset */
  5407. while (offset < code_size)
  5408. {
  5409. insn = code_seq[i];
  5410. if (insn & 0x80000000) /* 16-bits instruction. */
  5411. {
  5412. insn = (insn >> 16) & 0xFFFF;
  5413. insn_size = 2;
  5414. }
  5415. else /* 32-bits instruction. */
  5416. {
  5417. insn_size = 4;
  5418. }
  5419. nds32_elf_get_set_cond (relax_info, offset, &insn,
  5420. origin_insn, branch_range_type);
  5421. /* Try to convert to 16-bits instruction. Currently, only the first
  5422. insntruction in pattern can be converted. EX: bnez sethi ori jr,
  5423. only bnez can be converted to 16 bit and ori can't. */
  5424. while (fixup_info[k].size != 0
  5425. && relax_info->relax_fixup[branch_range_type][k].offset < offset)
  5426. k++;
  5427. number_to_chars_bigendian (fr_buffer + buf_offset, insn, insn_size);
  5428. buf_offset += insn_size;
  5429. offset += insn_size;
  5430. i++;
  5431. }
  5432. /* Set up fixup. */
  5433. exp.X_op = O_symbol;
  5434. for (i = 0; fixup_info[i].size != 0; i++)
  5435. {
  5436. fixup_size = fixup_info[i].size;
  5437. pcrel = ((fixup_info[i].ramp & NDS32_PCREL) != 0) ? 1 : 0;
  5438. if ((fixup_info[i].ramp & NDS32_CREATE_LABEL) != 0)
  5439. {
  5440. /* This is a reverse branch. */
  5441. exp.X_add_symbol = symbol_temp_new (sec, 0, fragP->fr_next);
  5442. exp.X_add_number = 0;
  5443. }
  5444. else if ((fixup_info[i].ramp & NDS32_PTR) != 0)
  5445. {
  5446. /* This relocation has to point to another instruction. */
  5447. branch_size = fr_where + code_size - 4;
  5448. exp.X_add_symbol = symbol_temp_new (sec, branch_size, fragP);
  5449. exp.X_add_number = 0;
  5450. }
  5451. else if ((fixup_info[i].ramp & NDS32_ABS) != 0)
  5452. {
  5453. /* This is a tag relocation. */
  5454. exp.X_add_symbol = abs_section_sym;
  5455. exp.X_add_number = 0;
  5456. }
  5457. else if ((fixup_info[i].ramp & NDS32_INSN16) != 0)
  5458. {
  5459. if (!enable_16bit)
  5460. continue;
  5461. /* This is a tag relocation. */
  5462. exp.X_add_symbol = abs_section_sym;
  5463. exp.X_add_number = 0;
  5464. }
  5465. else
  5466. {
  5467. exp.X_add_symbol = branch_symbol;
  5468. exp.X_add_number = branch_offset;
  5469. }
  5470. if (fixup_info[i].r_type != 0)
  5471. {
  5472. fixP = fix_new_exp (fragP, fr_where + fixup_info[i].offset,
  5473. fixup_size, &exp, pcrel,
  5474. fixup_info[i].r_type);
  5475. fixP->fx_addnumber = fixP->fx_offset;
  5476. }
  5477. }
  5478. fragP->fr_fix = fr_where + buf_offset;
  5479. }
  5480. }
  5481. /* tc_frob_file_before_fix */
  5482. void
  5483. nds32_frob_file_before_fix (void)
  5484. {
  5485. }
  5486. static bfd_boolean
  5487. nds32_relaxable_section (asection *sec)
  5488. {
  5489. return ((sec->flags & SEC_DEBUGGING) == 0
  5490. && strcmp (sec->name, ".eh_frame") != 0);
  5491. }
  5492. /* TC_FORCE_RELOCATION */
  5493. int
  5494. nds32_force_relocation (fixS * fix)
  5495. {
  5496. switch (fix->fx_r_type)
  5497. {
  5498. case BFD_RELOC_NDS32_INSN16:
  5499. case BFD_RELOC_NDS32_LABEL:
  5500. case BFD_RELOC_NDS32_LONGCALL1:
  5501. case BFD_RELOC_NDS32_LONGCALL2:
  5502. case BFD_RELOC_NDS32_LONGCALL3:
  5503. case BFD_RELOC_NDS32_LONGJUMP1:
  5504. case BFD_RELOC_NDS32_LONGJUMP2:
  5505. case BFD_RELOC_NDS32_LONGJUMP3:
  5506. case BFD_RELOC_NDS32_LOADSTORE:
  5507. case BFD_RELOC_NDS32_9_FIXED:
  5508. case BFD_RELOC_NDS32_15_FIXED:
  5509. case BFD_RELOC_NDS32_17_FIXED:
  5510. case BFD_RELOC_NDS32_25_FIXED:
  5511. case BFD_RELOC_NDS32_9_PCREL:
  5512. case BFD_RELOC_NDS32_15_PCREL:
  5513. case BFD_RELOC_NDS32_17_PCREL:
  5514. case BFD_RELOC_NDS32_WORD_9_PCREL:
  5515. case BFD_RELOC_NDS32_10_UPCREL:
  5516. case BFD_RELOC_NDS32_25_PCREL:
  5517. case BFD_RELOC_NDS32_MINUEND:
  5518. case BFD_RELOC_NDS32_SUBTRAHEND:
  5519. return 1;
  5520. case BFD_RELOC_8:
  5521. case BFD_RELOC_16:
  5522. case BFD_RELOC_32:
  5523. case BFD_RELOC_NDS32_DIFF_ULEB128:
  5524. /* Linker should handle difference between two symbol. */
  5525. return fix->fx_subsy != NULL
  5526. && nds32_relaxable_section (S_GET_SEGMENT (fix->fx_addsy));
  5527. case BFD_RELOC_64:
  5528. if (fix->fx_subsy)
  5529. as_bad ("Double word for difference between two symbols "
  5530. "is not supported across relaxation.");
  5531. default:
  5532. ;
  5533. }
  5534. if (generic_force_reloc (fix))
  5535. return 1;
  5536. return fix->fx_pcrel;
  5537. }
  5538. /* TC_VALIDATE_FIX_SUB */
  5539. int
  5540. nds32_validate_fix_sub (fixS *fix, segT add_symbol_segment)
  5541. {
  5542. segT sub_symbol_segment;
  5543. /* This code is referred from Xtensa. Check their implementation for
  5544. details. */
  5545. /* Make sure both symbols are in the same segment, and that segment is
  5546. "normal" and relaxable. */
  5547. sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
  5548. return (sub_symbol_segment == add_symbol_segment
  5549. && add_symbol_segment != undefined_section);
  5550. }
  5551. void
  5552. md_number_to_chars (char *buf, valueT val, int n)
  5553. {
  5554. if (target_big_endian)
  5555. number_to_chars_bigendian (buf, val, n);
  5556. else
  5557. number_to_chars_littleendian (buf, val, n);
  5558. }
  5559. /* Equal to MAX_PRECISION in atof-ieee.c. */
  5560. #define MAX_LITTLENUMS 6
  5561. /* This function is called to convert an ASCII string into a floating point
  5562. value in format used by the CPU. */
  5563. char *
  5564. md_atof (int type, char *litP, int *sizeP)
  5565. {
  5566. int i;
  5567. int prec;
  5568. LITTLENUM_TYPE words[MAX_LITTLENUMS];
  5569. char *t;
  5570. switch (type)
  5571. {
  5572. case 'f':
  5573. case 'F':
  5574. case 's':
  5575. case 'S':
  5576. prec = 2;
  5577. break;
  5578. case 'd':
  5579. case 'D':
  5580. case 'r':
  5581. case 'R':
  5582. prec = 4;
  5583. break;
  5584. default:
  5585. *sizeP = 0;
  5586. return _("Bad call to md_atof()");
  5587. }
  5588. t = atof_ieee (input_line_pointer, type, words);
  5589. if (t)
  5590. input_line_pointer = t;
  5591. *sizeP = prec * sizeof (LITTLENUM_TYPE);
  5592. if (target_big_endian)
  5593. {
  5594. for (i = 0; i < prec; i++)
  5595. {
  5596. md_number_to_chars (litP, (valueT) words[i],
  5597. sizeof (LITTLENUM_TYPE));
  5598. litP += sizeof (LITTLENUM_TYPE);
  5599. }
  5600. }
  5601. else
  5602. {
  5603. for (i = prec - 1; i >= 0; i--)
  5604. {
  5605. md_number_to_chars (litP, (valueT) words[i],
  5606. sizeof (LITTLENUM_TYPE));
  5607. litP += sizeof (LITTLENUM_TYPE);
  5608. }
  5609. }
  5610. return 0;
  5611. }
  5612. /* md_elf_section_change_hook */
  5613. void
  5614. nds32_elf_section_change_hook (void)
  5615. {
  5616. }
  5617. /* md_cleanup */
  5618. void
  5619. nds32_cleanup (void)
  5620. {
  5621. }
  5622. /* This function is used to scan leb128 subtraction expressions,
  5623. and insert fixups for them.
  5624. e.g., .leb128 .L1 - .L0
  5625. These expressions are heavily used in debug information or
  5626. exception tables. Because relaxation will change code size,
  5627. we must resolve them in link time. */
  5628. static void
  5629. nds32_insert_leb128_fixes (bfd *abfd ATTRIBUTE_UNUSED,
  5630. asection *sec, void *xxx ATTRIBUTE_UNUSED)
  5631. {
  5632. segment_info_type *seginfo = seg_info (sec);
  5633. struct frag *fragP;
  5634. subseg_set (sec, 0);
  5635. for (fragP = seginfo->frchainP->frch_root;
  5636. fragP; fragP = fragP->fr_next)
  5637. {
  5638. expressionS *exp;
  5639. /* Only unsigned leb128 can be handle. */
  5640. if (fragP->fr_type != rs_leb128 || fragP->fr_subtype != 0
  5641. || fragP->fr_symbol == NULL)
  5642. continue;
  5643. exp = symbol_get_value_expression (fragP->fr_symbol);
  5644. if (exp->X_op != O_subtract)
  5645. continue;
  5646. fix_new_exp (fragP, fragP->fr_fix, 0,
  5647. exp, 0, BFD_RELOC_NDS32_DIFF_ULEB128);
  5648. }
  5649. }
  5650. static void
  5651. nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
  5652. void *xxx ATTRIBUTE_UNUSED)
  5653. {
  5654. segment_info_type *seginfo;
  5655. fragS *fragP;
  5656. fixS *fixP;
  5657. expressionS exp;
  5658. fixS *fixp;
  5659. seginfo = seg_info (sec);
  5660. if (!seginfo || !symbol_rootP || !subseg_text_p (sec) || sec->size == 0)
  5661. return;
  5662. /* If there is no relocation and relax is disabled, it is not necessary to
  5663. insert R_NDS32_RELAX_ENTRY for linker do EX9 or IFC optimization. */
  5664. for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
  5665. if (!fixp->fx_done)
  5666. break;
  5667. if (!fixp && !enable_relax_ex9 && !verbatim)
  5668. return;
  5669. subseg_change (sec, 0);
  5670. /* Set RELAX_ENTRY flags for linker. */
  5671. fragP = seginfo->frchainP->frch_root;
  5672. exp.X_op = O_symbol;
  5673. exp.X_add_symbol = section_symbol (sec);
  5674. exp.X_add_number = 0;
  5675. if (!enable_relax_relocs)
  5676. exp.X_add_number |= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG;
  5677. else
  5678. {
  5679. /* These flags are only enabled when global relax is enabled.
  5680. Maybe we can check DISABLE_RELAX_FLAG at linke-time,
  5681. so we set them anyway. */
  5682. if (enable_relax_ex9)
  5683. exp.X_add_number |= R_NDS32_RELAX_ENTRY_EX9_FLAG;
  5684. if (enable_relax_ifc)
  5685. exp.X_add_number |= R_NDS32_RELAX_ENTRY_IFC_FLAG;
  5686. if (verbatim)
  5687. exp.X_add_number |= R_NDS32_RELAX_ENTRY_VERBATIM_FLAG;
  5688. }
  5689. if (optimize)
  5690. exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG;
  5691. if (optimize_for_space)
  5692. exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG;
  5693. fixP = fix_new_exp (fragP, 0, 0, &exp, 0, BFD_RELOC_NDS32_RELAX_ENTRY);
  5694. fixP->fx_no_overflow = 1;
  5695. }
  5696. /* Analysis relax hint and insert suitable relocation pattern. */
  5697. static void
  5698. nds32_elf_analysis_relax_hint (void)
  5699. {
  5700. hash_traverse (nds32_hint_hash, nds32_elf_append_relax_relocs);
  5701. }
  5702. static void
  5703. nds32_elf_insert_final_frag (void)
  5704. {
  5705. struct frchain *frchainP;
  5706. asection *s;
  5707. fragS *fragP;
  5708. if (!optimize)
  5709. return;
  5710. for (s = stdoutput->sections; s; s = s->next)
  5711. {
  5712. segment_info_type *seginfo = seg_info (s);
  5713. if (!seginfo)
  5714. continue;
  5715. for (frchainP = seginfo->frchainP; frchainP != NULL;
  5716. frchainP = frchainP->frch_next)
  5717. {
  5718. subseg_set (s, frchainP->frch_subseg);
  5719. if (subseg_text_p (now_seg))
  5720. {
  5721. fragP = frag_now;
  5722. frag_var (rs_machine_dependent, 2, /* Max size. */
  5723. 0, /* VAR is un-used. */ 0, NULL, 0, NULL);
  5724. fragP->tc_frag_data.flag |= NDS32_FRAG_FINAL;
  5725. }
  5726. }
  5727. }
  5728. }
  5729. void
  5730. md_end (void)
  5731. {
  5732. nds32_elf_insert_final_frag ();
  5733. nds32_elf_analysis_relax_hint ();
  5734. bfd_map_over_sections (stdoutput, nds32_insert_leb128_fixes, NULL);
  5735. }
  5736. /* Implement md_allow_local_subtract. */
  5737. bfd_boolean
  5738. nds32_allow_local_subtract (expressionS *expr_l ATTRIBUTE_UNUSED,
  5739. expressionS *expr_r ATTRIBUTE_UNUSED,
  5740. segT sec ATTRIBUTE_UNUSED)
  5741. {
  5742. /* Don't allow any subtraction, because relax may change the code. */
  5743. return FALSE;
  5744. }
  5745. /* Sort relocation by address.
  5746. We didn't use qsort () in stdlib, because quick-sort is not a stable
  5747. sorting algorithm. Relocations at the same address (r_offset) must keep
  5748. their relative order. For example, RELAX_ENTRY must be the very first
  5749. relocation entry.
  5750. Currently, this function implements insertion-sort. */
  5751. static int
  5752. compar_relent (const void *lhs, const void *rhs)
  5753. {
  5754. const arelent **l = (const arelent **) lhs;
  5755. const arelent **r = (const arelent **) rhs;
  5756. if ((*l)->address > (*r)->address)
  5757. return 1;
  5758. else if ((*l)->address == (*r)->address)
  5759. return 0;
  5760. else
  5761. return -1;
  5762. }
  5763. /* SET_SECTION_RELOCS ()
  5764. Although this macro is originally used to set a relocation for each section,
  5765. we use it to sort relocations in the same section by the address of the
  5766. relocation. */
  5767. void
  5768. nds32_set_section_relocs (asection *sec, arelent ** relocs ATTRIBUTE_UNUSED,
  5769. unsigned int n ATTRIBUTE_UNUSED)
  5770. {
  5771. bfd *abfd ATTRIBUTE_UNUSED = sec->owner;
  5772. if (bfd_get_section_flags (abfd, sec) & (flagword) SEC_RELOC)
  5773. nds32_insertion_sort (sec->orelocation, sec->reloc_count,
  5774. sizeof (arelent**), compar_relent);
  5775. }
  5776. long
  5777. nds32_pcrel_from_section (fixS *fixP, segT sec ATTRIBUTE_UNUSED)
  5778. {
  5779. if (fixP->fx_addsy == NULL || !S_IS_DEFINED (fixP->fx_addsy)
  5780. || S_IS_EXTERNAL (fixP->fx_addsy) || S_IS_WEAK (fixP->fx_addsy))
  5781. {
  5782. /* Let linker resolve undefined symbols. */
  5783. return 0;
  5784. }
  5785. return fixP->fx_frag->fr_address + fixP->fx_where;
  5786. }
  5787. /* md_post_relax_hook ()
  5788. Insert relax entry relocation into sections. */
  5789. void
  5790. nds32_post_relax_hook (void)
  5791. {
  5792. bfd_map_over_sections (stdoutput, nds32_insert_relax_entry, NULL);
  5793. }
  5794. /* tc_fix_adjustable ()
  5795. Return whether this symbol (fixup) can be replaced with
  5796. section symbols. */
  5797. bfd_boolean
  5798. nds32_fix_adjustable (fixS *fixP)
  5799. {
  5800. switch (fixP->fx_r_type)
  5801. {
  5802. case BFD_RELOC_NDS32_WORD_9_PCREL:
  5803. case BFD_RELOC_NDS32_9_PCREL:
  5804. case BFD_RELOC_NDS32_15_PCREL:
  5805. case BFD_RELOC_NDS32_17_PCREL:
  5806. case BFD_RELOC_NDS32_25_PCREL:
  5807. case BFD_RELOC_NDS32_HI20:
  5808. case BFD_RELOC_NDS32_LO12S0:
  5809. case BFD_RELOC_8:
  5810. case BFD_RELOC_16:
  5811. case BFD_RELOC_32:
  5812. case BFD_RELOC_NDS32_PTR:
  5813. case BFD_RELOC_NDS32_LONGCALL4:
  5814. case BFD_RELOC_NDS32_LONGCALL5:
  5815. case BFD_RELOC_NDS32_LONGCALL6:
  5816. case BFD_RELOC_NDS32_LONGJUMP4:
  5817. case BFD_RELOC_NDS32_LONGJUMP5:
  5818. case BFD_RELOC_NDS32_LONGJUMP6:
  5819. case BFD_RELOC_NDS32_LONGJUMP7:
  5820. return 1;
  5821. default:
  5822. return 0;
  5823. }
  5824. }
  5825. /* elf_tc_final_processing */
  5826. void
  5827. elf_nds32_final_processing (void)
  5828. {
  5829. /* An FPU_COM instruction is found without previous non-FPU_COM
  5830. instruction. */
  5831. if (nds32_fpu_com
  5832. && !(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
  5833. {
  5834. /* Since only FPU_COM instructions are used and no other FPU instructions
  5835. are used. The nds32_elf_flags will be decided by the enabled options
  5836. by command line or default configuration. */
  5837. if (nds32_fpu_dp_ext || nds32_fpu_sp_ext)
  5838. {
  5839. nds32_elf_flags |= nds32_fpu_dp_ext ? E_NDS32_HAS_FPU_DP_INST : 0;
  5840. nds32_elf_flags |= nds32_fpu_sp_ext ? E_NDS32_HAS_FPU_INST : 0;
  5841. }
  5842. else
  5843. {
  5844. /* Should never here. */
  5845. as_bad (_("Used FPU instructions requires enabling FPU extension"));
  5846. }
  5847. }
  5848. if (nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST))
  5849. {
  5850. /* Single/double FPU has been used, set FPU register config. */
  5851. /* We did not check the actual number of register used. We may
  5852. want to do it while assemble. */
  5853. nds32_elf_flags &= ~E_NDS32_FPU_REG_CONF;
  5854. nds32_elf_flags |= (nds32_freg << E_NDS32_FPU_REG_CONF_SHIFT);
  5855. }
  5856. if (nds32_pic)
  5857. nds32_elf_flags |= E_NDS32_HAS_PIC;
  5858. if (nds32_gpr16)
  5859. nds32_elf_flags |= E_NDS32_HAS_REDUCED_REGS;
  5860. nds32_elf_flags |= (E_NDS32_ELF_VER_1_4 | nds32_abi);
  5861. elf_elfheader (stdoutput)->e_flags |= nds32_elf_flags;
  5862. }
  5863. /* Implement md_apply_fix. Apply the fix-up or tranform the fix-up for
  5864. later relocation generation. */
  5865. void
  5866. nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
  5867. {
  5868. char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
  5869. bfd_vma value = *valP;
  5870. if (fixP->fx_r_type < BFD_RELOC_UNUSED
  5871. && fixP->fx_r_type > BFD_RELOC_NONE
  5872. && fixP->fx_r_type != BFD_RELOC_NDS32_DIFF_ULEB128)
  5873. {
  5874. /* In our old nds32 binutils, it must convert relocations which is
  5875. generated by CGEN. However, it does not have to consider this anymore.
  5876. In current, it only deal with data relocations which enum
  5877. is smaller than BFD_RELOC_NONE and BFD_RELOC_NDS32_DIFF_ULEB128.
  5878. It is believed that we can construct a better mechanism to
  5879. deal with the whole relocation issue in nds32 target
  5880. without using CGEN. */
  5881. fixP->fx_addnumber = value;
  5882. fixP->tc_fix_data = NULL;
  5883. /* Tranform specific relocations here for later relocation generation.
  5884. Tag data here for ex9 relaxtion and tag tls data for linker. */
  5885. switch (fixP->fx_r_type)
  5886. {
  5887. case BFD_RELOC_NDS32_DATA:
  5888. if (!enable_relax_ex9)
  5889. fixP->fx_done = 1;
  5890. break;
  5891. case BFD_RELOC_NDS32_TPOFF:
  5892. case BFD_RELOC_NDS32_TLS_LE_HI20:
  5893. case BFD_RELOC_NDS32_TLS_LE_LO12:
  5894. case BFD_RELOC_NDS32_TLS_LE_ADD:
  5895. case BFD_RELOC_NDS32_TLS_LE_LS:
  5896. case BFD_RELOC_NDS32_GOTTPOFF:
  5897. case BFD_RELOC_NDS32_TLS_IE_HI20:
  5898. case BFD_RELOC_NDS32_TLS_IE_LO12S2:
  5899. S_SET_THREAD_LOCAL (fixP->fx_addsy);
  5900. break;
  5901. default:
  5902. break;
  5903. }
  5904. return;
  5905. }
  5906. if (fixP->fx_addsy == (symbolS *) NULL)
  5907. fixP->fx_done = 1;
  5908. if (fixP->fx_subsy != (symbolS *) NULL)
  5909. {
  5910. /* HOW DIFF RELOCATION WORKS.
  5911. First of all, this relocation is used to calculate the distance
  5912. between two symbols in the SAME section. It is used for jump-
  5913. table, debug information, exception table, et al. Therefore,
  5914. it is a unsigned positive value. It is NOT used for general-
  5915. purpose arithmetic.
  5916. Consider this example, the distance between .LEND and .LBEGIN
  5917. is stored at the address of foo.
  5918. ---- >8 ---- >8 ---- >8 ---- >8 ----
  5919. .data
  5920. foo:
  5921. .word .LBEGIN - .LEND
  5922. .text
  5923. [before]
  5924. .LBEGIN
  5925. \
  5926. [between] distance
  5927. /
  5928. .LEND
  5929. [after]
  5930. ---- 8< ---- 8< ---- 8< ---- 8< ----
  5931. We use a single relocation entry for this expression.
  5932. * The initial distance value is stored direcly in that location
  5933. specified by r_offset (i.e., foo in this example.)
  5934. * The begin of the region, i.e., .LBEGIN, is specified by
  5935. r_info/R_SYM and r_addend, e.g., .text + 0x32.
  5936. * The end of region, i.e., .LEND, is represented by
  5937. .LBEGIN + distance instead of .LEND, so we only need
  5938. a single relocation entry instead of two.
  5939. When an instruction is relaxed, we adjust the relocation entry
  5940. depending on where the instruction locates. There are three
  5941. cases, before, after and between the region.
  5942. * between: Distance value is read from r_offset, adjusted and
  5943. written back into r_offset.
  5944. * before: Only r_addend is adjust.
  5945. * after: We don't care about it.
  5946. Hereby, there are some limitation.
  5947. `(.LEND - 1) - .LBEGIN' and `(.LEND - .LBEGIN) - 1'
  5948. are semantically different, and we cannot handle latter case
  5949. when relaxation.
  5950. The latter expression means subtracting 1 from the distance
  5951. between .LEND and .LBEGIN. And the former expression means
  5952. the distance between (.LEND - 1) and .LBEGIN.
  5953. The nuance affects whether to adjust distance value when relax
  5954. an instruction. In another words, whether the instruction
  5955. locates in the region. Because we use a single relocation entry,
  5956. there is no field left for .LEND and the subtrahend.
  5957. Since GCC-4.5, GCC may produce debug information in such expression
  5958. .long .L1-1-.L0
  5959. in order to describe register clobbering during an function-call.
  5960. .L0:
  5961. call foo
  5962. .L1:
  5963. Check http://gcc.gnu.org/ml/gcc-patches/2009-06/msg01317.html
  5964. for details. */
  5965. value -= S_GET_VALUE (fixP->fx_subsy);
  5966. *valP = value;
  5967. fixP->fx_subsy = NULL;
  5968. fixP->fx_offset -= value;
  5969. switch (fixP->fx_r_type)
  5970. {
  5971. case BFD_RELOC_8:
  5972. fixP->fx_r_type = BFD_RELOC_NDS32_DIFF8;
  5973. md_number_to_chars (where, value, 1);
  5974. break;
  5975. case BFD_RELOC_16:
  5976. fixP->fx_r_type = BFD_RELOC_NDS32_DIFF16;
  5977. md_number_to_chars (where, value, 2);
  5978. break;
  5979. case BFD_RELOC_32:
  5980. fixP->fx_r_type = BFD_RELOC_NDS32_DIFF32;
  5981. md_number_to_chars (where, value, 4);
  5982. break;
  5983. case BFD_RELOC_NDS32_DIFF_ULEB128:
  5984. /* cvt_frag_to_fill () has called output_leb128 () for us. */
  5985. break;
  5986. default:
  5987. as_bad_where (fixP->fx_file, fixP->fx_line,
  5988. _("expression too complex"));
  5989. return;
  5990. }
  5991. }
  5992. else if (fixP->fx_done)
  5993. {
  5994. /* We're finished with this fixup. Install it because
  5995. bfd_install_relocation won't be called to do it. */
  5996. switch (fixP->fx_r_type)
  5997. {
  5998. case BFD_RELOC_8:
  5999. md_number_to_chars (where, value, 1);
  6000. break;
  6001. case BFD_RELOC_16:
  6002. md_number_to_chars (where, value, 2);
  6003. break;
  6004. case BFD_RELOC_32:
  6005. md_number_to_chars (where, value, 4);
  6006. break;
  6007. case BFD_RELOC_64:
  6008. md_number_to_chars (where, value, 8);
  6009. default:
  6010. as_bad_where (fixP->fx_file, fixP->fx_line,
  6011. _("Internal error: Unknown fixup type %d (`%s')"),
  6012. fixP->fx_r_type,
  6013. bfd_get_reloc_code_name (fixP->fx_r_type));
  6014. break;
  6015. }
  6016. }
  6017. }
  6018. /* Implement tc_gen_reloc. Generate ELF relocation for a fix-up. */
  6019. arelent *
  6020. tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
  6021. {
  6022. arelent *reloc;
  6023. bfd_reloc_code_real_type code;
  6024. reloc = (arelent *) xmalloc (sizeof (arelent));
  6025. reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
  6026. *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
  6027. reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
  6028. code = fixP->fx_r_type;
  6029. reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
  6030. if (reloc->howto == (reloc_howto_type *) NULL)
  6031. {
  6032. as_bad_where (fixP->fx_file, fixP->fx_line,
  6033. _("internal error: can't export reloc type %d (`%s')"),
  6034. fixP->fx_r_type, bfd_get_reloc_code_name (code));
  6035. return NULL;
  6036. }
  6037. /* Add relocation handling here. */
  6038. switch (fixP->fx_r_type)
  6039. {
  6040. default:
  6041. /* In general, addend of a relocation is the offset to the
  6042. associated symbol. */
  6043. reloc->addend = fixP->fx_offset;
  6044. break;
  6045. case BFD_RELOC_NDS32_DATA:
  6046. /* Prevent linker from optimizing data in text sections.
  6047. For example, jump table. */
  6048. reloc->addend = fixP->fx_size;
  6049. break;
  6050. }
  6051. return reloc;
  6052. }
  6053. struct suffix_name suffix_table[] =
  6054. {
  6055. {"GOTOFF", BFD_RELOC_NDS32_GOTOFF, 1},
  6056. {"GOT", BFD_RELOC_NDS32_GOT20, 1},
  6057. {"TPOFF", BFD_RELOC_NDS32_TPOFF, 0},
  6058. {"PLT", BFD_RELOC_NDS32_25_PLTREL, 1},
  6059. {"GOTTPOFF", BFD_RELOC_NDS32_GOTTPOFF, 0}
  6060. };
  6061. /* Implement md_parse_name. */
  6062. int
  6063. nds32_parse_name (char const *name, expressionS *exprP,
  6064. enum expr_mode mode ATTRIBUTE_UNUSED,
  6065. char *nextcharP ATTRIBUTE_UNUSED)
  6066. {
  6067. segT segment;
  6068. exprP->X_op_symbol = NULL;
  6069. exprP->X_md = BFD_RELOC_UNUSED;
  6070. exprP->X_add_symbol = symbol_find_or_make (name);
  6071. exprP->X_op = O_symbol;
  6072. exprP->X_add_number = 0;
  6073. /* Check the specail name if a symbol. */
  6074. segment = S_GET_SEGMENT (exprP->X_add_symbol);
  6075. if (segment != undefined_section)
  6076. return 0;
  6077. if (strcmp (name, GOT_NAME) == 0 && *nextcharP != '@')
  6078. {
  6079. /* Set for _GOT_OFFSET_TABLE_. */
  6080. exprP->X_md = BFD_RELOC_NDS32_GOTPC20;
  6081. }
  6082. else if (*nextcharP == '@')
  6083. {
  6084. size_t i;
  6085. char *next;
  6086. for (i = 0; i < ARRAY_SIZE (suffix_table); i++)
  6087. {
  6088. next = input_line_pointer + 1 + strlen(suffix_table[i].suffix);
  6089. if (strncasecmp (input_line_pointer + 1, suffix_table[i].suffix,
  6090. strlen (suffix_table[i].suffix)) == 0
  6091. && !is_part_of_name (*next))
  6092. {
  6093. if (!nds32_pic && suffix_table[i].pic)
  6094. as_bad (_("need PIC qualifier with symbol."));
  6095. exprP->X_md = suffix_table[i].reloc;
  6096. *input_line_pointer = *nextcharP;
  6097. input_line_pointer = next;
  6098. *nextcharP = *input_line_pointer;
  6099. *input_line_pointer = '\0';
  6100. break;
  6101. }
  6102. }
  6103. }
  6104. return 1;
  6105. }
  6106. /* Implement tc_regname_to_dw2regnum. */
  6107. int
  6108. tc_nds32_regname_to_dw2regnum (char *regname)
  6109. {
  6110. struct nds32_keyword *sym = hash_find (nds32_gprs_hash, regname);
  6111. if (!sym)
  6112. return -1;
  6113. return sym->value;
  6114. }
  6115. void
  6116. tc_nds32_frame_initial_instructions (void)
  6117. {
  6118. /* CIE */
  6119. /* Default cfa is register-31/sp. */
  6120. cfi_add_CFA_def_cfa (31, 0);
  6121. }