agppcmpw.pas 45 KB

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