900-nios2.patch 407 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377
  1. diff --git a/config.sub b/config.sub
  2. index d2e3557..2297c30 100755
  3. --- a/config.sub
  4. +++ b/config.sub
  5. @@ -276,6 +276,15 @@ case $basic_machine in
  6. basic_machine=$basic_machine-unknown
  7. os=-none
  8. ;;
  9. + # JBG
  10. + nios2 | nios2-* | nios2el | nios2el-*)
  11. + basic_machine=nios2-altera
  12. + os=-none_el
  13. + ;;
  14. + nios2eb | nios2eb-*)
  15. + basic_machine=nios2-altera
  16. + os=-none_eb
  17. + ;;
  18. m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
  19. ;;
  20. diff --git a/gcc/combine.c b/gcc/combine.c
  21. index 8f43c23..02648b1 100644
  22. --- a/gcc/combine.c
  23. +++ b/gcc/combine.c
  24. @@ -4381,6 +4381,14 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int last,
  25. mode);
  26. }
  27. +#ifndef __nios2__
  28. +/* This screws up Nios II in this test case:
  29. +
  30. +if (x & 1)
  31. + return 2;
  32. +else
  33. + return 3;
  34. +*/
  35. else if (STORE_FLAG_VALUE == 1
  36. && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
  37. && op1 == const0_rtx
  38. @@ -4392,6 +4400,7 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int last,
  39. gen_lowpart_for_combine (mode, op0),
  40. const1_rtx);
  41. }
  42. +#endif
  43. else if (STORE_FLAG_VALUE == 1
  44. && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
  45. diff --git a/gcc/config.gcc b/gcc/config.gcc
  46. index d22f34b..4ecb6e9 100644
  47. --- a/gcc/config.gcc
  48. +++ b/gcc/config.gcc
  49. @@ -1337,6 +1337,17 @@ m32rle-*-linux*)
  50. thread_file='posix'
  51. fi
  52. ;;
  53. +# JBG
  54. +nios2-*-elf*_eb)
  55. + tm_file="elfos.h nios2/big.h ${tm_file}"
  56. + ;;
  57. +nios2-*-elf*)
  58. + tm_file="elfos.h ${tm_file}"
  59. + ;;
  60. +nios2-*-uclibc*) # Altera Nios2 running uClinux with uClibc
  61. + tm_file="elfos.h ${tm_file} nios2/nios2-uclibc.h"
  62. + tmake_file=nios2/t-nios2-uclibc
  63. + ;;
  64. # m68hc11 and m68hc12 share the same machine description.
  65. m68hc11-*-*|m6811-*-*)
  66. tm_file="dbxelf.h elfos.h m68hc11/m68hc11.h"
  67. diff --git a/gcc/config/nios2/big.h b/gcc/config/nios2/big.h
  68. new file mode 100644
  69. index 0000000..b7b1731
  70. --- /dev/null
  71. +++ b/gcc/config/nios2/big.h
  72. @@ -0,0 +1,23 @@
  73. +/*
  74. + big.h - Additional definitions for nios2 targets that default to big-endian
  75. +
  76. + Copyright (C) 2006 Altera
  77. +
  78. +This file is part of GNU CC.
  79. +
  80. +GNU CC is free software; you can redistribute it and/or modify
  81. +it under the terms of the GNU General Public License as published by
  82. +the Free Software Foundation; either version 2, or (at your option)
  83. +any later version.
  84. +
  85. +GNU CC is distributed in the hope that it will be useful,
  86. +but WITHOUT ANY WARRANTY; without even the implied warranty of
  87. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  88. +GNU General Public License for more details.
  89. +
  90. +You should have received a copy of the GNU General Public License
  91. +along with GNU CC; see the file COPYING. If not, write to
  92. +the Free Software Foundation, 59 Temple Place - Suite 330,
  93. +Boston, MA 02111-1307, USA. */
  94. +
  95. +#define TARGET_ENDIAN_DEFAULT BIG_ENDIAN_FLAG
  96. diff --git a/gcc/config/nios2/crti.asm b/gcc/config/nios2/crti.asm
  97. new file mode 100644
  98. index 0000000..1fcfeb2
  99. --- /dev/null
  100. +++ b/gcc/config/nios2/crti.asm
  101. @@ -0,0 +1,88 @@
  102. +/*
  103. + Copyright (C) 2003
  104. + by Jonah Graham (jgraham@altera.com)
  105. +
  106. +This file is free software; you can redistribute it and/or modify it
  107. +under the terms of the GNU General Public License as published by the
  108. +Free Software Foundation; either version 2, or (at your option) any
  109. +later version.
  110. +
  111. +In addition to the permissions in the GNU General Public License, the
  112. +Free Software Foundation gives you unlimited permission to link the
  113. +compiled version of this file with other programs, and to distribute
  114. +those programs without any restriction coming from the use of this
  115. +file. (The General Public License restrictions do apply in other
  116. +respects; for example, they cover modification of the file, and
  117. +distribution when not linked into another program.)
  118. +
  119. +This file is distributed in the hope that it will be useful, but
  120. +WITHOUT ANY WARRANTY; without even the implied warranty of
  121. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  122. +General Public License for more details.
  123. +
  124. +You should have received a copy of the GNU General Public License
  125. +along with this program; see the file COPYING. If not, write to
  126. +the Free Software Foundation, 59 Temple Place - Suite 330,
  127. +Boston, MA 02111-1307, USA.
  128. +
  129. + As a special exception, if you link this library with files
  130. + compiled with GCC to produce an executable, this does not cause
  131. + the resulting executable to be covered by the GNU General Public License.
  132. + This exception does not however invalidate any other reasons why
  133. + the executable file might be covered by the GNU General Public License.
  134. +
  135. +
  136. +This file just make a stack frame for the contents of the .fini and
  137. +.init sections. Users may put any desired instructions in those
  138. +sections.
  139. +
  140. +
  141. +While technically any code can be put in the init and fini sections
  142. +most stuff will not work other than stuff which obeys the call frame
  143. +and ABI. All the call-preserved registers are saved, the call clobbered
  144. +registers should have been saved by the code calling init and fini.
  145. +
  146. +See crtstuff.c for an example of code that inserts itself in the
  147. +init and fini sections.
  148. +
  149. +See crt0.s for the code that calls init and fini.
  150. +*/
  151. +
  152. + .file "crti.asm"
  153. +
  154. + .section ".init"
  155. + .align 2
  156. + .global _init
  157. +_init:
  158. + addi sp, sp, -48
  159. + stw ra, 44(sp)
  160. + stw r23, 40(sp)
  161. + stw r22, 36(sp)
  162. + stw r21, 32(sp)
  163. + stw r20, 28(sp)
  164. + stw r19, 24(sp)
  165. + stw r18, 20(sp)
  166. + stw r17, 16(sp)
  167. + stw r16, 12(sp)
  168. + stw fp, 8(sp)
  169. + mov fp, sp
  170. +
  171. +
  172. + .section ".fini"
  173. + .align 2
  174. + .global _fini
  175. +_fini:
  176. + addi sp, sp, -48
  177. + stw ra, 44(sp)
  178. + stw r23, 40(sp)
  179. + stw r22, 36(sp)
  180. + stw r21, 32(sp)
  181. + stw r20, 28(sp)
  182. + stw r19, 24(sp)
  183. + stw r18, 20(sp)
  184. + stw r17, 16(sp)
  185. + stw r16, 12(sp)
  186. + stw fp, 8(sp)
  187. + mov fp, sp
  188. +
  189. +
  190. diff --git a/gcc/config/nios2/crtn.asm b/gcc/config/nios2/crtn.asm
  191. new file mode 100644
  192. index 0000000..e337480
  193. --- /dev/null
  194. +++ b/gcc/config/nios2/crtn.asm
  195. @@ -0,0 +1,70 @@
  196. +/*
  197. + Copyright (C) 2003
  198. + by Jonah Graham (jgraham@altera.com)
  199. +
  200. +This file is free software; you can redistribute it and/or modify it
  201. +under the terms of the GNU General Public License as published by the
  202. +Free Software Foundation; either version 2, or (at your option) any
  203. +later version.
  204. +
  205. +In addition to the permissions in the GNU General Public License, the
  206. +Free Software Foundation gives you unlimited permission to link the
  207. +compiled version of this file with other programs, and to distribute
  208. +those programs without any restriction coming from the use of this
  209. +file. (The General Public License restrictions do apply in other
  210. +respects; for example, they cover modification of the file, and
  211. +distribution when not linked into another program.)
  212. +
  213. +This file is distributed in the hope that it will be useful, but
  214. +WITHOUT ANY WARRANTY; without even the implied warranty of
  215. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  216. +General Public License for more details.
  217. +
  218. +You should have received a copy of the GNU General Public License
  219. +along with this program; see the file COPYING. If not, write to
  220. +the Free Software Foundation, 59 Temple Place - Suite 330,
  221. +Boston, MA 02111-1307, USA.
  222. +
  223. + As a special exception, if you link this library with files
  224. + compiled with GCC to produce an executable, this does not cause
  225. + the resulting executable to be covered by the GNU General Public License.
  226. + This exception does not however invalidate any other reasons why
  227. + the executable file might be covered by the GNU General Public License.
  228. +
  229. +
  230. +This file just makes sure that the .fini and .init sections do in
  231. +fact return. Users may put any desired instructions in those sections.
  232. +This file is the last thing linked into any executable.
  233. +*/
  234. + .file "crtn.asm"
  235. +
  236. +
  237. +
  238. + .section ".init"
  239. + ldw ra, 44(sp)
  240. + ldw r23, 40(sp)
  241. + ldw r22, 36(sp)
  242. + ldw r21, 32(sp)
  243. + ldw r20, 28(sp)
  244. + ldw r19, 24(sp)
  245. + ldw r18, 20(sp)
  246. + ldw r17, 16(sp)
  247. + ldw r16, 12(sp)
  248. + ldw fp, 8(sp)
  249. + addi sp, sp, -48
  250. + ret
  251. +
  252. + .section ".fini"
  253. + ldw ra, 44(sp)
  254. + ldw r23, 40(sp)
  255. + ldw r22, 36(sp)
  256. + ldw r21, 32(sp)
  257. + ldw r20, 28(sp)
  258. + ldw r19, 24(sp)
  259. + ldw r18, 20(sp)
  260. + ldw r17, 16(sp)
  261. + ldw r16, 12(sp)
  262. + ldw fp, 8(sp)
  263. + addi sp, sp, -48
  264. + ret
  265. +
  266. diff --git a/gcc/config/nios2/lib2-divmod-hi.c b/gcc/config/nios2/lib2-divmod-hi.c
  267. new file mode 100644
  268. index 0000000..10bd6e4
  269. --- /dev/null
  270. +++ b/gcc/config/nios2/lib2-divmod-hi.c
  271. @@ -0,0 +1,123 @@
  272. +
  273. +/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
  274. + supposedly valid even though this is a "target" file. */
  275. +#include "auto-host.h"
  276. +
  277. +
  278. +#include "tconfig.h"
  279. +#include "tsystem.h"
  280. +#include "coretypes.h"
  281. +#include "tm.h"
  282. +
  283. +
  284. +/* Don't use `fancy_abort' here even if config.h says to use it. */
  285. +#ifdef abort
  286. +#undef abort
  287. +#endif
  288. +
  289. +
  290. +#ifdef HAVE_GAS_HIDDEN
  291. +#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
  292. +#else
  293. +#define ATTRIBUTE_HIDDEN
  294. +#endif
  295. +
  296. +#include "libgcc2.h"
  297. +
  298. +extern HItype __modhi3 (HItype, HItype);
  299. +extern HItype __divhi3 (HItype, HItype);
  300. +extern HItype __umodhi3 (HItype, HItype);
  301. +extern HItype __udivhi3 (HItype, HItype);
  302. +
  303. +static UHItype udivmodhi4(UHItype, UHItype, word_type);
  304. +
  305. +static UHItype
  306. +udivmodhi4(UHItype num, UHItype den, word_type modwanted)
  307. +{
  308. + UHItype bit = 1;
  309. + UHItype res = 0;
  310. +
  311. + while (den < num && bit && !(den & (1L<<15)))
  312. + {
  313. + den <<=1;
  314. + bit <<=1;
  315. + }
  316. + while (bit)
  317. + {
  318. + if (num >= den)
  319. + {
  320. + num -= den;
  321. + res |= bit;
  322. + }
  323. + bit >>=1;
  324. + den >>=1;
  325. + }
  326. + if (modwanted) return num;
  327. + return res;
  328. +}
  329. +
  330. +
  331. +HItype
  332. +__divhi3 (HItype a, HItype b)
  333. +{
  334. + word_type neg = 0;
  335. + HItype res;
  336. +
  337. + if (a < 0)
  338. + {
  339. + a = -a;
  340. + neg = !neg;
  341. + }
  342. +
  343. + if (b < 0)
  344. + {
  345. + b = -b;
  346. + neg = !neg;
  347. + }
  348. +
  349. + res = udivmodhi4 (a, b, 0);
  350. +
  351. + if (neg)
  352. + res = -res;
  353. +
  354. + return res;
  355. +}
  356. +
  357. +
  358. +HItype
  359. +__modhi3 (HItype a, HItype b)
  360. +{
  361. + word_type neg = 0;
  362. + HItype res;
  363. +
  364. + if (a < 0)
  365. + {
  366. + a = -a;
  367. + neg = 1;
  368. + }
  369. +
  370. + if (b < 0)
  371. + b = -b;
  372. +
  373. + res = udivmodhi4 (a, b, 1);
  374. +
  375. + if (neg)
  376. + res = -res;
  377. +
  378. + return res;
  379. +}
  380. +
  381. +
  382. +HItype
  383. +__udivhi3 (HItype a, HItype b)
  384. +{
  385. + return udivmodhi4 (a, b, 0);
  386. +}
  387. +
  388. +
  389. +HItype
  390. +__umodhi3 (HItype a, HItype b)
  391. +{
  392. + return udivmodhi4 (a, b, 1);
  393. +}
  394. +
  395. diff --git a/gcc/config/nios2/lib2-divmod.c b/gcc/config/nios2/lib2-divmod.c
  396. new file mode 100644
  397. index 0000000..00e730d
  398. --- /dev/null
  399. +++ b/gcc/config/nios2/lib2-divmod.c
  400. @@ -0,0 +1,126 @@
  401. +
  402. +/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
  403. + supposedly valid even though this is a "target" file. */
  404. +#include "auto-host.h"
  405. +
  406. +
  407. +#include "tconfig.h"
  408. +#include "tsystem.h"
  409. +#include "coretypes.h"
  410. +#include "tm.h"
  411. +
  412. +
  413. +/* Don't use `fancy_abort' here even if config.h says to use it. */
  414. +#ifdef abort
  415. +#undef abort
  416. +#endif
  417. +
  418. +
  419. +#ifdef HAVE_GAS_HIDDEN
  420. +#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
  421. +#else
  422. +#define ATTRIBUTE_HIDDEN
  423. +#endif
  424. +
  425. +#include "libgcc2.h"
  426. +
  427. +extern SItype __modsi3 (SItype, SItype);
  428. +extern SItype __divsi3 (SItype, SItype);
  429. +extern SItype __umodsi3 (SItype, SItype);
  430. +extern SItype __udivsi3 (SItype, SItype);
  431. +
  432. +static USItype udivmodsi4(USItype, USItype, word_type);
  433. +
  434. +/* 16-bit SI divide and modulo as used in NIOS */
  435. +
  436. +
  437. +static USItype
  438. +udivmodsi4(USItype num, USItype den, word_type modwanted)
  439. +{
  440. + USItype bit = 1;
  441. + USItype res = 0;
  442. +
  443. + while (den < num && bit && !(den & (1L<<31)))
  444. + {
  445. + den <<=1;
  446. + bit <<=1;
  447. + }
  448. + while (bit)
  449. + {
  450. + if (num >= den)
  451. + {
  452. + num -= den;
  453. + res |= bit;
  454. + }
  455. + bit >>=1;
  456. + den >>=1;
  457. + }
  458. + if (modwanted) return num;
  459. + return res;
  460. +}
  461. +
  462. +
  463. +SItype
  464. +__divsi3 (SItype a, SItype b)
  465. +{
  466. + word_type neg = 0;
  467. + SItype res;
  468. +
  469. + if (a < 0)
  470. + {
  471. + a = -a;
  472. + neg = !neg;
  473. + }
  474. +
  475. + if (b < 0)
  476. + {
  477. + b = -b;
  478. + neg = !neg;
  479. + }
  480. +
  481. + res = udivmodsi4 (a, b, 0);
  482. +
  483. + if (neg)
  484. + res = -res;
  485. +
  486. + return res;
  487. +}
  488. +
  489. +
  490. +SItype
  491. +__modsi3 (SItype a, SItype b)
  492. +{
  493. + word_type neg = 0;
  494. + SItype res;
  495. +
  496. + if (a < 0)
  497. + {
  498. + a = -a;
  499. + neg = 1;
  500. + }
  501. +
  502. + if (b < 0)
  503. + b = -b;
  504. +
  505. + res = udivmodsi4 (a, b, 1);
  506. +
  507. + if (neg)
  508. + res = -res;
  509. +
  510. + return res;
  511. +}
  512. +
  513. +
  514. +SItype
  515. +__udivsi3 (SItype a, SItype b)
  516. +{
  517. + return udivmodsi4 (a, b, 0);
  518. +}
  519. +
  520. +
  521. +SItype
  522. +__umodsi3 (SItype a, SItype b)
  523. +{
  524. + return udivmodsi4 (a, b, 1);
  525. +}
  526. +
  527. diff --git a/gcc/config/nios2/lib2-divtable.c b/gcc/config/nios2/lib2-divtable.c
  528. new file mode 100644
  529. index 0000000..48a7bd7
  530. --- /dev/null
  531. +++ b/gcc/config/nios2/lib2-divtable.c
  532. @@ -0,0 +1,46 @@
  533. +
  534. +/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
  535. + supposedly valid even though this is a "target" file. */
  536. +#include "auto-host.h"
  537. +
  538. +
  539. +#include "tconfig.h"
  540. +#include "tsystem.h"
  541. +#include "coretypes.h"
  542. +#include "tm.h"
  543. +
  544. +
  545. +/* Don't use `fancy_abort' here even if config.h says to use it. */
  546. +#ifdef abort
  547. +#undef abort
  548. +#endif
  549. +
  550. +
  551. +#ifdef HAVE_GAS_HIDDEN
  552. +#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
  553. +#else
  554. +#define ATTRIBUTE_HIDDEN
  555. +#endif
  556. +
  557. +#include "libgcc2.h"
  558. +
  559. +UQItype __divsi3_table[] =
  560. +{
  561. + 0, 0/1, 0/2, 0/3, 0/4, 0/5, 0/6, 0/7, 0/8, 0/9, 0/10, 0/11, 0/12, 0/13, 0/14, 0/15,
  562. + 0, 1/1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13, 1/14, 1/15,
  563. + 0, 2/1, 2/2, 2/3, 2/4, 2/5, 2/6, 2/7, 2/8, 2/9, 2/10, 2/11, 2/12, 2/13, 2/14, 2/15,
  564. + 0, 3/1, 3/2, 3/3, 3/4, 3/5, 3/6, 3/7, 3/8, 3/9, 3/10, 3/11, 3/12, 3/13, 3/14, 3/15,
  565. + 0, 4/1, 4/2, 4/3, 4/4, 4/5, 4/6, 4/7, 4/8, 4/9, 4/10, 4/11, 4/12, 4/13, 4/14, 4/15,
  566. + 0, 5/1, 5/2, 5/3, 5/4, 5/5, 5/6, 5/7, 5/8, 5/9, 5/10, 5/11, 5/12, 5/13, 5/14, 5/15,
  567. + 0, 6/1, 6/2, 6/3, 6/4, 6/5, 6/6, 6/7, 6/8, 6/9, 6/10, 6/11, 6/12, 6/13, 6/14, 6/15,
  568. + 0, 7/1, 7/2, 7/3, 7/4, 7/5, 7/6, 7/7, 7/8, 7/9, 7/10, 7/11, 7/12, 7/13, 7/14, 7/15,
  569. + 0, 8/1, 8/2, 8/3, 8/4, 8/5, 8/6, 8/7, 8/8, 8/9, 8/10, 8/11, 8/12, 8/13, 8/14, 8/15,
  570. + 0, 9/1, 9/2, 9/3, 9/4, 9/5, 9/6, 9/7, 9/8, 9/9, 9/10, 9/11, 9/12, 9/13, 9/14, 9/15,
  571. + 0, 10/1, 10/2, 10/3, 10/4, 10/5, 10/6, 10/7, 10/8, 10/9, 10/10, 10/11, 10/12, 10/13, 10/14, 10/15,
  572. + 0, 11/1, 11/2, 11/3, 11/4, 11/5, 11/6, 11/7, 11/8, 11/9, 11/10, 11/11, 11/12, 11/13, 11/14, 11/15,
  573. + 0, 12/1, 12/2, 12/3, 12/4, 12/5, 12/6, 12/7, 12/8, 12/9, 12/10, 12/11, 12/12, 12/13, 12/14, 12/15,
  574. + 0, 13/1, 13/2, 13/3, 13/4, 13/5, 13/6, 13/7, 13/8, 13/9, 13/10, 13/11, 13/12, 13/13, 13/14, 13/15,
  575. + 0, 14/1, 14/2, 14/3, 14/4, 14/5, 14/6, 14/7, 14/8, 14/9, 14/10, 14/11, 14/12, 14/13, 14/14, 14/15,
  576. + 0, 15/1, 15/2, 15/3, 15/4, 15/5, 15/6, 15/7, 15/8, 15/9, 15/10, 15/11, 15/12, 15/13, 15/14, 15/15,
  577. +};
  578. +
  579. diff --git a/gcc/config/nios2/lib2-mul.c b/gcc/config/nios2/lib2-mul.c
  580. new file mode 100644
  581. index 0000000..8511b33
  582. --- /dev/null
  583. +++ b/gcc/config/nios2/lib2-mul.c
  584. @@ -0,0 +1,103 @@
  585. +/* while we are debugging (ie compile outside of gcc build)
  586. + disable gcc specific headers */
  587. +#ifndef DEBUG_MULSI3
  588. +
  589. +
  590. +/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
  591. + supposedly valid even though this is a "target" file. */
  592. +#include "auto-host.h"
  593. +
  594. +
  595. +#include "tconfig.h"
  596. +#include "tsystem.h"
  597. +#include "coretypes.h"
  598. +#include "tm.h"
  599. +
  600. +
  601. +/* Don't use `fancy_abort' here even if config.h says to use it. */
  602. +#ifdef abort
  603. +#undef abort
  604. +#endif
  605. +
  606. +
  607. +#ifdef HAVE_GAS_HIDDEN
  608. +#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
  609. +#else
  610. +#define ATTRIBUTE_HIDDEN
  611. +#endif
  612. +
  613. +#include "libgcc2.h"
  614. +
  615. +#else
  616. +#define SItype int
  617. +#define USItype unsigned int
  618. +#endif
  619. +
  620. +
  621. +extern SItype __mulsi3 (SItype, SItype);
  622. +
  623. +SItype
  624. +__mulsi3 (SItype a, SItype b)
  625. +{
  626. + SItype res = 0;
  627. + USItype cnt = a;
  628. +
  629. + while (cnt)
  630. + {
  631. + if (cnt & 1)
  632. + {
  633. + res += b;
  634. + }
  635. + b <<= 1;
  636. + cnt >>= 1;
  637. + }
  638. +
  639. + return res;
  640. +}
  641. +/*
  642. +TODO: Choose best alternative implementation.
  643. +
  644. +SItype
  645. +__divsi3 (SItype a, SItype b)
  646. +{
  647. + SItype res = 0;
  648. + USItype cnt = 0;
  649. +
  650. + while (cnt < 32)
  651. + {
  652. + if (a & (1L << cnt))
  653. + {
  654. + res += b;
  655. + }
  656. + b <<= 1;
  657. + cnt++;
  658. + }
  659. +
  660. + return res;
  661. +}
  662. +*/
  663. +
  664. +
  665. +#ifdef DEBUG_MULSI3
  666. +
  667. +int
  668. +main ()
  669. +{
  670. + int i, j;
  671. + int error = 0;
  672. +
  673. + for (i = -1000; i < 1000; i++)
  674. + for (j = -1000; j < 1000; j++)
  675. + {
  676. + int expect = i * j;
  677. + int actual = A__divsi3 (i, j);
  678. + if (expect != actual)
  679. + {
  680. + printf ("error: %d * %d = %d not %d\n", i, j, expect, actual);
  681. + error = 1;
  682. + }
  683. + }
  684. +
  685. + return error;
  686. +}
  687. +#endif
  688. diff --git a/gcc/config/nios2/nios2-dp-bit.c b/gcc/config/nios2/nios2-dp-bit.c
  689. new file mode 100644
  690. index 0000000..4d63748
  691. --- /dev/null
  692. +++ b/gcc/config/nios2/nios2-dp-bit.c
  693. @@ -0,0 +1,1655 @@
  694. +
  695. +#ifndef __nios2_big_endian__
  696. +#define FLOAT_BIT_ORDER_MISMATCH
  697. +#endif
  698. +/* This is a software floating point library which can be used
  699. + for targets without hardware floating point.
  700. + Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
  701. + Free Software Foundation, Inc.
  702. +
  703. +This file is free software; you can redistribute it and/or modify it
  704. +under the terms of the GNU General Public License as published by the
  705. +Free Software Foundation; either version 2, or (at your option) any
  706. +later version.
  707. +
  708. +In addition to the permissions in the GNU General Public License, the
  709. +Free Software Foundation gives you unlimited permission to link the
  710. +compiled version of this file with other programs, and to distribute
  711. +those programs without any restriction coming from the use of this
  712. +file. (The General Public License restrictions do apply in other
  713. +respects; for example, they cover modification of the file, and
  714. +distribution when not linked into another program.)
  715. +
  716. +This file is distributed in the hope that it will be useful, but
  717. +WITHOUT ANY WARRANTY; without even the implied warranty of
  718. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  719. +General Public License for more details.
  720. +
  721. +You should have received a copy of the GNU General Public License
  722. +along with this program; see the file COPYING. If not, write to
  723. +the Free Software Foundation, 59 Temple Place - Suite 330,
  724. +Boston, MA 02111-1307, USA. */
  725. +
  726. +/* As a special exception, if you link this library with other files,
  727. + some of which are compiled with GCC, to produce an executable,
  728. + this library does not by itself cause the resulting executable
  729. + to be covered by the GNU General Public License.
  730. + This exception does not however invalidate any other reasons why
  731. + the executable file might be covered by the GNU General Public License. */
  732. +
  733. +/* This implements IEEE 754 format arithmetic, but does not provide a
  734. + mechanism for setting the rounding mode, or for generating or handling
  735. + exceptions.
  736. +
  737. + The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
  738. + Wilson, all of Cygnus Support. */
  739. +
  740. +/* The intended way to use this file is to make two copies, add `#define FLOAT'
  741. + to one copy, then compile both copies and add them to libgcc.a. */
  742. +
  743. +#include "tconfig.h"
  744. +#include "coretypes.h"
  745. +#include "tm.h"
  746. +#include "config/fp-bit.h"
  747. +
  748. +/* The following macros can be defined to change the behavior of this file:
  749. + FLOAT: Implement a `float', aka SFmode, fp library. If this is not
  750. + defined, then this file implements a `double', aka DFmode, fp library.
  751. + FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
  752. + don't include float->double conversion which requires the double library.
  753. + This is useful only for machines which can't support doubles, e.g. some
  754. + 8-bit processors.
  755. + CMPtype: Specify the type that floating point compares should return.
  756. + This defaults to SItype, aka int.
  757. + US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
  758. + US Software goFast library.
  759. + _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
  760. + two integers to the FLO_union_type.
  761. + NO_DENORMALS: Disable handling of denormals.
  762. + NO_NANS: Disable nan and infinity handling
  763. + SMALL_MACHINE: Useful when operations on QIs and HIs are faster
  764. + than on an SI */
  765. +
  766. +/* We don't currently support extended floats (long doubles) on machines
  767. + without hardware to deal with them.
  768. +
  769. + These stubs are just to keep the linker from complaining about unresolved
  770. + references which can be pulled in from libio & libstdc++, even if the
  771. + user isn't using long doubles. However, they may generate an unresolved
  772. + external to abort if abort is not used by the function, and the stubs
  773. + are referenced from within libc, since libgcc goes before and after the
  774. + system library. */
  775. +
  776. +#ifdef DECLARE_LIBRARY_RENAMES
  777. + DECLARE_LIBRARY_RENAMES
  778. +#endif
  779. +
  780. +#ifdef EXTENDED_FLOAT_STUBS
  781. +extern void abort (void);
  782. +void __extendsfxf2 (void) { abort(); }
  783. +void __extenddfxf2 (void) { abort(); }
  784. +void __truncxfdf2 (void) { abort(); }
  785. +void __truncxfsf2 (void) { abort(); }
  786. +void __fixxfsi (void) { abort(); }
  787. +void __floatsixf (void) { abort(); }
  788. +void __addxf3 (void) { abort(); }
  789. +void __subxf3 (void) { abort(); }
  790. +void __mulxf3 (void) { abort(); }
  791. +void __divxf3 (void) { abort(); }
  792. +void __negxf2 (void) { abort(); }
  793. +void __eqxf2 (void) { abort(); }
  794. +void __nexf2 (void) { abort(); }
  795. +void __gtxf2 (void) { abort(); }
  796. +void __gexf2 (void) { abort(); }
  797. +void __lexf2 (void) { abort(); }
  798. +void __ltxf2 (void) { abort(); }
  799. +
  800. +void __extendsftf2 (void) { abort(); }
  801. +void __extenddftf2 (void) { abort(); }
  802. +void __trunctfdf2 (void) { abort(); }
  803. +void __trunctfsf2 (void) { abort(); }
  804. +void __fixtfsi (void) { abort(); }
  805. +void __floatsitf (void) { abort(); }
  806. +void __addtf3 (void) { abort(); }
  807. +void __subtf3 (void) { abort(); }
  808. +void __multf3 (void) { abort(); }
  809. +void __divtf3 (void) { abort(); }
  810. +void __negtf2 (void) { abort(); }
  811. +void __eqtf2 (void) { abort(); }
  812. +void __netf2 (void) { abort(); }
  813. +void __gttf2 (void) { abort(); }
  814. +void __getf2 (void) { abort(); }
  815. +void __letf2 (void) { abort(); }
  816. +void __lttf2 (void) { abort(); }
  817. +#else /* !EXTENDED_FLOAT_STUBS, rest of file */
  818. +
  819. +/* IEEE "special" number predicates */
  820. +
  821. +#ifdef NO_NANS
  822. +
  823. +#define nan() 0
  824. +#define isnan(x) 0
  825. +#define isinf(x) 0
  826. +#else
  827. +
  828. +#if defined L_thenan_sf
  829. +const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
  830. +#elif defined L_thenan_df
  831. +const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
  832. +#elif defined L_thenan_tf
  833. +const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
  834. +#elif defined TFLOAT
  835. +extern const fp_number_type __thenan_tf;
  836. +#elif defined FLOAT
  837. +extern const fp_number_type __thenan_sf;
  838. +#else
  839. +extern const fp_number_type __thenan_df;
  840. +#endif
  841. +
  842. +INLINE
  843. +static fp_number_type *
  844. +nan (void)
  845. +{
  846. + /* Discard the const qualifier... */
  847. +#ifdef TFLOAT
  848. + return (fp_number_type *) (& __thenan_tf);
  849. +#elif defined FLOAT
  850. + return (fp_number_type *) (& __thenan_sf);
  851. +#else
  852. + return (fp_number_type *) (& __thenan_df);
  853. +#endif
  854. +}
  855. +
  856. +INLINE
  857. +static int
  858. +isnan ( fp_number_type * x)
  859. +{
  860. + return x->class == CLASS_SNAN || x->class == CLASS_QNAN;
  861. +}
  862. +
  863. +INLINE
  864. +static int
  865. +isinf ( fp_number_type * x)
  866. +{
  867. + return x->class == CLASS_INFINITY;
  868. +}
  869. +
  870. +#endif /* NO_NANS */
  871. +
  872. +INLINE
  873. +static int
  874. +iszero ( fp_number_type * x)
  875. +{
  876. + return x->class == CLASS_ZERO;
  877. +}
  878. +
  879. +INLINE
  880. +static void
  881. +flip_sign ( fp_number_type * x)
  882. +{
  883. + x->sign = !x->sign;
  884. +}
  885. +
  886. +extern FLO_type pack_d ( fp_number_type * );
  887. +
  888. +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
  889. +FLO_type
  890. +pack_d ( fp_number_type * src)
  891. +{
  892. + FLO_union_type dst;
  893. + fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
  894. + int sign = src->sign;
  895. + int exp = 0;
  896. +
  897. + if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
  898. + {
  899. + /* We can't represent these values accurately. By using the
  900. + largest possible magnitude, we guarantee that the conversion
  901. + of infinity is at least as big as any finite number. */
  902. + exp = EXPMAX;
  903. + fraction = ((fractype) 1 << FRACBITS) - 1;
  904. + }
  905. + else if (isnan (src))
  906. + {
  907. + exp = EXPMAX;
  908. + if (src->class == CLASS_QNAN || 1)
  909. + {
  910. +#ifdef QUIET_NAN_NEGATED
  911. + fraction |= QUIET_NAN - 1;
  912. +#else
  913. + fraction |= QUIET_NAN;
  914. +#endif
  915. + }
  916. + }
  917. + else if (isinf (src))
  918. + {
  919. + exp = EXPMAX;
  920. + fraction = 0;
  921. + }
  922. + else if (iszero (src))
  923. + {
  924. + exp = 0;
  925. + fraction = 0;
  926. + }
  927. + else if (fraction == 0)
  928. + {
  929. + exp = 0;
  930. + }
  931. + else
  932. + {
  933. + if (src->normal_exp < NORMAL_EXPMIN)
  934. + {
  935. +#ifdef NO_DENORMALS
  936. + /* Go straight to a zero representation if denormals are not
  937. + supported. The denormal handling would be harmless but
  938. + isn't unnecessary. */
  939. + exp = 0;
  940. + fraction = 0;
  941. +#else /* NO_DENORMALS */
  942. + /* This number's exponent is too low to fit into the bits
  943. + available in the number, so we'll store 0 in the exponent and
  944. + shift the fraction to the right to make up for it. */
  945. +
  946. + int shift = NORMAL_EXPMIN - src->normal_exp;
  947. +
  948. + exp = 0;
  949. +
  950. + if (shift > FRAC_NBITS - NGARDS)
  951. + {
  952. + /* No point shifting, since it's more that 64 out. */
  953. + fraction = 0;
  954. + }
  955. + else
  956. + {
  957. + int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
  958. + fraction = (fraction >> shift) | lowbit;
  959. + }
  960. + if ((fraction & GARDMASK) == GARDMSB)
  961. + {
  962. + if ((fraction & (1 << NGARDS)))
  963. + fraction += GARDROUND + 1;
  964. + }
  965. + else
  966. + {
  967. + /* Add to the guards to round up. */
  968. + fraction += GARDROUND;
  969. + }
  970. + /* Perhaps the rounding means we now need to change the
  971. + exponent, because the fraction is no longer denormal. */
  972. + if (fraction >= IMPLICIT_1)
  973. + {
  974. + exp += 1;
  975. + }
  976. + fraction >>= NGARDS;
  977. +#endif /* NO_DENORMALS */
  978. + }
  979. + else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
  980. + && src->normal_exp > EXPBIAS)
  981. + {
  982. + exp = EXPMAX;
  983. + fraction = 0;
  984. + }
  985. + else
  986. + {
  987. + exp = src->normal_exp + EXPBIAS;
  988. + if (!ROUND_TOWARDS_ZERO)
  989. + {
  990. + /* IF the gard bits are the all zero, but the first, then we're
  991. + half way between two numbers, choose the one which makes the
  992. + lsb of the answer 0. */
  993. + if ((fraction & GARDMASK) == GARDMSB)
  994. + {
  995. + if (fraction & (1 << NGARDS))
  996. + fraction += GARDROUND + 1;
  997. + }
  998. + else
  999. + {
  1000. + /* Add a one to the guards to round up */
  1001. + fraction += GARDROUND;
  1002. + }
  1003. + if (fraction >= IMPLICIT_2)
  1004. + {
  1005. + fraction >>= 1;
  1006. + exp += 1;
  1007. + }
  1008. + }
  1009. + fraction >>= NGARDS;
  1010. +
  1011. + if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
  1012. + {
  1013. + /* Saturate on overflow. */
  1014. + exp = EXPMAX;
  1015. + fraction = ((fractype) 1 << FRACBITS) - 1;
  1016. + }
  1017. + }
  1018. + }
  1019. +
  1020. + /* We previously used bitfields to store the number, but this doesn't
  1021. + handle little/big endian systems conveniently, so use shifts and
  1022. + masks */
  1023. +#ifdef FLOAT_BIT_ORDER_MISMATCH
  1024. + dst.bits.fraction = fraction;
  1025. + dst.bits.exp = exp;
  1026. + dst.bits.sign = sign;
  1027. +#else
  1028. +# if defined TFLOAT && defined HALFFRACBITS
  1029. + {
  1030. + halffractype high, low, unity;
  1031. + int lowsign, lowexp;
  1032. +
  1033. + unity = (halffractype) 1 << HALFFRACBITS;
  1034. +
  1035. + /* Set HIGH to the high double's significand, masking out the implicit 1.
  1036. + Set LOW to the low double's full significand. */
  1037. + high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
  1038. + low = fraction & (unity * 2 - 1);
  1039. +
  1040. + /* Get the initial sign and exponent of the low double. */
  1041. + lowexp = exp - HALFFRACBITS - 1;
  1042. + lowsign = sign;
  1043. +
  1044. + /* HIGH should be rounded like a normal double, making |LOW| <=
  1045. + 0.5 ULP of HIGH. Assume round-to-nearest. */
  1046. + if (exp < EXPMAX)
  1047. + if (low > unity || (low == unity && (high & 1) == 1))
  1048. + {
  1049. + /* Round HIGH up and adjust LOW to match. */
  1050. + high++;
  1051. + if (high == unity)
  1052. + {
  1053. + /* May make it infinite, but that's OK. */
  1054. + high = 0;
  1055. + exp++;
  1056. + }
  1057. + low = unity * 2 - low;
  1058. + lowsign ^= 1;
  1059. + }
  1060. +
  1061. + high |= (halffractype) exp << HALFFRACBITS;
  1062. + high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
  1063. +
  1064. + if (exp == EXPMAX || exp == 0 || low == 0)
  1065. + low = 0;
  1066. + else
  1067. + {
  1068. + while (lowexp > 0 && low < unity)
  1069. + {
  1070. + low <<= 1;
  1071. + lowexp--;
  1072. + }
  1073. +
  1074. + if (lowexp <= 0)
  1075. + {
  1076. + halffractype roundmsb, round;
  1077. + int shift;
  1078. +
  1079. + shift = 1 - lowexp;
  1080. + roundmsb = (1 << (shift - 1));
  1081. + round = low & ((roundmsb << 1) - 1);
  1082. +
  1083. + low >>= shift;
  1084. + lowexp = 0;
  1085. +
  1086. + if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
  1087. + {
  1088. + low++;
  1089. + if (low == unity)
  1090. + /* LOW rounds up to the smallest normal number. */
  1091. + lowexp++;
  1092. + }
  1093. + }
  1094. +
  1095. + low &= unity - 1;
  1096. + low |= (halffractype) lowexp << HALFFRACBITS;
  1097. + low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
  1098. + }
  1099. + dst.value_raw = ((fractype) high << HALFSHIFT) | low;
  1100. + }
  1101. +# else
  1102. + dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
  1103. + dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
  1104. + dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
  1105. +# endif
  1106. +#endif
  1107. +
  1108. +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
  1109. +#ifdef TFLOAT
  1110. + {
  1111. + qrtrfractype tmp1 = dst.words[0];
  1112. + qrtrfractype tmp2 = dst.words[1];
  1113. + dst.words[0] = dst.words[3];
  1114. + dst.words[1] = dst.words[2];
  1115. + dst.words[2] = tmp2;
  1116. + dst.words[3] = tmp1;
  1117. + }
  1118. +#else
  1119. + {
  1120. + halffractype tmp = dst.words[0];
  1121. + dst.words[0] = dst.words[1];
  1122. + dst.words[1] = tmp;
  1123. + }
  1124. +#endif
  1125. +#endif
  1126. +
  1127. + return dst.value;
  1128. +}
  1129. +#endif
  1130. +
  1131. +#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
  1132. +void
  1133. +unpack_d (FLO_union_type * src, fp_number_type * dst)
  1134. +{
  1135. + /* We previously used bitfields to store the number, but this doesn't
  1136. + handle little/big endian systems conveniently, so use shifts and
  1137. + masks */
  1138. + fractype fraction;
  1139. + int exp;
  1140. + int sign;
  1141. +
  1142. +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
  1143. + FLO_union_type swapped;
  1144. +
  1145. +#ifdef TFLOAT
  1146. + swapped.words[0] = src->words[3];
  1147. + swapped.words[1] = src->words[2];
  1148. + swapped.words[2] = src->words[1];
  1149. + swapped.words[3] = src->words[0];
  1150. +#else
  1151. + swapped.words[0] = src->words[1];
  1152. + swapped.words[1] = src->words[0];
  1153. +#endif
  1154. + src = &swapped;
  1155. +#endif
  1156. +
  1157. +#ifdef FLOAT_BIT_ORDER_MISMATCH
  1158. + fraction = src->bits.fraction;
  1159. + exp = src->bits.exp;
  1160. + sign = src->bits.sign;
  1161. +#else
  1162. +# if defined TFLOAT && defined HALFFRACBITS
  1163. + {
  1164. + halffractype high, low;
  1165. +
  1166. + high = src->value_raw >> HALFSHIFT;
  1167. + low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
  1168. +
  1169. + fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
  1170. + fraction <<= FRACBITS - HALFFRACBITS;
  1171. + exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
  1172. + sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
  1173. +
  1174. + if (exp != EXPMAX && exp != 0 && low != 0)
  1175. + {
  1176. + int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
  1177. + int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
  1178. + int shift;
  1179. + fractype xlow;
  1180. +
  1181. + xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
  1182. + if (lowexp)
  1183. + xlow |= (((halffractype)1) << HALFFRACBITS);
  1184. + else
  1185. + lowexp = 1;
  1186. + shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
  1187. + if (shift > 0)
  1188. + xlow <<= shift;
  1189. + else if (shift < 0)
  1190. + xlow >>= -shift;
  1191. + if (sign == lowsign)
  1192. + fraction += xlow;
  1193. + else if (fraction >= xlow)
  1194. + fraction -= xlow;
  1195. + else
  1196. + {
  1197. + /* The high part is a power of two but the full number is lower.
  1198. + This code will leave the implicit 1 in FRACTION, but we'd
  1199. + have added that below anyway. */
  1200. + fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
  1201. + exp--;
  1202. + }
  1203. + }
  1204. + }
  1205. +# else
  1206. + fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
  1207. + exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
  1208. + sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
  1209. +# endif
  1210. +#endif
  1211. +
  1212. + dst->sign = sign;
  1213. + if (exp == 0)
  1214. + {
  1215. + /* Hmm. Looks like 0 */
  1216. + if (fraction == 0
  1217. +#ifdef NO_DENORMALS
  1218. + || 1
  1219. +#endif
  1220. + )
  1221. + {
  1222. + /* tastes like zero */
  1223. + dst->class = CLASS_ZERO;
  1224. + }
  1225. + else
  1226. + {
  1227. + /* Zero exponent with nonzero fraction - it's denormalized,
  1228. + so there isn't a leading implicit one - we'll shift it so
  1229. + it gets one. */
  1230. + dst->normal_exp = exp - EXPBIAS + 1;
  1231. + fraction <<= NGARDS;
  1232. +
  1233. + dst->class = CLASS_NUMBER;
  1234. +#if 1
  1235. + while (fraction < IMPLICIT_1)
  1236. + {
  1237. + fraction <<= 1;
  1238. + dst->normal_exp--;
  1239. + }
  1240. +#endif
  1241. + dst->fraction.ll = fraction;
  1242. + }
  1243. + }
  1244. + else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp == EXPMAX)
  1245. + {
  1246. + /* Huge exponent*/
  1247. + if (fraction == 0)
  1248. + {
  1249. + /* Attached to a zero fraction - means infinity */
  1250. + dst->class = CLASS_INFINITY;
  1251. + }
  1252. + else
  1253. + {
  1254. + /* Nonzero fraction, means nan */
  1255. +#ifdef QUIET_NAN_NEGATED
  1256. + if ((fraction & QUIET_NAN) == 0)
  1257. +#else
  1258. + if (fraction & QUIET_NAN)
  1259. +#endif
  1260. + {
  1261. + dst->class = CLASS_QNAN;
  1262. + }
  1263. + else
  1264. + {
  1265. + dst->class = CLASS_SNAN;
  1266. + }
  1267. + /* Keep the fraction part as the nan number */
  1268. + dst->fraction.ll = fraction;
  1269. + }
  1270. + }
  1271. + else
  1272. + {
  1273. + /* Nothing strange about this number */
  1274. + dst->normal_exp = exp - EXPBIAS;
  1275. + dst->class = CLASS_NUMBER;
  1276. + dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
  1277. + }
  1278. +}
  1279. +#endif /* L_unpack_df || L_unpack_sf */
  1280. +
  1281. +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
  1282. +static fp_number_type *
  1283. +_fpadd_parts (fp_number_type * a,
  1284. + fp_number_type * b,
  1285. + fp_number_type * tmp)
  1286. +{
  1287. + intfrac tfraction;
  1288. +
  1289. + /* Put commonly used fields in local variables. */
  1290. + int a_normal_exp;
  1291. + int b_normal_exp;
  1292. + fractype a_fraction;
  1293. + fractype b_fraction;
  1294. +
  1295. + if (isnan (a))
  1296. + {
  1297. + return a;
  1298. + }
  1299. + if (isnan (b))
  1300. + {
  1301. + return b;
  1302. + }
  1303. + if (isinf (a))
  1304. + {
  1305. + /* Adding infinities with opposite signs yields a NaN. */
  1306. + if (isinf (b) && a->sign != b->sign)
  1307. + return nan ();
  1308. + return a;
  1309. + }
  1310. + if (isinf (b))
  1311. + {
  1312. + return b;
  1313. + }
  1314. + if (iszero (b))
  1315. + {
  1316. + if (iszero (a))
  1317. + {
  1318. + *tmp = *a;
  1319. + tmp->sign = a->sign & b->sign;
  1320. + return tmp;
  1321. + }
  1322. + return a;
  1323. + }
  1324. + if (iszero (a))
  1325. + {
  1326. + return b;
  1327. + }
  1328. +
  1329. + /* Got two numbers. shift the smaller and increment the exponent till
  1330. + they're the same */
  1331. + {
  1332. + int diff;
  1333. +
  1334. + a_normal_exp = a->normal_exp;
  1335. + b_normal_exp = b->normal_exp;
  1336. + a_fraction = a->fraction.ll;
  1337. + b_fraction = b->fraction.ll;
  1338. +
  1339. + diff = a_normal_exp - b_normal_exp;
  1340. +
  1341. + if (diff < 0)
  1342. + diff = -diff;
  1343. + if (diff < FRAC_NBITS)
  1344. + {
  1345. + /* ??? This does shifts one bit at a time. Optimize. */
  1346. + while (a_normal_exp > b_normal_exp)
  1347. + {
  1348. + b_normal_exp++;
  1349. + LSHIFT (b_fraction);
  1350. + }
  1351. + while (b_normal_exp > a_normal_exp)
  1352. + {
  1353. + a_normal_exp++;
  1354. + LSHIFT (a_fraction);
  1355. + }
  1356. + }
  1357. + else
  1358. + {
  1359. + /* Somethings's up.. choose the biggest */
  1360. + if (a_normal_exp > b_normal_exp)
  1361. + {
  1362. + b_normal_exp = a_normal_exp;
  1363. + b_fraction = 0;
  1364. + }
  1365. + else
  1366. + {
  1367. + a_normal_exp = b_normal_exp;
  1368. + a_fraction = 0;
  1369. + }
  1370. + }
  1371. + }
  1372. +
  1373. + if (a->sign != b->sign)
  1374. + {
  1375. + if (a->sign)
  1376. + {
  1377. + tfraction = -a_fraction + b_fraction;
  1378. + }
  1379. + else
  1380. + {
  1381. + tfraction = a_fraction - b_fraction;
  1382. + }
  1383. + if (tfraction >= 0)
  1384. + {
  1385. + tmp->sign = 0;
  1386. + tmp->normal_exp = a_normal_exp;
  1387. + tmp->fraction.ll = tfraction;
  1388. + }
  1389. + else
  1390. + {
  1391. + tmp->sign = 1;
  1392. + tmp->normal_exp = a_normal_exp;
  1393. + tmp->fraction.ll = -tfraction;
  1394. + }
  1395. + /* and renormalize it */
  1396. +
  1397. + while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
  1398. + {
  1399. + tmp->fraction.ll <<= 1;
  1400. + tmp->normal_exp--;
  1401. + }
  1402. + }
  1403. + else
  1404. + {
  1405. + tmp->sign = a->sign;
  1406. + tmp->normal_exp = a_normal_exp;
  1407. + tmp->fraction.ll = a_fraction + b_fraction;
  1408. + }
  1409. + tmp->class = CLASS_NUMBER;
  1410. + /* Now the fraction is added, we have to shift down to renormalize the
  1411. + number */
  1412. +
  1413. + if (tmp->fraction.ll >= IMPLICIT_2)
  1414. + {
  1415. + LSHIFT (tmp->fraction.ll);
  1416. + tmp->normal_exp++;
  1417. + }
  1418. + return tmp;
  1419. +
  1420. +}
  1421. +
  1422. +FLO_type
  1423. +add (FLO_type arg_a, FLO_type arg_b)
  1424. +{
  1425. + fp_number_type a;
  1426. + fp_number_type b;
  1427. + fp_number_type tmp;
  1428. + fp_number_type *res;
  1429. + FLO_union_type au, bu;
  1430. +
  1431. + au.value = arg_a;
  1432. + bu.value = arg_b;
  1433. +
  1434. + unpack_d (&au, &a);
  1435. + unpack_d (&bu, &b);
  1436. +
  1437. + res = _fpadd_parts (&a, &b, &tmp);
  1438. +
  1439. + return pack_d (res);
  1440. +}
  1441. +
  1442. +FLO_type
  1443. +sub (FLO_type arg_a, FLO_type arg_b)
  1444. +{
  1445. + fp_number_type a;
  1446. + fp_number_type b;
  1447. + fp_number_type tmp;
  1448. + fp_number_type *res;
  1449. + FLO_union_type au, bu;
  1450. +
  1451. + au.value = arg_a;
  1452. + bu.value = arg_b;
  1453. +
  1454. + unpack_d (&au, &a);
  1455. + unpack_d (&bu, &b);
  1456. +
  1457. + b.sign ^= 1;
  1458. +
  1459. + res = _fpadd_parts (&a, &b, &tmp);
  1460. +
  1461. + return pack_d (res);
  1462. +}
  1463. +#endif /* L_addsub_sf || L_addsub_df */
  1464. +
  1465. +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
  1466. +static inline __attribute__ ((__always_inline__)) fp_number_type *
  1467. +_fpmul_parts ( fp_number_type * a,
  1468. + fp_number_type * b,
  1469. + fp_number_type * tmp)
  1470. +{
  1471. + fractype low = 0;
  1472. + fractype high = 0;
  1473. +
  1474. + if (isnan (a))
  1475. + {
  1476. + a->sign = a->sign != b->sign;
  1477. + return a;
  1478. + }
  1479. + if (isnan (b))
  1480. + {
  1481. + b->sign = a->sign != b->sign;
  1482. + return b;
  1483. + }
  1484. + if (isinf (a))
  1485. + {
  1486. + if (iszero (b))
  1487. + return nan ();
  1488. + a->sign = a->sign != b->sign;
  1489. + return a;
  1490. + }
  1491. + if (isinf (b))
  1492. + {
  1493. + if (iszero (a))
  1494. + {
  1495. + return nan ();
  1496. + }
  1497. + b->sign = a->sign != b->sign;
  1498. + return b;
  1499. + }
  1500. + if (iszero (a))
  1501. + {
  1502. + a->sign = a->sign != b->sign;
  1503. + return a;
  1504. + }
  1505. + if (iszero (b))
  1506. + {
  1507. + b->sign = a->sign != b->sign;
  1508. + return b;
  1509. + }
  1510. +
  1511. + /* Calculate the mantissa by multiplying both numbers to get a
  1512. + twice-as-wide number. */
  1513. + {
  1514. +#if defined(NO_DI_MODE) || defined(TFLOAT)
  1515. + {
  1516. + fractype x = a->fraction.ll;
  1517. + fractype ylow = b->fraction.ll;
  1518. + fractype yhigh = 0;
  1519. + int bit;
  1520. +
  1521. + /* ??? This does multiplies one bit at a time. Optimize. */
  1522. + for (bit = 0; bit < FRAC_NBITS; bit++)
  1523. + {
  1524. + int carry;
  1525. +
  1526. + if (x & 1)
  1527. + {
  1528. + carry = (low += ylow) < ylow;
  1529. + high += yhigh + carry;
  1530. + }
  1531. + yhigh <<= 1;
  1532. + if (ylow & FRACHIGH)
  1533. + {
  1534. + yhigh |= 1;
  1535. + }
  1536. + ylow <<= 1;
  1537. + x >>= 1;
  1538. + }
  1539. + }
  1540. +#elif defined(FLOAT)
  1541. + /* Multiplying two USIs to get a UDI, we're safe. */
  1542. + {
  1543. + UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
  1544. +
  1545. + high = answer >> BITS_PER_SI;
  1546. + low = answer;
  1547. + }
  1548. +#else
  1549. + /* fractype is DImode, but we need the result to be twice as wide.
  1550. + Assuming a widening multiply from DImode to TImode is not
  1551. + available, build one by hand. */
  1552. + {
  1553. + USItype nl = a->fraction.ll;
  1554. + USItype nh = a->fraction.ll >> BITS_PER_SI;
  1555. + USItype ml = b->fraction.ll;
  1556. + USItype mh = b->fraction.ll >> BITS_PER_SI;
  1557. + UDItype pp_ll = (UDItype) ml * nl;
  1558. + UDItype pp_hl = (UDItype) mh * nl;
  1559. + UDItype pp_lh = (UDItype) ml * nh;
  1560. + UDItype pp_hh = (UDItype) mh * nh;
  1561. + UDItype res2 = 0;
  1562. + UDItype res0 = 0;
  1563. + UDItype ps_hh__ = pp_hl + pp_lh;
  1564. + if (ps_hh__ < pp_hl)
  1565. + res2 += (UDItype)1 << BITS_PER_SI;
  1566. + pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
  1567. + res0 = pp_ll + pp_hl;
  1568. + if (res0 < pp_ll)
  1569. + res2++;
  1570. + res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
  1571. + high = res2;
  1572. + low = res0;
  1573. + }
  1574. +#endif
  1575. + }
  1576. +
  1577. + tmp->normal_exp = a->normal_exp + b->normal_exp
  1578. + + FRAC_NBITS - (FRACBITS + NGARDS);
  1579. + tmp->sign = a->sign != b->sign;
  1580. + while (high >= IMPLICIT_2)
  1581. + {
  1582. + tmp->normal_exp++;
  1583. + if (high & 1)
  1584. + {
  1585. + low >>= 1;
  1586. + low |= FRACHIGH;
  1587. + }
  1588. + high >>= 1;
  1589. + }
  1590. + while (high < IMPLICIT_1)
  1591. + {
  1592. + tmp->normal_exp--;
  1593. +
  1594. + high <<= 1;
  1595. + if (low & FRACHIGH)
  1596. + high |= 1;
  1597. + low <<= 1;
  1598. + }
  1599. + /* rounding is tricky. if we only round if it won't make us round later. */
  1600. +#if 0
  1601. + if (low & FRACHIGH2)
  1602. + {
  1603. + if (((high & GARDMASK) != GARDMSB)
  1604. + && (((high + 1) & GARDMASK) == GARDMSB))
  1605. + {
  1606. + /* don't round, it gets done again later. */
  1607. + }
  1608. + else
  1609. + {
  1610. + high++;
  1611. + }
  1612. + }
  1613. +#endif
  1614. + if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
  1615. + {
  1616. + if (high & (1 << NGARDS))
  1617. + {
  1618. + /* half way, so round to even */
  1619. + high += GARDROUND + 1;
  1620. + }
  1621. + else if (low)
  1622. + {
  1623. + /* but we really weren't half way */
  1624. + high += GARDROUND + 1;
  1625. + }
  1626. + }
  1627. + tmp->fraction.ll = high;
  1628. + tmp->class = CLASS_NUMBER;
  1629. + return tmp;
  1630. +}
  1631. +
  1632. +FLO_type
  1633. +multiply (FLO_type arg_a, FLO_type arg_b)
  1634. +{
  1635. + fp_number_type a;
  1636. + fp_number_type b;
  1637. + fp_number_type tmp;
  1638. + fp_number_type *res;
  1639. + FLO_union_type au, bu;
  1640. +
  1641. + au.value = arg_a;
  1642. + bu.value = arg_b;
  1643. +
  1644. + unpack_d (&au, &a);
  1645. + unpack_d (&bu, &b);
  1646. +
  1647. + res = _fpmul_parts (&a, &b, &tmp);
  1648. +
  1649. + return pack_d (res);
  1650. +}
  1651. +#endif /* L_mul_sf || L_mul_df */
  1652. +
  1653. +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
  1654. +static inline __attribute__ ((__always_inline__)) fp_number_type *
  1655. +_fpdiv_parts (fp_number_type * a,
  1656. + fp_number_type * b)
  1657. +{
  1658. + fractype bit;
  1659. + fractype numerator;
  1660. + fractype denominator;
  1661. + fractype quotient;
  1662. +
  1663. + if (isnan (a))
  1664. + {
  1665. + return a;
  1666. + }
  1667. + if (isnan (b))
  1668. + {
  1669. + return b;
  1670. + }
  1671. +
  1672. + a->sign = a->sign ^ b->sign;
  1673. +
  1674. + if (isinf (a) || iszero (a))
  1675. + {
  1676. + if (a->class == b->class)
  1677. + return nan ();
  1678. + return a;
  1679. + }
  1680. +
  1681. + if (isinf (b))
  1682. + {
  1683. + a->fraction.ll = 0;
  1684. + a->normal_exp = 0;
  1685. + return a;
  1686. + }
  1687. + if (iszero (b))
  1688. + {
  1689. + a->class = CLASS_INFINITY;
  1690. + return a;
  1691. + }
  1692. +
  1693. + /* Calculate the mantissa by multiplying both 64bit numbers to get a
  1694. + 128 bit number */
  1695. + {
  1696. + /* quotient =
  1697. + ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
  1698. + */
  1699. +
  1700. + a->normal_exp = a->normal_exp - b->normal_exp;
  1701. + numerator = a->fraction.ll;
  1702. + denominator = b->fraction.ll;
  1703. +
  1704. + if (numerator < denominator)
  1705. + {
  1706. + /* Fraction will be less than 1.0 */
  1707. + numerator *= 2;
  1708. + a->normal_exp--;
  1709. + }
  1710. + bit = IMPLICIT_1;
  1711. + quotient = 0;
  1712. + /* ??? Does divide one bit at a time. Optimize. */
  1713. + while (bit)
  1714. + {
  1715. + if (numerator >= denominator)
  1716. + {
  1717. + quotient |= bit;
  1718. + numerator -= denominator;
  1719. + }
  1720. + bit >>= 1;
  1721. + numerator *= 2;
  1722. + }
  1723. +
  1724. + if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
  1725. + {
  1726. + if (quotient & (1 << NGARDS))
  1727. + {
  1728. + /* half way, so round to even */
  1729. + quotient += GARDROUND + 1;
  1730. + }
  1731. + else if (numerator)
  1732. + {
  1733. + /* but we really weren't half way, more bits exist */
  1734. + quotient += GARDROUND + 1;
  1735. + }
  1736. + }
  1737. +
  1738. + a->fraction.ll = quotient;
  1739. + return (a);
  1740. + }
  1741. +}
  1742. +
  1743. +FLO_type
  1744. +divide (FLO_type arg_a, FLO_type arg_b)
  1745. +{
  1746. + fp_number_type a;
  1747. + fp_number_type b;
  1748. + fp_number_type *res;
  1749. + FLO_union_type au, bu;
  1750. +
  1751. + au.value = arg_a;
  1752. + bu.value = arg_b;
  1753. +
  1754. + unpack_d (&au, &a);
  1755. + unpack_d (&bu, &b);
  1756. +
  1757. + res = _fpdiv_parts (&a, &b);
  1758. +
  1759. + return pack_d (res);
  1760. +}
  1761. +#endif /* L_div_sf || L_div_df */
  1762. +
  1763. +#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
  1764. + || defined(L_fpcmp_parts_tf)
  1765. +/* according to the demo, fpcmp returns a comparison with 0... thus
  1766. + a<b -> -1
  1767. + a==b -> 0
  1768. + a>b -> +1
  1769. + */
  1770. +
  1771. +int
  1772. +__fpcmp_parts (fp_number_type * a, fp_number_type * b)
  1773. +{
  1774. +#if 0
  1775. + /* either nan -> unordered. Must be checked outside of this routine. */
  1776. + if (isnan (a) && isnan (b))
  1777. + {
  1778. + return 1; /* still unordered! */
  1779. + }
  1780. +#endif
  1781. +
  1782. + if (isnan (a) || isnan (b))
  1783. + {
  1784. + return 1; /* how to indicate unordered compare? */
  1785. + }
  1786. + if (isinf (a) && isinf (b))
  1787. + {
  1788. + /* +inf > -inf, but +inf != +inf */
  1789. + /* b \a| +inf(0)| -inf(1)
  1790. + ______\+--------+--------
  1791. + +inf(0)| a==b(0)| a<b(-1)
  1792. + -------+--------+--------
  1793. + -inf(1)| a>b(1) | a==b(0)
  1794. + -------+--------+--------
  1795. + So since unordered must be nonzero, just line up the columns...
  1796. + */
  1797. + return b->sign - a->sign;
  1798. + }
  1799. + /* but not both... */
  1800. + if (isinf (a))
  1801. + {
  1802. + return a->sign ? -1 : 1;
  1803. + }
  1804. + if (isinf (b))
  1805. + {
  1806. + return b->sign ? 1 : -1;
  1807. + }
  1808. + if (iszero (a) && iszero (b))
  1809. + {
  1810. + return 0;
  1811. + }
  1812. + if (iszero (a))
  1813. + {
  1814. + return b->sign ? 1 : -1;
  1815. + }
  1816. + if (iszero (b))
  1817. + {
  1818. + return a->sign ? -1 : 1;
  1819. + }
  1820. + /* now both are "normal". */
  1821. + if (a->sign != b->sign)
  1822. + {
  1823. + /* opposite signs */
  1824. + return a->sign ? -1 : 1;
  1825. + }
  1826. + /* same sign; exponents? */
  1827. + if (a->normal_exp > b->normal_exp)
  1828. + {
  1829. + return a->sign ? -1 : 1;
  1830. + }
  1831. + if (a->normal_exp < b->normal_exp)
  1832. + {
  1833. + return a->sign ? 1 : -1;
  1834. + }
  1835. + /* same exponents; check size. */
  1836. + if (a->fraction.ll > b->fraction.ll)
  1837. + {
  1838. + return a->sign ? -1 : 1;
  1839. + }
  1840. + if (a->fraction.ll < b->fraction.ll)
  1841. + {
  1842. + return a->sign ? 1 : -1;
  1843. + }
  1844. + /* after all that, they're equal. */
  1845. + return 0;
  1846. +}
  1847. +#endif
  1848. +
  1849. +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
  1850. +CMPtype
  1851. +compare (FLO_type arg_a, FLO_type arg_b)
  1852. +{
  1853. + fp_number_type a;
  1854. + fp_number_type b;
  1855. + FLO_union_type au, bu;
  1856. +
  1857. + au.value = arg_a;
  1858. + bu.value = arg_b;
  1859. +
  1860. + unpack_d (&au, &a);
  1861. + unpack_d (&bu, &b);
  1862. +
  1863. + return __fpcmp_parts (&a, &b);
  1864. +}
  1865. +#endif /* L_compare_sf || L_compare_df */
  1866. +
  1867. +#ifndef US_SOFTWARE_GOFAST
  1868. +
  1869. +/* These should be optimized for their specific tasks someday. */
  1870. +
  1871. +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
  1872. +CMPtype
  1873. +_eq_f2 (FLO_type arg_a, FLO_type arg_b)
  1874. +{
  1875. + fp_number_type a;
  1876. + fp_number_type b;
  1877. + FLO_union_type au, bu;
  1878. +
  1879. + au.value = arg_a;
  1880. + bu.value = arg_b;
  1881. +
  1882. + unpack_d (&au, &a);
  1883. + unpack_d (&bu, &b);
  1884. +
  1885. + if (isnan (&a) || isnan (&b))
  1886. + return 1; /* false, truth == 0 */
  1887. +
  1888. + return __fpcmp_parts (&a, &b) ;
  1889. +}
  1890. +#endif /* L_eq_sf || L_eq_df */
  1891. +
  1892. +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
  1893. +CMPtype
  1894. +_ne_f2 (FLO_type arg_a, FLO_type arg_b)
  1895. +{
  1896. + fp_number_type a;
  1897. + fp_number_type b;
  1898. + FLO_union_type au, bu;
  1899. +
  1900. + au.value = arg_a;
  1901. + bu.value = arg_b;
  1902. +
  1903. + unpack_d (&au, &a);
  1904. + unpack_d (&bu, &b);
  1905. +
  1906. + if (isnan (&a) || isnan (&b))
  1907. + return 1; /* true, truth != 0 */
  1908. +
  1909. + return __fpcmp_parts (&a, &b) ;
  1910. +}
  1911. +#endif /* L_ne_sf || L_ne_df */
  1912. +
  1913. +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
  1914. +CMPtype
  1915. +_gt_f2 (FLO_type arg_a, FLO_type arg_b)
  1916. +{
  1917. + fp_number_type a;
  1918. + fp_number_type b;
  1919. + FLO_union_type au, bu;
  1920. +
  1921. + au.value = arg_a;
  1922. + bu.value = arg_b;
  1923. +
  1924. + unpack_d (&au, &a);
  1925. + unpack_d (&bu, &b);
  1926. +
  1927. + if (isnan (&a) || isnan (&b))
  1928. + return -1; /* false, truth > 0 */
  1929. +
  1930. + return __fpcmp_parts (&a, &b);
  1931. +}
  1932. +#endif /* L_gt_sf || L_gt_df */
  1933. +
  1934. +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
  1935. +CMPtype
  1936. +_ge_f2 (FLO_type arg_a, FLO_type arg_b)
  1937. +{
  1938. + fp_number_type a;
  1939. + fp_number_type b;
  1940. + FLO_union_type au, bu;
  1941. +
  1942. + au.value = arg_a;
  1943. + bu.value = arg_b;
  1944. +
  1945. + unpack_d (&au, &a);
  1946. + unpack_d (&bu, &b);
  1947. +
  1948. + if (isnan (&a) || isnan (&b))
  1949. + return -1; /* false, truth >= 0 */
  1950. + return __fpcmp_parts (&a, &b) ;
  1951. +}
  1952. +#endif /* L_ge_sf || L_ge_df */
  1953. +
  1954. +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
  1955. +CMPtype
  1956. +_lt_f2 (FLO_type arg_a, FLO_type arg_b)
  1957. +{
  1958. + fp_number_type a;
  1959. + fp_number_type b;
  1960. + FLO_union_type au, bu;
  1961. +
  1962. + au.value = arg_a;
  1963. + bu.value = arg_b;
  1964. +
  1965. + unpack_d (&au, &a);
  1966. + unpack_d (&bu, &b);
  1967. +
  1968. + if (isnan (&a) || isnan (&b))
  1969. + return 1; /* false, truth < 0 */
  1970. +
  1971. + return __fpcmp_parts (&a, &b);
  1972. +}
  1973. +#endif /* L_lt_sf || L_lt_df */
  1974. +
  1975. +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
  1976. +CMPtype
  1977. +_le_f2 (FLO_type arg_a, FLO_type arg_b)
  1978. +{
  1979. + fp_number_type a;
  1980. + fp_number_type b;
  1981. + FLO_union_type au, bu;
  1982. +
  1983. + au.value = arg_a;
  1984. + bu.value = arg_b;
  1985. +
  1986. + unpack_d (&au, &a);
  1987. + unpack_d (&bu, &b);
  1988. +
  1989. + if (isnan (&a) || isnan (&b))
  1990. + return 1; /* false, truth <= 0 */
  1991. +
  1992. + return __fpcmp_parts (&a, &b) ;
  1993. +}
  1994. +#endif /* L_le_sf || L_le_df */
  1995. +
  1996. +#endif /* ! US_SOFTWARE_GOFAST */
  1997. +
  1998. +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
  1999. +CMPtype
  2000. +_unord_f2 (FLO_type arg_a, FLO_type arg_b)
  2001. +{
  2002. + fp_number_type a;
  2003. + fp_number_type b;
  2004. + FLO_union_type au, bu;
  2005. +
  2006. + au.value = arg_a;
  2007. + bu.value = arg_b;
  2008. +
  2009. + unpack_d (&au, &a);
  2010. + unpack_d (&bu, &b);
  2011. +
  2012. + return (isnan (&a) || isnan (&b));
  2013. +}
  2014. +#endif /* L_unord_sf || L_unord_df */
  2015. +
  2016. +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
  2017. +FLO_type
  2018. +si_to_float (SItype arg_a)
  2019. +{
  2020. + fp_number_type in;
  2021. +
  2022. + in.class = CLASS_NUMBER;
  2023. + in.sign = arg_a < 0;
  2024. + if (!arg_a)
  2025. + {
  2026. + in.class = CLASS_ZERO;
  2027. + }
  2028. + else
  2029. + {
  2030. + in.normal_exp = FRACBITS + NGARDS;
  2031. + if (in.sign)
  2032. + {
  2033. + /* Special case for minint, since there is no +ve integer
  2034. + representation for it */
  2035. + if (arg_a == (- MAX_SI_INT - 1))
  2036. + {
  2037. + return (FLO_type)(- MAX_SI_INT - 1);
  2038. + }
  2039. + in.fraction.ll = (-arg_a);
  2040. + }
  2041. + else
  2042. + in.fraction.ll = arg_a;
  2043. +
  2044. + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
  2045. + {
  2046. + in.fraction.ll <<= 1;
  2047. + in.normal_exp -= 1;
  2048. + }
  2049. + }
  2050. + return pack_d (&in);
  2051. +}
  2052. +#endif /* L_si_to_sf || L_si_to_df */
  2053. +
  2054. +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
  2055. +FLO_type
  2056. +usi_to_float (USItype arg_a)
  2057. +{
  2058. + fp_number_type in;
  2059. +
  2060. + in.sign = 0;
  2061. + if (!arg_a)
  2062. + {
  2063. + in.class = CLASS_ZERO;
  2064. + }
  2065. + else
  2066. + {
  2067. + in.class = CLASS_NUMBER;
  2068. + in.normal_exp = FRACBITS + NGARDS;
  2069. + in.fraction.ll = arg_a;
  2070. +
  2071. + while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS)))
  2072. + {
  2073. + in.fraction.ll >>= 1;
  2074. + in.normal_exp += 1;
  2075. + }
  2076. + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
  2077. + {
  2078. + in.fraction.ll <<= 1;
  2079. + in.normal_exp -= 1;
  2080. + }
  2081. + }
  2082. + return pack_d (&in);
  2083. +}
  2084. +#endif
  2085. +
  2086. +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
  2087. +SItype
  2088. +float_to_si (FLO_type arg_a)
  2089. +{
  2090. + fp_number_type a;
  2091. + SItype tmp;
  2092. + FLO_union_type au;
  2093. +
  2094. + au.value = arg_a;
  2095. + unpack_d (&au, &a);
  2096. +
  2097. + if (iszero (&a))
  2098. + return 0;
  2099. + if (isnan (&a))
  2100. + return 0;
  2101. + /* get reasonable MAX_SI_INT... */
  2102. + if (isinf (&a))
  2103. + return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
  2104. + /* it is a number, but a small one */
  2105. + if (a.normal_exp < 0)
  2106. + return 0;
  2107. + if (a.normal_exp > BITS_PER_SI - 2)
  2108. + return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
  2109. + tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
  2110. + return a.sign ? (-tmp) : (tmp);
  2111. +}
  2112. +#endif /* L_sf_to_si || L_df_to_si */
  2113. +
  2114. +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
  2115. +#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
  2116. +/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
  2117. + we also define them for GOFAST because the ones in libgcc2.c have the
  2118. + wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
  2119. + out of libgcc2.c. We can't define these here if not GOFAST because then
  2120. + there'd be duplicate copies. */
  2121. +
  2122. +USItype
  2123. +float_to_usi (FLO_type arg_a)
  2124. +{
  2125. + fp_number_type a;
  2126. + FLO_union_type au;
  2127. +
  2128. + au.value = arg_a;
  2129. + unpack_d (&au, &a);
  2130. +
  2131. + if (iszero (&a))
  2132. + return 0;
  2133. + if (isnan (&a))
  2134. + return 0;
  2135. + /* it is a negative number */
  2136. + if (a.sign)
  2137. + return 0;
  2138. + /* get reasonable MAX_USI_INT... */
  2139. + if (isinf (&a))
  2140. + return MAX_USI_INT;
  2141. + /* it is a number, but a small one */
  2142. + if (a.normal_exp < 0)
  2143. + return 0;
  2144. + if (a.normal_exp > BITS_PER_SI - 1)
  2145. + return MAX_USI_INT;
  2146. + else if (a.normal_exp > (FRACBITS + NGARDS))
  2147. + return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
  2148. + else
  2149. + return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
  2150. +}
  2151. +#endif /* US_SOFTWARE_GOFAST */
  2152. +#endif /* L_sf_to_usi || L_df_to_usi */
  2153. +
  2154. +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
  2155. +FLO_type
  2156. +negate (FLO_type arg_a)
  2157. +{
  2158. + fp_number_type a;
  2159. + FLO_union_type au;
  2160. +
  2161. + au.value = arg_a;
  2162. + unpack_d (&au, &a);
  2163. +
  2164. + flip_sign (&a);
  2165. + return pack_d (&a);
  2166. +}
  2167. +#endif /* L_negate_sf || L_negate_df */
  2168. +
  2169. +#ifdef FLOAT
  2170. +
  2171. +#if defined(L_make_sf)
  2172. +SFtype
  2173. +__make_fp(fp_class_type class,
  2174. + unsigned int sign,
  2175. + int exp,
  2176. + USItype frac)
  2177. +{
  2178. + fp_number_type in;
  2179. +
  2180. + in.class = class;
  2181. + in.sign = sign;
  2182. + in.normal_exp = exp;
  2183. + in.fraction.ll = frac;
  2184. + return pack_d (&in);
  2185. +}
  2186. +#endif /* L_make_sf */
  2187. +
  2188. +#ifndef FLOAT_ONLY
  2189. +
  2190. +/* This enables one to build an fp library that supports float but not double.
  2191. + Otherwise, we would get an undefined reference to __make_dp.
  2192. + This is needed for some 8-bit ports that can't handle well values that
  2193. + are 8-bytes in size, so we just don't support double for them at all. */
  2194. +
  2195. +#if defined(L_sf_to_df)
  2196. +DFtype
  2197. +sf_to_df (SFtype arg_a)
  2198. +{
  2199. + fp_number_type in;
  2200. + FLO_union_type au;
  2201. +
  2202. + au.value = arg_a;
  2203. + unpack_d (&au, &in);
  2204. +
  2205. + return __make_dp (in.class, in.sign, in.normal_exp,
  2206. + ((UDItype) in.fraction.ll) << F_D_BITOFF);
  2207. +}
  2208. +#endif /* L_sf_to_df */
  2209. +
  2210. +#if defined(L_sf_to_tf) && defined(TMODES)
  2211. +TFtype
  2212. +sf_to_tf (SFtype arg_a)
  2213. +{
  2214. + fp_number_type in;
  2215. + FLO_union_type au;
  2216. +
  2217. + au.value = arg_a;
  2218. + unpack_d (&au, &in);
  2219. +
  2220. + return __make_tp (in.class, in.sign, in.normal_exp,
  2221. + ((UTItype) in.fraction.ll) << F_T_BITOFF);
  2222. +}
  2223. +#endif /* L_sf_to_df */
  2224. +
  2225. +#endif /* ! FLOAT_ONLY */
  2226. +#endif /* FLOAT */
  2227. +
  2228. +#ifndef FLOAT
  2229. +
  2230. +extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
  2231. +
  2232. +#if defined(L_make_df)
  2233. +DFtype
  2234. +__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
  2235. +{
  2236. + fp_number_type in;
  2237. +
  2238. + in.class = class;
  2239. + in.sign = sign;
  2240. + in.normal_exp = exp;
  2241. + in.fraction.ll = frac;
  2242. + return pack_d (&in);
  2243. +}
  2244. +#endif /* L_make_df */
  2245. +
  2246. +#if defined(L_df_to_sf)
  2247. +SFtype
  2248. +df_to_sf (DFtype arg_a)
  2249. +{
  2250. + fp_number_type in;
  2251. + USItype sffrac;
  2252. + FLO_union_type au;
  2253. +
  2254. + au.value = arg_a;
  2255. + unpack_d (&au, &in);
  2256. +
  2257. + sffrac = in.fraction.ll >> F_D_BITOFF;
  2258. +
  2259. + /* We set the lowest guard bit in SFFRAC if we discarded any non
  2260. + zero bits. */
  2261. + if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
  2262. + sffrac |= 1;
  2263. +
  2264. + return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
  2265. +}
  2266. +#endif /* L_df_to_sf */
  2267. +
  2268. +#if defined(L_df_to_tf) && defined(TMODES) \
  2269. + && !defined(FLOAT) && !defined(TFLOAT)
  2270. +TFtype
  2271. +df_to_tf (DFtype arg_a)
  2272. +{
  2273. + fp_number_type in;
  2274. + FLO_union_type au;
  2275. +
  2276. + au.value = arg_a;
  2277. + unpack_d (&au, &in);
  2278. +
  2279. + return __make_tp (in.class, in.sign, in.normal_exp,
  2280. + ((UTItype) in.fraction.ll) << D_T_BITOFF);
  2281. +}
  2282. +#endif /* L_sf_to_df */
  2283. +
  2284. +#ifdef TFLOAT
  2285. +#if defined(L_make_tf)
  2286. +TFtype
  2287. +__make_tp(fp_class_type class,
  2288. + unsigned int sign,
  2289. + int exp,
  2290. + UTItype frac)
  2291. +{
  2292. + fp_number_type in;
  2293. +
  2294. + in.class = class;
  2295. + in.sign = sign;
  2296. + in.normal_exp = exp;
  2297. + in.fraction.ll = frac;
  2298. + return pack_d (&in);
  2299. +}
  2300. +#endif /* L_make_tf */
  2301. +
  2302. +#if defined(L_tf_to_df)
  2303. +DFtype
  2304. +tf_to_df (TFtype arg_a)
  2305. +{
  2306. + fp_number_type in;
  2307. + UDItype sffrac;
  2308. + FLO_union_type au;
  2309. +
  2310. + au.value = arg_a;
  2311. + unpack_d (&au, &in);
  2312. +
  2313. + sffrac = in.fraction.ll >> D_T_BITOFF;
  2314. +
  2315. + /* We set the lowest guard bit in SFFRAC if we discarded any non
  2316. + zero bits. */
  2317. + if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
  2318. + sffrac |= 1;
  2319. +
  2320. + return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
  2321. +}
  2322. +#endif /* L_tf_to_df */
  2323. +
  2324. +#if defined(L_tf_to_sf)
  2325. +SFtype
  2326. +tf_to_sf (TFtype arg_a)
  2327. +{
  2328. + fp_number_type in;
  2329. + USItype sffrac;
  2330. + FLO_union_type au;
  2331. +
  2332. + au.value = arg_a;
  2333. + unpack_d (&au, &in);
  2334. +
  2335. + sffrac = in.fraction.ll >> F_T_BITOFF;
  2336. +
  2337. + /* We set the lowest guard bit in SFFRAC if we discarded any non
  2338. + zero bits. */
  2339. + if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
  2340. + sffrac |= 1;
  2341. +
  2342. + return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
  2343. +}
  2344. +#endif /* L_tf_to_sf */
  2345. +#endif /* TFLOAT */
  2346. +
  2347. +#endif /* ! FLOAT */
  2348. +#endif /* !EXTENDED_FLOAT_STUBS */
  2349. diff --git a/gcc/config/nios2/nios2-fp-bit.c b/gcc/config/nios2/nios2-fp-bit.c
  2350. new file mode 100644
  2351. index 0000000..839ffcc
  2352. --- /dev/null
  2353. +++ b/gcc/config/nios2/nios2-fp-bit.c
  2354. @@ -0,0 +1,1655 @@
  2355. +#define FLOAT
  2356. +#ifndef __nios2_big_endian__
  2357. +#define FLOAT_BIT_ORDER_MISMATCH
  2358. +#endif
  2359. +/* This is a software floating point library which can be used
  2360. + for targets without hardware floating point.
  2361. + Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
  2362. + Free Software Foundation, Inc.
  2363. +
  2364. +This file is free software; you can redistribute it and/or modify it
  2365. +under the terms of the GNU General Public License as published by the
  2366. +Free Software Foundation; either version 2, or (at your option) any
  2367. +later version.
  2368. +
  2369. +In addition to the permissions in the GNU General Public License, the
  2370. +Free Software Foundation gives you unlimited permission to link the
  2371. +compiled version of this file with other programs, and to distribute
  2372. +those programs without any restriction coming from the use of this
  2373. +file. (The General Public License restrictions do apply in other
  2374. +respects; for example, they cover modification of the file, and
  2375. +distribution when not linked into another program.)
  2376. +
  2377. +This file is distributed in the hope that it will be useful, but
  2378. +WITHOUT ANY WARRANTY; without even the implied warranty of
  2379. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  2380. +General Public License for more details.
  2381. +
  2382. +You should have received a copy of the GNU General Public License
  2383. +along with this program; see the file COPYING. If not, write to
  2384. +the Free Software Foundation, 59 Temple Place - Suite 330,
  2385. +Boston, MA 02111-1307, USA. */
  2386. +
  2387. +/* As a special exception, if you link this library with other files,
  2388. + some of which are compiled with GCC, to produce an executable,
  2389. + this library does not by itself cause the resulting executable
  2390. + to be covered by the GNU General Public License.
  2391. + This exception does not however invalidate any other reasons why
  2392. + the executable file might be covered by the GNU General Public License. */
  2393. +
  2394. +/* This implements IEEE 754 format arithmetic, but does not provide a
  2395. + mechanism for setting the rounding mode, or for generating or handling
  2396. + exceptions.
  2397. +
  2398. + The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
  2399. + Wilson, all of Cygnus Support. */
  2400. +
  2401. +/* The intended way to use this file is to make two copies, add `#define FLOAT'
  2402. + to one copy, then compile both copies and add them to libgcc.a. */
  2403. +
  2404. +#include "tconfig.h"
  2405. +#include "coretypes.h"
  2406. +#include "tm.h"
  2407. +#include "config/fp-bit.h"
  2408. +
  2409. +/* The following macros can be defined to change the behavior of this file:
  2410. + FLOAT: Implement a `float', aka SFmode, fp library. If this is not
  2411. + defined, then this file implements a `double', aka DFmode, fp library.
  2412. + FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
  2413. + don't include float->double conversion which requires the double library.
  2414. + This is useful only for machines which can't support doubles, e.g. some
  2415. + 8-bit processors.
  2416. + CMPtype: Specify the type that floating point compares should return.
  2417. + This defaults to SItype, aka int.
  2418. + US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
  2419. + US Software goFast library.
  2420. + _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
  2421. + two integers to the FLO_union_type.
  2422. + NO_DENORMALS: Disable handling of denormals.
  2423. + NO_NANS: Disable nan and infinity handling
  2424. + SMALL_MACHINE: Useful when operations on QIs and HIs are faster
  2425. + than on an SI */
  2426. +
  2427. +/* We don't currently support extended floats (long doubles) on machines
  2428. + without hardware to deal with them.
  2429. +
  2430. + These stubs are just to keep the linker from complaining about unresolved
  2431. + references which can be pulled in from libio & libstdc++, even if the
  2432. + user isn't using long doubles. However, they may generate an unresolved
  2433. + external to abort if abort is not used by the function, and the stubs
  2434. + are referenced from within libc, since libgcc goes before and after the
  2435. + system library. */
  2436. +
  2437. +#ifdef DECLARE_LIBRARY_RENAMES
  2438. + DECLARE_LIBRARY_RENAMES
  2439. +#endif
  2440. +
  2441. +#ifdef EXTENDED_FLOAT_STUBS
  2442. +extern void abort (void);
  2443. +void __extendsfxf2 (void) { abort(); }
  2444. +void __extenddfxf2 (void) { abort(); }
  2445. +void __truncxfdf2 (void) { abort(); }
  2446. +void __truncxfsf2 (void) { abort(); }
  2447. +void __fixxfsi (void) { abort(); }
  2448. +void __floatsixf (void) { abort(); }
  2449. +void __addxf3 (void) { abort(); }
  2450. +void __subxf3 (void) { abort(); }
  2451. +void __mulxf3 (void) { abort(); }
  2452. +void __divxf3 (void) { abort(); }
  2453. +void __negxf2 (void) { abort(); }
  2454. +void __eqxf2 (void) { abort(); }
  2455. +void __nexf2 (void) { abort(); }
  2456. +void __gtxf2 (void) { abort(); }
  2457. +void __gexf2 (void) { abort(); }
  2458. +void __lexf2 (void) { abort(); }
  2459. +void __ltxf2 (void) { abort(); }
  2460. +
  2461. +void __extendsftf2 (void) { abort(); }
  2462. +void __extenddftf2 (void) { abort(); }
  2463. +void __trunctfdf2 (void) { abort(); }
  2464. +void __trunctfsf2 (void) { abort(); }
  2465. +void __fixtfsi (void) { abort(); }
  2466. +void __floatsitf (void) { abort(); }
  2467. +void __addtf3 (void) { abort(); }
  2468. +void __subtf3 (void) { abort(); }
  2469. +void __multf3 (void) { abort(); }
  2470. +void __divtf3 (void) { abort(); }
  2471. +void __negtf2 (void) { abort(); }
  2472. +void __eqtf2 (void) { abort(); }
  2473. +void __netf2 (void) { abort(); }
  2474. +void __gttf2 (void) { abort(); }
  2475. +void __getf2 (void) { abort(); }
  2476. +void __letf2 (void) { abort(); }
  2477. +void __lttf2 (void) { abort(); }
  2478. +#else /* !EXTENDED_FLOAT_STUBS, rest of file */
  2479. +
  2480. +/* IEEE "special" number predicates */
  2481. +
  2482. +#ifdef NO_NANS
  2483. +
  2484. +#define nan() 0
  2485. +#define isnan(x) 0
  2486. +#define isinf(x) 0
  2487. +#else
  2488. +
  2489. +#if defined L_thenan_sf
  2490. +const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
  2491. +#elif defined L_thenan_df
  2492. +const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
  2493. +#elif defined L_thenan_tf
  2494. +const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
  2495. +#elif defined TFLOAT
  2496. +extern const fp_number_type __thenan_tf;
  2497. +#elif defined FLOAT
  2498. +extern const fp_number_type __thenan_sf;
  2499. +#else
  2500. +extern const fp_number_type __thenan_df;
  2501. +#endif
  2502. +
  2503. +INLINE
  2504. +static fp_number_type *
  2505. +nan (void)
  2506. +{
  2507. + /* Discard the const qualifier... */
  2508. +#ifdef TFLOAT
  2509. + return (fp_number_type *) (& __thenan_tf);
  2510. +#elif defined FLOAT
  2511. + return (fp_number_type *) (& __thenan_sf);
  2512. +#else
  2513. + return (fp_number_type *) (& __thenan_df);
  2514. +#endif
  2515. +}
  2516. +
  2517. +INLINE
  2518. +static int
  2519. +isnan ( fp_number_type * x)
  2520. +{
  2521. + return x->class == CLASS_SNAN || x->class == CLASS_QNAN;
  2522. +}
  2523. +
  2524. +INLINE
  2525. +static int
  2526. +isinf ( fp_number_type * x)
  2527. +{
  2528. + return x->class == CLASS_INFINITY;
  2529. +}
  2530. +
  2531. +#endif /* NO_NANS */
  2532. +
  2533. +INLINE
  2534. +static int
  2535. +iszero ( fp_number_type * x)
  2536. +{
  2537. + return x->class == CLASS_ZERO;
  2538. +}
  2539. +
  2540. +INLINE
  2541. +static void
  2542. +flip_sign ( fp_number_type * x)
  2543. +{
  2544. + x->sign = !x->sign;
  2545. +}
  2546. +
  2547. +extern FLO_type pack_d ( fp_number_type * );
  2548. +
  2549. +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
  2550. +FLO_type
  2551. +pack_d ( fp_number_type * src)
  2552. +{
  2553. + FLO_union_type dst;
  2554. + fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
  2555. + int sign = src->sign;
  2556. + int exp = 0;
  2557. +
  2558. + if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
  2559. + {
  2560. + /* We can't represent these values accurately. By using the
  2561. + largest possible magnitude, we guarantee that the conversion
  2562. + of infinity is at least as big as any finite number. */
  2563. + exp = EXPMAX;
  2564. + fraction = ((fractype) 1 << FRACBITS) - 1;
  2565. + }
  2566. + else if (isnan (src))
  2567. + {
  2568. + exp = EXPMAX;
  2569. + if (src->class == CLASS_QNAN || 1)
  2570. + {
  2571. +#ifdef QUIET_NAN_NEGATED
  2572. + fraction |= QUIET_NAN - 1;
  2573. +#else
  2574. + fraction |= QUIET_NAN;
  2575. +#endif
  2576. + }
  2577. + }
  2578. + else if (isinf (src))
  2579. + {
  2580. + exp = EXPMAX;
  2581. + fraction = 0;
  2582. + }
  2583. + else if (iszero (src))
  2584. + {
  2585. + exp = 0;
  2586. + fraction = 0;
  2587. + }
  2588. + else if (fraction == 0)
  2589. + {
  2590. + exp = 0;
  2591. + }
  2592. + else
  2593. + {
  2594. + if (src->normal_exp < NORMAL_EXPMIN)
  2595. + {
  2596. +#ifdef NO_DENORMALS
  2597. + /* Go straight to a zero representation if denormals are not
  2598. + supported. The denormal handling would be harmless but
  2599. + isn't unnecessary. */
  2600. + exp = 0;
  2601. + fraction = 0;
  2602. +#else /* NO_DENORMALS */
  2603. + /* This number's exponent is too low to fit into the bits
  2604. + available in the number, so we'll store 0 in the exponent and
  2605. + shift the fraction to the right to make up for it. */
  2606. +
  2607. + int shift = NORMAL_EXPMIN - src->normal_exp;
  2608. +
  2609. + exp = 0;
  2610. +
  2611. + if (shift > FRAC_NBITS - NGARDS)
  2612. + {
  2613. + /* No point shifting, since it's more that 64 out. */
  2614. + fraction = 0;
  2615. + }
  2616. + else
  2617. + {
  2618. + int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
  2619. + fraction = (fraction >> shift) | lowbit;
  2620. + }
  2621. + if ((fraction & GARDMASK) == GARDMSB)
  2622. + {
  2623. + if ((fraction & (1 << NGARDS)))
  2624. + fraction += GARDROUND + 1;
  2625. + }
  2626. + else
  2627. + {
  2628. + /* Add to the guards to round up. */
  2629. + fraction += GARDROUND;
  2630. + }
  2631. + /* Perhaps the rounding means we now need to change the
  2632. + exponent, because the fraction is no longer denormal. */
  2633. + if (fraction >= IMPLICIT_1)
  2634. + {
  2635. + exp += 1;
  2636. + }
  2637. + fraction >>= NGARDS;
  2638. +#endif /* NO_DENORMALS */
  2639. + }
  2640. + else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
  2641. + && src->normal_exp > EXPBIAS)
  2642. + {
  2643. + exp = EXPMAX;
  2644. + fraction = 0;
  2645. + }
  2646. + else
  2647. + {
  2648. + exp = src->normal_exp + EXPBIAS;
  2649. + if (!ROUND_TOWARDS_ZERO)
  2650. + {
  2651. + /* IF the gard bits are the all zero, but the first, then we're
  2652. + half way between two numbers, choose the one which makes the
  2653. + lsb of the answer 0. */
  2654. + if ((fraction & GARDMASK) == GARDMSB)
  2655. + {
  2656. + if (fraction & (1 << NGARDS))
  2657. + fraction += GARDROUND + 1;
  2658. + }
  2659. + else
  2660. + {
  2661. + /* Add a one to the guards to round up */
  2662. + fraction += GARDROUND;
  2663. + }
  2664. + if (fraction >= IMPLICIT_2)
  2665. + {
  2666. + fraction >>= 1;
  2667. + exp += 1;
  2668. + }
  2669. + }
  2670. + fraction >>= NGARDS;
  2671. +
  2672. + if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
  2673. + {
  2674. + /* Saturate on overflow. */
  2675. + exp = EXPMAX;
  2676. + fraction = ((fractype) 1 << FRACBITS) - 1;
  2677. + }
  2678. + }
  2679. + }
  2680. +
  2681. + /* We previously used bitfields to store the number, but this doesn't
  2682. + handle little/big endian systems conveniently, so use shifts and
  2683. + masks */
  2684. +#ifdef FLOAT_BIT_ORDER_MISMATCH
  2685. + dst.bits.fraction = fraction;
  2686. + dst.bits.exp = exp;
  2687. + dst.bits.sign = sign;
  2688. +#else
  2689. +# if defined TFLOAT && defined HALFFRACBITS
  2690. + {
  2691. + halffractype high, low, unity;
  2692. + int lowsign, lowexp;
  2693. +
  2694. + unity = (halffractype) 1 << HALFFRACBITS;
  2695. +
  2696. + /* Set HIGH to the high double's significand, masking out the implicit 1.
  2697. + Set LOW to the low double's full significand. */
  2698. + high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
  2699. + low = fraction & (unity * 2 - 1);
  2700. +
  2701. + /* Get the initial sign and exponent of the low double. */
  2702. + lowexp = exp - HALFFRACBITS - 1;
  2703. + lowsign = sign;
  2704. +
  2705. + /* HIGH should be rounded like a normal double, making |LOW| <=
  2706. + 0.5 ULP of HIGH. Assume round-to-nearest. */
  2707. + if (exp < EXPMAX)
  2708. + if (low > unity || (low == unity && (high & 1) == 1))
  2709. + {
  2710. + /* Round HIGH up and adjust LOW to match. */
  2711. + high++;
  2712. + if (high == unity)
  2713. + {
  2714. + /* May make it infinite, but that's OK. */
  2715. + high = 0;
  2716. + exp++;
  2717. + }
  2718. + low = unity * 2 - low;
  2719. + lowsign ^= 1;
  2720. + }
  2721. +
  2722. + high |= (halffractype) exp << HALFFRACBITS;
  2723. + high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
  2724. +
  2725. + if (exp == EXPMAX || exp == 0 || low == 0)
  2726. + low = 0;
  2727. + else
  2728. + {
  2729. + while (lowexp > 0 && low < unity)
  2730. + {
  2731. + low <<= 1;
  2732. + lowexp--;
  2733. + }
  2734. +
  2735. + if (lowexp <= 0)
  2736. + {
  2737. + halffractype roundmsb, round;
  2738. + int shift;
  2739. +
  2740. + shift = 1 - lowexp;
  2741. + roundmsb = (1 << (shift - 1));
  2742. + round = low & ((roundmsb << 1) - 1);
  2743. +
  2744. + low >>= shift;
  2745. + lowexp = 0;
  2746. +
  2747. + if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
  2748. + {
  2749. + low++;
  2750. + if (low == unity)
  2751. + /* LOW rounds up to the smallest normal number. */
  2752. + lowexp++;
  2753. + }
  2754. + }
  2755. +
  2756. + low &= unity - 1;
  2757. + low |= (halffractype) lowexp << HALFFRACBITS;
  2758. + low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
  2759. + }
  2760. + dst.value_raw = ((fractype) high << HALFSHIFT) | low;
  2761. + }
  2762. +# else
  2763. + dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
  2764. + dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
  2765. + dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
  2766. +# endif
  2767. +#endif
  2768. +
  2769. +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
  2770. +#ifdef TFLOAT
  2771. + {
  2772. + qrtrfractype tmp1 = dst.words[0];
  2773. + qrtrfractype tmp2 = dst.words[1];
  2774. + dst.words[0] = dst.words[3];
  2775. + dst.words[1] = dst.words[2];
  2776. + dst.words[2] = tmp2;
  2777. + dst.words[3] = tmp1;
  2778. + }
  2779. +#else
  2780. + {
  2781. + halffractype tmp = dst.words[0];
  2782. + dst.words[0] = dst.words[1];
  2783. + dst.words[1] = tmp;
  2784. + }
  2785. +#endif
  2786. +#endif
  2787. +
  2788. + return dst.value;
  2789. +}
  2790. +#endif
  2791. +
  2792. +#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
  2793. +void
  2794. +unpack_d (FLO_union_type * src, fp_number_type * dst)
  2795. +{
  2796. + /* We previously used bitfields to store the number, but this doesn't
  2797. + handle little/big endian systems conveniently, so use shifts and
  2798. + masks */
  2799. + fractype fraction;
  2800. + int exp;
  2801. + int sign;
  2802. +
  2803. +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
  2804. + FLO_union_type swapped;
  2805. +
  2806. +#ifdef TFLOAT
  2807. + swapped.words[0] = src->words[3];
  2808. + swapped.words[1] = src->words[2];
  2809. + swapped.words[2] = src->words[1];
  2810. + swapped.words[3] = src->words[0];
  2811. +#else
  2812. + swapped.words[0] = src->words[1];
  2813. + swapped.words[1] = src->words[0];
  2814. +#endif
  2815. + src = &swapped;
  2816. +#endif
  2817. +
  2818. +#ifdef FLOAT_BIT_ORDER_MISMATCH
  2819. + fraction = src->bits.fraction;
  2820. + exp = src->bits.exp;
  2821. + sign = src->bits.sign;
  2822. +#else
  2823. +# if defined TFLOAT && defined HALFFRACBITS
  2824. + {
  2825. + halffractype high, low;
  2826. +
  2827. + high = src->value_raw >> HALFSHIFT;
  2828. + low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
  2829. +
  2830. + fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
  2831. + fraction <<= FRACBITS - HALFFRACBITS;
  2832. + exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
  2833. + sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
  2834. +
  2835. + if (exp != EXPMAX && exp != 0 && low != 0)
  2836. + {
  2837. + int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
  2838. + int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
  2839. + int shift;
  2840. + fractype xlow;
  2841. +
  2842. + xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
  2843. + if (lowexp)
  2844. + xlow |= (((halffractype)1) << HALFFRACBITS);
  2845. + else
  2846. + lowexp = 1;
  2847. + shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
  2848. + if (shift > 0)
  2849. + xlow <<= shift;
  2850. + else if (shift < 0)
  2851. + xlow >>= -shift;
  2852. + if (sign == lowsign)
  2853. + fraction += xlow;
  2854. + else if (fraction >= xlow)
  2855. + fraction -= xlow;
  2856. + else
  2857. + {
  2858. + /* The high part is a power of two but the full number is lower.
  2859. + This code will leave the implicit 1 in FRACTION, but we'd
  2860. + have added that below anyway. */
  2861. + fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
  2862. + exp--;
  2863. + }
  2864. + }
  2865. + }
  2866. +# else
  2867. + fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
  2868. + exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
  2869. + sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
  2870. +# endif
  2871. +#endif
  2872. +
  2873. + dst->sign = sign;
  2874. + if (exp == 0)
  2875. + {
  2876. + /* Hmm. Looks like 0 */
  2877. + if (fraction == 0
  2878. +#ifdef NO_DENORMALS
  2879. + || 1
  2880. +#endif
  2881. + )
  2882. + {
  2883. + /* tastes like zero */
  2884. + dst->class = CLASS_ZERO;
  2885. + }
  2886. + else
  2887. + {
  2888. + /* Zero exponent with nonzero fraction - it's denormalized,
  2889. + so there isn't a leading implicit one - we'll shift it so
  2890. + it gets one. */
  2891. + dst->normal_exp = exp - EXPBIAS + 1;
  2892. + fraction <<= NGARDS;
  2893. +
  2894. + dst->class = CLASS_NUMBER;
  2895. +#if 1
  2896. + while (fraction < IMPLICIT_1)
  2897. + {
  2898. + fraction <<= 1;
  2899. + dst->normal_exp--;
  2900. + }
  2901. +#endif
  2902. + dst->fraction.ll = fraction;
  2903. + }
  2904. + }
  2905. + else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp == EXPMAX)
  2906. + {
  2907. + /* Huge exponent*/
  2908. + if (fraction == 0)
  2909. + {
  2910. + /* Attached to a zero fraction - means infinity */
  2911. + dst->class = CLASS_INFINITY;
  2912. + }
  2913. + else
  2914. + {
  2915. + /* Nonzero fraction, means nan */
  2916. +#ifdef QUIET_NAN_NEGATED
  2917. + if ((fraction & QUIET_NAN) == 0)
  2918. +#else
  2919. + if (fraction & QUIET_NAN)
  2920. +#endif
  2921. + {
  2922. + dst->class = CLASS_QNAN;
  2923. + }
  2924. + else
  2925. + {
  2926. + dst->class = CLASS_SNAN;
  2927. + }
  2928. + /* Keep the fraction part as the nan number */
  2929. + dst->fraction.ll = fraction;
  2930. + }
  2931. + }
  2932. + else
  2933. + {
  2934. + /* Nothing strange about this number */
  2935. + dst->normal_exp = exp - EXPBIAS;
  2936. + dst->class = CLASS_NUMBER;
  2937. + dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
  2938. + }
  2939. +}
  2940. +#endif /* L_unpack_df || L_unpack_sf */
  2941. +
  2942. +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
  2943. +static fp_number_type *
  2944. +_fpadd_parts (fp_number_type * a,
  2945. + fp_number_type * b,
  2946. + fp_number_type * tmp)
  2947. +{
  2948. + intfrac tfraction;
  2949. +
  2950. + /* Put commonly used fields in local variables. */
  2951. + int a_normal_exp;
  2952. + int b_normal_exp;
  2953. + fractype a_fraction;
  2954. + fractype b_fraction;
  2955. +
  2956. + if (isnan (a))
  2957. + {
  2958. + return a;
  2959. + }
  2960. + if (isnan (b))
  2961. + {
  2962. + return b;
  2963. + }
  2964. + if (isinf (a))
  2965. + {
  2966. + /* Adding infinities with opposite signs yields a NaN. */
  2967. + if (isinf (b) && a->sign != b->sign)
  2968. + return nan ();
  2969. + return a;
  2970. + }
  2971. + if (isinf (b))
  2972. + {
  2973. + return b;
  2974. + }
  2975. + if (iszero (b))
  2976. + {
  2977. + if (iszero (a))
  2978. + {
  2979. + *tmp = *a;
  2980. + tmp->sign = a->sign & b->sign;
  2981. + return tmp;
  2982. + }
  2983. + return a;
  2984. + }
  2985. + if (iszero (a))
  2986. + {
  2987. + return b;
  2988. + }
  2989. +
  2990. + /* Got two numbers. shift the smaller and increment the exponent till
  2991. + they're the same */
  2992. + {
  2993. + int diff;
  2994. +
  2995. + a_normal_exp = a->normal_exp;
  2996. + b_normal_exp = b->normal_exp;
  2997. + a_fraction = a->fraction.ll;
  2998. + b_fraction = b->fraction.ll;
  2999. +
  3000. + diff = a_normal_exp - b_normal_exp;
  3001. +
  3002. + if (diff < 0)
  3003. + diff = -diff;
  3004. + if (diff < FRAC_NBITS)
  3005. + {
  3006. + /* ??? This does shifts one bit at a time. Optimize. */
  3007. + while (a_normal_exp > b_normal_exp)
  3008. + {
  3009. + b_normal_exp++;
  3010. + LSHIFT (b_fraction);
  3011. + }
  3012. + while (b_normal_exp > a_normal_exp)
  3013. + {
  3014. + a_normal_exp++;
  3015. + LSHIFT (a_fraction);
  3016. + }
  3017. + }
  3018. + else
  3019. + {
  3020. + /* Somethings's up.. choose the biggest */
  3021. + if (a_normal_exp > b_normal_exp)
  3022. + {
  3023. + b_normal_exp = a_normal_exp;
  3024. + b_fraction = 0;
  3025. + }
  3026. + else
  3027. + {
  3028. + a_normal_exp = b_normal_exp;
  3029. + a_fraction = 0;
  3030. + }
  3031. + }
  3032. + }
  3033. +
  3034. + if (a->sign != b->sign)
  3035. + {
  3036. + if (a->sign)
  3037. + {
  3038. + tfraction = -a_fraction + b_fraction;
  3039. + }
  3040. + else
  3041. + {
  3042. + tfraction = a_fraction - b_fraction;
  3043. + }
  3044. + if (tfraction >= 0)
  3045. + {
  3046. + tmp->sign = 0;
  3047. + tmp->normal_exp = a_normal_exp;
  3048. + tmp->fraction.ll = tfraction;
  3049. + }
  3050. + else
  3051. + {
  3052. + tmp->sign = 1;
  3053. + tmp->normal_exp = a_normal_exp;
  3054. + tmp->fraction.ll = -tfraction;
  3055. + }
  3056. + /* and renormalize it */
  3057. +
  3058. + while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
  3059. + {
  3060. + tmp->fraction.ll <<= 1;
  3061. + tmp->normal_exp--;
  3062. + }
  3063. + }
  3064. + else
  3065. + {
  3066. + tmp->sign = a->sign;
  3067. + tmp->normal_exp = a_normal_exp;
  3068. + tmp->fraction.ll = a_fraction + b_fraction;
  3069. + }
  3070. + tmp->class = CLASS_NUMBER;
  3071. + /* Now the fraction is added, we have to shift down to renormalize the
  3072. + number */
  3073. +
  3074. + if (tmp->fraction.ll >= IMPLICIT_2)
  3075. + {
  3076. + LSHIFT (tmp->fraction.ll);
  3077. + tmp->normal_exp++;
  3078. + }
  3079. + return tmp;
  3080. +
  3081. +}
  3082. +
  3083. +FLO_type
  3084. +add (FLO_type arg_a, FLO_type arg_b)
  3085. +{
  3086. + fp_number_type a;
  3087. + fp_number_type b;
  3088. + fp_number_type tmp;
  3089. + fp_number_type *res;
  3090. + FLO_union_type au, bu;
  3091. +
  3092. + au.value = arg_a;
  3093. + bu.value = arg_b;
  3094. +
  3095. + unpack_d (&au, &a);
  3096. + unpack_d (&bu, &b);
  3097. +
  3098. + res = _fpadd_parts (&a, &b, &tmp);
  3099. +
  3100. + return pack_d (res);
  3101. +}
  3102. +
  3103. +FLO_type
  3104. +sub (FLO_type arg_a, FLO_type arg_b)
  3105. +{
  3106. + fp_number_type a;
  3107. + fp_number_type b;
  3108. + fp_number_type tmp;
  3109. + fp_number_type *res;
  3110. + FLO_union_type au, bu;
  3111. +
  3112. + au.value = arg_a;
  3113. + bu.value = arg_b;
  3114. +
  3115. + unpack_d (&au, &a);
  3116. + unpack_d (&bu, &b);
  3117. +
  3118. + b.sign ^= 1;
  3119. +
  3120. + res = _fpadd_parts (&a, &b, &tmp);
  3121. +
  3122. + return pack_d (res);
  3123. +}
  3124. +#endif /* L_addsub_sf || L_addsub_df */
  3125. +
  3126. +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
  3127. +static inline __attribute__ ((__always_inline__)) fp_number_type *
  3128. +_fpmul_parts ( fp_number_type * a,
  3129. + fp_number_type * b,
  3130. + fp_number_type * tmp)
  3131. +{
  3132. + fractype low = 0;
  3133. + fractype high = 0;
  3134. +
  3135. + if (isnan (a))
  3136. + {
  3137. + a->sign = a->sign != b->sign;
  3138. + return a;
  3139. + }
  3140. + if (isnan (b))
  3141. + {
  3142. + b->sign = a->sign != b->sign;
  3143. + return b;
  3144. + }
  3145. + if (isinf (a))
  3146. + {
  3147. + if (iszero (b))
  3148. + return nan ();
  3149. + a->sign = a->sign != b->sign;
  3150. + return a;
  3151. + }
  3152. + if (isinf (b))
  3153. + {
  3154. + if (iszero (a))
  3155. + {
  3156. + return nan ();
  3157. + }
  3158. + b->sign = a->sign != b->sign;
  3159. + return b;
  3160. + }
  3161. + if (iszero (a))
  3162. + {
  3163. + a->sign = a->sign != b->sign;
  3164. + return a;
  3165. + }
  3166. + if (iszero (b))
  3167. + {
  3168. + b->sign = a->sign != b->sign;
  3169. + return b;
  3170. + }
  3171. +
  3172. + /* Calculate the mantissa by multiplying both numbers to get a
  3173. + twice-as-wide number. */
  3174. + {
  3175. +#if defined(NO_DI_MODE) || defined(TFLOAT)
  3176. + {
  3177. + fractype x = a->fraction.ll;
  3178. + fractype ylow = b->fraction.ll;
  3179. + fractype yhigh = 0;
  3180. + int bit;
  3181. +
  3182. + /* ??? This does multiplies one bit at a time. Optimize. */
  3183. + for (bit = 0; bit < FRAC_NBITS; bit++)
  3184. + {
  3185. + int carry;
  3186. +
  3187. + if (x & 1)
  3188. + {
  3189. + carry = (low += ylow) < ylow;
  3190. + high += yhigh + carry;
  3191. + }
  3192. + yhigh <<= 1;
  3193. + if (ylow & FRACHIGH)
  3194. + {
  3195. + yhigh |= 1;
  3196. + }
  3197. + ylow <<= 1;
  3198. + x >>= 1;
  3199. + }
  3200. + }
  3201. +#elif defined(FLOAT)
  3202. + /* Multiplying two USIs to get a UDI, we're safe. */
  3203. + {
  3204. + UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
  3205. +
  3206. + high = answer >> BITS_PER_SI;
  3207. + low = answer;
  3208. + }
  3209. +#else
  3210. + /* fractype is DImode, but we need the result to be twice as wide.
  3211. + Assuming a widening multiply from DImode to TImode is not
  3212. + available, build one by hand. */
  3213. + {
  3214. + USItype nl = a->fraction.ll;
  3215. + USItype nh = a->fraction.ll >> BITS_PER_SI;
  3216. + USItype ml = b->fraction.ll;
  3217. + USItype mh = b->fraction.ll >> BITS_PER_SI;
  3218. + UDItype pp_ll = (UDItype) ml * nl;
  3219. + UDItype pp_hl = (UDItype) mh * nl;
  3220. + UDItype pp_lh = (UDItype) ml * nh;
  3221. + UDItype pp_hh = (UDItype) mh * nh;
  3222. + UDItype res2 = 0;
  3223. + UDItype res0 = 0;
  3224. + UDItype ps_hh__ = pp_hl + pp_lh;
  3225. + if (ps_hh__ < pp_hl)
  3226. + res2 += (UDItype)1 << BITS_PER_SI;
  3227. + pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
  3228. + res0 = pp_ll + pp_hl;
  3229. + if (res0 < pp_ll)
  3230. + res2++;
  3231. + res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
  3232. + high = res2;
  3233. + low = res0;
  3234. + }
  3235. +#endif
  3236. + }
  3237. +
  3238. + tmp->normal_exp = a->normal_exp + b->normal_exp
  3239. + + FRAC_NBITS - (FRACBITS + NGARDS);
  3240. + tmp->sign = a->sign != b->sign;
  3241. + while (high >= IMPLICIT_2)
  3242. + {
  3243. + tmp->normal_exp++;
  3244. + if (high & 1)
  3245. + {
  3246. + low >>= 1;
  3247. + low |= FRACHIGH;
  3248. + }
  3249. + high >>= 1;
  3250. + }
  3251. + while (high < IMPLICIT_1)
  3252. + {
  3253. + tmp->normal_exp--;
  3254. +
  3255. + high <<= 1;
  3256. + if (low & FRACHIGH)
  3257. + high |= 1;
  3258. + low <<= 1;
  3259. + }
  3260. + /* rounding is tricky. if we only round if it won't make us round later. */
  3261. +#if 0
  3262. + if (low & FRACHIGH2)
  3263. + {
  3264. + if (((high & GARDMASK) != GARDMSB)
  3265. + && (((high + 1) & GARDMASK) == GARDMSB))
  3266. + {
  3267. + /* don't round, it gets done again later. */
  3268. + }
  3269. + else
  3270. + {
  3271. + high++;
  3272. + }
  3273. + }
  3274. +#endif
  3275. + if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
  3276. + {
  3277. + if (high & (1 << NGARDS))
  3278. + {
  3279. + /* half way, so round to even */
  3280. + high += GARDROUND + 1;
  3281. + }
  3282. + else if (low)
  3283. + {
  3284. + /* but we really weren't half way */
  3285. + high += GARDROUND + 1;
  3286. + }
  3287. + }
  3288. + tmp->fraction.ll = high;
  3289. + tmp->class = CLASS_NUMBER;
  3290. + return tmp;
  3291. +}
  3292. +
  3293. +FLO_type
  3294. +multiply (FLO_type arg_a, FLO_type arg_b)
  3295. +{
  3296. + fp_number_type a;
  3297. + fp_number_type b;
  3298. + fp_number_type tmp;
  3299. + fp_number_type *res;
  3300. + FLO_union_type au, bu;
  3301. +
  3302. + au.value = arg_a;
  3303. + bu.value = arg_b;
  3304. +
  3305. + unpack_d (&au, &a);
  3306. + unpack_d (&bu, &b);
  3307. +
  3308. + res = _fpmul_parts (&a, &b, &tmp);
  3309. +
  3310. + return pack_d (res);
  3311. +}
  3312. +#endif /* L_mul_sf || L_mul_df */
  3313. +
  3314. +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
  3315. +static inline __attribute__ ((__always_inline__)) fp_number_type *
  3316. +_fpdiv_parts (fp_number_type * a,
  3317. + fp_number_type * b)
  3318. +{
  3319. + fractype bit;
  3320. + fractype numerator;
  3321. + fractype denominator;
  3322. + fractype quotient;
  3323. +
  3324. + if (isnan (a))
  3325. + {
  3326. + return a;
  3327. + }
  3328. + if (isnan (b))
  3329. + {
  3330. + return b;
  3331. + }
  3332. +
  3333. + a->sign = a->sign ^ b->sign;
  3334. +
  3335. + if (isinf (a) || iszero (a))
  3336. + {
  3337. + if (a->class == b->class)
  3338. + return nan ();
  3339. + return a;
  3340. + }
  3341. +
  3342. + if (isinf (b))
  3343. + {
  3344. + a->fraction.ll = 0;
  3345. + a->normal_exp = 0;
  3346. + return a;
  3347. + }
  3348. + if (iszero (b))
  3349. + {
  3350. + a->class = CLASS_INFINITY;
  3351. + return a;
  3352. + }
  3353. +
  3354. + /* Calculate the mantissa by multiplying both 64bit numbers to get a
  3355. + 128 bit number */
  3356. + {
  3357. + /* quotient =
  3358. + ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
  3359. + */
  3360. +
  3361. + a->normal_exp = a->normal_exp - b->normal_exp;
  3362. + numerator = a->fraction.ll;
  3363. + denominator = b->fraction.ll;
  3364. +
  3365. + if (numerator < denominator)
  3366. + {
  3367. + /* Fraction will be less than 1.0 */
  3368. + numerator *= 2;
  3369. + a->normal_exp--;
  3370. + }
  3371. + bit = IMPLICIT_1;
  3372. + quotient = 0;
  3373. + /* ??? Does divide one bit at a time. Optimize. */
  3374. + while (bit)
  3375. + {
  3376. + if (numerator >= denominator)
  3377. + {
  3378. + quotient |= bit;
  3379. + numerator -= denominator;
  3380. + }
  3381. + bit >>= 1;
  3382. + numerator *= 2;
  3383. + }
  3384. +
  3385. + if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
  3386. + {
  3387. + if (quotient & (1 << NGARDS))
  3388. + {
  3389. + /* half way, so round to even */
  3390. + quotient += GARDROUND + 1;
  3391. + }
  3392. + else if (numerator)
  3393. + {
  3394. + /* but we really weren't half way, more bits exist */
  3395. + quotient += GARDROUND + 1;
  3396. + }
  3397. + }
  3398. +
  3399. + a->fraction.ll = quotient;
  3400. + return (a);
  3401. + }
  3402. +}
  3403. +
  3404. +FLO_type
  3405. +divide (FLO_type arg_a, FLO_type arg_b)
  3406. +{
  3407. + fp_number_type a;
  3408. + fp_number_type b;
  3409. + fp_number_type *res;
  3410. + FLO_union_type au, bu;
  3411. +
  3412. + au.value = arg_a;
  3413. + bu.value = arg_b;
  3414. +
  3415. + unpack_d (&au, &a);
  3416. + unpack_d (&bu, &b);
  3417. +
  3418. + res = _fpdiv_parts (&a, &b);
  3419. +
  3420. + return pack_d (res);
  3421. +}
  3422. +#endif /* L_div_sf || L_div_df */
  3423. +
  3424. +#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
  3425. + || defined(L_fpcmp_parts_tf)
  3426. +/* according to the demo, fpcmp returns a comparison with 0... thus
  3427. + a<b -> -1
  3428. + a==b -> 0
  3429. + a>b -> +1
  3430. + */
  3431. +
  3432. +int
  3433. +__fpcmp_parts (fp_number_type * a, fp_number_type * b)
  3434. +{
  3435. +#if 0
  3436. + /* either nan -> unordered. Must be checked outside of this routine. */
  3437. + if (isnan (a) && isnan (b))
  3438. + {
  3439. + return 1; /* still unordered! */
  3440. + }
  3441. +#endif
  3442. +
  3443. + if (isnan (a) || isnan (b))
  3444. + {
  3445. + return 1; /* how to indicate unordered compare? */
  3446. + }
  3447. + if (isinf (a) && isinf (b))
  3448. + {
  3449. + /* +inf > -inf, but +inf != +inf */
  3450. + /* b \a| +inf(0)| -inf(1)
  3451. + ______\+--------+--------
  3452. + +inf(0)| a==b(0)| a<b(-1)
  3453. + -------+--------+--------
  3454. + -inf(1)| a>b(1) | a==b(0)
  3455. + -------+--------+--------
  3456. + So since unordered must be nonzero, just line up the columns...
  3457. + */
  3458. + return b->sign - a->sign;
  3459. + }
  3460. + /* but not both... */
  3461. + if (isinf (a))
  3462. + {
  3463. + return a->sign ? -1 : 1;
  3464. + }
  3465. + if (isinf (b))
  3466. + {
  3467. + return b->sign ? 1 : -1;
  3468. + }
  3469. + if (iszero (a) && iszero (b))
  3470. + {
  3471. + return 0;
  3472. + }
  3473. + if (iszero (a))
  3474. + {
  3475. + return b->sign ? 1 : -1;
  3476. + }
  3477. + if (iszero (b))
  3478. + {
  3479. + return a->sign ? -1 : 1;
  3480. + }
  3481. + /* now both are "normal". */
  3482. + if (a->sign != b->sign)
  3483. + {
  3484. + /* opposite signs */
  3485. + return a->sign ? -1 : 1;
  3486. + }
  3487. + /* same sign; exponents? */
  3488. + if (a->normal_exp > b->normal_exp)
  3489. + {
  3490. + return a->sign ? -1 : 1;
  3491. + }
  3492. + if (a->normal_exp < b->normal_exp)
  3493. + {
  3494. + return a->sign ? 1 : -1;
  3495. + }
  3496. + /* same exponents; check size. */
  3497. + if (a->fraction.ll > b->fraction.ll)
  3498. + {
  3499. + return a->sign ? -1 : 1;
  3500. + }
  3501. + if (a->fraction.ll < b->fraction.ll)
  3502. + {
  3503. + return a->sign ? 1 : -1;
  3504. + }
  3505. + /* after all that, they're equal. */
  3506. + return 0;
  3507. +}
  3508. +#endif
  3509. +
  3510. +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
  3511. +CMPtype
  3512. +compare (FLO_type arg_a, FLO_type arg_b)
  3513. +{
  3514. + fp_number_type a;
  3515. + fp_number_type b;
  3516. + FLO_union_type au, bu;
  3517. +
  3518. + au.value = arg_a;
  3519. + bu.value = arg_b;
  3520. +
  3521. + unpack_d (&au, &a);
  3522. + unpack_d (&bu, &b);
  3523. +
  3524. + return __fpcmp_parts (&a, &b);
  3525. +}
  3526. +#endif /* L_compare_sf || L_compare_df */
  3527. +
  3528. +#ifndef US_SOFTWARE_GOFAST
  3529. +
  3530. +/* These should be optimized for their specific tasks someday. */
  3531. +
  3532. +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
  3533. +CMPtype
  3534. +_eq_f2 (FLO_type arg_a, FLO_type arg_b)
  3535. +{
  3536. + fp_number_type a;
  3537. + fp_number_type b;
  3538. + FLO_union_type au, bu;
  3539. +
  3540. + au.value = arg_a;
  3541. + bu.value = arg_b;
  3542. +
  3543. + unpack_d (&au, &a);
  3544. + unpack_d (&bu, &b);
  3545. +
  3546. + if (isnan (&a) || isnan (&b))
  3547. + return 1; /* false, truth == 0 */
  3548. +
  3549. + return __fpcmp_parts (&a, &b) ;
  3550. +}
  3551. +#endif /* L_eq_sf || L_eq_df */
  3552. +
  3553. +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
  3554. +CMPtype
  3555. +_ne_f2 (FLO_type arg_a, FLO_type arg_b)
  3556. +{
  3557. + fp_number_type a;
  3558. + fp_number_type b;
  3559. + FLO_union_type au, bu;
  3560. +
  3561. + au.value = arg_a;
  3562. + bu.value = arg_b;
  3563. +
  3564. + unpack_d (&au, &a);
  3565. + unpack_d (&bu, &b);
  3566. +
  3567. + if (isnan (&a) || isnan (&b))
  3568. + return 1; /* true, truth != 0 */
  3569. +
  3570. + return __fpcmp_parts (&a, &b) ;
  3571. +}
  3572. +#endif /* L_ne_sf || L_ne_df */
  3573. +
  3574. +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
  3575. +CMPtype
  3576. +_gt_f2 (FLO_type arg_a, FLO_type arg_b)
  3577. +{
  3578. + fp_number_type a;
  3579. + fp_number_type b;
  3580. + FLO_union_type au, bu;
  3581. +
  3582. + au.value = arg_a;
  3583. + bu.value = arg_b;
  3584. +
  3585. + unpack_d (&au, &a);
  3586. + unpack_d (&bu, &b);
  3587. +
  3588. + if (isnan (&a) || isnan (&b))
  3589. + return -1; /* false, truth > 0 */
  3590. +
  3591. + return __fpcmp_parts (&a, &b);
  3592. +}
  3593. +#endif /* L_gt_sf || L_gt_df */
  3594. +
  3595. +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
  3596. +CMPtype
  3597. +_ge_f2 (FLO_type arg_a, FLO_type arg_b)
  3598. +{
  3599. + fp_number_type a;
  3600. + fp_number_type b;
  3601. + FLO_union_type au, bu;
  3602. +
  3603. + au.value = arg_a;
  3604. + bu.value = arg_b;
  3605. +
  3606. + unpack_d (&au, &a);
  3607. + unpack_d (&bu, &b);
  3608. +
  3609. + if (isnan (&a) || isnan (&b))
  3610. + return -1; /* false, truth >= 0 */
  3611. + return __fpcmp_parts (&a, &b) ;
  3612. +}
  3613. +#endif /* L_ge_sf || L_ge_df */
  3614. +
  3615. +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
  3616. +CMPtype
  3617. +_lt_f2 (FLO_type arg_a, FLO_type arg_b)
  3618. +{
  3619. + fp_number_type a;
  3620. + fp_number_type b;
  3621. + FLO_union_type au, bu;
  3622. +
  3623. + au.value = arg_a;
  3624. + bu.value = arg_b;
  3625. +
  3626. + unpack_d (&au, &a);
  3627. + unpack_d (&bu, &b);
  3628. +
  3629. + if (isnan (&a) || isnan (&b))
  3630. + return 1; /* false, truth < 0 */
  3631. +
  3632. + return __fpcmp_parts (&a, &b);
  3633. +}
  3634. +#endif /* L_lt_sf || L_lt_df */
  3635. +
  3636. +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
  3637. +CMPtype
  3638. +_le_f2 (FLO_type arg_a, FLO_type arg_b)
  3639. +{
  3640. + fp_number_type a;
  3641. + fp_number_type b;
  3642. + FLO_union_type au, bu;
  3643. +
  3644. + au.value = arg_a;
  3645. + bu.value = arg_b;
  3646. +
  3647. + unpack_d (&au, &a);
  3648. + unpack_d (&bu, &b);
  3649. +
  3650. + if (isnan (&a) || isnan (&b))
  3651. + return 1; /* false, truth <= 0 */
  3652. +
  3653. + return __fpcmp_parts (&a, &b) ;
  3654. +}
  3655. +#endif /* L_le_sf || L_le_df */
  3656. +
  3657. +#endif /* ! US_SOFTWARE_GOFAST */
  3658. +
  3659. +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
  3660. +CMPtype
  3661. +_unord_f2 (FLO_type arg_a, FLO_type arg_b)
  3662. +{
  3663. + fp_number_type a;
  3664. + fp_number_type b;
  3665. + FLO_union_type au, bu;
  3666. +
  3667. + au.value = arg_a;
  3668. + bu.value = arg_b;
  3669. +
  3670. + unpack_d (&au, &a);
  3671. + unpack_d (&bu, &b);
  3672. +
  3673. + return (isnan (&a) || isnan (&b));
  3674. +}
  3675. +#endif /* L_unord_sf || L_unord_df */
  3676. +
  3677. +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
  3678. +FLO_type
  3679. +si_to_float (SItype arg_a)
  3680. +{
  3681. + fp_number_type in;
  3682. +
  3683. + in.class = CLASS_NUMBER;
  3684. + in.sign = arg_a < 0;
  3685. + if (!arg_a)
  3686. + {
  3687. + in.class = CLASS_ZERO;
  3688. + }
  3689. + else
  3690. + {
  3691. + in.normal_exp = FRACBITS + NGARDS;
  3692. + if (in.sign)
  3693. + {
  3694. + /* Special case for minint, since there is no +ve integer
  3695. + representation for it */
  3696. + if (arg_a == (- MAX_SI_INT - 1))
  3697. + {
  3698. + return (FLO_type)(- MAX_SI_INT - 1);
  3699. + }
  3700. + in.fraction.ll = (-arg_a);
  3701. + }
  3702. + else
  3703. + in.fraction.ll = arg_a;
  3704. +
  3705. + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
  3706. + {
  3707. + in.fraction.ll <<= 1;
  3708. + in.normal_exp -= 1;
  3709. + }
  3710. + }
  3711. + return pack_d (&in);
  3712. +}
  3713. +#endif /* L_si_to_sf || L_si_to_df */
  3714. +
  3715. +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
  3716. +FLO_type
  3717. +usi_to_float (USItype arg_a)
  3718. +{
  3719. + fp_number_type in;
  3720. +
  3721. + in.sign = 0;
  3722. + if (!arg_a)
  3723. + {
  3724. + in.class = CLASS_ZERO;
  3725. + }
  3726. + else
  3727. + {
  3728. + in.class = CLASS_NUMBER;
  3729. + in.normal_exp = FRACBITS + NGARDS;
  3730. + in.fraction.ll = arg_a;
  3731. +
  3732. + while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS)))
  3733. + {
  3734. + in.fraction.ll >>= 1;
  3735. + in.normal_exp += 1;
  3736. + }
  3737. + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
  3738. + {
  3739. + in.fraction.ll <<= 1;
  3740. + in.normal_exp -= 1;
  3741. + }
  3742. + }
  3743. + return pack_d (&in);
  3744. +}
  3745. +#endif
  3746. +
  3747. +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
  3748. +SItype
  3749. +float_to_si (FLO_type arg_a)
  3750. +{
  3751. + fp_number_type a;
  3752. + SItype tmp;
  3753. + FLO_union_type au;
  3754. +
  3755. + au.value = arg_a;
  3756. + unpack_d (&au, &a);
  3757. +
  3758. + if (iszero (&a))
  3759. + return 0;
  3760. + if (isnan (&a))
  3761. + return 0;
  3762. + /* get reasonable MAX_SI_INT... */
  3763. + if (isinf (&a))
  3764. + return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
  3765. + /* it is a number, but a small one */
  3766. + if (a.normal_exp < 0)
  3767. + return 0;
  3768. + if (a.normal_exp > BITS_PER_SI - 2)
  3769. + return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
  3770. + tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
  3771. + return a.sign ? (-tmp) : (tmp);
  3772. +}
  3773. +#endif /* L_sf_to_si || L_df_to_si */
  3774. +
  3775. +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
  3776. +#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
  3777. +/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
  3778. + we also define them for GOFAST because the ones in libgcc2.c have the
  3779. + wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
  3780. + out of libgcc2.c. We can't define these here if not GOFAST because then
  3781. + there'd be duplicate copies. */
  3782. +
  3783. +USItype
  3784. +float_to_usi (FLO_type arg_a)
  3785. +{
  3786. + fp_number_type a;
  3787. + FLO_union_type au;
  3788. +
  3789. + au.value = arg_a;
  3790. + unpack_d (&au, &a);
  3791. +
  3792. + if (iszero (&a))
  3793. + return 0;
  3794. + if (isnan (&a))
  3795. + return 0;
  3796. + /* it is a negative number */
  3797. + if (a.sign)
  3798. + return 0;
  3799. + /* get reasonable MAX_USI_INT... */
  3800. + if (isinf (&a))
  3801. + return MAX_USI_INT;
  3802. + /* it is a number, but a small one */
  3803. + if (a.normal_exp < 0)
  3804. + return 0;
  3805. + if (a.normal_exp > BITS_PER_SI - 1)
  3806. + return MAX_USI_INT;
  3807. + else if (a.normal_exp > (FRACBITS + NGARDS))
  3808. + return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
  3809. + else
  3810. + return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
  3811. +}
  3812. +#endif /* US_SOFTWARE_GOFAST */
  3813. +#endif /* L_sf_to_usi || L_df_to_usi */
  3814. +
  3815. +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
  3816. +FLO_type
  3817. +negate (FLO_type arg_a)
  3818. +{
  3819. + fp_number_type a;
  3820. + FLO_union_type au;
  3821. +
  3822. + au.value = arg_a;
  3823. + unpack_d (&au, &a);
  3824. +
  3825. + flip_sign (&a);
  3826. + return pack_d (&a);
  3827. +}
  3828. +#endif /* L_negate_sf || L_negate_df */
  3829. +
  3830. +#ifdef FLOAT
  3831. +
  3832. +#if defined(L_make_sf)
  3833. +SFtype
  3834. +__make_fp(fp_class_type class,
  3835. + unsigned int sign,
  3836. + int exp,
  3837. + USItype frac)
  3838. +{
  3839. + fp_number_type in;
  3840. +
  3841. + in.class = class;
  3842. + in.sign = sign;
  3843. + in.normal_exp = exp;
  3844. + in.fraction.ll = frac;
  3845. + return pack_d (&in);
  3846. +}
  3847. +#endif /* L_make_sf */
  3848. +
  3849. +#ifndef FLOAT_ONLY
  3850. +
  3851. +/* This enables one to build an fp library that supports float but not double.
  3852. + Otherwise, we would get an undefined reference to __make_dp.
  3853. + This is needed for some 8-bit ports that can't handle well values that
  3854. + are 8-bytes in size, so we just don't support double for them at all. */
  3855. +
  3856. +#if defined(L_sf_to_df)
  3857. +DFtype
  3858. +sf_to_df (SFtype arg_a)
  3859. +{
  3860. + fp_number_type in;
  3861. + FLO_union_type au;
  3862. +
  3863. + au.value = arg_a;
  3864. + unpack_d (&au, &in);
  3865. +
  3866. + return __make_dp (in.class, in.sign, in.normal_exp,
  3867. + ((UDItype) in.fraction.ll) << F_D_BITOFF);
  3868. +}
  3869. +#endif /* L_sf_to_df */
  3870. +
  3871. +#if defined(L_sf_to_tf) && defined(TMODES)
  3872. +TFtype
  3873. +sf_to_tf (SFtype arg_a)
  3874. +{
  3875. + fp_number_type in;
  3876. + FLO_union_type au;
  3877. +
  3878. + au.value = arg_a;
  3879. + unpack_d (&au, &in);
  3880. +
  3881. + return __make_tp (in.class, in.sign, in.normal_exp,
  3882. + ((UTItype) in.fraction.ll) << F_T_BITOFF);
  3883. +}
  3884. +#endif /* L_sf_to_df */
  3885. +
  3886. +#endif /* ! FLOAT_ONLY */
  3887. +#endif /* FLOAT */
  3888. +
  3889. +#ifndef FLOAT
  3890. +
  3891. +extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
  3892. +
  3893. +#if defined(L_make_df)
  3894. +DFtype
  3895. +__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
  3896. +{
  3897. + fp_number_type in;
  3898. +
  3899. + in.class = class;
  3900. + in.sign = sign;
  3901. + in.normal_exp = exp;
  3902. + in.fraction.ll = frac;
  3903. + return pack_d (&in);
  3904. +}
  3905. +#endif /* L_make_df */
  3906. +
  3907. +#if defined(L_df_to_sf)
  3908. +SFtype
  3909. +df_to_sf (DFtype arg_a)
  3910. +{
  3911. + fp_number_type in;
  3912. + USItype sffrac;
  3913. + FLO_union_type au;
  3914. +
  3915. + au.value = arg_a;
  3916. + unpack_d (&au, &in);
  3917. +
  3918. + sffrac = in.fraction.ll >> F_D_BITOFF;
  3919. +
  3920. + /* We set the lowest guard bit in SFFRAC if we discarded any non
  3921. + zero bits. */
  3922. + if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
  3923. + sffrac |= 1;
  3924. +
  3925. + return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
  3926. +}
  3927. +#endif /* L_df_to_sf */
  3928. +
  3929. +#if defined(L_df_to_tf) && defined(TMODES) \
  3930. + && !defined(FLOAT) && !defined(TFLOAT)
  3931. +TFtype
  3932. +df_to_tf (DFtype arg_a)
  3933. +{
  3934. + fp_number_type in;
  3935. + FLO_union_type au;
  3936. +
  3937. + au.value = arg_a;
  3938. + unpack_d (&au, &in);
  3939. +
  3940. + return __make_tp (in.class, in.sign, in.normal_exp,
  3941. + ((UTItype) in.fraction.ll) << D_T_BITOFF);
  3942. +}
  3943. +#endif /* L_sf_to_df */
  3944. +
  3945. +#ifdef TFLOAT
  3946. +#if defined(L_make_tf)
  3947. +TFtype
  3948. +__make_tp(fp_class_type class,
  3949. + unsigned int sign,
  3950. + int exp,
  3951. + UTItype frac)
  3952. +{
  3953. + fp_number_type in;
  3954. +
  3955. + in.class = class;
  3956. + in.sign = sign;
  3957. + in.normal_exp = exp;
  3958. + in.fraction.ll = frac;
  3959. + return pack_d (&in);
  3960. +}
  3961. +#endif /* L_make_tf */
  3962. +
  3963. +#if defined(L_tf_to_df)
  3964. +DFtype
  3965. +tf_to_df (TFtype arg_a)
  3966. +{
  3967. + fp_number_type in;
  3968. + UDItype sffrac;
  3969. + FLO_union_type au;
  3970. +
  3971. + au.value = arg_a;
  3972. + unpack_d (&au, &in);
  3973. +
  3974. + sffrac = in.fraction.ll >> D_T_BITOFF;
  3975. +
  3976. + /* We set the lowest guard bit in SFFRAC if we discarded any non
  3977. + zero bits. */
  3978. + if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
  3979. + sffrac |= 1;
  3980. +
  3981. + return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
  3982. +}
  3983. +#endif /* L_tf_to_df */
  3984. +
  3985. +#if defined(L_tf_to_sf)
  3986. +SFtype
  3987. +tf_to_sf (TFtype arg_a)
  3988. +{
  3989. + fp_number_type in;
  3990. + USItype sffrac;
  3991. + FLO_union_type au;
  3992. +
  3993. + au.value = arg_a;
  3994. + unpack_d (&au, &in);
  3995. +
  3996. + sffrac = in.fraction.ll >> F_T_BITOFF;
  3997. +
  3998. + /* We set the lowest guard bit in SFFRAC if we discarded any non
  3999. + zero bits. */
  4000. + if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
  4001. + sffrac |= 1;
  4002. +
  4003. + return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
  4004. +}
  4005. +#endif /* L_tf_to_sf */
  4006. +#endif /* TFLOAT */
  4007. +
  4008. +#endif /* ! FLOAT */
  4009. +#endif /* !EXTENDED_FLOAT_STUBS */
  4010. diff --git a/gcc/config/nios2/nios2-protos.h b/gcc/config/nios2/nios2-protos.h
  4011. new file mode 100644
  4012. index 0000000..dc75c4f
  4013. --- /dev/null
  4014. +++ b/gcc/config/nios2/nios2-protos.h
  4015. @@ -0,0 +1,78 @@
  4016. +/* Subroutines for assembler code output for Altera NIOS 2G NIOS2 version.
  4017. + Copyright (C) 2003 Altera
  4018. + Contributed by Jonah Graham (jgraham@altera.com).
  4019. +
  4020. +This file is part of GNU CC.
  4021. +
  4022. +GNU CC is free software; you can redistribute it and/or modify
  4023. +it under the terms of the GNU General Public License as published by
  4024. +the Free Software Foundation; either version 2, or (at your option)
  4025. +any later version.
  4026. +
  4027. +GNU CC is distributed in the hope that it will be useful,
  4028. +but WITHOUT ANY WARRANTY; without even the implied warranty of
  4029. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4030. +GNU General Public License for more details.
  4031. +
  4032. +You should have received a copy of the GNU General Public License
  4033. +along with GNU CC; see the file COPYING. If not, write to
  4034. +the Free Software Foundation, 59 Temple Place - Suite 330,
  4035. +Boston, MA 02111-1307, USA. */
  4036. +
  4037. +extern void dump_frame_size (FILE *);
  4038. +extern HOST_WIDE_INT compute_frame_size (void);
  4039. +extern int nios2_initial_elimination_offset (int, int);
  4040. +extern void override_options (void);
  4041. +extern void optimization_options (int, int);
  4042. +extern int nios2_can_use_return_insn (void);
  4043. +extern void expand_prologue (void);
  4044. +extern void expand_epilogue (bool);
  4045. +extern void function_profiler (FILE *, int);
  4046. +extern enum reg_class reg_class_from_constraint (char, const char *);
  4047. +extern void nios2_register_target_pragmas (void);
  4048. +
  4049. +#ifdef RTX_CODE
  4050. +extern int nios2_legitimate_address (rtx, enum machine_mode, int);
  4051. +extern void nios2_print_operand (FILE *, rtx, int);
  4052. +extern void nios2_print_operand_address (FILE *, rtx);
  4053. +
  4054. +extern int nios2_emit_move_sequence (rtx *, enum machine_mode);
  4055. +extern int nios2_emit_expensive_div (rtx *, enum machine_mode);
  4056. +
  4057. +extern void gen_int_relational (enum rtx_code, rtx, rtx, rtx, rtx);
  4058. +extern void gen_conditional_move (rtx *, enum machine_mode);
  4059. +extern const char *asm_output_opcode (FILE *, const char *);
  4060. +
  4061. +/* predicates */
  4062. +extern int arith_operand (rtx, enum machine_mode);
  4063. +extern int uns_arith_operand (rtx, enum machine_mode);
  4064. +extern int logical_operand (rtx, enum machine_mode);
  4065. +extern int shift_operand (rtx, enum machine_mode);
  4066. +extern int reg_or_0_operand (rtx, enum machine_mode);
  4067. +extern int equality_op (rtx, enum machine_mode);
  4068. +extern int custom_insn_opcode (rtx, enum machine_mode);
  4069. +extern int rdwrctl_operand (rtx, enum machine_mode);
  4070. +
  4071. +/* custom fpu instruction output */
  4072. +extern const char *nios2_output_fpu_insn_cmps (rtx, enum rtx_code);
  4073. +extern const char *nios2_output_fpu_insn_cmpd (rtx, enum rtx_code);
  4074. +
  4075. +# ifdef HAVE_MACHINE_MODES
  4076. +# if defined TREE_CODE
  4077. +extern rtx function_arg (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
  4078. +extern int nios2_must_pass_in_stack (enum machine_mode, tree);
  4079. +extern int function_arg_partial_nregs (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
  4080. +extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
  4081. +extern int nios2_function_arg_padding (enum machine_mode, tree);
  4082. +extern int nios2_block_reg_padding (enum machine_mode, tree, int);
  4083. +extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
  4084. +extern int nios2_setup_incoming_varargs (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
  4085. +
  4086. +# endif /* TREE_CODE */
  4087. +# endif /* HAVE_MACHINE_MODES */
  4088. +#endif
  4089. +
  4090. +#ifdef TREE_CODE
  4091. +extern int nios2_return_in_memory (tree);
  4092. +
  4093. +#endif /* TREE_CODE */
  4094. diff --git a/gcc/config/nios2/nios2-uclibc.h b/gcc/config/nios2/nios2-uclibc.h
  4095. new file mode 100644
  4096. index 0000000..af98cdd
  4097. --- /dev/null
  4098. +++ b/gcc/config/nios2/nios2-uclibc.h
  4099. @@ -0,0 +1,75 @@
  4100. +#ifdef USE_UCLIBC
  4101. +
  4102. +#undef TARGET_SWITCHES
  4103. +#define TARGET_SWITCHES \
  4104. +{ \
  4105. + { "hw-div", HAS_DIV_FLAG, \
  4106. + N_("Enable DIV, DIVU") }, \
  4107. + { "no-hw-div", -HAS_DIV_FLAG, \
  4108. + N_("Disable DIV, DIVU (default)") }, \
  4109. + { "hw-mul", HAS_MUL_FLAG, \
  4110. + N_("Enable MUL instructions (default)") }, \
  4111. + { "hw-mulx", HAS_MULX_FLAG, \
  4112. + N_("Enable MULX instructions, assume fast shifter") }, \
  4113. + { "no-hw-mul", -HAS_MUL_FLAG, \
  4114. + N_("Disable MUL instructions") }, \
  4115. + { "no-hw-mulx", -HAS_MULX_FLAG, \
  4116. + N_("Disable MULX instructions, assume slow shifter (default and implied by -mno-hw-mul)") }, \
  4117. + { "fast-sw-div", FAST_SW_DIV_FLAG, \
  4118. + N_("Use table based fast divide (default at -O3)") }, \
  4119. + { "no-fast-sw-div", -FAST_SW_DIV_FLAG, \
  4120. + N_("Don't use table based fast divide ever") }, \
  4121. + { "inline-memcpy", INLINE_MEMCPY_FLAG, \
  4122. + N_("Inline small memcpy (default when optimizing)") }, \
  4123. + { "no-inline-memcpy", -INLINE_MEMCPY_FLAG, \
  4124. + N_("Don't Inline small memcpy") }, \
  4125. + { "cache-volatile", CACHE_VOLATILE_FLAG, \
  4126. + N_("Volatile accesses use non-io variants of instructions (default)") }, \
  4127. + { "no-cache-volatile", -CACHE_VOLATILE_FLAG, \
  4128. + N_("Volatile accesses use io variants of instructions") }, \
  4129. + { "bypass-cache", BYPASS_CACHE_FLAG, \
  4130. + N_("All ld/st instructins use io variants") }, \
  4131. + { "no-bypass-cache", -BYPASS_CACHE_FLAG, \
  4132. + N_("All ld/st instructins do not use io variants (default)") }, \
  4133. + { "smallc", 0, \
  4134. + N_("Link with a limited version of the C library") }, \
  4135. + { "stack-check", STACK_CHECK_FLAG, \
  4136. + N_("Enable stack limit checking.") }, \
  4137. + { "no-stack-check", -STACK_CHECK_FLAG, \
  4138. + N_("Disable stack limit checking (default).") }, \
  4139. + { "reverse-bitfields", REVERSE_BITFIELDS_FLAG, \
  4140. + N_("Reverse the order of bitfields in a struct.") }, \
  4141. + { "no-reverse-bitfields", -REVERSE_BITFIELDS_FLAG, \
  4142. + N_("Use the normal order of bitfields in a struct (default).") }, \
  4143. + { "eb", BIG_ENDIAN_FLAG, \
  4144. + N_("Use big-endian byte order") }, \
  4145. + { "el", -BIG_ENDIAN_FLAG, \
  4146. + N_("Use little-endian byte order") }, \
  4147. + { "", TARGET_DEFAULT, 0 } \
  4148. +}
  4149. +
  4150. +/* The GNU C++ standard library requires that these macros be defined. */
  4151. +#undef CPLUSPLUS_CPP_SPEC
  4152. +#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
  4153. +
  4154. +#undef LIB_SPEC
  4155. +#define LIB_SPEC \
  4156. +"--start-group %{msmallc: -lsmallc} %{!msmallc: -lc} -lgcc \
  4157. + %{msys-lib=*: -l%*} \
  4158. + %{!msys-lib=*: -lc} \
  4159. + --end-group \
  4160. + %{msys-lib=: %eYou need a library name for -msys-lib=} \
  4161. +"
  4162. +
  4163. +#undef STARTFILE_SPEC
  4164. +#define STARTFILE_SPEC \
  4165. +"%{msys-crt0=*: %*} %{!msys-crt0=*: crt1%O%s} \
  4166. + %{msys-crt0=: %eYou need a C startup file for -msys-crt0=} \
  4167. + crti%O%s crtbegin%O%s \
  4168. +"
  4169. +
  4170. +#undef ENDFILE_SPEC
  4171. +#define ENDFILE_SPEC \
  4172. + " crtend%O%s crtn%O%s"
  4173. +
  4174. +#endif /* USE_UCLIBC */
  4175. diff --git a/gcc/config/nios2/nios2.c b/gcc/config/nios2/nios2.c
  4176. new file mode 100644
  4177. index 0000000..8723a86
  4178. --- /dev/null
  4179. +++ b/gcc/config/nios2/nios2.c
  4180. @@ -0,0 +1,4694 @@
  4181. +/* Subroutines for assembler code output for Altera NIOS 2G NIOS2 version.
  4182. + Copyright (C) 2005 Altera
  4183. + Contributed by Jonah Graham (jgraham@altera.com) and Will Reece (wreece@altera.com).
  4184. +
  4185. +This file is part of GNU CC.
  4186. +
  4187. +GNU CC is free software; you can redistribute it and/or modify
  4188. +it under the terms of the GNU General Public License as published by
  4189. +the Free Software Foundation; either version 2, or (at your option)
  4190. +any later version.
  4191. +
  4192. +GNU CC is distributed in the hope that it will be useful,
  4193. +but WITHOUT ANY WARRANTY; without even the implied warranty of
  4194. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4195. +GNU General Public License for more details.
  4196. +
  4197. +You should have received a copy of the GNU General Public License
  4198. +along with GNU CC; see the file COPYING. If not, write to
  4199. +the Free Software Foundation, 59 Temple Place - Suite 330,
  4200. +Boston, MA 02111-1307, USA. */
  4201. +
  4202. +
  4203. +#include <stdio.h>
  4204. +#include "config.h"
  4205. +#include "system.h"
  4206. +#include "coretypes.h"
  4207. +#include "tm.h"
  4208. +#include "rtl.h"
  4209. +#include "tree.h"
  4210. +#include "tm_p.h"
  4211. +#include "regs.h"
  4212. +#include "hard-reg-set.h"
  4213. +#include "real.h"
  4214. +#include "insn-config.h"
  4215. +#include "conditions.h"
  4216. +#include "output.h"
  4217. +#include "insn-attr.h"
  4218. +#include "flags.h"
  4219. +#include "recog.h"
  4220. +#include "expr.h"
  4221. +#include "toplev.h"
  4222. +#include "basic-block.h"
  4223. +#include "function.h"
  4224. +#include "ggc.h"
  4225. +#include "reload.h"
  4226. +#include "debug.h"
  4227. +#include "optabs.h"
  4228. +#include "target.h"
  4229. +#include "target-def.h"
  4230. +#include "c-pragma.h" /* for c_register_pragma */
  4231. +#include "cpplib.h" /* for CPP_NUMBER */
  4232. +
  4233. +/* local prototypes */
  4234. +static bool nios2_rtx_costs (rtx, int, int, int *);
  4235. +
  4236. +static void nios2_asm_function_prologue (FILE *, HOST_WIDE_INT);
  4237. +static int nios2_use_dfa_pipeline_interface (void);
  4238. +static int nios2_issue_rate (void);
  4239. +static struct machine_function *nios2_init_machine_status (void);
  4240. +static bool nios2_in_small_data_p (tree);
  4241. +static rtx save_reg (int, HOST_WIDE_INT, rtx);
  4242. +static rtx restore_reg (int, HOST_WIDE_INT);
  4243. +static unsigned int nios2_section_type_flags (tree, const char *, int);
  4244. +
  4245. +/* 0 --> no #pragma seen
  4246. + 1 --> in scope of #pragma reverse_bitfields
  4247. + -1 --> in scope of #pragma no_reverse_bitfields */
  4248. +static int nios2_pragma_reverse_bitfields_flag = 0;
  4249. +static void nios2_pragma_reverse_bitfields (struct cpp_reader *);
  4250. +static void nios2_pragma_no_reverse_bitfields (struct cpp_reader *);
  4251. +static tree nios2_handle_struct_attribute (tree *, tree, tree, int, bool *);
  4252. +static void nios2_insert_attributes (tree, tree *);
  4253. +static bool nios2_reverse_bitfield_layout_p (tree record_type);
  4254. +static void nios2_init_builtins (void);
  4255. +static rtx nios2_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
  4256. +static bool nios2_function_ok_for_sibcall (tree, tree);
  4257. +static void nios2_encode_section_info (tree, rtx, int);
  4258. +
  4259. +/* Initialize the GCC target structure. */
  4260. +#undef TARGET_ASM_FUNCTION_PROLOGUE
  4261. +#define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue
  4262. +
  4263. +#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
  4264. +#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE \
  4265. + nios2_use_dfa_pipeline_interface
  4266. +#undef TARGET_SCHED_ISSUE_RATE
  4267. +#define TARGET_SCHED_ISSUE_RATE nios2_issue_rate
  4268. +#undef TARGET_IN_SMALL_DATA_P
  4269. +#define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p
  4270. +#undef TARGET_ENCODE_SECTION_INFO
  4271. +#define TARGET_ENCODE_SECTION_INFO nios2_encode_section_info
  4272. +#undef TARGET_SECTION_TYPE_FLAGS
  4273. +#define TARGET_SECTION_TYPE_FLAGS nios2_section_type_flags
  4274. +
  4275. +#undef TARGET_REVERSE_BITFIELD_LAYOUT_P
  4276. +#define TARGET_REVERSE_BITFIELD_LAYOUT_P nios2_reverse_bitfield_layout_p
  4277. +
  4278. +#undef TARGET_INIT_BUILTINS
  4279. +#define TARGET_INIT_BUILTINS nios2_init_builtins
  4280. +#undef TARGET_EXPAND_BUILTIN
  4281. +#define TARGET_EXPAND_BUILTIN nios2_expand_builtin
  4282. +
  4283. +#undef TARGET_FUNCTION_OK_FOR_SIBCALL
  4284. +#define TARGET_FUNCTION_OK_FOR_SIBCALL nios2_function_ok_for_sibcall
  4285. +
  4286. +#undef TARGET_RTX_COSTS
  4287. +#define TARGET_RTX_COSTS nios2_rtx_costs
  4288. +
  4289. +const struct attribute_spec nios2_attribute_table[] =
  4290. +{
  4291. + /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
  4292. + { "reverse_bitfields", 0, 0, false, false, false, nios2_handle_struct_attribute },
  4293. + { "no_reverse_bitfields", 0, 0, false, false, false, nios2_handle_struct_attribute },
  4294. + { "pragma_reverse_bitfields", 0, 0, false, false, false, NULL },
  4295. + { "pragma_no_reverse_bitfields", 0, 0, false, false, false, NULL },
  4296. + { NULL, 0, 0, false, false, false, NULL }
  4297. +};
  4298. +
  4299. +#undef TARGET_ATTRIBUTE_TABLE
  4300. +#define TARGET_ATTRIBUTE_TABLE nios2_attribute_table
  4301. +
  4302. +#undef TARGET_INSERT_ATTRIBUTES
  4303. +#define TARGET_INSERT_ATTRIBUTES nios2_insert_attributes
  4304. +
  4305. +/* ??? Might want to redefine TARGET_RETURN_IN_MSB here to handle
  4306. + big-endian case; depends on what ABI we choose. */
  4307. +
  4308. +struct gcc_target targetm = TARGET_INITIALIZER;
  4309. +
  4310. +
  4311. +
  4312. +/* Threshold for data being put into the small data/bss area, instead
  4313. + of the normal data area (references to the small data/bss area take
  4314. + 1 instruction, and use the global pointer, references to the normal
  4315. + data area takes 2 instructions). */
  4316. +unsigned HOST_WIDE_INT nios2_section_threshold = NIOS2_DEFAULT_GVALUE;
  4317. +
  4318. +
  4319. +/* Structure to be filled in by compute_frame_size with register
  4320. + save masks, and offsets for the current function. */
  4321. +
  4322. +struct nios2_frame_info
  4323. +GTY (())
  4324. +{
  4325. + long total_size; /* # bytes that the entire frame takes up */
  4326. + long var_size; /* # bytes that variables take up */
  4327. + long args_size; /* # bytes that outgoing arguments take up */
  4328. + int save_reg_size; /* # bytes needed to store gp regs */
  4329. + int save_reg_rounded; /* # bytes needed to store gp regs */
  4330. + long save_regs_offset; /* offset from new sp to store gp registers */
  4331. + int initialized; /* != 0 if frame size already calculated */
  4332. + int num_regs; /* number of gp registers saved */
  4333. +};
  4334. +
  4335. +struct machine_function
  4336. +GTY (())
  4337. +{
  4338. +
  4339. + /* Current frame information, calculated by compute_frame_size. */
  4340. + struct nios2_frame_info frame;
  4341. +};
  4342. +
  4343. +
  4344. +/***************************************
  4345. + * Register Classes
  4346. + ***************************************/
  4347. +
  4348. +enum reg_class
  4349. +reg_class_from_constraint (char chr, const char *str)
  4350. +{
  4351. + if (chr == 'D' && ISDIGIT (str[1]) && ISDIGIT (str[2]))
  4352. + {
  4353. + int regno;
  4354. + int ones = str[2] - '0';
  4355. + int tens = str[1] - '0';
  4356. +
  4357. + regno = ones + (10 * tens);
  4358. + if (regno < 0 || regno > 31)
  4359. + return NO_REGS;
  4360. +
  4361. + return D00_REG + regno;
  4362. + }
  4363. +
  4364. + return NO_REGS;
  4365. +}
  4366. +
  4367. +
  4368. +/***************************************
  4369. + * Stack Layout and Calling Conventions
  4370. + ***************************************/
  4371. +
  4372. +
  4373. +#define TOO_BIG_OFFSET(X) ((X) > ((1 << 15) - 1))
  4374. +#define TEMP_REG_NUM 8
  4375. +
  4376. +static void
  4377. +nios2_asm_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
  4378. +{
  4379. + if (flag_verbose_asm || flag_debug_asm)
  4380. + {
  4381. + compute_frame_size ();
  4382. + dump_frame_size (file);
  4383. + }
  4384. +}
  4385. +
  4386. +static rtx
  4387. +save_reg (int regno, HOST_WIDE_INT offset, rtx cfa_store_reg)
  4388. +{
  4389. + rtx insn, stack_slot;
  4390. +
  4391. + stack_slot = gen_rtx_PLUS (SImode,
  4392. + cfa_store_reg,
  4393. + GEN_INT (offset));
  4394. +
  4395. + insn = emit_insn (gen_rtx_SET (SImode,
  4396. + gen_rtx_MEM (SImode, stack_slot),
  4397. + gen_rtx_REG (SImode, regno)));
  4398. +
  4399. + RTX_FRAME_RELATED_P (insn) = 1;
  4400. +
  4401. + return insn;
  4402. +}
  4403. +
  4404. +static rtx
  4405. +restore_reg (int regno, HOST_WIDE_INT offset)
  4406. +{
  4407. + rtx insn, stack_slot;
  4408. +
  4409. + if (TOO_BIG_OFFSET (offset))
  4410. + {
  4411. + stack_slot = gen_rtx_REG (SImode, TEMP_REG_NUM);
  4412. + insn = emit_insn (gen_rtx_SET (SImode,
  4413. + stack_slot,
  4414. + GEN_INT (offset)));
  4415. +
  4416. + insn = emit_insn (gen_rtx_SET (SImode,
  4417. + stack_slot,
  4418. + gen_rtx_PLUS (SImode,
  4419. + stack_slot,
  4420. + stack_pointer_rtx)));
  4421. + }
  4422. + else
  4423. + {
  4424. + stack_slot = gen_rtx_PLUS (SImode,
  4425. + stack_pointer_rtx,
  4426. + GEN_INT (offset));
  4427. + }
  4428. +
  4429. + stack_slot = gen_rtx_MEM (SImode, stack_slot);
  4430. +
  4431. + insn = emit_move_insn (gen_rtx_REG (SImode, regno), stack_slot);
  4432. +
  4433. + return insn;
  4434. +}
  4435. +
  4436. +
  4437. +/* There are two possible paths for prologue expansion,
  4438. +- the first is if the total frame size is < 2^15-1. In that
  4439. +case all the immediates will fit into the 16-bit immediate
  4440. +fields.
  4441. +- the second is when the frame size is too big, in that
  4442. +case an additional temporary register is used, first
  4443. +as a cfa_temp to offset the sp, second as the cfa_store
  4444. +register.
  4445. +
  4446. +See the comment above dwarf2out_frame_debug_expr in
  4447. +dwarf2out.c for more explanation of the "rules."
  4448. +
  4449. +
  4450. +Case 1:
  4451. +Rule # Example Insn Effect
  4452. +2 addi sp, sp, -total_frame_size cfa.reg=sp, cfa.offset=total_frame_size
  4453. + cfa_store.reg=sp, cfa_store.offset=total_frame_size
  4454. +12 stw ra, offset(sp)
  4455. +12 stw r16, offset(sp)
  4456. +1 mov fp, sp
  4457. +
  4458. +Case 2:
  4459. +Rule # Example Insn Effect
  4460. +6 movi r8, total_frame_size cfa_temp.reg=r8, cfa_temp.offset=total_frame_size
  4461. +2 sub sp, sp, r8 cfa.reg=sp, cfa.offset=total_frame_size
  4462. + cfa_store.reg=sp, cfa_store.offset=total_frame_size
  4463. +5 add r8, r8, sp cfa_store.reg=r8, cfa_store.offset=0
  4464. +12 stw ra, offset(r8)
  4465. +12 stw r16, offset(r8)
  4466. +1 mov fp, sp
  4467. +
  4468. +*/
  4469. +
  4470. +void
  4471. +expand_prologue ()
  4472. +{
  4473. + int i;
  4474. + HOST_WIDE_INT total_frame_size;
  4475. + int cfa_store_offset = 0;
  4476. + rtx insn;
  4477. + rtx cfa_store_reg = 0;
  4478. +
  4479. + total_frame_size = compute_frame_size ();
  4480. +
  4481. + if (total_frame_size)
  4482. + {
  4483. +
  4484. + if (TOO_BIG_OFFSET (total_frame_size))
  4485. + {
  4486. + /* cfa_temp and cfa_store_reg are the same register,
  4487. + cfa_store_reg overwrites cfa_temp */
  4488. + cfa_store_reg = gen_rtx_REG (SImode, TEMP_REG_NUM);
  4489. + insn = emit_insn (gen_rtx_SET (SImode,
  4490. + cfa_store_reg,
  4491. + GEN_INT (total_frame_size)));
  4492. +
  4493. + RTX_FRAME_RELATED_P (insn) = 1;
  4494. +
  4495. +
  4496. + insn = gen_rtx_SET (SImode,
  4497. + stack_pointer_rtx,
  4498. + gen_rtx_MINUS (SImode,
  4499. + stack_pointer_rtx,
  4500. + cfa_store_reg));
  4501. +
  4502. + insn = emit_insn (insn);
  4503. + RTX_FRAME_RELATED_P (insn) = 1;
  4504. +
  4505. +
  4506. + /* if there are no registers to save, I don't need to
  4507. + create a cfa_store */
  4508. + if (cfun->machine->frame.save_reg_size)
  4509. + {
  4510. + insn = gen_rtx_SET (SImode,
  4511. + cfa_store_reg,
  4512. + gen_rtx_PLUS (SImode,
  4513. + cfa_store_reg,
  4514. + stack_pointer_rtx));
  4515. +
  4516. + insn = emit_insn (insn);
  4517. + RTX_FRAME_RELATED_P (insn) = 1;
  4518. + }
  4519. +
  4520. + cfa_store_offset
  4521. + = total_frame_size
  4522. + - (cfun->machine->frame.save_regs_offset
  4523. + + cfun->machine->frame.save_reg_rounded);
  4524. + }
  4525. + else
  4526. + {
  4527. + insn = gen_rtx_SET (SImode,
  4528. + stack_pointer_rtx,
  4529. + gen_rtx_PLUS (SImode,
  4530. + stack_pointer_rtx,
  4531. + GEN_INT (-total_frame_size)));
  4532. + insn = emit_insn (insn);
  4533. + RTX_FRAME_RELATED_P (insn) = 1;
  4534. +
  4535. + cfa_store_reg = stack_pointer_rtx;
  4536. + cfa_store_offset
  4537. + = cfun->machine->frame.save_regs_offset
  4538. + + cfun->machine->frame.save_reg_rounded;
  4539. + }
  4540. +
  4541. + if (current_function_limit_stack)
  4542. + {
  4543. + emit_insn (gen_stack_overflow_detect_and_trap ());
  4544. + }
  4545. + }
  4546. +
  4547. + if (MUST_SAVE_REGISTER (RA_REGNO))
  4548. + {
  4549. + cfa_store_offset -= 4;
  4550. + save_reg (RA_REGNO, cfa_store_offset, cfa_store_reg);
  4551. + }
  4552. + if (MUST_SAVE_REGISTER (FP_REGNO))
  4553. + {
  4554. + cfa_store_offset -= 4;
  4555. + save_reg (FP_REGNO, cfa_store_offset, cfa_store_reg);
  4556. + }
  4557. +
  4558. + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  4559. + {
  4560. + if (MUST_SAVE_REGISTER (i) && i != FP_REGNO && i != RA_REGNO)
  4561. + {
  4562. + cfa_store_offset -= 4;
  4563. + save_reg (i, cfa_store_offset, cfa_store_reg);
  4564. + }
  4565. + }
  4566. +
  4567. + if (frame_pointer_needed)
  4568. + {
  4569. + insn = emit_insn (gen_rtx_SET (SImode,
  4570. + gen_rtx_REG (SImode, FP_REGNO),
  4571. + gen_rtx_REG (SImode, SP_REGNO)));
  4572. +
  4573. + RTX_FRAME_RELATED_P (insn) = 1;
  4574. + }
  4575. +
  4576. + /* If we are profiling, make sure no instructions are scheduled before
  4577. + the call to mcount. */
  4578. + if (current_function_profile)
  4579. + emit_insn (gen_blockage ());
  4580. +}
  4581. +
  4582. +void
  4583. +expand_epilogue (bool sibcall_p)
  4584. +{
  4585. + rtx insn;
  4586. + int i;
  4587. + HOST_WIDE_INT total_frame_size;
  4588. + int register_store_offset;
  4589. +
  4590. + total_frame_size = compute_frame_size ();
  4591. +
  4592. + if (!sibcall_p && nios2_can_use_return_insn ())
  4593. + {
  4594. + insn = emit_jump_insn (gen_return ());
  4595. + return;
  4596. + }
  4597. +
  4598. + emit_insn (gen_blockage ());
  4599. +
  4600. + register_store_offset =
  4601. + cfun->machine->frame.save_regs_offset +
  4602. + cfun->machine->frame.save_reg_rounded;
  4603. +
  4604. + if (MUST_SAVE_REGISTER (RA_REGNO))
  4605. + {
  4606. + register_store_offset -= 4;
  4607. + restore_reg (RA_REGNO, register_store_offset);
  4608. + }
  4609. +
  4610. + if (MUST_SAVE_REGISTER (FP_REGNO))
  4611. + {
  4612. + register_store_offset -= 4;
  4613. + restore_reg (FP_REGNO, register_store_offset);
  4614. + }
  4615. +
  4616. + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  4617. + {
  4618. + if (MUST_SAVE_REGISTER (i) && i != FP_REGNO && i != RA_REGNO)
  4619. + {
  4620. + register_store_offset -= 4;
  4621. + restore_reg (i, register_store_offset);
  4622. + }
  4623. + }
  4624. +
  4625. + if (total_frame_size)
  4626. + {
  4627. + rtx sp_adjust;
  4628. +
  4629. + if (TOO_BIG_OFFSET (total_frame_size))
  4630. + {
  4631. + sp_adjust = gen_rtx_REG (SImode, TEMP_REG_NUM);
  4632. + insn = emit_insn (gen_rtx_SET (SImode,
  4633. + sp_adjust,
  4634. + GEN_INT (total_frame_size)));
  4635. +
  4636. + }
  4637. + else
  4638. + {
  4639. + sp_adjust = GEN_INT (total_frame_size);
  4640. + }
  4641. +
  4642. + insn = gen_rtx_SET (SImode,
  4643. + stack_pointer_rtx,
  4644. + gen_rtx_PLUS (SImode,
  4645. + stack_pointer_rtx,
  4646. + sp_adjust));
  4647. + insn = emit_insn (insn);
  4648. + }
  4649. +
  4650. +
  4651. + if (!sibcall_p)
  4652. + {
  4653. + insn = emit_jump_insn (gen_return_from_epilogue (gen_rtx (REG, Pmode,
  4654. + RA_REGNO)));
  4655. + }
  4656. +}
  4657. +
  4658. +
  4659. +bool
  4660. +nios2_function_ok_for_sibcall (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
  4661. +{
  4662. + return true;
  4663. +}
  4664. +
  4665. +
  4666. +
  4667. +
  4668. +
  4669. +/* ----------------------- *
  4670. + * Profiling
  4671. + * ----------------------- */
  4672. +
  4673. +void
  4674. +function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
  4675. +{
  4676. + fprintf (file, "\tmov\tr8, ra\n");
  4677. + fprintf (file, "\tcall\tmcount\n");
  4678. + fprintf (file, "\tmov\tra, r8\n");
  4679. +}
  4680. +
  4681. +
  4682. +/***************************************
  4683. + * Stack Layout
  4684. + ***************************************/
  4685. +
  4686. +
  4687. +void
  4688. +dump_frame_size (FILE *file)
  4689. +{
  4690. + fprintf (file, "\t%s Current Frame Info\n", ASM_COMMENT_START);
  4691. +
  4692. + fprintf (file, "\t%s total_size = %ld\n", ASM_COMMENT_START,
  4693. + cfun->machine->frame.total_size);
  4694. + fprintf (file, "\t%s var_size = %ld\n", ASM_COMMENT_START,
  4695. + cfun->machine->frame.var_size);
  4696. + fprintf (file, "\t%s args_size = %ld\n", ASM_COMMENT_START,
  4697. + cfun->machine->frame.args_size);
  4698. + fprintf (file, "\t%s save_reg_size = %d\n", ASM_COMMENT_START,
  4699. + cfun->machine->frame.save_reg_size);
  4700. + fprintf (file, "\t%s save_reg_rounded = %d\n", ASM_COMMENT_START,
  4701. + cfun->machine->frame.save_reg_rounded);
  4702. + fprintf (file, "\t%s initialized = %d\n", ASM_COMMENT_START,
  4703. + cfun->machine->frame.initialized);
  4704. + fprintf (file, "\t%s num_regs = %d\n", ASM_COMMENT_START,
  4705. + cfun->machine->frame.num_regs);
  4706. + fprintf (file, "\t%s save_regs_offset = %ld\n", ASM_COMMENT_START,
  4707. + cfun->machine->frame.save_regs_offset);
  4708. + fprintf (file, "\t%s current_function_is_leaf = %d\n", ASM_COMMENT_START,
  4709. + current_function_is_leaf);
  4710. + fprintf (file, "\t%s frame_pointer_needed = %d\n", ASM_COMMENT_START,
  4711. + frame_pointer_needed);
  4712. + fprintf (file, "\t%s pretend_args_size = %d\n", ASM_COMMENT_START,
  4713. + current_function_pretend_args_size);
  4714. +
  4715. +}
  4716. +
  4717. +
  4718. +/* Return the bytes needed to compute the frame pointer from the current
  4719. + stack pointer.
  4720. +*/
  4721. +
  4722. +HOST_WIDE_INT
  4723. +compute_frame_size ()
  4724. +{
  4725. + unsigned int regno;
  4726. + HOST_WIDE_INT var_size; /* # of var. bytes allocated */
  4727. + HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up */
  4728. + HOST_WIDE_INT save_reg_size; /* # bytes needed to store callee save regs */
  4729. + HOST_WIDE_INT save_reg_rounded;
  4730. + /* # bytes needed to store callee save regs (rounded) */
  4731. + HOST_WIDE_INT out_args_size; /* # bytes needed for outgoing args */
  4732. +
  4733. + save_reg_size = 0;
  4734. + var_size = STACK_ALIGN (get_frame_size ());
  4735. + out_args_size = STACK_ALIGN (current_function_outgoing_args_size);
  4736. +
  4737. + total_size = var_size + out_args_size;
  4738. +
  4739. + /* Calculate space needed for gp registers. */
  4740. + for (regno = 0; regno <= FIRST_PSEUDO_REGISTER; regno++)
  4741. + {
  4742. + if (MUST_SAVE_REGISTER (regno))
  4743. + {
  4744. + save_reg_size += 4;
  4745. + }
  4746. + }
  4747. +
  4748. + save_reg_rounded = STACK_ALIGN (save_reg_size);
  4749. + total_size += save_reg_rounded;
  4750. +
  4751. + total_size += STACK_ALIGN (current_function_pretend_args_size);
  4752. +
  4753. + /* Save other computed information. */
  4754. + cfun->machine->frame.total_size = total_size;
  4755. + cfun->machine->frame.var_size = var_size;
  4756. + cfun->machine->frame.args_size = current_function_outgoing_args_size;
  4757. + cfun->machine->frame.save_reg_size = save_reg_size;
  4758. + cfun->machine->frame.save_reg_rounded = save_reg_rounded;
  4759. + cfun->machine->frame.initialized = reload_completed;
  4760. + cfun->machine->frame.num_regs = save_reg_size / UNITS_PER_WORD;
  4761. +
  4762. + cfun->machine->frame.save_regs_offset
  4763. + = save_reg_rounded ? current_function_outgoing_args_size + var_size : 0;
  4764. +
  4765. + return total_size;
  4766. +}
  4767. +
  4768. +
  4769. +int
  4770. +nios2_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
  4771. +{
  4772. + int offset;
  4773. +
  4774. + /* Set OFFSET to the offset from the stack pointer. */
  4775. + switch (from)
  4776. + {
  4777. + case FRAME_POINTER_REGNUM:
  4778. + offset = 0;
  4779. + break;
  4780. +
  4781. + case ARG_POINTER_REGNUM:
  4782. + compute_frame_size ();
  4783. + offset = cfun->machine->frame.total_size;
  4784. + offset -= current_function_pretend_args_size;
  4785. + break;
  4786. +
  4787. + case RETURN_ADDRESS_POINTER_REGNUM:
  4788. + compute_frame_size ();
  4789. + /* since the return address is always the first of the
  4790. + saved registers, return the offset to the beginning
  4791. + of the saved registers block */
  4792. + offset = cfun->machine->frame.save_regs_offset;
  4793. + break;
  4794. +
  4795. + default:
  4796. + abort ();
  4797. + }
  4798. +
  4799. + return offset;
  4800. +}
  4801. +
  4802. +/* Return nonzero if this function is known to have a null epilogue.
  4803. + This allows the optimizer to omit jumps to jumps if no stack
  4804. + was created. */
  4805. +int
  4806. +nios2_can_use_return_insn ()
  4807. +{
  4808. + if (!reload_completed)
  4809. + return 0;
  4810. +
  4811. + if (regs_ever_live[RA_REGNO] || current_function_profile)
  4812. + return 0;
  4813. +
  4814. + if (cfun->machine->frame.initialized)
  4815. + return cfun->machine->frame.total_size == 0;
  4816. +
  4817. + return compute_frame_size () == 0;
  4818. +}
  4819. +
  4820. +
  4821. +
  4822. +
  4823. +
  4824. +/***************************************
  4825. + *
  4826. + ***************************************/
  4827. +
  4828. +/*
  4829. + * Try to take a bit of tedium out of the __builtin_custom_<blah>
  4830. + * builtin functions, too.
  4831. + */
  4832. +
  4833. +#define NIOS2_FOR_ALL_CUSTOM_BUILTINS \
  4834. + NIOS2_DO_BUILTIN (N, n, n ) \
  4835. + NIOS2_DO_BUILTIN (NI, ni, nX ) \
  4836. + NIOS2_DO_BUILTIN (NF, nf, nX ) \
  4837. + NIOS2_DO_BUILTIN (NP, np, nX ) \
  4838. + NIOS2_DO_BUILTIN (NII, nii, nXX ) \
  4839. + NIOS2_DO_BUILTIN (NIF, nif, nXX ) \
  4840. + NIOS2_DO_BUILTIN (NIP, nip, nXX ) \
  4841. + NIOS2_DO_BUILTIN (NFI, nfi, nXX ) \
  4842. + NIOS2_DO_BUILTIN (NFF, nff, nXX ) \
  4843. + NIOS2_DO_BUILTIN (NFP, nfp, nXX ) \
  4844. + NIOS2_DO_BUILTIN (NPI, npi, nXX ) \
  4845. + NIOS2_DO_BUILTIN (NPF, npf, nXX ) \
  4846. + NIOS2_DO_BUILTIN (NPP, npp, nXX ) \
  4847. + NIOS2_DO_BUILTIN (IN, in, Xn ) \
  4848. + NIOS2_DO_BUILTIN (INI, ini, XnX ) \
  4849. + NIOS2_DO_BUILTIN (INF, inf, XnX ) \
  4850. + NIOS2_DO_BUILTIN (INP, inp, XnX ) \
  4851. + NIOS2_DO_BUILTIN (INII, inii, XnXX ) \
  4852. + NIOS2_DO_BUILTIN (INIF, inif, XnXX ) \
  4853. + NIOS2_DO_BUILTIN (INIP, inip, XnXX ) \
  4854. + NIOS2_DO_BUILTIN (INFI, infi, XnXX ) \
  4855. + NIOS2_DO_BUILTIN (INFF, inff, XnXX ) \
  4856. + NIOS2_DO_BUILTIN (INFP, infp, XnXX ) \
  4857. + NIOS2_DO_BUILTIN (INPI, inpi, XnXX ) \
  4858. + NIOS2_DO_BUILTIN (INPF, inpf, XnXX ) \
  4859. + NIOS2_DO_BUILTIN (INPP, inpp, XnXX ) \
  4860. + NIOS2_DO_BUILTIN (FN, fn, Xn ) \
  4861. + NIOS2_DO_BUILTIN (FNI, fni, XnX ) \
  4862. + NIOS2_DO_BUILTIN (FNF, fnf, XnX ) \
  4863. + NIOS2_DO_BUILTIN (FNP, fnp, XnX ) \
  4864. + NIOS2_DO_BUILTIN (FNII, fnii, XnXX ) \
  4865. + NIOS2_DO_BUILTIN (FNIF, fnif, XnXX ) \
  4866. + NIOS2_DO_BUILTIN (FNIP, fnip, XnXX ) \
  4867. + NIOS2_DO_BUILTIN (FNFI, fnfi, XnXX ) \
  4868. + NIOS2_DO_BUILTIN (FNFF, fnff, XnXX ) \
  4869. + NIOS2_DO_BUILTIN (FNFP, fnfp, XnXX ) \
  4870. + NIOS2_DO_BUILTIN (FNPI, fnpi, XnXX ) \
  4871. + NIOS2_DO_BUILTIN (FNPF, fnpf, XnXX ) \
  4872. + NIOS2_DO_BUILTIN (FNPP, fnpp, XnXX ) \
  4873. + NIOS2_DO_BUILTIN (PN, pn, Xn ) \
  4874. + NIOS2_DO_BUILTIN (PNI, pni, XnX ) \
  4875. + NIOS2_DO_BUILTIN (PNF, pnf, XnX ) \
  4876. + NIOS2_DO_BUILTIN (PNP, pnp, XnX ) \
  4877. + NIOS2_DO_BUILTIN (PNII, pnii, XnXX ) \
  4878. + NIOS2_DO_BUILTIN (PNIF, pnif, XnXX ) \
  4879. + NIOS2_DO_BUILTIN (PNIP, pnip, XnXX ) \
  4880. + NIOS2_DO_BUILTIN (PNFI, pnfi, XnXX ) \
  4881. + NIOS2_DO_BUILTIN (PNFF, pnff, XnXX ) \
  4882. + NIOS2_DO_BUILTIN (PNFP, pnfp, XnXX ) \
  4883. + NIOS2_DO_BUILTIN (PNPI, pnpi, XnXX ) \
  4884. + NIOS2_DO_BUILTIN (PNPF, pnpf, XnXX ) \
  4885. + NIOS2_DO_BUILTIN (PNPP, pnpp, XnXX )
  4886. +
  4887. +const char *nios2_sys_nosys_string; /* for -msys=nosys */
  4888. +const char *nios2_sys_lib_string; /* for -msys-lib= */
  4889. +const char *nios2_sys_crt0_string; /* for -msys-crt0= */
  4890. +
  4891. +#undef NIOS2_FPU_INSN
  4892. +#define NIOS2_FPU_INSN(opt, insn, args) \
  4893. +static const char *NIOS2_CONCAT (nios2_output_fpu_insn_, insn) (rtx); \
  4894. +static void NIOS2_CONCAT (nios2_pragma_, insn) (struct cpp_reader *); \
  4895. +static void NIOS2_CONCAT (nios2_pragma_no_, insn) (struct cpp_reader *);
  4896. +NIOS2_FOR_ALL_FPU_INSNS
  4897. +
  4898. +nios2_fpu_info nios2_fpu_insns[nios2_fpu_max_insn] = {
  4899. +#undef NIOS2_FPU_INSN
  4900. +#define NIOS2_FPU_INSN(opt, insn, args) \
  4901. + { NIOS2_STRINGIFY (opt), \
  4902. + NIOS2_STRINGIFY (insn), \
  4903. + NIOS2_STRINGIFY (args), \
  4904. + 0, \
  4905. + -1, \
  4906. + NIOS2_CONCAT (nios2_output_fpu_insn_, insn), \
  4907. + "custom_" NIOS2_STRINGIFY (opt), \
  4908. + NIOS2_CONCAT (nios2_pragma_, insn), \
  4909. + "no_custom_" NIOS2_STRINGIFY (opt), \
  4910. + NIOS2_CONCAT (nios2_pragma_no_, insn), \
  4911. + 0, \
  4912. + 0, \
  4913. + 0, \
  4914. + 0, \
  4915. + 0 },
  4916. + NIOS2_FOR_ALL_FPU_INSNS
  4917. +};
  4918. +
  4919. +const char *nios2_custom_fpu_cfg_string;
  4920. +
  4921. +static const char *builtin_custom_seen[256];
  4922. +
  4923. +static void
  4924. +nios2_custom_switch (const char *parameter, int *value, const char *opt)
  4925. +{
  4926. + /*
  4927. + * We only document values from 0-255, but we secretly allow -1 so
  4928. + * that the -mno-custom-<opt> switches work.
  4929. + */
  4930. + if (parameter && *parameter)
  4931. + {
  4932. + char *endptr;
  4933. + long v = strtol (parameter, &endptr, 0);
  4934. + if (*endptr)
  4935. + {
  4936. + error ("switch `-mcustom-%s' value `%s' must be a number between 0 and 255",
  4937. + opt, parameter);
  4938. + }
  4939. + if (v < -1 || v > 255)
  4940. + {
  4941. + error ("switch `-mcustom-%s' value %ld must be between 0 and 255",
  4942. + opt, v);
  4943. + }
  4944. + *value = (int)v;
  4945. + }
  4946. +}
  4947. +
  4948. +static void
  4949. +nios2_custom_check_insns (int is_pragma)
  4950. +{
  4951. + int i;
  4952. + int has_double = 0;
  4953. + int errors = 0;
  4954. + const char *ns[256];
  4955. + int ps[256];
  4956. +
  4957. + for (i = 0; i < nios2_fpu_max_insn; i++)
  4958. + {
  4959. + if (nios2_fpu_insns[i].is_double && nios2_fpu_insns[i].N >= 0)
  4960. + {
  4961. + has_double = 1;
  4962. + }
  4963. + }
  4964. +
  4965. + if (has_double)
  4966. + {
  4967. + for (i = 0; i < nios2_fpu_max_insn; i++)
  4968. + {
  4969. + if (nios2_fpu_insns[i].needed_by_double
  4970. + && nios2_fpu_insns[i].N < 0)
  4971. + {
  4972. + if (is_pragma)
  4973. + {
  4974. + error ("either switch `-mcustom-%s' or `#pragma custom_%s' is required for double precision floating point",
  4975. + nios2_fpu_insns[i].option,
  4976. + nios2_fpu_insns[i].option);
  4977. + }
  4978. + else
  4979. + {
  4980. + error ("switch `-mcustom-%s' is required for double precision floating point",
  4981. + nios2_fpu_insns[i].option);
  4982. + }
  4983. + errors = 1;
  4984. + }
  4985. + }
  4986. + }
  4987. +
  4988. + /*
  4989. + * Warn if the user has certain exotic operations that won't get used
  4990. + * without -funsafe-math-optimizations, See expand_builtin () in
  4991. + * bulitins.c.
  4992. + */
  4993. + if (!flag_unsafe_math_optimizations)
  4994. + {
  4995. + for (i = 0; i < nios2_fpu_max_insn; i++)
  4996. + {
  4997. + if (nios2_fpu_insns[i].needs_unsafe && nios2_fpu_insns[i].N >= 0)
  4998. + {
  4999. + warning ("%s%s' has no effect unless -funsafe-math-optimizations is specified",
  5000. + is_pragma ? "`#pragma custom_" : "switch `-mcustom-",
  5001. + nios2_fpu_insns[i].option);
  5002. + /* Just one warning per function per compilation unit, please. */
  5003. + nios2_fpu_insns[i].needs_unsafe = 0;
  5004. + }
  5005. + }
  5006. + }
  5007. +
  5008. + /*
  5009. + * Warn if the user is trying to use -mcustom-fmins et. al, that won't
  5010. + * get used without -ffinite-math-only. See fold in fold () in
  5011. + * fold-const.c
  5012. + */
  5013. + if (!flag_finite_math_only)
  5014. + {
  5015. + for (i = 0; i < nios2_fpu_max_insn; i++)
  5016. + {
  5017. + if (nios2_fpu_insns[i].needs_finite && nios2_fpu_insns[i].N >= 0)
  5018. + {
  5019. + warning ("%s%s' has no effect unless -ffinite-math-only is specified",
  5020. + is_pragma ? "`#pragma custom_" : "switch `-mcustom-",
  5021. + nios2_fpu_insns[i].option);
  5022. + /* Just one warning per function per compilation unit, please. */
  5023. + nios2_fpu_insns[i].needs_finite = 0;
  5024. + }
  5025. + }
  5026. + }
  5027. +
  5028. + /*
  5029. + * Warn the user about double precision divide braindamage until we
  5030. + * can fix it properly. See the RDIV_EXPR case of expand_expr_real in
  5031. + * expr.c.
  5032. + */
  5033. + {
  5034. + static int warned = 0;
  5035. + if (flag_unsafe_math_optimizations
  5036. + && !optimize_size
  5037. + && nios2_fpu_insns[nios2_fpu_divdf3].N >= 0
  5038. + && !warned)
  5039. + {
  5040. + warning ("%s%s' behaves poorly without -Os",
  5041. + is_pragma ? "`#pragma custom_" : "switch `-mcustom-",
  5042. + nios2_fpu_insns[nios2_fpu_divdf3].option);
  5043. + warned = 1;
  5044. + }
  5045. + }
  5046. +
  5047. + /*
  5048. + * The following bit of voodoo is lifted from the generated file
  5049. + * insn-opinit.c: to allow #pragmas to work properly, we have to tweak
  5050. + * the optab_table manually -- it only gets initialized once after the
  5051. + * switches are handled and before any #pragmas are seen.
  5052. + */
  5053. + if (is_pragma)
  5054. + {
  5055. + /* Only do this if the optabs have already been defined, not
  5056. + when we're handling command line switches. */
  5057. + addv_optab->handlers[SFmode].insn_code =
  5058. + add_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5059. + addv_optab->handlers[DFmode].insn_code =
  5060. + add_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5061. + subv_optab->handlers[SFmode].insn_code =
  5062. + sub_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5063. + subv_optab->handlers[DFmode].insn_code =
  5064. + sub_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5065. + smulv_optab->handlers[SFmode].insn_code =
  5066. + smul_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5067. + smulv_optab->handlers[DFmode].insn_code =
  5068. + smul_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5069. + sdiv_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5070. + sdiv_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5071. + negv_optab->handlers[SFmode].insn_code =
  5072. + neg_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5073. + negv_optab->handlers[DFmode].insn_code =
  5074. + neg_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5075. + smin_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5076. + smin_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5077. + smax_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5078. + smax_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5079. + absv_optab->handlers[SFmode].insn_code =
  5080. + abs_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5081. + absv_optab->handlers[DFmode].insn_code =
  5082. + abs_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5083. + sqrt_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5084. + sqrt_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5085. + cos_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5086. + cos_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5087. + sin_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5088. + sin_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5089. + tan_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5090. + tan_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5091. + atan_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5092. + atan_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5093. + exp_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5094. + exp_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5095. + log_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5096. + log_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5097. + sfloat_optab->handlers[SFmode][SImode].insn_code = CODE_FOR_nothing;
  5098. + sfloat_optab->handlers[DFmode][SImode].insn_code = CODE_FOR_nothing;
  5099. + ufloat_optab->handlers[SFmode][SImode].insn_code = CODE_FOR_nothing;
  5100. + ufloat_optab->handlers[DFmode][SImode].insn_code = CODE_FOR_nothing;
  5101. + sfix_optab->handlers[SImode][SFmode].insn_code = CODE_FOR_nothing;
  5102. + sfix_optab->handlers[SImode][DFmode].insn_code = CODE_FOR_nothing;
  5103. + ufix_optab->handlers[SImode][SFmode].insn_code = CODE_FOR_nothing;
  5104. + ufix_optab->handlers[SImode][DFmode].insn_code = CODE_FOR_nothing;
  5105. + sext_optab->handlers[DFmode][SFmode].insn_code = CODE_FOR_nothing;
  5106. + trunc_optab->handlers[SFmode][DFmode].insn_code = CODE_FOR_nothing;
  5107. + cmp_optab->handlers[SFmode].insn_code = CODE_FOR_nothing;
  5108. + cmp_optab->handlers[DFmode].insn_code = CODE_FOR_nothing;
  5109. +
  5110. + if (HAVE_addsf3)
  5111. + addv_optab->handlers[SFmode].insn_code =
  5112. + add_optab->handlers[SFmode].insn_code = CODE_FOR_addsf3;
  5113. + if (HAVE_adddf3)
  5114. + addv_optab->handlers[DFmode].insn_code =
  5115. + add_optab->handlers[DFmode].insn_code = CODE_FOR_adddf3;
  5116. + if (HAVE_subsf3)
  5117. + subv_optab->handlers[SFmode].insn_code =
  5118. + sub_optab->handlers[SFmode].insn_code = CODE_FOR_subsf3;
  5119. + if (HAVE_subdf3)
  5120. + subv_optab->handlers[DFmode].insn_code =
  5121. + sub_optab->handlers[DFmode].insn_code = CODE_FOR_subdf3;
  5122. + if (HAVE_mulsf3)
  5123. + smulv_optab->handlers[SFmode].insn_code =
  5124. + smul_optab->handlers[SFmode].insn_code = CODE_FOR_mulsf3;
  5125. + if (HAVE_muldf3)
  5126. + smulv_optab->handlers[DFmode].insn_code =
  5127. + smul_optab->handlers[DFmode].insn_code = CODE_FOR_muldf3;
  5128. + if (HAVE_divsf3)
  5129. + sdiv_optab->handlers[SFmode].insn_code = CODE_FOR_divsf3;
  5130. + if (HAVE_divdf3)
  5131. + sdiv_optab->handlers[DFmode].insn_code = CODE_FOR_divdf3;
  5132. + if (HAVE_negsf2)
  5133. + negv_optab->handlers[SFmode].insn_code =
  5134. + neg_optab->handlers[SFmode].insn_code = CODE_FOR_negsf2;
  5135. + if (HAVE_negdf2)
  5136. + negv_optab->handlers[DFmode].insn_code =
  5137. + neg_optab->handlers[DFmode].insn_code = CODE_FOR_negdf2;
  5138. + if (HAVE_minsf3)
  5139. + smin_optab->handlers[SFmode].insn_code = CODE_FOR_minsf3;
  5140. + if (HAVE_mindf3)
  5141. + smin_optab->handlers[DFmode].insn_code = CODE_FOR_mindf3;
  5142. + if (HAVE_maxsf3)
  5143. + smax_optab->handlers[SFmode].insn_code = CODE_FOR_maxsf3;
  5144. + if (HAVE_maxdf3)
  5145. + smax_optab->handlers[DFmode].insn_code = CODE_FOR_maxdf3;
  5146. + if (HAVE_abssf2)
  5147. + absv_optab->handlers[SFmode].insn_code =
  5148. + abs_optab->handlers[SFmode].insn_code = CODE_FOR_abssf2;
  5149. + if (HAVE_absdf2)
  5150. + absv_optab->handlers[DFmode].insn_code =
  5151. + abs_optab->handlers[DFmode].insn_code = CODE_FOR_absdf2;
  5152. + if (HAVE_sqrtsf2)
  5153. + sqrt_optab->handlers[SFmode].insn_code = CODE_FOR_sqrtsf2;
  5154. + if (HAVE_sqrtdf2)
  5155. + sqrt_optab->handlers[DFmode].insn_code = CODE_FOR_sqrtdf2;
  5156. + if (HAVE_cossf2)
  5157. + cos_optab->handlers[SFmode].insn_code = CODE_FOR_cossf2;
  5158. + if (HAVE_cosdf2)
  5159. + cos_optab->handlers[DFmode].insn_code = CODE_FOR_cosdf2;
  5160. + if (HAVE_sinsf2)
  5161. + sin_optab->handlers[SFmode].insn_code = CODE_FOR_sinsf2;
  5162. + if (HAVE_sindf2)
  5163. + sin_optab->handlers[DFmode].insn_code = CODE_FOR_sindf2;
  5164. + if (HAVE_tansf2)
  5165. + tan_optab->handlers[SFmode].insn_code = CODE_FOR_tansf2;
  5166. + if (HAVE_tandf2)
  5167. + tan_optab->handlers[DFmode].insn_code = CODE_FOR_tandf2;
  5168. + if (HAVE_atansf2)
  5169. + atan_optab->handlers[SFmode].insn_code = CODE_FOR_atansf2;
  5170. + if (HAVE_atandf2)
  5171. + atan_optab->handlers[DFmode].insn_code = CODE_FOR_atandf2;
  5172. + if (HAVE_expsf2)
  5173. + exp_optab->handlers[SFmode].insn_code = CODE_FOR_expsf2;
  5174. + if (HAVE_expdf2)
  5175. + exp_optab->handlers[DFmode].insn_code = CODE_FOR_expdf2;
  5176. + if (HAVE_logsf2)
  5177. + log_optab->handlers[SFmode].insn_code = CODE_FOR_logsf2;
  5178. + if (HAVE_logdf2)
  5179. + log_optab->handlers[DFmode].insn_code = CODE_FOR_logdf2;
  5180. + if (HAVE_floatsisf2)
  5181. + sfloat_optab->handlers[SFmode][SImode].insn_code = CODE_FOR_floatsisf2;
  5182. + if (HAVE_floatsidf2)
  5183. + sfloat_optab->handlers[DFmode][SImode].insn_code = CODE_FOR_floatsidf2;
  5184. + if (HAVE_floatunssisf2)
  5185. + ufloat_optab->handlers[SFmode][SImode].insn_code = CODE_FOR_floatunssisf2;
  5186. + if (HAVE_floatunssidf2)
  5187. + ufloat_optab->handlers[DFmode][SImode].insn_code = CODE_FOR_floatunssidf2;
  5188. + if (HAVE_fixsfsi2)
  5189. + sfix_optab->handlers[SImode][SFmode].insn_code = CODE_FOR_fixsfsi2;
  5190. + if (HAVE_fixdfsi2)
  5191. + sfix_optab->handlers[SImode][DFmode].insn_code = CODE_FOR_fixdfsi2;
  5192. + if (HAVE_fixunssfsi2)
  5193. + ufix_optab->handlers[SImode][SFmode].insn_code = CODE_FOR_fixunssfsi2;
  5194. + if (HAVE_fixunsdfsi2)
  5195. + ufix_optab->handlers[SImode][DFmode].insn_code = CODE_FOR_fixunsdfsi2;
  5196. + if (HAVE_extendsfdf2)
  5197. + sext_optab->handlers[DFmode][SFmode].insn_code = CODE_FOR_extendsfdf2;
  5198. + if (HAVE_truncdfsf2)
  5199. + trunc_optab->handlers[SFmode][DFmode].insn_code = CODE_FOR_truncdfsf2;
  5200. + if (HAVE_cmpsf)
  5201. + cmp_optab->handlers[SFmode].insn_code = CODE_FOR_cmpsf;
  5202. + if (HAVE_cmpdf)
  5203. + cmp_optab->handlers[DFmode].insn_code = CODE_FOR_cmpdf;
  5204. + }
  5205. +
  5206. + /* Check for duplicate values of N */
  5207. + for (i = 0; i < 256; i++)
  5208. + {
  5209. + ns[i] = 0;
  5210. + ps[i] = 0;
  5211. + }
  5212. +
  5213. + for (i = 0; i < nios2_fpu_max_insn; i++)
  5214. + {
  5215. + int N = nios2_fpu_insns[i].N;
  5216. + if (N >= 0)
  5217. + {
  5218. + if (ns[N])
  5219. + {
  5220. + error ("%s%s' conflicts with %s%s'",
  5221. + is_pragma ? "`#pragma custom_" : "switch `-mcustom-",
  5222. + nios2_fpu_insns[i].option,
  5223. + ps[N] ? "`#pragma custom_" : "switch `-mcustom-",
  5224. + ns[N]);
  5225. + errors = 1;
  5226. + }
  5227. + else if (builtin_custom_seen[N])
  5228. + {
  5229. + error ("call to `%s' conflicts with %s%s'",
  5230. + builtin_custom_seen[N],
  5231. + (nios2_fpu_insns[i].pragma_seen
  5232. + ? "`#pragma custom_" : "switch `-mcustom-"),
  5233. + nios2_fpu_insns[i].option);
  5234. + errors = 1;
  5235. + }
  5236. + else
  5237. + {
  5238. + ns[N] = nios2_fpu_insns[i].option;
  5239. + ps[N] = nios2_fpu_insns[i].pragma_seen;
  5240. + }
  5241. + }
  5242. + }
  5243. +
  5244. + if (errors)
  5245. + {
  5246. + fatal_error ("conflicting use of -mcustom switches, #pragmas, and/or __builtin_custom_ functions");
  5247. + }
  5248. +}
  5249. +
  5250. +static void
  5251. +nios2_handle_custom_fpu_cfg (const char *cfg, int is_pragma)
  5252. +{
  5253. +#undef NIOS2_FPU_INSN
  5254. +#define NIOS2_FPU_INSN(opt, insn, args) \
  5255. + int opt = nios2_fpu_insns[NIOS2_CONCAT (nios2_fpu_, insn)].N;
  5256. +NIOS2_FOR_ALL_FPU_INSNS
  5257. +
  5258. + /*
  5259. + * ??? These are just some sample possibilities. We'll change these
  5260. + * at the last minute to match the capabilities of the actual fpu.
  5261. + */
  5262. + if (!strcasecmp (cfg, "60-1"))
  5263. + {
  5264. + fmuls = 252;
  5265. + fadds = 253;
  5266. + fsubs = 254;
  5267. + flag_single_precision_constant = 1;
  5268. + }
  5269. + else if (!strcasecmp (cfg, "60-2"))
  5270. + {
  5271. + fmuls = 252;
  5272. + fadds = 253;
  5273. + fsubs = 254;
  5274. + fdivs = 255;
  5275. + flag_single_precision_constant = 1;
  5276. + }
  5277. + else if (!strcasecmp (cfg, "72-3"))
  5278. + {
  5279. + floatus = 243;
  5280. + fixsi = 244;
  5281. + floatis = 245;
  5282. + fcmpgts = 246;
  5283. + fcmples = 249;
  5284. + fcmpeqs = 250;
  5285. + fcmpnes = 251;
  5286. + fmuls = 252;
  5287. + fadds = 253;
  5288. + fsubs = 254;
  5289. + fdivs = 255;
  5290. + flag_single_precision_constant = 1;
  5291. + }
  5292. + else
  5293. + {
  5294. + warning ("ignoring unrecognized %sfpu-cfg' value `%s'",
  5295. + is_pragma ? "`#pragma custom_" : "switch -mcustom-", cfg);
  5296. + }
  5297. +
  5298. +#undef NIOS2_FPU_INSN
  5299. +#define NIOS2_FPU_INSN(opt, insn, args) \
  5300. + nios2_fpu_insns[NIOS2_CONCAT (nios2_fpu_, insn)].N = opt;
  5301. +NIOS2_FOR_ALL_FPU_INSNS
  5302. +
  5303. + /* Guard against errors in the standard configurations. */
  5304. + nios2_custom_check_insns (is_pragma);
  5305. +}
  5306. +
  5307. +void
  5308. +override_options ()
  5309. +{
  5310. + int i;
  5311. +
  5312. + /* Function to allocate machine-dependent function status. */
  5313. + init_machine_status = &nios2_init_machine_status;
  5314. +
  5315. + nios2_section_threshold
  5316. + = g_switch_set ? g_switch_value : NIOS2_DEFAULT_GVALUE;
  5317. +
  5318. + if (nios2_sys_nosys_string && *nios2_sys_nosys_string)
  5319. + {
  5320. + error ("invalid option '-msys=nosys%s'", nios2_sys_nosys_string);
  5321. + }
  5322. +
  5323. + /* If we don't have mul, we don't have mulx either! */
  5324. + if (!TARGET_HAS_MUL && TARGET_HAS_MULX)
  5325. + {
  5326. + target_flags &= ~HAS_MULX_FLAG;
  5327. + }
  5328. +
  5329. + /* Set up for stack limit checking */
  5330. + if (TARGET_STACK_CHECK)
  5331. + {
  5332. + stack_limit_rtx = gen_rtx_REG(SImode, ET_REGNO);
  5333. + }
  5334. +
  5335. + for (i = 0; i < nios2_fpu_max_insn; i++)
  5336. + {
  5337. + nios2_fpu_insns[i].is_double = (nios2_fpu_insns[i].args[0] == 'd'
  5338. + || nios2_fpu_insns[i].args[0] == 'd'
  5339. + || nios2_fpu_insns[i].args[0] == 'd');
  5340. + nios2_fpu_insns[i].needed_by_double = (i == nios2_fpu_nios2_fwrx
  5341. + || i == nios2_fpu_nios2_fwry
  5342. + || i == nios2_fpu_nios2_frdxlo
  5343. + || i == nios2_fpu_nios2_frdxhi
  5344. + || i == nios2_fpu_nios2_frdy);
  5345. + nios2_fpu_insns[i].needs_unsafe = (i == nios2_fpu_cossf2
  5346. + || i == nios2_fpu_cosdf2
  5347. + || i == nios2_fpu_sinsf2
  5348. + || i == nios2_fpu_sindf2
  5349. + || i == nios2_fpu_tansf2
  5350. + || i == nios2_fpu_tandf2
  5351. + || i == nios2_fpu_atansf2
  5352. + || i == nios2_fpu_atandf2
  5353. + || i == nios2_fpu_expsf2
  5354. + || i == nios2_fpu_expdf2
  5355. + || i == nios2_fpu_logsf2
  5356. + || i == nios2_fpu_logdf2);
  5357. + nios2_fpu_insns[i].needs_finite = (i == nios2_fpu_minsf3
  5358. + || i == nios2_fpu_maxsf3
  5359. + || i == nios2_fpu_mindf3
  5360. + || i == nios2_fpu_maxdf3);
  5361. + }
  5362. +
  5363. + /*
  5364. + * We haven't seen any __builtin_custom functions yet.
  5365. + */
  5366. + for (i = 0; i < 256; i++)
  5367. + {
  5368. + builtin_custom_seen[i] = 0;
  5369. + }
  5370. +
  5371. + /*
  5372. + * Set up default handling for floating point custom instructions.
  5373. + *
  5374. + * Putting things in this order means that the -mcustom-fpu-cfg=
  5375. + * switch will always be overridden by individual -mcustom-fadds=
  5376. + * switches, regardless of the order in which they were specified
  5377. + * on the command line. ??? Remember to document this.
  5378. + */
  5379. + if (nios2_custom_fpu_cfg_string && *nios2_custom_fpu_cfg_string)
  5380. + {
  5381. + nios2_handle_custom_fpu_cfg (nios2_custom_fpu_cfg_string, 0);
  5382. + }
  5383. +
  5384. + for (i = 0; i < nios2_fpu_max_insn; i++)
  5385. + {
  5386. + nios2_custom_switch (nios2_fpu_insns[i].value,
  5387. + &nios2_fpu_insns[i].N,
  5388. + nios2_fpu_insns[i].option);
  5389. + }
  5390. +
  5391. + nios2_custom_check_insns (0);
  5392. +}
  5393. +
  5394. +void
  5395. +optimization_options (int level, int size)
  5396. +{
  5397. + if (level || size)
  5398. + {
  5399. + target_flags |= INLINE_MEMCPY_FLAG;
  5400. + }
  5401. +
  5402. + if (level >= 3 && !size)
  5403. + {
  5404. + target_flags |= FAST_SW_DIV_FLAG;
  5405. + }
  5406. +}
  5407. +
  5408. +/* Allocate a chunk of memory for per-function machine-dependent data. */
  5409. +static struct machine_function *
  5410. +nios2_init_machine_status ()
  5411. +{
  5412. + return ((struct machine_function *)
  5413. + ggc_alloc_cleared (sizeof (struct machine_function)));
  5414. +}
  5415. +
  5416. +
  5417. +
  5418. +/*****************
  5419. + * Describing Relative Costs of Operations
  5420. + *****************/
  5421. +
  5422. +/* Compute a (partial) cost for rtx X. Return true if the complete
  5423. + cost has been computed, and false if subexpressions should be
  5424. + scanned. In either case, *TOTAL contains the cost result. */
  5425. +
  5426. +
  5427. +
  5428. +static bool
  5429. +nios2_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total)
  5430. +{
  5431. + switch (code)
  5432. + {
  5433. + case CONST_INT:
  5434. + if (INTVAL (x) == 0)
  5435. + {
  5436. + *total = COSTS_N_INSNS (0);
  5437. + return true;
  5438. + }
  5439. + else if (SMALL_INT (INTVAL (x))
  5440. + || SMALL_INT_UNSIGNED (INTVAL (x))
  5441. + || UPPER16_INT (INTVAL (x)))
  5442. + {
  5443. + *total = COSTS_N_INSNS (2);
  5444. + return true;
  5445. + }
  5446. + else
  5447. + {
  5448. + *total = COSTS_N_INSNS (4);
  5449. + return true;
  5450. + }
  5451. +
  5452. + case LABEL_REF:
  5453. + case SYMBOL_REF:
  5454. + /* ??? gp relative stuff will fit in here */
  5455. + /* fall through */
  5456. + case CONST:
  5457. + case CONST_DOUBLE:
  5458. + {
  5459. + *total = COSTS_N_INSNS (4);
  5460. + return true;
  5461. + }
  5462. +
  5463. + case MULT:
  5464. + {
  5465. + *total = COSTS_N_INSNS (1);
  5466. + return false;
  5467. + }
  5468. + case SIGN_EXTEND:
  5469. + {
  5470. + *total = COSTS_N_INSNS (3);
  5471. + return false;
  5472. + }
  5473. + case ZERO_EXTEND:
  5474. + {
  5475. + *total = COSTS_N_INSNS (1);
  5476. + return false;
  5477. + }
  5478. +
  5479. + default:
  5480. + return false;
  5481. + }
  5482. +}
  5483. +
  5484. +
  5485. +/***************************************
  5486. + * INSTRUCTION SUPPORT
  5487. + *
  5488. + * These functions are used within the Machine Description to
  5489. + * handle common or complicated output and expansions from
  5490. + * instructions.
  5491. + ***************************************/
  5492. +
  5493. +int
  5494. +nios2_emit_move_sequence (rtx *operands, enum machine_mode mode)
  5495. +{
  5496. + rtx to = operands[0];
  5497. + rtx from = operands[1];
  5498. +
  5499. + if (!register_operand (to, mode) && !reg_or_0_operand (from, mode))
  5500. + {
  5501. + if (no_new_pseudos)
  5502. + internal_error ("Trying to force_reg no_new_pseudos == 1");
  5503. + from = copy_to_mode_reg (mode, from);
  5504. + }
  5505. +
  5506. + operands[0] = to;
  5507. + operands[1] = from;
  5508. + return 0;
  5509. +}
  5510. +
  5511. +/* Divide Support */
  5512. +
  5513. +/*
  5514. + If -O3 is used, we want to output a table lookup for
  5515. + divides between small numbers (both num and den >= 0
  5516. + and < 0x10). The overhead of this method in the worse
  5517. + case is 40 bytes in the text section (10 insns) and
  5518. + 256 bytes in the data section. Additional divides do
  5519. + not incur additional penalties in the data section.
  5520. +
  5521. + Code speed is improved for small divides by about 5x
  5522. + when using this method in the worse case (~9 cycles
  5523. + vs ~45). And in the worse case divides not within the
  5524. + table are penalized by about 10% (~5 cycles vs ~45).
  5525. + However in the typical case the penalty is not as bad
  5526. + because doing the long divide in only 45 cycles is
  5527. + quite optimistic.
  5528. +
  5529. + ??? It would be nice to have some benchmarks other
  5530. + than Dhrystone to back this up.
  5531. +
  5532. + This bit of expansion is to create this instruction
  5533. + sequence as rtl.
  5534. + or $8, $4, $5
  5535. + slli $9, $4, 4
  5536. + cmpgeui $3, $8, 16
  5537. + beq $3, $0, .L3
  5538. + or $10, $9, $5
  5539. + add $12, $11, divide_table
  5540. + ldbu $2, 0($12)
  5541. + br .L1
  5542. +.L3:
  5543. + call slow_div
  5544. +.L1:
  5545. +# continue here with result in $2
  5546. +
  5547. + ??? Ideally I would like the emit libcall block to contain
  5548. + all of this code, but I don't know how to do that. What it
  5549. + means is that if the divide can be eliminated, it may not
  5550. + completely disappear.
  5551. +
  5552. + ??? The __divsi3_table label should ideally be moved out
  5553. + of this block and into a global. If it is placed into the
  5554. + sdata section we can save even more cycles by doing things
  5555. + gp relative.
  5556. +*/
  5557. +int
  5558. +nios2_emit_expensive_div (rtx *operands, enum machine_mode mode)
  5559. +{
  5560. + rtx or_result, shift_left_result;
  5561. + rtx lookup_value;
  5562. + rtx lab1, lab3;
  5563. + rtx insns;
  5564. + rtx libfunc;
  5565. + rtx final_result;
  5566. + rtx tmp;
  5567. +
  5568. + /* it may look a little generic, but only SImode
  5569. + is supported for now */
  5570. + if (mode != SImode)
  5571. + abort ();
  5572. +
  5573. + libfunc = sdiv_optab->handlers[(int) SImode].libfunc;
  5574. +
  5575. +
  5576. +
  5577. + lab1 = gen_label_rtx ();
  5578. + lab3 = gen_label_rtx ();
  5579. +
  5580. + or_result = expand_simple_binop (SImode, IOR,
  5581. + operands[1], operands[2],
  5582. + 0, 0, OPTAB_LIB_WIDEN);
  5583. +
  5584. + emit_cmp_and_jump_insns (or_result, GEN_INT (15), GTU, 0,
  5585. + GET_MODE (or_result), 0, lab3);
  5586. + JUMP_LABEL (get_last_insn ()) = lab3;
  5587. +
  5588. + shift_left_result = expand_simple_binop (SImode, ASHIFT,
  5589. + operands[1], GEN_INT (4),
  5590. + 0, 0, OPTAB_LIB_WIDEN);
  5591. +
  5592. + lookup_value = expand_simple_binop (SImode, IOR,
  5593. + shift_left_result, operands[2],
  5594. + 0, 0, OPTAB_LIB_WIDEN);
  5595. +
  5596. + convert_move (operands[0],
  5597. + gen_rtx (MEM, QImode,
  5598. + gen_rtx (PLUS, SImode,
  5599. + lookup_value,
  5600. + gen_rtx_SYMBOL_REF (SImode, "__divsi3_table"))),
  5601. + 1);
  5602. +
  5603. +
  5604. + tmp = emit_jump_insn (gen_jump (lab1));
  5605. + JUMP_LABEL (tmp) = lab1;
  5606. + emit_barrier ();
  5607. +
  5608. + emit_label (lab3);
  5609. + LABEL_NUSES (lab3) = 1;
  5610. +
  5611. + start_sequence ();
  5612. + final_result = emit_library_call_value (libfunc, NULL_RTX,
  5613. + LCT_CONST, SImode, 2,
  5614. + operands[1], SImode,
  5615. + operands[2], SImode);
  5616. +
  5617. +
  5618. + insns = get_insns ();
  5619. + end_sequence ();
  5620. + emit_libcall_block (insns, operands[0], final_result,
  5621. + gen_rtx (DIV, SImode, operands[1], operands[2]));
  5622. +
  5623. + emit_label (lab1);
  5624. + LABEL_NUSES (lab1) = 1;
  5625. + return 1;
  5626. +}
  5627. +
  5628. +/* Branches/Compares */
  5629. +
  5630. +/* the way of handling branches/compares
  5631. + in gcc is heavily borrowed from MIPS */
  5632. +
  5633. +enum internal_test
  5634. +{
  5635. + ITEST_EQ,
  5636. + ITEST_NE,
  5637. + ITEST_GT,
  5638. + ITEST_GE,
  5639. + ITEST_LT,
  5640. + ITEST_LE,
  5641. + ITEST_GTU,
  5642. + ITEST_GEU,
  5643. + ITEST_LTU,
  5644. + ITEST_LEU,
  5645. + ITEST_MAX
  5646. +};
  5647. +
  5648. +static enum internal_test map_test_to_internal_test (enum rtx_code);
  5649. +
  5650. +/* Cached operands, and operator to compare for use in set/branch/trap
  5651. + on condition codes. */
  5652. +rtx branch_cmp[2];
  5653. +enum cmp_type branch_type;
  5654. +
  5655. +/* Make normal rtx_code into something we can index from an array */
  5656. +
  5657. +static enum internal_test
  5658. +map_test_to_internal_test (enum rtx_code test_code)
  5659. +{
  5660. + enum internal_test test = ITEST_MAX;
  5661. +
  5662. + switch (test_code)
  5663. + {
  5664. + case EQ:
  5665. + test = ITEST_EQ;
  5666. + break;
  5667. + case NE:
  5668. + test = ITEST_NE;
  5669. + break;
  5670. + case GT:
  5671. + test = ITEST_GT;
  5672. + break;
  5673. + case GE:
  5674. + test = ITEST_GE;
  5675. + break;
  5676. + case LT:
  5677. + test = ITEST_LT;
  5678. + break;
  5679. + case LE:
  5680. + test = ITEST_LE;
  5681. + break;
  5682. + case GTU:
  5683. + test = ITEST_GTU;
  5684. + break;
  5685. + case GEU:
  5686. + test = ITEST_GEU;
  5687. + break;
  5688. + case LTU:
  5689. + test = ITEST_LTU;
  5690. + break;
  5691. + case LEU:
  5692. + test = ITEST_LEU;
  5693. + break;
  5694. + default:
  5695. + break;
  5696. + }
  5697. +
  5698. + return test;
  5699. +}
  5700. +
  5701. +bool have_nios2_fpu_cmp_insn( enum rtx_code cond_t, enum cmp_type cmp_t );
  5702. +enum rtx_code get_reverse_cond(enum rtx_code cond_t);
  5703. +
  5704. +bool
  5705. +have_nios2_fpu_cmp_insn( enum rtx_code cond_t, enum cmp_type cmp_t )
  5706. +{
  5707. + if (cmp_t == CMP_SF)
  5708. + {
  5709. + switch (cond_t) {
  5710. + case EQ:
  5711. + return (nios2_fpu_insns[nios2_fpu_nios2_seqsf].N >= 0);
  5712. + case NE:
  5713. + return (nios2_fpu_insns[nios2_fpu_nios2_snesf].N >= 0);
  5714. + case GT:
  5715. + return (nios2_fpu_insns[nios2_fpu_nios2_sgtsf].N >= 0);
  5716. + case GE:
  5717. + return (nios2_fpu_insns[nios2_fpu_nios2_sgesf].N >= 0);
  5718. + case LT:
  5719. + return (nios2_fpu_insns[nios2_fpu_nios2_sltsf].N >= 0);
  5720. + case LE:
  5721. + return (nios2_fpu_insns[nios2_fpu_nios2_slesf].N >= 0);
  5722. + default:
  5723. + break;
  5724. + }
  5725. + }
  5726. + else if (cmp_t == CMP_DF)
  5727. + {
  5728. + switch (cond_t) {
  5729. + case EQ:
  5730. + return (nios2_fpu_insns[nios2_fpu_nios2_seqdf].N >= 0);
  5731. + case NE:
  5732. + return (nios2_fpu_insns[nios2_fpu_nios2_snedf].N >= 0);
  5733. + case GT:
  5734. + return (nios2_fpu_insns[nios2_fpu_nios2_sgtdf].N >= 0);
  5735. + case GE:
  5736. + return (nios2_fpu_insns[nios2_fpu_nios2_sgedf].N >= 0);
  5737. + case LT:
  5738. + return (nios2_fpu_insns[nios2_fpu_nios2_sltdf].N >= 0);
  5739. + case LE:
  5740. + return (nios2_fpu_insns[nios2_fpu_nios2_sledf].N >= 0);
  5741. + default:
  5742. + break;
  5743. + }
  5744. + }
  5745. +
  5746. + return false;
  5747. +}
  5748. +
  5749. +/* Note that get_reverse_cond() is not the same as get_inverse_cond()
  5750. + get_reverse_cond() means that if the operand order is reversed,
  5751. + what is the operand that is needed to generate the same condition?
  5752. +*/
  5753. +enum rtx_code
  5754. +get_reverse_cond(enum rtx_code cond_t)
  5755. +{
  5756. + switch (cond_t)
  5757. + {
  5758. + case GT: return LT;
  5759. + case GE: return LE;
  5760. + case LT: return GT;
  5761. + case LE: return GE;
  5762. + case GTU: return LTU;
  5763. + case GEU: return LEU;
  5764. + case LTU: return GTU;
  5765. + case LEU: return GEU;
  5766. + default: break;
  5767. + }
  5768. +
  5769. + return cond_t;
  5770. +}
  5771. +
  5772. +
  5773. +/* Generate the code to compare (and possibly branch) two integer values
  5774. + TEST_CODE is the comparison code we are trying to emulate
  5775. + (or implement directly)
  5776. + RESULT is where to store the result of the comparison,
  5777. + or null to emit a branch
  5778. + CMP0 CMP1 are the two comparison operands
  5779. + DESTINATION is the destination of the branch, or null to only compare
  5780. + */
  5781. +
  5782. +void
  5783. +gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
  5784. + rtx result, /* result to store comp. or 0 if branch */
  5785. + rtx cmp0, /* first operand to compare */
  5786. + rtx cmp1, /* second operand to compare */
  5787. + rtx destination) /* destination of the branch, or 0 if compare */
  5788. +{
  5789. + struct cmp_info
  5790. + {
  5791. + /* for register (or 0) compares */
  5792. + enum rtx_code test_code_reg; /* code to use in instruction (LT vs. LTU) */
  5793. + int reverse_regs; /* reverse registers in test */
  5794. +
  5795. + /* for immediate compares */
  5796. + enum rtx_code test_code_const;
  5797. + /* code to use in instruction (LT vs. LTU) */
  5798. + int const_low; /* low bound of constant we can accept */
  5799. + int const_high; /* high bound of constant we can accept */
  5800. + int const_add; /* constant to add */
  5801. +
  5802. + /* generic info */
  5803. + int unsignedp; /* != 0 for unsigned comparisons. */
  5804. + };
  5805. +
  5806. + static const struct cmp_info info[(int) ITEST_MAX] = {
  5807. +
  5808. + {EQ, 0, EQ, -32768, 32767, 0, 0}, /* EQ */
  5809. + {NE, 0, NE, -32768, 32767, 0, 0}, /* NE */
  5810. +
  5811. + {LT, 1, GE, -32769, 32766, 1, 0}, /* GT */
  5812. + {GE, 0, GE, -32768, 32767, 0, 0}, /* GE */
  5813. + {LT, 0, LT, -32768, 32767, 0, 0}, /* LT */
  5814. + {GE, 1, LT, -32769, 32766, 1, 0}, /* LE */
  5815. +
  5816. + {LTU, 1, GEU, 0, 65534, 1, 0}, /* GTU */
  5817. + {GEU, 0, GEU, 0, 65535, 0, 0}, /* GEU */
  5818. + {LTU, 0, LTU, 0, 65535, 0, 0}, /* LTU */
  5819. + {GEU, 1, LTU, 0, 65534, 1, 0}, /* LEU */
  5820. + };
  5821. +
  5822. + enum internal_test test;
  5823. + enum machine_mode mode;
  5824. + const struct cmp_info *p_info;
  5825. + int branch_p;
  5826. +
  5827. +
  5828. + test = map_test_to_internal_test (test_code);
  5829. + if (test == ITEST_MAX)
  5830. + abort ();
  5831. +
  5832. + p_info = &info[(int) test];
  5833. +
  5834. + mode = GET_MODE (cmp0);
  5835. + if (mode == VOIDmode)
  5836. + mode = GET_MODE (cmp1);
  5837. +
  5838. + branch_p = (destination != 0);
  5839. +
  5840. + /* Handle floating point comparison directly. */
  5841. + if (branch_type == CMP_SF || branch_type == CMP_DF)
  5842. + {
  5843. +
  5844. + bool reverse_operands = false;
  5845. +
  5846. + enum machine_mode float_mode = (branch_type == CMP_SF) ? SFmode : DFmode;
  5847. +
  5848. + if (!register_operand (cmp0, float_mode)
  5849. + || !register_operand (cmp1, float_mode))
  5850. + {
  5851. + abort ();
  5852. + }
  5853. +
  5854. + if (branch_p)
  5855. + {
  5856. + test_code = p_info->test_code_reg;
  5857. + reverse_operands = (p_info->reverse_regs);
  5858. + }
  5859. +
  5860. + if ( !have_nios2_fpu_cmp_insn(test_code, branch_type) &&
  5861. + have_nios2_fpu_cmp_insn(get_reverse_cond(test_code), branch_type) )
  5862. + {
  5863. + test_code = get_reverse_cond(test_code);
  5864. + reverse_operands = !reverse_operands;
  5865. + }
  5866. +
  5867. + if (reverse_operands)
  5868. + {
  5869. + rtx temp = cmp0;
  5870. + cmp0 = cmp1;
  5871. + cmp1 = temp;
  5872. + }
  5873. +
  5874. + if (branch_p)
  5875. + {
  5876. + rtx cond = gen_rtx (test_code, SImode, cmp0, cmp1);
  5877. + rtx label = gen_rtx_LABEL_REF (VOIDmode, destination);
  5878. + rtx insn = gen_rtx_SET (VOIDmode, pc_rtx,
  5879. + gen_rtx_IF_THEN_ELSE (VOIDmode,
  5880. + cond, label, pc_rtx));
  5881. + emit_jump_insn (insn);
  5882. + }
  5883. + else
  5884. + {
  5885. + emit_move_insn (result, gen_rtx (test_code, SImode, cmp0, cmp1));
  5886. + }
  5887. + return;
  5888. + }
  5889. +
  5890. + /* We can't, under any circumstances, have const_ints in cmp0
  5891. + ??? Actually we could have const0 */
  5892. + if (GET_CODE (cmp0) == CONST_INT)
  5893. + cmp0 = force_reg (mode, cmp0);
  5894. +
  5895. + /* if the comparison is against an int not in legal range
  5896. + move it into a register */
  5897. + if (GET_CODE (cmp1) == CONST_INT)
  5898. + {
  5899. + HOST_WIDE_INT value = INTVAL (cmp1);
  5900. +
  5901. + if (value < p_info->const_low || value > p_info->const_high)
  5902. + cmp1 = force_reg (mode, cmp1);
  5903. + }
  5904. +
  5905. + /* Comparison to constants, may involve adding 1 to change a GT into GE.
  5906. + Comparison between two registers, may involve switching operands. */
  5907. + if (GET_CODE (cmp1) == CONST_INT)
  5908. + {
  5909. + if (p_info->const_add != 0)
  5910. + {
  5911. + HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
  5912. +
  5913. + /* If modification of cmp1 caused overflow,
  5914. + we would get the wrong answer if we follow the usual path;
  5915. + thus, x > 0xffffffffU would turn into x > 0U. */
  5916. + if ((p_info->unsignedp
  5917. + ? (unsigned HOST_WIDE_INT) new >
  5918. + (unsigned HOST_WIDE_INT) INTVAL (cmp1)
  5919. + : new > INTVAL (cmp1)) != (p_info->const_add > 0))
  5920. + {
  5921. + /* ??? This case can never happen with the current numbers,
  5922. + but I am paranoid and would rather an abort than
  5923. + a bug I will never find */
  5924. + abort ();
  5925. + }
  5926. + else
  5927. + cmp1 = GEN_INT (new);
  5928. + }
  5929. + }
  5930. +
  5931. + else if (p_info->reverse_regs)
  5932. + {
  5933. + rtx temp = cmp0;
  5934. + cmp0 = cmp1;
  5935. + cmp1 = temp;
  5936. + }
  5937. +
  5938. +
  5939. +
  5940. + if (branch_p)
  5941. + {
  5942. + if (register_operand (cmp0, mode) && register_operand (cmp1, mode))
  5943. + {
  5944. + rtx insn;
  5945. + rtx cond = gen_rtx (p_info->test_code_reg, mode, cmp0, cmp1);
  5946. + rtx label = gen_rtx_LABEL_REF (VOIDmode, destination);
  5947. +
  5948. + insn = gen_rtx_SET (VOIDmode, pc_rtx,
  5949. + gen_rtx_IF_THEN_ELSE (VOIDmode,
  5950. + cond, label, pc_rtx));
  5951. + emit_jump_insn (insn);
  5952. + }
  5953. + else
  5954. + {
  5955. + rtx cond, label;
  5956. +
  5957. + result = gen_reg_rtx (mode);
  5958. +
  5959. + emit_move_insn (result,
  5960. + gen_rtx (p_info->test_code_const, mode, cmp0,
  5961. + cmp1));
  5962. +
  5963. + cond = gen_rtx (NE, mode, result, const0_rtx);
  5964. + label = gen_rtx_LABEL_REF (VOIDmode, destination);
  5965. +
  5966. + emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
  5967. + gen_rtx_IF_THEN_ELSE (VOIDmode,
  5968. + cond,
  5969. + label, pc_rtx)));
  5970. + }
  5971. + }
  5972. + else
  5973. + {
  5974. + if (register_operand (cmp0, mode) && register_operand (cmp1, mode))
  5975. + {
  5976. + emit_move_insn (result,
  5977. + gen_rtx (p_info->test_code_reg, mode, cmp0, cmp1));
  5978. + }
  5979. + else
  5980. + {
  5981. + emit_move_insn (result,
  5982. + gen_rtx (p_info->test_code_const, mode, cmp0,
  5983. + cmp1));
  5984. + }
  5985. + }
  5986. +
  5987. +}
  5988. +
  5989. +
  5990. +/* ??? For now conditional moves are only supported
  5991. + when the mode of the operands being compared are
  5992. + the same as the ones being moved */
  5993. +
  5994. +void
  5995. +gen_conditional_move (rtx *operands, enum machine_mode mode)
  5996. +{
  5997. + rtx insn, cond;
  5998. + rtx cmp_reg = gen_reg_rtx (mode);
  5999. + enum rtx_code cmp_code = GET_CODE (operands[1]);
  6000. + enum rtx_code move_code = EQ;
  6001. +
  6002. + /* emit a comparison if it is not "simple".
  6003. + Simple comparisons are X eq 0 and X ne 0 */
  6004. + if ((cmp_code == EQ || cmp_code == NE) && branch_cmp[1] == const0_rtx)
  6005. + {
  6006. + cmp_reg = branch_cmp[0];
  6007. + move_code = cmp_code;
  6008. + }
  6009. + else if ((cmp_code == EQ || cmp_code == NE) && branch_cmp[0] == const0_rtx)
  6010. + {
  6011. + cmp_reg = branch_cmp[1];
  6012. + move_code = cmp_code == EQ ? NE : EQ;
  6013. + }
  6014. + else
  6015. + gen_int_relational (cmp_code, cmp_reg, branch_cmp[0], branch_cmp[1],
  6016. + NULL_RTX);
  6017. +
  6018. + cond = gen_rtx (move_code, VOIDmode, cmp_reg, CONST0_RTX (mode));
  6019. + insn = gen_rtx_SET (mode, operands[0],
  6020. + gen_rtx_IF_THEN_ELSE (mode,
  6021. + cond, operands[2], operands[3]));
  6022. + emit_insn (insn);
  6023. +}
  6024. +
  6025. +/*******************
  6026. + * Addressing Modes
  6027. + *******************/
  6028. +
  6029. +int
  6030. +nios2_legitimate_address (rtx operand, enum machine_mode mode ATTRIBUTE_UNUSED,
  6031. + int strict)
  6032. +{
  6033. + int ret_val = 0;
  6034. +
  6035. + switch (GET_CODE (operand))
  6036. + {
  6037. + /* direct. */
  6038. + case SYMBOL_REF:
  6039. + if (SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (operand))
  6040. + {
  6041. + ret_val = 1;
  6042. + break;
  6043. + }
  6044. + /* else, fall through */
  6045. + case LABEL_REF:
  6046. + case CONST_INT:
  6047. + case CONST:
  6048. + case CONST_DOUBLE:
  6049. + /* ??? In here I need to add gp addressing */
  6050. + ret_val = 0;
  6051. +
  6052. + break;
  6053. +
  6054. + /* Register indirect. */
  6055. + case REG:
  6056. + ret_val = REG_OK_FOR_BASE_P2 (operand, strict);
  6057. + break;
  6058. +
  6059. + /* Register indirect with displacement */
  6060. + case PLUS:
  6061. + {
  6062. + rtx op0 = XEXP (operand, 0);
  6063. + rtx op1 = XEXP (operand, 1);
  6064. +
  6065. + if (REG_P (op0) && REG_P (op1))
  6066. + ret_val = 0;
  6067. + else if (REG_P (op0) && GET_CODE (op1) == CONST_INT)
  6068. + ret_val = REG_OK_FOR_BASE_P2 (op0, strict)
  6069. + && SMALL_INT (INTVAL (op1));
  6070. + else if (REG_P (op1) && GET_CODE (op0) == CONST_INT)
  6071. + ret_val = REG_OK_FOR_BASE_P2 (op1, strict)
  6072. + && SMALL_INT (INTVAL (op0));
  6073. + else
  6074. + ret_val = 0;
  6075. + }
  6076. + break;
  6077. +
  6078. + default:
  6079. + ret_val = 0;
  6080. + break;
  6081. + }
  6082. +
  6083. + return ret_val;
  6084. +}
  6085. +
  6086. +/* Return true if EXP should be placed in the small data section. */
  6087. +
  6088. +static bool
  6089. +nios2_in_small_data_p (tree exp)
  6090. +{
  6091. + /* We want to merge strings, so we never consider them small data. */
  6092. + if (TREE_CODE (exp) == STRING_CST)
  6093. + return false;
  6094. +
  6095. + if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
  6096. + {
  6097. + const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
  6098. + /* ??? these string names need moving into
  6099. + an array in some header file */
  6100. + if (nios2_section_threshold > 0
  6101. + && (strcmp (section, ".sbss") == 0
  6102. + || strncmp (section, ".sbss.", 6) == 0
  6103. + || strcmp (section, ".sdata") == 0
  6104. + || strncmp (section, ".sdata.", 7) == 0))
  6105. + return true;
  6106. + }
  6107. + else if (TREE_CODE (exp) == VAR_DECL)
  6108. + {
  6109. + HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
  6110. +
  6111. + /* If this is an incomplete type with size 0, then we can't put it
  6112. + in sdata because it might be too big when completed. */
  6113. + if (size > 0 && (unsigned HOST_WIDE_INT)size <= nios2_section_threshold)
  6114. + return true;
  6115. + }
  6116. +
  6117. + return false;
  6118. +}
  6119. +
  6120. +static void
  6121. +nios2_encode_section_info (tree decl, rtx rtl, int first)
  6122. +{
  6123. +
  6124. + rtx symbol;
  6125. + int flags;
  6126. +
  6127. + default_encode_section_info (decl, rtl, first);
  6128. +
  6129. + /* Careful not to prod global register variables. */
  6130. + if (GET_CODE (rtl) != MEM)
  6131. + return;
  6132. + symbol = XEXP (rtl, 0);
  6133. + if (GET_CODE (symbol) != SYMBOL_REF)
  6134. + return;
  6135. +
  6136. + flags = SYMBOL_REF_FLAGS (symbol);
  6137. +
  6138. + /* We don't want weak variables to be addressed with gp in case they end up with
  6139. + value 0 which is not within 2^15 of $gp */
  6140. + if (DECL_P (decl) && DECL_WEAK (decl))
  6141. + flags |= SYMBOL_FLAG_WEAK_DECL;
  6142. +
  6143. + SYMBOL_REF_FLAGS (symbol) = flags;
  6144. +}
  6145. +
  6146. +
  6147. +static unsigned int
  6148. +nios2_section_type_flags (tree decl, const char *name, int reloc)
  6149. +{
  6150. + unsigned int flags;
  6151. +
  6152. + flags = default_section_type_flags (decl, name, reloc);
  6153. +
  6154. + /* ??? these string names need moving into an array in some header file */
  6155. + if (strcmp (name, ".sbss") == 0
  6156. + || strncmp (name, ".sbss.", 6) == 0
  6157. + || strcmp (name, ".sdata") == 0
  6158. + || strncmp (name, ".sdata.", 7) == 0)
  6159. + flags |= SECTION_SMALL;
  6160. +
  6161. + return flags;
  6162. +}
  6163. +
  6164. +/* Handle a #pragma reverse_bitfields */
  6165. +static void
  6166. +nios2_pragma_reverse_bitfields (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
  6167. +{
  6168. + nios2_pragma_reverse_bitfields_flag = 1; /* Reverse */
  6169. +}
  6170. +
  6171. +/* Handle a #pragma no_reverse_bitfields */
  6172. +static void
  6173. +nios2_pragma_no_reverse_bitfields (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
  6174. +{
  6175. + nios2_pragma_reverse_bitfields_flag = -1; /* Forward */
  6176. +}
  6177. +
  6178. +/* Handle the various #pragma custom_<switch>s */
  6179. +static void
  6180. +nios2_pragma_fpu (int *value, const char *opt, int *seen)
  6181. +{
  6182. + tree t;
  6183. + if (c_lex (&t) != CPP_NUMBER)
  6184. + {
  6185. + error ("`#pragma custom_%s' value must be a number between 0 and 255",
  6186. + opt);
  6187. + return;
  6188. + }
  6189. +
  6190. + if (TREE_INT_CST_HIGH (t) == 0
  6191. + && TREE_INT_CST_LOW (t) <= 255)
  6192. + {
  6193. + *value = (int)TREE_INT_CST_LOW (t);
  6194. + *seen = 1;
  6195. + }
  6196. + else
  6197. + {
  6198. + error ("`#pragma custom_%s' value must be between 0 and 255", opt);
  6199. + }
  6200. + nios2_custom_check_insns (1);
  6201. +}
  6202. +
  6203. +/* Handle the various #pragma no_custom_<switch>s */
  6204. +static void
  6205. +nios2_pragma_no_fpu (int *value, const char *opt ATTRIBUTE_UNUSED)
  6206. +{
  6207. + *value = -1;
  6208. + nios2_custom_check_insns (1);
  6209. +}
  6210. +
  6211. +#undef NIOS2_FPU_INSN
  6212. +#define NIOS2_FPU_INSN(opt, insn, args) \
  6213. +static void \
  6214. +NIOS2_CONCAT (nios2_pragma_, insn) \
  6215. + (struct cpp_reader *pfile ATTRIBUTE_UNUSED) \
  6216. +{ \
  6217. + nios2_fpu_info *inf = &(nios2_fpu_insns[NIOS2_CONCAT (nios2_fpu_, insn)]); \
  6218. + nios2_pragma_fpu (&(inf->N), inf->option, &(inf->pragma_seen)); \
  6219. +} \
  6220. +static void \
  6221. +NIOS2_CONCAT (nios2_pragma_no_, insn) \
  6222. + (struct cpp_reader *pfile ATTRIBUTE_UNUSED) \
  6223. +{ \
  6224. + nios2_fpu_info *inf = &(nios2_fpu_insns[NIOS2_CONCAT (nios2_fpu_, insn)]); \
  6225. + nios2_pragma_no_fpu (&(inf->N), inf->option); \
  6226. +}
  6227. +NIOS2_FOR_ALL_FPU_INSNS
  6228. +
  6229. +static void
  6230. +nios2_pragma_handle_custom_fpu_cfg (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
  6231. +{
  6232. + tree t;
  6233. + if (c_lex (&t) != CPP_STRING)
  6234. + {
  6235. + error ("`#pragma custom_fpu_cfg' value must be a string");
  6236. + return;
  6237. + }
  6238. +
  6239. + if (TREE_STRING_LENGTH (t) > 0)
  6240. + {
  6241. + nios2_handle_custom_fpu_cfg (TREE_STRING_POINTER (t), 1);
  6242. + }
  6243. +}
  6244. +
  6245. +void
  6246. +nios2_register_target_pragmas ()
  6247. +{
  6248. + int i;
  6249. +
  6250. + c_register_pragma (0, "reverse_bitfields",
  6251. + nios2_pragma_reverse_bitfields);
  6252. + c_register_pragma (0, "no_reverse_bitfields",
  6253. + nios2_pragma_no_reverse_bitfields);
  6254. +
  6255. + for (i = 0; i < nios2_fpu_max_insn; i++)
  6256. + {
  6257. + nios2_fpu_info *inf = &(nios2_fpu_insns[i]);
  6258. + c_register_pragma (0, inf->pname, inf->pragma);
  6259. + c_register_pragma (0, inf->nopname, inf->nopragma);
  6260. + }
  6261. +
  6262. + c_register_pragma (0, "custom_fpu_cfg",
  6263. + nios2_pragma_handle_custom_fpu_cfg);
  6264. +}
  6265. +
  6266. +/* Handle a "reverse_bitfields" or "no_reverse_bitfields" attribute.
  6267. + ??? What do these attributes mean on a union? */
  6268. +static tree
  6269. +nios2_handle_struct_attribute (tree *node, tree name,
  6270. + tree args ATTRIBUTE_UNUSED,
  6271. + int flags ATTRIBUTE_UNUSED,
  6272. + bool *no_add_attrs)
  6273. +{
  6274. + tree *type = NULL;
  6275. + if (DECL_P (*node))
  6276. + {
  6277. + if (TREE_CODE (*node) == TYPE_DECL)
  6278. + {
  6279. + type = &TREE_TYPE (*node);
  6280. + }
  6281. + }
  6282. + else
  6283. + {
  6284. + type = node;
  6285. + }
  6286. +
  6287. + if (!(type && (TREE_CODE (*type) == RECORD_TYPE
  6288. + || TREE_CODE (*type) == UNION_TYPE)))
  6289. + {
  6290. + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
  6291. + *no_add_attrs = true;
  6292. + }
  6293. +
  6294. + else if ((is_attribute_p ("reverse_bitfields", name)
  6295. + && lookup_attribute ("no_reverse_bitfields",
  6296. + TYPE_ATTRIBUTES (*type)))
  6297. + || ((is_attribute_p ("no_reverse_bitfields", name)
  6298. + && lookup_attribute ("reverse_bitfields",
  6299. + TYPE_ATTRIBUTES (*type)))))
  6300. + {
  6301. + warning ("`%s' incompatible attribute ignored",
  6302. + IDENTIFIER_POINTER (name));
  6303. + *no_add_attrs = true;
  6304. + }
  6305. +
  6306. + return NULL_TREE;
  6307. +}
  6308. +
  6309. +/*
  6310. + Add __attribute__ ((pragma_reverse_bitfields)) when in the scope of a
  6311. + #pragma reverse_bitfields, or __attribute__
  6312. + ((pragma_no_reverse_bitfields)) when in the scope of a #pragma
  6313. + no_reverse_bitfields. This gets called before
  6314. + nios2_handle_struct_attribute above, so we can't just reuse the same
  6315. + attributes.
  6316. +*/
  6317. +static void
  6318. +nios2_insert_attributes (tree node, tree *attr_ptr)
  6319. +{
  6320. + tree type = NULL;
  6321. + if (DECL_P (node))
  6322. + {
  6323. + if (TREE_CODE (node) == TYPE_DECL)
  6324. + {
  6325. + type = TREE_TYPE (node);
  6326. + }
  6327. + }
  6328. + else
  6329. + {
  6330. + type = node;
  6331. + }
  6332. +
  6333. + if (!type
  6334. + || (TREE_CODE (type) != RECORD_TYPE
  6335. + && TREE_CODE (type) != UNION_TYPE))
  6336. + {
  6337. + /* We can ignore things other than structs & unions */
  6338. + return;
  6339. + }
  6340. +
  6341. + if (lookup_attribute ("reverse_bitfields", TYPE_ATTRIBUTES (type))
  6342. + || lookup_attribute ("no_reverse_bitfields", TYPE_ATTRIBUTES (type)))
  6343. + {
  6344. + /* If an attribute is already set, it silently overrides the
  6345. + current #pragma, if any */
  6346. + return;
  6347. + }
  6348. +
  6349. + if (nios2_pragma_reverse_bitfields_flag)
  6350. + {
  6351. + const char *id = (nios2_pragma_reverse_bitfields_flag == 1 ?
  6352. + "pragma_reverse_bitfields" :
  6353. + "pragma_no_reverse_bitfields");
  6354. + /* No attribute set, and we are in the scope of a #pragma */
  6355. + *attr_ptr = tree_cons (get_identifier (id), NULL, *attr_ptr);
  6356. + }
  6357. +}
  6358. +
  6359. +
  6360. +/*
  6361. + * The attributes take precedence over the pragmas, which in turn take
  6362. + * precedence over the compile-time switches.
  6363. + */
  6364. +static bool
  6365. +nios2_reverse_bitfield_layout_p (tree record_type)
  6366. +{
  6367. + return ((TARGET_REVERSE_BITFIELDS
  6368. + && !lookup_attribute ("pragma_no_reverse_bitfields",
  6369. + TYPE_ATTRIBUTES (record_type))
  6370. + && !lookup_attribute ("no_reverse_bitfields",
  6371. + TYPE_ATTRIBUTES (record_type)))
  6372. + || (lookup_attribute ("pragma_reverse_bitfields",
  6373. + TYPE_ATTRIBUTES (record_type))
  6374. + && !lookup_attribute ("no_reverse_bitfields",
  6375. + TYPE_ATTRIBUTES (record_type)))
  6376. + || lookup_attribute ("reverse_bitfields",
  6377. + TYPE_ATTRIBUTES (record_type)));
  6378. +}
  6379. +
  6380. +
  6381. +/*****************************************
  6382. + * Defining the Output Assembler Language
  6383. + *****************************************/
  6384. +
  6385. +/* -------------- *
  6386. + * Output of Data
  6387. + * -------------- */
  6388. +
  6389. +
  6390. +/* -------------------------------- *
  6391. + * Output of Assembler Instructions
  6392. + * -------------------------------- */
  6393. +
  6394. +
  6395. +/* print the operand OP to file stream
  6396. + FILE modified by LETTER. LETTER
  6397. + can be one of:
  6398. + i: print "i" if OP is an immediate, except 0
  6399. + o: print "io" if OP is volatile
  6400. +
  6401. + z: for const0_rtx print $0 instead of 0
  6402. + H: for %hiadj
  6403. + L: for %lo
  6404. + U: for upper half of 32 bit value
  6405. + D: for the upper 32-bits of a 64-bit double value
  6406. + */
  6407. +
  6408. +void
  6409. +nios2_print_operand (FILE *file, rtx op, int letter)
  6410. +{
  6411. +
  6412. + switch (letter)
  6413. + {
  6414. + case 'i':
  6415. + if (CONSTANT_P (op) && (op != const0_rtx))
  6416. + fprintf (file, "i");
  6417. + return;
  6418. +
  6419. + case 'o':
  6420. + if (GET_CODE (op) == MEM
  6421. + && ((MEM_VOLATILE_P (op) && !TARGET_CACHE_VOLATILE)
  6422. + || TARGET_BYPASS_CACHE))
  6423. + fprintf (file, "io");
  6424. + return;
  6425. +
  6426. + default:
  6427. + break;
  6428. + }
  6429. +
  6430. + if (comparison_operator (op, VOIDmode))
  6431. + {
  6432. + if (letter == 0)
  6433. + {
  6434. + fprintf (file, "%s", GET_RTX_NAME (GET_CODE (op)));
  6435. + return;
  6436. + }
  6437. + }
  6438. +
  6439. +
  6440. + switch (GET_CODE (op))
  6441. + {
  6442. + case REG:
  6443. + if (letter == 0 || letter == 'z')
  6444. + {
  6445. + fprintf (file, "%s", reg_names[REGNO (op)]);
  6446. + return;
  6447. + }
  6448. + else if (letter == 'D')
  6449. + {
  6450. + fprintf (file, "%s", reg_names[REGNO (op)+1]);
  6451. + return;
  6452. + }
  6453. + break;
  6454. +
  6455. + case CONST_INT:
  6456. + if (INTVAL (op) == 0 && letter == 'z')
  6457. + {
  6458. + fprintf (file, "zero");
  6459. + return;
  6460. + }
  6461. + else if (letter == 'U')
  6462. + {
  6463. + HOST_WIDE_INT val = INTVAL (op);
  6464. + rtx new_op;
  6465. + val = (val / 65536) & 0xFFFF;
  6466. + new_op = GEN_INT (val);
  6467. + output_addr_const (file, new_op);
  6468. + return;
  6469. + }
  6470. +
  6471. + /* else, fall through */
  6472. + case CONST:
  6473. + case LABEL_REF:
  6474. + case SYMBOL_REF:
  6475. + case CONST_DOUBLE:
  6476. + if (letter == 0 || letter == 'z')
  6477. + {
  6478. + output_addr_const (file, op);
  6479. + return;
  6480. + }
  6481. + else if (letter == 'H')
  6482. + {
  6483. + fprintf (file, "%%hiadj(");
  6484. + output_addr_const (file, op);
  6485. + fprintf (file, ")");
  6486. + return;
  6487. + }
  6488. + else if (letter == 'L')
  6489. + {
  6490. + fprintf (file, "%%lo(");
  6491. + output_addr_const (file, op);
  6492. + fprintf (file, ")");
  6493. + return;
  6494. + }
  6495. + break;
  6496. +
  6497. +
  6498. + case SUBREG:
  6499. + case MEM:
  6500. + if (letter == 0)
  6501. + {
  6502. + output_address (op);
  6503. + return;
  6504. + }
  6505. + break;
  6506. +
  6507. + case CODE_LABEL:
  6508. + if (letter == 0)
  6509. + {
  6510. + output_addr_const (file, op);
  6511. + return;
  6512. + }
  6513. + break;
  6514. +
  6515. + default:
  6516. + break;
  6517. + }
  6518. +
  6519. + fprintf (stderr, "Missing way to print (%c) ", letter);
  6520. + debug_rtx (op);
  6521. + abort ();
  6522. +}
  6523. +
  6524. +static int gprel_constant (rtx);
  6525. +
  6526. +static int
  6527. +gprel_constant (rtx op)
  6528. +{
  6529. + if (GET_CODE (op) == SYMBOL_REF
  6530. + && SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (op))
  6531. + {
  6532. + return 1;
  6533. + }
  6534. + else if (GET_CODE (op) == CONST
  6535. + && GET_CODE (XEXP (op, 0)) == PLUS)
  6536. + {
  6537. + return gprel_constant (XEXP (XEXP (op, 0), 0));
  6538. + }
  6539. + else
  6540. + {
  6541. + return 0;
  6542. + }
  6543. +}
  6544. +
  6545. +void
  6546. +nios2_print_operand_address (FILE *file, rtx op)
  6547. +{
  6548. + switch (GET_CODE (op))
  6549. + {
  6550. + case CONST:
  6551. + case CONST_INT:
  6552. + case LABEL_REF:
  6553. + case CONST_DOUBLE:
  6554. + case SYMBOL_REF:
  6555. + if (gprel_constant (op))
  6556. + {
  6557. + fprintf (file, "%%gprel(");
  6558. + output_addr_const (file, op);
  6559. + fprintf (file, ")(%s)", reg_names[GP_REGNO]);
  6560. + return;
  6561. + }
  6562. +
  6563. + break;
  6564. +
  6565. + case PLUS:
  6566. + {
  6567. + rtx op0 = XEXP (op, 0);
  6568. + rtx op1 = XEXP (op, 1);
  6569. +
  6570. + if (REG_P (op0) && CONSTANT_P (op1))
  6571. + {
  6572. + output_addr_const (file, op1);
  6573. + fprintf (file, "(%s)", reg_names[REGNO (op0)]);
  6574. + return;
  6575. + }
  6576. + else if (REG_P (op1) && CONSTANT_P (op0))
  6577. + {
  6578. + output_addr_const (file, op0);
  6579. + fprintf (file, "(%s)", reg_names[REGNO (op1)]);
  6580. + return;
  6581. + }
  6582. + }
  6583. + break;
  6584. +
  6585. + case REG:
  6586. + fprintf (file, "0(%s)", reg_names[REGNO (op)]);
  6587. + return;
  6588. +
  6589. + case MEM:
  6590. + {
  6591. + rtx base = XEXP (op, 0);
  6592. + PRINT_OPERAND_ADDRESS (file, base);
  6593. + return;
  6594. + }
  6595. + default:
  6596. + break;
  6597. + }
  6598. +
  6599. + fprintf (stderr, "Missing way to print address\n");
  6600. + debug_rtx (op);
  6601. + abort ();
  6602. +}
  6603. +
  6604. +
  6605. +
  6606. +
  6607. +
  6608. +/****************************
  6609. + * Predicates
  6610. + ****************************/
  6611. +
  6612. +int
  6613. +arith_operand (rtx op, enum machine_mode mode)
  6614. +{
  6615. + if (GET_CODE (op) == CONST_INT && SMALL_INT (INTVAL (op)))
  6616. + return 1;
  6617. +
  6618. + return register_operand (op, mode);
  6619. +}
  6620. +
  6621. +int
  6622. +uns_arith_operand (rtx op, enum machine_mode mode)
  6623. +{
  6624. + if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (INTVAL (op)))
  6625. + return 1;
  6626. +
  6627. + return register_operand (op, mode);
  6628. +}
  6629. +
  6630. +int
  6631. +logical_operand (rtx op, enum machine_mode mode)
  6632. +{
  6633. + if (GET_CODE (op) == CONST_INT
  6634. + && (SMALL_INT_UNSIGNED (INTVAL (op)) || UPPER16_INT (INTVAL (op))))
  6635. + return 1;
  6636. +
  6637. + return register_operand (op, mode);
  6638. +}
  6639. +
  6640. +int
  6641. +shift_operand (rtx op, enum machine_mode mode)
  6642. +{
  6643. + if (GET_CODE (op) == CONST_INT && SHIFT_INT (INTVAL (op)))
  6644. + return 1;
  6645. +
  6646. + return register_operand (op, mode);
  6647. +}
  6648. +
  6649. +int
  6650. +rdwrctl_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
  6651. +{
  6652. + return GET_CODE (op) == CONST_INT && RDWRCTL_INT (INTVAL (op));
  6653. +}
  6654. +
  6655. +/* Return truth value of whether OP is a register or the constant 0. */
  6656. +
  6657. +int
  6658. +reg_or_0_operand (rtx op, enum machine_mode mode)
  6659. +{
  6660. + switch (GET_CODE (op))
  6661. + {
  6662. + case CONST_INT:
  6663. + return INTVAL (op) == 0;
  6664. +
  6665. + case CONST_DOUBLE:
  6666. + return op == CONST0_RTX (mode);
  6667. +
  6668. + default:
  6669. + break;
  6670. + }
  6671. +
  6672. + return register_operand (op, mode);
  6673. +}
  6674. +
  6675. +
  6676. +int
  6677. +equality_op (rtx op, enum machine_mode mode)
  6678. +{
  6679. + if (mode != GET_MODE (op))
  6680. + return 0;
  6681. +
  6682. + return GET_CODE (op) == EQ || GET_CODE (op) == NE;
  6683. +}
  6684. +
  6685. +int
  6686. +custom_insn_opcode (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
  6687. +{
  6688. + return GET_CODE (op) == CONST_INT && CUSTOM_INSN_OPCODE (INTVAL (op));
  6689. +}
  6690. +
  6691. +
  6692. +
  6693. +
  6694. +/*****************************************************************************
  6695. +**
  6696. +** custom fpu instruction output
  6697. +**
  6698. +*****************************************************************************/
  6699. +
  6700. +static const char *nios2_custom_fpu_insn_zdz (rtx, int, const char *);
  6701. +static const char *nios2_custom_fpu_insn_zsz (rtx, int, const char *);
  6702. +static const char *nios2_custom_fpu_insn_szz (rtx, int, const char *);
  6703. +static const char *nios2_custom_fpu_insn_sss (rtx, int, const char *);
  6704. +static const char *nios2_custom_fpu_insn_ssz (rtx, int, const char *);
  6705. +static const char *nios2_custom_fpu_insn_iss (rtx, int, const char *);
  6706. +static const char *nios2_custom_fpu_insn_ddd (rtx, int, const char *);
  6707. +static const char *nios2_custom_fpu_insn_ddz (rtx, int, const char *);
  6708. +static const char *nios2_custom_fpu_insn_idd (rtx, int, const char *);
  6709. +static const char *nios2_custom_fpu_insn_siz (rtx, int, const char *);
  6710. +static const char *nios2_custom_fpu_insn_suz (rtx, int, const char *);
  6711. +static const char *nios2_custom_fpu_insn_diz (rtx, int, const char *);
  6712. +static const char *nios2_custom_fpu_insn_duz (rtx, int, const char *);
  6713. +static const char *nios2_custom_fpu_insn_isz (rtx, int, const char *);
  6714. +static const char *nios2_custom_fpu_insn_usz (rtx, int, const char *);
  6715. +static const char *nios2_custom_fpu_insn_idz (rtx, int, const char *);
  6716. +static const char *nios2_custom_fpu_insn_udz (rtx, int, const char *);
  6717. +static const char *nios2_custom_fpu_insn_dsz (rtx, int, const char *);
  6718. +static const char *nios2_custom_fpu_insn_sdz (rtx, int, const char *);
  6719. +
  6720. +static const char *
  6721. +nios2_custom_fpu_insn_zdz (rtx insn, int N, const char *opt)
  6722. +{
  6723. + static char buf[1024];
  6724. +
  6725. + if (N < 0)
  6726. + {
  6727. + fatal_insn ("attempt to use disabled fpu instruction", insn);
  6728. + }
  6729. + if (snprintf (buf, sizeof (buf),
  6730. + "custom\t%d, zero, %%0, %%D0 # %s %%0",
  6731. + N, opt) >= (int)sizeof (buf))
  6732. + {
  6733. + fatal_insn ("buffer overflow", insn);
  6734. + }
  6735. + return buf;
  6736. +}
  6737. +
  6738. +static const char *
  6739. +nios2_custom_fpu_insn_zsz (rtx insn, int N, const char *opt)
  6740. +{
  6741. + static char buf[1024];
  6742. +
  6743. + if (N < 0)
  6744. + {
  6745. + fatal_insn ("attempt to use disabled fpu instruction", insn);
  6746. + }
  6747. + if (snprintf (buf, sizeof (buf),
  6748. + "custom\t%d, zero, %%0, zero # %s %%0",
  6749. + N, opt) >= (int)sizeof (buf))
  6750. + {
  6751. + fatal_insn ("buffer overflow", insn);
  6752. + }
  6753. + return buf;
  6754. +}
  6755. +
  6756. +static const char *
  6757. +nios2_custom_fpu_insn_szz (rtx insn, int N, const char *opt)
  6758. +{
  6759. + static char buf[1024];
  6760. +
  6761. + if (N < 0)
  6762. + {
  6763. + fatal_insn ("attempt to use disabled fpu instruction", insn);
  6764. + }
  6765. + if (snprintf (buf, sizeof (buf),
  6766. + "custom\t%d, %%0, zero, zero # %s %%0",
  6767. + N, opt) >= (int)sizeof (buf))
  6768. + {
  6769. + fatal_insn ("buffer overflow", insn);
  6770. + }
  6771. + return buf;
  6772. +}
  6773. +
  6774. +static const char *
  6775. +nios2_custom_fpu_insn_sss (rtx insn, int N, const char *opt)
  6776. +{
  6777. + static char buf[1024];
  6778. +
  6779. + if (N < 0)
  6780. + {
  6781. + fatal_insn ("attempt to use disabled fpu instruction", insn);
  6782. + }
  6783. + if (snprintf (buf, sizeof (buf),
  6784. + "custom\t%d, %%0, %%1, %%2 # %s %%0, %%1, %%2",
  6785. + N, opt) >= (int)sizeof (buf))
  6786. + {
  6787. + fatal_insn ("buffer overflow", insn);
  6788. + }
  6789. + return buf;
  6790. +}
  6791. +
  6792. +static const char *
  6793. +nios2_custom_fpu_insn_ssz (rtx insn, int N, const char *opt)
  6794. +{
  6795. + static char buf[1024];
  6796. +
  6797. + if (N < 0)
  6798. + {
  6799. + fatal_insn ("attempt to use disabled fpu instruction", insn);
  6800. + }
  6801. + if (snprintf (buf, sizeof (buf),
  6802. + "custom\t%d, %%0, %%1, zero # %s %%0, %%1",
  6803. + N, opt) >= (int)sizeof (buf))
  6804. + {
  6805. + fatal_insn ("buffer overflow", insn);
  6806. + }
  6807. + return buf;
  6808. +}
  6809. +
  6810. +static const char *
  6811. +nios2_custom_fpu_insn_iss (rtx insn, int N, const char *opt)
  6812. +{
  6813. + return nios2_custom_fpu_insn_sss (insn, N, opt);
  6814. +}
  6815. +
  6816. +static const char *
  6817. +nios2_custom_fpu_insn_ddd (rtx insn, int N, const char *opt)
  6818. +{
  6819. + static char buf[1024];
  6820. +
  6821. + if (N < 0
  6822. + || nios2_fpu_insns[nios2_fpu_nios2_frdy].N < 0
  6823. + || nios2_fpu_insns[nios2_fpu_nios2_fwrx].N < 0)
  6824. + {
  6825. + fatal_insn ("attempt to use disabled fpu instruction", insn);
  6826. + }
  6827. + if (snprintf (buf, sizeof (buf),
  6828. + "custom\t%d, zero, %%1, %%D1 # fwrx %%1\n\t"
  6829. + "custom\t%d, %%D0, %%2, %%D2 # %s %%0, %%1, %%2\n\t"
  6830. + "custom\t%d, %%0, zero, zero # frdy %%0",
  6831. + nios2_fpu_insns[nios2_fpu_nios2_fwrx].N,
  6832. + N, opt,
  6833. + nios2_fpu_insns[nios2_fpu_nios2_frdy].N) >= (int)sizeof (buf))
  6834. + {
  6835. + fatal_insn ("buffer overflow", insn);
  6836. + }
  6837. + return buf;
  6838. +}
  6839. +
  6840. +static const char *
  6841. +nios2_custom_fpu_insn_ddz (rtx insn, int N, const char *opt)
  6842. +{
  6843. + static char buf[1024];
  6844. +
  6845. + if (N < 0 || nios2_fpu_insns[nios2_fpu_nios2_frdy].N < 0)
  6846. + {
  6847. + fatal_insn ("attempt to use disabled fpu instruction", insn);
  6848. + }
  6849. + if (snprintf (buf, sizeof (buf),
  6850. + "custom\t%d, %%D0, %%1, %%D1 # %s %%0, %%1\n\t"
  6851. + "custom\t%d, %%0, zero, zero # frdy %%0",
  6852. + N, opt,
  6853. + nios2_fpu_insns[nios2_fpu_nios2_frdy].N) >= (int)sizeof (buf))
  6854. + {
  6855. + fatal_insn ("buffer overflow", insn);
  6856. + }
  6857. + return buf;
  6858. +}
  6859. +
  6860. +static const char *
  6861. +nios2_custom_fpu_insn_idd (rtx insn, int N, const char *opt)
  6862. +{
  6863. + static char buf[1024];
  6864. +
  6865. + if (N < 0 || nios2_fpu_insns[nios2_fpu_nios2_fwrx].N < 0)
  6866. + {
  6867. + fatal_insn ("attempt to use disabled fpu instruction", insn);
  6868. + }
  6869. + if (snprintf (buf, sizeof (buf),
  6870. + "custom\t%d, zero, %%1, %%D1 # fwrx %%1\n\t"
  6871. + "custom\t%d, %%0, %%2, %%D2 # %s %%0, %%1, %%2",
  6872. + nios2_fpu_insns[nios2_fpu_nios2_fwrx].N,
  6873. + N, opt) >= (int)sizeof (buf))
  6874. + {
  6875. + fatal_insn ("buffer overflow", insn);
  6876. + }
  6877. + return buf;
  6878. +}
  6879. +
  6880. +static const char *
  6881. +nios2_custom_fpu_insn_siz (rtx insn, int N, const char *opt)
  6882. +{
  6883. + return nios2_custom_fpu_insn_ssz (insn, N, opt);
  6884. +}
  6885. +
  6886. +static const char *
  6887. +nios2_custom_fpu_insn_suz (rtx insn, int N, const char *opt)
  6888. +{
  6889. + return nios2_custom_fpu_insn_ssz (insn, N, opt);
  6890. +}
  6891. +
  6892. +static const char *
  6893. +nios2_custom_fpu_insn_diz (rtx insn, int N, const char *opt)
  6894. +{
  6895. + return nios2_custom_fpu_insn_dsz (insn, N, opt);
  6896. +}
  6897. +
  6898. +static const char *
  6899. +nios2_custom_fpu_insn_duz (rtx insn, int N, const char *opt)
  6900. +{
  6901. + return nios2_custom_fpu_insn_dsz (insn, N, opt);
  6902. +}
  6903. +
  6904. +static const char *
  6905. +nios2_custom_fpu_insn_isz (rtx insn, int N, const char *opt)
  6906. +{
  6907. + return nios2_custom_fpu_insn_ssz (insn, N, opt);
  6908. +}
  6909. +
  6910. +static const char *
  6911. +nios2_custom_fpu_insn_usz (rtx insn, int N, const char *opt)
  6912. +{
  6913. + return nios2_custom_fpu_insn_ssz (insn, N, opt);
  6914. +}
  6915. +
  6916. +static const char *
  6917. +nios2_custom_fpu_insn_idz (rtx insn, int N, const char *opt)
  6918. +{
  6919. + return nios2_custom_fpu_insn_sdz (insn, N, opt);
  6920. +}
  6921. +
  6922. +static const char *
  6923. +nios2_custom_fpu_insn_udz (rtx insn, int N, const char *opt)
  6924. +{
  6925. + return nios2_custom_fpu_insn_sdz (insn, N, opt);
  6926. +}
  6927. +
  6928. +static const char *
  6929. +nios2_custom_fpu_insn_dsz (rtx insn, int N, const char *opt)
  6930. +{
  6931. + static char buf[1024];
  6932. +
  6933. + if (N < 0 || nios2_fpu_insns[nios2_fpu_nios2_frdy].N < 0)
  6934. + {
  6935. + fatal_insn ("attempt to use disabled fpu instruction", insn);
  6936. + }
  6937. + if (snprintf (buf, sizeof (buf),
  6938. + "custom\t%d, %%D0, %%1, zero # %s %%0, %%1\n\t"
  6939. + "custom\t%d, %%0, zero, zero # frdy %%0",
  6940. + N, opt,
  6941. + nios2_fpu_insns[nios2_fpu_nios2_frdy].N) >= (int)sizeof (buf))
  6942. + {
  6943. + fatal_insn ("buffer overflow", insn);
  6944. + }
  6945. + return buf;
  6946. +}
  6947. +
  6948. +static const char *
  6949. +nios2_custom_fpu_insn_sdz (rtx insn, int N, const char *opt)
  6950. +{
  6951. + static char buf[1024];
  6952. +
  6953. + if (N < 0)
  6954. + {
  6955. + fatal_insn ("attempt to use disabled fpu instruction", insn);
  6956. + }
  6957. + if (snprintf (buf, sizeof (buf),
  6958. + "custom\t%d, %%0, %%1, %%D1 # %s %%0, %%1",
  6959. + N, opt) >= (int)sizeof (buf))
  6960. + {
  6961. + fatal_insn ("buffer overflow", insn);
  6962. + }
  6963. + return buf;
  6964. +}
  6965. +
  6966. +#undef NIOS2_FPU_INSN
  6967. +#define NIOS2_FPU_INSN(opt, insn, args) \
  6968. +static const char * \
  6969. +NIOS2_CONCAT (nios2_output_fpu_insn_, insn) (rtx i) \
  6970. +{ \
  6971. + return NIOS2_CONCAT (nios2_custom_fpu_insn_, args) \
  6972. + (i, \
  6973. + nios2_fpu_insns[NIOS2_CONCAT (nios2_fpu_, insn)].N, \
  6974. + nios2_fpu_insns[NIOS2_CONCAT (nios2_fpu_, insn)].option); \
  6975. +}
  6976. +NIOS2_FOR_ALL_FPU_INSNS
  6977. +
  6978. +
  6979. +
  6980. +const char *
  6981. +nios2_output_fpu_insn_cmps (rtx insn, enum rtx_code cond)
  6982. +{
  6983. + static char buf[1024];
  6984. + int N;
  6985. + const char *opt;
  6986. +
  6987. + int operandL = 2;
  6988. + int operandR = 3;
  6989. +
  6990. + if ( !have_nios2_fpu_cmp_insn(cond, CMP_SF) &&
  6991. + have_nios2_fpu_cmp_insn(get_reverse_cond(cond), CMP_SF) ) {
  6992. +
  6993. + int temp = operandL;
  6994. + operandL = operandR;
  6995. + operandR = temp;
  6996. +
  6997. + cond = get_reverse_cond(cond);
  6998. + }
  6999. +
  7000. + switch (cond)
  7001. + {
  7002. + case EQ:
  7003. + N = nios2_fpu_insns[nios2_fpu_nios2_seqsf].N;
  7004. + opt = "fcmpeqs";
  7005. + break;
  7006. + case NE:
  7007. + N = nios2_fpu_insns[nios2_fpu_nios2_snesf].N;
  7008. + opt = "fcmpnes";
  7009. + break;
  7010. + case GT:
  7011. + N = nios2_fpu_insns[nios2_fpu_nios2_sgtsf].N;
  7012. + opt = "fcmpgts";
  7013. + break;
  7014. + case GE:
  7015. + N = nios2_fpu_insns[nios2_fpu_nios2_sgesf].N;
  7016. + opt = "fcmpges";
  7017. + break;
  7018. + case LT:
  7019. + N = nios2_fpu_insns[nios2_fpu_nios2_sltsf].N;
  7020. + opt = "fcmplts";
  7021. + break;
  7022. + case LE:
  7023. + N = nios2_fpu_insns[nios2_fpu_nios2_slesf].N;
  7024. + opt = "fcmples"; break;
  7025. + default:
  7026. + fatal_insn ("bad single compare", insn);
  7027. + }
  7028. +
  7029. + if (N < 0)
  7030. + {
  7031. + fatal_insn ("attempt to use disabled fpu instruction", insn);
  7032. + }
  7033. +
  7034. + /*
  7035. + * ??? This raises the whole vexing issue of how to handle
  7036. + * out-of-range branches. Punt for now, seeing as how nios2-elf-as
  7037. + * doesn't even _try_ to handle out-of-range branches yet!
  7038. + */
  7039. + if (snprintf (buf, sizeof (buf),
  7040. + ".set\tnoat\n\t"
  7041. + "custom\t%d, at, %%%d, %%%d # %s at, %%%d, %%%d\n\t"
  7042. + "bne\tat, zero, %%l1\n\t"
  7043. + ".set\tat",
  7044. + N, operandL, operandR, opt, operandL, operandR) >= (int)sizeof (buf))
  7045. + {
  7046. + fatal_insn ("buffer overflow", insn);
  7047. + }
  7048. + return buf;
  7049. +}
  7050. +
  7051. +const char *
  7052. +nios2_output_fpu_insn_cmpd (rtx insn, enum rtx_code cond)
  7053. +{
  7054. + static char buf[1024];
  7055. + int N;
  7056. + const char *opt;
  7057. +
  7058. + int operandL = 2;
  7059. + int operandR = 3;
  7060. +
  7061. + if ( !have_nios2_fpu_cmp_insn(cond, CMP_DF) &&
  7062. + have_nios2_fpu_cmp_insn(get_reverse_cond(cond), CMP_DF) ) {
  7063. +
  7064. + int temp = operandL;
  7065. + operandL = operandR;
  7066. + operandR = temp;
  7067. +
  7068. + cond = get_reverse_cond(cond);
  7069. + }
  7070. +
  7071. + switch (cond)
  7072. + {
  7073. + case EQ:
  7074. + N = nios2_fpu_insns[nios2_fpu_nios2_seqdf].N;
  7075. + opt = "fcmpeqd";
  7076. + break;
  7077. + case NE:
  7078. + N = nios2_fpu_insns[nios2_fpu_nios2_snedf].N;
  7079. + opt = "fcmpned";
  7080. + break;
  7081. + case GT:
  7082. + N = nios2_fpu_insns[nios2_fpu_nios2_sgtdf].N;
  7083. + opt = "fcmpgtd";
  7084. + break;
  7085. + case GE:
  7086. + N = nios2_fpu_insns[nios2_fpu_nios2_sgedf].N;
  7087. + opt = "fcmpged";
  7088. + break;
  7089. + case LT:
  7090. + N = nios2_fpu_insns[nios2_fpu_nios2_sltdf].N;
  7091. + opt = "fcmpltd";
  7092. + break;
  7093. + case LE:
  7094. + N = nios2_fpu_insns[nios2_fpu_nios2_sledf].N;
  7095. + opt = "fcmpled";
  7096. + break;
  7097. + default:
  7098. + fatal_insn ("bad double compare", insn);
  7099. + }
  7100. +
  7101. + if (N < 0 || nios2_fpu_insns[nios2_fpu_nios2_fwrx].N < 0)
  7102. + {
  7103. + fatal_insn ("attempt to use disabled fpu instruction", insn);
  7104. + }
  7105. + if (snprintf (buf, sizeof (buf),
  7106. + ".set\tnoat\n\t"
  7107. + "custom\t%d, zero, %%%d, %%D%d # fwrx %%%d\n\t"
  7108. + "custom\t%d, at, %%%d, %%D%d # %s at, %%%d, %%%d\n\t"
  7109. + "bne\tat, zero, %%l1\n\t"
  7110. + ".set\tat",
  7111. + nios2_fpu_insns[nios2_fpu_nios2_fwrx].N, operandL, operandL, operandL,
  7112. + N, operandR, operandR, operandL, operandR, opt) >= (int)sizeof (buf))
  7113. + {
  7114. + fatal_insn ("buffer overflow", insn);
  7115. + }
  7116. + return buf;
  7117. +}
  7118. +
  7119. +
  7120. +
  7121. +
  7122. +/*****************************************************************************
  7123. +**
  7124. +** instruction scheduler
  7125. +**
  7126. +*****************************************************************************/
  7127. +static int
  7128. +nios2_use_dfa_pipeline_interface ()
  7129. +{
  7130. + return 1;
  7131. +}
  7132. +
  7133. +
  7134. +static int
  7135. +nios2_issue_rate ()
  7136. +{
  7137. +#ifdef MAX_DFA_ISSUE_RATE
  7138. + return MAX_DFA_ISSUE_RATE;
  7139. +#else
  7140. + return 1;
  7141. +#endif
  7142. +}
  7143. +
  7144. +
  7145. +const char *
  7146. +asm_output_opcode (FILE *file ATTRIBUTE_UNUSED,
  7147. + const char *ptr ATTRIBUTE_UNUSED)
  7148. +{
  7149. + const char *p;
  7150. +
  7151. + p = ptr;
  7152. + return ptr;
  7153. +}
  7154. +
  7155. +
  7156. +
  7157. +/*****************************************************************************
  7158. +**
  7159. +** function arguments
  7160. +**
  7161. +*****************************************************************************/
  7162. +
  7163. +void
  7164. +init_cumulative_args (CUMULATIVE_ARGS *cum,
  7165. + tree fntype ATTRIBUTE_UNUSED,
  7166. + rtx libname ATTRIBUTE_UNUSED,
  7167. + tree fndecl ATTRIBUTE_UNUSED,
  7168. + int n_named_args ATTRIBUTE_UNUSED)
  7169. +{
  7170. + cum->regs_used = 0;
  7171. +}
  7172. +
  7173. +
  7174. +/* Define where to put the arguments to a function. Value is zero to
  7175. + push the argument on the stack, or a hard register in which to
  7176. + store the argument.
  7177. +
  7178. + MODE is the argument's machine mode.
  7179. + TYPE is the data type of the argument (as a tree).
  7180. + This is null for libcalls where that information may
  7181. + not be available.
  7182. + CUM is a variable of type CUMULATIVE_ARGS which gives info about
  7183. + the preceding args and about the function being called.
  7184. + NAMED is nonzero if this argument is a named parameter
  7185. + (otherwise it is an extra parameter matching an ellipsis). */
  7186. +rtx
  7187. +function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
  7188. + tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED)
  7189. +{
  7190. + rtx return_rtx = NULL_RTX;
  7191. +
  7192. + if (cum->regs_used < NUM_ARG_REGS)
  7193. + {
  7194. + return_rtx = gen_rtx_REG (mode, FIRST_ARG_REGNO + cum->regs_used);
  7195. + }
  7196. +
  7197. + return return_rtx;
  7198. +}
  7199. +
  7200. +/*
  7201. + * This is just default_must_pass_in_stack from calls.c sans the final
  7202. + * test for padding which isn't needed: we define BLOCK_REG_PADDING
  7203. + * instead.
  7204. + */
  7205. +int
  7206. +nios2_must_pass_in_stack (enum machine_mode mode, tree type)
  7207. +{
  7208. + if (!type)
  7209. + return false;
  7210. +
  7211. + /* If the type has variable size... */
  7212. + if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
  7213. + return true;
  7214. +
  7215. + /* If the type is marked as addressable (it is required
  7216. + to be constructed into the stack)... */
  7217. + if (TREE_ADDRESSABLE (type))
  7218. + return true;
  7219. +
  7220. + return false;
  7221. +}
  7222. +
  7223. +int
  7224. +function_arg_partial_nregs (const CUMULATIVE_ARGS *cum,
  7225. + enum machine_mode mode, tree type,
  7226. + int named ATTRIBUTE_UNUSED)
  7227. +{
  7228. + HOST_WIDE_INT param_size;
  7229. +
  7230. + if (mode == BLKmode)
  7231. + {
  7232. + param_size = int_size_in_bytes (type);
  7233. + if (param_size < 0)
  7234. + internal_error
  7235. + ("Do not know how to handle large structs or variable length types");
  7236. + }
  7237. + else
  7238. + {
  7239. + param_size = GET_MODE_SIZE (mode);
  7240. + }
  7241. +
  7242. + /* convert to words (round up) */
  7243. + param_size = (3 + param_size) / 4;
  7244. +
  7245. + if (cum->regs_used < NUM_ARG_REGS
  7246. + && cum->regs_used + param_size > NUM_ARG_REGS)
  7247. + {
  7248. + return NUM_ARG_REGS - cum->regs_used;
  7249. + }
  7250. + else
  7251. + {
  7252. + return 0;
  7253. + }
  7254. +}
  7255. +
  7256. +
  7257. +/* Update the data in CUM to advance over an argument
  7258. + of mode MODE and data type TYPE.
  7259. + (TYPE is null for libcalls where that information may not be available.) */
  7260. +
  7261. +void
  7262. +function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
  7263. + tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED)
  7264. +{
  7265. + HOST_WIDE_INT param_size;
  7266. +
  7267. + if (mode == BLKmode)
  7268. + {
  7269. + param_size = int_size_in_bytes (type);
  7270. + if (param_size < 0)
  7271. + internal_error
  7272. + ("Do not know how to handle large structs or variable length types");
  7273. + }
  7274. + else
  7275. + {
  7276. + param_size = GET_MODE_SIZE (mode);
  7277. + }
  7278. +
  7279. + /* convert to words (round up) */
  7280. + param_size = (3 + param_size) / 4;
  7281. +
  7282. + if (cum->regs_used + param_size > NUM_ARG_REGS)
  7283. + {
  7284. + cum->regs_used = NUM_ARG_REGS;
  7285. + }
  7286. + else
  7287. + {
  7288. + cum->regs_used += param_size;
  7289. + }
  7290. +
  7291. + return;
  7292. +}
  7293. +
  7294. +int
  7295. +nios2_function_arg_padding_upward (enum machine_mode mode, tree type)
  7296. +{
  7297. + /* On little-endian targets, the first byte of every stack argument
  7298. + is passed in the first byte of the stack slot. */
  7299. + if (!BYTES_BIG_ENDIAN)
  7300. + return 1;
  7301. +
  7302. + /* Otherwise, integral types are padded downward: the last byte of a
  7303. + stack argument is passed in the last byte of the stack slot. */
  7304. + if (type != 0
  7305. + ? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
  7306. + : GET_MODE_CLASS (mode) == MODE_INT)
  7307. + return 0;
  7308. +
  7309. + /* Arguments smaller than a stack slot are padded downward. */
  7310. + if (mode != BLKmode)
  7311. + return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY) ? 1 : 0;
  7312. + else
  7313. + return ((int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT))
  7314. + ? 1 : 0);
  7315. +}
  7316. +
  7317. +int
  7318. +nios2_block_reg_padding_upward (enum machine_mode mode, tree type,
  7319. + int first ATTRIBUTE_UNUSED)
  7320. +{
  7321. + /* ??? Do we need to treat floating point specially, ala MIPS? */
  7322. + return nios2_function_arg_padding_upward (mode, type);
  7323. +}
  7324. +
  7325. +int
  7326. +nios2_return_in_memory (tree type)
  7327. +{
  7328. + int res = ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
  7329. + || (int_size_in_bytes (type) == -1));
  7330. +
  7331. + return res;
  7332. +}
  7333. +
  7334. +/* ??? It may be possible to eliminate the copyback and implement
  7335. + my own va_arg type, but that is more work for now. */
  7336. +int
  7337. +nios2_setup_incoming_varargs (const CUMULATIVE_ARGS *cum,
  7338. + enum machine_mode mode, tree type,
  7339. + int no_rtl)
  7340. +{
  7341. + CUMULATIVE_ARGS local_cum;
  7342. + int regs_to_push;
  7343. +
  7344. + local_cum = *cum;
  7345. + FUNCTION_ARG_ADVANCE (local_cum, mode, type, 1);
  7346. +
  7347. + regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
  7348. +
  7349. + if (!no_rtl)
  7350. + {
  7351. + if (regs_to_push > 0)
  7352. + {
  7353. + rtx ptr, mem;
  7354. +
  7355. + ptr = virtual_incoming_args_rtx;
  7356. + mem = gen_rtx_MEM (BLKmode, ptr);
  7357. +
  7358. + /* va_arg is an array access in this case, which causes
  7359. + it to get MEM_IN_STRUCT_P set. We must set it here
  7360. + so that the insn scheduler won't assume that these
  7361. + stores can't possibly overlap with the va_arg loads. */
  7362. + MEM_SET_IN_STRUCT_P (mem, 1);
  7363. +
  7364. + emit_insn (gen_blockage ());
  7365. + move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem,
  7366. + regs_to_push);
  7367. + emit_insn (gen_blockage ());
  7368. + }
  7369. + }
  7370. +
  7371. + return regs_to_push * UNITS_PER_WORD;
  7372. +
  7373. +}
  7374. +
  7375. +
  7376. +
  7377. +/*****************************************************************************
  7378. +**
  7379. +** builtins
  7380. +**
  7381. +** This method for handling builtins is from CSP where _many_ more types of
  7382. +** expanders have already been written. Check there first before writing
  7383. +** new ones.
  7384. +**
  7385. +*****************************************************************************/
  7386. +
  7387. +enum nios2_builtins
  7388. +{
  7389. + NIOS2_BUILTIN_LDBIO,
  7390. + NIOS2_BUILTIN_LDBUIO,
  7391. + NIOS2_BUILTIN_LDHIO,
  7392. + NIOS2_BUILTIN_LDHUIO,
  7393. + NIOS2_BUILTIN_LDWIO,
  7394. + NIOS2_BUILTIN_STBIO,
  7395. + NIOS2_BUILTIN_STHIO,
  7396. + NIOS2_BUILTIN_STWIO,
  7397. + NIOS2_BUILTIN_SYNC,
  7398. + NIOS2_BUILTIN_RDCTL,
  7399. + NIOS2_BUILTIN_WRCTL,
  7400. +
  7401. +#undef NIOS2_DO_BUILTIN
  7402. +#define NIOS2_DO_BUILTIN(upper, lower, handler) \
  7403. + NIOS2_CONCAT (NIOS2_BUILTIN_CUSTOM_, upper),
  7404. +NIOS2_FOR_ALL_CUSTOM_BUILTINS
  7405. +
  7406. + NIOS2_FIRST_FPU_INSN,
  7407. +
  7408. +#undef NIOS2_FPU_INSN
  7409. +#define NIOS2_FPU_INSN(opt, insn, args) \
  7410. + NIOS2_CONCAT (NIOS2_BUILTIN_FPU_, opt),
  7411. +NIOS2_FOR_ALL_FPU_INSNS
  7412. +
  7413. + NIOS2_LAST_FPU_INSN,
  7414. +
  7415. + LIM_NIOS2_BUILTINS
  7416. +};
  7417. +
  7418. +struct builtin_description
  7419. +{
  7420. + const enum insn_code icode;
  7421. + const char *const name;
  7422. + const enum nios2_builtins code;
  7423. + const tree *type;
  7424. + rtx (* expander) (const struct builtin_description *,
  7425. + tree, rtx, rtx, enum machine_mode, int);
  7426. +};
  7427. +
  7428. +static rtx nios2_expand_STXIO (const struct builtin_description *,
  7429. + tree, rtx, rtx, enum machine_mode, int);
  7430. +static rtx nios2_expand_LDXIO (const struct builtin_description *,
  7431. + tree, rtx, rtx, enum machine_mode, int);
  7432. +static rtx nios2_expand_sync (const struct builtin_description *,
  7433. + tree, rtx, rtx, enum machine_mode, int);
  7434. +static rtx nios2_expand_rdctl (const struct builtin_description *,
  7435. + tree, rtx, rtx, enum machine_mode, int);
  7436. +static rtx nios2_expand_wrctl (const struct builtin_description *,
  7437. + tree, rtx, rtx, enum machine_mode, int);
  7438. +
  7439. +static rtx nios2_expand_custom_n (const struct builtin_description *,
  7440. + tree, rtx, rtx, enum machine_mode, int);
  7441. +static rtx nios2_expand_custom_Xn (const struct builtin_description *,
  7442. + tree, rtx, rtx, enum machine_mode, int);
  7443. +static rtx nios2_expand_custom_nX (const struct builtin_description *,
  7444. + tree, rtx, rtx, enum machine_mode, int);
  7445. +static rtx nios2_expand_custom_XnX (const struct builtin_description *,
  7446. + tree, rtx, rtx, enum machine_mode, int);
  7447. +static rtx nios2_expand_custom_nXX (const struct builtin_description *,
  7448. + tree, rtx, rtx, enum machine_mode, int);
  7449. +static rtx nios2_expand_custom_XnXX (const struct builtin_description *,
  7450. + tree, rtx, rtx, enum machine_mode, int);
  7451. +
  7452. +static rtx nios2_expand_custom_zdz (const struct builtin_description *,
  7453. + tree, rtx, rtx, enum machine_mode, int);
  7454. +static rtx nios2_expand_custom_zsz (const struct builtin_description *,
  7455. + tree, rtx, rtx, enum machine_mode, int);
  7456. +static rtx nios2_expand_custom_szz (const struct builtin_description *,
  7457. + tree, rtx, rtx, enum machine_mode, int);
  7458. +static rtx nios2_expand_custom_sss (const struct builtin_description *,
  7459. + tree, rtx, rtx, enum machine_mode, int);
  7460. +static rtx nios2_expand_custom_ssz (const struct builtin_description *,
  7461. + tree, rtx, rtx, enum machine_mode, int);
  7462. +static rtx nios2_expand_custom_iss (const struct builtin_description *,
  7463. + tree, rtx, rtx, enum machine_mode, int);
  7464. +static rtx nios2_expand_custom_ddd (const struct builtin_description *,
  7465. + tree, rtx, rtx, enum machine_mode, int);
  7466. +static rtx nios2_expand_custom_ddz (const struct builtin_description *,
  7467. + tree, rtx, rtx, enum machine_mode, int);
  7468. +static rtx nios2_expand_custom_idd (const struct builtin_description *,
  7469. + tree, rtx, rtx, enum machine_mode, int);
  7470. +static rtx nios2_expand_custom_siz (const struct builtin_description *,
  7471. + tree, rtx, rtx, enum machine_mode, int);
  7472. +static rtx nios2_expand_custom_suz (const struct builtin_description *,
  7473. + tree, rtx, rtx, enum machine_mode, int);
  7474. +static rtx nios2_expand_custom_diz (const struct builtin_description *,
  7475. + tree, rtx, rtx, enum machine_mode, int);
  7476. +static rtx nios2_expand_custom_duz (const struct builtin_description *,
  7477. + tree, rtx, rtx, enum machine_mode, int);
  7478. +static rtx nios2_expand_custom_isz (const struct builtin_description *,
  7479. + tree, rtx, rtx, enum machine_mode, int);
  7480. +static rtx nios2_expand_custom_usz (const struct builtin_description *,
  7481. + tree, rtx, rtx, enum machine_mode, int);
  7482. +static rtx nios2_expand_custom_idz (const struct builtin_description *,
  7483. + tree, rtx, rtx, enum machine_mode, int);
  7484. +static rtx nios2_expand_custom_udz (const struct builtin_description *,
  7485. + tree, rtx, rtx, enum machine_mode, int);
  7486. +static rtx nios2_expand_custom_dsz (const struct builtin_description *,
  7487. + tree, rtx, rtx, enum machine_mode, int);
  7488. +static rtx nios2_expand_custom_sdz (const struct builtin_description *,
  7489. + tree, rtx, rtx, enum machine_mode, int);
  7490. +
  7491. +static tree endlink;
  7492. +
  7493. +/* int fn (volatile const void *)
  7494. + */
  7495. +static tree int_ftype_volatile_const_void_p;
  7496. +
  7497. +/* int fn (int)
  7498. + */
  7499. +static tree int_ftype_int;
  7500. +
  7501. +/* void fn (int, int)
  7502. + */
  7503. +static tree void_ftype_int_int;
  7504. +
  7505. +/* void fn (volatile void *, int)
  7506. + */
  7507. +static tree void_ftype_volatile_void_p_int;
  7508. +
  7509. +/* void fn (void)
  7510. + */
  7511. +static tree void_ftype_void;
  7512. +
  7513. +#undef NIOS2_DO_BUILTIN
  7514. +#define NIOS2_DO_BUILTIN(upper, lower, handler) \
  7515. + static tree NIOS2_CONCAT (custom_, lower);
  7516. +NIOS2_FOR_ALL_CUSTOM_BUILTINS
  7517. +
  7518. +static tree custom_zdz;
  7519. +static tree custom_zsz;
  7520. +static tree custom_szz;
  7521. +static tree custom_sss;
  7522. +static tree custom_ssz;
  7523. +static tree custom_iss;
  7524. +static tree custom_ddd;
  7525. +static tree custom_ddz;
  7526. +static tree custom_idd;
  7527. +static tree custom_siz;
  7528. +static tree custom_suz;
  7529. +static tree custom_diz;
  7530. +static tree custom_duz;
  7531. +static tree custom_isz;
  7532. +static tree custom_usz;
  7533. +static tree custom_idz;
  7534. +static tree custom_udz;
  7535. +static tree custom_dsz;
  7536. +static tree custom_sdz;
  7537. +
  7538. +static const struct builtin_description bdesc[] = {
  7539. + {CODE_FOR_ldbio, "__builtin_ldbio", NIOS2_BUILTIN_LDBIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
  7540. + {CODE_FOR_ldbuio, "__builtin_ldbuio", NIOS2_BUILTIN_LDBUIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
  7541. + {CODE_FOR_ldhio, "__builtin_ldhio", NIOS2_BUILTIN_LDHIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
  7542. + {CODE_FOR_ldhuio, "__builtin_ldhuio", NIOS2_BUILTIN_LDHUIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
  7543. + {CODE_FOR_ldwio, "__builtin_ldwio", NIOS2_BUILTIN_LDWIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
  7544. +
  7545. + {CODE_FOR_stbio, "__builtin_stbio", NIOS2_BUILTIN_STBIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
  7546. + {CODE_FOR_sthio, "__builtin_sthio", NIOS2_BUILTIN_STHIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
  7547. + {CODE_FOR_stwio, "__builtin_stwio", NIOS2_BUILTIN_STWIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
  7548. +
  7549. + {CODE_FOR_sync, "__builtin_sync", NIOS2_BUILTIN_SYNC, &void_ftype_void, nios2_expand_sync},
  7550. + {CODE_FOR_rdctl, "__builtin_rdctl", NIOS2_BUILTIN_RDCTL, &int_ftype_int, nios2_expand_rdctl},
  7551. + {CODE_FOR_wrctl, "__builtin_wrctl", NIOS2_BUILTIN_WRCTL, &void_ftype_int_int, nios2_expand_wrctl},
  7552. +
  7553. +#undef NIOS2_DO_BUILTIN
  7554. +#define NIOS2_DO_BUILTIN(upper, lower, handler) \
  7555. + {NIOS2_CONCAT (CODE_FOR_custom_, lower), \
  7556. + "__builtin_custom_" NIOS2_STRINGIFY (lower), \
  7557. + NIOS2_CONCAT (NIOS2_BUILTIN_CUSTOM_, upper), \
  7558. + &NIOS2_CONCAT (custom_, lower), \
  7559. + NIOS2_CONCAT (nios2_expand_custom_, handler)},
  7560. +NIOS2_FOR_ALL_CUSTOM_BUILTINS
  7561. +
  7562. +#undef NIOS2_FPU_INSN
  7563. +#define NIOS2_FPU_INSN(opt, insn, args) \
  7564. + {NIOS2_CONCAT (CODE_FOR_, insn), \
  7565. + "__builtin_custom_" NIOS2_STRINGIFY (opt), \
  7566. + NIOS2_CONCAT (NIOS2_BUILTIN_FPU_, opt), \
  7567. + &NIOS2_CONCAT (custom_, args), \
  7568. + NIOS2_CONCAT (nios2_expand_custom_, args)},
  7569. +NIOS2_FOR_ALL_FPU_INSNS
  7570. +
  7571. + {0, 0, 0, 0, 0},
  7572. +};
  7573. +
  7574. +/* This does not have a closing bracket on purpose (see use) */
  7575. +#define def_param(TYPE) \
  7576. + tree_cons (NULL_TREE, TYPE,
  7577. +
  7578. +static void
  7579. +nios2_init_builtins ()
  7580. +{
  7581. + const struct builtin_description *d;
  7582. +
  7583. +
  7584. + endlink = void_list_node;
  7585. +
  7586. + /* Special indenting here because one of the brackets is in def_param */
  7587. + /* *INDENT-OFF* */
  7588. +
  7589. + /* int fn (volatile const void *)
  7590. + */
  7591. + int_ftype_volatile_const_void_p
  7592. + = build_function_type (integer_type_node,
  7593. + def_param (build_qualified_type (ptr_type_node,
  7594. + TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))
  7595. + endlink));
  7596. +
  7597. +
  7598. + /* void fn (volatile void *, int)
  7599. + */
  7600. + void_ftype_volatile_void_p_int
  7601. + = build_function_type (void_type_node,
  7602. + def_param (build_qualified_type (ptr_type_node,
  7603. + TYPE_QUAL_VOLATILE))
  7604. + def_param (integer_type_node)
  7605. + endlink)));
  7606. +
  7607. + /* void fn (void)
  7608. + */
  7609. + void_ftype_void
  7610. + = build_function_type (void_type_node,
  7611. + endlink);
  7612. +
  7613. + /* int fn (int)
  7614. + */
  7615. + int_ftype_int
  7616. + = build_function_type (integer_type_node,
  7617. + def_param (integer_type_node)
  7618. + endlink));
  7619. +
  7620. + /* void fn (int, int)
  7621. + */
  7622. + void_ftype_int_int
  7623. + = build_function_type (void_type_node,
  7624. + def_param (integer_type_node)
  7625. + def_param (integer_type_node)
  7626. + endlink)));
  7627. +
  7628. +
  7629. +#define CUSTOM_NUM def_param (integer_type_node)
  7630. +
  7631. + custom_n
  7632. + = build_function_type (void_type_node,
  7633. + CUSTOM_NUM
  7634. + endlink));
  7635. + custom_ni
  7636. + = build_function_type (void_type_node,
  7637. + CUSTOM_NUM
  7638. + def_param (integer_type_node)
  7639. + endlink)));
  7640. + custom_nf
  7641. + = build_function_type (void_type_node,
  7642. + CUSTOM_NUM
  7643. + def_param (float_type_node)
  7644. + endlink)));
  7645. + custom_np
  7646. + = build_function_type (void_type_node,
  7647. + CUSTOM_NUM
  7648. + def_param (ptr_type_node)
  7649. + endlink)));
  7650. + custom_nii
  7651. + = build_function_type (void_type_node,
  7652. + CUSTOM_NUM
  7653. + def_param (integer_type_node)
  7654. + def_param (integer_type_node)
  7655. + endlink))));
  7656. + custom_nif
  7657. + = build_function_type (void_type_node,
  7658. + CUSTOM_NUM
  7659. + def_param (integer_type_node)
  7660. + def_param (float_type_node)
  7661. + endlink))));
  7662. + custom_nip
  7663. + = build_function_type (void_type_node,
  7664. + CUSTOM_NUM
  7665. + def_param (integer_type_node)
  7666. + def_param (ptr_type_node)
  7667. + endlink))));
  7668. + custom_nfi
  7669. + = build_function_type (void_type_node,
  7670. + CUSTOM_NUM
  7671. + def_param (float_type_node)
  7672. + def_param (integer_type_node)
  7673. + endlink))));
  7674. + custom_nff
  7675. + = build_function_type (void_type_node,
  7676. + CUSTOM_NUM
  7677. + def_param (float_type_node)
  7678. + def_param (float_type_node)
  7679. + endlink))));
  7680. + custom_nfp
  7681. + = build_function_type (void_type_node,
  7682. + CUSTOM_NUM
  7683. + def_param (float_type_node)
  7684. + def_param (ptr_type_node)
  7685. + endlink))));
  7686. + custom_npi
  7687. + = build_function_type (void_type_node,
  7688. + CUSTOM_NUM
  7689. + def_param (ptr_type_node)
  7690. + def_param (integer_type_node)
  7691. + endlink))));
  7692. + custom_npf
  7693. + = build_function_type (void_type_node,
  7694. + CUSTOM_NUM
  7695. + def_param (ptr_type_node)
  7696. + def_param (float_type_node)
  7697. + endlink))));
  7698. + custom_npp
  7699. + = build_function_type (void_type_node,
  7700. + CUSTOM_NUM
  7701. + def_param (ptr_type_node)
  7702. + def_param (ptr_type_node)
  7703. + endlink))));
  7704. +
  7705. + custom_in
  7706. + = build_function_type (integer_type_node,
  7707. + CUSTOM_NUM
  7708. + endlink));
  7709. + custom_ini
  7710. + = build_function_type (integer_type_node,
  7711. + CUSTOM_NUM
  7712. + def_param (integer_type_node)
  7713. + endlink)));
  7714. + custom_inf
  7715. + = build_function_type (integer_type_node,
  7716. + CUSTOM_NUM
  7717. + def_param (float_type_node)
  7718. + endlink)));
  7719. + custom_inp
  7720. + = build_function_type (integer_type_node,
  7721. + CUSTOM_NUM
  7722. + def_param (ptr_type_node)
  7723. + endlink)));
  7724. + custom_inii
  7725. + = build_function_type (integer_type_node,
  7726. + CUSTOM_NUM
  7727. + def_param (integer_type_node)
  7728. + def_param (integer_type_node)
  7729. + endlink))));
  7730. + custom_inif
  7731. + = build_function_type (integer_type_node,
  7732. + CUSTOM_NUM
  7733. + def_param (integer_type_node)
  7734. + def_param (float_type_node)
  7735. + endlink))));
  7736. + custom_inip
  7737. + = build_function_type (integer_type_node,
  7738. + CUSTOM_NUM
  7739. + def_param (integer_type_node)
  7740. + def_param (ptr_type_node)
  7741. + endlink))));
  7742. + custom_infi
  7743. + = build_function_type (integer_type_node,
  7744. + CUSTOM_NUM
  7745. + def_param (float_type_node)
  7746. + def_param (integer_type_node)
  7747. + endlink))));
  7748. + custom_inff
  7749. + = build_function_type (integer_type_node,
  7750. + CUSTOM_NUM
  7751. + def_param (float_type_node)
  7752. + def_param (float_type_node)
  7753. + endlink))));
  7754. + custom_infp
  7755. + = build_function_type (integer_type_node,
  7756. + CUSTOM_NUM
  7757. + def_param (float_type_node)
  7758. + def_param (ptr_type_node)
  7759. + endlink))));
  7760. + custom_inpi
  7761. + = build_function_type (integer_type_node,
  7762. + CUSTOM_NUM
  7763. + def_param (ptr_type_node)
  7764. + def_param (integer_type_node)
  7765. + endlink))));
  7766. + custom_inpf
  7767. + = build_function_type (integer_type_node,
  7768. + CUSTOM_NUM
  7769. + def_param (ptr_type_node)
  7770. + def_param (float_type_node)
  7771. + endlink))));
  7772. + custom_inpp
  7773. + = build_function_type (integer_type_node,
  7774. + CUSTOM_NUM
  7775. + def_param (ptr_type_node)
  7776. + def_param (ptr_type_node)
  7777. + endlink))));
  7778. +
  7779. + custom_fn
  7780. + = build_function_type (float_type_node,
  7781. + CUSTOM_NUM
  7782. + endlink));
  7783. + custom_fni
  7784. + = build_function_type (float_type_node,
  7785. + CUSTOM_NUM
  7786. + def_param (integer_type_node)
  7787. + endlink)));
  7788. + custom_fnf
  7789. + = build_function_type (float_type_node,
  7790. + CUSTOM_NUM
  7791. + def_param (float_type_node)
  7792. + endlink)));
  7793. + custom_fnp
  7794. + = build_function_type (float_type_node,
  7795. + CUSTOM_NUM
  7796. + def_param (ptr_type_node)
  7797. + endlink)));
  7798. + custom_fnii
  7799. + = build_function_type (float_type_node,
  7800. + CUSTOM_NUM
  7801. + def_param (integer_type_node)
  7802. + def_param (integer_type_node)
  7803. + endlink))));
  7804. + custom_fnif
  7805. + = build_function_type (float_type_node,
  7806. + CUSTOM_NUM
  7807. + def_param (integer_type_node)
  7808. + def_param (float_type_node)
  7809. + endlink))));
  7810. + custom_fnip
  7811. + = build_function_type (float_type_node,
  7812. + CUSTOM_NUM
  7813. + def_param (integer_type_node)
  7814. + def_param (ptr_type_node)
  7815. + endlink))));
  7816. + custom_fnfi
  7817. + = build_function_type (float_type_node,
  7818. + CUSTOM_NUM
  7819. + def_param (float_type_node)
  7820. + def_param (integer_type_node)
  7821. + endlink))));
  7822. + custom_fnff
  7823. + = build_function_type (float_type_node,
  7824. + CUSTOM_NUM
  7825. + def_param (float_type_node)
  7826. + def_param (float_type_node)
  7827. + endlink))));
  7828. + custom_fnfp
  7829. + = build_function_type (float_type_node,
  7830. + CUSTOM_NUM
  7831. + def_param (float_type_node)
  7832. + def_param (ptr_type_node)
  7833. + endlink))));
  7834. + custom_fnpi
  7835. + = build_function_type (float_type_node,
  7836. + CUSTOM_NUM
  7837. + def_param (ptr_type_node)
  7838. + def_param (integer_type_node)
  7839. + endlink))));
  7840. + custom_fnpf
  7841. + = build_function_type (float_type_node,
  7842. + CUSTOM_NUM
  7843. + def_param (ptr_type_node)
  7844. + def_param (float_type_node)
  7845. + endlink))));
  7846. + custom_fnpp
  7847. + = build_function_type (float_type_node,
  7848. + CUSTOM_NUM
  7849. + def_param (ptr_type_node)
  7850. + def_param (ptr_type_node)
  7851. + endlink))));
  7852. +
  7853. +
  7854. + custom_pn
  7855. + = build_function_type (ptr_type_node,
  7856. + CUSTOM_NUM
  7857. + endlink));
  7858. + custom_pni
  7859. + = build_function_type (ptr_type_node,
  7860. + CUSTOM_NUM
  7861. + def_param (integer_type_node)
  7862. + endlink)));
  7863. + custom_pnf
  7864. + = build_function_type (ptr_type_node,
  7865. + CUSTOM_NUM
  7866. + def_param (float_type_node)
  7867. + endlink)));
  7868. + custom_pnp
  7869. + = build_function_type (ptr_type_node,
  7870. + CUSTOM_NUM
  7871. + def_param (ptr_type_node)
  7872. + endlink)));
  7873. + custom_pnii
  7874. + = build_function_type (ptr_type_node,
  7875. + CUSTOM_NUM
  7876. + def_param (integer_type_node)
  7877. + def_param (integer_type_node)
  7878. + endlink))));
  7879. + custom_pnif
  7880. + = build_function_type (ptr_type_node,
  7881. + CUSTOM_NUM
  7882. + def_param (integer_type_node)
  7883. + def_param (float_type_node)
  7884. + endlink))));
  7885. + custom_pnip
  7886. + = build_function_type (ptr_type_node,
  7887. + CUSTOM_NUM
  7888. + def_param (integer_type_node)
  7889. + def_param (ptr_type_node)
  7890. + endlink))));
  7891. + custom_pnfi
  7892. + = build_function_type (ptr_type_node,
  7893. + CUSTOM_NUM
  7894. + def_param (float_type_node)
  7895. + def_param (integer_type_node)
  7896. + endlink))));
  7897. + custom_pnff
  7898. + = build_function_type (ptr_type_node,
  7899. + CUSTOM_NUM
  7900. + def_param (float_type_node)
  7901. + def_param (float_type_node)
  7902. + endlink))));
  7903. + custom_pnfp
  7904. + = build_function_type (ptr_type_node,
  7905. + CUSTOM_NUM
  7906. + def_param (float_type_node)
  7907. + def_param (ptr_type_node)
  7908. + endlink))));
  7909. + custom_pnpi
  7910. + = build_function_type (ptr_type_node,
  7911. + CUSTOM_NUM
  7912. + def_param (ptr_type_node)
  7913. + def_param (integer_type_node)
  7914. + endlink))));
  7915. + custom_pnpf
  7916. + = build_function_type (ptr_type_node,
  7917. + CUSTOM_NUM
  7918. + def_param (ptr_type_node)
  7919. + def_param (float_type_node)
  7920. + endlink))));
  7921. + custom_pnpp
  7922. + = build_function_type (ptr_type_node,
  7923. + CUSTOM_NUM
  7924. + def_param (ptr_type_node)
  7925. + def_param (ptr_type_node)
  7926. + endlink))));
  7927. +
  7928. + custom_zdz
  7929. + = build_function_type (void_type_node,
  7930. + def_param (double_type_node)
  7931. + endlink));
  7932. +
  7933. + custom_zsz
  7934. + = build_function_type (void_type_node,
  7935. + def_param (float_type_node)
  7936. + endlink));
  7937. +
  7938. + custom_szz
  7939. + = build_function_type (float_type_node,
  7940. + def_param (void_type_node)
  7941. + endlink));
  7942. +
  7943. + custom_sss
  7944. + = build_function_type (float_type_node,
  7945. + def_param (float_type_node)
  7946. + def_param (float_type_node)
  7947. + endlink)));
  7948. +
  7949. + custom_ssz
  7950. + = build_function_type (float_type_node,
  7951. + def_param (float_type_node)
  7952. + endlink));
  7953. +
  7954. + custom_iss
  7955. + = build_function_type (integer_type_node,
  7956. + def_param (float_type_node)
  7957. + def_param (float_type_node)
  7958. + endlink)));
  7959. +
  7960. + custom_ddd
  7961. + = build_function_type (double_type_node,
  7962. + def_param (double_type_node)
  7963. + def_param (double_type_node)
  7964. + endlink)));
  7965. +
  7966. + custom_ddz
  7967. + = build_function_type (double_type_node,
  7968. + def_param (double_type_node)
  7969. + endlink));
  7970. +
  7971. + custom_idd
  7972. + = build_function_type (integer_type_node,
  7973. + def_param (double_type_node)
  7974. + def_param (double_type_node)
  7975. + endlink)));
  7976. +
  7977. + custom_siz
  7978. + = build_function_type (float_type_node,
  7979. + def_param (integer_type_node)
  7980. + endlink));
  7981. +
  7982. + custom_suz
  7983. + = build_function_type (float_type_node,
  7984. + def_param (unsigned_type_node)
  7985. + endlink));
  7986. +
  7987. + custom_diz
  7988. + = build_function_type (double_type_node,
  7989. + def_param (integer_type_node)
  7990. + endlink));
  7991. +
  7992. + custom_duz
  7993. + = build_function_type (double_type_node,
  7994. + def_param (unsigned_type_node)
  7995. + endlink));
  7996. +
  7997. + custom_isz
  7998. + = build_function_type (integer_type_node,
  7999. + def_param (float_type_node)
  8000. + endlink));
  8001. +
  8002. + custom_usz
  8003. + = build_function_type (unsigned_type_node,
  8004. + def_param (float_type_node)
  8005. + endlink));
  8006. +
  8007. + custom_idz
  8008. + = build_function_type (integer_type_node,
  8009. + def_param (double_type_node)
  8010. + endlink));
  8011. +
  8012. + custom_udz
  8013. + = build_function_type (unsigned_type_node,
  8014. + def_param (double_type_node)
  8015. + endlink));
  8016. +
  8017. + custom_dsz
  8018. + = build_function_type (double_type_node,
  8019. + def_param (float_type_node)
  8020. + endlink));
  8021. +
  8022. + custom_sdz
  8023. + = build_function_type (float_type_node,
  8024. + def_param (double_type_node)
  8025. + endlink));
  8026. +
  8027. + /* *INDENT-ON* */
  8028. +
  8029. +
  8030. + for (d = bdesc; d->name; d++)
  8031. + {
  8032. + builtin_function (d->name, *d->type, d->code,
  8033. + BUILT_IN_MD, NULL, NULL);
  8034. + }
  8035. +}
  8036. +
  8037. +/* Expand an expression EXP that calls a built-in function,
  8038. + with result going to TARGET if that's convenient
  8039. + (and in mode MODE if that's convenient).
  8040. + SUBTARGET may be used as the target for computing one of EXP's operands.
  8041. + IGNORE is nonzero if the value is to be ignored. */
  8042. +
  8043. +static rtx
  8044. +nios2_expand_builtin (tree exp, rtx target, rtx subtarget,
  8045. + enum machine_mode mode, int ignore)
  8046. +{
  8047. + const struct builtin_description *d;
  8048. + tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
  8049. + unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
  8050. +
  8051. + for (d = bdesc; d->name; d++)
  8052. + if (d->code == fcode)
  8053. + {
  8054. + if (d->code > NIOS2_FIRST_FPU_INSN && d->code < NIOS2_LAST_FPU_INSN)
  8055. + {
  8056. + nios2_fpu_info *inf = &nios2_fpu_insns[d->code - (NIOS2_FIRST_FPU_INSN + 1)];
  8057. + const struct insn_data *idata = &insn_data[d->icode];
  8058. + if (inf->N < 0)
  8059. + {
  8060. + fatal_error ("Cannot call `%s' without specifying switch `-mcustom-%s'",
  8061. + d->name,
  8062. + inf->option);
  8063. + }
  8064. + if (inf->args[0] != 'z'
  8065. + && (!target
  8066. + || !(idata->operand[0].predicate) (target,
  8067. + idata->operand[0].mode)))
  8068. + target = gen_reg_rtx (idata->operand[0].mode);
  8069. + }
  8070. + return (d->expander) (d, exp, target, subtarget, mode, ignore);
  8071. + }
  8072. +
  8073. + /* we should have seen one of the functins we registered */
  8074. + abort ();
  8075. +}
  8076. +
  8077. +static rtx nios2_create_target (const struct builtin_description *, rtx);
  8078. +
  8079. +
  8080. +static rtx
  8081. +nios2_create_target (const struct builtin_description *d, rtx target)
  8082. +{
  8083. + if (!target
  8084. + || !(*insn_data[d->icode].operand[0].predicate) (target,
  8085. + insn_data[d->icode].operand[0].mode))
  8086. + {
  8087. + target = gen_reg_rtx (insn_data[d->icode].operand[0].mode);
  8088. + }
  8089. +
  8090. + return target;
  8091. +}
  8092. +
  8093. +
  8094. +static rtx nios2_extract_opcode (const struct builtin_description *, int, tree);
  8095. +static rtx nios2_extract_operand (const struct builtin_description *, int, int, tree);
  8096. +
  8097. +static rtx
  8098. +nios2_extract_opcode (const struct builtin_description *d, int op, tree arglist)
  8099. +{
  8100. + enum machine_mode mode = insn_data[d->icode].operand[op].mode;
  8101. + tree arg = TREE_VALUE (arglist);
  8102. + rtx opcode = expand_expr (arg, NULL_RTX, mode, 0);
  8103. + opcode = protect_from_queue (opcode, 0);
  8104. +
  8105. + if (!(*insn_data[d->icode].operand[op].predicate) (opcode, mode))
  8106. + error ("Custom instruction opcode must be compile time constant in the range 0-255 for %s", d->name);
  8107. +
  8108. + builtin_custom_seen[INTVAL (opcode)] = d->name;
  8109. + nios2_custom_check_insns (0);
  8110. + return opcode;
  8111. +}
  8112. +
  8113. +static rtx
  8114. +nios2_extract_operand (const struct builtin_description *d, int op, int argnum, tree arglist)
  8115. +{
  8116. + enum machine_mode mode = insn_data[d->icode].operand[op].mode;
  8117. + tree arg = TREE_VALUE (arglist);
  8118. + rtx operand = expand_expr (arg, NULL_RTX, mode, 0);
  8119. + operand = protect_from_queue (operand, 0);
  8120. +
  8121. + if (!(*insn_data[d->icode].operand[op].predicate) (operand, mode))
  8122. + operand = copy_to_mode_reg (mode, operand);
  8123. +
  8124. + /* ??? Better errors would be nice */
  8125. + if (!(*insn_data[d->icode].operand[op].predicate) (operand, mode))
  8126. + error ("Invalid argument %d to %s", argnum, d->name);
  8127. +
  8128. + return operand;
  8129. +}
  8130. +
  8131. +
  8132. +static rtx
  8133. +nios2_expand_custom_n (const struct builtin_description *d, tree exp,
  8134. + rtx target ATTRIBUTE_UNUSED, rtx subtarget ATTRIBUTE_UNUSED,
  8135. + enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED)
  8136. +{
  8137. + tree arglist = TREE_OPERAND (exp, 1);
  8138. + rtx pat;
  8139. + rtx opcode;
  8140. +
  8141. + /* custom_n should have exactly one operand */
  8142. + if (insn_data[d->icode].n_operands != 1)
  8143. + abort ();
  8144. +
  8145. + opcode = nios2_extract_opcode (d, 0, arglist);
  8146. +
  8147. + pat = GEN_FCN (d->icode) (opcode);
  8148. + if (!pat)
  8149. + return 0;
  8150. + emit_insn (pat);
  8151. + return 0;
  8152. +}
  8153. +
  8154. +static rtx
  8155. +nios2_expand_custom_Xn (const struct builtin_description *d, tree exp,
  8156. + rtx target, rtx subtarget ATTRIBUTE_UNUSED,
  8157. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8158. + int ignore ATTRIBUTE_UNUSED)
  8159. +{
  8160. + tree arglist = TREE_OPERAND (exp, 1);
  8161. + rtx pat;
  8162. + rtx opcode;
  8163. +
  8164. + /* custom_Xn should have exactly two operands */
  8165. + if (insn_data[d->icode].n_operands != 2)
  8166. + abort ();
  8167. +
  8168. + target = nios2_create_target (d, target);
  8169. + opcode = nios2_extract_opcode (d, 1, arglist);
  8170. +
  8171. + pat = GEN_FCN (d->icode) (target, opcode);
  8172. + if (!pat)
  8173. + return 0;
  8174. + emit_insn (pat);
  8175. + return target;
  8176. +}
  8177. +
  8178. +static rtx
  8179. +nios2_expand_custom_nX (const struct builtin_description *d, tree exp,
  8180. + rtx target ATTRIBUTE_UNUSED, rtx subtarget ATTRIBUTE_UNUSED,
  8181. + enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED)
  8182. +{
  8183. + tree arglist = TREE_OPERAND (exp, 1);
  8184. + rtx pat;
  8185. + rtx opcode;
  8186. + rtx operands[1];
  8187. + int i;
  8188. +
  8189. +
  8190. + /* custom_nX should have exactly two operands */
  8191. + if (insn_data[d->icode].n_operands != 2)
  8192. + abort ();
  8193. +
  8194. + opcode = nios2_extract_opcode (d, 0, arglist);
  8195. + for (i = 0; i < 1; i++)
  8196. + {
  8197. + arglist = TREE_CHAIN (arglist);
  8198. + operands[i] = nios2_extract_operand (d, i + 1, i + 1, arglist);
  8199. + }
  8200. +
  8201. + pat = GEN_FCN (d->icode) (opcode, operands[0]);
  8202. + if (!pat)
  8203. + return 0;
  8204. + emit_insn (pat);
  8205. + return 0;
  8206. +}
  8207. +
  8208. +static rtx
  8209. +nios2_expand_custom_XnX (const struct builtin_description *d, tree exp, rtx target,
  8210. + rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
  8211. + int ignore ATTRIBUTE_UNUSED)
  8212. +{
  8213. + tree arglist = TREE_OPERAND (exp, 1);
  8214. + rtx pat;
  8215. + rtx opcode;
  8216. + rtx operands[1];
  8217. + int i;
  8218. +
  8219. + /* custom_Xn should have exactly three operands */
  8220. + if (insn_data[d->icode].n_operands != 3)
  8221. + abort ();
  8222. +
  8223. + target = nios2_create_target (d, target);
  8224. + opcode = nios2_extract_opcode (d, 1, arglist);
  8225. +
  8226. + for (i = 0; i < 1; i++)
  8227. + {
  8228. + arglist = TREE_CHAIN (arglist);
  8229. + operands[i] = nios2_extract_operand (d, i + 2, i + 1, arglist);
  8230. + }
  8231. +
  8232. + pat = GEN_FCN (d->icode) (target, opcode, operands[0]);
  8233. +
  8234. + if (!pat)
  8235. + return 0;
  8236. + emit_insn (pat);
  8237. + return target;
  8238. +}
  8239. +
  8240. +static rtx
  8241. +nios2_expand_custom_nXX (const struct builtin_description *d, tree exp, rtx target ATTRIBUTE_UNUSED,
  8242. + rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
  8243. + int ignore ATTRIBUTE_UNUSED)
  8244. +{
  8245. + tree arglist = TREE_OPERAND (exp, 1);
  8246. + rtx pat;
  8247. + rtx opcode;
  8248. + rtx operands[2];
  8249. + int i;
  8250. +
  8251. +
  8252. + /* custom_nX should have exactly three operands */
  8253. + if (insn_data[d->icode].n_operands != 3)
  8254. + abort ();
  8255. +
  8256. + opcode = nios2_extract_opcode (d, 0, arglist);
  8257. + for (i = 0; i < 2; i++)
  8258. + {
  8259. + arglist = TREE_CHAIN (arglist);
  8260. + operands[i] = nios2_extract_operand (d, i + 1, i + 1, arglist);
  8261. + }
  8262. +
  8263. + pat = GEN_FCN (d->icode) (opcode, operands[0], operands[1]);
  8264. + if (!pat)
  8265. + return 0;
  8266. + emit_insn (pat);
  8267. + return 0;
  8268. +}
  8269. +
  8270. +static rtx
  8271. +nios2_expand_custom_XnXX (const struct builtin_description *d, tree exp, rtx target,
  8272. + rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
  8273. + int ignore ATTRIBUTE_UNUSED)
  8274. +{
  8275. + tree arglist = TREE_OPERAND (exp, 1);
  8276. + rtx pat;
  8277. + rtx opcode;
  8278. + rtx operands[2];
  8279. + int i;
  8280. +
  8281. +
  8282. + /* custom_XnX should have exactly four operands */
  8283. + if (insn_data[d->icode].n_operands != 4)
  8284. + abort ();
  8285. +
  8286. + target = nios2_create_target (d, target);
  8287. + opcode = nios2_extract_opcode (d, 1, arglist);
  8288. + for (i = 0; i < 2; i++)
  8289. + {
  8290. + arglist = TREE_CHAIN (arglist);
  8291. + operands[i] = nios2_extract_operand (d, i + 2, i + 1, arglist);
  8292. + }
  8293. +
  8294. + pat = GEN_FCN (d->icode) (target, opcode, operands[0], operands[1]);
  8295. +
  8296. + if (!pat)
  8297. + return 0;
  8298. + emit_insn (pat);
  8299. + return target;
  8300. +}
  8301. +
  8302. +
  8303. +
  8304. +static rtx
  8305. +nios2_expand_STXIO (const struct builtin_description *d, tree exp, rtx target ATTRIBUTE_UNUSED,
  8306. + rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
  8307. + int ignore ATTRIBUTE_UNUSED)
  8308. +{
  8309. + tree arglist = TREE_OPERAND (exp, 1);
  8310. + rtx pat;
  8311. + rtx store_dest, store_val;
  8312. + enum insn_code icode = d->icode;
  8313. +
  8314. + /* stores should have exactly two operands */
  8315. + if (insn_data[icode].n_operands != 2)
  8316. + abort ();
  8317. +
  8318. + /* process the destination of the store */
  8319. + {
  8320. + enum machine_mode mode = insn_data[icode].operand[0].mode;
  8321. + tree arg = TREE_VALUE (arglist);
  8322. + store_dest = expand_expr (arg, NULL_RTX, VOIDmode, 0);
  8323. + store_dest = protect_from_queue (store_dest, 0);
  8324. +
  8325. + store_dest = gen_rtx_MEM (mode, copy_to_mode_reg (Pmode, store_dest));
  8326. +
  8327. + /* ??? Better errors would be nice */
  8328. + if (!(*insn_data[icode].operand[0].predicate) (store_dest, mode))
  8329. + error ("Invalid argument 1 to %s", d->name);
  8330. + }
  8331. +
  8332. +
  8333. + /* process the value to store */
  8334. + {
  8335. + enum machine_mode mode = insn_data[icode].operand[1].mode;
  8336. + tree arg = TREE_VALUE (TREE_CHAIN (arglist));
  8337. + store_val = expand_expr (arg, NULL_RTX, mode, 0);
  8338. + store_val = protect_from_queue (store_val, 0);
  8339. +
  8340. + if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
  8341. + store_val = copy_to_mode_reg (mode, store_val);
  8342. +
  8343. + /* ??? Better errors would be nice */
  8344. + if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
  8345. + error ("Invalid argument 2 to %s", d->name);
  8346. + }
  8347. +
  8348. + pat = GEN_FCN (d->icode) (store_dest, store_val);
  8349. + if (!pat)
  8350. + return 0;
  8351. + emit_insn (pat);
  8352. + return 0;
  8353. +}
  8354. +
  8355. +
  8356. +static rtx
  8357. +nios2_expand_LDXIO (const struct builtin_description * d, tree exp, rtx target,
  8358. + rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
  8359. + int ignore ATTRIBUTE_UNUSED)
  8360. +{
  8361. + tree arglist = TREE_OPERAND (exp, 1);
  8362. + rtx pat;
  8363. + rtx ld_src;
  8364. + enum insn_code icode = d->icode;
  8365. +
  8366. + /* loads should have exactly two operands */
  8367. + if (insn_data[icode].n_operands != 2)
  8368. + abort ();
  8369. +
  8370. + target = nios2_create_target (d, target);
  8371. +
  8372. + {
  8373. + enum machine_mode mode = insn_data[icode].operand[1].mode;
  8374. + tree arg = TREE_VALUE (arglist);
  8375. + ld_src = expand_expr (arg, NULL_RTX, VOIDmode, 0);
  8376. + ld_src = protect_from_queue (ld_src, 0);
  8377. +
  8378. + ld_src = gen_rtx_MEM (mode, copy_to_mode_reg (Pmode, ld_src));
  8379. +
  8380. + /* ??? Better errors would be nice */
  8381. + if (!(*insn_data[icode].operand[1].predicate) (ld_src, mode))
  8382. + {
  8383. + error ("Invalid argument 1 to %s", d->name);
  8384. + }
  8385. + }
  8386. +
  8387. + pat = GEN_FCN (d->icode) (target, ld_src);
  8388. + if (!pat)
  8389. + return 0;
  8390. + emit_insn (pat);
  8391. + return target;
  8392. +}
  8393. +
  8394. +
  8395. +static rtx
  8396. +nios2_expand_sync (const struct builtin_description * d ATTRIBUTE_UNUSED,
  8397. + tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED,
  8398. + rtx subtarget ATTRIBUTE_UNUSED,
  8399. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8400. + int ignore ATTRIBUTE_UNUSED)
  8401. +{
  8402. + emit_insn (gen_sync ());
  8403. + return 0;
  8404. +}
  8405. +
  8406. +static rtx
  8407. +nios2_expand_rdctl (const struct builtin_description * d ATTRIBUTE_UNUSED,
  8408. + tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED,
  8409. + rtx subtarget ATTRIBUTE_UNUSED,
  8410. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8411. + int ignore ATTRIBUTE_UNUSED)
  8412. +{
  8413. + tree arglist = TREE_OPERAND (exp, 1);
  8414. + rtx pat;
  8415. + rtx rdctl_reg;
  8416. + enum insn_code icode = d->icode;
  8417. +
  8418. + /* rdctl should have exactly two operands */
  8419. + if (insn_data[icode].n_operands != 2)
  8420. + abort ();
  8421. +
  8422. + target = nios2_create_target (d, target);
  8423. +
  8424. + {
  8425. + enum machine_mode mode = insn_data[icode].operand[1].mode;
  8426. + tree arg = TREE_VALUE (arglist);
  8427. + rdctl_reg = expand_expr (arg, NULL_RTX, VOIDmode, 0);
  8428. + rdctl_reg = protect_from_queue (rdctl_reg, 0);
  8429. +
  8430. + if (!(*insn_data[icode].operand[1].predicate) (rdctl_reg, mode))
  8431. + {
  8432. + error ("Control register number must be in range 0-31 for %s", d->name);
  8433. + }
  8434. + }
  8435. +
  8436. + pat = GEN_FCN (d->icode) (target, rdctl_reg);
  8437. + if (!pat)
  8438. + return 0;
  8439. + emit_insn (pat);
  8440. + return target;
  8441. +}
  8442. +
  8443. +static rtx
  8444. +nios2_expand_wrctl (const struct builtin_description * d ATTRIBUTE_UNUSED,
  8445. + tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED,
  8446. + rtx subtarget ATTRIBUTE_UNUSED,
  8447. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8448. + int ignore ATTRIBUTE_UNUSED)
  8449. +{
  8450. + tree arglist = TREE_OPERAND (exp, 1);
  8451. + rtx pat;
  8452. + rtx wrctl_reg, store_val;
  8453. + enum insn_code icode = d->icode;
  8454. +
  8455. + /* stores should have exactly two operands */
  8456. + if (insn_data[icode].n_operands != 2)
  8457. + abort ();
  8458. +
  8459. + /* process the destination of the store */
  8460. + {
  8461. + enum machine_mode mode = insn_data[icode].operand[0].mode;
  8462. + tree arg = TREE_VALUE (arglist);
  8463. + wrctl_reg = expand_expr (arg, NULL_RTX, VOIDmode, 0);
  8464. + wrctl_reg = protect_from_queue (wrctl_reg, 0);
  8465. +
  8466. + if (!(*insn_data[icode].operand[0].predicate) (wrctl_reg, mode))
  8467. + error ("Control register number must be in range 0-31 for %s", d->name);
  8468. + }
  8469. +
  8470. +
  8471. + /* process the value to store */
  8472. + {
  8473. + enum machine_mode mode = insn_data[icode].operand[1].mode;
  8474. + tree arg = TREE_VALUE (TREE_CHAIN (arglist));
  8475. + store_val = expand_expr (arg, NULL_RTX, mode, 0);
  8476. + store_val = protect_from_queue (store_val, 0);
  8477. +
  8478. + if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
  8479. + store_val = copy_to_mode_reg (mode, store_val);
  8480. +
  8481. + /* ??? Better errors would be nice */
  8482. + if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
  8483. + error ("Invalid argument 2 to %s", d->name);
  8484. + }
  8485. +
  8486. + pat = GEN_FCN (d->icode) (wrctl_reg, store_val);
  8487. + if (!pat)
  8488. + return 0;
  8489. + emit_insn (pat);
  8490. + return 0;
  8491. +}
  8492. +
  8493. +static rtx
  8494. +nios2_extract_double (const struct insn_data *idata, tree arglist, int index)
  8495. +{
  8496. + rtx arg;
  8497. +
  8498. + while (index--)
  8499. + {
  8500. + arglist = TREE_CHAIN (arglist);
  8501. + }
  8502. + arg = expand_expr (TREE_VALUE (arglist), NULL_RTX, DFmode, 0);
  8503. + arg = protect_from_queue (arg, 0);
  8504. + if (!(*(idata->operand[index+1].predicate)) (arg, DFmode))
  8505. + {
  8506. + arg = copy_to_mode_reg (DFmode, arg);
  8507. + }
  8508. + return arg;
  8509. +}
  8510. +
  8511. +static rtx
  8512. +nios2_extract_float (const struct insn_data *idata, tree arglist, int index)
  8513. +{
  8514. + rtx arg;
  8515. +
  8516. + while (index--)
  8517. + {
  8518. + arglist = TREE_CHAIN (arglist);
  8519. + }
  8520. + arg = expand_expr (TREE_VALUE (arglist), NULL_RTX, SFmode, 0);
  8521. + arg = protect_from_queue (arg, 0);
  8522. + if (!(*(idata->operand[index+1].predicate)) (arg, SFmode))
  8523. + {
  8524. + arg = copy_to_mode_reg (SFmode, arg);
  8525. + }
  8526. + return arg;
  8527. +}
  8528. +
  8529. +static rtx
  8530. +nios2_extract_integer (const struct insn_data *idata, tree arglist, int index)
  8531. +{
  8532. + rtx arg;
  8533. +
  8534. + while (index--)
  8535. + {
  8536. + arglist = TREE_CHAIN (arglist);
  8537. + }
  8538. + arg = expand_expr (TREE_VALUE (arglist), NULL_RTX, SImode, 0);
  8539. + arg = protect_from_queue (arg, 0);
  8540. + if (!(*(idata->operand[index+1].predicate)) (arg, SImode))
  8541. + {
  8542. + arg = copy_to_mode_reg (SImode, arg);
  8543. + }
  8544. + return protect_from_queue (arg, 0);
  8545. +}
  8546. +
  8547. +static rtx
  8548. +nios2_expand_custom_zdz (const struct builtin_description *d,
  8549. + tree exp,
  8550. + rtx target ATTRIBUTE_UNUSED,
  8551. + rtx subtarget ATTRIBUTE_UNUSED,
  8552. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8553. + int ignore ATTRIBUTE_UNUSED)
  8554. +{
  8555. + tree arglist = TREE_OPERAND (exp, 1);
  8556. + rtx pat = GEN_FCN (d->icode) (nios2_extract_double (&insn_data[d->icode],
  8557. + arglist, 0));
  8558. + if (pat)
  8559. + emit_insn (pat);
  8560. + return 0;
  8561. +}
  8562. +
  8563. +static rtx
  8564. +nios2_expand_custom_zsz (const struct builtin_description *d,
  8565. + tree exp,
  8566. + rtx target ATTRIBUTE_UNUSED,
  8567. + rtx subtarget ATTRIBUTE_UNUSED,
  8568. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8569. + int ignore ATTRIBUTE_UNUSED)
  8570. +{
  8571. + tree arglist = TREE_OPERAND (exp, 1);
  8572. + rtx pat = GEN_FCN (d->icode) (nios2_extract_float (&insn_data[d->icode],
  8573. + arglist, 0));
  8574. + if (pat)
  8575. + emit_insn (pat);
  8576. + return 0;
  8577. +}
  8578. +
  8579. +static rtx
  8580. +nios2_expand_custom_szz (const struct builtin_description *d,
  8581. + tree exp ATTRIBUTE_UNUSED,
  8582. + rtx target,
  8583. + rtx subtarget ATTRIBUTE_UNUSED,
  8584. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8585. + int ignore ATTRIBUTE_UNUSED)
  8586. +{
  8587. + rtx pat = GEN_FCN (d->icode) (target);
  8588. + if (pat)
  8589. + emit_insn (pat);
  8590. + return target;
  8591. +}
  8592. +
  8593. +static rtx
  8594. +nios2_expand_custom_sss (const struct builtin_description *d,
  8595. + tree exp,
  8596. + rtx target,
  8597. + rtx subtarget ATTRIBUTE_UNUSED,
  8598. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8599. + int ignore ATTRIBUTE_UNUSED)
  8600. +{
  8601. + tree arglist = TREE_OPERAND (exp, 1);
  8602. + rtx pat = GEN_FCN (d->icode) (target,
  8603. + nios2_extract_float (&insn_data[d->icode],
  8604. + arglist, 0),
  8605. + nios2_extract_float (&insn_data[d->icode],
  8606. + arglist, 1));
  8607. + if (pat)
  8608. + emit_insn (pat);
  8609. + return target;
  8610. +}
  8611. +
  8612. +static rtx
  8613. +nios2_expand_custom_ssz (const struct builtin_description *d,
  8614. + tree exp,
  8615. + rtx target,
  8616. + rtx subtarget ATTRIBUTE_UNUSED,
  8617. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8618. + int ignore ATTRIBUTE_UNUSED)
  8619. +{
  8620. + tree arglist = TREE_OPERAND (exp, 1);
  8621. + rtx pat = GEN_FCN (d->icode) (target,
  8622. + nios2_extract_float (&insn_data[d->icode],
  8623. + arglist, 0));
  8624. + if (pat)
  8625. + emit_insn (pat);
  8626. + return target;
  8627. +}
  8628. +
  8629. +static rtx
  8630. +nios2_expand_custom_iss (const struct builtin_description *d,
  8631. + tree exp,
  8632. + rtx target,
  8633. + rtx subtarget ATTRIBUTE_UNUSED,
  8634. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8635. + int ignore ATTRIBUTE_UNUSED)
  8636. +{
  8637. + tree arglist = TREE_OPERAND (exp, 1);
  8638. + rtx pat = GEN_FCN (d->icode) (target,
  8639. + nios2_extract_float (&insn_data[d->icode],
  8640. + arglist, 0),
  8641. + nios2_extract_float (&insn_data[d->icode],
  8642. + arglist, 1));
  8643. + if (pat)
  8644. + emit_insn (pat);
  8645. + return target;
  8646. +}
  8647. +
  8648. +static rtx
  8649. +nios2_expand_custom_ddd (const struct builtin_description *d,
  8650. + tree exp,
  8651. + rtx target,
  8652. + rtx subtarget ATTRIBUTE_UNUSED,
  8653. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8654. + int ignore ATTRIBUTE_UNUSED)
  8655. +{
  8656. + tree arglist = TREE_OPERAND (exp, 1);
  8657. + rtx pat = GEN_FCN (d->icode) (target,
  8658. + nios2_extract_double (&insn_data[d->icode],
  8659. + arglist, 0),
  8660. + nios2_extract_double (&insn_data[d->icode],
  8661. + arglist, 1));
  8662. + if (pat)
  8663. + emit_insn (pat);
  8664. + return target;
  8665. +}
  8666. +
  8667. +static rtx
  8668. +nios2_expand_custom_ddz (const struct builtin_description *d,
  8669. + tree exp,
  8670. + rtx target,
  8671. + rtx subtarget ATTRIBUTE_UNUSED,
  8672. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8673. + int ignore ATTRIBUTE_UNUSED)
  8674. +{
  8675. + tree arglist = TREE_OPERAND (exp, 1);
  8676. + rtx pat = GEN_FCN (d->icode) (target,
  8677. + nios2_extract_double (&insn_data[d->icode],
  8678. + arglist, 0));
  8679. + if (pat)
  8680. + emit_insn (pat);
  8681. + return target;
  8682. +}
  8683. +
  8684. +static rtx
  8685. +nios2_expand_custom_idd (const struct builtin_description *d,
  8686. + tree exp,
  8687. + rtx target,
  8688. + rtx subtarget ATTRIBUTE_UNUSED,
  8689. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8690. + int ignore ATTRIBUTE_UNUSED)
  8691. +{
  8692. + tree arglist = TREE_OPERAND (exp, 1);
  8693. + rtx pat = GEN_FCN (d->icode) (target,
  8694. + nios2_extract_double (&insn_data[d->icode],
  8695. + arglist, 0),
  8696. + nios2_extract_double (&insn_data[d->icode],
  8697. + arglist, 1));
  8698. + if (pat)
  8699. + emit_insn (pat);
  8700. + return target;
  8701. +}
  8702. +
  8703. +static rtx
  8704. +nios2_expand_custom_siz (const struct builtin_description *d,
  8705. + tree exp,
  8706. + rtx target,
  8707. + rtx subtarget ATTRIBUTE_UNUSED,
  8708. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8709. + int ignore ATTRIBUTE_UNUSED)
  8710. +{
  8711. + tree arglist = TREE_OPERAND (exp, 1);
  8712. + rtx pat = GEN_FCN (d->icode) (target,
  8713. + nios2_extract_integer (&insn_data[d->icode],
  8714. + arglist, 0));
  8715. + if (pat)
  8716. + emit_insn (pat);
  8717. + return target;
  8718. +}
  8719. +
  8720. +static rtx
  8721. +nios2_expand_custom_suz (const struct builtin_description *d,
  8722. + tree exp,
  8723. + rtx target,
  8724. + rtx subtarget ATTRIBUTE_UNUSED,
  8725. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8726. + int ignore ATTRIBUTE_UNUSED)
  8727. +{
  8728. + tree arglist = TREE_OPERAND (exp, 1);
  8729. + rtx pat = GEN_FCN (d->icode) (target,
  8730. + nios2_extract_integer (&insn_data[d->icode],
  8731. + arglist, 0));
  8732. + if (pat)
  8733. + emit_insn (pat);
  8734. + return target;
  8735. +}
  8736. +
  8737. +static rtx
  8738. +nios2_expand_custom_diz (const struct builtin_description *d,
  8739. + tree exp,
  8740. + rtx target,
  8741. + rtx subtarget ATTRIBUTE_UNUSED,
  8742. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8743. + int ignore ATTRIBUTE_UNUSED)
  8744. +{
  8745. + tree arglist = TREE_OPERAND (exp, 1);
  8746. + rtx pat = GEN_FCN (d->icode) (target,
  8747. + nios2_extract_integer (&insn_data[d->icode],
  8748. + arglist, 0));
  8749. + if (pat)
  8750. + emit_insn (pat);
  8751. + return target;
  8752. +}
  8753. +
  8754. +static rtx
  8755. +nios2_expand_custom_duz (const struct builtin_description *d,
  8756. + tree exp,
  8757. + rtx target,
  8758. + rtx subtarget ATTRIBUTE_UNUSED,
  8759. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8760. + int ignore ATTRIBUTE_UNUSED)
  8761. +{
  8762. + tree arglist = TREE_OPERAND (exp, 1);
  8763. + rtx pat = GEN_FCN (d->icode) (target,
  8764. + nios2_extract_integer (&insn_data[d->icode],
  8765. + arglist, 0));
  8766. + if (pat)
  8767. + emit_insn (pat);
  8768. + return target;
  8769. +}
  8770. +
  8771. +static rtx
  8772. +nios2_expand_custom_isz (const struct builtin_description *d,
  8773. + tree exp,
  8774. + rtx target,
  8775. + rtx subtarget ATTRIBUTE_UNUSED,
  8776. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8777. + int ignore ATTRIBUTE_UNUSED)
  8778. +{
  8779. + tree arglist = TREE_OPERAND (exp, 1);
  8780. + rtx pat = GEN_FCN (d->icode) (target,
  8781. + nios2_extract_float (&insn_data[d->icode],
  8782. + arglist, 0));
  8783. + if (pat)
  8784. + emit_insn (pat);
  8785. + return target;
  8786. +}
  8787. +
  8788. +static rtx
  8789. +nios2_expand_custom_usz (const struct builtin_description *d,
  8790. + tree exp,
  8791. + rtx target,
  8792. + rtx subtarget ATTRIBUTE_UNUSED,
  8793. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8794. + int ignore ATTRIBUTE_UNUSED)
  8795. +{
  8796. + tree arglist = TREE_OPERAND (exp, 1);
  8797. + rtx pat = GEN_FCN (d->icode) (target,
  8798. + nios2_extract_float (&insn_data[d->icode],
  8799. + arglist, 0));
  8800. + if (pat)
  8801. + emit_insn (pat);
  8802. + return target;
  8803. +}
  8804. +
  8805. +static rtx
  8806. +nios2_expand_custom_idz (const struct builtin_description *d,
  8807. + tree exp,
  8808. + rtx target,
  8809. + rtx subtarget ATTRIBUTE_UNUSED,
  8810. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8811. + int ignore ATTRIBUTE_UNUSED)
  8812. +{
  8813. + tree arglist = TREE_OPERAND (exp, 1);
  8814. + rtx pat = GEN_FCN (d->icode) (target,
  8815. + nios2_extract_double (&insn_data[d->icode],
  8816. + arglist, 0));
  8817. + if (pat)
  8818. + emit_insn (pat);
  8819. + return target;
  8820. +}
  8821. +
  8822. +static rtx
  8823. +nios2_expand_custom_udz (const struct builtin_description *d,
  8824. + tree exp,
  8825. + rtx target,
  8826. + rtx subtarget ATTRIBUTE_UNUSED,
  8827. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8828. + int ignore ATTRIBUTE_UNUSED)
  8829. +{
  8830. + tree arglist = TREE_OPERAND (exp, 1);
  8831. + rtx pat = GEN_FCN (d->icode) (target,
  8832. + nios2_extract_double (&insn_data[d->icode],
  8833. + arglist, 0));
  8834. + if (pat)
  8835. + emit_insn (pat);
  8836. + return target;
  8837. +}
  8838. +
  8839. +static rtx
  8840. +nios2_expand_custom_dsz (const struct builtin_description *d,
  8841. + tree exp,
  8842. + rtx target,
  8843. + rtx subtarget ATTRIBUTE_UNUSED,
  8844. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8845. + int ignore ATTRIBUTE_UNUSED)
  8846. +{
  8847. + tree arglist = TREE_OPERAND (exp, 1);
  8848. + rtx pat = GEN_FCN (d->icode) (target,
  8849. + nios2_extract_float (&insn_data[d->icode],
  8850. + arglist, 0));
  8851. + if (pat)
  8852. + emit_insn (pat);
  8853. + return target;
  8854. +}
  8855. +
  8856. +static rtx
  8857. +nios2_expand_custom_sdz (const struct builtin_description *d,
  8858. + tree exp,
  8859. + rtx target,
  8860. + rtx subtarget ATTRIBUTE_UNUSED,
  8861. + enum machine_mode mode ATTRIBUTE_UNUSED,
  8862. + int ignore ATTRIBUTE_UNUSED)
  8863. +{
  8864. + tree arglist = TREE_OPERAND (exp, 1);
  8865. + rtx pat = GEN_FCN (d->icode) (target,
  8866. + nios2_extract_double (&insn_data[d->icode],
  8867. + arglist, 0));
  8868. + if (pat)
  8869. + emit_insn (pat);
  8870. + return target;
  8871. +}
  8872. +
  8873. +#include "gt-nios2.h"
  8874. +
  8875. diff --git a/gcc/config/nios2/nios2.h b/gcc/config/nios2/nios2.h
  8876. new file mode 100644
  8877. index 0000000..500ccf0
  8878. --- /dev/null
  8879. +++ b/gcc/config/nios2/nios2.h
  8880. @@ -0,0 +1,1130 @@
  8881. +/* Definitions of target machine for Altera NIOS 2G NIOS2 version.
  8882. + Copyright (C) 2005 Altera
  8883. + Contributed by Jonah Graham (jgraham@altera.com) and Will Reece (wreece@altera.com).
  8884. +
  8885. +This file is part of GNU CC.
  8886. +
  8887. +GNU CC is free software; you can redistribute it and/or modify
  8888. +it under the terms of the GNU General Public License as published by
  8889. +the Free Software Foundation; either version 2, or (at your option)
  8890. +any later version.
  8891. +
  8892. +GNU CC is distributed in the hope that it will be useful,
  8893. +but WITHOUT ANY WARRANTY; without even the implied warranty of
  8894. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8895. +GNU General Public License for more details.
  8896. +
  8897. +You should have received a copy of the GNU General Public License
  8898. +along with GNU CC; see the file COPYING. If not, write to
  8899. +the Free Software Foundation, 59 Temple Place - Suite 330,
  8900. +Boston, MA 02111-1307, USA. */
  8901. +
  8902. +
  8903. +
  8904. +#define TARGET_CPU_CPP_BUILTINS() \
  8905. + do \
  8906. + { \
  8907. + builtin_define_std ("NIOS2"); \
  8908. + builtin_define_std ("nios2"); \
  8909. + if (TARGET_BIG_ENDIAN) \
  8910. + builtin_define_std ("nios2_big_endian"); \
  8911. + else \
  8912. + builtin_define_std ("nios2_little_endian"); \
  8913. + } \
  8914. + while (0)
  8915. +#define TARGET_VERSION fprintf (stderr, " (Altera Nios II)")
  8916. +
  8917. +
  8918. +
  8919. +
  8920. +
  8921. +/*********************************
  8922. + * Run-time Target Specification
  8923. + *********************************/
  8924. +
  8925. +#define HAS_DIV_FLAG 0x0001
  8926. +#define HAS_MUL_FLAG 0x0002
  8927. +#define HAS_MULX_FLAG 0x0004
  8928. +#define FAST_SW_DIV_FLAG 0x0008
  8929. +#define INLINE_MEMCPY_FLAG 0x00010
  8930. +#define CACHE_VOLATILE_FLAG 0x0020
  8931. +#define BYPASS_CACHE_FLAG 0x0040
  8932. +#define STACK_CHECK_FLAG 0x0080
  8933. +#define REVERSE_BITFIELDS_FLAG 0x0100
  8934. +/* Reserve 0x0200 for REVERSE_ENDIAN_FLAG */
  8935. +#define BIG_ENDIAN_FLAG 0x0400
  8936. +
  8937. +extern int target_flags;
  8938. +#define TARGET_HAS_DIV (target_flags & HAS_DIV_FLAG)
  8939. +#define TARGET_HAS_MUL (target_flags & HAS_MUL_FLAG)
  8940. +#define TARGET_HAS_MULX (target_flags & HAS_MULX_FLAG)
  8941. +#define TARGET_FAST_SW_DIV (target_flags & FAST_SW_DIV_FLAG)
  8942. +#define TARGET_INLINE_MEMCPY (target_flags & INLINE_MEMCPY_FLAG)
  8943. +#define TARGET_CACHE_VOLATILE (target_flags & CACHE_VOLATILE_FLAG)
  8944. +#define TARGET_BYPASS_CACHE (target_flags & BYPASS_CACHE_FLAG)
  8945. +#define TARGET_STACK_CHECK (target_flags & STACK_CHECK_FLAG)
  8946. +#define TARGET_REVERSE_BITFIELDS (target_flags & REVERSE_BITFIELDS_FLAG)
  8947. +#define TARGET_BIG_ENDIAN (target_flags & BIG_ENDIAN_FLAG)
  8948. +
  8949. +#define TARGET_SWITCHES \
  8950. +{ \
  8951. + { "hw-div", HAS_DIV_FLAG, \
  8952. + N_("Enable DIV, DIVU") }, \
  8953. + { "no-hw-div", -HAS_DIV_FLAG, \
  8954. + N_("Disable DIV, DIVU (default)") }, \
  8955. + { "hw-mul", HAS_MUL_FLAG, \
  8956. + N_("Enable MUL instructions (default)") }, \
  8957. + { "hw-mulx", HAS_MULX_FLAG, \
  8958. + N_("Enable MULX instructions, assume fast shifter") }, \
  8959. + { "no-hw-mul", -HAS_MUL_FLAG, \
  8960. + N_("Disable MUL instructions") }, \
  8961. + { "no-hw-mulx", -HAS_MULX_FLAG, \
  8962. + N_("Disable MULX instructions, assume slow shifter (default and implied by -mno-hw-mul)") }, \
  8963. + { "fast-sw-div", FAST_SW_DIV_FLAG, \
  8964. + N_("Use table based fast divide (default at -O3)") }, \
  8965. + { "no-fast-sw-div", -FAST_SW_DIV_FLAG, \
  8966. + N_("Don't use table based fast divide ever") }, \
  8967. + { "inline-memcpy", INLINE_MEMCPY_FLAG, \
  8968. + N_("Inline small memcpy (default when optimizing)") }, \
  8969. + { "no-inline-memcpy", -INLINE_MEMCPY_FLAG, \
  8970. + N_("Don't Inline small memcpy") }, \
  8971. + { "cache-volatile", CACHE_VOLATILE_FLAG, \
  8972. + N_("Volatile accesses use non-io variants of instructions (default)") }, \
  8973. + { "no-cache-volatile", -CACHE_VOLATILE_FLAG, \
  8974. + N_("Volatile accesses use io variants of instructions") }, \
  8975. + { "bypass-cache", BYPASS_CACHE_FLAG, \
  8976. + N_("All ld/st instructins use io variants") }, \
  8977. + { "no-bypass-cache", -BYPASS_CACHE_FLAG, \
  8978. + N_("All ld/st instructins do not use io variants (default)") }, \
  8979. + { "smallc", 0, \
  8980. + N_("Link with a limited version of the C library") }, \
  8981. + { "ctors-in-init", 0, \
  8982. + "" /* undocumented: N_("Link with static constructors and destructors in init") */ }, \
  8983. + { "stack-check", STACK_CHECK_FLAG, \
  8984. + N_("Enable stack limit checking.") }, \
  8985. + { "no-stack-check", -STACK_CHECK_FLAG, \
  8986. + N_("Disable stack limit checking (default).") }, \
  8987. + { "reverse-bitfields", REVERSE_BITFIELDS_FLAG, \
  8988. + N_("Reverse the order of bitfields in a struct.") }, \
  8989. + { "no-reverse-bitfields", -REVERSE_BITFIELDS_FLAG, \
  8990. + N_("Use the normal order of bitfields in a struct (default).") }, \
  8991. + { "eb", BIG_ENDIAN_FLAG, \
  8992. + N_("Use big-endian byte order") }, \
  8993. + { "el", -BIG_ENDIAN_FLAG, \
  8994. + N_("Use little-endian byte order") }, \
  8995. + { "", TARGET_DEFAULT, 0 } \
  8996. +}
  8997. +
  8998. +extern const char *nios2_sys_nosys_string; /* for -msys=nosys */
  8999. +extern const char *nios2_sys_lib_string; /* for -msys-lib= */
  9000. +extern const char *nios2_sys_crt0_string; /* for -msys-crt0= */
  9001. +
  9002. +/*
  9003. + * There's a lot of error-prone tedium with all the different
  9004. + * custom floating point instructions. Try to automate it a bit
  9005. + * to make it easier to deal with.
  9006. + */
  9007. +#define NIOS2_STRINGIFY_INNER(x) #x
  9008. +#define NIOS2_STRINGIFY(x) NIOS2_STRINGIFY_INNER(x)
  9009. +#define NIOS2_CONCAT_INNER(x, y) x ## y
  9010. +#define NIOS2_CONCAT(x, y) NIOS2_CONCAT_INNER (x, y)
  9011. +
  9012. +#define NIOS2_FOR_ALL_FPU_INSNS \
  9013. + NIOS2_FPU_INSN (fwrx, nios2_fwrx, zdz) \
  9014. + NIOS2_FPU_INSN (fwry, nios2_fwry, zsz) \
  9015. + NIOS2_FPU_INSN (frdxlo, nios2_frdxlo, szz) \
  9016. + NIOS2_FPU_INSN (frdxhi, nios2_frdxhi, szz) \
  9017. + NIOS2_FPU_INSN (frdy, nios2_frdy, szz) \
  9018. +\
  9019. + NIOS2_FPU_INSN (fadds, addsf3, sss) \
  9020. + NIOS2_FPU_INSN (fsubs, subsf3, sss) \
  9021. + NIOS2_FPU_INSN (fmuls, mulsf3, sss) \
  9022. + NIOS2_FPU_INSN (fdivs, divsf3, sss) \
  9023. + NIOS2_FPU_INSN (fmins, minsf3, sss) \
  9024. + NIOS2_FPU_INSN (fmaxs, maxsf3, sss) \
  9025. + NIOS2_FPU_INSN (fnegs, negsf2, ssz) \
  9026. + NIOS2_FPU_INSN (fabss, abssf2, ssz) \
  9027. + NIOS2_FPU_INSN (fsqrts, sqrtsf2, ssz) \
  9028. + NIOS2_FPU_INSN (fcoss, cossf2, ssz) \
  9029. + NIOS2_FPU_INSN (fsins, sinsf2, ssz) \
  9030. + NIOS2_FPU_INSN (ftans, tansf2, ssz) \
  9031. + NIOS2_FPU_INSN (fatans, atansf2, ssz) \
  9032. + NIOS2_FPU_INSN (fexps, expsf2, ssz) \
  9033. + NIOS2_FPU_INSN (flogs, logsf2, ssz) \
  9034. + NIOS2_FPU_INSN (fcmplts, nios2_sltsf, iss) \
  9035. + NIOS2_FPU_INSN (fcmples, nios2_slesf, iss) \
  9036. + NIOS2_FPU_INSN (fcmpgts, nios2_sgtsf, iss) \
  9037. + NIOS2_FPU_INSN (fcmpges, nios2_sgesf, iss) \
  9038. + NIOS2_FPU_INSN (fcmpeqs, nios2_seqsf, iss) \
  9039. + NIOS2_FPU_INSN (fcmpnes, nios2_snesf, iss) \
  9040. +\
  9041. + NIOS2_FPU_INSN (faddd, adddf3, ddd) \
  9042. + NIOS2_FPU_INSN (fsubd, subdf3, ddd) \
  9043. + NIOS2_FPU_INSN (fmuld, muldf3, ddd) \
  9044. + NIOS2_FPU_INSN (fdivd, divdf3, ddd) \
  9045. + NIOS2_FPU_INSN (fmind, mindf3, ddd) \
  9046. + NIOS2_FPU_INSN (fmaxd, maxdf3, ddd) \
  9047. + NIOS2_FPU_INSN (fnegd, negdf2, ddz) \
  9048. + NIOS2_FPU_INSN (fabsd, absdf2, ddz) \
  9049. + NIOS2_FPU_INSN (fsqrtd, sqrtdf2, ddz) \
  9050. + NIOS2_FPU_INSN (fcosd, cosdf2, ddz) \
  9051. + NIOS2_FPU_INSN (fsind, sindf2, ddz) \
  9052. + NIOS2_FPU_INSN (ftand, tandf2, ddz) \
  9053. + NIOS2_FPU_INSN (fatand, atandf2, ddz) \
  9054. + NIOS2_FPU_INSN (fexpd, expdf2, ddz) \
  9055. + NIOS2_FPU_INSN (flogd, logdf2, ddz) \
  9056. + NIOS2_FPU_INSN (fcmpltd, nios2_sltdf, idd) \
  9057. + NIOS2_FPU_INSN (fcmpled, nios2_sledf, idd) \
  9058. + NIOS2_FPU_INSN (fcmpgtd, nios2_sgtdf, idd) \
  9059. + NIOS2_FPU_INSN (fcmpged, nios2_sgedf, idd) \
  9060. + NIOS2_FPU_INSN (fcmpeqd, nios2_seqdf, idd) \
  9061. + NIOS2_FPU_INSN (fcmpned, nios2_snedf, idd) \
  9062. +\
  9063. + NIOS2_FPU_INSN (floatis, floatsisf2, siz) \
  9064. + NIOS2_FPU_INSN (floatus, floatunssisf2, suz) \
  9065. + NIOS2_FPU_INSN (floatid, floatsidf2, diz) \
  9066. + NIOS2_FPU_INSN (floatud, floatunssidf2, duz) \
  9067. + NIOS2_FPU_INSN (fixsi, fixsfsi2, isz) \
  9068. + NIOS2_FPU_INSN (fixsu, fixunssfsi2, usz) \
  9069. + NIOS2_FPU_INSN (fixdi, fixdfsi2, idz) \
  9070. + NIOS2_FPU_INSN (fixdu, fixunsdfsi2, udz) \
  9071. + NIOS2_FPU_INSN (fextsd, extendsfdf2, dsz) \
  9072. + NIOS2_FPU_INSN (ftruncds, truncdfsf2, sdz)
  9073. +
  9074. +enum
  9075. +{
  9076. +#define NIOS2_FPU_INSN(opt, insn, args) \
  9077. + NIOS2_CONCAT (nios2_fpu_, insn),
  9078. +NIOS2_FOR_ALL_FPU_INSNS
  9079. + nios2_fpu_max_insn
  9080. +};
  9081. +
  9082. +struct cpp_reader;
  9083. +typedef const char * (*nios2_outputfn) (rtx);
  9084. +typedef void (*nios2_pragmafn) (struct cpp_reader *);
  9085. +
  9086. +typedef struct
  9087. +{
  9088. + const char *option; /* name of switch, e.g. fadds */
  9089. + const char *insnnm; /* name of gcc insn, e.g. addsf3 */
  9090. + const char *args; /* args to gcc insn, e.g. sss */
  9091. + const char *value; /* value of switch as a string */
  9092. + int N; /* value of switch as an integer, -1 = not used */
  9093. + nios2_outputfn output; /* output function for use in .md file */
  9094. + const char *pname; /* name of corresponding #pragma custom- */
  9095. + nios2_pragmafn pragma; /* pragma function for register_target_pragmas */
  9096. + const char *nopname; /* name of corresponding #pragma no-custom- */
  9097. + nios2_pragmafn nopragma; /* pragma function for register_target_pragmas */
  9098. + int is_double; /* does this insn have any double operands */
  9099. + int needed_by_double; /* is this insn needed if doubles are used? */
  9100. + int needs_unsafe; /* does this insn require
  9101. + -funsafe-math-optimizations to work? */
  9102. + int needs_finite; /* does this insn require
  9103. + -ffinite-math-only to work? */
  9104. + int pragma_seen; /* have we seen the corresponding #pragma? */
  9105. +} nios2_fpu_info;
  9106. +
  9107. +extern nios2_fpu_info nios2_fpu_insns[nios2_fpu_max_insn];
  9108. +extern const char *nios2_custom_fpu_cfg_string;
  9109. +
  9110. +#undef NIOS2_FPU_INSN
  9111. +#define NIOS2_FPU_INSN(opt, insn, args) \
  9112. + { \
  9113. + "custom-" NIOS2_STRINGIFY (opt) "=", \
  9114. + &(nios2_fpu_insns[NIOS2_CONCAT (nios2_fpu_, insn)].value), \
  9115. + N_("Integer id (N) of " NIOS2_STRINGIFY (opt) " custom instruction"), \
  9116. + 0 \
  9117. + }, \
  9118. + { \
  9119. + "no-custom-" NIOS2_STRINGIFY (opt), \
  9120. + &(nios2_fpu_insns[NIOS2_CONCAT (nios2_fpu_, insn)].value), \
  9121. + N_("Do not use the " NIOS2_STRINGIFY (opt) " custom instruction"), \
  9122. + "-1" \
  9123. + },
  9124. +
  9125. +#define TARGET_OPTIONS \
  9126. +{ \
  9127. + { "sys=nosys", &nios2_sys_nosys_string, \
  9128. + N_("Use stub versions of OS library calls (default)"), 0}, \
  9129. + { "sys-lib=", &nios2_sys_lib_string, \
  9130. + N_("Name of System Library to link against. (Converted to a -l option)"), 0}, \
  9131. + { "sys-crt0=", &nios2_sys_crt0_string, \
  9132. + N_("Name of the startfile. (default is a crt0 for the ISS only)"), 0}, \
  9133. + NIOS2_FOR_ALL_FPU_INSNS \
  9134. + { "custom-fpu-cfg=", &nios2_custom_fpu_cfg_string, \
  9135. + N_("Floating point custom instruction configuration name"), 0 }, \
  9136. +}
  9137. +
  9138. +/* We're little endian, unless otherwise specified by including big.h */
  9139. +#ifndef TARGET_ENDIAN_DEFAULT
  9140. +# define TARGET_ENDIAN_DEFAULT 0
  9141. +#endif
  9142. +
  9143. +/* Default target_flags if no switches specified. */
  9144. +#ifndef TARGET_DEFAULT
  9145. +# define TARGET_DEFAULT (HAS_MUL_FLAG | CACHE_VOLATILE_FLAG | TARGET_ENDIAN_DEFAULT)
  9146. +#endif
  9147. +
  9148. +/* Switch Recognition by gcc.c. Add -G xx support */
  9149. +#undef SWITCH_TAKES_ARG
  9150. +#define SWITCH_TAKES_ARG(CHAR) \
  9151. + (DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G')
  9152. +
  9153. +#define OVERRIDE_OPTIONS override_options ()
  9154. +#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) optimization_options (LEVEL, SIZE)
  9155. +#define CAN_DEBUG_WITHOUT_FP
  9156. +
  9157. +#define CC1_SPEC "\
  9158. +%{G*} %{EB:-meb} %{EL:-mel} %{EB:%{EL:%emay not use both -EB and -EL}}"
  9159. +
  9160. +#if TARGET_ENDIAN_DEFAULT == 0
  9161. +# define ASM_SPEC "\
  9162. +%{!EB:%{!meb:-EL}} %{EB|meb:-EB}"
  9163. +# define LINK_SPEC "\
  9164. +%{!EB:%{!meb:-EL}} %{EB|meb:-EB}"
  9165. +# define MULTILIB_DEFAULTS { "EL" }
  9166. +#else
  9167. +# define ASM_SPEC "\
  9168. +%{!EL:%{!mel:-EB}} %{EL|mel:-EL}"
  9169. +# define LINK_SPEC "\
  9170. +%{!EL:%{!mel:-EB}} %{EL|mel:-EL}"
  9171. +# define MULTILIB_DEFAULTS { "EB" }
  9172. +#endif
  9173. +
  9174. +#undef LIB_SPEC
  9175. +#define LIB_SPEC \
  9176. +"--start-group %{msmallc: -lsmallc} %{!msmallc: -lc} -lgcc \
  9177. + %{msys-lib=*: -l%*} \
  9178. + %{!msys-lib=*: -lnosys -lstack} \
  9179. + --end-group \
  9180. + %{msys-lib=: %eYou need a library name for -msys-lib=} \
  9181. +"
  9182. +
  9183. +
  9184. +#undef STARTFILE_SPEC
  9185. +#define STARTFILE_SPEC \
  9186. +"%{msys-crt0=*: %*} %{!msys-crt0=*: crt0%O%s} \
  9187. + %{msys-crt0=: %eYou need a C startup file for -msys-crt0=} \
  9188. + %{mctors-in-init: crti%O%s crtbegin%O%s} \
  9189. +"
  9190. +
  9191. +#undef ENDFILE_SPEC
  9192. +#define ENDFILE_SPEC \
  9193. + "%{mctors-in-init: crtend%O%s crtn%O%s}"
  9194. +
  9195. +
  9196. +/***********************
  9197. + * Storage Layout
  9198. + ***********************/
  9199. +
  9200. +#define DEFAULT_SIGNED_CHAR 1
  9201. +#define BITS_BIG_ENDIAN 0
  9202. +#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0)
  9203. +#define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0)
  9204. +#if defined(__nios2_big_endian__)
  9205. +#define LIBGCC2_WORDS_BIG_ENDIAN 1
  9206. +#else
  9207. +#define LIBGCC2_WORDS_BIG_ENDIAN 0
  9208. +#endif
  9209. +#define BITS_PER_UNIT 8
  9210. +#define BITS_PER_WORD 32
  9211. +#define UNITS_PER_WORD 4
  9212. +#define POINTER_SIZE 32
  9213. +#define BIGGEST_ALIGNMENT 32
  9214. +#define STRICT_ALIGNMENT 1
  9215. +#define FUNCTION_BOUNDARY 32
  9216. +#define PARM_BOUNDARY 32
  9217. +#define STACK_BOUNDARY 32
  9218. +#define PREFERRED_STACK_BOUNDARY 32
  9219. +#define MAX_FIXED_MODE_SIZE 64
  9220. +
  9221. +#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
  9222. + ((TREE_CODE (EXP) == STRING_CST) \
  9223. + && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  9224. +
  9225. +
  9226. +/**********************
  9227. + * Layout of Source Language Data Types
  9228. + **********************/
  9229. +
  9230. +#define INT_TYPE_SIZE 32
  9231. +#define SHORT_TYPE_SIZE 16
  9232. +#define LONG_TYPE_SIZE 32
  9233. +#define LONG_LONG_TYPE_SIZE 64
  9234. +#define FLOAT_TYPE_SIZE 32
  9235. +#define DOUBLE_TYPE_SIZE 64
  9236. +#define LONG_DOUBLE_TYPE_SIZE DOUBLE_TYPE_SIZE
  9237. +
  9238. +
  9239. +/*************************
  9240. + * Condition Code Status
  9241. + ************************/
  9242. +
  9243. +/* comparison type */
  9244. +/* ??? Currently CMP_DI is unused. CMP_SF and CMP_DF are only used if
  9245. + the corresponding -mcustom-<opcode> switches are present. */
  9246. +enum cmp_type {
  9247. + CMP_SI, /* compare four byte integers */
  9248. + CMP_DI, /* compare eight byte integers */
  9249. + CMP_SF, /* compare single precision floats */
  9250. + CMP_DF, /* compare double precision floats */
  9251. + CMP_MAX /* max comparison type */
  9252. +};
  9253. +
  9254. +extern GTY(()) rtx branch_cmp[2]; /* operands for compare */
  9255. +extern enum cmp_type branch_type; /* what type of branch to use */
  9256. +
  9257. +/**********************
  9258. + * Register Usage
  9259. + **********************/
  9260. +
  9261. +/* ---------------------------------- *
  9262. + * Basic Characteristics of Registers
  9263. + * ---------------------------------- */
  9264. +
  9265. +/*
  9266. +Register Number
  9267. + Register Name
  9268. + Alternate Name
  9269. + Purpose
  9270. +0 r0 zero always zero
  9271. +1 r1 at Assembler Temporary
  9272. +2-3 r2-r3 Return Location
  9273. +4-7 r4-r7 Register Arguments
  9274. +8-15 r8-r15 Caller Saved Registers
  9275. +16-22 r16-r22 Callee Saved Registers
  9276. +23 r23 sc Static Chain (Callee Saved)
  9277. + ??? Does $sc want to be caller or callee
  9278. + saved. If caller, 15, else 23.
  9279. +24 r24 et Exception Temporary
  9280. +25 r25 bt Breakpoint Temporary
  9281. +26 r26 gp Global Pointer
  9282. +27 r27 sp Stack Pointer
  9283. +28 r28 fp Frame Pointer
  9284. +29 r29 ea Exception Return Address
  9285. +30 r30 ba Breakpoint Return Address
  9286. +31 r31 ra Return Address
  9287. +
  9288. +32 ctl0 status
  9289. +33 ctl1 estatus STATUS saved by exception ?
  9290. +34 ctl2 bstatus STATUS saved by break ?
  9291. +35 ctl3 ipri Interrupt Priority Mask ?
  9292. +36 ctl4 ecause Exception Cause ?
  9293. +
  9294. +37 pc Not an actual register
  9295. +
  9296. +38 rap Return address pointer, this does not
  9297. + actually exist and will be eliminated
  9298. +
  9299. +39 fake_fp Fake Frame Pointer which will always be eliminated.
  9300. +40 fake_ap Fake Argument Pointer which will always be eliminated.
  9301. +
  9302. +41 First Pseudo Register
  9303. +
  9304. +
  9305. +The definitions for all the hard register numbers
  9306. +are located in nios2.md.
  9307. +*/
  9308. +
  9309. +#define FIRST_PSEUDO_REGISTER 41
  9310. +#define NUM_ARG_REGS (LAST_ARG_REGNO - FIRST_ARG_REGNO + 1)
  9311. +
  9312. +
  9313. +
  9314. +/* also see CONDITIONAL_REGISTER_USAGE */
  9315. +#define FIXED_REGISTERS \
  9316. + { \
  9317. +/* +0 1 2 3 4 5 6 7 8 9 */ \
  9318. +/* 0 */ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, \
  9319. +/* 10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
  9320. +/* 20 */ 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
  9321. +/* 30 */ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
  9322. +/* 40 */ 1 \
  9323. + }
  9324. +
  9325. +/* call used is the same as caller saved
  9326. + + fixed regs + args + ret vals */
  9327. +#define CALL_USED_REGISTERS \
  9328. + { \
  9329. +/* +0 1 2 3 4 5 6 7 8 9 */ \
  9330. +/* 0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
  9331. +/* 10 */ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, \
  9332. +/* 20 */ 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
  9333. +/* 30 */ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
  9334. +/* 40 */ 1 \
  9335. + }
  9336. +
  9337. +#define HARD_REGNO_NREGS(REGNO, MODE) \
  9338. + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
  9339. + / UNITS_PER_WORD)
  9340. +
  9341. +/* --------------------------- *
  9342. + * How Values Fit in Registers
  9343. + * --------------------------- */
  9344. +
  9345. +#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
  9346. +
  9347. +#define MODES_TIEABLE_P(MODE1, MODE2) 1
  9348. +
  9349. +
  9350. +/*************************
  9351. + * Register Classes
  9352. + *************************/
  9353. +
  9354. +enum reg_class
  9355. +{
  9356. + NO_REGS,
  9357. + D00_REG,
  9358. + D01_REG,
  9359. + D02_REG,
  9360. + D03_REG,
  9361. + D04_REG,
  9362. + D05_REG,
  9363. + D06_REG,
  9364. + D07_REG,
  9365. + D08_REG,
  9366. + D09_REG,
  9367. + D10_REG,
  9368. + D11_REG,
  9369. + D12_REG,
  9370. + D13_REG,
  9371. + D14_REG,
  9372. + D15_REG,
  9373. + D16_REG,
  9374. + D17_REG,
  9375. + D18_REG,
  9376. + D19_REG,
  9377. + D20_REG,
  9378. + D21_REG,
  9379. + D22_REG,
  9380. + D23_REG,
  9381. + D24_REG,
  9382. + D25_REG,
  9383. + D26_REG,
  9384. + D27_REG,
  9385. + D28_REG,
  9386. + D29_REG,
  9387. + D30_REG,
  9388. + D31_REG,
  9389. + GP_REGS,
  9390. + ALL_REGS,
  9391. + LIM_REG_CLASSES
  9392. +};
  9393. +
  9394. +#define N_REG_CLASSES (int) LIM_REG_CLASSES
  9395. +
  9396. +#define REG_CLASS_NAMES \
  9397. + {"NO_REGS", \
  9398. + "D00_REG", \
  9399. + "D01_REG", \
  9400. + "D02_REG", \
  9401. + "D03_REG", \
  9402. + "D04_REG", \
  9403. + "D05_REG", \
  9404. + "D06_REG", \
  9405. + "D07_REG", \
  9406. + "D08_REG", \
  9407. + "D09_REG", \
  9408. + "D10_REG", \
  9409. + "D11_REG", \
  9410. + "D12_REG", \
  9411. + "D13_REG", \
  9412. + "D14_REG", \
  9413. + "D15_REG", \
  9414. + "D16_REG", \
  9415. + "D17_REG", \
  9416. + "D18_REG", \
  9417. + "D19_REG", \
  9418. + "D20_REG", \
  9419. + "D21_REG", \
  9420. + "D22_REG", \
  9421. + "D23_REG", \
  9422. + "D24_REG", \
  9423. + "D25_REG", \
  9424. + "D26_REG", \
  9425. + "D27_REG", \
  9426. + "D28_REG", \
  9427. + "D29_REG", \
  9428. + "D30_REG", \
  9429. + "D31_REG", \
  9430. + "GP_REGS", \
  9431. + "ALL_REGS"}
  9432. +
  9433. +#define GENERAL_REGS ALL_REGS
  9434. +
  9435. +#define REG_CLASS_CONTENTS \
  9436. +/* NO_REGS */ {{ 0, 0}, \
  9437. +/* D00_REG */ { 1 << 0, 0}, \
  9438. +/* D01_REG */ { 1 << 1, 0}, \
  9439. +/* D02_REG */ { 1 << 2, 0}, \
  9440. +/* D03_REG */ { 1 << 3, 0}, \
  9441. +/* D04_REG */ { 1 << 4, 0}, \
  9442. +/* D05_REG */ { 1 << 5, 0}, \
  9443. +/* D06_REG */ { 1 << 6, 0}, \
  9444. +/* D07_REG */ { 1 << 7, 0}, \
  9445. +/* D08_REG */ { 1 << 8, 0}, \
  9446. +/* D09_REG */ { 1 << 9, 0}, \
  9447. +/* D10_REG */ { 1 << 10, 0}, \
  9448. +/* D11_REG */ { 1 << 11, 0}, \
  9449. +/* D12_REG */ { 1 << 12, 0}, \
  9450. +/* D13_REG */ { 1 << 13, 0}, \
  9451. +/* D14_REG */ { 1 << 14, 0}, \
  9452. +/* D15_REG */ { 1 << 15, 0}, \
  9453. +/* D16_REG */ { 1 << 16, 0}, \
  9454. +/* D17_REG */ { 1 << 17, 0}, \
  9455. +/* D18_REG */ { 1 << 18, 0}, \
  9456. +/* D19_REG */ { 1 << 19, 0}, \
  9457. +/* D20_REG */ { 1 << 20, 0}, \
  9458. +/* D21_REG */ { 1 << 21, 0}, \
  9459. +/* D22_REG */ { 1 << 22, 0}, \
  9460. +/* D23_REG */ { 1 << 23, 0}, \
  9461. +/* D24_REG */ { 1 << 24, 0}, \
  9462. +/* D25_REG */ { 1 << 25, 0}, \
  9463. +/* D26_REG */ { 1 << 26, 0}, \
  9464. +/* D27_REG */ { 1 << 27, 0}, \
  9465. +/* D28_REG */ { 1 << 28, 0}, \
  9466. +/* D29_REG */ { 1 << 29, 0}, \
  9467. +/* D30_REG */ { 1 << 30, 0}, \
  9468. +/* D31_REG */ { 1 << 31, 0}, \
  9469. +/* GP_REGS */ {~0, 0}, \
  9470. +/* ALL_REGS */ {~0,~0}} \
  9471. +
  9472. +#define REGNO_REG_CLASS(REGNO) ((REGNO) <= 31 ? GP_REGS : ALL_REGS)
  9473. +
  9474. +#define BASE_REG_CLASS ALL_REGS
  9475. +#define INDEX_REG_CLASS ALL_REGS
  9476. +
  9477. +/* 'r', is handled automatically */
  9478. +#define REG_CLASS_FROM_CONSTRAINT(CHAR, STR) \
  9479. + reg_class_from_constraint ((CHAR), (STR))
  9480. +
  9481. +
  9482. +#define REGNO_OK_FOR_BASE_P2(REGNO, STRICT) \
  9483. + ((STRICT) \
  9484. + ? (REGNO) < FIRST_PSEUDO_REGISTER \
  9485. + : (REGNO) < FIRST_PSEUDO_REGISTER || (reg_renumber && reg_renumber[REGNO] < FIRST_PSEUDO_REGISTER))
  9486. +
  9487. +#define REGNO_OK_FOR_INDEX_P2(REGNO, STRICT) \
  9488. + (REGNO_OK_FOR_BASE_P2 (REGNO, STRICT))
  9489. +
  9490. +#define REGNO_OK_FOR_BASE_P(REGNO) \
  9491. + (REGNO_OK_FOR_BASE_P2 (REGNO, 1))
  9492. +
  9493. +#define REGNO_OK_FOR_INDEX_P(REGNO) \
  9494. + (REGNO_OK_FOR_INDEX_P2 (REGNO, 1))
  9495. +
  9496. +#define REG_OK_FOR_BASE_P2(X, STRICT) \
  9497. + (STRICT \
  9498. + ? REGNO_OK_FOR_BASE_P2 (REGNO (X), 1) \
  9499. + : REGNO_OK_FOR_BASE_P2 (REGNO (X), 1) || REGNO(X) >= FIRST_PSEUDO_REGISTER)
  9500. +
  9501. +#define REG_OK_FOR_INDEX_P2(X, STRICT) \
  9502. + (STRICT \
  9503. + ? REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1) \
  9504. + : REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1) || REGNO(X) >= FIRST_PSEUDO_REGISTER)
  9505. +
  9506. +#define CLASS_MAX_NREGS(CLASS, MODE) \
  9507. + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
  9508. + / UNITS_PER_WORD)
  9509. +
  9510. +
  9511. +#define SMALL_INT(X) ((unsigned HOST_WIDE_INT) ((X) + 0x8000) < 0x10000)
  9512. +#define SMALL_INT_UNSIGNED(X) ((unsigned HOST_WIDE_INT) (X) < 0x10000)
  9513. +#define UPPER16_INT(X) (((X) & 0xffff) == 0)
  9514. +#define SHIFT_INT(X) ((X) >= 0 && (X) <= 31)
  9515. +#define RDWRCTL_INT(X) ((X) >= 0 && (X) <= 31)
  9516. +#define CUSTOM_INSN_OPCODE(X) ((X) >= 0 && (X) <= 255)
  9517. +
  9518. +#define CONST_OK_FOR_LETTER_P(VALUE, C) \
  9519. + ( \
  9520. + (C) == 'I' ? SMALL_INT (VALUE) : \
  9521. + (C) == 'J' ? SMALL_INT_UNSIGNED (VALUE) : \
  9522. + (C) == 'K' ? UPPER16_INT (VALUE) : \
  9523. + (C) == 'L' ? SHIFT_INT (VALUE) : \
  9524. + (C) == 'M' ? (VALUE) == 0 : \
  9525. + (C) == 'N' ? CUSTOM_INSN_OPCODE (VALUE) : \
  9526. + (C) == 'O' ? RDWRCTL_INT (VALUE) : \
  9527. + 0)
  9528. +
  9529. +#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
  9530. +
  9531. +#define PREFERRED_RELOAD_CLASS(X, CLASS) \
  9532. + ((CLASS) == NO_REGS ? GENERAL_REGS : (CLASS))
  9533. +
  9534. +#define CONSTRAINT_LEN(C, STR) \
  9535. + ((C) == 'D' ? 3 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
  9536. +
  9537. +/* 'S' matches immediates which are in small data
  9538. + and therefore can be added to gp to create a
  9539. + 32-bit value. */
  9540. +#define EXTRA_CONSTRAINT(VALUE, C) \
  9541. + ((C) == 'S' \
  9542. + && (GET_CODE (VALUE) == SYMBOL_REF) \
  9543. + && SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (VALUE))
  9544. +
  9545. +
  9546. +
  9547. +
  9548. +/* Say that the epilogue uses the return address register. Note that
  9549. + in the case of sibcalls, the values "used by the epilogue" are
  9550. + considered live at the start of the called function. */
  9551. +#define EPILOGUE_USES(REGNO) ((REGNO) == RA_REGNO)
  9552. +
  9553. +
  9554. +#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node)
  9555. +
  9556. +/**********************************
  9557. + * Trampolines for Nested Functions
  9558. + ***********************************/
  9559. +
  9560. +#define TRAMPOLINE_TEMPLATE(FILE) \
  9561. + error ("trampolines not yet implemented")
  9562. +#define TRAMPOLINE_SIZE 20
  9563. +#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
  9564. + error ("trampolines not yet implemented")
  9565. +
  9566. +/***************************
  9567. + * Stack Layout and Calling Conventions
  9568. + ***************************/
  9569. +
  9570. +/* ------------------ *
  9571. + * Basic Stack Layout
  9572. + * ------------------ */
  9573. +
  9574. +/* The downward variants are used by the compiler,
  9575. + the upward ones serve as documentation */
  9576. +#define STACK_GROWS_DOWNWARD
  9577. +#define FRAME_GROWS_UPWARD
  9578. +#define ARGS_GROW_UPWARD
  9579. +
  9580. +#define STARTING_FRAME_OFFSET current_function_outgoing_args_size
  9581. +#define FIRST_PARM_OFFSET(FUNDECL) 0
  9582. +
  9583. +/* Before the prologue, RA lives in r31. */
  9584. +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, RA_REGNO)
  9585. +
  9586. +/* -------------------------------------- *
  9587. + * Registers That Address the Stack Frame
  9588. + * -------------------------------------- */
  9589. +
  9590. +#define STACK_POINTER_REGNUM SP_REGNO
  9591. +#define STATIC_CHAIN_REGNUM SC_REGNO
  9592. +#define PC_REGNUM PC_REGNO
  9593. +#define DWARF_FRAME_RETURN_COLUMN RA_REGNO
  9594. +
  9595. +/* Base register for access to local variables of the function. We
  9596. + pretend that the frame pointer is a non-existent hard register, and
  9597. + then eliminate it to HARD_FRAME_POINTER_REGNUM. */
  9598. +#define FRAME_POINTER_REGNUM FAKE_FP_REGNO
  9599. +
  9600. +#define HARD_FRAME_POINTER_REGNUM FP_REGNO
  9601. +#define RETURN_ADDRESS_POINTER_REGNUM RAP_REGNO
  9602. +/* the argumnet pointer needs to always be eliminated
  9603. + so it is set to a fake hard register. */
  9604. +#define ARG_POINTER_REGNUM FAKE_AP_REGNO
  9605. +
  9606. +/* ----------------------------------------- *
  9607. + * Eliminating Frame Pointer and Arg Pointer
  9608. + * ----------------------------------------- */
  9609. +
  9610. +#define FRAME_POINTER_REQUIRED 0
  9611. +
  9612. +#define ELIMINABLE_REGS \
  9613. +{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
  9614. + { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
  9615. + { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
  9616. + { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
  9617. + { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
  9618. + { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
  9619. +
  9620. +#define CAN_ELIMINATE(FROM, TO) 1
  9621. +
  9622. +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
  9623. + (OFFSET) = nios2_initial_elimination_offset ((FROM), (TO))
  9624. +
  9625. +#define MUST_SAVE_REGISTER(regno) \
  9626. + ((regs_ever_live[regno] && !call_used_regs[regno]) \
  9627. + || (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) \
  9628. + || (regno == RA_REGNO && regs_ever_live[RA_REGNO]))
  9629. +
  9630. +/* Treat LOC as a byte offset from the stack pointer and round it up
  9631. + to the next fully-aligned offset. */
  9632. +#define STACK_ALIGN(LOC) \
  9633. + (((LOC) + ((PREFERRED_STACK_BOUNDARY / 8) - 1)) & ~((PREFERRED_STACK_BOUNDARY / 8) - 1))
  9634. +
  9635. +
  9636. +/* ------------------------------ *
  9637. + * Passing Arguments in Registers
  9638. + * ------------------------------ */
  9639. +
  9640. +/* see nios2.c */
  9641. +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
  9642. + (function_arg (&CUM, MODE, TYPE, NAMED))
  9643. +
  9644. +#define MUST_PASS_IN_STACK(MODE, TYPE) \
  9645. + nios2_must_pass_in_stack ((MODE), (TYPE))
  9646. +
  9647. +#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
  9648. + (function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED))
  9649. +
  9650. +#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0
  9651. +
  9652. +#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 0
  9653. +
  9654. +typedef struct nios2_args
  9655. +{
  9656. + int regs_used;
  9657. +} CUMULATIVE_ARGS;
  9658. +
  9659. +/* This is to initialize the above unused CUM data type */
  9660. +#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
  9661. + (init_cumulative_args (&CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS))
  9662. +
  9663. +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
  9664. + (function_arg_advance (&CUM, MODE, TYPE, NAMED))
  9665. +
  9666. +#define FUNCTION_ARG_PADDING(MODE, TYPE) \
  9667. + (nios2_function_arg_padding_upward ((MODE), (TYPE)) ? upward : downward)
  9668. +
  9669. +#define PAD_VARARGS_DOWN \
  9670. + (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
  9671. +
  9672. +#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
  9673. + (nios2_block_reg_padding_upward ((MODE), (TYPE), (FIRST)) ? upward : downward)
  9674. +
  9675. +#define FUNCTION_ARG_REGNO_P(REGNO) \
  9676. + ((REGNO) >= FIRST_ARG_REGNO && (REGNO) <= LAST_ARG_REGNO)
  9677. +
  9678. +#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
  9679. + { \
  9680. + int pret_size = nios2_setup_incoming_varargs (&(CUM), (MODE), \
  9681. + (TYPE), (NO_RTL)); \
  9682. + if (pret_size) \
  9683. + (PRETEND_SIZE) = pret_size; \
  9684. + }
  9685. +
  9686. +/* ----------------------------- *
  9687. + * Generating Code for Profiling
  9688. + * ----------------------------- */
  9689. +
  9690. +
  9691. +#define PROFILE_BEFORE_PROLOGUE
  9692. +#define NO_PROFILE_COUNTERS 1
  9693. +#define FUNCTION_PROFILER(FILE, LABELNO) \
  9694. + function_profiler ((FILE), (LABELNO))
  9695. +
  9696. +/* --------------------------------------- *
  9697. + * Passing Function Arguments on the Stack
  9698. + * --------------------------------------- */
  9699. +
  9700. +#define PROMOTE_PROTOTYPES 1
  9701. +
  9702. +#define PUSH_ARGS 0
  9703. +#define ACCUMULATE_OUTGOING_ARGS 1
  9704. +
  9705. +#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACKSIZE) 0
  9706. +
  9707. +/* --------------------------------------- *
  9708. + * How Scalar Function Values Are Returned
  9709. + * --------------------------------------- */
  9710. +
  9711. +#define FUNCTION_VALUE(VALTYPE, FUNC) \
  9712. + gen_rtx(REG, TYPE_MODE(VALTYPE), FIRST_RETVAL_REGNO)
  9713. +
  9714. +#define LIBCALL_VALUE(MODE) \
  9715. + gen_rtx(REG, MODE, FIRST_RETVAL_REGNO)
  9716. +
  9717. +#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == FIRST_RETVAL_REGNO)
  9718. +
  9719. +/* ----------------------------- *
  9720. + * How Large Values Are Returned
  9721. + * ----------------------------- */
  9722. +
  9723. +
  9724. +#define RETURN_IN_MEMORY(TYPE) \
  9725. + nios2_return_in_memory (TYPE)
  9726. +
  9727. +
  9728. +#define STRUCT_VALUE 0
  9729. +
  9730. +#define DEFAULT_PCC_STRUCT_RETURN 0
  9731. +
  9732. +/*******************
  9733. + * Addressing Modes
  9734. + *******************/
  9735. +
  9736. +
  9737. +#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)
  9738. +
  9739. +#define CONSTANT_ADDRESS_P(X) (CONSTANT_P (X))
  9740. +
  9741. +#define MAX_REGS_PER_ADDRESS 1
  9742. +
  9743. +/* Go to ADDR if X is a valid address. */
  9744. +#ifndef REG_OK_STRICT
  9745. +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
  9746. + { \
  9747. + if (nios2_legitimate_address ((X), (MODE), 0)) \
  9748. + goto ADDR; \
  9749. + }
  9750. +#else
  9751. +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
  9752. + { \
  9753. + if (nios2_legitimate_address ((X), (MODE), 1)) \
  9754. + goto ADDR; \
  9755. + }
  9756. +#endif
  9757. +
  9758. +#ifndef REG_OK_STRICT
  9759. +#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P2 (REGNO (X), 0)
  9760. +#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P2 (REGNO (X), 0)
  9761. +#else
  9762. +#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P2 (REGNO (X), 1)
  9763. +#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1)
  9764. +#endif
  9765. +
  9766. +#define LEGITIMATE_CONSTANT_P(X) 1
  9767. +
  9768. +/* Nios II has no mode dependent addresses. */
  9769. +#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
  9770. +
  9771. +/* Set if this has a weak declaration */
  9772. +#define SYMBOL_FLAG_WEAK_DECL (1 << SYMBOL_FLAG_MACH_DEP_SHIFT)
  9773. +#define SYMBOL_REF_WEAK_DECL_P(RTX) \
  9774. + ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_WEAK_DECL) != 0)
  9775. +
  9776. +
  9777. +/* true if a symbol is both small and not weak. In this case, gp
  9778. + relative access can be used */
  9779. +#define SYMBOL_REF_IN_NIOS2_SMALL_DATA_P(RTX) \
  9780. + (SYMBOL_REF_SMALL_P(RTX) && !SYMBOL_REF_WEAK_DECL_P(RTX))
  9781. +
  9782. +/*****************
  9783. + * Describing Relative Costs of Operations
  9784. + *****************/
  9785. +
  9786. +#define SLOW_BYTE_ACCESS 1
  9787. +
  9788. +/* It is as good to call a constant function address as to call an address
  9789. + kept in a register.
  9790. + ??? Not true anymore really. Now that call cannot address full range
  9791. + of memory callr may need to be used */
  9792. +
  9793. +#define NO_FUNCTION_CSE
  9794. +#define NO_RECURSIVE_FUNCTION_CSE
  9795. +
  9796. +
  9797. +
  9798. +/*****************************************
  9799. + * Defining the Output Assembler Language
  9800. + *****************************************/
  9801. +
  9802. +/* ------------------------------------------ *
  9803. + * The Overall Framework of an Assembler File
  9804. + * ------------------------------------------ */
  9805. +
  9806. +#define ASM_APP_ON "#APP\n"
  9807. +#define ASM_APP_OFF "#NO_APP\n"
  9808. +
  9809. +#define ASM_COMMENT_START "# "
  9810. +
  9811. +/* ------------------------------- *
  9812. + * Output and Generation of Labels
  9813. + * ------------------------------- */
  9814. +
  9815. +#define GLOBAL_ASM_OP "\t.global\t"
  9816. +
  9817. +
  9818. +/* -------------- *
  9819. + * Output of Data
  9820. + * -------------- */
  9821. +
  9822. +#define DWARF2_UNWIND_INFO 0
  9823. +
  9824. +
  9825. +/* -------------------------------- *
  9826. + * Assembler Commands for Alignment
  9827. + * -------------------------------- */
  9828. +
  9829. +#define ASM_OUTPUT_ALIGN(FILE, LOG) \
  9830. + do { \
  9831. + fprintf ((FILE), "%s%d\n", ALIGN_ASM_OP, (LOG)); \
  9832. + } while (0)
  9833. +
  9834. +
  9835. +/* -------------------------------- *
  9836. + * Output of Assembler Instructions
  9837. + * -------------------------------- */
  9838. +
  9839. +#define REGISTER_NAMES \
  9840. +{ \
  9841. + "zero", \
  9842. + "at", \
  9843. + "r2", \
  9844. + "r3", \
  9845. + "r4", \
  9846. + "r5", \
  9847. + "r6", \
  9848. + "r7", \
  9849. + "r8", \
  9850. + "r9", \
  9851. + "r10", \
  9852. + "r11", \
  9853. + "r12", \
  9854. + "r13", \
  9855. + "r14", \
  9856. + "r15", \
  9857. + "r16", \
  9858. + "r17", \
  9859. + "r18", \
  9860. + "r19", \
  9861. + "r20", \
  9862. + "r21", \
  9863. + "r22", \
  9864. + "r23", \
  9865. + "et", \
  9866. + "bt", \
  9867. + "gp", \
  9868. + "sp", \
  9869. + "fp", \
  9870. + "ta", \
  9871. + "ba", \
  9872. + "ra", \
  9873. + "status", \
  9874. + "estatus", \
  9875. + "bstatus", \
  9876. + "ipri", \
  9877. + "ecause", \
  9878. + "pc", \
  9879. + "rap", \
  9880. + "fake_fp", \
  9881. + "fake_ap", \
  9882. +}
  9883. +
  9884. +#define ADDITIONAL_REGISTER_NAMES \
  9885. +{ \
  9886. + {"r0", 0}, \
  9887. + {"r1", 1}, \
  9888. + {"r24", 24}, \
  9889. + {"r25", 25}, \
  9890. + {"r26", 26}, \
  9891. + {"r27", 27}, \
  9892. + {"r28", 28}, \
  9893. + {"r29", 29}, \
  9894. + {"r30", 30}, \
  9895. + {"r31", 31} \
  9896. +}
  9897. +
  9898. +
  9899. +#define ASM_OUTPUT_OPCODE(STREAM, PTR)\
  9900. + (PTR) = asm_output_opcode (STREAM, PTR)
  9901. +
  9902. +#define PRINT_OPERAND(STREAM, X, CODE) \
  9903. + nios2_print_operand (STREAM, X, CODE)
  9904. +
  9905. +#define PRINT_OPERAND_ADDRESS(STREAM, X) \
  9906. + nios2_print_operand_address (STREAM, X)
  9907. +
  9908. +#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
  9909. +do { fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), FILE); \
  9910. + fprintf (FILE, ".L%u\n", (unsigned) (VALUE)); \
  9911. + } while (0)
  9912. +
  9913. +
  9914. +/* ------------ *
  9915. + * Label Output
  9916. + * ------------ */
  9917. +
  9918. +
  9919. +/* ---------------------------------------------------- *
  9920. + * Dividing the Output into Sections (Texts, Data, ...)
  9921. + * ---------------------------------------------------- */
  9922. +
  9923. +/* Output before read-only data. */
  9924. +#define TEXT_SECTION_ASM_OP ("\t.section\t.text")
  9925. +
  9926. +/* Output before writable data. */
  9927. +#define DATA_SECTION_ASM_OP ("\t.section\t.data")
  9928. +
  9929. +
  9930. +/* Default the definition of "small data" to 8 bytes. */
  9931. +/* ??? How come I can't use HOST_WIDE_INT here? */
  9932. +extern unsigned long nios2_section_threshold;
  9933. +#define NIOS2_DEFAULT_GVALUE 8
  9934. +
  9935. +
  9936. +
  9937. +/* This says how to output assembler code to declare an
  9938. + uninitialized external linkage data object. Under SVR4,
  9939. + the linker seems to want the alignment of data objects
  9940. + to depend on their types. We do exactly that here. */
  9941. +
  9942. +#undef COMMON_ASM_OP
  9943. +#define COMMON_ASM_OP "\t.comm\t"
  9944. +
  9945. +#undef ASM_OUTPUT_ALIGNED_COMMON
  9946. +#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
  9947. +do \
  9948. +{ \
  9949. + if ((SIZE) <= nios2_section_threshold) \
  9950. + { \
  9951. + named_section (0, ".sbss", 0); \
  9952. + (*targetm.asm_out.globalize_label) (FILE, NAME); \
  9953. + ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
  9954. + if (!flag_inhibit_size_directive) \
  9955. + ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \
  9956. + ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT)); \
  9957. + ASM_OUTPUT_LABEL(FILE, NAME); \
  9958. + ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1); \
  9959. + } \
  9960. + else \
  9961. + { \
  9962. + fprintf ((FILE), "%s", COMMON_ASM_OP); \
  9963. + assemble_name ((FILE), (NAME)); \
  9964. + fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
  9965. + } \
  9966. +} \
  9967. +while (0)
  9968. +
  9969. +
  9970. +/* This says how to output assembler code to declare an
  9971. + uninitialized internal linkage data object. Under SVR4,
  9972. + the linker seems to want the alignment of data objects
  9973. + to depend on their types. We do exactly that here. */
  9974. +
  9975. +#undef ASM_OUTPUT_ALIGNED_LOCAL
  9976. +#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
  9977. +do { \
  9978. + if ((SIZE) <= nios2_section_threshold) \
  9979. + named_section (0, ".sbss", 0); \
  9980. + else \
  9981. + named_section (0, ".bss", 0); \
  9982. + ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
  9983. + if (!flag_inhibit_size_directive) \
  9984. + ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \
  9985. + ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT)); \
  9986. + ASM_OUTPUT_LABEL(FILE, NAME); \
  9987. + ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1); \
  9988. +} while (0)
  9989. +
  9990. +
  9991. +
  9992. +/***************************
  9993. + * Miscellaneous Parameters
  9994. + ***************************/
  9995. +
  9996. +#define MOVE_MAX 4
  9997. +
  9998. +#define STORE_FLAG_VALUE 1
  9999. +#define Pmode SImode
  10000. +#define FUNCTION_MODE QImode
  10001. +
  10002. +#define REGISTER_TARGET_PRAGMAS() nios2_register_target_pragmas ();
  10003. +
  10004. +#define CASE_VECTOR_MODE Pmode
  10005. +
  10006. +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
  10007. +
  10008. +#define LOAD_EXTEND_OP(MODE) (ZERO_EXTEND)
  10009. +
  10010. +#define WORD_REGISTER_OPERATIONS
  10011. diff --git a/gcc/config/nios2/nios2.md b/gcc/config/nios2/nios2.md
  10012. new file mode 100644
  10013. index 0000000..6183247
  10014. --- /dev/null
  10015. +++ b/gcc/config/nios2/nios2.md
  10016. @@ -0,0 +1,2867 @@
  10017. +;; Machine Description for Altera NIOS 2G NIOS2 version.
  10018. +;; Copyright (C) 2005 Altera
  10019. +;; Contributed by Jonah Graham (jgraham@altera.com) and Will Reece (wreece@altera.com).
  10020. +;;
  10021. +;; This file is part of GNU CC.
  10022. +;;
  10023. +;; GNU CC is free software; you can redistribute it and/or modify
  10024. +;; it under the terms of the GNU General Public License as published by
  10025. +;; the Free Software Foundation; either version 2, or (at your option)
  10026. +;; any later version.
  10027. +;;
  10028. +;; GNU CC is distributed in the hope that it will be useful,
  10029. +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10030. +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10031. +;; GNU General Public License for more details.
  10032. +;;
  10033. +;; You should have received a copy of the GNU General Public License
  10034. +;; along with GNU CC; see the file COPYING. If not, write to
  10035. +;; the Free Software Foundation, 59 Temple Place - Suite 330,
  10036. +;; Boston, MA 02111-1307, USA. */
  10037. +
  10038. +
  10039. +
  10040. +
  10041. +;*****************************************************************************
  10042. +;*
  10043. +;* constraint strings
  10044. +;*
  10045. +;*****************************************************************************
  10046. +;
  10047. +; We use the following constraint letters for constants
  10048. +;
  10049. +; I: -32768 to -32767
  10050. +; J: 0 to 65535
  10051. +; K: $nnnn0000 for some nnnn
  10052. +; L: 0 to 31 (for shift counts)
  10053. +; M: 0
  10054. +; N: 0 to 255 (for custom instruction numbers)
  10055. +; O: 0 to 31 (for control register numbers)
  10056. +;
  10057. +; We use the following built-in register classes:
  10058. +;
  10059. +; r: general purpose register (r0..r31)
  10060. +; m: memory operand
  10061. +;
  10062. +; Plus, we define the following constraint strings:
  10063. +;
  10064. +; S: symbol that is in the "small data" area
  10065. +; Dnn: Dnn_REG (just rnn)
  10066. +;
  10067. +
  10068. +
  10069. +
  10070. +;*****************************************************************************
  10071. +;*
  10072. +;* constants
  10073. +;*
  10074. +;*****************************************************************************
  10075. +(define_constants [
  10076. + (ET_REGNO 24)
  10077. + (GP_REGNO 26)
  10078. + (SP_REGNO 27)
  10079. + (FP_REGNO 28)
  10080. + (RA_REGNO 31)
  10081. + (RAP_REGNO 38)
  10082. + (FIRST_RETVAL_REGNO 2)
  10083. + (LAST_RETVAL_REGNO 3)
  10084. + (FIRST_ARG_REGNO 4)
  10085. + (LAST_ARG_REGNO 7)
  10086. + (SC_REGNO 23)
  10087. + (PC_REGNO 37)
  10088. + (FAKE_FP_REGNO 39)
  10089. + (FAKE_AP_REGNO 40)
  10090. +
  10091. +
  10092. + (UNSPEC_BLOCKAGE 0)
  10093. + (UNSPEC_LDBIO 1)
  10094. + (UNSPEC_LDBUIO 2)
  10095. + (UNSPEC_LDHIO 3)
  10096. + (UNSPEC_LDHUIO 4)
  10097. + (UNSPEC_LDWIO 5)
  10098. + (UNSPEC_STBIO 6)
  10099. + (UNSPEC_STHIO 7)
  10100. + (UNSPEC_STWIO 8)
  10101. + (UNSPEC_SYNC 9)
  10102. + (UNSPEC_WRCTL 10)
  10103. + (UNSPEC_RDCTL 11)
  10104. + (UNSPEC_TRAP 12)
  10105. + (UNSPEC_STACK_OVERFLOW_DETECT_AND_TRAP 13)
  10106. + (UNSPEC_FCOSS 14)
  10107. + (UNSPEC_FCOSD 15)
  10108. + (UNSPEC_FSINS 16)
  10109. + (UNSPEC_FSIND 17)
  10110. + (UNSPEC_FTANS 18)
  10111. + (UNSPEC_FTAND 19)
  10112. + (UNSPEC_FATANS 20)
  10113. + (UNSPEC_FATAND 21)
  10114. + (UNSPEC_FEXPS 22)
  10115. + (UNSPEC_FEXPD 23)
  10116. + (UNSPEC_FLOGS 24)
  10117. + (UNSPEC_FLOGD 25)
  10118. + (UNSPEC_FWRX 26)
  10119. + (UNSPEC_FWRY 27)
  10120. + (UNSPEC_FRDXLO 28)
  10121. + (UNSPEC_FRDXHI 29)
  10122. + (UNSPEC_FRDY 30)
  10123. + ;; Note that values 100..151 are used by custom instructions, see below.
  10124. +])
  10125. +
  10126. +
  10127. +
  10128. +;*****************************************************************************
  10129. +;*
  10130. +;* instruction scheduler
  10131. +;*
  10132. +;*****************************************************************************
  10133. +
  10134. +; No schedule info is currently available, using an assumption that no
  10135. +; instruction can use the results of the previous instruction without
  10136. +; incuring a stall.
  10137. +
  10138. +; length of an instruction (in bytes)
  10139. +(define_attr "length" "" (const_int 4))
  10140. +(define_attr "type" "unknown,complex,control,alu,cond_alu,st,ld,shift,mul,div,custom" (const_string "complex"))
  10141. +
  10142. +(define_asm_attributes
  10143. + [(set_attr "length" "4")
  10144. + (set_attr "type" "complex")])
  10145. +
  10146. +(define_automaton "nios2")
  10147. +(automata_option "v")
  10148. +;(automata_option "no-minimization")
  10149. +(automata_option "ndfa")
  10150. +
  10151. +; The nios2 pipeline is fairly straightforward for the fast model.
  10152. +; Every alu operation is pipelined so that an instruction can
  10153. +; be issued every cycle. However, there are still potential
  10154. +; stalls which this description tries to deal with.
  10155. +
  10156. +(define_cpu_unit "cpu" "nios2")
  10157. +
  10158. +(define_insn_reservation "complex" 1
  10159. + (eq_attr "type" "complex")
  10160. + "cpu")
  10161. +
  10162. +(define_insn_reservation "control" 1
  10163. + (eq_attr "type" "control")
  10164. + "cpu")
  10165. +
  10166. +(define_insn_reservation "alu" 1
  10167. + (eq_attr "type" "alu")
  10168. + "cpu")
  10169. +
  10170. +(define_insn_reservation "cond_alu" 1
  10171. + (eq_attr "type" "cond_alu")
  10172. + "cpu")
  10173. +
  10174. +(define_insn_reservation "st" 1
  10175. + (eq_attr "type" "st")
  10176. + "cpu")
  10177. +
  10178. +(define_insn_reservation "custom" 1
  10179. + (eq_attr "type" "custom")
  10180. + "cpu")
  10181. +
  10182. +; shifts, muls and lds have three cycle latency
  10183. +(define_insn_reservation "ld" 3
  10184. + (eq_attr "type" "ld")
  10185. + "cpu")
  10186. +
  10187. +(define_insn_reservation "shift" 3
  10188. + (eq_attr "type" "shift")
  10189. + "cpu")
  10190. +
  10191. +(define_insn_reservation "mul" 3
  10192. + (eq_attr "type" "mul")
  10193. + "cpu")
  10194. +
  10195. +(define_insn_reservation "div" 1
  10196. + (eq_attr "type" "div")
  10197. + "cpu")
  10198. +
  10199. +
  10200. +;*****************************************************************************
  10201. +;*
  10202. +;* MOV Instructions
  10203. +;*
  10204. +;*****************************************************************************
  10205. +
  10206. +(define_expand "movqi"
  10207. + [(set (match_operand:QI 0 "nonimmediate_operand" "")
  10208. + (match_operand:QI 1 "general_operand" ""))]
  10209. + ""
  10210. +{
  10211. + if (nios2_emit_move_sequence (operands, QImode))
  10212. + DONE;
  10213. +})
  10214. +
  10215. +(define_insn "movqi_internal"
  10216. + [(set (match_operand:QI 0 "nonimmediate_operand" "=m, r,r, r")
  10217. + (match_operand:QI 1 "general_operand" "rM,m,rM,I"))]
  10218. + "(register_operand (operands[0], QImode)
  10219. + || reg_or_0_operand (operands[1], QImode))"
  10220. + "@
  10221. + stb%o0\\t%z1, %0
  10222. + ldbu%o1\\t%0, %1
  10223. + mov\\t%0, %z1
  10224. + movi\\t%0, %1"
  10225. + [(set_attr "type" "st,ld,alu,alu")])
  10226. +
  10227. +(define_insn "ldbio"
  10228. + [(set (match_operand:SI 0 "register_operand" "=r")
  10229. + (unspec_volatile:SI [(const_int 0)] UNSPEC_LDBIO))
  10230. + (use (match_operand:SI 1 "memory_operand" "m"))]
  10231. + ""
  10232. + "ldbio\\t%0, %1"
  10233. + [(set_attr "type" "ld")])
  10234. +
  10235. +(define_insn "ldbuio"
  10236. + [(set (match_operand:SI 0 "register_operand" "=r")
  10237. + (unspec_volatile:SI [(const_int 0)] UNSPEC_LDBUIO))
  10238. + (use (match_operand:SI 1 "memory_operand" "m"))]
  10239. + ""
  10240. + "ldbuio\\t%0, %1"
  10241. + [(set_attr "type" "ld")])
  10242. +
  10243. +(define_insn "stbio"
  10244. + [(set (match_operand:SI 0 "memory_operand" "=m")
  10245. + (match_operand:SI 1 "reg_or_0_operand" "rM"))
  10246. + (unspec_volatile:SI [(const_int 0)] UNSPEC_STBIO)]
  10247. + ""
  10248. + "stbio\\t%z1, %0"
  10249. + [(set_attr "type" "st")])
  10250. +
  10251. +
  10252. +(define_expand "movhi"
  10253. + [(set (match_operand:HI 0 "nonimmediate_operand" "")
  10254. + (match_operand:HI 1 "general_operand" ""))]
  10255. + ""
  10256. +{
  10257. + if (nios2_emit_move_sequence (operands, HImode))
  10258. + DONE;
  10259. +})
  10260. +
  10261. +(define_insn "movhi_internal"
  10262. + [(set (match_operand:HI 0 "nonimmediate_operand" "=m, r,r, r,r")
  10263. + (match_operand:HI 1 "general_operand" "rM,m,rM,I,J"))]
  10264. + "(register_operand (operands[0], HImode)
  10265. + || reg_or_0_operand (operands[1], HImode))"
  10266. + "@
  10267. + sth%o0\\t%z1, %0
  10268. + ldhu%o1\\t%0, %1
  10269. + mov\\t%0, %z1
  10270. + movi\\t%0, %1
  10271. + movui\\t%0, %1"
  10272. + [(set_attr "type" "st,ld,alu,alu,alu")])
  10273. +
  10274. +(define_insn "ldhio"
  10275. + [(set (match_operand:SI 0 "register_operand" "=r")
  10276. + (unspec_volatile:SI [(const_int 0)] UNSPEC_LDHIO))
  10277. + (use (match_operand:SI 1 "memory_operand" "m"))]
  10278. + ""
  10279. + "ldhio\\t%0, %1"
  10280. + [(set_attr "type" "ld")])
  10281. +
  10282. +(define_insn "ldhuio"
  10283. + [(set (match_operand:SI 0 "register_operand" "=r")
  10284. + (unspec_volatile:SI [(const_int 0)] UNSPEC_LDHUIO))
  10285. + (use (match_operand:SI 1 "memory_operand" "m"))]
  10286. + ""
  10287. + "ldhuio\\t%0, %1"
  10288. + [(set_attr "type" "ld")])
  10289. +
  10290. +(define_insn "sthio"
  10291. + [(set (match_operand:SI 0 "memory_operand" "=m")
  10292. + (match_operand:SI 1 "reg_or_0_operand" "rM"))
  10293. + (unspec_volatile:SI [(const_int 0)] UNSPEC_STHIO)]
  10294. + ""
  10295. + "sthio\\t%z1, %0"
  10296. + [(set_attr "type" "st")])
  10297. +
  10298. +(define_expand "movsi"
  10299. + [(set (match_operand:SI 0 "nonimmediate_operand" "")
  10300. + (match_operand:SI 1 "general_operand" ""))]
  10301. + ""
  10302. +{
  10303. + if (nios2_emit_move_sequence (operands, SImode))
  10304. + DONE;
  10305. +})
  10306. +
  10307. +(define_insn "movsi_internal"
  10308. + [(set (match_operand:SI 0 "nonimmediate_operand" "=m, r,r, r,r,r,r")
  10309. + (match_operand:SI 1 "general_operand" "rM,m,rM,I,J,S,i"))]
  10310. + "(register_operand (operands[0], SImode)
  10311. + || reg_or_0_operand (operands[1], SImode))"
  10312. + "@
  10313. + stw%o0\\t%z1, %0
  10314. + ldw%o1\\t%0, %1
  10315. + mov\\t%0, %z1
  10316. + movi\\t%0, %1
  10317. + movui\\t%0, %1
  10318. + addi\\t%0, gp, %%gprel(%1)
  10319. + movhi\\t%0, %H1\;addi\\t%0, %0, %L1"
  10320. + [(set_attr "type" "st,ld,alu,alu,alu,alu,alu")])
  10321. +
  10322. +(define_insn "ldwio"
  10323. + [(set (match_operand:SI 0 "register_operand" "=r")
  10324. + (unspec_volatile:SI [(const_int 0)] UNSPEC_LDWIO))
  10325. + (use (match_operand:SI 1 "memory_operand" "m"))]
  10326. + ""
  10327. + "ldwio\\t%0, %1"
  10328. + [(set_attr "type" "ld")])
  10329. +
  10330. +(define_insn "stwio"
  10331. + [(set (match_operand:SI 0 "memory_operand" "=m")
  10332. + (match_operand:SI 1 "reg_or_0_operand" "rM"))
  10333. + (unspec_volatile:SI [(const_int 0)] UNSPEC_STWIO)]
  10334. + ""
  10335. + "stwio\\t%z1, %0"
  10336. + [(set_attr "type" "st")])
  10337. +
  10338. +
  10339. +
  10340. +;*****************************************************************************
  10341. +;*
  10342. +;* zero extension
  10343. +;*
  10344. +;*****************************************************************************
  10345. +
  10346. +
  10347. +(define_insn "zero_extendhisi2"
  10348. + [(set (match_operand:SI 0 "register_operand" "=r,r")
  10349. + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
  10350. + ""
  10351. + "@
  10352. + andi\\t%0, %1, 0xffff
  10353. + ldhu%o1\\t%0, %1"
  10354. + [(set_attr "type" "alu,ld")])
  10355. +
  10356. +(define_insn "zero_extendqihi2"
  10357. + [(set (match_operand:HI 0 "register_operand" "=r,r")
  10358. + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
  10359. + ""
  10360. + "@
  10361. + andi\\t%0, %1, 0xff
  10362. + ldbu%o1\\t%0, %1"
  10363. + [(set_attr "type" "alu,ld")])
  10364. +
  10365. +(define_insn "zero_extendqisi2"
  10366. + [(set (match_operand:SI 0 "register_operand" "=r,r")
  10367. + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
  10368. + ""
  10369. + "@
  10370. + andi\\t%0, %1, 0xff
  10371. + ldbu%o1\\t%0, %1"
  10372. + [(set_attr "type" "alu,ld")])
  10373. +
  10374. +
  10375. +
  10376. +;*****************************************************************************
  10377. +;*
  10378. +;* sign extension
  10379. +;*
  10380. +;*****************************************************************************
  10381. +(define_expand "extendhisi2"
  10382. + [(set (match_operand:SI 0 "register_operand" "")
  10383. + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
  10384. + ""
  10385. +{
  10386. +})
  10387. +
  10388. +(define_insn "*extendhisi2"
  10389. + [(set (match_operand:SI 0 "register_operand" "=r")
  10390. + (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
  10391. + ""
  10392. + "#")
  10393. +
  10394. +(define_split
  10395. + [(set (match_operand:SI 0 "register_operand" "")
  10396. + (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
  10397. + "reload_completed"
  10398. + [(set (match_dup 0)
  10399. + (and:SI (match_dup 1) (const_int 65535)))
  10400. + (set (match_dup 0)
  10401. + (xor:SI (match_dup 0) (const_int 32768)))
  10402. + (set (match_dup 0)
  10403. + (plus:SI (match_dup 0) (const_int -32768)))]
  10404. + "operands[1] = gen_lowpart (SImode, operands[1]);")
  10405. +
  10406. +(define_insn "extendhisi2_internal"
  10407. + [(set (match_operand:SI 0 "register_operand" "=r")
  10408. + (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
  10409. + ""
  10410. + "ldh%o1\\t%0, %1"
  10411. + [(set_attr "type" "ld")])
  10412. +
  10413. +
  10414. +(define_expand "extendqihi2"
  10415. + [(set (match_operand:HI 0 "register_operand" "")
  10416. + (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
  10417. + ""
  10418. +{
  10419. +})
  10420. +
  10421. +(define_insn "*extendqihi2"
  10422. + [(set (match_operand:HI 0 "register_operand" "=r")
  10423. + (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
  10424. + ""
  10425. + "#")
  10426. +
  10427. +(define_split
  10428. + [(set (match_operand:HI 0 "register_operand" "")
  10429. + (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
  10430. + "reload_completed"
  10431. + [(set (match_dup 0)
  10432. + (and:SI (match_dup 1) (const_int 255)))
  10433. + (set (match_dup 0)
  10434. + (xor:SI (match_dup 0) (const_int 128)))
  10435. + (set (match_dup 0)
  10436. + (plus:SI (match_dup 0) (const_int -128)))]
  10437. + "operands[0] = gen_lowpart (SImode, operands[0]);
  10438. + operands[1] = gen_lowpart (SImode, operands[1]);")
  10439. +
  10440. +
  10441. +
  10442. +(define_insn "extendqihi2_internal"
  10443. + [(set (match_operand:HI 0 "register_operand" "=r")
  10444. + (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
  10445. + ""
  10446. + "ldb%o1\\t%0, %1"
  10447. + [(set_attr "type" "ld")])
  10448. +
  10449. +
  10450. +(define_expand "extendqisi2"
  10451. + [(set (match_operand:SI 0 "register_operand" "")
  10452. + (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
  10453. + ""
  10454. +{
  10455. +})
  10456. +
  10457. +(define_insn "*extendqisi2"
  10458. + [(set (match_operand:SI 0 "register_operand" "=r")
  10459. + (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
  10460. + ""
  10461. + "#")
  10462. +
  10463. +(define_split
  10464. + [(set (match_operand:SI 0 "register_operand" "")
  10465. + (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
  10466. + "reload_completed"
  10467. + [(set (match_dup 0)
  10468. + (and:SI (match_dup 1) (const_int 255)))
  10469. + (set (match_dup 0)
  10470. + (xor:SI (match_dup 0) (const_int 128)))
  10471. + (set (match_dup 0)
  10472. + (plus:SI (match_dup 0) (const_int -128)))]
  10473. + "operands[1] = gen_lowpart (SImode, operands[1]);")
  10474. +
  10475. +(define_insn "extendqisi2_insn"
  10476. + [(set (match_operand:SI 0 "register_operand" "=r")
  10477. + (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
  10478. + ""
  10479. + "ldb%o1\\t%0, %1"
  10480. + [(set_attr "type" "ld")])
  10481. +
  10482. +
  10483. +
  10484. +
  10485. +;*****************************************************************************
  10486. +;*
  10487. +;* Arithmetic Operations
  10488. +;*
  10489. +;*****************************************************************************
  10490. +
  10491. +(define_insn "addsi3"
  10492. + [(set (match_operand:SI 0 "register_operand" "=r,r")
  10493. + (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
  10494. + (match_operand:SI 2 "arith_operand" "r,I")))]
  10495. + ""
  10496. + "add%i2\\t%0, %1, %z2"
  10497. + [(set_attr "type" "alu")])
  10498. +
  10499. +(define_insn "addsf3"
  10500. + [(set (match_operand:SF 0 "register_operand" "=r")
  10501. + (plus:SF (match_operand:SF 1 "register_operand" "%r")
  10502. + (match_operand:SF 2 "register_operand" "r")))]
  10503. + "nios2_fpu_insns[nios2_fpu_addsf3].N >= 0"
  10504. + {
  10505. + return (*nios2_fpu_insns[nios2_fpu_addsf3].output) (insn);
  10506. + }
  10507. + [(set_attr "type" "custom")])
  10508. +
  10509. +(define_insn "adddf3"
  10510. + [(set (match_operand:DF 0 "register_operand" "=r")
  10511. + (plus:DF (match_operand:DF 1 "register_operand" "%r")
  10512. + (match_operand:DF 2 "register_operand" "r")))]
  10513. + "nios2_fpu_insns[nios2_fpu_adddf3].N >= 0"
  10514. + {
  10515. + return (*nios2_fpu_insns[nios2_fpu_adddf3].output) (insn);
  10516. + }
  10517. + [(set_attr "type" "custom")])
  10518. +
  10519. +(define_insn "subsi3"
  10520. + [(set (match_operand:SI 0 "register_operand" "=r")
  10521. + (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
  10522. + (match_operand:SI 2 "register_operand" "r")))]
  10523. + ""
  10524. + "sub\\t%0, %z1, %2"
  10525. + [(set_attr "type" "alu")])
  10526. +
  10527. +(define_insn "subsf3"
  10528. + [(set (match_operand:SF 0 "register_operand" "=r")
  10529. + (minus:SF (match_operand:SF 1 "register_operand" "r")
  10530. + (match_operand:SF 2 "register_operand" "r")))]
  10531. + "nios2_fpu_insns[nios2_fpu_subsf3].N >= 0"
  10532. + {
  10533. + return (*nios2_fpu_insns[nios2_fpu_subsf3].output) (insn);
  10534. + }
  10535. + [(set_attr "type" "custom")])
  10536. +
  10537. +(define_insn "subdf3"
  10538. + [(set (match_operand:DF 0 "register_operand" "=r")
  10539. + (minus:DF (match_operand:DF 1 "register_operand" "r")
  10540. + (match_operand:DF 2 "register_operand" "r")))]
  10541. + "nios2_fpu_insns[nios2_fpu_subdf3].N >= 0"
  10542. + {
  10543. + return (*nios2_fpu_insns[nios2_fpu_subdf3].output) (insn);
  10544. + }
  10545. + [(set_attr "type" "custom")])
  10546. +
  10547. +(define_insn "mulsi3"
  10548. + [(set (match_operand:SI 0 "register_operand" "=r,r")
  10549. + (mult:SI (match_operand:SI 1 "register_operand" "r,r")
  10550. + (match_operand:SI 2 "arith_operand" "r,I")))]
  10551. + "TARGET_HAS_MUL"
  10552. + "mul%i2\\t%0, %1, %z2"
  10553. + [(set_attr "type" "mul")])
  10554. +
  10555. +(define_insn "mulsf3"
  10556. + [(set (match_operand:SF 0 "register_operand" "=r")
  10557. + (mult:SF (match_operand:SF 1 "register_operand" "%r")
  10558. + (match_operand:SF 2 "register_operand" "r")))]
  10559. + "nios2_fpu_insns[nios2_fpu_mulsf3].N >= 0"
  10560. + {
  10561. + return (*nios2_fpu_insns[nios2_fpu_mulsf3].output) (insn);
  10562. + }
  10563. + [(set_attr "type" "custom")])
  10564. +
  10565. +(define_insn "muldf3"
  10566. + [(set (match_operand:DF 0 "register_operand" "=r")
  10567. + (mult:DF (match_operand:DF 1 "register_operand" "%r")
  10568. + (match_operand:DF 2 "register_operand" "r")))]
  10569. + "nios2_fpu_insns[nios2_fpu_muldf3].N >= 0"
  10570. + {
  10571. + return (*nios2_fpu_insns[nios2_fpu_muldf3].output) (insn);
  10572. + }
  10573. + [(set_attr "type" "custom")])
  10574. +
  10575. +(define_expand "divsi3"
  10576. + [(set (match_operand:SI 0 "register_operand" "=r")
  10577. + (div:SI (match_operand:SI 1 "register_operand" "r")
  10578. + (match_operand:SI 2 "register_operand" "r")))]
  10579. + ""
  10580. +{
  10581. + if (!TARGET_HAS_DIV)
  10582. + {
  10583. + if (!TARGET_FAST_SW_DIV)
  10584. + FAIL;
  10585. + else
  10586. + {
  10587. + if (nios2_emit_expensive_div (operands, SImode))
  10588. + DONE;
  10589. + }
  10590. + }
  10591. +})
  10592. +
  10593. +(define_insn "divsi3_insn"
  10594. + [(set (match_operand:SI 0 "register_operand" "=r")
  10595. + (div:SI (match_operand:SI 1 "register_operand" "r")
  10596. + (match_operand:SI 2 "register_operand" "r")))]
  10597. + "TARGET_HAS_DIV"
  10598. + "div\\t%0, %1, %2"
  10599. + [(set_attr "type" "div")])
  10600. +
  10601. +(define_insn "divsf3"
  10602. + [(set (match_operand:SF 0 "register_operand" "=r")
  10603. + (div:SF (match_operand:SF 1 "register_operand" "r")
  10604. + (match_operand:SF 2 "register_operand" "r")))]
  10605. + "nios2_fpu_insns[nios2_fpu_divsf3].N >= 0"
  10606. + {
  10607. + return (*nios2_fpu_insns[nios2_fpu_divsf3].output) (insn);
  10608. + }
  10609. + [(set_attr "type" "custom")])
  10610. +
  10611. +(define_insn "divdf3"
  10612. + [(set (match_operand:DF 0 "register_operand" "=r")
  10613. + (div:DF (match_operand:DF 1 "register_operand" "r")
  10614. + (match_operand:DF 2 "register_operand" "r")))]
  10615. + "nios2_fpu_insns[nios2_fpu_divdf3].N >= 0"
  10616. + {
  10617. + return (*nios2_fpu_insns[nios2_fpu_divdf3].output) (insn);
  10618. + }
  10619. + [(set_attr "type" "custom")])
  10620. +
  10621. +(define_insn "udivsi3"
  10622. + [(set (match_operand:SI 0 "register_operand" "=r")
  10623. + (udiv:SI (match_operand:SI 1 "register_operand" "r")
  10624. + (match_operand:SI 2 "register_operand" "r")))]
  10625. + "TARGET_HAS_DIV"
  10626. + "divu\\t%0, %1, %2"
  10627. + [(set_attr "type" "div")])
  10628. +
  10629. +(define_insn "smulsi3_highpart"
  10630. + [(set (match_operand:SI 0 "register_operand" "=r")
  10631. + (truncate:SI
  10632. + (lshiftrt:DI
  10633. + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
  10634. + (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
  10635. + (const_int 32))))]
  10636. + "TARGET_HAS_MULX"
  10637. + "mulxss\\t%0, %1, %2"
  10638. + [(set_attr "type" "mul")])
  10639. +
  10640. +(define_insn "umulsi3_highpart"
  10641. + [(set (match_operand:SI 0 "register_operand" "=r")
  10642. + (truncate:SI
  10643. + (lshiftrt:DI
  10644. + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
  10645. + (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
  10646. + (const_int 32))))]
  10647. + "TARGET_HAS_MULX"
  10648. + "mulxuu\\t%0, %1, %2"
  10649. + [(set_attr "type" "mul")])
  10650. +
  10651. +
  10652. +(define_expand "mulsidi3_little_endian"
  10653. + [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 0)
  10654. + (mult:SI (match_operand:SI 1 "register_operand" "")
  10655. + (match_operand:SI 2 "register_operand" "")))
  10656. + (set (subreg:SI (match_dup 0) 4)
  10657. + (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
  10658. + (sign_extend:DI (match_dup 2)))
  10659. + (const_int 32))))]
  10660. + "TARGET_HAS_MULX && !WORDS_BIG_ENDIAN"
  10661. + "")
  10662. +
  10663. +(define_expand "mulsidi3_big_endian"
  10664. + [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
  10665. + (mult:SI (match_operand:SI 1 "register_operand" "")
  10666. + (match_operand:SI 2 "register_operand" "")))
  10667. + (set (subreg:SI (match_dup 0) 0)
  10668. + (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
  10669. + (sign_extend:DI (match_dup 2)))
  10670. + (const_int 32))))]
  10671. + "TARGET_HAS_MULX && WORDS_BIG_ENDIAN"
  10672. + "")
  10673. +
  10674. +(define_expand "mulsidi3"
  10675. + [(match_operand:DI 0 "register_operand" "")
  10676. + (match_operand:SI 1 "register_operand" "")
  10677. + (match_operand:SI 2 "register_operand" "")]
  10678. + "TARGET_HAS_MULX"
  10679. + {
  10680. + if (WORDS_BIG_ENDIAN)
  10681. + {
  10682. + emit_insn (gen_mulsidi3_big_endian (operands[0],
  10683. + operands[1],
  10684. + operands[2]));
  10685. + }
  10686. + else
  10687. + {
  10688. + emit_insn (gen_mulsidi3_little_endian (operands[0],
  10689. + operands[1],
  10690. + operands[2]));
  10691. + }
  10692. + DONE;
  10693. + })
  10694. +
  10695. +(define_expand "umulsidi3_little_endian"
  10696. + [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 0)
  10697. + (mult:SI (match_operand:SI 1 "register_operand" "")
  10698. + (match_operand:SI 2 "register_operand" "")))
  10699. + (set (subreg:SI (match_dup 0) 4)
  10700. + (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
  10701. + (zero_extend:DI (match_dup 2)))
  10702. + (const_int 32))))]
  10703. + "TARGET_HAS_MULX && !WORDS_BIG_ENDIAN"
  10704. + "")
  10705. +
  10706. +(define_expand "umulsidi3_big_endian"
  10707. + [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
  10708. + (mult:SI (match_operand:SI 1 "register_operand" "")
  10709. + (match_operand:SI 2 "register_operand" "")))
  10710. + (set (subreg:SI (match_dup 0) 0)
  10711. + (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
  10712. + (zero_extend:DI (match_dup 2)))
  10713. + (const_int 32))))]
  10714. + "TARGET_HAS_MULX && WORDS_BIG_ENDIAN"
  10715. + "")
  10716. +
  10717. +(define_expand "umulsidi3"
  10718. + [(match_operand:DI 0 "register_operand" "")
  10719. + (match_operand:SI 1 "register_operand" "")
  10720. + (match_operand:SI 2 "register_operand" "")]
  10721. + "TARGET_HAS_MULX"
  10722. + {
  10723. + if (WORDS_BIG_ENDIAN)
  10724. + {
  10725. + emit_insn (gen_umulsidi3_big_endian (operands[0],
  10726. + operands[1],
  10727. + operands[2]));
  10728. + }
  10729. + else
  10730. + {
  10731. + emit_insn (gen_umulsidi3_little_endian (operands[0],
  10732. + operands[1],
  10733. + operands[2]));
  10734. + }
  10735. + DONE;
  10736. + })
  10737. +
  10738. +
  10739. +;*****************************************************************************
  10740. +;*
  10741. +;* Negate and ones complement
  10742. +;*
  10743. +;*****************************************************************************
  10744. +
  10745. +(define_insn "negsi2"
  10746. + [(set (match_operand:SI 0 "register_operand" "=r")
  10747. + (neg:SI (match_operand:SI 1 "register_operand" "r")))]
  10748. + ""
  10749. +{
  10750. + operands[2] = const0_rtx;
  10751. + return "sub\\t%0, %z2, %1";
  10752. +}
  10753. + [(set_attr "type" "alu")])
  10754. +
  10755. +(define_insn "negsf2"
  10756. + [(set (match_operand:SF 0 "register_operand" "=r")
  10757. + (neg:SF (match_operand:SF 1 "register_operand" "r")))]
  10758. + "nios2_fpu_insns[nios2_fpu_negsf2].N >= 0"
  10759. + {
  10760. + return (*nios2_fpu_insns[nios2_fpu_negsf2].output) (insn);
  10761. + }
  10762. + [(set_attr "type" "custom")])
  10763. +
  10764. +(define_insn "negdf2"
  10765. + [(set (match_operand:DF 0 "register_operand" "=r")
  10766. + (neg:DF (match_operand:DF 1 "register_operand" "r")))]
  10767. + "nios2_fpu_insns[nios2_fpu_negdf2].N >= 0"
  10768. + {
  10769. + return (*nios2_fpu_insns[nios2_fpu_negdf2].output) (insn);
  10770. + }
  10771. + [(set_attr "type" "custom")])
  10772. +
  10773. +(define_insn "one_cmplsi2"
  10774. + [(set (match_operand:SI 0 "register_operand" "=r")
  10775. + (not:SI (match_operand:SI 1 "register_operand" "r")))]
  10776. + ""
  10777. +{
  10778. + operands[2] = const0_rtx;
  10779. + return "nor\\t%0, %z2, %1";
  10780. +}
  10781. + [(set_attr "type" "alu")])
  10782. +
  10783. +
  10784. +;*****************************************************************************
  10785. +;*
  10786. +;* Miscellaneous floating point
  10787. +;*
  10788. +;*****************************************************************************
  10789. +(define_insn "nios2_fwrx"
  10790. + [(unspec_volatile [(match_operand:DF 0 "register_operand" "r")] UNSPEC_FWRX)]
  10791. + "nios2_fpu_insns[nios2_fpu_nios2_fwrx].N >= 0"
  10792. + {
  10793. + return (*nios2_fpu_insns[nios2_fpu_nios2_fwrx].output) (insn);
  10794. + }
  10795. + [(set_attr "type" "custom")])
  10796. +
  10797. +(define_insn "nios2_fwry"
  10798. + [(unspec_volatile [(match_operand:SF 0 "register_operand" "r")] UNSPEC_FWRY)]
  10799. + "nios2_fpu_insns[nios2_fpu_nios2_fwry].N >= 0"
  10800. + {
  10801. + return (*nios2_fpu_insns[nios2_fpu_nios2_fwry].output) (insn);
  10802. + }
  10803. + [(set_attr "type" "custom")])
  10804. +
  10805. +(define_insn "nios2_frdxlo"
  10806. + [(set (match_operand:SF 0 "register_operand" "=r")
  10807. + (unspec_volatile:SF [(const_int 0)] UNSPEC_FRDXLO))]
  10808. + "nios2_fpu_insns[nios2_fpu_nios2_frdxlo].N >= 0"
  10809. + {
  10810. + return (*nios2_fpu_insns[nios2_fpu_nios2_frdxlo].output) (insn);
  10811. + }
  10812. + [(set_attr "type" "custom")])
  10813. +
  10814. +(define_insn "nios2_frdxhi"
  10815. + [(set (match_operand:SF 0 "register_operand" "=r")
  10816. + (unspec_volatile:SF [(const_int 0)] UNSPEC_FRDXHI))]
  10817. + "nios2_fpu_insns[nios2_fpu_nios2_frdxhi].N >= 0"
  10818. + {
  10819. + return (*nios2_fpu_insns[nios2_fpu_nios2_frdxhi].output) (insn);
  10820. + }
  10821. + [(set_attr "type" "custom")])
  10822. +
  10823. +(define_insn "nios2_frdy"
  10824. + [(set (match_operand:SF 0 "register_operand" "=r")
  10825. + (unspec_volatile:SF [(const_int 0)] UNSPEC_FRDY))]
  10826. + "nios2_fpu_insns[nios2_fpu_nios2_frdy].N >= 0"
  10827. + {
  10828. + return (*nios2_fpu_insns[nios2_fpu_nios2_frdy].output) (insn);
  10829. + }
  10830. + [(set_attr "type" "custom")])
  10831. +
  10832. +(define_insn "minsf3"
  10833. + [(set (match_operand:SF 0 "register_operand" "=r")
  10834. + (if_then_else:SF (lt:SF (match_operand:SF 1 "register_operand" "%r")
  10835. + (match_operand:SF 2 "register_operand" "r"))
  10836. + (match_dup 1)
  10837. + (match_dup 2)))]
  10838. + "nios2_fpu_insns[nios2_fpu_minsf3].N >= 0"
  10839. + {
  10840. + return (*nios2_fpu_insns[nios2_fpu_minsf3].output) (insn);
  10841. + }
  10842. + [(set_attr "type" "custom")])
  10843. +
  10844. +(define_insn "mindf3"
  10845. + [(set (match_operand:DF 0 "register_operand" "=r")
  10846. + (if_then_else:DF (lt:DF (match_operand:DF 1 "register_operand" "%r")
  10847. + (match_operand:DF 2 "register_operand" "r"))
  10848. + (match_dup 1)
  10849. + (match_dup 2)))]
  10850. + "nios2_fpu_insns[nios2_fpu_mindf3].N >= 0"
  10851. + {
  10852. + return (*nios2_fpu_insns[nios2_fpu_mindf3].output) (insn);
  10853. + }
  10854. + [(set_attr "type" "custom")])
  10855. +
  10856. +(define_insn "maxsf3"
  10857. + [(set (match_operand:SF 0 "register_operand" "=r")
  10858. + (if_then_else:SF (lt:SF (match_operand:SF 1 "register_operand" "%r")
  10859. + (match_operand:SF 2 "register_operand" "r"))
  10860. + (match_dup 2)
  10861. + (match_dup 1)))]
  10862. + "nios2_fpu_insns[nios2_fpu_maxsf3].N >= 0"
  10863. + {
  10864. + return (*nios2_fpu_insns[nios2_fpu_maxsf3].output) (insn);
  10865. + }
  10866. + [(set_attr "type" "custom")])
  10867. +
  10868. +(define_insn "maxdf3"
  10869. + [(set (match_operand:DF 0 "register_operand" "=r")
  10870. + (if_then_else:DF (lt:DF (match_operand:DF 1 "register_operand" "%r")
  10871. + (match_operand:DF 2 "register_operand" "r"))
  10872. + (match_dup 2)
  10873. + (match_dup 1)))]
  10874. + "nios2_fpu_insns[nios2_fpu_maxdf3].N >= 0"
  10875. + {
  10876. + return (*nios2_fpu_insns[nios2_fpu_maxdf3].output) (insn);
  10877. + }
  10878. + [(set_attr "type" "custom")])
  10879. +
  10880. +(define_insn "abssf2"
  10881. + [(set (match_operand:SF 0 "register_operand" "=r")
  10882. + (abs:SF (match_operand:SF 1 "register_operand" "r")))]
  10883. + "nios2_fpu_insns[nios2_fpu_abssf2].N >= 0"
  10884. + {
  10885. + return (*nios2_fpu_insns[nios2_fpu_abssf2].output) (insn);
  10886. + }
  10887. + [(set_attr "type" "custom")])
  10888. +
  10889. +(define_insn "absdf2"
  10890. + [(set (match_operand:DF 0 "register_operand" "=r")
  10891. + (abs:DF (match_operand:DF 1 "register_operand" "r")))]
  10892. + "nios2_fpu_insns[nios2_fpu_absdf2].N >= 0"
  10893. + {
  10894. + return (*nios2_fpu_insns[nios2_fpu_absdf2].output) (insn);
  10895. + }
  10896. + [(set_attr "type" "custom")])
  10897. +
  10898. +(define_insn "sqrtsf2"
  10899. + [(set (match_operand:SF 0 "register_operand" "=r")
  10900. + (sqrt:SF (match_operand:SF 1 "register_operand" "r")))]
  10901. + "nios2_fpu_insns[nios2_fpu_sqrtsf2].N >= 0"
  10902. + {
  10903. + return (*nios2_fpu_insns[nios2_fpu_sqrtsf2].output) (insn);
  10904. + }
  10905. + [(set_attr "type" "custom")])
  10906. +
  10907. +(define_insn "sqrtdf2"
  10908. + [(set (match_operand:DF 0 "register_operand" "=r")
  10909. + (sqrt:DF (match_operand:DF 1 "register_operand" "r")))]
  10910. + "nios2_fpu_insns[nios2_fpu_sqrtdf2].N >= 0"
  10911. + {
  10912. + return (*nios2_fpu_insns[nios2_fpu_sqrtdf2].output) (insn);
  10913. + }
  10914. + [(set_attr "type" "custom")])
  10915. +
  10916. +(define_insn "cossf2"
  10917. + [(set (match_operand:SF 0 "register_operand" "=r")
  10918. + (unspec:SF [(match_operand:SF 1 "register_operand" "r")] UNSPEC_FCOSS))]
  10919. + "nios2_fpu_insns[nios2_fpu_cossf2].N >= 0"
  10920. + {
  10921. + return (*nios2_fpu_insns[nios2_fpu_cossf2].output) (insn);
  10922. + }
  10923. + [(set_attr "type" "custom")])
  10924. +
  10925. +(define_insn "cosdf2"
  10926. + [(set (match_operand:DF 0 "register_operand" "=r")
  10927. + (unspec:DF [(match_operand:DF 1 "register_operand" "r")] UNSPEC_FCOSD))]
  10928. + "nios2_fpu_insns[nios2_fpu_cosdf2].N >= 0"
  10929. + {
  10930. + return (*nios2_fpu_insns[nios2_fpu_cosdf2].output) (insn);
  10931. + }
  10932. + [(set_attr "type" "custom")])
  10933. +
  10934. +(define_insn "sinsf2"
  10935. + [(set (match_operand:SF 0 "register_operand" "=r")
  10936. + (unspec:SF [(match_operand:SF 1 "register_operand" "r")] UNSPEC_FSINS))]
  10937. + "nios2_fpu_insns[nios2_fpu_sinsf2].N >= 0"
  10938. + {
  10939. + return (*nios2_fpu_insns[nios2_fpu_sinsf2].output) (insn);
  10940. + }
  10941. + [(set_attr "type" "custom")])
  10942. +
  10943. +(define_insn "sindf2"
  10944. + [(set (match_operand:DF 0 "register_operand" "=r")
  10945. + (unspec:DF [(match_operand:DF 1 "register_operand" "r")] UNSPEC_FSIND))]
  10946. + "nios2_fpu_insns[nios2_fpu_sindf2].N >= 0"
  10947. + {
  10948. + return (*nios2_fpu_insns[nios2_fpu_sindf2].output) (insn);
  10949. + }
  10950. + [(set_attr "type" "custom")])
  10951. +
  10952. +(define_insn "tansf2"
  10953. + [(set (match_operand:SF 0 "register_operand" "=r")
  10954. + (unspec:SF [(match_operand:SF 1 "register_operand" "r")] UNSPEC_FTANS))]
  10955. + "nios2_fpu_insns[nios2_fpu_tansf2].N >= 0"
  10956. + {
  10957. + return (*nios2_fpu_insns[nios2_fpu_tansf2].output) (insn);
  10958. + }
  10959. + [(set_attr "type" "custom")])
  10960. +
  10961. +(define_insn "tandf2"
  10962. + [(set (match_operand:DF 0 "register_operand" "=r")
  10963. + (unspec:DF [(match_operand:DF 1 "register_operand" "r")] UNSPEC_FTAND))]
  10964. + "nios2_fpu_insns[nios2_fpu_tandf2].N >= 0"
  10965. + {
  10966. + return (*nios2_fpu_insns[nios2_fpu_tandf2].output) (insn);
  10967. + }
  10968. + [(set_attr "type" "custom")])
  10969. +
  10970. +(define_insn "atansf2"
  10971. + [(set (match_operand:SF 0 "register_operand" "=r")
  10972. + (unspec:SF [(match_operand:SF 1 "register_operand" "r")] UNSPEC_FATANS))]
  10973. + "nios2_fpu_insns[nios2_fpu_atansf2].N >= 0"
  10974. + {
  10975. + return (*nios2_fpu_insns[nios2_fpu_atansf2].output) (insn);
  10976. + }
  10977. + [(set_attr "type" "custom")])
  10978. +
  10979. +(define_insn "atandf2"
  10980. + [(set (match_operand:DF 0 "register_operand" "=r")
  10981. + (unspec:DF [(match_operand:DF 1 "register_operand" "r")] UNSPEC_FATAND))]
  10982. + "nios2_fpu_insns[nios2_fpu_atandf2].N >= 0"
  10983. + {
  10984. + return (*nios2_fpu_insns[nios2_fpu_atandf2].output) (insn);
  10985. + }
  10986. + [(set_attr "type" "custom")])
  10987. +
  10988. +(define_insn "expsf2"
  10989. + [(set (match_operand:SF 0 "register_operand" "=r")
  10990. + (unspec:SF [(match_operand:SF 1 "register_operand" "r")] UNSPEC_FEXPS))]
  10991. + "nios2_fpu_insns[nios2_fpu_expsf2].N >= 0"
  10992. + {
  10993. + return (*nios2_fpu_insns[nios2_fpu_expsf2].output) (insn);
  10994. + }
  10995. + [(set_attr "type" "custom")])
  10996. +
  10997. +(define_insn "expdf2"
  10998. + [(set (match_operand:DF 0 "register_operand" "=r")
  10999. + (unspec:DF [(match_operand:DF 1 "register_operand" "r")] UNSPEC_FEXPD))]
  11000. + "nios2_fpu_insns[nios2_fpu_expdf2].N >= 0"
  11001. + {
  11002. + return (*nios2_fpu_insns[nios2_fpu_expdf2].output) (insn);
  11003. + }
  11004. + [(set_attr "type" "custom")])
  11005. +
  11006. +(define_insn "logsf2"
  11007. + [(set (match_operand:SF 0 "register_operand" "=r")
  11008. + (unspec:SF [(match_operand:SF 1 "register_operand" "r")] UNSPEC_FLOGS))]
  11009. + "nios2_fpu_insns[nios2_fpu_logsf2].N >= 0"
  11010. + {
  11011. + return (*nios2_fpu_insns[nios2_fpu_logsf2].output) (insn);
  11012. + }
  11013. + [(set_attr "type" "custom")])
  11014. +
  11015. +(define_insn "logdf2"
  11016. + [(set (match_operand:DF 0 "register_operand" "=r")
  11017. + (unspec:DF [(match_operand:DF 1 "register_operand" "r")] UNSPEC_FLOGD))]
  11018. + "nios2_fpu_insns[nios2_fpu_logdf2].N >= 0"
  11019. + {
  11020. + return (*nios2_fpu_insns[nios2_fpu_logdf2].output) (insn);
  11021. + }
  11022. + [(set_attr "type" "custom")])
  11023. +
  11024. +
  11025. +;*****************************************************************************
  11026. +;*
  11027. +;* Logical Operantions
  11028. +;*
  11029. +;*****************************************************************************
  11030. +
  11031. +(define_insn "andsi3"
  11032. + [(set (match_operand:SI 0 "register_operand" "=r, r,r")
  11033. + (and:SI (match_operand:SI 1 "register_operand" "%r, r,r")
  11034. + (match_operand:SI 2 "logical_operand" "rM,J,K")))]
  11035. + ""
  11036. + "@
  11037. + and\\t%0, %1, %z2
  11038. + and%i2\\t%0, %1, %2
  11039. + andh%i2\\t%0, %1, %U2"
  11040. + [(set_attr "type" "alu")])
  11041. +
  11042. +(define_insn "iorsi3"
  11043. + [(set (match_operand:SI 0 "register_operand" "=r, r,r")
  11044. + (ior:SI (match_operand:SI 1 "register_operand" "%r, r,r")
  11045. + (match_operand:SI 2 "logical_operand" "rM,J,K")))]
  11046. + ""
  11047. + "@
  11048. + or\\t%0, %1, %z2
  11049. + or%i2\\t%0, %1, %2
  11050. + orh%i2\\t%0, %1, %U2"
  11051. + [(set_attr "type" "alu")])
  11052. +
  11053. +(define_insn "*norsi3"
  11054. + [(set (match_operand:SI 0 "register_operand" "=r")
  11055. + (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
  11056. + (not:SI (match_operand:SI 2 "reg_or_0_operand" "rM"))))]
  11057. + ""
  11058. + "nor\\t%0, %1, %z2"
  11059. + [(set_attr "type" "alu")])
  11060. +
  11061. +(define_insn "xorsi3"
  11062. + [(set (match_operand:SI 0 "register_operand" "=r, r,r")
  11063. + (xor:SI (match_operand:SI 1 "register_operand" "%r, r,r")
  11064. + (match_operand:SI 2 "logical_operand" "rM,J,K")))]
  11065. + ""
  11066. + "@
  11067. + xor\\t%0, %1, %z2
  11068. + xor%i2\\t%0, %1, %2
  11069. + xorh%i2\\t%0, %1, %U2"
  11070. + [(set_attr "type" "alu")])
  11071. +
  11072. +
  11073. +
  11074. +;*****************************************************************************
  11075. +;*
  11076. +;* Shifts
  11077. +;*
  11078. +;*****************************************************************************
  11079. +
  11080. +(define_insn "ashlsi3"
  11081. + [(set (match_operand:SI 0 "register_operand" "=r,r")
  11082. + (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
  11083. + (match_operand:SI 2 "shift_operand" "r,L")))]
  11084. + ""
  11085. +
  11086. +{
  11087. + if( GET_CODE ( operands[2] ) == CONST_INT && INTVAL( operands[2] ) == 1 )
  11088. + return "add\t%0,%1,%1";
  11089. + return "sll%i2\t%0,%1,%z2";
  11090. +}
  11091. + [(set_attr "type" "shift")])
  11092. +
  11093. +(define_insn "ashrsi3"
  11094. + [(set (match_operand:SI 0 "register_operand" "=r,r")
  11095. + (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
  11096. + (match_operand:SI 2 "shift_operand" "r,L")))]
  11097. + ""
  11098. + "sra%i2\\t%0, %1, %z2"
  11099. + [(set_attr "type" "shift")])
  11100. +
  11101. +(define_insn "lshrsi3"
  11102. + [(set (match_operand:SI 0 "register_operand" "=r,r")
  11103. + (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
  11104. + (match_operand:SI 2 "shift_operand" "r,L")))]
  11105. + ""
  11106. + "srl%i2\\t%0, %1, %z2"
  11107. + [(set_attr "type" "shift")])
  11108. +
  11109. +(define_insn "rotlsi3"
  11110. + [(set (match_operand:SI 0 "register_operand" "=r,r")
  11111. + (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
  11112. + (match_operand:SI 2 "shift_operand" "r,L")))]
  11113. + ""
  11114. + "rol%i2\\t%0, %1, %z2"
  11115. + [(set_attr "type" "shift")])
  11116. +
  11117. +(define_insn "rotrsi3"
  11118. + [(set (match_operand:SI 0 "register_operand" "=r,r")
  11119. + (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
  11120. + (match_operand:SI 2 "register_operand" "r,r")))]
  11121. + ""
  11122. + "ror\\t%0, %1, %2"
  11123. + [(set_attr "type" "shift")])
  11124. +
  11125. +(define_insn "*shift_mul_constants"
  11126. + [(set (match_operand:SI 0 "register_operand" "=r")
  11127. + (ashift:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
  11128. + (match_operand:SI 2 "const_int_operand" "I"))
  11129. + (match_operand:SI 3 "const_int_operand" "I")))]
  11130. + "TARGET_HAS_MUL && SMALL_INT (INTVAL (operands[2]) << INTVAL (operands[3]))"
  11131. +{
  11132. + HOST_WIDE_INT mul = INTVAL (operands[2]) << INTVAL (operands[3]);
  11133. + rtx ops[3];
  11134. +
  11135. + ops[0] = operands[0];
  11136. + ops[1] = operands[1];
  11137. + ops[2] = GEN_INT (mul);
  11138. +
  11139. + output_asm_insn ("muli\t%0, %1, %2", ops);
  11140. + return "";
  11141. +}
  11142. + [(set_attr "type" "mul")])
  11143. +
  11144. +
  11145. +
  11146. +
  11147. +;*****************************************************************************
  11148. +;*
  11149. +;* Converting between floating point and fixed point
  11150. +;*
  11151. +;*****************************************************************************
  11152. +(define_insn "floatsisf2"
  11153. + [(set (match_operand:SF 0 "register_operand" "=r")
  11154. + (float:SF (match_operand:SI 1 "register_operand" "r")))]
  11155. + "nios2_fpu_insns[nios2_fpu_floatsisf2].N >= 0"
  11156. + {
  11157. + return (*nios2_fpu_insns[nios2_fpu_floatsisf2].output) (insn);
  11158. + }
  11159. + [(set_attr "type" "custom")])
  11160. +
  11161. +(define_insn "floatsidf2"
  11162. + [(set (match_operand:DF 0 "register_operand" "=r")
  11163. + (float:DF (match_operand:SI 1 "register_operand" "r")))]
  11164. + "nios2_fpu_insns[nios2_fpu_floatsidf2].N >= 0"
  11165. + {
  11166. + return (*nios2_fpu_insns[nios2_fpu_floatsidf2].output) (insn);
  11167. + }
  11168. + [(set_attr "type" "custom")])
  11169. +
  11170. +(define_insn "floatunssisf2"
  11171. + [(set (match_operand:SF 0 "register_operand" "=r")
  11172. + (unsigned_float:SF (match_operand:SI 1 "register_operand" "r")))]
  11173. + "nios2_fpu_insns[nios2_fpu_floatunssisf2].N >= 0"
  11174. + {
  11175. + return (*nios2_fpu_insns[nios2_fpu_floatunssisf2].output) (insn);
  11176. + }
  11177. + [(set_attr "type" "custom")])
  11178. +
  11179. +(define_insn "floatunssidf2"
  11180. + [(set (match_operand:DF 0 "register_operand" "=r")
  11181. + (unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))]
  11182. + "nios2_fpu_insns[nios2_fpu_floatunssidf2].N >= 0"
  11183. + {
  11184. + return (*nios2_fpu_insns[nios2_fpu_floatunssidf2].output) (insn);
  11185. + }
  11186. + [(set_attr "type" "custom")])
  11187. +
  11188. +(define_insn "fixsfsi2"
  11189. + [(set (match_operand:SI 0 "register_operand" "=r")
  11190. + (fix:SI (match_operand:SF 1 "general_operand" "r")))]
  11191. + "nios2_fpu_insns[nios2_fpu_fixsfsi2].N >= 0"
  11192. + {
  11193. + return (*nios2_fpu_insns[nios2_fpu_fixsfsi2].output) (insn);
  11194. + }
  11195. + [(set_attr "type" "custom")])
  11196. +
  11197. +(define_insn "fixdfsi2"
  11198. + [(set (match_operand:SI 0 "register_operand" "=r")
  11199. + (fix:SI (match_operand:DF 1 "general_operand" "r")))]
  11200. + "nios2_fpu_insns[nios2_fpu_fixdfsi2].N >= 0"
  11201. + {
  11202. + return (*nios2_fpu_insns[nios2_fpu_fixdfsi2].output) (insn);
  11203. + }
  11204. + [(set_attr "type" "custom")])
  11205. +
  11206. +(define_insn "fixunssfsi2"
  11207. + [(set (match_operand:SI 0 "register_operand" "=r")
  11208. + (unsigned_fix:SI (match_operand:SF 1 "general_operand" "r")))]
  11209. + "nios2_fpu_insns[nios2_fpu_fixunssfsi2].N >= 0"
  11210. + {
  11211. + return (*nios2_fpu_insns[nios2_fpu_fixunssfsi2].output) (insn);
  11212. + }
  11213. + [(set_attr "type" "custom")])
  11214. +
  11215. +(define_insn "fixunsdfsi2"
  11216. + [(set (match_operand:SI 0 "register_operand" "=r")
  11217. + (unsigned_fix:SI (match_operand:DF 1 "general_operand" "r")))]
  11218. + "nios2_fpu_insns[nios2_fpu_fixunsdfsi2].N >= 0"
  11219. + {
  11220. + return (*nios2_fpu_insns[nios2_fpu_fixunsdfsi2].output) (insn);
  11221. + }
  11222. + [(set_attr "type" "custom")])
  11223. +
  11224. +(define_insn "extendsfdf2"
  11225. + [(set (match_operand:DF 0 "register_operand" "=r")
  11226. + (float_extend:DF (match_operand:SF 1 "general_operand" "r")))]
  11227. + "nios2_fpu_insns[nios2_fpu_extendsfdf2].N >= 0"
  11228. + {
  11229. + return (*nios2_fpu_insns[nios2_fpu_extendsfdf2].output) (insn);
  11230. + }
  11231. + [(set_attr "type" "custom")])
  11232. +
  11233. +(define_insn "truncdfsf2"
  11234. + [(set (match_operand:SF 0 "register_operand" "=r")
  11235. + (float_truncate:SF (match_operand:DF 1 "general_operand" "r")))]
  11236. + "nios2_fpu_insns[nios2_fpu_truncdfsf2].N >= 0"
  11237. + {
  11238. + return (*nios2_fpu_insns[nios2_fpu_truncdfsf2].output) (insn);
  11239. + }
  11240. + [(set_attr "type" "custom")])
  11241. +
  11242. +
  11243. +
  11244. +
  11245. +
  11246. +
  11247. +
  11248. +
  11249. +;*****************************************************************************
  11250. +;*
  11251. +;* Prologue, Epilogue and Return
  11252. +;*
  11253. +;*****************************************************************************
  11254. +
  11255. +(define_expand "prologue"
  11256. + [(const_int 1)]
  11257. + ""
  11258. +{
  11259. + expand_prologue ();
  11260. + DONE;
  11261. +})
  11262. +
  11263. +(define_expand "epilogue"
  11264. + [(return)]
  11265. + ""
  11266. +{
  11267. + expand_epilogue (false);
  11268. + DONE;
  11269. +})
  11270. +
  11271. +(define_expand "sibcall_epilogue"
  11272. + [(return)]
  11273. + ""
  11274. +{
  11275. + expand_epilogue (true);
  11276. + DONE;
  11277. +})
  11278. +
  11279. +(define_insn "return"
  11280. + [(return)]
  11281. + "reload_completed && nios2_can_use_return_insn ()"
  11282. + "ret\\t"
  11283. +)
  11284. +
  11285. +(define_insn "return_from_epilogue"
  11286. + [(use (match_operand 0 "pmode_register_operand" ""))
  11287. + (return)]
  11288. + "reload_completed"
  11289. + "ret\\t"
  11290. +)
  11291. +
  11292. +;; Block any insns from being moved before this point, since the
  11293. +;; profiling call to mcount can use various registers that aren't
  11294. +;; saved or used to pass arguments.
  11295. +
  11296. +(define_insn "blockage"
  11297. + [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
  11298. + ""
  11299. + ""
  11300. + [(set_attr "type" "unknown")
  11301. + (set_attr "length" "0")])
  11302. +
  11303. +
  11304. +
  11305. +;*****************************************************************************
  11306. +;*
  11307. +;* Jumps and Calls
  11308. +;*
  11309. +;*****************************************************************************
  11310. +
  11311. +(define_insn "indirect_jump"
  11312. + [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
  11313. + ""
  11314. + "jmp\\t%0"
  11315. + [(set_attr "type" "control")])
  11316. +
  11317. +(define_insn "jump"
  11318. + [(set (pc)
  11319. + (label_ref (match_operand 0 "" "")))]
  11320. + ""
  11321. + "br\\t%0"
  11322. + [(set_attr "type" "control")])
  11323. +
  11324. +
  11325. +(define_insn "indirect_call"
  11326. + [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
  11327. + (match_operand 1 "" ""))
  11328. + (clobber (reg:SI RA_REGNO))]
  11329. + ""
  11330. + "callr\\t%0"
  11331. + [(set_attr "type" "control")])
  11332. +
  11333. +(define_insn "indirect_call_value"
  11334. + [(set (match_operand 0 "" "")
  11335. + (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
  11336. + (match_operand 2 "" "")))
  11337. + (clobber (reg:SI RA_REGNO))]
  11338. + ""
  11339. + "callr\\t%1"
  11340. +)
  11341. +
  11342. +(define_expand "call"
  11343. + [(parallel [(call (match_operand 0 "" "")
  11344. + (match_operand 1 "" ""))
  11345. + (clobber (reg:SI RA_REGNO))])]
  11346. + ""
  11347. + "")
  11348. +
  11349. +(define_expand "call_value"
  11350. + [(parallel [(set (match_operand 0 "" "")
  11351. + (call (match_operand 1 "" "")
  11352. + (match_operand 2 "" "")))
  11353. + (clobber (reg:SI RA_REGNO))])]
  11354. + ""
  11355. + "")
  11356. +
  11357. +(define_insn "*call"
  11358. + [(call (mem:QI (match_operand:SI 0 "immediate_operand" "i"))
  11359. + (match_operand 1 "" ""))
  11360. + (clobber (match_operand:SI 2 "register_operand" "=r"))]
  11361. + ""
  11362. + "call\\t%0"
  11363. + [(set_attr "type" "control")])
  11364. +
  11365. +(define_insn "*call_value"
  11366. + [(set (match_operand 0 "" "")
  11367. + (call (mem:QI (match_operand:SI 1 "immediate_operand" "i"))
  11368. + (match_operand 2 "" "")))
  11369. + (clobber (match_operand:SI 3 "register_operand" "=r"))]
  11370. + ""
  11371. + "call\\t%1"
  11372. + [(set_attr "type" "control")])
  11373. +
  11374. +(define_expand "sibcall"
  11375. + [(parallel [(call (match_operand 0 "" "")
  11376. + (match_operand 1 "" ""))
  11377. + (return)
  11378. + (use (match_operand 2 "" ""))])]
  11379. + ""
  11380. + {
  11381. + XEXP (operands[0], 0) = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
  11382. +
  11383. + if (operands[2] == NULL_RTX)
  11384. + operands[2] = const0_rtx;
  11385. + }
  11386. +)
  11387. +
  11388. +(define_expand "sibcall_value"
  11389. + [(parallel [(set (match_operand 0 "" "")
  11390. + (call (match_operand 1 "" "")
  11391. + (match_operand 2 "" "")))
  11392. + (return)
  11393. + (use (match_operand 3 "" ""))])]
  11394. + ""
  11395. + {
  11396. + XEXP (operands[1], 0) = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
  11397. +
  11398. + if (operands[3] == NULL_RTX)
  11399. + operands[3] = const0_rtx;
  11400. + }
  11401. +)
  11402. +
  11403. +(define_insn "sibcall_insn"
  11404. + [(call (mem:QI (match_operand:SI 0 "register_operand" "D08"))
  11405. + (match_operand 1 "" ""))
  11406. + (return)
  11407. + (use (match_operand 2 "" ""))]
  11408. + ""
  11409. + "jmp\\t%0"
  11410. +)
  11411. +
  11412. +(define_insn "sibcall_value_insn"
  11413. + [(set (match_operand 0 "register_operand" "")
  11414. + (call (mem:QI (match_operand:SI 1 "register_operand" "D08"))
  11415. + (match_operand 2 "" "")))
  11416. + (return)
  11417. + (use (match_operand 3 "" ""))]
  11418. + ""
  11419. + "jmp\\t%1"
  11420. +)
  11421. +
  11422. +
  11423. +
  11424. +
  11425. +(define_expand "tablejump"
  11426. + [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
  11427. + (use (label_ref (match_operand 1 "" "")))])]
  11428. + ""
  11429. + ""
  11430. +)
  11431. +
  11432. +(define_insn "*tablejump"
  11433. + [(set (pc)
  11434. + (match_operand:SI 0 "register_operand" "r"))
  11435. + (use (label_ref (match_operand 1 "" "")))]
  11436. + ""
  11437. + "jmp\\t%0"
  11438. + [(set_attr "type" "control")])
  11439. +
  11440. +
  11441. +
  11442. +;*****************************************************************************
  11443. +;*
  11444. +;* Comparisons
  11445. +;*
  11446. +;*****************************************************************************
  11447. +;; Flow here is rather complex (based on MIPS):
  11448. +;;
  11449. +;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
  11450. +;; arguments into the branch_cmp array, and the type into
  11451. +;; branch_type. No RTL is generated.
  11452. +;;
  11453. +;; 2) The appropriate branch define_expand is called, which then
  11454. +;; creates the appropriate RTL for the comparison and branch.
  11455. +;; Different CC modes are used, based on what type of branch is
  11456. +;; done, so that we can constrain things appropriately. There
  11457. +;; are assumptions in the rest of GCC that break if we fold the
  11458. +;; operands into the branchs for integer operations, and use cc0
  11459. +;; for floating point, so we use the fp status register instead.
  11460. +;; If needed, an appropriate temporary is created to hold the
  11461. +;; of the integer compare.
  11462. +
  11463. +(define_expand "cmpsi"
  11464. + [(set (cc0)
  11465. + (compare:CC (match_operand:SI 0 "register_operand" "")
  11466. + (match_operand:SI 1 "arith_operand" "")))]
  11467. + ""
  11468. +{
  11469. + branch_cmp[0] = operands[0];
  11470. + branch_cmp[1] = operands[1];
  11471. + branch_type = CMP_SI;
  11472. + DONE;
  11473. +})
  11474. +
  11475. +(define_expand "tstsi"
  11476. + [(set (cc0)
  11477. + (match_operand:SI 0 "register_operand" ""))]
  11478. + ""
  11479. +{
  11480. + branch_cmp[0] = operands[0];
  11481. + branch_cmp[1] = const0_rtx;
  11482. + branch_type = CMP_SI;
  11483. + DONE;
  11484. +})
  11485. +
  11486. +(define_expand "cmpsf"
  11487. + [(set (cc0)
  11488. + (compare:CC (match_operand:SF 0 "register_operand" "")
  11489. + (match_operand:SF 1 "register_operand" "")))]
  11490. + "(nios2_fpu_insns[nios2_fpu_nios2_sltsf].N >= 0
  11491. + || nios2_fpu_insns[nios2_fpu_nios2_sgtsf].N >= 0)
  11492. + && (nios2_fpu_insns[nios2_fpu_nios2_sgesf].N >= 0
  11493. + || nios2_fpu_insns[nios2_fpu_nios2_slesf].N >= 0)
  11494. + && nios2_fpu_insns[nios2_fpu_nios2_seqsf].N >= 0
  11495. + && nios2_fpu_insns[nios2_fpu_nios2_snesf].N >= 0"
  11496. +{
  11497. + branch_cmp[0] = operands[0];
  11498. + branch_cmp[1] = operands[1];
  11499. + branch_type = CMP_SF;
  11500. + DONE;
  11501. +})
  11502. +
  11503. +(define_expand "cmpdf"
  11504. + [(set (cc0)
  11505. + (compare:CC (match_operand:DF 0 "register_operand" "")
  11506. + (match_operand:DF 1 "register_operand" "")))]
  11507. + "(nios2_fpu_insns[nios2_fpu_nios2_sltdf].N >= 0
  11508. + || nios2_fpu_insns[nios2_fpu_nios2_sgtdf].N >= 0)
  11509. + && (nios2_fpu_insns[nios2_fpu_nios2_sgedf].N >= 0
  11510. + || nios2_fpu_insns[nios2_fpu_nios2_sledf].N >= 0)
  11511. + && nios2_fpu_insns[nios2_fpu_nios2_seqdf].N >= 0
  11512. + && nios2_fpu_insns[nios2_fpu_nios2_snedf].N >= 0"
  11513. +{
  11514. + branch_cmp[0] = operands[0];
  11515. + branch_cmp[1] = operands[1];
  11516. + branch_type = CMP_DF;
  11517. + DONE;
  11518. +})
  11519. +
  11520. +
  11521. +;*****************************************************************************
  11522. +;*
  11523. +;* setting a register from a comparison
  11524. +;*
  11525. +;*****************************************************************************
  11526. +
  11527. +(define_expand "seq"
  11528. + [(set (match_operand:SI 0 "register_operand" "=r")
  11529. + (eq:SI (match_dup 1)
  11530. + (match_dup 2)))]
  11531. + ""
  11532. +{
  11533. + if (branch_type != CMP_SI && branch_type != CMP_SF && branch_type != CMP_DF)
  11534. + FAIL;
  11535. +
  11536. + /* set up operands from compare. */
  11537. + operands[1] = branch_cmp[0];
  11538. + operands[2] = branch_cmp[1];
  11539. +
  11540. + gen_int_relational (EQ, operands[0], operands[1], operands[2], NULL_RTX);
  11541. + DONE;
  11542. +})
  11543. +
  11544. +
  11545. +(define_insn "*seq"
  11546. + [(set (match_operand:SI 0 "register_operand" "=r")
  11547. + (eq:SI (match_operand:SI 1 "reg_or_0_operand" "%rM")
  11548. + (match_operand:SI 2 "arith_operand" "rI")))]
  11549. + ""
  11550. + "cmpeq%i2\\t%0, %z1, %z2"
  11551. + [(set_attr "type" "alu")])
  11552. +
  11553. +
  11554. +(define_insn "nios2_seqsf"
  11555. + [(set (match_operand:SI 0 "register_operand" "=r")
  11556. + (eq:SI (match_operand:SF 1 "register_operand" "%r")
  11557. + (match_operand:SF 2 "register_operand" "r")))]
  11558. + "nios2_fpu_insns[nios2_fpu_nios2_seqsf].N >= 0"
  11559. + {
  11560. + return (*nios2_fpu_insns[nios2_fpu_nios2_seqsf].output) (insn);
  11561. + }
  11562. + [(set_attr "type" "custom")])
  11563. +
  11564. +
  11565. +(define_insn "nios2_seqdf"
  11566. + [(set (match_operand:SI 0 "register_operand" "=r")
  11567. + (eq:SI (match_operand:DF 1 "register_operand" "%r")
  11568. + (match_operand:DF 2 "register_operand" "r")))]
  11569. + "nios2_fpu_insns[nios2_fpu_nios2_seqdf].N >= 0"
  11570. + {
  11571. + return (*nios2_fpu_insns[nios2_fpu_nios2_seqdf].output) (insn);
  11572. + }
  11573. + [(set_attr "type" "custom")])
  11574. +
  11575. +
  11576. +(define_expand "sne"
  11577. + [(set (match_operand:SI 0 "register_operand" "=r")
  11578. + (ne:SI (match_dup 1)
  11579. + (match_dup 2)))]
  11580. + ""
  11581. +{
  11582. + if (branch_type != CMP_SI && branch_type != CMP_SF && branch_type != CMP_DF)
  11583. + FAIL;
  11584. +
  11585. + /* set up operands from compare. */
  11586. + operands[1] = branch_cmp[0];
  11587. + operands[2] = branch_cmp[1];
  11588. +
  11589. + gen_int_relational (NE, operands[0], operands[1], operands[2], NULL_RTX);
  11590. + DONE;
  11591. +})
  11592. +
  11593. +
  11594. +(define_insn "*sne"
  11595. + [(set (match_operand:SI 0 "register_operand" "=r")
  11596. + (ne:SI (match_operand:SI 1 "reg_or_0_operand" "%rM")
  11597. + (match_operand:SI 2 "arith_operand" "rI")))]
  11598. + ""
  11599. + "cmpne%i2\\t%0, %z1, %z2"
  11600. + [(set_attr "type" "alu")])
  11601. +
  11602. +
  11603. +(define_insn "nios2_snesf"
  11604. + [(set (match_operand:SI 0 "register_operand" "=r")
  11605. + (ne:SI (match_operand:SF 1 "register_operand" "%r")
  11606. + (match_operand:SF 2 "register_operand" "r")))]
  11607. + "nios2_fpu_insns[nios2_fpu_nios2_snesf].N >= 0"
  11608. + {
  11609. + return (*nios2_fpu_insns[nios2_fpu_nios2_snesf].output) (insn);
  11610. + }
  11611. + [(set_attr "type" "custom")])
  11612. +
  11613. +
  11614. +(define_insn "nios2_snedf"
  11615. + [(set (match_operand:SI 0 "register_operand" "=r")
  11616. + (ne:SI (match_operand:DF 1 "register_operand" "%r")
  11617. + (match_operand:DF 2 "register_operand" "r")))]
  11618. + "nios2_fpu_insns[nios2_fpu_nios2_snedf].N >= 0"
  11619. + {
  11620. + return (*nios2_fpu_insns[nios2_fpu_nios2_snedf].output) (insn);
  11621. + }
  11622. + [(set_attr "type" "custom")])
  11623. +
  11624. +
  11625. +(define_expand "sgt"
  11626. + [(set (match_operand:SI 0 "register_operand" "=r")
  11627. + (gt:SI (match_dup 1)
  11628. + (match_dup 2)))]
  11629. + ""
  11630. +{
  11631. + if (branch_type != CMP_SI && branch_type != CMP_SF && branch_type != CMP_DF)
  11632. + FAIL;
  11633. +
  11634. + /* set up operands from compare. */
  11635. + operands[1] = branch_cmp[0];
  11636. + operands[2] = branch_cmp[1];
  11637. +
  11638. + gen_int_relational (GT, operands[0], operands[1], operands[2], NULL_RTX);
  11639. + DONE;
  11640. +})
  11641. +
  11642. +
  11643. +(define_insn "*sgt"
  11644. + [(set (match_operand:SI 0 "register_operand" "=r")
  11645. + (gt:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
  11646. + (match_operand:SI 2 "reg_or_0_operand" "rM")))]
  11647. + ""
  11648. + "cmplt\\t%0, %z2, %z1"
  11649. + [(set_attr "type" "alu")])
  11650. +
  11651. +
  11652. +(define_insn "nios2_sgtsf"
  11653. + [(set (match_operand:SI 0 "register_operand" "=r")
  11654. + (gt:SI (match_operand:SF 1 "register_operand" "r")
  11655. + (match_operand:SF 2 "register_operand" "r")))]
  11656. + "nios2_fpu_insns[nios2_fpu_nios2_sgtsf].N >= 0"
  11657. + {
  11658. + return (*nios2_fpu_insns[nios2_fpu_nios2_sgtsf].output) (insn);
  11659. + }
  11660. + [(set_attr "type" "custom")])
  11661. +
  11662. +
  11663. +(define_insn "nios2_sgtdf"
  11664. + [(set (match_operand:SI 0 "register_operand" "=r")
  11665. + (gt:SI (match_operand:DF 1 "register_operand" "r")
  11666. + (match_operand:DF 2 "register_operand" "r")))]
  11667. + "nios2_fpu_insns[nios2_fpu_nios2_sgtdf].N >= 0"
  11668. + {
  11669. + return (*nios2_fpu_insns[nios2_fpu_nios2_sgtdf].output) (insn);
  11670. + }
  11671. + [(set_attr "type" "custom")])
  11672. +
  11673. +
  11674. +(define_expand "sge"
  11675. + [(set (match_operand:SI 0 "register_operand" "=r")
  11676. + (ge:SI (match_dup 1)
  11677. + (match_dup 2)))]
  11678. + ""
  11679. +{
  11680. + if (branch_type != CMP_SI && branch_type != CMP_SF && branch_type != CMP_DF)
  11681. + FAIL;
  11682. +
  11683. + /* set up operands from compare. */
  11684. + operands[1] = branch_cmp[0];
  11685. + operands[2] = branch_cmp[1];
  11686. +
  11687. + gen_int_relational (GE, operands[0], operands[1], operands[2], NULL_RTX);
  11688. + DONE;
  11689. +})
  11690. +
  11691. +
  11692. +(define_insn "*sge"
  11693. + [(set (match_operand:SI 0 "register_operand" "=r")
  11694. + (ge:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
  11695. + (match_operand:SI 2 "arith_operand" "rI")))]
  11696. + ""
  11697. + "cmpge%i2\\t%0, %z1, %z2"
  11698. + [(set_attr "type" "alu")])
  11699. +
  11700. +
  11701. +(define_insn "nios2_sgesf"
  11702. + [(set (match_operand:SI 0 "register_operand" "=r")
  11703. + (ge:SI (match_operand:SF 1 "register_operand" "r")
  11704. + (match_operand:SF 2 "register_operand" "r")))]
  11705. + "nios2_fpu_insns[nios2_fpu_nios2_sgesf].N >= 0"
  11706. + {
  11707. + return (*nios2_fpu_insns[nios2_fpu_nios2_sgesf].output) (insn);
  11708. + }
  11709. + [(set_attr "type" "custom")])
  11710. +
  11711. +
  11712. +(define_insn "nios2_sgedf"
  11713. + [(set (match_operand:SI 0 "register_operand" "=r")
  11714. + (ge:SI (match_operand:DF 1 "register_operand" "r")
  11715. + (match_operand:DF 2 "register_operand" "r")))]
  11716. + "nios2_fpu_insns[nios2_fpu_nios2_sgedf].N >= 0"
  11717. + {
  11718. + return (*nios2_fpu_insns[nios2_fpu_nios2_sgedf].output) (insn);
  11719. + }
  11720. + [(set_attr "type" "custom")])
  11721. +
  11722. +
  11723. +(define_expand "sle"
  11724. + [(set (match_operand:SI 0 "register_operand" "=r")
  11725. + (le:SI (match_dup 1)
  11726. + (match_dup 2)))]
  11727. + ""
  11728. +{
  11729. + if (branch_type != CMP_SI && branch_type != CMP_SF && branch_type != CMP_DF)
  11730. + FAIL;
  11731. +
  11732. + /* set up operands from compare. */
  11733. + operands[1] = branch_cmp[0];
  11734. + operands[2] = branch_cmp[1];
  11735. +
  11736. + gen_int_relational (LE, operands[0], operands[1], operands[2], NULL_RTX);
  11737. + DONE;
  11738. +})
  11739. +
  11740. +
  11741. +(define_insn "*sle"
  11742. + [(set (match_operand:SI 0 "register_operand" "=r")
  11743. + (le:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
  11744. + (match_operand:SI 2 "reg_or_0_operand" "rM")))]
  11745. + ""
  11746. + "cmpge\\t%0, %z2, %z1"
  11747. + [(set_attr "type" "alu")])
  11748. +
  11749. +
  11750. +(define_insn "nios2_slesf"
  11751. + [(set (match_operand:SI 0 "register_operand" "=r")
  11752. + (le:SI (match_operand:SF 1 "register_operand" "r")
  11753. + (match_operand:SF 2 "register_operand" "r")))]
  11754. + "nios2_fpu_insns[nios2_fpu_nios2_slesf].N >= 0"
  11755. + {
  11756. + return (*nios2_fpu_insns[nios2_fpu_nios2_slesf].output) (insn);
  11757. + }
  11758. + [(set_attr "type" "custom")])
  11759. +
  11760. +
  11761. +(define_insn "nios2_sledf"
  11762. + [(set (match_operand:SI 0 "register_operand" "=r")
  11763. + (le:SI (match_operand:DF 1 "register_operand" "r")
  11764. + (match_operand:DF 2 "register_operand" "r")))]
  11765. + "nios2_fpu_insns[nios2_fpu_nios2_sledf].N >= 0"
  11766. + {
  11767. + return (*nios2_fpu_insns[nios2_fpu_nios2_sledf].output) (insn);
  11768. + }
  11769. + [(set_attr "type" "custom")])
  11770. +
  11771. +
  11772. +(define_expand "slt"
  11773. + [(set (match_operand:SI 0 "register_operand" "=r")
  11774. + (lt:SI (match_dup 1)
  11775. + (match_dup 2)))]
  11776. + ""
  11777. +{
  11778. + if (branch_type != CMP_SI && branch_type != CMP_SF && branch_type != CMP_DF)
  11779. + FAIL;
  11780. +
  11781. + /* set up operands from compare. */
  11782. + operands[1] = branch_cmp[0];
  11783. + operands[2] = branch_cmp[1];
  11784. +
  11785. + gen_int_relational (LT, operands[0], operands[1], operands[2], NULL_RTX);
  11786. + DONE;
  11787. +})
  11788. +
  11789. +
  11790. +(define_insn "*slt"
  11791. + [(set (match_operand:SI 0 "register_operand" "=r")
  11792. + (lt:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
  11793. + (match_operand:SI 2 "arith_operand" "rI")))]
  11794. + ""
  11795. + "cmplt%i2\\t%0, %z1, %z2"
  11796. + [(set_attr "type" "alu")])
  11797. +
  11798. +
  11799. +(define_insn "nios2_sltsf"
  11800. + [(set (match_operand:SI 0 "register_operand" "=r")
  11801. + (lt:SI (match_operand:SF 1 "register_operand" "r")
  11802. + (match_operand:SF 2 "register_operand" "r")))]
  11803. + "nios2_fpu_insns[nios2_fpu_nios2_sltsf].N >= 0"
  11804. + {
  11805. + return (*nios2_fpu_insns[nios2_fpu_nios2_sltsf].output) (insn);
  11806. + }
  11807. + [(set_attr "type" "custom")])
  11808. +
  11809. +
  11810. +(define_insn "nios2_sltdf"
  11811. + [(set (match_operand:SI 0 "register_operand" "=r")
  11812. + (lt:SI (match_operand:DF 1 "register_operand" "r")
  11813. + (match_operand:DF 2 "register_operand" "r")))]
  11814. + "nios2_fpu_insns[nios2_fpu_nios2_sltdf].N >= 0"
  11815. + {
  11816. + return (*nios2_fpu_insns[nios2_fpu_nios2_sltdf].output) (insn);
  11817. + }
  11818. + [(set_attr "type" "custom")])
  11819. +
  11820. +
  11821. +(define_expand "sgtu"
  11822. + [(set (match_operand:SI 0 "register_operand" "=r")
  11823. + (gtu:SI (match_dup 1)
  11824. + (match_dup 2)))]
  11825. + ""
  11826. +{
  11827. + if (branch_type != CMP_SI)
  11828. + FAIL;
  11829. +
  11830. + /* set up operands from compare. */
  11831. + operands[1] = branch_cmp[0];
  11832. + operands[2] = branch_cmp[1];
  11833. +
  11834. + gen_int_relational (GTU, operands[0], operands[1], operands[2], NULL_RTX);
  11835. + DONE;
  11836. +})
  11837. +
  11838. +
  11839. +(define_insn "*sgtu"
  11840. + [(set (match_operand:SI 0 "register_operand" "=r")
  11841. + (gtu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
  11842. + (match_operand:SI 2 "reg_or_0_operand" "rM")))]
  11843. + ""
  11844. + "cmpltu\\t%0, %z2, %z1"
  11845. + [(set_attr "type" "alu")])
  11846. +
  11847. +
  11848. +(define_expand "sgeu"
  11849. + [(set (match_operand:SI 0 "register_operand" "=r")
  11850. + (geu:SI (match_dup 1)
  11851. + (match_dup 2)))]
  11852. + ""
  11853. +{
  11854. + if (branch_type != CMP_SI)
  11855. + FAIL;
  11856. +
  11857. + /* set up operands from compare. */
  11858. + operands[1] = branch_cmp[0];
  11859. + operands[2] = branch_cmp[1];
  11860. +
  11861. + gen_int_relational (GEU, operands[0], operands[1], operands[2], NULL_RTX);
  11862. + DONE;
  11863. +})
  11864. +
  11865. +
  11866. +(define_insn "*sgeu"
  11867. + [(set (match_operand:SI 0 "register_operand" "=r")
  11868. + (geu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
  11869. + (match_operand:SI 2 "uns_arith_operand" "rJ")))]
  11870. + ""
  11871. + "cmpgeu%i2\\t%0, %z1, %z2"
  11872. + [(set_attr "type" "alu")])
  11873. +
  11874. +(define_expand "sleu"
  11875. + [(set (match_operand:SI 0 "register_operand" "=r")
  11876. + (leu:SI (match_dup 1)
  11877. + (match_dup 2)))]
  11878. + ""
  11879. +{
  11880. + if (branch_type != CMP_SI)
  11881. + FAIL;
  11882. +
  11883. + /* set up operands from compare. */
  11884. + operands[1] = branch_cmp[0];
  11885. + operands[2] = branch_cmp[1];
  11886. +
  11887. + gen_int_relational (LEU, operands[0], operands[1], operands[2], NULL_RTX);
  11888. + DONE;
  11889. +})
  11890. +
  11891. +
  11892. +(define_insn "*sleu"
  11893. + [(set (match_operand:SI 0 "register_operand" "=r")
  11894. + (leu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
  11895. + (match_operand:SI 2 "reg_or_0_operand" "rM")))]
  11896. + ""
  11897. + "cmpgeu\\t%0, %z2, %z1"
  11898. + [(set_attr "type" "alu")])
  11899. +
  11900. +
  11901. +(define_expand "sltu"
  11902. + [(set (match_operand:SI 0 "register_operand" "=r")
  11903. + (ltu:SI (match_dup 1)
  11904. + (match_dup 2)))]
  11905. + ""
  11906. +{
  11907. + if (branch_type != CMP_SI)
  11908. + FAIL;
  11909. +
  11910. + /* set up operands from compare. */
  11911. + operands[1] = branch_cmp[0];
  11912. + operands[2] = branch_cmp[1];
  11913. +
  11914. + gen_int_relational (LTU, operands[0], operands[1], operands[2], NULL_RTX);
  11915. + DONE;
  11916. +})
  11917. +
  11918. +
  11919. +(define_insn "*sltu"
  11920. + [(set (match_operand:SI 0 "register_operand" "=r")
  11921. + (ltu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
  11922. + (match_operand:SI 2 "uns_arith_operand" "rJ")))]
  11923. + ""
  11924. + "cmpltu%i2\\t%0, %z1, %z2"
  11925. + [(set_attr "type" "alu")])
  11926. +
  11927. +
  11928. +
  11929. +
  11930. +;*****************************************************************************
  11931. +;*
  11932. +;* branches
  11933. +;*
  11934. +;*****************************************************************************
  11935. +
  11936. +(define_insn "*cbranch"
  11937. + [(set (pc)
  11938. + (if_then_else
  11939. + (match_operator:SI 0 "comparison_operator"
  11940. + [(match_operand:SI 2 "reg_or_0_operand" "rM")
  11941. + (match_operand:SI 3 "reg_or_0_operand" "rM")])
  11942. + (label_ref (match_operand 1 "" ""))
  11943. + (pc)))]
  11944. + ""
  11945. + "b%0\\t%z2, %z3, %l1"
  11946. + [(set_attr "type" "control")])
  11947. +
  11948. +
  11949. +(define_insn "nios2_cbranch_sf"
  11950. + [(set (pc)
  11951. + (if_then_else
  11952. + (match_operator:SI 0 "comparison_operator"
  11953. + [(match_operand:SF 2 "register_operand" "r")
  11954. + (match_operand:SF 3 "register_operand" "r")])
  11955. + (label_ref (match_operand 1 "" ""))
  11956. + (pc)))]
  11957. + ""
  11958. + {
  11959. + return nios2_output_fpu_insn_cmps (insn, GET_CODE (operands[0]));
  11960. + }
  11961. + [(set_attr "type" "custom")])
  11962. +
  11963. +
  11964. +(define_insn "nios2_cbranch_df"
  11965. + [(set (pc)
  11966. + (if_then_else
  11967. + (match_operator:SI 0 "comparison_operator"
  11968. + [(match_operand:DF 2 "register_operand" "r")
  11969. + (match_operand:DF 3 "register_operand" "r")])
  11970. + (label_ref (match_operand 1 "" ""))
  11971. + (pc)))]
  11972. + ""
  11973. + {
  11974. + return nios2_output_fpu_insn_cmpd (insn, GET_CODE (operands[0]));
  11975. + }
  11976. + [(set_attr "type" "custom")])
  11977. +
  11978. +
  11979. +(define_expand "beq"
  11980. + [(set (pc)
  11981. + (if_then_else (eq:CC (cc0)
  11982. + (const_int 0))
  11983. + (label_ref (match_operand 0 "" ""))
  11984. + (pc)))]
  11985. + ""
  11986. +{
  11987. + gen_int_relational (EQ, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  11988. + DONE;
  11989. +})
  11990. +
  11991. +
  11992. +(define_expand "bne"
  11993. + [(set (pc)
  11994. + (if_then_else (ne:CC (cc0)
  11995. + (const_int 0))
  11996. + (label_ref (match_operand 0 "" ""))
  11997. + (pc)))]
  11998. + ""
  11999. +{
  12000. + gen_int_relational (NE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  12001. + DONE;
  12002. +})
  12003. +
  12004. +
  12005. +(define_expand "bgt"
  12006. + [(set (pc)
  12007. + (if_then_else (gt:CC (cc0)
  12008. + (const_int 0))
  12009. + (label_ref (match_operand 0 "" ""))
  12010. + (pc)))]
  12011. + ""
  12012. +{
  12013. + gen_int_relational (GT, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  12014. + DONE;
  12015. +})
  12016. +
  12017. +(define_expand "bge"
  12018. + [(set (pc)
  12019. + (if_then_else (ge:CC (cc0)
  12020. + (const_int 0))
  12021. + (label_ref (match_operand 0 "" ""))
  12022. + (pc)))]
  12023. + ""
  12024. +{
  12025. + gen_int_relational (GE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  12026. + DONE;
  12027. +})
  12028. +
  12029. +(define_expand "ble"
  12030. + [(set (pc)
  12031. + (if_then_else (le:CC (cc0)
  12032. + (const_int 0))
  12033. + (label_ref (match_operand 0 "" ""))
  12034. + (pc)))]
  12035. + ""
  12036. +{
  12037. + gen_int_relational (LE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  12038. + DONE;
  12039. +})
  12040. +
  12041. +(define_expand "blt"
  12042. + [(set (pc)
  12043. + (if_then_else (lt:CC (cc0)
  12044. + (const_int 0))
  12045. + (label_ref (match_operand 0 "" ""))
  12046. + (pc)))]
  12047. + ""
  12048. +{
  12049. + gen_int_relational (LT, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  12050. + DONE;
  12051. +})
  12052. +
  12053. +
  12054. +(define_expand "bgtu"
  12055. + [(set (pc)
  12056. + (if_then_else (gtu:CC (cc0)
  12057. + (const_int 0))
  12058. + (label_ref (match_operand 0 "" ""))
  12059. + (pc)))]
  12060. + ""
  12061. +{
  12062. + gen_int_relational (GTU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  12063. + DONE;
  12064. +})
  12065. +
  12066. +(define_expand "bgeu"
  12067. + [(set (pc)
  12068. + (if_then_else (geu:CC (cc0)
  12069. + (const_int 0))
  12070. + (label_ref (match_operand 0 "" ""))
  12071. + (pc)))]
  12072. + ""
  12073. +{
  12074. + gen_int_relational (GEU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  12075. + DONE;
  12076. +})
  12077. +
  12078. +(define_expand "bleu"
  12079. + [(set (pc)
  12080. + (if_then_else (leu:CC (cc0)
  12081. + (const_int 0))
  12082. + (label_ref (match_operand 0 "" ""))
  12083. + (pc)))]
  12084. + ""
  12085. +{
  12086. + gen_int_relational (LEU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  12087. + DONE;
  12088. +})
  12089. +
  12090. +(define_expand "bltu"
  12091. + [(set (pc)
  12092. + (if_then_else (ltu:CC (cc0)
  12093. + (const_int 0))
  12094. + (label_ref (match_operand 0 "" ""))
  12095. + (pc)))]
  12096. + ""
  12097. +{
  12098. + gen_int_relational (LTU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  12099. + DONE;
  12100. +})
  12101. +
  12102. +
  12103. +;*****************************************************************************
  12104. +;*
  12105. +;* String and Block Operations
  12106. +;*
  12107. +;*****************************************************************************
  12108. +
  12109. +; ??? This is all really a hack to get Dhrystone to work as fast as possible
  12110. +; things to be fixed:
  12111. +; * let the compiler core handle all of this, for that to work the extra
  12112. +; aliasing needs to be addressed.
  12113. +; * we use three temporary registers for loading and storing to ensure no
  12114. +; ld use stalls, this is excessive, because after the first ld/st only
  12115. +; two are needed. Only two would be needed all the way through if
  12116. +; we could schedule with other code. Consider:
  12117. +; 1 ld $1, 0($src)
  12118. +; 2 ld $2, 4($src)
  12119. +; 3 ld $3, 8($src)
  12120. +; 4 st $1, 0($dest)
  12121. +; 5 ld $1, 12($src)
  12122. +; 6 st $2, 4($src)
  12123. +; 7 etc.
  12124. +; The first store has to wait until 4. If it does not there will be one
  12125. +; cycle of stalling. However, if any other instruction could be placed
  12126. +; between 1 and 4, $3 would not be needed.
  12127. +; * In small we probably don't want to ever do this ourself because there
  12128. +; is no ld use stall.
  12129. +
  12130. +(define_expand "movstrsi"
  12131. + [(parallel [(set (match_operand:BLK 0 "general_operand" "")
  12132. + (match_operand:BLK 1 "general_operand" ""))
  12133. + (use (match_operand:SI 2 "const_int_operand" ""))
  12134. + (use (match_operand:SI 3 "const_int_operand" ""))
  12135. + (clobber (match_scratch:SI 4 "=&r"))
  12136. + (clobber (match_scratch:SI 5 "=&r"))
  12137. + (clobber (match_scratch:SI 6 "=&r"))])]
  12138. + "TARGET_INLINE_MEMCPY"
  12139. +{
  12140. + rtx ld_addr_reg, st_addr_reg;
  12141. +
  12142. + /* If the predicate for op2 fails in expr.c:emit_block_move_via_movstr
  12143. + it trys to copy to a register, but does not re-try the predicate.
  12144. + ??? Intead of fixing expr.c, I fix it here. */
  12145. + if (!const_int_operand (operands[2], SImode))
  12146. + FAIL;
  12147. +
  12148. + /* ??? there are some magic numbers which need to be sorted out here.
  12149. + the basis for them is not increasing code size hugely or going
  12150. + out of range of offset addressing */
  12151. + if (INTVAL (operands[3]) < 4)
  12152. + FAIL;
  12153. + if (!optimize
  12154. + || (optimize_size && INTVAL (operands[2]) > 12)
  12155. + || (optimize < 3 && INTVAL (operands[2]) > 100)
  12156. + || INTVAL (operands[2]) > 200)
  12157. + FAIL;
  12158. +
  12159. + st_addr_reg
  12160. + = replace_equiv_address (operands[0],
  12161. + copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
  12162. + ld_addr_reg
  12163. + = replace_equiv_address (operands[1],
  12164. + copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
  12165. + emit_insn (gen_movstrsi_internal (st_addr_reg, ld_addr_reg,
  12166. + operands[2], operands[3]));
  12167. +
  12168. + DONE;
  12169. +})
  12170. +
  12171. +
  12172. +(define_insn "movstrsi_internal"
  12173. + [(set (match_operand:BLK 0 "memory_operand" "=o")
  12174. + (match_operand:BLK 1 "memory_operand" "o"))
  12175. + (use (match_operand:SI 2 "const_int_operand" "i"))
  12176. + (use (match_operand:SI 3 "const_int_operand" "i"))
  12177. + (clobber (match_scratch:SI 4 "=&r"))
  12178. + (clobber (match_scratch:SI 5 "=&r"))
  12179. + (clobber (match_scratch:SI 6 "=&r"))]
  12180. + "TARGET_INLINE_MEMCPY"
  12181. +{
  12182. + int ld_offset = INTVAL (operands[2]);
  12183. + int ld_len = INTVAL (operands[2]);
  12184. + int ld_reg = 0;
  12185. + rtx ld_addr_reg = XEXP (operands[1], 0);
  12186. + int st_offset = INTVAL (operands[2]);
  12187. + int st_len = INTVAL (operands[2]);
  12188. + int st_reg = 0;
  12189. + rtx st_addr_reg = XEXP (operands[0], 0);
  12190. + int delay_count = 0;
  12191. +
  12192. + /* ops[0] is the address used by the insn
  12193. + ops[1] is the register being loaded or stored */
  12194. + rtx ops[2];
  12195. +
  12196. + if (INTVAL (operands[3]) < 4)
  12197. + abort ();
  12198. +
  12199. + while (ld_offset >= 4)
  12200. + {
  12201. + /* if the load use delay has been met, I can start
  12202. + storing */
  12203. + if (delay_count >= 3)
  12204. + {
  12205. + ops[0] = gen_rtx (MEM, SImode,
  12206. + plus_constant (st_addr_reg, st_len - st_offset));
  12207. + ops[1] = operands[st_reg + 4];
  12208. + output_asm_insn ("stw\t%1, %0", ops);
  12209. +
  12210. + st_reg = (st_reg + 1) % 3;
  12211. + st_offset -= 4;
  12212. + }
  12213. +
  12214. + ops[0] = gen_rtx (MEM, SImode,
  12215. + plus_constant (ld_addr_reg, ld_len - ld_offset));
  12216. + ops[1] = operands[ld_reg + 4];
  12217. + output_asm_insn ("ldw\t%1, %0", ops);
  12218. +
  12219. + ld_reg = (ld_reg + 1) % 3;
  12220. + ld_offset -= 4;
  12221. + delay_count++;
  12222. + }
  12223. +
  12224. + if (ld_offset >= 2)
  12225. + {
  12226. + /* if the load use delay has been met, I can start
  12227. + storing */
  12228. + if (delay_count >= 3)
  12229. + {
  12230. + ops[0] = gen_rtx (MEM, SImode,
  12231. + plus_constant (st_addr_reg, st_len - st_offset));
  12232. + ops[1] = operands[st_reg + 4];
  12233. + output_asm_insn ("stw\t%1, %0", ops);
  12234. +
  12235. + st_reg = (st_reg + 1) % 3;
  12236. + st_offset -= 4;
  12237. + }
  12238. +
  12239. + ops[0] = gen_rtx (MEM, HImode,
  12240. + plus_constant (ld_addr_reg, ld_len - ld_offset));
  12241. + ops[1] = operands[ld_reg + 4];
  12242. + output_asm_insn ("ldh\t%1, %0", ops);
  12243. +
  12244. + ld_reg = (ld_reg + 1) % 3;
  12245. + ld_offset -= 2;
  12246. + delay_count++;
  12247. + }
  12248. +
  12249. + if (ld_offset >= 1)
  12250. + {
  12251. + /* if the load use delay has been met, I can start
  12252. + storing */
  12253. + if (delay_count >= 3)
  12254. + {
  12255. + ops[0] = gen_rtx (MEM, SImode,
  12256. + plus_constant (st_addr_reg, st_len - st_offset));
  12257. + ops[1] = operands[st_reg + 4];
  12258. + output_asm_insn ("stw\t%1, %0", ops);
  12259. +
  12260. + st_reg = (st_reg + 1) % 3;
  12261. + st_offset -= 4;
  12262. + }
  12263. +
  12264. + ops[0] = gen_rtx (MEM, QImode,
  12265. + plus_constant (ld_addr_reg, ld_len - ld_offset));
  12266. + ops[1] = operands[ld_reg + 4];
  12267. + output_asm_insn ("ldb\t%1, %0", ops);
  12268. +
  12269. + ld_reg = (ld_reg + 1) % 3;
  12270. + ld_offset -= 1;
  12271. + delay_count++;
  12272. + }
  12273. +
  12274. + while (st_offset >= 4)
  12275. + {
  12276. + ops[0] = gen_rtx (MEM, SImode,
  12277. + plus_constant (st_addr_reg, st_len - st_offset));
  12278. + ops[1] = operands[st_reg + 4];
  12279. + output_asm_insn ("stw\t%1, %0", ops);
  12280. +
  12281. + st_reg = (st_reg + 1) % 3;
  12282. + st_offset -= 4;
  12283. + }
  12284. +
  12285. + while (st_offset >= 2)
  12286. + {
  12287. + ops[0] = gen_rtx (MEM, HImode,
  12288. + plus_constant (st_addr_reg, st_len - st_offset));
  12289. + ops[1] = operands[st_reg + 4];
  12290. + output_asm_insn ("sth\t%1, %0", ops);
  12291. +
  12292. + st_reg = (st_reg + 1) % 3;
  12293. + st_offset -= 2;
  12294. + }
  12295. +
  12296. + while (st_offset >= 1)
  12297. + {
  12298. + ops[0] = gen_rtx (MEM, QImode,
  12299. + plus_constant (st_addr_reg, st_len - st_offset));
  12300. + ops[1] = operands[st_reg + 4];
  12301. + output_asm_insn ("stb\t%1, %0", ops);
  12302. +
  12303. + st_reg = (st_reg + 1) % 3;
  12304. + st_offset -= 1;
  12305. + }
  12306. +
  12307. + return "";
  12308. +}
  12309. +; ??? lengths are not being used yet, but I will probably forget
  12310. +; to update this once I am using lengths, so set it to something
  12311. +; definetely big enough to cover it. 400 allows for 200 bytes
  12312. +; of motion.
  12313. + [(set_attr "length" "400")])
  12314. +
  12315. +
  12316. +
  12317. +;*****************************************************************************
  12318. +;*
  12319. +;* Custom instructions
  12320. +;*
  12321. +;*****************************************************************************
  12322. +
  12323. +(define_constants [
  12324. + (CUSTOM_N 100)
  12325. + (CUSTOM_NI 101)
  12326. + (CUSTOM_NF 102)
  12327. + (CUSTOM_NP 103)
  12328. + (CUSTOM_NII 104)
  12329. + (CUSTOM_NIF 105)
  12330. + (CUSTOM_NIP 106)
  12331. + (CUSTOM_NFI 107)
  12332. + (CUSTOM_NFF 108)
  12333. + (CUSTOM_NFP 109)
  12334. + (CUSTOM_NPI 110)
  12335. + (CUSTOM_NPF 111)
  12336. + (CUSTOM_NPP 112)
  12337. + (CUSTOM_IN 113)
  12338. + (CUSTOM_INI 114)
  12339. + (CUSTOM_INF 115)
  12340. + (CUSTOM_INP 116)
  12341. + (CUSTOM_INII 117)
  12342. + (CUSTOM_INIF 118)
  12343. + (CUSTOM_INIP 119)
  12344. + (CUSTOM_INFI 120)
  12345. + (CUSTOM_INFF 121)
  12346. + (CUSTOM_INFP 122)
  12347. + (CUSTOM_INPI 123)
  12348. + (CUSTOM_INPF 124)
  12349. + (CUSTOM_INPP 125)
  12350. + (CUSTOM_FN 126)
  12351. + (CUSTOM_FNI 127)
  12352. + (CUSTOM_FNF 128)
  12353. + (CUSTOM_FNP 129)
  12354. + (CUSTOM_FNII 130)
  12355. + (CUSTOM_FNIF 131)
  12356. + (CUSTOM_FNIP 132)
  12357. + (CUSTOM_FNFI 133)
  12358. + (CUSTOM_FNFF 134)
  12359. + (CUSTOM_FNFP 135)
  12360. + (CUSTOM_FNPI 136)
  12361. + (CUSTOM_FNPF 137)
  12362. + (CUSTOM_FNPP 138)
  12363. + (CUSTOM_PN 139)
  12364. + (CUSTOM_PNI 140)
  12365. + (CUSTOM_PNF 141)
  12366. + (CUSTOM_PNP 142)
  12367. + (CUSTOM_PNII 143)
  12368. + (CUSTOM_PNIF 144)
  12369. + (CUSTOM_PNIP 145)
  12370. + (CUSTOM_PNFI 146)
  12371. + (CUSTOM_PNFF 147)
  12372. + (CUSTOM_PNFP 148)
  12373. + (CUSTOM_PNPI 149)
  12374. + (CUSTOM_PNPF 150)
  12375. + (CUSTOM_PNPP 151)
  12376. +])
  12377. +
  12378. +
  12379. +(define_insn "custom_n"
  12380. + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")] CUSTOM_N)]
  12381. + ""
  12382. + "custom\\t%0, zero, zero, zero"
  12383. + [(set_attr "type" "custom")])
  12384. +
  12385. +(define_insn "custom_ni"
  12386. + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  12387. + (match_operand:SI 1 "register_operand" "r")] CUSTOM_NI)]
  12388. + ""
  12389. + "custom\\t%0, zero, %1, zero"
  12390. + [(set_attr "type" "custom")])
  12391. +
  12392. +(define_insn "custom_nf"
  12393. + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  12394. + (match_operand:SF 1 "register_operand" "r")] CUSTOM_NF)]
  12395. + ""
  12396. + "custom\\t%0, zero, %1, zero"
  12397. + [(set_attr "type" "custom")])
  12398. +
  12399. +(define_insn "custom_np"
  12400. + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  12401. + (match_operand:SI 1 "register_operand" "r")] CUSTOM_NP)]
  12402. + ""
  12403. + "custom\\t%0, zero, %1, zero"
  12404. + [(set_attr "type" "custom")])
  12405. +
  12406. +(define_insn "custom_nii"
  12407. + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  12408. + (match_operand:SI 1 "register_operand" "r")
  12409. + (match_operand:SI 2 "register_operand" "r")] CUSTOM_NII)]
  12410. + ""
  12411. + "custom\\t%0, zero, %1, %2"
  12412. + [(set_attr "type" "custom")])
  12413. +
  12414. +(define_insn "custom_nif"
  12415. + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  12416. + (match_operand:SI 1 "register_operand" "r")
  12417. + (match_operand:SF 2 "register_operand" "r")] CUSTOM_NIF)]
  12418. + ""
  12419. + "custom\\t%0, zero, %1, %2"
  12420. + [(set_attr "type" "custom")])
  12421. +
  12422. +(define_insn "custom_nip"
  12423. + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  12424. + (match_operand:SI 1 "register_operand" "r")
  12425. + (match_operand:SI 2 "register_operand" "r")] CUSTOM_NIP)]
  12426. + ""
  12427. + "custom\\t%0, zero, %1, %2"
  12428. + [(set_attr "type" "custom")])
  12429. +
  12430. +(define_insn "custom_nfi"
  12431. + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  12432. + (match_operand:SF 1 "register_operand" "r")
  12433. + (match_operand:SI 2 "register_operand" "r")] CUSTOM_NFI)]
  12434. + ""
  12435. + "custom\\t%0, zero, %1, %2"
  12436. + [(set_attr "type" "custom")])
  12437. +
  12438. +(define_insn "custom_nff"
  12439. + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  12440. + (match_operand:SF 1 "register_operand" "r")
  12441. + (match_operand:SF 2 "register_operand" "r")] CUSTOM_NFF)]
  12442. + ""
  12443. + "custom\\t%0, zero, %1, %2"
  12444. + [(set_attr "type" "custom")])
  12445. +
  12446. +(define_insn "custom_nfp"
  12447. + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  12448. + (match_operand:SF 1 "register_operand" "r")
  12449. + (match_operand:SI 2 "register_operand" "r")] CUSTOM_NFP)]
  12450. + ""
  12451. + "custom\\t%0, zero, %1, %2"
  12452. + [(set_attr "type" "custom")])
  12453. +
  12454. +(define_insn "custom_npi"
  12455. + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  12456. + (match_operand:SI 1 "register_operand" "r")
  12457. + (match_operand:SI 2 "register_operand" "r")] CUSTOM_NPI)]
  12458. + ""
  12459. + "custom\\t%0, zero, %1, %2"
  12460. + [(set_attr "type" "custom")])
  12461. +
  12462. +(define_insn "custom_npf"
  12463. + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  12464. + (match_operand:SI 1 "register_operand" "r")
  12465. + (match_operand:SF 2 "register_operand" "r")] CUSTOM_NPF)]
  12466. + ""
  12467. + "custom\\t%0, zero, %1, %2"
  12468. + [(set_attr "type" "custom")])
  12469. +
  12470. +(define_insn "custom_npp"
  12471. + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  12472. + (match_operand:SI 1 "register_operand" "r")
  12473. + (match_operand:SI 2 "register_operand" "r")] CUSTOM_NPP)]
  12474. + ""
  12475. + "custom\\t%0, zero, %1, %2"
  12476. + [(set_attr "type" "custom")])
  12477. +
  12478. +
  12479. +
  12480. +(define_insn "custom_in"
  12481. + [(set (match_operand:SI 0 "register_operand" "=r")
  12482. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_IN))]
  12483. + ""
  12484. + "custom\\t%1, %0, zero, zero"
  12485. + [(set_attr "type" "custom")])
  12486. +
  12487. +(define_insn "custom_ini"
  12488. + [(set (match_operand:SI 0 "register_operand" "=r")
  12489. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12490. + (match_operand:SI 2 "register_operand" "r")] CUSTOM_INI))]
  12491. + ""
  12492. + "custom\\t%1, %0, %2, zero"
  12493. + [(set_attr "type" "custom")])
  12494. +
  12495. +(define_insn "custom_inf"
  12496. + [(set (match_operand:SI 0 "register_operand" "=r")
  12497. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12498. + (match_operand:SF 2 "register_operand" "r")] CUSTOM_INF))]
  12499. + ""
  12500. + "custom\\t%1, %0, %2, zero"
  12501. + [(set_attr "type" "custom")])
  12502. +
  12503. +(define_insn "custom_inp"
  12504. + [(set (match_operand:SI 0 "register_operand" "=r")
  12505. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12506. + (match_operand:SI 2 "register_operand" "r")] CUSTOM_INP))]
  12507. + ""
  12508. + "custom\\t%1, %0, %2, zero"
  12509. + [(set_attr "type" "custom")])
  12510. +
  12511. +(define_insn "custom_inii"
  12512. + [(set (match_operand:SI 0 "register_operand" "=r")
  12513. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12514. + (match_operand:SI 2 "register_operand" "r")
  12515. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_INII))]
  12516. + ""
  12517. + "custom\\t%1, %0, %2, %3"
  12518. + [(set_attr "type" "custom")])
  12519. +
  12520. +(define_insn "custom_inif"
  12521. + [(set (match_operand:SI 0 "register_operand" "=r")
  12522. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12523. + (match_operand:SI 2 "register_operand" "r")
  12524. + (match_operand:SF 3 "register_operand" "r")] CUSTOM_INIF))]
  12525. + ""
  12526. + "custom\\t%1, %0, %2, %3"
  12527. + [(set_attr "type" "custom")])
  12528. +
  12529. +(define_insn "custom_inip"
  12530. + [(set (match_operand:SI 0 "register_operand" "=r")
  12531. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12532. + (match_operand:SI 2 "register_operand" "r")
  12533. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_INIP))]
  12534. + ""
  12535. + "custom\\t%1, %0, %2, %3"
  12536. + [(set_attr "type" "custom")])
  12537. +
  12538. +(define_insn "custom_infi"
  12539. + [(set (match_operand:SI 0 "register_operand" "=r")
  12540. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12541. + (match_operand:SF 2 "register_operand" "r")
  12542. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_INFI))]
  12543. + ""
  12544. + "custom\\t%1, %0, %2, %3"
  12545. + [(set_attr "type" "custom")])
  12546. +
  12547. +(define_insn "custom_inff"
  12548. + [(set (match_operand:SI 0 "register_operand" "=r")
  12549. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12550. + (match_operand:SF 2 "register_operand" "r")
  12551. + (match_operand:SF 3 "register_operand" "r")] CUSTOM_INFF))]
  12552. + ""
  12553. + "custom\\t%1, %0, %2, %3"
  12554. + [(set_attr "type" "custom")])
  12555. +
  12556. +(define_insn "custom_infp"
  12557. + [(set (match_operand:SI 0 "register_operand" "=r")
  12558. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12559. + (match_operand:SF 2 "register_operand" "r")
  12560. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_INFP))]
  12561. + ""
  12562. + "custom\\t%1, %0, %2, %3"
  12563. + [(set_attr "type" "custom")])
  12564. +
  12565. +(define_insn "custom_inpi"
  12566. + [(set (match_operand:SI 0 "register_operand" "=r")
  12567. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12568. + (match_operand:SI 2 "register_operand" "r")
  12569. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_INPI))]
  12570. + ""
  12571. + "custom\\t%1, %0, %2, %3"
  12572. + [(set_attr "type" "custom")])
  12573. +
  12574. +(define_insn "custom_inpf"
  12575. + [(set (match_operand:SI 0 "register_operand" "=r")
  12576. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12577. + (match_operand:SI 2 "register_operand" "r")
  12578. + (match_operand:SF 3 "register_operand" "r")] CUSTOM_INPF))]
  12579. + ""
  12580. + "custom\\t%1, %0, %2, %3"
  12581. + [(set_attr "type" "custom")])
  12582. +
  12583. +(define_insn "custom_inpp"
  12584. + [(set (match_operand:SI 0 "register_operand" "=r")
  12585. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12586. + (match_operand:SI 2 "register_operand" "r")
  12587. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_INPP))]
  12588. + ""
  12589. + "custom\\t%1, %0, %2, %3"
  12590. + [(set_attr "type" "custom")])
  12591. +
  12592. +
  12593. +
  12594. +
  12595. +
  12596. +(define_insn "custom_fn"
  12597. + [(set (match_operand:SF 0 "register_operand" "=r")
  12598. + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_FN))]
  12599. + ""
  12600. + "custom\\t%1, %0, zero, zero"
  12601. + [(set_attr "type" "custom")])
  12602. +
  12603. +(define_insn "custom_fni"
  12604. + [(set (match_operand:SF 0 "register_operand" "=r")
  12605. + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  12606. + (match_operand:SI 2 "register_operand" "r")] CUSTOM_FNI))]
  12607. + ""
  12608. + "custom\\t%1, %0, %2, zero"
  12609. + [(set_attr "type" "custom")])
  12610. +
  12611. +(define_insn "custom_fnf"
  12612. + [(set (match_operand:SF 0 "register_operand" "=r")
  12613. + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  12614. + (match_operand:SF 2 "register_operand" "r")] CUSTOM_FNF))]
  12615. + ""
  12616. + "custom\\t%1, %0, %2, zero"
  12617. + [(set_attr "type" "custom")])
  12618. +
  12619. +(define_insn "custom_fnp"
  12620. + [(set (match_operand:SF 0 "register_operand" "=r")
  12621. + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  12622. + (match_operand:SI 2 "register_operand" "r")] CUSTOM_FNP))]
  12623. + ""
  12624. + "custom\\t%1, %0, %2, zero"
  12625. + [(set_attr "type" "custom")])
  12626. +
  12627. +(define_insn "custom_fnii"
  12628. + [(set (match_operand:SF 0 "register_operand" "=r")
  12629. + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  12630. + (match_operand:SI 2 "register_operand" "r")
  12631. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNII))]
  12632. + ""
  12633. + "custom\\t%1, %0, %2, %3"
  12634. + [(set_attr "type" "custom")])
  12635. +
  12636. +(define_insn "custom_fnif"
  12637. + [(set (match_operand:SF 0 "register_operand" "=r")
  12638. + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  12639. + (match_operand:SI 2 "register_operand" "r")
  12640. + (match_operand:SF 3 "register_operand" "r")] CUSTOM_FNIF))]
  12641. + ""
  12642. + "custom\\t%1, %0, %2, %3"
  12643. + [(set_attr "type" "custom")])
  12644. +
  12645. +(define_insn "custom_fnip"
  12646. + [(set (match_operand:SF 0 "register_operand" "=r")
  12647. + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  12648. + (match_operand:SI 2 "register_operand" "r")
  12649. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNIP))]
  12650. + ""
  12651. + "custom\\t%1, %0, %2, %3"
  12652. + [(set_attr "type" "custom")])
  12653. +
  12654. +(define_insn "custom_fnfi"
  12655. + [(set (match_operand:SF 0 "register_operand" "=r")
  12656. + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  12657. + (match_operand:SF 2 "register_operand" "r")
  12658. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNFI))]
  12659. + ""
  12660. + "custom\\t%1, %0, %2, %3"
  12661. + [(set_attr "type" "custom")])
  12662. +
  12663. +(define_insn "custom_fnff"
  12664. + [(set (match_operand:SF 0 "register_operand" "=r")
  12665. + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  12666. + (match_operand:SF 2 "register_operand" "r")
  12667. + (match_operand:SF 3 "register_operand" "r")] CUSTOM_FNFF))]
  12668. + ""
  12669. + "custom\\t%1, %0, %2, %3"
  12670. + [(set_attr "type" "custom")])
  12671. +
  12672. +(define_insn "custom_fnfp"
  12673. + [(set (match_operand:SF 0 "register_operand" "=r")
  12674. + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  12675. + (match_operand:SF 2 "register_operand" "r")
  12676. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNFP))]
  12677. + ""
  12678. + "custom\\t%1, %0, %2, %3"
  12679. + [(set_attr "type" "custom")])
  12680. +
  12681. +(define_insn "custom_fnpi"
  12682. + [(set (match_operand:SF 0 "register_operand" "=r")
  12683. + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  12684. + (match_operand:SI 2 "register_operand" "r")
  12685. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNPI))]
  12686. + ""
  12687. + "custom\\t%1, %0, %2, %3"
  12688. + [(set_attr "type" "custom")])
  12689. +
  12690. +(define_insn "custom_fnpf"
  12691. + [(set (match_operand:SF 0 "register_operand" "=r")
  12692. + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  12693. + (match_operand:SI 2 "register_operand" "r")
  12694. + (match_operand:SF 3 "register_operand" "r")] CUSTOM_FNPF))]
  12695. + ""
  12696. + "custom\\t%1, %0, %2, %3"
  12697. + [(set_attr "type" "custom")])
  12698. +
  12699. +(define_insn "custom_fnpp"
  12700. + [(set (match_operand:SF 0 "register_operand" "=r")
  12701. + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  12702. + (match_operand:SI 2 "register_operand" "r")
  12703. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNPP))]
  12704. + ""
  12705. + "custom\\t%1, %0, %2, %3"
  12706. + [(set_attr "type" "custom")])
  12707. +
  12708. +
  12709. +
  12710. +(define_insn "custom_pn"
  12711. + [(set (match_operand:SI 0 "register_operand" "=r")
  12712. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_PN))]
  12713. + ""
  12714. + "custom\\t%1, %0, zero, zero"
  12715. + [(set_attr "type" "custom")])
  12716. +
  12717. +(define_insn "custom_pni"
  12718. + [(set (match_operand:SI 0 "register_operand" "=r")
  12719. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12720. + (match_operand:SI 2 "register_operand" "r")] CUSTOM_PNI))]
  12721. + ""
  12722. + "custom\\t%1, %0, %2, zero"
  12723. + [(set_attr "type" "custom")])
  12724. +
  12725. +(define_insn "custom_pnf"
  12726. + [(set (match_operand:SI 0 "register_operand" "=r")
  12727. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12728. + (match_operand:SF 2 "register_operand" "r")] CUSTOM_PNF))]
  12729. + ""
  12730. + "custom\\t%1, %0, %2, zero"
  12731. + [(set_attr "type" "custom")])
  12732. +
  12733. +(define_insn "custom_pnp"
  12734. + [(set (match_operand:SI 0 "register_operand" "=r")
  12735. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12736. + (match_operand:SI 2 "register_operand" "r")] CUSTOM_PNP))]
  12737. + ""
  12738. + "custom\\t%1, %0, %2, zero"
  12739. + [(set_attr "type" "custom")])
  12740. +
  12741. +(define_insn "custom_pnii"
  12742. + [(set (match_operand:SI 0 "register_operand" "=r")
  12743. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12744. + (match_operand:SI 2 "register_operand" "r")
  12745. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNII))]
  12746. + ""
  12747. + "custom\\t%1, %0, %2, %3"
  12748. + [(set_attr "type" "custom")])
  12749. +
  12750. +(define_insn "custom_pnif"
  12751. + [(set (match_operand:SI 0 "register_operand" "=r")
  12752. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12753. + (match_operand:SI 2 "register_operand" "r")
  12754. + (match_operand:SF 3 "register_operand" "r")] CUSTOM_PNIF))]
  12755. + ""
  12756. + "custom\\t%1, %0, %2, %3"
  12757. + [(set_attr "type" "custom")])
  12758. +
  12759. +(define_insn "custom_pnip"
  12760. + [(set (match_operand:SI 0 "register_operand" "=r")
  12761. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12762. + (match_operand:SI 2 "register_operand" "r")
  12763. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNIP))]
  12764. + ""
  12765. + "custom\\t%1, %0, %2, %3"
  12766. + [(set_attr "type" "custom")])
  12767. +
  12768. +(define_insn "custom_pnfi"
  12769. + [(set (match_operand:SI 0 "register_operand" "=r")
  12770. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12771. + (match_operand:SF 2 "register_operand" "r")
  12772. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNFI))]
  12773. + ""
  12774. + "custom\\t%1, %0, %2, %3"
  12775. + [(set_attr "type" "custom")])
  12776. +
  12777. +(define_insn "custom_pnff"
  12778. + [(set (match_operand:SI 0 "register_operand" "=r")
  12779. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12780. + (match_operand:SF 2 "register_operand" "r")
  12781. + (match_operand:SF 3 "register_operand" "r")] CUSTOM_PNFF))]
  12782. + ""
  12783. + "custom\\t%1, %0, %2, %3"
  12784. + [(set_attr "type" "custom")])
  12785. +
  12786. +(define_insn "custom_pnfp"
  12787. + [(set (match_operand:SI 0 "register_operand" "=r")
  12788. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12789. + (match_operand:SF 2 "register_operand" "r")
  12790. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNFP))]
  12791. + ""
  12792. + "custom\\t%1, %0, %2, %3"
  12793. + [(set_attr "type" "custom")])
  12794. +
  12795. +(define_insn "custom_pnpi"
  12796. + [(set (match_operand:SI 0 "register_operand" "=r")
  12797. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12798. + (match_operand:SI 2 "register_operand" "r")
  12799. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNPI))]
  12800. + ""
  12801. + "custom\\t%1, %0, %2, %3"
  12802. + [(set_attr "type" "custom")])
  12803. +
  12804. +(define_insn "custom_pnpf"
  12805. + [(set (match_operand:SI 0 "register_operand" "=r")
  12806. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12807. + (match_operand:SI 2 "register_operand" "r")
  12808. + (match_operand:SF 3 "register_operand" "r")] CUSTOM_PNPF))]
  12809. + ""
  12810. + "custom\\t%1, %0, %2, %3"
  12811. + [(set_attr "type" "custom")])
  12812. +
  12813. +(define_insn "custom_pnpp"
  12814. + [(set (match_operand:SI 0 "register_operand" "=r")
  12815. + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  12816. + (match_operand:SI 2 "register_operand" "r")
  12817. + (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNPP))]
  12818. + ""
  12819. + "custom\\t%1, %0, %2, %3"
  12820. + [(set_attr "type" "custom")])
  12821. +
  12822. +
  12823. +
  12824. +
  12825. +
  12826. +
  12827. +;*****************************************************************************
  12828. +;*
  12829. +;* Misc
  12830. +;*
  12831. +;*****************************************************************************
  12832. +
  12833. +(define_insn "nop"
  12834. + [(const_int 0)]
  12835. + ""
  12836. + "nop\\t"
  12837. + [(set_attr "type" "alu")])
  12838. +
  12839. +(define_insn "sync"
  12840. + [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
  12841. + ""
  12842. + "sync\\t"
  12843. + [(set_attr "type" "control")])
  12844. +
  12845. +
  12846. +(define_insn "rdctl"
  12847. + [(set (match_operand:SI 0 "register_operand" "=r")
  12848. + (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")] UNSPEC_RDCTL))]
  12849. + ""
  12850. + "rdctl\\t%0, ctl%1"
  12851. + [(set_attr "type" "control")])
  12852. +
  12853. +(define_insn "wrctl"
  12854. + [(unspec_volatile:SI [(match_operand:SI 0 "rdwrctl_operand" "O")
  12855. + (match_operand:SI 1 "reg_or_0_operand" "rM")] UNSPEC_WRCTL)]
  12856. + ""
  12857. + "wrctl\\tctl%0, %z1"
  12858. + [(set_attr "type" "control")])
  12859. +
  12860. +;Used to signal a stack overflow
  12861. +(define_insn "trap"
  12862. + [(unspec_volatile [(const_int 0)] UNSPEC_TRAP)]
  12863. + ""
  12864. + "break\\t3"
  12865. + [(set_attr "type" "control")])
  12866. +
  12867. +(define_insn "stack_overflow_detect_and_trap"
  12868. + [(unspec_volatile [(const_int 0)] UNSPEC_STACK_OVERFLOW_DETECT_AND_TRAP)]
  12869. + ""
  12870. + "bgeu\\tsp, et, 1f\;break\\t3\;1:"
  12871. + [(set_attr "type" "control")])
  12872. +
  12873. +
  12874. +;*****************************************************************************
  12875. +;*
  12876. +;* Peepholes
  12877. +;*
  12878. +;*****************************************************************************
  12879. +
  12880. +
  12881. +;; Local Variables:
  12882. +;; mode: lisp
  12883. +;; End:
  12884. diff --git a/gcc/config/nios2/t-nios2 b/gcc/config/nios2/t-nios2
  12885. new file mode 100644
  12886. index 0000000..b92f80a
  12887. --- /dev/null
  12888. +++ b/gcc/config/nios2/t-nios2
  12889. @@ -0,0 +1,175 @@
  12890. +##
  12891. +## Compiler flags to use when compiling libgcc2.c.
  12892. +##
  12893. +## LIB2FUNCS_EXTRA
  12894. +## A list of source file names to be compiled or assembled and inserted into libgcc.a.
  12895. +
  12896. +LIB2FUNCS_EXTRA=$(srcdir)/config/nios2/lib2-divmod.c \
  12897. + $(srcdir)/config/nios2/lib2-divmod-hi.c \
  12898. + $(srcdir)/config/nios2/lib2-divtable.c \
  12899. + $(srcdir)/config/nios2/lib2-mul.c
  12900. +
  12901. +##
  12902. +## Floating Point Emulation
  12903. +## To have GCC include software floating point libraries in libgcc.a define FPBIT
  12904. +## and DPBIT along with a few rules as follows:
  12905. +##
  12906. +## # We want fine grained libraries, so use the new code
  12907. +## # to build the floating point emulation libraries.
  12908. +FPBIT=$(srcdir)/config/nios2/nios2-fp-bit.c
  12909. +DPBIT=$(srcdir)/config/nios2/nios2-dp-bit.c
  12910. +
  12911. +TARGET_LIBGCC2_CFLAGS = -O2
  12912. +
  12913. +# FLOAT_ONLY - no doubles
  12914. +# SMALL_MACHINE - QI/HI is faster than SI
  12915. +# Actually SMALL_MACHINE uses chars and shorts instead of ints
  12916. +# since ints (16-bit ones as they are today) are at least as fast
  12917. +# as chars and shorts, don't define SMALL_MACHINE
  12918. +# CMPtype - type returned by FP compare, i.e. INT (hard coded in fp-bit - see code )
  12919. +
  12920. +$(FPBIT): $(srcdir)/config/fp-bit.c Makefile
  12921. + echo '#define FLOAT' > ${FPBIT}
  12922. + echo '#ifndef __nios2_big_endian__' >> ${FPBIT}
  12923. + echo '#define FLOAT_BIT_ORDER_MISMATCH' >> ${FPBIT}
  12924. + echo '#endif' >> ${FPBIT}
  12925. + cat $(srcdir)/config/fp-bit.c >> ${FPBIT}
  12926. +
  12927. +$(DPBIT): $(srcdir)/config/fp-bit.c Makefile
  12928. + echo '' > ${DPBIT}
  12929. + echo '#ifndef __nios2_big_endian__' >> ${DPBIT}
  12930. + echo '#define FLOAT_BIT_ORDER_MISMATCH' >> ${DPBIT}
  12931. + echo '#endif' >> ${DPBIT}
  12932. + cat $(srcdir)/config/fp-bit.c >> ${DPBIT}
  12933. +
  12934. +EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
  12935. +
  12936. +# Assemble startup files.
  12937. +$(T)crti.o: $(srcdir)/config/nios2/crti.asm $(GCC_PASSES)
  12938. + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
  12939. + -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/nios2/crti.asm
  12940. +
  12941. +$(T)crtn.o: $(srcdir)/config/nios2/crtn.asm $(GCC_PASSES)
  12942. + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
  12943. + -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/nios2/crtn.asm
  12944. +
  12945. +
  12946. +## You may need to provide additional #defines at the beginning of
  12947. +## fp-bit.c and dp-bit.c to control target endianness and other options
  12948. +##
  12949. +## CRTSTUFF_T_CFLAGS
  12950. +## Special flags used when compiling crtstuff.c. See Initialization.
  12951. +##
  12952. +## CRTSTUFF_T_CFLAGS_S
  12953. +## Special flags used when compiling crtstuff.c for shared linking. Used
  12954. +## if you use crtbeginS.o and crtendS.o in EXTRA-PARTS. See Initialization.
  12955. +##
  12956. +## MULTILIB_OPTIONS
  12957. +## For some targets, invoking GCC in different ways produces objects that
  12958. +## can not be linked together. For example, for some targets GCC produces
  12959. +## both big and little endian code. For these targets, you must arrange
  12960. +## for multiple versions of libgcc.a to be compiled, one for each set of
  12961. +## incompatible options. When GCC invokes the linker, it arranges to link
  12962. +## in the right version of libgcc.a, based on the command line options
  12963. +## used.
  12964. +## The MULTILIB_OPTIONS macro lists the set of options for which special
  12965. +## versions of libgcc.a must be built. Write options that are mutually
  12966. +## incompatible side by side, separated by a slash. Write options that may
  12967. +## be used together separated by a space. The build procedure will build
  12968. +## all combinations of compatible options.
  12969. +##
  12970. +## For example, if you set MULTILIB_OPTIONS to m68000/m68020 msoft-float,
  12971. +## Makefile will build special versions of libgcc.a using the following
  12972. +## sets of options: -m68000, -m68020, -msoft-float, -m68000 -msoft-float,
  12973. +## and -m68020 -msoft-float.
  12974. +
  12975. +
  12976. +## The BUILD_BE_MULTILIB and BUILD_PG_MULTILIB variables allow the
  12977. +## makefile user to enable/disable the generation of the precompiled
  12978. +## big endian and profiling libraries. By default, the big endian
  12979. +## libraries are not created on a windows build and the profiling
  12980. +## libraries are not created on a Solaris build. All other library
  12981. +## combinations are created by default.
  12982. +
  12983. +# Uncomment to temporarily avoid building big endian and profiling libraries during a Windows build.
  12984. +#ifeq ($(DEV_HOST_OS), win32)
  12985. +#BUILD_BE_MULTILIB ?= 0
  12986. +#BUILD_PG_MULTILIB ?= 0
  12987. +#endif
  12988. +
  12989. +#By default, avoid building the profiling libraries during a Solaris build.
  12990. +ifeq ($(DEV_HOST_OS), solaris)
  12991. +BUILD_PG_MULTILIB ?= 0
  12992. +endif
  12993. +
  12994. +BUILD_BE_MULTILIB ?= 1
  12995. +BUILD_PG_MULTILIB ?= 1
  12996. +BUILD_MULTILIB ?= 1
  12997. +
  12998. +ifeq ($(BUILD_MULTILIB), 1)
  12999. +
  13000. +MULTILIB_OPTIONS = mno-hw-mul mhw-mulx mstack-check mcustom-fpu-cfg=60-1 mcustom-fpu-cfg=60-2
  13001. +
  13002. +#Add the profiling flag to the multilib variable if required
  13003. +ifeq ($(BUILD_PG_MULTILIB), 1)
  13004. +MULTILIB_OPTIONS += pg
  13005. +endif
  13006. +
  13007. +#Add the big endian flag to the multilib variable if required
  13008. +ifeq ($(BUILD_BE_MULTILIB), 1)
  13009. +MULTILIB_OPTIONS += EB/EL
  13010. +endif
  13011. +
  13012. +endif
  13013. +
  13014. +## MULTILIB_DIRNAMES
  13015. +## If MULTILIB_OPTIONS is used, this variable specifies the directory names
  13016. +## that should be used to hold the various libraries. Write one element in
  13017. +## MULTILIB_DIRNAMES for each element in MULTILIB_OPTIONS. If
  13018. +## MULTILIB_DIRNAMES is not used, the default value will be
  13019. +## MULTILIB_OPTIONS, with all slashes treated as spaces.
  13020. +## For example, if MULTILIB_OPTIONS is set to m68000/m68020 msoft-float,
  13021. +## then the default value of MULTILIB_DIRNAMES is m68000 m68020
  13022. +## msoft-float. You may specify a different value if you desire a
  13023. +## different set of directory names.
  13024. +
  13025. +# MULTILIB_DIRNAMES =
  13026. +
  13027. +## MULTILIB_MATCHES
  13028. +## Sometimes the same option may be written in two different ways. If an
  13029. +## option is listed in MULTILIB_OPTIONS, GCC needs to know about any
  13030. +## synonyms. In that case, set MULTILIB_MATCHES to a list of items of the
  13031. +## form option=option to describe all relevant synonyms. For example,
  13032. +## m68000=mc68000 m68020=mc68020.
  13033. +
  13034. +ifeq ($(BUILD_MULTILIB), 1)
  13035. +ifeq ($(BUILD_BE_MULTILIB), 1)
  13036. +MULTILIB_MATCHES = EL=mel EB=meb
  13037. +endif
  13038. +endif
  13039. +
  13040. +##
  13041. +## MULTILIB_EXCEPTIONS
  13042. +## Sometimes when there are multiple sets of MULTILIB_OPTIONS being
  13043. +## specified, there are combinations that should not be built. In that
  13044. +## case, set MULTILIB_EXCEPTIONS to be all of the switch exceptions in
  13045. +## shell case syntax that should not be built.
  13046. +## For example, in the PowerPC embedded ABI support, it is not desirable to
  13047. +## build libraries compiled with the -mcall-aix option and either of the
  13048. +## -fleading-underscore or -mlittle options at the same time. Therefore
  13049. +## MULTILIB_EXCEPTIONS is set to
  13050. +##
  13051. +## *mcall-aix/*fleading-underscore* *mlittle/*mcall-aix*
  13052. +##
  13053. +
  13054. +ifeq ($(BUILD_MULTILIB), 1)
  13055. +MULTILIB_EXCEPTIONS = *mno-hw-mul/*mhw-mulx* *mcustom-fpu-cfg=60-1/*mcustom-fpu-cfg=60-2*
  13056. +endif
  13057. +
  13058. +##
  13059. +## MULTILIB_EXTRA_OPTS Sometimes it is desirable that when building
  13060. +## multiple versions of libgcc.a certain options should always be passed on
  13061. +## to the compiler. In that case, set MULTILIB_EXTRA_OPTS to be the list
  13062. +## of options to be used for all builds.
  13063. +##
  13064. +
  13065. diff --git a/gcc/config/nios2/t-nios2-uclibc b/gcc/config/nios2/t-nios2-uclibc
  13066. new file mode 100644
  13067. index 0000000..9a303db
  13068. --- /dev/null
  13069. +++ b/gcc/config/nios2/t-nios2-uclibc
  13070. @@ -0,0 +1,152 @@
  13071. +##
  13072. +## Compiler flags to use when compiling libgcc2.c.
  13073. +##
  13074. +## LIB2FUNCS_EXTRA
  13075. +## A list of source file names to be compiled or assembled and inserted into libgcc.a.
  13076. +
  13077. +LIB2FUNCS_EXTRA=$(srcdir)/config/nios2/lib2-divmod.c \
  13078. + $(srcdir)/config/nios2/lib2-divmod-hi.c \
  13079. + $(srcdir)/config/nios2/lib2-divtable.c \
  13080. + $(srcdir)/config/nios2/lib2-mul.c
  13081. +
  13082. +##
  13083. +## Floating Point Emulation
  13084. +## To have GCC include software floating point libraries in libgcc.a define FPBIT
  13085. +## and DPBIT along with a few rules as follows:
  13086. +##
  13087. +## # We want fine grained libraries, so use the new code
  13088. +## # to build the floating point emulation libraries.
  13089. +FPBIT=$(srcdir)/config/nios2/nios2-fp-bit.c
  13090. +DPBIT=$(srcdir)/config/nios2/nios2-dp-bit.c
  13091. +
  13092. +TARGET_LIBGCC2_CFLAGS = -O2
  13093. +
  13094. +# FLOAT_ONLY - no doubles
  13095. +# SMALL_MACHINE - QI/HI is faster than SI
  13096. +# Actually SMALL_MACHINE uses chars and shorts instead of ints
  13097. +# since ints (16-bit ones as they are today) are at least as fast
  13098. +# as chars and shorts, don't define SMALL_MACHINE
  13099. +# CMPtype - type returned by FP compare, i.e. INT (hard coded in fp-bit - see code )
  13100. +
  13101. +$(FPBIT): $(srcdir)/config/fp-bit.c Makefile
  13102. + echo '#define FLOAT' > ${FPBIT}
  13103. + echo '#ifndef __nios2_big_endian__' >> ${FPBIT}
  13104. + echo '#define FLOAT_BIT_ORDER_MISMATCH' >> ${FPBIT}
  13105. + echo '#endif' >> ${FPBIT}
  13106. + cat $(srcdir)/config/fp-bit.c >> ${FPBIT}
  13107. +
  13108. +$(DPBIT): $(srcdir)/config/fp-bit.c Makefile
  13109. + echo '' > ${DPBIT}
  13110. + echo '#ifndef __nios2_big_endian__' >> ${DPBIT}
  13111. + echo '#define FLOAT_BIT_ORDER_MISMATCH' >> ${DPBIT}
  13112. + echo '#endif' >> ${DPBIT}
  13113. + cat $(srcdir)/config/fp-bit.c >> ${DPBIT}
  13114. +
  13115. +EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
  13116. +
  13117. +## You may need to provide additional #defines at the beginning of
  13118. +## fp-bit.c and dp-bit.c to control target endianness and other options
  13119. +##
  13120. +## CRTSTUFF_T_CFLAGS
  13121. +## Special flags used when compiling crtstuff.c. See Initialization.
  13122. +##
  13123. +## CRTSTUFF_T_CFLAGS_S
  13124. +## Special flags used when compiling crtstuff.c for shared linking. Used
  13125. +## if you use crtbeginS.o and crtendS.o in EXTRA-PARTS. See Initialization.
  13126. +##
  13127. +## MULTILIB_OPTIONS
  13128. +## For some targets, invoking GCC in different ways produces objects that
  13129. +## can not be linked together. For example, for some targets GCC produces
  13130. +## both big and little endian code. For these targets, you must arrange
  13131. +## for multiple versions of libgcc.a to be compiled, one for each set of
  13132. +## incompatible options. When GCC invokes the linker, it arranges to link
  13133. +## in the right version of libgcc.a, based on the command line options
  13134. +## used.
  13135. +## The MULTILIB_OPTIONS macro lists the set of options for which special
  13136. +## versions of libgcc.a must be built. Write options that are mutually
  13137. +## incompatible side by side, separated by a slash. Write options that may
  13138. +## be used together separated by a space. The build procedure will build
  13139. +## all combinations of compatible options.
  13140. +##
  13141. +## For example, if you set MULTILIB_OPTIONS to m68000/m68020 msoft-float,
  13142. +## Makefile will build special versions of libgcc.a using the following
  13143. +## sets of options: -m68000, -m68020, -msoft-float, -m68000 -msoft-float,
  13144. +## and -m68020 -msoft-float.
  13145. +
  13146. +
  13147. +## The BUILD_BE_MULTILIB and BUILD_PG_MULTILIB variables allow the
  13148. +## makefile user to enable/disable the generation of the precompiled
  13149. +## big endian and profiling libraries.
  13150. +
  13151. +# By default, avoid building big endian and profiling libraries
  13152. +BUILD_BE_MULTILIB ?= 0
  13153. +BUILD_PG_MULTILIB ?= 0
  13154. +BUILD_MULTILIB ?= 1
  13155. +
  13156. +ifeq ($(BUILD_MULTILIB), 1)
  13157. +
  13158. +MULTILIB_OPTIONS = mno-hw-mul mhw-mulx mstack-check mcustom-fpu-cfg=60-1 mcustom-fpu-cfg=60-2
  13159. +
  13160. +#Add the profiling flag to the multilib variable if required
  13161. +ifeq ($(BUILD_PG_MULTILIB), 1)
  13162. +MULTILIB_OPTIONS += pg
  13163. +endif
  13164. +
  13165. +#Add the big endian flag to the multilib variable if required
  13166. +ifeq ($(BUILD_BE_MULTILIB), 1)
  13167. +MULTILIB_OPTIONS += EB/EL
  13168. +endif
  13169. +
  13170. +endif
  13171. +
  13172. +## MULTILIB_DIRNAMES
  13173. +## If MULTILIB_OPTIONS is used, this variable specifies the directory names
  13174. +## that should be used to hold the various libraries. Write one element in
  13175. +## MULTILIB_DIRNAMES for each element in MULTILIB_OPTIONS. If
  13176. +## MULTILIB_DIRNAMES is not used, the default value will be
  13177. +## MULTILIB_OPTIONS, with all slashes treated as spaces.
  13178. +## For example, if MULTILIB_OPTIONS is set to m68000/m68020 msoft-float,
  13179. +## then the default value of MULTILIB_DIRNAMES is m68000 m68020
  13180. +## msoft-float. You may specify a different value if you desire a
  13181. +## different set of directory names.
  13182. +
  13183. +# MULTILIB_DIRNAMES =
  13184. +
  13185. +## MULTILIB_MATCHES
  13186. +## Sometimes the same option may be written in two different ways. If an
  13187. +## option is listed in MULTILIB_OPTIONS, GCC needs to know about any
  13188. +## synonyms. In that case, set MULTILIB_MATCHES to a list of items of the
  13189. +## form option=option to describe all relevant synonyms. For example,
  13190. +## m68000=mc68000 m68020=mc68020.
  13191. +
  13192. +ifeq ($(BUILD_MULTILIB), 1)
  13193. +ifeq ($(BUILD_BE_MULTILIB), 1)
  13194. +MULTILIB_MATCHES = EL=mel EB=meb
  13195. +endif
  13196. +endif
  13197. +
  13198. +##
  13199. +## MULTILIB_EXCEPTIONS
  13200. +## Sometimes when there are multiple sets of MULTILIB_OPTIONS being
  13201. +## specified, there are combinations that should not be built. In that
  13202. +## case, set MULTILIB_EXCEPTIONS to be all of the switch exceptions in
  13203. +## shell case syntax that should not be built.
  13204. +## For example, in the PowerPC embedded ABI support, it is not desirable to
  13205. +## build libraries compiled with the -mcall-aix option and either of the
  13206. +## -fleading-underscore or -mlittle options at the same time. Therefore
  13207. +## MULTILIB_EXCEPTIONS is set to
  13208. +##
  13209. +## *mcall-aix/*fleading-underscore* *mlittle/*mcall-aix*
  13210. +##
  13211. +
  13212. +ifeq ($(BUILD_MULTILIB), 1)
  13213. +MULTILIB_EXCEPTIONS = *mno-hw-mul/*mhw-mulx* *mcustom-fpu-cfg=60-1/*mcustom-fpu-cfg=60-2*
  13214. +endif
  13215. +
  13216. +##
  13217. +## MULTILIB_EXTRA_OPTS Sometimes it is desirable that when building
  13218. +## multiple versions of libgcc.a certain options should always be passed on
  13219. +## to the compiler. In that case, set MULTILIB_EXTRA_OPTS to be the list
  13220. +## of options to be used for all builds.
  13221. +##
  13222. +
  13223. diff --git a/gcc/cse.c b/gcc/cse.c
  13224. index 72af39a..b36310c 100644
  13225. --- a/gcc/cse.c
  13226. +++ b/gcc/cse.c
  13227. @@ -3134,6 +3134,10 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
  13228. #ifdef FLOAT_STORE_FLAG_VALUE
  13229. REAL_VALUE_TYPE fsfv;
  13230. #endif
  13231. +#ifdef __nios2__
  13232. + if (p->is_const)
  13233. + break;
  13234. +#endif
  13235. /* If the entry isn't valid, skip it. */
  13236. if (! exp_equiv_p (p->exp, p->exp, 1, 0))
  13237. diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
  13238. index 4638645..cdb248d 100644
  13239. --- a/gcc/doc/extend.texi
  13240. +++ b/gcc/doc/extend.texi
  13241. @@ -2488,6 +2488,33 @@ contents of that register. The @code{short_call} attribute always places
  13242. the offset to the function from the call site into the @samp{BL}
  13243. instruction directly.
  13244. +@item reverse_bitfields/no_reverse_bitfields
  13245. +@cindex reverse_bitfields on Altera Nios II
  13246. +This attribute specifies the order of bitfield allocation within a
  13247. +particular struct on Altera's Nios II processor. This overrides both
  13248. +the @option{-mno-reverse-bitfields} and @option{-mreverse-bitfields}
  13249. +switches, as well as any @code{#pragma} that might be present. It is
  13250. +ignored except when present on a struct.
  13251. +
  13252. +@smallexample
  13253. +struct inner
  13254. +@{
  13255. + unsigned int a:1;
  13256. + unsigned int b:31;
  13257. +@} __attribute__ ((reverse_bitfields));
  13258. +
  13259. +union outer
  13260. +@{
  13261. + struct inner inner;
  13262. + unsigned int val;
  13263. +@};
  13264. +
  13265. +@end smallexample
  13266. +
  13267. +will cause a to be allocated overlapping the most significant bit of
  13268. +val, regardless of any @code{#pragma} or compiler switch. See the
  13269. +@option{-mreverse-bitfields} switch for more examples.
  13270. +
  13271. @item function_vector
  13272. @cindex calling functions through the function vector on the H8/300 processors
  13273. Use this attribute on the H8/300, H8/300H, and H8S to indicate that the specified
  13274. @@ -5638,12 +5665,118 @@ to those machines. Generally these generate calls to specific machine
  13275. instructions, but allow the compiler to schedule those calls.
  13276. @menu
  13277. +* Altera Nios II Built-in Functions::
  13278. * Alpha Built-in Functions::
  13279. * ARM Built-in Functions::
  13280. * X86 Built-in Functions::
  13281. * PowerPC AltiVec Built-in Functions::
  13282. @end menu
  13283. +@node Altera Nios II Built-in Functions
  13284. +@subsection Altera Nios II Built-in Functions
  13285. +
  13286. +These built-in functions are available for the Altera Nios II
  13287. +family of processors.
  13288. +
  13289. +The following built-in functions are always available. They
  13290. +all generate the machine instruction that is part of the name.
  13291. +
  13292. +@example
  13293. +int __builtin_ldbio (volatile const void *)
  13294. +int __builtin_ldbuio (volatile const void *)
  13295. +int __builtin_ldhio (volatile const void *)
  13296. +int __builtin_ldhuio (volatile const void *)
  13297. +int __builtin_ldwio (volatile const void *)
  13298. +void __builtin_stbio (volatile void *, int)
  13299. +void __builtin_sthio (volatile void *, int)
  13300. +void __builtin_stwio (volatile void *, int)
  13301. +void __builtin_sync (void)
  13302. +int __builtin_rdctl (int)
  13303. +void __builtin_wrctl (int, int)
  13304. +@end example
  13305. +
  13306. +The following built-in functions are always available. They
  13307. +all generate a Nios II Custom Instruction. The name of the
  13308. +function represents the types that the function takes and
  13309. +returns. The letter before the @code{n} is the return type
  13310. +or void if absent. The @code{n} represnts the first parameter
  13311. +to all the custom instructions, the custom instruction number.
  13312. +The two letters after the @code{n} represent the up to two
  13313. +parameters to the function.
  13314. +
  13315. +The letters reprsent the following data types:
  13316. +@table @code
  13317. +@item <no letter>
  13318. +@code{void} for return type and no parameter for parameter types.
  13319. +
  13320. +@item i
  13321. +@code{int} for return type and parameter type
  13322. +
  13323. +@item f
  13324. +@code{float} for return type and parameter type
  13325. +
  13326. +@item p
  13327. +@code{void *} for return type and parameter type
  13328. +
  13329. +@end table
  13330. +
  13331. +And the function names are:
  13332. +@example
  13333. +void __builtin_custom_n (void)
  13334. +void __builtin_custom_ni (int)
  13335. +void __builtin_custom_nf (float)
  13336. +void __builtin_custom_np (void *)
  13337. +void __builtin_custom_nii (int, int)
  13338. +void __builtin_custom_nif (int, float)
  13339. +void __builtin_custom_nip (int, void *)
  13340. +void __builtin_custom_nfi (float, int)
  13341. +void __builtin_custom_nff (float, float)
  13342. +void __builtin_custom_nfp (float, void *)
  13343. +void __builtin_custom_npi (void *, int)
  13344. +void __builtin_custom_npf (void *, float)
  13345. +void __builtin_custom_npp (void *, void *)
  13346. +int __builtin_custom_in (void)
  13347. +int __builtin_custom_ini (int)
  13348. +int __builtin_custom_inf (float)
  13349. +int __builtin_custom_inp (void *)
  13350. +int __builtin_custom_inii (int, int)
  13351. +int __builtin_custom_inif (int, float)
  13352. +int __builtin_custom_inip (int, void *)
  13353. +int __builtin_custom_infi (float, int)
  13354. +int __builtin_custom_inff (float, float)
  13355. +int __builtin_custom_infp (float, void *)
  13356. +int __builtin_custom_inpi (void *, int)
  13357. +int __builtin_custom_inpf (void *, float)
  13358. +int __builtin_custom_inpp (void *, void *)
  13359. +float __builtin_custom_fn (void)
  13360. +float __builtin_custom_fni (int)
  13361. +float __builtin_custom_fnf (float)
  13362. +float __builtin_custom_fnp (void *)
  13363. +float __builtin_custom_fnii (int, int)
  13364. +float __builtin_custom_fnif (int, float)
  13365. +float __builtin_custom_fnip (int, void *)
  13366. +float __builtin_custom_fnfi (float, int)
  13367. +float __builtin_custom_fnff (float, float)
  13368. +float __builtin_custom_fnfp (float, void *)
  13369. +float __builtin_custom_fnpi (void *, int)
  13370. +float __builtin_custom_fnpf (void *, float)
  13371. +float __builtin_custom_fnpp (void *, void *)
  13372. +void * __builtin_custom_pn (void)
  13373. +void * __builtin_custom_pni (int)
  13374. +void * __builtin_custom_pnf (float)
  13375. +void * __builtin_custom_pnp (void *)
  13376. +void * __builtin_custom_pnii (int, int)
  13377. +void * __builtin_custom_pnif (int, float)
  13378. +void * __builtin_custom_pnip (int, void *)
  13379. +void * __builtin_custom_pnfi (float, int)
  13380. +void * __builtin_custom_pnff (float, float)
  13381. +void * __builtin_custom_pnfp (float, void *)
  13382. +void * __builtin_custom_pnpi (void *, int)
  13383. +void * __builtin_custom_pnpf (void *, float)
  13384. +void * __builtin_custom_pnpp (void *, void *)
  13385. +@end example
  13386. +
  13387. +
  13388. @node Alpha Built-in Functions
  13389. @subsection Alpha Built-in Functions
  13390. @@ -8022,6 +8155,7 @@ we do not recommend the use of pragmas; @xref{Function Attributes},
  13391. for further explanation.
  13392. @menu
  13393. +* Altera Nios II Pragmas::
  13394. * ARM Pragmas::
  13395. * RS/6000 and PowerPC Pragmas::
  13396. * Darwin Pragmas::
  13397. @@ -8029,6 +8163,29 @@ for further explanation.
  13398. * Tru64 Pragmas::
  13399. @end menu
  13400. +@node Altera Nios II Pragmas
  13401. +@subsection Altera Nios II Pragmas
  13402. +
  13403. +The Altera Nios II target defines two pragmas to control the placement
  13404. +of bitfields within a struct.
  13405. +
  13406. +@table @code
  13407. +@item reverse_bitfields
  13408. +@cindex pragma, reverse_bitfields
  13409. +Cause all subsequent structs to behave as though the -mreverse-bitfields
  13410. +compiler switch had been given. Can be overridden by the
  13411. +@code{no_reverse_bitfields} attribute or a subsequent
  13412. +@code{#pragma no_reverse_bitfields}.
  13413. +
  13414. +@item no_reverse_bitfields
  13415. +@cindex pragma, no_reverse_bitfields
  13416. +Cause all subsequent structs to behave as though the -mno-reverse-bitfields
  13417. +compiler switch had been given. Can be overridden by the
  13418. +@code{reverse_bitfields} attribute or a subsequent
  13419. +@code{#pragma reverse_bitfields}.
  13420. +
  13421. +@end table
  13422. +
  13423. @node ARM Pragmas
  13424. @subsection ARM Pragmas
  13425. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
  13426. index e683d0c..b34200f 100644
  13427. --- a/gcc/doc/invoke.texi
  13428. +++ b/gcc/doc/invoke.texi
  13429. @@ -337,6 +337,16 @@ in the following sections.
  13430. @item Machine Dependent Options
  13431. @xref{Submodel Options,,Hardware Models and Configurations}.
  13432. +@emph{Altera Nios II Options}
  13433. +@gccoptlist{-msmallc -mno-bypass-cache -mbypass-cache @gol
  13434. +-mno-cache-volatile -mcache-volatile -mno-inline-memcpy @gol
  13435. +-minline-memcpy -mno-fast-sw-div -mfast-sw-div @gol
  13436. +-mhw-mul -mno-hw-mul -mhw-mulx -mno-hw-mulx @gol
  13437. +-mno-hw-div -mhw-div @gol
  13438. +-mno-stack-check -mstack-check @gol
  13439. +-msys-crt0= -msys-lib= -msys=nosys @gol
  13440. +-mreverse-bitfields -mno-reverse-bitfields}
  13441. +
  13442. @emph{M680x0 Options}
  13443. @gccoptlist{-m68000 -m68020 -m68020-40 -m68020-60 -m68030 -m68040 @gol
  13444. -m68060 -mcpu32 -m5200 -m68881 -mbitfield -mc68000 -mc68020 @gol
  13445. @@ -5839,6 +5849,7 @@ machine description. The default for the options is also defined by
  13446. that macro, which enables you to change the defaults.
  13447. @menu
  13448. +* Altera Nios II Options::
  13449. * M680x0 Options::
  13450. * M68hc1x Options::
  13451. * VAX Options::
  13452. @@ -5874,6 +5885,290 @@ that macro, which enables you to change the defaults.
  13453. * FRV Options::
  13454. @end menu
  13455. +
  13456. +@node Altera Nios II Options
  13457. +@subsection Altera Nios II Options
  13458. +@cindex Altera Nios II options
  13459. +
  13460. +These are the @samp{-m} options defined for the Altera Nios II
  13461. +processor.
  13462. +
  13463. +@table @gcctabopt
  13464. +
  13465. +@item -msmallc
  13466. +@opindex msmallc
  13467. +Link with a limited version of the C library, -lsmallc. For more
  13468. +information see the C Library Documentation.
  13469. +
  13470. +
  13471. +@item -mbypass-cache
  13472. +@itemx -mno-bypass-cache
  13473. +@opindex mno-bypass-cache
  13474. +@opindex mbypass-cache
  13475. +Force all load and store instructions to always bypass cache by
  13476. +using io variants of the instructions. The default is to not
  13477. +bypass the cache.
  13478. +
  13479. +@item -mno-cache-volatile
  13480. +@itemx -mcache-volatile
  13481. +@opindex mcache-volatile
  13482. +@opindex mno-cache-volatile
  13483. +Volatile memory access bypass the cache using the io variants of
  13484. +the ld and st instructions. The default is to cache volatile
  13485. +accesses.
  13486. +
  13487. +-mno-cache-volatile is deprecated and will be deleted in a
  13488. +future GCC release.
  13489. +
  13490. +
  13491. +@item -mno-inline-memcpy
  13492. +@itemx -minline-memcpy
  13493. +@opindex mno-inline-memcpy
  13494. +@opindex minline-memcpy
  13495. +Do not inline memcpy. The default is to inline when -O is on.
  13496. +
  13497. +
  13498. +@item -mno-fast-sw-div
  13499. +@itemx -mfast-sw-div
  13500. +@opindex mno-fast-sw-div
  13501. +@opindex mfast-sw-div
  13502. +Do no use table based fast divide for small numbers. The default
  13503. +is to use the fast divide at -O3 and above.
  13504. +
  13505. +
  13506. +@item -mno-hw-mul
  13507. +@itemx -mhw-mul
  13508. +@itemx -mno-hw-mulx
  13509. +@itemx -mhw-mulx
  13510. +@itemx -mno-hw-div
  13511. +@itemx -mhw-div
  13512. +@opindex mno-hw-mul
  13513. +@opindex mhw-mul
  13514. +@opindex mno-hw-mulx
  13515. +@opindex mhw-mulx
  13516. +@opindex mno-hw-div
  13517. +@opindex mhw-div
  13518. +Enable or disable emitting @code{mul}, @code{mulx} and @code{div} family of
  13519. +instructions by the compiler. The default is to emit @code{mul}
  13520. +and not emit @code{div} and @code{mulx}.
  13521. +
  13522. +The different combinations of @code{mul} and @code{mulx} instructions
  13523. +generate a different multilib options.
  13524. +
  13525. +@item -mno-stack-check
  13526. +@itemx -mstack-check
  13527. +@opindex no-stack-check
  13528. +@opindex stack-check
  13529. +Enables or disables the checking for sufficient memory when
  13530. +items are pushed onto the stack. A checked and non-checked
  13531. +version of each of the multilibs is provided.
  13532. +
  13533. +@item -msys-crt0=@var{startfile}
  13534. +@opindex msys-crt0
  13535. +@var{startfile} is the file name of the startfile (crt0) to use
  13536. +when linking. The default is crt0.o that comes with libgloss
  13537. +and is only suitable for use with the instruction set
  13538. +simulator.
  13539. +
  13540. +@item -msys-lib=@var{systemlib}
  13541. +@itemx -msys-lib=nosys
  13542. +@opindex msys-lib
  13543. +@var{systemlib} is the library name of the library which provides
  13544. +the system calls required by the C library, e.g. @code{read}, @code{write}
  13545. +etc. The default is to use nosys, this library provides
  13546. +stub implementations of the calls and is part of libgloss.
  13547. +
  13548. +@item -mno-reverse-bitfields
  13549. +@itemx -mreverse-bitfields
  13550. +@opindex mno-reverse-bitfields
  13551. +@opindex mreverse-bitfields
  13552. +When enabled, bitfields within a struct are allocated in reverse order.
  13553. +This is useful with legacy code that depends on the (inherently
  13554. +non-portable) ordering of bitfields via a union. Given:
  13555. +
  13556. +@smallexample
  13557. +struct inner
  13558. +@{
  13559. + unsigned int a:1;
  13560. + unsigned int b:31;
  13561. +@};
  13562. +
  13563. +union outer
  13564. +@{
  13565. + struct inner inner;
  13566. + unsigned int val;
  13567. +@};
  13568. +
  13569. +unsigned int f()
  13570. +@{
  13571. + union outer o;
  13572. + o.inner.a = 1;
  13573. + o.inner.b = 0;
  13574. + return o.val;
  13575. +@}
  13576. +@end smallexample
  13577. +
  13578. +a call to @code{f} will return 1 when compiled with
  13579. +@option{-mno-reverse-bitfields} (the default), or 2147483648 when
  13580. +compiled with @option{-mreverse-bitfields}.
  13581. +
  13582. +For structures that are a multiple of 32 bits wide, the reversal is
  13583. +done 32 bits at a time. For structures that are an odd multiple of 16
  13584. +bits wide, the reversal is done 16 bits at a time. For structures
  13585. +that are an odd multiple of 8 bits wide, the reversal is done 8 bits
  13586. +at a time. The size of a structure (as measured by the @code{sizeof}
  13587. +operator) never changes between @option{-mno-reverse-bitfields} and
  13588. +@option{-mreverse-bitfields}. Nonetheless, there can be some
  13589. +confusing corner cases with structs where the compiler has to add
  13590. +additional padding to meet alignment restrictions. Consider:
  13591. +
  13592. +@smallexample
  13593. +struct inner
  13594. +@{
  13595. + unsigned int a:1;
  13596. + unsigned int b:15;
  13597. +@};
  13598. +
  13599. +union outer
  13600. +@{
  13601. + struct inner inner;
  13602. + unsigned int val;
  13603. +@};
  13604. +
  13605. +unsigned int f()
  13606. +@{
  13607. + union outer o;
  13608. + o.val = 0;
  13609. + o.inner.b = 1;
  13610. + return o.val;
  13611. +@}
  13612. +@end smallexample
  13613. +
  13614. +a call to @code{f} will return 2 when compiled with
  13615. +@option{-mno-reverse-bitfields} (the default), or 65536 when compiled
  13616. +with @option{-mreverse-bitfields}. This is because @code{sizeof
  13617. +(inner)} is 4 in both cases. In the @option{-mno-reverse-bitfields}
  13618. +case, the compiler pads the struct at the end to be 4 bytes long,
  13619. +effectively doing:
  13620. +
  13621. +@smallexample
  13622. +struct inner
  13623. +@{
  13624. + unsigned int a:1;
  13625. + unsigned int b:15;
  13626. + unsigned int padding:16;
  13627. +@};
  13628. +@end smallexample
  13629. +
  13630. +In the @option{-mreverse-bitfields} case, the hidden padding is
  13631. +reversed along with everything else, yielding the equivalent of:
  13632. +
  13633. +@smallexample
  13634. +struct inner
  13635. +@{
  13636. + unsigned int padding:16;
  13637. + unsigned int b:15;
  13638. + unsigned int a:1;
  13639. +@};
  13640. +@end smallexample
  13641. +
  13642. +Of course, if we would rather that @code{sizeof (inner)} was 2, we could
  13643. +write the struct as:
  13644. +
  13645. +@smallexample
  13646. +struct inner
  13647. +@{
  13648. + unsigned short a:1;
  13649. + unsigned short b:15;
  13650. +@};
  13651. +@end smallexample
  13652. +
  13653. +and the padding would go away.
  13654. +
  13655. +In some cases, especially when using the @code{__packed__} attribute,
  13656. +there is no well-defined bit reversal that is possible: the compiler
  13657. +will issue an error message in this case. Consider:
  13658. +
  13659. +@smallexample
  13660. +struct invalid
  13661. +@{
  13662. + unsigned int f1:1;
  13663. + unsigned int f2:15;
  13664. + unsigned int f3:4;
  13665. + unsigned int f4:4;
  13666. +@} __attribute__ ((__packed__));
  13667. +@end smallexample
  13668. +
  13669. +Since @code{sizeof (invalid)} is 3, we are forced to try reversing
  13670. +individual bytes in the struct. But f2 is more than a byte wide, so
  13671. +we can't reverse it and still have it be contiguous. Similar cases
  13672. +occur when dealing with arrays or other large contiguous objects:
  13673. +
  13674. +@smallexample
  13675. +struct invalid2
  13676. +@{
  13677. + unsigned char f1[5];
  13678. + unsigned char f2[3];
  13679. +@};
  13680. +@end smallexample
  13681. +
  13682. +You'll have to rewrite the affected structs to say exactly what you
  13683. +mean in odd cases like that.
  13684. +
  13685. +Finally, note that individual fields are sized as a whole. The structs
  13686. +
  13687. +@smallexample
  13688. +struct array1
  13689. +@{
  13690. + unsigned char f1[3];
  13691. + unsigned char f2;
  13692. +@}
  13693. +@end smallexample
  13694. +
  13695. +and:
  13696. +
  13697. +@smallexample
  13698. +struct array2
  13699. +@{
  13700. + unsigned char f1a;
  13701. + unsigned char f1b;
  13702. + unsigned char f1c;
  13703. + unsigned char f2;
  13704. +@}
  13705. +@end smallexample
  13706. +
  13707. +are not equivalent. When compiled with @option{-mreverse-bitfields},
  13708. +they behave the same as:
  13709. +
  13710. +@smallexample
  13711. +struct array1r
  13712. +@{
  13713. + unsigned char f2;
  13714. + unsigned char f1[3];
  13715. +@}
  13716. +@end smallexample
  13717. +
  13718. +and:
  13719. +
  13720. +@smallexample
  13721. +struct array2r
  13722. +@{
  13723. + unsigned char f2;
  13724. + unsigned char f1c;
  13725. + unsigned char f1b;
  13726. + unsigned char f1a;
  13727. +@}
  13728. +@end smallexample
  13729. +
  13730. +would, respectively, when compiled with
  13731. +@option{-mno-reverse-bitfields}. In particular, f1 is treated as a
  13732. +single contiguous 24-bit object for purposes of reversal, while f1a,
  13733. +f1b, and f1c are treated as individual 8-bit objects that need not
  13734. +(and do not) remain contiguous. Use caution.
  13735. +
  13736. +@end table
  13737. +
  13738. +
  13739. @node M680x0 Options
  13740. @subsection M680x0 Options
  13741. @cindex M680x0 options
  13742. diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
  13743. index b73f325..4a134b2 100644
  13744. --- a/gcc/doc/md.texi
  13745. +++ b/gcc/doc/md.texi
  13746. @@ -1337,6 +1337,58 @@ However, here is a summary of the machine-dependent constraints
  13747. available on some particular machines.
  13748. @table @emph
  13749. +
  13750. +@item Altera Nios II family---@file{nios2.h}
  13751. +@table @code
  13752. +
  13753. +@item I
  13754. +Integer that is valid as an immediate operand in an
  13755. +instruction taking a signed 16-bit number. Range
  13756. +@minus{}32768 to 32767.
  13757. +
  13758. +@item J
  13759. +Integer that is valid as an immediate operand in an
  13760. +instruction taking an unsigned 16-bit number. Range
  13761. +0 to 65535.
  13762. +
  13763. +@item K
  13764. +Integer that is valid as an immediate operand in an
  13765. +instruction taking only the upper 16-bits of a
  13766. +32-bit number. Range 32-bit numbers with the lower
  13767. +16-bits being 0.
  13768. +
  13769. +@item L
  13770. +Integer that is valid as an immediate operand for a
  13771. +shift instruction. Range 0 to 31.
  13772. +
  13773. +
  13774. +@item M
  13775. +Integer that is valid as an immediate operand for
  13776. +only the value 0. Can be used in conjunction with
  13777. +the format modifier @code{z} to use @code{r0}
  13778. +instead of @code{0} in the assembly output.
  13779. +
  13780. +@item N
  13781. +Integer that is valid as an immediate operand for
  13782. +a custom instruction opcode. Range 0 to 255.
  13783. +
  13784. +@item S
  13785. +Matches immediates which are addresses in the small
  13786. +data section and therefore can be added to @code{gp}
  13787. +as a 16-bit immediate to re-create their 32-bit value.
  13788. +
  13789. +@item D@var{nn}
  13790. +For a given two digit @var{nn} constrains the operand
  13791. +to the corresponding register. Example: D02 forces the
  13792. +operand into register r2. The side effect of using this
  13793. +operand constraint is that reload may not be able to
  13794. +meet the constraint. If reload fails, an error message
  13795. +about failing to find any register to spill in the
  13796. +D@var{nn}_REG register class will be emitted.
  13797. +
  13798. +@end table
  13799. +
  13800. +
  13801. @item ARM family---@file{arm.h}
  13802. @table @code
  13803. @item f
  13804. diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
  13805. index 4527fe4..e7cc581 100644
  13806. --- a/gcc/stor-layout.c
  13807. +++ b/gcc/stor-layout.c
  13808. @@ -1435,6 +1435,355 @@ finalize_type_size (tree type)
  13809. }
  13810. }
  13811. +static void
  13812. +reverse_bitfield_layout (record_layout_info rli)
  13813. +{
  13814. + tree field;
  13815. + tree rev_size;
  13816. + unsigned int rev_size_int;
  13817. +
  13818. + /*
  13819. + * The size of the words we'll be reversing. Normally, we reverse
  13820. + * entire SImode words. However, if the entire struct's size isn't an
  13821. + * exact multiple of the size of SImode, we can reverse HImode or even
  13822. + * QImode pieces. In the examples below, assume SImode/int is 32
  13823. + * bits, HImode/short is 16 bits, and QImode/char is 8 bits.
  13824. + * Consider:
  13825. + *
  13826. + * struct s1
  13827. + * {
  13828. + * int f1:1;
  13829. + * int f2:31;
  13830. + * };
  13831. + *
  13832. + * struct s2
  13833. + * {
  13834. + * int f1:1;
  13835. + * int f2:15;
  13836. + * } __attribute__ ((__packed__));
  13837. + *
  13838. + * struct s3
  13839. + * {
  13840. + * short f1:1;
  13841. + * short f2:15;
  13842. + * };
  13843. + *
  13844. + * struct s4
  13845. + * {
  13846. + * int f1:1;
  13847. + * int f2:15;
  13848. + * };
  13849. + *
  13850. + * struct s5
  13851. + * {
  13852. + * int f1:8;
  13853. + * int f2:8;
  13854. + * int f3:4;
  13855. + * int f4:4;
  13856. + * } __attribute__ ((__packed__));
  13857. + *
  13858. + * struct s6
  13859. + * {
  13860. + * int f1:1;
  13861. + * int f2:15;
  13862. + * int f3:4;
  13863. + * int f4:4;
  13864. + * int f5:8;
  13865. + * };
  13866. + *
  13867. + * struct s7
  13868. + * {
  13869. + * int f1:1;
  13870. + * int f2:15;
  13871. + * int f3:4;
  13872. + * int f4:4;
  13873. + * } __attribute__ ((__packed__));
  13874. + *
  13875. + * struct s8
  13876. + * {
  13877. + * char f1;
  13878. + * short f2;
  13879. + * char f3;
  13880. + * };
  13881. + *
  13882. + * struct s9
  13883. + * {
  13884. + * char f1;
  13885. + * short f2;
  13886. + * char f3;
  13887. + * } __attribute__ ((__packed__));
  13888. + *
  13889. + * struct s10
  13890. + * {
  13891. + * char f1;
  13892. + * short f2;
  13893. + * char f3;
  13894. + * short f4;
  13895. + * };
  13896. + *
  13897. + * struct s11
  13898. + * {
  13899. + * char f1[5];
  13900. + * int f2;
  13901. + * };
  13902. + *
  13903. + * struct s12
  13904. + * {
  13905. + * char f1[5];
  13906. + * char f2[3];
  13907. + * int f3;
  13908. + * };
  13909. + *
  13910. + * struct s13
  13911. + * {
  13912. + * char f1[3];
  13913. + * int f2;
  13914. + * };
  13915. + *
  13916. + * struct s14
  13917. + * {
  13918. + * char f1a;
  13919. + * char f1b;
  13920. + * char f1c;
  13921. + * int f2;
  13922. + * };
  13923. + *
  13924. + * Then we have:
  13925. + *
  13926. + * sizeof (struct s1) == 4
  13927. + * sizeof (struct s2) == 2
  13928. + * sizeof (struct s3) == 2
  13929. + * sizeof (struct s4) == 4
  13930. + * sizeof (struct s5) == 3
  13931. + * sizeof (struct s6) == 4
  13932. + * sizeof (struct s7) == 3
  13933. + * sizeof (struct s8) == 6
  13934. + * sizeof (struct s9) == 4
  13935. + * sizeof (struct s10) == 8
  13936. + * sizeof (struct s11) == 12
  13937. + * sizeof (struct s12) == 12
  13938. + *
  13939. + * We want the equivalent reversed bitfield structs to be:
  13940. + *
  13941. + * struct s1r
  13942. + * {
  13943. + * int f2:31;
  13944. + * int f1:1;
  13945. + * };
  13946. + *
  13947. + * struct s2r
  13948. + * {
  13949. + * int f2:15;
  13950. + * int f1:1;
  13951. + * } __attribute__ ((__packed__));
  13952. + *
  13953. + * struct s3r
  13954. + * {
  13955. + * short f2:15;
  13956. + * short f1:1;
  13957. + * };
  13958. + *
  13959. + * struct s4r
  13960. + * {
  13961. + * int unnamed:16;
  13962. + * int f2:15;
  13963. + * int f1:1;
  13964. + * };
  13965. + *
  13966. + * struct s5r
  13967. + * {
  13968. + * int f1:8;
  13969. + * int f2:8;
  13970. + * int f4:4;
  13971. + * int f3:4;
  13972. + * } __attribute__ ((__packed__));
  13973. + *
  13974. + * struct s6r
  13975. + * {
  13976. + * int f5:8;
  13977. + * int f4:4;
  13978. + * int f3:4;
  13979. + * int f2:15;
  13980. + * int f1:1;
  13981. + * };
  13982. + *
  13983. + * struct s7r
  13984. + * {
  13985. + * #error cannot reverse bitfield
  13986. + * } __attribute__ ((__packed__));
  13987. + *
  13988. + * struct s8r
  13989. + * {
  13990. + * char unnamed1;
  13991. + * char f1;
  13992. + * short f2;
  13993. + * char unnamed2;
  13994. + * char f3;
  13995. + * };
  13996. + *
  13997. + * struct s9r
  13998. + * {
  13999. + * char f3;
  14000. + * short f2;
  14001. + * char f1;
  14002. + * } __attribute__ ((__packed__));
  14003. + *
  14004. + * struct s10r
  14005. + * {
  14006. + * short f2;
  14007. + * char unnamed1;
  14008. + * char f1;
  14009. + * short f4;
  14010. + * char unnamed2;
  14011. + * char f3;
  14012. + * };
  14013. + *
  14014. + * struct s11r
  14015. + * {
  14016. + * char f1[5];
  14017. + * int f2;
  14018. + * };
  14019. + *
  14020. + * struct s12r
  14021. + * {
  14022. + * #error cannot reverse bitfield
  14023. + * };
  14024. + *
  14025. + * struct s13r
  14026. + * {
  14027. + * char unnamed;
  14028. + * char f1[3];
  14029. + * int f2;
  14030. + * };
  14031. + *
  14032. + * struct s14r
  14033. + * {
  14034. + * char unnamed;
  14035. + * char f1c;
  14036. + * char f1b;
  14037. + * char f1a;
  14038. + * int f2;
  14039. + * };
  14040. + *
  14041. + * Note that the s4, s8, s10, s13, and s14 cases produce somewhat
  14042. + * suprising results: the normally hidden padding bytes the compiler
  14043. + * adds are also reversed. Further note that s13 and s14 are not
  14044. + * equivalent: the f1 field in s13 is 24-bits wide, and is reversed
  14045. + * accordingly, while the three fields f1a, f1b, and f1c in s14 are
  14046. + * reversed as individual bytes.
  14047. + *
  14048. + * The s7 and s12 cases produce an error: we can't reverse a bitfield
  14049. + * that is larger than word size we're reversing. The error is
  14050. + * suppressed in the s11 case since the field in question and the
  14051. + * field that follows are both word aligned.
  14052. + */
  14053. +
  14054. + /*
  14055. + * First, figure out what size words to reverse. We look at the total
  14056. + * number of bits currently in use by the struct, rounded up to the
  14057. + * next multiple of rli->record_align, to decide.
  14058. + */
  14059. + {
  14060. + int bits_in_use = TREE_INT_CST_LOW (round_up (rli_size_so_far (rli),
  14061. + rli->record_align));
  14062. + unsigned int size;
  14063. + for (size = GET_MODE_BITSIZE (SImode);
  14064. + size >= GET_MODE_BITSIZE (QImode);
  14065. + size /= 2)
  14066. + {
  14067. + if (bits_in_use % size == 0)
  14068. + {
  14069. + break;
  14070. + }
  14071. + }
  14072. + if (size < GET_MODE_BITSIZE (QImode))
  14073. + {
  14074. + /*
  14075. + * rli->record_align should never be less than QImode, even
  14076. + * for packed structs.
  14077. + */
  14078. + abort ();
  14079. + }
  14080. + rev_size = size_int_type (size, bitsizetype);
  14081. + rev_size_int = size;
  14082. + }
  14083. +
  14084. + /*
  14085. + * Then, iterate over the fields, reversing them as we go.
  14086. + */
  14087. + for (field = TYPE_FIELDS (rli->t); field; field = TREE_CHAIN (field))
  14088. + {
  14089. + tree type = TREE_TYPE (field);
  14090. + if (TREE_CODE (field) != FIELD_DECL)
  14091. + {
  14092. + continue;
  14093. + }
  14094. + if (TREE_CODE (field) == ERROR_MARK || TREE_CODE (type) == ERROR_MARK)
  14095. + {
  14096. + return;
  14097. + }
  14098. + {
  14099. + tree offset = DECL_FIELD_OFFSET (field);
  14100. + tree offset_type = TREE_TYPE (offset);
  14101. + tree bit_offset = DECL_FIELD_BIT_OFFSET (field);
  14102. + tree bit_offset_type = TREE_TYPE (bit_offset);
  14103. + tree bit = bit_from_pos (offset, bit_offset);
  14104. + tree true_size = DECL_SIZE (field);
  14105. + pos_from_bit (&offset, &bit_offset, rev_size_int, bit);
  14106. + bit_offset = size_binop (MINUS_EXPR,
  14107. + size_binop (MINUS_EXPR, rev_size, true_size),
  14108. + bit_offset);
  14109. + if (TREE_INT_CST_HIGH (bit_offset) != 0)
  14110. + {
  14111. + /*
  14112. + * This happens when a field spans a rev_size boundary (see
  14113. + * example s7 above): rather than try to come up with some
  14114. + * well-defined, but non-intuitive definition for this case,
  14115. + * just issue an error. It can also happen for large fields,
  14116. + * e.g. arrays or other structs: if these large fields were
  14117. + * already aligned, leave them be; otherwise issue the error
  14118. + * in this case as well.
  14119. + */
  14120. + if ((TREE_INT_CST_HIGH (true_size) != 0
  14121. + || TREE_INT_CST_LOW (true_size) > rev_size_int)
  14122. + && TREE_INT_CST_HIGH (DECL_FIELD_BIT_OFFSET (field)) == 0
  14123. + && TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field)) == 0)
  14124. + {
  14125. + tree next_field = TREE_CHAIN (field);
  14126. + if (!next_field)
  14127. + {
  14128. + /* No following field, so we're ok. */
  14129. + continue;
  14130. + }
  14131. + else
  14132. + {
  14133. + tree next_offset = DECL_FIELD_OFFSET (next_field);
  14134. + tree next_bit_offset = DECL_FIELD_BIT_OFFSET (next_field);
  14135. + tree next_bit = bit_from_pos (next_offset, next_bit_offset);
  14136. + pos_from_bit (&next_offset, &next_bit_offset, rev_size_int,
  14137. + next_bit);
  14138. + if (TREE_INT_CST_HIGH (next_bit_offset) == 0
  14139. + && TREE_INT_CST_LOW (next_bit_offset) == 0)
  14140. + {
  14141. + /* Following field is aligned wrt rev_size_int boundary,
  14142. + so we're ok. */
  14143. + continue;
  14144. + }
  14145. + }
  14146. + }
  14147. + error ("unable to reverse bitfields in structure");
  14148. + return;
  14149. + }
  14150. + bit = bit_from_pos (offset, bit_offset);
  14151. + pos_from_bit (&offset, &bit_offset, rli->offset_align, bit);
  14152. + TREE_TYPE (offset) = offset_type;
  14153. + DECL_FIELD_OFFSET (field) = offset;
  14154. + TREE_TYPE (bit_offset) = bit_offset_type;
  14155. + DECL_FIELD_BIT_OFFSET (field) = bit_offset;
  14156. + }
  14157. + }
  14158. +}
  14159. +
  14160. /* Do all of the work required to layout the type indicated by RLI,
  14161. once the fields have been laid out. This function will call `free'
  14162. for RLI, unless FREE_P is false. Passing a value other than false
  14163. @@ -1444,6 +1793,12 @@ finalize_type_size (tree type)
  14164. void
  14165. finish_record_layout (record_layout_info rli, int free_p)
  14166. {
  14167. + /* Optionally reverse the placement of bitfields within the record */
  14168. + if ((* targetm.reverse_bitfield_layout_p) (rli->t))
  14169. + {
  14170. + reverse_bitfield_layout (rli);
  14171. + }
  14172. +
  14173. /* Compute the final size. */
  14174. finalize_record_size (rli);
  14175. diff --git a/gcc/target-def.h b/gcc/target-def.h
  14176. index 32d00ae..bdea4d4 100644
  14177. --- a/gcc/target-def.h
  14178. +++ b/gcc/target-def.h
  14179. @@ -300,6 +300,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14180. #define TARGET_INSERT_ATTRIBUTES hook_void_tree_treeptr
  14181. #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_tree_false
  14182. #define TARGET_MS_BITFIELD_LAYOUT_P hook_bool_tree_false
  14183. +#define TARGET_REVERSE_BITFIELD_LAYOUT_P hook_bool_tree_false
  14184. #define TARGET_RTX_COSTS hook_bool_rtx_int_int_intp_false
  14185. #define TARGET_MANGLE_FUNDAMENTAL_TYPE hook_constcharptr_tree_null
  14186. @@ -368,6 +369,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14187. TARGET_INSERT_ATTRIBUTES, \
  14188. TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P, \
  14189. TARGET_MS_BITFIELD_LAYOUT_P, \
  14190. + TARGET_REVERSE_BITFIELD_LAYOUT_P, \
  14191. TARGET_INIT_BUILTINS, \
  14192. TARGET_EXPAND_BUILTIN, \
  14193. TARGET_MANGLE_FUNDAMENTAL_TYPE, \
  14194. diff --git a/gcc/target.h b/gcc/target.h
  14195. index 59788f9..97bde5f 100644
  14196. --- a/gcc/target.h
  14197. +++ b/gcc/target.h
  14198. @@ -295,6 +295,10 @@ struct gcc_target
  14199. Microsoft Visual C++ bitfield layout rules. */
  14200. bool (* ms_bitfield_layout_p) (tree record_type);
  14201. + /* Return true if bitfields in RECORD_TYPE should be allocated
  14202. + within their base type's bytes starting at the opposite end. */
  14203. + bool (* reverse_bitfield_layout_p) (tree record_type);
  14204. +
  14205. /* Set up target-specific built-in functions. */
  14206. void (* init_builtins) (void);
  14207. diff --git a/gcc/varasm.c b/gcc/varasm.c
  14208. index 33307e5..d4ed0fc 100644
  14209. --- a/gcc/varasm.c
  14210. +++ b/gcc/varasm.c
  14211. @@ -3912,6 +3912,107 @@ array_size_for_constructor (tree val)
  14212. return tree_low_cst (i, 1);
  14213. }
  14214. +struct reorder_bitfields_key
  14215. +{
  14216. + tree field;
  14217. + tree value;
  14218. +};
  14219. +
  14220. +static int
  14221. +reorder_bitfields_compare (const void *x1, const void *x2)
  14222. +{
  14223. + const struct reorder_bitfields_key *key1 = x1;
  14224. + const struct reorder_bitfields_key *key2 = x2;
  14225. + int pos1 = int_bit_position (key1->field);
  14226. + int pos2 = int_bit_position (key2->field);
  14227. +
  14228. + if (pos1 < pos2)
  14229. + {
  14230. + return -1;
  14231. + }
  14232. + else if (pos1 > pos2)
  14233. + {
  14234. + return 1;
  14235. + }
  14236. + else
  14237. + {
  14238. + /*
  14239. + * No two fields should ever have the same bit_position, so
  14240. + * something is horribly wrong.
  14241. + */
  14242. + abort ();
  14243. + }
  14244. +}
  14245. +
  14246. +static void
  14247. +reorder_bitfields (tree *first_field, tree *first_value)
  14248. +{
  14249. + struct reorder_bitfields_key *keys;
  14250. + size_t field_count;
  14251. + tree field;
  14252. + tree value;
  14253. + size_t i;
  14254. +
  14255. + /*
  14256. + * Find out how many fields are in this record, and allocate an array
  14257. + * of keys to hold them all.
  14258. + */
  14259. + field_count = 0;
  14260. + for (field = *first_field; field; field = TREE_CHAIN (field))
  14261. + {
  14262. + field_count++;
  14263. + }
  14264. + if (field_count < 2)
  14265. + {
  14266. + return;
  14267. + }
  14268. + keys = xmalloc (sizeof (struct reorder_bitfields_key) * field_count);
  14269. +
  14270. + /*
  14271. + * Make copies of the existing fields and values (using signed integer
  14272. + * zeros for missing values) in the array of keys.
  14273. + */
  14274. + field = *first_field;
  14275. + value = *first_value;
  14276. + for (i = 0; i < field_count; i++)
  14277. + {
  14278. + keys[i].field = copy_node (field);
  14279. + field = TREE_CHAIN (field);
  14280. + if (value)
  14281. + {
  14282. + keys[i].value = copy_node (value);
  14283. + TREE_PURPOSE (keys[i].value) = keys[i].field;
  14284. + value = TREE_CHAIN (value);
  14285. + }
  14286. + else
  14287. + {
  14288. + keys[i].value = tree_cons (keys[i].field, ssize_int (0), 0);
  14289. + }
  14290. + }
  14291. +
  14292. + /*
  14293. + * Sort the array based on position of the fields in the record.
  14294. + */
  14295. + qsort (keys, field_count, sizeof (struct reorder_bitfields_key),
  14296. + reorder_bitfields_compare);
  14297. +
  14298. + /*
  14299. + * Build new lists out of the sorted array.
  14300. + */
  14301. + for (i = 0; i < field_count - 1; i++)
  14302. + {
  14303. + TREE_CHAIN (keys[i].field) = keys[i+1].field;
  14304. + TREE_CHAIN (keys[i].value) = keys[i+1].value;
  14305. + }
  14306. + *first_field = keys[0].field;
  14307. + *first_value = keys[0].value;
  14308. +
  14309. + /*
  14310. + * Get rid of our array of keys and we're done.
  14311. + */
  14312. + free (keys);
  14313. +}
  14314. +
  14315. /* Subroutine of output_constant, used for CONSTRUCTORs (aggregate constants).
  14316. Generate at least SIZE bytes, padding if necessary. */
  14317. @@ -3928,12 +4029,29 @@ output_constructor (tree exp, unsigned HOST_WIDE_INT size,
  14318. /* Nonzero means BYTE contains part of a byte, to be output. */
  14319. int byte_buffer_in_use = 0;
  14320. int byte = 0;
  14321. + tree first_link = CONSTRUCTOR_ELTS (exp);
  14322. if (HOST_BITS_PER_WIDE_INT < BITS_PER_UNIT)
  14323. abort ();
  14324. if (TREE_CODE (type) == RECORD_TYPE)
  14325. + {
  14326. + if ((*targetm.reverse_bitfield_layout_p) (type))
  14327. + {
  14328. + /*
  14329. + * If we're reversing bitfields, we have to reverse the order in
  14330. + * which constructors containing bitfields are output. The
  14331. + * easiest way to do that is to reorder the constructor elements
  14332. + * and fields to be in memory-order.
  14333. + */
  14334. field = TYPE_FIELDS (type);
  14335. + reorder_bitfields (&field, &first_link);
  14336. + }
  14337. + else
  14338. + {
  14339. + field = TYPE_FIELDS (type);
  14340. + }
  14341. + }
  14342. if (TREE_CODE (type) == ARRAY_TYPE
  14343. && TYPE_DOMAIN (type) != 0)
  14344. @@ -3948,7 +4066,7 @@ output_constructor (tree exp, unsigned HOST_WIDE_INT size,
  14345. There is always a maximum of one element in the chain LINK for unions
  14346. (even if the initializer in a source program incorrectly contains
  14347. more one). */
  14348. - for (link = CONSTRUCTOR_ELTS (exp);
  14349. + for (link = first_link;
  14350. link;
  14351. link = TREE_CHAIN (link),
  14352. field = field ? TREE_CHAIN (field) : 0)