agppcmpw.pas 45 KB

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