agppcmpw.pas 46 KB

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