tc-tic54x.c 139 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404
  1. /* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X
  2. Copyright (C) 1999-2015 Free Software Foundation, Inc.
  3. Contributed by Timothy Wall (twall@cygnus.com)
  4. This file is part of GAS, the GNU Assembler.
  5. GAS is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3, or (at your option)
  8. any later version.
  9. GAS is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GAS; see the file COPYING. If not, write to the Free
  15. Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
  16. 02110-1301, USA. */
  17. /* Texas Instruments TMS320C54X machine specific gas.
  18. Written by Timothy Wall (twall@alum.mit.edu).
  19. Valuable things to do:
  20. Pipeline conflict warnings
  21. We encode/decode "ld #_label, dp" differently in relocatable files
  22. This means we're not compatible with TI output containing those
  23. expressions. We store the upper nine bits; TI stores the lower nine
  24. bits. How they recover the original upper nine bits is beyond me.
  25. Tests to add to expect testsuite:
  26. '=' and '==' with .if, .elseif, and .break
  27. Incompatibilities (mostly trivial):
  28. We don't allow '''
  29. We fill text section with zeroes instead of "nop"s
  30. We don't convert '' or "" to a single instance
  31. We don't convert '' to '\0'
  32. We don't allow strings with .byte/.half/.short/.long
  33. Probably details of the subsym stuff are different
  34. TI sets labels to be data type 4 (T_INT); GAS uses T_NULL.
  35. COFF1 limits section names to 8 characters.
  36. Some of the default behavior changed from COFF1 to COFF2. */
  37. #include "as.h"
  38. #include <limits.h>
  39. #include "safe-ctype.h"
  40. #include "sb.h"
  41. #include "macro.h"
  42. #include "subsegs.h"
  43. #include "struc-symbol.h"
  44. #include "opcode/tic54x.h"
  45. #include "obj-coff.h"
  46. #include <math.h>
  47. static struct stag
  48. {
  49. symbolS *sym; /* Symbol for this stag; value is offset. */
  50. const char *name; /* Shortcut to symbol name. */
  51. bfd_vma size; /* Size of struct/union. */
  52. int current_bitfield_offset; /* Temporary for tracking fields. */
  53. int is_union;
  54. struct stag_field /* List of fields. */
  55. {
  56. const char *name;
  57. bfd_vma offset; /* Of start of this field. */
  58. int bitfield_offset; /* Of start of this field. */
  59. struct stag *stag; /* If field is struct/union. */
  60. struct stag_field *next;
  61. } *field;
  62. /* For nesting; used only in stag construction. */
  63. struct stag *inner; /* Enclosed .struct. */
  64. struct stag *outer; /* Enclosing .struct. */
  65. } *current_stag = NULL;
  66. #define MAX_LINE 256 /* Lines longer than this are truncated by TI's asm. */
  67. typedef struct _tic54x_insn
  68. {
  69. const insn_template *tm; /* Opcode template. */
  70. char mnemonic[MAX_LINE]; /* Opcode name/mnemonic. */
  71. char parmnemonic[MAX_LINE]; /* 2nd mnemonic of parallel insn. */
  72. int opcount;
  73. struct opstruct
  74. {
  75. char buf[MAX_LINE];
  76. enum optype type;
  77. expressionS exp;
  78. } operands[MAX_OPERANDS];
  79. int paropcount;
  80. struct opstruct paroperands[MAX_OPERANDS];
  81. int is_lkaddr;
  82. int lkoperand;
  83. int words; /* Size of insn in 16-bit words. */
  84. int using_default_dst; /* Do we need to explicitly set an
  85. omitted OP_DST operand? */
  86. struct
  87. {
  88. unsigned short word; /* Final encoded opcode data. */
  89. int unresolved;
  90. int r_nchars; /* Relocation size. */
  91. bfd_reloc_code_real_type r_type; /* Relocation type. */
  92. expressionS addr_expr; /* Storage for unresolved expressions. */
  93. } opcode[3];
  94. } tic54x_insn;
  95. enum cpu_version
  96. {
  97. VNONE = 0, V541 = 1, V542 = 2, V543 = 3, V545 = 5, V548 = 8, V549 = 9,
  98. V545LP = 15, V546LP = 16
  99. };
  100. enum address_mode
  101. {
  102. c_mode, /* 16-bit addresses. */
  103. far_mode /* >16-bit addresses. */
  104. };
  105. static segT stag_saved_seg;
  106. static subsegT stag_saved_subseg;
  107. const char comment_chars[] = ";";
  108. const char line_comment_chars[] = ";*#"; /* At column zero only. */
  109. const char line_separator_chars[] = ""; /* Not permitted. */
  110. int emitting_long = 0;
  111. /* Characters which indicate that this is a floating point constant. */
  112. const char FLT_CHARS[] = "fF";
  113. /* Characters that can be used to separate mantissa from exp in FP
  114. nums. */
  115. const char EXP_CHARS[] = "eE";
  116. const char *md_shortopts = "";
  117. #define OPTION_ADDRESS_MODE (OPTION_MD_BASE)
  118. #define OPTION_CPU_VERSION (OPTION_ADDRESS_MODE + 1)
  119. #define OPTION_COFF_VERSION (OPTION_CPU_VERSION + 1)
  120. #define OPTION_STDERR_TO_FILE (OPTION_COFF_VERSION + 1)
  121. struct option md_longopts[] =
  122. {
  123. { "mfar-mode", no_argument, NULL, OPTION_ADDRESS_MODE },
  124. { "mf", no_argument, NULL, OPTION_ADDRESS_MODE },
  125. { "mcpu", required_argument, NULL, OPTION_CPU_VERSION },
  126. { "merrors-to-file", required_argument, NULL, OPTION_STDERR_TO_FILE },
  127. { "me", required_argument, NULL, OPTION_STDERR_TO_FILE },
  128. { NULL, no_argument, NULL, 0},
  129. };
  130. size_t md_longopts_size = sizeof (md_longopts);
  131. static int assembly_begun = 0;
  132. /* Addressing mode is not entirely implemented; the latest rev of the Other
  133. assembler doesn't seem to make any distinction whatsoever; all relocations
  134. are stored as extended relocatiosn. Older versions used REL16 vs RELEXT16,
  135. but now it seems all relocations are RELEXT16. We use all RELEXT16.
  136. The cpu version is kind of a waste of time as well. There is one
  137. instruction (RND) for LP devices only, and several for devices with
  138. extended addressing only. We include it for compatibility. */
  139. static enum address_mode amode = c_mode;
  140. static enum cpu_version cpu = VNONE;
  141. /* Include string substitutions in listing? */
  142. static int listing_sslist = 0;
  143. /* Did we do subsym substitutions on the line? */
  144. static int substitution_line = 0;
  145. /* Last label seen. */
  146. static symbolS *last_label_seen = NULL;
  147. /* This ensures that all new labels are unique. */
  148. static int local_label_id;
  149. static struct hash_control *subsym_recurse_hash; /* Prevent infinite recurse. */
  150. static struct hash_control *math_hash; /* Built-in math functions. */
  151. /* Allow maximum levels of macro nesting; level 0 is the main substitution
  152. symbol table. The other assembler only does 32 levels, so there! */
  153. static struct hash_control *subsym_hash[100];
  154. /* Keep track of local labels so we can substitute them before GAS sees them
  155. since macros use their own 'namespace' for local labels, use a separate hash
  156. We do our own local label handling 'cuz it's subtly different from the
  157. stock GAS handling.
  158. We use our own macro nesting counter, since GAS overloads it when expanding
  159. other things (like conditionals and repeat loops). */
  160. static int macro_level = 0;
  161. static struct hash_control *local_label_hash[100];
  162. /* Keep track of struct/union tags. */
  163. static struct hash_control *stag_hash;
  164. static struct hash_control *op_hash;
  165. static struct hash_control *parop_hash;
  166. static struct hash_control *reg_hash;
  167. static struct hash_control *mmreg_hash;
  168. static struct hash_control *cc_hash;
  169. static struct hash_control *cc2_hash;
  170. static struct hash_control *cc3_hash;
  171. static struct hash_control *sbit_hash;
  172. static struct hash_control *misc_symbol_hash;
  173. /* Only word (et al.), align, or conditionals are allowed within
  174. .struct/.union. */
  175. #define ILLEGAL_WITHIN_STRUCT() \
  176. do \
  177. if (current_stag != NULL) \
  178. { \
  179. as_bad (_("pseudo-op illegal within .struct/.union")); \
  180. return; \
  181. } \
  182. while (0)
  183. static void subsym_create_or_replace (char *, char *);
  184. static char *subsym_lookup (char *, int);
  185. static char *subsym_substitute (char *, int);
  186. void
  187. md_show_usage (FILE *stream)
  188. {
  189. fprintf (stream, _("C54x-specific command line options:\n"));
  190. fprintf (stream, _("-mfar-mode | -mf Use extended addressing\n"));
  191. fprintf (stream, _("-mcpu=<CPU version> Specify the CPU version\n"));
  192. fprintf (stream, _("-merrors-to-file <filename>\n"));
  193. fprintf (stream, _("-me <filename> Redirect errors to a file\n"));
  194. }
  195. /* Output a single character (upper octect is zero). */
  196. static void
  197. tic54x_emit_char (char c)
  198. {
  199. expressionS expn;
  200. expn.X_op = O_constant;
  201. expn.X_add_number = c;
  202. emit_expr (&expn, 2);
  203. }
  204. /* Walk backwards in the frag chain. */
  205. static fragS *
  206. frag_prev (fragS *frag, segT seg)
  207. {
  208. segment_info_type *seginfo = seg_info (seg);
  209. fragS *fragp;
  210. for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next)
  211. if (fragp->fr_next == frag)
  212. return fragp;
  213. return NULL;
  214. }
  215. static fragS *
  216. bit_offset_frag (fragS *frag, segT seg)
  217. {
  218. while (frag != NULL)
  219. {
  220. if (frag->fr_fix == 0
  221. && frag->fr_opcode == NULL
  222. && frag->tc_frag_data == 0)
  223. frag = frag_prev (frag, seg);
  224. else
  225. return frag;
  226. }
  227. return NULL;
  228. }
  229. /* Return the number of bits allocated in the most recent word, or zero if
  230. none. .field/.space/.bes may leave words partially allocated. */
  231. static int
  232. frag_bit_offset (fragS *frag, segT seg)
  233. {
  234. frag = bit_offset_frag (frag, seg);
  235. if (frag)
  236. return frag->fr_opcode != NULL ? -1 : frag->tc_frag_data;
  237. return 0;
  238. }
  239. /* Read an expression from a C string; returns a pointer past the end of the
  240. expression. */
  241. static char *
  242. parse_expression (char *str, expressionS *expn)
  243. {
  244. char *s;
  245. char *tmp;
  246. tmp = input_line_pointer; /* Save line pointer. */
  247. input_line_pointer = str;
  248. expression (expn);
  249. s = input_line_pointer;
  250. input_line_pointer = tmp; /* Restore line pointer. */
  251. return s; /* Return pointer to where parsing stopped. */
  252. }
  253. /* .asg "character-string"|character-string, symbol
  254. .eval is the only pseudo-op allowed to perform arithmetic on substitution
  255. symbols. all other use of symbols defined with .asg are currently
  256. unsupported. */
  257. static void
  258. tic54x_asg (int x ATTRIBUTE_UNUSED)
  259. {
  260. int c;
  261. char *name;
  262. char *str;
  263. char *tmp;
  264. int quoted = *input_line_pointer == '"';
  265. ILLEGAL_WITHIN_STRUCT ();
  266. if (quoted)
  267. {
  268. int len;
  269. str = demand_copy_C_string (&len);
  270. c = *input_line_pointer;
  271. }
  272. else
  273. {
  274. str = input_line_pointer;
  275. while ((c = *input_line_pointer) != ',')
  276. {
  277. if (is_end_of_line[(int) *input_line_pointer])
  278. break;
  279. ++input_line_pointer;
  280. }
  281. *input_line_pointer = 0;
  282. }
  283. if (c != ',')
  284. {
  285. as_bad (_("Comma and symbol expected for '.asg STRING, SYMBOL'"));
  286. ignore_rest_of_line ();
  287. return;
  288. }
  289. ++input_line_pointer;
  290. c = get_symbol_name (&name); /* Get terminator. */
  291. if (!ISALPHA (*name))
  292. {
  293. as_bad (_("symbols assigned with .asg must begin with a letter"));
  294. ignore_rest_of_line ();
  295. return;
  296. }
  297. tmp = xmalloc (strlen (str) + 1);
  298. strcpy (tmp, str);
  299. str = tmp;
  300. tmp = xmalloc (strlen (name) + 1);
  301. strcpy (tmp, name);
  302. name = tmp;
  303. subsym_create_or_replace (name, str);
  304. (void) restore_line_pointer (c);
  305. demand_empty_rest_of_line ();
  306. }
  307. /* .eval expression, symbol
  308. There's something screwy about this. The other assembler sometimes does and
  309. sometimes doesn't substitute symbols defined with .eval.
  310. We'll put the symbols into the subsym table as well as the normal symbol
  311. table, since that's what works best. */
  312. static void
  313. tic54x_eval (int x ATTRIBUTE_UNUSED)
  314. {
  315. char c;
  316. int value;
  317. char *name;
  318. symbolS *symbolP;
  319. char valuestr[32], *tmp;
  320. int quoted;
  321. ILLEGAL_WITHIN_STRUCT ();
  322. SKIP_WHITESPACE ();
  323. quoted = *input_line_pointer == '"';
  324. if (quoted)
  325. ++input_line_pointer;
  326. value = get_absolute_expression ();
  327. if (quoted)
  328. {
  329. if (*input_line_pointer != '"')
  330. {
  331. as_bad (_("Unterminated string after absolute expression"));
  332. ignore_rest_of_line ();
  333. return;
  334. }
  335. ++input_line_pointer;
  336. }
  337. if (*input_line_pointer++ != ',')
  338. {
  339. as_bad (_("Comma and symbol expected for '.eval EXPR, SYMBOL'"));
  340. ignore_rest_of_line ();
  341. return;
  342. }
  343. c = get_symbol_name (&name); /* Get terminator. */
  344. tmp = xmalloc (strlen (name) + 1);
  345. name = strcpy (tmp, name);
  346. (void) restore_line_pointer (c);
  347. if (!ISALPHA (*name))
  348. {
  349. as_bad (_("symbols assigned with .eval must begin with a letter"));
  350. ignore_rest_of_line ();
  351. return;
  352. }
  353. symbolP = symbol_new (name, absolute_section,
  354. (valueT) value, &zero_address_frag);
  355. SF_SET_LOCAL (symbolP);
  356. symbol_table_insert (symbolP);
  357. /* The "other" assembler sometimes doesn't put .eval's in the subsym table
  358. But since there's not written rule as to when, don't even bother trying
  359. to match their behavior. */
  360. sprintf (valuestr, "%d", value);
  361. tmp = xmalloc (strlen (valuestr) + 1);
  362. strcpy (tmp, valuestr);
  363. subsym_create_or_replace (name, tmp);
  364. demand_empty_rest_of_line ();
  365. }
  366. /* .bss symbol, size [, [blocking flag] [, alignment flag]
  367. alignment is to a longword boundary; blocking is to 128-word boundary.
  368. 1) if there is a hole in memory, this directive should attempt to fill it
  369. (not yet implemented).
  370. 2) if the blocking flag is not set, allocate at the current SPC
  371. otherwise, check to see if the current SPC plus the space to be
  372. allocated crosses the page boundary (128 words).
  373. if there's not enough space, create a hole and align with the next page
  374. boundary.
  375. (not yet implemented). */
  376. static void
  377. tic54x_bss (int x ATTRIBUTE_UNUSED)
  378. {
  379. char c;
  380. char *name;
  381. char *p;
  382. int words;
  383. segT current_seg;
  384. subsegT current_subseg;
  385. symbolS *symbolP;
  386. int block = 0;
  387. int align = 0;
  388. ILLEGAL_WITHIN_STRUCT ();
  389. current_seg = now_seg; /* Save current seg. */
  390. current_subseg = now_subseg; /* Save current subseg. */
  391. c = get_symbol_name (&name); /* Get terminator. */
  392. if (c == '"')
  393. c = * ++ input_line_pointer;
  394. if (c != ',')
  395. {
  396. as_bad (_(".bss size argument missing\n"));
  397. ignore_rest_of_line ();
  398. return;
  399. }
  400. ++input_line_pointer;
  401. words = get_absolute_expression ();
  402. if (words < 0)
  403. {
  404. as_bad (_(".bss size %d < 0!"), words);
  405. ignore_rest_of_line ();
  406. return;
  407. }
  408. if (*input_line_pointer == ',')
  409. {
  410. /* The blocking flag may be missing. */
  411. ++input_line_pointer;
  412. if (*input_line_pointer != ',')
  413. block = get_absolute_expression ();
  414. else
  415. block = 0;
  416. if (*input_line_pointer == ',')
  417. {
  418. ++input_line_pointer;
  419. align = get_absolute_expression ();
  420. }
  421. else
  422. align = 0;
  423. }
  424. else
  425. block = align = 0;
  426. subseg_set (bss_section, 0);
  427. symbolP = symbol_find_or_make (name);
  428. if (S_GET_SEGMENT (symbolP) == bss_section)
  429. symbolP->sy_frag->fr_symbol = (symbolS *) NULL;
  430. symbol_set_frag (symbolP, frag_now);
  431. p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
  432. (offsetT) (words * OCTETS_PER_BYTE), (char *) 0);
  433. *p = 0; /* Fill char. */
  434. S_SET_SEGMENT (symbolP, bss_section);
  435. /* The symbol may already have been created with a preceding
  436. ".globl" directive -- be careful not to step on storage class
  437. in that case. Otherwise, set it to static. */
  438. if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
  439. S_SET_STORAGE_CLASS (symbolP, C_STAT);
  440. if (align)
  441. {
  442. /* s_align eats end of line; restore it */
  443. s_align_bytes (4);
  444. --input_line_pointer;
  445. }
  446. if (block)
  447. bss_section->flags |= SEC_TIC54X_BLOCK;
  448. subseg_set (current_seg, current_subseg); /* Restore current seg. */
  449. demand_empty_rest_of_line ();
  450. }
  451. static void
  452. stag_add_field_symbols (struct stag *stag,
  453. const char *path,
  454. bfd_vma base_offset,
  455. symbolS *rootsym,
  456. const char *root_stag_name)
  457. {
  458. char prefix[strlen (path) + 2];
  459. struct stag_field *field = stag->field;
  460. /* Construct a symbol for every field contained within this structure
  461. including fields within structure fields. */
  462. strcpy (prefix, path);
  463. if (*path)
  464. strcat (prefix, ".");
  465. while (field != NULL)
  466. {
  467. int len = strlen (prefix) + strlen (field->name) + 2;
  468. char *name = xmalloc (len);
  469. strcpy (name, prefix);
  470. strcat (name, field->name);
  471. if (rootsym == NULL)
  472. {
  473. symbolS *sym;
  474. sym = symbol_new (name, absolute_section,
  475. (field->stag ? field->offset :
  476. (valueT) (base_offset + field->offset)),
  477. &zero_address_frag);
  478. SF_SET_LOCAL (sym);
  479. symbol_table_insert (sym);
  480. }
  481. else
  482. {
  483. char *replacement = xmalloc (strlen (name)
  484. + strlen (stag->name) + 2);
  485. strcpy (replacement, S_GET_NAME (rootsym));
  486. strcat (replacement, "+");
  487. strcat (replacement, root_stag_name);
  488. strcat (replacement, name + strlen (S_GET_NAME (rootsym)));
  489. hash_insert (subsym_hash[0], name, replacement);
  490. }
  491. /* Recurse if the field is a structure.
  492. Note the field offset is relative to the outermost struct. */
  493. if (field->stag != NULL)
  494. stag_add_field_symbols (field->stag, name,
  495. field->offset,
  496. rootsym, root_stag_name);
  497. field = field->next;
  498. }
  499. }
  500. /* Keep track of stag fields so that when structures are nested we can add the
  501. complete dereferencing symbols to the symbol table. */
  502. static void
  503. stag_add_field (struct stag *parent,
  504. const char *name,
  505. bfd_vma offset,
  506. struct stag *stag)
  507. {
  508. struct stag_field *sfield = xmalloc (sizeof (struct stag_field));
  509. memset (sfield, 0, sizeof (*sfield));
  510. sfield->name = strcpy (xmalloc (strlen (name) + 1), name);
  511. sfield->offset = offset;
  512. sfield->bitfield_offset = parent->current_bitfield_offset;
  513. sfield->stag = stag;
  514. if (parent->field == NULL)
  515. parent->field = sfield;
  516. else
  517. {
  518. struct stag_field *sf = parent->field;
  519. while (sf->next != NULL)
  520. sf = sf->next;
  521. sf->next = sfield;
  522. }
  523. /* Only create a symbol for this field if the parent has no name. */
  524. if (!strncmp (".fake", parent->name, 5))
  525. {
  526. symbolS *sym = symbol_new (name, absolute_section,
  527. (valueT) offset, &zero_address_frag);
  528. SF_SET_LOCAL (sym);
  529. symbol_table_insert (sym);
  530. }
  531. }
  532. /* [STAG] .struct [OFFSET]
  533. Start defining structure offsets (symbols in absolute section). */
  534. static void
  535. tic54x_struct (int arg)
  536. {
  537. int start_offset = 0;
  538. int is_union = arg;
  539. if (!current_stag)
  540. {
  541. /* Starting a new struct, switch to absolute section. */
  542. stag_saved_seg = now_seg;
  543. stag_saved_subseg = now_subseg;
  544. subseg_set (absolute_section, 0);
  545. }
  546. /* Align the current pointer. */
  547. else if (current_stag->current_bitfield_offset != 0)
  548. {
  549. ++abs_section_offset;
  550. current_stag->current_bitfield_offset = 0;
  551. }
  552. /* Offset expression is only meaningful for global .structs. */
  553. if (!is_union)
  554. {
  555. /* Offset is ignored in inner structs. */
  556. SKIP_WHITESPACE ();
  557. if (!is_end_of_line[(int) *input_line_pointer])
  558. start_offset = get_absolute_expression ();
  559. else
  560. start_offset = 0;
  561. }
  562. if (current_stag)
  563. {
  564. /* Nesting, link to outer one. */
  565. current_stag->inner = (struct stag *) xmalloc (sizeof (struct stag));
  566. memset (current_stag->inner, 0, sizeof (struct stag));
  567. current_stag->inner->outer = current_stag;
  568. current_stag = current_stag->inner;
  569. if (start_offset)
  570. as_warn (_("Offset on nested structures is ignored"));
  571. start_offset = abs_section_offset;
  572. }
  573. else
  574. {
  575. current_stag = (struct stag *) xmalloc (sizeof (struct stag));
  576. memset (current_stag, 0, sizeof (struct stag));
  577. abs_section_offset = start_offset;
  578. }
  579. current_stag->is_union = is_union;
  580. if (line_label == NULL)
  581. {
  582. static int struct_count = 0;
  583. char fake[] = ".fake_stagNNNNNNN";
  584. sprintf (fake, ".fake_stag%d", struct_count++);
  585. current_stag->sym = symbol_new (fake, absolute_section,
  586. (valueT) abs_section_offset,
  587. &zero_address_frag);
  588. }
  589. else
  590. {
  591. char label[strlen (S_GET_NAME (line_label)) + 1];
  592. strcpy (label, S_GET_NAME (line_label));
  593. current_stag->sym = symbol_new (label, absolute_section,
  594. (valueT) abs_section_offset,
  595. &zero_address_frag);
  596. }
  597. current_stag->name = S_GET_NAME (current_stag->sym);
  598. SF_SET_LOCAL (current_stag->sym);
  599. /* Nested .structs don't go into the symbol table. */
  600. if (current_stag->outer == NULL)
  601. symbol_table_insert (current_stag->sym);
  602. line_label = NULL;
  603. }
  604. /* [LABEL] .endstruct
  605. finish defining structure offsets; optional LABEL's value will be the size
  606. of the structure. */
  607. static void
  608. tic54x_endstruct (int is_union)
  609. {
  610. int size;
  611. const char *path =
  612. !strncmp (current_stag->name, ".fake", 5) ? "" : current_stag->name;
  613. if (!current_stag || current_stag->is_union != is_union)
  614. {
  615. as_bad (_(".end%s without preceding .%s"),
  616. is_union ? "union" : "struct",
  617. is_union ? "union" : "struct");
  618. ignore_rest_of_line ();
  619. return;
  620. }
  621. /* Align end of structures. */
  622. if (current_stag->current_bitfield_offset)
  623. {
  624. ++abs_section_offset;
  625. current_stag->current_bitfield_offset = 0;
  626. }
  627. if (current_stag->is_union)
  628. size = current_stag->size;
  629. else
  630. size = abs_section_offset - S_GET_VALUE (current_stag->sym);
  631. if (line_label != NULL)
  632. {
  633. S_SET_VALUE (line_label, size);
  634. symbol_table_insert (line_label);
  635. line_label = NULL;
  636. }
  637. /* Union size has already been calculated. */
  638. if (!current_stag->is_union)
  639. current_stag->size = size;
  640. /* Nested .structs don't get put in the stag table. */
  641. if (current_stag->outer == NULL)
  642. {
  643. hash_insert (stag_hash, current_stag->name, current_stag);
  644. stag_add_field_symbols (current_stag, path,
  645. S_GET_VALUE (current_stag->sym),
  646. NULL, NULL);
  647. }
  648. current_stag = current_stag->outer;
  649. /* If this is a nested .struct/.union, add it as a field to the enclosing
  650. one. otherwise, restore the section we were in. */
  651. if (current_stag != NULL)
  652. {
  653. stag_add_field (current_stag, current_stag->inner->name,
  654. S_GET_VALUE (current_stag->inner->sym),
  655. current_stag->inner);
  656. }
  657. else
  658. subseg_set (stag_saved_seg, stag_saved_subseg);
  659. }
  660. /* [LABEL] .tag STAG
  661. Reference a structure within a structure, as a sized field with an optional
  662. label.
  663. If used outside of a .struct/.endstruct, overlays the given structure
  664. format on the existing allocated space. */
  665. static void
  666. tic54x_tag (int ignore ATTRIBUTE_UNUSED)
  667. {
  668. char *name;
  669. int c = get_symbol_name (&name);
  670. struct stag *stag = (struct stag *) hash_find (stag_hash, name);
  671. if (!stag)
  672. {
  673. if (*name)
  674. as_bad (_("Unrecognized struct/union tag '%s'"), name);
  675. else
  676. as_bad (_(".tag requires a structure tag"));
  677. ignore_rest_of_line ();
  678. return;
  679. }
  680. if (line_label == NULL)
  681. {
  682. as_bad (_("Label required for .tag"));
  683. ignore_rest_of_line ();
  684. return;
  685. }
  686. else
  687. {
  688. char label[strlen (S_GET_NAME (line_label)) + 1];
  689. strcpy (label, S_GET_NAME (line_label));
  690. if (current_stag != NULL)
  691. stag_add_field (current_stag, label,
  692. abs_section_offset - S_GET_VALUE (current_stag->sym),
  693. stag);
  694. else
  695. {
  696. symbolS *sym = symbol_find (label);
  697. if (!sym)
  698. {
  699. as_bad (_(".tag target '%s' undefined"), label);
  700. ignore_rest_of_line ();
  701. return;
  702. }
  703. stag_add_field_symbols (stag, S_GET_NAME (sym),
  704. S_GET_VALUE (stag->sym), sym, stag->name);
  705. }
  706. }
  707. /* Bump by the struct size, but only if we're within a .struct section. */
  708. if (current_stag != NULL && !current_stag->is_union)
  709. abs_section_offset += stag->size;
  710. (void) restore_line_pointer (c);
  711. demand_empty_rest_of_line ();
  712. line_label = NULL;
  713. }
  714. /* Handle all .byte, .char, .double, .field, .float, .half, .int, .long,
  715. .short, .string, .ubyte, .uchar, .uhalf, .uint, .ulong, .ushort, .uword,
  716. and .word. */
  717. static void
  718. tic54x_struct_field (int type)
  719. {
  720. int size;
  721. int count = 1;
  722. int new_bitfield_offset = 0;
  723. int field_align = current_stag->current_bitfield_offset != 0;
  724. int longword_align = 0;
  725. SKIP_WHITESPACE ();
  726. if (!is_end_of_line[(int) *input_line_pointer])
  727. count = get_absolute_expression ();
  728. switch (type)
  729. {
  730. case 'b':
  731. case 'B':
  732. case 'c':
  733. case 'C':
  734. case 'h':
  735. case 'H':
  736. case 'i':
  737. case 'I':
  738. case 's':
  739. case 'S':
  740. case 'w':
  741. case 'W':
  742. case '*': /* String. */
  743. size = 1;
  744. break;
  745. case 'f':
  746. case 'l':
  747. case 'L':
  748. longword_align = 1;
  749. size = 2;
  750. break;
  751. case '.': /* Bitfield. */
  752. size = 0;
  753. if (count < 1 || count > 32)
  754. {
  755. as_bad (_(".field count '%d' out of range (1 <= X <= 32)"), count);
  756. ignore_rest_of_line ();
  757. return;
  758. }
  759. if (current_stag->current_bitfield_offset + count > 16)
  760. {
  761. /* Set the appropriate size and new field offset. */
  762. if (count == 32)
  763. {
  764. size = 2;
  765. count = 1;
  766. }
  767. else if (count > 16)
  768. {
  769. size = 1;
  770. count = 1;
  771. new_bitfield_offset = count - 16;
  772. }
  773. else
  774. new_bitfield_offset = count;
  775. }
  776. else
  777. {
  778. field_align = 0;
  779. new_bitfield_offset = current_stag->current_bitfield_offset + count;
  780. }
  781. break;
  782. default:
  783. as_bad (_("Unrecognized field type '%c'"), type);
  784. ignore_rest_of_line ();
  785. return;
  786. }
  787. if (field_align)
  788. {
  789. /* Align to the actual starting position of the field. */
  790. current_stag->current_bitfield_offset = 0;
  791. ++abs_section_offset;
  792. }
  793. /* Align to longword boundary. */
  794. if (longword_align && (abs_section_offset & 0x1))
  795. ++abs_section_offset;
  796. if (line_label == NULL)
  797. {
  798. static int fieldno = 0;
  799. char fake[] = ".fake_fieldNNNNN";
  800. sprintf (fake, ".fake_field%d", fieldno++);
  801. stag_add_field (current_stag, fake,
  802. abs_section_offset - S_GET_VALUE (current_stag->sym),
  803. NULL);
  804. }
  805. else
  806. {
  807. char label[strlen (S_GET_NAME (line_label) + 1)];
  808. strcpy (label, S_GET_NAME (line_label));
  809. stag_add_field (current_stag, label,
  810. abs_section_offset - S_GET_VALUE (current_stag->sym),
  811. NULL);
  812. }
  813. if (current_stag->is_union)
  814. {
  815. /* Note we treat the element as if it were an array of COUNT. */
  816. if (current_stag->size < (unsigned) size * count)
  817. current_stag->size = size * count;
  818. }
  819. else
  820. {
  821. abs_section_offset += (unsigned) size * count;
  822. current_stag->current_bitfield_offset = new_bitfield_offset;
  823. }
  824. line_label = NULL;
  825. }
  826. /* Handle .byte, .word. .int, .long and all variants. */
  827. static void
  828. tic54x_cons (int type)
  829. {
  830. unsigned int c;
  831. int octets;
  832. /* If we're within a .struct construct, don't actually allocate space. */
  833. if (current_stag != NULL)
  834. {
  835. tic54x_struct_field (type);
  836. return;
  837. }
  838. #ifdef md_flush_pending_output
  839. md_flush_pending_output ();
  840. #endif
  841. generate_lineno_debug ();
  842. /* Align long words to long word boundaries (4 octets). */
  843. if (type == 'l' || type == 'L')
  844. {
  845. frag_align (2, 0, 2);
  846. /* If there's a label, assign it to the first allocated word. */
  847. if (line_label != NULL)
  848. {
  849. symbol_set_frag (line_label, frag_now);
  850. S_SET_VALUE (line_label, frag_now_fix ());
  851. }
  852. }
  853. switch (type)
  854. {
  855. case 'l':
  856. case 'L':
  857. case 'x':
  858. octets = 4;
  859. break;
  860. case 'b':
  861. case 'B':
  862. case 'c':
  863. case 'C':
  864. octets = 1;
  865. break;
  866. default:
  867. octets = 2;
  868. break;
  869. }
  870. do
  871. {
  872. if (*input_line_pointer == '"')
  873. {
  874. input_line_pointer++;
  875. while (is_a_char (c = next_char_of_string ()))
  876. tic54x_emit_char (c);
  877. know (input_line_pointer[-1] == '\"');
  878. }
  879. else
  880. {
  881. expressionS expn;
  882. input_line_pointer = parse_expression (input_line_pointer, &expn);
  883. if (expn.X_op == O_constant)
  884. {
  885. offsetT value = expn.X_add_number;
  886. /* Truncate overflows. */
  887. switch (octets)
  888. {
  889. case 1:
  890. if ((value > 0 && value > 0xFF)
  891. || (value < 0 && value < - 0x100))
  892. as_warn (_("Overflow in expression, truncated to 8 bits"));
  893. break;
  894. case 2:
  895. if ((value > 0 && value > 0xFFFF)
  896. || (value < 0 && value < - 0x10000))
  897. as_warn (_("Overflow in expression, truncated to 16 bits"));
  898. break;
  899. }
  900. }
  901. if (expn.X_op != O_constant && octets < 2)
  902. {
  903. /* Disallow .byte with a non constant expression that will
  904. require relocation. */
  905. as_bad (_("Relocatable values require at least WORD storage"));
  906. ignore_rest_of_line ();
  907. return;
  908. }
  909. if (expn.X_op != O_constant
  910. && amode == c_mode
  911. && octets == 4)
  912. {
  913. /* FIXME -- at one point TI tools used to output REL16
  914. relocations, but I don't think the latest tools do at all
  915. The current tools output extended relocations regardless of
  916. the addressing mode (I actually think that ".c_mode" is
  917. totally ignored in the latest tools). */
  918. amode = far_mode;
  919. emitting_long = 1;
  920. emit_expr (&expn, 4);
  921. emitting_long = 0;
  922. amode = c_mode;
  923. }
  924. else
  925. {
  926. emitting_long = octets == 4;
  927. emit_expr (&expn, (octets == 1) ? 2 : octets);
  928. emitting_long = 0;
  929. }
  930. }
  931. }
  932. while (*input_line_pointer++ == ',');
  933. input_line_pointer--; /* Put terminator back into stream. */
  934. demand_empty_rest_of_line ();
  935. }
  936. /* .global <symbol>[,...,<symbolN>]
  937. .def <symbol>[,...,<symbolN>]
  938. .ref <symbol>[,...,<symbolN>]
  939. These all identify global symbols.
  940. .def means the symbol is defined in the current module and can be accessed
  941. by other files. The symbol should be placed in the symbol table.
  942. .ref means the symbol is used in the current module but defined in another
  943. module. The linker is to resolve this symbol's definition at link time.
  944. .global should act as a .ref or .def, as needed.
  945. global, def and ref all have symbol storage classes of C_EXT.
  946. I can't identify any difference in how the "other" c54x assembler treats
  947. these, so we ignore the type here. */
  948. void
  949. tic54x_global (int type)
  950. {
  951. char *name;
  952. int c;
  953. symbolS *symbolP;
  954. if (type == 'r')
  955. as_warn (_("Use of .def/.ref is deprecated. Use .global instead"));
  956. ILLEGAL_WITHIN_STRUCT ();
  957. do
  958. {
  959. c = get_symbol_name (&name);
  960. symbolP = symbol_find_or_make (name);
  961. c = restore_line_pointer (c);
  962. S_SET_STORAGE_CLASS (symbolP, C_EXT);
  963. if (c == ',')
  964. {
  965. input_line_pointer++;
  966. if (is_end_of_line[(int) *input_line_pointer])
  967. c = *input_line_pointer;
  968. }
  969. }
  970. while (c == ',');
  971. demand_empty_rest_of_line ();
  972. }
  973. /* Remove the symbol from the local label hash lookup. */
  974. static void
  975. tic54x_remove_local_label (const char *key, void *value ATTRIBUTE_UNUSED)
  976. {
  977. void *elem = hash_delete (local_label_hash[macro_level], key, FALSE);
  978. free (elem);
  979. }
  980. /* Reset all local labels. */
  981. static void
  982. tic54x_clear_local_labels (int ignored ATTRIBUTE_UNUSED)
  983. {
  984. hash_traverse (local_label_hash[macro_level], tic54x_remove_local_label);
  985. }
  986. /* .text
  987. .data
  988. .sect "section name"
  989. Initialized section
  990. make sure local labels get cleared when changing sections
  991. ARG is 't' for text, 'd' for data, or '*' for a named section
  992. For compatibility, '*' sections are SEC_CODE if instructions are
  993. encountered, or SEC_DATA if not.
  994. */
  995. static void
  996. tic54x_sect (int arg)
  997. {
  998. ILLEGAL_WITHIN_STRUCT ();
  999. /* Local labels are cleared when changing sections. */
  1000. tic54x_clear_local_labels (0);
  1001. if (arg == 't')
  1002. s_text (0);
  1003. else if (arg == 'd')
  1004. s_data (0);
  1005. else
  1006. {
  1007. char *name = NULL;
  1008. int len;
  1009. /* If there are quotes, remove them. */
  1010. if (*input_line_pointer == '"')
  1011. {
  1012. name = demand_copy_C_string (&len);
  1013. demand_empty_rest_of_line ();
  1014. name = strcpy (xmalloc (len + 10), name);
  1015. }
  1016. else
  1017. {
  1018. int c;
  1019. c = get_symbol_name (&name);
  1020. len = strlen(name);
  1021. name = strcpy (xmalloc (len + 10), name);
  1022. (void) restore_line_pointer (c);
  1023. demand_empty_rest_of_line ();
  1024. }
  1025. /* Make sure all named initialized sections flagged properly. If we
  1026. encounter instructions, we'll flag it with SEC_CODE as well. */
  1027. strcat (name, ",\"w\"\n");
  1028. input_scrub_insert_line (name);
  1029. obj_coff_section (0);
  1030. /* If there was a line label, make sure that it gets assigned the proper
  1031. section. This is for compatibility, even though the actual behavior
  1032. is not explicitly defined. For consistency, we make .sect behave
  1033. like .usect, since that is probably what people expect. */
  1034. if (line_label != NULL)
  1035. {
  1036. S_SET_SEGMENT (line_label, now_seg);
  1037. symbol_set_frag (line_label, frag_now);
  1038. S_SET_VALUE (line_label, frag_now_fix ());
  1039. if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
  1040. S_SET_STORAGE_CLASS (line_label, C_LABEL);
  1041. }
  1042. }
  1043. }
  1044. /* [symbol] .space space_in_bits
  1045. [symbol] .bes space_in_bits
  1046. BES puts the symbol at the *last* word allocated
  1047. cribbed from s_space. */
  1048. static void
  1049. tic54x_space (int arg)
  1050. {
  1051. expressionS expn;
  1052. char *p = 0;
  1053. int octets = 0;
  1054. long words;
  1055. int bits_per_byte = (OCTETS_PER_BYTE * 8);
  1056. int bit_offset = 0;
  1057. symbolS *label = line_label;
  1058. int bes = arg;
  1059. ILLEGAL_WITHIN_STRUCT ();
  1060. #ifdef md_flush_pending_output
  1061. md_flush_pending_output ();
  1062. #endif
  1063. /* Read the bit count. */
  1064. expression (&expn);
  1065. /* Some expressions are unresolvable until later in the assembly pass;
  1066. postpone until relaxation/fixup. we also have to postpone if a previous
  1067. partial allocation has not been completed yet. */
  1068. if (expn.X_op != O_constant || frag_bit_offset (frag_now, now_seg) == -1)
  1069. {
  1070. struct bit_info *bi = xmalloc (sizeof (struct bit_info));
  1071. bi->seg = now_seg;
  1072. bi->type = bes;
  1073. bi->sym = label;
  1074. p = frag_var (rs_machine_dependent,
  1075. 65536 * 2, 1, (relax_substateT) 0,
  1076. make_expr_symbol (&expn), (offsetT) 0,
  1077. (char *) bi);
  1078. if (p)
  1079. *p = 0;
  1080. return;
  1081. }
  1082. /* Reduce the required size by any bit offsets currently left over
  1083. from a previous .space/.bes/.field directive. */
  1084. bit_offset = frag_now->tc_frag_data;
  1085. if (bit_offset != 0 && bit_offset < 16)
  1086. {
  1087. int spare_bits = bits_per_byte - bit_offset;
  1088. if (spare_bits >= expn.X_add_number)
  1089. {
  1090. /* Don't have to do anything; sufficient bits have already been
  1091. allocated; just point the label to the right place. */
  1092. if (label != NULL)
  1093. {
  1094. symbol_set_frag (label, frag_now);
  1095. S_SET_VALUE (label, frag_now_fix () - 1);
  1096. label = NULL;
  1097. }
  1098. frag_now->tc_frag_data += expn.X_add_number;
  1099. goto getout;
  1100. }
  1101. expn.X_add_number -= spare_bits;
  1102. /* Set the label to point to the first word allocated, which in this
  1103. case is the previous word, which was only partially filled. */
  1104. if (!bes && label != NULL)
  1105. {
  1106. symbol_set_frag (label, frag_now);
  1107. S_SET_VALUE (label, frag_now_fix () - 1);
  1108. label = NULL;
  1109. }
  1110. }
  1111. /* Convert bits to bytes/words and octets, rounding up. */
  1112. words = ((expn.X_add_number + bits_per_byte - 1) / bits_per_byte);
  1113. /* How many do we have left over? */
  1114. bit_offset = expn.X_add_number % bits_per_byte;
  1115. octets = words * OCTETS_PER_BYTE;
  1116. if (octets < 0)
  1117. {
  1118. as_warn (_(".space/.bes repeat count is negative, ignored"));
  1119. goto getout;
  1120. }
  1121. else if (octets == 0)
  1122. {
  1123. as_warn (_(".space/.bes repeat count is zero, ignored"));
  1124. goto getout;
  1125. }
  1126. /* If we are in the absolute section, just bump the offset. */
  1127. if (now_seg == absolute_section)
  1128. {
  1129. abs_section_offset += words;
  1130. if (bes && label != NULL)
  1131. S_SET_VALUE (label, abs_section_offset - 1);
  1132. frag_now->tc_frag_data = bit_offset;
  1133. goto getout;
  1134. }
  1135. if (!need_pass_2)
  1136. p = frag_var (rs_fill, 1, 1,
  1137. (relax_substateT) 0, (symbolS *) 0,
  1138. (offsetT) octets, (char *) 0);
  1139. /* Make note of how many bits of this word we've allocated so far. */
  1140. frag_now->tc_frag_data = bit_offset;
  1141. /* .bes puts label at *last* word allocated. */
  1142. if (bes && label != NULL)
  1143. {
  1144. symbol_set_frag (label, frag_now);
  1145. S_SET_VALUE (label, frag_now_fix () - 1);
  1146. }
  1147. if (p)
  1148. *p = 0;
  1149. getout:
  1150. demand_empty_rest_of_line ();
  1151. }
  1152. /* [symbol] .usect "section-name", size-in-words
  1153. [, [blocking-flag] [, alignment-flag]]
  1154. Uninitialized section.
  1155. Non-zero blocking means that if the section would cross a page (128-word)
  1156. boundary, it will be page-aligned.
  1157. Non-zero alignment aligns on a longword boundary.
  1158. Has no effect on the current section. */
  1159. static void
  1160. tic54x_usect (int x ATTRIBUTE_UNUSED)
  1161. {
  1162. char c;
  1163. char *name;
  1164. char *section_name;
  1165. char *p;
  1166. segT seg;
  1167. int size, blocking_flag, alignment_flag;
  1168. segT current_seg;
  1169. subsegT current_subseg;
  1170. flagword flags;
  1171. ILLEGAL_WITHIN_STRUCT ();
  1172. current_seg = now_seg; /* Save current seg. */
  1173. current_subseg = now_subseg; /* Save current subseg. */
  1174. c = get_symbol_name (&section_name); /* Get terminator. */
  1175. name = xmalloc (input_line_pointer - section_name + 1);
  1176. strcpy (name, section_name);
  1177. c = restore_line_pointer (c);
  1178. if (c == ',')
  1179. ++input_line_pointer;
  1180. else
  1181. {
  1182. as_bad (_("Missing size argument"));
  1183. ignore_rest_of_line ();
  1184. return;
  1185. }
  1186. size = get_absolute_expression ();
  1187. /* Read a possibly present third argument (blocking flag). */
  1188. if (*input_line_pointer == ',')
  1189. {
  1190. ++input_line_pointer;
  1191. if (*input_line_pointer != ',')
  1192. blocking_flag = get_absolute_expression ();
  1193. else
  1194. blocking_flag = 0;
  1195. /* Read a possibly present fourth argument (alignment flag). */
  1196. if (*input_line_pointer == ',')
  1197. {
  1198. ++input_line_pointer;
  1199. alignment_flag = get_absolute_expression ();
  1200. }
  1201. else
  1202. alignment_flag = 0;
  1203. }
  1204. else
  1205. blocking_flag = alignment_flag = 0;
  1206. seg = subseg_new (name, 0);
  1207. flags = bfd_get_section_flags (stdoutput, seg) | SEC_ALLOC;
  1208. if (alignment_flag)
  1209. {
  1210. /* s_align eats end of line; restore it. */
  1211. s_align_bytes (4);
  1212. --input_line_pointer;
  1213. }
  1214. if (line_label != NULL)
  1215. {
  1216. S_SET_SEGMENT (line_label, seg);
  1217. symbol_set_frag (line_label, frag_now);
  1218. S_SET_VALUE (line_label, frag_now_fix ());
  1219. /* Set scl to label, since that's what TI does. */
  1220. if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
  1221. S_SET_STORAGE_CLASS (line_label, C_LABEL);
  1222. }
  1223. seg_info (seg)->bss = 1; /* Uninitialized data. */
  1224. p = frag_var (rs_fill, 1, 1,
  1225. (relax_substateT) 0, (symbolS *) line_label,
  1226. size * OCTETS_PER_BYTE, (char *) 0);
  1227. *p = 0;
  1228. if (blocking_flag)
  1229. flags |= SEC_TIC54X_BLOCK;
  1230. if (!bfd_set_section_flags (stdoutput, seg, flags))
  1231. as_warn (_("Error setting flags for \"%s\": %s"), name,
  1232. bfd_errmsg (bfd_get_error ()));
  1233. subseg_set (current_seg, current_subseg); /* Restore current seg. */
  1234. demand_empty_rest_of_line ();
  1235. }
  1236. static enum cpu_version
  1237. lookup_version (const char *ver)
  1238. {
  1239. enum cpu_version version = VNONE;
  1240. if (ver[0] == '5' && ver[1] == '4')
  1241. {
  1242. if (strlen (ver) == 3
  1243. && (ver[2] == '1' || ver[2] == '2' || ver[2] == '3'
  1244. || ver[2] == '5' || ver[2] == '8' || ver[2] == '9'))
  1245. version = ver[2] - '0';
  1246. else if (strlen (ver) == 5
  1247. && TOUPPER (ver[3]) == 'L'
  1248. && TOUPPER (ver[4]) == 'P'
  1249. && (ver[2] == '5' || ver[2] == '6'))
  1250. version = ver[2] - '0' + 10;
  1251. }
  1252. return version;
  1253. }
  1254. static void
  1255. set_cpu (enum cpu_version version)
  1256. {
  1257. cpu = version;
  1258. if (version == V545LP || version == V546LP)
  1259. {
  1260. symbolS *symbolP = symbol_new ("__allow_lp", absolute_section,
  1261. (valueT) 1, &zero_address_frag);
  1262. SF_SET_LOCAL (symbolP);
  1263. symbol_table_insert (symbolP);
  1264. }
  1265. }
  1266. /* .version cpu-version
  1267. cpu-version may be one of the following:
  1268. 541
  1269. 542
  1270. 543
  1271. 545
  1272. 545LP
  1273. 546LP
  1274. 548
  1275. 549
  1276. This is for compatibility only. It currently has no affect on assembly. */
  1277. static int cpu_needs_set = 1;
  1278. static void
  1279. tic54x_version (int x ATTRIBUTE_UNUSED)
  1280. {
  1281. enum cpu_version version = VNONE;
  1282. enum cpu_version old_version = cpu;
  1283. int c;
  1284. char *ver;
  1285. ILLEGAL_WITHIN_STRUCT ();
  1286. SKIP_WHITESPACE ();
  1287. ver = input_line_pointer;
  1288. while (!is_end_of_line[(int) *input_line_pointer])
  1289. ++input_line_pointer;
  1290. c = *input_line_pointer;
  1291. *input_line_pointer = 0;
  1292. version = lookup_version (ver);
  1293. if (cpu != VNONE && cpu != version)
  1294. as_warn (_("CPU version has already been set"));
  1295. if (version == VNONE)
  1296. {
  1297. as_bad (_("Unrecognized version '%s'"), ver);
  1298. ignore_rest_of_line ();
  1299. return;
  1300. }
  1301. else if (assembly_begun && version != old_version)
  1302. {
  1303. as_bad (_("Changing of CPU version on the fly not supported"));
  1304. ignore_rest_of_line ();
  1305. return;
  1306. }
  1307. set_cpu (version);
  1308. *input_line_pointer = c;
  1309. demand_empty_rest_of_line ();
  1310. }
  1311. /* 'f' = float, 'x' = xfloat, 'd' = double, 'l' = ldouble. */
  1312. static void
  1313. tic54x_float_cons (int type)
  1314. {
  1315. if (current_stag != 0)
  1316. tic54x_struct_field ('f');
  1317. #ifdef md_flush_pending_output
  1318. md_flush_pending_output ();
  1319. #endif
  1320. /* Align to long word boundary (4 octets) unless it's ".xfloat". */
  1321. if (type != 'x')
  1322. {
  1323. frag_align (2, 0, 2);
  1324. /* If there's a label, assign it to the first allocated word. */
  1325. if (line_label != NULL)
  1326. {
  1327. symbol_set_frag (line_label, frag_now);
  1328. S_SET_VALUE (line_label, frag_now_fix ());
  1329. }
  1330. }
  1331. float_cons ('f');
  1332. }
  1333. /* The argument is capitalized if it should be zero-terminated
  1334. 's' is normal string with upper 8-bits zero-filled, 'p' is packed.
  1335. Code copied from stringer, and slightly modified so that strings are packed
  1336. and encoded into the correct octets. */
  1337. static void
  1338. tic54x_stringer (int type)
  1339. {
  1340. unsigned int c;
  1341. int append_zero = type == 'S' || type == 'P';
  1342. int packed = type == 'p' || type == 'P';
  1343. int last_char = -1; /* Packed strings need two bytes at a time to encode. */
  1344. if (current_stag != NULL)
  1345. {
  1346. tic54x_struct_field ('*');
  1347. return;
  1348. }
  1349. #ifdef md_flush_pending_output
  1350. md_flush_pending_output ();
  1351. #endif
  1352. c = ','; /* Do loop. */
  1353. while (c == ',')
  1354. {
  1355. SKIP_WHITESPACE ();
  1356. switch (*input_line_pointer)
  1357. {
  1358. default:
  1359. {
  1360. unsigned short value = get_absolute_expression ();
  1361. FRAG_APPEND_1_CHAR ( value & 0xFF);
  1362. FRAG_APPEND_1_CHAR ((value >> 8) & 0xFF);
  1363. break;
  1364. }
  1365. case '\"':
  1366. ++input_line_pointer; /* -> 1st char of string. */
  1367. while (is_a_char (c = next_char_of_string ()))
  1368. {
  1369. if (!packed)
  1370. {
  1371. FRAG_APPEND_1_CHAR (c);
  1372. FRAG_APPEND_1_CHAR (0);
  1373. }
  1374. else
  1375. {
  1376. /* Packed strings are filled MS octet first. */
  1377. if (last_char == -1)
  1378. last_char = c;
  1379. else
  1380. {
  1381. FRAG_APPEND_1_CHAR (c);
  1382. FRAG_APPEND_1_CHAR (last_char);
  1383. last_char = -1;
  1384. }
  1385. }
  1386. }
  1387. if (append_zero)
  1388. {
  1389. if (packed && last_char != -1)
  1390. {
  1391. FRAG_APPEND_1_CHAR (0);
  1392. FRAG_APPEND_1_CHAR (last_char);
  1393. last_char = -1;
  1394. }
  1395. else
  1396. {
  1397. FRAG_APPEND_1_CHAR (0);
  1398. FRAG_APPEND_1_CHAR (0);
  1399. }
  1400. }
  1401. know (input_line_pointer[-1] == '\"');
  1402. break;
  1403. }
  1404. SKIP_WHITESPACE ();
  1405. c = *input_line_pointer;
  1406. if (!is_end_of_line[c])
  1407. ++input_line_pointer;
  1408. }
  1409. /* Finish up any leftover packed string. */
  1410. if (packed && last_char != -1)
  1411. {
  1412. FRAG_APPEND_1_CHAR (0);
  1413. FRAG_APPEND_1_CHAR (last_char);
  1414. }
  1415. demand_empty_rest_of_line ();
  1416. }
  1417. static void
  1418. tic54x_p2align (int arg ATTRIBUTE_UNUSED)
  1419. {
  1420. as_bad (_("p2align not supported on this target"));
  1421. }
  1422. static void
  1423. tic54x_align_words (int arg)
  1424. {
  1425. /* Only ".align" with no argument is allowed within .struct/.union. */
  1426. int count = arg;
  1427. if (!is_end_of_line[(int) *input_line_pointer])
  1428. {
  1429. if (arg == 2)
  1430. as_warn (_("Argument to .even ignored"));
  1431. else
  1432. count = get_absolute_expression ();
  1433. }
  1434. if (current_stag != NULL && arg == 128)
  1435. {
  1436. if (current_stag->current_bitfield_offset != 0)
  1437. {
  1438. current_stag->current_bitfield_offset = 0;
  1439. ++abs_section_offset;
  1440. }
  1441. demand_empty_rest_of_line ();
  1442. return;
  1443. }
  1444. ILLEGAL_WITHIN_STRUCT ();
  1445. s_align_bytes (count << 1);
  1446. }
  1447. /* Initialize multiple-bit fields withing a single word of memory. */
  1448. static void
  1449. tic54x_field (int ignore ATTRIBUTE_UNUSED)
  1450. {
  1451. expressionS expn;
  1452. int size = 16;
  1453. char *p;
  1454. valueT value;
  1455. symbolS *label = line_label;
  1456. if (current_stag != NULL)
  1457. {
  1458. tic54x_struct_field ('.');
  1459. return;
  1460. }
  1461. input_line_pointer = parse_expression (input_line_pointer, &expn);
  1462. if (*input_line_pointer == ',')
  1463. {
  1464. ++input_line_pointer;
  1465. size = get_absolute_expression ();
  1466. if (size < 1 || size > 32)
  1467. {
  1468. as_bad (_("Invalid field size, must be from 1 to 32"));
  1469. ignore_rest_of_line ();
  1470. return;
  1471. }
  1472. }
  1473. /* Truncate values to the field width. */
  1474. if (expn.X_op != O_constant)
  1475. {
  1476. /* If the expression value is relocatable, the field size *must*
  1477. be 16. */
  1478. if (size != 16)
  1479. {
  1480. as_bad (_("field size must be 16 when value is relocatable"));
  1481. ignore_rest_of_line ();
  1482. return;
  1483. }
  1484. frag_now->tc_frag_data = 0;
  1485. emit_expr (&expn, 2);
  1486. }
  1487. else
  1488. {
  1489. unsigned long fmask = (size == 32) ? 0xFFFFFFFF : (1ul << size) - 1;
  1490. value = expn.X_add_number;
  1491. expn.X_add_number &= fmask;
  1492. if (value != (valueT) expn.X_add_number)
  1493. as_warn (_("field value truncated"));
  1494. value = expn.X_add_number;
  1495. /* Bits are stored MS first. */
  1496. while (size >= 16)
  1497. {
  1498. frag_now->tc_frag_data = 0;
  1499. p = frag_more (2);
  1500. md_number_to_chars (p, (value >> (size - 16)) & 0xFFFF, 2);
  1501. size -= 16;
  1502. }
  1503. if (size > 0)
  1504. {
  1505. int bit_offset = frag_bit_offset (frag_now, now_seg);
  1506. fragS *alloc_frag = bit_offset_frag (frag_now, now_seg);
  1507. if (bit_offset == -1)
  1508. {
  1509. struct bit_info *bi = xmalloc (sizeof (struct bit_info));
  1510. /* We don't know the previous offset at this time, so store the
  1511. info we need and figure it out later. */
  1512. expressionS size_exp;
  1513. size_exp.X_op = O_constant;
  1514. size_exp.X_add_number = size;
  1515. bi->seg = now_seg;
  1516. bi->type = TYPE_FIELD;
  1517. bi->value = value;
  1518. p = frag_var (rs_machine_dependent,
  1519. 4, 1, (relax_substateT) 0,
  1520. make_expr_symbol (&size_exp), (offsetT) 0,
  1521. (char *) bi);
  1522. goto getout;
  1523. }
  1524. else if (bit_offset == 0 || bit_offset + size > 16)
  1525. {
  1526. /* Align a new field. */
  1527. p = frag_more (2);
  1528. frag_now->tc_frag_data = 0;
  1529. alloc_frag = frag_now;
  1530. }
  1531. else
  1532. {
  1533. /* Put the new value entirely within the existing one. */
  1534. p = alloc_frag == frag_now ?
  1535. frag_now->fr_literal + frag_now_fix_octets () - 2 :
  1536. alloc_frag->fr_literal;
  1537. if (label != NULL)
  1538. {
  1539. symbol_set_frag (label, alloc_frag);
  1540. if (alloc_frag == frag_now)
  1541. S_SET_VALUE (label, frag_now_fix () - 1);
  1542. label = NULL;
  1543. }
  1544. }
  1545. value <<= 16 - alloc_frag->tc_frag_data - size;
  1546. /* OR in existing value. */
  1547. if (alloc_frag->tc_frag_data)
  1548. value |= ((unsigned short) p[1] << 8) | p[0];
  1549. md_number_to_chars (p, value, 2);
  1550. alloc_frag->tc_frag_data += size;
  1551. if (alloc_frag->tc_frag_data == 16)
  1552. alloc_frag->tc_frag_data = 0;
  1553. }
  1554. }
  1555. getout:
  1556. demand_empty_rest_of_line ();
  1557. }
  1558. /* Ideally, we want to check SEC_LOAD and SEC_HAS_CONTENTS, but those aren't
  1559. available yet. seg_info ()->bss is the next best thing. */
  1560. static int
  1561. tic54x_initialized_section (segT seg)
  1562. {
  1563. return !seg_info (seg)->bss;
  1564. }
  1565. /* .clink ["section name"]
  1566. Marks the section as conditionally linked (link only if contents are
  1567. referenced elsewhere.
  1568. Without a name, refers to the current initialized section.
  1569. Name is required for uninitialized sections. */
  1570. static void
  1571. tic54x_clink (int ignored ATTRIBUTE_UNUSED)
  1572. {
  1573. segT seg = now_seg;
  1574. ILLEGAL_WITHIN_STRUCT ();
  1575. if (*input_line_pointer == '\"')
  1576. {
  1577. char *section_name = ++input_line_pointer;
  1578. char *name;
  1579. while (is_a_char (next_char_of_string ()))
  1580. ;
  1581. know (input_line_pointer[-1] == '\"');
  1582. input_line_pointer[-1] = 0;
  1583. name = xmalloc (input_line_pointer - section_name + 1);
  1584. strcpy (name, section_name);
  1585. seg = bfd_get_section_by_name (stdoutput, name);
  1586. if (seg == NULL)
  1587. {
  1588. as_bad (_("Unrecognized section '%s'"), section_name);
  1589. ignore_rest_of_line ();
  1590. return;
  1591. }
  1592. }
  1593. else
  1594. {
  1595. if (!tic54x_initialized_section (seg))
  1596. {
  1597. as_bad (_("Current section is unitialized, "
  1598. "section name required for .clink"));
  1599. ignore_rest_of_line ();
  1600. return;
  1601. }
  1602. }
  1603. seg->flags |= SEC_TIC54X_CLINK;
  1604. demand_empty_rest_of_line ();
  1605. }
  1606. /* Change the default include directory to be the current source file's
  1607. directory, instead of the current working directory. If DOT is non-zero,
  1608. set to "." instead. */
  1609. static void
  1610. tic54x_set_default_include (int dot)
  1611. {
  1612. char *dir = ".";
  1613. char *tmp = NULL;
  1614. if (!dot)
  1615. {
  1616. char *curfile;
  1617. unsigned lineno;
  1618. as_where (&curfile, &lineno);
  1619. dir = strcpy (xmalloc (strlen (curfile) + 1), curfile);
  1620. tmp = strrchr (dir, '/');
  1621. }
  1622. if (tmp != NULL)
  1623. {
  1624. int len;
  1625. *tmp = '\0';
  1626. len = strlen (dir);
  1627. if (include_dir_count == 0)
  1628. {
  1629. include_dirs = (char **) xmalloc (sizeof (*include_dirs));
  1630. include_dir_count = 1;
  1631. }
  1632. include_dirs[0] = dir;
  1633. if (len > include_dir_maxlen)
  1634. include_dir_maxlen = len;
  1635. }
  1636. else if (include_dirs != NULL)
  1637. include_dirs[0] = ".";
  1638. }
  1639. /* .include "filename" | filename
  1640. .copy "filename" | filename
  1641. FIXME 'include' file should be omitted from any output listing,
  1642. 'copy' should be included in any output listing
  1643. FIXME -- prevent any included files from changing listing (compat only)
  1644. FIXME -- need to include source file directory in search path; what's a
  1645. good way to do this?
  1646. Entering/exiting included/copied file clears all local labels. */
  1647. static void
  1648. tic54x_include (int ignored ATTRIBUTE_UNUSED)
  1649. {
  1650. char newblock[] = " .newblock\n";
  1651. char *filename;
  1652. char *input;
  1653. int len, c = -1;
  1654. ILLEGAL_WITHIN_STRUCT ();
  1655. SKIP_WHITESPACE ();
  1656. if (*input_line_pointer == '"')
  1657. {
  1658. filename = demand_copy_C_string (&len);
  1659. demand_empty_rest_of_line ();
  1660. }
  1661. else
  1662. {
  1663. filename = input_line_pointer;
  1664. while (!is_end_of_line[(int) *input_line_pointer])
  1665. ++input_line_pointer;
  1666. c = *input_line_pointer;
  1667. *input_line_pointer = '\0';
  1668. filename = strcpy (xmalloc (strlen (filename) + 1), filename);
  1669. *input_line_pointer = c;
  1670. demand_empty_rest_of_line ();
  1671. }
  1672. /* Insert a partial line with the filename (for the sake of s_include)
  1673. and a .newblock.
  1674. The included file will be inserted before the newblock, so that the
  1675. newblock is executed after the included file is processed. */
  1676. input = xmalloc (sizeof (newblock) + strlen (filename) + 4);
  1677. sprintf (input, "\"%s\"\n%s", filename, newblock);
  1678. input_scrub_insert_line (input);
  1679. tic54x_clear_local_labels (0);
  1680. tic54x_set_default_include (0);
  1681. s_include (0);
  1682. }
  1683. static void
  1684. tic54x_message (int type)
  1685. {
  1686. char *msg;
  1687. char c;
  1688. int len;
  1689. ILLEGAL_WITHIN_STRUCT ();
  1690. if (*input_line_pointer == '"')
  1691. msg = demand_copy_C_string (&len);
  1692. else
  1693. {
  1694. msg = input_line_pointer;
  1695. while (!is_end_of_line[(int) *input_line_pointer])
  1696. ++input_line_pointer;
  1697. c = *input_line_pointer;
  1698. *input_line_pointer = 0;
  1699. msg = strcpy (xmalloc (strlen (msg) + 1), msg);
  1700. *input_line_pointer = c;
  1701. }
  1702. switch (type)
  1703. {
  1704. case 'm':
  1705. as_tsktsk ("%s", msg);
  1706. break;
  1707. case 'w':
  1708. as_warn ("%s", msg);
  1709. break;
  1710. case 'e':
  1711. as_bad ("%s", msg);
  1712. break;
  1713. }
  1714. demand_empty_rest_of_line ();
  1715. }
  1716. /* .label <symbol>
  1717. Define a special symbol that refers to the loadtime address rather than the
  1718. runtime address within the current section.
  1719. This symbol gets a special storage class so that when it is resolved, it is
  1720. resolved relative to the load address (lma) of the section rather than the
  1721. run address (vma). */
  1722. static void
  1723. tic54x_label (int ignored ATTRIBUTE_UNUSED)
  1724. {
  1725. char *name;
  1726. symbolS *symbolP;
  1727. int c;
  1728. ILLEGAL_WITHIN_STRUCT ();
  1729. c = get_symbol_name (&name);
  1730. symbolP = colon (name);
  1731. S_SET_STORAGE_CLASS (symbolP, C_STATLAB);
  1732. (void) restore_line_pointer (c);
  1733. demand_empty_rest_of_line ();
  1734. }
  1735. /* .mmregs
  1736. Install all memory-mapped register names into the symbol table as
  1737. absolute local symbols. */
  1738. static void
  1739. tic54x_mmregs (int ignored ATTRIBUTE_UNUSED)
  1740. {
  1741. symbol *sym;
  1742. ILLEGAL_WITHIN_STRUCT ();
  1743. for (sym = (symbol *) mmregs; sym->name; sym++)
  1744. {
  1745. symbolS *symbolP = symbol_new (sym->name, absolute_section,
  1746. (valueT) sym->value, &zero_address_frag);
  1747. SF_SET_LOCAL (symbolP);
  1748. symbol_table_insert (symbolP);
  1749. }
  1750. }
  1751. /* .loop [count]
  1752. Count defaults to 1024. */
  1753. static void
  1754. tic54x_loop (int count)
  1755. {
  1756. ILLEGAL_WITHIN_STRUCT ();
  1757. SKIP_WHITESPACE ();
  1758. if (!is_end_of_line[(int) *input_line_pointer])
  1759. count = get_absolute_expression ();
  1760. do_repeat (count, "LOOP", "ENDLOOP");
  1761. }
  1762. /* Normally, endloop gets eaten by the preceding loop. */
  1763. static void
  1764. tic54x_endloop (int ignore ATTRIBUTE_UNUSED)
  1765. {
  1766. as_bad (_("ENDLOOP without corresponding LOOP"));
  1767. ignore_rest_of_line ();
  1768. }
  1769. /* .break [condition]. */
  1770. static void
  1771. tic54x_break (int ignore ATTRIBUTE_UNUSED)
  1772. {
  1773. int cond = 1;
  1774. ILLEGAL_WITHIN_STRUCT ();
  1775. SKIP_WHITESPACE ();
  1776. if (!is_end_of_line[(int) *input_line_pointer])
  1777. cond = get_absolute_expression ();
  1778. if (cond)
  1779. end_repeat (substitution_line ? 1 : 0);
  1780. }
  1781. static void
  1782. set_address_mode (int mode)
  1783. {
  1784. amode = mode;
  1785. if (mode == far_mode)
  1786. {
  1787. symbolS *symbolP = symbol_new ("__allow_far", absolute_section,
  1788. (valueT) 1, &zero_address_frag);
  1789. SF_SET_LOCAL (symbolP);
  1790. symbol_table_insert (symbolP);
  1791. }
  1792. }
  1793. static int address_mode_needs_set = 1;
  1794. static void
  1795. tic54x_address_mode (int mode)
  1796. {
  1797. if (assembly_begun && amode != (unsigned) mode)
  1798. {
  1799. as_bad (_("Mixing of normal and extended addressing not supported"));
  1800. ignore_rest_of_line ();
  1801. return;
  1802. }
  1803. if (mode == far_mode && cpu != VNONE && cpu != V548 && cpu != V549)
  1804. {
  1805. as_bad (_("Extended addressing not supported on the specified CPU"));
  1806. ignore_rest_of_line ();
  1807. return;
  1808. }
  1809. set_address_mode (mode);
  1810. demand_empty_rest_of_line ();
  1811. }
  1812. /* .sblock "section"|section [,...,"section"|section]
  1813. Designate initialized sections for blocking. */
  1814. static void
  1815. tic54x_sblock (int ignore ATTRIBUTE_UNUSED)
  1816. {
  1817. int c = ',';
  1818. ILLEGAL_WITHIN_STRUCT ();
  1819. while (c == ',')
  1820. {
  1821. segT seg;
  1822. char *name;
  1823. if (*input_line_pointer == '"')
  1824. {
  1825. int len;
  1826. name = demand_copy_C_string (&len);
  1827. }
  1828. else
  1829. {
  1830. char *section_name;
  1831. c = get_symbol_name (&section_name);
  1832. name = xmalloc (strlen (section_name) + 1);
  1833. strcpy (name, section_name);
  1834. (void) restore_line_pointer (c);
  1835. }
  1836. seg = bfd_get_section_by_name (stdoutput, name);
  1837. if (seg == NULL)
  1838. {
  1839. as_bad (_("Unrecognized section '%s'"), name);
  1840. ignore_rest_of_line ();
  1841. return;
  1842. }
  1843. else if (!tic54x_initialized_section (seg))
  1844. {
  1845. as_bad (_(".sblock may be used for initialized sections only"));
  1846. ignore_rest_of_line ();
  1847. return;
  1848. }
  1849. seg->flags |= SEC_TIC54X_BLOCK;
  1850. c = *input_line_pointer;
  1851. if (!is_end_of_line[(int) c])
  1852. ++input_line_pointer;
  1853. }
  1854. demand_empty_rest_of_line ();
  1855. }
  1856. /* symbol .set value
  1857. symbol .equ value
  1858. value must be defined externals; no forward-referencing allowed
  1859. symbols assigned with .set/.equ may not be redefined. */
  1860. static void
  1861. tic54x_set (int ignore ATTRIBUTE_UNUSED)
  1862. {
  1863. symbolS *symbolP;
  1864. char *name;
  1865. ILLEGAL_WITHIN_STRUCT ();
  1866. if (!line_label)
  1867. {
  1868. as_bad (_("Symbol missing for .set/.equ"));
  1869. ignore_rest_of_line ();
  1870. return;
  1871. }
  1872. name = xstrdup (S_GET_NAME (line_label));
  1873. line_label = NULL;
  1874. if ((symbolP = symbol_find (name)) == NULL
  1875. && (symbolP = md_undefined_symbol (name)) == NULL)
  1876. {
  1877. symbolP = symbol_new (name, absolute_section, 0, &zero_address_frag);
  1878. S_SET_STORAGE_CLASS (symbolP, C_STAT);
  1879. }
  1880. free (name);
  1881. S_SET_DATA_TYPE (symbolP, T_INT);
  1882. S_SET_SEGMENT (symbolP, absolute_section);
  1883. symbol_table_insert (symbolP);
  1884. pseudo_set (symbolP);
  1885. demand_empty_rest_of_line ();
  1886. }
  1887. /* .fclist
  1888. .fcnolist
  1889. List false conditional blocks. */
  1890. static void
  1891. tic54x_fclist (int show)
  1892. {
  1893. if (show)
  1894. listing &= ~LISTING_NOCOND;
  1895. else
  1896. listing |= LISTING_NOCOND;
  1897. demand_empty_rest_of_line ();
  1898. }
  1899. static void
  1900. tic54x_sslist (int show)
  1901. {
  1902. ILLEGAL_WITHIN_STRUCT ();
  1903. listing_sslist = show;
  1904. }
  1905. /* .var SYM[,...,SYMN]
  1906. Define a substitution string to be local to a macro. */
  1907. static void
  1908. tic54x_var (int ignore ATTRIBUTE_UNUSED)
  1909. {
  1910. static char empty[] = "";
  1911. char *name;
  1912. int c;
  1913. ILLEGAL_WITHIN_STRUCT ();
  1914. if (macro_level == 0)
  1915. {
  1916. as_bad (_(".var may only be used within a macro definition"));
  1917. ignore_rest_of_line ();
  1918. return;
  1919. }
  1920. do
  1921. {
  1922. if (!ISALPHA (*input_line_pointer))
  1923. {
  1924. as_bad (_("Substitution symbols must begin with a letter"));
  1925. ignore_rest_of_line ();
  1926. return;
  1927. }
  1928. c = get_symbol_name (&name);
  1929. /* .var symbols start out with a null string. */
  1930. name = strcpy (xmalloc (strlen (name) + 1), name);
  1931. hash_insert (subsym_hash[macro_level], name, empty);
  1932. c = restore_line_pointer (c);
  1933. if (c == ',')
  1934. {
  1935. ++input_line_pointer;
  1936. if (is_end_of_line[(int) *input_line_pointer])
  1937. c = *input_line_pointer;
  1938. }
  1939. }
  1940. while (c == ',');
  1941. demand_empty_rest_of_line ();
  1942. }
  1943. /* .mlib <macro library filename>
  1944. Macro libraries are archived (standard AR-format) text macro definitions
  1945. Expand the file and include it.
  1946. FIXME need to try the source file directory as well. */
  1947. static void
  1948. tic54x_mlib (int ignore ATTRIBUTE_UNUSED)
  1949. {
  1950. char *filename;
  1951. char *path;
  1952. int len, i;
  1953. bfd *abfd, *mbfd;
  1954. ILLEGAL_WITHIN_STRUCT ();
  1955. /* Parse the filename. */
  1956. if (*input_line_pointer == '"')
  1957. {
  1958. if ((filename = demand_copy_C_string (&len)) == NULL)
  1959. return;
  1960. }
  1961. else
  1962. {
  1963. SKIP_WHITESPACE ();
  1964. len = 0;
  1965. while (!is_end_of_line[(int) *input_line_pointer]
  1966. && !ISSPACE (*input_line_pointer))
  1967. {
  1968. obstack_1grow (&notes, *input_line_pointer);
  1969. ++input_line_pointer;
  1970. ++len;
  1971. }
  1972. obstack_1grow (&notes, '\0');
  1973. filename = obstack_finish (&notes);
  1974. }
  1975. demand_empty_rest_of_line ();
  1976. tic54x_set_default_include (0);
  1977. path = xmalloc ((unsigned long) len + include_dir_maxlen + 5);
  1978. for (i = 0; i < include_dir_count; i++)
  1979. {
  1980. FILE *try;
  1981. strcpy (path, include_dirs[i]);
  1982. strcat (path, "/");
  1983. strcat (path, filename);
  1984. if ((try = fopen (path, "r")) != NULL)
  1985. {
  1986. fclose (try);
  1987. break;
  1988. }
  1989. }
  1990. if (i >= include_dir_count)
  1991. {
  1992. free (path);
  1993. path = filename;
  1994. }
  1995. /* FIXME: if path is found, malloc'd storage is not freed. Of course, this
  1996. happens all over the place, and since the assembler doesn't usually keep
  1997. running for a very long time, it really doesn't matter. */
  1998. register_dependency (path);
  1999. /* Expand all archive entries to temporary files and include them. */
  2000. abfd = bfd_openr (path, NULL);
  2001. if (!abfd)
  2002. {
  2003. as_bad (_("can't open macro library file '%s' for reading: %s"),
  2004. path, bfd_errmsg (bfd_get_error ()));
  2005. ignore_rest_of_line ();
  2006. return;
  2007. }
  2008. if (!bfd_check_format (abfd, bfd_archive))
  2009. {
  2010. as_bad (_("File '%s' not in macro archive format"), path);
  2011. ignore_rest_of_line ();
  2012. return;
  2013. }
  2014. /* Open each BFD as binary (it should be straight ASCII text). */
  2015. for (mbfd = bfd_openr_next_archived_file (abfd, NULL);
  2016. mbfd != NULL; mbfd = bfd_openr_next_archived_file (abfd, mbfd))
  2017. {
  2018. /* Get a size at least as big as the archive member. */
  2019. bfd_size_type size = bfd_get_size (mbfd);
  2020. char *buf = xmalloc (size);
  2021. char *fname = tmpnam (NULL);
  2022. FILE *ftmp;
  2023. /* We're not sure how big it is, but it will be smaller than "size". */
  2024. size = bfd_bread (buf, size, mbfd);
  2025. /* Write to a temporary file, then use s_include to include it
  2026. a bit of a hack. */
  2027. ftmp = fopen (fname, "w+b");
  2028. fwrite ((void *) buf, size, 1, ftmp);
  2029. if (size == 0 || buf[size - 1] != '\n')
  2030. fwrite ("\n", 1, 1, ftmp);
  2031. fclose (ftmp);
  2032. free (buf);
  2033. input_scrub_insert_file (fname);
  2034. unlink (fname);
  2035. }
  2036. }
  2037. const pseudo_typeS md_pseudo_table[] =
  2038. {
  2039. { "algebraic", s_ignore , 0 },
  2040. { "align" , tic54x_align_words , 128 },
  2041. { "ascii" , tic54x_stringer , 'p' },
  2042. { "asciz" , tic54x_stringer , 'P' },
  2043. { "even" , tic54x_align_words , 2 },
  2044. { "asg" , tic54x_asg , 0 },
  2045. { "eval" , tic54x_eval , 0 },
  2046. { "bss" , tic54x_bss , 0 },
  2047. { "byte" , tic54x_cons , 'b' },
  2048. { "ubyte" , tic54x_cons , 'B' },
  2049. { "char" , tic54x_cons , 'c' },
  2050. { "uchar" , tic54x_cons , 'C' },
  2051. { "clink" , tic54x_clink , 0 },
  2052. { "c_mode" , tic54x_address_mode , c_mode },
  2053. { "copy" , tic54x_include , 'c' },
  2054. { "include" , tic54x_include , 'i' },
  2055. { "data" , tic54x_sect , 'd' },
  2056. { "double" , tic54x_float_cons , 'd' },
  2057. { "ldouble" , tic54x_float_cons , 'l' },
  2058. { "drlist" , s_ignore , 0 },
  2059. { "drnolist" , s_ignore , 0 },
  2060. { "emsg" , tic54x_message , 'e' },
  2061. { "mmsg" , tic54x_message , 'm' },
  2062. { "wmsg" , tic54x_message , 'w' },
  2063. { "far_mode" , tic54x_address_mode , far_mode },
  2064. { "fclist" , tic54x_fclist , 1 },
  2065. { "fcnolist" , tic54x_fclist , 0 },
  2066. { "field" , tic54x_field , -1 },
  2067. { "float" , tic54x_float_cons , 'f' },
  2068. { "xfloat" , tic54x_float_cons , 'x' },
  2069. { "global" , tic54x_global , 'g' },
  2070. { "def" , tic54x_global , 'd' },
  2071. { "ref" , tic54x_global , 'r' },
  2072. { "half" , tic54x_cons , 'h' },
  2073. { "uhalf" , tic54x_cons , 'H' },
  2074. { "short" , tic54x_cons , 's' },
  2075. { "ushort" , tic54x_cons , 'S' },
  2076. { "if" , s_if , (int) O_ne },
  2077. { "elseif" , s_elseif , (int) O_ne },
  2078. { "else" , s_else , 0 },
  2079. { "endif" , s_endif , 0 },
  2080. { "int" , tic54x_cons , 'i' },
  2081. { "uint" , tic54x_cons , 'I' },
  2082. { "word" , tic54x_cons , 'w' },
  2083. { "uword" , tic54x_cons , 'W' },
  2084. { "label" , tic54x_label , 0 }, /* Loadtime
  2085. address. */
  2086. { "length" , s_ignore , 0 },
  2087. { "width" , s_ignore , 0 },
  2088. { "long" , tic54x_cons , 'l' },
  2089. { "ulong" , tic54x_cons , 'L' },
  2090. { "xlong" , tic54x_cons , 'x' },
  2091. { "loop" , tic54x_loop , 1024 },
  2092. { "break" , tic54x_break , 0 },
  2093. { "endloop" , tic54x_endloop , 0 },
  2094. { "mlib" , tic54x_mlib , 0 },
  2095. { "mlist" , s_ignore , 0 },
  2096. { "mnolist" , s_ignore , 0 },
  2097. { "mmregs" , tic54x_mmregs , 0 },
  2098. { "newblock" , tic54x_clear_local_labels, 0 },
  2099. { "option" , s_ignore , 0 },
  2100. { "p2align" , tic54x_p2align , 0 },
  2101. { "sblock" , tic54x_sblock , 0 },
  2102. { "sect" , tic54x_sect , '*' },
  2103. { "set" , tic54x_set , 0 },
  2104. { "equ" , tic54x_set , 0 },
  2105. { "space" , tic54x_space , 0 },
  2106. { "bes" , tic54x_space , 1 },
  2107. { "sslist" , tic54x_sslist , 1 },
  2108. { "ssnolist" , tic54x_sslist , 0 },
  2109. { "string" , tic54x_stringer , 's' },
  2110. { "pstring" , tic54x_stringer , 'p' },
  2111. { "struct" , tic54x_struct , 0 },
  2112. { "tag" , tic54x_tag , 0 },
  2113. { "endstruct", tic54x_endstruct , 0 },
  2114. { "tab" , s_ignore , 0 },
  2115. { "text" , tic54x_sect , 't' },
  2116. { "union" , tic54x_struct , 1 },
  2117. { "endunion" , tic54x_endstruct , 1 },
  2118. { "usect" , tic54x_usect , 0 },
  2119. { "var" , tic54x_var , 0 },
  2120. { "version" , tic54x_version , 0 },
  2121. {0 , 0 , 0 }
  2122. };
  2123. int
  2124. md_parse_option (int c, char *arg)
  2125. {
  2126. switch (c)
  2127. {
  2128. default:
  2129. return 0;
  2130. case OPTION_COFF_VERSION:
  2131. {
  2132. int version = atoi (arg);
  2133. if (version != 0 && version != 1 && version != 2)
  2134. as_fatal (_("Bad COFF version '%s'"), arg);
  2135. /* FIXME -- not yet implemented. */
  2136. break;
  2137. }
  2138. case OPTION_CPU_VERSION:
  2139. {
  2140. cpu = lookup_version (arg);
  2141. cpu_needs_set = 1;
  2142. if (cpu == VNONE)
  2143. as_fatal (_("Bad CPU version '%s'"), arg);
  2144. break;
  2145. }
  2146. case OPTION_ADDRESS_MODE:
  2147. amode = far_mode;
  2148. address_mode_needs_set = 1;
  2149. break;
  2150. case OPTION_STDERR_TO_FILE:
  2151. {
  2152. char *filename = arg;
  2153. FILE *fp = fopen (filename, "w+");
  2154. if (fp == NULL)
  2155. as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
  2156. fclose (fp);
  2157. if ((fp = freopen (filename, "w+", stderr)) == NULL)
  2158. as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
  2159. break;
  2160. }
  2161. }
  2162. return 1;
  2163. }
  2164. /* Create a "local" substitution string hash table for a new macro level
  2165. Some docs imply that macros have to use .newblock in order to be able
  2166. to re-use a local label. We effectively do an automatic .newblock by
  2167. deleting the local label hash between macro invocations. */
  2168. void
  2169. tic54x_macro_start (void)
  2170. {
  2171. ++macro_level;
  2172. subsym_hash[macro_level] = hash_new ();
  2173. local_label_hash[macro_level] = hash_new ();
  2174. }
  2175. void
  2176. tic54x_macro_info (const macro_entry *macro)
  2177. {
  2178. const formal_entry *entry;
  2179. /* Put the formal args into the substitution symbol table. */
  2180. for (entry = macro->formals; entry; entry = entry->next)
  2181. {
  2182. char *name = strncpy (xmalloc (entry->name.len + 1),
  2183. entry->name.ptr, entry->name.len);
  2184. char *value = strncpy (xmalloc (entry->actual.len + 1),
  2185. entry->actual.ptr, entry->actual.len);
  2186. name[entry->name.len] = '\0';
  2187. value[entry->actual.len] = '\0';
  2188. hash_insert (subsym_hash[macro_level], name, value);
  2189. }
  2190. }
  2191. /* Get rid of this macro's .var's, arguments, and local labels. */
  2192. void
  2193. tic54x_macro_end (void)
  2194. {
  2195. hash_die (subsym_hash[macro_level]);
  2196. subsym_hash[macro_level] = NULL;
  2197. hash_die (local_label_hash[macro_level]);
  2198. local_label_hash[macro_level] = NULL;
  2199. --macro_level;
  2200. }
  2201. static int
  2202. subsym_symlen (char *a, char *ignore ATTRIBUTE_UNUSED)
  2203. {
  2204. return strlen (a);
  2205. }
  2206. /* Compare symbol A to string B. */
  2207. static int
  2208. subsym_symcmp (char *a, char *b)
  2209. {
  2210. return strcmp (a, b);
  2211. }
  2212. /* Return the index of the first occurrence of B in A, or zero if none
  2213. assumes b is an integer char value as a string. Index is one-based. */
  2214. static int
  2215. subsym_firstch (char *a, char *b)
  2216. {
  2217. int val = atoi (b);
  2218. char *tmp = strchr (a, val);
  2219. return tmp ? tmp - a + 1 : 0;
  2220. }
  2221. /* Similar to firstch, but returns index of last occurrence of B in A. */
  2222. static int
  2223. subsym_lastch (char *a, char *b)
  2224. {
  2225. int val = atoi (b);
  2226. char *tmp = strrchr (a, val);
  2227. return tmp ? tmp - a + 1 : 0;
  2228. }
  2229. /* Returns 1 if string A is defined in the symbol table (NOT the substitution
  2230. symbol table). */
  2231. static int
  2232. subsym_isdefed (char *a, char *ignore ATTRIBUTE_UNUSED)
  2233. {
  2234. symbolS *symbolP = symbol_find (a);
  2235. return symbolP != NULL;
  2236. }
  2237. /* Assign first member of comma-separated list B (e.g. "1,2,3") to the symbol
  2238. A, or zero if B is a null string. Both arguments *must* be substitution
  2239. symbols, unsubstituted. */
  2240. static int
  2241. subsym_ismember (char *sym, char *list)
  2242. {
  2243. char *elem, *ptr, *listv;
  2244. if (!list)
  2245. return 0;
  2246. listv = subsym_lookup (list, macro_level);
  2247. if (!listv)
  2248. {
  2249. as_bad (_("Undefined substitution symbol '%s'"), list);
  2250. ignore_rest_of_line ();
  2251. return 0;
  2252. }
  2253. ptr = elem = xmalloc (strlen (listv) + 1);
  2254. strcpy (elem, listv);
  2255. while (*ptr && *ptr != ',')
  2256. ++ptr;
  2257. *ptr++ = 0;
  2258. subsym_create_or_replace (sym, elem);
  2259. /* Reassign the list. */
  2260. subsym_create_or_replace (list, ptr);
  2261. /* Assume this value, docs aren't clear. */
  2262. return *list != 0;
  2263. }
  2264. /* Return zero if not a constant; otherwise:
  2265. 1 if binary
  2266. 2 if octal
  2267. 3 if hexadecimal
  2268. 4 if character
  2269. 5 if decimal. */
  2270. static int
  2271. subsym_iscons (char *a, char *ignore ATTRIBUTE_UNUSED)
  2272. {
  2273. expressionS expn;
  2274. parse_expression (a, &expn);
  2275. if (expn.X_op == O_constant)
  2276. {
  2277. int len = strlen (a);
  2278. switch (TOUPPER (a[len - 1]))
  2279. {
  2280. case 'B':
  2281. return 1;
  2282. case 'Q':
  2283. return 2;
  2284. case 'H':
  2285. return 3;
  2286. case '\'':
  2287. return 4;
  2288. default:
  2289. break;
  2290. }
  2291. /* No suffix; either octal, hex, or decimal. */
  2292. if (*a == '0' && len > 1)
  2293. {
  2294. if (TOUPPER (a[1]) == 'X')
  2295. return 3;
  2296. return 2;
  2297. }
  2298. return 5;
  2299. }
  2300. return 0;
  2301. }
  2302. /* Return 1 if A is a valid symbol name. Expects string input. */
  2303. static int
  2304. subsym_isname (char *a, char *ignore ATTRIBUTE_UNUSED)
  2305. {
  2306. if (!is_name_beginner (*a))
  2307. return 0;
  2308. while (*a)
  2309. {
  2310. if (!is_part_of_name (*a))
  2311. return 0;
  2312. ++a;
  2313. }
  2314. return 1;
  2315. }
  2316. /* Return whether the string is a register; accepts ar0-7, unless .mmregs has
  2317. been seen; if so, recognize any memory-mapped register.
  2318. Note this does not recognize "A" or "B" accumulators. */
  2319. static int
  2320. subsym_isreg (char *a, char *ignore ATTRIBUTE_UNUSED)
  2321. {
  2322. if (hash_find (reg_hash, a))
  2323. return 1;
  2324. if (hash_find (mmreg_hash, a))
  2325. return 1;
  2326. return 0;
  2327. }
  2328. /* Return the structure size, given the stag. */
  2329. static int
  2330. subsym_structsz (char *name, char *ignore ATTRIBUTE_UNUSED)
  2331. {
  2332. struct stag *stag = (struct stag *) hash_find (stag_hash, name);
  2333. if (stag)
  2334. return stag->size;
  2335. return 0;
  2336. }
  2337. /* If anybody actually uses this, they can fix it :)
  2338. FIXME I'm not sure what the "reference point" of a structure is. It might
  2339. be either the initial offset given .struct, or it may be the offset of the
  2340. structure within another structure, or it might be something else
  2341. altogether. since the TI assembler doesn't seem to ever do anything but
  2342. return zero, we punt and return zero. */
  2343. static int
  2344. subsym_structacc (char *stag_name ATTRIBUTE_UNUSED,
  2345. char *ignore ATTRIBUTE_UNUSED)
  2346. {
  2347. return 0;
  2348. }
  2349. static float
  2350. math_ceil (float arg1, float ignore ATTRIBUTE_UNUSED)
  2351. {
  2352. return (float) ceil (arg1);
  2353. }
  2354. static float
  2355. math_cvi (float arg1, float ignore ATTRIBUTE_UNUSED)
  2356. {
  2357. return (int) arg1;
  2358. }
  2359. static float
  2360. math_floor (float arg1, float ignore ATTRIBUTE_UNUSED)
  2361. {
  2362. return (float) floor (arg1);
  2363. }
  2364. static float
  2365. math_fmod (float arg1, float arg2)
  2366. {
  2367. return (int) arg1 % (int) arg2;
  2368. }
  2369. static float
  2370. math_int (float arg1, float ignore ATTRIBUTE_UNUSED)
  2371. {
  2372. return ((float) ((int) arg1)) == arg1;
  2373. }
  2374. static float
  2375. math_round (float arg1, float ignore ATTRIBUTE_UNUSED)
  2376. {
  2377. return arg1 > 0 ? (int) (arg1 + 0.5) : (int) (arg1 - 0.5);
  2378. }
  2379. static float
  2380. math_sgn (float arg1, float ignore ATTRIBUTE_UNUSED)
  2381. {
  2382. return (arg1 < 0) ? -1 : (arg1 ? 1 : 0);
  2383. }
  2384. static float
  2385. math_trunc (float arg1, float ignore ATTRIBUTE_UNUSED)
  2386. {
  2387. return (int) arg1;
  2388. }
  2389. static float
  2390. math_acos (float arg1, float ignore ATTRIBUTE_UNUSED)
  2391. {
  2392. return (float) acos (arg1);
  2393. }
  2394. static float
  2395. math_asin (float arg1, float ignore ATTRIBUTE_UNUSED)
  2396. {
  2397. return (float) asin (arg1);
  2398. }
  2399. static float
  2400. math_atan (float arg1, float ignore ATTRIBUTE_UNUSED)
  2401. {
  2402. return (float) atan (arg1);
  2403. }
  2404. static float
  2405. math_atan2 (float arg1, float arg2)
  2406. {
  2407. return (float) atan2 (arg1, arg2);
  2408. }
  2409. static float
  2410. math_cosh (float arg1, float ignore ATTRIBUTE_UNUSED)
  2411. {
  2412. return (float) cosh (arg1);
  2413. }
  2414. static float
  2415. math_cos (float arg1, float ignore ATTRIBUTE_UNUSED)
  2416. {
  2417. return (float) cos (arg1);
  2418. }
  2419. static float
  2420. math_cvf (float arg1, float ignore ATTRIBUTE_UNUSED)
  2421. {
  2422. return (float) arg1;
  2423. }
  2424. static float
  2425. math_exp (float arg1, float ignore ATTRIBUTE_UNUSED)
  2426. {
  2427. return (float) exp (arg1);
  2428. }
  2429. static float
  2430. math_fabs (float arg1, float ignore ATTRIBUTE_UNUSED)
  2431. {
  2432. return (float) fabs (arg1);
  2433. }
  2434. /* expr1 * 2^expr2. */
  2435. static float
  2436. math_ldexp (float arg1, float arg2)
  2437. {
  2438. return arg1 * (float) pow (2.0, arg2);
  2439. }
  2440. static float
  2441. math_log10 (float arg1, float ignore ATTRIBUTE_UNUSED)
  2442. {
  2443. return (float) log10 (arg1);
  2444. }
  2445. static float
  2446. math_log (float arg1, float ignore ATTRIBUTE_UNUSED)
  2447. {
  2448. return (float) log (arg1);
  2449. }
  2450. static float
  2451. math_max (float arg1, float arg2)
  2452. {
  2453. return (arg1 > arg2) ? arg1 : arg2;
  2454. }
  2455. static float
  2456. math_min (float arg1, float arg2)
  2457. {
  2458. return (arg1 < arg2) ? arg1 : arg2;
  2459. }
  2460. static float
  2461. math_pow (float arg1, float arg2)
  2462. {
  2463. return (float) pow (arg1, arg2);
  2464. }
  2465. static float
  2466. math_sin (float arg1, float ignore ATTRIBUTE_UNUSED)
  2467. {
  2468. return (float) sin (arg1);
  2469. }
  2470. static float
  2471. math_sinh (float arg1, float ignore ATTRIBUTE_UNUSED)
  2472. {
  2473. return (float) sinh (arg1);
  2474. }
  2475. static float
  2476. math_sqrt (float arg1, float ignore ATTRIBUTE_UNUSED)
  2477. {
  2478. return (float) sqrt (arg1);
  2479. }
  2480. static float
  2481. math_tan (float arg1, float ignore ATTRIBUTE_UNUSED)
  2482. {
  2483. return (float) tan (arg1);
  2484. }
  2485. static float
  2486. math_tanh (float arg1, float ignore ATTRIBUTE_UNUSED)
  2487. {
  2488. return (float) tanh (arg1);
  2489. }
  2490. /* Built-in substitution symbol functions and math functions. */
  2491. typedef struct
  2492. {
  2493. char *name;
  2494. int (*proc) (char *, char *);
  2495. int nargs;
  2496. } subsym_proc_entry;
  2497. static const subsym_proc_entry subsym_procs[] =
  2498. {
  2499. /* Assembler built-in string substitution functions. */
  2500. { "$symlen", subsym_symlen, 1, },
  2501. { "$symcmp", subsym_symcmp, 2, },
  2502. { "$firstch", subsym_firstch, 2, },
  2503. { "$lastch", subsym_lastch, 2, },
  2504. { "$isdefed", subsym_isdefed, 1, },
  2505. { "$ismember", subsym_ismember, 2, },
  2506. { "$iscons", subsym_iscons, 1, },
  2507. { "$isname", subsym_isname, 1, },
  2508. { "$isreg", subsym_isreg, 1, },
  2509. { "$structsz", subsym_structsz, 1, },
  2510. { "$structacc", subsym_structacc, 1, },
  2511. { NULL, NULL, 0 },
  2512. };
  2513. typedef struct
  2514. {
  2515. char *name;
  2516. float (*proc) (float, float);
  2517. int nargs;
  2518. int int_return;
  2519. } math_proc_entry;
  2520. static const math_proc_entry math_procs[] =
  2521. {
  2522. /* Integer-returning built-in math functions. */
  2523. { "$cvi", math_cvi, 1, 1 },
  2524. { "$int", math_int, 1, 1 },
  2525. { "$sgn", math_sgn, 1, 1 },
  2526. /* Float-returning built-in math functions. */
  2527. { "$acos", math_acos, 1, 0 },
  2528. { "$asin", math_asin, 1, 0 },
  2529. { "$atan", math_atan, 1, 0 },
  2530. { "$atan2", math_atan2, 2, 0 },
  2531. { "$ceil", math_ceil, 1, 0 },
  2532. { "$cosh", math_cosh, 1, 0 },
  2533. { "$cos", math_cos, 1, 0 },
  2534. { "$cvf", math_cvf, 1, 0 },
  2535. { "$exp", math_exp, 1, 0 },
  2536. { "$fabs", math_fabs, 1, 0 },
  2537. { "$floor", math_floor, 1, 0 },
  2538. { "$fmod", math_fmod, 2, 0 },
  2539. { "$ldexp", math_ldexp, 2, 0 },
  2540. { "$log10", math_log10, 1, 0 },
  2541. { "$log", math_log, 1, 0 },
  2542. { "$max", math_max, 2, 0 },
  2543. { "$min", math_min, 2, 0 },
  2544. { "$pow", math_pow, 2, 0 },
  2545. { "$round", math_round, 1, 0 },
  2546. { "$sin", math_sin, 1, 0 },
  2547. { "$sinh", math_sinh, 1, 0 },
  2548. { "$sqrt", math_sqrt, 1, 0 },
  2549. { "$tan", math_tan, 1, 0 },
  2550. { "$tanh", math_tanh, 1, 0 },
  2551. { "$trunc", math_trunc, 1, 0 },
  2552. { NULL, NULL, 0, 0 },
  2553. };
  2554. void
  2555. md_begin (void)
  2556. {
  2557. insn_template *tm;
  2558. symbol *sym;
  2559. const subsym_proc_entry *subsym_proc;
  2560. const math_proc_entry *math_proc;
  2561. const char *hash_err;
  2562. char **symname;
  2563. char *TIC54X_DIR = getenv ("TIC54X_DIR");
  2564. char *A_DIR = TIC54X_DIR ? TIC54X_DIR : getenv ("A_DIR");
  2565. local_label_id = 0;
  2566. /* Look for A_DIR and add it to the include list. */
  2567. if (A_DIR != NULL)
  2568. {
  2569. char *tmp = xstrdup (A_DIR);
  2570. do
  2571. {
  2572. char *next = strchr (tmp, ';');
  2573. if (next)
  2574. *next++ = '\0';
  2575. add_include_dir (tmp);
  2576. tmp = next;
  2577. }
  2578. while (tmp != NULL);
  2579. }
  2580. op_hash = hash_new ();
  2581. for (tm = (insn_template *) tic54x_optab; tm->name; tm++)
  2582. {
  2583. if (hash_find (op_hash, tm->name))
  2584. continue;
  2585. hash_err = hash_insert (op_hash, tm->name, (char *) tm);
  2586. if (hash_err)
  2587. as_fatal ("Internal Error: Can't hash %s: %s",
  2588. tm->name, hash_err);
  2589. }
  2590. parop_hash = hash_new ();
  2591. for (tm = (insn_template *) tic54x_paroptab; tm->name; tm++)
  2592. {
  2593. if (hash_find (parop_hash, tm->name))
  2594. continue;
  2595. hash_err = hash_insert (parop_hash, tm->name, (char *) tm);
  2596. if (hash_err)
  2597. as_fatal ("Internal Error: Can't hash %s: %s",
  2598. tm->name, hash_err);
  2599. }
  2600. reg_hash = hash_new ();
  2601. for (sym = (symbol *) regs; sym->name; sym++)
  2602. {
  2603. /* Add basic registers to the symbol table. */
  2604. symbolS *symbolP = symbol_new (sym->name, absolute_section,
  2605. (valueT) sym->value, &zero_address_frag);
  2606. SF_SET_LOCAL (symbolP);
  2607. symbol_table_insert (symbolP);
  2608. hash_err = hash_insert (reg_hash, sym->name, (char *) sym);
  2609. }
  2610. for (sym = (symbol *) mmregs; sym->name; sym++)
  2611. hash_err = hash_insert (reg_hash, sym->name, (char *) sym);
  2612. mmreg_hash = hash_new ();
  2613. for (sym = (symbol *) mmregs; sym->name; sym++)
  2614. hash_err = hash_insert (mmreg_hash, sym->name, (char *) sym);
  2615. cc_hash = hash_new ();
  2616. for (sym = (symbol *) condition_codes; sym->name; sym++)
  2617. hash_err = hash_insert (cc_hash, sym->name, (char *) sym);
  2618. cc2_hash = hash_new ();
  2619. for (sym = (symbol *) cc2_codes; sym->name; sym++)
  2620. hash_err = hash_insert (cc2_hash, sym->name, (char *) sym);
  2621. cc3_hash = hash_new ();
  2622. for (sym = (symbol *) cc3_codes; sym->name; sym++)
  2623. hash_err = hash_insert (cc3_hash, sym->name, (char *) sym);
  2624. sbit_hash = hash_new ();
  2625. for (sym = (symbol *) status_bits; sym->name; sym++)
  2626. hash_err = hash_insert (sbit_hash, sym->name, (char *) sym);
  2627. misc_symbol_hash = hash_new ();
  2628. for (symname = (char **) misc_symbols; *symname; symname++)
  2629. hash_err = hash_insert (misc_symbol_hash, *symname, *symname);
  2630. /* Only the base substitution table and local label table are initialized;
  2631. the others (for local macro substitution) get instantiated as needed. */
  2632. local_label_hash[0] = hash_new ();
  2633. subsym_hash[0] = hash_new ();
  2634. for (subsym_proc = subsym_procs; subsym_proc->name; subsym_proc++)
  2635. hash_err = hash_insert (subsym_hash[0], subsym_proc->name,
  2636. (char *) subsym_proc);
  2637. math_hash = hash_new ();
  2638. for (math_proc = math_procs; math_proc->name; math_proc++)
  2639. {
  2640. /* Insert into the main subsym hash for recognition; insert into
  2641. the math hash to actually store information. */
  2642. hash_err = hash_insert (subsym_hash[0], math_proc->name,
  2643. (char *) math_proc);
  2644. hash_err = hash_insert (math_hash, math_proc->name,
  2645. (char *) math_proc);
  2646. }
  2647. subsym_recurse_hash = hash_new ();
  2648. stag_hash = hash_new ();
  2649. }
  2650. static int
  2651. is_accumulator (struct opstruct *operand)
  2652. {
  2653. return strcasecmp (operand->buf, "a") == 0
  2654. || strcasecmp (operand->buf, "b") == 0;
  2655. }
  2656. /* Return the number of operands found, or -1 on error, copying the
  2657. operands into the given array and the accompanying expressions into
  2658. the next array. */
  2659. static int
  2660. get_operands (struct opstruct operands[], char *line)
  2661. {
  2662. char *lptr = line;
  2663. int numexp = 0;
  2664. int expecting_operand = 0;
  2665. int i;
  2666. while (numexp < MAX_OPERANDS && !is_end_of_line[(int) *lptr])
  2667. {
  2668. int paren_not_balanced = 0;
  2669. char *op_start, *op_end;
  2670. while (*lptr && ISSPACE (*lptr))
  2671. ++lptr;
  2672. op_start = lptr;
  2673. while (paren_not_balanced || *lptr != ',')
  2674. {
  2675. if (*lptr == '\0')
  2676. {
  2677. if (paren_not_balanced)
  2678. {
  2679. as_bad (_("Unbalanced parenthesis in operand %d"), numexp);
  2680. return -1;
  2681. }
  2682. else
  2683. break;
  2684. }
  2685. if (*lptr == '(')
  2686. ++paren_not_balanced;
  2687. else if (*lptr == ')')
  2688. --paren_not_balanced;
  2689. ++lptr;
  2690. }
  2691. op_end = lptr;
  2692. if (op_end != op_start)
  2693. {
  2694. int len = op_end - op_start;
  2695. strncpy (operands[numexp].buf, op_start, len);
  2696. operands[numexp].buf[len] = 0;
  2697. /* Trim trailing spaces; while the preprocessor gets rid of most,
  2698. there are weird usage patterns that can introduce them
  2699. (i.e. using strings for macro args). */
  2700. while (len > 0 && ISSPACE (operands[numexp].buf[len - 1]))
  2701. operands[numexp].buf[--len] = 0;
  2702. lptr = op_end;
  2703. ++numexp;
  2704. }
  2705. else
  2706. {
  2707. if (expecting_operand || *lptr == ',')
  2708. {
  2709. as_bad (_("Expecting operand after ','"));
  2710. return -1;
  2711. }
  2712. }
  2713. if (*lptr == ',')
  2714. {
  2715. if (*++lptr == '\0')
  2716. {
  2717. as_bad (_("Expecting operand after ','"));
  2718. return -1;
  2719. }
  2720. expecting_operand = 1;
  2721. }
  2722. }
  2723. while (*lptr && ISSPACE (*lptr++))
  2724. ;
  2725. if (!is_end_of_line[(int) *lptr])
  2726. {
  2727. as_bad (_("Extra junk on line"));
  2728. return -1;
  2729. }
  2730. /* OK, now parse them into expressions. */
  2731. for (i = 0; i < numexp; i++)
  2732. {
  2733. memset (&operands[i].exp, 0, sizeof (operands[i].exp));
  2734. if (operands[i].buf[0] == '#')
  2735. {
  2736. /* Immediate. */
  2737. parse_expression (operands[i].buf + 1, &operands[i].exp);
  2738. }
  2739. else if (operands[i].buf[0] == '@')
  2740. {
  2741. /* Direct notation. */
  2742. parse_expression (operands[i].buf + 1, &operands[i].exp);
  2743. }
  2744. else if (operands[i].buf[0] == '*')
  2745. {
  2746. /* Indirect. */
  2747. char *paren = strchr (operands[i].buf, '(');
  2748. /* Allow immediate syntax in the inner expression. */
  2749. if (paren && paren[1] == '#')
  2750. *++paren = '(';
  2751. /* Pull out the lk expression or SP offset, if present. */
  2752. if (paren != NULL)
  2753. {
  2754. int len = strlen (paren);
  2755. char *end = paren + len;
  2756. int c;
  2757. while (end[-1] != ')')
  2758. if (--end <= paren)
  2759. {
  2760. as_bad (_("Badly formed address expression"));
  2761. return -1;
  2762. }
  2763. c = *end;
  2764. *end = '\0';
  2765. parse_expression (paren, &operands[i].exp);
  2766. *end = c;
  2767. }
  2768. else
  2769. operands[i].exp.X_op = O_absent;
  2770. }
  2771. else
  2772. parse_expression (operands[i].buf, &operands[i].exp);
  2773. }
  2774. return numexp;
  2775. }
  2776. /* Predicates for different operand types. */
  2777. static int
  2778. is_immediate (struct opstruct *operand)
  2779. {
  2780. return *operand->buf == '#';
  2781. }
  2782. /* This is distinguished from immediate because some numbers must be constants
  2783. and must *not* have the '#' prefix. */
  2784. static int
  2785. is_absolute (struct opstruct *operand)
  2786. {
  2787. return operand->exp.X_op == O_constant && !is_immediate (operand);
  2788. }
  2789. /* Is this an indirect operand? */
  2790. static int
  2791. is_indirect (struct opstruct *operand)
  2792. {
  2793. return operand->buf[0] == '*';
  2794. }
  2795. /* Is this a valid dual-memory operand? */
  2796. static int
  2797. is_dual (struct opstruct *operand)
  2798. {
  2799. if (is_indirect (operand) && strncasecmp (operand->buf, "*ar", 3) == 0)
  2800. {
  2801. char *tmp = operand->buf + 3;
  2802. int arf;
  2803. int valid_mod;
  2804. arf = *tmp++ - '0';
  2805. /* Only allow *ARx, *ARx-, *ARx+, or *ARx+0%. */
  2806. valid_mod = *tmp == '\0' ||
  2807. strcasecmp (tmp, "-") == 0 ||
  2808. strcasecmp (tmp, "+") == 0 ||
  2809. strcasecmp (tmp, "+0%") == 0;
  2810. return arf >= 2 && arf <= 5 && valid_mod;
  2811. }
  2812. return 0;
  2813. }
  2814. static int
  2815. is_mmreg (struct opstruct *operand)
  2816. {
  2817. return (is_absolute (operand)
  2818. || is_immediate (operand)
  2819. || hash_find (mmreg_hash, operand->buf) != 0);
  2820. }
  2821. static int
  2822. is_type (struct opstruct *operand, enum optype type)
  2823. {
  2824. switch (type)
  2825. {
  2826. case OP_None:
  2827. return operand->buf[0] == 0;
  2828. case OP_Xmem:
  2829. case OP_Ymem:
  2830. return is_dual (operand);
  2831. case OP_Sind:
  2832. return is_indirect (operand);
  2833. case OP_xpmad_ms7:
  2834. /* This one *must* be immediate. */
  2835. return is_immediate (operand);
  2836. case OP_xpmad:
  2837. case OP_pmad:
  2838. case OP_PA:
  2839. case OP_dmad:
  2840. case OP_Lmem:
  2841. case OP_MMR:
  2842. return 1;
  2843. case OP_Smem:
  2844. /* Address may be a numeric, indirect, or an expression. */
  2845. return !is_immediate (operand);
  2846. case OP_MMRY:
  2847. case OP_MMRX:
  2848. return is_mmreg (operand);
  2849. case OP_SRC:
  2850. case OP_SRC1:
  2851. case OP_RND:
  2852. case OP_DST:
  2853. return is_accumulator (operand);
  2854. case OP_B:
  2855. return is_accumulator (operand) && TOUPPER (operand->buf[0]) == 'B';
  2856. case OP_A:
  2857. return is_accumulator (operand) && TOUPPER (operand->buf[0]) == 'A';
  2858. case OP_ARX:
  2859. return strncasecmp ("ar", operand->buf, 2) == 0
  2860. && ISDIGIT (operand->buf[2]);
  2861. case OP_SBIT:
  2862. return hash_find (sbit_hash, operand->buf) != 0 || is_absolute (operand);
  2863. case OP_CC:
  2864. return hash_find (cc_hash, operand->buf) != 0;
  2865. case OP_CC2:
  2866. return hash_find (cc2_hash, operand->buf) != 0;
  2867. case OP_CC3:
  2868. return hash_find (cc3_hash, operand->buf) != 0
  2869. || is_immediate (operand) || is_absolute (operand);
  2870. case OP_16:
  2871. return (is_immediate (operand) || is_absolute (operand))
  2872. && operand->exp.X_add_number == 16;
  2873. case OP_N:
  2874. /* Allow st0 or st1 instead of a numeric. */
  2875. return is_absolute (operand) || is_immediate (operand) ||
  2876. strcasecmp ("st0", operand->buf) == 0 ||
  2877. strcasecmp ("st1", operand->buf) == 0;
  2878. case OP_12:
  2879. case OP_123:
  2880. return is_absolute (operand) || is_immediate (operand);
  2881. case OP_SHFT:
  2882. return (is_immediate (operand) || is_absolute (operand))
  2883. && operand->exp.X_add_number >= 0 && operand->exp.X_add_number < 16;
  2884. case OP_SHIFT:
  2885. /* Let this one catch out-of-range values. */
  2886. return (is_immediate (operand) || is_absolute (operand))
  2887. && operand->exp.X_add_number != 16;
  2888. case OP_BITC:
  2889. case OP_031:
  2890. case OP_k8:
  2891. return is_absolute (operand) || is_immediate (operand);
  2892. case OP_k8u:
  2893. return is_immediate (operand)
  2894. && operand->exp.X_op == O_constant
  2895. && operand->exp.X_add_number >= 0
  2896. && operand->exp.X_add_number < 256;
  2897. case OP_lk:
  2898. case OP_lku:
  2899. /* Allow anything; assumes opcodes are ordered with Smem operands
  2900. versions first. */
  2901. return 1;
  2902. case OP_k5:
  2903. case OP_k3:
  2904. case OP_k9:
  2905. /* Just make sure it's an integer; check range later. */
  2906. return is_immediate (operand);
  2907. case OP_T:
  2908. return strcasecmp ("t", operand->buf) == 0 ||
  2909. strcasecmp ("treg", operand->buf) == 0;
  2910. case OP_TS:
  2911. return strcasecmp ("ts", operand->buf) == 0;
  2912. case OP_ASM:
  2913. return strcasecmp ("asm", operand->buf) == 0;
  2914. case OP_TRN:
  2915. return strcasecmp ("trn", operand->buf) == 0;
  2916. case OP_DP:
  2917. return strcasecmp ("dp", operand->buf) == 0;
  2918. case OP_ARP:
  2919. return strcasecmp ("arp", operand->buf) == 0;
  2920. default:
  2921. return 0;
  2922. }
  2923. }
  2924. static int
  2925. operands_match (tic54x_insn *insn,
  2926. struct opstruct *operands,
  2927. int opcount,
  2928. const enum optype *refoptype,
  2929. int minops,
  2930. int maxops)
  2931. {
  2932. int op = 0, refop = 0;
  2933. if (opcount == 0 && minops == 0)
  2934. return 1;
  2935. while (op <= maxops && refop <= maxops)
  2936. {
  2937. while (!is_type (&operands[op], OPTYPE (refoptype[refop])))
  2938. {
  2939. /* Skip an optional template operand if it doesn't agree
  2940. with the current operand. */
  2941. if (refoptype[refop] & OPT)
  2942. {
  2943. ++refop;
  2944. --maxops;
  2945. if (refop > maxops)
  2946. return 0;
  2947. }
  2948. else
  2949. return 0;
  2950. }
  2951. /* Save the actual operand type for later use. */
  2952. operands[op].type = OPTYPE (refoptype[refop]);
  2953. ++refop;
  2954. ++op;
  2955. /* Have we matched them all yet? */
  2956. if (op == opcount)
  2957. {
  2958. while (op < maxops)
  2959. {
  2960. /* If a later operand is *not* optional, no match. */
  2961. if ((refoptype[refop] & OPT) == 0)
  2962. return 0;
  2963. /* Flag any implicit default OP_DST operands so we know to add
  2964. them explicitly when encoding the operand later. */
  2965. if (OPTYPE (refoptype[refop]) == OP_DST)
  2966. insn->using_default_dst = 1;
  2967. ++refop;
  2968. ++op;
  2969. }
  2970. return 1;
  2971. }
  2972. }
  2973. return 0;
  2974. }
  2975. /* 16-bit direct memory address
  2976. Explicit dmad operands are always in last word of insn (usually second
  2977. word, but bumped to third if lk addressing is used)
  2978. We allow *(dmad) notation because the TI assembler allows it.
  2979. XPC_CODE:
  2980. 0 for 16-bit addresses
  2981. 1 for full 23-bit addresses
  2982. 2 for the upper 7 bits of a 23-bit address (LDX). */
  2983. static int
  2984. encode_dmad (tic54x_insn *insn, struct opstruct *operand, int xpc_code)
  2985. {
  2986. int op = 1 + insn->is_lkaddr;
  2987. /* Only allow *(dmad) expressions; all others are invalid. */
  2988. if (is_indirect (operand) && operand->buf[strlen (operand->buf) - 1] != ')')
  2989. {
  2990. as_bad (_("Invalid dmad syntax '%s'"), operand->buf);
  2991. return 0;
  2992. }
  2993. insn->opcode[op].addr_expr = operand->exp;
  2994. if (insn->opcode[op].addr_expr.X_op == O_constant)
  2995. {
  2996. valueT value = insn->opcode[op].addr_expr.X_add_number;
  2997. if (xpc_code == 1)
  2998. {
  2999. insn->opcode[0].word &= 0xFF80;
  3000. insn->opcode[0].word |= (value >> 16) & 0x7F;
  3001. insn->opcode[1].word = value & 0xFFFF;
  3002. }
  3003. else if (xpc_code == 2)
  3004. insn->opcode[op].word = (value >> 16) & 0xFFFF;
  3005. else
  3006. insn->opcode[op].word = value;
  3007. }
  3008. else
  3009. {
  3010. /* Do the fixup later; just store the expression. */
  3011. insn->opcode[op].word = 0;
  3012. insn->opcode[op].r_nchars = 2;
  3013. if (amode == c_mode)
  3014. insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23;
  3015. else if (xpc_code == 1)
  3016. {
  3017. /* This relocation spans two words, so adjust accordingly. */
  3018. insn->opcode[0].addr_expr = operand->exp;
  3019. insn->opcode[0].r_type = BFD_RELOC_TIC54X_23;
  3020. insn->opcode[0].r_nchars = 4;
  3021. insn->opcode[0].unresolved = 1;
  3022. /* It's really 2 words, but we want to stop encoding after the
  3023. first, since we must encode both words at once. */
  3024. insn->words = 1;
  3025. }
  3026. else if (xpc_code == 2)
  3027. insn->opcode[op].r_type = BFD_RELOC_TIC54X_MS7_OF_23;
  3028. else
  3029. insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23;
  3030. insn->opcode[op].unresolved = 1;
  3031. }
  3032. return 1;
  3033. }
  3034. /* 7-bit direct address encoding. */
  3035. static int
  3036. encode_address (tic54x_insn *insn, struct opstruct *operand)
  3037. {
  3038. /* Assumes that dma addresses are *always* in word 0 of the opcode. */
  3039. insn->opcode[0].addr_expr = operand->exp;
  3040. if (operand->exp.X_op == O_constant)
  3041. insn->opcode[0].word |= (operand->exp.X_add_number & 0x7F);
  3042. else
  3043. {
  3044. if (operand->exp.X_op == O_register)
  3045. as_bad (_("Use the .mmregs directive to use memory-mapped register names such as '%s'"), operand->buf);
  3046. /* Do the fixup later; just store the expression. */
  3047. insn->opcode[0].r_nchars = 1;
  3048. insn->opcode[0].r_type = BFD_RELOC_TIC54X_PARTLS7;
  3049. insn->opcode[0].unresolved = 1;
  3050. }
  3051. return 1;
  3052. }
  3053. static int
  3054. encode_indirect (tic54x_insn *insn, struct opstruct *operand)
  3055. {
  3056. int arf;
  3057. int mod;
  3058. if (insn->is_lkaddr)
  3059. {
  3060. /* lk addresses always go in the second insn word. */
  3061. mod = ((TOUPPER (operand->buf[1]) == 'A') ? 12 :
  3062. (operand->buf[1] == '(') ? 15 :
  3063. (strchr (operand->buf, '%') != NULL) ? 14 : 13);
  3064. arf = ((mod == 12) ? operand->buf[3] - '0' :
  3065. (mod == 15) ? 0 : operand->buf[4] - '0');
  3066. insn->opcode[1].addr_expr = operand->exp;
  3067. if (operand->exp.X_op == O_constant)
  3068. insn->opcode[1].word = operand->exp.X_add_number;
  3069. else
  3070. {
  3071. insn->opcode[1].word = 0;
  3072. insn->opcode[1].r_nchars = 2;
  3073. insn->opcode[1].r_type = BFD_RELOC_TIC54X_16_OF_23;
  3074. insn->opcode[1].unresolved = 1;
  3075. }
  3076. }
  3077. else if (strncasecmp (operand->buf, "*sp (", 4) == 0)
  3078. {
  3079. /* Stack offsets look the same as 7-bit direct addressing. */
  3080. return encode_address (insn, operand);
  3081. }
  3082. else
  3083. {
  3084. arf = (TOUPPER (operand->buf[1]) == 'A' ?
  3085. operand->buf[3] : operand->buf[4]) - '0';
  3086. if (operand->buf[1] == '+')
  3087. {
  3088. mod = 3; /* *+ARx */
  3089. if (insn->tm->flags & FL_SMR)
  3090. as_warn (_("Address mode *+ARx is write-only. "
  3091. "Results of reading are undefined."));
  3092. }
  3093. else if (operand->buf[4] == '\0')
  3094. mod = 0; /* *ARx */
  3095. else if (operand->buf[5] == '\0')
  3096. mod = (operand->buf[4] == '-' ? 1 : 2); /* *ARx+ / *ARx- */
  3097. else if (operand->buf[6] == '\0')
  3098. {
  3099. if (operand->buf[5] == '0')
  3100. mod = (operand->buf[4] == '-' ? 5 : 6); /* *ARx+0 / *ARx-0 */
  3101. else
  3102. mod = (operand->buf[4] == '-' ? 8 : 10);/* *ARx+% / *ARx-% */
  3103. }
  3104. else if (TOUPPER (operand->buf[6]) == 'B')
  3105. mod = (operand->buf[4] == '-' ? 4 : 7); /* ARx+0B / *ARx-0B */
  3106. else if (TOUPPER (operand->buf[6]) == '%')
  3107. mod = (operand->buf[4] == '-' ? 9 : 11); /* ARx+0% / *ARx - 0% */
  3108. else
  3109. {
  3110. as_bad (_("Unrecognized indirect address format \"%s\""),
  3111. operand->buf);
  3112. return 0;
  3113. }
  3114. }
  3115. insn->opcode[0].word |= 0x80 | (mod << 3) | arf;
  3116. return 1;
  3117. }
  3118. static int
  3119. encode_integer (tic54x_insn *insn,
  3120. struct opstruct *operand,
  3121. int which,
  3122. int min,
  3123. int max,
  3124. unsigned short mask)
  3125. {
  3126. long parse, integer;
  3127. insn->opcode[which].addr_expr = operand->exp;
  3128. if (operand->exp.X_op == O_constant)
  3129. {
  3130. parse = operand->exp.X_add_number;
  3131. /* Hack -- fixup for 16-bit hex quantities that get converted positive
  3132. instead of negative. */
  3133. if ((parse & 0x8000) && min == -32768 && max == 32767)
  3134. integer = (short) parse;
  3135. else
  3136. integer = parse;
  3137. if (integer >= min && integer <= max)
  3138. {
  3139. insn->opcode[which].word |= (integer & mask);
  3140. return 1;
  3141. }
  3142. as_bad (_("Operand '%s' out of range (%d <= x <= %d)"),
  3143. operand->buf, min, max);
  3144. }
  3145. else
  3146. {
  3147. if (insn->opcode[which].addr_expr.X_op == O_constant)
  3148. {
  3149. insn->opcode[which].word |=
  3150. insn->opcode[which].addr_expr.X_add_number & mask;
  3151. }
  3152. else
  3153. {
  3154. /* Do the fixup later; just store the expression. */
  3155. bfd_reloc_code_real_type rtype =
  3156. (mask == 0x1FF ? BFD_RELOC_TIC54X_PARTMS9 :
  3157. mask == 0xFFFF ? BFD_RELOC_TIC54X_16_OF_23 :
  3158. mask == 0x7F ? BFD_RELOC_TIC54X_PARTLS7 : BFD_RELOC_8);
  3159. int size = (mask == 0x1FF || mask == 0xFFFF) ? 2 : 1;
  3160. if (rtype == BFD_RELOC_8)
  3161. as_bad (_("Error in relocation handling"));
  3162. insn->opcode[which].r_nchars = size;
  3163. insn->opcode[which].r_type = rtype;
  3164. insn->opcode[which].unresolved = 1;
  3165. }
  3166. return 1;
  3167. }
  3168. return 0;
  3169. }
  3170. static int
  3171. encode_condition (tic54x_insn *insn, struct opstruct *operand)
  3172. {
  3173. symbol *cc = (symbol *) hash_find (cc_hash, operand->buf);
  3174. if (!cc)
  3175. {
  3176. as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
  3177. return 0;
  3178. }
  3179. #define CC_GROUP 0x40
  3180. #define CC_ACC 0x08
  3181. #define CATG_A1 0x07
  3182. #define CATG_B1 0x30
  3183. #define CATG_A2 0x30
  3184. #define CATG_B2 0x0C
  3185. #define CATG_C2 0x03
  3186. /* Disallow group 1 conditions mixed with group 2 conditions
  3187. if group 1, allow only one category A and one category B
  3188. if group 2, allow only one each of category A, B, and C. */
  3189. if (((insn->opcode[0].word & 0xFF) != 0))
  3190. {
  3191. if ((insn->opcode[0].word & CC_GROUP) != (cc->value & CC_GROUP))
  3192. {
  3193. as_bad (_("Condition \"%s\" does not match preceding group"),
  3194. operand->buf);
  3195. return 0;
  3196. }
  3197. if (insn->opcode[0].word & CC_GROUP)
  3198. {
  3199. if ((insn->opcode[0].word & CC_ACC) != (cc->value & CC_ACC))
  3200. {
  3201. as_bad (_("Condition \"%s\" uses a different accumulator from "
  3202. "a preceding condition"),
  3203. operand->buf);
  3204. return 0;
  3205. }
  3206. if ((insn->opcode[0].word & CATG_A1) && (cc->value & CATG_A1))
  3207. {
  3208. as_bad (_("Only one comparison conditional allowed"));
  3209. return 0;
  3210. }
  3211. if ((insn->opcode[0].word & CATG_B1) && (cc->value & CATG_B1))
  3212. {
  3213. as_bad (_("Only one overflow conditional allowed"));
  3214. return 0;
  3215. }
  3216. }
  3217. else if ( ((insn->opcode[0].word & CATG_A2) && (cc->value & CATG_A2))
  3218. || ((insn->opcode[0].word & CATG_B2) && (cc->value & CATG_B2))
  3219. || ((insn->opcode[0].word & CATG_C2) && (cc->value & CATG_C2)))
  3220. {
  3221. as_bad (_("Duplicate %s conditional"), operand->buf);
  3222. return 0;
  3223. }
  3224. }
  3225. insn->opcode[0].word |= cc->value;
  3226. return 1;
  3227. }
  3228. static int
  3229. encode_cc3 (tic54x_insn *insn, struct opstruct *operand)
  3230. {
  3231. symbol *cc3 = (symbol *) hash_find (cc3_hash, operand->buf);
  3232. int value = cc3 ? cc3->value : operand->exp.X_add_number << 8;
  3233. if ((value & 0x0300) != value)
  3234. {
  3235. as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
  3236. return 0;
  3237. }
  3238. insn->opcode[0].word |= value;
  3239. return 1;
  3240. }
  3241. static int
  3242. encode_arx (tic54x_insn *insn, struct opstruct *operand)
  3243. {
  3244. int arf = strlen (operand->buf) >= 3 ? operand->buf[2] - '0' : -1;
  3245. if (strncasecmp ("ar", operand->buf, 2) || arf < 0 || arf > 7)
  3246. {
  3247. as_bad (_("Invalid auxiliary register (use AR0-AR7)"));
  3248. return 0;
  3249. }
  3250. insn->opcode[0].word |= arf;
  3251. return 1;
  3252. }
  3253. static int
  3254. encode_cc2 (tic54x_insn *insn, struct opstruct *operand)
  3255. {
  3256. symbol *cc2 = (symbol *) hash_find (cc2_hash, operand->buf);
  3257. if (!cc2)
  3258. {
  3259. as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
  3260. return 0;
  3261. }
  3262. insn->opcode[0].word |= cc2->value;
  3263. return 1;
  3264. }
  3265. static int
  3266. encode_operand (tic54x_insn *insn, enum optype type, struct opstruct *operand)
  3267. {
  3268. int ext = (insn->tm->flags & FL_EXT) != 0;
  3269. if (type == OP_MMR && operand->exp.X_op != O_constant)
  3270. {
  3271. /* Disallow long-constant addressing for memory-mapped addressing. */
  3272. if (insn->is_lkaddr)
  3273. {
  3274. as_bad (_("lk addressing modes are invalid for memory-mapped "
  3275. "register addressing"));
  3276. return 0;
  3277. }
  3278. type = OP_Smem;
  3279. /* Warn about *+ARx when used with MMR operands. */
  3280. if (strncasecmp (operand->buf, "*+ar", 4) == 0)
  3281. {
  3282. as_warn (_("Address mode *+ARx is not allowed in memory-mapped "
  3283. "register addressing. Resulting behavior is "
  3284. "undefined."));
  3285. }
  3286. }
  3287. switch (type)
  3288. {
  3289. case OP_None:
  3290. return 1;
  3291. case OP_dmad:
  3292. /* 16-bit immediate value. */
  3293. return encode_dmad (insn, operand, 0);
  3294. case OP_SRC:
  3295. if (TOUPPER (*operand->buf) == 'B')
  3296. {
  3297. insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 9);
  3298. if (insn->using_default_dst)
  3299. insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 8);
  3300. }
  3301. return 1;
  3302. case OP_RND:
  3303. /* Make sure this agrees with the OP_DST operand. */
  3304. if (!((TOUPPER (operand->buf[0]) == 'B') ^
  3305. ((insn->opcode[0].word & (1 << 8)) != 0)))
  3306. {
  3307. as_bad (_("Destination accumulator for each part of this parallel "
  3308. "instruction must be different"));
  3309. return 0;
  3310. }
  3311. return 1;
  3312. case OP_SRC1:
  3313. case OP_DST:
  3314. if (TOUPPER (operand->buf[0]) == 'B')
  3315. insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 8);
  3316. return 1;
  3317. case OP_Xmem:
  3318. case OP_Ymem:
  3319. {
  3320. int mod = (operand->buf[4] == '\0' ? 0 : /* *arx */
  3321. operand->buf[4] == '-' ? 1 : /* *arx- */
  3322. operand->buf[5] == '\0' ? 2 : 3); /* *arx+, *arx+0% */
  3323. int arf = operand->buf[3] - '0' - 2;
  3324. int code = (mod << 2) | arf;
  3325. insn->opcode[0].word |= (code << (type == OP_Xmem ? 4 : 0));
  3326. return 1;
  3327. }
  3328. case OP_Lmem:
  3329. case OP_Smem:
  3330. if (!is_indirect (operand))
  3331. return encode_address (insn, operand);
  3332. /* Fall through. */
  3333. case OP_Sind:
  3334. return encode_indirect (insn, operand);
  3335. case OP_xpmad_ms7:
  3336. return encode_dmad (insn, operand, 2);
  3337. case OP_xpmad:
  3338. return encode_dmad (insn, operand, 1);
  3339. case OP_PA:
  3340. case OP_pmad:
  3341. return encode_dmad (insn, operand, 0);
  3342. case OP_ARX:
  3343. return encode_arx (insn, operand);
  3344. case OP_MMRX:
  3345. case OP_MMRY:
  3346. case OP_MMR:
  3347. {
  3348. int value = operand->exp.X_add_number;
  3349. if (type == OP_MMR)
  3350. insn->opcode[0].word |= value;
  3351. else
  3352. {
  3353. if (value < 16 || value > 24)
  3354. {
  3355. as_bad (_("Memory mapped register \"%s\" out of range"),
  3356. operand->buf);
  3357. return 0;
  3358. }
  3359. if (type == OP_MMRX)
  3360. insn->opcode[0].word |= (value - 16) << 4;
  3361. else
  3362. insn->opcode[0].word |= (value - 16);
  3363. }
  3364. return 1;
  3365. }
  3366. case OP_B:
  3367. case OP_A:
  3368. return 1;
  3369. case OP_SHFT:
  3370. return encode_integer (insn, operand, ext + insn->is_lkaddr,
  3371. 0, 15, 0xF);
  3372. case OP_SHIFT:
  3373. return encode_integer (insn, operand, ext + insn->is_lkaddr,
  3374. -16, 15, 0x1F);
  3375. case OP_lk:
  3376. return encode_integer (insn, operand, 1 + insn->is_lkaddr,
  3377. -32768, 32767, 0xFFFF);
  3378. case OP_CC:
  3379. return encode_condition (insn, operand);
  3380. case OP_CC2:
  3381. return encode_cc2 (insn, operand);
  3382. case OP_CC3:
  3383. return encode_cc3 (insn, operand);
  3384. case OP_BITC:
  3385. return encode_integer (insn, operand, 0, 0, 15, 0xF);
  3386. case OP_k8:
  3387. return encode_integer (insn, operand, 0, -128, 127, 0xFF);
  3388. case OP_123:
  3389. {
  3390. int value = operand->exp.X_add_number;
  3391. int code;
  3392. if (value < 1 || value > 3)
  3393. {
  3394. as_bad (_("Invalid operand (use 1, 2, or 3)"));
  3395. return 0;
  3396. }
  3397. code = value == 1 ? 0 : value == 2 ? 0x2 : 0x1;
  3398. insn->opcode[0].word |= (code << 8);
  3399. return 1;
  3400. }
  3401. case OP_031:
  3402. return encode_integer (insn, operand, 0, 0, 31, 0x1F);
  3403. case OP_k8u:
  3404. return encode_integer (insn, operand, 0, 0, 255, 0xFF);
  3405. case OP_lku:
  3406. return encode_integer (insn, operand, 1 + insn->is_lkaddr,
  3407. 0, 65535, 0xFFFF);
  3408. case OP_SBIT:
  3409. {
  3410. symbol *sbit = (symbol *) hash_find (sbit_hash, operand->buf);
  3411. int value = is_absolute (operand) ?
  3412. operand->exp.X_add_number : (sbit ? sbit->value : -1);
  3413. int reg = 0;
  3414. if (insn->opcount == 1)
  3415. {
  3416. if (!sbit)
  3417. {
  3418. as_bad (_("A status register or status bit name is required"));
  3419. return 0;
  3420. }
  3421. /* Guess the register based on the status bit; "ovb" is the last
  3422. status bit defined for st0. */
  3423. if (sbit > (symbol *) hash_find (sbit_hash, "ovb"))
  3424. reg = 1;
  3425. }
  3426. if (value == -1)
  3427. {
  3428. as_bad (_("Unrecognized status bit \"%s\""), operand->buf);
  3429. return 0;
  3430. }
  3431. insn->opcode[0].word |= value;
  3432. insn->opcode[0].word |= (reg << 9);
  3433. return 1;
  3434. }
  3435. case OP_N:
  3436. if (strcasecmp (operand->buf, "st0") == 0
  3437. || strcasecmp (operand->buf, "st1") == 0)
  3438. {
  3439. insn->opcode[0].word |=
  3440. ((unsigned short) (operand->buf[2] - '0')) << 9;
  3441. return 1;
  3442. }
  3443. else if (operand->exp.X_op == O_constant
  3444. && (operand->exp.X_add_number == 0
  3445. || operand->exp.X_add_number == 1))
  3446. {
  3447. insn->opcode[0].word |=
  3448. ((unsigned short) (operand->exp.X_add_number)) << 9;
  3449. return 1;
  3450. }
  3451. as_bad (_("Invalid status register \"%s\""), operand->buf);
  3452. return 0;
  3453. case OP_k5:
  3454. return encode_integer (insn, operand, 0, -16, 15, 0x1F);
  3455. case OP_k3:
  3456. return encode_integer (insn, operand, 0, 0, 7, 0x7);
  3457. case OP_k9:
  3458. return encode_integer (insn, operand, 0, 0, 0x1FF, 0x1FF);
  3459. case OP_12:
  3460. if (operand->exp.X_add_number != 1
  3461. && operand->exp.X_add_number != 2)
  3462. {
  3463. as_bad (_("Operand \"%s\" out of range (use 1 or 2)"), operand->buf);
  3464. return 0;
  3465. }
  3466. insn->opcode[0].word |= (operand->exp.X_add_number - 1) << 9;
  3467. return 1;
  3468. case OP_16:
  3469. case OP_T:
  3470. case OP_TS:
  3471. case OP_ASM:
  3472. case OP_TRN:
  3473. case OP_DP:
  3474. case OP_ARP:
  3475. /* No encoding necessary. */
  3476. return 1;
  3477. default:
  3478. return 0;
  3479. }
  3480. return 1;
  3481. }
  3482. static void
  3483. emit_insn (tic54x_insn *insn)
  3484. {
  3485. int i;
  3486. flagword oldflags = bfd_get_section_flags (stdoutput, now_seg);
  3487. flagword flags = oldflags | SEC_CODE;
  3488. if (! bfd_set_section_flags (stdoutput, now_seg, flags))
  3489. as_warn (_("error setting flags for \"%s\": %s"),
  3490. bfd_section_name (stdoutput, now_seg),
  3491. bfd_errmsg (bfd_get_error ()));
  3492. for (i = 0; i < insn->words; i++)
  3493. {
  3494. int size = (insn->opcode[i].unresolved
  3495. && insn->opcode[i].r_type == BFD_RELOC_TIC54X_23) ? 4 : 2;
  3496. char *p = frag_more (size);
  3497. if (size == 2)
  3498. md_number_to_chars (p, (valueT) insn->opcode[i].word, 2);
  3499. else
  3500. md_number_to_chars (p, (valueT) insn->opcode[i].word << 16, 4);
  3501. if (insn->opcode[i].unresolved)
  3502. fix_new_exp (frag_now, p - frag_now->fr_literal,
  3503. insn->opcode[i].r_nchars, &insn->opcode[i].addr_expr,
  3504. FALSE, insn->opcode[i].r_type);
  3505. }
  3506. }
  3507. /* Convert the operand strings into appropriate opcode values
  3508. return the total number of words used by the instruction. */
  3509. static int
  3510. build_insn (tic54x_insn *insn)
  3511. {
  3512. int i;
  3513. /* Only non-parallel instructions support lk addressing. */
  3514. if (!(insn->tm->flags & FL_PAR))
  3515. {
  3516. for (i = 0; i < insn->opcount; i++)
  3517. {
  3518. if ((OPTYPE (insn->operands[i].type) == OP_Smem
  3519. || OPTYPE (insn->operands[i].type) == OP_Lmem
  3520. || OPTYPE (insn->operands[i].type) == OP_Sind)
  3521. && strchr (insn->operands[i].buf, '(')
  3522. /* Don't mistake stack-relative addressing for lk addressing. */
  3523. && strncasecmp (insn->operands[i].buf, "*sp (", 4) != 0)
  3524. {
  3525. insn->is_lkaddr = 1;
  3526. insn->lkoperand = i;
  3527. break;
  3528. }
  3529. }
  3530. }
  3531. insn->words = insn->tm->words + insn->is_lkaddr;
  3532. insn->opcode[0].word = insn->tm->opcode;
  3533. if (insn->tm->flags & FL_EXT)
  3534. insn->opcode[1 + insn->is_lkaddr].word = insn->tm->opcode2;
  3535. for (i = 0; i < insn->opcount; i++)
  3536. {
  3537. enum optype type = insn->operands[i].type;
  3538. if (!encode_operand (insn, type, &insn->operands[i]))
  3539. return 0;
  3540. }
  3541. if (insn->tm->flags & FL_PAR)
  3542. for (i = 0; i < insn->paropcount; i++)
  3543. {
  3544. enum optype partype = insn->paroperands[i].type;
  3545. if (!encode_operand (insn, partype, &insn->paroperands[i]))
  3546. return 0;
  3547. }
  3548. emit_insn (insn);
  3549. return insn->words;
  3550. }
  3551. static int
  3552. optimize_insn (tic54x_insn *insn)
  3553. {
  3554. /* Optimize some instructions, helping out the brain-dead programmer. */
  3555. #define is_zero(op) ((op).exp.X_op == O_constant && (op).exp.X_add_number == 0)
  3556. if (strcasecmp (insn->tm->name, "add") == 0)
  3557. {
  3558. if (insn->opcount > 1
  3559. && is_accumulator (&insn->operands[insn->opcount - 2])
  3560. && is_accumulator (&insn->operands[insn->opcount - 1])
  3561. && strcasecmp (insn->operands[insn->opcount - 2].buf,
  3562. insn->operands[insn->opcount - 1].buf) == 0)
  3563. {
  3564. --insn->opcount;
  3565. insn->using_default_dst = 1;
  3566. return 1;
  3567. }
  3568. /* Try to collapse if Xmem and shift count is zero. */
  3569. if ((OPTYPE (insn->tm->operand_types[0]) == OP_Xmem
  3570. && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT
  3571. && is_zero (insn->operands[1]))
  3572. /* Or if Smem, shift is zero or absent, and SRC == DST. */
  3573. || (OPTYPE (insn->tm->operand_types[0]) == OP_Smem
  3574. && OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
  3575. && is_type (&insn->operands[1], OP_SHIFT)
  3576. && is_zero (insn->operands[1]) && insn->opcount == 3))
  3577. {
  3578. insn->operands[1] = insn->operands[2];
  3579. insn->opcount = 2;
  3580. return 1;
  3581. }
  3582. }
  3583. else if (strcasecmp (insn->tm->name, "ld") == 0)
  3584. {
  3585. if (insn->opcount == 3 && insn->operands[0].type != OP_SRC)
  3586. {
  3587. if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
  3588. || OPTYPE (insn->tm->operand_types[1]) == OP_SHFT)
  3589. && is_zero (insn->operands[1])
  3590. && (OPTYPE (insn->tm->operand_types[0]) != OP_lk
  3591. || (insn->operands[0].exp.X_op == O_constant
  3592. && insn->operands[0].exp.X_add_number <= 255
  3593. && insn->operands[0].exp.X_add_number >= 0)))
  3594. {
  3595. insn->operands[1] = insn->operands[2];
  3596. insn->opcount = 2;
  3597. return 1;
  3598. }
  3599. }
  3600. }
  3601. else if (strcasecmp (insn->tm->name, "sth") == 0
  3602. || strcasecmp (insn->tm->name, "stl") == 0)
  3603. {
  3604. if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
  3605. || OPTYPE (insn->tm->operand_types[1]) == OP_SHFT)
  3606. && is_zero (insn->operands[1]))
  3607. {
  3608. insn->operands[1] = insn->operands[2];
  3609. insn->opcount = 2;
  3610. return 1;
  3611. }
  3612. }
  3613. else if (strcasecmp (insn->tm->name, "sub") == 0)
  3614. {
  3615. if (insn->opcount > 1
  3616. && is_accumulator (&insn->operands[insn->opcount - 2])
  3617. && is_accumulator (&insn->operands[insn->opcount - 1])
  3618. && strcasecmp (insn->operands[insn->opcount - 2].buf,
  3619. insn->operands[insn->opcount - 1].buf) == 0)
  3620. {
  3621. --insn->opcount;
  3622. insn->using_default_dst = 1;
  3623. return 1;
  3624. }
  3625. if ( ((OPTYPE (insn->tm->operand_types[0]) == OP_Smem
  3626. && OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT)
  3627. || (OPTYPE (insn->tm->operand_types[0]) == OP_Xmem
  3628. && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT))
  3629. && is_zero (insn->operands[1])
  3630. && insn->opcount == 3)
  3631. {
  3632. insn->operands[1] = insn->operands[2];
  3633. insn->opcount = 2;
  3634. return 1;
  3635. }
  3636. }
  3637. return 0;
  3638. }
  3639. /* Find a matching template if possible, and get the operand strings. */
  3640. static int
  3641. tic54x_parse_insn (tic54x_insn *insn, char *line)
  3642. {
  3643. insn->tm = (insn_template *) hash_find (op_hash, insn->mnemonic);
  3644. if (!insn->tm)
  3645. {
  3646. as_bad (_("Unrecognized instruction \"%s\""), insn->mnemonic);
  3647. return 0;
  3648. }
  3649. insn->opcount = get_operands (insn->operands, line);
  3650. if (insn->opcount < 0)
  3651. return 0;
  3652. /* Check each variation of operands for this mnemonic. */
  3653. while (insn->tm->name && strcasecmp (insn->tm->name, insn->mnemonic) == 0)
  3654. {
  3655. if (insn->opcount >= insn->tm->minops
  3656. && insn->opcount <= insn->tm->maxops
  3657. && operands_match (insn, &insn->operands[0], insn->opcount,
  3658. insn->tm->operand_types,
  3659. insn->tm->minops, insn->tm->maxops))
  3660. {
  3661. /* SUCCESS! now try some optimizations. */
  3662. if (optimize_insn (insn))
  3663. {
  3664. insn->tm = (insn_template *) hash_find (op_hash,
  3665. insn->mnemonic);
  3666. continue;
  3667. }
  3668. return 1;
  3669. }
  3670. ++(insn->tm);
  3671. }
  3672. as_bad (_("Unrecognized operand list '%s' for instruction '%s'"),
  3673. line, insn->mnemonic);
  3674. return 0;
  3675. }
  3676. /* We set this in start_line_hook, 'cause if we do a line replacement, we
  3677. won't be able to see the next line. */
  3678. static int parallel_on_next_line_hint = 0;
  3679. /* See if this is part of a parallel instruction
  3680. Look for a subsequent line starting with "||". */
  3681. static int
  3682. next_line_shows_parallel (char *next_line)
  3683. {
  3684. /* Look for the second half. */
  3685. while (ISSPACE (*next_line))
  3686. ++next_line;
  3687. return (next_line[0] == PARALLEL_SEPARATOR
  3688. && next_line[1] == PARALLEL_SEPARATOR);
  3689. }
  3690. static int
  3691. tic54x_parse_parallel_insn_firstline (tic54x_insn *insn, char *line)
  3692. {
  3693. insn->tm = (insn_template *) hash_find (parop_hash, insn->mnemonic);
  3694. if (!insn->tm)
  3695. {
  3696. as_bad (_("Unrecognized parallel instruction \"%s\""),
  3697. insn->mnemonic);
  3698. return 0;
  3699. }
  3700. while (insn->tm->name && strcasecmp (insn->tm->name,
  3701. insn->mnemonic) == 0)
  3702. {
  3703. insn->opcount = get_operands (insn->operands, line);
  3704. if (insn->opcount < 0)
  3705. return 0;
  3706. if (insn->opcount == 2
  3707. && operands_match (insn, &insn->operands[0], insn->opcount,
  3708. insn->tm->operand_types, 2, 2))
  3709. {
  3710. return 1;
  3711. }
  3712. ++(insn->tm);
  3713. }
  3714. /* Didn't find a matching parallel; try for a normal insn. */
  3715. return 0;
  3716. }
  3717. /* Parse the second line of a two-line parallel instruction. */
  3718. static int
  3719. tic54x_parse_parallel_insn_lastline (tic54x_insn *insn, char *line)
  3720. {
  3721. int valid_mnemonic = 0;
  3722. insn->paropcount = get_operands (insn->paroperands, line);
  3723. while (insn->tm->name && strcasecmp (insn->tm->name,
  3724. insn->mnemonic) == 0)
  3725. {
  3726. if (strcasecmp (insn->tm->parname, insn->parmnemonic) == 0)
  3727. {
  3728. valid_mnemonic = 1;
  3729. if (insn->paropcount >= insn->tm->minops
  3730. && insn->paropcount <= insn->tm->maxops
  3731. && operands_match (insn, insn->paroperands,
  3732. insn->paropcount,
  3733. insn->tm->paroperand_types,
  3734. insn->tm->minops, insn->tm->maxops))
  3735. return 1;
  3736. }
  3737. ++(insn->tm);
  3738. }
  3739. if (valid_mnemonic)
  3740. as_bad (_("Invalid operand (s) for parallel instruction \"%s\""),
  3741. insn->parmnemonic);
  3742. else
  3743. as_bad (_("Unrecognized parallel instruction combination \"%s || %s\""),
  3744. insn->mnemonic, insn->parmnemonic);
  3745. return 0;
  3746. }
  3747. /* If quotes found, return copy of line up to closing quote;
  3748. otherwise up until terminator.
  3749. If it's a string, pass as-is; otherwise attempt substitution symbol
  3750. replacement on the value. */
  3751. static char *
  3752. subsym_get_arg (char *line, char *terminators, char **str, int nosub)
  3753. {
  3754. char *ptr = line;
  3755. char *endp;
  3756. int is_string = *line == '"';
  3757. int is_char = ISDIGIT (*line);
  3758. if (is_char)
  3759. {
  3760. while (ISDIGIT (*ptr))
  3761. ++ptr;
  3762. endp = ptr;
  3763. *str = xmalloc (ptr - line + 1);
  3764. strncpy (*str, line, ptr - line);
  3765. (*str)[ptr - line] = 0;
  3766. }
  3767. else if (is_string)
  3768. {
  3769. char *savedp = input_line_pointer;
  3770. int len;
  3771. input_line_pointer = ptr;
  3772. *str = demand_copy_C_string (&len);
  3773. endp = input_line_pointer;
  3774. input_line_pointer = savedp;
  3775. /* Do forced substitutions if requested. */
  3776. if (!nosub && **str == ':')
  3777. *str = subsym_substitute (*str, 1);
  3778. }
  3779. else
  3780. {
  3781. char *term = terminators;
  3782. char *value = NULL;
  3783. while (*ptr && *ptr != *term)
  3784. {
  3785. if (!*term)
  3786. {
  3787. term = terminators;
  3788. ++ptr;
  3789. }
  3790. else
  3791. ++term;
  3792. }
  3793. endp = ptr;
  3794. *str = xmalloc (ptr - line + 1);
  3795. strncpy (*str, line, ptr - line);
  3796. (*str)[ptr - line] = 0;
  3797. /* Do simple substitution, if available. */
  3798. if (!nosub && (value = subsym_lookup (*str, macro_level)) != NULL)
  3799. *str = value;
  3800. }
  3801. return endp;
  3802. }
  3803. /* Replace the given substitution string.
  3804. We start at the innermost macro level, so that existing locals remain local
  3805. Note: we're treating macro args identically to .var's; I don't know if
  3806. that's compatible w/TI's assembler. */
  3807. static void
  3808. subsym_create_or_replace (char *name, char *value)
  3809. {
  3810. int i;
  3811. for (i = macro_level; i > 0; i--)
  3812. {
  3813. if (hash_find (subsym_hash[i], name))
  3814. {
  3815. hash_replace (subsym_hash[i], name, value);
  3816. return;
  3817. }
  3818. }
  3819. if (hash_find (subsym_hash[0], name))
  3820. hash_replace (subsym_hash[0], name, value);
  3821. else
  3822. hash_insert (subsym_hash[0], name, value);
  3823. }
  3824. /* Look up the substitution string replacement for the given symbol.
  3825. Start with the innermost macro substitution table given and work
  3826. outwards. */
  3827. static char *
  3828. subsym_lookup (char *name, int nest_level)
  3829. {
  3830. char *value = hash_find (subsym_hash[nest_level], name);
  3831. if (value || nest_level == 0)
  3832. return value;
  3833. return subsym_lookup (name, nest_level - 1);
  3834. }
  3835. /* Do substitution-symbol replacement on the given line (recursively).
  3836. return the argument if no substitution was done
  3837. Also look for built-in functions ($func (arg)) and local labels.
  3838. If FORCED is set, look for forced substitutions of the form ':SYMBOL:'. */
  3839. static char *
  3840. subsym_substitute (char *line, int forced)
  3841. {
  3842. /* For each apparent symbol, see if it's a substitution symbol, and if so,
  3843. replace it in the input. */
  3844. char *replacement; /* current replacement for LINE. */
  3845. char *head; /* Start of line. */
  3846. char *ptr; /* Current examination point. */
  3847. int changed = 0; /* Did we make a substitution? */
  3848. int eval_line = 0; /* Is this line a .eval/.asg statement? */
  3849. int eval_symbol = 0; /* Are we in the middle of the symbol for
  3850. .eval/.asg? */
  3851. char *eval_end = NULL;
  3852. int recurse = 1;
  3853. int line_conditional = 0;
  3854. char *tmp;
  3855. /* Work with a copy of the input line. */
  3856. replacement = xmalloc (strlen (line) + 1);
  3857. strcpy (replacement, line);
  3858. ptr = head = replacement;
  3859. /* Flag lines where we might need to replace a single '=' with two;
  3860. GAS uses single '=' to assign macro args values, and possibly other
  3861. places, so limit what we replace. */
  3862. if (strstr (line, ".if")
  3863. || strstr (line, ".elseif")
  3864. || strstr (line, ".break"))
  3865. line_conditional = 1;
  3866. /* Watch out for .eval, so that we avoid doing substitution on the
  3867. symbol being assigned a value. */
  3868. if (strstr (line, ".eval") || strstr (line, ".asg"))
  3869. eval_line = 1;
  3870. /* If it's a macro definition, don't do substitution on the argument
  3871. names. */
  3872. if (strstr (line, ".macro"))
  3873. return line;
  3874. while (!is_end_of_line[(int) *ptr])
  3875. {
  3876. int current_char = *ptr;
  3877. /* Need to update this since LINE may have been modified. */
  3878. if (eval_line)
  3879. eval_end = strrchr (ptr, ',');
  3880. /* Replace triple double quotes with bounding quote/escapes. */
  3881. if (current_char == '"' && ptr[1] == '"' && ptr[2] == '"')
  3882. {
  3883. ptr[1] = '\\';
  3884. tmp = strstr (ptr + 2, "\"\"\"");
  3885. if (tmp)
  3886. tmp[0] = '\\';
  3887. changed = 1;
  3888. }
  3889. /* Replace a single '=' with a '==';
  3890. for compatibility with older code only. */
  3891. if (line_conditional && current_char == '=')
  3892. {
  3893. if (ptr[1] == '=')
  3894. {
  3895. ptr += 2;
  3896. continue;
  3897. }
  3898. *ptr++ = '\0';
  3899. tmp = xmalloc (strlen (head) + 2 + strlen (ptr) + 1);
  3900. sprintf (tmp, "%s==%s", head, ptr);
  3901. /* Continue examining after the '=='. */
  3902. ptr = tmp + strlen (head) + 2;
  3903. free (replacement);
  3904. head = replacement = tmp;
  3905. changed = 1;
  3906. }
  3907. /* Flag when we've reached the symbol part of .eval/.asg. */
  3908. if (eval_line && ptr >= eval_end)
  3909. eval_symbol = 1;
  3910. /* For each apparent symbol, see if it's a substitution symbol, and if
  3911. so, replace it in the input. */
  3912. if ((forced && current_char == ':')
  3913. || (!forced && is_name_beginner (current_char)))
  3914. {
  3915. char *name; /* Symbol to be replaced. */
  3916. char *savedp = input_line_pointer;
  3917. int c;
  3918. char *value = NULL;
  3919. char *tail; /* Rest of line after symbol. */
  3920. /* Skip the colon. */
  3921. if (forced)
  3922. ++ptr;
  3923. input_line_pointer = ptr;
  3924. c = get_symbol_name (&name);
  3925. /* '?' is not normally part of a symbol, but it IS part of a local
  3926. label. */
  3927. if (c == '?')
  3928. {
  3929. *input_line_pointer++ = c;
  3930. c = *input_line_pointer;
  3931. *input_line_pointer = '\0';
  3932. }
  3933. /* Avoid infinite recursion; if a symbol shows up a second time for
  3934. substitution, leave it as is. */
  3935. if (hash_find (subsym_recurse_hash, name) == NULL)
  3936. value = subsym_lookup (name, macro_level);
  3937. else
  3938. as_warn (_("%s symbol recursion stopped at "
  3939. "second appearance of '%s'"),
  3940. forced ? "Forced substitution" : "Substitution", name);
  3941. ptr = tail = input_line_pointer;
  3942. input_line_pointer = savedp;
  3943. /* Check for local labels; replace them with the appropriate
  3944. substitution. */
  3945. if ((*name == '$' && ISDIGIT (name[1]) && name[2] == '\0')
  3946. || name[strlen (name) - 1] == '?')
  3947. {
  3948. /* Use an existing identifier for that label if, available, or
  3949. create a new, unique identifier. */
  3950. value = hash_find (local_label_hash[macro_level], name);
  3951. if (value == NULL)
  3952. {
  3953. char digit[11];
  3954. char *namecopy = strcpy (xmalloc (strlen (name) + 1), name);
  3955. value = strcpy (xmalloc (strlen (name) + sizeof (digit) + 1),
  3956. name);
  3957. if (*value != '$')
  3958. value[strlen (value) - 1] = '\0';
  3959. sprintf (digit, ".%d", local_label_id++);
  3960. strcat (value, digit);
  3961. hash_insert (local_label_hash[macro_level], namecopy, value);
  3962. }
  3963. /* Indicate where to continue looking for substitutions. */
  3964. ptr = tail;
  3965. }
  3966. /* Check for built-in subsym and math functions. */
  3967. else if (value != NULL && *name == '$')
  3968. {
  3969. subsym_proc_entry *entry = (subsym_proc_entry *) value;
  3970. math_proc_entry *math_entry = hash_find (math_hash, name);
  3971. char *arg1, *arg2 = NULL;
  3972. *ptr = c;
  3973. if (entry == NULL)
  3974. {
  3975. as_bad (_("Unrecognized substitution symbol function"));
  3976. break;
  3977. }
  3978. else if (*ptr != '(')
  3979. {
  3980. as_bad (_("Missing '(' after substitution symbol function"));
  3981. break;
  3982. }
  3983. ++ptr;
  3984. if (math_entry != NULL)
  3985. {
  3986. float farg1, farg2 = 0;
  3987. volatile float fresult;
  3988. farg1 = (float) strtod (ptr, &ptr);
  3989. if (math_entry->nargs == 2)
  3990. {
  3991. if (*ptr++ != ',')
  3992. {
  3993. as_bad (_("Expecting second argument"));
  3994. break;
  3995. }
  3996. farg2 = (float) strtod (ptr, &ptr);
  3997. }
  3998. fresult = (*math_entry->proc) (farg1, farg2);
  3999. value = xmalloc (128);
  4000. if (math_entry->int_return)
  4001. sprintf (value, "%d", (int) fresult);
  4002. else
  4003. sprintf (value, "%f", fresult);
  4004. if (*ptr++ != ')')
  4005. {
  4006. as_bad (_("Extra junk in function call, expecting ')'"));
  4007. break;
  4008. }
  4009. /* Don't bother recursing; the replacement isn't a
  4010. symbol. */
  4011. recurse = 0;
  4012. }
  4013. else
  4014. {
  4015. int val;
  4016. int arg_type[2] = { *ptr == '"' , 0 };
  4017. int ismember = !strcmp (entry->name, "$ismember");
  4018. /* Parse one or two args, which must be a substitution
  4019. symbol, string or a character-string constant. */
  4020. /* For all functions, a string or substitution symbol may be
  4021. used, with the following exceptions:
  4022. firstch/lastch: 2nd arg must be character constant
  4023. ismember: both args must be substitution symbols. */
  4024. ptr = subsym_get_arg (ptr, ",)", &arg1, ismember);
  4025. if (!arg1)
  4026. break;
  4027. if (entry->nargs == 2)
  4028. {
  4029. if (*ptr++ != ',')
  4030. {
  4031. as_bad (_("Function expects two arguments"));
  4032. break;
  4033. }
  4034. /* Character constants are converted to numerics
  4035. by the preprocessor. */
  4036. arg_type[1] = (ISDIGIT (*ptr)) ? 2 : (*ptr == '"');
  4037. ptr = subsym_get_arg (ptr, ")", &arg2, ismember);
  4038. }
  4039. /* Args checking. */
  4040. if ((!strcmp (entry->name, "$firstch")
  4041. || !strcmp (entry->name, "$lastch"))
  4042. && arg_type[1] != 2)
  4043. {
  4044. as_bad (_("Expecting character constant argument"));
  4045. break;
  4046. }
  4047. if (ismember
  4048. && (arg_type[0] != 0 || arg_type[1] != 0))
  4049. {
  4050. as_bad (_("Both arguments must be substitution symbols"));
  4051. break;
  4052. }
  4053. if (*ptr++ != ')')
  4054. {
  4055. as_bad (_("Extra junk in function call, expecting ')'"));
  4056. break;
  4057. }
  4058. val = (*entry->proc) (arg1, arg2);
  4059. value = xmalloc (64);
  4060. sprintf (value, "%d", val);
  4061. }
  4062. /* Fix things up to replace the entire expression, not just the
  4063. function name. */
  4064. tail = ptr;
  4065. c = *tail;
  4066. }
  4067. if (value != NULL && !eval_symbol)
  4068. {
  4069. /* Replace the symbol with its string replacement and
  4070. continue. Recursively replace VALUE until either no
  4071. substitutions are performed, or a substitution that has been
  4072. previously made is encountered again.
  4073. put the symbol into the recursion hash table so we only
  4074. try to replace a symbol once. */
  4075. if (recurse)
  4076. {
  4077. hash_insert (subsym_recurse_hash, name, name);
  4078. value = subsym_substitute (value, macro_level > 0);
  4079. hash_delete (subsym_recurse_hash, name, FALSE);
  4080. }
  4081. /* Temporarily zero-terminate where the symbol started. */
  4082. *name = 0;
  4083. if (forced)
  4084. {
  4085. if (c == '(')
  4086. {
  4087. /* Subscripted substitution symbol -- use just the
  4088. indicated portion of the string; the description
  4089. kinda indicates that forced substitution is not
  4090. supposed to be recursive, but I'm not sure. */
  4091. unsigned beg, len = 1; /* default to a single char */
  4092. char *newval = strcpy (xmalloc (strlen (value) + 1),
  4093. value);
  4094. savedp = input_line_pointer;
  4095. input_line_pointer = tail + 1;
  4096. beg = get_absolute_expression ();
  4097. if (beg < 1)
  4098. {
  4099. as_bad (_("Invalid subscript (use 1 to %d)"),
  4100. (int) strlen (value));
  4101. break;
  4102. }
  4103. if (*input_line_pointer == ',')
  4104. {
  4105. ++input_line_pointer;
  4106. len = get_absolute_expression ();
  4107. if (beg + len > strlen (value))
  4108. {
  4109. as_bad (_("Invalid length (use 0 to %d"),
  4110. (int) strlen (value) - beg);
  4111. break;
  4112. }
  4113. }
  4114. newval += beg - 1;
  4115. newval[len] = 0;
  4116. tail = input_line_pointer;
  4117. if (*tail++ != ')')
  4118. {
  4119. as_bad (_("Missing ')' in subscripted substitution "
  4120. "symbol expression"));
  4121. break;
  4122. }
  4123. c = *tail;
  4124. input_line_pointer = savedp;
  4125. value = newval;
  4126. }
  4127. name[-1] = 0;
  4128. }
  4129. tmp = xmalloc (strlen (head) + strlen (value) +
  4130. strlen (tail + 1) + 2);
  4131. strcpy (tmp, head);
  4132. strcat (tmp, value);
  4133. /* Make sure forced substitutions are properly terminated. */
  4134. if (forced)
  4135. {
  4136. if (c != ':')
  4137. {
  4138. as_bad (_("Missing forced substitution terminator ':'"));
  4139. break;
  4140. }
  4141. ++tail;
  4142. }
  4143. else
  4144. /* Restore the character after the symbol end. */
  4145. *tail = c;
  4146. strcat (tmp, tail);
  4147. /* Continue examining after the replacement value. */
  4148. ptr = tmp + strlen (head) + strlen (value);
  4149. free (replacement);
  4150. head = replacement = tmp;
  4151. changed = 1;
  4152. }
  4153. else
  4154. *ptr = c;
  4155. }
  4156. else
  4157. {
  4158. ++ptr;
  4159. }
  4160. }
  4161. if (changed)
  4162. return replacement;
  4163. else
  4164. return line;
  4165. }
  4166. /* We use this to handle substitution symbols
  4167. hijack input_line_pointer, replacing it with our substituted string.
  4168. .sslist should enable listing the line after replacements are made...
  4169. returns the new buffer limit. */
  4170. void
  4171. tic54x_start_line_hook (void)
  4172. {
  4173. char *line, *endp;
  4174. char *replacement = NULL;
  4175. /* Work with a copy of the input line, including EOL char. */
  4176. endp = input_line_pointer;
  4177. while (!is_end_of_line[(int) *endp++])
  4178. ;
  4179. line = xmalloc (endp - input_line_pointer + 1);
  4180. strncpy (line, input_line_pointer, endp - input_line_pointer + 1);
  4181. line[endp - input_line_pointer] = 0;
  4182. /* Scan ahead for parallel insns. */
  4183. parallel_on_next_line_hint = next_line_shows_parallel (endp);
  4184. /* If within a macro, first process forced replacements. */
  4185. if (macro_level > 0)
  4186. replacement = subsym_substitute (line, 1);
  4187. else
  4188. replacement = line;
  4189. replacement = subsym_substitute (replacement, 0);
  4190. if (replacement != line)
  4191. {
  4192. char *tmp = replacement;
  4193. char *comment = strchr (replacement, ';');
  4194. char endc = replacement[strlen (replacement) - 1];
  4195. /* Clean up the replacement; we'd prefer to have this done by the
  4196. standard preprocessing equipment (maybe do_scrub_chars?)
  4197. but for now, do a quick-and-dirty. */
  4198. if (comment != NULL)
  4199. {
  4200. comment[0] = endc;
  4201. comment[1] = 0;
  4202. --comment;
  4203. }
  4204. else
  4205. comment = replacement + strlen (replacement) - 1;
  4206. /* Trim trailing whitespace. */
  4207. while (ISSPACE (*comment))
  4208. {
  4209. comment[0] = endc;
  4210. comment[1] = 0;
  4211. --comment;
  4212. }
  4213. /* Compact leading whitespace. */
  4214. while (ISSPACE (tmp[0]) && ISSPACE (tmp[1]))
  4215. ++tmp;
  4216. input_line_pointer = endp;
  4217. input_scrub_insert_line (tmp);
  4218. free (replacement);
  4219. free (line);
  4220. /* Keep track of whether we've done a substitution. */
  4221. substitution_line = 1;
  4222. }
  4223. else
  4224. {
  4225. /* No change. */
  4226. free (line);
  4227. substitution_line = 0;
  4228. }
  4229. }
  4230. /* This is the guts of the machine-dependent assembler. STR points to a
  4231. machine dependent instruction. This function is supposed to emit
  4232. the frags/bytes it assembles to. */
  4233. void
  4234. md_assemble (char *line)
  4235. {
  4236. static int repeat_slot = 0;
  4237. static int delay_slots = 0; /* How many delay slots left to fill? */
  4238. static int is_parallel = 0;
  4239. static tic54x_insn insn;
  4240. char *lptr;
  4241. char *savedp = input_line_pointer;
  4242. int c;
  4243. input_line_pointer = line;
  4244. c = get_symbol_name (&line);
  4245. if (cpu == VNONE)
  4246. cpu = V542;
  4247. if (address_mode_needs_set)
  4248. {
  4249. set_address_mode (amode);
  4250. address_mode_needs_set = 0;
  4251. }
  4252. if (cpu_needs_set)
  4253. {
  4254. set_cpu (cpu);
  4255. cpu_needs_set = 0;
  4256. }
  4257. assembly_begun = 1;
  4258. if (is_parallel)
  4259. {
  4260. is_parallel = 0;
  4261. strcpy (insn.parmnemonic, line);
  4262. lptr = input_line_pointer;
  4263. *lptr = c;
  4264. input_line_pointer = savedp;
  4265. if (tic54x_parse_parallel_insn_lastline (&insn, lptr))
  4266. {
  4267. int words = build_insn (&insn);
  4268. if (delay_slots != 0)
  4269. {
  4270. if (words > delay_slots)
  4271. {
  4272. as_bad (_("Instruction does not fit in available delay "
  4273. "slots (%d-word insn, %d slots left)"),
  4274. words, delay_slots);
  4275. delay_slots = 0;
  4276. return;
  4277. }
  4278. delay_slots -= words;
  4279. }
  4280. }
  4281. return;
  4282. }
  4283. memset (&insn, 0, sizeof (insn));
  4284. strcpy (insn.mnemonic, line);
  4285. lptr = input_line_pointer;
  4286. *lptr = c;
  4287. input_line_pointer = savedp;
  4288. /* See if this line is part of a parallel instruction; if so, either this
  4289. line or the next line will have the "||" specifier preceding the
  4290. mnemonic, and we look for it in the parallel insn hash table. */
  4291. if (strstr (line, "||") != NULL || parallel_on_next_line_hint)
  4292. {
  4293. char *tmp = strstr (line, "||");
  4294. if (tmp != NULL)
  4295. *tmp = '\0';
  4296. if (tic54x_parse_parallel_insn_firstline (&insn, lptr))
  4297. {
  4298. is_parallel = 1;
  4299. /* If the parallel part is on the same line, process it now,
  4300. otherwise let the assembler pick up the next line for us. */
  4301. if (tmp != NULL)
  4302. {
  4303. while (ISSPACE (tmp[2]))
  4304. ++tmp;
  4305. md_assemble (tmp + 2);
  4306. }
  4307. }
  4308. else
  4309. {
  4310. as_bad (_("Unrecognized parallel instruction '%s'"), line);
  4311. }
  4312. return;
  4313. }
  4314. if (tic54x_parse_insn (&insn, lptr))
  4315. {
  4316. int words;
  4317. if ((insn.tm->flags & FL_LP)
  4318. && cpu != V545LP && cpu != V546LP)
  4319. {
  4320. as_bad (_("Instruction '%s' requires an LP cpu version"),
  4321. insn.tm->name);
  4322. return;
  4323. }
  4324. if ((insn.tm->flags & FL_FAR)
  4325. && amode != far_mode)
  4326. {
  4327. as_bad (_("Instruction '%s' requires far mode addressing"),
  4328. insn.tm->name);
  4329. return;
  4330. }
  4331. words = build_insn (&insn);
  4332. /* Is this instruction in a delay slot? */
  4333. if (delay_slots)
  4334. {
  4335. if (words > delay_slots)
  4336. {
  4337. as_warn (_("Instruction does not fit in available delay "
  4338. "slots (%d-word insn, %d slots left). "
  4339. "Resulting behavior is undefined."),
  4340. words, delay_slots);
  4341. delay_slots = 0;
  4342. return;
  4343. }
  4344. /* Branches in delay slots are not allowed. */
  4345. if (insn.tm->flags & FL_BMASK)
  4346. {
  4347. as_warn (_("Instructions which cause PC discontinuity are not "
  4348. "allowed in a delay slot. "
  4349. "Resulting behavior is undefined."));
  4350. }
  4351. delay_slots -= words;
  4352. }
  4353. /* Is this instruction the target of a repeat? */
  4354. if (repeat_slot)
  4355. {
  4356. if (insn.tm->flags & FL_NR)
  4357. as_warn (_("'%s' is not repeatable. "
  4358. "Resulting behavior is undefined."),
  4359. insn.tm->name);
  4360. else if (insn.is_lkaddr)
  4361. as_warn (_("Instructions using long offset modifiers or absolute "
  4362. "addresses are not repeatable. "
  4363. "Resulting behavior is undefined."));
  4364. repeat_slot = 0;
  4365. }
  4366. /* Make sure we check the target of a repeat instruction. */
  4367. if (insn.tm->flags & B_REPEAT)
  4368. {
  4369. repeat_slot = 1;
  4370. /* FIXME -- warn if repeat_slot == 1 at EOF. */
  4371. }
  4372. /* Make sure we check our delay slots for validity. */
  4373. if (insn.tm->flags & FL_DELAY)
  4374. {
  4375. delay_slots = 2;
  4376. /* FIXME -- warn if delay_slots != 0 at EOF. */
  4377. }
  4378. }
  4379. }
  4380. /* Do a final adjustment on the symbol table; in this case, make sure we have
  4381. a ".file" symbol. */
  4382. void
  4383. tic54x_adjust_symtab (void)
  4384. {
  4385. if (symbol_rootP == NULL
  4386. || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
  4387. {
  4388. char *filename;
  4389. unsigned lineno;
  4390. as_where (&filename, &lineno);
  4391. c_dot_file_symbol (filename, 0);
  4392. }
  4393. }
  4394. /* In order to get gas to ignore any | chars at the start of a line,
  4395. this function returns true if a | is found in a line.
  4396. This lets us process parallel instructions, which span two lines. */
  4397. int
  4398. tic54x_unrecognized_line (int c)
  4399. {
  4400. return c == PARALLEL_SEPARATOR;
  4401. }
  4402. /* Watch for local labels of the form $[0-9] and [_a-zA-Z][_a-zA-Z0-9]*?
  4403. Encode their names so that only we see them and can map them to the
  4404. appropriate places.
  4405. FIXME -- obviously this isn't done yet. These locals still show up in the
  4406. symbol table. */
  4407. void
  4408. tic54x_define_label (symbolS *sym)
  4409. {
  4410. /* Just in case we need this later; note that this is not necessarily the
  4411. same thing as line_label...
  4412. When aligning or assigning labels to fields, sometimes the label is
  4413. assigned other than the address at which the label appears.
  4414. FIXME -- is this really needed? I think all the proper label assignment
  4415. is done in tic54x_cons. */
  4416. last_label_seen = sym;
  4417. }
  4418. /* Try to parse something that normal parsing failed at. */
  4419. symbolS *
  4420. tic54x_undefined_symbol (char *name)
  4421. {
  4422. symbol *sym;
  4423. /* Not sure how to handle predefined symbols. */
  4424. if ((sym = (symbol *) hash_find (cc_hash, name)) != NULL ||
  4425. (sym = (symbol *) hash_find (cc2_hash, name)) != NULL ||
  4426. (sym = (symbol *) hash_find (cc3_hash, name)) != NULL ||
  4427. (sym = (symbol *) hash_find (misc_symbol_hash, name)) != NULL ||
  4428. (sym = (symbol *) hash_find (sbit_hash, name)) != NULL)
  4429. {
  4430. return symbol_new (name, reg_section,
  4431. (valueT) sym->value,
  4432. &zero_address_frag);
  4433. }
  4434. if ((sym = (symbol *) hash_find (reg_hash, name)) != NULL ||
  4435. (sym = (symbol *) hash_find (mmreg_hash, name)) != NULL ||
  4436. !strcasecmp (name, "a") || !strcasecmp (name, "b"))
  4437. {
  4438. return symbol_new (name, reg_section,
  4439. (valueT) sym ? sym->value : 0,
  4440. &zero_address_frag);
  4441. }
  4442. return NULL;
  4443. }
  4444. /* Parse a name in an expression before the expression parser takes a stab at
  4445. it. */
  4446. int
  4447. tic54x_parse_name (char *name ATTRIBUTE_UNUSED,
  4448. expressionS *expn ATTRIBUTE_UNUSED)
  4449. {
  4450. return 0;
  4451. }
  4452. char *
  4453. md_atof (int type, char *literalP, int *sizeP)
  4454. {
  4455. /* Target data is little-endian, but floats are stored
  4456. big-"word"ian. ugh. */
  4457. return ieee_md_atof (type, literalP, sizeP, TRUE);
  4458. }
  4459. arelent *
  4460. tc_gen_reloc (asection *section, fixS *fixP)
  4461. {
  4462. arelent *rel;
  4463. bfd_reloc_code_real_type code = fixP->fx_r_type;
  4464. asymbol *sym = symbol_get_bfdsym (fixP->fx_addsy);
  4465. rel = (arelent *) xmalloc (sizeof (arelent));
  4466. rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
  4467. *rel->sym_ptr_ptr = sym;
  4468. /* We assume that all rel->address are host byte offsets. */
  4469. rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
  4470. rel->address /= OCTETS_PER_BYTE;
  4471. rel->howto = bfd_reloc_type_lookup (stdoutput, code);
  4472. if (!strcmp (sym->name, section->name))
  4473. rel->howto += HOWTO_BANK;
  4474. if (!rel->howto)
  4475. {
  4476. const char *name = S_GET_NAME (fixP->fx_addsy);
  4477. if (name == NULL)
  4478. name = "<unknown>";
  4479. as_fatal ("Cannot generate relocation type for symbol %s, code %s",
  4480. name, bfd_get_reloc_code_name (code));
  4481. return NULL;
  4482. }
  4483. return rel;
  4484. }
  4485. /* Handle cons expressions. */
  4486. void
  4487. tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn,
  4488. bfd_reloc_code_real_type r)
  4489. {
  4490. switch (octets)
  4491. {
  4492. default:
  4493. as_bad (_("Unsupported relocation size %d"), octets);
  4494. r = BFD_RELOC_TIC54X_16_OF_23;
  4495. break;
  4496. case 2:
  4497. r = BFD_RELOC_TIC54X_16_OF_23;
  4498. break;
  4499. case 4:
  4500. /* TI assembler always uses this, regardless of addressing mode. */
  4501. if (emitting_long)
  4502. r = BFD_RELOC_TIC54X_23;
  4503. else
  4504. /* We never want to directly generate this; this is provided for
  4505. stabs support only. */
  4506. r = BFD_RELOC_32;
  4507. break;
  4508. }
  4509. fix_new_exp (frag, where, octets, expn, 0, r);
  4510. }
  4511. /* Attempt to simplify or even eliminate a fixup.
  4512. To indicate that a fixup has been eliminated, set fixP->fx_done.
  4513. If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry. */
  4514. void
  4515. md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
  4516. {
  4517. char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
  4518. valueT val = * valP;
  4519. switch (fixP->fx_r_type)
  4520. {
  4521. default:
  4522. as_fatal ("Bad relocation type: 0x%02x", fixP->fx_r_type);
  4523. return;
  4524. case BFD_RELOC_TIC54X_MS7_OF_23:
  4525. val = (val >> 16) & 0x7F;
  4526. /* Fall through. */
  4527. case BFD_RELOC_TIC54X_16_OF_23:
  4528. case BFD_RELOC_16:
  4529. bfd_put_16 (stdoutput, val, buf);
  4530. /* Indicate what we're actually writing, so that we don't get warnings
  4531. about exceeding available space. */
  4532. *valP = val & 0xFFFF;
  4533. break;
  4534. case BFD_RELOC_TIC54X_PARTLS7:
  4535. bfd_put_16 (stdoutput,
  4536. (bfd_get_16 (stdoutput, buf) & 0xFF80) | (val & 0x7F),
  4537. buf);
  4538. /* Indicate what we're actually writing, so that we don't get warnings
  4539. about exceeding available space. */
  4540. *valP = val & 0x7F;
  4541. break;
  4542. case BFD_RELOC_TIC54X_PARTMS9:
  4543. /* TI assembler doesn't shift its encoding for relocatable files, and is
  4544. thus incompatible with this implementation's relocatable files. */
  4545. bfd_put_16 (stdoutput,
  4546. (bfd_get_16 (stdoutput, buf) & 0xFE00) | (val >> 7),
  4547. buf);
  4548. break;
  4549. case BFD_RELOC_32:
  4550. case BFD_RELOC_TIC54X_23:
  4551. bfd_put_32 (stdoutput,
  4552. (bfd_get_32 (stdoutput, buf) & 0xFF800000) | val,
  4553. buf);
  4554. break;
  4555. }
  4556. if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
  4557. fixP->fx_done = 1;
  4558. }
  4559. /* This is our chance to record section alignment
  4560. don't need to do anything here, since BFD does the proper encoding. */
  4561. valueT
  4562. md_section_align (segT segment ATTRIBUTE_UNUSED, valueT section_size)
  4563. {
  4564. return section_size;
  4565. }
  4566. long
  4567. md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
  4568. {
  4569. return 0;
  4570. }
  4571. /* Mostly little-endian, but longwords (4 octets) get MS word stored
  4572. first. */
  4573. void
  4574. tic54x_number_to_chars (char *buf, valueT val, int n)
  4575. {
  4576. if (n != 4)
  4577. number_to_chars_littleendian (buf, val, n);
  4578. else
  4579. {
  4580. number_to_chars_littleendian (buf , val >> 16 , 2);
  4581. number_to_chars_littleendian (buf + 2, val & 0xFFFF, 2);
  4582. }
  4583. }
  4584. int
  4585. tic54x_estimate_size_before_relax (fragS *frag ATTRIBUTE_UNUSED,
  4586. segT seg ATTRIBUTE_UNUSED)
  4587. {
  4588. return 0;
  4589. }
  4590. /* We use this to handle bit allocations which we couldn't handle before due
  4591. to symbols being in different frags. return number of octets added. */
  4592. int
  4593. tic54x_relax_frag (fragS *frag, long stretch ATTRIBUTE_UNUSED)
  4594. {
  4595. symbolS *sym = frag->fr_symbol;
  4596. int growth = 0;
  4597. int i;
  4598. if (sym != NULL)
  4599. {
  4600. struct bit_info *bi = (struct bit_info *) frag->fr_opcode;
  4601. int bit_offset = frag_bit_offset (frag_prev (frag, bi->seg), bi->seg);
  4602. int size = S_GET_VALUE (sym);
  4603. fragS *prev_frag = bit_offset_frag (frag_prev (frag, bi->seg), bi->seg);
  4604. int available = 16 - bit_offset;
  4605. if (symbol_get_frag (sym) != &zero_address_frag
  4606. || S_IS_COMMON (sym)
  4607. || !S_IS_DEFINED (sym))
  4608. as_bad_where (frag->fr_file, frag->fr_line,
  4609. _("non-absolute value used with .space/.bes"));
  4610. if (size < 0)
  4611. {
  4612. as_warn (_("negative value ignored in %s"),
  4613. bi->type == TYPE_SPACE ? ".space" :
  4614. bi->type == TYPE_BES ? ".bes" : ".field");
  4615. growth = 0;
  4616. frag->tc_frag_data = frag->fr_fix = 0;
  4617. return 0;
  4618. }
  4619. if (bi->type == TYPE_FIELD)
  4620. {
  4621. /* Bit fields of 16 or larger will have already been handled. */
  4622. if (bit_offset != 0 && available >= size)
  4623. {
  4624. char *p = prev_frag->fr_literal;
  4625. valueT value = bi->value;
  4626. value <<= available - size;
  4627. value |= ((unsigned short) p[1] << 8) | p[0];
  4628. md_number_to_chars (p, value, 2);
  4629. if ((prev_frag->tc_frag_data += size) == 16)
  4630. prev_frag->tc_frag_data = 0;
  4631. if (bi->sym)
  4632. symbol_set_frag (bi->sym, prev_frag);
  4633. /* This frag is no longer used. */
  4634. growth = -frag->fr_fix;
  4635. frag->fr_fix = 0;
  4636. frag->tc_frag_data = 0;
  4637. }
  4638. else
  4639. {
  4640. char *p = frag->fr_literal;
  4641. valueT value = bi->value << (16 - size);
  4642. md_number_to_chars (p, value, 2);
  4643. if ((frag->tc_frag_data = size) == 16)
  4644. frag->tc_frag_data = 0;
  4645. growth = 0;
  4646. }
  4647. }
  4648. else
  4649. {
  4650. if (bit_offset != 0 && bit_offset < 16)
  4651. {
  4652. if (available >= size)
  4653. {
  4654. if ((prev_frag->tc_frag_data += size) == 16)
  4655. prev_frag->tc_frag_data = 0;
  4656. if (bi->sym)
  4657. symbol_set_frag (bi->sym, prev_frag);
  4658. /* This frag is no longer used. */
  4659. growth = -frag->fr_fix;
  4660. frag->fr_fix = 0;
  4661. frag->tc_frag_data = 0;
  4662. goto getout;
  4663. }
  4664. if (bi->type == TYPE_SPACE && bi->sym)
  4665. symbol_set_frag (bi->sym, prev_frag);
  4666. size -= available;
  4667. }
  4668. growth = (size + 15) / 16 * OCTETS_PER_BYTE - frag->fr_fix;
  4669. for (i = 0; i < growth; i++)
  4670. frag->fr_literal[i] = 0;
  4671. frag->fr_fix = growth;
  4672. frag->tc_frag_data = size % 16;
  4673. /* Make sure any BES label points to the LAST word allocated. */
  4674. if (bi->type == TYPE_BES && bi->sym)
  4675. S_SET_VALUE (bi->sym, frag->fr_fix / OCTETS_PER_BYTE - 1);
  4676. }
  4677. getout:
  4678. frag->fr_symbol = 0;
  4679. frag->fr_opcode = 0;
  4680. free ((void *) bi);
  4681. }
  4682. return growth;
  4683. }
  4684. void
  4685. tic54x_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
  4686. segT seg ATTRIBUTE_UNUSED,
  4687. fragS *frag)
  4688. {
  4689. /* Offset is in bytes. */
  4690. frag->fr_offset = (frag->fr_next->fr_address
  4691. - frag->fr_address
  4692. - frag->fr_fix) / frag->fr_var;
  4693. if (frag->fr_offset < 0)
  4694. {
  4695. as_bad_where (frag->fr_file, frag->fr_line,
  4696. _("attempt to .space/.bes backwards? (%ld)"),
  4697. (long) frag->fr_offset);
  4698. }
  4699. frag->fr_type = rs_space;
  4700. }
  4701. /* We need to avoid having labels defined for certain directives/pseudo-ops
  4702. since once the label is defined, it's in the symbol table for good. TI
  4703. syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax,
  4704. I guess, except I've never seen a definition of MRI syntax).
  4705. Don't allow labels to start with '.' */
  4706. int
  4707. tic54x_start_label (int nul_char, int next_char)
  4708. {
  4709. char *rest;
  4710. /* If within .struct/.union, no auto line labels, please. */
  4711. if (current_stag != NULL)
  4712. return 0;
  4713. /* Disallow labels starting with "." */
  4714. if (next_char != ':')
  4715. {
  4716. char *label = input_line_pointer;
  4717. while (!is_end_of_line[(int) label[-1]])
  4718. --label;
  4719. if (*label == '.')
  4720. {
  4721. as_bad (_("Invalid label '%s'"), label);
  4722. return 0;
  4723. }
  4724. }
  4725. if (is_end_of_line[(int) next_char])
  4726. return 1;
  4727. rest = input_line_pointer;
  4728. if (nul_char == '"')
  4729. ++rest;
  4730. while (ISSPACE (next_char))
  4731. next_char = *++rest;
  4732. if (next_char != '.')
  4733. return 1;
  4734. /* Don't let colon () define a label for any of these... */
  4735. return ((strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4]))
  4736. && (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7]))
  4737. && (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6]))
  4738. && (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6]))
  4739. && (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4]))
  4740. && (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4])));
  4741. }