2
0

agppcmpw.pas 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422
  1. {
  2. $Id$
  3. Copyright (c) 2002 by Florian Klaempfl
  4. This unit implements an asmoutput class for PowerPC with MPW syntax
  5. This program 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 2 of the License, or
  8. (at your option) any later version.
  9. This program 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 this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. {
  19. This unit implements an asmoutput class for PowerPC with MPW syntax
  20. }
  21. unit agppcmpw;
  22. {$i fpcdefs.inc}
  23. interface
  24. uses
  25. aasmtai,
  26. globals,aasmbase,aasmcpu,assemble,
  27. cpubase;
  28. type
  29. TPPCMPWAssembler = class(TExternalAssembler)
  30. procedure WriteTree(p:TAAsmoutput);override;
  31. procedure WriteAsmList;override;
  32. Function DoAssemble:boolean;override;
  33. procedure WriteExternals;
  34. {$ifdef GDB}
  35. procedure WriteFileLineInfo(var fileinfo : tfileposinfo);
  36. procedure WriteFileEndInfo;
  37. {$endif}
  38. procedure WriteAsmFileHeader;
  39. private
  40. procedure GenProcedureHeader(var hp:tai);
  41. procedure WriteDataExportHeader(var s:string; isGlobal, isConst:boolean);
  42. end;
  43. implementation
  44. uses
  45. {$ifdef delphi}
  46. sysutils,
  47. {$endif}
  48. cutils,globtype,systems,cclasses,
  49. verbose,finput,fmodule,script,cpuinfo,
  50. cgbase,
  51. itppcgas
  52. ;
  53. const
  54. line_length = 70;
  55. {Whether internal procedure references should be xxx[PR]: }
  56. use_PR = false;
  57. const_storage_class = '[RW]';
  58. {$ifdef GDB}
  59. var
  60. n_line : byte; { different types of source lines }
  61. linecount,
  62. includecount : longint;
  63. funcname : pchar;
  64. stabslastfileinfo : tfileposinfo;
  65. isInFunction: Boolean;
  66. firstLineInFunction: longint;
  67. {$endif}
  68. function ReplaceForbiddenChars(var s: string):Boolean;
  69. {Returns wheater a replacement has occured.}
  70. var
  71. i:Integer;
  72. {The dollar sign is not allowed in MPW PPCAsm}
  73. begin
  74. ReplaceForbiddenChars:=false;
  75. for i:=1 to Length(s) do
  76. if s[i]='$' then
  77. begin
  78. s[i]:='s';
  79. ReplaceForbiddenChars:=true;
  80. end;
  81. end;
  82. {*** From here is copyed from agppcgas.pp, except where marked with CHANGED.
  83. Perhaps put in a third common file. ***}
  84. function getreferencestring(var ref : treference) : string;
  85. var
  86. s : string;
  87. begin
  88. with ref do
  89. begin
  90. inc(offset,offsetfixup);
  91. if (symaddr <> refs_full) then
  92. InternalError(2002110301)
  93. else if ((offset < -32768) or (offset > 32767)) then
  94. InternalError(19991);
  95. if assigned(symbol) then
  96. begin
  97. s:= symbol.name;
  98. ReplaceForbiddenChars(s);
  99. {if symbol.typ = AT_FUNCTION then
  100. ;}
  101. s:= s+'[TC]' {ref to TOC entry }
  102. end
  103. else
  104. s:= '';
  105. if offset<0 then
  106. s:=s+tostr(offset)
  107. else
  108. if (offset>0) then
  109. begin
  110. if assigned(symbol) then
  111. s:=s+'+'+tostr(offset)
  112. else
  113. s:=s+tostr(offset);
  114. end;
  115. if (index=NR_NO) and (base<>NR_NO) then
  116. begin
  117. if offset=0 then
  118. if not assigned(symbol) then
  119. s:=s+'0';
  120. s:=s+'('+gas_regname(base)+')';
  121. end
  122. else if (index<>NR_NO) and (base<>NR_NO) and (offset=0) then
  123. begin
  124. if (offset=0) then
  125. s:=s+gas_regname(base)+','+gas_regname(index)
  126. else
  127. internalerror(19992); // *** ???
  128. end;
  129. end;
  130. getreferencestring:=s;
  131. end;
  132. function getopstr_jmp(const o:toper) : string;
  133. var
  134. hs : string;
  135. begin
  136. case o.typ of
  137. top_reg :
  138. getopstr_jmp:=gas_regname(o.reg);
  139. { no top_ref jumping for powerpc }
  140. top_const :
  141. getopstr_jmp:=tostr(o.val);
  142. top_symbol :
  143. begin
  144. hs:=o.sym.name;
  145. ReplaceForbiddenChars(hs);
  146. if o.symofs>0 then
  147. hs:=hs+'+'+tostr(o.symofs)
  148. else
  149. if o.symofs<0 then
  150. hs:=hs+tostr(o.symofs);
  151. getopstr_jmp:=hs;
  152. end;
  153. top_none:
  154. getopstr_jmp:='';
  155. else
  156. internalerror(2002070603);
  157. end;
  158. end;
  159. function getopstr(const o:toper) : string;
  160. var
  161. hs : string;
  162. begin
  163. case o.typ of
  164. top_reg:
  165. getopstr:=gas_regname(o.reg);
  166. top_const:
  167. getopstr:=tostr(longint(o.val));
  168. top_ref:
  169. getopstr:=getreferencestring(o.ref^);
  170. top_symbol:
  171. begin
  172. hs:=o.sym.name;
  173. ReplaceForbiddenChars(hs);
  174. if o.symofs>0 then
  175. hs:=hs+'+'+tostr(o.symofs)
  176. else
  177. if o.symofs<0 then
  178. hs:=hs+tostr(o.symofs);
  179. getopstr:=hs;
  180. end;
  181. else
  182. internalerror(2002070604);
  183. end;
  184. end;
  185. function branchmode(o: tasmop): string[4];
  186. var tempstr: string[4];
  187. begin
  188. tempstr := '';
  189. case o of
  190. A_BCCTR,A_BCCTRL: tempstr := 'ctr';
  191. A_BCLR,A_BCLRL: tempstr := 'lr';
  192. end;
  193. case o of
  194. A_BL,A_BLA,A_BCL,A_BCLA,A_BCCTRL,A_BCLRL: tempstr := tempstr+'l';
  195. end;
  196. case o of
  197. A_BA,A_BLA,A_BCA,A_BCLA: tempstr:=tempstr+'a';
  198. end;
  199. branchmode := tempstr;
  200. end;
  201. function cond2str(op: tasmop; c: tasmcond): string;
  202. { note: no checking is performed whether the given combination of }
  203. { conditions is valid }
  204. var tempstr: string;
  205. begin
  206. tempstr:=#9;
  207. case c.simple of
  208. false: cond2str := tempstr+gas_op2str[op]+#9+tostr(c.bo)+','+
  209. tostr(c.bi);
  210. true:
  211. if (op >= A_B) and (op <= A_BCLRL) then
  212. case c.cond of
  213. { unconditional branch }
  214. C_NONE:
  215. cond2str := tempstr+gas_op2str[op];
  216. { bdnzt etc }
  217. else
  218. begin
  219. tempstr := tempstr+'b'+asmcondflag2str[c.cond]+
  220. branchmode(op)+#9;
  221. case c.cond of
  222. C_LT..C_NU:
  223. cond2str := tempstr+gas_regname(newreg(R_SPECIALREGISTER,c.cr,R_SUBNONE)); // *** R_SUBWHOLE ???
  224. C_T..C_DZF:
  225. cond2str := tempstr+tostr(c.crbit);
  226. end;
  227. end;
  228. end
  229. { we have a trap instruction }
  230. else
  231. begin
  232. internalerror(2002070601);
  233. { not yet implemented !!!!!!!!!!!!!!!!!!!!! }
  234. { case tempstr := 'tw';}
  235. end;
  236. end;
  237. end;
  238. Function GetInstruction(hp : tai):string; {CHANGED from method to proc}
  239. var op: TAsmOp;
  240. s: string;
  241. i: byte;
  242. sep: string[3];
  243. begin
  244. op:=taicpu(hp).opcode;
  245. if is_calljmp(op) then
  246. begin
  247. { direct BO/BI in op[0] and op[1] not supported, put them in condition! }
  248. case op of
  249. A_B,A_BA:
  250. s:=#9+gas_op2str[op]+#9;
  251. A_BCTR,A_BCTRL,A_BLR,A_BLRL:
  252. s:=#9+gas_op2str[op];
  253. A_BL,A_BLA:
  254. s:=#9+gas_op2str[op]+#9'.';
  255. else
  256. s:=cond2str(op,taicpu(hp).condition)+',';
  257. end;
  258. if (taicpu(hp).oper[0]^.typ <> top_none) then
  259. s:=s+getopstr_jmp(taicpu(hp).oper[0]^);
  260. if use_PR then
  261. if (op=A_BL) or (op=A_BLA) then
  262. s:=s+'[PR]';
  263. end
  264. else
  265. { process operands }
  266. begin
  267. case op of
  268. A_MFSPR:
  269. case taicpu(hp).oper[1]^.reg of
  270. NR_CR:
  271. begin
  272. op:=A_MFCR;
  273. taicpu(hp).ops:=1;
  274. end;
  275. NR_LR:
  276. begin
  277. op:=A_MFLR;
  278. taicpu(hp).ops:=1;
  279. end;
  280. else
  281. internalerror(2002100701);
  282. end;
  283. A_MTSPR:
  284. case taicpu(hp).oper[1]^.reg of
  285. NR_CR:
  286. begin
  287. op:=A_MTCR;
  288. taicpu(hp).ops:=1;
  289. end;
  290. NR_LR:
  291. begin
  292. op:=A_MTLR;
  293. taicpu(hp).ops:=1;
  294. end;
  295. else
  296. internalerror(2002100701);
  297. end;
  298. end;
  299. s:=#9+gas_op2str[op];
  300. if taicpu(hp).ops<>0 then
  301. begin
  302. sep:=#9;
  303. for i:=0 to taicpu(hp).ops-1 do
  304. begin
  305. s:=s+sep+getopstr(taicpu(hp).oper[i]^);
  306. sep:=',';
  307. end;
  308. end;
  309. end;
  310. GetInstruction:=s;
  311. end;
  312. {*** Until here is copyed from agppcgas.pp. ***}
  313. function single2str(d : single) : string;
  314. var
  315. hs : string;
  316. p : byte;
  317. begin
  318. str(d,hs);
  319. { nasm expects a lowercase e }
  320. p:=pos('E',hs);
  321. if p>0 then
  322. hs[p]:='e';
  323. p:=pos('+',hs);
  324. if p>0 then
  325. delete(hs,p,1);
  326. single2str:=lower(hs);
  327. end;
  328. function double2str(d : double) : string;
  329. var
  330. hs : string;
  331. p : byte;
  332. begin
  333. str(d,hs);
  334. { nasm expects a lowercase e }
  335. p:=pos('E',hs);
  336. if p>0 then
  337. hs[p]:='e';
  338. p:=pos('+',hs);
  339. if p>0 then
  340. delete(hs,p,1);
  341. double2str:=lower(hs);
  342. end;
  343. function fixline(s:string):string;
  344. {
  345. return s with all leading and ending spaces and tabs removed
  346. }
  347. var
  348. i,j,k : longint;
  349. begin
  350. i:=length(s);
  351. while (i>0) and (s[i] in [#9,' ']) do
  352. dec(i);
  353. j:=1;
  354. while (j<i) and (s[j] in [#9,' ']) do
  355. inc(j);
  356. for k:=j to i do
  357. if s[k] in [#0..#31,#127..#255] then
  358. s[k]:='.';
  359. fixline:=Copy(s,j,i-j+1);
  360. end;
  361. {****************************************************************************
  362. PowerPC MPW Assembler
  363. ****************************************************************************}
  364. procedure TPPCMPWAssembler.GenProcedureHeader(var hp:tai);
  365. {Returns the current hp where the caller should continue from}
  366. {For multiple entry procedures, only the last is exported as xxx[PR]
  367. (if use_PR is set) }
  368. procedure WriteExportHeader(hp:tai);
  369. var
  370. s: string;
  371. replaced: boolean;
  372. begin
  373. s:= tai_symbol(hp).sym.name;
  374. replaced:= ReplaceForbiddenChars(s);
  375. if not use_PR then
  376. begin
  377. AsmWrite(#9'export'#9'.');
  378. AsmWrite(s);
  379. if replaced then
  380. begin
  381. AsmWrite(' => ''.');
  382. AsmWrite(tai_symbol(hp).sym.name);
  383. AsmWrite('''');
  384. end;
  385. AsmLn;
  386. end;
  387. AsmWrite(#9'export'#9);
  388. AsmWrite(s);
  389. AsmWrite('[DS]');
  390. if replaced then
  391. begin
  392. AsmWrite(' => ''');
  393. AsmWrite(tai_symbol(hp).sym.name);
  394. AsmWrite('[DS]''');
  395. end;
  396. AsmLn;
  397. {Entry in transition vector: }
  398. AsmWrite(#9'csect'#9); AsmWrite(s); AsmWriteLn('[DS]');
  399. AsmWrite(#9'dc.l'#9'.'); AsmWriteLn(s);
  400. AsmWriteln(#9'dc.l'#9'TOC[tc0]');
  401. {Entry in TOC: }
  402. AsmWriteLn(#9'toc');
  403. AsmWrite(#9'tc'#9);
  404. AsmWrite(s); AsmWrite('[TC],');
  405. AsmWrite(s); AsmWriteln('[DS]');
  406. end;
  407. function GetAdjacentTaiSymbol(var hp:tai):Boolean;
  408. begin
  409. GetAdjacentTaiSymbol:= false;
  410. while assigned(hp.next) do
  411. case tai(hp.next).typ of
  412. ait_symbol:
  413. begin
  414. hp:=tai(hp.next);
  415. GetAdjacentTaiSymbol:= true;
  416. Break;
  417. end;
  418. ait_stab_function_name:
  419. hp:=tai(hp.next);
  420. else
  421. begin
  422. //AsmWriteln(' ;#*#*# ' + tostr(Ord(tai(hp.next).typ)));
  423. Break;
  424. end;
  425. end;
  426. end;
  427. var
  428. first,last: tai;
  429. s: string;
  430. replaced: boolean;
  431. begin
  432. s:= tai_symbol(hp).sym.name;
  433. {Write all headers}
  434. first:= hp;
  435. repeat
  436. WriteExportHeader(hp);
  437. last:= hp;
  438. until not GetAdjacentTaiSymbol(hp);
  439. {Start the section of the body of the proc: }
  440. s:= tai_symbol(last).sym.name;
  441. replaced:= ReplaceForbiddenChars(s);
  442. if use_PR then
  443. begin
  444. AsmWrite(#9'export'#9'.'); AsmWrite(s); AsmWrite('[PR]');
  445. if replaced then
  446. begin
  447. AsmWrite(' => ''.');
  448. AsmWrite(tai_symbol(last).sym.name);
  449. AsmWrite('[PR]''');
  450. end;
  451. AsmLn;
  452. end;
  453. {Starts the section: }
  454. AsmWrite(#9'csect'#9'.');
  455. AsmWrite(s);
  456. AsmWriteLn('[PR]');
  457. {Info for the debugger: }
  458. AsmWrite(#9'function'#9'.');
  459. AsmWrite(s);
  460. AsmWriteLn('[PR]');
  461. {$ifdef GDB}
  462. if ((cs_debuginfo in aktmoduleswitches) or
  463. (cs_gdb_lineinfo in aktglobalswitches)) then
  464. begin
  465. //info for debuggers:
  466. firstLineInFunction:= stabslastfileinfo.line;
  467. AsmWriteLn(#9'beginf ' + tostr(firstLineInFunction));
  468. isInFunction:= true;
  469. end;
  470. {$endif}
  471. {Write all labels: }
  472. hp:= first;
  473. repeat
  474. s:= tai_symbol(hp).sym.name;
  475. ReplaceForbiddenChars(s);
  476. AsmWrite('.'); AsmWrite(s); AsmWriteLn(':');
  477. until not GetAdjacentTaiSymbol(hp);
  478. end;
  479. procedure TPPCMPWAssembler.WriteDataExportHeader(var s:string; isGlobal, isConst:boolean);
  480. // Returns in s the changed string
  481. var
  482. sym: string;
  483. replaced: boolean;
  484. begin
  485. sym:= s;
  486. replaced:= ReplaceForbiddenChars(s);
  487. if isGlobal then
  488. begin
  489. AsmWrite(#9'export'#9);
  490. AsmWrite(s);
  491. if isConst then
  492. AsmWrite(const_storage_class)
  493. else
  494. AsmWrite('[RW]');
  495. if replaced then
  496. begin
  497. AsmWrite(' => ''');
  498. AsmWrite(sym);
  499. AsmWrite('''');
  500. end;
  501. AsmLn;
  502. end;
  503. if not macos_direct_globals then
  504. begin
  505. AsmWriteLn(#9'toc');
  506. AsmWrite(#9'tc'#9);
  507. AsmWrite(s);
  508. AsmWrite('[TC], ');
  509. AsmWrite(s);
  510. if isConst then
  511. AsmWrite(const_storage_class)
  512. else
  513. AsmWrite('[RW]');
  514. AsmLn;
  515. AsmWrite(#9'csect'#9);
  516. AsmWrite(s);
  517. if isConst then
  518. AsmWrite(const_storage_class)
  519. else
  520. AsmWrite('[RW]');
  521. end
  522. else
  523. begin
  524. AsmWrite(#9'csect'#9);
  525. AsmWrite(s);
  526. AsmWrite('[TC]');
  527. end;
  528. AsmLn;
  529. end;
  530. var
  531. LasTSec : TSection;
  532. lastfileinfo : tfileposinfo;
  533. infile,
  534. lastinfile : tinputfile;
  535. const
  536. ait_const2str:array[ait_const_32bit..ait_const_8bit] of string[8]=
  537. (#9'dc.l'#9,#9'dc.w'#9,#9'dc.b'#9);
  538. Function PadTabs(const p:string;addch:char):string;
  539. var
  540. s : string;
  541. i : longint;
  542. begin
  543. i:=length(p);
  544. if addch<>#0 then
  545. begin
  546. inc(i);
  547. s:=p+addch;
  548. end
  549. else
  550. s:=p;
  551. if i<8 then
  552. PadTabs:=s+#9#9
  553. else
  554. PadTabs:=s+#9;
  555. end;
  556. {$ifdef GDB}
  557. procedure TPPCMPWAssembler.WriteFileLineInfo(var fileinfo : tfileposinfo);
  558. var
  559. curr_n : byte;
  560. begin
  561. if not ((cs_debuginfo in aktmoduleswitches) or
  562. (cs_gdb_lineinfo in aktglobalswitches)) then
  563. exit;
  564. { file changed ? (must be before line info) }
  565. if (fileinfo.fileindex<>0) and
  566. (stabslastfileinfo.fileindex<>fileinfo.fileindex) then
  567. begin
  568. infile:=current_module.sourcefiles.get_file(fileinfo.fileindex);
  569. if assigned(infile) then
  570. begin
  571. (*
  572. if includecount=0 then
  573. curr_n:=n_sourcefile
  574. else
  575. curr_n:=n_includefile;
  576. if (infile.path^<>'') then
  577. begin
  578. AsmWriteLn(#9'.stabs "'+lower(BsToSlash(FixPath(infile.path^,false)))+'",'+
  579. tostr(curr_n)+',0,0,'+target_asm.labelprefix+'text'+ToStr(IncludeCount));
  580. end;
  581. AsmWriteLn(#9'.stabs "'+lower(FixFileName(infile.name^))+'",'+
  582. tostr(curr_n)+',0,0,'+target_asm.labelprefix+'text'+ToStr(IncludeCount));
  583. *)
  584. AsmWriteLn(#9'file '''+lower(FixFileName(infile.name^))+'''');
  585. (*
  586. AsmWriteLn(target_asm.labelprefix+'text'+ToStr(IncludeCount)+':');
  587. *)
  588. inc(includecount);
  589. { force new line info }
  590. stabslastfileinfo.line:=-1;
  591. end;
  592. end;
  593. { line changed ? }
  594. if (stabslastfileinfo.line<>fileinfo.line) and (fileinfo.line<>0) then
  595. begin
  596. (*
  597. if (n_line=n_textline) and assigned(funcname) and
  598. (target_info.use_function_relative_addresses) then
  599. begin
  600. AsmWriteLn(target_asm.labelprefix+'l'+tostr(linecount)+':');
  601. AsmWrite(#9'.stabn '+tostr(n_line)+',0,'+tostr(fileinfo.line)+','+
  602. target_asm.labelprefix+'l'+tostr(linecount)+' - ');
  603. AsmWritePChar(FuncName);
  604. AsmLn;
  605. inc(linecount);
  606. end
  607. else
  608. AsmWriteLn(#9'.stabd'#9+tostr(n_line)+',0,'+tostr(fileinfo.line));
  609. *)
  610. if isInFunction then
  611. AsmWriteln(#9'line '+ tostr(fileinfo.line - firstLineInFunction - 1));
  612. end;
  613. stabslastfileinfo:=fileinfo;
  614. end;
  615. procedure TPPCMPWAssembler.WriteFileEndInfo;
  616. begin
  617. if not ((cs_debuginfo in aktmoduleswitches) or
  618. (cs_gdb_lineinfo in aktglobalswitches)) then
  619. exit;
  620. AsmLn;
  621. (*
  622. AsmWriteLn(ait_section2str(sec_code));
  623. AsmWriteLn(#9'.stabs "",'+tostr(n_sourcefile)+',0,0,'+target_asm.labelprefix+'etext');
  624. AsmWriteLn(target_asm.labelprefix+'etext:');
  625. *)
  626. end;
  627. {$endif}
  628. procedure TPPCMPWAssembler.WriteTree(p:TAAsmoutput);
  629. var
  630. s,
  631. prefix,
  632. suffix : string;
  633. hp : tai;
  634. hp1 : tailineinfo;
  635. counter,
  636. lines,
  637. InlineLevel : longint;
  638. i,j,l : longint;
  639. consttyp : taitype;
  640. found,
  641. do_line,DoNotSplitLine,
  642. quoted : boolean;
  643. sep : char;
  644. replaced : boolean;
  645. begin
  646. if not assigned(p) then
  647. exit;
  648. InlineLevel:=0;
  649. { lineinfo is only needed for codesegment (PFV) }
  650. do_line:=((cs_asm_source in aktglobalswitches) or
  651. (cs_lineinfo in aktmoduleswitches))
  652. and (p=codesegment);
  653. DoNotSplitLine:=false;
  654. hp:=tai(p.first);
  655. while assigned(hp) do
  656. begin
  657. if not(hp.typ in SkipLineInfo) and
  658. not DoNotSplitLine then
  659. begin
  660. hp1 := hp as tailineinfo;
  661. {$ifdef GDB}
  662. { write debug info }
  663. if (cs_debuginfo in aktmoduleswitches) or
  664. (cs_gdb_lineinfo in aktglobalswitches) then
  665. WriteFileLineInfo(hp1.fileinfo);
  666. {$endif GDB}
  667. if do_line then
  668. begin
  669. { load infile }
  670. if lastfileinfo.fileindex<>hp1.fileinfo.fileindex then
  671. begin
  672. infile:=current_module.sourcefiles.get_file(hp1.fileinfo.fileindex);
  673. if assigned(infile) then
  674. begin
  675. { open only if needed !! }
  676. if (cs_asm_source in aktglobalswitches) then
  677. infile.open;
  678. end;
  679. { avoid unnecessary reopens of the same file !! }
  680. lastfileinfo.fileindex:=hp1.fileinfo.fileindex;
  681. { be sure to change line !! }
  682. lastfileinfo.line:=-1;
  683. end;
  684. { write source }
  685. if (cs_asm_source in aktglobalswitches) and
  686. assigned(infile) then
  687. begin
  688. if (infile<>lastinfile) then
  689. begin
  690. AsmWriteLn(target_asm.comment+'['+infile.name^+']');
  691. if assigned(lastinfile) then
  692. lastinfile.close;
  693. end;
  694. if (hp1.fileinfo.line<>lastfileinfo.line) and
  695. ((hp1.fileinfo.line<infile.maxlinebuf) or (InlineLevel>0)) then
  696. begin
  697. if (hp1.fileinfo.line<>0) and
  698. ((infile.linebuf^[hp1.fileinfo.line]>=0) or (InlineLevel>0)) then
  699. AsmWriteLn(target_asm.comment+'['+tostr(hp1.fileinfo.line)+'] '+
  700. fixline(infile.GetLineStr(hp1.fileinfo.line)));
  701. { set it to a negative value !
  702. to make that is has been read already !! PM }
  703. if (infile.linebuf^[hp1.fileinfo.line]>=0) then
  704. infile.linebuf^[hp1.fileinfo.line]:=-infile.linebuf^[hp1.fileinfo.line]-1;
  705. end;
  706. end;
  707. lastfileinfo:=hp1.fileinfo;
  708. lastinfile:=infile;
  709. end;
  710. end;
  711. DoNotSplitLine:=false;
  712. case hp.typ of
  713. ait_comment:
  714. begin
  715. AsmWrite(target_asm.comment);
  716. AsmWritePChar(tai_comment(hp).str);
  717. AsmLn;
  718. end;
  719. ait_regalloc,
  720. ait_tempalloc:
  721. ;
  722. ait_section:
  723. begin
  724. {if LasTSec<>sec_none then
  725. AsmWriteLn('_'+target_asm.secnames[LasTSec]+#9#9'ENDS');}
  726. if tai_section(hp).sec<>sec_none then
  727. begin
  728. AsmLn;
  729. AsmWriteLn(#9+target_asm.secnames[tai_section(hp).sec]);
  730. {$ifdef GDB}
  731. lastfileinfo.line:=-1;
  732. {$endif GDB}
  733. end;
  734. LasTSec:=tai_section(hp).sec;
  735. end;
  736. ait_align:
  737. begin
  738. case tai_align(hp).aligntype of
  739. 1:AsmWriteLn(#9'align 0');
  740. 2:AsmWriteLn(#9'align 1');
  741. 4:AsmWriteLn(#9'align 2');
  742. otherwise internalerror(2002110302);
  743. end;
  744. end;
  745. ait_datablock:
  746. begin
  747. s:= tai_datablock(hp).sym.name;
  748. WriteDataExportHeader(s, tai_datablock(hp).is_global, false);
  749. if not macos_direct_globals then
  750. begin
  751. AsmWriteLn(#9'ds.b '+tostr(tai_datablock(hp).size));
  752. end
  753. else
  754. begin
  755. AsmWriteLn(PadTabs(s+':',#0)+'ds.b '+tostr(tai_datablock(hp).size));
  756. {TODO: ? PadTabs(s,#0) }
  757. end;
  758. end;
  759. ait_const_32bit,
  760. ait_const_8bit,
  761. ait_const_16bit :
  762. begin
  763. AsmWrite(ait_const2str[hp.typ]+tostr(tai_const(hp).value));
  764. consttyp:=hp.typ;
  765. l:=0;
  766. repeat
  767. found:=(not (tai(hp.next)=nil)) and (tai(hp.next).typ=consttyp);
  768. if found then
  769. begin
  770. hp:=tai(hp.next);
  771. s:=','+tostr(tai_const(hp).value);
  772. AsmWrite(s);
  773. inc(l,length(s));
  774. end;
  775. until (not found) or (l>line_length);
  776. AsmLn;
  777. end;
  778. ait_const_symbol:
  779. begin
  780. s:= tai_const_symbol(hp).sym.name;
  781. ReplaceForbiddenChars(s);
  782. AsmWrite(#9'dc.l'#9);
  783. if tai_const_symbol(hp).sym.typ = AT_FUNCTION then
  784. begin
  785. if use_PR then
  786. AsmWrite('.');
  787. AsmWrite(s);
  788. if use_PR then
  789. AsmWriteLn('[PR]')
  790. else
  791. AsmWriteLn('[DS]')
  792. end
  793. else
  794. begin
  795. AsmWrite(s);
  796. if not macos_direct_globals then
  797. AsmWriteLn(const_storage_class);
  798. end;
  799. (* TODO: the following might need to be included. Temporaily we
  800. generate an error
  801. if tai_const_symbol(hp).offset>0 then
  802. AsmWrite('+'+tostr(tai_const_symbol(hp).offset))
  803. else if tai_const_symbol(hp).offset<0 then
  804. AsmWrite(tostr(tai_const_symbol(hp).offset));
  805. *)
  806. if tai_const_symbol(hp).offset <> 0 then
  807. InternalError(2002110101);
  808. AsmLn;
  809. end;
  810. ait_real_32bit:
  811. AsmWriteLn(#9'dc.l'#9'"'+single2str(tai_real_32bit(hp).value)+'"');
  812. ait_real_64bit:
  813. AsmWriteLn(#9'dc.d'#9'"'+double2str(tai_real_64bit(hp).value)+'"');
  814. ait_string:
  815. begin
  816. {NOTE When a single quote char is encountered, it is
  817. replaced with a numeric ascii value. It could also
  818. have been replaced with the escape seq of double quotes.
  819. Backslash seems to be used as an escape char, although
  820. this is not mentioned in the PPCAsm documentation.}
  821. counter := 0;
  822. lines := tai_string(hp).len div line_length;
  823. { separate lines in different parts }
  824. if tai_string(hp).len > 0 then
  825. Begin
  826. for j := 0 to lines-1 do
  827. begin
  828. AsmWrite(#9'dc.b'#9);
  829. quoted:=false;
  830. for i:=counter to counter+line_length do
  831. begin
  832. { it is an ascii character. }
  833. if (ord(tai_string(hp).str[i])>31) and
  834. (ord(tai_string(hp).str[i])<128) and
  835. (tai_string(hp).str[i]<>'''') and
  836. (tai_string(hp).str[i]<>'\') then
  837. begin
  838. if not(quoted) then
  839. begin
  840. if i>counter then
  841. AsmWrite(',');
  842. AsmWrite('''');
  843. end;
  844. AsmWrite(tai_string(hp).str[i]);
  845. quoted:=true;
  846. end { if > 31 and < 128 and ord('"') }
  847. else
  848. begin
  849. if quoted then
  850. AsmWrite('''');
  851. if i>counter then
  852. AsmWrite(',');
  853. quoted:=false;
  854. AsmWrite(tostr(ord(tai_string(hp).str[i])));
  855. end;
  856. end; { end for i:=0 to... }
  857. if quoted then AsmWrite('''');
  858. AsmWrite(target_info.newline);
  859. counter := counter+line_length;
  860. end; { end for j:=0 ... }
  861. { do last line of lines }
  862. AsmWrite(#9'dc.b'#9);
  863. quoted:=false;
  864. for i:=counter to tai_string(hp).len-1 do
  865. begin
  866. { it is an ascii character. }
  867. if (ord(tai_string(hp).str[i])>31) and
  868. (ord(tai_string(hp).str[i])<128) and
  869. (tai_string(hp).str[i]<>'''') and
  870. (tai_string(hp).str[i]<>'\') then begin
  871. if not(quoted) then
  872. begin
  873. if i>counter then
  874. AsmWrite(',');
  875. AsmWrite('''');
  876. end;
  877. AsmWrite(tai_string(hp).str[i]);
  878. quoted:=true;
  879. end { if > 31 and < 128 and " }
  880. else
  881. begin
  882. if quoted then
  883. AsmWrite('''');
  884. if i>counter then
  885. AsmWrite(',');
  886. quoted:=false;
  887. AsmWrite(tostr(ord(tai_string(hp).str[i])));
  888. end;
  889. end; { end for i:=0 to... }
  890. if quoted then
  891. AsmWrite('''');
  892. end;
  893. AsmLn;
  894. end;
  895. ait_label:
  896. begin
  897. if tai_label(hp).l.is_used then
  898. begin
  899. s:= tai_label(hp).l.name;
  900. ReplaceForbiddenChars(s);
  901. if s[1] = '@' then
  902. //Local labels:
  903. AsmWriteLn(s+':')
  904. else
  905. begin
  906. //Procedure entry points:
  907. if not macos_direct_globals then
  908. begin
  909. AsmWriteLn(#9'toc');
  910. AsmWrite(#9'tc'#9); AsmWrite(s);
  911. AsmWrite('[TC], '); AsmWrite(s);
  912. AsmWriteLn(const_storage_class);
  913. AsmWrite(#9'csect'#9); AsmWrite(s);
  914. AsmWriteLn(const_storage_class);
  915. end
  916. else
  917. begin
  918. AsmWrite(#9'csect'#9); AsmWrite(s);
  919. AsmWriteLn('[TC]');
  920. AsmWriteLn(PadTabs(s+':',#0));
  921. end;
  922. end;
  923. end;
  924. end;
  925. ait_direct:
  926. begin
  927. AsmWritePChar(tai_direct(hp).str);
  928. AsmLn;
  929. end;
  930. ait_symbol:
  931. begin
  932. if tai_symbol(hp).sym.typ=AT_FUNCTION then
  933. GenProcedureHeader(hp)
  934. else if tai_symbol(hp).sym.typ=AT_DATA then
  935. begin
  936. s:= tai_symbol(hp).sym.name;
  937. WriteDataExportHeader(s, tai_symbol(hp).is_global, true);
  938. if macos_direct_globals then
  939. begin
  940. AsmWrite(s);
  941. AsmWriteLn(':');
  942. end;
  943. end
  944. else
  945. InternalError(2003071301);
  946. end;
  947. ait_symbol_end:
  948. {$ifdef GDB}
  949. if isInFunction then
  950. if ((cs_debuginfo in aktmoduleswitches) or
  951. (cs_gdb_lineinfo in aktglobalswitches)) then
  952. begin
  953. //info for debuggers:
  954. AsmWriteLn(#9'endf ' + tostr(stabslastfileinfo.line));
  955. isInFunction:= false;
  956. end
  957. {$endif GDB}
  958. ;
  959. ait_instruction:
  960. AsmWriteLn(GetInstruction(hp));
  961. {$ifdef GDB}
  962. ait_stabn: ;
  963. ait_stabs: ;
  964. ait_force_line :
  965. stabslastfileinfo.line:=0;
  966. ait_stab_function_name: ;
  967. {$endif GDB}
  968. ait_cut :
  969. begin
  970. { only reset buffer if nothing has changed }
  971. if AsmSize=AsmStartSize then
  972. AsmClear
  973. else
  974. begin
  975. {
  976. if LasTSec<>sec_none then
  977. AsmWriteLn('_'+target_asm.secnames[LasTSec]+#9#9'ends');
  978. AsmLn;
  979. }
  980. AsmWriteLn(#9'end');
  981. AsmClose;
  982. DoAssemble;
  983. AsmCreate(tai_cut(hp).place);
  984. end;
  985. { avoid empty files }
  986. while assigned(hp.next) and (tai(hp.next).typ in [ait_cut,ait_section,ait_comment]) do
  987. begin
  988. if tai(hp.next).typ=ait_section then
  989. begin
  990. lasTSec:=tai_section(hp.next).sec;
  991. end;
  992. hp:=tai(hp.next);
  993. end;
  994. WriteAsmFileHeader;
  995. if lasTSec<>sec_none then
  996. AsmWriteLn(#9+target_asm.secnames[lasTSec]);
  997. { AsmWriteLn('_'+target_asm.secnames[lasTSec]+#9#9+
  998. 'SEGMENT'#9'PARA PUBLIC USE32 '''+
  999. target_asm.secnames[lasTSec]+'''');
  1000. }
  1001. AsmStartSize:=AsmSize;
  1002. end;
  1003. ait_marker :
  1004. begin
  1005. if tai_marker(hp).kind=InlineStart then
  1006. inc(InlineLevel)
  1007. else if tai_marker(hp).kind=InlineEnd then
  1008. dec(InlineLevel);
  1009. end;
  1010. else
  1011. internalerror(2002110303);
  1012. end;
  1013. hp:=tai(hp.next);
  1014. end;
  1015. end;
  1016. var
  1017. currentasmlist : TExternalAssembler;
  1018. procedure writeexternal(p:tnamedindexitem;arg:pointer);
  1019. var
  1020. s:string;
  1021. replaced: boolean;
  1022. begin
  1023. if tasmsymbol(p).defbind=AB_EXTERNAL then
  1024. begin
  1025. //Writeln('ZZZ ',p.name,' ',p.classname,' ',Ord(tasmsymbol(p).typ));
  1026. s:= p.name;
  1027. replaced:= ReplaceForbiddenChars(s);
  1028. with currentasmlist do
  1029. case tasmsymbol(p).typ of
  1030. AT_FUNCTION:
  1031. begin
  1032. AsmWrite(#9'import'#9'.');
  1033. AsmWrite(s);
  1034. if use_PR then
  1035. AsmWrite('[PR]');
  1036. if replaced then
  1037. begin
  1038. AsmWrite(' <= ''.');
  1039. AsmWrite(p.name);
  1040. if use_PR then
  1041. AsmWrite('[PR]''')
  1042. else
  1043. AsmWrite('''');
  1044. end;
  1045. AsmLn;
  1046. AsmWrite(#9'import'#9);
  1047. AsmWrite(s);
  1048. AsmWrite('[DS]');
  1049. if replaced then
  1050. begin
  1051. AsmWrite(' <= ''');
  1052. AsmWrite(p.name);
  1053. AsmWrite('[DS]''');
  1054. end;
  1055. AsmLn;
  1056. AsmWriteLn(#9'toc');
  1057. AsmWrite(#9'tc'#9);
  1058. AsmWrite(s);
  1059. AsmWrite('[TC],');
  1060. AsmWrite(s);
  1061. AsmWriteLn('[DS]');
  1062. end;
  1063. AT_DATA:
  1064. begin
  1065. AsmWrite(#9'import'#9);
  1066. AsmWrite(s);
  1067. AsmWrite('[RW]');
  1068. if replaced then
  1069. begin
  1070. AsmWrite(' <= ''');
  1071. AsmWrite(p.name);
  1072. AsmWrite('''');
  1073. end;
  1074. AsmLn;
  1075. AsmWriteLn(#9'toc');
  1076. AsmWrite(#9'tc'#9);
  1077. AsmWrite(s);
  1078. AsmWrite('[TC],');
  1079. AsmWrite(s);
  1080. AsmWriteLn('[RW]');
  1081. end
  1082. else
  1083. InternalError(2003090901);
  1084. end;
  1085. end;
  1086. end;
  1087. procedure TPPCMPWAssembler.WriteExternals;
  1088. begin
  1089. currentasmlist:=self;
  1090. objectlibrary.symbolsearch.foreach_static({$ifdef fpcprocvar}@{$endif}writeexternal,nil);
  1091. end;
  1092. function TPPCMPWAssembler.DoAssemble : boolean;
  1093. var f : file;
  1094. begin
  1095. DoAssemble:=Inherited DoAssemble;
  1096. (*
  1097. { masm does not seem to recognize specific extensions and uses .obj allways PM }
  1098. if (aktoutputformat = as_i386_masm) then
  1099. begin
  1100. if not(cs_asm_extern in aktglobalswitches) then
  1101. begin
  1102. if Not FileExists(objfile) and
  1103. FileExists(ForceExtension(objfile,'.obj')) then
  1104. begin
  1105. Assign(F,ForceExtension(objfile,'.obj'));
  1106. Rename(F,objfile);
  1107. end;
  1108. end
  1109. else
  1110. AsmRes.AddAsmCommand('mv',ForceExtension(objfile,'.obj')+' '+objfile,objfile);
  1111. end;
  1112. *)
  1113. end;
  1114. procedure TPPCMPWAssembler.WriteAsmFileHeader;
  1115. begin
  1116. (*
  1117. AsmWriteLn(#9'.386p');
  1118. { masm 6.11 does not seem to like LOCALS PM }
  1119. if (aktoutputformat = as_i386_tasm) then
  1120. begin
  1121. AsmWriteLn(#9'LOCALS '+target_asm.labelprefix);
  1122. end;
  1123. AsmWriteLn('DGROUP'#9'GROUP'#9'_BSS,_DATA');
  1124. AsmWriteLn(#9'ASSUME'#9'CS:_CODE,ES:DGROUP,DS:DGROUP,SS:DGROUP');
  1125. AsmLn;
  1126. *)
  1127. AsmWriteLn(#9'string asis'); {Interpret strings just to be the content between the quotes.}
  1128. AsmWriteLn(#9'aligning off'); {We do our own aligning.}
  1129. AsmLn;
  1130. end;
  1131. procedure TPPCMPWAssembler.WriteAsmList;
  1132. {$ifdef GDB}
  1133. var
  1134. fileinfo : tfileposinfo;
  1135. {$endif GDB}
  1136. begin
  1137. {$ifdef EXTDEBUG}
  1138. if assigned(current_module.mainsource) then
  1139. comment(v_info,'Start writing MPW-styled assembler output for '+current_module.mainsource^);
  1140. {$endif}
  1141. LasTSec:=sec_none;
  1142. {$ifdef GDB}
  1143. FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
  1144. {$endif GDB}
  1145. {$ifdef GDB}
  1146. //n_line:=n_bssline;
  1147. funcname:=nil;
  1148. linecount:=1;
  1149. includecount:=0;
  1150. fileinfo.fileindex:=1;
  1151. fileinfo.line:=1;
  1152. isInFunction:= false;
  1153. firstLineInFunction:= 0;
  1154. { Write main file }
  1155. WriteFileLineInfo(fileinfo);
  1156. {$endif GDB}
  1157. WriteAsmFileHeader;
  1158. WriteExternals;
  1159. { PowerPC MPW ASM doesn't support stabs, as we know.
  1160. WriteTree(debuglist);}
  1161. WriteTree(codesegment);
  1162. WriteTree(datasegment);
  1163. WriteTree(consts);
  1164. WriteTree(rttilist);
  1165. WriteTree(resourcestringlist);
  1166. WriteTree(bsssegment);
  1167. {$ifdef GDB}
  1168. WriteFileEndInfo;
  1169. {$ENDIF}
  1170. AsmWriteLn(#9'end');
  1171. AsmLn;
  1172. {$ifdef EXTDEBUG}
  1173. if assigned(current_module.mainsource) then
  1174. comment(v_info,'Done writing MPW-styled assembler output for '+current_module.mainsource^);
  1175. {$endif EXTDEBUG}
  1176. end;
  1177. {*****************************************************************************
  1178. Initialize
  1179. *****************************************************************************}
  1180. const
  1181. as_powerpc_mpw_info : tasminfo =
  1182. (
  1183. id : as_powerpc_mpw;
  1184. idtxt : 'MPW';
  1185. asmbin : 'PPCAsm';
  1186. asmcmd : '';
  1187. supported_target : system_any; { what should I write here ?? }
  1188. outputbinary: false;
  1189. allowdirect : true;
  1190. needar : true;
  1191. labelprefix_only_inside_procedure : true;
  1192. labelprefix : '@';
  1193. comment : '; ';
  1194. secnames : ('',
  1195. 'csect','csect [TC]','csect [TC]', {TODO: Perhaps use other section types.}
  1196. '','','','','','',
  1197. '','','')
  1198. );
  1199. initialization
  1200. RegisterAssembler(as_powerpc_mpw_info,TPPCMPWAssembler);
  1201. end.
  1202. {
  1203. $Log$
  1204. Revision 1.27 2003-10-25 10:37:26 florian
  1205. * fixed compilation of ppc compiler
  1206. Revision 1.26 2003/10/01 20:34:49 peter
  1207. * procinfo unit contains tprocinfo
  1208. * cginfo renamed to cgbase
  1209. * moved cgmessage to verbose
  1210. * fixed ppc and sparc compiles
  1211. Revision 1.25 2003/09/12 12:30:27 olle
  1212. * max lenght of symbols increased to 255
  1213. * emitted strings can now contain backslashes
  1214. Revision 1.24 2003/09/03 19:35:24 peter
  1215. * powerpc compiles again
  1216. Revision 1.23 2003/08/24 21:40:12 olle
  1217. * minor adjustment
  1218. Revision 1.21 2003/08/18 11:47:15 olle
  1219. + added asm directive ALIGNING OFF to avoid unexpected aligning by the assembler
  1220. Revision 1.20 2002/10/01 05:17:27 olle
  1221. * minor fix
  1222. Revision 1.19 2003/04/06 21:01:40 olle
  1223. + line numbers are now emitted in the assembler code
  1224. * bug in export and import directive fixed
  1225. * made code more in sync with aggas.pas
  1226. Revision 1.18 2003/01/13 17:17:50 olle
  1227. * changed global var access, TOC now contain pointers to globals
  1228. * fixed handling of function pointers
  1229. Revision 1.17 2003/01/08 18:43:57 daniel
  1230. * Tregister changed into a record
  1231. Revision 1.16 2002/11/28 10:56:07 olle
  1232. * changed proc ref from .xxx[PR] (refering to its section)
  1233. to .xxx (refering to its label) to allow for multiple ref to a proc.
  1234. Revision 1.15 2002/11/17 16:31:59 carl
  1235. * memory optimization (3-4%) : cleanup of tai fields,
  1236. cleanup of tdef and tsym fields.
  1237. * make it work for m68k
  1238. Revision 1.14 2002/11/07 15:50:23 jonas
  1239. * fixed bctr(l) problems
  1240. Revision 1.13 2002/11/04 18:24:53 olle
  1241. * globals are located in TOC and relative r2, instead of absolute
  1242. * symbols which only differs in case are treated as a single symbol
  1243. + tai_const_symbol supported
  1244. * only refs_full accepted
  1245. Revision 1.12 2002/10/23 15:31:01 olle
  1246. * branch b does not jump to dotted symbol now
  1247. Revision 1.11 2002/10/19 23:52:40 olle
  1248. * import directive changed
  1249. Revision 1.10 2002/10/10 19:39:37 florian
  1250. * changes from Olle to get simple programs compiled and assembled
  1251. Revision 1.9 2002/10/07 21:19:53 florian
  1252. * more mpw fixes
  1253. Revision 1.8 2002/10/06 22:46:20 florian
  1254. * fixed function exporting
  1255. Revision 1.7 2002/10/02 22:14:15 florian
  1256. * improve function imports
  1257. Revision 1.6 2002/09/27 21:09:49 florian
  1258. + readed because previous version was broken
  1259. Revision 1.2 2002/08/31 12:43:31 florian
  1260. * ppc compilation fixed
  1261. Revision 1.1 2002/08/20 21:40:44 florian
  1262. + target macos for ppc added
  1263. + frame work for mpw assembler output
  1264. }