1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978 |
- diff --git a/bfd/Makefile.am b/bfd/Makefile.am
- index 435b30b..488c4ab 100644
- --- a/bfd/Makefile.am
- +++ b/bfd/Makefile.am
- @@ -92,6 +92,7 @@ ALL_MACHINES = \
- cpu-maxq.lo \
- cpu-mcore.lo \
- cpu-mips.lo \
- + cpu-nios2.lo \
- cpu-mmix.lo \
- cpu-mt.lo \
- cpu-msp430.lo \
- @@ -156,6 +157,7 @@ ALL_MACHINES_CFILES = \
- cpu-maxq.c \
- cpu-mcore.c \
- cpu-mips.c \
- + cpu-nios2.c \
- cpu-mmix.c \
- cpu-mt.c \
- cpu-msp430.c \
- @@ -270,6 +272,7 @@ BFD32_BACKENDS = \
- elf32-mips.lo \
- elf32-mt.lo \
- elf32-msp430.lo \
- + elf32-nios2.lo \
- elf32-openrisc.lo \
- elf32-or32.lo \
- elf32-pj.lo \
- @@ -446,6 +449,7 @@ BFD32_BACKENDS_CFILES = \
- elf32-mips.c \
- elf32-mt.c \
- elf32-msp430.c \
- + elf32-nios2.c \
- elf32-openrisc.c \
- elf32-or32.c \
- elf32-pj.c \
- @@ -1065,6 +1069,7 @@ cpu-m10300.lo: cpu-m10300.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- cpu-maxq.lo: cpu-maxq.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- cpu-mcore.lo: cpu-mcore.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- cpu-mips.lo: cpu-mips.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- +cpu-nios2.lo: cpu-nios2.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- cpu-mmix.lo: cpu-mmix.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- cpu-mt.lo: cpu-mt.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- cpu-msp430.lo: cpu-msp430.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- @@ -1428,6 +1433,10 @@ elf32-msp430.lo: elf32-msp430.c $(INCDIR)/filenames.h \
- $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
- $(INCDIR)/bfdlink.h $(INCDIR)/elf/msp430.h $(INCDIR)/elf/reloc-macros.h \
- elf32-target.h
- +elf32-nios2.lo: elf32-nios2.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
- + genlink.h elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
- + $(INCDIR)/elf/external.h $(INCDIR)/elf/nios2.h \
- + $(INCDIR)/elf/reloc-macros.h elf32-target.h
- elf32-openrisc.lo: elf32-openrisc.c $(INCDIR)/filenames.h \
- $(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
- $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
- diff --git a/bfd/Makefile.in b/bfd/Makefile.in
- index 5bde689..5e57321 100644
- --- a/bfd/Makefile.in
- +++ b/bfd/Makefile.in
- @@ -327,6 +327,7 @@ ALL_MACHINES = \
- cpu-mt.lo \
- cpu-msp430.lo \
- cpu-or32.lo \
- + cpu-nios2.lo \
- cpu-ns32k.lo \
- cpu-openrisc.lo \
- cpu-pdp11.lo \
- @@ -391,6 +392,7 @@ ALL_MACHINES_CFILES = \
- cpu-mt.c \
- cpu-msp430.c \
- cpu-or32.c \
- + cpu-nios2.c \
- cpu-ns32k.c \
- cpu-openrisc.c \
- cpu-pdp11.c \
- @@ -502,6 +504,7 @@ BFD32_BACKENDS = \
- elf32-mips.lo \
- elf32-mt.lo \
- elf32-msp430.lo \
- + elf32-nios2.lo \
- elf32-openrisc.lo \
- elf32-or32.lo \
- elf32-pj.lo \
- @@ -678,6 +681,7 @@ BFD32_BACKENDS_CFILES = \
- elf32-mips.c \
- elf32-mt.c \
- elf32-msp430.c \
- + elf32-nios2.c \
- elf32-openrisc.c \
- elf32-or32.c \
- elf32-pj.c \
- @@ -1626,6 +1630,7 @@ cpu-m10300.lo: cpu-m10300.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- cpu-maxq.lo: cpu-maxq.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- cpu-mcore.lo: cpu-mcore.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- cpu-mips.lo: cpu-mips.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- +cpu-nios2.lo: cpu-nios2.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- cpu-mmix.lo: cpu-mmix.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- cpu-mt.lo: cpu-mt.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- cpu-msp430.lo: cpu-msp430.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
- @@ -1989,6 +1994,10 @@ elf32-msp430.lo: elf32-msp430.c $(INCDIR)/filenames.h \
- $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
- $(INCDIR)/bfdlink.h $(INCDIR)/elf/msp430.h $(INCDIR)/elf/reloc-macros.h \
- elf32-target.h
- +elf32-nios2.lo: elf32-nios2.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
- + genlink.h elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
- + $(INCDIR)/elf/external.h $(INCDIR)/elf/nios2.h \
- + $(INCDIR)/elf/reloc-macros.h elf32-target.h
- elf32-openrisc.lo: elf32-openrisc.c $(INCDIR)/filenames.h \
- $(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
- $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
- diff --git a/bfd/archures.c b/bfd/archures.c
- index 5029cb0..ece60b4 100644
- --- a/bfd/archures.c
- +++ b/bfd/archures.c
- @@ -381,6 +381,8 @@ DESCRIPTION
- . bfd_arch_maxq, {* Dallas MAXQ 10/20 *}
- .#define bfd_mach_maxq10 10
- .#define bfd_mach_maxq20 20
- +. bfd_arch_nios2,
- +.#define bfd_mach_nios2 1
- . bfd_arch_z80,
- .#define bfd_mach_z80strict 1 {* No undocumented opcodes. *}
- .#define bfd_mach_z80 3 {* With ixl, ixh, iyl, and iyh. *}
- @@ -462,6 +464,7 @@ extern const bfd_arch_info_type bfd_mn10300_arch;
- extern const bfd_arch_info_type bfd_msp430_arch;
- extern const bfd_arch_info_type bfd_mt_arch;
- extern const bfd_arch_info_type bfd_ns32k_arch;
- +extern const bfd_arch_info_type bfd_nios2_arch;
- extern const bfd_arch_info_type bfd_openrisc_arch;
- extern const bfd_arch_info_type bfd_or32_arch;
- extern const bfd_arch_info_type bfd_pdp11_arch;
- @@ -530,6 +533,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] =
- &bfd_mn10300_arch,
- &bfd_mt_arch,
- &bfd_msp430_arch,
- + &bfd_nios2_arch,
- &bfd_ns32k_arch,
- &bfd_openrisc_arch,
- &bfd_or32_arch,
- diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
- index 8f2af8b..f5c51d6 100644
- --- a/bfd/bfd-in2.h
- +++ b/bfd/bfd-in2.h
- @@ -2010,6 +2010,8 @@ enum bfd_architecture
- bfd_arch_maxq, /* Dallas MAXQ 10/20 */
- #define bfd_mach_maxq10 10
- #define bfd_mach_maxq20 20
- + bfd_arch_nios2,
- +#define bfd_mach_nios2 1
- bfd_arch_z80,
- #define bfd_mach_z80strict 1 /* No undocumented opcodes. */
- #define bfd_mach_z80 3 /* With ixl, ixh, iyl, and iyh. */
- @@ -4271,6 +4273,23 @@ internally by the linker after analysis of a
- BFD_RELOC_XTENSA_ASM_EXPAND. */
- BFD_RELOC_XTENSA_ASM_SIMPLIFY,
-
- +/* Relocations used by the Altera New Jersey core */
- + BFD_RELOC_NIOS2_S16,
- + BFD_RELOC_NIOS2_U16,
- + BFD_RELOC_NIOS2_CALL26,
- + BFD_RELOC_NIOS2_IMM5,
- + BFD_RELOC_NIOS2_CACHE_OPX,
- + BFD_RELOC_NIOS2_IMM6,
- + BFD_RELOC_NIOS2_IMM8,
- + BFD_RELOC_NIOS2_HI16,
- + BFD_RELOC_NIOS2_LO16,
- + BFD_RELOC_NIOS2_HIADJ16,
- + BFD_RELOC_NIOS2_GPREL,
- + BFD_RELOC_NIOS2_UJMP,
- + BFD_RELOC_NIOS2_CJMP,
- + BFD_RELOC_NIOS2_CALLR,
- + BFD_RELOC_NIOS2_ALIGN,
- +
- /* 8 bit signed offset in (ix+d) or (iy+d). */
- BFD_RELOC_Z80_DISP8,
-
- diff --git a/bfd/config.bfd b/bfd/config.bfd
- old mode 100755
- new mode 100644
- index 9b81db7..fa86103
- --- a/bfd/config.bfd
- +++ b/bfd/config.bfd
- @@ -88,6 +88,7 @@ m68*) targ_archs=bfd_m68k_arch ;;
- m88*) targ_archs=bfd_m88k_arch ;;
- maxq*) targ_archs=bfd_maxq_arch ;;
- mips*) targ_archs=bfd_mips_arch ;;
- +nios2*) targ_archs=bfd_nios2_arch ;;
- or32*) targ_archs=bfd_or32_arch ;;
- pdp11*) targ_archs=bfd_pdp11_arch ;;
- pj*) targ_archs="bfd_pj_arch bfd_i386_arch";;
- @@ -985,6 +986,21 @@ case "${targ}" in
- targ_underscore=yes
- ;;
-
- + nios2eb-*-*)
- + targ_defvec=bfd_elf32_bignios2_vec
- + targ_selvecs=bfd_elf32_littlenios2_vec
- + ;;
- +
- + nios2el-*-*)
- + targ_defvec=bfd_elf32_littlenios2_vec
- + targ_selvecs=bfd_elf32_bignios2_vec
- + ;;
- +
- + nios2-*-*)
- + targ_defvec=bfd_elf32_littlenios2_vec
- + targ_selvecs=bfd_elf32_bignios2_vec
- + ;;
- +
- openrisc-*-elf)
- targ_defvec=bfd_elf32_openrisc_vec
- ;;
- diff --git a/bfd/configure b/bfd/configure
- index bc138ff..a64fef5 100755
- --- a/bfd/configure
- +++ b/bfd/configure
- @@ -10846,6 +10846,8 @@ do
- bfd_elf32_littlemips_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
- bfd_elf32_littlemips_vxworks_vec)
- tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
- + bfd_elf32_littlenios2_vec) tb="$tb elf32-nios2.lo elf32.lo $elf" ;;
- + bfd_elf32_bignios2_vec) tb="$tb elf32-nios2.lo elf32.lo $elf" ;;
- bfd_elf32_m32c_vec) tb="$tb elf32-m32c.lo elf32.lo $elf" ;;
- bfd_elf32_m32r_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
- bfd_elf32_m32rle_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
- diff --git a/bfd/configure.in b/bfd/configure.in
- index fa0d50f..eb1e5f6 100644
- --- a/bfd/configure.in
- +++ b/bfd/configure.in
- @@ -655,6 +655,8 @@ do
- bfd_elf32_nlittlemips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
- bfd_elf32_ntradbigmips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
- bfd_elf32_ntradlittlemips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
- + bfd_elf32_littlenios2_vec) tb="$tb elf32-nios2.lo elf32.lo $elf" ;;
- + bfd_elf32_bignios2_vec) tb="$tb elf32-nios2.lo elf32.lo $elf" ;;
- bfd_elf32_openrisc_vec) tb="$tb elf32-openrisc.lo elf32.lo $elf" ;;
- bfd_elf32_or32_big_vec) tb="$tb elf32-or32.lo elf32.lo $elf" ;;
- bfd_elf32_pj_vec) tb="$tb elf32-pj.lo elf32.lo $elf";;
- diff --git a/bfd/cpu-nios2.c b/bfd/cpu-nios2.c
- new file mode 100644
- index 0000000..c8f39c9
- --- /dev/null
- +++ b/bfd/cpu-nios2.c
- @@ -0,0 +1,70 @@
- +/* bfd back-end for Altera Nios II support
- +
- + Copyright (C) 2003
- + by Nigel Gray (ngray@altera.com).
- +
- +This file is part of BFD, the Binary File Descriptor library.
- +
- +This program is free software; you can redistribute it and/or modify
- +it under the terms of the GNU General Public License as published by
- +the Free Software Foundation; either version 2 of the License, or
- +(at your option) any later version.
- +
- +This program is distributed in the hope that it will be useful,
- +but WITHOUT ANY WARRANTY; without even the implied warranty of
- +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- +GNU General Public License for more details.
- +
- +You should have received a copy of the GNU General Public License
- +along with this program; if not, write to the Free Software
- +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
- +
- +#include "bfd.h"
- +#include "sysdep.h"
- +#include "libbfd.h"
- +
- +static const bfd_arch_info_type *nios2_compatible
- + (const bfd_arch_info_type *, const bfd_arch_info_type *);
- +
- +/* The default routine tests bits_per_word, which is wrong on mips as
- + mips word size doesn't correlate with reloc size. */
- +
- +static const bfd_arch_info_type *
- +nios2_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
- +{
- + if (a->arch != b->arch)
- + return NULL;
- +
- + /* Machine compatibility is checked in
- + _bfd_mips_elf_merge_private_bfd_data. */
- +
- + return a;
- +}
- +
- +#define N(BITS_WORD, BITS_ADDR, NUMBER, PRINT, DEFAULT, NEXT) \
- + { \
- + BITS_WORD, /* bits in a word */ \
- + BITS_ADDR, /* bits in an address */ \
- + 8, /* 8 bits in a byte */ \
- + bfd_arch_nios2, \
- + NUMBER, \
- + "nios2", \
- + PRINT, \
- + 3, \
- + DEFAULT, \
- + nios2_compatible, \
- + bfd_default_scan, \
- + NEXT, \
- + }
- +
- +#define NN(index) (&arch_info_struct[(index) + 1])
- +
- +static const bfd_arch_info_type arch_info_struct[] =
- +{
- + N (32, 32, bfd_mach_nios2, "nios2", FALSE, 0),
- +};
- +
- +/* There is only one architecture - but we give the default a machine number of 0
- + so the linker can distinguish it */
- +const bfd_arch_info_type bfd_nios2_arch =
- +N (32, 32, 0, "nios2", TRUE, &arch_info_struct[0]);
- diff --git a/bfd/elf32-nios2.c b/bfd/elf32-nios2.c
- new file mode 100644
- index 0000000..f9ba1a0
- --- /dev/null
- +++ b/bfd/elf32-nios2.c
- @@ -0,0 +1,2193 @@
- +/* New Jersey-specific support for 32-bit ELF
- +
- + Copyright (C) 2003
- + by Nigel Gray (ngray@altera.com).
- +
- +
- +This file is part of BFD, the Binary File Descriptor library.
- +
- +This program is free software; you can redistribute it and/or modify
- +it under the terms of the GNU General Public License as published by
- +the Free Software Foundation; either version 2 of the License, or
- +(at your option) any later version.
- +
- +This program is distributed in the hope that it will be useful,
- +but WITHOUT ANY WARRANTY; without even the implied warranty of
- +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- +GNU General Public License for more details.
- +
- +You should have received a copy of the GNU General Public License
- +along with this program; if not, write to the Free Software
- +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
- +
- +/* This file handles Altera New Jersey ELF targets */
- +
- +#include "bfd.h"
- +#include "sysdep.h"
- +#include "libbfd.h"
- +#include "bfdlink.h"
- +#include "genlink.h"
- +#include "elf-bfd.h"
- +#include "elf/nios2.h"
- +#include "opcode/nios2.h"
- +
- +/* use RELA relocations*/
- +#ifndef USE_RELA
- +#define USE_RELA
- +#endif
- +
- +#ifdef USE_REL
- +#undef USE_REL
- +#endif
- +
- +/* Function prototypes */
- +
- +static reloc_howto_type *nios2_elf32_bfd_reloc_type_lookup
- + (bfd *, bfd_reloc_code_real_type);
- +
- +static bfd_boolean nios2_elf32_relax_section
- + (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
- +
- +static bfd_boolean nios2_elf32_relax_delete_bytes
- + (bfd *, asection *, bfd_vma, int);
- +
- +static reloc_howto_type *nios2_elf32_rtype_to_howto
- + (unsigned int r_type, bfd_boolean rela_p);
- +
- +static void nios2_elf32_info_to_howto
- + (bfd * abfd, arelent * cache_ptr, Elf_Internal_Rela * dst);
- +
- +static bfd_boolean nios2_elf32_relocate_section
- + (bfd * output_bfd, struct bfd_link_info * info, bfd * input_bfd,
- + asection * input_section, bfd_byte * contents,
- + Elf_Internal_Rela * relocs, Elf_Internal_Sym * local_syms,
- + asection ** local_sections);
- +
- +static reloc_howto_type *lookup_howto (unsigned int rtype);
- +
- +static bfd_reloc_status_type nios2_elf_final_gp
- + (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *,
- + struct bfd_link_info *);
- +
- +static bfd_boolean nios2_elf_assign_gp
- + (bfd *, bfd_vma *, struct bfd_link_info *);
- +
- +static bfd_reloc_status_type nios2_elf32_ignore_reloc
- + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
- +
- +static bfd_reloc_status_type nios2_elf32_hi16_relocate
- + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
- +
- +static bfd_reloc_status_type nios2_elf32_lo16_relocate
- + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
- +
- +static bfd_reloc_status_type nios2_elf32_hiadj16_relocate
- + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
- +
- +static bfd_reloc_status_type nios2_elf32_pcrel16_relocate
- + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
- +
- +static bfd_reloc_status_type nios2_elf32_call26_relocate
- + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
- +
- +static bfd_reloc_status_type nios2_elf32_gprel_relocate
- + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
- +
- +static bfd_reloc_status_type nios2_elf32_ujmp_relocate
- + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
- +
- +static bfd_reloc_status_type nios2_elf32_cjmp_relocate
- + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
- +
- +static bfd_reloc_status_type nios2_elf32_callr_relocate
- + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
- +
- +static bfd_reloc_status_type nios2_elf32_do_hi16_relocate
- + (bfd *, reloc_howto_type *, asection *,
- + bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
- +
- +static bfd_reloc_status_type nios2_elf32_do_lo16_relocate
- + (bfd *, reloc_howto_type *, asection *,
- + bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
- +
- +static bfd_reloc_status_type nios2_elf32_do_hiadj16_relocate
- + (bfd *, reloc_howto_type *, asection *,
- + bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
- +
- +static bfd_reloc_status_type nios2_elf32_do_pcrel16_relocate
- + (bfd *, reloc_howto_type *, asection *,
- + bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
- +
- +static bfd_reloc_status_type nios2_elf32_do_call26_relocate
- + (bfd *, reloc_howto_type *, asection *,
- + bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
- +
- +static bfd_reloc_status_type nios2_elf32_do_gprel_relocate
- + (bfd *, reloc_howto_type *, asection *,
- + bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
- +
- +static bfd_reloc_status_type nios2_elf32_do_ujmp_relocate
- + (bfd *, reloc_howto_type *, asection *,
- + bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
- +
- +static bfd_reloc_status_type nios2_elf32_do_cjmp_relocate
- + (bfd *, reloc_howto_type *, asection *,
- + bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
- +
- +static bfd_reloc_status_type nios2_elf32_do_callr_relocate
- + (bfd *, reloc_howto_type *, asection *,
- + bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
- +
- +
- +static void nios2_elf32_post_process_headers
- + (bfd *, struct bfd_link_info *);
- +
- +static bfd_boolean nios2_elf32_section_from_shdr
- + (bfd *, Elf_Internal_Shdr *, const char *name, int shindex);
- +
- +static bfd_boolean nios2_elf32_section_flags
- + (flagword *, const Elf_Internal_Shdr *);
- +
- +static bfd_boolean nios2_elf32_fake_sections
- + (bfd *, Elf_Internal_Shdr *, asection *);
- +
- +
- +
- +static bfd_boolean nios2_elf32_check_relocs
- + (bfd *, struct bfd_link_info *, asection *,
- + const Elf_Internal_Rela *);
- +
- +static asection *nios2_elf32_gc_mark_hook (asection * sec,
- + struct bfd_link_info *
- + info,
- + Elf_Internal_Rela * rel,
- + struct elf_link_hash_entry
- + * h,
- + Elf_Internal_Sym * sym);
- +
- +
- +/* target vector */
- +extern const bfd_target bfd_elf32_littlenios2_vec;
- +extern const bfd_target bfd_elf32_bignios2_vec;
- +
- +/* The relocation table used for SHT_REL sections. */
- +
- +static reloc_howto_type elf_nios2_howto_table_rel[] = {
- + /* No relocation. */
- + HOWTO (R_NIOS2_NONE, /* type */
- + 0, /* rightshift */
- + 0, /* size (0 = byte, 1 = short, 2 = long) */
- + 0, /* bitsize */
- + FALSE, /* pc_relative */
- + 0, /* bitpos */
- + complain_overflow_dont, /* complain_on_overflow */
- + bfd_elf_generic_reloc, /* special_function */
- + "R_NIOS2_NONE", /* name */
- + FALSE, /* partial_inplace */
- + 0, /* src_mask */
- + 0, /* dst_mask */
- + FALSE), /* pcrel_offset */
- +
- + /* 16-bit signed immediate relocation */
- + HOWTO (R_NIOS2_S16, /* type */
- + 0, /* rightshift */
- + 2, /* size (0 = byte, 1 = short, 2 = long) */
- + 16, /* bitsize */
- + FALSE, /* pc_relative */
- + 6, /* bitpos */
- + complain_overflow_signed, /* complain on overflow */
- + bfd_elf_generic_reloc, /* special function */
- + "R_NIOS2_S16", /* name */
- + FALSE, /* partial_inplace */
- + 0x003fffc0, /* src_mask */
- + 0x003fffc0, /* dest_mask */
- + FALSE), /* pcrel_offset */
- +
- + /* 16-bit unsigned immediate relocation */
- + HOWTO (R_NIOS2_U16, /* type */
- + 0, /* rightshift */
- + 2, /* size (0 = byte, 1 = short, 2 = long) */
- + 16, /* bitsize */
- + FALSE, /* pc_relative */
- + 6, /* bitpos */
- + complain_overflow_unsigned, /* complain on overflow */
- + bfd_elf_generic_reloc, /* special function */
- + "R_NIOS2_U16", /* name */
- + FALSE, /* partial_inplace */
- + 0x003fffc0, /* src_mask */
- + 0x003fffc0, /* dest_mask */
- + FALSE), /* pcrel_offset */
- +
- + HOWTO (R_NIOS2_PCREL16, /* type */
- + 0, /* rightshift */
- + 2, /* size (0 = byte, 1 = short, 2 = long) */
- + 16, /* bitsize */
- + TRUE, /* pc_relative */
- + 6, /* bitpos */
- + complain_overflow_signed, /* complain on overflow */
- + nios2_elf32_pcrel16_relocate, /* special function */
- + "R_NIOS2_PCREL16", /* name */
- + FALSE, /* partial_inplace */
- + 0x003fffc0, /* src_mask */
- + 0x003fffc0, /* dest_mask */
- + TRUE), /* pcrel_offset */
- +
- + HOWTO (R_NIOS2_CALL26, /* type */
- + 2, /* rightshift */
- + 2, /* size (0 = byte, 1 = short, 2 = long) */
- + 26, /* bitsize */
- + FALSE, /* pc_relative */
- + 6, /* bitpos */
- + complain_overflow_dont, /* complain on overflow */
- + nios2_elf32_call26_relocate, /* special function */
- + "R_NIOS2_CALL26", /* name */
- + FALSE, /* partial_inplace */
- + 0xffffffc0, /* src_mask */
- + 0xffffffc0, /* dst_mask */
- + FALSE), /* pcrel_offset */
- +
- + HOWTO (R_NIOS2_IMM5,
- + 0,
- + 2,
- + 5,
- + FALSE,
- + 6,
- + complain_overflow_bitfield,
- + bfd_elf_generic_reloc,
- + "R_NIOS2_IMM5",
- + FALSE,
- + 0x000007c0,
- + 0x000007c0,
- + FALSE),
- +
- + HOWTO (R_NIOS2_CACHE_OPX,
- + 0,
- + 2,
- + 5,
- + FALSE,
- + 22,
- + complain_overflow_bitfield,
- + bfd_elf_generic_reloc,
- + "R_NIOS2_CACHE_OPX",
- + FALSE,
- + 0x07c00000,
- + 0x07c00000,
- + FALSE),
- +
- + HOWTO (R_NIOS2_IMM6,
- + 0,
- + 2,
- + 6,
- + FALSE,
- + 6,
- + complain_overflow_bitfield,
- + bfd_elf_generic_reloc,
- + "R_NIOS2_IMM6",
- + FALSE,
- + 0x00000fc0,
- + 0x00000fc0,
- + FALSE),
- +
- + HOWTO (R_NIOS2_IMM8,
- + 0,
- + 2,
- + 8,
- + FALSE,
- + 6,
- + complain_overflow_bitfield,
- + bfd_elf_generic_reloc,
- + "R_NIOS2_IMM8",
- + FALSE,
- + 0x00003fc0,
- + 0x00003fc0,
- + FALSE),
- +
- + HOWTO (R_NIOS2_HI16,
- + 0,
- + 2,
- + 32,
- + FALSE,
- + 6,
- + complain_overflow_dont,
- + nios2_elf32_hi16_relocate,
- + "R_NIOS2_HI16",
- + FALSE,
- + 0x003fffc0,
- + 0x003fffc0,
- + FALSE),
- +
- + HOWTO (R_NIOS2_LO16,
- + 0,
- + 2,
- + 32,
- + FALSE,
- + 6,
- + complain_overflow_dont,
- + nios2_elf32_lo16_relocate,
- + "R_NIOS2_LO16",
- + FALSE,
- + 0x003fffc0,
- + 0x003fffc0,
- + FALSE),
- +
- + HOWTO (R_NIOS2_HIADJ16,
- + 0,
- + 2,
- + 32,
- + FALSE,
- + 6,
- + complain_overflow_dont,
- + nios2_elf32_hiadj16_relocate,
- + "R_NIOS2_HIADJ16",
- + FALSE,
- + 0x003fffc0,
- + 0x003fffc0,
- + FALSE),
- +
- + HOWTO (R_NIOS2_BFD_RELOC_32,
- + 0,
- + 2, /* long */
- + 32,
- + FALSE,
- + 0,
- + complain_overflow_dont,
- + bfd_elf_generic_reloc,
- + "R_NIOS2_BFD_RELOC32",
- + FALSE,
- + 0xffffffff,
- + 0xffffffff,
- + FALSE),
- +
- + HOWTO (R_NIOS2_BFD_RELOC_16,
- + 0,
- + 1, /* short */
- + 16,
- + FALSE,
- + 0,
- + complain_overflow_bitfield,
- + bfd_elf_generic_reloc,
- + "R_NIOS2_BFD_RELOC16",
- + FALSE,
- + 0x0000ffff,
- + 0x0000ffff,
- + FALSE),
- +
- + HOWTO (R_NIOS2_BFD_RELOC_8,
- + 0,
- + 0, /* byte */
- + 8,
- + FALSE,
- + 0,
- + complain_overflow_bitfield,
- + bfd_elf_generic_reloc,
- + "R_NIOS2_BFD_RELOC8",
- + FALSE,
- + 0x000000ff,
- + 0x000000ff,
- + FALSE),
- +
- + HOWTO (R_NIOS2_GPREL,
- + 0,
- + 2,
- + 32,
- + FALSE,
- + 6,
- + complain_overflow_dont,
- + nios2_elf32_gprel_relocate,
- + "R_NIOS2_GPREL",
- + FALSE,
- + 0x003fffc0,
- + 0x003fffc0,
- + FALSE),
- +
- + HOWTO (R_NIOS2_GNU_VTINHERIT,
- + 0,
- + 2, /* short */
- + 0,
- + FALSE,
- + 0,
- + complain_overflow_dont,
- + NULL,
- + "R_NIOS2_GNU_VTINHERIT",
- + FALSE,
- + 0,
- + 0,
- + FALSE),
- +
- + HOWTO (R_NIOS2_GNU_VTENTRY,
- + 0,
- + 2, /* byte */
- + 0,
- + FALSE,
- + 0,
- + complain_overflow_dont,
- + _bfd_elf_rel_vtable_reloc_fn,
- + "R_NIOS2_GNU_VTENTRY",
- + FALSE,
- + 0,
- + 0,
- + FALSE),
- +
- + HOWTO (R_NIOS2_UJMP,
- + 0,
- + 2,
- + 32,
- + FALSE,
- + 6,
- + complain_overflow_dont,
- + nios2_elf32_ujmp_relocate,
- + "R_NIOS2_UJMP",
- + FALSE,
- + 0x003fffc0,
- + 0x003fffc0,
- + FALSE),
- +
- + HOWTO (R_NIOS2_CJMP,
- + 0,
- + 2,
- + 32,
- + FALSE,
- + 6,
- + complain_overflow_dont,
- + nios2_elf32_cjmp_relocate,
- + "R_NIOS2_CJMP",
- + FALSE,
- + 0x003fffc0,
- + 0x003fffc0,
- + FALSE),
- +
- + HOWTO (R_NIOS2_CALLR,
- + 0,
- + 2,
- + 32,
- + FALSE,
- + 6,
- + complain_overflow_dont,
- + nios2_elf32_callr_relocate,
- + "R_NIOS2_CALLR",
- + FALSE,
- + 0x003fffc0,
- + 0x003fffc0,
- + FALSE),
- +
- + HOWTO (R_NIOS2_ALIGN,
- + 0,
- + 2,
- + 0,
- + FALSE,
- + 0,
- + complain_overflow_dont,
- + nios2_elf32_ignore_reloc,
- + "R_NIOS2_ALIGN",
- + FALSE,
- + 0,
- + 0,
- + TRUE),
- +
- +/* add other relocations here */
- +};
- +
- +static unsigned char elf_code_to_howto_index[R_NIOS2_ILLEGAL + 1];
- +
- +static reloc_howto_type *
- +lookup_howto (unsigned int rtype)
- +{
- + static int initialized = 0;
- + int i;
- + int howto_tbl_size = (int) (sizeof (elf_nios2_howto_table_rel)
- + / sizeof (elf_nios2_howto_table_rel[0]));
- +
- + if (!initialized)
- + {
- + initialized = 1;
- + memset (elf_code_to_howto_index, 0xff,
- + sizeof (elf_code_to_howto_index));
- + for (i = 0; i < howto_tbl_size; i++)
- + elf_code_to_howto_index[elf_nios2_howto_table_rel[i].type] = i;
- + }
- +
- + BFD_ASSERT (rtype <= R_NIOS2_ILLEGAL);
- + i = elf_code_to_howto_index[rtype];
- + if (i >= howto_tbl_size)
- + return 0;
- + return elf_nios2_howto_table_rel + i;
- +}
- +
- +/*
- + map for converting BFD reloc types to New Jersey
- + reloc types
- + */
- +struct elf_reloc_map
- +{
- + bfd_reloc_code_real_type bfd_val;
- + enum elf_nios2_reloc_type elf_val;
- +};
- +
- +static const struct elf_reloc_map nios2_reloc_map[] = {
- + {BFD_RELOC_NIOS2_S16, R_NIOS2_S16},
- + {BFD_RELOC_NIOS2_U16, R_NIOS2_U16},
- + {BFD_RELOC_16_PCREL, R_NIOS2_PCREL16},
- + {BFD_RELOC_NIOS2_CALL26, R_NIOS2_CALL26},
- + {BFD_RELOC_NIOS2_IMM5, R_NIOS2_IMM5},
- + {BFD_RELOC_NIOS2_CACHE_OPX, R_NIOS2_CACHE_OPX},
- + {BFD_RELOC_NIOS2_IMM6, R_NIOS2_IMM6},
- + {BFD_RELOC_NIOS2_IMM8, R_NIOS2_IMM8},
- + {BFD_RELOC_NIOS2_HI16, R_NIOS2_HI16},
- + {BFD_RELOC_NIOS2_LO16, R_NIOS2_LO16},
- + {BFD_RELOC_NIOS2_HIADJ16, R_NIOS2_HIADJ16},
- + {BFD_RELOC_32, R_NIOS2_BFD_RELOC_32},
- + {BFD_RELOC_16, R_NIOS2_BFD_RELOC_16},
- + {BFD_RELOC_8, R_NIOS2_BFD_RELOC_8},
- + {BFD_RELOC_NIOS2_GPREL, R_NIOS2_GPREL},
- + {BFD_RELOC_VTABLE_INHERIT, R_NIOS2_GNU_VTINHERIT},
- + {BFD_RELOC_VTABLE_ENTRY, R_NIOS2_GNU_VTENTRY},
- + {BFD_RELOC_NIOS2_UJMP, R_NIOS2_UJMP},
- + {BFD_RELOC_NIOS2_CJMP, R_NIOS2_CJMP},
- + {BFD_RELOC_NIOS2_CALLR, R_NIOS2_CALLR},
- + {BFD_RELOC_NIOS2_ALIGN, R_NIOS2_ALIGN},
- +};
- +
- +/* Given a BFD reloc type, return a howto structure. */
- +
- +static reloc_howto_type *
- +nios2_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
- + bfd_reloc_code_real_type code)
- +{
- + int i;
- + for (i = 0;
- + i < (int) (sizeof (nios2_reloc_map) / sizeof (struct elf_reloc_map));
- + ++i)
- + {
- + if (nios2_reloc_map[i].bfd_val == code)
- + return &elf_nios2_howto_table_rel[(int) nios2_reloc_map[i].elf_val];
- + }
- +
- + return NULL;
- +}
- +
- +/* Helper function for nios2_elf32_info_to_howto */
- +
- +static reloc_howto_type *
- +nios2_elf32_rtype_to_howto (unsigned int r_type,
- + bfd_boolean rela_p ATTRIBUTE_UNUSED)
- +{
- + BFD_ASSERT (r_type < R_NIOS2_ILLEGAL);
- + return &elf_nios2_howto_table_rel[r_type];
- +}
- +
- +/* Given a ELF32 relocation, fill in a arelent structure */
- +
- +static void
- +nios2_elf32_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, arelent * cache_ptr,
- + Elf_Internal_Rela * dst)
- +{
- + unsigned int r_type;
- +
- + r_type = ELF32_R_TYPE (dst->r_info);
- + cache_ptr->howto = nios2_elf32_rtype_to_howto (r_type, FALSE);
- +
- + // FIXME - do we need to do anything else here???
- +}
- +
- +/* The assembler has output long jmp/call sequences for all calls
- + * and pc-relative branches that it cannot guarantee are within
- + * range, so the linker must attempt to "relax" these sequences to
- + * short branches and calls if it can. Since we only relax in one
- + * direction - long to short - we don't need to see whether each
- + * relaxation invalidates any others
- + *
- + *
- + **/
- +static bfd_boolean
- +nios2_elf32_relax_section (bfd * abfd,
- + asection * sec,
- + struct bfd_link_info *link_info, bfd_boolean * again)
- +{
- + Elf_Internal_Shdr *symtab_hdr;
- + Elf_Internal_Rela *internal_relocs;
- + Elf_Internal_Rela *irel, *irelend;
- + bfd_byte *contents = NULL;
- + Elf_Internal_Sym *isymbuf = NULL;
- +
- + /* Assume nothing changes. */
- + *again = FALSE;
- +
- + /* We don't have to do anything for a relocatable link, if
- + this section does not have relocs, or if this is not a
- + code section. */
- + if (link_info->relocatable
- + || (sec->flags & SEC_RELOC) == 0
- + || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0)
- + return TRUE;
- +
- + /* If this is the first time we have been called for this section,
- + initialize the cooked size. */
- + if (sec->size == 0)
- + sec->size = sec->rawsize;
- +
- + symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- +
- + /* Get a copy of the native relocations. */
- + internal_relocs = (_bfd_elf_link_read_relocs
- + (abfd, sec, (void *) NULL, (Elf_Internal_Rela *) NULL,
- + link_info->keep_memory));
- + if (internal_relocs == NULL)
- + goto error_return;
- +
- + /* Walk through them looking for relaxing opportunities. */
- + irelend = internal_relocs + sec->reloc_count;
- + for (irel = internal_relocs; irel < irelend; irel++)
- + {
- + bfd_vma symval;
- +
- + /* If this isn't something that can be relaxed, then ignore
- + this reloc. */
- + if (ELF32_R_TYPE (irel->r_info) != (int) R_NIOS2_UJMP
- + && ELF32_R_TYPE (irel->r_info) != (int) R_NIOS2_CJMP
- + && ELF32_R_TYPE (irel->r_info) != (int) R_NIOS2_CALLR)
- + {
- + continue;
- + }
- +
- + /* Get the section contents if we haven't done so already. */
- + if (contents == NULL)
- + {
- + /* Get cached copy if it exists. */
- + if (elf_section_data (sec)->this_hdr.contents != NULL)
- + contents = elf_section_data (sec)->this_hdr.contents;
- + else
- + {
- + /* Go get them off disk. */
- + contents = (bfd_byte *) bfd_malloc (sec->rawsize);
- + if (contents == NULL)
- + goto error_return;
- +
- + if (!bfd_get_section_contents (abfd, sec, contents,
- + (file_ptr) 0, sec->rawsize))
- + goto error_return;
- + }
- + }
- +
- + /* Read this BFD's local symbols if we haven't done so already. */
- + if (isymbuf == NULL && symtab_hdr->sh_info != 0)
- + {
- + isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
- + if (isymbuf == NULL)
- + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
- + symtab_hdr->sh_info, 0,
- + NULL, NULL, NULL);
- + if (isymbuf == NULL)
- + goto error_return;
- + }
- +
- + /* Get the value of the symbol referred to by the reloc. */
- + if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
- + {
- + /* A local symbol. */
- + Elf_Internal_Sym *isym;
- + asection *sym_sec;
- +
- + isym = isymbuf + ELF32_R_SYM (irel->r_info);
- + if (isym->st_shndx == SHN_UNDEF)
- + sym_sec = bfd_und_section_ptr;
- + else if (isym->st_shndx == SHN_ABS)
- + sym_sec = bfd_abs_section_ptr;
- + else if (isym->st_shndx == SHN_COMMON)
- + sym_sec = bfd_com_section_ptr;
- + else
- + sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
- + symval = (isym->st_value
- + + sym_sec->output_section->vma + sym_sec->output_offset);
- + }
- + else
- + {
- + unsigned long indx;
- + struct elf_link_hash_entry *h;
- +
- + /* An external symbol. */
- + indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
- + h = elf_sym_hashes (abfd)[indx];
- + BFD_ASSERT (h != NULL);
- + if (h->root.type != bfd_link_hash_defined
- + && h->root.type != bfd_link_hash_defweak)
- + {
- + /* This appears to be a reference to an undefined
- + symbol. Just ignore it--it will be caught by the
- + regular reloc processing. */
- + continue;
- + }
- +
- + symval = (h->root.u.def.value
- + + h->root.u.def.section->output_section->vma
- + + h->root.u.def.section->output_offset);
- + }
- +
- + /* For simplicity of coding, we are going to modify the section
- + contents, the section relocs, and the BFD symbol table. We
- + must tell the rest of the code not to free up this
- + information. It would be possible to instead create a table
- + of changes which have to be made, as is done in coff-mips.c;
- + that would be more work, but would require less memory when
- + the linker is run. */
- +
- + /* try to turn :
- + * movhi at, %hi(symbol)
- + * movui at, %lo(symbol)
- + * callr at
- + * into:
- + * call symbol
- + */
- + if (ELF32_R_TYPE (irel->r_info) == (int) R_NIOS2_CALLR)
- + {
- + bfd_vma targ_addr = symval + irel->r_addend;
- + bfd_vma curr_addr = (sec->output_section->vma + sec->output_offset);
- + bfd_vma targ_page, curr_page;
- + targ_page = targ_addr & 0xf0000000;
- + curr_page = curr_addr & 0xf0000000;
- +
- + if (targ_page == curr_page)
- + {
- + /* change the opcode to a call */
- + bfd_put_32 (abfd, OP_MATCH_CALL, contents + irel->r_offset);
- + /* Note that we've changed the relocs, section contents, etc. */
- + elf_section_data (sec)->relocs = internal_relocs;
- + elf_section_data (sec)->this_hdr.contents = contents;
- + symtab_hdr->contents = (unsigned char *) isymbuf;
- +
- + /* Fix the relocation's type. */
- + irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
- + R_NIOS2_CALL26);
- +
- + /* delete the next two instructions */
- + if (!nios2_elf32_relax_delete_bytes (abfd, sec,
- + irel->r_offset + 4, 8))
- + goto error_return;
- +
- + /* NG FIXME - I'm putting this in for now, but I don't think we need it */
- + *again = TRUE;
- + }
- + }
- +
- + /* try to turn :
- + * movhi at, %hi(symbol)
- + * movui at, %lo(symbol)
- + * jmp at
- + * into:
- + * br symbol
- + */
- + if (ELF32_R_TYPE (irel->r_info) == (int) R_NIOS2_UJMP)
- + {
- + bfd_vma pcrel_offset;
- + Elf_Internal_Rela *irelalign = NULL;
- + Elf_Internal_Rela *irela = elf_section_data (sec)->relocs;
- + Elf_Internal_Rela *irelend = irel + sec->reloc_count;
- +
- + for (; irela < irelend; irela++)
- + {
- + if (ELF32_R_TYPE (irela->r_info) == (int) R_NIOS2_ALIGN
- + && irela->r_offset > irel->r_offset + 4
- + && 8 < (1 << irela->r_addend))
- + {
- + irelalign = irela;
- + break;
- + }
- + }
- +
- + /* calculate the pcrelative offset from current location */
- + pcrel_offset = symval;
- + pcrel_offset -= (sec->output_section->vma + sec->output_offset);
- + pcrel_offset += irel->r_addend;
- +
- + /* we need to compute the pcrel_offset from the next instruction */
- + pcrel_offset -= (irel->r_offset + 4);
- +
- + /* does this value fit in 16 bits */
- + if ((irelalign == NULL && (long) pcrel_offset <= 0x8004
- + && (long) pcrel_offset >= -0x8000) || (irelalign != NULL
- + && (long) pcrel_offset
- + <= 0x7ffc
- + && (long) pcrel_offset
- + >= -0x8000))
- + {
- + /* change the opcode to an unconditional branch */
- + bfd_put_32 (abfd, OP_MATCH_BR, contents + irel->r_offset);
- + /* Note that we've changed the relocs, section contents, etc. */
- + elf_section_data (sec)->relocs = internal_relocs;
- + elf_section_data (sec)->this_hdr.contents = contents;
- + symtab_hdr->contents = (unsigned char *) isymbuf;
- +
- + /* Fix the relocation's type. */
- + irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
- + R_NIOS2_PCREL16);
- +
- + /* delete the next two instructions */
- + if (!nios2_elf32_relax_delete_bytes (abfd, sec,
- + irel->r_offset + 4, 8))
- + goto error_return;
- +
- + /* NG FIXME - I'm putting this in for now, but I don't think we need it */
- + *again = TRUE;
- + }
- + }
- +
- + /* try to turn :
- + * b{cond} a, b skip
- + * movhi at, %hi(symbol)
- + * movui at, %lo(symbol)
- + * jmp at
- + * skip:
- + * ...
- + * into:
- + * br{opp_cond} a, b, symbol
- + */
- + if (ELF32_R_TYPE (irel->r_info) == (int) R_NIOS2_CJMP)
- + {
- + bfd_vma pcrel_offset;
- + Elf_Internal_Rela *irelalign = NULL;
- + Elf_Internal_Rela *irela = elf_section_data (sec)->relocs;
- + Elf_Internal_Rela *irelend = irel + sec->reloc_count;
- +
- + for (; irela < irelend; irela++)
- + {
- + if (ELF32_R_TYPE (irela->r_info) == (int) R_NIOS2_ALIGN
- + && irela->r_offset > irel->r_offset + 4
- + && 8 < (1 << irela->r_addend))
- + {
- + irelalign = irela;
- + break;
- + }
- + }
- +
- + /* calculate the pcrelative offset from current location */
- + pcrel_offset = symval;
- + pcrel_offset -= (sec->output_section->vma + sec->output_offset);
- + pcrel_offset += irel->r_addend;
- +
- + /* we need to compute the pcrel_offset from this instruction
- + * ie the movhi */
- + pcrel_offset -= (irel->r_offset);
- +
- + /* does this value fit in 16 bits */
- + if ((irelalign == NULL && (long) pcrel_offset <= 0x8008
- + && (long) pcrel_offset >= -0x8000) || (irelalign != NULL
- + && (long) pcrel_offset
- + <= 0x7ffc
- + && (long) pcrel_offset
- + >= -0x8000))
- + {
- + unsigned long opcode, op_a, op_b;
- + /* get the conditional branch opcode */
- + opcode = bfd_get_32 (abfd, contents + irel->r_offset - 4);
- + /* reverse the condition */
- + switch (opcode & OP_MASK_OP)
- + {
- + case OP_MATCH_BEQ:
- + opcode = (opcode & ~OP_MASK_OP) | OP_MATCH_BNE;
- + break;
- + case OP_MATCH_BNE:
- + opcode = (opcode & ~OP_MASK_OP) | OP_MATCH_BEQ;
- + break;
- + case OP_MATCH_BGE:
- + case OP_MATCH_BGEU:
- + case OP_MATCH_BLT:
- + case OP_MATCH_BLTU:
- + /* swap the operands */
- + op_a = (opcode & OP_MASK_RRT) << 5;
- + op_b = (opcode & OP_MASK_RRS) >> 5;
- + opcode =
- + (opcode & ~(OP_MASK_RRS | OP_MASK_RRT)) | op_a | op_b;
- + break;
- + default:
- + fprintf (stderr,
- + "relaxation error - expecting conditional branch, aborting\n");
- + abort ();
- + break;
- + }
- +
- + /* we must set the branch target to zero so that the skip over the jmp doesn't get
- + * added to the jmp */
- + opcode = opcode & (~OP_MASK_IMM16);
- +
- + /* change the opcode to the reversed conditional branch */
- + bfd_put_32 (abfd, opcode, contents + irel->r_offset - 4);
- + /* Note that we've changed the relocs, section contents, etc. */
- + elf_section_data (sec)->relocs = internal_relocs;
- + elf_section_data (sec)->this_hdr.contents = contents;
- + symtab_hdr->contents = (unsigned char *) isymbuf;
- +
- + /* Fix the relocation's type. */
- + irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
- + R_NIOS2_PCREL16);
- +
- + /* this relocation's offset has also been reduced by 4 bytes */
- + irel->r_offset -= 4;
- +
- + /* delete the next three instructions */
- + if (!nios2_elf32_relax_delete_bytes (abfd, sec,
- + irel->r_offset + 4, 12))
- + goto error_return;
- +
- + /* NG FIXME - I'm putting this in for now, but I don't think we need it */
- + *again = TRUE;
- + }
- + }
- +
- + /* otherwise, leave alone */
- + }
- +
- + if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
- + {
- + if (!link_info->keep_memory)
- + free (isymbuf);
- + else
- + {
- + /* Cache the symbols for elf_link_input_bfd. */
- + symtab_hdr->contents = (unsigned char *) isymbuf;
- + }
- + }
- +
- + if (contents != NULL
- + && elf_section_data (sec)->this_hdr.contents != contents)
- + {
- + if (!link_info->keep_memory)
- + free (contents);
- + else
- + {
- + /* Cache the section contents for elf_link_input_bfd. */
- + elf_section_data (sec)->this_hdr.contents = contents;
- + }
- + }
- +
- + if (internal_relocs != NULL
- + && elf_section_data (sec)->relocs != internal_relocs)
- + free (internal_relocs);
- +
- +
- + return TRUE;
- +
- +error_return:
- + if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
- + free (isymbuf);
- + if (contents != NULL
- + && elf_section_data (sec)->this_hdr.contents != contents)
- + free (contents);
- + if (internal_relocs != NULL
- + && elf_section_data (sec)->relocs != internal_relocs)
- + free (internal_relocs);
- +
- + return FALSE;
- +}
- +
- +/* Delete some bytes from a section while relaxing.
- + * Copied from mn10200 port */
- +
- +static bfd_boolean
- +nios2_elf32_relax_delete_bytes (bfd * abfd,
- + asection * sec, bfd_vma addr, int count)
- +{
- + Elf_Internal_Shdr *symtab_hdr;
- + unsigned int sec_shndx;
- + bfd_byte *contents;
- + Elf_Internal_Rela *irel, *irelend;
- + Elf_Internal_Rela *irelalign;
- + bfd_vma toaddr;
- + Elf_Internal_Sym *isym;
- + Elf_Internal_Sym *isymend;
- + struct elf_link_hash_entry **sym_hashes;
- + struct elf_link_hash_entry **end_hashes;
- + unsigned int symcount;
- + asection *asec;
- +
- + sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
- +
- + contents = elf_section_data (sec)->this_hdr.contents;
- +
- + /* The deletion must stop at the next ALIGN reloc for an aligment
- + power larger than the number of bytes we are deleting. */
- +
- + irelalign = NULL;
- + /* +1 because we need to readjust symbols at end of section */
- + toaddr = sec->size + 1;
- +
- + irel = elf_section_data (sec)->relocs;
- + irelend = irel + sec->reloc_count;
- +
- + for (; irel < irelend; irel++)
- + {
- + if (ELF32_R_TYPE (irel->r_info) == (int) R_NIOS2_ALIGN
- + && irel->r_offset > addr && count < (1 << irel->r_addend))
- + {
- + irelalign = irel;
- + /* +1 because we need to readjust symbols at end of section */
- + toaddr = irel->r_offset + 1;
- + break;
- + }
- + }
- +
- +
- + /* Actually delete the bytes. */
- + memmove (contents + addr, contents + addr + count,
- + (size_t) ((toaddr - 1) - addr - count));
- +
- + if (irelalign == NULL)
- + sec->size -= count;
- + else
- + {
- + int i;
- +
- +#define NOP_OPCODE (0x0001883a)
- +
- + BFD_ASSERT ((count & 3) == 0);
- + for (i = 0; i < count; i += 4)
- + bfd_put_32 (abfd, (bfd_vma) NOP_OPCODE,
- + contents + (toaddr - 1) - count + i);
- + }
- +
- + /* get the symbol table */
- + symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- + isym = (Elf_Internal_Sym *) symtab_hdr->contents;
- +
- + /* Adjust all the reloc offsets in this section. */
- + for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
- + {
- + /* Get the new reloc address. */
- + if ((irel->r_offset > addr && irel->r_offset < toaddr))
- + irel->r_offset -= count;
- + }
- +
- + /* Adjust relocations against targets in this section whose positions
- + * have moved as a result of the relaxation */
- +
- + for (asec = abfd->sections; asec; asec = asec->next)
- + {
- + irelend = elf_section_data (asec)->relocs + asec->reloc_count;
- + for (irel = elf_section_data (asec)->relocs; irel < irelend; irel++)
- + {
- + Elf_Internal_Sym *sym;
- + /* if the symbol which this reloc is against doesn't change
- + * we need to change the reloc addend */
- +
- + sym = isym + ELF32_R_SYM (irel->r_info);
- + if (sym->st_shndx == sec_shndx
- + && !(sym->st_value > addr && sym->st_value < toaddr)
- + && sym->st_value + irel->r_addend > addr
- + && sym->st_value + irel->r_addend < toaddr)
- + {
- + irel->r_addend -= count;
- + }
- +
- + }
- + }
- +
- + /* Adjust the local symbols defined in this section. */
- + for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
- + {
- + if (isym->st_shndx == sec_shndx
- + && isym->st_value > addr && isym->st_value < toaddr)
- + isym->st_value -= count;
- +
- +
- + }
- +
- + /* Now adjust the global symbols defined in this section. */
- + symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
- + - symtab_hdr->sh_info);
- + sym_hashes = elf_sym_hashes (abfd);
- + end_hashes = sym_hashes + symcount;
- + for (; sym_hashes < end_hashes; sym_hashes++)
- + {
- + struct elf_link_hash_entry *sym_hash = *sym_hashes;
- + if ((sym_hash->root.type == bfd_link_hash_defined
- + || sym_hash->root.type == bfd_link_hash_defweak)
- + && sym_hash->root.u.def.section == sec
- + && sym_hash->root.u.def.value > addr
- + && sym_hash->root.u.def.value < toaddr)
- + {
- + sym_hash->root.u.def.value -= count;
- + }
- + }
- +
- + return TRUE;
- +}
- +
- +struct bfd_link_info *nios2_link_info = NULL;
- +
- +/*
- +void
- +_bfd_set_link_info (info)
- + struct bfd_link_info *info;
- +{
- + nios2_link_info = info;
- +}
- +*/
- +
- +bfd_boolean linker_force_make_executable = FALSE;
- +
- +/*
- +void
- +_bfd_set_force_make_executable (force)
- + bfd_boolean force;
- +{
- + linker_force_make_executable = force;
- +}
- +*/
- +
- +/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
- + dangerous relocation. */
- +
- +static bfd_boolean
- +nios2_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp, struct bfd_link_info *info)
- +{
- +
- + bfd_boolean gp_found;
- + struct bfd_hash_entry *h;
- + struct bfd_link_hash_entry *lh;
- +
- + /* If we've already figured out what GP will be, just return it. */
- + *pgp = _bfd_get_gp_value (output_bfd);
- + if (*pgp)
- + return TRUE;
- +
- + h = bfd_hash_lookup (&info->hash->table, "_gp", FALSE, FALSE);
- + lh = (struct bfd_link_hash_entry *) h;
- +lookup:
- + if (lh)
- + {
- + switch (lh->type)
- + {
- + case bfd_link_hash_undefined:
- + case bfd_link_hash_undefweak:
- + case bfd_link_hash_common:
- + gp_found = FALSE;
- + break;
- + case bfd_link_hash_defined:
- + case bfd_link_hash_defweak:
- + gp_found = TRUE;
- + *pgp = lh->u.def.value;
- + break;
- + case bfd_link_hash_indirect:
- + case bfd_link_hash_warning:
- + lh = lh->u.i.link;
- + /* @@FIXME ignoring warning for now */
- + goto lookup;
- + case bfd_link_hash_new:
- + default:
- + abort ();
- + }
- + }
- + else
- + gp_found = FALSE;
- +
- + if (!gp_found)
- + {
- + /* Only get the error once. */
- + *pgp = 4;
- + _bfd_set_gp_value (output_bfd, *pgp);
- + return FALSE;
- + }
- +
- + _bfd_set_gp_value (output_bfd, *pgp);
- +
- + return TRUE;
- +}
- +
- +/* We have to figure out the gp value, so that we can adjust the
- + symbol value correctly. We look up the symbol _gp in the output
- + BFD. If we can't find it, we're stuck. We cache it in the ELF
- + target data. We don't need to adjust the symbol value for an
- + external symbol if we are producing relocatable output. */
- +
- +static bfd_reloc_status_type
- +nios2_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
- + char **error_message, bfd_vma *pgp, struct bfd_link_info *info)
- +{
- + if (bfd_is_und_section (symbol->section) && !relocatable)
- + {
- + *pgp = 0;
- + return bfd_reloc_undefined;
- + }
- +
- + *pgp = _bfd_get_gp_value (output_bfd);
- + if (*pgp == 0 && (!relocatable || (symbol->flags & BSF_SECTION_SYM) != 0))
- + {
- + /* if this is called without link_info, then
- + we cannot be doing a final link */
- + if (info == NULL)
- + relocatable = TRUE;
- +
- + if (relocatable)
- + {
- + /* Make up a value. */
- + *pgp = symbol->section->output_section->vma + 0x4000;
- + _bfd_set_gp_value (output_bfd, *pgp);
- + }
- + else if (!nios2_elf_assign_gp (output_bfd, pgp, info))
- + {
- + *error_message =
- + (char *)
- + _("global pointer relative relocation when _gp not defined");
- + return bfd_reloc_dangerous;
- + }
- + }
- +
- + return bfd_reloc_ok;
- +}
- +
- +
- +/* Relocations that require special handling */
- +
- +/* This is for relocations used only when relaxing to ensure
- + * changes in size of section don't screw up .align */
- +static bfd_reloc_status_type
- +nios2_elf32_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
- + asymbol *symbol ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED,
- + asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
- +{
- + if (output_bfd != NULL)
- + reloc_entry->address += input_section->output_offset;
- + return bfd_reloc_ok;
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_hi16_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol, void *data,
- + asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
- +{
- + /* This part is from bfd_elf_generic_reloc. */
- + if (output_bfd != (bfd *) NULL
- + && (symbol->flags & BSF_SECTION_SYM) == 0
- + && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
- + {
- + reloc_entry->address += input_section->output_offset;
- + return bfd_reloc_ok;
- + }
- +
- + if (output_bfd != NULL)
- + /* FIXME: See bfd_perform_relocation. Is this right? */
- + return bfd_reloc_ok;
- +
- + return nios2_elf32_do_hi16_relocate (abfd, reloc_entry->howto,
- + input_section,
- + data, reloc_entry->address,
- + (symbol->value
- + + symbol->section->output_section->vma
- + + symbol->section->output_offset),
- + reloc_entry->addend);
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_lo16_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
- + void *data, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
- +{
- +/* This part is from bfd_elf_generic_reloc. */
- + if (output_bfd != (bfd *) NULL
- + && (symbol->flags & BSF_SECTION_SYM) == 0
- + && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
- + {
- + reloc_entry->address += input_section->output_offset;
- + return bfd_reloc_ok;
- + }
- +
- + if (output_bfd != NULL)
- + /* FIXME: See bfd_perform_relocation. Is this right? */
- + return bfd_reloc_ok;
- +
- + return nios2_elf32_do_lo16_relocate (abfd, reloc_entry->howto,
- + input_section,
- + data, reloc_entry->address,
- + (symbol->value
- + + symbol->section->output_section->vma
- + + symbol->section->output_offset),
- + reloc_entry->addend);
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_hiadj16_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
- + void *data, asection *input_section, bfd *output_bfd,
- + char **error_message ATTRIBUTE_UNUSED)
- +{
- +/* This part is from bfd_elf_generic_reloc. */
- + if (output_bfd != (bfd *) NULL
- + && (symbol->flags & BSF_SECTION_SYM) == 0
- + && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
- + {
- + reloc_entry->address += input_section->output_offset;
- + return bfd_reloc_ok;
- + }
- +
- + if (output_bfd != NULL)
- + /* FIXME: See bfd_perform_relocation. Is this right? */
- + return bfd_reloc_ok;
- +
- + return nios2_elf32_do_hiadj16_relocate (abfd, reloc_entry->howto,
- + input_section,
- + data, reloc_entry->address,
- + (symbol->value
- + +
- + symbol->section->output_section->
- + vma +
- + symbol->section->output_offset),
- + reloc_entry->addend);
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_pcrel16_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
- + void *data, asection *input_section, bfd *output_bfd,
- + char **error_message ATTRIBUTE_UNUSED)
- +{
- +/* This part is from bfd_elf_generic_reloc. */
- + if (output_bfd != (bfd *) NULL
- + && (symbol->flags & BSF_SECTION_SYM) == 0
- + && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
- + {
- + reloc_entry->address += input_section->output_offset;
- + return bfd_reloc_ok;
- + }
- +
- + if (output_bfd != NULL)
- + /* FIXME: See bfd_perform_relocation. Is this right? */
- + return bfd_reloc_ok;
- +
- + return nios2_elf32_do_pcrel16_relocate (abfd, reloc_entry->howto,
- + input_section,
- + data, reloc_entry->address,
- + (symbol->value
- + +
- + symbol->section->output_section->
- + vma +
- + symbol->section->output_offset),
- + reloc_entry->addend);
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_call26_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
- + void *data, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
- +{
- +/* This part is from bfd_elf_generic_reloc. */
- + if (output_bfd != (bfd *) NULL
- + && (symbol->flags & BSF_SECTION_SYM) == 0
- + && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
- + {
- + reloc_entry->address += input_section->output_offset;
- + return bfd_reloc_ok;
- + }
- +
- + if (output_bfd != NULL)
- + /* FIXME: See bfd_perform_relocation. Is this right? */
- + return bfd_reloc_ok;
- +
- + return nios2_elf32_do_call26_relocate (abfd, reloc_entry->howto,
- + input_section,
- + data, reloc_entry->address,
- + (symbol->value
- + +
- + symbol->section->output_section->
- + vma +
- + symbol->section->output_offset),
- + reloc_entry->addend);
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_gprel_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
- + void *data, asection *input_section, bfd *output_bfd, char **msg)
- +{
- + bfd_vma relocation;
- + bfd_vma gp;
- + bfd_reloc_status_type r;
- +
- +
- +/* This part is from bfd_elf_generic_reloc. */
- + if (output_bfd != (bfd *) NULL
- + && (symbol->flags & BSF_SECTION_SYM) == 0
- + && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
- + {
- + reloc_entry->address += input_section->output_offset;
- + return bfd_reloc_ok;
- + }
- +
- + if (output_bfd != NULL)
- + /* FIXME: See bfd_perform_relocation. Is this right? */
- + return bfd_reloc_ok;
- +
- + relocation = symbol->value
- + + symbol->section->output_section->vma + symbol->section->output_offset;
- +
- + if ((r =
- + nios2_elf_final_gp (abfd, symbol, FALSE, msg, &gp,
- + nios2_link_info)) == bfd_reloc_ok)
- + {
- + relocation = relocation + reloc_entry->addend - gp;
- + reloc_entry->addend = 0;
- + if ((signed) relocation < -32768 || (signed) relocation > 32767)
- + {
- + *msg = _("global pointer relative address out of range");
- + r = bfd_reloc_outofrange;
- + }
- + else
- + {
- + r = nios2_elf32_do_gprel_relocate (abfd, reloc_entry->howto,
- + input_section,
- + data, reloc_entry->address,
- + relocation, reloc_entry->addend);
- + }
- + }
- +
- + return r;
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_ujmp_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
- + void *data, asection *input_section, bfd *output_bfd, char **msg ATTRIBUTE_UNUSED)
- +{
- + /* This part is from bfd_elf_generic_reloc. */
- + if (output_bfd != (bfd *) NULL
- + && (symbol->flags & BSF_SECTION_SYM) == 0
- + && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
- + {
- + reloc_entry->address += input_section->output_offset;
- + return bfd_reloc_ok;
- + }
- +
- + if (output_bfd != NULL)
- + /* FIXME: See bfd_perform_relocation. Is this right? */
- + return bfd_reloc_ok;
- +
- + return nios2_elf32_do_ujmp_relocate (abfd, reloc_entry->howto,
- + input_section,
- + data, reloc_entry->address,
- + (symbol->value
- + + symbol->section->output_section->vma
- + + symbol->section->output_offset),
- + reloc_entry->addend);
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_cjmp_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
- + void *data, asection *input_section, bfd *output_bfd, char **msg ATTRIBUTE_UNUSED)
- +{
- + /* This part is from bfd_elf_generic_reloc. */
- + if (output_bfd != (bfd *) NULL
- + && (symbol->flags & BSF_SECTION_SYM) == 0
- + && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
- + {
- + reloc_entry->address += input_section->output_offset;
- + return bfd_reloc_ok;
- + }
- +
- + if (output_bfd != NULL)
- + /* FIXME: See bfd_perform_relocation. Is this right? */
- + return bfd_reloc_ok;
- +
- + return nios2_elf32_do_cjmp_relocate (abfd, reloc_entry->howto,
- + input_section,
- + data, reloc_entry->address,
- + (symbol->value
- + + symbol->section->output_section->vma
- + + symbol->section->output_offset),
- + reloc_entry->addend);
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_callr_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
- + void *data, asection *input_section, bfd *output_bfd, char **msg ATTRIBUTE_UNUSED)
- +{
- + /* This part is from bfd_elf_generic_reloc. */
- + if (output_bfd != (bfd *) NULL
- + && (symbol->flags & BSF_SECTION_SYM) == 0
- + && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
- + {
- + reloc_entry->address += input_section->output_offset;
- + return bfd_reloc_ok;
- + }
- +
- + if (output_bfd != NULL)
- + /* FIXME: See bfd_perform_relocation. Is this right? */
- + return bfd_reloc_ok;
- +
- +
- + return nios2_elf32_do_callr_relocate (abfd, reloc_entry->howto,
- + input_section,
- + data, reloc_entry->address,
- + (symbol->value
- + +
- + symbol->section->output_section->
- + vma +
- + symbol->section->output_offset),
- + reloc_entry->addend);
- +}
- +
- +/* Do the relocations which require special handling */
- +
- +static bfd_reloc_status_type
- +nios2_elf32_do_hi16_relocate (bfd *abfd, reloc_howto_type *howto,
- + asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
- + bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
- +{
- + symbol_value = symbol_value + addend;
- + addend = 0;
- + symbol_value = (symbol_value >> 16) & 0xffff;
- + return _bfd_final_link_relocate (howto, abfd, input_section,
- + data, offset, symbol_value, addend);
- +}
- +
- +
- +static bfd_reloc_status_type
- +nios2_elf32_do_lo16_relocate (bfd *abfd, reloc_howto_type *howto,
- + asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
- + bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
- +{
- + symbol_value = symbol_value + addend;
- + addend = 0;
- + symbol_value = symbol_value & 0xffff;
- + return _bfd_final_link_relocate (howto, abfd, input_section,
- + data, offset, symbol_value, addend);
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_do_hiadj16_relocate (bfd *abfd, reloc_howto_type *howto,
- + asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data, bfd_vma offset,
- + bfd_vma symbol_value, bfd_vma addend)
- +{
- + symbol_value = symbol_value + addend;
- + addend = 0;
- + symbol_value =
- + ((symbol_value >> 16) & 0xffff) + ((symbol_value >> 15) & 0x01);
- + return _bfd_final_link_relocate (howto, abfd, input_section, data, offset,
- + symbol_value, addend);
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_do_pcrel16_relocate (bfd *abfd, reloc_howto_type *howto,
- + asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
- + bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
- +{
- + // NIOS2 pc relative relocations are relative to the next 32-bit instruction so we need
- + // to subtract 4 before doing a final_link_relocate
- + symbol_value = symbol_value + addend - 4;
- + addend = 0;
- + return _bfd_final_link_relocate (howto, abfd, input_section,
- + data, offset, symbol_value, addend);
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_do_call26_relocate (bfd *abfd, reloc_howto_type *howto,
- + asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
- + bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
- +{
- + /* check that the relocation is in the same page as the current address */
- + if (((symbol_value + addend) & 0xf0000000)
- + != ((input_section->output_section->vma + offset) & 0xf0000000))
- + return bfd_reloc_overflow;
- +
- + return _bfd_final_link_relocate (howto, abfd, input_section,
- + data, offset, symbol_value, addend);
- +}
- +
- +
- +static bfd_reloc_status_type
- +nios2_elf32_do_gprel_relocate (bfd *abfd, reloc_howto_type *howto,
- + asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
- + bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
- +{
- + // because we need the output_bfd, the special handling is done
- + // in nios2_elf32_relocate_section or in nios2_elf32_gprel_relocate
- + return _bfd_final_link_relocate (howto, abfd, input_section,
- + data, offset, symbol_value, addend);
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_do_ujmp_relocate (bfd *abfd, reloc_howto_type *howto,
- + asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
- + bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
- +{
- + bfd_vma symbol_lo16, symbol_hi16;
- + bfd_reloc_status_type r;
- + symbol_value = symbol_value + addend;
- + addend = 0;
- + symbol_hi16 = (symbol_value >> 16) & 0xffff;
- + symbol_lo16 = symbol_value & 0xffff;
- +
- + r = _bfd_final_link_relocate (howto, abfd, input_section,
- + data, offset, symbol_hi16, addend);
- +
- + if (r == bfd_reloc_ok)
- + return _bfd_final_link_relocate (howto, abfd, input_section,
- + data, offset + 4, symbol_lo16, addend);
- +
- + return r;
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_do_cjmp_relocate (bfd *abfd, reloc_howto_type *howto,
- + asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
- + bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
- +{
- + bfd_vma symbol_lo16, symbol_hi16;
- + bfd_reloc_status_type r;
- + symbol_value = symbol_value + addend;
- + addend = 0;
- + symbol_hi16 = (symbol_value >> 16) & 0xffff;
- + symbol_lo16 = symbol_value & 0xffff;
- +
- + r = _bfd_final_link_relocate (howto, abfd, input_section,
- + data, offset, symbol_hi16, addend);
- +
- + if (r == bfd_reloc_ok)
- + return _bfd_final_link_relocate (howto, abfd, input_section,
- + data, offset + 4, symbol_lo16, addend);
- +
- + return r;
- +}
- +
- +static bfd_reloc_status_type
- +nios2_elf32_do_callr_relocate (bfd *abfd, reloc_howto_type *howto,
- + asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
- + bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
- +{
- + bfd_vma symbol_lo16, symbol_hi16;
- + bfd_reloc_status_type r;
- + symbol_value = symbol_value + addend;
- + addend = 0;
- + symbol_hi16 = (symbol_value >> 16) & 0xffff;
- + symbol_lo16 = symbol_value & 0xffff;
- +
- + r = _bfd_final_link_relocate (howto, abfd, input_section,
- + data, offset, symbol_hi16, addend);
- +
- + if (r == bfd_reloc_ok)
- + return _bfd_final_link_relocate (howto, abfd, input_section,
- + data, offset + 4, symbol_lo16, addend);
- +
- + return r;
- +}
- +
- +/*
- + The function nios2_elf32_relocate_section is used by the linker
- + to perform relocations
- +*/
- +static bfd_boolean
- +nios2_elf32_relocate_section (bfd * output_bfd,
- + struct bfd_link_info *info,
- + bfd * input_bfd,
- + asection * input_section,
- + bfd_byte * contents,
- + Elf_Internal_Rela * relocs,
- + Elf_Internal_Sym * local_syms,
- + asection ** local_sections)
- +{
- + Elf_Internal_Shdr *symtab_hdr;
- + struct elf_link_hash_entry **sym_hashes;
- + Elf_Internal_Rela *rel;
- + Elf_Internal_Rela *relend;
- +
- + symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
- + sym_hashes = elf_sym_hashes (input_bfd);
- + relend = relocs + input_section->reloc_count;
- +
- +// size_t psymalloc = 0;
- +// _bfd_generic_link_output_symbols(output_bfd, input_bfd, info, &psymalloc);
- + for (rel = relocs; rel < relend; rel++)
- + {
- + reloc_howto_type *howto;
- + unsigned long r_symndx;
- + Elf_Internal_Sym *sym;
- + asection *sec;
- + struct elf_link_hash_entry *h;
- + bfd_vma relocation;
- + bfd_vma gp;
- + bfd_reloc_status_type r = bfd_reloc_ok;
- + const char *name = NULL;
- + int r_type;
- + const char *msg;
- +
- + msg = (const char *) NULL;
- +
- + r_type = ELF32_R_TYPE (rel->r_info);
- +
- + r_symndx = ELF32_R_SYM (rel->r_info);
- +
- + if (info->relocatable)
- + {
- + /* This is a relocatable link. We don't have to change
- + anything, unless the reloc is against a section symbol,
- + in which case we have to adjust according to where the
- + section symbol winds up in the output section. */
- + if (r_symndx < symtab_hdr->sh_info)
- + {
- + sym = local_syms + r_symndx;
- +
- + if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
- + {
- + sec = local_sections[r_symndx];
- + rel->r_addend += sec->output_offset + sym->st_value;
- + }
- + }
- + continue;
- + }
- +
- + /* This is a final link. */
- + howto = lookup_howto ((unsigned) ELF32_R_TYPE (rel->r_info));
- + h = NULL;
- + sym = NULL;
- + sec = NULL;
- +
- + if (r_symndx < symtab_hdr->sh_info)
- + {
- + sym = local_syms + r_symndx;
- + sec = local_sections[r_symndx];
- +
- + relocation = (sec->output_section->vma
- + + sec->output_offset + sym->st_value);
- +
- + // this ensures that relocations against duplicated symbols
- + // in merged sections that have been removed are fixed up against
- + // the remaining symbol and not the one that has been removed
- + if ((sec->flags & SEC_MERGE)
- + && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
- + {
- + rel->r_addend =
- + _bfd_elf_rel_local_sym (output_bfd, sym, &sec, rel->r_addend);
- + rel->r_addend -= relocation;
- + rel->r_addend += sec->output_section->vma + sec->output_offset;
- + }
- +
- + name = bfd_elf_string_from_elf_section
- + (input_bfd, symtab_hdr->sh_link, sym->st_name);
- +
- + name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
- + }
- + else
- + {
- + h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- +
- + while (h->root.type == bfd_link_hash_indirect
- + || h->root.type == bfd_link_hash_warning)
- + h = (struct elf_link_hash_entry *) h->root.u.i.link;
- +
- + name = h->root.root.string;
- +
- + if (h->root.type == bfd_link_hash_defined
- + || h->root.type == bfd_link_hash_defweak)
- + {
- + sec = h->root.u.def.section;
- +
- + relocation = (h->root.u.def.value
- + + sec->output_section->vma + sec->output_offset);
- + }
- + else if (h->root.type == bfd_link_hash_undefweak)
- + {
- + relocation = 0;
- + }
- + else
- + {
- + if (!((*info->callbacks->undefined_symbol)
- + (info, h->root.root.string, input_bfd,
- + input_section, rel->r_offset, TRUE)))
- + return FALSE;
- + relocation = 0;
- + }
- + }
- +
- + if (howto != NULL)
- + {
- + switch (howto->type)
- + {
- + case R_NIOS2_HI16:
- + r =
- + nios2_elf32_do_hi16_relocate (input_bfd, howto, input_section,
- + contents, rel->r_offset,
- + relocation, rel->r_addend);
- + break;
- + case R_NIOS2_LO16:
- + r =
- + nios2_elf32_do_lo16_relocate (input_bfd, howto, input_section,
- + contents, rel->r_offset,
- + relocation, rel->r_addend);
- + break;
- + case R_NIOS2_HIADJ16:
- + r =
- + nios2_elf32_do_hiadj16_relocate (input_bfd, howto,
- + input_section, contents,
- + rel->r_offset, relocation,
- + rel->r_addend);
- + break;
- + case R_NIOS2_PCREL16:
- + r =
- + nios2_elf32_do_pcrel16_relocate (input_bfd, howto,
- + input_section, contents,
- + rel->r_offset, relocation,
- + rel->r_addend);
- + break;
- + case R_NIOS2_GPREL:
- + // turns an absolute address into a gp-relative address
- + if (!nios2_elf_assign_gp (output_bfd, &gp, info))
- + {
- + msg =
- + _
- + ("global pointer relative relocation when _gp not defined");
- + r = bfd_reloc_dangerous;
- + }
- + else
- + {
- + relocation = relocation + rel->r_addend - gp;
- + rel->r_addend = 0;
- + if ((signed) relocation < -32768
- + || (signed) relocation > 32767)
- + {
- + msg = _("global pointer relative address out of range");
- + r = bfd_reloc_outofrange;
- + }
- + else
- + {
- + r =
- + _bfd_final_link_relocate (howto, input_bfd,
- + input_section, contents,
- + rel->r_offset, relocation,
- + rel->r_addend);
- + }
- + }
- +
- + break;
- + case R_NIOS2_UJMP:
- + r =
- + nios2_elf32_do_ujmp_relocate (input_bfd, howto, input_section,
- + contents, rel->r_offset,
- + relocation, rel->r_addend);
- + break;
- + case R_NIOS2_CJMP:
- + r =
- + nios2_elf32_do_cjmp_relocate (input_bfd, howto, input_section,
- + contents, rel->r_offset,
- + relocation, rel->r_addend);
- + break;
- + case R_NIOS2_CALLR:
- + r =
- + nios2_elf32_do_callr_relocate (input_bfd, howto,
- + input_section, contents,
- + rel->r_offset, relocation,
- + rel->r_addend);
- + break;
- + case R_NIOS2_CALL26:
- + r =
- + nios2_elf32_do_call26_relocate (input_bfd, howto,
- + input_section, contents,
- + rel->r_offset, relocation,
- + rel->r_addend);
- + break;
- + case R_NIOS2_ALIGN:
- + r = bfd_reloc_ok;
- + /* comment - for symmetry this would be
- + r = nios2_elf32_do_ignore_reloc (input_bfd, howto, input_section,
- + contents, rel->r_offset,
- + relocation, rel->r_addend);
- + but do_ignore_reloc would do no more than return bfd_reloc_ok */
- + break;
- + default:
- + r = _bfd_final_link_relocate (howto, input_bfd, input_section,
- + contents, rel->r_offset,
- + relocation, rel->r_addend);
- + break;
- + }
- + }
- + else
- + {
- + r = bfd_reloc_notsupported;
- + }
- +
- + if (r != bfd_reloc_ok)
- + {
- + if (h != NULL)
- + name = h->root.root.string;
- + else
- + {
- + name = (bfd_elf_string_from_elf_section
- + (input_bfd, symtab_hdr->sh_link, sym->st_name));
- + if (name == NULL || *name == '\0')
- + name = bfd_section_name (input_bfd, sec);
- + }
- +
- + switch (r)
- + {
- + case bfd_reloc_overflow:
- + r = info->callbacks->reloc_overflow
- + (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
- + input_bfd, input_section, rel->r_offset);
- + break;
- +
- + case bfd_reloc_undefined:
- + r = info->callbacks->undefined_symbol
- + (info, name, input_bfd, input_section, rel->r_offset, TRUE);
- + break;
- +
- + case bfd_reloc_outofrange:
- + if (msg == NULL)
- + msg = _("relocation out of range");
- + break;
- +
- + case bfd_reloc_notsupported:
- + if (msg == NULL)
- + msg = _("unsupported relocation");
- + break;
- +
- + case bfd_reloc_dangerous:
- + if (msg == NULL)
- + msg = _("dangerous relocation");
- + break;
- +
- + default:
- + if (msg == NULL)
- + msg = _("unknown error");
- + break;
- + }
- +
- + if (msg)
- + {
- + r = info->callbacks->warning
- + (info, msg, name, input_bfd, input_section, rel->r_offset);
- + return linker_force_make_executable;
- + }
- + }
- + }
- + return TRUE;
- +}
- +
- +
- +
- +/* Handle an NIOS2 specific section when reading an object file. This
- + is called when elfcode.h finds a section with an unknown type.
- + FIXME: We need to handle the SHF_NIOS2_GPREL flag */
- +
- +static bfd_boolean
- +nios2_elf32_section_from_shdr (bfd *abfd,
- + Elf_Internal_Shdr *hdr, const char *name, int shindex)
- +{
- + asection *newsect;
- +
- + /* NG - I'm keeping this code commented out at the moment
- + in case we add a .mdebug section */
- +
- + /*
- + switch (hdr->sh_type)
- + {
- + case SHT_NIOS2_DEBUG:
- + if (strcmp (name, ".mdebug") != 0)
- + return FALSE;
- + break;
- + default:
- + return FALSE;
- + }
- + */
- +
- + if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
- + return FALSE;
- +
- + newsect = hdr->bfd_section;
- +
- + /* ditto */
- + /*
- + if (hdr->sh_type == SHT_NIOS2_DEBUG)
- + {
- + if (! bfd_set_section_flags (abfd, newsect,
- + (bfd_get_section_flags (abfd, newsect)
- + | SEC_DEBUGGING)))
- + return FALSE;
- + }
- + */
- + return TRUE;
- +}
- +
- +/* Convert NIOS2 specific section flags to bfd internal section flags. */
- +
- +static bfd_boolean
- +nios2_elf32_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
- +{
- + if (hdr->sh_flags & SHF_NIOS2_GPREL)
- + *flags |= SEC_SMALL_DATA;
- +
- + return TRUE;
- +}
- +
- +/* Set the correct type for an NIOS2 ELF section. We do this by the
- + section name, which is a hack, but ought to work. */
- +
- +static bfd_boolean
- +nios2_elf32_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
- + Elf_Internal_Shdr *hdr, asection *sec)
- +{
- + register const char *name;
- +
- + name = bfd_get_section_name (abfd, sec);
- +
- + if (strcmp (name, ".mdebug") == 0)
- + {
- + /* we don't yet have an .mdebug section, but I'm leaving this here
- + in case we ever do
- + hdr->sh_type = SHT_NIOS2_DEBUG;
- +
- + if ((abfd->flags & DYNAMIC) != 0 )
- + hdr->sh_entsize = 0;
- + else
- + hdr->sh_entsize = 1;
- + */
- + }
- + else if ((sec->flags & SEC_SMALL_DATA)
- + || strcmp (name, ".sdata") == 0
- + || strcmp (name, ".sbss") == 0
- + || strcmp (name, ".lit4") == 0 || strcmp (name, ".lit8") == 0)
- + hdr->sh_flags |= SHF_NIOS2_GPREL;
- +
- + return TRUE;
- +}
- +
- +/* Look through the relocs for a section during the first phase.
- + Since we don't do .gots or .plts, we just need to consider the
- + virtual table relocs for gc. */
- +
- +static bfd_boolean
- +nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
- + asection *sec, const Elf_Internal_Rela *relocs)
- +{
- + Elf_Internal_Shdr *symtab_hdr;
- + struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
- + const Elf_Internal_Rela *rel;
- + const Elf_Internal_Rela *rel_end;
- +
- + if (info->relocatable)
- + return TRUE;
- +
- + symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- + sym_hashes = elf_sym_hashes (abfd);
- + sym_hashes_end =
- + sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
- + if (!elf_bad_symtab (abfd))
- + sym_hashes_end -= symtab_hdr->sh_info;
- +
- + rel_end = relocs + sec->reloc_count;
- + for (rel = relocs; rel < rel_end; rel++)
- + {
- + struct elf_link_hash_entry *h;
- + unsigned long r_symndx;
- +
- + r_symndx = ELF32_R_SYM (rel->r_info);
- + if (r_symndx < symtab_hdr->sh_info)
- + h = NULL;
- + else
- + h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- +
- + switch (ELF32_R_TYPE (rel->r_info))
- + {
- + /* This relocation describes the C++ object vtable hierarchy.
- + Reconstruct it for later use during GC. */
- + case R_NIOS2_GNU_VTINHERIT:
- + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
- + return FALSE;
- + break;
- +
- + /* This relocation describes which C++ vtable entries are actually
- + used. Record for later use during GC. */
- + case R_NIOS2_GNU_VTENTRY:
- + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
- + return FALSE;
- + break;
- + }
- + }
- +
- + return TRUE;
- +}
- +
- +
- +/* Return the section that should be marked against GC for a given
- + relocation. */
- +
- +asection *
- +nios2_elf32_gc_mark_hook (asection *sec,
- + struct bfd_link_info *info ATTRIBUTE_UNUSED,
- + Elf_Internal_Rela *rel, struct elf_link_hash_entry *h,
- + Elf_Internal_Sym *sym)
- +{
- + if (h != NULL)
- + {
- + switch (ELF32_R_TYPE (rel->r_info))
- + {
- + case R_NIOS2_GNU_VTINHERIT:
- + case R_NIOS2_GNU_VTENTRY:
- + break;
- +
- + default:
- + switch (h->root.type)
- + {
- + case bfd_link_hash_defined:
- + case bfd_link_hash_defweak:
- + return h->root.u.def.section;
- +
- + case bfd_link_hash_common:
- + return h->root.u.c.p->section;
- +
- + default:
- + break;
- + }
- + }
- + }
- + else
- + return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
- +
- + return NULL;
- +}
- +
- +/*
- + NG ??? I'm marking the sections as standalone ie. I'm linking for
- + standalone embedded applications, not for UNIX System V or any other
- + OS/ABI - this may need to change when we deal with embedded PIC or
- + dynamic linking
- +*/
- +
- +static void
- +nios2_elf32_post_process_headers (bfd *abfd,
- + struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
- +{
- + Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
- +
- + i_ehdrp = elf_elfheader (abfd);
- + i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_STANDALONE;
- +}
- +
- +#define ELF_ARCH bfd_arch_nios2
- +#define ELF_MACHINE_CODE EM_ALTERA_NIOS2
- +
- +/* for now we just make this 1, as we have no MMU in New Jersey */
- +
- +#define ELF_MAXPAGESIZE 1
- +
- +/* relocation table lookup macros */
- +
- +#define bfd_elf32_bfd_reloc_type_lookup nios2_elf32_bfd_reloc_type_lookup
- +
- +/* JUMP_TABLE_LINK macros */
- +
- +#define bfd_elf32_bfd_relax_section nios2_elf32_relax_section
- +
- +/* elf_info_to_howto (using RELA relocations) */
- +
- +#define elf_info_to_howto nios2_elf32_info_to_howto
- +
- +/* elf backend functions */
- +
- +#define elf_backend_can_gc_sections 1
- +
- +#define elf_backend_relocate_section nios2_elf32_relocate_section
- +#define elf_backend_section_from_shdr nios2_elf32_section_from_shdr
- +#define elf_backend_section_flags nios2_elf32_section_flags
- +#define elf_backend_fake_sections nios2_elf32_fake_sections
- +#define elf_backend_post_process_headers nios2_elf32_post_process_headers
- +#define elf_backend_check_relocs nios2_elf32_check_relocs
- +
- +#define elf_backend_gc_mark_hook nios2_elf32_gc_mark_hook
- +
- +
- +
- +/* Support for SGI-ish mips targets. */
- +#define TARGET_LITTLE_SYM bfd_elf32_littlenios2_vec
- +#define TARGET_LITTLE_NAME "elf32-littlenios2"
- +#define TARGET_BIG_SYM bfd_elf32_bignios2_vec
- +#define TARGET_BIG_NAME "elf32-bignios2"
- +
- +#include "elf32-target.h"
- diff --git a/bfd/reloc.c b/bfd/reloc.c
- index 1b8c8d7..c66a23d 100644
- --- a/bfd/reloc.c
- +++ b/bfd/reloc.c
- @@ -4733,6 +4733,39 @@ ENUMDOC
- msp430 specific relocation codes
-
- ENUM
- + BFD_RELOC_NIOS2_S16
- +ENUMX
- + BFD_RELOC_NIOS2_U16
- +ENUMX
- + BFD_RELOC_NIOS2_CALL26
- +ENUMX
- + BFD_RELOC_NIOS2_IMM5
- +ENUMX
- + BFD_RELOC_NIOS2_CACHE_OPX
- +ENUMX
- + BFD_RELOC_NIOS2_IMM6
- +ENUMX
- + BFD_RELOC_NIOS2_IMM8
- +ENUMX
- + BFD_RELOC_NIOS2_HI16
- +ENUMX
- + BFD_RELOC_NIOS2_LO16
- +ENUMX
- + BFD_RELOC_NIOS2_HIADJ16
- +ENUMX
- + BFD_RELOC_NIOS2_GPREL
- +ENUMX
- + BFD_RELOC_NIOS2_UJMP
- +ENUMX
- + BFD_RELOC_NIOS2_CJMP
- +ENUMX
- + BFD_RELOC_NIOS2_CALLR
- +ENUMX
- + BFD_RELOC_NIOS2_ALIGN
- +ENUMDOC
- + Relocations used by the Altera Nios II core
- +
- +ENUM
- BFD_RELOC_IQ2000_OFFSET_16
- ENUMX
- BFD_RELOC_IQ2000_OFFSET_21
- diff --git a/bfd/targets.c b/bfd/targets.c
- index 71e3337..d5f6d60 100644
- --- a/bfd/targets.c
- +++ b/bfd/targets.c
- @@ -619,6 +619,8 @@ extern const bfd_target bfd_elf32_ntradbigmips_vec;
- extern const bfd_target bfd_elf32_ntradlittlemips_vec;
- extern const bfd_target bfd_elf32_openrisc_vec;
- extern const bfd_target bfd_elf32_or32_big_vec;
- +extern const bfd_target bfd_elf32_littlenios2_vec;
- +extern const bfd_target bfd_elf32_bignios2_vec;
- extern const bfd_target bfd_elf32_pj_vec;
- extern const bfd_target bfd_elf32_pjl_vec;
- extern const bfd_target bfd_elf32_powerpc_vec;
- @@ -819,6 +821,8 @@ extern const bfd_target sco5_core_vec;
- extern const bfd_target trad_core_vec;
-
- extern const bfd_target bfd_elf32_am33lin_vec;
- +extern const bfd_target bfd_elf32_littlenios2_vec;
- +extern const bfd_target bfd_elf32_bignios2_vec;
- static const bfd_target * const _bfd_target_vector[] =
- {
- #ifdef SELECT_VECS
- @@ -923,6 +927,8 @@ static const bfd_target * const _bfd_target_vector[] =
- &bfd_elf32_littlearm_vxworks_vec,
- &bfd_elf32_littlemips_vec,
- &bfd_elf32_littlemips_vxworks_vec,
- + &bfd_elf32_littlenios2_vec,
- + &bfd_elf32_bignios2_vec,
- &bfd_elf32_m32c_vec,
- &bfd_elf32_m32r_vec,
- &bfd_elf32_m32rle_vec,
- diff --git a/config.sub b/config.sub
- index fab0aa3..462e7c6 100755
- --- a/config.sub
- +++ b/config.sub
- @@ -270,7 +270,7 @@ case $basic_machine in
- | mn10200 | mn10300 \
- | mt \
- | msp430 \
- - | nios | nios2 \
- + | nios2 | nios2eb | nios2el \
- | ns16k | ns32k \
- | or32 \
- | pdp10 | pdp11 | pj | pjl \
- diff --git a/configure.in b/configure.in
- index a4befda..f2e34c7 100644
- --- a/configure.in
- +++ b/configure.in
- @@ -740,6 +740,9 @@ case "${target}" in
- mips*-*-*)
- noconfigdirs="$noconfigdirs gprof ${libgcj}"
- ;;
- + nios2*-*-*)
- + noconfigdirs="$noconfigdirs ld"
- + ;;
- romp-*-*)
- noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes target-libgloss ${libgcj}"
- ;;
- diff --git a/gdb/Makefile.in b/gdb/Makefile.in
- index 14fd58b..eac9489 100644
- --- a/gdb/Makefile.in
- +++ b/gdb/Makefile.in
- @@ -593,6 +593,7 @@ libiberty_h = $(INCLUDE_DIR)/libiberty.h
- libbfd_h = $(BFD_SRC)/libbfd.h
- remote_sim_h = $(INCLUDE_DIR)/gdb/remote-sim.h
- demangle_h = $(INCLUDE_DIR)/demangle.h
- +nios2_h = $(INCLUDE_DIR)/opcode/nios2.h
- obstack_h = $(INCLUDE_DIR)/obstack.h
- opcode_m68hc11_h = $(INCLUDE_DIR)/opcode/m68hc11.h
- readline_h = $(READLINE_SRC)/readline.h
- @@ -2399,6 +2400,7 @@ ms1-tdep.o: ms1-tdep.c $(defs_h) $(frame_h) $(frame_unwind_h) $(frame_base_h) \
- $(trad_frame_h) $(inferior_h) $(dwarf2_frame_h) $(infcall_h) \
- $(gdb_assert_h)
- nbsd-tdep.o: nbsd-tdep.c $(defs_h) $(gdb_string_h) $(solib_svr4_h)
- +nios2-tdep.o: nios2-tdep.c $(defs_h) $(symtab_h) $(frame_h) $(nios2_h)
- nlmread.o: nlmread.c $(defs_h) $(bfd_h) $(symtab_h) $(symfile_h) \
- $(objfiles_h) $(buildsym_h) $(stabsread_h) $(block_h)
- nto-procfs.o: nto-procfs.c $(defs_h) $(gdb_dirent_h) $(exceptions_h) \
- diff --git a/gdb/config/nios2/nios2.mt b/gdb/config/nios2/nios2.mt
- new file mode 100644
- index 0000000..63413b4
- --- /dev/null
- +++ b/gdb/config/nios2/nios2.mt
- @@ -0,0 +1,4 @@
- +# Target: Altera New Jersey Processor machine (NIOS2)
- +TDEPFILES= nios2-tdep.o
- +
- +
- diff --git a/gdb/config/nios2/tm-nios2.h b/gdb/config/nios2/tm-nios2.h
- new file mode 100644
- index 0000000..2962b6b
- --- /dev/null
- +++ b/gdb/config/nios2/tm-nios2.h
- @@ -0,0 +1,28 @@
- +/* Definitions to target GDB to New Jersey targets.
- + Copyright 1986, 1987, 1988, 1989, 1991, 1993, 1994,
- + 1995, 1996, 1997, 1998, 1999, 2000, 2003
- + by Peter Brookes (pbrookes@altera.com)
- +
- + This file is part of GDB.
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 59 Temple Place - Suite 330,
- + Boston, MA 02111-1307, USA. */
- +
- +#ifndef TM_NIOS2_H
- +#define TM_NIOS2_H
- +
- +#define GDB_MULTI_ARCH 1
- +
- +#endif /* TM_NIOS2_H */
- diff --git a/gdb/configure.tgt b/gdb/configure.tgt
- index dd2e719..7222f59 100644
- --- a/gdb/configure.tgt
- +++ b/gdb/configure.tgt
- @@ -20,6 +20,7 @@ m68hc11*|m6811*) gdb_target_cpu=m68hc11 ;;
- m68*) gdb_target_cpu=m68k ;;
- m88*) gdb_target_cpu=m88k ;;
- mips*) gdb_target_cpu=mips ;;
- +nios2*) gdb_target_cpu=nios2 ;;
- powerpc*) gdb_target_cpu=powerpc ;;
- sparc*) gdb_target_cpu=sparc ;;
- thumb*) gdb_target_cpu=arm ;;
- @@ -155,6 +156,8 @@ mn10300-*-*) gdb_target=mn10300 ;;
-
- mt-*-*) gdb_target=mt ;;
-
- +nios2*-*-*) gdb_target=nios2 ;;
- +
- powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu)
- gdb_target=nbsd ;;
- powerpc-*-openbsd*) gdb_target=obsd ;;
- diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
- index 9748c95..b3fb5f8 100644
- --- a/gdb/gdbserver/Makefile.in
- +++ b/gdb/gdbserver/Makefile.in
- @@ -280,6 +280,7 @@ linux-ia64-low.o: linux-ia64-low.c $(linux_low_h) $(server_h)
- linux-m32r-low.o: linux-m32r-low.c $(linux_low_h) $(server_h)
- linux-mips-low.o: linux-mips-low.c $(linux_low_h) $(server_h) \
- $(gdb_proc_service_h)
- +linux-nios2-low.o: linux-nios2-low.c $(linux_low_h) $(server_h)
- linux-ppc-low.o: linux-ppc-low.c $(linux_low_h) $(server_h)
- linux-ppc64-low.o: linux-ppc64-low.c $(linux_low_h) $(server_h)
- linux-s390-low.o: linux-s390-low.c $(linux_low_h) $(server_h)
- @@ -318,6 +319,9 @@ reg-m68k.c : $(srcdir)/../regformats/reg-m68k.dat $(regdat_sh)
- reg-mips.o : reg-mips.c $(regdef_h)
- reg-mips.c : $(srcdir)/../regformats/reg-mips.dat $(regdat_sh)
- sh $(regdat_sh) $(srcdir)/../regformats/reg-mips.dat reg-mips.c
- +reg-nios2.o : reg-nios2.c $(regdef_h)
- +reg-nios2.c : $(srcdir)/../regformats/reg-nios2.dat $(regdat_sh)
- + sh $(regdat_sh) $(srcdir)/../regformats/reg-nios2.dat reg-nios2.c
- reg-ppc.o : reg-ppc.c $(regdef_h)
- reg-ppc.c : $(srcdir)/../regformats/reg-ppc.dat $(regdat_sh)
- sh $(regdat_sh) $(srcdir)/../regformats/reg-ppc.dat reg-ppc.c
- diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
- index 5a4792c..fdc847c 100644
- --- a/gdb/gdbserver/configure.srv
- +++ b/gdb/gdbserver/configure.srv
- @@ -72,6 +72,10 @@ case "${target}" in
- srv_linux_usrregs=yes
- srv_linux_thread_db=yes
- ;;
- + nios2-*-linux*) srv_regobj=reg-nios2.o
- + srv_tgtobj="linux-low.o linux-nios2-low.o"
- + srv_linux_usrregs=yes
- + ;;
- powerpc64-*-linux*) srv_regobj=reg-ppc64.o
- srv_tgtobj="linux-low.o linux-ppc64-low.o"
- srv_linux_usrregs=yes
- diff --git a/gdb/gdbserver/linux-nios2-low.c b/gdb/gdbserver/linux-nios2-low.c
- new file mode 100644
- index 0000000..1fab749
- --- /dev/null
- +++ b/gdb/gdbserver/linux-nios2-low.c
- @@ -0,0 +1,89 @@
- +/* GNU/Linux/Nios2 specific low level interface for the remote server for GDB */
- +
- +#include "server.h"
- +#include "linux-low.h"
- +
- +#ifdef HAVE_SYS_REG_H
- +#include <sys/reg.h>
- +#endif
- +
- +#include <asm/ptrace.h>
- +
- +static int nios2_regmap[] =
- +{
- + -1, PTR_R1 * 4, PTR_R2 * 4, PTR_R3 * 4,
- + PTR_R4 * 4, PTR_R5 * 4, PTR_R6 * 4, PTR_R7 * 4,
- + PTR_R8 * 4, PTR_R9 * 4, PTR_R10 * 4, PTR_R11 * 4,
- + PTR_R12 * 4, PTR_R13 * 4, PTR_R14 * 4, PTR_R15 * 4, /* reg 15 */
- + PTR_R16 * 4, PTR_R17 * 4, PTR_R18 * 4, PTR_R19 * 4,
- + PTR_R20 * 4, PTR_R21 * 4, PTR_R22 * 4, PTR_R23 * 4,
- + -1, -1, PTR_GP * 4, PTR_SP * 4,
- + PTR_FP * 4, -1, -1, PTR_RA * 4, /* reg 31 */
- + PTR_PC * 4, -1, -1, -1,
- + -1, -1, -1, -1,
- + -1, -1, -1, -1
- +};
- +
- +#define nios2_num_regs (sizeof(nios2_regmap) / sizeof(nios2_regmap[0]))
- +
- +static int
- +nios2_cannot_store_register (int regno)
- +{
- + return (regno >= 33);
- +}
- +
- +static int
- +nios2_cannot_fetch_register (int regno)
- +{
- + return (regno >= 33);
- +}
- +
- +static CORE_ADDR
- +nios2_get_pc ()
- +{
- + unsigned long pc;
- + collect_register_by_name ("pc", &pc);
- + return pc;
- +}
- +
- +static void
- +nios2_set_pc (CORE_ADDR pc)
- +{
- + unsigned long newpc = pc;
- + supply_register_by_name ("pc", &newpc);
- +}
- +
- +#if 0
- +static const unsigned long nios2_breakpoint = 0x003da03a;
- +#else
- +static const unsigned long nios2_breakpoint = 0x003b687a; /* Trap instr. w/imm=0x01 */
- +#endif
- +#define nios2_breakpoint_len 4
- +
- +static int
- +nios2_breakpoint_at (CORE_ADDR where)
- +{
- + unsigned long insn;
- +
- + (*the_target->read_memory) (where, (char *) &insn, nios2_breakpoint_len);
- + if (insn == nios2_breakpoint)
- + return 1;
- +
- + /* If necessary, recognize more trap instructions here. GDB only uses the
- + one. */
- + return 0;
- +}
- +
- +struct linux_target_ops the_low_target = {
- + nios2_num_regs,
- + nios2_regmap,
- + nios2_cannot_fetch_register,
- + nios2_cannot_store_register,
- + nios2_get_pc,
- + nios2_set_pc,
- + (const char *) &nios2_breakpoint,
- + nios2_breakpoint_len,
- + NULL,
- + 0,
- + nios2_breakpoint_at,
- +};
- diff --git a/gdb/nios2-tdep.c b/gdb/nios2-tdep.c
- new file mode 100644
- index 0000000..e0712dd
- --- /dev/null
- +++ b/gdb/nios2-tdep.c
- @@ -0,0 +1,1610 @@
- +/* Target-machine dependent code for Nios2, for GDB.
- + Copyright (C) 2003-2005
- + by Peter Brookes (pbrookes@altera.com)
- + and Andrew Draper (adraper@altera.com)
- +
- + This file is part of GDB.
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 59 Temple Place - Suite 330,
- + Boston, MA 02111-1307, USA. */
- +
- +#include "defs.h"
- +#include "frame.h"
- +#include "frame-unwind.h"
- +#include "frame-base.h"
- +#include "trad-frame.h"
- +#include "dwarf2-frame.h"
- +#include "symtab.h"
- +#include "inferior.h"
- +#include "gdbtypes.h"
- +#include "gdbcore.h"
- +#include "gdbcmd.h"
- +#include "target.h"
- +#include "dis-asm.h"
- +#include "regcache.h"
- +#include "value.h"
- +#include "symfile.h"
- +#include "arch-utils.h"
- +#include "floatformat.h"
- +#include "gdb_assert.h"
- +
- +/* To get entry_point_address. */
- +#include "objfiles.h"
- +
- +/* Nios II ISA specific encodings and macros */
- +#include "opcode/nios2.h"
- +
- +/* Macros */
- +
- +#define Z_REGNUM 0 /* Zero */
- +#define R2_REGNUM 2 /* used for return value */
- +#define R3_REGNUM 3 /* used for return value */
- +/* used for hidden zero argument to store ptr to struct return value */
- +#define R4_REGNUM 4
- +#define R7_REGNUM 7
- +#define GP_REGNUM 26 /* Global Pointer */
- +#undef SP_REGNUM
- +#define SP_REGNUM 27 /* Stack Pointer */
- +#undef FP_REGNUM
- +#define FP_REGNUM 28 /* Frame Pointer */
- +#define EA_REGNUM 29 /* Exception address */
- +#define BA_REGNUM 30 /* Breakpoint return address */
- +#define RA_REGNUM 31 /* Return address */
- +#undef PC_REGNUM
- +#define PC_REGNUM 32
- +#define STATUS_REGNUM 33 /* Ctrl registers */
- +#define ESTATUS_REGNUM 34
- +#define BSTATUS_REGNUM 35
- +#define IENABLE_REGNUM 36
- +#define IPENDING_REGNUM 37
- +#define CPUID_REGNUM 38
- +#define PTEADDR_REGNUM 41
- +#define TLBACC_REGNUM 42
- +#define TLBMISC_REGNUM 43
- +#define FIRST_ARGREG R4_REGNUM
- +#define LAST_ARGREG R7_REGNUM
- +/* Number of all registers */
- +#define NIOS2_NUM_REGS (44)
- +/* The maximum register number displayed to the user, */
- +/* as a result of typing "info reg" at the gdb prompt */
- +#define NIOS2_MAX_REG_DISPLAYED_REGNUM (38)
- +
- +#define NIOS2_OPCODE_SIZE 4
- +
- +/* Structures */
- +struct register_info
- +{
- + int size;
- + char *name;
- + struct type **type;
- +};
- +
- +/* The current value in the register is the value in r[base] at the start of
- + * the function + offset ; unless base < 0 in which case it's unknown.
- + */
- +typedef struct
- +{
- + int reg;
- + unsigned int offset;
- +
- +} REG_VALUE;
- +
- +
- +typedef struct
- +{
- + int basereg;
- + CORE_ADDR addr;
- +
- +} REG_SAVED;
- +
- +struct nios2_unwind_cache
- +{
- + /* The frame's base, optionally used by the high-level debug info. */
- + CORE_ADDR base;
- +
- + /* The previous frame's inner most stack address. Used as this
- + frame ID's stack_addr. */
- + CORE_ADDR cfa;
- +
- + /* The address of the first instruction in this function */
- + CORE_ADDR pc;
- +
- + /* Which register holds the return address for the frame. */
- + int return_regnum;
- +
- + /* Table indicating what changes have been made to each register */
- + REG_VALUE reg_value[NIOS2_NUM_REGS];
- +
- + /* Table indicating where each register has been saved. */
- + REG_SAVED reg_saved[NIOS2_NUM_REGS];
- +};
- +
- +
- +/* Function prototypes */
- +CORE_ADDR nios2_saved_pc_after_call (struct frame_info *fi);
- +
- +/* nios2_register_info_table[i] is the number of bytes of storage in
- + GDB's register array occupied by register i. */
- +static struct register_info nios2_register_info_table[] = {
- + /* 0 */ {4, "zero", &builtin_type_uint32},
- + /* 1 */ {4, "at", &builtin_type_uint32},
- + /* 2 */ {4, "r2", &builtin_type_uint32},
- + /* 3 */ {4, "r3", &builtin_type_uint32},
- + /* 4 */ {4, "r4", &builtin_type_uint32},
- + /* 5 */ {4, "r5", &builtin_type_uint32},
- + /* 6 */ {4, "r6", &builtin_type_uint32},
- + /* 7 */ {4, "r7", &builtin_type_uint32},
- + /* 8 */ {4, "r8", &builtin_type_uint32},
- + /* 9 */ {4, "r9", &builtin_type_uint32},
- + /* 10 */ {4, "r10", &builtin_type_uint32},
- + /* 11 */ {4, "r11", &builtin_type_uint32},
- + /* 12 */ {4, "r12", &builtin_type_uint32},
- + /* 13 */ {4, "r13", &builtin_type_uint32},
- + /* 14 */ {4, "r14", &builtin_type_uint32},
- + /* 15 */ {4, "r15", &builtin_type_uint32},
- + /* 16 */ {4, "r16", &builtin_type_uint32},
- + /* 17 */ {4, "r17", &builtin_type_uint32},
- + /* 18 */ {4, "r18", &builtin_type_uint32},
- + /* 19 */ {4, "r19", &builtin_type_uint32},
- + /* 20 */ {4, "r20", &builtin_type_uint32},
- + /* 21 */ {4, "r21", &builtin_type_uint32},
- + /* 22 */ {4, "r22", &builtin_type_uint32},
- + /* 23 */ {4, "r23", &builtin_type_uint32},
- + /* 24 */ {4, "et", &builtin_type_uint32},
- + /* 25 */ {4, "bt", &builtin_type_uint32},
- + /* 26 */ {4, "gp", &builtin_type_uint32},
- + /* 27 */ {4, "sp", &builtin_type_uint32},
- + /* 28 */ {4, "fp", &builtin_type_uint32},
- + /* 29 */ {4, "ea", &builtin_type_uint32},
- + /* 30 */ {4, "ba", &builtin_type_uint32},
- + /* 31 */ {4, "ra", &builtin_type_uint32},
- + /* 32 */ {4, "pc", &builtin_type_uint32},
- + /* 33 */ {4, "status", &builtin_type_uint32},
- + /* 34 */ {4, "estatus", &builtin_type_uint32},
- + /* 35 */ {4, "bstatus", &builtin_type_uint32},
- + /* 36 */ {4, "ienable", &builtin_type_uint32},
- + /* 37 */ {4, "ipending", &builtin_type_uint32},
- + /* 38 */ {4, "cpuid", &builtin_type_uint32},
- + /* 39 */ {4, "ctl6", &builtin_type_uint32},
- + /* 40 */ {4, "ctl7", &builtin_type_uint32},
- + /* 41 */ {4, "pteaddr", &builtin_type_uint32},
- + /* 42 */ {4, "tlbacc", &builtin_type_uint32},
- + /* 43 */ {4, "tlbmisc", &builtin_type_uint32}
- +};
- +
- +/* This array is a mapping from Dwarf-2 register
- + numbering to GDB's */
- +static int nios2_dwarf2gdb_regno_map[] = {
- + 0, 1, 2, 3,
- + 4, 5, 6, 7,
- + 8, 9, 10, 11,
- + 12, 13, 14, 15,
- + 16, 17, 18, 19,
- + 20, 21, 22, 23,
- + 24, 25,
- + GP_REGNUM, /* 26 */
- + SP_REGNUM, /* 27 */
- + FP_REGNUM, /* 28 */
- + EA_REGNUM, /* 29 */
- + BA_REGNUM, /* 30 */
- + RA_REGNUM, /* 31 */
- + PC_REGNUM, /* 32 */
- + STATUS_REGNUM, /* 33 */
- + ESTATUS_REGNUM, /* 34 */
- + BSTATUS_REGNUM, /* 35 */
- + IENABLE_REGNUM, /* 36 */
- + IPENDING_REGNUM, /* 37 */
- + 38, 39, 40, 41, 42, 43
- +};
- +
- +/* Dwarf-2 <-> GDB register numbers mapping. */
- +int
- +nios2_dwarf_reg_to_regnum (int dw_reg)
- +{
- + if (dw_reg < 0 || dw_reg > NIOS2_NUM_REGS)
- + {
- + warning ("Dwarf-2 uses unmapped register #%d\n", dw_reg);
- + return dw_reg;
- + }
- +
- + return nios2_dwarf2gdb_regno_map[dw_reg];
- +}
- +
- +/* Same as read_memory_u6signed_integer, but don't report an error if
- + can't read. */
- +int
- +nios2_read_memory_unsigned_integer (CORE_ADDR memaddr, int len, ULONGEST *ret)
- +{
- + char buf[sizeof (ULONGEST)];
- + int error;
- +
- + error = target_read_memory (memaddr, buf, len);
- + if (error != 0)
- + return 0;
- + else
- + {
- + *ret = extract_unsigned_integer (buf, len);
- + return 1;
- + }
- +}
- +
- +/* Find the name for the specified NIOS2 regno */
- +static const char *
- +nios2_register_name (int regno)
- +{
- + /* Don't display any registers after NIOS2_MAX_REG_DISPLAYED_REGNUM */
- + if (regno < 0)
- + return NULL;
- + else if (regno > NIOS2_MAX_REG_DISPLAYED_REGNUM)
- + return NULL;
- + return nios2_register_info_table[regno].name;
- +}
- +
- +/* Returns the default type for register N. */
- +static struct type *
- +nios2_register_type (struct gdbarch *gdbarch, int regno)
- +{
- +/* FIXME Do we need some checks on regno ? */
- + return *nios2_register_info_table[regno].type;
- +}
- +
- +/* nios2_register_byte_table[i] is the offset into the register file of the
- + start of register number i. We initialize this from
- + nios2_register_info_table. */
- +int nios2_register_byte_table[NIOS2_NUM_REGS];
- +
- +/* Index within `registers' of the first byte of the space for register REGNO. */
- +int
- +nios2_register_byte (int regno)
- +{
- + return nios2_register_byte_table[regno];
- +}
- +
- +/* Number of bytes of storage in the actual machine representation for
- + register 'regno'. */
- +static int
- +nios2_register_raw_size (int regno)
- +{
- + return nios2_register_info_table[regno].size;
- +}
- +
- +/* Number of bytes of storage in the program's representation for
- + register 'regno'. */
- +static int
- +nios2_register_virtual_size (int regno)
- +{
- + return nios2_register_info_table[regno].size;
- +}
- +
- +/* Return the GDB type object for the "standard" data type
- + of data in register 'regno'. */
- +static struct type *
- +nios2_register_virtual_type (int regno)
- +{
- + return *nios2_register_info_table[regno].type;
- +}
- +
- +/* Does this register need conversion betwen raw and virtual formats */
- +int
- +nios2_register_convertible (int regno)
- +{
- + if (nios2_register_raw_size (regno) == nios2_register_virtual_size (regno))
- + return 0;
- + else
- + return 1;
- +}
- +
- +
- +
- +/* Given a return value in `regcache' with a type `valtype',
- + extract and copy its value into `valbuf'. */
- +/* FIXME: check this function*/
- +void
- +nios2_extract_return_value (struct type *valtype, struct regcache *regcache, void *valbuf)
- +{
- +#ifdef PORTINGTO61
- + int len = TYPE_LENGTH (valtype);
- +
- + /* pointer types are returned in register r2,
- + up to 16-bit types in r2
- + up to 32-bit types in r2,r3 */
- + if (len <= nios2_register_raw_size (R2_REGNUM))
- + memcpy (valbuf, regbuf + REGISTER_BYTE (R2_REGNUM), len);
- + else if (len <= (nios2_register_raw_size (R2_REGNUM)
- + + nios2_register_raw_size (R3_REGNUM)))
- + memcpy (valbuf, regbuf + REGISTER_BYTE (R2_REGNUM), len);
- + else
- + {
- + /* Can I get the returned value here ? */
- + memset(valbuf, 0, len);
- + }
- +#endif
- +}
- +
- +/* Write into appropriate registers a function return value
- + of type TYPE, given in virtual format. */
- +/* FIXME: check if required */
- +void
- +nios2_store_return_value (struct type *valtype, void *valbuf)
- +{
- +#ifdef PORTINGTO61
- + int len = TYPE_LENGTH (valtype);
- +
- + /* return values of up to 8 bytes are returned in $r2 $r3 */
- +
- + if (len <= nios2_register_raw_size (R2_REGNUM))
- + write_register_bytes (REGISTER_BYTE (R2_REGNUM),
- + valbuf,
- + len);
- + else if (len <= (nios2_register_raw_size (R2_REGNUM)
- + + nios2_register_raw_size (R3_REGNUM)))
- + write_register_bytes (REGISTER_BYTE (R2_REGNUM),
- + valbuf,
- + len);
- +#endif
- +}
- +
- +#ifdef PORTINGTO61
- +
- +/* Setup the function arguments for calling a function in the inferior. */
- +static CORE_ADDR
- +nios2_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
- + int struct_return, CORE_ADDR struct_addr)
- +{
- + int argreg;
- + int argnum;
- + struct stack_arg
- + {
- + int len;
- + char *val;
- + } *stack_args;
- + int nstack_args = 0;
- +
- + stack_args = (struct stack_arg *) alloca (nargs * sizeof (struct stack_arg));
- +
- + /* The lowest register number containing arguments */
- + argreg = FIRST_ARGREG;
- +
- + /* Align the stack. It will be needed
- + if we call a function which has argument overflow. */
- + sp &= ~3;
- +
- + /* If this function returns a struct which does not fit in the
- + return registers, we must pass a buffer to the function
- + which it can use to save the return value. */
- + if (struct_return)
- + write_register (R2_REGNUM, struct_addr);
- +
- + /* FIXME: what about unions? */
- + for (argnum = 0; argnum < nargs; argnum++)
- + {
- + char *val = (char *) VALUE_CONTENTS (args[argnum]);
- + int len = TYPE_LENGTH (VALUE_TYPE (args[argnum]));
- + struct type *type = VALUE_TYPE (args[argnum]);
- + int olen;
- +
- + if ((argreg <= LAST_ARGREG && len <= (LAST_ARGREG - argreg + 1) * DEPRECATED_REGISTER_SIZE)
- + || (TYPE_CODE (type) == TYPE_CODE_STRUCT))
- + {
- + /* Something that will fit entirely into registers or go on the stack. */
- + while (len > 0 && argreg <= LAST_ARGREG)
- + { write_register (argreg, extract_unsigned_integer (val, DEPRECATED_REGISTER_SIZE));
- +
- + argreg++;
- + val += DEPRECATED_REGISTER_SIZE;
- + len -= DEPRECATED_REGISTER_SIZE;
- + }
- +
- + /* Any remainder for the stack is noted below... */
- + }
- + else if (TYPE_CODE (VALUE_TYPE (args[argnum])) != TYPE_CODE_STRUCT
- + && len > DEPRECATED_REGISTER_SIZE)
- + {
- + /* All subsequent args go onto the stack. */
- + argnum = LAST_ARGREG + 1;
- + }
- +
- + if (len > 0)
- + {
- + /* Note that this must be saved onto the stack */
- + stack_args[nstack_args].val = val;
- + stack_args[nstack_args].len = len;
- + nstack_args++;
- + }
- + }
- +
- + /* We're done with registers and stack allocation. Now do the actual
- + stack pushes. */
- + while (nstack_args--)
- + {
- + sp -= stack_args[nstack_args].len;
- + write_memory (sp, stack_args[nstack_args].val, stack_args[nstack_args].len);
- + }
- +
- + /* Return adjusted stack pointer. */
- + return sp;
- +}
- +
- +/* Function: push_return_address (pc)
- + Set up the return address for the inferior function call.*/
- +/* FIXME: Check if required */
- +static CORE_ADDR
- +nios2_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
- +{
- + write_register (RA_REGNUM, CALL_DUMMY_ADDRESS ());
- + return sp;
- +}
- +
- +/* Extract from an array regcache containing the (raw) register state
- + the address in which a function should return its structure value,
- + as a CORE_ADDR (or an expression that can be used as one). */
- +/* FIXME: Check if required */
- +
- +static CORE_ADDR
- +nios2_extract_struct_value_address (char *regbuf)
- +{
- + return (extract_address ((regbuf) + REGISTER_BYTE (R4_REGNUM),
- + REGISTER_RAW_SIZE (R4_REGNUM)));
- +}
- +
- +/* Store the address of the place in which to copy the structure the
- + subroutine will return. This is called from call_function. */
- +
- +/* FIXME: Check if required */
- +static void
- +nios2_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
- +{
- + write_register (R4_REGNUM, (addr));
- +}
- +#endif
- +
- +
- +/* This function analyzes the function prologue and tries to work
- + out where registers are saved and how long the prologue is.
- + The prologue will consist of the following parts:
- + 1) Optional profiling instrumentation. The old version uses six
- + instructions. We step over this if there is an exact match.
- + nextpc r8
- + mov r9, ra
- + movhi r10, %hiadj(.LP2)
- + addi r10, r10, %lo(.LP2)
- + call mcount
- + mov ra, r9
- + The new version uses two or three instructions (the last of
- + these might get merged in with the STW which saves RA to the
- + stack). We interpret these.
- + mov r8, ra
- + call mcount
- + mov ra, r8
- +
- + 2) Optional interrupt entry decision. Again, we step over
- + this if there is an exact match.
- + rdctl et,estatus
- + andi et,et,1
- + beq et,zero, <software_exception>
- + rdctl et,ipending
- + beq et,zero, <software_exception>
- +
- + 3) A stack adjustment or stack which, which will be one of:
- + addi sp, sp, -constant
- + or:
- + movi r8, constant
- + sub sp, sp, r8
- + or
- + movhi r8, constant
- + addi r8, r8, constant
- + sub sp, sp, r8
- + or
- + movhi rx, %hiadj(newstack)
- + addhi rx, rx, %lo(newstack)
- + stw sp, constant(rx)
- + mov sp, rx
- +
- + 4) An optional stack check, which can take either of these forms:
- + bgeu sp, rx, +8
- + break 3
- + or
- + bltu sp, rx, .Lstack_overflow
- + ...
- + .Lstack_overflow:
- + break 3
- +
- + 5) Saving any registers which need to be saved. These will
- + normally just be stored onto the stack:
- + stw rx, constant(sp)
- + but in the large frame case will use r8 as an offset back
- + to the cfa:
- + add r8, r8, sp
- + stw rx, -constant(r8)
- +
- + Saving control registers looks slightly different:
- + rdctl rx, ctlN
- + stw rx, constant(sp)
- +
- + 6) An optional FP setup, either if the user has requested a
- + frame pointer or if the function calls alloca.
- + This is always:
- + mov fp, sp
- +
- + The prologue instructions may be interleaved, and the register
- + saves and FP setup can occur in either order.
- +
- + To cope with all this variability we decode all the instructions
- + from the start of the prologue until we hit a branch, call or
- + return. For each of the instructions mentioned in 3, 4 and 5 we
- + handle the limited cases of stores to the stack and operations
- + on constant values.
- + */
- +
- +typedef struct
- +{
- + unsigned int insn;
- + unsigned int mask;
- +} wild_insn;
- +
- +static const wild_insn profiler_insn[] =
- +{
- + { 0x0010e03a, 0x00000000 }, // nextpc r8
- + { 0xf813883a, 0x00000000 }, // mov r9,ra
- + { 0x02800034, 0x003FFFC0 }, // movhi r10,257
- + { 0x52800004, 0x003FFFC0 }, // addi r10,r10,-31992
- + { 0x00000000, 0xFFFFFFC0 }, // call <mcount>
- + { 0x483f883a, 0x00000000 } // mov ra,r9
- +};
- +
- +static const wild_insn irqentry_insn[] =
- +{
- + { 0x0031307a, 0x00000000 }, // rdctl et,estatus
- + { 0xc600004c, 0x00000000 }, // andi et,et,1
- + { 0xc0000026, 0x003FFFC0 }, // beq et,zero, <software_exception>
- + { 0x0031313a, 0x00000000 }, // rdctl et,ipending
- + { 0xc0000026, 0x003FFFC0 } // beq et,zero, <software_exception>
- +};
- +
- +static void
- +nios2_setup_default(struct nios2_unwind_cache *cache)
- +{
- + int i;
- +
- + for (i = 0; i < NIOS2_NUM_REGS; i++)
- + {
- + /* All registers start off holding their previous values */
- + cache->reg_value[i].reg = i;
- + cache->reg_value[i].offset = 0;
- +
- + /* All registers start off not saved */
- + cache->reg_saved[i].basereg = -1;
- + cache->reg_saved[i].addr = 0;
- + }
- +}
- +
- +static int
- +nios2_match_sequence(CORE_ADDR start_pc, const wild_insn * sequence, int count)
- +{
- + CORE_ADDR pc = start_pc;
- + int i;
- + unsigned int insn;
- +
- + for (i = 0 ; i < count ; i++)
- + {
- + insn = read_memory_unsigned_integer (pc, NIOS2_OPCODE_SIZE);
- + if ((insn & ~sequence[i].mask) != sequence[i].insn)
- + return 0;
- +
- + pc += NIOS2_OPCODE_SIZE;
- + }
- +
- + return 1;
- +}
- +
- +
- +CORE_ADDR
- +nios2_analyze_prologue (const CORE_ADDR start_pc, const CORE_ADDR current_pc,
- + struct nios2_unwind_cache *cache, struct frame_info *next_frame)
- +{
- + /* Maximum lines of prologue to check */
- + /* Note that this number should not be too large, else we can potentially */
- + /* end up iterating through unmapped memory */
- + CORE_ADDR limit_pc = start_pc + 200;
- + int regno;
- +
- + /* Does the frame set up the FP register? */
- + int base_reg = 0;
- +
- + REG_VALUE * value = cache->reg_value;
- + REG_VALUE temp_value[NIOS2_NUM_REGS];
- +
- + int i;
- +
- + /* Save the starting PC so we can correct the pc after running */
- + /* through the prolog, using symbol info */
- + CORE_ADDR pc = start_pc;
- +
- + /* Is this an exception handler? */
- + int exception_handler = 0;
- +
- + /* What was the original value of SP (or fake original value for
- + * functions which switch stacks?
- + */
- + CORE_ADDR frame_high;
- +
- + /* Is this the end of the prologue? */
- + int within_prologue = 1;
- +
- + CORE_ADDR prologue_end;
- +
- + /* Is this the innermost function? */
- + int innermost = (frame_relative_level(next_frame) < 0);
- +
- +#ifdef DEBUG_PRINT
- + fprintf_unfiltered (gdb_stdlog,
- + "{ nios2_analyze_prologue start=0x%s, current=0x%s ",
- + paddr_nz (start_pc), paddr_nz (current_pc));
- +#endif
- +
- + /* Set up the default values of the registers. */
- + nios2_setup_default(cache);
- +
- + /* If the first few instructions are the profile entry then skip over them. */
- + /* Newer versions of the compiler use more efficient profiling code. */
- + if (nios2_match_sequence(pc, profiler_insn, sizeof(profiler_insn)/sizeof(profiler_insn[0])))
- + pc += sizeof(profiler_insn)/sizeof(profiler_insn[0]) * NIOS2_OPCODE_SIZE;
- +
- + /* If the first few are an interrupt entry then skip over them too */
- + if (nios2_match_sequence(pc, irqentry_insn, sizeof(irqentry_insn)/sizeof(irqentry_insn[0])))
- + {
- + pc += sizeof(irqentry_insn)/sizeof(irqentry_insn[0]) * NIOS2_OPCODE_SIZE;
- + exception_handler = 1;
- + }
- +
- + prologue_end = start_pc;
- +
- + /* Find the prologue instructions. */
- + /* Fortunately we're in 32bit paradise */
- + while (pc < limit_pc && within_prologue)
- + {
- + /* Present instruction. */
- + unsigned int insn;
- +
- + int prologue_insn = 0;
- +
- + if (pc == current_pc)
- + {
- + /*
- + * When we reach the current PC we must save the current register
- + * state (for the backtrace) but keep analysing because there might
- + * be more to find out (eg. is this an exception handler).
- + */
- + memcpy(temp_value, value, sizeof(temp_value));
- + value = temp_value;
- +#ifdef DEBUG_PRINT
- + fprintf_unfiltered (gdb_stdlog, "*");
- +#endif
- + }
- +
- + insn = read_memory_unsigned_integer (pc, NIOS2_OPCODE_SIZE);
- + pc += NIOS2_OPCODE_SIZE;
- +
- +#ifdef DEBUG_PRINT
- + fprintf_unfiltered (gdb_stdlog, "[%08X]", insn);
- +#endif
- +
- + /* The following instructions can appear in the prologue */
- +
- + if ((insn & 0x0001FFFF) == 0x0001883A)
- + {
- + /* ADD rc, ra, rb (also used for MOV) */
- +
- + int ra = GET_IW_A(insn);
- + int rb = GET_IW_B(insn);
- + int rc = GET_IW_C(insn);
- +
- + if (rc == SP_REGNUM && rb == 0 && value[ra].reg == cache->reg_saved[SP_REGNUM].basereg)
- + {
- + /* If the previous value of SP is available somewhere near the new
- + * stack pointer value then this is a stack switch.
- + */
- +
- + /* If any registers were saved on the stack before then we can't backtrace
- + * into them now.
- + */
- + for (i = 0 ; i < NIOS2_NUM_REGS ; i++)
- + {
- + if (cache->reg_saved[i].basereg == SP_REGNUM)
- + cache->reg_saved[i].basereg = -1;
- + if (value[i].reg == SP_REGNUM)
- + value[i].reg = -1;
- + }
- +
- + /* Create a fake "high water mark" 4 bytes above where SP was stored
- + * and fake up the registers to be consistent with that.
- + */
- + value[SP_REGNUM].reg = SP_REGNUM;
- + value[SP_REGNUM].offset = value[ra].offset - cache->reg_saved[SP_REGNUM].addr - 4;
- +
- + cache->reg_saved[SP_REGNUM].basereg = SP_REGNUM;
- + cache->reg_saved[SP_REGNUM].addr = -4;
- + }
- +
- + else if (rc != 0)
- + {
- + if (value[rb].reg == 0)
- + value[rc].reg = value[ra].reg;
- + else if (value[ra].reg == 0)
- + value[rc].reg = value[rb].reg;
- + else
- + value[rc].reg = -1;
- +
- + value[rc].offset = value[ra].offset + value[rb].offset;
- + }
- + prologue_insn = 1;
- + }
- +
- + else if ((insn & 0x0001FFFF) == 0x0001983A)
- + {
- + /* SUB rc, ra, rb */
- +
- + int ra = GET_IW_A(insn);
- + int rb = GET_IW_B(insn);
- + int rc = GET_IW_C(insn);
- +
- + if (rc != 0)
- + {
- + if (value[rb].reg == 0)
- + value[rc].reg = value[ra].reg;
- + else
- + value[rc].reg = -1;
- +
- + value[rc].offset = value[ra].offset - value[rb].offset;
- + }
- + }
- +
- + else if ((insn & 0x0000003F) == 0x00000004)
- + {
- + /* ADDI rb, ra, immed (also used for MOVI) */
- + short immed = GET_IW_IMM16(insn);
- + int ra = GET_IW_A(insn);
- + int rb = GET_IW_B(insn);
- +
- + if (rb == SP_REGNUM)
- + {
- + /* The first stack adjustment is part of the prologue. Any subsequent
- + stack adjustments are either down to alloca or the epilogue so stop
- + analysing when we hit them. */
- + if (value[rb].offset != 0 || value[ra].reg != SP_REGNUM)
- + break;
- + }
- +
- + if (rb != 0)
- + {
- + value[rb].reg = value[ra].reg;
- + value[rb].offset = value[ra].offset + immed;
- + }
- +
- + prologue_insn = 1;
- + }
- +
- + else if ((insn & 0x0000003F) == 0x00000034)
- + {
- + /* ORHI rb, ra, immed (also used for MOVHI) */
- + unsigned int immed = GET_IW_IMM16(insn);
- + int ra = GET_IW_A(insn);
- + int rb = GET_IW_B(insn);
- +
- + if (rb != 0)
- + {
- + value[rb].reg = (value[ra].reg == 0) ? 0 : -1;
- + value[rb].offset = value[ra].offset | (immed << 16);
- + }
- + }
- +
- + else if (((insn & IW_OP_MASK) == OP_STW || (insn & IW_OP_MASK) == OP_STWIO))
- + {
- + /* STW rb, immediate(ra) */
- +
- + short immed16 = GET_IW_IMM16(insn);
- + int ra = GET_IW_A(insn);
- + int rb = GET_IW_B(insn);
- +
- + /* Are we storing the original value of a register? For exception handlers
- + * the value of EA-4 (return address from interrupts etc) is sometimes stored.
- + */
- + int orig = value[rb].reg;
- + if (orig > 0 && (value[rb].offset == 0 || (orig == EA_REGNUM && value[rb].offset == -4)))
- + {
- + /* We are most interested in stores to the stack, but will also take note
- + * of stores to other places as they might be useful later.
- + */
- + if ((value[ra].reg == SP_REGNUM && cache->reg_saved[orig].basereg != SP_REGNUM) ||
- + cache->reg_saved[orig].basereg == -1)
- + {
- + if (pc < current_pc)
- + {
- + /* Save off callee saved registers */
- + cache->reg_saved[orig].basereg = value[ra].reg;
- + cache->reg_saved[orig].addr = value[ra].offset + GET_IW_IMM16(insn);
- + }
- +
- + prologue_insn = 1;
- +
- + if (orig == EA_REGNUM || orig == ESTATUS_REGNUM)
- + exception_handler = 1;
- + }
- + }
- + }
- +
- + else if ((insn & 0xFFC1F83F) == 0x0001303A)
- + {
- + /* RDCTL rC, ctlN */
- + int rc = GET_IW_C(insn);
- + int n = GET_IW_CONTROL_REGNUM(insn);
- +
- + if (rc != 0)
- + {
- + value[rc].reg = STATUS_REGNUM + n;
- + value[rc].offset = 0;
- + }
- +
- + prologue_insn = 1;
- + }
- +
- + else if ((insn & 0x0000003F) == 0 &&
- + value[8].reg == RA_REGNUM && value[8].offset == 0 &&
- + value[SP_REGNUM].reg == SP_REGNUM && value[SP_REGNUM].offset == 0)
- + {
- + /* A CALL instruction. This is treated as a call to mcount if ra
- + * has been stored into r8 beforehand and if it's before the stack adjust.
- + * mcount corrupts r2-r3, r9-r15 & ra
- + */
- + for (i = 2 ; i <= 3 ; i++)
- + value[i].reg = -1;
- + for (i = 9 ; i <= 15 ; i++)
- + value[i].reg = -1;
- + value[RA_REGNUM].reg = -1;
- +
- + prologue_insn = 1;
- + }
- +
- + else if ((insn & 0xF83FFFFF) == 0xD800012E)
- + {
- + /* BGEU sp, rx, +8
- + * BREAK 3
- + * This instruction sequence is used in stack checking - we can ignore it
- + */
- + unsigned int next_insn = read_memory_unsigned_integer(pc, NIOS2_OPCODE_SIZE);
- +
- + if (next_insn != 0x003DA0FA)
- + within_prologue = 0;
- + else
- + pc += NIOS2_OPCODE_SIZE;
- + }
- +
- + else if ((insn & 0xF800003F) == 0xD8000036)
- + {
- + /* BLTU sp, rx, .Lstackoverflow
- + * If the location branched to holds a BREAK 3 instruction then this is
- + * also stack overflow detection. We can ignore it.
- + */
- + CORE_ADDR target_pc = pc + ((insn & 0x3FFFC0) >> 6);
- + unsigned int target_insn = read_memory_unsigned_integer(target_pc, NIOS2_OPCODE_SIZE);
- +
- + if (target_insn != 0x003DA0FA)
- + within_prologue = 0;
- + }
- +
- + /* Any other instructions are allowed to be moved up into the prologue. If we
- + reach a branch, call or return then the prologue is considered over */
- + /* We also consider a second stack adjustment as terminating the prologue (see
- + above) */
- +
- + else
- + {
- + switch (GET_IW_OP(insn))
- + {
- + case OP_BEQ:
- + case OP_BGE:
- + case OP_BGEU:
- + case OP_BLT:
- + case OP_BLTU:
- + case OP_BNE:
- + case OP_BR:
- + case OP_CALL:
- + within_prologue = 0;
- + break;
- + case OP_OPX:
- + if (GET_IW_OPX(insn) == OPX_RET ||
- + GET_IW_OPX(insn) == OPX_ERET ||
- + GET_IW_OPX(insn) == OPX_BRET ||
- + GET_IW_OPX(insn) == OPX_CALLR ||
- + GET_IW_OPX(insn) == OPX_JMP)
- + {
- + within_prologue = 0;
- + }
- + default:
- + break;
- + }
- + }
- +
- + if (prologue_insn)
- + prologue_end = pc;
- + }
- +
- + /* Are we within the function epilogue? If so then we should go back to the
- + original register values */
- + if (innermost && current_pc > start_pc)
- + {
- + /* First check whether the previous instruction was a stack
- + adjustment. */
- + unsigned int insn = read_memory_unsigned_integer (current_pc - NIOS2_OPCODE_SIZE, NIOS2_OPCODE_SIZE);
- +
- + if ((insn & 0xFFC0003C) == 0xDEC00004 || /* ADDI sp, sp, */
- + (insn & 0xFFC1FFFF) == 0xDEC1883A || /* ADD sp, sp, */
- + (insn & 0xFFC0003F) == 0xDEC00017) /* LDW sp, constant(sp) */
- + {
- + /* Then check if it's followed by a return or a tail call */
- + insn = read_memory_unsigned_integer (current_pc, NIOS2_OPCODE_SIZE);
- +
- + if (insn == 0xF800283A || /* RET */
- + insn == 0xE800083A || /* ERET */
- + (insn & 0x07FFFFFF) == 0x0000683A || /* JMP */
- + (insn & 0xFFC0003F) == 6) /* BR */
- + {
- + /* Go back to default value of the registers */
- + nios2_setup_default(cache);
- + }
- + }
- + }
- +
- + /* Exception handlers use a different return address register. */
- + if (exception_handler)
- + cache->return_regnum = EA_REGNUM;
- +
- +#ifdef DEBUG_PRINT
- + fprintf_unfiltered (gdb_stdlog, "\n-> retreg=%d, ", cache->return_regnum);
- +#endif
- +
- + if (cache->reg_value[FP_REGNUM].reg == SP_REGNUM)
- + {
- + /* If the FP now holds an offset from the CFA then this is a normal
- + frame which uses the frame pointer. */
- + base_reg = FP_REGNUM;
- + }
- + else if (cache->reg_value[SP_REGNUM].reg == SP_REGNUM)
- + {
- + /* FP doesn't hold an offset from the CFA. If SP still holds an
- + offset from the CFA then we might be in a function which omits
- + the frame pointer, or we might be partway through the prologue.
- + In both cases we can find the CFA using SP. */
- + base_reg = SP_REGNUM;
- + }
- + else
- + {
- + /* Somehow the stack pointer has been corrupted. We can't return. */
- +#ifdef DEBUG_PRINT
- + fprintf_unfiltered (gdb_stdlog, "<can't reach cfa> }\n");
- +#endif
- + return 0;
- + }
- +
- + if (cache->reg_value[base_reg].offset == 0 ||
- + cache->reg_saved[RA_REGNUM].basereg != SP_REGNUM ||
- + cache->reg_saved[cache->return_regnum].basereg != SP_REGNUM)
- + {
- + /*
- + * If the frame didn't adjust the stack, didn't save RA or didn't save
- + * EA in an exception handler then it must either be a leaf function
- + * (doesn't call any other functions) or it can't return. If it has
- + * called another function then it can't be a leaf, so set base == 0
- + * to indicate that we can't backtrace past it.
- + */
- +
- + if (!innermost)
- + {
- + /* If it isn't the innermost function then it can't be a leaf, unless
- + * it was interrupted. Check whether RA for this frame is the same
- + * as PC. If so then it probably wan't interrupted.
- + */
- + char buf[8];
- + CORE_ADDR ra;
- +
- + frame_unwind_register (next_frame, RA_REGNUM, buf);
- + ra = extract_typed_address (buf, builtin_type_void_func_ptr);
- +
- + if (ra == current_pc)
- + {
- +#ifdef DEBUG_PRINT
- + fprintf_unfiltered (gdb_stdlog, "<noreturn ADJUST 0x%s, r31@r%d+?>, r%d@r%d+?> }\n",
- + paddr_nz(cache->reg_value[base_reg].offset),
- + cache->reg_saved[RA_REGNUM].basereg,
- + cache->return_regnum, cache->reg_saved[cache->return_regnum].basereg);
- +#endif
- + return 0;
- + }
- + }
- + }
- +
- + /* Get the value of whichever register we are using for the base. */
- + cache->base = frame_unwind_register_unsigned (next_frame, base_reg);
- +
- + /* What was the value of SP at the start of this function (or just
- + * after the stack switch).
- + */
- + frame_high = cache->base - cache->reg_value[base_reg].offset;
- +
- + /* Adjust all the saved registers such that they contain addresses
- + instead of offsets. */
- + for (i = 0; i < NIOS2_NUM_REGS; i++)
- + if (cache->reg_saved[i].basereg == SP_REGNUM)
- + {
- + cache->reg_saved[i].basereg = Z_REGNUM;
- + cache->reg_saved[i].addr += frame_high;
- + }
- +
- + for (i = 0; i < NIOS2_NUM_REGS; i++)
- + if (cache->reg_saved[i].basereg == GP_REGNUM)
- + {
- + CORE_ADDR gp = frame_unwind_register_unsigned (next_frame, GP_REGNUM);
- +
- + for ( ; i < NIOS2_NUM_REGS; i++)
- + if (cache->reg_saved[i].basereg == GP_REGNUM)
- + {
- + cache->reg_saved[i].basereg = Z_REGNUM;
- + cache->reg_saved[i].addr += gp;
- + }
- + }
- +
- + /* Work out what the value of SP was on the first instruction of this
- + * function. If we didn't switch stacks then this can be trivially
- + * computed from the base address.
- + */
- + if (cache->reg_saved[SP_REGNUM].basereg == Z_REGNUM)
- + {
- + cache->cfa = read_memory_unsigned_integer(cache->reg_saved[SP_REGNUM].addr, 4);
- + }
- + else
- + cache->cfa = frame_high;
- +
- + /* Exception handlers restore ESTATUS into STATUS. */
- + if (exception_handler)
- + {
- + cache->reg_saved[STATUS_REGNUM] = cache->reg_saved[ESTATUS_REGNUM];
- + cache->reg_saved[ESTATUS_REGNUM].basereg = -1;
- + }
- +
- +#ifdef DEBUG_PRINT
- + fprintf_unfiltered (gdb_stdlog, "cfa=0x%s }\n", paddr_nz(cache->cfa));
- +#endif
- +
- + return prologue_end;
- +}
- +
- +struct frame_info *
- +setup_arbitrary_frame (int argc, CORE_ADDR *argv)
- +{
- + if (argc != 2)
- + error ("Nios II frame specifications require two arguments: sp and pc");
- +
- + return create_new_frame (argv[0], argv[1]);
- +}
- +
- +#ifdef PORTINGTO61
- +/* Should be handled by unwind informations. */
- +/* However, doing this manually until we can find */
- +/* use the CFA information to examine the stack */
- +void
- +nios2_frame_init_saved_regs (struct frame_info *fi)
- +{
- + CORE_ADDR ip;
- +
- + /* Examine the entire prologue. */
- + register int frameless_p = 0;
- +
- + /* Has this frame's registers already been initialized? */
- + if (fi->saved_regs)
- + return;
- +
- + frame_saved_regs_zalloc (fi);
- +
- + ip = get_pc_function_start (fi->pc);
- + nios2_examine (ip, fi, frameless_p);
- +}
- +#endif
- +
- +
- +/* Given a PC value corresponding to the start of a function, return the PC
- + of the first instruction after the function prologue. */
- +
- +CORE_ADDR
- +nios2_skip_prologue (CORE_ADDR start_pc)
- +{
- + CORE_ADDR func_addr, func_end;
- + struct symtab_and_line sal;
- + CORE_ADDR pc_after_prologue;
- +
- + /* If we have line debugging information, then the end of the prologue
- + should the first assembly instruction of the first source line. */
- + if (find_pc_partial_function (start_pc, NULL, &func_addr, &func_end))
- + {
- + sal = find_pc_line (func_addr, 0);
- + if (sal.end > 0 && sal.end < func_end)
- + return sal.end;
- + }
- +
- + return start_pc;
- +}
- +
- +/* nios2_software_single_step() is called just before we want to resume
- + the inferior, if we want to single-step it but there is no hardware
- + or kernel single-step support (NIOS2 on GNU/Linux for example). We find
- + the target of the coming instruction and breakpoint it.
- +
- + single_step is also called just after the inferior stops. If we had
- + set up a simulated single-step, we undo our damage. */
- +
- +void
- +nios2_software_single_step (enum target_signal sig, int insert_breakpoints_p)
- +{
- + int ii;
- + unsigned int insn;
- + CORE_ADDR pc;
- + CORE_ADDR breaks[2];
- + int imme;
- +
- + if (insert_breakpoints_p)
- + {
- + pc = read_pc ();
- + breaks[0] = pc + 4;
- + breaks[1] = -1;
- + insn = read_memory_unsigned_integer (pc, 4);
- +
- + /* Calculate the destination of a branch/jump */
- + switch (GET_IW_OP(insn))
- + {
- + /* I-type branch */
- + case OP_BEQ:
- + case OP_BGE:
- + case OP_BGEU:
- + case OP_BLT:
- + case OP_BLTU:
- + case OP_BNE:
- + imme = (short) GET_IW_IMM16(insn);
- + breaks[1] = pc + 4 + imme;
- + break;
- + case OP_BR:
- + imme = (short) GET_IW_IMM16(insn);
- + breaks[0] = pc + 4 + imme;
- + break;
- + /* J-type branch */
- + case OP_CALL:
- + case OP_JMPI:
- + imme = GET_IW_IMM26(insn);
- + breaks[0] = (pc & 0xf0000000) | (imme * 4);
- + break;
- + /* R-type branch */
- + case OP_OPX:
- + switch (GET_IW_OPX(insn))
- + {
- + case OPX_CALLR:
- + case OPX_JMP:
- + case OPX_RET:
- + imme = read_register (GET_IW_A(insn));
- + breaks[0] = imme;
- + break;
- + }
- + break;
- + }
- +
- + /* Don't put two breakpoints on the same address. */
- + if (breaks[1] == breaks[0])
- + breaks[1] = -1;
- +
- + for (ii = 0; ii < 2; ++ii)
- + {
- + /* ignore invalid breakpoint. */
- + if (breaks[ii] == -1)
- + continue;
- + insert_single_step_breakpoint (breaks[ii]);
- + }
- + }
- + else
- + remove_single_step_breakpoints ();
- +
- +}
- +
- +const unsigned char*
- +nios2_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size)
- +{
- + /* break encoding: 31->27 26->22 21->17 16->11 10->6 5->0 */
- + /* 00000 00000 0x1e 0x34 00000 0x3a */
- + /* 00000 00000 11110 110100 00000 111010 */
- + /* In bytes: 00000000 00111101 10100000 00111010 */
- + /* 0x0 0x3d 0xa0 0x3a */
- +#if 0
- + static unsigned char breakpoint[] = {0x3a, 0xa0, 0x3d, 0x0};
- +#else
- + static unsigned char breakpoint[] = {0x7a, 0x68, 0x3b, 0x0}; /* Trap instr. w/imm=0x01 */
- +#endif
- + *bp_size = 4;
- + return breakpoint;
- +}
- +
- +
- +int
- +gdb_print_insn_nios2 (bfd_vma memaddr, disassemble_info *info)
- +{
- + if (info->endian == BFD_ENDIAN_BIG)
- + {
- + return print_insn_big_nios2 (memaddr, info);
- + }
- + else
- + {
- + return print_insn_little_nios2 (memaddr, info);
- + }
- +}
- +
- +
- +
- +/* Adjust the address downward (direction of stack growth) so that it
- + is correctly aligned for a new stack frame. */
- +
- +/* ??? Big endian issues here? */
- +
- +static CORE_ADDR
- +nios2_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
- +{
- + return align_down (addr, 4);
- +}
- +
- +
- +
- +/* We don't convert anything at the moment */
- +static int
- +nios2_convert_register_p (int regnum, struct type *type)
- +{
- + return 0;
- +}
- +
- +static void
- +nios2_register_to_value (struct frame_info *frame, int regnum,
- + struct type *type, void *to)
- +{
- + get_frame_register (frame, regnum + 0, (char *) to + 0);
- + get_frame_register (frame, regnum + 0, (char *) to + 0);
- +}
- +
- +static void
- +nios2_value_to_register (struct frame_info *frame, int regnum,
- + struct type *type, const void *from)
- +{
- + put_frame_register (frame, regnum + 0, (const char *) from + 0);
- + put_frame_register (frame, regnum + 0, (const char *) from + 0);
- +}
- +
- +/* Determine, for architecture GDBARCH, how a return value of TYPE
- + should be returned. If it is supposed to be returned in registers,
- + and READBUF is non-zero, read the appropriate value from REGCACHE,
- + and copy it into READBUF. If WRITEBUF is non-zero, write the value
- + from WRITEBUF into REGCACHE. */
- +
- +static enum return_value_convention
- +nios2_return_value (struct gdbarch *gdbarch, struct type *type,
- + struct regcache *regcache, void *readbuf,
- + const void *writebuf)
- +{
- + enum type_code code = TYPE_CODE (type);
- +
- + /* FIXME PBrookes add struct return function */
- + if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
- + /*&& !nios2_reg_struct_return_p (gdbarch, type)*/)
- + return RETURN_VALUE_STRUCT_CONVENTION;
- +
- +
- + if (readbuf)
- + nios2_extract_return_value (type, regcache, readbuf);
- + if (writebuf)
- + nios2_store_return_value (type, regcache);
- +
- + return RETURN_VALUE_REGISTER_CONVENTION;
- +}
- +
- +/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
- + dummy frame. The frame ID's base needs to match the TOS value
- + saved by save_dummy_frame_tos() and returned from
- + nios2_push_dummy_call, and the PC needs to match the dummy frame's
- + breakpoint. */
- +
- +static struct frame_id
- +nios2_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
- +{
- + return frame_id_build (frame_unwind_register_unsigned (next_frame, SP_REGNUM),
- + frame_pc_unwind (next_frame));
- +}
- +
- +static CORE_ADDR
- +nios2_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
- +{
- + char buf[8];
- +
- + frame_unwind_register (next_frame, PC_REGNUM, buf);
- + return extract_typed_address (buf, builtin_type_void_func_ptr);
- +}
- +
- +
- +/* Frame base handling. */
- +
- +struct nios2_unwind_cache *
- +nios2_frame_unwind_cache (struct frame_info *next_frame,
- + void **this_prologue_cache)
- +{
- + CORE_ADDR current_pc;
- + struct nios2_unwind_cache *cache;
- + int i;
- +
- + if (*this_prologue_cache)
- + return *this_prologue_cache;
- +
- + cache = FRAME_OBSTACK_ZALLOC (struct nios2_unwind_cache);
- + (*this_prologue_cache) = cache;
- +
- + /* Zero all fields. */
- + cache->base = 0;
- + cache->cfa = 0;
- + cache->pc = 0;
- +
- + cache->return_regnum = RA_REGNUM;
- +
- + nios2_setup_default(cache);
- +
- + cache->pc = frame_func_unwind (next_frame);
- + current_pc = frame_pc_unwind (next_frame);
- +
- + /* Prologue analysis does the rest... */
- + if (cache->pc != 0)
- + nios2_analyze_prologue (cache->pc, current_pc, cache, next_frame);
- +
- + return cache;
- +}
- +
- +static void
- +nios2_frame_this_id (struct frame_info *next_frame, void **this_cache,
- + struct frame_id *this_id)
- +{
- + struct nios2_unwind_cache *cache =
- + nios2_frame_unwind_cache (next_frame, this_cache);
- +
- + /* This marks the outermost frame. */
- + if (cache->base == 0)
- + return;
- +
- + (*this_id) = frame_id_build (cache->cfa, cache->pc);
- +}
- +
- +static void
- +nios2_frame_prev_register (struct frame_info *next_frame, void **this_cache,
- + int regnum, int *optimizedp,
- + enum lval_type *lvalp, CORE_ADDR *addrp,
- + int *realnump, void *valuep)
- +{
- + struct nios2_unwind_cache *cache =
- + nios2_frame_unwind_cache (next_frame, this_cache);
- +
- + gdb_assert (regnum >= 0);
- +
- + /* The PC of the previous frame is stored in the RA register of
- + the current frame. Frob regnum so that we pull the value from
- + the correct place. */
- + if (regnum == PC_REGNUM)
- + regnum = cache->return_regnum;
- +
- + /* If we've worked out where a register is stored then load it from there.
- + */
- + if (regnum < NIOS2_NUM_REGS && cache->reg_saved[regnum].basereg == Z_REGNUM)
- + {
- + *optimizedp = 0;
- + *lvalp = lval_memory;
- + *addrp = cache->reg_saved[regnum].addr;
- + *realnump = -1;
- + if (valuep)
- + {
- + /* Read the value in from memory. */
- + read_memory (*addrp, valuep,
- + register_size (current_gdbarch, regnum));
- + }
- + return;
- + }
- +
- + if (regnum == SP_REGNUM && cache->cfa)
- + {
- + *optimizedp = 0;
- + *lvalp = not_lval;
- + *addrp = 0;
- + *realnump = -1;
- + if (valuep)
- + {
- + /* Store the value. */
- + store_unsigned_integer (valuep, 8, cache->cfa);
- + }
- + return;
- + }
- +
- + frame_register_unwind (next_frame, regnum,
- + optimizedp, lvalp, addrp, realnump, valuep);
- +}
- +
- +
- +
- +static const struct frame_unwind nios2_frame_unwind =
- +{
- + NORMAL_FRAME,
- + nios2_frame_this_id,
- + nios2_frame_prev_register
- +};
- +
- +static CORE_ADDR
- +nios2_frame_base_address (struct frame_info *next_frame, void **this_cache)
- +{
- + struct nios2_unwind_cache *info
- + = nios2_frame_unwind_cache (next_frame, this_cache);
- + return info->base;
- +}
- +
- +static const struct frame_base nios2_frame_base =
- +{
- + &nios2_frame_unwind,
- + nios2_frame_base_address,
- + nios2_frame_base_address,
- + nios2_frame_base_address
- +};
- +
- +static const struct frame_unwind *
- +nios2_frame_sniffer (struct frame_info *next_frame)
- +{
- + return &nios2_frame_unwind;
- +}
- +
- +
- +static struct gdbarch *
- +nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
- +{
- + struct gdbarch *gdbarch;
- + int register_bytes, i;
- +
- + /* Change the register names based on the current machine type. */
- + if (info.bfd_arch_info->arch != bfd_arch_nios2)
- + return NULL;
- +
- + /* None found, create a new architecture from the information
- + provided. We don't have any architecture specific state, so just
- + pass in 0 for the struct gdbarch_tdep parameter. */
- + gdbarch = gdbarch_alloc (&info, NULL);
- +
- + /* Data type sizes. */
- + set_gdbarch_ptr_bit (gdbarch, 32);
- + set_gdbarch_addr_bit (gdbarch, 32);
- + set_gdbarch_short_bit (gdbarch, 16);
- + set_gdbarch_int_bit (gdbarch, 32);
- + set_gdbarch_long_bit (gdbarch, 32);
- + set_gdbarch_long_long_bit (gdbarch, 64);
- + set_gdbarch_float_bit (gdbarch, 32);
- + set_gdbarch_double_bit (gdbarch, 64);
- +
- + switch (info.byte_order)
- + {
- + case BFD_ENDIAN_BIG:
- + set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big);
- + set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_big);
- + break;
- +
- + case BFD_ENDIAN_LITTLE:
- + set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
- + set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_little);
- + break;
- +
- + default:
- + internal_error (__FILE__, __LINE__,
- + "nios2_gdbarch_init: bad byte ordering");
- + break;
- + }
- +
- + /* The register set. */
- + set_gdbarch_num_regs (gdbarch, NIOS2_NUM_REGS);
- + set_gdbarch_sp_regnum (gdbarch, SP_REGNUM);
- + set_gdbarch_pc_regnum (gdbarch, PC_REGNUM); /* Pseudo register PC */
- +
- + set_gdbarch_register_name (gdbarch, nios2_register_name);
- + /* Length of ordinary registers used in push_word and a few other
- + places. DEPRECATED_REGISTER_RAW_SIZE is the real way to know how
- + big a register is. */
- +/* FIXME
- + set_gdbarch_deprecated_register_size (gdbarch, 4);
- + set_gdbarch_deprecated_register_virtual_type (gdbarch,
- + nios2_register_virtual_type);
- +*/
- +
- + set_gdbarch_register_type (gdbarch, nios2_register_type);
- +
- + /* The "default" register numbering scheme for AMD64 is referred to
- + as the "DWARF Register Number Mapping" in the System V psABI.
- + The preferred debugging format for all known Nios II targets is
- + actually DWARF2, and GCC doesn't seem to support DWARF (that is
- + DWARF-1), but we provide the same mapping just in case. This
- + mapping is also used for stabs, which GCC does support. */
- + set_gdbarch_stab_reg_to_regnum (gdbarch, nios2_dwarf_reg_to_regnum);
- + set_gdbarch_dwarf_reg_to_regnum (gdbarch, nios2_dwarf_reg_to_regnum);
- + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, nios2_dwarf_reg_to_regnum);
- +
- + set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- +
- + /* Call dummy code. */
- + set_gdbarch_frame_align (gdbarch, nios2_frame_align);
- +
- + /* Some registers require conversion from raw format to virtual format. */
- +/* FIXME
- + set_gdbarch_deprecated_register_convertible (gdbarch, nios2_register_convertible);
- +*/
- +
- + set_gdbarch_convert_register_p (gdbarch, nios2_convert_register_p);
- + set_gdbarch_register_to_value (gdbarch, nios2_register_to_value);
- + set_gdbarch_value_to_register (gdbarch, nios2_value_to_register);
- +
- + set_gdbarch_return_value (gdbarch, nios2_return_value);
- +
- + set_gdbarch_skip_prologue (gdbarch, nios2_skip_prologue);
- + set_gdbarch_breakpoint_from_pc (gdbarch, nios2_breakpoint_from_pc);
- + set_gdbarch_software_single_step (gdbarch, nios2_software_single_step);
- +
- + set_gdbarch_unwind_dummy_id (gdbarch, nios2_unwind_dummy_id);
- + set_gdbarch_unwind_pc (gdbarch, nios2_unwind_pc);
- +
- + /* The dwarf2 unwinder will normally produce the best results if the
- + debug information is available, so register it first. */
- + frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
- +
- + /* FIXME: PBrookes - copied from AMD64-TDEP.c (kettenis/20021026):
- + This is ELF-specific. Fine for now, since all supported NIOS II
- + targets are ELF, but that might change in the future. */
- +/* FIXME again.. Does not exist anymore...
- + set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
- +*/
- +
- + frame_unwind_append_sniffer (gdbarch, nios2_frame_sniffer);
- +
- + frame_base_set_default (gdbarch, &nios2_frame_base);
- +
- + set_gdbarch_print_insn (gdbarch, gdb_print_insn_nios2);
- +
- + return gdbarch;
- +}
- +
- +void
- +_initialize_nios2_tdep (void)
- +{
- + register_gdbarch_init (bfd_arch_nios2, nios2_gdbarch_init);
- +
- + int i, offset = 0;
- +
- + /* Do not display anything after NIOS2_MAX_REG_DISPLAYED_REGNUM */
- + for (i = 0; i <= NIOS2_MAX_REG_DISPLAYED_REGNUM; i++)
- + {
- + nios2_register_byte_table[i] = offset;
- + offset += nios2_register_info_table[i].size;
- + }
- +
- + for (i = NIOS2_MAX_REG_DISPLAYED_REGNUM + 1; i <= NIOS2_NUM_REGS; i++)
- + {
- + nios2_register_byte_table[i] = -1;
- + }
- +
- +}
- diff --git a/gdb/regformats/reg-nios2.dat b/gdb/regformats/reg-nios2.dat
- new file mode 100644
- index 0000000..77b39a9
- --- /dev/null
- +++ b/gdb/regformats/reg-nios2.dat
- @@ -0,0 +1,46 @@
- +name:nios2
- +expedite:sp,fp,pc
- +32:zero
- +32:at
- +32:r2
- +32:r3
- +32:r4
- +32:r5
- +32:r6
- +32:r7
- +32:r8
- +32:r9
- +32:r10
- +32:r11
- +32:r12
- +32:r13
- +32:r14
- +32:r15
- +32:r16
- +32:r17
- +32:r18
- +32:r19
- +32:r20
- +32:r21
- +32:r22
- +32:r23
- +32:et
- +32:bt
- +32:gp
- +32:sp
- +32:fp
- +32:ea
- +32:ba
- +32:ra
- +32:pc
- +32:status
- +32:estatus
- +32:bstatus
- +32:ienable
- +32:ipending
- +32:cpuid
- +32:ctl6
- +32:ctl7
- +32:pteaddr
- +32:tlbacc
- +32:tlbmisc
- diff --git a/gdb/testsuite/config/nios2-iss.exp b/gdb/testsuite/config/nios2-iss.exp
- new file mode 100644
- index 0000000..624f831
- --- /dev/null
- +++ b/gdb/testsuite/config/nios2-iss.exp
- @@ -0,0 +1,233 @@
- +# Test framework for GDB (remote protocol) using a "gdbserver",
- +# ie. a debug agent running as a native process on the same or
- +# a different host.
- +
- +# Copyright 2000, 2002 Free Software Foundation, Inc.
- +
- +# This program is free software; you can redistribute it and/or modify
- +# it under the terms of the GNU General Public License as published by
- +# the Free Software Foundation; either version 2 of the License, or
- +# (at your option) any later version.
- +#
- +# This program is distributed in the hope that it will be useful,
- +# but WITHOUT ANY WARRANTY; without even the implied warranty of
- +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- +# GNU General Public License for more details.
- +#
- +# You should have received a copy of the GNU General Public License
- +# along with this program; if not, write to the Free Software
- +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- +
- +# Please email any bugs, comments, and/or additions to this file to:
- +# bug-gdb@prep.ai.mit.edu
- +
- +# This file was written by Michael Snyder. (msnyder@redhat.com)
- +
- +#
- +# This module to be used for testing gdb with a "gdbserver"
- +# built either from libremote or from gdb/gdbserver.
- +#
- +
- +# Load the basic testing library, and the remote stuff.
- +load_lib ../config/monitor.exp
- +
- +#
- +# To be addressed or set in your baseboard config file:
- +#
- +# set_board_info gdb_protocol "remote"
- +# Unles you have a gdbserver that uses a different protocol...
- +#
- +# set_board_info use_gdb_stub 1
- +# This tells the rest of the test suite not to do things
- +# like "run" which don't work well on remote targets.
- +#
- +# set_board_info gdb,do_reload_on_run 1
- +# Unles you have a gdbserver that can handle multiple sessions.
- +#
- +# set_board_info noargs 1
- +# At present there is no provision in the remote protocol
- +# for passing arguments. This test framework does not
- +# address the issue, so it's best to set this variable
- +# in your baseboard configuration file.
- +# FIXME: there's no reason why the test harness couldn't
- +# pass commandline args when it spawns gdbserver.
- +#
- +# set_board_info gdb,noinferiorio 1
- +# Neither the traditional gdbserver nor the one in libremote
- +# can presently capture stdout and relay it to GDB via the
- +# 'O' packet. This means that tests involving printf will
- +# fail unles you set this varibale in your baseboard
- +# configuration file.
- +#
- +# set_board_info gdb,no_hardware_watchpoints 1
- +# Unles you have a gdbserver that supports hardware watchpoints.
- +# FIXME: gdb should detect if the target doesn't support them,
- +# and fall back to using software watchpoints.
- +#
- +# set_board_info gdb_server_prog
- +# This will be the path to the gdbserver program you want to test.
- +# Defaults to "gdbserver".
- +#
- +# set_board_info sockethost
- +# The name of the host computer whose socket is being used.
- +# Defaults to "localhost". Note: old gdbserver requires
- +# that you define this, but libremote/gdbserver does not.
- +#
- +# set_board_info socketport
- +# Port id to use for socket connection. If not set explicitly,
- +# it will start at "9996" and increment for each use.
- +#
- +
- +
- +
- +#
- +# gdb_load -- load a file into the debugger.
- +# return a -1 if anything goes wrong.
- +#
- +
- +global server_exec;
- +global portnum;
- +set portnum "9996";
- +
- +proc gdb_load { arg } {
- + global host_exec;
- + global server_exec;
- + global portnum;
- + global verbose;
- + global gdb_prompt;
- +
- + regsub "/cygdrive/c" $arg "c:" arg
- + regsub "/cygdrive/d" $arg "d:" arg
- + regsub "/cygdrive/e" $arg "e:" arg
- + regsub "/cygdrive/q" $arg "q:" arg
- + regsub "/cygdrive/r" $arg "r:" arg
- +
- + # Always kill and restart quest (or try to before loading)
- + slay quest
- + slay gdb
- +
- + # Port id -- either specified in baseboard file, or managed here.
- + if [target_info exists gdb,socketport] {
- + set portnum [target_info gdb,socketport];
- + } else {
- + # Bump the port number to avoid conflicts with hung ports.
- + incr portnum;
- + }
- +
- + verbose "gdb_load : portnum = $portnum arg = $arg"
- + # Extract the local and remote host ids from the target board struct.
- +
- + if [target_info exists sockethost] {
- + set debughost [target_info sockethost];
- + } else {
- + set debughost "localhost:";
- + }
- + # Extract the protocol
- + if [target_info exists gdb_protocol] {
- + set protocol [target_info gdb_protocol];
- + } else {
- + set protocol "remote";
- + }
- +
- + # Extract the name of the gdbserver, if known (default 'gdbserver').
- + if [target_info exists gdb_server_prog] {
- + set gdbserver [target_info gdb_server_prog];
- + } else {
- + set gdbserver "gdbserver";
- + }
- +
- + verbose "gdbserver is set to $gdbserver"
- + # Extract the socket hostname
- + if [target_info exists sockethost] {
- + set sockethost [target_info sockethost];
- + } else {
- + set sockethost ""
- + }
- +
- + # Export the host:port pair.
- + set gdbport $debughost$portnum;
- + verbose "gdbport is now $gdbport"
- + # Remember new exec file.
- + if { $arg == "" } {
- + if { ! [info exists host_exec] } {
- + send_gdb "info files\n";
- + gdb_expect 30 {
- + -re "Symbols from \"(\[^\"\]+)\"" {
- + set host_exec $expect_out(1,string);
- + exp_continue;
- + }
- + -re "Local exec file:\[\r\n\]+\[ \t\]*`(\[^'\]+)'," {
- + set host_exec $expect_out(1,string);
- + exp_continue;
- + }
- + -re "$gdb_prompt $" { }
- + }
- + }
- + } else {
- + set host_exec $arg
- + if [info exists server_exec] { unset server_exec }
- + }
- +
- + # Fire off the debug agent
- + if [target_info exists gdb_server_args] {
- + # This flavour of gdbserver takes as arguments those specified
- + # in the board configuration file
- + set custom_args [target_info gdb_server_args];
- + set launch_return [eval remote_spawn host \{ $gdbserver $custom_args \} $arg ]
- + verbose "spawned $gdbserver $custom_args $arg with return code $launch_return"
- + } else {
- + # This flavour of gdbserver takes as arguments the port information
- + # and the name of the executable file to be debugged.
- + set server_spawn_id [remote_spawn target\
- + "$gdbserver $sockethost$portnum "]
- + verbose "remote_spawn $gdbserver $sockethost$portnum"
- + }
- +
- + # We can't call close, because if gdbserver is local then that means
- + # that it will get a SIGHUP.
- + ## close -i $server_spawn_id
- + #wait -nowait -i $server_spawn_id
- +
- + # Give it a little time to establish
- + sleep 1
- +
- + # tell gdb what file we are debugging
- + if { $arg != "" } {
- + if [gdb_file_cmd $arg] {
- + return -1;
- + }
- + }
- + verbose "gdb_file_cmd has been called with $arg"
- +
- + # attach to the "serial port"
- + gdb_target_cmd $protocol $gdbport;
- +
- + # do the real load if needed
- + if [target_info exists gdb_server_do_load] {
- + send_gdb "load\n"
- + set timeout 2400
- + verbose "Timeout is now $timeout seconds" 2
- + gdb_expect {
- + -re ".*$gdb_prompt $" {
- + if $verbose>1 then {
- + send_user "Loaded $arg into $GDB\n"
- + }
- + set timeout 30
- + verbose "Timeout is now $timeout seconds" 2
- + return 1
- + }
- + -re "$gdb_prompt $" {
- + if $verbose>1 then {
- + perror "GDB couldn't load."
- + }
- + }
- + timeout {
- + if $verbose>1 then {
- + perror "Timed out trying to load $arg."
- + }
- + }
- + }
- + }
- +
- + return 0;
- +}
- diff --git a/include/dis-asm.h b/include/dis-asm.h
- index af48e85..e3d84ab 100644
- --- a/include/dis-asm.h
- +++ b/include/dis-asm.h
- @@ -280,6 +280,8 @@ extern int print_insn_xtensa (bfd_vma, disassemble_info *);
- extern int print_insn_z80 (bfd_vma, disassemble_info *);
- extern int print_insn_z8001 (bfd_vma, disassemble_info *);
- extern int print_insn_z8002 (bfd_vma, disassemble_info *);
- +extern int print_insn_little_nios2 (bfd_vma, disassemble_info *);
- +extern int print_insn_big_nios2 (bfd_vma, disassemble_info *);
-
- extern disassembler_ftype arc_get_disassembler (void *);
- extern disassembler_ftype cris_get_disassembler (bfd *);
- diff --git a/include/elf/nios2.h b/include/elf/nios2.h
- new file mode 100644
- index 0000000..ef810c5
- --- /dev/null
- +++ b/include/elf/nios2.h
- @@ -0,0 +1,65 @@
- +/* Altera New Jersey ELF support for BFD
- +
- + Copyright (C) 2003
- + by Nigel Gray (ngray@altera.com).
- +
- +This file is part of BFD, the Binary File Descriptor library.
- +
- +This program is free software; you can redistribute it and/or modify
- +it under the terms of the GNU General Public License as published by
- +the Free Software Foundation; either version 2 of the License, or
- +(at your option) any later version.
- +
- +This program is distributed in the hope that it will be useful,
- +but WITHOUT ANY WARRANTY; without even the implied warranty of
- +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- +GNU General Public License for more details.
- +
- +You should have received a copy of the GNU General Public License
- +along with this program; if not, write to the Free Software
- +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
- +
- +/* This file holds definitions specific to the Altera New Jersey ELF ABI. Note
- + that most of this is not actually implemented by BFD. */
- +
- +#ifndef _ELF_NIOS2_H
- +#define _ELF_NIOS2_H
- +
- +#include "elf/reloc-macros.h"
- +
- +/* the order of these numbers must match the order in
- + the elf_nios2_howto_table_rel table for the lookup
- + function to work properly */
- +
- +START_RELOC_NUMBERS (elf_nios2_reloc_type)
- + RELOC_NUMBER (R_NIOS2_NONE, 0)
- + RELOC_NUMBER (R_NIOS2_S16, 1)
- + RELOC_NUMBER (R_NIOS2_U16, 2)
- + RELOC_NUMBER (R_NIOS2_PCREL16, 3)
- + RELOC_NUMBER (R_NIOS2_CALL26, 4)
- + RELOC_NUMBER (R_NIOS2_IMM5, 5)
- + RELOC_NUMBER (R_NIOS2_CACHE_OPX, 6)
- + RELOC_NUMBER (R_NIOS2_IMM6, 7)
- + RELOC_NUMBER (R_NIOS2_IMM8, 8)
- + RELOC_NUMBER (R_NIOS2_HI16, 9)
- + RELOC_NUMBER (R_NIOS2_LO16, 10)
- + RELOC_NUMBER (R_NIOS2_HIADJ16, 11)
- + RELOC_NUMBER (R_NIOS2_BFD_RELOC_32, 12)
- + RELOC_NUMBER (R_NIOS2_BFD_RELOC_16, 13)
- + RELOC_NUMBER (R_NIOS2_BFD_RELOC_8, 14)
- + RELOC_NUMBER (R_NIOS2_GPREL, 15)
- + RELOC_NUMBER (R_NIOS2_GNU_VTINHERIT, 16)
- + RELOC_NUMBER (R_NIOS2_GNU_VTENTRY, 17)
- + RELOC_NUMBER (R_NIOS2_UJMP, 18)
- + RELOC_NUMBER (R_NIOS2_CJMP, 19)
- + RELOC_NUMBER (R_NIOS2_CALLR, 20)
- + RELOC_NUMBER (R_NIOS2_ALIGN, 21)
- + RELOC_NUMBER (R_NIOS2_ILLEGAL, 22)
- +END_RELOC_NUMBERS (R_NIOS2_maxext)
- +
- +/* Processor specific section flags */
- +
- +/* This is used to mark gp-relative sections */
- +#define SHF_NIOS2_GPREL 0x10000000
- +
- +#endif //_ELF_NIOS2_H
- diff --git a/include/opcode/nios2-isa.h b/include/opcode/nios2-isa.h
- new file mode 100644
- index 0000000..0023880
- --- /dev/null
- +++ b/include/opcode/nios2-isa.h
- @@ -0,0 +1,1860 @@
- +/*
- + * This file defines Nios II instruction set constants.
- + * To include it in assembly code (.S file), define ALT_ASM_SRC
- + * before including this file.
- + *
- + * This file is automatically generated by gen_isa.pl - do not edit
- + */
- +
- +#ifndef _NIOS2_ISA_H_
- +#define _NIOS2_ISA_H_
- +
- +/* OP instruction opcode values (index is OP field) */
- +#define NUM_OP_INSTS 64
- +
- +#ifndef ALT_ASM_SRC
- +extern const char* op_names[NUM_OP_INSTS];
- +#endif /* ALT_ASM_SRC */
- +
- +/* OPX instruction opcode values (index is OPX field) */
- +#define NUM_OPX_INSTS 64
- +
- +#ifndef ALT_ASM_SRC
- +extern const char* opx_names[NUM_OPX_INSTS];
- +#endif /* ALT_ASM_SRC */
- +
- +/* Constants for instruction fields and ISA */
- +#define CPU_RESET_EXC_ID 1
- +#define DIV_ERROR_EXC_ID 9
- +#define DTLB_MISS_EXC_ID 15
- +#define DTLB_PERM_EXC_ID 16
- +#define FAST_INTR_EXC_ID 3
- +#define HBREAK_EXC_ID 0
- +#define ITLB_MISS_EXC_ID 13
- +#define ITLB_PERM_EXC_ID 14
- +#define MISALIGNED_DATA_ADDR_EXC_ID 7
- +#define MISALIGNED_TARGET_PC_EXC_ID 8
- +#define NMI_EXC_ID 2
- +#define NORM_INTR_EXC_ID 4
- +#define SBREAK_EXC_ID 6
- +#define SLAVE_DATA_ACCESS_ERROR_EXC_ID 18
- +#define SLAVE_INST_ACCESS_ERROR_EXC_ID 17
- +#define SUPERVISOR_DATA_ADDR_EXC_ID 12
- +#define SUPERVISOR_INST_ADDR_EXC_ID 10
- +#define SUPERVISOR_INST_EXC_ID 11
- +#define TRAP_EXC_ID 5
- +#define AT_REGNUM 1
- +#define BRETADDR_REGNUM 30
- +#define BSTATUS_REG_LSB 2
- +#define BSTATUS_REG_MMU_LSB 0
- +#define BSTATUS_REG_MMU_MSB 2
- +#define BSTATUS_REG_MMU_SZ 3
- +#define BSTATUS_REG_MMU_MASK 0x7
- +#define BSTATUS_REG_NO_MMU_LSB 0
- +#define BSTATUS_REG_NO_MMU_MSB 0
- +#define BSTATUS_REG_NO_MMU_SZ 1
- +#define BSTATUS_REG_NO_MMU_MASK 0x1
- +#define BSTATUS_REG_REGNUM 2
- +#define BSTATUS_REG_SZ 3
- +#define BSTATUS_REG_MASK 0x7
- +#define BT_REGNUM 25
- +#define CACHE_MAX_BYTES 65536
- +#define CACHE_MAX_LINE_BYTES 32
- +#define CACHE_MIN_LINE_BYTES 4
- +#define COMPARE_OP_EQ 0x0
- +#define COMPARE_OP_GE 0x1
- +#define COMPARE_OP_LSB 3
- +#define COMPARE_OP_LT 0x2
- +#define COMPARE_OP_MSB 4
- +#define COMPARE_OP_NE 0x3
- +#define COMPARE_OP_SZ 2
- +#define COMPARE_OP_MASK 0x3
- +#define CPUID_REG_LSB 0
- +#define CPUID_REG_MSB 31
- +#define CPUID_REG_REGNUM 5
- +#define CPUID_REG_SZ 32
- +#define CPUID_REG_MASK 0xffffffff
- +#define DATAPATH_LOG2_SZ 5
- +#define DATAPATH_LOG2_MASK 0x1f
- +#define DATAPATH_LSB 0
- +#define DATAPATH_MSB 31
- +#define DATAPATH_SZ 32
- +#define DATAPATH_MASK 0xffffffff
- +#define EMPTY_CRST_IW 127034
- +#define EMPTY_HBREAK_IW 4040762
- +#define EMPTY_INTR_IW 3926074
- +#define EMPTY_NOP_IW 100410
- +#define EMPTY_RET_IW 4160759866
- +#define ERETADDR_REGNUM 29
- +#define ESTATUS_REG_LSB 0
- +#define ESTATUS_REG_MMU_LSB 0
- +#define ESTATUS_REG_MMU_MSB 2
- +#define ESTATUS_REG_MMU_SZ 3
- +#define ESTATUS_REG_MMU_MASK 0x7
- +#define ESTATUS_REG_MSB 2
- +#define ESTATUS_REG_NO_MMU_LSB 0
- +#define ESTATUS_REG_NO_MMU_MSB 0
- +#define ESTATUS_REG_NO_MMU_SZ 1
- +#define ESTATUS_REG_NO_MMU_MASK 0x1
- +#define ESTATUS_REG_REGNUM 1
- +#define ESTATUS_REG_SZ 3
- +#define ESTATUS_REG_MASK 0x7
- +#define ET_REGNUM 24
- +#define EXCEPTION_REG_LSB 0
- +#define EXCEPTION_REG_MEA_LSB 0
- +#define EXCEPTION_REG_MEA_MSB 0
- +#define EXCEPTION_REG_MEA_SZ 1
- +#define EXCEPTION_REG_MEA_MASK 0x1
- +#define EXCEPTION_REG_MEE_LSB 1
- +#define EXCEPTION_REG_MEE_MSB 1
- +#define EXCEPTION_REG_MEE_SZ 1
- +#define EXCEPTION_REG_MEE_MASK 0x1
- +#define EXCEPTION_REG_MSB 1
- +#define EXCEPTION_REG_REGNUM 7
- +#define EXCEPTION_REG_SZ 2
- +#define EXCEPTION_REG_MASK 0x3
- +#define FP_REGNUM 28
- +#define FSTATUS_REG_REGNUM 11
- +#define GP_REGNUM 26
- +#define IENABLE_REG_LSB 0
- +#define IENABLE_REG_MSB 31
- +#define IENABLE_REG_REGNUM 3
- +#define IENABLE_REG_SZ 32
- +#define IENABLE_REG_MASK 0xffffffff
- +#define IPENDING_REG_LSB 0
- +#define IPENDING_REG_MSB 31
- +#define IPENDING_REG_REGNUM 4
- +#define IPENDING_REG_SZ 32
- +#define IPENDING_REG_MASK 0xffffffff
- +#define IW_A_LSB 27
- +#define IW_A_MSB 31
- +#define IW_A_SZ 5
- +#define IW_A_MASK 0x1f
- +#define IW_B_LSB 22
- +#define IW_B_MSB 26
- +#define IW_B_SZ 5
- +#define IW_B_MASK 0x1f
- +#define IW_C_LSB 17
- +#define IW_C_MSB 21
- +#define IW_C_SZ 5
- +#define IW_C_MASK 0x1f
- +#define IW_CONTROL_REGNUM_BASE 0
- +#define IW_CONTROL_REGNUM_LSB 6
- +#define IW_CONTROL_REGNUM_MSB 9
- +#define IW_CONTROL_REGNUM_SZ 4
- +#define IW_CONTROL_REGNUM_MASK 0xf
- +#define IW_CUSTOM_N_LSB 6
- +#define IW_CUSTOM_N_MSB 13
- +#define IW_CUSTOM_N_SZ 8
- +#define IW_CUSTOM_N_MASK 0xff
- +#define IW_CUSTOM_READRA_LSB 16
- +#define IW_CUSTOM_READRA_MSB 16
- +#define IW_CUSTOM_READRA_SZ 1
- +#define IW_CUSTOM_READRA_MASK 0x1
- +#define IW_CUSTOM_READRB_LSB 15
- +#define IW_CUSTOM_READRB_MSB 15
- +#define IW_CUSTOM_READRB_SZ 1
- +#define IW_CUSTOM_READRB_MASK 0x1
- +#define IW_CUSTOM_WRITERC_LSB 14
- +#define IW_CUSTOM_WRITERC_MSB 14
- +#define IW_CUSTOM_WRITERC_SZ 1
- +#define IW_CUSTOM_WRITERC_MASK 0x1
- +#define IW_IMM16_LSB 6
- +#define IW_IMM16_MSB 21
- +#define IW_IMM16_SZ 16
- +#define IW_IMM16_MASK 0xffff
- +#define IW_IMM26_LSB 6
- +#define IW_IMM26_MSB 31
- +#define IW_IMM26_SZ 26
- +#define IW_IMM26_MASK 0x3ffffff
- +#define IW_MEMSZ_BYTE 0x0
- +#define IW_MEMSZ_HWORD 0x1
- +#define IW_MEMSZ_LSB 3
- +#define IW_MEMSZ_MSB 4
- +#define IW_MEMSZ_SZ 2
- +#define IW_MEMSZ_MASK 0x3
- +#define IW_MEMSZ_WORD 0x2
- +#define IW_MEMSZ_WORD_MSB 0x1
- +#define IW_OP_LSB 0
- +#define IW_OP_MSB 5
- +#define IW_OP_SZ 6
- +#define IW_OP_MASK 0x3f
- +#define IW_OPX_LSB 11
- +#define IW_OPX_MSB 16
- +#define IW_OPX_SZ 6
- +#define IW_OPX_MASK 0x3f
- +#define IW_SHIFT_IMM5_LSB 6
- +#define IW_SHIFT_IMM5_MSB 10
- +#define IW_SHIFT_IMM5_SZ 5
- +#define IW_SHIFT_IMM5_MASK 0x1f
- +#define IW_SZ 32
- +#define IW_MASK 0xffffffff
- +#define IW_TRAP_BREAK_IMM5_LSB 6
- +#define IW_TRAP_BREAK_IMM5_MSB 10
- +#define IW_TRAP_BREAK_IMM5_SZ 5
- +#define IW_TRAP_BREAK_IMM5_MASK 0x1f
- +#define JMP_CALLR_VS_RET_IS_RET 0
- +#define JMP_CALLR_VS_RET_OPX_BIT 3
- +#define LOGIC_OP_AND 0x1
- +#define LOGIC_OP_LSB 3
- +#define LOGIC_OP_MSB 4
- +#define LOGIC_OP_NOR 0x0
- +#define LOGIC_OP_OR 0x2
- +#define LOGIC_OP_SZ 2
- +#define LOGIC_OP_MASK 0x3
- +#define LOGIC_OP_XOR 0x3
- +#define MMU_ADDR_BYPASS_TLB 0x3
- +#define MMU_ADDR_BYPASS_TLB_CACHEABLE 0x0
- +#define MMU_ADDR_BYPASS_TLB_CACHEABLE_LSB 29
- +#define MMU_ADDR_BYPASS_TLB_CACHEABLE_MSB 29
- +#define MMU_ADDR_BYPASS_TLB_CACHEABLE_SZ 1
- +#define MMU_ADDR_BYPASS_TLB_CACHEABLE_MASK 0x1
- +#define MMU_ADDR_BYPASS_TLB_LSB 30
- +#define MMU_ADDR_BYPASS_TLB_MSB 31
- +#define MMU_ADDR_BYPASS_TLB_PADDR_LSB 0
- +#define MMU_ADDR_BYPASS_TLB_PADDR_MSB 28
- +#define MMU_ADDR_BYPASS_TLB_PADDR_SZ 29
- +#define MMU_ADDR_BYPASS_TLB_PADDR_MASK 0x1fffffff
- +#define MMU_ADDR_BYPASS_TLB_SZ 2
- +#define MMU_ADDR_BYPASS_TLB_MASK 0x3
- +#define MMU_ADDR_IO_REGION 0x7
- +#define MMU_ADDR_IO_REGION_LSB 29
- +#define MMU_ADDR_IO_REGION_MSB 31
- +#define MMU_ADDR_IO_REGION_SZ 3
- +#define MMU_ADDR_IO_REGION_MASK 0x7
- +#define MMU_ADDR_IO_REGION_VPN 0xe0000
- +#define MMU_ADDR_KERNEL_MMU_REGION 0x2
- +#define MMU_ADDR_KERNEL_MMU_REGION_LSB 30
- +#define MMU_ADDR_KERNEL_MMU_REGION_MSB 31
- +#define MMU_ADDR_KERNEL_MMU_REGION_SZ 2
- +#define MMU_ADDR_KERNEL_MMU_REGION_MASK 0x3
- +#define MMU_ADDR_KERNEL_REGION 0x6
- +#define MMU_ADDR_KERNEL_REGION_INT 6
- +#define MMU_ADDR_KERNEL_REGION_LSB 29
- +#define MMU_ADDR_KERNEL_REGION_MSB 31
- +#define MMU_ADDR_KERNEL_REGION_SZ 3
- +#define MMU_ADDR_KERNEL_REGION_MASK 0x7
- +#define MMU_ADDR_PAGE_OFFSET_LSB 0
- +#define MMU_ADDR_PAGE_OFFSET_MSB 11
- +#define MMU_ADDR_PAGE_OFFSET_SZ 12
- +#define MMU_ADDR_PAGE_OFFSET_MASK 0xfff
- +#define MMU_ADDR_PFN_LSB 12
- +#define MMU_ADDR_PFN_MSB 31
- +#define MMU_ADDR_PFN_SZ 20
- +#define MMU_ADDR_PFN_MASK 0xfffff
- +#define MMU_ADDR_USER_REGION 0x0
- +#define MMU_ADDR_USER_REGION_LSB 31
- +#define MMU_ADDR_USER_REGION_MSB 31
- +#define MMU_ADDR_USER_REGION_SZ 1
- +#define MMU_ADDR_USER_REGION_MASK 0x1
- +#define MMU_ADDR_VPN_LSB 12
- +#define MMU_ADDR_VPN_MSB 31
- +#define MMU_ADDR_VPN_SZ 20
- +#define MMU_ADDR_VPN_MASK 0xfffff
- +#define PTEADDR_REG_LSB 0
- +#define PTEADDR_REG_MSB 31
- +#define PTEADDR_REG_PTBASE_LSB 22
- +#define PTEADDR_REG_PTBASE_MSB 31
- +#define PTEADDR_REG_PTBASE_SZ 10
- +#define PTEADDR_REG_PTBASE_MASK 0x3ff
- +#define PTEADDR_REG_REGNUM 8
- +#define PTEADDR_REG_RSV_LSB 0
- +#define PTEADDR_REG_RSV_MSB 1
- +#define PTEADDR_REG_RSV_SZ 2
- +#define PTEADDR_REG_RSV_MASK 0x3
- +#define PTEADDR_REG_SZ 32
- +#define PTEADDR_REG_MASK 0xffffffff
- +#define PTEADDR_REG_VPN_LSB 2
- +#define PTEADDR_REG_VPN_MSB 21
- +#define PTEADDR_REG_VPN_SZ 20
- +#define PTEADDR_REG_VPN_MASK 0xfffff
- +#define REGNUM_SZ 5
- +#define REGNUM_MASK 0x1f
- +#define RETADDR_REGNUM 31
- +#define RF_ADDR_SZ 5
- +#define RF_ADDR_MASK 0x1f
- +#define RF_NUM_REG 32
- +#define SIM_REG_LSB 0
- +#define SIM_REG_MSB 3
- +#define SIM_REG_PERF_CNT_CLR_LSB 2
- +#define SIM_REG_PERF_CNT_CLR_MSB 2
- +#define SIM_REG_PERF_CNT_CLR_SZ 1
- +#define SIM_REG_PERF_CNT_CLR_MASK 0x1
- +#define SIM_REG_PERF_CNT_EN_LSB 1
- +#define SIM_REG_PERF_CNT_EN_MSB 1
- +#define SIM_REG_PERF_CNT_EN_SZ 1
- +#define SIM_REG_PERF_CNT_EN_MASK 0x1
- +#define SIM_REG_REGNUM 6
- +#define SIM_REG_SHOW_DTLB_LSB 4
- +#define SIM_REG_SHOW_DTLB_MSB 4
- +#define SIM_REG_SHOW_DTLB_SZ 1
- +#define SIM_REG_SHOW_DTLB_MASK 0x1
- +#define SIM_REG_SHOW_ITLB_LSB 3
- +#define SIM_REG_SHOW_ITLB_MSB 3
- +#define SIM_REG_SHOW_ITLB_SZ 1
- +#define SIM_REG_SHOW_ITLB_MASK 0x1
- +#define SIM_REG_SHOW_MMU_REGS_LSB 5
- +#define SIM_REG_SHOW_MMU_REGS_MSB 5
- +#define SIM_REG_SHOW_MMU_REGS_SZ 1
- +#define SIM_REG_SHOW_MMU_REGS_MASK 0x1
- +#define SIM_REG_STOP_LSB 0
- +#define SIM_REG_STOP_MSB 0
- +#define SIM_REG_STOP_SZ 1
- +#define SIM_REG_STOP_MASK 0x1
- +#define SIM_REG_SZ 4
- +#define SIM_REG_MASK 0xf
- +#define SP_REGNUM 27
- +#define STATUS_REG_EH_LSB 2
- +#define STATUS_REG_EH_MSB 2
- +#define STATUS_REG_EH_SZ 1
- +#define STATUS_REG_EH_MASK 0x1
- +#define STATUS_REG_LSB 0
- +#define STATUS_REG_MMU_LSB 0
- +#define STATUS_REG_MMU_MSB 2
- +#define STATUS_REG_MMU_RSV_LSB 3
- +#define STATUS_REG_MMU_RSV_MSB 31
- +#define STATUS_REG_MMU_RSV_SZ 29
- +#define STATUS_REG_MMU_RSV_MASK 0x1fffffff
- +#define STATUS_REG_MMU_SZ 3
- +#define STATUS_REG_MMU_MASK 0x7
- +#define STATUS_REG_MSB 2
- +#define STATUS_REG_NO_MMU_LSB 0
- +#define STATUS_REG_NO_MMU_MSB 0
- +#define STATUS_REG_NO_MMU_RSV_LSB 1
- +#define STATUS_REG_NO_MMU_RSV_MSB 31
- +#define STATUS_REG_NO_MMU_RSV_SZ 31
- +#define STATUS_REG_NO_MMU_RSV_MASK 0x7fffffff
- +#define STATUS_REG_NO_MMU_SZ 1
- +#define STATUS_REG_NO_MMU_MASK 0x1
- +#define STATUS_REG_PIE_LSB 0
- +#define STATUS_REG_PIE_MSB 0
- +#define STATUS_REG_PIE_SZ 1
- +#define STATUS_REG_PIE_MASK 0x1
- +#define STATUS_REG_REGNUM 0
- +#define STATUS_REG_SZ 3
- +#define STATUS_REG_MASK 0x7
- +#define STATUS_REG_U_LSB 1
- +#define STATUS_REG_U_MSB 1
- +#define STATUS_REG_U_SZ 1
- +#define STATUS_REG_U_MASK 0x1
- +#define TLB_MAX_ENTRIES 1024
- +#define TLB_MAX_LINES 512
- +#define TLB_MAX_PID_SZ 14
- +#define TLB_MAX_PID_MASK 0x3fff
- +#define TLB_MAX_PTR_SZ 10
- +#define TLB_MAX_PTR_MASK 0x3ff
- +#define TLB_MAX_WAYS 8
- +#define TLB_MIN_PID_SZ 1
- +#define TLB_MIN_PID_MASK 0x1
- +#define TLB_MIN_PTR_SZ 7
- +#define TLB_MIN_PTR_MASK 0x7f
- +#define TLB_MIN_WAYS 2
- +#define TLBACC_REG_C_LSB 24
- +#define TLBACC_REG_C_MSB 24
- +#define TLBACC_REG_C_SZ 1
- +#define TLBACC_REG_C_MASK 0x1
- +#define TLBACC_REG_G_LSB 20
- +#define TLBACC_REG_G_MSB 20
- +#define TLBACC_REG_G_SZ 1
- +#define TLBACC_REG_G_MASK 0x1
- +#define TLBACC_REG_IG_LSB 25
- +#define TLBACC_REG_IG_MSB 31
- +#define TLBACC_REG_IG_SZ 7
- +#define TLBACC_REG_IG_MASK 0x7f
- +#define TLBACC_REG_LSB 0
- +#define TLBACC_REG_MSB 24
- +#define TLBACC_REG_PFN_LSB 0
- +#define TLBACC_REG_PFN_MSB 19
- +#define TLBACC_REG_PFN_SZ 20
- +#define TLBACC_REG_PFN_MASK 0xfffff
- +#define TLBACC_REG_R_LSB 23
- +#define TLBACC_REG_R_MSB 23
- +#define TLBACC_REG_R_SZ 1
- +#define TLBACC_REG_R_MASK 0x1
- +#define TLBACC_REG_REGNUM 9
- +#define TLBACC_REG_SZ 25
- +#define TLBACC_REG_MASK 0x1ffffff
- +#define TLBACC_REG_W_LSB 22
- +#define TLBACC_REG_W_MSB 22
- +#define TLBACC_REG_W_SZ 1
- +#define TLBACC_REG_W_MASK 0x1
- +#define TLBACC_REG_X_LSB 21
- +#define TLBACC_REG_X_MSB 21
- +#define TLBACC_REG_X_SZ 1
- +#define TLBACC_REG_X_MASK 0x1
- +#define TLBMISC_REG_BAD_LSB 2
- +#define TLBMISC_REG_BAD_MSB 2
- +#define TLBMISC_REG_BAD_SZ 1
- +#define TLBMISC_REG_BAD_MASK 0x1
- +#define TLBMISC_REG_D_LSB 0
- +#define TLBMISC_REG_D_MSB 0
- +#define TLBMISC_REG_D_SZ 1
- +#define TLBMISC_REG_D_MASK 0x1
- +#define TLBMISC_REG_DBL_LSB 3
- +#define TLBMISC_REG_DBL_MSB 3
- +#define TLBMISC_REG_DBL_SZ 1
- +#define TLBMISC_REG_DBL_MASK 0x1
- +#define TLBMISC_REG_LSB 0
- +#define TLBMISC_REG_MSB 23
- +#define TLBMISC_REG_PERM_LSB 1
- +#define TLBMISC_REG_PERM_MSB 1
- +#define TLBMISC_REG_PERM_SZ 1
- +#define TLBMISC_REG_PERM_MASK 0x1
- +#define TLBMISC_REG_PID_LSB 4
- +#define TLBMISC_REG_PID_MSB 17
- +#define TLBMISC_REG_PID_SZ 14
- +#define TLBMISC_REG_PID_MASK 0x3fff
- +#define TLBMISC_REG_RD_LSB 24
- +#define TLBMISC_REG_RD_MSB 24
- +#define TLBMISC_REG_RD_SZ 1
- +#define TLBMISC_REG_RD_MASK 0x1
- +#define TLBMISC_REG_REGNUM 10
- +#define TLBMISC_REG_RSV0_LSB 18
- +#define TLBMISC_REG_RSV0_MSB 19
- +#define TLBMISC_REG_RSV0_SZ 2
- +#define TLBMISC_REG_RSV0_MASK 0x3
- +#define TLBMISC_REG_RSV1_LSB 25
- +#define TLBMISC_REG_RSV1_MSB 31
- +#define TLBMISC_REG_RSV1_SZ 7
- +#define TLBMISC_REG_RSV1_MASK 0x7f
- +#define TLBMISC_REG_SZ 24
- +#define TLBMISC_REG_MASK 0xffffff
- +#define TLBMISC_REG_WAY_LSB 20
- +#define TLBMISC_REG_WAY_MSB 22
- +#define TLBMISC_REG_WAY_SZ 3
- +#define TLBMISC_REG_WAY_MASK 0x7
- +#define TLBMISC_REG_WE_LSB 23
- +#define TLBMISC_REG_WE_MSB 23
- +#define TLBMISC_REG_WE_SZ 1
- +#define TLBMISC_REG_WE_MASK 0x1
- +
- +/* Macros to extract instruction fields */
- +#define GET_IW_A(Iw) \
- + (((Iw) >> IW_A_LSB) & IW_A_MASK)
- +#define SET_IW_A(Iw, Val) \
- + Iw = (((Iw) & (~(IW_A_MASK << IW_A_LSB))) | \
- + (((Val) & IW_A_MASK) << IW_A_LSB))
- +#define GET_IW_B(Iw) \
- + (((Iw) >> IW_B_LSB) & IW_B_MASK)
- +#define SET_IW_B(Iw, Val) \
- + Iw = (((Iw) & (~(IW_B_MASK << IW_B_LSB))) | \
- + (((Val) & IW_B_MASK) << IW_B_LSB))
- +#define GET_IW_C(Iw) \
- + (((Iw) >> IW_C_LSB) & IW_C_MASK)
- +#define SET_IW_C(Iw, Val) \
- + Iw = (((Iw) & (~(IW_C_MASK << IW_C_LSB))) | \
- + (((Val) & IW_C_MASK) << IW_C_LSB))
- +#define GET_IW_CONTROL_REGNUM(Iw) \
- + (((Iw) >> IW_CONTROL_REGNUM_LSB) & IW_CONTROL_REGNUM_MASK)
- +#define SET_IW_CONTROL_REGNUM(Iw, Val) \
- + Iw = (((Iw) & (~(IW_CONTROL_REGNUM_MASK << IW_CONTROL_REGNUM_LSB))) | \
- + (((Val) & IW_CONTROL_REGNUM_MASK) << IW_CONTROL_REGNUM_LSB))
- +#define GET_IW_CUSTOM_N(Iw) \
- + (((Iw) >> IW_CUSTOM_N_LSB) & IW_CUSTOM_N_MASK)
- +#define SET_IW_CUSTOM_N(Iw, Val) \
- + Iw = (((Iw) & (~(IW_CUSTOM_N_MASK << IW_CUSTOM_N_LSB))) | \
- + (((Val) & IW_CUSTOM_N_MASK) << IW_CUSTOM_N_LSB))
- +#define GET_IW_CUSTOM_READRA(Iw) \
- + (((Iw) >> IW_CUSTOM_READRA_LSB) & IW_CUSTOM_READRA_MASK)
- +#define SET_IW_CUSTOM_READRA(Iw, Val) \
- + Iw = (((Iw) & (~(IW_CUSTOM_READRA_MASK << IW_CUSTOM_READRA_LSB))) | \
- + (((Val) & IW_CUSTOM_READRA_MASK) << IW_CUSTOM_READRA_LSB))
- +#define GET_IW_CUSTOM_READRB(Iw) \
- + (((Iw) >> IW_CUSTOM_READRB_LSB) & IW_CUSTOM_READRB_MASK)
- +#define SET_IW_CUSTOM_READRB(Iw, Val) \
- + Iw = (((Iw) & (~(IW_CUSTOM_READRB_MASK << IW_CUSTOM_READRB_LSB))) | \
- + (((Val) & IW_CUSTOM_READRB_MASK) << IW_CUSTOM_READRB_LSB))
- +#define GET_IW_CUSTOM_WRITERC(Iw) \
- + (((Iw) >> IW_CUSTOM_WRITERC_LSB) & IW_CUSTOM_WRITERC_MASK)
- +#define SET_IW_CUSTOM_WRITERC(Iw, Val) \
- + Iw = (((Iw) & (~(IW_CUSTOM_WRITERC_MASK << IW_CUSTOM_WRITERC_LSB))) | \
- + (((Val) & IW_CUSTOM_WRITERC_MASK) << IW_CUSTOM_WRITERC_LSB))
- +#define GET_IW_IMM16(Iw) \
- + (((Iw) >> IW_IMM16_LSB) & IW_IMM16_MASK)
- +#define SET_IW_IMM16(Iw, Val) \
- + Iw = (((Iw) & (~(IW_IMM16_MASK << IW_IMM16_LSB))) | \
- + (((Val) & IW_IMM16_MASK) << IW_IMM16_LSB))
- +#define GET_IW_IMM26(Iw) \
- + (((Iw) >> IW_IMM26_LSB) & IW_IMM26_MASK)
- +#define SET_IW_IMM26(Iw, Val) \
- + Iw = (((Iw) & (~(IW_IMM26_MASK << IW_IMM26_LSB))) | \
- + (((Val) & IW_IMM26_MASK) << IW_IMM26_LSB))
- +#define GET_IW_MEMSZ(Iw) \
- + (((Iw) >> IW_MEMSZ_LSB) & IW_MEMSZ_MASK)
- +#define SET_IW_MEMSZ(Iw, Val) \
- + Iw = (((Iw) & (~(IW_MEMSZ_MASK << IW_MEMSZ_LSB))) | \
- + (((Val) & IW_MEMSZ_MASK) << IW_MEMSZ_LSB))
- +#define GET_IW_OP(Iw) \
- + (((Iw) >> IW_OP_LSB) & IW_OP_MASK)
- +#define SET_IW_OP(Iw, Val) \
- + Iw = (((Iw) & (~(IW_OP_MASK << IW_OP_LSB))) | \
- + (((Val) & IW_OP_MASK) << IW_OP_LSB))
- +#define GET_IW_OPX(Iw) \
- + (((Iw) >> IW_OPX_LSB) & IW_OPX_MASK)
- +#define SET_IW_OPX(Iw, Val) \
- + Iw = (((Iw) & (~(IW_OPX_MASK << IW_OPX_LSB))) | \
- + (((Val) & IW_OPX_MASK) << IW_OPX_LSB))
- +#define GET_IW_SHIFT_IMM5(Iw) \
- + (((Iw) >> IW_SHIFT_IMM5_LSB) & IW_SHIFT_IMM5_MASK)
- +#define SET_IW_SHIFT_IMM5(Iw, Val) \
- + Iw = (((Iw) & (~(IW_SHIFT_IMM5_MASK << IW_SHIFT_IMM5_LSB))) | \
- + (((Val) & IW_SHIFT_IMM5_MASK) << IW_SHIFT_IMM5_LSB))
- +#define GET_IW_TRAP_BREAK_IMM5(Iw) \
- + (((Iw) >> IW_TRAP_BREAK_IMM5_LSB) & IW_TRAP_BREAK_IMM5_MASK)
- +#define SET_IW_TRAP_BREAK_IMM5(Iw, Val) \
- + Iw = (((Iw) & (~(IW_TRAP_BREAK_IMM5_MASK << IW_TRAP_BREAK_IMM5_LSB))) | \
- + (((Val) & IW_TRAP_BREAK_IMM5_MASK) << IW_TRAP_BREAK_IMM5_LSB))
- +
- +/* Macros to extract control register fields */
- +#define GET_BSTATUS_REG_MMU(Reg) \
- + (((Reg) >> BSTATUS_REG_MMU_LSB) & BSTATUS_REG_MMU_MASK)
- +#define SET_BSTATUS_REG_MMU(Reg, Val) \
- + Reg = (((Reg) & (~(BSTATUS_REG_MMU_MASK << BSTATUS_REG_MMU_LSB))) | \
- + (((Val) & BSTATUS_REG_MMU_MASK) << BSTATUS_REG_MMU_LSB))
- +#define GET_BSTATUS_REG_NO_MMU(Reg) \
- + (((Reg) >> BSTATUS_REG_NO_MMU_LSB) & BSTATUS_REG_NO_MMU_MASK)
- +#define SET_BSTATUS_REG_NO_MMU(Reg, Val) \
- + Reg = (((Reg) & (~(BSTATUS_REG_NO_MMU_MASK << BSTATUS_REG_NO_MMU_LSB))) | \
- + (((Val) & BSTATUS_REG_NO_MMU_MASK) << BSTATUS_REG_NO_MMU_LSB))
- +#define GET_ESTATUS_REG_MMU(Reg) \
- + (((Reg) >> ESTATUS_REG_MMU_LSB) & ESTATUS_REG_MMU_MASK)
- +#define SET_ESTATUS_REG_MMU(Reg, Val) \
- + Reg = (((Reg) & (~(ESTATUS_REG_MMU_MASK << ESTATUS_REG_MMU_LSB))) | \
- + (((Val) & ESTATUS_REG_MMU_MASK) << ESTATUS_REG_MMU_LSB))
- +#define GET_ESTATUS_REG_NO_MMU(Reg) \
- + (((Reg) >> ESTATUS_REG_NO_MMU_LSB) & ESTATUS_REG_NO_MMU_MASK)
- +#define SET_ESTATUS_REG_NO_MMU(Reg, Val) \
- + Reg = (((Reg) & (~(ESTATUS_REG_NO_MMU_MASK << ESTATUS_REG_NO_MMU_LSB))) | \
- + (((Val) & ESTATUS_REG_NO_MMU_MASK) << ESTATUS_REG_NO_MMU_LSB))
- +#define GET_EXCEPTION_REG_MEA(Reg) \
- + (((Reg) >> EXCEPTION_REG_MEA_LSB) & EXCEPTION_REG_MEA_MASK)
- +#define SET_EXCEPTION_REG_MEA(Reg, Val) \
- + Reg = (((Reg) & (~(EXCEPTION_REG_MEA_MASK << EXCEPTION_REG_MEA_LSB))) | \
- + (((Val) & EXCEPTION_REG_MEA_MASK) << EXCEPTION_REG_MEA_LSB))
- +#define GET_EXCEPTION_REG_MEE(Reg) \
- + (((Reg) >> EXCEPTION_REG_MEE_LSB) & EXCEPTION_REG_MEE_MASK)
- +#define SET_EXCEPTION_REG_MEE(Reg, Val) \
- + Reg = (((Reg) & (~(EXCEPTION_REG_MEE_MASK << EXCEPTION_REG_MEE_LSB))) | \
- + (((Val) & EXCEPTION_REG_MEE_MASK) << EXCEPTION_REG_MEE_LSB))
- +#define GET_PTEADDR_REG_PTBASE(Reg) \
- + (((Reg) >> PTEADDR_REG_PTBASE_LSB) & PTEADDR_REG_PTBASE_MASK)
- +#define SET_PTEADDR_REG_PTBASE(Reg, Val) \
- + Reg = (((Reg) & (~(PTEADDR_REG_PTBASE_MASK << PTEADDR_REG_PTBASE_LSB))) | \
- + (((Val) & PTEADDR_REG_PTBASE_MASK) << PTEADDR_REG_PTBASE_LSB))
- +#define GET_PTEADDR_REG_RSV(Reg) \
- + (((Reg) >> PTEADDR_REG_RSV_LSB) & PTEADDR_REG_RSV_MASK)
- +#define SET_PTEADDR_REG_RSV(Reg, Val) \
- + Reg = (((Reg) & (~(PTEADDR_REG_RSV_MASK << PTEADDR_REG_RSV_LSB))) | \
- + (((Val) & PTEADDR_REG_RSV_MASK) << PTEADDR_REG_RSV_LSB))
- +#define GET_PTEADDR_REG_VPN(Reg) \
- + (((Reg) >> PTEADDR_REG_VPN_LSB) & PTEADDR_REG_VPN_MASK)
- +#define SET_PTEADDR_REG_VPN(Reg, Val) \
- + Reg = (((Reg) & (~(PTEADDR_REG_VPN_MASK << PTEADDR_REG_VPN_LSB))) | \
- + (((Val) & PTEADDR_REG_VPN_MASK) << PTEADDR_REG_VPN_LSB))
- +#define GET_SIM_REG_PERF_CNT_CLR(Reg) \
- + (((Reg) >> SIM_REG_PERF_CNT_CLR_LSB) & SIM_REG_PERF_CNT_CLR_MASK)
- +#define SET_SIM_REG_PERF_CNT_CLR(Reg, Val) \
- + Reg = (((Reg) & (~(SIM_REG_PERF_CNT_CLR_MASK << SIM_REG_PERF_CNT_CLR_LSB))) | \
- + (((Val) & SIM_REG_PERF_CNT_CLR_MASK) << SIM_REG_PERF_CNT_CLR_LSB))
- +#define GET_SIM_REG_PERF_CNT_EN(Reg) \
- + (((Reg) >> SIM_REG_PERF_CNT_EN_LSB) & SIM_REG_PERF_CNT_EN_MASK)
- +#define SET_SIM_REG_PERF_CNT_EN(Reg, Val) \
- + Reg = (((Reg) & (~(SIM_REG_PERF_CNT_EN_MASK << SIM_REG_PERF_CNT_EN_LSB))) | \
- + (((Val) & SIM_REG_PERF_CNT_EN_MASK) << SIM_REG_PERF_CNT_EN_LSB))
- +#define GET_SIM_REG_SHOW_DTLB(Reg) \
- + (((Reg) >> SIM_REG_SHOW_DTLB_LSB) & SIM_REG_SHOW_DTLB_MASK)
- +#define SET_SIM_REG_SHOW_DTLB(Reg, Val) \
- + Reg = (((Reg) & (~(SIM_REG_SHOW_DTLB_MASK << SIM_REG_SHOW_DTLB_LSB))) | \
- + (((Val) & SIM_REG_SHOW_DTLB_MASK) << SIM_REG_SHOW_DTLB_LSB))
- +#define GET_SIM_REG_SHOW_ITLB(Reg) \
- + (((Reg) >> SIM_REG_SHOW_ITLB_LSB) & SIM_REG_SHOW_ITLB_MASK)
- +#define SET_SIM_REG_SHOW_ITLB(Reg, Val) \
- + Reg = (((Reg) & (~(SIM_REG_SHOW_ITLB_MASK << SIM_REG_SHOW_ITLB_LSB))) | \
- + (((Val) & SIM_REG_SHOW_ITLB_MASK) << SIM_REG_SHOW_ITLB_LSB))
- +#define GET_SIM_REG_SHOW_MMU_REGS(Reg) \
- + (((Reg) >> SIM_REG_SHOW_MMU_REGS_LSB) & SIM_REG_SHOW_MMU_REGS_MASK)
- +#define SET_SIM_REG_SHOW_MMU_REGS(Reg, Val) \
- + Reg = (((Reg) & (~(SIM_REG_SHOW_MMU_REGS_MASK << SIM_REG_SHOW_MMU_REGS_LSB))) | \
- + (((Val) & SIM_REG_SHOW_MMU_REGS_MASK) << SIM_REG_SHOW_MMU_REGS_LSB))
- +#define GET_SIM_REG_STOP(Reg) \
- + (((Reg) >> SIM_REG_STOP_LSB) & SIM_REG_STOP_MASK)
- +#define SET_SIM_REG_STOP(Reg, Val) \
- + Reg = (((Reg) & (~(SIM_REG_STOP_MASK << SIM_REG_STOP_LSB))) | \
- + (((Val) & SIM_REG_STOP_MASK) << SIM_REG_STOP_LSB))
- +#define GET_STATUS_REG_EH(Reg) \
- + (((Reg) >> STATUS_REG_EH_LSB) & STATUS_REG_EH_MASK)
- +#define SET_STATUS_REG_EH(Reg, Val) \
- + Reg = (((Reg) & (~(STATUS_REG_EH_MASK << STATUS_REG_EH_LSB))) | \
- + (((Val) & STATUS_REG_EH_MASK) << STATUS_REG_EH_LSB))
- +#define GET_STATUS_REG_MMU(Reg) \
- + (((Reg) >> STATUS_REG_MMU_LSB) & STATUS_REG_MMU_MASK)
- +#define SET_STATUS_REG_MMU(Reg, Val) \
- + Reg = (((Reg) & (~(STATUS_REG_MMU_MASK << STATUS_REG_MMU_LSB))) | \
- + (((Val) & STATUS_REG_MMU_MASK) << STATUS_REG_MMU_LSB))
- +#define GET_STATUS_REG_MMU_RSV(Reg) \
- + (((Reg) >> STATUS_REG_MMU_RSV_LSB) & STATUS_REG_MMU_RSV_MASK)
- +#define SET_STATUS_REG_MMU_RSV(Reg, Val) \
- + Reg = (((Reg) & (~(STATUS_REG_MMU_RSV_MASK << STATUS_REG_MMU_RSV_LSB))) | \
- + (((Val) & STATUS_REG_MMU_RSV_MASK) << STATUS_REG_MMU_RSV_LSB))
- +#define GET_STATUS_REG_NO_MMU(Reg) \
- + (((Reg) >> STATUS_REG_NO_MMU_LSB) & STATUS_REG_NO_MMU_MASK)
- +#define SET_STATUS_REG_NO_MMU(Reg, Val) \
- + Reg = (((Reg) & (~(STATUS_REG_NO_MMU_MASK << STATUS_REG_NO_MMU_LSB))) | \
- + (((Val) & STATUS_REG_NO_MMU_MASK) << STATUS_REG_NO_MMU_LSB))
- +#define GET_STATUS_REG_NO_MMU_RSV(Reg) \
- + (((Reg) >> STATUS_REG_NO_MMU_RSV_LSB) & STATUS_REG_NO_MMU_RSV_MASK)
- +#define SET_STATUS_REG_NO_MMU_RSV(Reg, Val) \
- + Reg = (((Reg) & (~(STATUS_REG_NO_MMU_RSV_MASK << STATUS_REG_NO_MMU_RSV_LSB))) | \
- + (((Val) & STATUS_REG_NO_MMU_RSV_MASK) << STATUS_REG_NO_MMU_RSV_LSB))
- +#define GET_STATUS_REG_PIE(Reg) \
- + (((Reg) >> STATUS_REG_PIE_LSB) & STATUS_REG_PIE_MASK)
- +#define SET_STATUS_REG_PIE(Reg, Val) \
- + Reg = (((Reg) & (~(STATUS_REG_PIE_MASK << STATUS_REG_PIE_LSB))) | \
- + (((Val) & STATUS_REG_PIE_MASK) << STATUS_REG_PIE_LSB))
- +#define GET_STATUS_REG_U(Reg) \
- + (((Reg) >> STATUS_REG_U_LSB) & STATUS_REG_U_MASK)
- +#define SET_STATUS_REG_U(Reg, Val) \
- + Reg = (((Reg) & (~(STATUS_REG_U_MASK << STATUS_REG_U_LSB))) | \
- + (((Val) & STATUS_REG_U_MASK) << STATUS_REG_U_LSB))
- +#define GET_TLBACC_REG_C(Reg) \
- + (((Reg) >> TLBACC_REG_C_LSB) & TLBACC_REG_C_MASK)
- +#define SET_TLBACC_REG_C(Reg, Val) \
- + Reg = (((Reg) & (~(TLBACC_REG_C_MASK << TLBACC_REG_C_LSB))) | \
- + (((Val) & TLBACC_REG_C_MASK) << TLBACC_REG_C_LSB))
- +#define GET_TLBACC_REG_G(Reg) \
- + (((Reg) >> TLBACC_REG_G_LSB) & TLBACC_REG_G_MASK)
- +#define SET_TLBACC_REG_G(Reg, Val) \
- + Reg = (((Reg) & (~(TLBACC_REG_G_MASK << TLBACC_REG_G_LSB))) | \
- + (((Val) & TLBACC_REG_G_MASK) << TLBACC_REG_G_LSB))
- +#define GET_TLBACC_REG_IG(Reg) \
- + (((Reg) >> TLBACC_REG_IG_LSB) & TLBACC_REG_IG_MASK)
- +#define SET_TLBACC_REG_IG(Reg, Val) \
- + Reg = (((Reg) & (~(TLBACC_REG_IG_MASK << TLBACC_REG_IG_LSB))) | \
- + (((Val) & TLBACC_REG_IG_MASK) << TLBACC_REG_IG_LSB))
- +#define GET_TLBACC_REG_PFN(Reg) \
- + (((Reg) >> TLBACC_REG_PFN_LSB) & TLBACC_REG_PFN_MASK)
- +#define SET_TLBACC_REG_PFN(Reg, Val) \
- + Reg = (((Reg) & (~(TLBACC_REG_PFN_MASK << TLBACC_REG_PFN_LSB))) | \
- + (((Val) & TLBACC_REG_PFN_MASK) << TLBACC_REG_PFN_LSB))
- +#define GET_TLBACC_REG_R(Reg) \
- + (((Reg) >> TLBACC_REG_R_LSB) & TLBACC_REG_R_MASK)
- +#define SET_TLBACC_REG_R(Reg, Val) \
- + Reg = (((Reg) & (~(TLBACC_REG_R_MASK << TLBACC_REG_R_LSB))) | \
- + (((Val) & TLBACC_REG_R_MASK) << TLBACC_REG_R_LSB))
- +#define GET_TLBACC_REG_W(Reg) \
- + (((Reg) >> TLBACC_REG_W_LSB) & TLBACC_REG_W_MASK)
- +#define SET_TLBACC_REG_W(Reg, Val) \
- + Reg = (((Reg) & (~(TLBACC_REG_W_MASK << TLBACC_REG_W_LSB))) | \
- + (((Val) & TLBACC_REG_W_MASK) << TLBACC_REG_W_LSB))
- +#define GET_TLBACC_REG_X(Reg) \
- + (((Reg) >> TLBACC_REG_X_LSB) & TLBACC_REG_X_MASK)
- +#define SET_TLBACC_REG_X(Reg, Val) \
- + Reg = (((Reg) & (~(TLBACC_REG_X_MASK << TLBACC_REG_X_LSB))) | \
- + (((Val) & TLBACC_REG_X_MASK) << TLBACC_REG_X_LSB))
- +#define GET_TLBMISC_REG_BAD(Reg) \
- + (((Reg) >> TLBMISC_REG_BAD_LSB) & TLBMISC_REG_BAD_MASK)
- +#define SET_TLBMISC_REG_BAD(Reg, Val) \
- + Reg = (((Reg) & (~(TLBMISC_REG_BAD_MASK << TLBMISC_REG_BAD_LSB))) | \
- + (((Val) & TLBMISC_REG_BAD_MASK) << TLBMISC_REG_BAD_LSB))
- +#define GET_TLBMISC_REG_D(Reg) \
- + (((Reg) >> TLBMISC_REG_D_LSB) & TLBMISC_REG_D_MASK)
- +#define SET_TLBMISC_REG_D(Reg, Val) \
- + Reg = (((Reg) & (~(TLBMISC_REG_D_MASK << TLBMISC_REG_D_LSB))) | \
- + (((Val) & TLBMISC_REG_D_MASK) << TLBMISC_REG_D_LSB))
- +#define GET_TLBMISC_REG_DBL(Reg) \
- + (((Reg) >> TLBMISC_REG_DBL_LSB) & TLBMISC_REG_DBL_MASK)
- +#define SET_TLBMISC_REG_DBL(Reg, Val) \
- + Reg = (((Reg) & (~(TLBMISC_REG_DBL_MASK << TLBMISC_REG_DBL_LSB))) | \
- + (((Val) & TLBMISC_REG_DBL_MASK) << TLBMISC_REG_DBL_LSB))
- +#define GET_TLBMISC_REG_PERM(Reg) \
- + (((Reg) >> TLBMISC_REG_PERM_LSB) & TLBMISC_REG_PERM_MASK)
- +#define SET_TLBMISC_REG_PERM(Reg, Val) \
- + Reg = (((Reg) & (~(TLBMISC_REG_PERM_MASK << TLBMISC_REG_PERM_LSB))) | \
- + (((Val) & TLBMISC_REG_PERM_MASK) << TLBMISC_REG_PERM_LSB))
- +#define GET_TLBMISC_REG_PID(Reg) \
- + (((Reg) >> TLBMISC_REG_PID_LSB) & TLBMISC_REG_PID_MASK)
- +#define SET_TLBMISC_REG_PID(Reg, Val) \
- + Reg = (((Reg) & (~(TLBMISC_REG_PID_MASK << TLBMISC_REG_PID_LSB))) | \
- + (((Val) & TLBMISC_REG_PID_MASK) << TLBMISC_REG_PID_LSB))
- +#define GET_TLBMISC_REG_RD(Reg) \
- + (((Reg) >> TLBMISC_REG_RD_LSB) & TLBMISC_REG_RD_MASK)
- +#define SET_TLBMISC_REG_RD(Reg, Val) \
- + Reg = (((Reg) & (~(TLBMISC_REG_RD_MASK << TLBMISC_REG_RD_LSB))) | \
- + (((Val) & TLBMISC_REG_RD_MASK) << TLBMISC_REG_RD_LSB))
- +#define GET_TLBMISC_REG_RSV0(Reg) \
- + (((Reg) >> TLBMISC_REG_RSV0_LSB) & TLBMISC_REG_RSV0_MASK)
- +#define SET_TLBMISC_REG_RSV0(Reg, Val) \
- + Reg = (((Reg) & (~(TLBMISC_REG_RSV0_MASK << TLBMISC_REG_RSV0_LSB))) | \
- + (((Val) & TLBMISC_REG_RSV0_MASK) << TLBMISC_REG_RSV0_LSB))
- +#define GET_TLBMISC_REG_RSV1(Reg) \
- + (((Reg) >> TLBMISC_REG_RSV1_LSB) & TLBMISC_REG_RSV1_MASK)
- +#define SET_TLBMISC_REG_RSV1(Reg, Val) \
- + Reg = (((Reg) & (~(TLBMISC_REG_RSV1_MASK << TLBMISC_REG_RSV1_LSB))) | \
- + (((Val) & TLBMISC_REG_RSV1_MASK) << TLBMISC_REG_RSV1_LSB))
- +#define GET_TLBMISC_REG_WAY(Reg) \
- + (((Reg) >> TLBMISC_REG_WAY_LSB) & TLBMISC_REG_WAY_MASK)
- +#define SET_TLBMISC_REG_WAY(Reg, Val) \
- + Reg = (((Reg) & (~(TLBMISC_REG_WAY_MASK << TLBMISC_REG_WAY_LSB))) | \
- + (((Val) & TLBMISC_REG_WAY_MASK) << TLBMISC_REG_WAY_LSB))
- +#define GET_TLBMISC_REG_WE(Reg) \
- + (((Reg) >> TLBMISC_REG_WE_LSB) & TLBMISC_REG_WE_MASK)
- +#define SET_TLBMISC_REG_WE(Reg, Val) \
- + Reg = (((Reg) & (~(TLBMISC_REG_WE_MASK << TLBMISC_REG_WE_LSB))) | \
- + (((Val) & TLBMISC_REG_WE_MASK) << TLBMISC_REG_WE_LSB))
- +
- +/* Macros to extract MMU fields */
- +#define GET_MMU_ADDR_BYPASS_TLB_CACHEABLE(Addr) \
- + (((Addr) >> MMU_ADDR_BYPASS_TLB_CACHEABLE_LSB) & MMU_ADDR_BYPASS_TLB_CACHEABLE_MASK)
- +#define SET_MMU_ADDR_BYPASS_TLB_CACHEABLE(Addr, Val) \
- + Addr = (((Addr) & (~(MMU_ADDR_BYPASS_TLB_CACHEABLE_MASK << MMU_ADDR_BYPASS_TLB_CACHEABLE_LSB))) | \
- + (((Val) & MMU_ADDR_BYPASS_TLB_CACHEABLE_MASK) << MMU_ADDR_BYPASS_TLB_CACHEABLE_LSB))
- +#define GET_MMU_ADDR_BYPASS_TLB(Addr) \
- + (((Addr) >> MMU_ADDR_BYPASS_TLB_LSB) & MMU_ADDR_BYPASS_TLB_MASK)
- +#define SET_MMU_ADDR_BYPASS_TLB(Addr, Val) \
- + Addr = (((Addr) & (~(MMU_ADDR_BYPASS_TLB_MASK << MMU_ADDR_BYPASS_TLB_LSB))) | \
- + (((Val) & MMU_ADDR_BYPASS_TLB_MASK) << MMU_ADDR_BYPASS_TLB_LSB))
- +#define GET_MMU_ADDR_BYPASS_TLB_PADDR(Addr) \
- + (((Addr) >> MMU_ADDR_BYPASS_TLB_PADDR_LSB) & MMU_ADDR_BYPASS_TLB_PADDR_MASK)
- +#define SET_MMU_ADDR_BYPASS_TLB_PADDR(Addr, Val) \
- + Addr = (((Addr) & (~(MMU_ADDR_BYPASS_TLB_PADDR_MASK << MMU_ADDR_BYPASS_TLB_PADDR_LSB))) | \
- + (((Val) & MMU_ADDR_BYPASS_TLB_PADDR_MASK) << MMU_ADDR_BYPASS_TLB_PADDR_LSB))
- +#define GET_MMU_ADDR_IO_REGION(Addr) \
- + (((Addr) >> MMU_ADDR_IO_REGION_LSB) & MMU_ADDR_IO_REGION_MASK)
- +#define SET_MMU_ADDR_IO_REGION(Addr, Val) \
- + Addr = (((Addr) & (~(MMU_ADDR_IO_REGION_MASK << MMU_ADDR_IO_REGION_LSB))) | \
- + (((Val) & MMU_ADDR_IO_REGION_MASK) << MMU_ADDR_IO_REGION_LSB))
- +#define GET_MMU_ADDR_KERNEL_MMU_REGION(Addr) \
- + (((Addr) >> MMU_ADDR_KERNEL_MMU_REGION_LSB) & MMU_ADDR_KERNEL_MMU_REGION_MASK)
- +#define SET_MMU_ADDR_KERNEL_MMU_REGION(Addr, Val) \
- + Addr = (((Addr) & (~(MMU_ADDR_KERNEL_MMU_REGION_MASK << MMU_ADDR_KERNEL_MMU_REGION_LSB))) | \
- + (((Val) & MMU_ADDR_KERNEL_MMU_REGION_MASK) << MMU_ADDR_KERNEL_MMU_REGION_LSB))
- +#define GET_MMU_ADDR_KERNEL_REGION(Addr) \
- + (((Addr) >> MMU_ADDR_KERNEL_REGION_LSB) & MMU_ADDR_KERNEL_REGION_MASK)
- +#define SET_MMU_ADDR_KERNEL_REGION(Addr, Val) \
- + Addr = (((Addr) & (~(MMU_ADDR_KERNEL_REGION_MASK << MMU_ADDR_KERNEL_REGION_LSB))) | \
- + (((Val) & MMU_ADDR_KERNEL_REGION_MASK) << MMU_ADDR_KERNEL_REGION_LSB))
- +#define GET_MMU_ADDR_PAGE_OFFSET(Addr) \
- + (((Addr) >> MMU_ADDR_PAGE_OFFSET_LSB) & MMU_ADDR_PAGE_OFFSET_MASK)
- +#define SET_MMU_ADDR_PAGE_OFFSET(Addr, Val) \
- + Addr = (((Addr) & (~(MMU_ADDR_PAGE_OFFSET_MASK << MMU_ADDR_PAGE_OFFSET_LSB))) | \
- + (((Val) & MMU_ADDR_PAGE_OFFSET_MASK) << MMU_ADDR_PAGE_OFFSET_LSB))
- +#define GET_MMU_ADDR_PFN(Addr) \
- + (((Addr) >> MMU_ADDR_PFN_LSB) & MMU_ADDR_PFN_MASK)
- +#define SET_MMU_ADDR_PFN(Addr, Val) \
- + Addr = (((Addr) & (~(MMU_ADDR_PFN_MASK << MMU_ADDR_PFN_LSB))) | \
- + (((Val) & MMU_ADDR_PFN_MASK) << MMU_ADDR_PFN_LSB))
- +#define GET_MMU_ADDR_USER_REGION(Addr) \
- + (((Addr) >> MMU_ADDR_USER_REGION_LSB) & MMU_ADDR_USER_REGION_MASK)
- +#define SET_MMU_ADDR_USER_REGION(Addr, Val) \
- + Addr = (((Addr) & (~(MMU_ADDR_USER_REGION_MASK << MMU_ADDR_USER_REGION_LSB))) | \
- + (((Val) & MMU_ADDR_USER_REGION_MASK) << MMU_ADDR_USER_REGION_LSB))
- +#define GET_MMU_ADDR_VPN(Addr) \
- + (((Addr) >> MMU_ADDR_VPN_LSB) & MMU_ADDR_VPN_MASK)
- +#define SET_MMU_ADDR_VPN(Addr, Val) \
- + Addr = (((Addr) & (~(MMU_ADDR_VPN_MASK << MMU_ADDR_VPN_LSB))) | \
- + (((Val) & MMU_ADDR_VPN_MASK) << MMU_ADDR_VPN_LSB))
- +
- +/* OP instruction values */
- +#define OP_ADDI 4
- +#define OP_ANDHI 44
- +#define OP_ANDI 12
- +#define OP_BEQ 38
- +#define OP_BGE 14
- +#define OP_BGEU 46
- +#define OP_BLT 22
- +#define OP_BLTU 54
- +#define OP_BNE 30
- +#define OP_BR 6
- +#define OP_CALL 0
- +#define OP_CMPEQI 32
- +#define OP_CMPGEI 8
- +#define OP_CMPGEUI 40
- +#define OP_CMPLTI 16
- +#define OP_CMPLTUI 48
- +#define OP_CMPNEI 24
- +#define OP_CUSTOM 50
- +#define OP_FLUSHD 59
- +#define OP_FLUSHDA 27
- +#define OP_INITD 51
- +#define OP_JMPI 1
- +#define OP_LDB 7
- +#define OP_LDBIO 39
- +#define OP_LDBU 3
- +#define OP_LDBUIO 35
- +#define OP_LDH 15
- +#define OP_LDHIO 47
- +#define OP_LDHU 11
- +#define OP_LDHUIO 43
- +#define OP_LDW 23
- +#define OP_LDWIO 55
- +#define OP_MULI 36
- +#define OP_OPX 58
- +#define OP_ORHI 52
- +#define OP_ORI 20
- +#define OP_STB 5
- +#define OP_STBIO 37
- +#define OP_STH 13
- +#define OP_STHIO 45
- +#define OP_STW 21
- +#define OP_STWIO 53
- +#define OP_XORHI 60
- +#define OP_XORI 28
- +
- +/* OPX instruction values */
- +#define OPX_ADD 49
- +#define OPX_AND 14
- +#define OPX_BREAK 52
- +#define OPX_BRET 9
- +#define OPX_CALLR 29
- +#define OPX_CMPEQ 32
- +#define OPX_CMPGE 8
- +#define OPX_CMPGEU 40
- +#define OPX_CMPLT 16
- +#define OPX_CMPLTU 48
- +#define OPX_CMPNE 24
- +#define OPX_CRST 62
- +#define OPX_DIV 37
- +#define OPX_DIVU 36
- +#define OPX_ERET 1
- +#define OPX_FLUSHI 12
- +#define OPX_FLUSHP 4
- +#define OPX_HBREAK 53
- +#define OPX_INITI 41
- +#define OPX_INTR 61
- +#define OPX_JMP 13
- +#define OPX_MUL 39
- +#define OPX_MULXSS 31
- +#define OPX_MULXSU 23
- +#define OPX_MULXUU 7
- +#define OPX_NEXTPC 28
- +#define OPX_NOR 6
- +#define OPX_OR 22
- +#define OPX_RDCTL 38
- +#define OPX_RET 5
- +#define OPX_ROL 3
- +#define OPX_ROLI 2
- +#define OPX_ROR 11
- +#define OPX_SLL 19
- +#define OPX_SLLI 18
- +#define OPX_SRA 59
- +#define OPX_SRAI 58
- +#define OPX_SRL 27
- +#define OPX_SRLI 26
- +#define OPX_SUB 57
- +#define OPX_SYNC 54
- +#define OPX_TRAP 45
- +#define OPX_WRCTL 46
- +#define OPX_XOR 30
- +
- +/* Macros to detect sub-opcode instructions */
- +#define IS_OPX_INST(Iw) (GET_IW_OP(Iw) == OP_OPX)
- +#define IS_CUSTOM_INST(Iw) (GET_IW_OP(Iw) == OP_CUSTOM)
- +
- +/* Instruction property macros */
- +#define IW_PROP_RESERVED_OP(Iw) (0)
- +
- +#define IW_PROP_RESERVED_OPX(Iw) (0)
- +
- +#define IW_PROP_RESERVED(Iw) (0)
- +
- +#define IW_PROP_SUPERVISOR_ONLY(Iw) ( \
- + (op_prop_supervisor_only[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_supervisor_only[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_supervisor_only[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_supervisor_only[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_INITI_FLUSHI(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_INITI) && IS_OPX_INST(Iw)) || \
- + ((GET_IW_OPX((Iw)) == OPX_FLUSHI) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_FLUSH_PIPE(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_flush_pipe[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_flush_pipe[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_JMP_INDIRECT_NON_TRAP(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_jmp_indirect_non_trap[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_jmp_indirect_non_trap[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_JMP_INDIRECT(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_jmp_indirect[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_jmp_indirect[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_JMP_DIRECT(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_CALL)) || \
- + ((GET_IW_OP((Iw)) == OP_JMPI)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_MUL_LSW(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_MULI)) || \
- + ((GET_IW_OPX((Iw)) == OPX_MUL) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_MULX(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_mulx[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_mulx[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_MUL(Iw) ( \
- + (op_prop_mul[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_mul[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_mul[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_mul[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_DIV_UNSIGNED(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_DIVU) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_DIV_SIGNED(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_DIV) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_DIV(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_DIVU) && IS_OPX_INST(Iw)) || \
- + ((GET_IW_OPX((Iw)) == OPX_DIV) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_UNIMPLEMENTED(Iw) (0)
- +
- +#define IW_PROP_IMPLICIT_DST_RETADDR(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_CALL)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_IMPLICIT_DST_ERETADDR(Iw) (0)
- +
- +#define IW_PROP_EXCEPTION(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_TRAP) && IS_OPX_INST(Iw)) || \
- + ((GET_IW_OPX((Iw)) == OPX_INTR) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_BREAK(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_BREAK) && IS_OPX_INST(Iw)) || \
- + ((GET_IW_OPX((Iw)) == OPX_HBREAK) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_CRST(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_CRST) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_WR_CTL_REG(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_wr_ctl_reg[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_wr_ctl_reg[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_UNCOND_CTI_NON_BR(Iw) ( \
- + (op_prop_uncond_cti_non_br[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_uncond_cti_non_br[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_uncond_cti_non_br[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_uncond_cti_non_br[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_RETADDR(Iw) ( \
- + (op_prop_retaddr[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_retaddr[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_retaddr[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_retaddr[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_SHIFT_LEFT(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_SLLI) && IS_OPX_INST(Iw)) || \
- + ((GET_IW_OPX((Iw)) == OPX_SLL) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_SHIFT_LOGICAL(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_shift_logical[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_shift_logical[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_ROT_LEFT(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_ROLI) && IS_OPX_INST(Iw)) || \
- + ((GET_IW_OPX((Iw)) == OPX_ROL) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_SHIFT_ROT_LEFT(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_shift_rot_left[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_shift_rot_left[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_SHIFT_RIGHT_LOGICAL(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_SRLI) && IS_OPX_INST(Iw)) || \
- + ((GET_IW_OPX((Iw)) == OPX_SRL) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_SHIFT_RIGHT_ARITH(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_SRAI) && IS_OPX_INST(Iw)) || \
- + ((GET_IW_OPX((Iw)) == OPX_SRA) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_SHIFT_RIGHT(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_shift_right[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_shift_right[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_ROT_RIGHT(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_ROR) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_SHIFT_ROT_RIGHT(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_shift_rot_right[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_shift_rot_right[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_SHIFT_ROT(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_shift_rot[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_shift_rot[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_SHIFT_ROT_IMM(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_shift_rot_imm[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_shift_rot_imm[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_ROTATE(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_rotate[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_rotate[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_LOGIC_REG(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_logic_reg[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_logic_reg[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_LOGIC_HI_IMM16(Iw) ( \
- + (op_prop_logic_hi_imm16[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_logic_hi_imm16[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_LOGIC_LO_IMM16(Iw) ( \
- + (op_prop_logic_lo_imm16[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_logic_lo_imm16[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_LOGIC_IMM16(Iw) ( \
- + (op_prop_logic_imm16[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_logic_imm16[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_LOGIC(Iw) ( \
- + (op_prop_logic[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_logic[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_logic[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_logic[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_UNSIGNED_LO_IMM16(Iw) ( \
- + (op_prop_unsigned_lo_imm16[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_unsigned_lo_imm16[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_unsigned_lo_imm16[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_unsigned_lo_imm16[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_ARITH_IMM16(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_ADDI)) || \
- + ((GET_IW_OP((Iw)) == OP_MULI)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_CMP_IMM16(Iw) ( \
- + (op_prop_cmp_imm16[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_cmp_imm16[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_JMPI(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_JMPI)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_CMP_IMM16_WITH_CALL_JMPI(Iw) ( \
- + (op_prop_cmp_imm16_with_call_jmpi[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_cmp_imm16_with_call_jmpi[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_CMP_REG(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_cmp_reg[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_cmp_reg[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_SRC_IMM5(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_src_imm5[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_src_imm5[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_CMP_WITH_LT(Iw) ( \
- + (op_prop_cmp_with_lt[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_cmp_with_lt[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_cmp_with_lt[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_cmp_with_lt[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_CMP_WITH_EQ(Iw) ( \
- + (op_prop_cmp_with_eq[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_cmp_with_eq[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_cmp_with_eq[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_cmp_with_eq[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_CMP_WITH_GE(Iw) ( \
- + (op_prop_cmp_with_ge[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_cmp_with_ge[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_cmp_with_ge[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_cmp_with_ge[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_CMP_WITH_NE(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_CMPNEI)) || \
- + ((GET_IW_OPX((Iw)) == OPX_CMPNE) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_CMP_ALU_SIGNED(Iw) ( \
- + (op_prop_cmp_alu_signed[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_cmp_alu_signed[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_cmp_alu_signed[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_cmp_alu_signed[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_CMP(Iw) ( \
- + (op_prop_cmp[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_cmp[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_cmp[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_cmp[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_BR_WITH_LT(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_BLT)) || \
- + ((GET_IW_OP((Iw)) == OP_BLTU)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_BR_WITH_GE(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_BGE)) || \
- + ((GET_IW_OP((Iw)) == OP_BGEU)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_BR_WITH_EQ(Iw) ( \
- + (op_prop_br_with_eq[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_br_with_eq[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_BR_WITH_NE(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_BNE)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_BR_ALU_SIGNED(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_BGE)) || \
- + ((GET_IW_OP((Iw)) == OP_BLT)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_BR_COND(Iw) ( \
- + (op_prop_br_cond[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_br_cond[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_BR_UNCOND(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_BR)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_BR(Iw) ( \
- + (op_prop_br[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_br[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_ALU_SUB(Iw) ( \
- + (op_prop_alu_sub[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_alu_sub[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_alu_sub[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_alu_sub[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_FORCE_XOR(Iw) ( \
- + (op_prop_force_xor[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_force_xor[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_force_xor[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_force_xor[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_LOAD8(Iw) ( \
- + (op_prop_load8[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_load8[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_LOAD16(Iw) ( \
- + (op_prop_load16[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_load16[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_LOAD32(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_LDW)) || \
- + ((GET_IW_OP((Iw)) == OP_LDWIO)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_LOAD_SIGNED(Iw) ( \
- + (op_prop_load_signed[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_load_signed[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_LOAD_UNSIGNED(Iw) ( \
- + (op_prop_load_unsigned[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_load_unsigned[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_LOAD(Iw) ( \
- + (op_prop_load[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_load[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_LOAD_INITD_FLUSHD_FLUSHDA(Iw) ( \
- + (op_prop_load_initd_flushd_flushda[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_load_initd_flushd_flushda[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_LOAD_NON_IO(Iw) ( \
- + (op_prop_load_non_io[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_load_non_io[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_STORE8(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_STB)) || \
- + ((GET_IW_OP((Iw)) == OP_STBIO)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_STORE16(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_STH)) || \
- + ((GET_IW_OP((Iw)) == OP_STHIO)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_STORE32(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_STW)) || \
- + ((GET_IW_OP((Iw)) == OP_STWIO)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_STORE(Iw) ( \
- + (op_prop_store[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_store[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_STORE_NON_IO(Iw) ( \
- + (op_prop_store_non_io[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_store_non_io[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_MEM(Iw) ( \
- + (op_prop_mem[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_mem[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_INITD(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_INITD)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_FLUSHD(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_FLUSHD)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_INITD_FLUSHD(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_INITD)) || \
- + ((GET_IW_OP((Iw)) == OP_FLUSHD)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_FLUSHDA(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_FLUSHDA)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_FLUSHD_FLUSHDA(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_FLUSHD)) || \
- + ((GET_IW_OP((Iw)) == OP_FLUSHDA)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_INITD_FLUSHD_FLUSHDA(Iw) ( \
- + (op_prop_initd_flushd_flushda[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_initd_flushd_flushda[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_LOAD_IO(Iw) ( \
- + (op_prop_load_io[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_load_io[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_STORE_IO(Iw) ( \
- + (op_prop_store_io[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_store_io[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_MEM_IO(Iw) ( \
- + (op_prop_mem_io[GET_IW_OP(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_mem_io[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_ARITH(Iw) ( \
- + (op_prop_arith[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_arith[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_arith[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_arith[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_A_NOT_SRC(Iw) ( \
- + ( \
- + ((GET_IW_OP((Iw)) == OP_CALL)) || \
- + ((GET_IW_OP((Iw)) == OP_JMPI)) \
- + ) \
- + || (IS_CUSTOM_INST(Iw) && !GET_IW_CUSTOM_READRA(Iw)) \
- +)
- +
- +#define IW_PROP_B_NOT_SRC(Iw) ( \
- + (op_prop_b_not_src[GET_IW_OP(Iw)]) \
- + || (IS_CUSTOM_INST(Iw) && !GET_IW_CUSTOM_READRB(Iw)))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_b_not_src[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_IGNORE_DST(Iw) ( \
- + (op_prop_ignore_dst[GET_IW_OP(Iw)]) \
- + || (IS_CUSTOM_INST(Iw) && !GET_IW_CUSTOM_WRITERC(Iw)))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_ignore_dst[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_SRC2_CHOOSE_IMM(Iw) ( \
- + (op_prop_src2_choose_imm[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_src2_choose_imm[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_src2_choose_imm[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_src2_choose_imm[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_WRCTL_INST(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_WRCTL) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_RDCTL_INST(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_RDCTL) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_MUL_SRC1_SIGNED(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_MULXSS) && IS_OPX_INST(Iw)) || \
- + ((GET_IW_OPX((Iw)) == OPX_MULXSU) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_MUL_SRC2_SIGNED(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_MULXSS) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_MUL_SHIFT_SRC1_SIGNED(Iw) ( \
- + (IS_OPX_INST(Iw) && opx_prop_mul_shift_src1_signed[GET_IW_OPX(Iw)]))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_mul_shift_src1_signed[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_MUL_SHIFT_SRC2_SIGNED(Iw) ( \
- + ( \
- + ((GET_IW_OPX((Iw)) == OPX_MULXSS) && IS_OPX_INST(Iw)) \
- + ) \
- + \
- +)
- +
- +#define IW_PROP_DONT_DISPLAY_DST_REG(Iw) ( \
- + (op_prop_dont_display_dst_reg[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_dont_display_dst_reg[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_dont_display_dst_reg[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_dont_display_dst_reg[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_DONT_DISPLAY_SRC1_REG(Iw) ( \
- + (op_prop_dont_display_src1_reg[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_dont_display_src1_reg[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_dont_display_src1_reg[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_dont_display_src1_reg[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_DONT_DISPLAY_SRC2_REG(Iw) ( \
- + (op_prop_dont_display_src2_reg[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_dont_display_src2_reg[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_dont_display_src2_reg[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_dont_display_src2_reg[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_SRC1_NO_X(Iw) ( \
- + (op_prop_src1_no_x[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_src1_no_x[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_src1_no_x[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_src1_no_x[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#define IW_PROP_SRC2_NO_X(Iw) ( \
- + (op_prop_src2_no_x[GET_IW_OP(Iw)] || \
- + (IS_OPX_INST(Iw) && opx_prop_src2_no_x[GET_IW_OPX(Iw)])))
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char op_prop_src2_no_x[64];
- +#endif /* ALT_ASM_SRC */
- +
- +#ifndef ALT_ASM_SRC
- +extern unsigned char opx_prop_src2_no_x[64];
- +#endif /* ALT_ASM_SRC */
- +
- +/* Instruction types */
- +#define INST_TYPE_OP 0
- +#define INST_TYPE_OPX 1
- +
- +/* Canonical instruction codes independent of encoding */
- +#define CALL_INST_CODE 0
- +#define JMPI_INST_CODE 1
- +#define LDBU_INST_CODE 2
- +#define ADDI_INST_CODE 3
- +#define STB_INST_CODE 4
- +#define BR_INST_CODE 5
- +#define LDB_INST_CODE 6
- +#define CMPGEI_INST_CODE 7
- +#define LDHU_INST_CODE 8
- +#define ANDI_INST_CODE 9
- +#define STH_INST_CODE 10
- +#define BGE_INST_CODE 11
- +#define LDH_INST_CODE 12
- +#define CMPLTI_INST_CODE 13
- +#define ORI_INST_CODE 14
- +#define STW_INST_CODE 15
- +#define BLT_INST_CODE 16
- +#define LDW_INST_CODE 17
- +#define CMPNEI_INST_CODE 18
- +#define FLUSHDA_INST_CODE 19
- +#define XORI_INST_CODE 20
- +#define BNE_INST_CODE 21
- +#define CMPEQI_INST_CODE 22
- +#define LDBUIO_INST_CODE 23
- +#define MULI_INST_CODE 24
- +#define STBIO_INST_CODE 25
- +#define BEQ_INST_CODE 26
- +#define LDBIO_INST_CODE 27
- +#define CMPGEUI_INST_CODE 28
- +#define LDHUIO_INST_CODE 29
- +#define ANDHI_INST_CODE 30
- +#define STHIO_INST_CODE 31
- +#define BGEU_INST_CODE 32
- +#define LDHIO_INST_CODE 33
- +#define CMPLTUI_INST_CODE 34
- +#define CUSTOM_INST_CODE 35
- +#define INITD_INST_CODE 36
- +#define ORHI_INST_CODE 37
- +#define STWIO_INST_CODE 38
- +#define BLTU_INST_CODE 39
- +#define LDWIO_INST_CODE 40
- +#define FLUSHD_INST_CODE 41
- +#define XORHI_INST_CODE 42
- +#define ERET_INST_CODE 43
- +#define ROLI_INST_CODE 44
- +#define ROL_INST_CODE 45
- +#define FLUSHP_INST_CODE 46
- +#define RET_INST_CODE 47
- +#define NOR_INST_CODE 48
- +#define MULXUU_INST_CODE 49
- +#define CMPGE_INST_CODE 50
- +#define BRET_INST_CODE 51
- +#define ROR_INST_CODE 52
- +#define FLUSHI_INST_CODE 53
- +#define JMP_INST_CODE 54
- +#define AND_INST_CODE 55
- +#define CMPLT_INST_CODE 56
- +#define SLLI_INST_CODE 57
- +#define SLL_INST_CODE 58
- +#define OR_INST_CODE 59
- +#define MULXSU_INST_CODE 60
- +#define CMPNE_INST_CODE 61
- +#define SRLI_INST_CODE 62
- +#define SRL_INST_CODE 63
- +#define NEXTPC_INST_CODE 64
- +#define CALLR_INST_CODE 65
- +#define XOR_INST_CODE 66
- +#define MULXSS_INST_CODE 67
- +#define CMPEQ_INST_CODE 68
- +#define DIVU_INST_CODE 69
- +#define DIV_INST_CODE 70
- +#define RDCTL_INST_CODE 71
- +#define MUL_INST_CODE 72
- +#define CMPGEU_INST_CODE 73
- +#define INITI_INST_CODE 74
- +#define TRAP_INST_CODE 75
- +#define WRCTL_INST_CODE 76
- +#define CMPLTU_INST_CODE 77
- +#define ADD_INST_CODE 78
- +#define BREAK_INST_CODE 79
- +#define HBREAK_INST_CODE 80
- +#define SYNC_INST_CODE 81
- +#define SUB_INST_CODE 82
- +#define SRAI_INST_CODE 83
- +#define SRA_INST_CODE 84
- +#define INTR_INST_CODE 85
- +#define CRST_INST_CODE 86
- +#define RSV_INST_CODE 87
- +#define NUM_NIOS2_INST_CODES 88
- +
- +#ifndef ALT_ASM_SRC
- +/* Instruction information entry */
- +typedef struct {
- + const char* name; /* Assembly-language instruction name */
- + int instType; /* INST_TYPE_OP or INST_TYPE_OPX */
- + unsigned opcode; /* Value of instruction word OP/OPX field */
- +} Nios2InstInfo;
- +
- +extern Nios2InstInfo nios2InstInfo[NUM_NIOS2_INST_CODES];
- +#endif /* ALT_ASM_SRC */
- +
- +/* Returns the instruction code given the 32-bit instruction word */
- +#define GET_INST_CODE(Iw) \
- + (IS_OPX_INST(Iw) ? opxToInstCode[GET_IW_OPX(Iw)] : opToInstCode[GET_IW_OP(Iw)])
- +
- +#ifndef ALT_ASM_SRC
- +extern int opToInstCode[64];
- +extern int opxToInstCode[64];
- +#endif /* ALT_ASM_SRC */
- +
- +/*
- + * MMU Memory Region Macros
- + */
- +#define USER_REGION_MIN_VADDR 0x00000000
- +#define USER_REGION_MAX_VADDR 0x7fffffff
- +#define KERNEL_MMU_REGION_MIN_VADDR 0x80000000
- +#define KERNEL_MMU_REGION_MAX_VADDR 0xbfffffff
- +#define KERNEL_REGION_MIN_VADDR 0xc0000000
- +#define KERNEL_REGION_MAX_VADDR 0xdfffffff
- +#define IO_REGION_MIN_VADDR 0xe0000000
- +#define IO_REGION_MAX_VADDR 0xffffffff
- +
- +#define MMU_PAGE_SIZE (0x1 << (MMU_ADDR_PAGE_OFFSET_SZ))
- +
- +#define isMmuUserRegion(Vaddr) \
- + (GET_MMU_ADDR_USER_REGION(Vaddr) == MMU_ADDR_USER_REGION)
- +#define isMmuKernelMmuRegion(Vaddr) \
- + (GET_MMU_ADDR_KERNEL_MMU_REGION(Vaddr) == MMU_ADDR_KERNEL_MMU_REGION)
- +#define isMmuKernelRegion(Vaddr) \
- + (GET_MMU_ADDR_KERNEL_REGION(Vaddr) == MMU_ADDR_KERNEL_REGION)
- +#define isMmuIORegion(Vaddr) \
- + (GET_MMU_ADDR_IO_REGION(Vaddr) == MMU_ADDR_IO_REGION)
- +
- +/* Does this virtual address bypass the TLB? */
- +#define vaddrBypassTlb(Vaddr) \
- + (GET_MMU_ADDR_BYPASS_TLB(Vaddr) == MMU_ADDR_BYPASS_TLB)
- +
- +/* If TLB is bypassed, is the address cacheable or uncachable. */
- +#define vaddrBypassTlbCacheable(Vaddr) \
- + (GET_MMU_ADDR_BYPASS_TLB_CACHEABLE(Vaddr) == MMU_ADDR_BYPASS_TLB_CACHEABLE)
- +
- +/*
- + * Compute physical address for regions that bypass the TLB.
- + * Just need to clear some top bits.
- + */
- +#define bypassTlbVaddrToPaddr(Vaddr) \
- + ((Vaddr) & (MMU_ADDR_BYPASS_TLB_PADDR_MASK << MMU_ADDR_BYPASS_TLB_PADDR_LSB))
- +
- +/*
- + * Will the physical address fit in the Kernel/IO region virtual address space?
- + */
- +#define fitsInKernelRegion(Paddr) \
- + (GET_MMU_ADDR_KERNEL_REGION(Paddr) == 0)
- +#define fitsInIORegion(Paddr) \
- + (GET_MMU_ADDR_IO_REGION(Paddr) == 0)
- +
- +/* Convert a physical address to a Kernel/IO region virtual address. */
- +#define paddrToKernelRegionVaddr(Paddr) \
- + ((Paddr) | (MMU_ADDR_KERNEL_REGION << MMU_ADDR_KERNEL_REGION_LSB))
- +#define paddrToIORegionVaddr(Paddr) \
- + ((Paddr) | (MMU_ADDR_IO_REGION << MMU_ADDR_IO_REGION_LSB))
- +
- +/*
- + * Convert a virtual address to a Kernel/IO region virtual address.
- + * Uses bypassTlbVaddrToPaddr to clear top bits.
- + */
- +#define vaddrToKernelRegionVaddr(Vaddr) \
- + paddrToKernelRegionVaddr(bypassTlbVaddrToPaddr(Vaddr))
- +#define vaddrToIORegionVaddr(Vaddr) \
- + paddrToIORegionVaddr(bypassTlbVaddrToPaddr(Vaddr))
- +
- +/* Convert between VPN/PFN and virtual/physical addresses. */
- +#define vpnToVaddr(Vpn) ((Vpn) << MMU_ADDR_VPN_LSB)
- +#define pfnToPaddr(Pfn) ((Pfn) << MMU_ADDR_PFN_LSB)
- +#define vaddrToVpn(Vaddr) GET_MMU_ADDR_VPN(Vaddr)
- +#define paddrToPfn(Paddr) GET_MMU_ADDR_PFN(Paddr)
- +
- +/* Bitwise OR with a KERNEL region address to make it an IO region address */
- +#define KERNEL_TO_IO_REGION 0x20000000
- +
- +#endif /* _NIOS2_ISA_H_ */
- diff --git a/include/opcode/nios2.h b/include/opcode/nios2.h
- new file mode 100644
- index 0000000..992bb80
- --- /dev/null
- +++ b/include/opcode/nios2.h
- @@ -0,0 +1,361 @@
- +/* nios2.h. Altera New Jersey opcode list for GAS, the GNU assembler.
- +
- + Copyright (C) 2003
- + by Nigel Gray (ngray@altera.com).
- +
- +This file is part of GDB, GAS, and the GNU binutils.
- +
- +GDB, GAS, and the GNU binutils are free software; you can redistribute
- +them and/or modify them under the terms of the GNU General Public
- +License as published by the Free Software Foundation; either version
- +1, or (at your option) any later version.
- +
- +GDB, GAS, and the GNU binutils are distributed in the hope that they
- +will be useful, but WITHOUT ANY WARRANTY; without even the implied
- +warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- +the GNU General Public License for more details.
- +
- +You should have received a copy of the GNU General Public License
- +along with this file; see the file COPYING. If not, write to the Free
- +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
- +
- +#ifndef _NIOS2_H_
- +#define _NIOS2_H_
- +
- +
- +/****************************************************************************
- + * This file contains structures, bit masks and shift counts used
- + * by the GNU toolchain to define the New Jersey instruction set and
- + * access various opcode fields.
- + ****************************************************************************/
- +
- +enum overflow_type
- +{
- + call_target_overflow = 0,
- + branch_target_overflow,
- + address_offset_overflow,
- + signed_immed16_overflow,
- + unsigned_immed16_overflow,
- + unsigned_immed5_overflow,
- + custom_opcode_overflow,
- + no_overflow
- +};
- +
- +/*---------------------------------------------------------------------------
- + This structure holds information for a particular instruction
- + ---------------------------------------------------------------------------*/
- +
- +/* match When assembling, this
- + opcode is modified by the arguments to produce the actual opcode
- + that is used. If pinfo is INSN_MACRO, then this is 0. */
- +
- +/* mask If pinfo is not INSN_MACRO, then this is a bit mask for the
- + relevant portions of the opcode when disassembling. If the
- + actual opcode anded with the match field equals the opcode field,
- + then we have found the correct instruction. If pinfo is
- + INSN_MACRO, then this field is the macro identifier. */
- +
- +/* For a macro, this is INSN_MACRO. Otherwise, it is a collection
- + of bits describing the instruction, notably any relevant hazard
- + information. */
- +
- +struct nios2_opcode
- +{
- + const char *name; /* The name of the instruction. */
- + const char *args; /* A string describing the arguments for this instruction. */
- + const char *args_test; /* Like args, but with an extra argument for the expected opcode */
- + unsigned long num_args; /* the number of arguments the instruction takes */
- + unsigned long match; /* The basic opcode for the instruction. */
- + unsigned long mask; /* mask for the opcode field of the instruction */
- + unsigned long pinfo; /* is this a real instruction or instruction macro */
- + enum overflow_type overflow_msg; /* msg template used to generate informative message when fixup overflows */
- +};
- +
- +/* This value is used in the nios2_opcode.pinfo field to indicate that the instruction
- + is a macro or pseudo-op. This requires special treatment by the assembler, and is
- + used by the disassembler to determine whether to check for a nop */
- +#define NIOS2_INSN_MACRO 0x80000000
- +#define NIOS2_INSN_MACRO_MOV 0x80000001
- +#define NIOS2_INSN_MACRO_MOVI 0x80000002
- +#define NIOS2_INSN_MACRO_MOVIA 0x80000004
- +
- +#define NIOS2_INSN_RELAXABLE 0x40000000
- +#define NIOS2_INSN_UBRANCH 0x00000010
- +#define NIOS2_INSN_CBRANCH 0x00000020
- +#define NIOS2_INSN_CALL 0x00000040
- +
- +#define NIOS2_INSN_ADDI 0x00000080
- +#define NIOS2_INSN_ANDI 0x00000100
- +#define NIOS2_INSN_ORI 0x00000200
- +#define NIOS2_INSN_XORI 0x00000400
- +
- +
- +
- +/* Associates a register name ($6) with a 5-bit index (eg 6) */
- +struct nios2_reg
- +{
- + const char *name;
- + const int index;
- +};
- +
- +
- +/* -------------------------------------------------------------------------
- + Bitfield masks for New Jersey instructions
- + -------------------------------------------------------------------------*/
- +
- +/* These are bit masks and shift counts to use to access the various
- + fields of an instruction. */
- +
- +/* Macros for getting and setting an instruction field */
- +#define GET_INSN_FIELD(X, i) ((i) & OP_MASK_##X) >> OP_SH_##X
- +#define SET_INSN_FIELD(X, i, j) (i) = ((i) &~ (OP_MASK_##X)) | ((j) << OP_SH_##X)
- +
- +
- +/*
- + We include the auto-generated file nios2-isa.h and define the mask
- + and shifts below in terms of those in nios2-isa.h. This ensures
- + that the binutils and hardware are always in sync
- +*/
- +
- +#include "nios2-isa.h"
- +
- +#define OP_MASK_OP (IW_OP_MASK << IW_OP_LSB)
- +#define OP_SH_OP IW_OP_LSB
- +
- +
- +/* Masks and shifts for I-type instructions */
- +
- +#define OP_MASK_IOP (IW_OP_MASK << IW_OP_LSB)
- +#define OP_SH_IOP IW_OP_LSB
- +
- +#define OP_MASK_IMM16 (IW_IMM16_MASK << IW_IMM16_LSB)
- +#define OP_SH_IMM16 IW_IMM16_LSB
- +
- +#define OP_MASK_IRD (IW_B_MASK << IW_B_LSB) // the same as T for I-type
- +#define OP_SH_IRD IW_B_LSB
- +
- +#define OP_MASK_IRT (IW_B_MASK << IW_B_LSB)
- +#define OP_SH_IRT IW_B_LSB
- +
- +#define OP_MASK_IRS (IW_A_MASK << IW_A_LSB)
- +#define OP_SH_IRS IW_A_LSB
- +
- +/* Masks and shifts for R-type instructions */
- +
- +#define OP_MASK_ROP (IW_OP_MASK << IW_OP_LSB)
- +#define OP_SH_ROP IW_OP_LSB
- +
- +#define OP_MASK_ROPX (IW_OPX_MASK << IW_OPX_LSB)
- +#define OP_SH_ROPX IW_OPX_LSB
- +
- +#define OP_MASK_RRD (IW_C_MASK << IW_C_LSB)
- +#define OP_SH_RRD IW_C_LSB
- +
- +#define OP_MASK_RRT (IW_B_MASK << IW_B_LSB)
- +#define OP_SH_RRT IW_B_LSB
- +
- +#define OP_MASK_RRS (IW_A_MASK << IW_A_LSB)
- +#define OP_SH_RRS IW_A_LSB
- +
- +/* Masks and shifts for J-type instructions */
- +
- +#define OP_MASK_JOP (IW_OP_MASK << IW_OP_LSB)
- +#define OP_SH_JOP IW_OP_LSB
- +
- +#define OP_MASK_IMM26 (IW_IMM26_MASK << IW_IMM26_LSB)
- +#define OP_SH_IMM26 IW_IMM26_LSB
- +
- +/* Masks and shifts for CTL instructions */
- +
- +#define OP_MASK_RCTL 0x000007c0
- +#define OP_SH_RCTL 6
- +
- +/* break instruction imm5 field */
- +#define OP_MASK_TRAP_IMM5 0x000007c0
- +#define OP_SH_TRAP_IMM5 6
- +
- +/* instruction imm5 field */
- +#define OP_MASK_IMM5 (IW_SHIFT_IMM5_MASK << IW_SHIFT_IMM5_LSB)
- +#define OP_SH_IMM5 IW_SHIFT_IMM5_LSB
- +
- +/* cache operation fields (type j,i(s)) */
- +#define OP_MASK_CACHE_OPX (IW_B_MASK << IW_B_LSB)
- +#define OP_SH_CACHE_OPX IW_B_LSB
- +#define OP_MASK_CACHE_RRS (IW_A_MASK << IW_A_LSB)
- +#define OP_SH_CACHE_RRS IW_A_LSB
- +
- +/* custom instruction masks */
- +#define OP_MASK_CUSTOM_A 0x00010000
- +#define OP_SH_CUSTOM_A 16
- +
- +#define OP_MASK_CUSTOM_B 0x00008000
- +#define OP_SH_CUSTOM_B 15
- +
- +#define OP_MASK_CUSTOM_C 0x00004000
- +#define OP_SH_CUSTOM_C 14
- +
- +#define OP_MASK_CUSTOM_N 0x00003fc0
- +#define OP_SH_CUSTOM_N 6
- +#define OP_MAX_CUSTOM_N 255
- +
- +/*
- + The following macros define the opcode matches for each
- + instruction
- + code & OP_MASK_INST == OP_MATCH_INST
- + */
- +
- +/* OP instruction matches */
- +#define OP_MATCH_ADDI OP_ADDI
- +#define OP_MATCH_ANDHI OP_ANDHI
- +#define OP_MATCH_ANDI OP_ANDI
- +#define OP_MATCH_BEQ OP_BEQ
- +#define OP_MATCH_BGE OP_BGE
- +#define OP_MATCH_BGEU OP_BGEU
- +#define OP_MATCH_BLT OP_BLT
- +#define OP_MATCH_BLTU OP_BLTU
- +#define OP_MATCH_BNE OP_BNE
- +#define OP_MATCH_BR OP_BR
- +#define OP_MATCH_FLUSHD OP_FLUSHD
- +#define OP_MATCH_FLUSHDA OP_FLUSHDA
- +#define OP_MATCH_INITD OP_INITD
- +#define OP_MATCH_CALL OP_CALL
- +#define OP_MATCH_CMPEQI OP_CMPEQI
- +#define OP_MATCH_CMPGEI OP_CMPGEI
- +#define OP_MATCH_CMPGEUI OP_CMPGEUI
- +#define OP_MATCH_CMPLTI OP_CMPLTI
- +#define OP_MATCH_CMPLTUI OP_CMPLTUI
- +#define OP_MATCH_CMPNEI OP_CMPNEI
- +#define OP_MATCH_JMPI OP_JMPI
- +#define OP_MATCH_LDB OP_LDB
- +#define OP_MATCH_LDBIO OP_LDBIO
- +#define OP_MATCH_LDBU OP_LDBU
- +#define OP_MATCH_LDBUIO OP_LDBUIO
- +#define OP_MATCH_LDH OP_LDH
- +#define OP_MATCH_LDHIO OP_LDHIO
- +#define OP_MATCH_LDHU OP_LDHU
- +#define OP_MATCH_LDHUIO OP_LDHUIO
- +#define OP_MATCH_LDW OP_LDW
- +#define OP_MATCH_LDWIO OP_LDWIO
- +#define OP_MATCH_MULI OP_MULI
- +#define OP_MATCH_OPX OP_OPX
- +#define OP_MATCH_ORHI OP_ORHI
- +#define OP_MATCH_ORI OP_ORI
- +#define OP_MATCH_STB OP_STB
- +#define OP_MATCH_STBIO OP_STBIO
- +#define OP_MATCH_STH OP_STH
- +#define OP_MATCH_STHIO OP_STHIO
- +#define OP_MATCH_STW OP_STW
- +#define OP_MATCH_STWIO OP_STWIO
- +#define OP_MATCH_CUSTOM OP_CUSTOM
- +#define OP_MATCH_XORHI OP_XORHI
- +#define OP_MATCH_XORI OP_XORI
- +#define OP_MATCH_OPX OP_OPX
- +
- +
- +
- +/* OPX instruction values */
- +#define OP_MATCH_ADD ((OPX_ADD << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_AND ((OPX_AND << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_BREAK ((0x1e << 17) | (OPX_BREAK << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_BRET ((0xf0000000) | (OPX_BRET << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_CALLR ((0x1f << 17) | (OPX_CALLR << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_CMPEQ ((OPX_CMPEQ << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_CMPGE ((OPX_CMPGE << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_CMPGEU ((OPX_CMPGEU << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_CMPLT ((OPX_CMPLT << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_CMPLTU ((OPX_CMPLTU << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_CMPNE ((OPX_CMPNE << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_DIV ((OPX_DIV << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_DIVU ((OPX_DIVU << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_JMP ((OPX_JMP << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_MUL ((OPX_MUL << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_MULXSS ((OPX_MULXSS << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_MULXSU ((OPX_MULXSU << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_MULXUU ((OPX_MULXUU << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_NEXTPC ((OPX_NEXTPC << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_NOR ((OPX_NOR << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_OR ((OPX_OR << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_RDCTL ((OPX_RDCTL << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_RET ((0xf8000000) | (OPX_RET << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_ROL ((OPX_ROL << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_ROLI ((OPX_ROLI << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_ROR ((OPX_ROR << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_SLL ((OPX_SLL << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_SLLI ((OPX_SLLI << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_SRA ((OPX_SRA << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_SRAI ((OPX_SRAI << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_SRL ((OPX_SRL << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_SRLI ((OPX_SRLI << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_SUB ((OPX_SUB << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_SYNC ((OPX_SYNC << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_TRAP ((0x1d << 17) | (OPX_TRAP << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_ERET ((0xe8000000) | (OPX_ERET << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_WRCTL ((OPX_WRCTL << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_XOR ((OPX_XOR << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_FLUSHI ((OPX_FLUSHI << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_FLUSHP ((OPX_FLUSHP << IW_OPX_LSB) | (OP_OPX))
- +#define OP_MATCH_INITI ((OPX_INITI << IW_OPX_LSB) | (OP_OPX))
- +
- +/*
- + Some unusual op masks
- +*/
- +#define OP_MASK_BREAK ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP) & 0xfffff03f)
- +#define OP_MASK_CALLR ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
- +#define OP_MASK_JMP ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
- +#define OP_MASK_SYNC ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
- +#define OP_MASK_TRAP ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP) & 0xfffff83f)
- +#define OP_MASK_WRCTL ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP)) /*& 0xfffff83f */
- +#define OP_MASK_NEXTPC ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
- +#define OP_MASK_FLUSHI ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
- +#define OP_MASK_INITI ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
- +
- +#define OP_MASK_ROLI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
- +#define OP_MASK_SLLI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
- +#define OP_MASK_SRAI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
- +#define OP_MASK_SRLI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
- +#define OP_MASK_RDCTL ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP)) /*& 0xfffff83f */
- +
- +#ifndef OP_MASK
- +#define OP_MASK 0xffffffff
- +#endif
- +
- +/* These are the data structures we use to hold the instruction information */
- +
- +extern const struct nios2_opcode nios2_builtin_opcodes[];
- +extern const int bfd_nios2_num_builtin_opcodes;
- +extern struct nios2_opcode *nios2_opcodes;
- +extern int bfd_nios2_num_opcodes;
- +
- +/* These are the data structures used to hold the operand parsing information */
- +//extern const struct nios2_arg_parser nios2_arg_parsers[];
- +//extern struct nios2_arg_parser* nios2_arg_parsers;
- +//extern const int nios2_num_builtin_arg_parsers;
- +//extern int nios2_num_arg_parsers;
- +
- +/* These are the data structures used to hold the register information */
- +extern const struct nios2_reg nios2_builtin_regs[];
- +extern struct nios2_reg *nios2_regs;
- +extern const int nios2_num_builtin_regs;
- +extern int nios2_num_regs;
- +
- +/* Machine-independent macro for number of opcodes */
- +
- +#define NUMOPCODES bfd_nios2_num_opcodes
- +#define NUMREGISTERS nios2_num_regs;
- +
- +/* these are used in disassembly to get the correct register names */
- +#define NUMREGNAMES 32
- +#define NUMCTLREGNAMES 32
- +#define CTLREGBASE 42
- +#define COPROCREGBASE 83
- +#define NUMCOPROCREGNAMES 32
- +
- +
- +/* this is made extern so that the assembler can use it to find out
- + what instruction caused an error */
- +extern const struct nios2_opcode *nios2_find_opcode_hash (unsigned long);
- +
- +/* overflow message strings used in the assembler */
- +extern char *overflow_msgs[];
- +
- +#endif // _NIOS2_H
- diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am
- index ebd252f..a7ca06b 100644
- --- a/opcodes/Makefile.am
- +++ b/opcodes/Makefile.am
- @@ -146,6 +146,13 @@ CFILES = \
- mt-dis.c \
- mt-ibld.c \
- mt-opc.c \
- + nios2-opc.c \
- + nios2-dis.c \
- + ms1-asm.c \
- + ms1-desc.c \
- + ms1-dis.c \
- + ms1-ibld.c \
- + ms1-opc.c \
- ns32k-dis.c \
- openrisc-asm.c \
- openrisc-desc.c \
- @@ -281,6 +288,8 @@ ALL_MACHINES = \
- mt-dis.lo \
- mt-ibld.lo \
- mt-opc.lo \
- + nios2-opc.lo \
- + nios2-dis.lo \
- ns32k-dis.lo \
- openrisc-asm.lo \
- openrisc-desc.lo \
- @@ -980,6 +989,13 @@ mt-opc.lo: mt-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
- mt-desc.h $(INCDIR)/opcode/cgen-bitset.h $(INCDIR)/opcode/cgen.h \
- $(INCDIR)/symcat.h $(INCDIR)/opcode/cgen-bitset.h mt-opc.h \
- $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h $(INCDIR)/safe-ctype.h
- +nios2-opc.lo: nios2-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
- + $(INCDIR)/opcode/nios2.h
- +nios2-dis.lo: nios2-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
- + $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/nios2.h \
- + opintl.h $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h \
- + $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
- + $(INCDIR)/elf/nios2.h $(INCDIR)/elf/reloc-macros.h
- ns32k-dis.lo: ns32k-dis.c $(BFD_H) $(INCDIR)/ansidecl.h \
- $(INCDIR)/symcat.h sysdep.h config.h $(INCDIR)/ansidecl.h \
- $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/opcode/ns32k.h \
- diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in
- index 85003e6..9e3baae 100644
- --- a/opcodes/Makefile.in
- +++ b/opcodes/Makefile.in
- @@ -360,6 +360,8 @@ CFILES = \
- mt-dis.c \
- mt-ibld.c \
- mt-opc.c \
- + nios2-opc.c \
- + nios2-dis.c \
- ns32k-dis.c \
- openrisc-asm.c \
- openrisc-desc.c \
- @@ -495,6 +497,8 @@ ALL_MACHINES = \
- mt-dis.lo \
- mt-ibld.lo \
- mt-opc.lo \
- + nios2-opc.lo \
- + nios2-dis.lo \
- ns32k-dis.lo \
- openrisc-asm.lo \
- openrisc-desc.lo \
- @@ -1517,6 +1521,13 @@ mt-opc.lo: mt-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
- mt-desc.h $(INCDIR)/opcode/cgen-bitset.h $(INCDIR)/opcode/cgen.h \
- $(INCDIR)/symcat.h $(INCDIR)/opcode/cgen-bitset.h mt-opc.h \
- $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h $(INCDIR)/safe-ctype.h
- +nios2-opc.lo: nios2-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
- + $(INCDIR)/opcode/nios2.h
- +nios2-dis.lo: nios2-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
- + $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/nios2.h \
- + opintl.h $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h \
- + $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
- + $(INCDIR)/elf/nios2.h $(INCDIR)/elf/reloc-macros.h
- ns32k-dis.lo: ns32k-dis.c $(BFD_H) $(INCDIR)/ansidecl.h \
- $(INCDIR)/symcat.h sysdep.h config.h $(INCDIR)/ansidecl.h \
- $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/opcode/ns32k.h \
- diff --git a/opcodes/configure b/opcodes/configure
- index 8e3e27e..a28cc46 100755
- --- a/opcodes/configure
- +++ b/opcodes/configure
- @@ -6561,6 +6561,7 @@ if test x${all_targets} = xfalse ; then
- bfd_mn10300_arch) ta="$ta m10300-dis.lo m10300-opc.lo" ;;
- bfd_mt_arch) ta="$ta mt-asm.lo mt-desc.lo mt-dis.lo mt-ibld.lo mt-opc.lo" using_cgen=yes ;;
- bfd_msp430_arch) ta="$ta msp430-dis.lo" ;;
- + bfd_nios2_arch) ta="$ta nios2-opc.lo nios2-dis.lo" ;;
- bfd_ns32k_arch) ta="$ta ns32k-dis.lo" ;;
- bfd_openrisc_arch) ta="$ta openrisc-asm.lo openrisc-desc.lo openrisc-dis.lo openrisc-ibld.lo openrisc-opc.lo" using_cgen=yes ;;
- bfd_or32_arch) ta="$ta or32-dis.lo or32-opc.lo" using_cgen=yes ;;
- diff --git a/opcodes/configure.in b/opcodes/configure.in
- index d937784..c9df814 100644
- --- a/opcodes/configure.in
- +++ b/opcodes/configure.in
- @@ -190,6 +190,7 @@ if test x${all_targets} = xfalse ; then
- bfd_mn10300_arch) ta="$ta m10300-dis.lo m10300-opc.lo" ;;
- bfd_mt_arch) ta="$ta mt-asm.lo mt-desc.lo mt-dis.lo mt-ibld.lo mt-opc.lo" using_cgen=yes ;;
- bfd_msp430_arch) ta="$ta msp430-dis.lo" ;;
- + bfd_nios2_arch) ta="$ta nios2-opc.lo nios2-dis.lo" ;;
- bfd_ns32k_arch) ta="$ta ns32k-dis.lo" ;;
- bfd_openrisc_arch) ta="$ta openrisc-asm.lo openrisc-desc.lo openrisc-dis.lo openrisc-ibld.lo openrisc-opc.lo" using_cgen=yes ;;
- bfd_or32_arch) ta="$ta or32-dis.lo or32-opc.lo" using_cgen=yes ;;
- diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c
- index ca28f56..dfacbb9 100644
- --- a/opcodes/disassemble.c
- +++ b/opcodes/disassemble.c
- @@ -80,6 +80,7 @@
- #define ARCH_xtensa
- #define ARCH_z80
- #define ARCH_z8k
- +#define ARCH_nios2
- #define INCLUDE_SHMEDIA
- #endif
-
- @@ -424,6 +425,14 @@ disassembler (abfd)
- disassemble = print_insn_iq2000;
- break;
- #endif
- +#ifdef ARCH_nios2
- + case bfd_arch_nios2:
- + if (bfd_big_endian (abfd))
- + disassemble = print_insn_big_nios2;
- + else
- + disassemble = print_insn_little_nios2;
- + break;
- +#endif
- #ifdef ARCH_m32c
- case bfd_arch_m32c:
- disassemble = print_insn_m32c;
- diff --git a/opcodes/nios2-dis.c b/opcodes/nios2-dis.c
- new file mode 100644
- index 0000000..ac9eb0d
- --- /dev/null
- +++ b/opcodes/nios2-dis.c
- @@ -0,0 +1,462 @@
- +/* nios2-dis.c -- Altera New Jersey disassemble routines.
- +
- + Copyright (C) 2003
- + by Nigel Gray (ngray@altera.com).
- +
- +This file is part of GDB, GAS, and the GNU binutils.
- +
- +GDB, GAS, and the GNU binutils are free software; you can redistribute
- +them and/or modify them under the terms of the GNU General Public
- +License as published by the Free Software Foundation; either version
- +1, or (at your option) any later version.
- +
- +GDB, GAS, and the GNU binutils are distributed in the hope that they
- +will be useful, but WITHOUT ANY WARRANTY; without even the implied
- +warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- +the GNU General Public License for more details.
- +
- +You should have received a copy of the GNU General Public License
- +along with this file; see the file COPYING. If not, write to the Free
- +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
- +
- +#include <stdlib.h>
- +#include <assert.h>
- +#include <string.h>
- +#include "dis-asm.h"
- +#include "opcode/nios2.h"
- +
- +/* No symbol table is available when this code runs out in an embedded
- + system as when it is used for disassembler support in a monitor. */
- +
- +#if !defined(EMBEDDED_ENV)
- +#define SYMTAB_AVAILABLE 1
- +#include "elf-bfd.h"
- +#include "elf/nios2.h"
- +#endif
- +
- +/* length of New Jersey instruction in bytes */
- +#define INSNLEN 4
- +
- +/* helper function prototypes */
- +static int nios2_disassemble (bfd_vma, unsigned long, disassemble_info *);
- +static void nios2_init_opcode_hash (void);
- +
- +
- +static int nios2_print_insn_arg (const char *argptr, unsigned long opcode,
- + bfd_vma address, disassemble_info * info);
- +
- +
- +/* print_insn_nios2 is the main disassemble function for New Jersey.
- + The function diassembler(abfd) (source in disassemble.c) returns a
- + pointer to this either print_insn_big_nios2 or
- + print_insn_little_nios2, which in turn call this function, when the
- + bfd machine type is New Jersey. print_insn_nios2 reads the
- + instruction word at the address given, and prints the disassembled
- + instruction on the stream info->stream using info->fprintf_func. */
- +
- +static int
- +print_insn_nios2 (bfd_vma address, disassemble_info * info,
- + enum bfd_endian endianness)
- +{
- + /* buffer into which the instruction bytes are written */
- + bfd_byte buffer[INSNLEN];
- + /* used to indicate return status from function calls */
- + int status;
- +
- + assert (info != NULL);
- +
- + status = (*info->read_memory_func) (address, buffer, INSNLEN, info);
- + if (status == 0)
- + {
- + unsigned long insn;
- + if (endianness == BFD_ENDIAN_BIG)
- + insn = (unsigned long) bfd_getb32 (buffer);
- + else
- + insn = (unsigned long) bfd_getl32 (buffer);
- + status = nios2_disassemble (address, insn, info);
- + }
- + else
- + {
- + (*info->memory_error_func) (status, address, info);
- + status = -1;
- + }
- + return status;
- +}
- +
- +int
- +print_insn_big_nios2 (bfd_vma address, disassemble_info * info)
- +{
- + return print_insn_nios2 (address, info, BFD_ENDIAN_BIG);
- +}
- +
- +int
- +print_insn_little_nios2 (bfd_vma address, disassemble_info * info)
- +{
- + return print_insn_nios2 (address, info, BFD_ENDIAN_LITTLE);
- +}
- +
- +/* Data structures used by the opcode hash table */
- +
- +typedef struct _nios2_opcode_hash
- +{
- + const struct nios2_opcode *opcode;
- + struct _nios2_opcode_hash *next;
- +} nios2_opcode_hash;
- +
- +static bfd_boolean nios2_hash_init = 0;
- +static nios2_opcode_hash *nios2_hash[(OP_MASK_OP) + 1];
- +
- +/* separate hash table for pseudo-ops */
- +static nios2_opcode_hash *nios2_ps_hash[(OP_MASK_OP) + 1];
- +
- +/* Function to initialize the opcode hash table */
- +
- +void
- +nios2_init_opcode_hash ()
- +{
- + unsigned int i;
- + register const struct nios2_opcode *op;
- + nios2_opcode_hash *tmp_hash;
- +
- + for (i = 0; i <= OP_MASK_OP; ++i)
- + {
- + nios2_hash[0] = NULL;
- + }
- + for (i = 0; i <= OP_MASK_OP; i++)
- + {
- + for (op = nios2_opcodes; op < &nios2_opcodes[NUMOPCODES]; op++)
- + {
- + if ((op->pinfo & NIOS2_INSN_MACRO) == NIOS2_INSN_MACRO)
- + {
- + if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP) &&
- + (op->
- + pinfo & (NIOS2_INSN_MACRO_MOV | NIOS2_INSN_MACRO_MOVI) &
- + 0x7fffffff) != 0)
- + {
- + tmp_hash = nios2_ps_hash[i];
- + if (tmp_hash == NULL)
- + {
- + tmp_hash =
- + (nios2_opcode_hash *)
- + malloc (sizeof (nios2_opcode_hash));
- + nios2_ps_hash[i] = tmp_hash;
- + }
- + else
- + {
- + while (tmp_hash->next != NULL)
- + tmp_hash = tmp_hash->next;
- + tmp_hash->next =
- + (nios2_opcode_hash *)
- + malloc (sizeof (nios2_opcode_hash));
- + tmp_hash = tmp_hash->next;
- + }
- + if (tmp_hash == NULL)
- + {
- + fprintf (stderr,
- + "error allocating memory...broken disassembler\n");
- + abort ();
- + }
- + tmp_hash->opcode = op;
- + tmp_hash->next = NULL;
- + }
- + }
- + else if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
- + {
- + tmp_hash = nios2_hash[i];
- + if (tmp_hash == NULL)
- + {
- + tmp_hash =
- + (nios2_opcode_hash *) malloc (sizeof (nios2_opcode_hash));
- + nios2_hash[i] = tmp_hash;
- + }
- + else
- + {
- + while (tmp_hash->next != NULL)
- + tmp_hash = tmp_hash->next;
- + tmp_hash->next =
- + (nios2_opcode_hash *) malloc (sizeof (nios2_opcode_hash));
- + tmp_hash = tmp_hash->next;
- + }
- + if (tmp_hash == NULL)
- + {
- + fprintf (stderr,
- + "error allocating memory...broken disassembler\n");
- + abort ();
- + }
- + tmp_hash->opcode = op;
- + tmp_hash->next = NULL;
- + }
- + }
- + }
- + nios2_hash_init = 1;
- +#ifdef DEBUG_HASHTABLE
- + for (i = 0; i <= OP_MASK_OP; ++i)
- + {
- + printf ("index: 0x%02X ops: ", i);
- + tmp_hash = nios2_hash[i];
- + if (tmp_hash != NULL)
- + {
- + while (tmp_hash != NULL)
- + {
- + printf ("%s ", tmp_hash->opcode->name);
- + tmp_hash = tmp_hash->next;
- + }
- + }
- + printf ("\n");
- + }
- +
- + for (i = 0; i <= OP_MASK_OP; ++i)
- + {
- + printf ("index: 0x%02X ops: ", i);
- + tmp_hash = nios2_ps_hash[i];
- + if (tmp_hash != NULL)
- + {
- + while (tmp_hash != NULL)
- + {
- + printf ("%s ", tmp_hash->opcode->name);
- + tmp_hash = tmp_hash->next;
- + }
- + }
- + printf ("\n");
- + }
- +#endif
- +}
- +
- +/* Function which returns a pointer to an nios2_opcode struct for
- + a given instruction opcode, or NULL if there is an error */
- +
- +const struct nios2_opcode *
- +nios2_find_opcode_hash (unsigned long opcode)
- +{
- + nios2_opcode_hash *entry;
- +
- + /* Build a hash table to shorten the search time. */
- + if (!nios2_hash_init)
- + {
- + nios2_init_opcode_hash ();
- + }
- +
- + /* first look in the pseudo-op hashtable */
- + entry = nios2_ps_hash[(opcode >> OP_SH_OP) & OP_MASK_OP];
- +
- + /* look for a match and if we get one, this is the instruction we decode */
- + while (entry != NULL)
- + {
- + if ((entry->opcode->match) == (opcode & entry->opcode->mask))
- + return entry->opcode;
- + else
- + entry = entry->next;
- + }
- +
- + /* if we haven't yet returned, then we need to look in the main
- + hashtable */
- + entry = nios2_hash[(opcode >> OP_SH_OP) & OP_MASK_OP];
- +
- + if (entry == NULL)
- + return NULL;
- +
- +
- + while (entry != NULL)
- + {
- + if ((entry->opcode->match) == (opcode & entry->opcode->mask))
- + return entry->opcode;
- + else
- + entry = entry->next;
- + }
- +
- + return NULL;
- +}
- +
- +/* nios2_disassemble does all the work of disassembling a New Jersey
- + instruction opcode */
- +
- +int
- +nios2_disassemble (bfd_vma address, unsigned long opcode,
- + disassemble_info * info)
- +{
- + const struct nios2_opcode *op;
- + const char *argstr;
- +
- + info->bytes_per_line = INSNLEN;
- + info->bytes_per_chunk = INSNLEN;
- + info->display_endian = info->endian;
- + info->insn_info_valid = 1;
- + info->branch_delay_insns = 0;
- + info->data_size = 0;
- + info->insn_type = dis_nonbranch;
- + info->target = 0;
- + info->target2 = 0;
- +
- + /* Find the major opcode and use this to disassemble
- + the instruction and its arguments */
- + op = nios2_find_opcode_hash (opcode);
- +
- + if (op != NULL)
- + {
- + bfd_boolean is_nop = FALSE;
- + if (op->pinfo == NIOS2_INSN_MACRO_MOV)
- + {
- + /* check for mov r0, r0 and if it is
- + change to nop */
- + int dst, src;
- + dst = GET_INSN_FIELD (RRD, opcode);
- + src = GET_INSN_FIELD (RRS, opcode);
- + if (dst == 0 && src == 0)
- + {
- + (*info->fprintf_func) (info->stream, "nop");
- + is_nop = TRUE;
- + }
- + else
- + {
- + (*info->fprintf_func) (info->stream, "%s", op->name);
- + }
- + }
- + else
- + {
- + (*info->fprintf_func) (info->stream, "%s", op->name);
- + }
- +
- + if (!is_nop)
- + {
- + argstr = op->args;
- + if (argstr != NULL && *argstr != '\0')
- + {
- + (*info->fprintf_func) (info->stream, "\t");
- + while (*argstr != '\0')
- + {
- + nios2_print_insn_arg (argstr, opcode, address, info);
- + ++argstr;
- + }
- + }
- + }
- + }
- + else
- + {
- + /* Handle undefined instructions. */
- + info->insn_type = dis_noninsn;
- + (*info->fprintf_func) (info->stream, "0x%x", (unsigned int) opcode);
- + }
- + // this tells the caller how far to advance the program counter
- + return INSNLEN;
- +}
- +
- +/* The function nios2_print_insn_arg uses the character pointed
- + to by argptr to determine how it print the next token or separator
- + character in the arguments to an instruction */
- +int
- +nios2_print_insn_arg (const char *argptr,
- + unsigned long opcode, bfd_vma address,
- + disassemble_info * info)
- +{
- + unsigned long i = 0;
- + unsigned long reg_base;
- +
- + assert (argptr != NULL);
- + assert (info != NULL);
- +
- + switch (*argptr)
- + {
- + case ',':
- + case '(':
- + case ')':
- + (*info->fprintf_func) (info->stream, "%c", *argptr);
- + break;
- + case 'd':
- + i = GET_INSN_FIELD (RRD, opcode);
- +
- + if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
- + && GET_INSN_FIELD (CUSTOM_C, opcode) == 0)
- + reg_base = COPROCREGBASE;
- + else
- + reg_base = 0;
- +
- + if (i < NUMREGNAMES)
- + (*info->fprintf_func) (info->stream, "%s",
- + nios2_regs[i + reg_base].name);
- + else
- + (*info->fprintf_func) (info->stream, "unknown");
- + break;
- + case 's':
- + i = GET_INSN_FIELD (RRS, opcode);
- +
- + if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
- + && GET_INSN_FIELD (CUSTOM_A, opcode) == 0)
- + reg_base = COPROCREGBASE;
- + else
- + reg_base = 0;
- +
- + if (i < NUMREGNAMES)
- + (*info->fprintf_func) (info->stream, "%s",
- + nios2_regs[i + reg_base].name);
- + else
- + (*info->fprintf_func) (info->stream, "unknown");
- + break;
- + case 't':
- + i = GET_INSN_FIELD (RRT, opcode);
- +
- + if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
- + && GET_INSN_FIELD (CUSTOM_B, opcode) == 0)
- + reg_base = COPROCREGBASE;
- + else
- + reg_base = 0;
- +
- + if (i < NUMREGNAMES)
- + (*info->fprintf_func) (info->stream, "%s",
- + nios2_regs[i + reg_base].name);
- + else
- + (*info->fprintf_func) (info->stream, "unknown");
- + break;
- + case 'i':
- + /* 16-bit signed immediate */
- + i = (signed) (GET_INSN_FIELD (IMM16, opcode) << 16) >> 16;
- + (*info->fprintf_func) (info->stream, "%d", (int) i);
- + break;
- + case 'u':
- + /* 16-bit unsigned immediate */
- + i = GET_INSN_FIELD (IMM16, opcode);
- + (*info->fprintf_func) (info->stream, "%d", (int) i);
- + break;
- + case 'o':
- + /* 16-bit signed immediate address offset */
- + i = (signed) (GET_INSN_FIELD (IMM16, opcode) << 16) >> 16;
- + address = address + 4 + i; /* NG changed to byte offset 1/9/03 */
- + (*info->print_address_func) (address, info);
- + break;
- + case 'p':
- + /* 5-bit unsigned immediate */
- + i = GET_INSN_FIELD (CACHE_OPX, opcode);
- + (*info->fprintf_func) (info->stream, "%d", (int) i);
- + break;
- + case 'j':
- + /* 5-bit unsigned immediate */
- + i = GET_INSN_FIELD (IMM5, opcode);
- + (*info->fprintf_func) (info->stream, "%d", (int) i);
- + break;
- + case 'l':
- + /* 8-bit unsigned immediate */
- + /* FIXME - not yet implemented */
- + i = GET_INSN_FIELD (CUSTOM_N, opcode);
- + (*info->fprintf_func) (info->stream, "%u", (int) i);
- + break;
- + case 'm':
- + /* 26-bit unsigned immediate */
- + i = GET_INSN_FIELD (IMM26, opcode);
- + /* this translates to an address because its only used in call instructions */
- + address = (address & 0xf0000000) | (i << 2);
- + (*info->print_address_func) (address, info);
- + break;
- + case 'c':
- + i = GET_INSN_FIELD (IMM5, opcode); /* ctrl register index */
- + (*info->fprintf_func) (info->stream, "%s",
- + nios2_regs[CTLREGBASE + i].name);
- + break;
- + case 'b':
- + i = GET_INSN_FIELD (IMM5, opcode);
- + (*info->fprintf_func) (info->stream, "%d", (int) i);
- + break;
- + default:
- + (*info->fprintf_func) (info->stream, "unknown");
- + break;
- + }
- + return 0;
- +}
- diff --git a/opcodes/nios2-opc.c b/opcodes/nios2-opc.c
- new file mode 100644
- index 0000000..c860207
- --- /dev/null
- +++ b/opcodes/nios2-opc.c
- @@ -0,0 +1,320 @@
- +/* nios2-opc.c -- Altera New Jersey opcode list.
- +
- + Copyright (C) 2003
- + by Nigel Gray (ngray@altera.com).
- +
- +This file is part of GDB, GAS, and the GNU binutils.
- +
- +GDB, GAS, and the GNU binutils are free software; you can redistribute
- +them and/or modify them under the terms of the GNU General Public
- +License as published by the Free Software Foundation; either version
- +1, or (at your option) any later version.
- +
- +GDB, GAS, and the GNU binutils are distributed in the hope that they
- +will be useful, but WITHOUT ANY WARRANTY; without even the implied
- +warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- +the GNU General Public License for more details.
- +
- +You should have received a copy of the GNU General Public License
- +along with this file; see the file COPYING. If not, write to the Free
- +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
- +
- +#include <stdio.h>
- +#include "opcode/nios2.h"
- +
- +/* Register string table */
- +
- +const struct nios2_reg nios2_builtin_regs[] = {
- + {"zero", 0},
- + {"at", 1}, // assembler temporary
- + {"r2", 2},
- + {"r3", 3},
- + {"r4", 4},
- + {"r5", 5},
- + {"r6", 6},
- + {"r7", 7},
- + {"r8", 8},
- + {"r9", 9},
- + {"r10", 10},
- + {"r11", 11},
- + {"r12", 12},
- + {"r13", 13},
- + {"r14", 14},
- + {"r15", 15},
- + {"r16", 16},
- + {"r17", 17},
- + {"r18", 18},
- + {"r19", 19},
- + {"r20", 20},
- + {"r21", 21},
- + {"r22", 22},
- + {"r23", 23},
- + {"et", 24},
- + {"bt", 25},
- + {"gp", 26}, /* global pointer */
- + {"sp", 27}, /* stack pointer */
- + {"fp", 28}, /* frame pointer */
- + {"ea", 29}, /* exception return address */
- + {"ba", 30}, /* breakpoint return address */
- + {"ra", 31}, /* return address */
- +
- + /* alternative names for special registers */
- + {"r0", 0},
- + {"r1", 1},
- + {"r24", 24},
- + {"r25", 25},
- + {"r26", 26},
- + {"r27", 27},
- + {"r28", 28},
- + {"r29", 29},
- + {"r30", 30},
- + {"r31", 31},
- +
- + /* control register names */
- + {"status", 0},
- + {"estatus", 1},
- + {"bstatus", 2},
- + {"ienable", 3},
- + {"ipending", 4},
- + {"cpuid", 5},
- + {"ctl6", 6},
- + {"ctl7", 7},
- + {"pteaddr", 8},
- + {"tlbacc", 9},
- + {"tlbmisc", 10},
- + {"fstatus", 11},
- + {"ctl12", 12},
- + {"ctl13", 13},
- + {"ctl14", 14},
- + {"ctl15", 15},
- + {"ctl16", 16},
- + {"ctl17", 17},
- + {"ctl18", 18},
- + {"ctl19", 19},
- + {"ctl20", 20},
- + {"ctl21", 21},
- + {"ctl22", 22},
- + {"ctl23", 23},
- + {"ctl24", 24},
- + {"ctl25", 25},
- + {"ctl26", 26},
- + {"ctl27", 27},
- + {"ctl28", 28},
- + {"ctl29", 29},
- + {"ctl30", 30},
- + {"ctl31", 31},
- +
- + /* alternative names for special control registers */
- + {"ctl0", 0},
- + {"ctl1", 1},
- + {"ctl2", 2},
- + {"ctl3", 3},
- + {"ctl4", 4},
- + {"ctl5", 5},
- + {"ctl8", 8},
- + {"ctl9", 9},
- + {"ctl10", 10},
- + {"ctl11", 11},
- +
- + /* coprocessor register names */
- + {"c0", 0},
- + {"c1", 1},
- + {"c2", 2},
- + {"c3", 3},
- + {"c4", 4},
- + {"c5", 5},
- + {"c6", 6},
- + {"c7", 7},
- + {"c8", 8},
- + {"c9", 9},
- + {"c10", 10},
- + {"c11", 11},
- + {"c12", 12},
- + {"c13", 13},
- + {"c14", 14},
- + {"c15", 15},
- + {"c16", 16},
- + {"c17", 17},
- + {"c18", 18},
- + {"c19", 19},
- + {"c20", 20},
- + {"c21", 21},
- + {"c22", 22},
- + {"c23", 23},
- + {"c24", 24},
- + {"c25", 25},
- + {"c26", 26},
- + {"c27", 27},
- + {"c28", 28},
- + {"c29", 29},
- + {"c30", 30},
- + {"c31", 31},
- +};
- +
- +#define NIOS2_NUM_REGS \
- + ((sizeof nios2_builtin_regs) / (sizeof (nios2_builtin_regs[0])))
- +const int nios2_num_builtin_regs = NIOS2_NUM_REGS;
- +
- +/* const removed from the following to allow for dynamic extensions to the
- + * built-in instruction set. */
- +struct nios2_reg *nios2_regs = (struct nios2_reg *) nios2_builtin_regs;
- +int nios2_num_regs = NIOS2_NUM_REGS;
- +#undef NIOS2_NUM_REGS
- +
- +/* overflow message string templates */
- +
- +char *overflow_msgs[] = {
- + "call target address 0x%08x out of range 0x%08x to 0x%08x",
- + "branch offset %d out of range %d to %d",
- + "%s offset %d out of range %d to %d",
- + "immediate value %d out of range %d to %d",
- + "immediate value %u out of range %u to %u",
- + "immediate value %u out of range %u to %u",
- + "custom instruction opcode %u out of range %u to %u",
- +};
- +
- +
- +
- +/*--------------------------------------------------------------------------------
- + This is the opcode table used by the New Jersey GNU as, disassembler and GDB
- + --------------------------------------------------------------------------------*/
- +
- +/*
- + The following letters can appear in the args field of the nios2_opcode
- + structure:
- +
- + c - a 5-bit control register index or break opcode
- + d - a 5-bit destination register index
- + s - a 5-bit left source register index
- + t - a 5-bit right source register index
- + i - a 16-bit signed immediate
- + u - a 16-bit unsigned immediate
- +
- + j - a 5-bit unsigned immediate
- + k - a 6-bit unsigned immediate
- + l - an 8-bit unsigned immediate
- + m - a 26-bit unsigned immediate
- +*/
- +
- +/* *INDENT-OFF* */
- +/* FIXME: Re-format for GNU standards */
- +const struct nios2_opcode nios2_builtin_opcodes[] =
- +{
- + /* name, args, args_test num_args, match, mask, pinfo */
- + {"add", "d,s,t", "d,s,t,E", 3, OP_MATCH_ADD, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"addi", "t,s,i", "t,s,i,E", 3, OP_MATCH_ADDI, OP_MASK_IOP, NIOS2_INSN_ADDI, signed_immed16_overflow },
- + {"subi", "t,s,i", "t,s,i,E", 3, OP_MATCH_ADDI, OP_MASK_IOP, NIOS2_INSN_MACRO, signed_immed16_overflow },
- + {"and", "d,s,t", "d,s,t,E", 3, OP_MATCH_AND, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"andhi", "t,s,u", "t,s,u,E", 3, OP_MATCH_ANDHI, OP_MASK_IOP, 0, unsigned_immed16_overflow },
- + {"andi", "t,s,u", "t,s,u,E", 3, OP_MATCH_ANDI, OP_MASK_IOP, NIOS2_INSN_ANDI, unsigned_immed16_overflow },
- + {"beq", "s,t,o", "s,t,o,E", 3, OP_MATCH_BEQ, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow },
- + {"bge", "s,t,o", "s,t,o,E", 3, OP_MATCH_BGE, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow },
- + {"bgeu", "s,t,o", "s,t,o,E", 3, OP_MATCH_BGEU, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow },
- + {"bgt", "s,t,o", "s,t,o,E", 3, OP_MATCH_BLT, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow },
- + {"bgtu", "s,t,o", "s,t,o,E", 3, OP_MATCH_BLTU, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow },
- + {"ble", "s,t,o", "s,t,o,E", 3, OP_MATCH_BGE, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow },
- + {"bleu", "s,t,o", "s,t,o,E", 3, OP_MATCH_BGEU, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow },
- + {"blt", "s,t,o", "s,t,o,E", 3, OP_MATCH_BLT, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow },
- + {"bltu", "s,t,o", "s,t,o,E", 3, OP_MATCH_BLTU, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow },
- + {"bne", "s,t,o", "s,t,o,E", 3, OP_MATCH_BNE, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow },
- + {"br", "o", "o,E", 1, OP_MATCH_BR, OP_MASK_IOP, NIOS2_INSN_UBRANCH, branch_target_overflow },
- + {"break", "b", "b,E", 1, OP_MATCH_BREAK, OP_MASK_BREAK, 0, no_overflow },
- + {"bret", "", "E", 0, OP_MATCH_BRET, OP_MASK, 0, no_overflow },
- + {"flushd", "i(s)", "i(s)E", 2, OP_MATCH_FLUSHD, OP_MASK_IOP, 0, signed_immed16_overflow },
- + {"flushda", "i(s)", "i(s)E", 2, OP_MATCH_FLUSHDA, OP_MASK_IOP, 0, signed_immed16_overflow },
- + {"flushi", "s", "s,E", 1, OP_MATCH_FLUSHI, OP_MASK_FLUSHI, 0, no_overflow },
- + {"flushp", "", "E", 0, OP_MATCH_FLUSHP, OP_MASK, 0, no_overflow },
- + {"initd", "i(s)", "i(s)E", 2, OP_MATCH_INITD, OP_MASK_IOP, 0, signed_immed16_overflow },
- + {"initi", "s", "s,E", 1, OP_MATCH_INITI, OP_MASK_INITI, 0, no_overflow },
- + {"call", "m", "m,E", 1, OP_MATCH_CALL, OP_MASK_IOP, NIOS2_INSN_CALL, call_target_overflow },
- + {"callr", "s", "s,E", 1, OP_MATCH_CALLR, OP_MASK_CALLR, 0, no_overflow },
- + {"cmpeq", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPEQ, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"cmpeqi", "t,s,i", "t,s,i,E", 3, OP_MATCH_CMPEQI, OP_MASK_IOP, 0, signed_immed16_overflow },
- + {"cmpge", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPGE, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"cmpgei", "t,s,i", "t,s,i,E", 3, OP_MATCH_CMPGEI, OP_MASK_IOP, 0, signed_immed16_overflow },
- + {"cmpgeu", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPGEU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"cmpgeui", "t,s,u", "t,s,u,E", 3, OP_MATCH_CMPGEUI, OP_MASK_IOP, 0, unsigned_immed16_overflow },
- + {"cmpgt", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPLT, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow },
- + {"cmpgti", "t,s,i", "t,s,i,E", 3, OP_MATCH_CMPGEI, OP_MASK_IOP, NIOS2_INSN_MACRO, signed_immed16_overflow },
- + {"cmpgtu", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPLTU, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow },
- + {"cmpgtui", "t,s,u", "t,s,u,E", 3, OP_MATCH_CMPGEUI, OP_MASK_IOP, NIOS2_INSN_MACRO, unsigned_immed16_overflow },
- + {"cmple", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPGE, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow },
- + {"cmplei", "t,s,i", "t,s,i,E", 3, OP_MATCH_CMPLTI, OP_MASK_IOP, NIOS2_INSN_MACRO, signed_immed16_overflow },
- + {"cmpleu", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPGEU, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow },
- + {"cmpleui", "t,s,u", "t,s,u,E", 3, OP_MATCH_CMPLTUI, OP_MASK_IOP, NIOS2_INSN_MACRO, unsigned_immed16_overflow },
- + {"cmplt", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPLT, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"cmplti", "t,s,i", "t,s,i,E", 3, OP_MATCH_CMPLTI, OP_MASK_IOP, 0, signed_immed16_overflow },
- + {"cmpltu", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPLTU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"cmpltui", "t,s,u", "t,s,u,E", 3, OP_MATCH_CMPLTUI, OP_MASK_IOP, 0, unsigned_immed16_overflow },
- + {"cmpne", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPNE, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"cmpnei", "t,s,i", "t,s,i,E", 3, OP_MATCH_CMPNEI, OP_MASK_IOP, 0, signed_immed16_overflow },
- + {"div", "d,s,t", "d,s,t,E", 3, OP_MATCH_DIV, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"divu", "d,s,t", "d,s,t,E", 3, OP_MATCH_DIVU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"jmp", "s", "s,E", 1, OP_MATCH_JMP, OP_MASK_JMP, 0, no_overflow },
- + {"jmpi", "m", "m,E", 1, OP_MATCH_JMPI, OP_MASK_IOP, 0, no_overflow },
- + {"ldb", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDB, OP_MASK_IOP, 0, address_offset_overflow },
- + {"ldbio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDBIO, OP_MASK_IOP, 0, address_offset_overflow },
- + {"ldbu", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDBU, OP_MASK_IOP, 0, address_offset_overflow },
- + {"ldbuio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDBUIO, OP_MASK_IOP, 0, address_offset_overflow },
- + {"ldh", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDH, OP_MASK_IOP, 0, address_offset_overflow },
- + {"ldhio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDHIO, OP_MASK_IOP, 0, address_offset_overflow },
- + {"ldhu", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDHU, OP_MASK_IOP, 0, address_offset_overflow },
- + {"ldhuio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDHUIO, OP_MASK_IOP, 0, address_offset_overflow },
- + {"ldw", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDW, OP_MASK_IOP, 0, address_offset_overflow },
- + {"ldwio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDWIO, OP_MASK_IOP, 0, address_offset_overflow },
- + {"mov", "d,s", "d,s,E", 2, OP_MATCH_ADD, OP_MASK_RRT|OP_MASK_ROPX|OP_MASK_ROP, NIOS2_INSN_MACRO_MOV, no_overflow },
- + {"movhi", "t,u", "t,u,E", 2, OP_MATCH_ORHI, OP_MASK_IRS|OP_MASK_IOP, NIOS2_INSN_MACRO_MOVI, unsigned_immed16_overflow },
- + {"movui", "t,u", "t,u,E", 2, OP_MATCH_ORI, OP_MASK_IRS|OP_MASK_IOP, NIOS2_INSN_MACRO_MOVI, unsigned_immed16_overflow },
- + {"movi", "t,i", "t,i,E", 2, OP_MATCH_ADDI, OP_MASK_IRS|OP_MASK_IOP, NIOS2_INSN_MACRO_MOVI, signed_immed16_overflow },
- + /* movia expands to two instructions so there is no mask or match */
- + {"movia", "t,o", "t,o,E", 2, OP_MATCH_ORHI, OP_MASK_IOP, NIOS2_INSN_MACRO_MOVIA, no_overflow },
- + {"mul", "d,s,t", "d,s,t,E", 3, OP_MATCH_MUL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"muli", "t,s,i", "t,s,i,E", 3, OP_MATCH_MULI, OP_MASK_IOP, 0, signed_immed16_overflow },
- + {"mulxss", "d,s,t", "d,s,t,E", 3, OP_MATCH_MULXSS, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"mulxsu", "d,s,t", "d,s,t,E", 3, OP_MATCH_MULXSU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"mulxuu", "d,s,t", "d,s,t,E", 3, OP_MATCH_MULXUU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"nextpc", "d", "d,E", 1, OP_MATCH_NEXTPC, OP_MASK_NEXTPC, 0, no_overflow },
- + {"nop", "", "E", 0, OP_MATCH_ADD, OP_MASK, NIOS2_INSN_MACRO_MOV, no_overflow },
- + {"nor", "d,s,t", "d,s,t,E", 3, OP_MATCH_NOR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"or", "d,s,t", "d,s,t,E", 3, OP_MATCH_OR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"orhi", "t,s,u", "t,s,u,E", 3, OP_MATCH_ORHI, OP_MASK_IOP, 0, unsigned_immed16_overflow },
- + {"ori", "t,s,u", "t,s,u,E", 3, OP_MATCH_ORI, OP_MASK_IOP, NIOS2_INSN_ORI, unsigned_immed16_overflow },
- + {"rdctl", "d,c", "d,c,E", 2, OP_MATCH_RDCTL, OP_MASK_RDCTL, 0, no_overflow },
- + {"ret", "", "E", 0, OP_MATCH_RET, OP_MASK, 0, no_overflow },
- + {"rol", "d,s,t", "d,s,t,E", 3, OP_MATCH_ROL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"roli", "d,s,j", "d,s,j,E", 3, OP_MATCH_ROLI, OP_MASK_ROLI, 0, unsigned_immed5_overflow },
- + {"ror", "d,s,t", "d,s,t,E", 3, OP_MATCH_ROR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"sll", "d,s,t", "d,s,t,E", 3, OP_MATCH_SLL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"slli", "d,s,j", "d,s,j,E", 3, OP_MATCH_SLLI, OP_MASK_SLLI, 0, unsigned_immed5_overflow },
- + {"sra", "d,s,t", "d,s,t,E", 3, OP_MATCH_SRA, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"srai", "d,s,j", "d,s,j,E", 3, OP_MATCH_SRAI, OP_MASK_SRAI, 0, unsigned_immed5_overflow },
- + {"srl", "d,s,t", "d,s,t,E", 3, OP_MATCH_SRL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"srli", "d,s,j", "d,s,j,E", 3, OP_MATCH_SRLI, OP_MASK_SRLI, 0, unsigned_immed5_overflow },
- + {"stb", "t,i(s)", "t,i(s)E", 3, OP_MATCH_STB, OP_MASK_IOP, 0, address_offset_overflow },
- + {"stbio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_STBIO, OP_MASK_IOP, 0, address_offset_overflow },
- + {"sth", "t,i(s)", "t,i(s)E", 3, OP_MATCH_STH, OP_MASK_IOP, 0, address_offset_overflow },
- + {"sthio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_STHIO, OP_MASK_IOP, 0, address_offset_overflow },
- + {"stw", "t,i(s)", "t,i(s)E", 3, OP_MATCH_STW, OP_MASK_IOP, 0, address_offset_overflow },
- + {"stwio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_STWIO, OP_MASK_IOP, 0, address_offset_overflow },
- + {"sub", "d,s,t", "d,s,t,E", 3, OP_MATCH_SUB, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"sync", "", "E", 0, OP_MATCH_SYNC, OP_MASK_SYNC, 0, no_overflow },
- + {"trap", "", "E", 0, OP_MATCH_TRAP, OP_MASK_TRAP, 0, no_overflow },
- + {"eret", "", "E", 0, OP_MATCH_ERET, OP_MASK, 0, no_overflow },
- + {"custom", "l,d,s,t", "l,d,s,t,E", 4, OP_MATCH_CUSTOM, OP_MASK_ROP, 0, custom_opcode_overflow },
- + {"wrctl", "c,s", "c,s,E", 2, OP_MATCH_WRCTL, OP_MASK_WRCTL, 0, no_overflow },
- + {"xor", "d,s,t", "d,s,t,E", 3, OP_MATCH_XOR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
- + {"xorhi", "t,s,u", "t,s,u,E", 3, OP_MATCH_XORHI, OP_MASK_IOP, 0, unsigned_immed16_overflow },
- + {"xori", "t,s,u", "t,s,u,E", 3, OP_MATCH_XORI, OP_MASK_IOP, NIOS2_INSN_XORI, unsigned_immed16_overflow }
- +};
- +/* *INDENT-ON* */
- +
- +#define NIOS2_NUM_OPCODES \
- + ((sizeof nios2_builtin_opcodes) / (sizeof (nios2_builtin_opcodes[0])))
- +const int bfd_nios2_num_builtin_opcodes = NIOS2_NUM_OPCODES;
- +
- +/* const removed from the following to allow for dynamic extensions to the
- + * built-in instruction set. */
- +struct nios2_opcode *nios2_opcodes =
- + (struct nios2_opcode *) nios2_builtin_opcodes;
- +int bfd_nios2_num_opcodes = NIOS2_NUM_OPCODES;
- +#undef NIOS2_NUM_OPCODES
|