agppcmpw.pas 45 KB

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