agppcmpw.pas 46 KB

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