agppcmpw.pas 46 KB

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