agppcmpw.pas 44 KB

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