12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706337073370833709337103371133712337133371433715337163371733718337193372033721337223372333724337253372633727337283372933730337313373233733337343373533736337373373833739337403374133742337433374433745337463374733748337493375033751337523375333754337553375633757337583375933760337613376233763337643376533766337673376833769337703377133772337733377433775337763377733778337793378033781337823378333784337853378633787337883378933790337913379233793337943379533796337973379833799338003380133802338033380433805338063380733808338093381033811338123381333814338153381633817338183381933820338213382233823338243382533826338273382833829338303383133832338333383433835338363383733838338393384033841338423384333844338453384633847338483384933850338513385233853338543385533856338573385833859338603386133862338633386433865338663386733868338693387033871338723387333874338753387633877338783387933880338813388233883338843388533886338873388833889338903389133892338933389433895338963389733898338993390033901339023390333904339053390633907339083390933910339113391233913339143391533916339173391833919339203392133922339233392433925339263392733928339293393033931339323393333934339353393633937339383393933940339413394233943339443394533946339473394833949339503395133952339533395433955339563395733958339593396033961339623396333964339653396633967339683396933970339713397233973339743397533976339773397833979339803398133982339833398433985339863398733988339893399033991339923399333994339953399633997339983399934000340013400234003340043400534006340073400834009340103401134012340133401434015340163401734018340193402034021340223402334024340253402634027340283402934030340313403234033340343403534036340373403834039340403404134042340433404434045340463404734048340493405034051340523405334054340553405634057340583405934060340613406234063340643406534066340673406834069340703407134072340733407434075340763407734078340793408034081340823408334084340853408634087340883408934090340913409234093340943409534096340973409834099341003410134102341033410434105341063410734108341093411034111341123411334114341153411634117341183411934120341213412234123341243412534126341273412834129341303413134132341333413434135341363413734138341393414034141341423414334144341453414634147341483414934150341513415234153341543415534156341573415834159341603416134162341633416434165341663416734168341693417034171341723417334174341753417634177341783417934180341813418234183341843418534186341873418834189341903419134192341933419434195341963419734198341993420034201342023420334204342053420634207342083420934210342113421234213342143421534216342173421834219342203422134222342233422434225342263422734228342293423034231342323423334234342353423634237342383423934240342413424234243342443424534246342473424834249342503425134252342533425434255342563425734258342593426034261342623426334264342653426634267342683426934270342713427234273342743427534276342773427834279342803428134282342833428434285342863428734288342893429034291342923429334294342953429634297342983429934300343013430234303343043430534306343073430834309343103431134312343133431434315343163431734318343193432034321343223432334324343253432634327343283432934330343313433234333343343433534336343373433834339343403434134342343433434434345343463434734348343493435034351343523435334354343553435634357343583435934360343613436234363343643436534366343673436834369343703437134372343733437434375343763437734378343793438034381343823438334384343853438634387343883438934390343913439234393343943439534396343973439834399344003440134402344033440434405344063440734408344093441034411344123441334414344153441634417344183441934420344213442234423344243442534426344273442834429344303443134432344333443434435344363443734438344393444034441344423444334444344453444634447344483444934450344513445234453344543445534456344573445834459344603446134462344633446434465344663446734468344693447034471344723447334474344753447634477344783447934480344813448234483344843448534486344873448834489344903449134492344933449434495344963449734498344993450034501345023450334504345053450634507345083450934510345113451234513345143451534516345173451834519345203452134522345233452434525345263452734528345293453034531345323453334534345353453634537345383453934540345413454234543345443454534546345473454834549345503455134552345533455434555345563455734558345593456034561345623456334564345653456634567345683456934570345713457234573345743457534576345773457834579345803458134582345833458434585345863458734588345893459034591345923459334594345953459634597345983459934600346013460234603346043460534606346073460834609346103461134612346133461434615346163461734618346193462034621346223462334624346253462634627346283462934630346313463234633346343463534636346373463834639346403464134642346433464434645346463464734648346493465034651346523465334654346553465634657346583465934660346613466234663346643466534666346673466834669346703467134672346733467434675346763467734678346793468034681346823468334684346853468634687346883468934690346913469234693346943469534696346973469834699347003470134702347033470434705347063470734708347093471034711347123471334714347153471634717347183471934720347213472234723347243472534726347273472834729347303473134732347333473434735347363473734738347393474034741347423474334744347453474634747347483474934750347513475234753347543475534756347573475834759347603476134762347633476434765347663476734768347693477034771347723477334774347753477634777347783477934780347813478234783347843478534786347873478834789347903479134792347933479434795347963479734798347993480034801348023480334804348053480634807348083480934810348113481234813348143481534816348173481834819348203482134822348233482434825348263482734828348293483034831348323483334834348353483634837348383483934840348413484234843348443484534846348473484834849348503485134852348533485434855348563485734858348593486034861348623486334864348653486634867348683486934870348713487234873348743487534876348773487834879348803488134882348833488434885348863488734888348893489034891348923489334894348953489634897348983489934900349013490234903349043490534906349073490834909349103491134912349133491434915349163491734918349193492034921349223492334924349253492634927349283492934930349313493234933349343493534936349373493834939349403494134942349433494434945349463494734948349493495034951349523495334954349553495634957349583495934960349613496234963349643496534966349673496834969349703497134972349733497434975349763497734978349793498034981349823498334984349853498634987349883498934990349913499234993349943499534996349973499834999350003500135002350033500435005350063500735008350093501035011350123501335014350153501635017350183501935020350213502235023350243502535026350273502835029350303503135032350333503435035350363503735038350393504035041350423504335044350453504635047350483504935050350513505235053350543505535056350573505835059350603506135062350633506435065350663506735068350693507035071350723507335074350753507635077350783507935080350813508235083350843508535086350873508835089350903509135092350933509435095350963509735098350993510035101351023510335104351053510635107351083510935110351113511235113351143511535116351173511835119351203512135122351233512435125351263512735128351293513035131351323513335134351353513635137351383513935140351413514235143351443514535146351473514835149351503515135152351533515435155351563515735158351593516035161351623516335164351653516635167351683516935170351713517235173351743517535176351773517835179351803518135182351833518435185351863518735188351893519035191351923519335194351953519635197351983519935200352013520235203352043520535206352073520835209352103521135212352133521435215352163521735218352193522035221352223522335224352253522635227352283522935230352313523235233352343523535236352373523835239352403524135242352433524435245352463524735248352493525035251352523525335254352553525635257352583525935260352613526235263352643526535266352673526835269352703527135272352733527435275352763527735278352793528035281352823528335284352853528635287352883528935290352913529235293352943529535296352973529835299353003530135302353033530435305353063530735308353093531035311353123531335314353153531635317353183531935320353213532235323353243532535326353273532835329353303533135332353333533435335353363533735338353393534035341353423534335344353453534635347353483534935350353513535235353353543535535356353573535835359353603536135362353633536435365353663536735368353693537035371353723537335374353753537635377353783537935380353813538235383353843538535386353873538835389353903539135392353933539435395353963539735398353993540035401354023540335404354053540635407354083540935410354113541235413354143541535416354173541835419354203542135422354233542435425354263542735428354293543035431354323543335434354353543635437354383543935440354413544235443354443544535446354473544835449354503545135452354533545435455354563545735458354593546035461354623546335464354653546635467354683546935470354713547235473354743547535476354773547835479354803548135482354833548435485354863548735488354893549035491354923549335494354953549635497354983549935500355013550235503355043550535506355073550835509355103551135512355133551435515355163551735518355193552035521355223552335524355253552635527355283552935530355313553235533355343553535536355373553835539355403554135542355433554435545355463554735548355493555035551355523555335554355553555635557355583555935560355613556235563355643556535566355673556835569355703557135572355733557435575355763557735578355793558035581355823558335584355853558635587355883558935590355913559235593355943559535596355973559835599356003560135602356033560435605356063560735608356093561035611356123561335614356153561635617356183561935620356213562235623356243562535626356273562835629356303563135632356333563435635356363563735638356393564035641356423564335644356453564635647356483564935650356513565235653356543565535656356573565835659356603566135662356633566435665356663566735668356693567035671356723567335674356753567635677356783567935680356813568235683356843568535686356873568835689356903569135692356933569435695356963569735698356993570035701357023570335704357053570635707357083570935710357113571235713357143571535716357173571835719357203572135722357233572435725357263572735728357293573035731357323573335734357353573635737357383573935740357413574235743357443574535746357473574835749357503575135752357533575435755357563575735758357593576035761357623576335764357653576635767357683576935770357713577235773357743577535776357773577835779357803578135782357833578435785357863578735788357893579035791357923579335794357953579635797357983579935800358013580235803358043580535806358073580835809358103581135812358133581435815358163581735818358193582035821358223582335824358253582635827358283582935830358313583235833358343583535836358373583835839358403584135842358433584435845358463584735848358493585035851358523585335854358553585635857358583585935860358613586235863358643586535866358673586835869358703587135872358733587435875358763587735878358793588035881358823588335884358853588635887358883588935890358913589235893358943589535896358973589835899359003590135902359033590435905359063590735908359093591035911359123591335914359153591635917359183591935920359213592235923359243592535926359273592835929359303593135932359333593435935359363593735938359393594035941359423594335944359453594635947359483594935950359513595235953359543595535956359573595835959359603596135962359633596435965359663596735968359693597035971359723597335974359753597635977359783597935980359813598235983359843598535986359873598835989359903599135992359933599435995359963599735998359993600036001360023600336004360053600636007360083600936010360113601236013360143601536016360173601836019360203602136022360233602436025360263602736028360293603036031360323603336034360353603636037360383603936040360413604236043360443604536046360473604836049360503605136052360533605436055360563605736058360593606036061360623606336064360653606636067360683606936070360713607236073360743607536076360773607836079360803608136082360833608436085360863608736088360893609036091360923609336094360953609636097360983609936100361013610236103361043610536106361073610836109361103611136112361133611436115361163611736118361193612036121361223612336124361253612636127361283612936130361313613236133361343613536136361373613836139361403614136142361433614436145361463614736148361493615036151361523615336154361553615636157361583615936160361613616236163361643616536166361673616836169361703617136172361733617436175361763617736178361793618036181361823618336184361853618636187361883618936190361913619236193361943619536196361973619836199362003620136202362033620436205362063620736208362093621036211362123621336214362153621636217362183621936220362213622236223362243622536226362273622836229362303623136232362333623436235362363623736238362393624036241362423624336244362453624636247362483624936250362513625236253362543625536256362573625836259362603626136262362633626436265362663626736268362693627036271362723627336274362753627636277362783627936280362813628236283362843628536286 |
- diff -Nur gcc-4.2.4.orig/ccs_version.h gcc-4.2.4/ccs_version.h
- --- gcc-4.2.4.orig/ccs_version.h 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/ccs_version.h 2015-07-03 18:46:05.717283542 -0500
- @@ -0,0 +1,8 @@
- +/* This file has been generated by CCS - do not edit. */
- +
- +#define CCS_FULL_VSTR "1.4.0.3"
- +
- +#define CCS_MAJOR_VN 1
- +#define CCS_MINOR_VN 4
- +#define CCS_RELEASE_VN 0
- +#define CCS_BUILD_VN 3
- diff -Nur gcc-4.2.4.orig/config.guess gcc-4.2.4/config.guess
- --- gcc-4.2.4.orig/config.guess 2006-10-15 22:27:17.000000000 -0500
- +++ gcc-4.2.4/config.guess 2015-07-03 19:15:14.097267674 -0500
- @@ -1,14 +1,12 @@
- #! /bin/sh
- # Attempt to guess a canonical system name.
- -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- -# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
- -# Inc.
- +# Copyright 1992-2014 Free Software Foundation, Inc.
-
- -timestamp='2006-07-02'
- +timestamp='2014-03-23'
-
- # This file 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
- +# the Free Software Foundation; either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful, but
- @@ -17,26 +15,22 @@
- # 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., 51 Franklin Street - Fifth Floor, Boston, MA
- -# 02110-1301, USA.
- +# along with this program; if not, see <http://www.gnu.org/licenses/>.
- #
- # As a special exception to the GNU General Public License, if you
- # distribute this file as part of a program that contains a
- # configuration script generated by Autoconf, you may include it under
- -# the same distribution terms that you use for the rest of that program.
- -
- -
- -# Originally written by Per Bothner <per@bothner.com>.
- -# Please send patches to <config-patches@gnu.org>. Submit a context
- -# diff and a properly formatted ChangeLog entry.
- +# the same distribution terms that you use for the rest of that
- +# program. This Exception is an additional permission under section 7
- +# of the GNU General Public License, version 3 ("GPLv3").
- #
- -# This script attempts to guess a canonical system name similar to
- -# config.sub. If it succeeds, it prints the system name on stdout, and
- -# exits with 0. Otherwise, it exits with 1.
- +# Originally written by Per Bothner.
- #
- -# The plan is that this can be called by configure scripts if you
- -# don't specify an explicit build system type.
- +# You can get the latest version of this script from:
- +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
- +#
- +# Please send patches with a ChangeLog entry to config-patches@gnu.org.
- +
-
- me=`echo "$0" | sed -e 's,.*/,,'`
-
- @@ -56,8 +50,7 @@
- GNU config.guess ($timestamp)
-
- Originally written by Per Bothner.
- -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
- -Free Software Foundation, Inc.
- +Copyright 1992-2014 Free Software Foundation, Inc.
-
- This is free software; see the source for copying conditions. There is NO
- warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
- @@ -139,12 +132,33 @@
- UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
- UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
- +case "${UNAME_SYSTEM}" in
- +Linux|GNU|GNU/*)
- + # If the system lacks a compiler, then just pick glibc.
- + # We could probably try harder.
- + LIBC=gnu
- +
- + eval $set_cc_for_build
- + cat <<-EOF > $dummy.c
- + #include <features.h>
- + #if defined(__UCLIBC__)
- + LIBC=uclibc
- + #elif defined(__dietlibc__)
- + LIBC=dietlibc
- + #else
- + LIBC=gnu
- + #endif
- + EOF
- + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
- + ;;
- +esac
- +
- # Note: order is significant - the case branches are not exclusive.
-
- case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- *:NetBSD:*:*)
- # NetBSD (nbsd) targets should (where applicable) match one or
- - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
- + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
- # switched to ELF, *-*-netbsd* would select the old
- # object file format. This provides both forward
- @@ -161,6 +175,7 @@
- arm*) machine=arm-unknown ;;
- sh3el) machine=shl-unknown ;;
- sh3eb) machine=sh-unknown ;;
- + sh5el) machine=sh5le-unknown ;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
- esac
- # The Operating System including object format, if it has switched
- @@ -169,7 +184,7 @@
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- - | grep __ELF__ >/dev/null
- + | grep -q __ELF__
- then
- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
- # Return netbsd for either. FIX?
- @@ -179,7 +194,7 @@
- fi
- ;;
- *)
- - os=netbsd
- + os=netbsd
- ;;
- esac
- # The OS release
- @@ -200,6 +215,10 @@
- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
- exit ;;
- + *:Bitrig:*:*)
- + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
- + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
- + exit ;;
- *:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
- @@ -222,7 +241,7 @@
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- ;;
- *5.*)
- - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
- + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
- ;;
- esac
- # According to Compaq, /usr/sbin/psrinfo has been available on
- @@ -268,7 +287,10 @@
- # A Xn.n version is an unreleased experimental baselevel.
- # 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- - exit ;;
- + # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
- + exitcode=$?
- + trap '' 0
- + exit $exitcode ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- @@ -294,12 +316,12 @@
- echo s390-ibm-zvmoe
- exit ;;
- *:OS400:*:*)
- - echo powerpc-ibm-os400
- + echo powerpc-ibm-os400
- exit ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit ;;
- - arm:riscos:*:*|arm:RISCOS:*:*)
- + arm*:riscos:*:*|arm*:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- @@ -323,14 +345,33 @@
- case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
- + s390x:SunOS:*:*)
- + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- + exit ;;
- sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- - i86pc:SunOS:5.*:*)
- - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- + echo i386-pc-auroraux${UNAME_RELEASE}
- + exit ;;
- + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- + eval $set_cc_for_build
- + SUN_ARCH="i386"
- + # If there is a compiler, see if it is configured for 64-bit objects.
- + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
- + # This test works for both compilers.
- + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- + grep IS_64BIT_ARCH >/dev/null
- + then
- + SUN_ARCH="x86_64"
- + fi
- + fi
- + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- @@ -374,23 +415,23 @@
- # MiNT. But MiNT is downward compatible to TOS, so this should
- # be no problem.
- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- - echo m68k-atari-mint${UNAME_RELEASE}
- + echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- - exit ;;
- + exit ;;
- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- - echo m68k-atari-mint${UNAME_RELEASE}
- + echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- - echo m68k-milan-mint${UNAME_RELEASE}
- - exit ;;
- + echo m68k-milan-mint${UNAME_RELEASE}
- + exit ;;
- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- - echo m68k-hades-mint${UNAME_RELEASE}
- - exit ;;
- + echo m68k-hades-mint${UNAME_RELEASE}
- + exit ;;
- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- - echo m68k-unknown-mint${UNAME_RELEASE}
- - exit ;;
- + echo m68k-unknown-mint${UNAME_RELEASE}
- + exit ;;
- m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
- exit ;;
- @@ -460,8 +501,8 @@
- echo m88k-motorola-sysv3
- exit ;;
- AViiON:dgux:*:*)
- - # DG/UX returns AViiON for all architectures
- - UNAME_PROCESSOR=`/usr/bin/uname -p`
- + # DG/UX returns AViiON for all architectures
- + UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
- then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- @@ -474,7 +515,7 @@
- else
- echo i586-dg-dgux${UNAME_RELEASE}
- fi
- - exit ;;
- + exit ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
- @@ -531,7 +572,7 @@
- echo rs6000-ibm-aix3.2
- fi
- exit ;;
- - *:AIX:*:[45])
- + *:AIX:*:[4567])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- @@ -574,52 +615,52 @@
- 9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- - case "${sc_cpu_version}" in
- - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- - 532) # CPU_PA_RISC2_0
- - case "${sc_kernel_bits}" in
- - 32) HP_ARCH="hppa2.0n" ;;
- - 64) HP_ARCH="hppa2.0w" ;;
- + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- + case "${sc_cpu_version}" in
- + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- + 532) # CPU_PA_RISC2_0
- + case "${sc_kernel_bits}" in
- + 32) HP_ARCH="hppa2.0n" ;;
- + 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- - esac ;;
- - esac
- + esac ;;
- + esac
- fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- - sed 's/^ //' << EOF >$dummy.c
- + sed 's/^ //' << EOF >$dummy.c
- +
- + #define _HPUX_SOURCE
- + #include <stdlib.h>
- + #include <unistd.h>
- +
- + int main ()
- + {
- + #if defined(_SC_KERNEL_BITS)
- + long bits = sysconf(_SC_KERNEL_BITS);
- + #endif
- + long cpu = sysconf (_SC_CPU_VERSION);
-
- - #define _HPUX_SOURCE
- - #include <stdlib.h>
- - #include <unistd.h>
- -
- - int main ()
- - {
- - #if defined(_SC_KERNEL_BITS)
- - long bits = sysconf(_SC_KERNEL_BITS);
- - #endif
- - long cpu = sysconf (_SC_CPU_VERSION);
- -
- - switch (cpu)
- - {
- - case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- - case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- - case CPU_PA_RISC2_0:
- - #if defined(_SC_KERNEL_BITS)
- - switch (bits)
- - {
- - case 64: puts ("hppa2.0w"); break;
- - case 32: puts ("hppa2.0n"); break;
- - default: puts ("hppa2.0"); break;
- - } break;
- - #else /* !defined(_SC_KERNEL_BITS) */
- - puts ("hppa2.0"); break;
- - #endif
- - default: puts ("hppa1.0"); break;
- - }
- - exit (0);
- - }
- + switch (cpu)
- + {
- + case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- + case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- + case CPU_PA_RISC2_0:
- + #if defined(_SC_KERNEL_BITS)
- + switch (bits)
- + {
- + case 64: puts ("hppa2.0w"); break;
- + case 32: puts ("hppa2.0n"); break;
- + default: puts ("hppa2.0"); break;
- + } break;
- + #else /* !defined(_SC_KERNEL_BITS) */
- + puts ("hppa2.0"); break;
- + #endif
- + default: puts ("hppa1.0"); break;
- + }
- + exit (0);
- + }
- EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
- test -z "$HP_ARCH" && HP_ARCH=hppa
- @@ -639,7 +680,7 @@
- # => hppa64-hp-hpux11.23
-
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- - grep __LP64__ >/dev/null
- + grep -q __LP64__
- then
- HP_ARCH="hppa2.0w"
- else
- @@ -710,22 +751,22 @@
- exit ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- - exit ;;
- + exit ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- - exit ;;
- + exit ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- - exit ;;
- + exit ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- - exit ;;
- + exit ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- - exit ;;
- + exit ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- @@ -749,14 +790,14 @@
- exit ;;
- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- - exit ;;
- + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- + exit ;;
- 5000:UNIX_System_V:4.*:*)
- - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- @@ -768,37 +809,51 @@
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:FreeBSD:*:*)
- - case ${UNAME_MACHINE} in
- - pc98)
- - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- + UNAME_PROCESSOR=`/usr/bin/uname -p`
- + case ${UNAME_PROCESSOR} in
- amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- esac
- exit ;;
- i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit ;;
- - i*:MINGW*:*)
- + *:MINGW64*:*)
- + echo ${UNAME_MACHINE}-pc-mingw64
- + exit ;;
- + *:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit ;;
- + *:MSYS*:*)
- + echo ${UNAME_MACHINE}-pc-msys
- + exit ;;
- i*:windows32*:*)
- - # uname -m includes "-pc" on this system.
- - echo ${UNAME_MACHINE}-mingw32
- + # uname -m includes "-pc" on this system.
- + echo ${UNAME_MACHINE}-mingw32
- exit ;;
- i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- exit ;;
- - x86:Interix*:[3456]*)
- - echo i586-pc-interix${UNAME_RELEASE}
- - exit ;;
- - EM64T:Interix*:[3456]*)
- - echo x86_64-unknown-interix${UNAME_RELEASE}
- - exit ;;
- + *:Interix*:*)
- + case ${UNAME_MACHINE} in
- + x86)
- + echo i586-pc-interix${UNAME_RELEASE}
- + exit ;;
- + authenticamd | genuineintel | EM64T)
- + echo x86_64-unknown-interix${UNAME_RELEASE}
- + exit ;;
- + IA64)
- + echo ia64-unknown-interix${UNAME_RELEASE}
- + exit ;;
- + esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- + 8664:Windows_NT:*)
- + echo x86_64-pc-mks
- + exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- @@ -819,200 +874,157 @@
- exit ;;
- *:GNU:*:*)
- # the GNU system
- - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit ;;
- *:GNU/*:*:*)
- # other systems with GNU libc and userland
- - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
- + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
- exit ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit ;;
- + aarch64:Linux:*:*)
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- + exit ;;
- + aarch64_be:Linux:*:*)
- + UNAME_MACHINE=aarch64_be
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- + exit ;;
- + alpha:Linux:*:*)
- + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- + EV5) UNAME_MACHINE=alphaev5 ;;
- + EV56) UNAME_MACHINE=alphaev56 ;;
- + PCA56) UNAME_MACHINE=alphapca56 ;;
- + PCA57) UNAME_MACHINE=alphapca56 ;;
- + EV6) UNAME_MACHINE=alphaev6 ;;
- + EV67) UNAME_MACHINE=alphaev67 ;;
- + EV68*) UNAME_MACHINE=alphaev68 ;;
- + esac
- + objdump --private-headers /bin/sh | grep -q ld.so.1
- + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- + exit ;;
- + arc:Linux:*:* | arceb:Linux:*:*)
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- + exit ;;
- arm*:Linux:*:*)
- - echo ${UNAME_MACHINE}-unknown-linux-gnu
- + eval $set_cc_for_build
- + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
- + | grep -q __ARM_EABI__
- + then
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- + else
- + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
- + | grep -q __ARM_PCS_VFP
- + then
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
- + else
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
- + fi
- + fi
- exit ;;
- avr32*:Linux:*:*)
- - echo ${UNAME_MACHINE}-unknown-linux-gnu
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- cris:Linux:*:*)
- - echo cris-axis-linux-gnu
- + echo ${UNAME_MACHINE}-axis-linux-${LIBC}
- exit ;;
- crisv32:Linux:*:*)
- - echo crisv32-axis-linux-gnu
- + echo ${UNAME_MACHINE}-axis-linux-${LIBC}
- exit ;;
- frv:Linux:*:*)
- - echo frv-unknown-linux-gnu
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- + exit ;;
- + hexagon:Linux:*:*)
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- + exit ;;
- + i*86:Linux:*:*)
- + echo ${UNAME_MACHINE}-pc-linux-${LIBC}
- exit ;;
- ia64:Linux:*:*)
- - echo ${UNAME_MACHINE}-unknown-linux-gnu
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- m32r*:Linux:*:*)
- - echo ${UNAME_MACHINE}-unknown-linux-gnu
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- m68*:Linux:*:*)
- - echo ${UNAME_MACHINE}-unknown-linux-gnu
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- - mips:Linux:*:*)
- + mips:Linux:*:* | mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- - #undef mips
- - #undef mipsel
- + #undef ${UNAME_MACHINE}
- + #undef ${UNAME_MACHINE}el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- - CPU=mipsel
- + CPU=${UNAME_MACHINE}el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- - CPU=mips
- + CPU=${UNAME_MACHINE}
- #else
- CPU=
- #endif
- #endif
- EOF
- - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- - /^CPU/{
- - s: ::g
- - p
- - }'`"
- - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
- + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
- ;;
- - mips64:Linux:*:*)
- - eval $set_cc_for_build
- - sed 's/^ //' << EOF >$dummy.c
- - #undef CPU
- - #undef mips64
- - #undef mips64el
- - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- - CPU=mips64el
- - #else
- - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- - CPU=mips64
- - #else
- - CPU=
- - #endif
- - #endif
- -EOF
- - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- - /^CPU/{
- - s: ::g
- - p
- - }'`"
- - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- - ;;
- - or32:Linux:*:*)
- - echo or32-unknown-linux-gnu
- + openrisc*:Linux:*:*)
- + echo or1k-unknown-linux-${LIBC}
- exit ;;
- - ppc:Linux:*:*)
- - echo powerpc-unknown-linux-gnu
- + or32:Linux:*:* | or1k*:Linux:*:*)
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- - ppc64:Linux:*:*)
- - echo powerpc64-unknown-linux-gnu
- + padre:Linux:*:*)
- + echo sparc-unknown-linux-${LIBC}
- exit ;;
- - alpha:Linux:*:*)
- - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- - EV5) UNAME_MACHINE=alphaev5 ;;
- - EV56) UNAME_MACHINE=alphaev56 ;;
- - PCA56) UNAME_MACHINE=alphapca56 ;;
- - PCA57) UNAME_MACHINE=alphapca56 ;;
- - EV6) UNAME_MACHINE=alphaev6 ;;
- - EV67) UNAME_MACHINE=alphaev67 ;;
- - EV68*) UNAME_MACHINE=alphaev68 ;;
- - esac
- - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
- - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- + parisc64:Linux:*:* | hppa64:Linux:*:*)
- + echo hppa64-unknown-linux-${LIBC}
- exit ;;
- parisc:Linux:*:* | hppa:Linux:*:*)
- # Look for CPU level
- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- - PA7*) echo hppa1.1-unknown-linux-gnu ;;
- - PA8*) echo hppa2.0-unknown-linux-gnu ;;
- - *) echo hppa-unknown-linux-gnu ;;
- + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
- + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
- + *) echo hppa-unknown-linux-${LIBC} ;;
- esac
- exit ;;
- - parisc64:Linux:*:* | hppa64:Linux:*:*)
- - echo hppa64-unknown-linux-gnu
- + ppc64:Linux:*:*)
- + echo powerpc64-unknown-linux-${LIBC}
- + exit ;;
- + ppc:Linux:*:*)
- + echo powerpc-unknown-linux-${LIBC}
- + exit ;;
- + ppc64le:Linux:*:*)
- + echo powerpc64le-unknown-linux-${LIBC}
- + exit ;;
- + ppcle:Linux:*:*)
- + echo powerpcle-unknown-linux-${LIBC}
- exit ;;
- s390:Linux:*:* | s390x:Linux:*:*)
- - echo ${UNAME_MACHINE}-ibm-linux
- + echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
- exit ;;
- sh64*:Linux:*:*)
- - echo ${UNAME_MACHINE}-unknown-linux-gnu
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- sh*:Linux:*:*)
- - echo ${UNAME_MACHINE}-unknown-linux-gnu
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- sparc:Linux:*:* | sparc64:Linux:*:*)
- - echo ${UNAME_MACHINE}-unknown-linux-gnu
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- + exit ;;
- + tile*:Linux:*:*)
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- vax:Linux:*:*)
- - echo ${UNAME_MACHINE}-dec-linux-gnu
- + echo ${UNAME_MACHINE}-dec-linux-${LIBC}
- exit ;;
- x86_64:Linux:*:*)
- - echo x86_64-unknown-linux-gnu
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- + exit ;;
- + xtensa*:Linux:*:*)
- + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- - i*86:Linux:*:*)
- - # The BFD linker knows what the default object file format is, so
- - # first see if it will tell us. cd to the root directory to prevent
- - # problems with other programs or directories called `ld' in the path.
- - # Set LC_ALL=C to ensure ld outputs messages in English.
- - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
- - | sed -ne '/supported targets:/!d
- - s/[ ][ ]*/ /g
- - s/.*supported targets: *//
- - s/ .*//
- - p'`
- - case "$ld_supported_targets" in
- - elf32-i386)
- - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
- - ;;
- - a.out-i386-linux)
- - echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- - exit ;;
- - coff-i386)
- - echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- - exit ;;
- - "")
- - # Either a pre-BFD a.out linker (linux-gnuoldld) or
- - # one that does not give us useful --help.
- - echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- - exit ;;
- - esac
- - # Determine whether the default compiler is a.out or elf
- - eval $set_cc_for_build
- - sed 's/^ //' << EOF >$dummy.c
- - #include <features.h>
- - #ifdef __ELF__
- - # ifdef __GLIBC__
- - # if __GLIBC__ >= 2
- - LIBC=gnu
- - # else
- - LIBC=gnulibc1
- - # endif
- - # else
- - LIBC=gnulibc1
- - # endif
- - #else
- - #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
- - LIBC=gnu
- - #else
- - LIBC=gnuaout
- - #endif
- - #endif
- - #ifdef __dietlibc__
- - LIBC=dietlibc
- - #endif
- -EOF
- - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- - /^LIBC/{
- - s: ::g
- - p
- - }'`"
- - test x"${LIBC}" != x && {
- - echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- - exit
- - }
- - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
- - ;;
- i*86:DYNIX/ptx:4*:*)
- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
- # earlier versions are messed up and put the nodename in both
- @@ -1020,11 +1032,11 @@
- echo i386-sequent-sysv4
- exit ;;
- i*86:UNIX_SV:4.2MP:2.*)
- - # Unixware is an offshoot of SVR4, but it has its own version
- - # number series starting with 2...
- - # I am not positive that other SVR4 systems won't match this,
- + # Unixware is an offshoot of SVR4, but it has its own version
- + # number series starting with 2...
- + # I am not positive that other SVR4 systems won't match this,
- # I just have to hope. -- rms.
- - # Use sysv4.2uw... so that sysv4* matches it.
- + # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit ;;
- i*86:OS/2:*:*)
- @@ -1041,7 +1053,7 @@
- i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
- exit ;;
- - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
- + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- i*86:*DOS:*:*)
- @@ -1056,7 +1068,7 @@
- fi
- exit ;;
- i*86:*:5:[678]*)
- - # UnixWare 7.x, OpenUNIX and OpenServer 6.
- + # UnixWare 7.x, OpenUNIX and OpenServer 6.
- case `/bin/uname -X | grep "^Machine"` in
- *486*) UNAME_MACHINE=i486 ;;
- *Pentium) UNAME_MACHINE=i586 ;;
- @@ -1084,10 +1096,13 @@
- exit ;;
- pc:*:*:*)
- # Left here for compatibility:
- - # uname -m prints for DJGPP always 'pc', but it prints nothing about
- - # the processor, so we play safe by assuming i386.
- - echo i386-pc-msdosdjgpp
- - exit ;;
- + # uname -m prints for DJGPP always 'pc', but it prints nothing about
- + # the processor, so we play safe by assuming i586.
- + # Note: whatever this is, it MUST be the same as what config.sub
- + # prints for the "djgpp" host, or else GDB configury will decide that
- + # this is a cross-build.
- + echo i586-pc-msdosdjgpp
- + exit ;;
- Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
- @@ -1122,8 +1137,18 @@
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- - && { echo i486-ncr-sysv4; exit; } ;;
- + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- + && { echo i486-ncr-sysv4; exit; } ;;
- + NCR*:*:4.2:* | MPRAS*:*:4.2:*)
- + OS_REL='.3'
- + test -r /etc/.relid \
- + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- + && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- + && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
- + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
- + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- @@ -1136,7 +1161,7 @@
- rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
- + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- SM[BE]S:UNIX_SV:*:*)
- @@ -1156,10 +1181,10 @@
- echo ns32k-sni-sysv
- fi
- exit ;;
- - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- - # says <Richard.M.Bartel@ccMail.Census.GOV>
- - echo i586-unisys-sysv4
- - exit ;;
- + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- + # says <Richard.M.Bartel@ccMail.Census.GOV>
- + echo i586-unisys-sysv4
- + exit ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <hewes@openmarket.com>.
- # How about differentiating between stratus architectures? -djm
- @@ -1185,11 +1210,11 @@
- exit ;;
- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- - echo mips-nec-sysv${UNAME_RELEASE}
- + echo mips-nec-sysv${UNAME_RELEASE}
- else
- - echo mips-unknown-sysv${UNAME_RELEASE}
- + echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- - exit ;;
- + exit ;;
- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
- @@ -1199,6 +1224,12 @@
- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
- + BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
- + echo i586-pc-haiku
- + exit ;;
- + x86_64:Haiku:*:*)
- + echo x86_64-unknown-haiku
- + exit ;;
- SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit ;;
- @@ -1208,6 +1239,15 @@
- SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
- exit ;;
- + SX-7:SUPER-UX:*:*)
- + echo sx7-nec-superux${UNAME_RELEASE}
- + exit ;;
- + SX-8:SUPER-UX:*:*)
- + echo sx8-nec-superux${UNAME_RELEASE}
- + exit ;;
- + SX-8R:SUPER-UX:*:*)
- + echo sx8r-nec-superux${UNAME_RELEASE}
- + exit ;;
- Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- @@ -1216,9 +1256,31 @@
- exit ;;
- *:Darwin:*:*)
- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- - case $UNAME_PROCESSOR in
- - unknown) UNAME_PROCESSOR=powerpc ;;
- - esac
- + eval $set_cc_for_build
- + if test "$UNAME_PROCESSOR" = unknown ; then
- + UNAME_PROCESSOR=powerpc
- + fi
- + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
- + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- + grep IS_64BIT_ARCH >/dev/null
- + then
- + case $UNAME_PROCESSOR in
- + i386) UNAME_PROCESSOR=x86_64 ;;
- + powerpc) UNAME_PROCESSOR=powerpc64 ;;
- + esac
- + fi
- + fi
- + elif test "$UNAME_PROCESSOR" = i386 ; then
- + # Avoid executing cc on OS X 10.9, as it ships with a stub
- + # that puts up a graphical alert prompting to install
- + # developer tools. Any system running Mac OS X 10.7 or
- + # later (Darwin 11 and later) is required to have a 64-bit
- + # processor. This is not true of the ARM version of Darwin
- + # that Apple uses in portable devices.
- + UNAME_PROCESSOR=x86_64
- + fi
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
- exit ;;
- *:procnto*:*:* | *:QNX:[0123456789]*:*)
- @@ -1232,7 +1294,10 @@
- *:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
- - NSE-?:NONSTOP_KERNEL:*:*)
- + NEO-?:NONSTOP_KERNEL:*:*)
- + echo neo-tandem-nsk${UNAME_RELEASE}
- + exit ;;
- + NSE-*:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- @@ -1277,13 +1342,13 @@
- echo pdp10-unknown-its
- exit ;;
- SEI:*:*:SEIUX)
- - echo mips-sei-seiux${UNAME_RELEASE}
- + echo mips-sei-seiux${UNAME_RELEASE}
- exit ;;
- *:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit ;;
- *:*VMS:*:*)
- - UNAME_MACHINE=`(uname -p) 2>/dev/null`
- + UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- @@ -1298,158 +1363,13 @@
- i*86:rdos:*:*)
- echo ${UNAME_MACHINE}-pc-rdos
- exit ;;
- -esac
- -
- -#echo '(No uname command or uname output not recognized.)' 1>&2
- -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
- -
- -eval $set_cc_for_build
- -cat >$dummy.c <<EOF
- -#ifdef _SEQUENT_
- -# include <sys/types.h>
- -# include <sys/utsname.h>
- -#endif
- -main ()
- -{
- -#if defined (sony)
- -#if defined (MIPSEB)
- - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- - I don't know.... */
- - printf ("mips-sony-bsd\n"); exit (0);
- -#else
- -#include <sys/param.h>
- - printf ("m68k-sony-newsos%s\n",
- -#ifdef NEWSOS4
- - "4"
- -#else
- - ""
- -#endif
- - ); exit (0);
- -#endif
- -#endif
- -
- -#if defined (__arm) && defined (__acorn) && defined (__unix)
- - printf ("arm-acorn-riscix\n"); exit (0);
- -#endif
- -
- -#if defined (hp300) && !defined (hpux)
- - printf ("m68k-hp-bsd\n"); exit (0);
- -#endif
- -
- -#if defined (NeXT)
- -#if !defined (__ARCHITECTURE__)
- -#define __ARCHITECTURE__ "m68k"
- -#endif
- - int version;
- - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- - if (version < 4)
- - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- - else
- - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- - exit (0);
- -#endif
- -
- -#if defined (MULTIMAX) || defined (n16)
- -#if defined (UMAXV)
- - printf ("ns32k-encore-sysv\n"); exit (0);
- -#else
- -#if defined (CMU)
- - printf ("ns32k-encore-mach\n"); exit (0);
- -#else
- - printf ("ns32k-encore-bsd\n"); exit (0);
- -#endif
- -#endif
- -#endif
- -
- -#if defined (__386BSD__)
- - printf ("i386-pc-bsd\n"); exit (0);
- -#endif
- -
- -#if defined (sequent)
- -#if defined (i386)
- - printf ("i386-sequent-dynix\n"); exit (0);
- -#endif
- -#if defined (ns32000)
- - printf ("ns32k-sequent-dynix\n"); exit (0);
- -#endif
- -#endif
- -
- -#if defined (_SEQUENT_)
- - struct utsname un;
- -
- - uname(&un);
- -
- - if (strncmp(un.version, "V2", 2) == 0) {
- - printf ("i386-sequent-ptx2\n"); exit (0);
- - }
- - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- - printf ("i386-sequent-ptx1\n"); exit (0);
- - }
- - printf ("i386-sequent-ptx\n"); exit (0);
- -
- -#endif
- -
- -#if defined (vax)
- -# if !defined (ultrix)
- -# include <sys/param.h>
- -# if defined (BSD)
- -# if BSD == 43
- - printf ("vax-dec-bsd4.3\n"); exit (0);
- -# else
- -# if BSD == 199006
- - printf ("vax-dec-bsd4.3reno\n"); exit (0);
- -# else
- - printf ("vax-dec-bsd\n"); exit (0);
- -# endif
- -# endif
- -# else
- - printf ("vax-dec-bsd\n"); exit (0);
- -# endif
- -# else
- - printf ("vax-dec-ultrix\n"); exit (0);
- -# endif
- -#endif
- -
- -#if defined (alliant) && defined (i860)
- - printf ("i860-alliant-bsd\n"); exit (0);
- -#endif
- -
- - exit (1);
- -}
- -EOF
- -
- -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
- - { echo "$SYSTEM_NAME"; exit; }
- -
- -# Apollos put the system type in the environment.
- -
- -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
- -
- -# Convex versions that predate uname can use getsysinfo(1)
- -
- -if [ -x /usr/convex/getsysinfo ]
- -then
- - case `getsysinfo -f cpu_type` in
- - c1*)
- - echo c1-convex-bsd
- + i*86:AROS:*:*)
- + echo ${UNAME_MACHINE}-pc-aros
- exit ;;
- - c2*)
- - if getsysinfo -f scalar_acc
- - then echo c32-convex-bsd
- - else echo c2-convex-bsd
- - fi
- - exit ;;
- - c34*)
- - echo c34-convex-bsd
- + x86_64:VMkernel:*:*)
- + echo ${UNAME_MACHINE}-unknown-esx
- exit ;;
- - c38*)
- - echo c38-convex-bsd
- - exit ;;
- - c4*)
- - echo c4-convex-bsd
- - exit ;;
- - esac
- -fi
- +esac
-
- cat >&2 <<EOF
- $0: unable to guess system type
- @@ -1458,9 +1378,9 @@
- the operating system you are using. It is advised that you
- download the most up to date version of the config scripts from
-
- - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
- + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
- and
- - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
- + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
- If the version you run ($0) is already up to date, please
- send the following data and any information you think might be
- diff -Nur gcc-4.2.4.orig/config-ml.in gcc-4.2.4/config-ml.in
- --- gcc-4.2.4.orig/config-ml.in 2006-06-13 15:48:23.000000000 -0500
- +++ gcc-4.2.4/config-ml.in 2015-07-03 18:46:05.717283542 -0500
- @@ -1,8 +1,8 @@
- # Configure fragment invoked in the post-target section for subdirs
- # wanting multilib support.
- #
- -# Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
- -# Free Software Foundation, Inc.
- +# Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- +# 2005, 2006, 2007 Free Software Foundation, Inc.
- #
- # This file is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- @@ -108,6 +108,11 @@
- ml_verbose=--verbose
- for option in ${ac_configure_args}
- do
- + # strip single quotes surrounding individual options
- + case $option in
- + \'*\') eval option=$option ;;
- + esac
- +
- case $option in
- --*) ;;
- -*) option=-$option ;;
- @@ -535,7 +540,7 @@
- else \
- rootpre=`${PWD_COMMAND}`/; export rootpre; \
- srcrootpre=`cd $(srcdir); ${PWD_COMMAND}`/; export srcrootpre; \
- - lib=`echo $${rootpre} | sed -e 's,^.*/\([^/][^/]*\)/$$,\1,'`; \
- + lib=`echo "$${rootpre}" | sed -e 's,^.*/\([^/][^/]*\)/$$,\1,'`; \
- compiler="$(CC)"; \
- for i in `$${compiler} --print-multi-lib 2>/dev/null`; do \
- dir=`echo $$i | sed -e 's/;.*$$//'`; \
- @@ -581,8 +586,13 @@
- true; \
- else \
- lib=`${PWD_COMMAND} | sed -e 's,^.*/\([^/][^/]*\)$$,\1,'`; \
- - for dir in Makefile $(MULTIDIRS); do \
- - if [ -f ../$${dir}/$${lib}/Makefile ]; then \
- + for dir in : $(MULTIDIRS); do \
- + test $$dir != : || continue; \
- +EOF
- +cat >>Multi.tem <<EOF
- + if [ -f ../\$\${dir}/\$\${lib}/${Makefile} ]; then \\
- +EOF
- +cat >>Multi.tem <<\EOF
- if (cd ../$${dir}/$${lib}; $(MAKE) $(FLAGS_TO_PASS) $(DO)); \
- then true; \
- else exit 1; \
- @@ -600,7 +610,7 @@
- fi # ${ml_toplevel_p} = yes
-
- if [ "${ml_verbose}" = --verbose ]; then
- - echo "Adding multilib support to Makefile in ${ml_realsrcdir}"
- + echo "Adding multilib support to ${Makefile} in ${ml_realsrcdir}"
- if [ "${ml_toplevel_p}" = yes ]; then
- echo "multidirs=${multidirs}"
- fi
- @@ -691,7 +701,7 @@
- fi
-
- ml_origdir=`${PWDCMD-pwd}`
- - ml_libdir=`echo $ml_origdir | sed -e 's,^.*/,,'`
- + ml_libdir=`echo "$ml_origdir" | sed -e 's,^.*/,,'`
- # cd to top-level-build-dir/${with_target_subdir}
- cd ..
-
- @@ -727,7 +737,7 @@
-
- case ${srcdir} in
- ".")
- - echo Building symlink tree in `${PWDCMD-pwd}`/${ml_dir}/${ml_libdir}
- + echo "Building symlink tree in `${PWDCMD-pwd}`/${ml_dir}/${ml_libdir}"
- if [ "${with_target_subdir}" != "." ]; then
- ml_unsubdir="../"
- else
- @@ -735,7 +745,7 @@
- fi
- (cd ${ml_dir}/${ml_libdir};
- ../${dotdot}${ml_unsubdir}symlink-tree ../${dotdot}${ml_unsubdir}${ml_libdir} "")
- - if [ -f ${ml_dir}/${ml_libdir}/Makefile ]; then
- + if [ -f ${ml_dir}/${ml_libdir}/${Makefile} ]; then
- if [ x"${MAKE}" = x ]; then
- (cd ${ml_dir}/${ml_libdir}; make distclean)
- else
- @@ -792,7 +802,7 @@
- else
- # Create a regular expression that matches any string as long
- # as ML_POPDIR.
- - popdir_rx=`echo ${ML_POPDIR} | sed 's,.,.,g'`
- + popdir_rx=`echo "${ML_POPDIR}" | sed 's,.,.,g'`
- CC_=
- for arg in ${CC}; do
- case $arg in
- @@ -890,17 +900,17 @@
-
- if eval ${ml_config_env} ${ml_config_shell} ${ml_recprog} \
- --with-multisubdir=${ml_dir} --with-multisrctop=${multisrctop} \
- - ${ac_configure_args} ${ml_srcdiroption} ; then
- + ${ac_configure_args} ${ml_config_env} ${ml_srcdiroption} ; then
- true
- else
- exit 1
- fi
-
- - cd ${ML_POPDIR}
- + cd "${ML_POPDIR}"
-
- done
-
- - cd ${ml_origdir}
- + cd "${ml_origdir}"
- fi
-
- fi # ${ml_toplevel_p} = yes
- diff -Nur gcc-4.2.4.orig/config.sub gcc-4.2.4/config.sub
- --- gcc-4.2.4.orig/config.sub 2006-10-15 22:27:17.000000000 -0500
- +++ gcc-4.2.4/config.sub 2015-07-03 19:15:14.097267674 -0500
- @@ -1,44 +1,40 @@
- #! /bin/sh
- # Configuration validation subroutine script.
- -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- -# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
- -# Inc.
- -
- -timestamp='2006-09-20'
- -
- -# This file is (in principle) common to ALL GNU software.
- -# The presence of a machine in this file suggests that SOME GNU software
- -# can handle that machine. It does not imply ALL GNU software can.
- -#
- -# This file 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
- +# Copyright 1992-2014 Free Software Foundation, Inc.
- +
- +timestamp='2014-09-26'
- +
- +# This file 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 3 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.
- +# 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., 51 Franklin Street - Fifth Floor, Boston, MA
- -# 02110-1301, USA.
- +# along with this program; if not, see <http://www.gnu.org/licenses/>.
- #
- # As a special exception to the GNU General Public License, if you
- # distribute this file as part of a program that contains a
- # configuration script generated by Autoconf, you may include it under
- -# the same distribution terms that you use for the rest of that program.
- +# the same distribution terms that you use for the rest of that
- +# program. This Exception is an additional permission under section 7
- +# of the GNU General Public License, version 3 ("GPLv3").
-
-
- -# Please send patches to <config-patches@gnu.org>. Submit a context
- -# diff and a properly formatted ChangeLog entry.
- +# Please send patches with a ChangeLog entry to config-patches@gnu.org.
- #
- # Configuration subroutine to validate and canonicalize a configuration type.
- # Supply the specified configuration type as an argument.
- # If it is invalid, we print an error message on stderr and exit with code 1.
- # Otherwise, we print the canonical config type on stdout and succeed.
-
- +# You can get the latest version of this script from:
- +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
- +
- # This file is supposed to be the same for all GNU packages
- # and recognize all the CPU types, system types and aliases
- # that are meaningful with *any* GNU software.
- @@ -72,8 +68,7 @@
- version="\
- GNU config.sub ($timestamp)
-
- -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
- -Free Software Foundation, Inc.
- +Copyright 1992-2014 Free Software Foundation, Inc.
-
- This is free software; see the source for copying conditions. There is NO
- warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
- @@ -120,12 +115,18 @@
- # Here we must recognize all the valid KERNEL-OS combinations.
- maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
- case $maybe_os in
- - nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
- - uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
- + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
- + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
- + knetbsd*-gnu* | netbsd*-gnu* | \
- + kopensolaris*-gnu* | \
- storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- + android-linux)
- + os=-linux-android
- + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
- + ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- @@ -148,10 +149,13 @@
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- - -apple | -axis | -knuth | -cray)
- + -apple | -axis | -knuth | -cray | -microblaze*)
- os=
- basic_machine=$1
- ;;
- + -bluegene*)
- + os=-cnk
- + ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- @@ -166,10 +170,10 @@
- os=-chorusos
- basic_machine=$1
- ;;
- - -chorusrdb)
- - os=-chorusrdb
- + -chorusrdb)
- + os=-chorusrdb
- basic_machine=$1
- - ;;
- + ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- @@ -214,6 +218,12 @@
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- + -lynx*178)
- + os=-lynxos178
- + ;;
- + -lynx*5)
- + os=-lynxos5
- + ;;
- -lynx*)
- os=-lynxos
- ;;
- @@ -238,59 +248,89 @@
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- + | aarch64 | aarch64_be \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
- | am33_2.0 \
- - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
- + | arc | arceb \
- + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
- + | avr | avr32 \
- + | be32 | be64 \
- | bfin \
- - | c4x | clipper \
- + | c4x | c8051 | clipper \
- | d10v | d30v | dlx | dsp16xx \
- - | fr30 | frv \
- + | epiphany \
- + | fido | fr30 | frv \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- + | hexagon \
- | i370 | i860 | i960 | ia64 \
- | ip2k | iq2000 \
- + | k1om \
- + | le32 | le64 \
- + | lm32 \
- | m32c | m32r | m32rle | m68000 | m68k | m88k \
- - | maxq | mb | microblaze | mcore \
- + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- - | mips64vr | mips64vrel \
- + | mips64octeon | mips64octeonel \
- | mips64orion | mips64orionel \
- + | mips64r5900 | mips64r5900el \
- + | mips64vr | mips64vrel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- + | mipsisa32r6 | mipsisa32r6el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- + | mipsisa64r6 | mipsisa64r6el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- + | mipsr5900 | mipsr5900el \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- + | moxie \
- | mt \
- | msp430 \
- - | nios | nios2 \
- + | nds32 | nds32le | nds32be \
- + | nios | nios2 | nios2eb | nios2el \
- | ns16k | ns32k \
- - | or32 \
- + | open8 | or1k | or1knd | or32 \
- | pdp10 | pdp11 | pj | pjl \
- - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
- + | powerpc | powerpc64 | powerpc64le | powerpcle \
- | pyramid \
- + | riscv32 | riscv64 \
- + | rl78 | rx \
- | score \
- - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
- + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- - | spu | strongarm \
- - | tahoe | thumb | tic4x | tic80 | tron \
- - | v850 | v850e \
- + | spu \
- + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
- + | ubicom32 \
- + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
- | we32k \
- - | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
- - | z8k)
- + | x86 | xc16x | xstormy16 | xtensa \
- + | z8k | z80)
- basic_machine=$basic_machine-unknown
- ;;
- - m6811 | m68hc11 | m6812 | m68hc12)
- - # Motorola 68HC11/12.
- + c54x)
- + basic_machine=tic54x-unknown
- + ;;
- + c55x)
- + basic_machine=tic55x-unknown
- + ;;
- + c6x)
- + basic_machine=tic6x-unknown
- + ;;
- + leon|leon[3-9])
- + basic_machine=sparc-$basic_machine
- + ;;
- + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- @@ -300,6 +340,21 @@
- basic_machine=mt-unknown
- ;;
-
- + strongarm | thumb | xscale)
- + basic_machine=arm-unknown
- + ;;
- + xgate)
- + basic_machine=$basic_machine-unknown
- + os=-none
- + ;;
- + xscaleeb)
- + basic_machine=armeb-unknown
- + ;;
- +
- + xscaleel)
- + basic_machine=armel-unknown
- + ;;
- +
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- @@ -314,64 +369,86 @@
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- + | aarch64-* | aarch64_be-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
- + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* | avr32-* \
- + | be32-* | be64-* \
- | bfin-* | bs2000-* \
- - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
- - | clipper-* | craynv-* | cydra-* \
- + | c[123]* | c30-* | [cjt]90-* | c4x-* \
- + | c8051-* | clipper-* | craynv-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
- | elxsi-* \
- - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
- + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- + | hexagon-* \
- | i*86-* | i860-* | i960-* | ia64-* \
- | ip2k-* | iq2000-* \
- + | k1om-* \
- + | le32-* | le64-* \
- + | lm32-* \
- | m32c-* | m32r-* | m32rle-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- - | m88110-* | m88k-* | maxq-* | mcore-* \
- + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
- + | microblaze-* | microblazeel-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- - | mips64vr-* | mips64vrel-* \
- + | mips64octeon-* | mips64octeonel-* \
- | mips64orion-* | mips64orionel-* \
- + | mips64r5900-* | mips64r5900el-* \
- + | mips64vr-* | mips64vrel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mips64vr5900-* | mips64vr5900el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- + | mipsisa32r6-* | mipsisa32r6el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64r2-* | mipsisa64r2el-* \
- + | mipsisa64r6-* | mipsisa64r6el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- + | mipsr5900-* | mipsr5900el-* \
- | mipstx39-* | mipstx39el-* \
- | mmix-* \
- | mt-* \
- | msp430-* \
- - | nios-* | nios2-* \
- + | nds32-* | nds32le-* | nds32be-* \
- + | nios-* | nios2-* | nios2eb-* | nios2el-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
- + | open8-* \
- + | or1k*-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
- + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
- | pyramid-* \
- - | romp-* | rs6000-* \
- - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
- + | rl78-* | romp-* | rs6000-* | rx-* \
- + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
- | sparclite-* \
- - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
- - | tahoe-* | thumb-* \
- + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
- + | tahoe-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- + | tile*-* \
- | tron-* \
- - | v850-* | v850e-* | vax-* \
- + | ubicom32-* \
- + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
- + | vax-* \
- | we32k-* \
- - | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
- - | xstormy16-* | xtensa-* \
- + | x86-* | x86_64-* | xc16x-* | xps100-* \
- + | xstormy16-* | xtensa*-* \
- | ymp-* \
- - | z8k-*)
- + | z8k-* | z80-*)
- + ;;
- + # Recognize the basic CPU types without company name, with glob match.
- + xtensa*)
- + basic_machine=$basic_machine-unknown
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- @@ -389,7 +466,7 @@
- basic_machine=a29k-amd
- os=-udi
- ;;
- - abacus)
- + abacus)
- basic_machine=abacus-unknown
- ;;
- adobe68k)
- @@ -435,6 +512,10 @@
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- + aros)
- + basic_machine=i386-pc
- + os=-aros
- + ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- @@ -443,10 +524,35 @@
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- + blackfin)
- + basic_machine=bfin-unknown
- + os=-linux
- + ;;
- + blackfin-*)
- + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
- + os=-linux
- + ;;
- + bluegene*)
- + basic_machine=powerpc-ibm
- + os=-cnk
- + ;;
- + c54x-*)
- + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
- + ;;
- + c55x-*)
- + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
- + ;;
- + c6x-*)
- + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
- + ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- + cegcc)
- + basic_machine=arm-unknown
- + os=-cegcc
- + ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- @@ -475,8 +581,8 @@
- basic_machine=craynv-cray
- os=-unicosmp
- ;;
- - cr16c)
- - basic_machine=cr16c-unknown
- + cr16 | cr16-*)
- + basic_machine=cr16-unknown
- os=-elf
- ;;
- crds | unos)
- @@ -514,6 +620,10 @@
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- + dicos)
- + basic_machine=i686-pc
- + os=-dicos
- + ;;
- djgpp)
- basic_machine=i586-pc
- os=-msdosdjgpp
- @@ -629,7 +739,6 @@
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- ;;
- -# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- @@ -668,6 +777,17 @@
- basic_machine=m68k-isi
- os=-sysv
- ;;
- + leon-*|leon[3-9]-*)
- + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
- + ;;
- + m68knommu)
- + basic_machine=m68k-unknown
- + os=-linux
- + ;;
- + m68knommu-*)
- + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
- + os=-linux
- + ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- @@ -679,10 +799,21 @@
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- + microblaze*)
- + basic_machine=microblaze-xilinx
- + ;;
- + mingw64)
- + basic_machine=x86_64-pc
- + os=-mingw64
- + ;;
- mingw32)
- - basic_machine=i386-pc
- + basic_machine=i686-pc
- os=-mingw32
- ;;
- + mingw32ce)
- + basic_machine=arm-unknown
- + os=-mingw32ce
- + ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- @@ -704,6 +835,10 @@
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- + moxiebox)
- + basic_machine=moxie-unknown
- + os=-moxiebox
- + ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- @@ -711,10 +846,18 @@
- ms1-*)
- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
- ;;
- + msys)
- + basic_machine=i686-pc
- + os=-msys
- + ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- + nacl)
- + basic_machine=le32-unknown
- + os=-nacl
- + ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- @@ -779,6 +922,12 @@
- np1)
- basic_machine=np1-gould
- ;;
- + neo-tandem)
- + basic_machine=neo-tandem
- + ;;
- + nse-tandem)
- + basic_machine=nse-tandem
- + ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- @@ -809,6 +958,14 @@
- basic_machine=i860-intel
- os=-osf
- ;;
- + parisc)
- + basic_machine=hppa-unknown
- + os=-linux
- + ;;
- + parisc-*)
- + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
- + os=-linux
- + ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- @@ -853,9 +1010,10 @@
- ;;
- power) basic_machine=power-ibm
- ;;
- - ppc) basic_machine=powerpc-unknown
- + ppc | ppcbe) basic_machine=powerpc-unknown
- ;;
- - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- + ppc-* | ppcbe-*)
- + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- @@ -880,7 +1038,11 @@
- basic_machine=i586-unknown
- os=-pw32
- ;;
- - rdos)
- + rdos | rdos64)
- + basic_machine=x86_64-pc
- + os=-rdos
- + ;;
- + rdos32)
- basic_machine=i386-pc
- os=-rdos
- ;;
- @@ -925,6 +1087,9 @@
- basic_machine=sh-hitachi
- os=-hms
- ;;
- + sh5el)
- + basic_machine=sh5le-unknown
- + ;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- @@ -946,6 +1111,9 @@
- basic_machine=i860-stratus
- os=-sysv4
- ;;
- + strongarm-* | thumb-*)
- + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
- + ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- @@ -1002,17 +1170,9 @@
- basic_machine=t90-cray
- os=-unicos
- ;;
- - tic54x | c54x*)
- - basic_machine=tic54x-unknown
- - os=-coff
- - ;;
- - tic55x | c55x*)
- - basic_machine=tic55x-unknown
- - os=-coff
- - ;;
- - tic6x | c6x*)
- - basic_machine=tic6x-unknown
- - os=-coff
- + tile*)
- + basic_machine=$basic_machine-unknown
- + os=-linux-gnu
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- @@ -1081,6 +1241,9 @@
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- + xscale-* | xscalee[bl]-*)
- + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
- + ;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
- @@ -1089,6 +1252,10 @@
- basic_machine=z8k-unknown
- os=-sim
- ;;
- + z80-*-coff)
- + basic_machine=z80-unknown
- + os=-sim
- + ;;
- none)
- basic_machine=none-none
- os=-none
- @@ -1127,7 +1294,7 @@
- we32k)
- basic_machine=we32k-att
- ;;
- - sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
- + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
- basic_machine=sh-unknown
- ;;
- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
- @@ -1174,9 +1341,12 @@
- if [ x"$os" != x"" ]
- then
- case $os in
- - # First match some system type aliases
- - # that might get confused with valid system types.
- + # First match some system type aliases
- + # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- + -auroraux)
- + os=-auroraux
- + ;;
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- @@ -1197,29 +1367,31 @@
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
- - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
- + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
- + | -sym* | -kopensolaris* | -plan9* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- - | -aos* \
- + | -aos* | -aros* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- - | -openbsd* | -solidbsd* \
- + | -bitrig* | -openbsd* | -solidbsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- - | -chorusos* | -chorusrdb* \
- - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- - | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
- - | -uxpv* | -beos* | -mpeix* | -udk* \
- + | -chorusos* | -chorusrdb* | -cegcc* \
- + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
- + | -linux-newlib* | -linux-musl* | -linux-uclibc* \
- + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- - | -skyos* | -haiku* | -rdos* | -toppers*)
- + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- @@ -1258,7 +1430,7 @@
- -opened*)
- os=-openedition
- ;;
- - -os400*)
- + -os400*)
- os=-os400
- ;;
- -wince*)
- @@ -1307,7 +1479,7 @@
- -sinix*)
- os=-sysv4
- ;;
- - -tpf*)
- + -tpf*)
- os=-tpf
- ;;
- -triton*)
- @@ -1343,12 +1515,14 @@
- -aros*)
- os=-aros
- ;;
- - -kaos*)
- - os=-kaos
- - ;;
- -zvmoe)
- os=-zvmoe
- ;;
- + -dicos*)
- + os=-dicos
- + ;;
- + -nacl*)
- + ;;
- -none)
- ;;
- *)
- @@ -1371,10 +1545,10 @@
- # system, and we'll never get to this point.
-
- case $basic_machine in
- - score-*)
- + score-*)
- os=-elf
- ;;
- - spu-*)
- + spu-*)
- os=-elf
- ;;
- *-acorn)
- @@ -1386,8 +1560,23 @@
- arm*-semi)
- os=-aout
- ;;
- - c4x-* | tic4x-*)
- - os=-coff
- + c4x-* | tic4x-*)
- + os=-coff
- + ;;
- + c8051-*)
- + os=-elf
- + ;;
- + hexagon-*)
- + os=-elf
- + ;;
- + tic54x-*)
- + os=-coff
- + ;;
- + tic55x-*)
- + os=-coff
- + ;;
- + tic6x-*)
- + os=-coff
- ;;
- # This must come before the *-dec entry.
- pdp10-*)
- @@ -1407,13 +1596,13 @@
- ;;
- m68000-sun)
- os=-sunos3
- - # This also exists in the configure program, but was not the
- - # default.
- - # os=-sunos4
- ;;
- m68*-cisco)
- os=-aout
- ;;
- + mep-*)
- + os=-elf
- + ;;
- mips*-cisco)
- os=-elf
- ;;
- @@ -1438,7 +1627,7 @@
- *-ibm)
- os=-aix
- ;;
- - *-knuth)
- + *-knuth)
- os=-mmixware
- ;;
- *-wec)
- @@ -1543,7 +1732,7 @@
- -sunos*)
- vendor=sun
- ;;
- - -aix*)
- + -cnk*|-aix*)
- vendor=ibm
- ;;
- -beos*)
- diff -Nur gcc-4.2.4.orig/contrib/test_installed gcc-4.2.4/contrib/test_installed
- --- gcc-4.2.4.orig/contrib/test_installed 2003-07-11 01:05:01.000000000 -0500
- +++ gcc-4.2.4/contrib/test_installed 2015-07-03 18:46:05.717283542 -0500
- @@ -107,6 +107,8 @@
- set srcdir "${testsuite-${srcdir}/gcc/testsuite}"
- set CFLAGS ""
- set CXXFLAGS ""
- +set HOSTCC "cc"
- +set HOSTCFLAGS ""
- set GCC_UNDER_TEST "${GCC_UNDER_TEST-${prefix}${prefix+/bin/}gcc}"
- set GXX_UNDER_TEST "${GXX_UNDER_TEST-${prefix}${prefix+/bin/}g++}"
- set G77_UNDER_TEST "${G77_UNDER_TEST-${prefix}${prefix+/bin/}g77}"
- diff -Nur gcc-4.2.4.orig/fixincludes/mkfixinc.sh gcc-4.2.4/fixincludes/mkfixinc.sh
- --- gcc-4.2.4.orig/fixincludes/mkfixinc.sh 2004-11-23 16:45:53.000000000 -0600
- +++ gcc-4.2.4/fixincludes/mkfixinc.sh 2015-07-03 18:46:05.717283542 -0500
- @@ -23,6 +23,7 @@
- i?86-*-mingw32* | \
- i?86-*-uwin* | \
- i?86-*-interix* | \
- + metag*-linux-uclibc* | \
- powerpc-*-eabiaix* | \
- powerpc-*-eabisim* | \
- powerpc-*-eabi* | \
- diff -Nur gcc-4.2.4.orig/gcc/caller-save.c gcc-4.2.4/gcc/caller-save.c
- --- gcc-4.2.4.orig/gcc/caller-save.c 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/caller-save.c 2015-07-03 18:46:05.717283542 -0500
- @@ -36,6 +36,10 @@
- #include "tm_p.h"
- #include "addresses.h"
-
- +#ifndef CALLER_SAVE_INSN_CODE
- +#define CALLER_SAVE_INSN_CODE(CODE) (CODE)
- +#endif
- +
- #ifndef MAX_MOVE_MAX
- #define MAX_MOVE_MAX MOVE_MAX
- #endif
- @@ -776,7 +780,8 @@
-
- /* Emit a new caller-save insn and set the code. */
- static struct insn_chain *
- -insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
- +insert_one_insn (struct insn_chain *chain, int before_p,
- + int code ATTRIBUTE_UNUSED, rtx pat)
- {
- rtx insn = chain->insn;
- struct insn_chain *new;
- @@ -857,6 +862,6 @@
- new->block = chain->block;
- new->is_caller_save_insn = 1;
-
- - INSN_CODE (new->insn) = code;
- + INSN_CODE (new->insn) = CALLER_SAVE_INSN_CODE (code);
- return new;
- }
- diff -Nur gcc-4.2.4.orig/gcc/calls.c gcc-4.2.4/gcc/calls.c
- --- gcc-4.2.4.orig/gcc/calls.c 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/calls.c 2015-07-03 18:46:05.717283542 -0500
- @@ -829,6 +829,7 @@
- {
- int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
- int endian_correction = 0;
- + rtx value;
-
- if (args[i].partial)
- {
- @@ -858,10 +859,22 @@
- )
- endian_correction = BITS_PER_WORD - bytes * BITS_PER_UNIT;
-
- +
- + value = args[i].value;
- +
- +#if METAG_PARTIAL_ARGS
- + if (args[i].partial)
- + {
- + HOST_WIDE_INT excess = (bytes + (UNITS_PER_WORD - 1)) & ~(UNITS_PER_WORD - 1);
- +
- + value = adjust_address (value, GET_MODE (value), excess - args[i].partial);
- + }
- +#endif
- +
- for (j = 0; j < args[i].n_aligned_regs; j++)
- {
- rtx reg = gen_reg_rtx (word_mode);
- - rtx word = operand_subword_force (args[i].value, j, BLKmode);
- + rtx word = operand_subword_force (value, j, BLKmode);
- int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);
-
- args[i].aligned_regs[j] = reg;
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/builtins.md gcc-4.2.4/gcc/config/metag/builtins.md
- --- gcc-4.2.4.orig/gcc/config/metag/builtins.md 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/builtins.md 2015-07-03 18:46:05.741283542 -0500
- @@ -0,0 +1,106 @@
- +;; Machine description for GNU compiler,
- +;; Imagination Technologies Meta version.
- +;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
- +;; Imagination Technologies Ltd
- +
- +;; This file is part of GCC.
- +
- +;; GCC 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 3, or (at your option) any later
- +;; version.
- +
- +;; GCC 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 GCC; see the file COPYING3. If not see
- +;; <http://www.gnu.org/licenses/>.
- +
- +;;- meta builtins functions
- +
- +;; "__builtin_dcache_preload" data cache preload
- +(define_insn "dcache_preload"
- + [(set (reg:SI RAPF_REG)
- + (unspec_volatile:SI [(match_operand:SI 0 "metag_register_op" "r")] VUNSPEC_DCACHE_PRELOAD))]
- + "TARGET_BUILTINS_METAC_1_1 || TARGET_BUILTINS_METAC_1_2 || TARGET_BUILTINS_METAC_2_1"
- + "MOV\\tRAPF,%0\\t\\t%@ (*prefetch OK)"
- + [(set_attr "type" "fast")])
- +
- +;; "__builtin_dcache_flush" data cache flush
- +(define_insn "dcache_flush"
- + [(unspec_volatile [(match_operand:SI 0 "metag_register_op" "r")
- + (match_operand:SI 1 "metag_register_op" "r")] VUNSPEC_DCACHE)]
- + "TARGET_BUILTINS_METAC_1_2 || TARGET_BUILTINS_METAC_2_1"
- + "DCACHE\\t[%0],%1\\t\\t%@ (*flush OK)"
- + [(set_attr "type" "fast")])
- +
- +;; "__builtin_dcache_refresh" data cache refresh
- +(define_insn "dcache_refresh"
- + [(set (reg:SI RAPF_REG)
- + (unspec_volatile:SI [(match_operand:SI 0 "metag_register_op" "d")
- + (match_operand:SI 1 "metag_register_op" "a")] VUNSPEC_DCACHE_REFRESH))]
- + "TARGET_BUILTINS_METAC_1_1 || TARGET_BUILTINS_METAC_1_2 || TARGET_BUILTINS_METAC_2_1"
- + "*
- +{
- + if (TARGET_BUILTINS_METAC_1_1)
- + output_asm_insn (\"SETB\\t[%0],%1\\t\\t%@ (*refresh ...\\n\\tLSL\\tRAPF,%0,#6\\t\\t%@ ... OK)\",
- + operands);
- + else
- + output_asm_insn (\"DCACHE\\t[%0],%1\\t\\t%@ (*refresh ...\\n\\tADD\\tRAPF,%0,#0\\t\\t%@ ... OK)\",
- + operands);
- + return \"\";
- +}"
- + [(set_attr "type" "two")])
- +
- +;; "__builtin_meta2_cacherd"
- +(define_insn "meta2_cacherd"
- + [(set (match_operand:SI 0 "metag_register_op" "=r")
- + (unspec_volatile:SI [(match_operand:SI 1 "metag_register_op" "r")] VUNSPEC_META2_CACHERD))]
- + "TARGET_BUILTINS_METAC_2_1"
- + "CACHERD\\t%0,[%1]\\t\\t%@ (*cacherd OK)"
- + [(set_attr "type" "fast")])
- +
- +;; "__builtin_meta2_cacherl"
- +(define_insn "meta2_cacherl"
- + [(set (match_operand:DI 0 "metag_register_op" "=r")
- + (unspec_volatile:DI [(match_operand:SI 1 "metag_register_op" "r")] VUNSPEC_META2_CACHERL))]
- + "TARGET_BUILTINS_METAC_2_1"
- + "CACHERL\\t%0,%t0,[%1]\\t\\t%@ (*cacherl OK)"
- + [(set_attr "type" "fast")])
- +
- +;; "__builtin_meta2_cachewd"
- +(define_insn "meta2_cachewd"
- + [(unspec_volatile [(match_operand:SI 0 "metag_register_op" "r")
- + (match_operand:SI 1 "metag_register_op" "r")] VUNSPEC_META2_CACHEWD)]
- + "TARGET_BUILTINS_METAC_2_1"
- + "CACHEWD\\t[%0],%1\\t\\t%@ (*cachewd OK)"
- + [(set_attr "type" "fast")])
- +
- +;; "__builtin_meta2_cachewl"
- +(define_insn "meta2_cachewl"
- + [(unspec_volatile [(match_operand:SI 0 "metag_register_op" "r")
- + (match_operand:DI 1 "metag_register_op" "r")] VUNSPEC_META2_CACHEWL)]
- + "TARGET_BUILTINS_METAC_2_1"
- + "CACHEWL\\t[%0],%1,%t1\\t\\t%@ (*cachewl OK)"
- + [(set_attr "type" "fast")])
- +
- +; "__builtin_metag_bswap"
- +(define_insn "metag_bswap"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,f")
- + (unspec:SI [(match_operand:SI 1 "metag_register_op" "e,f")] UNSPEC_METAG_BSWAP))]
- + "TARGET_BUILTINS_METAC_2_1 && metag_meta2_bex_enabled"
- + "BEXD\\t%0,%1\\t\\t%@ (*bswap OK)"
- + [(set_attr "type" "fast")])
- +
- +; "__builtin_metag_bswapll"
- +(define_insn "metag_bswapll"
- + [(set (match_operand:DI 0 "metag_register_op" "=d")
- + (unspec:DI [(match_operand:DI 1 "metag_register_op" "d")] UNSPEC_METAG_BSWAPLL))]
- + "TARGET_BUILTINS_METAC_2_1 && metag_meta2_bex_enabled"
- + "BEXL\\t%t0,%1\\t\\t%@ (*bswapll OK)"
- + [(set_attr "type" "fast")])
- +
- +;; end of file
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/combines.md gcc-4.2.4/gcc/config/metag/combines.md
- --- gcc-4.2.4.orig/gcc/config/metag/combines.md 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/combines.md 2015-07-03 18:46:05.745283542 -0500
- @@ -0,0 +1,1052 @@
- +;; Machine description for GNU compiler,
- +;; Imagination Technologies Meta version.
- +;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
- +;; Imagination Technologies Ltd
- +
- +;; This file is part of GCC.
- +
- +;; GCC 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 3, or (at your option) any later
- +;; version.
- +
- +;; GCC 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 GCC; see the file COPYING3. If not see
- +;; <http://www.gnu.org/licenses/>.
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising SI/HI/QI store pre-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*sto_<mode>_pre_inc_dec_modify_disp_split"
- + [(set (mem:MEMOP (plus:SI (match_operand:SI 0 "metag_regnofrm_op" "+efhl")
- + (match_operand:SI 1 "metag_offset6_<mode>" "<O>")))
- + (match_operand:<MODE> 2 "metag_register_op" "r"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_dup 1)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx pre, mem, insn;
- +
- + if (INTVAL (operands[1]) == GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_INC (SImode, operands[0]);
- + else if (INTVAL (operands[1]) == -GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_DEC (SImode, operands[0]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- +
- + pre = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + }
- +
- + mem = gen_rtx_MEM (<MODE>mode, pre);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[2]));
- +
- + if (auto_inc_p (pre))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*sto_<mode>_pre_modify_reg_split"
- + [(set (mem:MEMOP (plus:SI (match_operand:SI 0 "metag_regnofrm_op" "+%e,f,h,l")
- + (match_operand:SI 1 "metag_register_op" "e,f,h,l")))
- + (match_operand:<MODE> 2 "metag_register_op" "t,u,y,z"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_dup 1)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- + rtx pre_modify = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + rtx mem = gen_rtx_MEM (<MODE>mode, pre_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[2]));
- +
- + if (auto_inc_p (pre_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising SI/HI/QI store post-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*sto_<mode>_post_inc_dec_modify_disp_split"
- + [(set (mem:MEMOP (match_operand:SI 0 "metag_regnofrm_op" "+efhl"))
- + (match_operand:<MODE> 1 "metag_register_op" "r"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 2 "metag_offset6_<mode>" "<O>")))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx post, mem, insn;
- +
- + if (INTVAL (operands[2]) == GET_MODE_SIZE (<MODE>mode))
- + post = gen_rtx_POST_INC (SImode, operands[0]);
- + else if (INTVAL (operands[2]) == -GET_MODE_SIZE (<MODE>mode))
- + post = gen_rtx_POST_DEC (SImode, operands[0]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[2]);
- +
- + post = gen_rtx_POST_MODIFY (SImode, operands[0], plus);
- + }
- +
- + mem = gen_rtx_MEM (<MODE>mode, post);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
- +
- + if (auto_inc_p (post))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*sto_<mode>_post_modify_reg_split"
- + [(set (mem:MEMOP (match_operand:SI 0 "metag_regnofrm_op" "+e,f,h,l"))
- + (match_operand:<MODE> 1 "metag_register_op" "t,u,y,z"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 2 "metag_register_op" "e,f,h,l")))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[2]);
- + rtx post_modify = gen_rtx_POST_MODIFY (SImode, operands[0], plus);
- + rtx mem = gen_rtx_MEM (<MODE>mode, post_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
- +
- + if (auto_inc_p (post_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising QI/HI/SI load pre-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*lod_<mode>_pre_inc_dec_modify_disp_split"
- + [(set (match_operand:<MODE> 0 "metag_register_op" "=r")
- + (mem:MEMOP (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "+efhl")
- + (match_operand:SI 2 "metag_offset6_<mode>" "<O>"))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx pre, mem, insn;
- +
- + if (INTVAL (operands[2]) == GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_INC (SImode, operands[1]);
- + else if (INTVAL (operands[2]) == -GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_DEC (SImode, operands[1]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- +
- + pre = gen_rtx_PRE_MODIFY (SImode, operands[1], plus);
- + }
- +
- + mem = gen_rtx_MEM (<MODE>mode, pre);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
- +
- + if (auto_inc_p (pre))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*lod_<mode>_pre_modify_reg_split"
- + [(set (match_operand:<MODE> 0 "metag_register_op" "=r,r,r,r")
- + (mem:MEMOP (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "+e,f,h,l")
- + (match_operand:SI 2 "metag_register_op" "e,f,h,l"))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- + rtx pre_modify = gen_rtx_PRE_MODIFY (SImode, operands[1], plus);
- + rtx mem = gen_rtx_MEM (<MODE>mode, pre_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
- +
- + if (auto_inc_p (pre_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising DI store pre-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*sto_di_pre_inc_dec_modify_disp_split"
- + [(set (mem:DI (plus:SI (match_operand:SI 0 "metag_regnofrm_op" "+efhl")
- + (match_operand:SI 1 "metag_offset6_di" "O8")))
- + (match_operand:DI 2 "metag_register_op" "r"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_dup 1)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx pre, mem, insn;
- +
- + if (INTVAL (operands[1]) == GET_MODE_SIZE (DImode))
- + pre = gen_rtx_PRE_INC (SImode, operands[0]);
- + else if (INTVAL (operands[1]) == -GET_MODE_SIZE (DImode))
- + pre = gen_rtx_PRE_DEC (SImode, operands[0]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- +
- + pre = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + }
- +
- + mem = gen_rtx_MEM (DImode, pre);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[2]));
- +
- + if (auto_inc_p (pre))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*sto_di_pre_modify_reg_split"
- + [(set (mem:DI (plus:SI (match_operand:SI 0 "metag_regnofrm_op" "+e,f,h,l")
- + (match_operand:SI 1 "metag_register_op" "e,f,h,l")))
- + (match_operand:DI 2 "metag_register_op" "a,a,d,d"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_dup 1)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- + rtx pre_modify = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + rtx mem = gen_rtx_MEM (DImode, pre_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[2]));
- +
- + if (auto_inc_p (pre_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising DI store post-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*sto_di_post_inc_dec_modify_disp_split"
- + [(set (mem:DI (match_operand:SI 0 "metag_regnofrm_op" "+efhl"))
- + (match_operand:DI 1 "metag_register_op" "r"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 2 "metag_offset6_di" "O8")))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx post, mem, insn;
- +
- + if (INTVAL (operands[2]) == GET_MODE_SIZE (DImode))
- + post = gen_rtx_POST_INC (SImode, operands[0]);
- + else if (INTVAL (operands[2]) == -GET_MODE_SIZE (DImode))
- + post = gen_rtx_POST_DEC (SImode, operands[0]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[2]);
- +
- + post = gen_rtx_POST_MODIFY (SImode, operands[0], plus);
- + }
- +
- + mem = gen_rtx_MEM (DImode, post);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
- +
- + if (auto_inc_p (post))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*sto_di_post_modify_reg_split"
- + [(set (mem:DI (match_operand:SI 0 "metag_regnofrm_op" "+e,f,h,l"))
- + (match_operand:DI 1 "metag_register_op" "a,a,d,d"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 2 "metag_register_op" "e,f,h,l")))]
- +
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[2]);
- + rtx post_modify = gen_rtx_POST_MODIFY (SImode, operands[0], plus);
- + rtx mem = gen_rtx_MEM (DImode, post_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
- +
- + if (auto_inc_p (post_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising DI load pre-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*lod_di_pre_inc_dec_modify_disp_split"
- + [(set (match_operand:DI 0 "metag_register_op" "=r")
- + (mem:DI (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "+efhl")
- + (match_operand:SI 2 "metag_offset6_di" "O8"))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx pre, mem, insn;
- +
- + if (INTVAL (operands[2]) == GET_MODE_SIZE (DImode))
- + pre = gen_rtx_PRE_INC (SImode, operands[1]);
- + else if (INTVAL (operands[2]) == -GET_MODE_SIZE (DImode))
- + pre = gen_rtx_PRE_DEC (SImode, operands[1]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- +
- + pre = gen_rtx_PRE_MODIFY (SImode, operands[1], plus);
- + }
- +
- + mem = gen_rtx_MEM (DImode, pre);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
- +
- + if (auto_inc_p (pre))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn_and_split "*lod_di_pre_modify_reg_split"
- + [(set (match_operand:DI 0 "metag_register_op" "=r,r,r,r")
- + (mem:DI (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "+e,f,h,l")
- + (match_operand:SI 2 "metag_register_op" "e,f,h,l"))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- + rtx pre_modify = gen_rtx_PRE_MODIFY (SImode, operands[1], plus);
- + rtx mem = gen_rtx_MEM (DImode, pre_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
- +
- + if (auto_inc_p (pre_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising DI load post-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*lod_di_post_inc_dec_modify_disp_split"
- + [(set (match_operand:SI 0 "metag_regnofrm_op" "+efhl")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_di" "O8")))
- + (set (match_operand:DI 2 "metag_register_op" "=r")
- + (mem:DI (match_dup 0)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx post, mem, insn;
- +
- + if (INTVAL (operands[1]) == GET_MODE_SIZE (DImode))
- + post = gen_rtx_PRE_INC (SImode, operands[0]);
- + else if (INTVAL (operands[1]) == -GET_MODE_SIZE (DImode))
- + post = gen_rtx_PRE_DEC (SImode, operands[0]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- +
- + post = gen_rtx_POST_MODIFY (SImode, operands[0], plus);
- + }
- +
- + mem = gen_rtx_MEM (DImode, post);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[2], mem));
- +
- + if (auto_inc_p (post))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn_and_split "*lod_di_post_modify_reg_split"
- + [(set (match_operand:SI 0 "metag_regnofrm_op" "+e,f,h,l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_register_op" "e,f,h,l")))
- + (set (match_operand:DI 2 "metag_register_op" "=r,r,r,r")
- + (mem:DI (match_dup 0)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- + rtx post_modify = gen_rtx_POST_MODIFY (SImode, operands[0], plus);
- + rtx mem = gen_rtx_MEM (DImode, post_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, operands[2], mem));
- +
- + if (auto_inc_p (post_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising zero extend EXTHI load pre-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*lodz_<mode>hi_pre_inc_dec_modify_disp_split"
- + [(set (match_operand:HI 0 "metag_register_op" "=r")
- + (zero_extend:HI
- + (mem:EXTHI (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "+efhl")
- + (match_operand:SI 2 "metag_offset6_<mode>" "<O>")))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx pre, mem, zextend, insn;
- +
- + if (INTVAL (operands[2]) == GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_INC (SImode, operands[1]);
- + else if (INTVAL (operands[2]) == -GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_DEC (SImode, operands[1]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- +
- + pre = gen_rtx_PRE_MODIFY (SImode, operands[1], plus);
- + }
- +
- + mem = gen_rtx_MEM (<MODE>mode, pre);
- + zextend = gen_rtx_ZERO_EXTEND (HImode, mem);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], zextend));
- +
- + if (auto_inc_p (pre))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*lodz_<mode>hi_pre_modify_reg_split"
- + [(set (match_operand:HI 0 "metag_register_op" "=r,r,r,r")
- + (zero_extend:HI
- + (mem:EXTHI (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "+e,f,h,l")
- + (match_operand:SI 2 "metag_register_op" "e,f,h,l")))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- + rtx pre_modify = gen_rtx_PRE_MODIFY (SImode, operands[1], plus);
- + rtx mem = gen_rtx_MEM (<MODE>mode, pre_modify);
- + rtx zextend = gen_rtx_ZERO_EXTEND (HImode, mem);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], zextend));
- +
- + if (auto_inc_p (pre_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising zero extend EXTSI load pre-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*lodz_<mode>si_pre_inc_dec_modify_disp_split"
- + [(set (match_operand:SI 0 "metag_register_op" "=r")
- + (zero_extend:SI
- + (mem:EXTSI (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "+efhl")
- + (match_operand:SI 2 "metag_offset6_<mode>" "<O>")))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx pre, mem, zextend, insn;
- +
- + if (INTVAL (operands[2]) == GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_INC (SImode, operands[1]);
- + else if (INTVAL (operands[2]) == -GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_DEC (SImode, operands[1]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- +
- + pre = gen_rtx_PRE_MODIFY (SImode, operands[1], plus);
- + }
- +
- + mem = gen_rtx_MEM (<MODE>mode, pre);
- + zextend = gen_rtx_ZERO_EXTEND (SImode, mem);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], zextend));
- +
- + if (auto_inc_p (pre))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*lodz_<mode>si_pre_modify_reg_split"
- + [(set (match_operand:SI 0 "metag_register_op" "=r,r,r,r")
- + (zero_extend:SI
- + (mem:EXTSI (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "+e,f,h,l")
- + (match_operand:SI 2 "metag_register_op" "e,f,h,l")))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- + rtx pre_modify = gen_rtx_PRE_MODIFY (SImode, operands[1], plus);
- + rtx mem = gen_rtx_MEM (<MODE>mode, pre_modify);
- + rtx zextend = gen_rtx_ZERO_EXTEND (SImode, mem);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], zextend));
- +
- + if (auto_inc_p (pre_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising SF store pre-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*sto_sf_pre_inc_dec_modify_disp_split"
- + [(set (mem:SF
- + (plus:SI (match_operand:SI 0 "metag_regnofrm_op" "+efhl")
- + (match_operand:SI 1 "metag_offset6_sf" "O4")))
- + (match_operand:SF 2 "metag_register_op" "r"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_dup 1)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx pre, mem, insn;
- +
- + if (INTVAL (operands[1]) == GET_MODE_SIZE (SFmode))
- + pre = gen_rtx_PRE_INC (SImode, operands[0]);
- + else if (INTVAL (operands[1]) == -GET_MODE_SIZE (SFmode))
- + pre = gen_rtx_PRE_DEC (SImode, operands[0]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- +
- + pre = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + }
- +
- + mem = gen_rtx_MEM (SFmode, pre);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[2]));
- +
- + if (auto_inc_p (pre))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*sto_sf_pre_modify_reg_split"
- + [(set (mem:SF
- + (plus:SI (match_operand:SI 0 "metag_regnofrm_op" "+%e,f,h,l")
- + (match_operand:SI 1 "metag_register_op" "e,f,h,l")))
- + (match_operand:SF 2 "metag_register_op" "t,u,y,z"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_dup 1)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- + rtx pre_modify = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + rtx mem = gen_rtx_MEM (SFmode, pre_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[2]));
- +
- + if (auto_inc_p (pre_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising SF store post-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*sto_sf_post_inc_dec_modify_disp_split"
- + [(set (mem:SF (match_operand:SI 0 "metag_regnofrm_op" "+efhl"))
- + (match_operand:SF 1 "metag_register_op" "r"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 2 "metag_offset6_sf" "O4")))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx post, mem, insn;
- +
- + if (INTVAL (operands[2]) == GET_MODE_SIZE (SFmode))
- + post = gen_rtx_POST_INC (SImode, operands[0]);
- + else if (INTVAL (operands[2]) == -GET_MODE_SIZE (SFmode))
- + post = gen_rtx_POST_DEC (SImode, operands[0]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[2]);
- +
- + post = gen_rtx_POST_MODIFY (SImode, operands[0], plus);
- + }
- +
- + mem = gen_rtx_MEM (SFmode, post);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
- +
- + if (auto_inc_p (post))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*sto_sf_post_modify_reg_split"
- + [(set (mem:SF (match_operand:SI 0 "metag_regnofrm_op" "+e,f,h,l"))
- + (match_operand:SF 1 "metag_register_op" "t,u,y,z"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 2 "metag_register_op" "e,f,h,l")))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[2]);
- + rtx post_modify = gen_rtx_POST_MODIFY (SImode, operands[0], plus);
- + rtx mem = gen_rtx_MEM (SFmode, post_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
- +
- + if (auto_inc_p (post_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising SF load pre-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*lod_sf_pre_inc_dec_modify_disp_split"
- + [(set (match_operand:SF 0 "metag_register_op" "=r")
- + (mem:SF (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "+efhl")
- + (match_operand:SI 2 "metag_offset6_sf" "O4"))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx pre, mem, insn;
- +
- + if (INTVAL (operands[2]) == GET_MODE_SIZE (SFmode))
- + pre = gen_rtx_PRE_INC (SImode, operands[1]);
- + else if (INTVAL (operands[2]) == -GET_MODE_SIZE (SFmode))
- + pre = gen_rtx_PRE_DEC (SImode, operands[1]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- +
- + pre = gen_rtx_PRE_MODIFY (SImode, operands[1], plus);
- + }
- +
- + mem = gen_rtx_MEM (SFmode, pre);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
- +
- + if (auto_inc_p (pre))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*lod_sf_pre_modify_reg_split"
- + [(set (match_operand:SF 0 "metag_register_op" "=r,r,r,r")
- + (mem:SF (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "+e,f,h,l")
- + (match_operand:SI 2 "metag_register_op" "e,f,h,l"))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- + rtx pre_modify = gen_rtx_PRE_MODIFY (SImode, operands[1], plus);
- + rtx mem = gen_rtx_MEM (SFmode, pre_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
- +
- + if (auto_inc_p (pre_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising DF load pre-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*lod_df_pre_inc_dec_modify_disp_split"
- + [(set (match_operand:DF 0 "metag_register_op" "=r")
- + (mem:DF (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "+efhl")
- + (match_operand:SI 2 "metag_offset6_df" "O8"))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx pre, mem, insn;
- +
- + if (INTVAL (operands[2]) == GET_MODE_SIZE (DFmode))
- + pre = gen_rtx_PRE_INC (SImode, operands[1]);
- + else if (INTVAL (operands[2]) == -GET_MODE_SIZE (DFmode))
- + pre = gen_rtx_PRE_DEC (SImode, operands[1]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- +
- + pre = gen_rtx_PRE_MODIFY (SImode, operands[1], plus);
- + }
- +
- + mem = gen_rtx_MEM (DFmode, pre);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
- +
- + if (auto_inc_p (pre))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn_and_split "*lod_df_pre_modify_reg_split"
- + [(set (match_operand:DF 0 "metag_register_op" "=r,r,r,r")
- + (mem:DF (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "+e,f,h,l")
- + (match_operand:SI 2 "metag_register_op" "e,f,h,l"))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- + rtx pre_modify = gen_rtx_PRE_MODIFY (SImode, operands[1], plus);
- + rtx mem = gen_rtx_MEM (DFmode, pre_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
- +
- + if (auto_inc_p (pre_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising DF load post-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*lod_df_post_inc_dec_modify_disp_split"
- + [(set (match_operand:SI 0 "metag_regnofrm_op" "+efhl")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_df" "O8")))
- + (set (match_operand:DF 2 "metag_register_op" "=r")
- + (mem:DF (match_dup 0)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx post, mem, insn;
- +
- + if (INTVAL (operands[1]) == GET_MODE_SIZE (DFmode))
- + post = gen_rtx_PRE_INC (SImode, operands[0]);
- + else if (INTVAL (operands[1]) == -GET_MODE_SIZE (DFmode))
- + post = gen_rtx_PRE_DEC (SImode, operands[0]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- +
- + post = gen_rtx_POST_MODIFY (SImode, operands[0], plus);
- + }
- +
- + mem = gen_rtx_MEM (DFmode, post);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[2], mem));
- +
- + if (auto_inc_p (post))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn_and_split "*lod_df_post_modify_reg_split"
- + [(set (match_operand:SI 0 "metag_regnofrm_op" "+e,f,h,l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_register_op" "e,f,h,l")))
- + (set (match_operand:DF 2 "metag_register_op" "=r,r,r,r")
- + (mem:DF (match_dup 0)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- + rtx post_modify = gen_rtx_POST_MODIFY (SImode, operands[0], plus);
- + rtx mem = gen_rtx_MEM (DFmode, post_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, operands[2], mem));
- +
- + if (auto_inc_p (post_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising DF store pre-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*sto_df_pre_inc_dec_modify_disp_split"
- + [(set (mem:DF (plus:SI (match_operand:SI 0 "metag_regnofrm_op" "+efhl")
- + (match_operand:SI 1 "metag_offset6_df" "O8")))
- + (match_operand:DF 2 "metag_register_op" "r"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_dup 1)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx pre, mem, insn;
- +
- + if (INTVAL (operands[1]) == GET_MODE_SIZE (DFmode))
- + pre = gen_rtx_PRE_INC (SImode, operands[0]);
- + else if (INTVAL (operands[1]) == -GET_MODE_SIZE (DFmode))
- + pre = gen_rtx_PRE_DEC (SImode, operands[0]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- +
- + pre = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + }
- +
- + mem = gen_rtx_MEM (DFmode, pre);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[2]));
- +
- + if (auto_inc_p (pre))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*sto_df_pre_modify_reg_split"
- + [(set (mem:DF (plus:SI (match_operand:SI 0 "metag_regnofrm_op" "+e,f,h,l")
- + (match_operand:SI 1 "metag_register_op" "e,f,h,l")))
- + (match_operand:DF 2 "metag_register_op" "a,a,d,d"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_dup 1)))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- + rtx pre_modify = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + rtx mem = gen_rtx_MEM (DFmode, pre_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[2]));
- +
- + if (auto_inc_p (pre_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +;; | Recognising DF store post-inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn_and_split "*sto_df_post_inc_dec_modify_disp_split"
- + [(set (mem:DF (match_operand:SI 0 "metag_regnofrm_op" "+efhl"))
- + (match_operand:DF 1 "metag_register_op" "r"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 2 "metag_offset6_df" "O8")))]
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx post, mem, insn;
- +
- + if (INTVAL (operands[2]) == GET_MODE_SIZE (DFmode))
- + post = gen_rtx_POST_INC (SImode, operands[0]);
- + else if (INTVAL (operands[2]) == -GET_MODE_SIZE (DFmode))
- + post = gen_rtx_POST_DEC (SImode, operands[0]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[2]);
- +
- + post = gen_rtx_POST_MODIFY (SImode, operands[0], plus);
- + }
- +
- + mem = gen_rtx_MEM (DFmode, post);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
- +
- + if (auto_inc_p (post))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*sto_df_post_modify_reg_split"
- + [(set (mem:DF (match_operand:SI 0 "metag_regnofrm_op" "+e,f,h,l"))
- + (match_operand:DF 1 "metag_register_op" "a,a,d,d"))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 2 "metag_register_op" "e,f,h,l")))]
- +
- + "TARGET_METAC_1_1
- + && !reload_in_progress && !reload_completed"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[2]);
- + rtx post_modify = gen_rtx_POST_MODIFY (SImode, operands[0], plus);
- + rtx mem = gen_rtx_MEM (DFmode, post_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
- +
- + if (auto_inc_p (post_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- + [(set_attr "type" "fast")])
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/constants.md gcc-4.2.4/gcc/config/metag/constants.md
- --- gcc-4.2.4.orig/gcc/config/metag/constants.md 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/constants.md 2015-07-03 18:46:05.745283542 -0500
- @@ -0,0 +1,179 @@
- +;; Constants definitions for META
- +;; Copyright (C) 2007 Imagination Technologies Ltd
- +
- +;; This file is part of GCC.
- +
- +;; GCC 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 3, or (at your option) any later
- +;; version.
- +
- +;; GCC 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 GCC; see the file COPYING3. If not see
- +;; <http://www.gnu.org/licenses/>.
- +
- +;; UNSPEC
- +(define_constants
- + [(UNSPEC_GOTOFF 1)
- + (UNSPEC_GOT 2)
- + (UNSPEC_PLT 3)
- + (UNSPEC_PIC 4)
- + (UNSPEC_PIC_BASE 5)
- +
- + (UNSPEC_PROLOGUE_USE 6)
- + (UNSPEC_CONCAT 7)
- + (UNSPEC_SIBCALL 8)
- + (UNSPEC_SIBCALL_VALUE 9)
- +
- + (UNSPEC_RET_COND 10)
- + (UNSPEC_RET_COND_INVERTED 11)
- +
- + (UNSPEC_METAG_BSWAP 12)
- + (UNSPEC_METAG_BSWAPLL 13)
- +
- + (UNSPEC_MINIM_JUMP_TABLE 14)
- +
- + (UNSPEC_FIRST_TLS 15)
- + (UNSPEC_TLS 15)
- + (UNSPEC_TLSGD 16)
- + (UNSPEC_TLSLDM 17)
- + (UNSPEC_TLSLDO 18)
- + (UNSPEC_TLSIE 19)
- + (UNSPEC_TLSLE 20)
- + (UNSPEC_LAST_TLS 20)])
- +
- +
- +;; UNSPEC VOLATILE
- +(define_constants
- + [(VUNSPEC_DCACHE_PRELOAD 1)
- + (VUNSPEC_DCACHE 2)
- + (VUNSPEC_DCACHE_REFRESH 3)
- + (VUNSPEC_BLOCKAGE 4)
- + (VUNSPEC_EPILOGUE 5)
- + (VUNSPEC_EH_RETURN 6)
- + (VUNSPEC_META2_CACHERD 7)
- + (VUNSPEC_META2_CACHERL 8)
- + (VUNSPEC_META2_CACHEWD 9)
- + (VUNSPEC_META2_CACHEWL 10)
- + (VUNSPEC_TTMOV 11)
- + (VUNSPEC_TTREC 12)])
- +
- +
- +;; Register
- +(define_constants
- + [(D0Ar6_REG 2)
- + (D1Ar5_REG 3)
- + (D0Ar4_REG 4)
- + (D1Ar3_REG 5)
- + (D0Ar2_REG 6)
- + (D1Ar1_REG 7)
- +
- + (D0Re0_REG 0)
- + (D1Re0_REG 1)
- + (D0FrT_REG 8)
- + (D1RtP_REG 9)
- +
- + (FIRST_DATA_REG 0)
- + (D0_0_REG 0)
- + (D1_0_REG 1)
- + (D0_1_REG 2)
- + (D1_1_REG 3)
- + (D0_2_REG 4)
- + (D1_2_REG 5)
- + (D0_3_REG 6)
- + (D1_3_REG 7)
- + (D0_4_REG 8)
- + (D1_4_REG 9)
- + (D0_5_REG 10)
- + (D1_5_REG 11)
- + (D0_6_REG 12)
- + (D1_6_REG 13)
- + (D0_7_REG 14)
- + (D1_7_REG 15)
- + (FIRST_ECH_DATA_REG 16)
- + (D0_8_REG 16)
- + (D1_8_REG 17)
- + (D0_9_REG 18)
- + (D1_9_REG 19)
- + (D0_10_REG 20)
- + (D1_10_REG 21)
- + (D0_11_REG 22)
- + (D1_11_REG 23)
- + (D0_12_REG 24)
- + (D1_12_REG 25)
- + (D0_13_REG 26)
- + (D1_13_REG 27)
- + (D0_14_REG 28)
- + (D1_14_REG 29)
- + (D0_15_REG 30)
- + (D1_15_REG 31)
- + (LAST_DATA_REG 31)
- +
- + (A0StP_REG 32)
- + (A1GbP_REG 33)
- + (A0FrP_REG 34)
- + (A1LbP_REG 35)
- +
- + (PIC_REG 35)
- +
- + (FIRST_ADDR_REG 32)
- + (A0_0_REG 32)
- + (A1_0_REG 33)
- + (A0_1_REG 34)
- + (A1_1_REG 35)
- + (A0_2_REG 36)
- + (A1_2_REG 37)
- + (A0_3_REG 38)
- + (A1_3_REG 39)
- + (FIRST_ECH_ADDR_REG 40)
- + (A0_4_REG 40)
- + (A1_4_REG 41)
- + (A0_5_REG 42)
- + (A1_5_REG 43)
- + (A0_6_REG 44)
- + (A1_6_REG 45)
- + (A0_7_REG 46)
- + (A1_7_REG 47)
- + (LAST_ADDR_REG 47)
- +
- + (FRAME_REG 48)
- + (CC_REG 49)
- + (ARGP_REG 50)
- + (RAPF_REG 51)
- + (CPC0_REG 52)
- + (CPC1_REG 53)
- + (PC_REG 54)
- + (TXRPT_REG 55)
- +
- + (FIRST_FP_REG 56)
- + (FX_0_REG 56)
- + (FX_1_REG 57)
- + (FX_2_REG 58)
- + (FX_3_REG 59)
- + (FX_4_REG 60)
- + (FX_5_REG 61)
- + (FX_6_REG 62)
- + (FX_7_REG 63)
- + (FX_8_REG 64)
- + (FX_9_REG 65)
- + (FX_10_REG 66)
- + (FX_11_REG 67)
- + (FX_12_REG 68)
- + (FX_13_REG 69)
- + (FX_14_REG 70)
- + (FX_15_REG 71)
- + (LAST_FP_REG 71)
- + (TTREC_REG 72)
- + (TTRECL_REG 73)
- + (LAST_REG 73)])
- +
- +;; Exception handling - dwarf2 call frame unwinder
- +(define_constants
- + [(EH_RETURN_FIRST_DATA_REG 2)
- + (EH_RETURN_LAST_DATA_REG 3)
- + (EH_RETURN_STACKADJ_REG 4)])
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/constraints.md gcc-4.2.4/gcc/config/metag/constraints.md
- --- gcc-4.2.4.orig/gcc/config/metag/constraints.md 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/constraints.md 2015-07-03 18:46:05.745283542 -0500
- @@ -0,0 +1,319 @@
- +;; Constraint definitions for META.
- +;; Copyright (C) 2007, 2010 Imagination Technologies Ltd
- +
- +;; This file is part of GCC.
- +
- +;; GCC 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 3, or (at your option) any later
- +;; version.
- +
- +;; GCC 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 GCC; see the file COPYING3. If not see
- +;; <http://www.gnu.org/licenses/>.
- +
- +;; Register constraints
- +
- +(define_register_constraint "d" "D_REGS"
- + "data unit register")
- +
- +(define_register_constraint "e" "D0_REGS"
- + "data unit 0 register")
- +
- +(define_register_constraint "f" "D1_REGS"
- + "data unit 1 register")
- +
- +(define_register_constraint "a" "A_REGS"
- + "address unit register")
- +
- +(define_register_constraint "h" "A0_REGS"
- + "address unit 0 register")
- +
- +(define_register_constraint "l" "A1_REGS"
- + "address unit 1 register")
- +
- +(define_register_constraint "be" "Be_REGS"
- + "O2R register data unit 0")
- +
- +(define_register_constraint "bf" "Bf_REGS"
- + "O2R register data unit 1")
- +
- +(define_register_constraint "bd" "Bd_REGS"
- + "O2R register data unit")
- +
- +(define_register_constraint "bh" "Bh_REGS"
- + "O2R register address unit 0")
- +
- +(define_register_constraint "bl" "Bl_REGS"
- + "O2R register address unit 1")
- +
- +(define_register_constraint "ba" "Ba_REGS"
- + "O2R register address unit")
- +
- +(define_register_constraint "br" "Br_REGS"
- + "O2R register any unit")
- +
- +(define_register_constraint "t" "nD0_REGS"
- + "data unit 1, addr unit 0, addr unit 1 register")
- +
- +(define_register_constraint "u" "nD1_REGS"
- + "data unit 0, addr unit 0, addr unit 1 register")
- +
- +(define_register_constraint "y" "nA0_REGS"
- + "data unit 0, data unit 1, addr unit 1 register")
- +
- +(define_register_constraint "z" "nA1_REGS"
- + "data unit 0, addr unit 1, addr unit 0 register")
- +
- +(define_register_constraint "q" "nBU_REGS"
- + "not base unit register")
- +
- +(define_register_constraint "Wx" "Wx_REGS"
- + "control register i.e. TXRPT")
- +
- +(define_register_constraint "WQh" "WQh_REGS"
- + "A0 QuickRoT control registers A0.2 A0.3")
- +
- +(define_register_constraint "WQl" "WQl_REGS"
- + "A1 QuickRoT control registers A1.2 A1.3")
- +
- +(define_register_constraint "Ye" "Ye_REGS"
- + "data unit 0 register 12-bit offsetable")
- +
- +(define_register_constraint "Yf" "Yf_REGS"
- + "data unit 1 register 12-bit offsetable")
- +
- +(define_register_constraint "Yd" "Yd_REGS"
- + "data unit register 12-bit offsetable")
- +
- +(define_register_constraint "Yh" "Yh_REGS"
- + "addr unit 0 register 12-bit offsetable")
- +
- +(define_register_constraint "Yl" "Yl_REGS"
- + "addr unit 1 register 12-bit offsetable")
- +
- +(define_register_constraint "Ya" "Ya_REGS"
- + "addr unit register 12-bit offsetable")
- +
- +(define_register_constraint "Yr" "Yr_REGS"
- + "data/addr register 12-bit offsetable")
- +
- +(define_register_constraint "Yne" "nYe_REGS"
- + "...")
- +
- +(define_register_constraint "Ynf" "nYf_REGS"
- + "...")
- +
- +(define_register_constraint "Ynd" "nYd_REGS"
- + "...")
- +
- +(define_register_constraint "Ynh" "nYh_REGS"
- + "...")
- +
- +(define_register_constraint "Ynl" "nYl_REGS"
- + "...")
- +
- +(define_register_constraint "Yna" "nYa_REGS"
- + "...")
- +
- +(define_register_constraint "Ynr" "nYr_REGS"
- + "...")
- +
- +(define_register_constraint "ce" "metag_fpu_resources ? cD0_REGS : D0_REGS"
- + "data 0 or float unit register")
- +
- +(define_register_constraint "cf" "metag_fpu_resources ? cD1_REGS : D1_REGS"
- + "data 1, or float unit register")
- +
- +(define_register_constraint "cd" "metag_fpu_resources ? cD_REGS : D_REGS"
- + "data, or float unit register")
- +
- +(define_register_constraint "ch" "metag_fpu_resources ? cA0_REGS : A0_REGS"
- + "addr 0 or float unit register")
- +
- +(define_register_constraint "cl" "metag_fpu_resources ? cA1_REGS : A1_REGS"
- + "addr 1 or float unit register")
- +
- +(define_register_constraint "ca" "metag_fpu_resources ? cA_REGS : A_REGS"
- + "addr or float unit register")
- +
- +(define_register_constraint "cr" "metag_fpu_resources ? cDA_REGS : DA_REGS"
- + "data, addr or float unit register")
- +
- +(define_register_constraint "ct" "metag_fpu_resources ? cnD0_REGS : nD0_REGS"
- + "data unit 1, addr unit 0, addr unit 1 or float unit register")
- +
- +(define_register_constraint "cu" "metag_fpu_resources ? cnD1_REGS : nD1_REGS"
- + "data unit 0, addr unit 0, addr unit 1 or float unit register")
- +
- +(define_register_constraint "cy" "metag_fpu_resources ? cnA0_REGS : nA0_REGS"
- + "data unit 0, data unit 0, addr unit 1 or float unit register")
- +
- +(define_register_constraint "cz" "metag_fpu_resources ? cnA1_REGS : nA1_REGS"
- + "data unit 0, data unit 1, addr unit 0 or float unit register")
- +
- +(define_register_constraint "cx" "metag_fpu_resources ? FPC_REGS : NO_REGS"
- + "floating point register")
- +
- +(define_register_constraint "cp" "metag_fpu_resources ? FPP_REGS : NO_REGS"
- + "floating point register pair")
- +
- +;; Integer constraints
- +
- +(define_constraint "I"
- + "...."
- + (and (match_code "const_int")
- + (match_test "(ival >= -32768 && ival <= -256) || (ival >= 256 && ival <= 65535)")))
- +
- +(define_constraint "J"
- + "...."
- + (and (match_code "const_int")
- + (match_test "(ival & 0x0000FFFF) == 0")))
- +
- +(define_constraint "O0"
- + "...."
- + (and (match_code "const_int")
- + (match_test "(ival & 0xFFFF) == 0")))
- +
- +(define_constraint "O3"
- + "...."
- + (and (match_code "const_int")
- + (match_test "((ival >> 16) & 0x0000FFFF) == 0")))
- +
- +(define_constraint "K"
- + "..."
- + (and (match_code "const_int")
- + (match_test "0 <= ival && ival <= 255")))
- +
- +(define_constraint "L"
- + "..."
- + (and (match_code "const_int")
- + (match_test "0 <= ival && ival <= 31")))
- +
- +(define_constraint "M"
- + "..."
- + (and (match_code "const_int")
- + (match_test "((ival >> 16) & 0xFFFF) == 0x0000FFFF")))
- +
- +(define_constraint "N"
- + "..."
- + (and (match_code "const_int")
- + (match_test "((ival & 0x0000FFFF) == 0x0000FFFF)")))
- +
- +(define_constraint "O1"
- + "..."
- + (and (match_code "const_int")
- + (match_test "-32 <= ival && ival < 32")))
- +
- +(define_constraint "O2"
- + "..."
- + (and (match_code "const_int")
- + (match_test "(-64 <= ival && ival < 64) && (ival & 1) == 0")))
- +
- +(define_constraint "O4"
- + "..."
- + (and (match_code "const_int")
- + (match_test "(-128 <= ival && ival < 128) && (ival & 3) == 0")))
- +
- +(define_constraint "O8"
- + "..."
- + (and (match_code "const_int")
- + (match_test "(-256 <= ival && ival < 256) && (ival & 7) == 0")))
- +
- +(define_constraint "P"
- + "..."
- + (and (match_code "const_int")
- + (match_test "-255 <= ival && ival < 0")))
- +
- +(define_constraint "vci"
- + "..."
- + (and (match_code "const_vector")
- + (match_test "GET_MODE_INNER (mode) == SImode")))
- +
- +(define_constraint "vcf"
- + "..."
- + (and (match_code "const_vector")
- + (match_test "GET_MODE_INNER (mode) == SFmode")))
- +
- +(define_constraint "vc5"
- + "..."
- + (and (match_code "const_vector")
- + (match_test "metag_vector_5bit_op (op, mode)")))
- +
- +(define_constraint "v16"
- + "..."
- + (and (match_code "const_vector")
- + (match_test "metag_vector_16bit_op (op, mode)")))
- +
- +;; Floating-point constraints
- +
- +(define_constraint "G"
- + "Floating-point zero."
- + (and (match_code "const_double")
- + (match_test "GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode)")))
- +
- +(define_constraint "H"
- + "Floating-point one."
- + (and (match_code "const_double")
- + (match_test "GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST1_RTX (mode)")))
- +
- +(define_constraint "ci"
- + "Floating-point immediates in half precision"
- + (and (match_code "const_double")
- + (match_test "GET_MODE_CLASS (mode) == MODE_FLOAT && metag_fphalf_imm_op (op, mode)")))
- +
- +;; General constraints
- +
- +(define_constraint "Th"
- + "@internal"
- + (and (match_test "metag_mem_base_p (op, A0_REGS)")
- + (match_test "metag_legitimate_address_p (XEXP (op, 0), GET_MODE (op), true)")))
- +
- +(define_constraint "Tl"
- + "@internal"
- + (and (match_test "metag_mem_base_p (op, A1_REGS)")
- + (match_test "metag_legitimate_address_p (XEXP (op, 0), GET_MODE (op), true)")))
- +
- +(define_constraint "Te"
- + "@internal"
- + (and (match_test "metag_mem_base_p (op, D0_REGS)")
- + (match_test "metag_legitimate_address_p (XEXP (op, 0), GET_MODE (op), true)")))
- +
- +(define_constraint "Tf"
- + "@internal"
- + (and (match_test "metag_mem_base_p (op, D1_REGS)")
- + (match_test "metag_legitimate_address_p (XEXP (op, 0), GET_MODE (op), true)")))
- +
- +(define_constraint "Tr"
- + "@internal"
- + (and (match_test "metag_legitimate_address_p (XEXP (op, 0), GET_MODE (op), true)")
- + (not (match_test "GET_CODE (XEXP (op, 0)) == PLUS
- + && metag_regs_ok_for_base_offset_p (XEXP (XEXP (op, 0), 0),
- + XEXP (XEXP (op, 0), 1),
- + true)"))))
- +
- +(define_constraint "Z1"
- + "..."
- + (and (match_code "const_int")
- + (match_test "-2048 <= ival && ival < 2048")))
- +
- +(define_constraint "Z2"
- + "..."
- + (and (match_code "const_int")
- + (match_test "-4096 <= ival && ival < 4096 && (ival & 1) == 0")))
- +
- +(define_constraint "Z4"
- + "..."
- + (and (match_code "const_int")
- + (match_test "-8192 <= ival && ival < 8192 && (ival & 3) == 0")))
- +
- +(define_constraint "Z8"
- + "..."
- + (and (match_code "const_int")
- + (match_test "-16384 <= ival && ival < 16384 && (ival & 7) == 0")))
- +
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/driver-metag.c gcc-4.2.4/gcc/config/metag/driver-metag.c
- --- gcc-4.2.4.orig/gcc/config/metag/driver-metag.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/driver-metag.c 2015-07-03 18:46:05.745283542 -0500
- @@ -0,0 +1,276 @@
- +/* Subroutines for the gcc driver.
- + Copyright (C) 2008 Imagination Technologies Ltd
- +
- +This file is part of GCC.
- +
- +GCC 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 3, or (at your option)
- +any later version.
- +
- +GCC 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 GCC; see the file COPYING3. If not see
- +<http://www.gnu.org/licenses/>. */
- +
- +#include <string.h>
- +#include <stdlib.h>
- +#include "libiberty.h"
- +#include "filenames.h"
- +
- +const char *metag_reduce_options (int argc, const char **argv);
- +const char *metag_emb_asm_preprocessor (int argc, const char **argv);
- +const char *metag_emb_onlylast (int argc, const char **argv);
- +const char *metag_emb_change_suffix (int argc, const char **argv);
- +
- +/* This function will reduce all -mmetac options to remove all but
- + the last one with the %<S construct. It will do the same for
- + hard-float taking in to account that soft-float is the inverse
- + and also dealing with simd-float */
- +
- +enum fpu_state
- +{
- + FPU_SOFT_FLOAT,
- + FPU_HARD_FLOAT,
- + FPU_HARD_FLOAT_DOUBLE,
- + FPU_HARD_FLOAT_SINGLE
- +};
- +
- +const char *
- +metag_reduce_options (int argc, const char **argv)
- +{
- + /* Default FPU mode is soft float */
- + enum fpu_state fpu_state = FPU_SOFT_FLOAT;
- +
- + /* Default META core is 2.1 (though this will always be overriden so it does not matter) */
- + int metac_state = 21;
- +
- + /* SIMD FPU is not enabled by default */
- + int simd_float = 0;
- +
- + /* 'i' is always useful */
- + int i;
- +
- + /* 140 is the total length of all possible options that will be emitted with a null
- + terminator at the end */
- + char* buf = (char*)xmalloc(159);
- +
- + for (i = 0 ; i < argc ; i++)
- + {
- + if (strcmp (argv[i], "mhard-float=D") == 0)
- + {
- + fpu_state = FPU_HARD_FLOAT_DOUBLE;
- + simd_float = 0;
- + }
- + else if (strcmp (argv[i], "mhard-float=S") == 0)
- + {
- + fpu_state = FPU_HARD_FLOAT_SINGLE;
- + simd_float = 0;
- + }
- + else if (strcmp (argv[i], "mhard-float") == 0)
- + {
- + fpu_state = FPU_HARD_FLOAT;
- + simd_float = 0;
- + }
- + else if (strcmp (argv[i], "msoft-float") == 0 || strcmp (argv[i], "mhard-float=none") == 0)
- + {
- + fpu_state = FPU_SOFT_FLOAT;
- + simd_float = 0;
- + }
- + else if (strcmp (argv[i], "msimd-float") == 0)
- + simd_float = 1;
- + else if (strncmp (argv[i], "mmetac=", 7) == 0)
- + if (strlen (argv[i]) == 10)
- + {
- + metac_state = (argv[i][7] - '0') * 10;
- + metac_state += (argv[i][9] - '0');
- + }
- + }
- +
- + /* Point to the start of the buffer */
- + i = 0;
- +
- + /* Strip various duplicated/overridden options */
- + strncpy (&buf[i], "%<mhard-float=none ", 19);
- + i += 19;
- +
- + if (simd_float == 0)
- + {
- + strncpy (&buf[i], "%<msimd-float ", 14);
- + i += 14;
- + }
- +
- + if (fpu_state != FPU_SOFT_FLOAT)
- + {
- + strncpy (&buf[i], "%<msoft-float ", 14);
- + i += 14;
- + }
- +
- + if (fpu_state != FPU_HARD_FLOAT)
- + {
- + strncpy (&buf[i], "%<mhard-float ", 14);
- + i += 14;
- + }
- +
- + if (fpu_state != FPU_HARD_FLOAT_DOUBLE)
- + {
- + strncpy (&buf[i], "%<mhard-float=D ", 16);
- + i += 16;
- + }
- +
- + if (fpu_state != FPU_HARD_FLOAT_SINGLE)
- + {
- + strncpy (&buf[i], "%<mhard-float=S ", 16);
- + i += 16;
- + }
- +
- + if (metac_state != 1)
- + {
- + strncpy (&buf[i], "%<mmetac=0.1 ", 13);
- + i += 13;
- + }
- +
- + if (metac_state != 10)
- + {
- + strncpy (&buf[i], "%<mmetac=1.0 ", 13);
- + i += 13;
- + }
- +
- + if (metac_state != 11)
- + {
- + strncpy (&buf[i], "%<mmetac=1.1 ", 13);
- + i += 13;
- + }
- +
- + if (metac_state != 12)
- + {
- + strncpy (&buf[i], "%<mmetac=1.2 ", 13);
- + i += 13;
- + }
- +
- + if (metac_state != 21)
- + {
- + strncpy (&buf[i], "%<mmetac=2.1 ", 13);
- + i += 13;
- + }
- +
- + buf[i] = 0;
- +
- + return buf;
- +}
- +
- +/* This will be called by the spec parser in gcc.c when it sees
- + a %:meta_preprocessor(args) construct.
- +
- + It returns a string containing new command line parameters to be
- + passed to the assembler. This is for transforming -Dwhatever
- + into --defwhatever. The spec will do the translation of -D
- + to --def but this code removes all definitions that have
- + assignments as the embedded assembler cannot cope with these
- +
- + ARGC and ARGV are set depending on the actual arguments given
- + in the spec. */
- +const char *
- +metag_emb_asm_preprocessor (int argc, const char **argv)
- +{
- + char * cmd_args = NULL;
- + char * current_pos = NULL;
- + int args_size = 0;
- + int i;
- +
- + for (i = 0 ; i < argc ; i++)
- + {
- + if (strchr (argv[i], '=') == NULL)
- + args_size += strlen (argv[i]) + 1;
- + }
- +
- + if (args_size == 0)
- + return NULL;
- +
- + cmd_args = (char *)malloc (args_size);
- + current_pos = cmd_args;
- +
- + for (i = 0 ; i < argc ; i++)
- + {
- + if (strchr (argv[i], '=') == NULL)
- + {
- + int length = strlen (argv[i]);
- +
- + strcpy (current_pos, argv[i]);
- + *(current_pos+length) = ' ';
- + current_pos += length + 1;
- + }
- + }
- + *(current_pos-1) = 0;
- +
- + return cmd_args;
- +}
- +
- +const char *
- +metag_emb_onlylast (int argc, const char **argv)
- +{
- + if (argc != 0)
- + return argv[argc-1];
- + else
- + return NULL;
- +}
- +
- +const char *
- +metag_emb_change_suffix (int argc, const char **argv)
- +{
- + const char * old_filename = NULL;
- + char * new_filename = NULL;
- + unsigned int old_length = 0;
- + unsigned int new_length = 0;
- + const char * suffix = NULL;
- + int new_suffix_length = 0;
- + int dot_pos = 0;
- + int has_dot = 0;
- +
- + if (argc < 2)
- + {
- + fprintf (stderr, "Not enough arguments given to the meta_change_suffix function!\n");
- + exit (1);
- + }
- + else
- + {
- + suffix = argv[0];
- + /* If multiple -o switches are used on the command line the last one is used */
- + old_filename = argv[argc - 1];
- + old_length = strlen (old_filename);
- + new_suffix_length = strlen (suffix);
- +
- + /* Find the location of the . in the filename */
- + dot_pos = old_length;
- + while (dot_pos-- && !IS_DIR_SEPARATOR (old_filename[dot_pos]))
- + {
- + if (old_filename[dot_pos] == '.')
- + {
- + has_dot = 1;
- + break;
- + }
- + }
- +
- + /* Deal with the case where there is no dot in the filename */
- + if (!has_dot)
- + dot_pos = old_length;
- +
- + /* Compute the length of the string to hold the filename with the new suffix. */
- + new_length = dot_pos + new_suffix_length + 1;
- +
- + /* Create a new string to hold the filename, and initialise
- + it with the old filename excluding the dot and suffix (if applicable) */
- + new_filename = (char *)malloc (new_length + 1);
- + strncpy (new_filename, old_filename, dot_pos + 1);
- +
- + /* Add the dot and new suffix to the filename */
- + new_filename[dot_pos] = '.';
- + strcpy (&new_filename[dot_pos + 1], suffix);
- +
- + return new_filename;
- + }
- +}
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/dsppeephole2.md gcc-4.2.4/gcc/config/metag/dsppeephole2.md
- --- gcc-4.2.4.orig/gcc/config/metag/dsppeephole2.md 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/dsppeephole2.md 2015-07-03 18:46:05.745283542 -0500
- @@ -0,0 +1,394 @@
- +;; Machine description for GNU compiler,
- +;; Imagination Technologies Meta version.
- +;; Copyright (C) 2008
- +;; Imagination Technologies Ltd
- +
- +;; This file is part of GCC.
- +
- +;; GCC 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 3, or (at your option) any later
- +;; version.
- +
- +;; GCC 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 GCC; see the file COPYING3. If not see
- +;; <http://www.gnu.org/licenses/>.
- +
- +;; See comment at the top of dsppeephole.md for information about
- +;; dual unit DSP support in the metag backend.
- +
- +;; The metag_dsp_peephole2_xxxxxx_convert functions used in these
- +;; rules promote operands to V2SI mode. They are all structured such
- +;; that they can be used for both flag setting and non-flag setting
- +;; rules.
- +
- +;; DSP Math peephole2s
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_datareg_op" "")))
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 5 "metag_datareg_op" "")))]
- + "TARGET_DSP
- + && metag_dsp_rrr_operands (operands, <commutative>)"
- + [(set (match_dup 3)
- + (3OPREG:V2SI (match_dup 4)
- + (match_dup 5)))]
- + {
- + metag_dsp_peephole2_rrr_convert (operands);
- + })
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPIMM16:SI (match_dup 0)
- + (match_operand:SI 1 "metag_16bit_op" "")))
- + (set (match_operand:SI 2 "metag_datareg_op" "")
- + (3OPIMM16:SI (match_dup 2)
- + (match_dup 1)))]
- + "TARGET_DSP
- + && metag_dsp_ri16_operands (operands)
- + <dualunitimmcondition>"
- + [(set (match_dup 2)
- + (3OPIMM16:V2SI (match_dup 2)
- + (match_dup 3)))]
- + {
- + metag_dsp_peephole2_ri16_convert (operands);
- + })
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_5bit_op" "")))
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_dup 2)))]
- + "TARGET_DSP
- + && metag_dsp_rri5_operands (operands)
- + <dualunitimmcondition>"
- + [(set (match_dup 3)
- + (3OPIMM5:V2SI (match_dup 4)
- + (match_dup 5)))]
- + {
- + metag_dsp_peephole2_rri5_convert (operands);
- + })
- +
- +;; DSP MUL peephole
- +
- +;; MUL is not supported due to default DSP arithmetic mode being 16x16
- +
- +;; DSP MIN/MAX
- +
- +(define_peephole2
- + [(parallel
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (MINMAX:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])
- + (parallel
- + [(set (match_operand:SI 3 "metag_datareg_op" "")
- + (MINMAX:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 5 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rrr_operands (operands, true)"
- + [(parallel
- + [(set (match_dup 3)
- + (MINMAX:V2SI (match_dup 4)
- + (match_dup 5)))
- + (clobber (reg:CC CC_REG))])]
- + {
- + metag_dsp_peephole2_rrr_convert (operands);
- + })
- +
- +;; DSP ABS peephole
- +
- +(define_peephole2
- + [(parallel
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (abs:SI (match_operand:SI 1 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])
- + (parallel
- + [(set (match_operand:SI 2 "metag_datareg_op" "")
- + (abs:SI (match_operand:SI 3 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rr_operands (operands)"
- + [(parallel
- + [(set (match_dup 2)
- + (abs:V2SI (match_dup 3)))
- + (clobber (reg:CC CC_REG))])]
- + {
- + metag_dsp_peephole2_rr_convert (operands);
- + })
- +
- +;; DSP MOV peephole
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (match_operand:SI 1 "metag_datareg_op" ""))
- + (set (match_operand:SI 2 "metag_datareg_op" "")
- + (match_operand:SI 3 "metag_datareg_op" ""))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rr_operands (operands)"
- + [(set (match_dup 2)
- + (match_dup 3))]
- + {
- + metag_dsp_peephole2_rr_convert (operands);
- + })
- +
- +;; DSP Math with flags peepholes
- +
- +(define_peephole2
- + [(parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPREG:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_datareg_op" ""))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPREG:SI (match_dup 1)
- + (match_dup 2)))])
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 5 "metag_datareg_op" "")))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rrr_operands (operands, <commutative>)"
- + [(parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPREG:SI (match_dup 1)
- + (match_dup 2))
- + (const_int 0)))
- + (set (match_dup 3)
- + (3OPREG:V2SI (match_dup 4)
- + (match_dup 5)))])]
- + {
- + metag_dsp_peephole2_rrr_convert (operands);
- + })
- +
- +(define_peephole2
- + [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPREG:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_datareg_op" ""))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPREG:SI (match_dup 1)
- + (match_dup 2)))
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 5 "metag_datareg_op" "")))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rrr_operands (operands, <commutative>)"
- + [(parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPREG:SI (match_dup 1)
- + (match_dup 2))
- + (const_int 0)))
- + (set (match_dup 3)
- + (3OPREG:V2SI (match_dup 4)
- + (match_dup 5)))])]
- + {
- + metag_dsp_peephole2_rrr_convert (operands);
- + })
- +
- +(define_peephole2
- + [(parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM16:SI (match_operand:SI 0 "metag_datareg_op" "")
- + (match_operand:SI 1 "metag_16bit_op" ""))
- + (const_int 0)))
- + (set (match_dup 0)
- + (3OPIMM16:SI (match_dup 0)
- + (match_dup 1)))])
- + (set (match_operand:SI 2 "metag_datareg_op" "")
- + (3OPIMM16:SI (match_dup 2)
- + (match_dup 1)))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_ri16_operands (operands)
- + <dualunitimmcondition>"
- + [(parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM16:SI (match_dup 0)
- + (match_dup 1))
- + (const_int 0)))
- + (set (match_dup 2)
- + (3OPIMM16:V2SI (match_dup 2)
- + (match_dup 3)))])]
- + {
- + metag_dsp_peephole2_ri16_convert (operands);
- + })
- +
- +(define_peephole2
- + [(parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM5:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_5bit_op" ""))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_dup 1)
- + (match_dup 2)))])
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_dup 2)))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rri5_operands (operands)
- + <dualunitimmcondition>"
- + [(parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM5:SI (match_dup 1)
- + (match_dup 2))
- + (const_int 0)))
- + (set (match_dup 3)
- + (3OPIMM5:V2SI (match_dup 4)
- + (match_dup 5)))])]
- + {
- + metag_dsp_peephole2_rri5_convert (operands);
- + })
- +
- +(define_peephole2
- + [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM16:SI (match_operand:SI 0 "metag_datareg_op" "")
- + (match_operand:SI 1 "metag_16bit_op" ""))
- + (const_int 0)))
- + (set (match_dup 0)
- + (3OPIMM16:SI (match_dup 0)
- + (match_dup 1)))
- + (set (match_operand:SI 2 "metag_datareg_op" "")
- + (3OPIMM16:SI (match_dup 2)
- + (match_dup 1)))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_ri16_operands (operands)
- + <dualunitimmcondition>"
- + [(parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM16:SI (match_dup 0)
- + (match_dup 1))
- + (const_int 0)))
- + (set (match_dup 2)
- + (3OPIMM16:V2SI (match_dup 2)
- + (match_dup 3)))])]
- + {
- + metag_dsp_peephole2_ri16_convert (operands);
- + })
- +
- +(define_peephole2
- + [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM5:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_5bit_op" ""))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_dup 1)
- + (match_dup 2)))
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_dup 2)))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rri5_operands (operands)
- + <dualunitimmcondition>"
- + [(parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM5:SI (match_dup 1)
- + (match_dup 2))
- + (const_int 0)))
- + (set (match_dup 3)
- + (3OPIMM5:V2SI (match_dup 4)
- + (match_dup 5)))])]
- + {
- + metag_dsp_peephole2_rri5_convert (operands);
- + })
- +
- +;; DSP OP + MOV
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_datareg_op" "")))
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 5 "metag_datareg_op" "")))
- + (set (match_operand:SI 6 "metag_datareg_op" "")
- + (match_dup 0))
- + (set (match_operand:SI 7 "metag_datareg_op" "")
- + (match_dup 3))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rrr_mov_operands (operands, <commutative>)
- + && peep2_reg_dead_p (3, operands[0])
- + && peep2_reg_dead_p (4, operands[3])"
- + [(set (match_dup 6)
- + (3OPREG:V2SI (match_dup 1)
- + (match_dup 2)))]
- + {
- + metag_dsp_peephole2_rrr_mov_convert (operands);
- + })
- +
- +;; DSP MUL + MOV
- +
- +;; MUL is not supported due to default dsp arithmetic mode being 16x16
- +
- +;; DSP ABS + MOV
- +
- +(define_peephole2
- + [(parallel
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (abs:SI (match_operand:SI 1 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])
- + (set (match_operand:SI 4 "metag_datareg_op" "")
- + (match_dup 0))
- + (parallel
- + [(set (match_operand:SI 2 "metag_reg_nofloat_op" "")
- + (abs:SI (match_operand:SI 3 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])
- + (set (match_operand:SI 5 "metag_datareg_op" "")
- + (match_dup 2))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rr_rr_mov_operands (operands)
- + && peep2_reg_dead_p (2, operands[0])
- + && peep2_reg_dead_p (4, operands[2])"
- + [(parallel
- + [(set (match_dup 4)
- + (abs:SI (match_dup 1)))
- + (clobber (reg:CC CC_REG))])]
- + {
- + metag_dsp_peephole2_rr_mov_convert (operands);
- + })
- +
- +;; DSP MIN/MAX + MOV
- +
- +(define_peephole2
- + [(parallel
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (MINMAX:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])
- + (set (match_operand:SI 6 "metag_datareg_op" "")
- + (match_dup 0))
- + (parallel
- + [(set (match_operand:SI 3 "metag_datareg_op" "")
- + (MINMAX:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 5 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])
- + (set (match_operand:SI 7 "metag_datareg_op" "")
- + (match_dup 3))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rrr_mov_operands (operands, <commutative>)
- + && peep2_reg_dead_p (2, operands[0])
- + && peep2_reg_dead_p (4, operands[3])"
- + [(parallel
- + [(set (match_dup 6)
- + (MINMAX:SI (match_dup 1)
- + (match_dup 2)))
- + (clobber (reg:CC CC_REG))])]
- + {
- + metag_dsp_peephole2_rrr_mov_convert (operands);
- + })
- +
- +;; END DSP Peephole2s
- +
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/dsppeephole.md gcc-4.2.4/gcc/config/metag/dsppeephole.md
- --- gcc-4.2.4.orig/gcc/config/metag/dsppeephole.md 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/dsppeephole.md 2015-07-03 18:46:05.745283542 -0500
- @@ -0,0 +1,434 @@
- +;; Machine description for GNU compiler,
- +;; Imagination Technologies Meta version.
- +;; Copyright (C) 2008
- +;; Imagination Technologies Ltd
- +
- +;; This file is part of GCC.
- +
- +;; GCC 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 3, or (at your option) any later
- +;; version.
- +
- +;; GCC 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 GCC; see the file COPYING3. If not see
- +;; <http://www.gnu.org/licenses/>.
- +
- +;; READ THIS...
- +
- +;; DSP peephole transformations are mostly templated. There are 3 templates:
- +;; 1) 3OPREG - This is the set of operations that have 3 register operands
- +;; 2 input and 1 output.
- +;; 2) 3OPIMM16 - This is the set of operations that have 3 operands
- +;; 1 register input, 1 16 bit immediate input, 1 register output
- +;; 2) 3OPIMM5 - This is the set of operations that have 3 operands
- +;; 1 register input, 1 5 bit immediate input, 1 register output
- +
- +;; Special code attributes:
- +
- +;; <commutative>
- +;; Indicates if an insn code has commutative input operands.
- +;; <dualunitimmcondition>
- +;; Special immediate conditions for dual unit operations.
- +;; <expander>
- +;; The name of the insn suitable for use in rtl generation.
- +;; <MNEMONIC>
- +;; The assembler nmemonic for the given insn code.
- +
- +;; Dual unit conditions:
- +
- +;; The conditions for all DSP transformations are checked in the functions
- +;; called metag_dsp_xxxxxxx_operands. These functions check that the operands
- +;; in one instruction are an exact mirror of the operands of another
- +;; instruction.
- +;; For example metag_dsp_rrr_operands returns true for the following 2
- +;; instructions regardless of which order they appear (D1 or D0 first):
- +;;
- +;; (set (reg D0Re0 [D0.0])
- +;; (operation (reg D0Ar6 [D0.1])
- +;; (reg D0Ar4 (D0.2])))
- +;; (set (reg D1Re0 [D1.0])
- +;; (operation (reg D1Ar5 [D1.1])
- +;; (reg D1Ar3 (D1.2])))
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_datareg_op" "")))
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 5 "metag_datareg_op" "")))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rrr_operands (operands, <commutative>)"
- + "DL\\t<MNEMONIC>\\t%0, %1, %2\\t%@ (*<MNEMONIC>\\t%3, %4, %5)"
- + [(set_attr "type" "fast")])
- +
- +(define_peephole
- + [(set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 5 "metag_datareg_op" "")))
- + (set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_datareg_op" "")))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rrr_operands (operands, <commutative>)"
- + "DL\\t<MNEMONIC>\\t%3, %4, %5\\t%@ (*<MNEMONIC>\\t%0, %1, %2)"
- + [(set_attr "type" "fast")])
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPIMM16:SI (match_dup 0)
- + (match_operand:SI 1 "metag_16bit_op" "")))
- + (set (match_operand:SI 2 "metag_datareg_op" "")
- + (3OPIMM16:SI (match_dup 2)
- + (match_dup 1)))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_ri16_operands (operands)
- + <dualunitimmcondition>"
- + "DL\\t<MNEMONIC>\\t%0, %0, %1\\t%@ (*<MNEMONIC>\\t%2, %2, %1)"
- + [(set_attr "type" "fast")])
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_5bit_op" "")))
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_dup 2)))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rri5_operands (operands)
- + <dualunitimmcondition>"
- + "DL\\t<MNEMONIC>\\t%0, %1, %2\\t%@ (*<MNEMONIC>\\t%3, %4, %2)"
- + [(set_attr "type" "fast")])
- +
- +;; DSP MIN/MAX
- +
- +(define_peephole
- + [(parallel
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (MINMAX:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])
- + (parallel
- + [(set (match_operand:SI 3 "metag_datareg_op" "")
- + (MINMAX:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 5 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rrr_operands (operands, true)"
- + "DL\\t<MNEMONIC>\\t%0, %1, %2\\t%@ (*<MNEMONIC>\\t%3, %4, %5)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "ccx")])
- +
- +;; DSP ABS peephole
- +
- +(define_peephole
- + [(parallel
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (abs:SI (match_operand:SI 1 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])
- + (parallel
- + [(set (match_operand:SI 2 "metag_datareg_op" "")
- + (abs:SI (match_operand:SI 3 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rr_operands (operands)"
- + "DL\\tABS\\t%0, %1\\t%@ *ABS\\t%2, %3)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "ccx")])
- +
- +;; DSP MOV peephole
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (match_operand:SI 1 "metag_datareg_op" ""))
- + (set (match_operand:SI 2 "metag_datareg_op" "")
- + (match_operand:SI 3 "metag_datareg_op" ""))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rr_operands (operands)"
- + "DL\\tMOV\\t%0, %1\\t%@ (*MOV\\t%2, %3)"
- + [(set_attr "type" "fast")])
- +
- +;; DSP Math with flags peepholes
- +
- +(define_peephole
- + [(parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPREG:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_datareg_op" ""))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPREG:SI (match_dup 1)
- + (match_dup 2)))])
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 5 "metag_datareg_op" "")))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rrr_operands (operands, <commutative>)"
- + "DL\\t<MNEMONIC>S\\t%0, %1, %2\\t%@ (*<MNEMONIC>S\\t%3, %4, %5)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_peephole
- + [(set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 5 "metag_datareg_op" "")))
- + (parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPREG:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_datareg_op" ""))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPREG:SI (match_dup 1)
- + (match_dup 2)))])]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rrr_operands (operands, <commutative>)"
- + "DL\\t<MNEMONIC>S\\t%0, %1, %2\\t%@ (*<MNEMONIC>S\\t%3, %4, %5)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_peephole
- + [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPREG:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 5 "metag_datareg_op" ""))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_datareg_op" "")))
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPREG:SI (match_dup 4)
- + (match_dup 5)))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rrr_operands (operands, <commutative>)"
- + "DL\\t<MNEMONIC>S\\t%3, %4, %5\\t%@ (*<MNEMONIC>S\\t%0, %1, %2)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_peephole
- + [(parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM16:SI (match_operand:SI 0 "metag_datareg_op" "")
- + (match_operand:SI 1 "metag_16bit_op" ""))
- + (const_int 0)))
- + (set (match_dup 0)
- + (3OPIMM16:SI (match_dup 0)
- + (match_dup 1)))])
- + (set (match_operand:SI 2 "metag_datareg_op" "")
- + (3OPIMM16:SI (match_dup 2)
- + (match_dup 1)))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_ri16_operands (operands)
- + <dualunitimmcondition>"
- + "DL\\t<MNEMONIC>S\\t%0, %0, %1\\t%@ (*<MNEMONIC>S\\t%2, %2, %1)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_peephole
- + [(parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM5:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_5bit_op" ""))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_dup 1)
- + (match_dup 2)))])
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_dup 2)))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rri5_operands (operands)
- + <dualunitimmcondition>"
- + "DL\\t<MNEMONIC>S\\t%0, %1, %2\\t%@ (*<MNEMONIC>S\\t%3, %4, %2)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_peephole
- + [(set (match_operand:SI 2 "metag_datareg_op" "")
- + (3OPIMM16:SI (match_dup 2)
- + (match_operand:SI 1 "metag_16bit_op" "")))
- + (parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM16:SI (match_operand:SI 0 "metag_datareg_op" "")
- + (match_dup 1))
- + (const_int 0)))
- + (set (match_dup 0)
- + (3OPIMM16:SI (match_dup 0)
- + (match_dup 1)))])]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_ri16_operands (operands)
- + <dualunitimmcondition>"
- + "DL\\t<MNEMONIC>S\\t%0, %0, %1\\t%@ (*<MNEMONIC>S\\t%2, %2, %1)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_peephole
- + [(set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_5bit_op" "")))
- + (parallel [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM5:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_dup 2))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_dup 1)
- + (match_dup 2)))])]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rri5_operands (operands)
- + <dualunitimmcondition>"
- + "DL\\t<MNEMONIC>S\\t%0, %1, %2\\t%@ (*<MNEMONIC>S\\t%3, %4, %2)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_peephole
- + [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM16:SI (match_operand:SI 2 "metag_datareg_op" "")
- + (match_operand:SI 1 "metag_16bit_op" ""))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPIMM16:SI (match_dup 0)
- + (match_dup 1)))
- + (set (match_dup 2)
- + (3OPIMM16:SI (match_dup 2)
- + (match_dup 1)))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_ri16_operands (operands)
- + <dualunitimmcondition>"
- + "DL\\t<MNEMONIC>S\\t%2, %2, %1\\t%@ (*<MNEMONIC>S\\t%0, %0, %1)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_peephole
- + [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM5:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_5bit_op" ""))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_dup 2)))
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_dup 4)
- + (match_dup 2)))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rri5_operands (operands)
- + <dualunitimmcondition>"
- + "DL\\t<MNEMONIC>S\\t%3, %4, %2\\t%@ (*<MNEMONIC>S\\t%0, %1, %2)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_peephole
- + [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM16:SI (match_operand:SI 2 "metag_datareg_op" "")
- + (match_operand:SI 1 "metag_16bit_op" ""))
- + (const_int 0)))
- + (set (match_dup 2)
- + (3OPIMM16:SI (match_dup 2)
- + (match_dup 1)))
- + (set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPIMM16:SI (match_dup 0)
- + (match_dup 1)))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_ri16_operands (operands)
- + <dualunitimmcondition>"
- + "DL\\t<MNEMONIC>S\\t%2, %2, %1\\t%@ (*<MNEMONIC>S\\t%0, %0, %1)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_peephole
- + [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM5:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_5bit_op" ""))
- + (const_int 0)))
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_dup 4)
- + (match_dup 2)))
- + (set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPIMM5:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_dup 2)))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rri5_operands (operands)
- + <dualunitimmcondition>"
- + "DL\\t<MNEMONIC>S\\t%3, %4, %2\\t%@ (*<MNEMONIC>S\\t%0, %1, %2)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +;; DSP OP + MOV
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_datareg_op" "")))
- + (set (match_operand:SI 3 "metag_datareg_op" "")
- + (3OPREG:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 5 "metag_datareg_op" "")))
- + (set (match_operand:SI 6 "metag_datareg_op" "")
- + (match_dup 0))
- + (set (match_operand:SI 7 "metag_datareg_op" "")
- + (match_dup 3))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rrr_mov_operands (operands, <commutative>)
- + && dead_or_set_p (PREV_INSN (insn), operands[0])
- + && dead_or_set_p (insn, operands[3])"
- + "DL\\t<MNEMONIC>\\t%6, %1, %2\\t%@ (*<MNEMONIC>\\t%7, %4, %5)"
- + [(set_attr "type" "fast")])
- +
- +;; DSP ABS + MOV
- +
- +(define_peephole
- + [(parallel
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (abs:SI (match_operand:SI 1 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])
- + (set (match_operand:SI 4 "metag_datareg_op" "")
- + (match_dup 0))
- + (parallel
- + [(set (match_operand:SI 2 "metag_reg_nofloat_op" "")
- + (abs:SI (match_operand:SI 3 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])
- + (set (match_operand:SI 5 "metag_datareg_op" "")
- + (match_dup 2))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rr_rr_mov_operands (operands)
- + && dead_or_set_p (PREV_INSN (PREV_INSN (insn)), operands[0])
- + && dead_or_set_p (insn, operands[2])"
- + "DL\\tABS\\t%4, %1\\t%@ (*ABS\\t%5, %2)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "ccx")])
- +
- +;; DSP MIN/MAX + MOV
- +
- +(define_peephole
- + [(parallel
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (MINMAX:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])
- + (set (match_operand:SI 6 "metag_datareg_op" "")
- + (match_dup 0))
- + (parallel
- + [(set (match_operand:SI 3 "metag_datareg_op" "")
- + (MINMAX:SI (match_operand:SI 4 "metag_datareg_op" "")
- + (match_operand:SI 5 "metag_datareg_op" "")))
- + (clobber (reg:CC CC_REG))])
- + (set (match_operand:SI 7 "metag_datareg_op" "")
- + (match_dup 3))]
- + "TARGET_DSP && !metag_cond_exec_p ()
- + && metag_dsp_rrr_mov_operands (operands, <commutative>)
- + && dead_or_set_p (PREV_INSN (PREV_INSN (insn)), operands[0])
- + && dead_or_set_p (insn, operands[3])"
- + "DL\\t<MNEMONIC>\\t%6, %1, %2\\t%@ (*<MNEMONIC>\\r%7, %4, %5)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "ccx")])
- +
- +;; END DSP Peepholes
- +
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/elf.h gcc-4.2.4/gcc/config/metag/elf.h
- --- gcc-4.2.4.orig/gcc/config/metag/elf.h 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/elf.h 2015-07-03 18:46:05.745283542 -0500
- @@ -0,0 +1,84 @@
- +/* Definitions of target machine for GNU compiler,
- + for Meta Linux-based GNU systems.
- + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
- + Free Software Foundation, Inc.
- + Contributed by Imagination Technologies Ltd (toolkit@metagence.com)
- +
- +This file is part of GCC.
- +
- +GCC 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 3, or (at your option) any later
- +version.
- +
- +GCC 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 GCC; see the file COPYING3. If not see
- +<http://www.gnu.org/licenses/>. */
- +
- +#ifndef OBJECT_FORMAT_ELF
- +#error elf.h included before elfos.h
- +#endif
- +
- +#undef BSS_SECTION_ASM_OP
- +
- +/* Dots in labels are not allowed. */
- +
- +#define NO_DOT_IN_LABEL 1
- +
- +#define ASM_PN_FORMAT "%s___%lu"
- +
- +#undef DBX_DEBUGGING_INFO
- +
- +#undef PREFERRED_DEBUGGING_TYPE
- +#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
- +
- +#undef ASM_FINAL_SPEC
- +
- +#ifdef MINIM_DEFAULT
- +#define DEFAULT_MINIM_LINK_SPEC "%{!mno-minim:%{mmetac=2.1:--minim}} "
- +#else
- +#define DEFAULT_MINIM_LINK_SPEC
- +#endif
- +
- +#ifdef METAG_LINK_GLOBAL
- +#define LINK_MACHINE_TYPE "-m elf32metag_global "
- +#else
- +#define LINK_MACHINE_TYPE "-m elf32metag "
- +#endif
- +
- +#undef LINK_SPEC
- +#define LINK_SPEC \
- + LINK_MACHINE_TYPE \
- + "%{shared:-shared} " \
- + "-init=__init -fini=__fini " \
- + "%{mminim:%{mmetac=2.1:--minim}%{!mmetac=2.1:%eMiniM mode is only available on a META 2.1}} "\
- + DEFAULT_MINIM_LINK_SPEC \
- + "%{!shared: " \
- + "%{!static: " \
- + "%{rdynamic:-export-dynamic} " \
- + "%{!dynamic-linker:-dynamic-linker %(elf_dynamic_linker)}} " \
- + "%{static:-static}} "
- +
- +#ifndef ASM_COMMENT_START
- +#define ASM_COMMENT_START "!"
- +#endif
- +
- +#define ASM_IDENTIFY_LANGUAGE(FILE) \
- + fprintf (FILE, "%s \"GCC (%s) %s\"\n", IDENT_ASM_OP, \
- + lang_identify (), version_string)
- +
- +
- +#undef ASM_OUTPUT_CASE_LABEL
- +
- +/* For PIC code we need to explicitly specify (PLT) and (GOT) relocs. */
- +#define NEED_PLT_RELOC flag_pic
- +#define NEED_GOT_RELOC flag_pic
- +
- +#ifndef SUBTARGET_CPP_SPEC
- +#define SUBTARGET_CPP_SPEC "-D__ELF__"
- +#endif
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/fp-hard-bit.c gcc-4.2.4/gcc/config/metag/fp-hard-bit.c
- --- gcc-4.2.4.orig/gcc/config/metag/fp-hard-bit.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/fp-hard-bit.c 2015-07-03 18:46:05.745283542 -0500
- @@ -0,0 +1,1756 @@
- +/* This is a software floating point library which can be used
- + for targets without hardware floating point.
- + Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003,
- + 2004, 2005, 2009 Free Software Foundation, Inc.
- +
- +This file is part of GCC.
- +
- +GCC 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 3, or (at your option) any later
- +version.
- +
- +GCC 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.
- +
- +Under Section 7 of GPL version 3, you are granted additional
- +permissions described in the GCC Runtime Library Exception, version
- +3.1, as published by the Free Software Foundation.
- +
- +You should have received a copy of the GNU General Public License and
- +a copy of the GCC Runtime Library Exception along with this program;
- +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
- +<http://www.gnu.org/licenses/>. */
- +
- +/* This implements IEEE 754 format arithmetic, but does not provide a
- + mechanism for setting the rounding mode, or for generating or handling
- + exceptions.
- +
- + The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
- + Wilson, all of Cygnus Support. */
- +
- +/* The intended way to use this file is to make two copies, add `#define FLOAT'
- + to one copy, then compile both copies and add them to libgcc.a. */
- +
- +#include "tconfig.h"
- +#include "coretypes.h"
- +#include "tm.h"
- +#include "config/fp-bit.h"
- +
- +/* The following macros can be defined to change the behavior of this file:
- + FLOAT: Implement a `float', aka SFmode, fp library. If this is not
- + defined, then this file implements a `double', aka DFmode, fp library.
- + FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
- + don't include float->double conversion which requires the double library.
- + This is useful only for machines which can't support doubles, e.g. some
- + 8-bit processors.
- + CMPtype: Specify the type that floating point compares should return.
- + This defaults to SItype, aka int.
- + US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
- + US Software goFast library.
- + _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
- + two integers to the FLO_union_type.
- + NO_DENORMALS: Disable handling of denormals.
- + NO_NANS: Disable nan and infinity handling
- + SMALL_MACHINE: Useful when operations on QIs and HIs are faster
- + than on an SI */
- +
- +/* We don't currently support extended floats (long doubles) on machines
- + without hardware to deal with them.
- +
- + These stubs are just to keep the linker from complaining about unresolved
- + references which can be pulled in from libio & libstdc++, even if the
- + user isn't using long doubles. However, they may generate an unresolved
- + external to abort if abort is not used by the function, and the stubs
- + are referenced from within libc, since libgcc goes before and after the
- + system library. */
- +
- +#ifdef DECLARE_LIBRARY_RENAMES
- + DECLARE_LIBRARY_RENAMES
- +#endif
- +
- +#ifdef EXTENDED_FLOAT_STUBS
- +extern void abort (void);
- +void __extendsfxf2 (void) { abort(); }
- +void __extenddfxf2 (void) { abort(); }
- +void __truncxfdf2 (void) { abort(); }
- +void __truncxfsf2 (void) { abort(); }
- +void __fixxfsi (void) { abort(); }
- +void __floatsixf (void) { abort(); }
- +void __addxf3 (void) { abort(); }
- +void __subxf3 (void) { abort(); }
- +void __mulxf3 (void) { abort(); }
- +void __divxf3 (void) { abort(); }
- +void __negxf2 (void) { abort(); }
- +void __eqxf2 (void) { abort(); }
- +void __nexf2 (void) { abort(); }
- +void __gtxf2 (void) { abort(); }
- +void __gexf2 (void) { abort(); }
- +void __lexf2 (void) { abort(); }
- +void __ltxf2 (void) { abort(); }
- +
- +void __extendsftf2 (void) { abort(); }
- +void __extenddftf2 (void) { abort(); }
- +void __trunctfdf2 (void) { abort(); }
- +void __trunctfsf2 (void) { abort(); }
- +void __fixtfsi (void) { abort(); }
- +void __floatsitf (void) { abort(); }
- +void __addtf3 (void) { abort(); }
- +void __subtf3 (void) { abort(); }
- +void __multf3 (void) { abort(); }
- +void __divtf3 (void) { abort(); }
- +void __negtf2 (void) { abort(); }
- +void __eqtf2 (void) { abort(); }
- +void __netf2 (void) { abort(); }
- +void __gttf2 (void) { abort(); }
- +void __getf2 (void) { abort(); }
- +void __letf2 (void) { abort(); }
- +void __lttf2 (void) { abort(); }
- +#else /* !EXTENDED_FLOAT_STUBS, rest of file */
- +
- +/* IEEE "special" number predicates */
- +
- +#ifdef NO_NANS
- +
- +#define nan() 0
- +#define isnan(x) 0
- +#define isinf(x) 0
- +#else
- +
- +#if defined L_thenan_sf
- +const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
- +#elif defined L_thenan_df
- +const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
- +#elif defined L_thenan_tf
- +const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
- +#elif defined TFLOAT
- +extern const fp_number_type __thenan_tf;
- +#elif defined FLOAT
- +extern const fp_number_type __thenan_sf;
- +#else
- +extern const fp_number_type __thenan_df;
- +#endif
- +
- +INLINE
- +static fp_number_type *
- +nan (void)
- +{
- + /* Discard the const qualifier... */
- +#ifdef TFLOAT
- + return (fp_number_type *) (& __thenan_tf);
- +#elif defined FLOAT
- + return (fp_number_type *) (& __thenan_sf);
- +#else
- + return (fp_number_type *) (& __thenan_df);
- +#endif
- +}
- +
- +INLINE
- +static int
- +isnan ( fp_number_type * x)
- +{
- + return __builtin_expect (x->class == CLASS_SNAN || x->class == CLASS_QNAN,
- + 0);
- +}
- +
- +INLINE
- +static int
- +isinf ( fp_number_type * x)
- +{
- + return __builtin_expect (x->class == CLASS_INFINITY, 0);
- +}
- +
- +#endif /* NO_NANS */
- +
- +INLINE
- +static int
- +iszero ( fp_number_type * x)
- +{
- + return x->class == CLASS_ZERO;
- +}
- +
- +INLINE
- +static void
- +flip_sign ( fp_number_type * x)
- +{
- + x->sign = !x->sign;
- +}
- +
- +/* Count leading zeroes in N. */
- +INLINE
- +static int
- +clzusi (USItype n)
- +{
- + extern int __clzsi2 (USItype);
- + if (sizeof (USItype) == sizeof (unsigned int))
- + return __builtin_clz (n);
- + else if (sizeof (USItype) == sizeof (unsigned long))
- + return __builtin_clzl (n);
- + else if (sizeof (USItype) == sizeof (unsigned long long))
- + return __builtin_clzll (n);
- + else
- + return __clzsi2 (n);
- +}
- +
- +extern FLO_type pack_d ( fp_number_type * );
- +
- +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
- +FLO_type
- +pack_d ( fp_number_type * src)
- +{
- + FLO_union_type dst;
- + fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
- + int sign = src->sign;
- + int exp = 0;
- +
- + if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
- + {
- + /* We can't represent these values accurately. By using the
- + largest possible magnitude, we guarantee that the conversion
- + of infinity is at least as big as any finite number. */
- + exp = EXPMAX;
- + fraction = ((fractype) 1 << FRACBITS) - 1;
- + }
- + else if (isnan (src))
- + {
- + exp = EXPMAX;
- + if (src->class == CLASS_QNAN || 1)
- + {
- +#ifdef QUIET_NAN_NEGATED
- + fraction |= QUIET_NAN - 1;
- +#else
- + fraction |= QUIET_NAN;
- +#endif
- + }
- + }
- + else if (isinf (src))
- + {
- + exp = EXPMAX;
- + fraction = 0;
- + }
- + else if (iszero (src))
- + {
- + exp = 0;
- + fraction = 0;
- + }
- + else if (fraction == 0)
- + {
- + exp = 0;
- + }
- + else
- + {
- + if (__builtin_expect (src->normal_exp < NORMAL_EXPMIN, 0))
- + {
- +#ifdef NO_DENORMALS
- + /* Go straight to a zero representation if denormals are not
- + supported. The denormal handling would be harmless but
- + isn't unnecessary. */
- + exp = 0;
- + fraction = 0;
- +#else /* NO_DENORMALS */
- + /* This number's exponent is too low to fit into the bits
- + available in the number, so we'll store 0 in the exponent and
- + shift the fraction to the right to make up for it. */
- +
- + int shift = NORMAL_EXPMIN - src->normal_exp;
- +
- + exp = 0;
- +
- + if (shift > FRAC_NBITS - NGARDS)
- + {
- + /* No point shifting, since it's more that 64 out. */
- + fraction = 0;
- + }
- + else
- + {
- + int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
- + fraction = (fraction >> shift) | lowbit;
- + }
- + if ((fraction & GARDMASK) == GARDMSB)
- + {
- + if ((fraction & (1 << NGARDS)))
- + fraction += GARDROUND + 1;
- + }
- + else
- + {
- + /* Add to the guards to round up. */
- + fraction += GARDROUND;
- + }
- + /* Perhaps the rounding means we now need to change the
- + exponent, because the fraction is no longer denormal. */
- + if (fraction >= IMPLICIT_1)
- + {
- + exp += 1;
- + }
- + fraction >>= NGARDS;
- +#endif /* NO_DENORMALS */
- + }
- + else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
- + && __builtin_expect (src->normal_exp > EXPBIAS, 0))
- + {
- + exp = EXPMAX;
- + fraction = 0;
- + }
- + else
- + {
- + exp = src->normal_exp + EXPBIAS;
- + if (!ROUND_TOWARDS_ZERO)
- + {
- + /* IF the gard bits are the all zero, but the first, then we're
- + half way between two numbers, choose the one which makes the
- + lsb of the answer 0. */
- + if ((fraction & GARDMASK) == GARDMSB)
- + {
- + if (fraction & (1 << NGARDS))
- + fraction += GARDROUND + 1;
- + }
- + else
- + {
- + /* Add a one to the guards to round up */
- + fraction += GARDROUND;
- + }
- + if (fraction >= IMPLICIT_2)
- + {
- + fraction >>= 1;
- + exp += 1;
- + }
- + }
- + fraction >>= NGARDS;
- +
- + if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
- + {
- + /* Saturate on overflow. */
- + exp = EXPMAX;
- + fraction = ((fractype) 1 << FRACBITS) - 1;
- + }
- + }
- + }
- +
- + /* We previously used bitfields to store the number, but this doesn't
- + handle little/big endian systems conveniently, so use shifts and
- + masks */
- +#ifdef FLOAT_BIT_ORDER_MISMATCH
- + dst.bits.fraction = fraction;
- + dst.bits.exp = exp;
- + dst.bits.sign = sign;
- +#else
- +# if defined TFLOAT && defined HALFFRACBITS
- + {
- + halffractype high, low, unity;
- + int lowsign, lowexp;
- +
- + unity = (halffractype) 1 << HALFFRACBITS;
- +
- + /* Set HIGH to the high double's significand, masking out the implicit 1.
- + Set LOW to the low double's full significand. */
- + high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
- + low = fraction & (unity * 2 - 1);
- +
- + /* Get the initial sign and exponent of the low double. */
- + lowexp = exp - HALFFRACBITS - 1;
- + lowsign = sign;
- +
- + /* HIGH should be rounded like a normal double, making |LOW| <=
- + 0.5 ULP of HIGH. Assume round-to-nearest. */
- + if (exp < EXPMAX)
- + if (low > unity || (low == unity && (high & 1) == 1))
- + {
- + /* Round HIGH up and adjust LOW to match. */
- + high++;
- + if (high == unity)
- + {
- + /* May make it infinite, but that's OK. */
- + high = 0;
- + exp++;
- + }
- + low = unity * 2 - low;
- + lowsign ^= 1;
- + }
- +
- + high |= (halffractype) exp << HALFFRACBITS;
- + high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
- +
- + if (exp == EXPMAX || exp == 0 || low == 0)
- + low = 0;
- + else
- + {
- + while (lowexp > 0 && low < unity)
- + {
- + low <<= 1;
- + lowexp--;
- + }
- +
- + if (lowexp <= 0)
- + {
- + halffractype roundmsb, round;
- + int shift;
- +
- + shift = 1 - lowexp;
- + roundmsb = (1 << (shift - 1));
- + round = low & ((roundmsb << 1) - 1);
- +
- + low >>= shift;
- + lowexp = 0;
- +
- + if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
- + {
- + low++;
- + if (low == unity)
- + /* LOW rounds up to the smallest normal number. */
- + lowexp++;
- + }
- + }
- +
- + low &= unity - 1;
- + low |= (halffractype) lowexp << HALFFRACBITS;
- + low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
- + }
- + dst.value_raw = ((fractype) high << HALFSHIFT) | low;
- + }
- +# else
- + dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
- + dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
- + dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
- +# endif
- +#endif
- +
- +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
- +#ifdef TFLOAT
- + {
- + qrtrfractype tmp1 = dst.words[0];
- + qrtrfractype tmp2 = dst.words[1];
- + dst.words[0] = dst.words[3];
- + dst.words[1] = dst.words[2];
- + dst.words[2] = tmp2;
- + dst.words[3] = tmp1;
- + }
- +#else
- + {
- + halffractype tmp = dst.words[0];
- + dst.words[0] = dst.words[1];
- + dst.words[1] = tmp;
- + }
- +#endif
- +#endif
- +
- + return dst.value;
- +}
- +#endif
- +
- +#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
- +void
- +unpack_d (FLO_union_type * src, fp_number_type * dst)
- +{
- + /* We previously used bitfields to store the number, but this doesn't
- + handle little/big endian systems conveniently, so use shifts and
- + masks */
- + fractype fraction;
- + int exp;
- + int sign;
- +
- +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
- + FLO_union_type swapped;
- +
- +#ifdef TFLOAT
- + swapped.words[0] = src->words[3];
- + swapped.words[1] = src->words[2];
- + swapped.words[2] = src->words[1];
- + swapped.words[3] = src->words[0];
- +#else
- + swapped.words[0] = src->words[1];
- + swapped.words[1] = src->words[0];
- +#endif
- + src = &swapped;
- +#endif
- +
- +#ifdef FLOAT_BIT_ORDER_MISMATCH
- + fraction = src->bits.fraction;
- + exp = src->bits.exp;
- + sign = src->bits.sign;
- +#else
- +# if defined TFLOAT && defined HALFFRACBITS
- + {
- + halffractype high, low;
- +
- + high = src->value_raw >> HALFSHIFT;
- + low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
- +
- + fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
- + fraction <<= FRACBITS - HALFFRACBITS;
- + exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
- + sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
- +
- + if (exp != EXPMAX && exp != 0 && low != 0)
- + {
- + int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
- + int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
- + int shift;
- + fractype xlow;
- +
- + xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
- + if (lowexp)
- + xlow |= (((halffractype)1) << HALFFRACBITS);
- + else
- + lowexp = 1;
- + shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
- + if (shift > 0)
- + xlow <<= shift;
- + else if (shift < 0)
- + xlow >>= -shift;
- + if (sign == lowsign)
- + fraction += xlow;
- + else if (fraction >= xlow)
- + fraction -= xlow;
- + else
- + {
- + /* The high part is a power of two but the full number is lower.
- + This code will leave the implicit 1 in FRACTION, but we'd
- + have added that below anyway. */
- + fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
- + exp--;
- + }
- + }
- + }
- +# else
- + fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
- + exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
- + sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
- +# endif
- +#endif
- +
- + dst->sign = sign;
- + if (exp == 0)
- + {
- + /* Hmm. Looks like 0 */
- + if (fraction == 0
- +#ifdef NO_DENORMALS
- + || 1
- +#endif
- + )
- + {
- + /* tastes like zero */
- + dst->class = CLASS_ZERO;
- + }
- + else
- + {
- + /* Zero exponent with nonzero fraction - it's denormalized,
- + so there isn't a leading implicit one - we'll shift it so
- + it gets one. */
- + dst->normal_exp = exp - EXPBIAS + 1;
- + fraction <<= NGARDS;
- +
- + dst->class = CLASS_NUMBER;
- +#if 1
- + while (fraction < IMPLICIT_1)
- + {
- + fraction <<= 1;
- + dst->normal_exp--;
- + }
- +#endif
- + dst->fraction.ll = fraction;
- + }
- + }
- + else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
- + && __builtin_expect (exp == EXPMAX, 0))
- + {
- + /* Huge exponent*/
- + if (fraction == 0)
- + {
- + /* Attached to a zero fraction - means infinity */
- + dst->class = CLASS_INFINITY;
- + }
- + else
- + {
- + /* Nonzero fraction, means nan */
- +#ifdef QUIET_NAN_NEGATED
- + if ((fraction & QUIET_NAN) == 0)
- +#else
- + if (fraction & QUIET_NAN)
- +#endif
- + {
- + dst->class = CLASS_QNAN;
- + }
- + else
- + {
- + dst->class = CLASS_SNAN;
- + }
- + /* Keep the fraction part as the nan number */
- + dst->fraction.ll = fraction;
- + }
- + }
- + else
- + {
- + /* Nothing strange about this number */
- + dst->normal_exp = exp - EXPBIAS;
- + dst->class = CLASS_NUMBER;
- + dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
- + }
- +}
- +#endif /* L_unpack_df || L_unpack_sf */
- +
- +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
- +static fp_number_type *
- +_fpadd_parts (fp_number_type * a,
- + fp_number_type * b,
- + fp_number_type * tmp)
- +{
- + intfrac tfraction;
- +
- + /* Put commonly used fields in local variables. */
- + int a_normal_exp;
- + int b_normal_exp;
- + fractype a_fraction;
- + fractype b_fraction;
- +
- + if (isnan (a))
- + {
- + return a;
- + }
- + if (isnan (b))
- + {
- + return b;
- + }
- + if (isinf (a))
- + {
- + /* Adding infinities with opposite signs yields a NaN. */
- + if (isinf (b) && a->sign != b->sign)
- + return nan ();
- + return a;
- + }
- + if (isinf (b))
- + {
- + return b;
- + }
- + if (iszero (b))
- + {
- + if (iszero (a))
- + {
- + *tmp = *a;
- + tmp->sign = a->sign & b->sign;
- + return tmp;
- + }
- + return a;
- + }
- + if (iszero (a))
- + {
- + return b;
- + }
- +
- + /* Got two numbers. shift the smaller and increment the exponent till
- + they're the same */
- + {
- + int diff;
- + int sdiff;
- +
- + a_normal_exp = a->normal_exp;
- + b_normal_exp = b->normal_exp;
- + a_fraction = a->fraction.ll;
- + b_fraction = b->fraction.ll;
- +
- + diff = a_normal_exp - b_normal_exp;
- + sdiff = diff;
- +
- + if (diff < 0)
- + diff = -diff;
- + if (diff < FRAC_NBITS)
- + {
- + if (sdiff > 0)
- + {
- + b_normal_exp += diff;
- + LSHIFT (b_fraction, diff);
- + }
- + else if (sdiff < 0)
- + {
- + a_normal_exp += diff;
- + LSHIFT (a_fraction, diff);
- + }
- + }
- + else
- + {
- + /* Somethings's up.. choose the biggest */
- + if (a_normal_exp > b_normal_exp)
- + {
- + b_normal_exp = a_normal_exp;
- + b_fraction = 0;
- + }
- + else
- + {
- + a_normal_exp = b_normal_exp;
- + a_fraction = 0;
- + }
- + }
- + }
- +
- + if (a->sign != b->sign)
- + {
- + if (a->sign)
- + {
- + tfraction = -a_fraction + b_fraction;
- + }
- + else
- + {
- + tfraction = a_fraction - b_fraction;
- + }
- + if (tfraction >= 0)
- + {
- + tmp->sign = 0;
- + tmp->normal_exp = a_normal_exp;
- + tmp->fraction.ll = tfraction;
- + }
- + else
- + {
- + tmp->sign = 1;
- + tmp->normal_exp = a_normal_exp;
- + tmp->fraction.ll = -tfraction;
- + }
- + /* and renormalize it */
- +
- + while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
- + {
- + tmp->fraction.ll <<= 1;
- + tmp->normal_exp--;
- + }
- + }
- + else
- + {
- + tmp->sign = a->sign;
- + tmp->normal_exp = a_normal_exp;
- + tmp->fraction.ll = a_fraction + b_fraction;
- + }
- + tmp->class = CLASS_NUMBER;
- + /* Now the fraction is added, we have to shift down to renormalize the
- + number */
- +
- + if (tmp->fraction.ll >= IMPLICIT_2)
- + {
- + LSHIFT (tmp->fraction.ll, 1);
- + tmp->normal_exp++;
- + }
- + return tmp;
- +
- +}
- +
- +FLO_type
- +add (FLO_type arg_a, FLO_type arg_b)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type a;
- + fp_number_type b;
- + fp_number_type tmp;
- + fp_number_type *res;
- + FLO_union_type au, bu;
- +
- + au.value = arg_a;
- + bu.value = arg_b;
- +
- + unpack_d (&au, &a);
- + unpack_d (&bu, &b);
- +
- + res = _fpadd_parts (&a, &b, &tmp);
- +
- + return pack_d (res);
- +#else
- + return arg_a + arg_b;
- +#endif
- +}
- +
- +FLO_type
- +sub (FLO_type arg_a, FLO_type arg_b)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type a;
- + fp_number_type b;
- + fp_number_type tmp;
- + fp_number_type *res;
- + FLO_union_type au, bu;
- +
- + au.value = arg_a;
- + bu.value = arg_b;
- +
- + unpack_d (&au, &a);
- + unpack_d (&bu, &b);
- +
- + b.sign ^= 1;
- +
- + res = _fpadd_parts (&a, &b, &tmp);
- +
- + return pack_d (res);
- +#else
- + return arg_a - arg_b;
- +#endif
- +}
- +#endif /* L_addsub_sf || L_addsub_df */
- +
- +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
- +static inline __attribute__ ((__always_inline__)) fp_number_type *
- +_fpmul_parts ( fp_number_type * a,
- + fp_number_type * b,
- + fp_number_type * tmp)
- +{
- + fractype low = 0;
- + fractype high = 0;
- +
- + if (isnan (a))
- + {
- + a->sign = a->sign != b->sign;
- + return a;
- + }
- + if (isnan (b))
- + {
- + b->sign = a->sign != b->sign;
- + return b;
- + }
- + if (isinf (a))
- + {
- + if (iszero (b))
- + return nan ();
- + a->sign = a->sign != b->sign;
- + return a;
- + }
- + if (isinf (b))
- + {
- + if (iszero (a))
- + {
- + return nan ();
- + }
- + b->sign = a->sign != b->sign;
- + return b;
- + }
- + if (iszero (a))
- + {
- + a->sign = a->sign != b->sign;
- + return a;
- + }
- + if (iszero (b))
- + {
- + b->sign = a->sign != b->sign;
- + return b;
- + }
- +
- + /* Calculate the mantissa by multiplying both numbers to get a
- + twice-as-wide number. */
- + {
- +#if defined(NO_DI_MODE) || defined(TFLOAT)
- + {
- + fractype x = a->fraction.ll;
- + fractype ylow = b->fraction.ll;
- + fractype yhigh = 0;
- + int bit;
- +
- + /* ??? This does multiplies one bit at a time. Optimize. */
- + for (bit = 0; bit < FRAC_NBITS; bit++)
- + {
- + int carry;
- +
- + if (x & 1)
- + {
- + carry = (low += ylow) < ylow;
- + high += yhigh + carry;
- + }
- + yhigh <<= 1;
- + if (ylow & FRACHIGH)
- + {
- + yhigh |= 1;
- + }
- + ylow <<= 1;
- + x >>= 1;
- + }
- + }
- +#elif defined(FLOAT)
- + /* Multiplying two USIs to get a UDI, we're safe. */
- + {
- + UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
- +
- + high = answer >> BITS_PER_SI;
- + low = answer;
- + }
- +#else
- + /* fractype is DImode, but we need the result to be twice as wide.
- + Assuming a widening multiply from DImode to TImode is not
- + available, build one by hand. */
- + {
- + USItype nl = a->fraction.ll;
- + USItype nh = a->fraction.ll >> BITS_PER_SI;
- + USItype ml = b->fraction.ll;
- + USItype mh = b->fraction.ll >> BITS_PER_SI;
- + UDItype pp_ll = (UDItype) ml * nl;
- + UDItype pp_hl = (UDItype) mh * nl;
- + UDItype pp_lh = (UDItype) ml * nh;
- + UDItype pp_hh = (UDItype) mh * nh;
- + UDItype res2 = 0;
- + UDItype res0 = 0;
- + UDItype ps_hh__ = pp_hl + pp_lh;
- + if (ps_hh__ < pp_hl)
- + res2 += (UDItype)1 << BITS_PER_SI;
- + pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
- + res0 = pp_ll + pp_hl;
- + if (res0 < pp_ll)
- + res2++;
- + res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
- + high = res2;
- + low = res0;
- + }
- +#endif
- + }
- +
- + tmp->normal_exp = a->normal_exp + b->normal_exp
- + + FRAC_NBITS - (FRACBITS + NGARDS);
- + tmp->sign = a->sign != b->sign;
- + while (high >= IMPLICIT_2)
- + {
- + tmp->normal_exp++;
- + if (high & 1)
- + {
- + low >>= 1;
- + low |= FRACHIGH;
- + }
- + high >>= 1;
- + }
- + while (high < IMPLICIT_1)
- + {
- + tmp->normal_exp--;
- +
- + high <<= 1;
- + if (low & FRACHIGH)
- + high |= 1;
- + low <<= 1;
- + }
- +
- + if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
- + {
- + if (high & (1 << NGARDS))
- + {
- + /* Because we're half way, we would round to even by adding
- + GARDROUND + 1, except that's also done in the packing
- + function, and rounding twice will lose precision and cause
- + the result to be too far off. Example: 32-bit floats with
- + bit patterns 0xfff * 0x3f800400 ~= 0xfff (less than 0.5ulp
- + off), not 0x1000 (more than 0.5ulp off). */
- + }
- + else if (low)
- + {
- + /* We're a further than half way by a small amount corresponding
- + to the bits set in "low". Knowing that, we round here and
- + not in pack_d, because there we don't have "low" available
- + anymore. */
- + high += GARDROUND + 1;
- +
- + /* Avoid further rounding in pack_d. */
- + high &= ~(fractype) GARDMASK;
- + }
- + }
- + tmp->fraction.ll = high;
- + tmp->class = CLASS_NUMBER;
- + return tmp;
- +}
- +
- +FLO_type
- +multiply (FLO_type arg_a, FLO_type arg_b)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type a;
- + fp_number_type b;
- + fp_number_type tmp;
- + fp_number_type *res;
- + FLO_union_type au, bu;
- +
- + au.value = arg_a;
- + bu.value = arg_b;
- +
- + unpack_d (&au, &a);
- + unpack_d (&bu, &b);
- +
- + res = _fpmul_parts (&a, &b, &tmp);
- +
- + return pack_d (res);
- +#else
- + return arg_a * arg_b;
- +#endif
- +}
- +#endif /* L_mul_sf || L_mul_df || L_mul_tf */
- +
- +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
- +static inline __attribute__ ((__always_inline__)) fp_number_type *
- +_fpdiv_parts (fp_number_type * a,
- + fp_number_type * b)
- +{
- + fractype bit;
- + fractype numerator;
- + fractype denominator;
- + fractype quotient;
- +
- + if (isnan (a))
- + {
- + return a;
- + }
- + if (isnan (b))
- + {
- + return b;
- + }
- +
- + a->sign = a->sign ^ b->sign;
- +
- + if (isinf (a) || iszero (a))
- + {
- + if (a->class == b->class)
- + return nan ();
- + return a;
- + }
- +
- + if (isinf (b))
- + {
- + a->fraction.ll = 0;
- + a->normal_exp = 0;
- + return a;
- + }
- + if (iszero (b))
- + {
- + a->class = CLASS_INFINITY;
- + return a;
- + }
- +
- + /* Calculate the mantissa by multiplying both 64bit numbers to get a
- + 128 bit number */
- + {
- + /* quotient =
- + ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
- + */
- +
- + a->normal_exp = a->normal_exp - b->normal_exp;
- + numerator = a->fraction.ll;
- + denominator = b->fraction.ll;
- +
- + if (numerator < denominator)
- + {
- + /* Fraction will be less than 1.0 */
- + numerator *= 2;
- + a->normal_exp--;
- + }
- + bit = IMPLICIT_1;
- + quotient = 0;
- + /* ??? Does divide one bit at a time. Optimize. */
- + while (bit)
- + {
- + if (numerator >= denominator)
- + {
- + quotient |= bit;
- + numerator -= denominator;
- + }
- + bit >>= 1;
- + numerator *= 2;
- + }
- +
- + if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
- + {
- + if (quotient & (1 << NGARDS))
- + {
- + /* Because we're half way, we would round to even by adding
- + GARDROUND + 1, except that's also done in the packing
- + function, and rounding twice will lose precision and cause
- + the result to be too far off. */
- + }
- + else if (numerator)
- + {
- + /* We're a further than half way by the small amount
- + corresponding to the bits set in "numerator". Knowing
- + that, we round here and not in pack_d, because there we
- + don't have "numerator" available anymore. */
- + quotient += GARDROUND + 1;
- +
- + /* Avoid further rounding in pack_d. */
- + quotient &= ~(fractype) GARDMASK;
- + }
- + }
- +
- + a->fraction.ll = quotient;
- + return (a);
- + }
- +}
- +
- +FLO_type
- +divide (FLO_type arg_a, FLO_type arg_b)
- +{
- + fp_number_type a;
- + fp_number_type b;
- + fp_number_type *res;
- + FLO_union_type au, bu;
- +
- + au.value = arg_a;
- + bu.value = arg_b;
- +
- + unpack_d (&au, &a);
- + unpack_d (&bu, &b);
- +
- + res = _fpdiv_parts (&a, &b);
- +
- + return pack_d (res);
- +}
- +#endif /* L_div_sf || L_div_df */
- +
- +#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
- + || defined(L_fpcmp_parts_tf)
- +/* according to the demo, fpcmp returns a comparison with 0... thus
- + a<b -> -1
- + a==b -> 0
- + a>b -> +1
- + */
- +
- +int
- +__fpcmp_parts (fp_number_type * a, fp_number_type * b)
- +{
- +#if 0
- + /* either nan -> unordered. Must be checked outside of this routine. */
- + if (isnan (a) && isnan (b))
- + {
- + return 1; /* still unordered! */
- + }
- +#endif
- +
- + if (isnan (a) || isnan (b))
- + {
- + return 1; /* how to indicate unordered compare? */
- + }
- + if (isinf (a) && isinf (b))
- + {
- + /* +inf > -inf, but +inf != +inf */
- + /* b \a| +inf(0)| -inf(1)
- + ______\+--------+--------
- + +inf(0)| a==b(0)| a<b(-1)
- + -------+--------+--------
- + -inf(1)| a>b(1) | a==b(0)
- + -------+--------+--------
- + So since unordered must be nonzero, just line up the columns...
- + */
- + return b->sign - a->sign;
- + }
- + /* but not both... */
- + if (isinf (a))
- + {
- + return a->sign ? -1 : 1;
- + }
- + if (isinf (b))
- + {
- + return b->sign ? 1 : -1;
- + }
- + if (iszero (a) && iszero (b))
- + {
- + return 0;
- + }
- + if (iszero (a))
- + {
- + return b->sign ? 1 : -1;
- + }
- + if (iszero (b))
- + {
- + return a->sign ? -1 : 1;
- + }
- + /* now both are "normal". */
- + if (a->sign != b->sign)
- + {
- + /* opposite signs */
- + return a->sign ? -1 : 1;
- + }
- + /* same sign; exponents? */
- + if (a->normal_exp > b->normal_exp)
- + {
- + return a->sign ? -1 : 1;
- + }
- + if (a->normal_exp < b->normal_exp)
- + {
- + return a->sign ? 1 : -1;
- + }
- + /* same exponents; check size. */
- + if (a->fraction.ll > b->fraction.ll)
- + {
- + return a->sign ? -1 : 1;
- + }
- + if (a->fraction.ll < b->fraction.ll)
- + {
- + return a->sign ? 1 : -1;
- + }
- + /* after all that, they're equal. */
- + return 0;
- +}
- +#endif
- +
- +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
- +CMPtype
- +compare (FLO_type arg_a, FLO_type arg_b)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type a;
- + fp_number_type b;
- + FLO_union_type au, bu;
- +
- + au.value = arg_a;
- + bu.value = arg_b;
- +
- + unpack_d (&au, &a);
- + unpack_d (&bu, &b);
- +
- + return __fpcmp_parts (&a, &b);
- +#else
- + if (arg_a < arg_b)
- + return -1;
- + else if (arg_a == arg_b)
- + return 0;
- + else
- + return 1;
- +#endif
- +}
- +#endif /* L_compare_sf || L_compare_df */
- +
- +#ifndef US_SOFTWARE_GOFAST
- +
- +/* These should be optimized for their specific tasks someday. */
- +
- +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
- +CMPtype
- +_eq_f2 (FLO_type arg_a, FLO_type arg_b)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type a;
- + fp_number_type b;
- + FLO_union_type au, bu;
- +
- + au.value = arg_a;
- + bu.value = arg_b;
- +
- + unpack_d (&au, &a);
- + unpack_d (&bu, &b);
- +
- + if (isnan (&a) || isnan (&b))
- + return 1; /* false, truth == 0 */
- +
- + return __fpcmp_parts (&a, &b) ;
- +#else
- + return compare (arg_a, arg_b);
- +#endif
- +}
- +#endif /* L_eq_sf || L_eq_df */
- +
- +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
- +CMPtype
- +_ne_f2 (FLO_type arg_a, FLO_type arg_b)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type a;
- + fp_number_type b;
- + FLO_union_type au, bu;
- +
- + au.value = arg_a;
- + bu.value = arg_b;
- +
- + unpack_d (&au, &a);
- + unpack_d (&bu, &b);
- +
- + if (isnan (&a) || isnan (&b))
- + return 1; /* true, truth != 0 */
- +
- + return __fpcmp_parts (&a, &b) ;
- +#else
- + return compare (arg_a, arg_b);
- +#endif
- +}
- +#endif /* L_ne_sf || L_ne_df */
- +
- +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
- +CMPtype
- +_gt_f2 (FLO_type arg_a, FLO_type arg_b)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type a;
- + fp_number_type b;
- + FLO_union_type au, bu;
- +
- + au.value = arg_a;
- + bu.value = arg_b;
- +
- + unpack_d (&au, &a);
- + unpack_d (&bu, &b);
- +
- + if (isnan (&a) || isnan (&b))
- + return -1; /* false, truth > 0 */
- +
- + return __fpcmp_parts (&a, &b);
- +#else
- + if (__builtin_isnan (arg_a) || __builtin_isnan (arg_b))
- + return -1;
- +
- + return compare (arg_a, arg_b);
- +#endif
- +}
- +#endif /* L_gt_sf || L_gt_df */
- +
- +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
- +CMPtype
- +_ge_f2 (FLO_type arg_a, FLO_type arg_b)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type a;
- + fp_number_type b;
- + FLO_union_type au, bu;
- +
- + au.value = arg_a;
- + bu.value = arg_b;
- +
- + unpack_d (&au, &a);
- + unpack_d (&bu, &b);
- +
- + if (isnan (&a) || isnan (&b))
- + return -1; /* false, truth >= 0 */
- + return __fpcmp_parts (&a, &b) ;
- +#else
- + if (__builtin_isnan (arg_a) || __builtin_isnan (arg_b))
- + return -1;
- +
- + return compare (arg_a, arg_b);
- +#endif
- +}
- +#endif /* L_ge_sf || L_ge_df */
- +
- +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
- +CMPtype
- +_lt_f2 (FLO_type arg_a, FLO_type arg_b)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type a;
- + fp_number_type b;
- + FLO_union_type au, bu;
- +
- + au.value = arg_a;
- + bu.value = arg_b;
- +
- + unpack_d (&au, &a);
- + unpack_d (&bu, &b);
- +
- + if (isnan (&a) || isnan (&b))
- + return 1; /* false, truth < 0 */
- +
- + return __fpcmp_parts (&a, &b);
- +#else
- + return compare (arg_a, arg_b);
- +#endif
- +}
- +#endif /* L_lt_sf || L_lt_df */
- +
- +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
- +CMPtype
- +_le_f2 (FLO_type arg_a, FLO_type arg_b)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type a;
- + fp_number_type b;
- + FLO_union_type au, bu;
- +
- + au.value = arg_a;
- + bu.value = arg_b;
- +
- + unpack_d (&au, &a);
- + unpack_d (&bu, &b);
- +
- + if (isnan (&a) || isnan (&b))
- + return 1; /* false, truth <= 0 */
- +
- + return __fpcmp_parts (&a, &b) ;
- +#else
- + return compare (arg_a, arg_b);
- +#endif
- +}
- +#endif /* L_le_sf || L_le_df */
- +
- +#endif /* ! US_SOFTWARE_GOFAST */
- +
- +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
- +CMPtype
- +_unord_f2 (FLO_type arg_a, FLO_type arg_b)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type a;
- + fp_number_type b;
- + FLO_union_type au, bu;
- +
- + au.value = arg_a;
- + bu.value = arg_b;
- +
- + unpack_d (&au, &a);
- + unpack_d (&bu, &b);
- +
- + return (isnan (&a) || isnan (&b));
- +#else
- + return __builtin_isunordered (arg_a, arg_b);
- +#endif
- +}
- +#endif /* L_unord_sf || L_unord_df */
- +
- +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
- +FLO_type
- +si_to_float (SItype arg_a)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type in;
- +
- + in.class = CLASS_NUMBER;
- + in.sign = arg_a < 0;
- + if (!arg_a)
- + {
- + in.class = CLASS_ZERO;
- + }
- + else
- + {
- + USItype uarg;
- + int shift;
- + in.normal_exp = FRACBITS + NGARDS;
- + if (in.sign)
- + {
- + /* Special case for minint, since there is no +ve integer
- + representation for it */
- + if (arg_a == (- MAX_SI_INT - 1))
- + {
- + return (FLO_type)(- MAX_SI_INT - 1);
- + }
- + uarg = (-arg_a);
- + }
- + else
- + uarg = arg_a;
- +
- + in.fraction.ll = uarg;
- + shift = clzusi (uarg) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
- + if (shift > 0)
- + {
- + in.fraction.ll <<= shift;
- + in.normal_exp -= shift;
- + }
- + }
- + return pack_d (&in);
- +#else
- + return (FLO_type)arg_a;
- +#endif
- +}
- +#endif /* L_si_to_sf || L_si_to_df */
- +
- +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
- +FLO_type
- +usi_to_float (USItype arg_a)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type in;
- +
- + in.sign = 0;
- + if (!arg_a)
- + {
- + in.class = CLASS_ZERO;
- + }
- + else
- + {
- + int shift;
- + in.class = CLASS_NUMBER;
- + in.normal_exp = FRACBITS + NGARDS;
- + in.fraction.ll = arg_a;
- +
- + shift = clzusi (arg_a) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
- + if (shift < 0)
- + {
- + fractype guard = in.fraction.ll & (((fractype)1 << -shift) - 1);
- + in.fraction.ll >>= -shift;
- + in.fraction.ll |= (guard != 0);
- + in.normal_exp -= shift;
- + }
- + else if (shift > 0)
- + {
- + in.fraction.ll <<= shift;
- + in.normal_exp -= shift;
- + }
- + }
- + return pack_d (&in);
- +#else
- + return (FLO_type)arg_a;
- +#endif
- +}
- +#endif
- +
- +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
- +SItype
- +float_to_si (FLO_type arg_a)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type a;
- + SItype tmp;
- + FLO_union_type au;
- +
- + au.value = arg_a;
- + unpack_d (&au, &a);
- +
- + if (iszero (&a))
- + return 0;
- + if (isnan (&a))
- + return 0;
- + /* get reasonable MAX_SI_INT... */
- + if (isinf (&a))
- + return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
- + /* it is a number, but a small one */
- + if (a.normal_exp < 0)
- + return 0;
- + if (a.normal_exp > BITS_PER_SI - 2)
- + return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
- + tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
- + return a.sign ? (-tmp) : (tmp);
- +#else
- + return (SItype)arg_a;
- +#endif
- +}
- +#endif /* L_sf_to_si || L_df_to_si */
- +
- +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
- +#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
- +/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
- + we also define them for GOFAST because the ones in libgcc2.c have the
- + wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
- + out of libgcc2.c. We can't define these here if not GOFAST because then
- + there'd be duplicate copies. */
- +
- +USItype
- +float_to_usi (FLO_type arg_a)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type a;
- + FLO_union_type au;
- +
- + au.value = arg_a;
- + unpack_d (&au, &a);
- +
- + if (iszero (&a))
- + return 0;
- + if (isnan (&a))
- + return 0;
- + /* it is a negative number */
- + if (a.sign)
- + return 0;
- + /* get reasonable MAX_USI_INT... */
- + if (isinf (&a))
- + return MAX_USI_INT;
- + /* it is a number, but a small one */
- + if (a.normal_exp < 0)
- + return 0;
- + if (a.normal_exp > BITS_PER_SI - 1)
- + return MAX_USI_INT;
- + else if (a.normal_exp > (FRACBITS + NGARDS))
- + return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
- + else
- + return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
- +#else
- + return (USItype)arg_a;
- +#endif
- +}
- +#endif /* US_SOFTWARE_GOFAST */
- +#endif /* L_sf_to_usi || L_df_to_usi */
- +
- +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
- +FLO_type
- +negate (FLO_type arg_a)
- +{
- +#if defined(TFLOAT) || (!defined(FLOAT) && !defined(METAC_FPU_DOUBLE)) || !defined(METAC_FPU_FLOAT)
- + fp_number_type a;
- + FLO_union_type au;
- +
- + au.value = arg_a;
- + unpack_d (&au, &a);
- +
- + flip_sign (&a);
- + return pack_d (&a);
- +#else
- + return -arg_a;
- +#endif
- +}
- +#endif /* L_negate_sf || L_negate_df */
- +
- +#ifdef FLOAT
- +
- +#if defined(L_make_sf)
- +SFtype
- +__make_fp(fp_class_type class,
- + unsigned int sign,
- + int exp,
- + USItype frac)
- +{
- + fp_number_type in;
- +
- + in.class = class;
- + in.sign = sign;
- + in.normal_exp = exp;
- + in.fraction.ll = frac;
- + return pack_d (&in);
- +}
- +#endif /* L_make_sf */
- +
- +#ifndef FLOAT_ONLY
- +
- +/* This enables one to build an fp library that supports float but not double.
- + Otherwise, we would get an undefined reference to __make_dp.
- + This is needed for some 8-bit ports that can't handle well values that
- + are 8-bytes in size, so we just don't support double for them at all. */
- +
- +#if defined(L_sf_to_df)
- +DFtype
- +sf_to_df (SFtype arg_a)
- +{
- +#if defined(TFLOAT) || !defined(METAC_FPU_DOUBLE)
- + fp_number_type in;
- + FLO_union_type au;
- +
- + au.value = arg_a;
- + unpack_d (&au, &in);
- +
- + return __make_dp (in.class, in.sign, in.normal_exp,
- + ((UDItype) in.fraction.ll) << F_D_BITOFF);
- +#else
- + return (DFtype)arg_a;
- +#endif
- +}
- +#endif /* L_sf_to_df */
- +
- +#if defined(L_sf_to_tf) && defined(TMODES)
- +TFtype
- +sf_to_tf (SFtype arg_a)
- +{
- + fp_number_type in;
- + FLO_union_type au;
- +
- + au.value = arg_a;
- + unpack_d (&au, &in);
- +
- + return __make_tp (in.class, in.sign, in.normal_exp,
- + ((UTItype) in.fraction.ll) << F_T_BITOFF);
- +}
- +#endif /* L_sf_to_df */
- +
- +#endif /* ! FLOAT_ONLY */
- +#endif /* FLOAT */
- +
- +#ifndef FLOAT
- +
- +extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
- +
- +#if defined(L_make_df)
- +DFtype
- +__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
- +{
- + fp_number_type in;
- +
- + in.class = class;
- + in.sign = sign;
- + in.normal_exp = exp;
- + in.fraction.ll = frac;
- + return pack_d (&in);
- +}
- +#endif /* L_make_df */
- +
- +#if defined(L_df_to_sf)
- +SFtype
- +df_to_sf (DFtype arg_a)
- +{
- +#if defined(TFLOAT) || !defined(METAC_FPU_DOUBLE)
- + fp_number_type in;
- + USItype sffrac;
- + FLO_union_type au;
- +
- + au.value = arg_a;
- + unpack_d (&au, &in);
- +
- + sffrac = in.fraction.ll >> F_D_BITOFF;
- +
- + /* We set the lowest guard bit in SFFRAC if we discarded any non
- + zero bits. */
- + if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
- + sffrac |= 1;
- +
- + return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
- +#else
- + return (SFtype)arg_a;
- +#endif
- +}
- +#endif /* L_df_to_sf */
- +
- +#if defined(L_df_to_tf) && defined(TMODES) \
- + && !defined(FLOAT) && !defined(TFLOAT)
- +TFtype
- +df_to_tf (DFtype arg_a)
- +{
- + fp_number_type in;
- + FLO_union_type au;
- +
- + au.value = arg_a;
- + unpack_d (&au, &in);
- +
- + return __make_tp (in.class, in.sign, in.normal_exp,
- + ((UTItype) in.fraction.ll) << D_T_BITOFF);
- +}
- +#endif /* L_sf_to_df */
- +
- +#ifdef TFLOAT
- +#if defined(L_make_tf)
- +TFtype
- +__make_tp(fp_class_type class,
- + unsigned int sign,
- + int exp,
- + UTItype frac)
- +{
- + fp_number_type in;
- +
- + in.class = class;
- + in.sign = sign;
- + in.normal_exp = exp;
- + in.fraction.ll = frac;
- + return pack_d (&in);
- +}
- +#endif /* L_make_tf */
- +
- +#if defined(L_tf_to_df)
- +DFtype
- +tf_to_df (TFtype arg_a)
- +{
- + fp_number_type in;
- + UDItype sffrac;
- + FLO_union_type au;
- +
- + au.value = arg_a;
- + unpack_d (&au, &in);
- +
- + sffrac = in.fraction.ll >> D_T_BITOFF;
- +
- + /* We set the lowest guard bit in SFFRAC if we discarded any non
- + zero bits. */
- + if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
- + sffrac |= 1;
- +
- + return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
- +}
- +#endif /* L_tf_to_df */
- +
- +#if defined(L_tf_to_sf)
- +SFtype
- +tf_to_sf (TFtype arg_a)
- +{
- + fp_number_type in;
- + USItype sffrac;
- + FLO_union_type au;
- +
- + au.value = arg_a;
- + unpack_d (&au, &in);
- +
- + sffrac = in.fraction.ll >> F_T_BITOFF;
- +
- + /* We set the lowest guard bit in SFFRAC if we discarded any non
- + zero bits. */
- + if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
- + sffrac |= 1;
- +
- + return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
- +}
- +#endif /* L_tf_to_sf */
- +#endif /* TFLOAT */
- +
- +#endif /* ! FLOAT */
- +#endif /* !EXTENDED_FLOAT_STUBS */
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/fp.md gcc-4.2.4/gcc/config/metag/fp.md
- --- gcc-4.2.4.orig/gcc/config/metag/fp.md 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/fp.md 2015-07-03 18:46:05.745283542 -0500
- @@ -0,0 +1,1037 @@
- +;; Machine description for GNU compiler,
- +;; Imagination Technologies Meta version.
- +;; Copyright (C) 2008
- +;; Imagination Technologies Ltd
- +
- +;; This file is part of GCC.
- +
- +;; GCC 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 3, or (at your option) any later
- +;; version.
- +
- +;; GCC 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 GCC; see the file COPYING3. If not see
- +;; <http://www.gnu.org/licenses/>.
- +
- +;;- instruction definitions
- +
- +;;- @@The original PO technology requires these to be ordered by speed,
- +;;- @@ so that assigner will pick the fastest.
- +
- +;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
- +
- +;;- When naming insn's (operand 0 of define_insn) be careful about using
- +;;- names from other targets machine descriptions.
- +
- +
- +
- +(define_insn_and_split "*movv2sfrr"
- + [(set (match_operand:V2SF 0 "metag_fpreg_or_dreg_op" "=cx,cx,d, d")
- + (match_operand:V2SF 1 "metag_fpreg_or_dreg_op" "cx,d, cx,d"))]
- + "TARGET_FPU_SIMD"
- + "@
- + FL\\tMOV\\t%0,%1\\t%@ (*mov v2sf rr)
- + #
- + #
- + #"
- + "&& reload_completed"
- + [(set (match_dup 2)
- + (match_dup 3))
- + (set (match_dup 4)
- + (match_dup 5))]
- + {
- + operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));
- + operands[3] = gen_rtx_REG (SImode, REGNO (operands[1]));
- + operands[4] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- + operands[5] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
- + }
- + [(set_attr "type" "FPfast")])
- +
- +(define_insn_and_split "*movv2sfri"
- + [(set (match_operand:V2SF 0 "metag_fpreg_op" "=cx")
- + (match_operand:V2SF 1 "metag_vector_float_op" "vcf"))]
- + "TARGET_FPU_SIMD"
- + {
- + if (rtx_equal_p (CONST_VECTOR_ELT (operands[1], 0),
- + CONST_VECTOR_ELT (operands[1], 1)))
- + return "FL\\tMOV\\t%0,#%h1";
- + else
- + return "#";
- + }
- + "&& reload_completed
- + && !rtx_equal_p (CONST_VECTOR_ELT (operands[1], 0),
- + CONST_VECTOR_ELT (operands[1], 1))"
- + [(set (match_dup 2)
- + (match_dup 4))
- + (set (match_dup 3)
- + (match_dup 5))]
- + {
- + operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));
- + operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0]) + 1);
- + operands[4] = CONST_VECTOR_ELT (operands[1], 0);
- + operands[5] = CONST_VECTOR_ELT (operands[1], 1);
- + }
- + [(set_attr "type" "FPfast")])
- +
- +(define_expand "movv2sf"
- + [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
- + (match_operand:V2SF 1 "general_operand" ""))]
- + "TARGET_FPU_SIMD"
- + {
- + if (MEM_P (operands[0]) && !REG_P (operands[1]))
- + {
- + /* All except mem = const, mem = mem, or mem = addr can be done quickly */
- + if (!no_new_pseudos)
- + operands[1] = force_reg (V2SFmode, operands[1]);
- + }
- + else if (GET_CODE(operands[1]) == CONST_VECTOR)
- + if ( (!metag_fphalf_imm_op (CONST_VECTOR_ELT (operands[1], 0), SFmode)
- + || !metag_fphalf_imm_op (CONST_VECTOR_ELT (operands[1], 1), SFmode)))
- + {
- + emit_move_insn (gen_rtx_SUBREG (SFmode, operands[0], 0),
- + CONST_VECTOR_ELT (operands[1], 0));
- + emit_move_insn (gen_rtx_SUBREG (SFmode, operands[0], UNITS_PER_WORD),
- + CONST_VECTOR_ELT (operands[1], 1));
- + DONE;
- + }
- + }
- +)
- +
- +;; -----------------------------------------------------------------------------
- +;; | Matching V2SF load [post/pre]_[inc/dec/modify]
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lod_v2sf_post_inc"
- + [(set (match_operand:V2SF 0 "metag_fpreg_op" "=cx")
- + (mem:V2SF (post_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_FPU_SIMD"
- + "F\\tGETL\\t%0, %t0, [%1++]\\t%@ (*load V2SF post_inc OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_v2sf_post_dec"
- + [(set (match_operand:V2SF 0 "metag_fpreg_op" "=cx")
- + (mem:V2SF (post_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_FPU_SIMD"
- + "F\\tGETL\\t%0, %t0, [%1--]\\t%@ (*load V2SF post_dec OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_v2sf_pre_inc"
- + [(set (match_operand:V2SF 0 "metag_fpreg_op" "=cx")
- + (mem:V2SF (pre_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_FPU_SIMD"
- + "F\\tGETL\\t%0, %t0, [++%1]\\t%@ (*load V2SF pre_inc OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_v2sf_pre_dec"
- + [(set (match_operand:V2SF 0 "metag_fpreg_op" "=cx")
- + (mem:V2SF (pre_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_FPU_SIMD"
- + "F\\tGETL\\t%0, %t0, [--%1]\\t%@ (*load V2SF pre_dec OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_v2sf_post_modify_disp"
- + [(set (match_operand:V2SF 0 "metag_fpreg_op" "=cx")
- + (mem:V2SF (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_v2sf" "O8")))))]
- + "TARGET_FPU_SIMD"
- + "F\\tGETL\\t%0, %t0, [%1+%2++]\\t%@ (*load V2SF post_modify_disp OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_v2sf_post_modify_reg"
- + [(set (match_operand:V2SF 0 "metag_fpreg_op" "=cx,cx,cx,cx")
- + (mem:V2SF (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l")))))]
- + "TARGET_FPU_SIMD"
- + "F\\tGETL\\t%0, %t0, [%1+%2++]\\t%@ (*load V2SF post_modify_reg OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_v2sf_pre_modify_disp"
- + [(set (match_operand:V2SF 0 "metag_fpreg_op" "=cx")
- + (mem:V2SF (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_v2sf" "O8")))))]
- + "TARGET_FPU_SIMD"
- + "F\\tGETL\\t%0, %t0, [%1++%2]\\t%@ (*load V2SF pre_modify_disp OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_v2sf_pre_modify_reg"
- + [(set (match_operand:V2SF 0 "metag_fpreg_op" "=cx,cx,cx,cx")
- + (mem:V2SF (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l")))))]
- + "TARGET_FPU_SIMD"
- + "F\\tGETL\\t%0, %t0, [%1++%2]\\t%@ (*load V2SF pre_modify_reg OK)"
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lod_v2sf_off6"
- + [(set (match_operand:V2SF 0 "metag_fpreg_op" "=cx")
- + (mem:V2SF (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 2 "metag_offset6_v2sf" "O8"))))]
- + "TARGET_FPU_SIMD"
- + "F\\tGETL\\t%0, %t0, [%1+%2]"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_v2sf_mem"
- + [(set (match_operand:V2SF 0 "metag_datareg_op" "=d")
- + (match_operand:V2SF 1 "memory_operand" "m"))]
- + "TARGET_FPU_SIMD"
- + "GETL\\t%0, %t0, %1\\t%@ (*lod v2sf rm OK)"
- + [(set_attr "memaccess" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +;; | Matching V2SF store [post/pre]_[inc/dec/modify]
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*sto_v2sf_post_inc"
- + [(set (mem:V2SF (post_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:V2SF 1 "metag_fpreg_op" "cx"))]
- + "TARGET_FPU_SIMD"
- + "F\\tSETL\\t[%0++], %1, %t1\\t%@ (*store V2SF post_inc OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_v2sf_post_dec"
- + [(set (mem:V2SF (post_dec:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:V2SF 1 "metag_fpreg_op" "cx"))]
- + "TARGET_FPU_SIMD"
- + "F\\tSETL\\t[%0--], %1, %t1\\t%@ (*store V2SF post_dec OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_v2sf_pre_inc"
- + [(set (mem:V2SF (pre_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:V2SF 1 "metag_fpreg_op" "cx"))]
- + "TARGET_FPU_SIMD"
- + "F\\tSETL\\t[++%0], %1, %t1\\t%@ (*store V2SF pre_inc OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_v2sf_pre_dec"
- + [(set (mem:V2SF (pre_dec:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:V2SF 1 "metag_fpreg_op" "cx"))]
- + "TARGET_FPU_SIMD"
- + "F\\tSETL\\t[--%0], %1, %t1\\t%@ (*store V2SF pre_dec OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_v2sf_post_modify_disp"
- + [(set (mem:V2SF (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_v2sf" "O8"))))
- + (match_operand:V2SF 2 "metag_fpreg_op" "cx"))]
- + "TARGET_FPU_SIMD"
- + "F\\tSETL\\t[%0+%1++], %2, %t2\\t%@ (*store V2SF post_modify_disp OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_v2sf_post_modify_reg"
- + [(set (mem:V2SF (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e, f, h, l"))))
- + (match_operand:V2SF 2 "metag_fpreg_op" "cx,cx,cx,cx"))]
- + "TARGET_FPU_SIMD"
- + "F\\tSETL\\t[%0+%1++], %2, %t2\\t%@ (*store V2SF post_modify_reg OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_v2sf_pre_modify_disp"
- + [(set (mem:V2SF (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_v2sf" "O8"))))
- + (match_operand:V2SF 2 "metag_fpreg_op" "cx"))]
- + "TARGET_FPU_SIMD"
- + "F\\tSETL\\t[%0++%1], %2, %t2\\t%@ (*store V2SF pre_modify_disp OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_v2sf_pre_modify_reg"
- + [(set (mem:V2SF (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e, f, h, l"))))
- + (match_operand:V2SF 2 "metag_fpreg_op" "cx,cx,cx,cx"))]
- + "TARGET_FPU_SIMD"
- + "F\\tSETL\\t[%0++%1], %2, %t2\\t%@ (*store V2SF pre_modify_reg OK)"
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*sto_v2sf_off6"
- + [(set (mem:V2SF (plus:SI (match_operand:SI 0 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 1 "metag_offset6_v2sf" "O8")))
- + (match_operand:V2SF 2 "metag_fpreg_op" "cx"))]
- + "TARGET_FPU_SIMD"
- + "F\\tSETL\\t[%0+%1], %2, %t2"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_v2sf_mem"
- + [(set (match_operand:V2SF 0 "memory_operand" "=m")
- + (match_operand:V2SF 1 "metag_datareg_op" "d"))]
- + "TARGET_FPU_SIMD"
- + "SETL\\t%0, %1, %t1\\t%@ (*sto v2sf rm OK)"
- + [(set_attr "type" "FPfast")])
- +
- +; Movement instructions
- +
- +(define_insn "abs<mode>2"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (abs:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")))]
- + "<fcondition>"
- + "F<FW>\\tABS%?\\t%0,%1"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +;;(define_insn "*mmovsf_d_to_f"
- +;; [(match_parallel 0 "metag_mmov_valid"
- +;; [(set (match_operand:SF 1 "metag_fpreg_op" "=cx")
- +;; (match_operand:SF 2 "metag_datareg_op" "d" ))
- +;; (set (match_operand:SF 3 "metag_fpreg_op" "=cx")
- +;; (match_operand:SF 4 "metag_datareg_op" "d" ))])]
- +;; "TARGET_FPU"
- +;; {
- +;; switch (XVECLEN(operands[0], 0))
- +;; {
- +;; case 2:
- +;; return "F\\tMMOV\\t%1,%3,%2,%4";
- +;; case 3:
- +;; return "F\\tMMOV\\t%1,%3,%5,%2,%4,%6";
- +;; case 4:
- +;; return "F\\tMMOV\\t%1,%3,%5,%7,%2,%4,%6,%8";
- +;; case 5:
- +;; return "F\\tMMOV\\t%1,%3,%5,%7,%9,%2,%4,%6,%8,%10";
- +;; case 6:
- +;; return "F\\tMMOV\\t%1,%3,%5,%7,%9,%11,%2,%4,%6,%8,%10,%12";
- +;; case 7:
- +;; return "F\\tMMOV\\t%1,%3,%5,%7,%9,%11,%13,%2,%4,%6,%8,%10,%12,%14";
- +;; case 8:
- +;; return "F\\tMMOV\\t%1,%3,%5,%7,%9,%11,%13,%15,%2,%4,%6,%8,%10,%12,%14,%16";
- +;; default:
- +;; gcc_unreachable ();
- +;; }
- +;; })
- +
- +(define_insn "*mov_<mode>_imm"
- + [(set (match_operand:FMODES 0 "metag_fpreg_op" "=cx")
- + (match_operand:<MODE> 1 "metag_fphalf_imm_op" "ci"))]
- + "<fcondition>"
- + "F<FW>\\tMOV\\t%0,#%h1"
- + [(set_attr "type" "FPfast")])
- +
- +(define_insn "neg<mode>2"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (neg:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")))]
- + "<fcondition>"
- + "F<FW>\\tNEG%?\\t%0,%1"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +; TODO: PACK
- +; TODO: SWAP
- +
- +; Comparison Operations
- +
- +(define_expand "cmp<mode>"
- + [(match_operand:FMODES 0 "metag_fpreg_op" "")
- + (match_operand:<MODE> 1 "metag_fpreg_or_imm_op" "")]
- + "<fcondition>"
- + {
- + enum machine_mode mode;
- +
- + /* These are processed via the conditional branch define_expand's later */
- + metag_compare_op0 = operands[0];
- + metag_compare_op1 = operands[1];
- +
- + mode = GET_MODE (operands[1]);
- +
- + /* Have to do register to register comparison for big constants */
- + if (CONST_DOUBLE_P (operands[1]) && operands[1] != CONST0_RTX (mode))
- + metag_compare_op1 = force_reg (mode, operands[1]);
- +
- + DONE;
- + })
- +
- +(define_insn "*cmpsf<CCFP:mode>"
- + [(set (reg:CCFP CC_REG)
- + (compare:CCFP
- + (match_operand:SF 0 "metag_fpreg_op" "cx,cx")
- + (match_operand:SF 1 "metag_fpreg_or_fpzero_imm_op" "cx,G")))]
- + "TARGET_FPU"
- + "@
- + F<CCQ>\\tCMP%?\\t%0,%1
- + F<CCQ>\\tCMP%?\\t%0,#%h1"
- + [(set_attr "type" "FPfast")])
- +
- +(define_insn "*cmpdf<CCFP:mode>"
- + [(set (reg:CCFP CC_REG)
- + (compare:CCFP
- + (match_operand:DF 0 "metag_fpreg_op" "cx,cx")
- + (match_operand:DF 1 "metag_fpreg_or_fpzero_imm_op" "cx,G")))]
- + "TARGET_FPU && !metag_fpu_single"
- + "@
- + FD<CCQ>\\tCMP%?\\t%0,%1
- + FD<CCQ>\\tCMP%?\\t%0,#%h1"
- + [(set_attr "type" "FPfast")])
- +
- +(define_insn "*abscmpsf<CCFP:mode>2"
- + [(set (reg:CCFP CC_REG)
- + (compare:CCFP
- + (abs:SF (match_operand:SF 0 "metag_fpreg_op" "cx,cx"))
- + (abs:SF (match_operand:SF 1 "metag_fpreg_or_fpzero_imm_op" "cx,G"))))]
- + "TARGET_FPU"
- + "@
- + FA<CCQ>\\tCMP%?\\t%0,%1
- + FA<CCQ>\\tCMP%?\\t%0,#%h1"
- + [(set_attr "type" "FPmas")])
- +
- +(define_insn "*abscmpdf<CCFP:mode>2"
- + [(set (reg:CCFP CC_REG)
- + (compare:CCFP
- + (abs:DF (match_operand:DF 0 "metag_fpreg_op" "cx,cx"))
- + (abs:DF (match_operand:DF 1 "metag_fpreg_or_fpzero_imm_op" "cx,G"))))]
- + "TARGET_FPU && !metag_fpu_single"
- + "@
- + FDA<CCQ>\\tCMP%?\\t%0,%1
- + FDA<CCQ>\\tCMP%?\\t%0,#%h1"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "smax<mode>3"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (smax:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx")))
- + (clobber (reg:CC CC_REG))]
- + "<fcondition>"
- + "F<FW>\\tMAX%?\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")
- + (set_attr "ccstate" "ccx")])
- +
- +(define_insn "smin<mode>3"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (smin:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx")))
- + (clobber (reg:CC CC_REG))]
- + "<fcondition>"
- + "F<FW>\\tMIN%?\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")
- + (set_attr "ccstate" "ccx")])
- +
- +; Data Conversion
- +(define_insn "extendsfdf2"
- + [(set (match_operand:DF 0 "metag_fpreg_op" "=cx")
- + (float_extend:DF (match_operand:SF 1 "metag_fpreg_op" "cx")))]
- + "TARGET_FPU && !metag_fpu_single"
- + "F\\tFTOD%?\\t%0,%1"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "truncdfsf2"
- + [(set (match_operand:SF 0 "metag_fpreg_op" "=cx")
- + (float_truncate:SF (match_operand:DF 1 "metag_fpreg_op" "cx")))]
- + "TARGET_FPU && !metag_fpu_single"
- + "F\\tDTOF%?\\t%0,%1"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +;; HFmode isnt supported at the moment but the rules would be something like:
- +;;
- +;;(define_insn "truncsfhf2"
- +;; [(set (match_operand:HF 0 "metag_fpreg_op" "=cx")
- +;; (float:HF (match_operand:SF 1 "metag_fpreg_op" "cx")))]
- +;; "TARGET_FPU"
- +;; "F\\tFTOH%?\\t%0,%1"
- +;; )
- +;;
- +;;(define_insn "truncdfhf2"
- +;; [(set (match_operand:HF 0 "metag_fpreg_op" "=cx")
- +;; (float:HF (match_operand:DF 1 "metag_fpreg_op" "cx")))]
- +;; "TARGET_FPU"
- +;; "F\\tDTOH%?\\t%0,%1"
- +;; )
- +
- +(define_insn "fix_trunc<mode>si2"
- + [(set (match_operand:SI 0 "metag_fpreg_op" "=cx")
- + (fix:SI (match_operand:FSMODES 1 "metag_fpreg_op" "cx")))]
- + "<fcondition>"
- + "FZ\\t<FT>TOI%?\\t%0,%1"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +(define_expand "fix_truncsfdi2"
- + [(set (match_dup 2)
- + (float_extend:DF (match_operand:SF 1 "metag_fpreg_op" "")))
- + (set (match_operand:DI 0 "metag_fpreg_op" "")
- + (fix:DI (match_dup 2)))]
- + "TARGET_FPU && !metag_fpu_single"
- + {
- + operands[2] = gen_reg_rtx (DFmode);
- + })
- +
- +(define_insn "fix_truncdfdi2"
- + [(set (match_operand:DI 0 "metag_fpreg_op" "=cx")
- + (fix:DI (match_operand:DF 1 "metag_fpreg_op" "cx")))]
- + "TARGET_FPU && !metag_fpu_single"
- + "FZ\\tDTOL%?\\t%0,%1"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +(define_expand "fixuns_truncsfdi2"
- + [(set (match_operand:DI 0 "metag_fpreg_op" "")
- + (unsigned_fix:DI (match_operand:SF 1 "metag_fpreg_op" "")))]
- + "TARGET_FPU && !metag_fpu_single"
- + {
- + rtx dscr = gen_reg_rtx (SImode);
- + rtx fscr = gen_reg_rtx (SFmode);
- + rtx fscr_as_si = gen_rtx_SUBREG (SImode, fscr, 0);
- + rtx fscr2 = gen_reg_rtx (SFmode);
- + rtx fdscr = gen_reg_rtx (DFmode);
- + rtx rdhi = gen_rtx_SUBREG (SImode, operands[0], 4);
- + rtx temp_operands[1];
- +
- + /* single precision 2^63 is 0x5F000000 */
- + emit_move_insn (fscr_as_si,
- + gen_int_mode (0x5F000000, SImode));
- +
- + /* Is input in 'difficult' range */
- + emit_insn (gen_cmpsf (operands[1], fscr));
- + gen_metag_compare (GE, temp_operands, 0);
- +
- + /* Copy input to scratch */
- + emit_move_insn (fscr2, operands[1]);
- +
- + /* If it is then wrap around once (note, we dont have to
- + * deal with the case where it's still difficult, C doesnt define
- + * overflow behaviour */
- + emit_insn (gen_rtx_SET (VOIDmode, fscr2,
- + gen_rtx_IF_THEN_ELSE (SFmode,
- + gen_rtx_GE (VOIDmode, temp_operands[0],
- + const0_rtx),
- + gen_rtx_MINUS (SFmode, operands[1],
- + fscr),
- + fscr2)));
- +
- + /* Extend to double before DI conversion */
- + emit_insn (gen_rtx_SET (DFmode, fdscr,
- + gen_rtx_FLOAT_EXTEND (DFmode, fscr2)));
- +
- + /* Convert to DI */
- + emit_insn (gen_rtx_SET (DImode, operands[0],
- + gen_rtx_FIX (DImode, fdscr)));
- +
- + /* Restore truncated value from earlier */
- + emit_insn (gen_rtx_SET (SImode, dscr,
- + gen_int_mode (0x80000000, SImode)));
- + emit_insn (gen_rtx_SET (VOIDmode, rdhi,
- + gen_rtx_IF_THEN_ELSE (SImode,
- + gen_rtx_GE (VOIDmode, temp_operands[0],
- + const0_rtx),
- + gen_rtx_PLUS (SImode, rdhi,
- + dscr),
- + rdhi)));
- + DONE;
- +
- + })
- +
- +(define_expand "fixuns_truncdfdi2"
- + [(set (match_operand:DI 0 "metag_fpreg_op" "")
- + (unsigned_fix:DI (match_operand:DF 1 "metag_fpreg_op" "")))]
- + "TARGET_FPU && !metag_fpu_single"
- + {
- + rtx dscr = gen_reg_rtx (SImode);
- + rtx fscr = gen_reg_rtx (DFmode);
- + rtx fscrlo_as_si = gen_rtx_SUBREG (SImode, fscr, 0);
- + rtx fscrhi_as_si = gen_rtx_SUBREG (SImode, fscr, 4);
- + rtx fdscr = gen_reg_rtx (DFmode);
- + rtx rdhi = gen_rtx_SUBREG (SImode, operands[0], 4);
- + rtx temp_operands[1];
- +
- + /* double precision 2^63 is 0x43e00000 00000000*/
- + emit_move_insn (fscrhi_as_si,
- + gen_int_mode (0x43e00000, SImode));
- + emit_move_insn (fscrlo_as_si, const0_rtx);
- +
- + /* Is input in 'difficult' range */
- + emit_insn (gen_cmpdf (operands[1], fscr));
- + gen_metag_compare (GE, temp_operands, 0);
- +
- + /* Copy input to scratch */
- + emit_move_insn (fdscr, operands[1]);
- +
- + /* If it is then wrap around once (note, we dont have to
- + * deal with the case where it's still difficult, C doesnt define
- + * overflow behaviour */
- + emit_insn (gen_rtx_SET (VOIDmode, fdscr,
- + gen_rtx_IF_THEN_ELSE (DFmode,
- + gen_rtx_GE (VOIDmode, temp_operands[0],
- + const0_rtx),
- + gen_rtx_MINUS (DFmode, operands[1],
- + fscr),
- + fdscr)));
- +
- + /* Convert to DI */
- + emit_insn (gen_rtx_SET (DImode, operands[0],
- + gen_rtx_FIX (DImode, fdscr)));
- +
- + /* Restore truncated value from earlier */
- + emit_insn (gen_rtx_SET (SImode, dscr,
- + gen_int_mode (0x80000000, SImode)));
- + emit_insn (gen_rtx_SET (VOIDmode, rdhi,
- + gen_rtx_IF_THEN_ELSE (SImode,
- + gen_rtx_GE (VOIDmode, temp_operands[0],
- + const0_rtx),
- + gen_rtx_PLUS (SImode, rdhi,
- + dscr),
- + rdhi)));
- +
- + DONE;
- +
- + })
- +
- +(define_expand "fixuns_truncsfsi2"
- + [(set (match_operand:SI 0 "metag_fpreg_op" "")
- + (unsigned_fix:SI (match_operand:SF 1 "metag_fpreg_op" "")))]
- + "TARGET_FPU && metag_fpu_single"
- + {
- + if (metag_fpu_single)
- + {
- + rtx dscr = gen_reg_rtx (SImode);
- + rtx fscr = gen_reg_rtx (SFmode);
- + rtx fscr_as_si = gen_rtx_SUBREG (SImode, fscr, 0);
- + rtx fscr2 = gen_reg_rtx (SFmode);
- + rtx temp_operands[1];
- +
- + /* single precision 2^31 is 0x4F000000 */
- + emit_move_insn (fscr_as_si,
- + gen_int_mode (0x4f000000, SImode));
- +
- + /* Is input in 'difficult' range */
- + emit_insn (gen_cmpsf (operands[1], fscr));
- + gen_metag_compare (GE, temp_operands, 0);
- +
- + /* Copy input to scratch */
- + emit_move_insn (fscr2, operands[1]);
- +
- + /* If it is then wrap around once (note, we dont have to
- + * deal with the case where it's still difficult, C doesnt define
- + * overflow behaviour */
- + emit_insn (gen_rtx_SET (VOIDmode, fscr2,
- + gen_rtx_IF_THEN_ELSE (SFmode,
- + gen_rtx_GE (VOIDmode, temp_operands[0],
- + const0_rtx),
- + gen_rtx_MINUS (SFmode, operands[1],
- + fscr),
- + fscr2)));
- +
- + /* Convert to SI */
- + emit_insn (gen_rtx_SET (SImode, operands[0],
- + gen_rtx_FIX (SImode, fscr2)));
- +
- + /* Restore truncated value from earlier */
- + emit_insn (gen_rtx_SET (SImode, dscr,
- + gen_int_mode (0x80000000, SImode)));
- + emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- + gen_rtx_IF_THEN_ELSE (SImode,
- + gen_rtx_GE (VOIDmode, temp_operands[0],
- + const0_rtx),
- + gen_rtx_PLUS (SImode, operands[0],
- + dscr),
- + operands[0])));
- +
- + DONE;
- + }
- + else
- + {
- + rtx op2 = gen_reg_rtx (DFmode);
- + rtx op3 = gen_reg_rtx (DImode);
- +
- + emit_insn (gen_extendsfdf2 (op2, operands[1]));
- + emit_insn (gen_fix_truncdfdi2 (op3, op2));
- + emit_move_insn (operands[0], gen_rtx_SUBREG (SImode, op3, 0));
- + DONE;
- + }
- +
- + })
- +
- +
- +; DTOX, FTOX, DTOXL not supported
- +(define_insn "floatsi<mode>2"
- + [(set (match_operand:FSMODES 0 "metag_fpreg_op" "=cx")
- + (float:<MODE> (match_operand:SI 1 "metag_fpreg_op" "cx")))]
- + "<fcondition>"
- + "F\\tITO<FT>%?\\t%0,%1"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +(define_expand "floatdisf2"
- + [(set (match_dup 2)
- + (float:DF (match_operand:DI 1 "metag_fpreg_op" "")))
- + (set (match_operand:SF 0 "metag_fpreg_op" "")
- + (float_truncate:SF (match_dup 2)))]
- + "TARGET_FPU && !metag_fpu_single"
- + {
- + operands[2] = gen_reg_rtx (DFmode);
- + })
- +
- +(define_insn "floatdidf2"
- + [(set (match_operand:DF 0 "metag_fpreg_op" "=cx")
- + (float:DF (match_operand:DI 1 "metag_fpreg_op" "cx")))]
- + "TARGET_FPU && !metag_fpu_single"
- + "F\\tLTOD%?\\t%0,%1"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +(define_expand "floatunshi<mode>2"
- + [(set (match_dup:SI 2)
- + (zero_extend:SI (match_operand:HI 1 "metag_reg_nofloat_op" "")))
- + (set (match_operand:FMODES 0 "metag_fpreg_op" "")
- + (float:<MODE> (match_dup 2)))]
- + "<fcondition>"
- + {
- + operands[2] = gen_reg_rtx (SImode);
- + })
- +
- +(define_expand "floatunssidf2"
- + [(set (match_dup 2)
- + (zero_extend:DI (match_operand:SI 1 "metag_register_op" "")))
- + (set (match_operand:DF 0 "metag_fpreg_op" "")
- + (float:DF (match_dup 2)))]
- + "TARGET_FPU && !metag_fpu_single"
- + {
- + operands[2] = gen_reg_rtx (DImode);
- + })
- +
- +(define_expand "floatunsdidf2"
- + [(set (match_operand:DF 0 "metag_fpreg_op" "")
- + (unsigned_float:DF (match_operand:DI 1 "metag_register_op" "")))]
- + "TARGET_FPU && !metag_fpu_single"
- + {
- + metag_expand_didf2 (operands[0], operands[1]);
- + DONE;
- + })
- +
- +(define_expand "floatunsdisf2"
- + [(set (match_dup 2)
- + (unsigned_float:DF (match_operand:DI 1 "metag_register_op" "")))
- + (set (match_operand:SF 0 "metag_fpreg_op" "")
- + (float_truncate:SF (match_dup 2)))]
- + "TARGET_FPU && !metag_fpu_single"
- + {
- + operands[2] = gen_reg_rtx (DFmode);
- +
- + metag_expand_didf2 (operands[2], operands[1]);
- +
- + emit_insn (gen_truncdfsf2 (operands[0], operands[2]));
- + DONE;
- + })
- +
- +(define_expand "floatunssisf2"
- + [(set (match_operand:SF 0 "metag_fpreg_op" "")
- + (unsigned_float:SF (match_operand:SI 1 "metag_register_op" "")))]
- + "TARGET_FPU && metag_fpu_single"
- + {
- + if (metag_fpu_single)
- + {
- + rtx dscr = gen_reg_rtx (SImode);
- + rtx fscr2 = gen_reg_rtx (SFmode);
- + rtx fscr2_as_si = gen_rtx_SUBREG (SImode, fscr2, 0);
- + rtx temp_operands[1];
- +
- + /* Test to see if rs is in the difficult range (> 2^31) */
- + emit_move_insn (dscr, operands[1]);
- + metag_compare_op0 = gen_rtx_AND (SImode, dscr,
- + gen_int_mode (0x80000000, SImode));
- + metag_compare_op1 = const0_rtx;
- + gen_metag_compare (NE, temp_operands, 0);
- +
- + /* Drop the 2^31 component */
- + emit_insn (gen_andsi3 (dscr, dscr,
- + gen_int_mode (0x7fffffff, SImode)));
- +
- + /* Convert to single */
- + emit_insn (gen_floatsisf2 (operands[0], dscr));
- +
- + /* Prepare 2^31 in single precision */
- + emit_move_insn (fscr2_as_si,
- + gen_int_mode (0x4f000000, SImode));
- +
- + /* Add on the missing 2^31 if requried */
- + emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- + gen_rtx_IF_THEN_ELSE (SFmode,
- + gen_rtx_NE (VOIDmode, temp_operands[0],
- + const0_rtx),
- + gen_rtx_PLUS (SFmode, operands[0], fscr2),
- + operands[0])));
- +
- + DONE;
- + }
- + else
- + {
- + rtx op2 = gen_reg_rtx (DImode);
- + rtx op3 = gen_reg_rtx (DFmode);
- +
- + emit_insn (gen_zero_extendsidi2 (op2, operands[1]));
- + emit_insn (gen_floatdidf2 (op3, op2));
- + emit_insn (gen_truncdfsf2 (operands[0], op3));
- + DONE;
- + }
- + })
- +
- +; Basic Arithmetic
- +; SFmode
- +(define_insn "add<mode>3"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (plus:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx")))]
- + "<fcondition>"
- + "F<FW>\\tADD%?\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*add<FMODES:mode>_if_<CCALL:mode>_cxcxcxcx"
- + [(set (match_operand:FMODES 0 "metag_fpreg_op" "=cx")
- + (if_then_else:FMODES (match_operator 1 "comparison_operator"
- + [(match_operand:CCALL 2 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (plus:FMODES (match_operand:FMODES 3 "metag_fpreg_op" "cx")
- + (match_operand:FMODES 4 "metag_fpreg_op" "cx"))
- + (match_operand:FMODES 5 "metag_fpreg_op" "0")))]
- + "<fcondition>"
- + "F<FMODES:FW>\\tADD%z1\\t%0,%3,%4"
- + [(set_attr "type" "FPmas")
- + (set_attr "ccstate" "xcc")])
- +
- +(define_insn "*nadd<mode>3"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (neg:<MODE>
- + (plus:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx"))))]
- + "<fcondition>"
- + "F<FW>I\\tADD%?\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "mul<mode>3"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (mult:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx")))]
- + "<fcondition>"
- + "F<FW>\\tMUL%?\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*nmul<mode>3"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (neg:<MODE>
- + (mult:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx"))))]
- + "<fcondition>"
- + "F<FW>I\\tMUL%?\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "sub<mode>3"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (minus:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx")))]
- + "<fcondition>"
- + "F<FW>\\tSUB%?\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*sub<FMODES:mode>_if_<CCALL:mode>_cxcxcxcx"
- + [(set (match_operand:FMODES 0 "metag_fpreg_op" "=cx")
- + (if_then_else:FMODES (match_operator 1 "comparison_operator"
- + [(match_operand:CCALL 2 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (minus:FMODES (match_operand:FMODES 3 "metag_fpreg_op" "cx")
- + (match_operand:FMODES 4 "metag_fpreg_op" "cx"))
- + (match_operand:FMODES 5 "metag_fpreg_op" "0")))]
- + "<fcondition>"
- + "F<FMODES:FW>\\tSUB%z1\\t%0,%3,%4"
- + [(set_attr "type" "FPmas")
- + (set_attr "ccstate" "xcc")])
- +
- +(define_insn "*nsub<mode>3"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (neg:<MODE>
- + (minus:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx"))))]
- + "<fcondition>"
- + "F<FW>I\\tSUB%?\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")
- + (set_attr "predicable" "yes")])
- +
- +
- +; Extended Floating Point Insn's
- +; SFmode
- +
- +; TODO MUZ
- +(define_insn "*muladd<mode>3_fused"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (plus:<MODE>
- + (mult:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx"))
- + (match_operand:<MODE> 3 "metag_fpreg_op" "0")))]
- + "<fcondition>"
- + "F<FW>\\tMUZ\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")])
- +
- +(define_insn "*muladd1<mode>3_fused"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (plus:<MODE>
- + (mult:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx"))
- + (match_operand:<MODE> 3 "metag_fpone_imm_op" "H")))]
- + "<fcondition>"
- + "F<FW>\\tMUZ1\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")])
- +
- +(define_insn "*mulsub<mode>3_fused"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (minus:<MODE>
- + (mult:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx"))
- + (match_operand:<MODE> 3 "metag_fpreg_op" "0")))]
- + "<fcondition>"
- + "F<FW>\\tMUZS\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")])
- +
- +(define_insn "*mulsub1<mode>3_fused"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (minus:<MODE>
- + (mult:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx"))
- + (match_operand:<MODE> 3 "metag_fpone_imm_op" "H")))]
- + "<fcondition>"
- + "F<FW>\\tMUZS1\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")])
- +
- +(define_insn "*nmuladd<mode>3_fused"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (neg:<MODE>
- + (plus:<MODE>
- + (mult:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx"))
- + (match_operand:<MODE> 3 "metag_fpreg_op" "0"))))]
- + "<fcondition>"
- + "F<FW>I\\tMUZ\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")])
- +
- +(define_insn "*nmuladd1<mode>3_fused"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (neg:<MODE>
- + (plus:<MODE>
- + (mult:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx"))
- + (match_operand:<MODE> 3 "metag_fpone_imm_op" "H"))))]
- + "<fcondition>"
- + "F<FW>I\\tMUZ1\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")])
- +
- +(define_insn "*nmulsub<mode>3_fused"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (neg:<MODE>
- + (minus:<MODE>
- + (mult:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx"))
- + (match_operand:<MODE> 3 "metag_fpreg_op" "0"))))]
- + "<fcondition>"
- + "F<FW>I\\tMUZS\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")])
- +
- +(define_insn "*nmulsub1<mode>3_fused"
- + [(set (match_operand:FLMODES 0 "metag_fpreg_op" "=cx")
- + (neg:<MODE>
- + (minus:<MODE>
- + (mult:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx"))
- + (match_operand:<MODE> 3 "metag_fpone_imm_op" "H"))))]
- + "<fcondition>"
- + "F<FW>I\\tMUZS1\\t%0,%1,%2"
- + [(set_attr "type" "FPmas")])
- +
- +;; Divides etc
- +
- +(define_expand "divsf3"
- + [(set (match_operand:SF 0 "metag_fpreg_op" "")
- + (div:SF (match_operand:SF 1 "metag_fpreg_op" "")
- + (match_operand:SF 2 "metag_fpreg_op" "")))]
- + "TARGET_FPU && TARGET_FAST_MATH"
- + {
- + })
- +
- +(define_expand "divdf3"
- + [(set (match_operand:DF 0 "metag_fpreg_op" "")
- + (div:DF (match_dup 3)
- + (match_operand:DF 2 "metag_fpreg_op" "")))
- + (set (match_dup 4)
- + (neg:DF (minus:DF (mult:DF (match_dup 2)
- + (match_dup 0))
- + (match_dup 3))))
- + (set (match_dup 0)
- + (plus:DF (mult:DF (match_dup 4)
- + (match_dup 0))
- + (match_dup 0)))
- + (set (match_dup 0)
- + (mult:DF (match_operand:DF 1 "metag_fpreg_op" "")
- + (match_dup 0)))]
- + "TARGET_FPU && !metag_fpu_single && TARGET_FAST_MATH"
- + {
- + operands[3] = CONST1_RTX (DFmode);
- + operands[4] = gen_reg_rtx (DFmode);
- + })
- +
- +(define_insn_and_split "*div<mode>2_fast"
- + [(set (match_operand:FMODES 0 "metag_fpreg_op" "=&cx")
- + (div:<MODE> (match_operand:<MODE> 1 "metag_fpreg_op" "cx")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx")))]
- + "<fcondition> && TARGET_FAST_MATH"
- + "#"
- + "&& 1"
- + [(const_int 0)]
- + {
- + emit_insn (gen_rcp<mode>2 (operands[0], CONST1_RTX (<MODE>mode), operands[2]));
- + emit_insn (gen_mul<mode>3 (operands[0], operands[0], operands[1]));
- + DONE;
- + }
- + [(set_attr "type" "FPrecipmas")])
- +
- +(define_insn "rcp<mode>2"
- + [(set (match_operand:FMODES 0 "metag_fpreg_op" "=cx")
- + (div:<MODE> (match_operand:<MODE> 1 "metag_fpone_imm_op" "H")
- + (match_operand:<MODE> 2 "metag_fpreg_op" "cx")))]
- + "<fcondition> && TARGET_FAST_MATH"
- + {
- + if (TARGET_FLUSH_TO_ZERO)
- + return "F<FW>Z\\tRCP\\t%0,%2";
- + else
- + return "F<FW>\\tRCP\\t%0,%2";
- + }
- + [(set_attr "type" "FPrecip")])
- +
- +(define_insn "*rsq<mode>2"
- + [(set (match_operand:FMODES 0 "metag_fpreg_op" "=cx")
- + (div:<MODE> (match_operand:<MODE> 1 "metag_fpone_imm_op" "H")
- + (sqrt:<MODE> (match_operand:<MODE> 2 "metag_fpreg_op" "cx"))))]
- + "<fcondition> && TARGET_FAST_MATH"
- + {
- + if (TARGET_FLUSH_TO_ZERO)
- + return "F<FW>Z\\tRSQ\\t%0,%2";
- + else
- + return "F<FW>\\tRSQ\\t%0,%2";
- + }
- + [(set_attr "type" "FPrecip")])
- +
- +; ADDRE, MULRE, and SUBRE need vector modes
- +; Memory operations all use core instrutions with U[sd]=9
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/lib1funcs.asm gcc-4.2.4/gcc/config/metag/lib1funcs.asm
- --- gcc-4.2.4.orig/gcc/config/metag/lib1funcs.asm 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/lib1funcs.asm 2015-07-03 18:46:05.749283542 -0500
- @@ -0,0 +1,2740 @@
- +/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
- + Imagination Technologies Ltd
- +
- +This file is part of GCC.
- +
- +GCC 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 3, or (at your option) any later
- +version.
- +
- +GCC 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.
- +
- +Under Section 7 of GPL version 3, you are granted additional
- +permissions described in the GCC Runtime Library Exception, version
- +3.1, as published by the Free Software Foundation.
- +
- +You should have received a copy of the GNU General Public License and
- +a copy of the GCC Runtime Library Exception along with this program;
- +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
- +<http://www.gnu.org/licenses/>. */
- +
- +/* As a special exception, if you link this library with other files,
- + some of which are compiled with GCC, to produce an executable,
- + this library does not by itself cause the resulting executable
- + to be covered by the GNU General Public License.
- + This exception does not however invalidate any other reasons why
- + the executable file might be covered by the GNU General Public License. */
- +
- +!! libgcc1 routines for META cpu.
- +!! Contributed by Metagence Technologies (toolkit@metagence.com)
- +
- +!! Division routines
- +
- +#ifdef L_udivsi3
- +!!
- +!! 32-bit division unsigned i/p - passed unsigned 32-bit numbers
- +!!
- + .text
- + .global ___udivsi3
- + .type ___udivsi3,function
- + .align 2
- +___udivsi3:
- +!!
- +!! Since core is signed divide case, just set control variable
- +!!
- + MOV D1Re0,D0Ar2 ! Au already in A1Ar1, Bu -> D1Re0
- + MOV D0Re0,#0 ! Result is 0
- + MOV D0Ar4,#0 ! Return positive result
- + B __IDMCUStart
- + .size ___udivsi3,.-___udivsi3
- +#endif
- +
- +#ifdef L_divsi3
- +!!
- +!! 32-bit division signed i/p - passed signed 32-bit numbers
- +!!
- + .text
- + .global ___divsi3
- + .type ___divsi3,function
- + .align 2
- +___divsi3:
- +!!
- +!! A already in D1Ar1, B already in D0Ar2 -> make B abs(B)
- +!!
- + MOV D1Re0,D0Ar2 ! A already in A1Ar1, B -> D1Re0
- + MOV D0Re0,#0 ! Result is 0
- + XOR D0Ar4,D1Ar1,D1Re0 ! D0Ar4 -ive if result is -ive
- + ABS D1Ar1,D1Ar1 ! abs(A) -> Au
- + ABS D1Re0,D1Re0 ! abs(B) -> Bu
- + .global __IDMCUStart
- + .hidden __IDMCUStart
- +__IDMCUStart:
- + CMP D1Ar1,D1Re0 ! Is ( Au > Bu )?
- + LSR D1Ar3,D1Ar1,#2 ! Calculate (Au & (~3)) >> 2
- + CMPHI D1Re0,D1Ar3 ! OR ( (Au & (~3)) <= (Bu << 2) )?
- + LSLSHI D1Ar3,D1Re0,#1 ! Buq = Bu << 1
- + BLS $IDMCUSetup ! Yes: Do normal divide
- +!!
- +!! Quick divide setup can assume that CurBit only needs to start at 2
- +!!
- +$IDMCQuick:
- + CMP D1Ar1,D1Ar3 ! ( A >= Buq )?
- + ADDCC D0Re0,D0Re0,#2 ! If yes result += 2
- + SUBCC D1Ar1,D1Ar1,D1Ar3 ! and A -= Buq
- + CMP D1Ar1,D1Re0 ! ( A >= Bu )?
- + ADDCC D0Re0,D0Re0,#1 ! If yes result += 1
- + SUBCC D1Ar1,D1Ar1,D1Re0 ! and A -= Bu
- + ORS D0Ar4,D0Ar4,D0Ar4 ! Return neg result?
- + NEG D0Ar2,D0Re0 ! Calulate neg result
- + MOVMI D0Re0,D0Ar2 ! Yes: Take neg result
- +$IDMCRet:
- + MOV PC,D1RtP
- +!!
- +!! Setup for general unsigned divide code
- +!!
- +!! D0Re0 is used to form the result, already set to Zero
- +!! D1Re0 is the input Bu value, this gets trashed
- +!! D0Ar6 is curbit which is set to 1 at the start and shifted up
- +!! D0Ar4 is negative if we should return a negative result
- +!! D1Ar1 is the input Au value, eventually this holds the remainder
- +!!
- +$IDMCUSetup:
- + CMP D1Ar1,D1Re0 ! Is ( Au < Bu )?
- + MOV D0Ar6,#1 ! Set curbit to 1
- + BCS $IDMCRet ! Yes: Return 0 remainder Au
- +!!
- +!! Calculate alignment using FFB instruction
- +!!
- + FFB D1Ar5,D1Ar1 ! Find first bit of Au
- + ANDN D1Ar5,D1Ar5,#31 ! Handle exceptional case.
- + ORN D1Ar5,D1Ar5,#31 ! if N bit set, set to 31
- + FFB D1Ar3,D1Re0 ! Find first bit of Bu
- + ANDN D1Ar3,D1Ar3,#31 ! Handle exceptional case.
- + ORN D1Ar3,D1Ar3,#31 ! if N bit set, set to 31
- + SUBS D1Ar3,D1Ar5,D1Ar3 ! calculate diff, ffbA - ffbB
- + MOV D0Ar2,D1Ar3 ! copy into bank 0
- + LSLGT D1Re0,D1Re0,D1Ar3 ! ( > 0) ? left shift B
- + LSLGT D0Ar6,D0Ar6,D0Ar2 ! ( > 0) ? left shift curbit
- +!!
- +!! Now we start the divide proper, logic is
- +!!
- +!! if ( A >= B ) add curbit to result and subtract B from A
- +!! shift curbit and B down by 1 in either case
- +!!
- +$IDMCLoop:
- + CMP D1Ar1, D1Re0 ! ( A >= B )?
- + ADDCC D0Re0, D0Re0, D0Ar6 ! If yes result += curbit
- + SUBCC D1Ar1, D1Ar1, D1Re0 ! and A -= B
- + LSRS D0Ar6, D0Ar6, #1 ! Shift down curbit, is it zero?
- + LSR D1Re0, D1Re0, #1 ! Shift down B
- + BNZ $IDMCLoop ! Was single bit in curbit lost?
- + ORS D0Ar4,D0Ar4,D0Ar4 ! Return neg result?
- + NEG D0Ar2,D0Re0 ! Calulate neg result
- + MOVMI D0Re0,D0Ar2 ! Yes: Take neg result
- + MOV PC,D1RtP
- + .size ___divsi3,.-___divsi3
- +#endif
- +
- +!! Modulus routines
- +
- +#ifdef L_umodsi3
- +!!
- +!! 32-bit modulus unsigned i/p - passed unsigned 32-bit numbers
- +!!
- + .text
- + .global ___umodsi3
- + .type ___umodsi3,function
- + .align 2
- +___umodsi3:
- +#ifdef __PIC__
- + SETL [A0StP++],D0FrT,D1RtP ! Save return address
- + CALLR D1RtP,___udivsi3@PLT
- + GETL D0FrT,D1RtP,[--A0StP] ! Recover return address
- +#else
- + MOV D0FrT,DRtP ! Save original return address
- + CALLR D1RtP,___udivsi3
- + MOV D1RtP,D0FrT ! Recover return address
- +#endif
- + MOV D0Re0,D1Ar1 ! Return remainder
- + MOV PC,D1RtP
- + .size ___umodsi3,.-___umodsi3
- +#endif
- +
- +#ifdef L_modsi3
- +!!
- +!! 32-bit modulus signed i/p - passed signed 32-bit numbers
- +!!
- + .text
- + .global ___modsi3
- + .type ___modsi3,function
- + .align 2
- +___modsi3:
- +#ifdef __PIC__
- + MOV D0.4,D1Ar1
- + SETL [A0StP++],D0.4,D1RtP ! Save A and return address
- + CALLR D1RtP,___divsi3@PLT
- + GETL D0.4,D1RtP,[--A0StP] ! Recover A and return address
- + MOV D1Re0,D0.4
- +#else
- + MOV D0FrT,D1RtP ! Save original return address
- + MOV A0.2,D1Ar1 ! Save A in A0.2
- + CALLR D1RtP,___divsi3
- + MOV D1RtP,D0FrT ! Recover return address
- + MOV D1Re0,A0.2 ! Recover A
- +#endif
- + MOV D0Re0,D1Ar1 ! Return remainder
- + ORS D1Re0,D1Re0,D1Re0 ! Was A negative?
- + NEG D1Ar1,D1Ar1 ! Negate remainder
- + MOVMI D0Re0,D1Ar1 ! Return neg remainder
- + MOV PC, D1RtP
- + .size ___modsi3,.-___modsi3
- +#endif
- +
- +!! Floating point support routines
- +
- +#ifdef L_adddf3
- +!!
- +!! Floating point - double add
- +!!
- + .text
- + .global ___adddf3
- + .type ___adddf3,function
- + .align 2
- +___adddf3:
- + AND D1Re0, D1Ar1, D1Ar3
- + ANDT D1Re0, D1Re0, #0x8000 ! sign1 & sign2
- +
- + LSL D0Re0, D1Ar1, #1 ! Ignore sign
- + ORS D0Re0, D0Re0, D0Ar2 ! Zero?
- +
- + LSL D0Re0, D1Ar3, #1 ! Ignore sign
- + ORSZ D0Re0, D0Re0, D0Ar4 ! Zero
- +
- + MOVZ PC, D1RtP ! both zero return +/-Zero
- +
- + LSL D0Re0, D1Ar1, #1 ! Ignore sign
- + ORS D0Re0, D0Re0, D0Ar2 ! Zero?
- +
- + MOVZ D0Re0, D0Ar4
- + MOVZ D1Re0, D1Ar3
- + MOVZ PC, D1RtP ! Arg1 zero return Arg2
- +
- + LSL D0Re0, D1Ar3, #1 ! Ignore sign
- + ORS D0Re0, D0Re0, D0Ar4 ! Zero?
- +
- + MOVZ D1Re0, D1Ar1
- + MOVZ D0Re0, D0Ar2
- + MOVZ PC, D1RtP ! Arg2 zero return Arg1
- +
- + MOV D1Ar5, D1Ar1
- + ANDMT D1Ar5, D1Ar5, #0x7FFF
- + LSR D1Ar5, D1Ar5, #20 ! exp1
- +
- + MOV D0Ar6, D1Ar3
- + ANDMT D0Ar6, D0Ar6, #0x7FFF
- + LSR D0Ar6, D0Ar6, #20 ! exp2
- +
- + MOV D0Re0, D1Ar5
- + SUBS D1Re0, D0Re0, D0Ar6 ! exp = exp1 - exp2 ---> D1Re0
- + BGE $L2
- +
- + SWAP D0Re0, D1Ar3 ! mant1 <-> mant2
- + SWAP D0Re0, D1Ar1
- + SWAP D0Re0, D1Ar3
- +
- + SWAP D1Re0, D0Ar4
- + SWAP D1Re0, D0Ar2
- + SWAP D1Re0, D0Ar4
- +
- + SWAP D0Ar6, D1Ar5 ! exp1 <-> exp2
- + NEG D1Re0, D1Re0 ! exp = -exp
- +
- +$L2:
- + CMP D1Re0, #54
- + BLE $L3
- +
- + MOV D1Re0, D1Ar1
- + MOV D0Re0, D0Ar2
- +
- + MOV PC, D1RtP
- +
- +$L3:
- + SWAP D1Re0, D0Re0
- +
- + ADDS D1Ar1, D1Ar1, #0
- + ANDMT D1Ar1, D1Ar1, #0x000F
- + ORT D1Ar1, D1Ar1, #0x0010
- + LSL D1Ar1, D1Ar1, #9
- +
- + LSR D1Re0, D0Ar2, #23
- + OR D1Ar1, D1Ar1, D1Re0
- + LSL D0Ar2, D0Ar2, #9 ! man1 <<= 9 ---> D1Ar1:D0Ar2
- +
- + BGE $L4
- +
- + NEGS D0Ar2, D0Ar2
- + NEG D1Ar1, D1Ar1
- + SUBNZ D1Ar1, D1Ar1, #1 ! man1 D1Ar1:D0Ar2
- +
- +$L4:
- + ADDS D1Ar3, D1Ar3, #0
- + ANDMT D1Ar3, D1Ar3, #0x000F
- + ORT D1Ar3, D1Ar3, #0x0010
- + LSL D1Ar3, D1Ar3, #9
- +
- + LSR D1Re0, D0Ar4, #23
- + OR D1Ar3, D1Ar3, D1Re0
- + LSL D0Ar4, D0Ar4, #9 ! man2 <<= 9 --->D1Ar3, D0Ar4
- +
- + BGE $L5
- +
- + NEGS D0Ar4, D0Ar4
- + NEG D1Ar3, D1Ar3
- + SUBNZ D1Ar3, D1Ar3, #1 ! man2 D1Ar3:D0Ar4
- +
- +$L5:
- + SWAP D1Re0, D0Re0
- + CMP D1Re0, #32 ! ought to consider 32 <= exp1 - exp2 <64
- + BGE $L6
- +
- + CMP D1Re0, #0 ! Zero is a special case
- + BZ $L7
- +
- + MOV D0Re0, D1Re0
- + NEG D0Re0, D0Re0
- + ADD D0Re0, D0Re0, #32 ! 32 + (- (exp1 - exp2))
- + ! man2 D1Ar3:D0Ar4
- + MOV D0Ar6, D1Re0 ! man2 >> exp1 - exp2
- + LSR D0Ar4, D0Ar4, D0Ar6
- + MOV D0Ar6, D1Ar3
- + LSL D0Ar6, D0Ar6, D0Re0
- + OR D0Ar4, D0Ar4, D0Ar6
- + ASR D1Ar3, D1Ar3, D1Re0
- + B $L7
- +
- +$L6: ! exp >= 32
- + SUB D1Re0, D1Re0, #32
- + ASRS D0Ar4, D1Ar3, D1Re0 ! man2 >>= exp
- + MOV D1Ar3, #-1
- + ADDGE D1Ar3, D1Ar3, #1
- +
- +$L7: ! man (D1Re0:D1Re0)
- + ADDS D0Re0, D0Ar2, D0Ar4 ! man = man1 + man2
- + ADD D1Re0, D1Ar1, D1Ar3
- + ADDCS D1Re0, D1Re0, #1
- +
- + MOV D0Ar6, #0 ! assume sign +ve
- +
- + CMP D1Re0, #0 ! man < 0 ?
- + BGT $L9
- + BLT $L8
- +
- + CMP D0Re0, #0
- +
- + MOVZ PC, D1RtP ! man == 0 return 0
- +
- +$L8:
- + CMP D1Re0, #0 ! man < 0
- + BZ $L9 ! treat D1Re0 0 as positive
- +
- + MOVT D0Ar6, #0x8000 ! sign -ve
- +
- + ! man D1Re0:D0Re0
- + NEGS D0Re0, D0Re0 ! man = -man
- + NEG D1Re0, D1Re0
- + SUBNZ D1Re0, D1Re0, #1
- +
- +$L9: ! man +ve
- + NORM D1Ar1, D1Re0
- + BZ $L10 ! MSword zero
- +
- + CMP D1Ar1, #0 ! Already normalised ?
- + BZ $L11 ! yes, skip normlisation
- +
- + MOV D0Ar2, D1Re0 ! Shifting < 32 bits
- + FFB D0Ar2, D0Ar2
- +
- + LSL D1Re0, D1Re0, D1Ar1 ! MSWord
- + ADD D0Ar2, D0Ar2, #2
- + LSR D1Ar3, D0Re0, D0Ar2
- + OR D1Re0, D1Re0, D1Ar3
- +
- + MOV D0Ar2, D1Ar1
- + LSL D0Re0, D0Re0, D0Ar2 ! LSWord
- +
- + SUB D1Ar5, D1Ar5, D1Ar1 ! exp -= NORM (man)
- + B $L11
- +
- +$L10: ! Shifting >= 32 bits
- + MOVS D1Re0, D0Re0 ! Shift by 32 bits.
- + SUBGT D0Re0, D0Re0, D0Re0
- +
- + LSRLT D1Re0, D1Re0, #1 ! If the results has MSBit set the
- + LSLLT D0Re0, D0Re0, #31 ! we must only shift by 31 bits so
- + ! we dont use NORM on a neg value.
- +
- + SUBLT D1Ar5, D1Ar5, #31 ! adjust exponent
- + SUBGE D1Ar5, D1Ar5, #32
- +
- + NORM D1Ar1, D1Re0
- +
- +
- + NEG D0Ar4, D1Ar1 ! (32 - D1Ar1)
- + ADD D0Ar4, D0Ar4, #32
- +
- + LSR D0Ar4, D0Re0, D0Ar4
- + MOV D0Ar2, D1Ar1
- + LSL D0Re0, D0Re0, D0Ar2
- + OR D0Re0, D0Re0, D0Ar4
- + LSL D1Re0, D1Re0, D1Ar1
- +
- + SUB D1Ar5, D1Ar5, D1Ar1 ! exp -= NORM (man)
- +
- +$L11:
- + ADD D1Ar5, D1Ar5, #(10-9)
- +
- + TST D0Re0, #(1<<10)
- + BZ $L12
- +
- + ADDS D0Re0, D0Re0, #1 ! man += 1
- + ADDCS D1Re0, D1Re0, #1
- +
- +$L12:
- + ADDS D0Re0, D0Re0, #((1<<9)-1)
- + ADDCS D1Re0, D1Re0, #1
- +
- + TSTT D1Re0, #0x8000 ! rounding overflowed?
- + BZ $L14
- +
- + ! adjust man and exp
- + LSR D0Re0, D0Re0, #1 ! man >>= 1
- + LSL D0Ar2, D1Re0, #(32-1)
- + LSR D1Re0, D1Re0, #1
- + OR D0Re0, D0Re0, D0Ar2
- +
- + ADD D1Ar5, D1Ar5, #1 ! exp += 1
- +
- +$L14:
- + CMP D1Ar5, #0 ! exp <= 0 ?
- + SUBLE D0Re0, D0Re0, D0Re0 ! underflow
- + MOVLE D1Re0, D1Ar3
- + MOVLE PC, D1RtP ! return +/-Zero
- +
- + LSR D0Re0, D0Re0, #10
- + LSL D0Ar4, D1Re0, #(32-10)
- + OR D0Re0, D0Re0, D0Ar4
- + LSR D1Re0, D1Re0, #10 ! man >>= 10
- +
- + ANDMT D1Re0, D1Re0, #0x000F
- + LSL D1Ar5, D1Ar5, #(52 - 32) ! position exp
- + MOV D1Ar3, D0Ar6
- + OR D1Ar5, D1Ar5, D1Ar3 ! sign|exp
- + OR D1Re0, D1Re0, D1Ar5 ! man|exp|sign -> D1Re0, D0Re0
- +
- + MOV PC, D1RtP
- + .size ___adddf3,.-___adddf3
- +#endif
- +
- +#ifdef L_addsf3
- +!!
- +!! Floating point - float add
- +!!
- + .text
- + .global ___addsf3
- + .type ___addsf3,function
- + .align 2
- +___addsf3:
- + MOV D1Re0, D0Ar2
- + AND D1Re0, D1Re0, D1Ar1
- + ANDT D1Re0, D1Re0, #0x8000 ! sign = sign1 & sign2
- +
- + LSLS D0Re0, D1Ar1, #1 ! Ignore sign bit
- + LSL D0Re0, D0Ar2, #1
- + ORSZ D0Re0, D0Re0, D0Re0
- +
- + MOVZ D0Re0, D1Re0 ! sign = sign1 & sign2
- + MOVZ PC, D1RtP ! both zero return +/-Zero
- +
- + LSLS D0Re0, D1Ar1, #1 ! Ignore sign bit
- + MOVZ D0Re0, D0Ar2
- + MOVZ PC, D1RtP ! Arg1 zero return Arg2
- +
- + LSLS D0Re0, D0Ar2, #1 ! Ignore sign bit
- + MOVZ D0Re0, D1Ar1
- + MOVZ PC, D1RtP ! Arg2 zero return Arg1
- +
- + MOV D1Ar5, D1Ar1
- + ANDMT D1Ar5, D1Ar5, #0x7FFF
- + LSR D1Ar5, D1Ar5, #23 ! exp1
- +
- + MOV D1Ar3, D0Ar2
- + ANDMT D1Ar3, D1Ar3, #0x7FFF
- + LSR D1Ar3, D1Ar3, #23 ! exp2
- +
- + SUB D0Re0, D1Ar5, D1Ar3 ! exp1 - exp2
- + CMP D0Re0, #25 ! >25
- +
- + MOVGT D0Re0, D1Ar1
- + MOVGT PC, D1RtP
- +
- + CMP D0Re0, #-25 ! <-25
- +
- + MOVLT D0Re0, D0Ar2
- + MOVLT PC, D1RtP
- +
- + MOV D0Ar6, D1Ar1
- + ANDMT D0Ar6, D0Ar6, #0x007F
- + ORT D0Ar6, D0Ar6, #0x0080 ! man1
- + LSL D0Ar6, D0Ar6, #6 ! man1 <<= 6
- +
- + MOV D0Ar4, D0Ar2
- + ANDMT D0Ar4, D0Ar4, #0x007F
- + ORT D0Ar4, D0Ar4, #0x0080 ! man2
- + LSL D0Ar4, D0Ar4, #6 ! man2 <<= 6
- +
- + CMP D1Ar1, #0
- + BGE $L4
- +
- + NEG D0Ar6, D0Ar6 ! man1 = -man1
- +
- +$L4:
- + CMP D0Ar2, #0
- + BGE $L5
- +
- + NEG D0Ar4, D0Ar4 ! man2 = -man2
- +
- +$L5:
- + CMP D0Re0, #0 ! D0Re0 = exp1 - exp2
- + BGE $L6
- +
- + NEG D0Re0, D0Re0
- + ASR D0Ar6, D0Ar6, D0Re0 ! man1 >> (exp2 - exp1)
- + MOV D1Ar5, D1Ar3 ! D1Ar5 = exp2
- + B $L7
- +
- +$L6:
- + ASR D0Ar4, D0Ar4, D0Re0 ! man2 >> (exp1 - exp2)
- +
- +$L7:
- + ADDS D0Re0, D0Ar6, D0Ar4 ! man = man1 + man2
- + MOV D1Re0, #0 ! --> sign
- + MOVZ PC, D1RtP
- +
- + BGT $L8
- + MOVT D1Re0, #0x8000 ! --->sign
- + NEG D0Re0, D0Re0
- +
- +$L8:
- + MOV D0Ar4, D0Re0 ! man
- + ANDT D0Ar4, D0Ar4, #0xE000
- + CMP D0Ar4, #0
- + BNE $L9
- +
- + LSL D0Re0, D0Re0, #1
- + SUB D1Ar5, D1Ar5, #1
- + B $L8
- +
- +$L9:
- + MOV D0Ar4, D0Re0 ! D0Ar4 = man
- + ANDT D0Re0, D0Re0, #0x4000
- + CMP D0Re0, #0
- + BZ $L11
- +
- + LSR D0Ar4, D0Ar4, #1
- + ADD D1Ar5, D1Ar5, #1
- +
- +$L11:
- + MOV D0Ar6, D0Ar4
- + AND D0Ar6, D0Ar6, #0x40
- + CMP D0Ar6, #0
- + ADDNZ D0Ar4, D0Ar4, #1
- + ADD D0Ar4, D0Ar4, #0x1F
- + MOV D0Ar6, D0Ar4
- + ANDT D0Ar6, D0Ar6, #0x4000
- + CMP D0Ar6, #0
- + BZ $L13
- +
- + ASR D0Ar4, D0Ar4, #1
- + ADD D1Ar5, D1Ar5, #1
- +
- +$L13:
- + CMP D1Ar5, #0 ! exp <= 0 ?
- + MOVLE D0Re0, D1Re0 ! underflow
- + MOVLE PC, D1RtP ! return +/-Zero
- +
- + LSR D0Ar4, D0Ar4, #6 ! man >>= 6
- + MOV D0Ar6, D1Ar5
- + LSL D0Ar6, D0Ar6, #23
- +
- + MOV D0Re0, D1Re0
- + OR D0Re0, D0Re0, D0Ar6
- + ANDMT D0Ar4, D0Ar4, #0x007F
- + OR D0Re0, D0Re0, D0Ar4
- +
- + MOV PC, D1RtP
- + .size ___addsf3,.-___addsf3
- +#endif
- +
- +#ifdef L_subdf3
- +!!
- +!! Floating point - double sub
- +!!
- + .text
- + .global ___subdf3
- + .type ___subdf3,function
- + .align 2
- +___subdf3:
- + MOV D1Re0, D0Ar4
- + ORS D0Re0, D1Ar3, D1Re0
- + MOVZ D1Re0, D1Ar1
- + MOVZ D0Re0, D0Ar2
- + MOVZ PC, D1RtP
- + XORT D1Ar3, D1Ar3, #0x8000
- +#ifdef __PIC__
- + B ___adddf3@PLT
- +#else
- + B ___adddf3
- +#endif
- + .size ___subdf3,.-___subdf3
- +#endif
- +
- +#ifdef L_addsf3
- +!!
- +!! Floating point - float sub
- +!!
- + .text
- + .global ___subsf3
- + .type ___subsf3,function
- + .align 2
- +___subsf3:
- + CMP D0Ar2, #0
- + MOVZ D0Re0, D1Ar1
- + MOVZ PC, D1RtP
- + XORT D0Ar2, D0Ar2, #0x8000
- +#ifdef __PIC__
- + B ___addsf3@PLT
- +#else
- + B ___addsf3
- +#endif
- + .size ___subsf3,.-___subsf3
- +#endif
- +
- +#ifdef L_negdf2
- +!!
- +!! Floating point - double negate
- +!!
- + .text
- + .global ___negdf2
- + .type ___negdf2,function
- + .align 2
- +___negdf2:
- + MOV D0Re0, D0Ar2
- + MOV D1Re0, D1Ar1
- + XORT D1Re0, D1Re0, #0x8000
- + MOV PC, D1RtP
- + .size ___negdf2,.-___negdf2
- +#endif
- +
- +#ifdef L_negsf2
- +!!
- +!! Floating point - double negate
- +!!
- + .text
- + .global ___negsf2
- + .type ___negsf2,function
- + .align 2
- +___negsf2:
- + MOV D0Re0, D1Ar1
- + XORT D0Re0, D0Re0, #0x8000
- + MOV PC, D1RtP
- + .size ___negsf2,.-___negsf2
- +#endif
- +
- +#ifdef L_cmpdf2
- +!!
- +!! Compare two double(s)
- +!! return -1 if <
- +!! 0 if ==
- +!! +1 if >
- + .text
- + .global ___cmpdf2
- + .type ___cmpdf2,function
- + .align 2
- +___cmpdf2:
- + LSR A0.2, D1Ar1, #31 ! sign1
- + LSR A0.3, D1Ar3, #31 ! sign2
- +
- + LSR D1Ar5, D1Ar1, #(52-32) ! exp1
- + AND D1Ar5, D1Ar5, #0x07FF
- +
- + LSR D0Ar6, D1Ar3, #(52-32) ! exp2
- + AND D0Ar6, D0Ar6, #0x07FF
- +
- + ANDMT D1Ar1, D1Ar1, #0x000F ! mant1
- + ANDMT D1Ar3, D1Ar3, #0x000F ! mant1
- +
- +!!
- +!! if (D_NAN_P (dp1) || D_NAN_P (dp2))
- +!! return 1;
- +
- + MOV D0Re0, #1
- +
- + CMP D1Ar5, #0x07FF ! exp1 == 0x07FF
- + BNE $L1
- +
- + ORS D1Re0, D1Ar1, D1Ar1 ! HI(mant1) == 0?
- + ORSZ D1Re0, D0Ar2, D0Ar2 ! and LO(mant1) == 0?
- + MOVNZ PC, D1RtP ! no, Nan, return 1
- +
- + B $L2
- +
- +$L1:
- +
- + CMP D0Ar6, #0x07FF ! exp2 == 0x07FF
- + BNE $L2
- +
- + ORS D1Re0, D1Ar3, D1Ar3 ! HI(mant2) == 0 ?
- + ORSZ D1Re0, D0Ar4, D0Ar4 ! and LO(mant2) == 0 ?
- + MOVNZ PC, D1RtP ! no, Nan, return 1
- +
- +$L2:
- +!!
- +!! if (D_INF_P (dp1) && D_INF_P (dp2))
- +!! return sign2 - sign1;
- +!!
- +
- + SUB D0Re0, A0.3, A0.2
- +
- + MOV D1Re0, D0Ar6
- + AND D1Re0, D1Re0, D1Ar5
- + CMP D1Re0, #0x7FF ! (exp1 & exp2) == 0x7FF
- +
- + CMPEQ D1Ar1,D1Ar3
- + CMPEQ D0Ar2,D0Ar4 ! mant1 == mant2
- + CMPEQ D1Ar1, #0
- + CMPEQ D0Ar2, #0 ! == 0
- + MOVEQ PC, D1RtP
- +
- +!! if (D_INF_P (dp1))
- +!! return sign1 ? -1 : 1;
- +
- + MOV D0Re0, #0 ! result
- + MOV D1Re0, A0.2
- + TST D1Re0, #1 ! sign1 ?
- + SUBNZ D0Re0, D0Re0, #1 ! -1
- + ADDZ D0Re0, D0Re0, #1 ! +1
- +
- + CMP D1Ar5, #0x7FF ! exp1 == 0x7FF
- + MOVEQ D1Re0, D0Ar2
- + ORSEQ D1Re0, D1Re0, D1Ar1 ! mant1 == 0
- + MOVEQ PC, D1RtP
- +
- +!!
- +!! if (D_INF_P (dp2))
- +!! return sign2 ? 1 : -1;
- +
- + MOV D0Re0, #0 ! result
- + MOV D1Re0, A0.3
- + TST D1Re0, #1 ! sign2 ?
- + ADDNZ D0Re0, D0Re0, #1 ! +1
- + SUBZ D0Re0, D0Re0, #1 ! -1
- +
- + CMP D0Ar6, #0x7FF ! exp2 == 0x7FF
- + MOVEQ D1Re0, D0Ar4
- + ORSEQ D1Re0, D1Re0, D1Ar3 ! mant2 == 0
- + MOVEQ PC, D1RtP
- +
- +!!
- +!! if (D_ZERO_P (dp1) && D_ZERO_P (dp2))
- +!! return 0;
- +
- + MOV D0Re0, #0
- + MOV D1Re0, D0Ar6
- + ORS D1Re0, D1Re0, D1Ar5 ! exp1 | exp1
- + ORSZ D1Re0, D1Ar1, D1Ar3 ! mant1 | mant2
- + ORSZ D1Re0, D0Ar2, D0Ar4
- + MOVZ PC, D1RtP ! both zero return 0
- +!!
- +!! if (D_ZERO_P (dp1))
- +!! return sign2 ? 1 : -1;
- +!!
- +
- + ! result (D0Re0) already 0
- + MOV D1Re0, A0.3
- + TST D1Re0, #1 ! sign2?
- + ADDNZ D0Re0, D0Re0, #1 ! +1
- + SUBZ D0Re0, D0Re0, #1 ! -1
- +
- + ORS D1Re0, D1Ar5, D1Ar5 ! exp1 == 0
- + ORSZ D1Re0, D1Ar1, D1Ar1 ! and mant1 == 0
- + ORSZ D1Re0, D0Ar2, D0Ar2
- + MOVZ PC, D1RtP
- +
- +!! if (D_ZERO_P (dp2))
- +!! return sign1 ? -1 : 1;
- +
- + MOV D0Re0, #0 ! result
- + MOV D1Re0, A0.2
- + TST D1Re0, #1 ! sign1?
- + SUBNZ D0Re0, D0Re0, #1 ! -1
- + ADDZ D0Re0, D0Re0, #1 ! +1
- +
- + ORS D1Re0, D0Ar6, D0Ar6 ! exp2 == 0
- + ORSZ D1Re0, D1Ar3, D1Ar3 ! and mant2 == 0
- + ORSZ D1Re0, D0Ar4, D0Ar4
- + MOVZ PC, D1RtP
- +
- +!! /* Normalize the numbers. */
- +!! D_NORMALIZE (dp1, exp1, mant1);
- +!! D_NORMALIZE (dp2, exp2, mant2);
- +
- +!! now both are "normal".
- +
- + MOV D0Re0, #0 ! result
- + MOV D1Re0,A0.2
- + TST D1Re0, #1 ! sign1
- + SUBNZ D0Re0, D0Re0, #1 ! -1
- + ADDZ D0Re0, D0Re0, #1 ! +1
- +
- + SUB D1Re0, A0.2, A0.3
- + CMP D1Re0, #0 ! sign1 != sign2
- + MOVNE PC, D1RtP ! yes, return sign1 ? -1 : +1
- +
- + MOV D1Re0, D0Ar6
- + CMP D1Ar5, D1Re0 ! exp1 > exp2
- + MOVGT PC, D1RtP ! yes, return sign1 ? -1 : +1
- +
- + NEG D0Re0, D0Re0 ! result -= result
- + MOVLT PC, D1RtP ! exp < exp2 return -(sign1 ? -1 : +1)
- +
- + CMP D1Ar1, D1Ar3 ! HI(mant1) < HI(mant2)
- + CMPEQ D0Ar2, D0Ar4 ! LO(mant1) < LO(mant2)
- + MOVLO PC, D1RtP ! yes, return -(sign1 ? -1 : +1)
- +
- + NEG D0Re0, D0Re0 ! result = -result
- + MOVHI PC, D1RtP ! > return sign1 ? -1 : +1
- +
- + MOV D0Re0, #0
- + MOV PC, D1RtP
- + .size ___cmpdf2,.-___cmpdf2
- +#endif
- +
- +#ifdef L_cmpdf2_nan
- +!!
- +!! Filters for Nan arguments before calling ___cmpdf2
- +!!
- +!! If either Arg1 or Arg2 is Nan then return Arg3 (D1Ar5)
- +!! otherwise tail calls ___cmpdf2
- +!!
- + .text
- + .global ___cmpdf2_nan
- + .type ___cmpdf2_nan,function
- + .align 2
- +___cmpdf2_nan:
- + LSR D1Re0, D1Ar1, #(52-32) ! arg1 NAN ?
- + AND D1Re0, D1Re0, #0x07FF
- + CMP D1Re0, #0x07FF ! exp all 1s
- + BNE $L10
- +
- + MOV D0Ar6, D1Ar1
- + LSL D0Ar6, D0Ar6, #(64-52) ! mantisa non-zero?
- + ORS D0Ar6, D0Ar6, D0Ar2
- + MOVNZ D0Re0, D1Ar5
- + MOVNZ PC, D1RtP ! return (D1Ar3)
- +
- +$L10:
- + LSR D1Re0, D1Ar3, #(52-32) ! arg2 NAN ?
- + AND D1Re0, D1Re0, #0x07FF
- + CMP D1Re0, #0x07FF ! exp all 1s
- + BNE $L11
- +
- + MOV D0Ar6, D1Ar3
- + LSL D0Ar6, D0Ar6, #(64-52) ! mantisa non-zero?
- + ORS D0Ar6, D0Ar6, D0Ar4
- + MOVNZ D0Re0, D1Ar5
- + MOVNZ PC, D1RtP ! return (D1Ar3)
- +
- +$L11:
- +#ifdef __PIC__
- + B ___cmpdf2@PLT
- +#else
- + B ___cmpdf2
- +#endif
- + .size ___cmpdf2_nan,.-___cmpdf2_nan
- +#endif
- +
- +#ifdef L_cmpsf2
- +!!
- +!! Compare two float(s)
- +!! return -1 if <
- +!! 0 if ==
- +!! +1 if >
- +!!
- + .text
- + .global ___cmpsf2
- + .type ___cmpsf2,function
- + .align 2
- +___cmpsf2:
- + LSR D1Ar3, D1Ar1, #31 ! sign1
- + LSR D1Ar5, D0Ar2, #31 ! sign2
- +
- + LSR D0Ar4, D1Ar1, #23 ! exp1
- + AND D0Ar4, D0Ar4, #0x00FF
- +
- + LSR D0Ar6, D0Ar2, #23 ! exp2
- + AND D0Ar6, D0Ar6, #0x00FF
- +
- + ANDMT D1Ar1, D1Ar1, #0x007F ! mant1
- + ANDMT D0Ar2, D0Ar2, #0x007F ! mant2
- +
- +!! if (F_NAN_P (fp1) || F_NAN_P (fp2))
- +!! return 1;
- +
- + MOV D0Re0, #1
- +
- + CMP D0Ar4, #0xFF ! exp1 == 0xFF?
- + BNE $L1
- +
- + CMP D1Ar1, #0 ! and mant1 == 0?
- + MOVNZ PC, D1RtP ! No, Nan, return 1
- +
- + B $L2
- +
- +$L1:
- + CMP D0Ar6, #0xFF ! exp2 == 0xFF?
- + BNE $L2
- +
- + CMP D0Ar2, #0 ! mant2 == 0?
- + MOVNZ PC, D1RtP ! No, Nan, return 1
- +
- +$L2:
- +
- +!! if (F_INF_P (fp1) && F_INF_P (fp2))
- +!! return sign2 - sign1;
- +
- + SUB D0Re0, D1Ar5, D1Ar3 ! sign2 - sign1
- +
- + AND D1Re0, D0Ar4, D0Ar6
- + CMP D1Re0, #0xFF ! (exp1 & exp2) == 0xFF
- + MOV D1Re0, D0Ar2
- + CMPEQ D1Ar1, D1Re0 ! mant1 == mant2
- + CMPEQ D1Ar1, #0 ! == 0
- + MOVEQ PC, D1RtP
- +
- +!! if (F_INF_P (fp1))
- +!! return sign1 ? -1 : 1;
- +
- + MOV D0Re0, #0 ! result
- + TST D1Ar3, #1 ! sign1 ?
- + SUBNZ D0Re0, D0Re0, #1 ! -1
- + ADDZ D0Re0, D0Re0, #1 ! +1
- +
- + CMP D0Ar4, #0x00FF ! exp1 == 0xFF
- + CMPEQ D1Ar1, #0 ! mant1 == 0
- + MOVEQ PC, D1RtP
- +
- +!! if (F_INF_P (fp2))
- +!! return sign2 ? 1 : -1;
- +
- + MOV D0Re0, #0 ! result
- + TST D1Ar5, #1 ! sign2 ?
- + ADDNZ D0Re0, D0Re0, #1 ! +1
- + SUBZ D0Re0, D0Re0, #1 ! -1
- +
- + CMP D0Ar6, #0x00FF ! exp2 == 0xFF
- + CMPEQ D0Ar2, #0 ! mant2 == 0
- + MOVEQ PC, D1RtP
- +
- +!! if (F_ZERO_P (fp1) && F_ZERO_P (fp2))
- +!! return 0;
- +
- + MOV D0Re0, #0
- + ORS D1Re0, D0Ar4, D0Ar6 ! exp1 | exp2
- + MOV D1Re0, D0Ar2
- + ORSZ D1Re0, D1Ar1, D1Re0 ! mant1 | mant1
- + MOVZ PC, D1RtP ! both zero return 0
- +
- +!! if (F_ZERO_P (fp1))
- +!! return sign2 ? 1 : -1;
- +
- + ! result (D0Re0) already 0
- + TST D1Ar5, #1 ! sign2 ?
- + ADDNZ D0Re0, D0Re0, #1 ! +1
- + SUBZ D0Re0, D0Re0, #1 ! -1
- +
- + ORS D1Re0, D0Ar4, D0Ar4 ! exp1 == 0
- + ORSZ D1Re0, D1Ar1, D1Ar1 ! and mant1 == 0?
- + MOVZ PC, D1RtP
- +
- +!! if (F_ZERO_P (fp2))
- +!! return sign1 ? -1 : 1;
- +
- + MOV D0Re0, #0 ! result
- + TST D1Ar3, #1 ! sign1 ?
- + SUBNZ D0Re0, D0Re0, #1 ! -1
- + ADDZ D0Re0, D0Re0, #1 ! +1
- +
- + ORS D1Re0, D0Ar6, D0Ar2 ! exp2 and mant2 == 0?
- + MOVZ PC, D1RtP
- +
- +!! /* Normalize the numbers. */
- +!! F_NORMALIZE (fp1, exp1, mant1);
- +!! F_NORMALIZE (fp2, exp2, mant2);
- +
- +!! now both are "normal".
- +
- + MOV D0Re0, #0 ! result
- + TST D1Ar3, #1 ! sign1 ?
- + SUBNZ D0Re0, D0Re0, #1 ! -1
- + ADDZ D0Re0, D0Re0, #1 ! +1
- +
- + CMP D1Ar3, D1Ar5 ! sign1 != sign2
- + MOVNE PC, D1RtP ! yes, return sign1 ? -1 : +1
- +
- + CMP D0Ar4, D0Ar6 ! exp1 > exp2
- + MOVGT PC, D1RtP ! yes, return sign1 ? -1 : +1
- +
- + NEG D0Re0, D0Re0 ! result -= result
- + MOVLT PC, D1RtP ! exp < exp2 return -(sign1 ? -1 : +1)
- +
- + MOV D1Re0, D0Ar2
- + CMP D1Ar1, D1Re0 ! mant1 < mant2
- + MOVLT PC, D1RtP ! yes, return -(sign1 ? -1 : +1)
- +
- + NEG D0Re0, D0Re0 ! result = -result
- + MOVGT PC, D1RtP ! > return sign1 ? -1 : +1
- +
- + MOV D0Re0, #0
- + MOV PC, D1RtP
- + .size ___cmpsf2,.-___cmpsf2
- +#endif
- +
- +#ifdef L_cmpsf2_nan
- +!!
- +!! Filters for Nan arguments before calling ___cmpsf2
- +!!
- +!! If either Arg1 or Arg2 is Nan then return Arg3 (D1Ar3)
- +!! otherwise tail calls ___cmpsf2
- +!!
- + .text
- + .global ___cmpsf2_nan
- + .type ___cmpsf2_nan,function
- + .align 2
- +___cmpsf2_nan:
- + LSR D1Re0, D1Ar1, #23 ! arg1 NAN ?
- + AND D1Re0, D1Re0, #0x00FF
- + CMP D1Re0, #0x00FF ! exp all 1s
- + BNE $L10
- +
- + MOV D1Re0, D1Ar1
- + LSLS D1Re0, D1Re0, #(32-23) ! mantisa non-zero?
- + MOVNZ D0Re0, D1Ar3
- + MOVNZ PC, D1RtP ! return (D1Ar3)
- +
- +$L10:
- + LSR D1Re0, D0Ar2, #23 ! arg2 NAN ?
- + AND D1Re0, D1Re0, #0x00FF
- + CMP D1Re0, #0x00FF ! exp all 1s
- + BNE $L11
- +
- + MOV D1Re0, D0Ar2
- + LSLS D1Re0, D1Re0, #(32-23) ! mantisa non-zero?
- + MOVNZ D0Re0, D1Ar3
- + MOVNZ PC, D1RtP ! return (D1Ar3)
- +
- +$L11:
- +#ifdef __PIC__
- + B ___cmpsf2@PLT
- +#else
- + B ___cmpsf2
- +#endif
- + .size ___cmpsf2_nan,.-___cmpsf2_nan
- +#endif
- +
- +#ifdef L_eqdf2
- +!!
- +!! Floating point - double comparison routines ==,!=,<,<==,>,>=
- +!! Wrapper entry points for common cmpdf2 routine, these entry points
- +!! set up correct return value if either is Nan.
- +!!
- + .text
- + .global ___eqdf2
- + .type ___eqdf2,function
- + .global ___nedf2
- + .type ___nedf2,function
- + .global ___ltdf2
- + .type ___ltdf2,function
- + .global ___ledf2
- + .type ___ledf2,function
- + .align 2
- +___eqdf2:
- +___nedf2:
- +___ltdf2:
- +___ledf2:
- +
- +!! If either is NAN return +1
- +
- + MOV D1Ar5, #1
- +#ifdef __PIC__
- + B ___cmpdf2_nan@PLT
- +#else
- + B ___cmpdf2_nan
- +#endif
- + .size ___eqdf2,.-___eqdf2
- + .size ___nedf2,.-___nedf2
- + .size ___ltdf2,.-___ltdf2
- + .size ___ledf2,.-___ledf2
- +
- + .global ___gedf2
- + .type ___gedf2,function
- + .global ___gtdf2
- + .type ___gtdf2,function
- + .align 2
- +___gedf2:
- +___gtdf2:
- +
- +!! If either is NAN return -1
- +
- + MOV D1Ar5, #-1
- +#ifdef __PIC__
- + B ___cmpdf2_nan@PLT
- +#else
- + B ___cmpdf2_nan
- +#endif
- + .size ___gedf2,.-___gedf2
- + .size ___gtdf2,.-___gtdf2
- +#endif
- +
- +#ifdef L_eqsf2
- +!!
- +!! Floating point - float comparison routines ==,!=,<,<==,>,>=
- +!! Wrapper entry points for common cmpsf2 routine, these entry points
- +!! set up correct return value if either is Nan.
- +!!
- + .text
- + .global ___eqsf2
- + .type ___eqsf2,function
- + .global ___nesf2
- + .type ___nesf2,function
- + .global ___ltsf2
- + .type ___ltsf2,function
- + .global ___lesf2
- + .type ___lesf2,function
- + .align 2
- +___eqsf2:
- +___nesf2:
- +___ltsf2:
- +___lesf2:
- +
- +!! If either is NAN return +1
- +
- + MOV D1Ar3, #1
- +#ifdef __PIC__
- + B ___cmpsf2_nan@PLT
- +#else
- + B ___cmpsf2_nan
- +#endif
- + .size ___eqsf2,.-___eqsf2
- + .size ___nesf2,.-___nesf2
- + .size ___ltsf2,.-___ltsf2
- + .size ___lesf2,.-___lesf2
- +
- + .global ___gesf2
- + .type ___gesf2,function
- + .global ___gtsf2
- + .type ___gtsf2,function
- + .align 2
- +___gesf2:
- +___gtsf2:
- +
- +!! If either is NAN return -1
- +
- + MOV D1Ar3, #-1
- +#ifdef __PIC__
- + B ___cmpsf2_nan@PLT
- +#else
- + B ___cmpsf2_nan
- +#endif
- + .size ___gesf2,.-___gesf2
- + .size ___gtsf2,.-___gtsf2
- +#endif
- +
- +!! Division routines.
- +
- +#ifdef L_divdf3
- +!!
- +!! Function : double divdf3 (double a1, double a2)
- +!!
- +!! Args : a1 - double precision floating point number (D1Ar1:D0Ar2)
- +!! : a2 - double precision floating point number (D1Ar3:D0Ar4)
- +!!
- +!! Description: Returns a1 divided by a2 (D1Re0:D0Re0)
- +!!
- +!! Returns : (+/-)0.0 / (+/-)0.0 = QNaN
- +!! : (+/-)Inf / (+/-)Inf = NaN
- +!! : n / (+/-)Inf = 0.0
- +!! : n / (+/-)0.0 = (+/-)Inf
- +!! : a1 / a2 = n.
- +!!
- +!! Notes : QNaN = 0xFFF80000:00000000 (Quiet NaN)
- +!! : SNan = 0xFFF7FFFF:FFFFFFFF (Signaling Nan)
- +!! : +Inf = 0x7FF00000:00000000
- +!! : -Inf = 0xFFF00000:00000000
- +!! : +0 = 0x00000000:00000000
- +!! : -0 = 0x80000000:00000000
- +!!
- + .text
- + .global ___divdf3
- + .type ___divdf3,function
- + .align 2
- +___divdf3:
- + XOR D1Re0, D1Ar1, D1Ar3 ! sign1 ^ sign2
- + ANDT D1Re0, D1Re0, #0x8000 ! extract sign result
- +
- + ! Test if a1 == 0.0
- + LSL D0Re0, D1Ar1, #1 ! Ignore sign bit
- + ORS D0Re0, D0Re0, D0Ar2 ! a1 == 0 ?
- + BZ $A1IsZero
- +
- + ! Test if a2 == 0.0
- + LSL D0Re0, D1Ar3, #1 ! Ignore sign bit
- + ORS D0Re0, D0Re0, D0Ar4 ! a2 == 0 ?
- + BNZ $DoDivision
- +
- + ! a1 != 0.0 and a2 == 0.0, so return +/-Inf
- + ORT D1Re0, D1Re0, #0x7FF0 ! Set exponent for (+/-)Inf
- + MOV PC, D1RtP
- +
- +$A1IsZero:
- + LSL D0Re0, D1Ar3, #1 ! Ignore sign bit
- + ORS D0Re0, D0Re0, D0Ar4 ! a2 == 0 ?
- + MOV D0Re0, #0
- +
- + ! a1 == 0.0 and a2 != 0.0, so return +/-Zero
- + SUBNZ D0Re0, D0Re0, D0Re0
- + MOVNZ PC, D1RtP ! (zero return already set up)
- +
- + ! a1 == 0.0 and a2 == 0.0, so return QNaN.
- + MOVT D1Re0, #0xFFF8 ! maybe sign depends on sign1 ^ sign2
- + MOV PC, D1RtP
- +
- +$DoDivision:
- + MOV A0.3, D1Re0 ! sign -> A0.3
- +
- + MOV D1Ar5, D1Ar1
- + ANDMT D1Ar5, D1Ar5, #0x7FFF
- + LSR D1Ar5, D1Ar5, #20 ! exp1
- +
- + MOV D1Re0, D1Ar3
- + ANDMT D1Re0, D1Re0, #0x7FFF
- + LSR D1Re0, D1Re0, #20 ! exp2
- +
- + SUB D1Ar5, D1Ar5, D1Re0 ! exp = exp1 - exp2 + 1022
- + ADD D1Ar5, D1Ar5, #1022 ! exp ---> D1Ar5
- + MOV A0.2, D1Ar5 ! exp ---> A0.2
- +
- + ANDMT D1Ar1, D1Ar1, #0x000F
- + ORT D1Ar1, D1Ar1, #0x0010 ! man1 --->D1Ar1, D0Ar2
- +
- + ANDMT D1Ar3, D1Ar3, #0x000F
- + ORT D1Ar3, D1Ar3, #0x0010 ! man2 --->D1Ar3, D0Ar4
- +
- + CMP D1Ar1, D1Ar3 ! man1 < man2
- + BGT $L2
- + BLT $L3
- +
- + CMP D0Ar2, D0Ar4
- + BGE $L2
- +
- +$L3:
- + LSL D1Ar1, D1Ar1, #1 ! man1 <<= 1
- + LSR D1Ar5, D0Ar2, #(32-1)
- + OR D1Ar1, D1Ar1, D1Ar5
- + LSL D0Ar2, D0Ar2, #1
- +
- + SUB A0.2, A0.2, #1 ! exp -= 1
- +
- +$L2:
- + MOV D0Re0, #0 ! prepare the result in D1Re0, D0Re0
- + ! mask = 1<<53 split into 21 + 31
- + MOVT D0Ar6, #(1<<(21-16)) ! 1<< 21
- + MOV D1Ar5, #2
- +
- +$L5:
- + ! while (mask)
- + CMP D0Ar6, #0
- + BZ $L4
- +
- + CMP D1Ar1, D1Ar3 ! man1 >= man2
- + BLT $L5_1
- + BGT $L5_2
- +
- + CMP D0Ar2, D0Ar4
- + BLT $L5_1
- +
- +$L5_2:
- + OR D0Re0, D0Re0, D0Ar6 ! result |= mask
- +
- + SUB D1Ar1, D1Ar1, D1Ar3 ! man1 - man2
- + SUBS D0Ar2, D0Ar2, D0Ar4
- + SUBCS D1Ar1, D1Ar1, #1
- +
- +$L5_1:
- + LSL D1Ar1, D1Ar1, #1 ! man1 <<= 1
- + TSTT D0Ar2, #0x8000
- + ORNZ D1Ar1, D1Ar1, #1 ! MSBit -> LSBit
- + LSL D0Ar2, D0Ar2, #1
- +
- + LSR D0Ar6, D0Ar6, #1 ! mask >>= 1
- + B $L5
- +
- +$L4:
- + SUBS D1Ar5, D1Ar5, #1
- + BZ $L6
- +
- + MOV D1Re0, D0Re0
- + MOV D0Re0, #0
- + MOVT D0Ar6, #(1<<(31-16)) ! 1 << 31
- + B $L5
- +
- +$L6:
- + ADDS D0Re0, D0Re0, #1 ! result += 1
- + ADDCS D1Re0, D1Re0, #1
- +
- + ADD D1Ar3, A0.2, #1 ! exp += 1
- +
- + LSR D0Re0, D0Re0, #1 ! result <<= 1
- + LSL D0Ar2, D1Re0, #(32-1)
- + OR D0Re0, D0Re0, D0Ar2
- + LSR D1Re0, D1Re0, #1
- +
- + MOV D1Ar1, A0.3
- + ANDMT D1Re0, D1Re0, #0x000F ! discard hidden bit
- + OR D1Re0, D1Re0, D1Ar1 ! combine sign
- +
- + MOV D1Ar5, #0
- + MAX D1Ar3, D1Ar3, D1Ar5 ! exp < 0 ?
- + SUBLT D0Re0, D0Re0, D0Re0 ! < 0 return +/-Zero
- + MOVLT D1Re0, D1Ar1
- + MOVLT PC, D1RtP
- +
- + SUBEQ D0Re0, D0Re0, D0Re0 ! Don(t) currently handle
- + MOVEQ D1Re0, D1Ar1 ! denormals, so return
- + MOVEQ PC, D1RtP ! +/-Zero
- +
- + MOV D1Ar5, #0x7FF
- + MIN D1Ar3, D1Ar3, D1Ar5 ! exp >= 0x7FF
- + SUBGE D0Re0, D0Re0, D0Re0 ! >= return +/- Inf
- + MOVGE D1Re0, D1Ar1
- +
- + LSL D1Ar3, D1Ar3, #20 ! postion exp
- + OR D1Re0, D1Re0, D1Ar3 ! combine exp
- +
- + MOV PC, D1RtP
- + .size ___divdf3,.-___divdf3
- +#endif
- +
- +#ifdef L_divsf3
- +!!
- +!! Function : float divsf3 (float a1, float a2)
- +!!
- +!! Args : a1 - single precision floating point number (D1Ar1)
- +!! : a2 - single precision floating point number (D0Ar2)
- +!!
- +!! Description: Returns a1 divided by a2 (D0Re0)
- +!!
- +!! Returns : (+/-)0.0 / (+/-)0.0 = QNaN
- +!! : (+/-)Inf / (+/-)Inf = NaN
- +!! : n / (+/-)Inf = 0.0
- +!! : n / (+/-)0.0 = (+/-)Inf
- +!! : a1 / a2 = n.
- +!!
- +!! Notes : QNaN = 0xFFC00000 (Quiet NaN)
- +!! : SNan = 0xFFBFFFFF (Signaling Nan)
- +!! : +Inf = 0x7F800000
- +!! : -Inf = 0xFF800000
- +!! : +0 = 0x00000000
- +!! : -0 = 0x80000000
- +!!
- + .text
- + .global ___divsf3
- + .type ___divsf3,function
- + .align 2
- +___divsf3:
- + MOV D0Re0, D1Ar1
- + XOR D0Re0, D0Re0, D0Ar2 ! sign1 ^ sign2
- + ANDT D0Re0, D0Re0, #0x8000 ! extract sign
- +
- + ! Test if a1 == 0.0
- + LSLS D1Re0, D1Ar1, #1 ! Ignore sign bit
- + BZ $L1
- +
- + ! Test if a2 == 0.0
- + LSLS D0Ar4, D0Ar2, #1 ! Ignore sign bit
- + BNZ $L2
- +
- + ! a1 != 0.0 and a2 == 0.0 so return +/-Inf
- + ORT D0Re0, D0Re0, #0x7F80
- + MOV PC, D1RtP
- +
- +$L1:
- + ! 0 / X return QNan or +/-Zero
- + LSLS D0Ar4, D0Ar2, #1 ! Ignore sign bit (D0Ar4)
- +
- + ! a1 == 0.0 and a2 != 0.0, so return +/-Zero
- + MOVNZ PC, D1RtP ! (zero return already set up)
- +
- + ! a1 == 0.0 and a2 == 0.0, so return QNAN
- + MOVT D0Re0, #0xFFC0 ! maybe sign depends on sign1 ^ sign2
- + MOV PC, D1RtP
- +
- +$L2:
- + MOV D0Ar4, D0Re0 ! sign bit
- +
- + MOV D1Ar5, D1Ar1
- + ANDMT D1Ar5, D1Ar5, #0x7FFF
- + LSR D1Ar5, D1Ar5, #23 ! exp1
- +
- + MOV D1Re0, D0Ar2
- + ANDMT D1Re0, D1Re0, #0x7FFF
- + LSR D1Re0, D1Re0, #23 ! exp2
- +
- + SUB D1Ar5, D1Ar5, D1Re0
- + ADD D1Ar5, D1Ar5, #126 ! exp = exp1 - exp2 + 126
- +
- + MOV D0Ar6, D1Ar1
- + ANDMT D0Ar6, D0Ar6, #0x007F
- + ORT D0Ar6, D0Ar6, #0x0080 ! man1 -->D0Ar6
- +
- + MOV D0Re0, D0Ar2
- + ANDMT D0Re0, D0Re0, #0x007F
- + ORT D0Re0, D0Re0, #0x0080 ! man2 --> D0Re0
- +
- + CMP D0Ar6, D0Re0 ! man1 < man2
- + BGE $L3
- +
- + LSL D0Ar6, D0Ar6, #1 ! man1 <<= 1
- + SUB D1Ar5, D1Ar5, #1 ! exp -= 1
- +
- +$L3:
- + !mask = 0x01000000
- + MOVT D1Ar1, #0x0100
- + MOV D1Re0, #0 ! result = 0
- +
- +$L4:
- + CMP D0Ar6, D0Re0
- + ORGE D1Re0, D1Re0, D1Ar1 ! result |= mask
- + SUBGE D0Ar6, D0Ar6, D0Re0
- +
- + LSL D0Ar6, D0Ar6, #1 ! man1 <<= 1
- + LSRS D1Ar1, D1Ar1, #1 ! mask >>= 1
- + BNZ $L4
- +
- + ADD D1Ar1, D1Re0, #1 ! result += 1
- +
- + ADD D1Ar5, D1Ar5, #1 ! exp += 1
- + LSR D1Ar1, D1Ar1, #1 ! result >>= 1
- +
- + ANDMT D1Ar1, D1Ar1, #0x007F ! remove hidden bit
- +
- + MOV D1Ar3, #0
- + MAX D1Ar5, D1Ar5, D1Ar3 ! exp < 0 ?
- + MOVLT D0Re0, D0Ar4 ! < 0 return +/-Zero
- + MOVLT PC, D1RtP
- +
- + MOVEQ D0Re0, D0Ar4 ! Don(t) currently handle
- + MOVEQ PC, D1RtP ! denormals, so return +/-Zero
- +
- + MOV D1Ar3, #0xFF
- + MIN D1Ar5, D1Ar5, D1Ar3 ! exp >= 0xFF
- + SUBGE D1Ar1, D1Ar1, D1Ar1 ! >= return +/-Inf
- +
- + LSL D1Ar5, D1Ar5, #23
- + OR D0Re0, D1Ar1, D1Ar5 ! man|exp
- + OR D0Re0, D0Re0, D0Ar4 ! |sign ->D0Re0
- +
- + MOV PC, D1RtP
- + .size ___divsf3,.-___divsf3
- +#endif
- +
- +!! Floating point multiplication
- +
- +#ifdef L_muldf3
- +!!
- +!! Floating point - double multiplicatiion
- +!!
- + .text
- + .global ___muldf3
- + .type ___muldf3,function
- + .align 2
- +___muldf3:
- + XOR D1Re0, D1Ar1, D1Ar3 ! sign1 ^ sign2
- + ANDT D1Re0, D1Re0, #0x8000 ! extract sign bit
- + LSL D0Re0, D1Ar1, #1 ! Ignore sign
- + ORS D0Re0, D0Re0, D0Ar2 ! zero * ...
- + MOVZ PC, D1RtP ! return 0
- +
- + LSL D0Re0, D1Ar3, #1 ! Ignore sign
- + ORS D0Re0, D0Re0, D0Ar4 ! ... * zero
- + MOVZ PC, D1RtP ! return 0
- +
- + MSETL [A0StP], D0.4, D0.5, D0.6, D0.7
- +
- + MOV D1Ar5, D1Ar1
- + ANDMT D1Ar5, D1Ar5, #0x7FFF
- + LSR D1Ar5, D1Ar5, #20 ! exp1
- +
- + MOV D1.5, D1Ar3
- + ANDMT D1.5, D1.5, #0x7FFF
- + LSR D1.5, D1.5, #20 ! exp2
- +
- + SUB D1Ar5, D1Ar5, #1022
- + ADD D1Ar5, D1Ar5, D1.5 ! exp = exp1 + exp2 - 1022
- +
- + MOV D1.5, D1Ar1
- + ANDMT D1.5, D1.5, #0x000F
- + ORT D1.5, D1.5, #0x0010 ! man1 --->D1.5, D0.5
- + MOV D0.5, D0Ar2
- +
- + MOV D1.6, D1Ar3
- + ANDMT D1.6, D1.6, #0x000F
- + ORT D1.6, D1.6, #0x0010 ! man2 --->D1.6, D0.6
- + MOV D0.6, D0Ar4
- +
- + XOR D1Re0, D1Ar1, D1Ar3 ! store the sign bit
- + MOV D0Re0, D1Ar5
- +
- + SETL [A0StP+#8++], D0Re0,D1Re0 ! XXX
- +
- + LSR D0Ar6, D0.5, #21 ! D1Ar1:D0Ar2 = man1 >> 21
- + LSL D0Ar2, D1.5, #(32-21)
- + MOV D1Ar1, #0 ! top 32 bits are zero
- + OR D0Ar2, D0Ar2, D0Ar6
- +
- + LSR D0Ar6, D0.6, #21 ! D1Ar3:D0Ar4 = man2 >> 21
- + LSL D0Ar4, D1.6, #(32-21)
- + MOV D1Ar3, #0 ! top 32 bits are zero
- + OR D0Ar4, D0Ar4, D0Ar6
- +
- + CALLR D1RtP, ___muldi3_
- +
- + MOV D1.7, D1Re0
- + MOV D0.7, D0Re0
- +
- + LSR D0Ar6, D0.5, #21 ! man1 >> 21
- + LSL D0Ar2, D1.5, #(32-21)
- + MOV D1Ar1, #0
- + OR D0Ar2, D0Ar2, D0Ar6
- +
- + MOV D0Ar4, D0.6
- + ANDMT D0Ar4, D0Ar4, #0x001F
- + MOV D1Ar3, #0
- +
- + CALLR D1RtP, ___muldi3_
- +
- + LSR D0Re0, D0Re0, #21 ! >> 21
- + LSL D0Ar6, D1Re0, #(32-21)
- + LSR D1Re0, D1Re0, #21
- + OR D0Re0, D0Re0, D0Ar6
- +
- + ADDS D0.7, D0.7, D0Re0 ! D1.7:D0.7 + D1Re0:D0Re0
- + ADD D1.7, D1.7, D1Re0
- + ADDCS D1.7, D1.7, #1
- +
- + MOV D1Ar1, #0
- + LSL D0Ar2, D1.6, #(32-21) ! man2 >> 21
- + LSR D0Ar6, D0.6, #21
- + OR D0Ar2, D0Ar2, D0Ar6
- +
- + MOV D0Ar4, D0.5
- + ANDMT D0Ar4, D0Ar4, #0x001F
- + MOV D1Ar3, #0
- +
- + CALLR D1RtP, ___muldi3_
- +
- + LSR D0Re0, D0Re0, #21 ! >> 21
- + LSL D0Ar6, D1Re0, #(32-21)
- + LSR D1Re0, D1Re0, #21
- + OR D0Re0, D0Re0, D0Ar6
- +
- + ADDS D0.7, D0.7, D0Re0 ! D1.7:D0.7 + D1Re0:D0Re0
- + ADD D1.7, D1.7, D1Re0
- + ADDCS D1.7, D1.7, #1
- +
- + GETL D0Re0,D1Re0, [A0StP++#-8] ! prepare to recover D1Re0, D1Ar5
- +
- + MOV D1.6, D1.7
- + MOV D0.6, D0.7
- +
- + LSR D0.6, D0.6, #2 ! man >> 2 (d1.6, d0.6)
- + LSL D0.5, D1.6, #(32-2)
- + LSR D1.6, D1.6, #2
- + OR D0.6, D0.6, D0.5
- +
- + MOV D1Ar5, D0Re0
- +
- + MOV D0Re0, D1.6
- + ANDT D0Re0, D0Re0, #0x2000 ! 1 << 61
- + CMP D0Re0, #0 ! round ...
- + BZ $L11
- +
- + ADDS D0.6, D0.6, #0x100 ! D1.6:D0.6 + 0x100
- + ADDCS D1.6, D1.6, #1
- +
- + LSL D0.5, D1.6, #(32-9) ! >> 9
- + LSR D0.6, D0.6, #9
- + LSR D1.6, D1.6, #9
- + OR D0.6, D0.6, D0.5
- + B $L13
- +
- +$L11:
- + ADDS D0.6, D0.6, #0x80 ! +128
- + ADDCS D1.6, D1.6, #1
- +
- + LSR D0.6, D0.6, #8 ! >> 8
- + LSL D0.5, D1.6, #(32-8)
- + LSR D1.6, D1.6, #8
- + OR D0.6, D0.6, D0.5
- +
- + SUB D1Ar5, D1Ar5, #1 ! exp -= 1
- +
- +$L13:
- + MOV D0Re0, D1.6
- + ANDT D0Re0, D0Re0, #0x0020
- + CMP D0Re0, #0
- + BZ $L14
- +
- + LSR D0.6, D0.6, #1 ! man >> 1
- + LSL D0.5, D1.6, #(32-1)
- + LSR D1.6, D1.6, #1
- + OR D0.6, D0.6, D0.5
- +
- + ADD D1Ar5, D1Ar5, #1 ! exp += 1
- +
- +$L14:
- + ANDT D1Re0, D1Re0, #0x8000 ! get the sign bit
- + MOV D1Ar1, D1Re0 ! remember sign
- + ANDMT D1.6, D1.6, #0x000F ! remove hidden bit
- + OR D1Re0, D1Re0, D1.6 ! sign | HI(mantisa)
- + MOV D0Re0, D0.6 ! LO(mantisa)
- +
- + SUB A0.3, A0StP, #32
- + MGETL D0.4, D0.5, D0.6, D0.7, [A0.3]
- + SUB A0StP, A0StP, #32
- +
- + MOV D1Ar3, #0
- + MAX D1Ar5, D1Ar5, D1Ar3 ! exp < 0 ?
- + SUBLT D0Re0, D0Re0, D0Re0 ! < 0 return +/-Zero
- + MOVLT D1Re0, D1Ar1
- + MOVLT PC, D1RtP
- +
- + SUBEQ D0Re0, D0Re0, D0Re0 ! Don(t) currently handle
- + MOVEQ D1Re0, D1Ar1 ! denormals, so return
- + MOVEQ PC, D1RtP ! +/-Zero
- +
- + MOV D1Ar3, #0x7FF
- + MIN D1Ar5, D1Ar5, D1Ar3 ! exp >= 0x7FF ?
- + SUBGE D0Re0, D0Re0, D0Re0 ! >= return +/-Inf
- + MOVGE D1Re0, D1Ar1
- +
- + LSL D1Ar5, D1Ar5, #20 ! position exp
- + OR D1Re0, D1Re0, D1Ar5 ! add exp
- +
- + MOV PC, D1RtP
- +
- +!!
- +!! 32-bit x 32-bit -> 64-bit
- +!!
- + .align 2
- +___muldi3_:
- + MOV A0.2, D0Ar6
- + MOV A0.3, D1Ar5
- +
- + LSR D1Ar1, D0Ar2, #16 ! h1
- + LSR D1Ar3, D0Ar4, #16 ! high 2
- + MULW D1Re0, D1Ar1, D1Ar3 ! h1 * h2
- +
- + MOV D0Ar6, #0xFFFF
- + AND D1Ar5, D0Ar2, D0Ar6 ! l1
- + MULW D0Re0, D1Ar5, D1Ar3 ! l1 * h2
- +
- + AND D0Ar2, D0Ar4, D0Ar6 ! l2
- + MOV D0Ar4, D1Ar1 ! h1
- + MULW D1Ar1, D0Ar4, D0Ar2 ! h1 * l2
- +
- + MOV D0Ar4, D1Ar5 ! l1
- + LSR D1Ar5, D0Re0, #16
- + LSL D0Re0, D0Re0, #16
- + ADD D1Re0, D1Re0, D1Ar5
- + LSR D1Ar5, D1Ar1, #16
- + ADD D1Re0, D1Re0, D1Ar5
- + LSL D0Ar6, D1Ar1, #16
- +
- + ADDS D0Re0, D0Re0, D0Ar6
- + ADDCS D1Re0, D1Re0, #1
- +
- + MULW D0Ar6, D0Ar2, D0Ar4
- +
- + ADDS D0Re0, D0Re0, D0Ar6
- + ADDCS D1Re0, D1Re0, #1
- +
- + MOV D0Ar6, A0.2
- + MOV D1Ar5, A0.3
- +
- + MOV PC, D1RtP
- + .size ___muldf3,.-___muldf3
- +#endif
- +
- +#ifdef L_mulsf3
- +!!
- +!! Floating point - float multiplication
- +!!
- + .text
- + .global ___mulsf3
- + .type ___mulsf3,function
- + .align 2
- +___mulsf3:
- + MOV D0Re0, D1Ar1
- + XOR D0Re0, D0Re0, D0Ar2 ! sign1 ^ sign2
- + ANDT D0Re0, D0Re0, #0x8000 ! extract sign bit
- + LSLS D1Re0, D1Ar1, #1 ! Ignore sign
- + MOVZ PC, D1RtP ! +/-Zero * ... return Zero
- +
- + LSLS D1Re0, D0Ar2, D0Ar2 ! Ignore sign
- + MOVZ PC, D1RtP ! ... * +/-Zero return Zero
- +
- + MOV D1Ar5, D1Ar1
- + ANDMT D1Ar5, D1Ar5, #0x7fff
- + LSR D1Ar5, D1Ar5, #23 ! exp1
- +
- + MOV D1Re0, D0Ar2
- + ANDMT D1Re0, D1Re0, #0x7fff
- + LSR D1Re0, D1Re0, #23 ! exp2
- +
- + SUB D1Ar5, D1Ar5, #126 ! exp = exp1 - 126
- + ADD D1Ar5, D1Ar5, D1Re0 ! exp += exp2
- +
- + MOV D0Ar6, D1Ar1
- + ANDMT D0Ar6, D0Ar6, #0x7f
- + ORT D0Ar6, D0Ar6, #0x80 ! man1
- +
- + MOV D0Re0, D0Ar2
- + ANDMT D0Re0, D0Re0, #0x7f
- + ORT D0Re0, D0Re0, #0x80 ! man2
- +
- + MOV D1Re0, D0Ar2
- + XOR D1Re0, D1Ar1, D1Re0 ! store the sign bit in D1Re0
- +
- + LSR D0Ar2, D0Ar6, #8
- + LSR D0Ar4, D0Re0, #8
- + MULW D1Ar1, D0Ar2, D0Ar4 ! one 16X16
- +
- + MOV D0Ar2, D0Ar6
- + AND D0Ar2, D0Ar2, #0xff
- + MULW D1Ar3, D0Ar2, D0Ar4 ! one 8X16
- +
- + LSR D0Ar2, D0Ar6, #8
- + MOV D0Ar4, D0Re0
- + AND D0Ar4, D0Ar4, #0xff
- + MULW D0Re0, D0Ar2, D0Ar4 ! another 16X8
- +
- + SWAP D1Re0, D0Re0
- + ADD D1Ar3, D1Ar3, D1Re0 ! add 16x8(s) partial results
- + LSR D1Ar3, D1Ar3, #8
- + ADD D1Ar1, D1Ar1, D1Ar3 ! accumulate partial result
- +
- + LSR D1Ar1, D1Ar1, #2 ! man >> 2
- + TSTT D1Ar1, #0x2000 ! round ...
- +
- + ADDNZ D1Ar1, D1Ar1, #0x20
- + LSRNZ D1Ar1, D1Ar1, #6
- +
- + ADDZ D1Ar1, D1Ar1, #0x10
- + LSRZ D1Ar1, D1Ar1, #5
- + SUBZ D1Ar5, D1Ar5, #1
- +
- + TSTT D1Ar1, #0x100
- +
- + LSRNZ D1Ar1, D1Ar1, #1
- + ADDNZ D1Ar5, D1Ar5, #1
- +
- + ANDT D0Re0, D0Re0, #0x8000 ! get the sign bit
- + ANDMT D1Ar1, D1Ar1, #0x7f ! remove hidden hit
- +
- + MOV D1Ar3, #0
- + MAX D1Ar5, D1Ar5, D1Ar3 ! exp < 0 ?
- + MOVLT PC, D1RtP ! < 0 return +/-Zero
- + ! Don(t) currently handle
- + MOVEQ PC, D1RtP ! denormals, so return +/-Zero
- +
- + MOV D1Ar3, #0xFF
- + MIN D1Ar5, D1Ar5, D1Ar3 ! exp >= 0xFF ?
- + SUBGE D1Ar1, D1Ar1, D1Ar1 ! >= return +/-Inf
- +
- + MOV D1Re0, D0Re0
- + LSL D1Ar5, D1Ar5, #23
- + OR D1Re0, D1Re0, D1Ar5 ! sign|exp
- + OR D0Re0, D1Re0, D1Ar1 ! |man ->D0Re0
- +
- + MOV PC, D1RtP
- + .size ___mulsf3,.-___mulsf3
- +#endif
- +
- +!! Floating point conversion routines
- +
- +#ifdef L_extendsfdf2
- +!!
- +!! float -> double conversion
- +!!
- + .text
- + .global ___extendsfdf2
- + .type ___extendsfdf2,function
- + .align 2
- +___extendsfdf2:
- + LSLS D0Re0, D1Ar1, #1 ! Ignore sign bit
- + MOVZ D1Re0, D1Ar1 ! +/- Zero
- + MOVZ PC, D1RtP ! return +/- Zero
- +
- + MOV D1Ar3, D1Ar1
- + ANDT D1Ar3, D1Ar3, #0x8000 ! extract sign (D1Ar3)
- +
- + MOV D0Ar2, D1Ar1 ! extract mant (D0Ar2)
- + ANDMT D0Ar2, D0Ar2, #0x007F
- +
- + LSR D1Re0, D1Ar1, #23 ! extract exp (D1Re0)
- + AND D1Re0, D1Re0, #0x00FF
- +
- + ADD D1Re0, D1Re0, #(1023-127) ! exp += ...
- +
- + LSL D1Re0, D1Re0, #(52-32) ! position exp MSWord
- +
- + OR D1Re0, D1Re0, D1Ar3 ! combine with sign | exp
- +
- + MOV D1Ar3, D0Ar2 ! extract mant MSWord
- + LSR D1Ar3, D1Ar3, #(23-(52-32))
- +
- + OR D1Re0, D1Re0, D1Ar3 ! combine sign | exp | mant
- + LSL D0Re0, D0Ar2, #(32 - 3) ! 3 = (23-(52-32))
- +
- + MOV PC, D1RtP
- + .size ___extendsfdf2,.-___extendsfdf2
- +#endif
- +
- +#ifdef L_truncdfsf2
- +!!
- +!! double -> float conversion
- +!!
- + .text
- + .global ___truncdfsf2
- + .type ___truncdfsf2,function
- + .align 2
- +___truncdfsf2: ! has round solution
- + LSL D0Re0, D1Ar1, #1 ! Ignore sign bit
- + ORS D0Re0, D0Re0, D0Ar2 ! zero?
- + MOVZ D0Re0, D1Ar1
- + MOVZ PC, D1RtP ! return +/-Zero
- +
- +!! extract sign
- + MOV D0Ar6, D1Ar1
- + ANDT D0Ar6, D0Ar6, #0x8000 ! save sign
- +
- +!! extract exponent
- + MOV D1Re0, D1Ar1
- + ANDMT D1Re0, D1Re0, #0x7FFF ! remove the sign bit
- + LSR D1Re0, D1Re0, #20
- + SUB D1Re0, D1Re0, #(1023-127)
- +
- +!! extract mantisa
- + ANDMT D1Ar1, D1Ar1, #0x000F
- +
- +!! add hidden bit
- + ORT D1Ar1, D1Ar1, #0x0010
- +
- +!! position significand for rounding
- + LSL D0Re0, D1Ar1, #4 ! (24 - (52 - 32))
- + LSR D0Ar2, D0Ar2, #(32 - 4)
- + OR D0Re0, D0Re0, D0Ar2
- +
- + ADD D0Re0, D0Re0, #1 ! round + 1
- + TSTT D0Re0, #0xFE00 ! test round overflowed?
- + ADDNZ D1Re0, D1Re0, #1
- + LSR D0Re0, D0Re0, #1
- +
- +!! check biased exponent within range 0 .. 254
- + CMP D1Re0, #0
- + MOVLT D0Re0, D0Ar6 ! return +/- Zero
- + MOVLT PC, D1RtP ! return 0
- +
- + MOVT D0Ar4, #0x7F80 ! Inf
- + OR D0Ar4, D0Ar4, D0Ar6 ! +/-Inf
- +
- + CMP D1Re0, #254
- + MOVGT D0Re0, D0Ar4
- + MOVGT PC, D1RtP ! return +/Inf
- +
- +!! pack sign , exp, mantisa
- + ANDMT D0Re0, D0Re0, #0x007F ! remove hidden bit
- + LSL D0Ar2, D1Re0, #23 ! align exp
- + OR D0Re0, D0Re0, D0Ar2 ! exp | mantisa
- + OR D0Re0, D0Re0, D0Ar6 ! sign | exp | mantisa
- + MOV PC, D1RtP ! done
- + .size ___truncdfsf2,.-___truncdfsf2
- +#endif
- +
- +!! Floating point -> integer conversion.
- +
- +#ifdef L_fixdfdi
- +!!
- +!! Floating point - double -> signed long long
- +!!
- + .text
- + .global ___fixdfdi
- + .type ___fixdfdi,function
- + .align 2
- +___fixdfdi:
- + MOV D0Re0, D1Ar1
- + ORS D0Re0, D0Re0, D0Ar2
- + MOVZ D1Re0, D0Re0
- + MOVZ PC, D1RtP
- +
- + MOV D1Re0, D1Ar1
- + ANDMT D1Re0, D1Re0, #0x7FFF ! discard sign bit
- +
- + LSR D1Re0, D1Re0, #20
- + SUBS D1Re0, D1Re0, #1085 ! exp
- + BLE $L3
- +
- +!! exp > 0 not representable (overflow)
- +
- + TSTT D1Ar1, #0x8000 ! signed?
- + MOVT D1Re0, #0x8000 ! yes, result
- + MOV D0Re0, #0 ! MIN_INT
- + SUBZ D1Re0, D1Re0, #1 ! else result
- + SUBZ D0Re0, D0Re0, #1 ! MAX_INT
- + MOV PC, D1RtP ! return
- +
- +$L3:
- + CMP D1Re0, #-62 ! -(BITS_PER_DI - 2)
- + SUBLT D0Re0, D0Re0, D0Re0
- + MOVLT D1Re0, D0Re0
- + MOVLT PC, D1RtP ! underflow
- +
- + MOV D0Ar6, D1Re0 ! exp
- +
- + MOV D0Re0, D0Ar2
- + MOV D1Re0, D1Ar1 ! man -> D1Re0, D0Re0
- +
- + ANDMT D1Re0, D1Re0, #0x000F
- + ORT D1Re0, D1Re0, #0x0010
- +
- + LSL D1Re0, D1Re0, #10 ! man <<=10
- +
- + LSR D1Ar5, D0Re0, #22
- + OR D1Re0, D1Re0, D1Ar5 ! mantissa
- +
- + LSL D0Re0, D0Re0, #10
- +
- + CMP D0Ar6, #0
- + BZ $L5
- +
- + CMP D0Ar6, #-32
- + BGT $L5_1
- + BLT $L5_2
- +
- +!! >> 32 bits.
- + MOV D0Re0, D1Re0
- + MOV D1Re0, #0
- + B $L5
- +
- +$L5_2:
- +!! >> more than 32 bits
- +
- + ADD D0Ar6, D0Ar6, #32
- + CMP D0Ar6, #-32
- +
- +!! >> more than 64 bits, return 0
- + ADDLE D0Re0, D0Re0, D0Re0
- + MOVLE PC, D1RtP
- +
- + MOV D0Re0, D1Re0
- + MOV D1Re0, #0
- + NEG D0Ar6, D0Ar6
- + LSR D0Re0, D0Re0, D0Ar6
- + B $L5
- +
- +$L5_1:
- +!! >> less than 32 bits
- + CMP D0Ar6, #0 ! shift >>0 ?
- + BEQ $L5
- +
- + ADD D1Ar5, D0Ar6, #32 ! (32 + (-exp))
- + LSL D0Ar2, D1Re0, D1Ar5
- +
- + NEG D0Ar6, D0Ar6
- + LSR D0Re0, D0Re0, D0Ar6
- +
- + MOV D1Ar5, D0Ar6
- + LSR D1Re0, D1Re0, D1Ar5
- +
- + OR D0Re0, D0Re0, D0Ar2
- +
- +$L5:
- + TSTT D1Ar1, #0x8000 ! test sign
- + MOVZ PC, D1RtP
- +
- + NEGS D0Re0, D0Re0 ! change sign
- + NEG D1Re0, D1Re0
- + SUBNZ D1Re0, D1Re0, #1
- + MOV PC, D1RtP
- + .size ___fixdfdi,.-___fixdfdi
- +#endif
- +
- +#ifdef L_fixdfsi
- +!!
- +!! Floating point - double -> signed long long
- +!!
- + .text
- + .global ___fixdfsi
- + .type ___fixdfsi,function
- + .align 2
- +___fixdfsi:
- + MOV D0Re0, D1Ar1
- + ORS D0Re0, D0Re0, D0Ar2 ! zero?
- + MOVZ PC, D1RtP ! return 0
- +
- + MOV D1Re0, D1Ar1 ! keep sign bit
- +
- + LSR D0Ar6, D1Ar1, #20 ! extact exponent (D0Ar6)
- + AND D0Ar6, D0Ar6, #0x07FF
- + SUBS D0Ar6, D0Ar6, #1053 ! exp -= (1023 + 30)
- + BLE $L1
- +
- +!! exp > 0 not representable (overflow)
- +
- + TSTT D1Re0, #0x8000 ! signed ?
- + MOVT D0Re0, #0x8000 ! yes, result MIN INT
- + SUBZ D0Re0, D0Re0, #1 ! no, result MAX INT
- + MOV PC, D1RtP ! return
- +
- +$L1:
- + ANDMT D1Ar1, D1Ar1, #0x000F ! extract mantisa
- + ORT D1Ar1, D1Ar1, #0x0010 ! add hidden bit
- + LSR D1Ar3, D0Ar2, #22 ! (32 - 10)
- + LSL D0Ar2, D0Ar2, #10
- + LSL D1Ar1, D1Ar1, #10
- + OR D1Ar1, D1Ar1, D1Ar3
- +
- + CMP D0Ar6, #-30 ! -(BITS_PER_SI - 2)
- +
- + SUBLT D0Re0, D0Re0, D0Re0 ! < -30 underflow
- + MOVLT PC, D1RtP ! return 0
- +
- + MOV D0Re0, D1Ar1
- + NEG D0Ar6, D0Ar6
- + LSR D0Re0, D0Re0, D0Ar6 ! mant >>= exp
- + TSTT D1Re0, #0x8000 ! signed?
- +
- + MOVZ PC, D1RtP ! return mant
- + NEG D0Re0, D0Re0
- + MOV PC, D1RtP ! return -mant
- + .size ___fixdfsi,.-___fixdfsi
- +#endif
- +
- +#ifdef L_fixsfdi
- +!!
- +!! Floating point - float -> signed long long
- +!!
- + .text
- + .global ___fixsfdi
- + .type ___fixsfdi,function
- + .align 2
- +___fixsfdi:
- + SETL [A0StP+#8++], D0.4, D1RtP
- +#ifdef __PIC__
- + CALLR D1RtP, ___extendsfdf2@PLT
- +#else
- + CALLR D1RtP, ___extendsfdf2
- +#endif
- + MOV D1Ar1, D1Re0
- + MOV D0Ar2, D0Re0
- +
- + GETL D0.4, D1RtP, [A0StP++#-8]
- +
- +#ifdef __PIC__
- + B ___fixdfdi@PLT
- +#else
- + B ___fixdfdi
- +#endif
- + .size ___fixsfdi,.-___fixsfdi
- +#endif
- +
- +#ifdef L_fixsfsi
- +!!
- +!! Floating point - float -> signed int/long
- +!!
- + .text
- + .global ___fixsfsi
- + .type ___fixsfsi,function
- + .align 2
- +___fixsfsi:
- + LSLS D0Re0, D1Ar1, #1 ! Ignore sign bit
- + MOVZ PC, D1RtP ! Zero? return 0
- +
- + MOV D1Re0, D1Ar1
- + ANDMT D1Re0, D1Re0, #0x7FFF ! remove sign bit
- + LSR D1Re0, D1Re0, #23
- + SUBS D1Re0, D1Re0, #(127 + 30)
- +
- + BLE $L3
- +
- +!! exp > 0 (overflow) return MIN_INT or MAX_INT
- +
- + MOVT D0Re0, #0x8000 ! MIN_INT (0x80000000)
- + TSTT D1Ar1, #0x8000
- + SUBZ D0Re0, D0Re0, #1 ! MAX_INT (0x7FFFFFFF)
- + MOV PC, D1RtP
- +
- +$L3:
- + CMP D1Re0, #-30 ! -(BITS_PER_SI - 2)
- +
- + SUBLT D0Re0, D0Re0, D0Re0 ! underflow?
- + MOVLT PC, D1RtP ! return 0
- +
- + MOV D0Re0, D1Ar1
- + ANDMT D1Ar1, D1Ar1, #0x007F ! extract mantisa
- + ORT D1Ar1, D1Ar1, #0x0080 ! add hidden bit
- + LSL D1Ar1, D1Ar1, #7
- +
- + CMP D1Re0, #0
- + BZ $L5
- +
- + NEG D1Re0, D1Re0
- + LSR D1Ar1, D1Ar1, D1Re0
- +$L5:
- +
- + TSTT D0Re0, #0x8000 ! signed?
- + MOV D0Re0, D1Ar1
- + MOVZ PC, D1RtP
- + NEG D0Re0, D0Re0
- + MOV PC, D1RtP
- + .size ___fixsfsi,.-___fixsfsi
- +#endif
- +
- +#ifdef L_fixunsdfdi
- +!!
- +!! Floating point - double -> unsigned long long
- +!!
- + .text
- + .global ___fixunsdfdi
- + .type ___fixunsdfdi,function
- + .align 2
- +___fixunsdfdi:
- + LSL D0Re0, D1Ar1, #1 ! Ignore sign bit
- + ORS D0Re0, D0Re0, D0Ar2 ! zero?
- + MOVZ D1Re0, D0Re0
- + MOVZ PC, D1RtP ! return 0
- +
- + TSTT D1Ar1, #0x8000 ! Negative?
- + SUBNZ D0Re0, D0Re0, D0Re0 ! < 0
- + MOVNZ D1Re0, D0Re0
- + MOVNZ PC, D1RtP ! return 0
- +
- + LSR D1Ar3, D1Ar1, #20 ! extract exponent (D1Ar3)
- + SUBS D1Ar3, D1Ar3, #1086 ! exp -= (1023 + 32 + 31)
- +
- + SUBGT D0Re0, D0Re0, D0Re0 ! exp > 0
- + SUBGT D0Re0, D0Re0, #1
- + MOVGT D1Re0, D0Re0
- + MOVGT PC, D1RtP ! return MAX_UDI
- +
- + ANDMT D1Ar1, D1Ar1, #0x000F ! extract mantisa
- + LSR D1Ar5, D0Ar2, #21 ! (32 - 11)
- + LSL D0Ar2, D0Ar2, #11
- + LSL D1Ar1, D1Ar1, #11
- + OR D1Ar1, D1Ar1, D1Ar5
- + ORT D1Ar1, D1Ar1, #0x8000 ! add hidden bit
- +
- + CMP D1Ar3, #-32 ! -exp >= 32
- + BLE $L9 ! branch
- +
- + CMP D1Ar3, #0 ! exp == 0?
- + MOVEQ D1Re0, D1Ar1
- + MOVEQ D0Re0, D0Ar2
- + MOVEQ PC, D1RtP
- +
- +!! Shift < 32 bits
- +
- + ADD D1Re0, D1Ar3, #32 ! (32 + (-exp))
- + LSL D0Re0, D1Ar1, D1Re0 ! H << (exp - 32)
- + NEG D1Ar3, D1Ar3 ! exp = -exp
- + MOV D1Ar5, D0Ar2
- + LSR D1Re0, D1Ar1, D1Ar3 ! H >> exp
- + LSR D0Ar6, D1Ar5, D1Ar3 ! L >> exp
- + OR D0Re0, D0Re0, D0Ar6
- + MOV PC, D1RtP
- +
- +$L9:
- +
- +!! Shift >= 32 bits
- +
- + MOV D1Re0, #0 ! shifting >= 32 (MSWord result 0)
- + ADD D1Ar3, D1Ar3, #32
- + CMP D1Ar3, #-31 ! -((BITS_PER_DI - 32) - 1)
- +
- + MOVLT D0Re0, D1Re0 ! underflow?
- + MOVLT PC, D1RtP ! return 0
- +
- + NEG D1Ar3, D1Ar3 ! exp = -exp
- + LSR D1Ar1, D1Ar1, D1Ar3 ! >>(exp - 32)
- + MOV D0Re0, D1Ar1
- + MOV PC, D1RtP
- + .size ___fixunsdfdi,.-___fixunsdfdi
- +#endif
- +
- +#ifdef L_fixunsdfsi
- +!!
- +!! Floating point - double -> unsigned int/long
- +!!
- + .text
- + .global ___fixunsdfsi
- + .type ___fixunsdfsi,function
- +___fixunsdfsi:
- + LSL D0Re0, D1Ar1, #1 ! Ignore sign bit
- + ORS D0Re0, D0Re0, D0Ar2 ! zero?
- + MOVZ PC, D1RtP ! return 0
- +
- + TSTT D1Ar1, #0x8000 ! Negative?
- + SUBNZ D0Re0, D0Re0, D0Re0 ! < 0
- + MOVNZ PC, D1RtP ! return 0
- +
- + LSR D0Ar6, D1Ar1, #20 ! extract exponent (D0Ar6)
- + SUBS D0Ar6, D0Ar6, #(1023+32+31) ! exp -= (1023 + 32 + 31)
- +
- + SUBGT D0Re0, D0Re0, D0Re0 ! exp > 0 (overflow)
- + SUBGT D0Re0, D0Re0, #1
- + MOVGT PC, D1RtP ! return MAX_USI
- +
- + ANDMT D1Ar1, D1Ar1, #0x000F ! extract mantisa
- + LSR D1Ar3, D0Ar2, #21 ! (32 - 11)
- + LSL D0Ar2, D0Ar2, #11
- + LSL D1Ar1, D1Ar1, #11
- + OR D1Ar1, D1Ar1, D1Ar3
- + ORT D1Ar1, D1Ar1, #0x8000 ! add hidden bit
- +
- + NEG D0Ar6, D0Ar6 ! exp = -exp
- + CMP D0Ar6, #64 ! exp >= BITS_PER_DI ?
- +
- + SUBGE D0Re0, D0Re0, D0Re0 ! >= underflow
- + MOVGE PC, D1RtP ! return 0
- +
- + CMP D0Ar6, #32 ! exp > (BITS_PER_DI - BITS_PER_SI)
- + SUBLT D0Re0, D0Re0, D0Re0 ! < overflow
- + SUBLT D0Re0, D0Re0, #1
- + MOVLT PC, D1RtP ! return MAX_USI_INT
- +
- + SUB D0Ar6, D0Ar6, #32 ! exp -= (BITS_PER_DI - BITS_PER_SI)
- +
- + MOV D0Re0, D1Ar1
- + LSR D0Re0, D0Re0, D0Ar6 ! return mant >> exp
- + MOV PC, D1RtP
- + .size ___fixunsdfsi,.-___fixunsdfsi
- +#endif
- +
- +#ifdef L_fixunssfdi
- +!!
- +!! Floating point - float -> unsigned long long
- +!!
- + .text
- + .global ___fixunssfdi
- + .type ___fixunssfdi,function
- + .align 2
- +___fixunssfdi:
- + LSLS D0Re0, D1Ar1, #1 ! Ignore sign bit
- + MOVZ PC, D1RtP ! Zero? return 0
- +
- + TSTT D1Ar1, #0x8000 ! Negative?
- + SUBNZ D0Re0, D0Re0, D0Re0 ! < 0
- + MOVNZ D1Re0, D0Re0
- + MOVNZ PC, D1RtP ! return 0
- +
- + LSR D0Ar6, D1Ar1, #23 ! extract exponent (D0Ar6)
- + SUBS D0Ar6, D0Ar6, #(127+63)
- +
- + SUBGT D0Re0, D0Re0, D0Re0 ! exp > 0 (overflow)
- + SUBGT D0Re0, D0Re0, #1
- + MOVGT D1Re0, D0Re0
- + MOVGT PC, D1RtP ! return MAX_UDI
- +
- + CMP D0Ar6, #-(64-1) ! -exp > (BITS_PER_DI - 1)
- +
- + SUBLT D0Re0, D0Re0, D0Re0 ! underflow
- + MOVLT D1Re0, D0Re0
- + MOVLT PC, D1RtP ! return 0
- +
- + LSL D1Re0, D1Ar1, #(63-32-23) ! extract mantisa MSWord
- + ORT D1Re0, D1Re0, #0x8000 ! add hidden bit
- +
- + CMP D0Ar6, #-32
- + NEG D0Ar4, D0Ar6
- + MOV D1Ar3, D0Ar4
- + BLE $L1
- +
- +!! Shift < 32 bits
- +
- + ORS D0Re0, D1Ar3, D1Ar3 ! shifting 0 ?
- + MOVZ PC, D1RtP !
- +
- + ADD D1Ar5, D0Ar6, #32 ! (-exp) + 32
- +
- + LSL D0Re0, D1Re0, D1Ar5 ! mant >> exp
- + LSR D1Re0, D1Re0, D1Ar3
- +
- + MOV PC, D1RtP
- +$L1:
- +!! Shift > 32 bits
- + SUB D1Ar3, D1Ar3, #32 ! exp -= 32
- +
- + LSR D0Re0, D1Re0, D1Ar3
- + MOV D1Re0, #0
- +
- + MOV PC, D1RtP
- + .size ___fixunssfdi,.-___fixunssfdi
- +#endif
- +
- +#ifdef L_fixunssfsi
- +!!
- +!! Floating point - float -> unsigned int/long
- +!!
- + .text
- + .global ___fixunssfsi
- + .type ___fixunssfsi,function
- + .align 2
- +___fixunssfsi:
- + LSLS D0Re0, D1Ar1, #1 ! Ignore sign bit
- + MOVZ PC, D1RtP ! Zero? return 0
- +
- + TSTT D1Ar1, #0x8000 ! Negative?
- + SUBNZ D0Re0, D0Re0, D0Re0 ! < 0
- + MOVNZ PC, D1RtP ! return 0
- +
- + LSR D0Ar6, D1Ar1, #23 ! extract exponent (D0Ar6)
- + SUBS D0Ar6, D0Ar6, #(127+31)
- +
- + SUBGT D0Re0, D0Re0, D0Re0 ! exp > 0 (overflow)
- + SUBGT D0Re0, D0Re0, #1
- + MOVGT PC, D1RtP ! return MAX_USI
- +
- + CMP D0Ar6, #-(32-1) ! -exp > (BITS_PER_SI - 1)
- +
- + SUBLT D0Re0, D0Re0, D0Re0 ! underflow
- + MOVLT PC, D1RtP ! return 0
- +
- + LSL D0Re0, D1Ar1, #(31-23) ! extract mantisa
- + ORT D0Re0, D0Re0, #0x8000 ! add hidden bit
- +
- + NEG D0Ar6, D0Ar6
- +
- + LSR D0Re0, D0Re0, D0Ar6 ! mant >> exp
- +
- + MOV PC, D1RtP
- + .size ___fixunssfsi,.-___fixunssfsi
- +#endif
- +
- +!! Integer -> Floating point conversion
- +
- +#ifdef L_floatdidf
- +!!
- +!! signed long long -> double conversion
- +!!
- + .text
- + .global ___floatdidf
- + .type ___floatdidf,function
- + .align 2
- +___floatdidf:
- +
- + MOV D1Ar3, #(1023+32+30) ! exp
- + MOV D0Ar6, #0 ! sign, assume +ve
- +
- + ORS D1Re0, D1Ar1, D1Ar1
- + BLT $L1
- + BGT $L2
- +
- + ORS D0Re0, D0Ar2, D0Ar2
- + BNE $L2
- +
- + MOV PC, D1RtP
- +
- +$L1:
- + ! <0
- + MOVT D0Ar6, #0x8000 ! sign, -ve
- +
- + NEGS D0Ar2, D0Ar2 ! negate
- + NEG D1Re0, D1Ar1
- + SUBNZ D1Re0, D1Re0, #1
- +
- + CMP D1Re0, #0 ! negative?
- + BGT $L2 ! branch, not MIN DI
- +
- +! Handle most negative value
- +
- + LSR D0Ar2, D0Ar2, #1 ! significand >>= 1
- + LSL D0Ar4, D1Re0, #(32-1)
- + OR D0Ar2, D0Ar2, D0Ar4
- + LSR D1Re0, D1Re0, #1
- +
- + ADD D1Ar3, D1Ar3, #1 ! exp += 1
- +
- +$L2:
- + MOV D0Re0, D0Ar2 ! mantisa
- + NORM D1Ar1, D1Re0 ! normalize up
- + BZ $L4 ! MSWord zero
- +
- + CMP D1Ar1, #0 ! Already normalised ?
- + BZ $L5 ! yes, skip normalisation
- +
- + MOV D0Ar4, D1Re0
- + FFB D0Ar4, D0Ar4
- +
- + LSL D1Re0, D1Re0, D1Ar1
- + ADD D0Ar4, D0Ar4, #2
- + LSR D1Ar5, D0Re0, D0Ar4
- + OR D1Re0, D1Re0, D1Ar5
- + MOV D0Ar4, D1Ar1
- + LSL D0Re0, D0Re0, D0Ar4
- +
- + SUB D1Ar3, D1Ar3, D1Ar1
- + B $L5
- +
- +$L4:
- + SWAP D1Re0, D0Re0 ! D1Re0 <- D0Re0, D0Re0 <- #0
- + SUB D1Ar3, D1Ar3, #32
- +
- + NORM D1Ar1, D1Re0
- + LSRLT D1Re0, D1Re0, #1 ! Watch out for low 32-bits with MSbit set
- + ADDLT D1Ar3, D1Ar3, #1 ! adjust exp and mantissa
- +
- + LSL D1Re0, D1Re0, D1Ar1
- +
- + SUB D1Ar3, D1Ar3, D1Ar1
- +
- +$L5:
- + TST D0Re0, #(1<<9) ! Test MSbit discared
- + LSR D0Re0, D0Re0, #10 ! Discard excess bits not representable
- + LSL D0Ar4, D1Re0, #(32 - 10)
- + LSR D1Re0, D1Re0, #10
- + OR D0Re0, D0Re0, D0Ar4
- + BZ $L7
- +
- + ADDS D0Re0, D0Re0, #1 ! Round up if MSbit discarded non-zero
- + ADDCS D1Re0, D1Re0, #1
- +
- +$L6:
- + TSTT D1Re0, #0xFFE0 ! Round up overflowed?
- + BZ $L7
- +
- + ADD D1Ar3, D1Ar3, #1 ! yes, adjust exp +=1
- + LSR D0Re0, D0Re0, #1 ! and adjust significand shifting >>1
- + LSL D0Ar4, D1Re0, #(32 - 1)
- + LSR D1Re0, D1Re0, #1
- + OR D0Re0, D0Re0, D0Ar4
- + B $L6
- +
- +$L7:
- + ANDMT D1Re0, D1Re0, #0x000F ! remove hidden bit <- mantisa MSword
- +
- + LSL D1Ar3, D1Ar3, #(52-32) ! position exp in result
- + MOV D1Ar1, D0Ar6 ! sign
- + OR D1Re0, D1Re0, D1Ar1 ! combine with sign -> sign | mant
- + OR D1Re0, D1Re0, D1Ar3 ! combine with exp -> sign | exp | mant
- +
- + MOV PC, D1RtP
- + .size ___floatdidf,.-___floatdidf
- +#endif
- +
- +#ifdef L_floatdisf
- +!!
- +!! signed signed long long -> float conversion
- +!!
- + .text
- + .global ___floatdisf
- + .type ___floatdisf,function
- +___floatdisf:
- +
- + MOV D0Ar6, #(127+32+30) ! exp
- + MOV D0Re0, #0 ! sign
- +
- + CMP D1Ar1, #0
- + BLT $L1
- + BGT $L2
- +
- + CMP D0Ar2, #0
- + BNE $L2
- +
- + MOV PC, D1RtP
- +$L1:
- + ! <0
- + MOVT D0Re0, #0x8000
- +
- + NEGS D0Ar2, D0Ar2 ! negate
- + NEG D1Ar1, D1Ar1
- + SUBNZ D1Ar1, D1Ar1, #1
- +
- + CMP D1Ar1, #0 ! deal min DI
- + BGT $L2 ! branch not min DI
- +
- + LSR D0Ar2, D0Ar2, #1 ! significand >> 1
- + MOV D0Ar4, D1Ar1
- + LSL D0Ar4, D0Ar4, #(32-1)
- + OR D0Ar2, D0Ar2, D0Ar4
- + LSR D1Ar1, D1Ar1, #1
- +
- + ADD D0Ar6, D0Ar6, #1 ! exp += 1
- +
- +$L2: ! normalize up
- + NORM D1Re0, D1Ar1
- + BZ $L4 ! MSWord zero
- +
- + CMP D1Re0, #0 ! Already normalised ?
- + BZ $L5 ! yes, skip normalisation
- +
- + MOV D0Ar4, D1Ar1
- + FFB D0Ar4, D0Ar4
- +
- + LSL D1Ar1, D1Ar1, D1Re0
- + ADD D0Ar4, D0Ar4, #2
- + LSR D1Ar5, D0Ar2, D0Ar4
- + OR D1Ar1, D1Ar1, D1Ar5
- + MOV D0Ar4, D1Re0
- + LSL D0Ar2, D0Ar2, D0Ar4
- +
- + MOV D0Ar4, D1Re0
- + SUB D0Ar6, D0Ar6, D0Ar4
- + B $L5
- +
- +$L4:
- + SWAP D1Ar1, D0Ar2 ! D1Ar1 <- D0Ar2, D0Ar2 <- #0
- + SUB D0Ar6, D0Ar6, #32
- +
- + NORM D1Re0, D1Ar1
- + LSL D1Ar1, D1Ar1, D1Re0
- +
- + MOV D0Ar4, D1Re0
- + SUB D0Ar6, D0Ar6, D0Ar4
- +
- +$L5:
- + MOV D0Ar2, D1Ar1
- + TST D0Ar2, #(1<<6) ! Round before discarding
- + LSR D0Ar2, D0Ar2, #7 ! Discard excess bits not representable
- + ADDNZ D0Ar2, D0Ar2, #1
- +
- +$L6:
- + TSTT D0Ar2, #0xFF00 ! Round up overflowed?
- + BZ $L7
- +
- + ADD D0Ar6, D0Ar6, #1 ! yes, adjust exp += 1
- + LSR D0Ar2, D0Ar2, #1 ! adn adjust significand shifting >>1
- + B $L6
- +
- +$L7:
- + ANDMT D0Ar2, D0Ar2, #0x007F ! remove hidden bit <- mantisa
- +
- + LSL D0Ar6, D0Ar6, #23 ! position exp in result
- + OR D0Re0, D0Re0, D0Ar6 ! combine sign with exp -> sign|exp
- + OR D0Re0, D0Re0, D0Ar2 ! combine sign|exp with mant -> sign|exp|mant
- +
- + MOV PC, D1RtP
- + .size ___floatdisf,.-___floatdisf
- +#endif
- +
- +#ifdef L_floatsidf
- +!!
- +!! signed int/long -> double conversion
- +!!
- + .text
- + .global ___floatsidf
- + .type ___floatsidf,function
- + .align 2
- +___floatsidf:
- +
- + MOV D1Ar5, #(1023+30) ! exp
- + MOV D1Re0, #0 ! assume result +ve
- + CMP D1Ar1, #0 ! num < 0
- + BGT $L2
- +
- + ! <= 0
- + MOVEQ D0Re0, D1Re0
- + MOVEQ PC, D1RtP ! num == 0 return 0
- +
- + ! < 0
- + MOVT D1Re0, #0x8000 ! result will be -ve
- + NEG D1Ar1, D1Ar1 ! num -= num
- + CMP D1Ar1, #0 ! num < 0
- + BGT $L2
- +
- + ! < 0 (num == MIN_INT)
- + LSR D1Ar1, D1Ar1, #1 ! num >>= 1
- + ADD D1Ar5, D1Ar5, #1 ! exp += 1
- +
- +$L2:
- + NORM D1Ar3, D1Ar1 ! Make MSBit non-zero
- + LSL D1Ar1, D1Ar1, D1Ar3 ! num <<= N
- + SUB D1Ar5, D1Ar5, D1Ar3 ! exp -= N
- +
- + MOV D0Re0, D1Ar1 ! position mantisa LSWord
- + LSL D0Re0, D0Re0, #(32-10)
- +
- + LSL D1Ar5, D1Ar5, #(52-32) ! position exponent
- + OR D1Re0, D1Re0, D1Ar5 ! combine sign | exp
- +
- + LSR D1Ar1, D1Ar1, #10 ! position significand MSWord
- + ANDMT D1Ar1, D1Ar1, #0x000F ! discard hidden bit
- + OR D1Re0, D1Re0, D1Ar1 ! combine sign | exp | mantisa
- +
- + MOV PC, D1RtP
- + .size ___floatsidf,.-___floatsidf
- +#endif
- +
- +#ifdef L_floatunsidf
- +!!
- +!! unsigned int/long -> double conversion
- +!!
- + .text
- + .global ___floatunsidf
- + .type ___floatunsidf,function
- + .align 2
- +___floatunsidf:
- +
- + MOV D1Ar5, #(1023+30) ! exp
- + MOV D1Re0, #0 ! assume result +ve
- + CMP D1Ar1, #0 ! num == 0
- +
- + ! == 0
- + MOVEQ D0Re0, D1Re0
- + MOVEQ PC, D1RtP ! num == 0 return 0
- +
- + NORM D1Ar3, D1Ar1 ! Make MSBit non-zero
- + LSL D1Ar1, D1Ar1, D1Ar3 ! num <<= N
- + SUB D1Ar5, D1Ar5, D1Ar3 ! exp -= N
- +
- + MOV D0Re0, D1Ar1 ! position mantisa LSWord
- + LSL D0Re0, D0Re0, #(32-10)
- +
- + LSL D1Ar5, D1Ar5, #(52-32) ! position exponent
- + OR D1Re0, D1Re0, D1Ar5 ! combine sign | exp
- +
- + LSR D1Ar1, D1Ar1, #10 ! position significand MSWord
- + ANDMT D1Ar1, D1Ar1, #0x000F ! discard hidden bit
- + OR D1Re0, D1Re0, D1Ar1 ! combine sign | exp | mantisa
- +
- + MOV PC, D1RtP
- + .size ___floatunsidf,.-___floatunsidf
- +#endif
- +
- +#ifdef L_floatsisf
- +!!
- +!! signed int/long -> float conversion
- +!!
- + .text
- + .global ___floatsisf
- + .type ___floatsisf,function
- + .align 2
- +___floatsisf:
- + MOV D0Ar6, #(127+32-2) ! exp
- + MOV D1Re0, #0 ! sign
- + ORS D0Re0, D1Ar1, D1Ar1 ! num ? -ve, zero, +ve
- + BGT $L2 ! branch, +ve
- + ! <=
- + MOVZ PC, D1RtP ! zero, return 0
- +
- + ! < 0
- + MOVT D1Re0, #0x8000 ! sign
- + NEGS D1Ar1, D1Ar1 ! Make >= 0
- + BGT $L2 ! branch, +ve
- +
- + ! Handle MIN INT
- + LSR D1Ar1, D1Ar1, #1 ! num >>= 1
- + ADD D0Ar6, D0Ar6, #1 ! exp += 1
- +
- +$L2: ! num > 0
- + NORM D1Ar3, D1Ar1 ! Shift up N bits
- + LSL D1Ar1, D1Ar1, D1Ar3 ! num <<= N
- + MOV D0Ar4, D1Ar3
- + SUB D0Ar6, D0Ar6, D0Ar4 ! exp -= N
- +
- + LSR D1Ar1, D1Ar1, #(8-2)
- + ADD D1Ar1, D1Ar1, #1 ! round
- + MOV D0Re0, D1Ar1 ! mantisa --> D0Re0
- +
- + TSTT D1Ar1, #0xFE00 ! rounding overflowed ?
- + ADDNZ D0Ar6, D0Ar6, #1 ! yes, adjust exp++
- + LSR D0Re0, D0Re0, #1 ! position mantisa
- +
- + LSL D0Ar6, D0Ar6, #23 ! position exponent
- + ANDMT D0Re0, D0Re0, #0x007F ! remove hidden bit
- + OR D0Re0, D0Re0, D0Ar6 ! man | exp
- +
- + MOV D0Ar6, D1Re0
- + OR D0Re0, D0Re0, D0Ar6 ! |sign
- +
- + MOV PC, D1RtP
- + .size ___floatsisf,.-___floatsisf
- +#endif
- +
- +#ifdef L_floatunsisf
- +!!
- +!! signed int/long -> float conversion
- +!!
- + .text
- + .global ___floatunsisf
- + .type ___floatunsisf,function
- + .align 2
- +___floatunsisf:
- + MOV D0Ar6, #(127+32-2) ! exp
- + ORS D0Re0, D1Ar1, D1Ar1 ! num ? -ve, zero, +ve
- + ! <=
- + MOVZ PC, D1RtP ! zero, return 0
- +
- + NORM D1Ar3, D1Ar1 ! Shift up N bits
- + LSL D1Ar1, D1Ar1, D1Ar3 ! num <<= N
- + MOV D0Ar4, D1Ar3
- + SUB D0Ar6, D0Ar6, D0Ar4 ! exp -= N
- +
- + LSR D1Ar1, D1Ar1, #(8-2)
- + ADD D1Ar1, D1Ar1, #1 ! round
- + MOV D0Re0, D1Ar1 ! mantisa --> D0Re0
- +
- + TSTT D1Ar1, #0xFE00 ! rounding overflowed ?
- + ADDNZ D0Ar6, D0Ar6, #1 ! yes, adjust exp++
- + LSR D0Re0, D0Re0, #1 ! position mantisa
- +
- + LSL D0Ar6, D0Ar6, #23 ! position exponent
- + ANDMT D0Re0, D0Re0, #0x007F ! remove hidden bit
- + OR D0Re0, D0Re0, D0Ar6 ! man | exp
- +
- + MOV PC, D1RtP
- + .size ___floatunsisf,.-___floatunsisf
- +#endif
- +
- +#ifdef L_unordsf2
- + .text
- + .global ___unordsf2
- + .type ___unordsf2,function
- + .align 2
- +___unordsf2:
- + MOV PC, D1RtP
- +#endif
- +
- +#ifdef L_unorddf2
- + .text
- + .global ___unorddf2
- + .type ___unorddf2,function
- + .align 2
- +___unorddf2:
- + MOV PC, D1RtP
- + .size ___unorddf2,.-___unorddf2
- +#endif
- +
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/linux-atomic.asm gcc-4.2.4/gcc/config/metag/linux-atomic.asm
- --- gcc-4.2.4.orig/gcc/config/metag/linux-atomic.asm 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/linux-atomic.asm 2015-07-03 18:46:05.749283542 -0500
- @@ -0,0 +1,227 @@
- +.macro linkset_check
- + DEFR D0FrT, TXSTAT
- + ANDT D0FrT, D0FrT, #HI(0x3F000000)
- + CMPT D0FrT, #HI(0x02000000)
- +.endm
- +
- +.macro func_start func_name
- + .text
- + .global \func_name
- + .type \func_name,function
- + .align 2
- +\func_name:
- +1:
- +.endm
- +
- +.macro func_end func_name
- + linkset_check
- + BNE 1b
- + cache_flush
- + 2: MOV PC, D1RtP
- + .size \func_name, .-\func_name
- +.endm
- +
- +.macro cache_flush
- + MOV D0FrT, #0
- + DCACHE [D1Ar1], D0FrT
- +.endm
- +
- +.macro sync_fetch_and_op op op_name n mode
- +func_start ___sync_fetch_and_\op_name\()_\n
- + LNKGET\mode D0Re0, [D1Ar1]
- + \op D0FrT, D0Re0, D0Ar2
- + LNKSET\mode [D1Ar1], D0FrT
- +func_end ___sync_fetch_and_\op_name\()_\n
- +.endm
- +
- +.macro sync_fetch_and_op_8 op op_name
- +func_start ___sync_fetch_and_\op_name\()_8
- + LNKGETL D0Re0, D1Re0, [D1Ar1]
- + \op A0.2, D0Re0, D0Ar4
- + \op A1.2, D1Re0, D1Ar3
- + LNKSETL [D1Ar1], A0.2, A1.2
- +func_end ___sync_fetch_and_\op_name\()_8
- +.endm
- +
- +.macro sync_fetch_and_alu_op_8 op op_name
- +func_start ___sync_fetch_and_\op_name\()_8
- + LNKGETL D0Re0, D1Re0, [D1Ar1]
- + \op\()S A0.2, D0Re0, D0Ar4
- + \op A1.2, D1Re0, D1Ar3
- + \op\()CS A1.2, A1.2, #1
- + LNKSETL [D1Ar1], A0.2, A1.2
- +func_end ___sync_fetch_and_\op_name\()_8
- +.endm
- +
- +.macro sync_op_and_fetch op op_name n mode
- +func_start ___sync_\op_name\()_and_fetch_\n
- + LNKGET\mode D0Re0, [D1Ar1]
- + \op D0Re0, D0Re0, D0Ar2
- + LNKSET\mode [D1Ar1], D0Re0
- +func_end ___sync_\op_name\()_and_fetch_\n
- +.endm
- +
- +.macro sync_op_and_fetch_8 op op_name
- +func_start ___sync_\op_name\()_and_fetch_8
- + LNKGETL D0Re0, D1Re0, [D1Ar1]
- + \op D0Re0, D0Re0, D0Ar4
- + \op D1Re0, D1Re0, D1Ar3
- + LNKSETL [D1Ar1], D0Re0, D1Re0
- +func_end ___sync_\op_name\()_and_fetch_8
- +.endm
- +
- +.macro sync_alu_op_and_fetch_8 op op_name
- +func_start ___sync_\op_name\()_and_fetch_8
- + LNKGETL D0Re0, D1Re0, [D1Ar1]
- + \op\()S D0Re0, D0Re0, D0Ar4
- + \op D1Re0, D1Re0, D1Ar3
- + \op\()CS D1Re0, D1Re0, #1
- + LNKSETL [D1Ar1], D0Re0, D1Re0
- +func_end ___sync_\op_name\()_and_fetch_8
- +.endm
- +
- +.macro sync_fetch_and_op_neg op op_name n mode
- +func_start ___sync_fetch_and_\op_name\()_\n
- + LNKGET\mode D0Re0, [D1Ar1]
- + \op D0FrT, D0Re0, D0Ar2
- + XOR D0FrT, D0FrT, #-1
- + LNKSET\mode [D1Ar1], D0FrT
- +func_end ___sync_fetch_and_\op_name\()_\n
- +.endm
- +
- +.macro sync_fetch_and_op_neg_8 op op_name
- +func_start ___sync_fetch_and_\op_name\()_8
- + LNKGETL D0Re0, D1Re0, [D1Ar1]
- + \op D0Ar6, D0Re0, D0Ar4
- + \op D1Ar5, D1Re0, D1Ar3
- + XOR D0Ar6, D0Ar6, #-1
- + XOR D1Ar5, D1Ar5, #-1
- + LNKSETL [D1Ar1], D0Ar6, D1Ar5
- +func_end ___sync_fetch_and_\op_name\()_8
- +.endm
- +
- +.macro sync_op_neg_and_fetch op op_name n mode
- +func_start ___sync_\op_name\()_and_fetch_\n
- + LNKGET\mode D0Re0, [D1Ar1]
- + \op D0Re0, D0Re0, D0Ar2
- + XOR D0Re0, D0Re0, #-1
- + LNKSET\mode [D1Ar1], D0Re0
- +func_end ___sync_\op_name\()_and_fetch_\n
- +.endm
- +
- +.macro sync_op_neg_and_fetch_8 op op_name
- +func_start ___sync_\op_name\()_and_fetch_8
- + LNKGETL D0Re0, D1Re0, [D1Ar1]
- + \op D0Re0, D0Re0, D0Ar4
- + \op D1Re0, D1Re0, D1Ar3
- + XOR D0Re0, D0Re0, #-1
- + XOR D1Re0, D1Re0, #-1
- + LNKSETL [D1Ar1], D0Re0, D1Re0
- +func_end ___sync_\op_name\()_and_fetch_8
- +.endm
- +
- +.macro sync_val_compare_and_swap n mode
- +func_start ___sync_val_compare_and_swap_\n
- + LNKGET\mode D0Re0, [D1Ar1]
- + CMP D0Re0, D0Ar2
- + LNKSET\mode\()EQ [D1Ar1], D1Ar3
- + BNE 2f
- +func_end ___sync_val_compare_and_swap_\n
- +.endm
- +
- +func_start ___sync_val_compare_and_swap_8
- + LNKGETL D0Re0, D1Re0, [D1Ar1]
- + CMP D0Re0, D0Ar4
- + CMPEQ D1Re0, D1Ar3
- + LNKSETLEQ [D1Ar1], D0Ar6, D1Ar5
- + BNE 2f
- +func_end ___sync_val_compare_and_swap_8
- +
- +.macro sync_bool_compare_and_swap n mode
- +func_start ___sync_bool_compare_and_swap_\n
- + MOV D0Re0, #1
- + 1: LNKGET\mode D0FrT, [D1Ar1]
- + CMP D0FrT, D0Ar2
- + LNKSET\mode\()EQ [D1Ar1], D1Ar3
- + XORNE D0Re0, D0Re0, D0Re0
- + BNE 2f
- +func_end ___sync_bool_compare_and_swap_\n
- +.endm
- +
- +func_start ___sync_bool_compare_and_swap_8
- + MOV D0Re0, #1
- + 1: LNKGETL A0.2, A1.2, [D1Ar1]
- + CMP D0Ar4, A0.2
- + CMPEQ D1Ar3, A1.2
- + LNKSETLEQ [D1Ar1], D0Ar6, D1Ar5
- + XORNE D0Re0, D0Re0, D0Re0
- + BNE 2f
- +func_end ___sync_bool_compare_and_swap_8
- +
- +.macro sync_lock_test_and_set n mode
- +func_start ___sync_lock_test_and_set_\n
- + LNKGET\mode D0Re0, [D1Ar1]
- + LNKSET\mode [D1Ar1], D0Ar2
- +func_end ___sync_lock_test_and_set_\n
- +.endm
- +
- +func_start ___sync_lock_test_and_set_8
- + LNKGETL D0Re0, D1Re0, [D1Ar1]
- + LNKSETL [D1Ar1], D0Ar4, D1Ar3
- +func_end ___sync_lock_test_and_set_8
- +
- +.macro sync_fetch_and_op_size op op_name
- + sync_fetch_and_op \op \op_name 1 B
- + sync_fetch_and_op \op \op_name 2 W
- + sync_fetch_and_op \op \op_name 4 D
- +
- + sync_op_and_fetch \op \op_name 1 B
- + sync_op_and_fetch \op \op_name 2 W
- + sync_op_and_fetch \op \op_name 4 D
- +.endm
- +
- +.macro sync_fetch_and_op_neg_size op op_name
- + sync_fetch_and_op_neg \op \op_name 1 B
- + sync_fetch_and_op_neg \op \op_name 2 W
- + sync_fetch_and_op_neg \op \op_name 4 D
- + sync_fetch_and_op_neg_8 \op \op_name
- +
- + sync_op_neg_and_fetch \op \op_name 1 B
- + sync_op_neg_and_fetch \op \op_name 2 W
- + sync_op_neg_and_fetch \op \op_name 4 D
- + sync_op_neg_and_fetch_8 \op \op_name
- +.endm
- +
- +sync_fetch_and_op_size ADD add
- +sync_fetch_and_op_size SUB sub
- +sync_fetch_and_op_size OR or
- +sync_fetch_and_op_size AND and
- +sync_fetch_and_op_size XOR xor
- +
- +sync_fetch_and_op_8 OR or
- +sync_fetch_and_op_8 AND and
- +sync_fetch_and_op_8 XOR xor
- +
- +sync_op_and_fetch_8 OR or
- +sync_op_and_fetch_8 AND and
- +sync_op_and_fetch_8 XOR xor
- +
- +sync_fetch_and_alu_op_8 ADD add
- +sync_fetch_and_alu_op_8 SUB sub
- +
- +sync_alu_op_and_fetch_8 ADD add
- +sync_alu_op_and_fetch_8 SUB sub
- +
- +sync_fetch_and_op_neg_size AND nand
- +
- +sync_val_compare_and_swap 1 B
- +sync_val_compare_and_swap 2 W
- +sync_val_compare_and_swap 4 D
- +
- +sync_bool_compare_and_swap 1 B
- +sync_bool_compare_and_swap 2 W
- +sync_bool_compare_and_swap 4 D
- +
- +sync_lock_test_and_set 1 B
- +sync_lock_test_and_set 2 W
- +sync_lock_test_and_set 4 D
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/linux-elf.h gcc-4.2.4/gcc/config/metag/linux-elf.h
- --- gcc-4.2.4.orig/gcc/config/metag/linux-elf.h 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/linux-elf.h 2015-07-03 18:46:05.749283542 -0500
- @@ -0,0 +1,77 @@
- +/* Definitions of target machine for GNU compiler
- + for Meta Linux-based GNU systems using ELF.
- + Copyright (C) 2004, 2007 Free Software Foundation, Inc.
- + Contributed by Imagination Technologies Ltd (toolkit@metagence.com)
- +
- +This file is part of GCC.
- +
- +GCC 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 3, or (at your option) any later
- +version.
- +
- +GCC 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 GCC; see the file COPYING3. If not see
- +<http://www.gnu.org/licenses/>. */
- +
- +#undef TARGET_VERSION
- +#define TARGET_VERSION fputs (" (Metag Linux GNU)", stderr)
- +
- +#undef SUBTARGET_EXTRA_SPECS
- +#define SUBTARGET_EXTRA_SPECS \
- + { "elf_dynamic_linker", ELF_DYNAMIC_LINKER },
- +
- +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0"
- +
- +#define TARGET_OS_CPP_BUILTINS() \
- + do \
- + { \
- + LINUX_TARGET_OS_CPP_BUILTINS (); \
- + } \
- +while (0)
- +
- +#undef LIB_SPEC
- +#define LIB_SPEC \
- + "%{pthread:-lpthread} " \
- + "%{shared:-lc} " \
- + "%{!shared: %{profile:-lc_p} %{!profile:-lc}} "
- +
- +#undef TYPE_OPERAND_FMT
- +#define TYPE_OPERAND_FMT "@%s"
- +
- +#undef GLOBAL_ASM_OP
- +#define GLOBAL_ASM_OP "\t.global\t"
- +
- +
- +/* Provide a STARTFILE_SPEC appropriate for ELF. Here we add the
- + (even more) magical crtbegin.o file which provides part of the
- + support for getting C++ file-scope static object constructed before
- + entering `main'.
- +
- + Don't bother seeing crtstuff.c -- there is absolutely no hope of
- + getting that file to understand multiple GPs. GNU Libc provides a
- + hand-coded version that is used on Linux; it could be copied here
- + if there is ever a need. */
- +
- +#undef STARTFILE_SPEC
- +#define STARTFILE_SPEC \
- + "%{!shared: " \
- + "%{pg:crt1.o%s} %{!pg:%{p:crt1.o%s} " \
- + "%{!p:%{profile:crt1.o%s} " \
- + "%{!profile:crt1.o%s}}}} " \
- + "crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s} "
- +
- +/* Provide a ENDFILE_SPEC appropriate for ELF. Here we tack on the
- + magical crtend.o file which provides part of the support for
- + getting C++ file-scope static object constructed before entering
- + `main', followed by a normal ELF "finalizer" file, `crtn.o'. */
- +
- +#undef ENDFILE_SPEC
- +#define ENDFILE_SPEC \
- + "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
- +
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/linux.h gcc-4.2.4/gcc/config/metag/linux.h
- --- gcc-4.2.4.orig/gcc/config/metag/linux.h 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/linux.h 2015-07-03 18:46:05.749283542 -0500
- @@ -0,0 +1,32 @@
- +/* Definitions of target machine for GNU compiler,
- + for Meta Linux-based GNU systems.
- + Copyright (C) 2005, 2007 Free Software Foundation, Inc.
- + Contributed by Imagination Technologies Ltd (toolkit@metagence.com)
- +
- +This file is part of GCC.
- +
- +GCC 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 3, or (at your option) any later
- +version.
- +
- +GCC 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 GCC; see the file COPYING3. If not see
- +<http://www.gnu.org/licenses/>. */
- +
- +#undef CPP_SUBTARGET_SPEC
- +#define CPP_SUBTARGET_SPEC \
- + "%{posix:-D_POSIX_SOURCE} " \
- + "%{pthread:-D_REENTRANT -D_PTHREADS} "
- +
- +#define NO_IMPLICIT_EXTERN_C
- +
- +#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
- +
- +#undef TARGET_C99_FUNCTIONS
- +#define TARGET_C99_FUNCTIONS 1
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/metag.c gcc-4.2.4/gcc/config/metag/metag.c
- --- gcc-4.2.4.orig/gcc/config/metag/metag.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/metag.c 2015-07-03 18:46:05.765283542 -0500
- @@ -0,0 +1,7661 @@
- +/* Definitions of target machine for GNU compiler.
- + Imagination Technologies Meta version.
- + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
- + Imagination Technologies Ltd
- +
- +This file is part of GCC.
- +
- +GCC 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 3, or (at your option) any later
- +version.
- +
- +GCC 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 GCC; see the file COPYING3. If not see
- +<http://www.gnu.org/licenses/>. */
- +
- +#include "config.h"
- +#include "system.h"
- +#include "coretypes.h"
- +#include "tm.h"
- +#include "rtl.h"
- +#include "tree.h"
- +#include "obstack.h"
- +#include "regs.h"
- +#include "hard-reg-set.h"
- +#include "real.h"
- +#include "insn-config.h"
- +#include "conditions.h"
- +#include "insn-flags.h"
- +#include "output.h"
- +#include "insn-attr.h"
- +#include "flags.h"
- +#include "reload.h"
- +#include "function.h"
- +#include "expr.h"
- +#include "optabs.h"
- +#include "toplev.h"
- +#include "recog.h"
- +#include "ggc.h"
- +#include "except.h"
- +#include "c-pragma.h"
- +#include "integrate.h"
- +#include "cfgloop.h"
- +#include "tm_p.h"
- +#include "timevar.h"
- +#include "options.h"
- +#include "cgraph.h"
- +#include "target.h"
- +#include "target-def.h"
- +#include "tm-constrs.h"
- +#include "langhooks.h"
- +#include "version.h"
- +#include <ctype.h>
- +
- +/* Is the given character a logical line separator for the assembler?
- + Set the default to be the gas line separator and allow the embedded
- + backend to override it. */
- +#ifndef IS_ASM_LOGICAL_LINE_SEPARATOR
- +#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == ';')
- +#endif
- +
- +#define IS_PSEUDO_REGNO(REGNO) \
- + ((REGNO) != INVALID_REGNUM && (REGNO) >= FIRST_PSEUDO_REGISTER)
- +
- +#define IS_HARD_OR_VIRT_REGNO(REGNO) \
- + ((REGNO) != INVALID_REGNUM && (REGNO) < FIRST_PSEUDO_REGISTER)
- +
- +#define NO_FUNCTION_CSE
- +
- +#define REGNO_BIT(REGNO) (1U << ((REGNO) >> 1))
- +
- +#define df_regs_ever_live_p(REGNO) regs_ever_live[(unsigned)(REGNO)]
- +
- +static tree metag_handle_model_decl_attribute (tree *, tree, tree, int, bool *);
- +static int metag_consumer_stalls_from_load_multi (rtx, rtx);
- +static bool metag_consumer_is_o2r (rtx, rtx, int, int);
- +static bool metag_pass_in_reg (CUMULATIVE_ARGS *, enum machine_mode, tree, bool);
- +static bool metag_same_reg_p (rtx, rtx, bool);
- +static long metag_const_double_sfmode (rtx);
- +static unsigned int metag_calculate_ech_ctx (void);
- +static unsigned int metag_adjust_savesize_ech (unsigned int*, unsigned int*,
- + unsigned int*);
- +static void metag_emit_byte_swap16 (rtx, rtx);
- +static void metag_emit_byte_swap32 (rtx, rtx);
- +static int metag_asm_insn_count (rtx);
- +static bool metag_is_label_within_function (rtx);
- +static rtx metag_function_return_reg (enum machine_mode mode);
- +
- +/* METAG specific attribute support.
- +
- + model - select code model used to access data
- +
- + on VAR_DECL effects code that references symbol (weak effect)
- +
- + small: intended to be addressed using A1GbP+OG(..) (1 inst)
- + large: intended to be addresses using A1GbP+HI(..)+LO(..) (3 insts)
- +
- + on FUNCTION_DECL effects code within function concerned (strong effect)
- +
- + small: access all small data using A1GbP+OG(..) (no fn overhead)
- + access all larger data using A1GbP+OLA(..)
- + large: access all data using A1GbP+HI(..)+LO(..) (no fn overhead)
- +
- +*/
- +
- +const struct
- +attribute_spec metag_attribute_table[] =
- +{
- +/*{ name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
- + { "model", 1, 1, true, false, false, metag_handle_model_decl_attribute },
- + { NULL, 0, 0, false, false, false, NULL }
- +};
- +
- +#define DEF_MCC \
- + DEF_MCC_CODES(A, NV, "A"), \
- + DEF_MCC_CODES(NV, A, "NV"), \
- + DEF_MCC_CODES(EQ, NE, "EQ"), \
- + DEF_MCC_CODES(NE, EQ, "NE"), \
- + DEF_MCC_CODES(LO, HS, "LO"), \
- + DEF_MCC_CODES(HS, LO, "HS"), \
- + DEF_MCC_CODES(MI, PL, "MI"), \
- + DEF_MCC_CODES(PL, MI, "PL"), \
- + DEF_MCC_CODES(VS, VC, "VS"), \
- + DEF_MCC_CODES(VC, VS, "VC"), \
- + DEF_MCC_CODES(HI, LS, "HI"), \
- + DEF_MCC_CODES(LS, HI, "LS"), \
- + DEF_MCC_CODES(GE, LT, "GE"), \
- + DEF_MCC_CODES(LT, GE, "LT"), \
- + DEF_MCC_CODES(GT, LE, "GT"), \
- + DEF_MCC_CODES(LE, GT, "LE"), \
- + DEF_MCC_CODES(CS, CC, "CS"), \
- + DEF_MCC_CODES(CC, CS, "CC"), \
- + DEF_MCC_CODES(FEQ, UNE, "FEQ"), \
- + DEF_MCC_CODES(UNE, FEQ, "UNE"), \
- + DEF_MCC_CODES(FGT, NFGT, "FGT"), \
- + DEF_MCC_CODES(FGE, NFGE, "FGE"), \
- + DEF_MCC_CODES(FLT, NFLT, "FLT"), \
- + DEF_MCC_CODES(FLE, NFLE, "FLE"), \
- + DEF_MCC_CODES(U, NU, "UVS"), \
- + DEF_MCC_CODES(FLEG, NFLEG, "FVC"), \
- + DEF_MCC_CODES(UGT, NUGT, "UGT"), \
- + DEF_MCC_CODES(UGE, NUGE, "UGE"), \
- + DEF_MCC_CODES(ULT, NULT, "ULT"), \
- + DEF_MCC_CODES(ULE, NULE, "ULE"), \
- + DEF_MCC_CODES(NFGT, FGT, "ULE"), \
- + DEF_MCC_CODES(NFGE, FGE, "ULT"), \
- + DEF_MCC_CODES(NFLT, FLT, "UGE"), \
- + DEF_MCC_CODES(NFLE, FLE, "UGT"), \
- + DEF_MCC_CODES(NU, U, "FVC"), \
- + DEF_MCC_CODES(NFLEG, FLEG, "UVS"), \
- + DEF_MCC_CODES(NUGT, UGT, "FLE"), \
- + DEF_MCC_CODES(NUGE, UGE, "FLT"), \
- + DEF_MCC_CODES(NULT, ULT, "FGE"), \
- + DEF_MCC_CODES(NULE, ULE, "FGT")
- +
- +#define MCC_MAX MCC_NULE
- +
- +#define DEF_MCC_CODES(CODE, INV, ASMCODE) MCC_##CODE
- +
- +typedef enum /* GCC : META condition codes */
- +{
- + DEF_MCC
- +} metag_cc;
- +
- +static metag_cc get_metag_cc (rtx);
- +static metag_cc get_metag_cc_float (enum rtx_code);
- +static bool metag_is_cc_quiet (metag_cc);
- +
- +#undef DEF_MCC_CODES
- +#define DEF_MCC_CODES(CODE, INV, ASMCODE) MCC_##INV
- +static metag_cc const metag_inv_cc[MCC_MAX + 1] =
- +{
- + DEF_MCC
- +};
- +
- +#undef DEF_MCC_CODES
- +#define DEF_MCC_CODES(CODE, INV, ASMCODE) ASMCODE
- +
- +static const char * const metag_cc_names[MCC_MAX + 1] =
- +{
- + DEF_MCC
- +};
- +
- +rtx metag_compare_op0;
- +rtx metag_compare_op1;
- +
- +enum metag_model metag_model;
- +
- +/* Which META core we're generating code for. */
- +enum metac_target metac_target;
- +
- +/* Which META core we are scheduling for see (define_attr "metacore" ...) */
- +enum attr_metacore metacore;
- +
- +/* What FPU pipeline are we targetting */
- +int metag_fpu_single = 0;
- +
- +/* Are we allowed to use any fpu resources */
- +int metag_fpu_resources = 0;
- +
- +/* How wide is the widest memory access on this core */
- +int metag_memory_width = 64;
- +
- +/* Should MiniM jump tables be emitted short, long or auto detected */
- +enum metag_jump_table_branch metag_jump_table_branch = METAG_MINIM_JUMP_TABLE_BRANCH_AUTO;
- +
- +/* -mextensions flags */
- +bool metag_meta2_bex_enabled = false;
- +
- +/* Force tbictxsave to be enabled */
- +int metag_force_tbictxsave = true;
- +
- +/* A finite state machine takes care of noticing whether or not instructions
- + can be conditionally executed, and thus decrease execution time and code
- + size by deleting branch instructions. The fsm is controlled by
- + final_prescan_insn, and controls the actions of ASM_OUTPUT_OPCODE. */
- +
- +/* For an explanation of these variables, see final_prescan_insn below. */
- +static int metag_ccfsm_state;
- +static metag_cc metag_current_cc;
- +static GTY(()) rtx metag_target_insn = NULL_RTX;
- +static int metag_target_label;
- +static int metag_max_insns_skipped = 10;
- +
- +#define METAG_DEBUG_CCEXEC 0
- +
- +#if METAG_DEBUG_CCEXEC
- +static const char *attr_cond_name (enum attr_cond);
- +static const char *attr_ccstate_name (enum attr_ccstate);
- +static const char *attr_predicale_name (enum attr_predicable);
- +#endif
- +
- +
- +bool
- +metag_datareg_p (unsigned int regno)
- +{
- +#if FIRST_DATA_REG == 0
- + return regno <= LAST_DATA_REG;
- +#else
- + return FIRST_DATA_REG <= regno && regno <= LAST_DATA_REG;
- +#endif
- +}
- +
- +bool
- +metag_addrreg_p (unsigned int regno)
- +{
- + return FIRST_ADDR_REG <= regno && regno <= LAST_ADDR_REG;
- +}
- +
- +bool
- +metag_fpcreg_p (unsigned int regno)
- +{
- + return FIRST_FP_REG <= regno && regno <= LAST_FP_REG;
- +}
- +
- +bool
- +metag_fppreg_p (unsigned int regno)
- +{
- + return FIRST_FP_REG <= regno && regno <= LAST_FP_REG && ((regno - FIRST_FP_REG) & 1) == 0;
- +}
- +
- +#define METAG_DATAREG_UNIT(REGNO) ((REGNO) & 1)
- +#define METAG_DATAREG_REGN(REGNO) ((REGNO) >> 1)
- +
- +static long
- +metag_const_double_sfmode (rtx op)
- +{
- + long l;
- + REAL_VALUE_TYPE rv;
- +
- + REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
- + REAL_VALUE_TO_TARGET_SINGLE (rv, l);
- + return l;
- +}
- +
- +void
- +metag_split_movsi_immediate (rtx operands[])
- +{
- + rtx target= operands[0];
- + rtx imm = operands[1];
- + HOST_WIDE_INT value = INTVAL (imm);
- +
- + if ((value & 0x0000FFFF) == 0)
- + emit_move_insn (target, imm);
- + else if ((value & 0xFFFF0000) == 0)
- + emit_move_insn (target, imm);
- + else if ((value & 0xFFFF8000) == 0xFFFF8000)
- + emit_move_insn (target, imm);
- + else
- + {
- + HOST_WIDE_INT ival;
- +
- + ival = trunc_int_for_mode (value & 0xFFFF0000, SImode);
- + emit_move_insn (target, GEN_INT (ival));
- +
- + ival = trunc_int_for_mode (value & 0x0000FFFF, SImode);
- + emit_insn (gen_addsi3 (target, target, GEN_INT (ival)));
- + }
- +}
- +
- +void
- +metag_split_movsf_immediate (rtx operands[])
- +{
- + rtx ops[2];
- +
- + ops[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
- + if (CONST_DOUBLE_P (operands[1]))
- + {
- + HOST_WIDE_INT ival = metag_const_double_sfmode (operands[1]);
- +
- + ival = trunc_int_for_mode (ival, SImode);
- + ops[1] = GEN_INT (ival);
- + }
- + else if (CONST_INT_P (operands[1]))
- + ops[1] = operands[1];
- + else
- + gcc_unreachable ();
- +
- + metag_split_movsi_immediate (ops);
- +}
- +
- +void
- +metag_split_movdi (rtx operands[])
- +{
- + unsigned int dst_reg = REGNO (operands[0]);
- + unsigned int src_reg = REGNO (operands[1]);
- +
- + emit_move_insn (gen_rtx_REG (SImode, dst_reg),
- + gen_rtx_REG (SImode, src_reg));
- +
- + emit_move_insn (gen_rtx_REG (SImode, dst_reg + 1),
- + gen_rtx_REG (SImode, src_reg + 1));
- +}
- +
- +void
- +metag_split_movdi_immediate (rtx operands[])
- +{
- + unsigned int dst_reg = REGNO (operands[0]);
- + rtx imm[2];
- + rtx ops[2];
- +
- + split_double (operands[1], &imm[0], &imm[1]);
- +
- + ops[0] = gen_rtx_REG (SImode, dst_reg);
- + ops[1] = imm[0];
- + metag_split_movsi_immediate (ops);
- +
- + ops[0] = gen_rtx_REG (SImode, dst_reg + 1);
- + ops[1] = imm[1];
- + metag_split_movsi_immediate (ops);
- +}
- +
- +void
- +metag_split_movdf (rtx operands[])
- +{
- + unsigned int dst_reg = REGNO (operands[0]);
- + unsigned int src_reg = REGNO (operands[1]);
- +
- + emit_move_insn (gen_rtx_REG (SImode, dst_reg),
- + gen_rtx_REG (SImode, src_reg));
- +
- + emit_move_insn (gen_rtx_REG (SImode, dst_reg + 1),
- + gen_rtx_REG (SImode, src_reg + 1));
- +}
- +
- +void
- +metag_split_movdf_immediate (rtx operands[])
- +{
- + unsigned int dst_reg = REGNO (operands[0]);
- + rtx imm[2];
- + rtx ops[2];
- +
- + split_double (operands[1], &imm[0], &imm[1]);
- +
- + ops[0] = gen_rtx_REG (SImode, dst_reg);
- + ops[1] = imm[0];
- + metag_split_movsi_immediate (ops);
- +
- + ops[0] = gen_rtx_REG (SImode, dst_reg + 1);
- + ops[1] = imm[1];
- +
- + metag_split_movsi_immediate (ops);
- +}
- +
- +#define metag_non_leaf_function_p() \
- + (reload_completed ? cfun->machine->non_leaf : !leaf_function_p ())
- +
- +#define TBICTX_XMCC_BIT 0x0020
- +#define TBICTX_XDX8_BIT 0x0100
- +#define TBICTX_XAX4_BIT 0x0200
- +#define TBICTX_XEXT_BIT 0x1000
- +
- +static unsigned int
- +metag_calculate_ech_ctx (void)
- +{
- + unsigned int ech_ctx = 0;
- +
- + /* Now emit ECH support */
- + if (TARGET_ECH)
- + {
- + int regno;
- +
- + for (regno = FIRST_ECH_DATA_REG ; regno <= LAST_DATA_REG ; regno++)
- + if (df_regs_ever_live_p (regno))
- + {
- + ech_ctx |= (TBICTX_XDX8_BIT << 16);
- + break;
- + }
- +
- + for (regno = FIRST_ECH_ADDR_REG ; regno <= LAST_ADDR_REG ; regno++)
- + if (df_regs_ever_live_p (regno))
- + {
- + ech_ctx |= (TBICTX_XAX4_BIT << 16);
- + break;
- + }
- + }
- +
- + return ech_ctx;
- +}
- +
- +static unsigned int
- +metag_adjust_savesize_ech (unsigned int* savesize_gp, unsigned int* extras_gp,
- + unsigned int* FP_SP_offset)
- +{
- + unsigned int ech_ctx = metag_calculate_ech_ctx ();
- +
- + if (ech_ctx != 0)
- + {
- + *extras_gp |= REGNO_BIT (METAG_ECH_REGNUM);
- + *savesize_gp += UNITS_PER_WORD * 2;
- +
- + if (FP_SP_offset != NULL && METAG_ECH_REGNUM >= MIN_METAG_CSAVE_REGNUM)
- + *FP_SP_offset += UNITS_PER_WORD * 2;
- + }
- +
- + return ech_ctx;
- +}
- +
- +/* function prologue */
- +
- +void
- +metag_function_prologue (FILE *file ATTRIBUTE_UNUSED, HOST_WIDE_INT size)
- +{
- + unsigned int savesize_gp = 0;
- + unsigned int savesize_eh = 0;
- + unsigned int FP_SP_offset = 0;
- + unsigned int pretend_size = ALIGN_ON_STACK_BOUNDARY (current_function_pretend_args_size);
- + unsigned int pretend_regs = pretend_size / UNITS_PER_WORD;
- + bool non_leaf = metag_non_leaf_function_p ();
- + unsigned int extras_gp = 0;
- + unsigned int extras_eh = 0;
- + unsigned int ech_ctx = 0;
- + bool loads_pic_register;
- +
- + if (metag_ccfsm_state || metag_target_insn)
- + gcc_unreachable (); /* Sanity check */
- +
- + /* Track basis for the varargs we save */
- + if (cfun->machine->anonymous_args)
- + fprintf (file, ASM_COMMENT_START " Store varargs in registers %d (%d)\n",
- + current_function_pretend_args_size, pretend_size);
- + else if (current_function_pretend_args_size)
- + fprintf (file, ASM_COMMENT_START " Store partial args in registers %d (%d)\n",
- + current_function_pretend_args_size, pretend_size);
- +
- + /* Add in outgoing sizes */
- + if (size != 0)
- + fprintf (file, ASM_COMMENT_START " Allocate local size %ld\n", (long)size);
- +
- + if (non_leaf)
- + fprintf (file, ASM_COMMENT_START " Allocate outgoing %d\n",
- + current_function_outgoing_args_size);
- +
- + size += current_function_outgoing_args_size;
- +
- + /* Round size of local stack to preserve 64-bit alignments */
- + size = ALIGN_ON_STACK_BOUNDARY (size);
- +
- + /* Make pretend regs into the first non-varargs register number */
- + pretend_regs += MIN_METAG_PARM_REGNUM;
- +
- + {
- + unsigned int regno;
- +
- + for (regno = MIN_METAG_PARM_REGNUM; regno <= MAX_METAG_CSAVE_REGNUM; regno += 2)
- + {
- + if (regno < pretend_regs
- + || (!call_used_regs[regno]
- + && (df_regs_ever_live_p (regno + 0) || df_regs_ever_live_p (regno + 1))))
- + {
- + extras_gp |= REGNO_BIT (regno);
- +
- + /* Push this data register */
- + savesize_gp += UNITS_PER_WORD * 2;
- +
- + if (regno >= MIN_METAG_CSAVE_REGNUM)
- + FP_SP_offset += UNITS_PER_WORD * 2;
- + }
- + }
- + }
- +
- + /* Exception handler bits */
- + if (current_function_calls_eh_return)
- + {
- + unsigned int n;
- +
- + for (n = 0; n < NUM_EH_RETURN_DATA_REGS; n++)
- + {
- + unsigned int regno = EH_RETURN_DATA_REGNO (n);
- +
- + if (regno != INVALID_REGNUM)
- + {
- + unsigned int regbit = REGNO_BIT (regno);
- +
- + if ((extras_eh & regbit) == 0)
- + {
- + extras_eh |= regbit;
- + savesize_eh += UNITS_PER_WORD * 2;
- + FP_SP_offset += UNITS_PER_WORD * 2;
- + }
- + }
- + }
- + }
- +
- + /* Adjust the saved registers for ECH support */
- + ech_ctx = metag_adjust_savesize_ech (&savesize_gp, &extras_gp, &FP_SP_offset);
- +
- + /* Recover original pretend regs */
- + pretend_regs -= MIN_METAG_PARM_REGNUM;
- +
- + /* Can only save frame pointer from D0 temporary */
- + if (cfun->machine->frame_pointer_epilogue)
- + fputs (ASM_COMMENT_START " frame_pointer_needed to optimize epilogue\n", file);
- + else if (frame_pointer_needed)
- + fputs (ASM_COMMENT_START " GCC says frame_pointer_needed\n", file);
- +
- + if (frame_pointer_needed || non_leaf)
- + {
- + if (non_leaf)
- + {
- + extras_gp |= REGNO_BIT (RETURN_POINTER_REGNUM);
- + fputs (ASM_COMMENT_START " Save return address for non_leaf\n", file);
- + }
- + else
- + fputs (ASM_COMMENT_START " Save return address with callers frame\n", file);
- +
- + if (frame_pointer_needed)
- + extras_gp |= REGNO_BIT (TEMP_D0FRT_REGNUM);
- +
- + savesize_gp += UNITS_PER_WORD * 2;
- + FP_SP_offset += UNITS_PER_WORD * 2;
- + }
- + else if (df_regs_ever_live_p (RETURN_POINTER_REGNUM))
- + {
- + extras_gp |= REGNO_BIT (RETURN_POINTER_REGNUM);
- +
- + /* Push this data register */
- + savesize_gp += UNITS_PER_WORD * 2;
- + if (RETURN_POINTER_REGNUM >= MIN_METAG_CSAVE_REGNUM)
- + FP_SP_offset += UNITS_PER_WORD * 2;
- + }
- +
- + loads_pic_register = METAG_CURRENT_FUNCTION_LOADS_PIC_REGISTER ();
- + if (loads_pic_register)
- + FP_SP_offset += UNITS_PER_WORD * 2; /* Save PIC register. */
- +
- + /* Sanity checks between initial_elimination and prologue.
- + If any of these tests fail then the generated code will be wrong so abort. */
- +
- + gcc_assert (cfun->machine->valid);
- + gcc_assert (cfun->machine->savesize_gp == savesize_gp);
- + gcc_assert (cfun->machine->savesize_eh == savesize_eh);
- + gcc_assert (cfun->machine->FP_SP_offset == FP_SP_offset);
- + gcc_assert (cfun->machine->frame_pointer_needed == frame_pointer_needed);
- + gcc_assert (cfun->machine->non_leaf == non_leaf);
- + gcc_assert (cfun->machine->out_local_size == (unsigned HOST_WIDE_INT)size);
- + gcc_assert (cfun->machine->calls_eh_return == current_function_calls_eh_return);
- + gcc_assert (cfun->machine->extras_gp == extras_gp);
- + gcc_assert (cfun->machine->extras_eh == extras_eh);
- + gcc_assert (cfun->machine->uses_pic_offset_table == current_function_uses_pic_offset_table);
- + gcc_assert (cfun->machine->loads_pic_register == loads_pic_register);
- + gcc_assert (cfun->machine->ech_ctx_required == (ech_ctx != 0));
- +}
- +
- +void
- +metag_function_end_prologue (FILE *file)
- +{
- + fputs (ASM_COMMENT_START " End prologue\n", file);
- + return;
- +}
- +
- +void
- +metag_function_begin_epilogue (FILE *file)
- +{
- + fputs (ASM_COMMENT_START " Begin epilogue\n", file);
- + return;
- +}
- +
- +/* function epilogue */
- +
- +void
- +metag_function_epilogue (FILE *file ATTRIBUTE_UNUSED, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
- +{
- + return;
- +}
- +
- +/* Is the return sequence just recover return address and return - two insts */
- +bool
- +metag_cheap_return (bool cond)
- +{
- + unsigned int regno = 0;
- + unsigned int savesize_gp = 0;
- + unsigned int extras_gp = 0;
- + unsigned int ech_ctx = 0;
- + bool non_leaf = metag_non_leaf_function_p ();
- +
- + if (!METAG_USE_RETURN_INSN (cond))
- + return false;
- +
- + if (non_leaf)
- + savesize_gp += UNITS_PER_WORD * 2; /* Must recover return address so return is not that cheap! */
- +
- +
- + /* Adjust the saved registers for ECH support */
- + ech_ctx = metag_adjust_savesize_ech (&savesize_gp, &extras_gp, NULL);
- +
- + for (regno = MIN_METAG_PARM_REGNUM; regno <= MAX_METAG_CSAVE_REGNUM; regno += 2)
- + {
- + if (!call_used_regs[regno]
- + && (df_regs_ever_live_p(regno + 0) || df_regs_ever_live_p(regno + 1)))
- + {
- + /* Cannot do any pops in a conditional return/call */
- + if (cond)
- + return false;
- +
- + /* Cannot do simple return - too many pops! */
- + if (savesize_gp != 0)
- + return false;
- +
- + /* Have to do at least one pop */
- + savesize_gp = UNITS_PER_WORD * 2;
- + }
- + }
- +
- + if (!(frame_pointer_needed || non_leaf) && df_regs_ever_live_p (RETURN_POINTER_REGNUM))
- + {
- + /* Have to do at least one pop */
- + savesize_gp += UNITS_PER_WORD * 2;
- + }
- +
- + if (current_function_calls_eh_return)
- + return false;
- +
- + /* Cannot make the pop conditional! */
- + if (cond && savesize_gp != 0)
- + return false;
- +
- + /* Detect those hardware trace scenarios that lead to three extra instructions */
- + if (cond && cfun->machine->hwtrace)
- + return false;
- +
- + /* We can announce our intentions to optimise returns */
- + return true;
- +}
- +
- +/* All the code we need to perform a function sibcall */
- +const char *
- +output_sibcall (rtx operands[], unsigned int op_offset)
- +{
- + char buf[1024];
- + rtx CallAddr;
- +
- + if (MEM_P (operands[op_offset]))
- + CallAddr = XEXP (operands[op_offset], 0);
- + else
- + CallAddr = operands[op_offset];
- +
- + if (!TARGET_METAC_1_1 && SYMBOL_REF_P (CallAddr))
- + {
- + if (METAG_FLAG_PIC)
- + gcc_unreachable ();
- + else /* !METAG_FLAG_PIC */
- + {
- + /* Calculate return pointer using fast address bank add */
- + sprintf (buf, "MOVT\t%s, #HI(%%c%d)",
- + reg_names[A0_2_REG], op_offset);
- + output_asm_insn (buf, operands);
- +
- + /* The actual call is a branch */
- + sprintf (buf, "JUMP\t%s, #LO(%%c%d)",
- + reg_names[A0_2_REG], op_offset);
- + output_asm_insn (buf, operands);
- + }
- + }
- + else if (SYMBOL_REF_P (CallAddr))
- + {
- + if (METAG_FLAG_PIC)
- + {
- + if (SYMBOL_REF_LOCAL_P (CallAddr))
- + {
- + /* Local funcs go via relative call */
- + if (TARGET_MODEL_SMALL)
- + {
- + sprintf (buf, "B\t%%c%d", op_offset);
- + output_asm_insn (buf, operands);
- + }
- + else
- + {
- + sprintf (buf, "B\t%%c%d", op_offset);
- + output_asm_insn (buf, operands);
- + }
- + }
- + else
- + {
- + /* The actual call is to an external function so goes via the PLT */
- + sprintf (buf, "B\t%%c%d@PLT", op_offset);
- + output_asm_insn (buf, operands);
- + }
- + }
- + else /* !METAG_FLAG_PIC */
- + {
- + sprintf (buf, "B\t%%c%d", op_offset);
- + output_asm_insn (buf, operands);
- + }
- + }
- + else if (REG_P (CallAddr)
- + && REGNO (CallAddr) != RETURN_POINTER_REGNUM)
- + {
- + sprintf (buf, "MOV%%?\tPC, %s", reg_names[REGNO (CallAddr)]);
- + output_asm_insn (buf, operands);
- + }
- + else
- + gcc_unreachable ();
- +
- + return "";
- +}
- +
- +/* All the code we need to perform a function call */
- +const char *
- +output_call (rtx operands[], unsigned int op_offset)
- +{
- + char buf[1024];
- + const char * prefix = "(*call instance ";
- + const char * const no_prefix = "";
- + rtx CallAddr;
- +
- + if (MEM_P (operands[op_offset]))
- + CallAddr = XEXP (operands[op_offset], 0);
- + else
- + CallAddr = operands[op_offset];
- +
- + if (!TARGET_METAC_1_1 && SYMBOL_REF_P (CallAddr))
- + {
- + if (METAG_FLAG_PIC)
- + gcc_unreachable ();
- + else /* !METAG_FLAG_PIC */
- + {
- + /* Calculate return pointer using fast address bank add */
- + sprintf (buf, "MOVT\t%s, #HI(%%c%d)\t%s %s",
- + reg_names[RETURN_POINTER_REGNUM], op_offset, ASM_COMMENT_START, prefix);
- + output_asm_insn (buf, operands);
- + prefix = no_prefix;
- +
- + /* The actual call is a branch */
- + sprintf (buf, "CALL\t%s, #LO(%%c%d)\t%s ... OK)",
- + reg_names[RETURN_POINTER_REGNUM], op_offset, ASM_COMMENT_START);
- + output_asm_insn (buf, operands);
- +
- + /* Some calls need additional padding instructions */
- + metag_pad_function_call (CallAddr);
- + }
- + }
- + else if (SYMBOL_REF_P (CallAddr))
- + {
- + if (METAG_FLAG_PIC)
- + {
- + if (SYMBOL_REF_LOCAL_P (CallAddr))
- + {
- + /* Local funcs go via relative CALL */
- + if (TARGET_MODEL_SMALL)
- + {
- + sprintf (buf, "CALLR\t%s, %%c%d\t%s %s)",
- + reg_names[RETURN_POINTER_REGNUM], op_offset, ASM_COMMENT_START, prefix);
- + output_asm_insn (buf, operands);
- + prefix = no_prefix;
- + }
- + else
- + {
- + sprintf (buf, "CALLR\t%s, %%c%d\t%s %s)",
- + reg_names[RETURN_POINTER_REGNUM], op_offset, ASM_COMMENT_START, prefix);
- + output_asm_insn (buf, operands);
- + prefix = no_prefix;
- + }
- + }
- + else
- + {
- + /* The actual call is to an external function so goes via the PLT */
- + sprintf (buf, "CALLR\t%s, %%c%d@PLT\t%s %s)",
- + reg_names[RETURN_POINTER_REGNUM], op_offset, ASM_COMMENT_START, prefix);
- + output_asm_insn (buf, operands);
- + prefix = no_prefix;
- + }
- + }
- + else /* !METAG_FLAG_PIC */
- + {
- + /* The actual call is a branch */
- + sprintf (buf, "CALLR\t%s, %%c%d\t%s %s)",
- + reg_names[RETURN_POINTER_REGNUM], op_offset, ASM_COMMENT_START, prefix);
- + output_asm_insn (buf, operands);
- + prefix = no_prefix;
- + }
- +
- + /* Some calls need additional padding instructions */
- + metag_pad_function_call (CallAddr);
- + }
- + else if (REG_P (CallAddr)
- + && REGNO (CallAddr) != RETURN_POINTER_REGNUM)
- + {
- + /* Must move the address to call into D1RtP */
- + sprintf (buf, "MOV%%?\t%s, %s\t%s %s ...",
- + reg_names[RETURN_POINTER_REGNUM],
- + reg_names[REGNO (CallAddr)], ASM_COMMENT_START, prefix);
- + output_asm_insn (buf, operands);
- +
- + /* The actual call is a SWAP */
- + sprintf (buf, "SWAP%%?\tPC, %s\t%s ... OK)",
- + reg_names[RETURN_POINTER_REGNUM], ASM_COMMENT_START);
- + output_asm_insn (buf, operands);
- + }
- + else
- + metag_abort (CallAddr);
- +
- + return "";
- +}
- +
- +unsigned int
- +metag_mem_base (rtx op)
- +{
- + rtx ref;
- +
- + /* We only match with MEM operands */
- + if (!MEM_P (op))
- + return INVALID_REGNUM;
- +
- + /* Get root of address expression */
- + ref = XEXP (op, 0);
- +
- + if (SYMBOL_REF_P (ref))
- + {
- + /* Must be a direct access to an atomic symbol */
- + return GLOBAL_POINTER_REGNUM;
- + }
- +
- + if (GET_CODE (ref) == PLUS
- + || GET_CODE (ref) == PRE_INC
- + || GET_CODE (ref) == PRE_DEC
- + || GET_CODE (ref) == POST_INC
- + || GET_CODE (ref) == POST_DEC
- + || GET_CODE (ref) == PRE_MODIFY
- + || GET_CODE (ref) == POST_MODIFY)
- + {
- + /* De-reference first parameter of address expression */
- + ref = XEXP (ref, 0);
- + }
- +
- + if (SUBREG_P (ref)
- + && REG_P (SUBREG_REG (ref)))
- + {
- + unsigned int regno = REGNO (SUBREG_REG (ref));
- +
- + if (IS_HARD_OR_VIRT_REGNO (regno))
- + return regno + SUBREG_BYTE (ref);
- +
- + return regno;
- + }
- +
- + if (REG_P (ref))
- + return REGNO (ref);
- +
- + return INVALID_REGNUM;
- +}
- +
- +bool
- +metag_mem_base_p (rtx op, enum reg_class class)
- +{
- + unsigned int reg_num = metag_mem_base (op);
- +
- + /* We only match with MEM operands */
- + if (reg_num == INVALID_REGNUM)
- + return false;
- +
- + if (reg_renumber != NULL && IS_PSEUDO_REGNO (reg_num))
- + reg_num = reg_renumber[reg_num];
- +
- + if (reg_num == INVALID_REGNUM)
- + return false;
- +
- + return METAG_REGNO_REG_CLASS (reg_num) == class;
- +}
- +
- +int
- +debug_metag_md (void)
- +{
- + static int counter = 0;
- +
- + return counter++;
- +}
- +
- +bool
- +metag_slow_store (rtx mem, rtx reg)
- +{
- + unsigned int regno;
- +
- + if (!MEM_P (mem))
- + return false;
- +
- + if (REG_P (reg))
- + regno = REGNO (reg);
- + else if (SUBREG_P (reg)
- + && REG_P (SUBREG_REG (reg)))
- + {
- + regno = REGNO (SUBREG_REG (reg));
- + if (IS_HARD_OR_VIRT_REGNO (regno))
- + regno += SUBREG_BYTE (reg);
- + }
- + else
- + return false;
- +
- + if (reg_renumber != NULL && IS_PSEUDO_REGNO (regno))
- + regno = reg_renumber[regno];
- +
- + if (IS_PSEUDO_REGNO (regno))
- + return false;
- +
- + if (GET_MODE_SIZE (GET_MODE (mem)) <= UNITS_PER_WORD)
- + return metag_mem_base_p (mem, METAG_REGNO_REG_CLASS (regno));
- + else
- + return (metag_mem_base_p (mem, METAG_REGNO_REG_CLASS (regno))
- + || metag_mem_base_p (mem, METAG_REGNO_REG_CLASS (regno + 1)));
- +}
- +
- +rtx
- +metag_gen_safe_temp (enum machine_mode mode, rtx reg)
- +{
- + unsigned int regno;
- +
- + gcc_assert ( A0_SCRATCH != INVALID_REGNUM && fixed_regs[A0_SCRATCH]
- + && A1_SCRATCH != INVALID_REGNUM && fixed_regs[A1_SCRATCH]);
- +
- + if (REG_P (reg))
- + regno = REGNO (reg);
- + else if (SUBREG_P (reg)
- + && REG_P (SUBREG_REG (reg)))
- + {
- + regno = REGNO (SUBREG_REG (reg));
- + if (IS_HARD_OR_VIRT_REGNO (regno))
- + regno += SUBREG_BYTE (reg);
- + }
- + else
- + regno = INVALID_REGNUM;
- +
- + if (reg_renumber != NULL && IS_PSEUDO_REGNO (regno))
- + regno = reg_renumber[regno];
- +
- + gcc_assert (regno != INVALID_REGNUM);
- +
- + if (METAG_REGNO_REG_CLASS (regno) == A1_REGS
- + && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
- + {
- + gcc_assert (regno != A0_SCRATCH);
- +
- + /* Not safe to use register in same unit */
- + return gen_rtx_REG (mode, A0_SCRATCH);
- + }
- +
- + /* Provide suitable temp register */
- + if (GET_MODE_SIZE (GET_MODE (reg)) > UNITS_PER_WORD)
- + {
- + gcc_assert (regno != A0_SCRATCH);
- + gcc_assert (regno != A1_SCRATCH);
- +
- + return gen_rtx_REG (mode, A0_SCRATCH);
- + }
- +
- + gcc_assert (regno != A1_SCRATCH);
- +
- + return gen_rtx_REG (mode, A1_SCRATCH);
- +}
- +
- +enum machine_mode
- +metag_select_cc_mode (enum rtx_code code, rtx x, rtx y)
- +{
- +#undef LETS_US_SEE
- +#ifdef LETS_US_SEE
- + fprintf (stderr, "metag_select_cc_mode %s\n", GET_RTX_NAME (code));
- + debug_rtx (x);
- + debug_rtx (y);
- +#endif
- +
- + /* An operation that sets the condition codes as a side-effect, the
- + V flag is not set correctly, so we can only use comparisons where
- + this doesn't matter. (For LT and GE we can use MI and PL instead. */
- + if (GET_MODE (x) == SImode
- + && y == const0_rtx
- + && (code == EQ || code == NE || code == LT || code == GE)
- + && (GET_CODE (x) == PLUS
- + || GET_CODE (x) == MINUS
- + || GET_CODE (x) == AND
- + || GET_CODE (x) == IOR
- + || GET_CODE (x) == XOR
- + || GET_CODE (x) == NOT
- + || GET_CODE (x) == NEG
- + || GET_CODE (x) == LSHIFTRT
- + || GET_CODE (x) == ASHIFT
- + || GET_CODE (x) == ASHIFTRT
- + || GET_CODE (x) == SIGN_EXTEND
- + || GET_CODE (x) == ZERO_EXTEND
- + || GET_CODE (x) == ZERO_EXTRACT))
- + {
- +#ifdef LETS_US_SEE
- + fputs (" return NOOV\n", stderr);
- +#endif
- + return CC_NOOVmode;
- + }
- +
- + /* A special case, Combine likes to generate
- + (compare (reg X) (neg (reg Y))
- + instead of
- + (compare (plus (reg X) (reg y))
- + (const_int 0))
- + */
- + if (GET_MODE (x) == SImode
- + && (code == EQ || code == NE || code == LT || code == GE)
- + && GET_CODE (y) == NEG)
- + {
- +#ifdef LETS_US_SEE
- + fputs (" return NOOV\n", stderr);
- +#endif
- + return CC_NOOVmode;
- + }
- +
- + /* If we're comparingi EQ/NE against 0 then use Zmode */
- + if (GET_MODE (x) == SImode
- + && y == const0_rtx
- + && (code == EQ || code == NE))
- + {
- +#ifdef LETS_US_SEE
- + fputs (" return Z\n", stderr);
- +#endif
- + return CC_Zmode;
- + }
- +
- + if ((GET_MODE (x) == HImode || GET_MODE (x) == QImode)
- + && (code == EQ || code == NE))
- + {
- + /* Enough to trigger the patterns if HI/QI equality involved */
- +#ifdef LETS_US_SEE
- + fputs (" return Z\n", stderr);
- +#endif
- + return CC_Zmode;
- + }
- +
- + if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
- + {
- + if (metag_is_cc_quiet (get_metag_cc_float (code)))
- + {
- +#ifdef LETS_US_SEE
- + fputs (" return FP_Q\n", stderr);
- +#endif
- + return CC_FP_Qmode;
- + }
- + else
- + {
- +#ifdef LETS_US_SEE
- + fputs (" return FP\n", stderr);
- +#endif
- + return CC_FPmode;
- + }
- + }
- +
- +#ifdef LETS_US_SEE
- + fputs (" return CC\n", stderr);
- +#endif
- + return CCmode;
- +}
- +
- +bool
- +gen_metag_compare (enum rtx_code code, rtx operands[], int index)
- +{
- + if (!(code == LTGT || code == UNEQ))
- + {
- + enum machine_mode mode = SELECT_CC_MODE (code, metag_compare_op0,
- + metag_compare_op1);
- +
- + rtx cc_reg = gen_rtx_REG (mode, MCC_REGNUM);
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + cc_reg,
- + gen_rtx_COMPARE (mode, metag_compare_op0, metag_compare_op1)));
- +
- + operands[index] = cc_reg;
- +
- + return true;
- + }
- +
- + return false;
- +}
- +
- +static metag_cc
- +get_metag_cc_float (enum rtx_code comp_code)
- +{
- + switch (comp_code)
- + {
- + case NE: return MCC_UNE;
- + case EQ: return MCC_FEQ;
- + case GE: return MCC_FGE;
- + case GT: return MCC_FGT;
- + case LE: return MCC_FLE;
- + case LT: return MCC_FLT;
- +/* LTGT cannot be handled by META */
- +/* UNEQ cannot be handled by META */
- + case UNGE: return MCC_UGE;
- + case UNGT: return MCC_UGT;
- + case UNLE: return MCC_ULE;
- + case UNLT: return MCC_ULT;
- + case UNORDERED: return MCC_U;
- + case ORDERED: return MCC_FLEG;
- + default:
- + break;
- + }
- + gcc_unreachable ();
- +}
- +
- +static metag_cc
- +get_metag_cc (rtx comparison)
- +{
- + enum machine_mode mode = GET_MODE (XEXP (comparison, 0));
- + enum rtx_code comp_code = GET_CODE (comparison);
- +
- + if (GET_MODE_CLASS (mode) != MODE_CC)
- + mode = SELECT_CC_MODE (comp_code, XEXP (comparison, 0),
- + XEXP (comparison, 1));
- +
- + switch (mode)
- + {
- + case CC_NOOVmode:
- + switch (comp_code)
- + {
- + case NE: return MCC_NE;
- + case EQ: return MCC_EQ;
- + case GE: return MCC_PL;
- + case LT: return MCC_MI;
- + case LTU: return MCC_CS;
- + case GEU: return MCC_CC;
- + default:
- + break;
- + }
- + break;
- +
- + case CC_Zmode:
- + switch (comp_code)
- + {
- + case NE: return MCC_NE;
- + case EQ: return MCC_EQ;
- + default:
- + break;
- + }
- + break;
- +
- + case CC_FPmode:
- + case CC_FP_Qmode:
- + return get_metag_cc_float (comp_code);
- +
- + case CCmode:
- + switch (comp_code)
- + {
- + case NE: return MCC_NE;
- + case EQ: return MCC_EQ;
- + case GE: return MCC_GE;
- + case GT: return MCC_GT;
- + case LE: return MCC_LE;
- + case LT: return MCC_LT;
- + case GEU: return MCC_HS;
- + case GTU: return MCC_HI;
- + case LEU: return MCC_LS;
- + case LTU: return MCC_LO;
- + default:
- + break;
- + }
- + break;
- +
- + default:
- + break;
- + }
- +
- + metag_abort (comparison);
- +}
- +
- +static bool
- +metag_is_cc_quiet (metag_cc metag_comp_code)
- +{
- + switch (metag_comp_code)
- + {
- + case MCC_FEQ:
- + case MCC_UNE:
- + case MCC_U:
- + case MCC_UGT:
- + case MCC_UGE:
- + case MCC_ULT:
- + case MCC_ULE:
- + case MCC_NU:
- + case MCC_NUGT:
- + case MCC_NUGE:
- + case MCC_NULT:
- + case MCC_NULE:
- + return true;
- + case MCC_FGT:
- + case MCC_FGE:
- + case MCC_FLT:
- + case MCC_FLE:
- + case MCC_FLEG:
- + case MCC_NFGT:
- + case MCC_NFGE:
- + case MCC_NFLT:
- + case MCC_NFLE:
- + case MCC_NFLEG:
- + return false;
- +/* LTGT cannot be handled by META */
- +/* UNEQ cannot be handled by META */
- + default:
- + gcc_unreachable ();
- + }
- +}
- +
- +/* Recognise VAR_DECL DECL's which are atomics of size <= 8
- +
- + For the metag we only want to mark variables that are atomic and less
- + than 64-bits for optimisation as condidates for direct LOAD/STORE using
- + A1LbP or A1GbP as a base.
- +
- + All other symbols will be accessed indirectly using OGA(), this is true of
- + functions, string constants, or constructors.
- +*/
- +
- +#define SET_SYMBOL_FLAG_SMALL(SYMBOL) \
- + (SYMBOL_REF_FLAGS (SYMBOL) = (SYMBOL_REF_FLAGS (SYMBOL) & ~METAG_SYMBOL_FLAG_GLOBAL \
- + & ~METAG_SYMBOL_FLAG_LARGE) \
- + | METAG_SYMBOL_FLAG_SMALL)
- +
- +#define SET_SYMBOL_FLAG_LARGE(SYMBOL) \
- + (SYMBOL_REF_FLAGS (SYMBOL) = (SYMBOL_REF_FLAGS (SYMBOL) & ~METAG_SYMBOL_FLAG_GLOBAL \
- + & ~METAG_SYMBOL_FLAG_SMALL) \
- + | METAG_SYMBOL_FLAG_LARGE)
- +
- +#define SET_SYMBOL_FLAG_GLOBAL(SYMBOL) \
- + (SYMBOL_REF_FLAGS (SYMBOL) = (SYMBOL_REF_FLAGS (SYMBOL) & ~METAG_SYMBOL_FLAG_SMALL \
- + & ~METAG_SYMBOL_FLAG_LARGE) \
- + | METAG_SYMBOL_FLAG_GLOBAL)
- +
- +#define SET_SYMBOL_FLAG_BYTE(SYMBOL) \
- + (SYMBOL_REF_FLAGS (SYMBOL) = (SYMBOL_REF_FLAGS (SYMBOL) & ~METAG_SYMBOL_FLAG_WORD \
- + & ~METAG_SYMBOL_FLAG_DWORD \
- + & ~METAG_SYMBOL_FLAG_LONG) \
- + | METAG_SYMBOL_FLAG_BYTE)
- +
- +#define SET_SYMBOL_FLAG_WORD(SYMBOL) \
- + (SYMBOL_REF_FLAGS (SYMBOL) = (SYMBOL_REF_FLAGS (SYMBOL) & ~METAG_SYMBOL_FLAG_BYTE \
- + & ~METAG_SYMBOL_FLAG_DWORD \
- + & ~METAG_SYMBOL_FLAG_LONG) \
- + | METAG_SYMBOL_FLAG_WORD)
- +
- +#define SET_SYMBOL_FLAG_DWORD(SYMBOL) \
- + (SYMBOL_REF_FLAGS (SYMBOL) = (SYMBOL_REF_FLAGS (SYMBOL) & ~METAG_SYMBOL_FLAG_BYTE \
- + & ~METAG_SYMBOL_FLAG_WORD \
- + & ~METAG_SYMBOL_FLAG_LONG) \
- + | METAG_SYMBOL_FLAG_DWORD)
- +
- +#define SET_SYMBOL_FLAG_LONG(SYMBOL) \
- + (SYMBOL_REF_FLAGS (SYMBOL) = (SYMBOL_REF_FLAGS (SYMBOL) & ~METAG_SYMBOL_FLAG_BYTE \
- + & ~METAG_SYMBOL_FLAG_WORD \
- + & ~METAG_SYMBOL_FLAG_DWORD) \
- + | METAG_SYMBOL_FLAG_LONG)
- +
- +#define SET_SYMBOL_FLAG_UNKN(SYMBOL) \
- + (SYMBOL_REF_FLAGS (SYMBOL) = (SYMBOL_REF_FLAGS (SYMBOL) & ~METAG_SYMBOL_FLAG_BYTE \
- + & ~METAG_SYMBOL_FLAG_WORD \
- + & ~METAG_SYMBOL_FLAG_DWORD \
- + & ~METAG_SYMBOL_FLAG_LONG)
- +
- +/* This macro definition, if any, is executed immediately after the rtl for
- + decl has been created and stored in DECL_RTL (decl). The value of the rtl
- + will be a mem whose address is a symbol_ref.
- +
- + The usual thing for this macro to do is to record a flag in the symbol_ref
- + (such as SYMBOL_REF_FLAG) or to store a modified name string in the
- + symbol_ref (if one bit is not enough information).
- +
- + For META we do both, the METAG_SYMBOL_FLAG_DIRECT is set if-
- +
- + The decl defines the address of an atomic variable <= 8 bytes in size
- + AND either we are targeting SMALL compilation mode
- + AND the decl DOES NOT HAVE __attribute__ ((model(large)))
- + or we are targeting LARGE compilation mode
- + AND the decl HAS __attribute__ ((model(small)))
- +
- + The METAG_SYMBOL_FLAG_DIRECT hence indicates if direct access to the data
- + symbols value is to be supported by the instruction patterns provided the
- + size of the load/store matches the size of atomic value concerned. The access
- + causes the symbol is to be generally accessed using either A1GbP+OG(..) or
- + A1GbP+OGA(...) if the address or value is to be accessed.
- +
- + METAG_SYMBOL_FLAG_SMALL
- + If SYMBOL_REF_FLAG_DIRECT set to directly access data using-
- +
- + GETx Reg, [A1GbP+#OG(Symbol)] ; x set to name[2]
- + SETx [A1GbP+#OG(Symbol)], Reg ; x set to name[2]
- +
- + else and if address of location required-
- +
- + GETD Reg, [A1GbP+#OGA(Symbol)]
- +
- + METAG_SYMBOL_FLAG_LARGE
- + Only support access to a data symbol's address via-
- +
- + MOV Reg, A1GbP ; name[2] will be 'X'
- + ADDT Reg, Reg, #HI(OG(Symbol)) ; 32-bit offset
- + ADD Reg, Reg, #LO(OG(Symbol))
- +
- + METAG_SYMBOL_FLAG_GLOBAL
- + Only support access as a absolute global address-
- +
- + MOVT Reg, #HI(Symbol) ; 32-bit absolute address
- + ADD Reg, Reg, #LO(Symbol)
- +
- + The following flags:
- + METAG_SYMBOL_FLAG_BYTE
- + METAG_SYMBOL_FLAG_WORD
- + METAG_SYMBOL_FLAG_DWORD
- + METAG_SYMBOL_FLAG_LONG
- + are used to indicate either the size of a directly accessible data symbol or
- + that only the address of the item can be accessed directly because it is
- + too large, a small array, a small structure, a small union, or not in the
- + optimised data section at all.
- +*/
- +
- +void
- +metag_encode_section_info (tree decl, rtx rtl, int first)
- +{
- + char SorLorG = '\0';
- + rtx symbol = NULL_RTX;
- + bool direct = false;
- + char size = 'X';
- + default_encode_section_info (decl, rtl, first);
- +
- + /* Grab the symbol from the rtl passed in */
- + symbol = XEXP (rtl, 0);
- +
- + if (METAG_FLAG_PIC)
- + {
- + /* PIC code only needs to deal with functions and variables */
- + if (TREE_CODE (decl) != FUNCTION_DECL
- + && TREE_CODE (decl) != VAR_DECL)
- + return;
- +
- + gcc_assert (SYMBOL_REF_P (symbol));
- +
- + direct = SYMBOL_REF_LOCAL_P (symbol);
- + }
- + else if (metag_bfd_tls_referenced_p (rtl))
- + {
- + if (TREE_CODE (decl) != VAR_DECL)
- + return;
- + }
- + else
- + {
- + /* Note: Binutils toolchain DOESN'T support #OG or #OGA addressing
- + via A1GbP so we ignore the memory model and always use direct
- + 32-bit absolute access. */
- +
- + /* Direct 32-bit absolute access */
- + SorLorG = 'G';
- + size = 'X';
- + direct = false;
- +
- + if (SorLorG == 'S')
- + SET_SYMBOL_FLAG_SMALL (symbol);
- + else if (SorLorG == 'L')
- + SET_SYMBOL_FLAG_LARGE (symbol);
- + else if (SorLorG == 'G')
- + SET_SYMBOL_FLAG_GLOBAL (symbol);
- + else
- + gcc_unreachable ();
- +
- + if (size == 'B')
- + SET_SYMBOL_FLAG_BYTE (symbol);
- + else if (size == 'W')
- + SET_SYMBOL_FLAG_WORD (symbol);
- + else if (size == 'D')
- + SET_SYMBOL_FLAG_DWORD (symbol);
- + else if (size == 'L')
- + SET_SYMBOL_FLAG_LONG (symbol);
- + else if (size == 'X')
- + SET_SYMBOL_FLAG_LONG (symbol);
- + else
- + gcc_unreachable ();
- + }
- +
- + if (direct)
- + SYMBOL_REF_FLAGS (symbol) |= METAG_SYMBOL_FLAG_DIRECT;
- + else
- + SYMBOL_REF_FLAGS (symbol) &= ~METAG_SYMBOL_FLAG_DIRECT;
- +}
- +
- +/* With DSP features enabled, the compiler will use the V2SImode
- + vectors and with FPU features enabled, the compiler will use
- + V2SFmode */
- +
- +bool
- +metag_vector_mode_supported_p (enum machine_mode mode)
- +{
- + return (TARGET_DSP && (mode == V2SImode))
- + || (TARGET_FPU_SIMD && (mode == V2SFmode));
- +}
- +
- +/* Called by OVERRIDE_OPTIONS to initialize various things. */
- +
- +void
- +metag_override_options (void)
- +{
- + static const struct cpu_table {
- + const char *const name;
- + const enum processor_type processor;
- + const enum attr_metacore tune;
- + const enum metac_target cpu;
- + } cpu_table[] = {
- + { "0.1", PROCESSOR_METAC_0_1, METACORE_METAC_0_1, METAC_0_1_ID },
- + { "1.0", PROCESSOR_METAC_1_0, METACORE_METAC_1_0, METAC_1_0_ID },
- + { "1.1", PROCESSOR_METAC_1_1, METACORE_METAC_1_1, METAC_1_1_ID },
- + { "1.2", PROCESSOR_METAC_1_2, METACORE_METAC_1_2, METAC_1_2_ID },
- + { "2.1", PROCESSOR_METAC_2_1, METACORE_METAC_2_1, METAC_2_1_ID },
- + { NULL, 0, 0, 0 }
- + };
- +
- + if (strcmp (metag_model_string, "small") == 0)
- + {
- + warning (0, "Small memory model not supported, using large model");
- + metag_model = METAG_MODEL_LARGE;
- + }
- + else if (strcmp (metag_model_string, "large") == 0)
- + metag_model = METAG_MODEL_LARGE;
- + else
- + error ("bad value %qs for -mmodel switch", metag_model_string);
- +
- + /* If it's not defined or still has the initial value then use METAC_DEFAULT
- + to set the target string. The conversion of string into ID can then take
- + place as normal. */
- + if (strcmp (metag_cpu_string, "") == 0)
- + {
- + if (TARGET_MTX)
- + metag_cpu_string = "1.2";
- + else
- + metag_cpu_string = METAC_DEFAULT;
- + }
- +
- + if (metag_cpu_string)
- + {
- + unsigned int i;
- + bool newer_than_default = false;
- +
- + for (i = 0; cpu_table[i].name != NULL; i++)
- + {
- + if (strcmp (metag_cpu_string, cpu_table[i].name) == 0)
- + {
- + /* This test is present in order to prevent a toolchain built for an old core
- + allowing a newer core to be targetted. The rest of the toolchain may
- + therefore not support the newer core! */
- + if (newer_than_default)
- + {
- + error ("Bad value %qs for -mmetac switch. Must not be more recent than %qs.", metag_cpu_string, METAC_DEFAULT);
- + break;
- + }
- + metac_target = cpu_table[i].cpu;
- + metacore = cpu_table[i].tune;
- + break;
- + }
- +
- + if (strcmp (METAC_DEFAULT, cpu_table[i].name) == 0)
- + newer_than_default = true;
- + }
- +
- + if (cpu_table[i].name == NULL)
- + error ("Bad value %qs for -mmetac switch", metag_cpu_string);
- + }
- +
- + if (metag_tune_string)
- + {
- + unsigned int i;
- +
- + for (i = 0; cpu_table[i].name != NULL; i++)
- + if (strcmp (metag_tune_string, cpu_table[i].name) == 0)
- + {
- + metacore = cpu_table[i].tune;
- + break;
- + }
- +
- + if (cpu_table[i].name == NULL)
- + error ("bad value %qs for -mtune switch", metag_tune_string);
- + }
- +
- + if (TARGET_MTX)
- + {
- + if (metac_target != METAC_1_2_ID)
- + error ("MTX is based on a Meta 1.2 core, use -mmetac=1.2");
- + }
- +
- + if (TARGET_MINIM_CORE)
- + metag_max_insns_skipped = 2;
- +
- + if (TARGET_FPU_SIMD && (!TARGET_FPU
- + || metag_fpu_single))
- + error ("-msimd-float only valid with -mhard-float=D");
- +
- + if (!TARGET_METAC_2_1 && TARGET_FPU)
- + error ("FPU not available on specified processor: %s", metag_cpu_string);
- +
- + if (!TARGET_METAC_2_1 && metag_meta2_bex_enabled)
- + error ("The 'bex' extension is not available for the specified meta core");
- +
- + metag_override_options_per_os();
- + flag_no_function_cse = 1;
- +}
- +
- +bool
- +metag_return_in_memory (tree type)
- +{
- + HOST_WIDE_INT size = int_size_in_bytes (type);
- +
- + return (size < 0 || size > UNITS_PER_WORD * 2);
- +}
- +
- +void
- +metag_abort (rtx val)
- +{
- + debug_rtx (val);
- + gcc_unreachable ();
- +}
- +
- +static void
- +metag_emit_load_post_inc (rtx dstbase, enum machine_mode mode, rtx dst,
- + HOST_WIDE_INT dstoffset, unsigned int reg)
- +{
- +#if 0
- + rtx addrm mem, insn;
- +
- + addr = gen_rtx_POST_INC (Pmode, dst);
- + mem = adjust_automodify_address_nv (dstbase, mode, addr, dstoffset);
- + insn = emit_insn (gen_rtx_SET (VOIDmode,
- + mem,
- + gen_rtx_REG (mode, reg)));
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (addr, 0), REG_NOTES (insn));
- +#else
- + rtx plus, mem, insn, set1, set2;
- +
- + mem = adjust_automodify_address_nv (dstbase, mode, dst, dstoffset);
- +
- + dst = XEXP (mem, 0);
- + plus = gen_rtx_PLUS (SImode, dst,
- + gen_int_mode (GET_MODE_SIZE (mode), SImode));
- + set1 = gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (mode, reg));
- + set2 = gen_rtx_SET (VOIDmode, dst, plus);
- +
- + insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
- + XVECEXP (insn, 0, 0) = set1;
- + XVECEXP (insn, 0, 1) = set2;
- + emit_insn (insn);
- +#endif
- +}
- +
- +rtx
- +metag_gen_load_multiple (unsigned int base_regno,
- + unsigned int count,
- + enum machine_mode mode,
- + rtx from,
- + bool write_back,
- + rtx basemem,
- + HOST_WIDE_INT * offsetp)
- +{
- + HOST_WIDE_INT offset = *offsetp;
- + unsigned int i;
- + unsigned int word_size = GET_MODE_SIZE (mode);
- + unsigned int j;
- + rtx result;
- +
- + if (count < 2)
- + gcc_unreachable ();
- +
- + result = gen_rtx_PARALLEL (VOIDmode,
- + rtvec_alloc (count + (write_back ? 1 : 0)));
- + if (write_back)
- + {
- + XVECEXP (result, 0, 0) = gen_rtx_SET (VOIDmode,
- + from,
- + plus_constant (from, count * word_size));
- + i = 1;
- + count++;
- + }
- + else
- + i = 0;
- +
- + for (j = 0; i < count; i++, j++)
- + {
- + rtx addr = plus_constant (from, j * word_size);
- + rtx mem = adjust_automodify_address_nv (basemem, mode, addr, offset);
- +
- + XVECEXP (result, 0, i) = gen_rtx_SET (VOIDmode,
- + gen_rtx_REG (mode, base_regno + (j * 2)),
- + mem);
- +
- + offset += word_size;
- + }
- +
- + if (write_back)
- + *offsetp = offset;
- +
- + return result;
- +}
- +
- +rtx
- +metag_gen_store_multiple (unsigned int base_regno,
- + unsigned int count,
- + enum machine_mode mode,
- + rtx to,
- + bool write_back,
- + rtx basemem,
- + HOST_WIDE_INT * offsetp)
- +{
- + HOST_WIDE_INT offset = *offsetp;
- + unsigned int i;
- + unsigned int word_size = GET_MODE_SIZE (mode);
- + unsigned int j;
- + rtx result;
- +
- + if (count < 2)
- + gcc_unreachable ();
- +
- + result = gen_rtx_PARALLEL (VOIDmode,
- + rtvec_alloc (count + (write_back ? 1 : 0)));
- +
- + if (write_back)
- + {
- + XVECEXP (result, 0, 0) = gen_rtx_SET (VOIDmode,
- + to,
- + plus_constant (to, count * word_size));
- + i = 1;
- + count++;
- + }
- + else
- + i = 0;
- +
- + for (j = 0; i < count; i++, j++)
- + {
- + rtx addr = plus_constant (to, j * word_size);
- + rtx mem = adjust_automodify_address_nv (basemem, mode, addr, offset);
- +
- + XVECEXP (result, 0, i) = gen_rtx_SET (VOIDmode,
- + mem,
- + gen_rtx_REG (mode, base_regno + (j * 2)));
- + offset += word_size;
- + }
- +
- + if (write_back)
- + *offsetp = offset;
- +
- + return result;
- +}
- +
- +bool
- +metag_gen_movmemqi (rtx operands[])
- +{
- + HOST_WIDE_INT xfer_bytes_to_go; /* # bytes to xfer in big chunks */
- + HOST_WIDE_INT last_bytes; /* # bytes left over */
- + HOST_WIDE_INT srcoffset;
- + HOST_WIDE_INT dstoffset;
- + enum machine_mode word_mode; /* mode in which to do the transfer */
- + unsigned int word_size; /* units in which to transfer */
- + unsigned int do_in_bytes = 0;
- + unsigned int do_in_max; /* max # of bytes to do in on go */
- + rtx src;
- + rtx dst;
- + rtx dstbase;
- + rtx srcbase;
- +
- + if ( !CONST_INT_P (operands[2])
- + || !CONST_INT_P (operands[3])
- + || INTVAL (operands[2]) > 96
- + || INTVAL (operands[2]) < 8
- + || INTVAL (operands[3]) & 3)
- + return false;
- +
- + dstbase = operands[0];
- + srcbase = operands[1];
- +
- + dst = copy_addr_to_reg (XEXP (dstbase, 0));
- + src = copy_addr_to_reg (XEXP (srcbase, 0));
- + if ((INTVAL (operands[3]) & 7) == 0
- + && INTVAL (operands[2]) >= 16)
- + {
- + /* Data 64-bit aligned with enough for two transfers */
- + xfer_bytes_to_go = INTVAL (operands[2]) & ~(UNITS_PER_WORD * 2 - 1);
- + word_mode = DImode;
- + word_size = UNITS_PER_WORD * 2;
- + last_bytes = INTVAL (operands[2]) & (UNITS_PER_WORD * 2 - 1);
- + do_in_max = 4 * word_size;
- +
- + /* Cannot use 64-bit mode if it's too short! */
- + gcc_assert (xfer_bytes_to_go >= 16);
- + }
- + else
- + {
- + /* Data not 64-bit aligned, used paired bursts so still 64-bit organised */
- + xfer_bytes_to_go = INTVAL (operands[2]) & ~(UNITS_PER_WORD - 1);
- + word_mode = SImode;
- + word_size = UNITS_PER_WORD;
- + last_bytes = INTVAL (operands[2]) & (UNITS_PER_WORD - 1);
- + do_in_max = 5 * word_size;
- +
- + if ((xfer_bytes_to_go + last_bytes) > 64)
- + return false;
- + }
- +
- + gcc_assert (do_in_max > 0);
- +
- + dstoffset = srcoffset = 0;
- +
- + while (xfer_bytes_to_go > 0)
- + {
- + unsigned int first_regno;
- +
- + /* Burst loop, transfer upto 32 or 20 bytes each */
- + do_in_bytes = xfer_bytes_to_go;
- +
- + /* On the input side bytes at the end count as an extra word */
- + if (last_bytes != 0)
- + do_in_bytes += word_size;
- +
- + if (do_in_bytes >= do_in_max * 2)
- + {
- + /* At least two full bursts left */
- + do_in_bytes = do_in_max;
- + }
- + else if (do_in_bytes > do_in_max)
- + {
- + /* Don't leave a runt at the end */
- + do_in_bytes |= (word_size * 2) - 1;
- + do_in_bytes >>= 1;
- + do_in_bytes += 1;
- + }
- +#if 0
- + first_regno = D0_0_REG;
- +#else
- + first_regno = D0_2_REG;
- + if (D0_7_REG - 2 * ((do_in_bytes / word_size)-1) < first_regno)
- + first_regno = D0_7_REG - 2 * ((do_in_bytes / word_size)-1);
- +#endif
- +
- + /* Load the data */
- + emit_insn (metag_gen_load_multiple (first_regno, do_in_bytes / word_size,
- + word_mode, src, true,
- + srcbase, &srcoffset));
- +
- + if (xfer_bytes_to_go < (int)do_in_bytes)
- + {
- + /* Replace the rounded up size with the real extra size */
- + do_in_bytes -= word_size;
- + xfer_bytes_to_go = 0;
- + }
- + else
- + {
- + /* Reduce bytes to go */
- + xfer_bytes_to_go -= do_in_bytes;
- + }
- +
- + /* Store the data */
- + if (do_in_bytes >= 2 * word_size)
- + emit_insn (metag_gen_store_multiple (first_regno, do_in_bytes / word_size,
- + word_mode, dst, true,
- + dstbase, &dstoffset));
- + else if (do_in_bytes >= word_size)
- + {
- + metag_emit_load_post_inc (dstbase, word_mode, dst,
- + dstoffset, first_regno);
- + dstoffset += word_size;
- + }
- + else
- + gcc_unreachable ();
- + }
- +
- + /* Are we finished? */
- + if (last_bytes > 0)
- + {
- +#if 0
- + unsigned int last_regno = D0_0_REG + 2 * (do_in_bytes / word_size);
- +#else
- + unsigned int last_regno = D0_2_REG + 2 * (do_in_bytes / word_size);
- + if (D0_7_REG - 2 * (do_in_bytes / word_size) < D0_2_REG)
- + last_regno -= D0_2_REG - (D0_7_REG - 2 * (do_in_bytes / word_size));
- +#endif
- +
- + /* Here we handle and remaining 4-byte chunks left to xfer */
- + if ((last_bytes & 4) != 0)
- + {
- + gcc_assert (word_size == UNITS_PER_WORD * 2);
- + /* Store last 32-bit word and switch remainder into SImode */
- +
- + /* Generate write for bottom SImode subreg of last DImode register,
- + Further manipulation needed on upper part of DImode register */
- + metag_emit_load_post_inc (dstbase, SImode, dst,
- + dstoffset, last_regno);
- +
- + dstoffset += 4;
- +
- + /* If we have any remaing 2-byte or 1-byte chunks left adjust dst */
- + if ((last_bytes & 3) != 0)
- + last_regno = last_regno + 1;
- + }
- +
- + /* Here we handle any remaining 2-byte chunks left to xfer */
- + if ((last_bytes & 2) != 0)
- + {
- + metag_emit_load_post_inc (dstbase, HImode, dst,
- + dstoffset, last_regno);
- +
- + dstoffset += 2;
- +
- + /* If we have any remaing 1-byte chunks left adjust dst */
- + if ((last_bytes & 1) != 0)
- + {
- + rtx tmp = gen_rtx_REG (SImode, last_regno);
- +
- + emit_insn (gen_lshrsi3 (tmp, tmp, GEN_INT (16)));
- + }
- + }
- +
- + /* Here we handle any remaining 1-byte chunks left to xfer */
- + if ((last_bytes & 1) != 0)
- + {
- + metag_emit_load_post_inc (dstbase, QImode, dst,
- + dstoffset, last_regno);
- +
- + dstoffset += 1;
- + }
- + }
- +
- + return true;
- +}
- +
- +#if METAG_DEBUG_CCEXEC
- +static const char *
- +attr_cond_name (enum attr_cond attr)
- +{
- + switch (attr)
- + {
- + case COND_YES:
- + return "yes";
- + case COND_NO:
- + return "no";
- + default:
- + break;
- + }
- +
- + return "??";
- +}
- +
- +static const char *
- +attr_ccstate_name (enum attr_ccstate attr)
- +{
- + switch (attr)
- + {
- + case CCSTATE_XCC:
- + return "xcc";
- + case CCSTATE_SET:
- + return "set";
- + case CCSTATE_FASTSET:
- + return "fastset";
- + case CCSTATE_FASTFASTSET:
- + return "fastfastset";
- + case CCSTATE_CCX:
- + return "ccx";
- + case CCSTATE_NCC:
- + return "ncc";
- + default:
- + break;
- + }
- +
- + return "???";
- +}
- +
- +static const char *
- +attr_predicable_name (enum attr_predicable attr)
- +{
- + switch (attr)
- + {
- + case PREDICABLE_YES:
- + return "yes";
- + case PREDICABLE_NO:
- + return "no";
- + default:
- + break;
- + }
- +
- + return "??";
- +}
- +#endif
- +
- +
- +/* The state of the fsm controlling condition codes are:
- + 0: normal, do nothing special
- + 1: make ASM_OUTPUT_OPCODE not output this instruction
- + 2: make ASM_OUTPUT_OPCODE not output this instruction
- + 3: make instructions conditional
- + 4: make instructions conditional
- +
- + State transitions (state->state by whom under condition):
- + 0 -> 1 final_prescan_insn if the `target' is a label
- + 0 -> 2 final_prescan_insn if the `target' is an unconditional branch
- + 1 -> 3 ASM_OUTPUT_OPCODE after not having output the conditional branch
- + 2 -> 4 ASM_OUTPUT_OPCODE after not having output the conditional branch
- + 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL if the `target' label is reached
- + (the target label has CODE_LABEL_NUMBER equal to metag_target_label).
- + 4 -> 0 final_prescan_insn if the `target' unconditional branch is reached
- + (the target insn is metag_target_insn).
- +
- + If the jump clobbers the conditions then we use states 2 and 4.
- +
- + A similar thing can be done with conditional return insns.
- +
- + XXX In case the `target' is an unconditional branch, this conditionalising
- + of the instructions always reduces code size, but not always execution
- + time. But then, I want to reduce the code size to somewhere near what
- + /bin/cc produces. */
- +
- +void
- +metag_final_prescan_insn (rtx insn)
- +{
- + /* BODY will hold the body of INSN. */
- + rtx body = PATTERN (insn);
- +
- + /* This will be 1 if trying to repeat the trick, and things need to be
- + reversed if it appears to fail. */
- + int reverse = 0;
- +
- + /* START_INSN will hold the insn from where we start looking. This is the
- + first insn after the following code_label if REVERSE is true. */
- + rtx start_insn = insn;
- +
- + /* If in state 4, check if the target branch is reached, in order to
- + change back to state 0. */
- + if (metag_ccfsm_state == 4)
- + {
- + if (insn == metag_target_insn)
- + {
- + metag_target_insn = NULL_RTX;
- + metag_ccfsm_state = 0;
- + }
- + return;
- + }
- +
- + /* If in state 3, it is possible to repeat the trick, if this insn is an
- + unconditional branch to a label, and immediately following this branch
- + is the previous target label which is only used once, and the label this
- + branch jumps to is not too far off. */
- + if (metag_ccfsm_state == 3)
- + {
- + if (simplejump_p (insn))
- + {
- + start_insn = next_nonnote_insn (start_insn);
- + if (BARRIER_P (start_insn))
- + {
- + /* XXX Isn't this always a barrier? */
- + start_insn = next_nonnote_insn (start_insn);
- + }
- +
- + if (GET_CODE (start_insn) == CODE_LABEL
- + && CODE_LABEL_NUMBER (start_insn) == metag_target_label
- + && LABEL_NUSES (start_insn) == 1)
- + reverse = true;
- + else
- + return;
- + }
- + else
- + return;
- + }
- +
- + if (metag_ccfsm_state != 0 && !reverse)
- + gcc_unreachable ();
- +
- + if (!JUMP_P (insn))
- + return;
- +
- + /* This jump might be paralleled with a clobber of the condition codes
- + the jump should always come first */
- + if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
- + body = XVECEXP (body, 0, 0);
- +
- + /* If this jump uses the hardware loop counter, leave it alone */
- + if (reg_mentioned_p (gen_rtx_REG (VOIDmode, TXRPT_REGNUM), body))
- + return;
- +
- + /* If this is a conditional return then we don't want to know */
- + if (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
- + && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
- + && (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN
- + || GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN))
- + return;
- +
- + if (reverse
- + || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
- + && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
- + {
- + int insns_skipped = 0;
- + int fail = 0;
- + int quit = false, succeed = false;
- + /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
- + int then_not_else = true;
- + rtx this_insn = start_insn;
- + rtx label = NULL_RTX;
- +
- + /* Register the insn jumped to. */
- + if (reverse)
- + label = XEXP (SET_SRC (body), 0);
- + else if (LABEL_REF_P (XEXP (SET_SRC (body), 1)))
- + label = XEXP (XEXP (SET_SRC (body), 1), 0);
- + else if (LABEL_REF_P (XEXP (SET_SRC (body), 2)))
- + {
- + label = XEXP (XEXP (SET_SRC (body), 2), 0);
- + then_not_else = false;
- + }
- + else
- + gcc_unreachable ();
- +
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE =====\n"); debug_rtx (insn);
- +#endif
- + /* See how many insns this branch skips, and what kind of insns. If all
- + insns are okay, and the label or unconditional branch to the same
- + label is not too far away, succeed. */
- + while (!quit && !succeed && insns_skipped < metag_max_insns_skipped)
- + {
- + this_insn = next_nonnote_insn (this_insn);
- + if (!this_insn)
- + break;
- +
- + /* Only count recognised instructions others aren't relevant.*/
- +
- + if (INSN_P (this_insn) && INSN_CODE (this_insn) >= 0)
- + insns_skipped++;
- +
- + switch (GET_CODE (this_insn))
- + {
- + case CODE_LABEL:
- + /* Succeed if it is the target label, otherwise fail since
- + control falls in from somewhere else. */
- + if (this_insn == label)
- + {
- + if (fail == 0)
- + {
- + metag_ccfsm_state = 1;
- + succeed = true;
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE found label after %d successes\n", insns_skipped);
- +#endif
- + }
- + else
- + {
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE found label after %d failures\n", fail);
- +#endif
- + quit = true;
- + }
- + }
- + else
- + {
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE failed CODE_LABEL after %d insns\n", insns_skipped);
- +#endif
- + fail++;
- + }
- +
- + break;
- +
- + case BARRIER:
- + /* Succeed if the following insn is the target label.
- + Otherwise fail.
- + If return insns are used then the last insn in a function
- + will be a barrier. */
- + this_insn = next_nonnote_insn (this_insn);
- + if (this_insn && this_insn == label)
- + {
- + if (fail == 0)
- + {
- + metag_ccfsm_state = 1;
- + succeed = true;
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE found label after %d successes\n", insns_skipped);
- +#endif
- + }
- + else
- + {
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE found label after %d failures\n", fail);
- +#endif
- + quit = true;
- + }
- + }
- + else
- + {
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE failed BARRIER after %d insns\n", insns_skipped);
- +#endif
- + fail++;
- + }
- +
- + break;
- +
- + case CALL_INSN:
- +#if 0
- + if (!(GET_CODE (operands[?]) == REG
- + && REGNO (operands[?]) != RETURN_POINTER_REGNUM))
- +#endif
- + {
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE failed CALL_INSN after %d insns\n", insns_skipped);
- + debug_rtx (this_insn);
- +#endif
- + fail++;
- + }
- + break;
- +
- + case JUMP_INSN:
- + /* If this is an unconditional branch to the same label, succeed.
- + If it is to another label, do nothing. If it is conditional,
- + fail. */
- + /* XXX Probably, the tests for SET and the PC are unnecessary. */
- +
- + {
- + rtx scanbody = PATTERN (this_insn);
- +
- + if (GET_CODE (scanbody) == SET
- + && GET_CODE (SET_DEST (scanbody)) == PC)
- + {
- + if (LABEL_REF_P (SET_SRC (scanbody))
- + && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
- + {
- + if (fail == 0)
- + {
- + metag_ccfsm_state = 2;
- + succeed = true;
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE found jump to target label after %d successes\n", insns_skipped);
- +#endif
- + }
- + else
- + {
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE found uncond branch after %d failures\n", fail);
- +#endif
- + quit = true;
- + }
- + }
- + else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
- + {
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE failed JUMP_INSN IF_THEN_ELSE after %d insn\n", insns_skipped);
- + debug_rtx (this_insn);
- +#endif
- + fail++;
- + }
- + }
- + else if (GET_CODE (scanbody) == RETURN)
- + {
- + if (!metag_cheap_return (true))
- + {
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE failed JUMP_INSN RETURN (not cheap) after %d insn\n", insns_skipped);
- + debug_rtx (this_insn);
- +#endif
- + fail++;
- + }
- + }
- + else
- + {
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE failed JUMP_INSN not recognised after %d insn\n", insns_skipped);
- + debug_rtx (this_insn);
- +#endif
- + fail++;
- + }
- + }
- +
- + break;
- +
- + case INSN:
- + if (INSN_CODE (this_insn) >= 0)
- + {
- + enum attr_cond cond_attr = get_attr_cond (this_insn);
- + enum attr_predicable predicable_attr = get_attr_predicable (this_insn);
- + enum attr_ccstate ccstate_attr = get_attr_ccstate (this_insn);
- +
- + /* A predicated instruction can't be COND_EXEC unless
- + the predication condition matches the condexec
- + condition. At present we ALWAYS reject predicated
- + instructions which is safe but sub-optimal. */
- + if (predicable_attr == PREDICABLE_YES && GET_CODE (PATTERN (this_insn)) == COND_EXEC)
- + {
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE failed INSN PREDICABLE=%s and COND_EXEC after %d insns\n",
- + attr_predicable_name (predicable_attr),
- + insns_skipped);
- + debug_rtx (this_insn);
- +#endif
- + fail++;
- + }
- +
- + /* Only insns which don't modify CC can be cond-exec */
- + if (cond_attr != COND_YES || ccstate_attr != CCSTATE_NCC)
- + {
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE failed INSN COND=%s CSTATE=%s after %d insns\n",
- + attr_cond_name (cond_attr),
- + attr_ccstate_name (ccstate_attr),
- + insns_skipped);
- + debug_rtx (this_insn);
- +#endif
- + fail++;
- + }
- + }
- + else if (asm_noperands (PATTERN (this_insn)) >= 0)
- + {
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE failed ASM_OPERANDS after %d insns\n",
- + insns_skipped);
- + debug_rtx (this_insn);
- +#endif
- + fail++;
- + }
- + else if (GET_CODE (PATTERN (this_insn)) != USE)
- + {
- + /* Anything else not recognised with the exception of
- + an USE (typically an USE of return register) fails
- + conditional execution. */
- +#if METAG_DEBUG_CCEXEC
- + fprintf (stderr, "CE failed unrecognised after %d insns\n",
- + insns_skipped);
- + debug_rtx (this_insn);
- +#endif
- + fail++;
- + }
- +
- + break;
- +
- + default:
- + break;
- + }
- + }
- +
- + if (succeed)
- + {
- + if (metag_ccfsm_state == 1 || reverse)
- + metag_target_label = CODE_LABEL_NUMBER (label);
- + else if (metag_ccfsm_state == 2)
- + {
- + while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
- + {
- + this_insn = next_nonnote_insn (this_insn);
- + if (this_insn
- + && (BARRIER_P (this_insn)
- + || GET_CODE (this_insn) == CODE_LABEL))
- + gcc_unreachable ();
- + }
- +
- + if (!this_insn)
- + {
- + /* Oh, dear! we ran off the end.. give up */
- + if (INSN_CODE (insn) >= 0)
- + {
- + recog (PATTERN (insn), insn, NULL);
- + cleanup_subreg_operands (insn);
- + }
- +
- + metag_ccfsm_state = 0;
- + metag_target_insn = NULL_RTX;
- + return;
- + }
- +
- + metag_target_insn = this_insn;
- + }
- + else
- + gcc_unreachable ();
- +
- + /* If REVERSE is true, METAG_CURRENT_CC needs to be inverted
- + * from what it was. */
- + if (!reverse)
- + metag_current_cc = get_metag_cc (XEXP (SET_SRC (body), 0));
- +
- + if (reverse || then_not_else)
- + metag_current_cc = metag_inv_cc [metag_current_cc];
- + }
- +
- + if (INSN_CODE (insn) >= 0)
- + {
- + /* restore recog_operand (getting the attributes of other insns can
- + destroy this array, but final.c assumes that it remains intact
- + across this call; since the insn has been recognized already we
- + call recog direct). */
- + recog (PATTERN (insn), insn, NULL);
- + cleanup_subreg_operands (insn);
- + }
- + }
- +}
- +
- +bool
- +metag_cond_exec_p (void)
- +{
- + return (metag_ccfsm_state == 3 || metag_ccfsm_state == 4);
- +}
- +
- +void
- +metag_print_cc_if_conditional (FILE *stream)
- +{
- + if (metag_cond_exec_p ())
- + {
- + gcc_assert (current_insn_predicate == NULL_RTX);
- + fputs (metag_cc_names[metag_current_cc], stream);
- + }
- + else if (current_insn_predicate != NULL_RTX)
- + fputs (metag_cc_names[get_metag_cc (current_insn_predicate)], stream);
- +
- + return;
- +}
- +
- +bool
- +metag_consume_branch (rtx insn ATTRIBUTE_UNUSED)
- +{
- + if (metag_ccfsm_state == 1 || metag_ccfsm_state == 2)
- + {
- + metag_ccfsm_state += 2;
- + return true;
- + }
- +
- + return false;
- +}
- +
- +
- +/* Output to FILE code to call mcount. */
- +void
- +metag_function_profiler (FILE *file)
- +{
- + if (1 || !TARGET_METAC_1_1)
- + {
- + fprintf (file, "\tMOVT\t%s, #HI(_mcount_wrapper)\n",
- + reg_names[TEMP_D0FRT_REGNUM]);
- + fprintf (file, "\tCALL\t%s, #LO(_mcount_wrapper)\n",
- + reg_names[TEMP_D0FRT_REGNUM]);
- + }
- + else
- + fprintf (file, "\tCALLR\t%s, _mcount_wrapper\n",
- + reg_names[TEMP_D0FRT_REGNUM]);
- +}
- +
- +static bool
- +metag_same_reg_p (rtx reg1, rtx reg2, bool strict)
- +{
- + unsigned int r1 = REGNO (reg1);
- + unsigned int r2 = REGNO (reg2);
- +
- + if (IS_PSEUDO_REGNO (r1) && reg_renumber != NULL)
- + r1 = reg_renumber[r1];
- +
- + if (IS_PSEUDO_REGNO (r2) && reg_renumber != NULL)
- + r2 = reg_renumber[r2];
- +
- + return strict ? IS_HARD_OR_VIRT_REGNO (r1) && IS_HARD_OR_VIRT_REGNO (r2) && r1 == r2
- + : r1 != INVALID_REGNUM && r1 != INVALID_REGNUM && r1 == r2;
- +}
- +
- +static bool
- +metag_regs_same_regclass_p (rtx reg1, rtx reg2, bool strict)
- +{
- + unsigned int r1 = REGNO (reg1);
- + unsigned int r2 = REGNO (reg2);
- + enum reg_class class1;
- + enum reg_class class2;
- +
- + if (IS_PSEUDO_REGNO (r1) && reg_renumber != NULL)
- + r1 = reg_renumber[r1];
- +
- + if (IS_PSEUDO_REGNO (r2) && reg_renumber != NULL)
- + r2 = reg_renumber[r2];
- +
- + class1 = METAG_REGNO_REG_CLASS (r1);
- + class2 = METAG_REGNO_REG_CLASS (r2);
- +
- + return strict ? class1 != NO_REGS && class2 != NO_REGS && class1 == class2
- + : class1 != NO_REGS && class2 != NO_REGS && class1 == class2;
- +}
- +
- +bool
- +metag_same_regclass_p (rtx reg1, rtx reg2)
- +{
- + return metag_regs_same_regclass_p (reg1, reg2, true);
- +}
- +
- +/* Return true iff the registers are in the same function unit
- + (i.e. D0, D1, A0, A1, CTRL). */
- +
- +bool
- +metag_regno_same_unit_p (unsigned int regno1, unsigned int regno2)
- +{
- + enum reg_class class1 = METAG_REGNO_REG_CLASS (regno1);
- + enum reg_class class2 = METAG_REGNO_REG_CLASS (regno2);
- +
- + return class1 != NO_REGS && class2 != NO_REGS && class1 == class2;
- +}
- +
- +/* (post_modify (REG ...)
- + (plus (REG ...)
- + (REG ...)))
- + or
- +
- + (post_modify (REG ...)
- + (plus (REG ...)
- + (CONST_INT ...)))
- +*/
- +bool
- +metag_legitimate_modify_p (rtx addr, enum machine_mode mode, bool strict)
- +{
- + rtx op0 = XEXP (addr, 0);
- + rtx op1 = XEXP (addr, 1);
- + rtx op2;
- + rtx op3;
- +
- + if (GET_CODE (op1) != PLUS)
- + return false;
- +
- + if (!METAG_LEGITIMATE_REG_P (op0, strict))
- + return false;
- +
- + op2 = XEXP (op1, 0);
- + op3 = XEXP (op1, 1);
- + if (!METAG_LEGITIMATE_REG_P (op2, strict))
- + return false;
- +
- + if (!metag_same_reg_p (op0, op2, strict))
- + return false;
- +
- + if (REG_P (op3))
- + return METAG_LEGITIMATE_TWIN_P (op2, op3, mode, strict);
- +
- + if (CONST_INT_P (op3) && metag_offset6_mode (op3, mode))
- + return true;
- +
- + return false;
- +}
- +
- +long
- +metag_const_double_to_hp (rtx op, bool *inexact)
- +{
- + REAL_VALUE_TYPE rv;
- + long half = 0;
- + bool dummy_inexact;
- +
- + if (!inexact)
- + inexact = &dummy_inexact;
- +
- + REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
- +
- + *inexact = false;
- +
- + if (GET_MODE(op) == SFmode)
- + {
- + long tgsingle;
- + bool tgsgn;
- + long tgexp;
- + long tgman;
- +
- + REAL_VALUE_TO_TARGET_SINGLE (rv, tgsingle);
- +
- + /* Split the parts */
- + tgsgn = ((tgsingle & 0x80000000ul) != 0);
- + tgexp = (tgsingle & 0x7F800000) >> 23;
- + tgman = tgsingle & 0x007FFFFF;
- +
- + /* If the fractional part would need rounding, raise inexact */
- + if (tgman & 0x00001FFF)
- + *inexact = true;
- +
- + /* Convert to HF (truncate) */
- +
- + /* Exp == MAX we must preserve the Inf or NaN */
- + if (tgexp == 0xFF)
- + half = tgman ? 0x7C01 : 0x7C00;
- + /* Exp == 0 is special we must not bias adjust it */
- + else if (tgexp == 0x00)
- + half = tgman >> (23 - 10);
- + else
- + {
- + tgexp -= 127; /* Remove SF bias */
- + tgexp += 15; /* Add HF bias */
- + tgman >>= 23 - 10;
- +
- + if (tgexp >= 32)
- + {
- + *inexact = true;
- + half = 0x7C00; /* Overflow to inf */
- + }
- + else if (tgexp < 0)
- + {
- + *inexact = true;
- + half = 0x0000; /* Underflow to 0 */
- + }
- + else
- + half = (tgexp & 0x01F) << 10
- + | (tgman & 0x3FF);
- + }
- +
- + /* Copy the sign */
- + if (tgsgn)
- + half |= 0x8000;
- + }
- + else if (GET_MODE(op) == DFmode)
- + {
- + long tgdouble[2];
- + bool tgsgn;
- + long tgexp;
- + long tgman[2];
- +
- + REAL_VALUE_TO_TARGET_DOUBLE (rv, tgdouble);
- +
- + /* Split the parts */
- + tgsgn = ((tgdouble[1] & 0x80000000ul) != 0);
- + tgexp = (tgdouble[1] & 0x7FF00000) >> (52-32);
- + tgman[1] = (tgdouble[1] & 0x000FFFFF);
- + tgman[0] = tgdouble[0];
- +
- + /* If the fractional part would need rounding, reject */
- + if (tgman[1] & 0x0000FFFF || tgman[0])
- + *inexact = true;
- +
- + /* Convert to HF (truncate) */
- +
- + /* Exp == MAX we must preserve the Inf or NaN */
- + if (tgexp == 0x7FF)
- + half = tgman[1] || tgman[0] ? 0x7C01 : 0x7C00;
- + /* Exp == 0 is special we must not bias adjust it */
- + else if (tgexp == 0x00)
- + half = tgman[1] >> (52 - 10 - 32);
- + else
- + {
- + tgexp -= 1023; /* Remove SF bias */
- + tgexp += 15; /* Add HF bias */
- + tgman[0] = tgman[1] >> (52 - 10 - 32);
- + tgman[1] = 0;
- +
- + if (tgexp >= 32)
- + {
- + *inexact = true;
- + half = 0x7C00; /* Overflow to inf */
- + }
- + else if (tgexp < 0)
- + {
- + *inexact = true;
- + half = 0x0000; /* Underflow to 0 */
- + }
- + else
- + half = (tgexp & 0x01F) << 10
- + | (tgman[0] & 0x3FF);
- + }
- +
- + /* Copy the sign */
- + if (tgsgn)
- + half |= 0x8000;
- + }
- +
- + return half;
- +}
- +
- +void
- +metag_print_operand (FILE * file, rtx op, enum rtx_code code)
- +{
- + if (code == '?')
- + metag_print_cc_if_conditional (file);
- + else if (code == '@')
- + fputs (ASM_COMMENT_START, file);
- + else if (code == 'z')
- + fputs (metag_cc_names[get_metag_cc (op)], file);
- + else if (code == 'Z')
- + fputs (metag_cc_names[metag_inv_cc [get_metag_cc (op)]], file);
- + else if (code == 'h')
- + {
- + if (GET_CODE (op) == CONST_VECTOR)
- + {
- + gcc_assert (GET_MODE_INNER (GET_MODE (op)) == SFmode);
- + gcc_assert (rtx_equal_p (CONST_VECTOR_ELT (op, 0),
- + CONST_VECTOR_ELT (op, 1)));
- + op = CONST_VECTOR_ELT (op, 0);
- + }
- + fprintf (file, "0x%04lX", metag_const_double_to_hp (op, NULL));
- + }
- + else if (REG_P (op))
- + {
- + if (code == 't')
- + fputs (reg_names[REGNO (op) + 1], file);
- + else
- + fputs (reg_names[REGNO (op)], file);
- + }
- + else
- + {
- + if (MEM_P (op))
- + {
- + if (SYMBOL_REF_P (XEXP (op, 0)))
- + {
- + /* Abort if we're about to generate #OG addressing. */
- + debug_rtx (op);
- + gcc_unreachable ();
- + }
- + else
- + output_address (op);
- + }
- + else
- + {
- + if (CONST_DOUBLE_P (op) && GET_MODE (op) == SFmode)
- + {
- + long value = metag_const_double_sfmode (op);
- +
- + if (code != 'c')
- + fputc ('#', file);
- + fprintf (file, "0x%08lx", value);
- + }
- + else
- + {
- + if (code != 'c')
- + {
- + rtx itemp = op;
- +
- + fputc ('#', file);
- + if (CONST_INT_P (op)
- + && (INTVAL (op) < -32768 || INTVAL (op) > 0x0000FFFF))
- + itemp = GEN_INT (((INTVAL (op)) >> 16) & 0x0000FFFF);
- +
- + output_addr_const (file, itemp);
- + }
- + else if (CONST_INT_P (op)
- + && (INTVAL (op) < -32768 || INTVAL (op) > 0x0000FFFF))
- + fprintf (file, "0x%08lx", (long)INTVAL (op));
- + else
- + output_addr_const (file, op);
- + }
- + }
- + }
- +}
- +
- +static void
- +metag_output_pic_addr_const (FILE *file, rtx addr)
- +{
- + output_addr_const (file, XVECEXP (addr, 0, 0));
- + switch (XINT (addr, 1))
- + {
- + case UNSPEC_GOT:
- + fputs ("@GOT", file);
- + break;
- + case UNSPEC_GOTOFF:
- + fputs ("@GOTOFF", file);
- + break;
- + case UNSPEC_PLT:
- + fputs ("@PLT", file);
- + break;
- + default:
- + metag_abort (addr);
- + break;
- + }
- +}
- +
- +void
- +metag_print_operand_address (FILE *file, rtx op)
- +{
- + rtx addr = MEM_P (op) ? XEXP (op, 0) : op;
- + rtx offset;
- + rtx reg;
- + int inc;
- +
- + switch (GET_CODE (addr))
- + {
- + case SYMBOL_REF:
- + /* Abort if we're about to generate #OG addressing. */
- + gcc_unreachable ();
- + break;
- + case REG:
- + fprintf (file, "[%s]", reg_names[REGNO (addr)]);
- + break;
- + case PRE_INC:
- + reg = XEXP (addr, 0);
- + inc = GET_MODE_SIZE (GET_MODE (op));
- + fprintf (file, "[%s ++#%d]", reg_names[REGNO (reg)], inc);
- + break;
- + case POST_INC:
- + reg = XEXP (addr, 0);
- + inc = GET_MODE_SIZE (GET_MODE (op));
- + fprintf (file, "[%s+#%d++]", reg_names[REGNO (reg)], inc);
- + break;
- + case PRE_DEC:
- + reg = XEXP (addr, 0);
- + inc = GET_MODE_SIZE (GET_MODE (op));
- + fprintf (file, "[%s ++#(-%d)]", reg_names[REGNO (reg)], inc);
- + break;
- + case POST_DEC:
- + reg = XEXP (addr, 0);
- + inc = GET_MODE_SIZE (GET_MODE (op));
- + fprintf (file, "[%s+#(-%d)++]", reg_names[REGNO (reg)], inc);
- + break;
- + case PRE_MODIFY:
- + reg = XEXP (addr, 0);
- + if (GET_CODE (XEXP (addr, 1)) != PLUS)
- + metag_abort (op);
- + else
- + {
- + rtx op0 = XEXP (XEXP (addr, 1), 0);
- +
- + if (!REG_P (op0))
- + metag_abort (op);
- + else if (REGNO (reg) != REGNO (op0))
- + metag_abort (op);
- + else
- + {
- + rtx op1 = XEXP (XEXP (addr, 1), 1);
- +
- + if (REG_P (op1))
- + fprintf (file, "[%s++%s]",
- + reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
- + else if (CONST_INT_P (op1))
- + fprintf (file, "[%s++#(%ld)]",
- + reg_names[REGNO (op0)], INTVAL (op1));
- + else
- + metag_abort (op);
- + }
- + }
- + break;
- + case POST_MODIFY:
- + reg = XEXP (addr, 0);
- + if (GET_CODE (XEXP (addr, 1)) != PLUS)
- + metag_abort (op);
- + else
- + {
- + rtx op0 = XEXP (XEXP (addr, 1), 0);
- +
- + if (!REG_P (op0))
- + metag_abort (op);
- + else if (REGNO (reg) != REGNO (op0))
- + metag_abort (op);
- + else
- + {
- + rtx op1 = XEXP (XEXP (addr, 1), 1);
- +
- + if (REG_P (op1))
- + fprintf (file, "[%s+%s++]",
- + reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
- + else if (CONST_INT_P (op1))
- + fprintf (file, "[%s+#(%ld)++]",
- + reg_names[REGNO (op0)], INTVAL (op1));
- + else
- + metag_abort (op);
- + }
- + }
- + break;
- + case PLUS:
- + reg = XEXP (addr, 0);
- + if (CONST_INT_P (reg))
- + {
- + offset = reg;
- + reg = XEXP (addr, 1);
- + }
- + else
- + offset = XEXP (addr, 1);
- +
- + if (!REG_P (reg))
- + metag_abort (addr);
- +
- + if (REG_P (offset))
- + fprintf (file, "[%s + %s]",
- + reg_names[REGNO (reg)], reg_names[REGNO (offset)]);
- + else if (CONST_INT_P (offset))
- + fprintf (file, "[%s + #%ld]", reg_names[REGNO (reg)], INTVAL (offset));
- + else if (METAG_FLAG_PIC
- + && reg == pic_offset_table_rtx
- + && GET_CODE (offset) == CONST
- + && GET_CODE (XEXP (offset, 0)) == UNSPEC
- + && XVECLEN (XEXP (offset, 0), 0) == 1
- + && (XINT (XEXP (offset, 0), 1) == UNSPEC_GOT
- + || XINT (XEXP (offset, 0), 1) == UNSPEC_PLT))
- + {
- + fprintf (file, "[%s + #(", reg_names[REGNO (reg)]);
- + metag_output_pic_addr_const (file, XEXP (offset, 0));
- + fputs (")]", file);
- + }
- + else
- + metag_abort (addr);
- + break;
- + default:
- + if (CONSTANT_ADDRESS_P (addr))
- + output_addr_const (file, addr);
- + else
- + metag_abort (addr);
- + break;
- + }
- +}
- +
- +int
- +metag_arg_partial_bytes (CUMULATIVE_ARGS * cum, enum machine_mode mode, tree type, bool named)
- +{
- + unsigned int acum;
- + unsigned int aarg;
- + unsigned int nbytes;
- +
- + /* variadic arguments a.k.a named are ALWAYS passed on the stack */
- +
- + if (!named)
- + return 0;
- +
- + acum = ROUND_ADVANCE_CUM (cum->narg, mode, type);
- + aarg = ROUND_ADVANCE_ARG (mode, type);
- +
- + nbytes = ((acum < MAX_METAG_PARM_BYTES && MAX_METAG_PARM_BYTES < (acum + aarg))
- + ? (MAX_METAG_PARM_BYTES - acum)
- + : 0);
- +
- + if (cum->partial == 0)
- + {
- + if (nbytes > 0)
- + {
- + int size = METAG_ARG_SIZE (mode, type);
- + int nstack = size - nbytes;
- +
- + gcc_assert ((nstack & (STACK_BOUNDARY_BYTES - 1)) == 0);
- + }
- +
- + cum->partial = nbytes;
- + }
- + else
- + gcc_assert (nbytes == 0);
- +
- + return nbytes;
- +}
- +
- +bool
- +metag_pass_by_reference (CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED,
- + enum machine_mode mode ATTRIBUTE_UNUSED,
- + tree type ATTRIBUTE_UNUSED,
- + bool named ATTRIBUTE_UNUSED)
- +{
- + return false;
- +}
- +
- +static bool
- +metag_pass_in_reg (CUMULATIVE_ARGS * cum,
- + enum machine_mode mode,
- + tree type,
- + bool named ATTRIBUTE_UNUSED)
- +{
- + int rcum;
- +
- + if (!named)
- + return false;
- +
- + if (cum->narg >= MAX_METAG_PARM_BYTES)
- + return false;
- +
- + rcum = ROUND_ADVANCE_CUM (cum->narg, mode, type);
- + if (rcum >= MAX_METAG_PARM_BYTES)
- + return false;
- +
- + return true;
- +}
- +
- +bool
- +metag_must_pass_in_stack (enum machine_mode mode ATTRIBUTE_UNUSED,
- + tree type ATTRIBUTE_UNUSED)
- +{
- + return false;
- +}
- +
- +rtx
- +metag_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, tree type, bool named)
- +{
- + bool pass_in_reg = metag_pass_in_reg (cum, mode, type, named);
- + int reg;
- +
- + if (!pass_in_reg)
- + return NULL_RTX;
- +
- + reg = CALCULATE_REG (MAX_METAG_PARM_REGNUM, cum->narg, mode, type);
- + if (reg < MIN_METAG_PARM_REGNUM)
- + reg = MIN_METAG_PARM_REGNUM;
- +
- + return gen_rtx_REG (mode, reg);
- +}
- +
- +void
- +metag_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode, tree type, bool named ATTRIBUTE_UNUSED)
- +{
- + cum->narg = ROUND_ADVANCE_CUM (cum->narg, mode, type) + ROUND_ADVANCE_ARG (mode, type);
- + return;
- +}
- +
- +/* Define the offset between two registers, one to be eliminated,
- + and the other its replacement, at the start of a routine.
- +
- + To kick things off we work out OFFSET as the size of the frame save
- + area. Then we need to apply the following-
- +
- + ARG_POINTER = STACK_POINTER - (PRETEND + SAVE + PIC_SAVE + LOCAL + OUT_GOING)
- + ARG_POINTER = HARD_FRAME_POINTER - (PRETEND )
- + FRAME_POINTER = STACK_POINTER - ( + SAVE + PIC_SAVE + LOCAL + OUT_GOING)
- + FRAME_POINTER = HARD_FRAME_POINTER + ( + SAVE + PIC_SAVE )
- + */
- +
- +int
- +metag_initial_elimination_offset (int from, int to)
- +{
- + /* This section of code and output_fn_prologue/epilogue
- + * MUST agree on how the stack is going to be layedout.
- + * Any discrepancy will result in wrong code being
- + * generated.
- + */
- +
- + HOST_WIDE_INT out_local_size = get_frame_size ();
- + bool non_leaf = metag_non_leaf_function_p ();
- + unsigned int savesize_gp = 0;
- + unsigned int savesize_eh = 0;
- + unsigned int FP_SP_offset = 0;
- + unsigned int pic_save_size = 0;
- + unsigned int pretend_size = ALIGN_ON_STACK_BOUNDARY (current_function_pretend_args_size);
- + unsigned int extras_gp = 0;
- + unsigned int extras_eh = 0;
- + unsigned int ech_ctx = 0;
- + unsigned int pretend_regs;
- + int delta;
- + bool loads_pic_register;
- +
- + if (pretend_size != 0)
- + {
- + /* Determine # register pairs needed for pretend args. */
- + pretend_regs = pretend_size / UNITS_PER_WORD;
- + }
- + else
- + pretend_regs = 0;
- +
- + out_local_size = ALIGN_ON_STACK_BOUNDARY (out_local_size + current_function_outgoing_args_size);
- +
- + /* Make pretend regs into the first non-varargs register number */
- + pretend_regs += MIN_METAG_PARM_REGNUM;
- +
- + {
- + unsigned int regno;
- +
- + for (regno = MIN_METAG_PARM_REGNUM;
- + regno <= MAX_METAG_CSAVE_REGNUM;
- + regno += 2)
- + {
- + if (regno < pretend_regs
- + || (!call_used_regs[regno]
- + && (df_regs_ever_live_p (regno + 0) || df_regs_ever_live_p (regno + 1))))
- + {
- + extras_gp |= REGNO_BIT (regno);
- + savesize_gp += UNITS_PER_WORD * 2;
- +
- + if (regno >= MIN_METAG_CSAVE_REGNUM)
- + FP_SP_offset += UNITS_PER_WORD * 2;
- + }
- + }
- + }
- +
- + /* Adjust the saved registers for ECH support */
- + ech_ctx = metag_adjust_savesize_ech (&savesize_gp, &extras_gp, &FP_SP_offset);
- +
- + if (current_function_calls_eh_return)
- + {
- + unsigned int n;
- +
- + for (n = 0; n < NUM_EH_RETURN_DATA_REGS; n++)
- + {
- + unsigned int regno = EH_RETURN_DATA_REGNO (n);
- +
- + if (regno != INVALID_REGNUM)
- + {
- + unsigned int regbit = REGNO_BIT (regno);
- +
- + if ((extras_eh & regbit) == 0)
- + {
- + extras_eh |= regbit;
- + savesize_eh += UNITS_PER_WORD * 2;
- + FP_SP_offset += UNITS_PER_WORD * 2;
- + }
- + }
- + }
- + }
- +
- + if (frame_pointer_needed || non_leaf)
- + {
- + savesize_gp += UNITS_PER_WORD * 2, FP_SP_offset += UNITS_PER_WORD * 2;
- +
- + if (non_leaf)
- + extras_gp |= REGNO_BIT (RETURN_POINTER_REGNUM);
- +
- + if (frame_pointer_needed)
- + extras_gp |= REGNO_BIT (TEMP_D0FRT_REGNUM);
- + }
- + else if (df_regs_ever_live_p (RETURN_POINTER_REGNUM))
- + {
- + extras_gp |= REGNO_BIT (RETURN_POINTER_REGNUM);
- +
- + /* Have to do at least one pop */
- + savesize_gp += UNITS_PER_WORD * 2;
- + }
- +
- + loads_pic_register = METAG_CURRENT_FUNCTION_LOADS_PIC_REGISTER ();
- + if (loads_pic_register)
- + pic_save_size += UNITS_PER_WORD * 2;
- +
- + cfun->machine->frame_pointer_needed = frame_pointer_needed;
- + cfun->machine->non_leaf = non_leaf;
- + cfun->machine->savesize_gp = savesize_gp;
- + cfun->machine->savesize_eh = savesize_eh;
- + cfun->machine->FP_SP_offset = FP_SP_offset + pic_save_size;
- + cfun->machine->pic_save_size = pic_save_size;
- + cfun->machine->out_local_size = out_local_size;
- + cfun->machine->calls_eh_return = current_function_calls_eh_return;
- + cfun->machine->extras_gp = extras_gp;
- + cfun->machine->extras_eh = extras_eh;
- + cfun->machine->uses_pic_offset_table = current_function_uses_pic_offset_table;
- + cfun->machine->loads_pic_register = loads_pic_register;
- + cfun->machine->ech_ctx_required = (ech_ctx != 0);
- + cfun->machine->arg_adjust_delta = 0;
- + cfun->machine->frame_adjust_delta = 0;
- + cfun->machine->can_use_short_branch = false;
- + cfun->machine->valid = true;
- +
- + switch (from)
- + {
- + case ARG_POINTER_REGNUM:
- + switch (to)
- + {
- + case STACK_POINTER_REGNUM:
- + delta = -savesize_gp - savesize_eh - pic_save_size - out_local_size;
- + if (cfun->machine->anonymous_args)
- + delta += ALIGN_ON_STACK_BOUNDARY (cfun->machine->anonymous_args_size);
- + cfun->machine->arg_adjust_delta = delta;
- + return delta;
- + case HARD_FRAME_POINTER_REGNUM:
- + delta = -pretend_size;
- + if (cfun->machine->anonymous_args)
- + delta += ALIGN_ON_STACK_BOUNDARY (cfun->machine->anonymous_args_size);
- + cfun->machine->arg_adjust_delta = delta;
- + return delta;
- + default:
- + gcc_unreachable ();
- + }
- + break;
- + case FRAME_POINTER_REGNUM:
- + switch (to)
- + {
- + case STACK_POINTER_REGNUM:
- + delta = -out_local_size;
- + cfun->machine->frame_adjust_delta = delta;
- + return delta;
- + case HARD_FRAME_POINTER_REGNUM:
- + delta = -pretend_size + savesize_gp + savesize_eh + pic_save_size;
- + cfun->machine->frame_adjust_delta = delta;
- + return delta;
- + default:
- + gcc_unreachable ();
- + break;
- + }
- + break;
- + default:
- + gcc_unreachable ();
- + break;
- + }
- +
- + gcc_unreachable ();
- +}
- +
- +typedef struct hwtrace_fn
- +{
- + const char * name;
- + int onoff;
- + struct hwtrace_fn *next;
- +} hwtrace_fn;
- +
- +/* A simple linked list records info about "#pragma hwtrace_function (name, 0|1) */
- +static hwtrace_fn *hwtrace_function_list = NULL;
- +/* records default if #pragma hwtrace_function (*, 0|1) */
- +static int hwtrace_function_default = -1; /* < 0 none, 0 off > 1 on */
- +
- +static bool
- +hwtrace_function_enabled (tree function_decl)
- +{
- + if (function_decl)
- + {
- + const char * fnname = IDENTIFIER_POINTER (DECL_NAME (function_decl));
- + hwtrace_fn *next = hwtrace_function_list;
- +
- + while (next != NULL)
- + {
- + if (strcmp (next->name, fnname) == 0)
- + return next->onoff;
- +
- + next = next->next;
- + }
- +
- + if (hwtrace_function_default < 0)
- + return true;
- +
- + if (hwtrace_function_default > 0)
- + return true;
- +
- + return false;
- + }
- +
- + return true;
- +}
- +
- +static struct machine_function *
- +metag_init_machine_status (void)
- +{
- + struct machine_function *machine
- + = (machine_function *) ggc_alloc_cleared (sizeof (*machine));
- + bool enabled = hwtrace_function_enabled (current_function_decl);
- +
- + machine->valid = false;
- + machine->hwtrace = TARGET_HWTRACE && enabled;
- + machine->hwtrace_leaf = TARGET_HWTRACE_LEAF && enabled;
- + machine->hwtrace_retpc = TARGET_HWTRACE_RETPC && enabled;
- +
- + machine->cond_return_state = METAG_COND_RETURN_NONE;
- + return machine;
- +}
- +
- +void
- +metag_init_expanders (void)
- +{
- + init_machine_status = metag_init_machine_status;
- +}
- +
- +bool
- +metag_legitimate_address_p (rtx addr, enum machine_mode mode, bool strict)
- +{
- + rtx tmp;
- +
- + if (METAG_FLAG_PIC && SYMBOLIC_CONST (addr))
- + return metag_legitimate_pic_address_disp_p (addr);
- +
- + if (SYMBOL_REF_P (addr) && METAG_SYMBOL_FLAG_DIRECT_P (addr))
- + return true;
- +
- + tmp = addr;
- +
- + if (SUBREG_P (tmp)
- + && (GET_MODE_SIZE (GET_MODE (tmp))
- + < GET_MODE_SIZE (GET_MODE (SUBREG_REG (tmp)))))
- + tmp = SUBREG_REG (tmp);
- +
- + if (METAG_LEGITIMATE_REG_P (tmp, strict))
- + return true;
- +
- + if (METAG_LEGITIMATE_PRE_INCDEC_P (addr, mode, strict))
- + return true;
- +
- + if (METAG_LEGITIMATE_POST_INCDEC_P (addr, mode, strict))
- + return true;
- +
- + if (METAG_LEGITIMATE_PRE_MODIFY_P (addr, mode, strict))
- + return true;
- +
- + if (METAG_LEGITIMATE_POST_MODIFY_P (addr, mode, strict))
- + return true;
- +
- + if (GET_CODE (addr) == PLUS)
- + {
- + rtx op0 = XEXP (addr, 0);
- + rtx op1 = XEXP (addr, 1);
- +
- + if (SUBREG_P (op0)
- + && (GET_MODE_SIZE (GET_MODE (op0))
- + < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))
- + op0 = SUBREG_REG (op0);
- +
- + if (METAG_LEGITIMATE_REG_P (op0, strict))
- + {
- + if (REG_P (op1)
- + && METAG_LEGITIMATE_TWIN_P (op0, op1, mode, strict))
- + return true;
- +
- + if (CONST_INT_P (op1)
- + && METAG_LEGITIMATE_OFF_P (op0, op1, mode, strict))
- + return true;
- + }
- +
- + if (METAG_FLAG_PIC && op0 == pic_offset_table_rtx)
- + return metag_legitimate_pic_address_disp_p (op1);
- + }
- +
- + if (0 && GET_CODE (addr) == PLUS)
- + {
- + rtx op0 = XEXP (addr, 0);
- + rtx op1 = XEXP (addr, 1);
- +
- + if (GET_CODE (op0) == PLUS
- + && GET_CODE (op1) == CONST_INT)
- + {
- + rtx op3 = XEXP (op0, 0);
- + rtx op4 = XEXP (op0, 1);
- +
- + if (CONST_INT_P (op4))
- + {
- + if (SUBREG_P (op3)
- + && (GET_MODE_SIZE (GET_MODE (op3))
- + < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op3)))))
- + op3 = SUBREG_REG (op3);
- +
- + op4 = GEN_INT (INTVAL (op1) + INTVAL (op4));
- + if (METAG_LEGITIMATE_REG_P (op3, strict)
- + && METAG_LEGITIMATE_OFF_P (op3, op4, mode, strict))
- + return true;
- + }
- + }
- + }
- +
- + return false;
- +}
- +
- +bool
- +metag_legitimate_regno_p (unsigned int regno, bool strict)
- +{
- + if (strict)
- + {
- + if (IS_PSEUDO_REGNO (regno) && reg_renumber != NULL)
- + regno = reg_renumber [regno];
- +
- + return regno <= FRAME_POINTER_REGNUM || regno == ARG_POINTER_REGNUM;
- + }
- +
- + return regno != INVALID_REGNUM;
- +}
- +
- +bool
- +metag_legitimate_reg_p (rtx reg, bool strict)
- +{
- + return REG_P (reg) ? metag_legitimate_regno_p (REGNO (reg), strict)
- + : false;
- +}
- +
- +/* Return true iff BASE and OFF are valid for Reg + Reg addressing.
- + If STRICT is true then we need to be strict w.r.t pseduo registers
- + */
- +bool
- +metag_regs_ok_for_base_offset_p (rtx base_reg, rtx off_reg, bool strict)
- +{
- + if (!METAG_LEGITIMATE_REG_P (base_reg, strict))
- + return false;
- +
- + if (!METAG_LEGITIMATE_REG_P (off_reg, strict))
- + return false;
- +
- + return metag_regs_same_regclass_p (base_reg, off_reg, strict);
- +}
- +
- +bool
- +metag_reg_ok_for_base_p (rtx reg ATTRIBUTE_UNUSED, bool strict)
- +{
- + return strict ? STRICT_REG_OK_FOR_BASE_P (reg)
- + : NONSTRICT_REG_OK_FOR_BASE_P (reg);
- +}
- +
- +bool
- +metag_reg_ok_for_offset_p (rtx reg, bool strict)
- +{
- + return strict ? STRICT_REG_OK_FOR_OFFSET_P (reg)
- + : NONSTRICT_REG_OK_FOR_OFFSET_P (reg);
- +}
- +
- +bool
- +metag_reg_ok_for_index_p (rtx reg ATTRIBUTE_UNUSED, bool strict)
- +{
- + return strict ? STRICT_REG_OK_FOR_INDEX_P (reg)
- + : NONSTRICT_REG_OK_FOR_INDEX_P (reg);
- +}
- +
- +bool
- +metag_legitimate_post_incdec_p (rtx addr, enum machine_mode mode ATTRIBUTE_UNUSED, bool strict)
- +{
- + return (GET_CODE (addr) == POST_INC || GET_CODE (addr) == POST_DEC)
- + && METAG_LEGITIMATE_REG_P (XEXP (addr, 0), strict)
- + && !METAG_ELIMINABLE_REG_P (XEXP (addr, 0));
- +}
- +
- +bool
- +metag_legitimate_pre_incdec_p (rtx addr, enum machine_mode mode ATTRIBUTE_UNUSED, bool strict)
- +{
- + return (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
- + && METAG_LEGITIMATE_REG_P (XEXP (addr, 0), strict)
- + && !METAG_ELIMINABLE_REG_P (XEXP (addr, 0));
- +}
- +
- +bool
- +metag_legitimate_off_p (rtx base, rtx off, enum machine_mode mode, bool strict ATTRIBUTE_UNUSED)
- +{
- + if (CONST_INT_P (off))
- + {
- + HOST_WIDE_INT value = INTVAL (off);
- + unsigned int modesize = GET_MODE_SIZE (mode);
- +
- + if ((value & (modesize - 1)) == 0)
- + {
- + unsigned int regno = REGNO (base);
- + HOST_WIDE_INT limit;
- +
- + if (reg_renumber != NULL && IS_PSEUDO_REGNO (regno))
- + regno = reg_renumber[regno];
- +
- + if (metag_regno12bit_p (regno)
- + && (!metag_fpu_resources
- + || (GET_MODE_CLASS (mode) != MODE_FLOAT)))
- + limit = 2048;
- + else if (cfun && regno == ARG_POINTER_REGNUM)
- + value += cfun->machine->arg_adjust_delta, limit = 2048;
- + else if (cfun && regno == FRAME_POINTER_REGNUM)
- + {
- + if (reload_in_progress)
- + return true;
- +
- + value += cfun->machine->frame_adjust_delta, limit = 2048;
- + }
- + else if (!strict && !reload_in_progress && !reload_completed
- + && (regno == ARG_POINTER_REGNUM
- + || regno == FRAME_POINTER_REGNUM))
- + limit = 2048;
- + else if (!strict && !reload_in_progress && !reload_completed && IS_PSEUDO_REGNO (regno)
- + && (!metag_fpu_resources
- + || (GET_MODE_CLASS (mode) != MODE_FLOAT)))
- + limit = 2048;
- + else
- + limit = 32;
- +
- + limit *= modesize;
- +
- + return (-limit <= value && value < limit);
- + }
- + }
- +
- + return false;
- +}
- +
- +bool
- +metag_legitimate_twin_p (rtx base, rtx off, enum machine_mode mode ATTRIBUTE_UNUSED, bool strict)
- +{
- + return METAG_REGS_OK_FOR_BASE_OFFSET_P (base, off, strict);
- +}
- +
- +bool
- +metag_frame_related_rtx (rtx op)
- +{
- + return (REG_P (op)
- + && (op == frame_pointer_rtx
- + || op == arg_pointer_rtx
- + || op == virtual_incoming_args_rtx
- + || op == virtual_stack_vars_rtx
- + || op == virtual_stack_dynamic_rtx
- + || op == virtual_outgoing_args_rtx
- + || op == virtual_cfa_rtx
- + || REGNO (op) == FRAME_POINTER_REGNUM
- + || REGNO (op) == ARG_POINTER_REGNUM));
- +}
- +
- +
- +/* Returns 1 if OP contains a symbol reference */
- +
- +bool
- +metag_symbolic_reference_mentioned_p (rtx op)
- +{
- + const char *fmt;
- + int i;
- +
- + if (SYMBOL_REF_P (op) || LABEL_REF_P (op))
- + return true;
- +
- + fmt = GET_RTX_FORMAT (GET_CODE (op));
- + for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
- + {
- + if (fmt[i] == 'E')
- + {
- + int j;
- +
- + for (j = XVECLEN (op, i) - 1; j >= 0; j--)
- + if (metag_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
- + return true;
- + }
- + else if (fmt[i] == 'e' && metag_symbolic_reference_mentioned_p (XEXP (op, i)))
- + return true;
- + }
- +
- + return false;
- +}
- +
- +bool
- +metag_legitimate_pic_address_disp_p (rtx disp)
- +{
- + if (GET_CODE (disp) != CONST)
- + return false;
- +
- + disp = XEXP (disp, 0);
- +
- + if (GET_CODE (disp) == PLUS)
- + {
- + if (!CONST_INT_P (XEXP (disp, 1)))
- + return false;
- +
- + disp = XEXP (disp, 0);
- + }
- +
- + if (GET_CODE (disp) != UNSPEC
- + || XVECLEN (disp, 0) != 1)
- + return false;
- +
- + /* Must be @GOT but not @GOTOFF */
- + if (XINT (disp, 1) != UNSPEC_GOT)
- + return false;
- +
- + if (!SYMBOL_REF_P (XVECEXP (disp, 0, 0))
- + && !LABEL_REF_P (XVECEXP (disp, 0, 0)))
- + return false;
- +
- + return true;
- +}
- +
- +/* Try machine-dependent ways of modifying an illegitimate address
- + to be legitimate. If we find one, return the new, valid address.
- + This macro is used in only one place: `memory_address' in explow.c.
- +
- + OLDX is the address as it was before break_out_memory_refs was called.
- + In some cases it is useful to look at this to decide what needs to be done.
- +
- + MODE and WIN are passed so that this macro can use
- + GO_IF_LEGITIMATE_ADDRESS.
- +
- + It is always safe for this macro to do nothing. It exists to recognize
- + opportunities to optimize the output.
- +*/
- +
- +rtx
- +metag_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
- + enum machine_mode mode ATTRIBUTE_UNUSED)
- +{
- +
- + /* We currently only have support for thread local storage (TLS)
- + under META Linux. There is no TLS support for the embedded
- + toolchain */
- +
- + if (tls_symbolic_operand_p (x))
- + return metag_bfd_legitimize_tls_address (x);
- +
- + if (METAG_FLAG_PIC)
- + return SYMBOLIC_CONST (x) ? metag_legitimize_pic_address (x, 0) : x;
- +
- + return x;
- +}
- +
- +/* This function has been created by using the output template from the movsi
- + insn in metag.md */
- +
- +void
- +metag_emit_move_sequence (rtx operands[],
- + enum machine_mode mode ATTRIBUTE_UNUSED)
- +{
- +
- + if (metag_bfd_tls_referenced_p (operands[1]))
- + {
- + rtx tmp = operands[1];
- + rtx addend = NULL;
- +
- + /* All TLS symbols should be wrapped in an UNSPEC prior to reload (the
- + check is performed by metag_bfd_tls_referenced_p) if they are still
- + symbols raise an error */
- + if (reload_in_progress)
- + gcc_unreachable ();
- + else
- + {
- + /* Catch and fix the case where GCC is trying to offset a TLS symbol */
- + if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
- + {
- + addend = XEXP (XEXP (tmp, 0), 1);
- + tmp = XEXP (XEXP (tmp, 0), 0);
- + }
- +
- + gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
- + gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
- +
- + tmp = metag_bfd_legitimize_tls_address (tmp);
- +
- + if (addend)
- + {
- + tmp = gen_rtx_PLUS (mode, tmp, addend);
- + tmp = force_operand (tmp, operands[0]);
- + }
- +
- + operands[1] = tmp;
- +
- + if (MEM_P (operands[0]))
- + {
- + /* All except mem = const, mem = mem, or mem = addr can be done quickly */
- + operands[1] = force_reg (SImode, operands[1]);
- + }
- + }
- + }
- + else if (METAG_FLAG_PIC && SYMBOLIC_CONST (operands[1]))
- + {
- + if (MEM_P (operands[0]) && SYMBOLIC_CONST (operands[1]))
- + operands[1] = force_reg (Pmode, operands[1]);
- + else
- + {
- + rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
- +
- + operands[1] = metag_legitimize_pic_address (operands[1], temp);
- + }
- + }
- + else if (MEM_P (operands[0]))
- + {
- + /* All except mem = const, mem = mem, or mem = addr can be done quickly */
- + operands[1] = force_reg (SImode, operands[1]);
- + }
- +
- + if (REG_P (operands[0])
- + && REGNO (operands[0]) == TXRPT_REGNUM)
- + {
- + if (CONST_INT_P (operands[1])
- + && !(METAG_CONST_OK_FOR_LETTERS_KPIJ (operands[1])))
- + {
- + operands[1] = force_reg (SImode, operands[1]);
- + }
- + }
- +}
- +
- +/* Return a legitimate reference for ORIG (an address) using the
- + register REG. If REG is 0, a new pseudo is generated.
- +
- + There are two types of references that must be handled:
- +
- + 1. Global data references must load the address from the GOT, via
- + the PIC reg. An insn is emitted to do this load, and the reg is
- + returned.
- +
- + 2. Static data references, constant pool addresses, and code labels
- + compute the address as an offset from the GOT, whose base is in
- + the PIC reg. Static data objects have SYMBOL_REF_FLAG set to
- + differentiate them from global data objects. The returned
- + address is the PIC reg + an unspec constant.
- +*/
- +
- +rtx
- +metag_legitimize_pic_address (rtx orig, rtx reg)
- +{
- + rtx addr = orig;
- + rtx new = orig;
- + rtx base;
- +
- + if (LABEL_REF_P (addr)
- + || (SYMBOL_REF_P (addr)
- + && (CONSTANT_POOL_ADDRESS_P (addr)
- + || METAG_SYMBOL_FLAG_DIRECT_P (addr)
- + || SYMBOL_REF_LOCAL_P (addr))))
- + {
- + /* This symbol may be referenced via a displacement from the PIC
- + base address (@GOTOFF). */
- +
- + /* Only mark this function as needing pic if we are not being called
- + as part of a cost-estimation process */
- + if (!ir_type ())
- + current_function_uses_pic_offset_table = 1;
- +
- + new = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
- + new = gen_rtx_CONST (VOIDmode, new);
- + new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
- +
- + if (reg != 0)
- + {
- + emit_move_insn (reg, new);
- + new = reg;
- + }
- + }
- + else if (SYMBOL_REF_P (addr))
- + {
- + /* This symbol must be referenced via a load from the
- + Global Offset Table (@GOT). */
- +
- + /* Only mark this function as needing pic if we are not being called
- + as part of a cost-estimation process */
- + if (!ir_type ())
- + current_function_uses_pic_offset_table = 1;
- +
- + new = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, addr), UNSPEC_GOT);
- + new = gen_rtx_CONST (VOIDmode, new);
- + new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
- + new = gen_rtx_MEM (Pmode, new);
- +
- + if (reg == 0)
- + reg = gen_reg_rtx (Pmode);
- +
- + emit_move_insn (reg, new);
- + new = reg;
- + }
- + else
- + {
- + if (GET_CODE (addr) == CONST)
- + {
- + addr = XEXP (addr, 0);
- + if (GET_CODE (addr) == UNSPEC)
- + {
- + /* Check that the unspec is one of the ones we generate? */
- + }
- + else if (GET_CODE (addr) != PLUS)
- + abort();
- + }
- +
- + if (GET_CODE (addr) == PLUS)
- + {
- + rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
- +
- + /* Check first to see if this is a constant offset from a @GOTOFF
- + symbol reference. */
- + if ((LABEL_REF_P (op0)
- + || (SYMBOL_REF_P (op0)
- + && (CONSTANT_POOL_ADDRESS_P (op0)
- + || METAG_SYMBOL_FLAG_DIRECT_P (op0))))
- + && CONST_INT_P (op1))
- + {
- + /* Only mark this function as needing pic if we are not being called
- + as part of a cost-estimation process */
- + if (!ir_type ())
- + current_function_uses_pic_offset_table = 1;
- +
- + new = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, op0), UNSPEC_GOTOFF);
- + new = gen_rtx_PLUS (Pmode, new, op1);
- + new = gen_rtx_CONST (VOIDmode, new);
- + new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
- +
- + if (reg != 0)
- + {
- + emit_move_insn (reg, new);
- + new = reg;
- + }
- + }
- + else
- + {
- + base = metag_legitimize_pic_address (XEXP (addr, 0), reg);
- + new = metag_legitimize_pic_address (XEXP (addr, 1),
- + base == reg ? NULL_RTX : reg);
- +
- + if (CONST_INT_P (new))
- + new = plus_constant (base, INTVAL (new));
- + else
- + {
- + if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
- + {
- + base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
- + new = XEXP (new, 1);
- + }
- +
- + new = gen_rtx_PLUS (Pmode, base, new);
- + }
- + }
- + }
- + }
- +
- + return new;
- +}
- +
- +/* Compute a (partial) cost for rtx X. Return true if the complete
- + cost has been computed, and false if subexpressions should be
- + scanned. In either case, *TOTAL contains the cost result. */
- +
- +bool
- +metag_rtx_costs (rtx x, int code, int outer_code, int *total)
- +{
- + switch (code)
- + {
- + case CONST_INT:
- + if (satisfies_constraint_K (x))
- + *total = (outer_code == SET ? COSTS_N_INSNS (1) :
- + outer_code == PLUS ? 0 :
- + outer_code == MINUS ? 0 :
- + outer_code == AND ? 0 :
- + outer_code == IOR ? 0 :
- + outer_code == XOR ? 0 :
- + outer_code == COMPARE ? 0 :
- + COSTS_N_INSNS (1));
- + else if (satisfies_constraint_P (x))
- + *total = (outer_code == SET ? COSTS_N_INSNS (1) :
- + outer_code == PLUS ? 0 :
- + outer_code == MINUS ? 0 :
- + outer_code == AND ? 0 :
- + outer_code == IOR ? 0 :
- + outer_code == XOR ? 0 :
- + outer_code == COMPARE ? 0 :
- + COSTS_N_INSNS (1));
- + else if ((INTVAL (x) & 0xffff) == 0xffff
- + && (outer_code == AND || outer_code == IOR || outer_code == XOR))
- + *total = COSTS_N_INSNS (1);
- + else if ((INTVAL (x) & 0xffff0000) == 0xffff0000
- + && (outer_code == AND || outer_code == IOR || outer_code == XOR))
- + *total = COSTS_N_INSNS (1);
- + else if (INTVAL (x) >= -32768 && INTVAL (x) <= 65535)
- + *total = COSTS_N_INSNS (1);
- + else if ((INTVAL (x) & 0xffff) == 0)
- + *total = COSTS_N_INSNS (2);
- + else
- + *total = COSTS_N_INSNS (5);
- + break;
- + case CONST:
- + if (outer_code == MEM)
- + {
- + *total = COSTS_N_INSNS (1);
- + return true;
- + }
- + *total = COSTS_N_INSNS (2);
- + break;
- + case LABEL_REF:
- + case SYMBOL_REF:
- + *total = COSTS_N_INSNS (6);
- + break;
- + case CONST_DOUBLE:
- + *total = COSTS_N_INSNS (10);
- + break;
- + case MULT:
- + *total = COSTS_N_INSNS (2);
- + break;
- + case DIV:
- + case UDIV:
- + case MOD:
- + case UMOD:
- + *total = COSTS_N_INSNS (50);
- + break;
- + case PLUS:
- + case MINUS:
- + if (GET_MODE (x) == SImode)
- + {
- + rtx exp = XEXP (x, 0);
- + unsigned int reg0 = REG_P (XEXP (x, 0)) ? REGNO (XEXP (x, 0)) : INVALID_REGNUM;
- + unsigned int reg1 = REG_P (XEXP (x, 1)) ? REGNO (XEXP (x, 1)) : INVALID_REGNUM;
- +
- + if (reg_renumber != NULL && IS_PSEUDO_REGNO (reg0))
- + reg0 = reg_renumber[reg0];
- +
- + if (reg_renumber != NULL && IS_PSEUDO_REGNO (reg1))
- + reg1 = reg_renumber[reg1];
- +
- + if (IS_HARD_OR_VIRT_REGNO (reg0)
- + && IS_HARD_OR_VIRT_REGNO (reg1)
- + && METAG_REGNO_REG_CLASS (reg0) != METAG_REGNO_REG_CLASS (reg1))
- + {
- + /* Cannot really add/sub registers in different units */
- + *total = COSTS_N_INSNS (50);
- + }
- + else if (exp != frame_pointer_rtx
- + && exp != stack_pointer_rtx
- + && exp != arg_pointer_rtx)
- + *total = COSTS_N_INSNS (1);
- + else
- + *total = COSTS_N_INSNS (2);
- + }
- + else
- + *total = COSTS_N_INSNS (4);
- +
- + break;
- + case COMPARE:
- + *total = COSTS_N_INSNS (1);
- + break;
- + case MEM:
- + if (outer_code == SIGN_EXTEND)
- + *total = COSTS_N_INSNS (2);
- + else
- + *total = COSTS_N_INSNS (1);
- + break;
- + case SIGN_EXTEND:
- + *total = COSTS_N_INSNS (1);
- + break;
- + default:
- + *total = COSTS_N_INSNS (1);
- + break;
- + }
- +
- + return false;
- +}
- +
- +int
- +metag_sched_adjust_cost (rtx insn, rtx link,
- + rtx dep_insn, int cost)
- +{
- + switch (REG_NOTE_KIND (link))
- + {
- + case REG_DEP_ANTI:
- + case REG_DEP_OUTPUT:
- + return 0;
- + case REG_DEP_TRUE:
- + if (recog_memoized (insn) >= 0 && recog_memoized (dep_insn) >= 0)
- + {
- + enum attr_type type_attr = get_attr_type (dep_insn);
- + enum attr_memaccess memaccess_attr = get_attr_memaccess (dep_insn);
- +
- + /* Match the twox|threex|fourx|fivex loads */
- + if ((type_attr == TYPE_TWOX || type_attr == TYPE_THREEX
- + || type_attr == TYPE_FOURX || type_attr == TYPE_FIVEX)
- + && memaccess_attr == MEMACCESS_LOAD)
- + {
- + /* If the dependency is based on either of the last 2 registers
- + * loaded, the latency increases. */
- + cost += metag_consumer_stalls_from_load_multi (dep_insn, insn);
- + }
- +
- + /* If there is an o2rhint then the insn may have an o2r operand which
- + * may stall. */
- + switch (get_attr_o2rhint (insn))
- + {
- + case O2RHINT_NONE:
- + break;
- + case O2RHINT_OP2OP1:
- + /* insn has an o2r operand if units of operands 2 and 1 differ. */
- + if (metag_consumer_is_o2r (dep_insn, insn, 2, 1))
- + return cost + 1;
- +
- + break;
- + case O2RHINT_OP1OP0:
- + /* insn has an o2r operand if units of operands 1 and 0 differ. */
- + if (metag_consumer_is_o2r (dep_insn, insn, 1, 0))
- + return cost + 1;
- +
- + break;
- + default:
- + /* Bad o2rhint, missing a case for the hint. */
- + gcc_unreachable ();
- + }
- +
- + break;
- + }
- + break;
- + default:
- + break;
- + }
- +
- + return cost;
- +}
- +
- +int
- +metag_address_cost (rtx x)
- +{
- + switch (GET_CODE (x))
- + {
- + case REG:
- + return 0;
- + case LABEL_REF:
- + case SYMBOL_REF:
- + case CONST:
- + case MEM:
- + return 10;
- + case PRE_INC:
- + case POST_INC:
- + case PRE_DEC:
- + case POST_DEC:
- + case PRE_MODIFY:
- + case POST_MODIFY:
- + return 0;
- + case PLUS:
- + if (REG_P (XEXP (x, 0))
- + && (REG_P (XEXP (x, 1)) || CONST_INT_P (XEXP (x, 1))))
- + return 2;
- + break;
- + default:
- + break;
- + }
- +
- + return 6;
- +}
- +
- +#define add_builtin_function(NAME, TYPE, CODE, CLASS, LIBNAME, ATTR) \
- + lang_hooks.builtin_function (NAME, TYPE, CODE, CLASS, LIBNAME, ATTR)
- +
- +void
- +metag_init_builtins(void)
- +{
- + tree nothrow = tree_cons (get_identifier ("nothrow"), NULL, NULL);
- +#if 0
- + tree const_throw = tree_cons (get_identifier ("const"), NULL, nothrow);
- +#endif
- + tree endlink = void_list_node;
- + tree ftdcache_preload
- + = build_function_type (ptr_type_node,
- + tree_cons (NULL_TREE, ptr_type_node,
- + endlink));
- +
- + tree ftdcache_flush
- + = build_function_type (void_type_node,
- + tree_cons (NULL_TREE, ptr_type_node,
- + endlink));
- +
- + tree ftdcache_refresh
- + = build_function_type (ptr_type_node,
- + tree_cons (NULL_TREE, ptr_type_node,
- + endlink));
- +
- + tree ftmeta2_cacherd
- + = build_function_type (unsigned_intSI_type_node,
- + tree_cons (NULL_TREE, ptr_type_node,
- + endlink));
- +
- + tree ftmeta2_cacherl
- + = build_function_type (unsigned_intDI_type_node,
- + tree_cons (NULL_TREE, ptr_type_node,
- + endlink));
- +
- + tree ftmeta2_cachewd
- + = build_function_type (void_type_node,
- + tree_cons (NULL_TREE, ptr_type_node,
- + tree_cons (NULL_TREE, unsigned_intSI_type_node,
- + endlink)));
- +
- + tree ftmeta2_cachewl
- + = build_function_type (void_type_node,
- + tree_cons (NULL_TREE, ptr_type_node,
- + tree_cons (NULL_TREE, unsigned_intDI_type_node,
- + endlink)));
- +
- + tree ftmetag_bswap
- + = build_function_type (intSI_type_node,
- + tree_cons (NULL_TREE, intSI_type_node,
- + endlink));
- +
- + tree ftmetag_bswaps
- + = build_function_type (intHI_type_node,
- + tree_cons (NULL_TREE, intHI_type_node,
- + endlink));
- +
- + tree ftmetag_bswapll
- + = build_function_type (intDI_type_node,
- + tree_cons (NULL_TREE, intDI_type_node,
- + endlink));
- +
- + tree ftmetag_wswap
- + = build_function_type (intSI_type_node,
- + tree_cons (NULL_TREE, intSI_type_node,
- + endlink));
- +
- + tree ftmetag_wswapll
- + = build_function_type (intDI_type_node,
- + tree_cons (NULL_TREE, intDI_type_node,
- + endlink));
- +
- + tree ftmetag_dswapll
- + = build_function_type (intDI_type_node,
- + tree_cons (NULL_TREE, intDI_type_node,
- + endlink));
- +
- +
- +
- + add_builtin_function ("__builtin_dcache_preload", ftdcache_preload,
- + METAG_BUILTIN_DCACHE_PRELOAD,
- + BUILT_IN_MD,
- + NULL, nothrow);
- +
- + add_builtin_function ("__builtin_dcache_flush", ftdcache_flush,
- + METAG_BUILTIN_DCACHE_FLUSH,
- + BUILT_IN_MD,
- + NULL, nothrow);
- +
- + add_builtin_function ("__builtin_dcache_refresh",
- + ftdcache_refresh,
- + METAG_BUILTIN_DCACHE_REFRESH,
- + BUILT_IN_MD,
- + NULL, nothrow);
- +
- + add_builtin_function ("__builtin_meta2_cacherd",
- + ftmeta2_cacherd,
- + METAG_BUILTIN_META2_CACHERD,
- + BUILT_IN_MD,
- + NULL, nothrow);
- +
- + add_builtin_function ("__builtin_meta2_cacherl",
- + ftmeta2_cacherl,
- + METAG_BUILTIN_META2_CACHERL,
- + BUILT_IN_MD,
- + NULL, nothrow);
- +
- + add_builtin_function ("__builtin_meta2_cachewd",
- + ftmeta2_cachewd,
- + METAG_BUILTIN_META2_CACHEWD,
- + BUILT_IN_MD,
- + NULL, nothrow);
- +
- + add_builtin_function ("__builtin_meta2_cachewl",
- + ftmeta2_cachewl,
- + METAG_BUILTIN_META2_CACHEWL,
- + BUILT_IN_MD,
- + NULL, nothrow);
- +
- + add_builtin_function ("__builtin_metag_bswaps",
- + ftmetag_bswaps,
- + METAG_BUILTIN_METAG_BSWAPS,
- + BUILT_IN_MD,
- + NULL, nothrow);
- +
- + add_builtin_function ("__builtin_metag_bswap",
- + ftmetag_bswap,
- + METAG_BUILTIN_METAG_BSWAP,
- + BUILT_IN_MD,
- + NULL, nothrow);
- +
- + add_builtin_function ("__builtin_metag_bswapll",
- + ftmetag_bswapll,
- + METAG_BUILTIN_METAG_BSWAPLL,
- + BUILT_IN_MD,
- + NULL, nothrow);
- +
- + add_builtin_function ("__builtin_metag_wswap",
- + ftmetag_wswap,
- + METAG_BUILTIN_METAG_WSWAP,
- + BUILT_IN_MD,
- + NULL, nothrow);
- +
- + add_builtin_function ("__builtin_metag_wswapll",
- + ftmetag_wswapll,
- + METAG_BUILTIN_METAG_WSWAPLL,
- + BUILT_IN_MD,
- + NULL, nothrow);
- +
- + add_builtin_function ("__builtin_metag_dswapll",
- + ftmetag_dswapll,
- + METAG_BUILTIN_METAG_DSWAPLL,
- + BUILT_IN_MD,
- + NULL, nothrow);
- + /* Initialise the builtin functions for the operating system gcc
- + is targeting code for */
- + metag_init_builtins_per_os ();
- +
- +}
- +
- +/* Emit the optimal byte swap sequence for a 16 bit byte swap */
- +
- +static void
- +metag_emit_byte_swap16 (rtx out, rtx in)
- +{
- + rtx tmp = gen_reg_rtx (SImode);
- +
- + emit_insn (gen_andsi3 (out, in,
- + gen_int_mode (0x0000FFFF, SImode)));
- + emit_insn (gen_lshrsi3 (tmp, out, GEN_INT (BITS_PER_UNIT)));
- + emit_insn (gen_ashlsi3 (out, out, GEN_INT (BITS_PER_UNIT * 3)));
- + emit_insn (gen_ashrsi3 (out, out, GEN_INT (BITS_PER_UNIT * 2)));
- + emit_insn (gen_iorsi3 (out, out, tmp));
- +}
- +
- +/* Emit the optimal byte swap sequence for a 32 bit byte swap */
- +
- +static void
- +metag_emit_byte_swap32 (rtx out, rtx in)
- +{
- + rtx tmp = gen_reg_rtx (SImode);
- +
- + emit_insn (gen_rotsi2_16 (tmp, in));
- + emit_insn (gen_lshrsi3 (out, tmp, GEN_INT (8)));
- + emit_insn (gen_andsi3 (tmp, tmp,
- + gen_int_mode (0xFFFF00FF, SImode)));
- + emit_insn (gen_andsi3 (out, out,
- + gen_int_mode (0xFFFF00FF, SImode)));
- + emit_insn (gen_ashlsi3 (tmp, tmp, GEN_INT (8)));
- + emit_insn (gen_iorsi3 (out, out, tmp));
- +}
- +
- +/* Expand an expression EXP that calls a built-in function,
- + with result going to TARGET if that's convenient
- + (and in mode MODE if that's convenient).
- + SUBTARGET may be used as the target for computing one of EXP's operands.
- + IGNORE is nonzero if the value is to be ignored. */
- +
- +rtx
- +metag_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
- + rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
- + int ignore ATTRIBUTE_UNUSED)
- +{
- + tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
- + tree arglist = TREE_OPERAND (exp, 1);
- + int fcode = DECL_FUNCTION_CODE (fndecl);
- +
- + switch (fcode)
- + {
- + case METAG_BUILTIN_DCACHE_PRELOAD: /* void * __builtin_dcache_preload (void *) */
- + if ( TARGET_BUILTINS_METAC_1_1
- + || TARGET_BUILTINS_METAC_1_2
- + || TARGET_BUILTINS_METAC_2_1)
- + {
- + tree arg0 = TREE_VALUE (arglist);
- + rtx op0 = expand_normal (arg0);
- + enum machine_mode mode0 = insn_data[CODE_FOR_dcache_preload].operand[0].mode;
- + rtx pat;
- +
- + if (! (*insn_data[CODE_FOR_dcache_preload].operand[0].predicate)(op0, mode0))
- + op0 = copy_to_mode_reg (mode0, op0);
- +
- + pat = GEN_FCN (CODE_FOR_dcache_preload)(op0);
- +
- + if (!pat)
- + return NULL_RTX;
- + emit_insn (pat);
- + return op0;
- + }
- + else
- + error ("__builtin_dcache_preload not supported for metac %s", metag_cpu_string);
- + break;
- + case METAG_BUILTIN_DCACHE_FLUSH: /* void __builtin_dcache_flush (void *) */
- + if ( TARGET_BUILTINS_METAC_1_2
- + || TARGET_BUILTINS_METAC_2_1)
- + {
- + tree arg0 = TREE_VALUE (arglist);
- + rtx op0 = expand_normal (arg0);
- + rtx op1;
- + enum machine_mode mode0 = insn_data[CODE_FOR_dcache_flush].operand[0].mode;
- + enum machine_mode mode1 = insn_data[CODE_FOR_dcache_flush].operand[1].mode;
- + rtx pat;
- +
- + if (! (*insn_data[CODE_FOR_dcache_flush].operand[0].predicate)(op0, mode0))
- + op0 = copy_to_mode_reg (mode0, op0);
- +
- + op1 = gen_reg_rtx (mode1);
- +
- + pat = GEN_FCN (CODE_FOR_dcache_flush)(op0, op1);
- +
- + if (!pat)
- + return NULL_RTX;
- +
- + emit_move_insn (op1, const0_rtx);
- + emit_insn (pat);
- + return const1_rtx;
- + }
- + else
- + error ("__builtin_dcache_flush not supported for metac %s", metag_cpu_string);
- + break;
- + case METAG_BUILTIN_DCACHE_REFRESH: /* void * __builtin_dcache_refresh (void *) */
- + if ( TARGET_BUILTINS_METAC_1_1
- + || TARGET_BUILTINS_METAC_1_2
- + || TARGET_BUILTINS_METAC_2_1)
- + {
- + tree arg0 = TREE_VALUE (arglist);
- + rtx op0 = expand_normal (arg0);
- + rtx op1;
- + enum machine_mode mode0 = insn_data[CODE_FOR_dcache_refresh].operand[0].mode;
- + enum machine_mode mode1 = insn_data[CODE_FOR_dcache_refresh].operand[1].mode;
- + rtx pat;
- +
- + if (! (*insn_data[CODE_FOR_dcache_refresh].operand[0].predicate)(op0, mode0))
- + op0 = copy_to_mode_reg (mode0, op0);
- +
- + op1 = gen_reg_rtx (mode1);
- +
- + pat = GEN_FCN (CODE_FOR_dcache_refresh)(op0, op1);
- +
- + if (!pat)
- + return NULL_RTX;
- +
- + emit_move_insn (op1, const0_rtx);
- + emit_insn (pat);
- + return op0;
- + }
- + else
- + error ("__builtin_dcache_refresh not supported for metac %s", metag_cpu_string);
- + break;
- + case METAG_BUILTIN_META2_CACHERD: /* unsigned long __builtin_meta2_cacherd (void *) */
- + case METAG_BUILTIN_META2_CACHERL: /* unsigned long long __builtin_meta2_cacherl (void *) */
- + if (TARGET_BUILTINS_METAC_2_1)
- + {
- + tree arg0 = TREE_VALUE (arglist);
- + rtx op1 = expand_normal (arg0);
- + enum machine_mode tgtmode;
- + enum machine_mode mode1;
- + enum insn_code icode = CODE_FOR_meta2_cacherd;
- + rtx pat;
- +
- + if (fcode == METAG_BUILTIN_META2_CACHERL)
- + icode = CODE_FOR_meta2_cacherl;
- +
- + tgtmode = insn_data[icode].operand[0].mode;
- + mode1 = insn_data[icode].operand[1].mode;
- +
- + if (target == 0 || !insn_data[icode].operand[0].predicate (target, tgtmode))
- + target = gen_reg_rtx (tgtmode);
- +
- + if (! (*insn_data[icode].operand[1].predicate)(op1, mode1))
- + op1 = copy_to_mode_reg (mode1, op1);
- +
- + pat = GEN_FCN (icode)(target, op1);
- +
- + if (!pat)
- + return NULL_RTX;
- +
- + emit_insn (pat);
- + return target;
- + }
- + else
- + error ("__builtin_meta2_cacher[dl] not supported for metac %s", metag_cpu_string);
- + break;
- + case METAG_BUILTIN_META2_CACHEWD: /* void __builtin_meta2_cachewd (void *, unsigned lon) */
- + case METAG_BUILTIN_META2_CACHEWL: /* void __builtin_meta2_cachewl (void *, unsigned long long) */
- + if (TARGET_BUILTINS_METAC_2_1)
- + {
- + tree arg0 = TREE_VALUE (arglist);
- + tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
- + rtx op0 = expand_normal (arg0);
- + rtx op1 = expand_normal (arg1);
- +
- + enum machine_mode mode0;
- + enum machine_mode mode1;
- + enum insn_code icode = CODE_FOR_meta2_cachewd;
- + rtx pat;
- +
- + if (fcode == METAG_BUILTIN_META2_CACHEWL)
- + icode = CODE_FOR_meta2_cachewl;
- +
- + mode0 = insn_data[icode].operand[0].mode;
- + mode1 = insn_data[icode].operand[1].mode;
- +
- + if (! (*insn_data[icode].operand[0].predicate)(op0, mode0))
- + op0 = copy_to_mode_reg (mode0, op0);
- +
- + if (! (*insn_data[icode].operand[1].predicate)(op1, mode1))
- + op1 = copy_to_mode_reg (mode1, op1);
- +
- + pat = GEN_FCN (icode)(op0, op1);
- +
- + if (!pat)
- + return NULL_RTX;
- +
- + emit_insn (pat);
- + return const1_rtx;
- + }
- + else
- + error ("__builtin_meta2_cachew[dl] not supported for metac %s (or extension disabled)", metag_cpu_string);
- + break;
- + case METAG_BUILTIN_METAG_BSWAPS: /* short __builtin_metag_bswaps (short) */
- + case METAG_BUILTIN_METAG_BSWAP: /* int __builtin_metag_bswap (int) */
- + case METAG_BUILTIN_METAG_BSWAPLL: /* long long __builtin_metag_bswap (long long) */
- + if (!TARGET_BUILTINS_METAC_2_1 && metag_meta2_bex_enabled)
- + error ("The 'bex' extension is only available on a META 2.1 core");
- + else
- + {
- + tree arg0 = TREE_VALUE (arglist);
- + rtx op1 = expand_normal (arg0);
- +
- + enum machine_mode mode;
- +
- + if (fcode == METAG_BUILTIN_METAG_BSWAPS)
- + /* This looks like it should be HImode, but type promotion on the arguments causes
- + shorts to become ints so SImode actually needs to be used */
- + mode = SImode;
- + else if (fcode == METAG_BUILTIN_METAG_BSWAP)
- + mode = SImode;
- + else
- + mode = DImode;
- +
- + if (target == 0 || !metag_register_op (target, mode))
- + target = gen_reg_rtx (mode);
- +
- + if (!metag_register_op (op1, mode))
- + op1 = copy_to_mode_reg (mode, op1);
- +
- + if (metag_meta2_bex_enabled)
- + {
- + if (fcode == METAG_BUILTIN_METAG_BSWAPS)
- + {
- + emit_insn (gen_metag_bswap (target, op1));
- + emit_insn (gen_ashrsi3 (target, target, GEN_INT ((UNITS_PER_WORD / 2) * BITS_PER_UNIT)));
- + }
- + else if (fcode == METAG_BUILTIN_METAG_BSWAP)
- + emit_insn (gen_metag_bswap (target, op1));
- + else
- + emit_insn (gen_metag_bswapll (target, op1));
- + }
- + else
- + {
- + /* Generate the optimal byte swap sequence */
- + if (fcode == METAG_BUILTIN_METAG_BSWAPS)
- + metag_emit_byte_swap16 (target, op1);
- + else if (fcode == METAG_BUILTIN_METAG_BSWAP)
- + metag_emit_byte_swap32 (target, op1);
- + else
- + {
- + rtx target_lo = gen_rtx_SUBREG (SImode, target, 0);
- + rtx target_hi = gen_rtx_SUBREG (SImode, target, 4);
- + rtx op1_lo = gen_rtx_SUBREG (SImode, op1, 0);
- + rtx op1_hi = gen_rtx_SUBREG (SImode, op1, 4);
- +
- + metag_emit_byte_swap32 (target_lo, op1_hi);
- + metag_emit_byte_swap32 (target_hi, op1_lo);
- + }
- + }
- +
- + return target;
- + }
- + break;
- + case METAG_BUILTIN_METAG_WSWAP: /* int __builtin_metag_wswap (int) */
- + case METAG_BUILTIN_METAG_WSWAPLL: /* long long __builtin_metag_wswapll (long long) */
- + case METAG_BUILTIN_METAG_DSWAPLL: /* long long __builtin_metag_dswapll (long long) */
- + {
- +
- + tree arg0 = TREE_VALUE (arglist);
- + rtx op1 = expand_normal (arg0);
- +
- + enum machine_mode mode;
- +
- + if (fcode == METAG_BUILTIN_METAG_WSWAP)
- + mode = SImode;
- + else
- + mode = DImode;
- +
- + if (target == 0 || !metag_register_op (target, mode))
- + target = gen_reg_rtx (mode);
- +
- + if (!metag_register_op (op1, mode))
- + op1 = copy_to_mode_reg (mode, op1);
- +
- + if (fcode == METAG_BUILTIN_METAG_WSWAP)
- + {
- + emit_insn (gen_rotsi2_16 (target, op1));
- + }
- + else if (fcode == METAG_BUILTIN_METAG_WSWAPLL)
- + {
- + rtx target_lo = gen_rtx_SUBREG (SImode, target, 0);
- + rtx target_hi = gen_rtx_SUBREG (SImode, target, 4);
- + if (TARGET_DSP)
- + {
- + emit_insn (gen_parallel_rotsi2_16 (target, op1));
- + emit_insn (gen_swapsi (target_hi, target_lo));
- + }
- + else
- + {
- + rtx op1_lo = gen_rtx_SUBREG (SImode, op1, 0);
- + rtx op1_hi = gen_rtx_SUBREG (SImode, op1, 4);
- + emit_insn (gen_rotsi2_16 (target_lo, op1_lo));
- + emit_insn (gen_rotsi2_16 (target_hi, op1_hi));
- + emit_insn (gen_swapsi (target_hi, target_lo));
- + }
- + }
- + else if (fcode == METAG_BUILTIN_METAG_DSWAPLL)
- + {
- + rtx target_lo = gen_rtx_SUBREG (SImode, target, 0);
- + rtx target_hi = gen_rtx_SUBREG (SImode, target, 4);
- + emit_insn (gen_movdi (target, op1));
- + emit_insn (gen_swapsi (target_hi, target_lo));
- + }
- + return target;
- + }
- + break;
- + default:
- + break;
- + }
- +
- + /* Expand any operating system specific builtin functions */
- + return metag_expand_builtin_per_os (exp, target);
- +}
- +
- +static tree
- +metag_handle_model_decl_attribute (tree *node ATTRIBUTE_UNUSED,
- + tree name ATTRIBUTE_UNUSED,
- + tree args ATTRIBUTE_UNUSED,
- + int flags ATTRIBUTE_UNUSED,
- + bool *no_add_attrs ATTRIBUTE_UNUSED)
- +{
- + tree value = TREE_VALUE (args);
- +
- + if (strcmp (IDENTIFIER_POINTER (name), "model") == 0)
- + {
- + if (TREE_CODE (value) != STRING_CST)
- + {
- + warning (OPT_Wattributes,
- + "argument of %qs attribute is not a string constant",
- + IDENTIFIER_POINTER (name));
- + *no_add_attrs = true;
- + }
- + else if ( strcmp (TREE_STRING_POINTER (value), "small") != 0
- + && strcmp (TREE_STRING_POINTER (value), "large") != 0)
- + {
- + warning (OPT_Wattributes,
- + "argument %qs of %qs is not \"small\" or \"large\"",
- + TREE_STRING_POINTER (value), IDENTIFIER_POINTER (name));
- + *no_add_attrs = true;
- + }
- + }
- +
- + return NULL_TREE;
- +}
- +
- +tree
- +metag_merge_decl_attributes (tree decl1, tree decl2)
- +{
- + return merge_decl_attributes (decl1, decl2);
- +}
- +
- +tree
- +metag_merge_type_attributes (tree type1, tree type2)
- +{
- + return merge_type_attributes (type1, type2);
- +}
- +
- +int
- +metag_comp_type_attributes (tree type1, tree type2)
- +{
- + tree m1 = lookup_attribute ("model", TYPE_ATTRIBUTES (type1));
- + tree m2 = lookup_attribute ("model", TYPE_ATTRIBUTES (type2));
- +
- + if (m1 != NULL_TREE)
- + m1 = TREE_VALUE (m1);
- +
- + if (m2 != NULL_TREE)
- + m2 = TREE_VALUE (m2);
- +
- + if (m1 && m2 && TREE_CODE (m1) == STRING_CST && TREE_CODE (m2) == STRING_CST)
- + return strcmp (TREE_STRING_POINTER (m1), TREE_STRING_POINTER (m2)) == 0 ? 1 : 0;
- +
- + return 1;
- +}
- +
- +int
- +metag_letter_for_const (rtx value)
- +{
- + if (satisfies_constraint_L (value))
- + return 'L';
- + else if (satisfies_constraint_P (value))
- + return 'P';
- + else if (satisfies_constraint_K (value))
- + return 'K';
- + else if (satisfies_constraint_I (value))
- + return 'I';
- + else if (satisfies_constraint_J (value))
- + return 'J';
- + else if (satisfies_constraint_M (value))
- + return 'M';
- + else if (satisfies_constraint_N (value))
- + return 'N';
- + else
- + return 0;
- +}
- +
- +bool
- +metag_const_ok_for_letters_p (rtx value, const char letters[])
- +{
- + char c;
- +
- + while ((c = *letters++) != '\0')
- + {
- + switch (c)
- + {
- + case 'L':
- + if (satisfies_constraint_L (value))
- + return true;
- + break;
- + case 'P':
- + if (satisfies_constraint_P (value))
- + return true;
- + break;
- + case 'K':
- + if (satisfies_constraint_K (value))
- + return true;
- + break;
- + case 'I':
- + if (satisfies_constraint_I (value))
- + return true;
- + break;
- + case 'J':
- + if (satisfies_constraint_J (value))
- + return true;
- + break;
- + case 'M':
- + if (satisfies_constraint_M (value))
- + return true;
- + break;
- + case 'N':
- + if (satisfies_constraint_N (value))
- + return true;
- + break;
- + case 'O':
- + switch (*letters)
- + {
- + case '0':
- + letters++;
- + if (satisfies_constraint_O0 (value))
- + return true;
- + break;
- + case '1':
- + letters++;
- + if (satisfies_constraint_O1 (value))
- + return true;
- + break;
- + case '2':
- + letters++;
- + if (satisfies_constraint_O2 (value))
- + return true;
- + break;
- + case '3':
- + letters++;
- + if (satisfies_constraint_O3 (value))
- + return true;
- + break;
- + case '4':
- + letters++;
- + if (satisfies_constraint_O4 (value))
- + return true;
- + break;
- + case '5':
- + gcc_unreachable ();
- + break;
- + case '6':
- + gcc_unreachable ();
- + break;
- + case '7':
- + gcc_unreachable ();
- + break;
- + case '8':
- + letters++;
- + if (satisfies_constraint_O8 (value))
- + return true;
- + break;
- + case '9':
- + gcc_unreachable ();
- + break;
- + default:
- + break;
- + }
- + break;
- + default:
- + gcc_unreachable ();
- + }
- + }
- +
- + return false;
- +}
- +
- +void
- +metag_machine_dependent_reorg (void)
- +{
- + return;
- +}
- +
- +void
- +metag_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode ATTRIBUTE_UNUSED,
- + tree type, int *pretend_size,
- + int no_rtl ATTRIBUTE_UNUSED)
- +{
- + int narg = ROUND_ADVANCE_CUM (cum->narg, mode, type);
- +
- + cfun->machine->anonymous_args = true;
- +
- + if (narg < MAX_METAG_PARM_BYTES)
- + {
- + *pretend_size = MAX_METAG_PARM_BYTES - narg;
- + cfun->machine->anonymous_args_size = *pretend_size;
- + }
- +}
- +
- +bool
- +metag_function_ok_for_sibcall (tree fndecl, tree exp)
- +{
- + return (current_function_outgoing_args_size == 0
- + && !current_function_calls_alloca
- + && !current_function_stdarg
- + && current_function_pretend_args_size == 0
- + && (fndecl == NULL_TREE || metag_function_ok_for_sibcall_per_os (fndecl, exp)));
- +}
- +
- +#define PARM_BYTE_BOUNDARY (PARM_BOUNDARY / BITS_PER_UNIT)
- +
- +tree
- +metag_gimplify_va_arg_expr (tree valist, tree type,
- + tree *pre_p ATTRIBUTE_UNUSED,
- + tree *post_p ATTRIBUTE_UNUSED)
- +{
- + tree ptr;
- + tree valist_type = TREE_TYPE (valist);
- + tree t;
- + int size;
- + bool indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
- + HOST_WIDE_INT boundary;
- +
- + if (indirect)
- + type = build_pointer_type (type);
- +
- + ptr = build_pointer_type (type);
- +
- + boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
- +
- + if (boundary < (int)TYPE_ALIGN (type))
- + {
- + type = build_variant_type_copy (type);
- + TYPE_ALIGN (type) = boundary;
- + }
- +
- + size = int_size_in_bytes (type);
- +
- + boundary /= BITS_PER_UNIT;
- + if (boundary > PARM_BYTE_BOUNDARY && size > 0)
- + {
- + tree u;
- +
- + u = fold_convert (valist_type, size_int (size));
- + t = build2 (MINUS_EXPR, valist_type, valist, u);
- +
- + u = fold_convert (valist_type, size_int (-boundary));
- + t = build2 (BIT_AND_EXPR, valist_type, t, u);
- + }
- + else if (boundary == PARM_BYTE_BOUNDARY && size > 0)
- + {
- + tree u;
- +
- + u = fold_convert (valist_type, size_int (PARM_BYTE_BOUNDARY));
- + t = build2 (MINUS_EXPR, valist_type, valist, u);
- + }
- + else if (boundary == PARM_BYTE_BOUNDARY && size == 0)
- + t = valist;
- + else
- + gcc_unreachable ();
- +
- + t = build2 (MODIFY_EXPR, valist_type, valist, t);
- +
- + t = fold_convert (ptr, t);
- +
- + if (indirect)
- + t = build_va_arg_indirect_ref (t);
- +
- + return build_va_arg_indirect_ref (t);
- +}
- +
- +#undef PARM_BYTE_BOUNDARY
- +
- +/* True if MODE is valid for the target. By "valid", we mean able to
- + be manipulated in non-trivial ways. In particular, this means all
- + the arithmetic is supported.
- +
- + Currently, TImode is not valid
- + Thus, we return false when PRECISION is 2 * BITS_PER_WORD and
- + 2 * BITS_PER_WORD isn't equal LONG_LONG_TYPE_SIZE.
- +*/
- +
- +bool
- +metag_scalar_mode_supported_p (enum machine_mode mode)
- +{
- + int precision = GET_MODE_PRECISION (mode);
- +
- + switch (GET_MODE_CLASS (mode))
- + {
- + case MODE_PARTIAL_INT:
- + case MODE_INT:
- + if (precision == CHAR_TYPE_SIZE)
- + return true;
- + if (precision == SHORT_TYPE_SIZE)
- + return true;
- + if (precision == INT_TYPE_SIZE)
- + return true;
- + if (precision == LONG_TYPE_SIZE)
- + return true;
- + if (precision == LONG_LONG_TYPE_SIZE)
- + return true;
- + return false;
- +
- + case MODE_FLOAT:
- + if (precision == FLOAT_TYPE_SIZE)
- + return true;
- + if (precision == DOUBLE_TYPE_SIZE)
- + return true;
- + if (precision == LONG_DOUBLE_TYPE_SIZE)
- + return true;
- + return false;
- +
- + case MODE_DECIMAL_FLOAT:
- + return false;
- +
- + default:
- + gcc_unreachable ();
- + }
- +}
- +
- +enum reg_class
- +metag_secondary_reload (bool in_p, rtx x, enum reg_class class,
- + enum machine_mode mode, secondary_reload_info *sri)
- +{
- + return default_secondary_reload (in_p, x, class, mode, sri);
- +}
- +
- +enum reg_class
- +metag_secondary_reload_class (enum reg_class class, enum machine_mode mode, rtx x, bool in_p)
- +{
- + if (in_p)
- + {
- + if (reg_class_subset_p (FPC_REGS, class))
- + {
- + switch (GET_CODE (x))
- + {
- + case SYMBOL_REF:
- + case CONST_INT:
- + case CONST:
- + return GENERAL_REGS;
- +
- + case SUBREG:
- + if (metag_fpu_resources)
- + {
- + x = SUBREG_REG (x);
- +
- + if (!metag_hard_genreg_op (x, VOIDmode))
- + return D_REGS;
- + }
- +
- + break;
- +
- + /* We can only reload from memory if it's 32 or 64 bit */
- + /* 12bit offsets are not supported for FX registers either */
- + case MEM:
- + if (mode != SImode && mode != DImode
- + && GET_MODE_CLASS (mode) != MODE_FLOAT)
- + return D_REGS;
- +
- + if (GET_CODE (XEXP (x, 0)) == PLUS
- + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
- + {
- + HOST_WIDE_INT offset = INTVAL (XEXP (XEXP (x, 0), 1));
- +
- + if (offset / GET_MODE_SIZE (mode) >= 32
- + || offset / GET_MODE_SIZE (mode) < -32)
- + return D_REGS;
- + }
- +
- + if (metag_fpu_resources && SYMBOL_REF_P (XEXP (x, 0)))
- + return D_REGS;
- +
- + /* With only single precision hard-float we must not reload
- + direct to FX registers for DFmode values*/
- + if (metag_fpu_resources && metag_fpu_single && mode == DFmode)
- + return D_REGS;
- +
- + break;
- +
- + /* We can reload const_double to FX but only if it's a half precision,
- + * otherwise we must use GENERAL_REGS
- + */
- + case CONST_DOUBLE:
- + if (metag_fpu_resources
- + && (GET_MODE_CLASS (mode) != MODE_FLOAT
- + || !metag_fphalf_imm_op (x, mode)
- + || (metag_fpu_single
- + && mode == DFmode)))
- + return D_REGS;
- +
- + break;
- +
- + /* Theres no connection from A0/A1 to/from FX */
- + case REG:
- + if (metag_fpu_resources && METAG_ADDR_REG_P (true_regnum (x)))
- + return D_REGS;
- +
- + break;
- +
- + case PLUS:
- + if (metag_fpu_resources && GET_MODE_CLASS (mode) != MODE_FLOAT)
- + return DA_REGS;
- +
- + break;
- +
- + default:
- + break;
- + }
- + }
- + else if (reg_class_subset_p (A0_REGS, class)
- + || reg_class_subset_p (A1_REGS, class))
- + {
- + /* We have some restrictions on copying to A0/A1 with respect
- + * to floating point
- + */
- + switch (GET_CODE (x))
- + {
- + /* Theres no connection from A0/A1 to/from FX */
- + case REG:
- + if (metag_fpu_resources && METAG_FPC_REG_P (true_regnum (x)))
- + return D_REGS;
- +
- + break;
- +
- + default:
- + break;
- + }
- + }
- + }
- + else
- + {
- + if (reg_class_subset_p (FPC_REGS, class))
- + {
- + switch (GET_CODE (x))
- + {
- + /* Theres no connection from A0/A1 to/from FX */
- + case REG:
- + if (metag_fpu_resources && METAG_ADDR_REG_P (true_regnum (x)))
- + return D_REGS;
- +
- + break;
- +
- + case SUBREG:
- + if (metag_fpu_resources)
- + {
- + x = SUBREG_REG (x);
- +
- + if (!metag_hard_genreg_op (x, VOIDmode))
- + return D_REGS;
- + }
- +
- + break;
- +
- + /* We can only reload to memory if it's 32 or 64 bit */
- + /* 12bit offsets are not supported for FX registers either */
- + case MEM:
- + if (mode != SImode && mode != DImode
- + && GET_MODE_CLASS (mode) != MODE_FLOAT)
- + return D_REGS;
- +
- + if (GET_CODE (XEXP (x, 0)) == PLUS
- + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
- + {
- + HOST_WIDE_INT offset = INTVAL (XEXP (XEXP (x, 0), 1));
- +
- + if (offset / GET_MODE_SIZE (mode) >= 32
- + || offset / GET_MODE_SIZE (mode) < -32)
- + return D_REGS;
- + }
- +
- + if (metag_fpu_resources && SYMBOL_REF_P (XEXP (x, 0)))
- + return D_REGS;
- +
- + /* With only single precision hard-float we must not reload
- + direct to FX registers for DFmode values*/
- + if (metag_fpu_resources && metag_fpu_single && mode == DFmode)
- + return D_REGS;
- +
- + break;
- +
- + case PLUS:
- + if (metag_fpu_resources && GET_MODE_CLASS (mode) != MODE_FLOAT)
- + return DA_REGS;
- +
- + break;
- +
- + default:
- + break;
- + }
- + }
- + else if (reg_class_subset_p (A0_REGS, class)
- + || reg_class_subset_p (A1_REGS, class))
- + {
- + /* We have some restrictions on copying to A0/A1 with respect
- + * to floating point
- + */
- + switch (GET_CODE (x))
- + {
- + /* Theres no connection from A0/A1 to/from FX */
- + case REG:
- + if (metag_fpu_resources && METAG_FPC_REG_P (true_regnum (x)))
- + return D_REGS;
- +
- + break;
- +
- + default:
- + break;
- + }
- + }
- +
- + if (MEM_P (x))
- + {
- + rtx addr = XEXP (x, 0);
- +
- + switch (GET_CODE (addr))
- + {
- + case PRE_MODIFY:
- + case POST_MODIFY:
- + addr = XEXP (addr, 0);
- + break;
- + default:
- + break;
- + }
- +
- + if (GET_CODE (addr) == PLUS)
- + {
- + rtx op0 = XEXP (addr, 0);
- + rtx op1 = XEXP (addr, 1);
- +
- + if (REG_P (op0) && REG_P (op1))
- + {
- + int regno = true_regnum (op0);
- +
- + switch (METAG_REGNO_REG_CLASS (regno))
- + {
- + case A0_REGS:
- + if (reg_class_subset_p (A0_REGS, class))
- + {
- + switch (mode)
- + {
- + case QImode:
- + case HImode:
- + case SImode:
- + case SFmode:
- + return nA0_REGS;
- + case V2SFmode:
- + return FPC_REGS;
- + default:
- + break;
- + }
- +
- + return D_REGS;
- + }
- + break;
- + case A1_REGS:
- + if (reg_class_subset_p (A1_REGS, class))
- + {
- + switch (mode)
- + {
- + case QImode:
- + case HImode:
- + case SImode:
- + case SFmode:
- + return nA1_REGS;
- + case V2SFmode:
- + return FPC_REGS;
- + default:
- + break;
- + }
- +
- + return D_REGS;
- + }
- + break;
- + case D0_REGS:
- + if (reg_class_subset_p (D0_REGS, class))
- + {
- + switch (mode)
- + {
- + case QImode:
- + case HImode:
- + case SImode:
- + case SFmode:
- + return nD0_REGS;
- + case V2SFmode:
- + return FPC_REGS;
- + default:
- + break;
- + }
- +
- + return A_REGS;
- + }
- + break;
- + case D1_REGS:
- + if (reg_class_subset_p (D1_REGS, class))
- + {
- + switch (mode)
- + {
- + case QImode:
- + case HImode:
- + case SImode:
- + case SFmode:
- + return nD1_REGS;
- + case V2SFmode:
- + return FPC_REGS;
- + default:
- + break;
- + }
- +
- + return A_REGS;
- + }
- + break;
- + default:
- + break;
- + }
- + }
- + }
- + }
- + }
- +
- + return NO_REGS;
- +}
- +
- +/* Output code to add DELTA to the first argument, and then jump
- + to FUNCTION. Used for C++ multiple inheritance. */
- +
- +void
- +metag_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
- + HOST_WIDE_INT delta,
- + HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
- + tree function)
- +{
- + unsigned int this_regno = MAX_METAG_PARM_REGNUM; /* "this" */
- +
- + /* This 1st argument is "this" unless thunk returns the result in memory,
- + in which case there is a hidden 1st argument we contains a pointer to
- + where the result should be stored. */
- + if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
- + this_regno--;
- +
- + /* Add delta to "this" */
- + if (satisfies_constraint_I (GEN_INT (delta)))
- + asm_fprintf (file, "\tADD\t%r, %r, #%wd\n", this_regno, this_regno, delta);
- + else if (satisfies_constraint_I (GEN_INT (-delta)))
- + asm_fprintf (file, "\tSUB\t%r, %r, #%wd\n", this_regno, this_regno, -delta);
- + else if (satisfies_constraint_K (GEN_INT (delta)))
- + asm_fprintf (file, "\tADD\t%r, %r, #%wd\n", this_regno, this_regno, delta);
- + else if (satisfies_constraint_K (GEN_INT (-delta)))
- + asm_fprintf (file, "\tSUB\t%r, %r, #%wd\n", this_regno, this_regno, -delta);
- + else if ((delta & 0x0000FFFF) == 0)
- + asm_fprintf (file, "\tADDT\t%r, %r, #HI(%wd)\n", this_regno, this_regno, delta);
- + else if (((-delta) & 0x0000FFFF) == 0)
- + asm_fprintf (file, "\tSUBT\t%r, %r, #HI(%wd)\n", this_regno, this_regno, -delta);
- + else if ((delta & 0xFFFF0000) == 0)
- + asm_fprintf (file, "\tADD\t%r, %r, #LO(%wd)\n", this_regno, this_regno, delta);
- + else if (((-delta) & 0xFFFF0000) == 0)
- + asm_fprintf (file, "\tSUB\t%r, %r, #LO(%wd)\n", this_regno, this_regno, -delta);
- + else
- + {
- + asm_fprintf (file, "\tADDT\t%r, %r, #HI(%wd)\n", this_regno, this_regno, delta);
- + asm_fprintf (file, "\tADD\t%r, %r, #LO(%wd)\n", this_regno, this_regno, delta);
- + }
- +
- + /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
- + if (vcall_offset != 0)
- + {
- + unsigned int temp1 = D0_0_REG;
- + unsigned int temp2 = D1_0_REG;
- +
- + /* Set TEMP1 to *THIS. */
- + asm_fprintf (file, "\tGETD\t%r, [%r]\n", temp1, this_regno);
- +
- + /* Load the offset from (TEMP1 + VCALL_OFFSET) in TEMP2 ... */
- + if (-128 <= vcall_offset && vcall_offset <= 124)
- + asm_fprintf (file, "\tGETD\t%r, [%r+#(%wd)]\n", temp2, temp1, vcall_offset);
- + else
- + {
- + if (satisfies_constraint_I (GEN_INT (vcall_offset)))
- + asm_fprintf (file, "\tADD\t%r, %r, #%wd\n", temp1, temp1, vcall_offset);
- + else if (satisfies_constraint_I (GEN_INT (-vcall_offset)))
- + asm_fprintf (file, "\tSUB\t%r, %r, #%wd\n", temp1, temp1, -vcall_offset);
- + else if (satisfies_constraint_K (GEN_INT (vcall_offset)))
- + asm_fprintf (file, "\tADD\t%r, %r, #%wd\n", temp1, temp1, vcall_offset);
- + else if (satisfies_constraint_K (GEN_INT (-vcall_offset)))
- + asm_fprintf (file, "\tSUB\t%r, %r, #%wd\n", temp1, temp1, -vcall_offset);
- + else if ((vcall_offset & 0x0000FFFF) == 0)
- + asm_fprintf (file, "\tADDT\t%r, %r, #HI(%wd)\n", temp1, temp1, vcall_offset);
- + else if (((-vcall_offset) & 0x0000FFFF) == 0)
- + asm_fprintf (file, "\tSUBT\t%r, %r, #HI(%wd)\n", temp1, temp1, -vcall_offset);
- + else if ((vcall_offset & 0xFFFF0000) == 0)
- + asm_fprintf (file, "\tADD\t%r, %r, #LO(%wd)\n", temp1, temp1, vcall_offset);
- + else if (((-vcall_offset) & 0xFFFF0000) == 0)
- + asm_fprintf (file, "\tSUB\t%r, %r, #LO(%wd)\n", temp1, temp1, -vcall_offset);
- + else
- + {
- + asm_fprintf (file, "\tADDT\t%r, %r, #HI(%wd)\n", temp1, temp1, vcall_offset);
- + asm_fprintf (file, "\tADD\t%r, %r, #LO(%wd)\n", temp1, temp1, vcall_offset);
- + }
- +
- + asm_fprintf (file, "\tGETD\t%r, [%r]\n", temp2, temp1);
- + }
- +
- + /* ... and add it to THIS. */
- + asm_fprintf (file, "\tADD\t%r, %r, %r\n", this_regno, this_regno, temp2);
- + }
- +
- + fputs ("\tB\t", file);
- + {
- + rtx symbol = XEXP (DECL_RTL (function), 0);
- +
- + gcc_assert (SYMBOL_REF_P (symbol));
- +
- + assemble_name (file, XSTR (symbol, 0));
- + if (METAG_FLAG_PIC && !SYMBOL_REF_LOCAL_P (symbol))
- + fputs ("@PLT", file);
- + }
- + fputc ('\n', file);
- +}
- +
- +bool
- +metag_can_output_mi_thunk (tree thunk_decl ATTRIBUTE_UNUSED,
- + HOST_WIDE_INT delta ATTRIBUTE_UNUSED,
- + HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
- + tree function_decl ATTRIBUTE_UNUSED)
- +{
- + return true;
- +}
- +
- +bool
- +metag_handle_option (size_t code, const char *arg, int value)
- +{
- + switch (code)
- + {
- + case OPT_mhard_float:
- + {
- + int length = strlen(arg);
- +
- + metag_fpureg_string = "16";
- + metag_fpu_resources = 1;
- +
- + /* Turn off SIMD float whenever we see a hardfloat option */
- + target_flags &= ~MASK_FPU_SIMD;
- +
- + if (length == 0)
- + metag_fpu_single = 0;
- + else if (length == 2 && arg[0] == '=')
- + if (arg[1] == 'S')
- + metag_fpu_single = 1;
- + else if (arg[1] == 'D')
- + metag_fpu_single = 0;
- + else
- + error("-mhard-float takes an optional argument of S or D. E.g. -mhard-float=S");
- + /* If set to none then just use soft float */
- + else if (length == 5 && strncmp ("none", &arg[1], 4) == 0)
- + {
- + metag_fpu_resources = 0;
- + metag_fpureg_string = "";
- + target_flags &= ~MASK_FPU;
- + }
- + else
- + error("-mhard-float takes an optional argument of S or D. E.g. -mhard-float=S");
- + }
- + break;
- +
- + case OPT_msoft_float:
- + target_flags &= ~MASK_FPU_SIMD;
- + break;
- +
- + case OPT_mdsp:
- + if (value)
- + metag_extreg_string = "8844";
- + else
- + metag_extreg_string = "0000";
- + break;
- +
- + case OPT_mwidth_:
- + {
- + metag_memory_width = strtol (metag_width_string, NULL, 10);
- + if (metag_memory_width != 32
- + && metag_memory_width != 64)
- + error ("Invalid memory width specified. Permitted widths are 32 or 64.");
- + }
- + break;
- +
- + case OPT_mjump_table_branch_:
- + {
- + if (strncmp (metag_jump_table_string, "short", 5) == 0)
- + metag_jump_table_branch = METAG_MINIM_JUMP_TABLE_BRANCH_SHORT;
- + else if (strncmp (metag_jump_table_string, "long", 4) == 0)
- + metag_jump_table_branch = METAG_MINIM_JUMP_TABLE_BRANCH_LONG;
- + else if (strncmp (metag_jump_table_string, "auto", 4) == 0)
- + metag_jump_table_branch = METAG_MINIM_JUMP_TABLE_BRANCH_AUTO;
- + else
- + error ("-mjump-table-branch must be either 'long', 'short' or 'auto'");
- + }
- + break;
- +
- + case OPT_mcond_exec:
- + return true;
- +
- + case OPT_mextensions_:
- + {
- + char* extension = (char*)metag_extensions_string;
- + int extension_length = 0;
- + unsigned int i;
- + char* comma_position;
- +
- + for (i = 0 ; i < strlen(extension) ; i++)
- + extension[i] = tolower (extension[i]);
- +
- + while (strlen(extension) != 0)
- + {
- + comma_position = strchr (metag_extensions_string, ',');
- +
- + if (comma_position == NULL)
- + extension_length = strlen (extension);
- + else
- + extension_length = (comma_position-extension);
- +
- + if (strncmp (extension, "bex", (extension_length > 3) ? extension_length : 3) == 0)
- + metag_meta2_bex_enabled = true;
- + else /* Print the rest of the list in the warning */
- + warning (0, "Instruction set extension not known in list: %s", extension);
- +
- + extension += extension_length;
- + }
- + }
- + break;
- +
- + case OPT_mtbictxsave:
- + metag_force_tbictxsave = value;
- + break;
- +
- + case OPT_mhwtrace:
- + if (!value)
- + {
- + target_flags &= ~MASK_HWTRACE_RETPC;
- + target_flags &= ~MASK_HWTRACE_LEAF;
- + }
- + break;
- +
- + case OPT_mhwtrace_retpc:
- + case OPT_mhwtrace_leaf:
- + if (value)
- + target_flags |= MASK_HWTRACE;
- + break;
- +
- + default:
- + break;
- + }
- +
- + return metag_handle_option_per_os (code, arg, value);
- +}
- +
- +bool
- +metag_zeroextract_mask_p (rtx op0, rtx op1)
- +{
- + rtx value = GEN_INT (((1 << INTVAL (op0)) - 1) << INTVAL (op1));
- +
- + return satisfies_constraint_I (value) ||
- + satisfies_constraint_P (value) ||
- + satisfies_constraint_K (value) ||
- + satisfies_constraint_J (value) ||
- + satisfies_constraint_M (value) ||
- + satisfies_constraint_N (value);
- +}
- +
- +rtx
- +metag_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
- +{
- + if (count != 0)
- + return NULL_RTX;
- +
- + return get_hard_reg_initial_val (Pmode, RETURN_POINTER_REGNUM);
- +}
- +
- +HOST_WIDE_INT
- +metag_function_arg_boundary (enum machine_mode mode, tree type)
- +{
- + HOST_WIDE_INT size;
- +
- + if (type != NULL_TREE)
- + size = int_size_in_bytes (type);
- + else
- + size = GET_MODE_BITSIZE (mode);
- +
- + if (size < 0)
- + return BIGGEST_ALIGNMENT;
- + else if (size > UNITS_PER_WORD)
- + return BIGGEST_ALIGNMENT;
- + else
- + return PARM_BOUNDARY;
- +}
- +
- +int
- +metag_first_parm_offset (tree fndecl ATTRIBUTE_UNUSED)
- +{
- + if (cfun->machine->anonymous_args)
- + return current_function_pretend_args_size
- + - ALIGN_ON_STACK_BOUNDARY (current_function_pretend_args_size);
- +
- + return 0;
- +}
- +
- +/* WORK NEEDED: Check that the condition for consumer is not always or never */
- +
- +bool
- +metag_consumer_is_cond_p (rtx producer, rtx consumer)
- +{
- + return (GET_CODE (PATTERN (consumer)) == COND_EXEC)
- + && (get_attr_ccstate (producer) == CCSTATE_SET);
- +}
- +
- +bool
- +metag_bypass_before_reload_p (rtx producer ATTRIBUTE_UNUSED, rtx consumer ATTRIBUTE_UNUSED)
- +{
- + return !reload_in_progress && !reload_completed;
- +}
- +
- +int
- +metag_consumer_stalls_from_load_multi (rtx producer, rtx consumer)
- +{
- + int opno;
- + bool firstoperand = true;
- + unsigned int penultimate_reg = INVALID_REGNUM;
- + unsigned int last_reg = INVALID_REGNUM;
- + int stalls = 0; /* Zero stalls to begin with */
- +
- + /* Extract the insn to iterate over the output operands */
- + extract_insn (producer);
- +
- + for (opno = 0 ; opno < recog_data.n_operands ; opno++)
- + {
- + if (recog_data.operand_type[opno] == OP_OUT)
- + {
- + rtx op;
- +
- + /* Ignore the first output as it refers to the offset addition */
- + if (firstoperand)
- + {
- + firstoperand = false;
- + continue;
- + }
- +
- + /* Find the output register number*/
- + op = recog_data.operand[opno];
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + if (REG_P (op))
- + {
- + unsigned int regno = REGNO (op);
- +
- + if (IS_HARD_OR_VIRT_REGNO (regno))
- + {
- + /* Save the two highest numbered load destination register numbers. */
- + if (last_reg == INVALID_REGNUM || regno > last_reg)
- + {
- + penultimate_reg = last_reg;
- + last_reg = regno;
- + }
- + else if (penultimate_reg == INVALID_REGNUM || regno > penultimate_reg)
- + penultimate_reg = regno;
- + }
- + }
- + }
- + }
- +
- + /* Both penultimate_reg and last_reg should have values now, if not there
- + * is a big problem. */
- + gcc_assert (penultimate_reg != INVALID_REGNUM && last_reg != INVALID_REGNUM);
- +
- + /* Extract the consumer to examine its operands. */
- + extract_insn (consumer);
- +
- + /* If the consumer is an MSET it has to be handled differently... */
- + if (store_multiop (PATTERN (consumer), VOIDmode))
- + {
- + unsigned int first_reg = INVALID_REGNUM;
- + unsigned int second_reg = INVALID_REGNUM;
- +
- + /* For MSET instructions stalls only occur if:
- + * 1) The penultimate load collides with the initial store
- + * 2) The last load collides with the initial store
- + * 3) The last load collides with the 2nd store
- + */
- + firstoperand = true;
- + for (opno = 0 ; opno < recog_data.n_operands ; opno++)
- + {
- + if (recog_data.operand_type[opno] == OP_IN)
- + {
- + rtx op;
- +
- + /* Ignore the first input as it refers to the offset
- + * addition. */
- + if (firstoperand)
- + {
- + firstoperand = false;
- + continue;
- + }
- +
- + /* Find the input register number. */
- + op = recog_data.operand[opno];
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + if (REG_P (op))
- + {
- + unsigned int regno = REGNO (op);
- +
- + if (IS_HARD_OR_VIRT_REGNO (regno))
- + {
- + /* Save the two lowest numbered store source register numbers. */
- + if (first_reg == INVALID_REGNUM || regno < first_reg)
- + {
- + second_reg = first_reg;
- + first_reg = regno;
- + }
- + else if (second_reg == INVALID_REGNUM || regno < second_reg)
- + second_reg = regno;
- + }
- + }
- + }
- + }
- +
- + /* First and second regs should have valid numbers now. */
- + gcc_assert (first_reg != INVALID_REGNUM
- + && second_reg != INVALID_REGNUM);
- +
- + if (last_reg == first_reg)
- + stalls = 2;
- + else if (last_reg == second_reg || penultimate_reg == first_reg)
- + stalls = 1;
- + }
- + else
- + {
- + /* For anything other than MSET we examine all input operands
- + * and return a stall count if any operand collides with the
- + * penultimate or last value loaded. */
- + for (opno = 0 ; opno < recog_data.n_operands ; opno++)
- + {
- + if (recog_data.operand_type[opno] == OP_IN)
- + {
- + rtx op;
- +
- + /* Find the register number. */
- + op = recog_data.operand[opno];
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + if (REG_P (op))
- + {
- + unsigned int regno = REGNO (op);
- +
- + if (IS_HARD_OR_VIRT_REGNO (regno))
- + {
- + /*
- + * The consumer will stall for 2 cycles if it uses the last
- + * register and 1 cycle if it uses the penultimate
- + * register.
- + */
- + if (regno == last_reg)
- + {
- + stalls = 2;
- + /* Maximum stalls, no point checking further. */
- + break;
- + }
- + else if (regno == penultimate_reg)
- + stalls = 1;
- + }
- + }
- + }
- + }
- + }
- +
- + return stalls;
- + }
- +
- +/* Detect if any of the output registers of producer are used
- + * as an O2R input of consumer
- + *
- + * op1 identifies the operand that may be o2r
- + * op2 identifies the operand to check for a mismatch in units. */
- +
- +bool
- +metag_consumer_is_o2r (rtx producer, rtx consumer, int op1, int op2)
- +{
- + enum reg_class o2rregclass = NO_REGS;
- + enum reg_class op2regclass = NO_REGS;
- + unsigned int o2rregno = INVALID_REGNUM;
- + unsigned int op2regno = INVALID_REGNUM;
- + rtx op;
- +
- + /* The registers aren't known until reload has completed. */
- +
- + if (!reload_completed)
- + return false;
- +
- + extract_insn (consumer);
- +
- + if (recog_data.n_operands <= ((op1 > op2) ? op1 : op2)
- + || recog_data.operand_type[op1] == OP_OUT)
- + {
- + /* Bad insn pattern. o2rhint attribute incorrect
- + * o2rhint should say which operands must be in different units for
- + * insn to have an O2R operand generated. both operands must be
- + * IN or INOUT. */
- + gcc_unreachable ();
- + }
- +
- + /* Find the register class for op2. */
- + op = recog_data.operand[op2];
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + if (REG_P (op))
- + op2regno = REGNO (op);
- +
- + /* We should know the registers at this point. */
- + gcc_assert (IS_HARD_OR_VIRT_REGNO (op2regno));
- +
- + op2regclass = METAG_REGNO_REG_CLASS (op2regno);
- +
- + /* Find the register number for op1. */
- + op = recog_data.operand[op1];
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + if (REG_P (op))
- + o2rregno = REGNO (op);
- +
- + /* We should know the register at this point. */
- + gcc_assert (IS_HARD_OR_VIRT_REGNO (o2rregno));
- +
- + o2rregclass = METAG_REGNO_REG_CLASS (o2rregno);
- +
- + /* Check if op1 and op2 have different class registers. */
- + if (op2regclass != o2rregclass)
- + {
- + int opno;
- +
- + /* We have an O2R operand in op1, check it against all OUT / INOUT
- + * operands of producer. */
- + extract_insn (producer);
- +
- + for (opno = 0 ; opno < recog_data.n_operands ; opno++)
- + {
- + if (recog_data.operand_type[opno] != OP_INOUT)
- + {
- + op = recog_data.operand[opno];
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + if (REG_P (op))
- + {
- + unsigned int regno = REGNO (op);
- +
- + /* We should know the register at this point. */
- + gcc_assert (IS_HARD_OR_VIRT_REGNO (regno));
- +
- + if (regno == o2rregno)
- + return true; /* Producer has output reg that feeds o2r
- + operand in consumer. */
- + }
- + }
- + }
- + }
- +
- + return false;
- +}
- +
- +bool
- +metag_hard_regno_rename_ok_p (rtx insn,
- + unsigned int from,
- + unsigned int to)
- +{
- + /* Insn must have been recognised and rename permitted */
- + if (INSN_CODE (insn) >= 0 && get_attr_rename (insn))
- + {
- + if (cfun->machine->ech_ctx_required)
- + /* Where an ECH context has been allocated, allow any
- + hard register to be renamed */
- + return from <= LAST_ADDR_REG && to <= LAST_ADDR_REG;
- + else
- + {
- + /* When an ECH context has not been allocated, restrict
- + rename to the GP register set, regardless of what
- + registers are available */
- + return from <= LAST_ADDR_REG
- + && ((to < FIRST_ECH_DATA_REG)
- + || (to >= FIRST_ADDR_REG
- + && to < FIRST_ECH_ADDR_REG));
- + }
- + }
- + else
- + return false;
- +}
- +
- +enum reg_class
- +metag_regno_reg_class_minimal (unsigned int regno)
- +{
- + if (regno == D0_0_REG || regno == D0_1_REG)
- + return Ye_REGS;
- +
- + if (regno == D1_0_REG || regno == D1_1_REG)
- + return Yf_REGS;
- +
- + if (regno == A0_0_REG || regno == A0_1_REG)
- + return Yh_REGS;
- +
- + if (regno == A1_0_REG || regno == A1_1_REG)
- + return Yl_REGS;
- +
- + if (regno == A0_2_REG || regno == A0_3_REG)
- + return WQh_REGS;
- +
- + if (regno == A1_2_REG || regno == A1_3_REG)
- + return WQl_REGS;
- +
- + if (regno == ARG_POINTER_REGNUM || regno == FRAME_POINTER_REGNUM)
- + return Yh_REGS;
- +
- + return metag_regno_reg_class_unit (regno);
- +}
- +
- +enum reg_class
- +metag_regno_reg_class_unit (unsigned int regno)
- +{
- + if (regno == HARD_FRAME_POINTER_REGNUM
- + || regno == STACK_POINTER_REGNUM
- + || regno == ARG_POINTER_REGNUM
- + || regno == FRAME_POINTER_REGNUM)
- + return A0_REGS;
- +
- + if (METAG_DATA_REG_P (regno))
- + return (regno & 1) ? D1_REGS : D0_REGS;
- +
- + if (METAG_ADDR_REG_P (regno))
- + return (regno & 1) ? A1_REGS : A0_REGS;
- +
- + if (METAG_FPC_REG_P (regno))
- + return FPC_REGS;
- +
- + if (regno == CPC0_REG)
- + return A0_REGS;
- +
- + if (regno == CPC1_REG)
- + return A1_REGS;
- +
- + if (regno == PC_REG)
- + return A_REGS;
- +
- + if (regno == TXRPT_REG || regno == TTREC_REG)
- + return Wx_REGS;
- +
- + return NO_REGS;
- +}
- +
- +/* Make the last instruction frame related and note that it performs
- + the operation described by FRAME_PATTERN. */
- +
- +static void
- +metag_set_frame_expr (rtx frame_pattern)
- +{
- + rtx insn = get_last_insn ();
- +
- + RTX_FRAME_RELATED_P (insn) = 1;
- + if (frame_pattern != NULL_RTX)
- + REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
- + frame_pattern,
- + REG_NOTES (insn));
- +}
- +
- +/* Make the last instruction frame related. */
- +
- +static void
- +metag_set_frame_related (void)
- +{
- + metag_set_frame_expr (NULL_RTX);
- +}
- +
- +static void
- +metag_push_frameregs (unsigned extras, unsigned int first_reg, unsigned int last_reg)
- +{
- + rtx basemem = gen_rtx_MEM (DImode, stack_pointer_rtx);
- + unsigned int count = 0;
- + unsigned int RegList[8];
- + unsigned int *pRegList = RegList;
- +
- + {
- + unsigned int regno;
- +
- + for (regno = first_reg; regno <= last_reg; regno += 2)
- + if ((extras & REGNO_BIT (regno)) != 0)
- + {
- + gcc_assert (pRegList < &RegList[sizeof(RegList)/sizeof(RegList[0])]);
- +
- + *pRegList++ = regno;
- + }
- + }
- +
- + count = pRegList - RegList;
- + gcc_assert (0 < count && count <= sizeof(RegList)/sizeof(RegList[0]));
- +
- + if (count == 1)
- + {
- + rtx frame_expr = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (3));
- + rtx set;
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + gen_rtx_MEM (DImode,
- + gen_rtx_POST_INC (Pmode,
- + stack_pointer_rtx)),
- + gen_rtx_REG (DImode, RegList[0])));
- +
- + /* Describe the above instruction to the Drwarf2 call frame unwinder. */
- + set = gen_rtx_SET (VOIDmode,
- + gen_rtx_MEM (SImode, stack_pointer_rtx),
- + gen_rtx_REG (SImode, RegList[0]));
- + XVECEXP (frame_expr, 0, 0) = set;
- + RTX_FRAME_RELATED_P (set) = 1;
- +
- + set = gen_rtx_SET (VOIDmode,
- + gen_rtx_MEM (SImode,
- + plus_constant (stack_pointer_rtx,
- + UNITS_PER_WORD)),
- + gen_rtx_REG (SImode, RegList[0] + 1));
- + XVECEXP (frame_expr, 0, 1) = set;
- + RTX_FRAME_RELATED_P (set) = 1;
- +
- + set = gen_rtx_SET (VOIDmode,
- + stack_pointer_rtx,
- + plus_constant (stack_pointer_rtx,
- + UNITS_PER_WORD * 2));
- + XVECEXP (frame_expr, 0, 2) = set;
- + RTX_FRAME_RELATED_P (set) = 1;
- +
- + metag_set_frame_expr (frame_expr);
- + }
- + else
- + {
- + rtx result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (1 + count));
- + rtx frame_expr = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (1 + count * 2));
- + rtx set;
- +
- + set = gen_rtx_SET (VOIDmode,
- + stack_pointer_rtx,
- + plus_constant (stack_pointer_rtx,
- + count * UNITS_PER_WORD * 2));
- + XVECEXP (result, 0, 0) = set;
- +
- + set = copy_rtx (set);
- + XVECEXP (frame_expr, 0, count * 2) = set;
- + RTX_FRAME_RELATED_P (set) = 1;
- +
- + {
- + unsigned int offset = 0;
- + unsigned int i;
- +
- + for (i = 0; i < count; i++)
- + {
- + rtx addr = plus_constant (stack_pointer_rtx, i * UNITS_PER_WORD * 2);
- + rtx mem = adjust_automodify_address_nv (basemem, DImode, addr, offset);
- + rtx set;
- + int j;
- +
- + set = gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (DImode, RegList[i]));
- + XVECEXP (result, 0, 1 + i) = set;
- +
- + for (j = 0; j < 2; j++)
- + {
- + set = gen_rtx_SET (VOIDmode,
- + gen_rtx_MEM (SImode,
- + plus_constant (stack_pointer_rtx,
- + offset)),
- + gen_rtx_REG (SImode, RegList[i] + j));
- + XVECEXP (frame_expr, 0, i * 2 + j) = set;
- + RTX_FRAME_RELATED_P (set) = 1;
- +
- + offset += UNITS_PER_WORD;
- + }
- + }
- +
- + emit_insn (result);
- +
- + metag_set_frame_expr (frame_expr);
- + }
- + }
- +}
- +
- +void
- +metag_expand_prologue (void)
- +{
- + unsigned int savesize_gp = 0;
- + unsigned int savesize_eh = 0;
- + unsigned int FP_SP_offset = 0;
- + HOST_WIDE_INT size = get_frame_size ();
- + unsigned int pretend_size = ALIGN_ON_STACK_BOUNDARY (current_function_pretend_args_size);
- + unsigned int pretend_regs = pretend_size / UNITS_PER_WORD;
- + unsigned int extras_gp = 0;
- + unsigned int extras_eh = 0;
- + unsigned int ech_ctx = 0;
- + bool non_leaf = metag_non_leaf_function_p ();
- + rtx use = NULL_RTX;
- + bool loads_pic_register;
- +
- + /* Round size of local stack to preserve 64-bit alignments */
- + size = ALIGN_ON_STACK_BOUNDARY (size + current_function_outgoing_args_size);
- +
- + /* Make pretend regs into the first non-varargs register number */
- + pretend_regs += MIN_METAG_PARM_REGNUM;
- +
- + {
- + unsigned int regno;
- +
- + for (regno = MIN_METAG_PARM_REGNUM; regno <= MAX_METAG_CSAVE_REGNUM; regno += 2)
- + {
- + if (regno < pretend_regs
- + || (!call_used_regs[regno]
- + && (df_regs_ever_live_p (regno + 0) || df_regs_ever_live_p (regno + 1))))
- + {
- + /* Push this data register */
- + savesize_gp += UNITS_PER_WORD * 2;
- + extras_gp |= REGNO_BIT (regno);
- +
- + if (regno >= MIN_METAG_CSAVE_REGNUM)
- + FP_SP_offset += UNITS_PER_WORD * 2;
- + }
- + }
- + }
- +
- + /* Adjust the saved registers for ECH support */
- + ech_ctx = metag_adjust_savesize_ech (&savesize_gp, &extras_gp, &FP_SP_offset);
- +
- + /* Recover original pretend regs */
- + pretend_regs -= MIN_METAG_PARM_REGNUM;
- +
- + if (cfun->tail_call_emit && cfun->machine->hwtrace_leaf)
- + {
- + /* The entry point of a function that ends in a tail call needs to be
- + marked up when tracing all functions */
- +
- + emit_insn (gen_ttmov_si (gen_rtx_REG (SImode, TEMP_D0FRT_REGNUM),
- + gen_rtx_REG (SImode, RETURN_POINTER_REGNUM)));
- + }
- + else if (!frame_pointer_needed && cfun->machine->hwtrace_leaf)
- + {
- + /* The entry point of all functions need to be marked up when tracing
- + all functions regardless of whether the frame pointer is omitted.
- + Handle the case where the frame pointer is omitted here. See below
- + for other case. */
- +
- + emit_insn (gen_ttmov_si (gen_rtx_REG (SImode, TEMP_D0FRT_REGNUM),
- + hard_frame_pointer_rtx));
- +
- + /* This is NOT frame related because there is no frame pointer really */
- + }
- +
- + if (frame_pointer_needed || non_leaf)
- + {
- + if (non_leaf)
- + extras_gp |= REGNO_BIT (RETURN_POINTER_REGNUM);
- +
- + /* Save return address and maybe frame pointer via {D0Frt,D1RtP} pair */
- + savesize_gp += UNITS_PER_WORD * 2;
- + FP_SP_offset += UNITS_PER_WORD * 2;
- +
- + if (frame_pointer_needed)
- + {
- + /* Need to spill A0FrP ready for saving and calc new frame */
- + if (cfun->machine->hwtrace)
- + {
- + rtx frame_expr;
- + /* Mark up function entry when frame pointer is not omitted, for all
- + types of H/W tracing */
- + emit_insn (gen_ttmov_si (gen_rtx_REG (SImode, TEMP_D0FRT_REGNUM),
- + hard_frame_pointer_rtx));
- + frame_expr = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, TEMP_D0FRT_REGNUM),
- + hard_frame_pointer_rtx);
- + RTX_FRAME_RELATED_P (frame_expr) = 1;
- + metag_set_frame_expr (frame_expr);
- + }
- + else
- + {
- + emit_insn (gen_rtx_SET (VOIDmode,
- + gen_rtx_REG (SImode, TEMP_D0FRT_REGNUM),
- + hard_frame_pointer_rtx));
- +
- + metag_set_frame_related ();
- + }
- +
- + /* Save return address and frame pointer via (D0FrT,D1RtP) pair */
- + extras_gp |= REGNO_BIT (TEMP_D0FRT_REGNUM);
- +
- + emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
- + stack_pointer_rtx,
- + gen_int_mode (pretend_size, SImode)));
- + metag_set_frame_related ();
- +
- + use = hard_frame_pointer_rtx;
- + }
- + }
- + else if (df_regs_ever_live_p (RETURN_POINTER_REGNUM))
- + {
- + extras_gp |= REGNO_BIT (RETURN_POINTER_REGNUM);
- +
- + /* Have to do at least ine pop */
- + savesize_gp += UNITS_PER_WORD * 2;
- +
- + if (RETURN_POINTER_REGNUM >= MIN_METAG_CSAVE_REGNUM)
- + FP_SP_offset += UNITS_PER_WORD * 2;
- + }
- +
- + if (current_function_calls_eh_return)
- + {
- + unsigned int n;
- +
- + for (n = 0; n < NUM_EH_RETURN_DATA_REGS; n++)
- + {
- + unsigned int regno = EH_RETURN_DATA_REGNO (n);
- +
- + if (regno != INVALID_REGNUM)
- + {
- + unsigned int regbit = REGNO_BIT (regno);
- +
- + if ((extras_eh & regbit) == 0)
- + {
- + extras_eh |= regbit;
- + savesize_eh += UNITS_PER_WORD * 2;
- + FP_SP_offset += UNITS_PER_WORD * 2;
- + }
- + }
- + }
- + }
- +
- + loads_pic_register = METAG_CURRENT_FUNCTION_LOADS_PIC_REGISTER ();
- + if (loads_pic_register)
- + FP_SP_offset += UNITS_PER_WORD * 2;/* Save PIC register. */
- +
- + /* Sanity checks between initial_elimination and prologue. If these
- + tests fail then the generated code will be wrong so abort. */
- +
- + gcc_assert (cfun->machine->valid);
- +
- + gcc_assert (cfun->machine->savesize_gp == savesize_gp);
- + gcc_assert (cfun->machine->savesize_eh == savesize_eh);
- + gcc_assert (cfun->machine->FP_SP_offset == FP_SP_offset);
- + gcc_assert (cfun->machine->frame_pointer_needed == frame_pointer_needed);
- + gcc_assert (cfun->machine->non_leaf == non_leaf);
- + gcc_assert (cfun->machine->extras_gp == extras_gp);
- + gcc_assert (cfun->machine->extras_eh == extras_eh);
- + gcc_assert (cfun->machine->calls_eh_return == current_function_calls_eh_return);
- + gcc_assert (cfun->machine->uses_pic_offset_table == current_function_uses_pic_offset_table);
- + gcc_assert (cfun->machine->loads_pic_register == loads_pic_register);
- + gcc_assert (cfun->machine->ech_ctx_required == (ech_ctx != 0));
- +
- + /* When ECH support is enabled, the register pair including D0.8 may be saved
- + therefore include it in the initial push */
- + if (extras_gp != 0)
- + metag_push_frameregs (extras_gp, MIN_METAG_PARM_REGNUM, TARGET_ECH ?
- + METAG_ECH_REGNUM :
- + MAX_METAG_CSAVE_REGNUM);
- +
- + if (extras_eh != 0)
- + metag_push_frameregs (extras_eh, EH_RETURN_FIRST_DATA_REG, EH_RETURN_LAST_DATA_REG);
- +
- + if (loads_pic_register)
- + {
- + rtx frame_expr = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
- + rtx set;
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + gen_rtx_MEM (DImode,
- + gen_rtx_POST_INC (Pmode,
- + stack_pointer_rtx)),
- + gen_rtx_UNSPEC (DImode,
- + gen_rtvec (2,
- + hard_frame_pointer_rtx,
- + pic_offset_table_rtx),
- + UNSPEC_CONCAT)));
- +
- + /* Describe the above instruction to the Dwarf2 call frame unwinder. */
- +
- + set = gen_rtx_SET (VOIDmode,
- + gen_rtx_MEM (SImode,
- + plus_constant (stack_pointer_rtx,
- + UNITS_PER_WORD)),
- + pic_offset_table_rtx);
- + XVECEXP (frame_expr, 0, 0) = set;
- + RTX_FRAME_RELATED_P (set) = 1;
- +
- + set = gen_rtx_SET (VOIDmode,
- + stack_pointer_rtx,
- + plus_constant (stack_pointer_rtx,
- + 2 * UNITS_PER_WORD));
- + XVECEXP (frame_expr, 0, 1) = set;
- + RTX_FRAME_RELATED_P (set) = 1;
- +
- + metag_set_frame_expr (frame_expr);
- + }
- +
- + /* Allocate local stack based storage */
- + if (size != 0)
- + {
- + rtx frame_expr = gen_rtx_SET (VOIDmode,
- + stack_pointer_rtx,
- + plus_constant (stack_pointer_rtx,
- + size));
- +
- + emit_insn (gen_addsi3 (stack_pointer_rtx,
- + stack_pointer_rtx,
- + gen_int_mode (size, SImode)));
- +
- + metag_set_frame_expr (frame_expr);
- + }
- +
- + /* Initialise PIC register. */
- + if (loads_pic_register)
- + {
- + emit_insn (gen_load_pic (pic_offset_table_rtx,
- + gen_rtx_REG (SImode, CPC1_REG)));
- + emit_insn (gen_prologue_use (pic_offset_table_rtx));
- + }
- +
- + if (use != NULL_RTX)
- + emit_insn (gen_prologue_use (use));
- +
- + if (ech_ctx != 0)
- + {
- + rtx reg_ech = gen_rtx_REG (SImode, METAG_ECH_REGNUM);
- +
- + /* Only store context if we used a register. The ECH register will be
- + reset to zero by any system supporting ECH contexts prior to
- + restoring the context for a process using ECH.
- +
- + We must always store the DX8 part of the context as ECH implicitly
- + uses D0.8. */
- +
- + ech_ctx |= ((TBICTX_XMCC_BIT | TBICTX_XEXT_BIT | TBICTX_XDX8_BIT) << 16);
- +
- + /* GCC does not use DSP RAM so the lower 16 bits will be zero */
- + gcc_assert ((ech_ctx & 0xFFFF) == 0);
- +
- + /* Guaranteed to have bottom 16bits zero, and hence will be set in a
- + single instruction */
- + emit_insn (gen_rtx_SET (SImode, reg_ech,
- + gen_int_mode (ech_ctx, SImode)));
- + emit_insn (gen_prologue_use (reg_ech));
- +
- + }
- +
- + emit_insn (gen_blockage ());
- +}
- +
- +void
- +metag_expand_epilogue (bool epilogue_for_tailcall)
- +{
- + unsigned int savesize_gp = 0;
- + unsigned int savesize_eh = 0;
- + unsigned int picsize = 0;
- + unsigned int num_saved_regs = 0;
- + unsigned int extras_gp = 0;
- + unsigned int extras_eh = 0;
- + unsigned int ech_ctx = 0;
- + bool non_leaf = metag_non_leaf_function_p ();
- + int pretend_size = ALIGN_ON_STACK_BOUNDARY (current_function_pretend_args_size);
- + HOST_WIDE_INT size = get_frame_size ();
- + unsigned int RegList[8];
- + unsigned int *pRegList = RegList;
- + bool loads_pic_register;
- +
- + emit_insn (gen_blockage ());
- +
- + /* Round size of local stack to preserve 64-bit alignments */
- + size = ALIGN_ON_STACK_BOUNDARY (size + current_function_outgoing_args_size);
- +
- + /* Calculate number of registers to restore
- + if they contain pretend args save all, else save registers with data in them */
- + {
- + unsigned int regno;
- +
- + for (regno = MIN_METAG_CSAVE_REGNUM; regno <= MAX_METAG_CSAVE_REGNUM; regno += 2)
- + {
- + if (!call_used_regs[regno]
- + && (df_regs_ever_live_p(regno + 0) || df_regs_ever_live_p(regno + 1)))
- + {
- + /* Need to restore all normal Dx register pairs required */
- + savesize_gp += UNITS_PER_WORD * 2;
- + extras_gp |= REGNO_BIT (regno);
- + }
- + }
- + }
- +
- + /* Adjust the saved registers for ECH support */
- + ech_ctx = metag_adjust_savesize_ech (&savesize_gp, &extras_gp, NULL);
- +
- + /* No registers so far for MGETL|GETL */
- +
- + if (frame_pointer_needed || non_leaf)
- + {
- + /* Restore frame pointer via D0FRT or restore return address */
- +
- + if (non_leaf)
- + {
- + /* Have to get D1RtP back */
- + extras_gp |= REGNO_BIT (RETURN_POINTER_REGNUM);
- + }
- +
- + if (frame_pointer_needed)
- + {
- + /* Must restore callers frame pointer */
- + extras_gp |= REGNO_BIT (TEMP_D0FRT_REGNUM);
- + }
- +
- + savesize_gp += UNITS_PER_WORD * 2;
- + }
- + else if (df_regs_ever_live_p (RETURN_POINTER_REGNUM))
- + {
- + extras_gp |= REGNO_BIT (RETURN_POINTER_REGNUM);
- +
- + /* Have to do at least one pop */
- + savesize_gp += UNITS_PER_WORD * 2;
- + }
- +
- + if (current_function_calls_eh_return)
- + {
- + unsigned int n;
- +
- + for (n = 0; n < NUM_EH_RETURN_DATA_REGS; n++)
- + {
- + unsigned int regno = EH_RETURN_DATA_REGNO (n);
- +
- + if (regno != INVALID_REGNUM)
- + {
- + unsigned int regbit = REGNO_BIT (regno);
- +
- + if ((extras_eh & regbit) == 0)
- + {
- + extras_eh |= regbit;
- + savesize_eh += UNITS_PER_WORD * 2;
- + }
- + }
- + }
- + }
- +
- + loads_pic_register = METAG_CURRENT_FUNCTION_LOADS_PIC_REGISTER ();
- + if (loads_pic_register)
- + picsize += UNITS_PER_WORD * 2;
- +
- + if (!frame_pointer_needed && size > 16352)
- + {
- + HOST_WIDE_INT excess = size & 0xFFFF0000;
- +
- + /* LCS is too big to use as direct offset for recovery */
- + if (excess != 0)
- + {
- + emit_insn (gen_addsi3 (stack_pointer_rtx,
- + stack_pointer_rtx,
- + GEN_INT (-trunc_int_for_mode (excess, SImode))));
- + size &= 0xFFFF;
- + }
- +
- + if (size > 16352)
- + {
- + emit_insn (gen_addsi3 (stack_pointer_rtx,
- + stack_pointer_rtx,
- + GEN_INT (-trunc_int_for_mode (size, SImode))));
- + size = 0;
- + }
- + }
- +
- + if (loads_pic_register)
- + {
- + if (frame_pointer_needed)
- + emit_insn (gen_rtx_SET (VOIDmode,
- + gen_rtx_UNSPEC (DImode,
- + gen_rtvec (2,
- + hard_frame_pointer_rtx,
- + pic_offset_table_rtx),
- + UNSPEC_CONCAT),
- + gen_rtx_MEM (DImode,
- + plus_constant (hard_frame_pointer_rtx,
- + savesize_gp + savesize_eh))));
- + else
- + emit_insn (gen_rtx_SET (VOIDmode,
- + gen_rtx_UNSPEC (DImode,
- + gen_rtvec (2,
- + hard_frame_pointer_rtx,
- + pic_offset_table_rtx),
- + UNSPEC_CONCAT),
- + gen_rtx_MEM (DImode,
- + plus_constant (stack_pointer_rtx,
- + -(HOST_WIDE_INT)(size + picsize)))));
- + }
- +
- + if (extras_eh != 0)
- + {
- + unsigned int delta = 0;
- + unsigned int regno;
- +
- + for (regno = 0; regno < 32; regno += 2)
- + {
- + if ((extras_eh & REGNO_BIT (regno)) != 0)
- + {
- + if (frame_pointer_needed)
- + {
- + emit_insn (gen_rtx_SET (VOIDmode,
- + gen_rtx_REG (DImode, regno),
- + gen_rtx_MEM (DImode,
- + plus_constant (hard_frame_pointer_rtx,
- + savesize_gp + delta))));
- + }
- + else
- + {
- + HOST_WIDE_INT offset = -(HOST_WIDE_INT)(size + picsize + savesize_eh);
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + gen_rtx_REG (DImode, regno),
- + gen_rtx_MEM (DImode,
- + plus_constant (stack_pointer_rtx,
- + offset + delta))));
- + }
- +
- + delta += UNITS_PER_WORD * 2;
- + }
- + }
- + }
- +
- + if (extras_gp != 0)
- + {
- + unsigned int regno;
- +
- + for (regno = MIN_METAG_PARM_REGNUM; regno < 32; regno += 2)
- + {
- + if ((extras_gp & REGNO_BIT (regno)) != 0)
- + {
- + HOST_WIDE_INT offset = -(HOST_WIDE_INT)(size + picsize + savesize_eh + savesize_gp);
- +
- + gcc_assert (pRegList < &RegList[sizeof(RegList)/sizeof(RegList[0])]);
- +
- + if (!frame_pointer_needed
- + && (savesize_gp != UNITS_PER_WORD * 2 || pretend_size != 0 || (size + picsize) >= 256))
- + {
- + offset += num_saved_regs * UNITS_PER_WORD * 2;
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + gen_rtx_REG (DImode, regno),
- + gen_rtx_MEM (DImode,
- + plus_constant (stack_pointer_rtx,
- + offset))));
- + pRegList = RegList;
- + }
- + else if (!frame_pointer_needed)
- + {
- + /* Only one pair and no pretend args, pre-decrement stack! */
- + emit_insn (gen_rtx_SET (VOIDmode,
- + gen_rtx_REG (DImode, regno),
- + gen_rtx_MEM (DImode,
- + gen_rtx_PRE_MODIFY (Pmode,
- + stack_pointer_rtx,
- + plus_constant (stack_pointer_rtx,
- + offset)))));
- + pRegList = RegList;
- +
- + /* Stack predecremented above */
- + size = -(HOST_WIDE_INT)(savesize_gp + savesize_eh + picsize);
- + }
- + else
- + *pRegList++ = regno;
- +
- + /* Count them */
- + num_saved_regs++;
- + }
- + }
- + }
- +
- + /* Take account of pretend args stored on the stack by the prologue */
- + savesize_gp += pretend_size;
- +
- + if (pRegList != RegList)
- + {
- + rtx basemem = gen_rtx_MEM (DImode, hard_frame_pointer_rtx);
- + unsigned int count = pRegList - RegList;
- +
- + gcc_assert (count > 0);
- +
- + /* Use frame pointer to recover caller-saved regs */
- + if (count == 1)
- + {
- + /* Only one pair needed, advance frame pointer */
- + emit_insn (gen_rtx_SET (VOIDmode,
- + gen_rtx_REG (DImode, RegList[0]),
- + gen_rtx_MEM (DImode,
- + gen_rtx_POST_INC (Pmode,
- + hard_frame_pointer_rtx))));
- + }
- + else
- + {
- + rtx result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (1 + count));
- + unsigned int offset = 0;
- + unsigned int i;
- +
- + XVECEXP (result, 0, 0) = gen_rtx_SET (VOIDmode,
- + hard_frame_pointer_rtx,
- + plus_constant (hard_frame_pointer_rtx,
- + count * UNITS_PER_WORD * 2));
- +
- + for (i = 0; i < count; i++)
- + {
- + rtx addr = plus_constant (hard_frame_pointer_rtx, i * UNITS_PER_WORD * 2);
- + rtx mem = adjust_automodify_address_nv (basemem, DImode, addr, offset);
- +
- + gcc_assert (i <= count);
- +
- + XVECEXP (result, 0, 1 + i) = gen_rtx_SET (VOIDmode,
- + gen_rtx_REG (DImode, RegList[i]),
- + mem);
- + offset += UNITS_PER_WORD * 2;
- + }
- +
- + emit_insn (result);
- + }
- +
- + /* Use frame pointer to recover stack pointer */
- + emit_insn (gen_addsi3 (stack_pointer_rtx,
- + hard_frame_pointer_rtx,
- + GEN_INT (-trunc_int_for_mode (savesize_gp, SImode))));
- + }
- + else if (frame_pointer_needed)
- + {
- + /* Use unmolested frame pointer to recover stack pointer */
- + emit_insn (gen_addsi3 (stack_pointer_rtx,
- + hard_frame_pointer_rtx,
- + GEN_INT (-trunc_int_for_mode (pretend_size, SImode))));
- + }
- + else
- + {
- + HOST_WIDE_INT adjust = size + picsize + savesize_eh + savesize_gp;
- +
- + /* Calculate return stack adjustment directly including savesize */
- +
- + if (adjust != 0)
- + emit_insn (gen_addsi3 (stack_pointer_rtx,
- + stack_pointer_rtx,
- + GEN_INT (-trunc_int_for_mode (adjust, SImode))));
- + }
- +
- + /* We should be able to insert code here for EPILOGUE delay-slots if
- + frame_pointer_needed. The next instruction will stall waiting
- + for return data from the MGETL or GETL done above in this case. */
- +
- + if (frame_pointer_needed)
- + {
- + if (!cfun->machine->hwtrace || cfun->machine->hwtrace_retpc)
- + {
- + /* Restore callers frame pointer. The HWTRACE code below will take
- + care of this when enabled, unless the RETPC method is being used,
- + in which case it must be done here as normal. */
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + hard_frame_pointer_rtx,
- + gen_rtx_REG (SImode, TEMP_D0FRT_REGNUM)));
- + }
- + }
- + else if ((!cfun->tail_call_emit || !epilogue_for_tailcall)
- + && cfun->machine->hwtrace_leaf && cfun->machine->hwtrace_retpc
- + && !non_leaf && df_regs_ever_live_p (TEMP_D0FRT_REGNUM))
- + {
- + /* When tracing all leaf functions with the RETPC method, and we are
- + in a leaf function that has clobbered D0FrT and the frame pointer
- + is not needed (and this function doesn't end in a sibcall)...
- + Then D0FrT must be recovered from the frame pointer ready to be used
- + below */
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + gen_rtx_REG (SImode, TEMP_D0FRT_REGNUM),
- + hard_frame_pointer_rtx));
- + }
- +
- + if ((!cfun->tail_call_emit || !epilogue_for_tailcall)
- + && cfun->machine->hwtrace_retpc)
- + {
- + /* The RETPC method of tracing is a MOVL TTREC, x,y. Emit one when
- + the function does not end in a sibcall*/
- +
- + emit_insn (gen_ttrec (gen_rtx_REG (DImode, TTREC_REGNUM),
- + gen_rtx_REG (DImode, TEMP_D0FRT_REGNUM)));
- + }
- + else if ((!cfun->tail_call_emit || !epilogue_for_tailcall)
- + && cfun->machine->hwtrace
- + && (frame_pointer_needed || cfun->machine->hwtrace_leaf))
- + {
- + /* The standard method of tracing is to mark up the FP restore with a
- + TTMOV.
- + This is done when tracing leaf functions or the frame pointer is
- + needed. In the latter case this replaces the normal frame pointer
- + restore from above. */
- +
- + emit_insn (gen_ttmov_si (hard_frame_pointer_rtx,
- + gen_rtx_REG (SImode, TEMP_D0FRT_REGNUM)));
- + }
- +
- + /* Returns to exception handlers require an additional stack adjustment. */
- + if (current_function_calls_eh_return)
- + emit_insn (gen_subsi3 (stack_pointer_rtx,
- + stack_pointer_rtx,
- + EH_RETURN_STACKADJ_RTX));
- +
- + return;
- +}
- +
- +/* Return TRUE if it is possible to return using a simple return
- + sequence instruction, possibly conditional. */
- +
- +bool
- +metag_use_return_insn (bool cond)
- +{
- + if (! reload_completed)
- + return false;
- +
- + if (current_function_profile)
- + return false;
- +
- + if (current_function_calls_alloca)
- + return false;
- +
- + if (current_function_calls_eh_return)
- + return false;
- +
- + if (current_function_outgoing_args_size != 0)
- + return false;
- +
- + if (current_function_pretend_args_size != 0)
- + return false;
- +
- + if (cfun->machine->anonymous_args_size != 0)
- + return false;
- +
- + if (cfun->machine->out_local_size != 0)
- + return false;
- +
- + if (cfun->machine->savesize_gp != 0)
- + return false;
- +
- + if (cfun->machine->loads_pic_register != 0)
- + return false;
- +
- + if (cond && cfun->machine->hwtrace)
- + return false;
- +
- + return true;
- +}
- +
- +/* Verify that any instruction that supports conditional execution
- + * includes the '%?' placeholder if that instruction has been
- + * marked as conditional. */
- +void
- +metag_asm_output_opcode (FILE *file ATTRIBUTE_UNUSED, const char * opcode)
- +{
- + if (metag_cond_exec_p () || current_insn_predicate != NULL_RTX)
- + {
- + if (strchr (opcode, '?') == NULL)
- + gcc_unreachable ();
- + }
- +}
- +
- +const char *
- +metag_invalid_within_doloop (rtx insn)
- +{
- + if (CALL_P (insn))
- + return "Function call in the loop.";
- +
- + if (INSN_P (insn) && asm_noperands (PATTERN (insn)) >= 0 &&
- + regno_clobbered_p (TXRPT_REGNUM, insn, SImode, 0))
- + return "In-line assembler clobbering TXRPT.";
- +
- + return NULL;
- +}
- +
- +/* Return TRUE iff the frame-pointer is required to efficiently restore
- + * the stack frame during the epilogue. */
- +
- +static bool
- +metag_frame_pointer_required_for_epilogue_restore (void)
- +{
- + return cfun->machine->frame_pointer_epilogue
- + = metag_non_leaf_function_p ()
- + && (ALIGN_ON_STACK_BOUNDARY (get_frame_size ()
- + + current_function_outgoing_args_size) > 16352);
- +}
- +
- +/* Return TRUE if the frame-pointer is required. */
- +
- +bool
- +metag_frame_pointer_required (void)
- +{
- + return (current_function_calls_alloca
- + || current_function_has_nonlocal_label
- + || profile_flag
- + || (cfun->machine->valid && cfun->machine->frame_pointer_epilogue)
- + || cfun->machine->accesses_prev_frame
- + || metag_frame_pointer_required_for_epilogue_restore ());
- +}
- +
- +void
- +metag_setup_frame_addresses (void)
- +{
- + cfun->machine->accesses_prev_frame = true;
- +}
- +
- +void
- +metag_expand_set_return_address (rtx source)
- +{
- + unsigned int savesize_gp = 0;
- + unsigned int savesize_eh = 0;
- + unsigned int picsize = 0;
- + unsigned int extras_gp = 0;
- + unsigned int extras_eh = 0;
- + unsigned int ech_ctx = 0;
- + bool non_leaf = metag_non_leaf_function_p ();
- + HOST_WIDE_INT size = get_frame_size ();
- + bool loads_pic_register;
- +
- + /* Round size of local stack to preserve 64-bit alignments */
- + size = ALIGN_ON_STACK_BOUNDARY (size + current_function_outgoing_args_size);
- +
- + /* Calculate number of registers to restore
- + if they contain pretend args save all, else save registers with data in them */
- + {
- + unsigned int regno;
- +
- + for (regno = MIN_METAG_CSAVE_REGNUM; regno <= MAX_METAG_CSAVE_REGNUM; regno += 2)
- + {
- + if (!call_used_regs[regno]
- + && (df_regs_ever_live_p (regno + 0) || df_regs_ever_live_p (regno + 1)))
- + {
- + /* Need to restore all normal Dx register pairs required */
- + savesize_gp += UNITS_PER_WORD * 2;
- + extras_gp |= REGNO_BIT (regno);
- + }
- + }
- + }
- +
- + /* Adjust the saved registers for ECH support */
- + ech_ctx = metag_adjust_savesize_ech (&savesize_gp, &extras_gp, NULL);
- +
- + if (frame_pointer_needed || non_leaf)
- + {
- + /* Restore frame pointer via D0FRT or restore return address */
- +
- + if (non_leaf)
- + extras_gp |= REGNO_BIT (RETURN_POINTER_REGNUM);
- +
- + if (frame_pointer_needed)
- + extras_gp |= REGNO_BIT (TEMP_D0FRT_REGNUM);
- +
- + savesize_gp += UNITS_PER_WORD * 2;
- + }
- + else if (df_regs_ever_live_p (RETURN_POINTER_REGNUM))
- + {
- + extras_gp |= REGNO_BIT (RETURN_POINTER_REGNUM);
- +
- + /* Have to do at least one pop */
- + savesize_gp += UNITS_PER_WORD * 2;
- + }
- +
- + if (current_function_calls_eh_return)
- + {
- + unsigned int n;
- +
- + for (n = 0; n < NUM_EH_RETURN_DATA_REGS; n++)
- + {
- + unsigned int regno = EH_RETURN_DATA_REGNO (n);
- +
- + if (regno != INVALID_REGNUM)
- + {
- + unsigned int regbit = REGNO_BIT (regno);
- +
- + if ((extras_eh & regbit) == 0)
- + {
- + extras_eh |= regbit;
- + savesize_eh += UNITS_PER_WORD * 2;
- + }
- + }
- + }
- + }
- +
- + loads_pic_register = METAG_CURRENT_FUNCTION_LOADS_PIC_REGISTER ();
- + if (loads_pic_register)
- + picsize += UNITS_PER_WORD * 2;
- +
- + gcc_assert (cfun->machine->valid);
- + gcc_assert (cfun->machine->savesize_gp == savesize_gp);
- + gcc_assert (cfun->machine->savesize_eh == savesize_eh);
- + gcc_assert (cfun->machine->extras_gp == extras_gp);
- + gcc_assert (cfun->machine->extras_eh == extras_eh);
- + gcc_assert (cfun->machine->pic_save_size == picsize);
- + gcc_assert (cfun->machine->uses_pic_offset_table == current_function_uses_pic_offset_table);
- + gcc_assert (cfun->machine->loads_pic_register == loads_pic_register);
- +
- + if ((extras_gp & REGNO_BIT (RETURN_POINTER_REGNUM)) != 0)
- + {
- + rtx base;
- +
- + /* The return address is @ hard frame pointer + UNITS_PER_WORD */
- + if (frame_pointer_needed)
- + base = plus_constant (hard_frame_pointer_rtx, UNITS_PER_WORD);
- + else
- + base = plus_constant (stack_pointer_rtx,
- + -(HOST_WIDE_INT)(size + picsize + savesize_eh + savesize_gp - UNITS_PER_WORD));
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + gen_rtx_MEM (SImode, base),
- + source));
- + }
- + else
- + emit_insn (gen_rtx_SET (VOIDmode,
- + gen_rtx_REG (SImode, RETURN_POINTER_REGNUM),
- + source));
- +
- + return;
- +}
- +
- +bool
- +metag_doloop_loop_nest_optimized (struct loop * loop, struct doloopnest * nest)
- +{
- + for ( ; nest != NULL ; nest = nest->next)
- + if (nest->inner == loop)
- + return true;
- +
- + return false;
- +}
- +
- +bool
- +metag_doloop_check_any_nest_optimized (struct loop * loop, struct doloopnest * nest)
- +{
- + if (loop->inner == NULL)
- + /* Check if nest already has an optimized loop */
- + return metag_doloop_loop_nest_optimized (loop, nest);
- + else
- + {
- + struct loop* innerloops = loop->inner;
- +
- + for ( ; innerloops != NULL ; innerloops = innerloops->next)
- + if (metag_doloop_check_any_nest_optimized (innerloops, nest))
- + return true;
- + }
- +
- + return false;
- +}
- +
- +void
- +metag_doloop_mark_nests_optimized (struct loop * loop, struct doloopnest ** nest_p)
- +{
- + /* Check if the nest already has an optimized loop */
- + if (loop->inner == NULL)
- + {
- + while (*nest_p != NULL)
- + /* Find the end of the list of nests */
- + nest_p = &((*nest_p)->next);
- +
- + /* Add the new loop nest (innermost loop) to the list */
- + *nest_p = (struct doloopnest *)xmalloc (sizeof (struct doloopnest));
- + (*nest_p)->next = NULL;
- + (*nest_p)->inner = loop;
- + }
- + else
- + {
- + /* Process all inner siblings if this loop is not innermost */
- + struct loop* innerloops = loop->inner;
- +
- + for ( ; innerloops != NULL ; innerloops = innerloops->next)
- + metag_doloop_mark_nests_optimized (innerloops, nest_p);
- + }
- +}
- +
- +bool
- +metag_current_function_loads_pic_register (void)
- +{
- +#if 0
- + /* We need to perform more analysis and house keeping
- + before we can optimize the loading of PIC register
- + based on local/global properties of functions.
- +
- + At present we only mark functions to load the pic
- + register if it uses the PIC register, but this
- + doesn't interact correctly with the intended local/
- + global optimization.
- +
- + Consider
- +
- + extern int a;
- +
- + static void s(void) { a = 1; }
- +
- + void g (void) { s (); }
- +
- + We need g() to load/restore the PIC and s() to
- + inherit the PIC from g();
- +
- + */
- + if (flag_unit_at_a_time)
- + {
- + struct cgraph_local_info * local_info
- + = cgraph_local_info (current_function_decl);
- +
- + if (local_info && local_info->local)
- + return false;
- + }
- +#endif
- +
- + return current_function_uses_pic_offset_table;
- +}
- +
- +#define MODE_BASE_REG_CLASS(MODE) (MODE)
- +
- +rtx
- +metag_legitimize_reload_address (rtx x, enum machine_mode mode,
- + int opnum, int type,
- + int ind_levels ATTRIBUTE_UNUSED)
- +{
- + if (GET_CODE (x) == PLUS
- + && REG_P (XEXP (x, 0))
- + && IS_HARD_OR_VIRT_REGNO (REGNO (XEXP (x, 0)))
- + && METAG_LEGITIMATE_REG_P (XEXP (x, 0), TRUE)
- + && CONST_INT_P (XEXP (x, 1)))
- + {
- + if (!strict_memory_address_p (mode, x))
- + {
- +#if 0
- + unsigned int modesize = GET_MODE_SIZE (mode);
- + HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
- + HOST_WIDE_INT limit_top;
- + HOST_WIDE_INT limit_bot;
- + HOST_WIDE_INT delta;
- +
- + if (metag_reg12bit_op (XEXP (x, 0), mode))
- + limit_top = 2048 * modesize;
- + else
- + limit_top = 32 * modesize;
- +
- + limit_bot = -limit_top;
- + limit_top = (limit_top - 1) & ~(modesize - 1);
- +
- + if (limit_top <= value && value < limit_top + 255)
- + delta = limit_top;
- + else if (limit_bot - 255 <= value && value < -limit_bot)
- + delta = limit_bot;
- + else
- + delta = 0;
- +#endif
- +
- + x = gen_rtx_PLUS (GET_MODE (x),
- + gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
- + XEXP (x, 1)),
- + GEN_INT (0));
- + push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
- + MODE_BASE_REG_CLASS (mode), GET_MODE (x),
- + VOIDmode, 0, 0, opnum, type);
- +
- + return x;
- + }
- + }
- +
- + return NULL_RTX;
- +}
- +
- +bool
- +metag_offset6_mode (rtx op, enum machine_mode mode)
- +{
- + gcc_assert (CONST_INT_P (op));
- +
- + switch (mode)
- + {
- + case DImode:
- + return metag_offset6_di (op, mode);
- +
- + case SImode:
- + return metag_offset6_si (op, mode);
- +
- + case HImode:
- + return metag_offset6_hi (op, mode);
- +
- + case QImode:
- + return metag_offset6_qi (op, mode);
- +
- + case DFmode:
- + return metag_offset6_df (op, mode);
- +
- + case SFmode:
- + return metag_offset6_sf (op, mode);
- +
- + case V2SImode:
- + return metag_offset6_v2si (op, mode);
- +
- + case V2SFmode:
- + return metag_offset6_v2sf (op, mode);
- +
- + default:
- + gcc_unreachable ();
- + }
- +
- + return false;
- +}
- +
- +bool
- +metag_offset12_mode (rtx op, enum machine_mode mode)
- +{
- + gcc_assert (CONST_INT_P (op));
- +
- + switch (mode)
- + {
- + case DImode:
- + return metag_offset12_di (op, mode);
- +
- + case SImode:
- + return metag_offset12_si (op, mode);
- +
- + case HImode:
- + return metag_offset12_hi (op, mode);
- +
- + case QImode:
- + return metag_offset12_qi (op, mode);
- +
- + case DFmode:
- + return metag_offset12_df (op, mode);
- +
- + case SFmode:
- + return metag_offset12_sf (op, mode);
- +
- + case V2SImode:
- + return metag_offset12_v2si (op, mode);
- +
- + case V2SFmode:
- + return metag_offset12_v2sf (op, mode);
- +
- + default:
- + gcc_unreachable ();
- + }
- +
- + return false;
- +}
- +
- +bool
- +metag_regno12bit_p (unsigned int regno)
- +{
- + return regno == D0_0_REG || regno == D0_1_REG
- + || regno == D1_0_REG || regno == D1_1_REG
- + || regno == A0_0_REG || regno == A0_1_REG
- + || regno == A1_0_REG || regno == A1_1_REG;
- +}
- +
- +bool
- +metag_split_early (void)
- +{
- + return reload_completed;
- +}
- +
- +bool
- +metag_split_hi_lo_sum_early (void)
- +{
- + return reload_completed;
- +}
- +
- +void
- +metag_internal_label (FILE *file, const char *prefix, unsigned long labelno)
- +{
- + if (metag_ccfsm_state == 3
- + && (unsigned)metag_target_label == labelno
- + && strcmp (prefix, "L") == 0)
- + {
- + metag_ccfsm_state = 0;
- + metag_target_insn = NULL;
- + }
- +
- + default_internal_label (file, prefix, labelno);
- + return;
- +}
- +
- +bool
- +metag_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
- +{
- + if (GET_MODE_CLASS (mode) == MODE_CC)
- + return regno == MCC_REGNUM;
- + else if (regno == MCC_REGNUM)
- + return false;
- +
- + if (LAST_ADDR_REG < regno && regno < FIRST_FP_REG)
- + return mode == SImode;
- +
- + if (FIRST_FP_REG <= regno && regno <= LAST_FP_REG)
- + {
- + /* FP regs can hold anything that fits in a single reg or a pair */
- + if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
- + return true;
- + else
- + return ((regno - FIRST_FP_REG) & 1) == 0 && ((regno + HARD_REGNO_NREGS (regno, mode) - 1) <= LAST_FP_REG);
- + }
- +
- + if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
- + return true;
- + else
- + {
- + unsigned int last_permitted_reg = LAST_ADDR_REG;
- +
- + /* V2SI can only use data registers */
- + if (mode == V2SImode || mode == V2SFmode)
- + last_permitted_reg = LAST_DATA_REG;
- +
- + return ((regno <= last_permitted_reg && (regno & 1) == 0)) && ((regno + HARD_REGNO_NREGS (regno, mode) - 1) <= last_permitted_reg);
- + }
- +
- + return false;
- +}
- +
- +bool
- +metag_dsp_ri16_operands (rtx operands[])
- +{
- + int dunit0, dunit2;
- + int regno0, regno2;
- +
- + /* Reject if not all registers and also in DATA register class. */
- + if (!(REG_P (operands[0 ])
- + && METAG_DATA_REG_P (REGNO (operands[0 ]))
- + && REG_P (operands[0+2])
- + && METAG_DATA_REG_P (REGNO (operands[0+2]))
- + && GET_CODE (operands[1 ]) == CONST_INT
- + && metag_16bit_op (operands[1], GET_MODE (operands[1]))))
- + return false;
- +
- + dunit0 = METAG_DATAREG_UNIT (REGNO (operands[0 ]));
- + dunit2 = METAG_DATAREG_UNIT (REGNO (operands[0+2]));
- +
- + regno0 = METAG_DATAREG_REGN (REGNO (operands[0 ]));
- + regno2 = METAG_DATAREG_REGN (REGNO (operands[0+2]));
- +
- + /* Accept if register units and regno's match. */
- + return (dunit0 != dunit2 && regno0 == regno2);
- +
- +}
- +
- +bool
- +metag_dsp_rri5_operands (rtx operands[])
- +{
- + int dunit0, dunit1, dunit3, dunit4;
- + int regno0, regno1, regno3, regno4;
- +
- + /* Reject if not all registers and also in DATA register class. */
- + if (!(REG_P (operands[0 ])
- + && METAG_DATA_REG_P (REGNO (operands[0 ]))
- + && REG_P (operands[0+1])
- + && METAG_DATA_REG_P (REGNO (operands[0+1]))
- + && REG_P (operands[3+0])
- + && METAG_DATA_REG_P (REGNO (operands[3+0]))
- + && REG_P (operands[3+1])
- + && METAG_DATA_REG_P (REGNO (operands[3+1]))
- + && GET_CODE (operands[2 ]) == CONST_INT
- + && metag_5bit_op (operands[2], GET_MODE (operands[2]))))
- + return false;
- +
- + dunit0 = METAG_DATAREG_UNIT (REGNO (operands[0 ]));
- + dunit1 = METAG_DATAREG_UNIT (REGNO (operands[0+1]));
- + dunit3 = METAG_DATAREG_UNIT (REGNO (operands[3 ]));
- + dunit4 = METAG_DATAREG_UNIT (REGNO (operands[3+1]));
- +
- + regno0 = METAG_DATAREG_REGN (REGNO (operands[0 ]));
- + regno1 = METAG_DATAREG_REGN (REGNO (operands[0+1]));
- + regno3 = METAG_DATAREG_REGN (REGNO (operands[3 ]));
- + regno4 = METAG_DATAREG_REGN (REGNO (operands[3+1]));
- +
- + /* Reject if register units don't match. */
- + if (dunit0 != dunit1
- + || dunit3 != dunit4
- + || dunit0 == dunit3)
- + return false;
- +
- + /* Reject is dest registers don't match. */
- + if (regno0 != regno3)
- + return false;
- +
- + /* Accept if src register match. */
- + return (regno1 == regno4);
- +}
- +
- +bool
- +metag_dsp_rrr_operands (rtx operands[], bool commutable)
- +{
- + int dunit0, dunit1, dunit2, dunit3, dunit4, dunit5;
- + int regno0, regno1, regno2, regno3, regno4, regno5;
- +
- + /* Reject if not operands DATA registers. */
- + if (!(REG_P (operands[0 ])
- + && METAG_DATA_REG_P (REGNO (operands[0 ]))
- + && REG_P (operands[0+3])
- + && METAG_DATA_REG_P (REGNO (operands[0+3]))
- + && REG_P (operands[1 ])
- + && METAG_DATA_REG_P (REGNO (operands[1 ]))
- + && REG_P (operands[1+3])
- + && METAG_DATA_REG_P (REGNO (operands[1+3]))
- + && REG_P (operands[2])
- + && METAG_DATA_REG_P (REGNO (operands[2 ]))
- + && REG_P (operands[2+3])
- + && METAG_DATA_REG_P (REGNO (operands[2+3]))))
- + return false;
- +
- + dunit0 = METAG_DATAREG_UNIT (REGNO (operands[0 ]));
- + dunit1 = METAG_DATAREG_UNIT (REGNO (operands[1 ]));
- + dunit2 = METAG_DATAREG_UNIT (REGNO (operands[2 ]));
- +
- + dunit3 = METAG_DATAREG_UNIT (REGNO (operands[0+3]));
- + dunit4 = METAG_DATAREG_UNIT (REGNO (operands[1+3]));
- + dunit5 = METAG_DATAREG_UNIT (REGNO (operands[2+3]));
- +
- + regno0 = METAG_DATAREG_REGN (REGNO (operands[0 ]));
- + regno1 = METAG_DATAREG_REGN (REGNO (operands[1 ]));
- + regno2 = METAG_DATAREG_REGN (REGNO (operands[2 ]));
- +
- + regno3 = METAG_DATAREG_REGN (REGNO (operands[0+3]));
- + regno4 = METAG_DATAREG_REGN (REGNO (operands[1+3]));
- + regno5 = METAG_DATAREG_REGN (REGNO (operands[2+3]));
- +
- + /* Reject if register units don't match. */
- + if (dunit0 != dunit1
- + || dunit1 != dunit2
- + || dunit3 != dunit4
- + || dunit4 != dunit5
- + || dunit0 == dunit3)
- + return false;
- +
- + /* Reject is dest registers don't match. */
- + if (regno0 != regno3)
- + return false;
- +
- + /* Accept if src register match. */
- + return ((regno1 == regno4 && regno2 == regno5)
- + || (commutable
- + && (regno1 == regno5 && regno2 == regno4)));
- +}
- +
- +bool
- +metag_dsp_rrr_mov_operands (rtx operands[], bool commutable)
- +{
- + int dunit1, dunit2, dunit4, dunit5, dunit6, dunit7;
- + int regno1, regno2, regno4, regno5, regno6, regno7;
- +
- + /* Reject if not operands DATA registers. */
- + if (!(REG_P (operands[0 ])
- + && REG_P (operands[0+3])
- + && REG_P (operands[1 ])
- + && METAG_DATA_REG_P (REGNO (operands[1 ]))
- + && REG_P (operands[1+3])
- + && METAG_DATA_REG_P (REGNO (operands[1+3]))
- + && REG_P (operands[2])
- + && METAG_DATA_REG_P (REGNO (operands[2 ]))
- + && REG_P (operands[2+3])
- + && METAG_DATA_REG_P (REGNO (operands[2+3]))
- + && REG_P (operands[0+6])
- + && METAG_DATA_REG_P (REGNO (operands[0+6]))
- + && REG_P (operands[1+6])
- + && METAG_DATA_REG_P (REGNO (operands[1+6]))))
- + return false;
- +
- + dunit1 = METAG_DATAREG_UNIT (REGNO (operands[1 ]));
- + dunit2 = METAG_DATAREG_UNIT (REGNO (operands[2 ]));
- + dunit4 = METAG_DATAREG_UNIT (REGNO (operands[1+3]));
- + dunit5 = METAG_DATAREG_UNIT (REGNO (operands[2+3]));
- + dunit6 = METAG_DATAREG_UNIT (REGNO (operands[6 ]));
- + dunit7 = METAG_DATAREG_UNIT (REGNO (operands[7 ]));
- +
- + regno1 = METAG_DATAREG_REGN (REGNO (operands[1 ]));
- + regno2 = METAG_DATAREG_REGN (REGNO (operands[2 ]));
- + regno4 = METAG_DATAREG_REGN (REGNO (operands[1+3]));
- + regno5 = METAG_DATAREG_REGN (REGNO (operands[2+3]));
- + regno6 = METAG_DATAREG_REGN (REGNO (operands[0+6]));
- + regno7 = METAG_DATAREG_REGN (REGNO (operands[1+6]));
- +
- + /* Reject if register units don't match */
- + if ( dunit1 != dunit2
- + || dunit1 != dunit6
- + || dunit4 != dunit5
- + || dunit4 != dunit7
- + || dunit6 == dunit7)
- + return false;
- +
- + /* Reject is dest registers don't match. */
- + if (regno6 != regno7)
- + return false;
- +
- + /* Accept if src register's match. */
- + return ((regno1 == regno4 && regno2 == regno5)
- + || (commutable
- + && (regno1 == regno5 && regno2 == regno4)));
- +}
- +
- +bool
- +metag_dsp_rr_operands (rtx operands[])
- +{
- + int dunit0, dunit1, dunit2, dunit3;
- + int regno0, regno1, regno2, regno3;
- +
- + /* Reject if not all are registers and also in DATA register class. */
- + if (!(REG_P (operands[0 ])
- + && METAG_DATA_REG_P (REGNO (operands[0 ]))
- + && REG_P (operands[0+2])
- + && METAG_DATA_REG_P (REGNO (operands[0+2]))
- + && REG_P (operands[1 ])
- + && METAG_DATA_REG_P (REGNO (operands[1 ]))
- + && REG_P (operands[1+2])
- + && METAG_DATA_REG_P (REGNO (operands[1+2]))))
- + return false;
- +
- + dunit0 = METAG_DATAREG_UNIT (REGNO (operands[0 ]));
- + dunit1 = METAG_DATAREG_UNIT (REGNO (operands[1 ]));
- + dunit2 = METAG_DATAREG_UNIT (REGNO (operands[0+2]));
- + dunit3 = METAG_DATAREG_UNIT (REGNO (operands[1+2]));
- +
- + regno0 = METAG_DATAREG_REGN (REGNO (operands[0 ]));
- + regno1 = METAG_DATAREG_REGN (REGNO (operands[1 ]));
- + regno2 = METAG_DATAREG_REGN (REGNO (operands[0+2]));
- + regno3 = METAG_DATAREG_REGN (REGNO (operands[1+2]));
- +
- + /* Accept if register units and regno's match. */
- + return ( dunit0 == dunit1
- + && dunit2 == dunit3
- + && dunit0 != dunit2
- + && regno0 == regno2
- + && regno1 == regno3);
- +}
- +
- +bool
- +metag_dsp_rr_rr_mov_operands (rtx operands[])
- +{
- + int dunit1, dunit3, dunit4, dunit5;
- + int regno1, regno3, regno4, regno5;
- +
- + /* Reject if not operands DATA registers. */
- + if (!(REG_P (operands[0 ])
- + && REG_P (operands[0+2])
- + && REG_P (operands[1 ])
- + && METAG_DATA_REG_P (REGNO (operands[1 ]))
- + && REG_P (operands[1+2])
- + && METAG_DATA_REG_P (REGNO (operands[1+2]))
- + && REG_P (operands[0+4])
- + && METAG_DATA_REG_P (REGNO (operands[0+4]))
- + && REG_P (operands[1+4])
- + && METAG_DATA_REG_P (REGNO (operands[1+4]))))
- + return false;
- +
- + dunit1 = METAG_DATAREG_UNIT (REGNO (operands[1 ]));
- + dunit3 = METAG_DATAREG_UNIT (REGNO (operands[1+2]));
- + dunit4 = METAG_DATAREG_UNIT (REGNO (operands[4 ]));
- + dunit5 = METAG_DATAREG_UNIT (REGNO (operands[5 ]));
- +
- + regno1 = METAG_DATAREG_REGN (REGNO (operands[1 ]));
- + regno3 = METAG_DATAREG_REGN (REGNO (operands[1+2]));
- + regno4 = METAG_DATAREG_REGN (REGNO (operands[0+4]));
- + regno5 = METAG_DATAREG_REGN (REGNO (operands[1+4]));
- +
- + /* Accept if register units and regno's match. */
- + return ( dunit4 == dunit1
- + && dunit5 == dunit3
- + && dunit4 != dunit5
- + && regno4 == regno5
- + && regno5 == regno3
- + && regno4 == regno5);
- +}
- +
- +/* This function sets operands 2,3 to support both flag setting and non flag
- + setting dsp peephole 2 transformations */
- +void
- +metag_dsp_peephole2_rr_convert (rtx operands[])
- +{
- + int adjust = 0;
- +
- + if (REGNO (operands[0]) > REGNO (operands[0+2]))
- + adjust = 2;
- +
- + operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0 + adjust]));
- + operands[3] = gen_rtx_REG (V2SImode, REGNO (operands[1 + adjust]));
- +}
- +
- +void
- +metag_dsp_peephole2_rr_mov_convert (rtx operands[])
- +{
- + int adjustin = 0;
- + int adjustout = 0;
- +
- + if (REGNO (operands[1]) > REGNO (operands[1+2]))
- + {
- + adjustin = 2;
- + adjustout = 1;
- + }
- + operands[4] = gen_rtx_REG (V2SImode, REGNO (operands[4 + adjustout]));
- + operands[1] = gen_rtx_REG (V2SImode, REGNO (operands[1 + adjustin]));
- +}
- +
- +/* This function sets operands 3,4,5 to support both flag setting and non flag
- + setting dsp peephole 2 transformations */
- +void
- +metag_dsp_peephole2_rrr_convert (rtx operands[])
- +{
- + int adjust = 0;
- +
- + if (REGNO (operands[0]) > REGNO (operands[0+3]))
- + adjust = 3;
- +
- + operands[3] = gen_rtx_REG (V2SImode, REGNO (operands[0 + adjust]));
- + operands[4] = gen_rtx_REG (V2SImode, REGNO (operands[1 + adjust]));
- + operands[5] = gen_rtx_REG (V2SImode, REGNO (operands[2 + adjust]));
- +}
- +
- +void
- +metag_dsp_peephole2_rrr_mov_convert (rtx operands[])
- +{
- + int adjustin = 0;
- + int adjustout = 0;
- +
- + /* Operands 0 and 3 are not related in this case */
- + if (REGNO (operands[1]) > REGNO (operands[1+3]))
- + {
- + adjustin = 3;
- + adjustout = 1;
- + }
- + operands[6] = gen_rtx_REG (V2SImode, REGNO (operands[6 + adjustout]));
- + operands[1] = gen_rtx_REG (V2SImode, REGNO (operands[1 + adjustin]));
- + operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[2 + adjustin]));
- +}
- +
- +/* This function sets operands 2 and 3 to support both flag setting and non flag
- + setting dsp peephole 2 transformations */
- +void
- +metag_dsp_peephole2_ri16_convert (rtx operands[])
- +{
- + int adjust = 0;
- +
- + if (REGNO (operands[0]) > REGNO (operands[0+2]))
- + adjust = 2;
- +
- + operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0 + adjust]));
- + operands[3] = gen_rtx_CONST_VECTOR (V2SImode,
- + gen_rtvec (2, operands[1], operands[1]));
- +}
- +
- +/* This function sets operands 3,4,5 to support both flag setting and non flag
- + setting dsp peephole 2 transformations */
- +void
- +metag_dsp_peephole2_rri5_convert (rtx operands[])
- +{
- + int adjust = 0;
- +
- + if (REGNO (operands[0]) > REGNO (operands[0+3]))
- + adjust = 3;
- +
- + operands[3] = gen_rtx_REG (V2SImode, REGNO (operands[0 + adjust]));
- + operands[4] = gen_rtx_REG (V2SImode, REGNO (operands[1 + adjust]));
- + operands[5] = gen_rtx_CONST_VECTOR (V2SImode,
- + gen_rtvec (2, operands[2], operands[2]));
- +}
- +
- +bool
- +metag_move_valid_p (rtx to, rtx from)
- +{
- + gcc_assert (reload_completed);
- +
- + if (REG_P (from))
- + {
- + if (METAG_FPC_REG_P (REGNO (from)) && METAG_ADDR_REG_P (REGNO (to)))
- + return false;
- + else if (METAG_ADDR_REG_P (REGNO (from)) && METAG_FPC_REG_P (REGNO (to)))
- + return false;
- + }
- + else if (CONST_INT_P (from))
- + {
- + if (METAG_FPC_REG_P (REGNO (to)))
- + return false;
- + }
- +
- + return true;
- +}
- +
- +#define builtin_define(TXT) cpp_define (pfile, TXT)
- +#define builtin_assert(TXT) cpp_assert (pfile, TXT)
- +
- +void
- +metag_cpu_cpp_builtins (cpp_reader *pfile)
- +{
- + switch (metac_target)
- + {
- + case METAC_0_1_ID:
- + builtin_define ("METAC_0_1");
- + break;
- + case METAC_1_0_ID:
- + builtin_define ("METAC_1_0");
- + break;
- + case METAC_1_1_ID:
- + builtin_define ("METAC_1_1");
- + break;
- + case METAC_1_2_ID:
- + builtin_define ("METAC_1_2");
- + break;
- + case METAC_2_1_ID:
- + builtin_define ("METAC_2_1");
- + break;
- + }
- +
- + switch (metacore)
- + {
- + case METACORE_METAC_0_1:
- + builtin_define ("METAC_TUNE_0_1");
- + break;
- + case METACORE_METAC_1_0:
- + builtin_define ("METAC_TUNE_1_0");
- + break;
- + case METACORE_METAC_1_1:
- + builtin_define ("METAC_TUNE_1_1");
- + break;
- + case METACORE_METAC_1_2:
- + builtin_define ("METAC_TUNE_1_2");
- + break;
- + case METACORE_METAC_2_1:
- + builtin_define ("METAC_TUNE_2_1");
- + break;
- + }
- +
- + if (TARGET_FPU)
- + {
- + builtin_define ("METAC_FPU_FLOAT");
- +
- + if (TARGET_FPU_SIMD)
- + builtin_define ("METAC_FPU_LFLOAT");
- +
- + if (!metag_fpu_single)
- + builtin_define ("METAC_FPU_DOUBLE");
- + }
- +
- + if (strcmp (metag_charset_string, "basic") == 0)
- + builtin_define ("strcmp=strcmpbcs");
- +
- + if (TARGET_MINIM)
- + builtin_define ("METAC_MINIM_ENC");
- +
- + if (metag_memory_width == 32)
- + builtin_define ("METAC_MEMW_32");
- + else if (metag_memory_width == 64)
- + builtin_define ("METAC_MEMW_64");
- +
- + builtin_define ("__metag__");
- + builtin_define ("__METAG__");
- + builtin_define ("__METAG");
- +
- + builtin_define ("METAG");
- +
- + builtin_assert ("cpu=metag");
- + builtin_assert ("machine=metag");
- +}
- +
- +void
- +metag_expand_didf2 (rtx out, rtx in)
- +{
- + rtx dscr = gen_reg_rtx (DImode);
- + rtx dscrhi = gen_rtx_SUBREG (SImode, dscr, 4);
- + rtx fscr2 = gen_reg_rtx (DFmode);
- + rtx fscr2hi_as_si = gen_rtx_SUBREG (SImode, fscr2, 4);
- + rtx fscr2lo_as_si = gen_rtx_SUBREG (SImode, fscr2, 0);
- + rtx operands[1];
- +
- + /* Test to see if rs is in the difficult range (> 2^63) */
- + emit_move_insn (dscr, in);
- + metag_compare_op0 = gen_rtx_AND (SImode, dscrhi,
- + gen_int_mode (0x80000000, SImode));
- + metag_compare_op1 = const0_rtx;
- + gen_metag_compare (NE, operands, 0);
- +
- + /* Drop the 2^63 component */
- + emit_insn (gen_andsi3 (dscrhi, dscrhi,
- + gen_int_mode (0x7fffffff, SImode)));
- +
- + /* Convert to double */
- + emit_insn (gen_floatdidf2 (out, dscr));
- +
- + /* Prepare 2^63 in double precision */
- + emit_move_insn (fscr2hi_as_si,
- + gen_int_mode (0x43e00000, SImode));
- + emit_move_insn (fscr2lo_as_si, GEN_INT (0x0));
- +
- + /* Add on the missing 2^63 if requried */
- + emit_insn (gen_rtx_SET (VOIDmode, out,
- + gen_rtx_IF_THEN_ELSE (DFmode,
- + gen_rtx_NE (VOIDmode, operands[0],
- + const0_rtx),
- + gen_rtx_PLUS (DFmode, out, fscr2),
- + out)));
- +
- +
- +}
- +
- +#define PRAGMA_JUMP_TABLE_BRANCH_WARNING() \
- + do { \
- + warning (OPT_Wpragmas, "Incorrect syntax for '#pragma mjump-table-branch=small|large|auto'"); \
- + return; \
- + } while (0)
- +
- +void
- +metag_pragma_jump_table_branch (struct cpp_reader* pFile ATTRIBUTE_UNUSED)
- +{
- + tree x;
- + const char * option = NULL;
- +
- + if (pragma_lex (&x) != CPP_MINUS)
- + PRAGMA_JUMP_TABLE_BRANCH_WARNING ();
- +
- + if (pragma_lex (&x) != CPP_NAME || strncmp (IDENTIFIER_POINTER (x), "table", 5) != 0)
- + PRAGMA_JUMP_TABLE_BRANCH_WARNING ();
- +
- + if (pragma_lex (&x) != CPP_MINUS)
- + PRAGMA_JUMP_TABLE_BRANCH_WARNING ();
- +
- + if (pragma_lex (&x) != CPP_NAME || strncmp (IDENTIFIER_POINTER (x), "branch", 6) != 0)
- + PRAGMA_JUMP_TABLE_BRANCH_WARNING ();
- +
- + if (pragma_lex (&x) != CPP_EQ)
- + PRAGMA_JUMP_TABLE_BRANCH_WARNING ();
- +
- + if (pragma_lex (&x) != CPP_NAME)
- + PRAGMA_JUMP_TABLE_BRANCH_WARNING ();
- +
- + option = IDENTIFIER_POINTER (x);
- +
- + if (pragma_lex (&x) != CPP_EOF)
- + PRAGMA_JUMP_TABLE_BRANCH_WARNING ();
- +
- + if (strncmp (option, "short", 5) == 0)
- + metag_jump_table_branch = METAG_MINIM_JUMP_TABLE_BRANCH_SHORT;
- + else if (strncmp (option, "long", 4) == 0)
- + metag_jump_table_branch = METAG_MINIM_JUMP_TABLE_BRANCH_LONG;
- + else if (strncmp (option, "auto", 4) == 0)
- + metag_jump_table_branch = METAG_MINIM_JUMP_TABLE_BRANCH_AUTO;
- + else if (strncmp (option, "default", 7) == 0)
- + {
- + if (strncmp (metag_jump_table_string, "short", 5) == 0)
- + metag_jump_table_branch = METAG_MINIM_JUMP_TABLE_BRANCH_SHORT;
- + else if (strncmp (metag_jump_table_string, "long", 4) == 0)
- + metag_jump_table_branch = METAG_MINIM_JUMP_TABLE_BRANCH_LONG;
- + else if (strncmp (metag_jump_table_string, "auto", 4) == 0)
- + metag_jump_table_branch = METAG_MINIM_JUMP_TABLE_BRANCH_AUTO;
- + }
- + else
- + PRAGMA_JUMP_TABLE_BRANCH_WARNING ();
- +}
- +
- +#define PRAGMA_HWTRACE_SYNTAX_ERROR() \
- + do { \
- + warning (OPT_Wpragmas, "Incorrect syntax for '#pragma hwtrace_function (func|*,0|1)"); \
- + return; \
- + } while (0)
- +
- +
- +void
- +metag_pragma_hwtrace_function (struct cpp_reader* pFile ATTRIBUTE_UNUSED)
- +{
- + tree x;
- + const char * name = NULL;
- + int onoff;
- +
- + if (pragma_lex (&x) != CPP_OPEN_PAREN)
- + PRAGMA_HWTRACE_SYNTAX_ERROR ();
- +
- + switch (pragma_lex (&x))
- + {
- + case CPP_MULT:
- + name = "*";
- + break;
- + case CPP_NAME:
- + name = IDENTIFIER_POINTER (x);
- + break;
- + default:
- + PRAGMA_HWTRACE_SYNTAX_ERROR ();
- + }
- +
- + if (pragma_lex (&x) != CPP_COMMA)
- + PRAGMA_HWTRACE_SYNTAX_ERROR ();
- +
- + if (pragma_lex (&x) != CPP_NUMBER)
- + PRAGMA_HWTRACE_SYNTAX_ERROR ();
- +
- + if (TREE_CODE (x) != INTEGER_CST)
- + PRAGMA_HWTRACE_SYNTAX_ERROR ();
- +
- + onoff = TREE_INT_CST_LOW (x);
- +
- + if (pragma_lex (&x) != CPP_CLOSE_PAREN)
- + PRAGMA_HWTRACE_SYNTAX_ERROR ();
- +
- + if (pragma_lex (&x) != CPP_EOF)
- + PRAGMA_HWTRACE_SYNTAX_ERROR ();
- +
- + if (strcmp (name, "*") == 0)
- + hwtrace_function_default = onoff ? 1 : 0;
- + else
- + {
- + hwtrace_fn * new_fn = xmalloc (sizeof (hwtrace_fn));
- +
- + new_fn->name = xstrdup (name);
- + new_fn->onoff = onoff ? 1 : 0;
- + new_fn->next = hwtrace_function_list;
- +
- + hwtrace_function_list = new_fn;
- + }
- +}
- +
- +/* Determine if 'label_ref' refers to a label in the current function */
- +void
- +metag_can_use_short_branch (void)
- +{
- + /* Once we have determined that we can use a short branch there is no need
- + to check again. We re-do the check if only long branches are allowed
- + even though the decision will not change */
- + if (!cfun->machine->can_use_short_branch)
- + {
- + /* Do the analysis */
- + rtx insn = next_active_insn (get_insns());
- + int count = 0;
- +
- + while (insn)
- + {
- + rtx body = PATTERN (insn);
- + /* Inline assembler... Take a best guess at the instruction count
- + then multiply by 8 to assume all insns need long encodings */
- + if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
- + count += (metag_asm_insn_count (body) << 3);
- + else if (GET_CODE (body) == ADDR_DIFF_VEC)
- + {
- + int i;
- + /* Add in the branches in jump tables */
- + for (i = 0 ; i < XVECLEN (body, 1) ; i++)
- + {
- + /* If a label is within the function it 'can' be short
- + encoded therefore it takes up 4 bytes of PC address
- + space. If a label is not within the function then
- + branch tables must be long encoded */
- + if (metag_is_label_within_function (XVECEXP (body, 1, i)))
- + count += 4;
- + else
- + {
- + count += 2049;
- + break;
- + }
- + }
- + }
- + else if (GET_CODE (body) != UNSPEC_VOLATILE
- + || XINT (body, 1) != VUNSPEC_BLOCKAGE)
- + /* *2 for each instruction to make them 'long' */
- + count += (get_attr_length (insn) << 1);
- +
- + insn = next_active_insn (insn);
- +
- + if (count > 2048)
- + break;
- + }
- +
- + /* 2048 is the number of bytes in PC address space that a short
- + branch can jump forward or backwards to. The 'count' variable
- + conservatively counts the number of bytes in the function
- + assuming all instructions will be double their stated size,
- + (double being a long MiniM encoding) */
- +
- + cfun->machine->can_use_short_branch = (count <= 2048);
- + }
- +}
- +
- +static bool
- +metag_is_label_within_function (rtx label_ref)
- +{
- + rtx insn = get_insns();
- +
- + while ((insn = next_label (insn)) != 0)
- + if (CODE_LABEL_NUMBER (insn) == CODE_LABEL_NUMBER (XEXP (label_ref, 0)))
- + return true;
- +
- + return false;
- +}
- +
- +static int
- +metag_asm_insn_count (rtx body)
- +{
- + const char *template;
- + int count = 1;
- +
- + if (GET_CODE (body) == ASM_INPUT)
- + template = XSTR (body, 0);
- + else
- + template = decode_asm_operands (body, NULL, NULL, NULL, NULL);
- +
- + for (; *template; template++)
- + if (IS_ASM_LOGICAL_LINE_SEPARATOR (*template) || *template == '\n')
- + count++;
- +
- + return count;
- +}
- +
- +/* Generate a conditional branch instruction, inserting the label number for
- + the return stub */
- +char *
- +metag_gen_cond_return_branch (const char * pattern)
- +{
- + int length = strlen(pattern) + 21;
- + char * buf = xmalloc (length);
- +
- + snprintf (buf, length, pattern, cfun->funcdef_no);
- +
- + if (cfun->machine->cond_return_state == METAG_COND_RETURN_NONE)
- + cfun->machine->cond_return_state = METAG_COND_RETURN_REQD;
- +
- + return buf;
- +}
- +
- +/* Generate the return stub instruction inserting the label number for the
- + return stub */
- +char *
- +metag_gen_cond_return_stub (void)
- +{
- + static const char * pattern = "$LX%d:\n\tMOV\tPC, D1RtP";
- + int length = strlen(pattern) + 21;
- + char * buf = xmalloc (length);
- +
- + snprintf (buf, length, pattern, cfun->funcdef_no);
- +
- + cfun->machine->cond_return_state = METAG_COND_RETURN_DONE;
- +
- + return buf;
- +}
- +
- +/* Create a stub at the end of a function if one is required and not already
- + emitted. */
- +void
- +metag_emit_cond_return_stub_if_reqd (void)
- +{
- + if (cfun->machine->cond_return_state == METAG_COND_RETURN_REQD)
- + {
- + char * stub = metag_gen_cond_return_stub ();
- +
- + fputs (stub, asm_out_file);
- + fputc ('\n', asm_out_file);
- + cfun->machine->cond_return_state = METAG_COND_RETURN_DONE;
- +
- + free (stub);
- + }
- +}
- +
- +bool
- +metag_output_addr_const_extra (FILE * stream, rtx x)
- +{
- + if (GET_CODE(x) == CONST_VECTOR && GET_MODE(x) == V2SImode)
- + {
- + /* WORK NEEDED: Assert more rigourously that the values are identical */
- + gcc_assert (INTVAL (CONST_VECTOR_ELT (x, 0)) == INTVAL (CONST_VECTOR_ELT (x, 1)));
- + output_addr_const (stream, CONST_VECTOR_ELT (x, 0));
- + return true;
- + }
- + return false;
- +}
- +
- +/* Produces a rtx representing the return register (D0Re0) using the correct mode. */
- +rtx
- +metag_function_return_reg (enum machine_mode mode)
- +{
- + if (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
- + return gen_rtx_REG (SImode, D0Re0_REG);
- + else
- + return gen_rtx_REG (mode, D0Re0_REG);
- +}
- +
- +rtx
- +metag_libcall_value (enum machine_mode mode)
- +{
- + return metag_function_return_reg (mode);
- +}
- +
- +rtx
- +metag_function_value (tree ret_type, tree fn_decl_or_type ATTRIBUTE_UNUSED, bool outgoing ATTRIBUTE_UNUSED)
- +{
- + return metag_function_return_reg (TYPE_MODE (ret_type));
- +}
- +
- +#include "gt-metag.h"
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/metag.h gcc-4.2.4/gcc/config/metag/metag.h
- --- gcc-4.2.4.orig/gcc/config/metag/metag.h 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/metag.h 2015-07-03 18:46:05.765283542 -0500
- @@ -0,0 +1,1955 @@
- +/* Definitions of target machine for GNU compiler.
- + Imagination Technologies Meta version.
- + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
- + Imagination Technologies Ltd
- +
- +This file is part of GCC.
- +
- +GCC 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 3, or (at your option) any later
- +version.
- +
- +GCC 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 GCC; see the file COPYING3. If not see
- +<http://www.gnu.org/licenses/>. */
- +
- +#ifndef __METAG_H_
- +#define __METAG_H_
- +
- +#define USE_EH_FRAME_REGISTRY
- +
- +/* Which processor to schedule for. The metacore attribute defines a list that
- + mirrors this list, so changes to metag.md must be made at the same time. */
- +
- +enum processor_type
- +{
- + PROCESSOR_METAC_1_0,
- + PROCESSOR_METAC_1_1,
- + PROCESSOR_METAC_1_2,
- + PROCESSOR_METAC_0_1,
- + PROCESSOR_METAC_2_1,
- + PROCESSOR_METAC_MAX
- +};
- +
- +/* Support for a compile-time default CPU, et cetera. The rules are:
- + --with-cpu is ignored if -mmetac is specified.
- + --with-tune is ignored if -mtune is specified. */
- +#define OPTION_DEFAULT_SPECS \
- + {"cpu", "%{!mmetac=*:-mmetac=%(VALUE)}" }, \
- + {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
- + {"fpu", "%{mhard-float|mhard-float=*|msoft-float|msimd-float:; :-mhard-float=%(VALUE)}" } \
- +
- +/* Handle the pragma to alter the default jump_table_branch size. */
- +#define REGISTER_TARGET_PRAGMAS() \
- + do { \
- + c_register_pragma (0, "mjump", metag_pragma_jump_table_branch); \
- + c_register_pragma (0, "hwtrace_function", metag_pragma_hwtrace_function); \
- + } while (0)
- +
- +#define SYMBOL_REF_P(RTX) (GET_CODE (RTX) == SYMBOL_REF)
- +#define LABEL_REF_P(RTX) (GET_CODE (RTX) == LABEL_REF)
- +#define CONST_DOUBLE_P(RTX) (GET_CODE (RTX) == CONST_DOUBLE)
- +#define SUBREG_P(RTX) (GET_CODE (RTX) == SUBREG)
- +
- +#define TARGET_USE_JCR_SECTION 0
- +
- +#define TARGET_LIBGCC_SDATA_SECTION DATA_SECTION_ASM_OP
- +
- +#define TARGET_FAST_MATH fast_math_flags_set_p ()
- +
- +#define DWARF2_UNWIND_INFO 1
- +
- +#define NUM_EH_RETURN_DATA_REGS \
- + (EH_RETURN_LAST_DATA_REG - EH_RETURN_FIRST_DATA_REG + 1)
- +
- +#define EH_RETURN_DATA_REGNO(N) \
- + ((N) < NUM_EH_RETURN_DATA_REGS \
- + ? EH_RETURN_FIRST_DATA_REG + (N) : INVALID_REGNUM)
- +
- +#define EH_RETURN_STACKADJ_RTX \
- + gen_rtx_REG (SImode, EH_RETURN_STACKADJ_REG)
- +
- +#define DWARF_FRAME_REGISTERS (2 + 8 + 3)
- +
- +/* An optimisation for reducing the size of an unwind table. Only registers
- + * that will be present in a frame are included
- + *
- + * D1.0 and D1.1 are present as they are the EH_RETURN data registers
- + * D0FrT and D1RtP because they store the frame pointer and return address
- + * D1Ar1 -> D0Ar6 are the call save registers
- + * A1LbP is present as it is the PIC register for META Linux
- + * A0StP and A0FrP are obvious!
- + *
- + * D0.8 is not included as it is not applicable to Linux and the relevant
- + * code that refers to this table is not currently used in the embedded
- + * toolchain
- + */
- +
- +#define DWARF_REG_TO_UNWIND_COLUMN_TABLE \
- +static signed char const dwarf_reg_to_unwind_column[FIRST_PSEUDO_REGISTER + 1] =\
- +{ \
- + /* D0_0/D1_0 ... D0_7/D1_7 */ \
- + -1, -1, 0, 1, -1, -1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9, \
- + /* D0_8/D1_8 ... D0_15/D1_15 */ \
- + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
- + /* A0_0/A1_0 .. A0_7/A1_7 */ \
- + 10, -1, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
- + /* FRAME ... TXRPT */ \
- + -1, -1, -1, -1, -1, -1, -1, -1, -1, \
- + /* FX */ \
- + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
- + /* TTREC(L) */ \
- + -1, -1 \
- +}
- +
- +#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) \
- + dwarf_reg_to_unwind_column[REGNO]
- +
- +/* We're using ELF files */
- +
- +#define OBJECT_FORMAT_ELF
- +
- +#ifndef CPP_SUBTARGET_SPEC
- +#define CPP_SUBTARGET_SPEC ""
- +#endif
- +
- +#undef CPP_SPEC
- +#define CPP_SPEC \
- + "%(cpp_cpu_arch) " \
- + "%(cpp_subtarget) " \
- + "%{pthread: -D_THREAD_SAFE} "
- +
- +#define CPP_CPU_ARCH_SPEC ""
- +
- +#ifndef SUBTARGET_EXTRA_SPECS
- +#define SUBTARGET_EXTRA_SPECS
- +#endif
- +
- +#ifndef SUBTARGET_CPP_SPEC
- +#define SUBTARGET_CPP_SPEC ""
- +#endif
- +
- +/* This macro defines names of additional specifications to put in the specs
- + that can be used in various specifications like CC1_SPEC. Its definition
- + is an initializer with a subgrouping for each command option.
- +
- + Each subgrouping contains a string constant, that defines the
- + specification name, and a string constant that used by the GNU CC driver
- + program.
- +
- + Do not define this macro if it does not need to do anything. */
- +
- +#define EXTRA_SPECS \
- + { "metac_default", METAC_DEFAULT }, \
- + { "cpp_cpu_arch", CPP_CPU_ARCH_SPEC }, \
- + { "cpp_subtarget", CPP_SUBTARGET_SPEC }, \
- + { "subtarget_cpp_spec", SUBTARGET_CPP_SPEC }, \
- + SUBTARGET_EXTRA_SPECS
- +
- +/* Run-time compilation parameters selecting different hardware subsets. */
- +
- +extern int frame_pointer_needed;
- +extern int target_flags;
- +
- +/* Define the information needed to expand branch insns. This is stored from
- + the previous compare operation - which we do not expand at all! */
- +extern GTY(()) rtx metag_compare_op0;
- +extern GTY(()) rtx metag_compare_op1;
- +
- +/* Macros used in the machine description to test the flags. */
- +
- +extern int optimize;
- +
- +#define TARGET_COND_EXEC_OPTIMIZE (optimize && TARGET_COND_EXEC)
- +#define TARGET_MINIM_CORE (TARGET_MINIM && TARGET_MINIM_OPTIMISE)
- +
- +enum metag_jump_table_branch
- +{
- + METAG_MINIM_JUMP_TABLE_BRANCH_AUTO,
- + METAG_MINIM_JUMP_TABLE_BRANCH_LONG,
- + METAG_MINIM_JUMP_TABLE_BRANCH_SHORT
- +};
- +
- +extern int metag_fpu_single;
- +extern enum metag_jump_table_branch metag_jump_table_branch;
- +extern int metag_fpu_resources;
- +extern int metag_force_tbictxsave;
- +
- +/* Access Models
- +
- + The __model__ attribute can be used to select the code model to use when
- + accessing particular objects. */
- +
- +enum metag_model { METAG_MODEL_SMALL, METAG_MODEL_LARGE };
- +
- +extern enum metag_model metag_model;
- +#define TARGET_MODEL_SMALL (metag_model == METAG_MODEL_SMALL)
- +#define TARGET_MODEL_LARGE (metag_model == METAG_MODEL_LARGE)
- +
- +/* Target options */
- +enum metac_target
- +{
- + METAC_1_0_ID,
- + METAC_1_1_ID,
- + METAC_1_2_ID,
- + METAC_0_1_ID,
- + METAC_2_1_ID
- +};
- +
- +extern enum metac_target metac_target;
- +
- +#define TARGET_METAC_0_1 \
- + (metac_target == METAC_0_1_ID)
- +
- +#define TARGET_METAC_1_0 \
- + (metac_target == METAC_1_0_ID)
- +
- +#define TARGET_METAC_1_1 \
- + (metac_target == METAC_1_1_ID || metac_target == METAC_1_2_ID || \
- + metac_target == METAC_0_1_ID || metac_target == METAC_2_1_ID)
- +
- +#define TARGET_METAC_1_2 \
- + (metac_target == METAC_1_2_ID || metac_target == METAC_0_1_ID \
- + metac_target == METAC_2_1_ID)
- +
- +#define TARGET_METAC_2_1 \
- + (metac_target == METAC_2_1_ID)
- +
- +/* target machine storage layout */
- +
- +/* Define this if most significant bit is lowest numbered
- + in instructions that operate on numbered bit-fields. */
- +#define BITS_BIG_ENDIAN 0
- +
- +/* Define this if most significant byte of a word is the lowest numbered. */
- +#define BYTES_BIG_ENDIAN 0
- +
- +/* Define this if most significant word of a multiword is lowest numbered. */
- +#define WORDS_BIG_ENDIAN 0
- +
- +/* number of bits in an addressable storage unit */
- +#define BITS_PER_UNIT 8
- +
- +/* Width in bits of a "word", which is the contents of a machine register.
- + Note that this is not necessarily the width of data type `int';
- + if using 16-bit ints on a metag, this would still be 32.
- + But on a machine with 16-bit registers, this would be 16. */
- +#define BITS_PER_WORD 32
- +
- +/* Width of a word, in units (bytes). */
- +#define UNITS_PER_WORD 4
- +
- +/* Width of a SIMD word, in units (bytes). */
- +#define UNITS_PER_SIMD_WORD 8
- +
- +/* Width in bits of a pointer.
- + See also the macro `Pmode' defined below. */
- +#define POINTER_SIZE 32
- +
- +/* Allocation boundary (in *bits*) for storing arguments in argument list. */
- +#define PARM_BOUNDARY 32
- +
- +/* Boundary (in *bits*) on which stack pointer should be aligned. */
- +#define STACK_BOUNDARY 64
- +
- +#define STACK_BOUNDARY_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
- +
- +#define ALIGN_ON_STACK_BOUNDARY(X) \
- + (((X) + STACK_BOUNDARY_BYTES - 1) & ~(STACK_BOUNDARY_BYTES - 1))
- +
- +/* Allocation boundary (in *bits*) for the code of a function. */
- +#define FUNCTION_BOUNDARY 32
- +
- +/* Alignment of field after `int : 0' in a structure. */
- +#define EMPTY_FIELD_BOUNDARY 32
- +
- +/* No data type wants to be aligned rounder than this. */
- +/* metag_emb_asm_select_section asserts that BIGGEST_ALIGNMENT is 64. This is
- + because a specific section is required for any alignment bigger than 4
- + bytes. Currently only 8 byte alignment maximum is supported, anything
- + greater is ignored and converted to 8 byte alignment.
- + 1, 2 and 4 byte alignment do not need special sections as the automatic
- + alignment handling in the assembler will correctly align such sections
- + depending on the data contained within. Only 8 byte must be explicitly
- + stated. */
- +#define BIGGEST_ALIGNMENT 64
- +
- +/* Every structure's size must be a multiple of this. */
- +#define STRUCTURE_SIZE_BOUNDARY 32
- +
- +/* The best alignment to use in cases where we have a choice. */
- +#define FASTEST_ALIGNMENT 32
- +
- +/* Make strings 32-bit aligned so strcpy from constants will be faster. */
- +#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
- + ((TREE_CODE (EXP) == STRING_CST && (ALIGN) < FASTEST_ALIGNMENT) \
- + ? FASTEST_ALIGNMENT : (ALIGN))
- +
- +/* Make arrays of chars 32-bit aligned for the same reasons. */
- +#define DATA_ALIGNMENT(TYPE, ALIGN) \
- + (TREE_CODE (TYPE) == ARRAY_TYPE \
- + && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
- + && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
- +
- +/* Make local arrays of chars 32-bit aligned for the same reasons. */
- +#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
- + (TREE_CODE (TYPE) == ARRAY_TYPE \
- + && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
- + && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
- +
- +/* Define this if move instructions will actually fail to work
- + when given unaligned data. */
- +#define STRICT_ALIGNMENT 1
- +
- +/* Define number of bits in most basic integer type.
- + (If undefined, default is BITS_PER_WORD). */
- +#define INT_TYPE_SIZE 32
- +
- +/* Integer bit fields have the same size and alignment as actual integers */
- +#define PCC_BITFIELD_TYPE_MATTERS 1
- +
- +/* Specify the size_t type. */
- +#define SIZE_TYPE "unsigned int"
- +
- +/* Standard register usage. */
- +
- +/* Number of actual hardware registers.
- + The hardware registers are assigned numbers for the compiler
- + from 0 to just below FIRST_PSEUDO_REGISTER.
- + All registers that the compiler knows about must be given numbers,
- + even those that are not normally considered general registers. */
- +#define FIRST_PSEUDO_REGISTER 74
- +
- +/* 1 for registers that have pervasive standard uses
- + and are not available for the register allocator. */
- +#define FIXED_REGISTERS \
- +{ \
- + /* D0.0/D1.0-D0.7/D1.7 */ \
- + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, \
- + /* D0.8/D1.8-D0.15/D1.15 currently reserved */ \
- + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
- + /* A0.0/A1.0-A0.7/A1.7 */ \
- + 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, \
- + /* FRAME, CC, ARGP, RAPF, CPC0, CPC1, PC, TXRPT */ \
- + 1, 1, 1, 1, 1, 1, 1, 1, \
- + /* FX */ \
- + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
- + /* TTREC(L) */ \
- + 1, 1 \
- +}
- +
- +/* 1 for registers not available across function calls.
- + These must include the FIXED_REGISTERS and also any
- + registers that can be used without being saved.
- + The latter must include the registers where values are returned
- + and the register where structure-value addresses are passed.
- + Aside from that, you can include as many other registers as you like. */
- +#define CALL_USED_REGISTERS \
- +{ \
- + /* D0.0/D1.0-D0.7/D1.7 */ \
- + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, \
- + /* D0.8-D0.15/D1.8-D1.15 currently reserved */ \
- + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
- + /* A0.0/A1.0-A0.7/A1.7 */ \
- + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
- + /* FRAME, CC, ARGP, RAPF, CPC0, CPC1, PC, TXRPT */ \
- + 1, 1, 1, 1, 1, 1, 1, 1, \
- + /* FX */ \
- + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
- + /* TTREC(L) */ \
- + 1, 1 \
- +}
- +
- +/* Like `CALL_USED_REGISTERS' except this macro doesn't require that
- + the entire set of `FIXED_REGISTERS' be included.
- + (`CALL_USED_REGISTERS' must be a superset of `FIXED_REGISTERS').
- + This macro is optional. If not specified, it defaults to the value
- + of `CALL_USED_REGISTERS'. */
- +
- +#define CALL_REALLY_USED_REGISTERS \
- +{ \
- + /* D0/D1 */ \
- + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, \
- + /* D0/D1 currently reserved */ \
- + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
- + /* A0/A1 */ \
- + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
- + /* FRAME, CC, ARGP, RAPF, CPC0, CPC1, PC, TXRPT */ \
- + 1, 1, 1, 1, 1, 1, 1, 0, \
- + /* FX */ \
- + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
- + /* TTREC(L) */ \
- + 1, 1 \
- +}
- +
- +/* Make sure everything's fine if we *don't* have a given processor.
- + This assumes that putting a register in fixed_regs will keep the
- + compilers mitt's completely off it. We don't bother to zero it out
- + of register classes. */
- +#define CONDITIONAL_REGISTER_USAGE \
- + do { \
- + static const int bases[] = {16, 17, 40, 41, 0}; \
- + static const int strides[] = { 2, 2, 2, 2, 0}; \
- + static const int limits[] = { 8, 8, 4, 4, 0}; \
- + const char *pmetagopt = metag_extreg_string; \
- + int unit; \
- + long int fpuregs = strtol (metag_fpureg_string, NULL, 10); \
- + bool extended_reg_enabled = false; \
- + \
- + /* Minimum 3 fpu regs, maximum 16 */ \
- + if (fpuregs != 0) \
- + { \
- + /* The compiler may use FX registers so all sections are FPU*/ \
- + metag_fpu_resources = 1; \
- + fpuregs = (fpuregs > 16) ? 16 : (fpuregs < 3) ? 3 : fpuregs; \
- + } \
- + \
- + if (strlen (pmetagopt) != 0 && strlen (pmetagopt) != 4) \
- + error ("-mextreg takes an argument of four digits"); \
- + \
- + if (TARGET_METAC_1_1) \
- + { \
- + /* Don't need temporary registers in AX unit */ \
- + fixed_regs[A0_3_REG] = 0; \
- + fixed_regs[A1_3_REG] = 0; \
- + /* Hence compact default/minimum register set to 8844 for v1.1 */ \
- + fixed_regs[A0_4_REG] = 1; \
- + fixed_regs[A1_4_REG] = 1; \
- + } \
- + \
- + /* Enabled only the extended regs specified in the extreg string */ \
- + for (unit = 0; *pmetagopt != 0 && limits[unit]; unit++) \
- + { \
- + int add = (*pmetagopt++ - '0'); \
- + int reg = bases[unit]; \
- + \
- + if (add > limits[unit]) \
- + add = limits[unit]; \
- + \
- + while (add-- > 0) \
- + { \
- + if (TARGET_MTX) \
- + error ("MTX does not support extended registers\n"); \
- + extended_reg_enabled = true; \
- + fixed_regs[reg] = 0; \
- + reg += strides[unit]; \
- + } \
- + } \
- + \
- + if (extended_reg_enabled && metag_force_tbictxsave) \
- + target_flags |= MASK_ECH; \
- + \
- + if (TARGET_ECH) \
- + { \
- + if (fixed_regs[METAG_ECH_REGNUM] == 0) \
- + fixed_regs[METAG_ECH_REGNUM] = 1; \
- + else \
- + error ("-mtbictxsave cannot be used unless D0.8 is enabled via -mextreg\n" \
- + "Either use -mno-tbictxsave or enable D0.8"); \
- + } \
- + \
- + for ( ; fpuregs > 0 ; fpuregs-- ) \
- + fixed_regs[FIRST_FP_REG+fpuregs-1] = 0; \
- + \
- + if (METAG_FLAG_PIC) \
- + fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1 ; \
- + } while (0)
- +
- +/* Determine which register classes are very likely used by spill registers.
- + local-alloc.c won't allocate pseudos that have these classes as their
- + preferred class unless they are "preferred or nothing". */
- +
- +#define CLASS_LIKELY_SPILLED_P(CLASS) \
- + (reg_class_size[(int) (CLASS)] == 1 \
- + || (CLASS) == A0_REGS \
- + || (CLASS) == A1_REGS \
- + || (CLASS) == A_REGS \
- + || (CLASS) == Ye_REGS \
- + || (CLASS) == Yf_REGS \
- + || (CLASS) == Yd_REGS \
- + || (CLASS) == Yh_REGS \
- + || (CLASS) == Yl_REGS \
- + || (CLASS) == Ya_REGS \
- + || (CLASS) == Yr_REGS)
- +
- +/* The order in which registers should be allocated is defined so that the
- + result registers are treated as the last scratch registers to be used
- + after the argument registers are used in least likely used first order.
- + Then we do the call-saved registers and address unit registers in numeric
- + order - which is the default anyway. */
- +#define REG_ALLOC_ORDER \
- +{ \
- + /* D0.4 happens to be a completely free scratch register */ \
- + D0_4_REG, \
- + /* If we have tons of free scratch data registers use them first */ \
- + D0_8_REG, D1_8_REG, D0_9_REG, D1_9_REG, D0_10_REG, D1_10_REG, \
- + D0_11_REG, D1_11_REG, D0_12_REG, D1_12_REG, D0_13_REG, D1_13_REG, \
- + D0_14_REG, D1_14_REG, D0_15_REG, D1_15_REG, \
- + /* Then use the args and result registers in least-used first order */ \
- + /* The D0.1 and D1.1 are however used for 12bit offsets so are */ \
- + /* towards the end */ \
- + D0_2_REG, D1_2_REG, D0_3_REG, D1_3_REG, \
- + D0_1_REG, D1_1_REG, D1_0_REG, D0_0_REG, \
- + /* Then use the call-saved registers */ \
- + D0_5_REG, D1_5_REG, D0_6_REG, D1_6_REG, D0_7_REG, D1_7_REG, \
- + /* Then use the address unit scratch registers */ \
- + A0_2_REG, A1_2_REG, A0_3_REG, A1_3_REG, A0_4_REG, A1_4_REG, \
- + A0_5_REG, A1_5_REG, A0_6_REG, A1_6_REG, A0_7_REG, A1_7_REG, \
- + /* FX - disuade use of FCC_REGS class */ \
- + FX_0_REG , FX_1_REG , FX_2_REG , FX_3_REG , \
- + FX_4_REG , FX_5_REG , FX_6_REG , FX_7_REG , \
- + FX_8_REG , FX_9_REG , FX_10_REG, FX_11_REG, \
- + FX_12_REG, FX_13_REG, FX_14_REG, FX_15_REG, \
- + TXRPT_REG, TTREC_REG, TTRECL_REG, \
- + /* The remainder can never be allocated by the compiler anyway */ \
- + D1_4_REG, A0_0_REG, A1_0_REG, A0_1_REG, A1_1_REG, \
- + FRAME_REG, CC_REG, ARGP_REG, RAPF_REG, CPC0_REG, CPC1_REG, PC_REG \
- +}
- +
- +/* Specify the registers used for certain standard purposes.
- + The values of these macros are register numbers. */
- +
- +/* Register used for the program counter */
- +#define PC_REGNUM PC_REG
- +
- +/* Logical base register for access to arguments of the function. */
- +#define ARG_POINTER_REGNUM ARGP_REG
- +
- +/* Condition flag register */
- +#define MCC_REGNUM CC_REG
- +
- +/* Extended context support register */
- +#define METAG_ECH_REGNUM D0_8_REG
- +
- +/* Logical base register for access to local variables of the function. */
- +#define FRAME_POINTER_REGNUM FRAME_REG
- +
- +/* Real frame pointer register */
- +#define HARD_FRAME_POINTER_REGNUM A0FrP_REG
- +
- +/* First and last register that accepts function arguments, D1.3 - D0.1 */
- +#define MIN_METAG_PARM_REGNUM D0Ar6_REG /* Actually contains last arg! */
- +#define MAX_METAG_PARM_REGNUM D1Ar1_REG /* Actually contains first arg! */
- +
- +/* The number of registers used for parameter passing. Local to this file. */
- +#define MAX_METAG_PARM_REGS (1 + (MAX_METAG_PARM_REGNUM - MIN_METAG_PARM_REGNUM))
- +#define MAX_METAG_PARM_BYTES (MAX_METAG_PARM_REGS * UNITS_PER_WORD)
- +
- +/* D0.4 is used temporarily to save/restore A0FrP */
- +#define TEMP_D0FRT_REGNUM D0FrT_REG
- +
- +/* First and last register that is call-saved, D0.5 - D1.7 */
- +#define MIN_METAG_CSAVE_REGNUM D0_5_REG
- +#define MAX_METAG_CSAVE_REGNUM D1_7_REG
- +
- +/* Register to use for call/return addresses D1RtP */
- +#define RETURN_POINTER_REGNUM D1RtP_REG
- +
- +/* Register to use for pushing function arguments. */
- +#define STACK_POINTER_REGNUM A0StP_REG
- +
- +/* Register in which static-chain is passed to a function. */
- +#define GLOBAL_POINTER_REGNUM A1GbP_REG
- +#define STATIC_CHAIN_REGNUM D0Re0_REG
- +
- +/* Some temporaries are currently left for internal library/config use */
- +#define A0_SCRATCH (!TARGET_METAC_1_1 ? A0_3_REG : INVALID_REGNUM)
- +#define A1_SCRATCH (!TARGET_METAC_1_1 ? A1_3_REG : INVALID_REGNUM)
- +
- +/* Structure value address is passed is 'hidden' parameter */
- +#define STRUCT_VALUE 0
- +
- +#define RAPF_REGNUM RAPF_REG
- +
- +#define CPC0_REGNUM CPC0_REG
- +#define CPC1_REGNUM CPC1_REG
- +
- +#define TXRPT_REGNUM TXRPT_REG
- +#define TTREC_REGNUM TTREC_REG
- +
- +#define DECREMENT_AND_BRANCH_REG(MODE) gen_rtx_REG (MODE, TXRPT_REGNUM)
- +
- +#define TABLEJUMP_USES_DBRA_REG 0
- +
- +/* Value should be nonzero if functions must have frame pointers.
- + Zero means the frame pointer need not be set up (and parms
- + may be accessed via the stack pointer) in functions that seem suitable.
- + This is computed in `reload', in reload1.c. */
- +#define FRAME_POINTER_REQUIRED \
- + metag_frame_pointer_required ()
- +
- +#define SETUP_FRAME_ADDRESSES() \
- + metag_setup_frame_addresses ()
- +
- +/* Definitions for register eliminations.
- +
- + This is an array of structures. Each structure initializes one pair
- + of eliminable registers. The "from" register number is given first,
- + followed by "to". Eliminations of the same "from" register are listed
- + in order of preference.
- +
- + We have two registers that MUST be eliminated FRAME_POINTER and
- + ARG_POINTER. ARG_POINTER is ALWAYS eliminated to either STACK_POINTER_REGNUM
- + or HARD_FRAME_POINTER_REGNUM. FRAME_POINTER is ALWAYS eliminated to either
- + STACK_POINTER_REGNUM or HARD_FRAME_POINTER_REGNUM.
- +
- + STACK_POINTER_REGUM is the preferred elimination. */
- +
- +#define ELIMINABLE_REGS \
- +{ \
- + {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
- + {ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
- + {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
- + {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM} \
- +}
- +
- +/* Given FROM and TO register numbers, say whether this elimination is allowed.
- + Frame pointer elimination is automatically handled.
- +
- + Only eliminate down to the HARD_FRAME_POINTER if it's available. */
- +#define CAN_ELIMINATE(FROM, TO) \
- + (((TO) == STACK_POINTER_REGNUM && frame_pointer_needed) ? 0 : 1)
- +
- +/* Define the offset between two registers, one to be eliminated,
- + and the other its replacement, at the start of a routine.
- + */
- +
- +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
- + ((OFFSET) = metag_initial_elimination_offset (FROM, TO))
- +
- +/* Return number of consecutive hard regs needed starting at reg REGNO
- + to hold something of mode MODE.
- + This is ordinarily the length in words of a value of mode MODE
- + but can be less for certain modes in special long registers. */
- +#define HARD_REGNO_NREGS(REGNO, MODE) \
- + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
- +
- +/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */
- +#define HARD_REGNO_MODE_OK(REGNO, MODE) \
- + metag_hard_regno_mode_ok (REGNO, MODE)
- +
- +/* Value is 1 if it is a good idea to tie two pseudo registers
- + when one has mode MODE1 and one has mode MODE2.
- + If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
- + for any hard reg, then this must be 0 for correct output. */
- +#define MODES_TIEABLE_P(MODE1, MODE2) \
- + (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))
- +
- +/* Define the classes of registers for register constraints in the
- + machine description. Also define ranges of constants.
- +
- + One of the classes must always be named ALL_REGS and include all hard regs.
- + If there is more than one class, another class must be named NO_REGS
- + and contain no registers.
- +
- + The name GENERAL_REGS must be the name of a class (or an alias for
- + another name such as ALL_REGS). This is the class of registers
- + that is allowed by "g" or "r" in a register constraint.
- + Also, registers outside this class are allocated only when
- + instructions express preferences for them.
- +
- + The classes must be numbered in nondecreasing order; that is,
- + a larger-numbered class must never be contained completely
- + in a smaller-numbered class.
- +
- + For any two classes, it is very desirable that there be another
- + class that represents their union. */
- +
- +enum reg_class
- +{
- + NO_REGS,
- + Wx_REGS,
- + WQh_REGS,
- + WQl_REGS,
- + Ye_REGS,
- + Yf_REGS,
- + Yd_REGS,
- + Yh_REGS,
- + Yl_REGS,
- + Ya_REGS,
- + Yr_REGS,
- + D0_REGS,
- + D1_REGS,
- + D_REGS,
- + A0_REGS,
- + A1_REGS,
- + A_REGS,
- + DA_REGS,
- + Be_REGS,
- + Bf_REGS,
- + Bd_REGS,
- + Bh_REGS,
- + Bl_REGS,
- + Ba_REGS,
- + Br_REGS,
- + nD0_REGS,
- + nD1_REGS,
- + nA0_REGS,
- + nA1_REGS,
- + nBU_REGS,
- + nYe_REGS,
- + nYf_REGS,
- + nYd_REGS,
- + nYh_REGS,
- + nYl_REGS,
- + nYa_REGS,
- + nYr_REGS,
- + GENERAL_REGS,
- + FPP_REGS,
- + FPC_REGS,
- + cD0_REGS,
- + cD1_REGS,
- + cD_REGS,
- + cA0_REGS,
- + cA1_REGS,
- + cA_REGS,
- + cnD0_REGS,
- + cnD1_REGS,
- + cnA0_REGS,
- + cnA1_REGS,
- + cDA_REGS,
- + ALL_REGS,
- + LIM_REG_CLASSES
- +};
- +
- +#define N_REG_CLASSES ((int) LIM_REG_CLASSES)
- +
- +/* Give names of register classes as strings for dump file. */
- +
- +#define REG_CLASS_NAMES \
- +{ \
- + "NO_REGS", \
- + "Wx_REGS", \
- + "WQh_REGS", \
- + "WQl_REGS", \
- + "Ye_REGS", \
- + "Yf_REGS", \
- + "Yd_REGS", \
- + "Yh_REGS", \
- + "Yl_REGS", \
- + "Ya_REGS", \
- + "Yr_REGS", \
- + "D0_REGS", \
- + "D1_REGS", \
- + "D_REGS", \
- + "A0_REGS", \
- + "A1_REGS", \
- + "A_REGS", \
- + "DA_REGS", \
- + "Be_REGS", \
- + "Bf_REGS", \
- + "Bd_REGS", \
- + "Bh_REGS", \
- + "Bl_REGS", \
- + "Ba_REGS", \
- + "Br_REGS", \
- + "nD0_REGS", \
- + "nD1_REGS", \
- + "nA0_REGS", \
- + "nA1_REGS", \
- + "nBU_REGS", \
- + "nYe_REGS", \
- + "nYf_REGS", \
- + "nYd_REGS", \
- + "nYh_REGS", \
- + "nYl_REGS", \
- + "nYa_REGS", \
- + "nYr_REGS", \
- + "GENERAL_REGS", \
- + "FPP_REGS", \
- + "FPC_REGS", \
- + "cD0_REGS", \
- + "cD1_REGS", \
- + "cD_REGS", \
- + "cA0_REGS", \
- + "cA1_REGS", \
- + "cA_REGS", \
- + "cnD0_REGS", \
- + "cnD1_REGS", \
- + "cnA0_REGS", \
- + "cnA1_REGS", \
- + "cDA_REGS", \
- + "ALL_REGS" \
- +}
- +
- +/* Define which registers fit in which classes.
- + This is an initializer for a vector of HARD_REG_SET
- + of length N_REG_CLASSES. */
- +
- +#define REG_CLASS_CONTENTS \
- +{ \
- + { 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \
- + { 0x00000000, 0x00800000, 0x00000300 }, /* Wx_REGS */ \
- + { 0x00000000, 0x00000050, 0x00000000 }, /* WQh_REGS */ \
- + { 0x00000000, 0x000000a0, 0x00000000 }, /* WQl_REGS */ \
- + { 0x00000005, 0x00000000, 0x00000000 }, /* Ye_REGS */ \
- + { 0x0000000a, 0x00000000, 0x00000000 }, /* Yf_REGS */ \
- + { 0x0000000f, 0x00000000, 0x00000000 }, /* Yd_REGS */ \
- + { 0x00000000, 0x00000005, 0x00000000 }, /* Yh_REGS */ \
- + { 0x00000000, 0x0000000a, 0x00000000 }, /* Yl_REGS */ \
- + { 0x00000000, 0x0000000f, 0x00000000 }, /* Ya_REGS */ \
- + { 0x0000000f, 0x0000000f, 0x00000000 }, /* Yr_REGS */ \
- + { 0x55555555, 0x00000000, 0x00000000 }, /* D0_REGS */ \
- + { 0xaaaaaaaa, 0x00000000, 0x00000000 }, /* D1_REGS */ \
- + { 0xffffffff, 0x00000000, 0x00000000 }, /* D_REGS */ \
- + { 0x00000000, 0x00005555, 0x00000000 }, /* A0_REGS */ \
- + { 0x00000000, 0x0000aaaa, 0x00000000 }, /* A1_REGS */ \
- + { 0x00000000, 0x0000ffff, 0x00000000 }, /* A_REGS */ \
- + { 0xffffffff, 0x0000ffff, 0x00000000 }, /* DA_REGS */ \
- + { 0x5555ffff, 0x0000ffff, 0x00000000 }, /* Be_REGS */ \
- + { 0xaaaaffff, 0x0000ffff, 0x00000000 }, /* Bf_REGS */ \
- + { 0x0000ffff, 0x0000ffff, 0x00000000 }, /* Bd_REGS */ \
- + { 0x0000ffff, 0x0000ffff, 0x00000000 }, /* Bh_REGS */ \
- + { 0x0000ffff, 0x0000ffff, 0x00000000 }, /* Bl_REGS */ \
- + { 0x0000ffff, 0x0000ffff, 0x00000000 }, /* Ba_REGS */ \
- + { 0x0000ffff, 0x0000ffff, 0x00000000 }, /* Br_REGS */ \
- + { 0xaaaaaaaa, 0x0000ffff, 0x00000000 }, /* nD0_REGS */ \
- + { 0x55555555, 0x0000ffff, 0x00000000 }, /* nD1_REGS */ \
- + { 0xffffffff, 0x0000aaaa, 0x00000000 }, /* nA0_REGS */ \
- + { 0xffffffff, 0x00005555, 0x00000000 }, /* nA1_REGS */ \
- + { 0xffff0000, 0x00000000, 0x00000000 }, /* nBU_REGS */ \
- + { 0xfffffffa, 0x0000ffff, 0x00000000 }, /* nYe_REGS */ \
- + { 0xfffffff5, 0x0000ffff, 0x00000000 }, /* nYf_REGS */ \
- + { 0xfffffff0, 0x0000ffff, 0x00000000 }, /* nYd_REGS */ \
- + { 0xffffffff, 0x0000fffa, 0x00000000 }, /* nYh_REGS */ \
- + { 0xffffffff, 0x0000fff5, 0x00000000 }, /* nYl_REGS */ \
- + { 0xffffffff, 0x0000fff0, 0x00000000 }, /* nYa_REGS */ \
- + { 0xfffffff0, 0x0000fff0, 0x00000000 }, /* nYr_REGS */ \
- + { 0xffffffff, 0x0000ffff, 0x00000000 }, /* GENERAL_REGS */ \
- + { 0x00000000, 0x55000000, 0x00000055 }, /* FPP_REGS */ \
- + { 0x00000000, 0xff000000, 0x000000ff }, /* FPC_REGS */ \
- + { 0x55555555, 0xff000000, 0x000000ff }, /* cD0_REGS */ \
- + { 0xaaaaaaaa, 0xff000000, 0x000000ff }, /* cD1_REGS */ \
- + { 0xffffffff, 0xff000000, 0x000000ff }, /* cD_REGS */ \
- + { 0x00000000, 0xff005555, 0x000000ff }, /* cA0_REGS */ \
- + { 0x00000000, 0xff00aaaa, 0x000000ff }, /* cA1_REGS */ \
- + { 0x00000000, 0xff00ffff, 0x000000ff }, /* cA_REGS */ \
- + { 0xaaaaaaaa, 0xff00ffff, 0x000000ff }, /* cnD0_REGS */ \
- + { 0x55555555, 0xff00ffff, 0x000000ff }, /* cnD1_REGS */ \
- + { 0xffffffff, 0xff00aaaa, 0x000000ff }, /* cnA0_REGS */ \
- + { 0xffffffff, 0xff005555, 0x000000ff }, /* cnA1_REGS */ \
- + { 0xffffffff, 0xff00ffff, 0x000000ff }, /* cDA_REGS */ \
- + { 0xffffffff, 0xff80ffff, 0x000003ff } /* ALL_REGS */ \
- +}
- +
- +/* The same information, inverted:
- + Return the class number of the smallest class containing
- + reg number REGNO. This could be a conditional expression
- + or could index an array. */
- +
- +#define REGNO_REG_CLASS(REGNO) \
- + metag_regno_reg_class_minimal (REGNO)
- +
- +#define METAG_REGNO_REG_CLASS(REGNO) \
- + metag_regno_reg_class_unit (REGNO)
- +
- +#define METAG_REGNO_SAME_UNIT(REGNUM1, REGNUM2) \
- + metag_regno_same_unit_p (REGNUM1, REGNUM2)
- +
- +/* The class value for index registers, and the one for base regs. */
- +#define INDEX_REG_CLASS NO_REGS
- +#define BASE_REG_CLASS GENERAL_REGS
- +
- +#define IN_RANGE_P(VALUE, LOW, HIGH) \
- + ((LOW) <= (VALUE) && (VALUE) <= (HIGH))
- +
- +#define METAG_CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
- +
- +/* Define the cost of moving between registers of various classes. */
- +#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
- + ((int)(CLASS1) == (int)(CLASS2) ? 1 : 4 )
- +
- +/* A C expressions returning the cost of moving data of MODE from a register to
- + or from memory. Keep it higher than max register/register costs */
- +#define MEMORY_MOVE_COST(MODE, CLASS, IN) 8
- +
- +/* Given an rtx X being reloaded into a reg required to be
- + in class CLASS, return the class of reg to actually use.
- + In general this is just CLASS; but on some machines
- + in some cases it is preferable to use a more restrictive class. */
- +#define PREFERRED_RELOAD_CLASS(X, CLASS) (CLASS)
- +
- +#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
- + metag_secondary_reload_class (CLASS, MODE, X, true)
- +
- +#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
- + metag_secondary_reload_class (CLASS, MODE, X, false)
- +
- +/* Return the maximum number of consecutive registers
- + needed to represent mode MODE in a register of class CLASS. */
- +#define CLASS_MAX_NREGS(CLASS, MODE) \
- + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
- +
- +/* Stack layout; function entry, exit and calling. */
- +
- +/* Define this if pushing a word on the stack
- + makes the stack pointer a smaller address. */
- +/*#define STACK_GROWS_DOWNWARD*/
- +
- +/* Define this if the nominal address of the stack frame
- + is at the high-address end of the local variables;
- + that is, each additional local variable allocated
- + goes at a more negative offset in the frame. */
- +/* #define FRAME_GROWS_DOWNWARD */
- +
- +#define ARGS_GROW_DOWNWARD
- +
- +/* We use post increment on metag because of 64-bit vs 32-bit alignments */
- +#define STACK_PUSH_CODE POST_INC
- +
- +/* Offset within stack frame to start allocating local variables at.
- + If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
- + first local allocated. Otherwise, it is the offset to the BEGINNING
- + of the first local allocated. */
- +#define STARTING_FRAME_OFFSET 0
- +
- +/* This points to the location of dynamically allocated memory on the stack
- + immediately after the stack pointer has been adjusted by the amount of
- + memory desired. */
- +#define STACK_DYNAMIC_OFFSET(FNDECL) \
- + (-(current_function_outgoing_args_size + (STACK_POINTER_OFFSET)))
- +
- +/* If we generate an insn to push BYTES bytes,
- + this says how many the stack pointer really advances by.
- + (incompatible with ACCUMULATE_OUTGOING_ARGS)
- +#define PUSH_ROUNDING(BYTES) (((BYTES) + 3) & ~3) */
- +
- +/* If nonzero, the maximum amount of space required for outgoing arguments will be
- + computed and placed into the variable current_function_outgoing_args_size. No space
- + will be pushed onto the stack for each call; instead, the function prologue should
- + increase the stack frame size by this amount. Setting both PUSH_ARGS and
- + ACCUMULATE_OUTGOING_ARGS is not proper.
- +*/
- +#define ACCUMULATE_OUTGOING_ARGS 1
- +
- +/* Offset of first parameter from the argument pointer register value. */
- +#define FIRST_PARM_OFFSET(FNDECL) \
- + metag_first_parm_offset (FNDECL)
- +
- +/* A C expression whose value is RTL representing the value of the return
- + address for the frame COUNT steps up from the current frame. */
- +
- +#define RETURN_ADDR_RTX(COUNT, FRAME) \
- + metag_return_addr_rtx (COUNT, FRAME)
- +
- +/* Value is 1 if returning from a function call automatically
- + pops the arguments described by the number-of-args field in the call.
- + FUNDECL is the declaration node of the function (as a tree),
- + FUNTYPE is the data type of the function (as a tree),
- + or for a library call it is an identifier node for the subroutine name. */
- +
- +#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) (0)
- +
- +/* Define how to find the value returned by a library function
- + assuming the value has mode MODE. */
- +
- +/* On the metag the return value is in D0.0/D1.0 regardless. */
- +
- +#define LIBCALL_VALUE(MODE) metag_libcall_value (MODE)
- +
- +/* 1 if N is a possible register number for a function value.
- + On the metag, D1.0/D1.1 is the only register thus used. */
- +
- +#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
- +
- +/* A C expression which can inhibit the returning of certain function values
- + in registers, based on the type of value. A nonzero value says to return
- + the function value in memory, just as large structures are always
- + returned. Here type will be a C expression of type tree, representing the
- + data type of the value. We target all 64-bit or less structures as return
- + in registers. */
- +#define RETURN_IN_MEMORY(TYPE) metag_return_in_memory (TYPE)
- +
- +/* Define this macro to be 1 if all structure and union return values must be
- + in memory. We want 64-bit structs to return in registers under the control
- + of the RETURN_IN_MEMORY macro. */
- +#define DEFAULT_PCC_STRUCT_RETURN 0
- +
- +/* 1 if N is a possible register number for function argument passing. */
- +#define FUNCTION_ARG_REGNO_P(N) \
- + (MIN_METAG_PARM_REGNUM <= (N) && (N) <= MAX_METAG_PARM_REGNUM)
- +
- +/* Define a data type for recording info about an argument list
- + during the scan of that argument list. This data type should
- + hold all necessary information about the function itself
- + and about the args processed so far, enough to enable macros
- + such as FUNCTION_ARG to determine where the next arg should go.
- +
- + On the metag, this is a single integer, which is a number of bytes
- + of arguments scanned so far. */
- +struct cumulative_args
- +{
- + int narg;
- + int partial;
- +};
- +
- +#define CUMULATIVE_ARGS struct cumulative_args
- +
- +/* Initialize a variable CUM of type CUMULATIVE_ARGS
- + for a call to a function whose data type is FNTYPE.
- + For a library call, FNTYPE is 0. */
- +#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
- + ((CUM).narg = 0, (CUM).partial = 0)
- +
- +/* Round VALUE up to next multiple of SIZE (Assumes SIZE is 2^N for some N */
- +#define ROUND_TO_SIZE(VALUE, SIZE) \
- + (((VALUE) + (SIZE) - 1) & ~((SIZE) - 1))
- +
- +/* Round VALUE up to a double word boundary */
- +#define ROUND_TO_DWORD(VALUE) \
- + ROUND_TO_SIZE (VALUE, 2 * UNITS_PER_WORD)
- +
- +/* Round VALUE up to a word boundary */
- +#define ROUND_TO_WORD(VALUE) \
- + ROUND_TO_SIZE (VALUE, UNITS_PER_WORD)
- +
- +/* Round VALUE up to a word boundary */
- +#define ROUND_ADVANCE(VALUE) \
- + ROUND_TO_WORD (VALUE)
- +
- +/* Argument size rounded up to word size. */
- +#define METAG_ARG_SIZE(MODE, TYPE) \
- + ((MODE) == BLKmode \
- + ? ROUND_TO_WORD (int_size_in_bytes (TYPE)) \
- + : ROUND_TO_WORD (GET_MODE_SIZE (MODE)))
- +
- +/* Round arg MODE/TYPE up to the next word boundary. */
- +#define ROUND_ADVANCE_ARG(MODE, TYPE) \
- + METAG_ARG_SIZE (MODE, TYPE)
- +
- +/* Round CUM up to the necessary point for argument MODE/TYPE. */
- +#define ROUND_ADVANCE_CUM(CUM, MODE, TYPE) \
- + (METAG_ARG_SIZE (MODE, TYPE) > UNITS_PER_WORD \
- + ? (ROUND_TO_DWORD ((CUM) + METAG_ARG_SIZE (MODE, TYPE)) \
- + - METAG_ARG_SIZE (MODE, TYPE)) \
- + : (CUM))
- +
- +/* Offset base register by one for 64-bit atomic values and the whole size of
- + struct/union parameters */
- +#define ROUND_BASEREG_NUM(MODE, TYPE) \
- + ((ROUND_ADVANCE_ARG (MODE, TYPE) / UNITS_PER_WORD) - 1)
- +
- +/* Update the data in CUM to advance over an argument of mode MODE and data
- + type TYPE. TYPE is null for libcalls where that information may not be
- + available. */
- +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
- + metag_function_arg_advance (&(CUM), MODE, TYPE, NAMED)
- +
- +/* Calculate register to place argument. align correctly for 64-bit data */
- +#define CALCULATE_REG(BASE_REG, CUM, MODE, TYPE) \
- + ((BASE_REG) - ((ROUND_ADVANCE_CUM (CUM, MODE, TYPE) / UNITS_PER_WORD) \
- + + ROUND_BASEREG_NUM (MODE, TYPE)))
- +
- +/* Define where to put the arguments to a function.
- + Value is zero to push the argument on the stack,
- + or a hard register in which to store the argument.
- +
- + MODE is the argument's machine mode.
- + TYPE is the data type of the argument (as a tree).
- + This is null for libcalls where that information may
- + not be available.
- + CUM is a variable of type CUMULATIVE_ARGS which gives info about
- + the preceding args and about the function being called.
- + NAMED is nonzero if this argument is a named parameter
- + (otherwise it is an extra parameter matching an ellipsis). */
- +
- +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
- + metag_function_arg (&(CUM), MODE, TYPE, NAMED)
- +
- +/* Defined if some argument types need more than PARM_BOUNDARY alignment */
- +#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
- + metag_function_arg_boundary (MODE, TYPE)
- +
- +/* Perform any actions needed for a function that is receiving a variable number
- + of arguments. CUM is as above. MODE and TYPE are the mode and type of the
- + current parameter. PRETEND_SIZE is a variable that should be set to the amount
- + of stack that must be pushed by the prologue to pretend that our caller pushed
- + it.
- +
- + Normally, this macro will push all remaining incoming registers on the stack
- + and set PRETEND_SIZE to the length of the registers pushed.
- +
- + On Metag, PRETEND_SIZE is set in order to have the prologue push the last
- + named argument and all anonymous arguments onto the stack .*/
- +
- +/* Don't output profile counters. */
- +#define NO_PROFILE_COUNTERS 1
- +
- +/* Output assembler code to FILE to increment profiler label # LABELNO
- + for profiling a function entry. */
- +
- +#define FUNCTION_PROFILER(FILE, LABELNO) \
- + do { \
- + if (!TARGET_HWTRACE) \
- + metag_function_profiler (FILE); \
- + } while (0)
- +
- +/* Output assembler code to FILE to initialize this source file's
- + basic block profiling info, if that has not already been done. */
- +
- +#define FIXME_FUNCTION_BLOCK_PROFILER(FILE, LABELNO) \
- + fprintf (FILE, ASM_COMMENT_START " block profile code %u\n", (LABELNO))
- +
- +/* Output assembler code to FILE to increment the entry-count for
- + the BLOCKNO'th basic block in this source file. */
- +
- +#define FIXME_BLOCK_PROFILER(FILE, BLOCKNO) \
- + fprintf (FILE, ASM_COMMENT_START " profile code %u\n", 4 * (BLOCKNO))
- +
- +/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
- + the stack pointer does not matter. The value is tested only in
- + functions that have frame pointers.
- + No definition is equivalent to always zero. */
- +#define EXIT_IGNORE_STACK 1
- +
- +/* Determine if the epilogue should be output as RTL.
- + You should override this if you define FUNCTION_EXTRA_EPILOGUE. */
- +#define METAG_CHEAP_RETURN metag_cheap_return
- +
- +#if 1
- +#define TRAMPOLINE_SECTION text_section
- +
- +/* Output assembler code for a block containing the constant parts
- + of a trampoline, leaving space for the variable parts. */
- +
- +/* On the metag, the trampoline contains 4 instructions + 2 data words:
- + MOV TEMP_D0FRT_REGNUM, PC
- + GETD STATIC_CHAIN_REGNUM, [TEMP_D0FRT_REGNUM + #(16 - 4)]
- + GETD TEMP_D0FRT_REGNUM, [TEMP_D0FRT_REGNUM + #(20 - 4)]
- + MOV PC, TEMP_D0FRT_REGNUM
- + .long <static-chain>
- + .long <function-address>
- + */
- +
- +/* Define offsets from start of Trampoline for the dynamic static
- + chain and function address data words. */
- +#define TRAMP_SC_OFFSET 16 /* Static chain offset. */
- +#define TRAMP_FN_OFFSET 20 /* Function address offset. */
- +
- +#define TRAMPOLINE_TEMPLATE(FILE) \
- +do { \
- + const char * const scratch = reg_names[TEMP_D0FRT_REGNUM]; \
- + const char * const chain = reg_names[STATIC_CHAIN_REGNUM]; \
- + \
- + fprintf (FILE, "\tMOV\t%s, PC\n", scratch); \
- + fprintf (FILE, "\tGETD\t%s, [%s + #%d]\n", \
- + chain, scratch, TRAMP_SC_OFFSET - 4); \
- + fprintf (FILE, "\tGETD\t%s, [%s + #%d]\n", \
- + scratch, scratch, TRAMP_FN_OFFSET - 4); \
- + fprintf (FILE, "\tMOV\tPC, %s\n", scratch); \
- + fputs (targetm.asm_out.aligned_op.si, FILE); \
- + fputs ("\t0\n", FILE); \
- + fputs (targetm.asm_out.aligned_op.si, FILE); \
- + fputs ("\t0\n", FILE); \
- +} while (0)
- +
- +/* Length in units of the trampoline for entering a nested function. */
- +
- +#define TRAMPOLINE_SIZE (UNITS_PER_WORD * 6)
- +
- +/* Emit RTL insns to initialize the variable parts of a trampoline.
- + FNADDR is an RTX for the address of the function's pure code.
- + CXT is an RTX for the static chain value for the function. */
- +
- +#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
- +do { \
- + if (!TARGET_MTX) \
- + { \
- + if (!TARGET_MINIM) \
- + { \
- + emit_move_insn (gen_rtx_MEM (SImode, \
- + plus_constant (TRAMP, TRAMP_SC_OFFSET)), \
- + CXT); \
- + emit_move_insn (gen_rtx_MEM (SImode, \
- + plus_constant (TRAMP, TRAMP_FN_OFFSET)), \
- + FNADDR); \
- + } \
- + else \
- + error ("GNU C nested C function extension not supported for MiniM.\n");\
- + } \
- + else \
- + error ("GNU C nested C function extension not supported.\n"); \
- +} while (0)
- +
- +#endif
- +
- +
- +/* Initialize data used by insn expanders. This is called from insn_emit,
- + once for every function before code is generated. */
- +
- +#define INIT_EXPANDERS metag_init_expanders ()
- +
- +/* Addressing modes, and classification of registers for them. */
- +
- +#define HAVE_PRE_INCREMENT 1
- +#define HAVE_POST_INCREMENT 1
- +#define HAVE_PRE_DECREMENT 1
- +#define HAVE_POST_DECREMENT 1
- +
- +#define HAVE_PRE_MODIFY_REG 1
- +#define HAVE_POST_MODIFY_REG 1
- +#define HAVE_PRE_MODIFY_DISP 1
- +#define HAVE_POST_MODIFY_DISP 1
- +
- +/* Macros to check register numbers against specific register classes. */
- +
- +/* These assume that REGNO is a hard or pseudo reg number.
- + They give nonzero only if REGNO is a hard reg of the suitable class
- + or a pseudo reg currently allocated to a suitable hard reg.
- + Since they use reg_renumber, they are safe only once reg_renumber
- + has been allocated, which happens in local-alloc.c. */
- +
- +#define REGNO_OK_FOR_INDEX_P(REGNO) \
- + FALSE /* REGNO_OK_FOR_BASE_P (REGNO) */
- +
- +#define TEST_REGNO(R, OP, VALUE) \
- + (((unsigned)(R) OP (VALUE)) || (unsigned)reg_renumber[R] OP (VALUE))
- +
- +#define REGNO_OK_FOR_BASE_P(REGNO) \
- + (TEST_REGNO (REGNO, <=, FRAME_POINTER_REGNUM) \
- + || TEST_REGNO (REGNO, ==, ARG_POINTER_REGNUM))
- +
- +/* Maximum number of registers that can appear in a valid memory address. */
- +#define MAX_REGS_PER_ADDRESS 2
- +
- +/* Recognize any constant value that is a valid address. */
- +
- +#define CONSTANT_ADDRESS_P(X) \
- + (LABEL_REF_P (X) \
- + || SYMBOL_REF_P (X) \
- + || CONST_INT_P (X) \
- + || GET_CODE (X) == CONST)
- +
- +/* Nonzero if the constant value X is a legitimate general operand.
- + It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
- +
- + TODO: This will need to be changed (see definition in metag-linux.h)
- + when implementing TLS for the embedded toolchain.
- + */
- +
- +#define LEGITIMATE_CONSTANT_P(X) 1
- +
- +/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
- + and check its validity for a certain class.
- + We have two alternate definitions for each of them.
- + The usual definition accepts all pseudo regs; the other rejects
- + them unless they have been allocated suitable hard regs.
- + The symbol REG_OK_STRICT causes the latter definition to be used.
- +
- + Most source files want to accept pseudo regs in the hope that
- + they will get allocated to the class that the insn wants them to be in.
- + Source files for reload pass need to be strict.
- + After reload, it makes no difference, since pseudo regs have
- + been eliminated by then. */
- +
- +#ifndef REG_OK_STRICT
- +#define REG_OK_STRICT_FLAG FALSE
- +#else
- +#define REG_OK_STRICT_FLAG TRUE
- +#endif
- +
- +/* -------------------------------- BEGIN NONSTRICT ------------------------ */
- +
- +#define NONSTRICT_REGNO_OK_P(R) \
- + METAG_LEGITIMATE_REGNO_P (R, false)
- +
- +#define NONSTRICT_REG_OK_P(R) \
- + METAG_LEGITIMATE_REG_P (R, false)
- +
- +/* Nonzero if X is a hard reg that can be used as an index
- + or if it is a pseudo reg. */
- +#define NONSTRICT_REG_OK_FOR_INDEX_P(X) \
- + FALSE /* NONSTRICT_REGNO_OK_P (REGNO (X)) */
- +
- +/* Nonzero if X is a hard reg that can be used as a base reg
- + or if it is a pseudo reg. */
- +#define NONSTRICT_REG_OK_FOR_BASE_P(X) \
- + FALSE /* NONSTRICT_REGNO_OK_P (REGNO (X)) */
- +
- +/* Nonzero if X is a hard reg that can be used as a base reg
- + or if it is a pseudo reg. */
- +#define NONSTRICT_REG_OK_FOR_OFFSET_P(X) \
- + NONSTRICT_REG_OK_P (X)
- +
- +/* Nonzero if the pair of hard regs are okay to use as base + offset
- + or if either is a psuedo reg. */
- +#define NONSTRICT_REGS_OK_FOR_BASE_OFFSET_P(X, Y) \
- + METAG_REGS_OK_FOR_BASE_OFFSET_P (X, Y, false)
- +
- +/* ---------------------------------- END NONSTRICT ------------------------ */
- +
- +/* ----------------------------------- BEGIN STRICT ------------------------ */
- +
- +#define STRICT_REGNO_OK_P(R) \
- + METAG_LEGITIMATE_REGNO_P (R, true)
- +
- +#define STRICT_REG_OK_P(R) \
- + METAG_LEGITIMATE_REG_P (R, false)
- +
- +/* Nonzero if X is a hard reg that can be used as an index. */
- +#define STRICT_REG_OK_FOR_INDEX_P(X) \
- + FALSE /* STRICT_REGNO_OK_P (REGNO (X)) */
- +
- +/* Nonzero if X is a hard reg that can be used as a base reg. */
- +#define STRICT_REG_OK_FOR_BASE_P(X) \
- + FALSE /* STRICT_REGNO_OK_P (REGNO (X)) */
- +
- +/* Nonzero if X is a hard reg that can be used as a base reg. */
- +#define STRICT_REG_OK_FOR_OFFSET_P(X) \
- + STRICT_REG_OK_P (X)
- +
- +/* Nonzero if the pair of hard regs is okay to use as base + offset */
- +#define STRICT_REGS_OK_FOR_BASE_OFFSET_P(X, Y) \
- + METAG_REGS_OK_FOR_BASE_OFFSET_P (X, Y, true)
- +
- +/* ------------------------------------ END STRICT ------------------------- */
- +
- +/* Nonzero if X is a hard reg that can be used as an index
- + or if it is a pseudo reg. */
- +#define REG_OK_FOR_INDEX_P(X) \
- + METAG_REG_OK_FOR_INDEX_P (X, REG_OK_STRICT_FLAG)
- +
- +#define METAG_REG_OK_FOR_INDEX_P(X, STRICT) \
- + metag_reg_ok_for_index_p (X, STRICT)
- +
- +/* Nonzero if X is a hard reg that can be used as a base reg. */
- +#define REG_OK_FOR_BASE_P(X) \
- + METAG_REG_OK_FOR_BASE_P (X, REG_OK_STRICT_FLAG)
- +
- +#define METAG_REG_OK_FOR_BASE_P(X, STRICT) \
- + metag_reg_ok_for_base_p (X, STRICT)
- +
- +/* Nonzero if X is a hard reg that can be used as a base reg. */
- +#define REG_OK_FOR_OFFSET_P(X) \
- + METAG_REG_OK_FOR_OFFSET_P (X, REG_OK_STRICT_FLAG)
- +
- +#define METAG_REG_OK_FOR_OFFSET_P(X, STRICT) \
- + metag_reg_ok_for_offset_p (X, STRICT)
- +
- +/* Nonzero if the pair of hard regs is okay to use as base + offset */
- +#define METAG_REGS_OK_FOR_BASE_OFFSET_P(X, Y, STRICT) \
- + metag_regs_ok_for_base_offset_p (X, Y, STRICT)
- +
- +/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- + that is a valid memory address for an instruction.
- + The MODE argument is the machine mode for the MEM expression
- + that wants to use this address. */
- +
- +#define METAG_LEGITIMATE_REGNO_P(REGNUM, STRICT) \
- + metag_legitimate_regno_p (REGNUM, STRICT)
- +
- +#define METAG_LEGITIMATE_REG_P(REG, STRICT) \
- + metag_legitimate_reg_p (REG, STRICT)
- +
- +/* PRE_MODIFY */
- +#define METAG_LEGITIMATE_PRE_MODIFY_P(ADDR, MODE, STRICT) \
- + (GET_CODE (ADDR) == PRE_MODIFY \
- + && metag_legitimate_modify_p (ADDR, MODE, STRICT))
- +
- +/* POST_MODIFY */
- +#define METAG_LEGITIMATE_POST_MODIFY_P(ADDR, MODE, STRICT) \
- + (GET_CODE (ADDR) == POST_MODIFY \
- + && metag_legitimate_modify_p (ADDR, MODE, STRICT))
- +
- +/* PRE_INC/PRE_DEC supportable */
- +#define METAG_LEGITIMATE_PRE_INCDEC_P(ADDR, MODE, STRICT) \
- + metag_legitimate_pre_incdec_p (ADDR, MODE, STRICT)
- +
- +/* POST_INC/POST_DEC supportable */
- +#define METAG_LEGITIMATE_POST_INCDEC_P(ADDR, MODE, STRICT) \
- + metag_legitimate_post_incdec_p (ADDR, MODE, STRICT)
- +
- +/* Two ranges of offset are supported dependant on base & mode */
- +#define METAG_LEGITIMATE_OFF_P(BASE, OFF, MODE, STRICT) \
- + metag_legitimate_off_p (BASE, OFF, MODE, STRICT)
- +
- +/* [ Rb + Ro ] */
- +#define METAG_LEGITIMATE_TWIN_P(BASE, OFF, MODE, STRICT) \
- + metag_legitimate_twin_p (BASE, OFF, MODE, STRICT)
- +
- +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
- + do { \
- + if (metag_legitimate_address_p (X, MODE, REG_OK_STRICT_FLAG)) \
- + goto LABEL; \
- + } while (0)
- +
- +#define SYMBOLIC_CONST(X) \
- + (SYMBOL_REF_P (X) \
- + || LABEL_REF_P (X) \
- + || (GET_CODE (X) == CONST && metag_symbolic_reference_mentioned_p (X)))
- +
- +/* Go to LABEL if ADDR (a legitimate address expression)
- + has an effect that depends on the machine mode it is used for. */
- +#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
- + do { \
- + if ( GET_CODE (ADDR) == PRE_DEC \
- + || GET_CODE (ADDR) == POST_DEC \
- + || GET_CODE (ADDR) == PRE_INC \
- + || GET_CODE (ADDR) == POST_INC \
- + || GET_CODE (ADDR) == PRE_MODIFY \
- + || GET_CODE (ADDR) == POST_MODIFY) \
- + goto LABEL; \
- + } while (0)
- +
- +/* Specify the machine mode that this machine uses
- + for the index in the tablejump instruction. */
- +#define CASE_VECTOR_MODE SImode
- +
- +/* Define as C expression which evaluates to nonzero if the tablejump
- + instruction expects the table to contain offsets from the address of the
- + table. */
- +#define CASE_VECTOR_PC_RELATIVE 1
- +
- +/* Define this as 1 if `char' should by default be signed; else as 0. */
- +#define DEFAULT_SIGNED_CHAR 0
- +
- +/* Max number of bytes we can move from memory to memory
- + in one reasonably fast instruction. */
- +#define MOVE_MAX 4
- +
- +/* Nonzero if access to memory by bytes is the same speed as words */
- +#define SLOW_BYTE_ACCESS 1
- +
- +/* Define this to be nonzero if shift instructions ignore all but the low-order
- + few bits. */
- +#define SHIFT_COUNT_TRUNCATED 1
- +
- +/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- + is done just by pretending it is already truncated. */
- +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
- +
- +/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
- + will either zero-extend or sign-extend. The value of this macro should
- + be the code that says which one of the two operations is implicitly
- + done, NIL if none. */
- +#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
- +
- +/* We assume that the store-condition-codes instructions store 0 for false
- + and some other value for true. This is the value stored for true. */
- +/* #define STORE_FLAG_VALUE -1 */
- +
- +/* Define this macro if it is advisable to hold scalars in registers
- + in a wider mode than that declared by the program. In such cases,
- + the value is constrained to be within the bounds of the declared
- + type, but kept valid in the wider mode. The signedness of the
- + extension may differ from that of the type. It is faster to
- + zero extend chars than to sign extend them on META, with 16 bit
- + values it's less obvious */
- +#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
- + do { \
- + if (GET_MODE_CLASS (MODE) == MODE_INT \
- + && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
- + (MODE) = SImode; \
- + } while (0)
- +
- +/* Specify the machine mode that pointers have.
- + After generation of rtl, the compiler makes no further distinction
- + between pointers and any other objects of this machine mode. */
- +#define Pmode SImode
- +
- +/* A function address in a call instruction
- + is a byte address (for indexing purposes)
- + so give the MEM rtx a byte's mode. */
- +#define FUNCTION_MODE QImode
- +
- +/* Try to generate sequences that don't involve branches; enables cc insts */
- +#define BRANCH_COST 3
- +
- +/* Comparison extensions-
- +
- + CC_NOOVmode is used when the state of the overflow flag is irrelavent to
- + the compare case - e.g. comparison against zero is required.
- +
- + CC_Zmode is used as a more refined case of CC_NOOVmode where only the zero
- + flag is relevant. For example if a HI or QI source value is being tested
- + directly and the condition in EQ or NE in this case it's left to the
- + pattern to check for other factors like zero as rhs of comparison.
- +
- +*/
- +
- +#define SELECT_CC_MODE(OP, X, Y) \
- + metag_select_cc_mode ((OP), (X), (Y))
- +
- +#define REVERSIBLE_CC_MODE(MODE) (1)
- +
- +#define REVERSE_CONDITION(CODE, MODE) \
- + (((MODE) != CC_FPmode && (MODE) != CC_FP_Qmode) ? reverse_condition (CODE) \
- + : reverse_condition_maybe_unordered (CODE))
- +
- +/* Output to assembler file text saying following lines
- + may contain character constants, extra white space, comments, etc. */
- +
- +#define ASM_APP_ON ""
- +
- +/* Output to assembler file text saying following lines
- + no longer contain unusual constructs. */
- +
- +#define ASM_APP_OFF ""
- +
- +
- +
- +#define METAG_SYMBOL_FLAG_DIRECT (SYMBOL_FLAG_MACH_DEP << 0)
- +#define METAG_SYMBOL_FLAG_DIRECT_P(SYMBOL) \
- + ((SYMBOL_REF_FLAGS (SYMBOL) & METAG_SYMBOL_FLAG_DIRECT) != 0)
- +
- +#define METAG_SYMBOL_FLAG_SMALL (SYMBOL_FLAG_MACH_DEP << 1)
- +#define METAG_SYMBOL_FLAG_SMALL_P(SYMBOL) \
- + ((SYMBOL_REF_FLAGS (SYMBOL) & METAG_SYMBOL_FLAG_SMALL) != 0)
- +
- +#define METAG_SYMBOL_FLAG_LARGE (SYMBOL_FLAG_MACH_DEP << 2)
- +#define METAG_SYMBOL_FLAG_LARGE_P(SYMBOL) \
- + ((SYMBOL_REF_FLAGS (SYMBOL) & METAG_SYMBOL_FLAG_LARGE) != 0)
- +
- +#define METAG_SYMBOL_FLAG_GLOBAL (SYMBOL_FLAG_MACH_DEP << 3)
- +#define METAG_SYMBOL_FLAG_GLOBAL_P(SYMBOL) \
- + ((SYMBOL_REF_FLAGS (SYMBOL) & METAG_SYMBOL_FLAG_GLOBAL) != 0)
- +
- +#define METAG_SYMBOL_FLAG_BYTE (SYMBOL_FLAG_MACH_DEP << 4)
- +#define METAG_SYMBOL_FLAG_BYTE_P(SYMBOL) \
- + ((SYMBOL_REF_FLAGS (SYMBOL) & METAG_SYMBOL_FLAG_BYTE) != 0)
- +
- +#define METAG_SYMBOL_FLAG_WORD (SYMBOL_FLAG_MACH_DEP << 5)
- +#define METAG_SYMBOL_FLAG_WORD_P(SYMBOL) \
- + ((SYMBOL_REF_FLAGS (SYMBOL) & METAG_SYMBOL_FLAG_WORD) != 0)
- +
- +#define METAG_SYMBOL_FLAG_DWORD (SYMBOL_FLAG_MACH_DEP << 6)
- +#define METAG_SYMBOL_FLAG_DWORD_P(SYMBOL) \
- + ((SYMBOL_REF_FLAGS (SYMBOL) & METAG_SYMBOL_FLAG_DWORD) != 0)
- +
- +#define METAG_SYMBOL_FLAG_LONG (SYMBOL_FLAG_MACH_DEP << 7)
- +#define METAG_SYMBOL_FLAG_LONG_P(SYMBOL) \
- + ((SYMBOL_REF_FLAGS (SYMBOL) & METAG_SYMBOL_FLAG_LONG) != 0)
- +
- +#define OVERRIDE_OPTIONS \
- + metag_override_options ()
- +
- +/* How to refer to registers in assembler output.
- + This sequence is indexed by compiler's hard-register-number (see above). */
- +
- +#define REGISTER_NAMES \
- +{ \
- + /* D0/D1 */ \
- + "D0Re0", "D1Re0", "D0Ar6", "D1Ar5", "D0Ar4", "D1Ar3", "D0Ar2", "D1Ar1", \
- + "D0.4", "D1RtP", "D0.5", "D1.5", "D0.6", "D1.6", "D0.7", "D1.7", \
- + /* D0/D1 reserved */ \
- + "D0.8", "D1.8", "D0.9", "D1.9", "D0.10", "D1.10", "D0.11", "D1.11", \
- + "D0.12", "D1.12", "D0.13", "D1.13", "D0.14", "D1.14", "D0.15", "D1.15", \
- + /* A0/A1 */ \
- + "A0StP", "A1GbP", "A0FrP", "A1LbP", "A0.2", "A1.2", "A0.3", "A1.3", \
- + "A0.4", "A1.4", "A0.5", "A1.5", "A0.6", "A1.6", "A0.7", "A1.7", \
- + /* Fakes may be seen in RTL */ \
- + "FRAMEP","MCC", "ARGP", "RAPF", "CPC0", "CPC1", "PC", "TXRPT", \
- + /* FX */ \
- + "FX.0", "FX.1", "FX.2" , "FX.3" , "FX.4" , "FX.5" , "FX.6" , "FX.7" , \
- + "FX.8", "FX.9", "FX.10", "FX.11", "FX.12", "FX.13", "FX.14", "FX.15", \
- + /* TTREC(L) */ \
- + "TTREC", "TTRECL" \
- +}
- +
- +#define ADDITIONAL_REGISTER_NAMES \
- +{ \
- + {"D0.0", D0_0_REG}, \
- + {"D1.0", D1_0_REG}, \
- + {"D0.1", D0_1_REG}, \
- + {"D1.1", D1_1_REG}, \
- + {"D0.2", D0_2_REG}, \
- + {"D1.2", D1_2_REG}, \
- + {"D0.3", D0_3_REG}, \
- + {"D1.3", D1_3_REG}, \
- + {"D1.4", D1_4_REG}, \
- + {"A0.0", A0_0_REG}, \
- + {"A1.0", A1_0_REG}, \
- + {"A0.1", A0_1_REG}, \
- + {"A1.1", A1_1_REG}, \
- + {"D0FrT", D0_4_REG}, \
- + {"cc", CC_REG} \
- +}
- +
- +#define ASM_IDENTIFY_CPU ".cpu"
- +
- +#define META_IDENTIFY_CPU(FILE) \
- + fprintf (FILE, "!\t%s\tmeta%s\n", ASM_IDENTIFY_CPU, metag_cpu_string)
- +
- +/* A FILE comment and register declaration section should always
- + begin the output. */
- +
- +/* Use direct B xx jump tables in code */
- +#define JUMP_TABLES_IN_TEXT_SECTION 1
- +
- +/* How to renumber registers for dbx and gdb. */
- +
- +#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
- +
- +#undef DWARF2_DENUGGING_INFO
- +#define DWARF2_DEBUGGING_INFO 1
- +#define CAN_DEBUG_WITHOUT_FP
- +
- +#define SUPPORTS_INIT_PRIORITY 0
- +
- +/* The prefix to add to internally generated labels. */
- +#undef LOCAL_LABEL_PREFIX
- +#define LOCAL_LABEL_PREFIX "$"
- +
- +#undef IMMEDIATE_PREFIX
- +#define IMMEDIATE_PREFIX "#"
- +
- +/* This is how to output an insn to push a register on the stack.
- + It need not be very fast code. */
- +
- +#define ASM_OUTPUT_REG_PUSH(FILE, REGNO) \
- + fprintf (FILE, "\tSETD\t[%s+#4++], %s\n", \
- + reg_names[STACK_POINTER_REGNUM], reg_names[REGNO])
- +
- +/* This is how to output an insn to pop a register from the stack.
- + It need not be very fast code. */
- +#define ASM_OUTPUT_REG_POP(FILE, REGNO) \
- + fprintf (FILE, "\tGETD\t%s, [%s+#(-4)++]\n", reg_names[REGNO], \
- + reg_names[STACK_POINTER_REGNUM])
- +
- +/* This is how to output an element of a case-vector that is absolute. */
- +#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
- + asm_fprintf (FILE, "\t%s\t%L%d\t" ASM_COMMENT_START \
- + " (abs table not expected)\n", \
- + targetm.asm_out.aligned_op.si, \
- + VALUE)
- +
- +
- +/* This is how to output an element of a case-vector that is relative. */
- +/* This is the first implementation of MiniM short branches. There is no check
- + to ensure jump targets are in range of a short encoding yet. Short is used
- + if requested otherwise long is used */
- +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
- + asm_fprintf (FILE, "\t%sB\t%LL%d\t\t" ASM_COMMENT_START \
- + " (table %LL%d OK)\n", \
- + (!TARGET_MINIM) ? "" : \
- + ((metag_jump_table_branch == METAG_MINIM_JUMP_TABLE_BRANCH_AUTO \
- + && cfun->machine->can_use_short_branch) \
- + || metag_jump_table_branch == METAG_MINIM_JUMP_TABLE_BRANCH_SHORT) \
- + ? "XS\t" : "XL\t", \
- + VALUE, REL)
- +
- +#define PRINT_OPERAND(FILE, X, CODE) \
- + metag_print_operand (FILE, X, CODE)
- +
- +#ifdef ENABLE_ASSERT_CHECKING
- +#define ASM_OUTPUT_OPCODE(FILE, OPCODE) \
- + metag_asm_output_opcode (FILE, OPCODE)
- +#endif /* ENABLE_ASSERT_CHECKING */
- +
- +#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
- + metag_print_operand_address (FILE, ADDR)
- +
- +#define OUTPUT_ADDR_CONST_EXTRA(FILE, X, FAIL) \
- + do { \
- + if (!metag_output_addr_const_extra (FILE, X)) \
- + goto FAIL; \
- + } while (0)
- +
- +/* On the META we want to pass partial stack/reg arguments such that
- + * the first N bytes of the argument are passed on the stack and the
- + * remaining M bytes of the argument are passed in registers.
- + *
- + * This allows the function prologue to just push the partial registers
- + * onto the stack, which can be combined with the normal stack frame
- + * setup.
- + *
- + * This macro is used in the machine independent files expr.c and function.c
- + * to enable some META specific code for handling partial args.
- + */
- +#define METAG_PARTIAL_ARGS 1
- +
- +/* Only perform branch elimination (by making instructions conditional) if
- + we're optimising. Otherwise it's of no use anyway. */
- +#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
- + do { \
- + if (TARGET_COND_EXEC_OPTIMIZE) \
- + { \
- + int saved_alternative = which_alternative; \
- + \
- + metag_final_prescan_insn (INSN); \
- + which_alternative = saved_alternative; \
- + } \
- + } while (0)
- +
- +#define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '?' || (CODE) == '@')
- +
- +enum metag_builtins
- +{
- + METAG_BUILTIN_DCACHE_PRELOAD,
- + METAG_BUILTIN_DCACHE_FLUSH,
- + METAG_BUILTIN_DCACHE_REFRESH,
- + METAG_BUILTIN_META2_CACHERD,
- + METAG_BUILTIN_META2_CACHERL,
- + METAG_BUILTIN_META2_CACHEWD,
- + METAG_BUILTIN_META2_CACHEWL,
- + METAG_BUILTIN_METAG_BSWAPS,
- + METAG_BUILTIN_METAG_BSWAP,
- + METAG_BUILTIN_METAG_BSWAPLL,
- + METAG_BUILTIN_METAG_WSWAP,
- + METAG_BUILTIN_METAG_WSWAPLL,
- + METAG_BUILTIN_METAG_DSWAPLL,
- + METAG_BUILTIN_THREAD_POINTER
- +};
- +
- +#define TARGET_BUILTINS_METAC_1_0 \
- + (metac_target == METAC_1_0_ID)
- +
- +#define TARGET_BUILTINS_METAC_1_1 \
- + (metac_target == METAC_1_1_ID)
- +
- +#define TARGET_BUILTINS_METAC_1_2 \
- + (metac_target == METAC_1_2_ID || metac_target == METAC_0_1_ID)
- +
- +#define TARGET_BUILTINS_METAC_2_1 \
- + (metac_target == METAC_2_1_ID)
- +
- +#define METAG_CURRENT_FUNCTION_LOADS_PIC_REGISTER() \
- + metag_current_function_loads_pic_register ()
- +
- +#define ASSEMBLE_SYMBOL_REF(STREAM, X) \
- + assemble_name (STREAM, XSTR (X, 0))
- +
- +/* The architecture define. */
- +extern char metag_arch_name[];
- +
- +/* Target CPU builtins. */
- +#define TARGET_CPU_CPP_BUILTINS() \
- + metag_cpu_cpp_builtins (pfile)
- +
- +#define METAG_CONST_OK_FOR_LETTERS_KPIJ(VALUE) \
- + metag_const_ok_for_letters_p (VALUE, "KIPJ")
- +
- +#define METAG_CONST_OK_FOR_LETTERS_KPIJO3(VALUE) \
- + metag_const_ok_for_letters_p (VALUE, "KIPJO3")
- +
- +#define METAG_LETTER_FOR_CONST(VALUE) \
- + metag_letter_for_const (VALUE)
- +
- +#define METAG_DATA_REG_P(REGNUM) \
- + metag_datareg_p (REGNUM)
- +
- +#define METAG_ADDR_REG_P(REGNUM) \
- + metag_addrreg_p (REGNUM)
- +
- +#define METAG_FPC_REG_P(REGNUM) \
- + metag_fpcreg_p (REGNUM)
- +
- +#define METAG_FPP_REG_P(REGNUM) \
- + metag_fppreg_p (REGNUM)
- +
- +extern char * metag_gen_cond_return_branch (const char *);
- +extern char * metag_gen_cond_return_stub (void);
- +extern void metag_emit_cond_return_stub_if_reqd (void);
- +
- +/* Track the status of condition returns. 'REQD' means that a stub is
- + required at the end of the function. 'DONE' means the stub has been emitted
- + and should not be emitted again */
- +enum metag_cond_return_state
- +{
- + METAG_COND_RETURN_NONE,
- + METAG_COND_RETURN_REQD,
- + METAG_COND_RETURN_DONE
- +};
- +
- +typedef struct machine_function GTY(())
- +{
- + int valid;
- + int can_use_short_branch;
- + int pretend_regs;
- + int anonymous_args;
- + int anonymous_args_size;
- + int uses_pic_offset_table;
- + int loads_pic_register;
- + unsigned int savesize_gp;
- + unsigned int savesize_eh;
- + unsigned int FP_SP_offset;
- + unsigned int pic_save_size;
- + unsigned int out_local_size;
- + int ech_ctx_required;
- + int frame_pointer_needed;
- + int non_leaf;
- + int frame_pointer_epilogue;
- + int accesses_prev_frame;
- + unsigned int extras_gp;
- + unsigned int extras_eh;
- + unsigned int calls_eh_return;
- + int arg_adjust_delta;
- + int frame_adjust_delta;
- + int hwtrace;
- + int hwtrace_leaf;
- + int hwtrace_retpc;
- + enum metag_cond_return_state cond_return_state;
- +} machine_function;
- +
- +#define INCOMING_RETURN_ADDR_RTX \
- + gen_rtx_REG (SImode, RETURN_POINTER_REGNUM)
- +
- +#define DWARF_FRAME_RETURN_COLUMN \
- + DWARF_FRAME_REGNUM (RETURN_POINTER_REGNUM)
- +
- +#define ASM_FPRINTF_EXTENSIONS(FILE, ARGS, P) \
- + case '@': \
- + fputs (ASM_COMMENT_START, FILE); \
- + break; \
- + \
- + case 'r': \
- + fputs (reg_names [va_arg (ARGS, unsigned int)], file); \
- + break;
- +
- +#define HARD_REGNO_RENAME_OK_FOR_INSN(INSN, FROM, TO) \
- + metag_hard_regno_rename_ok_p (INSN, FROM, TO)
- +
- +#define EPILOGUE_USES(REGNO) \
- + ((REGNO) == D1RtP_REG || (REGNO) == A0FrP_REG \
- + || (TARGET_ECH && (REGNO) == METAG_ECH_REGNUM))
- +
- +#define METAG_USE_RETURN_INSN(ISCOND) \
- + metag_use_return_insn (ISCOND)
- +
- +/* A stucture to support counting the number of doloop optimised loops per nest */
- +struct doloopnest
- +{
- + struct loop* inner;
- + struct doloopnest* next;
- +};
- +
- +#define DOLOOP_OPTIMIZE_INIT() \
- + struct doloopnest * nests = NULL
- +
- +#define DOLOOP_OPTIMIZE_LOOP(LOOP) \
- + do { \
- + /* Determine if any inner loop nests are already optimized */ \
- + if (!metag_doloop_check_any_nest_optimized (LOOP, nests)) \
- + /* If we doloop optimize this loop, mark all inner loops as optimized */ \
- + if (doloop_optimize (LOOP)) \
- + metag_doloop_mark_nests_optimized (LOOP, &nests); \
- + } while (0)
- +
- +
- +#define DOLOOP_OPTIMIZE_FINI() \
- + do { \
- + /* Free the doloop nest counters */ \
- + while (nests != NULL) \
- + { \
- + struct doloopnest * next = nests->next; \
- + \
- + free (nests); \
- + nests = next; \
- + } \
- + } while (0)
- +
- +/* Try a machine-dependent way of reloading an illegitimate address
- + operand. If we find one, push the reload and jump to WIN. This
- + macro is used in only one place: `find_reloads_address' in reload.c.
- +
- + For the META, we wish to handle large displacements off a base
- + register by splitting the addend across a MOV and the mem insn.
- + This can cut the number of reloads needed. */
- +#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND, WIN) \
- + do { \
- + rtx new ## X = metag_legitimize_reload_address (X, MODE, OPNUM, TYPE, IND); \
- + \
- + if (new ## X) \
- + { \
- + (X) = new ## X; \
- + goto WIN; \
- + } \
- + } while (0)
- +
- +#define METAG_ELIMINABLE_REG_P(X) \
- + (REGNO (X) == FRAME_POINTER_REGNUM || REGNO (X) == ARG_POINTER_REGNUM)
- +
- +
- +#define SPLIT_EARLY \
- + metag_split_early ()
- +
- +#define SPLIT_HI_LO_SUM_EARLY \
- + metag_split_hi_lo_sum_early ()
- +
- +#define CALLER_SAVE_INSN_CODE(CODE) (-1)
- +
- +/* In driver-metag.c. */
- +extern const char *metag_reduce_options (int argc, const char **argv);
- +extern const char *metag_emb_asm_preprocessor (int argc, const char **argv);
- +extern const char *metag_emb_onlylast (int argc, const char **argv);
- +extern const char *metag_emb_change_suffix (int argc, const char **argv);
- +#define EXTRA_SPEC_FUNCTIONS \
- + { "meta_preprocessor", metag_emb_asm_preprocessor }, \
- + { "meta_reduce_options", metag_reduce_options }, \
- + { "meta_onlylast", metag_emb_onlylast }, \
- + { "meta_change_suffix", metag_emb_change_suffix },
- +
- +
- +/* Do not re-invent the wheel!
- + Instead of writing our very own option file expander, get gcc to do it
- + convert the -mcpu-config=file option to be @file and expand */
- +
- +#define GCC_DRIVER_HOST_INITIALIZATION \
- + do { \
- + int i; \
- + char * inject_options = getenv ("METAG_COMPILER_OPTIONS"); \
- + \
- + /* Allow option injection from the environment primarily to reduce the \
- + build system logic required when building GCC with its library code and \
- + data in sections with non-standard names. This feature may find uses \
- + outside of this initial purpose but it's general use is discouraged. */ \
- + \
- + if (inject_options != NULL) \
- + { \
- + int env_argc = 0; \
- + int new_argc = 0; \
- + char** new_argv = NULL; \
- + char** env_argv = buildargv (inject_options); \
- + \
- + if (env_argv == NULL) \
- + { \
- + fputs ("\nout of memory\n", stderr); \
- + xexit (1); \
- + } \
- + \
- + /* Count the number of arguments. */ \
- + while (env_argv[env_argc] && *env_argv[env_argc]) \
- + ++env_argc; \
- + \
- + /* Make space for the new arguments */ \
- + new_argc = argc + env_argc; \
- + new_argv = (char **)xmalloc (sizeof (char*) * (new_argc + 1)); \
- + \
- + /* Fill in the new argv */ \
- + new_argv[0] = argv[0]; \
- + memcpy (new_argv + 1, env_argv, sizeof (char *) * env_argc); \
- + memcpy (new_argv + env_argc + 1, argv + 1, \
- + sizeof (char *) * (argc - 1)); \
- + new_argv[new_argc] = NULL; \
- + \
- + /* Swap in the new argv */ \
- + argv = new_argv; \
- + argc = new_argc; \
- + \
- + /* Free the env_argv */ \
- + free (env_argv); \
- + } \
- + \
- + for (i = 1 ; i < argc ; i++) \
- + { \
- + if (strncmp ("-mcpu-config=", argv[i], 13) == 0) \
- + { \
- + argv[i] = argv[i]+12; \
- + *argv[i] = '@'; \
- + } \
- + } \
- + \
- + expandargv (&argc, &argv); \
- + \
- + prune_options (&argc, &argv); \
- + } while (0)
- +
- +#endif /* __METAG_H */
- +
- +#define METAG_HAVE_TLS targetm.have_tls
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/metag-linux.c gcc-4.2.4/gcc/config/metag/metag-linux.c
- --- gcc-4.2.4.orig/gcc/config/metag/metag-linux.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/metag-linux.c 2015-07-03 18:46:05.749283542 -0500
- @@ -0,0 +1,660 @@
- +/* Definitions of target machine for GNU compiler.
- + Imagination Technologies Meta version.
- + Copyright (C) 2008
- + Imagination Technologies Ltd
- +
- +This file is part of GCC.
- +
- +GCC 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 3, or (at your option) any later
- +version.
- +
- +GCC 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 GCC; see the file COPYING3. If not see
- +<http://www.gnu.org/licenses/>. */
- +
- +#include "config.h"
- +#include "system.h"
- +#include "coretypes.h"
- +#include "tm.h"
- +#include "rtl.h"
- +#include "tree.h"
- +#include "obstack.h"
- +#include "regs.h"
- +#include "hard-reg-set.h"
- +#include "real.h"
- +#include "insn-config.h"
- +#include "conditions.h"
- +#include "insn-flags.h"
- +#include "output.h"
- +#include "insn-attr.h"
- +#include "flags.h"
- +#include "reload.h"
- +#include "function.h"
- +#include "expr.h"
- +#include "optabs.h"
- +#include "toplev.h"
- +#include "recog.h"
- +#include "ggc.h"
- +#include "except.h"
- +#include "c-pragma.h"
- +#include "integrate.h"
- +#include "cfgloop.h"
- +#include "tm_p.h"
- +#include "timevar.h"
- +#include "options.h"
- +#include "cgraph.h"
- +#include "target.h"
- +#include "target-def.h"
- +#include "tm-constrs.h"
- +#include "langhooks.h"
- +#include "version.h"
- +
- +/* --------------------------- begin target defines --------------------------*/
- +/* --------------------------- begin asm_out section -------------------------*/
- +
- +#undef TARGET_ASM_ALIGNED_DI_OP
- +#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
- +
- +#undef TARGET_ASM_INTERNAL_LABEL
- +#define TARGET_ASM_INTERNAL_LABEL metag_internal_label
- +
- +#undef TARGET_ASM_FUNCTION_PROLOGUE
- +#define TARGET_ASM_FUNCTION_PROLOGUE metag_function_prologue
- +
- +#undef TARGET_ASM_FUNCTION_END_PROLOGUE
- +#define TARGET_ASM_FUNCTION_END_PROLOGUE metag_function_end_prologue
- +
- +#undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
- +#define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE metag_function_begin_epilogue
- +
- +#undef TARGET_ASM_FUNCTION_EPILOGUE
- +#define TARGET_ASM_FUNCTION_EPILOGUE metag_function_epilogue
- +
- +static section * metag_bfd_select_section (tree, int, unsigned HOST_WIDE_INT);
- +#undef TARGET_ASM_SELECT_SECTION
- +#define TARGET_ASM_SELECT_SECTION metag_bfd_select_section
- +
- +static void metag_bfd_asm_unique_section (tree, int);
- +#undef TARGET_ASM_UNIQUE_SECTION
- +#define TARGET_ASM_UNIQUE_SECTION metag_bfd_asm_unique_section
- +
- +#undef TARGET_ASM_OUTPUT_MI_THUNK
- +#define TARGET_ASM_OUTPUT_MI_THUNK metag_output_mi_thunk
- +
- +#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
- +#define TARGET_ASM_CAN_OUTPUT_MI_THUNK metag_can_output_mi_thunk
- +
- +/* A FILE comment and register declaration section must always
- + * begin the output. */
- +static void metag_bfd_asm_file_start (void);
- +#undef TARGET_ASM_FILE_START
- +#define TARGET_ASM_FILE_START metag_bfd_asm_file_start
- +
- +/* Tidies everything up at the end of the file. */
- +static void metag_bfd_asm_file_end (void);
- +#undef TARGET_ASM_FILE_END
- +#define TARGET_ASM_FILE_END metag_bfd_asm_file_end
- +
- +/* ---------------------------- end asm_out section --------------------------*/
- +/* ---------------------------- begin sched section --------------------------*/
- +
- +#undef TARGET_SCHED_ADJUST_COST
- +#define TARGET_SCHED_ADJUST_COST metag_sched_adjust_cost
- +
- +/* ----------------------------- end sched section ---------------------------*/
- +/* ---------------------------- begin vector section -------------------------*/
- +/* ----------------------------- end vector section --------------------------*/
- +/* ------------------------------- begin section -----------------------------*/
- +
- +#undef TARGET_DEFAULT_TARGET_FLAGS
- +#ifdef MINIM_DEFAULT
- +#define TARGET_DEFAULT_TARGET_FLAGS ((MASK_COND_EXEC) | (MASK_MINIM) | (MASK_MINIM_OPTIMISE) | (MASK_FLUSH_TO_ZERO))
- +#else
- +#define TARGET_DEFAULT_TARGET_FLAGS ((MASK_COND_EXEC) | (MASK_MINIM_OPTIMISE) | (MASK_FLUSH_TO_ZERO))
- +#endif
- +
- +#undef TARGET_HANDLE_OPTION
- +#define TARGET_HANDLE_OPTION metag_handle_option
- +
- +#undef TARGET_MERGE_DECL_ATTRIBUTES
- +#define TARGET_MERGE_DECL_ATTRIBUTES metag_merge_decl_attributes
- +
- +#undef TARGET_MERGE_TYPE_ATTRIBUTES
- +#define TARGET_MERGE_TYPE_ATTRIBUTES metag_merge_type_attributes
- +
- +#undef TARGET_ATTRIBUTE_TABLE
- +#define TARGET_ATTRIBUTE_TABLE metag_attribute_table
- +
- +#undef TARGET_COMP_TYPE_ATTRIBUTES
- +#define TARGET_COMP_TYPE_ATTRIBUTES metag_comp_type_attributes
- +
- +#undef TARGET_INIT_BUILTINS
- +#define TARGET_INIT_BUILTINS metag_init_builtins
- +
- +#undef TARGET_EXPAND_BUILTIN
- +#define TARGET_EXPAND_BUILTIN metag_expand_builtin
- +
- +#undef TARGET_FUNCTION_OK_FOR_SIBCALL
- +#define TARGET_FUNCTION_OK_FOR_SIBCALL metag_function_ok_for_sibcall
- +
- +#undef TARGET_ENCODE_SECTION_INFO
- +#define TARGET_ENCODE_SECTION_INFO metag_encode_section_info
- +
- +static const char *metag_bfd_strip_name_encoding (const char *);
- +#undef TARGET_STRIP_NAME_ENCODING
- +#define TARGET_STRIP_NAME_ENCODING metag_bfd_strip_name_encoding
- +
- +#undef TARGET_SCALAR_MODE_SUPPORTED_P
- +#define TARGET_SCALAR_MODE_SUPPORTED_P metag_scalar_mode_supported_p
- +
- +#undef TARGET_VECTOR_MODE_SUPPORTED_P
- +#define TARGET_VECTOR_MODE_SUPPORTED_P metag_vector_mode_supported_p
- +
- +#undef TARGET_RTX_COSTS
- +#define TARGET_RTX_COSTS metag_rtx_costs
- +
- +#undef TARGET_ADDRESS_COST
- +#define TARGET_ADDRESS_COST metag_address_cost
- +
- +#undef TARGET_MACHINE_DEPENDENT_REORG
- +#define TARGET_MACHINE_DEPENDENT_REORG metag_machine_dependent_reorg
- +
- +#undef TARGET_GIMPLIFY_VA_ARG_EXPR
- +#define TARGET_GIMPLIFY_VA_ARG_EXPR metag_gimplify_va_arg_expr
- +
- +#undef TARGET_INVALID_WITHIN_DOLOOP
- +#define TARGET_INVALID_WITHIN_DOLOOP metag_invalid_within_doloop
- +
- +/* -------------------------------- end section ------------------------------*/
- +/* ---------------------------- begin calls section --------------------------*/
- +
- +#undef TARGET_PROMOTE_FUNCTION_ARGS
- +#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
- +
- +#undef TARGET_PROMOTE_FUNCTION_RETURN
- +#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
- +
- +#undef TARGET_FUNCTION_VALUE
- +#define TARGET_FUNCTION_VALUE metag_function_value
- +
- +#undef TARGET_PROMOTE_PROTOTYPES
- +#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
- +
- +#undef TARGET_PASS_BY_REFERENCE
- +#define TARGET_PASS_BY_REFERENCE metag_pass_by_reference
- +
- +#undef TARGET_SETUP_INCOMING_VARARGS
- +#define TARGET_SETUP_INCOMING_VARARGS metag_setup_incoming_varargs
- +
- +#undef TARGET_MUST_PASS_IN_STACK
- +#define TARGET_MUST_PASS_IN_STACK metag_must_pass_in_stack
- +
- +#undef TARGET_ARG_PARTIAL_BYTES
- +#define TARGET_ARG_PARTIAL_BYTES metag_arg_partial_bytes
- +
- +/* ----------------------------- end calls section ---------------------------*/
- +/* ------------------------------- begin section -----------------------------*/
- +
- +#undef TARGET_SECONDARY_RELOAD
- +#define TARGET_SECONDARY_RELOAD metag_secondary_reload
- +
- +/* -------------------------------- end section ------------------------------*/
- +/* ----------------------------- begin cxx section ---------------------------*/
- +
- +/* C++ specific macros */
- +
- +/* ------------------------------ end cxx section ----------------------------*/
- +/* ------------------------------- begin section -----------------------------*/
- +
- +#undef TARGET_HAVE_NAMED_SECTIONS
- +#define TARGET_HAVE_NAMED_SECTIONS true
- +
- +#undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
- +#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
- +
- +/* -------------------------------- end section ------------------------------*/
- +
- +#undef TARGET_CANNOT_FORCE_CONST_MEM
- +#define TARGET_CANNOT_FORCE_CONST_MEM metag_bfd_tls_referenced_p
- +
- +struct gcc_target targetm = TARGET_INITIALIZER;
- +
- +/* ---------------------------- end target defines ---------------------------*/
- +
- +static void
- +metag_bfd_asm_file_start (void)
- +{
- + fprintf (asm_out_file, "%s Generated by gcc %s for Meta(Linux)/elf\n",
- + ASM_COMMENT_START, version_string);
- +
- + fputc ('\n', asm_out_file);
- + output_file_directive (asm_out_file, main_input_filename);
- +
- + fputc ('\n', asm_out_file);
- + META_IDENTIFY_CPU (asm_out_file);
- + fputc ('\n', asm_out_file);
- +}
- +
- +static void
- +metag_bfd_asm_file_end (void)
- +{
- + return;
- +}
- +
- +static const char *
- +metag_bfd_strip_name_encoding (const char *str)
- +{
- + gcc_assert (str[0] != '&');
- +
- + return str + (str[0] == '*');
- +}
- +
- +/* Construct a unique section name based on the decl name and the
- + categorization performed above. */
- +
- +static void
- +metag_bfd_asm_unique_section (tree decl, int reloc)
- +{
- + /* We only need to use .gnu.linkonce if we don't have COMDAT groups. */
- + bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP;
- + const char *prefix, *name;
- + size_t nlen, plen;
- + char *string;
- +
- + switch (categorize_decl_for_section (decl, reloc))
- + {
- + case SECCAT_TEXT:
- + prefix = one_only ? ".gnu.linkonce.t." : ".text.";
- + break;
- + case SECCAT_RODATA:
- + prefix = one_only ? ".gnu.linkonce.r." : ".rodata.";
- + break;
- + case SECCAT_RODATA_MERGE_STR:
- + case SECCAT_RODATA_MERGE_STR_INIT:
- + case SECCAT_RODATA_MERGE_CONST:
- + prefix = one_only ? ".gnu.linkonce.r." : ".rodata.";
- + break;
- + case SECCAT_SRODATA:
- + prefix = one_only ? ".gnu.linkonce.s2." : ".sdata2.";
- + break;
- + case SECCAT_DATA:
- + prefix = one_only ? ".gnu.linkonce.d." : ".data.";
- + break;
- + case SECCAT_DATA_REL:
- + prefix = one_only ? ".gnu.linkonce.d.rel." : ".data.rel.";
- + break;
- + case SECCAT_DATA_REL_LOCAL:
- + prefix = one_only ? ".gnu.linkonce.d.rel.local" : ".data.rel.local.";
- + break;
- + case SECCAT_DATA_REL_RO:
- + prefix = one_only ? ".gnu.linkonce.d.rel.ro." : ".data.rel.ro.";
- + break;
- + case SECCAT_DATA_REL_RO_LOCAL:
- + prefix = one_only ? ".gnu.linkonce.d.rel.ro.local." : ".data.rel.ro.local.";
- + break;
- + case SECCAT_SDATA:
- + prefix = one_only ? ".gnu.linkonce.s." : ".sdata.";
- + break;
- + case SECCAT_BSS:
- + prefix = one_only ? ".gnu.linkonce.d." : ".data.";
- + break;
- + case SECCAT_SBSS:
- + prefix = one_only ? ".gnu.linkonce.s." : ".sdata.";
- + break;
- + /* Add default handlers to deal with tdata and tbss sections */
- + case SECCAT_TDATA:
- + prefix = one_only ? ".gnu.linkonce.td." : ".tdata.";
- + break;
- + case SECCAT_TBSS:
- + prefix = one_only ? ".gnu.linkonce.tb." : ".tbss.";
- + break;
- + default:
- + gcc_unreachable ();
- + }
- + plen = strlen (prefix);
- +
- + name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
- + name = targetm.strip_name_encoding (name);
- + nlen = strlen (name);
- +
- + string = alloca (nlen + plen + 1);
- + memcpy (string, prefix, plen);
- + memcpy (string + plen, name, nlen + 1);
- +
- + DECL_SECTION_NAME (decl) = build_string (nlen + plen, string);
- +}
- +
- +static section *
- +metag_bfd_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
- +{
- + const char *sname;
- +
- + switch (categorize_decl_for_section (decl, reloc))
- + {
- + case SECCAT_TEXT:
- + /* We're not supposed to be called on FUNCTION_DECLs. */
- + gcc_unreachable ();
- + case SECCAT_RODATA:
- + return readonly_data_section;
- + case SECCAT_RODATA_MERGE_STR:
- + return mergeable_string_section (decl, align, 0);
- + case SECCAT_RODATA_MERGE_STR_INIT:
- + return mergeable_string_section (DECL_INITIAL (decl), align, 0);
- + case SECCAT_RODATA_MERGE_CONST:
- + return mergeable_constant_section (DECL_MODE (decl), align, 0);
- + case SECCAT_SRODATA:
- + sname = ".sdata2";
- + break;
- + case SECCAT_DATA:
- + return data_section;
- + case SECCAT_DATA_REL:
- + sname = ".data.rel";
- + break;
- + case SECCAT_DATA_REL_LOCAL:
- + sname = ".data.rel.local";
- + break;
- + case SECCAT_DATA_REL_RO:
- + sname = ".data.rel.ro";
- + break;
- + case SECCAT_DATA_REL_RO_LOCAL:
- + sname = ".data.rel.ro.local";
- + break;
- + case SECCAT_SDATA:
- + sname = ".sdata";
- + break;
- + /* Add default handler to deal with tdata sections */
- + case SECCAT_TDATA:
- + sname = ".tdata";
- + break;
- + case SECCAT_BSS:
- + return data_section;
- + case SECCAT_SBSS:
- + return sdata_section;
- + /* Add default handler to deal with tbss sections */
- + case SECCAT_TBSS:
- + sname = ".tbss";
- + break;
- + default:
- + gcc_unreachable ();
- + }
- + if (!DECL_P (decl))
- + decl = NULL_TREE;
- + return get_named_section (decl, sname, reloc);
- +}
- +
- +bool
- +metag_handle_option_per_os (size_t code ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED, int value ATTRIBUTE_UNUSED)
- +{
- + return true;
- +}
- +
- +void
- +metag_override_options_per_os (void)
- +{
- + if (TARGET_MTX)
- + error ("Meta Linux does not have MTX support");
- +
- + if (metac_target == METAC_1_0_ID
- + || metac_target == METAC_1_1_ID
- + || metac_target == METAC_0_1_ID)
- + error ("Meta Linux does not have support for the specified core");
- +}
- +
- +/* Return 1 if X is a thread local symbol */
- +
- +static int
- +metag_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
- +{
- + if (GET_CODE (*x) == SYMBOL_REF)
- + return SYMBOL_REF_TLS_MODEL (*x) != 0;
- +
- + /* Don't recurse into UNSPEC_TLS looking for TLS symbols; these are
- + TLS offsets, not real symbol references. */
- + if (GET_CODE (*x) == UNSPEC
- + && XINT (*x, 1) >= UNSPEC_FIRST_TLS
- + && XINT (*x, 1) <= UNSPEC_LAST_TLS)
- + return -1;
- +
- + return 0;
- +}
- +
- +/* Return 1 if X contains a thread-local symbol. */
- +
- +bool
- +metag_bfd_tls_referenced_p (rtx x)
- +{
- + if (!METAG_HAVE_TLS)
- + return false;
- +
- + return for_each_rtx (&x, &metag_tls_symbol_ref_1, 0);
- +}
- +
- +bool
- +metag_function_ok_for_sibcall_per_os (tree fndecl ATTRIBUTE_UNUSED, tree exp ATTRIBUTE_UNUSED)
- +{
- + return true;
- +}
- +
- +void
- +metag_pad_function_call (rtx symbol_ref ATTRIBUTE_UNUSED)
- +{
- + return;
- +}
- +
- +bool
- +metag_tbiassert_p (rtx symbol_ref ATTRIBUTE_UNUSED)
- +{
- + return false;
- +}
- +
- +/* Construct the SYMBOL_REF for the __tls_get_addr function. */
- +
- +static GTY(()) rtx metag_tls_symbol;
- +
- +static rtx
- +metag_tls_get_addr (void)
- +{
- + if (!metag_tls_symbol)
- + metag_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_addr");
- +
- + return metag_tls_symbol;
- +}
- +
- +/* Construct the SYMBOL_REF for the __metag_load_tp function. */
- +
- +static GTY(()) rtx metag_tp_symbol;
- +
- +static rtx
- +metag_load_tp (void)
- +{
- + if (!metag_tp_symbol)
- + metag_tp_symbol = gen_rtx_SYMBOL_REF (Pmode, "__metag_load_tp");
- +
- + return metag_tp_symbol;
- +}
- +
- +/* Generates rtl to call the metag_load_tp function to get the address of the
- + thread pointer. The rtx representing the register containing this address
- + is then returned. */
- +
- +static rtx
- +gen_metag_load_tp (void)
- +{
- + rtx ret0, ret, tp, tmp, insn, eqv;
- + ret0 = gen_rtx_REG (Pmode, D0Re0_REG);
- + ret = gen_reg_rtx (Pmode);
- + tp = gen_reg_rtx (Pmode);
- +
- + start_sequence ();
- + tmp = gen_rtx_MEM (QImode, metag_load_tp ());
- + insn = gen_call_value (ret0, tmp, const0_rtx);
- + insn = emit_call_insn (insn);
- + CONST_OR_PURE_CALL_P (insn) = 1;
- + insn = get_insns ();
- + end_sequence ();
- +
- + /* We need this equivalence expression so that the RTL optimiser
- + can figure out it only needs to place one call to
- + __metag_load_tp regardless of how many thread-local variables
- + are present. */
- + eqv = gen_rtx_UNSPEC (VOIDmode,
- + gen_rtvec (1, metag_load_tp ()),
- + UNSPEC_TLS);
- + emit_libcall_block (insn, tp, ret0, eqv);
- +
- + return tp;
- +}
- +
- +/* Return the TLS type for TLS symbols, 0 otherwise. */
- +
- +bool
- +tls_symbolic_operand_p (rtx op)
- +{
- + return ((GET_CODE (op) == SYMBOL_REF) && (SYMBOL_REF_TLS_MODEL (op) != 0));
- +}
- +
- +/* These functions are part of a framework to allow the support of OS
- + specific builtin functions within GCC.
- + The only builtin function for META Linux is __builtin_thread_pointer
- + which returns the address of the thread pointer. */
- +
- +void
- +metag_init_builtins_per_os (void)
- +{
- + tree nothrow = tree_cons (get_identifier ("nothrow"), NULL, NULL);
- + tree ftmetag_tp = build_function_type (ptr_type_node, void_list_node);
- +
- + lang_hooks.builtin_function ("__builtin_thread_pointer",
- + ftmetag_tp,
- + METAG_BUILTIN_THREAD_POINTER,
- + BUILT_IN_MD,
- + NULL,
- + nothrow);
- +}
- +
- +/* Performs the expansion of the META Linux builtin functions */
- +
- +rtx
- +metag_expand_builtin_per_os (tree exp, rtx target)
- +{
- + tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
- + int fcode = DECL_FUNCTION_CODE (fndecl);
- +
- + switch(fcode)
- + {
- + case METAG_BUILTIN_THREAD_POINTER: /* void * __builtin_thread_pointer (void) */
- + target = gen_metag_load_tp ();
- + return target;
- + default:
- + break;
- + }
- +
- + return NULL_RTX;
- +}
- +
- +/* Adds code to calculate the address of a TLS operand */
- +
- +rtx
- +metag_bfd_legitimize_tls_address (rtx addr)
- +{
- + rtx tmp, tga, ret, tp, arg1, insn, ret0, eqv;
- +
- + gcc_assert (!no_new_pseudos);
- + gcc_assert (SYMBOL_REF_P(addr));
- +
- + switch (SYMBOL_REF_TLS_MODEL (addr))
- + {
- + case TLS_MODEL_GLOBAL_DYNAMIC:
- +
- + current_function_uses_pic_offset_table = 1;
- + arg1 = gen_rtx_REG (Pmode, D1Ar1_REG);
- + ret0 = gen_rtx_REG (Pmode, D0Re0_REG);
- + ret = gen_reg_rtx (Pmode);
- +
- + start_sequence ();
- + emit_insn (gen_tls_gd (arg1, pic_offset_table_rtx, addr));
- + tga = gen_rtx_MEM (QImode, metag_tls_get_addr ());
- + insn = gen_call_value (ret0, tga, const0_rtx);
- + insn = emit_call_insn (insn);
- + CONST_OR_PURE_CALL_P (insn) = 1;
- + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg1);
- + insn = get_insns ();
- + end_sequence ();
- +
- + emit_libcall_block (insn, ret, ret0, addr);
- +
- + return ret;
- +
- + case TLS_MODEL_LOCAL_DYNAMIC:
- +
- + current_function_uses_pic_offset_table = 1;
- + arg1 = gen_rtx_REG (Pmode, D1Ar1_REG);
- + ret0 = gen_rtx_REG (Pmode, D0Re0_REG);
- + tmp = gen_reg_rtx (Pmode);
- + ret = gen_reg_rtx (Pmode);
- +
- + start_sequence ();
- + emit_insn (gen_tls_ldm (arg1, pic_offset_table_rtx, addr));
- + tga = gen_rtx_MEM (QImode, metag_tls_get_addr ());
- + insn = gen_call_value (ret0, tga, const0_rtx);
- + insn = emit_call_insn (insn);
- + CONST_OR_PURE_CALL_P (insn) = 1;
- + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg1);
- + insn = get_insns ();
- + end_sequence ();
- +
- + /* We need this equivalence expression so that the RTL optimiser
- + can figure out it only needs to place one call to
- + __tls_get_addr regardless of how many local-dynamic model
- + variables are present. */
- + eqv = gen_rtx_UNSPEC (VOIDmode,
- + gen_rtvec (1, metag_tls_get_addr ()),
- + UNSPEC_TLSLDM);
- +
- + emit_libcall_block (insn, tmp, ret0, eqv);
- +
- + insn = gen_tls_ldo (ret, tmp, addr);
- + emit_insn (insn);
- +
- + return ret;
- +
- + case TLS_MODEL_INITIAL_EXEC:
- +
- + tmp = gen_reg_rtx (Pmode);
- +
- + /* Produce different relocations depending on if PIC is enabled or not */
- + if (METAG_FLAG_PIC)
- + {
- + current_function_uses_pic_offset_table = 1;
- + emit_insn (gen_tls_ie (tmp, pic_offset_table_rtx, addr));
- + }
- + else
- + {
- + current_function_uses_pic_offset_table = 0;
- + emit_insn (gen_tls_non_pic_ie (tmp, addr));
- + }
- +
- + tp = gen_metag_load_tp ();
- +
- + return gen_rtx_PLUS (Pmode, tp, tmp);
- +
- + case TLS_MODEL_LOCAL_EXEC:
- +
- + tmp = gen_reg_rtx (Pmode);
- + tp = gen_metag_load_tp ();
- +
- + emit_insn (gen_tls_le (tmp, tp, addr));
- +
- + return tmp;
- +
- + default:
- + gcc_unreachable ();
- + }
- +}
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/metag-linux.h gcc-4.2.4/gcc/config/metag/metag-linux.h
- --- gcc-4.2.4.orig/gcc/config/metag/metag-linux.h 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/metag-linux.h 2015-07-03 18:46:05.749283542 -0500
- @@ -0,0 +1,177 @@
- +/* Definitions of target machine for GNU compiler.
- + Imagination Technologies Meta version.
- + Copyright (C) 2008
- + Imagination Technologies Ltd
- +
- +This file is part of GCC.
- +
- +GCC 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 3, or (at your option) any later
- +version.
- +
- +GCC 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 GCC; see the file COPYING3. If not see
- +<http://www.gnu.org/licenses/>. */
- +
- +#include "metag.h"
- +
- +/* OG and OGA addressing are not available */
- +#define OG_ENABLED false
- +
- +#define METAG_FLAG_PIC flag_pic
- +
- +/* The prefix to add to user-visible assembler symbols. */
- +#undef USER_LABEL_PREFIX
- +#define USER_LABEL_PREFIX "_"
- +
- +#ifdef MINIM_DEFAULT
- +#define DEFAULT_MINIM_ASM_SPEC "%{!mno-minim:-minim} "
- +#else
- +#define DEFAULT_MINIM_ASM_SPEC
- +#endif
- +
- +#define ASM_SPEC \
- + "%:meta_reduce_options(%{mmetac=*&mhard-float*&msoft-float&msimd-float}) " \
- + "%{mdsp:%{mmetac=1.2:-mdsp=metac12}%{mmetac=2.1:-mdsp=metac21}} " \
- + "%{mmetac=0.1:-mcpu=metac01} " \
- + "%{mmetac=1.0:-mcpu=metac10} " \
- + "%{mmetac=1.1:-mcpu=metac11} " \
- + "%{mmetac=1.2:-mcpu=metac12} " \
- + "%{mmetac=2.1:-mcpu=metac21} " \
- + "%{mhard-float*:%{mmetac=2.1:-mfpu=metac21}%{!mmetac=2.1:%eThe floating point unit is only available on a META 2.1}} " \
- + "%{mminim:-minim} " \
- + DEFAULT_MINIM_ASM_SPEC
- +
- +/* This is how to output an assembler line for a numeric constant byte. */
- +
- +#define ASM_OUTPUT_BYTE(FILE, VALUE) \
- + fprintf (FILE, "\t.byte\t0x%x\n", (int) ((VALUE) & 0xff))
- +
- +/* There has been some confusion over the meaning of the .align directive
- + in gas over the last few years. However there is now a new directive
- + called .balign that is explicitly defined as taking an absolute alignment
- + value rather than a log2 value. We will now use this by default if
- + available and leave the old implementation as is (even though it is wrong) */
- +#ifdef HAVE_GAS_BALIGN_AND_P2ALIGN
- +
- +#undef ASM_OUTPUT_ALIGN
- +#define ASM_OUTPUT_ALIGN(FILE, LOG) \
- + do { \
- + if ((LOG)!=0) \
- + fprintf ((FILE), "\t.balign %d\n", 1<<(LOG)); \
- + } while (0)
- +
- +#else
- +
- +#undef ASM_OUTPUT_ALIGN
- +#define ASM_OUTPUT_ALIGN(FILE, LOG) \
- + do { \
- + if ((LOG) != 0) \
- + fprintf (FILE, "%s%u\n", ALIGN_ASM_OP, LOG); \
- + } while (0)
- +
- +#endif
- +
- +/* This says how to output an assembler line
- + to define a global common symbol. */
- +
- +#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
- + do { \
- + fputs ("\t.comm\t", FILE); \
- + assemble_name (FILE, (NAME)); \
- + fprintf (FILE, ",%u\n", (SIZE)); \
- + } while (0)
- +
- +/* This says how to output an assembler line
- + to define a local common symbol. */
- +
- +#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE,ROUNDED) \
- + do { \
- + fputs ("\t.lcomm\t", FILE); \
- + assemble_name (FILE, (NAME)); \
- + fprintf (FILE, ",%u\n", (SIZE)); \
- + } while (0)
- +
- +#define TEXT_SECTION_ASM_OP ".text"
- +
- +#define DATA_SECTION_ASM_OP ".data"
- +
- +#define DATA_SECTION DATA_SECTION_ASM_OP
- +
- +/* Try machine-dependent ways of modifying an illegitimate address
- + to be legitimate. If we find one, return the new, valid address.
- + This macro is used in only one place: `memory_address' in explow.c.
- +
- + OLDX is the address as it was before break_out_memory_refs was called.
- + In some cases it is useful to look at this to decide what needs to be done.
- +
- + MODE and WIN are passed so that this macro can use
- + GO_IF_LEGITIMATE_ADDRESS.
- +
- + It is always safe for this macro to do nothing. It exists to recognize
- + opportunities to optimize the output. */
- +
- +#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
- + do { \
- + (X) = metag_legitimize_address (X, OLDX, MODE); \
- + if (memory_address_p (MODE, X)) \
- + goto WIN; \
- + } while (0)
- +
- +#undef ASM_GENERATE_INTERNAL_LABEL
- +#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
- + sprintf (LABEL, "*%s%s%u", LOCAL_LABEL_PREFIX, PREFIX, (unsigned)(NUM))
- +
- +/* Register to hold the addressing base for position independent
- + code access to data items. */
- +#define PIC_OFFSET_TABLE_REGNUM PIC_REG
- +
- +/* Nonzero if the constant value X is a legitimate general operand
- + when generating PIC code. It is given that flag_pic is on and
- + that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
- +
- +#define LEGITIMATE_PIC_OPERAND_P(X) \
- + (! SYMBOLIC_CONST (X) || metag_legitimate_pic_address_disp_p (X))
- +
- +/* The `FINALIZE_PIC' macro serves as a hook to emit these special
- + codes once the function is being compiled into assembly code, but
- + not before. (It is not done before, because in the case of
- + compiling an inline function, it would lead to multiple PIC
- + prologues being included in functions which used inline functions
- + and were compiled to assembly language.) */
- +
- +#define FIXME_FINALIZE_PIC \
- + do \
- + { \
- + extern int current_function_uses_pic_offset_table; \
- + \
- + current_function_uses_pic_offset_table \
- + |= profile_flag | profile_block_flag; \
- + } \
- + while (0)
- +
- +#define ASSEMBLE_END_FUNCTION(DECL,FNNAME) \
- + do { \
- + metag_emit_cond_return_stub_if_reqd (); \
- + } while (0)
- +
- +#ifdef HAVE_AS_TLS
- +#undef TARGET_HAVE_TLS
- +#define TARGET_HAVE_TLS HAVE_AS_TLS
- +#endif
- +
- +/* Nonzero if the constant value X is a legitimate general operand.
- + It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
- +
- + This is true apart from cases where the symbol represents a TLS
- + symbol. */
- +
- +#undef LEGITIMATE_CONSTANT_P
- +#define LEGITIMATE_CONSTANT_P(X) \
- + (!tls_symbolic_operand_p (X))
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/metag-linux.opt gcc-4.2.4/gcc/config/metag/metag-linux.opt
- --- gcc-4.2.4.orig/gcc/config/metag/metag-linux.opt 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/metag-linux.opt 2015-07-03 18:46:05.749283542 -0500
- @@ -0,0 +1,25 @@
- +; Copyright (C) 2008 Imagination Technologies Ltd
- +
- +; This file is part of GCC.
- +
- +; GCC 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 3, or (at your option) any later
- +; version.
- +
- +; GCC 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 GCC; see the file COPYING3. If not see
- +; <http://www.gnu.org/licenses/>.
- +
- +
- +; Default model is large (small model is 'better' but not supported
- +; in binutils toolchain
- +mmodel=
- +Target RejectNegative Joined Var(metag_model_string) Init("large")
- +Memory access model (small|large) [NOTE: small not supported]
- +
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/metag.md gcc-4.2.4/gcc/config/metag/metag.md
- --- gcc-4.2.4.orig/gcc/config/metag/metag.md 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/metag.md 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,8255 @@
- +;; Machine description for GNU compiler,
- +;; Imagination Technologies Meta version.
- +;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
- +;; Imagination Technologies Ltd
- +
- +;; This file is part of GCC.
- +
- +;; GCC 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 3, or (at your option) any later
- +;; version.
- +
- +;; GCC 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 GCC; see the file COPYING3. If not see
- +;; <http://www.gnu.org/licenses/>.
- +
- +;;- instruction definitions
- +
- +;;- @@The original PO technology requires these to be ordered by speed,
- +;;- @@ so that assigner will pick the fastest.
- +
- +;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
- +
- +;;- When naming insn's (operand 0 of define_insn) be careful about using
- +;;- names from other targets machine descriptions.
- +
- +
- +;; MODE macros
- +(define_mode_macro CCALL [CC_FP CC_FP_Q CC CC_NOOV CC_Z])
- +
- +(define_mode_macro CCFP [CC_FP CC_FP_Q])
- +
- +(define_mode_macro CCANY [CC CC_NOOV CC_Z])
- +
- +(define_mode_macro CCZNC [CC_NOOV CC_Z])
- +
- +(define_mode_macro IMODES [QI HI SI DI])
- +
- +(define_mode_macro FMODES [SF DF])
- +
- +(define_mode_macro FLMODES [SF DF V2SF])
- +
- +; Floating point storage modes
- +; This is same as FMODES at the moment but HF would go here when it's supported
- +; WHen HF is added some insns need to be split as HF conversions have a single
- +; cycle stall whereas others have 5 cycle stalls
- +(define_mode_macro FSMODES [SF DF])
- +
- +(define_mode_macro MODES [QI HI SI DI SF DF V2SF V2SI])
- +
- +(define_mode_macro EXTDI [QI HI SI])
- +
- +(define_mode_macro EXTSI [QI HI])
- +
- +(define_mode_macro EXTHI [QI])
- +
- +(define_mode_macro MEMOP [QI HI SI])
- +
- +;; MODE attrs
- +
- +(define_mode_attr S [(DI "8") (SI "4") (HI "2") (QI "1") (SF "4") (DF "8") (V2SF "8") (V2SI "8")])
- +
- +(define_mode_attr W [(DI "L") (SI "D") (HI "W") (QI "B") (SF "D") (DF "L") (V2SF "L") (V2SI "L")])
- +
- +(define_mode_attr P [(DI "l") (SI "d") (HI "w") (QI "b") (SF "d") (DF "l") (V2SF "l") (V2SI "l")])
- +
- +(define_mode_attr O [(DI "O8") (SI "O4") (HI "O2") (QI "O1") (SF "O4") (DF "O8") (V2SF "O8") (V2SI "O8")])
- +
- +(define_mode_attr Z [(DI "Z8") (SI "Z4") (HI "Z2") (QI "Z1") (SF "Z4") (DF "Z8") (V2SF "Z8") (V2SI "Z8")])
- +
- +(define_mode_attr FT [(SF "F") (DF "D")])
- +(define_mode_attr FW [(SF "" ) (DF "D") (DI "D") (V2SF "L")])
- +(define_mode_attr fcondition [(SF "TARGET_FPU") (DF "TARGET_FPU && !metag_fpu_single") (V2SF "TARGET_FPU_SIMD")])
- +
- +(define_mode_attr CCQ [(CC_FP "") (CC_FP_Q "Q")])
- +
- +;; CODE macros
- +
- +(define_code_macro CCCOND [eq ne gt gtu lt ltu ge geu le leu])
- +
- +(define_code_macro CCFPCOND [eq ne
- + gt ge lt le unordered ltgt ordered
- + ungt unge unlt unle uneq])
- +
- +(define_code_macro CCANYCOND [eq ne
- + gtu ltu geu leu
- + gt ge lt le unordered ordered
- + ungt unge unlt unle])
- +
- +;; These code macros significantly simplify the peephole and vector patterns required
- +;; for supporting dual unit DSP operations
- +
- +(define_code_macro 3OPREG [plus minus and ior xor ashift ashiftrt lshiftrt])
- +(define_code_macro 3OPIMM16 [plus minus and ior xor])
- +(define_code_macro 3OPIMM5 [ashift ashiftrt lshiftrt])
- +(define_code_macro MINMAX [smin smax])
- +
- +;; CODE attrs
- +
- +;; These code attributes are used for peephole and vector patterns that support
- +;; dual unit DSP operations
- +
- +(define_code_attr MNEMONIC [(plus "ADD") (minus "SUB") (and "AND") (ior "OR") (xor "XOR")
- + (ashift "LSL") (ashiftrt "ASR") (lshiftrt "LSR") (smin "MIN")
- + (smax "MAX")])
- +
- +(define_code_attr commutative [(plus "true") (minus "false") (and "true") (ior "true") (xor "true")
- + (ashift "false") (ashiftrt "false") (lshiftrt "false") (smin "true")
- + (smax "true")])
- +
- +(define_code_attr expander [(plus "add") (minus "sub") (and "and") (ior "ior") (xor "xor")
- + (ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr") (smin "smin")
- + (smax "smax")])
- +
- +(define_code_attr dualunitimmcondition [(plus "&& !(TARGET_METAC_1_0 && (INTVAL (operands[1]) & 1) == 1)")
- + (minus "&& !(TARGET_METAC_1_0 && (INTVAL (operands[1]) & 1) == 1)")
- + (and "") (ior "") (xor "") (ashift "") (ashiftrt "") (lshiftrt "")
- + (smin "") (smax "")])
- +
- +;; constants
- +
- +
- +(include "constants.md")
- +(include "predicates.md")
- +(include "constraints.md")
- +(include "pipeline.md")
- +
- +;; Insn type. Used to default other attribute values.
- +(define_attr "type"
- + "fast,swap,slow,two,twox,three,threex,\
- + load,read,four,fourx,five,fivex,sixx,\
- + sevenx,mult,slowslow,nop,block,branch,\
- + FPfast,FPrecip,FPmas,FPrecipmas,unknown,invalid"
- + (const_string "unknown"))
- +
- +;; Indiate of insn is suitable for register renaming
- +(define_attr "rename" "no,yes" (const_string "yes"))
- +
- +;; Indicate if insn is conditional
- +(define_attr "cond" "no,yes" (const_string "no"))
- +
- +;; Conditional execution attribute, implicitly used when creating predicated insns
- +(define_attr "predicable" "no,yes" (const_string "no"))
- +
- +;; Type of memory operation
- +(define_attr "memaccess" "load,store,none" (const_string "none"))
- +
- +;; O2R hints
- +;; op2op1 - operand 2 is O2R if not in the same unit as operand 1
- +;; op1op0 - operand 1 is O2R if not in the same unit as operand 0
- +(define_attr "o2rhint" "op2op1,op1op0,none" (const_string "none"))
- +
- +;; Insn ccstate. Used to track interaction with the condition flags
- +
- +; xcc means that the condition codes are used by the insn in the process of
- +; outputting code
- +
- +; set means that the purpose of the insn is to set the condition codes.
- +
- +; ccx means that the condition codes are altered in an undefined manner, if
- +; they are altered at all
- +
- +; ncc means that the condition codes are neither altered nor affect the
- +; output of this insn
- +
- +(define_attr "ccstate" "xcc,set,fastset,fastfastset,ccx,ncc" (const_string "ncc"))
- +
- +;; Length (in # of insns).
- +(define_attr "length" ""
- + (cond [(eq_attr "type" "two,slowslow,read") (const_int 8)
- + (eq_attr "type" "three") (const_int 12)
- + (eq_attr "type" "four") (const_int 16)
- + (eq_attr "type" "five") (const_int 20)]
- + (const_int 4)))
- +
- +;; User supplied instructions
- +(define_asm_attributes
- + [(set_attr "type" "unknown")
- + (set_attr "ccstate" "ccx")
- + (set_attr "length" "4")
- + (set_attr "cond" "no")
- + (set_attr "predicable" "no")
- + (set_attr "memaccess" "none")
- + (set_attr "o2rhint" "none")
- + (set_attr "rename" "no")])
- +
- +
- +;; Metac core revision.
- +;; Used to select meta core revision specific insn scheduling.
- +;; this attribute must exactly match the processor_type enumeration in metag.h
- +
- +(define_attr "metacore" "metac_1_0,metac_1_1,metac_1_2,metac_0_1,metac_2_1"
- + (const (symbol_ref "metacore")))
- +
- +;; prologue/epilogue
- +(define_expand "prologue"
- + [(clobber (const_int 0))]
- + ""
- + {
- + metag_expand_prologue ();
- + DONE;
- + }
- +)
- +
- +(define_expand "epilogue"
- + [(return)]
- + ""
- + {
- + metag_expand_epilogue (false);
- + emit_jump_insn (gen_return_internal ());
- + DONE;
- + }
- +)
- +
- +(define_expand "sibcall_epilogue"
- + [(return)]
- + ""
- + {
- + metag_expand_epilogue (true);
- + DONE;
- + }
- +)
- +
- +(define_insn "prologue_use"
- + [(unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_PROLOGUE_USE)]
- + ""
- + "%@%@ %0 needed for prologue"
- +)
- +
- +;; Patterns for exception handling
- +
- +(define_expand "eh_return"
- + [(use (match_operand:SI 0 "register_operand" "r"))]
- + ""
- + {
- + emit_insn (gen_eh_return_internal (operands[0]));
- + DONE;
- + }
- +)
- +
- +(define_insn_and_split "eh_return_internal"
- + [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_EH_RETURN)]
- + ""
- + "#"
- + "reload_completed"
- + [(const_int 0)]
- + {
- + metag_expand_set_return_address (operands[0]);
- + DONE;
- + }
- +)
- +
- +
- +(define_insn "blockage"
- + [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
- + ""
- + ""
- + [(set_attr "length" "0")
- + (set_attr "type" "block")])
- +
- +
- +;; move instructions
- +
- +(define_insn "swapsi"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "+e,f,h,l")
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+t,u,y,z"))
- + (set (match_dup 1)
- + (match_dup 0))]
- + ""
- + "SWAP%?\\t%0, %1\\t%@ (*swap SI OK)"
- + [(set_attr "type" "swap")
- + (set_attr "predicable" "yes")
- + (set_attr "cond" "yes")])
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; movsi is made up of many parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "movsi"
- + [(set (match_operand:SI 0 "nonimmediate_operand" "")
- + (match_operand:SI 1 "general_operand" ""))]
- + ""
- + {
- +
- + /* The output template that was here has been moved in the
- + metag_emit_move_sequence function in metag.c */
- + metag_emit_move_sequence (operands, SImode);
- + }
- +)
- +
- +;; The problem:
- +;; GCC cannot differentiate a legitimate address from an illegitimate one when the only
- +;; factor affecting the split is the class that the register being loaded to or stored
- +;; from belongs to.
- +
- +;; This problem affects FX registers with SImode values in them. FX registers can only
- +;; be stored and loaded from register+6bit offset whereas all other registers can be
- +;; stored and loaded from register+12bit offset if the base register supports it.
- +
- +;; The solution:
- +;; Prevent reload from having a free-for-all on determining legitimate addresses. The
- +;; fallback case in mov_si therefore DOES NOT contain the FP register class in either
- +;; of the memory constraint alternatives. Reload will fix this by reloading any FX
- +;; register into another register as required.
- +
- +;; The caveat:
- +;; This solution prevents FX registers being reloaded directly to and from memory. To
- +;; solve this, the 6 and 12 bit load/store insns are above the fallback mov_si
- +;; pattern so as to allow FX registers to be reloaded to and from memory directly.
- +
- +;; WORK NEEDED: Prove this does actually allow FX registers holding SImode values to
- +;; be directly loaded and stored to base+6bit offset addresses.
- +
- +(define_insn "*sto_si_1_1_off12"
- + [(set (mem:SI (plus:SI (match_operand:SI 0 "metag_reg12bit_op" "da,Yr")
- + (match_operand:SI 1 "metag_offset12_si" "O4,Z4")))
- + (match_operand:SI 2 "metag_reg_nofloat_op" "da,da"))]
- + "TARGET_METAC_1_1"
- + "SETD\\t[%0+%1], %2"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_si_1_1_off6"
- + [(set (mem:SI (plus:SI (match_operand:SI 0 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 1 "metag_offset6_si" "O4")))
- + (match_operand:SI 2 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0+%1], %2\\t%@ (*sto SI off6 OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*lod_si_off12"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da,da")
- + (mem:SI (plus:SI (match_operand:SI 1 "metag_reg12bit_op" "da,Yr")
- + (match_operand:SI 2 "metag_offset12_si" "O4,Z4"))))]
- + ""
- + "GETD\\t%0, [%1+%2]"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_si_off"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr")
- + (mem:SI (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 2 "metag_offset6_si" "O4"))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1+%2]\\t%@ (*lod SI off6 OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +;; This instruction gets used by reload to generate reload instruction
- +;; which is why it needs to handle r -> mem and mem -> r alternatives.
- +;; Do not handle TXRPT as it cannot handle base + 12bit offsets loads/stores
- +;; Patterns below handle txrpt moving between R_REGS and Wx_REGS
- +
- +(define_insn "*mov_si"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,f,h,l,r,?*cx, r,!*m,*cx,!d")
- + (match_operand:SI 1 "metag_register_op" "e,f,h,l,r,?*cx,!*m, r,!d, *cx"))]
- + ""
- + {
- + switch (which_alternative)
- + {
- + case 0:
- + case 1:
- + case 2:
- + case 3:
- + case 4:
- + case 5:
- + case 8:
- + case 9:
- + if (METAG_FPC_REG_P (REGNO (operands[0]))
- + && METAG_FPC_REG_P (REGNO (operands[1])))
- + return "F\\tMOV%?\\t%0, %1";
- + else
- + return "MOV%?\\t%0, %1";
- + case 6:
- + if (METAG_FPC_REG_P (REGNO (operands[0])))
- + return "F\\tGETD\\t%0, %1";
- + else
- + return "GETD\\t%0, %1";
- + case 7:
- + if (METAG_FPC_REG_P (REGNO (operands[1])))
- + return "F\\tSETD\\t%0, %1";
- + else
- + return "SETD\\t%0, %1";
- + default:
- + gcc_unreachable ();
- + }
- + }
- + [(set_attr "type" "fast,fast,fast,fast,slow,fast,load,fast,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes,yes,yes,no,no,yes,yes")
- + (set_attr "memaccess" "none,none,none,none,none,none,load,store,none,none")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "ttmov_si"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (unspec_volatile:SI [(match_operand:SI 1 "metag_reg_nofloat_op" "da")] VUNSPEC_TTMOV))]
- + ""
- + "TTMOV%?\\t%0, %1 %@ H/W Tracing. Normal MOV but with value also sent to trace port"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")
- + (set_attr "rename" "no")])
- +
- +(define_insn "ttrec"
- + [(set (match_operand:DI 0 "metag_ttrec_op" "=Wx")
- + (unspec_volatile:DI [(match_operand:DI 1 "metag_reg_nofloat_op" "da")] VUNSPEC_TTREC))]
- + ""
- + "MOVL%?\\t%0, %1, %t1 %@ H/W Tracing. Functionally a NOP. Values sent to trace port"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*mov_si_rxrpt_r"
- + [(set (match_operand:SI 0 "metag_txrpt_op" "=Wx")
- + (match_operand:SI 1 "metag_register_op" "r"))]
- + ""
- + "MOV%?\\t%0, %1"
- + [(set_attr "type" "fast")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*mov_si_r_txrpt"
- + [(set (match_operand:SI 0 "metag_register_op" "=r")
- + (match_operand:SI 1 "metag_txrpt_op" "Wx"))]
- + ""
- + "MOV%?\\t%0, %1"
- + [(set_attr "type" "fast")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*mov_si_txrpt_ri"
- + [(set (match_operand:SI 0 "metag_txrpt_op" "=Wx,Wx,Wx")
- + (match_operand:SI 1 "metag_txrpt_src_op" "KIP,J, r"))]
- + ""
- + "@
- + MOV\\t%0, %1
- + MOVT\\t%0, %1
- + MOV%?\\t%0, %1"
- + [(set_attr "type" "fast,fast,fast")
- + (set_attr "cond" "no,no,yes")])
- +
- +;; movsi - all the immediate to register sets
- +(define_insn "*cond_<mode>_mov_si_zero"
- + [(cond_exec
- + (match_operator 1 "comparison_operator"
- + [(match_operand:CCALL 2 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (set (match_operand:SI 0 "metag_reg_nofloat_op" "=d,a")
- + (const_int 0)))]
- + "TARGET_COND_EXEC_OPTIMIZE"
- + "SUB%?\\t%0, %0, %0"
- + [(set_attr "type" "fast,slow")])
- +
- +(define_insn "*mov_si_zero"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=d,a")
- + (const_int 0))]
- + "TARGET_COND_EXEC_OPTIMIZE"
- + {
- + if (metag_cond_exec_p ())
- + return "SUB%?\\t%0, %0, %0";
- + else
- + return "MOV\\t%0, #0";
- + }
- + [(set_attr "type" "fast,slow")
- + (set_attr "cond" "yes")])
- +
- +(define_insn "*set_si_KIP"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:SI 1 "metag_KIP_operand" "KIP"))]
- + ""
- + "MOV\\t%0, %1\\t\\t%@ (*set si rKIP OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*set_si_J"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:SI 1 "metag_J_operand" "J"))]
- + ""
- + "MOVT\\t%0, %1\\t\\t%@ (*set si rJ OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*set_si_HI"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:SI 1 "metag_O0_operand" "O0"))]
- + ""
- + "MOVT\\t%0, #HI(%c1)\\t%@ (*set si rO0 OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*set_si_LO"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:SI 1 "metag_O3_operand" "O3"))]
- + ""
- + "MOVT\\t%0, #LO(%c1)\\t%@ (*set si rO3 OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*set_si"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da, da,da")
- + (match_operand:SI 1 "metag_bigint_op" "IPK,J, n"))]
- + ""
- + "#"
- + "reload_completed"
- + [(const_int 0)]
- + {
- + metag_split_movsi_immediate (operands);
- + DONE;
- + }
- + [(set_attr "type" "fast,fast,two")])
- +
- +;; movsi - symbol_ref to register sets
- +(define_insn "*set_si_symbol_got"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (mem:SI (plus:SI (match_operand:SI 1 "metag_pic_reg" "a")
- + (const (unspec [(match_operand:SI 2 "symbolic_operand" "")] UNSPEC_GOT)))))]
- + "METAG_FLAG_PIC&& operands[1] == pic_offset_table_rtx"
- + "GETD\\t%0, [%1+#(%c2@GOT)]\\t%@ (*set si r-picsym OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*add_si_HI_symbol_gotoff"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (high:SI (const (unspec [(match_operand:SI 2 "symbolic_operand" "")] UNSPEC_GOTOFF)))))]
- + "METAG_FLAG_PIC"
- + "ADDT\\t%0, %1, #HI(%c2@GOTOFF)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*mov_si_HI_symbol_gotoff"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (high:SI (const (unspec [(match_operand:SI 1 "symbolic_operand" "")] UNSPEC_GOTOFF))))]
- + "METAG_FLAG_PIC"
- + "MOVT\\t%0, #HI(%c1@GOTOFF)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*add_si_LO_symbol_gotoff"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (lo_sum:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (const (unspec [(match_operand:SI 2 "symbolic_operand" "")] UNSPEC_GOTOFF))))]
- + "METAG_FLAG_PIC"
- + "ADD\\t%0, %1, #LO(%c2@GOTOFF)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*set_si_symbol_gotoff"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=&da")
- + (plus:SI (match_operand:SI 1 "metag_pic_reg" "a")
- + (const (unspec [(match_operand:SI 2 "symbolic_operand" "")] UNSPEC_GOTOFF))))]
- + "METAG_FLAG_PIC&& operands[1] == pic_offset_table_rtx"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (match_dup 1))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (high:SI (const (unspec [(match_dup 2)] UNSPEC_GOTOFF)))))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (const (unspec [(match_dup 2)] UNSPEC_GOTOFF))))]
- + ""
- + [(set_attr "type" "three")])
- +
- +(define_insn_and_split "*set_si_symbol_gotoff_val"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=&da")
- + (const (unspec [(match_operand:SI 1 "symbolic_operand" "")] UNSPEC_GOTOFF)))]
- + "METAG_FLAG_PIC"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (high:SI (const (unspec [(match_dup 1)] UNSPEC_GOTOFF))))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (const (unspec [(match_dup 1)] UNSPEC_GOTOFF))))]
- + ""
- + [(set_attr "type" "two")])
- +
- +(define_insn "*add_si_HI_symbol_large"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (high:SI (match_operand 2 "metag_symlarge_op" ""))))]
- + "OG_ENABLED"
- + "ADDT\\t%0, %1, #HI(OG(%c2))"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*add_si_LO_symbol_large"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (lo_sum:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (match_operand 2 "metag_symlarge_op" "")))]
- + "OG_ENABLED"
- + "ADD\\t%0, %1, #LO(OG(%c2))"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*set_si_symbol_large"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=&l,!&da")
- + (match_operand:SI 1 "metag_symlarge_op" ""))]
- + "OG_ENABLED"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (match_dup 2))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (high:SI (match_dup 1))))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1)))]
- + {
- + operands[2] = gen_rtx_REG (SImode, A1GbP_REG);
- + }
- + [(set_attr "type" "three")])
- +
- +(define_insn "*set_si_HI_symbol_global"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (high:SI (match_operand:SI 1 "metag_symglobal_op" "")))]
- + "!METAG_FLAG_PIC"
- + "MOVT\\t%0,#HI(%c1)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*add_si_LO_symbol_global"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (lo_sum:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (match_operand:SI 2 "metag_symglobal_op" "" )))]
- + "!METAG_FLAG_PIC"
- + "ADD\\t%0, %1, #LO(%c2)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*set_si_symbol_global"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:SI 1 "metag_symglobal_op" ""))]
- + "!METAG_FLAG_PIC"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (high:SI (match_dup 1)))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1)))]
- + ""
- + [(set_attr "type" "two")])
- +
- +(define_insn "*set_si_symbol_small"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:SI 1 "metag_symsmall_op" ""))]
- + "OG_ENABLED"
- + "GETD\\t%0, [A1GbP+#OGA(%c1)]\\t%@ (*set si r-ssym OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*set_si_symbol_off_small"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (const:SI (plus:SI (match_operand:SI 1 "metag_symsmall_op" "")
- + (match_operand:SI 2 "const_int_operand" ""))))]
- + "OG_ENABLED"
- + "GETD\\t%0, [A1GbP+#OGA(%c1+%c2)]\\t%@ (*set si r-ssym OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*add_si_HI_symbol_off_pic"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (high:SI (const
- + (plus:SI (unspec [(match_operand:SI 2 "symbolic_operand" "")] UNSPEC_GOTOFF)
- + (match_operand:SI 3 "const_int_operand" ""))))))]
- + "METAG_FLAG_PIC"
- + "ADDT\\t%0, %1, #HI(%c2@GOTOFF+%c3)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*mov_si_HI_symbol_off_pic"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (high:SI (const
- + (plus:SI (unspec [(match_operand:SI 1 "symbolic_operand" "")] UNSPEC_GOTOFF)
- + (match_operand:SI 2 "const_int_operand" "")))))]
- + "METAG_FLAG_PIC"
- + "MOVT\\t%0, #HI(%c1@GOTOFF+%c2)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*add_si_LO_symbol_off_pic"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (lo_sum:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (const
- + (plus:SI (unspec [(match_operand:SI 2 "symbolic_operand" "")] UNSPEC_GOTOFF)
- + (match_operand:SI 3 "const_int_operand" "")))))]
- + "METAG_FLAG_PIC"
- + "ADD\\t%0, %1, #LO(%c2@GOTOFF+%c3)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*set_si_symbol_off_pic"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=&da")
- + (plus:SI (match_operand:SI 1 "metag_pic_reg" "a")
- + (const
- + (plus:SI (unspec [(match_operand:SI 2 "symbolic_operand" "")] UNSPEC_GOTOFF)
- + (match_operand:SI 3 "const_int_operand" "")))))]
- + "METAG_FLAG_PIC&& operands[1] == pic_offset_table_rtx"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (match_dup 1))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (high:SI (const
- + (plus:SI (unspec [(match_dup 2)] UNSPEC_GOTOFF)
- + (match_dup 3))))))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (const
- + (plus:SI (unspec [(match_dup 2)] UNSPEC_GOTOFF)
- + (match_dup 3)))))]
- + ""
- + [(set_attr "type" "three")])
- +
- +(define_insn_and_split "*set_si_symbol_off_pic_val"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=&da")
- + (const
- + (plus:SI (unspec [(match_operand:SI 1 "symbolic_operand" "")] UNSPEC_GOTOFF)
- + (match_operand:SI 2 "const_int_operand" ""))))]
- + "METAG_FLAG_PIC"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (high:SI (const
- + (plus:SI (unspec [(match_dup 1)] UNSPEC_GOTOFF)
- + (match_dup 2)))))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (const
- + (plus:SI (unspec [(match_dup 1)] UNSPEC_GOTOFF)
- + (match_dup 2)))))]
- + ""
- + [(set_attr "type" "two")])
- +
- +(define_insn "*add_si_HI_symbol_off_large"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (high:SI (const:SI (plus:SI (match_operand:SI 2 "metag_symlarge_op" "")
- + (match_operand:SI 3 "const_int_operand" ""))))))]
- + "OG_ENABLED"
- + "ADDT\\t%0, %1, #HI(OG(%c2+%c3))"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*add_si_LO_symbol_off_large"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (lo_sum:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (const:SI (plus:SI (match_operand:SI 2 "metag_symlarge_op" "")
- + (match_operand:SI 3 "const_int_operand" "")))))]
- + "OG_ENABLED"
- + "ADD\\t%0, %1, #LO(OG(%c2+%c3))"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*set_si_symbol_off_large"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=l,!da")
- + (const:SI (plus:SI (match_operand:SI 1 "metag_symlarge_op" "")
- + (match_operand:SI 2 "const_int_operand" ""))))]
- + "OG_ENABLED"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (match_dup 3))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (high:SI (match_dup 4))))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 4)))]
- + {
- + operands[3] = gen_rtx_REG (SImode, A1GbP_REG);
- + operands[4] = gen_rtx_CONST (SImode,
- + gen_rtx_PLUS (SImode,
- + operands[1],
- + operands[2]));
- + }
- + [(set_attr "type" "three,four")])
- +
- +(define_insn "*set_si_HI_symbol_off_global"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (high:SI (const:SI (plus:SI (match_operand:SI 1 "metag_symglobal_op" "")
- + (match_operand:SI 2 "const_int_operand" "")))))]
- + "!METAG_FLAG_PIC"
- + "MOVT\\t%0,#HI(%c1+%c2)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*add_si_LO_symbol_off_global"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (lo_sum:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (const:SI (plus:SI (match_operand:SI 2 "metag_symglobal_op" "" )
- + (match_operand:SI 3 "const_int_operand" "" )))))]
- + "!METAG_FLAG_PIC"
- + "ADD\\t%0, %1, #LO(%c2+%c3)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*set_si_symbol_off_global"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (const:SI (plus:SI (match_operand:SI 1 "metag_symglobal_op" "")
- + (match_operand:SI 2 "const_int_operand" ""))))]
- + "!METAG_FLAG_PIC"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (high:SI (match_dup 3)))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 3)))]
- + {
- + operands[3] = gen_rtx_CONST (SImode,
- + gen_rtx_PLUS (SImode,
- + operands[1],
- + operands[2]));
- + }
- + [(set_attr "type" "two")])
- +
- +;; movsi - code address to register sets
- +(define_insn "*set_si_HI_label"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (high:SI (match_operand:SI 1 "code_address" "")))]
- + "!METAG_FLAG_PIC"
- + "MOVT\\t%0,#HI(%c1)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*add_si_LO_label"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (lo_sum:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (match_operand:SI 2 "code_address" "" )))]
- + "!METAG_FLAG_PIC"
- + "ADD\\t%0, %1, #LO(%c2)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*set_si_label"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:SI 1 "code_address" ""))]
- + "!METAG_FLAG_PIC"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (high:SI (match_dup 1)))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1)))]
- + ""
- + [(set_attr "type" "two")])
- +
- +(define_insn "*set_si_HI_label_off"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (high:SI (const:SI (plus:SI (match_operand:SI 1 "code_address" "")
- + (match_operand:SI 2 "const_int_operand" "")))))]
- + "!METAG_FLAG_PIC"
- + "MOVT\\t%0,#HI(%c1+%c2)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*add_si_LO_label_off"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (lo_sum:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (const:SI (plus:SI (match_operand:SI 2 "code_address" "" )
- + (match_operand:SI 3 "const_int_operand" "" )))))]
- + "!METAG_FLAG_PIC"
- + "ADD\\t%0, %1, #LO(%c2+%c3)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*set_si_label_off"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (const:SI (plus:SI (match_operand:SI 1 "code_address" "")
- + (match_operand:SI 2 "const_int_operand" ""))))]
- + "!METAG_FLAG_PIC"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (high:SI (match_dup 3)))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 3)))]
- + {
- + operands[3] = gen_rtx_CONST (SImode,
- + gen_rtx_PLUS (SImode,
- + operands[1],
- + operands[2]));
- + }
- + [(set_attr "type" "two")])
- +
- +(define_insn "*add_si_HI_label_pic"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (high:SI (const (unspec [(label_ref:SI (match_operand 2 "" ""))] UNSPEC_GOTOFF)))))]
- + "METAG_FLAG_PIC"
- + "ADDT\\t%0, %0, #HI(%c2@GOTOFF)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*mov_si_HI_label_pic"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (high:SI (const (unspec [(label_ref:SI (match_operand 1 "" ""))] UNSPEC_GOTOFF))))]
- + "METAG_FLAG_PIC"
- + "MOVT\\t%0, #HI(%c1@GOTOFF)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*add_si_LO_label_pic"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (lo_sum:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (const (unspec [(label_ref:SI (match_operand 2 "" ""))] UNSPEC_GOTOFF))))]
- + "METAG_FLAG_PIC"
- + "ADD\\t%0, %0, #LO(%c2@GOTOFF)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*set_si_label_pic"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=&da")
- + (plus:SI (match_operand:SI 1 "metag_pic_reg" "a")
- + (const (unspec [(label_ref:SI (match_operand 2 "" ""))] UNSPEC_GOTOFF))))]
- + "METAG_FLAG_PIC&& operands[1] == pic_offset_table_rtx"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (match_dup 1))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (high:SI (const (unspec [(label_ref:SI (match_dup 2))] UNSPEC_GOTOFF)))))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (const (unspec [(label_ref:SI (match_dup 2))] UNSPEC_GOTOFF))))]
- + ""
- + [(set_attr "type" "three")])
- +
- +(define_insn_and_split "*set_si_label_pic_val"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=&da")
- + (const (unspec [(label_ref:SI (match_operand 1 "" ""))] UNSPEC_GOTOFF)))]
- + "METAG_FLAG_PIC"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (high:SI (const (unspec [(label_ref:SI (match_dup 1))] UNSPEC_GOTOFF))))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (const (unspec [(label_ref:SI (match_dup 1))] UNSPEC_GOTOFF))))]
- + ""
- + [(set_attr "type" "two")])
- +
- +(define_insn "*add_si_HI_label_off_pic"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (high:SI (const
- + (plus:SI (unspec [(label_ref:SI (match_operand 2 "" ""))] UNSPEC_GOTOFF)
- + (match_operand:SI 3 "const_int_operand" ""))))))]
- + "METAG_FLAG_PIC"
- + "ADDT\\t%0, %1, #HI(%c2@GOTOFF+%c3)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*mov_si_HI_label_off_pic"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (high:SI (const
- + (plus:SI (unspec [(label_ref:SI (match_operand 1 "" ""))] UNSPEC_GOTOFF)
- + (match_operand:SI 2 "const_int_operand" "")))))]
- + "METAG_FLAG_PIC"
- + "MOVT\\t%0, #HI(%c1@GOTOFF+%c2)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*add_si_LO_label_off_pic"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (lo_sum:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (const
- + (plus:SI (unspec [(label_ref:SI (match_operand 2 "" ""))] UNSPEC_GOTOFF)
- + (match_operand:SI 3 "const_int_operand" "")))))]
- + "METAG_FLAG_PIC"
- + "ADD\\t%0, %0, #LO(%c2@GOTOFF+%c3)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*set_si_label_off_pic"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=&da")
- + (plus:SI (match_operand:SI 1 "metag_pic_reg" "a")
- + (const
- + (plus:SI (unspec [(label_ref:SI (match_operand 2 "" ""))] UNSPEC_GOTOFF)
- + (match_operand:SI 3 "const_int_operand" "")))))]
- + "METAG_FLAG_PIC"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (match_dup 1))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (high:SI (const
- + (plus:SI (unspec [(label_ref:SI (match_dup 2))] UNSPEC_GOTOFF)
- + (match_dup 3))))))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (const
- + (plus:SI (unspec [(label_ref:SI (match_dup 2))] UNSPEC_GOTOFF)
- + (match_dup 3)))))]
- + ""
- + [(set_attr "type" "three")])
- +
- +(define_insn_and_split "*set_si_label_off_pic_val"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=&da")
- + (const
- + (plus:SI (unspec [(label_ref:SI (match_operand 1 "" ""))] UNSPEC_GOTOFF)
- + (match_operand:SI 2 "const_int_operand" ""))))]
- + "METAG_FLAG_PIC"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (high:SI (const
- + (plus:SI (unspec [(label_ref:SI (match_dup 1))] UNSPEC_GOTOFF)
- + (match_dup 2)))))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (const
- + (plus:SI (unspec [(label_ref:SI (match_dup 1))] UNSPEC_GOTOFF)
- + (match_dup 2)))))]
- + ""
- + [(set_attr "type" "two")])
- +
- +;; -----------------------------------------------------------------------------
- +;; | Matching SI store post/pre_inc/dec/modify and emitting ASM |
- +;; | ** These rules MUST come before the put_si_1_1 rule ** |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*sto_si_post_inc"
- + [(set (mem:SI (post_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:SI 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0++], %1\\t%@ (*store SI post_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_si_post_dec"
- + [(set (mem:SI (post_dec:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:SI 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0--], %1\\t%@ (*store SI post_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_si_pre_inc"
- + [(set (mem:SI (pre_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:SI 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[++%0], %1\\t%@ (*store SI pre_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_si_pre_dec"
- + [(set (mem:SI (pre_dec:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:SI 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[--%0], %1\\t%@ (*store SI pre_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_si_post_modify_disp"
- + [(set (mem:SI (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_si" "O4,O4,O4,O4"))))
- + (match_operand:SI 2 "metag_register_op" "t, u, y, z"))]
- + "!TARGET_METAC_1_1"
- + "SETD\\t[%0+%1++], %2\\t%@ (*store SI post_modify_disp OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_si_post_modify_disp_1_1"
- + [(set (mem:SI (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_si" "O4"))))
- + (match_operand:SI 2 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0+%1++], %2\\t%@ (*store SI post_modify_disp OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_si_post_modify_reg"
- + [(set (mem:SI (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e, f, h, l"))))
- + (match_operand:SI 2 "metag_register_op" "ct,cu,cy,cz"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0+%1++], %2\\t%@ (*store SI post_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_si_pre_modify_disp"
- + [(set (mem:SI (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_si" "O4,O4,O4,O4"))))
- + (match_operand:SI 2 "metag_reg_nofloat_op" "t, u, y, z"))]
- + "!TARGET_METAC_1_1"
- + "SETD\\t[%0++%1], %2\\t%@ (*store SI pre_modify_disp OK)"
- + [(set_attr "type" "fast,fast,fast,fast")])
- +
- +(define_insn "*sto_si_pre_modify_disp_1_1"
- + [(set (mem:SI (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_si" "O4"))))
- + (match_operand:SI 2 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0++%1], %2\\t%@ (*store SI pre_modify_disp OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_si_pre_modify_reg_1_1"
- + [(set (mem:SI (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e, f, h, l"))))
- + (match_operand:SI 2 "metag_register_op" "ct,cu,cy,cz"))]
- + ""
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0++%1], %2\\t%@ (*store SI pre_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Non-side effecting base+offset store SI and catchall store SI cases |
- +;; -----------------------------------------------------------------------------
- +
- +;; movsi - base+index register to memory (stors's)
- +(define_insn "*sto_si_mar"
- + [(set (mem:SI (plus:SI (match_operand:SI 0 "metag_regnofrm_op" "%e, f, h, l")
- + (match_operand:SI 1 "metag_regnofrm_op" " e, f, h, l")))
- + (match_operand:SI 2 "metag_register_op" "ct,cu,cy,cz"))]
- + ""
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0+%1], %2\\t%@ (*sto si mar OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")
- + (set_attr "length" "4,4,4,4")])
- +
- +;; movsi - register to memory (stores) some are fast, rest match spillsi below
- +(define_insn "*sto_si_reg_indirect"
- + [(set (mem:SI (match_operand:SI 0 "metag_reg_nofloat_op" "e,f,h,l,!*da"))
- + (match_operand:SI 1 "metag_register_op" "t,u,y,z, *da"))]
- + "TARGET_COND_EXEC_OPTIMIZE && !TARGET_METAC_1_1"
- + "@
- + SETD%?\\t[%0], %1\\t%@ (*sto si [e]t OK)
- + SETD%?\\t[%0], %1\\t%@ (*sto si [f]u OK)
- + SETD%?\\t[%0], %1\\t%@ (*sto si [h]y OK)
- + SETD%?\\t[%0], %1\\t%@ (*sto si [l]z OK)
- + #"
- + [(set_attr "type" "fast,fast,fast,fast,invalid")
- + (set_attr "cond" "yes,yes,yes,yes,no")])
- +
- +(define_insn "*sto_si"
- + [(set (match_operand:SI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl,!*m")
- + (match_operand:SI 1 "metag_register_op" "r, t, u, y, z, !*da"))]
- + "!TARGET_METAC_1_1 && !reload_completed"
- + "@
- + SETD\\t%0, %1\\t%@ (*sto si [r]r OK)
- + SETD\\t%0, %1\\t%@ (*sto si [e]t OK)
- + SETD\\t%0, %1\\t%@ (*sto si [f]u OK)
- + SETD\\t%0, %1\\t%@ (*sto si [h]y OK)
- + SETD\\t%0, %1\\t%@ (*sto si [l]z OK)
- + SETD\\t%0, %1\\t%@ (*sto si [m]r OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,invalid")])
- +
- +(define_insn "*sto_si_postreload"
- + [(set (match_operand:SI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl")
- + (match_operand:SI 1 "metag_register_op" "r, t, u, y, z"))]
- + "!TARGET_METAC_1_1 && reload_completed"
- + "@
- + SETD\\t%0, %1\\t%@ (*sto si [r]r OK)
- + SETD\\t%0, %1\\t%@ (*sto si [e]r OK)
- + SETD\\t%0, %1\\t%@ (*sto si [f]r OK)
- + SETD\\t%0, %1\\t%@ (*sto si [h]r OK)
- + SETD\\t%0, %1\\t%@ (*sto si [l]r OK)"
- + [(set_attr "type" "fast")])
- +
- +;; movsi - all the register to register|memory moves
- +(define_insn "*sto_si_reg_indirect_1_1"
- + [(set (mem:SI (match_operand:SI 0 "metag_reg_nofloat_op" "da"))
- + (match_operand:SI 1 "metag_register_op" "cr"))]
- + "TARGET_COND_EXEC_OPTIMIZE && TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD%?\\t[%0], %1\\t%@ (*sto si [r]r OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*sto_si_1_1"
- + [(set (match_operand:SI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl,!*m")
- + (match_operand:SI 1 "metag_reg_nofloat_op" "r, t, u, y, z, !*da"))]
- + "TARGET_METAC_1_1 && !reload_completed"
- + "@
- + SETD\\t%0, %1\\t%@ (*sto si [r]r OK)
- + SETD\\t%0, %1\\t%@ (*sto si [e]t OK)
- + SETD\\t%0, %1\\t%@ (*sto si [f]u OK)
- + SETD\\t%0, %1\\t%@ (*sto si [h]y OK)
- + SETD\\t%0, %1\\t%@ (*sto si [l]z OK)
- + SETD\\t%0, %1\\t%@ (*sto si [m]r OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,invalid")])
- +
- +(define_insn "*sto_si_1_1_postreload"
- + [(set (match_operand:SI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl")
- + (match_operand:SI 1 "metag_reg_nofloat_op" "r, t, u, y, z"))]
- + "TARGET_METAC_1_1 && reload_completed"
- + "@
- + SETD\\t%0, %1\\t%@ (*sto si [r]r OK)
- + SETD\\t%0, %1\\t%@ (*sto si [e]t OK)
- + SETD\\t%0, %1\\t%@ (*sto si [f]u OK)
- + SETD\\t%0, %1\\t%@ (*sto si [h]y OK)
- + SETD\\t%0, %1\\t%@ (*sto si [l]z OK)"
- + [(set_attr "type" "fast")])
- +
- +;; spillsi - register to memory (stores) from source/dest in same bank
- +(define_split
- + [(set (match_operand:SI 0 "memory_operand" "")
- + (match_operand:SI 1 "metag_register_op" ""))]
- + "!TARGET_METAC_1_1
- + && reload_completed
- + && metag_slow_store (operands[0], operands[1])"
- + [(set (match_dup 2)
- + (match_dup 1))
- + (set (match_dup 0)
- + (match_dup 2))]
- + {
- + operands[2] = metag_gen_safe_temp (SImode, operands[1]);
- + }
- +)
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Matching SI load post/pre_inc/dec/modify and emitting ASM |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lod_si_post_inc"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr")
- + (mem:SI (post_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1++]\\t%@ (*load SI post_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_si_post_dec"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr")
- + (mem:SI (post_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1--]\\t%@ (*load SI post_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_si_pre_inc"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr")
- + (mem:SI (pre_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [++%1]\\t%@ (*load SI pre_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_si_pre_dec"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr")
- + (mem:SI (pre_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [--%1]\\t%@ (*load SI pre_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_si_post_modify_disp"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr")
- + (mem:SI (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_si" "O4")))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1+%2++]\\t%@ (*load SI post_modify_disp OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_si_post_modify_reg"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr,cr,cr,cr")
- + (mem:SI (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l")))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1+%2++]\\t%@ (*load SI post_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_si_pre_modify_disp"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr")
- + (mem:SI (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_si" "O4")))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1++%2]\\t%@ (*load SI pre_modify_disp OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_si_pre_modify_reg"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr,cr,cr,cr")
- + (mem:SI (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l")))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1++%2]\\t%@ (*load SI pre_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Non-side effecting base+offset load SI and catchall load SI |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lod_si"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr")
- + (mem:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1]";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +;; movsi - base+index memory to register (loads)
- +(define_insn "*lod_si_rma"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr,cr,cr,cr")
- + (mem:SI (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "e, f, h, l")
- + (match_operand:SI 2 "metag_regnofrm_op" "e, f, h, l"))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1+%2]\\t%@ (*lod si rma OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +;; Removed FPC alternative owing to lack of 12bit offset support
- +;; base+12bit load to FX occurs during conversion of virtual_stack_args
- +(define_insn "*lod_si_mem"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:SI 1 "memory_operand" "m"))]
- + ""
- + "GETD\\t%0, %1\\t%@ (*lod si rm OK)"
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; movhi is made up of many parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "movhi"
- + [(set (match_operand:HI 0 "nonimmediate_operand" "")
- + (match_operand:HI 1 "general_operand" ""))]
- + ""
- + {
- + if (MEM_P (operands[0]))
- + {
- + /* All except mem = const or mem = mem can be done quickly */
- + operands[1] = force_reg (HImode, operands[1]);
- + }
- + }
- +)
- +
- +;; movhi - all the register to register moves
- +(define_insn "*mov_hi"
- + [(set (match_operand:HI 0 "metag_register_op" "=e,f,h,l,cx,d, cx,da")
- + (match_operand:HI 1 "metag_register_op" "e,f,h,l,cx,cx,d, da"))]
- + ""
- + "MOV%?\\t%0, %1\\t\\t%@ (*mov hi rr OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,slow,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes,yes,yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; movhi - all the immediate to register sets
- +(define_insn "*set_hi"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:HI 1 "metag_int_operand" "KIP"))]
- + ""
- + "MOV\\t%0, %1\\t\\t%@ (*set hi rI OK)"
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Matching HI store post/pre_inc/dec/modify and emitting ASM |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*sto_hi_post_inc"
- + [(set (mem:HI (post_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:HI 1 "metag_reg_nofloat_op" "da"))]
- + "TARGET_METAC_1_1"
- + "SETW\\t[%0++], %1\\t%@ (*store HI post_inc OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_hi_post_dec"
- + [(set (mem:HI (post_dec:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:HI 1 "metag_reg_nofloat_op" "da"))]
- + "TARGET_METAC_1_1"
- + "SETW\\t[%0--], %1\\t%@ (*store HI post_dec OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_hi_pre_inc"
- + [(set (mem:HI (pre_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:HI 1 "metag_reg_nofloat_op" "da"))]
- + "TARGET_METAC_1_1"
- + "SETW\\t[++%0], %1\\t%@ (*store HI pre_inc OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_hi_pre_dec"
- + [(set (mem:HI (pre_dec:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:HI 1 "metag_reg_nofloat_op" "da"))]
- + "TARGET_METAC_1_1"
- + "SETW\\t[--%0], %1\\t%@ (*store HI pre_dec OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_hi_post_modify_disp"
- + [(set (mem:HI (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_hi" "O2,O2,O2,O2"))))
- + (match_operand:HI 2 "metag_reg_nofloat_op" "t, u, y, z"))]
- + "!TARGET_METAC_1_1"
- + "SETW\\t[%0+%1++], %2\\t%@ (*store HI post_modify_disp OK)"
- + [(set_attr "type" "fast,fast,fast,fast")])
- +
- +(define_insn "*sto_hi_post_modify_disp_1_1"
- + [(set (mem:HI (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_hi" "O2"))))
- + (match_operand:HI 2 "metag_reg_nofloat_op" "da"))]
- + "TARGET_METAC_1_1"
- + "SETW\\t[%0+%1++], %2\\t%@ (*store HI post_modify_disp OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_hi_post_modify_reg"
- + [(set (mem:HI (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e,f,h,l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e,f,h,l"))))
- + (match_operand:HI 2 "metag_reg_nofloat_op" "t,u,y,z"))]
- + ""
- + "SETW\\t[%0+%1++], %2\\t%@ (*store HI post_modify_reg OK)"
- + [(set_attr "type" "fast,fast,fast,fast")])
- +
- +(define_insn "*sto_hi_pre_modify_disp"
- + [(set (mem:HI (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_hi" "O2,O2,O2,O2"))))
- + (match_operand:HI 2 "metag_reg_nofloat_op" "t, u, y, z"))]
- + "!TARGET_METAC_1_1"
- + "SETW\\t[%0++%1], %2\\t%@ (*store HI pre_modify_disp OK)"
- + [(set_attr "type" "fast,fast,fast,fast")])
- +
- +(define_insn "*sto_hi_pre_modify_disp_1_1"
- + [(set (mem:HI (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_hi" "O2"))))
- + (match_operand:HI 2 "metag_reg_nofloat_op" "da"))]
- + "TARGET_METAC_1_1"
- + "SETW\\t[%0++%1], %2\\t%@ (*store HI pre_modify_disp OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_hi_pre_modify_reg"
- + [(set (mem:HI (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e,f,h,l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e,f,h,l"))))
- + (match_operand:HI 2 "metag_reg_nofloat_op" "t,u,y,z"))]
- + ""
- + "SETW\\t[%0++%1], %2\\t%@ (*store HI pre_modify_reg OK)"
- + [(set_attr "type" "fast,fast,fast,fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Non-side effecting base+offset store HI and catchall store HI cases |
- +;; -----------------------------------------------------------------------------
- +
- +;; movhi - base+index register to memory (stors's)
- +(define_insn "*sto_hi_mar"
- + [(set (mem:HI (plus:SI (match_operand:SI 0 "metag_regnofrm_op" "%e,f,h,l")
- + (match_operand:SI 1 "metag_regnofrm_op" " e,f,h,l")))
- + (match_operand:HI 2 "metag_reg_nofloat_op" " t,u,y,z"))]
- + ""
- + "SETW\\t[%0+%1], %2\\t%@ (*sto hi mar OK)"
- + [(set_attr "type" "fast")
- + (set_attr "length" "4,4,4,4")])
- +
- +;; movhi - register to memory (stores) some are fast, rest match spillhi below
- +(define_insn "*sto_hi_reg_indirect"
- + [(set (mem:HI (match_operand:SI 0 "metag_reg_nofloat_op" "e,f,h,l,!*da"))
- + (match_operand:HI 1 "metag_reg_nofloat_op" "t,u,y,z, *da"))]
- + "TARGET_COND_EXEC_OPTIMIZE && !TARGET_METAC_1_1"
- + "@
- + SETW%?\\t[%0], %1\\t%@ (*sto hi [e]t OK)
- + SETW%?\\t[%0], %1\\t%@ (*sto hi [f]u OK)
- + SETW%?\\t[%0], %1\\t%@ (*sto hi [h]y OK)
- + SETW%?\\t[%0], %1\\t%@ (*sto hi [l]z OK)
- + #"
- + [(set_attr "type" "fast,fast,fast,fast,invalid")
- + (set_attr "cond" "yes,yes,yes,yes,no")])
- +
- +(define_insn "*sto_hi"
- + [(set (match_operand:HI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl,!*m")
- + (match_operand:HI 1 "metag_reg_nofloat_op" "r, t, u, y, z, !*da"))]
- + "!TARGET_METAC_1_1 && !reload_completed"
- + "@
- + SETW\\t%0, %1\\t%@ (*sto hi [r]r OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [e]t OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [f]u OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [h]y OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [l]z OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [m]r OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,invalid")])
- +
- +(define_insn "*sto_hi_postreload"
- + [(set (match_operand:HI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl")
- + (match_operand:HI 1 "metag_reg_nofloat_op" "r, t, u, y, z"))]
- + "!TARGET_METAC_1_1 && reload_completed"
- + "@
- + SETW\\t%0, %1\\t%@ (*sto hi [r]r OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [e]t OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [f]u OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [h]y OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [l]z OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_hi_reg_indirect_1_1"
- + [(set (mem:HI (match_operand:SI 0 "metag_reg_nofloat_op" "da"))
- + (match_operand:HI 1 "metag_reg_nofloat_op" "da"))]
- + "TARGET_COND_EXEC_OPTIMIZE && TARGET_METAC_1_1"
- + "SETW%?\\t[%0], %1\\t%@ (*sto hi [r]r OK)"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*sto_hi_1_1_off12"
- + [(set (mem:HI (plus:SI (match_operand:SI 0 "metag_reg12bit_op" "da,Yr")
- + (match_operand:SI 1 "metag_offset12_hi" "O2,Z2")))
- + (match_operand:HI 2 "metag_reg_nofloat_op" "da,da"))]
- + "TARGET_METAC_1_1"
- + "SETW\\t[%0+%1], %2"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_hi_1_1_off6"
- + [(set (mem:HI (plus:SI (match_operand:SI 0 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 1 "metag_offset6_hi" "O2")))
- + (match_operand:HI 2 "metag_reg_nofloat_op" "da"))]
- + "TARGET_METAC_1_1"
- + "SETW\\t[%0+%1], %2"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_hi_1_1"
- + [(set (match_operand:HI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl,!*m")
- + (match_operand:HI 1 "metag_reg_nofloat_op" "r, t, u, y, z, !*da"))]
- + "TARGET_METAC_1_1 && !reload_completed"
- + "@
- + SETW\\t%0, %1\\t%@ (*sto hi [r]r OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [e]r OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [f]r OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [h]r OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [l]r OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [m]r OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,invalid")])
- +
- +(define_insn "*sto_hi_1_1_postreload"
- + [(set (match_operand:HI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl")
- + (match_operand:HI 1 "metag_reg_nofloat_op" "r, t, u, y, z"))]
- + "TARGET_METAC_1_1 && reload_completed"
- + "@
- + SETW\\t%0, %1\\t%@ (*sto hi [r]r OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [e]r OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [f]r OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [h]r OK)
- + SETW\\t%0, %1\\t%@ (*sto hi [l]r OK)"
- + [(set_attr "type" "fast")])
- +
- +;; spillhi - register to memory (stores) from source/dest in same bank
- +(define_split
- + [(set (match_operand:HI 0 "memory_operand" "")
- + (match_operand:HI 1 "metag_register_op" ""))]
- + "!TARGET_METAC_1_1
- + && reload_completed
- + && metag_slow_store (operands[0], operands[1])"
- + [(set (match_dup 2)
- + (match_dup 1))
- + (set (match_dup 0)
- + (match_dup 2))]
- + {
- + operands[2] = metag_gen_safe_temp (HImode, operands[1]);
- + }
- +)
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Matching HI load post/pre_inc/dec/modify and emitting ASM |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lod_hi_post_inc"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da")
- + (mem:HI (post_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + "GETW\\t%0, [%1++]\\t%@ (*load HI post_inc OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_hi_post_dec"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da")
- + (mem:HI (post_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + "GETW\\t%0, [%1--]\\t%@ (*load HI post_dec OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_hi_pre_inc"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da")
- + (mem:HI (pre_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + "GETW\\t%0, [++%1]\\t%@ (*load HI pre_inc OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_hi_pre_dec"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da")
- + (mem:HI (pre_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + "GETW\\t%0, [--%1]\\t%@ (*load HI pre_dec OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_hi_post_modify_disp"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da")
- + (mem:HI (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_hi" "O2")))))]
- + ""
- + "GETW\\t%0, [%1+%2++]\\t%@ (*load HI post_modify_disp OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_hi_post_modify_reg"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da,da,da,da")
- + (mem:HI (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l")))))]
- + ""
- + "GETW\\t%0, [%1+%2++]\\t%@ (*load HI post_modify_reg OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_hi_pre_modify_disp"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da")
- + (mem:HI (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_hi" "O2")))))]
- + ""
- + "GETW\\t%0, [%1++%2]\\t%@ (*load HI pre_modify_disp OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_hi_pre_modify_reg"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da,da,da,da")
- + (mem:HI (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e,f,h,l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e,f,h,l")))))]
- + ""
- + "GETW\\t%0, [%1++%2]\\t%@ (*load HI pre_modify_reg OK)"
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Non-side effecting base+offset load HI and catchall load HI |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lod_hi"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da")
- + (mem:HI (match_operand:SI 1 "metag_reg_nofloat_op" "da")))]
- + ""
- + "GETW\\t%0, [%1]\\t%@ (*lod hi rma OK)"
- + [(set_attr "type" "load")])
- +
- +;; movhi - base+index memory to register (loads)
- +(define_insn "*lod_hi_rma"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da,da,da,da")
- + (mem:HI (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "%e, f, h, l ")
- + (match_operand:SI 2 "metag_regnofrm_op" "e, f, h, l "))))]
- + ""
- + "GETW\\t%0, [%1+%2]\\t%@ (*lod hi rma OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_hi_off12"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da,da")
- + (mem:HI (plus:SI (match_operand:SI 1 "metag_reg12bit_op" "da,Yr")
- + (match_operand:SI 2 "metag_offset12_hi" "O2,Z2"))))]
- + ""
- + "GETW\\t%0, [%1+%2]"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_hi_off"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da")
- + (mem:HI (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 2 "metag_offset6_hi" "O2"))))]
- + ""
- + "GETW\\t%0, [%1+%2]"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_hi_mem"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:HI 1 "memory_operand" "m"))]
- + ""
- + "GETW\\t%0, %1\\t%@ (*lod hi rm OK)"
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; movqi is made up of many parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "movqi"
- + [(set (match_operand:QI 0 "nonimmediate_operand" "")
- + (match_operand:QI 1 "general_operand" ""))]
- + ""
- + {
- + if (MEM_P (operands[0]))
- + {
- + /* All except mem = const or mem = mem can be done quickly */
- + operands[1] = force_reg (QImode, operands[1]);
- + }
- + }
- +)
- +
- +;; movqi - all the register to register moves
- +(define_insn "*mov_qi"
- + [(set (match_operand:QI 0 "metag_register_op" "=e,f,h,l,cx,cd,?da")
- + (match_operand:QI 1 "metag_register_op" "e,f,h,l,cx,cd,?da"))]
- + ""
- + "MOV%?\\t%0, %1\\t\\t%@ (*mov qi rr OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes,yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; movqi - all the immediate to register sets
- +(define_insn "*set_qi"
- + [(set (match_operand:QI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:QI 1 "metag_int_operand" "KP"))]
- + ""
- + "MOV\\t%0, %1\\t\\t%@ (*set qi rI OK)"
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +;; | Matching QI store post/pre_inc/dec/modify and emitting ASM |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*sto_qi_post_inc"
- + [(set (mem:QI (post_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:QI 1 "metag_reg_nofloat_op" "da"))]
- + "TARGET_METAC_1_1"
- + "SETB\\t[%0++], %1\\t%@ (*store QI post_inc OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_qi_post_dec"
- + [(set (mem:QI (post_dec:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:QI 1 "metag_reg_nofloat_op" "da"))]
- + "TARGET_METAC_1_1"
- + "SETB\\t[%0--], %1\\t%@ (*store QI post_dec OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_qi_pre_inc"
- + [(set (mem:QI (pre_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:QI 1 "metag_reg_nofloat_op" "da"))]
- + "TARGET_METAC_1_1"
- + "SETB\\t[++%0], %1\\t%@ (*store QI pre_inc OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_qi_pre_dec"
- + [(set (mem:QI (pre_dec:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:QI 1 "metag_reg_nofloat_op" "da"))]
- + "TARGET_METAC_1_1"
- + "SETB\\t[--%0], %1\\t%@ (*store QI pre_dec OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_qi_post_modify_disp"
- + [(set (mem:QI (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_qi" "O1,O1,O1,O1"))))
- + (match_operand:QI 2 "metag_reg_nofloat_op" "t, u, y, z"))]
- + "!TARGET_METAC_1_1"
- + "SETB\\t[%0+%1++], %2\\t%@ (*store QI post_modify_disp OK)"
- + [(set_attr "type" "fast,fast,fast,fast")])
- +
- +(define_insn "*sto_qi_post_modify_disp_1_1"
- + [(set (mem:QI (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_qi" "O1"))))
- + (match_operand:QI 2 "metag_reg_nofloat_op" "da"))]
- + "TARGET_METAC_1_1"
- + "SETB\\t[%0+%1++], %2\\t%@ (*store QI post_modify_disp OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_qi_post_modify_reg"
- + [(set (mem:QI (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e,f,h,l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e,f,h,l"))))
- + (match_operand:QI 2 "metag_reg_nofloat_op" "t,u,y,z"))]
- + ""
- + "SETB\\t[%0+%1++], %2\\t%@ (*store QI post_modify_reg OK)"
- + [(set_attr "type" "fast,fast,fast,fast")])
- +
- +(define_insn "*sto_qi_pre_modify_disp"
- + [(set (mem:QI (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_qi" "O1,O1,O1,O1"))))
- + (match_operand:QI 2 "metag_reg_nofloat_op" "t, u, y, z"))]
- + "!TARGET_METAC_1_1"
- + "SETB\\t[%0++%1], %2\\t%@ (*store QI pre_modify_disp OK) @2"
- + [(set_attr "type" "fast,fast,fast,fast")])
- +
- +(define_insn "*sto_qi_pre_modify_disp_1_1"
- + [(set (mem:QI (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_qi" "O1"))))
- + (match_operand:QI 2 "metag_reg_nofloat_op" "da"))]
- + "TARGET_METAC_1_1"
- + "SETB\\t[%0++%1], %2\\t%@ (*store QI pre_modify_disp OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_qi_pre_modify_reg"
- + [(set (mem:QI (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e,f,h,l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e,f,h,l"))))
- + (match_operand:QI 2 "metag_reg_nofloat_op" "t,u,y,z"))]
- + ""
- + "SETB\\t[%0++%1], %2\\t%@ (*store QI pre_modify_reg OK)"
- + [(set_attr "type" "fast,fast,fast,fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Non-side effecting base+offset store QI and catchall store QI cases |
- +;; -----------------------------------------------------------------------------
- +
- +;; movqi - base+index register to memory (stors's)
- +(define_insn "*sto_qi_mar"
- + [(set (mem:QI (plus:SI (match_operand:SI 0 "metag_regnofrm_op" "%e,f,h,l")
- + (match_operand:SI 1 "metag_regnofrm_op" " e,f,h,l")))
- + (match_operand:QI 2 "metag_reg_nofloat_op" " t,u,y,z"))]
- + ""
- + "SETB\\t[%0+%1], %2\\t%@ (*sto qi mar OK)"
- + [(set_attr "type" "fast")
- + (set_attr "length" "4,4,4,4")])
- +
- +;; movqi - register to memory (stores) some are fast, rest match spillqi below
- +(define_insn "*sto_qi_reg_indirect"
- + [(set (mem:QI (match_operand:SI 0 "metag_reg_nofloat_op" "e,f,h,l,!*da"))
- + (match_operand:QI 1 "metag_reg_nofloat_op" "t,u,y,z, *da"))]
- + "TARGET_COND_EXEC_OPTIMIZE && !TARGET_METAC_1_1"
- + "@
- + SETB%?\\t[%0], %1\\t%@ (*sto qi [e]t OK)
- + SETB%?\\t[%0], %1\\t%@ (*sto qi [f]u OK)
- + SETB%?\\t[%0], %1\\t%@ (*sto qi [h]y OK)
- + SETB%?\\t[%0], %1\\t%@ (*sto qi [l]z OK)
- + #"
- + [(set_attr "type" "fast,fast,fast,fast,invalid")
- + (set_attr "cond" "yes,yes,yes,yes,no")])
- +
- +(define_insn "*sto_qi"
- + [(set (match_operand:QI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl,!*m")
- + (match_operand:QI 1 "metag_reg_nofloat_op" "r, t, u, y, z, !*da"))]
- + "!TARGET_METAC_1_1 && !reload_completed"
- + "@
- + SETB\\t%0, %1\\t%@ (*sto qi [r]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [e]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [f]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [h]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [l]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [m]r OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,invalid")])
- +
- +(define_insn "*sto_qi_postreload"
- + [(set (match_operand:QI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl")
- + (match_operand:QI 1 "metag_reg_nofloat_op" "r, t, u, y, z"))]
- + "!TARGET_METAC_1_1 && reload_completed"
- + "@
- + SETB\\t%0, %1\\t%@ (*sto qi [r]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [e]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [f]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [h]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [l]r OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_qi_1_1_reg_indirect"
- + [(set (mem:QI (match_operand:SI 0 "metag_reg_nofloat_op" "da"))
- + (match_operand:QI 1 "metag_reg_nofloat_op" "da"))]
- + "TARGET_COND_EXEC_OPTIMIZE && TARGET_METAC_1_1"
- + "SETB%?\\t[%0], %1\\t%@ (*sto qi [r]r OK)"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*sto_qi_1_1_off12"
- + [(set (mem:QI (plus:SI (match_operand:SI 0 "metag_reg12bit_op" "da,Yr")
- + (match_operand:SI 1 "metag_offset12_qi" "O1,Z1")))
- + (match_operand:QI 2 "metag_reg_nofloat_op" "da,da"))]
- + "TARGET_METAC_1_1"
- + "SETB\\t[%0+%1], %2"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_qi_1_1_off6"
- + [(set (mem:QI (plus:SI (match_operand:SI 0 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 1 "metag_offset6_qi" "O1")))
- + (match_operand:QI 2 "metag_reg_nofloat_op" "da"))]
- + "TARGET_METAC_1_1"
- + "SETB\\t[%0+%1], %2"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_qi_1_1"
- + [(set (match_operand:QI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl,!*m")
- + (match_operand:QI 1 "metag_reg_nofloat_op" "r, t, u, y, z, !*da"))]
- + "TARGET_METAC_1_1 && !reload_completed"
- + "@
- + SETB\\t%0, %1\\t%@ (*sto qi [r]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [e]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [f]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [h]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [l]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [m]r OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,invalid")])
- +
- +(define_insn "*sto_qi_1_1_postreload"
- + [(set (match_operand:QI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl")
- + (match_operand:QI 1 "metag_reg_nofloat_op" "r, t, u, y, z"))]
- + "TARGET_METAC_1_1 && reload_completed"
- + "@
- + SETB\\t%0, %1\\t%@ (*sto qi [r]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [e]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [f]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [h]r OK)
- + SETB\\t%0, %1\\t%@ (*sto qi [l]r OK)"
- + [(set_attr "type" "fast")])
- +
- +;; spillqi - register to memory (stores) from source/dest in same bank
- +(define_split
- + [(set (match_operand:QI 0 "memory_operand" "")
- + (match_operand:QI 1 "metag_register_op" ""))]
- + "!TARGET_METAC_1_1
- + && reload_completed
- + && metag_slow_store (operands[0], operands[1])"
- + [(set (match_dup 2)
- + (match_dup 1))
- + (set (match_dup 0)
- + (match_dup 2))]
- + {
- + operands[2] = metag_gen_safe_temp (QImode, operands[1]);
- + }
- +)
- +
- +;; -----------------------------------------------------------------------------
- +;; | Matching QI load post/pre_inc/dec/modify and emitting ASM |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lod_qi_post_inc"
- + [(set (match_operand:QI 0 "metag_reg_nofloat_op" "=da")
- + (mem:QI (post_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + "GETB\\t%0, [%1++]\\t%@ (*load QI post_inc OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_qi_post_dec"
- + [(set (match_operand:QI 0 "metag_reg_nofloat_op" "=da")
- + (mem:QI (post_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + "GETB\\t%0, [%1--]\\t%@ (*load QI post_dec OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_qi_pre_inc"
- + [(set (match_operand:QI 0 "metag_reg_nofloat_op" "=da")
- + (mem:QI (pre_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + "GETB\\t%0, [++%1]\\t%@ (*load QI pre_inc OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_qi_pre_dec"
- + [(set (match_operand:QI 0 "metag_reg_nofloat_op" "=da")
- + (mem:QI (pre_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + "GETB\\t%0, [--%1]\\t%@ (*load QI pre_dec OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_qi_post_modify_disp"
- + [(set (match_operand:QI 0 "metag_register_op" "=da")
- + (mem:QI (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_qi" "O1")))))]
- + ""
- + "GETB\\t%0, [%1+%2++]\\t%@ (*load QI post_modify_disp OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_qi_post_modify_reg"
- + [(set (match_operand:QI 0 "metag_reg_nofloat_op" "=da,da,da,da")
- + (mem:QI (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l")))))]
- + ""
- + "GETB\\t%0, [%1+%2++]\\t%@ (*load QI post_modify_reg OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_qi_pre_modify_disp"
- + [(set (match_operand:QI 0 "metag_reg_nofloat_op" "=da")
- + (mem:QI (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_qi" "O1")))))]
- + ""
- + "GETB\\t%0, [%1++%2]\\t%@ (*load QI pre_modify_disp OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_qi_pre_modify_reg"
- + [(set (match_operand:QI 0 "metag_reg_nofloat_op" "=da,da,da,da")
- + (mem:QI (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l")))))]
- + ""
- + "GETB\\t%0, [%1++%2]\\t%@ (*load QI pre_modify_reg OK)"
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Non-side effecting base+offset load QI and catchall load QI |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lod_qi"
- + [(set (match_operand:QI 0 "metag_reg_nofloat_op" "=da")
- + (mem:QI (match_operand:SI 1 "metag_reg_nofloat_op" "da")))]
- + ""
- + "GETB\\t%0, [%1]\\t%@ (*lod qi rma OK)"
- + [(set_attr "type" "load")])
- +
- +;; movqi - base+index memory to register (loads)
- +(define_insn "*lod_qi_rma"
- + [(set (match_operand:QI 0 "metag_reg_nofloat_op" "=da,da,da,da")
- + (mem:QI (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "e, f, h, l")
- + (match_operand:SI 2 "metag_regnofrm_op" "e, f, h, l"))))]
- + ""
- + "GETB\\t%0, [%1+%2]\\t%@ (*lod qi rma OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_qi_off12"
- + [(set (match_operand:QI 0 "metag_reg_nofloat_op" "=da,da")
- + (mem:QI (plus:SI (match_operand:SI 1 "metag_reg12bit_op" "da,Yr")
- + (match_operand:SI 2 "metag_offset12_qi" "O1,Z1"))))]
- + ""
- + "GETB\\t%0, [%1+%2]"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_qi_off"
- + [(set (match_operand:QI 0 "metag_reg_nofloat_op" "=da")
- + (mem:QI (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 2 "metag_offset6_qi" "O1"))))]
- + ""
- + "GETB\\t%0, [%1+%2]"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_qi_mem"
- + [(set (match_operand:QI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:QI 1 "memory_operand" "m"))]
- + ""
- + "GETB\\t%0, %1"
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; movsf is made up of many parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "movsf"
- + [(set (match_operand:SF 0 "nonimmediate_operand" "")
- + (match_operand:SF 1 "general_operand" ""))]
- + ""
- + {
- + if (MEM_P (operands[0]))
- + {
- + /* All except mem = const or mem = mem can be done quickly */
- + operands[1] = force_reg (SFmode, operands[1]);
- + }
- + }
- +)
- +
- +;; movsf - all the register to register moves
- +(define_insn "*mov_sf"
- + [(set (match_operand:SF 0 "metag_register_op" "=cx,cx,d ,d,a,da")
- + (match_operand:SF 1 "metag_register_op" "cx,d, cx,d,a,da"))]
- + ""
- + "MOV%?\\t%0, %1\\t\\t%@ (*mov sf rr OK)"
- + [(set_attr "type" "fast,slow,slow,fast,fast,slow")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +;; movsf - all the immediate to register sets
- +(define_insn_and_split "*set_sf"
- + [(set (match_operand:SF 0 "metag_register_op" "=da,cx")
- + (match_operand:SF 1 "immediate_operand" "i, ci"))]
- + ""
- + "@
- + #
- + F\\tMOV\\t%0,#%h1"
- + "&& reload_completed
- + && (!METAG_FPC_REG_P (REGNO (operands[0]))
- + || !metag_fphalf_imm_op (operands[1], SFmode))"
- + [(const_int 0)]
- + {
- + metag_split_movsf_immediate (operands);
- + DONE;
- + }
- + [(set_attr "type" "two")])
- +
- +;; movsf - register to memory (stores) some are fast, rest match spillsf below
- +(define_insn "*sto_sf_reg_indirect"
- + [(set (mem:SF (match_operand:SI 0 "metag_reg_nofloat_op" "e,f,h,l,!*da"))
- + (match_operand:SF 1 "metag_register_op" "t,u,y,z, *da"))]
- + "TARGET_COND_EXEC_OPTIMIZE && !TARGET_METAC_1_1"
- + "@
- + SETD%?\\t[%0], %1\\t%@ (*sto sf [e]t OK)
- + SETD%?\\t[%0], %1\\t%@ (*sto sf [f]u OK)
- + SETD%?\\t[%0], %1\\t%@ (*sto sf [h]y OK)
- + SETD%?\\t[%0], %1\\t%@ (*sto sf [l]z OK)
- + #"
- + [(set_attr "type" "fast,fast,fast,fast,invalid")
- + (set_attr "cond" "yes,yes,yes,yes,no")])
- +
- +(define_insn "*sto_sf_post_inc"
- + [(set (mem:SF (post_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:SF 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0++], %1\\t%@ (*store SF post_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_sf_post_dec"
- + [(set (mem:SF (post_dec:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:SF 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0--], %1\\t%@ (*store SF post_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_sf_pre_inc"
- + [(set (mem:SF (pre_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:SF 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[++%0], %1\\t%@ (*store SF pre_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_sf_pre_dec"
- + [(set (mem:SF (pre_dec:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:SF 1 "metag_reg_nofloat_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[--%0], %1\\t%@ (*store SF pre_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_sf_post_modify_disp"
- + [(set (mem:SF (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_sf" "O4,O4,O4,O4"))))
- + (match_operand:SF 2 "metag_register_op" "t, u, y, z"))]
- + "!TARGET_METAC_1_1"
- + "SETD\\t[%0+%1++], %2\\t%@ (*store SF post_modify_disp OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_sf_post_modify_disp_1_1"
- + [(set (mem:SF (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_sf" "O4"))))
- + (match_operand:SF 2 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0+%1++], %2\\t%@ (*store SF post_modify_disp OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_sf_post_modify_reg"
- + [(set (mem:SF (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l ")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e, f, h, l"))))
- + (match_operand:SF 2 "metag_register_op" "ct,cu,cy,cz"))]
- + ""
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0+%1++], %2\\t%@ (*store SF post_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_sf_pre_modify_disp"
- + [(set (mem:SF (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_sf" "O4,O4,O4,O4"))))
- + (match_operand:SF 2 "metag_reg_nofloat_op" "t, u, y, z"))]
- + "!TARGET_METAC_1_1"
- + "SETD\\t[%0++%1], %2\\t%@ (*store SF pre_modify_disp OK)"
- + [(set_attr "type" "fast,fast,fast,fast")])
- +
- +(define_insn "*sto_sf_pre_modify_disp_1_1"
- + [(set (mem:SF (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_sf" "O4"))))
- + (match_operand:SF 2 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0++%1], %2\\t%@ (*store SF pre_modify_disp OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_sf_pre_modify_reg"
- + [(set (mem:SF (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e, f, h, l"))))
- + (match_operand:SF 2 "metag_register_op" "ct,cu,cy,cz"))]
- + ""
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0++%1], %2\\t%@ (*store SF pre_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; movsf - register to memory (stores) some are fast, rest match spillsf below
- +(define_insn "*sto_sf"
- + [(set (match_operand:SF 0 "memory_operand" "=Tr,Te,Tf,Th,Tl,!*m")
- + (match_operand:SF 1 "metag_reg_nofloat_op" "da,t, u, y, z, !*da"))]
- + "!TARGET_METAC_1_1 && !reload_completed"
- + "@
- + SETD\\t%0, %1\\t%@ (*sto sf [r]da OK)
- + SETD\\t%0, %1\\t%@ (*sto sf [e]t OK)
- + SETD\\t%0, %1\\t%@ (*sto sf [f]u OK)
- + SETD\\t%0, %1\\t%@ (*sto sf [h]y OK)
- + SETD\\t%0, %1\\t%@ (*sto sf [l]z OK)
- + SETD\\t%0, %1\\t%@ (*sto sf [m]da OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,invalid")])
- +
- +(define_insn "*sto_sf_postreload"
- + [(set (match_operand:SF 0 "memory_operand" "=Tr,Te,Tf,Th,Tl")
- + (match_operand:SF 1 "metag_reg_nofloat_op" "da,t, u, y, z"))]
- + "!TARGET_METAC_1_1 && reload_completed"
- + "@
- + SETD\\t%0, %1\\t%@ (*sto sf [r]da OK)
- + SETD\\t%0, %1\\t%@ (*sto sf [e]t OK)
- + SETD\\t%0, %1\\t%@ (*sto sf [f]u OK)
- + SETD\\t%0, %1\\t%@ (*sto sf [h]y OK)
- + SETD\\t%0, %1\\t%@ (*sto sf [l]z OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_sf_1_1_reg_indirect"
- + [(set (mem:SF (match_operand:SI 0 "metag_reg_nofloat_op" "da"))
- + (match_operand:SF 1 "metag_register_op" "cr"))]
- + "TARGET_COND_EXEC_OPTIMIZE && TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD%?\\t[%0], %1\\t%@ (*sto sf [r]r OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*sto_sf_1_1_off12"
- + [(set (mem:SF (plus:SI (match_operand:SI 0 "metag_reg12bit_op" "da,Yr")
- + (match_operand:SI 1 "metag_offset12_sf" "O4,Z4")))
- + (match_operand:SF 2 "metag_reg_nofloat_op" "da,da"))]
- + "TARGET_METAC_1_1"
- + "SETD\\t[%0+%1], %2"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_sf_1_1_off6"
- + [(set (mem:SF (plus:SI (match_operand:SI 0 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 1 "metag_offset6_sf" "O4")))
- + (match_operand:SF 2 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETD\\t[%0+%1], %2";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_sf_1_1"
- + [(set (match_operand:SF 0 "memory_operand" "=Tr,Te,Tf,Th,Tl,!*m")
- + (match_operand:SF 1 "metag_register_op" "da,t ,u, y, z, !*da"))]
- + "TARGET_METAC_1_1 && !reload_completed"
- + "SETD\\t%0, %1\\t%@ (*sto sf [m]r OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,invalid")])
- +
- +(define_insn "*sto_sf_1_1_postreload"
- + [(set (match_operand:SF 0 "memory_operand" "=Tr,Te,Tf,Th,Tl")
- + (match_operand:SF 1 "metag_register_op" "da,t, u, y, z"))]
- + "TARGET_METAC_1_1 && reload_completed"
- + "SETD\\t%0, %1\\t%@ (*sto sf [m]r OK)"
- + [(set_attr "type" "fast")])
- +
- +;; spillsf - register to memory (stores) from source/dest in same bank
- +(define_split
- + [(set (match_operand:SF 0 "memory_operand" "")
- + (match_operand:SF 1 "metag_register_op" ""))]
- + "!TARGET_METAC_1_1
- + && reload_completed
- + && metag_slow_store (operands[0], operands[1])"
- + [(set (match_dup 2)
- + (match_dup 1))
- + (set (match_dup 0)
- + (match_dup 2))]
- + {
- + operands[2] = metag_gen_safe_temp (SFmode, operands[1]);
- + }
- +)
- +
- +;; -----------------------------------------------------------------------------
- +;; | Matching SF load post/pre_inc/dec/modify and emitting ASM |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lod_sf_post_inc"
- + [(set (match_operand:SF 0 "metag_register_op" "=cr")
- + (mem:SF (post_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1++]\\t%@ (*load SF post_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_sf_post_dec"
- + [(set (match_operand:SF 0 "metag_register_op" "=cr")
- + (mem:SF (post_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1--]\\t%@ (*load SF post_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_sf_pre_inc"
- + [(set (match_operand:SF 0 "metag_register_op" "=cr")
- + (mem:SF (pre_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [++%1]\\t%@ (*load SF pre_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_sf_pre_dec"
- + [(set (match_operand:SF 0 "metag_register_op" "=cr")
- + (mem:SF (pre_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [--%1]\\t%@ (*load SF pre_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_sf_post_modify_disp"
- + [(set (match_operand:SF 0 "metag_register_op" "=cr")
- + (mem:SF (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_sf" "O4")))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1+%2++]\\t%@ (*load SF post_modify_disp OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_sf_post_modify_reg"
- + [(set (match_operand:SF 0 "metag_register_op" "=cr,cr,cr,cr")
- + (mem:SF (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l")))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1+%2++]\\t%@ (*load SF post_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_sf_pre_modify_disp"
- + [(set (match_operand:SF 0 "metag_register_op" "=cr")
- + (mem:SF (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_sf" "O4")))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1++%2]\\t%@ (*load SF pre_modify_disp OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_sf_pre_modify_reg"
- + [(set (match_operand:SF 0 "metag_register_op" "=cr,cr,cr,cr")
- + (mem:SF (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l")))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1++%2]\\t%@ (*load SF pre_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; movsf - memory to register (loads)
- +(define_insn "*lod_sf_rma"
- + [(set (match_operand:SF 0 "metag_register_op" "=cr,cr,cr,cr")
- + (mem:SF (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "e, f, h, l")
- + (match_operand:SI 2 "metag_regnofrm_op" "e, f, h, l"))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1+%2]";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_sf_off12"
- + [(set (match_operand:SF 0 "metag_reg_nofloat_op" "=da,da")
- + (mem:SF (plus:SI (match_operand:SI 1 "metag_reg12bit_op" "da,Yr")
- + (match_operand:SI 2 "metag_offset12_sf" "O4,Z4"))))]
- + ""
- + "GETD\\t%0, [%1+%2]"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_sf_off"
- + [(set (match_operand:SF 0 "metag_register_op" "=cr")
- + (mem:SF (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 2 "metag_offset6_sf" "O4"))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1+%2]";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_sf"
- + [(set (match_operand:SF 0 "metag_register_op" "=cr")
- + (mem:SF (match_operand:SI 1 "metag_reg_nofloat_op" "da")))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETD\\t%0, [%1]";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_sf_mem"
- + [(set (match_operand:SF 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:SF 1 "memory_operand" "m"))]
- + ""
- + "GETD\\t%0, %1\\t%@ (*lod sf rm OK)"
- + [(set_attr "type" "load")])
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; movdi is made up of many parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "movdi"
- + [(set (match_operand:DI 0 "nonimmediate_operand" "")
- + (match_operand:DI 1 "general_operand" ""))]
- + ""
- + {
- + if (MEM_P (operands[0]))
- + {
- + if (!no_new_pseudos)
- + {
- + /* All except mem = const or mem = mem can be done quickly */
- + operands[1] = force_reg (DImode, operands[1]);
- + }
- + }
- + }
- +)
- +
- +;; movdi - register to register forms
- +(define_insn_and_split "*mov_di"
- + [(set (match_operand:DI 0 "metag_register_op" "=d,a,d, cx,cx,?da")
- + (match_operand:DI 1 "metag_register_op" "d,a,cx,d, cx,?da"))]
- + ""
- + {
- + switch (which_alternative)
- + {
- + case 0:
- + case 1:
- + case 5:
- + return "#";
- + case 2:
- + case 3:
- + case 4:
- + if (metag_fpu_single)
- + return "#";
- + else
- + return "FD\\tMOV\\t%0,%1";
- + default:
- + gcc_unreachable();
- + }
- + }
- + "reload_completed"
- + [(const_int 0)]
- + {
- + /* WORK NEEDED: When in hard-float mode, FL MOV will do a dual
- + unit MOV to FCC regs */
- + if (TARGET_DSP
- + && metag_datareg_p (REGNO (operands[0]))
- + && metag_datareg_p (REGNO (operands[1])))
- + {
- + operands[0] = gen_rtx_REG (V2SImode, REGNO (operands[0]));
- + operands[1] = gen_rtx_REG (V2SImode, REGNO (operands[1]));
- + emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
- + }
- + else
- + metag_split_movdi (operands);
- + DONE;
- + }
- + [(set_attr "type" "two,two,two,two,two,slowslow")
- + (set_attr "cond" "yes,yes,yes,yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn_and_split "*set_di"
- + [(set (match_operand:DI 0 "metag_reg_nofloat_op" "=d,a")
- + (match_operand:DI 1 "immediate_operand" "i,i"))]
- + ""
- + "#"
- + "reload_completed"
- + [(const_int 0)]
- + {
- + metag_split_movdi_immediate (operands);
- + DONE;
- + }
- + [(set_attr "type" "four")])
- +
- +
- +;; -----------------------------------------------------------------------------
- +;; | Matching DI store post/pre_inc/dec/modify and emitting ASM |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*sto_di_post_inc_concat"
- + [(set (mem:DI (post_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da,da")))
- + (unspec:DI [(match_operand:SI 1 "metag_reg_nofloat_op" "e, h")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "f, l")] UNSPEC_CONCAT))]
- + "TARGET_METAC_1_1"
- + "SETL\\t[%0++], %1, %2"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_post_inc"
- + [(set (mem:DI (post_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:DI 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0++], %1, %t1\\t%@ (*store DI post_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_post_dec"
- + [(set (mem:DI (post_dec:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:DI 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0--], %1, %t1\\t%@ (*store DI post_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_pre_inc"
- + [(set (mem:DI (pre_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:DI 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[++%0], %1, %t1\\t%@ (*store DI pre_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_pre_dec"
- + [(set (mem:DI (pre_dec:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:DI 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[--%0], %1, %t1\\t%@ (*store DI pre_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_post_modify_disp"
- + [(set (mem:DI (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+d, a")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_di" "O8,O8"))))
- + (match_operand:DI 2 "metag_register_op" "a, d"))]
- + "!TARGET_METAC_1_1"
- + "SETL\\t[%0+%1++], %2, %t2\\t%@ (*store DI post_modify_disp OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_post_modify_disp_1_1"
- + [(set (mem:DI (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_di" "O8"))))
- + (match_operand:DI 2 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0+%1++], %2, %t2\\t%@ (*store DI post_modify_disp_1_1 OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_post_modify_reg"
- + [(set (mem:DI (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e, f, h, l"))))
- + (match_operand:DI 2 "metag_register_op" "ca,ca,cd,cd"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0+%1++], %2, %t2\\t%@ (*store DI post_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_pre_modify_disp"
- + [(set (mem:DI (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+d, a")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_di" "O8,O8"))))
- + (match_operand:DI 2 "metag_reg_nofloat_op" "a, d"))]
- + "!TARGET_METAC_1_1"
- + "SETL\\t[%0++%1], %2, %t2\\t%@ (*store DI pre_modify_disp OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_pre_modify_disp_1_1"
- + [(set (mem:DI (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_di" "O8"))))
- + (match_operand:DI 2 "metag_reg_nofloat_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0++%1], %2, %t2\\t%@ (*store DI pre_modify_disp_1_1 OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_pre_modify_reg"
- + [(set (mem:DI (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e, f, h, l"))))
- + (match_operand:DI 2 "metag_register_op" "ca,ca,cd,cd"))]
- + ""
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0++%1], %2, %t2\\t%@ (*store DI pre_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Non-side effecting base+offset store DI and catchall store DI cases |
- +;; -----------------------------------------------------------------------------
- +
- +;; movdi - register to memory (stores) some are fast, rest match spilldi below
- +(define_insn "*sto_di_cond_exec_concat"
- + [(set (mem:DI (match_operand:SI 0 "metag_reg_nofloat_op" "a,d,!da"))
- + (unspec:DI [(match_operand:SI 1 "metag_reg_nofloat_op" "d,a, da")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "d,a, da")] UNSPEC_CONCAT))]
- + "TARGET_COND_EXEC_OPTIMIZE
- + && !TARGET_METAC_1_1
- + && reload_completed
- + && !( metag_regno_same_unit_p (REGNO (operands[0]), REGNO (operands[1]))
- + || metag_regno_same_unit_p (REGNO (operands[0]), REGNO (operands[2])))"
- + "SETL%?\\t[%0], %1, %2\\t%@ (*sto di OK)"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*sto_di_cond_exec"
- + [(set (mem:DI (match_operand:SI 0 "metag_reg_nofloat_op" "a,d,!da"))
- + (match_operand:DI 1 "metag_reg_nofloat_op" "d,a, da"))]
- + "TARGET_COND_EXEC_OPTIMIZE
- + && !TARGET_METAC_1_1
- + && reload_completed
- + && !( metag_regno_same_unit_p (REGNO (operands[0]), REGNO (operands[1]))
- + || metag_regno_same_unit_p (REGNO (operands[0]), REGNO (operands[1]) + 1))"
- + "SETL%?\\t[%0], %1, %t1\\t%@ (*sto di OK)"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*sto_di_concat"
- + [(set (match_operand:DI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl,!m")
- + (unspec:DI [(match_operand:SI 1 "metag_reg_nofloat_op" "r, a, a, d, d, da")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "r, a, a, d, d, da")] UNSPEC_CONCAT))]
- + "!TARGET_METAC_1_1"
- + "SETL\\t%0, %1, %2"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_off12"
- + [(set (mem:DI (plus:SI (match_operand:SI 0 "metag_reg12bit_op" "e, f, h, l, Ye,Yf,Yh,Yl")
- + (match_operand:SI 1 "metag_offset12_di" "O8,O8,O8,O8,Z8,Z8,Z8,Z8")))
- + (match_operand:DI 2 "metag_reg_nofloat_op" "a, a, d, d, a, a, d, d"))]
- + "!TARGET_METAC_1_1"
- + "SETL\\t[%0+%1], %2, %t2"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_off6"
- + [(set (mem:DI (plus:SI (match_operand:SI 0 "metag_reg_nofloat_op" "e, f, h, l")
- + (match_operand:SI 1 "metag_offset6_di" "O8,O8,O8,O8")))
- + (match_operand:DI 2 "metag_register_op" "a, a, d, d"))]
- + "!TARGET_METAC_1_1"
- + "SETL\\t[%0+%1], %2, %t2"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di"
- + [(set (match_operand:DI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl,!*m")
- + (match_operand:DI 1 "metag_reg_nofloat_op" "r, a, a, d, d, !*da"))]
- + "!TARGET_METAC_1_1 && !reload_completed"
- + "SETL\\t%0, %1, %t1"
- + [(set_attr "type" "fast,fast,fast,fast,fast,invalid")])
- +
- +(define_insn "*sto_di_postreload"
- + [(set (match_operand:DI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl")
- + (match_operand:DI 1 "metag_reg_nofloat_op" "r, a, a, d, d"))]
- + "!TARGET_METAC_1_1 && reload_completed"
- + "SETL\\t%0, %1, %t1"
- + [(set_attr "type" "fast")])
- +
- +;; movdi - base+index register to memory (stores)
- +(define_insn "*sto_di_mar"
- + [(set (mem:DI (plus:SI (match_operand:SI 0 "metag_regnofrm_op" "%e, f, h, l")
- + (match_operand:SI 1 "metag_regnofrm_op" " e, f, h, l")))
- + (match_operand:DI 2 "metag_register_op" "ca,ca,cd,cd"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0+%1], %2, %t2\\t\\t%@ (*sto di mar OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")
- + (set_attr "length" "4,4,4,4")])
- +
- +(define_insn "*sto_di_reg_indirect_concat_1_1"
- + [(set (mem:DI (match_operand:SI 0 "metag_reg_nofloat_op" "da"))
- + (unspec:DI [(match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "da")] UNSPEC_CONCAT))]
- + "TARGET_COND_EXEC_OPTIMIZE && TARGET_METAC_1_1"
- + "SETL%?\\t[%0], %1, %2\\t%@ (*sto di OK)"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*sto_di_reg_indirect_1_1"
- + [(set (mem:DI (match_operand:SI 0 "metag_reg_nofloat_op" "da"))
- + (match_operand:DI 1 "metag_reg_nofloat_op" "da"))]
- + "TARGET_COND_EXEC_OPTIMIZE && TARGET_METAC_1_1"
- + "SETL%?\\t[%0], %1, %t1\\t%@ (*sto di OK)"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*sto_di_concat_1_1"
- + [(set (match_operand:DI 0 "memory_operand" "=m, m")
- + (unspec:DI [(match_operand:SI 1 "metag_register_op" "da,cx")
- + (match_operand:SI 2 "metag_register_op" "da,cx")] UNSPEC_CONCAT))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t%0, %1, %2\\t\\t%@ (*sto di [r]r OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_1_1_off12"
- + [(set (mem:DI (plus:SI (match_operand:SI 0 "metag_reg12bit_op" "da,Yr")
- + (match_operand:SI 1 "metag_offset12_di" "O8,Z8")))
- + (match_operand:DI 2 "metag_reg_nofloat_op" "da,da"))]
- + "TARGET_METAC_1_1"
- + "SETL\\t[%0+%1], %2, %t2"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_1_1_off6"
- + [(set (mem:DI (plus:SI (match_operand:SI 0 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 1 "metag_offset6_di" "O8")))
- + (match_operand:DI 2 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0+%1], %2, %t2";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_di_1_1"
- + [(set (match_operand:DI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl,!*m")
- + (match_operand:DI 1 "metag_reg_nofloat_op" "r, a, a, d, d, !*da"))]
- + "TARGET_METAC_1_1 && !reload_completed"
- + "SETL\\t%0, %1, %t1\\t\\t%@ (*sto di [r]r OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,invalid")])
- +
- +(define_insn "*sto_di_1_1_postreload"
- + [(set (match_operand:DI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl")
- + (match_operand:DI 1 "metag_reg_nofloat_op" "r, a, a, d, d"))]
- + "TARGET_METAC_1_1 && reload_completed"
- + "SETL\\t%0, %1, %t1\\t\\t%@ (*sto di [r]r OK)"
- + [(set_attr "type" "fast")])
- +
- +;; spilldi - register to memory (stores) from source/dest in same bank
- +(define_split
- + [(set (match_operand:DI 0 "memory_operand" "")
- + (match_operand:DI 1 "metag_register_op" ""))]
- + "!TARGET_METAC_1_1
- + && reload_completed
- + && metag_slow_store (operands[0], operands[1])"
- + [(set (match_dup 2)
- + (match_dup 1))
- + (set (match_dup 0)
- + (match_dup 2))]
- + {
- + operands[2] = metag_gen_safe_temp (DImode, operands[1]);
- + }
- +)
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; movdi - memory to register (loads)
- +
- +;; -----------------------------------------------------------------------------
- +;; | Matching DI store [post/pre]_[inc/dec/modify] and emitting ASM |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lod_di_concat_post_inc"
- + [(set (unspec:DI [(match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:SI 1 "metag_reg_nofloat_op" "=da")] UNSPEC_CONCAT)
- + (mem:DI (post_inc:SI (match_operand:SI 2 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + "GETL\\t%0, %1, [%2++]\\t%@ (*load DI post_inc OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_di_post_inc"
- + [(set (match_operand:DI 0 "metag_register_op" "=cr")
- + (mem:DI (post_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGETL\\t%0, %t0, [%1++]\\t%@ (*load DI post_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_di_post_dec"
- + [(set (match_operand:DI 0 "metag_register_op" "=cr")
- + (mem:DI (post_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGETL\\t%0, %t0, [%1--]\\t%@ (*load DI post_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_di_pre_inc"
- + [(set (match_operand:DI 0 "metag_register_op" "=cr")
- + (mem:DI (pre_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGETL\\t%0, %t0, [++%1]\\t%@ (*load DI pre_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_di_pre_dec"
- + [(set (match_operand:DI 0 "metag_register_op" "=cr")
- + (mem:DI (pre_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da"))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGETL\\t%0, %t0, [--%1]\\t%@ (*load DI pre_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_di_post_modify_disp"
- + [(set (match_operand:DI 0 "metag_register_op" "=cr")
- + (mem:DI (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_di" "O8")))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETL\\t%0, %t0, [%1+%2++]\\t%@ (*load DI post_modify_disp OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_di_post_modify_reg"
- + [(set (match_operand:DI 0 "metag_register_op" "=cr,cr,cr,cr")
- + (mem:DI (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l")))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETL\\t%0, %t0, [%1+%2++]\\t%@ (*load DI post_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_di_pre_modify_disp"
- + [(set (match_operand:DI 0 "metag_register_op" "=cr")
- + (mem:DI (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_di" "O8")))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETL\\t%0, %t0, [%1++%2]\\t%@ (*load DI pre_modify_disp OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_di_pre_modify_reg"
- + [(set (match_operand:DI 0 "metag_register_op" "=cr,cr,cr,cr")
- + (mem:DI (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l")))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETL\\t%0, %t0, [%1++%2]\\t%@ (*load DI pre_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Non-side effecting base+offset load DI and catchall load DI |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lod_di"
- + [(set (match_operand:DI 0 "metag_register_op" "=cr")
- + (mem:DI (match_operand:SI 1 "metag_regnofrm_op" "da")))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETL\\t%0, %t0, [%1]\\t%@ (*lod di rma OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +;; movdi - base+index memory to register (loads)
- +(define_insn "*lod_di_rma"
- + [(set (match_operand:DI 0 "metag_register_op" "=cr,cr,cr,cr")
- + (mem:DI (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "%e, f, h, l")
- + (match_operand:SI 2 "metag_regnofrm_op" "e, f, h, l"))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETL\\t%0, %t0, [%1+%2]\\t%@ (*lod qi rma OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_di_concat"
- + [(set (unspec:DI [(match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:SI 1 "metag_reg_nofloat_op" "=da")] UNSPEC_CONCAT)
- + (match_operand:DI 2 "memory_operand" "m"))]
- + ""
- + "GETL\\t%0, %1, %2"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_di_off12"
- + [(set (match_operand:DI 0 "metag_reg_nofloat_op" "=da,da")
- + (mem:DI (plus:SI (match_operand:SI 1 "metag_reg12bit_op" "da,Yr")
- + (match_operand:SI 2 "metag_offset12_di" "O8,Z8"))))]
- + ""
- + "GETL\\t%0, %t0, [%1+%2]"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_di_off6"
- + [(set (match_operand:DI 0 "metag_register_op" "=cr")
- + (mem:DI (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 2 "metag_offset6_di" "O8"))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETL\\t%0, %t0, [%1+%2]";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_di_mem"
- + [(set (match_operand:DI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:DI 1 "memory_operand" "m"))]
- + ""
- + "GETL\\t%0, %t0, %1\\t%@ (*lod di rm)"
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; movdf is made up of many parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "movdf"
- + [(set (match_operand:DF 0 "nonimmediate_operand" "")
- + (match_operand:DF 1 "general_operand" ""))]
- + ""
- + {
- + if (MEM_P (operands[0]))
- + {
- + /* All except mem = const or mem = mem can be done quickly */
- + operands[1] = force_reg (DFmode, operands[1]);
- + }
- +
- + if (metag_fpu_single
- + && REG_P (operands[0])
- + && METAG_FPC_REG_P (REGNO (operands[0]))
- + && CONST_DOUBLE_P (operands[1]))
- + FAIL;
- + }
- +)
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; and these are the movdf parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +
- +;; movdf - register to register forms
- +(define_insn_and_split "*mov_df"
- + [(set (match_operand:DF 0 "metag_register_op" "=cx,d, cx,d,a,da")
- + (match_operand:DF 1 "metag_register_op" "cx,cx,d, d,a,da"))]
- + ""
- + {
- + switch (which_alternative)
- + {
- + case 0:
- + if (!metag_fpu_single)
- + return "FL\\tMOV%?\\t%0,%1";
- + else
- + return "#";
- + case 1:
- + case 2:
- + return "F\\tMOVL\\t%0,%1";
- + case 3:
- + if (TARGET_DSP)
- + return "DL\\tMOV\\t%0, %1";
- + /* Fall through */
- + case 4:
- + case 5:
- + return "#";
- + default:
- + gcc_unreachable();
- + }
- + }
- + "&& reload_completed"
- + [(const_int 0)]
- + {
- + metag_split_movdf (operands);
- + DONE;
- + }
- + [(set_attr "type" "fast,fast,fast,two,two,slowslow")
- + (set_attr "cond" "yes,no,no,yes,yes,yes")
- + (set_attr "predicable" "no")])
- +
- +;; movdf - immediate to register forms
- +(define_insn_and_split "*set_df"
- + [(set (match_operand:DF 0 "metag_register_op" "=d,a,cx")
- + (match_operand:DF 1 "immediate_operand" "i,i,ci"))]
- + "!metag_fpu_single"
- + {
- + switch (which_alternative)
- + {
- + case 0:
- + case 1:
- + return "#";
- + case 2:
- + return "FD\\tMOV\\t%0,#%h1";
- + default:
- + gcc_unreachable();
- + }
- + }
- + "&& reload_completed
- + && (!METAG_FPC_REG_P (REGNO (operands[0]))
- + || !metag_fphalf_imm_op (operands[1], DFmode))"
- + [(const_int 0)]
- + {
- + metag_split_movdf_immediate (operands);
- + DONE;
- + }
- + [(set_attr "type" "four")])
- +
- +(define_insn_and_split "*set_df_fpu_single"
- + [(set (match_operand:DF 0 "metag_register_op" "=d,a")
- + (match_operand:DF 1 "immediate_operand" "i,i"))]
- + "metag_fpu_single"
- + "#"
- + "&& reload_completed"
- + [(const_int 0)]
- + {
- + metag_split_movdf_immediate (operands);
- + DONE;
- + }
- + [(set_attr "type" "four")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*sto_df_post_inc"
- + [(set (mem:DF (post_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:DF 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0++], %1, %t1\\t%@ (*store DF post_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_df_post_dec"
- + [(set (mem:DF (post_dec:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:DF 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0--], %1, %t1\\t%@ (*store DF post_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_df_pre_inc"
- + [(set (mem:DF (pre_inc:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:DF 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[++%0], %1, %t1\\t%@ (*store DF pre_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_df_pre_dec"
- + [(set (mem:DF (pre_dec:SI (match_operand:SI 0 "metag_reg_nofloat_op" "+da")))
- + (match_operand:DF 1 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[--%0], %1, %t1\\t%@ (*store DF pre_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_df_post_modify_disp"
- + [(set (mem:DF (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+d, a")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_df" "O8,O8"))))
- + (match_operand:DF 2 "metag_register_op" "a, d"))]
- + "!TARGET_METAC_1_1"
- + "SETL\\t[%0+%1++], %2, %t2\\t%@ (*store DF post_modify_disp OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_df_post_modify_disp_1_1"
- + [(set (mem:DF (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_df" "O8"))))
- + (match_operand:DF 2 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0+%1++], %2, %t2\\t%@ (*store DF post_modify_disp_1_1 OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_df_post_modify_reg"
- + [(set (mem:DF (post_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e, f, h, l"))))
- + (match_operand:DF 2 "metag_register_op" "ca,ca,cd,cd"))]
- + ""
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0+%1++], %2, %t2\\t%@ (*store DF post_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_df_pre_modify_disp"
- + [(set (mem:DF (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+d, a")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_df" "O8,O8"))))
- + (match_operand:DF 2 "metag_reg_nofloat_op" "a, d"))]
- + "!TARGET_METAC_1_1"
- + "SETL\\t[%0++%1], %2, %t2\\t%@ (*store DF pre_modify_disp OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_df_pre_modify_disp_1_1"
- + [(set (mem:DF (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_df" "O8"))))
- + (match_operand:DF 2 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0++%1], %2, %t2\\t%@ (*store DF pre_modify_disp_1_1 OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_df_pre_modify_reg"
- + [(set (mem:DF (pre_modify:SI
- + (match_operand:SI 0 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e, f, h, l"))))
- + (match_operand:DF 2 "metag_register_op" "ca,ca,cd,cd"))]
- + ""
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0++%1], %2, %t2\\t%@ (*store DF pre_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; movdf - register to memory forms (stores)
- +(define_insn "*sto_df_reg_indirect"
- + [(set (mem:DF (match_operand:SI 0 "metag_reg_nofloat_op" "a,d,ad,!da"))
- + (match_operand:DF 1 "metag_register_op" "d,a,cx, da"))]
- + "TARGET_COND_EXEC_OPTIMIZE
- + && !TARGET_METAC_1_1
- + && reload_completed
- + && !( metag_regno_same_unit_p (REGNO (operands[0]), REGNO (operands[1]))
- + || metag_regno_same_unit_p (REGNO (operands[0]), REGNO (operands[1]) + 1))"
- + {
- + static const char fmt[] = "F\\tSETL%?\\t[%0], %1, %t1\\t%@ (*sto df OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*sto_df"
- + [(set (match_operand:DF 0 "memory_operand" "=Tr,Te,Tf,Th,Tl,!*m")
- + (match_operand:DF 1 "metag_register_op" "da,a, a, d, d, !*da"))]
- + "!TARGET_METAC_1_1 && !reload_completed"
- + "SETL\\t%0, %1, %t1"
- + [(set_attr "type" "fast,fast,fast,fast,fast,invalid")])
- +
- +(define_insn "*sto_df_postreload"
- + [(set (match_operand:DF 0 "memory_operand" "=Tr,Te,Tf,Th,Tl")
- + (match_operand:DF 1 "metag_register_op" "da,a, a, d, d"))]
- + "!TARGET_METAC_1_1 && reload_completed"
- + "SETL\\t%0, %1, %t1"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_df_1_1_reg_indirect"
- + [(set (mem:DF (match_operand:SI 0 "metag_reg_nofloat_op" "da"))
- + (match_operand:DF 1 "metag_register_op" "cr"))]
- + "TARGET_COND_EXEC_OPTIMIZE && TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL%?\\t[%0], %1, %t1\\t%@ (*sto df [r]r OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[1])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*sto_df_1_1_off12"
- + [(set (mem:DF (plus:SI (match_operand:SI 0 "metag_reg12bit_op" "da,Yr")
- + (match_operand:SI 1 "metag_offset12_df" "O8,Z8")))
- + (match_operand:DF 2 "metag_reg_nofloat_op" "da,da"))]
- + "TARGET_METAC_1_1"
- + "SETL\\t[%0+%1], %2, %t2"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_df_1_1_off6"
- + [(set (mem:DF (plus:SI (match_operand:SI 0 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 1 "metag_offset6_df" "O8")))
- + (match_operand:DF 2 "metag_register_op" "cr"))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tSETL\\t[%0+%1], %2, %t2";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[2])) ? 0 : 2];
- + }
- + [(set_attr "type" "fast")])
- +
- +;; movdf - register to memory forms (stores)
- +(define_insn "*sto_df_1_1"
- + [(set (match_operand:DF 0 "memory_operand" "=Tr,Te,Tf,Th,Tl,!*m")
- + (match_operand:DF 1 "metag_reg_nofloat_op" "da, a, a, d, d,!*da"))]
- + "TARGET_METAC_1_1 && !reload_completed"
- + "SETL\\t%0, %1, %t1\\t\\t%@ (*sto df [r]r OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,invalid")])
- +
- +(define_insn "*sto_df_1_1_postreload"
- + [(set (match_operand:DF 0 "memory_operand" "=Tr,Te,Tf,Th,Tl")
- + (match_operand:DF 1 "metag_reg_nofloat_op" "da, a, a, d, d"))]
- + "TARGET_METAC_1_1 && reload_completed"
- + "SETL\\t%0, %1, %t1\\t\\t%@ (*sto df [r]r OK)"
- + [(set_attr "type" "fast")])
- +
- +;; spilldf - register to memory (stores) from source/dest in same bank
- +(define_split
- + [(set (match_operand:DF 0 "memory_operand" "")
- + (match_operand:DF 1 "metag_register_op" ""))]
- + "!TARGET_METAC_1_1
- + && reload_completed
- + && metag_slow_store (operands[0], operands[1])"
- + [(set (match_dup 2)
- + (match_dup 1))
- + (set (match_dup 0)
- + (match_dup 2))]
- + {
- + operands[2] = metag_gen_safe_temp (DFmode, operands[1]);
- + }
- +)
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; movdf - memory to register (loads)
- +
- +;; -----------------------------------------------------------------------------
- +;; | Matching DF store [post/pre]_[inc/dec/modify]
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lod_df_post_inc"
- + [(set (match_operand:DF 0 "metag_register_op" "=da,cx")
- + (mem:DF (post_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da,da"))))]
- + "TARGET_METAC_1_1"
- + "@
- + GETL\\t%0, %t0, [%1++]\\t%@ (*load DF post_inc OK)
- + F\\tGETL\\t%0, %t0, [%1++]\\t%@ (*load DF post_inc OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_df_post_dec"
- + [(set (match_operand:DF 0 "metag_register_op" "=da,cx")
- + (mem:DF (post_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da,da"))))]
- + "TARGET_METAC_1_1"
- + "@
- + GETL\\t%0, %t0, [%1--]\\t%@ (*load DF post_dec OK)
- + F\\tGETL\\t%0, %t0, [%1--]\\t%@ (*load DF post_dec OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_df_pre_inc"
- + [(set (match_operand:DF 0 "metag_register_op" "=da,cx")
- + (mem:DF (pre_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da,da"))))]
- + "TARGET_METAC_1_1"
- + "@
- + GETL\\t%0, %t0, [++%1]\\t%@ (*load DF pre_inc OK)
- + F\\tGETL\\t%0, %t0, [++%1]\\t%@ (*load DF pre_inc OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_df_pre_dec"
- + [(set (match_operand:DF 0 "metag_register_op" "=da,cx")
- + (mem:DF (pre_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da,da"))))]
- + "TARGET_METAC_1_1"
- + "@
- + GETL\\t%0, %t0, [--%1]\\t%@ (*load DF pre_dec OK)
- + F\\tGETL\\t%0, %t0, [--%1]\\t%@ (*load DF pre_dec OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_df_post_modify_disp"
- + [(set (match_operand:DF 0 "metag_register_op" "=da,cx")
- + (mem:DF (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da,da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_df" "O8,O8")))))]
- + ""
- + "@
- + GETL\\t%0, %t0, [%1+%2++]\\t%@ (*load DF post_modify_disp OK)
- + F\\tGETL\\t%0, %t0, [%1+%2++]\\t%@ (*load DF post_modify_disp OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_df_post_modify_reg"
- + [(set (match_operand:DF 0 "metag_register_op" "=da,da,da,da,cx,cx,cx,cx")
- + (mem:DF (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l, e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l, e, f, h, l")))))]
- + ""
- + "@
- + GETL\\t%0, %t0, [%1+%2++]\\t%@ (*load DF post_modify_reg OK)
- + GETL\\t%0, %t0, [%1+%2++]\\t%@ (*load DF post_modify_reg OK)
- + GETL\\t%0, %t0, [%1+%2++]\\t%@ (*load DF post_modify_reg OK)
- + GETL\\t%0, %t0, [%1+%2++]\\t%@ (*load DF post_modify_reg OK)
- + F\\tGETL\\t%0, %t0, [%1+%2++]\\t%@ (*load DF post_modify_reg OK)
- + F\\tGETL\\t%0, %t0, [%1+%2++]\\t%@ (*load DF post_modify_reg OK)
- + F\\tGETL\\t%0, %t0, [%1+%2++]\\t%@ (*load DF post_modify_reg OK)
- + F\\tGETL\\t%0, %t0, [%1+%2++]\\t%@ (*load DF post_modify_reg OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_df_pre_modify_disp"
- + [(set (match_operand:DF 0 "metag_register_op" "=da,cx")
- + (mem:DF (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da,da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_df" "O8,O8")))))]
- + ""
- + "@
- + GETL\\t%0, %t0, [%1++%2]\\t%@ (*load DF pre_modify_disp OK)
- + F\\tGETL\\t%0, %t0, [%1++%2]\\t%@ (*load DF pre_modify_disp OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_df_pre_modify_reg"
- + [(set (match_operand:DF 0 "metag_register_op" "=da,da,da,da,cx,cx,cx,cx")
- + (mem:DF (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l, e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l, e, f, h, l")))))]
- + ""
- + "@
- + GETL\\t%0, %t0, [%1++%2]\\t%@ (*load DF pre_modify_reg OK)
- + GETL\\t%0, %t0, [%1++%2]\\t%@ (*load DF pre_modify_reg OK)
- + GETL\\t%0, %t0, [%1++%2]\\t%@ (*load DF pre_modify_reg OK)
- + GETL\\t%0, %t0, [%1++%2]\\t%@ (*load DF pre_modify_reg OK)
- + F\\tGETL\\t%0, %t0, [%1++%2]\\t%@ (*load DF pre_modify_reg OK)
- + F\\tGETL\\t%0, %t0, [%1++%2]\\t%@ (*load DF pre_modify_reg OK)
- + F\\tGETL\\t%0, %t0, [%1++%2]\\t%@ (*load DF pre_modify_reg OK)
- + F\\tGETL\\t%0, %t0, [%1++%2]\\t%@ (*load DF pre_modify_reg OK)"
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lod_df_concat"
- + [(set (unspec:DF [(match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:SI 1 "metag_reg_nofloat_op" "=da")] UNSPEC_CONCAT)
- + (match_operand:DF 2 "memory_operand" "m"))]
- + ""
- + "GETL\\t%0, %1, %2"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_df_off12"
- + [(set (match_operand:DF 0 "metag_reg_nofloat_op" "=da,da")
- + (mem:DF (plus:SI (match_operand:SI 1 "metag_reg12bit_op" "da,Yr")
- + (match_operand:SI 2 "metag_offset12_df" "O8,Z8"))))]
- + ""
- + "GETL\\t%0, %t0, [%1+%2]"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_df_off6"
- + [(set (match_operand:DF 0 "metag_register_op" "=da,cx")
- + (mem:DF (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da,da")
- + (match_operand:SI 2 "metag_offset6_df" "O8,O8"))))]
- + ""
- + "@
- + GETL\\t%0, %t0, [%1+%2]
- + F\\tGETL\\t%0, %t0, [%1+%2]"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_df"
- + [(set (match_operand:DF 0 "metag_register_op" "=cr")
- + (mem:DF (match_operand:SI 1 "metag_reg_nofloat_op" "da")))]
- + ""
- + {
- + static const char fmt[] = "F\\tGETL\\t%0, %t0, [%1]";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lod_df_mem"
- + [(set (match_operand:DF 0 "metag_reg_nofloat_op" "=da")
- + (match_operand:DF 1 "memory_operand" "m"))]
- + ""
- + "GETL\\t%0, %t0, %1\\t%@ (*lod df rm OK)"
- + [(set_attr "type" "load")])
- +
- +;; Memory bloc xfer insn
- +
- +(define_expand "movmemqi"
- + [(match_operand:BLK 0 "general_operand" "")
- + (match_operand:BLK 1 "general_operand" "")
- + (match_operand:SI 2 "const_int_operand" "")
- + (match_operand:SI 3 "const_int_operand" "")]
- + ""
- + {
- + if (metag_gen_movmemqi (operands))
- + DONE;
- + FAIL;
- + }
- +)
- +
- +;; Transfer instructions 64-bit and 32-bit
- +
- +;; loads DImode
- +
- +(define_insn "*ldmdi_7"
- + [(match_parallel 0 "load_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 56)))
- + (set (match_operand:DI 3 "metag_hard_datareg_op" "=d")
- + (mem:DI (match_dup 2)))
- + (set (match_operand:DI 4 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 8))))
- + (set (match_operand:DI 5 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 16))))
- + (set (match_operand:DI 6 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 24))))
- + (set (match_operand:DI 7 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 32))))
- + (set (match_operand:DI 8 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 40))))
- + (set (match_operand:DI 9 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 48))))])]
- + "XVECLEN (operands[0], 0) == 7 + 1"
- + "MGETL\\t%3, %4, %5, %6, %7, %8, %9, [%1++]\\t%@ (lodmr di OK)"
- + [(set_attr "type" "fivex")
- + (set_attr "memaccess" "load")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*ldmdi_6"
- + [(match_parallel 0 "load_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 48)))
- + (set (match_operand:DI 3 "metag_hard_datareg_op" "=d")
- + (mem:DI (match_dup 2)))
- + (set (match_operand:DI 4 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 8))))
- + (set (match_operand:DI 5 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 16))))
- + (set (match_operand:DI 6 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 24))))
- + (set (match_operand:DI 7 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 32))))
- + (set (match_operand:DI 8 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 40))))])]
- + "XVECLEN (operands[0], 0) == 6 + 1"
- + "MGETL\\t%3, %4, %5, %6, %7, %8, [%1++]\\t%@ (lodmr di OK)"
- + [(set_attr "type" "fivex")
- + (set_attr "memaccess" "load")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*ldmdi_5"
- + [(match_parallel 0 "load_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 40)))
- + (set (match_operand:DI 3 "metag_hard_datareg_op" "=d")
- + (mem:DI (match_dup 2)))
- + (set (match_operand:DI 4 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 8))))
- + (set (match_operand:DI 5 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 16))))
- + (set (match_operand:DI 6 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 24))))
- + (set (match_operand:DI 7 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 32))))])]
- + "XVECLEN (operands[0], 0) == 5 + 1"
- + "MGETL\\t%3, %4, %5, %6, %7, [%1++]\\t%@ (lodmr di OK)"
- + [(set_attr "type" "fivex")
- + (set_attr "memaccess" "load")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*ldmdi_4"
- + [(match_parallel 0 "load_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 32)))
- + (set (match_operand:DI 3 "metag_hard_datareg_op" "=d")
- + (mem:DI (match_dup 2)))
- + (set (match_operand:DI 4 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 8))))
- + (set (match_operand:DI 5 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 16))))
- + (set (match_operand:DI 6 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 24))))])]
- + "XVECLEN (operands[0], 0) == 4 + 1"
- + "MGETL\\t%3, %4, %5, %6, [%1++]\\t%@ (lodmr di OK)"
- + [(set_attr "type" "fourx")
- + (set_attr "memaccess" "load")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*ldmdi_3"
- + [(match_parallel 0 "load_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 24)))
- + (set (match_operand:DI 3 "metag_hard_datareg_op" "=d")
- + (mem:DI (match_dup 2)))
- + (set (match_operand:DI 4 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 8))))
- + (set (match_operand:DI 5 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 16))))])]
- + "XVECLEN (operands[0], 0) == 3 + 1"
- + "MGETL\\t%3, %4, %5, [%1++]\\t%@ (lodmr di OK)"
- + [(set_attr "type" "threex")
- + (set_attr "memaccess" "load")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*ldmdi_2"
- + [(match_parallel 0 "load_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 16)))
- + (set (match_operand:DI 3 "metag_hard_datareg_op" "=d")
- + (mem:DI (match_dup 2)))
- + (set (match_operand:DI 4 "metag_hard_datareg_op" "=d")
- + (mem:DI (plus:SI (match_dup 2)
- + (const_int 8))))])]
- + "XVECLEN (operands[0], 0) == 2 + 1"
- + "MGETL\\t%3, %4, [%1++]\\t%@ (lodmr di OK)"
- + [(set_attr "type" "twox")
- + (set_attr "memaccess" "load")
- + (set_attr "rename" "no")])
- +
- +;; Loads SImode
- +
- +(define_insn "*ldmsi_7"
- + [(match_parallel 0 "load_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 28)))
- + (set (match_operand:SI 3 "metag_hard_datareg_op" "=d")
- + (mem:SI (match_dup 2)))
- + (set (match_operand:SI 4 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 4))))
- + (set (match_operand:SI 5 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 8))))
- + (set (match_operand:SI 6 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 12))))
- + (set (match_operand:SI 7 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 16))))
- + (set (match_operand:SI 8 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 20))))
- + (set (match_operand:SI 9 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 24))))])]
- + "XVECLEN (operands[0], 0) == 7 + 1"
- + "MGETD\\t%3, %4, %5, %6, %7, %8, %9, [%1]\\t%@ (lodmr si OK)"
- + [(set_attr "type" "fivex")
- + (set_attr "memaccess" "load")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*ldmsi_6"
- + [(match_parallel 0 "load_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 24)))
- + (set (match_operand:SI 3 "metag_hard_datareg_op" "=d")
- + (mem:SI (match_dup 2)))
- + (set (match_operand:SI 4 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 4))))
- + (set (match_operand:SI 5 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 8))))
- + (set (match_operand:SI 6 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 12))))
- + (set (match_operand:SI 7 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 16))))
- + (set (match_operand:SI 8 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 20))))])]
- + "XVECLEN (operands[0], 0) == 6 + 1"
- + "MGETD\\t%3, %4, %5, %6, %7, [%1]\\t%@ (lodmr si OK)"
- + [(set_attr "type" "fivex")
- + (set_attr "memaccess" "load")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*ldmsi_5"
- + [(match_parallel 0 "load_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 20)))
- + (set (match_operand:SI 3 "metag_hard_datareg_op" "=d")
- + (mem:SI (match_dup 2)))
- + (set (match_operand:SI 4 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 4))))
- + (set (match_operand:SI 5 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 8))))
- + (set (match_operand:SI 6 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 12))))
- + (set (match_operand:SI 7 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 16))))])]
- + "XVECLEN (operands[0], 0) == 5 + 1"
- + "MGETD\\t%3, %4, %5, %6, %7, [%1]\\t%@ (lodmr si OK)"
- + [(set_attr "type" "fivex")
- + (set_attr "memaccess" "load")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*ldmsi_4"
- + [(match_parallel 0 "load_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 16)))
- + (set (match_operand:SI 3 "metag_hard_datareg_op" "=d")
- + (mem:SI (match_dup 2)))
- + (set (match_operand:SI 4 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 4))))
- + (set (match_operand:SI 5 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 8))))
- + (set (match_operand:SI 6 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 12))))])]
- + "XVECLEN (operands[0], 0) == 4 + 1"
- + "MGETD\\t%3, %4, %5, %6, [%1]\\t%@ (lodmr si OK)"
- + [(set_attr "type" "fourx")
- + (set_attr "memaccess" "load")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*ldmsi_3"
- + [(match_parallel 0 "load_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 12)))
- + (set (match_operand:SI 3 "metag_hard_datareg_op" "=d")
- + (mem:SI (match_dup 2)))
- + (set (match_operand:SI 4 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 4))))
- + (set (match_operand:SI 5 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 8))))])]
- + "XVECLEN (operands[0], 0) == 3 + 1"
- + "MGETD\\t%3, %4, %5, [%1]\\t%@ (lodmr si OK)"
- + [(set_attr "type" "threex")
- + (set_attr "memaccess" "load")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*ldmsi_2"
- + [(match_parallel 0 "load_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 8)))
- + (set (match_operand:SI 3 "metag_hard_datareg_op" "=d")
- + (mem:SI (match_dup 2)))
- + (set (match_operand:SI 4 "metag_hard_datareg_op" "=d")
- + (mem:SI (plus:SI (match_dup 2)
- + (const_int 4))))])]
- + "XVECLEN (operands[0], 0) == 2 + 1"
- + "MGETD\\t%3, %4, [%1]\\t%@ (lodmr si OK)"
- + [(set_attr "type" "twox")
- + (set_attr "memaccess" "load")
- + (set_attr "rename" "no")])
- +
- +;; stores DImode
- +(define_insn "*stmdi_8"
- + [(match_parallel 0 "store_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 64)))
- + (set (mem:DI (match_dup 2))
- + (match_operand:DI 3 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 8)))
- + (match_operand:DI 4 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 16)))
- + (match_operand:DI 5 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 24)))
- + (match_operand:DI 6 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 32)))
- + (match_operand:DI 7 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 40)))
- + (match_operand:DI 8 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 48)))
- + (match_operand:DI 9 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 56)))
- + (match_operand:DI 10 "metag_hard_datareg_op" "d"))])]
- + "XVECLEN (operands[0], 0) == 8 + 1"
- + "MSETL\\t[%1++], %3, %4, %5, %6, %7, %8, %9, %10\\t%@ (*stomr di OK)"
- + [(set_attr "type" "fivex")
- + (set_attr "memaccess" "store")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*stmdi_7"
- + [(match_parallel 0 "store_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 56)))
- + (set (mem:DI (match_dup 2))
- + (match_operand:DI 3 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 8)))
- + (match_operand:DI 4 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 16)))
- + (match_operand:DI 5 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 24)))
- + (match_operand:DI 6 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 32)))
- + (match_operand:DI 7 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 40)))
- + (match_operand:DI 8 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 48)))
- + (match_operand:DI 9 "metag_hard_datareg_op" "d"))])]
- + "XVECLEN (operands[0], 0) == 7 + 1"
- + "MSETL\\t[%1++], %3, %4, %5, %6, %7, %8, %9\\t%@ (*stomr di OK)"
- + [(set_attr "type" "fivex")
- + (set_attr "memaccess" "store")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*stmdi_6"
- + [(match_parallel 0 "store_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 48)))
- + (set (mem:DI (match_dup 2))
- + (match_operand:DI 3 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 8)))
- + (match_operand:DI 4 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 16)))
- + (match_operand:DI 5 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 24)))
- + (match_operand:DI 6 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 32)))
- + (match_operand:DI 7 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 40)))
- + (match_operand:DI 8 "metag_hard_datareg_op" "d"))])]
- + "XVECLEN (operands[0], 0) == 6 + 1"
- + "MSETL\\t[%1++], %3, %4, %5, %6, %7, %8\\t%@ (*stomr di OK)"
- + [(set_attr "type" "fivex")
- + (set_attr "memaccess" "store")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*stmdi_5"
- + [(match_parallel 0 "store_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 40)))
- + (set (mem:DI (match_dup 2))
- + (match_operand:DI 3 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 8)))
- + (match_operand:DI 4 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 16)))
- + (match_operand:DI 5 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 24)))
- + (match_operand:DI 6 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 32)))
- + (match_operand:DI 7 "metag_hard_datareg_op" "d"))])]
- + "XVECLEN (operands[0], 0) == 5 + 1"
- + "MSETL\\t[%1++], %3, %4, %5, %6, %7\\t%@ (*stomr di OK)"
- + [(set_attr "type" "fivex")
- + (set_attr "memaccess" "store")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*stmdi_4"
- + [(match_parallel 0 "store_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 32)))
- + (set (mem:DI (match_dup 2))
- + (match_operand:DI 3 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 8)))
- + (match_operand:DI 4 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 16)))
- + (match_operand:DI 5 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 24)))
- + (match_operand:DI 6 "metag_hard_datareg_op" "d"))])]
- + "XVECLEN (operands[0], 0) == 4 + 1"
- + "MSETL\\t[%1++], %3, %4, %5, %6\\t%@ (*stomr di OK)"
- + [(set_attr "type" "fourx")
- + (set_attr "memaccess" "store")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*stmdi_3"
- + [(match_parallel 0 "store_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 24)))
- + (set (mem:DI (match_dup 2))
- + (match_operand:DI 3 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 8)))
- + (match_operand:DI 4 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 16)))
- + (match_operand:DI 5 "metag_hard_datareg_op" "d"))])]
- + "XVECLEN (operands[0], 0) == 3 + 1"
- + "MSETL\\t[%1++], %3, %4, %5\\t%@ (*stomr di OK)"
- + [(set_attr "type" "threex")
- + (set_attr "memaccess" "store")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*stmdi_2"
- + [(match_parallel 0 "store_multiop"
- + [(set (match_operand:SI 1 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 2 "metag_reg_nofloat_op" "1")
- + (const_int 16)))
- + (set (mem:DI (match_dup 2))
- + (match_operand:DI 3 "metag_hard_datareg_op" "d"))
- + (set (mem:DI (plus:SI (match_dup 2)
- + (const_int 8)))
- + (match_operand:DI 4 "metag_hard_datareg_op" "d"))])]
- + "XVECLEN (operands[0], 0) == 2 + 1"
- + "MSETL\\t[%1++], %3, %4\\t%@ (*stomr di OK)"
- + [(set_attr "type" "twox")
- + (set_attr "memaccess" "store")
- + (set_attr "rename" "no")])
- +
- +;; Stores SImode
- +
- +(define_insn "*stmsi_5"
- + [(match_parallel 0 "store_multiop"
- + [(set (match_operand:SI 1 "metag_addrreg_op" "=a")
- + (plus:SI (match_operand:SI 2 "metag_addrreg_op" "1")
- + (const_int 20)))
- + (set (mem:SI (match_dup 2))
- + (match_operand:SI 3 "metag_hard_datareg_op" "d"))
- + (set (mem:SI (plus:SI (match_dup 2)
- + (const_int 4)))
- + (match_operand:SI 4 "metag_hard_datareg_op" "d"))
- + (set (mem:SI (plus:SI (match_dup 2)
- + (const_int 8)))
- + (match_operand:SI 5 "metag_hard_datareg_op" "d"))
- + (set (mem:SI (plus:SI (match_dup 2)
- + (const_int 12)))
- + (match_operand:SI 6 "metag_hard_datareg_op" "d"))
- + (set (mem:SI (plus:SI (match_dup 2)
- + (const_int 16)))
- + (match_operand:SI 7 "metag_hard_datareg_op" "d"))])]
- + "XVECLEN (operands[0], 0) == 5 + 1"
- + "MSETD\\t[%1], %3, %4, %5, %6, %7\\t%@ (*stomr si OK)"
- + [(set_attr "type" "fivex")
- + (set_attr "memaccess" "store")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*stmsi_4"
- + [(match_parallel 0 "store_multiop"
- + [(set (match_operand:SI 1 "metag_addrreg_op" "=a")
- + (plus:SI (match_operand:SI 2 "metag_addrreg_op" "1")
- + (const_int 16)))
- + (set (mem:SI (match_dup 2))
- + (match_operand:SI 3 "metag_hard_datareg_op" "d"))
- + (set (mem:SI (plus:SI (match_dup 2)
- + (const_int 4)))
- + (match_operand:SI 4 "metag_hard_datareg_op" "d"))
- + (set (mem:SI (plus:SI (match_dup 2)
- + (const_int 8)))
- + (match_operand:SI 5 "metag_hard_datareg_op" "d"))
- + (set (mem:SI (plus:SI (match_dup 2)
- + (const_int 12)))
- + (match_operand:SI 6 "metag_hard_datareg_op" "d"))])]
- + "XVECLEN (operands[0], 0) == 4 + 1"
- + "MSETD\\t[%1], %3, %4, %5, %6\\t%@ (*stomr si OK)"
- + [(set_attr "type" "fourx")
- + (set_attr "memaccess" "store")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*stmsi_3"
- + [(match_parallel 0 "store_multiop"
- + [(set (match_operand:SI 1 "metag_addrreg_op" "=a")
- + (plus:SI (match_operand:SI 2 "metag_addrreg_op" "1")
- + (const_int 12)))
- + (set (mem:SI (match_dup 2))
- + (match_operand:SI 3 "metag_hard_datareg_op" "d"))
- + (set (mem:SI (plus:SI (match_dup 2)
- + (const_int 4)))
- + (match_operand:SI 4 "metag_hard_datareg_op" "d"))
- + (set (mem:SI (plus:SI (match_dup 2)
- + (const_int 8)))
- + (match_operand:SI 5 "metag_hard_datareg_op" "d"))])]
- + "XVECLEN (operands[0], 0) == 3 + 1"
- + "MSETD\\t[%1], %3, %4, %5\\t%@ (*stomr si OK)"
- + [(set_attr "type" "threex")
- + (set_attr "memaccess" "store")
- + (set_attr "rename" "no")])
- +
- +(define_insn "*stmsi_2"
- + [(match_parallel 0 "store_multiop"
- + [(set (match_operand:SI 1 "metag_addrreg_op" "=a")
- + (plus:SI (match_operand:SI 2 "metag_addrreg_op" "1")
- + (const_int 8)))
- + (set (mem:SI (match_dup 2))
- + (match_operand:SI 3 "metag_hard_datareg_op" "d"))
- + (set (mem:SI (plus:SI (match_dup 2)
- + (const_int 4)))
- + (match_operand:SI 4 "metag_hard_datareg_op" "d"))])]
- + "XVECLEN (operands[0], 0) == 2 + 1"
- + "MSETD\\t[%1], %3, %4\\t%@ (*stomr si OK)"
- + [(set_attr "type" "twox")
- + (set_attr "memaccess" "store")
- + (set_attr "rename" "no")])
- +
- +;; add instructions
- +
- +;; Addition insns.
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; adddi3 ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "adddi3"
- + [(parallel
- + [(set (match_operand:DI 0 "metag_reg_nofloat_op" "")
- + (plus:DI (match_operand:DI 1 "metag_reg_nofloat_op" "")
- + (match_operand:DI 2 "metag_reg_nofloat_op" "")))
- + (clobber (reg:CC CC_REG))])]
- + ""
- + "")
- +
- +(define_insn "*adddi3_dsp"
- + [(set (match_operand:DI 0 "metag_datareg_op" "=d")
- + (plus:DI (match_operand:DI 1 "metag_datareg_op" "%d")
- + (match_operand:DI 2 "metag_datareg_op" "d")))
- + (clobber (reg:CC CC_REG))]
- + "TARGET_DSP"
- + "DL\\tADDS\\t%0, %1, %2\\t%@ (*ADD\\t%t0, %t1, %t2)\;ADDCS\\t%t0, %t0, #1"
- + [(set_attr "type" "two")
- + (set_attr "ccstate" "ccx")])
- +
- +(define_insn_and_split "*adddi3"
- + [(set (match_operand:DI 0 "metag_datareg_op" "=d")
- + (plus:DI (match_operand:DI 1 "metag_datareg_op" "%d")
- + (match_operand:DI 2 "metag_datareg_op" "d")))
- + (clobber (reg:CC CC_REG))]
- + ""
- + "#"
- + "SPLIT_EARLY"
- + [(parallel
- + [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (plus:SI (match_dup 5)
- + (match_dup 7))
- + (const_int 0)))
- + (set (match_dup 3)
- + (plus:SI (match_dup 5)
- + (match_dup 7)))])
- + (set (match_dup 4)
- + (plus:SI (match_dup 6)
- + (match_dup 8)))
- + (set (match_dup 4)
- + (if_then_else:SI (ltu (reg:CC_NOOV CC_REG)
- + (const_int 0))
- + (plus:SI (match_dup 4)
- + (const_int 1))
- + (match_dup 4)))]
- + {
- + if (reload_completed)
- + {
- + operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
- + operands[4] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- +
- + operands[5] = gen_rtx_REG (SImode, REGNO (operands[1]));
- + operands[6] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
- +
- + operands[7] = gen_rtx_REG (SImode, REGNO (operands[2]));
- + operands[8] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
- + }
- + else
- + {
- + operands[3] = gen_rtx_SUBREG (SImode, operands[0], 0);
- + operands[4] = gen_rtx_SUBREG (SImode, operands[0], UNITS_PER_WORD);
- +
- + operands[5] = gen_rtx_SUBREG (SImode, operands[1], 0);
- + operands[6] = gen_rtx_SUBREG (SImode, operands[1], UNITS_PER_WORD);
- +
- + operands[7] = gen_rtx_SUBREG (SImode, operands[2], 0);
- + operands[8] = gen_rtx_SUBREG (SImode, operands[2], UNITS_PER_WORD);
- + }
- + }
- + [(set_attr "type" "three")
- + (set_attr "ccstate" "ccx")])
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; addsi3 is made up of many parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "addsi3"
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_operand:SI 1 "metag_register_op" "")
- + (match_operand:SI 2 "metag_regorint_op" "")))]
- + ""
- + {
- + if (metag_frame_related_rtx (operands[2]))
- + {
- + /* Put the magic frame registers first */
- + rtx temp = operands[1];
- +
- + operands[1] = operands[2];
- + operands[2] = temp;
- + }
- +
- + if (!reload_completed
- + && !reload_in_progress
- + && metag_frame_related_rtx (operands[1]))
- + {
- + /* Ensure reg+reg adds do not combine regs that may be eliminated */
- + operands[1] = force_reg (SImode, operands[1]);
- + }
- + }
- +)
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; these are the addsi3 parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +
- +;; control register = datareg + smallint
- +(define_insn "*add_si_cdi"
- + [(set (match_operand:SI 0 "metag_txrpt_op" "=Wx,Wx")
- + (plus:SI (match_operand:SI 1 "metag_datareg_op" "%d, d")
- + (match_operand:SI 2 "metag_smallint_op" "K, P")))]
- + ""
- + "@
- + ADD\\t%0, %1, %2\\t%@ (*add si cdK OK)
- + SUB\\t%0, %1, #%n2\\t%@ (*add si cdP OK)"
- + [(set_attr "type" "slow,slow")])
- +
- +;; control register = reg +/- reg
- +(define_insn "*sub_si_crr"
- + [(set (match_operand:SI 0 "metag_txrpt_op" "=Wx,Wx,Wx,Wx")
- + (minus:SI (match_operand:SI 1 "metag_regnofrm_op" "e, f, h, l")
- + (match_operand:SI 2 "metag_regnofrm_op" "e, f, h, l")))]
- + ""
- + "SUB\\t%0, %1, %2\\t%@ (*sub si crr OK)"
- + [(set_attr "type" "slow,slow,slow,slow")])
- +
- +(define_insn "*add_si_crr"
- + [(set (match_operand:SI 0 "metag_txrpt_op" "=Wx,Wx,Wx,Wx")
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "%e, f, h, l")
- + (match_operand:SI 2 "metag_regnofrm_op" "e, f, h, l")))]
- + ""
- + "ADD\\t%0, %1, %2\\t%@ (*add si crr OK)"
- + [(set_attr "type" "slow,slow,slow,slow")])
- +
- +;; register + register ops - generic case
- +(define_insn "*add_si_rrr"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,f,h,l,da,da,da,da")
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "%e,f,h,l,e, f, h, l")
- + (match_operand:SI 2 "metag_regnofrm_op" "e,f,h,l,e, f, h, l")))]
- + "!TARGET_METAC_1_1"
- + "ADD%?\\t%0, %1, %2"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes,yes,yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; register + register ops - v1.1 case
- +(define_insn "*add_si_rrb_1_1"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e, f, h, l, da,da,da,da")
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "%e, f, h, l, e, f, h, l")
- + (match_operand:SI 2 "metag_regnofrm_op" "be,bf,bh,bl,be,bf,bh,bl")))]
- + "TARGET_METAC_1_1 && !TARGET_MINIM_CORE"
- + "ADD%?\\t%0, %1, %2"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes,yes,yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*add_si_rrb_1_1_if_<mode>"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e, f, h, l, da,da,da,da")
- + (if_then_else:SI (match_operator 1 "comparison_operator"
- + [(match_operand:CCALL 2 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (plus:SI (match_operand:SI 3 "metag_regnofrm_op" "%e, f, h, l, e, f, h, l")
- + (match_operand:SI 4 "metag_regnofrm_op" "be,bf,bh,bl,be,bf,bh,bl"))
- + (match_operand:SI 5 "metag_reg_nofloat_op" "0, 0, 0, 0, 0, 0, 0, 0")))]
- + "TARGET_METAC_1_1 && !TARGET_MINIM_CORE"
- + "ADD%z1\\t%0, %3, %4"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "ccstate" "xcc")])
- +
- +;; register + register ops - minim case
- +(define_insn "*add_si_rrb_minim"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,!e, f,!f, h,!h, l,!l, da,!da,da,!da,da,!da,da,!da")
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "%e, e, f, f, h, h, l, l, e, e, f, f, h, h, l, l")
- + (match_operand:SI 2 "metag_regnofrm_op" "e, be,f, bf,h, bh,l, bl,e, be,f, bf,h, bh,l, bl")))]
- + "TARGET_METAC_1_1 && TARGET_MINIM_CORE"
- + "ADD%?\\t%0, %1, %2"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,fast,fast,slow,slow,slow,slow,slow,slow,slow,slow")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "*add_si_rrb_minim_if_<mode>"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,!e, f,!f, h,!h, l,!l, da,!da,da,!da,da,!da,da,!da")
- + (if_then_else:SI (match_operator 1 "comparison_operator"
- + [(match_operand:CCALL 2 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (plus:SI (match_operand:SI 3 "metag_regnofrm_op" "%e, e, f, f, h, h, l, l, e, e, f, f, h, h, l, l")
- + (match_operand:SI 4 "metag_regnofrm_op" "e, be,f, bf,h, bh,l, bl,e, be,f, bf,h, bh,l, bl"))
- + (match_operand:SI 5 "metag_reg_nofloat_op" "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0")))]
- + "TARGET_METAC_1_1 && TARGET_MINIM_CORE"
- + "ADD%z1\\t%0, %3, %4"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,fast,fast,slow,slow,slow,slow,slow,slow,slow,slow")
- + (set_attr "ccstate" "xcc")])
- +
- +;; Seperate stack frame related register+register adds
- +(define_insn "*add_si_index_frame"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=h,da,!da")
- + (plus:SI (match_operand:SI 1 "metag_regframe_op" "%h,h, h")
- + (match_operand:SI 2 "metag_regnofrm_op" "h,h, bh")))]
- + "!TARGET_METAC_1_1"
- + "ADD%?\\t%0, %1, %2\\t%@ (*add si rfrmh OK)"
- + [(set_attr "type" "fast,slow,three")
- + (set_attr "cond" "yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; Sadly instantiate_virtual_regs can be really dumb some times
- +(define_insn "*add_si_index_frame2"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=h,da,!da")
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "%h,h, h")
- + (match_operand:SI 2 "metag_regframe_op" "h,h, bh")))]
- + "!TARGET_METAC_1_1"
- + "ADD%?\\t%0, %1, %2\\t%@ (*add si rhfrm OK)"
- + [(set_attr "type" "fast,slow,three")
- + (set_attr "cond" "yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; Seperate stack frame related register+register adds - v1.1 case
- +(define_insn "*add_si_index_frame_1_1"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=h, da")
- + (plus:SI (match_operand:SI 1 "metag_regframe_op" "%h, h")
- + (match_operand:SI 2 "metag_regnofrm_op" "bh,bh")))]
- + "TARGET_METAC_1_1 && !TARGET_MINIM_CORE"
- + "ADD%?\\t%0, %1, %2\\t%@ (*add si rfrmb OK)"
- + [(set_attr "type" "fast,slow")
- + (set_attr "cond" "yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; Seperate stack frame related register+register adds - minim case
- +(define_insn "*add_si_index_frame_minim"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=h,!h, da,!da")
- + (plus:SI (match_operand:SI 1 "metag_regframe_op" "%h, h, h, h")
- + (match_operand:SI 2 "metag_regnofrm_op" "h, bh,h, bh")))]
- + "TARGET_METAC_1_1 && TARGET_MINIM_CORE"
- + "ADD%?\\t%0, %1, %2\\t%@ (*add si rfrmb OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +;; Sadly instantiate_virtual_regs can be really dumb some times - v1.1 case
- +(define_insn "*add_si_index_frame2_1_1"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=h, da")
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "%h, h")
- + (match_operand:SI 2 "metag_regframe_op" "bh,bh")))]
- + "TARGET_METAC_1_1 && !TARGET_MINIM_CORE"
- + "ADD%?\\t%0, %1, %2\\t%@ (*add si rbfrm OK)"
- + [(set_attr "type" "fast,slow")
- + (set_attr "cond" "yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; Sadly instantiate_virtual_regs can be really dumb some times - minim case
- +(define_insn "*add_si_index_frame2_minim"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=h,!h, da,!da")
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "%h, h, h, h")
- + (match_operand:SI 2 "metag_regframe_op" "h, bh,h, bh")))]
- + "TARGET_METAC_1_1 && TARGET_MINIM_CORE"
- + "ADD%?\\t%0, %1, %2\\t%@ (*add si rbfrm OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +;; spill_frame - cannot really add frame value to something else
- +(define_split
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (plus:SI (match_operand:SI 1 "metag_regframe_op" "")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "")))]
- + "!TARGET_METAC_1_1
- + && reload_completed
- + && METAG_REGNO_REG_CLASS (REGNO (operands[2])) != A0_REGS"
- + [(set (match_dup 3)
- + (match_dup 2))
- + (set (match_dup 0)
- + (plus:SI (match_dup 1)
- + (match_dup 3)))]
- + {
- + gcc_assert (A0_SCRATCH != INVALID_REGNUM && fixed_regs[A0_SCRATCH]);
- + operands[3] = gen_rtx_REG (SImode, A0_SCRATCH);
- + }
- +)
- +
- +(define_split
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "")
- + (match_operand:SI 2 "metag_regframe_op" "")))]
- + "!TARGET_METAC_1_1
- + && reload_completed
- + && METAG_REGNO_REG_CLASS (REGNO (operands[1])) != A0_REGS"
- + [(set (match_dup 3)
- + (match_dup 1))
- + (set (match_dup 0)
- + (plus:SI (match_dup 3)
- + (match_dup 2)))]
- + {
- + gcc_assert (A0_SCRATCH != INVALID_REGNUM && fixed_regs[A0_SCRATCH]);
- + operands[3] = gen_rtx_REG (SImode, A0_SCRATCH);
- + }
- +)
- +
- +;; register + immediate ops
- +(define_insn "*add_si_rri"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,e,f,f,h,h,l,l,da,da,da,da,da,da,da,da")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e,e,f,f,h,h,l,l,d, d, a, a, 0, 0, 0, 0")
- + (match_operand:SI 2 "const_int_operand" "K,P,K,P,K,P,K,P,K, P, K, P, I, J, O3,i")))]
- + "!TARGET_MINIM_CORE"
- + "@
- + ADD%?\\t%0, %1, %2\\t\\t%@ (*add si eeK OK)
- + SUB%?\\t%0, %1, #%n2\\t\\t%@ (*add si eeP)
- + ADD%?\\t%0, %1, %2\\t\\t%@ (*add si ffK OK)
- + SUB%?\\t%0, %1, #%n2\\t\\t%@ (*add si ffP)
- + ADD%?\\t%0, %1, %2\\t\\t%@ (*add si hhK OK)
- + SUB%?\\t%0, %1, #%n2\\t\\t%@ (*add si hhP OK)
- + ADD%?\\t%0, %1, %2\\t\\t%@ (*add si llK OK)
- + SUB%?\\t%0, %1, #%n2\\t\\t%@ (*add si llP OK)
- + ADD\\t%0, %1, %2\\t\\t%@ (*add si rdK OK)
- + SUB\\t%0, %1, #%n2\\t\\t%@ (*add si rdP OK)
- + ADD\\t%0, %1, %2\\t\\t%@ (*add si daaK OK)
- + SUB\\t%0, %1, #%n2\\t\\t%@ (*add si daaP OK)
- + ADD\\t%0, %1, %2\\t%@ (*add si da0I OK)
- + ADDT\\t%0, %1, #HI(%c2)\\t%@ (*add si da0J OK)
- + ADDT\\t%0, %1, #LO(%c2)\\t%@ (*add si da03 OK)
- + #"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,fast,fast,slow,slow,slow,slow,fast,fast,fast,two")
- + (set_attr "cond" "yes,yes,yes,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,no")])
- +
- +;; register + immediate ops
- +(define_insn "*add_si_rri"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da,da,!e,!e,!f,!f,!h,!h,!l,!l,da,da,da,da,da,da,da,da")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%0, 0, e, e, f, f, h, h, l, l,d, d, a, a, 0, 0, 0, 0")
- + (match_operand:SI 2 "const_int_operand" "K, P, K, P, K, P, K, P, K, P,K, P, K, P, I, J, O3,i")))]
- + "TARGET_MINIM_CORE"
- + "@
- + ADD%?\\t%0, %1, %2\\t\\t%@ (*add si r0K OK)
- + SUB%?\\t%0, %1, #%n2\\t\\t%@ (*add si r0P)
- + ADD%?\\t%0, %1, %2\\t\\t%@ (*add si eeK OK)
- + SUB%?\\t%0, %1, #%n2\\t\\t%@ (*add si eeP)
- + ADD%?\\t%0, %1, %2\\t\\t%@ (*add si ffK OK)
- + SUB%?\\t%0, %1, #%n2\\t\\t%@ (*add si ffP)
- + ADD%?\\t%0, %1, %2\\t\\t%@ (*add si hhK OK)
- + SUB%?\\t%0, %1, #%n2\\t\\t%@ (*add si hhP OK)
- + ADD%?\\t%0, %1, %2\\t\\t%@ (*add si llK OK)
- + SUB%?\\t%0, %1, #%n2\\t\\t%@ (*add si llP OK)
- + ADD\\t%0, %1, %2\\t\\t%@ (*add si rdK OK)
- + SUB\\t%0, %1, #%n2\\t\\t%@ (*add si rdP OK)
- + ADD\\t%0, %1, %2\\t\\t%@ (*add si daaK OK)
- + SUB\\t%0, %1, #%n2\\t\\t%@ (*add si daaP OK)
- + ADD\\t%0, %1, %2\\t%@ (*add si da0I OK)
- + ADDT\\t%0, %1, #HI(%c2)\\t%@ (*add si da0J OK)
- + ADDT\\t%0, %1, #LO(%c2)\\t%@ (*add si da03 OK)
- + #"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,fast,fast,fast,fast,slow,slow,slow,slow,fast,fast,fast,two")
- + (set_attr "cond" "yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,no")])
- +
- +;; Split the above add_si_rri if it needs more than one insn
- +(define_split
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "")
- + (match_operand:SI 2 "const_int_operand" "")))]
- + "reload_completed
- + && REGNO (operands[0]) == REGNO (operands[1]) && !METAG_CONST_OK_FOR_LETTERS_KPIJO3 (operands[2])"
- + [(set (match_dup 0)
- + (plus:SI (match_dup 1)
- + (match_dup 3)))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_dup 4)))]
- + {
- + HOST_WIDE_INT value = INTVAL (operands[2]);
- + HOST_WIDE_INT ival;
- +
- + ival = trunc_int_for_mode (value & 0xFFFF0000, SImode);
- + operands[3] = GEN_INT (ival);
- +
- + ival = trunc_int_for_mode (value & 0x0000FFFF, SImode);
- + operands[4] = GEN_INT (ival);
- + }
- +)
- +
- +;; conditional version for specific cases of add_si_rri
- +(define_insn "*cond_<mode>_add_si_rri"
- + [(cond_exec
- + (match_operator 3 "comparison_operator"
- + [(match_operand:CCALL 4 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (set (match_operand:SI 0 "metag_hard_genreg_op" "=e,e,f,f,h,h,l,l")
- + (plus:SI (match_operand:SI 1 "metag_hard_genreg_op" "%e,e,f,f,h,h,l,l")
- + (match_operand:SI 2 "metag_KP_operand" "K,P,K,P,K,P,K,P"))))]
- + "reload_completed
- + && metag_same_regclass_p (operands[0], operands[1])"
- + "@
- + ADD%?\\t%0, %1, %2\\t\\t%@ (*add si eeK OK)
- + SUB%?\\t%0, %1, #%n2\\t\\t%@ (*add si eeP)
- + ADD%?\\t%0, %1, %2\\t\\t%@ (*add si ffK OK)
- + SUB%?\\t%0, %1, #%n2\\t\\t%@ (*add si ffP)
- + ADD%?\\t%0, %1, %2\\t\\t%@ (*add si hhK OK)
- + SUB%?\\t%0, %1, #%n2\\t\\t%@ (*add si hhP OK)
- + ADD%?\\t%0, %1, %2\\t\\t%@ (*add si llK OK)
- + SUB%?\\t%0, %1, #%n2\\t\\t%@ (*add si llP OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,fast,fast")
- + (set_attr "cond" "no")])
- +
- +(define_insn_and_split"*adds_si_neg_<mode>_rr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (match_operand:SI 1 "metag_datareg_op" "e, f, e, f")
- + (neg:SI (match_operand:SI 2 "metag_reg_nofloat_op" "be,bf,be,bf"))))
- + (clobber (match_scratch:SI 0 "=e, f, r, r"))]
- + "TARGET_METAC_1_1"
- + "#"
- + "&& reload_completed"
- + [(parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (plus:SI (match_dup 1)
- + (match_dup 2))
- + (const_int 0)))
- + (set (match_dup 0)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))])]
- + ""
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +;; register + register|immediate ops that set the flags
- +(define_insn "*adds_<mode>_si_rrr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "%e,f,e,f")
- + (match_operand:SI 2 "metag_regnofrm_op" "e,f,e,f"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=e,f,r,r")
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "!TARGET_METAC_1_1"
- + "ADDS\\t%0, %1, %2\\t%@ (*adds si rrr OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")])
- +
- +;; register + register|immediate ops that set the flags - v1.1 case
- +(define_insn "*adds_<mode>_si_rrr_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "%e, f, e, f")
- + (match_operand:SI 2 "metag_regnofrm_op" "be,bf,be,bf"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=e, f, r, r")
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1"
- + "ADDS\\t%0, %1, %2\\t%@ (*adds si rrr OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")])
- +
- +(define_insn_and_split "*adds_si_r_<mode>_symglobal_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (match_operand:SI 1 "metag_symglobal_op" "")
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "=d")
- + (match_dup 1))]
- + "TARGET_METAC_1_1"
- + "#"
- + "&& reload_completed"
- + [(set (match_dup 0)
- + (high:SI (match_dup 1)))
- + (parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1))
- + (const_int 0)))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1)))])]
- + ""
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_insn "*adds_<mode>_si_txrpt_ri"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (plus:SI (match_operand:SI 1 "metag_datareg_op" "%d, d")
- + (match_operand:SI 2 "metag_smallint_op" "K, P"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_txrpt_op" "=Wx,Wx")
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "reload_completed"
- + "@
- + ADDS\\t%0, %1, #%2
- + SUBS\\t%0, %1, #%n2"
- + [(set_attr "type" "fast,fast")
- + (set_attr "ccstate" "set,set")])
- +
- +(define_insn "*adds_<mode>_si_rri"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e,e,f,f,d,d,0,0,0, 0")
- + (match_operand:SI 2 "const_int_operand" "K,P,K,P,K,P,I,J,O3,i"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=e,e,f,f,r,r,d,d,d, d")
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + ""
- + "@
- + ADDS\\t%0, %1, %2\\t\\t%@ (*adds si eeK OK)
- + SUBS\\t%0, %1, #%n2\\t\\t%@ (*adds si eeP OK)
- + ADDS\\t%0, %1, %2\\t\\t%@ (*adds si ffK OK)
- + SUBS\\t%0, %1, #%n2\\t\\t%@ (*adds si ffP OK)
- + ADDS\\t%0, %1, %2\\t\\t%@ (*adds si rdK OK)
- + SUBS\\t%0, %1, #%n2\\t\\t%@ (*adds si rdP OK)
- + ADDS\\t%0, %1, %2\\t%@ (*adds si d0I OK)
- + ADDST\\t%0, %1, #HI(%c2)\\t%@ (*adds si d0J OK)
- + ADDS\\t%0, %1, #LO(%c2)\\t%@ (*adds si d0O3 OK)
- + #"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,fast,fast,fast,two")
- + (set_attr "ccstate" "set,set,set,set,set,set,set,set,set,fastset")])
- +
- +;; Split the above insn if it needs more than one insn
- +(define_split
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "")
- + (match_operand:SI 2 "const_int_operand" ""))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "reload_completed
- + && REGNO (operands[0]) == REGNO (operands[1]) && !METAG_CONST_OK_FOR_LETTERS_KPIJO3 (operands[2])"
- + [(set (match_dup 0)
- + (plus:SI (match_dup 1)
- + (match_dup 3)))
- + (parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (plus:SI (match_dup 0)
- + (match_dup 4))
- + (const_int 0)))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_dup 4)))])]
- + {
- + HOST_WIDE_INT value = INTVAL (operands[2]);
- + HOST_WIDE_INT ival;
- +
- + ival = trunc_int_for_mode (value & 0xFFFF0000, SImode);
- + operands[3] = GEN_INT (ival);
- +
- + ival = trunc_int_for_mode (value & 0x0000FFFF, SImode);
- + operands[4] = GEN_INT (ival);
- + }
- +)
- +
- +;; register + register|immediate ops that set the flags using a scratch
- +(define_insn "*tadds_<mode>_si_rrr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "%e,f,e,f")
- + (match_operand:SI 2 "metag_regnofrm_op" "e,f,e,f"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=e,f,r,r"))]
- + "!TARGET_METAC_1_1"
- + "ADDS\\t%0, %1, %2\\t%@ (*tadd si rrr OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")])
- +
- +;; register + register|immediate ops that set the flags using a scratch - v1.1
- +(define_insn "*tadds_<mode>_si_rrr_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "%e, f, e, f")
- + (match_operand:SI 2 "metag_regnofrm_op" "be,bf,be,bf"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=e, f, r, r"))]
- + "TARGET_METAC_1_1"
- + "ADDS\\t%0, %1, %2\\t%@ (*tadd si rrb OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")])
- +
- +(define_insn "*tadds_rr_cc_noov_address_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (lo_sum:SI (match_operand:SI 1 "metag_datareg_op" "0")
- + (match_operand:SI 2 "code_address" ""))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "=d")
- + (lo_sum:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1"
- + "ADDS\\t%0, %1, #LO(%c2)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_insn_and_split "*tadds_si_cc_noov_address"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (match_operand:SI 1 "code_address" "")
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=d"))]
- + "TARGET_METAC_1_1 && 1"
- + "#"
- + "&& reload_completed"
- + [(set (match_dup 0)
- + (high:SI (match_dup 1)))
- + (parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1))
- + (const_int 0)))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1)))])]
- + ""
- + [(set_attr "type" "two")
- + (set_attr "ccstate" "set")])
- +
- +(define_insn "*tadds_rr_<mode>_symglobal_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (lo_sum:SI (match_operand:SI 1 "metag_datareg_op" "0")
- + (match_operand:SI 2 "metag_symglobal_op" ""))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "=d")
- + (lo_sum:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1"
- + "ADDS\\t%0, %1, #LO(%c2)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_insn_and_split "*tadds_<mode>_si_symglobal_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (match_operand:SI 1 "metag_symglobal_op" "")
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=d"))]
- + "TARGET_METAC_1_1 && 0"
- + "#"
- + "&& reload_completed"
- + [(set (match_dup 0)
- + (high:SI (match_dup 1)))
- + (parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1))
- + (const_int 0)))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1)))])]
- + ""
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_insn "*tadds_si_cc_rri"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e,e,f,f,d,d,0,0,0, 0")
- + (match_operand:SI 2 "const_int_operand" "K,P,K,P,K,P,I,J,O3,i"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=e,e,f,f,r,r,d,d,d, d"))]
- + ""
- + "@
- + ADDS\\t%0, %1, %2\\t\\t%@ (*tadd si eeK OK)
- + SUBS\\t%0, %1, #%n2\\t\\t%@ (*tadd si eeP OK)
- + ADDS\\t%0, %1, %2\\t\\t%@ (*tadd si ffK OK)
- + SUBS\\t%0, %1, #%n2\\t\\t%@ (*tadd si ffP OK)
- + ADDS\\t%0, %1, %2\\t\\t%@ (*tadd si rdK OK)
- + SUBS\\t%0, %1, #%n2\\t\\t%@ (*tadd si rdP OK)
- + ADDS\\t%0, %1, %2\\t%@ (*tadd si d0I OK)
- + ADDST\\t%0, %1, #HI(%c2)\\t%@ (*tadd si d0J OK)
- + ADDS\\t%0, %1, #LO(%c2)\\t%@ (*tadd si d0O3 OK)
- + #"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,fast,fast,fast,two")
- + (set_attr "ccstate" "set,set,set,set,set,set,set,set,set,fastset")])
- +
- +;; Split the above insn if it needs more that one insn.
- +(define_split
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "")
- + (match_operand:SI 2 "const_int_operand" ""))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 ""))]
- + "reload_completed
- + && REGNO (operands[0]) == REGNO (operands[1]) && !METAG_CONST_OK_FOR_LETTERS_KPIJO3 (operands[2])"
- + [(set (match_dup 0)
- + (plus:SI (match_dup 1)
- + (match_dup 3)))
- + (parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (plus:SI (match_dup 0)
- + (match_dup 4))
- + (const_int 0)))
- + (clobber (match_dup 0))])]
- + {
- + HOST_WIDE_INT value = INTVAL (operands[2]);
- + HOST_WIDE_INT ival;
- +
- + ival = trunc_int_for_mode (value & 0xFFFF0000, SImode);
- + operands[3] = GEN_INT (ival);
- +
- + ival = trunc_int_for_mode (value & 0x0000FFFF, SImode);
- + operands[4] = GEN_INT (ival);
- + }
- +)
- +
- +;; subtract instructions
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; subdi3 expander ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "subdi3"
- + [(parallel
- + [(set (match_operand:DI 0 "metag_reg_nofloat_op" "")
- + (minus:DI (match_operand:DI 1 "metag_reg_nofloat_op" "")
- + (match_operand:DI 2 "metag_reg_nofloat_op" "")))
- + (clobber (reg:CC CC_REG))])]
- + ""
- + "")
- +
- +(define_insn "*subdi3_dsp"
- + [(set (match_operand:DI 0 "metag_datareg_op" "=d")
- + (minus:DI (match_operand:DI 1 "metag_datareg_op" "d")
- + (match_operand:DI 2 "metag_datareg_op" "d")))
- + (clobber (reg:CC CC_REG))]
- + "TARGET_DSP"
- + "DL\\tSUBS\\t%0, %1, %2\\t%@ (*SUB\\t%t0, %t1, %t2)\;SUBCS\\t%t0, %t0, #1"
- + [(set_attr "type" "two")
- + (set_attr "ccstate" "ccx")])
- +
- +(define_insn_and_split "*subdi3"
- + [(set (match_operand:DI 0 "metag_datareg_op" "=d")
- + (minus:DI (match_operand:DI 1 "metag_datareg_op" "d")
- + (match_operand:DI 2 "metag_datareg_op" "d")))
- + (clobber (reg:CC CC_REG))]
- + ""
- + "#"
- + "SPLIT_EARLY"
- + [(parallel
- + [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (minus:SI (match_dup 5)
- + (match_dup 7))
- + (const_int 0)))
- + (set (match_dup 3)
- + (minus:SI (match_dup 5)
- + (match_dup 7)))])
- + (set (match_dup 4)
- + (minus:SI (match_dup 6)
- + (match_dup 8)))
- + (set (match_dup 4)
- + (if_then_else:SI (ltu (reg:CC_NOOV CC_REG)
- + (const_int 0))
- + (plus:SI (match_dup 4)
- + (const_int -1))
- + (match_dup 4)))]
- + {
- + if (reload_completed)
- + {
- + operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
- + operands[4] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- +
- + operands[5] = gen_rtx_REG (SImode, REGNO (operands[1]));
- + operands[6] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
- +
- + operands[7] = gen_rtx_REG (SImode, REGNO (operands[2]));
- + operands[8] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
- + }
- + else
- + {
- + operands[3] = gen_rtx_SUBREG (SImode, operands[0], 0);
- + operands[4] = gen_rtx_SUBREG (SImode, operands[0], UNITS_PER_WORD);
- +
- + operands[5] = gen_rtx_SUBREG (SImode, operands[1], 0);
- + operands[6] = gen_rtx_SUBREG (SImode, operands[1], UNITS_PER_WORD);
- +
- + operands[7] = gen_rtx_SUBREG (SImode, operands[2], 0);
- + operands[8] = gen_rtx_SUBREG (SImode, operands[2], UNITS_PER_WORD);
- + }
- + }
- + [(set_attr "type" "three")
- + (set_attr "ccstate" "ccx")])
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; subsi3 is made up of many parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "subsi3"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (minus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "")))]
- + ""
- + {
- + if (!reload_completed
- + && !reload_in_progress
- + && REG_P (operands[2]))
- + {
- + if (metag_frame_related_rtx (operands[1]))
- + {
- + /* Ensure reg-reg adds do not combine regs that may be eliminated */
- + rtx reg = gen_reg_rtx (SImode);
- +
- + emit_move_insn (reg, operands[1]);
- + operands[1] = force_reg (SImode, reg);
- + }
- + else if (metag_frame_related_rtx (operands[2]))
- + {
- + /* Ensure reg-reg adds do not combine regs that may be eliminated */
- + rtx reg = gen_reg_rtx (SImode);
- +
- + emit_move_insn (reg, operands[2]);
- + operands[2] = force_reg (SImode, reg);
- + }
- + }
- + }
- +)
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; and these are the subsi3 parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +
- +;; register - register ops
- +(define_insn "*sub_si_rrr"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,f,h,l,da,da,da,da")
- + (minus:SI (match_operand:SI 1 "metag_regnofrm_op" "e,f,h,l,e, f, h, l")
- + (match_operand:SI 2 "metag_regnofrm_op" "e,f,h,l,e, f, h, l")))]
- + "!TARGET_METAC_1_1"
- + "SUB%?\\t%0, %1, %2\\t%@ (*sub si rrr OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes,yes,yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; register - register ops - v1.1 case
- +(define_insn "*sub_si_rrr_1_1"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e, f, h, l, da,da,da,da")
- + (minus:SI (match_operand:SI 1 "metag_regnofrm_op" "e, f, h, l, e, f, h, l")
- + (match_operand:SI 2 "metag_regnofrm_op" "be,bf,bh,bl,be,bf,bh,bl")))]
- + "TARGET_METAC_1_1 && !TARGET_MINIM_CORE"
- + "SUB%?\\t%0, %1, %2\\t%@ (*sub si rrb OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes,yes,yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; register - register ops - minim case
- +(define_insn "*sub_si_rrr_minim"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,!e, f,!f, h,!h, l,!l, da,!da, da,!da, da,!da, da,!da")
- + (minus:SI (match_operand:SI 1 "metag_regnofrm_op" "e, e, f, f, h, h, l, l, e, e, f, f, h, h, l, l")
- + (match_operand:SI 2 "metag_regnofrm_op" "e, be,f, bf,h, bh,l, bl,e, be, f, bf, h, bh, l, bl")))]
- + "TARGET_METAC_1_1 && TARGET_MINIM_CORE"
- + "SUB%?\\t%0, %1, %2\\t%@ (*sub si rrb OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,fast,fast,slow,slow,slow,slow,slow,slow,slow,slow")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +;; Seperate stack frame related register-register subs
- +(define_insn "*sub_si_index_frame"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=h,da,!da")
- + (minus:SI (match_operand:SI 1 "metag_regframe_op" "h,h, h")
- + (match_operand:SI 2 "metag_regnofrm_op" "h,h, bh")))]
- + "!TARGET_METAC_1_1"
- + "SUB%?\\t%0, %1, %2\\t%@ (*sub si rfrmh OK)"
- + [(set_attr "type" "fast,slow,three")
- + (set_attr "cond" "yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; Subs are not commutative so second case required
- +(define_insn "*sub_si_index_frame2"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=h,da,!da")
- + (minus:SI (match_operand:SI 1 "metag_regnofrm_op" "h,h, h")
- + (match_operand:SI 2 "metag_regframe_op" "h,h, bh")))]
- + "!TARGET_METAC_1_1"
- + "SUB%?\\t%0, %1, %2\\t%@ (*sub si rhfrm OK)"
- + [(set_attr "type" "fast,slow,three")
- + (set_attr "cond" "yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; Seperate stack frame related register-register subs - v1.1 case
- +(define_insn "*sub_si_index_frame_1_1"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=h, da")
- + (minus:SI (match_operand:SI 1 "metag_regframe_op" "h, h")
- + (match_operand:SI 2 "metag_regnofrm_op" "bh,bh")))]
- + "TARGET_METAC_1_1 && !TARGET_MINIM_CORE"
- + "SUB%?\\t%0, %1, %2\\t%@ (*sub si rfrmb OK)"
- + [(set_attr "type" "fast,slow")
- + (set_attr "cond" "yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; Seperate stack frame related register-register subs - minim case
- +(define_insn "*sub_si_index_frame_minim"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=h,!h, da,!da")
- + (minus:SI (match_operand:SI 1 "metag_regframe_op" "h, h, h, h")
- + (match_operand:SI 2 "metag_regnofrm_op" "h, bh,h, bh")))]
- + "TARGET_METAC_1_1 && TARGET_MINIM_CORE"
- + "SUB%?\\t%0, %1, %2\\t%@ (*sub si rfrmb OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +;; Subs are not commutative so second case required - v1.1 case
- +(define_insn "*sub_si_index_frame2_1_1"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=h, da")
- + (minus:SI (match_operand:SI 1 "metag_regnofrm_op" "h, h")
- + (match_operand:SI 2 "metag_regframe_op" "bh,bh")))]
- + "TARGET_METAC_1_1 && !TARGET_MINIM_CORE"
- + "SUB%?\\t%0, %1, %2\\t%@ (*sub si rbfrm OK)"
- + [(set_attr "type" "fast,slow")
- + (set_attr "cond" "yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; Subs are not commutative so second case required - minim case
- +(define_insn "*sub_si_index_frame2_minim"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=h,!h, da,!da")
- + (minus:SI (match_operand:SI 1 "metag_regnofrm_op" "h, h, h, h")
- + (match_operand:SI 2 "metag_regframe_op" "h, bh,h, bh")))]
- + "TARGET_METAC_1_1 && TARGET_MINIM_CORE"
- + "SUB%?\\t%0, %1, %2\\t%@ (*sub si rbfrm OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +;; spill_frame - cannot really sub frame value to something else
- +(define_split
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (minus:SI (match_operand:SI 1 "metag_regframe_op" "")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "")))]
- + "!TARGET_METAC_1_1
- + && reload_completed
- + && METAG_REGNO_REG_CLASS (REGNO (operands[2])) != A0_REGS"
- + [(set (match_dup 3)
- + (match_dup 2))
- + (set (match_dup 0)
- + (minus:SI (match_dup 1)
- + (match_dup 3)))]
- + {
- + gcc_assert (A0_SCRATCH != INVALID_REGNUM && fixed_regs[A0_SCRATCH]);
- + operands[3] = gen_rtx_REG (SImode, A0_SCRATCH);
- + }
- +)
- +
- +(define_split
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (minus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "")
- + (match_operand:SI 2 "metag_regframe_op" "")))]
- + "!TARGET_METAC_1_1
- + && reload_completed
- + && METAG_REGNO_REG_CLASS (REGNO (operands[1])) != A0_REGS"
- + [(set (match_dup 3)
- + (match_dup 1))
- + (set (match_dup 0)
- + (minus:SI (match_dup 3)
- + (match_dup 2)))]
- + {
- + gcc_assert (A0_SCRATCH != INVALID_REGNUM && fixed_regs[A0_SCRATCH]);
- + operands[3] = gen_rtx_REG (SImode, A0_SCRATCH);
- + }
- +)
- +
- +;; register - register|immediate ops that set the flags
- +(define_insn "*subs_<mode>_si_rrr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (minus:SI (match_operand:SI 1 "metag_datareg_op" "e,f,e,f")
- + (match_operand:SI 2 "metag_datareg_op" "e,f,e,f"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=e,f,r,r")
- + (minus:SI (match_dup 1)
- + (match_dup 2)))]
- + "!TARGET_METAC_1_1"
- + "SUBS\\t%0, %1, %2\\t%@ (*subs si rrr OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")])
- +
- +;; register - register|immediate ops that set the flags - v1.1 case
- +(define_insn "*subs_<mode>_si_rrr_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (minus:SI (match_operand:SI 1 "metag_datareg_op" "e, f, e, f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "be,bf,be,bf"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=e, f, r, r")
- + (minus:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1"
- + "SUBS\\t%0, %1, %2\\t%@ (*subs si rrb OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; register - register|immediate ops that set the flags only -> compares
- +(define_insn "*tsub_<mode>_si_rrr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (minus:SI (match_operand:SI 0 "metag_datareg_op" "e,f")
- + (match_operand:SI 1 "metag_datareg_op" "e,f"))
- + (const_int 0)))]
- + "!TARGET_METAC_1_1"
- + "CMP\\t%0, %1\\t%@ (*tsub si dd OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "ccstate" "set,set")])
- +
- +;; register - register ops that set the flags only -> compares - v1.1 case
- +(define_insn "*tsub_<mode>_si_rrr_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (minus:SI (match_operand:SI 0 "metag_datareg_op" "e, f")
- + (match_operand:SI 1 "metag_datareg_op" "be,bf"))
- + (const_int 0)))]
- + "TARGET_METAC_1_1"
- + "CMP\\t%0, %1\\t%@ (*tsub si db OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "ccstate" "set,set")
- + (set_attr "o2rhint" "op1op0")])
- +
- +;; signed multiply instructions
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; mulsi3 is made up of many parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "mulsi3"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (mult:SI (match_operand:SI 1 "metag_reg_nofloat_op" "")
- + (match_operand:SI 2 "metag_regorint_op" "")))]
- + ""
- + {
- + if (metag_frame_related_rtx (operands[2]))
- + {
- + /* Put the magic frame registers first */
- + rtx temp = operands[1];
- +
- + operands[1] = operands[2];
- + operands[2] = temp;
- + }
- +
- + if (!TARGET_METAC_1_1 && !reload_completed && !reload_in_progress)
- + {
- + if (CONST_INT_P (operands[2])
- + && metag_frame_related_rtx (operands[1]))
- + {
- + /* Ensure reg*const do not combine reg that may be eliminated */
- + rtx reg = gen_reg_rtx (SImode);
- +
- + emit_move_insn (reg, operands[1]);
- + operands[1] = force_reg (SImode, reg);
- + }
- + }
- +
- + if (!CONST_INT_P (operands[2])
- + || ( !satisfies_constraint_I (operands[2])
- + && !satisfies_constraint_J (operands[2])
- + && !satisfies_constraint_K (operands[2])
- + && !satisfies_constraint_P (operands[2])
- + && !satisfies_constraint_O3(operands[2])))
- + {
- + /* All except reg = (reg * bigconst) can be done quickly */
- + operands[2] = force_reg (SImode, operands[2]);
- + }
- + }
- +)
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; and these are the mulsi3 parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +
- +;; register * register ops - v1.0 bug disables MULD Dn.x, Dm.x, Dm.y
- +(define_insn "*mul_si_rrr"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,f,a,a")
- + (mult:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e,f,e,f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e,f,e,f")))]
- + "!TARGET_METAC_1_1"
- + "MULD\\t%0, %1, %2\\t%@ (*mul si rrr OK)"
- + [(set_attr "type" "mult,mult,slowslow,slowslow")])
- +
- +;; register * register ops v1.1
- +(define_insn "*mul_si_rrr_1_1"
- + [(set (match_operand:SI 0 "metag_register_op" "=e, f, r, r")
- + (mult:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e, f, e, f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "be,bf,be,bf")))]
- + "TARGET_METAC_1_1 && !TARGET_MINIM_CORE"
- + "MULD\\t%0, %1, %2\\t%@ (*mul si rrr OK)"
- + [(set_attr "type" "mult,mult,slowslow,slowslow")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; register * register ops minim
- +(define_insn "*mul_si_rrr_minim"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,!e, f,!f, r,!r, r,!r")
- + (mult:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e, e, f, f, e, e, f, f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, be,f, bf,e, be,f, bf")))]
- + "TARGET_METAC_1_1 && TARGET_MINIM_CORE"
- + "MULD\\t%0, %1, %2\\t%@ (*mul si rrr OK)"
- + [(set_attr "type" "mult,mult,mult,mult,slowslow,slowslow,slowslow,slowslow")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; register * immediate ops - v1.0 bug disables MULD Dn.x, Dm.x, #0xnn
- +(define_insn "*mul_si_rri"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,f,d, d,d, a,a,&e,&f")
- + (mult:SI (match_operand:SI 1 "metag_regnofrm_op" "e,f,0, 0,0, e,f, e, f")
- + (match_operand:SI 2 "metag_int_operand" "K,K,IP,J,O3,K,K, i, i")))]
- + "!TARGET_METAC_1_1"
- + "@
- + MULD\\t%0, %1, %2\\t\\t%@ (*mul si eeK OK)
- + MULD\\t%0, %1, %2\\t\\t%@ (*mul si ffK OK)
- + MULD\\t%0, %1, %2\\t%@ (*mul si d0I OK)
- + MULDT\\t%0, %1, #HI(%c2)\\t%@ (*mul si d0J OK)
- + MULD\\t%0, %1, #LO(%c2)\\t%@ (*mul si d0O3 OK)
- + MULD\\t%0, %1, %2\\t\\t%@ (*mul si reK OK)
- + MULD\\t%0, %1, %2\\t\\t%@ (*mul si rfK OK)
- + #
- + #"
- + [(set_attr "type" "mult,mult,mult,mult,mult,slowslow,slowslow,four,four")])
- +
- +;; Split the above insn if it needs more than one insn
- +(define_split
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (mult:SI (match_operand:SI 1 "metag_reg_nofloat_op" "")
- + (match_operand:SI 2 "metag_int_operand" "")))]
- + "!TARGET_METAC_1_1
- + && reload_completed
- + && REGNO (operands[0]) == REGNO (operands[1]) && !METAG_CONST_OK_FOR_LETTERS_KPIJO3 (operands[2])"
- + [(set (match_dup 0)
- + (match_dup 3))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_dup 4)))
- + (set (match_dup 0)
- + (mult:SI (match_dup 1)
- + (match_dup 0)))]
- + {
- + HOST_WIDE_INT value = INTVAL (operands[2]);
- + HOST_WIDE_INT ival;
- +
- + ival = trunc_int_for_mode (value & 0xFFFF0000, SImode);
- + operands[3] = GEN_INT (ival);
- +
- + ival = trunc_int_for_mode (value & 0x0000FFFF, SImode);
- + operands[4] = GEN_INT (ival);
- + }
- +)
- +
- +;; register * immediate ops
- +(define_insn "*mul_si_rri_1_1"
- + [(set (match_operand:SI 0 "metag_register_op" "=r,d, d,d, &e,&f")
- + (mult:SI (match_operand:SI 1 "metag_reg_nofloat_op" "d,0, 0,0, e, f")
- + (match_operand:SI 2 "metag_int_operand" "K,IP,J,O3, i, i")))]
- + "TARGET_METAC_1_1"
- + "@
- + MULD\\t%0, %1, %2\\t\\t%@ (*mul si rdK OK)
- + MULD\\t%0, %1, %2\\t%@ (*mul si d0I OK)
- + MULDT\\t%0, %1, #HI(%c2)\\t%@ (*mul si d0J OK)
- + MULD \\t%0, %1, #LO(%c2)\\t%@ (*mul si d0J OK)
- + #
- + #"
- + [(set_attr "type" "slowslow,mult,mult,mult,four,four")])
- +
- +;; Split the above insn if it needs more than one insn
- +(define_split
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (mult:SI (match_operand:SI 1 "metag_reg_nofloat_op" "")
- + (match_operand:SI 2 "metag_int_operand" "")))]
- + "TARGET_METAC_1_1
- + && reload_completed
- + && REGNO (operands[0]) != REGNO (operands[1]) && !satisfies_constraint_K (operands[2])"
- + [(set (match_dup 0)
- + (match_dup 3))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_dup 4)))
- + (set (match_dup 0)
- + (mult:SI (match_dup 1)
- + (match_dup 0)))]
- + {
- + HOST_WIDE_INT value = INTVAL (operands[2]);
- + HOST_WIDE_INT ival;
- +
- + ival = trunc_int_for_mode (value & 0xFFFF0000, SImode);
- + operands[3] = GEN_INT (ival);
- +
- + ival = trunc_int_for_mode (value & 0x0000FFFF, SImode);
- + operands[4] = GEN_INT (ival);
- + }
- +)
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; umulhisi3 is made up of many parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "umulhisi3"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (mult:SI (zero_extend:SI (match_operand:HI 1 "metag_reg_nofloat_op" ""))
- + (zero_extend:SI (match_operand:HI 2 "metag_regorint_op" ""))))]
- + ""
- + {
- + if (CONST_INT_P (operands[2]))
- + {
- + /* Mask off the unsigned immediate to zero extend */
- + HOST_WIDE_INT ival = INTVAL (operands[2]) & GET_MODE_MASK (HImode);
- +
- + emit_move_insn (operands[0],
- + gen_rtx_MULT (SImode,
- + gen_rtx_ZERO_EXTEND (SImode, operands[1]),
- + GEN_INT (ival)));
- + DONE;
- + }
- + }
- +)
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; and these are the umulhisi3 parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +
- +;; register * register ops
- +(define_insn "*umul_hisi_rrr"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,f,r,r")
- + (mult:SI (zero_extend:SI
- + (match_operand:HI 1 "metag_reg_nofloat_op" "%e,f,e,f"))
- + (zero_extend:SI
- + (match_operand:HI 2 "metag_reg_nofloat_op" "e,f,e,f"))))]
- + "!TARGET_METAC_1_1"
- + "MULW%?\\t%0, %1, %2\\t%@ (*umul hisi rrr OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; register * register ops - v1.1 case
- +(define_insn "*umul_hisi_rrr_1_1"
- + [(set (match_operand:SI 0 "metag_register_op" "=e, f, r, r")
- + (mult:SI (zero_extend:SI
- + (match_operand:HI 1 "metag_reg_nofloat_op" "%e, f, e, f"))
- + (zero_extend:SI
- + (match_operand:HI 2 "metag_reg_nofloat_op" "be,bf,be,bf"))))]
- + "TARGET_METAC_1_1 && !TARGET_MINIM_CORE"
- + "MULW%?\\t%0, %1, %2\\t%@ (*umul hisi rrr OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes")
- + (set_attr "predicable" "yes")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; register * register ops - minim case
- +(define_insn "*umul_hisi_rrr_minim"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,!e, f,!f, r,!r, r,!r")
- + (mult:SI (zero_extend:SI
- + (match_operand:HI 1 "metag_reg_nofloat_op" "%e, e, f, f, e, e, f, f"))
- + (zero_extend:SI
- + (match_operand:HI 2 "metag_reg_nofloat_op" "e, be,f, bf,e, be,f, bf"))))]
- + "TARGET_METAC_1_1 && TARGET_MINIM_CORE"
- + "MULW%?\\t%0, %1, %2\\t%@ (*umul hisi rrr OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; register * immediate ops
- +(define_insn "*umul_hisi_rri"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,f,r,d")
- + (mult:SI (zero_extend:SI
- + (match_operand:HI 1 "metag_reg_nofloat_op" "e,f,d,0"))
- + (match_operand:SI 2 "metag_int_operand" "K,K,K,IP")))]
- + ""
- + "@
- + MULW%?\\t%0, %1, %2\\t\\t%@ (*umul hisi eeK OK)
- + MULW%?\\t%0, %1, %2\\t\\t%@ (*umul hisi ffK OK)
- + MULW\\t%0, %1, %2\\t\\t%@ (*umul hisi rdK OK)
- + MULW\\t%0, %1, %2\\t%@ (*umul hisi d0I OK)"
- + [(set_attr "type" "fast,fast,slow,fast")
- + (set_attr "cond" "yes,yes,no,no")])
- +
- +;; conditional version for specific cases of umul_hisi_rri
- +(define_insn "*cond_<mode>_umul_hisi_rri"
- + [(cond_exec
- + (match_operator 3 "comparison_operator"
- + [(match_operand:CCALL 4 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (set (match_operand:SI 0 "metag_datareg_op" "=e,f")
- + (mult:SI (zero_extend:SI
- + (match_operand:HI 1 "metag_datareg_op" "e,f"))
- + (match_operand:SI 2 "metag_K_operand" "K,K"))))]
- + "reload_completed
- + && metag_same_regclass_p (operands[0], operands[1])"
- + "@
- + MULW%?\\t%0, %1, %2\\t\\t%@ (*umul hisi eeK OK)
- + MULW%?\\t%0, %1, %2\\t\\t%@ (*umul hisi ffK OK)"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "no")])
- +
- +;; signed divide instructions
- +
- +; we don't have one..
- +
- +;; signed modulus instruction
- +
- +; we don't have one..
- +
- +;; unsigned divide instruction
- +
- +; we don't have one..
- +
- +;; logical-and instructions
- +
- +(define_insn "*anddi3_dsp"
- + [(set (match_operand:DI 0 "metag_register_op" "=d")
- + (and:DI (match_dup 0)
- + (match_operand:DI 1 "metag_16bit_op" "KIP")))]
- + "TARGET_DSP"
- + "DL\\tAND\\t%0, %0, %1\\t%@ (*AND\\t%t0, %t0, %1)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*anddi3"
- + [(set (match_operand:DI 0 "metag_register_op" "=d")
- + (and:DI (match_operand:DI 1 "metag_register_op" "d")
- + (match_operand:DI 2 "metag_register_op" "d")))]
- + "TARGET_DSP"
- + "DL\\tAND\\t%0, %1, %2\\t%@ (*AND\\t%t0, %t1, %t2)"
- + [(set_attr "type" "fast")])
- +
- +(define_expand "anddi3"
- + [(set (match_operand:DI 0 "metag_register_op" "=d")
- + (and:DI (match_operand:DI 1 "metag_register_op" "d")
- + (match_operand:DI 2 "metag_register_op" "d")))]
- + ""
- + {
- + if (!TARGET_DSP)
- + FAIL;
- + }
- + )
- +
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; andsi3 is made up of many parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "andsi3"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (and:SI (match_operand:SI 1 "metag_reg_nofloat_op" "")
- + (match_operand:SI 2 "metag_regorint_op" "")))]
- + ""
- + {
- + if (CONST_INT_P (operands[2])
- + && METAG_LETTER_FOR_CONST (operands[2]) == 0)
- + {
- + /* Need to use M,N cases to implement op */
- + rtx temp = (reload_in_progress || reload_completed)
- + ? operands[0] : gen_reg_rtx (SImode);
- + HOST_WIDE_INT value = INTVAL (operands[2]);
- + HOST_WIDE_INT ival;
- +
- + ival = trunc_int_for_mode (value | 0xFFFF0000, SImode);
- + emit_insn (gen_rtx_SET (VOIDmode, temp,
- + gen_rtx_AND (SImode, operands[1],
- + GEN_INT (ival))));
- + ival = trunc_int_for_mode (value | 0x0000FFFF, SImode);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- + gen_rtx_AND (SImode, temp,
- + GEN_INT (ival))));
- + DONE;
- + }
- + }
- +)
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; and these are the andsi3 parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +
- +;; register & register ops
- +(define_insn "*and_si_rrr"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,f,r,r")
- + (and:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e,f,e,f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e,f,e,f")))]
- + "!TARGET_METAC_1_1 || TARGET_MTX"
- + "AND%?\\t%0, %1, %2\\t%@ (*and si rrr OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; register & register ops - v1.1 case
- +(define_insn "*and_si_rrr_1_1"
- + [(set (match_operand:SI 0 "metag_register_op" "=e, f, r, r")
- + (and:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e, f, e, f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "be,bf,be,bf")))]
- + "TARGET_METAC_1_1 && !TARGET_MINIM_CORE && !TARGET_MTX"
- + "AND%?\\t%0, %1, %2\\t%@ (*and si rrr OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes")
- + (set_attr "predicable" "yes")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; register & register ops - minim case
- +(define_insn "*and_si_rrr_minim"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,!e, f,!f, r,!r, r,!r")
- + (and:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e, e, f, f, e, e, f, f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, be,f, bf,e, be,f, bf")))]
- + "TARGET_METAC_1_1 && TARGET_MINIM_CORE && !TARGET_MTX"
- + "AND%?\\t%0, %1, %2\\t%@ (*and si rrr OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; register & immediate ops
- +(define_insn "*and_si_rri"
- + [(set (match_operand:SI 0 "metag_register_op" "=d, d,d,d,e,f,r")
- + (and:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0, 0,0,0,e,f,d")
- + (match_operand:SI 2 "metag_int_operand" "IP,J,M,N,K,K,K")))]
- + "!TARGET_MINIM_CORE"
- + "@
- + AND\\t%0, %1, %2\\t%@ (*and si r0I OK)
- + ANDT\\t%0, %1, #HI(%c2)\\t%@ (*and si d0J OK)
- + ANDMB\\t%0, %1, #LO(%c2)\\t%@ (*and si d0M OK)
- + ANDMT\\t%0, %1, #HI(%c2)\\t%@ (*and si d0N OK)
- + AND%?\\t%0, %1, %2\\t\\t%@ (*and si eeK OK)
- + AND%?\\t%0, %1, %2\\t\\t%@ (*and si ffK OK)
- + AND\\t%0, %1, %2\\t\\t%@ (*and si rdK OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,slow")
- + (set_attr "cond" "no,no,no,no,yes,yes,no")])
- +
- +;; register & immediate ops
- +(define_insn "*and_si_rri"
- + [(set (match_operand:SI 0 "metag_register_op" "=d, d,d,d,d,!e,!f,!r")
- + (and:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0, 0,0,0,0, e, f, d")
- + (match_operand:SI 2 "metag_int_operand" "IP,J,M,N,K, K, K, K")))]
- + "TARGET_MINIM_CORE"
- + "@
- + AND\\t%0, %1, %2\\t%@ (*and si r0I OK)
- + ANDT\\t%0, %1, #HI(%c2)\\t%@ (*and si d0J OK)
- + ANDMB\\t%0, %1, #LO(%c2)\\t%@ (*and si d0M OK)
- + ANDMT\\t%0, %1, #HI(%c2)\\t%@ (*and si d0N OK)
- + AND%?\\t%0, %1, %2\\t\\t%@ (*and si d0K OK)
- + AND%?\\t%0, %1, %2\\t\\t%@ (*and si eeK OK)
- + AND%?\\t%0, %1, %2\\t\\t%@ (*and si ffK OK)
- + AND\\t%0, %1, %2\\t\\t%@ (*and si rdK OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,fast,slow")
- + (set_attr "cond" "no,no,no,no,yes,yes,yes,no")])
- +
- +;; conditional version for specific cases of and_si_rri
- +(define_insn "*cond_<mode>_and_si_rri"
- + [(cond_exec
- + (match_operator 3 "comparison_operator"
- + [(match_operand:CCALL 4 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (set (match_operand:SI 0 "metag_datareg_op" "=e,f")
- + (and:SI (match_operand:SI 1 "metag_datareg_op" "e,f")
- + (match_operand:SI 2 "metag_K_operand" "K,K"))))]
- + "reload_completed
- + && metag_same_regclass_p (operands[0], operands[1])"
- + "@
- + AND%?\\t%0, %1, %2\\t\\t%@ (*and si eeK OK)
- + AND%?\\t%0, %1, %2\\t\\t%@ (*and si ffK OK)"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "no")])
- +
- +;; test register ops setting the NOOV flags
- +(define_insn "*tst_<mode>_si_rr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (and:SI (match_operand:SI 0 "metag_datareg_op" "%e,f")
- + (match_operand:SI 1 "metag_datareg_op" "e,f"))
- + (const_int 0)))]
- + "!TARGET_METAC_1_1"
- + "TST\\t%0, %1\\t%@ (*tst si dd OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "ccstate" "set,set")])
- +
- +;; test register ops setting the NOOV flags - v1.1 case
- +(define_insn "*tst_<mode>_si_rr_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (and:SI (match_operand:SI 0 "metag_datareg_op" "%e, f")
- + (match_operand:SI 1 "metag_reg_nofloat_op" "be,bf"))
- + (const_int 0)))]
- + "TARGET_METAC_1_1 && !TARGET_MINIM_CORE"
- + "TST\\t%0, %1\\t%@ (*tst si db OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "ccstate" "set,set")
- + (set_attr "o2rhint" "op1op0")])
- +
- +;; test register ops setting the NOOV flags - minim case
- +(define_insn "*tst_<mode>_si_rr_minim"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (and:SI (match_operand:SI 0 "metag_datareg_op" "%e,!e, f,!f")
- + (match_operand:SI 1 "metag_register_op" "e, be,f, bf"))
- + (const_int 0)))]
- + "TARGET_METAC_1_1 && TARGET_MINIM_CORE"
- + "TST\\t%0, %1\\t%@ (*tst si db OK)"
- + [(set_attr "type" "fast,fast,fast,fast")
- + (set_attr "ccstate" "set")
- + (set_attr "o2rhint" "op1op0")])
- +
- +(define_insn "*tst_<mode>_si_ri"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (and:SI (match_operand:SI 0 "metag_reg_nofloat_op" "d,d, d,d,d")
- + (match_operand:SI 1 "metag_int_operand" "K,IP,J,M,N"))
- + (const_int 0)))]
- + ""
- + "@
- + TST\\t%0, %1\\t%@ (*tst si dI OK)
- + TST\\t%0, %1\\t%@ (*tst si dI OK)
- + TSTT\\t%0, %1\\t%@ (*tst si dJ OK)
- + TSTMB\\t%0, #LO(%c1)\\t%@ (*tst si dM OK)
- + TSTMT\\t%0, #HI(%c1)\\t%@ (*tst si dN OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast")
- + (set_attr "ccstate" "set,set,set,set,set")])
- +
- +;; and register ops combined with test cases
- +(define_insn "*ands_si_rrr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (and:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e,f,e,f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e,f,e,f"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=e,f,r,r")
- + (and:SI (match_dup 1)
- + (match_dup 2)))]
- + "!TARGET_METAC_1_1 || TARGET_MTX"
- + "ANDS\\t%0, %1, %2\\t%@ (*ands si xdd OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")])
- +
- +(define_insn "*ands_<mode>_si_rri"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (and:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0, 0,0,0,e,f,d")
- + (match_operand:SI 2 "metag_int_operand" "IP,J,M,N,K,K,K"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=d, d,d,d,e,f,r")
- + (and:SI (match_dup 1)
- + (match_dup 2)))]
- + ""
- + "@
- + ANDS\\t%0, %1, %2\\t%@ (*ands si r0I OK)
- + ANDST\\t%0, %1, #HI(%c2)\\t%@ (*ands si r0J OK)
- + ANDSMB\\t%0, %1, #LO(%c2)\\t%@ (*ands si r0M OK)
- + ANDSMT\\t%0, %1, #HI(%c2)\\t%@ (*ands si r0N OK)
- + ANDS\\t%0, %1, %2\\t\\t%@ (*ands si eeK OK)
- + ANDS\\t%0, %1, %2\\t\\t%@ (*ands si ffK OK)
- + ANDS\\t%0, %1, %2\\t\\t%@ (*ands si ddK OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,slow")
- + (set_attr "ccstate" "set,set,set,set,set,set,set")])
- +
- +;; and register ops combined with test cases - v1.1 case
- +(define_insn "*ands_si_rrr_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (and:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e, f, e, f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "be,bf,be,bf"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=e, f, r, r")
- + (and:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1 && !TARGET_MTX"
- + "ANDS\\t%0, %1, %2\\t%@ (*ands si xdb OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; bitextract - matched during combine
- +(define_insn_and_split "*zeroextractsi_<mode>_compare0"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (zero_extract:SI (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (match_operand 1 "const_int_operand" "")
- + (match_operand 2 "const_int_operand" ""))
- + (const_int 0)))]
- + "metag_zeroextract_mask_p (operands[1], operands[2])"
- + "#"
- + ""
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (and:SI (match_dup 0)
- + (match_dup 3))
- + (const_int 0)))]
- + {
- + operands[3] = GEN_INT (((1 << INTVAL (operands[1])) -1) << INTVAL (operands[2]));
- + }
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +;; inclusive-or instructions
- +
- +(define_insn "iordi3"
- + [(set (match_operand:DI 0 "metag_register_op" "=d")
- + (ior:DI (match_operand:DI 1 "metag_register_op" "d")
- + (match_operand:DI 2 "metag_register_op" "d")))]
- + "TARGET_DSP"
- + "DL\\tOR\\t%0, %1, %2\\t%@ (*OR\\t%t0, %t1, %t2)"
- + [(set_attr "type" "fast")])
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; iorsi3 is made up of many parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "iorsi3"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (ior:SI (match_operand:SI 1 "metag_reg_nofloat_op" "")
- + (match_operand:SI 2 "metag_regorint_op" "")))]
- + ""
- + {
- + if (CONST_INT_P (operands[2])
- + && METAG_LETTER_FOR_CONST (operands[2]) == 0)
- + {
- + /* Need to use I,J cases to implement op */
- + rtx temp = (reload_in_progress || reload_completed)
- + ? operands[0] : gen_reg_rtx (SImode);
- + HOST_WIDE_INT value = INTVAL (operands[2]);
- + HOST_WIDE_INT ival;
- +
- + ival = trunc_int_for_mode (value & 0xFFFF0000, SImode);
- + emit_insn (gen_rtx_SET (VOIDmode, temp,
- + gen_rtx_IOR (SImode, operands[1],
- + GEN_INT (ival))));
- +
- + ival = trunc_int_for_mode (value & 0x0000FFFF, SImode);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- + gen_rtx_IOR (SImode, temp,
- + GEN_INT (ival))));
- + DONE;
- + }
- + }
- +)
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; and these are the iorsi3 parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +
- +;; register | register ops
- +(define_insn "*ior_si_rrr"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,f,r,r")
- + (ior:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e,f,e,f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e,f,e,f")))]
- + "!TARGET_METAC_1_1 || TARGET_MTX"
- + "OR%?\\t%0, %1, %2\\t%@ (*ior si xdd OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; register | register ops - v1.1 case
- +(define_insn "*ior_si_rrr_1_1"
- + [(set (match_operand:SI 0 "metag_register_op" "=e, f, r, r")
- + (ior:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e, f, e, f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "be,bf,be,bf")))]
- + "TARGET_METAC_1_1 && !TARGET_MINIM_CORE && !TARGET_MTX"
- + "OR%?\\t%0, %1, %2\\t%@ (*ior si xdb OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes")
- + (set_attr "predicable" "yes")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; register | register ops - minim case
- +(define_insn "*ior_si_rrr_minim"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,!e, f,!f, r,!r, r,!r")
- + (ior:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e, e, f, f, e, e, f, f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, be,f, bf,e, be,f, bf")))]
- + "TARGET_METAC_1_1 && TARGET_MINIM_CORE && !TARGET_MTX"
- + "OR%?\\t%0, %1, %2\\t%@ (*ior si xdb OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; register | immediate ops
- +(define_insn "*ior_si_rri"
- + [(set (match_operand:SI 0 "metag_register_op" "=d, d,d,d,e,f,r")
- + (ior:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0, 0,0,0,e,f,d")
- + (match_operand:SI 2 "metag_int_operand" "IP,J,M,N,K,K,K")))]
- + "!TARGET_MINIM_CORE"
- + "@
- + OR\\t%0, %1, %2\\t%@ (*ior si r0I OK)
- + ORT\\t%0, %1, #HI(%c2)\\t%@ (*ior si r0J OK)
- + ORMB\\t%0, %1, #LO(%c2)\\t%@ (*ior si r0M OK)
- + ORMT\\t%0, %1, #HI(%c2)\\t%@ (*ior si r0N OK)
- + OR%?\\t%0, %1, %2\\t\\t%@ (*ior si eeK OK)
- + OR%?\\t%0, %1, %2\\t\\t%@ (*ior si ffK OK)
- + OR\\t%0, %1, %2\\t\\t%@ (*ior si rdK OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,slow")
- + (set_attr "cond" "no,no,no,no,yes,yes,no")])
- +
- +;; register | immediate ops
- +(define_insn "*ior_si_rri"
- + [(set (match_operand:SI 0 "metag_register_op" "=d, d,d,d,d,!e,!f,!r")
- + (ior:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0, 0,0,0,0, e, f, d")
- + (match_operand:SI 2 "metag_int_operand" "IP,J,M,N,K, K, K, K")))]
- + "TARGET_MINIM_CORE"
- + "@
- + OR\\t%0, %1, %2\\t%@ (*ior si r0I OK)
- + ORT\\t%0, %1, #HI(%c2)\\t%@ (*ior si r0J OK)
- + ORMB\\t%0, %1, #LO(%c2)\\t%@ (*ior si r0M OK)
- + ORMT\\t%0, %1, #HI(%c2)\\t%@ (*ior si r0N OK)
- + OR%?\\t%0, %1, %2\\t\\t%@ (*ior si d0K OK)
- + OR%?\\t%0, %1, %2\\t\\t%@ (*ior si eeK OK)
- + OR%?\\t%0, %1, %2\\t\\t%@ (*ior si ffK OK)
- + OR\\t%0, %1, %2\\t\\t%@ (*ior si rdK OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,fast,slow")
- + (set_attr "cond" "no,no,no,no,yes,yes,yes,no")])
- +
- +;; conditional version for specific cases of ior_si_rri
- +(define_insn "*cond_<mode>_ior_si_rri"
- + [(cond_exec
- + (match_operator 3 "comparison_operator"
- + [(match_operand:CCALL 4 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (set (match_operand:SI 0 "metag_datareg_op" "=e,f")
- + (ior:SI (match_operand:SI 1 "metag_datareg_op" "e,f")
- + (match_operand:SI 2 "metag_K_operand" "K,K"))))]
- + "reload_completed
- + && metag_same_regclass_p (operands[0], operands[1])"
- + "@
- + OR%?\\t%0, %1, %2\\t\\t%@ (*ior si eeK OK)
- + OR%?\\t%0, %1, %2\\t\\t%@ (*ior si ffK OK)"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "no")])
- +
- +;; ior register ops combined with test cases
- +(define_insn "*iors_<mode>_si_rrr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (ior:SI (match_operand:SI 1 "metag_datareg_op" "%e,f,e,f")
- + (match_operand:SI 2 "metag_datareg_op" "e,f,e,f"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=e,f,r,r")
- + (ior:SI (match_dup 1)
- + (match_dup 2)))]
- + "!TARGET_METAC_1_1 || TARGET_MTX"
- + "ORS\\t%0, %1, %2\\t%@ (*iors si xdd OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")])
- +
- +(define_insn "*iors_<mode>_si_rri"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (ior:SI (match_operand:SI 1 "metag_datareg_op" "0, 0,0,0,e,f,d")
- + (match_operand:SI 2 "metag_int_operand" "IP,J,M,N,K,K,K"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=d, d,d,d,e,f,r")
- + (ior:SI (match_dup 1)
- + (match_dup 2)))]
- + ""
- + "@
- + ORS\\t%0, %1, %2\\t%@ (*iors si d0I OK)
- + ORST\\t%0, %1, #HI(%c2)\\t%@ (*ands si d0J OK)
- + ORSMB\\t%0, %1, #LO(%c2)\\t%@ (*iors si d0M OK)
- + ORSMT\\t%0, %1, #HI(%c2)\\t%@ (*ands si d0N OK)
- + ORS\\t%0, %1, %2\\t\\t%@ (*iors si eeK OK)
- + ORS\\t%0, %1, %2\\t\\t%@ (*iors si ffK OK)
- + ORS\\t%0, %1, %2\\t\\t%@ (*iors si ddK OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,slow")
- + (set_attr "ccstate" "set,set,set,set,set,set,set")])
- +
- +;; ior register ops combined with test cases - v1.1 case
- +(define_insn "*iors_<mode>_si_rrr_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (ior:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e, f, e, f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "be,bf,be,bf"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=e, f, r, r")
- + (ior:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1 && !TARGET_MTX"
- + "ORS\\t%0, %1, %2\\t%@ (*iors si xdb OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; scratch ior register ops setting the NOOV flags - needed to enable combines
- +(define_insn "*tior_<mode>_si_rr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (ior:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e,f,e,f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e,f,e,f"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=e,f,r,r"))]
- + "!TARGET_METAC_1_1 || TARGET_MTX"
- + "ORS\\t%0, %1, %2\\t%@ (*tior si xdd OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")])
- +
- +(define_insn "*tior_<mode>_si_ri"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (ior:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0, 0,0,0,e,f")
- + (match_operand:SI 2 "metag_int_operand" "IP,J,M,N,K,K"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=d, d,d,d,e,f"))]
- + ""
- + "@
- + ORS\\t%0, %1, %2\\t%@ (*tior si dI OK)
- + ORST\\t%0, %1, #HI(%c2)\\t%@ (*tior si dJ OK)
- + ORSMB\\t%0, %1, #LO(%c2)\\t%@ (*tior si dM OK)
- + ORSMT\\t%0, %1, #HI(%c2)\\t%@ (*tior si dN OK)
- + ORS\\t%0, %1, %2\\t\\t%@ (*tior si eK OK)
- + ORS\\t%0, %1, %2\\t\\t%@ (*tior si fK OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast")
- + (set_attr "ccstate" "set,set,set,set,set,set")])
- +
- +;; scratch ior register ops setting the NOOV flags - v1.1 case
- +(define_insn "*tior_<mode>_si_rr_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (ior:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e, f, e, f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "be,bf,be,bf"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=e, f, r, r"))]
- + "TARGET_METAC_1_1 && !TARGET_MTX"
- + "ORS\\t%0, %1, %2\\t%@ (*tior si xdb OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; exclusive-or instructions
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; and these are the xordi3 parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +
- +(define_insn "*xordi3_rri"
- + [(set (match_operand:DI 0 "metag_register_op" "+d")
- + (xor:DI (match_dup 0)
- + (match_operand:DI 1 "metag_16bit_op" "KIP")))]
- + "TARGET_DSP"
- + "DL\\tXOR\\t%0, %0, %1\\t%@ (*OR\\t%t0, %t0, %1)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "xordi3"
- + [(set (match_operand:DI 0 "metag_register_op" "=d")
- + (xor:DI (match_operand:DI 1 "metag_register_op" "d")
- + (match_operand:DI 2 "metag_register_op" "d")))]
- + "TARGET_DSP"
- + "DL\\tXOR\\t%0, %1, %2\\t%@ (*OR\\t%t0, %t1, %t2)"
- + [(set_attr "type" "fast")])
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; xorsi3 is made up of many parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +(define_expand "xorsi3"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (xor:SI (match_operand:SI 1 "metag_reg_nofloat_op" "")
- + (match_operand:SI 2 "metag_regorint_op" "")))]
- + ""
- + {
- + if (CONST_INT_P (operands[2])
- + && METAG_LETTER_FOR_CONST (operands[2]) == 0)
- + {
- + /* Need to use I,J cases to implement op */
- + rtx temp = (reload_in_progress || reload_completed)
- + ? operands[0] : gen_reg_rtx (SImode);
- + HOST_WIDE_INT value = INTVAL (operands[2]);
- + HOST_WIDE_INT ival;
- +
- + ival = trunc_int_for_mode (value & 0xFFFF0000, SImode);
- + emit_insn (gen_rtx_SET (VOIDmode, temp,
- + gen_rtx_XOR (SImode, operands[1],
- + GEN_INT (ival))));
- +
- + ival = trunc_int_for_mode (value & 0x0000FFFF, SImode);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- + gen_rtx_XOR (SImode, temp,
- + GEN_INT (ival))));
- + DONE;
- + }
- + }
- +)
- +
- +;; register ^ register ops
- +
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +;; and these are the xorsi3 parts.. ;;
- +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
- +
- +;; register ^ register ops
- +(define_insn "*xor_si_rrr"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,f,r,r")
- + (xor:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e,f,e,f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e,f,e,f")))]
- + "!TARGET_METAC_1_1 || TARGET_MTX"
- + "XOR%?\\t%0, %1, %2\\t%@ (*xor si xdd OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes")
- + (set_attr "predicable" "yes")])
- +
- +;; register ^ register ops - v1.1 case
- +(define_insn "*xor_si_rrr_1_1"
- + [(set (match_operand:SI 0 "metag_register_op" "=e, f, r, r")
- + (xor:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e, f, e, f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "be,bf,be,bf")))]
- + "TARGET_METAC_1_1 && !TARGET_MINIM_CORE && !TARGET_MTX"
- + "XOR%?\\t%0, %1, %2\\t%@ (*xor si xdb OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes")
- + (set_attr "predicable" "yes")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; register ^ register ops - minim case
- +(define_insn "*xor_si_rrr_minim"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,!e, f,!f, r,!r, r,!r")
- + (xor:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e, e, f, f, e, e, f, f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, be,f, bf,e, be,f, bf")))]
- + "TARGET_METAC_1_1 && TARGET_MINIM_CORE && !TARGET_MTX"
- + "XOR%?\\t%0, %1, %2\\t%@ (*xor si xdb OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; same register ^ immediate ops
- +(define_insn "*xor_si_rri"
- + [(set (match_operand:SI 0 "metag_register_op" "=d, d,d,d,e,f,r")
- + (xor:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0, 0,0,0,e,f,d")
- + (match_operand:SI 2 "metag_int_operand" "IP,J,M,N,K,K,K")))]
- + "!TARGET_MINIM_CORE"
- + "@
- + XOR\\t%0, %1, %2\\t%@ (*xor si d0I OK)
- + XORT\\t%0, %1, #HI(%c2)\\t%@ (*xor si d0J OK)
- + XORMB\\t%0, %1, #LO(%c2)\\t%@ (*xor si d0M OK)
- + XORMT\\t%0, %1, #HI(%c2)\\t%@ (*xor si d0N OK)
- + XOR%?\\t%0, %1, %2\\t\\t%@ (*xor si eeK OK)
- + XOR%?\\t%0, %1, %2\\t\\t%@ (*xor si ffK OK)
- + XOR\\t%0, %1, %2\\t\\t%@ (*xor si rdK OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,slow")
- + (set_attr "cond" "no,no,no,no,yes,yes,no")])
- +
- +;; same register ^ immediate ops
- +(define_insn "*xor_si_rri"
- + [(set (match_operand:SI 0 "metag_register_op" "=d, d,d,d,d,e,f,r")
- + (xor:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0, 0,0,0,0,e,f,d")
- + (match_operand:SI 2 "metag_int_operand" "IP,J,M,N,K,K,K,K")))]
- + "TARGET_MINIM_CORE"
- + "@
- + XOR\\t%0, %1, %2\\t%@ (*xor si d0I OK)
- + XORT\\t%0, %1, #HI(%c2)\\t%@ (*xor si d0J OK)
- + XORMB\\t%0, %1, #LO(%c2)\\t%@ (*xor si d0M OK)
- + XORMT\\t%0, %1, #HI(%c2)\\t%@ (*xor si d0N OK)
- + XOR%?\\t%0, %1, %2\\t\\t%@ (*xor si d0K OK)
- + XOR%?\\t%0, %1, %2\\t\\t%@ (*xor si eeK OK)
- + XOR%?\\t%0, %1, %2\\t\\t%@ (*xor si ffK OK)
- + XOR\\t%0, %1, %2\\t\\t%@ (*xor si rdK OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,fast,slow")
- + (set_attr "cond" "no,no,no,no,yes,yes,yes,no")])
- +
- +;; conditional version for specific cases of xor_si_rri
- +(define_insn "*cond_<mode>_xor_si_rri"
- + [(cond_exec
- + (match_operator 3 "comparison_operator"
- + [(match_operand:CCALL 4 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (set (match_operand:SI 0 "metag_datareg_op" "=e,f")
- + (xor:SI (match_operand:SI 1 "metag_datareg_op" "e,f")
- + (match_operand:SI 2 "metag_K_operand" "K,K"))))]
- + "reload_completed
- + && metag_same_regclass_p (operands[0], operands[1])"
- + "@
- + XOR%?\\t%0, %1, %2\\t\\t%@ (*xor si eeK OK)
- + XOR%?\\t%0, %1, %2\\t\\t%@ (*xor si ffK OK)"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "no")])
- +
- +;; xor register ops combined with test cases
- +(define_insn "*xors_<mode>_si_rrr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (xor:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e,f,e,f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e,f,e,f"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=e,f,r,r")
- + (xor:SI (match_dup 1)
- + (match_dup 2)))]
- + "!TARGET_METAC_1_1 || TARGET_MTX"
- + "XORS\\t%0, %1, %2\\t%@ (*xors si xdd OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")])
- +
- +(define_insn "*xors_<mode>_si_rri"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (xor:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0, 0,0,0,e,f,d")
- + (match_operand:SI 2 "metag_int_operand" "IP,J,M,N,K,K,K"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=d, d,d,d,e,f,r")
- + (xor:SI (match_dup 1)
- + (match_dup 2)))]
- + ""
- + "@
- + XORS\\t%0, %1, %2\\t%@ (*xors si d0I OK)
- + XORST\\t%0, %1, #HI(%c2)\\t%@ (*xors si d0J OK)
- + XORSMB\\t%0, %1, #LO(%c2)\\t%@ (*xors si d0M OK)
- + XORSMT\\t%0, %1, #HI(%c2)\\t%@ (*xors si d0N OK)
- + XORS\\t%0, %1, %2\\t\\t%@ (*xors si eeK OK)
- + XORS\\t%0, %1, %2\\t\\t%@ (*xors si ffK OK)
- + XORS\\t%0, %1, %2\\t\\t%@ (*xors si rdK OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,slow")
- + (set_attr "ccstate" "set,set,set,set,set,set,set")])
- +
- +;; xor register ops combined with test cases - v1.1 case
- +(define_insn "*xors_<mode>_si_rrr_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (xor:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e, f, e, f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "be,bf,be,bf"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=e, f, r, r")
- + (xor:SI (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_METAC_1_1 && !TARGET_MTX"
- + "XORS\\t%0, %1, %2\\t%@ (*xors si xdb OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; scratch xor register ops setting the NOOV flags - needed to enable combines
- +(define_insn "*txor_<mode>_si_rr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (xor:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e,f,e,f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e,f,e,f"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=e,f,r,r"))]
- + "!TARGET_METAC_1_1 || TARGET_MTX"
- + "XORS\\t%0, %1, %2\\t%@ (*txor si xdd OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")])
- +
- +(define_insn "*txor_<mode>_si_ri"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (xor:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0, 0,0,0,e,f")
- + (match_operand:SI 2 "metag_int_operand" "IP,J,M,N,K,K"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=d, d,d,d,e,f"))]
- + ""
- + "@
- + XORS\\t%0, %1, %2\\t%@ (*txor si dI OK)
- + XORST\\t%0, %1, #HI(%c2)\\t%@ (*txor si dJ OK)
- + XORSMB\\t%0, %1, #LO(%c2)\\t%@ (*txor si dM OK)
- + XORSMT\\t%0, %1, #HI(%c2)\\t%@ (*txor si dN OK)
- + XORS\\t%0, %1, %2\\t\\t%@ (*txor si eK OK)
- + XORS\\t%0, %1, %2\\t\\t%@ (*txor si fK OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast")
- + (set_attr "ccstate" "set,set,set,set,set,set")])
- +
- +;; scratch xor register ops setting the NOOV flags - v1.1 case
- +(define_insn "*txor_<mode>_si_rr_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (xor:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e, f, e, f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "be,bf,be,bf"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=e, f, r, r"))]
- + "TARGET_METAC_1_1 && !TARGET_MTX"
- + "XORS\\t%0, %1, %2\\t%@ (*txor si xdd OK)"
- + [(set_attr "type" "fast,fast,slow,slow")
- + (set_attr "ccstate" "set,set,set,set")
- + (set_attr "o2rhint" "op2op1")])
- +
- +;; rotate instructions
- +(define_insn "rotsi2_16"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=d,e,f")
- + (rotate:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0,e,f")
- + (const_int 16)))]
- + ""
- + "RTDW\\t%0, %1"
- + [(set_attr "type" "fast,fast,fast")])
- +
- +(define_insn "parallel_rotsi2_16"
- + [(parallel
- + [(set (subreg:SI (match_operand:DI 0 "metag_datareg_op" "=d") 0)
- + (rotate:SI (subreg:SI (match_operand:DI 1 "metag_datareg_op" "d") 0)
- + (const_int 16)))
- + (set (subreg:SI (match_dup 0) 4)
- + (rotate:SI (subreg:SI (match_dup 1) 4)
- + (const_int 16)))])]
- + "TARGET_DSP"
- + "DL\\tRTDW\\t%0, %1"
- + [(set_attr "type" "fast")])
- +
- +;; arithmetic shift instructions
- +
- +(define_expand "ashlsi3"
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (ashift:SI (match_operand:SI 1 "metag_register_op" "")
- + (match_operand:SI 2 "metag_regorint_op" "")))]
- + ""
- + "")
- +
- +(define_insn "*ashlsi3"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,e,f,f,r,r,r,r")
- + (ashift:SI (match_operand:SI 1 "metag_reg_nofloat_op" "e,e,f,f,e,e,f,f")
- + (match_operand:SI 2 "metag_regorint_op" "e,L,f,L,e,L,f,L")))]
- + "!TARGET_MINIM_CORE"
- + "LSL%?\\t%0, %1, %2\\t%@ (*ashl si rrx OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes,no,no,no,no")])
- +
- +(define_insn "*ashlsi3_minim"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,e,!e,f,f,!f,r,r,r,r")
- + (ashift:SI (match_operand:SI 1 "metag_reg_nofloat_op" "e,0, e,f,0, f,e,e,f,f")
- + (match_operand:SI 2 "metag_regorint_op" "e,L, L,f,L, L,e,L,f,L")))]
- + "TARGET_MINIM_CORE"
- + "LSL%?\\t%0, %1, %2\\t%@ (*ashl si rrx OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes,yes,yes,no,no,no,no")])
- +
- +;; conditional version for specific cases of ashlsi3
- +(define_insn "*cond_<mode>_ashlsi3_rrr"
- + [(cond_exec
- + (match_operator 3 "comparison_operator"
- + [(match_operand:CCALL 4 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (set (match_operand:SI 0 "metag_datareg_op" "=e,f")
- + (ashift:SI (match_operand:SI 1 "metag_datareg_op" "e,f")
- + (match_operand:SI 2 "metag_datareg_op" "e,f"))))]
- + "reload_completed
- + && metag_same_regclass_p (operands[0], operands[1])
- + && metag_same_regclass_p (operands[0], operands[2])"
- + "@
- + LSL%?\\t%0, %1, %2\\t%@ (*ashl si eee OK)
- + LSL%?\\t%0, %1, %2\\t%@ (*ashl si fff OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "cond" "no")])
- +
- +(define_insn "*cond_<mode>_ashlsi3_rrL"
- + [(cond_exec
- + (match_operator 3 "comparison_operator"
- + [(match_operand:CCALL 4 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (set (match_operand:SI 0 "metag_datareg_op" "=e,f")
- + (ashift:SI (match_operand:SI 1 "metag_datareg_op" "e,f")
- + (match_operand:SI 2 "metag_L_operand" "L,L"))))]
- + "reload_completed
- + && metag_same_regclass_p (operands[0], operands[1])"
- + "@
- + LSL%?\\t%0, %1, %2\\t%@ (*ashl si eeL OK)
- + LSL%?\\t%0, %1, %2\\t%@ (*ashl si ffL OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "cond" "no")])
- +
- +(define_expand "ashrsi3"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,e,f,f,r,r,r,r")
- + (ashiftrt:SI (match_operand:SI 1 "metag_datareg_op" "e,e,f,f,e,e,f,f")
- + (match_operand:SI 2 "metag_regorint_op" "e,L,f,L,e,L,f,L")))]
- + ""
- + "")
- +
- +(define_insn "*ashrsi3"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,e,f,f,r,r,r,r")
- + (ashiftrt:SI (match_operand:SI 1 "metag_datareg_op" "e,e,f,f,e,e,f,f")
- + (match_operand:SI 2 "metag_regorint_op" "e,L,f,L,e,L,f,L")))]
- + "!TARGET_MINIM_CORE"
- + "ASR%?\\t%0, %1, %2\\t%@ (*ashr si rrx OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes,no,no,no,no")])
- +
- +(define_insn "*ashrsi3_minim"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,e,!e,f,f,!f,r,r,r,r")
- + (ashiftrt:SI (match_operand:SI 1 "metag_datareg_op" "e,0, e,f,0, f,e,e,f,f")
- + (match_operand:SI 2 "metag_regorint_op" "e,L, L,f,L, L,e,L,f,L")))]
- + "TARGET_MINIM_CORE"
- + "ASR%?\\t%0, %1, %2\\t%@ (*ashr si rrx OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes,yes,yes,no,no,no,no")])
- +
- +;; conditional version for specific cases of ashrsi3
- +(define_insn "*cond_<mode>_ashrsi3_rrr"
- + [(cond_exec
- + (match_operator 3 "comparison_operator"
- + [(match_operand:CCALL 4 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (set (match_operand:SI 0 "metag_datareg_op" "=e,f")
- + (ashiftrt:SI (match_operand:SI 1 "metag_datareg_op" "e,f")
- + (match_operand:SI 2 "metag_datareg_op" "e,f"))))]
- + "reload_completed
- + && metag_same_regclass_p (operands[0], operands[1])
- + && metag_same_regclass_p (operands[0], operands[2])"
- + "@
- + ASR%?\\t%0, %1, %2\\t%@ (*ashr si eee OK)
- + ASR%?\\t%0, %1, %2\\t%@ (*ashr si fff OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "cond" "no")])
- +
- +(define_insn "*cond_<mode>_ashrsi3_rrL"
- + [(cond_exec
- + (match_operator 3 "comparison_operator"
- + [(match_operand:CCALL 4 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (set (match_operand:SI 0 "metag_datareg_op" "=e,f")
- + (ashiftrt:SI (match_operand:SI 1 "metag_datareg_op" "e,f")
- + (match_operand:SI 2 "metag_L_operand" "L,L"))))]
- + "reload_completed
- + && metag_same_regclass_p (operands[0], operands[1])"
- + "@
- + ASR%?\\t%0, %1, %2\\t%@ (*ashr si eeL OK)
- + ASR%?\\t%0, %1, %2\\t%@ (*ashr si ffL OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "cond" "no")])
- +
- +(define_insn_and_split "*ashrdi3_32"
- + [(set (match_operand:DI 0 "metag_reg_nofloat_op" "=d,a")
- + (ashiftrt:DI (match_operand:DI 1 "metag_datareg_op" "d,d")
- + (const_int 32)))]
- + ""
- + "#"
- + "SPLIT_EARLY"
- + [(set (match_dup 2)
- + (match_dup 4))
- + (set (match_dup 3)
- + (ashiftrt:SI (match_dup 4)
- + (const_int 31)))]
- + {
- + if (reload_completed)
- + {
- + operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));
- + operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- +
- + operands[4] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
- + }
- + else
- + {
- + operands[2] = gen_rtx_SUBREG (SImode, operands[0], 0);
- + operands[3] = gen_rtx_SUBREG (SImode, operands[0], UNITS_PER_WORD);
- +
- + operands[4] = gen_rtx_SUBREG (SImode, operands[1], UNITS_PER_WORD);
- + }
- + }
- + [(set_attr "type" "two,slowslow")])
- +
- +;; logical shift instructions
- +
- +(define_expand "lshrsi3"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,e,f,f,r,r,r,r")
- + (lshiftrt:SI (match_operand:SI 1 "metag_reg_nofloat_op" "e,e,f,f,e,e,f,f")
- + (match_operand:SI 2 "metag_regorint_op" "e,L,f,L,e,L,f,L")))]
- + ""
- + "")
- +
- +(define_insn "*lshrsi3"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,e,f,f,r,r,r,r")
- + (lshiftrt:SI (match_operand:SI 1 "metag_reg_nofloat_op" "e,e,f,f,e,e,f,f")
- + (match_operand:SI 2 "metag_regorint_op" "e,L,f,L,e,L,f,L")))]
- + "!TARGET_MINIM_CORE"
- + "LSR%?\\t%0, %1, %2\\t%@ (lshr si rrx OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes,no,no,no,no")])
- +
- +(define_insn "*lshrsi3_minim"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,e,!e,f,f,!f,r,r,r,r")
- + (lshiftrt:SI (match_operand:SI 1 "metag_reg_nofloat_op" "e,0, e,f,0, f,e,e,f,f")
- + (match_operand:SI 2 "metag_regorint_op" "e,L, L,f,L, L,e,L,f,L")))]
- + "TARGET_MINIM_CORE"
- + "LSR%?\\t%0, %1, %2\\t%@ (lshr si rrx OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes,yes,yes,no,no,no,no")])
- +
- +;; conditional version for specific cases of lshrsi3
- +(define_insn "*cond_<mode>_lshrsi3_rrr"
- + [(cond_exec
- + (match_operator 3 "comparison_operator"
- + [(match_operand:CCALL 4 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (set (match_operand:SI 0 "metag_datareg_op" "=e,f")
- + (lshiftrt:SI (match_operand:SI 1 "metag_datareg_op" "e,f")
- + (match_operand:SI 2 "metag_datareg_op" "e,f"))))]
- + "reload_completed
- + && metag_same_regclass_p (operands[0], operands[1])
- + && metag_same_regclass_p (operands[0], operands[2])"
- + "@
- + LSR%?\\t%0, %1, %2\\t%@ (lshr si eee OK)
- + LSR%?\\t%0, %1, %2\\t%@ (lshr si fff OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "cond" "no")])
- +
- +(define_insn "*cond_<mode>_lshrsi3_rrL"
- + [(cond_exec
- + (match_operator 3 "comparison_operator"
- + [(match_operand:CCALL 4 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (set (match_operand:SI 0 "metag_datareg_op" "=e,f")
- + (lshiftrt:SI (match_operand:SI 1 "metag_datareg_op" "e,f")
- + (match_operand:SI 2 "metag_L_operand" "L,L"))))]
- + "reload_completed
- + && metag_same_regclass_p (operands[0], operands[1])"
- + "@
- + LSR%?\\t%0, %1, %2\\t%@ (lshr si eeL OK)
- + LSR%?\\t%0, %1, %2\\t%@ (lshr si ffL OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "cond" "no")])
- +
- +;; shift instructions combined with setting NOOV flags
- +
- +(define_insn "*ashls_<mode>_si_rrx"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (ashift:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e,e,f,f,e,e,f,f")
- + (match_operand:SI 2 "metag_regorint_op" "e,L,f,L,e,L,f,L"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=e,e,f,f,r,r,r,r")
- + (ashift:SI (match_dup 1)
- + (match_dup 2)))]
- + ""
- + "LSLS\\t%0, %1, %2\\t%@ (*ashls si rrx OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "ccstate" "set,set,set,set,set,set,set,set")])
- +
- +(define_insn "*ashrs_<mode>_si_rrx"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (ashiftrt:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e,e,f,f,e,e,f,f")
- + (match_operand:SI 2 "metag_regorint_op" "e,L,f,L,e,L,f,L"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=e,e,f,f,r,r,r,r")
- + (ashiftrt:SI (match_dup 1)
- + (match_dup 2)))]
- + ""
- + "ASRS\\t%0, %1, %2\\t%@ (*ashrs si rrx OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "ccstate" "set,set,set,set,set,set,set,set")])
- +
- +(define_insn "*lshrs_<mode>_si_rrx"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (lshiftrt:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e,e,f,f,e,e,f,f")
- + (match_operand:SI 2 "metag_regorint_op" "e,L,f,L,e,L,f,L"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_register_op" "=e,e,f,f,r,r,r,r")
- + (lshiftrt:SI (match_dup 1)
- + (match_dup 2)))]
- + ""
- + "LSRS\\t%0, %1, %2\\t%@ (lshrs si rrx OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "ccstate" "set,set,set,set,set,set,set,set")])
- +
- +;; shift instructions setting NOOV flags using scratch
- +(define_insn "*tashls_<mode>_si_rrx"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (ashift:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e,e,f,f,e,e,f,f")
- + (match_operand:SI 2 "metag_regorint_op" "e,L,f,L,e,L,f,L"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=e,e,f,f,r,r,r,r"))]
- + ""
- + "LSLS\\t%0, %1, %2\\t%@ (tashls si rrx OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "ccstate" "set,set,set,set,set,set,set,set")])
- +
- +(define_insn "*tashrs_<mode>_si_rrx"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (ashiftrt:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e,e,f,f,e,e,f,f")
- + (match_operand:SI 2 "metag_regorint_op" "e,L,f,L,e,L,f,L"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=e,e,f,f,r,r,r,r"))]
- + ""
- + "ASRS\\t%0, %1, %2\\t%@ (tashrs si rrx OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "ccstate" "set,set,set,set,set,set,set,set")])
- +
- +(define_insn "*tlshrs_<mode>_si_rrx"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (lshiftrt:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e,e,f,f,e,e,f,f")
- + (match_operand:SI 2 "metag_regorint_op" "e,L,f,L,e,L,f,L"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=e,e,f,f,r,r,r,r"))]
- + ""
- + "LSRS\\t%0, %1, %2\\t%@ (tlshrs si rrx OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "ccstate" "set,set,set,set,set,set,set,set")])
- +
- +;; negate instructions
- +
- +;; DImode negate
- +(define_expand "negdi2"
- + [(parallel
- + [(set (match_operand:DI 0 "metag_reg_nofloat_op" "")
- + (neg:DI (match_operand:DI 1 "metag_reg_nofloat_op" "")))
- + (clobber (reg:CC CC_REG))])]
- + ""
- + "")
- +
- +(define_insn_and_split "*negdi2"
- + [(set (match_operand:DI 0 "metag_reg_nofloat_op" "=d")
- + (neg:DI (match_operand:DI 1 "metag_reg_nofloat_op" "d")))
- + (clobber (reg:CC CC_REG))]
- + ""
- + "#"
- + "SPLIT_EARLY"
- + [(parallel
- + [(set (reg:CC_Z CC_REG)
- + (compare:CC_Z (neg:SI (match_dup 5))
- + (const_int 0)))
- + (set (match_dup 3)
- + (neg:SI (match_dup 5)))])
- + (set (match_dup 4)
- + (neg:SI (match_dup 6)))
- + (set (match_dup 4)
- + (if_then_else:SI (ne (reg:CC_Z CC_REG)
- + (const_int 0))
- + (plus:SI (match_dup 4)
- + (const_int -1))
- + (match_dup 4)))]
- + {
- + if (reload_completed)
- + {
- + operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
- + operands[4] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- +
- + operands[5] = gen_rtx_REG (SImode, REGNO (operands[1]));
- + operands[6] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
- + }
- + else
- + {
- + operands[3] = gen_rtx_SUBREG (SImode, operands[0], 0);
- + operands[4] = gen_rtx_SUBREG (SImode, operands[0], UNITS_PER_WORD);
- +
- + operands[5] = gen_rtx_SUBREG (SImode, operands[1], 0);
- + operands[6] = gen_rtx_SUBREG (SImode, operands[1], UNITS_PER_WORD);
- + }
- + }
- + [(set_attr "type" "three")
- + (set_attr "ccstate" "ccx")])
- +
- +;; SImode negate
- +(define_expand "negsi2"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (neg:SI (match_operand:SI 1 "metag_reg_nofloat_op" "")))]
- + ""
- + "")
- +
- +(define_insn "*negsi2"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,f")
- + (neg:SI (match_operand:SI 1 "metag_reg_nofloat_op" "e,f")))]
- + "!TARGET_METAC_1_1"
- + "NEG\\t%0, %1\\t\\t%@ (neg si dd OK)"
- + [(set_attr "type" "fast,fast")])
- +
- +(define_insn "*negs_<mode>_si_rr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (neg:SI (match_operand:SI 1 "metag_reg_nofloat_op" "e,f"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,f")
- + (neg:SI (match_dup 1)))]
- + "!TARGET_METAC_1_1"
- + "NEGS\\t%0, %1\\t\\t%@ (negs si dd OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "ccstate" "set,set")])
- +
- +(define_insn "*tneg_<mode>_si_rr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (neg:SI (match_operand:SI 1 "metag_reg_nofloat_op" "e,f"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=e,f"))]
- + "!TARGET_METAC_1_1"
- + "NEGS\\t%0, %1\\t\\t%@ (tneg si dd OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "ccstate" "set,set")])
- +
- +;; negate instructions - v1.1 case
- +(define_insn "*negsi2_1_1"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e, f")
- + (neg:SI (match_operand:SI 1 "metag_reg_nofloat_op" "be,bf")))]
- + "TARGET_METAC_1_1 && !TARGET_MINIM_CORE"
- + "NEG\\t%0, %1\\t\\t%@ (neg si db OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "o2rhint" "op1op0")])
- +
- +;; negate instructions - minim case
- +(define_insn "*negsi2_minim"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,!e, f,!f")
- + (neg:SI (match_operand:SI 1 "metag_reg_nofloat_op" "e, be,f, bf")))]
- + "TARGET_METAC_1_1 && TARGET_MINIM_CORE"
- + "NEG\\t%0, %1\\t\\t%@ (neg si db OK)"
- + [(set_attr "type" "fast,fast,fast,fast")
- + (set_attr "o2rhint" "op1op0")])
- +
- +(define_insn "*negs_<mode>_si_rr_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (neg:SI (match_operand:SI 1 "metag_reg_nofloat_op" "be,bf"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_reg_nofloat_op" "=e, f")
- + (neg:SI (match_dup 1)))]
- + "TARGET_METAC_1_1"
- + "NEGS\\t%0, %1\\t\\t%@ (negs si db OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "ccstate" "set,set")
- + (set_attr "o2rhint" "op1op0")])
- +
- +(define_insn "*tneg_<mode>_si_rr_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (neg:SI (match_operand:SI 1 "metag_reg_nofloat_op" "be,bf"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=e, f"))]
- + "TARGET_METAC_1_1"
- + "NEGS\\t%0, %1\\t\\t%@ (tneg si dx OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "ccstate" "set,set")
- + (set_attr "o2rhint" "op1op0")])
- +
- +;; complement instructions
- +(define_insn "one_cmplsi2"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,f,&e,&f")
- + (not:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0,0, e, f")))]
- + ""
- + "@
- + XOR\\t%0, %1, #-1\\t%@ (not si e0 OK)
- + XOR\\t%0, %1, #-1\\t%@ (not si f0 OK)
- + #
- + #"
- + [(set_attr "type" "fast,fast,two,two")])
- +
- +;; Split the above insn if it needs more than one insn
- +(define_split
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (not:SI (match_operand:SI 1 "metag_reg_nofloat_op" "")))]
- + "reload_completed
- + && REGNO (operands[0]) != REGNO (operands[1])"
- + [(set (match_dup 0)
- + (const_int -1))
- + (set (match_dup 0)
- + (xor:SI (match_dup 0)
- + (match_dup 1)))]
- + "")
- +
- +(define_insn "*nots_<mode>_si_rr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (not:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0,0, e, f"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,f,&e,&f")
- + (not:SI (match_dup 1)))]
- + ""
- + "@
- + XORS\\t%0, %1, #-1\\t%@ (nots si e0 OK)
- + XORS\\t%0, %1, #-1\\t%@ (nots si f0 OK)
- + #
- + #"
- + [(set_attr "type" "fast,fast,two,two")
- + (set_attr "ccstate" "set,set,fastset,fastset")])
- +
- +;; Split the above insn if it needs more than one insn
- +(define_split
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (not:SI (match_operand:SI 1 "metag_reg_nofloat_op" ""))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (not:SI (match_dup 1)))]
- + "reload_completed
- + && REGNO (operands[0]) != REGNO (operands[1])"
- + [(set (match_dup 0)
- + (const_int -1))
- + (parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (xor:SI (match_dup 0)
- + (match_dup 1))
- + (const_int 0)))
- + (set (match_dup 0)
- + (xor:SI (match_dup 0)
- + (match_dup 1)))])]
- + "")
- +
- +(define_insn "*tnot_<mode>_si_rr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (not:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0,0, e, f"))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 "=e,f,&e,&f"))]
- + ""
- + "@
- + XORS\\t%0, %1, #-1\\t%@ (tnot si e0 OK)
- + XORS\\t%0, %1, #-1\\t%@ (tnot si f0 OK)
- + #
- + #"
- + [(set_attr "type" "fast,fast,two,two")
- + (set_attr "ccstate" "set,set,fastset,fastset")])
- +
- +;; Split the above insn if it needs more than one insn.
- +(define_split
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (not:SI (match_operand:SI 1 "metag_reg_nofloat_op" ""))
- + (const_int 0)))
- + (clobber (match_scratch:SI 0 ""))]
- + "reload_completed
- + && REGNO (operands[0]) != REGNO (operands[1])"
- + [(set (match_dup 0)
- + (const_int -1))
- + (parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (xor:SI (match_dup 0)
- + (match_dup 1))
- + (const_int 0)))
- + (set (match_dup 0)
- + (xor:SI (match_dup 0)
- + (match_dup 1)))])]
- + "")
- +
- +
- +;; Comparison operations
- +
- +(define_expand "cmpsi"
- + [(match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (match_operand:SI 1 "metag_regorint_op" "")]
- + ""
- + {
- + /* These are processed via the conditional branch define_expand's later */
- + metag_compare_op0 = operands[0];
- + metag_compare_op1 = operands[1];
- +
- + if (CONST_INT_P (operands[1])
- + && METAG_LETTER_FOR_CONST (operands[1]) == 0)
- + {
- + /* Have to do register to register comparison for big constants */
- + metag_compare_op1 = force_reg (SImode, operands[1]);
- + }
- +
- + DONE;
- + }
- +)
- +
- +;; compare si instruction
- +(define_insn "*cmpsi_<mode>_rr"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCANY
- + (match_operand:SI 0 "metag_reg_nofloat_op" "e,f")
- + (match_operand:SI 1 "metag_reg_nofloat_op" "e,f")))]
- + "!TARGET_METAC_1_1"
- + "@
- + CMP\\t%0, %1\\t\\t%@ (*cmpsi ee OK)
- + CMP\\t%0, %1\\t\\t%@ (*cmpsi ff OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "ccstate" "set,set")])
- +
- +(define_insn "*cmpsi_<mode>_ri"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCANY
- + (match_operand:SI 0 "metag_reg_nofloat_op" "d,d, d,d,d")
- + (match_operand:SI 1 "metag_int_operand" "K,IP,J,M,N")))]
- + ""
- + "@
- + CMP\\t%0, %1\\t\\t%@ (*cmpsi dI OK)
- + CMP\\t%0, %1\\t\\t%@ (*cmpsi dI OK)
- + CMPT\\t%0, #HI(%c1)\\t\\t%@ (*cmpsi dJ OK)
- + CMPMB\\t%0, #LO(%c1)\\t\\t%@ (*cmpsi dM OK)
- + CMPMT\\t%0, #HI(%c1)\\t\\t%@ (*cmpsi dN OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast")
- + (set_attr "ccstate" "set,set,set,set,set")])
- +
- +;; compare si instruction - v1.1 case
- +(define_insn "*cmpsi_rr_1_1"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCANY
- + (match_operand:SI 0 "metag_reg_nofloat_op" "e, f")
- + (match_operand:SI 1 "metag_reg_nofloat_op" "be,bf")))]
- + "TARGET_METAC_1_1"
- + "@
- + CMP\\t%0, %1\\t\\t%@ (*cmpsi eb OK)
- + CMP\\t%0, %1\\t\\t%@ (*cmpsi fb OK)"
- + [(set_attr "type" "fast,fast")
- + (set_attr "ccstate" "set,set")
- + (set_attr "o2rhint" "op1op0")])
- +
- +;; compare hi instruction for zero flag
- +(define_insn "*tst_zhi"
- + [(set (reg:CC_Z CC_REG)
- + (compare:CC_Z
- + (match_operand:HI 0 "metag_datareg_op" "d")
- + (const_int 0)))]
- + ""
- + "TST\\t%0, #0xFFFF\\t%@ (*tst zhi d OK)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +;; compare qi instruction for zero flag
- +(define_insn "*tst_zqi"
- + [(set (reg:CC_Z CC_REG)
- + (compare:CC_Z
- + (match_operand:QI 0 "metag_datareg_op" "d")
- + (const_int 0)))]
- + ""
- + "TST\\t%0, #255\\t%@ (*tst zqi d OK)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +;; Copy and compare combines the flag setup with a move
- +;; Note MOVS/ADDS for DU -> FX is allowed but FX -> DU is not
- +(define_insn "*cmpsi_movsi_<mode>_eq0"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (match_operand:SI 1 "metag_datareg_op" "e,f,d")
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,f,da")
- + (match_dup 1))]
- + ""
- + "ADDS\\t%0, %1, #0\\t\\t%@ (*movs si rr OK)"
- + [(set_attr "type" "fast,fast,slow")
- + (set_attr "ccstate" "set")])
- +
- +(define_insn "*cmpsi_movsi_cc_eq0"
- + [(set (reg:CC CC_REG)
- + (compare:CC
- + (match_operand:SI 1 "metag_datareg_op" "e,f,d")
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,f,da")
- + (match_dup 1))]
- + ""
- + "SUBS\\t%0, %1, #0\\t\\t%@ (*movs si rr OK)"
- + [(set_attr "type" "fast,fast,slow")
- + (set_attr "ccstate" "set")])
- +
- +;; min instruction
- +
- +(define_insn "sminsi3"
- + [(set (match_operand:SI 0 "metag_datareg_op" "=e,f")
- + (smin:SI (match_operand:SI 1 "metag_datareg_op" "%e,f")
- + (match_operand:SI 2 "metag_datareg_op" "e,f")))
- + (clobber (reg:CC CC_REG))]
- + "!TARGET_METAC_0_1"
- + "MIN\\t%0, %1, %2\\t%@ (*min si ddd OK)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "ccx")])
- +
- +;; max instruction
- +
- +(define_insn "smaxsi3"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,f")
- + (smax:SI (match_operand:SI 1 "metag_reg_nofloat_op" "%e,f")
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e,f")))
- + (clobber (reg:CC CC_REG))]
- + "!TARGET_METAC_0_1"
- + "MAX\\t%0, %1, %2\\t%@ (*max si ddd OK)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "ccx")])
- +
- +;; abs instruction
- +
- +(define_insn "abssi2"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,f")
- + (abs:SI (match_operand:SI 1 "metag_reg_nofloat_op" "e,f")))
- + (clobber (reg:CC CC_REG))]
- + "!TARGET_METAC_0_1"
- + "ABS\\t%0, %1\\t%@ (*abs si dd OK)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "ccx")])
- +
- +;; Conditional move support
- +(define_expand "movsicc"
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (if_then_else:SI (match_operand 1 "comparison_operator" "")
- + (match_operand:SI 2 "metag_regorint_op" "")
- + (match_operand:SI 3 "metag_regorint_op" "")))]
- + ""
- + {
- + enum rtx_code code = GET_CODE (operands[1]);
- + enum machine_mode mode;
- + rtx ccreg;
- +
- + if (CONST_INT_P (operands[2]) && CONST_INT_P (operands[3]))
- + {
- + /* Can only support -255 to 255 delta between constants */
- + HOST_WIDE_INT op2_mi_op3 = INTVAL (operands[2]) - INTVAL (operands[3]);
- + rtx value = GEN_INT (op2_mi_op3);
- +
- + if (satisfies_constraint_P (value)
- + || satisfies_constraint_K (value))
- + {
- + rtx temp = (reload_in_progress || reload_completed)
- + ? operands[0] : gen_reg_rtx (SImode);
- +
- + emit_move_insn (temp, operands[3]);
- + operands[2] = gen_rtx_PLUS (SImode, temp, value);
- + operands[3] = temp;
- + }
- + }
- +
- + if (CONST_INT_P (operands[3]))
- + {
- + /* Make second source operand a register */
- + operands[3] = force_reg (SImode, operands[3]);
- + }
- +
- + if (CONST_INT_P (operands[2]))
- + {
- + /* Make first source operand a register! */
- + operands[2] = force_reg (SImode, operands[2]);
- + }
- +
- + /* Generate correct comparison insn */
- + mode = SELECT_CC_MODE (code, metag_compare_op0, metag_compare_op1);
- + ccreg = gen_rtx_REG (mode, CC_REG);
- + emit_insn (gen_rtx_SET (VOIDmode, ccreg,
- + gen_rtx_COMPARE (mode, metag_compare_op0, metag_compare_op1)));
- +
- + /* Expand condition to act on result */
- + operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
- + }
- +)
- +
- +(define_insn "*mov_if_<mode>_rr0"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,f,h,l,da")
- + (if_then_else:SI (match_operator 1 "comparison_operator"
- + [(match_operand:CCALL 2 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (match_operand:SI 3 "metag_reg_nofloat_op" "e,f,h,l,da")
- + (match_operand:SI 4 "metag_reg_nofloat_op" "0,0,0,0,0")))]
- + ""
- + "MOV%z1\\t%0, %3\\t%@ (*mov if <mode> rr0 OK)"
- + [(set_attr "type" "fast,fast,fast,fast,slow")
- + (set_attr "ccstate" "xcc,xcc,xcc,xcc,xcc")])
- +
- +;; Conditional add is targeted by expansion of if_then_else(const, const)
- +(define_insn "*add_if_<mode>_r0KP"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=e,f,h,l,e,f,h,l")
- + (if_then_else:SI (match_operator 1 "comparison_operator"
- + [(match_operand:CCALL 2 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (plus:SI (match_operand:SI 3 "metag_regnofrm_op" "e,f,h,l,e,f,h,l")
- + (match_operand:SI 4 "metag_smallint_op" "K,K,K,K,P,P,P,P"))
- + (match_operand:SI 5 "metag_reg_nofloat_op" "0,0,0,0,0,0,0,0")))]
- + ""
- + "@
- + ADD%z1\\t%0, %3, %4\\t\\t%@ (*add if eeK OK)
- + ADD%z1\\t%0, %3, %4\\t\\t%@ (*add if ffK OK)
- + ADD%z1\\t%0, %3, %4\\t\\t%@ (*add if hhK OK)
- + ADD%z1\\t%0, %3, %4\\t\\t%@ (*add if llK OK)
- + SUB%z1\\t%0, %3, #%n4\\t\\t%@ (*sub if eeP OK)
- + SUB%z1\\t%0, %3, #%n4\\t\\t%@ (*sub if ffP OK)
- + SUB%z1\\t%0, %3, #%n4\\t\\t%@ (*sub if hhP OK)
- + SUB%z1\\t%0, %3, #%n4\\t\\t%@ (*sub if llP OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,fast,fast,fast")
- + (set_attr "ccstate" "xcc,xcc,xcc,xcc,xcc,xcc,xcc,xcc")])
- +
- +
- +;; zero/sign extend instructions
- +
- +(define_insn_and_split "zero_extendsidi2"
- + [(set (match_operand:DI 0 "metag_reg_nofloat_op" "=da")
- + (zero_extend:DI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "da")))]
- + ""
- + "#"
- + "SPLIT_EARLY"
- + [(set (match_dup 2)
- + (match_dup 1))
- + (set (match_dup 3)
- + (const_int 0))]
- + {
- + if (reload_completed)
- + {
- + operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));
- + operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- + }
- + else
- + {
- + operands[2] = gen_rtx_SUBREG (SImode, operands[0], 0);
- + operands[3] = gen_rtx_SUBREG (SImode, operands[0], UNITS_PER_WORD);
- + }
- + }
- + [(set_attr "type" "two")]
- +)
- +
- +(define_expand "zero_extendhisi2"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (zero_extend:SI
- + (match_operand:HI 1 "metag_datareg_op" "")))]
- + ""
- + {
- + }
- +)
- +
- +(define_insn_and_split "*zero_extendhisi2"
- + [(set (match_operand:SI 0 "metag_datareg_op" "=d")
- + (zero_extend:SI
- + (match_operand:HI 1 "metag_datareg_op" "0")))]
- + ""
- + "#"
- + "SPLIT_EARLY"
- + [(set (match_dup 0)
- + (and:SI (match_dup 1)
- + (match_dup 2)))]
- + {
- + operands[1] = gen_lowpart (SImode, operands[1]);
- + operands[2] = gen_int_mode (0xFFFF, SImode);
- + })
- +
- +(define_expand "zero_extendqisi2"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (zero_extend:SI
- + (match_operand:QI 1 "metag_datareg_op" "")))]
- + ""
- + {
- + }
- +)
- +
- +(define_insn_and_split "*zero_extendqisi2"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (zero_extend:SI
- + (match_operand:QI 1 "metag_datareg_op" "d")))]
- + ""
- + "#"
- + "SPLIT_EARLY"
- + [(set (match_dup 0)
- + (and:SI (match_dup 1)
- + (match_dup 2)))]
- + {
- + operands[1] = gen_lowpart (SImode, operands[1]);
- + operands[2] = gen_int_mode (0xFF, SImode);
- + })
- +
- +(define_insn_and_split "extendsidi2"
- + [(set (match_operand:DI 0 "metag_reg_nofloat_op" "=d,d,a")
- + (sign_extend:DI
- + (match_operand:SI 1 "metag_datareg_op" "f,e,d")))]
- + ""
- + "#"
- + "SPLIT_EARLY"
- + [(set (match_dup 2)
- + (match_dup 1))
- + (set (match_dup 3)
- + (ashiftrt:SI (match_dup 1)
- + (const_int 31)))]
- + {
- + if (reload_completed)
- + {
- + operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));
- + operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- + }
- + else
- + {
- + operands[2] = gen_rtx_SUBREG (SImode, operands[0], 0);
- + operands[3] = gen_rtx_SUBREG (SImode, operands[0], UNITS_PER_WORD);
- + }
- + }
- + [(set_attr "type" "two,slowslow,slowslow")]
- +)
- +
- +(define_expand "extendhisi2"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (sign_extend:SI
- + (match_operand:HI 1 "metag_datareg_op" "")))]
- + ""
- + {
- + }
- +)
- +
- +(define_expand "extendqisi2"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (sign_extend:SI
- + (match_operand:QI 1 "metag_datareg_op" "")))]
- + ""
- + {
- + }
- +)
- +
- +;; -----------------------------------------------------------------------------
- +;; | Matching zero extends loads to HI post/pre_inc/dec/modify
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lodz_<mode>hi_post_inc"
- + [(set (match_operand:HI 0 "metag_register_op" "=cr")
- + (zero_extend:HI
- + (mem:EXTHI
- + (post_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da")))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%0, [%1++]\\t%@ (*lodz <MODE> HI post_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lodz_<mode>hi_post_dec"
- + [(set (match_operand:HI 0 "metag_register_op" "=cr")
- + (zero_extend:HI
- + (mem:EXTHI
- + (post_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da")))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%0, [%1--]\\t%@ (*lodz <MODE> HI post_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lodz_<mode>hi_pre_inc"
- + [(set (match_operand:HI 0 "metag_register_op" "=cr")
- + (zero_extend:HI
- + (mem:EXTHI
- + (pre_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da")))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%0, [++%1]\\t%@ (*lodz <MODE> HI pre_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lodz_<mode>hi_pre_dec"
- + [(set (match_operand:HI 0 "metag_register_op" "=cr")
- + (zero_extend:HI
- + (mem:EXTHI
- + (pre_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da")))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%0, [--%1]\\t%@ (*lodz <MODE> HI pre_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lodz_<mode>hi_post_modify_disp"
- + [(set (match_operand:HI 0 "metag_register_op" "=cr")
- + (zero_extend:HI
- + (mem:EXTHI
- + (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_<mode>" "<O>"))))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%0, [%1+%2++]\\t%@ (*load <MODE> HI post_modify_disp OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lodz_<mode>hi_post_modify_reg"
- + [(set (match_operand:HI 0 "metag_register_op" "=cr,cr,cr,cr")
- + (zero_extend:HI
- + (mem:EXTHI
- + (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l"))))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%0, [%1+%2++]\\t%@ (*lodz <MODE> HI post_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lodz_<mode>hi_pre_modify_disp"
- + [(set (match_operand:HI 0 "metag_reg_nofloat_op" "=da")
- + (zero_extend:HI
- + (mem:EXTHI
- + (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_<mode>" "<O>"))))))]
- + ""
- + "GET<W>\\t%0, [%1++%2]\\t%@ (*lodz <MODE> HI pre_modify_disp OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lodz_<mode>hi_pre_modify_reg"
- + [(set (match_operand:HI 0 "metag_register_op" "=cr,cr,cr,cr")
- + (zero_extend:HI
- + (mem:EXTHI
- + (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l"))))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%0, [%1++%2]\\t%@ (*lodz <MODE> HI pre_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; zero_extend loads to SI from EXTSI mode using base+index
- +(define_insn "*lodz_<mode>si_rma"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr,cr,cr,cr")
- + (zero_extend:SI
- + (mem:EXTSI
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "e, f, h, l")
- + (match_operand:SI 2 "metag_regnofrm_op" "e, f, h, l")))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%0, [%1+%2]\\t%@ (*lodz <MODE> SI rma OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +;; zero_extend loads to SI from EXTSI mode using base+offset6
- +(define_insn "*lodz_<mode>si_rmi"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr")
- + (zero_extend:SI
- + (mem:EXTSI
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "da")
- + (match_operand:SI 2 "metag_offset6_<mode>" "<O>")))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%0, [%1+%2]\\t%@ (*lodz <MODE> SI rmi OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +;; zero_extend loads to SI from EXTSI mode using base+offset12
- +(define_insn "*lodz_<mode>si_rmi"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da, da")
- + (zero_extend:SI
- + (mem:EXTSI
- + (plus:SI (match_operand:SI 1 "metag_reg12bit_op" "da, Yr")
- + (match_operand:SI 2 "metag_offset12_<mode>" "<O>,<Z>")))))]
- + ""
- + "GET<W>\\t%0, [%1+%2]\\t%@ (*lodz <MODE> SI rmi OK)"
- + [(set_attr "type" "load")])
- +
- +;; zero_extend loads to SI from EXTSI mode using base++index
- +(define_insn "*lodz_<mode>si_rmab"
- + [(set (match_operand:SI 3 "metag_register_op" "=cr,cr,cr,cr")
- + (zero_extend:SI
- + (mem:EXTSI
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "%0, 0, 0, 0")
- + (match_operand:SI 2 "metag_regnofrm_op" "e, f, h, l")))))
- + (set (match_operand:SI 0 "metag_regnofrm_op" "=e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "0"
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%3, [%1++%2]\\t%@ (*lodz <MODE> SI rmab OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[3])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +;; zero_extend loads to SI from EXTSI mode using base++increment
- +(define_insn "*lodz_<mode>si_rmib"
- + [(set (match_operand:SI 3 "metag_register_op" "=cr")
- + (zero_extend:SI
- + (mem:EXTSI
- + (plus:SI (match_operand:SI 1 "metag_regnofrm_op" "0")
- + (match_operand:SI 2 "metag_offset6_<mode>" "<O>")))))
- + (set (match_operand:SI 0 "metag_regnofrm_op" "=da")
- + (plus:SI (match_dup 1)
- + (match_dup 2)))]
- + "0"
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%3, [%1++%2]\\t%@ (*lodz <MODE> SI rmib OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[3])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; -----------------------------------------------------------------------------
- +;; | Matching zero extend loads to SI post/pre_inc/dec/modify |
- +;; -----------------------------------------------------------------------------
- +
- +(define_insn "*lodz_<mode>si_post_inc"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr")
- + (zero_extend:SI (mem:EXTSI
- + (post_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da")))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%0, [%1++]\\t%@ (*lodz <MODE> SI post_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lodz_<mode>si_post_dec"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr")
- + (zero_extend:SI (mem:EXTSI
- + (post_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da")))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%0, [%1--]\\t%@ (*lodz <MODE> SI post_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lodz_<mode>si_pre_inc"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr")
- + (zero_extend:SI (mem:EXTSI
- + (pre_inc:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da")))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%0, [++%1]\\t%@ (*lodz <MODE> SI pre_inc OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lodz_<mode>si_pre_dec"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr")
- + (zero_extend:SI (mem:EXTSI
- + (pre_dec:SI (match_operand:SI 1 "metag_reg_nofloat_op" "+da")))))]
- + "TARGET_METAC_1_1"
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%0, [--%1]\\t%@ (*lodz <MODE> SI pre_dec OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lodz_<mode>si_post_modify_disp"
- + [(set (match_operand:SI 0 "metag_register_op" "=r")
- + (zero_extend:SI (mem:EXTSI
- + (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_<mode>" "<O>"))))))]
- + ""
- + "GET<W>\\t%0, [%1+%2++]\\t%@ (*lodz <MODE> SI post_modify_disp OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lodz_<mode>si_post_modify_reg"
- + [(set (match_operand:SI 0 "metag_register_op" "=cr,cr,cr,cr")
- + (zero_extend:SI (mem:EXTSI
- + (post_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l"))))))]
- + ""
- + {
- + static const char fmt[] = "F\\tGET<W>\\t%0, [%1+%2++]\\t%@ (*lodz <MODE> SI post_modify_reg OK)";
- +
- + return &fmt[METAG_FPC_REG_P (REGNO (operands[0])) ? 0 : 2];
- + }
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lodz_<mode>si_pre_modify_disp"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (zero_extend:SI (mem:EXTSI
- + (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+da")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_<mode>" "<O>"))))))]
- + ""
- + "GET<W>\\t%0, [%1++%2]\\t%@ (*load <MODE> SI pre_modify_disp OK)"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*lodz_<mode>si_pre_modify_reg"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da,da,da,da")
- + (zero_extend:SI (mem:EXTSI
- + (pre_modify:SI
- + (match_operand:SI 1 "metag_reg_nofloat_op" "+e, f, h, l")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" "e, f, h, l"))))))]
- + ""
- + "GET<W>\\t%0, [%1++%2]\\t%@ (*loadz <MODE> SI pre_modify_reg OK)"
- + [(set_attr "type" "load")])
- +
- +;; zero_extend loads to SI from EXTSI mode - rest expanded as AND operations
- +(define_insn "*lodz_<mode>si"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (zero_extend:SI (match_operand:EXTSI 1 "memory_operand" "m")))]
- + ""
- + "GET<W>\\t%0, %1\\t%@ (*lodz <MODE> SI rm OK)"
- + [(set_attr "type" "load")])
- +
- +;; -----------------------------------------------------------------------------
- +
- +;; Sign extend register to SI mode register moves
- +(define_insn "*sign_extend_<mode>si"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=d,e,f")
- + (sign_extend:SI (match_operand:EXTSI 1 "metag_reg_nofloat_op" "0,e,f")))]
- + ""
- + "@
- + XSD<W>\\t%0, %1\\t\\t%@ (*ext <MODE> SI d0 OK)
- + XSD<W>\\t%0, %1\\t\\t%@ (*ext <MODE> SI ee OK)
- + XSD<W>\\t%0, %1\\t\\t%@ (*ext <MODE> SI ff OK)"
- + [(set_attr "type" "fast,fast,fast")])
- +
- +(define_insn "*sign_extend_hisi_<mode>"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (sign_extend:SI (match_operand:HI 1 "metag_datareg_op" "0,e,f"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "=d,e,f")
- + (sign_extend:SI (match_dup 1)))]
- + ""
- + "XSDSW\\t%0, %1\\t\\t%@ (*exts HI SI dd OK)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +(define_insn "*sign_extend_qisi_<mode>"
- + [(set (reg:<MODE> CC_REG)
- + (compare:CCZNC
- + (sign_extend:SI (match_operand:QI 1 "metag_datareg_op" "0,e,f"))
- + (const_int 0)))
- + (set (match_operand:SI 0 "metag_datareg_op" "=d,e,f")
- + (sign_extend:SI (match_dup 1)))]
- + ""
- + "XSDSB\\t%0, %1\\t\\t%@ (*exts QI SI dd OK)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +;; bit field instructions
- +
- +
- +;; Low overhead loop support
- +;; operand 0 is the loop count pseudo register
- +;; operand 1 is the number of loop iterations or 0 if it is unknown
- +;; operand 2 is the maximum number of loop iterations or -1 if unknown
- +;; operand 3 is the number of levels of enclosed loops
- +;; operand 4 is the label to jump to at the top of the loop
- +(define_expand "doloop_end"
- + [(use (match_operand 0 "" ""))
- + (use (match_operand:SI 1 "const_int_operand" ""))
- + (use (match_operand:SI 2 "const_int_operand" ""))
- + (use (match_operand:SI 3 "const_int_operand" ""))
- + (use (label_ref (match_operand 4 "" "")))]
- + ""
- + {
- + enum machine_mode mode = GET_MODE (operands[0]);
- +
- + if (mode == SImode && INTVAL (operands[3]) != -1)
- + {
- + unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
- + unsigned HOST_WIDE_INT num_iterations = INTVAL (operands[1]) & mask;
- + unsigned HOST_WIDE_INT max_iterations = INTVAL (operands[2]) & mask;
- + unsigned HOST_WIDE_INT limit = INTVAL (gen_int_mode (0xFFFFFFFF, SImode)) & mask;
- +
- + if (!(num_iterations > limit || (num_iterations == 0 && max_iterations > limit)))
- + {
- + emit_jump_insn (gen_br_si_txrpt (operands[4], operands[0]));
- + DONE;
- + }
- + }
- +
- + FAIL;
- + }
- +)
- +
- +(define_insn "br_si_txrpt"
- + [(set (pc)
- + (if_then_else (ne (match_operand:SI 1 "metag_txrpt_op" "+Wx")
- + (const_int 0))
- + (label_ref (match_operand 0 "" ""))
- + (pc)))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (const_int -1)))
- + (clobber (reg:CC_NOOV CC_REG))]
- + ""
- + "BR\\t%c0"
- + [(set_attr "type" "branch")
- + (set_attr "ccstate" "ccx")])
- +
- +
- +;; conditional branch instruction generators; expand previous compare
- +
- +(define_expand "b<code>"
- + [(set (pc)
- + (if_then_else (CCANYCOND (match_dup 1)
- + (const_int 0))
- + (label_ref (match_operand 0 "" ""))
- + (pc)))]
- + ""
- + {
- + if (!gen_metag_compare (<CODE>, operands, 1))
- + FAIL;
- + }
- +)
- +
- +;; patterns to match conditional branch insns
- +
- +(define_insn "*b<mode>"
- + [(set (pc)
- + (if_then_else (match_operator 1 "comparison_operator"
- + [(match_operand:CCALL 2 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (label_ref (match_operand 0 "" ""))
- + (pc)))]
- + ""
- + {
- + if (metag_consume_branch (insn))
- + return "";
- +
- + return "B%z1\\t%c0\\t\\t\\t%@ (*b<mode> OK)";
- + }
- + [(set_attr "type" "branch")
- + (set_attr "ccstate" "xcc")])
- +
- +(define_insn "*b<mode>_reversed"
- + [(set (pc)
- + (if_then_else (match_operator 1 "comparison_operator"
- + [(match_operand:CCALL 2 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (pc)
- + (label_ref (match_operand 0 "" ""))))]
- + ""
- + {
- + if (metag_consume_branch (insn))
- + return "";
- +
- + return "B%Z1\\t%c0\\t\\t\\t%@ (*b<mode> rev OK)";
- + }
- + [(set_attr "type" "branch")
- + (set_attr "ccstate" "xcc")])
- +
- +;; condition status evaluation
- +(define_expand "s<code>"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (CCANYCOND:SI (match_dup 1)
- + (const_int 0)))]
- + ""
- + {
- + if (!gen_metag_compare (<CODE>, operands, 1))
- + FAIL;
- + }
- +)
- +
- +;; patterns to match condition status insns
- +(define_insn_and_split "*movsi_m<mode>"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (match_operator:SI 1 "comparison_operator"
- + [(match_operand:CCALL 2 "metag_<mode>_reg" "")
- + (const_int 0)]))]
- + ""
- + "#"
- + "reload_completed"
- + [(set (match_dup 0)
- + (const_int 0))
- + (set (match_dup 0)
- + (if_then_else:SI (match_op_dup 1 [(match_dup 2)
- + (const_int 0)])
- + (plus:SI (match_dup 0)
- + (const_int 1))
- + (match_dup 0)))]
- + ""
- + [(set_attr "type" "two")
- + (set_attr "ccstate" "xcc")])
- +
- +(define_insn_and_split "*movsi_negm<mode>"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (neg:SI (match_operator:SI 1 "comparison_operator"
- + [(match_operand:CCALL 2 "metag_<mode>_reg" "")
- + (const_int 0)])))]
- + ""
- + "#"
- + "reload_completed"
- + [(set (match_dup 0)
- + (const_int 0))
- + (set (match_dup 0)
- + (if_then_else:SI (match_op_dup 1 [(match_dup 2)
- + (const_int 0)])
- + (plus:SI (match_dup 0)
- + (const_int -1))
- + (match_dup 0)))]
- + ""
- + [(set_attr "type" "two")
- + (set_attr "ccstate" "xcc")])
- +
- +(define_insn_and_split "*movsi_notm<mode>"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (not:SI (match_operator:SI 1 "comparison_operator"
- + [(match_operand:CCALL 2 "metag_<mode>_reg" "")
- + (const_int 0)])))]
- + ""
- + "#"
- + "reload_completed"
- + [(set (match_dup 0)
- + (const_int 0))
- + (set (match_dup 0)
- + (if_then_else:SI (match_op_dup 1 [(match_dup 2)
- + (const_int 0)])
- + (plus:SI (match_dup 0)
- + (const_int -2))
- + (match_dup 0)))]
- + ""
- + [(set_attr "type" "two")
- + (set_attr "ccstate" "xcc")])
- +
- +;; call instructions - can handle call to symbol hence special predicate
- +(define_expand "sibcall"
- + [(parallel [(call (match_operand:QI 0 "metag_call_addr" "")
- + (match_operand 1 "" ""))
- + (unspec [(const_int 0)] UNSPEC_SIBCALL)])]
- + ""
- + {
- + if (GET_CODE (operands[0]) != MEM)
- + {
- + rtx tmp = gen_rtx_REG (SImode, D0Re0_REG);
- +
- + emit_move_insn (tmp, operands[0]);
- + operands[0] = tmp;
- + }
- + }
- +)
- +
- +(define_expand "call"
- + [(call (match_operand:QI 0 "metag_call_addr" "")
- + (match_operand 1 "" ""))]
- + ""
- + "")
- +
- +(define_expand "call_value"
- + [(set (match_operand 0 "metag_reg_nofloat_op" "")
- + (call (match_operand:QI 1 "metag_call_addr" "")
- + (match_operand 2 "" "")))]
- + ""
- + "")
- +
- +(define_expand "sibcall_value"
- + [(parallel [(set (match_operand 0 "metag_reg_nofloat_op" "")
- + (call (match_operand:QI 1 "metag_call_addr" "")
- + (match_operand 2 "" "")))
- + (unspec [(const_int 0)] UNSPEC_SIBCALL_VALUE)])]
- + ""
- + {
- + if (GET_CODE (operands[1]) != MEM)
- + {
- + rtx tmp = gen_rtx_REG (SImode, D1Re0_REG);
- +
- + emit_move_insn (tmp, operands[1]);
- + operands[1] = tmp;
- + }
- + }
- +)
- +
- +(define_insn "*sibcall_reg"
- + [(call (mem:QI (match_operand:SI 0 "metag_addrreg_op" "a"))
- + (match_operand:SI 1 "immediate_operand" ""))
- + (unspec [(const_int 0)] UNSPEC_SIBCALL)]
- + ""
- + "MOV\\tPC, %0"
- + [(set_attr "type" "unknown")])
- +
- +(define_insn "*call_reg"
- + [(call (mem:QI (match_operand:SI 0 "metag_reg_nofloat_op" "da"))
- + (match_operand:SI 1 "immediate_operand" ""))]
- + ""
- + "*
- + return output_call (operands, 0);"
- + [(set_attr "type" "unknown")
- + (set_attr "length" "8")])
- +
- +(define_insn "*sibcall_value_reg"
- + [(set (match_operand 0 "metag_reg_nofloat_op" "=da")
- + (call (mem:QI (match_operand:SI 1 "metag_addrreg_op" "a"))
- + (match_operand:SI 2 "immediate_operand" "")))
- + (unspec [(const_int 0)] UNSPEC_SIBCALL_VALUE)]
- + ""
- + "MOV\\tPC, %1"
- + [(set_attr "type" "unknown")])
- +
- +(define_insn "*call_value_reg"
- + [(set (match_operand 0 "metag_reg_nofloat_op" "=da")
- + (call (mem:QI (match_operand:SI 1 "metag_reg_nofloat_op" "da"))
- + (match_operand:SI 2 "immediate_operand" "")))]
- + ""
- + "*
- + return output_call (operands, 1);"
- + [(set_attr "type" "unknown")
- + (set_attr "length" "8")])
- +
- +(define_insn "*sibcall_sym"
- + [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
- + (match_operand:SI 1 "immediate_operand" ""))
- + (unspec [(const_int 0)] UNSPEC_SIBCALL)]
- + ""
- + "*
- + return output_sibcall (operands, 0);"
- + [(set_attr "type" "branch")
- + (set_attr "length" "8")])
- +
- +(define_insn "*call_sym"
- + [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
- + (match_operand:SI 1 "immediate_operand" ""))]
- + ""
- + "*
- + return output_call (operands, 0);"
- + [(set_attr "type" "unknown")
- + (set (attr "length")
- + (if_then_else
- + (eq (symbol_ref "metag_tbiassert_p (operands[0])") (const_int 0))
- + (const_int 8)
- + (const_int 12)))])
- +
- +(define_insn "*sibcall_value_sym"
- + [(set (match_operand 0 "metag_reg_nofloat_op" "=da")
- + (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
- + (match_operand:SI 2 "immediate_operand" "")))
- + (unspec [(const_int 0)] UNSPEC_SIBCALL_VALUE)]
- + ""
- + "*
- + return output_sibcall (operands, 1);"
- + [(set_attr "type" "branch")
- + (set_attr "length" "8")])
- +
- +(define_insn "*call_value_sym"
- + [(set (match_operand 0 "metag_reg_nofloat_op" "=da")
- + (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
- + (match_operand:SI 2 "immediate_operand" "")))]
- + ""
- + "*
- + return output_call (operands, 1);"
- + [(set_attr "type" "unknown")
- + (set (attr "length")
- + (if_then_else
- + (eq (symbol_ref "metag_tbiassert_p (operands[1])") (const_int 0))
- + (const_int 8)
- + (const_int 12)))])
- +
- +;; Return instruction
- +(define_insn "return_internal"
- + [(use (reg:SI D1RtP_REG))
- + (return)]
- + ""
- + {
- + /* META 2 and unconditional return and no return stub emitted */
- + if (!metag_cond_exec_p ()
- + && current_insn_predicate == NULL_RTX
- + && TARGET_METAC_2_1
- + && cfun->machine->cond_return_state != METAG_COND_RETURN_DONE)
- + return metag_gen_cond_return_stub ();
- + else if (!TARGET_METAC_2_1 /* META 1.2 or unconditional returns */
- + || (!metag_cond_exec_p ()
- + && current_insn_predicate == NULL_RTX))
- + return "MOV%?\\tPC, D1RtP";
- + else
- + return metag_gen_cond_return_branch ("B%%?\\t$LX%d %%@\\t(* cond return stub)");
- + }
- + [(set_attr "type" "unknown")
- + (set_attr "cond" "yes")])
- +
- +(define_insn "return_internal_cond_<mode>"
- + [(set (pc)
- + (if_then_else (match_operator 0 "comparison_operator"
- + [(match_operand:CCANY 1 "metag_<mode>_reg" "")
- + (unspec [(const_int 0)] UNSPEC_RET_COND)])
- + (return)
- + (pc)))]
- + ""
- + {
- + if (!TARGET_METAC_2_1)
- + return "MOV%z0\\tPC, D1RtP";
- + else
- + return metag_gen_cond_return_branch ("B%%z0\\t$LX%d %%@\\t(* cond return stub)");
- + }
- + [(set_attr "type" "unknown")])
- +
- +(define_insn "return_internal_cond_inverted_<mode>"
- + [(set (pc)
- + (if_then_else (match_operator 0 "comparison_operator"
- + [(match_operand:CCANY 1 "metag_<mode>_reg" "")
- + (unspec [(const_int 0)] UNSPEC_RET_COND_INVERTED)])
- + (pc)
- + (return)))]
- + ""
- + {
- + if (!TARGET_METAC_2_1)
- + return "MOV%Z0\\tPC, D1RtP";
- + else
- + return metag_gen_cond_return_branch ("B%%Z0\\t$LX%d %%@\\t(* cond return stub)");
- + }
- + [(set_attr "type" "unknown")
- + (set_attr "cond" "yes")])
- +
- +(define_insn_and_split "return"
- + [(return)]
- + "METAG_USE_RETURN_INSN (false)"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + metag_expand_epilogue (false);
- + emit_jump_insn (gen_return_internal ());
- + DONE;
- + }
- + [(set_attr "type" "unknown")])
- +
- +(define_insn_and_split "*cond_<mode>_return"
- + [(set (pc)
- + (if_then_else (match_operator 0 "comparison_operator"
- + [(match_operand:CCANY 1 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (return)
- + (pc)))]
- + "METAG_USE_RETURN_INSN (true)"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + metag_expand_epilogue (false);
- + emit_jump_insn (gen_return_internal_cond_<mode> (operands[0], operands[1]));
- + DONE;
- + }
- + [(set_attr "type" "unknown")
- + (set_attr "ccstate" "xcc")])
- +
- +(define_insn_and_split "*cond_<mode>_return_inverted"
- + [(set (pc)
- + (if_then_else (match_operator 0 "comparison_operator"
- + [(match_operand:CCANY 1 "metag_<mode>_reg" "")
- + (const_int 0)])
- + (pc)
- + (return)))]
- + "METAG_USE_RETURN_INSN (true)"
- + "#"
- + "&& TRUE"
- + [(const_int 0)]
- + {
- + metag_expand_epilogue (false);
- + emit_jump_insn (gen_return_internal_cond_inverted_<mode> (operands[0], operands[1]));
- + DONE;
- + }
- + [(set_attr "type" "unknown")
- + (set_attr "ccstate" "xcc")])
- +
- +;; No-op instruction
- +
- +(define_insn "nop"
- + [(const_int 0)]
- + ""
- + "NOP\\t\\t! (*nop OK)"
- + [(set_attr "type" "nop")])
- +
- +(define_expand "casesi"
- + [(match_operand:SI 0 "metag_reg_nofloat_op" "") ; index to jump on
- + (match_operand:SI 1 "const_int_operand" "") ; lower bound
- + (match_operand:SI 2 "const_int_operand" "") ; total range
- + (match_operand:SI 3 "" "") ; table label
- + (match_operand:SI 4 "" "")] ; Out of range label
- + ""
- + {
- + rtx op5 = gen_reg_rtx (SImode);
- + rtx op6 = gen_reg_rtx (SImode);
- +
- + emit_insn (gen_addsi3 (op5, operands[0], gen_int_mode (-INTVAL (operands[1]), SImode)));
- + emit_insn (gen_cmpsi (op5, operands[2]));
- + emit_jump_insn (gen_bgtu (operands[4]));
- +
- + /* This code is intricate...
- + MiniM code can behave in three ways with respect to jump tables:
- + 1) Automatic analysis and branch instruction sizing (default)
- + 2) Forced short branch instructions
- + 3) Forced long branch instructions
- +
- + META code looks like MiniM short branches have been used but they are in fact
- + long branches.
- +
- + The first part of the following if block deals with all META cases and all MiniM
- + cases, unless long branches have been forced on.
- +
- + The second part of the if block deals with MTX 0.1 and MTX 1.2 without MiniM
- + enabled (this is 'classic MiniM') and also MiniM cases where long branches have
- + been forced.
- + */
- +
- + if ((TARGET_METAC_1_0 || TARGET_METAC_1_1) /* A Meta 1.0, 1.1, 1.2 or 2.1 */
- + && !TARGET_METAC_0_1 /* Not an MTX 0.1 */
- + /* MiniM code but with short or automatic branches */
- + && (!TARGET_MINIM || metag_jump_table_branch != METAG_MINIM_JUMP_TABLE_BRANCH_LONG)
- + && (!TARGET_MTX || TARGET_MINIM)) /* Either not an MTX 1.2
- + or is an MTX 1.2 with MiniM */
- + {
- + int offset = 4;
- +
- + /* The instruction that is 'jumped over' ADD PC, CPCx, <reg|int> is
- + always long encoded (see casesi_jmp) and can't be short encoded
- + so the initial jump is 8 rather than 4 in MiniM mode */
- +
- + if (TARGET_MINIM)
- + offset = 8;
- +
- + /* For automatic jump table analysis use the special ashlsi insn */
- + if (TARGET_MINIM && metag_jump_table_branch == METAG_MINIM_JUMP_TABLE_BRANCH_AUTO)
- + emit_insn (gen_jump_table_check_ashlsi3 (op6, op5, GEN_INT (2)));
- + else
- + emit_move_insn (op6,
- + gen_rtx_ASHIFT (SImode, op5, GEN_INT (2)));
- +
- + emit_insn (gen_addsi3 (op6, op6, gen_int_mode (offset, SImode)));
- + }
- + /* An MTX 0.1 or MiniM code with long branches or an MTX 1.2 (without MiniM) */
- + else if (TARGET_METAC_0_1 || TARGET_MINIM || TARGET_MTX)
- + {
- + emit_move_insn (op6,
- + gen_rtx_ASHIFT (SImode, op5, GEN_INT (3)));
- + emit_insn (gen_addsi3 (op6, op6, GEN_INT (8)));
- + }
- + else
- + gcc_unreachable ();
- +
- + emit_jump_insn (gen_casesi_jmp (op6, operands[3]));
- +
- + DONE;
- + }
- +)
- +
- +(define_insn "jump_table_check_ashlsi3"
- + [(set (match_operand:SI 0 "metag_register_op" "=e,e,f,f,r,r,r,r")
- + (ashift:SI (match_operand:SI 1 "metag_reg_nofloat_op" "e,e,f,f,e,e,f,f")
- + (unspec:SI [(match_operand:SI 2 "metag_regorint_op" "e,L,f,L,e,L,f,L")] UNSPEC_MINIM_JUMP_TABLE)))]
- + "TARGET_MINIM"
- + {
- + /* Detect if short branches are permitted in this function */
- + /* WORK NEEDED: This only needs to take place once per function just
- + before emitting instructions */
- + metag_can_use_short_branch ();
- +
- + operands[2] = GEN_INT (cfun->machine->can_use_short_branch ? 2 : 3);
- +
- + return "LSL%?\\t%0, %1, %2\\t%@ (*ashl si rrx OK)";
- + }
- + [(set_attr "type" "fast,fast,fast,fast,slow,slow,slow,slow")
- + (set_attr "cond" "yes,yes,yes,yes,no,no,no,no")])
- +
- +;; The USE in this pattern is needed to tell flow analysis that this is
- +;; a CASESI insn. It has no other purpose.
- +(define_insn "casesi_jmp"
- + [(parallel
- + [(set (pc)
- + (plus:SI (pc)
- + (match_operand:SI 0 "metag_addrreg_op" "h,l")))
- + (use (label_ref (match_operand 1 "" "")))])]
- + ""
- + {
- + /* These instructions are guaranteed to be long encoded as there are
- + no possible short encodings. However for clarity they are forced
- + long */
- + static const char* fmt;
- +
- + if (which_alternative == 0)
- + fmt = "XL\\tADD\\tPC, CPC0, %0\\t%@ ... OK)";
- + else
- + fmt = "XL\\tADD\\tPC, CPC1, %0\\t%@ ... OK)";
- +
- + return &fmt[TARGET_MINIM ? 0 : 3];
- + }
- + [(set_attr "type" "branch")])
- +
- +;; jump instructions
- +(define_insn "jump"
- + [(set (pc)
- + (label_ref (match_operand 0 "" "")))]
- + ""
- + {
- + if (metag_consume_branch (insn))
- + return "";
- +
- + return "B%?\\t%c0\\t\\t\\t%@ (*b ... OK)";
- + }
- + [(set_attr "type" "branch")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_expand "indirect_jump"
- + [(set (pc)
- + (match_operand:SI 0 "address_operand" "p"))]
- + ""
- + {
- + if (!REG_P (operands[0]))
- + {
- + /* Can only jump to register, see reg_jump below */
- + rtx reg = gen_reg_rtx (SImode);
- +
- + emit_move_insn (reg, operands[0]);
- + operands[0] = reg;
- + }
- + }
- +)
- +
- +(define_insn "*reg_jump"
- + [(set (pc)
- + (match_operand:SI 0 "metag_register_op" "r"))]
- + ""
- + "MOV%?\\tPC, %0\\t\\t%@ (*j r OK)"
- + [(set_attr "type" "branch")
- + (set_attr "cond" "yes")
- + (set_attr "predicable" "yes")])
- +
- +(define_insn "load_pic"
- + [(set (match_operand:SI 0 "register_operand" "=X")
- + (unspec:SI [(match_operand:SI 1 "register_operand" "X")] UNSPEC_PIC_BASE))]
- + ""
- + "ADDT\\t%0, %1, #HI(__GLOBAL_OFFSET_TABLE__)\\t\\n\\tADD\\t%0, %0, #LO(__GLOBAL_OFFSET_TABLE__ + 4)"
- + [(set_attr "type" "two")
- + (set_attr "ccstate" "ncc")
- + (set_attr "rename" "no")])
- +
- +(include "vector.md")
- +(include "builtins.md")
- +
- +(include "peephole2.md")
- +(include "dsppeephole2.md")
- +
- +(include "peephole.md")
- +(include "dsppeephole.md")
- +
- +(include "combines.md")
- +(include "fp.md")
- +
- +(include "tls.md")
- +
- +;; The 6bit frame elimination insns below intentionally have 12bit predicates on
- +;; their operands in the hope that the sum 'reduces' this value to fit a 6bit
- +;; value
- +
- +;; stores
- +(define_insn_and_split "*store_<mode>_via_frame_elimination_6bit"
- + [(set (mem:MODES (plus:SI (plus:SI (match_operand:SI 0 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 1 "metag_offset12_<mode>" "<Z>"))
- + (match_operand:SI 2 "metag_offset12_<mode>" "<Z>")))
- + (match_operand:<MODE> 3 "metag_register_op" "r"))]
- + "(reload_in_progress || reload_completed)
- + && metag_offset6_<mode> (GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2])), SImode)"
- + "#"
- + "reload_completed"
- + [(set (mem:<MODE> (plus:SI (match_dup 0)
- + (match_dup 4)))
- + (match_dup 3))]
- + {
- + operands[4] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]));
- + }
- +)
- +
- +(define_insn_and_split "*store_<mode>_via_frame_elimination_12bit"
- + [(set (mem:MODES (plus:SI (plus:SI (match_operand:SI 0 "metag_reg12bit_op" "Yr")
- + (match_operand:SI 1 "metag_offset12_<mode>" "<Z>"))
- + (match_operand:SI 2 "metag_offset12_<mode>" "<Z>")))
- + (match_operand:<MODE> 3 "metag_register_op" "r"))]
- + "(reload_in_progress || reload_completed)
- + && metag_offset12_<mode> (GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2])), SImode)"
- + "#"
- + "reload_completed"
- + [(set (mem:<MODE> (plus:SI (match_dup 0)
- + (match_dup 4)))
- + (match_dup 3))]
- + {
- + operands[4] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]));
- + }
- +)
- +
- +;; loads
- +
- +(define_insn_and_split "*load_<mode>_frame_elimination_6bit"
- + [(set (match_operand:<MODE> 0 "metag_register_op" "=r")
- + (mem:MODES (plus:SI (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 2 "metag_offset12_<mode>" "<Z>"))
- + (match_operand:SI 3 "metag_offset12_<mode>" "<Z>"))))]
- + "(reload_in_progress || reload_completed)
- + && metag_offset6_<mode> (GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])), SImode)"
- + "#"
- + "reload_completed"
- + [(set (match_dup 0)
- + (mem:<MODE> (plus:SI (match_dup 1)
- + (match_dup 4))))]
- + {
- + operands[4] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
- + }
- +)
- +
- +(define_insn_and_split "*load_<mode>_frame_elimination_12bit"
- + [(set (match_operand:<MODE> 0 "metag_register_op" "=r")
- + (mem:MODES (plus:SI (plus:SI (match_operand:SI 1 "metag_reg12bit_op" "Yr")
- + (match_operand:SI 2 "metag_offset12_<mode>" "<Z>"))
- + (match_operand:SI 3 "metag_offset12_<mode>" "<Z>"))))]
- + "(reload_in_progress || reload_completed)
- + && metag_offset12_<mode> (GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])), SImode)"
- + "#"
- + "reload_completed"
- + [(set (match_dup 0)
- + (mem:<MODE> (plus:SI (match_dup 1)
- + (match_dup 4))))]
- + {
- + operands[4] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
- + }
- +)
- +
- +;; load zero extend to SI
- +(define_insn_and_split "*loadz_<mode>si_frame_elimination_6bit"
- + [(set (match_operand:SI 0 "metag_register_op" "=r")
- + (zero_extend:SI
- + (mem:EXTSI (plus:SI (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 2 "metag_offset12_<mode>" "<Z>"))
- + (match_operand:SI 3 "metag_offset12_<mode>" "<Z>")))))]
- + "(reload_in_progress || reload_completed)
- + && metag_offset6_<mode> (GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])), SImode)"
- + "#"
- + "reload_completed"
- + [(set (match_dup 0)
- + (zero_extend:SI
- + (mem:<MODE> (plus:SI (match_dup 1)
- + (match_dup 4)))))]
- + {
- + operands[4] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
- + }
- +)
- +
- +(define_insn_and_split "*loadz_<mode>si_frame_elimination_12bit"
- + [(set (match_operand:SI 0 "metag_register_op" "=r")
- + (zero_extend:SI
- + (mem:EXTSI (plus:SI (plus:SI (match_operand:SI 1 "metag_reg12bit_op" "Yr")
- + (match_operand:SI 2 "metag_offset12_<mode>" "<Z>"))
- + (match_operand:SI 3 "metag_offset12_<mode>" "<Z>")))))]
- + "(reload_in_progress || reload_completed)
- + && metag_offset12_<mode> (GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])), SImode)"
- + "#"
- + "reload_completed"
- + [(set (match_dup 0)
- + (zero_extend:SI
- + (mem:<MODE> (plus:SI (match_dup 1)
- + (match_dup 4)))))]
- + {
- + operands[4] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
- + }
- +)
- +
- +;; load zero extend to HI
- +(define_insn_and_split "*loadz_<mode>hi_frame_elimination_6bit"
- + [(set (match_operand:HI 0 "metag_register_op" "=r")
- + (zero_extend:HI
- + (mem:EXTHI (plus:SI (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 2 "metag_offset12_<mode>" "<Z>"))
- + (match_operand:SI 3 "metag_offset12_<mode>" "<Z>")))))]
- + "(reload_in_progress || reload_completed)
- + && metag_offset6_<mode> (GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])), SImode)"
- + "#"
- + "reload_completed"
- + [(set (match_dup 0)
- + (zero_extend:HI
- + (mem:<MODE> (plus:SI (match_dup 1)
- + (match_dup 4)))))]
- + {
- + operands[4] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
- + }
- +)
- +
- +(define_insn_and_split "*loadz_<mode>hi_frame_elimination_12bit"
- + [(set (match_operand:HI 0 "metag_register_op" "=r")
- + (zero_extend:HI
- + (mem:EXTHI (plus:SI (plus:SI (match_operand:SI 1 "metag_reg12bit_op" "Yr")
- + (match_operand:SI 2 "metag_offset12_<mode>" "<Z>"))
- + (match_operand:SI 3 "metag_offset12_<mode>" "<Z>")))))]
- + "(reload_in_progress || reload_completed)
- + && metag_offset12_<mode> (GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])), SImode)"
- + "#"
- + "reload_completed"
- + [(set (match_dup 0)
- + (zero_extend:HI
- + (mem:<MODE> (plus:SI (match_dup 1)
- + (match_dup 4)))))]
- + {
- + operands[4] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
- + }
- +)
- +
- +(define_insn "*sto_<mode>_reload"
- + [(set (mem:MODES (plus:SI (match_operand:SI 0 "metag_reg_nofloat_op" "e,f,h,l")
- + (match_operand:SI 1 "const_int_operand" "n,n,n,n")))
- + (match_operand:<MODE> 2 "metag_register_op" "t,u,y,z"))]
- + "!TARGET_METAC_1_1 && reload_in_progress && REGNO (operands[0]) == FRAME_POINTER_REGNUM"
- + "#"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*sto_<mode>_1_1_reload"
- + [(set (mem:MODES (plus:SI (match_operand:SI 0 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 1 "const_int_operand" "n")))
- + (match_operand:<MODE> 2 "metag_register_op" "r"))]
- + "TARGET_METAC_1_1 && reload_in_progress && REGNO (operands[0]) == FRAME_POINTER_REGNUM"
- + "#"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*load_<mode>_reload"
- + [(set (match_operand:<MODE> 0 "metag_register_op" "=r")
- + (mem:MODES (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 2 "const_int_operand" "n"))))]
- + "reload_in_progress && REGNO (operands[1]) == FRAME_POINTER_REGNUM"
- + "#"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*loadz_<mode>si_reload"
- + [(set (match_operand:SI 0 "metag_register_op" "=r")
- + (zero_extend:SI
- + (mem:EXTSI (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 2 "const_int_operand" "n")))))]
- + "reload_in_progress && REGNO (operands[1]) == FRAME_POINTER_REGNUM"
- + "#"
- + [(set_attr "type" "load")])
- +
- +(define_insn "*loadz_<mode>hi_reload"
- + [(set (match_operand:HI 0 "metag_register_op" "=r")
- + (zero_extend:HI
- + (mem:EXTHI (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (match_operand:SI 2 "const_int_operand" "n")))))]
- + "reload_in_progress && REGNO (operands[1]) == FRAME_POINTER_REGNUM"
- + "#"
- + [(set_attr "type" "load")])
- +
- +(define_cond_exec
- + [(match_operator 0 "comparison_operator"
- + [(match_operand:CC 1 "metag_cc_reg" "")
- + (const_int 0)])]
- + "!metag_cond_exec_p ()"
- + "")
- +
- +;; end of file
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/metag-modes.def gcc-4.2.4/gcc/config/metag/metag-modes.def
- --- gcc-4.2.4.orig/gcc/config/metag/metag-modes.def 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/metag-modes.def 2015-07-03 18:46:05.749283542 -0500
- @@ -0,0 +1,37 @@
- +/* Definitions of target machine for GNU compiler, for META
- + Copyright (C) 2007, 2008 Imagination Technologies Ltd
- +
- +This file is part of GCC.
- +
- +GCC 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 3, or (at your option) any later
- +version.
- +
- +GCC 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 GCC; see the file COPYING3. If not see
- +<http://www.gnu.org/licenses/>. */
- +
- +
- +/* CC_NOOV mode should be used with SImode integer equalities.
- + CC_Z mode should be used if only the Z zero flag is set correctly
- + CC_N mode should be used if only the N sign flag is set correctly
- + CC_O mode should be used if only the O overflow flag is set correctly
- + CC_C mode should be used if only the C carry flag is set correctly
- + CC mode should be used otherwise. */
- +
- +CC_MODE (CC_NOOV);
- +CC_MODE (CC_Z);
- +CC_MODE (CC_N);
- +CC_MODE (CC_O);
- +CC_MODE (CC_C);
- +CC_MODE (CC_FP);
- +CC_MODE (CC_FP_Q);
- +
- +VECTOR_MODE (INT, SI, 2);
- +VECTOR_MODE (FLOAT, SF, 2);
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/metag.opt gcc-4.2.4/gcc/config/metag/metag.opt
- --- gcc-4.2.4.orig/gcc/config/metag/metag.opt 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/metag.opt 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,135 @@
- +; Copyright (C) 2007, 2008 Imagination Technologies Ltd
- +
- +; This file is part of GCC.
- +
- +; GCC 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 3, or (at your option) any later
- +; version.
- +
- +; GCC 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 GCC; see the file COPYING3. If not see
- +; <http://www.gnu.org/licenses/>.
- +
- +
- +; Conditional execution can be checked for using TARGET_COND_EXEC_OPTIMIZE
- +; This allows the optimize flag to be checked as well as the COND_EXEC
- +; flag
- +
- +mcond-exec
- +Target Mask(COND_EXEC)
- +Enable conditional instructions.
- +
- +mbr-txrpt
- +Target Var(flag_branch_on_count_reg) VarExists
- +Enable use of low overhead loop instructions
- +Default: Enabled
- +
- +mhwloop
- +Target Var(flag_branch_on_count_reg) VarExists
- +Enable use of low overhead loop instructions
- +Default: Enabled
- +
- +mcharset=
- +Target RejectNegative Joined Var(metag_charset_string) Init("")
- +Specify the character set used by strcmp
- +
- +mextreg=
- +Target RejectNegative Joined Var(metag_extreg_string) Init("")
- +Specify the allowed extended registers in each unit (D0D1A0A1)
- +Default: 0000
- +
- +mmetac=
- +Target RejectNegative Joined Var(metag_cpu_string) Init("")
- +Select Meta Core (0.1,1.0,1.1,1.2,2.1)
- +
- +mtune=
- +Target RejectNegative Joined Var(metag_tune_string)
- +Schedule for Meta Core (0.1,1.0,1.1,1.2,2.1)
- +
- +mmtx
- +Target RejectNegative Mask(MTX) UnDocumented
- +Target the MTX core family
- +
- +mminim
- +Target Mask(MINIM)
- +Optimise toward the core 16 bit MiniM instruction set and apply jump compression
- +
- +mminim-optimise
- +Target Mask(MINIM_OPTIMISE)
- +Apply MiniM optimisations.
- +
- +mhard-float
- +Target JoinedOrMissing Mask(FPU) Negative(msoft-float) RejectNegative
- +Enable generation of FPU instructions
- +=D Double precision support (default)
- +=S Single precision support
- +Implies -mregs-float=16
- +
- +mflush-to-zero
- +Target Mask(FLUSH_TO_ZERO)
- +Disable instructions flushing to zero
- +
- +msoft-float
- +Target InverseMask(FPU) Negative(mhard-float)
- +Disable generation of FPU instructions (default)
- +
- +msimd-float
- +Target Mask(FPU_SIMD)
- +Enable SIMD FPU instructions (dual single precision operations)
- +Only permitted with -mhard-float[=D]
- +
- +maccumfp
- +Target Mask(FPU_ACCUM)
- +Enable generation of FPU accumulator instructions
- +Meta GCC does not use the FPU accumulator regardless of this option
- +
- +mregs-float=
- +Target RejectNegative Joined Var(metag_fpureg_string) Init("")
- +Specify the allowed floating point registers
- +Default: 0
- +
- +mdsp
- +Target Mask(DSP)
- +Enable SIMD instructions (Requires DSP hardware thread).
- +Implies -mextreg=8844
- +
- +mwidth=
- +Target RejectNegative Joined Var(metag_width_string) Init("")
- +Specify maximum width of a single memory access (32|64)
- +
- +mjump-table-branch=
- +Target RejectNegative Joined Var(metag_jump_table_string) Init("auto") UnDocumented
- +Specify the default branch size for jump tables in MiniM code
- +Only permitted with -mminim
- +
- +mtbictxsave
- +Target Mask(ECH)
- +Enable extended context saving
- +Allows DSP resources to be preserved in pre-emptive environments
- +
- +mcpu-config=
- +Target RejectNegative Joined Var(metag_config_file) Init("")
- +Specify a configuration file for setting default options
- +
- +mextensions=
- +Target RejectNegative Joined Var(metag_extensions_string) Init("")
- +Specify the permitted extensions to the core instruction set
- +
- +mhwtrace
- +Target Mask(HWTRACE)
- +Enable H/W instrumented tracing.
- +
- +mhwtrace-retpc
- +Target Mask(HWTRACE_RETPC)
- +Enable H/W instrumented tracing, including return addresses
- +
- +mhwtrace-leaf
- +Target Mask(HWTRACE_LEAF)
- +Enable H/W instrumented tracing, for all functions
- +
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/metag-protos.h gcc-4.2.4/gcc/config/metag/metag-protos.h
- --- gcc-4.2.4.orig/gcc/config/metag/metag-protos.h 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/metag-protos.h 2015-07-03 18:46:05.749283542 -0500
- @@ -0,0 +1,265 @@
- +/* Definitions of target machine for GNU compiler.
- + Imagination Technologies Meta version.
- + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
- + Imagination Technologies Ltd
- +
- +This file is part of GCC.
- +
- +GCC 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 3, or (at your option) any later
- +version.
- +
- +GCC 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 GCC; see the file COPYING3. If not see
- +<http://www.gnu.org/licenses/>. */
- +
- +#include "target.h"
- +#include "tree.h"
- +#include "cpplib.h"
- +
- +#ifdef HAVE_ATTR_metacore
- +extern enum attr_metacore metacore;
- +#endif
- +
- +extern void metag_split_movsi_immediate (rtx []);
- +extern void metag_split_movdi (rtx []);
- +extern void metag_split_movdi_immediate (rtx []);
- +extern void metag_split_movdf (rtx []);
- +extern void metag_split_movdf_immediate (rtx []);
- +extern void metag_split_movsf (rtx []);
- +extern void metag_split_movsf_immediate (rtx []);
- +extern void metag_abort (rtx val) ATTRIBUTE_NORETURN;
- +extern int metag_search_rhs (rtx);
- +extern bool metag_cheap_return (bool);
- +extern int debug_metag_md (void);
- +extern unsigned int metag_mem_base (rtx);
- +extern bool metag_mem_base_p (rtx, enum reg_class);
- +extern void metag_override_options (void);
- +extern bool metag_valid_machine_decl_attribute (tree, tree, tree, tree);
- +extern bool metag_cond_exec_p (void);
- +extern void metag_print_cc_if_conditional (FILE *);
- +extern void metag_ccexec_label (const char *);
- +extern bool metag_consume_branch (rtx);
- +
- +extern void metag_init_expanders (void);
- +
- +extern bool metag_legitimate_reg_p (rtx, bool);
- +
- +extern bool metag_legitimate_regno_p (unsigned int, bool);
- +
- +extern bool metag_regs_ok_for_base_offset_p (rtx, rtx, bool);
- +extern bool metag_reg_ok_for_index_p (rtx, bool);
- +
- +extern bool metag_reg_ok_for_base_p (rtx, bool);
- +extern bool metag_reg_ok_for_offset_p (rtx, bool);
- +
- +extern bool metag_legitimate_address_p (rtx, enum machine_mode, bool);
- +
- +extern bool metag_legitimate_post_incdec_p (rtx, enum machine_mode, bool);
- +extern bool metag_legitimate_pre_incdec_p (rtx, enum machine_mode, bool);
- +
- +extern bool metag_legitimate_off_p (rtx, rtx, enum machine_mode, bool);
- +
- +extern bool metag_legitimate_twin_p (rtx, rtx, enum machine_mode, bool);
- +
- +extern bool metag_return_in_memory (tree);
- +
- +extern void output_fn_prologue (FILE *, int);
- +extern void output_fn_epilogue (FILE *, int);
- +
- +extern bool output_call_addr (rtx, enum machine_mode);
- +extern const char * output_sibcall (rtx [], unsigned int);
- +extern const char * output_call (rtx [], unsigned int);
- +extern bool metag_slow_store (rtx, rtx);
- +extern rtx metag_gen_safe_temp (enum machine_mode, rtx);
- +#ifdef RTX_CODE
- +extern enum machine_mode metag_select_cc_mode (RTX_CODE, rtx, rtx);
- +extern bool gen_metag_compare (RTX_CODE, rtx[], int);
- +#endif
- +
- +extern rtx metag_gen_load_multiple (unsigned int, unsigned int, enum machine_mode, rtx, bool, rtx, HOST_WIDE_INT *);
- +extern rtx metag_gen_store_multiple (unsigned int, unsigned int, enum machine_mode, rtx, bool, rtx, HOST_WIDE_INT *);
- +extern bool metag_gen_movmemqi (rtx []);
- +
- +extern void metag_final_prescan_insn (rtx);
- +extern int metag_initial_elimination_offset (int, int);
- +#ifdef CUMULATIVE_ARGS
- +extern void metag_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, bool);
- +extern rtx metag_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, bool);
- +#endif
- +
- +extern long metag_const_double_to_hp (rtx op, bool *inexact);
- +
- +extern void metag_function_profiler (FILE *);
- +#ifdef RTX_CODE
- +extern void metag_print_operand (FILE *, rtx, RTX_CODE);
- +#endif
- +extern void metag_print_operand_address (FILE *, rtx);
- +
- +extern void metag_asm_output_opcode (FILE *, const char *);
- +
- +extern bool metag_frame_related_rtx (rtx);
- +extern bool metag_symbolic_reference_mentioned_p (rtx);
- +extern bool metag_legitimate_pic_address_disp_p (rtx);
- +extern rtx metag_legitimize_pic_address (rtx, rtx);
- +extern rtx metag_legitimize_address (rtx, rtx, enum machine_mode);
- +extern int metag_letter_for_const (rtx);
- +extern bool metag_const_ok_for_letters_p (rtx, const char []);
- +extern bool metag_datareg_p (unsigned int);
- +extern bool metag_addrreg_p (unsigned int);
- +extern bool metag_fpcreg_p (unsigned int);
- +extern bool metag_fppreg_p (unsigned int);
- +extern bool metag_legitimate_modify_p (rtx, enum machine_mode, bool);
- +
- +extern bool metag_same_regclass_p (rtx, rtx);
- +
- +extern bool metag_regno_same_unit_p (unsigned int, unsigned int);
- +
- +extern bool metag_zeroextract_mask_p (rtx, rtx);
- +
- +extern rtx metag_return_addr_rtx (int, rtx);
- +
- +extern HOST_WIDE_INT metag_function_arg_boundary (enum machine_mode, tree);
- +
- +extern int metag_first_parm_offset (tree);
- +
- +extern bool metag_consumer_is_cond_p (rtx, rtx);
- +
- +extern bool metag_bypass_before_reload_p (rtx, rtx);
- +
- +extern bool metag_hard_regno_rename_ok_p (rtx, unsigned int, unsigned int);
- +
- +extern void metag_expand_prologue (void);
- +extern void metag_expand_epilogue (bool);
- +
- +extern enum reg_class metag_regno_reg_class_minimal (unsigned int);
- +
- +extern enum reg_class metag_regno_reg_class_unit (unsigned int);
- +
- +extern bool metag_use_return_insn (bool);
- +
- +extern bool metag_frame_pointer_required (void);
- +
- +extern void metag_setup_frame_addresses (void);
- +
- +extern void metag_expand_set_return_address (rtx);
- +
- +extern bool metag_doloop_loop_nest_optimized(struct loop *, struct doloopnest *);
- +
- +extern bool metag_doloop_check_any_nest_optimized (struct loop *, struct doloopnest *);
- +
- +extern void metag_doloop_mark_nests_optimized (struct loop *, struct doloopnest **);
- +
- +extern bool metag_current_function_loads_pic_register (void);
- +
- +extern rtx metag_legitimize_reload_address (rtx, enum machine_mode, int, int, int);
- +
- +extern bool metag_offset6_mode (rtx, enum machine_mode);
- +
- +extern bool metag_offset12_mode (rtx, enum machine_mode);
- +
- +extern bool metag_regno12bit_p (unsigned int);
- +
- +extern bool metag_split_early (void);
- +
- +extern bool metag_split_hi_lo_sum_early (void);
- +
- +extern bool metag_hard_regno_mode_ok (unsigned int, enum machine_mode);
- +
- +extern void metag_override_options_per_os (void);
- +extern bool metag_handle_option_per_os (size_t, const char *, int);
- +extern bool metag_function_ok_for_sibcall_per_os (tree, tree);
- +
- +/* These functions are part of a framework to allow the support of OS
- + specific builtin functions within GCC. */
- +extern void metag_init_builtins_per_os (void);
- +extern rtx metag_expand_builtin_per_os (tree, rtx);
- +extern void metag_pad_function_call (rtx);
- +extern bool metag_tbiassert_p (rtx);
- +
- +extern void metag_internal_label (FILE *, const char *, unsigned long);
- +extern void metag_function_prologue (FILE *, HOST_WIDE_INT);
- +extern void metag_function_end_prologue (FILE *);
- +extern void metag_function_begin_epilogue (FILE *);
- +extern void metag_function_epilogue (FILE *, HOST_WIDE_INT);
- +extern void metag_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
- + tree);
- +extern bool metag_can_output_mi_thunk (tree, HOST_WIDE_INT, HOST_WIDE_INT,
- + tree);
- +extern int metag_sched_adjust_cost (rtx, rtx, rtx, int);
- +extern bool metag_handle_option (size_t, const char *, int);
- +extern tree metag_merge_decl_attributes (tree, tree);
- +extern tree metag_merge_type_attributes (tree, tree);
- +extern const struct attribute_spec metag_attribute_table[];
- +extern int metag_comp_type_attributes (tree, tree);
- +extern void metag_init_builtins (void);
- +extern rtx metag_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
- +extern bool metag_function_ok_for_sibcall (tree, tree);
- +extern void metag_encode_section_info (tree, rtx, int);
- +extern bool metag_scalar_mode_supported_p (enum machine_mode);
- +extern bool metag_rtx_costs (rtx, int, int, int *);
- +extern int metag_address_cost (rtx);
- +extern void metag_machine_dependent_reorg (void);
- +extern tree metag_gimplify_va_arg_expr (tree, tree, tree *, tree *);
- +extern const char * metag_invalid_within_doloop (rtx);
- +extern bool metag_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, tree,
- + bool);
- +extern void metag_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
- + tree, int *, int);
- +extern bool metag_must_pass_in_stack (enum machine_mode, tree);
- +extern int metag_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, tree,
- + bool);
- +extern enum reg_class metag_secondary_reload (bool, rtx, enum reg_class,
- + enum machine_mode,
- + secondary_reload_info *);
- +extern bool metag_vector_mode_supported_p (enum machine_mode);
- +extern enum reg_class metag_secondary_reload_class (enum reg_class,
- + enum machine_mode,
- + rtx, bool);
- +
- +extern bool metag_output_addr_const_extra (FILE *, rtx);
- +
- +extern bool metag_dsp_ri16_operands (rtx[]);
- +extern bool metag_dsp_ri5_operands (rtx[]);
- +extern bool metag_dsp_rrr_operands (rtx[], bool);
- +extern bool metag_dsp_cmp_rrr_operands (rtx[], bool);
- +extern bool metag_dsp_cmp_ri16_operands (rtx[]);
- +extern bool metag_dsp_rrr_mov_operands (rtx[], bool);
- +extern bool metag_dsp_rri5_operands (rtx[]);
- +extern bool metag_dsp_rr_operands (rtx[]);
- +extern bool metag_dsp_cmp_rri5_operands (rtx[]);
- +extern bool metag_dsp_rr_rr_mov_operands (rtx[]);
- +
- +extern void metag_dsp_peephole2_rr_convert (rtx[]);
- +extern void metag_dsp_peephole2_rr_mov_convert (rtx[]);
- +extern void metag_dsp_peephole2_rrr_convert (rtx[]);
- +extern void metag_dsp_peephole2_rrr_mov_convert (rtx[]);
- +extern void metag_dsp_peephole2_ri16_convert (rtx[]);
- +extern void metag_dsp_peephole2_rri5_convert (rtx[]);
- +
- +extern bool metag_move_valid_p (rtx, rtx);
- +extern void metag_cpu_cpp_builtins (cpp_reader *);
- +
- +extern void metag_expand_didf2 (rtx, rtx);
- +
- +/* Handle the jump_table_branch pragma */
- +extern void metag_pragma_jump_table_branch (struct cpp_reader *);
- +/* Handle the hwtrace_function pragma */
- +extern void metag_pragma_hwtrace_function (struct cpp_reader *);
- +
- +extern bool metag_meta2_bex_enabled;
- +extern void metag_can_use_short_branch (void);
- +extern void metag_emit_move_sequence (rtx[], enum machine_mode);
- +
- +extern rtx metag_libcall_value (enum machine_mode);
- +extern rtx metag_function_value (tree, tree, bool);
- +
- +extern bool tls_symbolic_operand_p (rtx);
- +extern bool metag_bfd_tls_referenced_p (rtx);
- +extern rtx metag_bfd_legitimize_tls_address (rtx);
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/peephole2.md gcc-4.2.4/gcc/config/metag/peephole2.md
- --- gcc-4.2.4.orig/gcc/config/metag/peephole2.md 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/peephole2.md 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,1324 @@
- +;; Machine description for GNU compiler,
- +;; Imagination Technologies Meta version.
- +;; Copyright (C) 2007
- +;; Imagination Technologies Ltd
- +
- +;; This file is part of GCC.
- +
- +;; GCC 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 3, or (at your option) any later
- +;; version.
- +
- +;; GCC 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 GCC; see the file COPYING3. If not see
- +;; <http://www.gnu.org/licenses/>.
- +
- +
- +;; ====PRE_INC
- +
- +;; ----------------------------------------------------------------------------
- +;; Recognising DI/SI/HI/QI store pre-inc/dec/modify
- +;; ----------------------------------------------------------------------------
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_register_op" "")))
- + (set (match_operand:MODES 2 "memory_operand" "")
- + (match_operand:<MODE> 3 "metag_register_op" ""))]
- + "metag_same_regclass_p (operands[0], operands[1])
- + && !metag_same_regclass_p (operands[0], operands[3])
- + && rtx_equal_p (operands[0], XEXP (operands[2], 0))
- + && (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
- + || !metag_same_regclass_p (operands[0], gen_rtx_REG (SImode, REGNO (operands[3]) + 1)))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- + rtx pre_modify = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + rtx mem = gen_rtx_MEM (<MODE>mode, pre_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[3]));
- +
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[2]);
- + if (auto_inc_p (pre_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_<mode>" "")))
- + (set (match_operand:MODES 2 "memory_operand" "")
- + (match_operand:<MODE> 3 "metag_register_op" ""))]
- + "rtx_equal_p (operands[0], XEXP (operands[2], 0))"
- + [(const_int 0)]
- + {
- + rtx pre, mem, insn;
- +
- + if (INTVAL (operands[1]) == GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_INC (SImode, operands[0]);
- + else if (INTVAL (operands[1]) == -GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_DEC (SImode, operands[0]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- +
- + pre = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + }
- +
- + mem = gen_rtx_MEM (<MODE>mode, pre);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[2]);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[3]));
- +
- + if (auto_inc_p (pre))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +;; ----------------------------------------------------------------------------
- +
- +;; ----------------------------------------------------------------------------
- +;; Recognising DI/SI/HI/QI load pre-inc/dec/modify
- +;; ----------------------------------------------------------------------------
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_register_op" "")))
- + (set (match_operand:<MODE> 2 "metag_register_op" "")
- + (match_operand:MODES 3 "memory_operand" ""))]
- + "metag_same_regclass_p (operands[0], operands[1])
- + && rtx_equal_p (operands[0], XEXP (operands[3], 0))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- + rtx pre_modify = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + rtx mem = gen_rtx_MEM (<MODE>mode, pre_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, operands[2], mem));
- +
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]);
- +
- + if (auto_inc_p (pre_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_<mode>" "")))
- + (set (match_operand:<MODE> 2 "metag_register_op" "")
- + (match_operand:MODES 3 "memory_operand" ""))]
- + "rtx_equal_p (operands[0], XEXP (operands[3], 0))"
- + [(const_int 0)]
- + {
- + rtx pre, mem, insn;
- +
- + if (INTVAL (operands[1]) == GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_INC (SImode, operands[0]);
- + else if (INTVAL (operands[1]) == -GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_DEC (SImode, operands[0]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- +
- + pre = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + }
- +
- + mem = gen_rtx_MEM (<MODE>mode, pre);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[2], mem));
- +
- + if (auto_inc_p (pre))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +;; ----------------------------------------------------------------------------
- +
- +;; ----------------------------------------------------------------------------
- +;; Recognising zero extend SI load pre-inc/dec/modify
- +;; ----------------------------------------------------------------------------
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_register_op" "")))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (zero_extend:SI
- + (match_operand:EXTSI 3 "memory_operand" "")))]
- + "metag_same_regclass_p (operands[0], operands[1])
- + && rtx_equal_p (operands[0], XEXP (operands[3], 0))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- + rtx pre_modify = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + rtx mem = gen_rtx_MEM (<MODE>mode, pre_modify);
- + rtx zextend = gen_rtx_ZERO_EXTEND (SImode, mem);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, operands[2], zextend));
- +
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]);
- +
- + if (auto_inc_p (pre_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_<mode>" "")))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (zero_extend:SI
- + (match_operand:EXTSI 3 "memory_operand" "")))]
- + "rtx_equal_p (operands[0], XEXP (operands[3], 0))"
- + [(const_int 0)]
- + {
- + rtx pre, mem, zextend, insn;
- +
- + if (INTVAL (operands[1]) == GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_INC (SImode, operands[0]);
- + else if (INTVAL (operands[1]) == -GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_DEC (SImode, operands[0]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- +
- + pre = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + }
- +
- + mem = gen_rtx_MEM (<MODE>mode, pre);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]);
- + zextend = gen_rtx_ZERO_EXTEND (SImode, mem);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[2], zextend));
- +
- + if (auto_inc_p (pre))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +;; ----------------------------------------------------------------------------
- +;; Recognising zero extend HI load pre-inc/dec/modify
- +;; ----------------------------------------------------------------------------
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_register_op" "")))
- + (set (match_operand:HI 2 "metag_register_op" "")
- + (zero_extend:HI
- + (match_operand:EXTHI 3 "memory_operand" "")))]
- + "metag_same_regclass_p (operands[0], operands[1])
- + && rtx_equal_p (operands[0], XEXP (operands[3], 0))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- + rtx pre_modify = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + rtx mem = gen_rtx_MEM (<MODE>mode, pre_modify);
- + rtx zextend = gen_rtx_ZERO_EXTEND (HImode, mem);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, operands[2], zextend));
- +
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]);
- +
- + if (auto_inc_p (pre_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_<mode>" "")))
- + (set (match_operand:HI 2 "metag_register_op" "")
- + (zero_extend:HI
- + (match_operand:EXTHI 3 "memory_operand" "")))]
- + "rtx_equal_p (operands[0], XEXP (operands[3], 0))"
- + [(const_int 0)]
- + {
- + rtx pre, mem, zextend, insn;
- +
- + if (INTVAL (operands[1]) == GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_INC (SImode, operands[0]);
- + else if (INTVAL (operands[1]) == -GET_MODE_SIZE (<MODE>mode))
- + pre = gen_rtx_PRE_DEC (SImode, operands[0]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[0], operands[1]);
- +
- + pre = gen_rtx_PRE_MODIFY (SImode, operands[0], plus);
- + }
- +
- + mem = gen_rtx_MEM (<MODE>mode, pre);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]);
- + zextend = gen_rtx_ZERO_EXTEND (HImode, mem);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[2], zextend));
- +
- + if (auto_inc_p (pre))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (pre, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +;; ====PRE_INC
- +
- +;; ====POST_INC
- +
- +;; ----------------------------------------------------------------------------
- +;; Recognising DF/SF/DI/SI/HI/QI store post-inc/dec/modify
- +;; ----------------------------------------------------------------------------
- +
- +(define_peephole2
- + [(set (match_operand:MODES 0 "memory_operand" "")
- + (match_operand:<MODE> 1 "metag_register_op" ""))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (plus:SI (match_dup 2)
- + (match_operand:SI 3 "metag_register_op" "")))]
- + "metag_same_regclass_p (operands[3], operands[2])
- + && !metag_same_regclass_p (operands[2], operands[1])
- + && rtx_equal_p (operands[2], XEXP (operands[0], 0))
- + && (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
- + || !metag_same_regclass_p (operands[2], gen_rtx_REG (SImode, REGNO (operands[1]) + 1)))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[2], operands[3]);
- + rtx post_modify = gen_rtx_POST_MODIFY (SImode, operands[2], plus);
- + rtx mem = gen_rtx_MEM (<MODE>mode, post_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
- +
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[0]);
- +
- + if (auto_inc_p (post_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +(define_peephole2
- + [(set (match_operand:MODES 0 "memory_operand" "")
- + (match_operand:<MODE> 1 "metag_register_op" ""))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (plus:SI (match_dup 2)
- + (match_operand:SI 3 "metag_offset6_<mode>" "")))]
- + "rtx_equal_p (operands[2], XEXP (operands[0], 0))"
- + [(const_int 0)]
- + {
- + rtx post, mem, insn;
- +
- + if (INTVAL (operands[3]) == GET_MODE_SIZE (<MODE>mode))
- + post = gen_rtx_POST_INC (SImode, operands[2]);
- + else if (INTVAL (operands[3]) == -GET_MODE_SIZE (<MODE>mode))
- + post = gen_rtx_POST_DEC (SImode, operands[2]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[2], operands[3]);
- +
- + post = gen_rtx_POST_MODIFY (SImode, operands[2], plus);
- + }
- +
- + mem = gen_rtx_MEM (<MODE>mode, post);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[0]);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
- +
- + if (auto_inc_p (post))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +;; ----------------------------------------------------------------------------
- +
- +;; ----------------------------------------------------------------------------
- +;; Recognising DI/SI/HI/QI load post-inc/dec/modify
- +;; ----------------------------------------------------------------------------
- +
- +(define_peephole2
- + [(set (match_operand:<MODE> 0 "metag_register_op" "")
- + (match_operand:MODES 1 "memory_operand" ""))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (plus:SI (match_dup 2)
- + (match_operand:SI 3 "metag_register_op" "")))]
- + "metag_same_regclass_p (operands[3], operands[2])
- + && rtx_equal_p (operands[2], XEXP (operands[1], 0))
- + && REGNO (operands[0]) != REGNO (operands[3])
- + && REGNO (operands[0]) != REGNO (operands[2])"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[2], operands[3]);
- + rtx post_modify = gen_rtx_POST_MODIFY (SImode, operands[2], plus);
- + rtx mem = gen_rtx_MEM (<MODE>mode, post_modify);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
- +
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]);
- +
- + if (auto_inc_p (post_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +(define_peephole2
- + [(set (match_operand:<MODE> 0 "metag_register_op" "")
- + (match_operand:MODES 1 "memory_operand" ""))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (plus:SI (match_dup 2)
- + (match_operand:SI 3 "metag_offset6_<mode>" "")))]
- + "REGNO (operands[0]) != REGNO (operands[2])
- + && rtx_equal_p (operands[2], XEXP (operands[1], 0))"
- + [(const_int 0)]
- + {
- + rtx post, mem, insn;
- +
- + if (INTVAL (operands[3]) == GET_MODE_SIZE (<MODE>mode))
- + post = gen_rtx_POST_INC (SImode, operands[2]);
- + else if (INTVAL (operands[3]) == -GET_MODE_SIZE (<MODE>mode))
- + post = gen_rtx_POST_DEC (SImode, operands[2]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[2], operands[3]);
- +
- + post = gen_rtx_POST_MODIFY (SImode, operands[2], plus);
- + }
- +
- + mem = gen_rtx_MEM (<MODE>mode, post);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
- +
- + if (auto_inc_p (post))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +;; ----------------------------------------------------------------------------
- +
- +;; ----------------------------------------------------------------------------
- +;; Recognising zero extend SI load post-modify
- +;; ----------------------------------------------------------------------------
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (zero_extend:SI
- + (match_operand:EXTSI 1 "memory_operand" "")))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (plus:SI (match_dup 2)
- + (match_operand:SI 3 "metag_register_op" "")))]
- + "metag_same_regclass_p (operands[3], operands[2])
- + && REGNO (operands[0]) != REGNO (operands[3])
- + && REGNO (operands[0]) != REGNO (operands[2])
- + && rtx_equal_p (operands[2], XEXP (operands[1], 0))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[2], operands[3]);
- + rtx post_modify = gen_rtx_POST_MODIFY (SImode, operands[2], plus);
- + rtx mem = gen_rtx_MEM (<MODE>mode, post_modify);
- + rtx zextend = gen_rtx_ZERO_EXTEND (SImode, mem);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], zextend));
- +
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]);
- +
- + if (auto_inc_p (post_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (zero_extend:SI
- + (match_operand:EXTSI 1 "memory_operand" "")))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (plus:SI (match_dup 2)
- + (match_operand:SI 3 "metag_offset6_<mode>" "")))]
- + "REGNO (operands[0]) != REGNO (operands[2])
- + && rtx_equal_p (operands[2], XEXP (operands[1], 0))"
- + [(const_int 0)]
- + {
- + rtx post, mem, zextend, insn;
- +
- + if (INTVAL (operands[3]) == GET_MODE_SIZE (<MODE>mode))
- + post = gen_rtx_POST_INC (SImode, operands[2]);
- + else if (INTVAL (operands[3]) == -GET_MODE_SIZE (<MODE>mode))
- + post = gen_rtx_POST_DEC (SImode, operands[2]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[2], operands[3]);
- +
- + post = gen_rtx_POST_MODIFY (SImode, operands[2], plus);
- + }
- +
- + mem = gen_rtx_MEM (<MODE>mode, post);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]);
- + zextend = gen_rtx_ZERO_EXTEND (SImode, mem);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], zextend));
- +
- + if (auto_inc_p (post))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +;; ----------------------------------------------------------------------------
- +;; Recognising zero extend HI load post-inc/dec/modify
- +;; ----------------------------------------------------------------------------
- +
- +(define_peephole2
- + [(set (match_operand:HI 0 "metag_register_op" "")
- + (zero_extend:HI
- + (match_operand:EXTHI 1 "memory_operand" "")))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (plus:SI (match_dup 2)
- + (match_operand:SI 3 "metag_register_op" "")))]
- + "metag_same_regclass_p (operands[3], operands[2])
- + && REGNO (operands[0]) != REGNO (operands[3])
- + && REGNO (operands[0]) != REGNO (operands[2])
- + && rtx_equal_p (operands[2], XEXP (operands[1], 0))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[2], operands[3]);
- + rtx post_modify = gen_rtx_POST_MODIFY (SImode, operands[2], plus);
- + rtx mem = gen_rtx_MEM (<MODE>mode, post_modify);
- + rtx zextend = gen_rtx_ZERO_EXTEND (HImode, mem);
- + rtx insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], zextend));
- +
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]);
- +
- + if (auto_inc_p (post_modify))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post_modify, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +(define_peephole2
- + [(set (match_operand:HI 0 "metag_register_op" "")
- + (zero_extend:HI
- + (match_operand:EXTHI 1 "memory_operand" "")))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (plus:SI (match_dup 2)
- + (match_operand:SI 3 "metag_offset6_<mode>" "")))]
- + "REGNO (operands[0]) != REGNO (operands[2])
- + && rtx_equal_p (operands[2], XEXP (operands[1], 0))"
- + [(const_int 0)]
- + {
- + rtx post, mem, zextend, insn;
- +
- + if (INTVAL (operands[3]) == GET_MODE_SIZE (<MODE>mode))
- + post = gen_rtx_POST_INC (SImode, operands[2]);
- + else if (INTVAL (operands[3]) == -GET_MODE_SIZE (<MODE>mode))
- + post = gen_rtx_POST_DEC (SImode, operands[2]);
- + else
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[2], operands[3]);
- +
- + post = gen_rtx_POST_MODIFY (SImode, operands[2], plus);
- + }
- +
- + mem = gen_rtx_MEM (<MODE>mode, post);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]);
- + zextend = gen_rtx_ZERO_EXTEND (HImode, mem);
- + insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], zextend));
- +
- + if (auto_inc_p (post))
- + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (post, 0), REG_NOTES (insn));
- + DONE;
- + }
- +)
- +
- +;; ====POST_INC
- +
- +;; ----------------------------------------------------------------------------
- +;; Fixup some obvious reg alloc losage for loads
- +;; ----------------------------------------------------------------------------
- +
- +(define_peephole2
- + [(set (match_operand:MEMOP 0 "metag_register_op" "")
- + (match_operand:<MODE> 1 "memory_operand" ""))
- + (set (match_operand:<MODE> 2 "metag_reg_nofloat_op" "")
- + (match_dup 0))]
- + "peep2_reg_dead_p (2, operands[0])"
- + [(set (match_dup 2)
- + (match_dup 1))]
- + "")
- +
- +;; ----------------------------------------------------------------------------
- +
- +;; misc peephole2s
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (match_operand:SI 1 "metag_datareg_op" ""))
- + (set (reg:CCANY CC_REG)
- + (compare:<MODE>
- + (match_dup 0)
- + (match_operand:SI 2 "metag_int_operand" "")))]
- + "peep2_reg_dead_p (2, operands[0])"
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (match_dup 1)
- + (match_dup 2)))]
- + "")
- +
- +;;
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (match_operand:SI 1 "metag_datareg_op" ""))
- + (set (reg:CCANY CC_REG)
- + (compare:<MODE>
- + (match_dup 0)
- + (match_operand:SI 2 "metag_datareg_op" "")))]
- + "peep2_reg_dead_p (2, operands[0])
- + && metag_same_regclass_p (operands[0], operands[1])
- + && !rtx_equal_p (operands[0], operands[2])"
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (match_dup 1)
- + (match_dup 2)))]
- + "")
- +
- +;; SImode swap
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (match_operand:SI 1 "metag_reg_nofloat_op" ""))
- + (set (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" ""))
- + (set (match_dup 2)
- + (match_dup 0))]
- + "!metag_same_regclass_p (operands[1], operands[2])
- + && peep2_reg_dead_p (3, operands[0])"
- + [(parallel
- + [(set (match_dup 1)
- + (match_dup 2))
- + (set (match_dup 2)
- + (match_dup 1))])]
- + "")
- +
- +;; DImode swap
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (match_operand:SI 1 "metag_reg_nofloat_op" ""))
- + (set (match_operand:SI 2 "metag_reg_nofloat_op" "")
- + (match_operand:SI 3 "metag_reg_nofloat_op" ""))
- + (set (match_dup 1)
- + (match_operand:SI 4 "metag_reg_nofloat_op" ""))
- + (set (match_dup 3)
- + (match_operand:SI 5 "metag_reg_nofloat_op" ""))
- + (set (match_dup 4)
- + (match_dup 0))
- + (set (match_dup 5)
- + (match_dup 2))]
- + " !metag_same_regclass_p (operands[3], operands[4])
- + && !metag_same_regclass_p (operands[1], operands[5])
- + && !metag_same_regclass_p (operands[4], operands[5])
- + && !metag_same_regclass_p (operands[1], operands[3])
- + && peep2_reg_dead_p (5, operands[0])
- + && peep2_reg_dead_p (6, operands[2])"
- + [(parallel
- + [(set (match_dup 3)
- + (match_dup 4))
- + (set (match_dup 4)
- + (match_dup 3))])
- + (parallel
- + [(set (match_dup 1)
- + (match_dup 5))
- + (set (match_dup 5)
- + (match_dup 1))])
- + (parallel
- + [(set (match_dup 4)
- + (match_dup 5))
- + (set (match_dup 5)
- + (match_dup 4))])
- + (parallel
- + [(set (match_dup 1)
- + (match_dup 3))
- + (set (match_dup 3)
- + (match_dup 1))])]
- + "")
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (match_operand:SI 1 "metag_reg_nofloat_op" ""))
- + (set (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" ""))
- + (set (match_dup 2)
- + (match_dup 0))]
- + "!metag_same_regclass_p (operands[1], operands[2])"
- + [(set (match_dup 0)
- + (match_dup 1))
- + (parallel
- + [(set (match_dup 1)
- + (match_dup 2))
- + (set (match_dup 2)
- + (match_dup 1))])]
- + "")
- +
- +;; set full condition flags during move, flags from source value
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (match_operand:SI 1 "metag_datareg_op" ""))
- + (set (reg:CCANY CC_REG)
- + (compare:<MODE>
- + (match_dup 1)
- + (const_int 0)))]
- + "REGNO (operands[0]) <= LAST_ADDR_REG"
- + [(parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (match_dup 1)
- + (const_int 0)))
- + (set (match_dup 0)
- + (match_dup 1))])]
- + "")
- +
- +;; set full condition flags during move, flags from dest value
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (match_operand:SI 1 "metag_datareg_op" ""))
- + (set (reg:CCANY CC_REG)
- + (compare:<MODE>
- + (match_dup 0)
- + (const_int 0)))]
- + "REGNO (operands[0]) <= LAST_ADDR_REG"
- + [(parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (match_dup 1)
- + (const_int 0)))
- + (set (match_dup 0)
- + (match_dup 1))])]
- + "")
- +
- +;; set condition flags during sign extension of a hi value
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (sign_extend:SI (match_operand:HI 1 "metag_register_op" "")))
- + (set (reg:CCZNC CC_REG)
- + (compare:<MODE>
- + (match_dup 0)
- + (const_int 0)))]
- + ""
- + [(parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (sign_extend:SI (match_dup 1))
- + (const_int 0)))
- + (set (match_dup 0)
- + (sign_extend:SI (match_dup 1)))])]
- + "")
- +
- +;; set condition flags during sign extension of a qi value
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (sign_extend:SI (match_operand:QI 1 "metag_register_op" "")))
- + (set (reg:CCZNC CC_REG)
- + (compare:<MODE>
- + (match_dup 0)
- + (const_int 0)))]
- + ""
- + [(parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (sign_extend:SI (match_dup 1))
- + (const_int 0)))
- + (set (match_dup 0)
- + (sign_extend:SI (match_dup 1)))])]
- + "")
- +
- +;; eliminate redundant move
- +(define_peephole2
- + [(set (match_operand:MEMOP 0 "metag_register_op" "")
- + (match_operand:<MODE> 1 "metag_regorint_op" ""))
- + (set (match_operand:<MODE> 2 "metag_register_op" "")
- + (match_dup 0))]
- + "peep2_reg_dead_p (2, operands[0])
- + && metag_move_valid_p (operands[2], operands[1])"
- + [(set (match_dup 2)
- + (match_dup 1))]
- + "")
- +
- +;;
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_register_op" "")))
- + (set (reg:CCZNC CC_REG)
- + (compare:<MODE>
- + (match_dup 0)
- + (const_int 0)))]
- + ""
- + [(parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (plus:SI (match_dup 1)
- + (match_dup 2))
- + (const_int 0)))
- + (set (match_dup 0)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))])]
- + "")
- +
- +;;
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (minus:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_register_op" "")))
- + (set (reg:CCZNC CC_REG)
- + (compare:<MODE>
- + (match_dup 0)
- + (const_int 0)))]
- + ""
- + [(parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (minus:SI (match_dup 1)
- + (match_dup 2))
- + (const_int 0)))
- + (set (match_dup 0)
- + (minus:SI (match_dup 1)
- + (match_dup 2)))])]
- + "")
- +;;
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_operand:SI 1 "metag_datareg_op" "")
- + (match_operand:SI 2 "metag_smallint_op" "")))
- + (set (reg:CCZNC CC_REG)
- + (compare:<MODE>
- + (match_dup 0)
- + (const_int 0)))]
- + ""
- + [(parallel
- + [(set (reg:<MODE> CC_REG)
- + (compare:<MODE>
- + (plus:SI (match_dup 1)
- + (match_dup 2))
- + (const_int 0)))
- + (set (match_dup 0)
- + (plus:SI (match_dup 1)
- + (match_dup 2)))])]
- + "")
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (high:SI (match_operand:SI 1 "metag_symglobal_op" "")))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1)))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 2 "const_int_operand" "")))]
- + "!METAG_FLAG_PIC"
- + [(set (match_dup 0)
- + (high:SI (match_dup 3)))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 3)))]
- + "operands[3] = gen_rtx_CONST (SImode,
- + gen_rtx_PLUS (SImode,
- + operands[1],
- + operands[2]));")
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (high:SI (const:SI (plus:SI (match_operand:SI 1 "metag_symglobal_op" "")
- + (match_operand:SI 2 "const_int_operand" "")))))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (const:SI (plus:SI (match_dup 1)
- + (match_dup 2)))))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 3 "const_int_operand" "")))]
- + "!METAG_FLAG_PIC"
- + [(set (match_dup 0)
- + (high:SI (match_dup 4)))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 4)))]
- + "operands[4] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
- + operands[4] = gen_rtx_CONST (SImode,
- + gen_rtx_PLUS (SImode,
- + operands[1],
- + operands[4]));")
- +
- +;; Combine a load/store with pre address arithmetic into
- +;; a load/store with base + offset addressing.
- +;; Where the intermidiate address register dies in the load/store
- +
- +;; loads
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_operand:SI 1 "metag_register_op" "")
- + (match_operand:SI 2 "metag_offset6_<mode>" "")))
- + (set (match_operand:<MODE> 3 "metag_register_op" "")
- + (match_operand:MEMOP 4 "memory_operand" ""))]
- + "peep2_reg_dead_p (2, operands[0])
- + && rtx_equal_p (operands[0], XEXP (operands[4], 0))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- + rtx mem = gen_rtx_MEM (<MODE>mode, plus);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[4]);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[3], mem));
- +
- + DONE;
- + }
- +)
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_operand:SI 1 "metag_reg12bit_op" "")
- + (match_operand:SI 2 "metag_offset12_<mode>" "")))
- + (set (match_operand:<MODE> 3 "metag_reg_nofloat_op" "")
- + (match_operand:MEMOP 4 "memory_operand" ""))]
- + "peep2_reg_dead_p (2, operands[0])
- + && rtx_equal_p (operands[0], XEXP (operands[4], 0))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- + rtx mem = gen_rtx_MEM (<MODE>mode, plus);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[4]);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[3], mem));
- +
- + DONE;
- + }
- +)
- +
- +;; load zero_extend HI
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_operand:SI 1 "metag_register_op" "")
- + (match_operand:SI 2 "metag_offset6_<mode>" "")))
- + (set (match_operand:HI 3 "metag_register_op" "")
- + (zero_extend:HI
- + (match_operand:EXTHI 4 "memory_operand" "")))]
- + "peep2_reg_dead_p (2, operands[0])
- + && rtx_equal_p (operands[0], XEXP (operands[4], 0))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- + rtx mem = gen_rtx_MEM (<MODE>mode, plus);
- + rtx zextend = gen_rtx_ZERO_EXTEND (HImode, mem);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[4]);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[3], zextend));
- +
- + DONE;
- + }
- +)
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_operand:SI 1 "metag_reg12bit_op" "")
- + (match_operand:SI 2 "metag_offset12_<mode>" "")))
- + (set (match_operand:HI 3 "metag_reg_nofloat_op" "")
- + (zero_extend:HI
- + (match_operand:EXTHI 4 "memory_operand" "")))]
- + "peep2_reg_dead_p (2, operands[0])
- + && rtx_equal_p (operands[0], XEXP (operands[4], 0))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- + rtx mem = gen_rtx_MEM (<MODE>mode, plus);
- + rtx zextend = gen_rtx_ZERO_EXTEND (HImode, mem);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[4]);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[3], zextend));
- +
- + DONE;
- + }
- +)
- +
- +;; load zero_extend SI
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_operand:SI 1 "metag_register_op" "")
- + (match_operand:SI 2 "metag_offset6_<mode>" "")))
- + (set (match_operand:SI 3 "metag_register_op" "")
- + (zero_extend:SI
- + (match_operand:EXTSI 4 "memory_operand" "")))]
- + "peep2_reg_dead_p (2, operands[0])
- + && rtx_equal_p (operands[0], XEXP (operands[4], 0))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- + rtx mem = gen_rtx_MEM (<MODE>mode, plus);
- + rtx zextend = gen_rtx_ZERO_EXTEND (SImode, mem);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[4]);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[3], zextend));
- +
- + DONE;
- + }
- +)
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_operand:SI 1 "metag_reg12bit_op" "")
- + (match_operand:SI 2 "metag_offset12_<mode>" "")))
- + (set (match_operand:SI 3 "metag_reg_nofloat_op" "")
- + (zero_extend:SI
- + (match_operand:EXTSI 4 "memory_operand" "")))]
- + "peep2_reg_dead_p (2, operands[0])
- + && rtx_equal_p (operands[0], XEXP (operands[4], 0))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- + rtx mem = gen_rtx_MEM (<MODE>mode, plus);
- + rtx zextend = gen_rtx_ZERO_EXTEND (SImode, mem);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[4]);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[3], zextend));
- +
- + DONE;
- + }
- +)
- +
- +;; store QI/HI/SI
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_operand:SI 1 "metag_register_op" "")
- + (match_operand:SI 2 "metag_offset6_<mode>" "")))
- + (set (match_operand:MEMOP 3 "memory_operand" "")
- + (match_operand:<MODE> 4 "metag_register_op" ""))]
- + "peep2_reg_dead_p (2, operands[0])
- + && REGNO (operands[0]) != REGNO (operands[4])
- + && rtx_equal_p (operands[0], XEXP (operands[3], 0))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- + rtx mem = gen_rtx_MEM (<MODE>mode, plus);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]);
- + emit_insn (gen_rtx_SET (VOIDmode, mem, operands[4]));
- +
- + DONE;
- + }
- +)
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_operand:SI 1 "metag_reg12bit_op" "")
- + (match_operand:SI 2 "metag_offset12_<mode>" "")))
- + (set (match_operand:MEMOP 3 "memory_operand" "")
- + (match_operand:<MODE> 4 "metag_reg_nofloat_op" ""))]
- + "peep2_reg_dead_p (2, operands[0])
- + && REGNO (operands[0]) != REGNO (operands[4])
- + && rtx_equal_p (operands[0], XEXP (operands[3], 0))"
- + [(const_int 0)]
- + {
- + rtx plus = gen_rtx_PLUS (SImode, operands[1], operands[2]);
- + rtx mem = gen_rtx_MEM (<MODE>mode, plus);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]);
- + emit_insn (gen_rtx_SET (VOIDmode, mem, operands[4]));
- +
- + DONE;
- + }
- +)
- +
- +;; QI/HI->SI zero_extend load removing unneccessary temporary
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (high:SI (match_operand:SI 1 "metag_symglobal_op" "")))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1)))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (plus:SI (match_dup 2)
- + (match_dup 0)))
- + (set (match_operand:SI 3 "metag_register_op" "")
- + (zero_extend:SI
- + (match_operand:EXTSI 4 "memory_operand" "")))]
- + "!METAG_FLAG_PIC
- + && peep2_reg_dead_p (4, operands[2])
- + && peep2_reg_dead_p (3, operands[0])
- + && GET_MODE (XEXP (operands[4], 0)) == SImode
- + && GET_CODE (XEXP (operands[4], 0)) == PLUS
- + && rtx_equal_p (operands[2], XEXP (XEXP (operands[4], 0), 0))
- + && const_int_operand (XEXP (XEXP (operands[4], 0), 1), SImode)
- + && metag_regno_same_unit_p (REGNO (operands[2]), REGNO (operands[0]))"
- +
- + [(const_int 0)]
- + {
- + rtx plus, mem, zextend;
- + operands[5] = XEXP (XEXP (operands[4], 0), 1);
- + operands[6] = gen_rtx_CONST (SImode,
- + gen_rtx_PLUS (SImode,
- + operands[1],
- + operands[5]));
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + operands[0],
- + gen_rtx_HIGH (SImode,
- + operands[6])));
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + operands[0],
- + gen_rtx_LO_SUM (SImode,
- + operands[0],
- + operands[6])));
- +
- + plus = gen_rtx_PLUS (SImode, operands[2], operands[0]);
- + mem = gen_rtx_MEM (<MODE>mode, plus);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[4]);
- + zextend = gen_rtx_ZERO_EXTEND (SImode, mem);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[3], zextend));
- + DONE;
- + }
- +)
- +
- +;; QI->HI zero_extend load removing unneccessary temporary
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (high:SI (match_operand:SI 1 "metag_symglobal_op" "")))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1)))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (plus:SI (match_dup 2)
- + (match_dup 0)))
- + (set (match_operand:HI 3 "metag_register_op" "")
- + (zero_extend:HI
- + (match_operand:EXTHI 4 "memory_operand" "")))]
- + "!METAG_FLAG_PIC
- + && peep2_reg_dead_p (4, operands[2])
- + && peep2_reg_dead_p (3, operands[0])
- + && GET_MODE (XEXP (operands[4], 0)) == SImode
- + && GET_CODE (XEXP (operands[4], 0)) == PLUS
- + && rtx_equal_p (operands[2], XEXP (XEXP (operands[4], 0), 0))
- + && const_int_operand (XEXP (XEXP (operands[4], 0), 1), SImode)
- + && metag_regno_same_unit_p (REGNO (operands[2]), REGNO (operands[0]))"
- + [(const_int 0)]
- + {
- + rtx plus, mem, zextend;
- + operands[5] = XEXP (XEXP (operands[4], 0), 1);
- + operands[6] = gen_rtx_CONST (SImode,
- + gen_rtx_PLUS (SImode,
- + operands[1],
- + operands[5]));
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + operands[0],
- + gen_rtx_HIGH (SImode,
- + operands[6])));
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + operands[0],
- + gen_rtx_LO_SUM (SImode,
- + operands[0],
- + operands[6])));
- +
- + plus = gen_rtx_PLUS (SImode, operands[2], operands[0]);
- + mem = gen_rtx_MEM (<MODE>mode, plus);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[4]);
- + zextend = gen_rtx_ZERO_EXTEND (HImode, mem);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[3], zextend));
- + DONE;
- + }
- +)
- +
- +;; QI, HI and SI mode load, removing unneccessary temporary
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (high:SI (match_operand:SI 1 "metag_symglobal_op" "")))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1)))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (plus:SI (match_dup 2)
- + (match_dup 0)))
- + (set (match_operand:<MODE> 3 "metag_register_op" "")
- + (match_operand:MEMOP 4 "memory_operand" ""))]
- + "!METAG_FLAG_PIC
- + && peep2_reg_dead_p (4, operands[2])
- + && peep2_reg_dead_p (3, operands[0])
- + && GET_MODE (XEXP (operands[4], 0)) == SImode
- + && GET_CODE (XEXP (operands[4], 0)) == PLUS
- + && rtx_equal_p (operands[2], XEXP (XEXP (operands[4], 0), 0))
- + && const_int_operand (XEXP (XEXP (operands[4], 0), 1), SImode)
- + && metag_regno_same_unit_p (REGNO (operands[2]), REGNO (operands[0]))"
- + [(const_int 0)]
- + {
- + rtx plus, mem;
- + operands[5] = XEXP (XEXP (operands[4], 0), 1);
- + operands[6] = gen_rtx_CONST (SImode,
- + gen_rtx_PLUS (SImode,
- + operands[1],
- + operands[5]));
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + operands[0],
- + gen_rtx_HIGH (SImode,
- + operands[6])));
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + operands[0],
- + gen_rtx_LO_SUM (SImode,
- + operands[0],
- + operands[6])));
- +
- + plus = gen_rtx_PLUS (SImode, operands[2], operands[0]);
- + mem = gen_rtx_MEM (<MODE>mode, plus);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[4]);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[3], mem));
- + DONE;
- + }
- +)
- +
- +;; QI/HI->SI zero_extend when result register same as temporary address register
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (high:SI (match_operand:SI 1 "metag_symglobal_op" "")))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1)))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (plus:SI (match_dup 2)
- + (match_dup 0)))
- + (set (match_dup 2)
- + (zero_extend:SI
- + (match_operand:EXTSI 3 "memory_operand" "")))]
- + "!METAG_FLAG_PIC
- + && peep2_reg_dead_p (3, operands[0])
- + && GET_MODE (XEXP (operands[3], 0)) == SImode
- + && GET_CODE (XEXP (operands[3], 0)) == PLUS
- + && rtx_equal_p (operands[2], XEXP (XEXP (operands[3], 0), 0))
- + && const_int_operand (XEXP (XEXP (operands[3], 0), 1), SImode)
- + && metag_regno_same_unit_p (REGNO (operands[2]), REGNO (operands[0]))"
- + [(const_int 0)]
- + {
- + rtx plus, mem, zextend;
- + operands[4] = XEXP (XEXP (operands[3], 0), 1);
- + operands[5] = gen_rtx_CONST (SImode,
- + gen_rtx_PLUS (SImode,
- + operands[1],
- + operands[4]));
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + operands[0],
- + gen_rtx_HIGH (SImode,
- + operands[5])));
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + operands[0],
- + gen_rtx_LO_SUM (SImode,
- + operands[0],
- + operands[5])));
- +
- + plus = gen_rtx_PLUS (SImode, operands[2], operands[0]);
- + mem = gen_rtx_MEM (<MODE>mode, plus);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]);
- + zextend = gen_rtx_ZERO_EXTEND (SImode, mem);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[2], zextend));
- + DONE;
- + }
- +)
- +
- +;; result register same as temporary address.
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (high:SI (match_operand:SI 1 "metag_symglobal_op" "")))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1)))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (plus:SI (match_dup 2)
- + (match_dup 0)))
- + (set (match_operand:<MODE> 3 "metag_register_op" "")
- + (match_operand:MEMOP 4 "memory_operand" ""))]
- +
- + "!METAG_FLAG_PIC
- + && peep2_reg_dead_p (3, operands[0])
- + && REGNO (operands[3]) == REGNO (operands[2])
- + && GET_MODE (XEXP (operands[4], 0)) == SImode
- + && GET_CODE (XEXP (operands[4], 0)) == PLUS
- + && rtx_equal_p (operands[2], XEXP (XEXP (operands[4], 0), 0))
- + && const_int_operand (XEXP (XEXP (operands[4], 0), 1), SImode)
- + && metag_regno_same_unit_p (REGNO (operands[2]), REGNO (operands[0]))"
- + [(const_int 0)]
- + {
- + rtx plus, mem;
- + operands[5] = XEXP (XEXP (operands[4], 0), 1);
- + operands[6] = gen_rtx_CONST (SImode,
- + gen_rtx_PLUS (SImode,
- + operands[1],
- + operands[5]));
- + operands[7] = gen_rtx_REG (<MODE>mode, REGNO (operands[2]));
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + operands[0],
- + gen_rtx_HIGH (SImode,
- + operands[6])));
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + operands[0],
- + gen_rtx_LO_SUM (SImode,
- + operands[0],
- + operands[6])));
- +
- + plus = gen_rtx_PLUS (SImode, operands[2], operands[0]);
- + mem = gen_rtx_MEM (<MODE>mode, plus);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[4]);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[7], mem));
- + DONE;
- + }
- +)
- +
- +;; QI, HI and SI mode store, removing unneccessary temporary
- +
- +(define_peephole2
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (high:SI (match_operand:SI 1 "metag_symglobal_op" "")))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (match_dup 1)))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (plus:SI (match_dup 2)
- + (match_dup 0)))
- + (set (match_operand:MEMOP 3 "memory_operand" "")
- + (match_operand:<MODE> 4 "metag_register_op" "") )]
- + "!METAG_FLAG_PIC
- + && peep2_reg_dead_p (4, operands[2])
- + && peep2_reg_dead_p (3, operands[0])
- + && GET_MODE (XEXP (operands[3], 0)) == SImode
- + && GET_CODE (XEXP (operands[3], 0)) == PLUS
- + && rtx_equal_p (operands[2], XEXP (XEXP (operands[3], 0), 0))
- + && const_int_operand (XEXP (XEXP (operands[3], 0), 1), SImode)
- + && metag_regno_same_unit_p (REGNO (operands[2]), REGNO (operands[0]))
- + && !metag_regno_same_unit_p (REGNO (operands[2]), REGNO (operands[4]))"
- + [(const_int 0)]
- + {
- + operands[5] = XEXP (XEXP (operands[3], 0), 1);
- + operands[6] = gen_rtx_CONST (SImode,
- + gen_rtx_PLUS (SImode,
- + operands[1],
- + operands[5]));
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + operands[0],
- + gen_rtx_HIGH (SImode,
- + operands[6])));
- +
- + emit_insn (gen_rtx_SET (VOIDmode,
- + operands[0],
- + gen_rtx_LO_SUM (SImode,
- + operands[0],
- + operands[6])));
- +
- + rtx plus = gen_rtx_PLUS (SImode, operands[2], operands[0]);
- + rtx mem = gen_rtx_MEM (<MODE>mode, plus);
- + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]);
- + emit_insn (gen_rtx_SET (VOIDmode, mem, operands[4]));
- + DONE;
- + }
- +)
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/peephole.md gcc-4.2.4/gcc/config/metag/peephole.md
- --- gcc-4.2.4.orig/gcc/config/metag/peephole.md 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/peephole.md 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,491 @@
- +;; Machine description for GNU compiler,
- +;; Imagination Technologies Meta version.
- +;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
- +;; Imagination Technologies Ltd
- +
- +;; This file is part of GCC.
- +
- +;; GCC 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 3, or (at your option) any later
- +;; version.
- +
- +;; GCC 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 GCC; see the file COPYING3. If not see
- +;; <http://www.gnu.org/licenses/>.
- +
- +;;- peephole patterns
- +
- +;; set full condition flags during move, flags from source value
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (match_operand:SI 1 "metag_datareg_op" ""))
- + (set (reg:<MODE> CC_REG)
- + (compare:CCANY
- + (match_dup 1)
- + (const_int 0)))]
- + "!metag_cond_exec_p ()
- + && REGNO (operands[0]) <= LAST_ADDR_REG
- + && METAG_DATA_REG_P (REGNO (operands[1]))"
- + "SUBS\\t%0, %1, #0\\t\\t%@ (*movs rd 1 OK)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +;; set full condition flags during move, flags from dest value
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (match_operand:SI 1 "metag_datareg_op" ""))
- + (set (reg:<MODE> CC_REG)
- + (compare:CCANY
- + (match_dup 0)
- + (const_int 0)))]
- + "!metag_cond_exec_p ()
- + && REGNO (operands[0]) <= LAST_ADDR_REG
- + && METAG_DATA_REG_P (REGNO (operands[1]))"
- + "SUBS\\t%0, %1, #0\\t\\t%@ (*movs rd 0 OK)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +;; set condition flags during sign extension of a hi value
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (sign_extend:SI (match_operand:HI 1 "metag_datareg_op" "")))
- + (set (reg:CCZNC CC_REG)
- + (compare:<MODE>
- + (match_dup 0)
- + (const_int 0)))]
- + "!metag_cond_exec_p ()"
- + "XSDSW\\t%0, %1\\t\\t%@ (*exts hisi dd OK)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +;; set condition flags during sign extension of a qi value
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_datareg_op" "")
- + (sign_extend:SI (match_operand:QI 1 "metag_datareg_op" "")))
- + (set (reg:CCZNC CC_REG)
- + (compare:<MODE>
- + (match_dup 0)
- + (const_int 0)))]
- + "!metag_cond_exec_p ()"
- + "XSDSB\\t%0, %1\\t\\t%@ (*exts qisi dd OK)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "set")])
- +
- +;; Detect oppurtunities for post-increments of DI mode stores
- +(define_peephole
- + [(set (mem:DI (match_operand:SI 0 "metag_register_op" ""))
- + (match_operand:DI 1 "metag_register_op" ""))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 2 "metag_offset6_di" "")))]
- + "TARGET_METAC_1_1 && !metag_cond_exec_p ()"
- + "SETL\\t[%0+%2++], %1, %t1\\t%@ (*store DI post_inc OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (plus:SI (match_dup 0)
- + (match_operand:SI 2 "metag_offset6_di" "")))
- + (set (mem:DI (match_dup 0))
- + (match_operand:DI 1 "metag_register_op" ""))]
- + "TARGET_METAC_1_1 && !metag_cond_exec_p ()"
- + "SETL\\t[%0++%2], %1, %t1\\t%@ (*store DI pre_inc OK)"
- + [(set_attr "type" "fast")])
- +
- +;; Detect oppurtunities for post-increments of stores - not 1_1
- +(define_peephole
- + [(set (mem:SI (match_operand:SI 0 "metag_register_op" ""))
- + (match_operand:SI 2 "metag_register_op" ""))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_register_op" "")))]
- + "0 && !metag_cond_exec_p ()
- + && !TARGET_METAC_1_1"
- + "SETD\\t[%0+%1++], %2\\t%@ (*sto si maar OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_peephole
- + [(set (mem:SI (match_operand:SI 0 "metag_register_op" ""))
- + (match_operand:SI 2 "metag_register_op" ""))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_si" "")))]
- + "0 && !metag_cond_exec_p ()
- + && !TARGET_METAC_1_1"
- + "SETD\\t[%0+%1++], %2\\t%@ (*sto si miar OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_peephole
- + [(set (mem:HI (match_operand:SI 0 "metag_register_op" ""))
- + (match_operand:HI 2 "metag_register_op" ""))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_register_op" "")))]
- + "0 && !metag_cond_exec_p ()
- + && !TARGET_METAC_1_1"
- + "SETW\\t[%0+%1++], %2\\t%@ (*sto hi maar OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_peephole
- + [(set (mem:HI (match_operand:SI 0 "metag_register_op" ""))
- + (match_operand:HI 2 "metag_register_op" ""))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_hi" "")))]
- + "0 && !metag_cond_exec_p ()
- + && !TARGET_METAC_1_1"
- + "SETW\\t[%0+%1++], %2\\t%@ (*sto hi miar OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_peephole
- + [(set (mem:QI (match_operand:SI 0 "metag_register_op" ""))
- + (match_operand:QI 2 "metag_register_op" ""))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_register_op" "")))]
- + "0 && !metag_cond_exec_p ()
- + && !TARGET_METAC_1_1"
- + "SETB\\t[%0+%1++], %2\\t%@ (*sto qi maar OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_peephole
- + [(set (mem:QI (match_operand:SI 0 "metag_register_op" ""))
- + (match_operand:QI 2 "metag_register_op" ""))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_qi" "")))]
- + "0 && !metag_cond_exec_p ()
- + && !TARGET_METAC_1_1"
- + "SETB\\t[%0+%1++], %2\\t%@ (*sto qi miar OK)"
- + [(set_attr "type" "fast")])
- +
- +;; Detect oppurtunities for post-increments of stores - 1_1
- +(define_peephole
- + [(set (mem:SI (match_operand:SI 0 "metag_register_op" ""))
- + (match_operand:SI 2 "metag_register_op" ""))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_register_op" "")))]
- + "!metag_cond_exec_p ()
- + && TARGET_METAC_1_1
- + && metag_same_regclass_p (operands[0], operands[1])
- + && !metag_same_regclass_p (operands[0], operands[2])"
- + "SETD\\t[%0+%1++], %2\\t%@ (*sto si maar OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_peephole
- + [(set (mem:SI (match_operand:SI 0 "metag_register_op" ""))
- + (match_operand:SI 2 "metag_register_op" ""))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_si" "")))]
- + "!metag_cond_exec_p ()
- + && TARGET_METAC_1_1"
- + "SETD\\t[%0+%1++], %2\\t%@ (*sto si miar OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_peephole
- + [(set (mem:HI (match_operand:SI 0 "metag_register_op" ""))
- + (match_operand:HI 2 "metag_register_op" ""))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_register_op" "")))]
- + "!metag_cond_exec_p ()
- + && TARGET_METAC_1_1
- + && metag_same_regclass_p (operands[0], operands[1])
- + && !metag_same_regclass_p (operands[0], operands[2])"
- + "SETW\\t[%0+%1++], %2\\t%@ (*sto hi maar OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_peephole
- + [(set (mem:HI (match_operand:SI 0 "metag_register_op" ""))
- + (match_operand:HI 2 "metag_register_op" ""))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_hi" "")))]
- + "!metag_cond_exec_p ()
- + && TARGET_METAC_1_1"
- + "SETW\\t[%0+%1++], %2\\t%@ (*sto hi miar OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_peephole
- + [(set (mem:QI (match_operand:SI 0 "metag_register_op" ""))
- + (match_operand:QI 2 "metag_register_op" ""))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_register_op" "")))]
- + "!metag_cond_exec_p ()
- + && TARGET_METAC_1_1
- + && metag_same_regclass_p (operands[0], operands[1])
- + && !metag_same_regclass_p (operands[0], operands[2])"
- + "SETB\\t[%0+%1++], %2\\t%@ (*sto qi maar OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_peephole
- + [(set (mem:QI (match_operand:SI 0 "metag_register_op" ""))
- + (match_operand:QI 2 "metag_register_op" ""))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (match_operand:SI 1 "metag_offset6_qi" "")))]
- + "!metag_cond_exec_p ()
- + && TARGET_METAC_1_1"
- + "SETB\\t[%0+%1++], %2\\t%@ (*sto qi miar OK)"
- + [(set_attr "type" "fast")])
- +
- +;; Detect oppurtunities for post-increments of loads
- +
- +(define_peephole
- + [(set (match_operand:DI 0 "metag_register_op" "")
- + (mem:DI (match_operand:SI 1 "metag_register_op" "")))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_di" "")))]
- + "!metag_cond_exec_p ()"
- + "GETL\\t%0, %t0, [%1+%2++]\\t%@ (*load DI post_inc OK)"
- + [(set_attr "type" "load")])
- +
- +(define_peephole
- + [(set (match_operand:SI 1 "metag_register_op" "")
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_di" "")))
- + (set (match_operand:DI 0 "metag_register_op" "")
- + (mem:DI (match_dup 1)))]
- + "!metag_cond_exec_p ()"
- + "GETL\\t%0, %t0, [%1++%2]\\t%@ (*load DI pre_inc OK)"
- + [(set_attr "type" "load")])
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (mem:SI (match_operand:SI 1 "metag_register_op" "")))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_register_op" "")))]
- + "!metag_cond_exec_p ()
- + && REGNO (operands[0]) != REGNO (operands[1])
- + && REGNO (operands[0]) != REGNO (operands[2])
- + && metag_same_regclass_p (operands[1], operands[2])"
- + "GETD\\t%0, [%1+%2++]\\t%@ (*lod si rmaa OK)"
- + [(set_attr "type" "load")])
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (mem:SI (match_operand:SI 1 "metag_register_op" "")))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_si" "")))]
- + "!metag_cond_exec_p ()
- + && REGNO (operands[0]) != REGNO (operands[1])"
- + "GETD\\t%0, [%1+%2++]\\t%@ (*lod si rmia OK)"
- + [(set_attr "type" "load")])
- +
- +(define_peephole
- + [(set (match_operand:HI 0 "metag_register_op" "")
- + (mem:HI (match_operand:SI 1 "metag_register_op" "")))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_register_op" "")))]
- + "!metag_cond_exec_p ()
- + && REGNO (operands[0]) != REGNO (operands[1])
- + && REGNO (operands[0]) != REGNO (operands[2])
- + && metag_same_regclass_p (operands[1], operands[2])"
- + "GETW\\t%0, [%1+%2++]\\t%@ (*lod hi rmaa OK)"
- + [(set_attr "type" "load")])
- +
- +(define_peephole
- + [(set (match_operand:HI 0 "metag_register_op" "")
- + (mem:HI (match_operand:SI 1 "metag_register_op" "")))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_hi" "")))]
- + "!metag_cond_exec_p ()
- + && REGNO (operands[0]) != REGNO (operands[1])"
- + "GETW\\t%0, [%1+%2++]\\t%@ (*lod hi rmia OK)"
- + [(set_attr "type" "load")])
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (zero_extend:SI
- + (mem:HI (match_operand:SI 1 "metag_register_op" ""))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_register_op" "")))]
- + "!metag_cond_exec_p ()
- + && REGNO (operands[0]) != REGNO (operands[1])
- + && REGNO (operands[0]) != REGNO (operands[2])
- + && metag_same_regclass_p (operands[1], operands[2])"
- + "GETW\\t%0, [%1+%2++]\\t%@ (*lodz hi rmaa OK)"
- + [(set_attr "type" "load")])
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (zero_extend:SI
- + (mem:HI (match_operand:SI 1 "metag_register_op" ""))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_hi" "")))]
- + "!metag_cond_exec_p ()
- + && REGNO (operands[0]) != REGNO (operands[1])"
- + "GETW\\t%0, [%1+%2++]\\t%@ (*lodz hi rmia OK)"
- + [(set_attr "type" "load")])
- +
- +(define_peephole
- + [(set (match_operand:QI 0 "metag_register_op" "")
- + (mem:QI (match_operand:SI 1 "metag_register_op" "")))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_register_op" "")))]
- + "!metag_cond_exec_p ()
- + && REGNO (operands[0]) != REGNO (operands[1])
- + && REGNO (operands[0]) != REGNO (operands[2])
- + && metag_same_regclass_p (operands[1], operands[2])"
- + "GETB\\t%0, [%1+%2++]\\t%@ (*lod qi rmaa OK)"
- + [(set_attr "type" "load")])
- +
- +(define_peephole
- + [(set (match_operand:QI 0 "metag_register_op" "")
- + (mem:QI (match_operand:SI 1 "metag_register_op" "")))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_qi" "")))]
- + "!metag_cond_exec_p ()
- + && REGNO (operands[0]) != REGNO (operands[1])"
- + "GETB\\t%0, [%1+%2++]\\t%@ (*lod qi rmia OK)"
- + [(set_attr "type" "load")])
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (zero_extend:SI
- + (mem:QI (match_operand:SI 1 "metag_register_op" ""))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_register_op" "")))]
- + "!metag_cond_exec_p ()
- + && REGNO (operands[0]) != REGNO (operands[1])
- + && REGNO (operands[0]) != REGNO (operands[2])
- + && metag_same_regclass_p (operands[1], operands[2])"
- + "GETB\\t%0, [%1+%2++]\\t%@ (*lodz qi rmaa OK)"
- + [(set_attr "type" "load")])
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (zero_extend:SI
- + (mem:QI (match_operand:SI 1 "metag_register_op" ""))))
- + (set (match_dup 1)
- + (plus:SI (match_dup 1)
- + (match_operand:SI 2 "metag_offset6_qi" "")))]
- + "!metag_cond_exec_p ()
- + && REGNO (operands[0]) != REGNO (operands[1])"
- + "GETB\\t%0, [%1+%2++]\\t%@ (*lodz qi rmia OK)"
- + [(set_attr "type" "load")])
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (match_operand:SI 1 "metag_reg_nofloat_op" ""))
- + (set (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" ""))
- + (set (match_dup 2)
- + (match_dup 0))]
- + "!metag_same_regclass_p (operands[1], operands[2])
- + && dead_or_set_p (insn, operands[0])"
- + "SWAP%?\\t%1, %2"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")])
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "")
- + (match_operand:SI 1 "metag_reg_nofloat_op" ""))
- + (set (match_dup 1)
- + (match_operand:SI 2 "metag_reg_nofloat_op" ""))
- + (set (match_dup 2)
- + (match_dup 0))]
- + "!metag_same_regclass_p (operands[1], operands[2])"
- + "SWAP%?\\t%1, %2\\t\;MOV%?\\t%0, %2"
- + [(set_attr "type" "two")
- + (set_attr "cond" "yes")])
- +
- +;; Fixup some obvious reg alloc losage for loads
- +
- +(define_peephole
- + [(set (match_operand:QI 0 "metag_register_op" "")
- + (match_operand:QI 1 "memory_operand" ""))
- + (set (match_operand:QI 2 "metag_reg_nofloat_op" "")
- + (match_dup 0))]
- + "!metag_cond_exec_p ()
- + && dead_or_set_p (insn, operands[0])"
- + "GETB\\t%2, %1"
- + [(set_attr "type" "load")])
- +
- +(define_peephole
- + [(set (match_operand:HI 0 "metag_register_op" "")
- + (match_operand:HI 1 "memory_operand" ""))
- + (set (match_operand:HI 2 "metag_reg_nofloat_op" "")
- + (match_dup 0))]
- + "!metag_cond_exec_p ()
- + && dead_or_set_p (insn, operands[0])"
- + "GETW\\t%2, %1"
- + [(set_attr "type" "load")])
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (match_operand:SI 1 "memory_operand" ""))
- + (set (match_operand:SI 2 "metag_reg_nofloat_op" "")
- + (match_dup 0))]
- + "!metag_cond_exec_p ()
- + && dead_or_set_p (insn, operands[0])"
- + "GETD\\t%2, %1"
- + [(set_attr "type" "load")])
- +
- +;; misc peepholes
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (match_operand:SI 1 "metag_datareg_op" ""))
- + (set (reg:<MODE> CC_REG)
- + (compare:CCANY
- + (match_dup 0)
- + (match_operand:SI 2 "metag_int_operand" "")))]
- + "dead_or_set_p (insn, operands[0])"
- + "CMP%?\\t%1, %2"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")])
- +
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (match_operand:SI 1 "metag_datareg_op" ""))
- + (set (reg:<MODE> CC_REG)
- + (compare:CCANY
- + (match_dup 0)
- + (match_operand:SI 2 "metag_datareg_op" "")))]
- + "dead_or_set_p (insn, operands[0])
- + && metag_same_regclass_p (operands[0], operands[1])"
- + "CMP%?\\t%1, %2"
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")])
- +
- +;; This is an EVIL peephole. We should delete it!
- +(define_peephole
- + [(set (match_operand:SI 0 "metag_register_op" "")
- + (match_operand:SI 1 "metag_regorint_op" ""))
- + (set (match_operand:SI 2 "metag_register_op" "")
- + (match_dup 0))]
- + "!metag_cond_exec_p ()
- + && dead_or_set_p (insn, operands[0])
- + && metag_move_valid_p (operands[2], operands[1])"
- + {
- + if ((REG_P (operands[1]) && metag_fpcreg_p (REGNO (operands[1])))
- + || metag_fpcreg_p (REGNO (operands[2])))
- + return "F\\tMOV%?\\t%2, %1";
- + else if (metag_J_operand (operands[1], SImode))
- + return "MOVT%?\\t%2, %1";
- + else
- + return "MOV%?\\t%2, %1";
- + }
- + [(set_attr "type" "fast")
- + (set_attr "cond" "yes")])
- +
- +;; end of file
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/pipeline.md gcc-4.2.4/gcc/config/metag/pipeline.md
- --- gcc-4.2.4.orig/gcc/config/metag/pipeline.md 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/pipeline.md 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,335 @@
- +;; Machine description for GNU compiler,
- +;; Imagination Technologies Meta version.
- +;; Copyright (C) 2007
- +;; Imagination Technologies Ltd
- +
- +;; This file is part of GCC.
- +
- +;; GCC 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 3, or (at your option) any later
- +;; version.
- +
- +;; GCC 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 GCC; see the file COPYING3. If not see
- +;; <http://www.gnu.org/licenses/>.
- +
- +(define_automaton "metag")
- +
- +;; The UI and U2U instuctions have different ports to write results
- +(define_cpu_unit "UI_port, U2U_port, load_port" "metag")
- +
- +;; The FPU ports to write results
- +(define_cpu_unit "FP_port1, FP_port2" "metag")
- +
- +;; The FPU pipeline
- +(define_cpu_unit "mas1, mas2, mas3, mas4, mas5, recip1, recip2, recip3" "metag")
- +
- +;; All instructions have to be fetched!
- +(define_cpu_unit "issue" "metag")
- +
- +;; Multi-cycle operation stages
- +(define_cpu_unit "opfetch, execute" "metag")
- +
- +(define_cpu_unit "branch, load, read, mult" "metag")
- +
- +;; Simple case, single cycle operations
- +(define_insn_reservation "UI" 1
- + (eq_attr "type" "fast")
- + "issue, UI_port")
- +
- +;; WORK NEEDED: This needs checking, does a swap need to write each register on separate cycles?
- +(define_insn_reservation "UIswap" 1
- + (eq_attr "type" "swap")
- + "issue, UI_port, UI_port")
- +
- +;; Unknown type insns are user supplied ASM, invalid should not occur and nop is...
- +(define_insn_reservation "UIother" 1
- + (eq_attr "type" "unknown, invalid, nop, block")
- + "issue, UI_port")
- +
- +;; Multiply has 2 cycle latency (only MULD comes through here)
- +(define_insn_reservation "UImult" 2
- + (eq_attr "type" "mult")
- + "issue, mult, UI_port")
- +
- +;; Multiple UI instruction have a complex latency
- +(define_insn_reservation "UIUI" 2
- + (eq_attr "type" "two")
- + "issue, issue + UI_port, UI_port")
- +
- +(define_insn_reservation "UIUIUI" 3
- + (eq_attr "type" "three")
- + "issue, issue + UI_port, issue + UI_port, UI_port")
- +
- +(define_insn_reservation "UIUIUIUI" 4
- + (eq_attr "type" "four")
- + "issue, issue + UI_port, issue + UI_port, issue + UI_port, UI_port")
- +
- +(define_insn_reservation "UIUIUIUIUI" 5
- + (eq_attr "type" "five")
- + "issue, issue + UI_port, issue + UI_port, issue + UI_port, issue + UI_port, UI_port")
- +
- +;; Inter unit operations
- +;; Results are written on 3rd cycle but are ready to be used on 2nd cycle using feedback path
- +(define_insn_reservation "U2U" 2
- + (eq_attr "type" "slow")
- + "issue, opfetch, execute, U2U_port")
- +
- +(define_insn_reservation "U2UU2U" 3
- + (eq_attr "type" "slowslow")
- + "issue, issue + opfetch, opfetch + execute, execute + U2U_port, U2U_port")
- +
- +;; META 2 FPU
- +
- +(define_reservation "FP_ports" "FP_port1 | FP_port2")
- +(define_reservation "mas" "mas1, mas2, mas3, mas4, mas5")
- +(define_reservation "recip" "recip1, recip2, recip3")
- +
- +(define_insn_reservation "FP" 1
- + (eq_attr "type" "FPfast")
- + "issue, FP_ports")
- +
- +(define_insn_reservation "FPmas" 5
- + (eq_attr "type" "FPmas")
- + "issue, mas, FP_ports")
- +
- +(define_insn_reservation "FPrecip" 3
- + (eq_attr "type" "FPrecip")
- + "issue, recip, FP_ports")
- +
- +(define_insn_reservation "FPrecipmas" 8
- + (eq_attr "type" "FPrecipmas")
- + "issue, recip, FP_ports + issue, mas, FP_ports")
- +
- +;; META 2_1
- +(define_insn_reservation "branch_2_1" 5
- + (and (eq_attr "metacore" "metac_2_1")
- + (eq_attr "type" "branch"))
- + "issue, branch*3, UI_port")
- +
- +(define_insn_reservation "load_2_1" 3
- + (and (eq_attr "metacore" "metac_2_1")
- + (eq_attr "type" "load"))
- + "issue, load, load_port")
- +
- +(define_insn_reservation "read_2_1" 3
- + (and (eq_attr "metacore" "metac_2_1")
- + (eq_attr "type" "read"))
- + "issue, read, load_port")
- +
- +;; META 1_2
- +(define_insn_reservation "branch_1_2" 5
- + (and (eq_attr "metacore" "metac_1_2")
- + (eq_attr "type" "branch"))
- + "issue, branch*3, UI_port")
- +
- +(define_insn_reservation "load_1_2" 3
- + (and (eq_attr "metacore" "metac_1_2")
- + (eq_attr "type" "load"))
- + "issue, load, load_port")
- +
- +(define_insn_reservation "read_1_2" 3
- + (and (eq_attr "metacore" "metac_1_2")
- + (eq_attr "type" "read"))
- + "issue, read, load_port")
- +;; META 1_1
- +(define_insn_reservation "branch_1_1" 6
- + (and (eq_attr "metacore" "metac_1_1")
- + (eq_attr "type" "branch"))
- + "issue, branch*4, UI_port")
- +
- +(define_insn_reservation "load_1_1" 8
- + (and (eq_attr "metacore" "metac_1_1")
- + (eq_attr "type" "load"))
- + "issue, load, load_port")
- +
- +(define_insn_reservation "read_1_1" 8
- + (and (eq_attr "metacore" "metac_1_1")
- + (eq_attr "type" "read"))
- + "issue, read, load_port")
- +;; META 1_0
- +(define_insn_reservation "branch_1_0" 7
- + (and (eq_attr "metacore" "metac_1_0")
- + (eq_attr "type" "branch"))
- + "issue, branch*5, UI_port")
- +
- +(define_insn_reservation "load_1_0" 10
- + (and (eq_attr "metacore" "metac_1_0")
- + (eq_attr "type" "load"))
- + "issue, load, load_port")
- +
- +(define_insn_reservation "read_1_0" 9
- + (and (eq_attr "metacore" "metac_1_0")
- + (eq_attr "type" "read"))
- + "issue, read, load_port")
- +
- +;; MGET latencies are complex... The minimum latency is specified here
- +;; and the more complex work is done in metag_sched_adjust_cost
- +
- +;; META 1_2 and 2_1
- +(define_insn_reservation "UI2xld_2_1" 1
- + (and (ior (eq_attr "metacore" "metac_1_2")
- + (eq_attr "metacore" "metac_2_1"))
- + (and (eq_attr "type" "twox")
- + (eq_attr "memaccess" "load")))
- + "issue, issue, load_port, load_port")
- +
- +(define_insn_reservation "UI3xld_2_1" 1
- + (and (ior (eq_attr "metacore" "metac_1_2")
- + (eq_attr "metacore" "metac_2_1"))
- + (and (eq_attr "type" "threex")
- + (eq_attr "memaccess" "load")))
- + "issue, issue, issue + load_port, load_port, load_port")
- +
- +(define_insn_reservation "UI4xld_2_1" 1
- + (and (ior (eq_attr "metacore" "metac_1_2")
- + (eq_attr "metacore" "metac_2_1"))
- + (and (eq_attr "type" "fourx")
- + (eq_attr "memaccess" "load")))
- + "issue, issue, issue + load_port, issue + load_port, load_port, load_port")
- +
- +(define_insn_reservation "UI5xld_2_1" 1
- + (and (ior (eq_attr "metacore" "metac_1_2")
- + (eq_attr "metacore" "metac_2_1"))
- + (and (eq_attr "type" "fivex")
- + (eq_attr "memaccess" "load")))
- + "issue, issue, issue + load_port, issue + load_port, issue + load_port, load_port, load_port")
- +
- +;; META 1_1 - The stalls are not accurately modelled here
- +(define_insn_reservation "UI2xld_1_1" 7
- + (and (eq_attr "metacore" "metac_1_1")
- + (and (eq_attr "type" "twox")
- + (eq_attr "memaccess" "load")))
- + "issue, issue, load*5, load_port, load_port")
- +
- +(define_insn_reservation "UI3xld_1_1" 7
- + (and (eq_attr "metacore" "metac_1_1")
- + (and (eq_attr "type" "threex")
- + (eq_attr "memaccess" "load")))
- + "issue, issue, issue, load *4, load_port, load_port, load_port")
- +
- +(define_insn_reservation "UI4xld_1_1" 7
- + (and (eq_attr "metacore" "metac_1_1")
- + (and (eq_attr "type" "fourx")
- + (eq_attr "memaccess" "load")))
- + "issue, issue, issue, issue, load*3, load_port, load_port, load_port, load_port")
- +
- +(define_insn_reservation "UI5xld_1_1" 7
- + (and (eq_attr "metacore" "metac_1_1")
- + (and (eq_attr "type" "fivex")
- + (eq_attr "memaccess" "load")))
- + "issue, issue, issue, issue, issue, load*2, load_port, load_port, load_port, load_port, load_port")
- +
- +;; META 1_0 - The stalls are not accurately modelled here
- +(define_insn_reservation "UI2xld_1_0" 9
- + (and (eq_attr "metacore" "metac_1_0")
- + (and (eq_attr "type" "twox")
- + (eq_attr "memaccess" "load")))
- + "issue, issue, load*8, load_port, load_port")
- +
- +(define_insn_reservation "UI3xld_1_0" 9
- + (and (eq_attr "metacore" "metac_1_0")
- + (and (eq_attr "type" "threex")
- + (eq_attr "memaccess" "load")))
- + "issue, issue, issue, load*7, load_port, load_port, load_port")
- +
- +(define_insn_reservation "UI4xld_1_0" 9
- + (and (eq_attr "metacore" "metac_1_0")
- + (and (eq_attr "type" "fourx")
- + (eq_attr "memaccess" "load")))
- + "issue, issue, issue, issue, load*6, load_port, load_port, load_port, load_port")
- +
- +(define_insn_reservation "UI5xld_1_0" 9
- + (and (eq_attr "metacore" "metac_1_0")
- + (and (eq_attr "type" "fivex")
- + (eq_attr "memaccess" "load")))
- + "issue, issue, issue, issue, issue, load*5, load_port, load_port, load_port, load_port, load_port")
- +
- +(define_insn_reservation "UI2xst" 1
- + (and (eq_attr "type" "twox")
- + (eq_attr "memaccess" "store"))
- + "issue, issue")
- +
- +(define_insn_reservation "UI3xst" 1
- + (and (eq_attr "type" "threex")
- + (eq_attr "memaccess" "store"))
- + "issue, issue, issue")
- +
- +(define_insn_reservation "UI4xst" 1
- + (and (eq_attr "type" "fourx")
- + (eq_attr "memaccess" "store"))
- + "issue, issue, issue, issue")
- +
- +(define_insn_reservation "UI5xst" 1
- + (and (eq_attr "type" "fivex")
- + (eq_attr "memaccess" "store"))
- + "issue, issue, issue, issue, issue")
- +
- +;; Catch all the cond_exec cases that will cause single cycle ops to become 3 cycle
- +;; WORK NEEDED: optimize those cases where the condition is ALWAYS or NONE or if the
- +;; condition value is known at issue (no updates to CC in the pipeline).
- +;; In such cases the instruction becomes UI (if it were UI to start with).
- +(define_bypass 2 "UI, FP"
- + "UIother,UI,UIswap,UImult, \
- + UIUI,UIUIUI,UIUIUIUI,UIUIUIUIUI,U2U,U2UU2U, \
- + branch_2_1,load_2_1,read_2_1, \
- + branch_1_2,load_1_2,read_1_2, \
- + branch_1_1,load_1_1,read_1_1, \
- + branch_1_0,load_1_0,read_1_0, \
- + UI2xld_2_1,UI3xld_2_1,UI4xld_2_1,UI5xld_2_1, \
- + UI2xld_1_1,UI3xld_1_1,UI4xld_1_1,UI5xld_1_1, \
- + UI2xld_1_0,UI3xld_1_0,UI4xld_1_0,UI5xld_1_0, \
- + UI2xst,UI3xst,UI4xst,UI5xst,\
- + FP, FPmas, FPrecip, FPrecipmas"
- + "metag_consumer_is_cond_p")
- +
- +;; SWAP has to write two registers so in effect takes 2 cycles rather than one so it is
- +;; a slightly slower case.
- +(define_bypass 4 "UIswap"
- + "UIother,UI,UIswap,UImult, \
- + UIUI,UIUIUI,UIUIUIUI,UIUIUIUIUI,U2U,U2UU2U, \
- + branch_2_1,load_2_1,read_2_1, \
- + branch_1_2,load_1_2,read_1_2, \
- + branch_1_1,load_1_1,read_1_1, \
- + branch_1_0,load_1_0,read_1_0, \
- + UI2xld_2_1,UI3xld_2_1,UI4xld_2_1,UI5xld_2_1, \
- + UI2xld_1_1,UI3xld_1_1,UI4xld_1_1,UI5xld_1_1, \
- + UI2xld_1_0,UI3xld_1_0,UI4xld_1_0,UI5xld_1_0, \
- + UI2xst,UI3xst,UI4xst,UI5xst, \
- + FP, FPmas, FPrecip, FPrecipmas"
- + "metag_consumer_is_cond_p")
- +
- +;; Regalloc/reload needs registers to have the shortest possible lifetime in order to
- +;; successfully allocate registers. D0Re0, D1Re0, D1Ar6, D0Ar5 are very popular
- +;; especially with modes that require 2 registers, load/store multiops,
- +;; base + 12bit offset memory operations, argument registers, return registers...
- +
- +;; The automata is very pessimistic when it comes across insns with multiple opcodes
- +;; it assumes that they will never be split. In reality almost all are split and
- +;; therefore scheduling them as one block before reload has a negative effect on
- +;; the associated registers lifetime (it increases). To counter this we bypass the
- +;; automata prior to reload to say that multi opcode insns actually have no latency,
- +;; i.e. ignore them completely, there is nothing that can be inferred.
- +;; After reload they are treated as proper insns.
- +
- +;; The reduced lifetime gives the register allocator and reload more scope to fulfil
- +;; insns constraints.
- +(define_bypass 0 "UIUI,UIUIUI,UIUIUIUI,UIUIUIUIUI,U2U,U2UU2U"
- + "UI,UIswap,UIother,UImult,UIUI,UIUIUI,UIUIUIUI,UIUIUIUIUI, \
- + U2U,U2UU2U,FP,FPmas,FPrecip,FPrecipmas, \
- + branch_2_1,load_2_1,read_2_1, \
- + branch_1_2,load_1_2,read_1_2, \
- + branch_1_1,load_1_1,read_1_1, \
- + branch_1_0,load_1_0,read_1_0, \
- + UI2xld_2_1,UI3xld_2_1,UI4xld_2_1,UI5xld_2_1, \
- + UI2xld_1_1,UI3xld_1_1,UI4xld_1_1,UI5xld_1_1, \
- + UI2xld_1_0,UI3xld_1_0,UI4xld_1_0,UI5xld_1_0, \
- + UI2xst,UI3xst,UI4xst,UI5xst"
- + "metag_bypass_before_reload_p")
- +
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/predicates.md gcc-4.2.4/gcc/config/metag/predicates.md
- --- gcc-4.2.4.orig/gcc/config/metag/predicates.md 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/predicates.md 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,815 @@
- +;; Predicate definitions for META
- +;; Copyright (C) 2007, 2010 Imagination Technologies Ltd
- +
- +;; This file is part of GCC.
- +
- +;; GCC 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 3, or (at your option) any later
- +;; version.
- +
- +;; GCC 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 GCC; see the file COPYING3. If not see
- +;; <http://www.gnu.org/licenses/>.
- +
- +(define_predicate "metag_register_op"
- +(match_code "subreg,reg")
- +{
- + if (!register_operand (op, mode))
- + return false;
- +
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + return !REG_P (op) || (REGNO (op) != TXRPT_REG
- + && REGNO (op) != TTREC_REG);
- +})
- +
- +(define_predicate "metag_reg_nofloat_op"
- +(match_code "subreg,reg")
- +{
- + if (!register_operand (op, mode))
- + return false;
- +
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + return (!REG_P (op) || (REGNO (op) != TXRPT_REG
- + && REGNO (op) != TTREC_REG))
- + && !METAG_FPC_REG_P (REGNO (op));
- +})
- +
- +;; Any hard data register
- +(define_predicate "metag_hard_datareg_op"
- +(match_code "reg")
- +{
- + unsigned int regno = REGNO (op);
- +
- + return mode == GET_MODE (op)
- + && METAG_DATA_REG_P (regno);
- +})
- +
- +;; Any hard address register
- +(define_predicate "metag_hard_addrreg_op"
- +(match_code "reg")
- +{
- + unsigned int regno = REGNO (op);
- +
- + return mode == GET_MODE (op)
- + && METAG_ADDR_REG_P (regno);
- +})
- +
- +;; Any hard gen register
- +(define_predicate "metag_hard_genreg_op"
- +(ior (match_operand 0 "metag_hard_datareg_op")
- + (match_operand 0 "metag_hard_addrreg_op")))
- +
- +(define_predicate "metag_regnofrm_op"
- +(match_code "subreg,reg")
- +{
- + if (metag_reg_nofloat_op (op, mode))
- + {
- + /* Subreg can hide a lot of non-reg things that we don't want! */
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + /* Reject all stack frame related pointers. */
- + return !metag_frame_related_rtx (op);
- + }
- +
- + return false;
- +})
- +
- +
- +(define_predicate "metag_regframe_op"
- +(match_code "subreg,reg")
- +{
- + if (metag_register_op (op, mode))
- + {
- + /* Subreg can hide a lot of non-reg things that we don't want! */
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + /* Accept only stack relasted pointers */
- + return metag_frame_related_rtx (op);
- + }
- +
- + return false;
- +})
- +
- +(define_predicate "metag_regorint_op"
- +(match_code "subreg,reg,const_int")
- +{
- + /* Integer constants are allowed */
- + if (CONST_INT_P (op))
- + return true;
- +
- + return metag_register_op (op, mode);
- +})
- +
- +(define_predicate "metag_okbindex_op"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_O1 (op)")))
- +
- +(define_predicate "metag_okwindex_op"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_O2 (op)")))
- +
- +(define_predicate "metag_okdindex_op"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_O4 (op)")))
- +
- +(define_predicate "metag_oklindex_op"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_O8 (op)")))
- +
- +(define_predicate "metag_int_operand"
- +(and (match_code "const_int")
- + (match_test "METAG_LETTER_FOR_CONST (op) != 0")))
- +
- +(define_predicate "metag_smallint_op"
- +(and (match_code "const_int")
- + (match_test "(INTVAL (op) >= -255 && INTVAL (op) <= 255)")))
- +
- +(define_predicate "metag_bigint_op"
- +(match_code "const_int"))
- +
- +(define_predicate "symbolic_operand"
- +(match_code "symbol_ref"))
- +
- +(define_predicate "metag_symsmall_op"
- +(and (match_code "symbol_ref")
- + (match_test "METAG_SYMBOL_FLAG_SMALL_P (op)")))
- +
- +(define_predicate "metag_symlarge_op"
- +(and (match_code "symbol_ref")
- + (match_test "METAG_SYMBOL_FLAG_LARGE_P (op)")))
- +
- +(define_predicate "metag_symglobal_op"
- +(and (match_code "symbol_ref")
- + (match_test "METAG_SYMBOL_FLAG_GLOBAL_P (op)")))
- +
- +(define_predicate "metag_symdirect_op"
- +(and (match_code "symbol_ref")
- + (match_test "METAG_SYMBOL_FLAG_DIRECT_P (op)")))
- +
- +(define_predicate "metag_call_addr"
- +(and (match_code "mem")
- + (ior (match_test "SYMBOL_REF_P (XEXP (op, 0))")
- + (match_test "REG_P (XEXP (op, 0))"))))
- +
- +(define_predicate "code_address"
- +(match_code "label_ref,symbol_ref")
- +{
- + /* Label references are the easy bit */
- + if (LABEL_REF_P (op))
- + return true;
- +
- + if (METAG_FLAG_PIC)
- + return false;
- +
- + return SYMBOL_REF_P (op)
- + && !METAG_SYMBOL_FLAG_SMALL_P (op)
- + && !METAG_SYMBOL_FLAG_LARGE_P (op)
- + && !METAG_SYMBOL_FLAG_GLOBAL_P (op)
- + && (SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_NONE);
- +})
- +
- +(define_predicate "metag_cc_reg"
- +(match_code "reg")
- +{
- + if (mode == VOIDmode)
- + {
- + mode = GET_MODE (op);
- + if (GET_MODE_CLASS (mode) != MODE_CC)
- + return false;
- + }
- +
- + return (mode == GET_MODE (op)
- + && REG_P (op)
- + && REGNO (op) == MCC_REGNUM);
- +})
- +
- +(define_predicate "metag_cc_noov_reg"
- +(match_code "reg")
- +{
- + if (mode == VOIDmode)
- + {
- + mode = GET_MODE (op);
- + if (GET_MODE_CLASS (mode) != MODE_CC)
- + return false;
- + }
- +
- + return (mode == GET_MODE (op)
- + && REG_P (op)
- + && REGNO (op) == MCC_REGNUM);
- +})
- +
- +(define_predicate "metag_cc_z_reg"
- +(match_code "reg")
- +{
- + if (mode == VOIDmode)
- + {
- + mode = GET_MODE (op);
- + if (GET_MODE_CLASS (mode) != MODE_CC)
- + return false;
- + }
- +
- + return (mode == GET_MODE (op)
- + && REG_P (op)
- + && REGNO (op) == MCC_REGNUM);
- +})
- +
- +(define_predicate "metag_cc_fp_reg"
- +(match_code "reg")
- +{
- + if (mode == VOIDmode)
- + {
- + mode = GET_MODE (op);
- + if (GET_MODE_CLASS (mode) != MODE_CC)
- + return false;
- + }
- +
- + return (mode == GET_MODE (op)
- + && REG_P (op)
- + && REGNO (op) == MCC_REGNUM);
- +})
- +
- +(define_predicate "metag_cc_fp_q_reg"
- +(match_code "reg")
- +{
- + if (mode == VOIDmode)
- + {
- + mode = GET_MODE (op);
- + if (GET_MODE_CLASS (mode) != MODE_CC)
- + return false;
- + }
- +
- + return (mode == GET_MODE (op)
- + && REG_P (op)
- + && REGNO (op) == MCC_REGNUM);
- +})
- +
- +(define_predicate "load_multiop"
- +(match_code "parallel")
- +{
- + HOST_WIDE_INT count = XVECLEN (op, 0);
- + unsigned int dst_regno;
- + enum machine_mode xfer_mode;
- + unsigned int word_size;
- + unsigned int lastreg;
- + rtx src_addr;
- + enum reg_class dst_regclass;
- + HOST_WIDE_INT i;
- + rtx elt;
- + rtx src;
- + rtx dst;
- +
- + elt = XVECEXP (op, 0, 0);
- + if (count < 2 || count > 8 || GET_CODE (elt) != SET)
- + return false;
- +
- + src = SET_SRC (elt);
- + dst = SET_DEST (elt);
- +
- + if (GET_CODE (src) != PLUS)
- + return false;
- +
- + elt = XVECEXP (op, 0, 1);
- + if (GET_CODE (elt) != SET)
- + return false;
- +
- + /* Work out if this is SImode or DImode case */
- + xfer_mode = GET_MODE (SET_SRC (elt));
- + word_size = GET_MODE_SIZE (xfer_mode);
- +
- + if (word_size == 4 && count <= 2)
- + return false;
- +
- + /* Now check it more carefully */
- + if (!REG_P (dst)
- + || !REG_P (XEXP (src, 0))
- + || REGNO (XEXP (src, 0)) != REGNO (dst)
- + || !CONST_INT_P (XEXP (src, 1))
- + || INTVAL (XEXP (src, 1)) != (HOST_WIDE_INT)((count - 1) * word_size))
- + return false;
- +
- + src = SET_SRC (elt);
- + dst = SET_DEST (elt);
- +
- + /* Perform a quick check so we don't blow up below. */
- + if (!REG_P (dst) || !MEM_P (src))
- + return false;
- +
- + lastreg = REGNO (dst);
- + dst_regno = REGNO (dst);
- + src_addr = XEXP (src, 0);
- + dst_regclass = METAG_REGNO_REG_CLASS (dst_regno);
- +
- + for (i = 2; i < count; i++)
- + {
- + elt = XVECEXP (op, 0, i);
- + if (GET_CODE (elt) != SET)
- + return false;
- +
- + src = SET_SRC (elt);
- + dst = SET_DEST (elt);
- +
- + if (!REG_P (dst)
- + || GET_MODE (dst) != xfer_mode
- + || REGNO (dst) - dst_regno > 2 * word_size
- + || REGNO (dst) <= lastreg
- + || METAG_REGNO_REG_CLASS (REGNO (dst)) != dst_regclass
- + || !MEM_P (src)
- + || GET_MODE (src) != xfer_mode
- + || GET_CODE (XEXP (src, 0)) != PLUS
- + || !rtx_equal_p (XEXP (XEXP (src, 0), 0), src_addr)
- + || !CONST_INT_P (XEXP (XEXP (src, 0), 1))
- + || INTVAL (XEXP (XEXP (src, 0), 1)) != (HOST_WIDE_INT)((i - 1) * word_size))
- + return false;
- +
- + lastreg = REGNO (dst);
- + }
- +
- + return true;
- +})
- +
- +(define_predicate "store_multiop"
- +(match_code "parallel")
- +{
- + HOST_WIDE_INT count = XVECLEN (op, 0);
- + unsigned int src_regno;
- + enum machine_mode xfer_mode;
- + unsigned int word_size;
- + unsigned int lastreg;
- + enum reg_class src_regclass;
- + rtx dst_addr;
- + HOST_WIDE_INT i;
- + rtx elt;
- + rtx src;
- + rtx dst;
- +
- + elt = XVECEXP (op, 0, 0);
- + if (count <= 2 || count > 9 || GET_CODE (elt) != SET)
- + return false;
- +
- + dst = SET_DEST (elt);
- + src = SET_SRC (elt);
- +
- + if (GET_CODE (src) != PLUS)
- + return false;
- +
- + elt = XVECEXP (op, 0, 1);
- + if (GET_CODE (elt) != SET)
- + return false;
- +
- + /* Work out if this is SImode or DImode case */
- + xfer_mode = GET_MODE (SET_DEST (elt));
- + word_size = GET_MODE_SIZE (xfer_mode);
- +
- + /* Now check it more carefully */
- + if (!REG_P (dst)
- + || !REG_P (XEXP (src, 0))
- + || REGNO (XEXP (src, 0)) != REGNO (dst)
- + || !CONST_INT_P (XEXP (src, 1))
- + || INTVAL (XEXP (src, 1)) != (HOST_WIDE_INT)((count - 1) * word_size))
- + return false;
- +
- + src = SET_SRC (elt);
- + dst = SET_DEST (elt);
- +
- + /* Perform a quick check so we don't blow up below. */
- + if (!MEM_P (dst) || !REG_P (src))
- + return false;
- +
- + lastreg = REGNO (src);
- + src_regno = REGNO (src);
- + dst_addr = XEXP (dst, 0);
- + src_regclass = METAG_REGNO_REG_CLASS (src_regno);
- +
- + for (i = 2; i < count; i++)
- + {
- + elt = XVECEXP (op, 0, i);
- + if (GET_CODE (elt) != SET)
- + return false;
- +
- + src = SET_SRC (elt);
- + dst = SET_DEST (elt);
- +
- + if (!REG_P (src)
- + || GET_MODE (src) != xfer_mode
- + || REGNO (src) - src_regno > 2 * word_size
- + || REGNO (src) <= lastreg
- + || METAG_REGNO_REG_CLASS (REGNO (src)) != src_regclass
- + || !MEM_P (dst)
- + || GET_MODE (dst) != xfer_mode
- + || GET_CODE (XEXP (dst, 0)) != PLUS
- + || !rtx_equal_p (XEXP (XEXP (dst, 0), 0), dst_addr)
- + || !CONST_INT_P (XEXP (XEXP (dst, 0), 1))
- + || INTVAL (XEXP (XEXP (dst, 0), 1)) != (HOST_WIDE_INT)((i - 1) * word_size))
- + return false;
- +
- + lastreg = REGNO (src);
- + }
- +
- + return true;
- +})
- +
- +(define_predicate "metag_datareg_op"
- +(and (match_code "subreg,reg")
- + (match_operand 0 "metag_register_op"))
- +{
- + unsigned int regno;
- +
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + /* A subreg may refer to a mem before reload, metag_register_op ensures
- + that reload has not completed if it is a mem */
- + if (!REG_P (op))
- + return true;
- +
- + regno = REGNO (op);
- +
- + if (regno >= FIRST_PSEUDO_REGISTER)
- + return true;
- +
- + return METAG_DATA_REG_P (regno);
- +})
- +
- +(define_predicate "metag_addrreg_op"
- +(and (match_code "subreg,reg")
- + (match_operand 0 "metag_register_op"))
- +{
- + unsigned int regno;
- +
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + /* A subreg may refer to a mem before reload, metag_register_op ensures
- + that reload has not completed if it is a mem */
- + if (!REG_P (op))
- + return true;
- +
- + regno = REGNO (op);
- +
- + if (regno >= FIRST_PSEUDO_REGISTER)
- + return true;
- +
- + return METAG_ADDR_REG_P (regno);
- +})
- +
- +(define_predicate "metag_fpreg_op"
- +(and (match_code "subreg,reg")
- + (match_operand 0 "metag_register_op"))
- +{
- + unsigned int regno;
- +
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + /* A subreg may refer to a mem before reload, metag_register_op ensures
- + that reload has not completed if it is a mem */
- + if (!REG_P (op))
- + return true;
- +
- + regno = REGNO (op);
- +
- + if (regno >= FIRST_PSEUDO_REGISTER)
- + return true;
- +
- + return METAG_FPC_REG_P (regno);
- +})
- +
- +(define_predicate "metag_fpreg_or_dreg_op"
- +(and (match_code "subreg,reg")
- + (match_operand 0 "metag_register_op"))
- +{
- + unsigned int regno;
- +
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + /* A subreg may refer to a mem before reload, metag_register_op ensures
- + that reload has not completed if it is a mem */
- + if (!REG_P (op))
- + return true;
- +
- + regno = REGNO (op);
- +
- + if (regno >= FIRST_PSEUDO_REGISTER)
- + return true;
- +
- + return METAG_FPC_REG_P (regno) || METAG_DATA_REG_P (regno);
- +})
- +
- +(define_predicate "metag_txrpt_op"
- +(and (match_code "reg")
- + (match_test "REGNO (op) == TXRPT_REGNUM")))
- +
- +(define_predicate "metag_ttrec_op"
- +(and (match_code "reg")
- + (match_test "REGNO (op) == TTREC_REGNUM")))
- +
- +;; Return true if OP is a valid TXRPT_REGNUM
- +;; source operand that can be loaded quickly for the given mode
- +(define_predicate "metag_txrpt_src_op"
- +(ior (and (match_code "const_int")
- + (match_test "satisfies_constraint_I (op)
- + || satisfies_constraint_K (op)
- + || satisfies_constraint_P (op)
- + || satisfies_constraint_J (op)"))
- + (match_code "reg")))
- +
- +(define_predicate "metag_16bit_op"
- +(and (match_code "const_int")
- + (match_test "-32768 <= INTVAL (op) && INTVAL (op) <= 32767")))
- +
- +(define_predicate "metag_vector_float_op"
- +(match_code "const_vector")
- +{
- + int nunits = GET_MODE_NUNITS (mode);
- +
- + if (GET_CODE (op) == CONST_VECTOR
- + && CONST_VECTOR_NUNITS (op) == nunits)
- + {
- + int i;
- + for (i = 0; i < nunits; ++i)
- + {
- + rtx x = CONST_VECTOR_ELT (op, i);
- + if (!metag_fphalf_imm_op (x, GET_MODE_INNER (mode)))
- + return false;
- + }
- + return true;
- + }
- + return false;
- +})
- +
- +(define_predicate "metag_vector_int_op"
- +(match_code "const_vector")
- +{
- + int nunits = GET_MODE_NUNITS (mode);
- +
- + if (GET_CODE (op) == CONST_VECTOR
- + && CONST_VECTOR_NUNITS (op) == nunits)
- + {
- + int i;
- + for (i = 0; i < nunits; ++i)
- + {
- + rtx x = CONST_VECTOR_ELT (op, i);
- + if (!CONST_INT_P (x))
- + return false;
- + }
- + return true;
- + }
- + return false;
- +})
- +
- +(define_predicate "metag_vector_16bit_op"
- + (match_code "const_vector")
- +{
- + int nunits = GET_MODE_NUNITS (mode);
- +
- + if (GET_CODE (op) == CONST_VECTOR
- + && CONST_VECTOR_NUNITS (op) == nunits)
- + {
- + int i;
- + HOST_WIDE_INT val = INTVAL (CONST_VECTOR_ELT (op, 0));
- + for (i = 0; i < nunits; ++i)
- + {
- + rtx x = CONST_VECTOR_ELT (op, i);
- + if (!metag_16bit_op (x, GET_MODE_INNER (mode)))
- + return false;
- + if (val != INTVAL (x))
- + return false;
- + }
- + return true;
- + }
- + return false;
- +})
- +
- +(define_predicate "metag_5bit_op"
- +(and (match_code "const_int")
- + (match_test "0 <= INTVAL (op) && INTVAL (op) <= 31")))
- +
- +(define_predicate "metag_vector_5bit_op"
- + (match_code "const_vector")
- +{
- + int nunits = GET_MODE_NUNITS (mode);
- +
- + if (GET_CODE (op) == CONST_VECTOR
- + && CONST_VECTOR_NUNITS (op) == nunits)
- + {
- + int i;
- + HOST_WIDE_INT val = INTVAL (CONST_VECTOR_ELT (op, 0));
- + for (i = 0; i < nunits; ++i)
- + {
- + rtx x = CONST_VECTOR_ELT (op, i);
- + if (!metag_5bit_op (x, GET_MODE_INNER (mode)))
- + return false;
- + if (val != INTVAL (x))
- + return false;
- + }
- + return true;
- + }
- + return false;
- +})
- +
- +(define_predicate "metag_K_operand"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_K (op)")))
- +
- +(define_predicate "metag_L_operand"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_L (op)")))
- +
- +(define_predicate "metag_J_operand"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_J (op)")))
- +
- +(define_predicate "metag_O0_operand"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_O0 (op)")))
- +
- +(define_predicate "metag_O3_operand"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_O3 (op)")))
- +
- +(define_predicate "metag_P_operand"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_P (op)")))
- +
- +(define_predicate "metag_KP_operand"
- +(and (match_code "const_int")
- + (ior (match_test "satisfies_constraint_K (op)")
- + (match_test "satisfies_constraint_P (op)"))))
- +
- +(define_predicate "metag_KIP_operand"
- +(and (match_code "const_int")
- + (ior (match_test "satisfies_constraint_K (op)")
- + (ior (match_test "satisfies_constraint_P (op)")
- + (match_test "satisfies_constraint_I (op)")))))
- +
- +(define_predicate "metag_pic_reg"
- +(and (match_code "reg")
- + (ior (match_test "op == pic_offset_table_rtx")
- + (and (match_code "reg")
- + (match_test "REGNO (op) == PIC_OFFSET_TABLE_REGNUM")))))
- +
- +(define_predicate "metag_offset12_qi"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_Z1 (op)")))
- +
- +(define_predicate "metag_offset12_hi"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_Z2 (op)")))
- +
- +(define_predicate "metag_offset12_si"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_Z4 (op)")))
- +
- +(define_predicate "metag_offset12_di"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_Z8 (op)")))
- +
- +(define_predicate "metag_offset12_sf"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_Z4 (op)")))
- +
- +(define_predicate "metag_offset12_df"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_Z8 (op)")))
- +
- +(define_predicate "metag_offset12_v2si"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_Z8 (op)")))
- +
- +(define_predicate "metag_offset12_v2sf"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_Z8 (op)")))
- +
- +(define_predicate "metag_offset6_qi"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_O1 (op)")))
- +
- +(define_predicate "metag_offset6_hi"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_O2 (op)")))
- +
- +(define_predicate "metag_offset6_si"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_O4 (op)")))
- +
- +(define_predicate "metag_offset6_di"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_O8 (op)")))
- +
- +(define_predicate "metag_offset6_sf"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_O4 (op)")))
- +
- +(define_predicate "metag_offset6_df"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_O8 (op)")))
- +
- +(define_predicate "metag_offset6_v2si"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_O8 (op)")))
- +
- +(define_predicate "metag_offset6_v2sf"
- +(and (match_code "const_int")
- + (match_test "satisfies_constraint_O8 (op)")))
- +
- +(define_predicate "metag_reg12bit_op"
- +(match_code "subreg,reg")
- +{
- + if (metag_register_op (op, mode))
- + {
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + if (REG_P (op))
- + {
- + unsigned regno = REGNO (op);
- +
- + if (regno == INVALID_REGNUM)
- + return false;
- + else if (regno >= FIRST_PSEUDO_REGISTER)
- + return !reload_completed;
- + else if (metag_regno12bit_p (regno))
- + return true;
- + else if (!reload_completed && !reload_in_progress)
- + return (regno == FRAME_REG || regno == ARGP_REG);
- + }
- + }
- +
- + return false;
- +})
- +
- +(define_predicate "metag_fphalf_imm_op"
- +(match_code "const_double")
- +{
- + bool inexact = false;
- +
- + if (mode != SFmode && mode != DFmode)
- + return false;
- +
- + metag_const_double_to_hp (op, &inexact);
- + return !inexact;
- +})
- +
- +(define_predicate "metag_fpreg_or_imm_op"
- +(ior (and (match_code "subreg,reg")
- + (match_operand 0 "metag_register_op"))
- + (match_code "const_double"))
- +{
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + if (REG_P(op))
- + {
- + unsigned int regno = REGNO (op);
- +
- + if (regno >= FIRST_PSEUDO_REGISTER)
- + return true;
- +
- + return METAG_FPC_REG_P (regno);
- + }
- + else
- + return GET_CODE (op) == CONST_DOUBLE
- + && GET_MODE_CLASS (mode) == MODE_FLOAT;
- +})
- +
- +(define_predicate "metag_fpreg_or_fpzero_imm_op"
- +(ior (and (match_code "subreg,reg")
- + (match_operand 0 "metag_register_op"))
- + (match_code "const_double"))
- +{
- + if (SUBREG_P (op))
- + op = SUBREG_REG (op);
- +
- + if (REG_P (op))
- + {
- + unsigned int regno = REGNO (op);
- +
- + if (regno >= FIRST_PSEUDO_REGISTER)
- + return true;
- +
- + return METAG_FPC_REG_P (regno);
- + }
- + else
- + return GET_CODE (op) == CONST_DOUBLE
- + && GET_MODE_CLASS (mode) == MODE_FLOAT
- + && op == CONST0_RTX (mode);
- +})
- +
- +(define_predicate "metag_fpone_imm_op"
- + (match_code "const_double")
- +{
- + return satisfies_constraint_H (op);
- +})
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/t-linux gcc-4.2.4/gcc/config/metag/t-linux
- --- gcc-4.2.4.orig/gcc/config/metag/t-linux 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/t-linux 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,46 @@
- +# t-linux
- +# Copyright (C) 2011 Imagination Technologies Ltd
- +
- +# This file is part of GCC.
- +
- +# GCC 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 3, or (at your option) any later
- +# version.
- +#
- +# GCC 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 GCC; see the file COPYING3. If not see
- +# <http://www.gnu.org/licenses/>.
- +
- +# Don't run fixproto
- +STMP_FIXPROTO =
- +
- +# Don't install "assert.h" in gcc. We use the one in uClibc.
- +INSTALL_ASSERT_H =
- +
- +# Compile crtbeginS.o and crtendS.o with pic.
- +CRTSTUFF_T_CFLAGS_S = -fPIC
- +
- +# Compile crtbegin.o and crtend.o without pic.
- +CRTSTUFF_T_CFLAGS =
- +
- +# Compile libgcc2.a
- +TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC
- +LIBGCC2_DEBUG_CFLAGS = -g0
- +
- +CROSS_LIBGCC1 = libgcc1-asm.a
- +LIBGCC1 = libgcc1-asm.a
- +LIB1ASMSRC = metag/lib1funcs.asm
- +LIB1ASMFUNCS = _udivsi3 \
- + _divsi3 \
- + _umodsi3 \
- + _modsi3 \
- +
- +# Don't make libgcc1-test since it will fail because it tries to link with liblow.a which doesn't exist for linux toolchain!
- +LIBGCC1_TEST =
- +
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/t-linux-2.1 gcc-4.2.4/gcc/config/metag/t-linux-2.1
- --- gcc-4.2.4.orig/gcc/config/metag/t-linux-2.1 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/t-linux-2.1 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,20 @@
- +# t-linux-2.1
- +# Copyright (C) 2012 Imagination Technologies Ltd
- +
- +# This file is part of GCC.
- +
- +# GCC 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 3, or (at your option) any later
- +# version.
- +#
- +# GCC 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 GCC; see the file COPYING3. If not see
- +# <http://www.gnu.org/licenses/>.
- +
- +LIB2FUNCS_STATIC_EXTRA += $(srcdir)/config/metag/linux-atomic.asm
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/tls.md gcc-4.2.4/gcc/config/metag/tls.md
- --- gcc-4.2.4.orig/gcc/config/metag/tls.md 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/tls.md 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,205 @@
- +;; Machine description for Thread-Local Storage,
- +;; Imagination Technologies Meta version.
- +;; Copyright (C) 2009, 2010
- +;; Imagination Technologies Ltd
- +
- +;; This file is part of GCC.
- +
- +;; GCC 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 3, or (at your option) any later
- +;; version.
- +
- +;; GCC 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 GCC; see the file COPYING3. If not see
- +;; <http://www.gnu.org/licenses/>.
- +
- +;;Global dynamic insns to set up the call to __tls_get_addr
- +;;These insns will generate the same code for PIC and non PIC cases
- +(define_insn "*tls_gd_sum"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (const:SI (unspec [(match_operand:SI 2 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))))]
- + "METAG_HAVE_TLS"
- + "ADD\\t%0, %1, #(%c2@TLSGD)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "tls_gd"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 1 "metag_pic_reg" "a")
- + (const:SI (unspec [(match_operand:SI 2 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))))]
- + "METAG_HAVE_TLS && operands[1] == pic_offset_table_rtx"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (match_dup 1))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (const:SI (unspec [(match_dup 2)] UNSPEC_TLSGD))))]
- + ""
- + [])
- +
- +;;Local dynamic insns to set up the call to __tls_get_addr to get the address of the start of the current module.
- +;;These insns will generate the same code for PIC and non PIC cases
- +(define_insn "*tls_ldm_sum"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (const:SI (unspec [(match_operand:SI 2 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))))]
- + "METAG_HAVE_TLS"
- + "ADD\\t%0, %1, #(%c2@TLSLDM)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "tls_ldm"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 1 "metag_pic_reg" "a")
- + (const:SI (unspec [(match_operand:SI 2 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))))]
- + "METAG_HAVE_TLS && operands[1] == pic_offset_table_rtx"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (match_dup 1))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (const:SI (unspec [(match_dup 2)] UNSPEC_TLSLDM))))]
- + ""
- + [])
- +
- +;;Local dynamic insns to compute the location of the TLS object from the start of the current TLS block.
- +(define_insn "*tls_ldo_high"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (high:SI (const:SI (unspec [(match_operand:SI 2 "tld_symbolic_operand" "")] UNSPEC_TLSLDO)))))]
- + "METAG_HAVE_TLS"
- + "ADDT\\t%0, %1, #HI(%c2@TLSLDO)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*tls_ldo_lo_sum"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (lo_sum:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (const:SI (unspec [(match_operand:SI 2 "tld_symbolic_operand" "")] UNSPEC_TLSLDO))))]
- + "METAG_HAVE_TLS"
- + "ADD\\t%0, %1, #LO(%c2@TLSLDO)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "tls_ldo"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (const:SI (unspec [(match_operand:SI 2 "tld_symbolic_operand" "")] UNSPEC_TLSLDO))))]
- + "METAG_HAVE_TLS"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (match_dup 1))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (high:SI (const:SI (unspec [(match_dup 2)] UNSPEC_TLSLDO)))))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (const:SI (unspec [(match_dup 2)] UNSPEC_TLSLDO))))]
- + ""
- + [])
- +
- +;;Initial exec insn for PIC.
- +(define_insn "tls_ie"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (mem:SI (plus:SI (match_operand:SI 1 "metag_pic_reg" "a")
- + (const:SI (unspec [(match_operand:SI 2 "tie_symbolic_operand" "")] UNSPEC_TLSIE)))))]
- + "METAG_HAVE_TLS && METAG_FLAG_PIC && operands[1] == pic_offset_table_rtx"
- + "GETD\t%0, [A1LbP+#(%c2@TLSIE)]")
- +
- +;;Initial exec insns for non-PIC.
- +(define_insn "*tls_non_pic_ie_high"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (high:SI (const:SI (unspec [(match_operand:SI 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))))]
- + "METAG_HAVE_TLS"
- + "MOVT\\t%0, #HI(%c1@TLSIENONPIC)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*tls_non_pic_ie_lo_sum"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (lo_sum:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (const:SI (unspec [(match_operand:SI 2 "tie_symbolic_operand" "")] UNSPEC_TLSIE))))]
- + "METAG_HAVE_TLS"
- + "ADD\\t%0, %1, #LO(%c2@TLSIENONPIC)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "tls_non_pic_ie"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (const:SI (unspec [(match_operand:SI 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE)))]
- + "METAG_HAVE_TLS"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (high:SI (const:SI (unspec [(match_dup 1)] UNSPEC_TLSIE))))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (const:SI (unspec [(match_dup 1)] UNSPEC_TLSIE))))]
- + ""
- + [])
- +
- +;;Local exec insns
- +(define_insn "*tls_le_high"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (high:SI (const:SI (unspec [(match_operand:SI 2 "tle_symbolic_operand" "")] UNSPEC_TLSLE)))))]
- + "METAG_HAVE_TLS"
- + "ADDT\\t%0, %1, #HI(%c2@TLSLE)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*tls_le_lo_sum"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (lo_sum:SI (match_operand:SI 1 "metag_reg_nofloat_op" "0")
- + (const:SI (unspec [(match_operand:SI 2 "tle_symbolic_operand" "")] UNSPEC_TLSLE))))]
- + "METAG_HAVE_TLS"
- + "ADD\\t%0, %1, #LO(%c2@TLSLE)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "tls_le"
- + [(set (match_operand:SI 0 "metag_reg_nofloat_op" "=da")
- + (plus:SI (match_operand:SI 1 "metag_reg_nofloat_op" "da")
- + (const:SI (unspec [(match_operand:SI 2 "tle_symbolic_operand" "")] UNSPEC_TLSLE))))]
- + "METAG_HAVE_TLS"
- + "#"
- + "&& SPLIT_HI_LO_SUM_EARLY"
- + [(set (match_dup 0)
- + (match_dup 1))
- + (set (match_dup 0)
- + (plus:SI (match_dup 0)
- + (high:SI (const:SI (unspec [(match_dup 2)] UNSPEC_TLSLE)))))
- + (set (match_dup 0)
- + (lo_sum:SI (match_dup 0)
- + (const:SI (unspec [(match_dup 2)] UNSPEC_TLSLE))))]
- + ""
- + [])
- +
- +;;
- +;; Predicates
- +;;
- +
- +;; Return true if OP is a symbolic operand for the TLS Global Dynamic model.
- +(define_predicate "tgd_symbolic_operand"
- + (and (match_code "symbol_ref")
- + (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_GLOBAL_DYNAMIC")))
- +
- +;; Return true if OP is a symbolic operand for the TLS Local Dynamic model.
- +(define_predicate "tld_symbolic_operand"
- + (and (match_code "symbol_ref")
- + (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_DYNAMIC")))
- +
- +;; Return true if OP is a symbolic operand for the TLS Initial Exec model.
- +(define_predicate "tie_symbolic_operand"
- + (and (match_code "symbol_ref")
- + (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC")))
- +
- +;; Return true if OP is a symbolic operand for the TLS Local Exec model.
- +(define_predicate "tle_symbolic_operand"
- + (and (match_code "symbol_ref")
- + (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC")))
- +
- +;; end of file
- +
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/t-metag gcc-4.2.4/gcc/config/metag/t-metag
- --- gcc-4.2.4.orig/gcc/config/metag/t-metag 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/t-metag 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,39 @@
- +# Rules common to all metag targets
- +# Copyright (C) 2011 Imagination Technologies Ltd
- +
- +# This file is part of GCC.
- +
- +# GCC 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 3, or (at your option) any later
- +# version.
- +#
- +# GCC 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 GCC; see the file COPYING3. If not see
- +# <http://www.gnu.org/licenses/>.
- +
- +MD_INCLUDES=$(srcdir)/config/metag/constants.md \
- + $(srcdir)/config/metag/predicates.md \
- + $(srcdir)/config/metag/peephole2.md \
- + $(srcdir)/config/metag/dsppeephole2.md \
- + $(srcdir)/config/metag/constraints.md \
- + $(srcdir)/config/metag/pipeline.md \
- + $(srcdir)/config/metag/builtins.md \
- + $(srcdir)/config/metag/peephole.md \
- + $(srcdir)/config/metag/dsppeephole.md \
- + $(srcdir)/config/metag/combines.md \
- + $(srcdir)/config/metag/fp.md \
- + $(srcdir)/config/metag/vector.md
- +
- +s-config s-conditions s-flags s-codes s-constants s-emit s-recog s-preds \
- + s-opinit s-extract s-peep s-attr s-attrtab s-output: $(MD_INCLUDES)
- +
- +$(out_object_file): s-gtype
- +
- +driver-metag.o : $(srcdir)/config/metag/driver-metag.c
- + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/t-metag-linux gcc-4.2.4/gcc/config/metag/t-metag-linux
- --- gcc-4.2.4.orig/gcc/config/metag/t-metag-linux 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/t-metag-linux 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,44 @@
- +# t-metag-linux
- +# Copyright (C) 2011 Imagination Technologies Ltd
- +
- +# This file is part of GCC.
- +
- +# GCC 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 3, or (at your option) any later
- +# version.
- +#
- +# GCC 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 GCC; see the file COPYING3. If not see
- +# <http://www.gnu.org/licenses/>.
- +
- +# WORK NEEDED: We have to have minim versions of libraries but will also need
- +# hardfloat variants
- +MULTILIB_OPTIONS= mminim
- +MULTILIB_DIRNAMES= minim
- +MULTILIB_EXCEPTIONS=
- +MULTILIB_MATCHES=
- +
- +# We want fine grained libraries, so use the new code to build the
- +# floating point emulation libraries.
- +FPBIT = fp-bit.c
- +DPBIT = dp-bit.c
- +
- +fp-bit.c: $(srcdir)/config/fp-bit.c
- + echo '#define FLOAT' >> fp-bit.c
- + cat $(srcdir)/config/fp-bit.c >> fp-bit.c
- +
- +dp-bit.c: $(srcdir)/config/fp-bit.c
- + cat $(srcdir)/config/fp-bit.c >> dp-bit.c
- +
- +metag-linux.o: $(srcdir)/config/metag/metag-linux.c $(CONFIG_H) $(SYSTEM_H) \
- + coretypes.h $(TM_H) $(RTL_H) output.h flags.h $(TREE_H) \
- + expr.h toplev.h $(TM_P_H)
- + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
- + $(srcdir)/config/metag/metag-linux.c
- +
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/t-metag-slibgcc-elf-ver gcc-4.2.4/gcc/config/metag/t-metag-slibgcc-elf-ver
- --- gcc-4.2.4.orig/gcc/config/metag/t-metag-slibgcc-elf-ver 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/t-metag-slibgcc-elf-ver 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,37 @@
- +# Build a shared libgcc library for ELF with symbol versioning
- +# with the GNU linker.
- +
- +SHLIB_EXT = .so
- +SHLIB_SOLINK = @shlib_base_name@.so
- +SHLIB_SOVERSION = 1
- +SHLIB_SONAME = @shlib_base_name@.so.$(SHLIB_SOVERSION)
- +SHLIB_MAP = @shlib_map_file@
- +SHLIB_OBJS = @shlib_objs@
- +SHLIB_DIR = @multilib_dir@
- +SHLIB_SLIBDIR_QUAL = @shlib_slibdir_qual@
- +SHLIB_LC = -lc
- +
- +SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
- + -Wl,--soname=$(SHLIB_SONAME) \
- + -Wl,--version-script=$(SHLIB_MAP) \
- + -o $(SHLIB_DIR)/$(SHLIB_SONAME).tmp @multilib_flags@ \
- + $(SHLIB_OBJS) $(SHLIB_LC) && \
- + rm -f $(SHLIB_DIR)/$(SHLIB_SOLINK) && \
- + if [ -f $(SHLIB_DIR)/$(SHLIB_SONAME) ]; then \
- + mv -f $(SHLIB_DIR)/$(SHLIB_SONAME) \
- + $(SHLIB_DIR)/$(SHLIB_SONAME).backup; \
- + else true; fi && \
- + mv $(SHLIB_DIR)/$(SHLIB_SONAME).tmp $(SHLIB_DIR)/$(SHLIB_SONAME) && \
- + $(LN_S) $(SHLIB_SONAME) $(SHLIB_DIR)/$(SHLIB_SOLINK)
- +# $(slibdir) double quoted to protect it from expansion while building
- +# libgcc.mk. We want this delayed until actual install time.
- +SHLIB_INSTALL = \
- + $$(mkinstalldirs) $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL); \
- + $(INSTALL_DATA) $(SHLIB_DIR)/$(SHLIB_SONAME) \
- + $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SONAME); \
- + rm -f $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK); \
- + $(LN_S) $(SHLIB_SONAME) \
- + $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK)
- +SHLIB_MKMAP = $(srcdir)/mkmap-symver.awk
- +SHLIB_MKMAP_OPTS = -v leading_underscore=1 -v no_show_underscore=1
- +SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/vector.md gcc-4.2.4/gcc/config/metag/vector.md
- --- gcc-4.2.4.orig/gcc/config/metag/vector.md 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/vector.md 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,282 @@
- +;; Machine description for GNU compiler,
- +;; Imagination Technologies Meta version.
- +;; Copyright (C) 2008
- +;; Imagination Technologies Ltd
- +
- +;; This file is part of GCC.
- +
- +;; GCC 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 3, or (at your option) any later
- +;; version.
- +
- +;; GCC 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 GCC; see the file COPYING3. If not see
- +;; <http://www.gnu.org/licenses/>.
- +
- +;; See comment at the top of dsppeephole.md for information about
- +;; dual unit DSP support in the metag backend.
- +
- +(define_insn "*movv2sirr"
- + [(set (match_operand:V2SI 0 "metag_datareg_op" "=d")
- + (match_operand:V2SI 1 "metag_datareg_op" "d"))]
- + "TARGET_DSP"
- + "DL\\tMOV\\t%0,%1\\t%@ (*mov v2si rr)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn_and_split "*movv2siri"
- + [(set (match_operand:V2SI 0 "metag_datareg_op" "=d")
- + (match_operand:V2SI 1 "metag_vector_int_op" "vci"))]
- + "TARGET_DSP
- + && !reload_completed
- + && !reload_in_progress"
- + "#"
- + ""
- + [(set (match_dup 2)
- + (match_dup 4))
- + (set (match_dup 3)
- + (match_dup 5))]
- + {
- + operands[2] = gen_rtx_SUBREG (SImode, operands[0], 0);
- + operands[3] = gen_rtx_SUBREG (SImode, operands[0], UNITS_PER_WORD);
- + operands[4] = XVECEXP (operands[1], 0, 0);
- + operands[5] = XVECEXP (operands[1], 0, 1);
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_expand "movv2si"
- + [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
- + (match_operand:V2SI 1 "general_operand" ""))]
- + "TARGET_DSP"
- + {
- + if (MEM_P (operands[0]) && !REG_P (operands[1]))
- + {
- + /* All except mem = const, mem = mem, or mem = addr can be done quickly */
- + if (!no_new_pseudos)
- + operands[1] = force_reg (V2SImode, operands[1]);
- + }
- +
- + }
- +)
- +
- +(define_insn "*lod_v2si"
- + [(set (match_operand:V2SI 0 "metag_datareg_op" "=d")
- + (match_operand:V2SI 1 "memory_operand" "m"))]
- + "TARGET_DSP"
- + "GETL\\t%0, %t0, %1\\t%@ (*lod v2si rm OK)"
- + [(set_attr "memaccess" "load")])
- +
- +(define_insn "*sto_v2si"
- + [(set (match_operand:V2SI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl,!*m")
- + (match_operand:V2SI 1 "metag_datareg_op" "r, a, a, d, d, !*da"))]
- + "TARGET_DSP && !reload_completed"
- + "SETL\\t%0, %1, %t1\\t%@ (*sto v2si rm OK)"
- + [(set_attr "type" "fast,fast,fast,fast,fast,invalid")])
- +
- +(define_insn "*sto_v2si_postreload"
- + [(set (match_operand:V2SI 0 "memory_operand" "=Tr,Te,Tf,Th,Tl")
- + (match_operand:V2SI 1 "metag_datareg_op" "r, a, a, d, d"))]
- + "TARGET_DSP && reload_completed"
- + "SETL\\t%0, %1, %t1\\t%@ (*sto v2si rm OK)"
- + [(set_attr "type" "fast")])
- +
- +(define_expand "vec_setv2si"
- + [(match_operand:V2SI 0 "metag_datareg_op" "=d")
- + (match_operand:SI 1 "metag_register_op" "da")
- + (match_operand 2 "const_int_operand" "i")]
- + "TARGET_DSP"
- + {
- + rtx tmp = gen_reg_rtx (SImode);
- +
- + rtx tmp2 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (1 - INTVAL (operands[2]))));
- + tmp2 = gen_rtx_VEC_SELECT (SImode, operands[0], tmp2);
- + emit_insn (gen_rtx_SET (VOIDmode, tmp, tmp2));
- +
- + if (INTVAL (operands[2]) == 0)
- + tmp = gen_rtx_VEC_CONCAT (V2SImode, tmp, operands[1]);
- + else
- + tmp = gen_rtx_VEC_CONCAT (V2SImode, operands[1], tmp);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[0], tmp));
- + DONE;
- + })
- +
- +(define_insn_and_split "*vec_concatv2si"
- + [(set (match_operand:V2SI 0 "metag_register_op" "=d")
- + (vec_concat:V2SI (match_operand:SI 1 "metag_register_op" "d")
- + (match_operand:SI 2 "metag_register_op" "d")))]
- + "TARGET_DSP"
- + "#"
- + "&& reload_completed"
- + [(set (match_dup 0)
- + (match_dup 1))
- + (set (match_dup 3)
- + (match_dup 2))]
- + {
- + operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- + operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
- + }
- + [(set_attr "type" "two")])
- +
- +(define_expand "vec_extractv2si"
- + [(match_operand:SI 0 "metag_register_op" "=da")
- + (match_operand:V2SI 1 "metag_register_op" "d")
- + (match_operand 2 "const_int_operand" "i")]
- + "TARGET_DSP"
- + {
- + rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, operands[2]));
- + tmp = gen_rtx_VEC_SELECT (SImode, operands[1], tmp);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[0], tmp));
- + DONE;
- + })
- +
- +(define_insn "*vec_selectv2si"
- + [(set (match_operand:SI 0 "metag_register_op" "=r")
- + (vec_select:SI (match_operand:V2SI 1 "metag_datareg_op" "d")
- + (parallel [(match_operand 2 "const_int_operand" "i")])))]
- + "TARGET_DSP"
- + {
- + switch (INTVAL (operands[2]))
- + {
- + case 0:
- + return "MOV\\t%0, %1\\t%@ (*vec_select v2si 0)";
- + case 1:
- + return "MOV\\t%0, %t1\\t%@ (*vec_select v2si 1)";
- + default:
- + gcc_unreachable ();
- + }
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_expand "vec_initv2si"
- + [(match_operand:V2SI 0 "metag_datareg_op" "=d")
- + (match_operand 1 "" "")]
- + "TARGET_DSP"
- + {
- + rtx val0 = force_reg (SImode, XVECEXP (operands[1], 0, 0));
- + rtx val1 = force_reg (SImode, XVECEXP (operands[1], 0, 1));
- + rtx tmp = gen_rtx_VEC_CONCAT (V2SImode, val0, val1);
- + emit_insn (gen_rtx_SET (VOIDmode, operands[0], tmp));
- + DONE;
- + })
- +
- +(define_insn "*<expander>v2siddi16"
- + [(set (match_operand:V2SI 0 "metag_datareg_op" "+d")
- + (3OPIMM16:V2SI (match_dup 0)
- + (match_operand:V2SI 1 "metag_vector_16bit_op" "v16")))]
- + "TARGET_DSP"
- + "DL\\t<MNEMONIC>\\t\\t%0,%0,%1\\t%@(*<MNEMONIC> v2si ddi)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*<expander>v2siddi5"
- + [(set (match_operand:V2SI 0 "metag_datareg_op" "=d")
- + (3OPIMM5:V2SI (match_operand:V2SI 1 "metag_datareg_op" "d")
- + (match_operand:V2SI 2 "metag_vector_5bit_op" "vc5")))]
- + "TARGET_DSP"
- + "DL\\t<MNEMONIC>\\t\\t%0,%1,%2\\t%@(*<MNEMONIC> v2si ddi)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "<expander>v2si3"
- + [(set (match_operand:V2SI 0 "metag_datareg_op" "=d")
- + (3OPREG:V2SI (match_operand:V2SI 1 "metag_datareg_op" "d")
- + (match_operand:V2SI 2 "metag_datareg_op" "d")))]
- + "TARGET_DSP"
- + "DL\\t<MNEMONIC>\\t\\t%0,%1,%2\\t%@(*<MNEMONIC> v2si ddd)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "absv2si2"
- + [(set (match_operand:V2SI 0 "metag_datareg_op" "=d")
- + (abs:V2SI (match_operand:V2SI 1 "metag_datareg_op" "d")))
- + (clobber (reg:CC CC_REG))]
- + "TARGET_DSP"
- + "DL\\tABS\\t\\t%0,%1\\t%@(*abs v2si dd)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "ccx")])
- +
- +(define_insn "negv2si2"
- + [(set (match_operand:V2SI 0 "metag_datareg_op" "=d")
- + (neg:V2SI (match_operand:V2SI 1 "metag_datareg_op" "d")))]
- + "TARGET_DSP"
- + "DL\\tNEG\\t\\t%0,%1\\t%@(*neg v2si dd)"
- + [(set_attr "type" "fast")])
- +
- +(define_insn "<expander>v2si3"
- + [(set (match_operand:V2SI 0 "metag_datareg_op" "=d")
- + (MINMAX:V2SI (match_operand:V2SI 1 "metag_datareg_op" "d")
- + (match_operand:V2SI 2 "metag_datareg_op" "d")))
- + (clobber (reg:CC CC_REG))]
- + "TARGET_DSP"
- + "DL\\t<MNEMONIC>\\t\\t%0,%1,%2\\t%@(*<MNEMONIC> v2si ddd)"
- + [(set_attr "type" "fast")
- + (set_attr "ccstate" "ccx")])
- +
- +;; OP + flag set
- +
- +(define_insn "*<expander>sv2siddi16"
- + [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM16:SI (match_operand:SI 2 "metag_datareg_op" "d")
- + (match_operand:SI 3 "metag_16bit_op" "KIP"))
- + (const_int 0)))
- + (set (match_operand:V2SI 0 "metag_datareg_op" "+d")
- + (3OPIMM16:V2SI (match_dup 0)
- + (match_operand:V2SI 1 "metag_vector_16bit_op" "v16")))]
- + "TARGET_DSP
- + && (REGNO (operands[2]) == REGNO (operands[0])
- + || (REGNO (operands[2]) == REGNO (operands[0]) + 1))
- + && INTVAL (operands[3]) == INTVAL (CONST_VECTOR_ELT (operands[1], 0))"
- + {
- + if (REGNO (operands[3]) == REGNO (operands[1]))
- + return "DL\\t<MNEMONIC>S\\t\\t%0,%0,%1\\t%@(*<MNEMONIC>S v2si ddi)";
- + else
- + return "DL\\t<MNEMONIC>S\\t\\t%t0,%t0,%t1\\t%@(*<MNEMONIC>S v2si ddi)";
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*<expander>sv2siddi5"
- + [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPIMM5:SI (match_operand:SI 3 "metag_datareg_op" "d")
- + (match_operand:SI 4 "metag_5bit_op" "L"))
- + (const_int 0)))
- + (set (match_operand:V2SI 0 "metag_datareg_op" "=d")
- + (3OPIMM5:V2SI (match_operand:V2SI 1 "metag_datareg_op" "d")
- + (match_operand:V2SI 2 "metag_vector_5bit_op" "v16")))]
- + "TARGET_DSP
- + && (REGNO (operands[3]) == REGNO (operands[1])
- + || (REGNO (operands[3]) == REGNO (operands[1]) + 1))
- + && INTVAL (operands[4]) == INTVAL (CONST_VECTOR_ELT (operands[2], 0))"
- + {
- + if (REGNO (operands[3]) == REGNO (operands[1]))
- + return "DL\\t<MNEMONIC>S\\t\\t%0,%1,%2\\t%@(*<MNEMONIC>S v2si di)";
- + else
- + return "DL\\t<MNEMONIC>S\\t\\t%t0,%t1,%t2\\t%@(*<MNEMONIC>S v2si di)";
- + }
- + [(set_attr "type" "fast")])
- +
- +(define_insn "*<expander>sv2si3"
- + [(set (reg:CC_NOOV CC_REG)
- + (compare:CC_NOOV
- + (3OPREG:SI (match_operand:SI 3 "metag_datareg_op" "d")
- + (match_operand:SI 4 "metag_datareg_op" "d"))
- + (const_int 0)))
- + (set (match_operand:V2SI 0 "metag_datareg_op" "=d")
- + (3OPREG:V2SI (match_operand:V2SI 1 "metag_datareg_op" "d")
- + (match_operand:V2SI 2 "metag_datareg_op" "d")))]
- + "TARGET_DSP
- + && ((REGNO (operands[3]) == REGNO (operands[1])
- + && REGNO (operands[4]) == REGNO (operands[2]))
- + || (REGNO (operands[3]) == REGNO (operands[1]) + 1
- + && REGNO (operands[4]) == REGNO (operands[2]) + 1))"
- + {
- + if (REGNO (operands[3]) == REGNO (operands[1]))
- + return "DL\\t<MNEMONIC>S\\t\\t%0,%1,%2\\t%@(*<MNEMONIC>S v2si ddd)";
- + else
- + return "DL\\t<MNEMONIC>S\\t\\t%t0,%t1,%t2\\t%@(*<MNEMONIC>S v2si ddd)";
- + }
- + [(set_attr "type" "fast")])
- +
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/x-metag-linux gcc-4.2.4/gcc/config/metag/x-metag-linux
- --- gcc-4.2.4.orig/gcc/config/metag/x-metag-linux 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/x-metag-linux 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,20 @@
- +# Configuration for GNU C-compiler.
- +# Imagination Technologies Meta version.
- +# Copyright (C) 2001, 2004, 2007 Imagination Technologies Ltd
- +
- +# This file is part of GCC.
- +
- +# GCC 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 3, or (at your option) any later
- +# version.
- +
- +# GCC 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 GCC; see the file COPYING3. If not see
- +# <http://www.gnu.org/licenses/>.
- +
- diff -Nur gcc-4.2.4.orig/gcc/config/metag/xm-metag-linux gcc-4.2.4/gcc/config/metag/xm-metag-linux
- --- gcc-4.2.4.orig/gcc/config/metag/xm-metag-linux 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/config/metag/xm-metag-linux 2015-07-03 18:46:05.773283541 -0500
- @@ -0,0 +1,20 @@
- +# Configuration for GNU C-compiler.
- +# Imagination Technologies Meta version.
- +# Copyright (C) 2001, 2004, 2007 Imagination Technologies Ltd
- +
- +# This file is part of GCC.
- +
- +# GCC 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 3, or (at your option) any later
- +# version.
- +
- +# GCC 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 GCC; see the file COPYING3. If not see
- +# <http://www.gnu.org/licenses/>.
- +
- diff -Nur gcc-4.2.4.orig/gcc/config.gcc gcc-4.2.4/gcc/config.gcc
- --- gcc-4.2.4.orig/gcc/config.gcc 2008-03-13 14:11:43.000000000 -0500
- +++ gcc-4.2.4/gcc/config.gcc 2015-07-03 18:46:05.717283542 -0500
- @@ -291,6 +291,9 @@
- m68k-*-*)
- extra_headers=math-68881.h
- ;;
- +metag*-*-*)
- + cpu_type=metag
- + ;;
- mips*-*-*)
- cpu_type=mips
- need_64bit_hwint=yes
- @@ -332,6 +335,74 @@
- ;;
- esac
-
- +case ${cpu_type} in
- +metag)
- + tm_defines="${tm_defines} METAG_EXEC_PREFIX=\\\"\$(exec_prefix)/\\\""
- +
- + # Set the default core if with_cpu is not defined
- + if test x${with_cpu} = x
- + then
- + if test x${cpu_type} = xmetag
- + then
- + with_cpu=2.1
- + else
- + with_cpu=1.2
- + fi
- + fi
- +
- + # Set the default tune if with_tune is not defined
- + if test x${with_tune} = x
- + then
- + if test x${cpu_type} = xmetag
- + then
- + with_tune=2.1
- + fi
- + fi
- +
- + # Set the default fpu if with_fpu is not defined
- + if test x${with_fpu} = x
- + then
- + if test x${cpu_type} = xmetag
- + then
- + with_fpu=none
- + fi
- + fi
- +
- + case x${with_cpu} in
- + x2.1)
- + tm_defines="${tm_defines} METAC_DEFAULT=\\\"2.1\\\" METAC_DEFAULT_AS=\\\"METAC_2_1\\\""
- + ;;
- + x1.2)
- + tm_defines="${tm_defines} METAC_DEFAULT=\\\"1.2\\\" METAC_DEFAULT_AS=\\\"METAC_1_2\\\""
- + ;;
- + x1.1)
- + tm_defines="${tm_defines} METAC_DEFAULT=\\\"1.1\\\" METAC_DEFAULT_AS=\\\"METAC_1_1\\\""
- + ;;
- + x1.0)
- + tm_defines="${tm_defines} METAC_DEFAULT=\\\"1.0\\\" METAC_DEFAULT_AS=\\\"METAC_1_0\\\""
- + ;;
- + x0.1)
- + tm_defines="${tm_defines} METAC_DEFAULT=\\\"0.1\\\" METAC_DEFAULT_AS=\\\"METAC_0_1\\\""
- + ;;
- + x*)
- + echo "--with-cpu=\"${with_cpu}\" not recognised",
- + exit 1;
- + ;;
- + esac
- +
- + case x${enable_meta_default} in
- + xyes)
- + # Nothing
- + ;;
- + x*)
- + # When not explicitly META, enable MiniM
- + tm_defines="${tm_defines} MINIM_DEFAULT"
- + ;;
- + esac
- + ;;
- +esac
- +
- +
- tm_file=${cpu_type}/${cpu_type}.h
- if test -f ${srcdir}/config/${cpu_type}/${cpu_type}-protos.h
- then
- @@ -481,6 +552,15 @@
- # Assume that glibc or uClibc are being used and so __cxa_atexit is provided.
- default_use_cxa_atexit=yes
- ;;
- +metag*-linux-uclibc*)
- + gas=yes
- + gnu_ld=yes
- + case ${enable_threads} in
- + "" | yes | posix) thread_file='posix' ;;
- + esac
- + # uClibc provides __cxa_atexit
- + default_use_cxa_atexit=yes
- + ;;
- *-*-gnu*)
- # On the Hurd, the setup is just about the same on
- # each different CPU. The specific machines that we
- @@ -1518,6 +1598,31 @@
- tmake_file=mcore/t-mcore-pe
- use_fixproto=yes
- ;;
- +metag*-linux-uclibc*)
- + tm_file="dbxelf.h elfos.h metag/metag.h metag/metag-linux.h linux.h metag/linux.h metag/elf.h metag/linux-elf.h"
- + tmake_file="metag/t-metag-slibgcc-elf-ver metag/t-metag metag/t-metag-linux metag/t-linux"
- + target_cpu_default=""
- + tm_defines="${tm_defines} METAG_BFD"
- + extra_gcc_objs="driver-metag.o"
- + out_file=metag/metag.c
- + use_fixproto=no
- + use_collect2=no
- + extra_objs="metag-linux.o"
- + extra_options="${extra_options} metag/metag-linux.opt"
- + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- +
- + case x${enable_link_global} in
- + xyes)
- + tm_defines="${tm_defines} METAG_LINK_GLOBAL"
- + ;;
- + esac
- +
- + case x${with_cpu} in
- + x2.1)
- + tmake_file="${tmake_file} metag/t-linux-2.1"
- + ;;
- + esac
- + ;;
- mips-sgi-irix[56]*)
- tm_file="elfos.h ${tm_file} mips/iris.h"
- tmake_file="mips/t-iris mips/t-slibgcc-irix"
- @@ -2757,6 +2862,46 @@
- esac
- ;;
-
- + metag*)
- + supported_defaults="cpu tune fpu"
- + case "$with_cpu" in
- + "" | 1.0 | 1.1 | 1.2 | 2.1 | 0.1)
- + # OK
- + ;;
- + *)
- + echo "Unknown CPU used in --with-cpu=$with_cpu, known values:" 1>&2
- + echo "1.0 1.1 1.2 2.1 0.1" 1>&2
- + exit 1
- + ;;
- + esac
- +
- + case "$with_tune" in
- + "" | 1.0 | 1.1 | 1.2 | 2.1 | 0.1)
- + # OK
- + ;;
- + *)
- + echo "Unknown CPU used in --with-tune=$with_tune, known values:" 1>&2
- + echo "1.0 1.1 1.2 2.1 0.1" 1>&2
- + exit 1
- + ;;
- + esac
- +
- + case "$with_fpu" in
- + none | S | D)
- + # OK
- + ;;
- + yes)
- + with_fpu=D
- + ;;
- + *)
- + echo "Unknown FPU precision used in --with-fpu=$with_fpu, known values:" 1>&2
- + echo "S D" 1>&2
- + exit 1
- + ;;
- + esac
- +
- + ;;
- +
- hppa*-*-* | parisc*-*-*)
- supported_defaults="arch schedule"
-
- diff -Nur gcc-4.2.4.orig/gcc/crtstuff.c gcc-4.2.4/gcc/crtstuff.c
- --- gcc-4.2.4.orig/gcc/crtstuff.c 2006-05-15 22:49:57.000000000 -0500
- +++ gcc-4.2.4/gcc/crtstuff.c 2015-07-03 18:46:05.717283542 -0500
- @@ -207,7 +207,7 @@
- = { };
- #endif /* USE_EH_FRAME_REGISTRY */
-
- -#ifdef JCR_SECTION_NAME
- +#if TARGET_USE_JCR_SECTION && defined(JCR_SECTION_NAME)
- /* Stick a label at the beginning of the java class registration info
- so we can register them properly. */
- STATIC void *__JCR_LIST__[]
- @@ -242,6 +242,20 @@
- extern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK;
-
- /* Run all the global destructors on exit from the program. */
- +
- +#ifndef DO_GLOBAL_DTORS_AUX_BODY
- +#define DO_GLOBAL_DTORS_AUX_BODY \
- +do { \
- + static func_ptr *p = __DTOR_LIST__ + 1; \
- + func_ptr f; \
- + \
- + while ((f = *p)) \
- + { \
- + p++; \
- + f (); \
- + } \
- +} while (0)
- +#endif
-
- /* Some systems place the number of pointers in the first word of the
- table. On SVR4 however, that word is -1. In all cases, the table is
- @@ -263,10 +277,6 @@
- static void __attribute__((used))
- __do_global_dtors_aux (void)
- {
- -#ifndef FINI_ARRAY_SECTION_ASM_OP
- - static func_ptr *p = __DTOR_LIST__ + 1;
- - func_ptr f;
- -#endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */
- static _Bool completed;
-
- if (__builtin_expect (completed, 0))
- @@ -281,11 +291,7 @@
- /* If we are using .fini_array then destructors will be run via that
- mechanism. */
- #else /* !defined (FINI_ARRAY_SECTION_ASM_OP) */
- - while ((f = *p))
- - {
- - p++;
- - f ();
- - }
- + DO_GLOBAL_DTORS_AUX_BODY;
- #endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */
-
- #ifdef USE_EH_FRAME_REGISTRY
- @@ -312,7 +318,7 @@
- = { __do_global_dtors_aux };
- #endif /* !defined(FINI_SECTION_ASM_OP) */
-
- -#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
- +#if defined(USE_EH_FRAME_REGISTRY) || (TARGET_USE_JCR_SECTION && defined(JCR_SECTION_NAME))
- /* Stick a call to __register_frame_info into the .init section. For some
- reason calls with no arguments work more reliably in .init, so stick the
- call in another function. */
- @@ -333,7 +339,7 @@
- __register_frame_info (__EH_FRAME_BEGIN__, &object);
- #endif /* CRT_GET_RFIB_DATA */
- #endif /* USE_EH_FRAME_REGISTRY */
- -#ifdef JCR_SECTION_NAME
- +#if TARGET_USE_JCR_SEVTION && defined(JCR_SECTION_NAME)
- if (__JCR_LIST__[0])
- {
- void (*register_classes) (void *) = _Jv_RegisterClasses;
- @@ -397,6 +403,15 @@
-
- extern void __do_global_dtors (void);
-
- +#ifndef DO_GLOBAL_DTORS_BODY
- +#define DO_GLOBAL_DTORS_BODY \
- +do { \
- + func_ptr *p, f; \
- + for (p = __DTOR_LIST__ + 1; (f = *p); p++) \
- + f (); \
- +} while (0)
- +#endif
- +
- /* This case is used by the Irix 6 port, which supports named sections but
- not an SVR4-style .fini section. __do_global_dtors can be non-static
- in this case because we protect it with -hidden_symbol. */
- @@ -404,9 +419,7 @@
- void
- __do_global_dtors (void)
- {
- - func_ptr *p, f;
- - for (p = __DTOR_LIST__ + 1; (f = *p); p++)
- - f ();
- + DO_GLOBAL_DTORS_BODY;
-
- #ifdef USE_EH_FRAME_REGISTRY
- if (__deregister_frame_info)
- @@ -414,7 +427,7 @@
- #endif
- }
-
- -#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
- +#if defined(USE_EH_FRAME_REGISTRY) || (TARGET_USE_JCR_SECTION && defined(JCR_SECTION_NAME))
- /* A helper function for __do_global_ctors, which is in crtend.o. Here
- in crtbegin.o, we can reference a couple of symbols not visible there.
- Plus, since we're before libgcc.a, we have no problems referencing
- @@ -427,7 +440,7 @@
- if (__register_frame_info)
- __register_frame_info (__EH_FRAME_BEGIN__, &object);
- #endif
- -#ifdef JCR_SECTION_NAME
- +#if TARGET_USE_JCR_SECTION && defined (JCR_SECTION_NAME)
- if (__JCR_LIST__[0])
- {
- void (*register_classes) (void *) = _Jv_RegisterClasses;
- @@ -498,7 +511,7 @@
- = { 0 };
- #endif /* EH_FRAME_SECTION_NAME */
-
- -#ifdef JCR_SECTION_NAME
- +#if TARGET_USE_JCR_SECTION && defined(JCR_SECTION_NAME)
- /* Null terminate the .jcr section array. */
- STATIC void *__JCR_END__[1]
- __attribute__ ((unused, section(JCR_SECTION_NAME),
- @@ -513,12 +526,20 @@
- #elif defined(INIT_SECTION_ASM_OP)
-
- #ifdef OBJECT_FORMAT_ELF
- +
- +#ifndef DO_GLOBAL_CTORS_AUX_BODY
- +#define DO_GLOBAL_CTORS_AUX_BODY \
- +do { \
- + func_ptr *p; \
- + for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) \
- + (*p)(); \
- +} while (0)
- +#endif
- +
- static void __attribute__((used))
- __do_global_ctors_aux (void)
- {
- - func_ptr *p;
- - for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
- - (*p) ();
- + DO_GLOBAL_CTORS_AUX_BODY;
- }
-
- /* Stick a call to __do_global_ctors_aux into the .init section. */
- @@ -561,6 +582,16 @@
-
- #elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */
-
- +#ifndef DO_GLOBAL_CTORS_BODY
- +#define DO_GLOBAL_CTORS_BODY \
- +do { \
- + func_ptr *p; \
- + \
- + for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) \
- + (*p) (); \
- +} while (0)
- +#endif
- +
- extern void __do_global_ctors (void);
-
- /* This case is used by the Irix 6 port, which supports named sections but
- @@ -573,8 +604,7 @@
- #if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
- __do_global_ctors_1();
- #endif
- - for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
- - (*p) ();
- + DO_GLOBAL_CTORS_BODY;
- }
-
- #else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */
- diff -Nur gcc-4.2.4.orig/gcc/cse.c gcc-4.2.4/gcc/cse.c
- --- gcc-4.2.4.orig/gcc/cse.c 2008-01-14 06:18:30.000000000 -0600
- +++ gcc-4.2.4/gcc/cse.c 2015-07-03 18:46:05.721283542 -0500
- @@ -4881,6 +4881,17 @@
- }
- }
-
- +#ifdef AUTO_INC_DEC
- + /* Invalidate all AUTO inc registers. */
- + {
- + rtx link;
- +
- + for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
- + if (REG_NOTE_KIND (link) == REG_INC)
- + invalidate (XEXP (link, 0), VOIDmode);
- + }
- +#endif
- +
- if (GET_CODE (x) == SET)
- {
- sets = alloca (sizeof (struct set));
- diff -Nur gcc-4.2.4.orig/gcc/expr.c gcc-4.2.4/gcc/expr.c
- --- gcc-4.2.4.orig/gcc/expr.c 2008-02-04 16:03:09.000000000 -0600
- +++ gcc-4.2.4/gcc/expr.c 2015-07-03 18:46:05.721283542 -0500
- @@ -3652,9 +3652,23 @@
-
- /* USED is now the # of bytes we need not copy to the stack
- because registers will take care of them. */
- -
- if (partial != 0)
- - xinner = adjust_address (xinner, BLKmode, used);
- + {
- +#ifdef METAG_PARTIAL_ARGS
- + if (GET_CODE (size) == CONST_INT)
- + {
- + HOST_WIDE_INT onstack = INTVAL (size) - partial;
- +
- + onstack = (onstack + (STACK_BOUNDARY_BYTES - 1)) & ~(STACK_BOUNDARY_BYTES - 1);
- +
- + size = GEN_INT (onstack + partial);
- + }
- + else
- + gcc_unreachable ();
- +#else
- + xinner = adjust_address (xinner, BLKmode, used);
- +#endif
- + }
-
- /* If the partial register-part of the arg counts in its stack size,
- skip the part of stack space corresponding to the registers.
- @@ -3765,6 +3779,8 @@
- int offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
- int args_offset = INTVAL (args_so_far);
- int skip;
- + int begin_on_stack;
- + int end_on_stack;
-
- /* Push padding now if padding above and stack grows down,
- or if padding below and stack grows up.
- @@ -3784,11 +3800,19 @@
- not_stack = (partial - offset) / UNITS_PER_WORD;
- offset /= UNITS_PER_WORD;
-
- +#ifdef METAG_PARTIAL_ARGS
- + begin_on_stack = 0;
- + end_on_stack = size - not_stack;
- +#else
- + begin_on_stack = not_stack;
- + end_on_stack = size;
- +#endif
- +
- /* If the partial register-part of the arg counts in its stack size,
- skip the part of stack space corresponding to the registers.
- Otherwise, start copying to the beginning of the stack space,
- by setting SKIP to 0. */
- - skip = (reg_parm_stack_space == 0) ? 0 : not_stack;
- + skip = (reg_parm_stack_space == 0) ? 0 : begin_on_stack;
-
- if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
- x = validize_mem (force_const_mem (mode, x));
- @@ -3803,15 +3827,15 @@
- /* We can do it by words, because any scalar bigger than a word
- has a size a multiple of a word. */
- #ifndef PUSH_ARGS_REVERSED
- - for (i = not_stack; i < size; i++)
- + for (i = begin_on_stack; i < end_on_stack; i++)
- #else
- - for (i = size - 1; i >= not_stack; i--)
- + for (i = end_on_stack - 1; i >= begin_on_stack; i--)
- #endif
- - if (i >= not_stack + offset)
- + if (i >= begin_on_stack + offset)
- emit_push_insn (operand_subword_force (x, i, mode),
- word_mode, NULL_TREE, NULL_RTX, align, 0, NULL_RTX,
- 0, args_addr,
- - GEN_INT (args_offset + ((i - not_stack + skip)
- + GEN_INT (args_offset + ((i - begin_on_stack + skip)
- * UNITS_PER_WORD)),
- reg_parm_stack_space, alignment_pad);
- }
- @@ -3867,8 +3891,32 @@
- emit_group_load (reg, x, type, -1);
- else
- {
- + xinner = x;
- +
- +#ifdef METAG_PARTIAL_ARGS
- + if (mode != BLKmode)
- + size = GEN_INT (GET_MODE_SIZE (mode) - partial);
- +
- + gcc_assert (size && GET_CODE (size) == CONST_INT);
- +
- + if (GET_CODE (xinner) == CONCAT)
- + {
- + xinner = XEXP (xinner, 1);
- + mode = GET_MODE (xinner);
- +
- + gcc_assert (INTVAL (size) == GET_MODE_SIZE (mode));
- + }
- + else if (GET_CODE (xinner) == MEM)
- + {
- + gcc_assert ((INTVAL (size) & (STACK_BOUNDARY_BYTES - 1)) == 0);
- + xinner = adjust_address (xinner, mode, INTVAL (size) );
- + }
- + else
- + gcc_unreachable ();
- +#endif
- +
- gcc_assert (partial % UNITS_PER_WORD == 0);
- - move_block_to_reg (REGNO (reg), x, partial / UNITS_PER_WORD, mode);
- + move_block_to_reg (REGNO (reg), xinner, partial / UNITS_PER_WORD, mode);
- }
- }
-
- @@ -4779,7 +4827,14 @@
-
- case UNION_TYPE:
- case QUAL_UNION_TYPE:
- - return -1;
- + {
- + /* Ho hum. How in the world do we guess here? Clearly it isn't
- + right to count the fields. Guess based on the number of words. */
- + HOST_WIDE_INT n = int_size_in_bytes (type);
- + if (n < 0)
- + return -1;
- + return n / UNITS_PER_WORD;
- + }
-
- case COMPLEX_TYPE:
- return 2;
- diff -Nur gcc-4.2.4.orig/gcc/function.c gcc-4.2.4/gcc/function.c
- --- gcc-4.2.4.orig/gcc/function.c 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/function.c 2015-07-03 18:46:05.721283542 -0500
- @@ -2245,7 +2245,11 @@
- gcc_assert (!all->extra_pretend_bytes && !all->pretend_args_size);
-
- pretend_bytes = partial;
- +#ifdef METAG_PARTIAL_ARGS
- + all->pretend_args_size = pretend_bytes;
- +#else
- all->pretend_args_size = CEIL_ROUND (pretend_bytes, STACK_BYTES);
- +#endif
-
- /* We want to align relative to the actual stack pointer, so
- don't include this in the stack size until later. */
- @@ -2259,8 +2263,13 @@
-
- /* Adjust offsets to include the pretend args. */
- pretend_bytes = all->extra_pretend_bytes - pretend_bytes;
- - data->locate.slot_offset.constant += pretend_bytes;
- - data->locate.offset.constant += pretend_bytes;
- +#ifdef METAG_PARTIAL_ARGS
- + if (data->partial != 0)
- +#endif
- + {
- + data->locate.slot_offset.constant += pretend_bytes;
- + data->locate.offset.constant += pretend_bytes;
- + }
-
- data->entry_parm = entry_parm;
- }
- @@ -2369,8 +2378,10 @@
- else
- {
- gcc_assert (data->partial % UNITS_PER_WORD == 0);
- +#ifndef METAG_PARTIAL_ARGS
- move_block_from_reg (REGNO (entry_parm), validize_mem (stack_parm),
- data->partial / UNITS_PER_WORD);
- +#endif
- }
-
- entry_parm = stack_parm;
- @@ -3062,8 +3073,10 @@
-
- /* We have aligned all the args, so add space for the pretend args. */
- current_function_pretend_args_size = all.pretend_args_size;
- +#ifndef METAG_PARTIAL_ARGS
- all.stack_args_size.constant += all.extra_pretend_bytes;
- current_function_args_size = all.stack_args_size.constant;
- +#endif
-
- /* Adjust function incoming argument size for alignment and
- minimum length. */
- diff -Nur gcc-4.2.4.orig/gcc/genattrtab.c gcc-4.2.4/gcc/genattrtab.c
- --- gcc-4.2.4.orig/gcc/genattrtab.c 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/genattrtab.c 2015-07-03 18:46:05.721283542 -0500
- @@ -4582,7 +4582,6 @@
- printf ("#include \"coretypes.h\"\n");
- printf ("#include \"tm.h\"\n");
- printf ("#include \"rtl.h\"\n");
- - printf ("#include \"tm_p.h\"\n");
- printf ("#include \"insn-config.h\"\n");
- printf ("#include \"recog.h\"\n");
- printf ("#include \"regs.h\"\n");
- @@ -4592,6 +4591,7 @@
- printf ("#include \"toplev.h\"\n");
- printf ("#include \"flags.h\"\n");
- printf ("#include \"function.h\"\n");
- + printf ("#include \"tm_p.h\"\n");
- printf ("\n");
- printf ("#define operands recog_data.operand\n\n");
-
- diff -Nur gcc-4.2.4.orig/gcc/genmodes.c gcc-4.2.4/gcc/genmodes.c
- --- gcc-4.2.4.orig/gcc/genmodes.c 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/genmodes.c 2015-07-03 18:46:05.725283542 -0500
- @@ -785,8 +785,7 @@
- /* Output routines. */
-
- #define tagged_printf(FMT, ARG, TAG) do { \
- - int count_; \
- - printf (" " FMT ",%n", ARG, &count_); \
- + int count_ = printf (" " FMT ",", ARG); \
- printf ("%*s/* %s */\n", 27 - count_, "", TAG); \
- } while (0)
-
- @@ -820,8 +819,7 @@
- for (c = 0; c < MAX_MODE_CLASS; c++)
- for (m = modes[c]; m; m = m->next)
- {
- - int count_;
- - printf (" %smode,%n", m->name, &count_);
- + int count_ = printf (" %smode,", m->name);
- printf ("%*s/* %s:%d */\n", 27 - count_, "",
- trim_filename (m->file), m->line);
- }
- diff -Nur gcc-4.2.4.orig/gcc/genopinit.c gcc-4.2.4/gcc/genopinit.c
- --- gcc-4.2.4.orig/gcc/genopinit.c 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/genopinit.c 2015-07-03 18:46:05.725283542 -0500
- @@ -1,6 +1,7 @@
- /* Generate code to initialize optabs from machine description.
- Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- - 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
- + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2010
- + Free Software Foundation, Inc.
-
- This file is part of GCC.
-
- @@ -414,7 +415,8 @@
- printf ("#include \"recog.h\"\n");
- printf ("#include \"expr.h\"\n");
- printf ("#include \"optabs.h\"\n");
- - printf ("#include \"reload.h\"\n\n");
- + printf ("#include \"reload.h\"\n");
- + printf ("#include \"toplev.h\"\n\n");
-
- printf ("void\ninit_all_optabs (void)\n{\n");
-
- diff -Nur gcc-4.2.4.orig/gcc/loop-doloop.c gcc-4.2.4/gcc/loop-doloop.c
- --- gcc-4.2.4.orig/gcc/loop-doloop.c 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/loop-doloop.c 2015-07-03 18:46:05.725283542 -0500
- @@ -65,6 +65,10 @@
-
- #ifdef HAVE_doloop_end
-
- +#ifndef DECREMENT_AND_BRANCH_REG
- +#define DECREMENT_AND_BRANCH_REG(MODE) gen_reg_rtx (MODE)
- +#endif
- +
- /* Return the loop termination condition for PATTERN or zero
- if it is not a decrement and branch jump insn. */
-
- @@ -358,6 +362,10 @@
- if (increment_count)
- count = simplify_gen_binary (PLUS, mode, count, const1_rtx);
-
- + /* CONST_INT's must be correctly sign-extended for mode. */
- + if (CONST_INT_P (count))
- + count = gen_int_mode (INTVAL (count), mode);
- +
- /* Insert initialization of the count register into the loop header. */
- start_sequence ();
- tmp = force_operand (count, counter_reg);
- @@ -544,7 +552,7 @@
- to modify the loop since there is some aspect the back-end does
- not like. */
- start_label = block_label (desc->in_edge->dest);
- - doloop_reg = gen_reg_rtx (mode);
- + doloop_reg = DECREMENT_AND_BRANCH_REG (mode);
- doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
- GEN_INT (level), start_label);
-
- @@ -612,6 +620,18 @@
- return true;
- }
-
- +#ifndef DOLOOP_OPTIMIZE_INIT
- +#define DOLOOP_OPTIMIZE_INIT()
- +#endif
- +
- +#ifndef DOLOOP_OPTIMIZE_LOOP
- +#define DOLOOP_OPTIMIZE_LOOP(LOOP) doloop_optimize (LOOP)
- +#endif
- +
- +#ifndef DOLOOP_OPTIMIZE_FINI
- +#define DOLOOP_OPTIMIZE_FINI()
- +#endif
- +
- /* This is the main entry point. Process all LOOPS using doloop_optimize. */
-
- void
- @@ -620,15 +640,19 @@
- unsigned i;
- struct loop *loop;
-
- + DOLOOP_OPTIMIZE_INIT ();
- +
- for (i = 1; i < loops->num; i++)
- {
- loop = loops->parray[i];
- if (!loop)
- continue;
-
- - doloop_optimize (loop);
- + DOLOOP_OPTIMIZE_LOOP (loop);
- }
-
- + DOLOOP_OPTIMIZE_FINI ();
- +
- iv_analysis_done ();
-
- #ifdef ENABLE_CHECKING
- diff -Nur gcc-4.2.4.orig/gcc/mkmap-symver.awk gcc-4.2.4/gcc/mkmap-symver.awk
- --- gcc-4.2.4.orig/gcc/mkmap-symver.awk 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/mkmap-symver.awk 2015-07-03 18:46:05.725283542 -0500
- @@ -21,8 +21,13 @@
- BEGIN {
- state = "nm";
- sawsymbol = 0;
- + showprefix = "_";
- if (leading_underscore)
- + {
- + if (no_show_underscore)
- + showprefix = "";
- prefix = "_";
- + }
- else
- prefix = "";
- }
- @@ -81,7 +86,7 @@
- }
-
- {
- - sym = prefix $1;
- + sym = $1;
- if (thislib != "%exclude")
- ver[sym] = thislib;
- else
- @@ -108,7 +113,7 @@
-
- empty=1
- for (sym in ver)
- - if ((ver[sym] == lib) && (sym in def))
- + if (((ver[sym]) == lib) && ((prefix sym) in def))
- {
- if (empty)
- {
- @@ -116,7 +121,7 @@
- printf(" global:\n");
- empty = 0;
- }
- - printf("\t%s;\n", sym);
- + printf("\t%s;\n", showprefix sym);
- }
-
- if (empty)
- diff -Nur gcc-4.2.4.orig/gcc/output.h gcc-4.2.4/gcc/output.h
- --- gcc-4.2.4.orig/gcc/output.h 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/output.h 2015-07-03 18:46:05.725283542 -0500
- @@ -490,7 +490,7 @@
- /* The callback used to switch to the section, and the data that
- should be passed to the callback. */
- unnamed_section_callback GTY ((skip)) callback;
- - const void *GTY ((skip)) data;
- + const char *GTY (()) data;
-
- /* The next entry in the chain of unnamed sections. */
- section *next;
- @@ -557,6 +557,9 @@
- extern void place_block_symbol (rtx);
- extern rtx get_section_anchor (struct object_block *, HOST_WIDE_INT,
- enum tls_model);
- +extern section *mergeable_string_section (tree,
- + unsigned HOST_WIDE_INT,
- + unsigned int);
- extern section *mergeable_constant_section (enum machine_mode,
- unsigned HOST_WIDE_INT,
- unsigned int);
- diff -Nur gcc-4.2.4.orig/gcc/print-rtl.c gcc-4.2.4/gcc/print-rtl.c
- --- gcc-4.2.4.orig/gcc/print-rtl.c 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/print-rtl.c 2015-07-03 18:46:05.725283542 -0500
- @@ -428,11 +428,11 @@
- const char *name;
-
- #ifndef GENERATOR_FILE
- - if (REG_P (in_rtx) && value < FIRST_PSEUDO_REGISTER)
- + if (REG_P (in_rtx) && (unsigned)value < FIRST_PSEUDO_REGISTER)
- fprintf (outfile, " %d %s", REGNO (in_rtx),
- reg_names[REGNO (in_rtx)]);
- else if (REG_P (in_rtx)
- - && value <= LAST_VIRTUAL_REGISTER)
- + && (unsigned)value <= LAST_VIRTUAL_REGISTER)
- {
- if (value == VIRTUAL_INCOMING_ARGS_REGNUM)
- fprintf (outfile, " %d virtual-incoming-args", value);
- diff -Nur gcc-4.2.4.orig/gcc/regmove.c gcc-4.2.4/gcc/regmove.c
- --- gcc-4.2.4.orig/gcc/regmove.c 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/regmove.c 2015-07-03 18:46:05.725283542 -0500
- @@ -80,6 +80,10 @@
- static int regclass_compatible_p (int, int);
- static int replacement_quality (rtx);
- static int fixup_match_2 (rtx, rtx, rtx, rtx);
- +#ifdef AUTO_INC_DEC
- +static void update_auto_inc_notes (rtx);
- +static void remove_auto_inc_notes (rtx);
- +#endif
-
- /* Return nonzero if registers with CLASS1 and CLASS2 can be merged without
- causing too much register allocation problems. */
- @@ -1043,6 +1047,52 @@
- return 0;
- }
-
- +#ifdef AUTO_INC_DEC
- +/* Remove all REG_INC notes from INSN. */
- +
- +static void
- +remove_auto_inc_notes (rtx insn)
- +{
- + rtx prev = NULL_RTX;
- + rtx link;
- +
- + gcc_assert (insn);
- +
- + link = REG_NOTES (insn);
- + while (link)
- + {
- + rtx next = XEXP (link, 1);
- +
- + if (REG_NOTE_KIND (link) == REG_INC)
- + {
- + if (link == REG_NOTES (insn))
- + REG_NOTES (insn) = next;
- + else
- + XEXP (prev, 1) = next;
- + }
- +
- + prev = link;
- + link = next;
- + }
- +}
- +
- +/* Updates REG_INC notes for all insns in the sequence starting at FIRST. */
- +
- +static void
- +update_auto_inc_notes (rtx first)
- +{
- + rtx insn;
- +
- + for (insn = first; insn; insn = NEXT_INSN (insn))
- + if (INSN_P (insn))
- + {
- + remove_auto_inc_notes (insn);
- +
- + add_auto_inc_notes (insn, PATTERN (insn));
- + }
- +}
- +#endif
- +
- /* Main entry for the register move optimization.
- F is the first instruction.
- NREGS is one plus the highest pseudo-reg number used in the instruction.
- @@ -2491,6 +2541,11 @@
- rest_of_handle_regmove (void)
- {
- regmove_optimize (get_insns (), max_reg_num ());
- +#ifdef AUTO_INC_DEC
- + /* The regmove optimization may invalidate existing REG_INC notes
- + so update the REG_INC note afterwards. */
- + update_auto_inc_notes (get_insns ());
- +#endif
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
- return 0;
- }
- diff -Nur gcc-4.2.4.orig/gcc/regrename.c gcc-4.2.4/gcc/regrename.c
- --- gcc-4.2.4.orig/gcc/regrename.c 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/regrename.c 2015-07-03 18:46:05.725283542 -0500
- @@ -182,6 +182,11 @@
- }
- }
-
- +#if !defined(HARD_REGNO_RENAME_OK_FOR_INSN) && defined(HARD_REGNO_RENAME_OK)
- +#define HARD_REGNO_RENAME_OK_FOR_INSN(INSN, FROM, TOO) \
- + HARD_REGNO_RENAME_OK (FROM, TOO)
- +#endif
- +
- /* Perform register renaming on the current function. */
-
- static void
- @@ -303,8 +308,8 @@
- || (current_function_is_leaf
- && !LEAF_REGISTERS[new_reg + i])
- #endif
- -#ifdef HARD_REGNO_RENAME_OK
- - || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i)
- +#ifdef HARD_REGNO_RENAME_OK_FOR_INSN
- + || ! HARD_REGNO_RENAME_OK_FOR_INSN (this->insn, reg + i, new_reg + i)
- #endif
- )
- break;
- @@ -1546,13 +1551,13 @@
- case PRE_INC:
- case PRE_DEC:
- case PRE_MODIFY:
- - return false;
- + return changed;
-
- case MEM:
- - return replace_oldest_value_mem (x, insn, vd);
- + return changed | replace_oldest_value_mem (x, insn, vd);
-
- case REG:
- - return replace_oldest_value_reg (loc, cl, insn, vd);
- + return changed | replace_oldest_value_reg (loc, cl, insn, vd);
-
- default:
- break;
- @@ -1674,14 +1679,18 @@
- if (REG_P (SET_DEST (set)))
- {
- new = find_oldest_value_reg (REGNO_REG_CLASS (regno), src, vd);
- - if (new && validate_change (insn, &SET_SRC (set), new, 0))
- + if (new)
- {
- - if (dump_file)
- - fprintf (dump_file,
- - "insn %u: replaced reg %u with %u\n",
- - INSN_UID (insn), regno, REGNO (new));
- - changed = true;
- - goto did_replacement;
- + if (validate_change (insn, &SET_SRC (set), new, 0))
- + {
- + if (dump_file)
- + fprintf (dump_file,
- + "insn %u: replaced reg %u with %u\n",
- + INSN_UID (insn), regno, REGNO (new));
- + changed = true;
- + goto did_replacement;
- + }
- + extract_insn (insn);
- }
- }
-
- @@ -1704,6 +1713,7 @@
- changed = true;
- goto did_replacement;
- }
- + extract_insn (insn);
- }
- }
- }
- @@ -1711,6 +1721,8 @@
-
- any_replacements = false;
-
- + gcc_assert (n_ops == recog_data.n_operands);
- +
- /* For each input operand, replace a hard register with the
- eldest live copy that's in an appropriate register class. */
- for (i = 0; i < n_ops; i++)
- diff -Nur gcc-4.2.4.orig/gcc/reload1.c gcc-4.2.4/gcc/reload1.c
- --- gcc-4.2.4.orig/gcc/reload1.c 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/reload1.c 2015-07-03 18:46:05.725283542 -0500
- @@ -438,9 +438,6 @@
- static void delete_address_reloads (rtx, rtx);
- static void delete_address_reloads_1 (rtx, rtx, rtx);
- static rtx inc_for_reload (rtx, rtx, rtx, int);
- -#ifdef AUTO_INC_DEC
- -static void add_auto_inc_notes (rtx, rtx);
- -#endif
- static void copy_eh_notes (rtx, rtx);
- static int reloads_conflict (int, int);
- static rtx gen_reload (rtx, rtx, int, enum reload_type);
- @@ -653,6 +650,10 @@
- struct elim_table *ep;
- basic_block bb;
-
- +#ifdef ENABLE_CHECKING
- + verify_auto_inc_notes_p (first);
- +#endif
- +
- /* Make sure even insns with volatile mem refs are recognizable. */
- init_recog ();
-
- @@ -8296,34 +8297,6 @@
- return store;
- }
-
- -#ifdef AUTO_INC_DEC
- -static void
- -add_auto_inc_notes (rtx insn, rtx x)
- -{
- - enum rtx_code code = GET_CODE (x);
- - const char *fmt;
- - int i, j;
- -
- - if (code == MEM && auto_inc_p (XEXP (x, 0)))
- - {
- - REG_NOTES (insn)
- - = gen_rtx_EXPR_LIST (REG_INC, XEXP (XEXP (x, 0), 0), REG_NOTES (insn));
- - return;
- - }
- -
- - /* Scan all the operand sub-expressions. */
- - fmt = GET_RTX_FORMAT (code);
- - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- - {
- - if (fmt[i] == 'e')
- - add_auto_inc_notes (insn, XEXP (x, i));
- - else if (fmt[i] == 'E')
- - for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- - add_auto_inc_notes (insn, XVECEXP (x, i, j));
- - }
- -}
- -#endif
- -
- /* Copy EH notes from an insn to its reloads. */
- static void
- copy_eh_notes (rtx insn, rtx x)
- diff -Nur gcc-4.2.4.orig/gcc/rtlanal.c gcc-4.2.4/gcc/rtlanal.c
- --- gcc-4.2.4.orig/gcc/rtlanal.c 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/rtlanal.c 2015-07-03 18:46:05.729283542 -0500
- @@ -1042,6 +1042,11 @@
- a special insn which should not be considered a no-op. */
- if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
- return 0;
- +
- + /* Extract the code of a cond_exec as a conditional noop is no
- + more useful than a noop itself */
- + if (GET_CODE (pat) == COND_EXEC)
- + pat = COND_EXEC_CODE (pat);
-
- if (GET_CODE (pat) == SET && set_noop_p (pat))
- return 1;
- @@ -2832,6 +2837,74 @@
- return 0;
- }
-
- +/* If X has autoincrement side effects then add required REG_INC notes. */
- +void
- +add_auto_inc_notes (rtx insn, rtx x)
- +{
- + enum rtx_code code = GET_CODE (x);
- + const char *fmt;
- + int i, j;
- +
- + if (code == MEM && auto_inc_p (XEXP (x, 0)))
- + {
- + REG_NOTES (insn)
- + = gen_rtx_EXPR_LIST (REG_INC, XEXP (XEXP (x, 0), 0), REG_NOTES (insn));
- + return;
- + }
- +
- + /* Scan all the operand sub-expressions. */
- + fmt = GET_RTX_FORMAT (code);
- + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- + {
- + if (fmt[i] == 'e')
- + add_auto_inc_notes (insn, XEXP (x, i));
- + else if (fmt[i] == 'E')
- + for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- + add_auto_inc_notes (insn, XVECEXP (x, i, j));
- + }
- +}
- +
- +/* Verify if INSN has required REG_INC notes. */
- +
- +void
- +verify_auto_inc_notes_for_insn_p (rtx insn, rtx x)
- +{
- + enum rtx_code code = GET_CODE (x);
- + const char *fmt;
- + int i, j;
- +
- + if (code == MEM && auto_inc_p (XEXP (x, 0)))
- + {
- + if (find_reg_note (insn, REG_INC, XEXP (XEXP (x, 0), 0)) == NULL_RTX)
- + fatal_insn ("Insn missing REG_INC note:", insn);
- + }
- +
- + /* Scan all the operand sub-expressions. */
- + fmt = GET_RTX_FORMAT (code);
- + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- + {
- + if (fmt[i] == 'e')
- + verify_auto_inc_notes_for_insn_p (insn, XEXP (x, i));
- + else if (fmt[i] == 'E')
- + for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- + verify_auto_inc_notes_for_insn_p (insn, XVECEXP (x, i, j));
- + }
- +
- + return;
- +}
- +
- +/* Verify that all insns in the sequence starting at FIRST
- + have required REG_INC notes. */
- +void
- +verify_auto_inc_notes_p (rtx first)
- +{
- + rtx insn;
- +
- + for (insn = first; insn; insn = NEXT_INSN (insn))
- + if (INSN_P (insn))
- + verify_auto_inc_notes_for_insn_p (insn, PATTERN (insn));
- +}
- +
- /* Return nonzero if IN contains a piece of rtl that has the address LOC. */
- int
- loc_mentioned_in_p (rtx *loc, rtx in)
- diff -Nur gcc-4.2.4.orig/gcc/rtl.h gcc-4.2.4/gcc/rtl.h
- --- gcc-4.2.4.orig/gcc/rtl.h 2007-11-07 14:48:38.000000000 -0600
- +++ gcc-4.2.4/gcc/rtl.h 2015-07-03 18:46:05.729283542 -0500
- @@ -1722,6 +1722,9 @@
- extern int for_each_rtx (rtx *, rtx_function, void *);
- extern rtx regno_use_in (unsigned int, rtx);
- extern int auto_inc_p (rtx);
- +extern void add_auto_inc_notes (rtx, rtx);
- +extern void verify_auto_inc_notes_p (rtx);
- +extern void verify_auto_inc_notes_for_insn_p (rtx, rtx);
- extern int in_expr_list_p (rtx, rtx);
- extern void remove_node_from_expr_list (rtx, rtx *);
- extern int loc_mentioned_in_p (rtx *, rtx);
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.c-torture/execute/builtins/lib/chk.c gcc-4.2.4/gcc/testsuite/gcc.c-torture/execute/builtins/lib/chk.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.c-torture/execute/builtins/lib/chk.c 2005-06-27 07:17:39.000000000 -0500
- +++ gcc-4.2.4/gcc/testsuite/gcc.c-torture/execute/builtins/lib/chk.c 2015-07-03 18:46:05.777283542 -0500
- @@ -448,6 +448,10 @@
- return ret;
- }
-
- +/* This doesn't work on a target which uses uclibc.
- + This is because in uclibc vsprint is implemented by use vsnprintf
- + so this code will end up recusing itself to death. */
- +#ifndef __metag__
- int
- vsnprintf (char *str, __SIZE_TYPE__ len, const char *fmt, va_list ap)
- {
- @@ -470,3 +474,4 @@
- }
- return ret;
- }
- +#endif
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.c-torture/execute/pr36093.x gcc-4.2.4/gcc/testsuite/gcc.c-torture/execute/pr36093.x
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.c-torture/execute/pr36093.x 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.c-torture/execute/pr36093.x 2015-07-03 18:46:05.777283542 -0500
- @@ -0,0 +1,10 @@
- +# The META and MTX linkers require data aligned more than 64 bytes to be
- +# placed in a named section.
- +if { [istarget "metag*-local"] } {
- + set torture_compile_xfail "metag*-local"
- +}
- +
- +if { [istarget "mtxg*-local"] } {
- + set torture_compile_xfail "mtxg*-local"
- +}
- +return 0
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.dg/20020312-2.c gcc-4.2.4/gcc/testsuite/gcc.dg/20020312-2.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.dg/20020312-2.c 2006-04-13 18:14:25.000000000 -0500
- +++ gcc-4.2.4/gcc/testsuite/gcc.dg/20020312-2.c 2015-07-03 18:46:05.789283541 -0500
- @@ -72,6 +72,8 @@
- /* No pic register. */
- #elif defined(__m32c__)
- /* No pic register. */
- +#elif defined(__metag__)
- +# define PIC_REG "A1LbP"
- #else
- # error "Modify the test for your target."
- #endif
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/condret1.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/condret1.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/condret1.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/condret1.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,38 @@
- +/* { dg-options "-mmetac=2.1 -O2" } */
- +/* { dg-skip-if "" { *-*-* } { "-mmetac=1.2" } { "" } } */
- +/* { dg-skip-if "" { mtxg*-local } { "*" } { "" } } */
- +
- +/*
- + * Check that conditional returns are not used
- + * for META 2 code
- + */
- +
- +extern int bar;
- +extern int bar2;
- +extern int zee(int);
- +int mainly(int foo)
- +{
- + if (bar2 == 0)
- + {
- + return 0;
- + }
- + if (foo >5)
- + {
- + foo+=bar;
- + return foo;
- + }
- + else if (foo >2)
- + {
- + foo+=bar2;
- + return foo+34;
- + }
- + else
- + {
- + foo-=bar;
- + return zee(foo);
- + }
- +}
- +
- +/* { dg-final { scan-assembler-times "\\\$LX\[0-9\]\+:" 1 } }*/
- +/* { dg-final { scan-assembler-times "MOV\tPC, D1RtP" 2 } }*/
- +/* { dg-final { scan-assembler-not "MOV\[A-Z\]\[A-Z\]\tPC, D1RtP" } }*/
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/condret2.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/condret2.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/condret2.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/condret2.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,37 @@
- +/* { dg-options "-mmetac=1.2 -O2" } */
- +/* { dg-skip-if "" { *-*-* } { "-mmetac=2.1" } { "" } } */
- +
- +/*
- + * Check that conditional returns are used
- + * for META 1 code
- + */
- +
- +extern int bar;
- +extern int bar2;
- +extern int zee(int);
- +int mainly(int foo)
- +{
- + if (bar2 == 0)
- + {
- + return 0;
- + }
- + if (foo >5)
- + {
- + foo+=bar;
- + return foo;
- + }
- + else if (foo >2)
- + {
- + foo+=bar2;
- + return foo+34;
- + }
- + else
- + {
- + foo-=bar;
- + return zee(foo);
- + }
- +}
- +
- +/* { dg-final { scan-assembler-not "\\\$LX\[0-9\]+:" } }*/
- +/* { dg-final { scan-assembler-times "MOV\tPC, D1RtP" 1 } }*/
- +/* { dg-final { scan-assembler-times "MOV\[A-Z\]\[A-Z\]\tPC, D1RtP" 2 } }*/
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/condret3.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/condret3.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/condret3.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/condret3.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,21 @@
- +/* { dg-options "-mmetac=2.1 -O2" } */
- +/* { dg-skip-if "" { *-*-* } { "-mmetac=1.2" } { "" } } */
- +/* { dg-skip-if "" { mtxg*-local } { "*" } { "" } } */
- +
- +/*
- + * Check that conditional returns are not used
- + * for META 2 code
- + */
- +
- +typedef void (*my_func)(int);
- +int cond;
- +
- +int no_unconditional_return (my_func *f)
- +{
- + if (cond)
- + (*f) (3);
- +}
- +
- +/* { dg-final { scan-assembler-times "\\\$LX\[0-9\]+:" 1 } }*/
- +/* { dg-final { scan-assembler-times "MOV\tPC, D1RtP" 1 } }*/
- +/* { dg-final { scan-assembler-not "MOV\[A-Z\]\[A-Z\]\tPC, D1RtP" } }*/
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/condret4.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/condret4.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/condret4.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/condret4.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,19 @@
- +/* { dg-options "-mmetac=1.2 -O2" } */
- +/* { dg-skip-if "" { *-*-* } { "-mmetac=2.1" } { "" } } */
- +
- +/*
- + * Check that conditional returns are not used
- + * for META 1 code
- + */
- +
- +typedef void (*my_func)(int);
- +int cond;
- +
- +int no_unconditional_return (my_func *f)
- +{
- + if (cond)
- + (*f) (3);
- +}
- +
- +/* { dg-final { scan-assembler-not "\\\$LX\[0-9\]+:" } }*/
- +/* { dg-final { scan-assembler-times "MOV\[A-Z\]\[A-Z\]\tPC, D1RtP" 1 } }*/
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/ech1.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/ech1.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/ech1.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/ech1.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,16 @@
- +/* { dg-options "-O2" } */
- +/* { dg-skip-if "" { mtxg*-local } { "*" } { "" } } */
- +
- +/*
- + * Check that ECH is not used when no dsp resources are enabled
- + * ECH is implemented using D0.8 so it will not be referred to
- + * when ECH is disabled
- + */
- +int glob;
- +
- +void test_func()
- +{
- + glob++;
- +}
- +
- +/* { dg-final { scan-assembler-not "D0.8" } }*/
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/ech2.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/ech2.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/ech2.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/ech2.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,15 @@
- +/* { dg-options "-O2 -mdsp" } */
- +/* { dg-skip-if "" { mtxg*-local } { "*" } { "" } } */
- +
- +/*
- + * Check that ECH status is not changed by a function that uses no
- + * dsp resources
- + */
- +int glob;
- +
- +void test_func()
- +{
- + glob++;
- +}
- +
- +/* { dg-final { scan-assembler-not "D0.8" } }*/
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/ech3.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/ech3.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/ech3.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/ech3.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,15 @@
- +/* { dg-options "-O2 -mdsp" } */
- +/* { dg-skip-if "" { mtxg*-local } { "*" } { "" } } */
- +
- +/*
- + * Check that ECH status is set when a dsp register is used
- + */
- +int glob;
- +
- +void test_func()
- +{
- + glob++;
- + asm ("":::"D0.9");
- +}
- +
- +/* { dg-final { scan-assembler "MOVT\tD0.8, #4384" } }*/
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/ech4.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/ech4.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/ech4.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/ech4.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,16 @@
- +/* { dg-options "-O2 -mdsp -mno-tbictxsave" } */
- +/* { dg-skip-if "" { mtxg*-local } { "*" } { "" } } */
- +
- +/*
- + * Check that ECH is disabled when requested even if DSP resources
- + * are used
- + */
- +int glob;
- +
- +void test_func()
- +{
- + glob++;
- + asm ("":::"D0.9");
- +}
- +
- +/* { dg-final { scan-assembler-not "D0.8" } }*/
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/ech5.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/ech5.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/ech5.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/ech5.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,17 @@
- +/* { dg-options "-O2 -mdsp" } */
- +/* { dg-skip-if "" { mtxg*-local } { "*" } { "" } } */
- +
- +/*
- + * Check that ECH status is set when a dsp register is used from
- + * both A and D units
- + */
- +int glob;
- +
- +void test_func()
- +{
- + glob++;
- + asm ("":::"D0.9");
- + asm ("":::"A0.4");
- +}
- +
- +/* { dg-final { scan-assembler "MOVT\tD0.8, #4896" } }*/
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/ech6.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/ech6.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/ech6.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/ech6.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,17 @@
- +/* { dg-options "-O2 -mdsp" } */
- +/* { dg-skip-if "" { mtxg*-local } { "*" } { "" } } */
- +
- +/*
- + * Check that ECH status is set when a dsp register is used from
- + * just A unit. This should also result in D registers being saved
- + * as D0.8 is in that range.
- + */
- +int glob;
- +
- +void test_func()
- +{
- + glob++;
- + asm ("":::"A0.4");
- +}
- +
- +/* { dg-final { scan-assembler "MOVT\tD0.8, #4896" } }*/
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/metag.exp gcc-4.2.4/gcc/testsuite/gcc.target/metag/metag.exp
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/metag.exp 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/metag.exp 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,41 @@
- +# Copyright (C) 2010 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 3 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 GCC; see the file COPYING3. If not see
- +# <http://www.gnu.org/licenses/>.
- +
- +# GCC testsuite that uses the `dg.exp' driver.
- +
- +# Exit immediately if this isn't an METAG target.
- +if ![istarget metag*-*-*] then {
- + return
- +}
- +
- +# Load support procs.
- +load_lib gcc-dg.exp
- +
- +# If a testcase doesn't have special options, use these.
- +global DEFAULT_CFLAGS
- +if ![info exists DEFAULT_CFLAGS] then {
- + set DEFAULT_CFLAGS " -ansi -pedantic-errors"
- +}
- +
- +# Initialize `dg'.
- +dg-init
- +
- +# Main loop.
- +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
- + "" $DEFAULT_CFLAGS
- +
- +# All done.
- +dg-finish
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/strcmpbcs.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/strcmpbcs.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/strcmpbcs.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/strcmpbcs.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,20 @@
- +/* { dg-do compile } */
- +/* { dg-options "-mcharset=basic" } */
- +#include <stdio.h>
- +
- +char c [100];
- +char f [100];
- +
- +int main(void)
- +{
- + if(strcmp (c,f) == 0)
- + {
- + return 1;
- + }
- + else
- + {
- + return 0;
- + }
- +}
- +
- +/* { dg-final { scan-assembler "strcmpbcs" } } */
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/thread_pointer_builtin.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/thread_pointer_builtin.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/thread_pointer_builtin.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/thread_pointer_builtin.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,11 @@
- +/* { dg-do compile } */
- +/* { dg-options "-O2 -fpic" } */
- +/* { dg-require-effective-target tls } */
- +
- +void *foo(void)
- +{
- + return __builtin_thread_pointer();
- +}
- +
- +/* { dg-final { scan-assembler-times "___metag_load_tp@PLT" 1 } } */
- +/* { dg-final { scan-assembler-not "___metag_load_tp$" } } */
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/thread_pointer_builtin-non-pic.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/thread_pointer_builtin-non-pic.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/thread_pointer_builtin-non-pic.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/thread_pointer_builtin-non-pic.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,11 @@
- +/* { dg-do compile } */
- +/* { dg-options "-O2" } */
- +/* { dg-require-effective-target tls } */
- +
- +void *foo(void)
- +{
- + return __builtin_thread_pointer();
- +}
- +
- +/* { dg-final { scan-assembler-not "___metag_load_tp@PLT" } } */
- +/* { dg-final { scan-assembler-times "___metag_load_tp" 1 } } */
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/tls.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/tls.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/tls.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/tls.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,47 @@
- +/* { dg-do compile } */
- +/* { dg-options "-O2 -fpic" } */
- +/* { dg-require-effective-target tls } */
- +
- +extern __thread int a __attribute__ ((tls_model ("global-dynamic")));
- +static __thread int b __attribute__ ((tls_model ("local-dynamic")));
- +extern __thread int c __attribute__ ((tls_model ("initial-exec")));
- +static __thread int d __attribute__ ((tls_model ("local-exec")));
- +
- +int*
- +test (void)
- +{
- + a=a+7;
- + return &a;
- +}
- +
- +int*
- +test2 (void)
- +{
- + b=b+10;
- + return &b;
- +}
- +
- +int*
- +test3 (void)
- +{
- + c=c+7;
- + return &c;
- +}
- +
- +int*
- +test4 (void)
- +{
- + d=d+10;
- + return &d;
- +}
- +
- +/* { dg-final { scan-assembler-times "\\(_a@TLSGD\\)" 1 } } */
- +/* { dg-final { scan-assembler-times "\\(_b@TLSLDM\\)" 1 } } */
- +/* { dg-final { scan-assembler-times "#HI\\(_b@TLSLDO\\)" 1 } } */
- +/* { dg-final { scan-assembler-times "#LO\\(_b@TLSLDO\\)" 1 } } */
- +/* { dg-final { scan-assembler-times "\\(_c@TLSIE\\)" 1 } } */
- +/* { dg-final { scan-assembler-times "#HI\\(_d@TLSLE\\)" 1 } } */
- +/* { dg-final { scan-assembler-times "#LO\\(_d@TLSLE\\)" 1 } } */
- +/* { dg-final { scan-assembler-times "___metag_load_tp@PLT" 2 } } */
- +/* { dg-final { scan-assembler-times "___tls_get_addr@PLT" 2 } } */
- +/* { dg-final { scan-assembler-not "_c@TLSIENONPIC\\)" } } */
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/tls-non-pic.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/tls-non-pic.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/tls-non-pic.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/tls-non-pic.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,50 @@
- +/* { dg-do compile } */
- +/* { dg-options "-O2" } */
- +/* { dg-require-effective-target tls } */
- +
- +extern __thread int a __attribute__ ((tls_model ("global-dynamic")));
- +static __thread int b __attribute__ ((tls_model ("local-dynamic")));
- +extern __thread int c __attribute__ ((tls_model ("initial-exec")));
- +static __thread int d __attribute__ ((tls_model ("local-exec")));
- +
- +int*
- +test (void)
- +{
- + a=a+7;
- + return &a;
- +}
- +
- +int*
- +test2 (void)
- +{
- + b=b+10;
- + return &b;
- +}
- +
- +int*
- +test3 (void)
- +{
- + c=c+7;
- + return &c;
- +}
- +
- +int*
- +test4 (void)
- +{
- + d=d+10;
- + return &d;
- +}
- +
- +/* { dg-final { scan-assembler-not "_c@TLSIE\\)" } } */
- +/* { dg-final { scan-assembler-times "#HI\\(_c@TLSIENONPIC\\)" 1 } } */
- +/* { dg-final { scan-assembler-times "#LO\\(_c@TLSIENONPIC\\)" 1 } } */
- +/* { dg-final { scan-assembler-times "\\(_a@TLSGD\\)" 1 } } */
- +/* { dg-final { scan-assembler-times "\\(_b@TLSLDM\\)" 1 } } */
- +/* { dg-final { scan-assembler-times "#HI\\(_b@TLSLDO\\)" 1 } } */
- +/* { dg-final { scan-assembler-times "#LO\\(_b@TLSLDO\\)" 1 } } */
- +/* { dg-final { scan-assembler-times "#HI\\(_d@TLSLE\\)" 1 } } */
- +/* { dg-final { scan-assembler-times "#LO\\(_d@TLSLE\\)" 1 } } */
- +/* { dg-final { scan-assembler-not "___metag_load_tp@PLT" } } */
- +/* { dg-final { scan-assembler-not "___tls_get_addr@PLT" } } */
- +/* { dg-final { scan-assembler-times "___metag_load_tp" 2 } } */
- +/* { dg-final { scan-assembler-times "___tls_get_addr" 2 } } */
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/txrpt-clobber.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/txrpt-clobber.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/txrpt-clobber.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/txrpt-clobber.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,12 @@
- +/* { dg-do compile } */
- +/* { dg-options "-O2" } */
- +int wibble()
- +{
- + int i;
- + for (i = 0 ; i < 100 ; i++)
- + {
- + asm volatile ("foo":::"TXRPT");
- + }
- +}
- +
- +/* { dg-final { scan-assembler-not "BR" } } */
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/umulhisi1.c gcc-4.2.4/gcc/testsuite/gcc.target/metag/umulhisi1.c
- --- gcc-4.2.4.orig/gcc/testsuite/gcc.target/metag/umulhisi1.c 1969-12-31 18:00:00.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/gcc.target/metag/umulhisi1.c 2015-07-03 18:46:05.789283541 -0500
- @@ -0,0 +1,18 @@
- +/* { dg-options "-O2" } */
- +/* { dg-final { scan-assembler-times "47662" 1 } }*/
- +
- +/*
- + * Check that the unsigned 16 bit multiply by constant
- + * optimisation copes with numbers greater than 2^15
- + */
- +
- +#define CONSTANT (47662)
- +
- +unsigned int
- +test(unsigned short in)
- +{
- + unsigned int out = 0;
- + out = (in * CONSTANT);
- + return out;
- +}
- +
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/g++.dg/other/PR23205.C gcc-4.2.4/gcc/testsuite/g++.dg/other/PR23205.C
- --- gcc-4.2.4.orig/gcc/testsuite/g++.dg/other/PR23205.C 2005-10-05 19:47:21.000000000 -0500
- +++ gcc-4.2.4/gcc/testsuite/g++.dg/other/PR23205.C 2015-07-03 18:46:05.777283542 -0500
- @@ -1,5 +1,5 @@
- /* { dg-do compile } */
- -/* { dg-skip-if "No stabs" { mmix-*-* *-*-aix* *-*-netware* alpha*-*-* hppa*64*-*-* ia64-*-* } { "*" } { "" } } */
- +/* { dg-skip-if "No stabs" { mmix-*-* *-*-aix* *-*-netware* alpha*-*-* hppa*64*-*-* ia64-*-* metag*-*-* } { "*" } { "" } } */
- /* { dg-options "-gstabs+ -fno-eliminate-unused-debug-types" } */
-
- const int foobar = 4;
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/lib/file-format.exp gcc-4.2.4/gcc/testsuite/lib/file-format.exp
- --- gcc-4.2.4.orig/gcc/testsuite/lib/file-format.exp 2007-08-31 03:27:50.000000000 -0500
- +++ gcc-4.2.4/gcc/testsuite/lib/file-format.exp 2015-07-03 18:46:05.789283541 -0500
- @@ -39,6 +39,9 @@
- } else {
- set gcc_target_object_format_saved som
- }
- + } elseif { [string match "metag*-linux-uclibc*" $target_triplet] } {
- + # META we deduce the object format from the target_triplet, so hand-code it.
- + set gcc_target_object_format_saved elf
- } else {
- set objdump_name [find_binutils_prog objdump]
- set open_file [open objfmtst.c w]
- diff -Nur gcc-4.2.4.orig/gcc/testsuite/lib/target-supports.exp gcc-4.2.4/gcc/testsuite/lib/target-supports.exp
- --- gcc-4.2.4.orig/gcc/testsuite/lib/target-supports.exp 2008-01-08 22:47:27.000000000 -0600
- +++ gcc-4.2.4/gcc/testsuite/lib/target-supports.exp 2015-07-03 18:46:05.789283541 -0500
- @@ -332,6 +332,13 @@
- return 0
- }
-
- + # uClibc does not have gcrt1.o
- + if { [check_effective_target_uclibc]
- + && ([lindex $test_what 1] == "-p"
- + || [lindex $test_what 1] == "-pg") } {
- + return 0
- + }
- +
- # Now examine the cache variable.
- if {![info exists profiling_available_saved]} {
- # Some targets don't have any implementation of __bb_init_func or are
- @@ -346,6 +353,7 @@
- || [istarget cris-*-*]
- || [istarget h8300-*-*]
- || [istarget m32c-*-elf]
- + || [istarget metag-*-uclibc]
- || [istarget m68k-*-elf]
- || [istarget mips*-*-elf]
- || [istarget xtensa-*-elf]
- @@ -1900,6 +1908,17 @@
- return $et_sync_char_short_saved
- }
-
- +# Return true if this is a uClibc target.
- +
- +proc check_effective_target_uclibc {} {
- + return [check_no_compiler_messages uclibc object {
- + #include <features.h>
- + #if !defined (__UCLIBC__)
- + #error FOO
- + #endif
- + }]
- +}
- +
- # Return 1 if the target matches the effective target 'arg', 0 otherwise.
- # This can be used with any check_* proc that takes no argument and
- # returns only 1 or 0. It could be used with check_* procs that take
- diff -Nur gcc-4.2.4.orig/gcc/toplev.c gcc-4.2.4/gcc/toplev.c
- --- gcc-4.2.4.orig/gcc/toplev.c 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/toplev.c 2015-07-03 18:46:05.741283542 -0500
- @@ -1787,12 +1787,6 @@
- }
- }
-
- - if (flag_function_sections && profile_flag)
- - {
- - warning (0, "-ffunction-sections disabled; it makes profiling impossible");
- - flag_function_sections = 0;
- - }
- -
- #ifndef HAVE_prefetch
- if (flag_prefetch_loop_arrays)
- {
- diff -Nur gcc-4.2.4.orig/gcc/tree-ssa-loop-ivopts.c gcc-4.2.4/gcc/tree-ssa-loop-ivopts.c
- --- gcc-4.2.4.orig/gcc/tree-ssa-loop-ivopts.c 2007-10-12 17:26:47.000000000 -0500
- +++ gcc-4.2.4/gcc/tree-ssa-loop-ivopts.c 2015-07-03 18:46:05.741283542 -0500
- @@ -3377,6 +3377,7 @@
- HOST_WIDE_INT s_offset;
- unsigned HOST_WIDE_INT mask;
- unsigned bits;
- + int start_offset = (STRICT_ALIGNMENT ? GET_MODE_SIZE (Pmode) : 1);
-
- if (!initialized)
- {
- @@ -3391,7 +3392,7 @@
- reg1 = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1);
-
- addr = gen_rtx_fmt_ee (PLUS, Pmode, reg1, NULL_RTX);
- - for (i = 1; i <= 1 << 20; i <<= 1)
- + for (i = start_offset; i <= 1 << 20; i <<= 1)
- {
- XEXP (addr, 1) = gen_int_mode (i, Pmode);
- if (!memory_address_p (Pmode, addr))
- @@ -3400,7 +3401,7 @@
- max_offset = i >> 1;
- off = max_offset;
-
- - for (i = 1; i <= 1 << 20; i <<= 1)
- + for (i = start_offset; i <= 1 << 20; i <<= 1)
- {
- XEXP (addr, 1) = gen_int_mode (-i, Pmode);
- if (!memory_address_p (Pmode, addr))
- @@ -3541,7 +3542,8 @@
-
- cost = 0;
- offset_p = (s_offset != 0
- - && min_offset <= s_offset && s_offset <= max_offset);
- + && min_offset <= s_offset && s_offset <= max_offset
- + && (s_offset <= -start_offset || s_offset >= start_offset));
- ratio_p = (ratio != 1
- && multiplier_allowed_in_address_p (ratio));
-
- diff -Nur gcc-4.2.4.orig/gcc/unwind-dw2.c gcc-4.2.4/gcc/unwind-dw2.c
- --- gcc-4.2.4.orig/gcc/unwind-dw2.c 2007-01-25 01:13:44.000000000 -0600
- +++ gcc-4.2.4/gcc/unwind-dw2.c 2015-07-03 18:46:05.741283542 -0500
- @@ -56,6 +56,11 @@
- #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
- #endif
-
- +/* Table to map Dwarf registers to unwind column. */
- +#ifdef DWARF_REG_TO_UNWIND_COLUMN_TABLE
- +DWARF_REG_TO_UNWIND_COLUMN_TABLE;
- +#endif
- +
- #ifndef DWARF_REG_TO_UNWIND_COLUMN
- #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
- #endif
- @@ -153,23 +158,22 @@
-
- /* Get the value of register INDEX as saved in CONTEXT. */
-
- -inline _Unwind_Word
- -_Unwind_GetGR (struct _Unwind_Context *context, int index)
- +static inline _Unwind_Word
- +_Unwind_ByColumn_GetGR (struct _Unwind_Context *context, int column)
- {
- int size;
- void *ptr;
-
- #ifdef DWARF_ZERO_REG
- - if (index == DWARF_ZERO_REG)
- + if (column == DWARF_REG_TO_UNWIND_COLUMN (DWARF_ZERO_REG))
- return 0;
- #endif
-
- - index = DWARF_REG_TO_UNWIND_COLUMN (index);
- - gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
- - size = dwarf_reg_size_table[index];
- - ptr = context->reg[index];
- + gcc_assert (0 <= column && column < (int) sizeof(dwarf_reg_size_table));
- + size = dwarf_reg_size_table[column];
- + ptr = context->reg[column];
-
- - if (_Unwind_IsExtendedContext (context) && context->by_value[index])
- + if (_Unwind_IsExtendedContext (context) && context->by_value[column])
- return (_Unwind_Word) (_Unwind_Internal_Ptr) ptr;
-
- /* This will segfault if the register hasn't been saved. */
- @@ -182,6 +186,15 @@
- }
- }
-
- +/* Get the value of register INDEX as saved in CONTEXT. */
- +
- +inline _Unwind_Word
- +_Unwind_GetGR (struct _Unwind_Context *context, int index)
- +{
- + gcc_assert (0 <= index && index < FIRST_PSEUDO_REGISTER + 1);
- + return _Unwind_ByColumn_GetGR (context, DWARF_REG_TO_UNWIND_COLUMN (index));
- +}
- +
- static inline void *
- _Unwind_GetPtr (struct _Unwind_Context *context, int index)
- {
- @@ -198,23 +211,22 @@
-
- /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
-
- -inline void
- -_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
- +static inline void
- +_Unwind_ByColumn_SetGR (struct _Unwind_Context *context, int column, _Unwind_Word val)
- {
- int size;
- void *ptr;
-
- - index = DWARF_REG_TO_UNWIND_COLUMN (index);
- - gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
- - size = dwarf_reg_size_table[index];
- + gcc_assert (0 <= column && column < (int) sizeof(dwarf_reg_size_table));
- + size = dwarf_reg_size_table[column];
-
- - if (_Unwind_IsExtendedContext (context) && context->by_value[index])
- + if (_Unwind_IsExtendedContext (context) && context->by_value[column])
- {
- - context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
- + context->reg[column] = (void *) (_Unwind_Internal_Ptr) val;
- return;
- }
-
- - ptr = context->reg[index];
- + ptr = context->reg[column];
-
- if (size == sizeof(_Unwind_Ptr))
- * (_Unwind_Ptr *) ptr = val;
- @@ -225,15 +237,44 @@
- }
- }
-
- +/* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
- +
- +inline void
- +_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
- +{
- + gcc_assert (0 <= index && index < FIRST_PSEUDO_REGISTER + 1);
- + return _Unwind_ByColumn_SetGR (context, DWARF_REG_TO_UNWIND_COLUMN (index), val);
- +}
- +
- +/* Get the pointer to a register COLUMN as saved in CONTEXT. */
- +
- +static inline void *
- +_Unwind_ByColumn_GetGRPtr (struct _Unwind_Context *context, int column)
- +{
- + gcc_assert (0 <= column && column < DWARF_FRAME_REGISTERS + 1);
- + if (_Unwind_IsExtendedContext (context) && context->by_value[column])
- + return &context->reg[column];
- + return context->reg[column];
- +}
- +
- /* Get the pointer to a register INDEX as saved in CONTEXT. */
-
- static inline void *
- _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
- {
- - index = DWARF_REG_TO_UNWIND_COLUMN (index);
- - if (_Unwind_IsExtendedContext (context) && context->by_value[index])
- - return &context->reg[index];
- - return context->reg[index];
- + gcc_assert (0 <= index && index < FIRST_PSEUDO_REGISTER + 1);
- + return _Unwind_ByColumn_GetGRPtr (context, DWARF_REG_TO_UNWIND_COLUMN (index));
- +}
- +
- +/* Set the pointer to a register COLUMN as saved in CONTEXT. */
- +
- +static inline void
- +_Unwind_ByColumn_SetGRPtr (struct _Unwind_Context *context, int column, void *p)
- +{
- + gcc_assert (0 <= column && column < DWARF_FRAME_REGISTERS + 1);
- + if (_Unwind_IsExtendedContext (context))
- + context->by_value[column] = 0;
- + context->reg[column] = p;
- }
-
- /* Set the pointer to a register INDEX as saved in CONTEXT. */
- @@ -241,24 +282,41 @@
- static inline void
- _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
- {
- - index = DWARF_REG_TO_UNWIND_COLUMN (index);
- - if (_Unwind_IsExtendedContext (context))
- - context->by_value[index] = 0;
- - context->reg[index] = p;
- + gcc_assert (0 <= index && index < FIRST_PSEUDO_REGISTER + 1);
- + _Unwind_ByColumn_SetGRPtr (context, DWARF_REG_TO_UNWIND_COLUMN (index), p);
- }
-
- +/* Overwrite the saved value for register COLUMN in CONTEXT with VAL. */
- +
- +static inline void
- +_Unwind_ByColumn_SetGRValue (struct _Unwind_Context *context, int column,
- + _Unwind_Word val)
- +{
- + gcc_assert (0 <= column && column < (int) sizeof(dwarf_reg_size_table));
- + gcc_assert (dwarf_reg_size_table[column] == sizeof (_Unwind_Ptr));
- +
- + context->by_value[column] = 1;
- + context->reg[column] = (void *) (_Unwind_Internal_Ptr) val;
- +}
- /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
-
- static inline void
- _Unwind_SetGRValue (struct _Unwind_Context *context, int index,
- _Unwind_Word val)
- {
- - index = DWARF_REG_TO_UNWIND_COLUMN (index);
- - gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
- - gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Ptr));
- + gcc_assert (0 <= index && index < FIRST_PSEUDO_REGISTER + 1);
- + _Unwind_ByColumn_SetGRValue (context, DWARF_REG_TO_UNWIND_COLUMN (index), val);
- +}
- +
- +/* Return nonzero if register COLUMN is stored by value rather than
- + by reference. */
- +
- +static inline int
- +_Unwind_ByColumn_GRByValue (struct _Unwind_Context *context, int column)
- +{
-
- - context->by_value[index] = 1;
- - context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
- + gcc_assert (0 <= column && column < DWARF_FRAME_REGISTERS + 1);
- + return context->by_value[column];
- }
-
- /* Return nonzero if register INDEX is stored by value rather than
- @@ -267,8 +325,8 @@
- static inline int
- _Unwind_GRByValue (struct _Unwind_Context *context, int index)
- {
- - index = DWARF_REG_TO_UNWIND_COLUMN (index);
- - return context->by_value[index];
- + gcc_assert (0 <= index && index < FIRST_PSEUDO_REGISTER + 1);
- + return _Unwind_ByColumn_GRByValue (context, DWARF_REG_TO_UNWIND_COLUMN (index));
- }
-
- /* Retrieve the return address for CONTEXT. */
- @@ -1225,8 +1283,12 @@
- _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
- _Unwind_SpTmp *tmp_sp)
- {
- - int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
- -
- + int column = DWARF_REG_TO_UNWIND_COLUMN (__builtin_dwarf_sp_column ());
- + int size;
- +
- + gcc_assert (0 <= column && column < (int)sizeof (dwarf_reg_size_table));
- +
- + size = dwarf_reg_size_table[column];
- if (size == sizeof(_Unwind_Ptr))
- tmp_sp->ptr = (_Unwind_Ptr) cfa;
- else
- @@ -1234,7 +1296,8 @@
- gcc_assert (size == sizeof(_Unwind_Word));
- tmp_sp->word = (_Unwind_Ptr) cfa;
- }
- - _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
- +
- + _Unwind_ByColumn_SetGRPtr (context, column, tmp_sp);
- }
-
- static void
- @@ -1299,19 +1362,19 @@
- break;
-
- case REG_SAVED_OFFSET:
- - _Unwind_SetGRPtr (context, i,
- + _Unwind_ByColumn_SetGRPtr (context, i,
- (void *) (cfa + fs->regs.reg[i].loc.offset));
- break;
-
- case REG_SAVED_REG:
- if (_Unwind_GRByValue (&orig_context, fs->regs.reg[i].loc.reg))
- - _Unwind_SetGRValue (context, i,
- - _Unwind_GetGR (&orig_context,
- - fs->regs.reg[i].loc.reg));
- + _Unwind_ByColumn_SetGRValue (context, i,
- + _Unwind_GetGR (&orig_context,
- + fs->regs.reg[i].loc.reg));
- else
- - _Unwind_SetGRPtr (context, i,
- - _Unwind_GetGRPtr (&orig_context,
- - fs->regs.reg[i].loc.reg));
- + _Unwind_ByColumn_SetGRPtr (context, i,
- + _Unwind_GetGRPtr (&orig_context,
- + fs->regs.reg[i].loc.reg));
- break;
-
- case REG_SAVED_EXP:
- @@ -1323,14 +1386,14 @@
- exp = read_uleb128 (exp, &len);
- val = execute_stack_op (exp, exp + len, &orig_context,
- (_Unwind_Ptr) cfa);
- - _Unwind_SetGRPtr (context, i, (void *) val);
- + _Unwind_ByColumn_SetGRPtr (context, i, (void *) val);
- }
- break;
-
- case REG_SAVED_VAL_OFFSET:
- - _Unwind_SetGRValue (context, i,
- - (_Unwind_Internal_Ptr)
- - (cfa + fs->regs.reg[i].loc.offset));
- + _Unwind_ByColumn_SetGRValue (context, i,
- + (_Unwind_Internal_Ptr)
- + (cfa + fs->regs.reg[i].loc.offset));
- break;
-
- case REG_SAVED_VAL_EXP:
- @@ -1342,7 +1405,7 @@
- exp = read_uleb128 (exp, &len);
- val = execute_stack_op (exp, exp + len, &orig_context,
- (_Unwind_Ptr) cfa);
- - _Unwind_SetGRValue (context, i, val);
- + _Unwind_ByColumn_SetGRValue (context, i, val);
- }
- break;
- }
- diff -Nur gcc-4.2.4.orig/gcc/varasm.c gcc-4.2.4/gcc/varasm.c
- --- gcc-4.2.4.orig/gcc/varasm.c 2008-02-01 19:42:03.000000000 -0600
- +++ gcc-4.2.4/gcc/varasm.c 2015-07-03 18:46:05.741283542 -0500
- @@ -58,6 +58,22 @@
- declarations for e.g. AIX 4.x. */
- #endif
-
- +
- +/* Hooks to allow target specific control over the start/end of each
- + function or variable definition */
- +#ifndef ASSEMBLE_START_FUNCTION
- +#define ASSEMBLE_START_FUNCTION(DECL,FNNAME)
- +#endif
- +#ifndef ASSEMBLE_END_FUNCTION
- +#define ASSEMBLE_END_FUNCTION(DECL,FNNAME)
- +#endif
- +#ifndef ASSEMBLE_START_VARIABLE
- +#define ASSEMBLE_START_VARIABLE(DECL)
- +#endif
- +#ifndef ASSEMBLE_END_VARIABLE
- +#define ASSEMBLE_END_VARIABLE(DECL)
- +#endif
- +
- /* The (assembler) name of the first globally-visible object output. */
- extern GTY(()) const char *first_global_object_name;
- extern GTY(()) const char *weak_global_object_name;
- @@ -649,7 +665,7 @@
-
- /* Return the section to use for string merging. */
-
- -static section *
- +section *
- mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED,
- unsigned int flags ATTRIBUTE_UNUSED)
- @@ -1416,6 +1432,9 @@
-
- in_cold_section_p = first_function_block_is_cold;
-
- + /* Prepare to emit a function */
- + ASSEMBLE_START_FUNCTION (decl, fnname);
- +
- /* Switch to the correct text section for the start of the function. */
-
- switch_to_section (function_section (decl));
- @@ -1508,6 +1527,9 @@
- ASM_OUTPUT_LABEL (asm_out_file, cfun->hot_section_end_label);
- switch_to_section (save_text_section);
- }
- +
- + /* Clean up after outputting a function */
- + ASSEMBLE_END_FUNCTION (decl, fnname);
- }
-
- /* Assemble code to leave SIZE bytes of zeros. */
- @@ -1826,6 +1848,9 @@
- if (sect && (sect->common.flags & SECTION_CODE) != 0)
- DECL_IN_TEXT_SECTION (decl) = 1;
-
- + /* Prepare to output a variable */
- + ASSEMBLE_START_VARIABLE (decl);
- +
- /* If the decl is part of an object_block, make sure that the decl
- has been positioned within its block, but do not write out its
- definition yet. output_object_blocks will do that later. */
- @@ -1843,6 +1868,9 @@
- ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (DECL_ALIGN_UNIT (decl)));
- assemble_variable_contents (decl, name, dont_output_data);
- }
- +
- + /* Clean up after outputting a variable */
- + ASSEMBLE_END_VARIABLE (decl);
- }
-
- /* Return 1 if type TYPE contains any pointers. */
- @@ -5872,10 +5900,9 @@
- else if (DECL_WEAK (exp))
- local_p = false;
- /* If PIC, then assume that any global name can be overridden by
- - symbols resolved from other modules, unless we are compiling with
- - -fwhole-program, which assumes that names are local. */
- + symbols resolved from other modules. */
- else if (shlib)
- - local_p = flag_whole_program;
- + local_p = false;
- /* Uninitialized COMMON variable may be unified with symbols
- resolved from other modules. */
- else if (DECL_COMMON (exp)
- diff -Nur gcc-4.2.4.orig/gcc/var-tracking.c gcc-4.2.4/gcc/var-tracking.c
- --- gcc-4.2.4.orig/gcc/var-tracking.c 2007-11-07 14:48:38.000000000 -0600
- +++ gcc-4.2.4/gcc/var-tracking.c 2015-07-03 18:46:05.741283542 -0500
- @@ -105,6 +105,7 @@
- #include "expr.h"
- #include "timevar.h"
- #include "tree-pass.h"
- +#include "tm_p.h"
-
- /* Type of micro operation. */
- enum micro_operation_type
- diff -Nur gcc-4.2.4.orig/gcc/version.c gcc-4.2.4/gcc/version.c
- --- gcc-4.2.4.orig/gcc/version.c 2005-03-16 00:04:10.000000000 -0600
- +++ gcc-4.2.4/gcc/version.c 2015-07-03 18:46:05.741283542 -0500
- @@ -1,4 +1,5 @@
- #include "version.h"
- +#include "../ccs_version.h"
-
- /* This is the trailing component of the string reported as the
- version number by all components of the compiler. For an official
- @@ -8,7 +9,23 @@
- in parentheses. You may also wish to include a number indicating
- the revision of your modified compiler. */
-
- -#define VERSUFFIX ""
- +#ifndef CCS_BRANCH0_VN
- +#define CCS_BRANCH0_VN 0
- +#endif
- +
- +#ifndef CCS_STEP0_VN
- +#define CCS_STEP0_VN 0
- +#endif
- +
- +#define LIT(S) #S
- +#define STR(N) LIT(N)
- +
- +#define VERSUFFIX " (IMG-" STR (CCS_MAJOR_VN) "." \
- + STR (CCS_MINOR_VN) "." \
- + STR (CCS_RELEASE_VN) "." \
- + STR (CCS_BUILD_VN) \
- + STR (CCS_BRANCH0_VN) \
- + STR (CCS_STEP0_VN) ")"
-
- /* This is the location of the online document giving instructions for
- reporting bugs. If you distribute a modified version of GCC,
- @@ -17,7 +34,7 @@
- forward us bugs reported to you, if you determine that they are
- not bugs in your modifications.) */
-
- -const char bug_report_url[] = "<URL:http://gcc.gnu.org/bugs.html>";
- +const char bug_report_url[] = "toolkit@metagence.com";
-
- /* The complete version string, assembled from several pieces.
- BASEVER, DATESTAMP, and DEVPHASE are defined by the Makefile. */
- diff -Nur gcc-4.2.4.orig/gcc/web.c gcc-4.2.4/gcc/web.c
- --- gcc-4.2.4.orig/gcc/web.c 2007-09-01 10:28:30.000000000 -0500
- +++ gcc-4.2.4/gcc/web.c 2015-07-03 18:46:05.741283542 -0500
- @@ -106,20 +106,20 @@
- {
- rtx insn = DF_REF_INSN (use);
- struct df_link *link = DF_REF_CHAIN (use);
- - struct df_ref *use_link;
- - struct df_ref *def_link;
- + struct df_ref *USE_link;
- + struct df_ref *DEF_link;
- rtx set;
-
- if (insn)
- {
- - use_link = DF_INSN_USES (df, insn);
- - def_link = DF_INSN_DEFS (df, insn);
- + USE_link = DF_INSN_USES (df, insn);
- + DEF_link = DF_INSN_DEFS (df, insn);
- set = single_set (insn);
- }
- else
- {
- - use_link = NULL;
- - def_link = NULL;
- + USE_link = NULL;
- + DEF_link = NULL;
- set = NULL;
- }
-
- @@ -128,14 +128,35 @@
- invalid instructions, so union all uses of the same operand for each
- insn. */
-
- - while (use_link)
- - {
- - if (use != use_link
- - && DF_REF_REAL_REG (use) == DF_REF_REAL_REG (use_link))
- - (*fun) (use_entry + DF_REF_ID (use),
- + /* First handle any uses that are match_dup's of this use ... */
- + {
- + struct df_ref *use_link = USE_link;
- +
- + while (use_link)
- + {
- + if (use != use_link
- + && DF_REF_REAL_REG (use) == DF_REF_REAL_REG (use_link))
- + (*fun) (use_entry + DF_REF_ID (use),
- use_entry + DF_REF_ID (use_link));
- - use_link = use_link->next_ref;
- - }
- +
- + use_link = use_link->next_ref;
- + }
- + }
- +
- + /* then handle any defs that are match_dup's of this use ... */
- + {
- + struct df_ref *def_link = DEF_link;
- +
- + while (def_link)
- + {
- + if (use != def_link
- + && DF_REF_REAL_REG (use) == DF_REF_REAL_REG (def_link))
- + (*fun) (use_entry + DF_REF_ID (use),
- + def_entry + DF_REF_ID (def_link));
- +
- + def_link = def_link->next_ref;
- + }
- + }
-
- /* Recognize trivial noop moves and attempt to keep them as noop.
- While most of noop moves should be removed, we still keep some
- @@ -145,6 +166,8 @@
- && SET_SRC (set) == DF_REF_REG (use)
- && SET_SRC (set) == SET_DEST (set))
- {
- + struct df_ref *def_link = DEF_link;
- +
- while (def_link)
- {
- if (DF_REF_REAL_REG (use) == DF_REF_REAL_REG (def_link))
- @@ -153,6 +176,7 @@
- def_link = def_link->next_ref;
- }
- }
- +
- while (link)
- {
- (*fun) (use_entry + DF_REF_ID (use),
- @@ -236,6 +260,7 @@
- if (dump_file)
- fprintf (dump_file, "Updating insn %i (%i->%i)\n",
- INSN_UID (DF_REF_INSN (ref)), REGNO (oldreg), REGNO (reg));
- +
- *loc = reg;
- }
-
- @@ -273,6 +298,7 @@
- for (i = 0; i < DF_USES_SIZE (df); i++)
- replace_ref (DF_USES_GET (df, i),
- entry_register (use_entry + i, DF_USES_GET (df, i), used));
- +
- for (i = 0; i < DF_DEFS_SIZE (df); i++)
- replace_ref (DF_DEFS_GET (df, i),
- entry_register (def_entry + i, DF_DEFS_GET (df, i), used));
- diff -Nur gcc-4.2.4.orig/libstdc++-v3/configure.host gcc-4.2.4/libstdc++-v3/configure.host
- --- gcc-4.2.4.orig/libstdc++-v3/configure.host 2006-07-14 17:41:43.000000000 -0500
- +++ gcc-4.2.4/libstdc++-v3/configure.host 2015-07-03 18:46:05.789283541 -0500
- @@ -97,6 +97,9 @@
- m680[246]0)
- try_cpu=m68k
- ;;
- + metag*)
- + try_cpu=metag
- + ;;
- powerpc* | rs6000)
- try_cpu=powerpc
- ;;
- @@ -231,6 +234,9 @@
- atomicity_dir=os/irix
- atomic_word_dir=os/irix
- ;;
- + metag*)
- + os_include_dir="os/generic"
- + ;;
- mingw32*)
- os_include_dir="os/mingw32"
- ;;
- @@ -297,6 +303,9 @@
- fi
- esac
- ;;
- + metag*)
- + atomicity_dir="cpu/generic"
- + ;;
- mips*-*-*)
- case "${host_os}" in
- gnu* | linux* | irix*)
- diff -Nur gcc-4.2.4.orig/libstdc++-v3/include/c_std/std_cstring.h gcc-4.2.4/libstdc++-v3/include/c_std/std_cstring.h
- --- gcc-4.2.4.orig/libstdc++-v3/include/c_std/std_cstring.h 2006-12-07 03:33:51.000000000 -0600
- +++ gcc-4.2.4/libstdc++-v3/include/c_std/std_cstring.h 2015-07-03 18:46:05.789283541 -0500
- @@ -75,6 +75,8 @@
- #undef strerror
- #undef strlen
-
- +#undef index
- +
- _GLIBCXX_BEGIN_NAMESPACE(std)
-
- using ::memcpy;
- diff -Nur gcc-4.2.4.orig/libstdc++-v3/include/Makefile.in gcc-4.2.4/libstdc++-v3/include/Makefile.in
- --- gcc-4.2.4.orig/libstdc++-v3/include/Makefile.in 2007-07-05 06:46:00.000000000 -0500
- +++ gcc-4.2.4/libstdc++-v3/include/Makefile.in 2015-07-03 18:46:05.789283541 -0500
- @@ -974,6 +974,7 @@
- ${host_builddir}/gthr.h \
- ${host_builddir}/gthr-single.h \
- ${host_builddir}/gthr-posix.h \
- + ${host_builddir}/gthr-posix95.h \
- ${host_builddir}/gthr-tpf.h \
- ${host_builddir}/gthr-default.h
-
- @@ -1413,6 +1414,14 @@
- -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \
- < ${toplevel_srcdir}/gcc/gthr-posix.h > $@
-
- +${host_builddir}/gthr-posix95.h: ${toplevel_srcdir}/gcc/gthr-posix95.h \
- + stamp-${host_alias}
- + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \
- + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \
- + -e 's/SUPPORTS_WEAK/__GXX_WEAK__/g' \
- + -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \
- + < ${toplevel_srcdir}/gcc/gthr-posix95.h > $@
- +
- ${host_builddir}/gthr-tpf.h: ${toplevel_srcdir}/gcc/gthr-tpf.h \
- stamp-${host_alias}
- sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \
|