600-ubicom_support.patch 297 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368
  1. --- a/configure
  2. +++ b/configure
  3. @@ -3350,6 +3350,9 @@ case "${target}" in
  4. *-*-freebsd*)
  5. noconfigdirs="$noconfigdirs target-newlib target-libgloss"
  6. ;;
  7. + ubicom32-*-*)
  8. + noconfigdirs="$noconfigdirs target-libffi"
  9. + ;;
  10. *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
  11. noconfigdirs="$noconfigdirs target-newlib target-libgloss"
  12. ;;
  13. --- /dev/null
  14. +++ b/gcc/config/ubicom32/constraints.md
  15. @@ -0,0 +1,149 @@
  16. +; Constraint definitions for Ubicom32
  17. +
  18. +; Copyright (C) 2009 Free Software Foundation, Inc.
  19. +; Contributed by Ubicom, Inc.
  20. +
  21. +; This file is part of GCC.
  22. +
  23. +; GCC is free software; you can redistribute it and/or modify it
  24. +; under the terms of the GNU General Public License as published
  25. +; by the Free Software Foundation; either version 3, or (at your
  26. +; option) any later version.
  27. +
  28. +; GCC is distributed in the hope that it will be useful, but WITHOUT
  29. +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  30. +; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  31. +; License for more details.
  32. +
  33. +; You should have received a copy of the GNU General Public License
  34. +; along with GCC; see the file COPYING3. If not see
  35. +; <http://www.gnu.org/licenses/>.
  36. +
  37. +(define_register_constraint "a" "ALL_ADDRESS_REGS"
  38. + "An An register.")
  39. +
  40. +(define_register_constraint "d" "DATA_REGS"
  41. + "A Dn register.")
  42. +
  43. +(define_register_constraint "h" "ACC_REGS"
  44. + "An accumulator register.")
  45. +
  46. +(define_register_constraint "l" "ACC_LO_REGS"
  47. + "An accn_lo register.")
  48. +
  49. +(define_register_constraint "Z" "FDPIC_REG"
  50. + "The FD-PIC GOT pointer: A0.")
  51. +
  52. +(define_constraint "I"
  53. + "An 8-bit signed constant value."
  54. + (and (match_code "const_int")
  55. + (match_test "(ival >= -128) && (ival <= 127)")))
  56. +
  57. +(define_constraint "Q"
  58. + "An 8-bit signed constant value represented as unsigned."
  59. + (and (match_code "const_int")
  60. + (match_test "(ival >= 0x00) && (ival <= 0xff)")))
  61. +
  62. +(define_constraint "R"
  63. + "An 8-bit signed constant value represented as unsigned."
  64. + (and (match_code "const_int")
  65. + (match_test "((ival >= 0x0000) && (ival <= 0x007f)) || ((ival >= 0xff80) && (ival <= 0xffff))")))
  66. +
  67. +(define_constraint "J"
  68. + "A 7-bit unsigned constant value."
  69. + (and (match_code "const_int")
  70. + (match_test "(ival >= 0) && (ival <= 127)")))
  71. +
  72. +(define_constraint "K"
  73. + "A 7-bit unsigned constant value shifted << 1."
  74. + (and (match_code "const_int")
  75. + (match_test "(ival >= 0) && (ival <= 254) && ((ival & 1) == 0)")))
  76. +
  77. +(define_constraint "L"
  78. + "A 7-bit unsigned constant value shifted << 2."
  79. + (and (match_code "const_int")
  80. + (match_test "(ival >= 0) && (ival <= 508) && ((ival & 3) == 0)")))
  81. +
  82. +(define_constraint "M"
  83. + "A 5-bit unsigned constant value."
  84. + (and (match_code "const_int")
  85. + (match_test "(ival >= 0) && (ival <= 31)")))
  86. +
  87. +(define_constraint "N"
  88. + "A signed 16 bit constant value."
  89. + (and (match_code "const_int")
  90. + (match_test "(ival >= -32768) && (ival <= 32767)")))
  91. +
  92. +(define_constraint "O"
  93. + "An exact bitmask of contiguous 1 bits starting at bit 0."
  94. + (and (match_code "const_int")
  95. + (match_test "exact_log2 (ival + 1) != -1")))
  96. +
  97. +(define_constraint "P"
  98. + "A 7-bit negative constant value shifted << 2."
  99. + (and (match_code "const_int")
  100. + (match_test "(ival >= -504) && (ival <= 0) && ((ival & 3) == 0)")))
  101. +
  102. +(define_constraint "S"
  103. + "A symbolic reference."
  104. + (match_code "symbol_ref"))
  105. +
  106. +(define_constraint "Y"
  107. + "An FD-PIC symbolic reference."
  108. + (and (match_test "TARGET_FDPIC")
  109. + (match_test "GET_CODE (op) == UNSPEC")
  110. + (ior (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT")
  111. + (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT_FUNCDESC"))))
  112. +
  113. +(define_memory_constraint "T1"
  114. + "A memory operand that can be used for .1 instruction."
  115. + (and (match_test "memory_operand (op, GET_MODE(op))")
  116. + (match_test "GET_MODE (op) == QImode")))
  117. +
  118. +(define_memory_constraint "T2"
  119. + "A memory operand that can be used for .2 instruction."
  120. + (and (match_test "memory_operand (op, GET_MODE(op))")
  121. + (match_test "GET_MODE (op) == HImode")))
  122. +
  123. +(define_memory_constraint "T4"
  124. + "A memory operand that can be used for .4 instruction."
  125. + (and (match_test "memory_operand (op, GET_MODE(op))")
  126. + (ior (match_test "GET_MODE (op) == SImode")
  127. + (match_test "GET_MODE (op) == DImode")
  128. + (match_test "GET_MODE (op) == SFmode"))))
  129. +
  130. +(define_memory_constraint "U1"
  131. + "An offsettable memory operand that can be used for .1 instruction."
  132. + (and (match_test "memory_operand (op, GET_MODE(op))")
  133. + (match_test "GET_MODE (op) == QImode")
  134. + (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
  135. + (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
  136. + (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
  137. + (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
  138. + (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
  139. + (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
  140. +
  141. +(define_memory_constraint "U2"
  142. + "An offsettable memory operand that can be used for .2 instruction."
  143. + (and (match_test "memory_operand (op, GET_MODE(op))")
  144. + (match_test "GET_MODE (op) == HImode")
  145. + (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
  146. + (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
  147. + (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
  148. + (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
  149. + (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
  150. + (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
  151. +
  152. +(define_memory_constraint "U4"
  153. + "An offsettable memory operand that can be used for .4 instruction."
  154. + (and (match_test "memory_operand (op, GET_MODE(op))")
  155. + (ior (match_test "GET_MODE (op) == SImode")
  156. + (match_test "GET_MODE (op) == DImode")
  157. + (match_test "GET_MODE (op) == SFmode"))
  158. + (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
  159. + (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
  160. + (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
  161. + (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
  162. + (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
  163. + (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
  164. +
  165. --- /dev/null
  166. +++ b/gcc/config/ubicom32/crti.S
  167. @@ -0,0 +1,54 @@
  168. +/* Specialized code needed to support construction and destruction of
  169. + file-scope objects in C++ and Java code, and to support exception handling.
  170. + Copyright (C) 1999 Free Software Foundation, Inc.
  171. + Contributed by Charles-Antoine Gauthier ([email protected]).
  172. +
  173. +This file is part of GCC.
  174. +
  175. +GCC is free software; you can redistribute it and/or modify
  176. +it under the terms of the GNU General Public License as published by
  177. +the Free Software Foundation; either version 2, or (at your option)
  178. +any later version.
  179. +
  180. +GCC is distributed in the hope that it will be useful,
  181. +but WITHOUT ANY WARRANTY; without even the implied warranty of
  182. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  183. +GNU General Public License for more details.
  184. +
  185. +You should have received a copy of the GNU General Public License
  186. +along with GCC; see the file COPYING. If not, write to
  187. +the Free Software Foundation, 59 Temple Place - Suite 330,
  188. +Boston, MA 02111-1307, USA. */
  189. +
  190. +/* As a special exception, if you link this library with files
  191. + compiled with GCC to produce an executable, this does not cause
  192. + the resulting executable to be covered by the GNU General Public License.
  193. + This exception does not however invalidate any other reasons why
  194. + the executable file might be covered by the GNU General Public License. */
  195. +
  196. +/*
  197. + * This file just supplies function prologues for the .init and .fini
  198. + * sections. It is linked in before crtbegin.o.
  199. + */
  200. + .file "crti.o"
  201. + .ident "GNU C crti.o"
  202. +
  203. + .section .init
  204. + .align 2
  205. + .globl _init
  206. + .type _init, @function
  207. +_init:
  208. + move.4 -4(sp)++, a5
  209. +#ifdef __UBICOM32_FDPIC__
  210. + move.4 -4(sp)++, a0
  211. +#endif
  212. +
  213. + .section .fini
  214. + .align 2
  215. + .globl _fini
  216. + .type _fini, @function
  217. +_fini:
  218. + move.4 -4(sp)++, a5
  219. +#ifdef __UBICOM32_FDPIC__
  220. + move.4 -4(sp)++, a0
  221. +#endif
  222. --- /dev/null
  223. +++ b/gcc/config/ubicom32/crtn.S
  224. @@ -0,0 +1,47 @@
  225. +/* Specialized code needed to support construction and destruction of
  226. + file-scope objects in C++ and Java code, and to support exception handling.
  227. + Copyright (C) 1999 Free Software Foundation, Inc.
  228. + Contributed by Charles-Antoine Gauthier ([email protected]).
  229. +
  230. +This file is part of GCC.
  231. +
  232. +GCC is free software; you can redistribute it and/or modify
  233. +it under the terms of the GNU General Public License as published by
  234. +the Free Software Foundation; either version 2, or (at your option)
  235. +any later version.
  236. +
  237. +GCC is distributed in the hope that it will be useful,
  238. +but WITHOUT ANY WARRANTY; without even the implied warranty of
  239. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  240. +GNU General Public License for more details.
  241. +
  242. +You should have received a copy of the GNU General Public License
  243. +along with GCC; see the file COPYING. If not, write to
  244. +the Free Software Foundation, 59 Temple Place - Suite 330,
  245. +Boston, MA 02111-1307, USA. */
  246. +
  247. +/* As a special exception, if you link this library with files
  248. + compiled with GCC to produce an executable, this does not cause
  249. + the resulting executable to be covered by the GNU General Public License.
  250. + This exception does not however invalidate any other reasons why
  251. + the executable file might be covered by the GNU General Public License. */
  252. +
  253. +/*
  254. + * This file supplies function epilogues for the .init and .fini sections.
  255. + * It is linked in after all other files.
  256. + */
  257. +
  258. + .file "crtn.o"
  259. + .ident "GNU C crtn.o"
  260. +
  261. + .section .init
  262. +#ifdef __UBICOM32_FDPIC__
  263. + move.4 a0, (sp)4++
  264. +#endif
  265. + ret (sp)4++
  266. +
  267. + .section .fini
  268. +#ifdef __UBICOM32_FDPIC__
  269. + move.4 a0, (sp)4++
  270. +#endif
  271. + ret (sp)4++
  272. --- /dev/null
  273. +++ b/gcc/config/ubicom32/elf.h
  274. @@ -0,0 +1,29 @@
  275. +#undef STARTFILE_SPEC
  276. +#define STARTFILE_SPEC "\
  277. +%{msim:%{!shared:crt0%O%s}} \
  278. +crti%O%s crtbegin%O%s"
  279. +
  280. +#undef ENDFILE_SPEC
  281. +#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
  282. +
  283. +#ifdef __UBICOM32_FDPIC__
  284. +#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
  285. + asm (SECTION_OP); \
  286. + asm ("move.4 a0, 0(sp);\n\t" \
  287. + "call a5," USER_LABEL_PREFIX #FUNC ";"); \
  288. + asm (TEXT_SECTION_ASM_OP);
  289. +#endif
  290. +
  291. +#undef SUBTARGET_DRIVER_SELF_SPECS
  292. +#define SUBTARGET_DRIVER_SELF_SPECS \
  293. + "%{mfdpic:-msim} "
  294. +
  295. +#define NO_IMPLICIT_EXTERN_C
  296. +
  297. +/*
  298. + * We need this to compile crtbegin/crtend. This should really be picked
  299. + * up from elfos.h but at the moment including elfos.h causes other more
  300. + * serous linker issues.
  301. + */
  302. +#define INIT_SECTION_ASM_OP "\t.section\t.init"
  303. +#define FINI_SECTION_ASM_OP "\t.section\t.fini"
  304. --- /dev/null
  305. +++ b/gcc/config/ubicom32/linux.h
  306. @@ -0,0 +1,80 @@
  307. +/* Definitions of target machine for Ubicom32-uclinux
  308. +
  309. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
  310. + 2009 Free Software Foundation, Inc.
  311. + Contributed by Ubicom, Inc.
  312. +
  313. + This file is part of GCC.
  314. +
  315. + GCC is free software; you can redistribute it and/or modify it
  316. + under the terms of the GNU General Public License as published
  317. + by the Free Software Foundation; either version 3, or (at your
  318. + option) any later version.
  319. +
  320. + GCC is distributed in the hope that it will be useful, but WITHOUT
  321. + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  322. + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  323. + License for more details.
  324. +
  325. + You should have received a copy of the GNU General Public License
  326. + along with GCC; see the file COPYING3. If not see
  327. + <http://www.gnu.org/licenses/>. */
  328. +
  329. +/* Don't assume anything about the header files. */
  330. +#define NO_IMPLICIT_EXTERN_C
  331. +
  332. +#undef LIB_SPEC
  333. +#define LIB_SPEC \
  334. + "%{pthread:-lpthread} " \
  335. + "-lc"
  336. +
  337. +#undef LINK_GCC_C_SEQUENCE_SPEC
  338. +#define LINK_GCC_C_SEQUENCE_SPEC \
  339. + "%{static:--start-group} %G %L %{static:--end-group} " \
  340. + "%{!static: %G}"
  341. +
  342. +#undef STARTFILE_SPEC
  343. +#define STARTFILE_SPEC \
  344. + "%{!shared: %{pg|p|profile:gcrt1%O%s;pie:Scrt1%O%s;:crt1%O%s}} " \
  345. + "crtreloc%O%s crti%O%s %{shared|pie:crtbeginS%O%s;:crtbegin%O%s}"
  346. +
  347. +#undef ENDFILE_SPEC
  348. +#define ENDFILE_SPEC \
  349. + "%{shared|pie:crtendS%O%s;:crtend%O%s} crtn%O%s"
  350. +
  351. +/* taken from linux.h */
  352. +/* The GNU C++ standard library requires that these macros be defined. */
  353. +#undef CPLUSPLUS_CPP_SPEC
  354. +#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
  355. +
  356. +#define TARGET_OS_CPP_BUILTINS() \
  357. + do { \
  358. + builtin_define_std ("__UBICOM32__"); \
  359. + builtin_define_std ("__ubicom32__"); \
  360. + builtin_define ("__gnu_linux__"); \
  361. + builtin_define_std ("linux"); \
  362. + builtin_define_std ("unix"); \
  363. + builtin_assert ("system=linux"); \
  364. + builtin_assert ("system=unix"); \
  365. + builtin_assert ("system=posix"); \
  366. + } while (0)
  367. +
  368. +#define OBJECT_FORMAT_ELF
  369. +
  370. +
  371. +#undef DRIVER_SELF_SPECS
  372. +#define DRIVER_SELF_SPECS \
  373. + "%{!mno-fdpic:-mfdpic}"
  374. +
  375. +#undef LINK_SPEC
  376. +#define LINK_SPEC "%{mfdpic: -m elf32ubicom32fdpic -z text } %{shared} %{pie} \
  377. + %{static:-dn -Bstatic} \
  378. + %{shared:-G -Bdynamic} \
  379. + %{!shared: %{!static: \
  380. + %{rdynamic:-export-dynamic} \
  381. + %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}} \
  382. + %{static}} "
  383. +
  384. +/*
  385. +#define MD_UNWIND_SUPPORT "config/bfin/linux-unwind.h"
  386. +*/
  387. --- /dev/null
  388. +++ b/gcc/config/ubicom32/predicates.md
  389. @@ -0,0 +1,327 @@
  390. +; Predicate definitions for Ubicom32.
  391. +
  392. +; Copyright (C) 2009 Free Software Foundation, Inc.
  393. +; Contributed by Ubicom, Inc.
  394. +
  395. +; This file is part of GCC.
  396. +
  397. +; GCC is free software; you can redistribute it and/or modify it
  398. +; under the terms of the GNU General Public License as published
  399. +; by the Free Software Foundation; either version 3, or (at your
  400. +; option) any later version.
  401. +
  402. +; GCC is distributed in the hope that it will be useful, but WITHOUT
  403. +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  404. +; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  405. +; License for more details.
  406. +
  407. +; You should have received a copy of the GNU General Public License
  408. +; along with GCC; see the file COPYING3. If not see
  409. +; <http://www.gnu.org/licenses/>.
  410. +
  411. +(define_predicate "ubicom32_move_operand"
  412. + (match_code "const_int, const_double, const, mem, subreg, reg, lo_sum")
  413. +{
  414. + if (CONST_INT_P (op))
  415. + return true;
  416. +
  417. + if (GET_CODE (op) == CONST_DOUBLE)
  418. + return true;
  419. +
  420. + if (GET_CODE (op) == CONST)
  421. + return memory_address_p (mode, op);
  422. +
  423. + if (GET_MODE (op) != mode)
  424. + return false;
  425. +
  426. + if (MEM_P (op))
  427. + return memory_address_p (mode, XEXP (op, 0));
  428. +
  429. + if (GET_CODE (op) == SUBREG) {
  430. + op = SUBREG_REG (op);
  431. +
  432. + if (REG_P (op))
  433. + return true;
  434. +
  435. + if (! MEM_P (op))
  436. + return false;
  437. +
  438. + /* Paradoxical SUBREG. */
  439. + if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (op)))
  440. + return false;
  441. +
  442. + return memory_address_p (GET_MODE (op), XEXP (op, 0));
  443. + }
  444. +
  445. + return register_operand (op, mode);
  446. +})
  447. +
  448. +;; Returns true if OP is either a symbol reference or a sum of a
  449. +;; symbol reference and a constant.
  450. +
  451. +(define_predicate "ubicom32_symbolic_address_operand"
  452. + (match_code "symbol_ref, label_ref, const")
  453. +{
  454. + switch (GET_CODE (op))
  455. + {
  456. + case SYMBOL_REF:
  457. + case LABEL_REF:
  458. + return true;
  459. +
  460. + case CONST:
  461. + op = XEXP (op, 0);
  462. + return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
  463. + || GET_CODE (XEXP (op, 0)) == LABEL_REF)
  464. + && CONST_INT_P (XEXP (op, 1)));
  465. +
  466. + default:
  467. + return false;
  468. + }
  469. +})
  470. +
  471. +;; Return true if operand is the uClinux FD-PIC register.
  472. +
  473. +(define_predicate "ubicom32_fdpic_operand"
  474. + (match_code "reg")
  475. +{
  476. + if (! TARGET_FDPIC)
  477. + return false;
  478. +
  479. + if (!REG_P (op))
  480. + return false;
  481. +
  482. + if (GET_MODE (op) != mode && mode != VOIDmode)
  483. + return false;
  484. +
  485. + if (REGNO (op) != FDPIC_REGNUM && REGNO (op) < FIRST_PSEUDO_REGISTER)
  486. + return false;
  487. +
  488. + return true;
  489. +})
  490. +
  491. +(define_predicate "ubicom32_fdpic_got_offset_operand"
  492. + (match_code "unspec")
  493. +{
  494. + if (! TARGET_FDPIC)
  495. + return false;
  496. +
  497. + if (GET_CODE (op) != UNSPEC)
  498. + return false;
  499. +
  500. + if (XINT (op, 1) != UNSPEC_FDPIC_GOT
  501. + && XINT (op, 1) != UNSPEC_FDPIC_GOT_FUNCDESC)
  502. + return false;
  503. +
  504. + return true;
  505. +})
  506. +
  507. +(define_predicate "ubicom32_arith_operand"
  508. + (match_code "subreg, reg, const_int, lo_sum, mem")
  509. +{
  510. + return (ubicom32_move_operand (op, mode)
  511. + && ! ubicom32_symbolic_address_operand (op, mode)
  512. + && (! CONST_INT_P (op)
  513. + || satisfies_constraint_I (op)));
  514. +})
  515. +
  516. +(define_predicate "ubicom32_arith_operand_dot1"
  517. + (match_code "subreg, reg, const_int, lo_sum, mem")
  518. +{
  519. + return (ubicom32_move_operand (op, mode)
  520. + && ! ubicom32_symbolic_address_operand (op, mode)
  521. + && (! CONST_INT_P (op)
  522. + || satisfies_constraint_Q (op)));
  523. +})
  524. +
  525. +(define_predicate "ubicom32_arith_operand_dot2"
  526. + (match_code "subreg, reg, const_int, lo_sum, mem")
  527. +{
  528. + return (ubicom32_move_operand (op, mode)
  529. + && ! ubicom32_symbolic_address_operand (op, mode)
  530. + && (! CONST_INT_P (op)
  531. + || satisfies_constraint_R (op)));
  532. +})
  533. +
  534. +(define_predicate "ubicom32_compare_operand"
  535. + (match_code "subreg, reg, const_int, lo_sum, mem")
  536. +{
  537. + return (ubicom32_move_operand (op, mode)
  538. + && ! ubicom32_symbolic_address_operand (op, mode)
  539. + && (! CONST_INT_P (op)
  540. + || satisfies_constraint_N (op)));
  541. +})
  542. +
  543. +(define_predicate "ubicom32_compare_operator"
  544. + (match_code "compare"))
  545. +
  546. +(define_predicate "ubicom32_and_or_si3_operand"
  547. + (match_code "subreg, reg, const_int, lo_sum, mem")
  548. +{
  549. + return (ubicom32_arith_operand (op, mode)
  550. + || (CONST_INT_P (op)
  551. + && ((exact_log2 (INTVAL (op) + 1) != -1
  552. + && exact_log2 (INTVAL (op) + 1) <= 31)
  553. + || (exact_log2 (INTVAL (op)) != -1
  554. + && exact_log2 (INTVAL (op)) <= 31)
  555. + || (exact_log2 (~INTVAL (op)) != -1
  556. + && exact_log2 (~INTVAL (op)) <= 31))));
  557. +})
  558. +
  559. +(define_predicate "ubicom32_and_or_hi3_operand"
  560. + (match_code "subreg, reg, const_int, lo_sum, mem")
  561. +{
  562. + return (ubicom32_arith_operand (op, mode)
  563. + || (CONST_INT_P (op)
  564. + && exact_log2 (INTVAL (op) + 1) != -1
  565. + && exact_log2 (INTVAL (op) + 1) <= 15));
  566. +})
  567. +
  568. +(define_predicate "ubicom32_mem_or_address_register_operand"
  569. + (match_code "subreg, reg, mem")
  570. +{
  571. + unsigned int regno;
  572. +
  573. + if (MEM_P (op)
  574. + && memory_operand (op, mode))
  575. + return true;
  576. +
  577. + if (REG_P (op))
  578. + regno = REGNO (op);
  579. + else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
  580. + {
  581. + int offset;
  582. + if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
  583. + offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
  584. + else
  585. + offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
  586. + GET_MODE (SUBREG_REG (op)),
  587. + SUBREG_BYTE (op),
  588. + GET_MODE (op));
  589. + regno = REGNO (SUBREG_REG (op)) + offset;
  590. + }
  591. + else
  592. + return false;
  593. +
  594. + return (regno >= FIRST_PSEUDO_REGISTER
  595. + || REGNO_REG_CLASS (regno) == FDPIC_REG
  596. + || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
  597. +})
  598. +
  599. +(define_predicate "ubicom32_data_register_operand"
  600. + (match_code "subreg, reg")
  601. +{
  602. + unsigned int regno;
  603. +
  604. + if (REG_P (op))
  605. + regno = REGNO (op);
  606. + else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
  607. + {
  608. + int offset;
  609. + if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
  610. + offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
  611. + else
  612. + offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
  613. + GET_MODE (SUBREG_REG (op)),
  614. + SUBREG_BYTE (op),
  615. + GET_MODE (op));
  616. + regno = REGNO (SUBREG_REG (op)) + offset;
  617. + }
  618. + else
  619. + return false;
  620. +
  621. + return ((regno >= FIRST_PSEUDO_REGISTER
  622. + && regno != REGNO (virtual_stack_vars_rtx))
  623. + || REGNO_REG_CLASS (regno) == DATA_REGS);
  624. +})
  625. +
  626. +(define_predicate "ubicom32_address_register_operand"
  627. + (match_code "subreg, reg")
  628. +{
  629. + unsigned int regno;
  630. +
  631. + if (REG_P (op))
  632. + regno = REGNO (op);
  633. + else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
  634. + {
  635. + int offset;
  636. + if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
  637. + offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
  638. + else
  639. + offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
  640. + GET_MODE (SUBREG_REG (op)),
  641. + SUBREG_BYTE (op),
  642. + GET_MODE (op));
  643. + regno = REGNO (SUBREG_REG (op)) + offset;
  644. + }
  645. + else
  646. + return false;
  647. +
  648. + return (regno >= FIRST_PSEUDO_REGISTER
  649. + || REGNO_REG_CLASS (regno) == FDPIC_REG
  650. + || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
  651. +})
  652. +
  653. +(define_predicate "ubicom32_acc_lo_register_operand"
  654. + (match_code "subreg, reg")
  655. +{
  656. + unsigned int regno;
  657. +
  658. + if (REG_P (op))
  659. + regno = REGNO (op);
  660. + else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
  661. + {
  662. + int offset;
  663. + if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
  664. + offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
  665. + else
  666. + offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
  667. + GET_MODE (SUBREG_REG (op)),
  668. + SUBREG_BYTE (op),
  669. + GET_MODE (op));
  670. + regno = REGNO (SUBREG_REG (op)) + offset;
  671. + }
  672. + else
  673. + return false;
  674. +
  675. + return ((regno >= FIRST_PSEUDO_REGISTER
  676. + && regno != REGNO (virtual_stack_vars_rtx))
  677. + || REGNO_REG_CLASS (regno) == ACC_LO_REGS);
  678. +})
  679. +
  680. +(define_predicate "ubicom32_acc_hi_register_operand"
  681. + (match_code "subreg, reg")
  682. +{
  683. + unsigned int regno;
  684. +
  685. + if (REG_P (op))
  686. + regno = REGNO (op);
  687. + else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
  688. + {
  689. + int offset;
  690. + if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
  691. + offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
  692. + else
  693. + offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
  694. + GET_MODE (SUBREG_REG (op)),
  695. + SUBREG_BYTE (op),
  696. + GET_MODE (op));
  697. + regno = REGNO (SUBREG_REG (op)) + offset;
  698. + }
  699. + else
  700. + return false;
  701. +
  702. + return ((regno >= FIRST_PSEUDO_REGISTER
  703. + && regno != REGNO (virtual_stack_vars_rtx))
  704. + || REGNO_REG_CLASS (regno) == ACC_REGS);
  705. +})
  706. +
  707. +(define_predicate "ubicom32_call_address_operand"
  708. + (match_code "symbol_ref, subreg, reg")
  709. +{
  710. + return (GET_CODE (op) == SYMBOL_REF || REG_P (op));
  711. +})
  712. +
  713. +(define_special_predicate "ubicom32_cc_register_operand"
  714. + (and (match_code "reg")
  715. + (match_test "REGNO (op) == CC_REGNUM")))
  716. +
  717. --- /dev/null
  718. +++ b/gcc/config/ubicom32/t-ubicom32
  719. @@ -0,0 +1,52 @@
  720. +# Name of assembly file containing libgcc1 functions.
  721. +# This entry must be present, but it can be empty if the target does
  722. +# not need any assembler functions to support its code generation.
  723. +CROSS_LIBGCC1 =
  724. +
  725. +# Alternatively if assembler functions *are* needed then define the
  726. +# entries below:
  727. +# CROSS_LIBGCC1 = libgcc1-asm.a
  728. +
  729. +LIB2FUNCS_EXTRA = \
  730. + $(srcdir)/config/udivmodsi4.c \
  731. + $(srcdir)/config/divmod.c \
  732. + $(srcdir)/config/udivmod.c
  733. +
  734. +# If any special flags are necessary when building libgcc2 put them here.
  735. +#
  736. +# TARGET_LIBGCC2_CFLAGS =
  737. +
  738. +# We want fine grained libraries, so use the new code to build the
  739. +# floating point emulation libraries.
  740. +FPBIT = fp-bit.c
  741. +DPBIT = dp-bit.c
  742. +
  743. +fp-bit.c: $(srcdir)/config/fp-bit.c
  744. + echo '#define FLOAT' > fp-bit.c
  745. + cat $(srcdir)/config/fp-bit.c >> fp-bit.c
  746. +
  747. +dp-bit.c: $(srcdir)/config/fp-bit.c
  748. + cat $(srcdir)/config/fp-bit.c > dp-bit.c
  749. +
  750. +# Commented out to speed up compiler development!
  751. +#
  752. +# MULTILIB_OPTIONS = march=ubicom32v1/march=ubicom32v2/march=ubicom32v3/march=ubicom32v4
  753. +# MULTILIB_DIRNAMES = ubicom32v1 ubicom32v2 ubicom32v3 ubicom32v4
  754. +
  755. +MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
  756. +MULTILIB_OPTIONS += mfdpic
  757. +MULTILIB_OPTIONS += mno-ipos-abi/mipos-abi
  758. +MULTILIB_OPTIONS += fno-leading-underscore/fleading-underscore
  759. +
  760. +# Assemble startup files.
  761. +$(T)crti.o: $(srcdir)/config/ubicom32/crti.S $(GCC_PASSES)
  762. + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
  763. + -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crti.S
  764. +
  765. +$(T)crtn.o: $(srcdir)/config/ubicom32/crtn.S $(GCC_PASSES)
  766. + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
  767. + -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crtn.S
  768. +
  769. +# these parts are required because uClibc ldso needs them to link.
  770. +# they are not in the specfile so they will not be included automatically.
  771. +EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crti.o crtn.o
  772. --- /dev/null
  773. +++ b/gcc/config/ubicom32/t-ubicom32-linux
  774. @@ -0,0 +1,35 @@
  775. +# Name of assembly file containing libgcc1 functions.
  776. +# This entry must be present, but it can be empty if the target does
  777. +# not need any assembler functions to support its code generation.
  778. +CROSS_LIBGCC1 =
  779. +
  780. +# Alternatively if assembler functions *are* needed then define the
  781. +# entries below:
  782. +# CROSS_LIBGCC1 = libgcc1-asm.a
  783. +
  784. +LIB2FUNCS_EXTRA = \
  785. + $(srcdir)/config/udivmodsi4.c \
  786. + $(srcdir)/config/divmod.c \
  787. + $(srcdir)/config/udivmod.c
  788. +
  789. +# If any special flags are necessary when building libgcc2 put them here.
  790. +#
  791. +# TARGET_LIBGCC2_CFLAGS =
  792. +
  793. +# We want fine grained libraries, so use the new code to build the
  794. +# floating point emulation libraries.
  795. +FPBIT = fp-bit.c
  796. +DPBIT = dp-bit.c
  797. +
  798. +fp-bit.c: $(srcdir)/config/fp-bit.c
  799. + echo '#define FLOAT' > fp-bit.c
  800. + cat $(srcdir)/config/fp-bit.c >> fp-bit.c
  801. +
  802. +dp-bit.c: $(srcdir)/config/fp-bit.c
  803. + cat $(srcdir)/config/fp-bit.c > dp-bit.c
  804. +
  805. +# We only support v3 and v4 ISAs for uClinux.
  806. +
  807. +MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
  808. +
  809. +#EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o
  810. --- /dev/null
  811. +++ b/gcc/config/ubicom32/t-ubicom32-uclinux
  812. @@ -0,0 +1,35 @@
  813. +# Name of assembly file containing libgcc1 functions.
  814. +# This entry must be present, but it can be empty if the target does
  815. +# not need any assembler functions to support its code generation.
  816. +CROSS_LIBGCC1 =
  817. +
  818. +# Alternatively if assembler functions *are* needed then define the
  819. +# entries below:
  820. +# CROSS_LIBGCC1 = libgcc1-asm.a
  821. +
  822. +LIB2FUNCS_EXTRA = \
  823. + $(srcdir)/config/udivmodsi4.c \
  824. + $(srcdir)/config/divmod.c \
  825. + $(srcdir)/config/udivmod.c
  826. +
  827. +# If any special flags are necessary when building libgcc2 put them here.
  828. +#
  829. +# TARGET_LIBGCC2_CFLAGS =
  830. +
  831. +# We want fine grained libraries, so use the new code to build the
  832. +# floating point emulation libraries.
  833. +FPBIT = fp-bit.c
  834. +DPBIT = dp-bit.c
  835. +
  836. +fp-bit.c: $(srcdir)/config/fp-bit.c
  837. + echo '#define FLOAT' > fp-bit.c
  838. + cat $(srcdir)/config/fp-bit.c >> fp-bit.c
  839. +
  840. +dp-bit.c: $(srcdir)/config/fp-bit.c
  841. + cat $(srcdir)/config/fp-bit.c > dp-bit.c
  842. +
  843. +# We only support v3 and v4 ISAs for uClinux.
  844. +
  845. +MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
  846. +
  847. +EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o # crtbeginS.o crtendS.o
  848. --- /dev/null
  849. +++ b/gcc/config/ubicom32/ubicom32-modes.def
  850. @@ -0,0 +1,30 @@
  851. +/* Definitions of target machine for GNU compiler, Ubicom32 architecture.
  852. + Copyright (C) 2009 Free Software Foundation, Inc.
  853. + Contributed by Ubicom, Inc.
  854. +
  855. + This file is part of GCC.
  856. +
  857. + GCC is free software; you can redistribute it and/or modify it
  858. + under the terms of the GNU General Public License as published
  859. + by the Free Software Foundation; either version 3, or (at your
  860. + option) any later version.
  861. +
  862. + GCC is distributed in the hope that it will be useful, but WITHOUT
  863. + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  864. + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  865. + License for more details.
  866. +
  867. + You should have received a copy of the GNU General Public License
  868. + along with GCC; see the file COPYING3. If not see
  869. + <http://www.gnu.org/licenses/>. */
  870. +
  871. +/* Some insns set all condition code flags, some only set the Z and N flags, and
  872. + some only set the Z flag. */
  873. +
  874. +CC_MODE (CCW);
  875. +CC_MODE (CCWZN);
  876. +CC_MODE (CCWZ);
  877. +CC_MODE (CCS);
  878. +CC_MODE (CCSZN);
  879. +CC_MODE (CCSZ);
  880. +
  881. --- /dev/null
  882. +++ b/gcc/config/ubicom32/ubicom32-protos.h
  883. @@ -0,0 +1,84 @@
  884. +/* Function prototypes for Ubicom IP3000.
  885. +
  886. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
  887. + 2009 Free Software Foundation, Inc.
  888. + Contributed by Ubicom, Inc.
  889. +
  890. + This file is part of GNU CC.
  891. +
  892. + GNU CC is free software; you can redistribute it and/or modify it under
  893. + the terms of the GNU General Public License as published by the Free
  894. + Software Foundation; either version 2, or (at your option) any later
  895. + version.
  896. +
  897. + GNU CC is distributed in the hope that it will be useful, but WITHOUT
  898. + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  899. + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  900. + for more details.
  901. +
  902. + You should have received a copy of the GNU General Public License along
  903. + with GNU CC; see the file COPYING. If not, write to the Free Software
  904. + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  905. +
  906. +#ifdef RTX_CODE
  907. +
  908. +#ifdef TREE_CODE
  909. +extern void ubicom32_va_start (tree, rtx);
  910. +#endif /* TREE_CODE */
  911. +
  912. +extern void ubicom32_print_operand (FILE *, rtx, int);
  913. +extern void ubicom32_print_operand_address (FILE *, rtx);
  914. +
  915. +extern void ubicom32_conditional_register_usage (void);
  916. +extern enum reg_class ubicom32_preferred_reload_class (rtx, enum reg_class);
  917. +extern int ubicom32_regno_ok_for_index_p (int, int);
  918. +extern void ubicom32_expand_movsi (rtx *);
  919. +extern void ubicom32_expand_addsi3 (rtx *);
  920. +extern int ubicom32_emit_mult_sequence (rtx *);
  921. +extern void ubicom32_emit_move_const_int (rtx, rtx);
  922. +extern bool ubicom32_legitimate_constant_p (rtx);
  923. +extern bool ubicom32_legitimate_address_p (enum machine_mode, rtx, int);
  924. +extern rtx ubicom32_legitimize_address (rtx, rtx, enum machine_mode);
  925. +extern rtx ubicom32_legitimize_reload_address (rtx, enum machine_mode, int, int);
  926. +extern void ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1);
  927. +extern int ubicom32_mode_dependent_address_p (rtx);
  928. +extern void ubicom32_output_cond_jump (rtx, rtx, rtx);
  929. +extern void ubicom32_expand_eh_return (rtx *);
  930. +extern void ubicom32_expand_call_fdpic (rtx *);
  931. +extern void ubicom32_expand_call_value_fdpic (rtx *);
  932. +extern enum machine_mode ubicom32_select_cc_mode (RTX_CODE, rtx, rtx);
  933. +extern rtx ubicom32_gen_compare_reg (RTX_CODE, rtx, rtx);
  934. +extern int ubicom32_shiftable_const_int (int);
  935. +#endif /* RTX_CODE */
  936. +
  937. +#ifdef TREE_CODE
  938. +extern void init_cumulative_args (CUMULATIVE_ARGS *cum,
  939. + tree fntype,
  940. + struct rtx_def *libname,
  941. + int indirect);
  942. +extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
  943. + enum machine_mode, tree, int);
  944. +extern struct rtx_def *function_incoming_arg (CUMULATIVE_ARGS *,
  945. + enum machine_mode,
  946. + tree, int);
  947. +extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
  948. + enum machine_mode, tree, int);
  949. +extern struct rtx_def *ubicom32_va_arg (tree, tree);
  950. +extern int ubicom32_reg_parm_stack_space (tree);
  951. +#endif /* TREE_CODE */
  952. +
  953. +extern struct rtx_def * ubicom32_builtin_saveregs (void);
  954. +extern void asm_file_start (FILE *);
  955. +extern void ubicom32_expand_prologue (void);
  956. +extern void ubicom32_expand_epilogue (void);
  957. +extern int ubicom32_initial_elimination_offset (int, int);
  958. +extern int ubicom32_regno_ok_for_base_p (int, int);
  959. +extern bool ubicom32_hard_regno_mode_ok (unsigned int, enum machine_mode);
  960. +extern int ubicom32_can_use_return_insn_p (void);
  961. +extern rtx ubicom32_return_addr_rtx (int, rtx);
  962. +extern void ubicom32_optimization_options (int, int);
  963. +extern void ubicom32_override_options (void);
  964. +extern bool ubicom32_match_cc_mode (rtx, enum machine_mode);
  965. +
  966. +extern int ubicom32_reorg_completed;
  967. +
  968. --- /dev/null
  969. +++ b/gcc/config/ubicom32/ubicom32.c
  970. @@ -0,0 +1,2881 @@
  971. +/* Subroutines for insn-output.c for Ubicom32
  972. +
  973. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
  974. + 2009 Free Software Foundation, Inc.
  975. + Contributed by Ubicom, Inc.
  976. +
  977. + This file is part of GCC.
  978. +
  979. + GCC is free software; you can redistribute it and/or modify it
  980. + under the terms of the GNU General Public License as published
  981. + by the Free Software Foundation; either version 3, or (at your
  982. + option) any later version.
  983. +
  984. + GCC is distributed in the hope that it will be useful, but WITHOUT
  985. + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  986. + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  987. + License for more details.
  988. +
  989. + You should have received a copy of the GNU General Public License
  990. + along with GCC; see the file COPYING3. If not see
  991. + <http://www.gnu.org/licenses/>. */
  992. +
  993. +#include "config.h"
  994. +#include "system.h"
  995. +#include "coretypes.h"
  996. +#include "tm.h"
  997. +#include "rtl.h"
  998. +#include "tree.h"
  999. +#include "regs.h"
  1000. +#include "hard-reg-set.h"
  1001. +#include "real.h"
  1002. +#include "insn-config.h"
  1003. +#include "conditions.h"
  1004. +#include "insn-flags.h"
  1005. +#include "output.h"
  1006. +#include "insn-attr.h"
  1007. +#include "insn-codes.h"
  1008. +#include "flags.h"
  1009. +#include "recog.h"
  1010. +#include "expr.h"
  1011. +#include "function.h"
  1012. +#include "obstack.h"
  1013. +#include "toplev.h"
  1014. +#include "tm_p.h"
  1015. +#include "tm-constrs.h"
  1016. +#include "basic-block.h"
  1017. +#include "integrate.h"
  1018. +#include "target.h"
  1019. +#include "target-def.h"
  1020. +#include "reload.h"
  1021. +#include "df.h"
  1022. +#include "langhooks.h"
  1023. +#include "optabs.h"
  1024. +
  1025. +static tree ubicom32_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
  1026. +static void ubicom32_layout_frame (void);
  1027. +static void ubicom32_function_prologue (FILE *, HOST_WIDE_INT);
  1028. +static void ubicom32_function_epilogue (FILE *, HOST_WIDE_INT);
  1029. +static bool ubicom32_rtx_costs (rtx, int, int, int *, bool speed);
  1030. +static bool ubicom32_fixed_condition_code_regs (unsigned int *,
  1031. + unsigned int *);
  1032. +static enum machine_mode ubicom32_cc_modes_compatible (enum machine_mode,
  1033. + enum machine_mode);
  1034. +static int ubicom32_naked_function_p (void);
  1035. +static void ubicom32_machine_dependent_reorg (void);
  1036. +static bool ubicom32_assemble_integer (rtx, unsigned int, int);
  1037. +static void ubicom32_asm_init_sections (void);
  1038. +static int ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,tree,
  1039. + bool);
  1040. +static bool ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
  1041. + enum machine_mode mode, const_tree type,
  1042. + bool named ATTRIBUTE_UNUSED);
  1043. +static bool ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
  1044. + enum machine_mode mode, const_tree type,
  1045. + bool named ATTRIBUTE_UNUSED);
  1046. +
  1047. +static bool ubicom32_return_in_memory (const_tree type,
  1048. + const_tree fntype ATTRIBUTE_UNUSED);
  1049. +static bool ubicom32_is_base_reg (rtx, int);
  1050. +static void ubicom32_init_builtins (void);
  1051. +static rtx ubicom32_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
  1052. +static tree ubicom32_fold_builtin (tree, tree, bool);
  1053. +static int ubicom32_get_valid_offset_mask (enum machine_mode);
  1054. +static bool ubicom32_cannot_force_const_mem (rtx);
  1055. +
  1056. +/* Case values threshold */
  1057. +int ubicom32_case_values_threshold = 6;
  1058. +
  1059. +/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
  1060. +int ubicom32_v3 = 1;
  1061. +
  1062. +/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
  1063. +int ubicom32_v4 = 1;
  1064. +
  1065. +/* Valid attributes:
  1066. + naked - don't generate function prologue/epilogue and `ret' command. */
  1067. +const struct attribute_spec ubicom32_attribute_table[] =
  1068. +{
  1069. + /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
  1070. + { "naked", 0, 0, true, false, false, ubicom32_handle_fndecl_attribute },
  1071. + { NULL, 0, 0, false, false, false, NULL }
  1072. +};
  1073. +
  1074. +#undef TARGET_ASM_FUNCTION_PROLOGUE
  1075. +#define TARGET_ASM_FUNCTION_PROLOGUE ubicom32_function_prologue
  1076. +
  1077. +#undef TARGET_ASM_FUNCTION_EPILOGUE
  1078. +#define TARGET_ASM_FUNCTION_EPILOGUE ubicom32_function_epilogue
  1079. +
  1080. +#undef TARGET_ATTRIBUTE_TABLE
  1081. +#define TARGET_ATTRIBUTE_TABLE ubicom32_attribute_table
  1082. +
  1083. +/* All addresses cost the same amount. */
  1084. +#undef TARGET_ADDRESS_COST
  1085. +#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
  1086. +
  1087. +#undef TARGET_RTX_COSTS
  1088. +#define TARGET_RTX_COSTS ubicom32_rtx_costs
  1089. +
  1090. +#undef TARGET_FIXED_CONDITION_CODE_REGS
  1091. +#define TARGET_FIXED_CONDITION_CODE_REGS ubicom32_fixed_condition_code_regs
  1092. +
  1093. +#undef TARGET_CC_MODES_COMPATIBLE
  1094. +#define TARGET_CC_MODES_COMPATIBLE ubicom32_cc_modes_compatible
  1095. +
  1096. +#undef TARGET_MACHINE_DEPENDENT_REORG
  1097. +#define TARGET_MACHINE_DEPENDENT_REORG ubicom32_machine_dependent_reorg
  1098. +
  1099. +#undef TARGET_ASM_INTEGER
  1100. +#define TARGET_ASM_INTEGER ubicom32_assemble_integer
  1101. +
  1102. +#undef TARGET_ASM_INIT_SECTIONS
  1103. +#define TARGET_ASM_INIT_SECTIONS ubicom32_asm_init_sections
  1104. +
  1105. +#undef TARGET_ARG_PARTIAL_BYTES
  1106. +#define TARGET_ARG_PARTIAL_BYTES ubicom32_arg_partial_bytes
  1107. +
  1108. +#undef TARGET_PASS_BY_REFERENCE
  1109. +#define TARGET_PASS_BY_REFERENCE ubicom32_pass_by_reference
  1110. +
  1111. +#undef TARGET_CALLEE_COPIES
  1112. +#define TARGET_CALLEE_COPIES ubicom32_callee_copies
  1113. +
  1114. +#undef TARGET_RETURN_IN_MEMORY
  1115. +#define TARGET_RETURN_IN_MEMORY ubicom32_return_in_memory
  1116. +
  1117. +#undef TARGET_INIT_BUILTINS
  1118. +#define TARGET_INIT_BUILTINS ubicom32_init_builtins
  1119. +
  1120. +#undef TARGET_EXPAND_BUILTIN
  1121. +#define TARGET_EXPAND_BUILTIN ubicom32_expand_builtin
  1122. +
  1123. +#undef TARGET_FOLD_BUILTIN
  1124. +#define TARGET_FOLD_BUILTIN ubicom32_fold_builtin
  1125. +
  1126. +#undef TARGET_CANNOT_FORCE_CONST_MEM
  1127. +#define TARGET_CANNOT_FORCE_CONST_MEM ubicom32_cannot_force_const_mem
  1128. +
  1129. +struct gcc_target targetm = TARGET_INITIALIZER;
  1130. +
  1131. +static char save_regs[FIRST_PSEUDO_REGISTER];
  1132. +static int nregs;
  1133. +static int frame_size;
  1134. +int ubicom32_stack_size = 0; /* size of allocated stack (including frame) */
  1135. +int ubicom32_can_use_calli_to_ret;
  1136. +
  1137. +#define STACK_UNIT_BOUNDARY (STACK_BOUNDARY / BITS_PER_UNIT)
  1138. +#define ROUND_CALL_BLOCK_SIZE(BYTES) \
  1139. + (((BYTES) + (STACK_UNIT_BOUNDARY - 1)) & ~(STACK_UNIT_BOUNDARY - 1))
  1140. +
  1141. +/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
  1142. + must report the mode of the memory reference from PRINT_OPERAND to
  1143. + PRINT_OPERAND_ADDRESS. */
  1144. +enum machine_mode output_memory_reference_mode;
  1145. +
  1146. +/* Flag for some split insns from the ubicom32.md. */
  1147. +int ubicom32_reorg_completed;
  1148. +
  1149. +enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER] =
  1150. +{
  1151. + DATA_REGS,
  1152. + DATA_REGS,
  1153. + DATA_REGS,
  1154. + DATA_REGS,
  1155. + DATA_REGS,
  1156. + DATA_REGS,
  1157. + DATA_REGS,
  1158. + DATA_REGS,
  1159. + DATA_REGS,
  1160. + DATA_REGS,
  1161. + DATA_REGS,
  1162. + DATA_REGS,
  1163. + DATA_REGS,
  1164. + DATA_REGS,
  1165. + DATA_REGS,
  1166. + DATA_REGS,
  1167. + FDPIC_REG,
  1168. + ADDRESS_REGS,
  1169. + ADDRESS_REGS,
  1170. + ADDRESS_REGS,
  1171. + ADDRESS_REGS,
  1172. + ADDRESS_REGS,
  1173. + ADDRESS_REGS,
  1174. + ADDRESS_REGS,
  1175. + ACC_REGS,
  1176. + ACC_LO_REGS,
  1177. + ACC_REGS,
  1178. + ACC_LO_REGS,
  1179. + SOURCE3_REG,
  1180. + ADDRESS_REGS,
  1181. + NO_REGS, /* CC_REG must be NO_REGS */
  1182. + SPECIAL_REGS,
  1183. + SPECIAL_REGS,
  1184. + SPECIAL_REGS,
  1185. + SPECIAL_REGS,
  1186. + SPECIAL_REGS,
  1187. + SPECIAL_REGS,
  1188. + SPECIAL_REGS,
  1189. + SPECIAL_REGS
  1190. +};
  1191. +
  1192. +rtx ubicom32_compare_op0;
  1193. +rtx ubicom32_compare_op1;
  1194. +
  1195. +/* Handle command line option overrides. */
  1196. +
  1197. +void
  1198. +ubicom32_override_options (void)
  1199. +{
  1200. + flag_pic = 0;
  1201. +
  1202. + if (strcmp (ubicom32_arch_name, "ubicom32v1") == 0) {
  1203. + /* If we have a version 1 architecture then we want to avoid using jump
  1204. + tables. */
  1205. + ubicom32_case_values_threshold = 30000;
  1206. + ubicom32_v3 = 0;
  1207. + ubicom32_v4 = 0;
  1208. + } else if (strcmp (ubicom32_arch_name, "ubicom32v2") == 0) {
  1209. + ubicom32_v3 = 0;
  1210. + ubicom32_v4 = 0;
  1211. + } else if (strcmp (ubicom32_arch_name, "ubicom32v3") == 0) {
  1212. + ubicom32_v3 = 1;
  1213. + ubicom32_v4 = 0;
  1214. + } else if (strcmp (ubicom32_arch_name, "ubicom32v4") == 0) {
  1215. + ubicom32_v3 = 1;
  1216. + ubicom32_v4 = 1;
  1217. + }
  1218. +
  1219. + /* There is no single unaligned SI op for PIC code. Sometimes we
  1220. + need to use ".4byte" and sometimes we need to use ".picptr".
  1221. + See ubicom32_assemble_integer for details. */
  1222. + if (TARGET_FDPIC)
  1223. + targetm.asm_out.unaligned_op.si = 0;
  1224. +}
  1225. +
  1226. +void
  1227. +ubicom32_conditional_register_usage (void)
  1228. +{
  1229. + /* If we're using the old ipOS ABI we need to make D10 through D13
  1230. + caller-clobbered. */
  1231. + if (TARGET_IPOS_ABI)
  1232. + {
  1233. + call_used_regs[D10_REGNUM] = 1;
  1234. + call_used_regs[D11_REGNUM] = 1;
  1235. + call_used_regs[D12_REGNUM] = 1;
  1236. + call_used_regs[D13_REGNUM] = 1;
  1237. + }
  1238. +}
  1239. +
  1240. +/* We have some number of optimizations that don't really work for the Ubicom32
  1241. + architecture so we deal with them here. */
  1242. +
  1243. +void
  1244. +ubicom32_optimization_options (int level ATTRIBUTE_UNUSED,
  1245. + int size ATTRIBUTE_UNUSED)
  1246. +{
  1247. + /* The tree IVOPTs pass seems to do really bad things for the Ubicom32
  1248. + architecture - it tends to turn things that would happily use pre/post
  1249. + increment/decrement into operations involving unecessary loop
  1250. + indicies. */
  1251. + flag_ivopts = 0;
  1252. +
  1253. + /* We have problems where DSE at the RTL level misses partial stores
  1254. + to the stack. For now we disable it to avoid this. */
  1255. + flag_dse = 0;
  1256. +}
  1257. +
  1258. +/* Print operand X using operand code CODE to assembly language output file
  1259. + FILE. */
  1260. +
  1261. +void
  1262. +ubicom32_print_operand (FILE *file, rtx x, int code)
  1263. +{
  1264. + switch (code)
  1265. + {
  1266. + case 'A':
  1267. + /* Identify the correct accumulator to use. */
  1268. + if (REGNO (x) == ACC0_HI_REGNUM || REGNO (x) == ACC0_LO_REGNUM)
  1269. + fprintf (file, "acc0");
  1270. + else if (REGNO (x) == ACC1_HI_REGNUM || REGNO (x) == ACC1_LO_REGNUM)
  1271. + fprintf (file, "acc1");
  1272. + else
  1273. + abort ();
  1274. + break;
  1275. +
  1276. + case 'b':
  1277. + case 'B':
  1278. + {
  1279. + enum machine_mode mode;
  1280. +
  1281. + mode = GET_MODE (XEXP (x, 0));
  1282. +
  1283. + /* These are normal and reversed branches. */
  1284. + switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
  1285. + {
  1286. + case NE:
  1287. + fprintf (file, "ne");
  1288. + break;
  1289. +
  1290. + case EQ:
  1291. + fprintf (file, "eq");
  1292. + break;
  1293. +
  1294. + case GE:
  1295. + if (mode == CCSZNmode || mode == CCWZNmode)
  1296. + fprintf (file, "pl");
  1297. + else
  1298. + fprintf (file, "ge");
  1299. + break;
  1300. +
  1301. + case GT:
  1302. + fprintf (file, "gt");
  1303. + break;
  1304. +
  1305. + case LE:
  1306. + fprintf (file, "le");
  1307. + break;
  1308. +
  1309. + case LT:
  1310. + if (mode == CCSZNmode || mode == CCWZNmode)
  1311. + fprintf (file, "mi");
  1312. + else
  1313. + fprintf (file, "lt");
  1314. + break;
  1315. +
  1316. + case GEU:
  1317. + fprintf (file, "cs");
  1318. + break;
  1319. +
  1320. + case GTU:
  1321. + fprintf (file, "hi");
  1322. + break;
  1323. +
  1324. + case LEU:
  1325. + fprintf (file, "ls");
  1326. + break;
  1327. +
  1328. + case LTU:
  1329. + fprintf (file, "cc");
  1330. + break;
  1331. +
  1332. + default:
  1333. + abort ();
  1334. + }
  1335. + }
  1336. + break;
  1337. +
  1338. + case 'C':
  1339. + /* This is used for the operand to a call instruction;
  1340. + if it's a REG, enclose it in parens, else output
  1341. + the operand normally. */
  1342. + if (REG_P (x))
  1343. + {
  1344. + fputc ('(', file);
  1345. + ubicom32_print_operand (file, x, 0);
  1346. + fputc (')', file);
  1347. + }
  1348. + else
  1349. + ubicom32_print_operand (file, x, 0);
  1350. + break;
  1351. +
  1352. + case 'd':
  1353. + /* Bit operations we need bit numbers. */
  1354. + fprintf (file, "%d", exact_log2 (INTVAL (x)));
  1355. + break;
  1356. +
  1357. + case 'D':
  1358. + /* Bit operations we need bit numbers. */
  1359. + fprintf (file, "%d", exact_log2 (~ INTVAL (x)));
  1360. + break;
  1361. +
  1362. + case 'E':
  1363. + /* For lea, which we use to add address registers.
  1364. + We don't want the '#' on a constant. */
  1365. + if (CONST_INT_P (x))
  1366. + {
  1367. + fprintf (file, "%ld", INTVAL (x));
  1368. + break;
  1369. + }
  1370. + /* FALL THROUGH */
  1371. +
  1372. + default:
  1373. + switch (GET_CODE (x))
  1374. + {
  1375. + case MEM:
  1376. + output_memory_reference_mode = GET_MODE (x);
  1377. + output_address (XEXP (x, 0));
  1378. + break;
  1379. +
  1380. + case PLUS:
  1381. + output_address (x);
  1382. + break;
  1383. +
  1384. + case REG:
  1385. + fprintf (file, "%s", reg_names[REGNO (x)]);
  1386. + break;
  1387. +
  1388. + case SUBREG:
  1389. + fprintf (file, "%s", reg_names[subreg_regno (x)]);
  1390. + break;
  1391. +
  1392. + /* This will only be single precision.... */
  1393. + case CONST_DOUBLE:
  1394. + {
  1395. + unsigned long val;
  1396. + REAL_VALUE_TYPE rv;
  1397. +
  1398. + REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
  1399. + REAL_VALUE_TO_TARGET_SINGLE (rv, val);
  1400. + fprintf (file, "0x%lx", val);
  1401. + break;
  1402. + }
  1403. +
  1404. + case CONST_INT:
  1405. + case SYMBOL_REF:
  1406. + case CONST:
  1407. + case LABEL_REF:
  1408. + case CODE_LABEL:
  1409. + case LO_SUM:
  1410. + ubicom32_print_operand_address (file, x);
  1411. + break;
  1412. +
  1413. + case HIGH:
  1414. + fprintf (file, "#%%hi(");
  1415. + ubicom32_print_operand_address (file, XEXP (x, 0));
  1416. + fprintf (file, ")");
  1417. + break;
  1418. +
  1419. + case UNSPEC:
  1420. + switch (XINT (x, 1))
  1421. + {
  1422. + case UNSPEC_FDPIC_GOT:
  1423. + fprintf (file, "#%%got_lo(");
  1424. + ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
  1425. + fprintf (file, ")");
  1426. + break;
  1427. +
  1428. + case UNSPEC_FDPIC_GOT_FUNCDESC:
  1429. + fprintf (file, "#%%got_funcdesc_lo(");
  1430. + ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
  1431. + fprintf (file, ")");
  1432. + break;
  1433. +
  1434. + default:
  1435. + abort ();
  1436. + }
  1437. + break;
  1438. +
  1439. + default:
  1440. + abort ();
  1441. + }
  1442. + break;
  1443. + }
  1444. +}
  1445. +
  1446. +/* Output assembly language output for the address ADDR to FILE. */
  1447. +
  1448. +void
  1449. +ubicom32_print_operand_address (FILE *file, rtx addr)
  1450. +{
  1451. + switch (GET_CODE (addr))
  1452. + {
  1453. + case POST_INC:
  1454. + ubicom32_print_operand_address (file, XEXP (addr, 0));
  1455. + fprintf (file, "%d++", GET_MODE_SIZE (output_memory_reference_mode));
  1456. + break;
  1457. +
  1458. + case PRE_INC:
  1459. + fprintf (file, "%d", GET_MODE_SIZE (output_memory_reference_mode));
  1460. + ubicom32_print_operand_address (file, XEXP (addr, 0));
  1461. + fprintf (file, "++");
  1462. + break;
  1463. +
  1464. + case POST_DEC:
  1465. + ubicom32_print_operand_address (file, XEXP (addr, 0));
  1466. + fprintf (file, "%d++", -GET_MODE_SIZE (output_memory_reference_mode));
  1467. + break;
  1468. +
  1469. + case PRE_DEC:
  1470. + fprintf (file, "%d", -GET_MODE_SIZE (output_memory_reference_mode));
  1471. + ubicom32_print_operand_address (file, XEXP (addr, 0));
  1472. + fprintf (file, "++");
  1473. + break;
  1474. +
  1475. + case POST_MODIFY:
  1476. + ubicom32_print_operand_address (file, XEXP (addr, 0));
  1477. + fprintf (file, "%ld++", INTVAL (XEXP (XEXP (addr,1), 1)));
  1478. + break;
  1479. +
  1480. + case PRE_MODIFY:
  1481. + fprintf (file, "%ld", INTVAL (XEXP (XEXP (addr,1), 1)));
  1482. + ubicom32_print_operand_address (file, XEXP (addr, 0));
  1483. + fprintf (file, "++");
  1484. + break;
  1485. +
  1486. + case REG:
  1487. + fputc ('(', file);
  1488. + fprintf (file, "%s", reg_names[REGNO (addr)]);
  1489. + fputc (')', file);
  1490. + break;
  1491. +
  1492. + case PLUS:
  1493. + {
  1494. + rtx base = XEXP (addr, 0);
  1495. + rtx index = XEXP (addr, 1);
  1496. +
  1497. + /* Switch around addresses of the form index * scaling + base. */
  1498. + if (! ubicom32_is_base_reg (base, 1))
  1499. + {
  1500. + rtx tmp = base;
  1501. + base = index;
  1502. + index = tmp;
  1503. + }
  1504. +
  1505. + if (CONST_INT_P (index))
  1506. + {
  1507. + fprintf (file, "%ld", INTVAL (index));
  1508. + fputc ('(', file);
  1509. + fputs (reg_names[REGNO (base)], file);
  1510. + }
  1511. + else if (GET_CODE (index) == MULT
  1512. + || REG_P (index))
  1513. + {
  1514. + if (GET_CODE (index) == MULT)
  1515. + index = XEXP (index, 0);
  1516. + fputc ('(', file);
  1517. + fputs (reg_names[REGNO (base)], file);
  1518. + fputc (',', file);
  1519. + fputs (reg_names[REGNO (index)], file);
  1520. + }
  1521. + else
  1522. + abort ();
  1523. +
  1524. + fputc (')', file);
  1525. + break;
  1526. + }
  1527. +
  1528. + case LO_SUM:
  1529. + fprintf (file, "%%lo(");
  1530. + ubicom32_print_operand (file, XEXP (addr, 1), 'L');
  1531. + fprintf (file, ")(");
  1532. + ubicom32_print_operand (file, XEXP (addr, 0), 0);
  1533. + fprintf (file, ")");
  1534. + break;
  1535. +
  1536. + case CONST_INT:
  1537. + fputc ('#', file);
  1538. + output_addr_const (file, addr);
  1539. + break;
  1540. +
  1541. + default:
  1542. + output_addr_const (file, addr);
  1543. + break;
  1544. + }
  1545. +}
  1546. +
  1547. +/* X and Y are two things to compare using CODE. Emit the compare insn and
  1548. + return the rtx for the cc reg in the proper mode. */
  1549. +
  1550. +rtx
  1551. +ubicom32_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
  1552. +{
  1553. + enum machine_mode mode = SELECT_CC_MODE (code, x, y);
  1554. + rtx cc_reg;
  1555. +
  1556. + cc_reg = gen_rtx_REG (mode, CC_REGNUM);
  1557. +
  1558. + emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
  1559. + gen_rtx_COMPARE (mode, x, y)));
  1560. +
  1561. + return cc_reg;
  1562. +}
  1563. +
  1564. +/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
  1565. + return the mode to be used for the comparison. */
  1566. +
  1567. +enum machine_mode
  1568. +ubicom32_select_cc_mode (enum rtx_code op, rtx x, rtx y)
  1569. +{
  1570. + /* Is this a short compare? */
  1571. + if (GET_MODE (x) == QImode
  1572. + || GET_MODE (x) == HImode
  1573. + || GET_MODE (y) == QImode
  1574. + || GET_MODE (y) == HImode)
  1575. + {
  1576. + switch (op)
  1577. + {
  1578. + case EQ :
  1579. + case NE :
  1580. + return CCSZmode;
  1581. +
  1582. + case GE:
  1583. + case LT:
  1584. + if (y == const0_rtx)
  1585. + return CCSZNmode;
  1586. +
  1587. + default :
  1588. + return CCSmode;
  1589. + }
  1590. + }
  1591. +
  1592. + /* We have a word compare. */
  1593. + switch (op)
  1594. + {
  1595. + case EQ :
  1596. + case NE :
  1597. + return CCWZmode;
  1598. +
  1599. + case GE :
  1600. + case LT :
  1601. + if (y == const0_rtx)
  1602. + return CCWZNmode;
  1603. +
  1604. + default :
  1605. + return CCWmode;
  1606. + }
  1607. +}
  1608. +
  1609. +/* Return TRUE or FALSE depending on whether the first SET in INSN
  1610. + has source and destination with matching CC modes, and that the
  1611. + CC mode is at least as constrained as REQ_MODE. */
  1612. +bool
  1613. +ubicom32_match_cc_mode (rtx insn, enum machine_mode req_mode)
  1614. +{
  1615. + rtx set;
  1616. + enum machine_mode set_mode;
  1617. +
  1618. + set = PATTERN (insn);
  1619. + if (GET_CODE (set) == PARALLEL)
  1620. + set = XVECEXP (set, 0, 0);
  1621. + gcc_assert (GET_CODE (set) == SET);
  1622. + gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
  1623. +
  1624. + /* SET_MODE is the mode we have in the instruction. This must either
  1625. + be the same or less restrictive that the required mode REQ_MODE. */
  1626. + set_mode = GET_MODE (SET_DEST (set));
  1627. +
  1628. + switch (req_mode)
  1629. + {
  1630. + case CCSZmode:
  1631. + if (set_mode != CCSZmode)
  1632. + return 0;
  1633. + break;
  1634. +
  1635. + case CCSZNmode:
  1636. + if (set_mode != CCSZmode
  1637. + && set_mode != CCSZNmode)
  1638. + return 0;
  1639. + break;
  1640. +
  1641. + case CCSmode:
  1642. + if (set_mode != CCSmode
  1643. + && set_mode != CCSZmode
  1644. + && set_mode != CCSZNmode)
  1645. + return 0;
  1646. + break;
  1647. +
  1648. + case CCWZmode:
  1649. + if (set_mode != CCWZmode)
  1650. + return 0;
  1651. + break;
  1652. +
  1653. + case CCWZNmode:
  1654. + if (set_mode != CCWZmode
  1655. + && set_mode != CCWZNmode)
  1656. + return 0;
  1657. + break;
  1658. +
  1659. + case CCWmode:
  1660. + if (set_mode != CCWmode
  1661. + && set_mode != CCWZmode
  1662. + && set_mode != CCWZNmode)
  1663. + return 0;
  1664. + break;
  1665. +
  1666. + default:
  1667. + gcc_unreachable ();
  1668. + }
  1669. +
  1670. + return (GET_MODE (SET_SRC (set)) == set_mode);
  1671. +}
  1672. +
  1673. +/* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
  1674. + that we can implement more efficiently. */
  1675. +
  1676. +void
  1677. +ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
  1678. +{
  1679. + /* If we have a REG and a MEM then compare the MEM with the REG and not
  1680. + the other way round. */
  1681. + if (REG_P (*op0) && MEM_P (*op1))
  1682. + {
  1683. + rtx tem = *op0;
  1684. + *op0 = *op1;
  1685. + *op1 = tem;
  1686. + *code = swap_condition (*code);
  1687. + return;
  1688. + }
  1689. +
  1690. + /* If we have a REG and a CONST_INT then we may want to reverse things
  1691. + if the constant can be represented as an "I" constraint. */
  1692. + if (REG_P (*op0) && CONST_INT_P (*op1) && satisfies_constraint_I (*op1))
  1693. + {
  1694. + rtx tem = *op0;
  1695. + *op0 = *op1;
  1696. + *op1 = tem;
  1697. + *code = swap_condition (*code);
  1698. + return;
  1699. + }
  1700. +}
  1701. +
  1702. +/* Return the fixed registers used for condition codes. */
  1703. +
  1704. +static bool
  1705. +ubicom32_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
  1706. +{
  1707. + *p1 = CC_REGNUM;
  1708. + *p2 = INVALID_REGNUM;
  1709. +
  1710. + return true;
  1711. +}
  1712. +
  1713. +/* If two condition code modes are compatible, return a condition code
  1714. + mode which is compatible with both. Otherwise, return
  1715. + VOIDmode. */
  1716. +
  1717. +static enum machine_mode
  1718. +ubicom32_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
  1719. +{
  1720. + if (m1 == m2)
  1721. + return m1;
  1722. +
  1723. + if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
  1724. + return VOIDmode;
  1725. +
  1726. + switch (m1)
  1727. + {
  1728. + case CCWmode:
  1729. + if (m2 == CCWZNmode || m2 == CCWZmode)
  1730. + return m1;
  1731. +
  1732. + return VOIDmode;
  1733. +
  1734. + case CCWZNmode:
  1735. + if (m2 == CCWmode)
  1736. + return m2;
  1737. +
  1738. + if (m2 == CCWZmode)
  1739. + return m1;
  1740. +
  1741. + return VOIDmode;
  1742. +
  1743. + case CCWZmode:
  1744. + if (m2 == CCWmode || m2 == CCWZNmode)
  1745. + return m2;
  1746. +
  1747. + return VOIDmode;
  1748. +
  1749. + case CCSmode:
  1750. + if (m2 == CCSZNmode || m2 == CCSZmode)
  1751. + return m1;
  1752. +
  1753. + return VOIDmode;
  1754. +
  1755. + case CCSZNmode:
  1756. + if (m2 == CCSmode)
  1757. + return m2;
  1758. +
  1759. + if (m2 == CCSZmode)
  1760. + return m1;
  1761. +
  1762. + return VOIDmode;
  1763. +
  1764. + case CCSZmode:
  1765. + if (m2 == CCSmode || m2 == CCSZNmode)
  1766. + return m2;
  1767. +
  1768. + return VOIDmode;
  1769. +
  1770. + default:
  1771. + gcc_unreachable ();
  1772. + }
  1773. +}
  1774. +
  1775. +static rtx
  1776. +ubicom32_legitimize_fdpic_address_symbol (rtx orig, rtx reg, rtx fdpic_reg)
  1777. +{
  1778. + int unspec;
  1779. + rtx got_offs;
  1780. + rtx got_offs_scaled;
  1781. + rtx plus_scaled;
  1782. + rtx tmp;
  1783. + rtx new_rtx;
  1784. +
  1785. + gcc_assert (reg != 0);
  1786. +
  1787. + if (GET_CODE (orig) == SYMBOL_REF
  1788. + && SYMBOL_REF_FUNCTION_P (orig))
  1789. + unspec = UNSPEC_FDPIC_GOT_FUNCDESC;
  1790. + else
  1791. + unspec = UNSPEC_FDPIC_GOT;
  1792. +
  1793. + got_offs = gen_reg_rtx (SImode);
  1794. + tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), unspec);
  1795. + emit_move_insn (got_offs, tmp);
  1796. +
  1797. + got_offs_scaled = gen_rtx_MULT (SImode, got_offs, GEN_INT (4));
  1798. + plus_scaled = gen_rtx_PLUS (Pmode, fdpic_reg, got_offs_scaled);
  1799. + new_rtx = gen_const_mem (Pmode, plus_scaled);
  1800. + emit_move_insn (reg, new_rtx);
  1801. +
  1802. + return reg;
  1803. +}
  1804. +
  1805. +static rtx
  1806. +ubicom32_legitimize_fdpic_address (rtx orig, rtx reg, rtx fdpic_reg)
  1807. +{
  1808. + rtx addr = orig;
  1809. + rtx new_rtx = orig;
  1810. +
  1811. + if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
  1812. + {
  1813. + rtx base;
  1814. +
  1815. + if (GET_CODE (addr) == CONST)
  1816. + {
  1817. + addr = XEXP (addr, 0);
  1818. + gcc_assert (GET_CODE (addr) == PLUS);
  1819. + }
  1820. +
  1821. + base = ubicom32_legitimize_fdpic_address_symbol (XEXP (addr, 0), reg, fdpic_reg);
  1822. + return gen_rtx_PLUS (Pmode, base, XEXP (addr, 1));
  1823. + }
  1824. +
  1825. + return new_rtx;
  1826. +}
  1827. +
  1828. +/* Code generation. */
  1829. +
  1830. +void
  1831. +ubicom32_expand_movsi (rtx *operands)
  1832. +{
  1833. + if (GET_CODE (operands[1]) == SYMBOL_REF
  1834. + || (GET_CODE (operands[1]) == CONST
  1835. + && GET_CODE (XEXP (operands[1], 0)) == PLUS
  1836. + && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
  1837. + || CONSTANT_ADDRESS_P (operands[1]))
  1838. + {
  1839. + if (TARGET_FDPIC)
  1840. + {
  1841. + rtx tmp;
  1842. + rtx fdpic_reg;
  1843. +
  1844. + gcc_assert (can_create_pseudo_p ());
  1845. + tmp = gen_reg_rtx (Pmode);
  1846. + fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
  1847. + if (GET_CODE (operands[1]) == SYMBOL_REF
  1848. + || GET_CODE (operands[1]) == LABEL_REF)
  1849. + operands[1] = ubicom32_legitimize_fdpic_address_symbol (operands[1], tmp, fdpic_reg);
  1850. + else
  1851. + operands[1] = ubicom32_legitimize_fdpic_address (operands[1], tmp, fdpic_reg);
  1852. + }
  1853. + else
  1854. + {
  1855. + rtx tmp;
  1856. + enum machine_mode mode;
  1857. +
  1858. + /* We want to avoid reusing operand 0 if we can because it limits
  1859. + our ability to optimize later. */
  1860. + tmp = ! can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
  1861. +
  1862. + mode = GET_MODE (operands[0]);
  1863. + emit_insn (gen_rtx_SET (VOIDmode, tmp,
  1864. + gen_rtx_HIGH (mode, operands[1])));
  1865. + operands[1] = gen_rtx_LO_SUM (mode, tmp, operands[1]);
  1866. + if (can_create_pseudo_p() && ! REG_P (operands[0]))
  1867. + {
  1868. + tmp = gen_reg_rtx (mode);
  1869. + emit_insn (gen_rtx_SET (VOIDmode, tmp, operands[1]));
  1870. + operands[1] = tmp;
  1871. + }
  1872. + }
  1873. + }
  1874. +}
  1875. +
  1876. +/* Emit code for addsi3. */
  1877. +
  1878. +void
  1879. +ubicom32_expand_addsi3 (rtx *operands)
  1880. +{
  1881. + rtx op, clob;
  1882. +
  1883. + if (can_create_pseudo_p ())
  1884. + {
  1885. + /* If we have a non-data reg for operand 1 then prefer that over
  1886. + a CONST_INT in operand 2. */
  1887. + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
  1888. + && CONST_INT_P (operands[2]))
  1889. + operands[2] = copy_to_mode_reg (SImode, operands[2]);
  1890. +
  1891. + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
  1892. + operands[2] = copy_to_mode_reg (SImode, operands[2]);
  1893. + }
  1894. +
  1895. + /* Emit the instruction. */
  1896. +
  1897. + op = gen_rtx_SET (VOIDmode, operands[0],
  1898. + gen_rtx_PLUS (SImode, operands[1], operands[2]));
  1899. +
  1900. + if (! can_create_pseudo_p ())
  1901. + {
  1902. + /* Reload doesn't know about the flags register, and doesn't know that
  1903. + it doesn't want to clobber it. We can only do this with PLUS. */
  1904. + emit_insn (op);
  1905. + }
  1906. + else
  1907. + {
  1908. + clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
  1909. + emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
  1910. + }
  1911. +}
  1912. +
  1913. +/* Emit code for mulsi3. Return 1 if we have generated all the code
  1914. + necessary to do the multiplication. */
  1915. +
  1916. +int
  1917. +ubicom32_emit_mult_sequence (rtx *operands)
  1918. +{
  1919. + if (! ubicom32_v4)
  1920. + {
  1921. + rtx a1, a1_1, a2;
  1922. + rtx b1, b1_1, b2;
  1923. + rtx mac_lo_rtx;
  1924. + rtx t1, t2, t3;
  1925. +
  1926. + /* Give up if we cannot create new pseudos. */
  1927. + if (!can_create_pseudo_p())
  1928. + return 0;
  1929. +
  1930. + /* Synthesize 32-bit multiplication using 16-bit operations:
  1931. +
  1932. + a1 = highpart (a)
  1933. + a2 = lowpart (a)
  1934. +
  1935. + b1 = highpart (b)
  1936. + b2 = lowpart (b)
  1937. +
  1938. + c = (a1 * b1) << 32 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
  1939. + = 0 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
  1940. + ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^
  1941. + Signed Signed Unsigned */
  1942. +
  1943. + if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
  1944. + {
  1945. + rtx op1;
  1946. +
  1947. + op1 = gen_reg_rtx (SImode);
  1948. + emit_move_insn (op1, operands[1]);
  1949. + operands[1] = op1;
  1950. + }
  1951. +
  1952. + if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
  1953. + {
  1954. + rtx op2;
  1955. +
  1956. + op2 = gen_reg_rtx (SImode);
  1957. + emit_move_insn (op2, operands[2]);
  1958. + operands[2] = op2;
  1959. + }
  1960. +
  1961. + /* a1 = highpart (a) */
  1962. + a1 = gen_reg_rtx (HImode);
  1963. + a1_1 = gen_reg_rtx (SImode);
  1964. + emit_insn (gen_ashrsi3 (a1_1, operands[1], GEN_INT (16)));
  1965. + emit_move_insn (a1, gen_lowpart (HImode, a1_1));
  1966. +
  1967. + /* a2 = lowpart (a) */
  1968. + a2 = gen_reg_rtx (HImode);
  1969. + emit_move_insn (a2, gen_lowpart (HImode, operands[1]));
  1970. +
  1971. + /* b1 = highpart (b) */
  1972. + b1 = gen_reg_rtx (HImode);
  1973. + b1_1 = gen_reg_rtx (SImode);
  1974. + emit_insn (gen_ashrsi3 (b1_1, operands[2], GEN_INT (16)));
  1975. + emit_move_insn (b1, gen_lowpart (HImode, b1_1));
  1976. +
  1977. + /* b2 = lowpart (b) */
  1978. + b2 = gen_reg_rtx (HImode);
  1979. + emit_move_insn (b2, gen_lowpart (HImode, operands[2]));
  1980. +
  1981. + /* t1 = (a1 * b2) << 16 */
  1982. + t1 = gen_reg_rtx (SImode);
  1983. + mac_lo_rtx = gen_rtx_REG (SImode, ACC0_LO_REGNUM);
  1984. + emit_insn (gen_mulhisi3 (mac_lo_rtx, a1, b2));
  1985. + emit_insn (gen_ashlsi3 (t1, mac_lo_rtx, GEN_INT (16)));
  1986. +
  1987. + /* t2 = (a2 * b1) << 16 */
  1988. + t2 = gen_reg_rtx (SImode);
  1989. + emit_insn (gen_mulhisi3 (mac_lo_rtx, a2, b1));
  1990. + emit_insn (gen_ashlsi3 (t2, mac_lo_rtx, GEN_INT (16)));
  1991. +
  1992. + /* mac_lo = a2 * b2 */
  1993. + emit_insn (gen_umulhisi3 (mac_lo_rtx, a2, b2));
  1994. +
  1995. + /* t3 = t1 + t2 */
  1996. + t3 = gen_reg_rtx (SImode);
  1997. + emit_insn (gen_addsi3 (t3, t1, t2));
  1998. +
  1999. + /* c = t3 + mac_lo_rtx */
  2000. + emit_insn (gen_addsi3 (operands[0], mac_lo_rtx, t3));
  2001. +
  2002. + return 1;
  2003. + }
  2004. + else
  2005. + {
  2006. + rtx acc_rtx;
  2007. +
  2008. + /* Give up if we cannot create new pseudos. */
  2009. + if (!can_create_pseudo_p())
  2010. + return 0;
  2011. +
  2012. + if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
  2013. + {
  2014. + rtx op1;
  2015. +
  2016. + op1 = gen_reg_rtx (SImode);
  2017. + emit_move_insn (op1, operands[1]);
  2018. + operands[1] = op1;
  2019. + }
  2020. +
  2021. + if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
  2022. + {
  2023. + rtx op2;
  2024. +
  2025. + op2 = gen_reg_rtx (SImode);
  2026. + emit_move_insn (op2, operands[2]);
  2027. + operands[2] = op2;
  2028. + }
  2029. +
  2030. + acc_rtx = gen_reg_rtx (DImode);
  2031. + emit_insn (gen_umulsidi3 (acc_rtx, operands[1], operands[2]));
  2032. + emit_move_insn (operands[0], gen_lowpart (SImode, acc_rtx));
  2033. +
  2034. + return 1;
  2035. + }
  2036. +}
  2037. +
  2038. +/* Move the integer value VAL into OPERANDS[0]. */
  2039. +
  2040. +void
  2041. +ubicom32_emit_move_const_int (rtx dest, rtx imm)
  2042. +{
  2043. + rtx xoperands[2];
  2044. +
  2045. + xoperands[0] = dest;
  2046. + xoperands[1] = imm;
  2047. +
  2048. + /* Treat mem destinations separately. Values must be explicitly sign
  2049. + extended. */
  2050. + if (MEM_P (dest))
  2051. + {
  2052. + rtx low_hword_mem;
  2053. + rtx low_hword_addr;
  2054. +
  2055. + /* Emit shorter sequence for signed 7-bit quantities. */
  2056. + if (satisfies_constraint_I (imm))
  2057. + {
  2058. + output_asm_insn ("move.4\t%0, %1", xoperands);
  2059. + return;
  2060. + }
  2061. +
  2062. + /* Special case for pushing constants. */
  2063. + if (GET_CODE (XEXP (dest, 0)) == PRE_DEC
  2064. + && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
  2065. + {
  2066. + output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
  2067. + output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
  2068. + return;
  2069. + }
  2070. +
  2071. + /* See if we can add 2 to the original address. This is only
  2072. + possible if the original address is of the form REG or
  2073. + REG+const. */
  2074. + low_hword_addr = plus_constant (XEXP (dest, 0), 2);
  2075. + if (ubicom32_legitimate_address_p (HImode, low_hword_addr, 1))
  2076. + {
  2077. + low_hword_mem = gen_rtx_MEM (HImode, low_hword_addr);
  2078. + MEM_COPY_ATTRIBUTES (low_hword_mem, dest);
  2079. + output_asm_insn ("movei\t%0, #%%hi(%E1)", xoperands);
  2080. + xoperands[0] = low_hword_mem;
  2081. + output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
  2082. + return;
  2083. + }
  2084. +
  2085. + /* The original address is too complex. We need to use a
  2086. + scratch memory by (sp) and move that to the original
  2087. + destination. */
  2088. + if (! reg_mentioned_p (stack_pointer_rtx, dest))
  2089. + {
  2090. + output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
  2091. + output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
  2092. + output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
  2093. + return;
  2094. + }
  2095. +
  2096. + /* Our address mentions the stack pointer so we need to
  2097. + use our scratch data register here as well as scratch
  2098. + memory. */
  2099. + output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
  2100. + output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
  2101. + output_asm_insn ("move.4\td15, (sp)4++", xoperands);
  2102. + output_asm_insn ("move.4\t%0, d15", xoperands);
  2103. + return;
  2104. + }
  2105. +
  2106. + /* Move into registers are zero extended by default. */
  2107. + if (! REG_P (dest))
  2108. + abort ();
  2109. +
  2110. + if (satisfies_constraint_N (imm))
  2111. + {
  2112. + output_asm_insn ("movei\t%0, %1", xoperands);
  2113. + return;
  2114. + }
  2115. +
  2116. + if (INTVAL (xoperands[1]) >= 0xff80
  2117. + && INTVAL (xoperands[1]) < 0x10000)
  2118. + {
  2119. + xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 0x10000);
  2120. + output_asm_insn ("move.2\t%0, %1", xoperands);
  2121. + return;
  2122. + }
  2123. +
  2124. + if ((REGNO_REG_CLASS (REGNO (xoperands[0])) == ADDRESS_REGS
  2125. + || REGNO_REG_CLASS (REGNO (xoperands[0])) == FDPIC_REG)
  2126. + && ((INTVAL (xoperands[1]) & 0x80000000) == 0))
  2127. + {
  2128. + output_asm_insn ("moveai\t%0, #%%hi(%E1)", xoperands);
  2129. + if ((INTVAL (xoperands[1]) & 0x7f) != 0)
  2130. + output_asm_insn ("lea.1\t%0, %%lo(%E1)(%0)", xoperands);
  2131. + return;
  2132. + }
  2133. +
  2134. + if ((INTVAL (xoperands[1]) & 0xffff0000) == 0)
  2135. + {
  2136. + output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
  2137. + output_asm_insn ("move.2\t%0, %0", xoperands);
  2138. + return;
  2139. + }
  2140. +
  2141. + /* This is very expensive. The constant is so large that we
  2142. + need to use the stack to do the load. */
  2143. + output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
  2144. + output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
  2145. + output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
  2146. +}
  2147. +
  2148. +/* Stack layout. Prologue/Epilogue. */
  2149. +
  2150. +static int save_regs_size;
  2151. +
  2152. +static void
  2153. +ubicom32_layout_frame (void)
  2154. +{
  2155. + int regno;
  2156. +
  2157. + memset ((char *) &save_regs[0], 0, sizeof (save_regs));
  2158. + nregs = 0;
  2159. + frame_size = get_frame_size ();
  2160. +
  2161. + if (frame_pointer_needed || df_regs_ever_live_p (FRAME_POINTER_REGNUM))
  2162. + {
  2163. + save_regs[FRAME_POINTER_REGNUM] = 1;
  2164. + ++nregs;
  2165. + }
  2166. +
  2167. + if (current_function_is_leaf && ! df_regs_ever_live_p (LINK_REGNO))
  2168. + ubicom32_can_use_calli_to_ret = 1;
  2169. + else
  2170. + {
  2171. + ubicom32_can_use_calli_to_ret = 0;
  2172. + save_regs[LINK_REGNO] = 1;
  2173. + ++nregs;
  2174. + }
  2175. +
  2176. + /* Figure out which register(s) needs to be saved. */
  2177. + for (regno = 0; regno <= LAST_ADDRESS_REGNUM; regno++)
  2178. + if (df_regs_ever_live_p(regno)
  2179. + && ! call_used_regs[regno]
  2180. + && ! fixed_regs[regno]
  2181. + && ! save_regs[regno])
  2182. + {
  2183. + save_regs[regno] = 1;
  2184. + ++nregs;
  2185. + }
  2186. +
  2187. + save_regs_size = 4 * nregs;
  2188. +}
  2189. +
  2190. +static void
  2191. +ubicom32_emit_add_movsi (int regno, int adj)
  2192. +{
  2193. + rtx x;
  2194. + rtx reg = gen_rtx_REG (SImode, regno);
  2195. +
  2196. + adj += 4;
  2197. + if (adj > 8 * 4)
  2198. + {
  2199. + x = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
  2200. + GEN_INT (-adj)));
  2201. + RTX_FRAME_RELATED_P (x) = 1;
  2202. + x = emit_move_insn (gen_rtx_MEM (SImode, stack_pointer_rtx), reg);
  2203. + }
  2204. + else
  2205. + {
  2206. + rtx addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx,
  2207. + gen_rtx_PLUS (Pmode, stack_pointer_rtx,
  2208. + GEN_INT (-adj)));
  2209. + x = emit_move_insn (gen_rtx_MEM (SImode, addr), reg);
  2210. + }
  2211. + RTX_FRAME_RELATED_P (x) = 1;
  2212. +}
  2213. +
  2214. +void
  2215. +ubicom32_expand_prologue (void)
  2216. +{
  2217. + rtx x;
  2218. + int regno;
  2219. + int outgoing_args_size = crtl->outgoing_args_size;
  2220. + int adj;
  2221. +
  2222. + if (ubicom32_naked_function_p ())
  2223. + return;
  2224. +
  2225. + ubicom32_builtin_saveregs ();
  2226. +
  2227. + ubicom32_layout_frame ();
  2228. + adj = (outgoing_args_size + get_frame_size () + save_regs_size
  2229. + + crtl->args.pretend_args_size);
  2230. +
  2231. + if (!adj)
  2232. + ;
  2233. + else if (outgoing_args_size + save_regs_size < 508
  2234. + && get_frame_size () + save_regs_size > 508)
  2235. + {
  2236. + int i = 0;
  2237. + x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
  2238. + GEN_INT (-adj));
  2239. + x = emit_insn (x);
  2240. + RTX_FRAME_RELATED_P (x) = 1;
  2241. +
  2242. + for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
  2243. + if (save_regs[regno] && regno != LINK_REGNO)
  2244. + {
  2245. + x = gen_rtx_MEM (SImode,
  2246. + gen_rtx_PLUS (Pmode,
  2247. + stack_pointer_rtx,
  2248. + GEN_INT (i * 4 + outgoing_args_size)));
  2249. + x = emit_move_insn (x, gen_rtx_REG (SImode, regno));
  2250. + RTX_FRAME_RELATED_P (x) = 1;
  2251. + ++i;
  2252. + }
  2253. + if (save_regs[LINK_REGNO])
  2254. + {
  2255. + x = gen_rtx_MEM (SImode,
  2256. + gen_rtx_PLUS (Pmode,
  2257. + stack_pointer_rtx,
  2258. + GEN_INT (i * 4 + outgoing_args_size)));
  2259. + x = emit_move_insn (x, gen_rtx_REG (SImode, LINK_REGNO));
  2260. + RTX_FRAME_RELATED_P (x) = 1;
  2261. + }
  2262. + }
  2263. + else
  2264. + {
  2265. + int regno;
  2266. + int adj = get_frame_size () + crtl->args.pretend_args_size;
  2267. + int i = 0;
  2268. +
  2269. + if (save_regs[LINK_REGNO])
  2270. + {
  2271. + ubicom32_emit_add_movsi (LINK_REGNO, adj);
  2272. + ++i;
  2273. + }
  2274. +
  2275. + for (regno = 0; regno <= LAST_ADDRESS_REGNUM; ++regno)
  2276. + if (save_regs[regno] && regno != LINK_REGNO)
  2277. + {
  2278. + if (i)
  2279. + {
  2280. + rtx mem = gen_rtx_MEM (SImode,
  2281. + gen_rtx_PRE_DEC (Pmode,
  2282. + stack_pointer_rtx));
  2283. + x = emit_move_insn (mem, gen_rtx_REG (SImode, regno));
  2284. + RTX_FRAME_RELATED_P (x) = 1;
  2285. + }
  2286. + else
  2287. + ubicom32_emit_add_movsi (regno, adj);
  2288. + ++i;
  2289. + }
  2290. +
  2291. + if (outgoing_args_size || (!i && adj))
  2292. + {
  2293. + x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
  2294. + GEN_INT (-outgoing_args_size - (i ? 0 : adj)));
  2295. + x = emit_insn (x);
  2296. + RTX_FRAME_RELATED_P (x) = 1;
  2297. + }
  2298. + }
  2299. +
  2300. + if (frame_pointer_needed)
  2301. + {
  2302. + int fp_adj = save_regs_size + outgoing_args_size;
  2303. + x = gen_addsi3 (frame_pointer_rtx, stack_pointer_rtx,
  2304. + GEN_INT (fp_adj));
  2305. + x = emit_insn (x);
  2306. + RTX_FRAME_RELATED_P (x) = 1;
  2307. + }
  2308. +}
  2309. +
  2310. +void
  2311. +ubicom32_expand_epilogue (void)
  2312. +{
  2313. + rtx x;
  2314. + int regno;
  2315. + int outgoing_args_size = crtl->outgoing_args_size;
  2316. + int adj;
  2317. + int i;
  2318. +
  2319. + if (ubicom32_naked_function_p ())
  2320. + {
  2321. + emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode,
  2322. + LINK_REGNO)));
  2323. + return;
  2324. + }
  2325. +
  2326. + if (cfun->calls_alloca)
  2327. + {
  2328. + x = gen_addsi3 (stack_pointer_rtx, frame_pointer_rtx,
  2329. + GEN_INT (-save_regs_size));
  2330. + emit_insn (x);
  2331. + outgoing_args_size = 0;
  2332. + }
  2333. +
  2334. + if (outgoing_args_size)
  2335. + {
  2336. + x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
  2337. + GEN_INT (outgoing_args_size));
  2338. + emit_insn (x);
  2339. + }
  2340. +
  2341. + i = 0;
  2342. + for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
  2343. + if (save_regs[regno] && regno != LINK_REGNO)
  2344. + {
  2345. + x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
  2346. + emit_move_insn (gen_rtx_REG (SImode, regno), x);
  2347. + ++i;
  2348. + }
  2349. +
  2350. + /* Do we have to adjust the stack after we've finished restoring regs? */
  2351. + adj = get_frame_size() + crtl->args.pretend_args_size;
  2352. + if (cfun->stdarg)
  2353. + adj += UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
  2354. +
  2355. +#if 0
  2356. + if (crtl->calls_eh_return && 0)
  2357. + {
  2358. + if (save_regs[LINK_REGNO])
  2359. + {
  2360. + x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
  2361. + emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
  2362. + }
  2363. +
  2364. + if (adj)
  2365. + {
  2366. + x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
  2367. + GEN_INT (adj));
  2368. + x = emit_insn (x);
  2369. + }
  2370. +
  2371. + /* Perform the additional bump for __throw. */
  2372. + emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
  2373. + EH_RETURN_STACKADJ_RTX));
  2374. + emit_jump_insn (gen_eh_return_internal ());
  2375. + return;
  2376. + }
  2377. +#endif
  2378. +
  2379. + if (save_regs[LINK_REGNO])
  2380. + {
  2381. + if (adj >= 4 && adj <= (6 * 4))
  2382. + {
  2383. + x = GEN_INT (adj + 4);
  2384. + emit_jump_insn (gen_return_from_post_modify_sp (x));
  2385. + return;
  2386. + }
  2387. +
  2388. + if (adj == 0)
  2389. + {
  2390. + x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
  2391. + emit_jump_insn (gen_return_internal (x));
  2392. + return;
  2393. + }
  2394. +
  2395. + x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
  2396. + emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
  2397. + }
  2398. +
  2399. + if (adj)
  2400. + {
  2401. + x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
  2402. + GEN_INT (adj));
  2403. + x = emit_insn (x);
  2404. + adj = 0;
  2405. + }
  2406. +
  2407. + /* Given that we've just done all the hard work here we may as well use
  2408. + a calli to return. */
  2409. + ubicom32_can_use_calli_to_ret = 1;
  2410. + emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode, LINK_REGNO)));
  2411. +}
  2412. +
  2413. +void
  2414. +ubicom32_expand_call_fdpic (rtx *operands)
  2415. +{
  2416. + rtx c;
  2417. + rtx addr;
  2418. + rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
  2419. +
  2420. + addr = XEXP (operands[0], 0);
  2421. +
  2422. + c = gen_call_fdpic (addr, operands[1], fdpic_reg);
  2423. + emit_call_insn (c);
  2424. +}
  2425. +
  2426. +void
  2427. +ubicom32_expand_call_value_fdpic (rtx *operands)
  2428. +{
  2429. + rtx c;
  2430. + rtx addr;
  2431. + rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
  2432. +
  2433. + addr = XEXP (operands[1], 0);
  2434. +
  2435. + c = gen_call_value_fdpic (operands[0], addr, operands[2], fdpic_reg);
  2436. + emit_call_insn (c);
  2437. +}
  2438. +
  2439. +void
  2440. +ubicom32_expand_eh_return (rtx *operands)
  2441. +{
  2442. + if (REG_P (operands[0])
  2443. + || REGNO (operands[0]) != EH_RETURN_STACKADJ_REGNO)
  2444. + {
  2445. + rtx sp = EH_RETURN_STACKADJ_RTX;
  2446. + emit_move_insn (sp, operands[0]);
  2447. + operands[0] = sp;
  2448. + }
  2449. +
  2450. + if (REG_P (operands[1])
  2451. + || REGNO (operands[1]) != EH_RETURN_HANDLER_REGNO)
  2452. + {
  2453. + rtx ra = EH_RETURN_HANDLER_RTX;
  2454. + emit_move_insn (ra, operands[1]);
  2455. + operands[1] = ra;
  2456. + }
  2457. +}
  2458. +
  2459. +/* Compute the offsets between eliminable registers. */
  2460. +
  2461. +int
  2462. +ubicom32_initial_elimination_offset (int from, int to)
  2463. +{
  2464. + ubicom32_layout_frame ();
  2465. + if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
  2466. + return save_regs_size + crtl->outgoing_args_size;
  2467. +
  2468. + if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
  2469. + return get_frame_size ()/* + save_regs_size */;
  2470. +
  2471. + if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
  2472. + return get_frame_size ()
  2473. + + crtl->outgoing_args_size
  2474. + + save_regs_size;
  2475. +
  2476. + return 0;
  2477. +}
  2478. +
  2479. +/* Return 1 if it is appropriate to emit `ret' instructions in the
  2480. + body of a function. Do this only if the epilogue is simple, needing a
  2481. + couple of insns. Prior to reloading, we can't tell how many registers
  2482. + must be saved, so return 0 then. Return 0 if there is no frame
  2483. + marker to de-allocate.
  2484. +
  2485. + If NON_SAVING_SETJMP is defined and true, then it is not possible
  2486. + for the epilogue to be simple, so return 0. This is a special case
  2487. + since NON_SAVING_SETJMP will not cause regs_ever_live to change
  2488. + until final, but jump_optimize may need to know sooner if a
  2489. + `return' is OK. */
  2490. +
  2491. +int
  2492. +ubicom32_can_use_return_insn_p (void)
  2493. +{
  2494. + if (! reload_completed || frame_pointer_needed)
  2495. + return 0;
  2496. +
  2497. + return 1;
  2498. +}
  2499. +
  2500. +/* Attributes and CC handling. */
  2501. +
  2502. +/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
  2503. + struct attribute_spec.handler. */
  2504. +static tree
  2505. +ubicom32_handle_fndecl_attribute (tree *node, tree name,
  2506. + tree args ATTRIBUTE_UNUSED,
  2507. + int flags ATTRIBUTE_UNUSED,
  2508. + bool *no_add_attrs)
  2509. +{
  2510. + if (TREE_CODE (*node) != FUNCTION_DECL)
  2511. + {
  2512. + warning ("'%s' attribute only applies to functions",
  2513. + IDENTIFIER_POINTER (name));
  2514. + *no_add_attrs = true;
  2515. + }
  2516. +
  2517. + return NULL_TREE;
  2518. +}
  2519. +
  2520. +/* A C expression that places additional restrictions on the register class to
  2521. + use when it is necessary to copy value X into a register in class CLASS.
  2522. + The value is a register class; perhaps CLASS, or perhaps another, smaller
  2523. + class. On many machines, the following definition is safe:
  2524. +
  2525. + #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
  2526. +
  2527. + Sometimes returning a more restrictive class makes better code. For
  2528. + example, on the 68000, when X is an integer constant that is in range for a
  2529. + `moveq' instruction, the value of this macro is always `DATA_REGS' as long
  2530. + as CLASS includes the data registers. Requiring a data register guarantees
  2531. + that a `moveq' will be used.
  2532. +
  2533. + If X is a `const_double', by returning `NO_REGS' you can force X into a
  2534. + memory constant. This is useful on certain machines where immediate
  2535. + floating values cannot be loaded into certain kinds of registers. */
  2536. +
  2537. +enum reg_class
  2538. +ubicom32_preferred_reload_class (rtx x, enum reg_class class)
  2539. +{
  2540. + /* If a symbolic constant, HIGH or a PLUS is reloaded,
  2541. + it is most likely being used as an address, so
  2542. + prefer ADDRESS_REGS. If 'class' is not a superset
  2543. + of ADDRESS_REGS, e.g. DATA_REGS, then reject this reload. */
  2544. + if (GET_CODE (x) == PLUS
  2545. + || GET_CODE (x) == HIGH
  2546. + || GET_CODE (x) == LABEL_REF
  2547. + || GET_CODE (x) == SYMBOL_REF
  2548. + || GET_CODE (x) == CONST)
  2549. + {
  2550. + if (reg_class_subset_p (ALL_ADDRESS_REGS, class))
  2551. + return ALL_ADDRESS_REGS;
  2552. +
  2553. + return NO_REGS;
  2554. + }
  2555. +
  2556. + return class;
  2557. +}
  2558. +
  2559. +/* Function arguments and varargs. */
  2560. +
  2561. +int
  2562. +ubicom32_reg_parm_stack_space (tree fndecl)
  2563. +{
  2564. + return 0;
  2565. +
  2566. + if (fndecl
  2567. + && TYPE_ARG_TYPES (TREE_TYPE (fndecl)) != 0
  2568. + && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
  2569. + != void_type_node))
  2570. + return UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
  2571. +
  2572. + return 0;
  2573. +}
  2574. +
  2575. +/* Flush the argument registers to the stack for a stdarg function;
  2576. + return the new argument pointer. */
  2577. +
  2578. +rtx
  2579. +ubicom32_builtin_saveregs (void)
  2580. +{
  2581. + int regno;
  2582. +
  2583. + if (! cfun->stdarg)
  2584. + return 0;
  2585. +
  2586. + for (regno = UBICOM32_FUNCTION_ARG_REGS - 1; regno >= 0; --regno)
  2587. + emit_move_insn (gen_rtx_MEM (SImode,
  2588. + gen_rtx_PRE_DEC (SImode,
  2589. + stack_pointer_rtx)),
  2590. + gen_rtx_REG (SImode, regno));
  2591. +
  2592. + return stack_pointer_rtx;
  2593. +}
  2594. +
  2595. +void
  2596. +ubicom32_va_start (tree valist, rtx nextarg)
  2597. +{
  2598. + std_expand_builtin_va_start (valist, nextarg);
  2599. +}
  2600. +
  2601. +rtx
  2602. +ubicom32_va_arg (tree valist, tree type)
  2603. +{
  2604. + HOST_WIDE_INT size, rsize;
  2605. + tree addr, incr, tmp;
  2606. + rtx addr_rtx;
  2607. + int indirect = 0;
  2608. +
  2609. + /* Round up sizeof(type) to a word. */
  2610. + size = int_size_in_bytes (type);
  2611. + rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
  2612. +
  2613. + /* Large types are passed by reference. */
  2614. + if (size > 8)
  2615. + {
  2616. + indirect = 1;
  2617. + size = rsize = UNITS_PER_WORD;
  2618. + }
  2619. +
  2620. + incr = valist;
  2621. + addr = incr = save_expr (incr);
  2622. +
  2623. + /* FIXME Nat's version - is it correct? */
  2624. + tmp = fold_convert (ptr_type_node, size_int (rsize));
  2625. + tmp = build2 (PLUS_EXPR, ptr_type_node, incr, tmp);
  2626. + incr = fold (tmp);
  2627. +
  2628. + /* FIXME Nat's version - is it correct? */
  2629. + incr = build2 (MODIFY_EXPR, ptr_type_node, valist, incr);
  2630. +
  2631. + TREE_SIDE_EFFECTS (incr) = 1;
  2632. + expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL);
  2633. +
  2634. + addr_rtx = expand_expr (addr, NULL, Pmode, EXPAND_NORMAL);
  2635. +
  2636. + if (size < UNITS_PER_WORD)
  2637. + emit_insn (gen_addsi3 (addr_rtx, addr_rtx,
  2638. + GEN_INT (UNITS_PER_WORD - size)));
  2639. +
  2640. + if (indirect)
  2641. + {
  2642. + addr_rtx = force_reg (Pmode, addr_rtx);
  2643. + addr_rtx = gen_rtx_MEM (Pmode, addr_rtx);
  2644. + set_mem_alias_set (addr_rtx, get_varargs_alias_set ());
  2645. + }
  2646. +
  2647. + return addr_rtx;
  2648. +}
  2649. +
  2650. +void
  2651. +init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
  2652. + int indirect ATTRIBUTE_UNUSED)
  2653. +{
  2654. + cum->nbytes = 0;
  2655. +
  2656. + if (!libname)
  2657. + {
  2658. + cum->stdarg = (TYPE_ARG_TYPES (fntype) != 0
  2659. + && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
  2660. + != void_type_node));
  2661. + }
  2662. +}
  2663. +
  2664. +/* Return an RTX to represent where a value in mode MODE will be passed
  2665. + to a function. If the result is 0, the argument will be pushed. */
  2666. +
  2667. +rtx
  2668. +function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
  2669. + int named ATTRIBUTE_UNUSED)
  2670. +{
  2671. + rtx result = 0;
  2672. + int size, align;
  2673. + int nregs = UBICOM32_FUNCTION_ARG_REGS;
  2674. +
  2675. + /* Figure out the size of the object to be passed. */
  2676. + if (mode == BLKmode)
  2677. + size = int_size_in_bytes (type);
  2678. + else
  2679. + size = GET_MODE_SIZE (mode);
  2680. +
  2681. + /* Figure out the alignment of the object to be passed. */
  2682. + align = size;
  2683. +
  2684. + cum->nbytes = (cum->nbytes + 3) & ~3;
  2685. +
  2686. + /* Don't pass this arg via a register if all the argument registers
  2687. + are used up. */
  2688. + if (cum->nbytes >= nregs * UNITS_PER_WORD)
  2689. + return 0;
  2690. +
  2691. + /* Don't pass this arg via a register if it would be split between
  2692. + registers and memory. */
  2693. + result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
  2694. +
  2695. + return result;
  2696. +}
  2697. +
  2698. +rtx
  2699. +function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
  2700. + int named ATTRIBUTE_UNUSED)
  2701. +{
  2702. + if (cfun->stdarg)
  2703. + return 0;
  2704. +
  2705. + return function_arg (cum, mode, type, named);
  2706. +}
  2707. +
  2708. +
  2709. +/* Implement hook TARGET_ARG_PARTIAL_BYTES.
  2710. +
  2711. + Returns the number of bytes at the beginning of an argument that
  2712. + must be put in registers. The value must be zero for arguments
  2713. + that are passed entirely in registers or that are entirely pushed
  2714. + on the stack. */
  2715. +static int
  2716. +ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
  2717. + tree type, bool named ATTRIBUTE_UNUSED)
  2718. +{
  2719. + int size, diff;
  2720. +
  2721. + int nregs = UBICOM32_FUNCTION_ARG_REGS;
  2722. +
  2723. + /* round up to full word */
  2724. + cum->nbytes = (cum->nbytes + 3) & ~3;
  2725. +
  2726. + if (targetm.calls.pass_by_reference (cum, mode, type, named))
  2727. + return 0;
  2728. +
  2729. + /* number of bytes left in registers */
  2730. + diff = nregs*UNITS_PER_WORD - cum->nbytes;
  2731. +
  2732. + /* regs all used up */
  2733. + if (diff <= 0)
  2734. + return 0;
  2735. +
  2736. + /* Figure out the size of the object to be passed. */
  2737. + if (mode == BLKmode)
  2738. + size = int_size_in_bytes (type);
  2739. + else
  2740. + size = GET_MODE_SIZE (mode);
  2741. +
  2742. + /* enough space left in regs for size */
  2743. + if (size <= diff)
  2744. + return 0;
  2745. +
  2746. + /* put diff bytes in regs and rest on stack */
  2747. + return diff;
  2748. +
  2749. +}
  2750. +
  2751. +static bool
  2752. +ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
  2753. + enum machine_mode mode, const_tree type,
  2754. + bool named ATTRIBUTE_UNUSED)
  2755. +{
  2756. + int size;
  2757. +
  2758. + if (type)
  2759. + size = int_size_in_bytes (type);
  2760. + else
  2761. + size = GET_MODE_SIZE (mode);
  2762. +
  2763. + return size <= 0 || size > 8;
  2764. +}
  2765. +
  2766. +static bool
  2767. +ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
  2768. + enum machine_mode mode, const_tree type,
  2769. + bool named ATTRIBUTE_UNUSED)
  2770. +{
  2771. + int size;
  2772. +
  2773. + if (type)
  2774. + size = int_size_in_bytes (type);
  2775. + else
  2776. + size = GET_MODE_SIZE (mode);
  2777. +
  2778. + return size <= 0 || size > 8;
  2779. +}
  2780. +
  2781. +static bool
  2782. +ubicom32_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
  2783. +{
  2784. + int size, mode;
  2785. +
  2786. + if (!type)
  2787. + return true;
  2788. +
  2789. + size = int_size_in_bytes(type);
  2790. + if (size > 8)
  2791. + return true;
  2792. +
  2793. + mode = TYPE_MODE(type);
  2794. + if (mode == BLKmode)
  2795. + return true;
  2796. +
  2797. + return false;
  2798. +}
  2799. +
  2800. +/* Return true if a given register number REGNO is acceptable for machine
  2801. + mode MODE. */
  2802. +bool
  2803. +ubicom32_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
  2804. +{
  2805. + /* If we're not at least a v3 ISA then ACC0_HI is only 16 bits. */
  2806. + if (! ubicom32_v3)
  2807. + {
  2808. + if (regno == ACC0_HI_REGNUM)
  2809. + return (mode == QImode || mode == HImode);
  2810. + }
  2811. +
  2812. + /* Only the flags reg can hold CCmode. */
  2813. + if (GET_MODE_CLASS (mode) == MODE_CC)
  2814. + return regno == CC_REGNUM;
  2815. +
  2816. + /* We restrict the choice of DImode registers to only being address,
  2817. + data or accumulator regs. We also restrict them to only start on
  2818. + even register numbers so we never have to worry about partial
  2819. + overlaps between operands in instructions. */
  2820. + if (GET_MODE_SIZE (mode) > 4)
  2821. + {
  2822. + switch (REGNO_REG_CLASS (regno))
  2823. + {
  2824. + case ADDRESS_REGS:
  2825. + case DATA_REGS:
  2826. + case ACC_REGS:
  2827. + return (regno & 1) == 0;
  2828. +
  2829. + default:
  2830. + return false;
  2831. + }
  2832. + }
  2833. +
  2834. + return true;
  2835. +}
  2836. +
  2837. +/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
  2838. + and check its validity for a certain class.
  2839. + We have two alternate definitions for each of them.
  2840. + The usual definition accepts all pseudo regs; the other rejects
  2841. + them unless they have been allocated suitable hard regs.
  2842. + The symbol REG_OK_STRICT causes the latter definition to be used.
  2843. +
  2844. + Most source files want to accept pseudo regs in the hope that
  2845. + they will get allocated to the class that the insn wants them to be in.
  2846. + Source files for reload pass need to be strict.
  2847. + After reload, it makes no difference, since pseudo regs have
  2848. + been eliminated by then.
  2849. +
  2850. + These assume that REGNO is a hard or pseudo reg number.
  2851. + They give nonzero only if REGNO is a hard reg of the suitable class
  2852. + or a pseudo reg currently allocated to a suitable hard reg.
  2853. + Since they use reg_renumber, they are safe only once reg_renumber
  2854. + has been allocated, which happens in local-alloc.c. */
  2855. +
  2856. +int
  2857. +ubicom32_regno_ok_for_base_p (int regno, int strict)
  2858. +{
  2859. + if ((regno >= FIRST_ADDRESS_REGNUM && regno <= STACK_POINTER_REGNUM)
  2860. + || (!strict
  2861. + && (regno >= FIRST_PSEUDO_REGISTER
  2862. + || regno == ARG_POINTER_REGNUM))
  2863. + || (strict && (reg_renumber
  2864. + && reg_renumber[regno] >= FIRST_ADDRESS_REGNUM
  2865. + && reg_renumber[regno] <= STACK_POINTER_REGNUM)))
  2866. + return 1;
  2867. +
  2868. + return 0;
  2869. +}
  2870. +
  2871. +int
  2872. +ubicom32_regno_ok_for_index_p (int regno, int strict)
  2873. +{
  2874. + if ((regno >= FIRST_DATA_REGNUM && regno <= LAST_DATA_REGNUM)
  2875. + || (!strict && regno >= FIRST_PSEUDO_REGISTER)
  2876. + || (strict && (reg_renumber
  2877. + && reg_renumber[regno] >= FIRST_DATA_REGNUM
  2878. + && reg_renumber[regno] <= LAST_DATA_REGNUM)))
  2879. + return 1;
  2880. +
  2881. + return 0;
  2882. +}
  2883. +
  2884. +/* Returns 1 if X is a valid index register. STRICT is 1 if only hard
  2885. + registers should be accepted. Accept either REG or SUBREG where a
  2886. + register is valid. */
  2887. +
  2888. +static bool
  2889. +ubicom32_is_index_reg (rtx x, int strict)
  2890. +{
  2891. + if ((REG_P (x) && ubicom32_regno_ok_for_index_p (REGNO (x), strict))
  2892. + || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
  2893. + && ubicom32_regno_ok_for_index_p (REGNO (SUBREG_REG (x)), strict)))
  2894. + return true;
  2895. +
  2896. + return false;
  2897. +}
  2898. +
  2899. +/* Return 1 if X is a valid index for a memory address. */
  2900. +
  2901. +static bool
  2902. +ubicom32_is_index_expr (enum machine_mode mode, rtx x, int strict)
  2903. +{
  2904. + /* Immediate index must be an unsigned 7-bit offset multiple of 1, 2
  2905. + or 4 depending on mode. */
  2906. + if (CONST_INT_P (x))
  2907. + {
  2908. + switch (mode)
  2909. + {
  2910. + case QImode:
  2911. + return satisfies_constraint_J (x);
  2912. +
  2913. + case HImode:
  2914. + return satisfies_constraint_K (x);
  2915. +
  2916. + case SImode:
  2917. + case SFmode:
  2918. + return satisfies_constraint_L (x);
  2919. +
  2920. + case DImode:
  2921. + return satisfies_constraint_L (x)
  2922. + && satisfies_constraint_L (GEN_INT (INTVAL (x) + 4));
  2923. +
  2924. + default:
  2925. + return false;
  2926. + }
  2927. + }
  2928. +
  2929. + if (mode != SImode && mode != HImode && mode != QImode)
  2930. + return false;
  2931. +
  2932. + /* Register index scaled by mode of operand: REG + REG * modesize.
  2933. + Valid scaled index registers are:
  2934. +
  2935. + SImode (mult (dreg) 4))
  2936. + HImode (mult (dreg) 2))
  2937. + QImode (mult (dreg) 1)) */
  2938. + if (GET_CODE (x) == MULT
  2939. + && ubicom32_is_index_reg (XEXP (x, 0), strict)
  2940. + && CONST_INT_P (XEXP (x, 1))
  2941. + && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT)GET_MODE_SIZE (mode))
  2942. + return true;
  2943. +
  2944. + /* REG + REG addressing is allowed for QImode. */
  2945. + if (ubicom32_is_index_reg (x, strict) && mode == QImode)
  2946. + return true;
  2947. +
  2948. + return false;
  2949. +}
  2950. +
  2951. +static bool
  2952. +ubicom32_is_valid_offset (enum machine_mode mode, HOST_WIDE_INT offs)
  2953. +{
  2954. + if (offs < 0)
  2955. + return false;
  2956. +
  2957. + switch (mode)
  2958. + {
  2959. + case QImode:
  2960. + return offs <= 127;
  2961. +
  2962. + case HImode:
  2963. + return offs <= 254;
  2964. +
  2965. + case SImode:
  2966. + case SFmode:
  2967. + return offs <= 508;
  2968. +
  2969. + case DImode:
  2970. + return offs <= 504;
  2971. +
  2972. + default:
  2973. + return false;
  2974. + }
  2975. +}
  2976. +
  2977. +static int
  2978. +ubicom32_get_valid_offset_mask (enum machine_mode mode)
  2979. +{
  2980. + switch (mode)
  2981. + {
  2982. + case QImode:
  2983. + return 127;
  2984. +
  2985. + case HImode:
  2986. + return 255;
  2987. +
  2988. + case SImode:
  2989. + case SFmode:
  2990. + return 511;
  2991. +
  2992. + case DImode:
  2993. + return 255;
  2994. +
  2995. + default:
  2996. + return 0;
  2997. + }
  2998. +}
  2999. +
  3000. +/* Returns 1 if X is a valid base register. STRICT is 1 if only hard
  3001. + registers should be accepted. Accept either REG or SUBREG where a
  3002. + register is valid. */
  3003. +
  3004. +static bool
  3005. +ubicom32_is_base_reg (rtx x, int strict)
  3006. +{
  3007. + if ((REG_P (x) && ubicom32_regno_ok_for_base_p (REGNO (x), strict))
  3008. + || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
  3009. + && ubicom32_regno_ok_for_base_p (REGNO (SUBREG_REG (x)), strict)))
  3010. + return true;
  3011. +
  3012. + return false;
  3013. +}
  3014. +
  3015. +static bool
  3016. +ubicom32_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
  3017. +{
  3018. + return TARGET_FDPIC;
  3019. +}
  3020. +
  3021. +/* Determine if X is a legitimate constant. */
  3022. +
  3023. +bool
  3024. +ubicom32_legitimate_constant_p (rtx x)
  3025. +{
  3026. + /* Among its other duties, LEGITIMATE_CONSTANT_P decides whether
  3027. + a constant can be entered into reg_equiv_constant[]. If we return true,
  3028. + reload can create new instances of the constant whenever it likes.
  3029. +
  3030. + The idea is therefore to accept as many constants as possible (to give
  3031. + reload more freedom) while rejecting constants that can only be created
  3032. + at certain times. In particular, anything with a symbolic component will
  3033. + require use of the pseudo FDPIC register, which is only available before
  3034. + reload. */
  3035. + if (TARGET_FDPIC)
  3036. + {
  3037. + if (GET_CODE (x) == SYMBOL_REF
  3038. + || (GET_CODE (x) == CONST
  3039. + && GET_CODE (XEXP (x, 0)) == PLUS
  3040. + && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
  3041. + || CONSTANT_ADDRESS_P (x))
  3042. + return false;
  3043. +
  3044. + return true;
  3045. + }
  3046. +
  3047. + /* For non-PIC code anything goes! */
  3048. + return true;
  3049. +}
  3050. +
  3051. +/* Address validation. */
  3052. +
  3053. +bool
  3054. +ubicom32_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
  3055. +{
  3056. + if (TARGET_DEBUG_ADDRESS)
  3057. + {
  3058. + fprintf (stderr, "\n==> GO_IF_LEGITIMATE_ADDRESS%s\n",
  3059. + (strict) ? " (STRICT)" : "");
  3060. + debug_rtx (x);
  3061. + }
  3062. +
  3063. + if (CONSTANT_ADDRESS_P (x))
  3064. + return false;
  3065. +
  3066. + if (ubicom32_is_base_reg (x, strict))
  3067. + return true;
  3068. +
  3069. + if ((GET_CODE (x) == POST_INC
  3070. + || GET_CODE (x) == PRE_INC
  3071. + || GET_CODE (x) == POST_DEC
  3072. + || GET_CODE (x) == PRE_DEC)
  3073. + && REG_P (XEXP (x, 0))
  3074. + && ubicom32_is_base_reg (XEXP (x, 0), strict)
  3075. + && mode != DImode)
  3076. + return true;
  3077. +
  3078. + if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
  3079. + && ubicom32_is_base_reg (XEXP (x, 0), strict)
  3080. + && GET_CODE (XEXP (x, 1)) == PLUS
  3081. + && rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0))
  3082. + && CONST_INT_P (XEXP (XEXP (x, 1), 1))
  3083. + && mode != DImode)
  3084. + {
  3085. + HOST_WIDE_INT disp = INTVAL (XEXP (XEXP (x, 1), 1));
  3086. + switch (mode)
  3087. + {
  3088. + case QImode:
  3089. + return disp >= -8 && disp <= 7;
  3090. +
  3091. + case HImode:
  3092. + return disp >= -16 && disp <= 14 && ! (disp & 1);
  3093. +
  3094. + case SImode:
  3095. + return disp >= -32 && disp <= 28 && ! (disp & 3);
  3096. +
  3097. + default:
  3098. + return false;
  3099. + }
  3100. + }
  3101. +
  3102. + /* Accept base + index * scale. */
  3103. + if (GET_CODE (x) == PLUS
  3104. + && ubicom32_is_base_reg (XEXP (x, 0), strict)
  3105. + && ubicom32_is_index_expr (mode, XEXP (x, 1), strict))
  3106. + return true;
  3107. +
  3108. + /* Accept index * scale + base. */
  3109. + if (GET_CODE (x) == PLUS
  3110. + && ubicom32_is_base_reg (XEXP (x, 1), strict)
  3111. + && ubicom32_is_index_expr (mode, XEXP (x, 0), strict))
  3112. + return true;
  3113. +
  3114. + if (! TARGET_FDPIC)
  3115. + {
  3116. + /* Accept (lo_sum (reg) (symbol_ref)) that can be used as a mem+7bits
  3117. + displacement operand:
  3118. +
  3119. + moveai a1, #%hi(SYM)
  3120. + move.4 d3, %lo(SYM)(a1) */
  3121. + if (GET_CODE (x) == LO_SUM
  3122. + && ubicom32_is_base_reg (XEXP (x, 0), strict)
  3123. + && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
  3124. + || GET_CODE (XEXP (x, 1)) == LABEL_REF /* FIXME: wrong */)
  3125. + && mode != DImode)
  3126. + return true;
  3127. + }
  3128. +
  3129. + if (TARGET_DEBUG_ADDRESS)
  3130. + fprintf (stderr, "\nNot a legitimate address.\n");
  3131. +
  3132. + return false;
  3133. +}
  3134. +
  3135. +rtx
  3136. +ubicom32_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
  3137. + enum machine_mode mode)
  3138. +{
  3139. + if (mode == BLKmode)
  3140. + return NULL_RTX;
  3141. +
  3142. + if (GET_CODE (x) == PLUS
  3143. + && REG_P (XEXP (x, 0))
  3144. + && ! REGNO_PTR_FRAME_P (REGNO (XEXP (x, 0)))
  3145. + && CONST_INT_P (XEXP (x, 1))
  3146. + && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (x, 1))))
  3147. + {
  3148. + rtx base;
  3149. + rtx plus;
  3150. + rtx new_rtx;
  3151. + HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
  3152. + HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
  3153. + HOST_WIDE_INT high = val ^ low;
  3154. +
  3155. + if (val < 0)
  3156. + return NULL_RTX;
  3157. +
  3158. + if (! low)
  3159. + return NULL_RTX;
  3160. +
  3161. + /* Reload the high part into a base reg; leave the low part
  3162. + in the mem directly. */
  3163. + base = XEXP (x, 0);
  3164. + if (! ubicom32_is_base_reg (base, 0))
  3165. + base = copy_to_mode_reg (Pmode, base);
  3166. +
  3167. + plus = expand_simple_binop (Pmode, PLUS,
  3168. + gen_int_mode (high, Pmode),
  3169. + base, NULL, 0, OPTAB_WIDEN);
  3170. + new_rtx = plus_constant (plus, low);
  3171. +
  3172. + return new_rtx;
  3173. + }
  3174. +
  3175. + return NULL_RTX;
  3176. +}
  3177. +
  3178. +/* Try a machine-dependent way of reloading an illegitimate address AD
  3179. + operand. If we find one, push the reload and and return the new address.
  3180. +
  3181. + MODE is the mode of the enclosing MEM. OPNUM is the operand number
  3182. + and TYPE is the reload type of the current reload. */
  3183. +
  3184. +rtx
  3185. +ubicom32_legitimize_reload_address (rtx ad, enum machine_mode mode,
  3186. + int opnum, int type)
  3187. +{
  3188. + /* Is this an address that we've already fixed up? If it is then
  3189. + recognize it and move on. */
  3190. + if (GET_CODE (ad) == PLUS
  3191. + && GET_CODE (XEXP (ad, 0)) == PLUS
  3192. + && REG_P (XEXP (XEXP (ad, 0), 0))
  3193. + && CONST_INT_P (XEXP (XEXP (ad, 0), 1))
  3194. + && CONST_INT_P (XEXP (ad, 1)))
  3195. + {
  3196. + push_reload (XEXP (ad, 0), NULL_RTX, &XEXP (ad, 0), NULL,
  3197. + BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
  3198. + opnum, (enum reload_type) type);
  3199. + return ad;
  3200. + }
  3201. +
  3202. + /* Have we got an address where the offset is simply out of range? If
  3203. + yes then reload the range as a high part and smaller offset. */
  3204. + if (GET_CODE (ad) == PLUS
  3205. + && REG_P (XEXP (ad, 0))
  3206. + && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
  3207. + && REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0)))
  3208. + && CONST_INT_P (XEXP (ad, 1))
  3209. + && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (ad, 1))))
  3210. + {
  3211. + rtx temp;
  3212. + rtx new_rtx;
  3213. +
  3214. + HOST_WIDE_INT val = INTVAL (XEXP (ad, 1));
  3215. + HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
  3216. + HOST_WIDE_INT high = val ^ low;
  3217. +
  3218. + /* Reload the high part into a base reg; leave the low part
  3219. + in the mem directly. */
  3220. + temp = gen_rtx_PLUS (Pmode, XEXP (ad, 0), GEN_INT (high));
  3221. + new_rtx = gen_rtx_PLUS (Pmode, temp, GEN_INT (low));
  3222. +
  3223. + push_reload (XEXP (new_rtx, 0), NULL_RTX, &XEXP (new_rtx, 0), NULL,
  3224. + BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
  3225. + opnum, (enum reload_type) type);
  3226. + return new_rtx;
  3227. + }
  3228. +
  3229. + /* If we're presented with an pre/post inc/dec then we must force this
  3230. + to be done in an address register. The register allocator should
  3231. + work this out for itself but at times ends up trying to use the wrong
  3232. + class. If we get the wrong class then reload will end up generating
  3233. + at least 3 instructions whereas this way we can hopefully keep it to
  3234. + just 2. */
  3235. + if ((GET_CODE (ad) == POST_INC
  3236. + || GET_CODE (ad) == PRE_INC
  3237. + || GET_CODE (ad) == POST_DEC
  3238. + || GET_CODE (ad) == PRE_DEC)
  3239. + && REG_P (XEXP (ad, 0))
  3240. + && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
  3241. + && ! REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0))))
  3242. + {
  3243. + push_reload (XEXP (ad, 0), XEXP (ad, 0), &XEXP (ad, 0), &XEXP (ad, 0),
  3244. + BASE_REG_CLASS, GET_MODE (XEXP (ad, 0)), GET_MODE (XEXP (ad, 0)), 0, 0,
  3245. + opnum, RELOAD_OTHER);
  3246. + return ad;
  3247. + }
  3248. +
  3249. + return NULL_RTX;
  3250. +}
  3251. +
  3252. +/* Compute a (partial) cost for rtx X. Return true if the complete
  3253. + cost has been computed, and false if subexpressions should be
  3254. + scanned. In either case, *TOTAL contains the cost result. */
  3255. +
  3256. +static bool
  3257. +ubicom32_rtx_costs (rtx x, int code, int outer_code, int *total,
  3258. + bool speed ATTRIBUTE_UNUSED)
  3259. +{
  3260. + enum machine_mode mode = GET_MODE (x);
  3261. +
  3262. + switch (code)
  3263. + {
  3264. + case CONST_INT:
  3265. + /* Very short constants often fold into instructions so
  3266. + we pretend that they don't cost anything! This is
  3267. + really important as regards zero values as otherwise
  3268. + the compiler has a nasty habit of wanting to reuse
  3269. + zeroes that are in regs but that tends to pessimize
  3270. + the code. */
  3271. + if (satisfies_constraint_I (x))
  3272. + {
  3273. + *total = 0;
  3274. + return true;
  3275. + }
  3276. +
  3277. + /* Bit clearing costs nothing */
  3278. + if (outer_code == AND
  3279. + && exact_log2 (~INTVAL (x)) != -1)
  3280. + {
  3281. + *total = 0;
  3282. + return true;
  3283. + }
  3284. +
  3285. + /* Masking the lower set of bits costs nothing. */
  3286. + if (outer_code == AND
  3287. + && exact_log2 (INTVAL (x) + 1) != -1)
  3288. + {
  3289. + *total = 0;
  3290. + return true;
  3291. + }
  3292. +
  3293. + /* Bit setting costs nothing. */
  3294. + if (outer_code == IOR
  3295. + && exact_log2 (INTVAL (x)) != -1)
  3296. + {
  3297. + *total = 0;
  3298. + return true;
  3299. + }
  3300. +
  3301. + /* Larger constants that can be loaded via movei aren't too
  3302. + bad. If we're just doing a set they cost nothing extra. */
  3303. + if (satisfies_constraint_N (x))
  3304. + {
  3305. + if (mode == DImode)
  3306. + *total = COSTS_N_INSNS (2);
  3307. + else
  3308. + *total = COSTS_N_INSNS (1);
  3309. + return true;
  3310. + }
  3311. +
  3312. + if (mode == DImode)
  3313. + *total = COSTS_N_INSNS (5);
  3314. + else
  3315. + *total = COSTS_N_INSNS (3);
  3316. + return true;
  3317. +
  3318. + case CONST_DOUBLE:
  3319. + /* We don't optimize CONST_DOUBLEs well nor do we relax them well,
  3320. + so their cost is very high. */
  3321. + *total = COSTS_N_INSNS (6);
  3322. + return true;
  3323. +
  3324. + case CONST:
  3325. + case SYMBOL_REF:
  3326. + case MEM:
  3327. + *total = 0;
  3328. + return true;
  3329. +
  3330. + case IF_THEN_ELSE:
  3331. + *total = COSTS_N_INSNS (1);
  3332. + return true;
  3333. +
  3334. + case LABEL_REF:
  3335. + case HIGH:
  3336. + case LO_SUM:
  3337. + case BSWAP:
  3338. + case PLUS:
  3339. + case MINUS:
  3340. + case AND:
  3341. + case IOR:
  3342. + case XOR:
  3343. + case ASHIFT:
  3344. + case ASHIFTRT:
  3345. + case LSHIFTRT:
  3346. + case NEG:
  3347. + case NOT:
  3348. + case SIGN_EXTEND:
  3349. + case ZERO_EXTEND:
  3350. + case ZERO_EXTRACT:
  3351. + if (outer_code == SET)
  3352. + {
  3353. + if (mode == DImode)
  3354. + *total = COSTS_N_INSNS (2);
  3355. + else
  3356. + *total = COSTS_N_INSNS (1);
  3357. + }
  3358. + return true;
  3359. +
  3360. + case COMPARE:
  3361. + if (outer_code == SET)
  3362. + {
  3363. + if (GET_MODE (XEXP (x, 0)) == DImode
  3364. + || GET_MODE (XEXP (x, 1)) == DImode)
  3365. + *total = COSTS_N_INSNS (2);
  3366. + else
  3367. + *total = COSTS_N_INSNS (1);
  3368. + }
  3369. + return true;
  3370. +
  3371. + case UMOD:
  3372. + case UDIV:
  3373. + case MOD:
  3374. + case DIV:
  3375. + if (outer_code == SET)
  3376. + {
  3377. + if (mode == DImode)
  3378. + *total = COSTS_N_INSNS (600);
  3379. + else
  3380. + *total = COSTS_N_INSNS (200);
  3381. + }
  3382. + return true;
  3383. +
  3384. + case MULT:
  3385. + if (outer_code == SET)
  3386. + {
  3387. + if (! ubicom32_v4)
  3388. + {
  3389. + if (mode == DImode)
  3390. + *total = COSTS_N_INSNS (15);
  3391. + else
  3392. + *total = COSTS_N_INSNS (5);
  3393. + }
  3394. + else
  3395. + {
  3396. + if (mode == DImode)
  3397. + *total = COSTS_N_INSNS (6);
  3398. + else
  3399. + *total = COSTS_N_INSNS (2);
  3400. + }
  3401. + }
  3402. + return true;
  3403. +
  3404. + case UNSPEC:
  3405. + if (XINT (x, 1) == UNSPEC_FDPIC_GOT
  3406. + || XINT (x, 1) == UNSPEC_FDPIC_GOT_FUNCDESC)
  3407. + *total = 0;
  3408. + return true;
  3409. +
  3410. + default:
  3411. + return false;
  3412. + }
  3413. +}
  3414. +
  3415. +/* Return 1 if ADDR can have different meanings depending on the machine
  3416. + mode of the memory reference it is used for or if the address is
  3417. + valid for some modes but not others.
  3418. +
  3419. + Autoincrement and autodecrement addresses typically have
  3420. + mode-dependent effects because the amount of the increment or
  3421. + decrement is the size of the operand being addressed. Some machines
  3422. + have other mode-dependent addresses. Many RISC machines have no
  3423. + mode-dependent addresses.
  3424. +
  3425. + You may assume that ADDR is a valid address for the machine. */
  3426. +
  3427. +int
  3428. +ubicom32_mode_dependent_address_p (rtx addr)
  3429. +{
  3430. + if (GET_CODE (addr) == POST_INC
  3431. + || GET_CODE (addr) == PRE_INC
  3432. + || GET_CODE (addr) == POST_DEC
  3433. + || GET_CODE (addr) == PRE_DEC
  3434. + || GET_CODE (addr) == POST_MODIFY
  3435. + || GET_CODE (addr) == PRE_MODIFY)
  3436. + return 1;
  3437. +
  3438. + return 0;
  3439. +}
  3440. +
  3441. +static void
  3442. +ubicom32_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
  3443. +{
  3444. + fprintf (file, "/* frame/pretend: %ld/%d save_regs: %d out_args: %d %s */\n",
  3445. + get_frame_size (), crtl->args.pretend_args_size,
  3446. + save_regs_size, crtl->outgoing_args_size,
  3447. + current_function_is_leaf ? "leaf" : "nonleaf");
  3448. +}
  3449. +
  3450. +static void
  3451. +ubicom32_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
  3452. + HOST_WIDE_INT size ATTRIBUTE_UNUSED)
  3453. +{
  3454. + ubicom32_reorg_completed = 0;
  3455. +}
  3456. +
  3457. +static void
  3458. +ubicom32_machine_dependent_reorg (void)
  3459. +{
  3460. +#if 0 /* Commenting out this optimization until it is fixed */
  3461. + if (optimize)
  3462. + {
  3463. + compute_bb_for_insn ();
  3464. +
  3465. + /* Do a very simple CSE pass over just the hard registers. */
  3466. + reload_cse_regs (get_insns ());
  3467. +
  3468. + /* Reload_cse_regs can eliminate potentially-trapping MEMs.
  3469. + Remove any EH edges associated with them. */
  3470. + if (flag_non_call_exceptions)
  3471. + purge_all_dead_edges ();
  3472. + }
  3473. +#endif
  3474. + ubicom32_reorg_completed = 1;
  3475. +}
  3476. +
  3477. +void
  3478. +ubicom32_output_cond_jump (rtx insn, rtx cond, rtx target)
  3479. +{
  3480. + rtx note;
  3481. + int mostly_false_jump;
  3482. + rtx xoperands[2];
  3483. + rtx cc_reg;
  3484. +
  3485. + note = find_reg_note (insn, REG_BR_PROB, 0);
  3486. + mostly_false_jump = !note || (INTVAL (XEXP (note, 0))
  3487. + <= REG_BR_PROB_BASE / 2);
  3488. +
  3489. + xoperands[0] = target;
  3490. + xoperands[1] = cond;
  3491. + cc_reg = XEXP (cond, 0);
  3492. +
  3493. + if (GET_MODE (cc_reg) == CCWmode
  3494. + || GET_MODE (cc_reg) == CCWZmode
  3495. + || GET_MODE (cc_reg) == CCWZNmode)
  3496. + {
  3497. + if (mostly_false_jump)
  3498. + output_asm_insn ("jmp%b1.w.f\t%0", xoperands);
  3499. + else
  3500. + output_asm_insn ("jmp%b1.w.t\t%0", xoperands);
  3501. + return;
  3502. + }
  3503. +
  3504. + if (GET_MODE (cc_reg) == CCSmode
  3505. + || GET_MODE (cc_reg) == CCSZmode
  3506. + || GET_MODE (cc_reg) == CCSZNmode)
  3507. + {
  3508. + if (mostly_false_jump)
  3509. + output_asm_insn ("jmp%b1.s.f\t%0", xoperands);
  3510. + else
  3511. + output_asm_insn ("jmp%b1.s.t\t%0", xoperands);
  3512. + return;
  3513. + }
  3514. +
  3515. + abort ();
  3516. +}
  3517. +
  3518. +/* Return non-zero if FUNC is a naked function. */
  3519. +
  3520. +static int
  3521. +ubicom32_naked_function_p (void)
  3522. +{
  3523. + return lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE;
  3524. +}
  3525. +
  3526. +/* Return an RTX indicating where the return address to the
  3527. + calling function can be found. */
  3528. +rtx
  3529. +ubicom32_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
  3530. +{
  3531. + if (count != 0)
  3532. + return NULL_RTX;
  3533. +
  3534. + return get_hard_reg_initial_val (Pmode, LINK_REGNO);
  3535. +}
  3536. +
  3537. +/*
  3538. + * ubicom32_readonly_data_section: This routtine handles code
  3539. + * at the start of readonly data sections
  3540. + */
  3541. +static void
  3542. +ubicom32_readonly_data_section (const void *data ATTRIBUTE_UNUSED)
  3543. +{
  3544. + static int num = 0;
  3545. + if (in_section == readonly_data_section){
  3546. + fprintf (asm_out_file, "%s", DATA_SECTION_ASM_OP);
  3547. + if (flag_data_sections){
  3548. + fprintf (asm_out_file, ".rodata%d", num);
  3549. + fprintf (asm_out_file, ",\"a\"");
  3550. + }
  3551. + fprintf (asm_out_file, "\n");
  3552. + }
  3553. + num++;
  3554. +}
  3555. +
  3556. +/*
  3557. + * ubicom32_text_section: not in readonly section
  3558. + */
  3559. +static void
  3560. +ubicom32_text_section(const void *data ATTRIBUTE_UNUSED)
  3561. +{
  3562. + fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
  3563. +}
  3564. +
  3565. +/*
  3566. + * ubicom32_data_section: not in readonly section
  3567. + */
  3568. +static void
  3569. +ubicom32_data_section(const void *data ATTRIBUTE_UNUSED)
  3570. +{
  3571. + fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
  3572. +}
  3573. +
  3574. +/*
  3575. + * ubicom32_asm_init_sections: This routine implements special
  3576. + * section handling
  3577. + */
  3578. +static void
  3579. +ubicom32_asm_init_sections(void)
  3580. +{
  3581. + text_section = get_unnamed_section(SECTION_CODE, ubicom32_text_section, NULL);
  3582. +
  3583. + data_section = get_unnamed_section(SECTION_WRITE, ubicom32_data_section, NULL);
  3584. +
  3585. + readonly_data_section = get_unnamed_section(0, ubicom32_readonly_data_section, NULL);
  3586. +}
  3587. +
  3588. +/*
  3589. + * ubicom32_profiler: This routine would call
  3590. + * mcount to support prof and gprof if mcount
  3591. + * was supported. Currently, do nothing.
  3592. + */
  3593. +void
  3594. +ubicom32_profiler(void)
  3595. +{
  3596. +}
  3597. +
  3598. +/* Initialise the builtin functions. Start by initialising
  3599. + descriptions of different types of functions (e.g., void fn(int),
  3600. + int fn(void)), and then use these to define the builtins. */
  3601. +static void
  3602. +ubicom32_init_builtins (void)
  3603. +{
  3604. + tree endlink;
  3605. + tree short_unsigned_endlink;
  3606. + tree unsigned_endlink;
  3607. + tree short_unsigned_ftype_short_unsigned;
  3608. + tree unsigned_ftype_unsigned;
  3609. +
  3610. + endlink = void_list_node;
  3611. +
  3612. + short_unsigned_endlink
  3613. + = tree_cons (NULL_TREE, short_unsigned_type_node, endlink);
  3614. +
  3615. + unsigned_endlink
  3616. + = tree_cons (NULL_TREE, unsigned_type_node, endlink);
  3617. +
  3618. + short_unsigned_ftype_short_unsigned
  3619. + = build_function_type (short_unsigned_type_node, short_unsigned_endlink);
  3620. +
  3621. + unsigned_ftype_unsigned
  3622. + = build_function_type (unsigned_type_node, unsigned_endlink);
  3623. +
  3624. + /* Initialise the byte swap function. */
  3625. + add_builtin_function ("__builtin_ubicom32_swapb_2",
  3626. + short_unsigned_ftype_short_unsigned,
  3627. + UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
  3628. + BUILT_IN_MD, NULL,
  3629. + NULL_TREE);
  3630. +
  3631. + /* Initialise the byte swap function. */
  3632. + add_builtin_function ("__builtin_ubicom32_swapb_4",
  3633. + unsigned_ftype_unsigned,
  3634. + UBICOM32_BUILTIN_UBICOM32_SWAPB_4,
  3635. + BUILT_IN_MD, NULL,
  3636. + NULL_TREE);
  3637. +}
  3638. +
  3639. +/* Given a builtin function taking 2 operands (i.e., target + source),
  3640. + emit the RTL for the underlying instruction. */
  3641. +static rtx
  3642. +ubicom32_expand_builtin_2op (enum insn_code icode, tree arglist, rtx target)
  3643. +{
  3644. + tree arg0;
  3645. + rtx op0, pat;
  3646. + enum machine_mode tmode, mode0;
  3647. +
  3648. + /* Grab the incoming argument and emit its RTL. */
  3649. + arg0 = TREE_VALUE (arglist);
  3650. + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
  3651. +
  3652. + /* Determine the modes of the instruction operands. */
  3653. + tmode = insn_data[icode].operand[0].mode;
  3654. + mode0 = insn_data[icode].operand[1].mode;
  3655. +
  3656. + /* Ensure that the incoming argument RTL is in a register of the
  3657. + correct mode. */
  3658. + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
  3659. + op0 = copy_to_mode_reg (mode0, op0);
  3660. +
  3661. + /* If there isn't a suitable target, emit a target register. */
  3662. + if (target == 0
  3663. + || GET_MODE (target) != tmode
  3664. + || !(*insn_data[icode].operand[0].predicate) (target, tmode))
  3665. + target = gen_reg_rtx (tmode);
  3666. +
  3667. + /* Emit and return the new instruction. */
  3668. + pat = GEN_FCN (icode) (target, op0);
  3669. + if (!pat)
  3670. + return 0;
  3671. + emit_insn (pat);
  3672. +
  3673. + return target;
  3674. +}
  3675. +
  3676. +/* Expand a call to a builtin function. */
  3677. +static rtx
  3678. +ubicom32_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
  3679. + enum machine_mode mode ATTRIBUTE_UNUSED,
  3680. + int ignore ATTRIBUTE_UNUSED)
  3681. +{
  3682. + tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
  3683. + tree arglist = CALL_EXPR_ARGS(exp);
  3684. + int fcode = DECL_FUNCTION_CODE (fndecl);
  3685. +
  3686. + switch (fcode)
  3687. + {
  3688. + case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
  3689. + return ubicom32_expand_builtin_2op (CODE_FOR_bswaphi, arglist, target);
  3690. +
  3691. + case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
  3692. + return ubicom32_expand_builtin_2op (CODE_FOR_bswapsi, arglist, target);
  3693. +
  3694. + default:
  3695. + gcc_unreachable();
  3696. + }
  3697. +
  3698. + /* Should really do something sensible here. */
  3699. + return NULL_RTX;
  3700. +}
  3701. +
  3702. +/* Fold any constant argument for a swapb.2 instruction. */
  3703. +static tree
  3704. +ubicom32_fold_builtin_ubicom32_swapb_2 (tree fndecl, tree arglist)
  3705. +{
  3706. + tree arg0;
  3707. +
  3708. + arg0 = TREE_VALUE (arglist);
  3709. +
  3710. + /* Optimize constant value. */
  3711. + if (TREE_CODE (arg0) == INTEGER_CST)
  3712. + {
  3713. + HOST_WIDE_INT v;
  3714. + HOST_WIDE_INT res;
  3715. +
  3716. + v = TREE_INT_CST_LOW (arg0);
  3717. + res = ((v >> 8) & 0xff)
  3718. + | ((v & 0xff) << 8);
  3719. +
  3720. + return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
  3721. + }
  3722. +
  3723. + return NULL_TREE;
  3724. +}
  3725. +
  3726. +/* Fold any constant argument for a swapb.4 instruction. */
  3727. +static tree
  3728. +ubicom32_fold_builtin_ubicom32_swapb_4 (tree fndecl, tree arglist)
  3729. +{
  3730. + tree arg0;
  3731. +
  3732. + arg0 = TREE_VALUE (arglist);
  3733. +
  3734. + /* Optimize constant value. */
  3735. + if (TREE_CODE (arg0) == INTEGER_CST)
  3736. + {
  3737. + unsigned HOST_WIDE_INT v;
  3738. + unsigned HOST_WIDE_INT res;
  3739. +
  3740. + v = TREE_INT_CST_LOW (arg0);
  3741. + res = ((v >> 24) & 0xff)
  3742. + | (((v >> 16) & 0xff) << 8)
  3743. + | (((v >> 8) & 0xff) << 16)
  3744. + | ((v & 0xff) << 24);
  3745. +
  3746. + return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), res, 0);
  3747. + }
  3748. +
  3749. + return NULL_TREE;
  3750. +}
  3751. +
  3752. +/* Fold any constant arguments for builtin functions. */
  3753. +static tree
  3754. +ubicom32_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
  3755. +{
  3756. + switch (DECL_FUNCTION_CODE (fndecl))
  3757. + {
  3758. + case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
  3759. + return ubicom32_fold_builtin_ubicom32_swapb_2 (fndecl, arglist);
  3760. +
  3761. + case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
  3762. + return ubicom32_fold_builtin_ubicom32_swapb_4 (fndecl, arglist);
  3763. +
  3764. + default:
  3765. + return NULL;
  3766. + }
  3767. +}
  3768. +
  3769. +/* Implementation of TARGET_ASM_INTEGER. When using FD-PIC, we need to
  3770. + tell the assembler to generate pointers to function descriptors in
  3771. + some cases. */
  3772. +static bool
  3773. +ubicom32_assemble_integer (rtx value, unsigned int size, int aligned_p)
  3774. +{
  3775. + if (TARGET_FDPIC && size == UNITS_PER_WORD)
  3776. + {
  3777. + if (GET_CODE (value) == SYMBOL_REF
  3778. + && SYMBOL_REF_FUNCTION_P (value))
  3779. + {
  3780. + fputs ("\t.picptr\t%funcdesc(", asm_out_file);
  3781. + output_addr_const (asm_out_file, value);
  3782. + fputs (")\n", asm_out_file);
  3783. + return true;
  3784. + }
  3785. +
  3786. + if (!aligned_p)
  3787. + {
  3788. + /* We've set the unaligned SI op to NULL, so we always have to
  3789. + handle the unaligned case here. */
  3790. + assemble_integer_with_op ("\t.4byte\t", value);
  3791. + return true;
  3792. + }
  3793. + }
  3794. +
  3795. + return default_assemble_integer (value, size, aligned_p);
  3796. +}
  3797. +
  3798. +/* If the constant I can be constructed by shifting a source-1 immediate
  3799. + by a constant number of bits then return the bit count. If not
  3800. + return 0. */
  3801. +
  3802. +int
  3803. +ubicom32_shiftable_const_int (int i)
  3804. +{
  3805. + int shift = 0;
  3806. +
  3807. + /* Note that any constant that can be represented as an immediate to
  3808. + a movei instruction is automatically ignored here in the interests
  3809. + of the clarity of the output asm code. */
  3810. + if (i >= -32768 && i <= 32767)
  3811. + return 0;
  3812. +
  3813. + /* Find the number of trailing zeroes. We could use __builtin_ctz
  3814. + here but it's not obvious if this is supported on all build
  3815. + compilers so we err on the side of caution. */
  3816. + if ((i & 0xffff) == 0)
  3817. + {
  3818. + shift += 16;
  3819. + i >>= 16;
  3820. + }
  3821. +
  3822. + if ((i & 0xff) == 0)
  3823. + {
  3824. + shift += 8;
  3825. + i >>= 8;
  3826. + }
  3827. +
  3828. + if ((i & 0xf) == 0)
  3829. + {
  3830. + shift += 4;
  3831. + i >>= 4;
  3832. + }
  3833. +
  3834. + if ((i & 0x3) == 0)
  3835. + {
  3836. + shift += 2;
  3837. + i >>= 2;
  3838. + }
  3839. +
  3840. + if ((i & 0x1) == 0)
  3841. + {
  3842. + shift += 1;
  3843. + i >>= 1;
  3844. + }
  3845. +
  3846. + if (i >= -128 && i <= 127)
  3847. + return shift;
  3848. +
  3849. + return 0;
  3850. +}
  3851. +
  3852. --- /dev/null
  3853. +++ b/gcc/config/ubicom32/ubicom32.h
  3854. @@ -0,0 +1,1564 @@
  3855. +/* Definitions of target machine for Ubicom32
  3856. +
  3857. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
  3858. + 2009 Free Software Foundation, Inc.
  3859. + Contributed by Ubicom, Inc.
  3860. +
  3861. + This file is part of GCC.
  3862. +
  3863. + GCC is free software; you can redistribute it and/or modify it
  3864. + under the terms of the GNU General Public License as published
  3865. + by the Free Software Foundation; either version 3, or (at your
  3866. + option) any later version.
  3867. +
  3868. + GCC is distributed in the hope that it will be useful, but WITHOUT
  3869. + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  3870. + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  3871. + License for more details.
  3872. +
  3873. + You should have received a copy of the GNU General Public License
  3874. + along with GCC; see the file COPYING3. If not see
  3875. + <http://www.gnu.org/licenses/>. */
  3876. +
  3877. +
  3878. +
  3879. +#define OBJECT_FORMAT_ELF
  3880. +
  3881. +/* Run-time target specifications. */
  3882. +
  3883. +/* Target CPU builtins. */
  3884. +#define TARGET_CPU_CPP_BUILTINS() \
  3885. + do \
  3886. + { \
  3887. + builtin_define_std ("__UBICOM32__"); \
  3888. + builtin_define_std ("__ubicom32__"); \
  3889. + \
  3890. + if (TARGET_FDPIC) \
  3891. + { \
  3892. + builtin_define ("__UBICOM32_FDPIC__"); \
  3893. + builtin_define ("__FDPIC__"); \
  3894. + } \
  3895. + } \
  3896. + while (0)
  3897. +
  3898. +#ifndef TARGET_DEFAULT
  3899. +#define TARGET_DEFAULT 0
  3900. +#endif
  3901. +
  3902. +extern int ubicom32_case_values_threshold;
  3903. +
  3904. +/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
  3905. +extern int ubicom32_v3;
  3906. +
  3907. +/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
  3908. +extern int ubicom32_v4;
  3909. +
  3910. +extern int ubicom32_stack_size;
  3911. +
  3912. +/* Flag for whether we can use calli instead of ret in returns. */
  3913. +extern int ubicom32_can_use_calli_to_ret;
  3914. +
  3915. +/* This macro is a C statement to print on `stderr' a string describing the
  3916. + particular machine description choice. Every machine description should
  3917. + define `TARGET_VERSION'. */
  3918. +#define TARGET_VERSION fprintf (stderr, " (UBICOM32)");
  3919. +
  3920. +/* We don't need a frame pointer to debug things. Doing this means
  3921. + that gcc can turn on -fomit-frame-pointer when '-O' is specified. */
  3922. +#define CAN_DEBUG_WITHOUT_FP
  3923. +
  3924. +/* We need to handle processor-specific options. */
  3925. +#define OVERRIDE_OPTIONS ubicom32_override_options ()
  3926. +
  3927. +#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \
  3928. + ubicom32_optimization_options (LEVEL, SIZE)
  3929. +
  3930. +/* For Ubicom32 the least significant bit has the lowest bit number
  3931. + so we define this to be 0. */
  3932. +#define BITS_BIG_ENDIAN 0
  3933. +
  3934. +/* For Ubicom32 the most significant byte in a word has the lowest
  3935. + number. */
  3936. +#define BYTES_BIG_ENDIAN 1
  3937. +
  3938. +/* For Ubicom32, in a multiword object, the most signifant word has the
  3939. + lowest number. */
  3940. +#define WORDS_BIG_ENDIAN 1
  3941. +
  3942. +/* Ubicom32 has 8 bits per byte. */
  3943. +#define BITS_PER_UNIT 8
  3944. +
  3945. +/* Ubicom32 has 32 bits per word. */
  3946. +#define BITS_PER_WORD 32
  3947. +
  3948. +/* Width of a word, in units (bytes). */
  3949. +#define UNITS_PER_WORD 4
  3950. +
  3951. +/* Width of a pointer, in bits. */
  3952. +#define POINTER_SIZE 32
  3953. +
  3954. +/* Alias for pointers. Ubicom32 is a 32-bit architecture so we use
  3955. + SImode. */
  3956. +#define Pmode SImode
  3957. +
  3958. +/* Normal alignment required for function parameters on the stack, in
  3959. + bits. */
  3960. +#define PARM_BOUNDARY 32
  3961. +
  3962. +/* We need to maintain the stack on a 32-bit boundary. */
  3963. +#define STACK_BOUNDARY 32
  3964. +
  3965. +/* Alignment required for a function entry point, in bits. */
  3966. +#define FUNCTION_BOUNDARY 32
  3967. +
  3968. +/* Alias for the machine mode used for memory references to functions being
  3969. + called, in `call' RTL expressions. We use byte-oriented addresses
  3970. + here. */
  3971. +#define FUNCTION_MODE QImode
  3972. +
  3973. +/* Biggest alignment that any data type can require on this machine,
  3974. + in bits. */
  3975. +#define BIGGEST_ALIGNMENT 32
  3976. +
  3977. +/* this default to BIGGEST_ALIGNMENT unless defined */
  3978. +/* ART: What's the correct value here? Default is (((unsigned int)1<<28)*8)*/
  3979. +#undef MAX_OFILE_ALIGNMENT
  3980. +#define MAX_OFILE_ALIGNMENT (128 * 8)
  3981. +
  3982. +/* Alignment in bits to be given to a structure bit field that follows an empty
  3983. + field such as `int : 0;'. */
  3984. +#define EMPTY_FIELD_BOUNDARY 32
  3985. +
  3986. +/* All structures must be a multiple of 32 bits in size. */
  3987. +#define STRUCTURE_SIZE_BOUNDARY 32
  3988. +
  3989. +/* A bit-field declared as `int' forces `int' alignment for the struct. */
  3990. +#define PCC_BITFIELD_TYPE_MATTERS 1
  3991. +
  3992. +/* For Ubicom32 we absolutely require that data be aligned with nominal
  3993. + alignment. */
  3994. +#define STRICT_ALIGNMENT 1
  3995. +
  3996. +/* Make strcpy of constants fast. */
  3997. +#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
  3998. + (TREE_CODE (EXP) == STRING_CST \
  3999. + && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  4000. +
  4001. +/* Define this macro as an expression for the alignment of a structure
  4002. + (given by STRUCT as a tree node) if the alignment computed in the
  4003. + usual way is COMPUTED and the alignment explicitly specified was
  4004. + SPECIFIED. */
  4005. +#define DATA_ALIGNMENT(TYPE, ALIGN) \
  4006. + ((((ALIGN) < BITS_PER_WORD) \
  4007. + && (TREE_CODE (TYPE) == ARRAY_TYPE \
  4008. + || TREE_CODE (TYPE) == UNION_TYPE \
  4009. + || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
  4010. +
  4011. +#define LOCAL_ALIGNMENT(TYPE,ALIGN) DATA_ALIGNMENT(TYPE,ALIGN)
  4012. +
  4013. +/* For Ubicom32 we default to unsigned chars. */
  4014. +#define DEFAULT_SIGNED_CHAR 0
  4015. +
  4016. +/* Machine-specific data register numbers. */
  4017. +#define FIRST_DATA_REGNUM 0
  4018. +#define D10_REGNUM 10
  4019. +#define D11_REGNUM 11
  4020. +#define D12_REGNUM 12
  4021. +#define D13_REGNUM 13
  4022. +#define LAST_DATA_REGNUM 15
  4023. +
  4024. +/* Machine-specific address register numbers. */
  4025. +#define FIRST_ADDRESS_REGNUM 16
  4026. +#define LAST_ADDRESS_REGNUM 22
  4027. +
  4028. +/* Register numbers used for passing a function's static chain pointer. If
  4029. + register windows are used, the register number as seen by the called
  4030. + function is `STATIC_CHAIN_INCOMING_REGNUM', while the register number as
  4031. + seen by the calling function is `STATIC_CHAIN_REGNUM'. If these registers
  4032. + are the same, `STATIC_CHAIN_INCOMING_REGNUM' need not be defined.
  4033. +
  4034. + The static chain register need not be a fixed register.
  4035. +
  4036. + If the static chain is passed in memory, these macros should not be defined;
  4037. + instead, the next two macros should be defined. */
  4038. +#define STATIC_CHAIN_REGNUM (FIRST_ADDRESS_REGNUM + 1)
  4039. +
  4040. +/* The register number of the frame pointer register, which is used to access
  4041. + automatic variables in the stack frame. We generally eliminate this anyway
  4042. + for Ubicom32 but we make it A6 by default. */
  4043. +#define FRAME_POINTER_REGNUM (LAST_ADDRESS_REGNUM)
  4044. +
  4045. +/* The register number of the stack pointer register, which is also be a
  4046. + fixed register according to `FIXED_REGISTERS'. For Ubicom32 we don't
  4047. + have a hardware requirement about which register this is, but by convention
  4048. + we use A7. */
  4049. +#define STACK_POINTER_REGNUM (LAST_ADDRESS_REGNUM + 1)
  4050. +
  4051. +/* Machine-specific accumulator register numbers. */
  4052. +#define ACC0_HI_REGNUM 24
  4053. +#define ACC0_LO_REGNUM 25
  4054. +#define ACC1_HI_REGNUM 26
  4055. +#define ACC1_LO_REGNUM 27
  4056. +
  4057. +/* source3 register number */
  4058. +#define SOURCE3_REGNUM 28
  4059. +
  4060. +/* The register number of the arg pointer register, which is used to access the
  4061. + function's argument list. On some machines, this is the same as the frame
  4062. + pointer register. On some machines, the hardware determines which register
  4063. + this is. On other machines, you can choose any register you wish for this
  4064. + purpose. If this is not the same register as the frame pointer register,
  4065. + then you must mark it as a fixed register according to `FIXED_REGISTERS', or
  4066. + arrange to be able to eliminate it. */
  4067. +#define ARG_POINTER_REGNUM 29
  4068. +
  4069. +/* Pseudo-reg for condition code. */
  4070. +#define CC_REGNUM 30
  4071. +
  4072. +/* Interrupt set/clear registers. */
  4073. +#define INT_SET0_REGNUM 31
  4074. +#define INT_SET1_REGNUM 32
  4075. +#define INT_CLR0_REGNUM 33
  4076. +#define INT_CLR1_REGNUM 34
  4077. +
  4078. +/* Scratchpad registers. */
  4079. +#define SCRATCHPAD0_REGNUM 35
  4080. +#define SCRATCHPAD1_REGNUM 36
  4081. +#define SCRATCHPAD2_REGNUM 37
  4082. +#define SCRATCHPAD3_REGNUM 38
  4083. +
  4084. +/* FDPIC register. */
  4085. +#define FDPIC_REGNUM 16
  4086. +
  4087. +/* Number of hardware registers known to the compiler. They receive numbers 0
  4088. + through `FIRST_PSEUDO_REGISTER-1'; thus, the first pseudo register's number
  4089. + really is assigned the number `FIRST_PSEUDO_REGISTER'. */
  4090. +#define FIRST_PSEUDO_REGISTER 39
  4091. +
  4092. +/* An initializer that says which registers are used for fixed purposes all
  4093. + throughout the compiled code and are therefore not available for general
  4094. + allocation. These would include the stack pointer, the frame pointer
  4095. + (except on machines where that can be used as a general register when no
  4096. + frame pointer is needed), the program counter on machines where that is
  4097. + considered one of the addressable registers, and any other numbered register
  4098. + with a standard use.
  4099. +
  4100. + This information is expressed as a sequence of numbers, separated by commas
  4101. + and surrounded by braces. The Nth number is 1 if register N is fixed, 0
  4102. + otherwise.
  4103. +
  4104. + The table initialized from this macro, and the table initialized by the
  4105. + following one, may be overridden at run time either automatically, by the
  4106. + actions of the macro `CONDITIONAL_REGISTER_USAGE', or by the user with the
  4107. + command options `-ffixed-REG', `-fcall-used-REG' and `-fcall-saved-REG'. */
  4108. +#define FIXED_REGISTERS \
  4109. + { \
  4110. + 0, 0, 0, 0, 0, 0, 0, 0, /* d0 - d7 */ \
  4111. + 0, 0, 0, 0, 0, 0, 0, 1, /* d8 - d15 */ \
  4112. + 0, 0, 0, 0, 0, 0, 0, 1, /* a0 - a7 */ \
  4113. + 0, 0, /* acc0 hi/lo */ \
  4114. + 0, 0, /* acc1 hi/lo */ \
  4115. + 0, /* source3 */ \
  4116. + 1, /* arg */ \
  4117. + 1, /* cc */ \
  4118. + 1, 1, /* int_set[01] */ \
  4119. + 1, 1, /* int_clr[01] */ \
  4120. + 1, 1, 1, 1 /* scratchpad[0123] */ \
  4121. + }
  4122. +
  4123. +/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in
  4124. + general) by function calls as well as for fixed registers. This macro
  4125. + therefore identifies the registers that are not available for general
  4126. + allocation of values that must live across function calls.
  4127. +
  4128. + If a register has 0 in `CALL_USED_REGISTERS', the compiler automatically
  4129. + saves it on function entry and restores it on function exit, if the register
  4130. + is used within the function. */
  4131. +#define CALL_USED_REGISTERS \
  4132. + { \
  4133. + 1, 1, 1, 1, 1, 1, 1, 1, /* d0 - d7 */ \
  4134. + 1, 1, 0, 0, 0, 0, 1, 1, /* d8 - d15 */ \
  4135. + 1, 0, 0, 1, 1, 1, 0, 1, /* a0 - a7 */ \
  4136. + 1, 1, /* acc0 hi/lo */ \
  4137. + 1, 1, /* acc1 hi/lo */ \
  4138. + 1, /* source3 */ \
  4139. + 1, /* arg */ \
  4140. + 1, /* cc */ \
  4141. + 1, 1, /* int_set[01] */ \
  4142. + 1, 1, /* int_clr[01] */ \
  4143. + 1, 1, 1, 1 /* scratchpad[0123] */ \
  4144. + }
  4145. +
  4146. +/* How to refer to registers in assembler output.
  4147. + This sequence is indexed by compiler's hard-register-number (see above). */
  4148. +
  4149. +/* A C initializer containing the assembler's names for the machine registers,
  4150. + each one as a C string constant. This is what translates register numbers
  4151. + in the compiler into assembler language. */
  4152. +#define REGISTER_NAMES \
  4153. + { \
  4154. + "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
  4155. + "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", \
  4156. + "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", \
  4157. + "acc0_hi", "acc0_lo", \
  4158. + "acc1_hi", "acc1_lo", \
  4159. + "source3", \
  4160. + "arg", \
  4161. + "cc", \
  4162. + "int_set0", "int_set1", \
  4163. + "int_clr0", "int_clr1", \
  4164. + "scratchpad0", "scratchpad1", "scratchpad2", "scratchpad3" \
  4165. + }
  4166. +
  4167. +#define CONDITIONAL_REGISTER_USAGE \
  4168. + ubicom32_conditional_register_usage ();
  4169. +
  4170. +/* Order of allocation of registers. */
  4171. +
  4172. +/* If defined, an initializer for a vector of integers, containing the numbers
  4173. + of hard registers in the order in which GNU CC should prefer to use them
  4174. + (from most preferred to least).
  4175. +
  4176. + For Ubicom32 we try using caller-clobbered data registers first, then
  4177. + callee-saved data registers, then caller-clobbered address registers,
  4178. + then callee-saved address registers and finally everything else.
  4179. +
  4180. + The caller-clobbered registers are usually slightly cheaper to use because
  4181. + there's no need to save/restore. */
  4182. +#define REG_ALLOC_ORDER \
  4183. + { \
  4184. + 0, 1, 2, 3, 4, /* d0 - d4 */ \
  4185. + 5, 6, 7, 8, 9, /* d5 - d9 */ \
  4186. + 14, /* d14 */ \
  4187. + 10, 11, 12, 13, /* d10 - d13 */ \
  4188. + 19, 20, 16, 21, /* a3, a4, a0, a5 */ \
  4189. + 17, 18, 22, /* a1, a2, a6 */ \
  4190. + 24, 25, /* acc0 hi/lo */ \
  4191. + 26, 27, /* acc0 hi/lo */ \
  4192. + 28 /* source3 */ \
  4193. + }
  4194. +
  4195. +/* C expression for the number of consecutive hard registers, starting at
  4196. + register number REGNO, required to hold a value of mode MODE. */
  4197. +#define HARD_REGNO_NREGS(REGNO, MODE) \
  4198. + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
  4199. +
  4200. +/* Most registers can hold QImode, HImode and SImode values but we have to
  4201. + be able to indicate any hard registers that cannot hold values with some
  4202. + modes. */
  4203. +#define HARD_REGNO_MODE_OK(REGNO, MODE) \
  4204. + ubicom32_hard_regno_mode_ok(REGNO, MODE)
  4205. +
  4206. +/* We can rename most registers aside from the FDPIC register if we're using
  4207. + FDPIC. */
  4208. +#define HARD_REGNO_RENAME_OK(from, to) (TARGET_FDPIC ? ((to) != FDPIC_REGNUM) : 1)
  4209. +
  4210. +/* A C expression that is nonzero if it is desirable to choose register
  4211. + allocation so as to avoid move instructions between a value of mode MODE1
  4212. + and a value of mode MODE2.
  4213. +
  4214. + If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
  4215. + ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
  4216. + zero. */
  4217. +#define MODES_TIEABLE_P(MODE1, MODE2) 1
  4218. +
  4219. +/* An enumeral type that must be defined with all the register class names as
  4220. + enumeral values. `NO_REGS' must be first. `ALL_REGS' must be the last
  4221. + register class, followed by one more enumeral value, `LIM_REG_CLASSES',
  4222. + which is not a register class but rather tells how many classes there are.
  4223. +
  4224. + Each register class has a number, which is the value of casting the class
  4225. + name to type `int'. The number serves as an index in many of the tables
  4226. + described below. */
  4227. +
  4228. +enum reg_class
  4229. +{
  4230. + NO_REGS,
  4231. + DATA_REGS,
  4232. + FDPIC_REG,
  4233. + ADDRESS_REGS,
  4234. + ALL_ADDRESS_REGS,
  4235. + ACC_LO_REGS,
  4236. + ACC_REGS,
  4237. + CC_REG,
  4238. + DATA_ACC_REGS,
  4239. + SOURCE3_REG,
  4240. + SPECIAL_REGS,
  4241. + GENERAL_REGS,
  4242. + ALL_REGS,
  4243. + LIM_REG_CLASSES
  4244. +};
  4245. +
  4246. +/* The number of distinct register classes. */
  4247. +#define N_REG_CLASSES (int) LIM_REG_CLASSES
  4248. +
  4249. +/* An initializer containing the names of the register classes as C string
  4250. + constants. These names are used in writing some of the debugging dumps. */
  4251. +
  4252. +#define REG_CLASS_NAMES \
  4253. +{ \
  4254. + "NO_REGS", \
  4255. + "DATA_REGS", \
  4256. + "FDPIC_REG", \
  4257. + "ADDRESS_REGS", \
  4258. + "ALL_ADDRESS_REGS", \
  4259. + "ACC_LO_REGS", \
  4260. + "ACC_REGS", \
  4261. + "CC_REG", \
  4262. + "DATA_ACC_REGS", \
  4263. + "SOURCE3_REG", \
  4264. + "SPECIAL_REGS", \
  4265. + "GENERAL_REGS", \
  4266. + "ALL_REGS", \
  4267. + "LIM_REGS" \
  4268. +}
  4269. +
  4270. +/* An initializer containing the contents of the register classes, as integers
  4271. + which are bit masks. The Nth integer specifies the contents of class N.
  4272. + The way the integer MASK is interpreted is that register R is in the class
  4273. + if `MASK & (1 << R)' is 1.
  4274. +
  4275. + When the machine has more than 32 registers, an integer does not suffice.
  4276. + Then the integers are replaced by sub-initializers, braced groupings
  4277. + containing several integers. Each sub-initializer must be suitable as an
  4278. + initializer for the type `HARD_REG_SET' which is defined in
  4279. + `hard-reg-set.h'. */
  4280. +#define REG_CLASS_CONTENTS \
  4281. +{ \
  4282. + {0x00000000, 0x00000000}, /* No regs */ \
  4283. + {0x0000ffff, 0x00000000}, /* DATA_REGS */ \
  4284. + {0x00010000, 0x00000000}, /* FDPIC_REG */ \
  4285. + {0x20fe0000, 0x00000000}, /* ADDRESS_REGS */ \
  4286. + {0x20ff0000, 0x00000000}, /* ALL_ADDRESS_REGS */ \
  4287. + {0x0a000000, 0x00000000}, /* ACC_LO_REGS */ \
  4288. + {0x0f000000, 0x00000000}, /* ACC_REGS */ \
  4289. + {0x40000000, 0x00000000}, /* CC_REG */ \
  4290. + {0x0f00ffff, 0x00000000}, /* DATA_ACC_REGS */ \
  4291. + {0x10000000, 0x00000000}, /* SOURGE3_REG */ \
  4292. + {0x80000000, 0x0000007f}, /* SPECIAL_REGS */ \
  4293. + {0xbfffffff, 0x0000007f}, /* GENERAL_REGS */ \
  4294. + {0xbfffffff, 0x0000007f} /* ALL_REGS */ \
  4295. +}
  4296. +
  4297. +extern enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER];
  4298. +
  4299. +/* A C expression whose value is a register class containing hard register
  4300. + REGNO. In general there is more than one such class; choose a class which
  4301. + is "minimal", meaning that no smaller class also contains the register. */
  4302. +#define REGNO_REG_CLASS(REGNO) (ubicom32_regclass_map[REGNO])
  4303. +
  4304. +#define IRA_COVER_CLASSES \
  4305. +{ \
  4306. + GENERAL_REGS, \
  4307. + LIM_REG_CLASSES \
  4308. +}
  4309. +
  4310. +/* Ubicom32 base registers must be address registers since addresses can
  4311. + only be reached via address registers. */
  4312. +#define BASE_REG_CLASS ALL_ADDRESS_REGS
  4313. +
  4314. +/* Ubicom32 index registers must be data registers since we cannot add
  4315. + two address registers together to form an address. */
  4316. +#define INDEX_REG_CLASS DATA_REGS
  4317. +
  4318. +/* A C expression which is nonzero if register number NUM is suitable for use
  4319. + as a base register in operand addresses. It may be either a suitable hard
  4320. + register or a pseudo register that has been allocated such a hard register. */
  4321. +
  4322. +#ifndef REG_OK_STRICT
  4323. +#define REGNO_OK_FOR_BASE_P(regno) \
  4324. + ubicom32_regno_ok_for_base_p (regno, 0)
  4325. +#else
  4326. +#define REGNO_OK_FOR_BASE_P(regno) \
  4327. + ubicom32_regno_ok_for_base_p (regno, 1)
  4328. +#endif
  4329. +
  4330. +/* A C expression which is nonzero if register number NUM is suitable for use
  4331. + as an index register in operand addresses. It may be either a suitable hard
  4332. + register or a pseudo register that has been allocated such a hard register.
  4333. +
  4334. + The difference between an index register and a base register is that the
  4335. + index register may be scaled. If an address involves the sum of two
  4336. + registers, neither one of them scaled, then either one may be labeled the
  4337. + "base" and the other the "index"; but whichever labeling is used must fit
  4338. + the machine's constraints of which registers may serve in each capacity.
  4339. + The compiler will try both labelings, looking for one that is valid, and
  4340. + will reload one or both registers only if neither labeling works. */
  4341. +#ifndef REG_OK_STRICT
  4342. +#define REGNO_OK_FOR_INDEX_P(regno) \
  4343. + ubicom32_regno_ok_for_index_p (regno, 0)
  4344. +#else
  4345. +#define REGNO_OK_FOR_INDEX_P(regno) \
  4346. + ubicom32_regno_ok_for_index_p (regno, 1)
  4347. +#endif
  4348. +
  4349. +/* Attempt to restrict the register class we need to copy value X intoto the
  4350. + would-be register class CLASS. Most things are fine for Ubicom32 but we
  4351. + have to restrict certain types of address loads. */
  4352. +#define PREFERRED_RELOAD_CLASS(X, CLASS) \
  4353. + ubicom32_preferred_reload_class (X, CLASS)
  4354. +
  4355. +/* A C expression for the maximum number of consecutive registers of
  4356. + class CLASS needed to hold a value of mode MODE. For Ubicom32 this
  4357. + is pretty much identical to HARD_REGNO_NREGS. */
  4358. +#define CLASS_MAX_NREGS(CLASS, MODE) \
  4359. + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
  4360. +
  4361. +/* For Ubicom32 the stack grows downwards when we push a word onto the stack
  4362. + - i.e. it moves to a smaller address. */
  4363. +#define STACK_GROWS_DOWNWARD 1
  4364. +
  4365. +/* Offset from the frame pointer to the first local variable slot to
  4366. + be allocated. */
  4367. +#define STARTING_FRAME_OFFSET 0
  4368. +
  4369. +/* Offset from the argument pointer register to the first argument's
  4370. + address. */
  4371. +#define FIRST_PARM_OFFSET(FNDECL) 0
  4372. +
  4373. +/* A C expression whose value is RTL representing the value of the return
  4374. + address for the frame COUNT steps up from the current frame, after the
  4375. + prologue. FRAMEADDR is the frame pointer of the COUNT frame, or the frame
  4376. + pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
  4377. + defined.
  4378. +
  4379. + The value of the expression must always be the correct address when COUNT is
  4380. + zero, but may be `NULL_RTX' if there is not way to determine the return
  4381. + address of other frames. */
  4382. +#define RETURN_ADDR_RTX(COUNT, FRAME) \
  4383. + ubicom32_return_addr_rtx (COUNT, FRAME)
  4384. +
  4385. +/* Register That Address the Stack Frame. */
  4386. +
  4387. +/* We don't actually require a frame pointer in most functions with the
  4388. + Ubicom32 architecture so we allow it to be eliminated. */
  4389. +#define FRAME_POINTER_REQUIRED 0
  4390. +
  4391. +/* Macro that defines a table of register pairs used to eliminate unecessary
  4392. + registers that point into the stack frame.
  4393. +
  4394. + For Ubicom32 we don't generally need an arg pointer of a frame pointer
  4395. + so we allow the arg pointer to be replaced by either the frame pointer or
  4396. + the stack pointer. We also allow the frame pointer to be replaced by
  4397. + the stack pointer. */
  4398. +#define ELIMINABLE_REGS \
  4399. +{ \
  4400. + {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
  4401. + {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
  4402. + {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \
  4403. +}
  4404. +
  4405. +/* Let the compiler know that we want to use the ELIMINABLE_REGS macro
  4406. + above. */
  4407. +#define CAN_ELIMINATE(FROM, TO) 1
  4408. +
  4409. +/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the
  4410. + initial difference between the specified pair of registers. This macro must
  4411. + be defined if `ELIMINABLE_REGS' is defined. */
  4412. +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
  4413. + (OFFSET) = ubicom32_initial_elimination_offset (FROM, TO)
  4414. +
  4415. +/* If defined, the maximum amount of space required for outgoing arguments will
  4416. + be computed and placed into the variable
  4417. + `current_function_outgoing_args_size'. No space will be pushed onto the
  4418. + stack for each call; instead, the function prologue should increase the
  4419. + stack frame size by this amount.
  4420. +
  4421. + Defining both `PUSH_ROUNDING' and `ACCUMULATE_OUTGOING_ARGS' is not
  4422. + proper. */
  4423. +#define ACCUMULATE_OUTGOING_ARGS 1
  4424. +
  4425. +/* Define this macro if functions should assume that stack space has been
  4426. + allocated for arguments even when their values are passed in registers.
  4427. +
  4428. + The value of this macro is the size, in bytes, of the area reserved for
  4429. + arguments passed in registers for the function represented by FNDECL.
  4430. +
  4431. + This space can be allocated by the caller, or be a part of the
  4432. + machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
  4433. + which. */
  4434. +#define REG_PARM_STACK_SPACE(FNDECL) ubicom32_reg_parm_stack_space(FNDECL)
  4435. +
  4436. +/* A C expression that should indicate the number of bytes of its own arguments
  4437. + that a function pops on returning, or 0 if the function pops no arguments
  4438. + and the caller must therefore pop them all after the function returns.
  4439. +
  4440. + FUNDECL is a C variable whose value is a tree node that describes the
  4441. + function in question. Normally it is a node of type `FUNCTION_DECL' that
  4442. + describes the declaration of the function. From this it is possible to
  4443. + obtain the DECL_MACHINE_ATTRIBUTES of the function.
  4444. +
  4445. + FUNTYPE is a C variable whose value is a tree node that describes the
  4446. + function in question. Normally it is a node of type `FUNCTION_TYPE' that
  4447. + describes the data type of the function. From this it is possible to obtain
  4448. + the data types of the value and arguments (if known).
  4449. +
  4450. + When a call to a library function is being considered, FUNTYPE will contain
  4451. + an identifier node for the library function. Thus, if you need to
  4452. + distinguish among various library functions, you can do so by their names.
  4453. + Note that "library function" in this context means a function used to
  4454. + perform arithmetic, whose name is known specially in the compiler and was
  4455. + not mentioned in the C code being compiled.
  4456. +
  4457. + STACK-SIZE is the number of bytes of arguments passed on the stack. If a
  4458. + variable number of bytes is passed, it is zero, and argument popping will
  4459. + always be the responsibility of the calling function.
  4460. +
  4461. + On the Vax, all functions always pop their arguments, so the definition of
  4462. + this macro is STACK-SIZE. On the 68000, using the standard calling
  4463. + convention, no functions pop their arguments, so the value of the macro is
  4464. + always 0 in this case. But an alternative calling convention is available
  4465. + in which functions that take a fixed number of arguments pop them but other
  4466. + functions (such as `printf') pop nothing (the caller pops all). When this
  4467. + convention is in use, FUNTYPE is examined to determine whether a function
  4468. + takes a fixed number of arguments. */
  4469. +#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
  4470. +
  4471. +/* A C expression that controls whether a function argument is passed in a
  4472. + register, and which register.
  4473. +
  4474. + The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes (in a way
  4475. + defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE) all of the previous
  4476. + arguments so far passed in registers; MODE, the machine mode of the argument;
  4477. + TYPE, the data type of the argument as a tree node or 0 if that is not known
  4478. + (which happens for C support library functions); and NAMED, which is 1 for an
  4479. + ordinary argument and 0 for nameless arguments that correspond to `...' in the
  4480. + called function's prototype.
  4481. +
  4482. + The value of the expression should either be a `reg' RTX for the hard
  4483. + register in which to pass the argument, or zero to pass the argument on the
  4484. + stack.
  4485. +
  4486. + For machines like the Vax and 68000, where normally all arguments are
  4487. + pushed, zero suffices as a definition.
  4488. +
  4489. + The usual way to make the ANSI library `stdarg.h' work on a machine where
  4490. + some arguments are usually passed in registers, is to cause nameless
  4491. + arguments to be passed on the stack instead. This is done by making
  4492. + `FUNCTION_ARG' return 0 whenever NAMED is 0.
  4493. +
  4494. + You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
  4495. + this macro to determine if this argument is of a type that must be passed in
  4496. + the stack. If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
  4497. + returns non-zero for such an argument, the compiler will abort. If
  4498. + `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
  4499. + stack and then loaded into a register. */
  4500. +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
  4501. + function_arg (&CUM, MODE, TYPE, NAMED)
  4502. +
  4503. +#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
  4504. + function_incoming_arg (&CUM, MODE, TYPE, NAMED)
  4505. +
  4506. +/* A C expression for the number of words, at the beginning of an argument,
  4507. + must be put in registers. The value must be zero for arguments that are
  4508. + passed entirely in registers or that are entirely pushed on the stack.
  4509. +
  4510. + On some machines, certain arguments must be passed partially in registers
  4511. + and partially in memory. On these machines, typically the first N words of
  4512. + arguments are passed in registers, and the rest on the stack. If a
  4513. + multi-word argument (a `double' or a structure) crosses that boundary, its
  4514. + first few words must be passed in registers and the rest must be pushed.
  4515. + This macro tells the compiler when this occurs, and how many of the words
  4516. + should go in registers.
  4517. +
  4518. + `FUNCTION_ARG' for these arguments should return the first register to be
  4519. + used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
  4520. + the called function. */
  4521. +
  4522. +/* A C expression that indicates when an argument must be passed by reference.
  4523. + If nonzero for an argument, a copy of that argument is made in memory and a
  4524. + pointer to the argument is passed instead of the argument itself. The
  4525. + pointer is passed in whatever way is appropriate for passing a pointer to
  4526. + that type.
  4527. +
  4528. + On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
  4529. + definition of this macro might be
  4530. + #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
  4531. + MUST_PASS_IN_STACK (MODE, TYPE) */
  4532. +
  4533. +/* If defined, a C expression that indicates when it is the called function's
  4534. + responsibility to make a copy of arguments passed by invisible reference.
  4535. + Normally, the caller makes a copy and passes the address of the copy to the
  4536. + routine being called. When FUNCTION_ARG_CALLEE_COPIES is defined and is
  4537. + nonzero, the caller does not make a copy. Instead, it passes a pointer to
  4538. + the "live" value. The called function must not modify this value. If it
  4539. + can be determined that the value won't be modified, it need not make a copy;
  4540. + otherwise a copy must be made. */
  4541. +
  4542. +/* A C type for declaring a variable that is used as the first argument of
  4543. + `FUNCTION_ARG' and other related values. For some target machines, the type
  4544. + `int' suffices and can hold the number of bytes of argument so far.
  4545. +
  4546. + There is no need to record in `CUMULATIVE_ARGS' anything about the arguments
  4547. + that have been passed on the stack. The compiler has other variables to
  4548. + keep track of that. For target machines on which all arguments are passed
  4549. + on the stack, there is no need to store anything in `CUMULATIVE_ARGS';
  4550. + however, the data structure must exist and should not be empty, so use
  4551. + `int'. */
  4552. +struct cum_arg
  4553. +{
  4554. + int nbytes;
  4555. + int reg;
  4556. + int stdarg;
  4557. +};
  4558. +#define CUMULATIVE_ARGS struct cum_arg
  4559. +
  4560. +/* A C statement (sans semicolon) for initializing the variable CUM for the
  4561. + state at the beginning of the argument list. The variable has type
  4562. + `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
  4563. + of the function which will receive the args, or 0 if the args are to a
  4564. + compiler support library function. The value of INDIRECT is nonzero when
  4565. + processing an indirect call, for example a call through a function pointer.
  4566. + The value of INDIRECT is zero for a call to an explicitly named function, a
  4567. + library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
  4568. + arguments for the function being compiled.
  4569. +
  4570. + When processing a call to a compiler support library function, LIBNAME
  4571. + identifies which one. It is a `symbol_ref' rtx which contains the name of
  4572. + the function, as a string. LIBNAME is 0 when an ordinary C function call is
  4573. + being processed. Thus, each time this macro is called, either LIBNAME or
  4574. + FNTYPE is nonzero, but never both of them at once. */
  4575. +
  4576. +#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT, NAMED_ARGS) \
  4577. + init_cumulative_args (&(CUM), FNTYPE, LIBNAME, INDIRECT);
  4578. +
  4579. +/* A C statement (sans semicolon) to update the summarizer variable CUM to
  4580. + advance past an argument in the argument list. The values MODE, TYPE and
  4581. + NAMED describe that argument. Once this is done, the variable CUM is
  4582. + suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
  4583. +
  4584. + This macro need not do anything if the argument in question was passed on
  4585. + the stack. The compiler knows how to track the amount of stack space used
  4586. + for arguments without any special help. */
  4587. +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
  4588. + ((CUM).nbytes += ((MODE) != BLKmode \
  4589. + ? (GET_MODE_SIZE (MODE) + 3) & ~3 \
  4590. + : (int_size_in_bytes (TYPE) + 3) & ~3))
  4591. +
  4592. +/* For the Ubicom32 we define the upper function argument register here. */
  4593. +#define UBICOM32_FUNCTION_ARG_REGS 10
  4594. +
  4595. +/* A C expression that is nonzero if REGNO is the number of a hard register in
  4596. + which function arguments are sometimes passed. This does *not* include
  4597. + implicit arguments such as the static chain and the structure-value address.
  4598. + On many machines, no registers can be used for this purpose since all
  4599. + function arguments are pushed on the stack. */
  4600. +#define FUNCTION_ARG_REGNO_P(N) ((N) < UBICOM32_FUNCTION_ARG_REGS)
  4601. +
  4602. +
  4603. +/* How Scalar Function Values are Returned. */
  4604. +
  4605. +/* The number of the hard register that is used to return a scalar value from a
  4606. + function call. */
  4607. +#define RETURN_VALUE_REGNUM 0
  4608. +
  4609. +/* A C expression to create an RTX representing the place where a function
  4610. + returns a value of data type VALTYPE. VALTYPE is a tree node representing a
  4611. + data type. Write `TYPE_MODE (VALTYPE)' to get the machine mode used to
  4612. + represent that type. On many machines, only the mode is relevant.
  4613. + (Actually, on most machines, scalar values are returned in the same place
  4614. + regardless of mode).
  4615. +
  4616. + If `PROMOTE_FUNCTION_RETURN' is defined, you must apply the same promotion
  4617. + rules specified in `PROMOTE_MODE' if VALTYPE is a scalar type.
  4618. +
  4619. + If the precise function being called is known, FUNC is a tree node
  4620. + (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer. This makes it
  4621. + possible to use a different value-returning convention for specific
  4622. + functions when all their calls are known.
  4623. +
  4624. + `FUNCTION_VALUE' is not used for return vales with aggregate data types,
  4625. + because these are returned in another way. See `STRUCT_VALUE_REGNUM' and
  4626. + related macros, below. */
  4627. +#define FUNCTION_VALUE(VALTYPE, FUNC) \
  4628. + gen_rtx_REG (TYPE_MODE (VALTYPE), FIRST_DATA_REGNUM)
  4629. +
  4630. +/* A C expression to create an RTX representing the place where a library
  4631. + function returns a value of mode MODE.
  4632. +
  4633. + Note that "library function" in this context means a compiler support
  4634. + routine, used to perform arithmetic, whose name is known specially by the
  4635. + compiler and was not mentioned in the C code being compiled.
  4636. +
  4637. + The definition of `LIBRARY_VALUE' need not be concerned aggregate data
  4638. + types, because none of the library functions returns such types. */
  4639. +#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, FIRST_DATA_REGNUM)
  4640. +
  4641. +/* A C expression that is nonzero if REGNO is the number of a hard register in
  4642. + which the values of called function may come back.
  4643. +
  4644. + A register whose use for returning values is limited to serving as the
  4645. + second of a pair (for a value of type `double', say) need not be recognized
  4646. + by this macro. So for most machines, this definition suffices:
  4647. +
  4648. + #define FUNCTION_VALUE_REGNO_P(N) ((N) == RETURN)
  4649. +
  4650. + If the machine has register windows, so that the caller and the called
  4651. + function use different registers for the return value, this macro should
  4652. + recognize only the caller's register numbers. */
  4653. +#define FUNCTION_VALUE_REGNO_P(N) ((N) == FIRST_DATA_REGNUM)
  4654. +
  4655. +
  4656. +/* How Large Values are Returned. */
  4657. +
  4658. +/* A C expression which can inhibit the returning of certain function values in
  4659. + registers, based on the type of value. A nonzero value says to return the
  4660. + function value in memory, just as large structures are always returned.
  4661. + Here TYPE will be a C expression of type `tree', representing the data type
  4662. + of the value.
  4663. +
  4664. + Note that values of mode `BLKmode' must be explicitly handled by this macro.
  4665. + Also, the option `-fpcc-struct-return' takes effect regardless of this
  4666. + macro. On most systems, it is possible to leave the macro undefined; this
  4667. + causes a default definition to be used, whose value is the constant 1 for
  4668. + `BLKmode' values, and 0 otherwise.
  4669. +
  4670. + Do not use this macro to indicate that structures and unions should always
  4671. + be returned in memory. You should instead use `DEFAULT_PCC_STRUCT_RETURN'
  4672. + to indicate this. */
  4673. +#define RETURN_IN_MEMORY(TYPE) \
  4674. + (int_size_in_bytes (TYPE) > 8 || TYPE_MODE (TYPE) == BLKmode)
  4675. +
  4676. +/* Define this macro to be 1 if all structure and union return values must be
  4677. + in memory. Since this results in slower code, this should be defined only
  4678. + if needed for compatibility with other compilers or with an ABI. If you
  4679. + define this macro to be 0, then the conventions used for structure and union
  4680. + return values are decided by the `RETURN_IN_MEMORY' macro.
  4681. +
  4682. + If not defined, this defaults to the value 1. */
  4683. +#define DEFAULT_PCC_STRUCT_RETURN 0
  4684. +
  4685. +/* If the structure value address is not passed in a register, define
  4686. + `STRUCT_VALUE' as an expression returning an RTX for the place
  4687. + where the address is passed. If it returns 0, the address is
  4688. + passed as an "invisible" first argument. */
  4689. +#define STRUCT_VALUE 0
  4690. +
  4691. +/* Define this macro as a C expression that is nonzero if the return
  4692. + instruction or the function epilogue ignores the value of the stack pointer;
  4693. + in other words, if it is safe to delete an instruction to adjust the stack
  4694. + pointer before a return from the function.
  4695. +
  4696. + Note that this macro's value is relevant only for functions for which frame
  4697. + pointers are maintained. It is never safe to delete a final stack
  4698. + adjustment in a function that has no frame pointer, and the compiler knows
  4699. + this regardless of `EXIT_IGNORE_STACK'. */
  4700. +#define EXIT_IGNORE_STACK 1
  4701. +
  4702. +/* A C statement or compound statement to output to FILE some assembler code to
  4703. + call the profiling subroutine `mcount'. Before calling, the assembler code
  4704. + must load the address of a counter variable into a register where `mcount'
  4705. + expects to find the address. The name of this variable is `LP' followed by
  4706. + the number LABELNO, so you would generate the name using `LP%d' in a
  4707. + `fprintf'.
  4708. +
  4709. + The details of how the address should be passed to `mcount' are determined
  4710. + by your operating system environment, not by GNU CC. To figure them out,
  4711. + compile a small program for profiling using the system's installed C
  4712. + compiler and look at the assembler code that results.
  4713. +
  4714. + This declaration must be present, but it can be an abort if profiling is
  4715. + not implemented. */
  4716. +
  4717. +#define FUNCTION_PROFILER(file, labelno) ubicom32_profiler(file, labelno)
  4718. +
  4719. +/* A C statement to output, on the stream FILE, assembler code for a block of
  4720. + data that contains the constant parts of a trampoline. This code should not
  4721. + include a label--the label is taken care of automatically. */
  4722. +#if 0
  4723. +#define TRAMPOLINE_TEMPLATE(FILE) \
  4724. + do { \
  4725. + fprintf (FILE, "\tadd -4,sp\n"); \
  4726. + fprintf (FILE, "\t.long 0x0004fffa\n"); \
  4727. + fprintf (FILE, "\tmov (0,sp),a0\n"); \
  4728. + fprintf (FILE, "\tadd 4,sp\n"); \
  4729. + fprintf (FILE, "\tmov (13,a0),a1\n"); \
  4730. + fprintf (FILE, "\tmov (17,a0),a0\n"); \
  4731. + fprintf (FILE, "\tjmp (a0)\n"); \
  4732. + fprintf (FILE, "\t.long 0\n"); \
  4733. + fprintf (FILE, "\t.long 0\n"); \
  4734. + } while (0)
  4735. +#endif
  4736. +
  4737. +/* A C expression for the size in bytes of the trampoline, as an integer. */
  4738. +#define TRAMPOLINE_SIZE 0x1b
  4739. +
  4740. +/* Alignment required for trampolines, in bits.
  4741. +
  4742. + If you don't define this macro, the value of `BIGGEST_ALIGNMENT' is used for
  4743. + aligning trampolines. */
  4744. +#define TRAMPOLINE_ALIGNMENT 32
  4745. +
  4746. +/* A C statement to initialize the variable parts of a trampoline. ADDR is an
  4747. + RTX for the address of the trampoline; FNADDR is an RTX for the address of
  4748. + the nested function; STATIC_CHAIN is an RTX for the static chain value that
  4749. + should be passed to the function when it is called. */
  4750. +#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
  4751. +{ \
  4752. + emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x14)), \
  4753. + (CXT)); \
  4754. + emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x18)), \
  4755. + (FNADDR)); \
  4756. +}
  4757. +
  4758. +/* Ubicom32 supports pre and post increment/decrement addressing. */
  4759. +#define HAVE_POST_INCREMENT 1
  4760. +#define HAVE_PRE_INCREMENT 1
  4761. +#define HAVE_POST_DECREMENT 1
  4762. +#define HAVE_PRE_DECREMENT 1
  4763. +
  4764. +/* Ubicom32 supports pre and post address side-effects with constants
  4765. + other than the size of the memory operand. */
  4766. +#define HAVE_PRE_MODIFY_DISP 1
  4767. +#define HAVE_POST_MODIFY_DISP 1
  4768. +
  4769. +/* A C expression that is 1 if the RTX X is a constant which is a valid
  4770. + address. On most machines, this can be defined as `CONSTANT_P (X)',
  4771. + but a few machines are more restrictive in which constant addresses
  4772. + are supported.
  4773. +
  4774. + `CONSTANT_P' accepts integer-values expressions whose values are not
  4775. + explicitly known, such as `symbol_ref', `label_ref', and `high'
  4776. + expressions and `const' arithmetic expressions, in addition to
  4777. + `const_int' and `const_double' expressions. */
  4778. +#define CONSTANT_ADDRESS_P(X) \
  4779. + (GET_CODE (X) == LABEL_REF \
  4780. + || (GET_CODE (X) == CONST \
  4781. + && GET_CODE (XEXP (X, 0)) == PLUS \
  4782. + && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF))
  4783. +
  4784. +/* Ubicom32 supports a maximum of 2 registers in a valid memory address.
  4785. + One is always an address register while a second, optional, one may be a
  4786. + data register. */
  4787. +#define MAX_REGS_PER_ADDRESS 2
  4788. +
  4789. +/* A C compound statement with a conditional `goto LABEL;' executed if X (an
  4790. + RTX) is a legitimate memory address on the target machine for a memory
  4791. + operand of mode MODE.
  4792. +
  4793. + It usually pays to define several simpler macros to serve as subroutines for
  4794. + this one. Otherwise it may be too complicated to understand.
  4795. +
  4796. + This macro must exist in two variants: a strict variant and a non-strict
  4797. + one. The strict variant is used in the reload pass. It must be defined so
  4798. + that any pseudo-register that has not been allocated a hard register is
  4799. + considered a memory reference. In contexts where some kind of register is
  4800. + required, a pseudo-register with no hard register must be rejected.
  4801. +
  4802. + The non-strict variant is used in other passes. It must be defined to
  4803. + accept all pseudo-registers in every context where some kind of register is
  4804. + required.
  4805. +
  4806. + Compiler source files that want to use the strict variant of this macro
  4807. + define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
  4808. + conditional to define the strict variant in that case and the non-strict
  4809. + variant otherwise.
  4810. +
  4811. + Subroutines to check for acceptable registers for various purposes (one for
  4812. + base registers, one for index registers, and so on) are typically among the
  4813. + subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'. Then only these
  4814. + subroutine macros need have two variants; the higher levels of macros may be
  4815. + the same whether strict or not.
  4816. +
  4817. + Normally, constant addresses which are the sum of a `symbol_ref' and an
  4818. + integer are stored inside a `const' RTX to mark them as constant.
  4819. + Therefore, there is no need to recognize such sums specifically as
  4820. + legitimate addresses. Normally you would simply recognize any `const' as
  4821. + legitimate.
  4822. +
  4823. + Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that
  4824. + are not marked with `const'. It assumes that a naked `plus' indicates
  4825. + indexing. If so, then you *must* reject such naked constant sums as
  4826. + illegitimate addresses, so that none of them will be given to
  4827. + `PRINT_OPERAND_ADDRESS'.
  4828. +
  4829. + On some machines, whether a symbolic address is legitimate depends on the
  4830. + section that the address refers to. On these machines, define the macro
  4831. + `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
  4832. + then check for it here. When you see a `const', you will have to look
  4833. + inside it to find the `symbol_ref' in order to determine the section.
  4834. +
  4835. + The best way to modify the name string is by adding text to the beginning,
  4836. + with suitable punctuation to prevent any ambiguity. Allocate the new name
  4837. + in `saveable_obstack'. You will have to modify `ASM_OUTPUT_LABELREF' to
  4838. + remove and decode the added text and output the name accordingly, and define
  4839. + `STRIP_NAME_ENCODING' to access the original name string.
  4840. +
  4841. + You can check the information stored here into the `symbol_ref' in the
  4842. + definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
  4843. + `PRINT_OPERAND_ADDRESS'. */
  4844. +/* On the ubicom32, the value in the address register must be
  4845. + in the same memory space/segment as the effective address.
  4846. +
  4847. + This is problematical for reload since it does not understand
  4848. + that base+index != index+base in a memory reference. */
  4849. +
  4850. +#ifdef REG_OK_STRICT
  4851. +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
  4852. + if (ubicom32_legitimate_address_p (MODE, X, 1)) goto ADDR;
  4853. +#else
  4854. +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
  4855. + if (ubicom32_legitimate_address_p (MODE, X, 0)) goto ADDR;
  4856. +#endif
  4857. +
  4858. +/* Try machine-dependent ways of modifying an illegitimate address
  4859. + to be legitimate. If we find one, return the new, valid address.
  4860. + This macro is used in only one place: `memory_address' in explow.c.
  4861. +
  4862. + OLDX is the address as it was before break_out_memory_refs was called.
  4863. + In some cases it is useful to look at this to decide what needs to be done.
  4864. +
  4865. + MODE and WIN are passed so that this macro can use
  4866. + GO_IF_LEGITIMATE_ADDRESS.
  4867. +
  4868. + It is always safe for this macro to do nothing. It exists to recognize
  4869. + opportunities to optimize the output.
  4870. +
  4871. + On RS/6000, first check for the sum of a register with a constant
  4872. + integer that is out of range. If so, generate code to add the
  4873. + constant with the low-order 16 bits masked to the register and force
  4874. + this result into another register (this can be done with `cau').
  4875. + Then generate an address of REG+(CONST&0xffff), allowing for the
  4876. + possibility of bit 16 being a one.
  4877. +
  4878. + Then check for the sum of a register and something not constant, try to
  4879. + load the other things into a register and return the sum. */
  4880. +
  4881. +#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
  4882. +{ \
  4883. + rtx result = ubicom32_legitimize_address ((X), (OLDX), (MODE)); \
  4884. + if (result != NULL_RTX) \
  4885. + { \
  4886. + (X) = result; \
  4887. + goto WIN; \
  4888. + } \
  4889. +}
  4890. +
  4891. +/* Try a machine-dependent way of reloading an illegitimate address
  4892. + operand. If we find one, push the reload and jump to WIN. This
  4893. + macro is used in only one place: `find_reloads_address' in reload.c. */
  4894. +#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \
  4895. +{ \
  4896. + rtx new_rtx = ubicom32_legitimize_reload_address ((AD), (MODE), (OPNUM), (int)(TYPE)); \
  4897. + if (new_rtx) \
  4898. + { \
  4899. + (AD) = new_rtx; \
  4900. + goto WIN; \
  4901. + } \
  4902. +}
  4903. +
  4904. +/* A C statement or compound statement with a conditional `goto LABEL;'
  4905. + executed if memory address X (an RTX) can have different meanings depending
  4906. + on the machine mode of the memory reference it is used for or if the address
  4907. + is valid for some modes but not others.
  4908. +
  4909. + Autoincrement and autodecrement addresses typically have mode-dependent
  4910. + effects because the amount of the increment or decrement is the size of the
  4911. + operand being addressed. Some machines have other mode-dependent addresses.
  4912. + Many RISC machines have no mode-dependent addresses.
  4913. +
  4914. + You may assume that ADDR is a valid address for the machine. */
  4915. +#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
  4916. + if (ubicom32_mode_dependent_address_p (ADDR)) \
  4917. + goto LABEL;
  4918. +
  4919. +/* A C expression that is nonzero if X is a legitimate constant for an
  4920. + immediate operand on the target machine. You can assume that X
  4921. + satisfies `CONSTANT_P', so you need not check this. In fact, `1' is
  4922. + a suitable definition for this macro on machines where anything
  4923. + `CONSTANT_P' is valid. */
  4924. +#define LEGITIMATE_CONSTANT_P(X) \
  4925. + ubicom32_legitimate_constant_p ((X))
  4926. +
  4927. +/* Moves between registers are pretty-much single instructions for
  4928. + Ubicom32. We make this the default "2" that gcc likes. */
  4929. +#define REGISTER_MOVE_COST(MODE, FROM, TO) 2
  4930. +
  4931. +/* This is a little bit of magic from the S390 port that wins 2% on code
  4932. + size when building the Linux kernel! Unfortunately while it wins on
  4933. + that size the user-space apps built using FD-PIC don't improve and the
  4934. + performance is lower because we put more pressure on the caches. We may
  4935. + want this back on some future CPU that has higher cache performance. */
  4936. +/* #define IRA_HARD_REGNO_ADD_COST_MULTIPLIER(regno) 0.5 */
  4937. +
  4938. +/* Moves between registers and memory are more expensive than between
  4939. + registers because we have caches and write buffers that slow things
  4940. + down! */
  4941. +#define MEMORY_MOVE_COST(MODE, CLASS, IN) 2
  4942. +
  4943. +/* A fall-through branch is very low cost but anything that changes the PC
  4944. + incurs a major pipeline hazard. We don't make the full extent of this
  4945. + hazard visible because we hope that multiple threads will absorb much
  4946. + of the cost and so we don't want a jump being replaced with, say, 7
  4947. + instructions. */
  4948. +#define BRANCH_COST(SPEED_P, PREDICTABLE_P) \
  4949. + ((PREDICTABLE_P) ? 1 : 3)
  4950. +
  4951. +/* Define this macro as a C expression which is nonzero if accessing less than
  4952. + a word of memory (i.e. a `char' or a `short') is no faster than accessing a
  4953. + word of memory, i.e., if such access require more than one instruction or if
  4954. + there is no difference in cost between byte and (aligned) word loads.
  4955. +
  4956. + When this macro is not defined, the compiler will access a field by finding
  4957. + the smallest containing object; when it is defined, a fullword load will be
  4958. + used if alignment permits. Unless bytes accesses are faster than word
  4959. + accesses, using word accesses is preferable since it may eliminate
  4960. + subsequent memory access if subsequent accesses occur to other fields in the
  4961. + same word of the structure, but to different bytes. */
  4962. +#define SLOW_BYTE_ACCESS 0
  4963. +
  4964. +/* The number of scalar move insns which should be generated instead of a
  4965. + string move insn or a library call. Increasing the value will always make
  4966. + code faster, but eventually incurs high cost in increased code size.
  4967. +
  4968. + If you don't define this, a reasonable default is used. */
  4969. +/* According to expr.c, a value of around 6 should minimize code size. */
  4970. +#define MOVE_RATIO(SPEED) 6
  4971. +
  4972. +/* We're much better off calling a constant function address with the
  4973. + Ubicom32 architecture because we have an opcode for doing so. Don't
  4974. + let the compiler extract function addresses as common subexpressions
  4975. + into an address register. */
  4976. +#define NO_FUNCTION_CSE
  4977. +
  4978. +#define SELECT_CC_MODE(OP, X, Y) ubicom32_select_cc_mode (OP, X, Y)
  4979. +
  4980. +#define REVERSIBLE_CC_MODE(MODE) 1
  4981. +
  4982. +/* Canonicalize a comparison from one we don't have to one we do have. */
  4983. +#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
  4984. + ubicom32_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
  4985. +
  4986. +/* Dividing the output into sections. */
  4987. +
  4988. +/* A C expression whose value is a string containing the assembler operation
  4989. + that should precede instructions and read-only data. Normally `".text"' is
  4990. + right. */
  4991. +#define TEXT_SECTION_ASM_OP "\t.section .text"
  4992. +
  4993. +/* A C expression whose value is a string containing the assembler operation to
  4994. + identify the following data as writable initialized data. Normally
  4995. + `".data"' is right. */
  4996. +#define DATA_SECTION_ASM_OP "\t.section .data"
  4997. +
  4998. +
  4999. +/* If defined, a C expression whose value is a string containing the
  5000. + assembler operation to identify the following data as
  5001. + uninitialized global data. If not defined, and neither
  5002. + `ASM_OUTPUT_BSS' nor `ASM_OUTPUT_ALIGNED_BSS' are defined,
  5003. + uninitialized global data will be output in the data section if
  5004. + `-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
  5005. + used. */
  5006. +#define BSS_SECTION_ASM_OP "\t.section .bss"
  5007. +
  5008. +/* This is how we tell the assembler that a symbol is weak. */
  5009. +
  5010. +#define ASM_WEAKEN_LABEL(FILE, NAME) \
  5011. + do \
  5012. + { \
  5013. + fputs ("\t.weak\t", (FILE)); \
  5014. + assemble_name ((FILE), (NAME)); \
  5015. + fputc ('\n', (FILE)); \
  5016. + } \
  5017. + while (0)
  5018. +
  5019. +/* The Overall Framework of an Assembler File. */
  5020. +
  5021. +#undef SET_ASM_OP
  5022. +#define SET_ASM_OP "\t.set\t"
  5023. +
  5024. +/* A C string constant describing how to begin a comment in the target
  5025. + assembler language. The compiler assumes that the comment will end at the
  5026. + end of the line. */
  5027. +#define ASM_COMMENT_START ";"
  5028. +
  5029. +/* A C string constant for text to be output before each `asm' statement or
  5030. + group of consecutive ones. Normally this is `"#APP"', which is a comment
  5031. + that has no effect on most assemblers but tells the GNU assembler that it
  5032. + must check the lines that follow for all valid assembler constructs. */
  5033. +#define ASM_APP_ON "#APP\n"
  5034. +
  5035. +/* A C string constant for text to be output after each `asm' statement or
  5036. + group of consecutive ones. Normally this is `"#NO_APP"', which tells the
  5037. + GNU assembler to resume making the time-saving assumptions that are valid
  5038. + for ordinary compiler output. */
  5039. +#define ASM_APP_OFF "#NO_APP\n"
  5040. +
  5041. +/* Like `ASM_OUTPUT_BSS' except takes the required alignment as a separate,
  5042. + explicit argument. If you define this macro, it is used in place of
  5043. + `ASM_OUTPUT_BSS', and gives you more flexibility in handling the required
  5044. + alignment of the variable. The alignment is specified as the number of
  5045. + bits.
  5046. +
  5047. + Try to use function `asm_output_aligned_bss' defined in file `varasm.c' when
  5048. + defining this macro. */
  5049. +#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
  5050. + asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
  5051. +
  5052. +/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
  5053. + newly allocated string made from the string NAME and the number NUMBER, with
  5054. + some suitable punctuation added. Use `alloca' to get space for the string.
  5055. +
  5056. + The string will be used as an argument to `ASM_OUTPUT_LABELREF' to produce
  5057. + an assembler label for an internal static variable whose name is NAME.
  5058. + Therefore, the string must be such as to result in valid assembler code.
  5059. + The argument NUMBER is different each time this macro is executed; it
  5060. + prevents conflicts between similarly-named internal static variables in
  5061. + different scopes.
  5062. +
  5063. + Ideally this string should not be a valid C identifier, to prevent any
  5064. + conflict with the user's own symbols. Most assemblers allow periods or
  5065. + percent signs in assembler symbols; putting at least one of these between
  5066. + the name and the number will suffice. */
  5067. +#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
  5068. + ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
  5069. + sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
  5070. +
  5071. +#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
  5072. + sprintf (STRING, "*.%s%ld", PREFIX, (long)(NUM))
  5073. +/* A C statement to store into the string STRING a label whose name
  5074. + is made from the string PREFIX and the number NUM.
  5075. +
  5076. + This string, when output subsequently by `assemble_name', should
  5077. + produce the output that `(*targetm.asm_out.internal_label)' would produce
  5078. + with the same PREFIX and NUM.
  5079. +
  5080. + If the string begins with `*', then `assemble_name' will output
  5081. + the rest of the string unchanged. It is often convenient for
  5082. + `ASM_GENERATE_INTERNAL_LABEL' to use `*' in this way. If the
  5083. + string doesn't start with `*', then `ASM_OUTPUT_LABELREF' gets to
  5084. + output the string, and may change it. (Of course,
  5085. + `ASM_OUTPUT_LABELREF' is also part of your machine description, so
  5086. + you should know what it does on your machine.) */
  5087. +
  5088. +/* This says how to output assembler code to declare an
  5089. + uninitialized external linkage data object. Under SVR4,
  5090. + the linker seems to want the alignment of data objects
  5091. + to depend on their types. We do exactly that here. */
  5092. +
  5093. +#define COMMON_ASM_OP "\t.comm\t"
  5094. +
  5095. +#undef ASM_OUTPUT_COMMON
  5096. +#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
  5097. + do \
  5098. + { \
  5099. + fprintf ((FILE), "%s", COMMON_ASM_OP); \
  5100. + assemble_name ((FILE), (NAME)); \
  5101. + fprintf ((FILE), ", %u\n", (SIZE)); \
  5102. + } \
  5103. + while (0)
  5104. +
  5105. +/* This says how to output assembler code to declare an
  5106. + uninitialized internal linkage data object. Under SVR4,
  5107. + the linker seems to want the alignment of data objects
  5108. + to depend on their types. We do exactly that here. */
  5109. +#define LOCAL_ASM_OP "\t.lcomm\t"
  5110. +
  5111. +#undef ASM_OUTPUT_LOCAL
  5112. +#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
  5113. + do \
  5114. + { \
  5115. + fprintf ((FILE), "%s", LOCAL_ASM_OP); \
  5116. + assemble_name ((FILE), (NAME)); \
  5117. + fprintf ((FILE), ", %u\n", (SIZE)); \
  5118. + } \
  5119. + while (0)
  5120. +
  5121. +/* Globalizing directive for a label. */
  5122. +#define GLOBAL_ASM_OP ".global\t"
  5123. +
  5124. +/* Output the operand of an instruction. */
  5125. +#define PRINT_OPERAND(FILE, X, CODE) \
  5126. + ubicom32_print_operand(FILE, X, CODE)
  5127. +
  5128. +/* Output the address of an operand. */
  5129. +#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
  5130. + ubicom32_print_operand_address (FILE, ADDR)
  5131. +
  5132. +/* A C expression to output to STREAM some assembler code which will push hard
  5133. + register number REGNO onto the stack. The code need not be optimal, since
  5134. + this macro is used only when profiling. */
  5135. +#define ASM_OUTPUT_REG_PUSH(FILE, REGNO)
  5136. +
  5137. +/* A C expression to output to STREAM some assembler code which will pop hard
  5138. + register number REGNO off of the stack. The code need not be optimal, since
  5139. + this macro is used only when profiling. */
  5140. +#define ASM_OUTPUT_REG_POP(FILE, REGNO)
  5141. +
  5142. +/* This macro should be provided on machines where the addresses in a dispatch
  5143. + table are relative to the table's own address.
  5144. +
  5145. + The definition should be a C statement to output to the stdio stream STREAM
  5146. + an assembler pseudo-instruction to generate a difference between two labels.
  5147. + VALUE and REL are the numbers of two internal labels. The definitions of
  5148. + these labels are output using `ASM_OUTPUT_INTERNAL_LABEL', and they must be
  5149. + printed in the same way here. For example,
  5150. +
  5151. + fprintf (STREAM, "\t.word L%d-L%d\n", VALUE, REL) */
  5152. +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
  5153. + fprintf (FILE, "\t%s .L%d-.L%d\n", ".long", VALUE, REL)
  5154. +
  5155. +/* This macro should be provided on machines where the addresses in a dispatch
  5156. + table are absolute.
  5157. +
  5158. + The definition should be a C statement to output to the stdio stream STREAM
  5159. + an assembler pseudo-instruction to generate a reference to a label. VALUE
  5160. + is the number of an internal label whose definition is output using
  5161. + `ASM_OUTPUT_INTERNAL_LABEL'. For example,
  5162. +
  5163. + fprintf (STREAM, "\t.word L%d\n", VALUE) */
  5164. +#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
  5165. + fprintf (STREAM, "\t.word .L%d\n", VALUE)
  5166. +
  5167. +/* Switch into a generic section. */
  5168. +#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
  5169. +
  5170. +/* Assembler Commands for Alignment. */
  5171. +
  5172. +#define ASM_OUTPUT_SKIP(STREAM, N) fprintf (STREAM, "\t.skip %d,0\n", N)
  5173. +/* A C statement to output to the stdio stream STREAM an assembler
  5174. + instruction to advance the location counter by NBYTES bytes.
  5175. + Those bytes should be zero when loaded. NBYTES will be a C
  5176. + expression of type `int'. */
  5177. +
  5178. +/* A C statement to output to the stdio stream STREAM an assembler command to
  5179. + advance the location counter to a multiple of 2 to the POWER bytes. POWER
  5180. + will be a C expression of type `int'. */
  5181. +#define ASM_OUTPUT_ALIGN(FILE, LOG) \
  5182. + if ((LOG) != 0) \
  5183. + fprintf (FILE, "\t.align %d\n", (LOG))
  5184. +
  5185. +/* A C expression that returns the DBX register number for the compiler
  5186. + register number REGNO. In simple cases, the value of this expression may be
  5187. + REGNO itself. But sometimes there are some registers that the compiler
  5188. + knows about and DBX does not, or vice versa. In such cases, some register
  5189. + may need to have one number in the compiler and another for DBX.
  5190. +
  5191. + If two registers have consecutive numbers inside GNU CC, and they can be
  5192. + used as a pair to hold a multiword value, then they *must* have consecutive
  5193. + numbers after renumbering with `DBX_REGISTER_NUMBER'. Otherwise, debuggers
  5194. + will be unable to access such a pair, because they expect register pairs to
  5195. + be consecutive in their own numbering scheme.
  5196. +
  5197. + If you find yourself defining `DBX_REGISTER_NUMBER' in way that does not
  5198. + preserve register pairs, then what you must do instead is redefine the
  5199. + actual register numbering scheme.
  5200. +
  5201. + This declaration is required. */
  5202. +#define DBX_REGISTER_NUMBER(REGNO) REGNO
  5203. +
  5204. +/* A C expression that returns the integer offset value for an automatic
  5205. + variable having address X (an RTL expression). The default computation
  5206. + assumes that X is based on the frame-pointer and gives the offset from the
  5207. + frame-pointer. This is required for targets that produce debugging output
  5208. + for DBX or COFF-style debugging output for SDB and allow the frame-pointer
  5209. + to be eliminated when the `-g' options is used. */
  5210. +#define DEBUGGER_AUTO_OFFSET(X) \
  5211. + ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) \
  5212. + + (frame_pointer_needed \
  5213. + ? 0 : -initial_elimination_offset (FRAME_POINTER_REGNUM, \
  5214. + STACK_POINTER_REGNUM)))
  5215. +
  5216. +/* A C expression that returns the integer offset value for an argument having
  5217. + address X (an RTL expression). The nominal offset is OFFSET. */
  5218. +#define DEBUGGER_ARG_OFFSET(OFFSET, X) \
  5219. + ((GET_CODE (X) == PLUS ? OFFSET : 0) \
  5220. + + (frame_pointer_needed \
  5221. + ? 0 : -initial_elimination_offset (ARG_POINTER_REGNUM, \
  5222. + STACK_POINTER_REGNUM)))
  5223. +
  5224. +/* A C expression that returns the type of debugging output GNU CC produces
  5225. + when the user specifies `-g' or `-ggdb'. Define this if you have arranged
  5226. + for GNU CC to support more than one format of debugging output. Currently,
  5227. + the allowable values are `DBX_DEBUG', `SDB_DEBUG', `DWARF_DEBUG',
  5228. + `DWARF2_DEBUG', and `XCOFF_DEBUG'.
  5229. +
  5230. + The value of this macro only affects the default debugging output; the user
  5231. + can always get a specific type of output by using `-gstabs', `-gcoff',
  5232. + `-gdwarf-1', `-gdwarf-2', or `-gxcoff'.
  5233. +
  5234. + Defined in svr4.h.
  5235. +*/
  5236. +#undef PREFERRED_DEBUGGING_TYPE
  5237. +#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
  5238. +
  5239. +/* Define this macro if GNU CC should produce dwarf version 2 format debugging
  5240. + output in response to the `-g' option.
  5241. +
  5242. + To support optional call frame debugging information, you must also define
  5243. + `INCOMING_RETURN_ADDR_RTX' and either set `RTX_FRAME_RELATED_P' on the
  5244. + prologue insns if you use RTL for the prologue, or call `dwarf2out_def_cfa'
  5245. + and `dwarf2out_reg_save' as appropriate from `FUNCTION_PROLOGUE' if you
  5246. + don't.
  5247. +
  5248. + Defined in svr4.h. */
  5249. +
  5250. +#define DWARF2_DEBUGGING_INFO 1
  5251. +/*#define DWARF2_UNWIND_INFO 1*/
  5252. +#define DWARF2_UNWIND_INFO 0
  5253. +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNO)
  5254. +#define INCOMING_FRAME_SP_OFFSET 0
  5255. +#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGNO)
  5256. +#define EH_RETURN_FIRST 9
  5257. +#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) + EH_RETURN_FIRST : INVALID_REGNUM)
  5258. +
  5259. +/* The EH_RETURN_STACKADJ_RTX macro returns RTL which describes the
  5260. + location used to store the amount to ajdust the stack. This is
  5261. + usually a registers that is available from end of the function's body
  5262. + to the end of the epilogue. Thus, this cannot be a register used as a
  5263. + temporary by the epilogue.
  5264. +
  5265. + This must be an integer register. */
  5266. +#define EH_RETURN_STACKADJ_REGNO 11
  5267. +#define EH_RETURN_STACKADJ_RTX \
  5268. + gen_rtx_REG (Pmode, EH_RETURN_STACKADJ_REGNO)
  5269. +
  5270. +/* The EH_RETURN_HANDLER_RTX macro returns RTL which describes the
  5271. + location used to store the address the processor should jump to
  5272. + catch exception. This is usually a registers that is available from
  5273. + end of the function's body to the end of the epilogue. Thus, this
  5274. + cannot be a register used as a temporary by the epilogue.
  5275. +
  5276. + This must be an address register. */
  5277. +#define EH_RETURN_HANDLER_REGNO 18
  5278. +#define EH_RETURN_HANDLER_RTX \
  5279. + gen_rtx_REG (Pmode, EH_RETURN_HANDLER_REGNO)
  5280. +
  5281. +/* #define DWARF2_DEBUGGING_INFO */
  5282. +
  5283. +/* Define this macro if GNU CC should produce dwarf version 2-style
  5284. + line numbers. This usually requires extending the assembler to
  5285. + support them, and #defining DWARF2_LINE_MIN_INSN_LENGTH in the
  5286. + assembler configuration header files. */
  5287. +/* #define DWARF2_ASM_LINE_DEBUG_INFO 1 */
  5288. +
  5289. +
  5290. +/* An alias for a machine mode name. This is the machine mode that elements
  5291. + of a jump-table have. */
  5292. +#define CASE_VECTOR_MODE Pmode
  5293. +
  5294. +/* Smallest number of different values for which it is best to use a
  5295. + jump-table instead of a tree of conditional branches. For most Ubicom32
  5296. + targets this is quite small, but for the v1 architecture implementations
  5297. + we had very little data memory and so heavily prefer the tree approach
  5298. + rather than the jump tables. */
  5299. +#define CASE_VALUES_THRESHOLD ubicom32_case_values_threshold
  5300. +
  5301. +/* Register operations within the Ubicom32 architecture always operate on
  5302. + the whole register word and not just the sub-bits required for the opcode
  5303. + mode size. */
  5304. +#define WORD_REGISTER_OPERATIONS
  5305. +
  5306. +/* The maximum number of bytes that a single instruction can move quickly from
  5307. + memory to memory. */
  5308. +#define MOVE_MAX 4
  5309. +
  5310. +/* A C expression that is nonzero if on this machine the number of bits
  5311. + actually used for the count of a shift operation is equal to the number of
  5312. + bits needed to represent the size of the object being shifted. When this
  5313. + macro is non-zero, the compiler will assume that it is safe to omit a
  5314. + sign-extend, zero-extend, and certain bitwise `and' instructions that
  5315. + truncates the count of a shift operation. On machines that have
  5316. + instructions that act on bitfields at variable positions, which may include
  5317. + `bit test' instructions, a nonzero `SHIFT_COUNT_TRUNCATED' also enables
  5318. + deletion of truncations of the values that serve as arguments to bitfield
  5319. + instructions.
  5320. +
  5321. + If both types of instructions truncate the count (for shifts) and position
  5322. + (for bitfield operations), or if no variable-position bitfield instructions
  5323. + exist, you should define this macro.
  5324. +
  5325. + However, on some machines, such as the 80386 and the 680x0, truncation only
  5326. + applies to shift operations and not the (real or pretended) bitfield
  5327. + operations. Define `SHIFT_COUNT_TRUNCATED' to be zero on such machines.
  5328. + Instead, add patterns to the `md' file that include the implied truncation
  5329. + of the shift instructions.
  5330. +
  5331. + You need not define this macro if it would always have the value of zero. */
  5332. +#define SHIFT_COUNT_TRUNCATED 1
  5333. +
  5334. +/* A C expression which is nonzero if on this machine it is safe to "convert"
  5335. + an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
  5336. + than INPREC) by merely operating on it as if it had only OUTPREC bits.
  5337. +
  5338. + On many machines, this expression can be 1.
  5339. +
  5340. + When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for modes for
  5341. + which `MODES_TIEABLE_P' is 0, suboptimal code can result. If this is the
  5342. + case, making `TRULY_NOOP_TRUNCATION' return 0 in such cases may improve
  5343. + things. */
  5344. +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
  5345. +
  5346. +/* A C string constant that tells the GNU CC driver program options to pass
  5347. + to the assembler. It can also specify how to translate options you give
  5348. + to GNU CC into options for GNU CC to pass to the assembler. See the
  5349. + file `sun3.h' for an example of this.
  5350. +
  5351. + Defined in svr4.h. */
  5352. +#undef ASM_SPEC
  5353. +#define ASM_SPEC \
  5354. + "%{march=*:-m%*} %{!march=*:-mubicom32v4} %{mfdpic:-mfdpic}"
  5355. +
  5356. +#define LINK_SPEC "\
  5357. +%{h*} %{v:-V} \
  5358. +%{b} \
  5359. +%{mfdpic:-melf32ubicom32fdpic -z text} \
  5360. +%{static:-dn -Bstatic} \
  5361. +%{shared:-G -Bdynamic} \
  5362. +%{symbolic:-Bsymbolic} \
  5363. +%{G*} \
  5364. +%{YP,*} \
  5365. +%{Qy:} %{!Qn:-Qy}"
  5366. +
  5367. +#undef STARTFILE_SPEC
  5368. +#undef ENDFILE_SPEC
  5369. +
  5370. +/* The svr4.h LIB_SPEC with -leval and --*group tacked on */
  5371. +
  5372. +#undef LIB_SPEC
  5373. +#define LIB_SPEC "%{!shared:%{!symbolic:--start-group -lc -leval -lgcc --end-group}}"
  5374. +
  5375. +#undef HAVE_GAS_SHF_MERGE
  5376. +#define HAVE_GAS_SHF_MERGE 0
  5377. +
  5378. +#define HANDLE_SYSV_PRAGMA 1
  5379. +#undef HANDLE_PRAGMA_PACK
  5380. +
  5381. +typedef void (*ubicom32_func_ptr) (void);
  5382. +
  5383. +/* Define builtins for selected special-purpose instructions. */
  5384. +enum ubicom32_builtins
  5385. +{
  5386. + UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
  5387. + UBICOM32_BUILTIN_UBICOM32_SWAPB_4
  5388. +};
  5389. +
  5390. +extern rtx ubicom32_compare_op0;
  5391. +extern rtx ubicom32_compare_op1;
  5392. +
  5393. +#define TYPE_ASM_OP "\t.type\t"
  5394. +#define TYPE_OPERAND_FMT "@%s"
  5395. +
  5396. +#ifndef ASM_DECLARE_RESULT
  5397. +#define ASM_DECLARE_RESULT(FILE, RESULT)
  5398. +#endif
  5399. +
  5400. +/* These macros generate the special .type and .size directives which
  5401. + are used to set the corresponding fields of the linker symbol table
  5402. + entries in an ELF object file under SVR4. These macros also output
  5403. + the starting labels for the relevant functions/objects. */
  5404. +
  5405. +/* Write the extra assembler code needed to declare a function properly.
  5406. + Some svr4 assemblers need to also have something extra said about the
  5407. + function's return value. We allow for that here. */
  5408. +
  5409. +#ifndef ASM_DECLARE_FUNCTION_NAME
  5410. +#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
  5411. + do \
  5412. + { \
  5413. + ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
  5414. + ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
  5415. + ASM_OUTPUT_LABEL (FILE, NAME); \
  5416. + } \
  5417. + while (0)
  5418. +#endif
  5419. --- /dev/null
  5420. +++ b/gcc/config/ubicom32/ubicom32.md
  5421. @@ -0,0 +1,3753 @@
  5422. +; GCC machine description for Ubicom32
  5423. +;
  5424. +; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
  5425. +; Foundation, Inc.
  5426. +; Contributed by Ubicom, Inc.
  5427. +;
  5428. +; This file is part of GCC.
  5429. +;
  5430. +; GCC is free software; you can redistribute it and/or modify
  5431. +; it under the terms of the GNU General Public License as published by
  5432. +; the Free Software Foundation; either version 3, or (at your option)
  5433. +; any later version.
  5434. +;
  5435. +; GCC is distributed in the hope that it will be useful,
  5436. +; but WITHOUT ANY WARRANTY; without even the implied warranty of
  5437. +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  5438. +; GNU General Public License for more details.
  5439. +;
  5440. +; You should have received a copy of the GNU General Public License
  5441. +; along with GCC; see the file COPYING3. If not see
  5442. +; <http://www.gnu.org/licenses/>.
  5443. +
  5444. +(define_constants
  5445. + [(AUX_DATA_REGNO 15)
  5446. + (LINK_REGNO 21)
  5447. + (SP_REGNO 23)
  5448. + (ACC0_HI_REGNO 24)
  5449. + (ACC1_HI_REGNO 26)
  5450. + (CC_REGNO 30)])
  5451. +
  5452. +(define_constants
  5453. + [(UNSPEC_FDPIC_GOT 0)
  5454. + (UNSPEC_FDPIC_GOT_FUNCDESC 1)])
  5455. +
  5456. +(define_constants
  5457. + [(UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC 0)])
  5458. +
  5459. +;; Types of instructions (for scheduling purposes).
  5460. +
  5461. +(define_attr "type" "mul,addr,other"
  5462. + (const_string "other"))
  5463. +
  5464. +; Define instruction scheduling characteristics. We can only issue
  5465. +; one instruction per clock so we don't need to define CPU units.
  5466. +;
  5467. +(define_automaton "ubicom32")
  5468. +
  5469. +(define_cpu_unit "i_pipeline" "ubicom32");
  5470. +
  5471. +; We have a 4 cycle hazard associated with address calculations which
  5472. +; seems rather tricky to avoid so we go with a defensive assumption
  5473. +; that almost anything can be used to generate addresses.
  5474. +;
  5475. +;(define_insn_reservation "ubicom32_other" 4
  5476. +; (eq_attr "type" "other")
  5477. +; "i_pipeline")
  5478. +
  5479. +; Some moves don't generate hazards.
  5480. +;
  5481. +;(define_insn_reservation "ubicom32_addr" 1
  5482. +; (eq_attr "type" "addr")
  5483. +; "i_pipeline")
  5484. +
  5485. +; We need 3 cycles between a multiply instruction and any use of the
  5486. +; matching accumulator register(s).
  5487. +;
  5488. +(define_insn_reservation "ubicom32_mul" 4
  5489. + (eq_attr "type" "mul")
  5490. + "i_pipeline")
  5491. +
  5492. +(define_attr "length" ""
  5493. + (const_int 4))
  5494. +
  5495. +(include "predicates.md")
  5496. +(include "constraints.md")
  5497. +
  5498. +; 8-bit move with no change to the flags reg.
  5499. +;
  5500. +(define_insn "movqi"
  5501. + [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
  5502. + (match_operand:QI 1 "ubicom32_move_operand" "g"))]
  5503. + ""
  5504. + "move.1\\t%0, %1")
  5505. +
  5506. +; Combiner-generated 8-bit move with the zero flag set accordingly.
  5507. +;
  5508. +(define_insn "movqi_ccszn"
  5509. + [(set (reg CC_REGNO)
  5510. + (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
  5511. + (const_int 0)))
  5512. + (set (match_operand:QI 1 "nonimmediate_operand" "=rm")
  5513. + (match_dup 0))]
  5514. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  5515. + "ext.1\\t%1, %0")
  5516. +
  5517. +; Combine isn't very good at merging some types of operations so we
  5518. +; have to make do with a peephole. It's not as effective but it's better
  5519. +; than doing nothing.
  5520. +;
  5521. +(define_peephole2
  5522. + [(set (match_operand:QI 0 "nonimmediate_operand" "")
  5523. + (match_operand:QI 1 "nonimmediate_operand" ""))
  5524. + (set (match_operand 2 "ubicom32_cc_register_operand" "")
  5525. + (match_operator 3 "ubicom32_compare_operator"
  5526. + [(match_dup 0)
  5527. + (const_int 0)]))]
  5528. + "(GET_MODE (operands[2]) == CCSZNmode
  5529. + || GET_MODE (operands[2]) == CCSZmode)"
  5530. + [(parallel
  5531. + [(set (match_dup 2)
  5532. + (match_op_dup 3
  5533. + [(match_dup 1)
  5534. + (const_int 0)]))
  5535. + (set (match_dup 0)
  5536. + (match_dup 1))])]
  5537. + "")
  5538. +
  5539. +; Combine isn't very good at merging some types of operations so we
  5540. +; have to make do with a peephole. It's not as effective but it's better
  5541. +; than doing nothing.
  5542. +;
  5543. +(define_peephole2
  5544. + [(set (match_operand:QI 0 "nonimmediate_operand" "")
  5545. + (match_operand:QI 1 "nonimmediate_operand" ""))
  5546. + (set (match_operand 2 "ubicom32_cc_register_operand" "")
  5547. + (match_operator 3 "ubicom32_compare_operator"
  5548. + [(match_dup 1)
  5549. + (const_int 0)]))]
  5550. + "(GET_MODE (operands[2]) == CCSZNmode
  5551. + || GET_MODE (operands[2]) == CCSZmode)"
  5552. + [(parallel
  5553. + [(set (match_dup 2)
  5554. + (match_op_dup 3
  5555. + [(match_dup 1)
  5556. + (const_int 0)]))
  5557. + (set (match_dup 0)
  5558. + (match_dup 1))])]
  5559. + "")
  5560. +
  5561. +; 16-bit move with no change to the flags reg.
  5562. +;
  5563. +(define_insn "movhi"
  5564. + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
  5565. + (match_operand:HI 1 "ubicom32_move_operand" "g"))]
  5566. + ""
  5567. + "*
  5568. + {
  5569. + if (CONST_INT_P (operands[1]))
  5570. + return \"movei\\t%0, %1\";
  5571. +
  5572. + return \"move.2\\t%0, %1\";
  5573. + }")
  5574. +
  5575. +; Combiner-generated 16-bit move with the zero flag set accordingly.
  5576. +;
  5577. +(define_insn "movhi_ccszn"
  5578. + [(set (reg CC_REGNO)
  5579. + (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
  5580. + (const_int 0)))
  5581. + (set (match_operand:HI 1 "nonimmediate_operand" "=rm")
  5582. + (match_dup 0))]
  5583. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  5584. + "ext.2\\t%1, %0")
  5585. +
  5586. +; Combine isn't very good at merging some types of operations so we
  5587. +; have to make do with a peephole. It's not as effective but it's better
  5588. +; than doing nothing.
  5589. +;
  5590. +(define_peephole2
  5591. + [(set (match_operand:HI 0 "nonimmediate_operand" "")
  5592. + (match_operand:HI 1 "nonimmediate_operand" ""))
  5593. + (set (match_operand 2 "ubicom32_cc_register_operand" "")
  5594. + (match_operator 3 "ubicom32_compare_operator"
  5595. + [(match_dup 0)
  5596. + (const_int 0)]))]
  5597. + "(GET_MODE (operands[2]) == CCSZNmode
  5598. + || GET_MODE (operands[2]) == CCSZmode)"
  5599. + [(parallel
  5600. + [(set (match_dup 2)
  5601. + (match_op_dup 3
  5602. + [(match_dup 1)
  5603. + (const_int 0)]))
  5604. + (set (match_dup 0)
  5605. + (match_dup 1))])]
  5606. + "")
  5607. +
  5608. +; Combine isn't very good at merging some types of operations so we
  5609. +; have to make do with a peephole. It's not as effective but it's better
  5610. +; than doing nothing.
  5611. +;
  5612. +(define_peephole2
  5613. + [(set (match_operand:HI 0 "nonimmediate_operand" "")
  5614. + (match_operand:HI 1 "nonimmediate_operand" ""))
  5615. + (set (match_operand 2 "ubicom32_cc_register_operand" "")
  5616. + (match_operator 3 "ubicom32_compare_operator"
  5617. + [(match_dup 1)
  5618. + (const_int 0)]))]
  5619. + "(GET_MODE (operands[2]) == CCSZNmode
  5620. + || GET_MODE (operands[2]) == CCSZmode)"
  5621. + [(parallel
  5622. + [(set (match_dup 2)
  5623. + (match_op_dup 3
  5624. + [(match_dup 1)
  5625. + (const_int 0)]))
  5626. + (set (match_dup 0)
  5627. + (match_dup 1))])]
  5628. + "")
  5629. +
  5630. +; 32-bit move with no change to the flags reg.
  5631. +;
  5632. +(define_expand "movsi"
  5633. + [(set (match_operand:SI 0 "nonimmediate_operand" "")
  5634. + (match_operand:SI 1 "general_operand" ""))]
  5635. + ""
  5636. + "{
  5637. + /* Convert any complexities in operand 1 into something that can just
  5638. + fall into the default expander code. */
  5639. + ubicom32_expand_movsi (operands);
  5640. + }")
  5641. +
  5642. +(define_insn "movsi_high"
  5643. + [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
  5644. + (high:SI (match_operand:SI 1 "ubicom32_symbolic_address_operand" "s")))]
  5645. + ""
  5646. + "moveai\\t%0, #%%hi(%E1)")
  5647. +
  5648. +(define_insn "movsi_lo_sum"
  5649. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
  5650. + (lo_sum:SI (match_operand:SI 1 "ubicom32_address_register_operand" "a")
  5651. + (match_operand:SI 2 "immediate_operand" "s")))]
  5652. + ""
  5653. + "lea.1\\t%0, %%lo(%E2)(%1)")
  5654. +
  5655. +(define_insn "movsi_internal"
  5656. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
  5657. + (match_operand:SI 1 "ubicom32_move_operand" "rmnY"))]
  5658. + ""
  5659. + "*
  5660. + {
  5661. + if (CONST_INT_P (operands[1]))
  5662. + {
  5663. + ubicom32_emit_move_const_int (operands[0], operands[1]);
  5664. + return \"\";
  5665. + }
  5666. +
  5667. + if (GET_CODE (operands[1]) == CONST_DOUBLE)
  5668. + {
  5669. + HOST_WIDE_INT i = CONST_DOUBLE_LOW (operands[1]);
  5670. +
  5671. + ubicom32_emit_move_const_int (operands[0], GEN_INT (i));
  5672. + return \"\";
  5673. + }
  5674. +
  5675. + if (ubicom32_address_register_operand (operands[0], VOIDmode)
  5676. + && register_operand (operands[1], VOIDmode))
  5677. + {
  5678. + if (ubicom32_address_register_operand (operands[1], VOIDmode))
  5679. + return \"lea.1\\t%0, 0(%1)\";
  5680. +
  5681. + /* Use movea here to utilize the hazard bypass in the >= v4 ISA. */
  5682. + if (ubicom32_v4)
  5683. + return \"movea\\t%0, %1\";
  5684. +
  5685. + return \"move.4\\t%0, %1\";
  5686. + }
  5687. +
  5688. + return \"move.4\\t%0, %1\";
  5689. + }")
  5690. +
  5691. +; If we're not dependent on the state of the condition codes we can construct
  5692. +; constants of value 2^n by using a bset.
  5693. +;
  5694. +(define_peephole2
  5695. + [(set (match_operand:SI 0 "nonimmediate_operand" "")
  5696. + (match_operand:SI 1 "const_int_operand" ""))]
  5697. + "(exact_log2 (INTVAL (operands[1])) > 14
  5698. + && peep2_regno_dead_p (0, CC_REGNO))"
  5699. + [(parallel
  5700. + [(set (match_dup 0)
  5701. + (ior:SI (const_int 0)
  5702. + (match_dup 1)))
  5703. + (clobber (reg:CC CC_REGNO))])]
  5704. + "")
  5705. +
  5706. +; If we're not dependent on the state of the condition codes we can construct
  5707. +; constants of value ~(2^n) by using a bclr.
  5708. +;
  5709. +(define_peephole2
  5710. + [(set (match_operand:SI 0 "nonimmediate_operand" "")
  5711. + (match_operand:SI 1 "const_int_operand" ""))]
  5712. + "(exact_log2 (~INTVAL (operands[1])) > 14
  5713. + && peep2_regno_dead_p (0, CC_REGNO))"
  5714. + [(parallel
  5715. + [(set (match_dup 0)
  5716. + (and:SI (const_int -1)
  5717. + (match_dup 1)))
  5718. + (clobber (reg:CC CC_REGNO))])]
  5719. + "")
  5720. +
  5721. +; For 32-bit constants that have bits 0 through 24 and bit 31 set the same
  5722. +; we can use swapb.4!
  5723. +;
  5724. +(define_peephole2
  5725. + [(set (match_operand:SI 0 "nonimmediate_operand" "")
  5726. + (match_operand:SI 1 "const_int_operand" ""))]
  5727. + "(ubicom32_v4
  5728. + && (INTVAL (operands[1]) & 0xffffffff) != 0xffffffff
  5729. + && (INTVAL (operands[1]) & 0xffffffff) != 0
  5730. + && ((INTVAL (operands[1]) & 0x80ffffff) == 0
  5731. + || (INTVAL (operands[1]) & 0x80ffffff) == 0x80ffffff))"
  5732. + [(set (match_dup 0)
  5733. + (bswap:SI (match_dup 2)))]
  5734. + "{
  5735. + operands[2] = GEN_INT (INTVAL (operands[1]) >> 24);
  5736. + }")
  5737. +
  5738. +; If this is a write of a constant to memory look to see if we can usefully
  5739. +; transform this into 2 smaller writes.
  5740. +;
  5741. +(define_peephole2
  5742. + [(set (match_operand:SI 0 "memory_operand" "")
  5743. + (match_operand:SI 1 "const_int_operand" ""))]
  5744. + "! satisfies_constraint_I (operands[1])
  5745. + && ubicom32_legitimate_address_p (HImode, plus_constant (XEXP (operands[0], 0), 2), 1)"
  5746. + [(set (match_dup 4) (match_dup 2))
  5747. + (set (match_dup 5) (match_dup 3))]
  5748. + "{
  5749. + rtx low_hword_addr;
  5750. +
  5751. + operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
  5752. + operands[3] = gen_lowpart (HImode, operands[1]);
  5753. +
  5754. + operands[4] = gen_rtx_MEM (HImode, XEXP (operands[0], 0));
  5755. + MEM_COPY_ATTRIBUTES (operands[4], operands[0]);
  5756. +
  5757. + low_hword_addr = plus_constant (XEXP (operands[0], 0), 2);
  5758. + operands[5] = gen_rtx_MEM (HImode, low_hword_addr);
  5759. + MEM_COPY_ATTRIBUTES (operands[5], operands[0]);
  5760. + }")
  5761. +
  5762. +; If we're writing memory and we've not found a better way to do this then
  5763. +; try loading into a D register and then copying to memory. This will
  5764. +; perform the fewest possible memory read/writes.
  5765. +;
  5766. +(define_peephole2
  5767. + [(match_scratch:SI 2 "d")
  5768. + (set (match_operand:SI 0 "memory_operand" "")
  5769. + (match_operand:SI 1 "const_int_operand" ""))]
  5770. + "! satisfies_constraint_I (operands[1])"
  5771. + [(set (match_dup 2) (match_dup 1))
  5772. + (set (match_dup 0) (match_dup 2))]
  5773. + "")
  5774. +
  5775. +; If we're not dependent on the state of the condition codes we can construct
  5776. +; constants of value (2^n - 1) by using an lsr.4.
  5777. +;
  5778. +(define_peephole2
  5779. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
  5780. + (match_operand:SI 1 "const_int_operand" ""))]
  5781. + "(exact_log2 (INTVAL (operands[1]) + 1) > 14
  5782. + && peep2_regno_dead_p (0, CC_REGNO))"
  5783. + [(parallel
  5784. + [(set (match_dup 0)
  5785. + (lshiftrt:SI (const_int -1)
  5786. + (match_dup 2)))
  5787. + (clobber (reg:CC CC_REGNO))])]
  5788. + "{
  5789. + operands[2] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
  5790. + }")
  5791. +
  5792. +; If we're not dependent on the state of the condition codes we can construct
  5793. +; constants of value (2^n - 1) by using an lsr.4.
  5794. +;
  5795. +(define_peephole2
  5796. + [(match_scratch:SI 2 "d")
  5797. + (set (match_operand:SI 0 "nonimmediate_operand" "")
  5798. + (match_operand:SI 1 "const_int_operand" ""))]
  5799. + "(exact_log2 (INTVAL (operands[1]) + 1) > 14
  5800. + && peep2_regno_dead_p (0, CC_REGNO))"
  5801. + [(parallel
  5802. + [(set (match_dup 2)
  5803. + (lshiftrt:SI (const_int -1)
  5804. + (match_dup 3)))
  5805. + (clobber (reg:CC CC_REGNO))])
  5806. + (set (match_dup 0)
  5807. + (match_dup 2))]
  5808. + "{
  5809. + operands[3] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
  5810. + }")
  5811. +
  5812. +; If we're not dependent on the state of the condition codes we can construct
  5813. +; some other constants by using an lsl.4 to shift 7 bits left by some
  5814. +; constant.
  5815. +;
  5816. +(define_peephole2
  5817. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
  5818. + (match_operand:SI 1 "const_int_operand" ""))]
  5819. + "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
  5820. + && peep2_regno_dead_p (0, CC_REGNO))"
  5821. + [(parallel
  5822. + [(set (match_dup 0)
  5823. + (ashift:SI (match_dup 2)
  5824. + (match_dup 3)))
  5825. + (clobber (reg:CC CC_REGNO))])]
  5826. + "{
  5827. + int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
  5828. + operands[2] = GEN_INT (INTVAL (operands[1]) >> shift);
  5829. + operands[3] = GEN_INT (shift);
  5830. + }")
  5831. +
  5832. +; If we're not dependent on the state of the condition codes we can construct
  5833. +; some other constants by using an lsl.4 to shift 7 bits left by some
  5834. +; constant.
  5835. +;
  5836. +(define_peephole2
  5837. + [(match_scratch:SI 2 "d")
  5838. + (set (match_operand:SI 0 "nonimmediate_operand" "")
  5839. + (match_operand:SI 1 "const_int_operand" ""))]
  5840. + "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
  5841. + && peep2_regno_dead_p (0, CC_REGNO))"
  5842. + [(parallel
  5843. + [(set (match_dup 2)
  5844. + (ashift:SI (match_dup 3)
  5845. + (match_dup 4)))
  5846. + (clobber (reg:CC CC_REGNO))])
  5847. + (set (match_dup 0)
  5848. + (match_dup 2))]
  5849. + "{
  5850. + int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
  5851. + operands[3] = GEN_INT (INTVAL (operands[1]) >> shift);
  5852. + operands[4] = GEN_INT (shift);
  5853. + }")
  5854. +
  5855. +; For some 16-bit unsigned constants that have bit 15 set we can use
  5856. +; swapb.2!
  5857. +;
  5858. +; Note that the movsi code emits the same sequence but by using a peephole2
  5859. +; we split the pattern early enough to allow instruction scheduling to
  5860. +; occur.
  5861. +;
  5862. +(define_peephole2
  5863. + [(set (match_operand:SI 0 "register_operand" "")
  5864. + (match_operand:SI 1 "const_int_operand" ""))]
  5865. + "(ubicom32_v4
  5866. + && (INTVAL (operands[1]) & 0xffff80ff) == 0x80ff)"
  5867. + [(set (match_dup 0)
  5868. + (zero_extend:SI (bswap:HI (match_dup 2))))]
  5869. + "{
  5870. + HOST_WIDE_INT i = INTVAL (operands[1]) >> 8;
  5871. + if (i >= 0x80)
  5872. + i -= 0x100;
  5873. + operands[2] = GEN_INT (i);
  5874. + }")
  5875. +
  5876. +; In general for a 16-bit unsigned constant that has bit 15 set
  5877. +; then we need a movei/move.2 pair unless we can represent it
  5878. +; via just a move.2.
  5879. +;
  5880. +(define_peephole2
  5881. + [(set (match_operand:SI 0 "register_operand" "")
  5882. + (match_operand:SI 1 "const_int_operand" ""))]
  5883. + "(INTVAL (operands[1]) & 0xffff8000) == 0x8000
  5884. + && (INTVAL (operands[1]) & 0xffff) < 0xff80"
  5885. + [(set (match_dup 2)
  5886. + (match_dup 1))
  5887. + (set (match_dup 0)
  5888. + (zero_extend:SI (match_dup 2)))]
  5889. + "{
  5890. + operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
  5891. + }")
  5892. +
  5893. +; If we're not dependent on the state of the condition codes we can construct
  5894. +; 32-bit constants that have bits 16 through 31 set to arbitrary values
  5895. +; and have bits 0 through 15 set to something representable as a default
  5896. +; source-1 immediate - we use movei/shmrg.2
  5897. +;
  5898. +(define_peephole2
  5899. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
  5900. + (match_operand:SI 1 "const_int_operand" ""))]
  5901. + "(((INTVAL (operands[1]) >= 0x8000
  5902. + && INTVAL (operands[1]) < 0xff80)
  5903. + || INTVAL (operands[1]) >= 0x10000
  5904. + || INTVAL (operands[1]) < -0x8000)
  5905. + && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
  5906. + || (INTVAL (operands[1]) & 0xffff) < 0x80)
  5907. + && peep2_regno_dead_p (0, CC_REGNO))"
  5908. + [(set (match_dup 0)
  5909. + (match_dup 2))
  5910. + (parallel
  5911. + [(set (match_dup 0)
  5912. + (ior:SI
  5913. + (ashift:SI (match_dup 0)
  5914. + (const_int 16))
  5915. + (zero_extend:SI
  5916. + (match_dup 3))))
  5917. + (clobber (reg:CC CC_REGNO))])]
  5918. + "{
  5919. + operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
  5920. + operands[3] = gen_lowpart (HImode, operands[1]);
  5921. + }")
  5922. +
  5923. +; Exactly the same as the peephole2 preceding except that this targets a
  5924. +; general register instead of D register. Hopefully the later optimization
  5925. +; passes will notice that the value ended up in a D register first here
  5926. +; and eliminate away the other register!
  5927. +;
  5928. +(define_peephole2
  5929. + [(match_scratch:SI 2 "d")
  5930. + (set (match_operand:SI 0 "register_operand" "")
  5931. + (match_operand:SI 1 "const_int_operand" ""))]
  5932. + "(((INTVAL (operands[1]) >= 0x8000
  5933. + && INTVAL (operands[1]) < 0xff80)
  5934. + || INTVAL (operands[1]) >= 0x10000
  5935. + || INTVAL (operands[1]) < -0x8000)
  5936. + && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
  5937. + || (INTVAL (operands[1]) & 0xffff) < 0x80)
  5938. + && peep2_regno_dead_p (0, CC_REGNO))"
  5939. + [(set (match_dup 2)
  5940. + (match_dup 3))
  5941. + (parallel
  5942. + [(set (match_dup 2)
  5943. + (ior:SI
  5944. + (ashift:SI (match_dup 2)
  5945. + (const_int 16))
  5946. + (zero_extend:SI
  5947. + (match_dup 4))))
  5948. + (clobber (reg:CC CC_REGNO))])
  5949. + (set (match_dup 0)
  5950. + (match_dup 2))]
  5951. + "{
  5952. + operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
  5953. + operands[4] = gen_lowpart (HImode, operands[1]);
  5954. + }")
  5955. +
  5956. +; If we have a load of a large integer constant which does not have bit 31
  5957. +; set and we have a spare A reg then construct it with a moveai/lea.1 pair
  5958. +; instead. This avoids constructing it in 3 instructions on the stack.
  5959. +;
  5960. +; Note that we have to be careful not to match anything that matches
  5961. +; something we can do in a single instruction! There aren't many such
  5962. +; constants but there are some.
  5963. +;
  5964. +(define_peephole2
  5965. + [(match_scratch:SI 2 "a")
  5966. + (set (match_operand:SI 0 "register_operand" "")
  5967. + (match_operand:SI 1 "const_int_operand" ""))]
  5968. + "(! (INTVAL (operands[1]) & 0x80000000)
  5969. + && ((INTVAL (operands[1]) >= 0x8000
  5970. + && INTVAL (operands[1]) < 0xff80)
  5971. + || INTVAL (operands[1]) >= 0x10000))"
  5972. + [(set (match_dup 2)
  5973. + (match_dup 3))
  5974. + (set (match_dup 0)
  5975. + (plus:SI (match_dup 2)
  5976. + (match_dup 4)))]
  5977. + "{
  5978. + HOST_WIDE_INT i = INTVAL (operands[1]);
  5979. + operands[3] = GEN_INT (i & 0xffffff80);
  5980. + operands[4] = GEN_INT (i & 0x7f);
  5981. + }")
  5982. +
  5983. +; If we're not dependent on the state of the condition codes we can construct
  5984. +; a 32-bit constant with a movei/movei/shmrg.2 sequence if possible.
  5985. +;
  5986. +(define_peephole2
  5987. + [(match_scratch:HI 2 "d")
  5988. + (set (match_operand:SI 0 "ubicom32_data_register_operand" "")
  5989. + (match_operand:SI 1 "const_int_operand" ""))
  5990. + (match_dup 2)]
  5991. + "(INTVAL (operands[1]) & 0x80000000
  5992. + && INTVAL (operands[1]) < -0x8000
  5993. + && peep2_regno_dead_p (0, CC_REGNO))"
  5994. + [(set (match_dup 0)
  5995. + (match_dup 3))
  5996. + (set (match_dup 2)
  5997. + (match_dup 4))
  5998. + (parallel
  5999. + [(set (match_dup 0)
  6000. + (ior:SI
  6001. + (ashift:SI (match_dup 0)
  6002. + (const_int 16))
  6003. + (zero_extend:SI
  6004. + (match_dup 2))))
  6005. + (clobber (reg:CC CC_REGNO))])]
  6006. + "{
  6007. + operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
  6008. + operands[4] = gen_lowpart (HImode, operands[1]);
  6009. + }")
  6010. +
  6011. +; Exactly the same as the peephole2 preceding except that this targets a
  6012. +; general register instead of D register. Hopefully the later optimization
  6013. +; passes will notice that the value ended up in a D register first here
  6014. +; and eliminate away the other register!
  6015. +;
  6016. +(define_peephole2
  6017. + [(match_scratch:SI 2 "d")
  6018. + (match_scratch:HI 3 "d")
  6019. + (set (match_operand:SI 0 "register_operand" "")
  6020. + (match_operand:SI 1 "const_int_operand" ""))
  6021. + (match_dup 3)]
  6022. + "(INTVAL (operands[1]) & 0x80000000
  6023. + && INTVAL (operands[1]) < -0x8000
  6024. + && peep2_regno_dead_p (0, CC_REGNO))"
  6025. + [(set (match_dup 2)
  6026. + (match_dup 4))
  6027. + (set (match_dup 3)
  6028. + (match_dup 5))
  6029. + (parallel
  6030. + [(set (match_dup 2)
  6031. + (ior:SI
  6032. + (ashift:SI (match_dup 2)
  6033. + (const_int 16))
  6034. + (zero_extend:SI
  6035. + (match_dup 3))))
  6036. + (clobber (reg:CC CC_REGNO))])
  6037. + (set (match_dup 0)
  6038. + (match_dup 2))]
  6039. + "{
  6040. + operands[4] = gen_highpart_mode (HImode, SImode, operands[1]);
  6041. + operands[5] = gen_lowpart (HImode, operands[1]);
  6042. + }")
  6043. +
  6044. +(define_insn "movsi_fdpic_got_offset"
  6045. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  6046. + (match_operand:SI 1 "ubicom32_fdpic_got_offset_operand" "Y"))]
  6047. + ""
  6048. + "movei\\t%0, %1")
  6049. +
  6050. +; The explicit MEM inside the UNSPEC prevents the compiler from moving
  6051. +; the load before a branch after a NULL test, or before a store that
  6052. +; initializes a function descriptor.
  6053. +
  6054. +(define_insn_and_split "load_fdpic_funcdesc"
  6055. + [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
  6056. + (unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
  6057. + UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC))]
  6058. + ""
  6059. + "#"
  6060. + "reload_completed"
  6061. + [(set (match_dup 0)
  6062. + (mem:SI (match_dup 1)))])
  6063. +
  6064. +; Combiner-generated 32-bit move with the zero flag set accordingly.
  6065. +;
  6066. +(define_insn "movsi_ccwzn"
  6067. + [(set (reg CC_REGNO)
  6068. + (compare (match_operand:SI 0 "nonimmediate_operand" "rm, d")
  6069. + (const_int 0)))
  6070. + (set (match_operand:SI 1 "nonimmediate_operand" "=d,rm")
  6071. + (match_dup 0))]
  6072. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  6073. + "@
  6074. + lsl.4\\t%1, %0, #0
  6075. + add.4\\t%1, #0, %0")
  6076. +
  6077. +; Combiner-generated 32-bit move with all flags set accordingly.
  6078. +;
  6079. +(define_insn "movsi_ccw"
  6080. + [(set (reg CC_REGNO)
  6081. + (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
  6082. + (const_int 0)))
  6083. + (set (match_operand:SI 1 "nonimmediate_operand" "=rm")
  6084. + (match_dup 0))]
  6085. + "ubicom32_match_cc_mode(insn, CCWmode)"
  6086. + "add.4\\t%1, #0, %0")
  6087. +
  6088. +; Combine isn't very good at merging some types of operations so we
  6089. +; have to make do with a peephole. It's not as effective but it's better
  6090. +; than doing nothing.
  6091. +;
  6092. +(define_peephole2
  6093. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
  6094. + (match_operand:SI 1 "nonimmediate_operand" ""))
  6095. + (parallel
  6096. + [(set (match_operand 2 "ubicom32_cc_register_operand" "")
  6097. + (match_operator 3 "ubicom32_compare_operator"
  6098. + [(match_dup 0)
  6099. + (const_int 0)]))
  6100. + (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
  6101. + "(GET_MODE (operands[2]) == CCWZNmode
  6102. + || GET_MODE (operands[2]) == CCWZmode)"
  6103. + [(parallel
  6104. + [(set (match_dup 2)
  6105. + (match_op_dup 3
  6106. + [(match_dup 1)
  6107. + (const_int 0)]))
  6108. + (set (match_dup 0)
  6109. + (match_dup 1))])]
  6110. + "")
  6111. +
  6112. +; Combine isn't very good at merging some types of operations so we
  6113. +; have to make do with a peephole. It's not as effective but it's better
  6114. +; than doing nothing.
  6115. +;
  6116. +(define_peephole2
  6117. + [(set (match_operand:SI 0 "nonimmediate_operand" "")
  6118. + (match_operand:SI 1 "ubicom32_data_register_operand" ""))
  6119. + (parallel
  6120. + [(set (match_operand 2 "ubicom32_cc_register_operand" "")
  6121. + (match_operator 3 "ubicom32_compare_operator"
  6122. + [(match_dup 1)
  6123. + (const_int 0)]))
  6124. + (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
  6125. + "(GET_MODE (operands[2]) == CCWZNmode
  6126. + || GET_MODE (operands[2]) == CCWZmode)"
  6127. + [(parallel
  6128. + [(set (match_dup 2)
  6129. + (match_op_dup 3
  6130. + [(match_dup 1)
  6131. + (const_int 0)]))
  6132. + (set (match_dup 0)
  6133. + (match_dup 1))])]
  6134. + "")
  6135. +
  6136. +; Combine isn't very good at merging some types of operations so we
  6137. +; have to make do with a peephole. It's not as effective but it's better
  6138. +; than doing nothing.
  6139. +;
  6140. +(define_peephole2
  6141. + [(set (match_operand:SI 0 "register_operand" "")
  6142. + (match_operand:SI 1 "nonimmediate_operand" ""))
  6143. + (parallel
  6144. + [(set (match_operand 2 "ubicom32_cc_register_operand" "")
  6145. + (match_operator 3 "ubicom32_compare_operator"
  6146. + [(match_dup 0)
  6147. + (const_int 0)]))
  6148. + (set (match_operand:SI 4 "ubicom32_data_register_operand" "")
  6149. + (match_dup 0))])]
  6150. + "(peep2_reg_dead_p (2, operands[0])
  6151. + && (GET_MODE (operands[2]) == CCWZNmode
  6152. + || GET_MODE (operands[2]) == CCWZmode))"
  6153. + [(parallel
  6154. + [(set (match_dup 2)
  6155. + (match_op_dup 3
  6156. + [(match_dup 1)
  6157. + (const_int 0)]))
  6158. + (set (match_dup 4)
  6159. + (match_dup 1))])]
  6160. + "")
  6161. +
  6162. +; Register renaming may make a general reg into a D reg in which case
  6163. +; we may be able to simplify a compare.
  6164. +;
  6165. +(define_peephole2
  6166. + [(set (match_operand:SI 0 "register_operand" "")
  6167. + (match_operand:SI 1 "nonimmediate_operand" ""))
  6168. + (parallel
  6169. + [(set (match_operand 2 "ubicom32_cc_register_operand" "")
  6170. + (match_operator 3 "ubicom32_compare_operator"
  6171. + [(match_dup 0)
  6172. + (const_int 0)]))
  6173. + (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
  6174. + "(peep2_reg_dead_p (2, operands[0])
  6175. + && (GET_MODE (operands[2]) == CCWZNmode
  6176. + || GET_MODE (operands[2]) == CCWZmode))"
  6177. + [(parallel
  6178. + [(set (match_dup 2)
  6179. + (match_op_dup 3
  6180. + [(match_dup 1)
  6181. + (const_int 0)]))
  6182. + (clobber (match_dup 4))])]
  6183. + "")
  6184. +
  6185. +(define_insn_and_split "movdi"
  6186. + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
  6187. + (match_operand:DI 1 "general_operand" "rmi,ri"))]
  6188. + ""
  6189. + "#"
  6190. + "reload_completed"
  6191. + [(set (match_dup 2) (match_dup 3))
  6192. + (set (match_dup 4) (match_dup 5))]
  6193. + "{
  6194. + rtx dest_low;
  6195. + rtx src_low;
  6196. +
  6197. + dest_low = gen_lowpart (SImode, operands[0]);
  6198. + src_low = gen_lowpart (SImode, operands[1]);
  6199. +
  6200. + if (REG_P (operands[0])
  6201. + && REG_P (operands[1])
  6202. + && REGNO (operands[0]) < REGNO (operands[1]))
  6203. + {
  6204. + operands[2] = gen_highpart (SImode, operands[0]);
  6205. + operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
  6206. + operands[4] = dest_low;
  6207. + operands[5] = src_low;
  6208. + }
  6209. + else if (reg_mentioned_p (dest_low, src_low))
  6210. + {
  6211. + operands[2] = gen_highpart (SImode, operands[0]);
  6212. + operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
  6213. + operands[4] = dest_low;
  6214. + operands[5] = src_low;
  6215. + }
  6216. + else
  6217. + {
  6218. + operands[2] = dest_low;
  6219. + operands[3] = src_low;
  6220. + operands[4] = gen_highpart (SImode, operands[0]);
  6221. + operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
  6222. + }
  6223. + }"
  6224. + [(set_attr "length" "8")])
  6225. +
  6226. +; Combiner-generated 64-bit move with all flags set accordingly.
  6227. +;
  6228. +(define_insn "movdi_ccwzn"
  6229. + [(set (reg CC_REGNO)
  6230. + (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
  6231. + (const_int 0)))
  6232. + (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
  6233. + (match_dup 0))
  6234. + (clobber (match_scratch:SI 2 "=X, d, d"))]
  6235. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  6236. + "*
  6237. + {
  6238. + operands[3] = gen_lowpart (SImode, operands[0]);
  6239. + operands[4] = gen_lowpart (SImode, operands[1]);
  6240. + operands[5] = gen_highpart (SImode, operands[0]);
  6241. + operands[6] = gen_highpart (SImode, operands[1]);
  6242. +
  6243. + if (ubicom32_data_register_operand (operands[0], VOIDmode))
  6244. + return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
  6245. +
  6246. + return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
  6247. + }"
  6248. + [(set_attr "length" "8")])
  6249. +
  6250. +(define_insn "movdi_ccw"
  6251. + [(set (reg CC_REGNO)
  6252. + (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
  6253. + (const_int 0)))
  6254. + (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
  6255. + (match_dup 0))
  6256. + (clobber (match_scratch:SI 2 "=X, d, d"))]
  6257. + "ubicom32_match_cc_mode(insn, CCWmode)"
  6258. + "*
  6259. + {
  6260. + operands[3] = gen_lowpart (SImode, operands[0]);
  6261. + operands[4] = gen_lowpart (SImode, operands[1]);
  6262. + operands[5] = gen_highpart (SImode, operands[0]);
  6263. + operands[6] = gen_highpart (SImode, operands[1]);
  6264. +
  6265. + if (ubicom32_data_register_operand (operands[0], VOIDmode))
  6266. + return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
  6267. +
  6268. + return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
  6269. + }"
  6270. + [(set_attr "length" "8")])
  6271. +
  6272. +(define_insn "movsf"
  6273. + [(set (match_operand:SF 0 "nonimmediate_operand" "=!d,*rm")
  6274. + (match_operand:SF 1 "ubicom32_move_operand" "rmF,rmF"))]
  6275. + ""
  6276. + "*
  6277. + {
  6278. + if (GET_CODE (operands[1]) == CONST_DOUBLE)
  6279. + {
  6280. + HOST_WIDE_INT val;
  6281. + REAL_VALUE_TYPE rv;
  6282. +
  6283. + REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
  6284. + REAL_VALUE_TO_TARGET_SINGLE (rv, val);
  6285. +
  6286. + ubicom32_emit_move_const_int (operands[0], GEN_INT (val));
  6287. + return \"\";
  6288. + }
  6289. +
  6290. + return \"move.4\\t%0, %1\";
  6291. + }")
  6292. +
  6293. +(define_insn "zero_extendqihi2"
  6294. + [(set (match_operand:HI 0 "register_operand" "=r")
  6295. + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
  6296. + ""
  6297. + "move.1\\t%0, %1")
  6298. +
  6299. +(define_insn "zero_extendqisi2"
  6300. + [(set (match_operand:SI 0 "register_operand" "=r")
  6301. + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
  6302. + ""
  6303. + "move.1\\t%0, %1")
  6304. +
  6305. +(define_insn "zero_extendqisi2_ccwz_1"
  6306. + [(set (reg CC_REGNO)
  6307. + (compare
  6308. + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm"))
  6309. + (const_int 0)))
  6310. + (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  6311. + (zero_extend:SI (match_dup 1)))]
  6312. + "ubicom32_match_cc_mode(insn, CCWZmode)"
  6313. + "shmrg.1\\t%0, %1, #0")
  6314. +
  6315. +(define_insn "zero_extendhisi2"
  6316. + [(set (match_operand:SI 0 "register_operand" "=r")
  6317. + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
  6318. + ""
  6319. + "move.2\\t%0, %1")
  6320. +
  6321. +(define_insn "zero_extendhisi2_ccwz_1"
  6322. + [(set (reg CC_REGNO)
  6323. + (compare
  6324. + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm"))
  6325. + (const_int 0)))
  6326. + (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  6327. + (zero_extend:SI (match_dup 1)))]
  6328. + "ubicom32_match_cc_mode(insn, CCWZmode)"
  6329. + "shmrg.2\\t%0, %1, #0")
  6330. +
  6331. +(define_insn_and_split "zero_extendqidi2"
  6332. + [(set (match_operand:DI 0 "register_operand" "=r")
  6333. + (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
  6334. + ""
  6335. + "#"
  6336. + "reload_completed"
  6337. + [(set (match_dup 2)
  6338. + (zero_extend:SI (match_dup 1)))
  6339. + (set (match_dup 3)
  6340. + (const_int 0))]
  6341. + "{
  6342. + operands[2] = gen_lowpart (SImode, operands[0]);
  6343. + operands[3] = gen_highpart (SImode, operands[0]);
  6344. + }"
  6345. + [(set_attr "length" "8")])
  6346. +
  6347. +(define_insn_and_split "zero_extendhidi2"
  6348. + [(set (match_operand:DI 0 "register_operand" "=r")
  6349. + (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
  6350. + ""
  6351. + "#"
  6352. + "reload_completed"
  6353. + [(set (match_dup 2)
  6354. + (zero_extend:SI (match_dup 1)))
  6355. + (set (match_dup 3)
  6356. + (const_int 0))]
  6357. + "{
  6358. + operands[2] = gen_lowpart (SImode, operands[0]);
  6359. + operands[3] = gen_highpart (SImode, operands[0]);
  6360. + }"
  6361. + [(set_attr "length" "8")])
  6362. +
  6363. +(define_insn_and_split "zero_extendsidi2"
  6364. + [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
  6365. + (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  6366. + ""
  6367. + "#"
  6368. + "reload_completed"
  6369. + [(set (match_dup 2)
  6370. + (match_dup 1))
  6371. + (set (match_dup 3)
  6372. + (const_int 0))]
  6373. + "{
  6374. + operands[2] = gen_lowpart (SImode, operands[0]);
  6375. + operands[3] = gen_highpart (SImode, operands[0]);
  6376. + }"
  6377. + [(set_attr "length" "8")])
  6378. +
  6379. +(define_insn "extendqihi2"
  6380. + [(set (match_operand:HI 0 "register_operand" "=r")
  6381. + (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))
  6382. + (clobber (reg:CC CC_REGNO))]
  6383. + ""
  6384. + "ext.1\\t%0, %1")
  6385. +
  6386. +(define_insn "extendqisi2"
  6387. + [(set (match_operand:SI 0 "register_operand" "=r")
  6388. + (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))
  6389. + (clobber (reg:CC CC_REGNO))]
  6390. + ""
  6391. + "ext.1\\t%0, %1")
  6392. +
  6393. +(define_insn "extendhisi2"
  6394. + [(set (match_operand:SI 0 "register_operand" "=r")
  6395. + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))
  6396. + (clobber (reg:CC CC_REGNO))]
  6397. + ""
  6398. + "ext.2\\t%0, %1")
  6399. +
  6400. +(define_insn_and_split "extendsidi2"
  6401. + [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
  6402. + (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))
  6403. + (clobber (reg:CC CC_REGNO))]
  6404. + ""
  6405. + "#"
  6406. + "reload_completed"
  6407. + [(set (match_dup 2)
  6408. + (match_dup 1))
  6409. + (parallel
  6410. + [(set (match_dup 3)
  6411. + (ashiftrt:SI (match_dup 2)
  6412. + (const_int 31)))
  6413. + (clobber (reg:CC CC_REGNO))])]
  6414. + "{
  6415. + operands[2] = gen_lowpart (SImode, operands[0]);
  6416. + operands[3] = gen_highpart (SImode, operands[0]);
  6417. + }"
  6418. + [(set_attr "length" "8")])
  6419. +
  6420. +(define_insn "bswaphi"
  6421. + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
  6422. + (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
  6423. + "(ubicom32_v4)"
  6424. + "swapb.2\\t%0, %1");
  6425. +
  6426. +(define_insn "bswaphisi"
  6427. + [(set (match_operand:SI 0 "register_operand" "=r")
  6428. + (zero_extend:SI
  6429. + (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI"))))]
  6430. + "(ubicom32_v4)"
  6431. + "swapb.2\\t%0, %1");
  6432. +
  6433. +(define_insn "bswapsi"
  6434. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
  6435. + (bswap:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))]
  6436. + "(ubicom32_v4)"
  6437. + "swapb.4\\t%0, %1");
  6438. +
  6439. +(define_insn "tstqi_ext1"
  6440. + [(set (reg CC_REGNO)
  6441. + (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
  6442. + (const_int 0)))]
  6443. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  6444. + "ext.1\\t#0, %0")
  6445. +
  6446. +(define_expand "cmpqi"
  6447. + [(set (reg CC_REGNO)
  6448. + (compare (match_operand:QI 0 "ubicom32_arith_operand" "")
  6449. + (match_operand:QI 1 "ubicom32_data_register_operand" "")))]
  6450. + "(ubicom32_v4)"
  6451. + "{
  6452. + ubicom32_compare_op0 = operands[0];
  6453. + ubicom32_compare_op1 = operands[1];
  6454. + DONE;
  6455. + }")
  6456. +
  6457. +(define_insn "sub1_ccs"
  6458. + [(set (reg CC_REGNO)
  6459. + (compare (match_operand:QI 0 "ubicom32_arith_operand" "rmI")
  6460. + (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
  6461. + "(ubicom32_v4)"
  6462. + "sub.1\\t#0, %0, %1")
  6463. +
  6464. +; If we're testing for equality we don't have to worry about reversing conditions.
  6465. +;
  6466. +(define_insn "sub1_ccsz_1"
  6467. + [(set (reg:CCSZ CC_REGNO)
  6468. + (compare:CCSZ (match_operand:QI 0 "nonimmediate_operand" "rm")
  6469. + (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
  6470. + "(ubicom32_v4)"
  6471. + "sub.1\\t#0, %0, %1")
  6472. +
  6473. +(define_insn "sub1_ccsz_2"
  6474. + [(set (reg:CCSZ CC_REGNO)
  6475. + (compare:CCSZ (match_operand:QI 0 "ubicom32_data_register_operand" "d")
  6476. + (match_operand:QI 1 "ubicom32_arith_operand" "rmI")))]
  6477. + "(ubicom32_v4)"
  6478. + "sub.1\\t#0, %1, %0")
  6479. +
  6480. +; When the combiner runs it doesn't have any insight into whether or not an argument
  6481. +; to a compare is spilled to the stack and therefore can't swap the comparison in
  6482. +; an attempt to use sub.1 more effectively. We peephole this case here.
  6483. +;
  6484. +(define_peephole2
  6485. + [(set (match_operand:QI 0 "register_operand" "")
  6486. + (match_operand:QI 1 "ubicom32_arith_operand" ""))
  6487. + (set (match_operand 2 "ubicom32_cc_register_operand" "")
  6488. + (compare (match_operand:QI 3 "ubicom32_data_register_operand" "")
  6489. + (match_dup 0)))
  6490. + (set (pc)
  6491. + (if_then_else (match_operator 4 "comparison_operator"
  6492. + [(match_dup 2)
  6493. + (const_int 0)])
  6494. + (label_ref (match_operand 5 "" ""))
  6495. + (pc)))]
  6496. + "(peep2_reg_dead_p (2, operands[0])
  6497. + && peep2_regno_dead_p (3, CC_REGNO))"
  6498. + [(set (match_dup 2)
  6499. + (compare (match_dup 1)
  6500. + (match_dup 3)))
  6501. + (set (pc)
  6502. + (if_then_else (match_op_dup 6
  6503. + [(match_dup 2)
  6504. + (const_int 0)])
  6505. + (label_ref (match_dup 5))
  6506. + (pc)))]
  6507. + "{
  6508. + rtx cc_reg;
  6509. +
  6510. + cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
  6511. + operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
  6512. + GET_MODE (operands[4]),
  6513. + cc_reg,
  6514. + const0_rtx);
  6515. + }")
  6516. +
  6517. +(define_insn "tsthi_ext2"
  6518. + [(set (reg CC_REGNO)
  6519. + (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
  6520. + (const_int 0)))]
  6521. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  6522. + "ext.2\\t#0, %0")
  6523. +
  6524. +(define_expand "cmphi"
  6525. + [(set (reg CC_REGNO)
  6526. + (compare (match_operand:HI 0 "ubicom32_arith_operand" "")
  6527. + (match_operand:HI 1 "ubicom32_compare_operand" "")))]
  6528. + ""
  6529. + "{
  6530. + do
  6531. + {
  6532. + /* Is this a cmpi? */
  6533. + if (CONST_INT_P (operands[1]))
  6534. + break;
  6535. +
  6536. + /* Must be a sub.2 - if necessary copy an operand into a reg. */
  6537. + if (! ubicom32_data_register_operand (operands[1], HImode))
  6538. + operands[1] = copy_to_mode_reg (HImode, operands[1]);
  6539. + }
  6540. + while (0);
  6541. +
  6542. + ubicom32_compare_op0 = operands[0];
  6543. + ubicom32_compare_op1 = operands[1];
  6544. + DONE;
  6545. + }")
  6546. +
  6547. +(define_insn "cmpi"
  6548. + [(set (reg CC_REGNO)
  6549. + (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
  6550. + (match_operand 1 "const_int_operand" "N")))]
  6551. + ""
  6552. + "cmpi\\t%0, %1")
  6553. +
  6554. +(define_insn "sub2_ccs"
  6555. + [(set (reg CC_REGNO)
  6556. + (compare (match_operand:HI 0 "ubicom32_arith_operand" "rmI")
  6557. + (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
  6558. + ""
  6559. + "sub.2\\t#0, %0, %1")
  6560. +
  6561. +; If we're testing for equality we don't have to worry about reversing conditions.
  6562. +;
  6563. +(define_insn "sub2_ccsz_1"
  6564. + [(set (reg:CCSZ CC_REGNO)
  6565. + (compare:CCSZ (match_operand:HI 0 "nonimmediate_operand" "rm")
  6566. + (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
  6567. + ""
  6568. + "sub.2\\t#0, %0, %1")
  6569. +
  6570. +(define_insn "sub2_ccsz_2"
  6571. + [(set (reg:CCSZ CC_REGNO)
  6572. + (compare:CCSZ (match_operand:HI 0 "ubicom32_data_register_operand" "d")
  6573. + (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
  6574. + ""
  6575. + "sub.2\\t#0, %1, %0")
  6576. +
  6577. +; When the combiner runs it doesn't have any insight into whether or not an argument
  6578. +; to a compare is spilled to the stack and therefore can't swap the comparison in
  6579. +; an attempt to use sub.2 more effectively. We peephole this case here.
  6580. +;
  6581. +(define_peephole2
  6582. + [(set (match_operand:HI 0 "register_operand" "")
  6583. + (match_operand:HI 1 "ubicom32_arith_operand" ""))
  6584. + (set (match_operand 2 "ubicom32_cc_register_operand" "")
  6585. + (compare (match_operand:HI 3 "ubicom32_data_register_operand" "")
  6586. + (match_dup 0)))
  6587. + (set (pc)
  6588. + (if_then_else (match_operator 4 "comparison_operator"
  6589. + [(match_dup 2)
  6590. + (const_int 0)])
  6591. + (label_ref (match_operand 5 "" ""))
  6592. + (pc)))]
  6593. + "(peep2_reg_dead_p (2, operands[0])
  6594. + && peep2_regno_dead_p (3, CC_REGNO))"
  6595. + [(set (match_dup 2)
  6596. + (compare (match_dup 1)
  6597. + (match_dup 3)))
  6598. + (set (pc)
  6599. + (if_then_else (match_op_dup 6
  6600. + [(match_dup 2)
  6601. + (const_int 0)])
  6602. + (label_ref (match_dup 5))
  6603. + (pc)))]
  6604. + "{
  6605. + rtx cc_reg;
  6606. +
  6607. + cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
  6608. + operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
  6609. + GET_MODE (operands[4]),
  6610. + cc_reg,
  6611. + const0_rtx);
  6612. + }")
  6613. +
  6614. +(define_insn_and_split "tstsi_lsl4"
  6615. + [(set (match_operand 0 "ubicom32_cc_register_operand" "=r")
  6616. + (match_operator 1 "ubicom32_compare_operator"
  6617. + [(match_operand:SI 2 "nonimmediate_operand" "rm")
  6618. + (const_int 0)]))]
  6619. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  6620. + "#"
  6621. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  6622. + [(parallel
  6623. + [(set (match_dup 0)
  6624. + (match_op_dup 1
  6625. + [(match_dup 2)
  6626. + (const_int 0)]))
  6627. + (clobber (match_dup 3))])]
  6628. + "{
  6629. + operands[3] = gen_reg_rtx (SImode);
  6630. + }")
  6631. +
  6632. +(define_insn "tstsi_lsl4_d"
  6633. + [(set (reg CC_REGNO)
  6634. + (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
  6635. + (const_int 0)))
  6636. + (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
  6637. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  6638. + "lsl.4\\t%1, %0, #0")
  6639. +
  6640. +; Comparison for equality with -1.
  6641. +;
  6642. +(define_insn "cmpsi_not4_ccwz"
  6643. + [(set (reg CC_REGNO)
  6644. + (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
  6645. + (const_int -1)))]
  6646. + "ubicom32_match_cc_mode(insn, CCWZmode)"
  6647. + "not.4\\t#0, %0")
  6648. +
  6649. +(define_expand "cmpsi"
  6650. + [(set (reg CC_REGNO)
  6651. + (compare (match_operand:SI 0 "ubicom32_arith_operand" "")
  6652. + (match_operand:SI 1 "ubicom32_compare_operand" "")))]
  6653. + ""
  6654. + "{
  6655. + do
  6656. + {
  6657. + /* Is this a cmpi? We can't take a memory address as cmpi takes
  6658. + 16-bit operands. */
  6659. + if (register_operand (operands[0], SImode)
  6660. + && CONST_INT_P (operands[1])
  6661. + && satisfies_constraint_N (operands[1]))
  6662. + break;
  6663. +
  6664. + /* Must be a sub.4 - if necessary copy an operand into a reg. */
  6665. + if (! ubicom32_data_register_operand (operands[1], SImode))
  6666. + operands[1] = copy_to_mode_reg (SImode, operands[1]);
  6667. + }
  6668. + while (0);
  6669. +
  6670. + ubicom32_compare_op0 = operands[0];
  6671. + ubicom32_compare_op1 = operands[1];
  6672. + DONE;
  6673. + }")
  6674. +
  6675. +(define_insn "cmpsi_cmpi"
  6676. + [(set (reg CC_REGNO)
  6677. + (compare (match_operand:SI 0 "register_operand" "r")
  6678. + (match_operand 1 "const_int_operand" "N")))]
  6679. + "(satisfies_constraint_N (operands[1]))"
  6680. + "cmpi\\t%0, %1")
  6681. +
  6682. +(define_insn "cmpsi_sub4"
  6683. + [(set (reg CC_REGNO)
  6684. + (compare (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
  6685. + (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
  6686. + ""
  6687. + "sub.4\\t#0, %0, %1")
  6688. +
  6689. +; If we're testing for equality we don't have to worry about reversing conditions.
  6690. +;
  6691. +(define_insn "cmpsi_sub4_ccwz_1"
  6692. + [(set (reg CC_REGNO)
  6693. + (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
  6694. + (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
  6695. + "ubicom32_match_cc_mode(insn, CCWZmode)"
  6696. + "sub.4\\t#0, %0, %1")
  6697. +
  6698. +(define_insn "cmpsi_sub4_ccwz_2"
  6699. + [(set (reg CC_REGNO)
  6700. + (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
  6701. + (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  6702. + "ubicom32_match_cc_mode(insn, CCWZmode)"
  6703. + "sub.4\\t#0, %1, %0")
  6704. +
  6705. +; When the combiner runs it doesn't have any insight into whether or not an argument
  6706. +; to a compare is spilled to the stack and therefore can't swap the comparison in
  6707. +; an attempt to use sub.4 more effectively. We peephole this case here.
  6708. +;
  6709. +(define_peephole2
  6710. + [(set (match_operand:SI 0 "register_operand" "")
  6711. + (match_operand:SI 1 "ubicom32_arith_operand" ""))
  6712. + (set (match_operand 2 "ubicom32_cc_register_operand" "")
  6713. + (compare (match_operand:SI 3 "ubicom32_data_register_operand" "")
  6714. + (match_dup 0)))
  6715. + (set (pc)
  6716. + (if_then_else (match_operator 4 "comparison_operator"
  6717. + [(match_dup 2)
  6718. + (const_int 0)])
  6719. + (label_ref (match_operand 5 "" ""))
  6720. + (pc)))]
  6721. + "(peep2_reg_dead_p (2, operands[0])
  6722. + && peep2_regno_dead_p (3, CC_REGNO))"
  6723. + [(set (match_dup 2)
  6724. + (compare (match_dup 1)
  6725. + (match_dup 3)))
  6726. + (set (pc)
  6727. + (if_then_else (match_op_dup 6
  6728. + [(match_dup 2)
  6729. + (const_int 0)])
  6730. + (label_ref (match_dup 5))
  6731. + (pc)))]
  6732. + "{
  6733. + rtx cc_reg;
  6734. +
  6735. + cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
  6736. + operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
  6737. + GET_MODE (operands[4]),
  6738. + cc_reg,
  6739. + const0_rtx);
  6740. + }")
  6741. +
  6742. +(define_insn_and_split "tstdi_or4"
  6743. + [(set (reg:CCWZ CC_REGNO)
  6744. + (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
  6745. + (const_int 0)))]
  6746. + ""
  6747. + "#"
  6748. + ""
  6749. + [(parallel
  6750. + [(set (reg:CCWZ CC_REGNO)
  6751. + (compare:CCWZ (match_dup 0)
  6752. + (const_int 0)))
  6753. + (clobber (match_dup 1))])]
  6754. + "{
  6755. + operands[1] = gen_reg_rtx (SImode);
  6756. + }")
  6757. +
  6758. +(define_insn "tstdi_or4_d"
  6759. + [(set (reg:CCWZ CC_REGNO)
  6760. + (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
  6761. + (const_int 0)))
  6762. + (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
  6763. + ""
  6764. + "*
  6765. + {
  6766. + operands[2] = gen_lowpart (SImode, operands[0]);
  6767. + operands[3] = gen_highpart_mode (SImode, DImode, operands[0]);
  6768. +
  6769. + if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
  6770. + return \"or.4\\t#0, %2, %3\";
  6771. +
  6772. + return \"move.4\\t%1, %2\;or.4\\t%1, %3, %1\";
  6773. + }"
  6774. + [(set_attr "length" "8")])
  6775. +
  6776. +(define_expand "cmpdi"
  6777. + [(set (reg CC_REGNO)
  6778. + (compare (match_operand:DI 0 "ubicom32_arith_operand" "")
  6779. + (match_operand:DI 1 "ubicom32_data_register_operand" "")))]
  6780. + ""
  6781. + "{
  6782. + ubicom32_compare_op0 = operands[0];
  6783. + ubicom32_compare_op1 = operands[1];
  6784. + DONE;
  6785. + }")
  6786. +
  6787. +(define_insn "cmpdi_sub4subc"
  6788. + [(set (reg CC_REGNO)
  6789. + (compare (match_operand:DI 0 "ubicom32_arith_operand" "rmI")
  6790. + (match_operand:DI 1 "ubicom32_data_register_operand" "d")))]
  6791. + ""
  6792. + "*
  6793. + {
  6794. + operands[2] = gen_lowpart (SImode, operands[0]);
  6795. + operands[3] = gen_lowpart (SImode, operands[1]);
  6796. + operands[4] = gen_highpart_mode (SImode, DImode, operands[0]);
  6797. + operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
  6798. +
  6799. + return \"sub.4\\t#0, %2, %3\;subc\\t#0, %4, %5\";
  6800. + }"
  6801. + [(set_attr "length" "8")])
  6802. +
  6803. +; When the combiner runs it doesn't have any insight into whether or not an argument
  6804. +; to a compare is spilled to the stack and therefore can't swap the comparison in
  6805. +; an attempt to use sub.4/subc more effectively. We peephole this case here.
  6806. +;
  6807. +(define_peephole2
  6808. + [(set (match_operand:DI 0 "register_operand" "")
  6809. + (match_operand:DI 1 "ubicom32_arith_operand" ""))
  6810. + (set (match_operand 2 "ubicom32_cc_register_operand" "")
  6811. + (compare (match_operand:DI 3 "ubicom32_data_register_operand" "")
  6812. + (match_dup 0)))
  6813. + (set (pc)
  6814. + (if_then_else (match_operator 4 "comparison_operator"
  6815. + [(match_dup 2)
  6816. + (const_int 0)])
  6817. + (label_ref (match_operand 5 "" ""))
  6818. + (pc)))]
  6819. + "(peep2_reg_dead_p (2, operands[0])
  6820. + && peep2_regno_dead_p (3, CC_REGNO))"
  6821. + [(set (match_dup 2)
  6822. + (compare (match_dup 1)
  6823. + (match_dup 3)))
  6824. + (set (pc)
  6825. + (if_then_else (match_op_dup 6
  6826. + [(match_dup 2)
  6827. + (const_int 0)])
  6828. + (label_ref (match_dup 5))
  6829. + (pc)))]
  6830. + "{
  6831. + rtx cc_reg;
  6832. +
  6833. + cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
  6834. + operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
  6835. + GET_MODE (operands[4]),
  6836. + cc_reg,
  6837. + const0_rtx);
  6838. + }")
  6839. +
  6840. +(define_insn "btst"
  6841. + [(set (reg:CCWZ CC_REGNO)
  6842. + (compare:CCWZ
  6843. + (zero_extract:SI
  6844. + (match_operand:SI 0 "nonimmediate_operand" "rm")
  6845. + (const_int 1)
  6846. + (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
  6847. + (const_int 0)))]
  6848. + ""
  6849. + "btst\\t%0, %1")
  6850. +
  6851. +(define_insn "bfextu_ccwz_null"
  6852. + [(set (reg:CCWZ CC_REGNO)
  6853. + (compare:CCWZ
  6854. + (zero_extract:SI
  6855. + (match_operand:SI 0 "nonimmediate_operand" "rm")
  6856. + (match_operand 1 "const_int_operand" "M")
  6857. + (const_int 0))
  6858. + (const_int 0)))
  6859. + (clobber (match_scratch:SI 2 "=d"))]
  6860. + ""
  6861. + "bfextu\\t%2, %0, %1")
  6862. +
  6863. +(define_expand "addqi3"
  6864. + [(parallel
  6865. + [(set (match_operand:QI 0 "memory_operand" "")
  6866. + (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
  6867. + (match_operand:QI 2 "ubicom32_arith_operand" "")))
  6868. + (clobber (reg:CC CC_REGNO))])]
  6869. + "(ubicom32_v4)"
  6870. + "{
  6871. + if (!memory_operand (operands[0], QImode))
  6872. + FAIL;
  6873. +
  6874. + /* If we have a non-data reg for operand 1 then prefer that over
  6875. + a CONST_INT in operand 2. */
  6876. + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
  6877. + && CONST_INT_P (operands[2]))
  6878. + operands[2] = copy_to_mode_reg (QImode, operands[2]);
  6879. +
  6880. + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
  6881. + operands[2] = copy_to_mode_reg (QImode, operands[2]);
  6882. + }")
  6883. +
  6884. +(define_insn "addqi3_add1"
  6885. + [(set (match_operand:QI 0 "memory_operand" "=m, m")
  6886. + (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
  6887. + (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
  6888. + (clobber (reg:CC CC_REGNO))]
  6889. + "(ubicom32_v4)"
  6890. + "@
  6891. + add.1\\t%0, %2, %1
  6892. + add.1\\t%0, %1, %2")
  6893. +
  6894. +(define_insn "addqi3_add1_ccszn_null"
  6895. + [(set (reg CC_REGNO)
  6896. + (compare
  6897. + (neg:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm"))
  6898. + (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d")))]
  6899. + "(ubicom32_v4
  6900. + && ubicom32_match_cc_mode(insn, CCSZNmode))"
  6901. + "@
  6902. + add.1\\t#0, %1, %0
  6903. + add.1\\t#0, %0, %1")
  6904. +
  6905. +(define_expand "addhi3"
  6906. + [(parallel
  6907. + [(set (match_operand:HI 0 "memory_operand" "")
  6908. + (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
  6909. + (match_operand:HI 2 "ubicom32_arith_operand" "")))
  6910. + (clobber (reg:CC CC_REGNO))])]
  6911. + ""
  6912. + "{
  6913. + if (!memory_operand (operands[0], HImode))
  6914. + FAIL;
  6915. +
  6916. + /* If we have a non-data reg for operand 1 then prefer that over
  6917. + a CONST_INT in operand 2. */
  6918. + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
  6919. + && CONST_INT_P (operands[2]))
  6920. + operands[2] = copy_to_mode_reg (HImode, operands[2]);
  6921. +
  6922. + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
  6923. + operands[2] = copy_to_mode_reg (HImode, operands[2]);
  6924. + }")
  6925. +
  6926. +(define_insn "addhi3_add2"
  6927. + [(set (match_operand:HI 0 "memory_operand" "=m, m")
  6928. + (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
  6929. + (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
  6930. + (clobber (reg:CC CC_REGNO))]
  6931. + ""
  6932. + "@
  6933. + add.2\\t%0, %2, %1
  6934. + add.2\\t%0, %1, %2")
  6935. +
  6936. +(define_insn "addhi3_add2_ccszn_null"
  6937. + [(set (reg CC_REGNO)
  6938. + (compare
  6939. + (neg:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm"))
  6940. + (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d")))]
  6941. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  6942. + "@
  6943. + add.2\\t#0, %1, %0
  6944. + add.2\\t#0, %0, %1")
  6945. +
  6946. +(define_expand "addsi3"
  6947. + [(set (match_operand:SI 0 "nonimmediate_operand" "")
  6948. + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
  6949. + (match_operand:SI 2 "ubicom32_move_operand" "")))]
  6950. + ""
  6951. + "{
  6952. + ubicom32_expand_addsi3 (operands);
  6953. + DONE;
  6954. + }")
  6955. +
  6956. +; We start with an instruction pattern that can do all sorts of interesting
  6957. +; things but we split out any uses of lea or pdec instructions because
  6958. +; those instructions don't clobber the condition codes.
  6959. +;
  6960. +(define_insn_and_split "addsi3_1"
  6961. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm, rm,rm")
  6962. + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%a, a, a, a, a, d,rm")
  6963. + (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d,rmI, d")))
  6964. + (clobber (reg:CC CC_REGNO))]
  6965. + ""
  6966. + "@
  6967. + #
  6968. + #
  6969. + #
  6970. + #
  6971. + #
  6972. + add.4\\t%0, %2, %1
  6973. + add.4\\t%0, %1, %2"
  6974. + "(reload_completed
  6975. + && ubicom32_address_register_operand (operands[1], GET_MODE (operands[1])))"
  6976. + [(set (match_dup 0)
  6977. + (plus:SI (match_dup 1)
  6978. + (match_dup 2)))]
  6979. + ""
  6980. +)
  6981. +
  6982. +(define_insn "addsi3_1_ccwzn"
  6983. + [(set (reg CC_REGNO)
  6984. + (compare
  6985. + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
  6986. + (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
  6987. + (const_int 0)))
  6988. + (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
  6989. + (plus:SI (match_dup 1)
  6990. + (match_dup 2)))]
  6991. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  6992. + "@
  6993. + add.4\\t%0, %2, %1
  6994. + add.4\\t%0, %1, %2")
  6995. +
  6996. +(define_insn "addsi3_1_ccwzn_null"
  6997. + [(set (reg CC_REGNO)
  6998. + (compare
  6999. + (neg:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm"))
  7000. + (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d")))]
  7001. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  7002. + "@
  7003. + add.4\\t#0, %1, %0
  7004. + add.4\\t#0, %0, %1")
  7005. +
  7006. +(define_insn_and_split "addsi3_2"
  7007. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm,rm")
  7008. + (plus:SI (match_operand:SI 1 "ubicom32_address_register_operand" "%a, a, a, a, a, a")
  7009. + (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d, n")))]
  7010. + ""
  7011. + "@
  7012. + lea.4\\t%0, %E2(%1)
  7013. + lea.2\\t%0, %E2(%1)
  7014. + lea.1\\t%0, %E2(%1)
  7015. + pdec\\t%0, %n2(%1)
  7016. + lea.1\\t%0, (%1,%2)
  7017. + #"
  7018. + "(reload_completed
  7019. + && ! satisfies_constraint_L (operands[2])
  7020. + && ! satisfies_constraint_K (operands[2])
  7021. + && ! satisfies_constraint_J (operands[2])
  7022. + && ! satisfies_constraint_P (operands[2])
  7023. + && ! ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))"
  7024. + [(set (reg:SI AUX_DATA_REGNO)
  7025. + (match_dup 2))
  7026. + (set (match_dup 0)
  7027. + (plus:SI (match_dup 1)
  7028. + (reg:SI AUX_DATA_REGNO)))]
  7029. + ""
  7030. +)
  7031. +
  7032. +(define_insn "lea_2"
  7033. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
  7034. + (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
  7035. + (const_int 2))
  7036. + (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
  7037. + ""
  7038. + "lea.2\\t%0, (%2,%1)")
  7039. +
  7040. +(define_insn "lea_4"
  7041. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
  7042. + (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
  7043. + (const_int 4))
  7044. + (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
  7045. + ""
  7046. + "lea.4\\t%0, (%2,%1)")
  7047. +
  7048. +(define_expand "adddi3"
  7049. + [(parallel
  7050. + [(set (match_operand:DI 0 "nonimmediate_operand" "")
  7051. + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
  7052. + (match_operand:DI 2 "ubicom32_arith_operand" "")))
  7053. + (clobber (reg:CC CC_REGNO))])]
  7054. + ""
  7055. + "{
  7056. + /* If we have a non-data reg for operand 1 then prefer that over
  7057. + a CONST_INT in operand 2. */
  7058. + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
  7059. + && CONST_INT_P (operands[2]))
  7060. + operands[2] = copy_to_mode_reg (DImode, operands[2]);
  7061. +
  7062. + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
  7063. + operands[2] = copy_to_mode_reg (DImode, operands[2]);
  7064. + }")
  7065. +
  7066. +; We construct a 64-bit add from 32-bit operations. Note that we use the
  7067. +; & constraint to prevent overlapping registers being allocated. We do
  7068. +; allow identical registers though as that won't break anything.
  7069. +;
  7070. +(define_insn "adddi3_add4addc"
  7071. + [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
  7072. + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
  7073. + (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d")))
  7074. + (clobber (reg:CC CC_REGNO))]
  7075. + ""
  7076. + "*
  7077. + {
  7078. + operands[3] = gen_lowpart (SImode, operands[0]);
  7079. + operands[4] = gen_lowpart (SImode, operands[1]);
  7080. + operands[5] = gen_lowpart (SImode, operands[2]);
  7081. + operands[6] = gen_highpart (SImode, operands[0]);
  7082. + operands[7] = gen_highpart (SImode, operands[1]);
  7083. + operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
  7084. +
  7085. + if (ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
  7086. + return \"add.4\\t%3, %4, %5\;addc\\t%6, %7, %8\";
  7087. +
  7088. + return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
  7089. + }"
  7090. + [(set_attr "length" "8")])
  7091. +
  7092. +(define_insn "adddi3_ccwz"
  7093. + [(set (reg CC_REGNO)
  7094. + (compare
  7095. + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
  7096. + (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d"))
  7097. + (const_int 0)))
  7098. + (set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
  7099. + (plus:DI (match_dup 1)
  7100. + (match_dup 2)))]
  7101. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  7102. + "*
  7103. + {
  7104. + operands[3] = gen_lowpart (SImode, operands[0]);
  7105. + operands[6] = gen_highpart (SImode, operands[0]);
  7106. +
  7107. + if (ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
  7108. + {
  7109. + operands[4] = gen_lowpart (SImode, operands[1]);
  7110. + operands[5] = gen_lowpart (SImode, operands[2]);
  7111. + operands[7] = gen_highpart (SImode, operands[1]);
  7112. + operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
  7113. + }
  7114. + else
  7115. + {
  7116. + operands[4] = gen_lowpart (SImode, operands[2]);
  7117. + operands[5] = gen_lowpart (SImode, operands[1]);
  7118. + operands[7] = gen_highpart (SImode, operands[2]);
  7119. + operands[8] = gen_highpart (SImode, operands[1]);
  7120. + }
  7121. +
  7122. + return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
  7123. + }"
  7124. + [(set_attr "length" "8")])
  7125. +
  7126. +(define_insn "adddi3_ccwz_null"
  7127. + [(set (reg CC_REGNO)
  7128. + (compare
  7129. + (neg:DI (match_operand:DI 0 "nonimmediate_operand" "%d,rm"))
  7130. + (match_operand:DI 1 "ubicom32_arith_operand" "rmI, d")))]
  7131. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  7132. + "*
  7133. + {
  7134. + if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
  7135. + {
  7136. + operands[2] = gen_lowpart (SImode, operands[0]);
  7137. + operands[3] = gen_lowpart (SImode, operands[1]);
  7138. + operands[4] = gen_highpart (SImode, operands[0]);
  7139. + operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
  7140. + }
  7141. + else
  7142. + {
  7143. + operands[2] = gen_lowpart (SImode, operands[1]);
  7144. + operands[3] = gen_lowpart (SImode, operands[0]);
  7145. + operands[4] = gen_highpart (SImode, operands[1]);
  7146. + operands[5] = gen_highpart (SImode, operands[0]);
  7147. + }
  7148. +
  7149. + return \"add.4\\t#0, %3, %2\;addc\\t#0, %5, %4\";
  7150. + }"
  7151. + [(set_attr "length" "8")])
  7152. +
  7153. +(define_expand "subqi3"
  7154. + [(parallel
  7155. + [(set (match_operand:QI 0 "memory_operand" "")
  7156. + (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "")
  7157. + (match_operand:QI 2 "ubicom32_data_register_operand" "")))
  7158. + (clobber (reg:CC CC_REGNO))])]
  7159. + "(ubicom32_v4)"
  7160. + "{
  7161. + if (!memory_operand (operands[0], QImode))
  7162. + FAIL;
  7163. + }")
  7164. +
  7165. +(define_insn "subqi3_sub1"
  7166. + [(set (match_operand:QI 0 "memory_operand" "=m")
  7167. + (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "rmI")
  7168. + (match_operand:QI 2 "ubicom32_data_register_operand" "d")))
  7169. + (clobber (reg:CC CC_REGNO))]
  7170. + "(ubicom32_v4)"
  7171. + "sub.1\\t%0, %1, %2")
  7172. +
  7173. +(define_expand "subhi3"
  7174. + [(parallel
  7175. + [(set (match_operand:HI 0 "memory_operand" "")
  7176. + (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "")
  7177. + (match_operand:HI 2 "ubicom32_data_register_operand" "")))
  7178. + (clobber (reg:CC CC_REGNO))])]
  7179. + "(ubicom32_v4)"
  7180. + "{
  7181. + if (!memory_operand (operands[0], HImode))
  7182. + FAIL;
  7183. + }")
  7184. +
  7185. +(define_insn "subhi3_sub2"
  7186. + [(set (match_operand:HI 0 "memory_operand" "=m")
  7187. + (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")
  7188. + (match_operand:HI 2 "ubicom32_data_register_operand" "d")))
  7189. + (clobber (reg:CC CC_REGNO))]
  7190. + ""
  7191. + "sub.2\\t%0, %1, %2")
  7192. +
  7193. +(define_insn "subsi3"
  7194. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
  7195. + (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
  7196. + (match_operand:SI 2 "ubicom32_data_register_operand" "d")))
  7197. + (clobber (reg:CC CC_REGNO))]
  7198. + ""
  7199. + "sub.4\\t%0, %1, %2")
  7200. +
  7201. +(define_insn "subsi3_ccwz"
  7202. + [(set (reg CC_REGNO)
  7203. + (compare
  7204. + (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
  7205. + (match_operand:SI 2 "ubicom32_data_register_operand" "d"))
  7206. + (const_int 0)))
  7207. + (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
  7208. + (minus:SI (match_dup 1)
  7209. + (match_dup 2)))]
  7210. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  7211. + "sub.4\\t%0, %1, %2")
  7212. +
  7213. +; We construct a 64-bit add from 32-bit operations. Note that we use the
  7214. +; & constraint to prevent overlapping registers being allocated. We do
  7215. +; allow identical registers though as that won't break anything.
  7216. +;
  7217. +(define_insn "subdi3"
  7218. + [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r, d, m")
  7219. + (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,0,rmI,rmI")
  7220. + (match_operand:DI 2 "ubicom32_data_register_operand" "d,d, 0, d")))
  7221. + (clobber (reg:CC CC_REGNO))]
  7222. + ""
  7223. + "*
  7224. + {
  7225. + operands[3] = gen_lowpart (SImode, operands[0]);
  7226. + operands[4] = gen_lowpart (SImode, operands[1]);
  7227. + operands[5] = gen_lowpart (SImode, operands[2]);
  7228. + operands[6] = gen_highpart (SImode, operands[0]);
  7229. + operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
  7230. + operands[8] = gen_highpart (SImode, operands[2]);
  7231. +
  7232. + return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
  7233. + }"
  7234. + [(set_attr "length" "8")])
  7235. +
  7236. +(define_insn "subdi3_ccwz"
  7237. + [(set (reg CC_REGNO)
  7238. + (compare
  7239. + (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,rmI")
  7240. + (match_operand:DI 2 "ubicom32_data_register_operand" "d, d"))
  7241. + (const_int 0)))
  7242. + (set (match_operand:DI 0 "nonimmediate_operand" "=&r, m")
  7243. + (minus:DI (match_dup 1)
  7244. + (match_dup 2)))]
  7245. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  7246. + "*
  7247. + {
  7248. + operands[3] = gen_lowpart (SImode, operands[0]);
  7249. + operands[4] = gen_lowpart (SImode, operands[1]);
  7250. + operands[5] = gen_lowpart (SImode, operands[2]);
  7251. + operands[6] = gen_highpart (SImode, operands[0]);
  7252. + operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
  7253. + operands[8] = gen_highpart (SImode, operands[2]);
  7254. +
  7255. + return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
  7256. + }"
  7257. + [(set_attr "length" "8")])
  7258. +
  7259. +;(define_insn "negqi2"
  7260. +; [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
  7261. +; (neg:QI (match_operand:QI 1 "ubicom32_data_register_operand" "d")))
  7262. +; (clobber (reg:CC CC_REGNO))]
  7263. +; "(ubicom32_v4)"
  7264. +; "sub.1\\t%0, #0, %1")
  7265. +
  7266. +;(define_insn "neghi2"
  7267. +; [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
  7268. +; (neg:HI (match_operand:HI 1 "ubicom32_data_register_operand" "d")))
  7269. +; (clobber (reg:CC CC_REGNO))]
  7270. +; ""
  7271. +; "sub.2\\t%0, #0, %1")
  7272. +
  7273. +(define_insn "negsi2"
  7274. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
  7275. + (neg:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")))
  7276. + (clobber (reg:CC CC_REGNO))]
  7277. + ""
  7278. + "sub.4\\t%0, #0, %1")
  7279. +
  7280. +(define_insn_and_split "negdi2"
  7281. + [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
  7282. + (neg:DI (match_operand:DI 1 "ubicom32_data_register_operand" "d")))
  7283. + (clobber (reg:CC CC_REGNO))]
  7284. + ""
  7285. + "#"
  7286. + "reload_completed"
  7287. + [(parallel [(set (match_dup 0)
  7288. + (minus:DI (const_int 0)
  7289. + (match_dup 1)))
  7290. + (clobber (reg:CC CC_REGNO))])]
  7291. + ""
  7292. + [(set_attr "length" "8")])
  7293. +
  7294. +(define_insn "umulhisi3"
  7295. + [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
  7296. + (mult:SI
  7297. + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
  7298. + (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
  7299. + (clobber (reg:HI ACC0_HI_REGNO))
  7300. + (clobber (reg:HI ACC1_HI_REGNO))]
  7301. + ""
  7302. + "@
  7303. + mulu\\t%A0, %2, %1
  7304. + mulu\\t%A0, %1, %2"
  7305. + [(set_attr "type" "mul,mul")])
  7306. +
  7307. +(define_insn "mulhisi3"
  7308. + [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
  7309. + (mult:SI
  7310. + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
  7311. + (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
  7312. + (clobber (reg:HI ACC0_HI_REGNO))
  7313. + (clobber (reg:HI ACC1_HI_REGNO))]
  7314. + ""
  7315. + "@
  7316. + muls\\t%A0, %2, %1
  7317. + muls\\t%A0, %1, %2"
  7318. + [(set_attr "type" "mul,mul")])
  7319. +
  7320. +(define_expand "mulsi3"
  7321. + [(set (match_operand:SI 0 "ubicom32_acc_hi_register_operand" "")
  7322. + (mult:SI (match_operand:SI 1 "ubicom32_arith_operand" "")
  7323. + (match_operand:SI 2 "ubicom32_arith_operand" "")))]
  7324. + ""
  7325. + "{
  7326. + if (ubicom32_emit_mult_sequence (operands))
  7327. + DONE;
  7328. + }")
  7329. +
  7330. +(define_insn "umulsidi3"
  7331. + [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
  7332. + (mult:DI
  7333. + (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
  7334. + (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
  7335. + "(ubicom32_v4)"
  7336. + "@
  7337. + mulu.4\\t%A0, %2, %1
  7338. + mulu.4\\t%A0, %1, %2"
  7339. + [(set_attr "type" "mul,mul")])
  7340. +
  7341. +(define_peephole2
  7342. + [(set (match_operand:SI 0 "register_operand" "")
  7343. + (match_operand:SI 1 "nonimmediate_operand" ""))
  7344. + (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
  7345. + (mult:DI
  7346. + (zero_extend:DI (match_dup 0))
  7347. + (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
  7348. + "(peep2_reg_dead_p (2, operands[0])
  7349. + || REGNO (operands[0]) == REGNO (operands[2])
  7350. + || REGNO (operands[0]) == REGNO (operands[2]) + 1)
  7351. + && ! rtx_equal_p (operands[0], operands[3])"
  7352. + [(set (match_dup 2)
  7353. + (mult:DI
  7354. + (zero_extend:DI (match_dup 1))
  7355. + (zero_extend:DI (match_dup 3))))]
  7356. + "")
  7357. +
  7358. +(define_peephole2
  7359. + [(set (match_operand:SI 0 "register_operand" "")
  7360. + (match_operand:SI 1 "nonimmediate_operand" ""))
  7361. + (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
  7362. + (mult:DI
  7363. + (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
  7364. + (zero_extend:DI (match_dup 0))))]
  7365. + "(peep2_reg_dead_p (2, operands[0])
  7366. + || REGNO (operands[0]) == REGNO (operands[2])
  7367. + || REGNO (operands[0]) == REGNO (operands[2]) + 1)
  7368. + && ! rtx_equal_p (operands[0], operands[3])"
  7369. + [(set (match_dup 2)
  7370. + (mult:DI
  7371. + (zero_extend:DI (match_dup 1))
  7372. + (zero_extend:DI (match_dup 3))))]
  7373. + "")
  7374. +
  7375. +(define_insn "umulsidi3_const"
  7376. + [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
  7377. + (mult:DI
  7378. + (zero_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
  7379. + (match_operand 2 "const_int_operand" "I")))]
  7380. + "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
  7381. + "mulu.4\\t%A0, %2, %1"
  7382. + [(set_attr "type" "mul")])
  7383. +
  7384. +(define_insn "mulsidi3"
  7385. + [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
  7386. + (mult:DI
  7387. + (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
  7388. + (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
  7389. + "(ubicom32_v4)"
  7390. + "@
  7391. + muls.4\\t%A0, %2, %1
  7392. + muls.4\\t%A0, %1, %2"
  7393. + [(set_attr "type" "mul,mul")])
  7394. +
  7395. +(define_peephole2
  7396. + [(set (match_operand:SI 0 "register_operand" "")
  7397. + (match_operand:SI 1 "nonimmediate_operand" ""))
  7398. + (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
  7399. + (mult:DI
  7400. + (sign_extend:DI (match_dup 0))
  7401. + (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
  7402. + "(peep2_reg_dead_p (2, operands[0])
  7403. + || REGNO (operands[0]) == REGNO (operands[2])
  7404. + || REGNO (operands[0]) == REGNO (operands[2]) + 1)
  7405. + && ! rtx_equal_p (operands[0], operands[3])"
  7406. + [(set (match_dup 2)
  7407. + (mult:DI
  7408. + (sign_extend:DI (match_dup 1))
  7409. + (sign_extend:DI (match_dup 3))))]
  7410. + "")
  7411. +
  7412. +(define_peephole2
  7413. + [(set (match_operand:SI 0 "register_operand" "")
  7414. + (match_operand:SI 1 "nonimmediate_operand" ""))
  7415. + (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
  7416. + (mult:DI
  7417. + (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
  7418. + (sign_extend:DI (match_dup 0))))]
  7419. + "(peep2_reg_dead_p (2, operands[0])
  7420. + || REGNO (operands[0]) == REGNO (operands[2])
  7421. + || REGNO (operands[0]) == REGNO (operands[2]) + 1)
  7422. + && ! rtx_equal_p (operands[0], operands[3])"
  7423. + [(set (match_dup 2)
  7424. + (mult:DI
  7425. + (sign_extend:DI (match_dup 1))
  7426. + (sign_extend:DI (match_dup 3))))]
  7427. + "")
  7428. +
  7429. +(define_insn "mulsidi3_const"
  7430. + [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
  7431. + (mult:DI
  7432. + (sign_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
  7433. + (match_operand 2 "const_int_operand" "I")))]
  7434. + "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
  7435. + "muls.4\\t%A0, %2, %1"
  7436. + [(set_attr "type" "mul")])
  7437. +
  7438. +(define_expand "andqi3"
  7439. + [(parallel
  7440. + [(set (match_operand:QI 0 "memory_operand" "")
  7441. + (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
  7442. + (match_operand:QI 2 "ubicom32_arith_operand" "")))
  7443. + (clobber (reg:CC CC_REGNO))])]
  7444. + "(ubicom32_v4)"
  7445. + "{
  7446. + if (!memory_operand (operands[0], QImode))
  7447. + FAIL;
  7448. +
  7449. + /* If we have a non-data reg for operand 1 then prefer that over
  7450. + a CONST_INT in operand 2. */
  7451. + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
  7452. + && CONST_INT_P (operands[2]))
  7453. + operands[2] = copy_to_mode_reg (QImode, operands[2]);
  7454. +
  7455. + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
  7456. + operands[2] = copy_to_mode_reg (QImode, operands[2]);
  7457. + }")
  7458. +
  7459. +(define_insn "andqi3_and1"
  7460. + [(set (match_operand:QI 0 "memory_operand" "=m, m")
  7461. + (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
  7462. + (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
  7463. + (clobber (reg:CC CC_REGNO))]
  7464. + "(ubicom32_v4)"
  7465. + "@
  7466. + and.1\\t%0, %2, %1
  7467. + and.1\\t%0, %1, %2")
  7468. +
  7469. +(define_insn "andqi3_and1_ccszn"
  7470. + [(set (reg CC_REGNO)
  7471. + (compare
  7472. + (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
  7473. + (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
  7474. + (const_int 0)))
  7475. + (set (match_operand:QI 0 "memory_operand" "=m, m")
  7476. + (and:QI (match_dup 1)
  7477. + (match_dup 2)))]
  7478. + "(ubicom32_v4
  7479. + && ubicom32_match_cc_mode(insn, CCSZNmode))"
  7480. + "@
  7481. + and.1\\t%0, %2, %1
  7482. + and.1\\t%0, %1, %2")
  7483. +
  7484. +(define_insn "andqi3_and1_ccszn_null"
  7485. + [(set (reg CC_REGNO)
  7486. + (compare
  7487. + (and:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
  7488. + (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
  7489. + (const_int 0)))]
  7490. + "(ubicom32_v4
  7491. + && ubicom32_match_cc_mode(insn, CCSZNmode))"
  7492. + "@
  7493. + and.1\\t#0, %1, %0
  7494. + and.1\\t#0, %0, %1")
  7495. +
  7496. +(define_insn "and1_ccszn_null_1"
  7497. + [(set (reg CC_REGNO)
  7498. + (compare
  7499. + (subreg:QI
  7500. + (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
  7501. + (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
  7502. + 3)
  7503. + (const_int 0)))]
  7504. + "(ubicom32_v4
  7505. + && ubicom32_match_cc_mode(insn, CCSZNmode))"
  7506. + "and.1\\t#0, %1, %0")
  7507. +
  7508. +(define_insn "and1_ccszn_null_2"
  7509. + [(set (reg CC_REGNO)
  7510. + (compare
  7511. + (subreg:QI
  7512. + (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
  7513. + (subreg:SI
  7514. + (match_operand:QI 1 "memory_operand" "m")
  7515. + 0))
  7516. + 3)
  7517. + (const_int 0)))]
  7518. + "(ubicom32_v4
  7519. + && ubicom32_match_cc_mode(insn, CCSZNmode))"
  7520. + "and.1\\t#0, %1, %0")
  7521. +
  7522. +(define_insn "and1_ccszn_null_3"
  7523. + [(set (reg CC_REGNO)
  7524. + (compare
  7525. + (subreg:QI
  7526. + (and:SI (subreg:SI
  7527. + (match_operand:QI 0 "memory_operand" "m")
  7528. + 0)
  7529. + (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
  7530. + 3)
  7531. + (const_int 0)))]
  7532. + "(ubicom32_v4
  7533. + && ubicom32_match_cc_mode(insn, CCSZNmode))"
  7534. + "and.1\\t#0, %0, %1")
  7535. +
  7536. +(define_expand "andhi3"
  7537. + [(parallel
  7538. + [(set (match_operand:HI 0 "memory_operand" "")
  7539. + (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
  7540. + (match_operand:HI 2 "ubicom32_arith_operand" "")))
  7541. + (clobber (reg:CC CC_REGNO))])]
  7542. + ""
  7543. + "{
  7544. + if (!memory_operand (operands[0], HImode))
  7545. + FAIL;
  7546. +
  7547. + /* If we have a non-data reg for operand 1 then prefer that over
  7548. + a CONST_INT in operand 2. */
  7549. + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
  7550. + && CONST_INT_P (operands[2]))
  7551. + operands[2] = copy_to_mode_reg (HImode, operands[2]);
  7552. +
  7553. + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
  7554. + operands[2] = copy_to_mode_reg (HImode, operands[2]);
  7555. + }")
  7556. +
  7557. +(define_insn "andhi3_and2"
  7558. + [(set (match_operand:HI 0 "memory_operand" "=m, m")
  7559. + (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
  7560. + (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
  7561. + (clobber (reg:CC CC_REGNO))]
  7562. + ""
  7563. + "@
  7564. + and.2\\t%0, %2, %1
  7565. + and.2\\t%0, %1, %2")
  7566. +
  7567. +(define_insn "andhi3_and2_ccszn"
  7568. + [(set (reg CC_REGNO)
  7569. + (compare
  7570. + (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
  7571. + (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
  7572. + (const_int 0)))
  7573. + (set (match_operand:HI 0 "memory_operand" "=m, m")
  7574. + (and:HI (match_dup 1)
  7575. + (match_dup 2)))]
  7576. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  7577. + "@
  7578. + and.2\\t%0, %2, %1
  7579. + and.2\\t%0, %1, %2")
  7580. +
  7581. +(define_insn "andhi3_and2_ccszn_null"
  7582. + [(set (reg CC_REGNO)
  7583. + (compare
  7584. + (and:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
  7585. + (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
  7586. + (const_int 0)))]
  7587. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  7588. + "@
  7589. + and.2\\t#0, %1, %0
  7590. + and.2\\t#0, %0, %1")
  7591. +
  7592. +(define_insn "and2_ccszn_null_1"
  7593. + [(set (reg CC_REGNO)
  7594. + (compare
  7595. + (subreg:HI
  7596. + (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
  7597. + (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
  7598. + 2)
  7599. + (const_int 0)))]
  7600. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  7601. + "and.2\\t#0, %1, %0")
  7602. +
  7603. +(define_insn "and2_ccszn_null_2"
  7604. + [(set (reg CC_REGNO)
  7605. + (compare
  7606. + (subreg:HI
  7607. + (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
  7608. + (subreg:SI
  7609. + (match_operand:HI 1 "memory_operand" "m")
  7610. + 0))
  7611. + 2)
  7612. + (const_int 0)))]
  7613. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  7614. + "and.2\\t#0, %1, %0")
  7615. +
  7616. +(define_insn "and2_ccszn_null_3"
  7617. + [(set (reg CC_REGNO)
  7618. + (compare
  7619. + (subreg:HI
  7620. + (and:SI (subreg:SI
  7621. + (match_operand:HI 0 "memory_operand" "m")
  7622. + 0)
  7623. + (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
  7624. + 2)
  7625. + (const_int 0)))]
  7626. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  7627. + "and.2\\t#0, %0, %1")
  7628. +
  7629. +(define_expand "andsi3"
  7630. + [(parallel
  7631. + [(set (match_operand:SI 0 "nonimmediate_operand" "")
  7632. + (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
  7633. + (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
  7634. + (clobber (reg:CC CC_REGNO))])]
  7635. + ""
  7636. + "{
  7637. + do
  7638. + {
  7639. + /* Is this a bfextu? */
  7640. + if (ubicom32_data_register_operand (operands[0], SImode)
  7641. + && CONST_INT_P (operands[2])
  7642. + && exact_log2 (INTVAL (operands[2]) + 1) != -1)
  7643. + break;
  7644. +
  7645. + /* Is this a bclr? */
  7646. + if (CONST_INT_P (operands[2])
  7647. + && exact_log2 (~INTVAL (operands[2])) != -1)
  7648. + break;
  7649. +
  7650. + /* Must be an and.4 */
  7651. + if (!ubicom32_data_register_operand (operands[1], SImode))
  7652. + operands[1] = copy_to_mode_reg (SImode, operands[1]);
  7653. +
  7654. + if (!ubicom32_arith_operand (operands[2], SImode))
  7655. + operands[2] = copy_to_mode_reg (SImode, operands[2]);
  7656. + }
  7657. + while (0);
  7658. + }")
  7659. +
  7660. +(define_insn "andsi3_bfextu"
  7661. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  7662. + (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
  7663. + (match_operand:SI 2 "const_int_operand" "O")))
  7664. + (clobber (reg:CC CC_REGNO))]
  7665. + "(satisfies_constraint_O (operands[2]))"
  7666. + "*
  7667. + {
  7668. + operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
  7669. +
  7670. + return \"bfextu\\t%0, %1, %3\";
  7671. + }")
  7672. +
  7673. +(define_insn "andsi3_bfextu_ccwz"
  7674. + [(set (reg CC_REGNO)
  7675. + (compare
  7676. + (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
  7677. + (match_operand:SI 2 "const_int_operand" "O"))
  7678. + (const_int 0)))
  7679. + (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  7680. + (and:SI (match_dup 1)
  7681. + (match_dup 2)))]
  7682. + "(satisfies_constraint_O (operands[2])
  7683. + && ubicom32_match_cc_mode(insn, CCWZmode))"
  7684. + "*
  7685. + {
  7686. + operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
  7687. +
  7688. + return \"bfextu\\t%0, %1, %3\";
  7689. + }")
  7690. +
  7691. +(define_insn "andsi3_bfextu_ccwz_null"
  7692. + [(set (reg CC_REGNO)
  7693. + (compare
  7694. + (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
  7695. + (match_operand:SI 1 "const_int_operand" "O"))
  7696. + (const_int 0)))
  7697. + (clobber (match_scratch:SI 2 "=d"))]
  7698. + "(satisfies_constraint_O (operands[1])
  7699. + && ubicom32_match_cc_mode(insn, CCWZmode))"
  7700. + "*
  7701. + {
  7702. + operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
  7703. +
  7704. + return \"bfextu\\t%2, %0, %3\";
  7705. + }")
  7706. +
  7707. +(define_insn "andsi3_bclr"
  7708. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
  7709. + (and:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
  7710. + (match_operand:SI 2 "const_int_operand" "n")))
  7711. + (clobber (reg:CC CC_REGNO))]
  7712. + "(exact_log2 (~INTVAL (operands[2])) != -1)"
  7713. + "bclr\\t%0, %1, #%D2")
  7714. +
  7715. +(define_insn "andsi3_and4"
  7716. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
  7717. + (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
  7718. + (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
  7719. + (clobber (reg:CC CC_REGNO))]
  7720. + ""
  7721. + "@
  7722. + and.4\\t%0, %2, %1
  7723. + and.4\\t%0, %1, %2")
  7724. +
  7725. +(define_insn "andsi3_and4_ccwzn"
  7726. + [(set (reg CC_REGNO)
  7727. + (compare
  7728. + (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
  7729. + (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
  7730. + (const_int 0)))
  7731. + (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
  7732. + (and:SI (match_dup 1)
  7733. + (match_dup 2)))]
  7734. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  7735. + "@
  7736. + and.4\\t%0, %2, %1
  7737. + and.4\\t%0, %1, %2")
  7738. +
  7739. +(define_insn "andsi3_and4_ccwzn_null"
  7740. + [(set (reg CC_REGNO)
  7741. + (compare
  7742. + (and:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
  7743. + (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
  7744. + (const_int 0)))]
  7745. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  7746. + "@
  7747. + and.4\\t#0, %1, %0
  7748. + and.4\\t#0, %0, %1")
  7749. +
  7750. +(define_insn "andsi3_lsr4_ccwz_null"
  7751. + [(set (reg CC_REGNO)
  7752. + (compare
  7753. + (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
  7754. + (match_operand:SI 1 "const_int_operand" "n"))
  7755. + (const_int 0)))
  7756. + (clobber (match_scratch:SI 2 "=d"))]
  7757. + "(exact_log2 ((~(INTVAL (operands[1]))) + 1) != -1
  7758. + && ubicom32_match_cc_mode(insn, CCWZmode))"
  7759. + "*
  7760. + {
  7761. + operands[3] = GEN_INT (exact_log2 ((~(INTVAL (operands[1]))) + 1));
  7762. +
  7763. + return \"lsr.4\\t%2, %0, %3\";
  7764. + }")
  7765. +
  7766. +; We really would like the combiner to recognize this scenario and deal with
  7767. +; it but unfortunately it tries to canonicalize zero_extract ops on MEMs
  7768. +; into QImode operations and we can't match them in any useful way.
  7769. +;
  7770. +(define_peephole2
  7771. + [(set (match_operand:SI 0 "register_operand" "")
  7772. + (match_operand:SI 1 "const_int_operand" ""))
  7773. + (set (reg:CCWZ CC_REGNO)
  7774. + (compare:CCWZ
  7775. + (and:SI (match_operand:SI 2 "nonimmediate_operand" "")
  7776. + (match_dup 0))
  7777. + (const_int 0)))]
  7778. + "(exact_log2 (INTVAL (operands[1])) != -1
  7779. + && peep2_reg_dead_p (2, operands[0]))"
  7780. + [(set (reg:CCWZ CC_REGNO)
  7781. + (compare:CCWZ
  7782. + (zero_extract:SI
  7783. + (match_dup 2)
  7784. + (const_int 1)
  7785. + (match_dup 3))
  7786. + (const_int 0)))]
  7787. + "{
  7788. + operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1])));
  7789. + }")
  7790. +
  7791. +(define_expand "anddi3"
  7792. + [(parallel
  7793. + [(set (match_operand:DI 0 "nonimmediate_operand" "")
  7794. + (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
  7795. + (match_operand:DI 2 "ubicom32_arith_operand" "")))
  7796. + (clobber (reg:CC CC_REGNO))])]
  7797. + ""
  7798. + "{
  7799. + /* If we have a non-data reg for operand 1 then prefer that over
  7800. + a CONST_INT in operand 2. */
  7801. + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
  7802. + && CONST_INT_P (operands[2]))
  7803. + operands[2] = copy_to_mode_reg (DImode, operands[2]);
  7804. +
  7805. + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
  7806. + operands[2] = copy_to_mode_reg (DImode, operands[2]);
  7807. + }")
  7808. +
  7809. +(define_insn_and_split "anddi3_and4"
  7810. + [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
  7811. + (and:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
  7812. + (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
  7813. + (clobber (reg:CC CC_REGNO))]
  7814. + ""
  7815. + "#"
  7816. + "reload_completed"
  7817. + [(parallel [(set (match_dup 3)
  7818. + (and:SI (match_dup 4)
  7819. + (match_dup 5)))
  7820. + (clobber (reg:CC CC_REGNO))])
  7821. + (parallel [(set (match_dup 6)
  7822. + (and:SI (match_dup 7)
  7823. + (match_dup 8)))
  7824. + (clobber (reg:CC CC_REGNO))])]
  7825. + "{
  7826. + operands[3] = gen_lowpart (SImode, operands[0]);
  7827. + operands[4] = gen_lowpart (SImode, operands[1]);
  7828. + operands[5] = gen_lowpart (SImode, operands[2]);
  7829. + operands[6] = gen_highpart (SImode, operands[0]);
  7830. + operands[7] = gen_highpart (SImode, operands[1]);
  7831. + operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
  7832. + }"
  7833. + [(set_attr "length" "8")])
  7834. +
  7835. +(define_expand "iorqi3"
  7836. + [(parallel
  7837. + [(set (match_operand:QI 0 "memory_operand" "")
  7838. + (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
  7839. + (match_operand:QI 2 "ubicom32_arith_operand" "")))
  7840. + (clobber (reg:CC CC_REGNO))])]
  7841. + "(ubicom32_v4)"
  7842. + "{
  7843. + if (!memory_operand (operands[0], QImode))
  7844. + FAIL;
  7845. +
  7846. + /* If we have a non-data reg for operand 1 then prefer that over
  7847. + a CONST_INT in operand 2. */
  7848. + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
  7849. + && CONST_INT_P (operands[2]))
  7850. + operands[2] = copy_to_mode_reg (QImode, operands[2]);
  7851. +
  7852. + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
  7853. + operands[2] = copy_to_mode_reg (QImode, operands[2]);
  7854. + }")
  7855. +
  7856. +(define_insn "iorqi3_or1"
  7857. + [(set (match_operand:QI 0 "memory_operand" "=m, m")
  7858. + (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
  7859. + (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
  7860. + (clobber (reg:CC CC_REGNO))]
  7861. + "(ubicom32_v4)"
  7862. + "@
  7863. + or.1\\t%0, %2, %1
  7864. + or.1\\t%0, %1, %2")
  7865. +
  7866. +(define_expand "iorhi3"
  7867. + [(parallel
  7868. + [(set (match_operand:HI 0 "memory_operand" "")
  7869. + (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
  7870. + (match_operand:HI 2 "ubicom32_arith_operand" "")))
  7871. + (clobber (reg:CC CC_REGNO))])]
  7872. + ""
  7873. + "{
  7874. + if (!memory_operand (operands[0], HImode))
  7875. + FAIL;
  7876. +
  7877. + /* If we have a non-data reg for operand 1 then prefer that over
  7878. + a CONST_INT in operand 2. */
  7879. + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
  7880. + && CONST_INT_P (operands[2]))
  7881. + operands[2] = copy_to_mode_reg (HImode, operands[2]);
  7882. +
  7883. + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
  7884. + operands[2] = copy_to_mode_reg (HImode, operands[2]);
  7885. + }")
  7886. +
  7887. +(define_insn "iorhi3_or2"
  7888. + [(set (match_operand:HI 0 "memory_operand" "=m, m")
  7889. + (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
  7890. + (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
  7891. + (clobber (reg:CC CC_REGNO))]
  7892. + ""
  7893. + "@
  7894. + or.2\\t%0, %2, %1
  7895. + or.2\\t%0, %1, %2")
  7896. +
  7897. +(define_expand "iorsi3"
  7898. + [(parallel
  7899. + [(set (match_operand:SI 0 "nonimmediate_operand" "")
  7900. + (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
  7901. + (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
  7902. + (clobber (reg:CC CC_REGNO))])]
  7903. + ""
  7904. + "{
  7905. + do
  7906. + {
  7907. + /* Is this a bset? */
  7908. + if (CONST_INT_P (operands[2])
  7909. + && exact_log2 (INTVAL (operands[2])) != -1)
  7910. + break;
  7911. +
  7912. + /* Must be an or.4 */
  7913. + if (!ubicom32_data_register_operand (operands[1], SImode))
  7914. + operands[1] = copy_to_mode_reg (SImode, operands[1]);
  7915. +
  7916. + if (!ubicom32_arith_operand (operands[2], SImode))
  7917. + operands[2] = copy_to_mode_reg (SImode, operands[2]);
  7918. + }
  7919. + while (0);
  7920. + }")
  7921. +
  7922. +(define_insn "iorsi3_bset"
  7923. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
  7924. + (ior:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
  7925. + (match_operand 2 "const_int_operand" "n")))
  7926. + (clobber (reg:CC CC_REGNO))]
  7927. + "(exact_log2 (INTVAL (operands[2])) != -1)"
  7928. + "bset\\t%0, %1, #%d2")
  7929. +
  7930. +(define_insn "iorsi3_or4"
  7931. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
  7932. + (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
  7933. + (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
  7934. + (clobber (reg:CC CC_REGNO))]
  7935. + ""
  7936. + "@
  7937. + or.4\\t%0, %2, %1
  7938. + or.4\\t%0, %1, %2")
  7939. +
  7940. +(define_insn "iorsi3_ccwzn"
  7941. + [(set (reg CC_REGNO)
  7942. + (compare
  7943. + (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
  7944. + (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
  7945. + (const_int 0)))
  7946. + (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
  7947. + (ior:SI (match_dup 1)
  7948. + (match_dup 2)))]
  7949. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  7950. + "@
  7951. + or.4\\t%0, %2, %1
  7952. + or.4\\t%0, %1, %2")
  7953. +
  7954. +(define_insn "iorsi3_ccwzn_null"
  7955. + [(set (reg CC_REGNO)
  7956. + (compare
  7957. + (ior:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
  7958. + (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
  7959. + (const_int 0)))]
  7960. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  7961. + "@
  7962. + or.4\\t#0, %1, %0
  7963. + or.4\\t#0, %0, %1")
  7964. +
  7965. +(define_expand "iordi3"
  7966. + [(parallel
  7967. + [(set (match_operand:DI 0 "nonimmediate_operand" "")
  7968. + (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
  7969. + (match_operand:DI 2 "ubicom32_arith_operand" "")))
  7970. + (clobber (reg:CC CC_REGNO))])]
  7971. + ""
  7972. + "{
  7973. + /* If we have a non-data reg for operand 1 then prefer that over
  7974. + a CONST_INT in operand 2. */
  7975. + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
  7976. + && CONST_INT_P (operands[2]))
  7977. + operands[2] = copy_to_mode_reg (DImode, operands[2]);
  7978. +
  7979. + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
  7980. + operands[2] = copy_to_mode_reg (DImode, operands[2]);
  7981. + }")
  7982. +
  7983. +(define_insn_and_split "iordi3_or4"
  7984. + [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
  7985. + (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
  7986. + (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
  7987. + (clobber (reg:CC CC_REGNO))]
  7988. + ""
  7989. + "#"
  7990. + "reload_completed"
  7991. + [(parallel [(set (match_dup 3)
  7992. + (ior:SI (match_dup 4)
  7993. + (match_dup 5)))
  7994. + (clobber (reg:CC CC_REGNO))])
  7995. + (parallel [(set (match_dup 6)
  7996. + (ior:SI (match_dup 7)
  7997. + (match_dup 8)))
  7998. + (clobber (reg:CC CC_REGNO))])]
  7999. + "{
  8000. + operands[3] = gen_lowpart (SImode, operands[0]);
  8001. + operands[4] = gen_lowpart (SImode, operands[1]);
  8002. + operands[5] = gen_lowpart (SImode, operands[2]);
  8003. + operands[6] = gen_highpart (SImode, operands[0]);
  8004. + operands[7] = gen_highpart (SImode, operands[1]);
  8005. + operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
  8006. + }"
  8007. + [(set_attr "length" "8")])
  8008. +
  8009. +(define_expand "xorqi3"
  8010. + [(parallel
  8011. + [(set (match_operand:QI 0 "memory_operand" "")
  8012. + (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
  8013. + (match_operand:QI 2 "ubicom32_arith_operand" "")))
  8014. + (clobber (reg:CC CC_REGNO))])]
  8015. + "(ubicom32_v4)"
  8016. + "{
  8017. + if (!memory_operand (operands[0], QImode))
  8018. + FAIL;
  8019. +
  8020. + /* If we have a non-data reg for operand 1 then prefer that over
  8021. + a CONST_INT in operand 2. */
  8022. + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
  8023. + && CONST_INT_P (operands[2]))
  8024. + operands[2] = copy_to_mode_reg (QImode, operands[2]);
  8025. +
  8026. + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
  8027. + operands[2] = copy_to_mode_reg (QImode, operands[2]);
  8028. + }")
  8029. +
  8030. +(define_insn "xorqi3_xor1"
  8031. + [(set (match_operand:QI 0 "memory_operand" "=m, m")
  8032. + (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
  8033. + (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
  8034. + (clobber (reg:CC CC_REGNO))]
  8035. + "(ubicom32_v4)"
  8036. + "@
  8037. + xor.1\\t%0, %2, %1
  8038. + xor.1\\t%0, %1, %2")
  8039. +
  8040. +(define_insn "xorqi3_xor1_ccszn"
  8041. + [(set (reg CC_REGNO)
  8042. + (compare
  8043. + (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
  8044. + (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
  8045. + (const_int 0)))
  8046. + (set (match_operand:QI 0 "memory_operand" "=m, m")
  8047. + (xor:QI (match_dup 1)
  8048. + (match_dup 2)))]
  8049. + "(ubicom32_v4
  8050. + && ubicom32_match_cc_mode(insn, CCSZNmode))"
  8051. + "@
  8052. + xor.1\\t%0, %2, %1
  8053. + xor.1\\t%0, %1, %2")
  8054. +
  8055. +(define_insn "xorqi3_xor1_ccszn_null"
  8056. + [(set (reg CC_REGNO)
  8057. + (compare
  8058. + (xor:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
  8059. + (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
  8060. + (const_int 0)))]
  8061. + "(ubicom32_v4
  8062. + && ubicom32_match_cc_mode(insn, CCSZNmode))"
  8063. + "@
  8064. + xor.1\\t#0, %1, %0
  8065. + xor.1\\t#0, %0, %1")
  8066. +
  8067. +(define_insn "xor1_ccszn_null_1"
  8068. + [(set (reg CC_REGNO)
  8069. + (compare
  8070. + (subreg:QI
  8071. + (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
  8072. + (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
  8073. + 3)
  8074. + (const_int 0)))]
  8075. + "(ubicom32_v4
  8076. + && ubicom32_match_cc_mode(insn, CCSZNmode))"
  8077. + "xor.1\\t#0, %1, %0")
  8078. +
  8079. +(define_insn "xor1_ccszn_null_2"
  8080. + [(set (reg CC_REGNO)
  8081. + (compare
  8082. + (subreg:QI
  8083. + (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
  8084. + (subreg:SI
  8085. + (match_operand:QI 1 "memory_operand" "m")
  8086. + 0))
  8087. + 3)
  8088. + (const_int 0)))]
  8089. + "(ubicom32_v4
  8090. + && ubicom32_match_cc_mode(insn, CCSZNmode))"
  8091. + "xor.1\\t#0, %1, %0")
  8092. +
  8093. +(define_insn "xor1_ccwzn_null_3"
  8094. + [(set (reg CC_REGNO)
  8095. + (compare
  8096. + (subreg:QI
  8097. + (xor:SI (subreg:SI
  8098. + (match_operand:QI 0 "memory_operand" "m")
  8099. + 0)
  8100. + (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
  8101. + 3)
  8102. + (const_int 0)))]
  8103. + "(ubicom32_v4
  8104. + && ubicom32_match_cc_mode(insn, CCSZNmode))"
  8105. + "xor.1\\t#0, %0, %1")
  8106. +
  8107. +(define_expand "xorhi3"
  8108. + [(parallel
  8109. + [(set (match_operand:HI 0 "memory_operand" "")
  8110. + (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
  8111. + (match_operand:HI 2 "ubicom32_arith_operand" "")))
  8112. + (clobber (reg:CC CC_REGNO))])]
  8113. + ""
  8114. + "{
  8115. + if (!memory_operand (operands[0], HImode))
  8116. + FAIL;
  8117. +
  8118. + /* If we have a non-data reg for operand 1 then prefer that over
  8119. + a CONST_INT in operand 2. */
  8120. + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
  8121. + && CONST_INT_P (operands[2]))
  8122. + operands[2] = copy_to_mode_reg (HImode, operands[2]);
  8123. +
  8124. + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
  8125. + operands[2] = copy_to_mode_reg (HImode, operands[2]);
  8126. + }")
  8127. +
  8128. +(define_insn "xorhi3_xor2"
  8129. + [(set (match_operand:HI 0 "memory_operand" "=m, m")
  8130. + (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
  8131. + (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
  8132. + (clobber (reg:CC CC_REGNO))]
  8133. + ""
  8134. + "@
  8135. + xor.2\\t%0, %2, %1
  8136. + xor.2\\t%0, %1, %2")
  8137. +
  8138. +(define_insn "xorhi3_xor2_ccszn"
  8139. + [(set (reg CC_REGNO)
  8140. + (compare
  8141. + (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
  8142. + (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
  8143. + (const_int 0)))
  8144. + (set (match_operand:HI 0 "memory_operand" "=m, m")
  8145. + (xor:HI (match_dup 1)
  8146. + (match_dup 2)))]
  8147. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  8148. + "@
  8149. + xor.2\\t%0, %2, %1
  8150. + xor.2\\t%0, %1, %2")
  8151. +
  8152. +(define_insn "xorhi3_xor2_ccszn_null"
  8153. + [(set (reg CC_REGNO)
  8154. + (compare
  8155. + (xor:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
  8156. + (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
  8157. + (const_int 0)))]
  8158. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  8159. + "@
  8160. + xor.2\\t#0, %1, %0
  8161. + xor.2\\t#0, %0, %1")
  8162. +
  8163. +(define_insn "xor2_ccszn_null_1"
  8164. + [(set (reg CC_REGNO)
  8165. + (compare
  8166. + (subreg:HI
  8167. + (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
  8168. + (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
  8169. + 2)
  8170. + (const_int 0)))]
  8171. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  8172. + "xor.2\\t#0, %1, %0")
  8173. +
  8174. +(define_insn "xor2_ccszn_null_2"
  8175. + [(set (reg CC_REGNO)
  8176. + (compare
  8177. + (subreg:HI
  8178. + (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
  8179. + (subreg:SI
  8180. + (match_operand:HI 1 "memory_operand" "m")
  8181. + 0))
  8182. + 2)
  8183. + (const_int 0)))]
  8184. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  8185. + "xor.2\\t#0, %1, %0")
  8186. +
  8187. +(define_insn "xor2_ccszn_null_3"
  8188. + [(set (reg CC_REGNO)
  8189. + (compare
  8190. + (subreg:HI
  8191. + (xor:SI (subreg:SI
  8192. + (match_operand:HI 0 "memory_operand" "m")
  8193. + 0)
  8194. + (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
  8195. + 2)
  8196. + (const_int 0)))]
  8197. + "ubicom32_match_cc_mode(insn, CCSZNmode)"
  8198. + "xor.2\\t#0, %0, %1")
  8199. +
  8200. +(define_insn "xorsi3"
  8201. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
  8202. + (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
  8203. + (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
  8204. + (clobber (reg:CC CC_REGNO))]
  8205. + ""
  8206. + "@
  8207. + xor.4\\t%0, %2, %1
  8208. + xor.4\\t%0, %1, %2")
  8209. +
  8210. +(define_insn "xorsi3_ccwzn"
  8211. + [(set (reg CC_REGNO)
  8212. + (compare
  8213. + (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
  8214. + (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
  8215. + (const_int 0)))
  8216. + (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
  8217. + (xor:SI (match_dup 1)
  8218. + (match_dup 2)))]
  8219. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  8220. + "@
  8221. + xor.4\\t%0, %2, %1
  8222. + xor.4\\t%0, %1, %2")
  8223. +
  8224. +(define_insn "xorsi3_ccwzn_null"
  8225. + [(set (reg CC_REGNO)
  8226. + (compare
  8227. + (xor:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
  8228. + (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
  8229. + (const_int 0)))]
  8230. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  8231. + "@
  8232. + xor.4\\t#0, %1, %0
  8233. + xor.4\\t#0, %0, %1")
  8234. +
  8235. +(define_expand "xordi3"
  8236. + [(parallel
  8237. + [(set (match_operand:DI 0 "nonimmediate_operand" "")
  8238. + (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
  8239. + (match_operand:DI 2 "ubicom32_arith_operand" "")))
  8240. + (clobber (reg:CC CC_REGNO))])]
  8241. + ""
  8242. + "{
  8243. + /* If we have a non-data reg for operand 1 then prefer that over
  8244. + a CONST_INT in operand 2. */
  8245. + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
  8246. + && CONST_INT_P (operands[2]))
  8247. + operands[2] = copy_to_mode_reg (DImode, operands[2]);
  8248. +
  8249. + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
  8250. + operands[2] = copy_to_mode_reg (DImode, operands[2]);
  8251. + }")
  8252. +
  8253. +(define_insn_and_split "xordi3_xor4"
  8254. + [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
  8255. + (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
  8256. + (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
  8257. + (clobber (reg:CC CC_REGNO))]
  8258. + ""
  8259. + "#"
  8260. + "reload_completed"
  8261. + [(parallel [(set (match_dup 3)
  8262. + (xor:SI (match_dup 4)
  8263. + (match_dup 5)))
  8264. + (clobber (reg:CC CC_REGNO))])
  8265. + (parallel [(set (match_dup 6)
  8266. + (xor:SI (match_dup 7)
  8267. + (match_dup 8)))
  8268. + (clobber (reg:CC CC_REGNO))])]
  8269. + "{
  8270. + operands[3] = gen_lowpart (SImode, operands[0]);
  8271. + operands[4] = gen_lowpart (SImode, operands[1]);
  8272. + operands[5] = gen_lowpart (SImode, operands[2]);
  8273. + operands[6] = gen_highpart (SImode, operands[0]);
  8274. + operands[7] = gen_highpart (SImode, operands[1]);
  8275. + operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
  8276. + }"
  8277. + [(set_attr "length" "8")])
  8278. +
  8279. +(define_insn "not2_2"
  8280. + [(set (match_operand:HI 0 "memory_operand" "=m")
  8281. + (subreg:HI
  8282. + (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
  8283. + 2))
  8284. + (clobber (reg:CC CC_REGNO))]
  8285. + ""
  8286. + "not.2\\t%0, %1")
  8287. +
  8288. +(define_insn "one_cmplsi2"
  8289. + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
  8290. + (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))
  8291. + (clobber (reg:CC CC_REGNO))]
  8292. + ""
  8293. + "not.4\\t%0, %1")
  8294. +
  8295. +(define_insn "one_cmplsi2_ccwzn"
  8296. + [(set (reg CC_REGNO)
  8297. + (compare
  8298. + (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
  8299. + (const_int 0)))
  8300. + (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
  8301. + (not:SI (match_dup 1)))]
  8302. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  8303. + "not.4\\t%0, %1")
  8304. +
  8305. +(define_insn "one_cmplsi2_ccwzn_null"
  8306. + [(set (reg CC_REGNO)
  8307. + (compare
  8308. + (not:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI"))
  8309. + (const_int 0)))]
  8310. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  8311. + "not.4\\t#0, %0")
  8312. +
  8313. +(define_insn_and_split "one_cmpldi2"
  8314. + [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
  8315. + (not:DI (match_operand:DI 1 "nonimmediate_operand" "rmI0")))
  8316. + (clobber (reg:CC CC_REGNO))]
  8317. + ""
  8318. + "#"
  8319. + ""
  8320. + [(parallel [(set (match_dup 2)
  8321. + (not:SI (match_dup 3)))
  8322. + (clobber (reg:CC CC_REGNO))])
  8323. + (parallel [(set (match_dup 4)
  8324. + (not:SI (match_dup 5)))
  8325. + (clobber (reg:CC CC_REGNO))])]
  8326. + "{
  8327. + operands[2] = gen_lowpart (SImode, operands[0]);
  8328. + operands[3] = gen_lowpart (SImode, operands[1]);
  8329. + operands[4] = gen_highpart (SImode, operands[0]);
  8330. + operands[5] = gen_highpart (SImode, operands[1]);
  8331. + }"
  8332. + [(set_attr "length" "8")])
  8333. +
  8334. +; Conditional jump instructions
  8335. +
  8336. +(define_expand "beq"
  8337. + [(set (pc)
  8338. + (if_then_else (eq (match_dup 1)
  8339. + (const_int 0))
  8340. + (label_ref (match_operand 0 "" ""))
  8341. + (pc)))]
  8342. + ""
  8343. + "{
  8344. + operands[1] = ubicom32_gen_compare_reg (EQ, ubicom32_compare_op0,
  8345. + ubicom32_compare_op1);
  8346. + }")
  8347. +
  8348. +(define_expand "bne"
  8349. + [(set (pc)
  8350. + (if_then_else (ne (match_dup 1)
  8351. + (const_int 0))
  8352. + (label_ref (match_operand 0 "" ""))
  8353. + (pc)))]
  8354. + ""
  8355. + "{
  8356. + operands[1] = ubicom32_gen_compare_reg (NE, ubicom32_compare_op0,
  8357. + ubicom32_compare_op1);
  8358. + }")
  8359. +
  8360. +(define_expand "bgt"
  8361. + [(set (pc)
  8362. + (if_then_else (gt (match_dup 1)
  8363. + (const_int 0))
  8364. + (label_ref (match_operand 0 "" ""))
  8365. + (pc)))]
  8366. + ""
  8367. + "{
  8368. + operands[1] = ubicom32_gen_compare_reg (GT, ubicom32_compare_op0,
  8369. + ubicom32_compare_op1);
  8370. + }")
  8371. +
  8372. +(define_expand "ble"
  8373. + [(set (pc)
  8374. + (if_then_else (le (match_dup 1)
  8375. + (const_int 0))
  8376. + (label_ref (match_operand 0 "" ""))
  8377. + (pc)))]
  8378. + ""
  8379. + "{
  8380. + operands[1] = ubicom32_gen_compare_reg (LE, ubicom32_compare_op0,
  8381. + ubicom32_compare_op1);
  8382. + }")
  8383. +
  8384. +(define_expand "bge"
  8385. + [(set (pc)
  8386. + (if_then_else (ge (match_dup 1)
  8387. + (const_int 0))
  8388. + (label_ref (match_operand 0 "" ""))
  8389. + (pc)))]
  8390. + ""
  8391. + "{
  8392. + operands[1] = ubicom32_gen_compare_reg (GE, ubicom32_compare_op0,
  8393. + ubicom32_compare_op1);
  8394. + }")
  8395. +
  8396. +(define_expand "blt"
  8397. + [(set (pc)
  8398. + (if_then_else (lt (match_dup 1)
  8399. + (const_int 0))
  8400. + (label_ref (match_operand 0 "" ""))
  8401. + (pc)))]
  8402. + ""
  8403. + "{
  8404. + operands[1] = ubicom32_gen_compare_reg (LT, ubicom32_compare_op0,
  8405. + ubicom32_compare_op1);
  8406. + }")
  8407. +
  8408. +(define_expand "bgtu"
  8409. + [(set (pc)
  8410. + (if_then_else (gtu (match_dup 1)
  8411. + (const_int 0))
  8412. + (label_ref (match_operand 0 "" ""))
  8413. + (pc)))]
  8414. + ""
  8415. + "{
  8416. + operands[1] = ubicom32_gen_compare_reg (GTU, ubicom32_compare_op0,
  8417. + ubicom32_compare_op1);
  8418. + }")
  8419. +
  8420. +(define_expand "bleu"
  8421. + [(set (pc)
  8422. + (if_then_else (leu (match_dup 1)
  8423. + (const_int 0))
  8424. + (label_ref (match_operand 0 "" ""))
  8425. + (pc)))]
  8426. + ""
  8427. + "{
  8428. + operands[1] = ubicom32_gen_compare_reg (LEU, ubicom32_compare_op0,
  8429. + ubicom32_compare_op1);
  8430. + }")
  8431. +
  8432. +(define_expand "bgeu"
  8433. + [(set (pc)
  8434. + (if_then_else (geu (match_dup 1)
  8435. + (const_int 0))
  8436. + (label_ref (match_operand 0 "" ""))
  8437. + (pc)))]
  8438. + ""
  8439. + "{
  8440. + operands[1] = ubicom32_gen_compare_reg (GEU, ubicom32_compare_op0,
  8441. + ubicom32_compare_op1);
  8442. + }")
  8443. +
  8444. +(define_expand "bltu"
  8445. + [(set (pc)
  8446. + (if_then_else (ltu (match_dup 1)
  8447. + (const_int 0))
  8448. + (label_ref (match_operand 0 "" ""))
  8449. + (pc)))]
  8450. + ""
  8451. + "{
  8452. + operands[1] = ubicom32_gen_compare_reg (LTU, ubicom32_compare_op0,
  8453. + ubicom32_compare_op1);
  8454. + }")
  8455. +
  8456. +(define_insn "jcc"
  8457. + [(set (pc)
  8458. + (if_then_else (match_operator 1 "comparison_operator"
  8459. + [(match_operand 2 "ubicom32_cc_register_operand" "")
  8460. + (const_int 0)])
  8461. + (label_ref (match_operand 0 "" ""))
  8462. + (pc)))]
  8463. + ""
  8464. + "*
  8465. + {
  8466. + ubicom32_output_cond_jump (insn, operands[1], operands[0]);
  8467. + return \"\";
  8468. + }")
  8469. +
  8470. +; Reverse branch - reverse our comparison condition so that we can
  8471. +; branch in the opposite sense.
  8472. +;
  8473. +(define_insn_and_split "jcc_reverse"
  8474. + [(set (pc)
  8475. + (if_then_else (match_operator 1 "comparison_operator"
  8476. + [(match_operand 2 "ubicom32_cc_register_operand" "")
  8477. + (const_int 0)])
  8478. + (pc)
  8479. + (label_ref (match_operand 0 "" ""))))]
  8480. + ""
  8481. + "#"
  8482. + "reload_completed"
  8483. + [(set (pc)
  8484. + (if_then_else (match_dup 3)
  8485. + (label_ref (match_dup 0))
  8486. + (pc)))]
  8487. + "{
  8488. + rtx cc_reg;
  8489. +
  8490. + cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
  8491. + operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
  8492. + GET_MODE (operands[1]),
  8493. + cc_reg,
  8494. + const0_rtx);
  8495. + }")
  8496. +
  8497. +(define_insn "jump"
  8498. + [(set (pc)
  8499. + (label_ref (match_operand 0 "" "")))]
  8500. + ""
  8501. + "jmpt\\t%l0")
  8502. +
  8503. +(define_expand "indirect_jump"
  8504. + [(parallel [(set (pc)
  8505. + (match_operand:SI 0 "register_operand" ""))
  8506. + (clobber (match_dup 0))])]
  8507. + ""
  8508. + "")
  8509. +
  8510. +(define_insn "indirect_jump_internal"
  8511. + [(set (pc)
  8512. + (match_operand:SI 0 "register_operand" "a"))
  8513. + (clobber (match_dup 0))]
  8514. + ""
  8515. + "calli\\t%0,0(%0)")
  8516. +
  8517. +; Program Space: The table contains instructions, typically jumps.
  8518. +; CALL An,TABLE_SIZE(PC) ;An = Jump Table Base Address.
  8519. +; <Jump Table is Here> ;An -> Here.
  8520. +; LEA Ak, (An,Dn) ;Ak -> Table Entry
  8521. +; JMP/CALL (Ak)
  8522. +
  8523. +(define_expand "tablejump"
  8524. + [(parallel [(set (pc)
  8525. + (match_operand:SI 0 "nonimmediate_operand" ""))
  8526. + (use (label_ref (match_operand 1 "" "")))])]
  8527. + ""
  8528. + "")
  8529. +
  8530. +(define_insn "tablejump_internal"
  8531. + [(set (pc)
  8532. + (match_operand:SI 0 "nonimmediate_operand" "rm"))
  8533. + (use (label_ref (match_operand 1 "" "")))]
  8534. + ""
  8535. + "ret\\t%0")
  8536. +
  8537. +; Call subroutine with no return value.
  8538. +;
  8539. +(define_expand "call"
  8540. + [(call (match_operand:QI 0 "general_operand" "")
  8541. + (match_operand:SI 1 "general_operand" ""))]
  8542. + ""
  8543. + "{
  8544. + if (TARGET_FDPIC)
  8545. + {
  8546. + ubicom32_expand_call_fdpic (operands);
  8547. + DONE;
  8548. + }
  8549. +
  8550. + if (! ubicom32_call_address_operand (XEXP (operands[0], 0), VOIDmode))
  8551. + XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
  8552. + }")
  8553. +
  8554. +; We expand to a simple form that doesn't clobber the link register and
  8555. +; then split to a form that does. This allows the RTL optimizers that
  8556. +; run before the splitter to have the opportunity to eliminate the call
  8557. +; without marking A5 as being clobbered and this in turn avoids saves
  8558. +; and returns in a number of cases.
  8559. +;
  8560. +(define_insn_and_split "call_1"
  8561. + [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
  8562. + (match_operand:SI 1 "general_operand" "g,g"))]
  8563. + "! TARGET_FDPIC"
  8564. + "#"
  8565. + ""
  8566. + [(parallel
  8567. + [(call (mem:QI (match_dup 0))
  8568. + (match_dup 1))
  8569. + (clobber (reg:SI LINK_REGNO))])]
  8570. + "")
  8571. +
  8572. +(define_insn "call_slow"
  8573. + [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
  8574. + (match_operand:SI 1 "general_operand" "g,g"))
  8575. + (clobber (reg:SI LINK_REGNO))]
  8576. + "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
  8577. + "@
  8578. + calli\\ta5, 0(%0)
  8579. + moveai\\ta5, #%%hi(%C0)\;calli\\ta5, %%lo(%C0)(a5)")
  8580. +
  8581. +(define_insn "call_fast"
  8582. + [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
  8583. + (match_operand:SI 1 "general_operand" "g,g"))
  8584. + (clobber (reg:SI LINK_REGNO))]
  8585. + "(! TARGET_FDPIC && TARGET_FASTCALL)"
  8586. + "@
  8587. + calli\\ta5, 0(%0)
  8588. + call\\ta5, %C0")
  8589. +
  8590. +; We expand to a simple form that doesn't clobber the link register and
  8591. +; then split to a form that does. This allows the RTL optimizers that
  8592. +; run before the splitter to have the opportunity to eliminate the call
  8593. +; without marking A5 as being clobbered and this in turn avoids saves
  8594. +; and returns in a number of cases.
  8595. +;
  8596. +(define_insn_and_split "call_fdpic"
  8597. + [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
  8598. + (match_operand:SI 1 "general_operand" "g,g"))
  8599. + (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))]
  8600. + "TARGET_FDPIC"
  8601. + "#"
  8602. + ""
  8603. + [(parallel
  8604. + [(call (mem:QI (match_dup 0))
  8605. + (match_dup 1))
  8606. + (use (match_dup 2))
  8607. + (clobber (reg:SI LINK_REGNO))])]
  8608. + "")
  8609. +
  8610. +(define_insn "call_fdpic_clobber"
  8611. + [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
  8612. + (match_operand:SI 1 "general_operand" "g,g"))
  8613. + (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))
  8614. + (clobber (reg:SI LINK_REGNO))]
  8615. + "TARGET_FDPIC"
  8616. + "@
  8617. + move.4\\ta5, 0(%0)\;move.4\\t%2, 4(%0)\;calli\\ta5, 0(a5)
  8618. + call\\ta5, %C0")
  8619. +
  8620. +; Call subroutine, returning value in operand 0
  8621. +; (which must be a hard register).
  8622. +;
  8623. +(define_expand "call_value"
  8624. + [(set (match_operand 0 "" "")
  8625. + (call (match_operand:QI 1 "general_operand" "")
  8626. + (match_operand:SI 2 "general_operand" "")))]
  8627. + ""
  8628. + "{
  8629. + if (TARGET_FDPIC)
  8630. + {
  8631. + ubicom32_expand_call_value_fdpic (operands);
  8632. + DONE;
  8633. + }
  8634. +
  8635. + if (! ubicom32_call_address_operand (XEXP (operands[1], 0), VOIDmode))
  8636. + XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
  8637. + }")
  8638. +
  8639. +; We expand to a simple form that doesn't clobber the link register and
  8640. +; then split to a form that does. This allows the RTL optimizers that
  8641. +; run before the splitter to have the opportunity to eliminate the call
  8642. +; without marking A5 as being clobbered and this in turn avoids saves
  8643. +; and returns in a number of cases.
  8644. +;
  8645. +(define_insn_and_split "call_value_1"
  8646. + [(set (match_operand 0 "register_operand" "=r,r")
  8647. + (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
  8648. + (match_operand:SI 2 "general_operand" "g,g")))]
  8649. + "! TARGET_FDPIC"
  8650. + "#"
  8651. + ""
  8652. + [(parallel
  8653. + [(set (match_dup 0)
  8654. + (call (mem:QI (match_dup 1))
  8655. + (match_dup 2)))
  8656. + (clobber (reg:SI LINK_REGNO))])]
  8657. + "")
  8658. +
  8659. +(define_insn "call_value_slow"
  8660. + [(set (match_operand 0 "register_operand" "=r,r")
  8661. + (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
  8662. + (match_operand:SI 2 "general_operand" "g,g")))
  8663. + (clobber (reg:SI LINK_REGNO))]
  8664. + "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
  8665. + "@
  8666. + calli\\ta5, 0(%1)
  8667. + moveai\\ta5, #%%hi(%C1)\;calli\\ta5, %%lo(%C1)(a5)")
  8668. +
  8669. +(define_insn "call_value_fast"
  8670. + [(set (match_operand 0 "register_operand" "=r,r")
  8671. + (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
  8672. + (match_operand:SI 2 "general_operand" "g,g")))
  8673. + (clobber (reg:SI LINK_REGNO))]
  8674. + "(! TARGET_FDPIC && TARGET_FASTCALL)"
  8675. + "@
  8676. + calli\\ta5, 0(%1)
  8677. + call\\ta5, %C1")
  8678. +
  8679. +; We expand to a simple form that doesn't clobber the link register and
  8680. +; then split to a form that does. This allows the RTL optimizers that
  8681. +; run before the splitter to have the opportunity to eliminate the call
  8682. +; without marking A5 as being clobbered and this in turn avoids saves
  8683. +; and returns in a number of cases.
  8684. +;
  8685. +(define_insn_and_split "call_value_fdpic"
  8686. + [(set (match_operand 0 "register_operand" "=r,r")
  8687. + (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
  8688. + (match_operand:SI 2 "general_operand" "g,g")))
  8689. + (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))]
  8690. + "TARGET_FDPIC"
  8691. + "#"
  8692. + ""
  8693. + [(parallel
  8694. + [(set (match_dup 0)
  8695. + (call (mem:QI (match_dup 1))
  8696. + (match_dup 2)))
  8697. + (use (match_dup 3))
  8698. + (clobber (reg:SI LINK_REGNO))])]
  8699. + "")
  8700. +
  8701. +(define_insn "call_value_fdpic_clobber"
  8702. + [(set (match_operand 0 "register_operand" "=r,r")
  8703. + (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
  8704. + (match_operand:SI 2 "general_operand" "g,g")))
  8705. + (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))
  8706. + (clobber (reg:SI LINK_REGNO))]
  8707. + "TARGET_FDPIC"
  8708. + "@
  8709. + move.4\\ta5, 0(%1)\;move.4\\t%3, 4(%1)\;calli\\ta5, 0(a5)
  8710. + call\\ta5, %C1")
  8711. +
  8712. +(define_expand "untyped_call"
  8713. + [(parallel [(call (match_operand 0 "" "")
  8714. + (const_int 0))
  8715. + (match_operand 1 "" "")
  8716. + (match_operand 2 "" "")])]
  8717. + ""
  8718. + "{
  8719. + int i;
  8720. +
  8721. + emit_call_insn (gen_call (operands[0], const0_rtx));
  8722. +
  8723. + for (i = 0; i < XVECLEN (operands[2], 0); i++)
  8724. + {
  8725. + rtx set = XVECEXP (operands[2], 0, i);
  8726. + emit_move_insn (SET_DEST (set), SET_SRC (set));
  8727. + }
  8728. + DONE;
  8729. + }")
  8730. +
  8731. +(define_insn "lsl1_1"
  8732. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8733. + (ashift:SI (subreg:SI
  8734. + (match_operand:QI 1 "memory_operand" "m")
  8735. + 0)
  8736. + (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
  8737. + (clobber (reg:CC CC_REGNO))]
  8738. + "(ubicom32_v4)"
  8739. + "lsl.1\\t%0, %1, %2")
  8740. +
  8741. +; The combiner gets rather creative about left shifts of sub-word memory
  8742. +; operands because it's uncertain about whether the memory is sign or
  8743. +; zero extended. It only wants zero-extended behaviour and so throws
  8744. +; in an extra and operation.
  8745. +;
  8746. +(define_insn "lsl1_2"
  8747. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8748. + (and:SI
  8749. + (ashift:SI (subreg:SI
  8750. + (match_operand:QI 1 "memory_operand" "m")
  8751. + 0)
  8752. + (match_operand:SI 2 "const_int_operand" "M"))
  8753. + (match_operand:SI 3 "const_int_operand" "n")))
  8754. + (clobber (reg:CC CC_REGNO))]
  8755. + "(ubicom32_v4
  8756. + && INTVAL (operands[3]) == (0xff << INTVAL (operands[2])))"
  8757. + "lsl.1\\t%0, %1, %2")
  8758. +
  8759. +(define_insn "lsl2_1"
  8760. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8761. + (ashift:SI (subreg:SI
  8762. + (match_operand:HI 1 "memory_operand" "m")
  8763. + 0)
  8764. + (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
  8765. + (clobber (reg:CC CC_REGNO))]
  8766. + "(ubicom32_v4)"
  8767. + "lsl.2\\t%0, %1, %2")
  8768. +
  8769. +; The combiner gets rather creative about left shifts of sub-word memory
  8770. +; operands because it's uncertain about whether the memory is sign or
  8771. +; zero extended. It only wants zero-extended behaviour and so throws
  8772. +; in an extra and operation.
  8773. +;
  8774. +(define_insn "lsl2_2"
  8775. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8776. + (and:SI
  8777. + (ashift:SI (subreg:SI
  8778. + (match_operand:HI 1 "memory_operand" "m")
  8779. + 0)
  8780. + (match_operand:SI 2 "const_int_operand" "M"))
  8781. + (match_operand:SI 3 "const_int_operand" "n")))
  8782. + (clobber (reg:CC CC_REGNO))]
  8783. + "(ubicom32_v4
  8784. + && INTVAL (operands[3]) == (0xffff << INTVAL (operands[2])))"
  8785. + "lsl.2\\t%0, %1, %2")
  8786. +
  8787. +(define_insn "ashlsi3"
  8788. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8789. + (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
  8790. + (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
  8791. + (clobber (reg:CC CC_REGNO))]
  8792. + ""
  8793. + "lsl.4\\t%0, %1, %2")
  8794. +
  8795. +(define_insn "lshlsi3_ccwz"
  8796. + [(set (reg CC_REGNO)
  8797. + (compare
  8798. + (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
  8799. + (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
  8800. + (const_int 0)))
  8801. + (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8802. + (ashift:SI (match_dup 1)
  8803. + (match_dup 2)))]
  8804. + "ubicom32_match_cc_mode(insn, CCWZmode)"
  8805. + "lsl.4\\t%0, %1, %2")
  8806. +
  8807. +(define_insn "lshlsi3_ccwz_null"
  8808. + [(set (reg CC_REGNO)
  8809. + (compare
  8810. + (ashift:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
  8811. + (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
  8812. + (const_int 0)))
  8813. + (clobber (match_scratch:SI 2 "=d"))]
  8814. + "ubicom32_match_cc_mode(insn, CCWZmode)"
  8815. + "lsl.4\\t%2, %0, %1")
  8816. +
  8817. +; The combiner finds this canonical form for what is in essence a right
  8818. +; shift.
  8819. +;
  8820. +(define_insn "asr1_2"
  8821. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8822. + (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
  8823. + (match_operand:SI 2 "const_int_operand" "M")
  8824. + (match_operand:SI 3 "const_int_operand" "M")))
  8825. + (clobber (reg:CC CC_REGNO))]
  8826. + "(ubicom32_v4
  8827. + && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
  8828. + "asr.1\\t%0, %1, %3")
  8829. +
  8830. +; The combiner finds this canonical form for what is in essence a right
  8831. +; shift.
  8832. +;
  8833. +(define_insn "asr2_2"
  8834. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8835. + (sign_extract:SI (match_operand:HI 1 "memory_operand" "m")
  8836. + (match_operand:SI 2 "const_int_operand" "M")
  8837. + (match_operand:SI 3 "const_int_operand" "M")))
  8838. + (clobber (reg:CC CC_REGNO))]
  8839. + "(ubicom32_v4
  8840. + && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
  8841. + "asr.2\\t%0, %1, %3")
  8842. +
  8843. +(define_insn "ashrsi3"
  8844. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8845. + (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
  8846. + (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
  8847. + (clobber (reg:CC CC_REGNO))]
  8848. + ""
  8849. + "asr.4\\t%0, %1, %2")
  8850. +
  8851. +(define_insn "ashrsi3_ccwzn"
  8852. + [(set (reg CC_REGNO)
  8853. + (compare
  8854. + (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
  8855. + (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
  8856. + (const_int 0)))
  8857. + (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8858. + (ashiftrt:SI (match_dup 1)
  8859. + (match_dup 2)))]
  8860. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  8861. + "asr.4\\t%0, %1, %2")
  8862. +
  8863. +(define_insn "ashrsi3_ccwzn_null"
  8864. + [(set (reg CC_REGNO)
  8865. + (compare
  8866. + (ashiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmJ")
  8867. + (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
  8868. + (const_int 0)))
  8869. + (clobber (match_scratch:SI 2 "=d"))]
  8870. + "ubicom32_match_cc_mode(insn, CCWZNmode)"
  8871. + "asr.4\\t%2, %0, %1")
  8872. +
  8873. +(define_insn "lsr1_1"
  8874. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8875. + (lshiftrt:SI (subreg:SI
  8876. + (match_operand:QI 1 "memory_operand" "m")
  8877. + 0)
  8878. + (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
  8879. + (clobber (reg:CC CC_REGNO))]
  8880. + "(ubicom32_v4)"
  8881. + "lsr.1\\t%0, %1, %2")
  8882. +
  8883. +; The combiner finds this canonical form for what is in essence a right
  8884. +; shift.
  8885. +;
  8886. +(define_insn "lsr1_2"
  8887. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8888. + (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
  8889. + (match_operand:SI 2 "const_int_operand" "M")
  8890. + (match_operand:SI 3 "const_int_operand" "M")))
  8891. + (clobber (reg:CC CC_REGNO))]
  8892. + "(ubicom32_v4
  8893. + && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
  8894. + "lsr.1\\t%0, %1, %3")
  8895. +
  8896. +(define_insn "lsr2_1"
  8897. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8898. + (lshiftrt:SI (subreg:SI
  8899. + (match_operand:HI 1 "memory_operand" "m")
  8900. + 0)
  8901. + (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
  8902. + (clobber (reg:CC CC_REGNO))]
  8903. + "(ubicom32_v4)"
  8904. + "lsr.2\\t%0, %1, %2")
  8905. +
  8906. +; The combiner finds this canonical form for what is in essence a right
  8907. +; shift.
  8908. +;
  8909. +(define_insn "lsr2_2"
  8910. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8911. + (zero_extract:SI (match_operand:HI 1 "memory_operand" "m")
  8912. + (match_operand:SI 2 "const_int_operand" "M")
  8913. + (match_operand:SI 3 "const_int_operand" "M")))
  8914. + (clobber (reg:CC CC_REGNO))]
  8915. + "(ubicom32_v4
  8916. + && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
  8917. + "lsr.2\\t%0, %1, %3")
  8918. +
  8919. +(define_insn "lshrsi3"
  8920. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8921. + (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
  8922. + (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
  8923. + (clobber (reg:CC CC_REGNO))]
  8924. + ""
  8925. + "lsr.4\\t%0, %1, %2")
  8926. +
  8927. +(define_insn "lshrsi3_ccwz"
  8928. + [(set (reg CC_REGNO)
  8929. + (compare
  8930. + (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
  8931. + (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
  8932. + (const_int 0)))
  8933. + (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  8934. + (lshiftrt:SI (match_dup 1)
  8935. + (match_dup 2)))]
  8936. + "ubicom32_match_cc_mode(insn, CCWZmode)"
  8937. + "lsr.4\\t%0, %1, %2")
  8938. +
  8939. +(define_insn "lshrsi3_ccwz_null"
  8940. + [(set (reg CC_REGNO)
  8941. + (compare
  8942. + (lshiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
  8943. + (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
  8944. + (const_int 0)))
  8945. + (clobber (match_scratch:SI 2 "=d"))]
  8946. + "ubicom32_match_cc_mode(insn, CCWZmode)"
  8947. + "lsr.4\\t%2, %0, %1")
  8948. +
  8949. +(define_expand "prologue"
  8950. + [(const_int 0)]
  8951. + ""
  8952. + "{
  8953. + ubicom32_expand_prologue ();
  8954. + DONE;
  8955. + }")
  8956. +
  8957. +(define_expand "epilogue"
  8958. + [(return)]
  8959. + ""
  8960. + "{
  8961. + ubicom32_expand_epilogue ();
  8962. + DONE;
  8963. + }")
  8964. +
  8965. +(define_expand "return"
  8966. + [(return)]
  8967. + ""
  8968. + "{
  8969. + ubicom32_expand_epilogue ();
  8970. + DONE;
  8971. + }")
  8972. +
  8973. +(define_expand "_eh_return"
  8974. + [(use (match_operand:SI 0 "register_operand" "r"))
  8975. + (use (match_operand:SI 1 "register_operand" "r"))]
  8976. + ""
  8977. + "{
  8978. + ubicom32_expand_eh_return (operands);
  8979. + DONE;
  8980. + }")
  8981. +
  8982. +; XXX - it looks almost certain that we could make return_internal use a Dn
  8983. +; register too. In that instance we'd have to use a ret instruction
  8984. +; rather than a calli but it might save cycles.
  8985. +;
  8986. +(define_insn "return_internal"
  8987. + [(const_int 2)
  8988. + (return)
  8989. + (use (match_operand:SI 0 "ubicom32_mem_or_address_register_operand" "rm"))]
  8990. + ""
  8991. + "*
  8992. + {
  8993. + if (REG_P (operands[0]) && REGNO (operands[0]) == LINK_REGNO
  8994. + && ubicom32_can_use_calli_to_ret)
  8995. + return \"calli\\t%0, 0(%0)\";
  8996. +
  8997. + return \"ret\\t%0\";
  8998. + }")
  8999. +
  9000. +(define_insn "return_from_post_modify_sp"
  9001. + [(parallel
  9002. + [(const_int 2)
  9003. + (return)
  9004. + (use (mem:SI (post_modify:SI
  9005. + (reg:SI SP_REGNO)
  9006. + (plus:SI (reg:SI SP_REGNO)
  9007. + (match_operand:SI 0 "const_int_operand" "n")))))])]
  9008. + "INTVAL (operands[0]) >= 4 && INTVAL (operands[0]) <= 7 * 4"
  9009. + "ret\\t(sp)%E0++")
  9010. +
  9011. +;(define_insn "eh_return_internal"
  9012. +; [(const_int 4)
  9013. +; (return)
  9014. +; (use (reg:SI 34))]
  9015. +; ""
  9016. +; "ret\\ta2")
  9017. +
  9018. +; No operation, needed in case the user uses -g but not -O.
  9019. +(define_expand "nop"
  9020. + [(const_int 0)]
  9021. + ""
  9022. + "")
  9023. +
  9024. +(define_insn "nop_internal"
  9025. + [(const_int 0)]
  9026. + ""
  9027. + "nop")
  9028. +
  9029. +; The combiner will generate this pattern given shift and add operations.
  9030. +; The canonical form that the combiner wants to use appears to be multiplies
  9031. +; instead of shifts even if the compiled sources use shifts.
  9032. +;
  9033. +(define_insn "shmrg1_add"
  9034. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  9035. + (plus:SI
  9036. + (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
  9037. + (const_int 256))
  9038. + (zero_extend:SI
  9039. + (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
  9040. + (clobber (reg:CC CC_REGNO))]
  9041. + ""
  9042. + "shmrg.1\\t%0, %2, %1")
  9043. +
  9044. +; The combiner will generate this pattern given shift and or operations.
  9045. +;
  9046. +(define_insn "shmrg1_ior"
  9047. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  9048. + (ior:SI
  9049. + (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
  9050. + (const_int 8))
  9051. + (zero_extend:SI
  9052. + (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
  9053. + (clobber (reg:CC CC_REGNO))]
  9054. + ""
  9055. + "shmrg.1\\t%0, %2, %1")
  9056. +
  9057. +; The combiner will generate this pattern given shift and add operations.
  9058. +; The canonical form that the combiner wants to use appears to be multiplies
  9059. +; instead of shifts even if the compiled sources use shifts.
  9060. +;
  9061. +(define_insn "shmrg2_add"
  9062. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  9063. + (plus:SI
  9064. + (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
  9065. + (const_int 65536))
  9066. + (zero_extend:SI
  9067. + (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
  9068. + (clobber (reg:CC CC_REGNO))]
  9069. + ""
  9070. + "shmrg.2\\t%0, %2, %1")
  9071. +
  9072. +; The combiner will generate this pattern given shift and or operations.
  9073. +;
  9074. +(define_insn "shmrg2_ior"
  9075. + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
  9076. + (ior:SI
  9077. + (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
  9078. + (const_int 16))
  9079. + (zero_extend:SI
  9080. + (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
  9081. + (clobber (reg:CC CC_REGNO))]
  9082. + ""
  9083. + "shmrg.2\\t%0, %2, %1")
  9084. +
  9085. +; Match the case where we load a word from the stack but then discard the
  9086. +; upper 16 bits. We turn this into a zero-extended load of that useful
  9087. +; 16 bits direct from the stack where possible.
  9088. +;
  9089. +
  9090. +; XXX - do these peephole2 ops actually work after the CCmode conversion?
  9091. +(define_peephole2
  9092. + [(set (match_operand:SI 0 "register_operand" "")
  9093. + (mem:SI (plus:SI (reg:SI SP_REGNO)
  9094. + (match_operand:SI 1 "const_int_operand" ""))))
  9095. + (set (match_operand:SI 2 "nonimmediate_operand" "")
  9096. + (zero_extend:SI (match_operand:HI 3 "register_operand" "")))]
  9097. + "(INTVAL (operands[1]) <= 252
  9098. + && REGNO (operands[3]) == REGNO (operands[0])
  9099. + && ((peep2_reg_dead_p (2, operands[0])
  9100. + && ! reg_mentioned_p (operands[0], operands[2]))
  9101. + || rtx_equal_p (operands[0], operands[2])))"
  9102. + [(set (match_dup 2)
  9103. + (zero_extend:SI (mem:HI (plus:SI (reg:SI SP_REGNO)
  9104. + (match_dup 4)))))]
  9105. + "{
  9106. + operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
  9107. + }")
  9108. +
  9109. +; Match the case where we load a word from the stack but then discard the
  9110. +; upper 16 bits. We turn this into a 16-bit load of that useful
  9111. +; 16 bits direct from the stack where possible.
  9112. +;
  9113. +(define_peephole2
  9114. + [(set (match_operand:SI 0 "register_operand" "")
  9115. + (mem:SI (plus:SI (reg:SI SP_REGNO)
  9116. + (match_operand:SI 1 "const_int_operand" ""))))
  9117. + (set (match_operand:HI 2 "nonimmediate_operand" "")
  9118. + (match_operand:HI 3 "register_operand" ""))]
  9119. + "(INTVAL (operands[1]) <= 252
  9120. + && REGNO (operands[3]) == REGNO (operands[0])
  9121. + && ((peep2_reg_dead_p (2, operands[0])
  9122. + && ! reg_mentioned_p (operands[0], operands[2]))
  9123. + || rtx_equal_p (operands[0], operands[2])))"
  9124. + [(set (match_dup 2)
  9125. + (mem:HI (plus:SI (reg:SI SP_REGNO)
  9126. + (match_dup 4))))]
  9127. + "{
  9128. + operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
  9129. + }")
  9130. +
  9131. +; Match the case where we load a word from the stack but then discard the
  9132. +; upper 24 bits. We turn this into a zero-extended load of that useful
  9133. +; 8 bits direct from the stack where possible.
  9134. +;
  9135. +(define_peephole2
  9136. + [(set (match_operand:SI 0 "register_operand" "")
  9137. + (mem:SI (plus:SI (reg:SI SP_REGNO)
  9138. + (match_operand:SI 1 "const_int_operand" ""))))
  9139. + (set (match_operand:SI 2 "nonimmediate_operand" "")
  9140. + (zero_extend:SI (match_operand:QI 3 "register_operand" "")))]
  9141. + "(INTVAL (operands[1]) <= 124
  9142. + && REGNO (operands[3]) == REGNO (operands[0])
  9143. + && ((peep2_reg_dead_p (2, operands[0])
  9144. + && ! reg_mentioned_p (operands[0], operands[2]))
  9145. + || rtx_equal_p (operands[0], operands[2])))"
  9146. + [(set (match_dup 2)
  9147. + (zero_extend:SI (mem:QI (plus:SI (reg:SI SP_REGNO)
  9148. + (match_dup 4)))))]
  9149. + "{
  9150. + operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
  9151. + }")
  9152. +
  9153. +; Match the case where we load a word from the stack but then discard the
  9154. +; upper 24 bits. We turn this into an 8-bit load of that useful
  9155. +; 8 bits direct from the stack where possible.
  9156. +;
  9157. +(define_peephole2
  9158. + [(set (match_operand:SI 0 "register_operand" "")
  9159. + (mem:SI (plus:SI (reg:SI SP_REGNO)
  9160. + (match_operand:SI 1 "const_int_operand" ""))))
  9161. + (set (match_operand:QI 2 "nonimmediate_operand" "")
  9162. + (match_operand:QI 3 "register_operand" ""))]
  9163. + "(INTVAL (operands[1]) <= 124
  9164. + && REGNO (operands[3]) == REGNO (operands[0])
  9165. + && ((peep2_reg_dead_p (2, operands[0])
  9166. + && ! reg_mentioned_p (operands[0], operands[2]))
  9167. + || rtx_equal_p (operands[0], operands[2])))"
  9168. + [(set (match_dup 2)
  9169. + (mem:QI (plus:SI (reg:SI SP_REGNO)
  9170. + (match_dup 4))))]
  9171. + "{
  9172. + operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
  9173. + }")
  9174. +
  9175. --- /dev/null
  9176. +++ b/gcc/config/ubicom32/ubicom32.opt
  9177. @@ -0,0 +1,27 @@
  9178. +mdebug-address
  9179. +Target RejectNegative Report Undocumented Mask(DEBUG_ADDRESS)
  9180. +Debug addresses
  9181. +
  9182. +mdebug-context
  9183. +Target RejectNegative Report Undocumented Mask(DEBUG_CONTEXT)
  9184. +Debug contexts
  9185. +
  9186. +march=
  9187. +Target Report Var(ubicom32_arch_name) Init("ubicom32v4") Joined
  9188. +Specify the name of the target architecture
  9189. +
  9190. +mfdpic
  9191. +Target Report Mask(FDPIC)
  9192. +Enable Function Descriptor PIC mode
  9193. +
  9194. +minline-plt
  9195. +Target Report Mask(INLINE_PLT)
  9196. +Enable inlining of PLT in function calls
  9197. +
  9198. +mfastcall
  9199. +Target Report Mask(FASTCALL)
  9200. +Enable default fast (call) calling sequence for smaller applications
  9201. +
  9202. +mipos-abi
  9203. +Target Report Mask(IPOS_ABI)
  9204. +Enable the ipOS ABI in which D10-D13 are caller-clobbered
  9205. --- /dev/null
  9206. +++ b/gcc/config/ubicom32/uclinux.h
  9207. @@ -0,0 +1,67 @@
  9208. +/* Definitions of target machine for Ubicom32-uclinux
  9209. +
  9210. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
  9211. + 2009 Free Software Foundation, Inc.
  9212. + Contributed by Ubicom, Inc.
  9213. +
  9214. + This file is part of GCC.
  9215. +
  9216. + GCC is free software; you can redistribute it and/or modify it
  9217. + under the terms of the GNU General Public License as published
  9218. + by the Free Software Foundation; either version 3, or (at your
  9219. + option) any later version.
  9220. +
  9221. + GCC is distributed in the hope that it will be useful, but WITHOUT
  9222. + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  9223. + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  9224. + License for more details.
  9225. +
  9226. + You should have received a copy of the GNU General Public License
  9227. + along with GCC; see the file COPYING3. If not see
  9228. + <http://www.gnu.org/licenses/>. */
  9229. +
  9230. +/* Don't assume anything about the header files. */
  9231. +#define NO_IMPLICIT_EXTERN_C
  9232. +
  9233. +#undef LIB_SPEC
  9234. +#define LIB_SPEC \
  9235. + "%{pthread:-lpthread} " \
  9236. + "%{!shared:%{!symbolic: -lc}} "
  9237. +
  9238. +
  9239. +#undef LINK_GCC_C_SEQUENCE_SPEC
  9240. +#define LINK_GCC_C_SEQUENCE_SPEC \
  9241. + "%{!shared:--start-group} %G %L %{!shared:--end-group}%{shared:%G} "
  9242. +
  9243. +#undef STARTFILE_SPEC
  9244. +#define STARTFILE_SPEC \
  9245. + "%{!shared: crt1%O%s}" \
  9246. + " crti%O%s crtbegin%O%s"
  9247. +
  9248. +#undef ENDFILE_SPEC
  9249. +#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
  9250. +
  9251. +/* This macro applies on top of OBJECT_FORMAT_ELF and indicates that
  9252. + we want to support both flat and ELF output. */
  9253. +#define OBJECT_FORMAT_FLAT
  9254. +
  9255. +#undef DRIVER_SELF_SPECS
  9256. +#define DRIVER_SELF_SPECS \
  9257. + "%{!mno-fastcall:-mfastcall}"
  9258. +
  9259. +/* taken from linux.h */
  9260. +/* The GNU C++ standard library requires that these macros be defined. */
  9261. +#undef CPLUSPLUS_CPP_SPEC
  9262. +#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
  9263. +
  9264. +#define TARGET_OS_CPP_BUILTINS() \
  9265. + do { \
  9266. + builtin_define_std ("__UBICOM32__"); \
  9267. + builtin_define_std ("__ubicom32__"); \
  9268. + builtin_define ("__gnu_linux__"); \
  9269. + builtin_define_std ("linux"); \
  9270. + builtin_define_std ("unix"); \
  9271. + builtin_assert ("system=linux"); \
  9272. + builtin_assert ("system=unix"); \
  9273. + builtin_assert ("system=posix"); \
  9274. + } while (0)
  9275. --- /dev/null
  9276. +++ b/gcc/config/ubicom32/xm-ubicom32.h
  9277. @@ -0,0 +1,36 @@
  9278. +/* Configuration for Ubicom's Ubicom32 architecture.
  9279. + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
  9280. + Foundation, Inc.
  9281. + Contributed by Ubicom Inc.
  9282. +
  9283. +This file is part of GNU CC.
  9284. +
  9285. +GNU CC is free software; you can redistribute it and/or modify
  9286. +it under the terms of the GNU General Public License as published by
  9287. +the Free Software Foundation; either version 2, or (at your option)
  9288. +any later version.
  9289. +
  9290. +GNU CC is distributed in the hope that it will be useful,
  9291. +but WITHOUT ANY WARRANTY; without even the implied warranty of
  9292. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9293. +GNU General Public License for more details.
  9294. +
  9295. +You should have received a copy of the GNU General Public License
  9296. +along with GNU CC; see the file COPYING. If not, write to
  9297. +the Free Software Foundation, 59 Temple Place - Suite 330,
  9298. +Boston, MA 02111-1307, USA. */
  9299. +
  9300. +/* #defines that need visibility everywhere. */
  9301. +#define FALSE 0
  9302. +#define TRUE 1
  9303. +
  9304. +/* This describes the machine the compiler is hosted on. */
  9305. +#define HOST_BITS_PER_CHAR 8
  9306. +#define HOST_BITS_PER_SHORT 16
  9307. +#define HOST_BITS_PER_INT 32
  9308. +#define HOST_BITS_PER_LONG 32
  9309. +#define HOST_BITS_PER_LONGLONG 64
  9310. +
  9311. +/* Arguments to use with `exit'. */
  9312. +#define SUCCESS_EXIT_CODE 0
  9313. +#define FATAL_EXIT_CODE 33
  9314. --- a/gcc/config.gcc
  9315. +++ b/gcc/config.gcc
  9316. @@ -2503,6 +2503,34 @@ tilepro-*-linux*)
  9317. c_target_objs="tilepro-c.o"
  9318. cxx_target_objs="tilepro-c.o"
  9319. ;;
  9320. +ubicom32-*-elf)
  9321. + xm_file=ubicom32/xm-ubicom32.h
  9322. + tm_file="${tm_file} ubicom32/elf.h" # still need dbxelf.h elfos.h
  9323. + tmake_file=ubicom32/t-ubicom32
  9324. + ;;
  9325. +ubicom32-*-uclinux*)
  9326. + xm_file=ubicom32/xm-ubicom32.h
  9327. + tm_file="${tm_file} ubicom32/elf.h ubicom32/uclinux.h" # still need dbxelf.h elfos.h linux.h
  9328. + tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
  9329. + extra_options="${extra_options} linux.opt"
  9330. + tmake_file=ubicom32/t-ubicom32-uclinux
  9331. + use_collect2=no
  9332. + ;;
  9333. +ubicom32-*-linux-uclibc)
  9334. + xm_file=ubicom32/xm-ubicom32.h
  9335. + tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
  9336. + tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
  9337. + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
  9338. + use_collect2=no
  9339. + ;;
  9340. +ubicom32-*-linux*)
  9341. + xm_file=ubicom32/xm-ubicom32.h
  9342. + tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
  9343. + tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
  9344. + tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
  9345. + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
  9346. + use_collect2=no
  9347. + ;;
  9348. v850*-*-*)
  9349. case ${target} in
  9350. v850e2v3-*-*)
  9351. --- a/libgcc/config.host
  9352. +++ b/libgcc/config.host
  9353. @@ -1098,6 +1098,15 @@ tilepro-*-linux*)
  9354. tmake_file="${tmake_file} tilepro/t-crtstuff t-softfp-sfdf t-softfp tilepro/t-tilepro"
  9355. md_unwind_header=tilepro/linux-unwind.h
  9356. ;;
  9357. +ubicom32*-*-elf*)
  9358. + ;;
  9359. +ubicom32*-*-uclinux*)
  9360. + ;;
  9361. +ubicom32*-*-linux*)
  9362. + # No need to build crtbeginT.o on uClibc systems. Should probably
  9363. + # be moved to the OS specific section above.
  9364. + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
  9365. + ;;
  9366. v850*-*-*)
  9367. tmake_file="v850/t-v850 t-fdpbit"
  9368. ;;